summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'devices/vector')
-rw-r--r--devices/vector/doc_common.c16
-rw-r--r--devices/vector/doc_common.h15
-rw-r--r--devices/vector/gdevdocxw.c16
-rw-r--r--devices/vector/gdevpdf.c150
-rw-r--r--devices/vector/gdevpdfb.c53
-rw-r--r--devices/vector/gdevpdfb.h7
-rw-r--r--devices/vector/gdevpdfd.c30
-rw-r--r--devices/vector/gdevpdfe.c34
-rw-r--r--devices/vector/gdevpdfg.c2
-rw-r--r--devices/vector/gdevpdfi.c15
-rw-r--r--devices/vector/gdevpdfj.c6
-rw-r--r--devices/vector/gdevpdfo.c2
-rw-r--r--devices/vector/gdevpdfp.c31
-rw-r--r--devices/vector/gdevpdft.c8
-rw-r--r--devices/vector/gdevpdfu.c7
-rw-r--r--devices/vector/gdevpdfx.h9
-rw-r--r--devices/vector/gdevpdte.c2
-rw-r--r--devices/vector/gdevpdtt.c38
-rw-r--r--devices/vector/gdevpsdp.c20
-rw-r--r--devices/vector/gdevpsft.c10
-rw-r--r--devices/vector/gdevpsu.c8
-rw-r--r--devices/vector/gdevtxtw.c22
-rw-r--r--devices/vector/gdevxps.c19
23 files changed, 361 insertions, 159 deletions
diff --git a/devices/vector/doc_common.c b/devices/vector/doc_common.c
index c7d38836..4575aea4 100644
--- a/devices/vector/doc_common.c
+++ b/devices/vector/doc_common.c
@@ -1,3 +1,18 @@
+/* Copyright (C) 2018-2022 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied,
+ modified or distributed except as expressly authorized under the terms
+ of the license contained in the file LICENSE in this distribution.
+
+ Refer to licensing information at http://www.artifex.com or contact
+ Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato,
+ CA 94945, U.S.A., +1(415)492-9861, for further information.
+*/
+
#include "doc_common.h"
#include "gxfont.h"
@@ -32,6 +47,7 @@ font_orig_matrix(const gs_font *font, gs_glyph cid, gs_matrix *pmat)
case ft_encrypted2:
case ft_CID_encrypted:
case ft_user_defined:
+ case ft_PDF_user_defined:
case ft_PCL_user_defined:
case ft_GL2_stick_user_defined:
case ft_GL2_531:
diff --git a/devices/vector/doc_common.h b/devices/vector/doc_common.h
index 24369054..08fba48b 100644
--- a/devices/vector/doc_common.h
+++ b/devices/vector/doc_common.h
@@ -1,3 +1,18 @@
+/* Copyright (C) 2018-2022 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied,
+ modified or distributed except as expressly authorized under the terms
+ of the license contained in the file LICENSE in this distribution.
+
+ Refer to licensing information at http://www.artifex.com or contact
+ Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato,
+ CA 94945, U.S.A., +1(415)492-9861, for further information.
+*/
+
#ifndef gdevtxtw_INCLUDED
#define gdevtxtw_INCLUDED
diff --git a/devices/vector/gdevdocxw.c b/devices/vector/gdevdocxw.c
index b637a4c8..7783bff4 100644
--- a/devices/vector/gdevdocxw.c
+++ b/devices/vector/gdevdocxw.c
@@ -273,7 +273,8 @@ docxwrite_open_device(gx_device * dev)
code = s_errno_to_gs();
goto end;
}
- if (extract_page_begin(tdev->extract)) {
+ /* Pass dummy page bbox for now; our simple use of extract ignores it. */
+ if (extract_page_begin(tdev->extract, 0, 0, 0, 0)) {
code = s_errno_to_gs();
goto end;
}
@@ -383,7 +384,8 @@ docxwrite_output_page(gx_device * dev, int num_copies, int flush)
goto end;
}
}
- if (extract_page_begin(tdev->extract)) {
+ /* Pass dummy page bbox for now; our simple use of extract ignores it. */
+ if (extract_page_begin(tdev->extract, 0, 0, 0, 0)) {
code = s_errno_to_gs();
goto end;
}
@@ -939,13 +941,16 @@ docxwrite_process_cmap_text(gx_device_docxwrite_t *tdev, gs_text_enum_t *pte)
txt_get_unicode(penum->dev, (gs_font *)pte->orig_font, glyph, chr, &buffer[0]);
+ /* Pass dummy glyph bbox because our use of extract does not
+ currently cause it to be used. */
if (extract_add_char(
tdev->extract,
tdev->x,
fixed2float(penum->origin.y) - penum->text_state->matrix.ty,
buffer[0] /*ucs*/,
glyph_width / penum->text_state->size /*adv*/,
- 0 /*autosplit*/
+ 0 /*autosplit*/,
+ 0, 0, 0, 0 /* bbox*/
)) {
return s_errno_to_gs();
}
@@ -1095,13 +1100,16 @@ docxwrite_process_plain_text(gx_device_docxwrite_t *tdev, gs_text_enum_t *pte)
* 'extra' code points' widths to 0.
*/
+ /* Pass dummy glyph bbox because our use of extract does not currently
+ cause it to be used. */
if (extract_add_char(
tdev->extract,
tdev->x,
fixed2float(penum->origin.y) - penum->text_state->matrix.ty,
chr2[0] /*ucs*/,
glyph_width / penum->text_state->size /*adv*/,
- 0 /*autosplit*/
+ 0 /*autosplit*/,
+ 0, 0, 0, 0 /*bbox*/
)) {
return s_errno_to_gs();
}
diff --git a/devices/vector/gdevpdf.c b/devices/vector/gdevpdf.c
index cb268f62..40beb06a 100644
--- a/devices/vector/gdevpdf.c
+++ b/devices/vector/gdevpdf.c
@@ -425,6 +425,7 @@ pdf_initialize_ids(gx_device_pdf * pdev)
* date and time, rather than (for example) %%CreationDate from the
* PostScript file. We think this is wrong, but we do the same.
*/
+ if (!pdev->OmitInfoDate)
{
struct tm tms;
time_t t;
@@ -466,6 +467,7 @@ pdf_initialize_ids(gx_device_pdf * pdev)
static int
pdf_compute_fileID(gx_device_pdf * pdev)
{
+
/* We compute a file identifier when beginning a document
to allow its usage with PDF encryption. Due to that,
in contradiction to the Adobe recommendation, our
@@ -933,10 +935,14 @@ pdf_ferror(gx_device_pdf *pdev)
{
gp_fflush(pdev->file);
gp_fflush(pdev->xref.file);
- sflush(pdev->strm);
- sflush(pdev->asides.strm);
- sflush(pdev->streams.strm);
- sflush(pdev->pictures.strm);
+ if (pdev->strm->file != NULL)
+ sflush(pdev->strm);
+ if (pdev->asides.strm->file != NULL)
+ sflush(pdev->asides.strm);
+ if (pdev->streams.strm->file != NULL)
+ sflush(pdev->streams.strm);
+ if (pdev->pictures.strm->file != NULL)
+ sflush(pdev->pictures.strm);
return gp_ferror(pdev->file) || gp_ferror(pdev->xref.file) ||
gp_ferror(pdev->asides.file) || gp_ferror(pdev->streams.file) ||
gp_ferror(pdev->pictures.file);
@@ -1139,13 +1145,14 @@ pdf_write_page(gx_device_pdf *pdev, int page_num)
pdf_page_t *page;
double mediabox[4] = {0, 0};
stream *s;
- const cos_value_t *v_mediabox;
+ const cos_value_t *v_mediabox = NULL;
if (pdev->pages == NULL)
return_error(gs_error_undefined);
page = &pdev->pages[page_num - 1];
- v_mediabox = cos_dict_find_c_key(page->Page, "/MediaBox");
+ if (page->Page != NULL)
+ v_mediabox = cos_dict_find_c_key(page->Page, "/MediaBox");
page_id = pdf_page_id(pdev, page_num);
/* If we have not been given a MediaBox overriding pdfmark, use the current media size. */
@@ -1170,7 +1177,8 @@ pdf_write_page(gx_device_pdf *pdev, int page_num)
buf[l] = 0;
if (sscanf(buf, "[ %g %g %g %g ]",
&temp[0], &temp[1], &temp[2], &temp[3]) == 4) {
- cos_dict_delete_c_key(page->Page, "/MediaBox");
+ if (page->Page)
+ cos_dict_delete_c_key(page->Page, "/MediaBox");
}
pprintg4(s, "<</Type/Page/MediaBox [%g %g %g %g]\n",
temp[0], temp[1], temp[2], temp[3]);
@@ -1178,13 +1186,20 @@ pdf_write_page(gx_device_pdf *pdev, int page_num)
mediabox[i] = temp[i];
}
if (pdev->PDFX) {
- const cos_value_t *v_trimbox = cos_dict_find_c_key(page->Page, "/TrimBox");
- const cos_value_t *v_artbox = cos_dict_find_c_key(page->Page, "/ArtBox");
- const cos_value_t *v_cropbox = cos_dict_find_c_key(page->Page, "/CropBox");
- const cos_value_t *v_bleedbox = cos_dict_find_c_key(page->Page, "/BleedBox");
- double trimbox[4] = {0, 0}, bleedbox[4] = {0, 0};
+ const cos_value_t *v_trimbox = NULL;
+ const cos_value_t *v_artbox = NULL;
+ const cos_value_t *v_cropbox = NULL;
+ const cos_value_t *v_bleedbox = NULL;
+ float trimbox[4] = {0, 0}, bleedbox[4] = {0, 0};
bool print_bleedbox = false;
+ if (page->Page != NULL) {
+ v_trimbox = cos_dict_find_c_key(page->Page, "/TrimBox");
+ v_artbox = cos_dict_find_c_key(page->Page, "/ArtBox");
+ v_cropbox = cos_dict_find_c_key(page->Page, "/CropBox");
+ v_bleedbox = cos_dict_find_c_key(page->Page, "/BleedBox");
+ }
+
trimbox[2] = bleedbox[2] = mediabox[2];
trimbox[3] = bleedbox[3] = mediabox[3];
/* Offsets are [left right top bottom] according to the Acrobat 7.0
@@ -1203,9 +1218,10 @@ pdf_write_page(gx_device_pdf *pdev, int page_num)
trimbox[1] = temp[1];
trimbox[2] = temp[2];
trimbox[3] = temp[3];
- cos_dict_delete_c_key(page->Page, "/TrimBox");
+ if (page->Page != NULL)
+ cos_dict_delete_c_key(page->Page, "/TrimBox");
}
- if (v_artbox != NULL && v_artbox->value_type == COS_VALUE_SCALAR)
+ if (v_artbox != NULL && v_artbox->value_type == COS_VALUE_SCALAR && page->Page != NULL)
cos_dict_delete_c_key(page->Page, "/ArtBox");
} else if (v_artbox != NULL && v_artbox->value_type == COS_VALUE_SCALAR) {
@@ -1225,7 +1241,8 @@ pdf_write_page(gx_device_pdf *pdev, int page_num)
trimbox[1] = temp[1];
trimbox[2] = temp[2];
trimbox[3] = temp[3];
- cos_dict_delete_c_key(page->Page, "/ArtBox");
+ if (page->Page != NULL)
+ cos_dict_delete_c_key(page->Page, "/ArtBox");
}
} else {
if (pdev->PDFXTrimBoxToMediaBoxOffset.size >= 4 &&
@@ -1267,7 +1284,8 @@ pdf_write_page(gx_device_pdf *pdev, int page_num)
else
bleedbox[3] = temp[3];
print_bleedbox = true;
- cos_dict_delete_c_key(page->Page, "/BleedBox");
+ if (page->Page != NULL)
+ cos_dict_delete_c_key(page->Page, "/BleedBox");
}
} else if (pdev->PDFXSetBleedBoxToMediaBox)
print_bleedbox = true;
@@ -1330,7 +1348,8 @@ pdf_write_page(gx_device_pdf *pdev, int page_num)
buf[l] = 0;
if (sscanf(buf, "[ %g %g %g %g ]",
&temp[0], &temp[1], &temp[2], &temp[3]) == 4) {
- cos_dict_delete_c_key(page->Page, "/CropBox");
+ if (page->Page != NULL)
+ cos_dict_delete_c_key(page->Page, "/CropBox");
/* Ensure that CropBox is no larger than MediaBox. The spec says *nothing* about
* this, but Acrobat Preflight complains if it is larger. This can happen because
* we apply 'round_box_coord' to the mediabox at the start of this rouinte.
@@ -1386,14 +1405,16 @@ pdf_write_page(gx_device_pdf *pdev, int page_num)
}
}
- if (cos_dict_find_c_key(page->Page, "/TrimBox") == NULL &&
- cos_dict_find_c_key(page->Page, "/ArtBox") == NULL)
- pprintg4(s, "/TrimBox [%g %g %g %g]\n",
- trimbox[0], trimbox[1], trimbox[2], trimbox[3]);
- if (print_bleedbox &&
- cos_dict_find_c_key(page->Page, "/BleedBox") == NULL)
- pprintg4(s, "/BleedBox [%g %g %g %g]\n",
- bleedbox[0], bleedbox[1], bleedbox[2], bleedbox[3]);
+ if (page->Page != NULL) {
+ if (cos_dict_find_c_key(page->Page, "/TrimBox") == NULL &&
+ cos_dict_find_c_key(page->Page, "/ArtBox") == NULL)
+ pprintg4(s, "/TrimBox [%g %g %g %g]\n",
+ trimbox[0], trimbox[1], trimbox[2], trimbox[3]);
+ if (print_bleedbox &&
+ cos_dict_find_c_key(page->Page, "/BleedBox") == NULL)
+ pprintg4(s, "/BleedBox [%g %g %g %g]\n",
+ bleedbox[0], bleedbox[1], bleedbox[2], bleedbox[3]);
+ }
}
pdf_print_orientation(pdev, page);
if (page->UserUnit != 1)
@@ -1480,7 +1501,8 @@ pdf_write_page(gx_device_pdf *pdev, int page_num)
/* Write any elements stored by pdfmarks. */
- cos_dict_elements_write(page->Page, pdev);
+ if (page->Page != NULL)
+ cos_dict_elements_write(page->Page, pdev);
stream_puts(s, ">>\n");
pdf_end_obj(pdev, resourcePage);
@@ -1906,7 +1928,11 @@ static int pdf_linearise(gx_device_pdf *pdev, pdf_linearisation_t *linear_params
* +1 for the linearisation dict and +1 for the primary hint stream.
*/
linear_params->FirsttrailerOffset = gp_ftell(linear_params->Lin_File.file);
- gs_snprintf(LDict, sizeof(LDict), "\ntrailer\n<</Size %ld/Info %d 0 R/Root %d 0 R/ID[%s%s]/Prev %d>>\nstartxref\r\n0\n%%%%EOF\n \n",
+ if (pdev->OmitID)
+ gs_snprintf(LDict, sizeof(LDict), "\ntrailer\n<</Size %ld/Info %d 0 R/Root %d 0 R/Prev %d>>\nstartxref\r\n0\n%%%%EOF\n \n",
+ linear_params->LastResource + 3, pdev->ResourceUsage[linear_params->Info_id].NewObjectNumber, pdev->ResourceUsage[linear_params->Catalog_id].NewObjectNumber, 0);
+ else
+ gs_snprintf(LDict, sizeof(LDict), "\ntrailer\n<</Size %ld/Info %d 0 R/Root %d 0 R/ID[%s%s]/Prev %d>>\nstartxref\r\n0\n%%%%EOF\n \n",
linear_params->LastResource + 3, pdev->ResourceUsage[linear_params->Info_id].NewObjectNumber, pdev->ResourceUsage[linear_params->Catalog_id].NewObjectNumber, fileID, fileID, 0);
gp_fwrite(LDict, strlen(LDict), 1, linear_params->Lin_File.file);
@@ -2442,7 +2468,11 @@ static int pdf_linearise(gx_device_pdf *pdev, pdf_linearisation_t *linear_params
if (code != 0)
return_error(gs_error_ioerror);
- gs_snprintf(LDict, sizeof(LDict), "\ntrailer\n<</Size %ld/Info %d 0 R/Root %d 0 R/ID[%s%s]/Prev %"PRId64">>\nstartxref\r\n0\n%%%%EOF\n",
+ if (pdev->OmitID)
+ gs_snprintf(LDict, sizeof(LDict), "\ntrailer\n<</Size %ld/Info %d 0 R/Root %d 0 R/Prev %"PRId64">>\nstartxref\r\n0\n%%%%EOF\n",
+ linear_params->LastResource + 3, pdev->ResourceUsage[linear_params->Info_id].NewObjectNumber, pdev->ResourceUsage[linear_params->Catalog_id].NewObjectNumber, mainxref);
+ else
+ gs_snprintf(LDict, sizeof(LDict), "\ntrailer\n<</Size %ld/Info %d 0 R/Root %d 0 R/ID[%s%s]/Prev %"PRId64">>\nstartxref\r\n0\n%%%%EOF\n",
linear_params->LastResource + 3, pdev->ResourceUsage[linear_params->Info_id].NewObjectNumber, pdev->ResourceUsage[linear_params->Catalog_id].NewObjectNumber, fileID, fileID, mainxref);
gp_fwrite(LDict, strlen(LDict), 1, linear_params->sfile);
@@ -2871,10 +2901,12 @@ pdf_close(gx_device * dev)
COS_WRITE_OBJECT(pdev->PageLabels, pdev, resourceLabels);
}
- /* Write the document metadata. */
- code1 = pdf_document_metadata(pdev);
- if (code >= 0)
- code = code1;
+ if (!pdev->OmitXMP) {
+ /* Write the document metadata. */
+ code1 = pdf_document_metadata(pdev);
+ if (code >= 0)
+ code = code1;
+ }
/* Write the Catalog. */
@@ -3136,10 +3168,12 @@ pdf_close(gx_device * dev)
stream_puts(s, "trailer\n");
pprintld3(s, "<< /Size %ld /Root %ld 0 R /Info %ld 0 R\n",
pdev->next_id, Catalog_id, Info_id);
- stream_puts(s, "/ID [");
- psdf_write_string(pdev->strm, pdev->fileID, sizeof(pdev->fileID), 0);
- psdf_write_string(pdev->strm, pdev->fileID, sizeof(pdev->fileID), 0);
- stream_puts(s, "]\n");
+ if (!pdev->OmitID) {
+ stream_puts(s, "/ID [");
+ psdf_write_string(pdev->strm, pdev->fileID, sizeof(pdev->fileID), 0);
+ psdf_write_string(pdev->strm, pdev->fileID, sizeof(pdev->fileID), 0);
+ stream_puts(s, "]\n");
+ }
if (pdev->OwnerPassword.size > 0) {
pprintld1(s, "/Encrypt %ld 0 R ", Encrypt_id);
}
@@ -3429,6 +3463,27 @@ error_cleanup:
}
}
+ /* Free named objects. */
+
+ if (pdev->NI_stack != NULL) {
+ cos_release((cos_object_t *)pdev->NI_stack, "Release Name Index stack");
+ gs_free_object(mem, pdev->NI_stack, "Free Name Index stack");
+ pdev->NI_stack = 0;
+ }
+
+ if (pdev->local_named_objects != NULL) {
+ cos_dict_objects_delete(pdev->local_named_objects);
+ COS_FREE(pdev->local_named_objects, "pdf_close(local_named_objects)");
+ pdev->local_named_objects = 0;
+ }
+
+ if (pdev->global_named_objects != NULL) {
+ /* global resources include the Catalog object and apparently the Info dict */
+ cos_dict_objects_delete(pdev->global_named_objects);
+ COS_FREE(pdev->global_named_objects, "pdf_close(global_named_objects)");
+ pdev->global_named_objects = 0;
+ }
+
code1 = pdf_free_resource_objects(pdev, resourceOther);
if (code >= 0)
code = code1;
@@ -3477,27 +3532,6 @@ error_cleanup:
pdev->last_resource = 0;
}
- /* Free named objects. */
-
- if (pdev->NI_stack != NULL) {
- cos_release((cos_object_t *)pdev->NI_stack, "Release Name Index stack");
- gs_free_object(mem, pdev->NI_stack, "Free Name Index stack");
- pdev->NI_stack = 0;
- }
-
- if (pdev->local_named_objects != NULL) {
- cos_dict_objects_delete(pdev->local_named_objects);
- COS_FREE(pdev->local_named_objects, "pdf_close(local_named_objects)");
- pdev->local_named_objects = 0;
- }
-
- if (pdev->global_named_objects != NULL) {
- /* global resources include the Catalog object and apparently the Info dict */
- cos_dict_objects_delete(pdev->global_named_objects);
- COS_FREE(pdev->global_named_objects, "pdf_close(global_named_objects)");
- pdev->global_named_objects = 0;
- }
-
/* Wrap up. */
pdev->font_cache = 0;
@@ -3517,7 +3551,7 @@ error_cleanup:
for (i=0;i < pdev->num_pages;i++) {
if (pdev->pages[i].Page != NULL) {
emprintf(pdev->memory,
- "Page object was reserved for an Annotation destinatio, but no such page was drawn, annotation in output will be invalid.\n");
+ "Page object was reserved for an Annotation destination, but no such page was drawn, annotation in output will be invalid.\n");
gs_free_object(mem, pdev->pages[i].Page, "Free Page object");
pdev->pages[i].Page = NULL;
}
diff --git a/devices/vector/gdevpdfb.c b/devices/vector/gdevpdfb.c
index a7b36d82..1851bab3 100644
--- a/devices/vector/gdevpdfb.c
+++ b/devices/vector/gdevpdfb.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2021 Artifex Software, Inc.
+/* Copyright (C) 2001-2022 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -137,7 +137,7 @@ pdf_copy_mono(gx_device_pdf *pdev,
pdf_stream_position_t ipos;
pdf_resource_t *pres = 0;
byte invert = 0;
- bool in_line = false;
+ bool in_line = false, char_proc_begun = false;
gs_show_enum *show_enum = (gs_show_enum *)pdev->pte;
int x_offset, y_offset;
double width;
@@ -181,6 +181,7 @@ pdf_copy_mono(gx_device_pdf *pdev,
&pcp, &ipos);
if (code < 0)
return code;
+ char_proc_begun = true;
y_offset = -y_offset;
width = psdf_round(pdev->char_width.x, 100, 10); /* See
pdf_write_Widths about rounding. We need to provide
@@ -192,7 +193,7 @@ pdf_copy_mono(gx_device_pdf *pdev,
pdf_image_writer_init(&writer);
code = pdf_begin_write_image(pdev, &writer, gs_no_id, w, h, NULL, true);
if (code < 0)
- return code;
+ goto fail;
pres = (pdf_resource_t *) pcp;
goto wr;
} else if (pdev->pte != NULL) {
@@ -216,13 +217,17 @@ pdf_copy_mono(gx_device_pdf *pdev,
set_image_color(pdev, zero);
} else if (zero == pdev->black && one == pdev->white) {
pcs = gs_cspace_new_DeviceGray(pdev->memory);
- if (pcs == NULL)
- return_error(gs_error_VMerror);
+ if (pcs == NULL) {
+ code = gs_note_error(gs_error_VMerror);
+ goto fail;
+ }
gs_image_t_init(&image, pcs);
} else if (zero == pdev->white && one == pdev->black) {
pcs = gs_cspace_new_DeviceGray(pdev->memory);
- if (pcs == NULL)
- return_error(gs_error_VMerror);
+ if (pcs == NULL) {
+ code = gs_note_error(gs_error_VMerror);
+ goto fail;
+ }
gs_image_t_init(&image, pcs);
invert = 0xff;
} else {
@@ -240,13 +245,14 @@ pdf_copy_mono(gx_device_pdf *pdev,
code = pdf_cspace_init_Device(pdev->memory, &pcs_base, ncomp);
if (code < 0)
- return code;
+ goto fail;
c[0] = psdf_adjust_color_index((gx_device_vector *)pdev, zero);
c[1] = psdf_adjust_color_index((gx_device_vector *)pdev, one);
pcs = gs_cspace_alloc(pdev->memory, &gs_color_space_type_Indexed);
if (pcs == NULL) {
rc_decrement_cs(pcs_base, "pdf_copy_mono");
- return_error(gs_error_VMerror);
+ code = gs_note_error(gs_error_VMerror);
+ goto fail;
}
pcs->base_space = pcs_base;
pcs->params.indexed.hival = 1;
@@ -267,14 +273,14 @@ pdf_copy_mono(gx_device_pdf *pdev,
code = pdf_open_page(pdev, PDF_IN_STREAM);
if (code < 0)
- return code;
+ goto fail;
in_line = nbytes < pdev->MaxInlineImageSize;
if (in_line)
pdf_put_image_matrix(pdev, &image.ImageMatrix, 1.0);
pdf_image_writer_init(&writer);
code = pdf_begin_write_image(pdev, &writer, gs_no_id, w, h, NULL, in_line);
if (code < 0)
- return code;
+ goto fail;
}
wr:
if (image.ImageMask)
@@ -287,7 +293,7 @@ pdf_copy_mono(gx_device_pdf *pdev,
code = pdf_color_space_named(pdev, NULL, &cs_value, NULL, pcs,
&writer.pin->color_spaces, in_line, NULL, 0, false);
if (code < 0)
- return code;
+ goto fail;
pcsvalue = &cs_value;
}
/*
@@ -322,33 +328,37 @@ pdf_copy_mono(gx_device_pdf *pdev,
code = pdf_begin_image_data(pdev, &writer, (const gs_pixel_image_t *)&image,
pcsvalue, 0);
if (code < 0)
- return code;
+ goto fail;
code = pdf_copy_mask_bits(writer.binary[0].strm, base, sourcex, raster,
w, h, invert);
if (code < 0)
- return code;
+ goto fail;
code = pdf_end_image_binary(pdev, &writer, writer.height);
if (code < 0)
- return code;
+ goto fail;
if (!pres) {
switch ((code = pdf_end_write_image(pdev, &writer))) {
default: /* error */
- return code;
+ goto fail;
case 1:
- return 0;
+ code = 0;
+ goto fail;
case 0:
- return pdf_do_image(pdev, writer.pres, &image.ImageMatrix,
+ code = pdf_do_image(pdev, writer.pres, &image.ImageMatrix,
true);
+ goto fail;
}
}
writer.end_string = ""; /* no Q */
switch ((code = pdf_end_write_image(pdev, &writer))) {
default: /* error */
+ goto fail;
return code;
case 0: /* not possible */
- return_error(gs_error_Fatal);
+ code = gs_note_error(gs_error_Fatal);
+ goto fail;
case 1:
break;
}
@@ -365,6 +375,11 @@ pdf_copy_mono(gx_device_pdf *pdev,
imat.yy /= h;
return pdf_do_char_image(pdev, (const pdf_char_proc_t *)pres, &imat);
}
+
+fail:
+ if (char_proc_begun)
+ (void)pdf_end_char_proc(pdev, &ipos);
+ return code;
}
int
gdev_pdf_copy_mono(gx_device * dev,
diff --git a/devices/vector/gdevpdfb.h b/devices/vector/gdevpdfb.h
index b85dffe3..b6439f53 100644
--- a/devices/vector/gdevpdfb.h
+++ b/devices/vector/gdevpdfb.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2021 Artifex Software, Inc.
+/* Copyright (C) 2001-2022 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -237,7 +237,10 @@ const gx_device_pdf PDF_DEVICE_IDENT =
0, /* OCR_char_code */
0, /* OCR_glyph */
NULL, /* ocr_glyphs */
- 0 /* initial_pattern_state */
+ 0, /* initial_pattern_state */
+ false, /* OmitInfoDate */
+ false, /* OmitXMP */
+ false /* OmitID */
};
#else
diff --git a/devices/vector/gdevpdfd.c b/devices/vector/gdevpdfd.c
index ea40111b..892fc4c9 100644
--- a/devices/vector/gdevpdfd.c
+++ b/devices/vector/gdevpdfd.c
@@ -973,13 +973,13 @@ lcvd_close_device_with_writing(gx_device *pdev)
pdf_lcvd_t *cvd = (pdf_lcvd_t *)pdev;
int code, code1;
- code = pdf_dump_converted_image(cvd->pdev, cvd);
+ code = pdf_dump_converted_image(cvd->pdev, cvd, 0);
code1 = cvd->std_close_device((gx_device *)&cvd->mdev);
return code < 0 ? code : code1;
}
static int
-write_image(gx_device_pdf *pdev, gx_device_memory *mdev, gs_matrix *m)
+write_image(gx_device_pdf *pdev, gx_device_memory *mdev, gs_matrix *m, int for_pattern)
{
gs_image_t image;
pdf_image_writer writer;
@@ -990,7 +990,7 @@ write_image(gx_device_pdf *pdev, gx_device_memory *mdev, gs_matrix *m)
pdf_put_matrix(pdev, NULL, m, " cm\n");
code = pdf_copy_color_data(pdev, mdev->base, sourcex,
mdev->raster, gx_no_bitmap_id, 0, 0, mdev->width, mdev->height,
- &image, &writer, 2);
+ &image, &writer, for_pattern);
if (code == 1)
code = 0; /* Empty image. */
else if (code == 0)
@@ -1176,7 +1176,7 @@ mask_to_clip(gx_device_pdf *pdev, int width, int height,
}
static int
-write_subimage(gx_device_pdf *pdev, gx_device_memory *mdev, int x, int y, int x1, int y1)
+write_subimage(gx_device_pdf *pdev, gx_device_memory *mdev, int x, int y, int x1, int y1, int for_pattern)
{
gs_image_t image;
pdf_image_writer writer;
@@ -1190,7 +1190,7 @@ write_subimage(gx_device_pdf *pdev, gx_device_memory *mdev, int x, int y, int x1
code = pdf_copy_color_data(pdev, mdev->base + mdev->raster * Y, X,
mdev->raster, gx_no_bitmap_id,
X, Y, X1 - X, Y1 - Y,
- &image, &writer, 2);
+ &image, &writer, for_pattern);
if (code < 0)
return code;
if (!writer.pres)
@@ -1199,7 +1199,7 @@ write_subimage(gx_device_pdf *pdev, gx_device_memory *mdev, int x, int y, int x1
}
static int
-write_image_with_clip(gx_device_pdf *pdev, pdf_lcvd_t *cvd)
+write_image_with_clip(gx_device_pdf *pdev, pdf_lcvd_t *cvd, int for_pattern)
{
int x = 0, y = 0;
int code, code1;
@@ -1219,7 +1219,7 @@ write_image_with_clip(gx_device_pdf *pdev, pdf_lcvd_t *cvd)
if (code < 0)
return code;
if (code > 0) {
- code1 = write_subimage(pdev, &cvd->mdev, x, y, x1, y1);
+ code1 = write_subimage(pdev, &cvd->mdev, x, y, x1, y1, for_pattern);
if (code1 < 0)
return code1;
}
@@ -1241,14 +1241,14 @@ write_image_with_clip(gx_device_pdf *pdev, pdf_lcvd_t *cvd)
}
int
-pdf_dump_converted_image(gx_device_pdf *pdev, pdf_lcvd_t *cvd)
+pdf_dump_converted_image(gx_device_pdf *pdev, pdf_lcvd_t *cvd, int for_pattern)
{
int code = 0;
if (!cvd->path_is_empty || cvd->has_background) {
if (!cvd->has_background)
stream_puts(pdev->strm, "W n\n");
- code = write_image(pdev, &cvd->mdev, (cvd->write_matrix ? &cvd->m : NULL));
+ code = write_image(pdev, &cvd->mdev, (cvd->write_matrix ? &cvd->m : NULL), for_pattern);
cvd->path_is_empty = true;
} else if (!cvd->mask_is_empty && pdev->PatternImagemask) {
/* Convert to imagemask with a pattern color. */
@@ -1288,7 +1288,7 @@ pdf_dump_converted_image(gx_device_pdf *pdev, pdf_lcvd_t *cvd)
if (code >= 0) {
stream_puts(pdev->strm, "W n\n");
- code = write_image(pdev, &cvd->mdev, NULL);
+ code = write_image(pdev, &cvd->mdev, NULL, for_pattern);
}
pres = pdev->accumulating_substream_resource;
if (code >= 0) {
@@ -1302,7 +1302,7 @@ pdf_dump_converted_image(gx_device_pdf *pdev, pdf_lcvd_t *cvd)
}
if (code >= 0)
code = (*dev_proc(pdev, dev_spec_op))((gx_device *)pdev,
- gxdso_pattern_load, &inst, id);
+ gxdso_pattern_load, &id, sizeof(gs_id));
if (code >= 0)
code = pdf_cs_Pattern_colored(pdev, &v);
if (code >= 0) {
@@ -1315,7 +1315,7 @@ pdf_dump_converted_image(gx_device_pdf *pdev, pdf_lcvd_t *cvd)
} else if (!cvd->mask_is_empty && !pdev->PatternImagemask) {
/* Convert to image with a clipping path. */
stream_puts(pdev->strm, "q\n");
- code = write_image_with_clip(pdev, cvd);
+ code = write_image_with_clip(pdev, cvd, for_pattern);
stream_puts(pdev->strm, "Q\n");
}
if (code > 0)
@@ -1338,7 +1338,7 @@ lcvd_handle_fill_path_as_shading_coverage(gx_device *dev,
if (gx_path_is_null(ppath)) {
/* use the mask. */
if (!cvd->path_is_empty) {
- code = pdf_dump_converted_image(pdev, cvd);
+ code = pdf_dump_converted_image(pdev, cvd, 2);
if (code < 0)
return code;
stream_puts(pdev->strm, "Q q\n");
@@ -1362,7 +1362,7 @@ lcvd_handle_fill_path_as_shading_coverage(gx_device *dev,
gs_make_translation(cvd->path_offset.x, cvd->path_offset.y, &m);
/* use the clipping. */
if (!cvd->mask_is_empty) {
- code = pdf_dump_converted_image(pdev, cvd);
+ code = pdf_dump_converted_image(pdev, cvd, 2);
if (code < 0)
return code;
stream_puts(pdev->strm, "Q q\n");
@@ -1685,7 +1685,7 @@ gdev_pdf_fill_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath,
code = gs_shading_do_fill_rectangle(pi.templat.Shading,
NULL, (gx_device *)&cvd.mdev, pgs2, !pi.shfill);
if (code >= 0)
- code = pdf_dump_converted_image(pdev, &cvd);
+ code = pdf_dump_converted_image(pdev, &cvd, 2);
stream_puts(pdev->strm, "Q Q\n");
pdf_remove_masked_image_converter(pdev, &cvd, need_mask);
gs_setmatrix((gs_gstate *)pgs, &save_ctm);
diff --git a/devices/vector/gdevpdfe.c b/devices/vector/gdevpdfe.c
index ec011d8b..66767bd9 100644
--- a/devices/vector/gdevpdfe.c
+++ b/devices/vector/gdevpdfe.c
@@ -568,7 +568,7 @@ pdf_make_uuid(const byte node[6], uint64_t uuid_time, ulong time_seq, char *buf,
writehex(&p, node[4], 1);
writehex(&p, node[5], 1);
*p = 0;
- strncpy(buf, b, buf_length);
+ strncpy(buf, b, strlen(b) + 1);
}
static int
@@ -696,21 +696,23 @@ pdf_write_document_metadata(gx_device_pdf *pdev, const byte digest[6])
pdf_xml_attribute_name(s, "xmlns:xmp");
pdf_xml_attribute_value(s, "http://ns.adobe.com/xap/1.0/");
pdf_xml_tag_end(s);
- {
- pdf_xml_tag_open_beg(s, "xmp:ModifyDate");
- pdf_xml_tag_end(s);
- mod_date_time[mod_date_time_len] = 0x00;
- pdf_xml_copy(s, mod_date_time);
- pdf_xml_tag_close(s, "xmp:ModifyDate");
- pdf_xml_newline(s);
- }
- {
- pdf_xml_tag_open_beg(s, "xmp:CreateDate");
- pdf_xml_tag_end(s);
- cre_date_time[cre_date_time_len] = 0x00;
- pdf_xml_copy(s, cre_date_time);
- pdf_xml_tag_close(s, "xmp:CreateDate");
- pdf_xml_newline(s);
+ if (!pdev->OmitInfoDate) {
+ {
+ pdf_xml_tag_open_beg(s, "xmp:ModifyDate");
+ pdf_xml_tag_end(s);
+ mod_date_time[mod_date_time_len] = 0x00;
+ pdf_xml_copy(s, mod_date_time);
+ pdf_xml_tag_close(s, "xmp:ModifyDate");
+ pdf_xml_newline(s);
+ }
+ {
+ pdf_xml_tag_open_beg(s, "xmp:CreateDate");
+ pdf_xml_tag_end(s);
+ cre_date_time[cre_date_time_len] = 0x00;
+ pdf_xml_copy(s, cre_date_time);
+ pdf_xml_tag_close(s, "xmp:CreateDate");
+ pdf_xml_newline(s);
+ }
}
{
pdf_xml_tag_open_beg(s, "xmp:CreatorTool");
diff --git a/devices/vector/gdevpdfg.c b/devices/vector/gdevpdfg.c
index d61712b0..3e2a2b6d 100644
--- a/devices/vector/gdevpdfg.c
+++ b/devices/vector/gdevpdfg.c
@@ -3069,7 +3069,7 @@ pdf_prepare_drawing(gx_device_pdf *pdev, const gs_gstate *pgs,
break;
default:
emprintf(pdev->memory,
- "\nSetting Overprint Mode to 1\n not permitted in PDF/A, unrecognised PDFACompatibilityLevel,\nreverting to normal PDF output\n");
+ "\nSetting Halftone Phase or Halftone Offset\n not permitted in PDF/A, unrecognised PDFACompatibilityLevel,\nreverting to normal PDF output\n");
pdev->AbortPDFAX = true;
pdev->PDFA = 0;
break;
diff --git a/devices/vector/gdevpdfi.c b/devices/vector/gdevpdfi.c
index 1e1a9daa..1de48cee 100644
--- a/devices/vector/gdevpdfi.c
+++ b/devices/vector/gdevpdfi.c
@@ -1872,7 +1872,7 @@ use_image_as_pattern(gx_device_pdf *pdev, pdf_resource_t *pres1,
}
if (code >= 0)
code = (*dev_proc(pdev, dev_spec_op))((gx_device *)pdev,
- gxdso_pattern_load, &inst, id);
+ gxdso_pattern_load, &id, sizeof(gs_id));
if (code >= 0) {
stream_puts(pdev->strm, "q ");
code = pdf_cs_Pattern_colored(pdev, &v);
@@ -2032,7 +2032,7 @@ pdf_image_end_image(gx_image_enum_common_t * info, bool draw_last)
static int
pdf_image_end_image_cvd(gx_image_enum_common_t * info, bool draw_last)
{ pdf_lcvd_t *cvd = (pdf_lcvd_t *)info->dev;
- int code = pdf_dump_converted_image(cvd->pdev, cvd);
+ int code = pdf_dump_converted_image(cvd->pdev, cvd, 0);
int code1 = gx_image1_end_image(info, draw_last);
int code2 = gs_closedevice((gx_device *)cvd->mask);
int code3 = gs_closedevice((gx_device *)cvd);
@@ -2214,8 +2214,10 @@ pdf_image3x_make_mcde(gx_device *dev, const gs_gstate *pgs,
code = pdf_begin_typed_image
((gx_device_pdf *)dev, pgs, pmat, pic, prect, pdcolor, pcpath, mem,
pinfo, PDF_IMAGE_TYPE3_DATA);
- if (code < 0)
+ if (code < 0) {
+ rc_decrement(*pmcdev, "pdf_image3x_make_mcde");
return code;
+ }
if ((*pinfo)->procs != &pdf_image_enum_procs) {
/* We couldn't handle the image. Bail out. */
gx_image_end(*pinfo, false);
@@ -2695,7 +2697,6 @@ gdev_pdf_dev_spec_op(gx_device *pdev1, int dev_spec_op, void *data, int size)
gs_pattern1_instance_t *pinst = param->pinst;
gs_gstate *pgs = param->graphics_state;
- id = param->pinst_id;
code = pdf_check_soft_mask(pdev, (gs_gstate *)pgs);
if (code < 0)
return code;
@@ -2735,7 +2736,7 @@ gdev_pdf_dev_spec_op(gx_device *pdev1, int dev_spec_op, void *data, int size)
memset(pdev->initial_pattern_states[pdev->PatternDepth], 0x00, sizeof(gs_gstate));
reset_gstate_for_pattern(pdev, pdev->initial_pattern_states[pdev->PatternDepth], pgs);
- code = pdf_enter_substream(pdev, resourcePattern, id, &pres, false,
+ code = pdf_enter_substream(pdev, resourcePattern, pinst->id, &pres, false,
pdev->CompressStreams);
if (code < 0) {
gs_free_object(pdev->pdf_memory->non_gc_memory, pdev->initial_pattern_states[pdev->PatternDepth], "Freeing dangling pattern state");
@@ -2751,7 +2752,7 @@ gdev_pdf_dev_spec_op(gx_device *pdev1, int dev_spec_op, void *data, int size)
* the ID is restored when we finish capturing the pattern.
*/
pdev->state.soft_mask_id = pgs->soft_mask_id;
- pres->rid = id;
+ pres->rid = pinst->id;
code = pdf_store_pattern1_params(pdev, pres, pinst);
if (code < 0) {
gs_free_object(pdev->pdf_memory->non_gc_memory, pdev->initial_pattern_states[pdev->PatternDepth], "Freeing dangling pattern state");
@@ -2830,7 +2831,7 @@ gdev_pdf_dev_spec_op(gx_device *pdev1, int dev_spec_op, void *data, int size)
}
return 1;
case gxdso_pattern_load:
- pres = pdf_find_resource_by_gs_id(pdev, resourcePattern, id);
+ pres = pdf_find_resource_by_gs_id(pdev, resourcePattern, *((gx_bitmap_id *)data));
if (pres == 0)
return 0;
pres = pdf_substitute_pattern(pres);
diff --git a/devices/vector/gdevpdfj.c b/devices/vector/gdevpdfj.c
index 02692510..5888ac70 100644
--- a/devices/vector/gdevpdfj.c
+++ b/devices/vector/gdevpdfj.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2021 Artifex Software, Inc.
+/* Copyright (C) 2001-2022 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -348,8 +348,10 @@ pdf_begin_write_image(gx_device_pdf * pdev, pdf_image_writer * piw,
}
pdev->strm = pdev->streams.strm;
pdev->strm = cos_write_stream_alloc(data, pdev, "pdf_begin_write_image");
- if (pdev->strm == 0)
+ if (pdev->strm == 0) {
+ pdev->strm = save_strm;
return_error(gs_error_VMerror);
+ }
if (!mask)
piw->data = data;
piw->height = h;
diff --git a/devices/vector/gdevpdfo.c b/devices/vector/gdevpdfo.c
index 3ec00f5e..e00a9258 100644
--- a/devices/vector/gdevpdfo.c
+++ b/devices/vector/gdevpdfo.c
@@ -1485,6 +1485,8 @@ cos_dict_find(const cos_dict_t *pcd, const byte *key_data, uint key_size)
const cos_value_t *
cos_dict_find_c_key(const cos_dict_t *pcd, const char *key)
{
+ if (pcd == NULL)
+ return NULL;
return cos_dict_find(pcd, (const byte *)key, strlen(key));
}
diff --git a/devices/vector/gdevpdfp.c b/devices/vector/gdevpdfp.c
index 42fa1c52..690a9e13 100644
--- a/devices/vector/gdevpdfp.c
+++ b/devices/vector/gdevpdfp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2021 Artifex Software, Inc.
+/* Copyright (C) 2001-2022 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -129,6 +129,9 @@ static const gs_param_item_t pdf_param_items[] = {
pi("NoOutputFonts", gs_param_type_bool, FlattenFonts),
pi("WantsPageLabels", gs_param_type_bool, WantsPageLabels),
pi("UserUnit", gs_param_type_float, UserUnit),
+ pi("OmitInfoDate", gs_param_type_bool, OmitInfoDate),
+ pi("OmitID", gs_param_type_bool, OmitID),
+ pi("OmitXMP", gs_param_type_bool, OmitXMP),
#undef pi
gs_param_item_end
};
@@ -297,6 +300,13 @@ gdev_pdf_get_param(gx_device *dev, char *Param, void *list)
}
#endif
+ if (strcmp(Param, "OmitInfoDate") == 0)
+ return(param_write_bool(plist, "OmitInfoDate", &pdev->OmitInfoDate));
+ if (strcmp(Param, "OmitXMP") == 0)
+ return(param_write_bool(plist, "OmitXMP", &pdev->OmitXMP));
+ if (strcmp(Param, "OmitID") == 0)
+ return(param_write_bool(plist, "OmitID", &pdev->OmitID));
+
return gdev_psdf_get_param(dev, Param, list);
}
@@ -649,6 +659,25 @@ gdev_pdf_put_params_impl(gx_device * dev, const gx_device_pdf * save_dev, gs_par
param_signal_error(plist, param_name, code);
}
+ if (pdev->OmitInfoDate && pdev->PDFX != 0) {
+ emprintf(pdev->memory, "\nIt is not possible to omit the CreationDate when creating PDF/X\nOmitInfoDate is being ignored.\n");
+ pdev->OmitInfoDate = 0;
+ }
+
+ if (pdev->OmitID && pdev->CompatibilityLevel > 1.7) {
+ emprintf(pdev->memory, "\nIt is not possible to omit the ID array when creating a version 2.0 or greater PDF\nOmitID is being ignored.\n");
+ pdev->OmitID = 0;
+ }
+ if (pdev->OmitID && pdev->OwnerPassword.size != 0) {
+ emprintf(pdev->memory, "\nIt is not possible to omit the ID array when creating an encrypted PDF\nOmitID is being ignored.\n");
+ pdev->OmitID = 0;
+ }
+
+ if (pdev->OmitXMP && pdev->PDFA != 0) {
+ emprintf(pdev->memory, "\nIt is not possible to omit the XMP metadta when creating a PDF/A\nOmitXMP is being ignored.\n");
+ pdev->OmitXMP = 0;
+ }
+
/* PDFA and PDFX are stored in the page device dictionary and therefore
* set on every setpagedevice. However, if we have encountered a file which
* can't be made this way, and the PDFACompatibilityPolicy is 1, we want to
diff --git a/devices/vector/gdevpdft.c b/devices/vector/gdevpdft.c
index 72f082f9..6f50df01 100644
--- a/devices/vector/gdevpdft.c
+++ b/devices/vector/gdevpdft.c
@@ -110,8 +110,12 @@ pdf_make_group_dict(gx_device_pdf * pdev, const gs_pdf14trans_params_t * pparams
if (pgs != NULL && pparams->group_color_type != UNKNOWN) {
const gs_color_space *cs = gs_currentcolorspace_inline(pgs);
- code = pdf_color_space_named(pdev, pgs, &cs_value, NULL, cs,
- &pdf_color_space_names, false, NULL, 0, false);
+ if (pparams->ColorSpace == NULL)
+ code = pdf_color_space_named(pdev, pgs, &cs_value, NULL, cs,
+ &pdf_color_space_names, false, NULL, 0, false);
+ else
+ code = pdf_color_space_named(pdev, pgs, &cs_value, NULL, pparams->ColorSpace,
+ &pdf_color_space_names, false, NULL, 0, false);
if (code < 0)
return code;
code = cos_dict_put_c_key(group_dict, "/CS", &cs_value);
diff --git a/devices/vector/gdevpdfu.c b/devices/vector/gdevpdfu.c
index f12fa38e..9545bd58 100644
--- a/devices/vector/gdevpdfu.c
+++ b/devices/vector/gdevpdfu.c
@@ -1589,10 +1589,15 @@ pdf_begin_aside(gx_device_pdf * pdev, pdf_resource_t ** plist,
pdf_resource_type_t type)
{
long id = pdf_begin_separate(pdev, type);
+ int code = 0;
if (id < 0)
return (int)id;
- return pdf_alloc_aside(pdev, plist, pst, ppres, id);
+ code = pdf_alloc_aside(pdev, plist, pst, ppres, id);
+ if (code < 0)
+ (void)pdf_end_separate(pdev, type);
+
+ return code;
}
/* Begin a resource of a given type. */
diff --git a/devices/vector/gdevpdfx.h b/devices/vector/gdevpdfx.h
index 774a5156..098fc4fc 100644
--- a/devices/vector/gdevpdfx.h
+++ b/devices/vector/gdevpdfx.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2021 Artifex Software, Inc.
+/* Copyright (C) 2001-2022 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -946,7 +946,7 @@ struct gx_device_pdf_s {
* anything in the image processing routines.
*/
float UserUnit;
- pdf_OCR_usage UseOCR; /* Never, AsNeeded or Always */
+ pdf_OCR_usage UseOCR; /* Never, AsNeeded or Always */
gs_text_enum_t* OCRSaved; /* Saved state of the text enumerator before rendering glyph bitmaps for later OCR */
pdf_OCR_stage OCRStage; /* Used to control a (sort of) state machine when using OCR to get a Unicode value for a glyph */
int *OCRUnicode; /* Used to pass back the Unicode value from the OCR engine to the text processing */
@@ -954,6 +954,9 @@ struct gx_device_pdf_s {
gs_glyph OCR_glyph; /* Passes the current glyph code from text processing to the image processing code when rendering glyph bitmaps for OCR */
ocr_glyph_t *ocr_glyphs; /* Records bitmaps and other data from text processing when doing OCR */
gs_gstate **initial_pattern_states;
+ bool OmitInfoDate; /* If true, do not emit CreationDate and ModDate in the Infor dictionary and XMP Metadata (must not be true for PDF/X support) */
+ bool OmitXMP; /* If true, do not emit an XMP /Metadata block and do not reference it from the Catalog (must not be true for PDF/A output) */
+ bool OmitID; /* If true, do not emit a /ID array in the trailer dicionary (must not be true for encrypted files or PDF 2.0) */
};
#define is_in_page(pdev)\
@@ -1290,7 +1293,7 @@ typedef struct pdf_lcvd_s {
int pdf_setup_masked_image_converter(gx_device_pdf *pdev, gs_memory_t *mem, const gs_matrix *m, pdf_lcvd_t **pcvd,
bool need_mask, int x, int y, int w, int h, bool write_on_close);
-int pdf_dump_converted_image(gx_device_pdf *pdev, pdf_lcvd_t *cvd);
+int pdf_dump_converted_image(gx_device_pdf *pdev, pdf_lcvd_t *cvd, int for_pattern);
void pdf_remove_masked_image_converter(gx_device_pdf *pdev, pdf_lcvd_t *cvd, bool need_mask);
/* ------ Miscellaneous output ------ */
diff --git a/devices/vector/gdevpdte.c b/devices/vector/gdevpdte.c
index 5e50d2cf..9760094b 100644
--- a/devices/vector/gdevpdte.c
+++ b/devices/vector/gdevpdte.c
@@ -382,6 +382,8 @@ pdf_add_ToUnicode(gx_device_pdf *pdev, gs_font *font, pdf_font_resource_t *pdfon
if (!unicode) {
unicode = (ushort *)gs_alloc_bytes(pdev->memory, length * sizeof(short), "temporary Unicode array");
+ if (unicode == NULL)
+ return_error(gs_error_VMerror);
length = font->procs.decode_glyph((gs_font *)font, glyph, ch, unicode, length);
}
diff --git a/devices/vector/gdevpdtt.c b/devices/vector/gdevpdtt.c
index 98ce8892..9483e051 100644
--- a/devices/vector/gdevpdtt.c
+++ b/devices/vector/gdevpdtt.c
@@ -86,6 +86,30 @@ pdf_text_current_width(const gs_text_enum_t *pte, gs_point *pwidth)
return gs_text_current_width(penum->pte_default, pwidth);
return_error(gs_error_rangecheck); /* can't happen */
}
+
+static void
+pdf_show_text_release(gs_text_enum_t *pte, client_name_t cname)
+{
+ gs_show_enum *const penum = (gs_show_enum *)pte;
+ gs_text_enum_procs_t *procs = (gs_text_enum_procs_t *)penum->procs;
+
+ penum->cc = 0;
+ if (penum->dev_cache2) {
+ gx_device_retain((gx_device *)penum->dev_cache2, false);
+ penum->dev_cache2 = 0;
+ }
+ if (penum->dev_cache) {
+ gx_device_retain((gx_device *)penum->dev_cache, false);
+ penum->dev_cache = 0;
+ }
+ if (penum->dev_null) {
+ gx_device_retain((gx_device *)penum->dev_null, false);
+ penum->dev_null = 0;
+ }
+ gx_default_text_release(pte, cname);
+ gs_free_object(penum->memory->non_gc_memory, procs, "pdf_show_text_release");
+}
+
static int
pdf_text_set_cache(gs_text_enum_t *pte, const double *pw,
gs_text_cache_control_t control)
@@ -655,7 +679,7 @@ gdev_pdf_text_begin(gx_device * dev, gs_gstate * pgs,
penum->output_char_code = GS_NO_CHAR;
code = gs_text_enum_init((gs_text_enum_t *)penum, &pdf_text_procs,
dev, pgs, text, font, pcpath, mem);
- penum->k_text_release = 1; /* early release of black_text_state */
+ penum->k_text_release = 1; /* early release of black_textvec_state */
if (code < 0) {
gs_free_object(mem, penum, "gdev_pdf_text_begin");
@@ -3392,12 +3416,18 @@ pdf_text_process(gs_text_enum_t *pte)
*/
gs_show_enum psenum = *(gs_show_enum *)pte_default;
gs_gstate *pgs = (gs_gstate *)penum->pgs;
- gs_text_enum_procs_t special_procs = *pte_default->procs;
+ gs_text_enum_procs_t *special_procs;
void (*save_proc)(gx_device *, gs_matrix *) = pdev->procs.get_initial_matrix;
gs_matrix m, savem;
- special_procs.set_cache = pdf_text_set_cache;
- pte_default->procs = &special_procs;
+ special_procs = (gs_text_enum_procs_t *)gs_alloc_bytes(pte_default->memory->non_gc_memory, sizeof(gs_text_enum_procs_t), "pdf_text_process");
+ if (special_procs == NULL)
+ return_error(gs_error_VMerror);
+
+ *special_procs = *pte_default->procs;
+ special_procs->set_cache = pdf_text_set_cache;
+ special_procs->release = pdf_show_text_release;
+ pte_default->procs = special_procs;
{
/* We should not come here if we already have a cached character (except for the special case
diff --git a/devices/vector/gdevpsdp.c b/devices/vector/gdevpsdp.c
index fc944539..cf6933ec 100644
--- a/devices/vector/gdevpsdp.c
+++ b/devices/vector/gdevpsdp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2021 Artifex Software, Inc.
+/* Copyright (C) 2001-2022 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -1254,13 +1254,17 @@ gdev_psdf_put_params(gx_device * dev, gs_param_list * plist)
exit:
if (!(pdev->params.LockDistillerParams && params.LockDistillerParams)) {
/* Only update the device paramters if there was no error */
- /* If we have any copied param_string_arrays, start by freeing them */
- if (pdev->params.PSPageOptions.size && params.PSPageOptions.size) {
- int ix;
-
- for (ix = 0; ix < pdev->params.PSPageOptions.size;ix++)
- gs_free_object(mem->non_gc_memory, (byte *)pdev->params.PSPageOptions.data[ix].data, "freeing old string array copy");
- gs_free_object(mem->non_gc_memory, (byte *)pdev->params.PSPageOptions.data, "freeing old string array");
+ /* Do not permit changes to pdev->Params.PSPageOptions, it doesn't make any sense */
+ if (pdev->params.PSPageOptions.size != 0) {
+ if (params.PSPageOptions.size != 0 && params.PSPageOptions.data != pdev->params.PSPageOptions.data) {
+ int ix;
+
+ for (ix = 0; ix < pdev->params.PSPageOptions.size;ix++)
+ gs_free_object(mem->non_gc_memory, (byte *)params.PSPageOptions.data[ix].data, "freeing old string array copy");
+ gs_free_object(mem->non_gc_memory, (byte *)params.PSPageOptions.data, "freeing old string array");
+ }
+ params.PSPageOptions.data = pdev->params.PSPageOptions.data;
+ params.PSPageOptions.size = pdev->params.PSPageOptions.size;
}
pdev->params = params;
} else {
diff --git a/devices/vector/gdevpsft.c b/devices/vector/gdevpsft.c
index ae6600be..4d6384f2 100644
--- a/devices/vector/gdevpsft.c
+++ b/devices/vector/gdevpsft.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2021 Artifex Software, Inc.
+/* Copyright (C) 2001-2022 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -845,7 +845,6 @@ psf_write_truetype_data(stream *s, gs_font_type42 *pfont, int options,
length = u32(tab + 12);
/* Copy the table data now (a rudiment of old code). */
memcpy(&tables[numTables * 16], tab, 16);
-
switch (u32(tab)) {
case W('h','e','a','d'):
if (length < 54)
@@ -900,13 +899,16 @@ psf_write_truetype_data(stream *s, gs_font_type42 *pfont, int options,
/* falls through */
case W('c','v','t',' '):
case W('f','p','g','m'):
- case W('g','a','s','p'):
- case W('k','e','r','n'):
case W('p','r','e','p'):
break; /* always copy these if present */
+ case W('D','S','I','G'):
case W('E','B','D','T'):
case W('E','B','L','C'):
case W('E','B','S','C'):
+ case W('G','D','E','F'):
+ case W('G','P','O','S'):
+ case W('g','a','s','p'):
+ case W('k','e','r','n'):
continue;
default:
if (writing_cid)
diff --git a/devices/vector/gdevpsu.c b/devices/vector/gdevpsu.c
index 83b8bdbb..123dda69 100644
--- a/devices/vector/gdevpsu.c
+++ b/devices/vector/gdevpsu.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2021 Artifex Software, Inc.
+/* Copyright (C) 2001-2022 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -180,8 +180,12 @@ psw_begin_file_header(gp_file *f, const gx_device *dev, const gs_rect *pbbox,
fputs("%...............................................................\n", f);
fputs("%...............................................................\n", f);
}
+#ifdef CLUSTER
+ fprintf(f, "%%%%Creator: GPL Ghostscript (%s)\n", dev->dname);
+#else
fprintf(f, "%%%%Creator: %s %ld (%s)\n", gs_product, (long)gs_revision,
dev->dname);
+#endif
{
time_t t;
struct tm tms;
@@ -204,7 +208,9 @@ psw_begin_file_header(gp_file *f, const gx_device *dev, const gs_rect *pbbox,
else if (pdpc->LanguageLevel == 1.5)
fputs("%%Extensions: CMYK\n", f);
psw_print_lines(f, psw_begin_prolog);
+#ifndef CLUSTER
fprintf(f, "%% %s\n", gs_copyright);
+#endif
fputs("%%BeginResource: procset ", f);
fflush(f);
psw_print_procset_name(f, dev, pdpc);
diff --git a/devices/vector/gdevtxtw.c b/devices/vector/gdevtxtw.c
index 5c885f5f..71be58b6 100644
--- a/devices/vector/gdevtxtw.c
+++ b/devices/vector/gdevtxtw.c
@@ -1167,7 +1167,7 @@ txtwrite_put_params(gx_device * dev, gs_param_list * plist)
if (code < 0)
return code;
- if (ofs.data != 0) { /* Close the file if it's open. */
+ if (ofs.data != 0 && (ofs.size != strlen(tdev->fname) || strncmp((const char *)ofs.data, tdev->fname, ofs.size)) != 0) { /* Close the file if it's open. */
if (tdev->file != 0) {
gp_fclose(tdev->file);
tdev->file = 0;
@@ -1185,10 +1185,10 @@ txtwrite_put_params(gx_device * dev, gs_param_list * plist)
dev->is_open = false;
code = gx_default_put_params(dev, plist);
+ dev->is_open = open;
if (code < 0)
return code;
- dev->is_open = open;
dev->interpolate_control = 0;
@@ -1875,10 +1875,14 @@ textw_text_process(gs_text_enum_t *pte)
if (!penum->SpanDeltaX)
return gs_note_error(gs_error_VMerror);
}
+retry:
{
switch (font->FontType) {
case ft_CID_encrypted:
case ft_CID_TrueType:
+ errprintf(pte->memory, "\n\n*** The txtwrite device does not currently support the use of CID-Keyed fonts. ***\n\n");
+ return_error(gs_error_typecheck);
+ break;
case ft_composite:
code = txtwrite_process_cmap_text(pte);
break;
@@ -1886,13 +1890,14 @@ textw_text_process(gs_text_enum_t *pte)
case ft_encrypted2:
case ft_TrueType:
case ft_user_defined:
+ case ft_PDF_user_defined:
case ft_PCL_user_defined:
case ft_GL2_stick_user_defined:
case ft_GL2_531:
code = txtwrite_process_plain_text(pte);
break;
default:
- return_error(gs_error_rangecheck);
+ return_error(gs_error_rangecheck);
break;
}
if (code == 0) {
@@ -1935,6 +1940,9 @@ textw_text_process(gs_text_enum_t *pte)
penum->pte_fallback = pte_fallback;
gs_text_enum_copy_dynamic(pte_fallback, pte, false);
+ if (font->FontType == ft_PDF_user_defined && pte->text.size != 1)
+ pte_fallback->text.size = pte->index + 1;
+
code = gs_text_process(pte_fallback);
if (code != 0) {
penum->returned.current_char = pte_fallback->returned.current_char;
@@ -1943,6 +1951,8 @@ textw_text_process(gs_text_enum_t *pte)
}
gs_text_release(NULL, pte_fallback, "txtwrite_text_process");
penum->pte_fallback = 0;
+ if (font->FontType == ft_PDF_user_defined)
+ goto retry;
}
}
return code;
@@ -1954,7 +1964,11 @@ textw_text_process(gs_text_enum_t *pte)
static int
textw_text_resync(gs_text_enum_t *pte, const gs_text_enum_t *pfrom)
{
- return gs_text_resync(pte, pfrom);
+ if ((pte->text.operation ^ pfrom->text.operation) & ~TEXT_FROM_ANY)
+ return_error(gs_error_rangecheck);
+ pte->text = pfrom->text;
+ gs_text_enum_copy_dynamic(pte, pfrom, false);
+ return 0;
}
static bool
textw_text_is_width_only(const gs_text_enum_t *pte)
diff --git a/devices/vector/gdevxps.c b/devices/vector/gdevxps.c
index 1ab854be..20d9dbd5 100644
--- a/devices/vector/gdevxps.c
+++ b/devices/vector/gdevxps.c
@@ -1790,7 +1790,7 @@ static TIFF* tiff_from_name(gx_device_xps *dev, const char *name, int big_endian
static int tiff_set_values(xps_image_enum_t *pie, TIFF *tif,
cmm_profile_t *profile, bool force8bit);
static void xps_tiff_set_handlers(void);
-static void tiff_client_release(gx_device_xps* dev, TIFF* t);
+static void xps_tiff_cleanup(xps_image_enum_t *xpie);
/* Check if we have the ICC profile in the package */
static xps_icc_data_t*
@@ -1930,6 +1930,7 @@ xps_begin_typed_image(gx_device *dev,
pie->buffer = NULL;
pie->devc_buffer = NULL;
pie->pgs = NULL;
+ pie->tif = NULL;
/* Set the brush types to image */
xps_setstrokebrush(xdev, xps_imagebrush);
@@ -2295,8 +2296,7 @@ xps_image_end_image(gx_image_enum_common_t * info, bool draw_last)
/* N.B. Write the final strip, if any. */
code = TIFFWriteDirectory(pie->tif);
- tiff_client_release((gx_device_xps*)(pie->dev), pie->tif);
- TIFFCleanup(pie->tif);
+ xps_tiff_cleanup(pie);
/* Stuff the image into the zip archive and close the file */
code = xps_add_tiff_image(pie);
@@ -2573,11 +2573,14 @@ tiff_from_name(gx_device_xps *dev, const char *name, int big_endian, bool usebig
return t;
}
-static void
-tiff_client_release(gx_device_xps *dev, TIFF *t)
+static void xps_tiff_cleanup(xps_image_enum_t *xpie)
{
- gs_free_object(dev->memory->non_gc_memory, TIFFClientdata(t),
- "tiff_client_release");
+ if (xpie->tif != NULL) {
+ void *t = TIFFClientdata(xpie->tif);
+ TIFFCleanup(xpie->tif);
+ xpie->tif = NULL;
+ gs_free_object(xpie->memory->non_gc_memory, t, "xps_image_enum_finalize");
+ }
}
static void
@@ -2586,6 +2589,8 @@ xps_image_enum_finalize(const gs_memory_t *cmem, void *vptr)
xps_image_enum_t *xpie = (xps_image_enum_t *)vptr;
gx_device_xps *xdev = (gx_device_xps *)xpie->dev;
+ xps_tiff_cleanup(xpie);
+
xpie->dev = NULL;
if (xpie->pcs != NULL)
rc_decrement(xpie->pcs, "xps_image_end_image (pcs)");