From 93cbba6c3e034227440edeeae2b0dd75c3be6851 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Mon, 7 Nov 2016 19:10:49 +0100 Subject: [PATCH] gtk: Add gtk_widget_snapshot() It's functionally equivalent to gtk_widget_get_render_node() but uses a GtkSnapshot argument to carry the state. --- gtk/Makefile.am | 5 ++- gtk/gtk.h | 1 + gtk/gtksnapshot.c | 80 ++++++++++++++++++++++++++++++++++++++++ gtk/gtksnapshot.h | 50 +++++++++++++++++++++++++ gtk/gtksnapshotprivate.h | 43 +++++++++++++++++++++ gtk/gtkwidget.c | 44 +++++++++++++--------- gtk/gtkwidgetprivate.h | 3 ++ 7 files changed, 207 insertions(+), 19 deletions(-) create mode 100644 gtk/gtksnapshot.c create mode 100644 gtk/gtksnapshot.h create mode 100644 gtk/gtksnapshotprivate.h diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 34bfab78bb..d11ba0c6d5 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -293,6 +293,7 @@ gtk_public_h_sources = \ gtkstacksidebar.h \ gtksizegroup.h \ gtksizerequest.h \ + gtksnapshot.h \ gtkspinbutton.h \ gtkspinner.h \ gtkstack.h \ @@ -540,6 +541,7 @@ gtk_private_h_sources = \ gtksidebarrowprivate.h \ gtksizegroup-private.h \ gtksizerequestcacheprivate.h \ + gtksnapshotprivate.h \ gtkstyleanimationprivate.h \ gtkstylecascadeprivate.h \ gtkstylecontextprivate.h \ @@ -871,10 +873,11 @@ gtk_base_c_sources = \ gtksizerequest.c \ gtksizerequestcache.c \ gtkshow.c \ - gtkstacksidebar.c \ + gtksnapshot.c \ gtkspinbutton.c \ gtkspinner.c \ gtkstack.c \ + gtkstacksidebar.c \ gtkstackswitcher.c \ gtkstatusbar.c \ gtkstyleanimation.c \ diff --git a/gtk/gtk.h b/gtk/gtk.h index a3f903dfdb..8d13dfd66c 100644 --- a/gtk/gtk.h +++ b/gtk/gtk.h @@ -193,6 +193,7 @@ #include #include #include +#include #include #include #include diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c new file mode 100644 index 0000000000..0dbc3d1b76 --- /dev/null +++ b/gtk/gtksnapshot.c @@ -0,0 +1,80 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 2016 Benjamin Otte + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include "config.h" + +#include "gtksnapshot.h" +#include "gtksnapshotprivate.h" + +void +gtk_snapshot_init (GtkSnapshot *state, + const GtkSnapshot *parent, + const graphene_matrix_t *transform) +{ + state->parent = parent; + state->renderer = parent->renderer; + + graphene_matrix_init_from_matrix (&state->transform, transform); +} + +void +gtk_snapshot_init_root (GtkSnapshot *state, + GskRenderer *renderer) +{ + state->parent = NULL; + state->renderer = renderer; + + graphene_matrix_init_identity (&state->transform); +} + +void +gtk_snapshot_finish (GtkSnapshot *state) +{ + /* nothing to do so far */ +} + +GskRenderer * +gtk_snapshot_get_renderer (const GtkSnapshot *state) +{ + return state->renderer; +} + +GskRenderNode * +gtk_snapshot_create_render_node (const GtkSnapshot *state, + const char *name, + ...) +{ + GskRenderNode *node; + + node = gsk_renderer_create_render_node (state->renderer); + + 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); + } + + return node; +} diff --git a/gtk/gtksnapshot.h b/gtk/gtksnapshot.h new file mode 100644 index 0000000000..2d4e826923 --- /dev/null +++ b/gtk/gtksnapshot.h @@ -0,0 +1,50 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 2016 Benjamin Otte + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +/* + * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __GTK_SNAPSHOT_H__ +#define __GTK_SNAPSHOT_H__ + + +#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +typedef struct _GtkSnapshot GtkSnapshot; + + +GDK_AVAILABLE_IN_3_90 +GskRenderer * gtk_snapshot_get_renderer (const GtkSnapshot *state); + +GDK_AVAILABLE_IN_3_90 +GskRenderNode * gtk_snapshot_create_render_node (const GtkSnapshot *state, + const char *name, + ...) G_GNUC_PRINTF(2, 3); + +G_END_DECLS + +#endif /* __GTK_SNAPSHOT_H__ */ diff --git a/gtk/gtksnapshotprivate.h b/gtk/gtksnapshotprivate.h new file mode 100644 index 0000000000..5b238b74d2 --- /dev/null +++ b/gtk/gtksnapshotprivate.h @@ -0,0 +1,43 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 2016 Benjamin Otte + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#ifndef __GTK_SNAPSHOT_PRIVATE_H__ +#define __GTK_SNAPSHOT_PRIVATE_H__ + +#include "gtksnapshot.h" + +G_BEGIN_DECLS + +struct _GtkSnapshot { + const GtkSnapshot *parent; + + GskRenderer *renderer; + + graphene_matrix_t transform; +}; + +void gtk_snapshot_init (GtkSnapshot *state, + const GtkSnapshot *parent, + const graphene_matrix_t *transform); +void gtk_snapshot_init_root (GtkSnapshot *state, + GskRenderer *renderer); + +void gtk_snapshot_finish (GtkSnapshot *state); + +G_END_DECLS + +#endif /* __GTK_SNAPSHOT_PRIVATE_H__ */ diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index f74104b0e5..f051175d4a 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -67,6 +67,7 @@ #include "gtkapplicationprivate.h" #include "gtkgestureprivate.h" #include "gtkwidgetpathprivate.h" +#include "gtksnapshotprivate.h" #include "inspector/window.h" @@ -15627,6 +15628,22 @@ gtk_widget_create_render_node (GtkWidget *widget, GskRenderNode * gtk_widget_get_render_node (GtkWidget *widget, GskRenderer *renderer) +{ + GtkSnapshot snapshot; + GskRenderNode *node; + + gtk_snapshot_init_root (&snapshot, renderer); + + node = gtk_widget_snapshot (widget, &snapshot); + + gtk_snapshot_finish (&snapshot); + + return node; +} + +GskRenderNode * +gtk_widget_snapshot (GtkWidget *widget, + const GtkSnapshot *snapshot) { GtkWidgetClass *klass = GTK_WIDGET_GET_CLASS (widget); GskRenderNode *node; @@ -15651,27 +15668,21 @@ gtk_widget_get_render_node (GtkWidget *widget, { GskRenderNode *tmp; cairo_t *cr; - char *str; - str = g_strconcat ("Fallback<", G_OBJECT_TYPE_NAME (widget), ">", NULL); - - tmp = gsk_renderer_create_render_node (renderer); - gsk_render_node_set_name (tmp, str); + tmp = gtk_snapshot_create_render_node (snapshot, "Fallback<%s>", G_OBJECT_TYPE_NAME (widget)); gsk_render_node_set_bounds (tmp, &bounds); gsk_render_node_set_transform (tmp, &m); - cr = gsk_render_node_get_draw_context (tmp, renderer); + cr = gsk_render_node_get_draw_context (tmp, gtk_snapshot_get_renderer (snapshot)); cairo_translate (cr, alloc.x - clip.x, alloc.y - clip.y); gtk_widget_draw_internal (widget, cr, TRUE); cairo_destroy (cr); - g_free (str); - node = tmp; } else { - node = klass->get_render_node (widget, renderer); + node = klass->get_render_node (widget, gtk_snapshot_get_renderer (snapshot)); /* Compatibility mode: if there's a ::draw signal handler, we add a * child node with the contents of the handler @@ -15681,21 +15692,15 @@ gtk_widget_get_render_node (GtkWidget *widget, GskRenderNode *tmp; gboolean result; cairo_t *cr; - char *str; - str = g_strconcat ("DrawSignal<", G_OBJECT_TYPE_NAME (widget), ">", NULL); - - tmp = gsk_renderer_create_render_node (renderer); - gsk_render_node_set_name (tmp, str); + tmp = gtk_snapshot_create_render_node (snapshot, "DrawSignal<%s>", G_OBJECT_TYPE_NAME (widget)); gsk_render_node_set_bounds (tmp, &bounds); - cr = gsk_render_node_get_draw_context (tmp, renderer); + cr = gsk_render_node_get_draw_context (tmp, gtk_snapshot_get_renderer (snapshot)); cairo_translate (cr, alloc.x - clip.x, alloc.y - clip.y); g_signal_emit (widget, widget_signals[DRAW], 0, cr, &result); cairo_destroy (cr); - g_free (str); - if (node != NULL) { gsk_render_node_append_child (node, tmp); @@ -15717,6 +15722,7 @@ gtk_widget_render (GtkWidget *widget, const cairo_region_t *region) { GdkDrawingContext *context; + GtkSnapshot snapshot; GskRenderer *renderer; GskRenderNode *root; @@ -15728,7 +15734,9 @@ gtk_widget_render (GtkWidget *widget, if (renderer == NULL) return; - root = gtk_widget_get_render_node (widget, renderer); + gtk_snapshot_init_root (&snapshot, renderer); + root = gtk_widget_snapshot (widget, &snapshot); + gtk_snapshot_finish (&snapshot); if (root == NULL) return; diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h index 816928118d..38c2e0ae4d 100644 --- a/gtk/gtkwidgetprivate.h +++ b/gtk/gtkwidgetprivate.h @@ -31,6 +31,7 @@ #include "gtkeventcontroller.h" #include "gtkactionmuxer.h" #include "gtksizerequestcacheprivate.h" +#include "gtksnapshot.h" G_BEGIN_DECLS @@ -285,6 +286,8 @@ void gtk_widget_render (GtkWidget GskRenderNode * gtk_widget_get_render_node (GtkWidget *widget, GskRenderer *renderer); +GskRenderNode * gtk_widget_snapshot (GtkWidget *widget, + const GtkSnapshot *snapshot); GskRenderNode * gtk_widget_create_render_node (GtkWidget *widget, GskRenderer *renderer,