[gtk+/wip/otte/snapshot: 7/15] snapshot: Add gtk_snapshot_render_background()
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/snapshot: 7/15] snapshot: Add gtk_snapshot_render_background()
- Date: Mon, 14 Nov 2016 03:28:59 +0000 (UTC)
commit 93c0dd61de717a4f998253dca94c49618605e246
Author: Benjamin Otte <otte redhat com>
Date: Sun Nov 13 16:16:39 2016 +0100
snapshot: Add gtk_snapshot_render_background()
and gtk_snapshot_render_frame() to be direct replacements for the
old gtk_render_*() functions.
Use them to replace Cairo usage completely in gtk_window_snapshot().
gtk/gtkrenderbackground.c | 43 ++++++++++++++++
gtk/gtkrenderbackgroundprivate.h | 7 ++-
gtk/gtkrenderborder.c | 103 ++++++++++++++++++++++++++++++++++++++
gtk/gtkrenderborderprivate.h | 10 ++++
gtk/gtksnapshot.c | 77 +++++++++++++++++++++++++++-
gtk/gtksnapshot.h | 22 ++++++++
gtk/gtkwindow.c | 74 ++++++++++++---------------
7 files changed, 291 insertions(+), 45 deletions(-)
---
diff --git a/gtk/gtkrenderbackground.c b/gtk/gtkrenderbackground.c
index f3e09e4..2e850ca 100644
--- a/gtk/gtkrenderbackground.c
+++ b/gtk/gtkrenderbackground.c
@@ -593,3 +593,46 @@ gtk_css_style_render_background_is_opaque (GtkCssStyle *style)
&& corner_value_is_right_angle (gtk_css_style_get_value (style,
GTK_CSS_PROPERTY_BORDER_BOTTOM_RIGHT_RADIUS))
&& corner_value_is_right_angle (gtk_css_style_get_value (style,
GTK_CSS_PROPERTY_BORDER_BOTTOM_LEFT_RADIUS));
}
+
+void
+gtk_css_style_snapshot_background (GtkCssStyle *style,
+ GtkSnapshot *snapshot,
+ gdouble width,
+ gdouble height,
+ GtkJunctionSides junction)
+{
+ GtkCssValue *background_image;
+ GtkCssValue *box_shadow;
+ const GdkRGBA *bg_color;
+ GtkBorder shadow;
+ graphene_rect_t bounds;
+ cairo_t *cr;
+
+ background_image = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BACKGROUND_IMAGE);
+ 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);
+
+ /* This is the common default case of no background */
+ if (gtk_rgba_is_clear (bg_color) &&
+ _gtk_css_array_value_get_n_values (background_image) == 1 &&
+ _gtk_css_image_value_get_image (_gtk_css_array_value_get_nth (background_image, 0)) == NULL &&
+ _gtk_css_shadows_value_is_none (box_shadow))
+ return;
+
+ _gtk_css_shadows_value_get_extents (box_shadow, &shadow);
+
+ graphene_rect_init (&bounds,
+ - shadow.left,
+ - shadow.top,
+ ceil (width) + shadow.left + shadow.right,
+ ceil (height) + shadow.top + shadow.bottom);
+
+ cr = gtk_snapshot_append_cairo_node (snapshot,
+ &bounds,
+ "Background");
+
+ gtk_css_style_render_background (style, cr, 0, 0, width, height, junction);
+
+ cairo_destroy (cr);
+}
+
diff --git a/gtk/gtkrenderbackgroundprivate.h b/gtk/gtkrenderbackgroundprivate.h
index a3927f0..cb6ab5b 100644
--- a/gtk/gtkrenderbackgroundprivate.h
+++ b/gtk/gtkrenderbackgroundprivate.h
@@ -24,8 +24,8 @@
#include <cairo.h>
#include "gtkcsstypesprivate.h"
+#include "gtksnapshot.h"
#include "gtktypes.h"
-#include "gsk/gsk.h"
G_BEGIN_DECLS
@@ -47,6 +47,11 @@ void gtk_css_style_add_background_render_nodes (GtkCssStyle
gdouble width,
gdouble height,
GtkJunctionSides junction);
+void gtk_css_style_snapshot_background (GtkCssStyle *style,
+ GtkSnapshot *snapshot,
+ gdouble width,
+ gdouble height,
+ GtkJunctionSides junction);
diff --git a/gtk/gtkrenderborder.c b/gtk/gtkrenderborder.c
index f755f9f..2672dec 100644
--- a/gtk/gtkrenderborder.c
+++ b/gtk/gtkrenderborder.c
@@ -757,6 +757,71 @@ gtk_css_style_render_border (GtkCssStyle *style,
}
}
+void
+gtk_css_style_snapshot_border (GtkCssStyle *style,
+ GtkSnapshot *state,
+ gdouble width,
+ gdouble height,
+ GtkJunctionSides junction)
+{
+ GtkBorderImage border_image;
+ double border_width[4];
+ graphene_rect_t bounds;
+ cairo_t *cr;
+
+ border_width[0] = _gtk_css_number_value_get (gtk_css_style_get_value (style,
GTK_CSS_PROPERTY_BORDER_TOP_WIDTH), 100);
+ border_width[1] = _gtk_css_number_value_get (gtk_css_style_get_value (style,
GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH), 100);
+ border_width[2] = _gtk_css_number_value_get (gtk_css_style_get_value (style,
GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH), 100);
+ border_width[3] = _gtk_css_number_value_get (gtk_css_style_get_value (style,
GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH), 100);
+
+ graphene_rect_init (&bounds, 0, 0, width, height);
+
+ if (gtk_border_image_init (&border_image, style))
+ {
+ cr = gtk_snapshot_append_cairo_node (state,
+ &bounds,
+ "Border Image");
+ gtk_border_image_render (&border_image, border_width, cr, 0, 0, width, height);
+ cairo_destroy (cr);
+ }
+ else
+ {
+ GtkBorderStyle border_style[4];
+ GtkRoundedBox border_box;
+ GdkRGBA colors[4];
+
+ /* Optimize the most common case of "This widget has no border" */
+ if (border_width[0] == 0 &&
+ border_width[1] == 0 &&
+ border_width[2] == 0 &&
+ border_width[3] == 0)
+ return;
+
+ cr = gtk_snapshot_append_cairo_node (state,
+ &bounds,
+ "Border");
+
+ border_style[0] = _gtk_css_border_style_value_get (gtk_css_style_get_value (style,
GTK_CSS_PROPERTY_BORDER_TOP_STYLE));
+ border_style[1] = _gtk_css_border_style_value_get (gtk_css_style_get_value (style,
GTK_CSS_PROPERTY_BORDER_RIGHT_STYLE));
+ border_style[2] = _gtk_css_border_style_value_get (gtk_css_style_get_value (style,
GTK_CSS_PROPERTY_BORDER_BOTTOM_STYLE));
+ border_style[3] = _gtk_css_border_style_value_get (gtk_css_style_get_value (style,
GTK_CSS_PROPERTY_BORDER_LEFT_STYLE));
+
+ hide_border_sides (border_width, border_style, 0);
+
+ colors[0] = *_gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (style,
GTK_CSS_PROPERTY_BORDER_TOP_COLOR));
+ colors[1] = *_gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (style,
GTK_CSS_PROPERTY_BORDER_RIGHT_COLOR));
+ colors[2] = *_gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (style,
GTK_CSS_PROPERTY_BORDER_BOTTOM_COLOR));
+ colors[3] = *_gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (style,
GTK_CSS_PROPERTY_BORDER_LEFT_COLOR));
+
+ _gtk_rounded_box_init_rect (&border_box, 0, 0, width, height);
+ _gtk_rounded_box_apply_border_radius_for_style (&border_box, style, junction);
+
+ render_border (cr, &border_box, border_width, 0, colors, border_style);
+
+ cairo_destroy (cr);
+ }
+}
+
gboolean
gtk_css_style_render_border_get_clip (GtkCssStyle *style,
gdouble x,
@@ -854,6 +919,44 @@ gtk_css_style_render_outline (GtkCssStyle *style,
}
}
+void
+gtk_css_style_snapshot_outline (GtkCssStyle *style,
+ GtkSnapshot *state,
+ gdouble width,
+ gdouble height)
+{
+ GtkBorderStyle border_style[4];
+ GtkRoundedBox border_box;
+ double border_width[4];
+ GdkRGBA colors[4];
+
+ border_style[0] = _gtk_css_border_style_value_get (gtk_css_style_get_value (style,
GTK_CSS_PROPERTY_OUTLINE_STYLE));
+ if (border_style[0] != GTK_BORDER_STYLE_NONE)
+ {
+ cairo_rectangle_t rect;
+ cairo_t *cr;
+
+ compute_outline_rect (style, 0, 0, width, height, &rect);
+
+ border_style[1] = border_style[2] = border_style[3] = border_style[0];
+ border_width[0] = _gtk_css_number_value_get (gtk_css_style_get_value (style,
GTK_CSS_PROPERTY_OUTLINE_WIDTH), 100);
+ border_width[3] = border_width[2] = border_width[1] = border_width[0];
+ colors[0] = *_gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (style,
GTK_CSS_PROPERTY_OUTLINE_COLOR));
+ colors[3] = colors[2] = colors[1] = colors[0];
+
+ _gtk_rounded_box_init_rect (&border_box, rect.x, rect.y, rect.width, rect.height);
+ _gtk_rounded_box_apply_outline_radius_for_style (&border_box, style, GTK_JUNCTION_NONE);
+
+ cr = gtk_snapshot_append_cairo_node (state,
+ &(graphene_rect_t) GRAPHENE_RECT_INIT (rect.x, rect.y,
rect.width, rect.height),
+ "Outline");
+
+ render_border (cr, &border_box, border_width, 0, colors, border_style);
+
+ cairo_destroy (cr);
+ }
+}
+
gboolean
gtk_css_style_render_outline_get_clip (GtkCssStyle *style,
gdouble x,
diff --git a/gtk/gtkrenderborderprivate.h b/gtk/gtkrenderborderprivate.h
index b72010e..e05a664 100644
--- a/gtk/gtkrenderborderprivate.h
+++ b/gtk/gtkrenderborderprivate.h
@@ -25,6 +25,7 @@
#include "gtkborder.h"
#include "gtkcssimageprivate.h"
#include "gtkcssvalueprivate.h"
+#include "gtksnapshot.h"
G_BEGIN_DECLS
@@ -43,6 +44,11 @@ gboolean gtk_css_style_render_border_get_clip (GtkCssStyle
gdouble width,
gdouble height,
GdkRectangle *out_clip)
G_GNUC_WARN_UNUSED_RESULT;
+void gtk_css_style_snapshot_border (GtkCssStyle *style,
+ GtkSnapshot *state,
+ gdouble width,
+ gdouble height,
+ GtkJunctionSides junction);
gboolean gtk_css_style_render_has_outline (GtkCssStyle *style);
void gtk_css_style_render_outline (GtkCssStyle *style,
@@ -51,6 +57,10 @@ void gtk_css_style_render_outline (GtkCssStyle
gdouble y,
gdouble width,
gdouble height);
+void gtk_css_style_snapshot_outline (GtkCssStyle *style,
+ GtkSnapshot *state,
+ gdouble width,
+ gdouble height);
gboolean gtk_css_style_render_outline_get_clip (GtkCssStyle *style,
gdouble x,
gdouble y,
diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c
index c638243..2a0507a 100644
--- a/gtk/gtksnapshot.c
+++ b/gtk/gtksnapshot.c
@@ -20,6 +20,10 @@
#include "gtksnapshot.h"
#include "gtksnapshotprivate.h"
+#include "gtkrenderbackgroundprivate.h"
+#include "gtkrenderborderprivate.h"
+#include "gtkstylecontextprivate.h"
+
#include "gsk/gskrendernodeprivate.h"
void
@@ -45,8 +49,8 @@ gtk_snapshot_finish (GtkSnapshot *state)
}
void
-gtk_snapshot_push (GtkSnapshot *state,
- GskRenderNode *node)
+gtk_snapshot_push_node (GtkSnapshot *state,
+ GskRenderNode *node)
{
gtk_snapshot_append_node (state, node);
@@ -55,6 +59,35 @@ gtk_snapshot_push (GtkSnapshot *state,
}
void
+gtk_snapshot_push (GtkSnapshot *state,
+ const graphene_rect_t *bounds,
+ const char *name,
+ ...)
+{
+ GskRenderNode *node;
+
+ node = gsk_renderer_create_render_node (state->renderer);
+ gsk_render_node_set_bounds (node, bounds);
+
+ if (name)
+ {
+ va_list args;
+ char *str;
+
+ va_start (args, name);
+ str = g_strdup_vprintf (name, args);
+ va_end (args);
+
+ gsk_render_node_set_name (node, str);
+
+ g_free (str);
+ }
+
+ gtk_snapshot_push_node (state, node);
+ gsk_render_node_unref (node);
+}
+
+void
gtk_snapshot_pop (GtkSnapshot *state)
{
if (state->node == NULL)
@@ -212,8 +245,46 @@ gtk_snapshot_push_cairo_node (GtkSnapshot *state,
g_free (str);
}
- gtk_snapshot_push (state, node);
+ gtk_snapshot_push_node (state, node);
gsk_render_node_unref (node);
return gsk_render_node_get_draw_context (node, state->renderer);
}
+
+void
+gtk_snapshot_render_background (GtkSnapshot *state,
+ GtkStyleContext *context,
+ gdouble x,
+ gdouble y,
+ gdouble width,
+ gdouble height)
+{
+ g_return_if_fail (state != NULL);
+ g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
+
+ gtk_snapshot_translate_2d (state, x, y);
+ gtk_css_style_snapshot_background (gtk_style_context_lookup_style (context),
+ state,
+ width, height,
+ gtk_style_context_get_junction_sides (context));
+ gtk_snapshot_translate_2d (state, -x, -y);
+}
+
+void
+gtk_snapshot_render_frame (GtkSnapshot *state,
+ GtkStyleContext *context,
+ gdouble x,
+ gdouble y,
+ gdouble width,
+ gdouble height)
+{
+ g_return_if_fail (state != NULL);
+ g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
+
+ gtk_snapshot_translate_2d (state, x, y);
+ gtk_css_style_snapshot_border (gtk_style_context_lookup_style (context),
+ state,
+ width, height,
+ gtk_style_context_get_junction_sides (context));
+ gtk_snapshot_translate_2d (state, -x, -y);
+}
diff --git a/gtk/gtksnapshot.h b/gtk/gtksnapshot.h
index b5a4b38..90ecef0 100644
--- a/gtk/gtksnapshot.h
+++ b/gtk/gtksnapshot.h
@@ -32,6 +32,8 @@
#include <gsk/gsk.h>
+#include <gtk/gtktypes.h>
+
G_BEGIN_DECLS
typedef struct _GtkSnapshot GtkSnapshot;
@@ -42,6 +44,11 @@ GskRenderer * gtk_snapshot_get_renderer (const GtkSnapshot
GDK_AVAILABLE_IN_3_90
void gtk_snapshot_push (GtkSnapshot *state,
+ const graphene_rect_t *bounds,
+ const char *name,
+ ...) G_GNUC_PRINTF(3, 4);
+GDK_AVAILABLE_IN_3_90
+void gtk_snapshot_push_node (GtkSnapshot *state,
GskRenderNode *node);
GDK_AVAILABLE_IN_3_90
cairo_t * gtk_snapshot_push_cairo_node (GtkSnapshot *state,
@@ -71,6 +78,21 @@ cairo_t * gtk_snapshot_append_cairo_node (GtkSnapshot
const char *name,
...) G_GNUC_PRINTF(3, 4);
+GDK_AVAILABLE_IN_3_90
+void gtk_snapshot_render_background (GtkSnapshot *state,
+ GtkStyleContext *context,
+ gdouble x,
+ gdouble y,
+ gdouble width,
+ gdouble height);
+GDK_AVAILABLE_IN_3_90
+void gtk_snapshot_render_frame (GtkSnapshot *state,
+ GtkStyleContext *context,
+ gdouble x,
+ gdouble y,
+ gdouble width,
+ gdouble height);
+
G_END_DECLS
#endif /* __GTK_SNAPSHOT_H__ */
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 19136e8..9854f2e 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -9379,9 +9379,6 @@ gtk_window_snapshot (GtkWidget *widget,
GtkBorder window_border;
gint title_height;
graphene_rect_t bounds;
- graphene_matrix_t m;
- graphene_point3d_t p;
- cairo_t *cr;
GList *l;
context = gtk_widget_get_style_context (widget);
@@ -9390,11 +9387,8 @@ gtk_window_snapshot (GtkWidget *widget,
_gtk_widget_get_allocation (widget, &allocation);
graphene_rect_init (&bounds, allocation.x, allocation.y, allocation.width, allocation.height);
- graphene_matrix_init_translate (&m, graphene_point3d_init (&p, allocation.x, allocation.y, 0.));
- cr = gtk_snapshot_push_cairo_node (snapshot,
- &bounds,
- "Window Decoration");
+ gtk_snapshot_push (snapshot, &bounds, "Window Decoration");
if (priv->client_decorated &&
priv->decorated &&
@@ -9411,28 +9405,28 @@ gtk_window_snapshot (GtkWidget *widget,
gtk_style_context_get_border (context, &border);
sum_borders (&border, &padding);
- gtk_render_background (context, cr,
- window_border.left - border.left, window_border.top - border.top,
- allocation.width -
- (window_border.left + window_border.right - border.left - border.right),
- allocation.height -
- (window_border.top + window_border.bottom - border.top - border.bottom));
- gtk_render_frame (context, cr,
- window_border.left - border.left, window_border.top - border.top,
- allocation.width -
- (window_border.left + window_border.right - border.left - border.right),
- allocation.height -
- (window_border.top + window_border.bottom - border.top - border.bottom));
+ gtk_snapshot_render_background (snapshot, context,
+ window_border.left - border.left, window_border.top - border.top,
+ allocation.width -
+ (window_border.left + window_border.right - border.left -
border.right),
+ allocation.height -
+ (window_border.top + window_border.bottom - border.top -
border.bottom));
+ gtk_snapshot_render_frame (snapshot, context,
+ window_border.left - border.left, window_border.top - border.top,
+ allocation.width -
+ (window_border.left + window_border.right - border.left -
border.right),
+ allocation.height -
+ (window_border.top + window_border.bottom - border.top -
border.bottom));
}
else
{
- gtk_render_background (context, cr, 0, 0,
- allocation.width,
- allocation.height);
+ gtk_snapshot_render_background (snapshot, context, 0, 0,
+ allocation.width,
+ allocation.height);
- gtk_render_frame (context, cr, 0, 0,
- allocation.width,
- allocation.height);
+ gtk_snapshot_render_frame (snapshot, context, 0, 0,
+ allocation.width,
+ allocation.height);
}
gtk_style_context_restore (context);
}
@@ -9444,22 +9438,20 @@ gtk_window_snapshot (GtkWidget *widget,
else
title_height = 0;
- gtk_render_background (context, cr,
- window_border.left,
- window_border.top + title_height,
- allocation.width -
- (window_border.left + window_border.right),
- allocation.height -
- (window_border.top + window_border.bottom + title_height));
- gtk_render_frame (context, cr,
- window_border.left,
- window_border.top + title_height,
- allocation.width -
- (window_border.left + window_border.right),
- allocation.height -
- (window_border.top + window_border.bottom + title_height));
-
- cairo_destroy (cr);
+ gtk_snapshot_render_background (snapshot, context,
+ window_border.left,
+ window_border.top + title_height,
+ allocation.width -
+ (window_border.left + window_border.right),
+ allocation.height -
+ (window_border.top + window_border.bottom + title_height));
+ gtk_snapshot_render_frame (snapshot, context,
+ window_border.left,
+ window_border.top + title_height,
+ allocation.width -
+ (window_border.left + window_border.right),
+ allocation.height -
+ (window_border.top + window_border.bottom + title_height));
if (priv->title_box != NULL)
gtk_container_snapshot_child (GTK_CONTAINER (widget), priv->title_box, snapshot);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]