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);