summaryrefslogtreecommitdiff
path: root/src/ui/theme.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/theme.c')
-rw-r--r--src/ui/theme.c145
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;