[gtk/path-work-rebased: 112/121] Add gsk_path_offset




commit a322bf860bc2a092a8649d97e0bda9db4ce7357e
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Dec 26 23:59:16 2020 -0500

    Add gsk_path_offset
    
    Add a function that takes a path, and offsets it
    by some distance, applying line-join parameters
    as needed.
    
    This commit just adds the api, the implementation
    will be in the following commit.

 gsk/gskcontour.c        | 55 ++++++++++++++++++++++++++++++++++++++++++++-----
 gsk/gskcontourprivate.h |  6 ++++++
 gsk/gskpath.c           | 33 +++++++++++++++++++++++++++++
 gsk/gskpath.h           |  6 ++++++
 4 files changed, 95 insertions(+), 5 deletions(-)
---
diff --git a/gsk/gskcontour.c b/gsk/gskcontour.c
index 2329e9fd2b..d3514d03dd 100644
--- a/gsk/gskcontour.c
+++ b/gsk/gskcontour.c
@@ -89,6 +89,11 @@ struct _GskContourClass
   void                  (* add_stroke)          (const GskContour       *contour,
                                                  GskPathBuilder         *builder,
                                                  GskStroke              *stroke);
+  void                  (* offset)              (const GskContour       *contour,
+                                                 GskPathBuilder         *builder,
+                                                 float                   distance,
+                                                 GskLineJoin             line_join,
+                                                 float                   miter_limit);
 };
 
 static gsize
