[gtk/wip/matthiasc/lottie-stroke: 46/58] Implement dashing




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

    Implement dashing
    
    Implement dashing by converting the original path to one that has
    one 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 2357d42a3a..9ff371582f 100644
--- a/gsk/gskpathmeasure.c
+++ b/gsk/gskpathmeasure.c
@@ -23,6 +23,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]