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;
gint *sizes = NULL, n_sizes, alpha_size;
FcCharSet *charset = NULL;
cairo_t *cr;
GdkWindow *window = gtk_widget_get_window (drawing_area);
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);
if (!pixmap)
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);
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
expose_event(GtkWidget *widget, GdkEventExpose *event, GdkPixmap *pixmap)
{
gdk_draw_drawable(gtk_widget_get_window (widget),
gtk_widget_get_style (widget)->fg_gc[gtk_widget_get_state (widget)],
pixmap,
event->area.x, event->area.y,
event->area.x, event->area.y,
event->area.width, event->area.height);
cairo_t *cr;
cr = gdk_cairo_create (gtk_widget_get_window (widget));
gdk_cairo_set_source_pixmap (cr, pixmap, 0, 0);
gdk_cairo_region (cr, event->region);
cairo_fill (cr);
cairo_destroy (cr);
return FALSE;
}
@ -505,7 +513,6 @@ main(int argc, char **argv)
gchar *font_file, *title;
gint row;
GtkWidget *window, *hbox, *table, *swin, *drawing_area;
GdkPixmap *pixmap;
GdkColor white = { 0, 0xffff, 0xffff, 0xffff };
GtkWidget *button, *align;
@ -567,7 +574,7 @@ main(int argc, char **argv)
gtk_widget_modify_bg(drawing_area, GTK_STATE_NORMAL, &white);
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(swin),
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
* unnecessary scrolling */

View file

@ -486,23 +486,6 @@ clip_to_region (cairo_t *cr, cairo_region_t *region)
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
foo_scroll_area_expose (GtkWidget *widget,
GdkEventExpose *expose)
@ -512,7 +495,6 @@ foo_scroll_area_expose (GtkWidget *widget,
GdkRectangle extents;
cairo_region_t *region;
int x_offset, y_offset;
GdkGC *gc;
GtkAllocation widget_allocation;
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->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);
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);
return TRUE;
@ -727,6 +708,7 @@ create_new_pixmap (GtkWidget *widget,
{
GtkAllocation widget_allocation;
GdkPixmap *new;
cairo_t *cr;
gtk_widget_get_allocation (widget, &widget_allocation);
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
* 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;
}
@ -1150,6 +1136,7 @@ foo_scroll_area_scroll (FooScrollArea *area,
if (gdk_rectangle_intersect (&allocation, &src_area, &move_area))
{
cairo_region_t *move_region;
cairo_t *cr;
#if 0
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,
dx, dy);
#endif
simple_draw_drawable (area->priv->pixmap, area->priv->pixmap,
move_area.x, move_area.y,
move_area.x + dx, move_area.y + dy,
move_area.width, move_area.height);
cr = gdk_cairo_create (area->priv->pixmap);
/* Cairo doesn't allow self-copies, so we do this little trick instead:
* 1) Clip so the group size is small.
* 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));
move_region = cairo_region_create_rectangle (&move_area);

View file

@ -588,34 +588,31 @@ label_expose_event_cb (GtkLabel *label,
GdkEventExpose *event,
gpointer user_data)
{
gint x, y;
GdkColor color;
GtkWidget *widget;
GdkWindow *window;
GdkGC *gc;
color.red = 0;
color.green = 0;
color.blue = 0;
color.pixel = 0;
gint x, y;
GtkWidget *widget;
GdkWindow *window;
cairo_t *cr;
get_layout_location (label, &x, &y);
widget = GTK_WIDGET (label);
window = gtk_widget_get_window (widget);
gc = gdk_gc_new (window);
gdk_gc_set_rgb_fg_color (gc, &color);
gdk_gc_set_clip_rectangle (gc, &event->area);
cr = gdk_cairo_create (window);
gdk_draw_layout_with_colors (window,
gc,
x + 1,
y + 1,
gtk_label_get_layout (label),
&color,
NULL);
g_object_unref (gc);
gdk_cairo_rectangle (cr, &event->area);
cairo_clip (cr);
cairo_set_source_rgb (cr, 0, 0, 0);
/* Can't use pango_cairo_show_layout() here as we need to override
* the layout's colors with our shadow color.
*/
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),
window,

View file

@ -150,6 +150,7 @@ set_pixmap_background (GtkWidget *window)
GdkRectangle rect;
GdkColor color;
gint width, height;
cairo_t *cr;
gtk_widget_realize (window);
@ -205,18 +206,10 @@ set_pixmap_background (GtkWidget *window)
height,
-1);
gdk_draw_pixbuf (pixmap,
NULL,
tmp_pixbuf,
0,
0,
0,
0,
width,
height,
GDK_RGB_DITHER_NONE,
0,
0);
cr = gdk_cairo_create (pixmap);
gdk_cairo_set_source_pixbuf (cr, tmp_pixbuf, 0, 0);
cairo_paint (cr);
cairo_destroy (cr);
g_object_unref (tmp_pixbuf);