[gtk/path-work-rebased: 966/1045] stroke: Add miter limit
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/path-work-rebased: 966/1045] stroke: Add miter limit
- Date: Thu, 7 Apr 2022 19:09:25 +0000 (UTC)
commit 4d5fc177bdf21da07690b33cc7c6b46065d62913
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.
gsk/gskenums.h | 5 +++++
gsk/gskstroke.c | 46 +++++++++++++++++++++++++++++++++++++++++++++-
gsk/gskstroke.h | 6 ++++++
gsk/gskstrokeprivate.h | 1 +
4 files changed, 57 insertions(+), 1 deletion(-)
---
diff --git a/gsk/gskenums.h b/gsk/gskenums.h
index 2d60d477ca..7435884292 100644
--- a/gsk/gskenums.h
+++ b/gsk/gskenums.h
@@ -220,6 +220,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
@@ -227,10 +228,14 @@ typedef enum {
*
* Specifies how to render the junction of two lines when stroking.
*
+ * See [method@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 0752929a58..4b0256f911 100644
--- a/gsk/gskstroke.c
+++ b/gsk/gskstroke.c
@@ -50,6 +50,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;
}
@@ -120,6 +123,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:
@@ -132,6 +136,8 @@ gsk_stroke_to_cairo (const GskStroke *self,
g_assert_not_reached ();
break;
}
+
+ cairo_set_miter_limit (cr, self->miter_limit);
}
/**
@@ -152,7 +158,8 @@ gsk_stroke_equal (gconstpointer stroke1,
if (self1->line_width != self2->line_width ||
self1->line_cap != self2->line_cap ||
- self1->line_join != self2->line_join)
+ self1->line_join != self2->line_join ||
+ self1->miter_limit != self2->miter_limit)
return FALSE;
return TRUE;
@@ -265,3 +272,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]