[gtk/matthiasc/lottie2] Add a test for get_closest_point



commit 0ede4fd2fb9360521882a1c4c313c164550659b5
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Nov 26 02:02:55 2020 -0500

    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.

 testsuite/gsk/path.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 139 insertions(+)
---
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 ();
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]