[gtk/wip/matthiasc/lottie-stroke: 57/58] Add another stroker test




commit 54e088aed19811f2c1fffa6fc79e23fecb817c0d
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Dec 6 17:16:42 2020 -0500

    Add another stroker test
    
    Check that the outlines of random paths look as
    expected. We currently have to exclude paths where
    points get too close to each other.

 testsuite/gsk/path.c | 237 ++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 177 insertions(+), 60 deletions(-)
---
diff --git a/testsuite/gsk/path.c b/testsuite/gsk/path.c
index 6b49b862c0..f04cd84d7c 100644
--- a/testsuite/gsk/path.c
+++ b/testsuite/gsk/path.c
@@ -37,8 +37,8 @@ create_random_degenerate_path (guint max_contours)
     case 1:
       /* a single point */
       gsk_path_builder_move_to (builder, 
-                                g_test_rand_double_range (-1000, 1000),
-                                g_test_rand_double_range (-1000, 1000));
+                                g_test_rand_double_range (0, 100),
+                                g_test_rand_double_range (0, 100));
       break;
 
     case 2:
@@ -46,24 +46,24 @@ create_random_degenerate_path (guint max_contours)
       for (i = 0; i < MIN (10, max_contours); i++)
         {
           gsk_path_builder_move_to (builder, 
-                                    g_test_rand_double_range (-1000, 1000),
-                                    g_test_rand_double_range (-1000, 1000));
+                                    g_test_rand_double_range (0, 100),
+                                    g_test_rand_double_range (0, 100));
         }
       break;
 
     case 3:
       /* 1 closed point */
       gsk_path_builder_move_to (builder, 
-                                g_test_rand_double_range (-1000, 1000),
-                                g_test_rand_double_range (-1000, 1000));
+                                g_test_rand_double_range (0, 100),
+                                g_test_rand_double_range (0, 100));
       gsk_path_builder_close (builder);
       break;
 
     case 4:
       /* the same point closed N times */
       gsk_path_builder_move_to (builder, 
-                                g_test_rand_double_range (-1000, 1000),
-                                g_test_rand_double_range (-1000, 1000));
+                                g_test_rand_double_range (0, 100),
+                                g_test_rand_double_range (0, 100));
       for (i = 0; i < MIN (10, max_contours); i++)
         {
           gsk_path_builder_close (builder);
@@ -73,62 +73,62 @@ create_random_degenerate_path (guint max_contours)
     case 5:
       /* a zero-width and zero-height rect */
       gsk_path_builder_add_rect (builder,
-                                 &GRAPHENE_RECT_INIT (g_test_rand_double_range (-1000, 1000),
-                                                      g_test_rand_double_range (-1000, 1000),
+                                 &GRAPHENE_RECT_INIT (g_test_rand_double_range (0, 100),
+                                                      g_test_rand_double_range (0, 100),
                                                       0, 0));
       break;
 
     case 6:
       /* a zero-width rect */
       gsk_path_builder_add_rect (builder,
-                                 &GRAPHENE_RECT_INIT (g_test_rand_double_range (-1000, 1000),
-                                                      g_test_rand_double_range (-1000, 1000),
+                                 &GRAPHENE_RECT_INIT (g_test_rand_double_range (0, 100),
+                                                      g_test_rand_double_range (0, 100),
                                                       0,
-                                                      g_test_rand_double_range (-1000, 1000)));
+                                                      g_test_rand_double_range (0, 100)));
       break;
 
     case 7:
       /* a zero-height rect */
       gsk_path_builder_add_rect (builder,
-                                 &GRAPHENE_RECT_INIT (g_test_rand_double_range (-1000, 1000),
-                                                      g_test_rand_double_range (-1000, 1000),
-                                                      g_test_rand_double_range (-1000, 1000),
+                                 &GRAPHENE_RECT_INIT (g_test_rand_double_range (0, 100),
+                                                      g_test_rand_double_range (0, 100),
+                                                      g_test_rand_double_range (0, 100),
                                                       0));
       break;
 
     case 8:
       /* a negative-size rect */
       gsk_path_builder_add_rect (builder,
-                                 &GRAPHENE_RECT_INIT (g_test_rand_double_range (-1000, 1000),
-                                                      g_test_rand_double_range (-1000, 1000),
-                                                      g_test_rand_double_range (-1000, 0),
-                                                      g_test_rand_double_range (-1000, 0)));
+                                 &GRAPHENE_RECT_INIT (g_test_rand_double_range (0, 100),
+                                                      g_test_rand_double_range (0, 100),
+                                                      g_test_rand_double_range (0, 0),
+                                                      g_test_rand_double_range (0, 0)));
       break;
 
     case 9:
       /* an absolutely random rect */
       gsk_path_builder_add_rect (builder,
-                                 &GRAPHENE_RECT_INIT (g_test_rand_double_range (-1000, 1000),
-                                                      g_test_rand_double_range (-1000, 1000),
-                                                      g_test_rand_double_range (-1000, 1000),
-                                                      g_test_rand_double_range (-1000, 1000)));
+                                 &GRAPHENE_RECT_INIT (g_test_rand_double_range (0, 100),
+                                                      g_test_rand_double_range (0, 100),
+                                                      g_test_rand_double_range (0, 100),
+                                                      g_test_rand_double_range (0, 100)));
       break;
 
     case 10:
       /* an absolutely random rect */
       gsk_path_builder_add_rect (builder,
-                                 &GRAPHENE_RECT_INIT (g_test_rand_double_range (-1000, 1000),
-                                                      g_test_rand_double_range (-1000, 1000),
-                                                      g_test_rand_double_range (-1000, 1000),
-                                                      g_test_rand_double_range (-1000, 1000)));
+                                 &GRAPHENE_RECT_INIT (g_test_rand_double_range (0, 100),
+                                                      g_test_rand_double_range (0, 100),
+                                                      g_test_rand_double_range (0, 100),
+                                                      g_test_rand_double_range (0, 100)));
       break;
 
     case 11:
       /* an absolutely random circle */
       gsk_path_builder_add_circle (builder,
-                                   &GRAPHENE_POINT_INIT (g_test_rand_double_range (-1000, 1000),
-                                                         g_test_rand_double_range (-1000, 1000)),
-                                   g_test_rand_double_range (1, 1000));
+                                   &GRAPHENE_POINT_INIT (g_test_rand_double_range (0, 100),
+                                                         g_test_rand_double_range (0, 100)),
+                                   g_test_rand_double_range (1, 100));
       break;
 
     case N_DEGENERATE_PATHS:
