diff options
author | Matthias Clasen <mclasen@redhat.com> | 2020-11-26 02:02:55 -0500 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2020-11-26 14:28:11 -0500 |
commit | 0ede4fd2fb9360521882a1c4c313c164550659b5 (patch) | |
tree | 25f4c6c38ef64b6071dbd0cc904de19d52d5eb6d | |
parent | 03c863e369276a1a8f0bfea1ca7accea89f925e4 (diff) | |
download | gtk+-0ede4fd2fb9360521882a1c4c313c164550659b5.tar.gz |
Add a test for get_closest_point
Check that the returned offset actually matches the point
that is returned by gsk_path_measure_get_closest_point_full.
We do the extra work to detect when we end up with a point
that is straddling a contour boundary, and accept if get_point
returns a different point than get_closest_point in this case.
-rw-r--r-- | testsuite/gsk/path.c | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/testsuite/gsk/path.c b/testsuite/gsk/path.c index a5a7986660..c830583cf7 100644 --- a/testsuite/gsk/path.c +++ b/testsuite/gsk/path.c @@ -765,6 +765,8 @@ test_bounds (void) for (i = 0; i < 10; i++) { path = create_random_path (); + if (gsk_path_is_empty (path)) + continue; measure = gsk_path_measure_new (path); length = gsk_path_measure_get_length (measure); gsk_path_get_bounds (path, &bounds); @@ -782,6 +784,142 @@ test_bounds (void) } } +static gboolean +add_segment (GskPathOperation op, + const graphene_point_t *pts, + gsize n_pts, + gpointer user_data) +{ + GPtrArray *segments = user_data; + GskPathBuilder *builder; + GskPath *path; + + builder = gsk_path_builder_new (); + gsk_path_builder_move_to (builder, pts[0].x, pts[0].y); + + switch (op) + { + case GSK_PATH_MOVE: + break; + + case GSK_PATH_CLOSE: + case GSK_PATH_LINE: + gsk_path_builder_line_to (builder, pts[1].x, pts[1].y); + break; + + case GSK_PATH_CURVE: + gsk_path_builder_curve_to (builder, pts[1].x, pts[1].y, + pts[2].x, pts[2].y, + pts[3].x, pts[3].y); + break; + + default: + g_assert_not_reached (); + } + + path = gsk_path_builder_free_to_path (builder); + g_ptr_array_add (segments, gsk_path_measure_new (path)); + gsk_path_unref (path); + + return TRUE; +} + +static GPtrArray * +get_segments (GskPath *path) +{ + GPtrArray *segments; + + segments = g_ptr_array_new_with_free_func ((GDestroyNotify)gsk_path_measure_unref); + + gsk_path_foreach (path, add_segment, segments); + + return segments; +} + +static void +test_closest_point_offset (void) +{ + guint i; + + for (i = 0; i < 10; i++) + { + GskPath *path; + GskPathMeasure *measure; + int j; + GPtrArray *segments; + + path = create_random_path (); + measure = gsk_path_measure_new (path); + + segments = get_segments (path); + + for (j = 0; j < 100; j++) + { + graphene_point_t test = GRAPHENE_POINT_INIT (g_test_rand_double_range (-1000, 1000), + g_test_rand_double_range (-1000, 1000)); + graphene_point_t p; + graphene_vec2_t t; + float offset; + float distance; + gboolean found; + + found = gsk_path_measure_get_closest_point_full (measure, + &test, + INFINITY, + &distance, + &p, + &offset, + &t); + + if (found) + { + graphene_point_t p2; + gboolean at_segment_start = FALSE; + gboolean at_segment_end = FALSE; + int k; + + for (k = 0; k < segments->len; k++) + { + GskPathMeasure *m = g_ptr_array_index (segments, k); + graphene_vec2_t t2; + float offset2; + float distance2; + gboolean found2; + + found2 = gsk_path_measure_get_closest_point_full (m, + &test, + INFINITY, + &distance2, + &p2, + &offset2, + &t2); + + g_assert_true (found2); + + if (offset2 == 0) + { + at_segment_start = TRUE; + } + if (offset2 == gsk_path_measure_get_length (m)) + { + at_segment_end = TRUE; + } + } + + gsk_path_measure_get_point (measure, offset, &p2, NULL); + if (!graphene_point_near (&p, &p2, 0.0001)) + { + g_assert_true (at_segment_start || at_segment_end); + } + } + } + + g_ptr_array_unref (segments); + gsk_path_measure_unref (measure); + gsk_path_unref (path); + } +} + int main (int argc, char *argv[]) @@ -798,6 +936,7 @@ main (int argc, g_test_add_func ("/path/from-random-string", test_from_random_string); g_test_add_func ("/path/serialize", test_serialize); g_test_add_func ("/path/bounds", test_bounds); + g_test_add_func ("/path/closest_point_offset", test_closest_point_offset); return g_test_run (); } |