[gtk/wip/matthiasc/lottie-stroke: 9/9] An initial dashing implementation




commit ca9b8a4f2e26ebef17aca7cc9e673bc8574ac766
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Dec 5 23:30:46 2020 -0500

    An initial dashing implementation
    
    Implement a simple-minded approach to dashing: convert
    the path to one that has a contour per dash, then stroke
    that.

 gsk/gskpathmeasure.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 71 insertions(+), 2 deletions(-)
---
diff --git a/gsk/gskpathmeasure.c b/gsk/gskpathmeasure.c
index 57fae0ec97..fd1940e51f 100644
--- a/gsk/gskpathmeasure.c
+++ b/gsk/gskpathmeasure.c
@@ -24,6 +24,7 @@
 
 #include "gskpathbuilder.h"
 #include "gskpathprivate.h"
+#include "gskstrokeprivate.h"
 
 /**
  * SECTION:gskpathmeasure
@@ -476,6 +477,57 @@ gsk_path_builder_add_segment (GskPathBuilder *self,
     }
 }
 
+static gboolean
+stroke_has_dashes (GskStroke *stroke)
+{
+  int i;
+
+  if (stroke->n_dash == 0)
+    return FALSE;
+
+  for (i = 0; i < stroke->n_dash; i++)
+    {
+      if (stroke->dash[i] < 0)
+        return FALSE;
+      if (stroke->dash[i] > 0)
+        break;
+    }
+
+  if (i == stroke->n_dash)
+    return FALSE;
+
+  return TRUE;
+}
+
+static GskPath *
+get_dash_path (GskPathMeasure *self,
+               GskStroke      *stroke)
+{
+  int i;
+  GskPathBuilder *builder;
+  float length;
+  float s, e;
+
+  builder = gsk_path_builder_new ();
+
+  i = 0;
+  e = - stroke->dash_offset;
+  length = gsk_path_measure_get_length (self);
+
+  while (e < length)
+    {
+      s = e;
+      e = s + stroke->dash[i];
+      if (e >= 0)
+        gsk_path_builder_add_segment (builder, self, s, e);
+      i = (i + 1) % stroke->n_dash;
+      e = e + stroke->dash[i];
+      i = (i + 1) % stroke->n_dash;
+    }
+
+  return gsk_path_builder_free_to_path (builder);
+}
+
 /**
  * gsk_path_measure_stroke:
  * @self: a #GskPathMeasure
@@ -492,14 +544,31 @@ gsk_path_measure_stroke (GskPathMeasure *self,
                          GskStroke      *stroke)
 {
   GskPathBuilder *builder;
+  GskPath *path;
+  GskStroke *str;
   int i;
 
+  str = gsk_stroke_copy (stroke);
+
+  if (stroke_has_dashes (str))
+    {
+      path = get_dash_path (self, str);
+      gsk_stroke_set_dash (str, NULL, 0);
+    }
+  else
+    {
+      path = gsk_path_ref (self->path);
+    }
+
   builder = gsk_path_builder_new ();
 
-  for (i = 0; i < self->n_contours; i++)
+  for (i = 0; i < gsk_path_get_n_contours (path); i++)
     {
-      gsk_contour_add_stroke (gsk_path_get_contour (self->path, i), builder, stroke);
+      gsk_contour_add_stroke (gsk_path_get_contour (path, i), builder, stroke);
     }
 
+  gsk_path_unref (path);
+  gsk_stroke_free (str);
+
   return gsk_path_builder_free_to_path (builder);
 }


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