[gtk/matthiasc/color-profile-rebased: 31/66] API: Add color space get/set for cairo




commit d5b958d17cb988f1eb9804a21655c7bd0106de4a
Author: Benjamin Otte <otte redhat com>
Date:   Sat Sep 25 22:56:34 2021 +0200

    API: Add color space get/set for cairo
    
    Add a centralized place to attach color space to.
    
    Nothing uses that information yet, but all the
    backends do set it.

 gdk/broadway/gdkcairocontext-broadway.c | 17 ++----
 gdk/gdkcairo.c                          | 98 ++++++++++++++++++++++++++++++++-
 gdk/gdkcairo.h                          | 14 +++--
 gdk/gdksurface.c                        |  4 +-
 gdk/gdktexture.c                        | 12 ++--
 gdk/wayland/gdkcairocontext-wayland.c   |  3 +
 gdk/win32/gdkcairocontext-win32.c       |  1 +
 gdk/x11/gdkcairocontext-x11.c           |  1 +
 8 files changed, 127 insertions(+), 23 deletions(-)
---
diff --git a/gdk/broadway/gdkcairocontext-broadway.c b/gdk/broadway/gdkcairocontext-broadway.c
index c2924bdf29..8f15facce6 100644
--- a/gdk/broadway/gdkcairocontext-broadway.c
+++ b/gdk/broadway/gdkcairocontext-broadway.c
@@ -39,26 +39,19 @@ gdk_broadway_cairo_context_begin_frame (GdkDrawContext *draw_context,
 {
   GdkBroadwayCairoContext *self = GDK_BROADWAY_CAIRO_CONTEXT (draw_context);
   GdkSurface *surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self));
-  cairo_t *cr;
   cairo_region_t *repaint_region;
-  int width, height, scale;
+  int width, height;
 
   width = gdk_surface_get_width (surface);
   height = gdk_surface_get_height (surface);
-  scale = gdk_surface_get_scale_factor (surface);
-  self->paint_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
-                                                    width * scale, height * scale);
-  cairo_surface_set_device_scale (self->paint_surface, scale, scale);
+  self->paint_surface = gdk_surface_create_similar_surface (surface,
+                                                            CAIRO_CONTENT_COLOR_ALPHA,
+                                                            width,
+                                                            height);
 
   repaint_region = cairo_region_create_rectangle (&(cairo_rectangle_int_t) { 0, 0, width, height });
   cairo_region_union (region, repaint_region);
   cairo_region_destroy (repaint_region);
-
-  /* clear the repaint area */
-  cr = cairo_create (self->paint_surface);
-  cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
-  cairo_fill (cr);
-  cairo_destroy (cr);
 }
 
 static void
