From 2d878f29ebe810696222cb2a157abfb39f8e68a4 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 28 Oct 2011 21:52:07 -0400 Subject: [PATCH] theme: Use cairo for drawing ICON Thanks to Benjamin Otte for helping me clean this up. https://bugzilla.gnome.org/show_bug.cgi?id=662962 --- src/ui/theme.c | 80 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 54 insertions(+), 26 deletions(-) diff --git a/src/ui/theme.c b/src/ui/theme.c index 3ef1677ec..e9ae3fbb7 100644 --- a/src/ui/theme.c +++ b/src/ui/theme.c @@ -3484,20 +3484,6 @@ draw_op_as_pixbuf (const MetaDrawOp *op, break; } case META_DRAW_ICON: - if (info->mini_icon && - width <= gdk_pixbuf_get_width (info->mini_icon) && - height <= gdk_pixbuf_get_height (info->mini_icon)) - pixbuf = scale_and_alpha_pixbuf (info->mini_icon, - op->data.icon.fill_type, - width, height, - FALSE, FALSE); - else if (info->icon) - pixbuf = scale_and_alpha_pixbuf (info->icon, - op->data.icon.fill_type, - width, height, - FALSE, FALSE); - break; - case META_DRAW_LINE: case META_DRAW_RECTANGLE: case META_DRAW_ARC: @@ -3515,6 +3501,46 @@ draw_op_as_pixbuf (const MetaDrawOp *op, return pixbuf; } +static void +draw_image (cairo_t *cr, + GdkPixbuf *src, + MetaImageFillType fill_type, + int x, + int y, + int width, + int height) +{ + cairo_save (cr); + + cairo_rectangle (cr, x, y, width, height); + + if (fill_type == META_IMAGE_FILL_TILE) + { + gdk_cairo_set_source_pixbuf (cr, src, 0, 0); + + cairo_pattern_set_extend (cairo_get_source (cr), + CAIRO_EXTEND_REPEAT); + } + else + { + float pixbuf_width, pixbuf_height; + + pixbuf_width = gdk_pixbuf_get_width (src); + pixbuf_height = gdk_pixbuf_get_height (src); + + cairo_translate (cr, x, y); + cairo_scale (cr, + pixbuf_width / width, + pixbuf_height / height); + + gdk_cairo_set_source_pixbuf (cr, src, 0, 0); + } + + cairo_fill (cr); + + cairo_restore (cr); +} + static void fill_env (MetaPositionExprEnv *env, const MetaDrawInfo *info, @@ -3885,24 +3911,26 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op, case META_DRAW_ICON: { int rx, ry, rwidth, rheight; - GdkPixbuf *pixbuf; + GdkPixbuf *src; rwidth = parse_size_unchecked (op->data.icon.width, env); rheight = parse_size_unchecked (op->data.icon.height, env); - - pixbuf = draw_op_as_pixbuf (op, style_gtk, info, - rwidth, rheight); - if (pixbuf) - { - rx = parse_x_position_unchecked (op->data.icon.x, env); - ry = parse_y_position_unchecked (op->data.icon.y, env); + if (info->mini_icon && + rwidth < gdk_pixbuf_get_width (info->mini_icon) && + rheight < gdk_pixbuf_get_height (info->mini_icon)) + src = info->mini_icon; + else if (info->icon) + src = info->icon; + else + break; - gdk_cairo_set_source_pixbuf (cr, pixbuf, rx, ry); - cairo_paint (cr); + rx = parse_x_position_unchecked (op->data.icon.x, env); + ry = parse_y_position_unchecked (op->data.icon.y, env); - g_object_unref (G_OBJECT (pixbuf)); - } + draw_image (cr, src, + op->data.icon.fill_type, + rwidth, rheight, rx, ry); } break;