From: Matthias Clasen Date: Sat, 11 Feb 2023 15:06:54 +0000 (-0500) Subject: Add gtk_snapshot_push_mask X-Git-Tag: archive/raspbian/4.12.3+ds-1+rpi1~1^2^2^2~22^2~7^2~14^2~2 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=8f47e885f0fdc43733c1e1a583f71274e8b1828a;p=gtk4.git Add gtk_snapshot_push_mask --- diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c index 32686d264b..f64a3cc99f 100644 --- a/gtk/gtksnapshot.c +++ b/gtk/gtksnapshot.c @@ -121,6 +121,9 @@ struct _GtkSnapshotState { struct { char *message; } debug; + struct { + GskRenderNode *mask_node; + } mask; } data; }; @@ -1241,6 +1244,79 @@ gtk_snapshot_push_blend (GtkSnapshot *snapshot, NULL); } +static GskRenderNode * +gtk_snapshot_collect_mask_source (GtkSnapshot *snapshot, + GtkSnapshotState *state, + GskRenderNode **nodes, + guint n_nodes) +{ + GskRenderNode *source_child, *mask_child, *mask_node; + + mask_child = gsk_render_node_ref (state->data.mask.mask_node); + source_child = gtk_snapshot_collect_default (snapshot, state, nodes, n_nodes); + + if (source_child == NULL || mask_child == NULL) + return NULL; + + mask_node = gsk_mask_node_new (source_child, mask_child); + + gsk_render_node_unref (source_child); + gsk_render_node_unref (mask_child); + + return mask_node; +} + +static void +gtk_snapshot_clear_mask_source (GtkSnapshotState *state) +{ + g_clear_pointer (&(state->data.mask.mask_node), gsk_render_node_unref); +} + +static GskRenderNode * +gtk_snapshot_collect_mask_mask (GtkSnapshot *snapshot, + GtkSnapshotState *state, + GskRenderNode **nodes, + guint n_nodes) +{ + GtkSnapshotState *prev_state = gtk_snapshot_get_previous_state (snapshot); + + g_assert (prev_state->collect_func == gtk_snapshot_collect_mask_source); + + prev_state->data.mask.mask_node = gtk_snapshot_collect_default (snapshot, state, nodes, n_nodes); + + return NULL; +} + +/** + * gtk_snapshot_push_mask: + * @snapshot: a #GtkSnapshot + * + * Until the first call to [method@Gtk.Snapshot.pop], the + * mask image for the mask operation will be recorded. + * After that call, the source image will be recorded until + * the second call to [method@Gtk.Snapshot.pop]. + * + * Calling this function requires 2 subsequent calls to gtk_snapshot_pop(). + * + * Since: 4.10 + */ +void +gtk_snapshot_push_mask (GtkSnapshot *snapshot) +{ + GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot); + GtkSnapshotState *source_state; + + source_state = gtk_snapshot_push_state (snapshot, + current_state->transform, + gtk_snapshot_collect_mask_source, + gtk_snapshot_clear_mask_source); + + gtk_snapshot_push_state (snapshot, + source_state->transform, + gtk_snapshot_collect_mask_mask, + NULL); +} + static GskRenderNode * gtk_snapshot_collect_cross_fade_end (GtkSnapshot *snapshot, GtkSnapshotState *state, diff --git a/gtk/gtksnapshot.h b/gtk/gtksnapshot.h index 66d0d879f1..d1d5c1a757 100644 --- a/gtk/gtksnapshot.h +++ b/gtk/gtksnapshot.h @@ -95,6 +95,9 @@ void gtk_snapshot_push_shadow (GtkSnapshot GDK_AVAILABLE_IN_ALL void gtk_snapshot_push_blend (GtkSnapshot *snapshot, GskBlendMode blend_mode); +GDK_AVAILABLE_IN_4_10 +void gtk_snapshot_push_mask (GtkSnapshot *snapshot); + GDK_AVAILABLE_IN_ALL void gtk_snapshot_push_cross_fade (GtkSnapshot *snapshot, double progress);