[metacity] libmetacity: add meta-gradient-spec.[c/h]



commit 7a52e2c88c63b3af3e8c6e182b3d950bd2543dec
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Thu Jan 28 01:29:15 2016 +0200

    libmetacity: add meta-gradient-spec.[c/h]

 libmetacity/Makefile.am             |    4 +
 libmetacity/meta-gradient-private.h |   59 ++++++++
 libmetacity/meta-gradient-spec.c    |  253 +++++++++++++++++++++++++++++++++++
 libmetacity/meta-gradient-spec.h    |   70 ++++++++++
 libmetacity/meta-gradient.c         |    2 +-
 libmetacity/meta-gradient.h         |   28 +----
 po/POTFILES.in                      |    1 +
 src/ui/testgradient.c               |    1 +
 src/ui/theme-parser.c               |   28 +---
 src/ui/theme-private.h              |   28 +----
 src/ui/theme.c                      |  184 +------------------------
 11 files changed, 406 insertions(+), 252 deletions(-)
---
diff --git a/libmetacity/Makefile.am b/libmetacity/Makefile.am
index d84aefd..bc2fc5c 100644
--- a/libmetacity/Makefile.am
+++ b/libmetacity/Makefile.am
@@ -10,6 +10,9 @@ libmetacity_la_SOURCES = \
        meta-color-spec.h \
        meta-gradient.c \
        meta-gradient.h \
+       meta-gradient-private.h \
+       meta-gradient-spec.c \
+       meta-gradient-spec.h \
        meta-hsla.c \
        meta-hsla-private.h \
        meta-theme.c \
@@ -17,6 +20,7 @@ libmetacity_la_SOURCES = \
        $(NULL)
 
 libmetacity_la_CPPFLAGS = \
+       -I$(top_srcdir) \
        $(AM_CPPFLAGS) \
        $(NULL)
 
