[metacity] libmetacity: use cairo to apply alpha



commit 3f320e26af922a7d88b2486075a716481987ca2a
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Thu Jul 7 22:12:50 2016 +0300

    libmetacity: use cairo to apply alpha

 libmetacity/Makefile.am                  |    2 -
 libmetacity/meta-draw-op.c               |  103 ++++++++------
 libmetacity/meta-gradient-private.h      |   51 -------
 libmetacity/meta-gradient-spec-private.h |   26 +++-
 libmetacity/meta-gradient-spec.c         |   68 +++++-----
 libmetacity/meta-gradient.c              |  218 ------------------------------
 6 files changed, 111 insertions(+), 357 deletions(-)
---
diff --git a/libmetacity/Makefile.am b/libmetacity/Makefile.am
index e2d0f48..6d4b573 100644
--- a/libmetacity/Makefile.am
+++ b/libmetacity/Makefile.am
@@ -26,8 +26,6 @@ libmetacity_la_SOURCES = \
        meta-frame-layout-private.h \
        meta-frame-style.c \
        meta-frame-style-private.h \
-       meta-gradient.c \
-       meta-gradient-private.h \
        meta-gradient-spec.c \
        meta-gradient-spec-private.h \
        meta-hsla.c \
diff --git a/libmetacity/meta-draw-op.c b/libmetacity/meta-draw-op.c
index e3740ed..48798b6 100644
--- a/libmetacity/meta-draw-op.c
+++ b/libmetacity/meta-draw-op.c
@@ -24,12 +24,6 @@
 #include "meta-draw-op-private.h"
 #include "meta-theme-impl-private.h"
 
