diff --git a/docs/reference/gsk/gsk4-sections.txt b/docs/reference/gsk/gsk4-sections.txt index 102d08467c..4bbeba513a 100644 --- a/docs/reference/gsk/gsk4-sections.txt +++ b/docs/reference/gsk/gsk4-sections.txt @@ -38,7 +38,6 @@ gsk_texture_node_new gsk_cairo_node_new gsk_cairo_node_get_draw_context gsk_container_node_new -gsk_container_node_append_child gsk_container_node_get_n_children gsk_container_node_get_child gsk_transform_node_new diff --git a/gsk/gskrendernode.h b/gsk/gskrendernode.h index b98bd56ce6..93a100eaf6 100644 --- a/gsk/gskrendernode.h +++ b/gsk/gskrendernode.h @@ -55,15 +55,13 @@ cairo_t * gsk_cairo_node_get_draw_context (GskRenderNode GskRenderer *renderer); GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_container_node_new (void); +GskRenderNode * gsk_container_node_new (GskRenderNode **children, + guint n_children); GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_container_node_append_child (GskRenderNode *node, - GskRenderNode *child); +guint gsk_container_node_get_n_children (GskRenderNode *node); GDK_AVAILABLE_IN_3_90 -guint gsk_container_node_get_n_children (GskRenderNode *node); -GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_container_node_get_child (GskRenderNode *node, - guint idx); +GskRenderNode * gsk_container_node_get_child (GskRenderNode *node, + guint idx); GDK_AVAILABLE_IN_3_90 GskRenderNode * gsk_transform_node_new (GskRenderNode *child, diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c index e719a1d6e9..d23d18ddba 100644 --- a/gsk/gskrendernodeimpl.c +++ b/gsk/gskrendernodeimpl.c @@ -285,15 +285,20 @@ struct _GskContainerNode { GskRenderNode render_node; - GPtrArray *children; + GskRenderNode **children; + guint n_children; }; static void gsk_container_node_finalize (GskRenderNode *node) { GskContainerNode *container = (GskContainerNode *) node; + guint i; - g_ptr_array_unref (container->children); + for (i = 0; i < container->n_children; i++) + gsk_render_node_unref (container->children[i]); + + g_free (container->children); } static void @@ -302,9 +307,9 @@ gsk_container_node_make_immutable (GskRenderNode *node) GskContainerNode *container = (GskContainerNode *) node; guint i; - for (i = 1; i < container->children->len; i++) + for (i = 1; i < container->n_children; i++) { - gsk_render_node_make_immutable (g_ptr_array_index (container->children, i)); + gsk_render_node_make_immutable (container->children[i]); } } @@ -343,55 +348,34 @@ static const GskRenderNodeClass GSK_CONTAINER_NODE_CLASS = { /** * gsk_container_node_new: + * @children: (array length=n_children) (transfer none): The children of the node + * @n_children: Number of children in the @children array * - * Creates a new #GskRenderNode instance for holding multiple different - * render nodes. You can use gsk_container_node_append_child() to add - * nodes to the container. + * Creates a new #GskRenderNode instance for holding the given @children. + * The new node will acquire a reference to each of the children. * * Returns: (transfer full): the new #GskRenderNode * * Since: 3.90 */ GskRenderNode * -gsk_container_node_new (void) +gsk_container_node_new (GskRenderNode **children, + guint n_children) { GskContainerNode *container; + guint i; container = (GskContainerNode *) gsk_render_node_new (&GSK_CONTAINER_NODE_CLASS); - container->children = g_ptr_array_new_with_free_func ((GDestroyNotify) gsk_render_node_unref); + container->children = g_memdup (children, sizeof (GskRenderNode *) * n_children); + container->n_children = n_children; + + for (i = 0; i < container->n_children; i++) + gsk_render_node_ref (container->children[i]); return &container->render_node; } -/** - * gsk_container_node_append_child: - * @node: a container node - * @child: a #GskRenderNode - * - * Appends @child to the list of children of @node. - * - * This function acquires a reference on @child. - * - * Returns: (transfer none): the #GskRenderNode - * - * Since: 3.90 - */ -GskRenderNode * -gsk_container_node_append_child (GskRenderNode *node, - GskRenderNode *child) -{ - GskContainerNode *container = (GskContainerNode *) node; - - g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_CONTAINER_NODE), NULL); - g_return_val_if_fail (GSK_IS_RENDER_NODE (child), node); - g_return_val_if_fail (node->is_mutable, node); - - g_ptr_array_add (container->children, gsk_render_node_ref (child)); - - return node; -} - /** * gsk_container_node_get_n_children: * @node: a container #GskRenderNode @@ -409,7 +393,7 @@ gsk_container_node_get_n_children (GskRenderNode *node) g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_CONTAINER_NODE), 0); - return container->children->len; + return container->n_children; } GskRenderNode * @@ -419,9 +403,9 @@ gsk_container_node_get_child (GskRenderNode *node, GskContainerNode *container = (GskContainerNode *) node; g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_CONTAINER_NODE), NULL); - g_return_val_if_fail (idx < container->children->len, 0); + g_return_val_if_fail (idx < container->n_children, 0); - return g_ptr_array_index (container->children, idx); + return container->children[idx]; } /*** GSK_TRANSFORM_NODE ***/ diff --git a/gtk/gtkrendericon.c b/gtk/gtkrendericon.c index 0304f0d02f..082f87d7d2 100644 --- a/gtk/gtkrendericon.c +++ b/gtk/gtkrendericon.c @@ -126,7 +126,7 @@ gtk_css_style_snapshot_icon (GtkCssStyle *style, else { graphene_matrix_t m1, m2, m3; - GskRenderNode *transform_node, *container_node; + GskRenderNode *transform_node, *icon_node; double offset_x, offset_y; gtk_snapshot_get_offset (snapshot, &offset_x, &offset_y); @@ -136,15 +136,16 @@ gtk_css_style_snapshot_icon (GtkCssStyle *style, graphene_matrix_init_translate (&m2, &GRAPHENE_POINT3D_INIT(- width / 2.0, - height / 2.0, 0)); graphene_matrix_multiply (&m2, &m3, &m1); - container_node = gsk_container_node_new (); - gsk_render_node_set_name (container_node, "CSS Icon Transform Container"); - transform_node = gsk_transform_node_new (container_node, &m1); + gtk_snapshot_push (snapshot, FALSE, "CSS Icon Transform Container"); + gtk_css_image_builtin_snapshot (image, snapshot, width, height, builtin_type); + icon_node = gtk_snapshot_pop (snapshot); + + transform_node = gsk_transform_node_new (icon_node, &m1); gsk_render_node_set_name (transform_node, "CSS Icon Transform"); gtk_snapshot_append_node (snapshot, transform_node); - gtk_snapshot_push_node (snapshot, container_node); - gtk_css_image_builtin_snapshot (image, snapshot, width, height, builtin_type); - gtk_snapshot_pop (snapshot); + gsk_render_node_unref (transform_node); + gsk_render_node_unref (icon_node); } } diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c index 331e9804d3..ff0eda2dd7 100644 --- a/gtk/gtksnapshot.c +++ b/gtk/gtksnapshot.c @@ -50,15 +50,21 @@ static GtkSnapshotState * gtk_snapshot_state_new (GtkSnapshotState *parent, + char *name, cairo_region_t *clip, - GskRenderNode *node) + double translate_x, + double translate_y) { GtkSnapshotState *state; state = g_slice_new0 (GtkSnapshotState); - state->node = node; + state->nodes = g_ptr_array_new_with_free_func ((GDestroyNotify) gsk_render_node_unref); + state->parent = parent; + state->name = name; + state->translate_x = translate_x; + state->translate_y = translate_y; if (clip) state->clip_region = cairo_region_reference (clip); @@ -68,9 +74,13 @@ gtk_snapshot_state_new (GtkSnapshotState *parent, static void gtk_snapshot_state_free (GtkSnapshotState *state) { + g_ptr_array_unref (state->nodes); + if (state->clip_region) cairo_region_destroy (state->clip_region); + g_free (state->name); + g_slice_free (GtkSnapshotState, state); } @@ -81,66 +91,49 @@ gtk_snapshot_init (GtkSnapshot *snapshot, const char *name, ...) { - cairo_rectangle_int_t extents; - - cairo_region_get_extents (clip, &extents); + char *str; snapshot->state = NULL; snapshot->renderer = renderer; - snapshot->root = gsk_container_node_new (); 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 (snapshot->root, str); - - g_free (str); } + else + str = NULL; - snapshot->state = gtk_snapshot_state_new (NULL, (cairo_region_t *) clip, snapshot->root); + snapshot->state = gtk_snapshot_state_new (NULL, + str, + (cairo_region_t *) clip, + 0, 0); } GskRenderNode * gtk_snapshot_finish (GtkSnapshot *snapshot) { - gtk_snapshot_pop (snapshot); + GskRenderNode *result; + + result = gtk_snapshot_pop (snapshot); if (snapshot->state != NULL) { g_warning ("Too many gtk_snapshot_push() calls."); } - return snapshot->root; -} - -/** - * gtk_snapshot_push_node: - * @snapshot: a #GtkSnapshot - * @node: the render node to push - * - * Makes @node the new current render node. You are responsible for adding - * @node to the snapshot. - * - * Since: 3.90 - */ -void -gtk_snapshot_push_node (GtkSnapshot *snapshot, - GskRenderNode *node) -{ - g_return_if_fail (gsk_render_node_get_node_type (node) == GSK_CONTAINER_NODE); - - snapshot->state = gtk_snapshot_state_new (snapshot->state, snapshot->state->clip_region, node); + return result; } /** * gtk_snapshot_push: * @snapshot: a #GtkSnapshot + * @keep_coordinates: If %TRUE, the current offset and clip will be kept. + * Otherwise, the clip will be unset and the offset will be reset to + * (0, 0). * @bounds: the bounds for the new node * @name: (transfer none): a printf() style format string for the name for the new node * @...: arguments to insert into the format string @@ -152,30 +145,38 @@ gtk_snapshot_push_node (GtkSnapshot *snapshot, */ void gtk_snapshot_push (GtkSnapshot *snapshot, + gboolean keep_coordinates, const char *name, ...) { - GskRenderNode *node; - - node = gsk_container_node_new (); + char *str; 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); } + else + str = NULL; - gtk_snapshot_append_node (snapshot, node); - gtk_snapshot_push_node (snapshot, node); - gsk_render_node_unref (node); + if (keep_coordinates) + { + snapshot->state = gtk_snapshot_state_new (snapshot->state, + str, + snapshot->state->clip_region, + snapshot->state->translate_x, + snapshot->state->translate_y); + } + else + { + snapshot->state = gtk_snapshot_state_new (snapshot->state, + str, + NULL, + 0, 0); + } } /** @@ -185,23 +186,45 @@ gtk_snapshot_push (GtkSnapshot *snapshot, * Removes the top element from the stack of render nodes, * making the node underneath the current node again. * + * Returns: (transfer full) (allow none): A #GskRenderNode for + * the contents that were rendered to @snapshot since + * the corresponding gtk_snapshot_push() call + * * Since: 3.90 */ -void +GskRenderNode * gtk_snapshot_pop (GtkSnapshot *snapshot) { GtkSnapshotState *state; + GskRenderNode *node; if (snapshot->state == NULL) { g_warning ("Too many gtk_snapshot_pop() calls."); - return; + return NULL; } state = snapshot->state; snapshot->state = state->parent; + if (state->nodes->len == 0) + { + node = NULL; + } + else if (state->nodes->len == 1) + { + node = gsk_render_node_ref (g_ptr_array_index (state->nodes, 0)); + } + else + { + node = gsk_container_node_new ((GskRenderNode **) state->nodes->pdata, + state->nodes->len); + gsk_render_node_set_name (node, state->name); + } + gtk_snapshot_state_free (state); + + return node; } /** @@ -288,7 +311,7 @@ gtk_snapshot_append_node (GtkSnapshot *snapshot, if (snapshot->state) { - gsk_container_node_append_child (snapshot->state->node, node); + g_ptr_array_add (snapshot->state->nodes, gsk_render_node_ref (node)); } else { diff --git a/gtk/gtksnapshot.h b/gtk/gtksnapshot.h index 6acb5aa50a..2c62533400 100644 --- a/gtk/gtksnapshot.h +++ b/gtk/gtksnapshot.h @@ -41,13 +41,11 @@ GskRenderer * gtk_snapshot_get_renderer (const GtkSnapshot GDK_AVAILABLE_IN_3_90 void gtk_snapshot_push (GtkSnapshot *snapshot, + gboolean keep_coordinates, const char *name, - ...) G_GNUC_PRINTF(2, 3); + ...) G_GNUC_PRINTF (3, 4); GDK_AVAILABLE_IN_3_90 -void gtk_snapshot_push_node (GtkSnapshot *snapshot, - GskRenderNode *node); -GDK_AVAILABLE_IN_3_90 -void gtk_snapshot_pop (GtkSnapshot *snapshot); +GskRenderNode * gtk_snapshot_pop (GtkSnapshot *snapshot) G_GNUC_WARN_UNUSED_RESULT; GDK_AVAILABLE_IN_3_90 void gtk_snapshot_translate_2d (GtkSnapshot *snapshot, diff --git a/gtk/gtksnapshotprivate.h b/gtk/gtksnapshotprivate.h index 54b3a6bbbe..eb8cbacba0 100644 --- a/gtk/gtksnapshotprivate.h +++ b/gtk/gtksnapshotprivate.h @@ -27,7 +27,8 @@ typedef struct _GtkSnapshotState GtkSnapshotState; struct _GtkSnapshotState { GtkSnapshotState *parent; - GskRenderNode *node; + char *name; + GPtrArray *nodes; cairo_region_t *clip_region; double translate_x; @@ -37,7 +38,6 @@ struct _GtkSnapshotState { struct _GtkSnapshot { GtkSnapshotState *state; - GskRenderNode *root; GskRenderer *renderer; };