forked from AuroraMiddleware/gtk
snapshot: Work on pushing and popping again
It is now possible to call push() subfunctions for simple container nodes with just a single child. So you can for example gtk_snapshot_push_clip() a clip region that all the nodes that get appended later will then obey. gtk_snapshot_pop() will then not return a container node, but a clip node containing the container node (and similar for the transform example). This is implemented internally by providing a "collect function" when pushing that is called when popping to collects all the accumulated nodes and combine them into the single node that gets returned. To simplify things even more, gtk_snapshot_pop_and_append() has been added, which pops the currently pushed node and appends it to the parent. The icon rendering code has been converted to this approach.
This commit is contained in:
parent
1f988d8b05
commit
1137483d15
@ -4455,7 +4455,10 @@ gtk_volume_button_get_type
|
||||
GtkSnapshot
|
||||
gtk_snapshot_push
|
||||
gtk_snapshot_push_node
|
||||
gtk_snapshot_push_transform
|
||||
gtk_snapshot_push_clip
|
||||
gtk_snapshot_pop
|
||||
gtk_snapshot_pop_and_append
|
||||
gtk_snapshot_set_transform
|
||||
gtk_snapshot_transform
|
||||
gtk_snapshot_translate_2d
|
||||
|
@ -126,26 +126,18 @@ gtk_css_style_snapshot_icon (GtkCssStyle *style,
|
||||
else
|
||||
{
|
||||
graphene_matrix_t m1, m2, m3;
|
||||
GskRenderNode *transform_node, *icon_node;
|
||||
double offset_x, offset_y;
|
||||
|
||||
gtk_snapshot_get_offset (snapshot, &offset_x, &offset_y);
|
||||
/* XXX: Implement -gtk-icon-transform-origin instead of hardcoding "50% 50%" here */
|
||||
graphene_matrix_init_translate (&m1, &GRAPHENE_POINT3D_INIT(offset_x + width / 2.0, offset_y + height / 2.0, 0));
|
||||
graphene_matrix_init_translate (&m1, &GRAPHENE_POINT3D_INIT (width / 2.0, height / 2.0, 0));
|
||||
graphene_matrix_multiply (&transform_matrix, &m1, &m3);
|
||||
graphene_matrix_init_translate (&m2, &GRAPHENE_POINT3D_INIT(- width / 2.0, - height / 2.0, 0));
|
||||
graphene_matrix_init_translate (&m2, &GRAPHENE_POINT3D_INIT (- width / 2.0, - height / 2.0, 0));
|
||||
graphene_matrix_multiply (&m2, &m3, &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);
|
||||
gtk_snapshot_push_transform (snapshot, &m1, "CSS Icon Transform Container");
|
||||
|
||||
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);
|
||||
|
||||
gsk_render_node_unref (transform_node);
|
||||
gsk_render_node_unref (icon_node);
|
||||
gtk_css_image_builtin_snapshot (image, snapshot, width, height, builtin_type);
|
||||
|
||||
gtk_snapshot_pop_and_append (snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
@ -272,7 +264,6 @@ gtk_css_style_snapshot_icon_texture (GtkCssStyle *style,
|
||||
const GtkCssValue *shadows, *transform;
|
||||
graphene_matrix_t transform_matrix;
|
||||
graphene_rect_t bounds;
|
||||
GskRenderNode *icon_node, *transform_node;
|
||||
double width, height;
|
||||
static gboolean shadow_warning;
|
||||
|
||||
@ -306,24 +297,18 @@ gtk_css_style_snapshot_icon_texture (GtkCssStyle *style,
|
||||
else
|
||||
{
|
||||
graphene_matrix_t translate, matrix;
|
||||
double offset_x, offset_y;
|
||||
|
||||
gtk_snapshot_get_offset (snapshot, &offset_x, &offset_y);
|
||||
/* XXX: Implement -gtk-icon-transform-origin instead of hardcoding "50% 50%" here */
|
||||
graphene_matrix_init_translate (&translate, &GRAPHENE_POINT3D_INIT(offset_x + width / 2.0, offset_y + height / 2.0, 0));
|
||||
graphene_matrix_init_translate (&translate, &GRAPHENE_POINT3D_INIT (width / 2.0, height / 2.0, 0));
|
||||
graphene_matrix_multiply (&transform_matrix, &translate, &matrix);
|
||||
graphene_matrix_translate (&matrix, &GRAPHENE_POINT3D_INIT(- width / 2.0, - height / 2.0, 0));
|
||||
graphene_matrix_scale (&matrix, 1.0 / texture_scale, 1.0 / texture_scale, 1);
|
||||
|
||||
gtk_snapshot_push_transform (snapshot, &matrix, "Icon Transform");
|
||||
|
||||
graphene_rect_init (&bounds, 0, 0, gsk_texture_get_width (texture), gsk_texture_get_height (texture));
|
||||
icon_node = gsk_texture_node_new (texture, &bounds);
|
||||
gsk_render_node_set_name (icon_node, "Icon");
|
||||
gtk_snapshot_append_texture_node (snapshot, texture, &bounds, "Icon");
|
||||
|
||||
transform_node = gsk_transform_node_new (icon_node, &matrix);
|
||||
gsk_render_node_set_name (transform_node, "Icon Transform");
|
||||
gtk_snapshot_append_node (snapshot, transform_node);
|
||||
|
||||
gsk_render_node_unref (icon_node);
|
||||
gsk_render_node_unref (transform_node);
|
||||
gtk_snapshot_pop_and_append (snapshot);
|
||||
}
|
||||
}
|
||||
|
@ -48,12 +48,39 @@
|
||||
* the #GtkWidget::snapshot vfunc.
|
||||
*/
|
||||
|
||||
static GskRenderNode *
|
||||
gtk_snapshot_collect_default (GskRenderNode **nodes,
|
||||
guint n_nodes,
|
||||
const char *name,
|
||||
gpointer unused)
|
||||
{
|
||||
GskRenderNode *node;
|
||||
|
||||
if (n_nodes == 0)
|
||||
{
|
||||
node = NULL;
|
||||
}
|
||||
else if (n_nodes == 1)
|
||||
{
|
||||
node = gsk_render_node_ref (nodes[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
node = gsk_container_node_new (nodes, n_nodes);
|
||||
gsk_render_node_set_name (node, name);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static GtkSnapshotState *
|
||||
gtk_snapshot_state_new (GtkSnapshotState *parent,
|
||||
char *name,
|
||||
cairo_region_t *clip,
|
||||
double translate_x,
|
||||
double translate_y)
|
||||
gtk_snapshot_state_new (GtkSnapshotState *parent,
|
||||
char *name,
|
||||
cairo_region_t *clip,
|
||||
double translate_x,
|
||||
double translate_y,
|
||||
GtkSnapshotCollectFunc collect_func,
|
||||
gpointer collect_data)
|
||||
{
|
||||
GtkSnapshotState *state;
|
||||
|
||||
@ -63,10 +90,12 @@ gtk_snapshot_state_new (GtkSnapshotState *parent,
|
||||
|
||||
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);
|
||||
state->translate_x = translate_x;
|
||||
state->translate_y = translate_y;
|
||||
state->collect_func = collect_func;
|
||||
state->collect_data = collect_data;
|
||||
|
||||
return state;
|
||||
}
|
||||
@ -110,7 +139,9 @@ gtk_snapshot_init (GtkSnapshot *snapshot,
|
||||
snapshot->state = gtk_snapshot_state_new (NULL,
|
||||
str,
|
||||
(cairo_region_t *) clip,
|
||||
0, 0);
|
||||
0, 0,
|
||||
gtk_snapshot_collect_default,
|
||||
NULL);
|
||||
}
|
||||
|
||||
GskRenderNode *
|
||||
@ -168,17 +199,159 @@ gtk_snapshot_push (GtkSnapshot *snapshot,
|
||||
str,
|
||||
snapshot->state->clip_region,
|
||||
snapshot->state->translate_x,
|
||||
snapshot->state->translate_y);
|
||||
snapshot->state->translate_y,
|
||||
gtk_snapshot_collect_default,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
snapshot->state = gtk_snapshot_state_new (snapshot->state,
|
||||
str,
|
||||
NULL,
|
||||
0, 0);
|
||||
0, 0,
|
||||
gtk_snapshot_collect_default,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
gtk_snapshot_collect_transform (GskRenderNode **nodes,
|
||||
guint n_nodes,
|
||||
const char *name,
|
||||
gpointer transform)
|
||||
{
|
||||
GskRenderNode *node, *transform_node;
|
||||
|
||||
node = gtk_snapshot_collect_default (nodes, n_nodes, name, NULL);
|
||||
if (node == NULL)
|
||||
return NULL;
|
||||
|
||||
transform_node = gsk_transform_node_new (node, transform);
|
||||
gsk_render_node_set_name (transform_node, name);
|
||||
|
||||
gsk_render_node_unref (node);
|
||||
g_slice_free (graphene_matrix_t, transform);
|
||||
|
||||
return transform_node;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_snapshot_push_transform (GtkSnapshot *snapshot,
|
||||
const graphene_matrix_t *transform,
|
||||
const char *name,
|
||||
...)
|
||||
{
|
||||
graphene_matrix_t offset;
|
||||
graphene_matrix_t* real_transform;
|
||||
|
||||
graphene_matrix_init_translate (&offset,
|
||||
&GRAPHENE_POINT3D_INIT(
|
||||
snapshot->state->translate_x,
|
||||
snapshot->state->translate_y,
|
||||
0
|
||||
));
|
||||
|
||||
real_transform = g_slice_new (graphene_matrix_t);
|
||||
graphene_matrix_multiply (transform, &offset, real_transform);
|
||||
|
||||
char *str;
|
||||
|
||||
if (name)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start (args, name);
|
||||
str = g_strdup_vprintf (name, args);
|
||||
va_end (args);
|
||||
}
|
||||
else
|
||||
str = NULL;
|
||||
|
||||
snapshot->state = gtk_snapshot_state_new (snapshot->state,
|
||||
str,
|
||||
NULL,
|
||||
0, 0,
|
||||
gtk_snapshot_collect_transform,
|
||||
real_transform);
|
||||
}
|
||||
|
||||
static void
|
||||
rectangle_init_from_graphene (cairo_rectangle_int_t *cairo,
|
||||
const graphene_rect_t *graphene)
|
||||
{
|
||||
cairo->x = floorf (graphene->origin.x);
|
||||
cairo->y = floorf (graphene->origin.y);
|
||||
cairo->width = ceilf (graphene->origin.x + graphene->size.width) - cairo->x;
|
||||
cairo->height = ceilf (graphene->origin.y + graphene->size.height) - cairo->y;
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
gtk_snapshot_collect_clip (GskRenderNode **nodes,
|
||||
guint n_nodes,
|
||||
const char *name,
|
||||
gpointer bounds)
|
||||
{
|
||||
GskRenderNode *node, *clip_node;
|
||||
|
||||
node = gtk_snapshot_collect_default (nodes, n_nodes, name, NULL);
|
||||
if (node == NULL)
|
||||
return NULL;
|
||||
|
||||
clip_node = gsk_clip_node_new (node, bounds);
|
||||
gsk_render_node_set_name (clip_node, name);
|
||||
|
||||
gsk_render_node_unref (node);
|
||||
g_slice_free (graphene_rect_t, bounds);
|
||||
|
||||
return clip_node;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_snapshot_push_clip (GtkSnapshot *snapshot,
|
||||
const graphene_rect_t *bounds,
|
||||
const char *name,
|
||||
...)
|
||||
{
|
||||
graphene_rect_t *real_bounds;
|
||||
cairo_region_t *clip;
|
||||
cairo_rectangle_int_t rect;
|
||||
char *str;
|
||||
|
||||
real_bounds = g_slice_new (graphene_rect_t);
|
||||
graphene_rect_offset_r (bounds, snapshot->state->translate_x, snapshot->state->translate_y, real_bounds);
|
||||
|
||||
if (name)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start (args, name);
|
||||
str = g_strdup_vprintf (name, args);
|
||||
va_end (args);
|
||||
}
|
||||
else
|
||||
str = NULL;
|
||||
|
||||
rectangle_init_from_graphene (&rect, real_bounds);
|
||||
if (snapshot->state->clip_region)
|
||||
{
|
||||
clip = cairo_region_copy (snapshot->state->clip_region);
|
||||
cairo_region_intersect_rectangle (clip, &rect);
|
||||
}
|
||||
else
|
||||
{
|
||||
clip = cairo_region_create_rectangle (&rect);
|
||||
}
|
||||
snapshot->state = gtk_snapshot_state_new (snapshot->state,
|
||||
str,
|
||||
clip,
|
||||
snapshot->state->translate_x,
|
||||
snapshot->state->translate_y,
|
||||
gtk_snapshot_collect_clip,
|
||||
real_bounds);
|
||||
|
||||
cairo_region_destroy (clip);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_snapshot_pop:
|
||||
* @snapshot: a #GtkSnapshot
|
||||
@ -207,26 +380,35 @@ gtk_snapshot_pop (GtkSnapshot *snapshot)
|
||||
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);
|
||||
}
|
||||
node = state->collect_func ((GskRenderNode **) state->nodes->pdata,
|
||||
state->nodes->len,
|
||||
state->name,
|
||||
state->collect_data);
|
||||
|
||||
gtk_snapshot_state_free (state);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_snapshot_pop_and_append:
|
||||
* @snapshot: a #GtkSnapshot
|
||||
*
|
||||
* Removes the top element from the stack of render nodes,
|
||||
* and appends it to the node underneath it.
|
||||
*
|
||||
* Since: 3.90
|
||||
*/
|
||||
void
|
||||
gtk_snapshot_pop_and_append (GtkSnapshot *snapshot)
|
||||
{
|
||||
GskRenderNode *node;
|
||||
|
||||
node = gtk_snapshot_pop (snapshot);
|
||||
gtk_snapshot_append_node (snapshot, node);
|
||||
gsk_render_node_unref (node);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_snapshot_get_renderer:
|
||||
* @snapshot: a #GtkSnapshot
|
||||
@ -468,16 +650,6 @@ gtk_snapshot_append_color_node (GtkSnapshot *snapshot,
|
||||
gsk_render_node_unref (node);
|
||||
}
|
||||
|
||||
static void
|
||||
rectangle_init_from_graphene (cairo_rectangle_int_t *cairo,
|
||||
const graphene_rect_t *graphene)
|
||||
{
|
||||
cairo->x = floorf (graphene->origin.x);
|
||||
cairo->y = floorf (graphene->origin.y);
|
||||
cairo->width = ceilf (graphene->origin.x + graphene->size.width) - cairo->x;
|
||||
cairo->height = ceilf (graphene->origin.y + graphene->size.height) - cairo->y;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_snapshot_clips_rect:
|
||||
* @snapshot: a #GtkSnapshot
|
||||
|
@ -42,7 +42,19 @@ void gtk_snapshot_push (GtkSnapshot
|
||||
const char *name,
|
||||
...) G_GNUC_PRINTF (3, 4);
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
void gtk_snapshot_push_transform (GtkSnapshot *snapshot,
|
||||
const graphene_matrix_t*transform,
|
||||
const char *name,
|
||||
...) G_GNUC_PRINTF (3, 4);
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
void gtk_snapshot_push_clip (GtkSnapshot *snapshot,
|
||||
const graphene_rect_t *bounds,
|
||||
const char *name,
|
||||
...) G_GNUC_PRINTF (3, 4);
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
GskRenderNode * gtk_snapshot_pop (GtkSnapshot *snapshot) G_GNUC_WARN_UNUSED_RESULT;
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
void gtk_snapshot_pop_and_append (GtkSnapshot *snapshot);
|
||||
|
||||
GDK_AVAILABLE_IN_3_90
|
||||
void gtk_snapshot_translate_2d (GtkSnapshot *snapshot,
|
||||
|
@ -24,6 +24,11 @@ G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GtkSnapshotState GtkSnapshotState;
|
||||
|
||||
typedef GskRenderNode * (* GtkSnapshotCollectFunc) (GskRenderNode **nodes,
|
||||
guint n_nodes,
|
||||
const char *name,
|
||||
gpointer user_data);
|
||||
|
||||
struct _GtkSnapshotState {
|
||||
GtkSnapshotState *parent;
|
||||
|
||||
@ -33,6 +38,9 @@ struct _GtkSnapshotState {
|
||||
cairo_region_t *clip_region;
|
||||
double translate_x;
|
||||
double translate_y;
|
||||
|
||||
GtkSnapshotCollectFunc collect_func;
|
||||
gpointer collect_data;
|
||||
};
|
||||
|
||||
struct _GtkSnapshot {
|
||||
|
Loading…
Reference in New Issue
Block a user