summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2018-03-10 20:52:06 -0500
committerMatthias Clasen <mclasen@redhat.com>2018-03-11 00:31:44 -0500
commite23f641e491fd85371a613dde7f90fee8924657d (patch)
tree1bcd10f8b5cf083ed47a2c7c0593d8c32a3f9258 /gtk
parent7eb3736760c4b05e89aebbb833b4ca9917f280ce (diff)
downloadgtk+-e23f641e491fd85371a613dde7f90fee8924657d.tar.gz
GtkSnapshot: Implement the builder pattern
Make GtkSnapshot a refcounted boxed type, and add public API that follows the builder pattern described here: https://blogs.gnome.org/otte/2018/02/03/builders/
Diffstat (limited to 'gtk')
-rw-r--r--gtk/gtksnapshot.c115
-rw-r--r--gtk/gtksnapshot.h20
-rw-r--r--gtk/gtksnapshotprivate.h1
3 files changed, 125 insertions, 11 deletions
diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c
index a4f118cca7..7956eba43a 100644
--- a/gtk/gtksnapshot.c
+++ b/gtk/gtksnapshot.c
@@ -50,6 +50,37 @@
* the #GtkWidget::snapshot vfunc.
*/
+G_DEFINE_BOXED_TYPE (GtkSnapshot, gtk_snapshot, gtk_snapshot_ref, gtk_snapshot_unref)
+
+GtkSnapshot *
+gtk_snapshot_ref (GtkSnapshot *snapshot)
+{
+ g_assert (snapshot->ref_count > 0);
+
+ snapshot->ref_count += 1;
+
+ return snapshot;
+}
+
+void
+gtk_snapshot_unref (GtkSnapshot *snapshot)
+{
+ g_assert (snapshot->ref_count > 0);
+
+ snapshot->ref_count -= 1;
+
+ if (snapshot->ref_count > 0)
+ return;
+
+ if (snapshot->state_stack)
+ gsk_render_node_unref (gtk_snapshot_to_node (snapshot));
+
+ g_assert (snapshot->state_stack == NULL);
+ g_assert (snapshot->nodes == NULL);
+
+ g_free (snapshot);
+}
+
static GskRenderNode *
gtk_snapshot_collect_default (GtkSnapshot *snapshot,
GtkSnapshotState *state,
@@ -125,6 +156,26 @@ gtk_snapshot_state_clear (GtkSnapshotState *state)
g_clear_pointer (&state->name, g_free);
}
+static void
+gtk_snapshot_init_internal (GtkSnapshot *snapshot,
+ GskRenderer *renderer,
+ gboolean record_names,
+ const cairo_region_t *clip,
+ char *name)
+{
+ snapshot->record_names = record_names;
+ snapshot->renderer = renderer;
+ snapshot->state_stack = g_array_new (FALSE, TRUE, sizeof (GtkSnapshotState));
+ g_array_set_clear_func (snapshot->state_stack, (GDestroyNotify)gtk_snapshot_state_clear);
+ snapshot->nodes = g_ptr_array_new_with_free_func ((GDestroyNotify)gsk_render_node_unref);
+
+ gtk_snapshot_push_state (snapshot,
+ name,
+ (cairo_region_t *) clip,
+ 0, 0,
+ gtk_snapshot_collect_default);
+}
+
void
gtk_snapshot_init (GtkSnapshot *snapshot,
GskRenderer *renderer,
@@ -135,11 +186,31 @@ gtk_snapshot_init (GtkSnapshot *snapshot,
{
char *str;
- snapshot->record_names = record_names;
- snapshot->renderer = renderer;
- snapshot->state_stack = g_array_new (FALSE, TRUE, sizeof (GtkSnapshotState));
- g_array_set_clear_func (snapshot->state_stack, (GDestroyNotify)gtk_snapshot_state_clear);
- snapshot->nodes = g_ptr_array_new_with_free_func ((GDestroyNotify)gsk_render_node_unref);
+ if (name && record_names)
+ {
+ va_list args;
+
+ va_start (args, name);
+ str = g_strdup_vprintf (name, args);
+ va_end (args);
+ }
+ else
+ str = NULL;
+
+ snapshot->ref_count = 0;
+
+ gtk_snapshot_init_internal (snapshot, renderer, record_names, clip, str);
+}
+
+GtkSnapshot *
+gtk_snapshot_new (GskRenderer *renderer,
+ gboolean record_names,
+ const cairo_region_t *clip,
+ const char *name,
+ ...)
+{
+ GtkSnapshot *snapshot;
+ char *str;
if (name && record_names)
{
@@ -152,11 +223,23 @@ gtk_snapshot_init (GtkSnapshot *snapshot,
else
str = NULL;
- gtk_snapshot_push_state (snapshot,
- str,
- (cairo_region_t *) clip,
- 0, 0,
- gtk_snapshot_collect_default);
+ snapshot = g_new (GtkSnapshot, 1);
+ snapshot->ref_count = 1;
+
+ gtk_snapshot_init_internal (snapshot, renderer, record_names, clip, str);
+
+ return snapshot;
+}
+
+GskRenderNode *
+gtk_snapshot_free_to_node (GtkSnapshot *snapshot)
+{
+ GskRenderNode *result;
+
+ result = gtk_snapshot_to_node (snapshot);
+ gtk_snapshot_unref (snapshot);
+
+ return result;
}
/**
@@ -1068,7 +1151,7 @@ gtk_snapshot_pop_internal (GtkSnapshot *snapshot)
}
GskRenderNode *
-gtk_snapshot_finish (GtkSnapshot *snapshot)
+gtk_snapshot_to_node (GtkSnapshot *snapshot)
{
GskRenderNode *result;
@@ -1089,10 +1172,20 @@ gtk_snapshot_finish (GtkSnapshot *snapshot)
result = gtk_snapshot_pop_internal (snapshot);
g_array_free (snapshot->state_stack, TRUE);
+ snapshot->state_stack = NULL;
+
g_ptr_array_free (snapshot->nodes, TRUE);
+ snapshot->nodes = NULL;
+
return result;
}
+GskRenderNode *
+gtk_snapshot_finish (GtkSnapshot *snapshot)
+{
+ return gtk_snapshot_to_node (snapshot);
+}
+
/**
* gtk_snapshot_pop:
* @snapshot: a #GtkSnapshot
diff --git a/gtk/gtksnapshot.h b/gtk/gtksnapshot.h
index 8a02345f11..67c502dea4 100644
--- a/gtk/gtksnapshot.h
+++ b/gtk/gtksnapshot.h
@@ -36,6 +36,26 @@
G_BEGIN_DECLS
+
+GDK_AVAILABLE_IN_ALL
+GType gtk_snapshot_get_type (void) G_GNUC_CONST;
+GDK_AVAILABLE_IN_ALL
+GtkSnapshot * gtk_snapshot_ref (GtkSnapshot *snapshot);
+GDK_AVAILABLE_IN_ALL
+void gtk_snapshot_unref (GtkSnapshot *snapshot);
+
+GDK_AVAILABLE_IN_ALL
+GtkSnapshot * gtk_snapshot_new (GskRenderer *renderer,
+ gboolean record_names,
+ const cairo_region_t *clip,
+ const char *name,
+ ...) G_GNUC_PRINTF (4, 5);
+GDK_AVAILABLE_IN_ALL
+GskRenderNode * gtk_snapshot_free_to_node (GtkSnapshot *snapshot);
+
+GDK_AVAILABLE_IN_ALL
+GskRenderNode * gtk_snapshot_to_node (GtkSnapshot *snapshot);
+
GDK_AVAILABLE_IN_ALL
void gtk_snapshot_push (GtkSnapshot *snapshot,
gboolean keep_coordinates,
diff --git a/gtk/gtksnapshotprivate.h b/gtk/gtksnapshotprivate.h
index 1319df7d7b..9a8659063c 100644
--- a/gtk/gtksnapshotprivate.h
+++ b/gtk/gtksnapshotprivate.h
@@ -81,6 +81,7 @@ struct _GtkSnapshotState {
};
struct _GtkSnapshot {
+ int ref_count;
gboolean record_names;
GskRenderer *renderer;
GArray *state_stack;