diff --git a/libmetacity/meta-gradient-private.h b/libmetacity/meta-gradient-private.h
new file mode 100644
index 0000000..e460bdd
--- /dev/null
+++ b/libmetacity/meta-gradient-private.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2001 Havoc Pennington, 99% copied from wrlib in
+ * WindowMaker, Copyright (C) 1997-2000 Dan Pascu and Alfredo Kojima
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef META_GRADIENT_PRIVATE_H
+#define META_GRADIENT_PRIVATE_H
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gdk/gdk.h>
+
+#include "meta-gradient.h"
+
+G_BEGIN_DECLS
+
+G_GNUC_INTERNAL
+GdkPixbuf *meta_gradient_create_simple     (int               width,
+                                            int               height,
+                                            const GdkRGBA    *from,
+                                            const GdkRGBA    *to,
+                                            MetaGradientType  style);
+
+G_GNUC_INTERNAL
+GdkPixbuf *meta_gradient_create_multi      (int               width,
+                                            int               height,
+                                            const GdkRGBA    *colors,
+                                            int               n_colors,
+                                            MetaGradientType  style);
+
+G_GNUC_INTERNAL
+GdkPixbuf *meta_gradient_create_interwoven (int               width,
+                                            int               height,
+                                            const GdkRGBA     colors1[2],
+                                            int               thickness1,
+                                            const GdkRGBA     colors2[2],
+                                            int               thickness2);
+
+G_GNUC_INTERNAL
+void       meta_gradient_add_alpha         (GdkPixbuf        *pixbuf,
+                                            const guchar     *alphas,
+                                            int               n_alphas,
+                                            MetaGradientType  type);
+
+G_END_DECLS
+
+#endif
diff --git a/libmetacity/meta-gradient-spec.c b/libmetacity/meta-gradient-spec.c
new file mode 100644
index 0000000..dcf974f
--- /dev/null
+++ b/libmetacity/meta-gradient-spec.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2001 Havoc Pennington
+ * Copyright (C) 2016 Alberts Muktupāvels
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <glib/gi18n-lib.h>
+
+#include "meta-color-spec.h"
+#include "meta-gradient-private.h"
+#include "meta-gradient-spec.h"
+#include "meta-theme.h"
+
+struct _MetaGradientSpec
+{
+  MetaGradientType  type;
+  GSList           *color_specs;
+};
+
+struct _MetaAlphaGradientSpec
+{
+  MetaGradientType  type;
+  guchar           *alphas;
+  gint              n_alphas;
+};
+
+static void
+free_color_spec (gpointer spec,
+                 gpointer user_data)
+{
+  meta_color_spec_free (spec);
+}
+
+MetaGradientSpec *
+meta_gradient_spec_new (MetaGradientType type)
+{
+  MetaGradientSpec *spec;
+
+  spec = g_new (MetaGradientSpec, 1);
+
+  spec->type = type;
+  spec->color_specs = NULL;
+
+  return spec;
+}
+
+void
+meta_gradient_spec_free (MetaGradientSpec *spec)
+{
+  g_return_if_fail (spec != NULL);
+
+  g_slist_foreach (spec->color_specs, free_color_spec, NULL);
+  g_slist_free (spec->color_specs);
+
+  g_free (spec);
+}
+
+void
+meta_gradient_spec_add_color_spec (MetaGradientSpec *spec,
+                                   MetaColorSpec    *color_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)
+{
+  gint n_colors;
+  GdkRGBA *colors;
+  GSList *tmp;
+  gint i;
+  GdkPixbuf *pixbuf;
+
+  n_colors = g_slist_length (spec->color_specs);
+
+  if (n_colors == 0)
+    return NULL;
+
+  colors = g_new (GdkRGBA, n_colors);
+
+  i = 0;
+  tmp = spec->color_specs;
+  while (tmp != NULL)
+    {
+      meta_color_spec_render (tmp->data, context, &colors[i]);
+
+      tmp = tmp->next;
+      ++i;
+    }
+
+  pixbuf = meta_gradient_create_multi (width, height, colors,
+                                       n_colors, spec->type);
+
+  g_free (colors);
+
+  return pixbuf;
+}
+
+gboolean
+meta_gradient_spec_validate (MetaGradientSpec  *spec,
+                             GError           **error)
+{
+  g_return_val_if_fail (spec != NULL, FALSE);
+
+  if (g_slist_length (spec->color_specs) < 2)
+    {
+      g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
+                   _("Gradients should have at least two colors"));
+
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+MetaAlphaGradientSpec *
+meta_alpha_gradient_spec_new (MetaGradientType type,
+                              gint             n_alphas)
+{
+  MetaAlphaGradientSpec *spec;
+
+  g_return_val_if_fail (n_alphas > 0, NULL);
+
+  spec = g_new0 (MetaAlphaGradientSpec, 1);
+
+  spec->type = type;
+  spec->alphas = g_new0 (guchar, n_alphas);
+  spec->n_alphas = n_alphas;
+
+  return spec;
+}
+
+void
+meta_alpha_gradient_spec_free (MetaAlphaGradientSpec *spec)
+{
+  g_return_if_fail (spec != NULL);
+
+  g_free (spec->alphas);
+  g_free (spec);
+}
+
+void
+meta_alpha_gradient_spec_add_alpha (MetaAlphaGradientSpec *spec,
+                                    gint                   n_alpha,
+                                    gdouble                alpha)
+{
+  spec->alphas[n_alpha] = (guchar) (alpha * 255);
+}
+
+guchar
+meta_alpha_gradient_spec_get_alpha (MetaAlphaGradientSpec *spec,
+                                    gint                   n_alpha)
+{
+  return spec->alphas[n_alpha];
+}
+
+gboolean
+meta_alpha_gradient_spec_needs_alpha (MetaAlphaGradientSpec *spec)
+{
+  return spec && (spec->n_alphas > 1 || spec->alphas[0] != 0xff);
+}
+
+GdkPixbuf *
+meta_alpha_gradient_spec_apply_alpha (MetaAlphaGradientSpec *spec,
+                                      GdkPixbuf             *pixbuf,
+                                      gboolean               force_copy)
+{
+  GdkPixbuf *new_pixbuf;
+  gboolean needs_alpha;
+
+  g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
+
+  needs_alpha = meta_alpha_gradient_spec_needs_alpha (spec);
+
+  if (!needs_alpha)
+    return pixbuf;
+
+  if (!gdk_pixbuf_get_has_alpha (pixbuf))
+    {
+      new_pixbuf = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
+      g_object_unref (G_OBJECT (pixbuf));
+      pixbuf = new_pixbuf;
+    }
+  else if (force_copy)
+    {
+      new_pixbuf = gdk_pixbuf_copy (pixbuf);
+      g_object_unref (G_OBJECT (pixbuf));
+      pixbuf = new_pixbuf;
+    }
+
+  g_assert (gdk_pixbuf_get_has_alpha (pixbuf));
+
+  meta_gradient_add_alpha (pixbuf, spec->alphas, spec->n_alphas, spec->type);
+
+  return pixbuf;
+}
+
+GdkPixbuf *
+meta_alpha_gradient_spec_render (MetaAlphaGradientSpec *spec,
+                                 gint                   width,
+                                 gint                   height,
+                                 GdkRGBA                color)
+{
+  gboolean has_alpha;
+  GdkPixbuf *pixbuf;
+  guint32 rgba;
+
+  has_alpha = spec && (spec->n_alphas > 1 || spec->alphas[0] != 0xff);
+  pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, has_alpha, 8, width, height);
+
+  rgba = 0xff;
+  rgba |= (gint) (color.red * 255) << 24;
+  rgba |= (gint) (color.green * 255) << 16;
+  rgba |= (gint) (color.blue * 255) << 8;
+
+  if (!has_alpha)
+    {
+      gdk_pixbuf_fill (pixbuf, rgba);
+    }
+  else if (spec->n_alphas == 1)
+    {
+      rgba &= ~0xff;
+      rgba |= spec->alphas[0];
+
+      gdk_pixbuf_fill (pixbuf, rgba);
+    }
+  else
+    {
+      gdk_pixbuf_fill (pixbuf, rgba);
+
+      meta_gradient_add_alpha (pixbuf, spec->alphas, spec->n_alphas,
+                               spec->type);
+    }
+
+  return pixbuf;
+}
diff --git a/libmetacity/meta-gradient-spec.h b/libmetacity/meta-gradient-spec.h
new file mode 100644
index 0000000..bae2d7e
--- /dev/null
+++ b/libmetacity/meta-gradient-spec.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2001 Havoc Pennington
+ * Copyright (C) 2016 Alberts Muktupāvels
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef META_GRADIENT_SPEC_H
+#define META_GRADIENT_SPEC_H
+
+#include <gtk/gtk.h>
+#include <libmetacity/meta-gradient.h>
+
+G_BEGIN_DECLS
+
+typedef struct _MetaAlphaGradientSpec MetaAlphaGradientSpec;
+typedef struct _MetaGradientSpec MetaGradientSpec;
+
+MetaGradientSpec      *meta_gradient_spec_new               (MetaGradientType         type);
+
+void                   meta_gradient_spec_free              (MetaGradientSpec        *spec);
+
+void                   meta_gradient_spec_add_color_spec    (MetaGradientSpec        *spec,
+                                                             MetaColorSpec           *color_spec);
+
+GdkPixbuf             *meta_gradient_spec_render            (const MetaGradientSpec  *spec,
+                                                             GtkStyleContext         *context,
+                                                             gint                     width,
+                                                             gint                     height);
+
+gboolean               meta_gradient_spec_validate          (MetaGradientSpec        *spec,
+                                                             GError                 **error);
+
+MetaAlphaGradientSpec *meta_alpha_gradient_spec_new         (MetaGradientType         type,
+                                                             gint                     n_alphas);
+
+void                   meta_alpha_gradient_spec_free        (MetaAlphaGradientSpec   *spec);
+
+void                   meta_alpha_gradient_spec_add_alpha   (MetaAlphaGradientSpec   *spec,
+                                                             gint                     n_alpha,
+                                                             gdouble                  alpha);
+
+guchar                 meta_alpha_gradient_spec_get_alpha   (MetaAlphaGradientSpec   *spec,
+                                                             gint                     n_alpha);
+
+gboolean               meta_alpha_gradient_spec_needs_alpha (MetaAlphaGradientSpec   *spec);
+
+GdkPixbuf             *meta_alpha_gradient_spec_apply_alpha (MetaAlphaGradientSpec   *spec,
+                                                             GdkPixbuf               *pixbuf,
+                                                             gboolean                 force_copy);
+
+GdkPixbuf             *meta_alpha_gradient_spec_render      (MetaAlphaGradientSpec   *spec,
+                                                             gint                     width,
+                                                             gint                     height,
+                                                             GdkRGBA                  color);
+
+G_END_DECLS
+
+#endif
diff --git a/libmetacity/meta-gradient.c b/libmetacity/meta-gradient.c
index cef707d..c1965cd 100644
--- a/libmetacity/meta-gradient.c
+++ b/libmetacity/meta-gradient.c
@@ -27,7 +27,7 @@
 
 #include <string.h>
 
