Replace Gdk drawing with Cairo
https://bugzilla.gnome.org/show_bug.cgi?id=626870
This commit is contained in:
parent
58a4b4a252
commit
7ea3249a4a
4 changed files with 74 additions and 76 deletions
|
@ -112,6 +112,7 @@ create_text_pixmap(GtkWidget *drawing_area, FT_Face face)
|
||||||
XftFont *font;
|
XftFont *font;
|
||||||
gint *sizes = NULL, n_sizes, alpha_size;
|
gint *sizes = NULL, n_sizes, alpha_size;
|
||||||
FcCharSet *charset = NULL;
|
FcCharSet *charset = NULL;
|
||||||
|
cairo_t *cr;
|
||||||
GdkWindow *window = gtk_widget_get_window (drawing_area);
|
GdkWindow *window = gtk_widget_get_window (drawing_area);
|
||||||
|
|
||||||
text = pango_language_get_sample_string(NULL);
|
text = pango_language_get_sample_string(NULL);
|
||||||
|
@ -192,8 +193,11 @@ create_text_pixmap(GtkWidget *drawing_area, FT_Face face)
|
||||||
pixmap_width, pixmap_height, -1);
|
pixmap_width, pixmap_height, -1);
|
||||||
if (!pixmap)
|
if (!pixmap)
|
||||||
goto end;
|
goto end;
|
||||||
gdk_draw_rectangle(pixmap, gtk_widget_get_style(drawing_area)->white_gc,
|
|
||||||
TRUE, 0, 0, pixmap_width, pixmap_height);
|
cr = gdk_cairo_create (pixmap);
|
||||||
|
cairo_set_source_rgb (cr, 1, 1, 1);
|
||||||
|
cairo_paint (cr);
|
||||||
|
cairo_destroy (cr);
|
||||||
|
|
||||||
xdrawable = GDK_DRAWABLE_XID(pixmap);
|
xdrawable = GDK_DRAWABLE_XID(pixmap);
|
||||||
draw = XftDrawCreate(xdisplay, xdrawable, xvisual, xcolormap);
|
draw = XftDrawCreate(xdisplay, xdrawable, xvisual, xcolormap);
|
||||||
|
@ -376,12 +380,16 @@ add_face_info(GtkWidget *table, gint *row_p, const gchar *uri, FT_Face face)
|
||||||
static gboolean
|
static gboolean
|
||||||
expose_event(GtkWidget *widget, GdkEventExpose *event, GdkPixmap *pixmap)
|
expose_event(GtkWidget *widget, GdkEventExpose *event, GdkPixmap *pixmap)
|
||||||
{
|
{
|
||||||
gdk_draw_drawable(gtk_widget_get_window (widget),
|
cairo_t *cr;
|
||||||
gtk_widget_get_style (widget)->fg_gc[gtk_widget_get_state (widget)],
|
|
||||||
pixmap,
|
cr = gdk_cairo_create (gtk_widget_get_window (widget));
|
||||||
event->area.x, event->area.y,
|
|
||||||
event->area.x, event->area.y,
|
gdk_cairo_set_source_pixmap (cr, pixmap, 0, 0);
|
||||||
event->area.width, event->area.height);
|
gdk_cairo_region (cr, event->region);
|
||||||
|
cairo_fill (cr);
|
||||||
|
|
||||||
|
cairo_destroy (cr);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -505,7 +513,6 @@ main(int argc, char **argv)
|
||||||
gchar *font_file, *title;
|
gchar *font_file, *title;
|
||||||
gint row;
|
gint row;
|
||||||
GtkWidget *window, *hbox, *table, *swin, *drawing_area;
|
GtkWidget *window, *hbox, *table, *swin, *drawing_area;
|
||||||
GdkPixmap *pixmap;
|
|
||||||
GdkColor white = { 0, 0xffff, 0xffff, 0xffff };
|
GdkColor white = { 0, 0xffff, 0xffff, 0xffff };
|
||||||
GtkWidget *button, *align;
|
GtkWidget *button, *align;
|
||||||
|
|
||||||
|
@ -567,7 +574,7 @@ main(int argc, char **argv)
|
||||||
gtk_widget_modify_bg(drawing_area, GTK_STATE_NORMAL, &white);
|
gtk_widget_modify_bg(drawing_area, GTK_STATE_NORMAL, &white);
|
||||||
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(swin),
|
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(swin),
|
||||||
drawing_area);
|
drawing_area);
|
||||||
g_signal_connect (drawing_area, "realize", create_text_pixmap, face);
|
g_signal_connect (drawing_area, "realize", G_CALLBACK (create_text_pixmap), face);
|
||||||
|
|
||||||
/* set the minimum size on the scrolled window to prevent
|
/* set the minimum size on the scrolled window to prevent
|
||||||
* unnecessary scrolling */
|
* unnecessary scrolling */
|
||||||
|
|
|
@ -486,23 +486,6 @@ clip_to_region (cairo_t *cr, cairo_region_t *region)
|
||||||
cairo_clip (cr);
|
cairo_clip (cr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
simple_draw_drawable (GdkDrawable *dst,
|
|
||||||
GdkDrawable *src,
|
|
||||||
int src_x,
|
|
||||||
int src_y,
|
|
||||||
int dst_x,
|
|
||||||
int dst_y,
|
|
||||||
int width,
|
|
||||||
int height)
|
|
||||||
{
|
|
||||||
GdkGC *gc = gdk_gc_new (dst);
|
|
||||||
|
|
||||||
gdk_draw_drawable (dst, gc, src, src_x, src_y, dst_x, dst_y, width, height);
|
|
||||||
|
|
||||||
g_object_unref (gc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
foo_scroll_area_expose (GtkWidget *widget,
|
foo_scroll_area_expose (GtkWidget *widget,
|
||||||
GdkEventExpose *expose)
|
GdkEventExpose *expose)
|
||||||
|
@ -512,7 +495,6 @@ foo_scroll_area_expose (GtkWidget *widget,
|
||||||
GdkRectangle extents;
|
GdkRectangle extents;
|
||||||
cairo_region_t *region;
|
cairo_region_t *region;
|
||||||
int x_offset, y_offset;
|
int x_offset, y_offset;
|
||||||
GdkGC *gc;
|
|
||||||
GtkAllocation widget_allocation;
|
GtkAllocation widget_allocation;
|
||||||
GdkWindow *window = gtk_widget_get_window (widget);
|
GdkWindow *window = gtk_widget_get_window (widget);
|
||||||
|
|
||||||
|
@ -563,17 +545,16 @@ foo_scroll_area_expose (GtkWidget *widget,
|
||||||
scroll_area->priv->expose_region = NULL;
|
scroll_area->priv->expose_region = NULL;
|
||||||
scroll_area->priv->current_input = NULL;
|
scroll_area->priv->current_input = NULL;
|
||||||
|
|
||||||
/* Finally draw the backing pixmap */
|
|
||||||
gc = gdk_gc_new (window);
|
|
||||||
|
|
||||||
gdk_gc_set_clip_region (gc, expose->region);
|
|
||||||
|
|
||||||
gtk_widget_get_allocation (widget, &widget_allocation);
|
gtk_widget_get_allocation (widget, &widget_allocation);
|
||||||
gdk_draw_drawable (window, gc, scroll_area->priv->pixmap,
|
|
||||||
0, 0, widget_allocation.x, widget_allocation.y,
|
|
||||||
widget_allocation.width, widget_allocation.height);
|
|
||||||
|
|
||||||
g_object_unref (gc);
|
/* Finally draw the backing pixmap */
|
||||||
|
cr = gdk_cairo_create (window);
|
||||||
|
gdk_cairo_set_source_pixmap (cr, scroll_area->priv->pixmap,
|
||||||
|
widget_allocation.x, widget_allocation.y);
|
||||||
|
gdk_cairo_region (cr, expose->region);
|
||||||
|
cairo_fill (cr);
|
||||||
|
cairo_destroy (cr);
|
||||||
|
|
||||||
cairo_region_destroy (region);
|
cairo_region_destroy (region);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -727,6 +708,7 @@ create_new_pixmap (GtkWidget *widget,
|
||||||
{
|
{
|
||||||
GtkAllocation widget_allocation;
|
GtkAllocation widget_allocation;
|
||||||
GdkPixmap *new;
|
GdkPixmap *new;
|
||||||
|
cairo_t *cr;
|
||||||
|
|
||||||
gtk_widget_get_allocation (widget, &widget_allocation);
|
gtk_widget_get_allocation (widget, &widget_allocation);
|
||||||
new = gdk_pixmap_new (gtk_widget_get_window (widget),
|
new = gdk_pixmap_new (gtk_widget_get_window (widget),
|
||||||
|
@ -741,7 +723,11 @@ create_new_pixmap (GtkWidget *widget,
|
||||||
* That might just work, actually. We need to make sure metacity uses
|
* That might just work, actually. We need to make sure metacity uses
|
||||||
* static gravity for the window before this will be useful.
|
* static gravity for the window before this will be useful.
|
||||||
*/
|
*/
|
||||||
simple_draw_drawable (new, old, 0, 0, 0, 0, -1, -1);
|
cr = gdk_cairo_create (new);
|
||||||
|
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||||
|
gdk_cairo_set_source_pixmap (cr, old, 0, 0);
|
||||||
|
cairo_paint (cr);
|
||||||
|
cairo_destroy (cr);
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
@ -1150,6 +1136,7 @@ foo_scroll_area_scroll (FooScrollArea *area,
|
||||||
if (gdk_rectangle_intersect (&allocation, &src_area, &move_area))
|
if (gdk_rectangle_intersect (&allocation, &src_area, &move_area))
|
||||||
{
|
{
|
||||||
cairo_region_t *move_region;
|
cairo_region_t *move_region;
|
||||||
|
cairo_t *cr;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
g_print ("scrolling %d %d %d %d (%d %d)\n",
|
g_print ("scrolling %d %d %d %d (%d %d)\n",
|
||||||
|
@ -1157,11 +1144,25 @@ foo_scroll_area_scroll (FooScrollArea *area,
|
||||||
move_area.width, move_area.height,
|
move_area.width, move_area.height,
|
||||||
dx, dy);
|
dx, dy);
|
||||||
#endif
|
#endif
|
||||||
|
cr = gdk_cairo_create (area->priv->pixmap);
|
||||||
simple_draw_drawable (area->priv->pixmap, area->priv->pixmap,
|
|
||||||
move_area.x, move_area.y,
|
/* Cairo doesn't allow self-copies, so we do this little trick instead:
|
||||||
move_area.x + dx, move_area.y + dy,
|
* 1) Clip so the group size is small.
|
||||||
move_area.width, move_area.height);
|
* 2) Call push_group() which creates a temporary pixmap as a workaround
|
||||||
|
*/
|
||||||
|
gdk_cairo_rectangle (cr, &move_area);
|
||||||
|
cairo_clip (cr);
|
||||||
|
cairo_push_group (cr);
|
||||||
|
|
||||||
|
gdk_cairo_set_source_pixmap (cr, area->priv->pixmap, dx, dy);
|
||||||
|
gdk_cairo_rectangle (cr, &move_area);
|
||||||
|
cairo_fill (cr);
|
||||||
|
|
||||||
|
cairo_pop_group_to_source (cr);
|
||||||
|
cairo_paint (cr);
|
||||||
|
|
||||||
|
cairo_destroy (cr);
|
||||||
|
|
||||||
gtk_widget_queue_draw (GTK_WIDGET (area));
|
gtk_widget_queue_draw (GTK_WIDGET (area));
|
||||||
|
|
||||||
move_region = cairo_region_create_rectangle (&move_area);
|
move_region = cairo_region_create_rectangle (&move_area);
|
||||||
|
|
|
@ -588,34 +588,31 @@ label_expose_event_cb (GtkLabel *label,
|
||||||
GdkEventExpose *event,
|
GdkEventExpose *event,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
gint x, y;
|
gint x, y;
|
||||||
GdkColor color;
|
GtkWidget *widget;
|
||||||
GtkWidget *widget;
|
GdkWindow *window;
|
||||||
GdkWindow *window;
|
cairo_t *cr;
|
||||||
GdkGC *gc;
|
|
||||||
|
|
||||||
color.red = 0;
|
|
||||||
color.green = 0;
|
|
||||||
color.blue = 0;
|
|
||||||
color.pixel = 0;
|
|
||||||
|
|
||||||
get_layout_location (label, &x, &y);
|
get_layout_location (label, &x, &y);
|
||||||
|
|
||||||
widget = GTK_WIDGET (label);
|
widget = GTK_WIDGET (label);
|
||||||
window = gtk_widget_get_window (widget);
|
window = gtk_widget_get_window (widget);
|
||||||
|
|
||||||
gc = gdk_gc_new (window);
|
cr = gdk_cairo_create (window);
|
||||||
gdk_gc_set_rgb_fg_color (gc, &color);
|
|
||||||
gdk_gc_set_clip_rectangle (gc, &event->area);
|
|
||||||
|
|
||||||
gdk_draw_layout_with_colors (window,
|
gdk_cairo_rectangle (cr, &event->area);
|
||||||
gc,
|
cairo_clip (cr);
|
||||||
x + 1,
|
|
||||||
y + 1,
|
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||||
gtk_label_get_layout (label),
|
|
||||||
&color,
|
/* Can't use pango_cairo_show_layout() here as we need to override
|
||||||
NULL);
|
* the layout's colors with our shadow color.
|
||||||
g_object_unref (gc);
|
*/
|
||||||
|
cairo_move_to (cr, x + 1, y + 1);
|
||||||
|
pango_cairo_layout_path (cr, gtk_label_get_layout (label));
|
||||||
|
cairo_fill (cr);
|
||||||
|
|
||||||
|
cairo_destroy (cr);
|
||||||
|
|
||||||
gtk_paint_layout (gtk_widget_get_style (widget),
|
gtk_paint_layout (gtk_widget_get_style (widget),
|
||||||
window,
|
window,
|
||||||
|
|
|
@ -150,6 +150,7 @@ set_pixmap_background (GtkWidget *window)
|
||||||
GdkRectangle rect;
|
GdkRectangle rect;
|
||||||
GdkColor color;
|
GdkColor color;
|
||||||
gint width, height;
|
gint width, height;
|
||||||
|
cairo_t *cr;
|
||||||
|
|
||||||
gtk_widget_realize (window);
|
gtk_widget_realize (window);
|
||||||
|
|
||||||
|
@ -205,18 +206,10 @@ set_pixmap_background (GtkWidget *window)
|
||||||
height,
|
height,
|
||||||
-1);
|
-1);
|
||||||
|
|
||||||
gdk_draw_pixbuf (pixmap,
|
cr = gdk_cairo_create (pixmap);
|
||||||
NULL,
|
gdk_cairo_set_source_pixbuf (cr, tmp_pixbuf, 0, 0);
|
||||||
tmp_pixbuf,
|
cairo_paint (cr);
|
||||||
0,
|
cairo_destroy (cr);
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
GDK_RGB_DITHER_NONE,
|
|
||||||
0,
|
|
||||||
0);
|
|
||||||
|
|
||||||
g_object_unref (tmp_pixbuf);
|
g_object_unref (tmp_pixbuf);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue