[gtk/matthiasc/color-profile-rebased: 60/66] gdk: Introduce GdkColor




commit 3241a8d3dd3ee9ad192d8b067578b9fba4359c18
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu May 12 18:17:21 2022 -0400

    gdk: Introduce GdkColor
    
    GdkColor represents a color in the real world, by combining a color
    profile, an alpha valueand N component values.
    
    gsk_render_node_draw() has been ported to use GdkColor when rendering,
    which makes it so the rendering happens in a color-managed way when a
    color profile has been attached to the target.

 gdk/gdkcairo.c            |  16 ++++--
 gdk/gdkcolor.c            | 123 ++++++++++++++++++++++++++++++++++++++++
 gdk/gdkcolorprivate.h     |  73 ++++++++++++++++++++++++
 gdk/gdkcolorprivateimpl.h |  97 ++++++++++++++++++++++++++++++++
 gdk/meson.build           |   1 +
 gsk/gskrendernodeimpl.c   | 140 +++++++++++++++++++++++++++-------------------
 6 files changed, 389 insertions(+), 61 deletions(-)
---
diff --git a/gdk/gdkcairo.c b/gdk/gdkcairo.c
index c7a5476b7b..92aff82241 100644
--- a/gdk/gdkcairo.c
+++ b/gdk/gdkcairo.c
@@ -20,6 +20,8 @@
 #include "gdkcairoprivate.h"
 
 #include "gdkcolorspace.h"
+#include "gdkcolorprivate.h"
+#include "gdkmemoryformatprivate.h"
 
 #include <math.h>
 
