[gtk: 9/40] Break out cairo color matrix recoloring to gdk_cairo_image_surface_recolor()



commit afa6cc23692f83f0d38de24c9cf58a7a494c01d2
Author: Alexander Larsson <alexl redhat com>
Date:   Tue Jan 28 11:42:24 2020 +0100

    Break out cairo color matrix recoloring to gdk_cairo_image_surface_recolor()
    
    This is useful in some parts of the icon theme APIs.

 gdk/gdkcairo.c          | 59 +++++++++++++++++++++++++++++++++++++++++++++++++
 gdk/gdkcairo.h          |  6 +++++
 gsk/gskrendernodeimpl.c | 53 +++-----------------------------------------
 3 files changed, 68 insertions(+), 50 deletions(-)
---
diff --git a/gdk/gdkcairo.c b/gdk/gdkcairo.c
index c5917cfeb9..94accf847b 100644
--- a/gdk/gdkcairo.c
+++ b/gdk/gdkcairo.c
@@ -456,3 +456,62 @@ gdk_cairo_region_from_clip (cairo_t *cr)
 
   return region;
 }
+
+void
+gdk_cairo_image_surface_recolor (cairo_surface_t *image_surface,
+                                 const graphene_matrix_t *color_matrix,
+                                 const graphene_vec4_t *color_offset)
+{
+  graphene_vec4_t pixel;
+  guint32* pixel_data;
+  guchar *data;
+  gsize x, y, width, height, stride;
+  float alpha;
+
+  data = cairo_image_surface_get_data (image_surface);
+  width = cairo_image_surface_get_width (image_surface);
+  height = cairo_image_surface_get_height (image_surface);
+  stride = cairo_image_surface_get_stride (image_surface);
+
+  for (y = 0; y < height; y++)
+    {
+      pixel_data = (guint32 *) data;
+      for (x = 0; x < width; x++)
+        {
+          alpha = ((pixel_data[x] >> 24) & 0xFF) / 255.0;
+
+          if (alpha == 0)
+            {
+              graphene_vec4_init (&pixel, 0.0, 0.0, 0.0, 0.0);
+            }
+          else
+            {
+              graphene_vec4_init (&pixel,
+                                  ((pixel_data[x] >> 16) & 0xFF) / (255.0 * alpha),
+                                  ((pixel_data[x] >>  8) & 0xFF) / (255.0 * alpha),
+                                  ( pixel_data[x]        & 0xFF) / (255.0 * alpha),
+                                  alpha);
+              graphene_matrix_transform_vec4 (color_matrix, &pixel, &pixel);
+            }
+
+          graphene_vec4_add (&pixel, color_offset, &pixel);
+
+          alpha = graphene_vec4_get_w (&pixel);
+          if (alpha > 0.0)
+            {
+              alpha = MIN (alpha, 1.0);
+              pixel_data[x] = (((guint32) roundf (alpha * 255)) << 24) |
+                              (((guint32) roundf (CLAMP (graphene_vec4_get_x (&pixel), 0, 1) * alpha * 255)) 
<< 16) |
+                              (((guint32) roundf (CLAMP (graphene_vec4_get_y (&pixel), 0, 1) * alpha * 255)) 
<<  8) |
+                               ((guint32) roundf (CLAMP (graphene_vec4_get_z (&pixel), 0, 1) * alpha * 255));
+            }
+          else
+            {
+              pixel_data[x] = 0;
+            }
+        }
+      data += stride;
+    }
+
+  cairo_surface_mark_dirty (image_surface);
+}
diff --git a/gdk/gdkcairo.h b/gdk/gdkcairo.h
index c4e2d3836c..52a6abdef3 100644
--- a/gdk/gdkcairo.h
+++ b/gdk/gdkcairo.h
@@ -26,6 +26,7 @@
 #include <gdk/gdkrgba.h>
 #include <gdk/gdkpixbuf.h>
 #include <pango/pangocairo.h>
+#include <graphene.h>
 
 G_BEGIN_DECLS
 
@@ -72,6 +73,11 @@ void      gdk_cairo_surface_upload_to_gl (cairo_surface_t *surface,
                                           int              height,
                                           GdkGLContext    *context);
 
+GDK_AVAILABLE_IN_ALL
+void      gdk_cairo_image_surface_recolor (cairo_surface_t *image_surface,
+                                           const graphene_matrix_t *color_matrix,
+                                           const graphene_vec4_t *color_offset);
+
 G_END_DECLS
 
 #endif /* __GDK_CAIRO_H__ */
diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c
index 2434c5d40e..f82343054b 100644
--- a/gsk/gskrendernodeimpl.c
+++ b/gsk/gskrendernodeimpl.c
@@ -2339,11 +2339,6 @@ gsk_color_matrix_node_draw (GskRenderNode *node,
   GskColorMatrixNode *self = (GskColorMatrixNode *) node;
   cairo_pattern_t *pattern;
   cairo_surface_t *surface, *image_surface;
-  graphene_vec4_t pixel;
-  guint32* pixel_data;
-  guchar *data;
-  gsize x, y, width, height, stride;
-  float alpha;
 
   cairo_save (cr);
 
@@ -2360,52 +2355,10 @@ gsk_color_matrix_node_draw (GskRenderNode *node,
   cairo_pattern_get_surface (pattern, &surface);
   image_surface = cairo_surface_map_to_image (surface, NULL);
 
-  data = cairo_image_surface_get_data (image_surface);
-  width = cairo_image_surface_get_width (image_surface);
-  height = cairo_image_surface_get_height (image_surface);
-  stride = cairo_image_surface_get_stride (image_surface);
+  gdk_cairo_image_surface_recolor (image_surface,
+                                   &self->color_matrix,
+                                   &self->color_offset);
 
-  for (y = 0; y < height; y++)
-    {
-      pixel_data = (guint32 *) data;
-      for (x = 0; x < width; x++)
-        {
-          alpha = ((pixel_data[x] >> 24) & 0xFF) / 255.0;
-
-          if (alpha == 0)
-            {
-              graphene_vec4_init (&pixel, 0.0, 0.0, 0.0, 0.0);
-            }
-          else
-            {
-              graphene_vec4_init (&pixel,
-                                  ((pixel_data[x] >> 16) & 0xFF) / (255.0 * alpha),
-                                  ((pixel_data[x] >>  8) & 0xFF) / (255.0 * alpha),
-                                  ( pixel_data[x]        & 0xFF) / (255.0 * alpha),
-                                  alpha);
-              graphene_matrix_transform_vec4 (&self->color_matrix, &pixel, &pixel);
-            }
-
-          graphene_vec4_add (&pixel, &self->color_offset, &pixel);
-
-          alpha = graphene_vec4_get_w (&pixel);
-          if (alpha > 0.0)
-            {
-              alpha = MIN (alpha, 1.0);
-              pixel_data[x] = (((guint32) roundf (alpha * 255)) << 24) |
-                              (((guint32) roundf (CLAMP (graphene_vec4_get_x (&pixel), 0, 1) * alpha * 255)) 
<< 16) |
-                              (((guint32) roundf (CLAMP (graphene_vec4_get_y (&pixel), 0, 1) * alpha * 255)) 
<<  8) |
-                               ((guint32) roundf (CLAMP (graphene_vec4_get_z (&pixel), 0, 1) * alpha * 255));
-            }
-          else
-            {
-              pixel_data[x] = 0;
-            }
-        }
-      data += stride;
-    }
-
-  cairo_surface_mark_dirty (image_surface);
   cairo_surface_unmap_image (surface, image_surface);
 
   cairo_set_source (cr, pattern);


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