gsk: Fix clipping error when drawing shadows
When shadows were offset - in particular when offset so the original source was out of bounds of the result - the drawing code would create a pattern for it that didn't include enough of it to compose a shadow. Fix that by not creating those patterns anymore, but instead drawing the source (potentially multiple times) at the required offsets. While that does more drawing, it simplifies the shadow node draw code, and that's the primary goal of the Cairo rendering. Test included.
This commit is contained in:
@@ -4852,18 +4852,8 @@ gsk_shadow_node_draw (GskRenderNode *node,
|
||||
cairo_t *cr)
|
||||
{
|
||||
GskShadowNode *self = (GskShadowNode *) node;
|
||||
cairo_pattern_t *pattern;
|
||||
gsize i;
|
||||
|
||||
cairo_save (cr);
|
||||
/* clip so the push_group() creates a small surface */
|
||||
gsk_cairo_rectangle (cr, &self->child->bounds);
|
||||
cairo_clip (cr);
|
||||
cairo_push_group (cr);
|
||||
gsk_render_node_draw (self->child, cr);
|
||||
pattern = cairo_pop_group (cr);
|
||||
cairo_restore (cr);
|
||||
|
||||
cairo_save (cr);
|
||||
/* clip so the blur area stays small */
|
||||
gsk_cairo_rectangle (cr, &node->bounds);
|
||||
@@ -4872,27 +4862,31 @@ gsk_shadow_node_draw (GskRenderNode *node,
|
||||
for (i = 0; i < self->n_shadows; i++)
|
||||
{
|
||||
GskShadow *shadow = &self->shadows[i];
|
||||
cairo_pattern_t *pattern;
|
||||
|
||||
/* We don't need to draw invisible shadows */
|
||||
if (gdk_rgba_is_clear (&shadow->color))
|
||||
continue;
|
||||
|
||||
cairo_save (cr);
|
||||
gdk_cairo_set_source_rgba (cr, &shadow->color);
|
||||
cr = gsk_cairo_blur_start_drawing (cr, shadow->radius, GSK_BLUR_X | GSK_BLUR_Y);
|
||||
|
||||
cairo_save (cr);
|
||||
cairo_translate (cr, shadow->dx, shadow->dy);
|
||||
cairo_push_group (cr);
|
||||
gsk_render_node_draw (self->child, cr);
|
||||
pattern = cairo_pop_group (cr);
|
||||
gdk_cairo_set_source_rgba (cr, &shadow->color);
|
||||
cairo_mask (cr, pattern);
|
||||
cairo_restore (cr);
|
||||
|
||||
cr = gsk_cairo_blur_finish_drawing (cr, shadow->radius, &shadow->color, GSK_BLUR_X | GSK_BLUR_Y);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_paint (cr);
|
||||
cairo_restore (cr);
|
||||
gsk_render_node_draw (self->child, cr);
|
||||
|
||||
cairo_pattern_destroy (pattern);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
10
testsuite/gsk/compare/shadow-clip-contents.node
Normal file
10
testsuite/gsk/compare/shadow-clip-contents.node
Normal file
@@ -0,0 +1,10 @@
|
||||
clip {
|
||||
clip: 0 0 50 50;
|
||||
child: shadow {
|
||||
shadows: rgb(0,0,0) -20 -20;
|
||||
child: color {
|
||||
bounds: 40 40 50 50;
|
||||
color: rgb(255,0,204);
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
testsuite/gsk/compare/shadow-clip-contents.png
Normal file
BIN
testsuite/gsk/compare/shadow-clip-contents.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 116 B |
@@ -92,6 +92,7 @@ compare_render_tests = [
|
||||
'scaled-cairo',
|
||||
'scaled-texture',
|
||||
'shadow-behind',
|
||||
'shadow-clip-contents',
|
||||
'shadow-in-opacity',
|
||||
'shadow-opacity',
|
||||
'shrink-rounded-border',
|
||||
|
||||
Reference in New Issue
Block a user