@@ -34,14 +36,20 @@ void
 gdk_cairo_set_source_rgba (cairo_t       *cr,
                            const GdkRGBA *rgba)
 {
+  GdkColor color;
+  const float *components;
+
   g_return_if_fail (cr != NULL);
   g_return_if_fail (rgba != NULL);
 
+  gdk_color_convert_rgba (&color, gdk_cairo_get_color_space (cr), rgba);
+  components = gdk_color_get_components (&color);
   cairo_set_source_rgba (cr,
-                         rgba->red,
-                         rgba->green,
-                         rgba->blue,
-                         rgba->alpha);
+                         components[0],
+                         components[1],
+                         components[2],
+                         gdk_color_get_alpha (&color));
+  gdk_color_finish (&color);
 }
 
 /**
diff --git a/gdk/gdkcolor.c b/gdk/gdkcolor.c
new file mode 100644
index 0000000000..a873c50af8
--- /dev/null
+++ b/gdk/gdkcolor.c
@@ -0,0 +1,123 @@
+/* GDK - The GIMP Drawing Kit
+ *
+ * Copyright (C) 2021 Benjamin Otte
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "gdkcolorprivate.h"
+#include "gdkcolorspaceprivate.h"
+#include "gdklcmscolorspaceprivate.h"
+
+#include <lcms2.h>
+
+static inline cmsHTRANSFORM *
+gdk_color_get_transform (GdkColorSpace *src,
+                         GdkColorSpace *dest)
+{
+  cmsHPROFILE *src_profile, *dest_profile;
+
+  src_profile = gdk_lcms_color_space_get_lcms_profile (src);
+  dest_profile = gdk_lcms_color_space_get_lcms_profile (dest);
+
+  return gdk_lcms_color_space_lookup_transform (src,
+                                                cmsFormatterForColorspaceOfProfile (src_profile, 4, 1),
+                                                dest,
+                                                cmsFormatterForColorspaceOfProfile (dest_profile, 4, 1));
+}
+
+void
+gdk_color_convert (GdkColor        *self,
+                   GdkColorSpace   *color_space,
+                   const GdkColor  *other)
+{
+  gdk_color_init (self,
+                  color_space,
+                  other->alpha,
+                  NULL,
+                  gdk_color_space_get_n_components (color_space));
+
+  cmsDoTransform (gdk_color_get_transform (other->color_space, color_space),
+                  gdk_color_get_components (other),
+                  (float *) gdk_color_get_components (self),
+                  1);
+}
+
+void
+gdk_color_convert_rgba (GdkColor        *self,
+                        GdkColorSpace   *color_space,
+                        const GdkRGBA   *rgba)
+{
+  gdk_color_init (self,
+                  color_space,
+                  rgba->alpha,
+                  NULL,
+                  gdk_color_space_get_n_components (color_space));
+
+  cmsDoTransform (gdk_color_get_transform (gdk_color_space_get_srgb (), color_space),
+                  (float[3]) { rgba->red, rgba->green, rgba->blue },
+                  (float *) gdk_color_get_components (self),
+                  1);
+}
+
+void
+gdk_color_mix (GdkColor        *self,
+               GdkColorSpace   *color_space,
+               const GdkColor  *src1,
+               const GdkColor  *src2,
+               double           progress)
+{
+  if (src1->color_space != color_space)
+    {
+      GdkColor tmp;
+      gdk_color_convert (&tmp, color_space, src1);
+      gdk_color_mix (self, color_space, &tmp, src2, progress);
+    }
+  else if (src2->color_space != color_space)
+    {
+      GdkColor tmp;
+      gdk_color_convert (&tmp, color_space, src2);
+      gdk_color_mix (self, color_space, src1, &tmp, progress);
+    }
+  else
+    {
+      gsize i, n;
+      const float *s1, *s2;
+      float *d;
+
+      n = gdk_color_space_get_n_components (color_space);
+
+      gdk_color_init (self,
+                      color_space,
+                      src1->alpha * (1.0 - progress) + src2->alpha * progress,
+                      NULL, n);
+
+      d = (float *) gdk_color_get_components (self);
+      s1 = gdk_color_get_components (src1);
+      s2 = gdk_color_get_components (src2);
+
+      if (self->alpha == 0)
+        {
+          for (i = 0; i < n; i++)
+            d[i] = s1[i] * (1.0 - progress) + s2[i] * progress;
+        }
+      else
+        {
+          for (i = 0; i < n; i++)
+            d[i] = (s1[i] * src1->alpha * (1.0 - progress) + s2[i] * src2->alpha * progress) / self->alpha;
+        }
+    }
+}
diff --git a/gdk/gdkcolorprivate.h b/gdk/gdkcolorprivate.h
new file mode 100644
index 0000000000..c71f6d5dba
--- /dev/null
+++ b/gdk/gdkcolorprivate.h
@@ -0,0 +1,73 @@
+/* GDK - The GIMP Drawing Kit
+ *
+ * Copyright (C) 2021 Benjamin Otte
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GDK_COLOR_PRIVATE_H__
+#define __GDK_COLOR_PRIVATE_H__
+
+#include <gdk/gdkcolorspace.h>
+#include <gdk/gdkrgba.h>
+
+/* RGB - and it makes the struct size a multiple of 8 bytes, ie pointer-aligned */
+#define GDK_COLOR_MAX_NATIVE_COMPONENTS 3
+
+typedef struct _GdkColor GdkColor;
+
+struct _GdkColor
+{
+  GdkColorSpace *color_space;
+  float alpha;
+  union {
+    float values[GDK_COLOR_MAX_NATIVE_COMPONENTS];
+    float *components;
+  };
+};
+
+G_STATIC_ASSERT (sizeof (GdkColor) % sizeof (gpointer) == 0);
+
+static inline void              gdk_color_init                          (GdkColor               *self,
+                                                                         GdkColorSpace          *color_space,
+                                                                         float                   alpha,
+                                                                         float                  *components,
+                                                                         gsize                   
n_components);
+static inline void              gdk_color_init_from_rgba                (GdkColor               *self,
+                                                                         const GdkRGBA          *rgba);
+static inline void              gdk_color_finish                        (GdkColor               *self);
+
+void                            gdk_color_convert                       (GdkColor               *self,
+                                                                         GdkColorSpace          *color_space,
+                                                                         const GdkColor         *other);
+void                            gdk_color_convert_rgba                  (GdkColor               *self,
+                                                                         GdkColorSpace          *color_space,
+                                                                         const GdkRGBA          *rgba);
+
+void                            gdk_color_mix                           (GdkColor               *self,
+                                                                         GdkColorSpace          *color_space,
+                                                                         const GdkColor         *src1,
+                                                                         const GdkColor         *src2,
+                                                                         double                  progress);
+
+static inline GdkColorSpace *   gdk_color_get_color_space               (const GdkColor         *self);
+static inline float             gdk_color_get_alpha                     (const GdkColor         *self);
+static inline const float *     gdk_color_get_components                (const GdkColor         *self);
+static inline gsize             gdk_color_get_n_components              (const GdkColor         *self);
+
+#include "gdkcolorprivateimpl.h"
+
+G_END_DECLS
+
+#endif
diff --git a/gdk/gdkcolorprivateimpl.h b/gdk/gdkcolorprivateimpl.h
new file mode 100644
index 0000000000..965ad8f974
--- /dev/null
+++ b/gdk/gdkcolorprivateimpl.h
@@ -0,0 +1,97 @@
+/* GDK - The GIMP Drawing Kit
+ *
+ * Copyright (C) 2021 Benjamin Otte
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+static inline gboolean
+gdk_color_is_allocated (const GdkColor *self)
+{
+  return GPOINTER_TO_SIZE (self->color_space) & 1;
+}
+
+static inline void
+gdk_color_init (GdkColor        *self,
+                GdkColorSpace   *color_space,
+                float            alpha,
+                float           *components,
+                gsize            n_components)
+{
+  gboolean allocated = n_components > GDK_COLOR_MAX_NATIVE_COMPONENTS;
+
+  g_assert (n_components == gdk_color_space_get_n_components (color_space));
+
+  self->color_space = GSIZE_TO_POINTER (GPOINTER_TO_SIZE (g_object_ref (color_space)) | allocated);
+  self->alpha = alpha;
+  if (allocated)
+    {
+      if (components)
+        self->components = g_memdup (components, sizeof (float) * n_components);
+      else
+        self->components = g_new (float, n_components);
+    }
+  else
+    {
+      if (components)
+        memcpy (self->values, components, sizeof (float) * n_components);
+    }
+}
+
+static inline void
+gdk_color_init_from_rgba (GdkColor      *self,
+                          const GdkRGBA *rgba)
+{
+  gdk_color_init (self,
+                  gdk_color_space_get_srgb (),
+                  rgba->alpha,
+                  (float[3]) { rgba->red, rgba->green, rgba->blue },
+                  3);
+}
+
+static inline void
+gdk_color_finish (GdkColor *self)
+{
+  if (gdk_color_is_allocated (self))
+    g_free (self->components);
+
+  g_object_unref (gdk_color_get_color_space (self));
+}
+
+static inline GdkColorSpace *
+gdk_color_get_color_space (const GdkColor *self)
+{
+  return GSIZE_TO_POINTER (GPOINTER_TO_SIZE (self->color_space) & ~1); 
+}
+
+static inline float
+gdk_color_get_alpha (const GdkColor *self)
+{
+  return self->alpha;
+}
+
+static inline const float *
+gdk_color_get_components (const GdkColor *self)
+{
+  if (gdk_color_is_allocated (self))
+    return self->components;
+  else
+    return self->values;
+}
+
+static inline gsize
+gdk_color_get_n_components (const GdkColor *self)
+{
+  return gdk_color_space_get_n_components (gdk_color_get_color_space (self));
+}
diff --git a/gdk/meson.build b/gdk/meson.build
index d6384baee5..f77552dfd9 100644
--- a/gdk/meson.build
+++ b/gdk/meson.build
@@ -5,6 +5,7 @@ gdk_public_sources = files([
   'gdkcairocontext.c',
   'gdkclipboard.c',
   'gdkcolorspace.c',
+  'gdkcolor.c',
   'gdkcontentdeserializer.c',
   'gdkcontentformats.c',
   'gdkcontentprovider.c',
diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c
index edc973f126..35099b6253 100644
--- a/gsk/gskrendernodeimpl.c
+++ b/gsk/gskrendernodeimpl.c
@@ -27,6 +27,7 @@
 #include "gskroundedrectprivate.h"
 #include "gsktransformprivate.h"
 
+#include "gdk/gdkcolorprivate.h"
 #include "gdk/gdktextureprivate.h"
 #include "gdk/gdkmemoryformatprivate.h"
 #include "gdk/gdk-private.h"
@@ -194,6 +195,7 @@ gsk_linear_gradient_node_draw (GskRenderNode *node,
                                cairo_t       *cr)
 {
   GskLinearGradientNode *self = (GskLinearGradientNode *) node;
+  GdkColorSpace *color_space;
   cairo_pattern_t *pattern;
   gsize i;
 
@@ -203,14 +205,20 @@ gsk_linear_gradient_node_draw (GskRenderNode *node,
   if (gsk_render_node_get_node_type (node) == GSK_REPEATING_LINEAR_GRADIENT_NODE)
     cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
 
+  color_space = gdk_cairo_get_color_space (cr);
   for (i = 0; i < self->n_stops; i++)
     {
+      GdkColor color;
+      const float *components;
+      gdk_color_convert_rgba (&color, color_space, &self->stops[i].color);
+      components = gdk_color_get_components (&color);
       cairo_pattern_add_color_stop_rgba (pattern,
                                          self->stops[i].offset,
-                                         self->stops[i].color.red,
-                                         self->stops[i].color.green,
-                                         self->stops[i].color.blue,
-                                         self->stops[i].color.alpha);
+                                         components[0],
+                                         components[1],
+                                         components[2],
+                                         gdk_color_get_alpha (&color));
+      gdk_color_finish (&color);
     }
 
   cairo_set_source (cr, pattern);
@@ -471,6 +479,7 @@ gsk_radial_gradient_node_draw (GskRenderNode *node,
                                cairo_t       *cr)
 {
   GskRadialGradientNode *self = (GskRadialGradientNode *) node;
+  GdkColorSpace *color_space;
   cairo_pattern_t *pattern;
   gsize i;
 
@@ -490,13 +499,21 @@ gsk_radial_gradient_node_draw (GskRenderNode *node,
   else
     cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
 
+  color_space = gdk_cairo_get_color_space (cr);
   for (i = 0; i < self->n_stops; i++)
-    cairo_pattern_add_color_stop_rgba (pattern,
-                                       self->stops[i].offset,
-                                       self->stops[i].color.red,
-                                       self->stops[i].color.green,
-                                       self->stops[i].color.blue,
-                                       self->stops[i].color.alpha);
+    {
+      GdkColor color;
+      const float *components;
+      gdk_color_convert_rgba (&color, color_space, &self->stops[i].color);
+      components = gdk_color_get_components (&color);
+      cairo_pattern_add_color_stop_rgba (pattern,
+                                         self->stops[i].offset,
+                                         components[0],
+                                         components[1],
+                                         components[2],
+                                         gdk_color_get_alpha (&color));
+      gdk_color_finish (&color);
+    }
 
   gsk_cairo_rectangle (cr, &node->bounds);
   cairo_translate (cr, self->center.x, self->center.y);
@@ -831,11 +848,17 @@ gsk_conic_gradient_node_finalize (GskRenderNode *node)
 #define DEG_TO_RAD(x)          ((x) * (G_PI / 180.f))
 
 static void
-_cairo_mesh_pattern_set_corner_rgba (cairo_pattern_t *pattern,
-                                     guint            corner_num,
-                                     const GdkRGBA   *rgba)
+_cairo_mesh_pattern_set_corner_color (cairo_pattern_t *pattern,
+                                      guint            corner_num,
+                                      const GdkColor  *color)
 {
-  cairo_mesh_pattern_set_corner_color_rgba (pattern, corner_num, rgba->red, rgba->green, rgba->blue, 
rgba->alpha);
+  const float *components = gdk_color_get_components (color);
+  cairo_mesh_pattern_set_corner_color_rgba (pattern,
+                                            corner_num,
+                                            components[0],
+                                            components[1],
+                                            components[2],
+                                            gdk_color_get_alpha (color));
 }
 
 static void
@@ -860,9 +883,9 @@ static void
 gsk_conic_gradient_node_add_patch (cairo_pattern_t *pattern,
                                    float            radius,
                                    float            start_angle,
-                                   const GdkRGBA   *start_color,
+                                   const GdkColor  *start_color,
                                    float            end_angle,
-                                   const GdkRGBA   *end_color)
+                                   const GdkColor  *end_color)
 {
   double x, y;
 
@@ -875,47 +898,27 @@ gsk_conic_gradient_node_add_patch (cairo_pattern_t *pattern,
   cairo_mesh_pattern_line_to  (pattern, x, y);
   cairo_mesh_pattern_line_to  (pattern, 0, 0);
 
-  _cairo_mesh_pattern_set_corner_rgba (pattern, 0, start_color);
-  _cairo_mesh_pattern_set_corner_rgba (pattern, 1, start_color);
-  _cairo_mesh_pattern_set_corner_rgba (pattern, 2, end_color);
-  _cairo_mesh_pattern_set_corner_rgba (pattern, 3, end_color);
+  _cairo_mesh_pattern_set_corner_color (pattern, 0, start_color);
+  _cairo_mesh_pattern_set_corner_color (pattern, 1, start_color);
+  _cairo_mesh_pattern_set_corner_color (pattern, 2, end_color);
+  _cairo_mesh_pattern_set_corner_color (pattern, 3, end_color);
 
   cairo_mesh_pattern_end_patch (pattern);
 }
 
-static void
-gdk_rgba_color_interpolate (GdkRGBA       *dest,
-                            const GdkRGBA *src1,
-                            const GdkRGBA *src2,
-                            double         progress)
-{
-  double alpha = src1->alpha * (1.0 - progress) + src2->alpha * progress;
-
-  dest->alpha = alpha;
-  if (alpha == 0)
-    {
-      dest->red = src1->red * (1.0 - progress) + src2->red * progress;
-      dest->green = src1->green * (1.0 - progress) + src2->green * progress;
-      dest->blue = src1->blue * (1.0 - progress) + src2->blue * progress;
-    }
-  else
-    {
-      dest->red = (src1->red * src1->alpha * (1.0 - progress) + src2->red * src2->alpha * progress) / alpha;
-      dest->green = (src1->green * src1->alpha * (1.0 - progress) + src2->green * src2->alpha * progress) / 
alpha;
-      dest->blue = (src1->blue * src1->alpha * (1.0 - progress) + src2->blue * src2->alpha * progress) / 
alpha;
-    }
-}
-
 static void
 gsk_conic_gradient_node_draw (GskRenderNode *node,
                               cairo_t       *cr)
 {
   GskConicGradientNode *self = (GskConicGradientNode *) node;
+  GdkColorSpace *color_space;
   cairo_pattern_t *pattern;
   graphene_point_t corner;
   float radius;
   gsize i;
 
+  color_space = gdk_cairo_get_color_space (cr);
+
   pattern = cairo_pattern_create_mesh ();
   graphene_rect_get_top_right (&node->bounds, &corner);
   radius = graphene_point_distance (&self->center, &corner, NULL, NULL);
@@ -930,26 +933,31 @@ gsk_conic_gradient_node_draw (GskRenderNode *node,
     {
       GskColorStop *stop1 = &self->stops[MAX (i, 1) - 1];
       GskColorStop *stop2 = &self->stops[MIN (i, self->n_stops - 1)];
+      GdkColor stop1_color, stop2_color;
       double offset1 = i > 0 ? stop1->offset : 0;
       double offset2 = i < self->n_stops ? stop2->offset : 1;
       double start_angle, end_angle;
 
       offset1 = offset1 * 360 + self->rotation - 90;
       offset2 = offset2 * 360 + self->rotation - 90;
+      gdk_color_convert_rgba (&stop1_color, color_space, &stop1->color);
+      gdk_color_convert_rgba (&stop2_color, color_space, &stop1->color);
 
       for (start_angle = offset1; start_angle < offset2; start_angle = end_angle)
         {
-          GdkRGBA start_color, end_color;
+          GdkColor start_color, end_color;
           end_angle = (floor (start_angle / 45) + 1) * 45;
           end_angle = MIN (end_angle, offset2);
-          gdk_rgba_color_interpolate (&start_color,
-                                      &stop1->color,
-                                      &stop2->color,
-                                      (start_angle - offset1) / (offset2 - offset1));
-          gdk_rgba_color_interpolate (&end_color,
-                                      &stop1->color,
-                                      &stop2->color,
-                                      (end_angle - offset1) / (offset2 - offset1));
+          gdk_color_mix (&start_color,
+                         color_space,
+                         &stop1_color,
+                         &stop2_color,
+                         (start_angle - offset1) / (offset2 - offset1));
+          gdk_color_mix (&end_color,
+                         color_space,
+                         &stop1_color,
+                         &stop2_color,
+                         (end_angle - offset1) / (offset2 - offset1));
 
           gsk_conic_gradient_node_add_patch (pattern,
                                              radius,
@@ -958,6 +966,9 @@ gsk_conic_gradient_node_draw (GskRenderNode *node,
                                              DEG_TO_RAD (end_angle),
                                              &end_color);
         }
+
+      gdk_color_finish (&stop2_color);
+      gdk_color_finish (&stop1_color);
     }
 
   cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
@@ -1174,7 +1185,8 @@ struct _GskBorderNode
 
 static void
 gsk_border_node_mesh_add_patch (cairo_pattern_t *pattern,
-                                const GdkRGBA   *color,
+                                GdkColorSpace   *color_space,
+                                const GdkRGBA   *rgba,
                                 double           x0,
                                 double           y0,
                                 double           x1,
@@ -1184,15 +1196,23 @@ gsk_border_node_mesh_add_patch (cairo_pattern_t *pattern,
                                 double           x3,
                                 double           y3)
 {
+  GdkColor color;
+  const float *components;
+  float alpha;
+
+  gdk_color_convert_rgba (&color, color_space, rgba);
+  components = gdk_color_get_components (&color);
+  alpha = gdk_color_get_alpha (&color);
+
   cairo_mesh_pattern_begin_patch (pattern);
   cairo_mesh_pattern_move_to (pattern, x0, y0);
   cairo_mesh_pattern_line_to (pattern, x1, y1);
   cairo_mesh_pattern_line_to (pattern, x2, y2);
   cairo_mesh_pattern_line_to (pattern, x3, y3);
-  cairo_mesh_pattern_set_corner_color_rgba (pattern, 0, color->red, color->green, color->blue, color->alpha);
-  cairo_mesh_pattern_set_corner_color_rgba (pattern, 1, color->red, color->green, color->blue, color->alpha);
-  cairo_mesh_pattern_set_corner_color_rgba (pattern, 2, color->red, color->green, color->blue, color->alpha);
-  cairo_mesh_pattern_set_corner_color_rgba (pattern, 3, color->red, color->green, color->blue, color->alpha);
+  cairo_mesh_pattern_set_corner_color_rgba (pattern, 0, components[0], components[1], components[2], alpha);
+  cairo_mesh_pattern_set_corner_color_rgba (pattern, 1, components[0], components[1], components[2], alpha);
+  cairo_mesh_pattern_set_corner_color_rgba (pattern, 2, components[0], components[1], components[2], alpha);
+  cairo_mesh_pattern_set_corner_color_rgba (pattern, 3, components[0], components[1], components[2], alpha);
   cairo_mesh_pattern_end_patch (pattern);
 }
 
@@ -1238,11 +1258,13 @@ gsk_border_node_draw (GskRenderNode *node,
        * Note that the call to cairo_fill() will add the potential final
        * segment by closing the path, so we don't have to care.
        */
