mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-26 21:51:08 +00:00
cairo: Handle clipped blur content
This is the result of experimenting with corner cases when blurring. The result is a test that tests when the child of a blur node is clipped out but the blurred child is not, the blurred parts are still visible. This immediately broke the cairo renderer, so the fix is included.
This commit is contained in:
parent
8fd02f6fa2
commit
e3299e38df
@ -5901,35 +5901,42 @@ gsk_blur_node_draw (GskRenderNode *node,
|
||||
cairo_t *cr)
|
||||
{
|
||||
GskBlurNode *self = (GskBlurNode *) node;
|
||||
cairo_pattern_t *pattern;
|
||||
cairo_surface_t *surface;
|
||||
cairo_surface_t *image_surface;
|
||||
cairo_t *cr2;
|
||||
graphene_rect_t blur_bounds;
|
||||
double clip_radius;
|
||||
|
||||
cairo_save (cr);
|
||||
clip_radius = gsk_cairo_blur_compute_pixels (0.5 * self->radius);
|
||||
|
||||
/* clip so the push_group() creates a smaller surface */
|
||||
gsk_cairo_rectangle (cr, &node->bounds);
|
||||
cairo_clip (cr);
|
||||
/* We need to extend the clip by the blur radius
|
||||
* so we can blur pixels in that region */
|
||||
_graphene_rect_init_from_clip_extents (&blur_bounds, cr);
|
||||
graphene_rect_inset (&blur_bounds, - clip_radius, - clip_radius);
|
||||
if (!gsk_rect_intersection (&blur_bounds, &node->bounds, &blur_bounds))
|
||||
return;
|
||||
|
||||
cairo_push_group (cr);
|
||||
surface = cairo_surface_create_similar_image (cairo_get_target (cr),
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
ceil (blur_bounds.size.width),
|
||||
ceil (blur_bounds.size.height));
|
||||
cairo_surface_set_device_offset (surface,
|
||||
- blur_bounds.origin.x,
|
||||
- blur_bounds.origin.y);
|
||||
|
||||
gsk_render_node_draw (self->child, cr);
|
||||
cr2 = cairo_create (surface);
|
||||
gsk_render_node_draw (self->child, cr2);
|
||||
cairo_destroy (cr2);
|
||||
|
||||
pattern = cairo_pop_group (cr);
|
||||
cairo_pattern_get_surface (pattern, &surface);
|
||||
image_surface = cairo_surface_map_to_image (surface, NULL);
|
||||
blur_image_surface (image_surface, (int)self->radius, 3);
|
||||
blur_image_surface (surface, (int) ceil (0.5 * self->radius), 3);
|
||||
cairo_surface_mark_dirty (surface);
|
||||
cairo_surface_unmap_image (surface, image_surface);
|
||||
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_set_source_surface (cr, surface, 0, 0);
|
||||
cairo_rectangle (cr,
|
||||
node->bounds.origin.x, node->bounds.origin.y,
|
||||
node->bounds.size.width, node->bounds.size.height);
|
||||
cairo_fill (cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
cairo_pattern_destroy (pattern);
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
|
40
testsuite/gsk/compare/blur-contents-outside-of-clip.node
Normal file
40
testsuite/gsk/compare/blur-contents-outside-of-clip.node
Normal file
@ -0,0 +1,40 @@
|
||||
color-matrix {
|
||||
matrix: matrix3d(256, 0, 0, 0, 0, 256, 0, 0, 0, 0, 256, 0, 0, 0, 0, 256);
|
||||
child: clip {
|
||||
clip: -37 59 50 50;
|
||||
child: container {
|
||||
blur {
|
||||
blur: 17;
|
||||
child: color {
|
||||
bounds: -87 59 50 50;
|
||||
color: rgb(255,0,0);
|
||||
}
|
||||
}
|
||||
blur {
|
||||
blur: 17;
|
||||
child: color {
|
||||
bounds: 13 59 50 50;
|
||||
color: rgb(255,0,0);
|
||||
}
|
||||
}
|
||||
blur {
|
||||
blur: 17;
|
||||
child: color {
|
||||
bounds: -37 9 50 50;
|
||||
color: rgb(255,0,0);
|
||||
}
|
||||
}
|
||||
blur {
|
||||
blur: 17;
|
||||
child: color {
|
||||
bounds: -37 109 50 50;
|
||||
color: rgb(255,0,0);
|
||||
}
|
||||
}
|
||||
color {
|
||||
bounds: -22 74 20 20;
|
||||
color: rgb(0,0,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
BIN
testsuite/gsk/compare/blur-contents-outside-of-clip.png
Normal file
BIN
testsuite/gsk/compare/blur-contents-outside-of-clip.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 168 B |
@ -20,6 +20,7 @@ compare_render_tests = [
|
||||
'blend-in-rotate',
|
||||
'blend-normal',
|
||||
'blurred-lines',
|
||||
'blur-contents-outside-of-clip',
|
||||
'border-bottom-right',
|
||||
'border-one-rounded',
|
||||
'borders-rotated',
|
||||
|
Loading…
Reference in New Issue
Block a user