mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2025-12-21 00:30:11 +01:00
gstate: Set an error status when restoring a push_group
cairo_push_group (cr) followed by cairo_restore (cr) should put cr in an error status of CAIRO_STATUS_INVALID_RESTORE. Fixes group-state.
This commit is contained in:
parent
e0b741de90
commit
5d95ae924e
3 changed files with 30 additions and 15 deletions
|
|
@ -87,6 +87,9 @@ _cairo_gstate_save (cairo_gstate_t **gstate, cairo_gstate_t **freelist);
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_gstate_restore (cairo_gstate_t **gstate, cairo_gstate_t **freelist);
|
_cairo_gstate_restore (cairo_gstate_t **gstate, cairo_gstate_t **freelist);
|
||||||
|
|
||||||
|
cairo_private cairo_bool_t
|
||||||
|
_cairo_gstate_is_group (cairo_gstate_t *gstate);
|
||||||
|
|
||||||
cairo_private cairo_bool_t
|
cairo_private cairo_bool_t
|
||||||
_cairo_gstate_is_redirected (cairo_gstate_t *gstate);
|
_cairo_gstate_is_redirected (cairo_gstate_t *gstate);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -341,6 +341,22 @@ _cairo_gstate_redirect_target (cairo_gstate_t *gstate, cairo_surface_t *child)
|
||||||
&matrix);
|
&matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _cairo_gstate_is_group
|
||||||
|
* @gstate: a #cairo_gstate_t
|
||||||
|
*
|
||||||
|
* Check if _cairo_gstate_redirect_target has been called on the head
|
||||||
|
* of the stack.
|
||||||
|
*
|
||||||
|
* Return value: %TRUE if @gstate is redirected to a target different
|
||||||
|
* than the previous state in the stack, %FALSE otherwise.
|
||||||
|
**/
|
||||||
|
cairo_bool_t
|
||||||
|
_cairo_gstate_is_group (cairo_gstate_t *gstate)
|
||||||
|
{
|
||||||
|
return gstate->parent_target != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* _cairo_gstate_is_redirected
|
* _cairo_gstate_is_redirected
|
||||||
* @gstate: a #cairo_gstate_t
|
* @gstate: a #cairo_gstate_t
|
||||||
|
|
|
||||||
26
src/cairo.c
26
src/cairo.c
|
|
@ -585,6 +585,11 @@ cairo_restore (cairo_t *cr)
|
||||||
if (unlikely (cr->status))
|
if (unlikely (cr->status))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (unlikely (_cairo_gstate_is_group (cr->gstate))) {
|
||||||
|
_cairo_set_error (cr, _cairo_error (CAIRO_STATUS_INVALID_RESTORE));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
status = _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist);
|
status = _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist);
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
_cairo_set_error (cr, status);
|
_cairo_set_error (cr, status);
|
||||||
|
|
@ -754,7 +759,7 @@ slim_hidden_def(cairo_push_group_with_content);
|
||||||
cairo_pattern_t *
|
cairo_pattern_t *
|
||||||
cairo_pop_group (cairo_t *cr)
|
cairo_pop_group (cairo_t *cr)
|
||||||
{
|
{
|
||||||
cairo_surface_t *group_surface, *parent_target;
|
cairo_surface_t *group_surface;
|
||||||
cairo_pattern_t *group_pattern;
|
cairo_pattern_t *group_pattern;
|
||||||
cairo_matrix_t group_matrix, device_transform_matrix;
|
cairo_matrix_t group_matrix, device_transform_matrix;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
|
@ -762,27 +767,18 @@ cairo_pop_group (cairo_t *cr)
|
||||||
if (unlikely (cr->status))
|
if (unlikely (cr->status))
|
||||||
return _cairo_pattern_create_in_error (cr->status);
|
return _cairo_pattern_create_in_error (cr->status);
|
||||||
|
|
||||||
/* Grab the active surfaces */
|
|
||||||
group_surface = _cairo_gstate_get_target (cr->gstate);
|
|
||||||
parent_target = _cairo_gstate_get_parent_target (cr->gstate);
|
|
||||||
|
|
||||||
/* Verify that we are at the right nesting level */
|
/* Verify that we are at the right nesting level */
|
||||||
if (parent_target == NULL) {
|
if (unlikely (! _cairo_gstate_is_group (cr->gstate))) {
|
||||||
_cairo_set_error (cr, CAIRO_STATUS_INVALID_POP_GROUP);
|
_cairo_set_error (cr, CAIRO_STATUS_INVALID_POP_GROUP);
|
||||||
return _cairo_pattern_create_in_error (CAIRO_STATUS_INVALID_POP_GROUP);
|
return _cairo_pattern_create_in_error (CAIRO_STATUS_INVALID_POP_GROUP);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We need to save group_surface before we restore; we don't need
|
/* Get a reference to the active surface before restoring */
|
||||||
* to reference parent_target and original_target, since the
|
group_surface = _cairo_gstate_get_target (cr->gstate);
|
||||||
* gstate will still hold refs to them once we restore. */
|
|
||||||
group_surface = cairo_surface_reference (group_surface);
|
group_surface = cairo_surface_reference (group_surface);
|
||||||
|
|
||||||
cairo_restore (cr);
|
status = _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist);
|
||||||
|
assert (status == CAIRO_STATUS_SUCCESS);
|
||||||
if (unlikely (cr->status)) {
|
|
||||||
group_pattern = _cairo_pattern_create_in_error (cr->status);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
group_pattern = cairo_pattern_create_for_surface (group_surface);
|
group_pattern = cairo_pattern_create_for_surface (group_surface);
|
||||||
status = group_pattern->status;
|
status = group_pattern->status;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue