[gtk/wip/otte/color-profiles: 3/18] cairo: Add color profile get/set
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/color-profiles: 3/18] cairo: Add color profile get/set
- Date: Wed, 29 Sep 2021 05:02:57 +0000 (UTC)
commit 6f8562018ef1b8407912d796f4a178a11f94cd12
Author: Benjamin Otte <otte redhat com>
Date: Sat Sep 25 22:56:34 2021 +0200
cairo: Add color profile get/set
Add a centralized place to attach color profiles to.
Nothing uses that information yet, but all the backends do set it.
gdk/broadway/gdkcairocontext-broadway.c | 17 ++----
gdk/gdkcairo.c | 96 +++++++++++++++++++++++++++++++++
gdk/gdkcairo.h | 12 +++--
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 | 2 +
8 files changed, 126 insertions(+), 21 deletions(-)
---
diff --git a/gdk/broadway/gdkcairocontext-broadway.c b/gdk/broadway/gdkcairocontext-broadway.c
index bc45b5094a..24e7d61e13 100644
--- a/gdk/broadway/gdkcairocontext-broadway.c
+++ b/gdk/broadway/gdkcairocontext-broadway.c
@@ -38,26 +38,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 ef8f5d2fb5..1f1eb58a61 100644
--- a/gdk/gdkcairo.c
+++ b/gdk/gdkcairo.c
@@ -19,6 +19,8 @@
#include "gdkcairoprivate.h"
+#include "gdkcolorprofile.h"
+
#include <math.h>
/**
@@ -399,3 +401,97 @@ gdk_cairo_region_from_clip (cairo_t *cr)
return region;
}
+
+static cairo_user_data_key_t color_profile_key;
+
+/**
+ * gdk_cairo_surface_set_color_profile:
+ * @surface: a surface
+ * @profile: the profile to attach to the surface
+ *
+ * Attaches a `GdkColorProfile` 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 profile.
+ *
+ * The default color profile is assumed to be sRGB, which is not
+ * linear.
+ *
+ * Since: 4.6
+ **/
+void
+gdk_cairo_surface_set_color_profile (cairo_surface_t *surface,
+ GdkColorProfile *profile)
+{
+ g_return_if_fail (surface != NULL);
+ g_return_if_fail (GDK_IS_COLOR_PROFILE (profile));
+
+ cairo_surface_set_user_data (surface,
+ &color_profile_key,
+ g_object_ref (profile),
+ g_object_unref);
+}
+
+/**
+ * gdk_cairo_surface_get_color_profile:
+ * @surface: a surface
+ *
+ * Gets the color profile GTK assumes for the surface. See
+ * gdk_cairo_surface_set_color_profile() for details.
+ *
+ * Returns: (transfer none): the assumed profile
+ *
+ * Since: 4.6
+ **/
+GdkColorProfile *
+gdk_cairo_surface_get_color_profile (cairo_surface_t *surface)
+{
+ GdkColorProfile *profile;
+
+ g_return_val_if_fail (surface != NULL, gdk_color_profile_get_srgb ());
+
+ profile = cairo_surface_get_user_data (surface, &color_profile_key);
+ if (profile == NULL)
+ profile = gdk_color_profile_get_srgb ();
+
+ return profile;
+}
+
+/**
+ * gdk_cairo_get_color_profile:
+ * @cr: a cairo context
+ *
+ * Gets the color profile GTK assumes for the cairo context.
+ *
+ * Returns: (transfer none): the assumed profile
+ *
+ * Since: 4.6
+ **/
+GdkColorProfile *
+gdk_cairo_get_color_profile (cairo_t *cr)
+{
+ GdkColorProfile *profile;
+ cairo_surface_t *surface;
+
+ g_return_val_if_fail (cr != NULL, gdk_color_profile_get_srgb ());
+
+ surface = cairo_get_group_target (cr);
+ profile = cairo_surface_get_user_data (surface, &color_profile_key);
+ if (profile != NULL)
+ return profile;
+
+ /* theoretically, we should walk the whole group stack, but I don't
+ * think Cairo lets us do that
+ */
+ surface = cairo_get_target (cr);
+ profile = cairo_surface_get_user_data (surface, &color_profile_key);
+ if (profile != NULL)
+ return profile;
+
+ return gdk_color_profile_get_srgb ();
+}
diff --git a/gdk/gdkcairo.h b/gdk/gdkcairo.h
index f2dfa3177e..eea08975b0 100644
--- a/gdk/gdkcairo.h
+++ b/gdk/gdkcairo.h
@@ -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_6
+void gdk_cairo_surface_set_color_profile (cairo_surface_t *surface,
+ GdkColorProfile *profile);
+GDK_AVAILABLE_IN_4_6
+GdkColorProfile * gdk_cairo_surface_get_color_profile (cairo_surface_t *surface);
+GDK_AVAILABLE_IN_4_6
+GdkColorProfile * gdk_cairo_get_color_profile (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 c53ed89fe1..e1abb68e58 100644
--- a/gdk/gdksurface.c
+++ b/gdk/gdksurface.c
@@ -30,6 +30,7 @@
#include "gdksurface.h"
#include "gdk-private.h"
+#include "gdkcairo.h"
#include "gdkcolorprofile.h"
#include "gdkcontentprovider.h"
#include "gdkdeviceprivate.h"
@@ -2334,7 +2335,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)
@@ -2350,6 +2351,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_profile (similar_surface, gdk_surface_get_color_profile (surface));
return similar_surface;
}
diff --git a/gdk/gdktexture.c b/gdk/gdktexture.c
index 975e6c5f9a..b062667b54 100644
--- a/gdk/gdktexture.c
+++ b/gdk/gdktexture.c
@@ -40,6 +40,7 @@
#include "gdktextureprivate.h"
+#include "gdkcairo.h"
#include "gdkcolorprofile.h"
#include "gdkintl.h"
#include "gdkmemorytextureprivate.h"
@@ -421,11 +422,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_profile (cairo_image_surface_get_width (surface),
+ cairo_image_surface_get_height (surface),
+ GDK_MEMORY_DEFAULT,
+ gdk_cairo_surface_get_color_profile (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 4ce7134327..1996c963d0 100644
--- a/gdk/wayland/gdkcairocontext-wayland.c
+++ b/gdk/wayland/gdkcairocontext-wayland.c
@@ -156,6 +156,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_profile (self->paint_surface,
+ gdk_surface_get_color_profile (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 9eb115ffcd..b1a6391133 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 36bf1ae0ba..a6275f969a 100644
--- a/gdk/x11/gdkcairocontext-x11.c
+++ b/gdk/x11/gdkcairocontext-x11.c
@@ -49,6 +49,8 @@ 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_profile (cairo_surface,
+ gdk_surface_get_color_profile (surface));
return cairo_surface;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]