diff options
author | Ken Sharp <ken.sharp@artifex.com> | 2023-03-09 14:05:47 +0000 |
---|---|---|
committer | Ken Sharp <ken.sharp@artifex.com> | 2023-03-09 14:07:23 +0000 |
commit | f00a2966ec40cf9d593e1b6e52f5cd656ae32402 (patch) | |
tree | 788652badb53bd202a1722f5d81d03b9b11cdbe8 /devices | |
parent | 7c8a46b827063bea9318f30479eb7d6e519970c3 (diff) | |
download | ghostpdl-f00a2966ec40cf9d593e1b6e52f5cd656ae32402.tar.gz |
pdfwrite - Fix missing shading case
Bug #706453 "Element missing while converting pdf from rgb to cmyk using Ghostscript"
When converting a shading to an image (for ps2write or certain cases of
colour converting shadings with pdfwrite) it is possible that the
shading functions only call fill_trapezoid() and not fill_path().
This can result in us reaching dump_converted_image with
cvd->mask_is_empty and cvd->path_is_empty both true and we would then not
write out the rendered image.
Because of the convoluted nature of this code (which I am convinced is
sub-optimal!) simply setting either mask_is_empty and/or path_is_empty
to false results in incorrect rendering. So here we add a new boolean
'filled_trap' and add a case to deal with that after testing all the
other conditions.
This results in distinct progressions with ps2write and thee files:
/tests_private/comparefiles/Bug689189.pdf
/tests_private/comparefiles/Clarke-Tate-Manns-Chinese.ai
The file /tests_private/comparefiles/Bug691775.pdf shows diffs that
are imperceptible by eye.
Diffstat (limited to 'devices')
-rw-r--r-- | devices/vector/gdevpdfd.c | 22 | ||||
-rw-r--r-- | devices/vector/gdevpdfx.h | 1 |
2 files changed, 22 insertions, 1 deletions
diff --git a/devices/vector/gdevpdfd.c b/devices/vector/gdevpdfd.c index 96d60ea13..fb55655c9 100644 --- a/devices/vector/gdevpdfd.c +++ b/devices/vector/gdevpdfd.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2022 Artifex Software, Inc. +/* Copyright (C) 2001-2023 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -1397,7 +1397,12 @@ pdf_dump_converted_image(gx_device_pdf *pdev, pdf_lcvd_t *cvd, int for_pattern) stream_puts(pdev->strm, "q\n"); code = write_image_with_clip(pdev, cvd, for_pattern); stream_puts(pdev->strm, "Q\n"); + } else if (cvd->filled_trap){ + stream_puts(pdev->strm, "q\n"); + code = write_image_with_clip(pdev, cvd, for_pattern); + stream_puts(pdev->strm, "Q\n"); } + cvd->filled_trap = false; cvd->mdev.width += cvd->mdev.mapped_x; cvd->mdev.height += cvd->mdev.mapped_y; if (code > 0) @@ -1406,6 +1411,19 @@ pdf_dump_converted_image(gx_device_pdf *pdev, pdf_lcvd_t *cvd, int for_pattern) return code; } static int +lcvd_fill_trapezoid(gx_device * dev, const gs_fixed_edge * left, + const gs_fixed_edge * right, fixed ybot, fixed ytop, bool swap_axes, + const gx_device_color * pdevc, gs_logical_operation_t lop) +{ + int code = 0; + pdf_lcvd_t *cvd = (pdf_lcvd_t *)dev; + + if (cvd->mask != NULL) + cvd->filled_trap = true; + return gx_default_fill_trapezoid(dev, left, right, ybot, ytop, swap_axes, pdevc, lop); +} + +static int lcvd_handle_fill_path_as_shading_coverage(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, const gx_fill_params *params, @@ -1539,6 +1557,7 @@ pdf_setup_masked_image_converter(gx_device_pdf *pdev, gs_memory_t *mem, const gs cvd->path_is_empty = true; cvd->mask_is_empty = true; cvd->mask_is_clean = false; + cvd->filled_trap = false; cvd->has_background = false; cvd->mask = 0; cvd->write_matrix = true; @@ -1588,6 +1607,7 @@ pdf_setup_masked_image_converter(gx_device_pdf *pdev, gs_memory_t *mem, const gs dev_proc(&cvd->mdev, dev_spec_op) = lcvd_dev_spec_op; dev_proc(&cvd->mdev, fill_path) = lcvd_handle_fill_path_as_shading_coverage; dev_proc(&cvd->mdev, transform_pixel_region) = lcvd_transform_pixel_region; + dev_proc(&cvd->mdev, fill_trapezoid) = lcvd_fill_trapezoid; cvd->m = *m; if (write_on_close) { cvd->mdev.is_open = true; diff --git a/devices/vector/gdevpdfx.h b/devices/vector/gdevpdfx.h index e2b7c98d5..c7d564f96 100644 --- a/devices/vector/gdevpdfx.h +++ b/devices/vector/gdevpdfx.h @@ -1282,6 +1282,7 @@ typedef struct pdf_lcvd_s { bool mask_is_empty; bool path_is_empty; bool mask_is_clean; + bool filled_trap; bool write_matrix; bool has_background; gs_matrix m; |