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..ed764ea188 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 "gdkcolorprofile.h" + #include /** @@ -335,3 +337,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.8 + */ +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.8 + */ +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.8 + */ +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..298eef77b1 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_profile (cairo_surface_t *surface, + GdkColorProfile *profile); +GDK_AVAILABLE_IN_4_8 +GdkColorProfile * gdk_cairo_surface_get_color_profile (cairo_surface_t *surface); +GDK_AVAILABLE_IN_4_8 +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 f9733bc97b..de55fbcc5e 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" @@ -2433,7 +2434,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) @@ -2449,6 +2450,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 6beea11431..d298510be3 100644 --- a/gdk/gdktexture.c +++ b/gdk/gdktexture.c @@ -39,6 +39,7 @@ #include "gdktextureprivate.h" +#include "gdkcairo.h" #include "gdkcolorprofile.h" #include "gdkintl.h" #include "gdkmemorytextureprivate.h" @@ -396,11 +397,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 b75353b577..4a31338148 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_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 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..efad24645e 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; }