summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2020-11-28 11:14:59 -0500
committerMatthias Clasen <mclasen@redhat.com>2020-11-28 13:36:22 -0500
commit5069410fdf72b8a16fd7301a205f4e772cb341de (patch)
tree5c84c6df4b5080b52284b062d303888f249ec6a3
parentc82080ccea0e8c843209fb78c8b1673d4bc73ea9 (diff)
downloadgtk+-matthiasc/miter-limit.tar.gz
stroke: Add miter limitmatthiasc/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.
-rw-r--r--gsk/gskenums.h7
-rw-r--r--gsk/gskstroke.c41
-rw-r--r--gsk/gskstroke.h6
-rw-r--r--gsk/gskstrokeprivate.h1
4 files changed, 54 insertions, 1 deletions
diff --git a/gsk/gskenums.h b/gsk/gskenums.h
index cb4fa5fe13..bf1df8b43e 100644
--- a/gsk/gskenums.h
+++ b/gsk/gskenums.h
@@ -216,7 +216,8 @@ typedef enum {
/**
* GskLineJoin:
- * @GSK_LINE_JOIN_MITER: Use a shart angled corner
+ * @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 joing point
* @GSK_LINE_JOIN_BEVEL: use a cut-off join, the join is cut off at half
@@ -224,10 +225,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 4a04ca70d1..493ac6ad35 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:
@@ -270,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