From 71d5decc42f3367bcbe2c4656356edd0f94d9feb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alberts=20Muktup=C4=81vels?= Date: Thu, 7 Jul 2016 15:17:32 +0300 Subject: libmetacity: use cairo to render gradient --- libmetacity/meta-draw-op.c | 24 ++------ libmetacity/meta-gradient-spec-private.h | 12 ++-- libmetacity/meta-gradient-spec.c | 99 +++++++++++++++++++++++--------- 3 files changed, 83 insertions(+), 52 deletions(-) (limited to 'libmetacity') diff --git a/libmetacity/meta-draw-op.c b/libmetacity/meta-draw-op.c index fdff1626..4d3ba5be 100644 --- a/libmetacity/meta-draw-op.c +++ b/libmetacity/meta-draw-op.c @@ -407,16 +407,6 @@ draw_op_as_pixbuf (const MetaDrawOp *op, } break; - case META_DRAW_GRADIENT: - { - pixbuf = meta_gradient_spec_render (op->data.gradient.gradient_spec, - context, width, height); - - pixbuf = meta_alpha_gradient_spec_apply_alpha (op->data.gradient.alpha_spec, - pixbuf, FALSE); - } - break; - case META_DRAW_IMAGE: { if (op->data.image.colorize_spec) @@ -483,6 +473,7 @@ draw_op_as_pixbuf (const MetaDrawOp *op, case META_DRAW_RECTANGLE: case META_DRAW_ARC: case META_DRAW_CLIP: + case META_DRAW_GRADIENT: case META_DRAW_GTK_ARROW: case META_DRAW_GTK_BOX: case META_DRAW_GTK_VLINE: @@ -713,22 +704,15 @@ draw_op_draw_with_env (const MetaDrawOp *op, case META_DRAW_GRADIENT: { int rx, ry, rwidth, rheight; - GdkPixbuf *pixbuf; rx = meta_draw_spec_parse_x_position (op->data.gradient.x, env); ry = meta_draw_spec_parse_y_position (op->data.gradient.y, env); rwidth = meta_draw_spec_parse_size (op->data.gradient.width, env); rheight = meta_draw_spec_parse_size (op->data.gradient.height, env); - pixbuf = draw_op_as_pixbuf (op, context, info, rwidth, rheight); - - if (pixbuf) - { - gdk_cairo_set_source_pixbuf (cr, pixbuf, rx, ry); - cairo_paint (cr); - - g_object_unref (G_OBJECT (pixbuf)); - } + meta_gradient_spec_render (op->data.gradient.gradient_spec, + op->data.gradient.alpha_spec, + cr, context, rx, ry, rwidth, rheight); } break; diff --git a/libmetacity/meta-gradient-spec-private.h b/libmetacity/meta-gradient-spec-private.h index e131214d..b3416e2e 100644 --- a/libmetacity/meta-gradient-spec-private.h +++ b/libmetacity/meta-gradient-spec-private.h @@ -39,10 +39,14 @@ void meta_gradient_spec_add_color_spec (MetaGradientSpec MetaColorSpec *color_spec); G_GNUC_INTERNAL -GdkPixbuf *meta_gradient_spec_render (const MetaGradientSpec *spec, - GtkStyleContext *context, - gint width, - gint height); +void meta_gradient_spec_render (const MetaGradientSpec *spec, + const MetaAlphaGradientSpec *alpha_spec, + cairo_t *cr, + GtkStyleContext *context, + gint x, + gint y, + gint width, + gint height); G_GNUC_INTERNAL gboolean meta_gradient_spec_validate (MetaGradientSpec *spec, diff --git a/libmetacity/meta-gradient-spec.c b/libmetacity/meta-gradient-spec.c index 71f4f5ba..19c52912 100644 --- a/libmetacity/meta-gradient-spec.c +++ b/libmetacity/meta-gradient-spec.c @@ -38,6 +38,56 @@ struct _MetaAlphaGradientSpec gint n_alphas; }; + +static cairo_pattern_t * +create_cairo_pattern_from_gradient_spec (const MetaGradientSpec *spec, + const MetaAlphaGradientSpec *alpha_spec, + GtkStyleContext *context) +{ + gint n_colors; + cairo_pattern_t *pattern; + GSList *tmp; + gint i; + + n_colors = g_slist_length (spec->color_specs); + if (n_colors == 0) + return NULL; + + if (alpha_spec != NULL) + g_assert (n_colors == alpha_spec->n_alphas); + + if (spec->type == META_GRADIENT_HORIZONTAL) + pattern = cairo_pattern_create_linear (0, 0, 1, 0); + else if (spec->type == META_GRADIENT_VERTICAL) + pattern = cairo_pattern_create_linear (0, 0, 0, 1); + else if (spec->type == META_GRADIENT_DIAGONAL) + pattern = cairo_pattern_create_linear (0, 0, 1, 1); + else + g_assert_not_reached (); + + i = 0; + tmp = spec->color_specs; + while (tmp != NULL) + { + GdkRGBA color; + + meta_color_spec_render (tmp->data, context, &color); + + if (alpha_spec != NULL) + cairo_pattern_add_color_stop_rgba (pattern, i / (gfloat) n_colors, + color.red, color.green, color.blue, + alpha_spec->alphas[i]); + else + cairo_pattern_add_color_stop_rgb (pattern, i / (gfloat) n_colors, + color.red, color.green, color.blue); + + tmp = tmp->next; + ++i; + } + + return pattern; +} + static void free_color_spec (gpointer spec, gpointer user_data) @@ -76,41 +126,34 @@ meta_gradient_spec_add_color_spec (MetaGradientSpec *spec, spec->color_specs = g_slist_append (spec->color_specs, color_spec); } -GdkPixbuf * -meta_gradient_spec_render (const MetaGradientSpec *spec, - GtkStyleContext *context, - gint width, - gint height) +void +meta_gradient_spec_render (const MetaGradientSpec *spec, + const MetaAlphaGradientSpec *alpha_spec, + cairo_t *cr, + GtkStyleContext *context, + gint x, + gint y, + gint width, + gint height) { - gint n_colors; - GdkRGBA *colors; - GSList *tmp; - gint i; - GdkPixbuf *pixbuf; - - n_colors = g_slist_length (spec->color_specs); + cairo_pattern_t *pattern; - if (n_colors == 0) - return NULL; + cairo_save (cr); - colors = g_new (GdkRGBA, n_colors); + pattern = create_cairo_pattern_from_gradient_spec (spec, alpha_spec, context); + if (pattern == NULL) + return; - i = 0; - tmp = spec->color_specs; - while (tmp != NULL) - { - meta_color_spec_render (tmp->data, context, &colors[i]); + cairo_rectangle (cr, x, y, width, height); - tmp = tmp->next; - ++i; - } + cairo_translate (cr, x, y); + cairo_scale (cr, width, height); - pixbuf = meta_gradient_create_multi (width, height, colors, - n_colors, spec->type); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); - g_free (colors); - - return pixbuf; + cairo_restore (cr); } gboolean -- cgit v1.2.1