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.
This commit is contained in:
Benjamin Otte
2021-09-25 22:56:34 +02:00
committed by Matthias Clasen
parent 81da727a9c
commit baefbc5259
8 changed files with 124 additions and 11 deletions

View File

@@ -46,9 +46,10 @@ gdk_broadway_cairo_context_begin_frame (GdkDrawContext *draw_context,
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 * scale, height *scale);
repaint_region = cairo_region_create_rectangle (&(cairo_rectangle_int_t) { 0, 0, width, height });
cairo_region_union (region, repaint_region);

View File

@@ -21,6 +21,7 @@
#include "gdkrgba.h"
#include "gdktexture.h"
#include "gdkcolorstate.h"
#include <math.h>
@@ -303,3 +304,98 @@ gdk_cairo_region_create_from_surface (cairo_surface_t *surface)
return region;
}
static cairo_user_data_key_t color_state_key;
/**
* gdk_cairo_surface_set_color_state:
* @surface: a surface
* @color_state: the color state to attach to the surface
*
* Attaches a `GdkColorState` 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 state, so if you want to use the surface
* as a target for rendering in a color managed way, you should use
* such a color state.
*
* The default color state is assumed to be sRGB, which is not
* linear.
*
* Since: 4.16
*/
void
gdk_cairo_surface_set_color_state (cairo_surface_t *surface,
GdkColorState *color_state)
{
g_return_if_fail (surface != NULL);
g_return_if_fail (color_state != NULL);
cairo_surface_set_user_data (surface,
&color_state_key,
gdk_color_state_ref (color_state),
(cairo_destroy_func_t) gdk_color_state_unref);
}
/**
* gdk_cairo_surface_get_color_state:
* @surface: a surface
*
* Gets the color state GTK assumes for the surface.
*
* See [method@Gdk.CairoSurface.set_color_state] for details.
*
* Returns: (transfer none): the color state
*
* Since: 4.16
*/
GdkColorState *
gdk_cairo_surface_get_color_state (cairo_surface_t *surface)
{
GdkColorState *color_state;
g_return_val_if_fail (surface != NULL, gdk_color_state_get_srgb ());
color_state = cairo_surface_get_user_data (surface, &color_state_key);
if (color_state == NULL)
color_state = gdk_color_state_get_srgb ();
return color_state;
}
/**
* gdk_cairo_get_color_state:
* @cr: a cairo context
*
* Gets the color state GTK assumes for the cairo context.
*
* Returns: (transfer none): the color state
*
* Since: 4.16
*/
GdkColorState *
gdk_cairo_get_color_state (cairo_t *cr)
{
GdkColorState *color_state;
cairo_surface_t *surface;
g_return_val_if_fail (cr != NULL, gdk_color_state_get_srgb ());
surface = cairo_get_group_target (cr);
color_state = cairo_surface_get_user_data (surface, &color_state_key);
if (color_state != NULL)
return color_state;
/* theoretically, we should walk the whole group stack, but I don't
* think Cairo lets us do that
*/
surface = cairo_get_target (cr);
color_state = cairo_surface_get_user_data (surface, &color_state_key);
if (color_state != NULL)
return color_state;
return gdk_color_state_get_srgb ();
}

View File

@@ -44,9 +44,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_16
void gdk_cairo_surface_set_color_state (cairo_surface_t *surface,
GdkColorState *color_state);
GDK_AVAILABLE_IN_4_16
GdkColorState * gdk_cairo_surface_get_color_state (cairo_surface_t *surface);
GDK_AVAILABLE_IN_4_16
GdkColorState * gdk_cairo_get_color_state (cairo_t *cr);
GDK_DEPRECATED_IN_4_6_FOR(gdk_gl_texture_new)
void gdk_cairo_draw_from_gl (cairo_t *cr,

View File

@@ -30,6 +30,8 @@
#include "gdksurface.h"
#include "gdkprivate.h"
#include "gdkcolorstate.h"
#include "gdkcairo.h"
#include "gdkcontentprovider.h"
#include "gdkdeviceprivate.h"
#include "gdkdisplayprivate.h"
@@ -2361,6 +2363,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_state (similar_surface, gdk_surface_get_color_state (surface));
return similar_surface;
}

View File

@@ -45,6 +45,7 @@
#include "gdkpaintable.h"
#include "gdksnapshot.h"
#include "gdkcolorstate.h"
#include "gdkcairo.h"
#include <graphene.h>
#include "loaders/gdkpngprivate.h"
@@ -455,11 +456,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_state (cairo_image_surface_get_width (surface),
cairo_image_surface_get_height (surface),
GDK_MEMORY_DEFAULT,
gdk_cairo_surface_get_color_state (surface),
bytes,
cairo_image_surface_get_stride (surface));
g_bytes_unref (bytes);

View File

@@ -158,6 +158,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_state (self->paint_surface,
gdk_surface_get_color_state (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);

View File

@@ -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_state (cairo_surface, gdk_surface_get_color_state (surface));
return cairo_surface;
}

View File

@@ -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_state (cairo_surface, gdk_surface_get_color_state (surface));
return cairo_surface;
}