diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c index 87de5421f1..ef97077821 100644 --- a/gtk/gtksnapshot.c +++ b/gtk/gtksnapshot.c @@ -30,6 +30,7 @@ #include "gsk/gskrendernodeprivate.h" #include "gsk/gskroundedrectprivate.h" +#include "gsk/gskstrokeprivate.h" #include "gtk/gskpangoprivate.h" @@ -109,6 +110,10 @@ struct _GtkSnapshotState { GskPath *path; GskFillRule fill_rule; } fill; + struct { + GskPath *path; + GskStroke stroke; + } stroke; struct { gsize n_shadows; GskShadow *shadows; @@ -1167,6 +1172,74 @@ gtk_snapshot_push_fill (GtkSnapshot *snapshot, state->data.fill.fill_rule = fill_rule; } +static GskRenderNode * +gtk_snapshot_collect_stroke (GtkSnapshot *snapshot, + GtkSnapshotState *state, + GskRenderNode **nodes, + guint n_nodes) +{ + GskRenderNode *node, *stroke_node; + + node = gtk_snapshot_collect_default (snapshot, state, nodes, n_nodes); + if (node == NULL) + return NULL; + + stroke_node = gsk_stroke_node_new (node, + state->data.stroke.path, + &state->data.stroke.stroke); + + if (stroke_node->bounds.size.width == 0 || + stroke_node->bounds.size.height == 0) + { + gsk_render_node_unref (node); + gsk_render_node_unref (stroke_node); + return NULL; + } + + gsk_render_node_unref (node); + + return stroke_node; +} + +static void +gtk_snapshot_clear_stroke (GtkSnapshotState *state) +{ + gsk_path_unref (state->data.stroke.path); + gsk_stroke_clear (&state->data.stroke.stroke); +} + +/** + * gtk_snapshot_push_stroke: + * @snapshot: a #GtkSnapshot + * @path: The path to stroke + * @stroke: The stroke attributes + * + * Strokes the given @path with the attributes given by @stroke and + * an image. + * + * The image is recorded until the next call to [method@Gtk.Snapshot.pop]. + * + * Since: 4.14 + */ +void +gtk_snapshot_push_stroke (GtkSnapshot *snapshot, + GskPath *path, + const GskStroke *stroke) +{ + GtkSnapshotState *state; + + /* FIXME: Is it worth calling ensure_affine() and transforming the path here? */ + gtk_snapshot_ensure_identity (snapshot); + + state = gtk_snapshot_push_state (snapshot, + gtk_snapshot_get_current_state (snapshot)->transform, + gtk_snapshot_collect_stroke, + gtk_snapshot_clear_stroke); + + state->data.stroke.path = gsk_path_ref (path); + gsk_stroke_init_copy (&state->data.stroke.stroke, stroke); +} + static GskRenderNode * gtk_snapshot_collect_shadow (GtkSnapshot *snapshot, GtkSnapshotState *state, diff --git a/gtk/gtksnapshot.h b/gtk/gtksnapshot.h index d20b483480..faa40b732d 100644 --- a/gtk/gtksnapshot.h +++ b/gtk/gtksnapshot.h @@ -91,6 +91,10 @@ GDK_AVAILABLE_IN_4_14 void gtk_snapshot_push_fill (GtkSnapshot *snapshot, GskPath *path, GskFillRule fill_rule); +GDK_AVAILABLE_IN_4_14 +void gtk_snapshot_push_stroke (GtkSnapshot *snapshot, + GskPath *path, + const GskStroke *stroke); GDK_AVAILABLE_IN_ALL void gtk_snapshot_push_shadow (GtkSnapshot *snapshot, const GskShadow *shadow,