diff --git a/gsk/gskcontour.c b/gsk/gskcontour.c index db67ed6b6d..32f38c562c 100644 --- a/gsk/gskcontour.c +++ b/gsk/gskcontour.c @@ -914,6 +914,7 @@ gsk_standard_contour_get_point (const GskContour *contour, { result->idx = curve_measure->idx; result->t = p->t; + g_assert (0 <= result->t && result->t <= 1); return; } } @@ -941,9 +942,9 @@ gsk_standard_contour_get_point (const GskContour *contour, result->idx = curve_measure->idx; fraction = (distance - p0->length) / (p1->length - p0->length); - g_assert (fraction >= 0.f && fraction <= 1.f); + g_assert (fraction >= 0 && fraction <= 1); result->t = p0->t * (1 - fraction) + p1->t * fraction; - g_assert (result->t >= 0.f && result->t <= 1.f); + g_assert (result->t >= 0 && result->t <= 1); } } @@ -986,7 +987,7 @@ gsk_standard_contour_get_distance (const GskContour *contour, g_assert (p0->t <= point->t && point->t <= p1->t); fraction = (point->t - p0->t) / (p1->t - p0->t); - g_assert (fraction >= 0.f && fraction <= 1.f); + g_assert (fraction >= 0 && fraction <= 1); return p0->length * (1 - fraction) + p1->length * fraction; } @@ -1295,7 +1296,10 @@ gsk_circle_contour_get_curvature (const GskContour *contour, if (center) *center = self->center; - return 1 / self->radius; + if (self->radius == 0) + return INFINITY; + + return 1.f / self->radius; } static void @@ -1377,13 +1381,17 @@ gsk_circle_contour_get_point (const GskContour *contour, const GskCircleContour *self = (const GskCircleContour *) contour; float t; - t = distance / (2 * M_PI * self->radius); + if (self->radius == 0) + t = 0; + else + t = distance / (2 * M_PI * self->radius); if (self->ccw) t = 1 - t; result->idx = 1; result->t = t; + g_assert (result->t >= 0 && result->t <= 1); } static float @@ -1433,7 +1441,7 @@ gsk_circle_contour_new (const graphene_point_t *center, { GskCircleContour *self; - g_assert (radius > 0); + g_assert (radius >= 0); self = g_new0 (GskCircleContour, 1); @@ -1936,6 +1944,7 @@ gsk_rect_contour_get_point (const GskContour *contour, result->t = 0; else result->t = CLAMP (distance / self->length, 0, 1); + g_assert (0 <= result->t && result->t <= 1); } static float diff --git a/gsk/gskpathbuilder.c b/gsk/gskpathbuilder.c index b612d4ebf8..d31699c52a 100644 --- a/gsk/gskpathbuilder.c +++ b/gsk/gskpathbuilder.c @@ -497,6 +497,8 @@ gsk_path_builder_add_rounded_rect (GskPathBuilder *self, * * The path is going around the circle in clockwise direction. * + * If @radius is zero, the contour will be a closed point. + * * Since: 4.14 */ void @@ -506,7 +508,7 @@ gsk_path_builder_add_circle (GskPathBuilder *self, { g_return_if_fail (self != NULL); g_return_if_fail (center != NULL); - g_return_if_fail (radius > 0); + g_return_if_fail (radius >= 0); gsk_path_builder_add_contour (self, gsk_circle_contour_new (center, radius)); } diff --git a/gsk/gskpathpoint.c b/gsk/gskpathpoint.c index 0e550d69f2..1b515ea947 100644 --- a/gsk/gskpathpoint.c +++ b/gsk/gskpathpoint.c @@ -285,6 +285,8 @@ gsk_path_point_get_rotation (const GskPathPoint *point, * Lines have a curvature of zero (indicating an osculating circle of * infinite radius. In this case, the @center is not modified. * + * Circles with a radius of zero have `INFINITY` as curvature + * * Note that certain points on a path may not have a single curvature, * such as sharp turns. At such points, there are two curvatures -- * the (limit of) the curvature of the path going into the point, diff --git a/testsuite/gsk/path-special-cases.c b/testsuite/gsk/path-special-cases.c index 17a242de39..538e310cf2 100644 --- a/testsuite/gsk/path-special-cases.c +++ b/testsuite/gsk/path-special-cases.c @@ -938,7 +938,6 @@ test_circle (void) g_assert_true (gsk_path_in_fill (path6, &GRAPHENE_POINT_INIT (0, 0), GSK_FILL_RULE_WINDING)); g_assert_false (gsk_path_in_fill (path6, &GRAPHENE_POINT_INIT (0, 0), GSK_FILL_RULE_EVEN_ODD)); - gsk_path_measure_unref (measure); gsk_path_measure_unref (measure1); gsk_path_measure_unref (measure2); @@ -1035,6 +1034,28 @@ test_rect_segment (void) gsk_path_measure_unref (measure2); } +static void +test_circle_point (void) +{ + GskPathBuilder *builder; + GskPath *path; + GskPathPoint point; + graphene_point_t center; + float k; + + builder = gsk_path_builder_new (); + gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (1, 2), 0); + path = gsk_path_builder_free_to_path (builder); + + gsk_path_get_start_point (path, &point); + k = gsk_path_point_get_curvature (&point, path, GSK_PATH_TO_END, ¢er); + + g_assert_true (k == INFINITY); + g_assert_true (graphene_point_equal (¢er, &GRAPHENE_POINT_INIT (1, 2))); + + gsk_path_unref (path); +} + int main (int argc, char *argv[]) { @@ -1055,6 +1076,7 @@ main (int argc, char *argv[]) g_test_add_func ("/path/circle", test_circle); g_test_add_func ("/path/length", test_length); g_test_add_func ("/path/rect/segment", test_rect_segment); + g_test_add_func ("/path/circle-point", test_circle_point); return g_test_run (); } diff --git a/testsuite/gsk/path.c b/testsuite/gsk/path.c index 1c25d6e3a2..a0fb6613c3 100644 --- a/testsuite/gsk/path.c +++ b/testsuite/gsk/path.c @@ -22,7 +22,7 @@ static GskPath * create_random_degenerate_path (guint max_contours) { -#define N_DEGENERATE_PATHS 14 +#define N_DEGENERATE_PATHS 15 GskPathBuilder *builder; guint i; @@ -132,6 +132,14 @@ create_random_degenerate_path (guint max_contours) break; case 12: + /* circle with radius 0 */ + gsk_path_builder_add_circle (builder, + &GRAPHENE_POINT_INIT (g_test_rand_double_range (-1000, 1000), + g_test_rand_double_range (-1000, 1000)), + 0); + break; + + case 13: /* a zero-length line */ { graphene_point_t point = GRAPHENE_POINT_INIT (g_test_rand_double_range (-1000, 1000), @@ -141,7 +149,7 @@ create_random_degenerate_path (guint max_contours) } break; - case 13: + case 14: /* a cubic with start == end */ { graphene_point_t point = GRAPHENE_POINT_INIT (g_test_rand_double_range (-1000, 1000),