[gtk/matthiasc/lottie] path: Fix up handling of z



commit bbf832cb8f4006418d6092536a4b7d2bc3a3d0a6
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Nov 24 14:24:23 2020 -0500

    path: Fix up handling of z
    
    Fix up our handling of z: draw a line from the
    current position to the initial point of the contour.
    
    Also fix up handling of initial subpath positions to
    follow what the SVG spec says: An M after a Z sets the
    initial point of the next contour. For every other
    command after Z, the new contour starts at the current
    point.

 gsk/gskpath.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 67 insertions(+), 2 deletions(-)
---
diff --git a/gsk/gskpath.c b/gsk/gskpath.c
index 7447035790..affa15c919 100644
--- a/gsk/gskpath.c
+++ b/gsk/gskpath.c
@@ -2218,6 +2218,7 @@ gsk_path_from_string (const char *s)
   GskPathBuilder *builder;
   double x, y;
   double prev_x1, prev_y1;
+  double path_x, path_y;
   const char *p;
   char cmd;
   char prev_cmd;
@@ -2227,6 +2228,7 @@ gsk_path_from_string (const char *s)
   builder = gsk_path_builder_new ();
 
   cmd = 'X';
+  path_x = path_y = 0;
   x = y = 0;
   prev_x1 = prev_y1 = 0;
   after_comma = FALSE;
@@ -2236,8 +2238,10 @@ gsk_path_from_string (const char *s)
     {
       prev_cmd = cmd;
       repeat = !parse_command (&p, &cmd);
+
       if (after_comma && !repeat)
         goto error;
+
       switch (cmd)
         {
         case 'X':
@@ -2248,7 +2252,12 @@ gsk_path_from_string (const char *s)
           if (repeat)
             goto error;
           else
-            gsk_path_builder_close (builder);
+            {
+              gsk_path_builder_line_to (builder, path_x, path_y);
+              gsk_path_builder_close (builder);
+              x = path_x;
+              y = path_y;
+            }
           break;
 
         case 'M':
@@ -2266,7 +2275,14 @@ gsk_path_from_string (const char *s)
                 if (repeat)
                   gsk_path_builder_line_to (builder, x1, y1);
                 else
-                  gsk_path_builder_move_to (builder, x1, y1);
+                  {
+                    gsk_path_builder_move_to (builder, x1, y1);
+                    if (strchr ("zZX", prev_cmd))
+                      {
+                        path_x = x1;
+                        path_y = y1;
+                      }
+                  }
                 x = x1;
                 y = y1;
               }
@@ -2287,6 +2303,13 @@ gsk_path_from_string (const char *s)
                     x1 += x;
                     y1 += y;
                   }
+
+                if (strchr ("zZ", prev_cmd))
+                  {
+                    gsk_path_builder_move_to (builder, x, y);
+                    path_x = x;
+                    path_y = y;
+                  }
                 gsk_path_builder_line_to (builder, x1, y1);
                 x = x1;
                 y = y1;
@@ -2305,6 +2328,12 @@ gsk_path_from_string (const char *s)
               {
                 if (cmd == 'h')
                   x1 += x;
+                if (strchr ("zZ", prev_cmd))
+                  {
+                    gsk_path_builder_move_to (builder, x, y);
+                    path_x = x;
+                    path_y = y;
+                  }
                 gsk_path_builder_line_to (builder, x1, y);
                 x = x1;
               }
@@ -2322,6 +2351,12 @@ gsk_path_from_string (const char *s)
               {
                 if (cmd == 'v')
                   y1 += y;
+                if (strchr ("zZ", prev_cmd))
+                  {
+                    gsk_path_builder_move_to (builder, x, y);
+                    path_x = x;
+                    path_y = y;
+                  }
                 gsk_path_builder_line_to (builder, x, y1);
                 y = y1;
               }
@@ -2348,6 +2383,12 @@ gsk_path_from_string (const char *s)
                     x2 += x;
                     y2 += y;
                   }
+                if (strchr ("zZ", prev_cmd))
+                  {
+                    gsk_path_builder_move_to (builder, x, y);
+                    path_x = x;
+                    path_y = y;
+                  }
                 gsk_path_builder_curve_to (builder, x0, y0, x1, y1, x2, y2);
                 prev_x1 = x1;
                 prev_y1 = y1;
@@ -2384,6 +2425,12 @@ gsk_path_from_string (const char *s)
                     x0 = x;
                     y0 = y;
                   }
+                if (strchr ("zZ", prev_cmd))
+                  {
+                    gsk_path_builder_move_to (builder, x, y);
+                    path_x = x;
+                    path_y = y;
+                  }
                 gsk_path_builder_curve_to (builder, x0, y0, x1, y1, x2, y2);
                 prev_x1 = x1;
                 prev_y1 = y1;
@@ -2414,6 +2461,12 @@ gsk_path_from_string (const char *s)
                 yy1 = (y + 2.0 * y1) / 3.0;
                 xx2 = (x2 + 2.0 * x1) / 3.0;
                 yy2 = (y2 + 2.0 * y1) / 3.0;
+                if (strchr ("zZ", prev_cmd))
+                  {
+                    gsk_path_builder_move_to (builder, x, y);
+                    path_x = x;
+                    path_y = y;
+                  }
                 gsk_path_builder_curve_to (builder, xx1, yy1, xx2, yy2, x2, y2);
                 prev_x1 = x1;
                 prev_y1 = y1;
@@ -2451,6 +2504,12 @@ gsk_path_from_string (const char *s)
                 yy1 = (y + 2.0 * y1) / 3.0;
                 xx2 = (x2 + 2.0 * x1) / 3.0;
                 yy2 = (y2 + 2.0 * y1) / 3.0;
+                if (strchr ("zZ", prev_cmd))
+                  {
+                    gsk_path_builder_move_to (builder, x, y);
+                    path_x = x;
+                    path_y = y;
+                  }
                 gsk_path_builder_curve_to (builder, xx1, yy1, xx2, yy2, x2, y2);
                 prev_x1 = x1;
                 prev_y1 = y1;
@@ -2483,6 +2542,12 @@ gsk_path_from_string (const char *s)
                     y1 += y;
                   }
 
+                if (strchr ("zZ", prev_cmd))
+                  {
+                    gsk_path_builder_move_to (builder, x, y);
+                    path_x = x;
+                    path_y = y;
+                  }
                 gsk_path_builder_arc_to (builder,
                                          rx, ry, x_axis_rotation,
                                          large_arc, sweep,


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