[gtk/matthiasc/lottie] path: Stop using arcs for serializing circles



commit 97f385991c90b24c533fb000869d79cb3ff4cde8
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Nov 24 02:20:09 2020 -0500

    path: Stop using arcs for serializing circles
    
    The svg A can not do a full circle, since it is a
    two point parametrization - if the start and end
    point are the same, it draws nothing. Breaking
    the circle into multiple arcs may work, but it
    is much more straightforward to just use Bezier
    segments.

 gsk/gskpath.c | 40 +++++++++++++++++++++++++++++-----------
 1 file changed, 29 insertions(+), 11 deletions(-)
---
diff --git a/gsk/gskpath.c b/gsk/gskpath.c
index a718380042..7447035790 100644
--- a/gsk/gskpath.c
+++ b/gsk/gskpath.c
@@ -376,22 +376,40 @@ gsk_circle_contour_get_flags (const GskContour *contour)
     return 0;
 }
 
+static gboolean
+circle_contour_print_func (const graphene_point_t pts[4],
+                           gpointer               data)
+{
+  GString *string = data;
+
+  g_string_append_printf (string, "C %g %g, %g %g, %g %g ",
+                          pts[1].x, pts[1].y,
+                          pts[2].x, pts[2].y,
+                          pts[3].x, pts[3].y);
+  return TRUE;
+}
+
 static void
 gsk_circle_contour_print (const GskContour *contour,
                           GString          *string)
 {
   const GskCircleContour *self = (const GskCircleContour *) contour;
-  graphene_point_t start = GRAPHENE_POINT_INIT (cos (DEG_TO_RAD (self->start_angle)) * self->radius,
-                                                sin (DEG_TO_RAD (self->start_angle)) * self->radius);
-  graphene_point_t end = GRAPHENE_POINT_INIT (cos (DEG_TO_RAD (self->end_angle)) * self->radius,
-                                              sin (DEG_TO_RAD (self->end_angle)) * self->radius);
+  graphene_point_t start = GRAPHENE_POINT_INIT (self->center.x + cos (DEG_TO_RAD (self->start_angle)) * 
self->radius,
+                                                self->center.y + sin (DEG_TO_RAD (self->start_angle)) * 
self->radius);
 
-  g_string_append_printf (string, "M %g %g A %g %g 0 %u %u %g %g",
-                          self->center.x + start.x, self->center.y + start.y, 
-                          self->radius, self->radius,
-                          fabs (self->start_angle - self->end_angle) > 180 ? 1 : 0,
-                          self->start_angle < self->end_angle ? 0 : 1,
-                          self->center.x + end.x, self->center.y + end.y);
+  g_string_append_printf (string, "M %g %g ", start.x, start.y);
+
+  if (!gsk_spline_decompose_arc (&self->center,
+                                 self->radius,
+                                 GSK_PATH_TOLERANCE_DEFAULT,
+                                 DEG_TO_RAD (self->start_angle),
+                                 DEG_TO_RAD (self->end_angle),
+                                 circle_contour_print_func,
+                                 string))
+    return;
+
+  if (fabs (self->start_angle - self->end_angle) >= 360)
+    g_string_append (string, "Z");
 }
 
 static gboolean
@@ -2490,7 +2508,7 @@ gsk_path_from_string (const char *s)
   return gsk_path_builder_free_to_path (builder);
 
 error:
-  //g_warning ("Can't parse string '%s' as GskPath, error at %ld", s, p - s);
+  g_warning ("Can't parse string '%s' as GskPath, error at %ld", s, p - s);
   gsk_path_builder_unref (builder);
 
   return NULL;


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