[gtk+] snapshot: Add gtk_snapshot_push_blend()
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] snapshot: Add gtk_snapshot_push_blend()
- Date: Fri, 13 Jan 2017 02:39:03 +0000 (UTC)
commit bc3ba6864174a905d095a3a57a2cb0889d229d9e
Author: Benjamin Otte <otte redhat com>
Date: Thu Jan 12 23:20:31 2017 +0100
snapshot: Add gtk_snapshot_push_blend()
and use it for backgrounds.
docs/reference/gtk/gtk4-sections.txt | 1 +
gtk/gtkrenderbackground.c | 75 +++++++---------------------
gtk/gtksnapshot.c | 91 ++++++++++++++++++++++++++++++++++
gtk/gtksnapshot.h | 5 ++
gtk/gtksnapshotprivate.h | 4 ++
5 files changed, 120 insertions(+), 56 deletions(-)
---
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index 13a4b0d..76fb079 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -4459,6 +4459,7 @@ gtk_snapshot_push_repeat
gtk_snapshot_push_clip
gtk_snapshot_push_rounded_clip
gtk_snapshot_push_cross_fade
+gtk_snapshot_push_blend
gtk_snapshot_pop
gtk_snapshot_pop_and_append
gtk_snapshot_set_transform
diff --git a/gtk/gtkrenderbackground.c b/gtk/gtkrenderbackground.c
index e52d1de..6d2f2fd 100644
--- a/gtk/gtkrenderbackground.c
+++ b/gtk/gtkrenderbackground.c
@@ -619,6 +619,8 @@ gtk_css_style_snapshot_background (GtkCssStyle *style,
gint idx;
GtkCssValue *background_image;
GtkCssValue *box_shadow;
+ GtkCssValue *blend_modes;
+ GskBlendMode blend_mode;
const GdkRGBA *bg_color;
gint number_of_layers;
@@ -639,71 +641,32 @@ gtk_css_style_snapshot_background (GtkCssStyle *style,
snapshot,
&bg.boxes[GTK_CSS_AREA_BORDER_BOX]);
- /*
- * When we have a blend mode set for the background, we must blend on a transparent
- * background. GSK can't do that yet.
- */
- if (_gtk_theming_background_needs_push_group (style))
- {
- GtkCssValue *blend_modes;
- GskBlendMode blend_mode;
+ blend_modes = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BACKGROUND_BLEND_MODE);
+ number_of_layers = _gtk_css_array_value_get_n_values (background_image);
- blend_modes = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BACKGROUND_BLEND_MODE);
+ for (idx = number_of_layers - 1; idx >= 0; idx--)
+ {
+ blend_mode = _gtk_css_blend_mode_value_get (_gtk_css_array_value_get_nth (blend_modes, idx));
- gtk_snapshot_push (snapshot, TRUE, "BackgroundBlendGroup");
+ if (blend_mode != GSK_BLEND_MODE_DEFAULT)
+ gtk_snapshot_push_blend (snapshot, blend_mode, "Background<%u>Blend<%u>", idx, blend_mode);
+ }
- gtk_theming_background_snapshot_color (&bg, snapshot, bg_color, background_image);
+ gtk_theming_background_snapshot_color (&bg, snapshot, bg_color, background_image);
- number_of_layers = _gtk_css_array_value_get_n_values (background_image);
+ for (idx = number_of_layers - 1; idx >= 0; idx--)
+ {
+ blend_mode = _gtk_css_blend_mode_value_get (_gtk_css_array_value_get_nth (blend_modes, idx));
- for (idx = number_of_layers - 1; idx >= 0; idx--)
+ if (blend_mode == GSK_BLEND_MODE_DEFAULT)
{
- blend_mode = _gtk_css_blend_mode_value_get (_gtk_css_array_value_get_nth (blend_modes, idx));
-
- if (blend_mode == GSK_BLEND_MODE_DEFAULT)
- {
- gtk_theming_background_snapshot_layer (&bg, idx, snapshot);
- }
- else
- {
- GskRenderNode *bottom, *top, *blend;
-
- bottom = gtk_snapshot_pop (snapshot);
-
- gtk_snapshot_push (snapshot, TRUE, "BackgroundBlendGroup<Mode%u>", blend_mode);
- gtk_theming_background_snapshot_layer (&bg, idx, snapshot);
- top = gtk_snapshot_pop (snapshot);
-
- /* XXX: Is this necessary? Do we need a NULL node? */
- if (top == NULL)
- top = gsk_container_node_new (NULL, 0);
- if (bottom == NULL)
- bottom = gsk_container_node_new (NULL, 0);
-
- blend = gsk_blend_node_new (bottom, top, blend_mode);
- if (snapshot->record_names)
- gsk_render_node_set_name (blend, "BackgroundBlend");
-
- gtk_snapshot_push (snapshot, TRUE, "BackgroundBlendGroup");
- gtk_snapshot_append_node (snapshot, blend);
-
- gsk_render_node_unref (blend);
- gsk_render_node_unref (top);
- gsk_render_node_unref (bottom);
- }
+ gtk_theming_background_snapshot_layer (&bg, idx, snapshot);
}
-
- gtk_snapshot_pop_and_append (snapshot);
- }
- else
- {
- gtk_theming_background_snapshot_color (&bg, snapshot, bg_color, background_image);
-
- number_of_layers = _gtk_css_array_value_get_n_values (background_image);
-
- for (idx = number_of_layers - 1; idx >= 0; idx--)
+ else
{
+ gtk_snapshot_pop_and_append (snapshot);
gtk_theming_background_snapshot_layer (&bg, idx, snapshot);
+ gtk_snapshot_pop_and_append (snapshot);
}
}
diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c
index d79f903..3e0b9f4 100644
--- a/gtk/gtksnapshot.c
+++ b/gtk/gtksnapshot.c
@@ -676,6 +676,97 @@ gtk_snapshot_push_shadow (GtkSnapshot *snapshot,
}
static GskRenderNode *
+gtk_snapshot_collect_blend_top (GtkSnapshotState *state,
+ GskRenderNode **nodes,
+ guint n_nodes,
+ const char *name)
+{
+ GskRenderNode *bottom_node, *top_node, *blend_node;
+
+ top_node = gtk_snapshot_collect_default (state, nodes, n_nodes, name);
+ bottom_node = state->data.blend.bottom_node;
+
+ /* XXX: Is this necessary? Do we need a NULL node? */
+ if (top_node == NULL)
+ top_node = gsk_container_node_new (NULL, 0);
+ if (bottom_node == NULL)
+ bottom_node = gsk_container_node_new (NULL, 0);
+
+ blend_node = gsk_blend_node_new (bottom_node, top_node, state->data.blend.blend_mode);
+ gsk_render_node_set_name (blend_node, name);
+
+ gsk_render_node_unref (top_node);
+ gsk_render_node_unref (bottom_node);
+
+ return blend_node;
+}
+
+static GskRenderNode *
+gtk_snapshot_collect_blend_bottom (GtkSnapshotState *state,
+ GskRenderNode **nodes,
+ guint n_nodes,
+ const char *name)
+{
+ state->parent->data.blend.bottom_node = gtk_snapshot_collect_default (state, nodes, n_nodes, name);
+
+ return NULL;
+}
+
+/**
+ * gtk_snapshot_push_blend:
+ * @snapshot: a #GtkSnapshot
+ * @blend_mode: blend mode to use
+ * @name: printf format string for name of the pushed node
+ * @...: printf-style arguments for the @name string
+ *
+ * Blends together 2 images with the given blend mode.
+ *
+ * Until the first call to gtk_snapshot_pop(), the bottom image for the
+ * blend operation will be recorded. After that call, the top image to
+ * be blended will be recorded until the second call to gtk_snapshot_pop().
+ *
+ * Calling this function requires 2 subsequent calls to gtk_snapshot_pop().
+ **/
+void
+gtk_snapshot_push_blend (GtkSnapshot *snapshot,
+ GskBlendMode blend_mode,
+ const char *name,
+ ...)
+{
+ GtkSnapshotState *state;
+ char *str;
+
+ if (name && snapshot->record_names)
+ {
+ va_list args;
+
+ va_start (args, name);
+ str = g_strdup_vprintf (name, args);
+ va_end (args);
+ }
+ else
+ str = NULL;
+
+ state = gtk_snapshot_state_new (snapshot->state,
+ str,
+ snapshot->state->clip_region,
+ snapshot->state->translate_x,
+ snapshot->state->translate_y,
+ gtk_snapshot_collect_blend_top);
+ state->data.blend.blend_mode = blend_mode;
+ state->data.blend.bottom_node = NULL;
+
+ state = gtk_snapshot_state_new (state,
+ str,
+ state->clip_region,
+ state->translate_x,
+ state->translate_y,
+ gtk_snapshot_collect_blend_bottom);
+
+ snapshot->state = state;
+}
+
+static GskRenderNode *
gtk_snapshot_collect_cross_fade_end (GtkSnapshotState *state,
GskRenderNode **nodes,
guint n_nodes,
diff --git a/gtk/gtksnapshot.h b/gtk/gtksnapshot.h
index 7ac7a43..b59f32c 100644
--- a/gtk/gtksnapshot.h
+++ b/gtk/gtksnapshot.h
@@ -80,6 +80,11 @@ void gtk_snapshot_push_shadow (GtkSnapshot
const char *name,
...) G_GNUC_PRINTF (4, 5);
GDK_AVAILABLE_IN_3_90
+void gtk_snapshot_push_blend (GtkSnapshot *snapshot,
+ GskBlendMode blend_mode,
+ const char *name,
+ ...) G_GNUC_PRINTF (3, 4);
+GDK_AVAILABLE_IN_3_90
void gtk_snapshot_push_cross_fade (GtkSnapshot *snapshot,
double progress,
const char *name,
diff --git a/gtk/gtksnapshotprivate.h b/gtk/gtksnapshotprivate.h
index 3989bc5..3676a10 100644
--- a/gtk/gtksnapshotprivate.h
+++ b/gtk/gtksnapshotprivate.h
@@ -68,6 +68,10 @@ struct _GtkSnapshotState {
GskShadow a_shadow; /* Used if n_shadows == 1 */
} shadow;
struct {
+ GskBlendMode blend_mode;
+ GskRenderNode *bottom_node;
+ } blend;
+ struct {
double progress;
GskRenderNode *start_node;
} cross_fade;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]