[gtk/wip/otte/lottie: 30/42] path: Add gsk_path_measure_restrict_to_contour()




commit dc123e45158ec44af0c2e7fcd114e7e81184a8bb
Author: Benjamin Otte <otte redhat com>
Date:   Thu Dec 17 04:37:18 2020 +0100

    path: Add gsk_path_measure_restrict_to_contour()

 docs/reference/gsk/gsk4-sections.txt |  3 ++
 gsk/gskpathmeasure.c                 | 77 ++++++++++++++++++++++++++++++++----
 gsk/gskpathmeasure.h                 |  6 +++
 3 files changed, 79 insertions(+), 7 deletions(-)
---
diff --git a/docs/reference/gsk/gsk4-sections.txt b/docs/reference/gsk/gsk4-sections.txt
index 6c600954ed..8c8729302b 100644
--- a/docs/reference/gsk/gsk4-sections.txt
+++ b/docs/reference/gsk/gsk4-sections.txt
@@ -382,6 +382,9 @@ gsk_path_measure_unref
 <SUBSECTION>
 gsk_path_measure_get_path
 gsk_path_measure_get_tolerance
+gsk_path_measure_get_n_contours
+gsk_path_measure_restrict_to_contour
+<SUBSECTION>
 gsk_path_measure_get_length
 gsk_path_measure_get_point
 gsk_path_measure_get_closest_point
diff --git a/gsk/gskpathmeasure.c b/gsk/gskpathmeasure.c
index 4062ab45a9..2e73d95051 100644
--- a/gsk/gskpathmeasure.c
+++ b/gsk/gskpathmeasure.c
@@ -50,6 +50,9 @@ struct _GskPathMeasure
   GskPath *path;
   float tolerance;
 
+  gsize first;
+  gsize last;
+
   float length;
   gsize n_contours;
   GskContourMeasure measures[];
@@ -107,6 +110,8 @@ gsk_path_measure_new_with_tolerance (GskPath *path,
   self->path = gsk_path_ref (path);
   self->tolerance = tolerance;
   self->n_contours = n_contours;
+  self->first = 0;
+  self->last = n_contours;
 
   for (i = 0; i < n_contours; i++)
     {
@@ -177,6 +182,8 @@ gsk_path_measure_unref (GskPathMeasure *self)
 GskPath *
 gsk_path_measure_get_path (GskPathMeasure *self)
 {
+  g_return_val_if_fail (self != NULL, NULL);
+
   return self->path;
 }
 
@@ -191,9 +198,65 @@ gsk_path_measure_get_path (GskPathMeasure *self)
 float
 gsk_path_measure_get_tolerance (GskPathMeasure *self)
 {
+  g_return_val_if_fail (self != NULL, 0.f);
+
   return self->tolerance;
 }
 
+/**
+ * gsk_path_measure_get_n_contours:
+ * @self: a #GskPathMeasure
+ *
+ * Returns the number of contours in the path being measured.
+ *
+ * The returned value is independent of whether @self if restricted
+ * or not.
+ *
+ * Returns: The number of contours
+ **/
+gsize
+gsk_path_measure_get_n_contours (GskPathMeasure *self)
+{
+  g_return_val_if_fail (self != NULL, 0);
+
+  return self->n_contours;
+}
+
+/**
+ * gsk_path_measure_restrict_to_contour:
+ * @self: a #GskPathMeasure
+ * @contour: contour to restrict to or (gsize) -1 for using the
+ *     whole path
+ *
+ * Restricts all functions on the path to just the given @contour.
+ *
+ * If @contour >= gsk_path_measure_get_n_contours() - so in
+ * particular when it is set to -1 - the whole path will be used.
+ **/
+void
+gsk_path_measure_restrict_to_contour (GskPathMeasure *self,
+                                      gsize           contour)
+{
+  if (contour >= self->n_contours)
+    {
+      /* use the whole path */
+      self->first = 0;
+      self->last = self->n_contours;
+    }
+  else
+    {
+      /* use just one contour */
+      self->first = contour;
+      self->last = contour + 1;
+    }
+
+  self->length = 0;
+  for (gsize i = self->first; i < self->last; i++)
+    {
+      self->length += self->measures[i].length;
+    }
+}
+
 /**
  * gsk_path_measure_get_length:
  * @self: a #GskPathMeasure
@@ -257,7 +320,7 @@ gsk_path_measure_get_point (GskPathMeasure   *self,
 
   distance = gsk_path_measure_clamp_distance (self, distance);
 
-  for (i = 0; i < self->n_contours; i++)
+  for (i = self->first; i < self->last; i++)
     {
       if (distance < self->measures[i].length)
         break;
@@ -266,10 +329,10 @@ gsk_path_measure_get_point (GskPathMeasure   *self,
     }
 
   /* weird corner cases */
-  if (i == self->n_contours)
+  if (i == self->last)
     {
       /* the empty path goes here */
-      if (self->n_contours == 0)
+      if (self->first == self->last)
         {
           if (pos)
             graphene_point_init (pos, 0.f, 0.f);
@@ -278,7 +341,7 @@ gsk_path_measure_get_point (GskPathMeasure   *self,
           return;
         }
       /* rounding errors can make this happen */
-      i = self->n_contours - 1;
+      i = self->last - 1;
       distance = self->measures[i].length;
     }
 
@@ -372,7 +435,7 @@ gsk_path_measure_get_closest_point_full (GskPathMeasure         *self,
   result = FALSE;
   length = 0;
 
-  for (i = 0; i < self->n_contours; i++)
+  for (i = self->first; i < self->last; i++)
     {
       if (gsk_contour_get_closest_point (gsk_path_get_contour (self->path, i),
                                          self->measures[i].contour_data,
@@ -422,7 +485,7 @@ gsk_path_measure_in_fill (GskPathMeasure         *self,
   gboolean on_edge = FALSE;
   int i;
 
-  for (i = 0; i < self->n_contours; i++)
+  for (i = self->first; i < self->last; i++)
     {
       winding += gsk_contour_get_winding (gsk_path_get_contour (self->path, i),
                                           self->measures[i].contour_data,
@@ -476,7 +539,7 @@ gsk_path_builder_add_segment (GskPathBuilder *self,
   if (start >= end)
     return;
 
-  for (i = 0; i < measure->n_contours; i++)
+  for (i = measure->first; i < measure->last; i++)
     {
       if (measure->measures[i].length < start)
         {
diff --git a/gsk/gskpathmeasure.h b/gsk/gskpathmeasure.h
index d899b01f7d..35bf44edb8 100644
--- a/gsk/gskpathmeasure.h
+++ b/gsk/gskpathmeasure.h
@@ -48,6 +48,12 @@ GDK_AVAILABLE_IN_ALL
 GskPath *               gsk_path_measure_get_path               (GskPathMeasure         *self) G_GNUC_PURE;
 GDK_AVAILABLE_IN_ALL
 float                   gsk_path_measure_get_tolerance          (GskPathMeasure         *self) G_GNUC_PURE;
+GDK_AVAILABLE_IN_ALL
+gsize                   gsk_path_measure_get_n_contours         (GskPathMeasure         *self) G_GNUC_PURE;
+
+GDK_AVAILABLE_IN_ALL
+void                    gsk_path_measure_restrict_to_contour    (GskPathMeasure         *self,
+                                                                 gsize                   contour);
 
 GDK_AVAILABLE_IN_ALL
 float                   gsk_path_measure_get_length             (GskPathMeasure         *self);


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