From 95e72be25c6fa5b57360212875895007d407634c Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Wed, 11 Nov 2020 01:17:42 +0100 Subject: [PATCH] snapshot: Add gtk_snapshot_push_fill() --- docs/reference/gtk/gtk4-sections.txt | 1 + gtk/gtksnapshot.c | 69 ++++++++++++++++++++++++++++ gtk/gtksnapshot.h | 4 ++ 3 files changed, 74 insertions(+) diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt index 5d0e11331b..3d750365f7 100644 --- a/docs/reference/gtk/gtk4-sections.txt +++ b/docs/reference/gtk/gtk4-sections.txt @@ -4296,6 +4296,7 @@ gtk_snapshot_push_color_matrix gtk_snapshot_push_repeat gtk_snapshot_push_clip gtk_snapshot_push_rounded_clip +gtk_snapshot_push_fill gtk_snapshot_push_cross_fade gtk_snapshot_push_blend gtk_snapshot_push_blur diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c index e01ce5ec68..38afe2b98a 100644 --- a/gtk/gtksnapshot.c +++ b/gtk/gtksnapshot.c @@ -108,6 +108,10 @@ struct _GtkSnapshotState { struct { GskRoundedRect bounds; } rounded_clip; + struct { + GskPath *path; + GskFillRule fill_rule; + } fill; struct { gsize n_shadows; GskShadow *shadows; @@ -1102,6 +1106,71 @@ gtk_snapshot_push_rounded_clip (GtkSnapshot *snapshot, gtk_rounded_rect_scale_affine (&state->data.rounded_clip.bounds, bounds, scale_x, scale_y, dx, dy); } +static GskRenderNode * +gtk_snapshot_collect_fill (GtkSnapshot *snapshot, + GtkSnapshotState *state, + GskRenderNode **nodes, + guint n_nodes) +{ + GskRenderNode *node, *fill_node; + + node = gtk_snapshot_collect_default (snapshot, state, nodes, n_nodes); + if (node == NULL) + return NULL; + + fill_node = gsk_fill_node_new (node, + state->data.fill.path, + state->data.fill.fill_rule); + + if (fill_node->bounds.size.width == 0 || + fill_node->bounds.size.height == 0) + { + gsk_render_node_unref (node); + gsk_render_node_unref (fill_node); + return NULL; + } + + gsk_render_node_unref (node); + + return fill_node; +} + +static void +gtk_snapshot_clear_fill (GtkSnapshotState *state) +{ + gsk_path_unref (state->data.fill.path); +} + +/** + * gtk_snapshot_push_fill: + * @snapshot: a #GtkSnapshot + * @path: The path describing the area to fill + * @fill_rule: The fill rule to use + * + * Fills the area given by @path and @fill_rule with an image and discards everything + * outside of it. + * + * The image is recorded until the next call to gtk_snapshot_pop(). + */ +void +gtk_snapshot_push_fill (GtkSnapshot *snapshot, + GskPath *path, + GskFillRule fill_rule) +{ + 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_fill, + gtk_snapshot_clear_fill); + + state->data.fill.path = gsk_path_ref (path); + state->data.fill.fill_rule = fill_rule; +} + static GskRenderNode * gtk_snapshot_collect_shadow (GtkSnapshot *snapshot, GtkSnapshotState *state, diff --git a/gtk/gtksnapshot.h b/gtk/gtksnapshot.h index 6125e44ecc..45592c963c 100644 --- a/gtk/gtksnapshot.h +++ b/gtk/gtksnapshot.h @@ -89,6 +89,10 @@ GDK_AVAILABLE_IN_ALL void gtk_snapshot_push_rounded_clip (GtkSnapshot *snapshot, const GskRoundedRect *bounds); GDK_AVAILABLE_IN_ALL +void gtk_snapshot_push_fill (GtkSnapshot *snapshot, + GskPath *path, + GskFillRule fill_rule); +GDK_AVAILABLE_IN_ALL void gtk_snapshot_push_shadow (GtkSnapshot *snapshot, const GskShadow *shadow, gsize n_shadows);