-#include "meta-gradient.h"
+#include "meta-gradient-private.h"
 
 static void
 free_buffer (guchar   *pixels,
diff --git a/libmetacity/meta-gradient.h b/libmetacity/meta-gradient.h
index 7d7588b..a0af8fd 100644
--- a/libmetacity/meta-gradient.h
+++ b/libmetacity/meta-gradient.h
@@ -19,8 +19,9 @@
 #ifndef META_GRADIENT_H
 #define META_GRADIENT_H
 
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <gdk/gdk.h>
+#include <glib.h>
+
+G_BEGIN_DECLS
 
 /**
  * MetaGradientType:
@@ -38,27 +39,6 @@ typedef enum
   META_GRADIENT_LAST
 } MetaGradientType;
 
-GdkPixbuf *meta_gradient_create_simple     (int               width,
-                                            int               height,
-                                            const GdkRGBA    *from,
-                                            const GdkRGBA    *to,
-                                            MetaGradientType  style);
-
-GdkPixbuf *meta_gradient_create_multi      (int               width,
-                                            int               height,
-                                            const GdkRGBA    *colors,
-                                            int               n_colors,
-                                            MetaGradientType  style);
-
-GdkPixbuf *meta_gradient_create_interwoven (int               width,
-                                            int               height,
-                                            const GdkRGBA     colors1[2],
-                                            int               thickness1,
-                                            const GdkRGBA     colors2[2],
-                                            int               thickness2);
+G_END_DECLS
 
-void       meta_gradient_add_alpha         (GdkPixbuf        *pixbuf,
-                                            const guchar     *alphas,
-                                            int               n_alphas,
-                                            MetaGradientType  type);
 #endif
diff --git a/po/POTFILES.in b/po/POTFILES.in
index d768852..34ecd38 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,6 +1,7 @@
 # List of source files containing translatable strings.
 # Please keep this file sorted alphabetically.
 libmetacity/meta-color-spec.c
+libmetacity/meta-gradient-spec.c
 src/50-metacity-navigation.xml.in
 src/50-metacity-system.xml.in
 src/50-metacity-windows.xml.in
diff --git a/src/ui/testgradient.c b/src/ui/testgradient.c
index 59f3cb3..759775a 100644
--- a/src/ui/testgradient.c
+++ b/src/ui/testgradient.c
@@ -20,6 +20,7 @@
 
 #include <gtk/gtk.h>
 #include <libmetacity/meta-gradient.h>
+#include <libmetacity/meta-gradient-private.h>
 
 typedef void (* RenderGradientFunc) (cairo_t     *cr,
                                      int          width,
diff --git a/src/ui/theme-parser.c b/src/ui/theme-parser.c
index ac29178..7b9e290 100644
--- a/src/ui/theme-parser.c
+++ b/src/ui/theme-parser.c
@@ -793,7 +793,7 @@ parse_alpha (const char             *str,
           return FALSE;
         }
 
-      spec->alphas[i] = (unsigned char) (v * 255);
+      meta_alpha_gradient_spec_add_alpha (spec, i, v);
 
       ++i;
     }
@@ -1160,7 +1160,6 @@ parse_toplevel_element (GMarkupParseContext  *context,
 
           if (alpha != NULL)
             {
-
                gboolean success;
                MetaAlphaGradientSpec *alpha_vector;
 
@@ -1174,7 +1173,7 @@ parse_toplevel_element (GMarkupParseContext  *context,
                  return;
 
                /* alpha_vector->alphas must contain at least one element */
-               info->style->window_background_alpha = alpha_vector->alphas[0];
+               info->style->window_background_alpha = meta_alpha_gradient_spec_get_alpha (alpha_vector, 0);
 
                meta_alpha_gradient_spec_free (alpha_vector);
             }
