diff options
Diffstat (limited to 'src/ui/theme.c')
-rw-r--r-- | src/ui/theme.c | 145 |
1 files changed, 91 insertions, 54 deletions
diff --git a/src/ui/theme.c b/src/ui/theme.c index ec922b74..d7932e67 100644 --- a/src/ui/theme.c +++ b/src/ui/theme.c @@ -994,6 +994,70 @@ meta_gradient_spec_new (MetaGradientType type) return spec; } +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 && alpha_spec->n_alphas != 1) + 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) + { + gdouble alpha; + + if (alpha_spec->n_alphas == 1) + alpha = alpha_spec->alphas[0] / 255.0; + else + alpha = alpha_spec->alphas[i] / 255.0; + + cairo_pattern_add_color_stop_rgba (pattern, i / (gfloat) (n_colors - 1), + color.red, color.green, color.blue, + alpha); + } + else + cairo_pattern_add_color_stop_rgb (pattern, i / (gfloat) (n_colors - 1), + color.red, color.green, color.blue); + + tmp = tmp->next; + ++i; + } + + if (cairo_pattern_status (pattern) != CAIRO_STATUS_SUCCESS) + { + cairo_pattern_destroy (pattern); + return NULL; + } + + return pattern; +} + static void free_color_spec (gpointer spec, gpointer user_data) { @@ -1012,42 +1076,34 @@ meta_gradient_spec_free (MetaGradientSpec *spec) g_free (spec); } -GdkPixbuf* -meta_gradient_spec_render (const MetaGradientSpec *spec, - GtkStyleContext *style, - int width, - int height) -{ - int n_colors; - GdkRGBA *colors; - GSList *tmp; - int i; - GdkPixbuf *pixbuf; - - n_colors = g_slist_length (spec->color_specs); - - if (n_colors == 0) - return NULL; - - colors = g_new (GdkRGBA, n_colors); +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) +{ + cairo_pattern_t *pattern; + + 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, style, &colors[i]); + cairo_save (cr); - tmp = tmp->next; - ++i; - } + cairo_rectangle (cr, x, y, width, height); - pixbuf = meta_gradient_create_multi (width, height, - colors, n_colors, - spec->type); + cairo_translate (cr, x, y); + cairo_scale (cr, width, height); - g_free (colors); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); - return pixbuf; + cairo_restore (cr); } gboolean @@ -3488,18 +3544,6 @@ draw_op_as_pixbuf (const MetaDrawOp *op, } break; - case META_DRAW_GRADIENT: - { - pixbuf = meta_gradient_spec_render (op->data.gradient.gradient_spec, - style, width, height); - - pixbuf = apply_alpha (pixbuf, - op->data.gradient.alpha_spec, - FALSE); - } - break; - - case META_DRAW_IMAGE: { if (op->data.image.colorize_spec) @@ -3545,6 +3589,7 @@ draw_op_as_pixbuf (const MetaDrawOp *op, break; } + case META_DRAW_GRADIENT: case META_DRAW_GTK_ARROW: case META_DRAW_GTK_BOX: case META_DRAW_GTK_VLINE: @@ -3838,23 +3883,15 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op, case META_DRAW_GRADIENT: { int rx, ry, rwidth, rheight; - GdkPixbuf *pixbuf; rx = parse_x_position_unchecked (op->data.gradient.x, env); ry = parse_y_position_unchecked (op->data.gradient.y, env); rwidth = parse_size_unchecked (op->data.gradient.width, env); rheight = parse_size_unchecked (op->data.gradient.height, env); - pixbuf = draw_op_as_pixbuf (op, style_gtk, 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, style_gtk, rx, ry, rwidth, rheight); } break; |