diff --git a/gdk/gdkcairo.c b/gdk/gdkcairo.c
index d69b9bc602..c7a5476b7b 100644
--- a/gdk/gdkcairo.c
+++ b/gdk/gdkcairo.c
@@ -1,5 +1,5 @@
 /* GDK - The GIMP Drawing Kit
- * Copyright (C) 2005 Red Hat, Inc. 
+ * Copyright (C) 2005 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -19,6 +19,8 @@
 
 #include "gdkcairoprivate.h"
 
+#include "gdkcolorspace.h"
+
 #include <math.h>
 
 /**
@@ -335,3 +337,97 @@ gdk_cairo_region_from_clip (cairo_t *cr)
 
   return region;
 }
+
+static cairo_user_data_key_t color_space_key;
+
+/**
+ * gdk_cairo_surface_set_color_space:
+ * @surface: a surface
+ * @color_space: the color space to attach to the surface
+ *
+ * Attaches a `GdkColorSpace` to the Cairo surface.
+ *
+ * This is just auxiliary data for use by GTK, no Cairo functions
+ * do interact with this information.
+ *
+ * Note that all Cairo compositing operations are assumed to happen
+ * in a linear RGB color space, so if you want to use the surface
+ * as a target for rendering in a color managed way, you should use
+ * such a color space.
+ *
+ * The default color space is assumed to be sRGB, which is not
+ * linear.
+ *
+ * Since: 4.8
+ */
+void
+gdk_cairo_surface_set_color_space (cairo_surface_t *surface,
+                                   GdkColorSpace   *color_space)
+{
+  g_return_if_fail (surface != NULL);
+  g_return_if_fail (GDK_IS_COLOR_SPACE (color_space));
+
+  cairo_surface_set_user_data (surface,
+                               &color_space_key,
+                               g_object_ref (color_space),
+                               g_object_unref);
+}
+
+/**
+ * gdk_cairo_surface_get_color_space:
+ * @surface: a surface
+ *
+ * Gets the color space GTK assumes for the surface. See
+ * [method@Gdk.CairoSurface.set_color_space] for details.
+ *
+ * Returns: (transfer none): the color space
+ *
+ * Since: 4.8
+ */
+GdkColorSpace *
+gdk_cairo_surface_get_color_space (cairo_surface_t *surface)
+{
+  GdkColorSpace *color_space;
+
+  g_return_val_if_fail (surface != NULL, gdk_color_space_get_srgb ());
+
+  color_space = cairo_surface_get_user_data (surface, &color_space_key);
+  if (color_space == NULL)
+    color_space = gdk_color_space_get_srgb ();
+
+  return color_space;
+}
+
+/**
+ * gdk_cairo_get_color_space:
+ * @cr: a cairo context
+ *
+ * Gets the color space GTK assumes for the cairo context.
+ *
+ * Returns: (transfer none): the color space
+ *
+ * Since: 4.8
+ */
+GdkColorSpace *
+gdk_cairo_get_color_space (cairo_t *cr)
+{
+  GdkColorSpace *color_space;
+  cairo_surface_t *surface;
+
+  g_return_val_if_fail (cr != NULL, gdk_color_space_get_srgb ());
+
+  surface = cairo_get_group_target (cr);
+  color_space = cairo_surface_get_user_data (surface, &color_space_key);
+  if (color_space != NULL)
+    return color_space;
+
+  /* theoretically, we should walk the whole group stack, but I don't
+   * think Cairo lets us do that
+   */
+  surface = cairo_get_target (cr);
+  color_space = cairo_surface_get_user_data (surface, &color_space_key);
+  if (color_space != NULL)
+    return color_space;
+
+  return gdk_color_space_get_srgb ();
+}
diff --git a/gdk/gdkcairo.h b/gdk/gdkcairo.h
index f2dfa3177e..b11c984b66 100644
--- a/gdk/gdkcairo.h
+++ b/gdk/gdkcairo.h
@@ -1,5 +1,5 @@
 /* GDK - The GIMP Drawing Kit
- * Copyright (C) 2005 Red Hat, Inc. 
+ * Copyright (C) 2005 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -46,9 +46,15 @@ void       gdk_cairo_region             (cairo_t              *cr,
                                          const cairo_region_t *region);
 
 GDK_AVAILABLE_IN_ALL
-cairo_region_t *
-           gdk_cairo_region_create_from_surface
-                                        (cairo_surface_t      *surface);
+cairo_region_t *        gdk_cairo_region_create_from_surface    (cairo_surface_t        *surface);
+
+GDK_AVAILABLE_IN_4_8
+void                    gdk_cairo_surface_set_color_space       (cairo_surface_t        *surface,
+                                                                 GdkColorSpace          *color_space);
+GDK_AVAILABLE_IN_4_8
+GdkColorSpace *         gdk_cairo_surface_get_color_space       (cairo_surface_t        *surface);
+GDK_AVAILABLE_IN_4_8
+GdkColorSpace *         gdk_cairo_get_color_space               (cairo_t                *cr);
 
 GDK_DEPRECATED_IN_4_6_FOR(gdk_gl_texture_new)
 void       gdk_cairo_draw_from_gl (cairo_t              *cr,
diff --git a/gdk/gdksurface.c b/gdk/gdksurface.c
index aa5baa1733..587070ae10 100644
--- a/gdk/gdksurface.c
+++ b/gdk/gdksurface.c
@@ -31,6 +31,7 @@
 
 #include "gdk-private.h"
 #include "gdkcolorspace.h"
+#include "gdkcairo.h"
 #include "gdkcontentprovider.h"
 #include "gdkdeviceprivate.h"
 #include "gdkdisplayprivate.h"
@@ -2418,7 +2419,7 @@ _gdk_windowing_got_event (GdkDisplay *display,
  *   with it.
  */
 cairo_surface_t *