@@ -498,8 +503,8 @@ gsk_rect_contour_get_stroke_bounds (const GskContour       *contour,
 static gboolean
 stroke_is_simple (GskStroke *stroke)
 {
-  if (stroke->line_join != GSK_LINE_JOIN_MITER &&
-      stroke->line_join != GSK_LINE_JOIN_MITER_CLIP)
+  if (stroke->line_join == GSK_LINE_JOIN_ROUND ||
+      stroke->line_join == GSK_LINE_JOIN_BEVEL)
     return FALSE;
 
   if (stroke->miter_limit < 1.5)
@@ -536,6 +541,15 @@ gsk_rect_contour_add_stroke (const GskContour *contour,
     gsk_contour_default_add_stroke (contour, builder, stroke);
 }
 
+static void
+gsk_rect_contour_offset (const GskContour *contour,
+                         GskPathBuilder   *builder,
+                         float             distance,
+                         GskLineJoin       line_join,
+                         float             miter_limit)
+{
+}
+
 static const GskContourClass GSK_RECT_CONTOUR_CLASS =
 {
   sizeof (GskRectContour),
@@ -554,7 +568,8 @@ static const GskContourClass GSK_RECT_CONTOUR_CLASS =
   gsk_rect_contour_add_segment,
   gsk_rect_contour_get_winding,
   gsk_rect_contour_get_stroke_bounds,
-  gsk_rect_contour_add_stroke
+  gsk_rect_contour_add_stroke,
+  gsk_rect_contour_offset
 };
 
 GskContour *
@@ -911,6 +926,15 @@ gsk_circle_contour_add_stroke (const GskContour *contour,
     gsk_contour_default_add_stroke (contour, builder, stroke);
 }
 
+static void
+gsk_circle_contour_offset (const GskContour *contour,
+                           GskPathBuilder   *builder,
+                           float             distance,
+                           GskLineJoin       line_join,
+                           float             miter_limit)
+{
+}
+
 static const GskContourClass GSK_CIRCLE_CONTOUR_CLASS =
 {
   sizeof (GskCircleContour),
@@ -929,7 +953,8 @@ static const GskContourClass GSK_CIRCLE_CONTOUR_CLASS =
   gsk_circle_contour_add_segment,
   gsk_circle_contour_get_winding,
   gsk_circle_contour_get_stroke_bounds,
-  gsk_circle_contour_add_stroke
+  gsk_circle_contour_add_stroke,
+  gsk_circle_contour_offset
 };
 
 GskContour *
@@ -1625,6 +1650,15 @@ gsk_standard_contour_add_stroke (const GskContour *contour,
   gsk_contour_default_add_stroke (contour, builder, stroke);
 }
 
+static void
+gsk_standard_contour_offset (const GskContour *contour,
+                             GskPathBuilder   *builder,
+                             float             distance,
+                             GskLineJoin       line_join,
+                             float             miter_limit)
+{
+}
+
 static const GskContourClass GSK_STANDARD_CONTOUR_CLASS =
 {
   sizeof (GskStandardContour),
@@ -1643,7 +1677,8 @@ static const GskContourClass GSK_STANDARD_CONTOUR_CLASS =
   gsk_standard_contour_add_segment,
   gsk_standard_contour_get_winding,
   gsk_standard_contour_get_stroke_bounds,
-  gsk_standard_contour_add_stroke
+  gsk_standard_contour_add_stroke,
+  gsk_standard_contour_offset
 };
 
 /* You must ensure the contour has enough size allocated,
@@ -1823,6 +1858,16 @@ gsk_contour_add_stroke (const GskContour *self,
   self->klass->add_stroke (self, builder, stroke);
 }
 
+void
+gsk_contour_offset (const GskContour *self,
+                    GskPathBuilder   *builder,
+                    float             distance,
+                    GskLineJoin       line_join,
+                    float             miter_limit)
+{
+  self->klass->offset (self, builder, distance, line_join, miter_limit);
+}
+
 void
 gsk_contour_copy (GskContour       *dest,
                   const GskContour *src)
diff --git a/gsk/gskcontourprivate.h b/gsk/gskcontourprivate.h
index a8cea1eb95..f1f765706b 100644
--- a/gsk/gskcontourprivate.h
+++ b/gsk/gskcontourprivate.h
@@ -103,6 +103,12 @@ void                    gsk_contour_default_add_stroke          (const GskContou
                                                                  GskPathBuilder         *builder,
                                                                  GskStroke              *stroke);
 
+void                    gsk_contour_offset                      (const GskContour       *contour,
+                                                                 GskPathBuilder         *builder,
+                                                                 float                   distance,
+                                                                 GskLineJoin             line_join,
+                                                                 float                   miter_limit);
+
 G_END_DECLS
 
 #endif /* __GSK_CONTOUR_PRIVATE_H__ */
diff --git a/gsk/gskpath.c b/gsk/gskpath.c
index 14d8431d6b..4d5961bf94 100644
--- a/gsk/gskpath.c
+++ b/gsk/gskpath.c
@@ -1264,3 +1264,36 @@ gsk_path_stroke (GskPath   *self,
 
   return gsk_path_builder_free_to_path (builder);
 }
+
+/**
+ * gsk_path_offset:
+ * @self: a `GskPath`
+ * @distance: the distance to offset the path by
+ * @line_join: how joins are supposed to be drawn
+ * @miter_limit: miter limit for joins
+ *
+ * Create a new path that is offset from @self by @distance.
+ *
+ * The offset can be positive (to the right) or negative.
+ * The @line_join and @miter_limit arguments influence how
+ * joins between the offset path segments are made.
+ *
+ * Returns: a new `GskPath`
+ */
+GskPath *
+gsk_path_offset (GskPath     *self,
+                 float        distance,
+                 GskLineJoin  line_join,
+                 float        miter_limit)
+{
+  GskPathBuilder *builder;
+
+  builder = gsk_path_builder_new ();
+
+  for (int i = 0; i < self->n_contours; i++)
+    gsk_contour_offset (gsk_path_get_contour (self, i), builder, distance, line_join, miter_limit);
+
+  return gsk_path_builder_free_to_path (builder);
+}
+
+
diff --git a/gsk/gskpath.h b/gsk/gskpath.h
index ba463ec359..4a45b00564 100644
--- a/gsk/gskpath.h
+++ b/gsk/gskpath.h
@@ -113,6 +113,12 @@ GDK_AVAILABLE_IN_ALL
 GskPath *               gsk_path_stroke                         (GskPath                *self,
                                                                  GskStroke              *stroke);
 
+GDK_AVAILABLE_IN_ALL
+GskPath *               gsk_path_offset                         (GskPath                *self,
+                                                                 float                   distance,
+                                                                 GskLineJoin             line_join,
+                                                                 float                   miter_limit);
+
 
 G_END_DECLS
 


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