From e18c5534570ef6021501f39b293a864668301fec Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 29 Sep 2024 05:58:55 +0200 Subject: [PATCH] gpu: Consider scissor when intersecting with recangle The clip might be different from the scissor due to incompatible intersections. But the resulting intersection might be fully clipped, so we should consider it. Testsuite with longer explanation attached. Fixes #7044 --- gsk/gpu/gskgpunodeprocessor.c | 13 ++++++ .../compare/clip-all-clipped-issue-7044.node | 42 ++++++++++++++++++ .../compare/clip-all-clipped-issue-7044.png | Bin 0 -> 129 bytes testsuite/gsk/meson.build | 1 + 4 files changed, 56 insertions(+) create mode 100644 testsuite/gsk/compare/clip-all-clipped-issue-7044.node create mode 100644 testsuite/gsk/compare/clip-all-clipped-issue-7044.png diff --git a/gsk/gpu/gskgpunodeprocessor.c b/gsk/gpu/gskgpunodeprocessor.c index 316578aab0..c2c2f756a2 100644 --- a/gsk/gpu/gskgpunodeprocessor.c +++ b/gsk/gpu/gskgpunodeprocessor.c @@ -1039,6 +1039,19 @@ gsk_gpu_node_processor_add_node_clipped (GskGpuNodeProcessor *self, } else { + graphene_rect_t scissored_clip; + + if (gsk_gpu_node_processor_rect_device_to_clip (self, + &GSK_RECT_INIT_CAIRO (&self->scissor), + &scissored_clip)) + { + if (!gsk_rect_intersection (&scissored_clip, &clip, &clip)) + { + gsk_gpu_clip_init_copy (&self->clip, &old_clip); + return; + } + } + if (!gsk_gpu_clip_intersect_rect (&self->clip, &old_clip, &clip)) { GskGpuImage *image; diff --git a/testsuite/gsk/compare/clip-all-clipped-issue-7044.node b/testsuite/gsk/compare/clip-all-clipped-issue-7044.node new file mode 100644 index 0000000000..dcb2a62427 --- /dev/null +++ b/testsuite/gsk/compare/clip-all-clipped-issue-7044.node @@ -0,0 +1,42 @@ +/* establish proper bounds for the node */ +color { + bounds: 0 0 200 200; + color: black; +} + +/* ensure the scissor is set */ +clip { + clip: 0 0 100 100; + /* Create a cip that does not intersect the scissor + * and will be taken verbatim. + * We now have a scissor and a clip that overlap, + * but neither contains the other + */ + child: rounded-clip { + clip: 90.5 90.5 100 100 / 20; + child: container { + /* Guarantee the rounded-clip's bounds match + * its clip bounds. + */ + color { + bounds: 0 0 200 200; + color: black; + } + /* Clip by a region that has these characteristics: + * 1. It does not intersect with the scissor above + * 2. It is not pixel-aligned, so it can't be + * represented with a scissor. + * Code should properly detect (1). + */ + clip { + clip: 100 100 55.5 55.5; + /* Draw a child that triggers "Clipping is broken" */ + child: linear-gradient { + bounds: 0 0 200 200; + stops: 0 red, 0.1 green, 0.2 red, 0.3 blue, 0.4 yellow, + 0.5 blue, 0.6 white, 0.7 purple, 0.8 pink, 0.9 orange, 1.0 red; + } + } + } + } +} diff --git a/testsuite/gsk/compare/clip-all-clipped-issue-7044.png b/testsuite/gsk/compare/clip-all-clipped-issue-7044.png new file mode 100644 index 0000000000000000000000000000000000000000..6cd981aa2f32365d179396689a54975509034600 GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5y8Awi_W^)%vF%}28J29*~C-V}>VM+FM4q)VE zV4Ra_Z3N^q2l#}z0_o*dwzq(kjHioZh=keTm`Wi{1`<77#MHK Q31)zJp00i_>zopr04G=;CjbBd literal 0 HcmV?d00001 diff --git a/testsuite/gsk/meson.build b/testsuite/gsk/meson.build index 915117a425..d4896a0563 100644 --- a/testsuite/gsk/meson.build +++ b/testsuite/gsk/meson.build @@ -31,6 +31,7 @@ compare_render_tests = [ 'border-zero-width-color', 'borders-rotated', 'borders-scaled-nogl', + 'clip-all-clipped-issue-7044', 'clip-contained', 'clip-coordinates-2d', 'clip-coordinates-nocairo',