[gtk/curve-ops: 43/97] stroke: Add miter limit




commit 40aa395fe830f54db14ab71c0650ca74a5992adf
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Nov 28 11:14:59 2020 -0500

    stroke: Add miter limit
    
    Add a miter limit to GskStroke. This will be needed to
    fully implement line joins.
    
    Also introduce the GSK_LINE_JOIN_MITER_CLIP value,
    following SVG 2.0. cairo does not have it, so translate
    it to plain miter when using cairo.

 docs/reference/gsk/gsk4-sections.txt |  6 +++--
 gsk/gskenums.h                       |  5 +++++
 gsk/gskstroke.c                      | 43 ++++++++++++++++++++++++++++++++++++
 gsk/gskstroke.h                      |  6 +++++
 gsk/gskstrokeprivate.h               |  1 +
 5 files changed, 59 insertions(+), 2 deletions(-)
---
diff --git a/docs/reference/gsk/gsk4-sections.txt b/docs/reference/gsk/gsk4-sections.txt
index b0f1f0cc8b..17cbca7268 100644
--- a/docs/reference/gsk/gsk4-sections.txt
+++ b/docs/reference/gsk/gsk4-sections.txt
@@ -393,10 +393,12 @@ gsk_stroke_free
 gsk_stroke_equal
 gsk_stroke_set_line_width
 gsk_stroke_get_line_width
-gsk_stroke_set_line_cap
-gsk_stroke_get_line_cap
 gsk_stroke_set_line_join
 gsk_stroke_get_line_join
+gsk_stroke_set_line_cap
+gsk_stroke_get_line_cap
+gsk_stroke_set_miter_limit
+gsk_stroke_get_miter_limit
 <SUBSECTION Private>
 GSK_TYPE_STROKE
 gsk_stroke_get_type
diff --git a/gsk/gskenums.h b/gsk/gskenums.h
index 04a814e618..9582525408 100644
--- a/gsk/gskenums.h
+++ b/gsk/gskenums.h
@@ -219,6 +219,7 @@ typedef enum {
 /**
  * GskLineJoin:
  * @GSK_LINE_JOIN_MITER: Use a sharp, angled corner
+ * @GSK_LINE_JOIN_MITER_CLIP: Use a sharp, angled corner, at a distance
  * @GSK_LINE_JOIN_ROUND: Use a round join, the center of the circle is
  *     the joint point
  * @GSK_LINE_JOIN_BEVEL: Use a cut-off join, the join is cut off at half
@@ -226,10 +227,14 @@ typedef enum {
  *
  * Specifies how to render the junction of two lines when stroking.
  *
+ * See gsk_stroke_set_miter_limit() for details on the difference between
+ * @GSK_LINE_JOIN_MITER and @GSK_LINE_JOIN_MITER_CLIP.
+ *
  * The default line join style is %GSK_LINE_JOIN_MITER.
  **/
 typedef enum {
   GSK_LINE_JOIN_MITER,
+  GSK_LINE_JOIN_MITER_CLIP,
   GSK_LINE_JOIN_ROUND,
   GSK_LINE_JOIN_BEVEL
 } GskLineJoin;
diff --git a/gsk/gskstroke.c b/gsk/gskstroke.c
index 2e6c6293d6..7b72f4ac71 100644
--- a/gsk/gskstroke.c
+++ b/gsk/gskstroke.c
@@ -65,6 +65,9 @@ gsk_stroke_new (float line_width)
   self = g_new0 (GskStroke, 1);
 
   self->line_width = line_width;
+  self->line_cap = GSK_LINE_CAP_BUTT;
+  self->line_join = GSK_LINE_JOIN_MITER;
+  self->miter_limit = 4.f; /* following svg */
 
   return self;
 }
@@ -135,6 +138,7 @@ gsk_stroke_to_cairo (const GskStroke *self,
   switch (self->line_join)
     {
       case GSK_LINE_JOIN_MITER:
+      case GSK_LINE_JOIN_MITER_CLIP:
         cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
         break;
       case GSK_LINE_JOIN_ROUND:
@@ -147,6 +151,8 @@ gsk_stroke_to_cairo (const GskStroke *self,
         g_assert_not_reached ();
         break;
     }
+
+  cairo_set_miter_limit (cr, self->miter_limit);
 }
 
 /**
@@ -268,3 +274,40 @@ gsk_stroke_get_line_join (const GskStroke *self)
   return self->line_join;
 }
 
+/**
+ * gsk_stroke_set_miter_limit:
+ * @self: a #GskStroke
+ * @limit: the miter limit, must be non-negative
+ *
+ * Sets the limit for the distance from the corner where sharp
+ * turns of joins get cut off. The miter limit is in units of
+ * line width.
+ *
+ * For joins of type %GSK_LINE_JOIN_MITER that exceed the miter
+ * limit, the join gets rendered as if it was of type
+ * %GSK_LINE_JOIN_BEVEL. For joins of type %GSK_LINE_JOIN_MITER_CLIP,
+ * the miter is clipped at a distance of half the miter limit.
+ */
+void
+gsk_stroke_set_miter_limit (GskStroke  *self,
+                            float       limit)
+{
+  g_return_if_fail (self != NULL);
+  g_return_if_fail (limit >= 0);
+
+  self->miter_limit = limit;
+}
+
+/**
+ * gsk_stroke_get_miter_limit:
+ * @self: a #GskStroke
+ *
+ * Returns the miter limit of a #GskStroke.
+ */
+float
+gsk_stroke_get_miter_limit (const GskStroke *self)
+{
+  g_return_val_if_fail (self != NULL, 4.f);
+
+  return self->miter_limit;
+}
diff --git a/gsk/gskstroke.h b/gsk/gskstroke.h
index df9295adf6..0605262f3e 100644
--- a/gsk/gskstroke.h
+++ b/gsk/gskstroke.h
@@ -60,6 +60,12 @@ void                    gsk_stroke_set_line_join                (GskStroke
 GDK_AVAILABLE_IN_ALL
 GskLineJoin             gsk_stroke_get_line_join                (const GskStroke        *self);
 
+GDK_AVAILABLE_IN_ALL
+void                    gsk_stroke_set_miter_limit              (GskStroke              *self,
+                                                                 float                   limit);
+GDK_AVAILABLE_IN_ALL
+float                   gsk_stroke_get_miter_limit              (const GskStroke        *self);
+
 
 G_END_DECLS
 
diff --git a/gsk/gskstrokeprivate.h b/gsk/gskstrokeprivate.h
index c6e5c8dc16..850356b1ec 100644
--- a/gsk/gskstrokeprivate.h
+++ b/gsk/gskstrokeprivate.h
@@ -30,6 +30,7 @@ struct _GskStroke
   float line_width;
   GskLineCap line_cap;
   GskLineJoin line_join;
+  float miter_limit;
 };
 
 static inline void


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