@@ -2722,9 +2721,9 @@ parse_gradient_element (GMarkupParseContext  *context,
       g_assert (info->op);
       g_assert (info->op->type == META_DRAW_GRADIENT);
       g_assert (info->op->data.gradient.gradient_spec != NULL);
-      info->op->data.gradient.gradient_spec->color_specs =
-        g_slist_append (info->op->data.gradient.gradient_spec->color_specs,
-                        color_spec);
+
+      meta_gradient_spec_add_color_spec (info->op->data.gradient.gradient_spec,
+                                         color_spec);
 
       push_state (info, STATE_COLOR);
     }
@@ -3768,23 +3767,6 @@ meta_theme_validate (MetaTheme *theme,
   return TRUE;
 }
 
-static gboolean
-meta_gradient_spec_validate (MetaGradientSpec *spec,
-                             GError          **error)
-{
-  g_return_val_if_fail (spec != NULL, FALSE);
-
-  if (g_slist_length (spec->color_specs) < 2)
-    {
-      g_set_error (error, META_THEME_ERROR,
-                   META_THEME_ERROR_FAILED,
-                   _("Gradients should have at least two colors"));
-      return FALSE;
-    }
-
-  return TRUE;
-}
-
 static void
 end_element_handler (GMarkupParseContext *context,
                      const gchar         *element_name,
diff --git a/src/ui/theme-private.h b/src/ui/theme-private.h
index 05649fc..1586655 100644
--- a/src/ui/theme-private.h
+++ b/src/ui/theme-private.h
@@ -19,14 +19,13 @@
 #define META_THEME_PRIVATE_H
 
 #include <libmetacity/meta-color-spec.h>
-#include <libmetacity/meta-gradient.h>
+#include <libmetacity/meta-gradient-spec.h>
 
 #include "boxes.h"
 #include "theme.h"
 
 G_BEGIN_DECLS
 
-typedef struct _MetaAlphaGradientSpec MetaAlphaGradientSpec;
 typedef struct _MetaDrawInfo MetaDrawInfo;
 typedef struct _MetaDrawOp MetaDrawOp;
 typedef struct _MetaDrawOpList MetaDrawOpList;
@@ -34,7 +33,6 @@ typedef struct _MetaDrawSpec MetaDrawSpec;
 typedef struct _MetaFrameLayout MetaFrameLayout;
 typedef struct _MetaFrameStyle MetaFrameStyle;
 typedef struct _MetaFrameStyleSet MetaFrameStyleSet;
-typedef struct _MetaGradientSpec MetaGradientSpec;
 typedef struct _MetaPositionExprEnv MetaPositionExprEnv;
 
 /**
@@ -550,19 +548,6 @@ struct _MetaDrawOpList
   int n_allocated;
 };
 
-struct _MetaGradientSpec
-{
-  MetaGradientType type;
-  GSList *color_specs;
-};
-
-struct _MetaAlphaGradientSpec
-{
-  MetaGradientType type;
-  unsigned char *alphas;
-  int n_alphas;
-};
-
 /**
  * How to draw a frame in a particular state (say, a focussed, non-maximised,
  * resizable frame). This corresponds closely to the <frame_style> tag
@@ -711,17 +696,6 @@ gboolean               meta_draw_op_list_validate              (MetaDrawOpList
 gboolean               meta_draw_op_list_contains              (MetaDrawOpList              *op_list,
                                                                 MetaDrawOpList              *child);
 
-MetaGradientSpec      *meta_gradient_spec_new                  (MetaGradientType             type);
-void                   meta_gradient_spec_free                 (MetaGradientSpec            *desc);
-GdkPixbuf             *meta_gradient_spec_render               (const MetaGradientSpec      *desc,
-                                                                GtkStyleContext             *widget,
-                                                                int                          width,
-                                                                int                          height);
-
-MetaAlphaGradientSpec *meta_alpha_gradient_spec_new            (MetaGradientType             type,
-                                                                int                          n_alphas);
-void                   meta_alpha_gradient_spec_free           (MetaAlphaGradientSpec       *spec);
-
 MetaFrameStyle        *meta_frame_style_new                    (MetaFrameStyle              *parent);
 void                   meta_frame_style_ref                    (MetaFrameStyle              *style);
 void                   meta_frame_style_unref                  (MetaFrameStyle              *style);
diff --git a/src/ui/theme.c b/src/ui/theme.c
index 540d09d..2cdd3c2 100644
--- a/src/ui/theme.c
+++ b/src/ui/theme.c
@@ -1156,101 +1156,6 @@ meta_frame_layout_calc_geometry (MetaFrameLayout        *layout,
     fgeom->bottom_right_corner_rounded_radius = layout->bottom_right_corner_rounded_radius;
 }
 
-MetaGradientSpec*
-meta_gradient_spec_new (MetaGradientType type)
-{
-  MetaGradientSpec *spec;
-
-  spec = g_new (MetaGradientSpec, 1);
-
-  spec->type = type;
-  spec->color_specs = NULL;
-
-  return spec;
-}
-
-static void
-free_color_spec (gpointer spec, gpointer user_data)
-{
-  meta_color_spec_free (spec);
-}
-
-void
-meta_gradient_spec_free (MetaGradientSpec *spec)
-{
-  g_return_if_fail (spec != NULL);
-
-  g_slist_foreach (spec->color_specs, free_color_spec, NULL);
-  g_slist_free (spec->color_specs);
-
-  DEBUG_FILL_STRUCT (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);
-
-  i = 0;
-  tmp = spec->color_specs;
-  while (tmp != NULL)
-    {
-      meta_color_spec_render (tmp->data, style, &colors[i]);
-
-      tmp = tmp->next;
-      ++i;
-    }
-
-  pixbuf = meta_gradient_create_multi (width, height,
-                                       colors, n_colors,
-                                       spec->type);
-
-  g_free (colors);
-
-  return pixbuf;
-}
-
-MetaAlphaGradientSpec*
-meta_alpha_gradient_spec_new (MetaGradientType       type,
-                              int                    n_alphas)
-{
-  MetaAlphaGradientSpec *spec;
-
-  g_return_val_if_fail (n_alphas > 0, NULL);
-
-  spec = g_new0 (MetaAlphaGradientSpec, 1);
-
-  spec->type = type;
-  spec->alphas = g_new0 (unsigned char, n_alphas);
-  spec->n_alphas = n_alphas;
-
-  return spec;
-}
-
-void
-meta_alpha_gradient_spec_free (MetaAlphaGradientSpec *spec)
-{
-  g_return_if_fail (spec != NULL);
-
-  g_free (spec->alphas);
-  g_free (spec);
-}
-
 /**
  * Represents an operation as a string.
  *
@@ -2665,42 +2570,6 @@ meta_draw_op_free (MetaDrawOp *op)
 }
 
 static GdkPixbuf*
-apply_alpha (GdkPixbuf             *pixbuf,
-             MetaAlphaGradientSpec *spec,
-             gboolean               force_copy)
-{
-  GdkPixbuf *new_pixbuf;
-  gboolean needs_alpha;
-
-  g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
-
-  needs_alpha = spec && (spec->n_alphas > 1 ||
-                         spec->alphas[0] != 0xff);
-
-  if (!needs_alpha)
-    return pixbuf;
-
-  if (!gdk_pixbuf_get_has_alpha (pixbuf))
-    {
-      new_pixbuf = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
-      g_object_unref (G_OBJECT (pixbuf));
-      pixbuf = new_pixbuf;
-    }
-  else if (force_copy)
-    {
-      new_pixbuf = gdk_pixbuf_copy (pixbuf);
-      g_object_unref (G_OBJECT (pixbuf));
-      pixbuf = new_pixbuf;
-    }
-
-  g_assert (gdk_pixbuf_get_has_alpha (pixbuf));
-
-  meta_gradient_add_alpha (pixbuf, spec->alphas, spec->n_alphas, spec->type);
-
-  return pixbuf;
-}
-
-static GdkPixbuf*
 pixbuf_tile (GdkPixbuf *tile,
              int        width,
              int        height)
@@ -2914,7 +2783,7 @@ scale_and_alpha_pixbuf (GdkPixbuf             *src,
     }
 
   if (pixbuf)
-    pixbuf = apply_alpha (pixbuf, alpha_spec, pixbuf == src);
+    pixbuf = meta_alpha_gradient_spec_apply_alpha (alpha_spec, pixbuf, pixbuf == src);
 
   return pixbuf;
 }
@@ -2965,47 +2834,12 @@ draw_op_as_pixbuf (const MetaDrawOp    *op,
     case META_DRAW_TINT:
       {
         GdkRGBA color;
-        guint32 rgba;
-        gboolean has_alpha;
 
         meta_color_spec_render (op->data.rectangle.color_spec,
-                                context,
-                                &color);
+                                context, &color);
 
-        has_alpha =
-          op->data.tint.alpha_spec &&
-          (op->data.tint.alpha_spec->n_alphas > 1 ||
-           op->data.tint.alpha_spec->alphas[0] != 0xff);
-
-        pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
-                                 has_alpha,
-                                 8, width, height);
-
-        if (!has_alpha)
-          {
-            rgba = GDK_COLOR_RGBA (color);
-
-            gdk_pixbuf_fill (pixbuf, rgba);
-          }
-        else if (op->data.tint.alpha_spec->n_alphas == 1)
-          {
-            rgba = GDK_COLOR_RGBA (color);
-            rgba &= ~0xff;
-            rgba |= op->data.tint.alpha_spec->alphas[0];
-
-            gdk_pixbuf_fill (pixbuf, rgba);
-          }
-        else
-          {
-            rgba = GDK_COLOR_RGBA (color);
-
-            gdk_pixbuf_fill (pixbuf, rgba);
-
-            meta_gradient_add_alpha (pixbuf,
-                                     op->data.tint.alpha_spec->alphas,
-                                     op->data.tint.alpha_spec->n_alphas,
-                                     op->data.tint.alpha_spec->type);
-          }
+        pixbuf = meta_alpha_gradient_spec_render (op->data.tint.alpha_spec,
+                                                  width, height, color);
       }
       break;
 
@@ -3014,13 +2848,11 @@ draw_op_as_pixbuf (const MetaDrawOp    *op,
         pixbuf = meta_gradient_spec_render (op->data.gradient.gradient_spec,
                                             context, width, height);
 
-        pixbuf = apply_alpha (pixbuf,
-                              op->data.gradient.alpha_spec,
-                              FALSE);
+        pixbuf = meta_alpha_gradient_spec_apply_alpha (op->data.gradient.alpha_spec,
+                                                       pixbuf, FALSE);
       }
       break;
 
-
     case META_DRAW_IMAGE:
       {
        if (op->data.image.colorize_spec)
@@ -3322,9 +3154,7 @@ meta_draw_op_draw_with_env (const MetaDrawOp    *op,
         int rx, ry, rwidth, rheight;
         gboolean needs_alpha;
 
-        needs_alpha = op->data.tint.alpha_spec &&
-          (op->data.tint.alpha_spec->n_alphas > 1 ||
-           op->data.tint.alpha_spec->alphas[0] != 0xff);
+        needs_alpha = meta_alpha_gradient_spec_needs_alpha (op->data.tint.alpha_spec);
 
         rx = parse_x_position_unchecked (op->data.tint.x, env);
         ry = parse_y_position_unchecked (op->data.tint.y, env);


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