[gtk+/wip/otte/snapshot: 23/30] snapshot: Convert GtkImage and GtkIconHelper
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/snapshot: 23/30] snapshot: Convert GtkImage and GtkIconHelper
- Date: Tue, 15 Nov 2016 06:33:34 +0000 (UTC)
commit b2f962a84da681af525904623d0d72786d4964bb
Author: Benjamin Otte <otte redhat com>
Date: Tue Nov 15 06:19:16 2016 +0100
snapshot: Convert GtkImage and GtkIconHelper
Adds a bunch of new APIs to render textures with theming.
FIXME: Cannot draw shadows for textures.
gtk/gtkiconhelper.c | 17 +++-----
gtk/gtkiconhelperprivate.h | 4 +-
gtk/gtkimage.c | 96 ++++++++++++++++++++++---------------------
gtk/gtkrendericon.c | 49 ++++++++++++++++++++++
gtk/gtkrendericonprivate.h | 5 ++
gtk/gtksnapshot.c | 52 ++++++++++++++++++++++++
gtk/gtksnapshot.h | 11 +++++
7 files changed, 175 insertions(+), 59 deletions(-)
---
diff --git a/gtk/gtkiconhelper.c b/gtk/gtkiconhelper.c
index 278ace3..5bd099d 100644
--- a/gtk/gtkiconhelper.c
+++ b/gtk/gtkiconhelper.c
@@ -857,27 +857,24 @@ _gtk_icon_helper_draw (GtkIconHelper *self,
}
}
-GskRenderNode *
-gtk_icon_helper_get_render_node (GtkIconHelper *self,
- GskRenderer *renderer)
+void
+gtk_icon_helper_snapshot (GtkIconHelper *self,
+ GtkSnapshot *snapshot)
{
GskTexture *texture;
GskRenderNode *node;
graphene_rect_t bounds;
- gtk_icon_helper_ensure_texture (self, renderer);
+ gtk_icon_helper_ensure_texture (self, gtk_snapshot_get_renderer (snapshot));
texture = self->priv->texture;
if (texture == NULL)
- return NULL;
+ return;
graphene_rect_init (&bounds, 0, 0, gsk_texture_get_width (texture), gsk_texture_get_height (texture));
- node = gsk_renderer_create_render_node (renderer);
- gsk_render_node_set_name (node, "Icon Helper");
- gsk_render_node_set_bounds (node, &bounds);
+ node = gtk_snapshot_append (snapshot, &bounds, "Icon Helper");
gsk_render_node_set_texture (node, texture);
-
- return node;
+ gsk_render_node_unref (node);
}
gboolean
diff --git a/gtk/gtkiconhelperprivate.h b/gtk/gtkiconhelperprivate.h
index 6576e81..0fd3240 100644
--- a/gtk/gtkiconhelperprivate.h
+++ b/gtk/gtkiconhelperprivate.h
@@ -125,8 +125,8 @@ void _gtk_icon_helper_draw (GtkIconHelper *self,
cairo_t *cr,
gdouble x,
gdouble y);
-GskRenderNode * gtk_icon_helper_get_render_node (GtkIconHelper *self,
- GskRenderer *renderer);
+void gtk_icon_helper_snapshot (GtkIconHelper *self,
+ GtkSnapshot *snapshot);
gboolean _gtk_icon_helper_get_force_scale_pixbuf (GtkIconHelper *self);
void _gtk_icon_helper_set_force_scale_pixbuf (GtkIconHelper *self,
diff --git a/gtk/gtkimage.c b/gtk/gtkimage.c
index 8712d81..ffb5f81 100644
--- a/gtk/gtkimage.c
+++ b/gtk/gtkimage.c
@@ -142,8 +142,8 @@ struct _GtkImagePrivate
#define DEFAULT_ICON_SIZE GTK_ICON_SIZE_BUTTON
-static GskRenderNode *gtk_image_get_render_node (GtkWidget *widget,
- GskRenderer *renderer);
+static void gtk_image_snapshot (GtkWidget *widget,
+ GtkSnapshot *snapshot);
static void gtk_image_size_allocate (GtkWidget *widget,
GtkAllocation*allocation);
static void gtk_image_unmap (GtkWidget *widget);
@@ -163,6 +163,13 @@ static void gtk_image_get_content_size (GtkCssGadget *gadget,
gint *minimum_baseline,
gint *natural_baseline,
gpointer unused);
+static gboolean gtk_image_render_contents (GtkCssGadget *gadget,
+ GtkSnapshot *snapshot,
+ int x,
+ int y,
+ int width,
+ int height,
+ gpointer data);
static void gtk_image_style_updated (GtkWidget *widget);
static void gtk_image_finalize (GObject *object);
@@ -211,7 +218,7 @@ gtk_image_class_init (GtkImageClass *class)
gobject_class->finalize = gtk_image_finalize;
widget_class = GTK_WIDGET_CLASS (class);
- widget_class->get_render_node = gtk_image_get_render_node;
+ widget_class->snapshot = gtk_image_snapshot;
widget_class->measure = gtk_image_measure;
widget_class->size_allocate = gtk_image_size_allocate;
widget_class->unmap = gtk_image_unmap;
@@ -367,8 +374,9 @@ gtk_image_init (GtkImage *image)
gtk_image_get_content_size,
NULL,
NULL,
- NULL,
+ gtk_image_render_contents,
NULL, NULL);
+
}
static void
@@ -1403,66 +1411,60 @@ gtk_image_get_content_size (GtkCssGadget *gadget,
}
-static GskRenderNode *
-gtk_image_get_render_node (GtkWidget *widget,
- GskRenderer *renderer)
+static void
+gtk_image_snapshot (GtkWidget *widget,
+ GtkSnapshot *snapshot)
{
- GtkImage *image = GTK_IMAGE (widget);
- GtkImagePrivate *priv = image->priv;
- gint w, h, baseline;
- gint x, y, width, height;
- GskRenderNode *res;
- GskRenderNode *node;
- GtkAllocation alloc, clip;
- cairo_t *cr;
-
- res = gtk_css_gadget_get_render_node (priv->gadget, renderer, FALSE);
-
- if (res == NULL)
- return NULL;
-
- if (gtk_image_get_storage_type (image) == GTK_IMAGE_ANIMATION)
- {
- node = gtk_widget_create_render_node (widget, renderer, "Image Content");
+ gtk_css_gadget_snapshot (GTK_IMAGE (widget)->priv->gadget,
+ snapshot);
+}
- gtk_widget_get_clip (widget, &clip);
- _gtk_widget_get_allocation (widget, &alloc);
+static gboolean
+gtk_image_render_contents (GtkCssGadget *gadget,
+ GtkSnapshot *snapshot,
+ int x,
+ int y,
+ int width,
+ int height,
+ gpointer data)
+{
+ GtkWidget *widget;
+ GtkImage *image;
+ GtkImagePrivate *priv;
+ gint w, h, baseline;
- cr = gsk_render_node_get_draw_context (node, renderer);
- cairo_translate (cr, alloc.x - clip.x, alloc.y - clip.y);
- x = 0;
- y = 0;
- width = alloc.width;
- height = alloc.height;
+ widget = gtk_css_gadget_get_owner (gadget);
+ image = GTK_IMAGE (widget);
+ priv = image->priv;
- _gtk_icon_helper_get_size (priv->icon_helper, &w, &h);
+ _gtk_icon_helper_get_size (priv->icon_helper, &w, &h);
- baseline = gtk_widget_get_allocated_baseline (widget);
+ baseline = gtk_widget_get_allocated_baseline (widget);
- if (baseline == -1)
- y += floor(height - h) / 2;
- else
- y += CLAMP (baseline - h * gtk_image_get_baseline_align (image), 0, height - h);
+ if (baseline == -1)
+ y += floor(height - h) / 2;
+ else
+ y += CLAMP (baseline - h * gtk_image_get_baseline_align (image), 0, height - h);
- x += (width - w) / 2;
+ x += (width - w) / 2;
+ gtk_snapshot_translate_2d (snapshot, x, y);
+ if (gtk_image_get_storage_type (image) == GTK_IMAGE_ANIMATION)
+ {
GtkStyleContext *context = gtk_widget_get_style_context (widget);
GdkPixbuf *pixbuf = get_animation_frame (image);
- gtk_render_icon (context, cr, pixbuf, x, y);
+ gtk_snapshot_render_icon (snapshot, context, pixbuf, x, y);
+
g_object_unref (pixbuf);
-
- cairo_destroy (cr);
}
else
{
- node = gtk_icon_helper_get_render_node (priv->icon_helper, renderer);
+ gtk_icon_helper_snapshot (priv->icon_helper, snapshot);
}
+ gtk_snapshot_translate_2d (snapshot, -x, -y);
- gsk_render_node_append_child (res, node);
- gsk_render_node_unref (node);
-
- return res;
+ return FALSE;
}
static void
diff --git a/gtk/gtkrendericon.c b/gtk/gtkrendericon.c
index b2ca78a..cd43ec9 100644
--- a/gtk/gtkrendericon.c
+++ b/gtk/gtkrendericon.c
@@ -26,6 +26,7 @@
#include "gtkcssshadowsvalueprivate.h"
#include "gtkcssstyleprivate.h"
#include "gtkcsstransformvalueprivate.h"
+#include "gtksnapshotprivate.h"
#include <math.h>
@@ -222,3 +223,51 @@ gtk_css_style_render_icon_get_extents (GtkCssStyle *style,
extents->height += border.top + border.bottom;
}
+void
+gtk_css_style_snapshot_icon (GtkCssStyle *style,
+ GtkSnapshot *snapshot,
+ GskTexture *texture)
+{
+ const GtkCssValue *shadows, *transform;
+ cairo_matrix_t transform_matrix;
+ graphene_matrix_t matrix, other, saved_matrix;
+ graphene_rect_t bounds;
+ GskRenderNode *node;
+ int width, height;
+
+ g_return_if_fail (GTK_IS_CSS_STYLE (style));
+ g_return_if_fail (snapshot != NULL);
+ g_return_if_fail (GSK_IS_TEXTURE (texture));
+
+ shadows = 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);
+ height = gsk_texture_get_height (texture);
+
+ if (!_gtk_css_transform_value_get_matrix (transform, &transform_matrix))
+ return;
+
+ graphene_matrix_init_from_matrix (&saved_matrix, gtk_snapshot_get_transform (snapshot));
+
+ /* XXX: Implement -gtk-icon-transform-origin instead of hardcoding "50% 50%" here */
+ graphene_matrix_init_translate (&matrix, &(graphene_point3d_t)GRAPHENE_POINT3D_INIT(width / 2.0, height /
2.0, 0));
+ graphene_matrix_init_from_2d (&other, transform_matrix.xx, transform_matrix.yx,
+ transform_matrix.xy, transform_matrix.yy,
+ transform_matrix.x0, transform_matrix.y0);
+ graphene_matrix_multiply (&other, &matrix, &matrix);
+ graphene_matrix_init_translate (&other, &(graphene_point3d_t)GRAPHENE_POINT3D_INIT(- width / 2.0, - height
/ 2.0, 0));
+ graphene_matrix_multiply (&matrix, &other, &matrix);
+ gtk_snapshot_transform (snapshot, &matrix);
+
+ graphene_rect_init (&bounds, 0, 0, width, height);
+
+ node = gtk_snapshot_append (snapshot, &bounds, "Icon");
+ if (!_gtk_css_shadows_value_is_none (shadows))
+ {
+ g_warning ("Painting shadows not implemented for textures yet.");
+ }
+ gsk_render_node_set_texture (node, texture);
+ gsk_render_node_unref (node);
+
+ gtk_snapshot_set_transform (snapshot, &saved_matrix);
+}
diff --git a/gtk/gtkrendericonprivate.h b/gtk/gtkrendericonprivate.h
index f627655..83a3b04 100644
--- a/gtk/gtkrendericonprivate.h
+++ b/gtk/gtkrendericonprivate.h
@@ -22,8 +22,10 @@
#include <glib-object.h>
#include <cairo.h>
+#include <gsk/gsk.h>
#include "gtkcsstypesprivate.h"
+#include "gtksnapshot.h"
#include "gtktypes.h"
G_BEGIN_DECLS
@@ -41,6 +43,9 @@ void gtk_css_style_render_icon_surface (GtkCssStyle *style,
cairo_surface_t *surface,
double x,
double y);
+void gtk_css_style_snapshot_icon (GtkCssStyle *style,
+ GtkSnapshot *snapshot,
+ GskTexture *texture);
void gtk_css_style_render_icon_get_extents (GtkCssStyle *style,
GdkRectangle *extents,
diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c
index 62defef..aacb24f 100644
--- a/gtk/gtksnapshot.c
+++ b/gtk/gtksnapshot.c
@@ -24,6 +24,7 @@
#include "gtkcssshadowsvalueprivate.h"
#include "gtkrenderbackgroundprivate.h"
#include "gtkrenderborderprivate.h"
+#include "gtkrendericonprivate.h"
#include "gtkstylecontextprivate.h"
#include "gsk/gskrendernodeprivate.h"
@@ -185,6 +186,39 @@ gtk_snapshot_append_node (GtkSnapshot *state,
}
}
+GskRenderNode *
+gtk_snapshot_append (GtkSnapshot *state,
+ const graphene_rect_t *bounds,
+ const char *name,
+ ...)
+{
+ GskRenderNode *node;
+
+ g_return_val_if_fail (state != NULL, NULL);
+ g_return_val_if_fail (bounds != NULL, NULL);
+
+ 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_append_node (state, node);
+
+ return node;
+}
+
cairo_t *
gtk_snapshot_append_cairo_node (GtkSnapshot *state,
const graphene_rect_t *bounds,
@@ -357,3 +391,21 @@ gtk_snapshot_render_layout (GtkSnapshot *state,
gtk_snapshot_translate_2d (state, -x, -y);
}
+void
+gtk_snapshot_render_icon (GtkSnapshot *snapshot,
+ GtkStyleContext *context,
+ GdkPixbuf *pixbuf,
+ gdouble x,
+ gdouble y)
+{
+ GskTexture *texture;
+
+ texture = gsk_texture_new_for_pixbuf (snapshot->renderer, pixbuf);
+ gtk_snapshot_translate_2d (snapshot, x, y);
+ gtk_css_style_snapshot_icon (gtk_style_context_lookup_style (context),
+ snapshot,
+ texture);
+ gtk_snapshot_translate_2d (snapshot, -x, -y);
+ gsk_texture_unref (texture);
+}
+
diff --git a/gtk/gtksnapshot.h b/gtk/gtksnapshot.h
index 74be2c1..20315b0 100644
--- a/gtk/gtksnapshot.h
+++ b/gtk/gtksnapshot.h
@@ -73,6 +73,11 @@ GDK_AVAILABLE_IN_3_90
void gtk_snapshot_append_node (GtkSnapshot *state,
GskRenderNode *node);
GDK_AVAILABLE_IN_3_90
+GskRenderNode * gtk_snapshot_append (GtkSnapshot *state,
+ const graphene_rect_t *bounds,
+ const char *name,
+ ...) G_GNUC_PRINTF(3, 4);
+GDK_AVAILABLE_IN_3_90
cairo_t * gtk_snapshot_append_cairo_node (GtkSnapshot *state,
const graphene_rect_t *bounds,
const char *name,
@@ -117,6 +122,12 @@ void gtk_snapshot_render_insertion_cursor (GtkSnapshot
PangoLayout *layout,
int index,
PangoDirection direction);
+GDK_AVAILABLE_IN_3_90
+void gtk_snapshot_render_icon (GtkSnapshot *snapshot,
+ GtkStyleContext *context,
+ GdkPixbuf *pixbuf,
+ gdouble x,
+ gdouble y);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]