summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2016-12-19 00:45:35 +0100
committerBenjamin Otte <otte@redhat.com>2016-12-20 18:01:12 +0100
commit2480e0d57530b72a8efa4fefeff98971b61e16da (patch)
treed3cfc00d1b527c4a87c5745389ce98e61d90870a /gtk
parent071c9a8221b53ab3e3586349187119221621d00a (diff)
downloadgtk+-2480e0d57530b72a8efa4fefeff98971b61e16da.tar.gz
gsk: Add GskShadowNode
... and make the icon rendering code use it. This requires moving even more shadow renering code into GSK, but so be it. At least the "shadows not implemented" warning is now gone!
Diffstat (limited to 'gtk')
-rw-r--r--gtk/gtkcssshadowsvalue.c19
-rw-r--r--gtk/gtkcssshadowsvalueprivate.h3
-rw-r--r--gtk/gtkcssshadowvalue.c11
-rw-r--r--gtk/gtkcssshadowvalueprivate.h2
-rw-r--r--gtk/gtkrendericon.c42
-rw-r--r--gtk/gtksnapshot.c61
-rw-r--r--gtk/gtksnapshot.h6
-rw-r--r--gtk/inspector/gtktreemodelrendernode.c4
-rw-r--r--gtk/inspector/recorder.c2
9 files changed, 134 insertions, 16 deletions
diff --git a/gtk/gtkcssshadowsvalue.c b/gtk/gtkcssshadowsvalue.c
index c7037a7a3e..40fb07af6c 100644
--- a/gtk/gtkcssshadowsvalue.c
+++ b/gtk/gtkcssshadowsvalue.c
@@ -268,6 +268,25 @@ _gtk_css_shadows_value_is_none (const GtkCssValue *shadows)
return shadows->len == 0;
}
+GskShadow *
+gtk_css_shadows_value_get_shadows (const GtkCssValue *shadows,
+ gsize *n_shadows)
+{
+ GskShadow *result;
+ guint i;
+
+ result = g_new (GskShadow, shadows->len);
+
+ for (i = 0; i < shadows->len; i++)
+ {
+ gtk_css_shadow_value_get_shadow (shadows->values[i], &result[i]);
+ }
+
+ *n_shadows = shadows->len;
+
+ return result;
+}
+
void
_gtk_css_shadows_value_paint_layout (const GtkCssValue *shadows,
cairo_t *cr,
diff --git a/gtk/gtkcssshadowsvalueprivate.h b/gtk/gtkcssshadowsvalueprivate.h
index a0e6b66d7c..039c8f0cb7 100644
--- a/gtk/gtkcssshadowsvalueprivate.h
+++ b/gtk/gtkcssshadowsvalueprivate.h
@@ -36,6 +36,9 @@ GtkCssValue * _gtk_css_shadows_value_parse (GtkCssParser
gboolean _gtk_css_shadows_value_is_none (const GtkCssValue *shadows);
+GskShadow * gtk_css_shadows_value_get_shadows (const GtkCssValue *shadows,
+ gsize *n_shadows);
+
void _gtk_css_shadows_value_paint_layout (const GtkCssValue *shadows,
cairo_t *cr,
PangoLayout *layout);
diff --git a/gtk/gtkcssshadowvalue.c b/gtk/gtkcssshadowvalue.c
index f68a39e66c..c0cccd7835 100644
--- a/gtk/gtkcssshadowvalue.c
+++ b/gtk/gtkcssshadowvalue.c
@@ -625,6 +625,17 @@ gtk_css_shadow_value_get_extents (const GtkCssValue *shadow,
border->left = MAX (0, ceil (clip_radius + spread - hoffset));
}
+void
+gtk_css_shadow_value_get_shadow (const GtkCssValue *value,
+ GskShadow *shadow)
+{
+ shadow->color = *_gtk_css_rgba_value_get_rgba (value->color);
+ shadow->dx = _gtk_css_number_value_get (value->hoffset, 0);
+ shadow->dy = _gtk_css_number_value_get (value->voffset, 0);
+ shadow->spread = _gtk_css_number_value_get (value->spread, 0);
+ shadow->radius = _gtk_css_number_value_get (value->radius, 0);
+}
+
static gboolean
has_empty_clip (cairo_t *cr)
{
diff --git a/gtk/gtkcssshadowvalueprivate.h b/gtk/gtkcssshadowvalueprivate.h
index 4eb6b7967f..2c139c86e8 100644
--- a/gtk/gtkcssshadowvalueprivate.h
+++ b/gtk/gtkcssshadowvalueprivate.h
@@ -39,6 +39,8 @@ gboolean _gtk_css_shadow_value_get_inset (const GtkCssValue
void gtk_css_shadow_value_get_extents (const GtkCssValue *shadow,
GtkBorder *border);
+void gtk_css_shadow_value_get_shadow (const GtkCssValue *value,
+ GskShadow *shadow);
void _gtk_css_shadow_value_paint_layout (const GtkCssValue *shadow,
cairo_t *cr,
diff --git a/gtk/gtkrendericon.c b/gtk/gtkrendericon.c
index 3af2613b76..15f8397d3c 100644
--- a/gtk/gtkrendericon.c
+++ b/gtk/gtkrendericon.c
@@ -95,10 +95,11 @@ gtk_css_style_snapshot_icon (GtkCssStyle *style,
double height,
GtkCssImageBuiltinType builtin_type)
{
- const GtkCssValue *shadows, *transform;
- static gboolean shadow_warning;
+ const GtkCssValue *shadows_value, *transform;
graphene_matrix_t transform_matrix;
GtkCssImage *image;
+ GskShadow *shadows;
+ gsize n_shadows;
g_return_if_fail (GTK_IS_CSS_STYLE (style));
g_return_if_fail (snapshot != NULL);
@@ -107,17 +108,15 @@ gtk_css_style_snapshot_icon (GtkCssStyle *style,
if (image == NULL)
return;
- shadows = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_SHADOW);
+ shadows_value = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_SHADOW);
transform = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_TRANSFORM);
if (!gtk_css_transform_value_get_matrix (transform, &transform_matrix))
return;
- if (!_gtk_css_shadows_value_is_none (shadows) && !shadow_warning)
- {
- g_warning ("Painting shadows not implemented for textures yet.");
- shadow_warning = TRUE;
- }
+ shadows = gtk_css_shadows_value_get_shadows (shadows_value, &n_shadows);
+ if (shadows)
+ gtk_snapshot_push_shadow (snapshot, shadows, n_shadows, "IconShadow<%zu>", n_shadows);
if (graphene_matrix_is_identity (&transform_matrix))
{
@@ -139,6 +138,12 @@ gtk_css_style_snapshot_icon (GtkCssStyle *style,
gtk_snapshot_pop_and_append (snapshot);
}
+
+ if (shadows)
+ {
+ gtk_snapshot_pop_and_append (snapshot);
+ g_free (shadows);
+ }
}
static gboolean
@@ -261,18 +266,19 @@ gtk_css_style_snapshot_icon_texture (GtkCssStyle *style,
GskTexture *texture,
double texture_scale)
{
- const GtkCssValue *shadows, *transform;
+ const GtkCssValue *shadows_value, *transform;
graphene_matrix_t transform_matrix;
graphene_rect_t bounds;
double width, height;
- static gboolean shadow_warning;
+ GskShadow *shadows;
+ gsize n_shadows;
g_return_if_fail (GTK_IS_CSS_STYLE (style));
g_return_if_fail (snapshot != NULL);
g_return_if_fail (GSK_IS_TEXTURE (texture));
g_return_if_fail (texture_scale > 0);
- shadows = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_SHADOW);
+ shadows_value = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_SHADOW);
transform = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_TRANSFORM);
width = gsk_texture_get_width (texture) / texture_scale;
height = gsk_texture_get_height (texture) / texture_scale;
@@ -280,11 +286,9 @@ gtk_css_style_snapshot_icon_texture (GtkCssStyle *style,
if (!gtk_css_transform_value_get_matrix (transform, &transform_matrix))
return;
- if (!_gtk_css_shadows_value_is_none (shadows) && !shadow_warning)
- {
- g_warning ("Painting shadows not implemented for textures yet.");
- shadow_warning = TRUE;
- }
+ shadows = gtk_css_shadows_value_get_shadows (shadows_value, &n_shadows);
+ if (shadows)
+ gtk_snapshot_push_shadow (snapshot, shadows, n_shadows, "IconShadow<%zu>", n_shadows);
if (graphene_matrix_is_identity (&transform_matrix))
{
@@ -311,4 +315,10 @@ gtk_css_style_snapshot_icon_texture (GtkCssStyle *style,
gtk_snapshot_pop_and_append (snapshot);
}
+
+ if (shadows)
+ {
+ gtk_snapshot_pop_and_append (snapshot);
+ g_free (shadows);
+ }
}
diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c
index e977e4af9f..06895d6ad3 100644
--- a/gtk/gtksnapshot.c
+++ b/gtk/gtksnapshot.c
@@ -472,6 +472,67 @@ gtk_snapshot_push_rounded_clip (GtkSnapshot *snapshot,
cairo_region_destroy (clip);
}
+typedef struct {
+ gsize n_shadows;
+ GskShadow shadows[0];
+} Shadow;
+
+static GskRenderNode *
+gtk_snapshot_collect_shadow (GskRenderNode **nodes,
+ guint n_nodes,
+ const char *name,
+ gpointer data)
+{
+ Shadow *shadow = data;
+ GskRenderNode *node, *shadow_node;
+
+ node = gtk_snapshot_collect_default (nodes, n_nodes, name, NULL);
+ if (node == NULL)
+ return NULL;
+
+ shadow_node = gsk_shadow_node_new (node, shadow->shadows, shadow->n_shadows);
+ gsk_render_node_set_name (shadow_node, name);
+
+ gsk_render_node_unref (node);
+ g_free (shadow);
+
+ return shadow_node;
+}
+
+void
+gtk_snapshot_push_shadow (GtkSnapshot *snapshot,
+ const GskShadow *shadow,
+ gsize n_shadows,
+ const char *name,
+ ...)
+{
+ Shadow *real_shadow;
+ char *str;
+
+ real_shadow = g_malloc (sizeof (GskShadow) * n_shadows + sizeof (GskShadow));
+ real_shadow->n_shadows = n_shadows;
+ memcpy (real_shadow->shadows, shadow, sizeof (GskShadow) * n_shadows);
+
+ if (name)
+ {
+ va_list args;
+
+ va_start (args, name);
+ str = g_strdup_vprintf (name, args);
+ va_end (args);
+ }
+ else
+ str = NULL;
+
+ snapshot->state = gtk_snapshot_state_new (snapshot->state,
+ str,
+ snapshot->state->clip_region,
+ snapshot->state->translate_x,
+ snapshot->state->translate_y,
+ gtk_snapshot_collect_shadow,
+ real_shadow);
+}
+
/**
* gtk_snapshot_pop:
* @snapshot: a #GtkSnapshot
diff --git a/gtk/gtksnapshot.h b/gtk/gtksnapshot.h
index c5c2d20b3d..22a12a3527 100644
--- a/gtk/gtksnapshot.h
+++ b/gtk/gtksnapshot.h
@@ -62,6 +62,12 @@ void gtk_snapshot_push_rounded_clip (GtkSnapshot
const char *name,
...) G_GNUC_PRINTF (3, 4);
GDK_AVAILABLE_IN_3_90
+void gtk_snapshot_push_shadow (GtkSnapshot *snapshot,
+ const GskShadow *shadow,
+ gsize n_shadows,
+ const char *name,
+ ...) G_GNUC_PRINTF (4, 5);
+GDK_AVAILABLE_IN_3_90
GskRenderNode * gtk_snapshot_pop (GtkSnapshot *snapshot) G_GNUC_WARN_UNUSED_RESULT;
GDK_AVAILABLE_IN_3_90
void gtk_snapshot_pop_and_append (GtkSnapshot *snapshot);
diff --git a/gtk/inspector/gtktreemodelrendernode.c b/gtk/inspector/gtktreemodelrendernode.c
index 96b0d944e9..6064f9c431 100644
--- a/gtk/inspector/gtktreemodelrendernode.c
+++ b/gtk/inspector/gtktreemodelrendernode.c
@@ -547,6 +547,10 @@ append_node (GtkTreeModelRenderNode *nodemodel,
append_node (nodemodel, gsk_rounded_clip_node_get_child (node), priv->nodes->len - 1);
break;
+ case GSK_SHADOW_NODE:
+ append_node (nodemodel, gsk_shadow_node_get_child (node), priv->nodes->len - 1);
+ break;
+
case GSK_BLEND_NODE:
{
int elt_index = priv->nodes->len - 1;
diff --git a/gtk/inspector/recorder.c b/gtk/inspector/recorder.c
index b87e043b3b..d1b4117556 100644
--- a/gtk/inspector/recorder.c
+++ b/gtk/inspector/recorder.c
@@ -159,6 +159,8 @@ node_type_name (GskRenderNodeType type)
return "Clip";
case GSK_ROUNDED_CLIP_NODE:
return "Rounded Clip";
+ case GSK_SHADOW_NODE:
+ return "Shadow";
case GSK_BLEND_NODE:
return "Blend";
case GSK_CROSS_FADE_NODE: