Test special contours harder

Check that the start- and endpoint work
as expected and verify that their winding
numbers match the ones of the standard contour,
and are negated when the contour is reversed.
This commit is contained in:
Matthias Clasen 2023-08-27 10:10:26 -04:00
parent 8d1844135b
commit 78c5aff956
2 changed files with 164 additions and 16 deletions

View File

@ -21,12 +21,66 @@
#include "gsk/gskpathprivate.h"
#include "gsk/gskcontourprivate.h"
static void
test_roundtrip_circle (void)
static gboolean
add_segment (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer user_data)
{
GskPathBuilder *builder = user_data;
switch (op)
{
case GSK_PATH_MOVE:
gsk_path_builder_move_to (builder, pts[0].x, pts[0].y);
break;
case GSK_PATH_LINE:
gsk_path_builder_line_to (builder, pts[1].x, pts[1].y);
break;
case GSK_PATH_QUAD:
gsk_path_builder_quad_to (builder,
pts[1].x, pts[1].y,
pts[2].x, pts[2].y);
break;
case GSK_PATH_CUBIC:
gsk_path_builder_cubic_to (builder,
pts[1].x, pts[1].y,
pts[2].x, pts[2].y,
pts[3].x, pts[3].y);
break;
case GSK_PATH_CONIC:
gsk_path_builder_conic_to (builder,
pts[1].x, pts[1].y,
pts[2].x, pts[2].y,
weight);
break;
case GSK_PATH_CLOSE:
gsk_path_builder_close (builder);
break;
default:
g_assert_not_reached ();
}
return TRUE;
}
static GskPath *
convert_to_standard_contour (GskPath *path)
{
GskPathBuilder *builder;
GskPath *path, *path2;
const GskContour *contour;
builder = gsk_path_builder_new ();
gsk_path_foreach (path, -1, add_segment, builder);
return gsk_path_builder_free_to_path (builder);
}
static void
test_circle_roundtrip (void)
{
GskPathBuilder *builder;
GskPath *path, *path1;
const GskContour *contour, *contour1;
char *s;
builder = gsk_path_builder_new ();
@ -37,18 +91,51 @@ test_roundtrip_circle (void)
g_assert_cmpstr (gsk_contour_get_type_name (contour), ==, "GskCircleContour");
s = gsk_path_to_string (path);
path2 = gsk_path_parse (s);
contour = gsk_path_get_contour (path2, 0);
g_assert_cmpstr (gsk_contour_get_type_name (contour), ==, "GskCircleContour");
path1 = gsk_path_parse (s);
contour1 = gsk_path_get_contour (path1, 0);
g_free (s);
gsk_path_unref (path2);
g_assert_cmpstr (gsk_contour_get_type_name (contour1), ==, "GskCircleContour");
gsk_path_unref (path1);
gsk_path_unref (path);
}
static void
test_roundtrip_rounded_rect (void)
test_circle_winding (void)
{
GskPathBuilder *builder;
GskPath *path, *path1, *path2;
const GskContour *contour, *contour1, *contour2;
builder = gsk_path_builder_new ();
gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (100, 100), 33);
path = gsk_path_builder_free_to_path (builder);
contour = gsk_path_get_contour (path, 0);
path1 = convert_to_standard_contour (path);
contour1 = gsk_path_get_contour (path1, 0);
g_assert_true (gsk_contour_get_winding (contour, &GRAPHENE_POINT_INIT (100, 100))
==
gsk_contour_get_winding (contour1, &GRAPHENE_POINT_INIT (100, 100)));
builder = gsk_path_builder_new ();
gsk_path_builder_add_reverse_path (builder, path);
path2 = gsk_path_builder_free_to_path (builder);
contour2 = gsk_path_get_contour (path2, 0);
g_assert_true (gsk_contour_get_winding (contour, &GRAPHENE_POINT_INIT (100, 100))
==
- gsk_contour_get_winding (contour2, &GRAPHENE_POINT_INIT (100, 100)));
gsk_path_unref (path2);
gsk_path_unref (path1);
gsk_path_unref (path);
}
static void
test_rounded_rect_roundtrip (void)
{
GskRoundedRect rr;
GskPathBuilder *builder;
@ -80,13 +167,55 @@ test_roundtrip_rounded_rect (void)
gsk_path_unref (path);
}
static void
test_rounded_rect_winding (void)
{
GskRoundedRect rr;
GskPathBuilder *builder;
GskPath *path, *path1, *path2;
const GskContour *contour, *contour1, *contour2;
rr.bounds = GRAPHENE_RECT_INIT (100, 100, 200, 150);
rr.corner[GSK_CORNER_TOP_LEFT] = GRAPHENE_SIZE_INIT (10, 10);
rr.corner[GSK_CORNER_TOP_RIGHT] = GRAPHENE_SIZE_INIT (20, 10);
rr.corner[GSK_CORNER_BOTTOM_RIGHT] = GRAPHENE_SIZE_INIT (20, 0);
rr.corner[GSK_CORNER_BOTTOM_LEFT] = GRAPHENE_SIZE_INIT (0, 0);
builder = gsk_path_builder_new ();
gsk_path_builder_add_rounded_rect (builder, &rr);
path = gsk_path_builder_free_to_path (builder);
contour = gsk_path_get_contour (path, 0);
path1 = convert_to_standard_contour (path);
contour1 = gsk_path_get_contour (path1, 0);
g_assert_true (gsk_contour_get_winding (contour, &GRAPHENE_POINT_INIT (150, 150))
==
gsk_contour_get_winding (contour1, &GRAPHENE_POINT_INIT (150, 150)));
builder = gsk_path_builder_new ();
gsk_path_builder_add_reverse_path (builder, path);
path2 = gsk_path_builder_free_to_path (builder);
contour2 = gsk_path_get_contour (path2, 0);
g_assert_true (gsk_contour_get_winding (contour, &GRAPHENE_POINT_INIT (150, 150))
==
- gsk_contour_get_winding (contour2, &GRAPHENE_POINT_INIT (150, 150)));
gsk_path_unref (path2);
gsk_path_unref (path1);
gsk_path_unref (path);
}
int
main (int argc, char *argv[])
{
gtk_test_init (&argc, &argv, NULL);
g_test_add_func ("/path/roundtrip/circle", test_roundtrip_circle);
g_test_add_func ("/path/roundtrip/rounded-rect", test_roundtrip_rounded_rect);
g_test_add_func ("/path/circle/roundtrip", test_circle_roundtrip);
g_test_add_func ("/path/circle/winding", test_circle_winding);
g_test_add_func ("/path/rounded-rect/roundtrip", test_rounded_rect_roundtrip);
g_test_add_func ("/path/rounded-rect/winding", test_rounded_rect_winding);
return g_test_run ();
}

