mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-27 06:00:22 +00:00
Merge branch 'css-color-hookup-4' into 'main'
Make non-srgb css colors work for shadows See merge request GNOME/gtk!7557
This commit is contained in:
commit
4426194ee6
@ -56,18 +56,22 @@ static const GskGpuShaderOpClass GSK_GPU_BLUR_OP_CLASS = {
|
||||
static void
|
||||
gsk_gpu_blur_op_full (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
GskGpuColorStates color_states,
|
||||
guint32 variation,
|
||||
GdkColorState *ccs,
|
||||
float opacity,
|
||||
const graphene_point_t *offset,
|
||||
guint32 variation,
|
||||
const GskGpuShaderImage *image,
|
||||
const graphene_vec2_t *blur_direction,
|
||||
float blur_color[4])
|
||||
const GdkColor *blur_color)
|
||||
{
|
||||
GskGpuBlurInstance *instance;
|
||||
GdkColorState *alt;
|
||||
|
||||
alt = gsk_gpu_color_states_find (ccs, blur_color);
|
||||
|
||||
gsk_gpu_shader_op_alloc (frame,
|
||||
&GSK_GPU_BLUR_OP_CLASS,
|
||||
color_states,
|
||||
gsk_gpu_color_states_create (ccs, TRUE, alt, variation & VARIATION_COLORIZE ? FALSE : TRUE),
|
||||
variation,
|
||||
clip,
|
||||
(GskGpuImage *[1]) { image->image },
|
||||
@ -77,41 +81,49 @@ gsk_gpu_blur_op_full (GskGpuFrame *frame,
|
||||
gsk_gpu_rect_to_float (image->coverage, offset, instance->rect);
|
||||
gsk_gpu_rect_to_float (image->bounds, offset, instance->tex_rect);
|
||||
graphene_vec2_to_float (blur_direction, instance->blur_direction);
|
||||
gsk_gpu_vec4_to_float (blur_color, instance->blur_color);
|
||||
gsk_gpu_color_to_float (blur_color, alt, opacity, instance->blur_color);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gpu_blur_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
GskGpuColorStates color_states,
|
||||
GdkColorState *ccs,
|
||||
float opacity,
|
||||
const graphene_point_t *offset,
|
||||
const GskGpuShaderImage *image,
|
||||
const graphene_vec2_t *blur_direction)
|
||||
{
|
||||
GdkColor blur_color;
|
||||
|
||||
gdk_color_init (&blur_color, ccs, (float[]) { 1, 1, 1, 1 });
|
||||
gsk_gpu_blur_op_full (frame,
|
||||
clip,
|
||||
color_states,
|
||||
0,
|
||||
ccs,
|
||||
opacity,
|
||||
offset,
|
||||
0,
|
||||
image,
|
||||
blur_direction,
|
||||
(float[4]) { 1, 1, 1, 1 });
|
||||
&blur_color);
|
||||
gdk_color_finish (&blur_color);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gpu_blur_shadow_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
GskGpuColorStates color_states,
|
||||
GdkColorState *ccs,
|
||||
float opacity,
|
||||
const graphene_point_t *offset,
|
||||
const GskGpuShaderImage *image,
|
||||
const graphene_vec2_t *blur_direction,
|
||||
float shadow_color[4])
|
||||
const GdkColor *shadow_color)
|
||||
{
|
||||
gsk_gpu_blur_op_full (frame,
|
||||
clip,
|
||||
color_states,
|
||||
VARIATION_COLORIZE,
|
||||
ccs,
|
||||
opacity,
|
||||
offset,
|
||||
VARIATION_COLORIZE,
|
||||
image,
|
||||
blur_direction,
|
||||
shadow_color);
|
||||
|
@ -8,18 +8,20 @@ G_BEGIN_DECLS
|
||||
|
||||
void gsk_gpu_blur_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
GskGpuColorStates color_states,
|
||||
GdkColorState *ccs,
|
||||
float opacity,
|
||||
const graphene_point_t *offset,
|
||||
const GskGpuShaderImage *image,
|
||||
const graphene_vec2_t *blur_direction);
|
||||
|
||||
void gsk_gpu_blur_shadow_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
GskGpuColorStates color_states,
|
||||
GdkColorState *ccs,
|
||||
float opacity,
|
||||
const graphene_point_t *offset,
|
||||
const GskGpuShaderImage *image,
|
||||
const graphene_vec2_t *blur_direction,
|
||||
float shadow_color[4]);
|
||||
const GdkColor *shadow_color);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -52,16 +52,20 @@ static const GskGpuShaderOpClass GSK_GPU_COLORIZE_OP_CLASS = {
|
||||
void
|
||||
gsk_gpu_colorize_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
GskGpuColorStates color_states,
|
||||
GdkColorState *ccs,
|
||||
float opacity,
|
||||
const graphene_point_t *offset,
|
||||
const GskGpuShaderImage *image,
|
||||
const float color[4])
|
||||
const GdkColor *color)
|
||||
{
|
||||
GskGpuColorizeInstance *instance;
|
||||
GdkColorState *alt;
|
||||
|
||||
alt = gsk_gpu_color_states_find (ccs, color);
|
||||
|
||||
gsk_gpu_shader_op_alloc (frame,
|
||||
&GSK_GPU_COLORIZE_OP_CLASS,
|
||||
color_states,
|
||||
gsk_gpu_color_states_create (ccs, TRUE, alt, FALSE),
|
||||
0,
|
||||
clip,
|
||||
(GskGpuImage *[1]) { image->image },
|
||||
@ -70,5 +74,5 @@ gsk_gpu_colorize_op (GskGpuFrame *frame,
|
||||
|
||||
gsk_gpu_rect_to_float (image->coverage ? image->coverage : image->bounds, offset, instance->rect);
|
||||
gsk_gpu_rect_to_float (image->bounds, offset, instance->tex_rect);
|
||||
gsk_gpu_vec4_to_float (color, instance->color);
|
||||
gsk_gpu_color_to_float (color, alt, opacity, instance->color);
|
||||
}
|
||||
|
@ -8,10 +8,11 @@ G_BEGIN_DECLS
|
||||
|
||||
void gsk_gpu_colorize_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
GskGpuColorStates color_states,
|
||||
GdkColorState *ccs,
|
||||
float opacity,
|
||||
const graphene_point_t *offset,
|
||||
const GskGpuShaderImage *image,
|
||||
const float color[4]);
|
||||
const GdkColor *color);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -265,12 +265,6 @@ gsk_gpu_node_processor_color_states_explicit (GskGpuNodeProcessor *self,
|
||||
alt_premultiplied);
|
||||
}
|
||||
|
||||
static inline GskGpuColorStates
|
||||
gsk_gpu_node_processor_color_states_self (GskGpuNodeProcessor *self)
|
||||
{
|
||||
return gsk_gpu_color_states_create_equal (TRUE, TRUE);
|
||||
}
|
||||
|
||||
static inline GskGpuColorStates
|
||||
gsk_gpu_node_processor_color_states_for_rgba (GskGpuNodeProcessor *self)
|
||||
{
|
||||
@ -833,7 +827,7 @@ gsk_gpu_node_processor_blur_op (GskGpuNodeProcessor *self,
|
||||
const graphene_rect_t *rect,
|
||||
const graphene_point_t *shadow_offset,
|
||||
float blur_radius,
|
||||
const GdkRGBA *shadow_color,
|
||||
const GdkColor *shadow_color,
|
||||
GskGpuImage *source_image,
|
||||
GdkMemoryDepth source_depth,
|
||||
const graphene_rect_t *source_rect)
|
||||
@ -869,7 +863,8 @@ gsk_gpu_node_processor_blur_op (GskGpuNodeProcessor *self,
|
||||
graphene_vec2_init (&direction, blur_radius, 0.0f);
|
||||
gsk_gpu_blur_op (other.frame,
|
||||
gsk_gpu_clip_get_shader_clip (&other.clip, &other.offset, &intermediate_rect),
|
||||
gsk_gpu_node_processor_color_states_self (&other),
|
||||
other.ccs,
|
||||
1,
|
||||
&other.offset,
|
||||
&(GskGpuShaderImage) {
|
||||
source_image,
|
||||
@ -888,7 +883,8 @@ gsk_gpu_node_processor_blur_op (GskGpuNodeProcessor *self,
|
||||
{
|
||||
gsk_gpu_blur_shadow_op (self->frame,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &real_offset, rect),
|
||||
gsk_gpu_node_processor_color_states_for_rgba (self),
|
||||
self->ccs,
|
||||
1,
|
||||
&real_offset,
|
||||
&(GskGpuShaderImage) {
|
||||
intermediate,
|
||||
@ -897,13 +893,14 @@ gsk_gpu_node_processor_blur_op (GskGpuNodeProcessor *self,
|
||||
&intermediate_rect,
|
||||
},
|
||||
&direction,
|
||||
GSK_RGBA_TO_VEC4 (shadow_color));
|
||||
shadow_color);
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_gpu_blur_op (self->frame,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &real_offset, rect),
|
||||
gsk_gpu_node_processor_color_states_self (self),
|
||||
self->ccs,
|
||||
1,
|
||||
&real_offset,
|
||||
&(GskGpuShaderImage) {
|
||||
intermediate,
|
||||
@ -2635,14 +2632,17 @@ gsk_gpu_node_processor_add_shadow_node (GskGpuNodeProcessor *self,
|
||||
|
||||
for (i = 0; i < n_shadows; i++)
|
||||
{
|
||||
const GskShadow *shadow = gsk_shadow_node_get_shadow (node, i);
|
||||
const GskShadow2 *shadow = gsk_shadow_node_get_shadow2 (node, i);
|
||||
|
||||
if (shadow->radius == 0)
|
||||
{
|
||||
graphene_point_t shadow_offset = GRAPHENE_POINT_INIT (self->offset.x + shadow->dx,
|
||||
self->offset.y + shadow->dy);
|
||||
graphene_point_t shadow_offset = GRAPHENE_POINT_INIT (self->offset.x + shadow->offset.x,
|
||||
self->offset.y + shadow->offset.y);
|
||||
|
||||
gsk_gpu_colorize_op (self->frame,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &shadow_offset, &child->bounds),
|
||||
gsk_gpu_node_processor_color_states_for_rgba (self),
|
||||
self->ccs,
|
||||
1,
|
||||
&shadow_offset,
|
||||
&(GskGpuShaderImage) {
|
||||
image,
|
||||
@ -2650,7 +2650,7 @@ gsk_gpu_node_processor_add_shadow_node (GskGpuNodeProcessor *self,
|
||||
&child->bounds,
|
||||
&tex_rect,
|
||||
},
|
||||
GSK_RGBA_TO_VEC4 (&shadow->color));
|
||||
&shadow->color);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2659,7 +2659,7 @@ gsk_gpu_node_processor_add_shadow_node (GskGpuNodeProcessor *self,
|
||||
graphene_rect_inset_r (&child->bounds, - clip_radius, - clip_radius, &bounds);
|
||||
gsk_gpu_node_processor_blur_op (self,
|
||||
&bounds,
|
||||
&GRAPHENE_POINT_INIT (shadow->dx, shadow->dy),
|
||||
&shadow->offset,
|
||||
shadow->radius,
|
||||
&shadow->color,
|
||||
image,
|
||||
@ -2871,14 +2871,10 @@ gsk_gpu_node_processor_add_mask_node (GskGpuNodeProcessor *self,
|
||||
if (gsk_render_node_get_node_type (source_child) == GSK_COLOR_NODE &&
|
||||
mask_mode == GSK_MASK_MODE_ALPHA)
|
||||
{
|
||||
float color[4];
|
||||
|
||||
gdk_color_to_float (gsk_color_node_get_color2 (source_child), self->ccs, color);
|
||||
color[3] *= self->opacity;
|
||||
|
||||
gsk_gpu_colorize_op (self->frame,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
|
||||
gsk_gpu_node_processor_color_states_explicit (self, self->ccs, FALSE),
|
||||
self->ccs,
|
||||
self->opacity,
|
||||
&self->offset,
|
||||
&(GskGpuShaderImage) {
|
||||
mask_image,
|
||||
@ -2886,7 +2882,7 @@ gsk_gpu_node_processor_add_mask_node (GskGpuNodeProcessor *self,
|
||||
&node->bounds,
|
||||
&mask_rect,
|
||||
},
|
||||
color);
|
||||
gsk_color_node_get_color2 (source_child));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2938,7 +2934,7 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
|
||||
graphene_point_t offset;
|
||||
guint i, num_glyphs;
|
||||
float scale;
|
||||
GdkRGBA color;
|
||||
GdkColor color;
|
||||
float align_scale_x, align_scale_y;
|
||||
float inv_align_scale_x, inv_align_scale_y;
|
||||
unsigned int flags_mask;
|
||||
@ -2954,8 +2950,7 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
|
||||
|
||||
cache = gsk_gpu_device_get_cache (gsk_gpu_frame_get_device (self->frame));
|
||||
|
||||
color = *gsk_text_node_get_color (node);
|
||||
color.alpha *= self->opacity;
|
||||
gdk_color_init_from_rgba (&color, gsk_text_node_get_color (node));
|
||||
num_glyphs = gsk_text_node_get_num_glyphs (node);
|
||||
glyphs = gsk_text_node_get_glyphs (node, NULL);
|
||||
font = gsk_text_node_get_font (node);
|
||||
@ -3033,7 +3028,8 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
|
||||
else
|
||||
gsk_gpu_colorize_op (self->frame,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &glyph_origin, &glyph_bounds),
|
||||
gsk_gpu_node_processor_color_states_for_rgba (self),
|
||||
self->ccs,
|
||||
self->opacity,
|
||||
&glyph_origin,
|
||||
&(GskGpuShaderImage) {
|
||||
image,
|
||||
@ -3041,10 +3037,12 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
|
||||
&glyph_bounds,
|
||||
&glyph_tex_rect
|
||||
},
|
||||
GSK_RGBA_TO_VEC4 (&color));
|
||||
&color);
|
||||
|
||||
offset.x += glyphs[i].geometry.width * inv_pango_scale;
|
||||
}
|
||||
|
||||
gdk_color_finish (&color);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -5565,7 +5565,9 @@ struct _GskShadowNode
|
||||
GskRenderNode *child;
|
||||
|
||||
gsize n_shadows;
|
||||
GskShadow *shadows;
|
||||
GskShadow2 *shadows;
|
||||
|
||||
GskShadow *rgba_shadows;
|
||||
};
|
||||
|
||||
static void
|
||||
@ -5575,8 +5577,13 @@ gsk_shadow_node_finalize (GskRenderNode *node)
|
||||
GskRenderNodeClass *parent_class = g_type_class_peek (g_type_parent (GSK_TYPE_SHADOW_NODE));
|
||||
|
||||
gsk_render_node_unref (self->child);
|
||||
|
||||
for (gsize i = 0; i < self->n_shadows; i++)
|
||||
gdk_color_finish (&self->shadows[i].color);
|
||||
g_free (self->shadows);
|
||||
|
||||
g_free (self->rgba_shadows);
|
||||
|
||||
parent_class->finalize (node);
|
||||
}
|
||||
|
||||
@ -5596,31 +5603,28 @@ gsk_shadow_node_draw (GskRenderNode *node,
|
||||
|
||||
for (i = 0; i < self->n_shadows; i++)
|
||||
{
|
||||
GskShadow *shadow = &self->shadows[i];
|
||||
GskShadow2 *shadow = &self->shadows[i];
|
||||
cairo_pattern_t *pattern;
|
||||
GdkColor color;
|
||||
|
||||
/* We don't need to draw invisible shadows */
|
||||
if (gdk_rgba_is_clear (&shadow->color))
|
||||
if (gdk_color_is_clear (&shadow->color))
|
||||
continue;
|
||||
|
||||
cairo_save (cr);
|
||||
cr = gsk_cairo_blur_start_drawing (cr, 0.5 * shadow->radius, GSK_BLUR_X | GSK_BLUR_Y);
|
||||
|
||||
cairo_save (cr);
|
||||
cairo_translate (cr, shadow->dx, shadow->dy);
|
||||
cairo_translate (cr, shadow->offset.x, shadow->offset.y);
|
||||
cairo_push_group (cr);
|
||||
gsk_render_node_draw_ccs (self->child, cr, ccs);
|
||||
pattern = cairo_pop_group (cr);
|
||||
cairo_reset_clip (cr);
|
||||
gdk_cairo_set_source_rgba_ccs (cr, ccs, &shadow->color);
|
||||
gdk_cairo_set_source_color (cr, ccs, &shadow->color);
|
||||
cairo_mask (cr, pattern);
|
||||
cairo_pattern_destroy (pattern);
|
||||
cairo_restore (cr);
|
||||
|
||||
gdk_color_init_from_rgba (&color, &shadow->color);
|
||||
cr = gsk_cairo_blur_finish_drawing (cr, ccs, 0.5 * shadow->radius, &color, GSK_BLUR_X | GSK_BLUR_Y);
|
||||
gdk_color_finish (&color);
|
||||
cr = gsk_cairo_blur_finish_drawing (cr, ccs, 0.5 * shadow->radius, &shadow->color, GSK_BLUR_X | GSK_BLUR_Y);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
@ -5647,13 +5651,12 @@ gsk_shadow_node_diff (GskRenderNode *node1,
|
||||
|
||||
for (i = 0; i < self1->n_shadows; i++)
|
||||
{
|
||||
GskShadow *shadow1 = &self1->shadows[i];
|
||||
GskShadow *shadow2 = &self2->shadows[i];
|
||||
GskShadow2 *shadow1 = &self1->shadows[i];
|
||||
GskShadow2 *shadow2 = &self2->shadows[i];
|
||||
float clip_radius;
|
||||
|
||||
if (!gdk_rgba_equal (&shadow1->color, &shadow2->color) ||
|
||||
shadow1->dx != shadow2->dx ||
|
||||
shadow1->dy != shadow2->dy ||
|
||||
if (!gdk_color_equal (&shadow1->color, &shadow2->color) ||
|
||||
!graphene_point_equal (&shadow1->offset, &shadow2->offset) ||
|
||||
shadow1->radius != shadow2->radius)
|
||||
{
|
||||
gsk_render_node_diff_impossible (node1, node2, data);
|
||||
@ -5661,10 +5664,10 @@ gsk_shadow_node_diff (GskRenderNode *node1,
|
||||
}
|
||||
|
||||
clip_radius = gsk_cairo_blur_compute_pixels (shadow1->radius / 2.0);
|
||||
top = MAX (top, ceil (clip_radius - shadow1->dy));
|
||||
right = MAX (right, ceil (clip_radius + shadow1->dx));
|
||||
bottom = MAX (bottom, ceil (clip_radius + shadow1->dy));
|
||||
left = MAX (left, ceil (clip_radius - shadow1->dx));
|
||||
top = MAX (top, ceil (clip_radius - shadow1->offset.y));
|
||||
right = MAX (right, ceil (clip_radius + shadow1->offset.x));
|
||||
bottom = MAX (bottom, ceil (clip_radius + shadow1->offset.y));
|
||||
left = MAX (left, ceil (clip_radius - shadow1->offset.x));
|
||||
}
|
||||
|
||||
sub = cairo_region_create ();
|
||||
@ -5695,10 +5698,10 @@ gsk_shadow_node_get_bounds (GskShadowNode *self,
|
||||
for (i = 0; i < self->n_shadows; i++)
|
||||
{
|
||||
float clip_radius = gsk_cairo_blur_compute_pixels (self->shadows[i].radius / 2.0);
|
||||
top = MAX (top, clip_radius - self->shadows[i].dy);
|
||||
right = MAX (right, clip_radius + self->shadows[i].dx);
|
||||
bottom = MAX (bottom, clip_radius + self->shadows[i].dy);
|
||||
left = MAX (left, clip_radius - self->shadows[i].dx);
|
||||
top = MAX (top, clip_radius - self->shadows[i].offset.y);
|
||||
right = MAX (right, clip_radius + self->shadows[i].offset.x);
|
||||
bottom = MAX (bottom, clip_radius + self->shadows[i].offset.y);
|
||||
left = MAX (left, clip_radius - self->shadows[i].offset.x);
|
||||
}
|
||||
|
||||
bounds->origin.x -= left;
|
||||
@ -5735,10 +5738,52 @@ GskRenderNode *
|
||||
gsk_shadow_node_new (GskRenderNode *child,
|
||||
const GskShadow *shadows,
|
||||
gsize n_shadows)
|
||||
{
|
||||
GskShadow2 *shadows2;
|
||||
GskRenderNode *node;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_RENDER_NODE (child), NULL);
|
||||
g_return_val_if_fail (shadows != NULL, NULL);
|
||||
g_return_val_if_fail (n_shadows > 0, NULL);
|
||||
|
||||
shadows2 = g_new (GskShadow2, n_shadows);
|
||||
for (gsize i = 0; i < n_shadows; i++)
|
||||
{
|
||||
gdk_color_init_from_rgba (&shadows2[i].color, &shadows[i].color);
|
||||
graphene_point_init (&shadows2[i].offset, shadows[i].dx, shadows[i].dy);
|
||||
shadows2[i].radius = shadows[i].radius;
|
||||
}
|
||||
|
||||
node = gsk_shadow_node_new2 (child, shadows2, n_shadows);
|
||||
|
||||
for (gsize i = 0; i < n_shadows; i++)
|
||||
gdk_color_finish (&shadows2[i].color);
|
||||
g_free (shadows2);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gsk_shadow_node_new2:
|
||||
* @child: The node to draw
|
||||
* @shadows: (array length=n_shadows): The shadows to apply
|
||||
* @n_shadows: number of entries in the @shadows array
|
||||
*
|
||||
* Creates a `GskRenderNode` that will draw a @child with the given
|
||||
* @shadows below it.
|
||||
*
|
||||
* Returns: (transfer full) (type GskShadowNode): A new `GskRenderNode`
|
||||
*/
|
||||
GskRenderNode *
|
||||
gsk_shadow_node_new2 (GskRenderNode *child,
|
||||
const GskShadow2 *shadows,
|
||||
gsize n_shadows)
|
||||
{
|
||||
GskShadowNode *self;
|
||||
GskRenderNode *node;
|
||||
gsize i;
|
||||
GdkMemoryDepth depth;
|
||||
gboolean is_hdr;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_RENDER_NODE (child), NULL);
|
||||
g_return_val_if_fail (shadows != NULL, NULL);
|
||||
@ -5750,19 +5795,25 @@ gsk_shadow_node_new (GskRenderNode *child,
|
||||
|
||||
self->child = gsk_render_node_ref (child);
|
||||
self->n_shadows = n_shadows;
|
||||
self->shadows = g_malloc_n (n_shadows, sizeof (GskShadow));
|
||||
memcpy (self->shadows, shadows, n_shadows * sizeof (GskShadow));
|
||||
self->shadows = g_new (GskShadow2, n_shadows);
|
||||
|
||||
gsk_shadow_node_get_bounds (self, &node->bounds);
|
||||
depth = gsk_render_node_get_preferred_depth (child);
|
||||
is_hdr = gsk_render_node_is_hdr (child);
|
||||
|
||||
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
|
||||
node->is_hdr = gsk_render_node_is_hdr (child);
|
||||
for (i = 0; i < n_shadows; i++)
|
||||
{
|
||||
node->preferred_depth = gdk_memory_depth_merge (node->preferred_depth,
|
||||
my_color_get_depth (&shadows->color));
|
||||
gdk_color_init_copy (&self->shadows[i].color, &shadows[i].color);
|
||||
graphene_point_init_from_point (&self->shadows[i].offset, &shadows[i].offset);
|
||||
self->shadows[i].radius = shadows[i].radius;
|
||||
depth = gdk_memory_depth_merge (depth, gdk_color_get_depth (&shadows[i].color));
|
||||
is_hdr = is_hdr || color_state_is_hdr (shadows[i].color.color_state);
|
||||
}
|
||||
|
||||
node->preferred_depth = depth;
|
||||
node->is_hdr = is_hdr;
|
||||
|
||||
gsk_shadow_node_get_bounds (self, &node->bounds);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -5794,6 +5845,45 @@ gsk_shadow_node_get_child (const GskRenderNode *node)
|
||||
const GskShadow *
|
||||
gsk_shadow_node_get_shadow (const GskRenderNode *node,
|
||||
gsize i)
|
||||
{
|
||||
GskShadowNode *self = (GskShadowNode *) node;
|
||||
const GskShadow *shadow;
|
||||
|
||||
G_LOCK (rgba);
|
||||
|
||||
if (self->rgba_shadows == NULL)
|
||||
{
|
||||
self->rgba_shadows = g_new (GskShadow, self->n_shadows);
|
||||
for (gsize j = 0; j < self->n_shadows; j++)
|
||||
{
|
||||
gdk_color_to_float (&self->shadows[j].color,
|
||||
GDK_COLOR_STATE_SRGB,
|
||||
(float *) &self->rgba_shadows[j].color);
|
||||
self->rgba_shadows[j].dx = self->shadows[j].offset.x;
|
||||
self->rgba_shadows[j].dy = self->shadows[j].offset.y;
|
||||
self->rgba_shadows[j].radius = self->shadows[j].radius;
|
||||
}
|
||||
}
|
||||
|
||||
shadow = &self->rgba_shadows[i];
|
||||
|
||||
G_UNLOCK (rgba);
|
||||
|
||||
return shadow;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gsk_shadow_node_get_shadow2:
|
||||
* @node: (type GskShadowNode): a shadow `GskRenderNode`
|
||||
* @i: the given index
|
||||
*
|
||||
* Retrieves the shadow data at the given index @i.
|
||||
*
|
||||
* Returns: (transfer none): the shadow data
|
||||
*/
|
||||
const GskShadow2 *
|
||||
gsk_shadow_node_get_shadow2 (const GskRenderNode *node,
|
||||
gsize i)
|
||||
{
|
||||
const GskShadowNode *self = (const GskShadowNode *) node;
|
||||
|
||||
|
@ -693,6 +693,10 @@ parse_float4 (GtkCssParser *parser,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean parse_color2 (GtkCssParser *parser,
|
||||
Context *context,
|
||||
gpointer color);
|
||||
|
||||
static gboolean
|
||||
parse_shadows (GtkCssParser *parser,
|
||||
Context *context,
|
||||
@ -702,10 +706,11 @@ parse_shadows (GtkCssParser *parser,
|
||||
|
||||
do
|
||||
{
|
||||
GskShadow shadow = { GDK_RGBA("000000"), 0, 0, 0 };
|
||||
GskShadow2 shadow;
|
||||
GdkColor color = GDK_COLOR_SRGB (0, 0, 0, 1);
|
||||
double dx = 0, dy = 0, radius = 0;
|
||||
|
||||
if (!gdk_rgba_parser_parse (parser, &shadow.color))
|
||||
if (!parse_color2 (parser, context, &color))
|
||||
gtk_css_parser_error_value (parser, "Expected shadow color");
|
||||
|
||||
if (!gtk_css_parser_consume_number (parser, &dx))
|
||||
@ -720,11 +725,13 @@ parse_shadows (GtkCssParser *parser,
|
||||
gtk_css_parser_error_value (parser, "Expected shadow blur radius");
|
||||
}
|
||||
|
||||
shadow.dx = dx;
|
||||
shadow.dy = dy;
|
||||
gdk_color_init_copy (&shadow.color, &color);
|
||||
graphene_point_init (&shadow.offset, dx, dy);
|
||||
shadow.radius = radius;
|
||||
|
||||
g_array_append_val (shadows, shadow);
|
||||
|
||||
gdk_color_finish (&color);
|
||||
}
|
||||
while (gtk_css_parser_try_token (parser, GTK_CSS_TOKEN_COMMA));
|
||||
|
||||
@ -734,7 +741,15 @@ parse_shadows (GtkCssParser *parser,
|
||||
static void
|
||||
clear_shadows (gpointer inout_shadows)
|
||||
{
|
||||
g_array_set_size (inout_shadows, 0);
|
||||
GArray *shadows = inout_shadows;
|
||||
|
||||
for (gsize i = 0; i < shadows->len; i++)
|
||||
{
|
||||
GskShadow2 *shadow = &g_array_index (shadows, GskShadow2, i);
|
||||
gdk_color_finish (&shadow->color);
|
||||
}
|
||||
|
||||
g_array_set_size (shadows, 0);
|
||||
}
|
||||
|
||||
static const struct
|
||||
@ -1437,12 +1452,6 @@ create_default_path (void)
|
||||
return gsk_path_builder_free_to_path (builder);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GdkColorState *color_state;
|
||||
float values[4];
|
||||
} Color;
|
||||
|
||||
static gboolean
|
||||
parse_cicp_range (GtkCssParser *parser,
|
||||
Context *context,
|
||||
@ -1578,35 +1587,6 @@ parse_color_state (GtkCssParser *parser,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_parser_consume_number_or_percentage (GtkCssParser *parser,
|
||||
double min,
|
||||
double max,
|
||||
double *value)
|
||||
{
|
||||
if (gtk_css_parser_has_percentage (parser))
|
||||
{
|
||||
double number;
|
||||
|
||||
gtk_css_parser_consume_percentage (parser, &number);
|
||||
*value = min + (number / 100.0) * (max - min);
|
||||
return TRUE;
|
||||
}
|
||||
else if (gtk_css_parser_has_number (parser))
|
||||
{
|
||||
double number;
|
||||
|
||||
gtk_css_parser_consume_number (parser, &number);
|
||||
*value = number;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected a number or percentage");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
Context *context;
|
||||
GdkColor *color;
|
||||
@ -2935,10 +2915,10 @@ parse_shadow_node (GtkCssParser *parser,
|
||||
Context *context)
|
||||
{
|
||||
GskRenderNode *child = NULL;
|
||||
GArray *shadows = g_array_new (FALSE, TRUE, sizeof (GskShadow));
|
||||
GArray *shadows = g_array_new (FALSE, TRUE, sizeof (GskShadow2));
|
||||
const Declaration declarations[] = {
|
||||
{ "child", parse_node, clear_node, &child },
|
||||
{ "shadows", parse_shadows, clear_shadows, shadows }
|
||||
{ "shadows", parse_shadows, clear_shadows, shadows },
|
||||
};
|
||||
GskRenderNode *result;
|
||||
|
||||
@ -2948,12 +2928,13 @@ parse_shadow_node (GtkCssParser *parser,
|
||||
|
||||
if (shadows->len == 0)
|
||||
{
|
||||
GskShadow default_shadow = { GDK_RGBA("000000"), 1, 1, 0 };
|
||||
GskShadow2 default_shadow = { GDK_COLOR_SRGB (0, 0, 0, 1), GRAPHENE_POINT_INIT (1, 1), 0 };
|
||||
g_array_append_val (shadows, default_shadow);
|
||||
}
|
||||
|
||||
result = gsk_shadow_node_new (child, (GskShadow *)shadows->data, shadows->len);
|
||||
result = gsk_shadow_node_new2 (child, (GskShadow2 *)shadows->data, shadows->len);
|
||||
|
||||
clear_shadows (shadows);
|
||||
g_array_free (shadows, TRUE);
|
||||
gsk_render_node_unref (child);
|
||||
|
||||
@ -3389,6 +3370,11 @@ printer_init_duplicates_for_node (Printer *printer,
|
||||
|
||||
case GSK_SHADOW_NODE:
|
||||
printer_init_duplicates_for_node (printer, gsk_shadow_node_get_child (node));
|
||||
for (int i = 0; i < gsk_shadow_node_get_n_shadows (node); i++)
|
||||
{
|
||||
const GskShadow2 * shadow = gsk_shadow_node_get_shadow2 (node, i);
|
||||
printer_init_check_color_state (printer, shadow->color.color_state);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_DEBUG_NODE:
|
||||
@ -4522,25 +4508,21 @@ render_node_print (Printer *p,
|
||||
g_string_append (p->str, "shadows: ");
|
||||
for (i = 0; i < n_shadows; i ++)
|
||||
{
|
||||
const GskShadow *s = gsk_shadow_node_get_shadow (node, i);
|
||||
char *color;
|
||||
const GskShadow2 *s = gsk_shadow_node_get_shadow2 (node, i);
|
||||
|
||||
if (i > 0)
|
||||
g_string_append (p->str, ", ");
|
||||
|
||||
color = gdk_rgba_to_string (&s->color);
|
||||
g_string_append (p->str, color);
|
||||
print_color (p, &s->color);
|
||||
g_string_append_c (p->str, ' ');
|
||||
string_append_double (p->str, s->dx);
|
||||
string_append_double (p->str, s->offset.x);
|
||||
g_string_append_c (p->str, ' ');
|
||||
string_append_double (p->str, s->dy);
|
||||
string_append_double (p->str, s->offset.y);
|
||||
if (s->radius > 0)
|
||||
{
|
||||
g_string_append_c (p->str, ' ');
|
||||
string_append_double (p->str, s->radius);
|
||||
}
|
||||
|
||||
g_free (color);
|
||||
}
|
||||
|
||||
g_string_append_c (p->str, ';');
|
||||
|
@ -149,6 +149,20 @@ GskRenderNode * gsk_outset_shadow_node_new2 (const GskRoundedRect *o
|
||||
float blur_radius);
|
||||
const GdkColor *gsk_outset_shadow_node_get_color2 (const GskRenderNode *node);
|
||||
|
||||
typedef struct _GskShadow2 GskShadow2;
|
||||
struct _GskShadow2
|
||||
{
|
||||
GdkColor color;
|
||||
graphene_point_t offset;
|
||||
float radius;
|
||||
};
|
||||
|
||||
GskRenderNode * gsk_shadow_node_new2 (GskRenderNode *child,
|
||||
const GskShadow2 *shadows,
|
||||
gsize n_shadows);
|
||||
|
||||
const GskShadow2 *gsk_shadow_node_get_shadow2 (const GskRenderNode *node,
|
||||
gsize i);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -1290,6 +1290,35 @@ gtk_css_parser_consume_percentage (GtkCssParser *self,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_css_parser_consume_number_or_percentage (GtkCssParser *parser,
|
||||
double min,
|
||||
double max,
|
||||
double *value)
|
||||
{
|
||||
double number = 0;
|
||||
|
||||
if (gtk_css_parser_has_percentage (parser))
|
||||
{
|
||||
if (gtk_css_parser_consume_percentage (parser, &number))
|
||||
{
|
||||
*value = min + (number / 100.0) * (max - min);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else if (gtk_css_parser_has_number (parser))
|
||||
{
|
||||
if (gtk_css_parser_consume_number (parser, &number))
|
||||
{
|
||||
*value = number;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
gtk_css_parser_error_syntax (parser, "Expected a number or percentage");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gsize
|
||||
gtk_css_parser_consume_any (GtkCssParser *parser,
|
||||
const GtkCssParseOption *options,
|
||||
|
@ -154,6 +154,11 @@ gboolean gtk_css_parser_consume_integer (GtkCssParser
|
||||
int *number);
|
||||
gboolean gtk_css_parser_consume_percentage (GtkCssParser *self,
|
||||
double *number);
|
||||
gboolean gtk_css_parser_consume_number_or_percentage
|
||||
(GtkCssParser *parser,
|
||||
double min,
|
||||
double max,
|
||||
double *value);
|
||||
gboolean gtk_css_parser_consume_function (GtkCssParser *self,
|
||||
guint min_args,
|
||||
guint max_args,
|
||||
|
@ -755,28 +755,31 @@ gboolean
|
||||
gtk_css_shadow_value_push_snapshot (const GtkCssValue *value,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
GskShadow *shadows;
|
||||
GskShadow2 *shadows;
|
||||
guint i;
|
||||
|
||||
if (gtk_css_shadow_value_is_clear (value))
|
||||
return FALSE;
|
||||
|
||||
shadows = g_newa (GskShadow, value->n_shadows);
|
||||
shadows = g_newa (GskShadow2, value->n_shadows);
|
||||
|
||||
for (i = 0; i < value->n_shadows; i++)
|
||||
{
|
||||
const ShadowValue *shadow = &value->shadows[i];
|
||||
|
||||
shadows[i].color = *gtk_css_color_value_get_rgba (shadow->color);
|
||||
|
||||
shadows[i].dx = gtk_css_number_value_get (shadow->hoffset, 0);
|
||||
shadows[i].dy = gtk_css_number_value_get (shadow->voffset, 0);
|
||||
gtk_css_color_to_color (gtk_css_color_value_get_color (shadow->color), &shadows[i].color);
|
||||
graphene_point_init (&shadows[i].offset,
|
||||
gtk_css_number_value_get (shadow->hoffset, 0),
|
||||
gtk_css_number_value_get (shadow->voffset, 0));
|
||||
shadows[i].radius = gtk_css_number_value_get (shadow->radius, 0);
|
||||
if (value->is_filter)
|
||||
shadows[i].radius *= 2;
|
||||
}
|
||||
|
||||
gtk_snapshot_push_shadow (snapshot, shadows, value->n_shadows);
|
||||
gtk_snapshot_push_shadow2 (snapshot, shadows, value->n_shadows);
|
||||
|
||||
for (i = 0; i < value->n_shadows; i++)
|
||||
gdk_color_finish (&shadows[i].color);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -119,8 +119,8 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
} stroke;
|
||||
struct {
|
||||
gsize n_shadows;
|
||||
GskShadow *shadows;
|
||||
GskShadow a_shadow; /* Used if n_shadows == 1 */
|
||||
GskShadow2 *shadows;
|
||||
GskShadow2 a_shadow; /* Used if n_shadows == 1 */
|
||||
} shadow;
|
||||
struct {
|
||||
GskBlendMode blend_mode;
|
||||
@ -1348,11 +1348,11 @@ gtk_snapshot_collect_shadow (GtkSnapshot *snapshot,
|
||||
if (node == NULL)
|
||||
return NULL;
|
||||
|
||||
shadow_node = gsk_shadow_node_new (node,
|
||||
state->data.shadow.shadows != NULL ?
|
||||
state->data.shadow.shadows :
|
||||
&state->data.shadow.a_shadow,
|
||||
state->data.shadow.n_shadows);
|
||||
shadow_node = gsk_shadow_node_new2 (node,
|
||||
state->data.shadow.shadows != NULL
|
||||
? state->data.shadow.shadows
|
||||
: &state->data.shadow.a_shadow,
|
||||
state->data.shadow.n_shadows);
|
||||
|
||||
gsk_render_node_unref (node);
|
||||
|
||||
@ -1391,6 +1391,12 @@ gtk_snapshot_append_stroke (GtkSnapshot *snapshot,
|
||||
static void
|
||||
gtk_snapshot_clear_shadow (GtkSnapshotState *state)
|
||||
{
|
||||
if (state->data.shadow.shadows != 0)
|
||||
for (gsize i = 0; i < state->data.shadow.n_shadows; i++)
|
||||
gdk_color_finish (&state->data.shadow.shadows[i].color);
|
||||
else
|
||||
gdk_color_finish (&state->data.shadow.a_shadow.color);
|
||||
|
||||
g_free (state->data.shadow.shadows);
|
||||
}
|
||||
|
||||
@ -1408,6 +1414,41 @@ void
|
||||
gtk_snapshot_push_shadow (GtkSnapshot *snapshot,
|
||||
const GskShadow *shadow,
|
||||
gsize n_shadows)
|
||||
{
|
||||
GskShadow2 *shadow2;
|
||||
|
||||
g_return_if_fail (n_shadows > 0);
|
||||
|
||||
shadow2 = g_new (GskShadow2, n_shadows);
|
||||
for (gsize i = 0; i < n_shadows; i++)
|
||||
{
|
||||
gdk_color_init_from_rgba (&shadow2[i].color, &shadow[i].color);
|
||||
graphene_point_init (&shadow2[i].offset, shadow[i].dx,shadow[i].dy);
|
||||
shadow2[i].radius = shadow[i].radius;
|
||||
}
|
||||
|
||||
gtk_snapshot_push_shadow2 (snapshot, shadow2, n_shadows);
|
||||
|
||||
for (gsize i = 0; i < n_shadows; i++)
|
||||
gdk_color_finish (&shadow2[i].color);
|
||||
|
||||
g_free (shadow2);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gtk_snapshot_push_shadow2:
|
||||
* @snapshot: a `GtkSnapshot`
|
||||
* @shadow: (array length=n_shadows): the first shadow specification
|
||||
* @n_shadows: number of shadow specifications
|
||||
*
|
||||
* Applies a shadow to an image.
|
||||
*
|
||||
* The image is recorded until the next call to [method@Gtk.Snapshot.pop].
|
||||
*/
|
||||
void
|
||||
gtk_snapshot_push_shadow2 (GtkSnapshot *snapshot,
|
||||
const GskShadow2 *shadow,
|
||||
gsize n_shadows)
|
||||
{
|
||||
GtkSnapshotState *state;
|
||||
GskTransform *transform;
|
||||
@ -1429,20 +1470,23 @@ gtk_snapshot_push_shadow (GtkSnapshot *snapshot,
|
||||
if (n_shadows == 1)
|
||||
{
|
||||
state->data.shadow.shadows = NULL;
|
||||
memcpy (&state->data.shadow.a_shadow, shadow, sizeof (GskShadow));
|
||||
state->data.shadow.a_shadow.dx *= scale_x;
|
||||
state->data.shadow.a_shadow.dy *= scale_y;
|
||||
state->data.shadow.a_shadow.radius *= scale_x;
|
||||
gdk_color_init_copy (&state->data.shadow.a_shadow.color, &shadow->color);
|
||||
graphene_point_init (&state->data.shadow.a_shadow.offset,
|
||||
shadow->offset.x * scale_x,
|
||||
shadow->offset.y * scale_y);
|
||||
state->data.shadow.a_shadow.radius = shadow->radius * scale_x;
|
||||
}
|
||||
else
|
||||
{
|
||||
state->data.shadow.shadows = g_malloc (sizeof (GskShadow) * n_shadows);
|
||||
memcpy (state->data.shadow.shadows, shadow, sizeof (GskShadow) * n_shadows);
|
||||
state->data.shadow.shadows = g_malloc (sizeof (GskShadow2) * n_shadows);
|
||||
memcpy (state->data.shadow.shadows, shadow, sizeof (GskShadow2) * n_shadows);
|
||||
for (i = 0; i < n_shadows; i++)
|
||||
{
|
||||
state->data.shadow.shadows[i].dx *= scale_x;
|
||||
state->data.shadow.shadows[i].dy *= scale_y;
|
||||
state->data.shadow.shadows[i].radius *= scale_x;
|
||||
gdk_color_init_copy (&state->data.shadow.shadows[i].color, &shadow[i].color);
|
||||
graphene_point_init (&state->data.shadow.shadows[i].offset,
|
||||
shadow[i].offset.x * scale_x,
|
||||
shadow[i].offset.y * scale_y);
|
||||
state->data.shadow.shadows[i].radius = shadow[i].radius * scale_x;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,5 +61,9 @@ void gtk_snapshot_append_outset_shadow2 (GtkSnapshot
|
||||
float spread,
|
||||
float blur_radius);
|
||||
|
||||
void gtk_snapshot_push_shadow2 (GtkSnapshot *snapshot,
|
||||
const GskShadow2 *shadow,
|
||||
gsize n_shadows);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -1532,14 +1532,14 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
for (i = 0; i < gsk_shadow_node_get_n_shadows (node); i++)
|
||||
{
|
||||
char *label;
|
||||
const GskShadow *shadow = gsk_shadow_node_get_shadow (node, i);
|
||||
const GskShadow2 *shadow = gsk_shadow_node_get_shadow2 (node, i);
|
||||
|
||||
label = g_strdup_printf ("Color %d", i);
|
||||
add_color_row (store, label, &shadow->color);
|
||||
add_color2_row (store, label, &shadow->color);
|
||||
g_free (label);
|
||||
|
||||
label = g_strdup_printf ("Offset %d", i);
|
||||
add_text_row (store, label, "%.2f %.2f", shadow->dx, shadow->dy);
|
||||
add_text_row (store, label, "%.2f %.2f", shadow->offset.x, shadow->offset.y);
|
||||
g_free (label);
|
||||
|
||||
label = g_strdup_printf ("Radius %d", i);
|
||||
|
@ -3,5 +3,5 @@ shadow {
|
||||
bounds: 100 100 100 100;
|
||||
color: green;
|
||||
}
|
||||
shadows: red 10 10 4, blue -10 -10 8;
|
||||
shadows: red 10 10 4, blue -10 -10 8, color(srgb-linear 0.5 0.5 0.3) -5 5 8;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
shadow {
|
||||
shadows: rgb(255,0,0) 10 10 4, rgb(0,0,255) -10 -10 8;
|
||||
shadows: rgb(255,0,0) 10 10 4, rgb(0,0,255) -10 -10 8, color(srgb-linear 0.5 0.5 0.3) -5 5 8;
|
||||
child: color {
|
||||
bounds: 100 100 100 100;
|
||||
color: rgb(0,128,0);
|
||||
|
@ -219,10 +219,10 @@ replay_shadow_node (GskRenderNode *node, GtkSnapshot *snapshot)
|
||||
{
|
||||
gsize n_shadows = gsk_shadow_node_get_n_shadows (node);
|
||||
/* Hack: we know GskShadowNode stores shadows in a contiguous array. */
|
||||
const GskShadow *shadow = gsk_shadow_node_get_shadow (node, 0);
|
||||
const GskShadow2 *shadow = gsk_shadow_node_get_shadow2 (node, 0);
|
||||
GskRenderNode *child = gsk_shadow_node_get_child (node);
|
||||
|
||||
gtk_snapshot_push_shadow (snapshot, shadow, n_shadows);
|
||||
gtk_snapshot_push_shadow2 (snapshot, shadow, n_shadows);
|
||||
replay_node (child, snapshot);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user