-gdk_surface_create_similar_surface (GdkSurface *     surface,
+gdk_surface_create_similar_surface (GdkSurface *    surface,
                                     cairo_content_t content,
                                     int             width,
                                     int             height)
@@ -2434,6 +2435,7 @@ gdk_surface_create_similar_surface (GdkSurface *     surface,
                                                 content == CAIRO_CONTENT_ALPHA ? CAIRO_FORMAT_A8 : 
CAIRO_FORMAT_ARGB32,
                                                 width * scale, height * scale);
   cairo_surface_set_device_scale (similar_surface, scale, scale);
+  gdk_cairo_surface_set_color_space (similar_surface, gdk_surface_get_color_space (surface));
 
   return similar_surface;
 }
diff --git a/gdk/gdktexture.c b/gdk/gdktexture.c
index 2641655fb9..bc1dc0cf57 100644
--- a/gdk/gdktexture.c
+++ b/gdk/gdktexture.c
@@ -40,6 +40,7 @@
 #include "gdktextureprivate.h"
 
 #include "gdkcolorspace.h"
+#include "gdkcairo.h"
 #include "gdkintl.h"
 #include "gdkmemorytextureprivate.h"
 #include "gdkpaintable.h"
@@ -386,11 +387,12 @@ gdk_texture_new_for_surface (cairo_surface_t *surface)
                                       (GDestroyNotify) cairo_surface_destroy,
                                       cairo_surface_reference (surface));
 
-  texture = gdk_memory_texture_new (cairo_image_surface_get_width (surface),
-                                    cairo_image_surface_get_height (surface),
-                                    GDK_MEMORY_DEFAULT,
-                                    bytes,
-                                    cairo_image_surface_get_stride (surface));
+  texture = gdk_memory_texture_new_with_color_space (cairo_image_surface_get_width (surface),
+                                                     cairo_image_surface_get_height (surface),
+                                                     GDK_MEMORY_DEFAULT,
+                                                     gdk_cairo_surface_get_color_space (surface),
+                                                     bytes,
+                                                     cairo_image_surface_get_stride (surface));
 
   g_bytes_unref (bytes);
 
diff --git a/gdk/wayland/gdkcairocontext-wayland.c b/gdk/wayland/gdkcairocontext-wayland.c
index b75353b577..336edd8027 100644
--- a/gdk/wayland/gdkcairocontext-wayland.c
+++ b/gdk/wayland/gdkcairocontext-wayland.c
@@ -157,6 +157,9 @@ gdk_wayland_cairo_context_begin_frame (GdkDrawContext *draw_context,
   else
     self->paint_surface = gdk_wayland_cairo_context_create_surface (self);
 
+  gdk_cairo_surface_set_color_space (self->paint_surface,
+                                     gdk_surface_get_color_space (gdk_draw_context_get_surface 
(draw_context)));
+
   surface_region = gdk_wayland_cairo_context_surface_get_region (self->paint_surface);
   if (surface_region)
     cairo_region_union (region, surface_region);
diff --git a/gdk/win32/gdkcairocontext-win32.c b/gdk/win32/gdkcairocontext-win32.c
index 480baf7802..0ae273700b 100644
--- a/gdk/win32/gdkcairocontext-win32.c
+++ b/gdk/win32/gdkcairocontext-win32.c
@@ -47,6 +47,7 @@ create_cairo_surface_for_surface (GdkSurface *surface,
 
   cairo_surface = cairo_win32_surface_create_with_format (hdc, CAIRO_FORMAT_ARGB32);
   cairo_surface_set_device_scale (cairo_surface, scale, scale);
+  gdk_cairo_surface_set_color_profile (cairo_surface, gdk_surface_get_color_profile (surface));
 
   return cairo_surface;
 }
diff --git a/gdk/x11/gdkcairocontext-x11.c b/gdk/x11/gdkcairocontext-x11.c
index e25ec197a7..f0250b1ba1 100644
--- a/gdk/x11/gdkcairocontext-x11.c
+++ b/gdk/x11/gdkcairocontext-x11.c
@@ -49,6 +49,7 @@ create_cairo_surface_for_surface (GdkSurface *surface)
                                              gdk_surface_get_width (surface) * scale,
                                              gdk_surface_get_height (surface) * scale);
   cairo_surface_set_device_scale (cairo_surface, scale, scale);
+  gdk_cairo_surface_set_color_space (cairo_surface, gdk_surface_get_color_space(surface));
 
   return cairo_surface;
 }


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