View File

@ -785,6 +785,8 @@ test_rounded_rect (void)
GskRoundedRect rect;
GskPathBuilder *builder;
GskPath *path;
GskPathPoint point;
graphene_point_t p;
gsk_rounded_rect_init (&rect, &GRAPHENE_RECT_INIT (10, 10, 100, 50),
&GRAPHENE_SIZE_INIT (0, 0),
@ -798,14 +800,22 @@ test_rounded_rect (void)
path = gsk_path_builder_free_to_path (builder);
for (int i = 0; i < 1000; i++)
for (int i = 0; i < 100; i++)
{
graphene_point_t p = GRAPHENE_POINT_INIT (g_test_rand_double_range (0, 200),
g_test_rand_double_range (0, 200));
p = GRAPHENE_POINT_INIT (g_test_rand_double_range (0, 200),
g_test_rand_double_range (0, 200));
g_assert_true (gsk_rounded_rect_contains_point (&rect, &p) == gsk_path_in_fill (path, &p, GSK_FILL_RULE_WINDING));
}
gsk_path_get_start_point (path, &point);
gsk_path_point_get_position (&point, path, &p);
g_assert_true (graphene_point_equal (&p, &GRAPHENE_POINT_INIT (10, 10)));
gsk_path_get_end_point (path, &point);
gsk_path_point_get_position (&point, path, &p);
g_assert_true (graphene_point_equal (&p, &GRAPHENE_POINT_INIT (10, 10)));
gsk_path_unref (path);
}
@ -817,6 +827,7 @@ test_circle (void)
GskPathMeasure *measure, *measure1, *measure2, *measure3;
float length, length1, length2, length3;
GskPathPoint point0, point1;
graphene_point_t p;
builder = gsk_path_builder_new ();
gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (0, 0), 1);
@ -827,6 +838,14 @@ test_circle (void)
g_assert_cmpfloat_with_epsilon (length, 2 * M_PI, 0.001);
gsk_path_get_start_point (path, &point0);
gsk_path_point_get_position (&point0, path, &p);
g_assert_true (graphene_point_equal (&p, &GRAPHENE_POINT_INIT (1, 0)));
gsk_path_get_end_point (path, &point0);
gsk_path_point_get_position (&point0, path, &p);
g_assert_true (graphene_point_equal (&p, &GRAPHENE_POINT_INIT (1, 0)));
gsk_path_get_closest_point (path, &GRAPHENE_POINT_INIT (1, 1), INFINITY, &point0);
gsk_path_get_closest_point (path, &GRAPHENE_POINT_INIT (-1, 1), INFINITY, &point1);