Replace Gdk drawing with Cairo

https://bugzilla.gnome.org/show_bug.cgi?id=626870
This commit is contained in:
Benjamin Otte 2010-07-25 14:31:49 +02:00
parent 58a4b4a252
commit 7ea3249a4a
4 changed files with 74 additions and 76 deletions

View file

@ -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 */

View file

@ -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);

View file

@ -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,

View file

@ -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);