roundedrect: Fix an intersection cornercase

These 2 rectangles used to intersect fine:
  0 0 50 50 / 50 0
  0 0 50 50 / 0 50
But the computed result was:
  0 0 50 50 / 50
which is not a valid rectangle, because the corners overlap.

Make sure such rectangles return NOT_REPRESENTABLE.

The above rectangle has been added to the testsuite.
This commit is contained in:
Benjamin Otte
2023-12-28 03:59:46 +01:00
committed by Matthias Clasen
parent 58861ef18e
commit 2223abd432
2 changed files with 29 additions and 13 deletions

View File

@@ -46,22 +46,12 @@
#include <math.h>
static void
gsk_rounded_rect_normalize_in_place (GskRoundedRect *self)
static float
gsk_rounded_rect_get_corner_scale_factor (GskRoundedRect *self)
{
float factor = 1.0;
float corners;
guint i;
graphene_rect_normalize (&self->bounds);
for (i = 0; i < 4; i++)
{
self->corner[i].width = MAX (self->corner[i].width, 0);
self->corner[i].height = MAX (self->corner[i].height, 0);
}
/* clamp border radius, following CSS specs */
corners = self->corner[GSK_CORNER_TOP_LEFT].width + self->corner[GSK_CORNER_TOP_RIGHT].width;
if (corners > self->bounds.size.width)
factor = MIN (factor, self->bounds.size.width / corners);
@@ -78,6 +68,26 @@ gsk_rounded_rect_normalize_in_place (GskRoundedRect *self)
if (corners > self->bounds.size.height)
factor = MIN (factor, self->bounds.size.height / corners);
return factor;
}
static void
gsk_rounded_rect_normalize_in_place (GskRoundedRect *self)
{
float factor;
guint i;
graphene_rect_normalize (&self->bounds);
for (i = 0; i < 4; i++)
{
self->corner[i].width = MAX (self->corner[i].width, 0);
self->corner[i].height = MAX (self->corner[i].height, 0);
}
/* clamp border radius, following CSS specs */
factor = gsk_rounded_rect_get_corner_scale_factor (self);
for (i = 0; i < 4; i++)
graphene_size_scale (&self->corner[i], factor, &self->corner[i]);
}
@@ -812,7 +822,8 @@ gsk_rounded_rect_intersection (const GskRoundedRect *a,
check_corner (a, b,
GSK_CORNER_BOTTOM_RIGHT,
right, bottom,
result))
result) &&
gsk_rounded_rect_get_corner_scale_factor (result) >= 1.0)
return GSK_INTERSECTION_NONEMPTY;
return GSK_INTERSECTION_NOT_REPRESENTABLE;

View File

@@ -346,6 +346,11 @@ test_intersect (void)
ROUNDED_RECT_INIT_UNIFORM(0, 0, 21, 21, 21, 0, 0, 0),
GSK_INTERSECTION_NOT_REPRESENTABLE,
},
{
ROUNDED_RECT_INIT_UNIFORM(0, 0, 50, 50, 50, 0, 50, 0),
ROUNDED_RECT_INIT_UNIFORM(0, 0, 50, 50, 0, 50, 0, 50),
GSK_INTERSECTION_NOT_REPRESENTABLE,
},
};
gsize i;