[gtk+/wip/matthiasc/gsk-renderer: 10/11] Split css background into individual render nodes
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/matthiasc/gsk-renderer: 10/11] Split css background into individual render nodes
- Date: Tue, 16 Aug 2016 16:20:42 +0000 (UTC)
commit e8b8d4f8e15d05cb66075d5ef8441401fcf6597c
Author: Matthias Clasen <mclasen redhat com>
Date: Sat Aug 13 04:17:35 2016 -0400
Split css background into individual render nodes
Use separate render nodes for each layer in a multi-image
background. WARNING: blend modes don't work right yet.
gtk/gtkcssgadget.c | 4 +-
gtk/gtkrenderbackground.c | 121 ++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 114 insertions(+), 11 deletions(-)
---
diff --git a/gtk/gtkcssgadget.c b/gtk/gtkcssgadget.c
index 0b67ede..fbf9e23 100644
--- a/gtk/gtkcssgadget.c
+++ b/gtk/gtkcssgadget.c
@@ -866,18 +866,16 @@ gtk_css_gadget_get_render_node (GtkCssGadget *gadget,
get_box_border (style, &border);
get_box_padding (style, &padding);
- str = g_strconcat ("Background<", G_OBJECT_TYPE_NAME (gtk_css_gadget_get_owner (gadget)), ">", NULL);
gtk_css_style_add_background_render_nodes (style,
renderer,
box_node,
&bounds,
- str,
+ G_OBJECT_TYPE_NAME (gtk_css_gadget_get_owner (gadget)),
clip.left + margin.left,
clip.top + margin.top,
width - clip.left - clip.right - margin.left - margin.right,
height - clip.top - clip.bottom - margin.top - margin.bottom,
gtk_css_node_get_junction_sides (priv->node));
- g_free (str);
str = g_strconcat ("Border<", G_OBJECT_TYPE_NAME (gtk_css_gadget_get_owner (gadget)), ">", NULL);
border_node = gsk_renderer_create_render_node (renderer);
diff --git a/gtk/gtkrenderbackground.c b/gtk/gtkrenderbackground.c
index 1189e4c..6d0daf1 100644
--- a/gtk/gtkrenderbackground.c
+++ b/gtk/gtkrenderbackground.c
@@ -428,6 +428,33 @@ gtk_css_style_render_background (GtkCssStyle *style,
cairo_restore (cr);
}
+static GskBlendMode
+translate_blend_mode (GtkCssBlendMode blend_mode)
+{
+ switch (blend_mode)
+ {
+ case GTK_CSS_BLEND_MODE_COLOR_BURN: return GSK_BLEND_MODE_COLOR_BURN;
+ case GTK_CSS_BLEND_MODE_COLOR_DODGE: return GSK_BLEND_MODE_COLOR_BURN;
+ case GTK_CSS_BLEND_MODE_DARKEN: return GSK_BLEND_MODE_DARKEN;
+ case GTK_CSS_BLEND_MODE_LIGHTEN: return GSK_BLEND_MODE_LIGHTEN;
+ case GTK_CSS_BLEND_MODE_DIFFERENCE: return GSK_BLEND_MODE_DIFFERENCE;
+ case GTK_CSS_BLEND_MODE_EXCLUSION: return GSK_BLEND_MODE_EXCLUSION;
+ case GTK_CSS_BLEND_MODE_HARD_LIGHT: return GSK_BLEND_MODE_HARD_LIGHT;
+ case GTK_CSS_BLEND_MODE_SOFT_LIGHT: return GSK_BLEND_MODE_SOFT_LIGHT;
+ case GTK_CSS_BLEND_MODE_MULTIPLY: return GSK_BLEND_MODE_MULTIPLY;
+ case GTK_CSS_BLEND_MODE_NORMAL: return GSK_BLEND_MODE_DEFAULT;
+ case GTK_CSS_BLEND_MODE_OVERLAY: return GSK_BLEND_MODE_OVERLAY;
+ case GTK_CSS_BLEND_MODE_SCREEN: return GSK_BLEND_MODE_SCREEN;
+ case GTK_CSS_BLEND_MODE_SATURATE:
+ case GTK_CSS_BLEND_MODE_LUMINOSITY:
+ case GTK_CSS_BLEND_MODE_COLOR:
+ case GTK_CSS_BLEND_MODE_HUE:
+ default:
+ g_warning ("CSS blend mode %d not supported by GSK yet", blend_mode);
+ return GSK_BLEND_MODE_DEFAULT;
+ }
+}
+
void
gtk_css_style_add_background_render_nodes (GtkCssStyle *style,
GskRenderer *renderer,
@@ -443,10 +470,16 @@ gtk_css_style_add_background_render_nodes (GtkCssStyle *style,
GskRenderNode *bg_node;
cairo_t *cr;
GtkCssValue *background_image;
+ GtkCssValue *blend_modes;
GtkCssValue *box_shadow;
const GdkRGBA *bg_color;
+ GtkThemingBackground bg;
+ gchar *str;
+ gint number_of_layers;
+ gint idx;
background_image = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BACKGROUND_IMAGE);
+ blend_modes = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BACKGROUND_BLEND_MODE);
bg_color = _gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (style,
GTK_CSS_PROPERTY_BACKGROUND_COLOR));
box_shadow = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BOX_SHADOW);
@@ -457,15 +490,87 @@ gtk_css_style_add_background_render_nodes (GtkCssStyle *style,
_gtk_css_shadows_value_is_none (box_shadow))
return;
- bg_node = gsk_renderer_create_render_node (renderer);
- gsk_render_node_set_name (bg_node, name);
- gsk_render_node_set_bounds (bg_node, bounds);
- cr = gsk_render_node_get_draw_context (bg_node);
- gtk_css_style_render_background (style, cr, x, y, width, height, junction);
- cairo_destroy (cr);
+ bg.style = style;
+ _gtk_theming_background_init_style (&bg, width, height, junction);
+
+ if (!_gtk_css_shadows_value_is_none (box_shadow))
+ {
+ str = g_strconcat ("Outer Shadow<", name, ">", NULL);
+ bg_node = gsk_renderer_create_render_node (renderer);
+ gsk_render_node_set_name (bg_node, str);
+ gsk_render_node_set_bounds (bg_node, bounds);
+ cr = gsk_render_node_get_draw_context (bg_node);
+ cairo_translate (cr, x, y);
+ _gtk_css_shadows_value_paint_box (box_shadow,
+ cr,
+ &bg.boxes[GTK_CSS_AREA_BORDER_BOX],
+ FALSE);
+ cairo_destroy (cr);
+ g_free (str);
+
+ gsk_render_node_append_child (parent_node, bg_node);
+ gsk_render_node_unref (bg_node);
+ }
+
+ if (!gtk_rgba_is_clear (bg_color))
+ {
+ str = g_strconcat ("Background Color<", name, ">", NULL);
+ bg_node = gsk_renderer_create_render_node (renderer);
+ gsk_render_node_set_name (bg_node, str);
+ gsk_render_node_set_bounds (bg_node, bounds);
+ cr = gsk_render_node_get_draw_context (bg_node);
+ cairo_translate (cr, x, y);
+ _gtk_theming_background_paint_color (&bg, cr, bg_color, background_image);
+ cairo_destroy (cr);
+ g_free (str);
+
+ gsk_render_node_append_child (parent_node, bg_node);
+ gsk_render_node_unref (bg_node);
+ }
+
+ number_of_layers = _gtk_css_array_value_get_n_values (background_image);
- gsk_render_node_append_child (parent_node, bg_node);
- gsk_render_node_unref (bg_node);
+ for (idx = number_of_layers - 1; idx >= 0; idx--)
+ {
+ GtkCssBlendMode blend_mode;
+
+ blend_mode = _gtk_css_blend_mode_value_get (_gtk_css_array_value_get_nth (blend_modes, idx));
+
+ str = g_strdup_printf ("Background%d<%s>", idx, name);
+ bg_node = gsk_renderer_create_render_node (renderer);
+
+ gsk_render_node_set_blend_mode (bg_node,
+ translate_blend_mode (blend_mode));
+ gsk_render_node_set_name (bg_node, str);
+ gsk_render_node_set_bounds (bg_node, bounds);
+ cr = gsk_render_node_get_draw_context (bg_node);
+ cairo_translate (cr, x, y);
+ _gtk_theming_background_paint_layer (&bg, idx, cr, GTK_CSS_BLEND_MODE_NORMAL);
+ cairo_destroy (cr);
+ g_free (str);
+
+ gsk_render_node_append_child (parent_node, bg_node);
+ gsk_render_node_unref (bg_node);
+ }
+
+ if (!_gtk_css_shadows_value_is_none (box_shadow))
+ {
+ str = g_strconcat ("Inner Shadow<", name, ">", NULL);
+ bg_node = gsk_renderer_create_render_node (renderer);
+ gsk_render_node_set_name (bg_node, str);
+ gsk_render_node_set_bounds (bg_node, bounds);
+ cr = gsk_render_node_get_draw_context (bg_node);
+ cairo_translate (cr, x, y);
+ _gtk_css_shadows_value_paint_box (box_shadow,
+ cr,
+ &bg.boxes[GTK_CSS_AREA_PADDING_BOX],
+ TRUE);
+ cairo_destroy (cr);
+ g_free (str);
+
+ gsk_render_node_append_child (parent_node, bg_node);
+ gsk_render_node_unref (bg_node);
+ }
}
static gboolean
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]