From 6287eaa74570bf8232ad33b458c746ef2b0fbbf1 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 2 Jul 2024 07:02:09 +0200 Subject: [PATCH] cairo: Add colorstate to GskRenderNode::draw and use it This adds the following: - ccs argument to GskRenderNode::draw This is the compositing color state to use when drawing. - make implementations use the CCS argument FIXME: Some implementations are missing - gsk_render_node_draw_with_color_state() Draws a node with any color state, by switching to its compositing color state, drawing in that color state and then converting to the desired color state. This does draw the result OVER the previous contents in the passed in color state, so this function should be called with the target being empty. - gsk_render_node_draw_ccs() This needs to be passed a css and then draws with that ccs. The main use for this is chaining up in rendernode draw() implementations. - split out shared Cairo functions into gdkcairoprivate.h gskrendernode.c and gskrendernodeimpl.c need the same functions. Plus, there's various code in GDK that wants to use it, so put it in gdk/ not in gsk/ gsk_render_node_draw() now calls gsk_render_node_draw_with_color_state() with GDK_COLOR_STATE_SRGB. --- gdk/gdkcairoprivate.h | 94 ++++++++++ gsk/gskrendernode.c | 88 ++++++--- gsk/gskrendernodeimpl.c | 362 +++++++++++++++++++++---------------- gsk/gskrendernodeprivate.h | 9 +- 4 files changed, 377 insertions(+), 176 deletions(-) create mode 100644 gdk/gdkcairoprivate.h diff --git a/gdk/gdkcairoprivate.h b/gdk/gdkcairoprivate.h new file mode 100644 index 0000000000..98f06e3107 --- /dev/null +++ b/gdk/gdkcairoprivate.h @@ -0,0 +1,94 @@ +#pragma once + +#include "gdk/gdkcolorstateprivate.h" + +#include + +static GdkMemoryFormat +gdk_cairo_format_to_memory_format (cairo_format_t format) +{ + switch (format) + { + case CAIRO_FORMAT_ARGB32: + return GDK_MEMORY_DEFAULT; + + case CAIRO_FORMAT_RGB24: +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + return GDK_MEMORY_B8G8R8X8; +#elif G_BYTE_ORDER == G_BIG_ENDIAN + return GDK_MEMORY_X8R8G8B8; +#else +#error "Unknown byte order for Cairo format" +#endif + case CAIRO_FORMAT_A8: + return GDK_MEMORY_A8; + case CAIRO_FORMAT_RGB96F: + return GDK_MEMORY_R32G32B32_FLOAT; + case CAIRO_FORMAT_RGBA128F: + return GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED; + + case CAIRO_FORMAT_RGB16_565: + case CAIRO_FORMAT_RGB30: + case CAIRO_FORMAT_INVALID: + case CAIRO_FORMAT_A1: + default: + g_assert_not_reached (); + return GDK_MEMORY_DEFAULT; + } +} + +static inline void +gdk_cairo_set_source_rgba_ccs (cairo_t *cr, + GdkColorState *ccs, + const GdkRGBA *rgba) +{ + float color[4]; + + gdk_color_state_from_rgba (ccs, rgba, color); + cairo_set_source_rgba (cr, color[0], color[1], color[2], color[3]); +} + +static inline void +gdk_cairo_pattern_add_color_stop_rgba_ccs (cairo_pattern_t *pattern, + GdkColorState *ccs, + double offset, + const GdkRGBA *rgba) +{ + float color[4]; + + gdk_color_state_from_rgba (ccs, rgba, color); + cairo_pattern_add_color_stop_rgba (pattern, offset, color[0], color[1], color[2], color[3]); +} + +static inline void +gdk_cairo_rect (cairo_t *cr, + const graphene_rect_t *rect) +{ + cairo_rectangle (cr, + rect->origin.x, rect->origin.y, + rect->size.width, rect->size.height); +} + +static inline void +gdk_cairo_surface_convert_color_state (cairo_surface_t *surface, + GdkColorState *source, + GdkColorState *target) +{ + cairo_surface_t *image_surface; + + image_surface = cairo_surface_map_to_image (surface, NULL); + + gdk_memory_convert_color_state (cairo_image_surface_get_data (image_surface), + cairo_image_surface_get_stride (image_surface), + gdk_cairo_format_to_memory_format (cairo_image_surface_get_format (image_surface)), + source, + target, + cairo_image_surface_get_width (image_surface), + cairo_image_surface_get_height (image_surface)); + + cairo_surface_mark_dirty (image_surface); + cairo_surface_unmap_image (surface, image_surface); + /* https://gitlab.freedesktop.org/cairo/cairo/-/merge_requests/487 */ + cairo_surface_mark_dirty (surface); +} + diff --git a/gsk/gskrendernode.c b/gsk/gskrendernode.c index 32f62abc7c..551820e4dc 100644 --- a/gsk/gskrendernode.c +++ b/gsk/gskrendernode.c @@ -42,6 +42,9 @@ #include "gskrendererprivate.h" #include "gskrendernodeparserprivate.h" +#include "gdk/gdkcairoprivate.h" +#include "gdk/gdkcolorstateprivate.h" + #include #include @@ -371,6 +374,68 @@ gsk_render_node_get_bounds (GskRenderNode *node, graphene_rect_init_from_rect (bounds, &node->bounds); } +void +gsk_render_node_draw_ccs (GskRenderNode *node, + cairo_t *cr, + GdkColorState *ccs) +{ + /* Check that the calling function did pass a correct color state */ + g_assert (ccs == gdk_color_state_get_rendering_color_state (ccs)); + + cairo_save (cr); + + GSK_RENDER_NODE_GET_CLASS (node)->draw (node, cr, ccs); + + if (GSK_DEBUG_CHECK (GEOMETRY)) + { + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + cairo_rectangle (cr, node->bounds.origin.x - 1, node->bounds.origin.y - 1, + node->bounds.size.width + 2, node->bounds.size.height + 2); + cairo_set_line_width (cr, 2); + cairo_set_source_rgba (cr, 0, 0, 0, 0.5); + cairo_stroke (cr); + } + + cairo_restore (cr); + + if (cairo_status (cr)) + { + g_warning ("drawing failure for render node %s: %s", + g_type_name_from_instance ((GTypeInstance *) node), + cairo_status_to_string (cairo_status (cr))); + } +} + +void +gsk_render_node_draw_with_color_state (GskRenderNode *node, + cairo_t *cr, + GdkColorState *color_state) +{ + GdkColorState *ccs; + + ccs = gdk_color_state_get_rendering_color_state (color_state); + + if (gdk_color_state_equal (color_state, ccs)) + { + gsk_render_node_draw_ccs (node, cr, ccs); + } + else + { + cairo_save (cr); + gdk_cairo_rect (cr, &node->bounds); + cairo_clip (cr); + cairo_push_group (cr); + + gsk_render_node_draw_ccs (node, cr, ccs); + gdk_cairo_surface_convert_color_state (cairo_get_group_target (cr), + ccs, + color_state); + cairo_pop_group_to_source (cr); + cairo_paint (cr); + cairo_restore (cr); + } +} + /** * gsk_render_node_draw: * @node: a `GskRenderNode` @@ -393,28 +458,7 @@ gsk_render_node_draw (GskRenderNode *node, g_return_if_fail (cr != NULL); g_return_if_fail (cairo_status (cr) == CAIRO_STATUS_SUCCESS); - cairo_save (cr); - - GSK_RENDER_NODE_GET_CLASS (node)->draw (node, cr); - - if (GSK_DEBUG_CHECK (GEOMETRY)) - { - cairo_set_operator (cr, CAIRO_OPERATOR_OVER); - cairo_rectangle (cr, node->bounds.origin.x - 1, node->bounds.origin.y - 1, - node->bounds.size.width + 2, node->bounds.size.height + 2); - cairo_set_line_width (cr, 2); - cairo_set_source_rgba (cr, 0, 0, 0, 0.5); - cairo_stroke (cr); - } - - cairo_restore (cr); - - if (cairo_status (cr)) - { - g_warning ("drawing failure for render node %s: %s", - g_type_name_from_instance ((GTypeInstance *) node), - cairo_status_to_string (cairo_status (cr))); - } + gsk_render_node_draw_with_color_state (node, cr, GDK_COLOR_STATE_SRGB); } /* diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c index 426e4f3d9d..a7d0399b7a 100644 --- a/gsk/gskrendernodeimpl.c +++ b/gsk/gskrendernodeimpl.c @@ -33,6 +33,7 @@ #include "gsktransformprivate.h" #include "gskprivate.h" +#include "gdk/gdkcairoprivate.h" #include "gdk/gdkcolorstateprivate.h" #include "gdk/gdkmemoryformatprivate.h" #include "gdk/gdkprivate.h" @@ -89,15 +90,6 @@ my_color_stops_get_depth (const GskColorStop *stops, return gdk_color_state_get_depth (GDK_COLOR_STATE_SRGB); } -static inline void -gsk_cairo_rectangle (cairo_t *cr, - const graphene_rect_t *rect) -{ - cairo_rectangle (cr, - rect->origin.x, rect->origin.y, - rect->size.width, rect->size.height); -} - /* apply a rectangle that bounds @rect in * pixel-aligned device coordinates. * @@ -186,13 +178,14 @@ struct _GskColorNode static void gsk_color_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskColorNode *self = (GskColorNode *) node; - gdk_cairo_set_source_rgba (cr, &self->color); + gdk_cairo_set_source_rgba_ccs (cr, ccs, &self->color); - gsk_cairo_rectangle (cr, &node->bounds); + gdk_cairo_rect (cr, &node->bounds); cairo_fill (cr); } @@ -312,7 +305,8 @@ gsk_linear_gradient_node_finalize (GskRenderNode *node) static void gsk_linear_gradient_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskLinearGradientNode *self = (GskLinearGradientNode *) node; cairo_pattern_t *pattern; @@ -325,33 +319,21 @@ gsk_linear_gradient_node_draw (GskRenderNode *node, cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT); if (self->stops[0].offset > 0.0) - cairo_pattern_add_color_stop_rgba (pattern, - 0.0, - self->stops[0].color.red, - self->stops[0].color.green, - self->stops[0].color.blue, - self->stops[0].color.alpha); + gdk_cairo_pattern_add_color_stop_rgba_ccs (pattern, ccs, 0.0, &self->stops[0].color); 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); + gdk_cairo_pattern_add_color_stop_rgba_ccs (pattern, + ccs, + self->stops[i].offset, + &self->stops[i].color); } if (self->stops[self->n_stops-1].offset < 1.0) - cairo_pattern_add_color_stop_rgba (pattern, - 1.0, - self->stops[self->n_stops-1].color.red, - self->stops[self->n_stops-1].color.green, - self->stops[self->n_stops-1].color.blue, - self->stops[self->n_stops-1].color.alpha); + gdk_cairo_pattern_add_color_stop_rgba_ccs (pattern, ccs, 1.0, &self->stops[self->n_stops-1].color); cairo_set_source (cr, pattern); cairo_pattern_destroy (pattern); - gsk_cairo_rectangle (cr, &node->bounds); + gdk_cairo_rect (cr, &node->bounds); cairo_fill (cr); } @@ -636,7 +618,8 @@ gsk_radial_gradient_node_finalize (GskRenderNode *node) static void gsk_radial_gradient_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskRadialGradientNode *self = (GskRadialGradientNode *) node; cairo_pattern_t *pattern; @@ -659,30 +642,18 @@ gsk_radial_gradient_node_draw (GskRenderNode *node, cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); if (self->stops[0].offset > 0.0) - cairo_pattern_add_color_stop_rgba (pattern, - 0.0, - self->stops[0].color.red, - self->stops[0].color.green, - self->stops[0].color.blue, - self->stops[0].color.alpha); + gdk_cairo_pattern_add_color_stop_rgba_ccs (pattern, ccs, 0.0, &self->stops[0].color); 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); + gdk_cairo_pattern_add_color_stop_rgba_ccs (pattern, + ccs, + self->stops[i].offset, + &self->stops[i].color); } if (self->stops[self->n_stops-1].offset < 1.0) - cairo_pattern_add_color_stop_rgba (pattern, - 1.0, - self->stops[self->n_stops-1].color.red, - self->stops[self->n_stops-1].color.green, - self->stops[self->n_stops-1].color.blue, - self->stops[self->n_stops-1].color.alpha); + gdk_cairo_pattern_add_color_stop_rgba_ccs (pattern, ccs, 1.0, &self->stops[self->n_stops-1].color); - gsk_cairo_rectangle (cr, &node->bounds); + gdk_cairo_rect (cr, &node->bounds); cairo_translate (cr, self->center.x, self->center.y); cairo_set_source (cr, pattern); cairo_fill (cr); @@ -1050,9 +1021,9 @@ gsk_conic_gradient_node_finalize (GskRenderNode *node) static void _cairo_mesh_pattern_set_corner_rgba (cairo_pattern_t *pattern, guint corner_num, - const GdkRGBA *rgba) + const float color[4]) { - cairo_mesh_pattern_set_corner_color_rgba (pattern, corner_num, rgba->red, rgba->green, rgba->blue, rgba->alpha); + cairo_mesh_pattern_set_corner_color_rgba (pattern, corner_num, color[0], color[1], color[2], color[3]); } static void @@ -1075,6 +1046,7 @@ project (double angle, static void gsk_conic_gradient_node_add_patch (cairo_pattern_t *pattern, + GdkColorState *ccs, float radius, float start_angle, const GdkRGBA *start_color, @@ -1082,6 +1054,7 @@ gsk_conic_gradient_node_add_patch (cairo_pattern_t *pattern, const GdkRGBA *end_color) { double x, y; + float start[4], end[4]; cairo_mesh_pattern_begin_patch (pattern); @@ -1092,10 +1065,12 @@ 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); + gdk_color_state_from_rgba (ccs, start_color, start); + _cairo_mesh_pattern_set_corner_rgba (pattern, 0, start); + _cairo_mesh_pattern_set_corner_rgba (pattern, 1, start); + gdk_color_state_from_rgba (ccs, end_color, end); + _cairo_mesh_pattern_set_corner_rgba (pattern, 2, end); + _cairo_mesh_pattern_set_corner_rgba (pattern, 3, end); cairo_mesh_pattern_end_patch (pattern); } @@ -1125,7 +1100,8 @@ gdk_rgba_color_interpolate (GdkRGBA *dest, static void gsk_conic_gradient_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskConicGradientNode *self = (GskConicGradientNode *) node; cairo_pattern_t *pattern; @@ -1169,6 +1145,7 @@ gsk_conic_gradient_node_draw (GskRenderNode *node, (end_angle - offset1) / (offset2 - offset1)); gsk_conic_gradient_node_add_patch (pattern, + ccs, radius, DEG_TO_RAD (start_angle), &start_color, @@ -1179,7 +1156,7 @@ gsk_conic_gradient_node_draw (GskRenderNode *node, cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); - gsk_cairo_rectangle (cr, &node->bounds); + gdk_cairo_rect (cr, &node->bounds); cairo_translate (cr, self->center.x, self->center.y); cairo_set_source (cr, pattern); cairo_fill (cr); @@ -1408,7 +1385,8 @@ struct _GskBorderNode static void gsk_border_node_mesh_add_patch (cairo_pattern_t *pattern, - const GdkRGBA *color, + GdkColorState *ccs, + const GdkRGBA *rgba, double x0, double y0, double x1, @@ -1418,21 +1396,25 @@ gsk_border_node_mesh_add_patch (cairo_pattern_t *pattern, double x3, double y3) { + float color[4]; + + gdk_color_state_from_rgba (ccs, rgba, 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, color[0], color[1], color[2], color[3]); + cairo_mesh_pattern_set_corner_color_rgba (pattern, 1, color[0], color[1], color[2], color[3]); + cairo_mesh_pattern_set_corner_color_rgba (pattern, 2, color[0], color[1], color[2], color[3]); + cairo_mesh_pattern_set_corner_color_rgba (pattern, 3, color[0], color[1], color[2], color[3]); cairo_mesh_pattern_end_patch (pattern); } static void gsk_border_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskBorderNode *self = (GskBorderNode *) node; GskRoundedRect inside; @@ -1452,7 +1434,7 @@ gsk_border_node_draw (GskRenderNode *node, gdk_rgba_equal (&self->border_color[0], &self->border_color[2]) && gdk_rgba_equal (&self->border_color[0], &self->border_color[3])) { - gdk_cairo_set_source_rgba (cr, &self->border_color[0]); + gdk_cairo_set_source_rgba_ccs (cr, ccs, &self->border_color[0]); } else { @@ -1494,6 +1476,7 @@ gsk_border_node_draw (GskRenderNode *node, if (self->border_width[0] > 0) { gsk_border_node_mesh_add_patch (mesh, + ccs, &self->border_color[0], 0, 0, tl.x, tl.y, @@ -1505,6 +1488,7 @@ gsk_border_node_draw (GskRenderNode *node, if (self->border_width[1] > 0) { gsk_border_node_mesh_add_patch (mesh, + ccs, &self->border_color[1], bounds->size.width, 0, br.x, tl.y, @@ -1516,6 +1500,7 @@ gsk_border_node_draw (GskRenderNode *node, if (self->border_width[2] > 0) { gsk_border_node_mesh_add_patch (mesh, + ccs, &self->border_color[2], 0, bounds->size.height, tl.x, br.y, @@ -1527,6 +1512,7 @@ gsk_border_node_draw (GskRenderNode *node, if (self->border_width[3] > 0) { gsk_border_node_mesh_add_patch (mesh, + ccs, &self->border_color[3], 0, 0, tl.x, tl.y, @@ -1745,7 +1731,8 @@ gsk_texture_node_finalize (GskRenderNode *node) static void gsk_texture_node_draw_oversized (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskTextureNode *self = (GskTextureNode *) node; cairo_surface_t *surface; @@ -1762,6 +1749,12 @@ gsk_texture_node_draw_oversized (GskRenderNode *node, bytes = gdk_texture_downloader_download_bytes (&downloader, &stride); gdk_texture_downloader_finish (&downloader); data = g_bytes_get_data (bytes, NULL); + gdk_memory_convert_color_state ((guchar *) data, + stride, + GDK_MEMORY_DEFAULT, + GDK_COLOR_STATE_SRGB, + ccs, + width, height); gsk_cairo_rectangle_pixel_aligned (cr, &node->bounds); cairo_clip (cr); @@ -1802,7 +1795,8 @@ gsk_texture_node_draw_oversized (GskRenderNode *node, static void gsk_texture_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskTextureNode *self = (GskTextureNode *) node; cairo_surface_t *surface; @@ -1814,11 +1808,11 @@ gsk_texture_node_draw (GskRenderNode *node, height = gdk_texture_get_height (self->texture); if (width > MAX_CAIRO_IMAGE_WIDTH || height > MAX_CAIRO_IMAGE_HEIGHT) { - gsk_texture_node_draw_oversized (node, cr); + gsk_texture_node_draw_oversized (node, cr, ccs); return; } - surface = gdk_texture_download_surface (self->texture, GDK_COLOR_STATE_SRGB); + surface = gdk_texture_download_surface (self->texture, ccs); pattern = cairo_pattern_create_for_surface (surface); cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); @@ -1834,7 +1828,7 @@ gsk_texture_node_draw (GskRenderNode *node, cairo_pattern_destroy (pattern); cairo_surface_destroy (surface); - gsk_cairo_rectangle (cr, &node->bounds); + gdk_cairo_rect (cr, &node->bounds); cairo_fill (cr); } @@ -1967,7 +1961,8 @@ gsk_texture_scale_node_finalize (GskRenderNode *node) static void gsk_texture_scale_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskTextureScaleNode *self = (GskTextureScaleNode *) node; cairo_surface_t *surface; @@ -1983,7 +1978,7 @@ gsk_texture_scale_node_draw (GskRenderNode *node, graphene_rect_t clip_rect; /* Make sure we draw the minimum region by using the clip */ - gsk_cairo_rectangle (cr, &node->bounds); + gdk_cairo_rect (cr, &node->bounds); cairo_clip (cr); _graphene_rect_init_from_clip_extents (&clip_rect, cr); if (clip_rect.size.width <= 0 || clip_rect.size.height <= 0) @@ -1995,7 +1990,7 @@ gsk_texture_scale_node_draw (GskRenderNode *node, cairo_surface_set_device_offset (surface2, -clip_rect.origin.x, -clip_rect.origin.y); cr2 = cairo_create (surface2); - surface = gdk_texture_download_surface (self->texture, GDK_COLOR_STATE_SRGB); + surface = gdk_texture_download_surface (self->texture, ccs); pattern = cairo_pattern_create_for_surface (surface); cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); @@ -2010,7 +2005,7 @@ gsk_texture_scale_node_draw (GskRenderNode *node, cairo_pattern_destroy (pattern); cairo_surface_destroy (surface); - gsk_cairo_rectangle (cr2, &node->bounds); + gdk_cairo_rect (cr2, &node->bounds); cairo_fill (cr2); cairo_destroy (cr2); @@ -2189,6 +2184,7 @@ has_empty_clip (cairo_t *cr) static void draw_shadow (cairo_t *cr, + GdkColorState *ccs, gboolean inset, const GskRoundedRect *box, const GskRoundedRect *clip_box, @@ -2201,13 +2197,13 @@ draw_shadow (cairo_t *cr, if (has_empty_clip (cr)) return; - gdk_cairo_set_source_rgba (cr, color); + gdk_cairo_set_source_rgba_ccs (cr, ccs, color); shadow_cr = gsk_cairo_blur_start_drawing (cr, radius, blur_flags); cairo_set_fill_rule (shadow_cr, CAIRO_FILL_RULE_EVEN_ODD); gsk_rounded_rect_path (box, shadow_cr); if (inset) - gsk_cairo_rectangle (shadow_cr, &clip_box->bounds); + gdk_cairo_rect (shadow_cr, &clip_box->bounds); cairo_fill (shadow_cr); @@ -2246,6 +2242,7 @@ corner_mask_equal (CornerMask *mask1, static void draw_shadow_corner (cairo_t *cr, + GdkColorState *ccs, gboolean inset, const GskRoundedRect *box, const GskRoundedRect *clip_box, @@ -2328,7 +2325,7 @@ draw_shadow_corner (cairo_t *cr, { /* Fall back to generic path if inset or if the corner radius runs into each other */ - draw_shadow (cr, inset, box, clip_box, radius, color, GSK_BLUR_X | GSK_BLUR_Y); + draw_shadow (cr, ccs, inset, box, clip_box, radius, color, GSK_BLUR_X | GSK_BLUR_Y); return; } @@ -2374,7 +2371,7 @@ draw_shadow_corner (cairo_t *cr, g_hash_table_insert (corner_mask_cache, g_memdup2 (&key, sizeof (key)), mask); } - gdk_cairo_set_source_rgba (cr, color); + gdk_cairo_set_source_rgba_ccs (cr, ccs, color); pattern = cairo_pattern_create_for_surface (mask); cairo_matrix_init_identity (&matrix); cairo_matrix_scale (&matrix, sx, sy); @@ -2386,6 +2383,7 @@ draw_shadow_corner (cairo_t *cr, static void draw_shadow_side (cairo_t *cr, + GdkColorState *ccs, gboolean inset, const GskRoundedRect *box, const GskRoundedRect *clip_box, @@ -2441,7 +2439,7 @@ draw_shadow_side (cairo_t *cr, cairo_rectangle (cr, x1, y1, x2 - x1, y2 - y1); cairo_clip (cr); - draw_shadow (cr, inset, box, clip_box, radius, color, blur_flags); + draw_shadow (cr, ccs, inset, box, clip_box, radius, color, blur_flags); } static gboolean @@ -2457,7 +2455,8 @@ needs_blur (double radius) static void gsk_inset_shadow_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskInsetShadowNode *self = (GskInsetShadowNode *) node; GskRoundedRect box, clip_box; @@ -2490,7 +2489,7 @@ gsk_inset_shadow_node_draw (GskRenderNode *node, gsk_rounded_rect_shrink (&clip_box, -clip_radius, -clip_radius, -clip_radius, -clip_radius); if (!needs_blur (blur_radius)) - draw_shadow (cr, TRUE, &box, &clip_box, blur_radius, &self->color, GSK_BLUR_NONE); + draw_shadow (cr, ccs, TRUE, &box, &clip_box, blur_radius, &self->color, GSK_BLUR_NONE); else { cairo_region_t *remaining; @@ -2518,7 +2517,7 @@ gsk_inset_shadow_node_draw (GskRenderNode *node, /* Always clip with remaining to ensure we never draw any area twice */ gdk_cairo_region (cr, remaining); cairo_clip (cr); - draw_shadow_corner (cr, TRUE, &box, &clip_box, blur_radius, &self->color, i, &r); + draw_shadow_corner (cr, ccs, TRUE, &box, &clip_box, blur_radius, &self->color, i, &r); cairo_restore (cr); /* We drew the region, remove it from remaining */ @@ -2532,7 +2531,7 @@ gsk_inset_shadow_node_draw (GskRenderNode *node, /* Always clip with remaining to ensure we never draw any area twice */ gdk_cairo_region (cr, remaining); cairo_clip (cr); - draw_shadow_side (cr, TRUE, &box, &clip_box, blur_radius, &self->color, i, &r); + draw_shadow_side (cr, ccs, TRUE, &box, &clip_box, blur_radius, &self->color, i, &r); cairo_restore (cr); /* We drew the region, remove it from remaining */ @@ -2544,7 +2543,7 @@ gsk_inset_shadow_node_draw (GskRenderNode *node, cairo_save (cr); gdk_cairo_region (cr, remaining); cairo_clip (cr); - draw_shadow (cr, TRUE, &box, &clip_box, blur_radius, &self->color, GSK_BLUR_NONE); + draw_shadow (cr, ccs, TRUE, &box, &clip_box, blur_radius, &self->color, GSK_BLUR_NONE); cairo_restore (cr); cairo_region_destroy (remaining); @@ -2764,7 +2763,8 @@ gsk_outset_shadow_get_extents (GskOutsetShadowNode *self, static void gsk_outset_shadow_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskOutsetShadowNode *self = (GskOutsetShadowNode *) node; GskRoundedRect box, clip_box; @@ -2793,7 +2793,7 @@ gsk_outset_shadow_node_draw (GskRenderNode *node, cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); gsk_rounded_rect_path (&self->outline, cr); - gsk_cairo_rectangle (cr, &clip_box.bounds); + gdk_cairo_rect (cr, &clip_box.bounds); cairo_clip (cr); @@ -2802,7 +2802,7 @@ gsk_outset_shadow_node_draw (GskRenderNode *node, gsk_rounded_rect_shrink (&box, -self->spread, -self->spread, -self->spread, -self->spread); if (!needs_blur (blur_radius)) - draw_shadow (cr, FALSE, &box, &clip_box, blur_radius, &self->color, GSK_BLUR_NONE); + draw_shadow (cr, ccs, FALSE, &box, &clip_box, blur_radius, &self->color, GSK_BLUR_NONE); else { int i; @@ -2832,7 +2832,7 @@ gsk_outset_shadow_node_draw (GskRenderNode *node, /* Always clip with remaining to ensure we never draw any area twice */ gdk_cairo_region (cr, remaining); cairo_clip (cr); - draw_shadow_corner (cr, FALSE, &box, &clip_box, blur_radius, &self->color, i, &r); + draw_shadow_corner (cr, ccs, FALSE, &box, &clip_box, blur_radius, &self->color, i, &r); cairo_restore (cr); /* We drew the region, remove it from remaining */ @@ -2846,7 +2846,7 @@ gsk_outset_shadow_node_draw (GskRenderNode *node, /* Always clip with remaining to ensure we never draw any area twice */ gdk_cairo_region (cr, remaining); cairo_clip (cr); - draw_shadow_side (cr, FALSE, &box, &clip_box, blur_radius, &self->color, i, &r); + draw_shadow_side (cr, ccs, FALSE, &box, &clip_box, blur_radius, &self->color, i, &r); cairo_restore (cr); /* We drew the region, remove it from remaining */ @@ -2858,7 +2858,7 @@ gsk_outset_shadow_node_draw (GskRenderNode *node, cairo_save (cr); gdk_cairo_region (cr, remaining); cairo_clip (cr); - draw_shadow (cr, FALSE, &box, &clip_box, blur_radius, &self->color, GSK_BLUR_NONE); + draw_shadow (cr, ccs, FALSE, &box, &clip_box, blur_radius, &self->color, GSK_BLUR_NONE); cairo_restore (cr); cairo_region_destroy (remaining); @@ -3076,15 +3076,35 @@ gsk_cairo_node_finalize (GskRenderNode *node) static void gsk_cairo_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskCairoNode *self = (GskCairoNode *) node; if (self->surface == NULL) return; - cairo_set_source_surface (cr, self->surface, 0, 0); - cairo_paint (cr); + if (gdk_color_state_equal (ccs, GDK_COLOR_STATE_SRGB)) + { + cairo_set_source_surface (cr, self->surface, 0, 0); + cairo_paint (cr); + } + else + { + cairo_save (cr); + gdk_cairo_rect (cr, &node->bounds); + cairo_clip (cr); + cairo_push_group (cr); + + cairo_set_source_surface (cr, self->surface, 0, 0); + cairo_paint (cr); + gdk_cairo_surface_convert_color_state (cairo_get_group_target (cr), + GDK_COLOR_STATE_SRGB, + ccs); + cairo_pop_group_to_source (cr); + cairo_paint (cr); + cairo_restore (cr); + } } static void @@ -3194,7 +3214,7 @@ gsk_cairo_node_get_draw_context (GskRenderNode *node) res = cairo_create (self->surface); } - gsk_cairo_rectangle (res, &node->bounds); + gdk_cairo_rect (res, &node->bounds); cairo_clip (res); return res; @@ -3234,14 +3254,15 @@ gsk_container_node_finalize (GskRenderNode *node) static void gsk_container_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskContainerNode *container = (GskContainerNode *) node; guint i; for (i = 0; i < container->n_children; i++) { - gsk_render_node_draw (container->children[i], cr); + gsk_render_node_draw_ccs (container->children[i], cr, ccs); } } @@ -3533,7 +3554,8 @@ gsk_transform_node_finalize (GskRenderNode *node) static void gsk_transform_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskTransformNode *self = (GskTransformNode *) node; float xx, yx, xy, yy, dx, dy; @@ -3541,8 +3563,9 @@ gsk_transform_node_draw (GskRenderNode *node, if (gsk_transform_get_category (self->transform) < GSK_TRANSFORM_CATEGORY_2D) { - cairo_set_source_rgb (cr, 255 / 255., 105 / 255., 180 / 255.); - gsk_cairo_rectangle (cr, &node->bounds); + GdkRGBA pink = { 255 / 255., 105 / 255., 180 / 255., 1.0 }; + gdk_cairo_set_source_rgba_ccs (cr, ccs, &pink); + gdk_cairo_rect (cr, &node->bounds); cairo_fill (cr); return; } @@ -3561,7 +3584,7 @@ gsk_transform_node_draw (GskRenderNode *node, } cairo_transform (cr, &ctm); - gsk_render_node_draw (self->child, cr); + gsk_render_node_draw_ccs (self->child, cr, ccs); } static gboolean @@ -3800,7 +3823,8 @@ gsk_opacity_node_finalize (GskRenderNode *node) static void gsk_opacity_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskOpacityNode *self = (GskOpacityNode *) node; @@ -3813,7 +3837,7 @@ gsk_opacity_node_draw (GskRenderNode *node, cairo_push_group (cr); - gsk_render_node_draw (self->child, cr); + gsk_render_node_draw_ccs (self->child, cr, ccs); cairo_pop_group_to_source (cr); cairo_paint_with_alpha (cr, self->opacity); @@ -4008,13 +4032,14 @@ apply_color_matrix_to_pattern (cairo_pattern_t *pattern, static void gsk_color_matrix_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskColorMatrixNode *self = (GskColorMatrixNode *) node; cairo_pattern_t *pattern; /* clip so the push_group() creates a smaller surface */ - gsk_cairo_rectangle (cr, &node->bounds); + gdk_cairo_rect (cr, &node->bounds); cairo_clip (cr); if (has_empty_clip (cr)) @@ -4022,7 +4047,7 @@ gsk_color_matrix_node_draw (GskRenderNode *node, cairo_push_group (cr); - gsk_render_node_draw (self->child, cr); + gsk_render_node_draw_ccs (self->child, cr, ccs); pattern = cairo_pop_group (cr); apply_color_matrix_to_pattern (pattern, &self->color_matrix, &self->color_offset); @@ -4188,6 +4213,7 @@ gsk_repeat_node_finalize (GskRenderNode *node) static void gsk_repeat_node_draw_tiled (cairo_t *cr, + GdkColorState *ccs, const graphene_rect_t *rect, float x, float y, @@ -4203,11 +4229,11 @@ gsk_repeat_node_draw_tiled (cairo_t *cr, cairo_translate (cr, x * child_bounds->size.width, y * child_bounds->size.height); - gsk_cairo_rectangle (cr, child_bounds); + gdk_cairo_rect (cr, child_bounds); cairo_clip (cr); cairo_push_group (cr); - gsk_render_node_draw (child, cr); + gsk_render_node_draw_ccs (child, cr, ccs); pattern = cairo_pop_group (cr); cairo_restore (cr); @@ -4220,13 +4246,14 @@ gsk_repeat_node_draw_tiled (cairo_t *cr, cairo_set_source (cr, pattern); cairo_pattern_destroy (pattern); - gsk_cairo_rectangle (cr, rect); + gdk_cairo_rect (cr, rect); cairo_fill (cr); } static void gsk_repeat_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskRepeatNode *self = (GskRepeatNode *) node; graphene_rect_t clip_bounds; @@ -4251,6 +4278,7 @@ gsk_repeat_node_draw (GskRenderNode *node, { /* tile in both directions */ gsk_repeat_node_draw_tiled (cr, + ccs, &clip_bounds, ceilf (tile_left), ceilf (tile_top), @@ -4268,6 +4296,7 @@ gsk_repeat_node_draw (GskRenderNode *node, float end_y = MAX (clip_bounds.origin.y + clip_bounds.size.height, self->child_bounds.origin.y + (y + 1) * self->child_bounds.size.height); gsk_repeat_node_draw_tiled (cr, + ccs, &GRAPHENE_RECT_INIT ( clip_bounds.origin.x, start_y, @@ -4293,6 +4322,7 @@ gsk_repeat_node_draw (GskRenderNode *node, float end_x = MAX (clip_bounds.origin.x + clip_bounds.size.width, self->child_bounds.origin.x + (x + 1) * self->child_bounds.size.width); gsk_repeat_node_draw_tiled (cr, + ccs, &GRAPHENE_RECT_INIT ( start_x, clip_bounds.origin.y, @@ -4318,9 +4348,9 @@ gsk_repeat_node_draw (GskRenderNode *node, cairo_translate (cr, x * self->child_bounds.size.width, y * self->child_bounds.size.height); - gsk_cairo_rectangle (cr, &self->child_bounds); + gdk_cairo_rect (cr, &self->child_bounds); cairo_clip (cr); - gsk_render_node_draw (self->child, cr); + gsk_render_node_draw_ccs (self->child, cr, ccs); cairo_restore (cr); } } @@ -4475,16 +4505,17 @@ gsk_clip_node_finalize (GskRenderNode *node) static void gsk_clip_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskClipNode *self = (GskClipNode *) node; cairo_save (cr); - gsk_cairo_rectangle (cr, &self->clip); + gdk_cairo_rect (cr, &self->clip); cairo_clip (cr); - gsk_render_node_draw (self->child, cr); + gsk_render_node_draw_ccs (self->child, cr, ccs); cairo_restore (cr); } @@ -4640,7 +4671,8 @@ gsk_rounded_clip_node_finalize (GskRenderNode *node) static void gsk_rounded_clip_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskRoundedClipNode *self = (GskRoundedClipNode *) node; @@ -4649,7 +4681,7 @@ gsk_rounded_clip_node_draw (GskRenderNode *node, gsk_rounded_rect_path (&self->clip, cr); cairo_clip (cr); - gsk_render_node_draw (self->child, cr); + gsk_render_node_draw_ccs (self->child, cr, ccs); cairo_restore (cr); } @@ -4828,7 +4860,8 @@ gsk_fill_node_finalize (GskRenderNode *node) static void gsk_fill_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskFillNode *self = (GskFillNode *) node; @@ -4848,13 +4881,13 @@ gsk_fill_node_draw (GskRenderNode *node, if (gsk_render_node_get_node_type (self->child) == GSK_COLOR_NODE && gsk_rect_contains_rect (&self->child->bounds, &node->bounds)) { - gdk_cairo_set_source_rgba (cr, gsk_color_node_get_color (self->child)); + gdk_cairo_set_source_rgba_ccs (cr, ccs, gsk_color_node_get_color (self->child)); cairo_fill (cr); } else { cairo_clip (cr); - gsk_render_node_draw (self->child, cr); + gsk_render_node_draw_ccs (self->child, cr, ccs); } } @@ -5036,14 +5069,15 @@ gsk_stroke_node_finalize (GskRenderNode *node) static void gsk_stroke_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskStrokeNode *self = (GskStrokeNode *) node; if (gsk_render_node_get_node_type (self->child) == GSK_COLOR_NODE && gsk_rect_contains_rect (&self->child->bounds, &node->bounds)) { - gdk_cairo_set_source_rgba (cr, gsk_color_node_get_color (self->child)); + gdk_cairo_set_source_rgba_ccs (cr, ccs, gsk_color_node_get_color (self->child)); } else { @@ -5053,7 +5087,7 @@ gsk_stroke_node_draw (GskRenderNode *node, return; cairo_push_group (cr); - gsk_render_node_draw (self->child, cr); + gsk_render_node_draw_ccs (self->child, cr, ccs); cairo_pop_group_to_source (cr); } @@ -5241,7 +5275,8 @@ gsk_shadow_node_finalize (GskRenderNode *node) static void gsk_shadow_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskShadowNode *self = (GskShadowNode *) node; gsize i; @@ -5267,10 +5302,10 @@ gsk_shadow_node_draw (GskRenderNode *node, cairo_save (cr); cairo_translate (cr, shadow->dx, shadow->dy); cairo_push_group (cr); - gsk_render_node_draw (self->child, cr); + gsk_render_node_draw_ccs (self->child, cr, ccs); pattern = cairo_pop_group (cr); cairo_reset_clip (cr); - gdk_cairo_set_source_rgba (cr, &shadow->color); + gdk_cairo_set_source_rgba_ccs (cr, ccs, &shadow->color); cairo_mask (cr, pattern); cairo_pattern_destroy (pattern); cairo_restore (cr); @@ -5279,7 +5314,7 @@ gsk_shadow_node_draw (GskRenderNode *node, cairo_restore (cr); } - gsk_render_node_draw (self->child, cr); + gsk_render_node_draw_ccs (self->child, cr, ccs); } static void @@ -5543,18 +5578,22 @@ gsk_blend_node_finalize (GskRenderNode *node) static void gsk_blend_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskBlendNode *self = (GskBlendNode *) node; if (has_empty_clip (cr)) return; - cairo_push_group (cr); - gsk_render_node_draw (self->bottom, cr); + if (!gdk_color_state_equal (ccs, GDK_COLOR_STATE_SRGB)) + g_warning ("blend node in non-srgb colorstate isn't implemented yet."); cairo_push_group (cr); - gsk_render_node_draw (self->top, cr); + gsk_render_node_draw_ccs (self->bottom, cr, ccs); + + cairo_push_group (cr); + gsk_render_node_draw_ccs (self->top, cr, ccs); cairo_pop_group_to_source (cr); cairo_set_operator (cr, gsk_blend_mode_to_cairo_operator (self->blend_mode)); @@ -5713,7 +5752,8 @@ gsk_cross_fade_node_finalize (GskRenderNode *node) static void gsk_cross_fade_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskCrossFadeNode *self = (GskCrossFadeNode *) node; @@ -5721,10 +5761,10 @@ gsk_cross_fade_node_draw (GskRenderNode *node, return; cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR_ALPHA); - gsk_render_node_draw (self->start, cr); + gsk_render_node_draw_ccs (self->start, cr, ccs); cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR_ALPHA); - gsk_render_node_draw (self->end, cr); + gsk_render_node_draw_ccs (self->end, cr, ccs); cairo_pop_group_to_source (cr); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); @@ -5906,7 +5946,8 @@ gsk_text_node_finalize (GskRenderNode *node) static void gsk_text_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskTextNode *self = (GskTextNode *) node; PangoGlyphString glyphs; @@ -5917,9 +5958,17 @@ gsk_text_node_draw (GskRenderNode *node, cairo_save (cr); - gdk_cairo_set_source_rgba (cr, &self->color); - cairo_translate (cr, self->offset.x, self->offset.y); - pango_cairo_show_glyph_string (cr, self->font, &glyphs); + if (!gdk_color_state_equal (ccs, GDK_COLOR_STATE_SRGB) && + self->has_color_glyphs) + { + g_warning ("whoopsie, color glyphs and we're not in sRGB"); + } + else + { + gdk_cairo_set_source_rgba_ccs (cr, ccs, &self->color); + cairo_translate (cr, self->offset.x, self->offset.y); + pango_cairo_show_glyph_string (cr, self->font, &glyphs); + } cairo_restore (cr); } @@ -6335,7 +6384,8 @@ blur_image_surface (cairo_surface_t *surface, int radius, int iterations) static void gsk_blur_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskBlurNode *self = (GskBlurNode *) node; cairo_surface_t *surface; @@ -6361,7 +6411,7 @@ gsk_blur_node_draw (GskRenderNode *node, - blur_bounds.origin.y); cr2 = cairo_create (surface); - gsk_render_node_draw (self->child, cr2); + gsk_render_node_draw_ccs (self->child, cr2, ccs); cairo_destroy (cr2); blur_image_surface (surface, (int) ceil (0.5 * self->radius), 3); @@ -6573,7 +6623,8 @@ apply_luminance_to_pattern (cairo_pattern_t *pattern, static void gsk_mask_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskMaskNode *self = (GskMaskNode *) node; cairo_pattern_t *mask_pattern; @@ -6581,18 +6632,18 @@ gsk_mask_node_draw (GskRenderNode *node, graphene_vec4_t color_offset; /* clip so the push_group() creates a smaller surface */ - gsk_cairo_rectangle (cr, &node->bounds); + gdk_cairo_rect (cr, &node->bounds); cairo_clip (cr); if (has_empty_clip (cr)) return; cairo_push_group (cr); - gsk_render_node_draw (self->source, cr); + gsk_render_node_draw_ccs (self->source, cr, ccs); cairo_pop_group_to_source (cr); cairo_push_group (cr); - gsk_render_node_draw (self->mask, cr); + gsk_render_node_draw_ccs (self->mask, cr, ccs); mask_pattern = cairo_pop_group (cr); switch (self->mask_mode) @@ -6617,7 +6668,7 @@ gsk_mask_node_draw (GskRenderNode *node, g_assert_not_reached (); } - gsk_cairo_rectangle (cr, &node->bounds); + gdk_cairo_rect (cr, &node->bounds); cairo_clip (cr); cairo_mask (cr, mask_pattern); @@ -6786,11 +6837,12 @@ gsk_debug_node_finalize (GskRenderNode *node) static void gsk_debug_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskDebugNode *self = (GskDebugNode *) node; - gsk_render_node_draw (self->child, cr); + gsk_render_node_draw_ccs (self->child, cr, ccs); } static gboolean @@ -6944,10 +6996,13 @@ gsk_gl_shader_node_finalize (GskRenderNode *node) static void gsk_gl_shader_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { - cairo_set_source_rgb (cr, 255 / 255., 105 / 255., 180 / 255.); - gsk_cairo_rectangle (cr, &node->bounds); + GdkRGBA pink = { 255 / 255., 105 / 255., 180 / 255., 1.0 }; + + gdk_cairo_set_source_rgba_ccs (cr, ccs, &pink); + gdk_cairo_rect (cr, &node->bounds); cairo_fill (cr); } @@ -7179,11 +7234,12 @@ gsk_subsurface_node_finalize (GskRenderNode *node) static void gsk_subsurface_node_draw (GskRenderNode *node, - cairo_t *cr) + cairo_t *cr, + GdkColorState *ccs) { GskSubsurfaceNode *self = (GskSubsurfaceNode *) node; - gsk_render_node_draw (self->child, cr); + gsk_render_node_draw_ccs (self->child, cr, ccs); } static gboolean diff --git a/gsk/gskrendernodeprivate.h b/gsk/gskrendernodeprivate.h index 66dc4cf86b..c4c6b00ebf 100644 --- a/gsk/gskrendernodeprivate.h +++ b/gsk/gskrendernodeprivate.h @@ -51,7 +51,8 @@ struct _GskRenderNodeClass void (* finalize) (GskRenderNode *node); void (* draw) (GskRenderNode *node, - cairo_t *cr); + cairo_t *cr, + GdkColorState *ccs); gboolean (* can_diff) (const GskRenderNode *node1, const GskRenderNode *node2); void (* diff) (GskRenderNode *node1, @@ -82,6 +83,12 @@ void gsk_render_node_diff_impossible (GskRenderNode void gsk_container_node_diff_with (GskRenderNode *container, GskRenderNode *other, GskDiffData *data); +void gsk_render_node_draw_ccs (GskRenderNode *node, + cairo_t *cr, + GdkColorState *ccs); +void gsk_render_node_draw_with_color_state (GskRenderNode *node, + cairo_t *cr, + GdkColorState *color_state); void gsk_render_node_draw_fallback (GskRenderNode *node, cairo_t *cr);