Fix testing in the full mode for PDF, PS and SVG backends

Fix how offset, scale and transparency are handled.

Also do the same change in the "win32-printing" backend as it has a copy of the code from PDS, PS and SVG backends.
This commit is contained in:
Anton Danilkin 2020-11-11 17:33:31 +01:00 committed by Uli Schlachter
parent ab7b45feb7
commit b5175fd8a6
4 changed files with 103 additions and 48 deletions

View file

@ -120,16 +120,20 @@ _cairo_boilerplate_pdf_finish_surface (cairo_surface_t *surface)
&pdf_closure_key); &pdf_closure_key);
cairo_status_t status; cairo_status_t status;
/* 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) { if (ptc->target) {
/* 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 and scale 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. */
double x_offset, y_offset;
double x_scale, y_scale;
cairo_surface_get_device_offset (surface, &x_offset, &y_offset);
cairo_surface_get_device_scale (surface, &x_scale, &y_scale);
cairo_surface_set_device_offset (surface, 0, 0);
cairo_surface_set_device_scale (surface, 1, 1);
cairo_t *cr; cairo_t *cr;
cr = cairo_create (ptc->target); cr = cairo_create (ptc->target);
cairo_set_source_surface (cr, surface, 0, 0); cairo_set_source_surface (cr, surface, 0, 0);
@ -137,6 +141,8 @@ _cairo_boilerplate_pdf_finish_surface (cairo_surface_t *surface)
cairo_show_page (cr); cairo_show_page (cr);
status = cairo_status (cr); status = cairo_status (cr);
cairo_destroy (cr); cairo_destroy (cr);
cairo_surface_set_device_offset (surface, x_offset, y_offset);
cairo_surface_set_device_scale (surface, x_scale, y_scale);
if (status) if (status)
return status; return status;
@ -196,11 +202,14 @@ _cairo_boilerplate_pdf_get_image_surface (cairo_surface_t *surface,
int height) int height)
{ {
cairo_surface_t *image; cairo_surface_t *image;
double x_offset, y_offset;
double x_scale, y_scale;
image = _cairo_boilerplate_pdf_convert_to_image (surface, page); image = _cairo_boilerplate_pdf_convert_to_image (surface, page);
cairo_surface_set_device_offset (image, cairo_surface_get_device_offset (surface, &x_offset, &y_offset);
cairo_image_surface_get_width (image) - width, cairo_surface_get_device_scale (surface, &x_scale, &y_scale);
cairo_image_surface_get_height (image) - height); cairo_surface_set_device_offset (image, x_offset, y_offset);
cairo_surface_set_device_scale (image, x_scale, y_scale);
surface = _cairo_boilerplate_get_image_surface (image, 0, width, height); surface = _cairo_boilerplate_get_image_surface (image, 0, width, height);
cairo_surface_destroy (image); cairo_surface_destroy (image);

View file

@ -178,24 +178,29 @@ _cairo_boilerplate_ps_finish_surface (cairo_surface_t *surface)
&ps_closure_key); &ps_closure_key);
cairo_status_t status; cairo_status_t status;
/* 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) { if (ptc->target) {
/* 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 and scale 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. */
double x_offset, y_offset;
double x_scale, y_scale;
cairo_surface_get_device_offset (surface, &x_offset, &y_offset);
cairo_surface_get_device_scale (surface, &x_scale, &y_scale);
cairo_surface_set_device_offset (surface, 0, 0);
cairo_surface_set_device_scale (surface, 1, 1);
cairo_t *cr; cairo_t *cr;
cr = cairo_create (ptc->target); cr = cairo_create (ptc->target);
cairo_set_source_surface (cr, surface, 0, 0); cairo_set_source_surface (cr, surface, 0, 0);
cairo_paint (cr); cairo_paint (cr);
cairo_show_page (cr); cairo_show_page (cr);
status = cairo_status (cr); status = cairo_status (cr);
cairo_destroy (cr); cairo_destroy (cr);
cairo_surface_set_device_offset (surface, x_offset, y_offset);
cairo_surface_set_device_scale (surface, x_scale, y_scale);
if (status) if (status)
return status; return status;
@ -244,6 +249,8 @@ _cairo_boilerplate_ps_get_image_surface (cairo_surface_t *surface,
{ {
ps_target_closure_t *ptc = cairo_surface_get_user_data (surface, ps_target_closure_t *ptc = cairo_surface_get_user_data (surface,
&ps_closure_key); &ps_closure_key);
double x_offset, y_offset;
double x_scale, y_scale;
char *filename; char *filename;
cairo_status_t status; cairo_status_t status;
@ -259,15 +266,28 @@ _cairo_boilerplate_ps_get_image_surface (cairo_surface_t *surface,
free (filename); free (filename);
xasprintf (&filename, "%s-%05d.png", ptc->filename, page); xasprintf (&filename, "%s-%05d.png", ptc->filename, page);
} }
surface = cairo_boilerplate_get_image_surface_from_png (filename, cairo_surface_t *converted = cairo_boilerplate_get_image_surface_from_png (filename,
width, ptc->width,
height, ptc->height,
ptc->target == NULL); ptc->target == NULL);
remove (filename); remove (filename);
free (filename); free (filename);
return surface; cairo_surface_t *image = cairo_image_surface_create(ptc->target ? CAIRO_FORMAT_RGB24 : CAIRO_FORMAT_ARGB32,
width,
height);
cairo_surface_get_device_offset (surface, &x_offset, &y_offset);
cairo_surface_get_device_scale (surface, &x_scale, &y_scale);
cairo_surface_set_device_offset (converted, x_offset, y_offset);
cairo_surface_set_device_scale (converted, x_scale, y_scale);
cairo_t *cr = cairo_create (image);
cairo_set_source_surface (cr, converted, 0, 0);
cairo_paint (cr);
cairo_destroy (cr);
cairo_surface_destroy (converted);
return image;
} }
static void static void

