pdf: fix record-replay-extend test failures
|
|
@ -146,6 +146,7 @@ _analyze_recording_surface_pattern (cairo_analysis_surface_t *surface,
|
|||
cairo_surface_t *source, *proxy;
|
||||
cairo_matrix_t p2d, surface_transform;
|
||||
cairo_status_t status, analysis_status;
|
||||
cairo_bool_t surface_is_unbounded;
|
||||
cairo_bool_t unused;
|
||||
|
||||
assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE);
|
||||
|
|
@ -175,8 +176,12 @@ _analyze_recording_surface_pattern (cairo_analysis_surface_t *surface,
|
|||
surface_transform = tmp->ctm;
|
||||
status = cairo_matrix_invert (&surface_transform);
|
||||
source = _cairo_surface_get_source (source, NULL);
|
||||
surface_is_unbounded = (pattern->extend == CAIRO_EXTEND_REPEAT
|
||||
|| pattern->extend == CAIRO_EXTEND_REFLECT);
|
||||
status = _cairo_recording_surface_replay_and_create_regions (source,
|
||||
&surface_transform, &tmp->base);
|
||||
&surface_transform,
|
||||
&tmp->base,
|
||||
surface_is_unbounded);
|
||||
|
||||
if (!tmp->first_op)
|
||||
_cairo_box_add_box (&surface->page_bbox, &tmp->page_bbox);
|
||||
|
|
|
|||
|
|
@ -355,7 +355,7 @@ _paint_page (cairo_paginated_surface_t *surface)
|
|||
surface->backend->set_paginated_mode (surface->target,
|
||||
CAIRO_PAGINATED_MODE_ANALYZE);
|
||||
status = _cairo_recording_surface_replay_and_create_regions (surface->recording_surface,
|
||||
NULL, analysis);
|
||||
NULL, analysis, FALSE);
|
||||
if (status)
|
||||
goto FAIL;
|
||||
|
||||
|
|
|
|||
|
|
@ -166,6 +166,7 @@ struct _cairo_pdf_surface {
|
|||
double width;
|
||||
double height;
|
||||
cairo_rectangle_int_t surface_extents;
|
||||
cairo_bool_t surface_bounded;
|
||||
cairo_matrix_t cairo_to_pdf;
|
||||
cairo_bool_t in_xobject;
|
||||
|
||||
|
|
|
|||
|
|
@ -380,6 +380,7 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
|
|||
surface->surface_extents.y = 0;
|
||||
surface->surface_extents.width = ceil (surface->width);
|
||||
surface->surface_extents.height = ceil (surface->height);
|
||||
surface->surface_bounded = TRUE;
|
||||
|
||||
_cairo_array_init (&surface->objects, sizeof (cairo_pdf_object_t));
|
||||
_cairo_array_init (&surface->pages, sizeof (cairo_pdf_resource_t));
|
||||
|
|
@ -3028,6 +3029,7 @@ _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t *surface,
|
|||
{
|
||||
double old_width, old_height;
|
||||
cairo_rectangle_int_t old_surface_extents;
|
||||
cairo_bool_t old_surface_bounded;
|
||||
cairo_paginated_mode_t old_paginated_mode;
|
||||
cairo_surface_clipper_t old_clipper;
|
||||
cairo_bool_t old_in_xobject;
|
||||
|
|
@ -3069,16 +3071,17 @@ _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t *surface,
|
|||
old_height = surface->height;
|
||||
old_in_xobject = surface->in_xobject;
|
||||
old_surface_extents = surface->surface_extents;
|
||||
old_surface_bounded = surface->surface_bounded;
|
||||
old_paginated_mode = surface->paginated_mode;
|
||||
old_clipper = surface->clipper;
|
||||
surface->surface_extents = *extents;
|
||||
_cairo_surface_clipper_init (&surface->clipper,
|
||||
_cairo_pdf_surface_clipper_intersect_clip_path);
|
||||
|
||||
_cairo_pdf_surface_set_size_internal (surface, width, height);
|
||||
_cairo_pdf_operators_reset (&surface->pdf_operators);
|
||||
surface->in_xobject = TRUE;
|
||||
surface->surface_extents = *extents;
|
||||
surface->surface_bounded = FALSE;
|
||||
|
||||
/* Patterns are emitted after fallback images. The paginated mode
|
||||
* needs to be set to _RENDER while the recording surface is replayed
|
||||
|
|
@ -3131,13 +3134,11 @@ _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t *surface,
|
|||
|
||||
_cairo_surface_clipper_reset (&surface->clipper);
|
||||
surface->clipper = old_clipper;
|
||||
_cairo_pdf_surface_set_size_internal (surface,
|
||||
old_width,
|
||||
old_height);
|
||||
_cairo_pdf_operators_reset (&surface->pdf_operators);
|
||||
surface->in_xobject = old_in_xobject;
|
||||
surface->paginated_mode = old_paginated_mode;
|
||||
surface->surface_extents = old_surface_extents;
|
||||
surface->surface_bounded = old_surface_bounded;
|
||||
|
||||
err:
|
||||
cairo_surface_destroy (free_me);
|
||||
|
|
@ -3165,16 +3166,16 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
|
|||
cairo_extend_t extend = cairo_pattern_get_extend (pattern);
|
||||
double xstep, ystep;
|
||||
cairo_rectangle_int_t pattern_extents;
|
||||
int pattern_width = 0; /* squelch bogus compiler warning */
|
||||
int pattern_height = 0; /* squelch bogus compiler warning */
|
||||
double x_offset;
|
||||
double y_offset;
|
||||
char draw_surface[200];
|
||||
char draw_surface[50];
|
||||
char draw_surface2[200];
|
||||
cairo_box_double_t bbox;
|
||||
cairo_matrix_t mat;
|
||||
cairo_pdf_source_surface_entry_t *pdf_source;
|
||||
cairo_rectangle_int_t op_extents;
|
||||
|
||||
assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE);
|
||||
if (pattern->extend == CAIRO_EXTEND_PAD) {
|
||||
status = _cairo_pdf_surface_add_padded_image_surface (surface,
|
||||
pattern,
|
||||
|
|
@ -3202,8 +3203,6 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
|
|||
return status;
|
||||
|
||||
pattern_extents = pdf_source->extents;
|
||||
pattern_width = pdf_source->extents.width;
|
||||
pattern_height = pdf_source->extents.height;
|
||||
if (!pdf_source->bounded)
|
||||
{
|
||||
extend = CAIRO_EXTEND_NONE;
|
||||
|
|
@ -3238,13 +3237,12 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
|
|||
* required an answer that's large enough, we don't really
|
||||
* care if it's not as tight as possible.*/
|
||||
xstep = ystep = ceil ((x2 - x1) + (y2 - y1) +
|
||||
pattern_width + pattern_height);
|
||||
pattern_extents.width + pattern_extents.height);
|
||||
}
|
||||
break;
|
||||
|
||||
case CAIRO_EXTEND_REPEAT:
|
||||
xstep = pattern_width;
|
||||
ystep = pattern_height;
|
||||
xstep = pattern_extents.width;
|
||||
ystep = pattern_extents.height;
|
||||
break;
|
||||
|
||||
case CAIRO_EXTEND_REFLECT:
|
||||
|
|
@ -3303,11 +3301,11 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
|
|||
cairo_matrix_translate (&pdf_p2d, x_offset, y_offset);
|
||||
if (((cairo_surface_pattern_t *)pattern)->surface->type != CAIRO_SURFACE_TYPE_RECORDING)
|
||||
{
|
||||
cairo_matrix_translate (&pdf_p2d, 0.0, pattern_height);
|
||||
cairo_matrix_translate (&pdf_p2d, 0.0, pdf_source->extents.height);
|
||||
cairo_matrix_scale (&pdf_p2d, 1.0, -1.0);
|
||||
}
|
||||
|
||||
_get_bbox_from_extents (pattern_height, &pattern_extents, &bbox);
|
||||
_get_bbox_from_extents (pattern_extents.height, &pattern_extents, &bbox);
|
||||
_cairo_pdf_surface_update_object (surface, pdf_pattern->pattern_res);
|
||||
status = _cairo_pdf_surface_open_stream (surface,
|
||||
&pdf_pattern->pattern_res,
|
||||
|
|
@ -3330,35 +3328,54 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
|
|||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE &&
|
||||
((cairo_surface_pattern_t *) pattern)->surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
|
||||
if (((cairo_surface_pattern_t *) pattern)->surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
|
||||
snprintf(draw_surface,
|
||||
sizeof (draw_surface),
|
||||
"/x%d Do\n",
|
||||
"/x%d Do",
|
||||
pdf_source->surface_res.id);
|
||||
} else {
|
||||
snprintf(draw_surface,
|
||||
sizeof (draw_surface),
|
||||
"q %d 0 0 %d 0 0 cm /x%d Do Q",
|
||||
pattern_width,
|
||||
pattern_height,
|
||||
pdf_source->extents.width,
|
||||
pdf_source->extents.height,
|
||||
pdf_source->surface_res.id);
|
||||
}
|
||||
|
||||
if (extend == CAIRO_EXTEND_REFLECT) {
|
||||
_cairo_output_stream_printf (surface->output,
|
||||
"q 0 0 %d %d re W n %s Q\n"
|
||||
"q -1 0 0 1 %d 0 cm 0 0 %d %d re W n %s Q\n"
|
||||
"q 1 0 0 -1 0 %d cm 0 0 %d %d re W n %s Q\n"
|
||||
"q -1 0 0 -1 %d %d cm 0 0 %d %d re W n %s Q\n",
|
||||
pattern_width, pattern_height,
|
||||
draw_surface,
|
||||
pattern_width*2, pattern_width, pattern_height,
|
||||
draw_surface,
|
||||
pattern_height*2, pattern_width, pattern_height,
|
||||
draw_surface,
|
||||
pattern_width*2, pattern_height*2, pattern_width, pattern_height,
|
||||
draw_surface);
|
||||
cairo_rectangle_int_t p_extents = pdf_source->extents;
|
||||
snprintf(draw_surface2,
|
||||
sizeof (draw_surface2),
|
||||
"%d %d %d %d re W n %s",
|
||||
p_extents.x, p_extents.y,
|
||||
p_extents.width, p_extents.height,
|
||||
draw_surface);
|
||||
|
||||
_cairo_output_stream_printf (surface->output, "q %s Q\n", draw_surface2);
|
||||
|
||||
cairo_matrix_init_translate (&mat, p_extents.x, p_extents.y);
|
||||
cairo_matrix_scale (&mat, -1, 1);
|
||||
cairo_matrix_translate (&mat, -2*p_extents.width, 0);
|
||||
cairo_matrix_translate (&mat, -p_extents.x, -p_extents.y);
|
||||
_cairo_output_stream_printf (surface->output, "q ");
|
||||
_cairo_output_stream_print_matrix (surface->output, &mat);
|
||||
_cairo_output_stream_printf (surface->output, " cm %s Q\n", draw_surface2);
|
||||
|
||||
cairo_matrix_init_translate (&mat, p_extents.x, p_extents.y);
|
||||
cairo_matrix_scale (&mat, 1, -1);
|
||||
cairo_matrix_translate (&mat, 0, -2*p_extents.height);
|
||||
cairo_matrix_translate (&mat, -p_extents.x, -p_extents.y);
|
||||
_cairo_output_stream_printf (surface->output, "q ");
|
||||
_cairo_output_stream_print_matrix (surface->output, &mat);
|
||||
_cairo_output_stream_printf (surface->output, " cm %s Q\n", draw_surface2);
|
||||
|
||||
cairo_matrix_init_translate (&mat, p_extents.x, p_extents.y);
|
||||
cairo_matrix_scale (&mat, -1, -1);
|
||||
cairo_matrix_translate (&mat, -2*p_extents.width, -2*p_extents.height);
|
||||
cairo_matrix_translate (&mat, -p_extents.x, -p_extents.y);
|
||||
_cairo_output_stream_printf (surface->output, "q ");
|
||||
_cairo_output_stream_print_matrix (surface->output, &mat);
|
||||
_cairo_output_stream_printf (surface->output, " cm %s Q\n", draw_surface2);
|
||||
} else {
|
||||
_cairo_output_stream_printf (surface->output,
|
||||
" %s \n",
|
||||
|
|
@ -4681,9 +4698,10 @@ _cairo_pdf_surface_get_extents (void *abstract_surface,
|
|||
{
|
||||
cairo_pdf_surface_t *surface = abstract_surface;
|
||||
|
||||
*rectangle = surface->surface_extents;
|
||||
if (surface->surface_bounded)
|
||||
*rectangle = surface->surface_extents;
|
||||
|
||||
return TRUE;
|
||||
return surface->surface_bounded;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -6280,9 +6298,11 @@ _cairo_pdf_surface_write_smask_group (cairo_pdf_surface_t *surface,
|
|||
cairo_bool_t old_in_xobject;
|
||||
cairo_int_status_t status;
|
||||
cairo_box_double_t bbox;
|
||||
cairo_rectangle_int_t old_surface_extents;
|
||||
|
||||
old_width = surface->width;
|
||||
old_height = surface->height;
|
||||
old_surface_extents = surface->surface_extents;
|
||||
old_in_xobject = surface->in_xobject;
|
||||
surface->in_xobject = TRUE;
|
||||
_cairo_pdf_surface_set_size_internal (surface,
|
||||
|
|
@ -6352,6 +6372,7 @@ RESTORE_SIZE:
|
|||
_cairo_pdf_surface_set_size_internal (surface,
|
||||
old_width,
|
||||
old_height);
|
||||
surface->surface_extents = old_surface_extents;
|
||||
_cairo_pdf_operators_reset (&surface->pdf_operators);
|
||||
|
||||
return status;
|
||||
|
|
|
|||
|
|
@ -170,7 +170,8 @@ _cairo_recording_surface_replay_with_clip (cairo_surface_t *surface,
|
|||
cairo_private cairo_status_t
|
||||
_cairo_recording_surface_replay_and_create_regions (cairo_surface_t *surface,
|
||||
const cairo_matrix_t *surface_transform,
|
||||
cairo_surface_t *target);
|
||||
cairo_surface_t *target,
|
||||
cairo_bool_t surface_is_unbounded);
|
||||
cairo_private cairo_status_t
|
||||
_cairo_recording_surface_replay_region (cairo_surface_t *surface,
|
||||
const cairo_rectangle_int_t *surface_extents,
|
||||
|
|
|
|||
|
|
@ -725,10 +725,6 @@ _cairo_recording_surface_paint (void *abstract_surface,
|
|||
(surface->base.is_clear || _cairo_pattern_is_opaque_solid (source)))))
|
||||
{
|
||||
_cairo_recording_surface_reset (surface);
|
||||
if (is_identity_recording_pattern (source)) {
|
||||
cairo_surface_t *src = ((cairo_surface_pattern_t *)source)->surface;
|
||||
return _cairo_recording_surface_replay (src, &surface->base);
|
||||
}
|
||||
}
|
||||
|
||||
status = _cairo_composite_rectangles_init_for_paint (&composite,
|
||||
|
|
@ -1676,6 +1672,7 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t *surface,
|
|||
const cairo_matrix_t *surface_transform,
|
||||
cairo_surface_t *target,
|
||||
const cairo_clip_t *target_clip,
|
||||
cairo_bool_t surface_is_unbounded,
|
||||
cairo_recording_replay_type_t type,
|
||||
cairo_recording_region_type_t region)
|
||||
{
|
||||
|
|
@ -1708,7 +1705,7 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t *surface,
|
|||
if (surface_extents)
|
||||
_cairo_surface_wrapper_intersect_extents (&wrapper, surface_extents);
|
||||
r = &_cairo_unbounded_rectangle;
|
||||
if (! surface->unbounded) {
|
||||
if (! surface->unbounded && !surface_is_unbounded) {
|
||||
_cairo_surface_wrapper_intersect_extents (&wrapper, &surface->extents);
|
||||
r = &surface->extents;
|
||||
}
|
||||
|
|
@ -1716,7 +1713,7 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t *surface,
|
|||
_cairo_surface_wrapper_set_clip (&wrapper, target_clip);
|
||||
|
||||
/* Compute the extents of the target clip in recorded device space */
|
||||
if (! _cairo_surface_wrapper_get_target_extents (&wrapper, &extents))
|
||||
if (! _cairo_surface_wrapper_get_target_extents (&wrapper, surface_is_unbounded, &extents))
|
||||
goto done;
|
||||
|
||||
surface->has_bilevel_alpha = TRUE;
|
||||
|
|
@ -2001,7 +1998,7 @@ _cairo_recording_surface_replay (cairo_surface_t *surface,
|
|||
cairo_surface_t *target)
|
||||
{
|
||||
return _cairo_recording_surface_replay_internal ((cairo_recording_surface_t *) surface, NULL, NULL,
|
||||
target, NULL,
|
||||
target, NULL, FALSE,
|
||||
CAIRO_RECORDING_REPLAY,
|
||||
CAIRO_RECORDING_REGION_ALL);
|
||||
}
|
||||
|
|
@ -2013,7 +2010,7 @@ _cairo_recording_surface_replay_with_clip (cairo_surface_t *surface,
|
|||
const cairo_clip_t *target_clip)
|
||||
{
|
||||
return _cairo_recording_surface_replay_internal ((cairo_recording_surface_t *) surface, NULL, surface_transform,
|
||||
target, target_clip,
|
||||
target, target_clip, FALSE,
|
||||
CAIRO_RECORDING_REPLAY,
|
||||
CAIRO_RECORDING_REGION_ALL);
|
||||
}
|
||||
|
|
@ -2027,10 +2024,12 @@ _cairo_recording_surface_replay_with_clip (cairo_surface_t *surface,
|
|||
cairo_status_t
|
||||
_cairo_recording_surface_replay_and_create_regions (cairo_surface_t *surface,
|
||||
const cairo_matrix_t *surface_transform,
|
||||
cairo_surface_t *target)
|
||||
cairo_surface_t *target,
|
||||
cairo_bool_t surface_is_unbounded)
|
||||
{
|
||||
return _cairo_recording_surface_replay_internal ((cairo_recording_surface_t *) surface, NULL, surface_transform,
|
||||
target, NULL,
|
||||
surface_is_unbounded,
|
||||
CAIRO_RECORDING_CREATE_REGIONS,
|
||||
CAIRO_RECORDING_REGION_ALL);
|
||||
}
|
||||
|
|
@ -2043,7 +2042,7 @@ _cairo_recording_surface_replay_region (cairo_surface_t *surface,
|
|||
{
|
||||
return _cairo_recording_surface_replay_internal ((cairo_recording_surface_t *) surface,
|
||||
surface_extents, NULL,
|
||||
target, NULL,
|
||||
target, NULL, FALSE,
|
||||
CAIRO_RECORDING_REPLAY,
|
||||
region);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -186,6 +186,7 @@ _cairo_surface_wrapper_is_active (cairo_surface_wrapper_t *wrapper)
|
|||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_surface_wrapper_get_target_extents (cairo_surface_wrapper_t *wrapper,
|
||||
cairo_bool_t surface_is_unbounded,
|
||||
cairo_rectangle_int_t *extents);
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
|
|
|||
|
|
@ -625,12 +625,15 @@ _cairo_surface_wrapper_fini (cairo_surface_wrapper_t *wrapper)
|
|||
|
||||
cairo_bool_t
|
||||
_cairo_surface_wrapper_get_target_extents (cairo_surface_wrapper_t *wrapper,
|
||||
cairo_bool_t surface_is_unbounded,
|
||||
cairo_rectangle_int_t *extents)
|
||||
{
|
||||
cairo_rectangle_int_t clip;
|
||||
cairo_bool_t has_clip;
|
||||
cairo_bool_t has_clip = FALSE;
|
||||
|
||||
if (!surface_is_unbounded)
|
||||
has_clip = _cairo_surface_get_extents (wrapper->target, &clip);
|
||||
|
||||
has_clip = _cairo_surface_get_extents (wrapper->target, &clip);
|
||||
if (wrapper->clip) {
|
||||
if (has_clip) {
|
||||
if (! _cairo_rectangle_intersect (&clip,
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 520 B After Width: | Height: | Size: 477 B |
|
Before Width: | Height: | Size: 520 B After Width: | Height: | Size: 477 B |
BIN
test/reference/record-replay-extend-none.pdf.argb32.ref.png
Normal file
|
After Width: | Height: | Size: 737 B |
BIN
test/reference/record-replay-extend-none.pdf.rgb24.ref.png
Normal file
|
After Width: | Height: | Size: 472 B |
BIN
test/reference/record-replay-extend-pad.pdf.argb32.ref.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
test/reference/record-replay-extend-reflect.pdf.argb32.ref.png
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
test/reference/record-replay-extend-reflect.pdf.rgb24.ref.png
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
BIN
test/reference/record-replay-extend-repeat.pdf.argb32.ref.png
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
test/reference/record-replay-extend-repeat.pdf.rgb24.ref.png
Normal file
|
After Width: | Height: | Size: 7.4 KiB |