mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-05 22:48:07 +02:00
Implement the device_offset functionality at surface, not gstate layer
This is a mega-patch that has the advantage that the entire test suite passes both immediately before and immediately after this commit. The disadvantage of the mega-patch is that it does not reflect the development history of the device-offset branch, (with its various fumblings and flailings). To capture that history, we will next merge in that branch.
This commit is contained in:
parent
40b39dddf9
commit
a6b1b014bb
13 changed files with 449 additions and 157 deletions
|
|
@ -435,6 +435,15 @@ _cairo_clip_clip (cairo_clip_t *clip,
|
|||
{
|
||||
cairo_status_t status;
|
||||
cairo_traps_t traps;
|
||||
cairo_path_fixed_t path_transformed;
|
||||
|
||||
if (_cairo_surface_has_device_offset_or_scale (target)) {
|
||||
_cairo_path_fixed_init_copy (&path_transformed, path);
|
||||
_cairo_path_fixed_offset (&path_transformed,
|
||||
_cairo_fixed_from_double (target->device_x_offset),
|
||||
_cairo_fixed_from_double (target->device_y_offset));
|
||||
path = &path_transformed;
|
||||
}
|
||||
|
||||
status = _cairo_clip_intersect_path (clip,
|
||||
path, fill_rule, tolerance,
|
||||
|
|
@ -458,6 +467,8 @@ _cairo_clip_clip (cairo_clip_t *clip,
|
|||
|
||||
bail:
|
||||
_cairo_traps_fini (&traps);
|
||||
if (path == &path_transformed)
|
||||
_cairo_path_fixed_fini (&path_transformed);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -501,37 +501,10 @@ _cairo_gstate_get_miter_limit (cairo_gstate_t *gstate)
|
|||
return gstate->stroke_style.miter_limit;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_gstate_apply_device_transform (cairo_gstate_t *gstate,
|
||||
cairo_matrix_t *matrix)
|
||||
{
|
||||
if (gstate->target->device_x_scale != 1.0 ||
|
||||
gstate->target->device_y_scale != 1.0)
|
||||
{
|
||||
cairo_matrix_scale (matrix,
|
||||
gstate->target->device_x_scale,
|
||||
gstate->target->device_y_scale);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_gstate_apply_device_inverse_transform (cairo_gstate_t *gstate,
|
||||
cairo_matrix_t *matrix)
|
||||
{
|
||||
if (gstate->target->device_x_scale != 1.0 ||
|
||||
gstate->target->device_y_scale != 1.0)
|
||||
{
|
||||
cairo_matrix_scale (matrix,
|
||||
1/gstate->target->device_x_scale,
|
||||
1/gstate->target->device_y_scale);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_gstate_get_matrix (cairo_gstate_t *gstate, cairo_matrix_t *matrix)
|
||||
{
|
||||
*matrix = gstate->ctm;
|
||||
_cairo_gstate_apply_device_inverse_transform (gstate, matrix);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
|
|
@ -617,9 +590,6 @@ _cairo_gstate_set_matrix (cairo_gstate_t *gstate,
|
|||
if (status)
|
||||
return status;
|
||||
|
||||
_cairo_gstate_apply_device_transform (gstate, &gstate->ctm);
|
||||
_cairo_gstate_apply_device_inverse_transform (gstate, &gstate->ctm_inverse);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -631,9 +601,6 @@ _cairo_gstate_identity_matrix (cairo_gstate_t *gstate)
|
|||
cairo_matrix_init_identity (&gstate->ctm);
|
||||
cairo_matrix_init_identity (&gstate->ctm_inverse);
|
||||
|
||||
_cairo_gstate_apply_device_transform (gstate, &gstate->ctm);
|
||||
_cairo_gstate_apply_device_inverse_transform (gstate, &gstate->ctm_inverse);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -675,15 +642,11 @@ void
|
|||
_cairo_gstate_user_to_backend (cairo_gstate_t *gstate, double *x, double *y)
|
||||
{
|
||||
cairo_matrix_transform_point (&gstate->ctm, x, y);
|
||||
*x += gstate->target->device_x_offset;
|
||||
*y += gstate->target->device_y_offset;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_gstate_backend_to_user (cairo_gstate_t *gstate, double *x, double *y)
|
||||
{
|
||||
*x -= gstate->target->device_x_offset;
|
||||
*y -= gstate->target->device_y_offset;
|
||||
cairo_matrix_transform_point (&gstate->ctm_inverse, x, y);
|
||||
}
|
||||
|
||||
|
|
@ -704,16 +667,24 @@ _cairo_gstate_copy_transformed_pattern (cairo_gstate_t *gstate,
|
|||
cairo_pattern_t *original,
|
||||
cairo_matrix_t *ctm_inverse)
|
||||
{
|
||||
cairo_matrix_t tmp_matrix = *ctm_inverse;
|
||||
|
||||
cairo_surface_pattern_t *surface_pattern;
|
||||
cairo_surface_t *surface;
|
||||
cairo_matrix_t offset_matrix;
|
||||
|
||||
_cairo_pattern_init_copy (pattern, original);
|
||||
_cairo_pattern_transform (pattern, ctm_inverse);
|
||||
|
||||
if (gstate->target)
|
||||
cairo_matrix_translate (&tmp_matrix,
|
||||
- gstate->target->device_x_offset,
|
||||
- gstate->target->device_y_offset);
|
||||
if (cairo_pattern_get_type (original) == CAIRO_PATTERN_TYPE_SURFACE) {
|
||||
surface_pattern = (cairo_surface_pattern_t *) original;
|
||||
surface = surface_pattern->surface;
|
||||
if (_cairo_surface_has_device_offset_or_scale (surface)) {
|
||||
cairo_matrix_init_translate (&offset_matrix,
|
||||
surface->device_x_offset,
|
||||
surface->device_y_offset);
|
||||
_cairo_pattern_transform (pattern, &offset_matrix);
|
||||
}
|
||||
}
|
||||
|
||||
_cairo_pattern_transform (pattern, &tmp_matrix);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -568,3 +568,49 @@ _cairo_path_fixed_interpret (cairo_path_fixed_t *path,
|
|||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t offx,
|
||||
cairo_fixed_t offy,
|
||||
cairo_fixed_t scalex,
|
||||
cairo_fixed_t scaley)
|
||||
{
|
||||
cairo_path_arg_buf_t *arg_buf = path->arg_buf_head;
|
||||
int i;
|
||||
cairo_int64_t i64temp;
|
||||
cairo_fixed_t fixedtemp;
|
||||
|
||||
while (arg_buf) {
|
||||
for (i = 0; i < arg_buf->num_points; i++) {
|
||||
if (scalex == CAIRO_FIXED_ONE) {
|
||||
arg_buf->points[i].x += offx;
|
||||
} else {
|
||||
fixedtemp = arg_buf->points[i].x + offx;
|
||||
i64temp = _cairo_int32x32_64_mul (fixedtemp, scalex);
|
||||
arg_buf->points[i].x = _cairo_int64_to_int32(_cairo_int64_rsl (i64temp, 16));
|
||||
}
|
||||
|
||||
if (scaley == CAIRO_FIXED_ONE) {
|
||||
arg_buf->points[i].y += offy;
|
||||
} else {
|
||||
fixedtemp = arg_buf->points[i].y + offy;
|
||||
i64temp = _cairo_int32x32_64_mul (fixedtemp, scaley);
|
||||
arg_buf->points[i].y = _cairo_int64_to_int32(_cairo_int64_rsl (i64temp, 16));
|
||||
}
|
||||
}
|
||||
|
||||
arg_buf = arg_buf->next;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_path_fixed_offset (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t offx,
|
||||
cairo_fixed_t offy)
|
||||
{
|
||||
_cairo_path_fixed_offset_and_scale (path, offx, offy,
|
||||
CAIRO_FIXED_ONE,
|
||||
CAIRO_FIXED_ONE);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1194,10 +1194,8 @@ _cairo_ps_surface_start_page (void *abstract_surface)
|
|||
(int) ceil (surface->height));
|
||||
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
"gsave %f %f translate %f %f scale \n",
|
||||
0.0, surface->height,
|
||||
1.0/surface->base.device_x_scale,
|
||||
-1.0/surface->base.device_y_scale);
|
||||
"gsave %f %f translate 1.0 -1.0 scale \n",
|
||||
0.0, surface->height);
|
||||
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
"%%%%EndPageSetup\n");
|
||||
|
|
|
|||
|
|
@ -920,11 +920,11 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
|
|||
|
||||
/* round glyph locations to the nearest pixel */
|
||||
x = (int) floor (glyphs[i].x +
|
||||
glyph_surface->base.device_x_offset +
|
||||
0.5);
|
||||
glyph_surface->base.device_x_offset +
|
||||
0.5);
|
||||
y = (int) floor (glyphs[i].y +
|
||||
glyph_surface->base.device_y_offset +
|
||||
0.5);
|
||||
glyph_surface->base.device_y_offset +
|
||||
0.5);
|
||||
|
||||
_cairo_pattern_init_for_surface (&glyph_pattern, &glyph_surface->base);
|
||||
|
||||
|
|
|
|||
|
|
@ -895,7 +895,8 @@ _cairo_surface_old_show_glyphs_draw_func (void *closure,
|
|||
op,
|
||||
src, dst,
|
||||
extents->x, extents->y,
|
||||
extents->x - dst_x, extents->y - dst_y,
|
||||
extents->x - dst_x,
|
||||
extents->y - dst_y,
|
||||
extents->width, extents->height,
|
||||
glyph_info->glyphs,
|
||||
glyph_info->num_glyphs);
|
||||
|
|
@ -989,6 +990,9 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface)
|
|||
_cairo_surface_release_source_image (surface,
|
||||
image, &image_extra);
|
||||
|
||||
snapshot->device_x_offset = surface->device_x_offset;
|
||||
snapshot->device_y_offset = surface->device_y_offset;
|
||||
|
||||
snapshot->is_snapshot = TRUE;
|
||||
|
||||
return snapshot;
|
||||
|
|
@ -1018,12 +1022,17 @@ _cairo_surface_fallback_composite (cairo_operator_t op,
|
|||
return status;
|
||||
}
|
||||
|
||||
status = state.image->base.backend->composite (op, src, mask,
|
||||
&state.image->base,
|
||||
src_x, src_y, mask_x, mask_y,
|
||||
dst_x - state.image_rect.x,
|
||||
dst_y - state.image_rect.y,
|
||||
width, height);
|
||||
/* We know this will never fail with the image backend; but
|
||||
* instead of calling into it directly, we call
|
||||
* _cairo_surface_composite so that we get the correct device
|
||||
* offset handling.
|
||||
*/
|
||||
status = _cairo_surface_composite (op, src, mask,
|
||||
&state.image->base,
|
||||
src_x, src_y, mask_x, mask_y,
|
||||
dst_x - state.image_rect.x,
|
||||
dst_y - state.image_rect.y,
|
||||
width, height);
|
||||
_fallback_fini (&state);
|
||||
|
||||
return status;
|
||||
|
|
@ -1093,9 +1102,9 @@ _cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface,
|
|||
rects = offset_rects;
|
||||
}
|
||||
|
||||
status = state.image->base.backend->fill_rectangles (&state.image->base,
|
||||
op, color,
|
||||
rects, num_rects);
|
||||
status = _cairo_surface_fill_rectangles (&state.image->base,
|
||||
op, color,
|
||||
rects, num_rects);
|
||||
|
||||
free (offset_rects);
|
||||
|
||||
|
|
@ -1122,7 +1131,6 @@ _cairo_surface_fallback_composite_trapezoids (cairo_operator_t op,
|
|||
fallback_state_t state;
|
||||
cairo_trapezoid_t *offset_traps = NULL;
|
||||
cairo_status_t status;
|
||||
int i;
|
||||
|
||||
status = _fallback_init (&state, dst, dst_x, dst_y, width, height);
|
||||
if (status) {
|
||||
|
|
@ -1134,39 +1142,25 @@ _cairo_surface_fallback_composite_trapezoids (cairo_operator_t op,
|
|||
/* If the destination image isn't at 0,0, we need to offset the trapezoids */
|
||||
|
||||
if (state.image_rect.x != 0 || state.image_rect.y != 0) {
|
||||
|
||||
cairo_fixed_t xoff = _cairo_fixed_from_int (state.image_rect.x);
|
||||
cairo_fixed_t yoff = _cairo_fixed_from_int (state.image_rect.y);
|
||||
|
||||
offset_traps = malloc (sizeof (cairo_trapezoid_t) * num_traps);
|
||||
if (!offset_traps) {
|
||||
status = CAIRO_STATUS_NO_MEMORY;
|
||||
goto DONE;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_traps; i++) {
|
||||
offset_traps[i].top = traps[i].top - yoff;
|
||||
offset_traps[i].bottom = traps[i].bottom - yoff;
|
||||
offset_traps[i].left.p1.x = traps[i].left.p1.x - xoff;
|
||||
offset_traps[i].left.p1.y = traps[i].left.p1.y - yoff;
|
||||
offset_traps[i].left.p2.x = traps[i].left.p2.x - xoff;
|
||||
offset_traps[i].left.p2.y = traps[i].left.p2.y - yoff;
|
||||
offset_traps[i].right.p1.x = traps[i].right.p1.x - xoff;
|
||||
offset_traps[i].right.p1.y = traps[i].right.p1.y - yoff;
|
||||
offset_traps[i].right.p2.x = traps[i].right.p2.x - xoff;
|
||||
offset_traps[i].right.p2.y = traps[i].right.p2.y - yoff;
|
||||
}
|
||||
|
||||
_cairo_trapezoid_array_translate_and_scale (offset_traps, traps, num_traps,
|
||||
- state.image_rect.x, - state.image_rect.y,
|
||||
1.0, 1.0);
|
||||
traps = offset_traps;
|
||||
}
|
||||
|
||||
state.image->base.backend->composite_trapezoids (op, pattern,
|
||||
&state.image->base,
|
||||
antialias,
|
||||
src_x, src_y,
|
||||
dst_x - state.image_rect.x,
|
||||
dst_y - state.image_rect.y,
|
||||
width, height, traps, num_traps);
|
||||
_cairo_surface_composite_trapezoids (op, pattern,
|
||||
&state.image->base,
|
||||
antialias,
|
||||
src_x, src_y,
|
||||
dst_x - state.image_rect.x,
|
||||
dst_y - state.image_rect.y,
|
||||
width, height, traps, num_traps);
|
||||
if (offset_traps)
|
||||
free (offset_traps);
|
||||
|
||||
|
|
|
|||
|
|
@ -92,6 +92,14 @@ const cairo_surface_t _cairo_surface_nil_read_error = {
|
|||
0 /* current_clip_serial */
|
||||
};
|
||||
|
||||
/* Helper macros for transforming surface coords to backend coords */
|
||||
#define SURFACE_TO_BACKEND_X(_surf, _sx) ((_sx)+((_surf)->device_x_offset))
|
||||
#define SURFACE_TO_BACKEND_Y(_surf, _sy) ((_sy)+((_surf)->device_y_offset))
|
||||
|
||||
static void _cairo_surface_copy_pattern_for_destination (const cairo_pattern_t *pattern,
|
||||
cairo_surface_t *destination,
|
||||
cairo_pattern_t *pattern_out);
|
||||
|
||||
/**
|
||||
* _cairo_surface_set_error:
|
||||
* @surface: a surface
|
||||
|
|
@ -171,8 +179,6 @@ _cairo_surface_init (cairo_surface_t *surface,
|
|||
|
||||
surface->device_x_offset = 0.0;
|
||||
surface->device_y_offset = 0.0;
|
||||
surface->device_x_scale = 1.0;
|
||||
surface->device_y_scale = 1.0;
|
||||
|
||||
surface->clip = NULL;
|
||||
surface->next_clip_serial = 0;
|
||||
|
|
@ -556,7 +562,10 @@ cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
|
|||
if (surface->backend->mark_dirty_rectangle) {
|
||||
cairo_status_t status;
|
||||
|
||||
status = surface->backend->mark_dirty_rectangle (surface, x, y, width, height);
|
||||
status = surface->backend->mark_dirty_rectangle (surface,
|
||||
SURFACE_TO_BACKEND_X(surface, x),
|
||||
SURFACE_TO_BACKEND_Y(surface, y),
|
||||
width, height);
|
||||
|
||||
if (status)
|
||||
_cairo_surface_set_error (surface, status);
|
||||
|
|
@ -596,8 +605,34 @@ cairo_surface_set_device_offset (cairo_surface_t *surface,
|
|||
return;
|
||||
}
|
||||
|
||||
surface->device_x_offset = x_offset * surface->device_x_scale;
|
||||
surface->device_y_offset = y_offset * surface->device_y_scale;
|
||||
surface->device_x_offset = x_offset;
|
||||
surface->device_y_offset = y_offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_surface_get_device_offset:
|
||||
* @surface: a #cairo_surface_t
|
||||
* @x_offset: the offset in the X direction, in device units
|
||||
* @y_offset: the offset in the Y direction, in device units
|
||||
*
|
||||
* Returns a previous device offset set by
|
||||
* cairo_surface_set_device_offset().
|
||||
*
|
||||
**/
|
||||
void
|
||||
cairo_surface_get_device_offset (cairo_surface_t *surface,
|
||||
double *x_offset,
|
||||
double *y_offset)
|
||||
{
|
||||
*x_offset = surface->device_x_offset;
|
||||
*y_offset = surface->device_y_offset;
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
_cairo_surface_has_device_offset_or_scale (cairo_surface_t *surface)
|
||||
{
|
||||
return (surface->device_x_offset != 0.0 ||
|
||||
surface->device_y_offset != 0.0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -651,6 +686,7 @@ _cairo_surface_release_source_image (cairo_surface_t *surface,
|
|||
* @surface: a #cairo_surface_t
|
||||
* @interest_rect: area of @surface for which fallback drawing is being done.
|
||||
* A value of %NULL indicates that the entire surface is desired.
|
||||
* XXXX I'd like to get rid of being able to pass NULL here (nothing seems to)
|
||||
* @image_out: location to store a pointer to an image surface that includes at least
|
||||
* the intersection of @interest_rect with the visible area of @surface.
|
||||
* This surface could be @surface itself, a surface held internal to @surface,
|
||||
|
|
@ -685,7 +721,8 @@ _cairo_surface_acquire_dest_image (cairo_surface_t *surface,
|
|||
{
|
||||
assert (!surface->finished);
|
||||
|
||||
return surface->backend->acquire_dest_image (surface, interest_rect,
|
||||
return surface->backend->acquire_dest_image (surface,
|
||||
interest_rect,
|
||||
image_out, image_rect, image_extra);
|
||||
}
|
||||
|
||||
|
|
@ -747,6 +784,11 @@ _cairo_surface_clone_similar (cairo_surface_t *surface,
|
|||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
status = surface->backend->clone_similar (surface, src, clone_out);
|
||||
if (status == CAIRO_STATUS_SUCCESS) {
|
||||
(*clone_out)->device_x_offset = src->device_x_offset;
|
||||
(*clone_out)->device_y_offset = src->device_y_offset;
|
||||
}
|
||||
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
|
|
@ -755,6 +797,10 @@ _cairo_surface_clone_similar (cairo_surface_t *surface,
|
|||
return status;
|
||||
|
||||
status = surface->backend->clone_similar (surface, &image->base, clone_out);
|
||||
if (status == CAIRO_STATUS_SUCCESS) {
|
||||
(*clone_out)->device_x_offset = src->device_x_offset;
|
||||
(*clone_out)->device_y_offset = src->device_y_offset;
|
||||
}
|
||||
|
||||
/* If the above failed point, we could implement a full fallback
|
||||
* using acquire_dest_image, but that's going to be very
|
||||
|
|
@ -829,9 +875,9 @@ _cairo_surface_composite (cairo_operator_t op,
|
|||
if (dst->backend->composite) {
|
||||
status = dst->backend->composite (op,
|
||||
src, mask, dst,
|
||||
src_x, src_y,
|
||||
mask_x, mask_y,
|
||||
dst_x, dst_y,
|
||||
src_x, src_y,
|
||||
mask_x, mask_y,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
|
@ -989,16 +1035,24 @@ _cairo_surface_paint (cairo_surface_t *surface,
|
|||
cairo_pattern_t *source)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_pattern_union_t dev_source;
|
||||
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
_cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
|
||||
|
||||
if (surface->backend->paint) {
|
||||
status = surface->backend->paint (surface, op, source);
|
||||
status = surface->backend->paint (surface, op, &dev_source.base);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
goto FINISH;
|
||||
}
|
||||
|
||||
return _cairo_surface_fallback_paint (surface, op, source);
|
||||
status = _cairo_surface_fallback_paint (surface, op, &dev_source.base);
|
||||
|
||||
FINISH:
|
||||
_cairo_pattern_fini (&dev_source.base);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
|
|
@ -1008,16 +1062,27 @@ _cairo_surface_mask (cairo_surface_t *surface,
|
|||
cairo_pattern_t *mask)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_pattern_union_t dev_source;
|
||||
cairo_pattern_union_t dev_mask;
|
||||
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
_cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
|
||||
_cairo_surface_copy_pattern_for_destination (mask, surface, &dev_mask.base);
|
||||
|
||||
if (surface->backend->mask) {
|
||||
status = surface->backend->mask (surface, op, source, mask);
|
||||
status = surface->backend->mask (surface, op, &dev_source.base, &dev_mask.base);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
goto FINISH;
|
||||
}
|
||||
|
||||
return _cairo_surface_fallback_mask (surface, op, source, mask);
|
||||
status = _cairo_surface_fallback_mask (surface, op, &dev_source.base, &dev_mask.base);
|
||||
|
||||
FINISH:
|
||||
_cairo_pattern_fini (&dev_source.base);
|
||||
_cairo_pattern_fini (&dev_mask.base);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
|
|
@ -1031,22 +1096,45 @@ _cairo_surface_stroke (cairo_surface_t *surface,
|
|||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_pattern_union_t dev_source;
|
||||
cairo_path_fixed_t *dev_path = path;
|
||||
cairo_path_fixed_t real_dev_path;
|
||||
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
if (surface->backend->stroke) {
|
||||
cairo_status_t status;
|
||||
status = surface->backend->stroke (surface, op, source,
|
||||
path, stroke_style,
|
||||
ctm, ctm_inverse,
|
||||
tolerance, antialias);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
_cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
|
||||
|
||||
if (_cairo_surface_has_device_offset_or_scale (surface))
|
||||
{
|
||||
_cairo_path_fixed_init_copy (&real_dev_path, path);
|
||||
_cairo_path_fixed_offset (&real_dev_path,
|
||||
_cairo_fixed_from_double (surface->device_x_offset),
|
||||
_cairo_fixed_from_double (surface->device_y_offset));
|
||||
dev_path = &real_dev_path;
|
||||
}
|
||||
|
||||
return _cairo_surface_fallback_stroke (surface, op, source,
|
||||
path, stroke_style,
|
||||
if (surface->backend->stroke) {
|
||||
status = surface->backend->stroke (surface, op, &dev_source.base,
|
||||
dev_path, stroke_style,
|
||||
ctm, ctm_inverse,
|
||||
tolerance, antialias);
|
||||
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
goto FINISH;
|
||||
}
|
||||
|
||||
status = _cairo_surface_fallback_stroke (surface, op, &dev_source.base,
|
||||
dev_path, stroke_style,
|
||||
ctm, ctm_inverse,
|
||||
tolerance, antialias);
|
||||
|
||||
FINISH:
|
||||
if (dev_path == &real_dev_path)
|
||||
_cairo_path_fixed_fini (&real_dev_path);
|
||||
_cairo_pattern_fini (&dev_source.base);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
|
|
@ -1059,20 +1147,42 @@ _cairo_surface_fill (cairo_surface_t *surface,
|
|||
cairo_antialias_t antialias)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_pattern_union_t dev_source;
|
||||
cairo_path_fixed_t *dev_path = path;
|
||||
cairo_path_fixed_t real_dev_path;
|
||||
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
if (surface->backend->fill) {
|
||||
status = surface->backend->fill (surface, op, source,
|
||||
path, fill_rule,
|
||||
tolerance, antialias);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
_cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
|
||||
|
||||
if (_cairo_surface_has_device_offset_or_scale (surface))
|
||||
{
|
||||
_cairo_path_fixed_init_copy (&real_dev_path, path);
|
||||
_cairo_path_fixed_offset (&real_dev_path,
|
||||
_cairo_fixed_from_double (surface->device_x_offset),
|
||||
_cairo_fixed_from_double (surface->device_y_offset));
|
||||
dev_path = &real_dev_path;
|
||||
}
|
||||
|
||||
return _cairo_surface_fallback_fill (surface, op, source,
|
||||
path, fill_rule,
|
||||
if (surface->backend->fill) {
|
||||
status = surface->backend->fill (surface, op, &dev_source.base,
|
||||
dev_path, fill_rule,
|
||||
tolerance, antialias);
|
||||
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
goto FINISH;
|
||||
}
|
||||
|
||||
status = _cairo_surface_fallback_fill (surface, op, &dev_source.base,
|
||||
dev_path, fill_rule,
|
||||
tolerance, antialias);
|
||||
|
||||
FINISH:
|
||||
if (dev_path == &real_dev_path)
|
||||
_cairo_path_fixed_fini (&real_dev_path);
|
||||
_cairo_pattern_fini (&dev_source.base);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
|
|
@ -1109,7 +1219,7 @@ _cairo_surface_composite_trapezoids (cairo_operator_t op,
|
|||
pattern, dst,
|
||||
antialias,
|
||||
src_x, src_y,
|
||||
dst_x, dst_y,
|
||||
dst_x, dst_y,
|
||||
width, height,
|
||||
traps, num_traps);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
|
|
@ -1258,6 +1368,8 @@ _cairo_surface_set_clip_region (cairo_surface_t *surface,
|
|||
pixman_region16_t *region,
|
||||
unsigned int serial)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
if (surface->status)
|
||||
return surface->status;
|
||||
|
||||
|
|
@ -1265,10 +1377,12 @@ _cairo_surface_set_clip_region (cairo_surface_t *surface,
|
|||
return CAIRO_STATUS_SURFACE_FINISHED;
|
||||
|
||||
assert (surface->backend->set_clip_region != NULL);
|
||||
|
||||
|
||||
surface->current_clip_serial = serial;
|
||||
|
||||
return surface->backend->set_clip_region (surface, region);
|
||||
status = surface->backend->set_clip_region (surface, region);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_int_status_t
|
||||
|
|
@ -1278,6 +1392,9 @@ _cairo_surface_intersect_clip_path (cairo_surface_t *surface,
|
|||
double tolerance,
|
||||
cairo_antialias_t antialias)
|
||||
{
|
||||
cairo_path_fixed_t *dev_path = path;
|
||||
cairo_status_t status;
|
||||
|
||||
if (surface->status)
|
||||
return surface->status;
|
||||
|
||||
|
|
@ -1286,11 +1403,13 @@ _cairo_surface_intersect_clip_path (cairo_surface_t *surface,
|
|||
|
||||
assert (surface->backend->intersect_clip_path != NULL);
|
||||
|
||||
return surface->backend->intersect_clip_path (surface,
|
||||
path,
|
||||
fill_rule,
|
||||
tolerance,
|
||||
antialias);
|
||||
status = surface->backend->intersect_clip_path (surface,
|
||||
dev_path,
|
||||
fill_rule,
|
||||
tolerance,
|
||||
antialias);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
|
|
@ -1306,11 +1425,11 @@ _cairo_surface_set_clip_path_recursive (cairo_surface_t *surface,
|
|||
if (status)
|
||||
return status;
|
||||
|
||||
return surface->backend->intersect_clip_path (surface,
|
||||
&clip_path->path,
|
||||
clip_path->fill_rule,
|
||||
clip_path->tolerance,
|
||||
clip_path->antialias);
|
||||
return _cairo_surface_intersect_clip_path (surface,
|
||||
&clip_path->path,
|
||||
clip_path->fill_rule,
|
||||
clip_path->tolerance,
|
||||
clip_path->antialias);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1413,13 +1532,22 @@ cairo_status_t
|
|||
_cairo_surface_get_extents (cairo_surface_t *surface,
|
||||
cairo_rectangle_t *rectangle)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
if (surface->status)
|
||||
return surface->status;
|
||||
|
||||
if (surface->finished)
|
||||
return CAIRO_STATUS_SURFACE_FINISHED;
|
||||
|
||||
return surface->backend->get_extents (surface, rectangle);
|
||||
status = surface->backend->get_extents (surface, rectangle);
|
||||
|
||||
rectangle->x = SURFACE_TO_BACKEND_X(surface, rectangle->x);
|
||||
rectangle->y = SURFACE_TO_BACKEND_Y(surface, rectangle->y);
|
||||
rectangle->width = rectangle->width - surface->device_x_offset;
|
||||
rectangle->height = rectangle->height - surface->device_y_offset;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
|
|
@ -1431,20 +1559,48 @@ _cairo_surface_show_glyphs (cairo_surface_t *surface,
|
|||
cairo_scaled_font_t *scaled_font)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_glyph_t *dev_glyphs = (cairo_glyph_t*) glyphs;
|
||||
cairo_pattern_union_t dev_source;
|
||||
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
if (surface->backend->show_glyphs) {
|
||||
status = surface->backend->show_glyphs (surface, op, source,
|
||||
glyphs, num_glyphs,
|
||||
scaled_font);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
_cairo_surface_copy_pattern_for_destination (source,
|
||||
surface,
|
||||
&dev_source.base);
|
||||
|
||||
if (_cairo_surface_has_device_offset_or_scale (surface))
|
||||
{
|
||||
int i;
|
||||
|
||||
dev_glyphs = malloc (sizeof(cairo_glyph_t) * num_glyphs);
|
||||
if (!dev_glyphs)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
for (i = 0; i < num_glyphs; i++) {
|
||||
dev_glyphs[i].index = glyphs[i].index;
|
||||
/* XXX: err, we really should scale the size of the glyphs, no? */
|
||||
dev_glyphs[i].x = SURFACE_TO_BACKEND_X(surface, glyphs[i].x);
|
||||
dev_glyphs[i].y = SURFACE_TO_BACKEND_Y(surface, glyphs[i].y);
|
||||
}
|
||||
}
|
||||
|
||||
return _cairo_surface_fallback_show_glyphs (surface, op, source,
|
||||
glyphs, num_glyphs,
|
||||
scaled_font);
|
||||
if (surface->backend->show_glyphs) {
|
||||
status = surface->backend->show_glyphs (surface, op, &dev_source.base,
|
||||
dev_glyphs, num_glyphs,
|
||||
scaled_font);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
goto FINISH;
|
||||
}
|
||||
|
||||
status = _cairo_surface_fallback_show_glyphs (surface, op, &dev_source.base,
|
||||
dev_glyphs, num_glyphs,
|
||||
scaled_font);
|
||||
|
||||
FINISH:
|
||||
if (dev_glyphs != glyphs)
|
||||
free (dev_glyphs);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* XXX: Previously, we had a function named _cairo_surface_show_glyphs
|
||||
|
|
@ -1476,14 +1632,14 @@ _cairo_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
|
|||
if (dst->finished)
|
||||
return CAIRO_STATUS_SURFACE_FINISHED;
|
||||
|
||||
if (dst->backend->old_show_glyphs)
|
||||
if (dst->backend->old_show_glyphs) {
|
||||
status = dst->backend->old_show_glyphs (scaled_font,
|
||||
op, pattern, dst,
|
||||
source_x, source_y,
|
||||
dest_x, dest_y,
|
||||
dest_x, dest_y,
|
||||
width, height,
|
||||
glyphs, num_glyphs);
|
||||
else
|
||||
} else
|
||||
status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
return status;
|
||||
|
|
@ -1593,7 +1749,7 @@ _cairo_surface_composite_fixup_unbounded (cairo_surface_t *dst,
|
|||
cairo_rectangle_t *mask_rectangle = NULL;
|
||||
|
||||
assert (! dst->is_snapshot);
|
||||
|
||||
|
||||
/* The RENDER/libpixman operators are clipped to the bounds of the untransformed,
|
||||
* non-repeating sources and masks. Other sources and masks can be ignored.
|
||||
*/
|
||||
|
|
@ -1668,7 +1824,7 @@ _cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t *dst,
|
|||
cairo_rectangle_t *mask_rectangle = NULL;
|
||||
|
||||
assert (! dst->is_snapshot);
|
||||
|
||||
|
||||
/* The RENDER/libpixman operators are clipped to the bounds of the untransformed,
|
||||
* non-repeating sources and masks. Other sources and masks can be ignored.
|
||||
*/
|
||||
|
|
@ -1729,3 +1885,29 @@ _cairo_surface_is_opaque (const cairo_surface_t *surface)
|
|||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_surface_copy_pattern_for_destination
|
||||
* @pattern: the pattern to copy
|
||||
* @destination: the destination surface for which the pattern is being copied
|
||||
* @pattern_out: the location to hold the copy
|
||||
*
|
||||
* Copies the given pattern, taking into account device scale and offsets
|
||||
* of the destination surface.
|
||||
*/
|
||||
void
|
||||
_cairo_surface_copy_pattern_for_destination (const cairo_pattern_t *pattern,
|
||||
cairo_surface_t *destination,
|
||||
cairo_pattern_t *pattern_out)
|
||||
{
|
||||
_cairo_pattern_init_copy (pattern_out, pattern);
|
||||
|
||||
if (_cairo_surface_has_device_offset_or_scale (destination)) {
|
||||
cairo_matrix_t device_to_surface;
|
||||
cairo_matrix_init_translate (&device_to_surface,
|
||||
- destination->device_x_offset,
|
||||
- destination->device_y_offset);
|
||||
|
||||
_cairo_pattern_transform (pattern_out, &device_to_surface);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -258,6 +258,54 @@ _cairo_traps_translate (cairo_traps_t *traps, int x, int y)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_trapezoid_array_translate_and_scale (cairo_trapezoid_t *offset_traps,
|
||||
cairo_trapezoid_t *src_traps,
|
||||
int num_traps,
|
||||
double tx, double ty,
|
||||
double sx, double sy)
|
||||
{
|
||||
int i;
|
||||
cairo_fixed_t xoff = _cairo_fixed_from_double (tx);
|
||||
cairo_fixed_t yoff = _cairo_fixed_from_double (ty);
|
||||
|
||||
if (sx == 1.0 && sy == 1.0) {
|
||||
for (i = 0; i < num_traps; i++) {
|
||||
offset_traps[i].top = src_traps[i].top + yoff;
|
||||
offset_traps[i].bottom = src_traps[i].bottom + yoff;
|
||||
offset_traps[i].left.p1.x = src_traps[i].left.p1.x + xoff;
|
||||
offset_traps[i].left.p1.y = src_traps[i].left.p1.y + yoff;
|
||||
offset_traps[i].left.p2.x = src_traps[i].left.p2.x + xoff;
|
||||
offset_traps[i].left.p2.y = src_traps[i].left.p2.y + yoff;
|
||||
offset_traps[i].right.p1.x = src_traps[i].right.p1.x + xoff;
|
||||
offset_traps[i].right.p1.y = src_traps[i].right.p1.y + yoff;
|
||||
offset_traps[i].right.p2.x = src_traps[i].right.p2.x + xoff;
|
||||
offset_traps[i].right.p2.y = src_traps[i].right.p2.y + yoff;
|
||||
}
|
||||
} else {
|
||||
cairo_fixed_t xsc = _cairo_fixed_from_double (sx);
|
||||
cairo_fixed_t ysc = _cairo_fixed_from_double (sy);
|
||||
|
||||
for (i = 0; i < num_traps; i++) {
|
||||
#define FIXED_MUL(_a, _b) \
|
||||
(_cairo_int64_to_int32(_cairo_int64_rsl(_cairo_int32x32_64_mul((_a), (_b)), 16)))
|
||||
|
||||
offset_traps[i].top = FIXED_MUL(src_traps[i].top + yoff, ysc);
|
||||
offset_traps[i].bottom = FIXED_MUL(src_traps[i].bottom + yoff, ysc);
|
||||
offset_traps[i].left.p1.x = FIXED_MUL(src_traps[i].left.p1.x + xoff, xsc);
|
||||
offset_traps[i].left.p1.y = FIXED_MUL(src_traps[i].left.p1.y + yoff, ysc);
|
||||
offset_traps[i].left.p2.x = FIXED_MUL(src_traps[i].left.p2.x + xoff, xsc);
|
||||
offset_traps[i].left.p2.y = FIXED_MUL(src_traps[i].left.p2.y + yoff, ysc);
|
||||
offset_traps[i].right.p1.x = FIXED_MUL(src_traps[i].right.p1.x + xoff, xsc);
|
||||
offset_traps[i].right.p1.y = FIXED_MUL(src_traps[i].right.p1.y + yoff, ysc);
|
||||
offset_traps[i].right.p2.x = FIXED_MUL(src_traps[i].right.p2.x + xoff, xsc);
|
||||
offset_traps[i].right.p2.y = FIXED_MUL(src_traps[i].right.p2.y + yoff, ysc);
|
||||
|
||||
#undef FIXED_MUL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_traps_tessellate_triangle (cairo_traps_t *traps, cairo_point_t t[3])
|
||||
{
|
||||
|
|
@ -859,4 +907,3 @@ _cairo_traps_extract_region (cairo_traps_t *traps,
|
|||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2151,8 +2151,8 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
|
|||
* sitting around for x and y.
|
||||
*/
|
||||
|
||||
glyph_info.x = -(int) glyph_surface->base.device_x_offset;
|
||||
glyph_info.y = -(int) glyph_surface->base.device_y_offset;
|
||||
glyph_info.x = - (int) floor(glyph_surface->base.device_x_offset + 0.5);
|
||||
glyph_info.y = - (int) floor(glyph_surface->base.device_y_offset + 0.5);
|
||||
glyph_info.width = glyph_surface->width;
|
||||
glyph_info.height = glyph_surface->height;
|
||||
glyph_info.xOff = 0;
|
||||
|
|
|
|||
|
|
@ -1304,6 +1304,11 @@ cairo_surface_set_device_offset (cairo_surface_t *surface,
|
|||
double x_offset,
|
||||
double y_offset);
|
||||
|
||||
cairo_public void
|
||||
cairo_surface_get_device_offset (cairo_surface_t *surface,
|
||||
double *x_offset,
|
||||
double *y_offset);
|
||||
|
||||
/* Image-surface functions */
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -861,8 +861,6 @@ struct _cairo_surface {
|
|||
|
||||
double device_x_offset;
|
||||
double device_y_offset;
|
||||
double device_x_scale;
|
||||
double device_y_scale;
|
||||
|
||||
cairo_clip_t *clip;
|
||||
|
||||
|
|
@ -1058,6 +1056,8 @@ _cairo_restrict_value (double *value, double min, double max);
|
|||
cairo_private cairo_fixed_t
|
||||
_cairo_fixed_from_int (int i);
|
||||
|
||||
#define CAIRO_FIXED_ONE _cairo_fixed_from_int (1)
|
||||
|
||||
cairo_private cairo_fixed_t
|
||||
_cairo_fixed_from_double (double d);
|
||||
|
||||
|
|
@ -1488,6 +1488,11 @@ _cairo_path_fixed_bounds (cairo_path_fixed_t *path,
|
|||
double *x1, double *y1,
|
||||
double *x2, double *y2);
|
||||
|
||||
cairo_private void
|
||||
_cairo_path_fixed_offset (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t offx,
|
||||
cairo_fixed_t offy);
|
||||
|
||||
/* cairo_path_fill.c */
|
||||
cairo_private cairo_status_t
|
||||
_cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path,
|
||||
|
|
@ -1836,6 +1841,9 @@ _cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t *dst,
|
|||
cairo_private cairo_bool_t
|
||||
_cairo_surface_is_opaque (const cairo_surface_t *surface);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_surface_has_device_offset_or_scale (cairo_surface_t *surface);
|
||||
|
||||
/* cairo_image_surface.c */
|
||||
|
||||
#define CAIRO_FORMAT_VALID(format) ((format) >= CAIRO_FORMAT_ARGB32 && \
|
||||
|
|
@ -2038,6 +2046,13 @@ cairo_private cairo_status_t
|
|||
_cairo_traps_extract_region (cairo_traps_t *tr,
|
||||
pixman_region16_t **region);
|
||||
|
||||
cairo_private void
|
||||
_cairo_trapezoid_array_translate_and_scale (cairo_trapezoid_t *offset_traps,
|
||||
cairo_trapezoid_t *src_traps,
|
||||
int num_traps,
|
||||
double tx, double ty,
|
||||
double sx, double sy);
|
||||
|
||||
/* cairo_slope.c */
|
||||
cairo_private void
|
||||
_cairo_slope_init (cairo_slope_t *slope, cairo_point_t *a, cairo_point_t *b);
|
||||
|
|
|
|||
|
|
@ -287,9 +287,9 @@ image_diff_flattened (const char *filename_a,
|
|||
|
||||
b_flat_surface = cairo_image_surface_create_for_data (b_flat,
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
width_a, height_a,
|
||||
stride_a);
|
||||
/*cairo_surface_set_device_offset (b_flat_surface, -bx, -by);*/
|
||||
width_b, height_b,
|
||||
stride_b);
|
||||
cairo_surface_set_device_offset (b_flat_surface, -bx, -by);
|
||||
|
||||
cr = cairo_create (b_flat_surface);
|
||||
|
||||
|
|
@ -306,7 +306,7 @@ image_diff_flattened (const char *filename_a,
|
|||
b_flat,
|
||||
buf_diff,
|
||||
width_a, height_a,
|
||||
stride_a, stride_a, stride_a);
|
||||
stride_a, stride_b, stride_a);
|
||||
|
||||
if (pixels_changed) {
|
||||
FILE *png_file = fopen (filename_diff, "wb");
|
||||
|
|
|
|||
|
|
@ -1181,6 +1181,15 @@ ps_surface_write_to_png (cairo_surface_t *surface, const char *filename)
|
|||
ps_target_closure_t *ptc = cairo_surface_get_user_data (surface, &ps_closure_key);
|
||||
char command[4096];
|
||||
|
||||
/* Both surface and ptc->target were originally created at the
|
||||
* same dimensions. We want a 1:1 copy here, so we first clear any
|
||||
* device offset on surface.
|
||||
*
|
||||
* In a more realistic use case of device offsets, the target of
|
||||
* this copying would be of a different size than the source, and
|
||||
* the offset would be desirable during the copy operation. */
|
||||
cairo_surface_set_device_offset (surface, 0, 0);
|
||||
|
||||
if (ptc->target) {
|
||||
cairo_t *cr;
|
||||
cr = cairo_create (ptc->target);
|
||||
|
|
@ -1273,6 +1282,15 @@ pdf_surface_write_to_png (cairo_surface_t *surface, const char *filename)
|
|||
pdf_target_closure_t *ptc = cairo_surface_get_user_data (surface, &pdf_closure_key);
|
||||
char command[4096];
|
||||
|
||||
/* Both surface and ptc->target were originally created at the
|
||||
* same dimensions. We want a 1:1 copy here, so we first clear any
|
||||
* device offset on surface.
|
||||
*
|
||||
* In a more realistic use case of device offsets, the target of
|
||||
* this copying would be of a different size than the source, and
|
||||
* the offset would be desirable during the copy operation. */
|
||||
cairo_surface_set_device_offset (surface, 0, 0);
|
||||
|
||||
if (ptc->target) {
|
||||
cairo_t *cr;
|
||||
cr = cairo_create (ptc->target);
|
||||
|
|
@ -1427,6 +1445,11 @@ cairo_test_for_target (cairo_test_t *test,
|
|||
else
|
||||
offset_str = strdup("");
|
||||
|
||||
if (dev_offset)
|
||||
xasprintf (&offset_str, "-%d", dev_offset);
|
||||
else
|
||||
offset_str = strdup("");
|
||||
|
||||
xasprintf (&png_name, "%s-%s-%s%s%s", test->name,
|
||||
target->name, format, offset_str, CAIRO_TEST_PNG_SUFFIX);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue