diff options
Diffstat (limited to 'devices/vector')
-rw-r--r-- | devices/vector/doc_common.c | 16 | ||||
-rw-r--r-- | devices/vector/doc_common.h | 15 | ||||
-rw-r--r-- | devices/vector/gdevdocxw.c | 16 | ||||
-rw-r--r-- | devices/vector/gdevpdf.c | 150 | ||||
-rw-r--r-- | devices/vector/gdevpdfb.c | 53 | ||||
-rw-r--r-- | devices/vector/gdevpdfb.h | 7 | ||||
-rw-r--r-- | devices/vector/gdevpdfd.c | 30 | ||||
-rw-r--r-- | devices/vector/gdevpdfe.c | 34 | ||||
-rw-r--r-- | devices/vector/gdevpdfg.c | 2 | ||||
-rw-r--r-- | devices/vector/gdevpdfi.c | 15 | ||||
-rw-r--r-- | devices/vector/gdevpdfj.c | 6 | ||||
-rw-r--r-- | devices/vector/gdevpdfo.c | 2 | ||||
-rw-r--r-- | devices/vector/gdevpdfp.c | 31 | ||||
-rw-r--r-- | devices/vector/gdevpdft.c | 8 | ||||
-rw-r--r-- | devices/vector/gdevpdfu.c | 7 | ||||
-rw-r--r-- | devices/vector/gdevpdfx.h | 9 | ||||
-rw-r--r-- | devices/vector/gdevpdte.c | 2 | ||||
-rw-r--r-- | devices/vector/gdevpdtt.c | 38 | ||||
-rw-r--r-- | devices/vector/gdevpsdp.c | 20 | ||||
-rw-r--r-- | devices/vector/gdevpsft.c | 10 | ||||
-rw-r--r-- | devices/vector/gdevpsu.c | 8 | ||||
-rw-r--r-- | devices/vector/gdevtxtw.c | 22 | ||||
-rw-r--r-- | devices/vector/gdevxps.c | 19 |
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)"); |