-#define GDK_COLOR_RGBA(color)                            \
-        ((guint32) (0xff                               | \
-                    ((int)((color).red * 255) << 24)   | \
-                    ((int)((color).green * 255) << 16) | \
-                    ((int)((color).blue * 255) << 8)))
-
 #define GDK_COLOR_RGB(color)                             \
         ((guint32) (((int)((color).red * 255) << 16)   | \
                     ((int)((color).green * 255) << 8)  | \
@@ -210,18 +204,15 @@ replicate_cols (GdkPixbuf  *src,
 }
 
 static GdkPixbuf*
-scale_and_alpha_pixbuf (GdkPixbuf             *src,
-                        MetaAlphaGradientSpec *alpha_spec,
-                        MetaImageFillType      fill_type,
-                        int                    width,
-                        int                    height,
-                        gboolean               vertical_stripes,
-                        gboolean               horizontal_stripes)
+scale_pixbuf (GdkPixbuf             *src,
+              MetaAlphaGradientSpec *alpha_spec,
+              MetaImageFillType      fill_type,
+              gint                   width,
+              gint                   height,
+              gboolean               vertical_stripes,
+              gboolean               horizontal_stripes)
 {
   GdkPixbuf *pixbuf;
-  GdkPixbuf *temp_pixbuf;
-
-  pixbuf = NULL;
 
   pixbuf = src;
 
@@ -238,6 +229,7 @@ scale_and_alpha_pixbuf (GdkPixbuf             *src,
         }
       else
         {
+          GdkPixbuf *temp_pixbuf;
           int src_h, src_w, dest_h, dest_w;
           src_h = gdk_pixbuf_get_height (src);
           src_w = gdk_pixbuf_get_width (src);
@@ -294,9 +286,6 @@ scale_and_alpha_pixbuf (GdkPixbuf             *src,
         }
     }
 
-  if (pixbuf)
-    pixbuf = meta_alpha_gradient_spec_apply_alpha (alpha_spec, pixbuf, pixbuf == src);
-
   return pixbuf;
 }
 
@@ -420,22 +409,22 @@ draw_op_as_pixbuf (const MetaDrawOp   *op,
 
             if (op->data.image.colorize_cache_pixbuf)
               {
-                pixbuf = scale_and_alpha_pixbuf (op->data.image.colorize_cache_pixbuf,
-                                                 op->data.image.alpha_spec,
-                                                 op->data.image.fill_type,
-                                                 width, height,
-                                                 op->data.image.vertical_stripes,
-                                                 op->data.image.horizontal_stripes);
+                pixbuf = scale_pixbuf (op->data.image.colorize_cache_pixbuf,
+                                       op->data.image.alpha_spec,
+                                       op->data.image.fill_type,
+                                       width, height,
+                                       op->data.image.vertical_stripes,
+                                       op->data.image.horizontal_stripes);
               }
          }
        else
          {
-           pixbuf = scale_and_alpha_pixbuf (op->data.image.pixbuf,
-                                             op->data.image.alpha_spec,
-                                             op->data.image.fill_type,
-                                             width, height,
-                                             op->data.image.vertical_stripes,
-                                             op->data.image.horizontal_stripes);
+           pixbuf = scale_pixbuf (op->data.image.pixbuf,
+                                  op->data.image.alpha_spec,
+                                  op->data.image.fill_type,
+                                  width, height,
+                                  op->data.image.vertical_stripes,
+                                  op->data.image.horizontal_stripes);
          }
         break;
       }
@@ -444,17 +433,13 @@ draw_op_as_pixbuf (const MetaDrawOp   *op,
       if (info->mini_icon &&
           width <= gdk_pixbuf_get_width (info->mini_icon) &&
           height <= gdk_pixbuf_get_height (info->mini_icon))
-        pixbuf = scale_and_alpha_pixbuf (info->mini_icon,
-                                         op->data.icon.alpha_spec,
-                                         op->data.icon.fill_type,
-                                         width, height,
-                                         FALSE, FALSE);
+        pixbuf = scale_pixbuf (info->mini_icon, op->data.icon.alpha_spec,
+                               op->data.icon.fill_type, width, height,
+                               FALSE, FALSE);
       else if (info->icon)
-        pixbuf = scale_and_alpha_pixbuf (info->icon,
-                                         op->data.icon.alpha_spec,
-                                         op->data.icon.fill_type,
-                                         width, height,
-                                         FALSE, FALSE);
+        pixbuf = scale_pixbuf (info->icon, op->data.icon.alpha_spec,
+                               op->data.icon.fill_type, width, height,
+                               FALSE, FALSE);
       break;
 
     case META_DRAW_TINT:
@@ -705,7 +690,23 @@ draw_op_draw_with_env (const MetaDrawOp    *op,
             ry = meta_draw_spec_parse_y_position (op->data.image.y, env);
 
             gdk_cairo_set_source_pixbuf (cr, pixbuf, rx, ry);
-            cairo_paint (cr);
+
+            if (op->data.image.alpha_spec)
+              {
+                cairo_pattern_t *pattern;
+
+                cairo_translate (cr, rx, ry);
+                cairo_scale (cr, rwidth, rheight);
+
+                pattern = meta_alpha_gradient_spec_get_mask (op->data.image.alpha_spec);
+                cairo_mask (cr, pattern);
+
+                cairo_pattern_destroy (pattern);
+              }
+            else
+              {
+                cairo_paint (cr);
+              }
 
             g_object_unref (G_OBJECT (pixbuf));
           }
@@ -793,7 +794,23 @@ draw_op_draw_with_env (const MetaDrawOp    *op,
             ry = meta_draw_spec_parse_y_position (op->data.icon.y, env);
 
             gdk_cairo_set_source_pixbuf (cr, pixbuf, rx, ry);
-            cairo_paint (cr);
+
+            if (op->data.icon.alpha_spec)
+              {
+                cairo_pattern_t *pattern;
+
+                cairo_translate (cr, rx, ry);
+                cairo_scale (cr, rwidth, rheight);
+
+                pattern = meta_alpha_gradient_spec_get_mask (op->data.icon.alpha_spec);
+                cairo_mask (cr, pattern);
+
+                cairo_pattern_destroy (pattern);
+              }
+            else
+              {
+                cairo_paint (cr);
+              }
 
             g_object_unref (G_OBJECT (pixbuf));
           }
diff --git a/libmetacity/meta-gradient-spec-private.h b/libmetacity/meta-gradient-spec-private.h
index a07240f..9667db8 100644
--- a/libmetacity/meta-gradient-spec-private.h
+++ b/libmetacity/meta-gradient-spec-private.h
@@ -21,13 +21,27 @@
 
 #include <gtk/gtk.h>
 
-#include "meta-gradient-private.h"
-
 G_BEGIN_DECLS
 
 typedef struct _MetaAlphaGradientSpec MetaAlphaGradientSpec;
 typedef struct _MetaGradientSpec MetaGradientSpec;
 
+/**
+ * MetaGradientType:
+ * @META_GRADIENT_VERTICAL: Vertical gradient
+ * @META_GRADIENT_HORIZONTAL: Horizontal gradient
+ * @META_GRADIENT_DIAGONAL: Diagonal gradient
+ * @META_GRADIENT_LAST: Marks the end of the #MetaGradientType enumeration
+ *
+ */
+typedef enum
+{
+  META_GRADIENT_VERTICAL,
+  META_GRADIENT_HORIZONTAL,
+  META_GRADIENT_DIAGONAL,
+  META_GRADIENT_LAST
+} MetaGradientType;
+
 G_GNUC_INTERNAL
 MetaGradientSpec      *meta_gradient_spec_new               (MetaGradientType         type);
 
@@ -69,11 +83,6 @@ guchar                 meta_alpha_gradient_spec_get_alpha   (MetaAlphaGradientSp
                                                              gint                     n_alpha);
 
 G_GNUC_INTERNAL
-GdkPixbuf             *meta_alpha_gradient_spec_apply_alpha (MetaAlphaGradientSpec   *spec,
-                                                             GdkPixbuf               *pixbuf,
-                                                             gboolean                 force_copy);
-
-G_GNUC_INTERNAL
 void                   meta_alpha_gradient_spec_render      (MetaAlphaGradientSpec   *spec,
                                                              GdkRGBA                  color,
                                                              cairo_t                 *cr,
@@ -82,6 +91,9 @@ void                   meta_alpha_gradient_spec_render      (MetaAlphaGradientSp
                                                              gint                     width,
                                                              gint                     height);
 
+G_GNUC_INTERNAL
+cairo_pattern_t       *meta_alpha_gradient_spec_get_mask    (const MetaAlphaGradientSpec  *spec);
+
 G_END_DECLS
 
 #endif
diff --git a/libmetacity/meta-gradient-spec.c b/libmetacity/meta-gradient-spec.c
index dd4b48e..36ffafe 100644
--- a/libmetacity/meta-gradient-spec.c
+++ b/libmetacity/meta-gradient-spec.c
@@ -21,7 +21,6 @@
 #include <glib/gi18n-lib.h>
 
 #include "meta-color-spec-private.h"
-#include "meta-gradient-private.h"
 #include "meta-gradient-spec-private.h"
 #include "meta-theme.h"
 
@@ -220,41 +219,6 @@ meta_alpha_gradient_spec_get_alpha (MetaAlphaGradientSpec *spec,
   return spec->alphas[n_alpha];
 }
 
-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 = 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;
-}
-
 void
 meta_alpha_gradient_spec_render (MetaAlphaGradientSpec *spec,
                                  GdkRGBA                color,
@@ -309,3 +273,35 @@ meta_alpha_gradient_spec_render (MetaAlphaGradientSpec *spec,
       cairo_restore (cr);
     }
 }
+
+cairo_pattern_t *
+meta_alpha_gradient_spec_get_mask (const MetaAlphaGradientSpec *spec)
+{
+  gint n_alphas;
+  cairo_pattern_t *pattern;
+  gint i;
+
+  /* Hardcoded in meta-theme-metacity.c */
+  g_assert (spec->type == META_GRADIENT_HORIZONTAL);
+
+  n_alphas = spec->n_alphas;
+  if (n_alphas == 0)
+    return NULL;
+
+  if (n_alphas == 1)
+    return cairo_pattern_create_rgba (0, 0, 0, spec->alphas[0] / 255.0);
+
+  pattern = cairo_pattern_create_linear (0, 0, 1, 0);
+
+  for (i = 0; i < n_alphas; i++)
+    cairo_pattern_add_color_stop_rgba (pattern, i / (gfloat) (n_alphas - 1),
+                                       0, 0, 0, spec->alphas[i] / 255.0);
+
+  if (cairo_pattern_status (pattern) != CAIRO_STATUS_SUCCESS)
+    {
+      cairo_pattern_destroy (pattern);
+      return NULL;
+    }
+
+  return pattern;
+}


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