summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlberts Muktupāvels <alberts.muktupavels@gmail.com>2016-07-07 15:17:32 +0300
committerAlberts Muktupāvels <alberts.muktupavels@gmail.com>2016-07-07 15:23:55 +0300
commit1d5b066284264089ea3982c354782eb1acb14a28 (patch)
tree514ebe9c05c6552116b68a0f2e36c52a5ab63bf0
parent2b34699ff18462946d2816f2ec4840a05c6d79ea (diff)
downloadmetacity-1d5b066284264089ea3982c354782eb1acb14a28.tar.gz
libmetacity: use cairo to render gradient
-rw-r--r--libmetacity/meta-draw-op.c20
-rw-r--r--libmetacity/meta-gradient-spec-private.h12
-rw-r--r--libmetacity/meta-gradient-spec.c99
3 files changed, 82 insertions, 49 deletions
diff --git a/libmetacity/meta-draw-op.c b/libmetacity/meta-draw-op.c
index fbdd7d64..6a648b3b 100644
--- a/libmetacity/meta-draw-op.c
+++ b/libmetacity/meta-draw-op.c
@@ -434,13 +434,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:
@@ -741,22 +734,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