@@ -150,17 +150,17 @@ add_shape_contour (GskPathBuilder *builder)
   {
     case 0:
       gsk_path_builder_add_rect (builder,
-                                 &GRAPHENE_RECT_INIT (g_test_rand_double_range (-1000, 1000),
-                                                      g_test_rand_double_range (-1000, 1000),
-                                                      g_test_rand_double_range (1, 1000),
-                                                      g_test_rand_double_range (1, 1000)));
+                                 &GRAPHENE_RECT_INIT (g_test_rand_double_range (0, 100),
+                                                      g_test_rand_double_range (0, 100),
+                                                      g_test_rand_double_range (1, 100),
+                                                      g_test_rand_double_range (1, 100)));
       break;
 
     case 1:
       gsk_path_builder_add_circle (builder,
-                                   &GRAPHENE_POINT_INIT (g_test_rand_double_range (-1000, 1000),
-                                                         g_test_rand_double_range (-1000, 1000)),
-                                   g_test_rand_double_range (1, 1000));
+                                   &GRAPHENE_POINT_INIT (g_test_rand_double_range (0, 100),
+                                                         g_test_rand_double_range (0, 100)),
+                                   g_test_rand_double_range (1, 100));
       break;
 
     case 2:
@@ -187,12 +187,12 @@ add_standard_contour (GskPathBuilder *builder)
     {
       if (g_test_rand_bit ())
         gsk_path_builder_move_to (builder,
-                                  g_test_rand_double_range (-1000, 1000),
-                                  g_test_rand_double_range (-1000, 1000));
+                                  g_test_rand_double_range (0, 100),
+                                  g_test_rand_double_range (0, 100));
       else
         gsk_path_builder_rel_move_to (builder,
-                                      g_test_rand_double_range (-1000, 1000),
-                                      g_test_rand_double_range (-1000, 1000));
+                                      g_test_rand_double_range (0, 100),
+                                      g_test_rand_double_range (0, 100));
     }
 
   /* that 20 is random, but should be enough to get some
@@ -204,34 +204,34 @@ add_standard_contour (GskPathBuilder *builder)
       {
         case 0:
           gsk_path_builder_line_to (builder,
-                                    g_test_rand_double_range (-1000, 1000),
-                                    g_test_rand_double_range (-1000, 1000));
+                                    g_test_rand_double_range (0, 100),
+                                    g_test_rand_double_range (0, 100));
           break;
 
         case 1:
           gsk_path_builder_rel_line_to (builder,
-                                        g_test_rand_double_range (-1000, 1000),
-                                        g_test_rand_double_range (-1000, 1000));
+                                        g_test_rand_double_range (0, 100),
+                                        g_test_rand_double_range (0, 100));
           break;
 
         case 2:
           gsk_path_builder_curve_to (builder,
-                                     g_test_rand_double_range (-1000, 1000),
-                                     g_test_rand_double_range (-1000, 1000),
-                                     g_test_rand_double_range (-1000, 1000),
-                                     g_test_rand_double_range (-1000, 1000),
-                                     g_test_rand_double_range (-1000, 1000),
-                                     g_test_rand_double_range (-1000, 1000));
+                                     g_test_rand_double_range (0, 100),
+                                     g_test_rand_double_range (0, 100),
+                                     g_test_rand_double_range (0, 100),
+                                     g_test_rand_double_range (0, 100),
+                                     g_test_rand_double_range (0, 100),
+                                     g_test_rand_double_range (0, 100));
           break;
 
         case 3:
           gsk_path_builder_rel_curve_to (builder,
-                                         g_test_rand_double_range (-1000, 1000),
-                                         g_test_rand_double_range (-1000, 1000),
-                                         g_test_rand_double_range (-1000, 1000),
-                                         g_test_rand_double_range (-1000, 1000),
-                                         g_test_rand_double_range (-1000, 1000),
-                                         g_test_rand_double_range (-1000, 1000));
+                                         g_test_rand_double_range (0, 100),
+                                         g_test_rand_double_range (0, 100),
+                                         g_test_rand_double_range (0, 100),
+                                         g_test_rand_double_range (0, 100),
+                                         g_test_rand_double_range (0, 100),
+                                         g_test_rand_double_range (0, 100));
           break;
 
         default:
@@ -740,8 +740,8 @@ test_closest_point (void)
 
       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 test = GRAPHENE_POINT_INIT (g_test_rand_double_range (00, 1000),
+                                                       g_test_rand_double_range (00, 1000));
           graphene_point_t p1, p2, p;
           graphene_vec2_t t1, t2, t;
           float offset1, offset2, offset;
@@ -1049,6 +1049,122 @@ test_in_fill_rotated (void)
 #undef N_FILL_RULES
 }
 
+static void
+check_stroke_at_position (GskPathMeasure *measure,
+                          GskStroke      *stroke,
+                          GskPathMeasure *stroke_measure,
+                          float           position)
+{
+  graphene_point_t p;
+  graphene_point_t s;
+  float w;
+  float d;
+
+  w = gsk_stroke_get_line_width (stroke);
+
+  gsk_path_measure_get_point (measure, position, &p, NULL);
+  gsk_path_measure_get_closest_point (stroke_measure, &p, &s);
+
+  d = graphene_point_distance (&p, &s, NULL, NULL);
+  if (d > w/2 + gsk_path_measure_get_tolerance (stroke_measure))
+    {
+      char *str = gsk_path_to_string (gsk_path_measure_get_path (measure));
+      char *str2 = gsk_path_to_string (gsk_path_measure_get_path (stroke_measure));
+      g_print ("BAD!\n"
+               "path: %s\n"
+               "stroke path: %s\n"
+               "line width: %f\n"
+               "position: %f\n"
+               "distance: %f\n"
+               "curve point: %f %f\n"
+               "offset point: %f %f\n",
+                   str, str2, w, position, d,
+                   p.x, p.y, s.x, s.y);
+      g_free (str);
+      g_free (str2);
+      g_assert_not_reached ();
+    }
+}
+
+static void
+check_stroke_distance (GskPath        *path,
+                       GskPathMeasure *measure,
+                       GskStroke      *stroke,
+                       GskPath        *stroke_path)
+{
+  GskPathMeasure *stroke_measure;
+  float length;
+  float t;
+  int i;
+
+  stroke_measure = gsk_path_measure_new_with_tolerance (stroke_path, 0.1);
+  length = gsk_path_measure_get_length (measure);
+
+  for (i = 0; i < 1000; i++)
+    {
+      t = g_test_rand_double_range (0, length);
+      check_stroke_at_position (measure, stroke, stroke_measure, t);
+    }
+
+  gsk_path_measure_unref (stroke_measure);
+}
+
+static gboolean
+check_spaced_out (GskPathOperation        op,
+                  const graphene_point_t *pts,
+                  gsize                   n_pts,
+                  float                   weight,
+                  gpointer                user_data)
+{
+  float *distance = user_data;
+  return graphene_point_distance (&pts[0], &pts[n_pts - 1], NULL, NULL) >= *distance;
+}
+
+static gboolean
+path_is_spaced_out (GskPath *path,
+                    float    distance)
+{
+  return gsk_path_foreach (path, GSK_PATH_FOREACH_ALLOW_CURVE | GSK_PATH_FOREACH_ALLOW_CONIC, 
check_spaced_out, &distance);
+}
+
+static void
+test_path_stroke_distance (void)
+{
+  GskPath *path;
+  GskPathMeasure *measure;
+  GskPath *stroke_path;
+  GskStroke *stroke;
+  int i;
+  float width = 10;
+
+  stroke = gsk_stroke_new (width);
+  gsk_stroke_set_line_cap (stroke, GSK_LINE_CAP_ROUND);
+
+  i = 0;
+  while (i < 1000)
+    {
+      path = create_random_path (1);
+      /* We know the stroker can't robustly handle paths with
+       * too close neighbouring points
+       */
+      if (!path_is_spaced_out (path, width / 2))
+        continue;
+
+      measure = gsk_path_measure_new (path);
+      stroke_path = gsk_path_measure_stroke (measure, stroke);
+
+      check_stroke_distance (path, measure, stroke, stroke_path);
+
+      gsk_path_unref (stroke_path);
+      gsk_path_measure_unref (measure);
+      gsk_path_unref (path);
+
+      i++;
+    }
+
+  gsk_stroke_free (stroke);
+}
+
 int
 main (int   argc,
       char *argv[])
@@ -1066,6 +1182,7 @@ main (int   argc,
   g_test_add_func ("/path/parse", test_parse);
   g_test_add_func ("/path/in-fill-union", test_in_fill_union);
   g_test_add_func ("/path/in-fill-rotated", test_in_fill_rotated);
+  g_test_add_func ("/path/stroke/distance", test_path_stroke_distance);
 
   return g_test_run ();
 }


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