[gtk+] render: Propagate snapshot drawing to box shadows
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] render: Propagate snapshot drawing to box shadows
- Date: Sat, 19 Nov 2016 20:01:39 +0000 (UTC)
commit 38f226b5cef1660c7a7f465528befbd65ab944a5
Author: Benjamin Otte <otte redhat com>
Date: Sat Nov 19 20:38:22 2016 +0100
render: Propagate snapshot drawing to box shadows
This decouples actual background drawing from shadow drawing in the
snapshot case.
We also now create seperate nodes for shadows vs for backgrounds.
gtk/gtkcssshadowsvalue.c | 36 +++++++++++++++++++++++++
gtk/gtkcssshadowsvalueprivate.h | 6 ++++
gtk/gtkcssshadowvalue.c | 53 ++++++++++++++++++++++++++++++++++++
gtk/gtkcssshadowvalueprivate.h | 8 +++++-
gtk/gtkrenderbackground.c | 56 +++++++++++++++++++++++++++------------
5 files changed, 141 insertions(+), 18 deletions(-)
---
diff --git a/gtk/gtkcssshadowsvalue.c b/gtk/gtkcssshadowsvalue.c
index e2be207..1838155 100644
--- a/gtk/gtkcssshadowsvalue.c
+++ b/gtk/gtkcssshadowsvalue.c
@@ -316,6 +316,42 @@ _gtk_css_shadows_value_paint_box (const GtkCssValue *shadows,
}
void
+gtk_css_shadows_value_snapshot_outset (const GtkCssValue *shadows,
+ GtkSnapshot *snapshot,
+ const GtkRoundedBox *border_box)
+{
+ guint i;
+
+ g_return_if_fail (shadows->class == >K_CSS_VALUE_SHADOWS);
+
+ for (i = 0; i < shadows->len; i++)
+ {
+ if (_gtk_css_shadow_value_get_inset (shadows->values[i]))
+ continue;
+
+ gtk_css_shadow_value_snapshot_outset (shadows->values[i], snapshot, border_box);
+ }
+}
+
+void
+gtk_css_shadows_value_snapshot_inset (const GtkCssValue *shadows,
+ GtkSnapshot *snapshot,
+ const GtkRoundedBox *padding_box)
+{
+ guint i;
+
+ g_return_if_fail (shadows->class == >K_CSS_VALUE_SHADOWS);
+
+ for (i = 0; i < shadows->len; i++)
+ {
+ if (!_gtk_css_shadow_value_get_inset (shadows->values[i]))
+ continue;
+
+ gtk_css_shadow_value_snapshot_inset (shadows->values[i], snapshot, padding_box);
+ }
+}
+
+void
_gtk_css_shadows_value_get_extents (const GtkCssValue *shadows,
GtkBorder *border)
{
diff --git a/gtk/gtkcssshadowsvalueprivate.h b/gtk/gtkcssshadowsvalueprivate.h
index 790e8ec..5909740 100644
--- a/gtk/gtkcssshadowsvalueprivate.h
+++ b/gtk/gtkcssshadowsvalueprivate.h
@@ -47,6 +47,12 @@ void _gtk_css_shadows_value_paint_box (const GtkCssValue
cairo_t *cr,
const GtkRoundedBox *padding_box,
gboolean inset);
+void gtk_css_shadows_value_snapshot_outset (const GtkCssValue *shadows,
+ GtkSnapshot *snapshot,
+ const GtkRoundedBox *border_box);
+void gtk_css_shadows_value_snapshot_inset (const GtkCssValue *shadows,
+ GtkSnapshot *snapshot,
+ const GtkRoundedBox *padding_box);
void _gtk_css_shadows_value_get_extents (const GtkCssValue *shadows,
GtkBorder *border);
diff --git a/gtk/gtkcssshadowvalue.c b/gtk/gtkcssshadowvalue.c
index a17b213..3c7aeb9 100644
--- a/gtk/gtkcssshadowvalue.c
+++ b/gtk/gtkcssshadowvalue.c
@@ -25,6 +25,7 @@
#include "gtkcsscolorvalueprivate.h"
#include "gtkcssnumbervalueprivate.h"
#include "gtkcssrgbavalueprivate.h"
+#include "gtksnapshot.h"
#include "gtkstylecontextprivate.h"
#include "gtkrenderprivate.h"
#include "gtkpango.h"
@@ -1019,3 +1020,55 @@ _gtk_css_shadow_value_paint_box (const GtkCssValue *shadow,
cairo_restore (cr);
}
+
+void
+gtk_css_shadow_value_snapshot_outset (const GtkCssValue *shadow,
+ GtkSnapshot *snapshot,
+ const GtkRoundedBox *border_box)
+{
+ GtkBorder extents;
+ cairo_t *cr;
+
+ g_return_if_fail (shadow->class == >K_CSS_VALUE_SHADOW);
+
+ /* We don't need to draw invisible shadows */
+ if (gtk_rgba_is_clear (_gtk_css_rgba_value_get_rgba (shadow->color)))
+ return;
+
+ gtk_css_shadow_value_get_extents (shadow, &extents);
+
+ cr = gtk_snapshot_append_cairo_node (snapshot,
+ &(graphene_rect_t) GRAPHENE_RECT_INIT (
+ border_box->box.x - extents.left,
+ border_box->box.y - extents.top,
+ border_box->box.width + extents.left + extents.right,
+ border_box->box.height + extents.top + extents.bottom),
+ "Outset Shadow");
+ _gtk_css_shadow_value_paint_box (shadow, cr, border_box);
+ cairo_destroy (cr);
+}
+
+void
+gtk_css_shadow_value_snapshot_inset (const GtkCssValue *shadow,
+ GtkSnapshot *snapshot,
+ const GtkRoundedBox *padding_box)
+{
+ cairo_t *cr;
+
+ g_return_if_fail (shadow->class == >K_CSS_VALUE_SHADOW);
+
+ /* We don't need to draw invisible shadows */
+ if (gtk_rgba_is_clear (_gtk_css_rgba_value_get_rgba (shadow->color)))
+ return;
+
+ cr = gtk_snapshot_append_cairo_node (snapshot,
+ &(graphene_rect_t) GRAPHENE_RECT_INIT (
+ padding_box->box.x,
+ padding_box->box.y,
+ padding_box->box.width,
+ padding_box->box.height),
+ "Inset Shadow");
+ _gtk_css_shadow_value_paint_box (shadow, cr, padding_box);
+ cairo_destroy (cr);
+}
+
diff --git a/gtk/gtkcssshadowvalueprivate.h b/gtk/gtkcssshadowvalueprivate.h
index 5b89944..7f8c86b 100644
--- a/gtk/gtkcssshadowvalueprivate.h
+++ b/gtk/gtkcssshadowvalueprivate.h
@@ -46,11 +46,17 @@ void _gtk_css_shadow_value_paint_layout (const GtkCssValue
void _gtk_css_shadow_value_paint_icon (const GtkCssValue *shadow,
cairo_t *cr);
-
void _gtk_css_shadow_value_paint_box (const GtkCssValue *shadow,
cairo_t *cr,
const GtkRoundedBox *padding_box);
+void gtk_css_shadow_value_snapshot_outset (const GtkCssValue *shadow,
+ GtkSnapshot *snapshot,
+ const GtkRoundedBox *border_box);
+void gtk_css_shadow_value_snapshot_inset (const GtkCssValue *shadow,
+ GtkSnapshot *snapshot,
+ const GtkRoundedBox *padding_box);
+
G_END_DECLS
#endif /* __GTK_SHADOW_H__ */
diff --git a/gtk/gtkrenderbackground.c b/gtk/gtkrenderbackground.c
index c0a7d75..7def6b0 100644
--- a/gtk/gtkrenderbackground.c
+++ b/gtk/gtkrenderbackground.c
@@ -302,13 +302,16 @@ _gtk_theming_background_paint_layer (GtkThemingBackground *bg,
}
static void
-_gtk_theming_background_init_style (GtkThemingBackground *bg,
- double width,
- double height,
- GtkJunctionSides junction)
+gtk_theming_background_init (GtkThemingBackground *bg,
+ GtkCssStyle *style,
+ double width,
+ double height,
+ GtkJunctionSides junction)
{
GtkBorder border, padding;
+ bg->style = style;
+
border.top = _gtk_css_number_value_get (gtk_css_style_get_value (bg->style,
GTK_CSS_PROPERTY_BORDER_TOP_WIDTH), 100);
border.right = _gtk_css_number_value_get (gtk_css_style_get_value (bg->style,
GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH), 100);
border.bottom = _gtk_css_number_value_get (gtk_css_style_get_value (bg->style,
GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH), 100);
@@ -370,8 +373,7 @@ gtk_css_style_render_background (GtkCssStyle *style,
_gtk_css_shadows_value_is_none (box_shadow))
return;
- bg.style = style;
- _gtk_theming_background_init_style (&bg, width, height, junction);
+ gtk_theming_background_init (&bg, style, width, height, junction);
cairo_save (cr);
cairo_translate (cr, x, y);
@@ -435,14 +437,17 @@ gtk_css_style_snapshot_background (GtkCssStyle *style,
gdouble height,
GtkJunctionSides junction)
{
+ GtkThemingBackground bg;
+ gint idx;
GtkCssValue *background_image;
+ GtkCssValue *blend_modes;
GtkCssValue *box_shadow;
const GdkRGBA *bg_color;
- GtkBorder shadow;
- graphene_rect_t bounds;
+ gint number_of_layers;
cairo_t *cr;
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);
@@ -453,20 +458,37 @@ gtk_css_style_snapshot_background (GtkCssStyle *style,
_gtk_css_shadows_value_is_none (box_shadow))
return;
- _gtk_css_shadows_value_get_extents (box_shadow, &shadow);
+ gtk_theming_background_init (&bg, style, width, height, junction);
- graphene_rect_init (&bounds,
- - shadow.left,
- - shadow.top,
- ceil (width) + shadow.left + shadow.right,
- ceil (height) + shadow.top + shadow.bottom);
+ gtk_css_shadows_value_snapshot_outset (box_shadow,
+ 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.
+ */
cr = gtk_snapshot_append_cairo_node (snapshot,
- &bounds,
- "Background");
+ &(graphene_rect_t)GRAPHENE_RECT_INIT(0, 0, width, height),
+ "Background with blend mode");
- gtk_css_style_render_background (style, cr, 0, 0, width, height, junction);
+ _gtk_theming_background_paint_color (&bg, cr, 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--)
+ {
+ GtkCssBlendMode blend_mode;
+
+ blend_mode = _gtk_css_blend_mode_value_get (_gtk_css_array_value_get_nth (blend_modes, idx));
+
+ _gtk_theming_background_paint_layer (&bg, idx, cr, blend_mode);
+ }
cairo_destroy (cr);
+
+ gtk_css_shadows_value_snapshot_inset (box_shadow,
+ snapshot,
+ &bg.boxes[GTK_CSS_AREA_PADDING_BOX]);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]