summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'devices')
-rw-r--r--devices/extract.mak10
-rw-r--r--devices/gdevclj.c4
-rw-r--r--devices/gdevpng.c5
-rw-r--r--devices/gdevpsd.c16
-rw-r--r--devices/gdevsppr.c4
-rw-r--r--devices/gdevtfax.c11
-rw-r--r--devices/gdevtifs.c23
-rw-r--r--devices/gdevtifs.h12
-rw-r--r--devices/gdevtsep.c118
-rw-r--r--devices/gdevxini.c30
-rw-r--r--devices/gxfcopy.c23
-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
34 files changed, 515 insertions, 261 deletions
diff --git a/devices/extract.mak b/devices/extract.mak
index 71f30825..1ed6080b 100644
--- a/devices/extract.mak
+++ b/devices/extract.mak
@@ -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
@@ -22,6 +22,9 @@ $(extract_out_prefix)alloc.$(OBJ): $(EXTRACT_DIR)/src/alloc.c $(MAKEDIR
$(extract_out_prefix)astring.$(OBJ): $(EXTRACT_DIR)/src/astring.c $(MAKEDIRS)
$(extract_cc)$@ $(C_) $(EXTRACT_DIR)/src/astring.c
+$(extract_out_prefix)boxer.$(OBJ): $(EXTRACT_DIR)/src/boxer.c $(MAKEDIRS)
+ $(extract_cc)$@ $(C_) $(EXTRACT_DIR)/src/boxer.c
+
$(extract_out_prefix)buffer.$(OBJ): $(EXTRACT_DIR)/src/buffer.c $(MAKEDIRS)
$(extract_cc)$@ $(C_) $(EXTRACT_DIR)/src/buffer.c
@@ -55,6 +58,9 @@ $(extract_out_prefix)odt_template.$(OBJ): $(EXTRACT_DIR)/src/odt_template.c $(
$(extract_out_prefix)outf.$(OBJ): $(EXTRACT_DIR)/src/outf.c $(MAKEDIRS)
$(extract_cc)$@ $(C_) $(EXTRACT_DIR)/src/outf.c
+$(extract_out_prefix)rect.$(OBJ): $(EXTRACT_DIR)/src/rect.c $(MAKEDIRS)
+ $(extract_cc)$@ $(C_) $(EXTRACT_DIR)/src/rect.c
+
$(extract_out_prefix)sys.$(OBJ): $(EXTRACT_DIR)/src/sys.c $(MAKEDIRS)
$(extract_cc)$@ $(C_) $(EXTRACT_DIR)/src/sys.c
@@ -70,6 +76,7 @@ $(extract_out_prefix)zip.$(OBJ): $(EXTRACT_DIR)/src/zip.c $(MAKEDIRS)
EXTRACT_OBJS = \
$(extract_out_prefix)alloc.$(OBJ) \
$(extract_out_prefix)astring.$(OBJ) \
+ $(extract_out_prefix)boxer.$(OBJ) \
$(extract_out_prefix)buffer.$(OBJ) \
$(extract_out_prefix)document.$(OBJ) \
$(extract_out_prefix)docx.$(OBJ) \
@@ -81,6 +88,7 @@ EXTRACT_OBJS = \
$(extract_out_prefix)odt.$(OBJ) \
$(extract_out_prefix)odt_template.$(OBJ) \
$(extract_out_prefix)outf.$(OBJ) \
+ $(extract_out_prefix)rect.$(OBJ) \
$(extract_out_prefix)sys.$(OBJ) \
$(extract_out_prefix)text.$(OBJ) \
$(extract_out_prefix)xml.$(OBJ) \
diff --git a/devices/gdevclj.c b/devices/gdevclj.c
index 4d4d9c71..26bf0f0e 100644
--- a/devices/gdevclj.c
+++ b/devices/gdevclj.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
@@ -380,7 +380,7 @@ pack_and_compress_scanline(
}
/* clear to up a longword boundary */
- while ((((ulong)p_c) & (sizeof(ulong) - 1)) != 0) {
+ while ((((intptr_t)p_c) & (sizeof(ulong) - 1)) != 0) {
*p_c++ = 0;
*p_m++ = 0;
*p_y++ = 0;
diff --git a/devices/gdevpng.c b/devices/gdevpng.c
index 554c664c..e9e776b5 100644
--- a/devices/gdevpng.c
+++ b/devices/gdevpng.c
@@ -632,6 +632,10 @@ do_png_print_page(gx_device_png * pdev, gp_file * file, bool monod)
num_palette = 0;
}
/* add comment */
+#ifdef CLUSTER
+ strncpy(software_key, "GPL Ghostscript", sizeof(software_key));
+ strncpy(software_text, "GPL Ghostscript", sizeof(software_text));
+#else
strncpy(software_key, "Software", sizeof(software_key));
{
int major = (int)(gs_revision / 1000);
@@ -640,6 +644,7 @@ do_png_print_page(gx_device_png * pdev, gp_file * file, bool monod)
gs_snprintf(software_text, sizeof(software_text), "%s %d.%02d.%d", gs_product, major, minor, patch);
}
+#endif
text_png.compression = -1; /* uncompressed */
text_png.key = software_key;
text_png.text = software_text;
diff --git a/devices/gdevpsd.c b/devices/gdevpsd.c
index d538b784..2a54a471 100644
--- a/devices/gdevpsd.c
+++ b/devices/gdevpsd.c
@@ -942,12 +942,20 @@ psd_setup(psd_write_ctx *xc, gx_devn_prn_device *dev, gp_file *file, int w, int
xc->num_channels = i;
if (dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE
&& strcmp(dev->dname, "psdcmykog") != 0) {
+
+ /* Note: num_separation_order_names is only set if
+ SeparationColorNames was setup. If this was not set,
+ we need may need to make use of the ICCOutputColors
+ and page spot colors for our setup. */
if (dev->devn_params.num_separation_order_names == 0) {
/* Page spot colors has been truncated to ensure max
colorants of the target device is not exceeded. This
is set if PDF file was encountered and should be used.
- Also make sure PS file does not exceed limit of device. */
- if (dev->devn_params.page_spot_colors > 0)
+ Also make sure PS file does not exceed limit of device.
+ However, if ICCOutputColors was specified, that should
+ take precedence. */
+ if (dev->devn_params.page_spot_colors > 0 &&
+ dev->icc_struct->spotnames == NULL)
xc->n_extra_channels = dev->devn_params.page_spot_colors;
else {
if (dev->devn_params.separations.num_separations <= (dev->color_info.max_components - NUM_CMYK_COMPONENTS))
@@ -1008,13 +1016,13 @@ psd_setup(psd_write_ctx *xc, gx_devn_prn_device *dev, gp_file *file, int w, int
bool has_tags = (pdev_psd->color_model == psd_DEVICE_CMYKT);
xc->num_channels += xc->n_extra_channels;
- for (i=xc->base_num_channels; i < xc->num_channels; i++) {
+ for (i=xc->base_num_channels + has_tags; i < xc->num_channels; i++) {
int j;
const char *curr = "\377";
int curr_size = 1;
bool compare;
- for (j=xc->base_num_channels; j < (xc->num_channels - has_tags); j++) {
+ for (j=xc->base_num_channels + has_tags; j < xc->num_channels; j++) {
devn_separation_name *separation_name;
separation_name = &(dev->devn_params.separations.names[j - xc->base_num_channels]);
diff --git a/devices/gdevsppr.c b/devices/gdevsppr.c
index 29d34dd9..2806253d 100644
--- a/devices/gdevsppr.c
+++ b/devices/gdevsppr.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
@@ -101,7 +101,7 @@ err_code_string(int err_code)
{
if ((err_code<EMOTOR)||(err_code>ESERIAL))
{
- gs_sprintf(err_buffer,"err_code out of range: %d",err_code);
+ gs_snprintf(err_buffer, 80, "err_code out of range: %d",err_code);
return err_buffer;
}
return errmsg[err_code];
diff --git a/devices/gdevtfax.c b/devices/gdevtfax.c
index 531eb964..5acd2626 100644
--- a/devices/gdevtfax.c
+++ b/devices/gdevtfax.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
@@ -47,7 +47,7 @@ struct gx_device_tfax_s {
/* The type and range of FillOrder follows TIFF 6 spec */
bool BigEndian; /* true = big endian; false = little endian*/
bool UseBigTIFF;
- uint16 Compression; /* same values as TIFFTAG_COMPRESSION */
+ uint16_t Compression; /* same values as TIFFTAG_COMPRESSION */
bool write_datetime;
TIFF *tif; /* For TIFF output only */
};
@@ -71,7 +71,10 @@ tfax_initialize_device_procs(gx_device *dev)
#define TFAX_DEVICE(dname, print_page, compr)\
{\
FAX_DEVICE_BODY(gx_device_tfax, tfax_initialize_device_procs, dname, print_page),\
- TIFF_DEFAULT_STRIP_SIZE /* strip size byte count */,\
+ /* We want Fax output to be contained in one strip because apparently 'many' fax readers have\
+ * problems reading TIFF images in strips (see commit 0abc209b8460396cdece8fc824c053a2662c4cbf\
+ */\
+ 0 /* strip size byte count */,\
ARCH_IS_BIG_ENDIAN /* default to native endian (i.e. use big endian iff the platform is so*/,\
false, /* default to not using bigtiff */\
compr,\
@@ -160,7 +163,7 @@ tfax_put_params(gx_device * dev, gs_param_list * plist)
bool big_endian = tfdev->BigEndian;
bool usebigtiff = tfdev->UseBigTIFF;
bool write_datetime = tfdev->write_datetime;
- uint16 compr = tfdev->Compression;
+ uint16_t compr = tfdev->Compression;
gs_param_string comprstr;
switch (code = param_read_long(plist, (param_name = "MaxStripSize"), &mss)) {
diff --git a/devices/gdevtifs.c b/devices/gdevtifs.c
index 9c629afa..55ae5a7d 100644
--- a/devices/gdevtifs.c
+++ b/devices/gdevtifs.c
@@ -149,7 +149,7 @@ tiff_put_some_params(gx_device * dev, gs_param_list * plist, int which)
bool big_endian = tfdev->BigEndian;
bool usebigtiff = tfdev->UseBigTIFF;
bool write_datetime = tfdev->write_datetime;
- uint16 compr = tfdev->Compression;
+ uint16_t compr = tfdev->Compression;
gs_param_string comprstr;
long mss = tfdev->MaxStripSize;
long aw = tfdev->AdjustWidth;
@@ -325,11 +325,16 @@ int tiff_set_compression(gx_device_printer *pdev,
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, pdev->height);
}
else {
- int rows = max_strip_size /
+ int rows = 0;
+
+ if (pdev->width >=1) {
+ rows = max_strip_size /
gdev_mem_bytes_per_scan_line((gx_device *)pdev);
- TIFFSetField(tif,
+ TIFFSetField(tif,
TIFFTAG_ROWSPERSTRIP,
TIFFDefaultStripSize(tif, max(1, rows)));
+ } else
+ return_error(gs_error_rangecheck);
}
return 0;
@@ -355,6 +360,7 @@ int tiff_set_fields_for_printer(gx_device_printer *pdev,
TIFFSetField(tif, TIFFTAG_XRESOLUTION, (float)xpi);
TIFFSetField(tif, TIFFTAG_YRESOLUTION, (float)ypi);
+#ifndef CLUSTER
{
char revs[32];
#define maxSoftware 40
@@ -372,6 +378,7 @@ int tiff_set_fields_for_printer(gx_device_printer *pdev,
TIFFSetField(tif, TIFFTAG_SOFTWARE, softwareValue);
}
+#endif
if (writedatetime) {
struct tm tms;
time_t t;
@@ -458,7 +465,7 @@ tiff_print_page(gx_device_printer *dev, TIFF *tif, int min_feature_size)
if (row - line_lag >= 0) {
#if defined(ARCH_IS_BIG_ENDIAN) && (!ARCH_IS_BIG_ENDIAN)
if (bpc == 16)
- TIFFSwabArrayOfShort((uint16 *)data,
+ TIFFSwabArrayOfShort((uint16_t *)data,
dev->width * (long)dev->color_info.num_components);
#endif
@@ -565,7 +572,7 @@ tiff_downscale_and_print_page(gx_device_printer *dev, TIFF *tif,
static struct compression_string {
- uint16 id;
+ uint16_t id;
const char *str;
} compression_strings [] = {
{ COMPRESSION_NONE, "none" },
@@ -579,7 +586,7 @@ static struct compression_string {
};
int
-tiff_compression_param_string(gs_param_string *param, uint16 id)
+tiff_compression_param_string(gs_param_string *param, uint16_t id)
{
struct compression_string *c;
for (c = compression_strings; c->str; c++)
@@ -591,7 +598,7 @@ tiff_compression_param_string(gs_param_string *param, uint16 id)
}
int
-tiff_compression_id(uint16 *id, gs_param_string *param)
+tiff_compression_id(uint16_t *id, gs_param_string *param)
{
struct compression_string *c;
for (c = compression_strings; c->str; c++)
@@ -604,7 +611,7 @@ tiff_compression_id(uint16 *id, gs_param_string *param)
return_error(gs_error_undefined);
}
-int tiff_compression_allowed(uint16 compression, byte depth)
+int tiff_compression_allowed(uint16_t compression, byte depth)
{
return ((depth == 1 && (compression == COMPRESSION_NONE ||
compression == COMPRESSION_CCITTRLE ||
diff --git a/devices/gdevtifs.h b/devices/gdevtifs.h
index bbd01bb6..17eacb51 100644
--- a/devices/gdevtifs.h
+++ b/devices/gdevtifs.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
@@ -32,7 +32,7 @@ typedef struct gx_device_tiff_s {
gx_prn_device_common;
bool BigEndian; /* true = big endian; false = little endian*/
bool UseBigTIFF; /* true = output big tiff file, false don't */
- uint16 Compression; /* same values as TIFFTAG_COMPRESSION */
+ uint16_t Compression; /* same values as TIFFTAG_COMPRESSION */
long MaxStripSize;
long AdjustWidth; /* 0 = no adjust, 1 = adjust to fax values, >1 = adjust to this */
bool write_datetime;
@@ -63,7 +63,7 @@ void tiff_set_handlers (void);
* Sets the compression tag for TIFF and updates the rows_per_strip tag to
* reflect max_strip_size under the new compression scheme.
*/
-#define TIFF_DEFAULT_STRIP_SIZE 1048576
+#define TIFF_DEFAULT_STRIP_SIZE 8192
#define TIFF_DEFAULT_DOWNSCALE 1
@@ -80,17 +80,17 @@ int gdev_tiff_begin_page(gx_device_tiff *tfdev, gp_file *file);
/*
* Returns the gs_param_string that corresponds to the tiff COMPRESSION_* id.
*/
-int tiff_compression_param_string(gs_param_string *param, uint16 id);
+int tiff_compression_param_string(gs_param_string *param, uint16_t id);
/*
* Returns the COMPRESSION_* id which corresponds to 'str'.
*/
-int tiff_compression_id(uint16 *id, gs_param_string *param);
+int tiff_compression_id(uint16_t *id, gs_param_string *param);
/*
* Returns true if 'compression' can be used for encoding a data with a bit
* depth of 'depth' (crle, g3, and g4 only work on 1-bit devices).
*/
-int tiff_compression_allowed(uint16 compression, byte depth);
+int tiff_compression_allowed(uint16_t compression, byte depth);
#endif /* gdevtifs_INCLUDED */
diff --git a/devices/gdevtsep.c b/devices/gdevtsep.c
index fd859ddc..6d75d600 100644
--- a/devices/gdevtsep.c
+++ b/devices/gdevtsep.c
@@ -445,7 +445,7 @@ tiffscaled24_print_page(gx_device_printer * pdev, gp_file * file)
static void
tiff_set_cmyk_fields(gx_device_printer *pdev, TIFF *tif,
short bits_per_sample,
- uint16 compression,
+ uint16_t compression,
long max_strip_size)
{
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bits_per_sample);
@@ -667,7 +667,7 @@ static dev_proc_decode_color(tiffsep1_decode_color);
bool UseBigTIFF; /* true = output bigtiff, false don't */ \
bool write_datetime; /* true = write DATETIME tag, false = don't */ \
bool PrintSpotCMYK; /* true = print CMYK equivalents for spot inks; false = do nothing */\
- uint16 Compression; /* for the separation files, same values as TIFFTAG_COMPRESSION */\
+ uint16_t Compression; /* for the separation files, same values as TIFFTAG_COMPRESSION */\
long MaxStripSize;\
long BitsPerComponent;\
int max_spots;\
@@ -678,7 +678,8 @@ static dev_proc_decode_color(tiffsep1_decode_color);
bool warning_given; /* avoid issuing lots of warnings */\
gp_file *comp_file; /* Underlying file for tiff_comp */\
TIFF *tiff_comp; /* tiff file for comp file */\
- gsicc_link_t *icclink /* link profile if we are doing post rendering */
+ gsicc_link_t *icclink; /* link profile if we are doing post rendering */\
+ unsigned int page_num_comps /* Number of components at end of page, for cleanup */
/*
* A structure definition for a DeviceN type device
@@ -1224,26 +1225,16 @@ int
tiffsep1_prn_close(gx_device * pdev)
{
tiffsep1_device * const tfdev = (tiffsep1_device *) pdev;
- int num_dev_comp = tfdev->color_info.num_components;
- int num_std_colorants = tfdev->devn_params.num_std_colorant_names;
- int num_order = tfdev->devn_params.num_separation_order_names;
- int num_spot = tfdev->devn_params.separations.num_separations;
char *name= NULL;
int code = gdev_prn_close(pdev);
short map_comp_to_sep[GX_DEVICE_COLOR_MAX_COMPONENTS];
int comp_num;
- int num_comp = number_output_separations(num_dev_comp, num_std_colorants,
- num_order, num_spot);
const char *fmt;
gs_parsed_file_name_t parsed;
if (code < 0)
return code;
- name = (char *)gs_alloc_bytes(pdev->memory, gp_file_name_sizeof, "tiffsep1_prn_close(name)");
- if (!name)
- return_error(gs_error_VMerror);
-
code = gx_parse_output_file_name(&parsed, &fmt, tfdev->fname,
strlen(tfdev->fname), pdev->memory);
if (code < 0) {
@@ -1278,33 +1269,44 @@ tiffsep1_prn_close(gx_device * pdev)
build_comp_to_sep_map((tiffsep_device *)tfdev, map_comp_to_sep);
/* Close the separation files */
- for (comp_num = 0; comp_num < num_comp; comp_num++ ) {
- if (tfdev->sep_file[comp_num] != NULL) {
- int sep_num = map_comp_to_sep[comp_num];
+ for (comp_num = 0; comp_num < tfdev->page_num_comps; comp_num++ ) {
+ const char *lname_empty = "";
+ char *lname = NULL;
- code = create_separation_file_name((tiffsep_device *)tfdev, name,
- gp_file_name_sizeof, sep_num, true);
- if (code < 0) {
- goto done;
- }
- code = gx_device_close_output_file(pdev, name, tfdev->sep_file[comp_num]);
+ if (tfdev->tiff[comp_num] != NULL) {
+ tiff_filename_from_tiff(tfdev->tiff[comp_num], &name);
+ }
+ else {
+ name = (char *)lname_empty;
+ }
+
+ lname = (char *)gs_alloc_bytes(tfdev->memory, strlen(name) + 1, "tiffsep1_prn_close");
+ if (lname == NULL) {
+ code = gs_note_error(gs_error_VMerror);
+ goto done;
+ }
+ memcpy(lname, name, strlen(name) + 1);
+
+ if (tfdev->tiff[comp_num]) {
+ void *t = TIFFClientdata(tfdev->tiff[comp_num]);
+
+ TIFFCleanup(tfdev->tiff[comp_num]);
+ gs_free(pdev->memory, t, sizeof(tifs_io_private), 1, "tiffsep1_prn_close");
+ tfdev->tiff[comp_num] = NULL;
+ }
+ if (tfdev->sep_file[comp_num] != NULL) {
+ code = gx_device_close_output_file(pdev, lname, tfdev->sep_file[comp_num]);
if (code >= 0)
- code = gs_remove_outputfile_control_path(pdev->memory, name);
+ code = gs_remove_outputfile_control_path(pdev->memory, lname);
if (code < 0) {
goto done;
}
tfdev->sep_file[comp_num] = NULL;
}
- if (tfdev->tiff[comp_num]) {
- TIFFCleanup(tfdev->tiff[comp_num]);
- tfdev->tiff[comp_num] = NULL;
- }
+ gs_free_object(tfdev->memory, lname, "tiffsep1_prn_close");
}
done:
-
- if (name)
- gs_free_object(pdev->memory, name, "tiffsep1_prn_close(name)");
return code;
}
@@ -1730,26 +1732,18 @@ int
tiffsep_prn_close(gx_device * pdev)
{
tiffsep_device * const pdevn = (tiffsep_device *) pdev;
- int num_dev_comp = pdevn->color_info.num_components;
- int num_std_colorants = pdevn->devn_params.num_std_colorant_names;
- int num_order = pdevn->devn_params.num_separation_order_names;
- int num_spot = pdevn->devn_params.separations.num_separations;
short map_comp_to_sep[GX_DEVICE_COLOR_MAX_COMPONENTS];
char *name = NULL;
int code;
int comp_num;
- int num_comp = number_output_separations(num_dev_comp, num_std_colorants,
- num_order, num_spot);
gsicc_free_link_dev(pdevn->icclink);
pdevn->icclink = NULL;
- name = (char *)gs_alloc_bytes(pdevn->memory, gp_file_name_sizeof, "tiffsep_prn_close(name)");
- if (!name)
- return_error(gs_error_VMerror);
-
if (pdevn->tiff_comp) {
+ void *t = TIFFClientdata(pdevn->tiff_comp);
TIFFCleanup(pdevn->tiff_comp);
+ gs_free(pdev->memory, t, sizeof(tifs_io_private), 1, "tiffsep_prn_close");
pdevn->tiff_comp = NULL;
}
code = gdev_prn_close(pdev);
@@ -1759,27 +1753,44 @@ tiffsep_prn_close(gx_device * pdev)
build_comp_to_sep_map(pdevn, map_comp_to_sep);
/* Close the separation files */
- for (comp_num = 0; comp_num < num_comp; comp_num++ ) {
- if (pdevn->sep_file[comp_num] != NULL) {
- int sep_num = pdevn->devn_params.separation_order_map[comp_num];
+ for (comp_num = 0; comp_num < pdevn->page_num_comps; comp_num++ ) {
+ const char *lname_empty = "";
+ char *lname = NULL;
- code = create_separation_file_name(pdevn, name,
- gp_file_name_sizeof, sep_num, true);
- if (code < 0) {
- goto done;
- }
- code = tiffsep_close_sep_file(pdevn, name, comp_num);
+ if (pdevn->tiff[comp_num] != NULL) {
+ tiff_filename_from_tiff(pdevn->tiff[comp_num], &name);
+ }
+ else {
+ name = (char *)lname_empty;
+ }
+
+ lname = (char *)gs_alloc_bytes(pdevn->memory, strlen(name) + 1, "tiffsep1_prn_close");
+ if (lname == NULL) {
+ code = gs_note_error(gs_error_VMerror);
+ goto done;
+ }
+ memcpy(lname, name, strlen(name) + 1);
+
+ if (pdevn->tiff[comp_num]) {
+ void *t = TIFFClientdata(pdevn->tiff[comp_num]);
+ TIFFCleanup(pdevn->tiff[comp_num]);
+ gs_free(pdevn->memory, t, sizeof(tifs_io_private), 1, "tiffsep_prn_close");
+ pdevn->tiff[comp_num] = NULL;
+ }
+
+ if (pdevn->sep_file[comp_num]) {
+ code = gx_device_close_output_file((gx_device *)pdevn, lname, pdevn->sep_file[comp_num]);
if (code >= 0)
- code = gs_remove_outputfile_control_path(pdevn->memory, name);
+ code = gs_remove_outputfile_control_path(pdevn->memory, lname);
if (code < 0) {
goto done;
}
+ pdevn->sep_file[comp_num] = NULL;
}
+ gs_free_object(pdevn->memory, lname, "tiffsep1_prn_close");
}
done:
- if (name)
- gs_free_object(pdev->memory, name, "tiffsep_prn_close(name)");
return code;
}
@@ -2123,6 +2134,7 @@ tiffsep_print_page(gx_device_printer * pdev, gp_file * file)
/* Set up the separation output files */
num_comp = number_output_separations( tfdev->color_info.num_components,
num_std_colorants, num_order, num_spot);
+ tfdev->page_num_comps = num_comp;
if (!tfdev->NoSeparationFiles && !num_order && num_comp < num_std_colorants + num_spot) {
dmlprintf(pdev->memory, "Warning: skipping one or more colour separations, see: Devices.htm#TIFF\n");
@@ -2493,6 +2505,8 @@ tiffsep1_print_page(gx_device_printer * pdev, gp_file * file)
/* Set up the separation output files */
num_comp = number_output_separations(tfdev->color_info.num_components,
num_std_colorants, num_order, num_spot);
+ tfdev->page_num_comps = num_comp;
+
build_cmyk_map((gx_device *)tfdev, num_comp, &tfdev->equiv_cmyk_colors, cmyk_map);
if (tfdev->PrintSpotCMYK) {
code = print_cmyk_equivalent_colors((tiffsep_device *)tfdev, num_comp, cmyk_map);
diff --git a/devices/gdevxini.c b/devices/gdevxini.c
index fafcd42a..fcaab232 100644
--- a/devices/gdevxini.c
+++ b/devices/gdevxini.c
@@ -906,16 +906,22 @@ gdev_x_put_params(gx_device * dev, gs_param_list * plist)
/* Get work area */
x_get_work_area(xdev, &area_width, &area_height);
- /* Preserve screen resolution */
- dev->x_pixels_per_inch = values.x_pixels_per_inch;
- dev->y_pixels_per_inch = values.y_pixels_per_inch;
- dev->HWResolution[0] = values.HWResolution[0];
- dev->HWResolution[1] = values.HWResolution[1];
-
- /* Recompute window size using screen resolution and available work area size*/
- /* pixels */
- dev->width = min(dev->width, area_width);
- dev->height = min(dev->height, area_height);
+ /* Prioritize HWResolution over page size. If we can't fit the
+ page size at the requested resolution in the available screen
+ area, keep the resolution, clamp the page size.
+ This replaces the previous solution which refused requests to
+ change resolution at all.
+ */
+ if (dev->width > area_width) {
+ outprintf(dev->memory, "\nWARNING: page width %f at %f dpi exceeds available area, clamping width to %f\n",
+ ((dev->width / 72.0) * dev->HWResolution[0]), dev->HWResolution[0], ((area_width / 72) * dev->HWResolution[0]));
+ dev->width = area_width;
+ }
+ if (dev->height > area_height) {
+ outprintf(dev->memory, "\nWARNING: page height %f at %f dpi exceeds available area, clamping height to %f\n",
+ ((dev->height / 72.0) * dev->HWResolution[1]), dev->HWResolution[1], ((area_height / 72) * dev->HWResolution[1]));
+ dev->height = area_height;
+ }
if (dev->width <= 0 || dev->height <= 0) {
emprintf3(dev->memory, "Requested pagesize %d x %d not supported by %s device\n",
@@ -924,8 +930,8 @@ gdev_x_put_params(gx_device * dev, gs_param_list * plist)
}
/* points */
- dev->MediaSize[0] = (float)dev->width / xdev->x_pixels_per_inch * 72;
- dev->MediaSize[1] = (float)dev->height / xdev->y_pixels_per_inch * 72;
+ dev->MediaSize[0] = (float)dev->width / dev->HWResolution[0] * 72;
+ dev->MediaSize[1] = (float)dev->height / dev->HWResolution[1] * 72;
dw = dev->width - values.width;
dh = dev->height - values.height;
diff --git a/devices/gxfcopy.c b/devices/gxfcopy.c
index 76f0a19e..571ff646 100644
--- a/devices/gxfcopy.c
+++ b/devices/gxfcopy.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
@@ -2108,6 +2108,8 @@ gs_copy_font(gs_font *font, const gs_matrix *orig_matrix, gs_memory_t *mem, gs_f
copied = gs_alloc_struct(mem, gs_font, fstype,
"gs_copy_font(copied font)");
if (copied) {
+ gs_font_base *bfont = (gs_font_base *)copied;
+
/* Initialize the copied font - minumum we need
* so we can safely free it in the "fail:" case
* below
@@ -2118,6 +2120,15 @@ gs_copy_font(gs_font *font, const gs_matrix *orig_matrix, gs_memory_t *mem, gs_f
copied->is_resource = false;
gs_notify_init(&copied->notify_list, mem);
copied->base = copied;
+
+ bfont->FAPI = 0;
+ bfont->FAPI_font_data = 0;
+ bfont->encoding_index = ENCODING_INDEX_UNKNOWN;
+ code = uid_copy(&bfont->UID, mem, "gs_copy_font(UID)");
+ if (code < 0) {
+ uid_set_invalid(&bfont->UID);
+ goto fail;
+ }
}
cfdata = gs_alloc_struct(mem, gs_copied_font_data_t,
&st_gs_copied_font_data,
@@ -2179,16 +2190,6 @@ gs_copy_font(gs_font *font, const gs_matrix *orig_matrix, gs_memory_t *mem, gs_f
copied->procs.encode_char = procs->encode_char;
copied->procs.glyph_info = procs->glyph_info;
copied->procs.glyph_outline = procs->glyph_outline;
- {
- gs_font_base *bfont = (gs_font_base *)copied;
-
- bfont->FAPI = 0;
- bfont->FAPI_font_data = 0;
- bfont->encoding_index = ENCODING_INDEX_UNKNOWN;
- code = uid_copy(&bfont->UID, mem, "gs_copy_font(UID)");
- if (code < 0)
- goto fail;
- }
cfdata->procs = procs;
memset(glyphs, 0, glyphs_size * sizeof(*glyphs));
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)");