View file

@ -152,16 +152,20 @@ _cairo_boilerplate_svg_finish_surface (cairo_surface_t *surface)
&svg_closure_key); &svg_closure_key);
cairo_status_t status; cairo_status_t status;
/* 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) { if (ptc->target) {
/* 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 and scale 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. */
double x_offset, y_offset;
double x_scale, y_scale;
cairo_surface_get_device_offset (surface, &x_offset, &y_offset);
cairo_surface_get_device_scale (surface, &x_scale, &y_scale);
cairo_surface_set_device_offset (surface, 0, 0);
cairo_surface_set_device_scale (surface, 1, 1);
cairo_t *cr; cairo_t *cr;
cr = cairo_create (ptc->target); cr = cairo_create (ptc->target);
cairo_set_source_surface (cr, surface, 0, 0); cairo_set_source_surface (cr, surface, 0, 0);
@ -169,6 +173,8 @@ _cairo_boilerplate_svg_finish_surface (cairo_surface_t *surface)
cairo_show_page (cr); cairo_show_page (cr);
status = cairo_status (cr); status = cairo_status (cr);
cairo_destroy (cr); cairo_destroy (cr);
cairo_surface_set_device_offset (surface, x_offset, y_offset);
cairo_surface_set_device_scale (surface, x_scale, y_scale);
if (status) if (status)
return status; return status;
@ -228,15 +234,29 @@ _cairo_boilerplate_svg_get_image_surface (cairo_surface_t *surface,
int height) int height)
{ {
cairo_surface_t *image; cairo_surface_t *image;
double x_offset, y_offset;
double x_scale, y_scale;
svg_target_closure_t *ptc = cairo_surface_get_user_data (surface,
&svg_closure_key);
if (page != 0) if (page != 0)
return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
image = _cairo_boilerplate_svg_convert_to_image (surface); image = _cairo_boilerplate_svg_convert_to_image (surface);
cairo_surface_set_device_offset (image, cairo_surface_get_device_offset (surface, &x_offset, &y_offset);
cairo_image_surface_get_width (image) - width, cairo_surface_get_device_scale (surface, &x_scale, &y_scale);
cairo_image_surface_get_height (image) - height); cairo_surface_set_device_offset (image, x_offset, y_offset);
cairo_surface_set_device_scale (image, x_scale, y_scale);
surface = _cairo_boilerplate_get_image_surface (image, 0, width, height); surface = _cairo_boilerplate_get_image_surface (image, 0, width, height);
if (ptc->target) {
cairo_surface_t *old_surface = surface;
surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
cairo_t *cr = cairo_create (surface);
cairo_set_source_surface (cr, old_surface, 0, 0);
cairo_paint (cr);
cairo_destroy (cr);
cairo_surface_destroy (old_surface);
}
cairo_surface_destroy (image); cairo_surface_destroy (image);
return surface; return surface;

View file

@ -270,22 +270,28 @@ _cairo_boilerplate_win32_printing_surface_write_to_png (cairo_surface_t *surface
cairo_t *cr; cairo_t *cr;
cairo_status_t status; cairo_status_t status;
/* 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) { if (ptc->target) {
/* 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 and scale 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. */
double x_offset, y_offset;
double x_scale, y_scale;
cairo_surface_get_device_offset (surface, &x_offset, &y_offset);
cairo_surface_get_device_scale (surface, &x_scale, &y_scale);
cairo_surface_set_device_offset (surface, 0, 0);
cairo_surface_set_device_scale (surface, 1, 1);
cairo_t *cr; cairo_t *cr;
cr = cairo_create (ptc->target); cr = cairo_create (ptc->target);
cairo_set_source_surface (cr, surface, 0, 0); cairo_set_source_surface (cr, surface, 0, 0);
cairo_paint (cr); cairo_paint (cr);
cairo_show_page (cr); cairo_show_page (cr);
cairo_destroy (cr); cairo_destroy (cr);
cairo_surface_set_device_offset (surface, x_offset, y_offset);
cairo_surface_set_device_scale (surface, x_scale, y_scale);
cairo_surface_finish (surface); cairo_surface_finish (surface);
surface = ptc->target; surface = ptc->target;