[metacity/gnome-3-20] libmetacity: use cairo to render gradient



commit 1d5b066284264089ea3982c354782eb1acb14a28
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Thu Jul 7 15:17:32 2016 +0300

    libmetacity: use cairo to render gradient

 libmetacity/meta-draw-op.c               |   20 +-----
 libmetacity/meta-gradient-spec-private.h |   12 +++-
 libmetacity/meta-gradient-spec.c         |   99 +++++++++++++++++++++--------
 3 files changed, 82 insertions(+), 49 deletions(-)
---
diff --git a/libmetacity/meta-draw-op.c b/libmetacity/meta-draw-op.c
index fbdd7d6..6a648b3 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 e131214..b3416e2 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 71f4f5b..19c5291 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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]