forked from AuroraMiddleware/gtk
snapshot: Introduce transform APIs
Instead of gtk_snapshot_offset(), provide a full set of functions kept in sync with GtkTransform APIs. On top of that, add gtk_snapshot_save() and gtk_snapshot_restore() mirroring cairo_save()/restore() that allow saving a snapshot's transform state.
This commit is contained in:
parent
2bdc0748e5
commit
51fac44ba5
@ -4402,6 +4402,16 @@ gtk_snapshot_push_rounded_clip
|
||||
gtk_snapshot_push_cross_fade
|
||||
gtk_snapshot_push_blend
|
||||
gtk_snapshot_pop
|
||||
gtk_snapshot_save
|
||||
gtk_snapshot_restore
|
||||
gtk_snapshot_transform
|
||||
gtk_snapshot_transform_matrix
|
||||
gtk_snapshot_translate
|
||||
gtk_snapshot_translate_3d
|
||||
gtk_snapshot_rotate
|
||||
gtk_snapshot_rotate_3d
|
||||
gtk_snapshot_scale
|
||||
gtk_snapshot_scale_3d
|
||||
gtk_snapshot_offset
|
||||
gtk_snapshot_append_node
|
||||
gtk_snapshot_append_cairo
|
||||
|
@ -275,8 +275,7 @@ gtk_snapshot_autopush_transform (GtkSnapshot *snapshot)
|
||||
static gboolean
|
||||
gtk_snapshot_state_should_autopop (const GtkSnapshotState *state)
|
||||
{
|
||||
return state->collect_func == NULL ||
|
||||
state->collect_func == gtk_snapshot_collect_autopush_transform;
|
||||
return state->collect_func == gtk_snapshot_collect_autopush_transform;
|
||||
}
|
||||
|
||||
static GskRenderNode *
|
||||
@ -1033,11 +1032,16 @@ gtk_snapshot_pop_internal (GtkSnapshot *snapshot)
|
||||
{
|
||||
GtkSnapshotState *state;
|
||||
GskRenderNode *node;
|
||||
guint forgotten_restores = 0;
|
||||
|
||||
for (state = gtk_snapshot_get_current_state (snapshot);
|
||||
gtk_snapshot_state_should_autopop (state);
|
||||
gtk_snapshot_state_should_autopop (state) ||
|
||||
state->collect_func == NULL;
|
||||
state = gtk_snapshot_get_current_state (snapshot))
|
||||
{
|
||||
if (state->collect_func == NULL)
|
||||
forgotten_restores++;
|
||||
|
||||
node = gtk_snapshot_pop_one (snapshot);
|
||||
if (node)
|
||||
{
|
||||
@ -1046,6 +1050,11 @@ gtk_snapshot_pop_internal (GtkSnapshot *snapshot)
|
||||
}
|
||||
}
|
||||
|
||||
if (forgotten_restores)
|
||||
{
|
||||
g_warning ("Too many gtk_snapshot_save() calls. %u saves remaining.", forgotten_restores);
|
||||
}
|
||||
|
||||
return gtk_snapshot_pop_one (snapshot);
|
||||
}
|
||||
|
||||
@ -1149,6 +1158,251 @@ gtk_snapshot_pop (GtkSnapshot *snapshot)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_snapshot_save:
|
||||
* @snapshot: a #GtkSnapshot
|
||||
*
|
||||
* Makes a copy of the current state of @snapshot and saves it
|
||||
* on an internal stack of saved states for @snapshot. When
|
||||
* gtk_snapshot_restore() is called, @snapshot will be restored to
|
||||
* the saved state. Multiple calls to gtk_snapshot_save() and
|
||||
* gtk_snapshot_restore() can be nested; each call to
|
||||
* gtk_snapshot_restore() restores the state from the matching paired
|
||||
* gtk_snapshot_save().
|
||||
*
|
||||
* It is necessary to clear all saved states with corresponding calls
|
||||
* to gtk_snapshot_restore().
|
||||
**/
|
||||
void
|
||||
gtk_snapshot_save (GtkSnapshot *snapshot)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_SNAPSHOT (snapshot));
|
||||
|
||||
gtk_snapshot_push_state (snapshot,
|
||||
gtk_snapshot_get_current_state (snapshot)->transform,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_snapshot_restore:
|
||||
* @snapshot: a #GtkSnapshot
|
||||
*
|
||||
* Restores @snapshot to the state saved by a preceding call to
|
||||
* gtk_snapshot_save() and removes that state from the stack of
|
||||
* saved states.
|
||||
**/
|
||||
void
|
||||
gtk_snapshot_restore (GtkSnapshot *snapshot)
|
||||
{
|
||||
GtkSnapshotState *state;
|
||||
GskRenderNode *node;
|
||||
|
||||
for (state = gtk_snapshot_get_current_state (snapshot);
|
||||
gtk_snapshot_state_should_autopop (state);
|
||||
state = gtk_snapshot_get_current_state (snapshot))
|
||||
{
|
||||
node = gtk_snapshot_pop_one (snapshot);
|
||||
if (node)
|
||||
{
|
||||
gtk_snapshot_append_node_internal (snapshot, node);
|
||||
gsk_render_node_unref (node);
|
||||
}
|
||||
}
|
||||
|
||||
if (state->collect_func != NULL)
|
||||
{
|
||||
g_warning ("Too many gtk_snapshot_restore() calls.");
|
||||
return;
|
||||
}
|
||||
|
||||
node = gtk_snapshot_pop_one (snapshot);
|
||||
g_assert (node == NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_snapshot_transform:
|
||||
* @snapshot: a #GtkSnapshot
|
||||
* @tranform: (allow-none): the transform to apply
|
||||
*
|
||||
* Transforms @snapshot's coordinate system with the given @transform.
|
||||
**/
|
||||
void
|
||||
gtk_snapshot_transform (GtkSnapshot *snapshot,
|
||||
GtkTransform *transform)
|
||||
{
|
||||
GtkSnapshotState *state;
|
||||
|
||||
g_return_if_fail (GTK_IS_SNAPSHOT (snapshot));
|
||||
|
||||
state = gtk_snapshot_get_current_state (snapshot);
|
||||
state->transform = gtk_transform_transform (state->transform, transform);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_snapshot_transform_matrix:
|
||||
* @snapshot: a #GtkSnapshot
|
||||
* @matrix: the matrix to multiply the transform with
|
||||
*
|
||||
* Transforms @snapshot's coordinate system with the given @matrix.
|
||||
**/
|
||||
void
|
||||
gtk_snapshot_transform_matrix (GtkSnapshot *snapshot,
|
||||
const graphene_matrix_t *matrix)
|
||||
{
|
||||
GtkSnapshotState *state;
|
||||
|
||||
g_return_if_fail (GTK_IS_SNAPSHOT (snapshot));
|
||||
g_return_if_fail (matrix != NULL);
|
||||
|
||||
state = gtk_snapshot_get_current_state (snapshot);
|
||||
state->transform = gtk_transform_matrix (state->transform, matrix);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_snapshot_transform_matrix_with_category (GtkSnapshot *snapshot,
|
||||
const graphene_matrix_t *matrix,
|
||||
GskMatrixCategory category)
|
||||
{
|
||||
GtkSnapshotState *state;
|
||||
|
||||
g_return_if_fail (GTK_IS_SNAPSHOT (snapshot));
|
||||
g_return_if_fail (matrix != NULL);
|
||||
|
||||
state = gtk_snapshot_get_current_state (snapshot);
|
||||
state->transform = gtk_transform_matrix_with_category (state->transform, matrix, category);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_snapshot_transform_translate:
|
||||
* @snapshot: a #GtkSnapshot
|
||||
* @point: the point to translate the snapshot by
|
||||
*
|
||||
* Translates @snapshot's coordinate system by @point in 2-dimensional space.
|
||||
*/
|
||||
void
|
||||
gtk_snapshot_translate (GtkSnapshot *snapshot,
|
||||
const graphene_point_t *point)
|
||||
{
|
||||
GtkSnapshotState *state;
|
||||
|
||||
g_return_if_fail (GTK_IS_SNAPSHOT (snapshot));
|
||||
g_return_if_fail (point != NULL);
|
||||
|
||||
state = gtk_snapshot_get_current_state (snapshot);
|
||||
state->transform = gtk_transform_translate (state->transform, point);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_snapshot_transform_translate_3d:
|
||||
* @snapshot: a #GtkSnapshot
|
||||
* @point: the point to translate the snapshot by
|
||||
*
|
||||
* Translates @snapshot's coordinate system by @point.
|
||||
*/
|
||||
void
|
||||
gtk_snapshot_translate_3d (GtkSnapshot *snapshot,
|
||||
const graphene_point3d_t *point)
|
||||
{
|
||||
GtkSnapshotState *state;
|
||||
|
||||
g_return_if_fail (GTK_IS_SNAPSHOT (snapshot));
|
||||
g_return_if_fail (point != NULL);
|
||||
|
||||
state = gtk_snapshot_get_current_state (snapshot);
|
||||
state->transform = gtk_transform_translate_3d (state->transform, point);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_snapshot_transform_rotate:
|
||||
* @snapshot: a #GtkSnapshot
|
||||
* @angle: the rotation angle, in degrees (clockwise)
|
||||
*
|
||||
* Rotates @@snapshot's coordinate system by @angle degrees in 2D space -
|
||||
* or in 3D speak, rotates around the z axis.
|
||||
*/
|
||||
void
|
||||
gtk_snapshot_rotate (GtkSnapshot *snapshot,
|
||||
float angle)
|
||||
{
|
||||
GtkSnapshotState *state;
|
||||
|
||||
g_return_if_fail (GTK_IS_SNAPSHOT (snapshot));
|
||||
|
||||
state = gtk_snapshot_get_current_state (snapshot);
|
||||
state->transform = gtk_transform_rotate (state->transform, angle);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_snapshot_transform_rotate_3d:
|
||||
* @snapshot: a #GtkSnapshot
|
||||
* @angle: the rotation angle, in degrees (clockwise)
|
||||
* @axis: The rotation axis
|
||||
*
|
||||
* Rotates @snapshot's coordinate system by @angle degrees around @axis.
|
||||
*
|
||||
* For a rotation in 2D space, use gtk_transform_rotate().
|
||||
*/
|
||||
void
|
||||
gtk_snapshot_rotate_3d (GtkSnapshot *snapshot,
|
||||
float angle,
|
||||
const graphene_vec3_t *axis)
|
||||
{
|
||||
GtkSnapshotState *state;
|
||||
|
||||
g_return_if_fail (GTK_IS_SNAPSHOT (snapshot));
|
||||
g_return_if_fail (axis != NULL);
|
||||
|
||||
state = gtk_snapshot_get_current_state (snapshot);
|
||||
state->transform = gtk_transform_rotate_3d (state->transform, angle, axis);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_snapshot_scale:
|
||||
* @snapshot: a #GtkSnapshot
|
||||
* @factor_x: scaling factor on the X axis
|
||||
* @factor_y: scaling factor on the Y axis
|
||||
*
|
||||
* Scales @@snapshot's coordinate system in 2-dimensional space by
|
||||
* the given factors.
|
||||
*
|
||||
* Use gtk_snapshot_scale_3d() to scale in all 3 dimensions.
|
||||
**/
|
||||
void
|
||||
gtk_snapshot_scale (GtkSnapshot *snapshot,
|
||||
float factor_x,
|
||||
float factor_y)
|
||||
{
|
||||
GtkSnapshotState *state;
|
||||
|
||||
g_return_if_fail (GTK_IS_SNAPSHOT (snapshot));
|
||||
|
||||
state = gtk_snapshot_get_current_state (snapshot);
|
||||
state->transform = gtk_transform_scale (state->transform, factor_x, factor_y);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_snapshot_scale_3d:
|
||||
* @snapshot: a #GtkSnapshot
|
||||
* @factor_x: scaling factor on the X axis
|
||||
* @factor_y: scaling factor on the Y axis
|
||||
* @factor_z: scaling factor on the Z axis
|
||||
*
|
||||
* Scales @@snapshot's coordinate system by the given factors.
|
||||
*/
|
||||
void
|
||||
gtk_snapshot_scale_3d (GtkSnapshot *snapshot,
|
||||
float factor_x,
|
||||
float factor_y,
|
||||
float factor_z)
|
||||
{
|
||||
GtkSnapshotState *state;
|
||||
|
||||
g_return_if_fail (GTK_IS_SNAPSHOT (snapshot));
|
||||
|
||||
state = gtk_snapshot_get_current_state (snapshot);
|
||||
state->transform = gtk_transform_scale_3d (state->transform, factor_x, factor_y, factor_z);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_snapshot_offset:
|
||||
* @snapshot: a #GtkSnapshot
|
||||
|
@ -104,6 +104,38 @@ void gtk_snapshot_push_cross_fade (GtkSnapshot
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_snapshot_pop (GtkSnapshot *snapshot);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_snapshot_save (GtkSnapshot *snapshot);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_snapshot_restore (GtkSnapshot *snapshot);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_snapshot_transform (GtkSnapshot *snapshot,
|
||||
GtkTransform *transform);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_snapshot_transform_matrix (GtkSnapshot *snapshot,
|
||||
const graphene_matrix_t*matrix);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_snapshot_translate (GtkSnapshot *snapshot,
|
||||
const graphene_point_t *point);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_snapshot_translate_3d (GtkSnapshot *snapshot,
|
||||
const graphene_point3d_t*point);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_snapshot_rotate (GtkSnapshot *snapshot,
|
||||
float angle);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_snapshot_rotate_3d (GtkSnapshot *snapshot,
|
||||
float angle,
|
||||
const graphene_vec3_t *axis);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_snapshot_scale (GtkSnapshot *snapshot,
|
||||
float factor_x,
|
||||
float factor_y);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_snapshot_scale_3d (GtkSnapshot *snapshot,
|
||||
float factor_x,
|
||||
float factor_y,
|
||||
float factor_z);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_snapshot_offset (GtkSnapshot *snapshot,
|
||||
int x,
|
||||
|
@ -108,6 +108,10 @@ GtkSnapshot * gtk_snapshot_new_with_parent (GtkSnapshot
|
||||
void gtk_snapshot_push_transform_with_category (GtkSnapshot *snapshot,
|
||||
const graphene_matrix_t*transform,
|
||||
GskMatrixCategory category);
|
||||
void gtk_snapshot_transform_matrix_with_category
|
||||
(GtkSnapshot *snapshot,
|
||||
const graphene_matrix_t*matrix,
|
||||
GskMatrixCategory category);
|
||||
void gtk_snapshot_append_text (GtkSnapshot *snapshot,
|
||||
PangoFont *font,
|
||||
PangoGlyphString *glyphs,
|
||||
|
Loading…
Reference in New Issue
Block a user