static cairo_pattern_t * _cairo_default_context_pop_group (void *abstract_cr) { cairo_default_context_t *cr = abstract_cr; cairo_surface_t *group_surface; cairo_pattern_t *group_pattern; cairo_matrix_t group_matrix, device_transform_matrix; cairo_status_t status; /* Verify that we are at the right nesting level */ if (unlikely (! _cairo_gstate_is_group (cr->gstate))) return _cairo_pattern_create_in_error (CAIRO_STATUS_INVALID_POP_GROUP); /* Get a reference to the active surface before restoring */ group_surface = _cairo_gstate_get_target (cr->gstate); group_surface = cairo_surface_reference (group_surface); status = _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist); assert (status == CAIRO_STATUS_SUCCESS); group_pattern = cairo_pattern_create_for_surface (group_surface); status = group_pattern->status; if (unlikely (status)) goto done; _cairo_gstate_get_matrix (cr->gstate, &group_matrix); /* Transform by group_matrix centered around device_transform so that when * we call _cairo_gstate_copy_transformed_pattern the result is a pattern * with a matrix equivalent to the device_transform of group_surface. */ if (_cairo_surface_has_device_transform (group_surface)) { cairo_pattern_set_matrix (group_pattern, &group_surface->device_transform); _cairo_pattern_transform (group_pattern, &group_matrix); _cairo_pattern_transform (group_pattern, &group_surface->device_transform_inverse); } else { cairo_pattern_set_matrix (group_pattern, &group_matrix); } /* If we have a current path, we need to adjust it to compensate for * the device offset just removed. */ cairo_matrix_multiply (&device_transform_matrix, &_cairo_gstate_get_target (cr->gstate)->device_transform, &group_surface->device_transform_inverse); _cairo_path_fixed_transform (cr->path, &device_transform_matrix); done: cairo_surface_destroy (group_surface); return group_pattern; }
static cairo_pattern_t * _cairo_skia_context_pop_group (void *abstract_cr) { cairo_skia_context_t *cr = (cairo_skia_context_t *) abstract_cr; cairo_surface_t *group_surface; cairo_pattern_t *group_pattern; cairo_status_t status; group_surface = cairo_surface_reference (&cr->target->image.base); status = _cairo_skia_context_restore (cr); if (unlikely (status)) { group_pattern = _cairo_pattern_create_in_error (status); goto done; } group_pattern = cairo_pattern_create_for_surface (group_surface); status = group_pattern->status; if (unlikely (status)) goto done; #if 0 _cairo_gstate_get_matrix (cr->gstate, &group_matrix); /* Transform by group_matrix centered around device_transform so that when * we call _cairo_gstate_copy_transformed_pattern the result is a pattern * with a matrix equivalent to the device_transform of group_surface. */ if (_cairo_surface_has_device_transform (group_surface)) { cairo_pattern_set_matrix (group_pattern, &group_surface->device_transform); _cairo_pattern_transform (group_pattern, &group_matrix); _cairo_pattern_transform (group_pattern, &group_surface->device_transform_inverse); } else { cairo_pattern_set_matrix (group_pattern, &group_matrix); } /* If we have a current path, we need to adjust it to compensate for * the device offset just removed. */ _cairo_path_fixed_transform (cr->path, &group_surface->device_transform_inverse); #endif done: cairo_surface_destroy (group_surface); return group_pattern; }
static cairo_pattern_t * _cairo_default_context_pop_group (void *abstract_cr) { cairo_default_context_t *cr = abstract_cr; cairo_surface_t *group_surface; cairo_pattern_t *group_pattern; cairo_surface_t *parent_surface; cairo_matrix_t group_matrix; cairo_status_t status; /* Verify that we are at the right nesting level */ if (unlikely (! _cairo_gstate_is_group (cr->gstate))) return _cairo_pattern_create_in_error (CAIRO_STATUS_INVALID_POP_GROUP); /* Get a reference to the active surface before restoring */ group_surface = _cairo_gstate_get_target (cr->gstate); group_surface = cairo_surface_reference (group_surface); status = _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist); assert (status == CAIRO_STATUS_SUCCESS); parent_surface = _cairo_gstate_get_target (cr->gstate); group_pattern = cairo_pattern_create_for_surface (group_surface); status = group_pattern->status; if (unlikely (status)) goto done; _cairo_gstate_get_matrix (cr->gstate, &group_matrix); cairo_pattern_set_matrix (group_pattern, &group_matrix); /* If we have a current path, we need to adjust it to compensate for * the device offset just removed. */ _cairo_path_fixed_translate (cr->path, _cairo_fixed_from_int (parent_surface->device_transform.x0 - group_surface->device_transform.x0), _cairo_fixed_from_int (parent_surface->device_transform.y0 - group_surface->device_transform.y0)); done: cairo_surface_destroy (group_surface); return group_pattern; }