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;
}
示例#3
0
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;
}