diff options
author | Victor Kareh <[email protected]> | 2019-05-31 07:17:47 -0400 |
---|---|---|
committer | Victor Kareh <[email protected]> | 2019-06-05 12:34:34 -0400 |
commit | 9891d7a679a5553b1c155b8ba2af4aa2bc1e1dd6 (patch) | |
tree | 70dd9791f5b66ef3c463cc19182348fcfad2e243 /src/ui/theme.c | |
parent | a1797ff49005fe18a3ae55f763f5a58ade66b480 (diff) | |
download | marco-9891d7a679a5553b1c155b8ba2af4aa2bc1e1dd6.tar.bz2 marco-9891d7a679a5553b1c155b8ba2af4aa2bc1e1dd6.tar.xz |
libmetacity: use cairo to render gradient
upstream commits:
https://gitlab.gnome.org/GNOME/metacity/commit/71d5decc
https://gitlab.gnome.org/GNOME/metacity/commit/127638ca
https://gitlab.gnome.org/GNOME/metacity/commit/fc1a21ea
https://gitlab.gnome.org/GNOME/metacity/commit/431e0418
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 b97b0118..a7368c92 100644 --- a/src/ui/theme.c +++ b/src/ui/theme.c @@ -996,6 +996,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) { @@ -1014,42 +1078,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 @@ -3490,18 +3546,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) @@ -3547,6 +3591,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: @@ -3840,23 +3885,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; |