+      GdkColorSpace *color_space;
       cairo_pattern_t *mesh;
       cairo_matrix_t mat;
       graphene_point_t tl, br;
       float scale;
 
+      color_space = gdk_cairo_get_color_space (cr);
       mesh = cairo_pattern_create_mesh ();
       cairo_matrix_init_translate (&mat, -bounds->origin.x, -bounds->origin.y);
       cairo_pattern_set_matrix (mesh, &mat);
@@ -1260,6 +1282,7 @@ gsk_border_node_draw (GskRenderNode *node,
       if (self->border_width[0] > 0)
         {
           gsk_border_node_mesh_add_patch (mesh,
+                                          color_space,
                                           &self->border_color[0],
                                           0, 0,
                                           tl.x, tl.y,
@@ -1271,6 +1294,7 @@ gsk_border_node_draw (GskRenderNode *node,
       if (self->border_width[1] > 0)
         {
           gsk_border_node_mesh_add_patch (mesh,
+                                          color_space,
                                           &self->border_color[1],
                                           bounds->size.width, 0,
                                           br.x, tl.y,
@@ -1282,6 +1306,7 @@ gsk_border_node_draw (GskRenderNode *node,
       if (self->border_width[2] > 0)
         {
           gsk_border_node_mesh_add_patch (mesh,
+                                          color_space,
                                           &self->border_color[2],
                                           0, bounds->size.height,
                                           tl.x, br.y,
@@ -1293,6 +1318,7 @@ gsk_border_node_draw (GskRenderNode *node,
       if (self->border_width[3] > 0)
         {
           gsk_border_node_mesh_add_patch (mesh,
+                                          color_space,
                                           &self->border_color[3],
                                           0, 0,
                                           tl.x, tl.y,


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