mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-25 21:21:21 +00:00
snapshot: Change how gtk_snapshot_push/pop works
Instead of appending a container node and adding the nodes to it as they come in, we now collect the nodes until gtk_snapshot_pop() is called and then hand them out in a container node. The caller of gtk_snapshot_push() is then responsible for doing whatever he wants with the created node. Another addigion is the keep_coordinates flag to gtk_snapshot_push() which allows callers to keep the current offset and clip region or discard it. Discarding is useful when doing transforms, keeping it is useful when inserting effect nodes (like the ones I'm about to add).
This commit is contained in:
parent
ca80e9decf
commit
02131d590e
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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 ***/
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user