summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam James <sam@gentoo.org>2022-03-29 10:27:10 +0100
committerSam James <sam@gentoo.org>2022-04-17 12:53:05 +0100
commit085bde903b9e684c3c1160e4df912bea9a660997 (patch)
treec4f5e6e9f2422e869ca5bc0b944520d451001282 /devices
parentImport Ghostscript 9.55 (diff)
downloadghostscript-gpl-patches-085bde903b9e684c3c1160e4df912bea9a660997.tar.gz
ghostscript-gpl-patches-085bde903b9e684c3c1160e4df912bea9a660997.tar.bz2
ghostscript-gpl-patches-085bde903b9e684c3c1160e4df912bea9a660997.zip
Import Ghostscript 9.56.0ghostscript-9.56
Signed-off-by: Sam James <sam@gentoo.org>
Diffstat (limited to 'devices')
-rw-r--r--devices/devs.mak48
-rw-r--r--devices/extract.mak10
-rw-r--r--devices/gdev8510.c4
-rw-r--r--devices/gdevccr.c8
-rw-r--r--devices/gdevcdj.c4
-rw-r--r--devices/gdevchameleon.c304
-rw-r--r--devices/gdevdjet.c22
-rw-r--r--devices/gdevdsp.c15
-rw-r--r--devices/gdevfpng.c18
-rw-r--r--devices/gdevijs.c18
-rw-r--r--devices/gdevl31s.c8
-rw-r--r--devices/gdevpdfimg.c154
-rw-r--r--devices/gdevpdfocr.c18
-rw-r--r--devices/gdevplan.c178
-rw-r--r--devices/gdevpng.c40
-rw-r--r--devices/gdevpsd.c328
-rw-r--r--devices/gdevtifs.c54
-rw-r--r--devices/gdevtsep.c97
-rw-r--r--devices/gdevupd.c21
-rw-r--r--devices/gdevwpr2.c26
-rw-r--r--devices/gdevxini.c19
-rw-r--r--devices/gxfcopy.c17
-rw-r--r--devices/vector/gdevdocxw.c39
-rw-r--r--devices/vector/gdevpdf.c85
-rw-r--r--devices/vector/gdevpdfb.h1
-rw-r--r--devices/vector/gdevpdfd.c4
-rw-r--r--devices/vector/gdevpdfe.c11
-rw-r--r--devices/vector/gdevpdfg.c78
-rw-r--r--devices/vector/gdevpdfi.c6
-rw-r--r--devices/vector/gdevpdfm.c112
-rw-r--r--devices/vector/gdevpdfo.c6
-rw-r--r--devices/vector/gdevpdfr.c8
-rw-r--r--devices/vector/gdevpdft.c6
-rw-r--r--devices/vector/gdevpdfu.c34
-rw-r--r--devices/vector/gdevpdfv.c18
-rw-r--r--devices/vector/gdevpdfx.h1
-rw-r--r--devices/vector/gdevpdtb.c6
-rw-r--r--devices/vector/gdevpdtc.c51
-rw-r--r--devices/vector/gdevpdte.c30
-rw-r--r--devices/vector/gdevpdtf.c55
-rw-r--r--devices/vector/gdevpdtf.h25
-rw-r--r--devices/vector/gdevpdti.c24
-rw-r--r--devices/vector/gdevpdtt.c59
-rw-r--r--devices/vector/gdevpdtv.c274
-rw-r--r--devices/vector/gdevpdtv.h6
-rw-r--r--devices/vector/gdevpdtw.c24
-rw-r--r--devices/vector/gdevpsf1.c6
-rw-r--r--devices/vector/gdevpsf2.c88
-rw-r--r--devices/vector/gdevtxtw.c55
-rw-r--r--devices/vector/gdevxps.c38
50 files changed, 1717 insertions, 844 deletions
diff --git a/devices/devs.mak b/devices/devs.mak
index 484e0e36..bfe2903a 100644
--- a/devices/devs.mak
+++ b/devices/devs.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
@@ -180,7 +180,8 @@ DEVGEN=$(DEVGENDIR)$(D)
# png16 4-bit color Portable Network Graphics (PNG)
# png256 8-bit color Portable Network Graphics (PNG)
# png16m 24-bit color Portable Network Graphics (PNG)
-# pngalpha 32-bit RGBA color Portable Network Graphics (PNG)
+# pngalpha 32-bit RGBA color Portable Network Graphics (PNG) (aa)
+# png16malpha 32-bit RGBA color Portable Network Graphics (PNG)
# tiffgray TIFF 8-bit gray, no compression
# tiff12nc TIFF 12-bit RGB, no compression
# tiff24nc TIFF 24-bit RGB, no compression (NeXT standard format)
@@ -1165,7 +1166,7 @@ $(DD)chameleon.dev : $(chameleon_) $(GLD)page.dev $(GLD)cielib.dev $(GDEV) \
$(DEVOBJ)gdevchameleon.$(OBJ) : $(DEVSRC)gdevchameleon.c $(PDEVH)\
$(gsparam_h) $(gdevdcrd_h) $(gscrd_h) $(gscrdp_h) $(gxlum_h) $(gxdcconv_h)\
- $(gsutil_h) $(DEVS_MAK) $(MAKEDIRS)
+ $(gsutil_h) $(gsicc_manage_h) $(DEVS_MAK) $(MAKEDIRS)
$(DEVCC) $(DEVO_)gdevchameleon.$(OBJ) $(C_) $(DEVSRC)gdevchameleon.c
### ------------------------- .BMP file formats ------------------------- ###
@@ -1243,12 +1244,18 @@ $(DD)psdrgb.dev : $(psd_) $(GLD)page.dev $(GDEV) $(DEVS_MAK) $(MAKEDIRS)
$(DD)psdcmyk.dev : $(psd_) $(GLD)page.dev $(GDEV) $(DEVS_MAK) $(MAKEDIRS)
$(SETDEV) $(DD)psdcmyk $(psd_)
+$(DD)psdcmyktags.dev : $(psd_) $(GLD)page.dev $(GDEV) $(DEVS_MAK) $(MAKEDIRS)
+ $(SETDEV) $(DD)psdcmyktags $(psd_)
+
$(DD)psdrgb16.dev : $(DEVS_MAK) $(psd_) $(GLD)page.dev $(GDEV)
$(SETDEV) $(DD)psdrgb16 $(psd_)
$(DD)psdcmyk16.dev : $(DEVS_MAK) $(psd_) $(GLD)page.dev $(GDEV)
$(SETDEV) $(DD)psdcmyk16 $(psd_)
+$(DD)psdcmyktags16.dev : $(DEVS_MAK) $(psd_) $(GLD)page.dev $(GDEV)
+ $(SETDEV) $(DD)psdcmyktags16 $(psd_)
+
$(DEVOBJ)gdevpsd.$(OBJ) : $(DEVSRC)gdevpsd.c $(PDEVH) $(math__h)\
$(gdevdcrd_h) $(gscrd_h) $(gscrdp_h) $(gsparam_h) $(gxlum_h)\
$(gstypes_h) $(gxdcconv_h) $(gdevdevn_h) $(gxdevsop_h) $(gsequivc_h)\
@@ -1516,6 +1523,11 @@ $(DD)pngalpha.dev : $(libpng_dev) $(png_) $(GLD)page.dev $(GDEV) \
$(SETPDEV2) $(DD)pngalpha $(png_)
$(ADDMOD) $(DD)pngalpha $(png_i_)
+$(DD)png16malpha.dev : $(libpng_dev) $(png_) $(GLD)page.dev $(GDEV) \
+ $(DEVS_MAK) $(MAKEDIRS)
+ $(SETPDEV2) $(DD)png16malpha $(png_)
+ $(ADDMOD) $(DD)png16malpha $(png_i_)
+
### --------------- Portable Network Graphics file format --------------- ###
### Requires zlib 0.95 (or more recent versions). ###
### See zlib.mak for more details. ###
@@ -1799,8 +1811,8 @@ $(DD)tiffsep1.dev : $(tiffsep_) $(DD)tiffs.dev $(minftrsz_h)\
plan_=$(DEVOBJ)gdevplan.$(OBJ) $(DEVOBJ)gdevppla.$(OBJ) $(DEVOBJ)gdevmpla.$(OBJ)
-$(DEVOBJ)gdevplan.$(OBJ) : $(DEVSRC)gdevplan.c $(PDEVH)\
- $(gdevmpla_h) $(gdevplnx_h) $(gdevppla_h)\
+$(DEVOBJ)gdevplan.$(OBJ) : $(DEVSRC)gdevplan.c $(PDEVH) $(gxdevsop_h)\
+ $(gdevmpla_h) $(gdevplnx_h) $(gdevppla_h) $(gxdownscale_h) $(gsicc_cache_h)\
$(gscdefs_h) $(gscspace_h) $(gxgetbit_h) $(gxiparam_h) $(gxlum_h) \
$(DEVS_MAK) $(MAKEDIRS)
$(DEVCC) $(DEVO_)gdevplan.$(OBJ) $(C_) $(DEVSRC)gdevplan.c
@@ -1888,12 +1900,26 @@ $(DD)pwgraster.dev : $(lcups_dev) $(lcupsi_dev) $(cups_) $(GDEV) $(GLD)page.dev
$(ADDMOD) $(DD)pwgraster -include $(lcupsi_dev)
$(ADDMOD) $(DD)pwgraster -include $(GLD)page
+$(DD)appleraster.dev : $(lcups_dev) $(lcupsi_dev) $(cups_) $(GDEV) $(GLD)page.dev \
+ $(DEVS_MAK) $(MAKEDIRS)
+ $(SETPDEV2) $(DD)appleraster $(cups_)
+ $(ADDMOD) $(DD)appleraster -include $(lcups_dev)
+ $(ADDMOD) $(DD)appleraster -include $(lcupsi_dev)
+ $(ADDMOD) $(DD)appleraster -include $(GLD)page
+
+$(DD)urf.dev : $(lcups_dev) $(lcupsi_dev) $(cups_) $(GDEV) $(GLD)page.dev \
+ $(DEVS_MAK) $(MAKEDIRS)
+ $(SETPDEV2) $(DD)urf $(cups_)
+ $(ADDMOD) $(DD)urf -include $(lcups_dev)
+ $(ADDMOD) $(DD)urf -include $(lcupsi_dev)
+ $(ADDMOD) $(DD)urf -include $(GLD)page
+
$(DEVOBJ)gdevcups.$(OBJ) : $(LCUPSSRCDIR)$(D)gdevcups.c $(std_h) $(gxdevsop_h) $(DEVS_MAK) $(MAKEDIRS)
$(CUPS_CC) $(DEVO_)gdevcups.$(OBJ) $(C_) $(CFLAGS) $(CUPSCFLAGS) \
- $(I_)$(GLSRC) \
- $(I_)$(DEVSRC) \
- $(I_)$(DEVOBJ) $(I_)$(LCUPSSRCDIR)$(D)libs \
- $(LCUPSSRCDIR)$(D)gdevcups.c
+ $(I_)$(GLSRC)$(_I) \
+ $(I_)$(DEVSRC)$(_I) $(I_)$(LIBCUPSSRCDIR)$(D)libs$(_I) \
+ $(I_)$(DEVOBJ)$(_I) \
+ $(LCUPSSRCDIR)$(D)gdevcups.c
### ---------------------------- Tracing -------------------------------- ###
@@ -1943,6 +1969,10 @@ $(DD)PCLm.dev : $(DEVOBJ)gdevpdfimg.$(OBJ) $(GLD)page.dev $(GDEV) $(DEVS_MAK) $(
$(SETPDEV2) $(DD)PCLm $(DEVOBJ)gdevpdfimg.$(OBJ)
$(ADDMOD) $(DD)PCLm -include $(GLD)page
+$(DD)PCLm8.dev : $(DEVOBJ)gdevpdfimg.$(OBJ) $(GLD)page.dev $(GDEV) $(DEVS_MAK) $(MAKEDIRS)
+ $(SETPDEV2) $(DD)PCLm8 $(DEVOBJ)gdevpdfimg.$(OBJ)
+ $(ADDMOD) $(DD)PCLm8 -include $(GLD)page
+
$(DEVOBJ)gdevpdfimg.$(OBJ) : $(DEVSRC)gdevpdfimg.c $(AK) $(gdevkrnlsclass_h) \
$(DEVS_MAK) $(arch_h) $(stdint__h) $(gdevprn_h) $(gxdownscale_h) \
$(stream_h) $(spprint_h) $(time__h) $(smd5_h) $(sstring_h) $(strimpl_h) \
diff --git a/devices/extract.mak b/devices/extract.mak
index 74f1f29c..71f30825 100644
--- a/devices/extract.mak
+++ b/devices/extract.mak
@@ -13,7 +13,7 @@
# CA 94945, U.S.A., +1(415)492-9861, for further information.
#
-extract_cc = $(CC) $(CCFLAGS) $(I_)$(EXTRACT_DIR)/include$(_I) $(I_)$(ZSRCDIR)$(_I) $(O_)
+extract_cc = $(CC) $(CCFLAGS) -DEXTRACT_CV=0 $(I_)$(EXTRACT_DIR)/include$(_I) $(I_)$(ZSRCDIR)$(_I) $(O_)
extract_out_prefix = $(GLOBJDIR)$(D)extract_
$(extract_out_prefix)alloc.$(OBJ): $(EXTRACT_DIR)/src/alloc.c $(MAKEDIRS)
@@ -25,6 +25,9 @@ $(extract_out_prefix)astring.$(OBJ): $(EXTRACT_DIR)/src/astring.c $(MAKED
$(extract_out_prefix)buffer.$(OBJ): $(EXTRACT_DIR)/src/buffer.c $(MAKEDIRS)
$(extract_cc)$@ $(C_) $(EXTRACT_DIR)/src/buffer.c
+$(extract_out_prefix)document.$(OBJ): $(EXTRACT_DIR)/src/document.c $(MAKEDIRS)
+ $(extract_cc)$@ $(C_) $(EXTRACT_DIR)/src/document.c
+
$(extract_out_prefix)docx.$(OBJ): $(EXTRACT_DIR)/src/docx.c $(MAKEDIRS)
$(extract_cc)$@ $(C_) $(EXTRACT_DIR)/src/docx.c
@@ -37,6 +40,9 @@ $(extract_out_prefix)extract.$(OBJ): $(EXTRACT_DIR)/src/extract.c $(MAKED
$(extract_out_prefix)join.$(OBJ): $(EXTRACT_DIR)/src/join.c $(MAKEDIRS)
$(extract_cc)$@ $(C_) $(EXTRACT_DIR)/src/join.c
+$(extract_out_prefix)html.$(OBJ): $(EXTRACT_DIR)/src/html.c $(MAKEDIRS)
+ $(extract_cc)$@ $(C_) $(EXTRACT_DIR)/src/html.c
+
$(extract_out_prefix)mem.$(OBJ): $(EXTRACT_DIR)/src/mem.c $(MAKEDIRS)
$(extract_cc)$@ $(C_) $(EXTRACT_DIR)/src/mem.c
@@ -65,9 +71,11 @@ EXTRACT_OBJS = \
$(extract_out_prefix)alloc.$(OBJ) \
$(extract_out_prefix)astring.$(OBJ) \
$(extract_out_prefix)buffer.$(OBJ) \
+ $(extract_out_prefix)document.$(OBJ) \
$(extract_out_prefix)docx.$(OBJ) \
$(extract_out_prefix)docx_template.$(OBJ) \
$(extract_out_prefix)extract.$(OBJ) \
+ $(extract_out_prefix)html.$(OBJ) \
$(extract_out_prefix)join.$(OBJ) \
$(extract_out_prefix)mem.$(OBJ) \
$(extract_out_prefix)odt.$(OBJ) \
diff --git a/devices/gdev8510.c b/devices/gdev8510.c
index 534435c0..40c9ab80 100644
--- a/devices/gdev8510.c
+++ b/devices/gdev8510.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
@@ -134,7 +134,7 @@ m8510_output_run(gx_device_printer *pdev,
/* Transfer the line of data. */
count = out_end - out;
if (count > 0) {
- gs_sprintf(tmp, "\033g%03d", count/8);
+ gs_snprintf(tmp, sizeof(tmp), "\033g%03d", count/8);
gp_fwrite(tmp, 1, 5, prn_stream);
gp_fwrite(out, 1, count, prn_stream);
gp_fwrite("\r", 1, 1, prn_stream);
diff --git a/devices/gdevccr.c b/devices/gdevccr.c
index 03fcfa59..4f138659 100644
--- a/devices/gdevccr.c
+++ b/devices/gdevccr.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
@@ -220,9 +220,9 @@ static int alloc_rb( gs_memory_t *mem, cmyrow **rb, int rows)
int r;
for(r=0; r<rows; r++)
{
- gs_sprintf((*rb)[r].cname, "C%02x", r);
- gs_sprintf((*rb)[r].mname, "M%02x", r);
- gs_sprintf((*rb)[r].yname, "Y%02x", r);
+ gs_snprintf((*rb)[r].cname, sizeof((*rb)[r].cname), "C%02x", r);
+ gs_snprintf((*rb)[r].mname, sizeof((*rb)[r].mname), "M%02x", r);
+ gs_snprintf((*rb)[r].yname, sizeof((*rb)[r].yname), "Y%02x", r);
(*rb)[r].is_used=0;
}
return 0;
diff --git a/devices/gdevcdj.c b/devices/gdevcdj.c
index 6908067b..cb2160ee 100644
--- a/devices/gdevcdj.c
+++ b/devices/gdevcdj.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
@@ -2040,7 +2040,7 @@ hp_colour_print_page(gx_device_printer * pdev, gp_file * prn_stream, int ptype)
int outbuff_size = 0;
int compression = 0;
int scan = 0;
- int *errors[2];
+ int *errors[2] = { 0 }; /* Shut up coverity */
int code = 0;
const char *cid_string = (const char*) 0;
byte *data[4], *plane_data[4][4], *out_data;
diff --git a/devices/gdevchameleon.c b/devices/gdevchameleon.c
index 6d7ba87c..789a5b01 100644
--- a/devices/gdevchameleon.c
+++ b/devices/gdevchameleon.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
@@ -25,6 +25,7 @@
#include "gdevdcrd.h"
#include "gxdownscale.h"
#include "gxdevsop.h"
+#include "gsicc_manage.h"
/* Define the device parameters. */
#ifndef X_DPI
@@ -45,6 +46,13 @@ static dev_proc_get_params(chameleon_get_params);
static dev_proc_put_params(chameleon_put_params);
static dev_proc_print_page(chameleon_print_page);
static dev_proc_dev_spec_op(chameleon_spec_op);
+static dev_proc_close_device(chameleon_close);
+
+typedef enum {
+ linktype_none = 0,
+ linktype_postrender,
+ linktype_device
+} linktype_t;
struct gx_device_chameleon_s {
gx_device_common;
@@ -56,10 +64,21 @@ struct gx_device_chameleon_s {
int output_as_pxm;
bool language_uses_rops;
gx_downscaler_params downscale;
+ gsicc_link_t *icclink;
+ linktype_t linktype;
+ cmm_profile_t *default_device_profile;
};
typedef struct gx_device_chameleon_s gx_device_chameleon;
static void
+chameleon_finalize(gx_device *dev)
+{
+ gx_device_chameleon *pcdev = (gx_device_chameleon *)dev;
+
+ gsicc_adjust_profile_rc(pcdev->default_device_profile, -1, "chameleon_finalize");
+}
+
+static void
chameleon_initialize_device_procs(gx_device *dev)
{
gdev_prn_initialize_device_procs_bg(dev);
@@ -72,6 +91,8 @@ chameleon_initialize_device_procs(gx_device *dev)
set_dev_proc(dev, encode_color, chameleon_rgb_encode_color);
set_dev_proc(dev, decode_color, chameleon_rgb_decode_color);
set_dev_proc(dev, dev_spec_op, chameleon_spec_op);
+ set_dev_proc(dev, close_device, chameleon_close);
+ dev->finalize = chameleon_finalize;
}
const gx_device_chameleon gs_chameleon_device =
@@ -208,62 +229,143 @@ chameleon_cmyk_decode_color(gx_device * dev, gx_color_index color, gx_color_valu
#undef cvalue
}
-/* # So long, oh, I hate to see you go */
+static int
+fixup_icc_struct(gx_device_chameleon *pcdev, gsicc_colorbuffer_t cs, char *profile)
+{
+ if (pcdev->icc_struct &&
+ pcdev->icc_struct->device_profile[gsDEFAULTPROFILE] &&
+ pcdev->icc_struct->device_profile[gsDEFAULTPROFILE]->data_cs == cs)
+ return 0; /* Already the right profile type */
+
+ rc_decrement(pcdev->icc_struct, "fixup_icc_struct(chameleon)");
+
+ pcdev->icc_struct = gsicc_new_device_profile_array((gx_device *)pcdev);
+ if (pcdev->icc_struct == NULL)
+ return gs_error_VMerror;
+
+ return gsicc_set_device_profile((gx_device *)pcdev, pcdev->memory,
+ profile, gsDEFAULTPROFILE);
+}
+
+static void reset_icclink(gx_device_chameleon *pcdev)
+{
+ gsicc_free_link_dev(pcdev->icclink);
+ pcdev->icclink = NULL;
+ pcdev->linktype = linktype_none;
+}
+
static void
+stash_default_device_profile(gx_device_chameleon *pcdev)
+{
+ if (pcdev->default_device_profile != NULL)
+ return;
+
+ pcdev->default_device_profile = pcdev->icc_struct->device_profile[gsDEFAULTPROFILE];
+ gsicc_adjust_profile_rc(pcdev->default_device_profile, 1, "stash_default_device_profile");
+}
+
+/* # So long, oh, I hate to see you go */
+static int
reconfigure_baby(gx_device_chameleon *pcdev)
{
int bpc = pcdev->dst_bpc;
int num_comps = pcdev->dst_num_components;
+ int code;
+
+ stash_default_device_profile(pcdev);
if (pcdev->language_uses_rops) {
bpc = 8;
num_comps = 3;
}
- if (pcdev->bpc != bpc ||
- pcdev->num_components != num_comps) {
-
- gs_closedevice((gx_device *)pcdev);
-
- pcdev->bpc = bpc;
- pcdev->num_components = num_comps;
-
- switch (num_comps * bpc) {
- case 1*1: case 1*2: case 1*4: case 1*8:
- case 4*4: case 4*8:
- pcdev->color_info.depth = bpc * num_comps;
- break;
- case 3*1:
- pcdev->color_info.depth = 4;
- break;
- case 3*2:
- pcdev->color_info.depth = 8;
- break;
- case 3*4:
- pcdev->color_info.depth = 16;
- break;
- }
- pcdev->color_info.max_gray = pcdev->color_info.max_color =
- (pcdev->color_info.dither_grays = pcdev->color_info.dither_colors = 1<<bpc) - 1;
-
- set_dev_proc(pcdev, map_cmyk_color, NULL);
- set_dev_proc(pcdev, map_rgb_color, NULL);
- set_dev_proc(pcdev, map_color_rgb, NULL);
- set_dev_proc(pcdev, encode_color,
- num_comps == 1 ? chameleon_mono_encode_color :
- num_comps == 4 ? chameleon_cmyk_encode_color :
- chameleon_rgb_encode_color);
- set_dev_proc(pcdev, decode_color,
- num_comps == 1 ? chameleon_mono_decode_color :
- num_comps == 4 ? chameleon_cmyk_decode_color :
- chameleon_rgb_decode_color);
-
- /* Reset the separable and linear shift, masks, bits. */
- set_linear_color_bits_mask_shift((gx_device *)pcdev);
- pcdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN;
- pcdev->bpc = bpc;
- pcdev->num_components = num_comps;
+ if (pcdev->bpc == bpc && pcdev->num_components == num_comps)
+ return 0; /* Nothing needs to change! */
+
+ gs_closedevice((gx_device *)pcdev);
+
+ pcdev->bpc = bpc;
+ pcdev->num_components = num_comps;
+
+ switch (num_comps * bpc) {
+ case 1*1: case 1*2: case 1*4: case 1*8:
+ case 3*8:
+ case 4*4: case 4*8:
+ pcdev->color_info.depth = bpc * num_comps;
+ break;
+ case 3*1:
+ pcdev->color_info.depth = 4;
+ break;
+ case 3*2:
+ pcdev->color_info.depth = 8;
+ break;
+ case 3*4:
+ pcdev->color_info.depth = 16;
+ break;
}
+ pcdev->color_info.num_components = num_comps;
+ pcdev->color_info.max_components = num_comps;
+ pcdev->color_info.max_gray = pcdev->color_info.max_color =
+ (pcdev->color_info.dither_grays = pcdev->color_info.dither_colors = 1<<bpc) - 1;
+
+ switch (num_comps) {
+ case 1:
+ set_dev_proc(pcdev, encode_color, chameleon_mono_encode_color);
+ set_dev_proc(pcdev, decode_color, chameleon_mono_decode_color);
+ set_dev_proc(pcdev, get_color_mapping_procs,
+ gx_default_DevGray_get_color_mapping_procs);
+ set_dev_proc(pcdev, get_color_comp_index,
+ gx_default_DevGray_get_color_comp_index);
+ pcdev->color_info.polarity = GX_CINFO_POLARITY_ADDITIVE;
+ pcdev->color_info.cm_name = "DeviceGray";
+ pcdev->color_info.gray_index = 0;
+ code = fixup_icc_struct(pcdev, gsGRAY, DEFAULT_GRAY_ICC);
+ if (code < 0)
+ return code;
+ break;
+ case 3:
+ set_dev_proc(pcdev, encode_color, chameleon_rgb_encode_color);
+ set_dev_proc(pcdev, decode_color, chameleon_rgb_decode_color);
+ set_dev_proc(pcdev, get_color_mapping_procs,
+ gx_default_DevRGB_get_color_mapping_procs);
+ set_dev_proc(pcdev, get_color_comp_index,
+ gx_default_DevRGB_get_color_comp_index);
+ pcdev->color_info.polarity = GX_CINFO_POLARITY_ADDITIVE;
+ pcdev->color_info.cm_name = "DeviceRGB";
+ pcdev->color_info.gray_index = GX_CINFO_COMP_NO_INDEX;
+ code = fixup_icc_struct(pcdev, gsRGB, DEFAULT_RGB_ICC);
+ if (code < 0)
+ return code;
+ break;
+ case 4:
+ set_dev_proc(pcdev, encode_color, chameleon_cmyk_encode_color);
+ set_dev_proc(pcdev, decode_color, chameleon_cmyk_decode_color);
+ set_dev_proc(pcdev, get_color_mapping_procs,
+ gx_default_DevCMYK_get_color_mapping_procs);
+ set_dev_proc(pcdev, get_color_comp_index,
+ gx_default_DevCMYK_get_color_comp_index);
+ pcdev->color_info.polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
+ pcdev->color_info.cm_name = "DevicCMYK";
+ pcdev->color_info.gray_index = 3;
+ code = fixup_icc_struct(pcdev, gsCMYK, DEFAULT_CMYK_ICC);
+ if (code < 0)
+ return code;
+ break;
+ }
+ set_dev_proc(pcdev, map_color_rgb, dev_proc(pcdev, decode_color));
+ set_dev_proc(pcdev, map_cmyk_color, dev_proc(pcdev, encode_color));
+ set_dev_proc(pcdev, map_rgb_color, dev_proc(pcdev, encode_color));
+
+ /* Reset the separable and linear shift, masks, bits. */
+ set_linear_color_bits_mask_shift((gx_device *)pcdev);
+ pcdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN;
+ pcdev->bpc = bpc;
+ pcdev->num_components = num_comps;
+
+ /* Invalidate the link. */
+ reset_icclink(pcdev);
+
+ return 0;
}
/* Get parameters. We provide a default CRD. */
@@ -357,9 +459,7 @@ chameleon_put_params(gx_device * pdev, gs_param_list * plist)
pcdev->output_as_pxm = pxm;
pcdev->language_uses_rops = language_uses_rops;
- reconfigure_baby(pcdev);
-
- return 0;
+ return reconfigure_baby(pcdev);
}
static int
@@ -374,35 +474,6 @@ chameleon_spec_op(gx_device *dev_, int op, void *data, int datasize)
}
static int
-craprgbtocmyk(void *arg,
- byte **dst,
- byte **src,
- int w,
- int h,
- int raster)
-{
- byte *d = *dst;
- byte *s = *src;
-
- while (w--) {
- int c = 255-*s++;
- int m = 255-*s++;
- int y = 255-*s++;
- int k = c;
- if (k > m)
- k = m;
- if (k > y)
- k = y;
- *d++ = c - k;
- *d++ = m - k;
- *d++ = y - k;
- *d++ = k;
- }
-
- return 0;
-}
-
-static int
header_4x1(gp_file *file, gx_device_chameleon *pcdev)
{
gp_fprintf(file, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\nTUPLTYPE CMYK\nENDHDR\n",
@@ -448,12 +519,20 @@ header_3x8(gp_file *file, gx_device_chameleon *pcdev)
}
static int
+header_4x8(gp_file *file, gx_device_chameleon *pcdev)
+{
+ gp_fprintf(file, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\nTUPLTYPE CMYK\nENDHDR\n",
+ pcdev->width, pcdev->height);
+ return 0;
+}
+
+static int
do_fwrite(const byte *data, int n, gp_file *file)
{
return gp_fwrite(data, 1, (n+7)>>3, file);
}
-static int tiff_chunky_post_cm(void *arg, byte **dst, byte **src, int w, int h,
+static int chunky_post_cm(void *arg, byte **dst, byte **src, int w, int h,
int raster)
{
gsicc_bufferdesc_t input_buffer_desc, output_buffer_desc;
@@ -517,8 +596,6 @@ chameleon_print_page(gx_device_printer * pdev, gp_file * prn_stream)
int (*write)(const byte *, int, gp_file *) = do_fwrite;
int (*header)(gp_file *, gx_device_chameleon *) = NULL;
int bitwidth;
- gx_downscale_cm_fn *col_convert = NULL;
- void *col_convert_arg = NULL;
switch (pcdev->dst_num_components * pcdev->dst_bpc) {
case 1*1: case 1*2: case 1*4: case 1*8:
@@ -552,6 +629,8 @@ chameleon_print_page(gx_device_printer * pdev, gp_file * prn_stream)
case 4:
if (pcdev->dst_bpc == 1)
header = header_4x1, write = write_4x1;
+ else if (pcdev->dst_bpc == 8)
+ header = header_4x8;
break;
case 3:
if (pcdev->dst_bpc == 8)
@@ -565,18 +644,48 @@ chameleon_print_page(gx_device_printer * pdev, gp_file * prn_stream)
* components, then use that. */
if (pcdev->icc_struct->postren_profile &&
pcdev->icc_struct->postren_profile->num_comps == pcdev->dst_num_components) {
- col_convert = tiff_chunky_post_cm;
- col_convert_arg = pcdev->icc_struct->postren_profile;
- }
- /* Can we get away with no conversion? */
- else if (pcdev->num_components == pcdev->dst_num_components &&
- pcdev->bpc == pcdev->dst_bpc) {
+ if (pcdev->linktype != linktype_postrender) {
+ reset_icclink(pcdev);
+ code = gx_downscaler_create_post_render_link((gx_device *)pdev,
+ &pcdev->icclink);
+ if (code < 0)
+ return code;
+ pcdev->linktype = linktype_postrender;
+ }
+ } else if (pcdev->num_components == pcdev->dst_num_components &&
+ pcdev->bpc == pcdev->dst_bpc) {
/* Nothing to do */
- }
- /* Otherwise, use some inbuilt crap conversions */
- else if (pcdev->num_components == 3 && pcdev->bpc == 8 && pcdev->dst_num_components == 4) {
- col_convert = craprgbtocmyk;
- col_convert_arg = NULL;
+ reset_icclink(pcdev);
+ } else if (pcdev->bpc == 8 && pcdev->dst_num_components == 4) {
+ if (pcdev->linktype != linktype_device) {
+ reset_icclink(pcdev);
+ code = gx_downscaler_create_icc_link((gx_device *)pdev,
+ &pcdev->icclink,
+ pcdev->default_device_profile);
+ if (code < 0)
+ return code;
+ pcdev->linktype = linktype_device;
+ }
+ } else if (pcdev->bpc == 8 && pcdev->dst_num_components == 3) {
+ if (pcdev->linktype != linktype_device) {
+ reset_icclink(pcdev);
+ code = gx_downscaler_create_icc_link((gx_device *)pdev,
+ &pcdev->icclink,
+ pcdev->default_device_profile);
+ if (code < 0)
+ return code;
+ pcdev->linktype = linktype_device;
+ }
+ } else if (pcdev->bpc == 8 && pcdev->dst_num_components == 1) {
+ if (pcdev->linktype != linktype_device) {
+ reset_icclink(pcdev);
+ code = gx_downscaler_create_icc_link((gx_device *)pdev,
+ &pcdev->icclink,
+ pcdev->default_device_profile);
+ if (code < 0)
+ return code;
+ pcdev->linktype = linktype_device;
+ }
} else {
emprintf(pdev->memory, "Chameleon device doesn't support this color conversion.\n");
return gs_error_rangecheck;
@@ -589,7 +698,8 @@ chameleon_print_page(gx_device_printer * pdev, gp_file * prn_stream)
pcdev->num_components,
&pcdev->downscale,
NULL, 0, /* Adjust width */
- col_convert, col_convert_arg, /* Color Management */
+ pcdev->icclink ? chunky_post_cm : NULL,
+ pcdev->icclink, /* Color Management */
pcdev->dst_num_components,
default_ht);
if (code < 0)
@@ -613,3 +723,13 @@ cleanup:
gs_free_object(pdev->memory, in_alloc, "chameleon_print_page(in)");
return code;
}
+
+static int
+chameleon_close(gx_device *pdev)
+{
+ gx_device_chameleon *pcdev = (gx_device_chameleon *)pdev;
+
+ gsicc_free_link_dev(pcdev->icclink);
+ pcdev->icclink = NULL;
+ return gdev_prn_close(pdev);
+}
diff --git a/devices/gdevdjet.c b/devices/gdevdjet.c
index 1ded0813..d2f936d1 100644
--- a/devices/gdevdjet.c
+++ b/devices/gdevdjet.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
@@ -330,7 +330,7 @@ ljet4pjl_close(gx_device *pdev)
init string is stored in buf, so make sure that buf is at least 5
bytes larger than str. */
static void
-hpjet_make_init(gx_device_printer *pdev, char *buf, const char *str)
+hpjet_make_init(gx_device_printer *pdev, char buf[80], const char *str)
{
gx_device_hpjet *dev = (gx_device_hpjet *)pdev;
int paper_source = -1;
@@ -339,9 +339,9 @@ hpjet_make_init(gx_device_printer *pdev, char *buf, const char *str)
else if (dev->MediaPosition_set && dev->MediaPosition >= 0)
paper_source = dev->MediaPosition;
if (paper_source >= 0)
- gs_sprintf(buf, "%s\033&l%dH", str, paper_source);
+ gs_snprintf(buf, 80, "%s\033&l%dH", str, paper_source);
else
- gs_sprintf(buf, "%s", str);
+ gs_snprintf(buf, 80, "%s", str);
}
/* The DeskJet can compress (mode 2) */
@@ -377,7 +377,7 @@ fs600_print_page_copies(gx_device_printer * pdev, gp_file * prn_stream,
char base_init[60];
char init[80];
- gs_sprintf(base_init, "\033*r0F\033&u%dD", dots_per_inch);
+ gs_snprintf(base_init, sizeof(base_init), "\033*r0F\033&u%dD", dots_per_inch);
hpjet_make_init(pdev, init, base_init);
return dljet_mono_print_page_copies(pdev, prn_stream, num_copies,
dots_per_inch, PCL_FS600_FEATURES,
@@ -441,7 +441,7 @@ ljet3d_print_page_copies(gx_device_printer * pdev, gp_file * prn_stream,
bool tumble=dev->Tumble;
hpjet_make_init(pdev, init, "\033&l-180u36Z\033*r0F");
- gs_sprintf(even_init, "\033&l180u36Z\033*r0F");
+ gs_snprintf(even_init, sizeof(even_init), "\033&l180u36Z\033*r0F");
return dljet_mono_print_page_copies(pdev, prn_stream, num_copies,
300, PCL_LJ3D_FEATURES, init, even_init, tumble);
}
@@ -456,9 +456,9 @@ ljet4_print_page_copies(gx_device_printer * pdev, gp_file * prn_stream,
char base_init[60];
char init[80];
- gs_sprintf(base_init, "\033&l-180u36Z\033*r0F\033&u%dD", dots_per_inch);
+ gs_snprintf(base_init, sizeof(base_init), "\033&l-180u36Z\033*r0F\033&u%dD", dots_per_inch);
if (gdev_pcl_page_orientation((gx_device *) pdev) == PAGE_ORIENTATION_LANDSCAPE)
- gs_sprintf(base_init, "\033&l0u140Z\033*r0F\033&u%dD", dots_per_inch);
+ gs_snprintf(base_init, sizeof(base_init), "\033&l0u140Z\033*r0F\033&u%dD", dots_per_inch);
hpjet_make_init(pdev, init, base_init);
return dljet_mono_print_page_copies(pdev, prn_stream, num_copies,
@@ -490,9 +490,9 @@ ljet4d_print_page_copies(gx_device_printer * pdev, gp_file * prn_stream,
in duplex mode we set this parameters for each odd page
(paper tray is set by "hpjet_make_init")
*/
- gs_sprintf(base_init, "\033&l-180u36Z\033*r0F\033&u%dD", dots_per_inch);
+ gs_snprintf(base_init, sizeof(base_init), "\033&l-180u36Z\033*r0F\033&u%dD", dots_per_inch);
hpjet_make_init(pdev, init, base_init);
- gs_sprintf(even_init, "\033&l180u36Z\033*r0F\033&u%dD", dots_per_inch);
+ gs_snprintf(even_init, sizeof(even_init), "\033&l180u36Z\033*r0F\033&u%dD", dots_per_inch);
return dljet_mono_print_page_copies(pdev, prn_stream, num_copies,
dots_per_inch, PCL_LJ4D_FEATURES,
init,even_init,tumble);
@@ -507,7 +507,7 @@ ljet4pjl_print_page_copies(gx_device_printer *pdev, gp_file *prn_stream,
{ int dots_per_inch = (int)pdev->y_pixels_per_inch;
char real_init[60];
- gs_sprintf(real_init, "\033&l-180u36Z\033*r0F\033&u%dD", dots_per_inch);
+ gs_snprintf(real_init, sizeof(real_init), "\033&l-180u36Z\033*r0F\033&u%dD", dots_per_inch);
return dljet_mono_print_page_copies(pdev, prn_stream, num_copies,
dots_per_inch, PCL_LJ4PJL_FEATURES,
real_init, real_init, false);
diff --git a/devices/gdevdsp.c b/devices/gdevdsp.c
index d772ccfd..f757666a 100644
--- a/devices/gdevdsp.c
+++ b/devices/gdevdsp.c
@@ -372,7 +372,7 @@ display_output_page(gx_device * dev, int copies, int flush)
}
if (code >= 0)
- code = gx_finish_output_page(dev, copies, flush);
+ code = gx_finish_output_page((gx_device *)ddev, copies, flush);
return code;
}
@@ -1276,12 +1276,12 @@ display_separation_decode_color(gx_device * dev, gx_color_index color,
* Device proc for updating the equivalent CMYK color for spot colors.
*/
static int
-display_update_spot_equivalent_colors(gx_device * dev, const gs_gstate * pgs)
+display_update_spot_equivalent_colors(gx_device * dev, const gs_gstate * pgs, const gs_color_space *pcs)
{
gx_device_display * ddev = (gx_device_display *)dev;
if ((ddev->nFormat & DISPLAY_COLORS_MASK) == DISPLAY_COLORS_SEPARATION)
- update_spot_equivalent_cmyk_colors(dev, pgs,
+ update_spot_equivalent_cmyk_colors(dev, pgs, pcs,
&ddev->devn_params, &ddev->equiv_cmyk_colors);
return 0;
}
@@ -1810,6 +1810,10 @@ display_set_separations(gx_device_display *dev)
int sep_num;
int sep_name_size;
unsigned int c, m, y, k;
+ gx_device_display *head = dev;
+
+ while(head->parent)
+ head = (gx_device_display *)head->parent;
/* Map the separation numbers to component numbers */
memset(comp_map, 0, sizeof(comp_map));
@@ -1858,10 +1862,7 @@ display_set_separations(gx_device_display *dev)
* 65535 / frac_1;
}
}
- while(dev->parent)
- dev = (gx_device_display *)dev->parent;
-
- (*dev->callback->display_separation)(dev->pHandle, dev,
+ (*head->callback->display_separation)(dev->pHandle, head,
comp_num, name,
(unsigned short)c, (unsigned short)m,
(unsigned short)y, (unsigned short)k);
diff --git a/devices/gdevfpng.c b/devices/gdevfpng.c
index d57df8f8..f533d777 100644
--- a/devices/gdevfpng.c
+++ b/devices/gdevfpng.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
@@ -301,6 +301,8 @@ static int fpng_process(void *arg, gx_device *dev, gx_device *bdev, const gs_int
p = params.data[0];
stream.next_out = &buffer->data[0];
stream.avail_out = buffer->size;
+ stream.total_out = 0;
+ stream.total_in = 0;
/* Nasty zlib hackery here. Zlib always outputs a 'start of stream'
* marker at the beginning. We just want a block, so for all blocks
@@ -311,7 +313,9 @@ static int fpng_process(void *arg, gx_device *dev, gx_device *bdev, const gs_int
{
stream.next_in = &sub;
stream.avail_in = 1;
- deflate(&stream, Z_FULL_FLUSH);
+ err = deflate(&stream, Z_FULL_FLUSH);
+ if (err != Z_OK)
+ return_error(gs_error_VMerror);
stream.next_out = &buffer->data[0];
stream.avail_out = buffer->size;
stream.total_out = 0;
@@ -321,15 +325,19 @@ static int fpng_process(void *arg, gx_device *dev, gx_device *bdev, const gs_int
for (y = h-1; y >= 0; y--)
{
stream.avail_in = 1;
- deflate(&stream, Z_NO_FLUSH);
+ err = deflate(&stream, Z_NO_FLUSH);
+ if (err != Z_OK)
+ return_error(gs_error_VMerror);
stream.next_in = p;
stream.avail_in = w*3;
- deflate(&stream, (y == 0 ? (lastband ? Z_FINISH : Z_FULL_FLUSH) : Z_NO_FLUSH));
+ err = deflate(&stream, (y == 0 ? (lastband ? Z_FINISH : Z_FULL_FLUSH) : Z_NO_FLUSH));
+ if (err != Z_OK)
+ return_error(gs_error_VMerror);
p += raster;
stream.next_in = &paeth;
}
/* Ignore errors given here */
- deflateEnd(&stream);
+ (void)deflateEnd(&stream);
buffer->compressed = stream.total_out;
diff --git a/devices/gdevijs.c b/devices/gdevijs.c
index 0252e3b5..3851f911 100644
--- a/devices/gdevijs.c
+++ b/devices/gdevijs.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
@@ -633,7 +633,7 @@ gsijs_set_margin_params(gx_device_ijs *ijsdev)
}
if (code == 0) {
- gs_sprintf (buf, "%gx%g", ijsdev->MediaSize[0] * (1.0 / 72),
+ gs_snprintf (buf, sizeof(buf), "%gx%g", ijsdev->MediaSize[0] * (1.0 / 72),
ijsdev->MediaSize[1] * (1.0 / 72));
code = ijs_client_set_param(ijsdev->ctx, 0, "PaperSize",
buf, strlen(buf));
@@ -678,7 +678,7 @@ gsijs_set_margin_params(gx_device_ijs *ijsdev)
m[1] = ijsdev->MediaSize[1] * (1.0 / 72) -
printable_top - printable_height;
gx_device_set_margins((gx_device *)ijsdev, m, true);
- gs_sprintf (buf, "%gx%g", printable_left, printable_top);
+ gs_snprintf (buf, sizeof(buf), "%gx%g", printable_left, printable_top);
code = ijs_client_set_param(ijsdev->ctx, 0, "TopLeft",
buf, strlen(buf));
}
@@ -848,7 +848,7 @@ gsijs_open(gx_device *dev)
/* Note: dup() may not be portable to all interesting IJS
platforms. In that case, this branch should be #ifdef'ed out.
*/
- gs_sprintf(buf, "%d", fd);
+ gs_snprintf(buf, sizeof(buf), "%d", fd);
ijs_client_set_param(ijsdev->ctx, 0, "OutputFD", buf, strlen(buf));
close(fd);
} else {
@@ -1013,9 +1013,9 @@ gsijs_output_page(gx_device *dev, int num_copies, int flush)
}
/* Required page parameters */
- gs_sprintf(buf, "%d", n_chan);
+ gs_snprintf(buf, sizeof(buf), "%d", n_chan);
gsijs_client_set_param(ijsdev, "NumChan", buf);
- gs_sprintf(buf, "%d", ijsdev->BitsPerSample);
+ gs_snprintf(buf, sizeof(buf), "%d", ijsdev->BitsPerSample);
gsijs_client_set_param(ijsdev, "BitsPerSample", buf);
/* This needs to become more sophisticated for DeviceN. */
@@ -1023,12 +1023,12 @@ gsijs_output_page(gx_device *dev, int num_copies, int flush)
((n_chan == 3) ? (krgb_mode ? ((k_bits == 1) ? "KRGB" : "KxRGB") : "DeviceRGB") : "DeviceGray"));
gsijs_client_set_param(ijsdev, "ColorSpace", buf);
- gs_sprintf(buf, "%d", ijs_width);
+ gs_snprintf(buf, sizeof(buf), "%d", ijs_width);
gsijs_client_set_param(ijsdev, "Width", buf);
- gs_sprintf(buf, "%d", ijs_height);
+ gs_snprintf(buf, sizeof(buf), "%d", ijs_height);
gsijs_client_set_param(ijsdev, "Height", buf);
- gs_sprintf(buf, "%gx%g", xres, yres);
+ gs_snprintf(buf, sizeof(buf), "%gx%g", xres, yres);
gsijs_client_set_param(ijsdev, "Dpi", buf);
#ifdef KRGB_DEBUG
diff --git a/devices/gdevl31s.c b/devices/gdevl31s.c
index 8832c13a..5532ec5e 100644
--- a/devices/gdevl31s.c
+++ b/devices/gdevl31s.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
@@ -191,9 +191,9 @@ lj3100sw_print_page_copies(gx_device_printer *pdev, gp_file *prn_stream, int num
if (gdev_prn_file_is_new(pdev)) {
lj3100sw_output_section_header(prn_stream, 1, 0, 0);
lj3100sw_output_repeated_data_bytes(prn_stream, buffer, &ptr, 0x1b, 12);
- ptr += gs_sprintf(ptr, "\r\nBD");
+ ptr += gs_snprintf(ptr, sizeof(buffer) - (ptr - buffer), "\r\nBD");
lj3100sw_output_repeated_data_bytes(prn_stream, buffer, &ptr, 0, 5520);
- ptr += gs_sprintf(ptr, "%s\r\n%s %d\r\n%s %d\r\n%s %d\r\n%s %d\r\n%s %d\r\n%s %d\r\n",
+ ptr += gs_snprintf(ptr, sizeof(buffer) - (ptr - buffer), "%s\r\n%s %d\r\n%s %d\r\n%s %d\r\n%s %d\r\n%s %d\r\n%s %d\r\n",
"NJ",
"PQ", -1,
"RE", high_resolution ? 6 : 2,
@@ -205,7 +205,7 @@ lj3100sw_print_page_copies(gx_device_printer *pdev, gp_file *prn_stream, int num
}
lj3100sw_output_section_header(prn_stream, 3, ppdev->NumCopies, 0);
- ptr += gs_sprintf(ptr, "%s %d\r\n%s\r\n",
+ ptr += gs_snprintf(ptr, sizeof(buffer) - (ptr - buffer), "%s %d\r\n%s\r\n",
"CM", 1,
"PD");
*ptr++ = 0;
diff --git a/devices/gdevpdfimg.c b/devices/gdevpdfimg.c
index 81e7a48e..d0b412ec 100644
--- a/devices/gdevpdfimg.c
+++ b/devices/gdevpdfimg.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
@@ -200,8 +200,6 @@ static int gdev_pdf_image_begin_page(gx_device_pdf_image *pdf_dev,
gp_file *file)
{
gx_device_printer *const pdev = (gx_device_printer *)pdf_dev;
- cmm_dev_profile_t *profile_struct;
- gsicc_rendering_param_t rendering_params;
int code;
pdfimage_page *page;
@@ -213,39 +211,11 @@ static int gdev_pdf_image_begin_page(gx_device_pdf_image *pdf_dev,
if (gdev_prn_file_is_new(pdev)) {
/* Set up the icc link settings at this time */
- code = dev_proc(pdev, get_profile)((gx_device *)pdev, &profile_struct);
- if (code < 0)
- return_error(gs_error_undefined);
- if (profile_struct->postren_profile != NULL) {
- rendering_params.black_point_comp = gsBLACKPTCOMP_ON;
- rendering_params.graphics_type_tag = GS_UNKNOWN_TAG;
- rendering_params.override_icc = false;
- rendering_params.preserve_black = gsBLACKPRESERVE_OFF;
- rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC;
- rendering_params.cmm = gsCMM_DEFAULT;
- if (profile_struct->oi_profile != NULL) {
- pdf_dev->icclink = gsicc_alloc_link_dev(pdev->memory,
- profile_struct->oi_profile, profile_struct->postren_profile,
- &rendering_params);
- } else if (profile_struct->link_profile != NULL) {
- pdf_dev->icclink = gsicc_alloc_link_dev(pdev->memory,
- profile_struct->link_profile, profile_struct->postren_profile,
- &rendering_params);
- } else {
- pdf_dev->icclink = gsicc_alloc_link_dev(pdev->memory,
- profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], profile_struct->postren_profile,
- &rendering_params);
- }
- if (pdf_dev->icclink == NULL) {
- gs_free_object(pdf_dev->memory->non_gc_memory, page, "pdfimage create new page");
- return_error(gs_error_VMerror);
- }
- /* If it is identity, release it now and set link to NULL */
- if (pdf_dev->icclink->is_identity) {
- pdf_dev->icclink->procs.free_link(pdf_dev->icclink);
- gsicc_free_link_dev(pdev->memory, pdf_dev->icclink);
- pdf_dev->icclink = NULL;
- }
+ code = gx_downscaler_create_post_render_link((gx_device *)pdev,
+ &pdf_dev->icclink);
+ if (code < 0) {
+ gs_free_object(pdf_dev->memory->non_gc_memory, page, "pdfimage create new page");
+ return code;
}
/* Set up the stream and insert the file header */
@@ -603,7 +573,7 @@ pdf_image_downscale_and_print_page(gx_device_printer *dev,
pprintd1(pdf_dev->strm, "%d 0 obj\n", page->PageDictObjectNumber);
pprintd1(pdf_dev->strm, "<<\n/Contents %d 0 R\n", page->PageStreamObjectNumber);
stream_puts(pdf_dev->strm, "/Type /Page\n/Parent 2 0 R\n");
- gs_sprintf(Buffer, "/MediaBox [0 0 %f %f]\n", ((double)pdf_dev->width / pdf_dev->HWResolution[0]) * 72, ((double)pdf_dev->height / pdf_dev->HWResolution[1]) * 72);
+ gs_snprintf(Buffer, sizeof(Buffer), "/MediaBox [0 0 %f %f]\n", ((double)pdf_dev->width / pdf_dev->HWResolution[0]) * 72, ((double)pdf_dev->height / pdf_dev->HWResolution[1]) * 72);
stream_puts(pdf_dev->strm, Buffer);
pprintd1(pdf_dev->strm, "/Resources <<\n/XObject <<\n/Im1 %d 0 R\n>>\n", page->ImageObjectNumber);
if (pdf_dev->ocr.file_init)
@@ -699,7 +669,7 @@ static void write_xref_entry (stream *s, gs_offset_t Offset)
if (Offset > 9999999999){
Offset = 0;
}
- gs_sprintf(O, "%d", Offset);
+ gs_snprintf(O, sizeof(O), "%d", Offset);
for (i=0; i< (10 - strlen(O)); i++)
stream_puts(s, "0");
stream_puts(s, O);
@@ -707,13 +677,13 @@ static void write_xref_entry (stream *s, gs_offset_t Offset)
}
static void
-pdf_store_default_Producer(char *buf)
+pdf_store_default_Producer(char buf[256])
{
int major = (int)(gs_revision / 1000);
int minor = (int)(gs_revision - (major * 1000)) / 10;
int patch = gs_revision % 10;
- gs_sprintf(buf, "(%s %d.%02d.%d)", gs_product, major, minor, patch);
+ gs_snprintf(buf, 256, "(%s %d.%02d.%d)", gs_product, major, minor, patch);
}
static int pdf_image_finish_file(gx_device_pdf_image *pdf_dev, int PCLm)
@@ -759,7 +729,7 @@ static int pdf_image_finish_file(gx_device_pdf_image *pdf_dev, int PCLm)
tms = *localtime(&t);
#endif
- gs_sprintf(CreationDate, "(D:%04d%02d%02d%02d%02d%02d%c%02d\'%02d\')",
+ gs_snprintf(CreationDate, sizeof(CreationDate), "(D:%04d%02d%02d%02d%02d%02d%c%02d\'%02d\')",
tms.tm_year + 1900, tms.tm_mon + 1, tms.tm_mday,
tms.tm_hour, tms.tm_min, tms.tm_sec,
timesign, timeoffset / 60, timeoffset % 60);
@@ -851,12 +821,8 @@ static int pdf_image_finish_file(gx_device_pdf_image *pdf_dev, int PCLm)
pdf_dev->Pages = NULL;
pdf_dev->NumPages = 0;
}
- if (pdf_dev->icclink != NULL)
- {
- pdf_dev->icclink->procs.free_link(pdf_dev->icclink);
- gsicc_free_link_dev(pdf_dev->memory, pdf_dev->icclink);
- pdf_dev->icclink = NULL;
- }
+ gsicc_free_link_dev(pdf_dev->icclink);
+ pdf_dev->icclink = NULL;
pdf_dev->RootOffset = 0;
pdf_dev->PagesOffset = 0;
pdf_dev->xrefOffset = 0;
@@ -1095,10 +1061,7 @@ pdf_image_put_some_params(gx_device * dev, gs_param_list * plist, int which)
(which & 2 ? GX_DOWNSCALER_PARAMS_TRAP : 0) |
(which & 4 ? GX_DOWNSCALER_PARAMS_ETS : 0)));
if (code < 0)
- {
ecode = code;
- param_signal_error(plist, param_name, ecode);
- }
}
if (ecode < 0)
return ecode;
@@ -1127,7 +1090,7 @@ pdf_image_put_params_downscale_cmyk_ets(gx_device * dev, gs_param_list * plist)
return pdf_image_put_some_params(dev, plist, 7);
}
-void
+static void
PCLm_get_initial_matrix(gx_device * dev, register gs_matrix * pmat)
{
gx_device_pdf_image *pdev = (gx_device_pdf_image *)dev;
@@ -1176,6 +1139,21 @@ PCLm_initialize_device_procs(gx_device *dev)
set_dev_proc(dev, put_params, pdf_image_put_params_downscale);
}
+static void
+PCLm8_initialize_device_procs(gx_device *dev)
+{
+ gdev_prn_initialize_device_procs_rgb(dev);
+
+ set_dev_proc(dev, open_device, PCLm_open);
+ set_dev_proc(dev, output_page, gdev_prn_output_page);
+ set_dev_proc(dev, get_initial_matrix, PCLm_get_initial_matrix);
+ set_dev_proc(dev, close_device, PCLm_close);
+ set_dev_proc(dev, get_params, pdf_image_get_params_downscale);
+ set_dev_proc(dev, put_params, pdf_image_put_params_downscale);
+ set_dev_proc(dev, encode_color, gx_default_8bit_map_gray_color);
+ set_dev_proc(dev, decode_color, gx_default_8bit_map_color_gray);
+}
+
static dev_proc_print_page(PCLm_print_page);
const gx_device_pdf_image gs_PCLm_device = {
@@ -1196,6 +1174,24 @@ const gx_device_pdf_image gs_PCLm_device = {
0 /* JPEGQ */
};
+const gx_device_pdf_image gs_PCLm8_device = {
+ prn_device_body_duplex(gx_device_pdf_image,
+ PCLm8_initialize_device_procs,
+ "pclm8",
+ DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
+ 600, 600, /* 600 dpi by default */
+ 0, 0, 0, 0, /* Margins */
+ 1, /* num components */
+ 8, /* bits per sample */
+ 255, 0, 256, 0,
+ PCLm_print_page),
+ 3,
+ GX_DOWNSCALER_PARAMS_DEFAULTS,
+ 16, /* StripHeight */
+ 0.0, /* QFactor */
+ 0 /* JPEGQ */
+};
+
/* Open a temporary file, with or without a stream. */
static int
PCLm_open_temp_file(gx_device_pdf_image *pdev, PCLm_temp_file_t *ptf)
@@ -1328,8 +1324,6 @@ static int gdev_PCLm_begin_page(gx_device_pdf_image *pdf_dev,
gp_file *file)
{
gx_device_printer *const pdev = (gx_device_printer *)pdf_dev;
- cmm_dev_profile_t *profile_struct;
- gsicc_rendering_param_t rendering_params;
int code;
pdfimage_page *page;
@@ -1341,39 +1335,11 @@ static int gdev_PCLm_begin_page(gx_device_pdf_image *pdf_dev,
if (gdev_prn_file_is_new(pdev)) {
/* Set up the icc link settings at this time */
- code = dev_proc(pdev, get_profile)((gx_device *)pdev, &profile_struct);
- if (code < 0)
- return_error(gs_error_undefined);
- if (profile_struct->postren_profile != NULL) {
- rendering_params.black_point_comp = gsBLACKPTCOMP_ON;
- rendering_params.graphics_type_tag = GS_UNKNOWN_TAG;
- rendering_params.override_icc = false;
- rendering_params.preserve_black = gsBLACKPRESERVE_OFF;
- rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC;
- rendering_params.cmm = gsCMM_DEFAULT;
- if (profile_struct->oi_profile != NULL) {
- pdf_dev->icclink = gsicc_alloc_link_dev(pdev->memory,
- profile_struct->oi_profile, profile_struct->postren_profile,
- &rendering_params);
- } else if (profile_struct->link_profile != NULL) {
- pdf_dev->icclink = gsicc_alloc_link_dev(pdev->memory,
- profile_struct->link_profile, profile_struct->postren_profile,
- &rendering_params);
- } else {
- pdf_dev->icclink = gsicc_alloc_link_dev(pdev->memory,
- profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], profile_struct->postren_profile,
- &rendering_params);
- }
- if (pdf_dev->icclink == NULL) {
- gs_free_object(pdf_dev->memory->non_gc_memory, page, "pdfimage create new page");
- return_error(gs_error_VMerror);
- }
- /* If it is identity, release it now and set link to NULL */
- if (pdf_dev->icclink->is_identity) {
- pdf_dev->icclink->procs.free_link(pdf_dev->icclink);
- gsicc_free_link_dev(pdev->memory, pdf_dev->icclink);
- pdf_dev->icclink = NULL;
- }
+ code = gx_downscaler_create_post_render_link((gx_device *)pdev,
+ &pdf_dev->icclink);
+ if (code < 0) {
+ gs_free_object(pdf_dev->memory->non_gc_memory, page, "pdfimage create new page");
+ return code;
}
/* Set up the stream and insert the file header */
@@ -1475,7 +1441,7 @@ PCLm_downscale_and_print_page(gx_device_printer *dev,
pprintd1(pdf_dev->strm, "%d 0 obj\n", page->PageDictObjectNumber);
pprintd1(pdf_dev->strm, "<<\n/Contents %d 0 R\n", page->PageStreamObjectNumber);
stream_puts(pdf_dev->strm, "/Type /Page\n/Parent 2 0 R\n");
- gs_sprintf(Buffer, "/MediaBox [0 0 %.3f %.3f]\n", ((double)pdf_dev->width / pdf_dev->HWResolution[0]) * 72, ((double)pdf_dev->height / pdf_dev->HWResolution[1]) * 72);
+ gs_snprintf(Buffer, sizeof(Buffer), "/MediaBox [0 0 %.3f %.3f]\n", ((double)pdf_dev->width / pdf_dev->HWResolution[0]) * 72, ((double)pdf_dev->height / pdf_dev->HWResolution[1]) * 72);
stream_puts(pdf_dev->strm, Buffer);
stream_puts(pdf_dev->strm, "/Resources <<\n/XObject <<\n");
@@ -1494,9 +1460,9 @@ PCLm_downscale_and_print_page(gx_device_printer *dev,
double adjusted;
adjusted = height - (row * pdf_dev->StripHeight);
adjusted = adjusted / (pdf_dev->HWResolution[1] / (factor * 72));
- gs_sprintf(Buffer, "%.3f 0 0 %.3f 0 0 cm\n/Im%d Do Q\n", (width / (pdf_dev->HWResolution[0] / 72)) * factor, adjusted, row);
+ gs_snprintf(Buffer, sizeof(Buffer), "%.3f 0 0 %.3f 0 0 cm\n/Im%d Do Q\n", (width / (pdf_dev->HWResolution[0] / 72)) * factor, adjusted, row);
} else
- gs_sprintf(Buffer, "%.3f 0 0 %.3f 0 %f cm\n/Im%d Do Q\n", (width / (pdf_dev->HWResolution[0] / 72)) * factor, StripDecrement, ((height / (pdf_dev->HWResolution[1] / 72)) * factor) - (StripDecrement * (row + 1)), row);
+ gs_snprintf(Buffer, sizeof(Buffer), "%.3f 0 0 %.3f 0 %f cm\n/Im%d Do Q\n", (width / (pdf_dev->HWResolution[0] / 72)) * factor, StripDecrement, ((height / (pdf_dev->HWResolution[1] / 72)) * factor) - (StripDecrement * (row + 1)), row);
stream_puts(pdf_dev->temp_stream.strm, Buffer);
pprintd2(pdf_dev->strm, "/Im%d %d 0 R\n", row, page->ImageObjectNumber + (row * 2));
}
@@ -1574,7 +1540,10 @@ PCLm_downscale_and_print_page(gx_device_printer *dev,
stream_puts(pdf_dev->strm, "/Subtype /Image\n");
pprintd1(pdf_dev->strm, "/Width %d\n", width);
pprintd1(pdf_dev->strm, "/Height %d\n", Read);
- stream_puts(pdf_dev->strm, "/ColorSpace /DeviceRGB\n");
+ if (dev->color_info.max_components == 1)
+ stream_puts(pdf_dev->strm, "/ColorSpace /DeviceGray\n");
+ else
+ stream_puts(pdf_dev->strm, "/ColorSpace /DeviceRGB\n");
stream_puts(pdf_dev->strm, "/BitsPerComponent 8\n");
switch (pdf_dev->Compression) {
case COMPRESSION_FLATE:
@@ -1674,7 +1643,10 @@ PCLm_downscale_and_print_page(gx_device_printer *dev,
stream_puts(pdf_dev->strm, "/Subtype /Image\n");
pprintd1(pdf_dev->strm, "/Width %d\n", width);
pprintd1(pdf_dev->strm, "/Height %d\n", Read);
- stream_puts(pdf_dev->strm, "/ColorSpace /DeviceRGB\n");
+ if (dev->color_info.max_components == 1)
+ stream_puts(pdf_dev->strm, "/ColorSpace /DeviceGray\n");
+ else
+ stream_puts(pdf_dev->strm, "/ColorSpace /DeviceRGB\n");
stream_puts(pdf_dev->strm, "/BitsPerComponent 8\n");
switch (pdf_dev->Compression) {
case COMPRESSION_FLATE:
diff --git a/devices/gdevpdfocr.c b/devices/gdevpdfocr.c
index 8dd5a599..ff60c120 100644
--- a/devices/gdevpdfocr.c
+++ b/devices/gdevpdfocr.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
@@ -544,20 +544,20 @@ flush_word(gx_device_pdf_image *dev)
size = bbox[3]-bbox[1];
if (dev->ocr.cur_size != size) {
- gs_sprintf(buffer, "/Ft0 %.3f Tf", size);
+ gs_snprintf(buffer, sizeof(buffer), "/Ft0 %.3f Tf", size);
stream_puts(dev->strm, buffer);
dev->ocr.cur_size = size;
}
scale = (bbox[2]-bbox[0]) / size / len * 200;
if (dev->ocr.cur_scale != scale) {
- gs_sprintf(buffer, " %.3f Tz", scale);
+ gs_snprintf(buffer, sizeof(buffer), " %.3f Tz", scale);
stream_puts(dev->strm, buffer);
dev->ocr.cur_scale = scale;
}
- gs_sprintf(buffer, " 1 0 0 1 %.3f %.3f Tm[<", bbox[0], bbox[1]);
+ gs_snprintf(buffer, sizeof(buffer), " 1 0 0 1 %.3f %.3f Tm[<", bbox[0], bbox[1]);
stream_puts(dev->strm, buffer);
for (i = 0; i < len; i++) {
- gs_sprintf(buffer, "%04x", dev->ocr.word_chars[i]);
+ gs_snprintf(buffer, sizeof(buffer), "%04x", dev->ocr.word_chars[i]);
stream_puts(dev->strm, buffer);
}
stream_puts(dev->strm, ">]TJ\n");
@@ -607,19 +607,19 @@ ocr_callback(void *arg, const char *rune_,
size = bbox[3]-bbox[1];
if (ppdev->ocr.cur_size != size) {
- gs_sprintf(buffer, "/Ft0 %f Tf ", size);
+ gs_snprintf(buffer, sizeof(buffer), "/Ft0 %f Tf ", size);
stream_puts(ppdev->strm, buffer);
ppdev->ocr.cur_size = size;
}
scale = (bbox[2]-bbox[0]) / size * 200;
if (ppdev->ocr.cur_scale != scale) {
- gs_sprintf(buffer, " %f Tz ", scale);
+ gs_snprintf(buffer, sizeof(buffer), " %f Tz ", scale);
stream_puts(ppdev->strm, buffer);
ppdev->ocr.cur_scale = scale;
}
- gs_sprintf(buffer, "1 0 0 1 %f %f Tm ", bbox[0], bbox[1]);
+ gs_snprintf(buffer, sizeof(buffer), "1 0 0 1 %f %f Tm ", bbox[0], bbox[1]);
stream_puts(ppdev->strm, buffer);
- gs_sprintf(buffer, "<%04x>Tj\n", unicode);
+ gs_snprintf(buffer, sizeof(buffer), "<%04x>Tj\n", unicode);
stream_puts(ppdev->strm, buffer);
#else
bbox[0] = word_bbox[0] * scale / ppdev->ocr.xres;
diff --git a/devices/gdevplan.c b/devices/gdevplan.c
index 0ce82cda..abef8295 100644
--- a/devices/gdevplan.c
+++ b/devices/gdevplan.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
@@ -24,6 +24,9 @@
#include "gdevplnx.h"
#include "gdevppla.h"
#include "gdevmem.h"
+#include "gxdownscale.h"
+#include "gsicc_cache.h"
+#include "gxdevsop.h"
/* This file defines 5 different devices:
*
@@ -48,6 +51,13 @@
/* ------ The device descriptors ------ */
+typedef struct {
+ gx_device_common;
+ gx_prn_device_common;
+ gx_downscaler_params downscale;
+ gsicc_link_t *icclink;
+} gx_device_plan;
+
/*
* Default X and Y resolution.
*/
@@ -61,6 +71,7 @@ static dev_proc_decode_color(plang_decode_color);
static dev_proc_encode_color(planc_encode_color);
static dev_proc_decode_color(planc_decode_color);
static dev_proc_map_color_rgb(planc_map_color_rgb);
+static dev_proc_dev_spec_op(plan_spec_op);
static dev_proc_open_device(plan_open);
static dev_proc_close_device(plan_close);
@@ -77,6 +88,31 @@ static int planr_print_page(gx_device_printer * pdev, gp_file * pstream);
/* The device procedures */
+static int
+plan_get_params(gx_device * dev, gs_param_list * plist)
+{
+ gx_device_plan *pdev = (gx_device_plan *)dev;
+ int code = gdev_prn_get_params(dev, plist);
+
+ if (code < 0)
+ return code;
+
+ return gx_downscaler_write_params(plist, &pdev->downscale, 0);
+}
+
+static int
+plan_put_params(gx_device *dev, gs_param_list * plist)
+{
+ gx_device_plan *pdev = (gx_device_plan *)dev;
+ int code;
+
+ code = gx_downscaler_read_params(plist, &pdev->downscale, 0);
+ if (code < 0)
+ return code;
+
+ return gdev_prn_put_params(dev, plist);
+}
+
static void
plan_base_initialize_device_procs(gx_device *dev,
dev_proc_map_color_rgb(map_color_rgb),
@@ -91,6 +127,8 @@ plan_base_initialize_device_procs(gx_device *dev,
set_dev_proc(dev, get_page_device, gx_page_device_get_page_device);
set_dev_proc(dev, encode_color, encode_color);
set_dev_proc(dev, decode_color, decode_color);
+ set_dev_proc(dev, get_params, plan_get_params);
+ set_dev_proc(dev, put_params, plan_put_params);
}
static void
@@ -109,6 +147,7 @@ plang_initialize_device_procs(gx_device *dev)
plang_decode_color,
plang_encode_color,
plang_decode_color);
+ set_dev_proc(dev, dev_spec_op, plan_spec_op);
}
static void
@@ -118,6 +157,7 @@ plan_initialize_device_procs(gx_device *dev)
plan_decode_color,
gx_default_rgb_map_rgb_color,
plan_decode_color);
+ set_dev_proc(dev, dev_spec_op, plan_spec_op);
}
static void
@@ -127,6 +167,7 @@ planc_initialize_device_procs(gx_device *dev)
planc_map_color_rgb,
planc_encode_color,
planc_decode_color);
+ set_dev_proc(dev, dev_spec_op, plan_spec_op);
}
static void
@@ -149,30 +190,31 @@ planr_initialize_device_procs(gx_device *dev)
/* Macro for generating device descriptors. */
#define plan_prn_device(init, dev_name, num_comp, depth, max_gray, max_rgb, print_page) \
-{ prn_device_body(gx_device_printer, init, dev_name,\
+{ prn_device_body(gx_device_plan, init, dev_name,\
DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, X_DPI, Y_DPI,\
0, 0, 0, 0,\
num_comp, depth, max_gray, max_rgb, max_gray + 1, max_rgb + 1,\
- print_page)\
+ print_page),\
+ GX_DOWNSCALER_PARAMS_DEFAULTS\
}
/* The device descriptors themselves */
-const gx_device_printer gs_plan_device =
+const gx_device_plan gs_plan_device =
plan_prn_device(plan_initialize_device_procs, "plan",
3, 24, 255, 255, plan_print_page);
-const gx_device_printer gs_plang_device =
+const gx_device_plan gs_plang_device =
plan_prn_device(plang_initialize_device_procs, "plang",
1, 8, 255, 0, plang_print_page);
-const gx_device_printer gs_planm_device =
+const gx_device_plan gs_planm_device =
plan_prn_device(planm_initialize_device_procs, "planm",
1, 1, 1, 0, planm_print_page);
-const gx_device_printer gs_plank_device =
+const gx_device_plan gs_plank_device =
plan_prn_device(plank_initialize_device_procs, "plank",
4, 4, 1, 1, plank_print_page);
-const gx_device_printer gs_planc_device =
+const gx_device_plan gs_planc_device =
plan_prn_device(planc_initialize_device_procs, "planc",
4, 32, 255, 255, planc_print_page);
-const gx_device_printer gs_planr_device =
+const gx_device_plan gs_planr_device =
plan_prn_device(planr_initialize_device_procs, "planr",
3, 3, 1, 1, planr_print_page);
@@ -363,10 +405,14 @@ plan_open(gx_device * pdev)
static int
plan_close(gx_device *pdev)
{
+ gx_device_plan *dev = (gx_device_plan *)pdev;
+
#ifdef DEBUG_PRINT
emprintf(pdev->memory, "plan_close\n");
#endif
+ gsicc_free_link_dev(dev->icclink);
+ dev->icclink = NULL;
return gdev_prn_close(pdev);
}
@@ -486,26 +532,75 @@ planc_encode_color(gx_device * dev, const gx_color_value cv[])
return (color == gx_no_color_index ? color ^ 1 : color);
}
+static int
+plan_spec_op(gx_device *dev, int op, void *data, int datasize)
+{
+ if (op == gxdso_supports_iccpostrender) {
+ int bpc = dev->color_info.depth / dev->color_info.num_components;
+ return bpc == 8;
+ }
+ if (op == gxdso_skip_icc_component_validation) {
+ int bpc = dev->color_info.depth / dev->color_info.num_components;
+ return bpc == 8;
+ }
+ return gdev_prn_dev_spec_op(dev, op, data, datasize);
+}
+
/* ------ Internal routines ------ */
+static int post_cm(void *arg,
+ byte **dst,
+ byte **src,
+ int w,
+ int h,
+ int raster)
+{
+ gsicc_bufferdesc_t input_buffer_desc, output_buffer_desc;
+ gsicc_link_t *icclink = (gsicc_link_t*)arg;
+
+ gsicc_init_buffer(&input_buffer_desc, icclink->num_input, 1, false,
+ false, true, src[1] - src[0], raster, h, w);
+ gsicc_init_buffer(&output_buffer_desc, icclink->num_output, 1, false,
+ false, true, dst[1] - dst[0], raster, h, w);
+ icclink->procs.map_buffer(NULL, icclink, &input_buffer_desc, &output_buffer_desc,
+ src[0], dst[0]);
+ return 0;
+}
+
/* Print a page using a given row printing routine. */
static int
-plan_print_page_loop(gx_device_printer * pdev, int log2bits, int numComps,
+plan_print_page_loop(gx_device_printer *pdev, int log2bits, int numComps,
gp_file *pstream)
{
- int lnum;
+ gx_device_plan *dev = (gx_device_plan *)pdev;
+ int i, lnum;
int code = 0;
gs_get_bits_options_t options;
+ gx_downscaler_t ds;
+ gs_get_bits_params_t params;
+ int post_cm_comps;
+ byte *planes[GS_CLIENT_COLOR_MAX_COMPONENTS];
+ int factor = dev->downscale.downscale_factor;
+ int width = gx_downscaler_scale(pdev->width, factor);
+ int height = gx_downscaler_scale(pdev->height, factor);
+ int raster_plane = bitmap_raster(width << log2bits);
+
#ifdef DEBUG_DUMP
dump_row row_proc = NULL;
int output_is_nul = !strncmp(pdev->fname, "nul:", min(strlen(pdev->fname), 4)) ||
!strncmp(pdev->fname, "/dev/null", min(strlen(pdev->fname), 9));
-
- if (!output_is_nul)
- row_proc = dump_start(pdev->width, pdev->height, numComps, log2bits, pstream);
#endif
+
+ if (gdev_prn_file_is_new(pdev)) {
+ code = gx_downscaler_create_post_render_link((gx_device *)pdev,
+ &dev->icclink);
+ if (code < 0)
+ return code;
+ }
+
options = GB_ALIGN_ANY |
GB_RETURN_POINTER |
+ GB_RETURN_COPY |
GB_OFFSET_0 |
GB_RASTER_STANDARD |
GB_COLORS_NATIVE |
@@ -514,25 +609,54 @@ plan_print_page_loop(gx_device_printer * pdev, int log2bits, int numComps,
options |= GB_PACKING_CHUNKY;
else
options |= GB_PACKING_PLANAR;
- for (lnum = 0; lnum < pdev->height; lnum++) {
- gs_int_rect rect;
- gs_get_bits_params_t params;
-
- rect.p.x = 0;
- rect.p.y = lnum;
- rect.q.x = pdev->width;
- rect.q.y = lnum+1;
- memset(&params, 0, sizeof(params));
- params.options = options;
- params.x_offset = 0;
- code = (*dev_proc(pdev, get_bits_rectangle))((gx_device *)pdev, &rect, &params);
+
+ memset(&params, 0, sizeof(params));
+ params.options = options;
+ params.x_offset = 0;
+ post_cm_comps = dev->icclink ? dev->icclink->num_output : numComps;
+
+ planes[0] = gs_alloc_bytes(pdev->memory, raster_plane * post_cm_comps,
+ "plan_print_page_loop");
+ if (planes[0] == NULL)
+ return_error(gs_error_VMerror);
+ for (i = 1; i < post_cm_comps; i++) {
+ planes[i] = planes[i-1] + raster_plane;
+ params.data[i] = planes[i];
+ }
+
+ code = gx_downscaler_init_planar_cm(&ds,
+ (gx_device *)dev,
+ 1<<log2bits, /* src_bpc */
+ 1<<log2bits, /* dst_bpc */
+ numComps,
+ &dev->downscale,
+ &params,
+ dev->icclink ? post_cm : NULL,
+ dev->icclink,
+ post_cm_comps);
+ if (code < 0)
+ goto fail;
+
+#ifdef DEBUG_DUMP
+ if (!output_is_nul)
+ row_proc = dump_start(width, height, post_cm_comps, log2bits, pstream);
+#endif
+
+ for (lnum = 0; lnum < height; lnum++) {
+ for (i = 0; i < post_cm_comps; i++)
+ params.data[i] = planes[i];
+ code = gx_downscaler_get_bits_rectangle(&ds, &params, lnum);
if (code < 0)
break;
#ifdef DEBUG_DUMP
if (row_proc)
- (*row_proc)(pdev->width, params.data, pstream);
+ (*row_proc)(width, params.data, pstream);
#endif
}
+
+ gx_downscaler_fin(&ds);
+fail:
+ gs_free_object(pdev->memory, planes[0], "plan_print_page_loop");
return (code < 0 ? code : 0);
}
diff --git a/devices/gdevpng.c b/devices/gdevpng.c
index 5d353a12..554c664c 100644
--- a/devices/gdevpng.c
+++ b/devices/gdevpng.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
@@ -317,6 +317,41 @@ const gx_device_pngalpha gs_pngalpha_device = {
0xffffff /* white background */
};
+const gx_device_pngalpha gs_png16malpha_device = {
+ std_device_part1_(gx_device_pngalpha,
+ pngalpha_initialize_device_procs, "png16malpha",
+ &st_device_printer, open_init_closed),
+ /* color_info */
+ {3 /* max components */,
+ 3 /* number components */,
+ GX_CINFO_POLARITY_ADDITIVE /* polarity */,
+ 32 /* depth */,
+ -1 /* gray index */,
+ 255 /* max gray */,
+ 255 /* max color */,
+ 256 /* dither grays */,
+ 256 /* dither colors */,
+ { 1, 1 } /* antialias info text, graphics */,
+ GX_CINFO_UNKNOWN_SEP_LIN /* separable_and_linear */,
+ { 0 } /* component shift */,
+ { 0 } /* component bits */,
+ { 0 } /* component mask */,
+ "DeviceRGB" /* process color name */,
+ GX_CINFO_OPMSUPPORTED_UNKNOWN /* opmsupported */,
+ 0 /* process_cmps */,
+ 0 /* icc_locations */
+ },
+ std_device_part2_(
+ (int)((float)(DEFAULT_WIDTH_10THS) * (X_DPI) / 10 + 0.5),
+ (int)((float)(DEFAULT_HEIGHT_10THS) * (Y_DPI) / 10 + 0.5),
+ X_DPI, Y_DPI),
+ offset_margin_values(0, 0, 0, 0, 0, 0),
+ std_device_part3_(),
+ prn_device_body_rest_(png_print_page),
+ GX_DOWNSCALER_PARAMS_DEFAULTS,
+ 0xffffff /* white background */
+};
+
/* ------ Private definitions ------ */
static int
@@ -603,7 +638,7 @@ do_png_print_page(gx_device_png * pdev, gp_file * file, bool monod)
int minor = (int)(gs_revision - (major * 1000)) / 10;
int patch = gs_revision % 10;
- gs_sprintf(software_text, "%s %d.%02d.%d", gs_product, major, minor, patch);
+ gs_snprintf(software_text, sizeof(software_text), "%s %d.%02d.%d", gs_product, major, minor, patch);
}
text_png.compression = -1; /* uncompressed */
text_png.key = software_key;
@@ -821,6 +856,7 @@ pngalpha_create_buf_device(gx_device **pbdev, gx_device *target, int y,
ptarget= (gx_device_printer *)target;
set_dev_proc(*pbdev, copy_alpha, ptarget->orig_procs.copy_alpha);
+ set_dev_proc(*pbdev, dev_spec_op, ptarget->orig_procs.dev_spec_op);
set_dev_proc(*pbdev, fillpage, pngalpha_fillpage);
return code;
}
diff --git a/devices/gdevpsd.c b/devices/gdevpsd.c
index 3c9f6b01..d538b784 100644
--- a/devices/gdevpsd.c
+++ b/devices/gdevpsd.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
@@ -57,6 +57,7 @@ static dev_proc_get_params(psd_get_params);
static dev_proc_put_params(psd_put_params);
static dev_proc_get_params(psd_get_params_cmyk);
static dev_proc_put_params(psd_put_params_cmyk);
+static dev_proc_put_params(psd_put_params_cmyktag);
static dev_proc_print_page(psd_print_page);
static dev_proc_map_color_rgb(psd_map_color_rgb);
static dev_proc_get_color_mapping_procs(get_psdrgb_color_mapping_procs);
@@ -69,9 +70,19 @@ typedef enum {
psd_DEVICE_GRAY,
psd_DEVICE_RGB,
psd_DEVICE_CMYK,
+ psd_DEVICE_CMYKT,
psd_DEVICE_N
} psd_color_model;
+fixed_colorant_name DevCMYKTComponents[] = {
+ "Cyan",
+ "Magenta",
+ "Yellow",
+ "Black",
+ "Tags",
+ 0 /* List terminator */
+};
+
/*
* A structure definition for a DeviceN type device
*/
@@ -205,7 +216,7 @@ const psd_device gs_psdrgb_device =
{ true }, /* equivalent CMYK colors for spot colors */
/* PSD device specific parameters */
psd_DEVICE_RGB, /* Color model */
- GS_SOFT_MAX_SPOTS, /* max_spots */
+ GS_SOFT_MAX_SPOTS, /* max_spots */
false, /* colorants not locked */
GX_DOWNSCALER_PARAMS_DEFAULTS
};
@@ -215,13 +226,13 @@ const psd_device gs_psdrgb16_device =
psd_device_body(psd_initialize_device_procs, "psdrgb16", 3, GX_CINFO_POLARITY_ADDITIVE, 48, 65535, 65535, GX_CINFO_SEP_LIN, "DeviceRGB"),
/* devn_params specific parameters */
{ 16, /* Bits per color - must match ncomp, depth, etc. above */
- DeviceRGBComponents, /* Names of color model colorants */
- 3, /* Number colorants for RGB */
- 0, /* MaxSeparations has not been specified */
- -1, /* PageSpotColors has not been specified */
- { 0 }, /* SeparationNames */
- 0, /* SeparationOrder names */
- { 0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
+ DeviceRGBComponents, /* Names of color model colorants */
+ 3, /* Number colorants for RGB */
+ 0, /* MaxSeparations has not been specified */
+ -1, /* PageSpotColors has not been specified */
+ { 0 }, /* SeparationNames */
+ 0, /* SeparationOrder names */
+ {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
},
{ true }, /* equivalent CMYK colors for spot colors */
/* PSD device specific parameters */
@@ -244,6 +255,19 @@ psdcmyk_initialize_device_procs(gx_device *dev)
set_dev_proc(dev, get_color_mapping_procs, get_psd_color_mapping_procs);
}
+/*
+ * PSD device with CMYK process color model, spot color support, and tags.
+ */
+static void
+psdcmyktag_initialize_device_procs(gx_device *dev)
+{
+ psd_initialize_device_procs(dev);
+
+ set_dev_proc(dev, get_params, psd_get_params_cmyk);
+ set_dev_proc(dev, put_params, psd_put_params_cmyktag);
+ set_dev_proc(dev, get_color_mapping_procs, get_psd_color_mapping_procs);
+}
+
const psd_device gs_psdcmyk_device =
{
psd_device_body(psdcmyk_initialize_device_procs, "psdcmyk",
@@ -269,22 +293,47 @@ const psd_device gs_psdcmyk_device =
GX_DOWNSCALER_PARAMS_DEFAULTS
};
+const psd_device gs_psdcmyktags_device =
+{
+ psd_device_body(psdcmyktag_initialize_device_procs, "psdcmyktags",
+ ARCH_SIZEOF_GX_COLOR_INDEX, /* Number of components - need a nominal 1 bit for each */
+ GX_CINFO_POLARITY_SUBTRACTIVE,
+ ARCH_SIZEOF_GX_COLOR_INDEX * 8, /* 8 bits per component (albeit in planes) */
+ 255, 255, GX_CINFO_SEP_LIN, "DeviceCMYK"),
+ /* devn_params specific parameters */
+ { 8, /* Bits per color - must match ncomp, depth, etc. above */
+ DevCMYKTComponents, /* Names of color model colorants */
+ 4, /* Number colorants for CMYK. Tags added to extra in DevCMYKTComponents */
+ 0, /* MaxSeparations has not been specified */
+ -1, /* PageSpotColors has not been specified */
+ {0}, /* SeparationNames */
+ 0, /* SeparationOrder names */
+ {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
+ },
+ { true }, /* equivalent CMYK colors for spot colors */
+ /* PSD device specific parameters */
+ psd_DEVICE_CMYKT, /* Color model */
+ GS_SOFT_MAX_SPOTS, /* max_spots */
+ false, /* colorants not locked */
+ GX_DOWNSCALER_PARAMS_DEFAULTS
+};
+
const psd_device gs_psdcmyk16_device =
{
psd_device_body(psdcmyk_initialize_device_procs, "psdcmyk16",
- ARCH_SIZEOF_GX_COLOR_INDEX, /* Number of components - need a nominal 1 bit for each */
- GX_CINFO_POLARITY_SUBTRACTIVE,
- ARCH_SIZEOF_GX_COLOR_INDEX * 16, /* 8 bits per component (albeit in planes) */
- 65535, 65535, GX_CINFO_SEP_LIN, "DeviceCMYK"),
+ ARCH_SIZEOF_GX_COLOR_INDEX, /* Number of components - need a nominal 1 bit for each */
+ GX_CINFO_POLARITY_SUBTRACTIVE,
+ ARCH_SIZEOF_GX_COLOR_INDEX * 16, /* 8 bits per component (albeit in planes) */
+ 65535, 65535, GX_CINFO_SEP_LIN, "DeviceCMYK"),
/* devn_params specific parameters */
{ 16, /* Bits per color - must match ncomp, depth, etc. above */
- DeviceCMYKComponents, /* Names of color model colorants */
- 4, /* Number colorants for CMYK */
- 0, /* MaxSeparations has not been specified */
- -1, /* PageSpotColors has not been specified */
- { 0 }, /* SeparationNames */
- 0, /* SeparationOrder names */
- { 0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
+ DeviceCMYKComponents, /* Names of color model colorants */
+ 4, /* Number colorants for CMYK */
+ 0, /* MaxSeparations has not been specified */
+ -1, /* PageSpotColors has not been specified */
+ { 0 }, /* SeparationNames */
+ 0, /* SeparationOrder names */
+ {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
},
{ true }, /* equivalent CMYK colors for spot colors */
/* PSD device specific parameters */
@@ -294,6 +343,31 @@ const psd_device gs_psdcmyk16_device =
GX_DOWNSCALER_PARAMS_DEFAULTS
};
+const psd_device gs_psdcmyktags16_device =
+{
+ psd_device_body(psdcmyktag_initialize_device_procs, "psdcmyktags16",
+ ARCH_SIZEOF_GX_COLOR_INDEX, /* Number of components - need a nominal 1 bit for each */
+ GX_CINFO_POLARITY_SUBTRACTIVE,
+ ARCH_SIZEOF_GX_COLOR_INDEX * 16, /* 8 bits per component (albeit in planes) */
+ 65535, 65535, GX_CINFO_SEP_LIN, "DeviceCMYK"),
+ /* devn_params specific parameters */
+ { 16, /* Bits per color - must match ncomp, depth, etc. above */
+ DevCMYKTComponents, /* Names of color model colorants */
+ 4, /* Number colorants for CMYK. Tags added to extra in DevCMYKTComponents */
+ 0, /* MaxSeparations has not been specified */
+ -1, /* PageSpotColors has not been specified */
+ { 0 }, /* SeparationNames */
+ 0, /* SeparationOrder names */
+ {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
+ },
+ { true }, /* equivalent CMYK colors for spot colors */
+ /* PSD device specific parameters */
+ psd_DEVICE_CMYKT, /* Color model */
+ GS_SOFT_MAX_SPOTS, /* max_spots */
+ false, /* colorants not locked */
+ GX_DOWNSCALER_PARAMS_DEFAULTS
+};
+
/* Open the psd devices */
int
psd_prn_open(gx_device * pdev)
@@ -302,6 +376,7 @@ psd_prn_open(gx_device * pdev)
int code;
int k;
cmm_dev_profile_t *profile_struct;
+ bool has_tags = (pdev_psd->color_model == psd_DEVICE_CMYKT);
#ifdef TEST_PAD_AND_ALIGN
pdev->pad = 5;
@@ -340,7 +415,7 @@ psd_prn_open(gx_device * pdev)
}
pdev->color_info.num_components =
(profile_struct->spotnames->count
- + pdev_psd->devn_params.page_spot_colors);
+ + pdev_psd->devn_params.page_spot_colors + has_tags);
if (pdev->color_info.num_components > pdev->color_info.max_components)
pdev->color_info.num_components = pdev->color_info.max_components;
} else {
@@ -351,7 +426,7 @@ psd_prn_open(gx_device * pdev)
if (!(pdev_psd->lock_colorants)) {
pdev->color_info.num_components =
(pdev_psd->devn_params.page_spot_colors
- + pdev_psd->devn_params.num_std_colorant_names);
+ + pdev_psd->devn_params.num_std_colorant_names + has_tags);
if (pdev->color_info.num_components > pdev->color_info.max_components)
pdev->color_info.num_components = pdev->color_info.max_components;
}
@@ -369,7 +444,7 @@ psd_prn_open(gx_device * pdev)
was set (Default is GS_SOFT_MAX_SPOTS which is 10),
it is made use of here. */
if (!(pdev_psd->lock_colorants)) {
- int num_comp = pdev_psd->max_spots + 4; /* Spots + CMYK */
+ int num_comp = pdev_psd->max_spots + 4 + has_tags; /* Spots + CMYK */
if (num_comp > GS_CLIENT_COLOR_MAX_COMPONENTS)
num_comp = GS_CLIENT_COLOR_MAX_COMPONENTS;
pdev->color_info.num_components = num_comp;
@@ -474,6 +549,49 @@ rgb_cs_to_psdcmyk_cm(const gx_device * dev, const gs_gstate *pgs,
}
static void
+cmyk_cs_to_psdcmyktags_cm(const gx_device *dev,
+ frac c, frac m, frac y, frac k, frac out[])
+{
+ const gs_devn_params *devn = gx_devn_prn_ret_devn_params_const(dev);
+ const int *map = devn->separation_order_map;
+ int j;
+
+ if (devn->num_separation_order_names > 0) {
+ /* This is to set only those that we are using */
+ int ncomps = dev->color_info.num_components;
+ for (j = 0; j < ncomps; j++)
+ out[j] = 0;
+ for (j = 0; j < devn->num_separation_order_names; j++) {
+ switch (map[j]) {
+ case 0:
+ out[0] = c;
+ break;
+ case 1:
+ out[1] = m;
+ break;
+ case 2:
+ out[2] = y;
+ break;
+ case 3:
+ out[3] = k;
+ break;
+ default:
+ break;
+ }
+ }
+ } else {
+ cmyk_cs_to_devn_cm(dev, map, c, m, y, k, out);
+ }
+ /* And set the tags. At this point, the color values
+ are frac representation for the range [0.0 1.0]. We
+ need to encode the graphics type, which is 0 to 255
+ accordingly, as it goes through the same mappings on
+ its way to devn and then eventually to 8 or 16 bit values */
+ if (map[4] != GX_DEVICE_COLOR_MAX_COMPONENTS)
+ out[4] = byte2frac(dev->graphics_type_tag & ~GS_DEVICE_ENCODES_TAGS);
+}
+
+static void
cmyk_cs_to_psdcmyk_cm(const gx_device * dev,
frac c, frac m, frac y, frac k, frac out[])
{
@@ -602,6 +720,10 @@ static const gx_cm_color_map_procs psdCMYK_procs = {
gray_cs_to_psdcmyk_cm, rgb_cs_to_psdcmyk_cm, cmyk_cs_to_psdcmyk_cm
};
+static const gx_cm_color_map_procs psdCMYKtags_procs = {
+ gray_cs_to_psdcmyk_cm, rgb_cs_to_psdcmyk_cm, cmyk_cs_to_psdcmyktags_cm
+};
+
static const gx_cm_color_map_procs psdN_procs = {
gray_cs_to_spotn_cm, rgb_cs_to_spotn_cm, cmyk_cs_to_spotn_cm
};
@@ -627,6 +749,8 @@ get_psd_color_mapping_procs(const gx_device * dev, const gx_device **map_dev)
return &psdRGB_procs;
else if (xdev->color_model == psd_DEVICE_CMYK)
return &psdCMYK_procs;
+ else if (xdev->color_model == psd_DEVICE_CMYKT)
+ return &psdCMYKtags_procs;
else if (xdev->color_model == psd_DEVICE_N)
return &psdN_procs;
else if (xdev->color_model == psd_DEVICE_GRAY)
@@ -744,6 +868,13 @@ psd_put_params_cmyk(gx_device * pdev, gs_param_list * plist)
return psd_put_params_generic(pdev, plist, 1);
}
+static int
+psd_put_params_cmyktag(gx_device *pdev, gs_param_list* plist)
+{
+ pdev->graphics_type_tag |= GS_DEVICE_ENCODES_TAGS;
+ return psd_put_params_generic(pdev, plist, 1);
+}
+
/*
* This routine will check to see if the color component name match those
* that are available amoung the current device's color components.
@@ -812,7 +943,18 @@ psd_setup(psd_write_ctx *xc, gx_devn_prn_device *dev, gp_file *file, int w, int
if (dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE
&& strcmp(dev->dname, "psdcmykog") != 0) {
if (dev->devn_params.num_separation_order_names == 0) {
- xc->n_extra_channels = dev->devn_params.separations.num_separations;
+ /* 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)
+ 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))
+ xc->n_extra_channels = dev->devn_params.separations.num_separations;
+ else
+ xc->n_extra_channels = dev->color_info.max_components - NUM_CMYK_COMPONENTS;
+ }
} else {
/* Have to figure out how many in the order list were not std
colorants */
@@ -856,24 +998,33 @@ psd_setup(psd_write_ctx *xc, gx_devn_prn_device *dev, gp_file *file, int w, int
/* No order specified, map them alpabetically */
/* This isn't at all speed critical -- only runs once per page and */
/* there are never very many spot colors, so just search in a loop */
- byte *prev = " ";
+
+ /* If the device has tags, then that goes at the end, after all the
+ spot colors */
+
+ const char *prev = " ";
int prev_size = 1;
+ psd_device *pdev_psd = (psd_device*)dev;
+ 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++) {
int j;
- byte* curr = "\377";
+ const char *curr = "\377";
int curr_size = 1;
+ bool compare;
- for (j=xc->base_num_channels; j < xc->num_channels; j++) {
- const devn_separation_name *separation_name;
+ for (j=xc->base_num_channels; j < (xc->num_channels - has_tags); j++) {
+ devn_separation_name *separation_name;
separation_name = &(dev->devn_params.separations.names[j - xc->base_num_channels]);
- if (strncmp(separation_name->data, curr, min(curr_size, separation_name->size)) < 0) {
- if (strncmp(separation_name->data, prev, min(prev_size, separation_name->size)) > 0) {
+ compare = strncmp((const char*) separation_name->data, curr, min(curr_size, separation_name->size));
+ if (compare < 0 || (compare == 0 && separation_name->size < curr_size)) {
+ compare = strncmp((const char*) separation_name->data, prev, min(prev_size, separation_name->size));
+ if (compare > 0 || (compare == 0 && separation_name->size > prev_size)) {
xc->chnl_to_position[i] = j;
xc->chnl_to_orig_sep[i] = j;
- curr = separation_name->data;
+ curr = (const char*) separation_name->data;
curr_size = separation_name->size;
}
}
@@ -934,8 +1085,36 @@ get_sep_name(gx_devn_prn_device *pdev, int n)
return p;
}
+static inline void
+psd_write_src_spot_names(psd_write_ctx *xc, gx_devn_prn_device *pdev, int chan_idx, bool has_tags)
+{
+ int sep_num;
+ const devn_separation_name *separation_name;
+
+ for (; chan_idx < xc->num_channels; chan_idx++) {
+ sep_num = xc->chnl_to_orig_sep[chan_idx] - NUM_CMYK_COMPONENTS - has_tags;
+ separation_name = &(pdev->devn_params.separations.names[sep_num]);
+ psd_write_8(xc, (byte)separation_name->size);
+ psd_write(xc, separation_name->data, separation_name->size);
+ }
+}
+
+static inline void
+psd_write_std_extra_names(psd_write_ctx *xc, gx_devn_prn_device *pdev, int chan_idx)
+{
+ for (; chan_idx < xc->num_channels; chan_idx++) {
+ int len;
+ fixed_colorant_name n = pdev->devn_params.std_colorant_names[chan_idx];
+ if (n == NULL)
+ break;
+ len = strlen(n);
+ psd_write_8(xc, (byte)len);
+ psd_write(xc, (const byte*)n, len);
+ }
+}
+
int
-psd_write_header(psd_write_ctx *xc, gx_devn_prn_device *pdev)
+psd_write_header(psd_write_ctx* xc, gx_devn_prn_device* pdev)
{
int code = 0;
int num_channels = xc->num_channels;
@@ -944,8 +1123,14 @@ psd_write_header(psd_write_ctx *xc, gx_devn_prn_device *pdev)
int chan_names_len = 0;
int sep_num;
const devn_separation_name *separation_name;
+ cmm_dev_profile_t *profile_struct;
+ cmm_profile_t *dev_profile;
+ int profile_resource_size;
+ psd_device *pdev_psd = (psd_device*)pdev;
+ bool has_tags = (pdev_psd->color_model == psd_DEVICE_CMYKT);
+ int extra_std_colors = 0;
- psd_write(xc, (const byte *)"8BPS", 4); /* Signature */
+ psd_write(xc, (const byte*)"8BPS", 4); /* Signature */
psd_write_16(xc, 1); /* Version - Always equal to 1*/
/* Reserved 6 Bytes - Must be zero */
psd_write_32(xc, 0);
@@ -955,51 +1140,71 @@ psd_write_header(psd_write_ctx *xc, gx_devn_prn_device *pdev)
psd_write_32(xc, xc->width); /* Columns */
psd_write_16(xc, bpc); /* Depth - 1, 8 and 16 */
/* Modes: Bitmap=0, Grayscale=1, RGB=3, CMYK=4 MultiChannel=7 Lab=9 */
- psd_write_16(xc, (bits16) xc->base_num_channels); /* We use 1, 3 or 4. */
+ psd_write_16(xc, (bits16)xc->base_num_channels); /* We use 1, 3 or 4. */
- /* Color Mode Data */
- psd_write_32(xc, 0); /* No color mode data */
+ /* Color Mode Data. Only used for indexed and duotone */
+ psd_write_32(xc, 0);
- /* Image Resources */
+ /* Resources */
- /* Channel Names */
+ /* ICC profile */
+ code = dev_proc(pdev, get_profile)((gx_device*)pdev, &profile_struct);
+ if (code < 0) {
+ dev_profile = NULL;
+ profile_resource_size = 0;
+ } else {
+ dev_profile = profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
+
+ /* Resource has to be padded to even size */
+ profile_resource_size = dev_profile->buffer_size + dev_profile->buffer_size % 2;
+ }
+
+ /* Channel Names size computation -- this will get the "Tags" name */
for (chan_idx = NUM_CMYK_COMPONENTS; chan_idx < xc->num_channels; chan_idx++) {
fixed_colorant_name n = pdev->devn_params.std_colorant_names[chan_idx];
if (n == NULL)
break;
chan_names_len += strlen(n) + 1;
}
+ extra_std_colors = chan_idx - NUM_CMYK_COMPONENTS;
+
for (; chan_idx < xc->num_channels; chan_idx++) {
- sep_num = xc->chnl_to_orig_sep[chan_idx] - NUM_CMYK_COMPONENTS;
+ sep_num = xc->chnl_to_orig_sep[chan_idx] - NUM_CMYK_COMPONENTS - has_tags;
separation_name = &(pdev->devn_params.separations.names[sep_num]);
chan_names_len += (separation_name->size + 1);
}
+
+ /* Length of resource section */
psd_write_32(xc, 12 + (chan_names_len + (chan_names_len % 2))
+ (12 + (14 * (xc->num_channels - xc->base_num_channels)))
- + 28);
+ + (profile_resource_size ? (12 + profile_resource_size) : 0) + 28);
+
+ /* Channel names resource */
psd_write(xc, (const byte *)"8BIM", 4);
psd_write_16(xc, 1006); /* 0x03EE */
psd_write_16(xc, 0); /* PString */
psd_write_32(xc, chan_names_len + (chan_names_len % 2));
- for (chan_idx = NUM_CMYK_COMPONENTS; chan_idx < xc->num_channels; chan_idx++) {
- int len;
- fixed_colorant_name n = pdev->devn_params.std_colorant_names[chan_idx];
- if (n == NULL)
- break;
- len = strlen(n);
- psd_write_8(xc, (byte)len);
- psd_write(xc, (const byte *)n, len);
- }
- for (; chan_idx < xc->num_channels; chan_idx++) {
- sep_num = xc->chnl_to_orig_sep[chan_idx] - NUM_CMYK_COMPONENTS;
- separation_name = &(pdev->devn_params.separations.names[sep_num]);
- psd_write_8(xc, (byte) separation_name->size);
- psd_write(xc, separation_name->data, separation_name->size);
+
+ /* If it has tags, do the spots first (if there are any),
+ then the tags. We will need to rework this if we were
+ to add tags to psdcmykog or similar such device that
+ has pre-defined spots with the tags plane */
+ if (has_tags) {
+ chan_idx = NUM_CMYK_COMPONENTS + extra_std_colors;
+ psd_write_src_spot_names(xc, pdev, chan_idx, has_tags);
+ chan_idx = NUM_CMYK_COMPONENTS;
+ psd_write_std_extra_names(xc, pdev, chan_idx);
+
+ } else {
+ chan_idx = NUM_CMYK_COMPONENTS;
+ psd_write_std_extra_names(xc, pdev, chan_idx);
+ chan_idx = NUM_CMYK_COMPONENTS + extra_std_colors;
+ psd_write_src_spot_names(xc, pdev, chan_idx, has_tags);
}
if (chan_names_len % 2)
psd_write_8(xc, 0); /* pad */
- /* DisplayInfo - Colors for each spot channels */
+ /* DisplayInfo - Colors for each spot channels resource*/
psd_write(xc, (const byte *)"8BIM", 4);
psd_write_16(xc, 1007); /* 0x03EF */
psd_write_16(xc, 0); /* PString */
@@ -1044,7 +1249,7 @@ psd_write_header(psd_write_ctx *xc, gx_devn_prn_device *pdev)
psd_write_8(xc, 0); /* Padding - Always Zero */
}
- /* Image resolution */
+ /* Image resolution resource */
psd_write(xc, (const byte *)"8BIM", 4);
psd_write_16(xc, 1005); /* 0x03ED */
psd_write_16(xc, 0); /* PString */
@@ -1057,6 +1262,17 @@ psd_write_header(psd_write_ctx *xc, gx_devn_prn_device *pdev)
psd_write_16(xc, 1); /* height: 1 --> resolution is pixels per inch */
psd_write_16(xc, 1); /* height: 1 --> resolution is pixels per inch */
+ /* ICC Profile resource */
+ if (profile_resource_size) {
+ psd_write(xc, (const byte*)"8BIM", 4);
+ psd_write_16(xc, 1039); /* 0x040F */
+ psd_write_16(xc, 0); /* PString */
+ psd_write_32(xc, profile_resource_size);
+ psd_write(xc, dev_profile->buffer, dev_profile->buffer_size);
+ if (dev_profile->buffer_size % 2)
+ psd_write_8(xc, 0);
+ }
+
/* Layer and Mask information */
psd_write_32(xc, 0); /* No layer or mask information */
diff --git a/devices/gdevtifs.c b/devices/gdevtifs.c
index b937d0e3..9c629afa 100644
--- a/devices/gdevtifs.c
+++ b/devices/gdevtifs.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
@@ -76,12 +76,9 @@ tiff_close(gx_device * pdev)
if (tfdev->tif)
TIFFClose(tfdev->tif);
- if (tfdev->icclink != NULL)
- {
- tfdev->icclink->procs.free_link(tfdev->icclink);
- gsicc_free_link_dev(pdev->memory, tfdev->icclink);
- tfdev->icclink = NULL;
- }
+ gsicc_free_link_dev(tfdev->icclink);
+ tfdev->icclink = NULL;
+
return gdev_prn_close(pdev);
}
@@ -298,8 +295,6 @@ int gdev_tiff_begin_page(gx_device_tiff *tfdev,
gp_file *file)
{
gx_device_printer *const pdev = (gx_device_printer *)tfdev;
- cmm_dev_profile_t *profile_struct;
- gsicc_rendering_param_t rendering_params;
int code;
if (gdev_prn_file_is_new(pdev)) {
@@ -308,39 +303,10 @@ int gdev_tiff_begin_page(gx_device_tiff *tfdev,
if (!tfdev->tif)
return_error(gs_error_invalidfileaccess);
/* Set up the icc link settings at this time */
- code = dev_proc(pdev, get_profile)((gx_device *)pdev, &profile_struct);
+ code = gx_downscaler_create_post_render_link((gx_device *)pdev,
+ &tfdev->icclink);
if (code < 0)
- return_error(gs_error_undefined);
- if (profile_struct->postren_profile != NULL) {
- rendering_params.black_point_comp = gsBLACKPTCOMP_ON;
- rendering_params.graphics_type_tag = GS_UNKNOWN_TAG;
- rendering_params.override_icc = false;
- rendering_params.preserve_black = gsBLACKPRESERVE_OFF;
- rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC;
- rendering_params.cmm = gsCMM_DEFAULT;
- if (profile_struct->oi_profile != NULL) {
- tfdev->icclink = gsicc_alloc_link_dev(pdev->memory,
- profile_struct->oi_profile, profile_struct->postren_profile,
- &rendering_params);
- } else if (profile_struct->link_profile != NULL) {
- tfdev->icclink = gsicc_alloc_link_dev(pdev->memory,
- profile_struct->link_profile, profile_struct->postren_profile,
- &rendering_params);
- } else {
- tfdev->icclink = gsicc_alloc_link_dev(pdev->memory,
- profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
- profile_struct->postren_profile, &rendering_params);
- }
- if (tfdev->icclink == NULL) {
- return_error(gs_error_VMerror);
- }
- /* If it is identity, release it now and set link to NULL */
- if (tfdev->icclink->is_identity) {
- tfdev->icclink->procs.free_link(tfdev->icclink);
- gsicc_free_link_dev(pdev->memory, tfdev->icclink);
- tfdev->icclink = NULL;
- }
- }
+ return code;
}
return tiff_set_fields_for_printer(pdev, tfdev->tif, tfdev->downscale.downscale_factor,
@@ -400,7 +366,7 @@ int tiff_set_fields_for_printer(gx_device_printer *pdev,
strncpy(softwareValue, gs_product, maxSoftware);
softwareValue[maxSoftware - 1] = 0;
- gs_sprintf(revs, " %d.%2d.%d", major, minor, patch);
+ gs_snprintf(revs, sizeof(revs), " %d.%2d.%d", major, minor, patch);
strncat(softwareValue, revs,
maxSoftware - strlen(softwareValue) - 1);
@@ -418,7 +384,7 @@ int tiff_set_fields_for_printer(gx_device_printer *pdev,
time(&t);
tms = *localtime(&t);
#endif
- gs_sprintf(dateTimeValue, "%04d:%02d:%02d %02d:%02d:%02d",
+ gs_snprintf(dateTimeValue, sizeof(dateTimeValue), "%04d:%02d:%02d %02d:%02d:%02d",
tms.tm_year + 1900, tms.tm_mon + 1, tms.tm_mday,
tms.tm_hour, tms.tm_min, tms.tm_sec);
@@ -438,8 +404,6 @@ int tiff_set_fields_for_printer(gx_device_printer *pdev,
if (pdev->icc_struct->postren_profile != NULL)
icc_profile = pdev->icc_struct->postren_profile;
- else if (pdev->icc_struct->oi_profile != NULL)
- icc_profile = pdev->icc_struct->oi_profile;
else
icc_profile = pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
diff --git a/devices/gdevtsep.c b/devices/gdevtsep.c
index 10d3b633..fd859ddc 100644
--- a/devices/gdevtsep.c
+++ b/devices/gdevtsep.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
@@ -395,8 +395,6 @@ tiff_set_rgb_fields(gx_device_tiff *tfdev)
if (tfdev->icc_struct->postren_profile != NULL)
icc_profile = tfdev->icc_struct->postren_profile;
- else if (tfdev->icc_struct->oi_profile != NULL)
- icc_profile = tfdev->icc_struct->oi_profile;
else
icc_profile = tfdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
@@ -956,11 +954,11 @@ tiffsep_decode_color(gx_device * dev, gx_color_index color, gx_color_value * out
* Device proc for updating the equivalent CMYK color for spot colors.
*/
static int
-tiffsep_update_spot_equivalent_colors(gx_device * dev, const gs_gstate * pgs)
+tiffsep_update_spot_equivalent_colors(gx_device * dev, const gs_gstate * pgs, const gs_color_space *pcs)
{
tiffsep_device * pdev = (tiffsep_device *)dev;
- update_spot_equivalent_cmyk_colors(dev, pgs,
+ update_spot_equivalent_cmyk_colors(dev, pgs, pcs,
&pdev->devn_params, &pdev->equiv_cmyk_colors);
return 0;
}
@@ -1267,9 +1265,9 @@ tiffsep1_prn_close(gx_device * pdev)
while (*fmt != 'l' && *fmt != '%')
--fmt;
if (*fmt == 'l')
- gs_sprintf(compname, parsed.fname, count1);
+ gs_snprintf(compname, gp_file_name_sizeof, parsed.fname, count1);
else
- gs_sprintf(compname, parsed.fname, (int)count1);
+ gs_snprintf(compname, gp_file_name_sizeof, parsed.fname, (int)count1);
parsed.iodev->procs.delete_file(parsed.iodev, compname);
} else {
parsed.iodev->procs.delete_file(parsed.iodev, tfdev->fname);
@@ -1368,7 +1366,9 @@ copy_separation_name(tiffsep_device * pdev,
{
int sep_size = pdev->devn_params.separations.names[sep_num].size;
const byte *p = pdev->devn_params.separations.names[sep_num].data;
- int r, w;
+ int r, w, use_sep_num = 0;
+ const char *stdnames[4] = {"CYAN", "MAGENTA", "YELLOW", "BLACK"};
+ char sep_num_str[16] = "";
/* Previously the code here would simply replace any char that wasn't
* passed by gp_file_name_good_char (and %) with '_'. The grounds for
@@ -1378,13 +1378,28 @@ copy_separation_name(tiffsep_device * pdev,
* the file handling routines as they assume the filenames are in
* utf-8 format. */
+ for (r=0;r<4;r++)
+ {
+ if (strlen(stdnames[r]) == pdev->devn_params.separations.names[sep_num].size) {
+ use_sep_num = 1;
+ for (w=0;w<strlen(stdnames[r]);w++) {
+ if (toupper(pdev->devn_params.separations.names[sep_num].data[w]) != stdnames[r][w]) {
+ use_sep_num = 0;
+ break;
+ }
+ }
+ }
+ }
+ if (use_sep_num != 0)
+ gs_snprintf(sep_num_str, sizeof(sep_num_str), "%d", sep_num);
+
/* New code: Copy the name, escaping non gp_file_name_good_char chars,
* % and top bit set chars using %02x format. In addition, if 'escape'
* is set, output % as %% to allow for printf later.
*/
r = 0;
w = 0;
- while (r < sep_size && w < max_size-1)
+ while (r < sep_size && w < max_size-1 - strlen(sep_num_str))
{
int c = p[r++];
if (c >= 127 ||
@@ -1393,7 +1408,7 @@ copy_separation_name(tiffsep_device * pdev,
{
/* Top bit set, backspace, or char we can't represent on the
* filesystem. */
- if (w + 2 + escape >= max_size-1)
+ if (w + 2 + escape >= max_size-1 - strlen(sep_num_str))
break;
buffer[w++] = '%';
if (escape)
@@ -1406,6 +1421,10 @@ copy_separation_name(tiffsep_device * pdev,
buffer[w++] = c;
}
}
+ if (use_sep_num) {
+ for (r = 0;r < strlen(sep_num_str);r++)
+ buffer[w++] = sep_num_str[r];
+ }
buffer[w] = 0; /* Terminate string */
}
@@ -1479,7 +1498,7 @@ create_separation_file_name(tiffsep_device * pdev, char * buffer,
/* Max of 10 chars in %d format */
if (max_size < base_filename_length + 11)
return_error(gs_error_rangecheck);
- gs_sprintf(buffer + base_filename_length, "s%d", sep_num);
+ gs_snprintf(buffer + base_filename_length, max_size - base_filename_length, "s%d", sep_num);
}
}
if (use_sep_name)
@@ -1575,12 +1594,13 @@ tiffsep_prn_open(gx_device * pdev)
tiffsep_device *pdev_sep = (tiffsep_device *) pdev;
int code, k;
cmm_dev_profile_t *profile_struct;
- gsicc_rendering_param_t rendering_params;
/* Use our own warning and error message handlers in libtiff */
tiff_set_handlers();
code = dev_proc(pdev, get_profile)((gx_device *)pdev, &profile_struct);
+ if (code < 0)
+ return code;
/* For the planar device we need to set up the bit depth of each plane.
For other devices this is handled in check_device_separable where
@@ -1653,6 +1673,8 @@ tiffsep_prn_open(gx_device * pdev)
pdev_sep->devn_params.bitspercomponent;
pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN;
code = gdev_prn_open_planar(pdev, true);
+ if (code < 0)
+ return code;
while (pdev->child)
pdev = pdev->child;
ppdev = (gx_device_printer *)pdev;
@@ -1662,42 +1684,8 @@ tiffsep_prn_open(gx_device * pdev)
/* Set up the icc link settings at this time. Only CMYK post render profiles
are allowed */
- code = dev_proc(pdev, get_profile)((gx_device *)pdev, &profile_struct);
- if (code < 0)
- return_error(gs_error_undefined);
-
- if (profile_struct->postren_profile != NULL &&
- profile_struct->postren_profile->data_cs == gsCMYK) {
- rendering_params.black_point_comp = gsBLACKPTCOMP_ON;
- rendering_params.graphics_type_tag = GS_UNKNOWN_TAG;
- rendering_params.override_icc = false;
- rendering_params.preserve_black = gsBLACKPRESERVE_OFF;
- rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC;
- rendering_params.cmm = gsCMM_DEFAULT;
- if (profile_struct->oi_profile != NULL) {
- pdev_sep->icclink = gsicc_alloc_link_dev(pdev->memory,
- profile_struct->oi_profile, profile_struct->postren_profile,
- &rendering_params);
- } else if (profile_struct->link_profile != NULL) {
- pdev_sep->icclink = gsicc_alloc_link_dev(pdev->memory,
- profile_struct->link_profile, profile_struct->postren_profile,
- &rendering_params);
- } else {
- pdev_sep->icclink = gsicc_alloc_link_dev(pdev->memory,
- profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
- profile_struct->postren_profile, &rendering_params);
- }
- if (pdev_sep->icclink == NULL) {
- return_error(gs_error_VMerror);
- }
- /* If it is identity, release it now and set link to NULL */
- if (pdev_sep->icclink->is_identity) {
- pdev_sep->icclink->procs.free_link(pdev_sep->icclink);
- gsicc_free_link_dev(pdev->memory, pdev_sep->icclink);
- pdev_sep->icclink = NULL;
- }
- }
- return code;
+ return gx_downscaler_create_post_render_link((gx_device *)pdev,
+ &pdev_sep->icclink);
}
static int
@@ -1752,11 +1740,9 @@ tiffsep_prn_close(gx_device * pdev)
int comp_num;
int num_comp = number_output_separations(num_dev_comp, num_std_colorants,
num_order, num_spot);
- if (pdevn->icclink != NULL) {
- pdevn->icclink->procs.free_link(pdevn->icclink);
- gsicc_free_link_dev(pdevn->memory, pdevn->icclink);
- pdevn->icclink = NULL;
- }
+
+ 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)
@@ -2066,7 +2052,6 @@ tiffsep_print_page(gx_device_printer * pdev, gp_file * file)
int num_comp, comp_num, code = 0, code1 = 0;
cmyk_composite_map cmyk_map[GX_DEVICE_COLOR_MAX_COMPONENTS];
char *name = NULL;
- bool double_f = false;
int save_depth = pdev->color_info.depth;
int save_numcomps = pdev->color_info.num_components;
const char *fmt;
@@ -2490,9 +2475,9 @@ tiffsep1_print_page(gx_device_printer * pdev, gp_file * file)
while (*fmt != 'l' && *fmt != '%')
--fmt;
if (*fmt == 'l')
- gs_sprintf(compname, parsed.fname, count1);
+ gs_snprintf(compname, gp_file_name_sizeof, parsed.fname, count1);
else
- gs_sprintf(compname, parsed.fname, (int)count1);
+ gs_snprintf(compname, gp_file_name_sizeof, parsed.fname, (int)count1);
parsed.iodev->procs.delete_file(parsed.iodev, compname);
}
#endif /* PPM_COMBINED_OUTPUT */
diff --git a/devices/gdevupd.c b/devices/gdevupd.c
index 66359847..179c400d 100644
--- a/devices/gdevupd.c
+++ b/devices/gdevupd.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
@@ -216,6 +216,7 @@ static int upd_procs_map( upd_device *udev);
static void
upd_initialize_device_procs(gx_device *dev)
{
+ set_dev_proc(dev, initialize_device, gx_init_non_threadsafe_device);
set_dev_proc(dev, open_device, upd_open);
set_dev_proc(dev, output_page, gdev_prn_output_page);
set_dev_proc(dev, close_device, upd_close);
@@ -6483,7 +6484,7 @@ upd_open_wrtrtl(upd_device *udev)
if( (B_PAGEWIDTH & upd->flags) &&
((c == 0x73) || (c == 0x53)) ) { /* esc * r # S */
- gs_sprintf(cv,"%d",upd->pwidth);
+ gs_snprintf(cv,sizeof(cv),"%d",upd->pwidth);
ncv = strlen(cv);
nbp = (j+1) + ncv + (upd->strings[S_BEGIN].size-i);
@@ -6501,7 +6502,7 @@ upd_open_wrtrtl(upd_device *udev)
} else if((B_PAGELENGTH & upd->flags) &&
((c == 0x74) || (c == 0x54)) ) { /* esc * r # T */
- gs_sprintf(cv,"%d",upd->pheight);
+ gs_snprintf(cv,sizeof(cv),"%d",upd->pheight);
ncv = strlen(cv);
nbp = (j+1) + ncv + (upd->strings[S_BEGIN].size-i);
@@ -6530,7 +6531,7 @@ upd_open_wrtrtl(upd_device *udev)
if( (B_RESOLUTION & upd->flags) &&
((c == 0x72) || (c == 0x52)) ) { /* esc * t # R */
- gs_sprintf(cv,"%d",(int)
+ gs_snprintf(cv,sizeof(cv),"%d",(int)
((udev->y_pixels_per_inch < udev->x_pixels_per_inch ?
udev->x_pixels_per_inch : udev->y_pixels_per_inch)
+0.5));
@@ -6737,7 +6738,7 @@ upd_open_wrtrtl(upd_device *udev)
if(B_PAGELENGTH & upd->flags) { /* insert new number */
- gs_sprintf(cv,"%d",(int)
+ gs_snprintf(cv,sizeof(cv),"%d",(int)
(720.0 * udev->height / udev->y_pixels_per_inch + 0.5));
ncv = strlen(cv);
@@ -6802,7 +6803,7 @@ upd_open_wrtrtl(upd_device *udev)
if(B_PAGEWIDTH & upd->flags) { /* insert new number */
- gs_sprintf(cv,"%d",(int)
+ gs_snprintf(cv,sizeof(cv),"%d",(int)
(720.0 * udev->width / udev->x_pixels_per_inch + 0.5));
ncv = strlen(cv);
@@ -6897,7 +6898,7 @@ upd_open_wrtrtl(upd_device *udev)
if(B_RESOLUTION & upd->flags) { /* insert new number */
- gs_sprintf(cv,"%d",(int)
+ gs_snprintf(cv,sizeof(cv),"%d",(int)
((udev->y_pixels_per_inch < udev->x_pixels_per_inch ?
udev->x_pixels_per_inch : udev->y_pixels_per_inch)
+0.5));
@@ -6952,7 +6953,7 @@ It must hold:
char tmp[16];
if(0 < upd->strings[S_YMOVE].size) {
- gs_sprintf(tmp,"%d",upd->pheight);
+ gs_snprintf(tmp,sizeof(tmp),"%d",upd->pheight);
ny = upd->strings[S_YMOVE].size + strlen(tmp);
} else {
ny = 1 + upd->string_a[SA_WRITECOMP].data[upd->ocomp-1].size;
@@ -7013,14 +7014,14 @@ upd_wrtrtl(upd_p upd, gp_file *out)
*/
if(upd->yscan != upd->yprinter) { /* Adjust Y-Position */
if(1 < upd->strings[S_YMOVE].size) {
- gs_sprintf((char *)upd->outbuf+ioutbuf,
+ gs_snprintf((char *)upd->outbuf+ioutbuf, upd->noutbuf-ioutbuf,
(const char *) upd->strings[S_YMOVE].data,
upd->yscan - upd->yprinter);
ioutbuf += strlen((char *)upd->outbuf+ioutbuf);
} else {
while(upd->yscan > upd->yprinter) {
for(icomp = 0; icomp < upd->ocomp; ++icomp) {
- gs_sprintf((char *)upd->outbuf+ioutbuf,
+ gs_snprintf((char *)upd->outbuf+ioutbuf, upd->noutbuf-ioutbuf,
(const char *) upd->string_a[SA_WRITECOMP].data[icomp].data,0);
ioutbuf += strlen((char *)upd->outbuf+ioutbuf);
}
diff --git a/devices/gdevwpr2.c b/devices/gdevwpr2.c
index eeb94896..a8e812f6 100644
--- a/devices/gdevwpr2.c
+++ b/devices/gdevwpr2.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
@@ -574,7 +574,7 @@ win_pr2_print_page(gx_device_printer * pdev, gp_file * file)
}
if (!wdev->nocancel) {
- gs_sprintf(dlgtext, "Printing page %d", (int)(pdev->PageCount) + 1);
+ gs_snprintf(dlgtext, sizeof(dlgtext), "Printing page %d", (int)(pdev->PageCount) + 1);
SetWindowText(GetDlgItem(wdev->hDlgModeless, CANCEL_PRINTING), dlgtext);
ShowWindow(wdev->hDlgModeless, SW_SHOW);
}
@@ -606,7 +606,7 @@ win_pr2_print_page(gx_device_printer * pdev, gp_file * file)
if (!wdev->nocancel) {
/* inform user of progress */
- gs_sprintf(dlgtext, "%d%% done", (int)(y * 100L / scan_lines));
+ gs_snprintf(dlgtext, sizeof(dlgtext), "%d%% done", (int)(y * 100L / scan_lines));
SetWindowText(GetDlgItem(wdev->hDlgModeless, CANCEL_PCDONE), dlgtext);
}
/* process message loop */
@@ -1080,11 +1080,11 @@ win_pr2_getdc(gx_device_win_pr2 * wdev)
DocumentProperties(NULL, hprinter, device, podevmode, NULL, DM_OUT_BUFFER);
/* now find out what paper sizes are available */
- devcapsize = DeviceCapabilities(device, output, DC_PAPERSIZE, NULL, NULL);
+ devcapsize = DeviceCapabilities(podevmode->dmDeviceName, output, DC_PAPERSIZE, NULL, NULL);
devcapsize *= sizeof(POINT);
if ((devcap = gs_malloc(wdev->memory, devcapsize, 1, "win_pr2_getdc")) == (LPBYTE) NULL)
return FALSE;
- n = DeviceCapabilities(device, output, DC_PAPERSIZE, devcap, NULL);
+ n = DeviceCapabilities(podevmode->dmDeviceName, output, DC_PAPERSIZE, devcap, NULL);
paperwidth = (int)(wdev->MediaSize[0] * 254 / 72);
paperheight = (int)(wdev->MediaSize[1] * 254 / 72);
papername[0] = '\0';
@@ -1119,21 +1119,21 @@ win_pr2_getdc(gx_device_win_pr2 * wdev)
gs_free(wdev->memory, devcap, devcapsize, 1, "win_pr2_getdc");
/* get the dmPaperSize */
- devcapsize = DeviceCapabilities(device, output, DC_PAPERS, NULL, NULL);
+ devcapsize = DeviceCapabilities(podevmode->dmDeviceName, output, DC_PAPERS, NULL, NULL);
devcapsize *= sizeof(WORD);
if ((devcap = gs_malloc(wdev->memory, devcapsize, 1, "win_pr2_getdc")) == (LPBYTE) NULL)
return FALSE;
- n = DeviceCapabilities(device, output, DC_PAPERS, devcap, NULL);
+ n = DeviceCapabilities(podevmode->dmDeviceName, output, DC_PAPERS, devcap, NULL);
if ((paperindex >= 0) && (paperindex < n))
papersize = ((WORD *) devcap)[paperindex];
gs_free(wdev->memory, devcap, devcapsize, 1, "win_pr2_getdc");
/* get the paper name */
- devcapsize = DeviceCapabilities(device, output, DC_PAPERNAMES, NULL, NULL);
+ devcapsize = DeviceCapabilities(podevmode->dmDeviceName, output, DC_PAPERNAMES, NULL, NULL);
devcapsize *= 64;
if ((devcap = gs_malloc(wdev->memory, devcapsize, 1, "win_pr2_getdc")) == (LPBYTE) NULL)
return FALSE;
- n = DeviceCapabilities(device, output, DC_PAPERNAMES, devcap, NULL);
+ n = DeviceCapabilities(podevmode->dmDeviceName, output, DC_PAPERNAMES, devcap, NULL);
if ((paperindex >= 0) && (paperindex < n))
strcpy(papername, devcap + paperindex * 64);
gs_free(wdev->memory, devcap, devcapsize, 1, "win_pr2_getdc");
@@ -1175,7 +1175,7 @@ win_pr2_getdc(gx_device_win_pr2 * wdev)
wdev->user_media_size[1] = paperheight / 254.0 * 72.0;
}
- if (DeviceCapabilities(device, output, DC_DUPLEX, NULL, NULL)) {
+ if (DeviceCapabilities(podevmode->dmDeviceName, output, DC_DUPLEX, NULL, NULL)) {
wdev->Duplex_set = 1;
}
@@ -1186,7 +1186,7 @@ win_pr2_getdc(gx_device_win_pr2 * wdev)
ClosePrinter(hprinter);
/* now get a DC */
- wdev->hdcprn = CreateDC(driver, device, NULL, podevmode);
+ wdev->hdcprn = CreateDC(driver, podevmode->dmDeviceName, NULL, podevmode);
if (wdev->win32_hdevmode == NULL)
wdev->win32_hdevmode = GlobalAlloc(0, devmode_size);
@@ -1505,9 +1505,9 @@ win_pr2_print_setup_interaction(gx_device_win_pr2 * wdev, int mode)
wdev->user_changed_settings = TRUE;
if (wdev->use_old_spool_name) {
- gs_sprintf(wdev->fname, "\\\\spool\\%s", (char*)(devnames)+(devnames->wDeviceOffset));
+ gs_snprintf(wdev->fname, prn_fname_sizeof, "\\\\spool\\%s", (char*)(devnames)+(devnames->wDeviceOffset));
} else {
- gs_sprintf(wdev->fname, "%%printer%%%s", (char*)(devnames)+(devnames->wDeviceOffset));
+ gs_snprintf(wdev->fname, prn_fname_sizeof, "%%printer%%%s", (char*)(devnames)+(devnames->wDeviceOffset));
}
if (mode == 3) {
diff --git a/devices/gdevxini.c b/devices/gdevxini.c
index 1944c9a9..fafcd42a 100644
--- a/devices/gdevxini.c
+++ b/devices/gdevxini.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
@@ -88,7 +88,7 @@ gdev_x_open(gx_device_X * xdev)
XSizeHints sizehints;
char *window_id;
XEvent event;
- XVisualInfo xvinfo;
+ XVisualInfo xvinfo = { 0 };
int nitems;
XtAppContext app_con;
Widget toplevel;
@@ -385,7 +385,7 @@ gdev_x_open(gx_device_X * xdev)
char gstr[40];
int bitmask;
- gs_sprintf(gstr, "%dx%d+%d+%d", sizehints.width,
+ gs_snprintf(gstr, sizeof(gstr), "%dx%d+%d+%d", sizehints.width,
sizehints.height, sizehints.x, sizehints.y);
bitmask = XWMGeometry(xdev->dpy, DefaultScreen(xdev->dpy),
xdev->geometry, gstr, xdev->borderWidth,
@@ -589,9 +589,9 @@ x_set_buffer(gx_device_X * xdev)
* *But* if we run buffered, we have to use the real specs of the real x11 device.
* Hence, the real color_info is saved into orig_color_info, and we use that here.
*/
- if (mdev == 0 || mdev->color_info.depth != xdev->orig_color_info.depth) {
+ if (mdev == 0 || mdev->color_info.depth != xdev->color_info.depth) {
const gx_device_memory *mdproto =
- gdev_mem_device_for_bits(xdev->orig_color_info.depth);
+ gdev_mem_device_for_bits(xdev->color_info.depth);
if (!mdproto) {
buffered = false;
@@ -643,7 +643,7 @@ x_set_buffer(gx_device_X * xdev)
rc_decrement(mdev->icc_struct, "x_set_buffer");
mdev->icc_struct = xdev->icc_struct;
rc_increment(xdev->icc_struct);
- mdev->color_info = xdev->orig_color_info;
+ mdev->color_info = xdev->color_info;
mdev->base = xdev->buffer;
gdev_mem_open_scan_lines(mdev, xdev->height);
}
@@ -762,6 +762,10 @@ static int
x_initialize_device(gx_device *dev)
{
gx_device_X *xdev = (gx_device_X *) dev;
+ int code = gx_init_non_threadsafe_device(dev);
+
+ if (code < 0)
+ return code;
/* Mark the new instance as closed. */
xdev->is_open = false;
@@ -984,7 +988,8 @@ gdev_x_close(gx_device_X *xdev)
xdev->gc = NULL;
}
if (xdev->dpy && xdev->bpixmap != (Pixmap)0) {
- XFreePixmap(xdev->dpy, xdev->bpixmap);
+ /* Only free the pixmap if we created it */
+ if (xdev->ghostview == 0) XFreePixmap(xdev->dpy, xdev->bpixmap);
xdev->bpixmap = (Pixmap)0;
xdev->dest = (Pixmap)0;
}
diff --git a/devices/gxfcopy.c b/devices/gxfcopy.c
index 72235693..76f0a19e 100644
--- a/devices/gxfcopy.c
+++ b/devices/gxfcopy.c
@@ -1735,6 +1735,10 @@ copy_font_cid0(gs_font *font, gs_font *copied)
subdata->glyphs = cfdata->glyphs;
subdata->glyphs_size = cfdata->glyphs_size;
subdata->names = 0;
+ if (subdata->global_subrs.data != NULL)
+ gs_free_object(copied->memory, subdata->global_subrs.data, "copy parent global subrs to child, free child global subrs");
+ if (subdata->global_subrs.starts != NULL)
+ gs_free_object(copied->memory, subdata->global_subrs.starts, "copy parent global subrs to child, free child global subrs");
subdata->global_subrs = cfdata->global_subrs;
FDArray[i] = subcopy1;
}
@@ -2236,7 +2240,7 @@ gs_copy_font(gs_font *font, const gs_matrix *orig_matrix, gs_memory_t *mem, gs_f
return code;
}
-/* We only need this because the ddescndant(s) share the parent
+/* We only need this because the descendant(s) share the parent
* CIDFont glyph space, so we can't free that if we are a descendant.
*/
static int gs_free_copied_descendant_font(gs_font *font)
@@ -2257,6 +2261,13 @@ static int gs_free_copied_descendant_font(gs_font *font)
gs_free_object(mem, cfdata->Encoding, "gs_free_copied_font(Encoding)");
gs_free_object(mem, cfdata->names, "gs_free_copied_font(names)");
gs_free_object(mem, cfdata->data, "gs_free_copied_font(data)");
+ if (cfdata->subrs.data != NULL)
+ gs_free_object(mem, cfdata->subrs.data, "gs_free_copied_font(subrs->data)");
+ if (cfdata->subrs.starts != NULL)
+ gs_free_object(mem, cfdata->subrs.starts, "gs_free_copied_font(subrs->starts)");
+ /* global subrs are 'shared with the parent', see copy_font_cid0()
+ * so we don't want to free them here, they are freed by the parent font.
+ */
gs_free_object(mem, cfdata, "gs_free_copied_font(wrapper data)");
}
gs_free_object(mem, font, "gs_free_copied_font(copied font)");
@@ -2295,6 +2306,10 @@ int gs_free_copied_font(gs_font *font)
if (copied2->subst_CID_on_WMode)
rc_decrement(copied2->subst_CID_on_WMode, "gs_free_copied_font(subst_CID_on_WMode");
+ gs_free_string(mem, (byte *)copied2->cidata.common.CIDSystemInfo.Registry.data, copied2->cidata.common.CIDSystemInfo.Registry.size, "Free copied Registry");
+ gs_free_string(mem, (byte *)copied2->cidata.common.CIDSystemInfo.Ordering.data, copied2->cidata.common.CIDSystemInfo.Ordering.size, "Free copied Registry");
+ copied2->cidata.common.CIDSystemInfo.Registry.data = copied2->cidata.common.CIDSystemInfo.Ordering.data = NULL;
+ copied2->cidata.common.CIDSystemInfo.Registry.size = copied2->cidata.common.CIDSystemInfo.Ordering.size = 0;
}
if (cfdata) {
diff --git a/devices/vector/gdevdocxw.c b/devices/vector/gdevdocxw.c
index 54ab5be7..b637a4c8 100644
--- a/devices/vector/gdevdocxw.c
+++ b/devices/vector/gdevdocxw.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
@@ -241,6 +241,12 @@ docxwrite_open_device(gx_device * dev)
gs_parsed_file_name_t parsed;
int code = 0;
+ if (tdev->extract) {
+ /* We can be called multiple times; nothing to do after the first time.
+ */
+ return 0;
+ }
+
gx_device_fill_in_procs(dev);
if (tdev->fname[0] == 0)
return_error(gs_error_undefinedfilename);
@@ -728,7 +734,8 @@ docx_update_text_state(docx_list_entry_t *ppts,
font->font_name.size + 1, "txtwrite alloc font name");
if (!ppts->FontName)
return gs_note_error(gs_error_VMerror);
- memcpy(ppts->FontName, font->font_name.chars, font->font_name.size + 1);
+ memcpy(ppts->FontName, font->font_name.chars, font->font_name.size);
+ ppts->FontName[font->font_name.size] = 0;
if (font->PaintType == 2 && penum->pgs->text_rendering_mode == 0)
{
@@ -980,7 +987,7 @@ docxwrite_process_plain_text(gx_device_docxwrite_t *tdev, gs_text_enum_t *pte)
ch = pte->text.data.chars[pte->index];
} else if (operation & (TEXT_FROM_GLYPHS | TEXT_FROM_SINGLE_GLYPH)) {
if (operation & TEXT_FROM_GLYPHS) {
- gdata = pte->text.data.glyphs + (pte->index++ * sizeof (gs_glyph));
+ gdata = pte->text.data.glyphs + pte->index++;
} else {
gdata = &pte->text.data.d_glyph;
}
@@ -1031,14 +1038,36 @@ docxwrite_process_plain_text(gx_device_docxwrite_t *tdev, gs_text_enum_t *pte)
return s_errno_to_gs();
}
}
+
+ /* Calculate glyph_width from the **original** glyph metrics, not the overriding
+ * advance width (if TEXT_REPLACE_WIDTHS is set below)
+ */
txt_char_widths_to_uts(pte->orig_font, &widths); /* convert design->text space */
+ glyph_width = widths.real_width.xy.x * penum->text_state->size;
+
+ if (pte->text.operation & TEXT_REPLACE_WIDTHS)
+ {
+ gs_point tpt;
+
+ /* We are applying a width override, from x/y/xyshow. This could be from
+ * a PostScript file, or it could be from a PDF file where we have a font
+ * with a FontMatrix which is neither horizontal nor vertical.
+ */
+ code = gs_text_replaced_width(&pte->text, pte->xy_index++, &tpt);
+ if (code < 0)
+ return_error(gs_error_unregistered);
+
+ widths.Width.w = widths.real_width.w = tpt.x;
+ widths.Width.xy.x = widths.real_width.xy.x = tpt.x;
+ widths.Width.xy.y = widths.real_width.xy.y = tpt.y;
+ }
+
gs_distance_transform(widths.real_width.xy.x * penum->text_state->size,
widths.real_width.xy.y * penum->text_state->size,
&penum->text_state->matrix, &wanted);
pte->returned.total_width.x += wanted.x;
pte->returned.total_width.y += wanted.y;
span_delta_x = widths.real_width.xy.x * penum->text_state->size;
- glyph_width = widths.real_width.xy.x * penum->text_state->size;
if (pte->text.operation & TEXT_ADD_TO_ALL_WIDTHS) {
gs_point tpt;
@@ -1061,7 +1090,7 @@ docxwrite_process_plain_text(gx_device_docxwrite_t *tdev, gs_text_enum_t *pte)
span_delta_x += dpt.x;
- code = txt_get_unicode(penum->dev, (gs_font *)pte->orig_font, glyph, ch, &chr2[0]);
+ (void) txt_get_unicode(penum->dev, (gs_font *)pte->orig_font, glyph, ch, &chr2[0]);
/* If a single text code returned multiple Unicode values, then we need to set the
* 'extra' code points' widths to 0.
*/
diff --git a/devices/vector/gdevpdf.c b/devices/vector/gdevpdf.c
index 9ab562c7..cb268f62 100644
--- a/devices/vector/gdevpdf.c
+++ b/devices/vector/gdevpdf.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
@@ -447,7 +447,7 @@ pdf_initialize_ids(gx_device_pdf * pdev)
tms = *localtime(&t);
#endif
- gs_sprintf(buf, "(D:%04d%02d%02d%02d%02d%02d%c%02d\'%02d\')",
+ gs_snprintf(buf, sizeof(buf), "(D:%04d%02d%02d%02d%02d%02d%c%02d\'%02d\')",
tms.tm_year + 1900, tms.tm_mon + 1, tms.tm_mday,
tms.tm_hour, tms.tm_min, tms.tm_sec,
timesign, timeoffset / 60, timeoffset % 60);
@@ -1600,7 +1600,7 @@ static int write_xref_section(gx_device_pdf *pdev, gp_file *tfile, int64_t start
* chances of needing to write white space to pad the file out.
*/
if (!pdev->Linearise) {
- gs_sprintf(str, "%010"PRId64" 00000 n \n", pos);
+ gs_snprintf(str, sizeof(str), "%010"PRId64" 00000 n \n", pos);
stream_puts(pdev->strm, str);
}
if (Offsets)
@@ -1633,7 +1633,7 @@ rewrite_object(gx_device_pdf *const pdev, pdf_linearisation_t *linear_params, in
code = gp_fread(&c, 1, 1, linear_params->sfile);
read++;
} while (c != '\n' && code > 0);
- gs_sprintf(Scratch, "%d 0 obj\n", pdev->ResourceUsage[object].NewObjectNumber);
+ gs_snprintf(Scratch, ScratchSize, "%d 0 obj\n", pdev->ResourceUsage[object].NewObjectNumber);
gp_fwrite(Scratch, strlen(Scratch), 1, linear_params->Lin_File.file);
code = gp_fread(&c, 1, 1, linear_params->sfile);
@@ -1685,7 +1685,7 @@ rewrite_object(gx_device_pdf *const pdev, pdf_linearisation_t *linear_params, in
target++;
(void)sscanf(target, "%d 0 R", &ID);
gp_fwrite(source, target - source, 1, linear_params->Lin_File.file);
- gs_sprintf(Buf, "%d 0 R", pdev->ResourceUsage[ID].NewObjectNumber);
+ gs_snprintf(Buf, sizeof(Buf), "%d 0 R", pdev->ResourceUsage[ID].NewObjectNumber);
gp_fwrite(Buf, strlen(Buf), 1, linear_params->Lin_File.file);
source = next;
} else {
@@ -1874,7 +1874,7 @@ static int pdf_linearise(gx_device_pdf *pdev, pdf_linearisation_t *linear_params
}
#endif
/* Linearisation. Part 1, file header */
- gs_sprintf(Header, "%%PDF-%d.%d\n", level / 10, level % 10);
+ gs_snprintf(Header, sizeof(Header), "%%PDF-%d.%d\n", level / 10, level % 10);
gp_fwrite(Header, strlen(Header), 1, linear_params->Lin_File.file);
if (pdev->binary_ok)
gp_fwrite(Binary, strlen(Binary), 1, linear_params->Lin_File.file);
@@ -1887,16 +1887,16 @@ static int pdf_linearise(gx_device_pdf *pdev, pdf_linearisation_t *linear_params
/* Linearisation. Part 2, the Linearisation dictioanry */
linear_params->LDictOffset = gp_ftell(linear_params->Lin_File.file);
- gs_sprintf(LDict, "%d 0 obj\n<< \n",
+ gs_snprintf(LDict, sizeof(LDict), "%d 0 obj\n<< \n",
LDictObj);
gp_fwrite(LDict, strlen(LDict), 1, linear_params->Lin_File.file);
/* First page cross-reference table here (Part 3) */
linear_params->FirstxrefOffset = gp_ftell(linear_params->Lin_File.file);
- gs_sprintf(Header, "xref\n%d %d\n", LDictObj, Part1To6 - LDictObj + 1); /* +1 for the primary hint stream */
+ gs_snprintf(Header, sizeof(Header), "xref\n%d %d\n", LDictObj, Part1To6 - LDictObj + 1); /* +1 for the primary hint stream */
gp_fwrite(Header, strlen(Header), 1, linear_params->Lin_File.file);
- gs_sprintf(Header, "0000000000 00000 n \n");
+ gs_snprintf(Header, sizeof(Header), "0000000000 00000 n \n");
for (i = LDictObj;i <= linear_params->LastResource + 2; i++) {
gp_fwrite(Header, 20, 1, linear_params->Lin_File.file);
@@ -1906,7 +1906,7 @@ 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_sprintf(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",
+ 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);
@@ -2024,7 +2024,7 @@ static int pdf_linearise(gx_device_pdf *pdev, pdf_linearisation_t *linear_params
}
}
/* insert the primary hint stream */
- gs_sprintf(LDict, "%d 0 obj\n<</Length \n/S >>\nstream\n", HintStreamObj);
+ gs_snprintf(LDict, sizeof(LDict), "%d 0 obj\n<</Length \n/S >>\nstream\n", HintStreamObj);
gp_fwrite(LDict, strlen(LDict), 1, linear_params->sfile);
HintStreamStart = gp_ftell(linear_params->sfile);
@@ -2338,7 +2338,7 @@ static int pdf_linearise(gx_device_pdf *pdev, pdf_linearisation_t *linear_params
flush_hint_stream(linear_params);
HintLength = gp_ftell(linear_params->sfile) - HintStreamStart;
- gs_sprintf(LDict, "\nendstream\nendobj\n");
+ gs_snprintf(LDict, sizeof(LDict), "\nendstream\nendobj\n");
gp_fwrite(LDict, strlen(LDict), 1, linear_params->sfile);
/* Calculate the length of the primary hint stream */
HintStreamLen = gp_ftell(linear_params->sfile) - pdev->ResourceUsage[HintStreamObj].LinearisedOffset;
@@ -2371,23 +2371,23 @@ static int pdf_linearise(gx_device_pdf *pdev, pdf_linearisation_t *linear_params
/* Now the file is long enough, write the xref */
mainxref = gp_ftell(linear_params->sfile);
- gs_sprintf(Header, "xref\n0 %d\n", LDictObj);
+ gs_snprintf(Header, sizeof(Header), "xref\n0 %d\n", LDictObj);
gp_fwrite(Header, strlen(Header), 1, linear_params->sfile);
linear_params->T = gp_ftell(linear_params->sfile) - 1;
- gs_sprintf(Header, "0000000000 65535 f \n");
+ gs_snprintf(Header, sizeof(Header), "0000000000 65535 f \n");
gp_fwrite(Header, strlen(Header), 1, linear_params->sfile);
for (i = 1;i < LDictObj; i++) {
for (j = 0; j < pdev->ResourceUsageSize;j++) {
if (pdev->ResourceUsage[j].NewObjectNumber == i) {
- gs_sprintf(Header, "%010"PRId64" 00000 n \n", pdev->ResourceUsage[j].LinearisedOffset + HintStreamLen);
+ gs_snprintf(Header, sizeof(Header), "%010"PRId64" 00000 n \n", pdev->ResourceUsage[j].LinearisedOffset + HintStreamLen);
gp_fwrite(Header, 20, 1, linear_params->sfile);
}
}
}
- gs_sprintf(LDict, "trailer\n<</Size %d>>\nstartxref\n%"PRId64"\n%%%%EOF\n",
+ gs_snprintf(LDict, sizeof(LDict), "trailer\n<</Size %d>>\nstartxref\n%"PRId64"\n%%%%EOF\n",
LDictObj, linear_params->FirstxrefOffset);
gp_fwrite(LDict, strlen(LDict), 1, linear_params->sfile);
@@ -2401,19 +2401,19 @@ static int pdf_linearise(gx_device_pdf *pdev, pdf_linearisation_t *linear_params
* versions.
*/
gp_fseek(linear_params->sfile, linear_params->LDictOffset, SEEK_SET);
- gs_sprintf(LDict, "%d 0 obj\n<</Linearized 1/L %"PRId64"/H[ ", LDictObj, linear_params->FileLength);
+ gs_snprintf(LDict, sizeof(LDict), "%d 0 obj\n<</Linearized 1/L %"PRId64"/H[ ", LDictObj, linear_params->FileLength);
gp_fwrite(LDict, strlen(LDict), 1, linear_params->sfile);
- gs_sprintf(LDict, "%"PRId64"", pdev->ResourceUsage[HintStreamObj].LinearisedOffset);
+ gs_snprintf(LDict, sizeof(LDict), "%"PRId64"", pdev->ResourceUsage[HintStreamObj].LinearisedOffset);
gp_fwrite(LDict, strlen(LDict), 1, linear_params->sfile);
- gs_sprintf(LDict, " %"PRId64"]", HintStreamLen);
+ gs_snprintf(LDict, sizeof(LDict), " %"PRId64"]", HintStreamLen);
gp_fwrite(LDict, strlen(LDict), 1, linear_params->sfile);
/* Implementation Note 180 in hte PDF Reference 1.7 says that Acrobat
* gets the 'E' value wrong. So its probably not important....
*/
- gs_sprintf(LDict, "/O %d/E %"PRId64"",pdev->ResourceUsage[pdev->pages[0].Page->id].NewObjectNumber, linear_params->E);
+ gs_snprintf(LDict, sizeof(LDict), "/O %d/E %"PRId64"",pdev->ResourceUsage[pdev->pages[0].Page->id].NewObjectNumber, linear_params->E);
gp_fwrite(LDict, strlen(LDict), 1, linear_params->sfile);
- gs_sprintf(LDict, "/N %d/T %"PRId64">>\nendobj\n", pdev->next_page, linear_params->T);
+ gs_snprintf(LDict, sizeof(LDict), "/N %d/T %"PRId64">>\nendobj\n", pdev->next_page, linear_params->T);
gp_fwrite(LDict, strlen(LDict), 1, linear_params->sfile);
/* Return to the secondary xref and write it again filling
@@ -2423,13 +2423,13 @@ static int pdf_linearise(gx_device_pdf *pdev, pdf_linearisation_t *linear_params
code = gs_error_ioerror;
goto error;
}
- gs_sprintf(Header, "xref\n%d %d\n", LDictObj, Part1To6 - LDictObj + 1); /* +1 for the primary hint stream */
+ gs_snprintf(Header, sizeof(Header), "xref\n%d %d\n", LDictObj, Part1To6 - LDictObj + 1); /* +1 for the primary hint stream */
gp_fwrite(Header, strlen(Header), 1, linear_params->sfile);
for (i = LDictObj;i <= linear_params->LastResource + 2; i++) {
for (j = 0; j < pdev->ResourceUsageSize;j++) {
if (pdev->ResourceUsage[j].NewObjectNumber == i) {
- gs_sprintf(Header, "%010"PRId64" 00000 n \n", pdev->ResourceUsage[j].LinearisedOffset);
+ gs_snprintf(Header, sizeof(Header), "%010"PRId64" 00000 n \n", pdev->ResourceUsage[j].LinearisedOffset);
gp_fwrite(Header, 20, 1, linear_params->sfile);
}
}
@@ -2442,7 +2442,7 @@ static int pdf_linearise(gx_device_pdf *pdev, pdf_linearisation_t *linear_params
if (code != 0)
return_error(gs_error_ioerror);
- gs_sprintf(LDict, "\ntrailer\n<</Size %ld/Info %d 0 R/Root %d 0 R/ID[%s%s]/Prev %"PRId64">>\nstartxref\r\n0\n%%%%EOF\n",
+ 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);
@@ -2450,9 +2450,9 @@ static int pdf_linearise(gx_device_pdf *pdev, pdf_linearisation_t *linear_params
if (code != 0)
return_error(gs_error_ioerror);
- gs_sprintf(LDict, "%d 0 obj\n<</Length %10"PRId64"", HintStreamObj, HintLength);
+ gs_snprintf(LDict, sizeof(LDict), "%d 0 obj\n<</Length %10"PRId64"", HintStreamObj, HintLength);
gp_fwrite(LDict, strlen(LDict), 1, linear_params->sfile);
- gs_sprintf(LDict, "\n/S %10"PRId64">>\nstream\n", SharedHintOffset);
+ gs_snprintf(LDict, sizeof(LDict), "\n/S %10"PRId64">>\nstream\n", SharedHintOffset);
gp_fwrite(LDict, strlen(LDict), 1, linear_params->sfile);
error:
@@ -2648,11 +2648,21 @@ pdf_close(gx_device * dev)
char str[256];
pdf_linearisation_t linear_params;
bool file_per_page = false;
+ int bottom = (pdev->ResourcesBeforeUsage ? 1 : 0);
if (!dev->is_open)
return_error(gs_error_undefined);
dev->is_open = false;
+ if (pdev->sbstack_depth > bottom) {
+ emprintf(pdev->pdf_memory, "Error closing device; open substreams detected!\n");
+ emprintf(pdev->pdf_memory, "Probably due to errors in the input. Output file is incorrect/invalid.\n");
+ }
+
+ while(pdev->sbstack_depth > bottom)
+ /* This is an error, and we are trying to recover, so ignore any further errors */
+ (void)pdf_exit_substream(pdev);
+
if (pdev->initial_pattern_states != NULL) {
int pdepth = 0;
@@ -3093,12 +3103,12 @@ pdf_close(gx_device * dev)
linear_params.xref = xref;
if (pdev->FirstObjectNumber == 1) {
- gs_sprintf(str, "xref\n0 %"PRId64"\n0000000000 65535 f \n",
+ gs_snprintf(str, sizeof(str), "xref\n0 %"PRId64"\n0000000000 65535 f \n",
end_section);
stream_puts(s, str);
}
else {
- gs_sprintf(str, "xref\n0 1\n0000000000 65535 f \n%"PRId64" %"PRId64"\n",
+ gs_snprintf(str, sizeof(str), "xref\n0 1\n0000000000 65535 f \n%"PRId64" %"PRId64"\n",
start_section,
end_section - start_section);
stream_puts(s, str);
@@ -3107,7 +3117,7 @@ pdf_close(gx_device * dev)
do {
code = write_xref_section(pdev, tfile, start_section, end_section, resource_pos, linear_params.Offsets);
if (code < 0)
- return code;
+ goto error_cleanup;
if (end_section >= pdev->next_id)
break;
@@ -3115,7 +3125,7 @@ pdf_close(gx_device * dev)
end_section = find_end_xref_section(pdev, tfile, start_section, resource_pos);
if (end_section < 0)
return end_section;
- gs_sprintf(str, "%"PRId64" %"PRId64"\n", start_section, end_section - start_section);
+ gs_snprintf(str, sizeof(str), "%"PRId64" %"PRId64"\n", start_section, end_section - start_section);
stream_puts(s, str);
} while (1);
@@ -3134,7 +3144,7 @@ pdf_close(gx_device * dev)
pprintld1(s, "/Encrypt %ld 0 R ", Encrypt_id);
}
stream_puts(s, ">>\n");
- gs_sprintf(xref_str, "startxref\n%"PRId64"\n%%%%EOF\n", xref);
+ gs_snprintf(xref_str, sizeof(xref_str), "startxref\n%"PRId64"\n%%%%EOF\n", xref);
stream_puts(s, xref_str);
}
}
@@ -3150,6 +3160,7 @@ pdf_close(gx_device * dev)
gs_free_object(pdev->pdf_memory->non_gc_memory, pdev->ResourceUsage, "Free linearisation resource usage records");
}
+error_cleanup:
/* Require special handling for Fonts, ColorSpace and Pattern resources
* These are tracked in pdev->last_resource, and are complex structures which may
* contain other memory allocations. All other resource types can be simply dicarded
@@ -3501,6 +3512,15 @@ pdf_close(gx_device * dev)
gs_free_object(mem, pdev->pages[i].Annots, "Free Annots dict");
}
gs_free_object(mem, pdev->pages[i].Page, "Free Page object");
+ pdev->pages[i].Page = NULL;
+ }
+ 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");
+ gs_free_object(mem, pdev->pages[i].Page, "Free Page object");
+ pdev->pages[i].Page = NULL;
+ }
}
}
gs_free_object(mem, pdev->pages, "pages");
@@ -3562,6 +3582,8 @@ pdf_close(gx_device * dev)
code = gs_error_ioerror;
}
+ pdf_free_pdf_font_cache(pdev);
+
code1 = gdev_vector_close_file((gx_device_vector *) pdev);
if (code >= 0)
code = code1;
@@ -3588,6 +3610,5 @@ pdf_close(gx_device * dev)
code = gs_note_error(gs_error_ioerror);
}
- pdf_free_pdf_font_cache(pdev);
return code;
}
diff --git a/devices/vector/gdevpdfb.h b/devices/vector/gdevpdfb.h
index daa6ba0a..b85dffe3 100644
--- a/devices/vector/gdevpdfb.h
+++ b/devices/vector/gdevpdfb.h
@@ -184,6 +184,7 @@ const gx_device_pdf PDF_DEVICE_IDENT =
{{0, 0}, {0, 0}}, /* Charproc BBox */
0, /* charproc_just_accumulated */
1, /* PS_accumulator */
+ 0, /* Scaled_accumulator */
0, /* accumulating_a_global_object */
0, /* cgp */
0, /* substituted_pattern_count */
diff --git a/devices/vector/gdevpdfd.c b/devices/vector/gdevpdfd.c
index c7cad3e5..ea40111b 100644
--- a/devices/vector/gdevpdfd.c
+++ b/devices/vector/gdevpdfd.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
@@ -499,7 +499,7 @@ static int pdf_write_path(gx_device_pdf * pdev, gs_path_enum *cenum, gdev_vector
buffering = 0;
seg_index = -1;
}
- if (type & gx_path_type_optimize) {
+ if (type & gx_path_type_optimize && seg_index > 0) {
if (segments[seg_index - 1].op == gs_pe_lineto) {
if (segments[seg_index].vs[0].x == segments[seg_index - 1].vs[0].x && segments[seg_index].vs[0].x == line_start.x) {
if (segments[seg_index - 1].vs[0].y > line_start.y && segments[seg_index].vs[0].y >= segments[seg_index - 1].vs[0].y) {
diff --git a/devices/vector/gdevpdfe.c b/devices/vector/gdevpdfe.c
index e083ee11..ec011d8b 100644
--- a/devices/vector/gdevpdfe.c
+++ b/devices/vector/gdevpdfe.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
@@ -209,7 +209,7 @@ pdf_xmp_time(char *buf, int buf_length)
time(&t);
tms = *localtime(&t);
#endif
- gs_sprintf(buf1,
+ gs_snprintf(buf1, sizeof(buf1),
"%04d-%02d-%02d",
tms.tm_year + 1900, tms.tm_mon + 1, tms.tm_mday);
strncpy(buf, buf1, buf_length);
@@ -489,8 +489,11 @@ pdf_xmp_write_translated(gx_device_pdf *pdev, stream *s, const byte *data, int d
/* Skip the Byte Order Mark (0xfe 0xff) */
buf0b = (short *)(buf0 + 2);
code = gs_ConvertUTF16((unsigned char *)buf0b, j - 2, (unsigned char **)&buf1b, data_length * 2 * sizeof(unsigned char));
- if (code < 0)
+ if (code < 0) {
+ gs_free_object(pdev->memory, buf0, "pdf_xmp_write_translated");
+ gs_free_object(pdev->memory, buf1, "pdf_xmp_write_translated");
return code;
+ }
write(s, (const byte *)buf1, buf1b - buf1);
gs_free_object(pdev->memory, buf1, "pdf_xmp_write_translated");
}
@@ -881,7 +884,7 @@ pdf_document_metadata(gx_device_pdf *pdev)
code = COS_WRITE_OBJECT(pres->object, pdev, resourceNone);
if (code < 0)
return code;
- gs_sprintf(buf, "%ld 0 R", pres->object->id);
+ gs_snprintf(buf, sizeof(buf), "%ld 0 R", pres->object->id);
pdf_record_usage(pdev, pres->object->id, resource_usage_part9_structure);
code = cos_dict_put_c_key_object(pdev->Catalog, "/Metadata", pres->object);
diff --git a/devices/vector/gdevpdfg.c b/devices/vector/gdevpdfg.c
index 6feec8b0..d61712b0 100644
--- a/devices/vector/gdevpdfg.c
+++ b/devices/vector/gdevpdfg.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
@@ -2083,7 +2083,7 @@ transfer_map_access_signed(const gs_data_source_t *psrc,
static int
pdf_write_transfer_map(gx_device_pdf *pdev, const gx_transfer_map *map,
int range0, bool check_identity,
- const char *key, char *ids)
+ const char *key, char *ids, int id_max)
{
gs_memory_t *mem = pdev->pdf_memory;
gs_function_Sd_params_t params;
@@ -2152,14 +2152,14 @@ pdf_write_transfer_map(gx_device_pdf *pdev, const gx_transfer_map *map,
gs_function_free(pfn, false, mem);
if (code < 0)
return code;
- gs_sprintf(ids, "%s%s%ld 0 R", key, (key[0] && key[0] != ' ' ? " " : ""), id);
+ gs_snprintf(ids, id_max, "%s%s%ld 0 R", key, (key[0] && key[0] != ' ' ? " " : ""), id);
return 0;
}
static int
pdf_write_transfer(gx_device_pdf *pdev, const gx_transfer_map *map,
- const char *key, char *ids)
+ const char *key, char *ids, int id_max)
{
- return pdf_write_transfer_map(pdev, map, 0, true, key, ids);
+ return pdf_write_transfer_map(pdev, map, 0, true, key, ids, id_max);
}
/* ------ Halftones ------ */
@@ -2395,7 +2395,7 @@ pdf_write_spot_halftone(gx_device_pdf *pdev, const gs_spot_halftone *psht,
if (pdev->CompatibilityLevel <= 1.7) {
code = pdf_write_transfer(pdev, porder->transfer, "/TransferFunction",
- trs);
+ trs, sizeof(trs));
if (code < 0)
return code;
}
@@ -2515,7 +2515,7 @@ pdf_write_threshold_halftone(gx_device_pdf *pdev,
memset(trs, 0x00, 17 + MAX_FN_CHARS + 1);
if (pdev->CompatibilityLevel <= 1.7) {
code = pdf_write_transfer(pdev, porder->transfer, "",
- trs);
+ trs, sizeof(trs));
if (code < 0)
return code;
@@ -2549,7 +2549,7 @@ pdf_write_threshold2_halftone(gx_device_pdf *pdev,
memset(trs, 0x00, 17 + MAX_FN_CHARS + 1);
if (pdev->CompatibilityLevel <= 1.7) {
code = pdf_write_transfer(pdev, porder->transfer, "",
- trs);
+ trs, sizeof(trs));
if (code < 0)
return code;
@@ -2710,7 +2710,7 @@ pdf_write_multiple_halftone(gx_device_pdf *pdev, gs_gstate *pgs,
*/
static int
pdf_update_halftone(gx_device_pdf *pdev, const gs_gstate *pgs,
- char *hts)
+ char *hts, int hts_max)
{
const gs_halftone *pht = pgs->halftone;
const gx_device_halftone *pdht = pgs->dev_ht[HT_OBJTYPE_DEFAULT];
@@ -2748,7 +2748,7 @@ pdf_update_halftone(gx_device_pdf *pdev, const gs_gstate *pgs,
}
if (code < 0)
return code;
- gs_sprintf(hts, "%ld 0 R", id);
+ gs_snprintf(hts, hts_max, "%ld 0 R", id);
pdev->halftone_id = pgs->dev_ht[HT_OBJTYPE_DEFAULT]->id;
return code;
}
@@ -2816,7 +2816,7 @@ pdf_end_gstate(gx_device_pdf *pdev, pdf_resource_t *pres)
*/
static int
pdf_update_transfer(gx_device_pdf *pdev, const gs_gstate *pgs,
- char *trs)
+ char *trs, int trs_max)
{
int i, pi = -1;
bool multiple = false, update = false;
@@ -2842,7 +2842,7 @@ pdf_update_transfer(gx_device_pdf *pdev, const gs_gstate *pgs,
int mask;
if (!multiple) {
- code = pdf_write_transfer(pdev, tm[pi], "", trs);
+ code = pdf_write_transfer(pdev, tm[pi], "", trs, trs_max);
if (code < 0)
return code;
mask = code == 0;
@@ -2851,9 +2851,10 @@ pdf_update_transfer(gx_device_pdf *pdev, const gs_gstate *pgs,
mask = 0;
for (i = 0; i < 4; ++i)
if (tm[i] != NULL) {
+ int len = (int)strlen(trs);
code = pdf_write_transfer_map(pdev,
tm[i],
- 0, true, " ", trs + strlen(trs));
+ 0, true, " ", trs + len, trs_max - len);
if (code < 0)
return code;
mask |= (code == 0) << i;
@@ -2891,7 +2892,7 @@ pdf_update_alpha(gx_device_pdf *pdev, const gs_gstate *pgs,
}
}
else{
- gs_sprintf(buf, "%ld 0 R", pgs->soft_mask_id);
+ gs_snprintf(buf, sizeof(buf), "%ld 0 R", pgs->soft_mask_id);
code = pdf_open_gstate(pdev, ppres);
if (code < 0)
return code;
@@ -2941,6 +2942,9 @@ pdf_prepare_drawing(gx_device_pdf *pdev, const gs_gstate *pgs,
int bottom;
if (pdev->CompatibilityLevel >= 1.4) {
+ code = pdf_update_alpha(pdev, pgs, ppres, for_text);
+ if (code < 0)
+ return code;
if (pdev->state.blend_mode != pgs->blend_mode) {
static const char *const bm_names[] = { GS_BLEND_MODE_NAMES };
char buf[20];
@@ -2955,9 +2959,6 @@ pdf_prepare_drawing(gx_device_pdf *pdev, const gs_gstate *pgs,
return code;
pdev->state.blend_mode = pgs->blend_mode;
}
- code = pdf_update_alpha(pdev, pgs, ppres, for_text);
- if (code < 0)
- return code;
} else {
/*
* If the graphics state calls for any transparency functions,
@@ -2991,28 +2992,28 @@ pdf_prepare_drawing(gx_device_pdf *pdev, const gs_gstate *pgs,
pdev->halftone_id != pgs->dev_ht[HT_OBJTYPE_DEFAULT]->id &&
!pdev->PDFX
) {
- code = pdf_update_halftone(pdev, pgs, hts);
+ code = pdf_update_halftone(pdev, pgs, hts, sizeof(hts));
if (code < 0)
return code;
}
if (pdev->params.TransferFunctionInfo != tfi_Remove &&
!pdev->PDFX && pdev->PDFA == 0
) {
- code = pdf_update_transfer(pdev, pgs, trs);
+ code = pdf_update_transfer(pdev, pgs, trs, sizeof(trs));
if (code < 0)
return code;
}
if (pdev->params.UCRandBGInfo == ucrbg_Preserve) {
if (pgs->black_generation && pdev->black_generation_id != pgs->black_generation->id) {
code = pdf_write_transfer_map(pdev, pgs->black_generation,
- 0, false, "", bgs);
+ 0, false, "", bgs, sizeof(bgs));
if (code < 0)
return code;
pdev->black_generation_id = pgs->black_generation->id;
}
if (pgs->undercolor_removal && pdev->undercolor_removal_id != pgs->undercolor_removal->id) {
code = pdf_write_transfer_map(pdev, pgs->undercolor_removal,
- -1, false, "", ucrs);
+ -1, false, "", ucrs, sizeof(ucrs));
if (code < 0)
return code;
pdev->undercolor_removal_id = pgs->undercolor_removal->id;
@@ -3046,14 +3047,45 @@ pdf_prepare_drawing(gx_device_pdf *pdev, const gs_gstate *pgs,
if (!pdev->PDFX) {
gs_currentscreenphase(pgs, &phase, 0);
gs_currentscreenphase(&pdev->state, &dev_phase, 0);
+ if ((dev_phase.x != phase.x || dev_phase.y != phase.y) && pdev->PDFA != 0) {
+ switch (pdev->PDFACompatibilityPolicy) {
+ case 0:
+ emprintf(pdev->memory,
+ "\nSetting Halftone Phase or Halftone Offset\n not permitted in PDF/A, reverting to normal PDF output\n");
+ pdev->AbortPDFAX = true;
+ pdev->PDFA = 0;
+ break;
+ case 1:
+ emprintf(pdev->memory,
+ "\nSetting Halftone Phase or Halftone Offset\n not permitted in PDF/A, values not set\n\n");
+ /* Deliberately breaking const here in order to force the graphics state overprint mode to be unchanged */
+ dev_phase.x = phase.x;
+ dev_phase.y = phase.y;
+ break;
+ case 2:
+ emprintf(pdev->memory,
+ "\nSetting Halftone Phase or Halftone Offset\n not permitted in PDF/A, aborting conversion\n");
+ return_error(gs_error_undefined);
+ break;
+ default:
+ emprintf(pdev->memory,
+ "\nSetting Overprint Mode to 1\n not permitted in PDF/A, unrecognised PDFACompatibilityLevel,\nreverting to normal PDF output\n");
+ pdev->AbortPDFAX = true;
+ pdev->PDFA = 0;
+ break;
+ }
+ }
if (dev_phase.x != phase.x || dev_phase.y != phase.y) {
char buf[sizeof(int) * 3 + 5];
code = pdf_open_gstate(pdev, ppres);
if (code < 0)
return code;
- gs_sprintf(buf, "[%d %d]", phase.x, phase.y);
- code = cos_dict_put_string_copy(resource_dict(*ppres), "/HTP", buf);
+ gs_snprintf(buf, sizeof(buf), "[%d %d]", phase.x, phase.y);
+ if (pdev->CompatibilityLevel >= 1.999)
+ code = cos_dict_put_string_copy(resource_dict(*ppres), "/HTO", buf);
+ else
+ code = cos_dict_put_string_copy(resource_dict(*ppres), "/HTP", buf);
if (code < 0)
return code;
gx_gstate_setscreenphase(&pdev->state, phase.x, phase.y,
diff --git a/devices/vector/gdevpdfi.c b/devices/vector/gdevpdfi.c
index 82e8f7a2..1e1a9daa 100644
--- a/devices/vector/gdevpdfi.c
+++ b/devices/vector/gdevpdfi.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
@@ -1923,7 +1923,7 @@ pdf_end_and_do_image(gx_device_pdf *pdev, pdf_image_writer *piw,
if (pdev->image_mask_id != gs_no_id) {
char buf[20];
- gs_sprintf(buf, "%ld 0 R", pdev->image_mask_id);
+ gs_snprintf(buf, sizeof(buf), "%ld 0 R", pdev->image_mask_id);
code = cos_dict_put_string_copy((cos_dict_t *)pres->object,
pdev->image_mask_is_SMask ? "/SMask" : "/Mask", buf);
(*(pres->object)).md5_valid = 0;
@@ -2372,6 +2372,8 @@ static int reset_gstate_for_pattern(gx_device_pdf * pdev, gs_gstate *destination
source->line_params.dot_length_absolute = pdev->vg_initial.line_params.dot_length_absolute;
destination->line_params.dot_orientation = source->line_params.dot_orientation;
source->line_params.dot_orientation = pdev->vg_initial.line_params.dot_orientation;
+ if (destination->line_params.dash.pattern != NULL && destination->line_params.dash.pattern != source->line_params.dash.pattern)
+ gs_free_object(destination->memory, destination->line_params.dash.pattern, "free dash assigned during pattern accumulation");
memcpy(&destination->line_params.dash, &source->line_params.dash, sizeof(source->line_params.dash));
memcpy(&source->line_params.dash, &pdev->vg_initial.line_params.dash, sizeof(source->line_params.dash));
}
diff --git a/devices/vector/gdevpdfm.c b/devices/vector/gdevpdfm.c
index 902c17ac..f6b6c51f 100644
--- a/devices/vector/gdevpdfm.c
+++ b/devices/vector/gdevpdfm.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
@@ -171,12 +171,12 @@ pdfmark_make_dest(char dstr[MAX_DEST_STRING], gx_device_pdf * pdev,
else if (pdfmark_find_key("/Action", pairs, count, &action) &&
pdf_key_eq(&action, "/GoToR")
)
- gs_sprintf(dstr, "[%d ", page - 1);
+ gs_snprintf(dstr, MAX_DEST_STRING, "[%d ", page - 1);
else {
code = update_max_page_reference(pdev, &page);
if (code < 0)
return code;
- gs_sprintf(dstr, "[%ld 0 R ", pdf_page_id(pdev, page));
+ gs_snprintf(dstr, MAX_DEST_STRING, "[%ld 0 R ", pdf_page_id(pdev, page));
}
len = strlen(dstr);
if (len + view_string.size > MAX_DEST_STRING)
@@ -912,7 +912,7 @@ pdfmark_put_ao_pairs(gx_device_pdf * pdev, cos_dict_t *pcd,
char dstr[1 + (sizeof(long) * 8 / 3 + 1) + 25 + 1];
long page_id = pdf_page_id(pdev, pdev->next_page + 1);
- gs_sprintf(dstr, "[%ld 0 R /XYZ null null null]", page_id);
+ gs_snprintf(dstr, MAX_DEST_STRING, "[%ld 0 R /XYZ null null null]", page_id);
cos_dict_put_c_key_string(pcd, "/Dest", (const unsigned char*) dstr,
strlen(dstr));
}
@@ -1769,7 +1769,7 @@ pdfmark_PS(gx_device_pdf * pdev, gs_param_string * pairs, uint count,
if (level1_id != gs_no_id) {
char r[MAX_DEST_STRING];
- gs_sprintf(r, "%ld 0 R", level1_id);
+ gs_snprintf(r, sizeof(r), "%ld 0 R", level1_id);
code = cos_dict_put_c_key_string(cos_stream_dict(pcs), "/Level1",
(byte *)r, strlen(r));
if (code < 0)
@@ -1933,7 +1933,7 @@ pdfmark_PAGELABEL(gx_device_pdf * pdev, gs_param_string * pairs, uint count,
return 0;
}
-static int is_XMP_Key(gs_param_string *param)
+static int is_XMP_Key(const gs_param_string *param)
{
if (pdf_key_eq(param, "/Title"))
return 1;
@@ -2450,7 +2450,23 @@ static int
pdfmark_MP(gx_device_pdf *pdev, gs_param_string *pairs, uint count,
const gs_matrix *pctm, const gs_param_string *objname)
{
- return 0; /****** NOT IMPLEMENTED YET ******/
+ int code;
+ char *tag;
+
+ if (count != 1) return_error(gs_error_rangecheck);
+
+ tag = (char *)gs_alloc_bytes(pdev->memory, (pairs[0].size + 1) * sizeof(unsigned char),
+ "pdfmark_MP");
+ memcpy(tag, pairs[0].data, pairs[0].size);
+ tag[pairs[0].size] = 0x00;
+
+ code = pdf_open_contents(pdev, PDF_IN_STREAM);
+ if (code < 0) return code;
+
+ pprints1(pdev->strm, "%s MP\n", tag);
+
+ gs_free_object(pdev->memory, tag, "pdfmark_MP");
+ return 0;
}
/* [ tag propdict /DP pdfmark */
@@ -2458,7 +2474,87 @@ static int
pdfmark_DP(gx_device_pdf *pdev, gs_param_string *pairs, uint count,
const gs_matrix *pctm, const gs_param_string *objname)
{
- return 0; /****** NOT IMPLEMENTED YET ******/
+ int code;
+ cos_object_t *pco;
+ char *cstring;
+ pdf_resource_t *pres;
+
+ if (count != 2) return_error(gs_error_rangecheck);
+
+ /* check tag for /Name object syntax */
+ if ((pairs[0].data)[0] != '/') return_error(gs_error_rangecheck);
+
+ /* check propdict for {object name} syntax */
+ if (pdf_objname_is_valid(pairs[1].data, pairs[1].size))
+ {
+ code = pdf_refer_named(pdev, &pairs[1], &pco);
+ if(code < 0) return code;
+ }
+ else /* << inline prop dict >> */
+ {
+ /* strip << and >> */
+ if ((pairs[1].data)[0]=='<'&&(pairs[1].data)[1]=='<')
+ {
+ int ix = 0;
+ byte *p = (byte *)pairs[1].data;
+
+ /* Fortunately we don't use the 'size' when freeing the memory
+ * so we can quickly copy the string content up two places and reduce
+ * the size by 2 to remove the '<<'. This saves an alloc and free of the
+ * string data.
+ */
+ for (ix = 0; ix < pairs[1].size - 2;ix++)
+ p[ix] = pairs[1].data[ix + 2];
+ pairs[1].size-=2;
+ }
+ else
+ return_error(gs_error_rangecheck);
+
+ if ((pairs[1].data)[pairs[1].size-1]=='>'&&(pairs[1].data)[pairs[1].size-2]=='>')
+ pairs[1].size-=2;
+
+ /* convert inline propdict to C string with object names replaced by refs */
+ code = pdf_replace_names(pdev, &pairs[1], &pairs[1]);
+ if (code<0) return code;
+ cstring = (char *)gs_alloc_bytes(pdev->memory, (pairs[1].size + 1) * sizeof(unsigned char),
+ "pdfmark_DP");
+ memcpy(cstring, pairs[1].data, pairs[1].size);
+ cstring[pairs[1].size] = 0x00;
+
+ code = pdf_make_named_dict(pdev, NULL, (cos_dict_t**) &pco, true);
+ if (code<0) return code;
+
+ /* copy inline propdict to new object */
+ code = cos_dict_put_c_strings((cos_dict_t*) pco, cstring, "");
+ if(code < 0) return code;
+ COS_WRITE_OBJECT(pco, pdev, resourceProperties);
+ COS_RELEASE(pco, "pdfmark_DP");
+ gs_free_object(pdev->memory, cstring, "pdfmark_DP");
+ }
+
+ pres = pdf_find_resource_by_resource_id(pdev, resourceProperties, pco->id);
+ if (pres==0){
+ if ((code = pdf_alloc_resource(pdev, resourceProperties, pco->id, &(pco->pres), pco->id))<0)
+ return code;
+ }
+
+ cstring = (char *)gs_alloc_bytes(pdev->memory, (pairs[0].size + 1) * sizeof(unsigned char),
+ "pdfmark_DP");
+ memcpy(cstring, pairs[0].data, pairs[0].size);
+ cstring[pairs[0].size] = 0x00;
+
+ /* make sure we write to the correct stream */
+ code = pdf_open_contents(pdev, PDF_IN_STREAM);
+ if (code < 0) return code;
+
+ pprints1(pdev->strm, "%s", cstring); /* write tag */
+ pprintld1(pdev->strm, "/R%ld DP\n", pco->id);
+ pco->pres->where_used |= pdev->used_mask;
+ if ((code = pdf_add_resource(pdev, pdev->substream_Resources, "/Properties", pco->pres))<0)
+ return code;
+
+ gs_free_object(pdev->memory, cstring, "pdfmark_DP");
+ return 0;
}
/* [ tag /BMC pdfmark */
diff --git a/devices/vector/gdevpdfo.c b/devices/vector/gdevpdfo.c
index a1c18012..3ec00f5e 100644
--- a/devices/vector/gdevpdfo.c
+++ b/devices/vector/gdevpdfo.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
@@ -701,7 +701,7 @@ cos_array_add_int(cos_array_t *pca, int i)
char str[sizeof(int) * 8 / 3 + 3]; /* sign, rounding, 0 terminator */
cos_value_t v;
- gs_sprintf(str, "%d", i);
+ gs_snprintf(str, sizeof(str), "%d", i);
return cos_array_add(pca, cos_string_value(&v, (byte *)str, strlen(str)));
}
int
@@ -1380,7 +1380,7 @@ cos_dict_put_c_key_int(cos_dict_t *pcd, const char *key, int value)
{
char str[sizeof(int) * 8 / 3 + 3]; /* sign, rounding, 0 terminator */
- gs_sprintf(str, "%d", value);
+ gs_snprintf(str, sizeof(str), "%d", value);
return cos_dict_put_c_key_string(pcd, key, (byte *)str, strlen(str));
}
int
diff --git a/devices/vector/gdevpdfr.c b/devices/vector/gdevpdfr.c
index 7aca15a6..fd641aef 100644
--- a/devices/vector/gdevpdfr.c
+++ b/devices/vector/gdevpdfr.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
@@ -140,7 +140,7 @@ pdf_refer_named(gx_device_pdf * pdev, const gs_param_string * pname_orig,
}
if (page_number <= 0)
return code;
- gs_sprintf(page_name_chars, "{Page%d}", page_number);
+ gs_snprintf(page_name_chars, sizeof(page_name_chars), "{Page%d}", page_number);
param_string_from_string(pnstr, page_name_chars);
pname = &pnstr;
code = pdf_find_named(pdev, pname, ppco);
@@ -470,7 +470,7 @@ pdf_replace_names(gx_device_pdf * pdev, const gs_param_string * from,
size += sname - scan;
if (pco) {
- gs_sprintf(ref, " %ld 0 R ", pco->id);
+ gs_snprintf(ref, sizeof(ref), " %ld 0 R ", pco->id);
size += strlen(ref);
/* Special 'name' escaping convention (see gs_pdfwr.ps, /.pdf===dict
* the /nametype procedure). We do not want to write out the NULL
@@ -509,7 +509,7 @@ pdf_replace_names(gx_device_pdf * pdev, const gs_param_string * from,
memcpy(sto, scan, copy);
sto += copy;
if (pco) {
- gs_sprintf(ref, " %ld 0 R ", pco->id);
+ gs_snprintf(ref, sizeof(ref), " %ld 0 R ", pco->id);
rlen = strlen(ref);
if (sname >= (start + 2) && sname[-1] == 0x00 && sname[-2] == 0x00 && next[0] == 0x00) {
sto -= 2;
diff --git a/devices/vector/gdevpdft.c b/devices/vector/gdevpdft.c
index 5b8af68d..72f082f9 100644
--- a/devices/vector/gdevpdft.c
+++ b/devices/vector/gdevpdft.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
@@ -63,7 +63,7 @@ pdf_make_soft_mask_dict(gx_device_pdf * pdev, const gs_pdf14trans_params_t * ppa
code = pdf_write_function(pdev, pparams->transfer_function, &id);
if (code < 0)
return code;
- gs_sprintf(buf, " %ld 0 R", id);
+ gs_snprintf(buf, sizeof(buf), " %ld 0 R", id);
code = cos_dict_put_c_key_string(soft_mask_dict, "/TR", (const byte *)buf, strlen(buf));
if (code < 0)
return code;
@@ -365,7 +365,7 @@ pdf_end_transparency_mask(gs_gstate * pgs, gx_device_pdf * pdev,
return 0;
/* We need to update the 'where_used' field, in case we substituted a resource */
pres->where_used |= pdev->used_mask;
- gs_sprintf(buf, "%ld 0 R", pdf_resource_id(pres));
+ gs_snprintf(buf, sizeof(buf), "%ld 0 R", pdf_resource_id(pres));
if (pdev->pres_soft_mask_dict == 0L) {
/* something went horribly wrong, we have an 'end' wihtout a matching 'begin'
* Give up, throw an error.
diff --git a/devices/vector/gdevpdfu.c b/devices/vector/gdevpdfu.c
index ec4a8165..f12fa38e 100644
--- a/devices/vector/gdevpdfu.c
+++ b/devices/vector/gdevpdfu.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
@@ -335,14 +335,14 @@ static int write_tt_encodings(stream *s, bool HaveTrueTypes)
char Buffer[256];
single_glyph_list_t *entry = SingleGlyphList;
- gs_sprintf(Buffer, "/AdobeGlyphList mark\n");
+ gs_snprintf(Buffer, sizeof(Buffer), "/AdobeGlyphList mark\n");
stream_write(s, Buffer, strlen(Buffer));
while (entry->Glyph) {
- gs_sprintf(Buffer, "/%s 16#%04x\n", entry->Glyph, entry->Unicode);
+ gs_snprintf(Buffer, sizeof(Buffer), "/%s 16#%04x\n", entry->Glyph, entry->Unicode);
stream_write(s, Buffer, strlen(Buffer));
entry++;
};
- gs_sprintf(Buffer, ".dicttomark readonly def\n");
+ gs_snprintf(Buffer, sizeof(Buffer), ".dicttomark readonly def\n");
stream_write(s, Buffer, strlen(Buffer));
index = 0;
@@ -523,29 +523,29 @@ int ps2write_dsc_header(gx_device_pdf * pdev, int pages)
}
}
if (!pdev->Eps2Write || pdev->BBox.p.x > pdev->BBox.q.x || pdev->BBox.p.y > pdev->BBox.q.y)
- gs_sprintf(BBox, "%%%%BoundingBox: 0 0 %d %d\n", (int)urx, (int)ury);
+ gs_snprintf(BBox, sizeof(BBox), "%%%%BoundingBox: 0 0 %d %d\n", (int)urx, (int)ury);
else
- gs_sprintf(BBox, "%%%%BoundingBox: %d %d %d %d\n", (int)floor(pdev->BBox.p.x), (int)floor(pdev->BBox.p.y), (int)ceil(pdev->BBox.q.x), (int)ceil(pdev->BBox.q.y));
+ gs_snprintf(BBox, sizeof(BBox), "%%%%BoundingBox: %d %d %d %d\n", (int)floor(pdev->BBox.p.x), (int)floor(pdev->BBox.p.y), (int)ceil(pdev->BBox.q.x), (int)ceil(pdev->BBox.q.y));
stream_write(s, (byte *)BBox, strlen(BBox));
if (!pdev->Eps2Write || pdev->BBox.p.x > pdev->BBox.q.x || pdev->BBox.p.y > pdev->BBox.q.y)
- gs_sprintf(BBox, "%%%%HiResBoundingBox: 0 0 %.2f %.2f\n", urx, ury);
+ gs_snprintf(BBox, sizeof(BBox), "%%%%HiResBoundingBox: 0 0 %.2f %.2f\n", urx, ury);
else
- gs_sprintf(BBox, "%%%%HiResBoundingBox: %.2f %.2f %.2f %.2f\n", pdev->BBox.p.x, pdev->BBox.p.y, pdev->BBox.q.x, pdev->BBox.q.y);
+ gs_snprintf(BBox, sizeof(BBox), "%%%%HiResBoundingBox: %.2f %.2f %.2f %.2f\n", pdev->BBox.p.x, pdev->BBox.p.y, pdev->BBox.q.x, pdev->BBox.q.y);
stream_write(s, (byte *)BBox, strlen(BBox));
}
cre_date_time_len = pdf_get_docinfo_item(pdev, "/CreationDate", cre_date_time, sizeof(cre_date_time) - 1);
cre_date_time[cre_date_time_len] = 0;
- gs_sprintf(BBox, "%%%%Creator: %s %d (%s)\n", gs_product, (int)gs_revision,
+ gs_snprintf(BBox, sizeof(BBox), "%%%%Creator: %s %d (%s)\n", gs_product, (int)gs_revision,
pdev->dname);
stream_write(s, (byte *)BBox, strlen(BBox));
stream_puts(s, "%%LanguageLevel: 2\n");
- gs_sprintf(BBox, "%%%%CreationDate: %s\n", cre_date_time);
+ gs_snprintf(BBox, sizeof(BBox), "%%%%CreationDate: %s\n", cre_date_time);
stream_write(s, (byte *)BBox, strlen(BBox));
- gs_sprintf(BBox, "%%%%Pages: %d\n", pages);
+ gs_snprintf(BBox, sizeof(BBox), "%%%%Pages: %d\n", pages);
stream_write(s, (byte *)BBox, strlen(BBox));
- gs_sprintf(BBox, "%%%%EndComments\n");
+ gs_snprintf(BBox, sizeof(BBox), "%%%%EndComments\n");
stream_write(s, (byte *)BBox, strlen(BBox));
- gs_sprintf(BBox, "%%%%BeginProlog\n");
+ gs_snprintf(BBox, sizeof(BBox), "%%%%BeginProlog\n");
stream_write(s, (byte *)BBox, strlen(BBox));
if (pdev->params.CompressPages) {
/* When CompressEntireFile is true and ASCII85EncodePages is false,
@@ -605,7 +605,7 @@ pdfwrite_pdf_open_document(gx_device_pdf * pdev)
pdev->CompressEntireFile = 0;
else {
stream_write(s, (byte *)"%!\r", 3);
- gs_sprintf(BBox, "%%%%BoundingBox: 0 0 %d %d\n", width, height);
+ gs_snprintf(BBox, sizeof(BBox), "%%%%BoundingBox: 0 0 %d %d\n", width, height);
stream_write(s, (byte *)BBox, strlen(BBox));
if (pdev->params.CompressPages || pdev->CompressEntireFile) {
/* When CompressEntireFile is true and ASCII85EncodePages is false,
@@ -1544,7 +1544,7 @@ void
pdf_reserve_object_id(gx_device_pdf * pdev, pdf_resource_t *pres, long id)
{
pres->object->id = (id == 0 ? pdf_obj_ref(pdev) : id);
- gs_sprintf(pres->rname, "R%ld", pres->object->id);
+ gs_snprintf(pres->rname, sizeof(pres->rname), "R%ld", pres->object->id);
}
/* Begin an aside (resource, annotation, ...). */
@@ -2006,7 +2006,7 @@ pdf_store_default_Producer(char buf[PDF_MAX_PRODUCER])
int minor = (int)(gs_revision - (major * 1000)) / 10;
int patch = gs_revision % 10;
- gs_sprintf(buf, "(%s %d.%02d.%d)", gs_product, major, minor, patch);
+ gs_snprintf(buf, PDF_MAX_PRODUCER, "(%s %d.%02d.%d)", gs_product, major, minor, patch);
}
/* Write matrix values. */
@@ -2053,7 +2053,7 @@ pdf_put_name_chars_1_2(stream *s, const byte *nstr, uint size)
case '[': case ']':
case '{': case '}':
case '/':
- gs_sprintf(hex, "#%02x", c);
+ gs_snprintf(hex, sizeof(hex), "#%02x", c);
stream_puts(s, hex);
break;
case 0:
diff --git a/devices/vector/gdevpdfv.c b/devices/vector/gdevpdfv.c
index 0159169c..8a44dcce 100644
--- a/devices/vector/gdevpdfv.c
+++ b/devices/vector/gdevpdfv.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
@@ -157,7 +157,7 @@ pdf_pattern(gx_device_pdf *pdev, const gx_drawing_color *pdc,
if (pcd_XObject == 0)
return_error(gs_error_VMerror);
- gs_sprintf(key, "/R%ld", pcs_image->id);
+ gs_snprintf(key, sizeof(key), "/R%ld", pcs_image->id);
/* This is non-obvious code. Previously we would put the image object (pcs_image)
* into the Resources dit. When we come to write out the Resources dict
* that code writes a reference (index 0 R) using the ID from the object.
@@ -203,7 +203,7 @@ pdf_pattern(gx_device_pdf *pdev, const gx_drawing_color *pdc,
{
char buf[MAX_REF_CHARS + 6 + 1]; /* +6 for /R# Do\n */
- gs_sprintf(buf, "/R%ld Do\n", pcs_image->id);
+ gs_snprintf(buf, sizeof(buf), "/R%ld Do\n", pcs_image->id);
cos_stream_add_bytes(pdev, pcos, (const byte *)buf, strlen(buf));
}
@@ -231,6 +231,14 @@ pdf_store_pattern1_params(gx_device_pdf *pdev, pdf_resource_t *pres,
bbox[1] = t->BBox.p.y;
bbox[2] = t->BBox.q.x;
bbox[3] = t->BBox.q.y;
+ if (pdev->accumulating_charproc) {
+ /* Assume here we can only be installing a pattern while acumulating a
+ * charproc if the font is a coloured type 3 font. In this case we will
+ * have set the CTM to be the identity scaled by 100 (!). See gdevpdtt.c
+ * install_PS_charproc_accumulator() for details.
+ */
+ gs_make_identity(&smat2);
+ }
/* The graphics library assumes a shifted origin to provide
positive bitmap pixel indices. Compensate it now. */
smat2.tx += pinst->step_matrix.tx;
@@ -242,7 +250,7 @@ pdf_store_pattern1_params(gx_device_pdf *pdev, pdf_resource_t *pres,
* form is nested inside a form, the default space is the space of the
* first form, and therefore we do *not* remove the resolution scaling.
*/
- if (pdev->FormDepth == 0 || (pdev->FormDepth > 0 && pdev->PatternsSinceForm > 0)) {
+ if ((pdev->FormDepth == 0 || (pdev->FormDepth > 0 && pdev->PatternsSinceForm > 0)) && !pdev->accumulating_charproc) {
gs_matrix scaled;
gs_make_scaling(1 / scale_x, 1 / scale_y, &scaled);
@@ -614,7 +622,7 @@ pdf_put_linear_shading(gx_device_pdf *pdev, cos_dict_t *pscd, const float *Coord
if (Extend[0] | Extend[1]) {
char extend_str[1 + 5 + 1 + 5 + 1 + 1]; /* [bool bool] */
- gs_sprintf(extend_str, "[%s %s]",
+ gs_snprintf(extend_str, sizeof(extend_str), "[%s %s]",
(Extend[0] ? "true" : "false"),
(Extend[1] ? "true" : "false"));
code = cos_dict_put_c_key_string(pscd, "/Extend",
diff --git a/devices/vector/gdevpdfx.h b/devices/vector/gdevpdfx.h
index d5dfd756..774a5156 100644
--- a/devices/vector/gdevpdfx.h
+++ b/devices/vector/gdevpdfx.h
@@ -856,6 +856,7 @@ struct gx_device_pdf_s {
Used only with uncached charprocs. */
bool PS_accumulator; /* A flag to determine whether a given
accumulator is for a PostScript type 3 font or not. */
+ bool Scaled_accumulator; /* We scale teh CTM when accumulating type 3 fonts */
bool accumulating_a_global_object; /* ps2write only.
Accumulating a global object (such as a named Form,
so that resources used in it must also be global.
diff --git a/devices/vector/gdevpdtb.c b/devices/vector/gdevpdtb.c
index 42ef43e4..5c8fb8d8 100644
--- a/devices/vector/gdevpdtb.c
+++ b/devices/vector/gdevpdtb.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
@@ -371,7 +371,7 @@ pdf_base_font_alloc(gx_device_pdf *pdev, pdf_base_font_t **ppbfont,
font_name.size -= SUBSET_PREFIX_SIZE;
}
} else {
- gs_sprintf(fnbuf, ".F" PRI_INTPTR, (intptr_t)copied);
+ gs_snprintf(fnbuf, sizeof(fnbuf), ".F" PRI_INTPTR, (intptr_t)copied);
font_name.data = (byte *)fnbuf;
font_name.size = strlen(fnbuf);
}
@@ -572,7 +572,7 @@ pdf_adjust_font_name(gx_device_pdf *pdev, long id, pdf_base_font_t *pbfont)
size = i + 1;
}
/* Create a unique name. */
- gs_sprintf(suffix, "%c%lx", SUFFIX_CHAR, id);
+ gs_snprintf(suffix, sizeof(suffix), "%c%lx", SUFFIX_CHAR, id);
suffix_size = strlen(suffix);
data = gs_resize_string(pdev->pdf_memory, chars, size,
size + suffix_size,
diff --git a/devices/vector/gdevpdtc.c b/devices/vector/gdevpdtc.c
index 81d66dd5..7ad7dec4 100644
--- a/devices/vector/gdevpdtc.c
+++ b/devices/vector/gdevpdtc.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
@@ -341,31 +341,52 @@ attach_cmap_resource(gx_device_pdf *pdev, pdf_font_resource_t *pdfont,
}
}
if (pcmres || is_identity) {
- uint size = pcmap->CMapName.size;
- byte *chars = gs_alloc_string(pdev->pdf_memory, size,
- "pdf_font_resource_t(CMapName)");
-
- if (chars == 0)
- return_error(gs_error_VMerror);
- memcpy(chars, pcmap->CMapName.data, size);
+ if (pdfont->u.type0.CMapName_data == NULL || pcmap->CMapName.size != pdfont->u.type0.CMapName_size ||
+ memcmp(pdfont->u.type0.CMapName_data, pcmap->CMapName.data, pcmap->CMapName.size))
+ {
+ byte *chars = gs_alloc_bytes(pdev->pdf_memory->non_gc_memory, pcmap->CMapName.size,
+ "pdf_font_resource_t(CMapName)");
+
+ if (chars == 0)
+ return_error(gs_error_VMerror);
+ memcpy(chars, pcmap->CMapName.data, pcmap->CMapName.size);
+ if (pdfont->u.type0.CMapName_data != NULL)
+ gs_free_object(pdev->pdf_memory->non_gc_memory, pdfont->u.type0.CMapName_data, "rewriting CMapName");
+ pdfont->u.type0.CMapName_data = chars;
+ pdfont->u.type0.CMapName_size = pcmap->CMapName.size;
+ }
if (is_identity)
strcpy(pdfont->u.type0.Encoding_name,
(pcmap->WMode ? "/Identity-V" : "/Identity-H"));
else
- gs_sprintf(pdfont->u.type0.Encoding_name, "%ld 0 R",
- pdf_resource_id(pcmres));
- pdfont->u.type0.CMapName.data = chars;
- pdfont->u.type0.CMapName.size = size;
+ gs_snprintf(pdfont->u.type0.Encoding_name, sizeof(pdfont->u.type0.Encoding_name),
+ "%ld 0 R", pdf_resource_id(pcmres));
} else {
+ uint size = 0;
+
if (!*pcmn)
/* Should not be possible, if *pcmn is NULL then either
* is_identity is true or we create pcmres.
*/
return_error(gs_error_invalidfont);
- gs_sprintf(pdfont->u.type0.Encoding_name, "/%s", *pcmn);
- pdfont->u.type0.CMapName.data = (const byte *)*pcmn;
- pdfont->u.type0.CMapName.size = strlen(*pcmn);
+ size = strlen(*pcmn);
+ if (pdfont->u.type0.CMapName_data == NULL || size != pdfont->u.type0.CMapName_size ||
+ memcmp(pdfont->u.type0.CMapName_data, *pcmn, size) != 0)
+ {
+ byte *chars = gs_alloc_bytes(pdev->pdf_memory->non_gc_memory, size, "pdf_font_resource_t(CMapName)");
+ if (chars == 0)
+ return_error(gs_error_VMerror);
+
+ memcpy(chars, *pcmn, size);
+
+ if (pdfont->u.type0.CMapName_data != NULL)
+ gs_free_object(pdev->pdf_memory->non_gc_memory, pdfont->u.type0.CMapName_data, "rewriting CMapName");
+ pdfont->u.type0.CMapName_data = chars;
+ pdfont->u.type0.CMapName_size = size;
+ }
+
+ gs_snprintf(pdfont->u.type0.Encoding_name, sizeof(pdfont->u.type0.Encoding_name), "/%s", *pcmn);
pdfont->u.type0.cmap_is_standard = true;
}
pdfont->u.type0.WMode = pcmap->WMode;
diff --git a/devices/vector/gdevpdte.c b/devices/vector/gdevpdte.c
index 592205fd..5e50d2cf 100644
--- a/devices/vector/gdevpdte.c
+++ b/devices/vector/gdevpdte.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
@@ -485,14 +485,14 @@ pdf_encode_string_element(gx_device_pdf *pdev, gs_font *font, pdf_font_resource_
: *gdata);
if (glyph == GS_NO_GLYPH || glyph == pet->glyph) {
if((pdfont->cmap_ToUnicode == NULL || !gs_cmap_ToUnicode_check_pair(pdfont->cmap_ToUnicode, ch)) && pdev->UseOCR != UseOCRNever)
- (void)pdf_add_ToUnicode(pdev, font, pdfont, glyph, ch, &gnstr);
+ (void)pdf_add_ToUnicode(pdev, font, pdfont, glyph, ch, NULL);
return 0;
}
if (pet->glyph != GS_NO_GLYPH) { /* encoding conflict */
return_error(gs_error_rangecheck);
/* Must not happen because pdf_obtain_font_resource
- * checks for encoding compatibility.
- */
+ * checks for encoding compatibility.
+ */
}
code = font->procs.glyph_name(font, glyph, &gnstr);
if (code < 0)
@@ -547,13 +547,13 @@ pdf_encode_string_element(gx_device_pdf *pdev, gs_font *font, pdf_font_resource_
/* PS font has no such glyph. */
if (bytes_compare(gnstr.data, gnstr.size, (const byte *)".notdef", 7)) {
pet->glyph = glyph;
- pet->str = gnstr;
+ pdf_copy_string_to_encoding(pdev, &gnstr, pet);
pet->is_difference = true;
}
} else if (pdfont->base_font == NULL && ccfont != NULL &&
(gs_copy_glyph_options(font, glyph, (gs_font *)ccfont, COPY_GLYPH_NO_NEW) != 1 ||
gs_copied_font_add_encoding((gs_font *)ccfont, ch, glyph) < 0)) {
- /*
+ /*
* The "complete" copy of the font appears incomplete
* due to incrementally added glyphs. Drop the "complete"
* copy now and continue with subset font only.
@@ -566,7 +566,7 @@ pdf_encode_string_element(gx_device_pdf *pdev, gs_font *font, pdf_font_resource_
* We also check whether the encoding is compatible.
* It must be compatible here due to the pdf_obtain_font_resource
* and ccfont logics, but we want to ensure for safety reason.
- */
+ */
ccfont = NULL;
pdf_font_descriptor_drop_complete_font(pdfont->FontDescriptor);
}
@@ -584,16 +584,15 @@ pdf_encode_string_element(gx_device_pdf *pdev, gs_font *font, pdf_font_resource_
pdfont->used[ch >> 3] |= 0x80 >> (ch & 7);
}
/*
- * We always generate ToUnicode for simple fonts, because
- * we can't detemine in advance, which glyphs the font actually uses.
- * The decision about writing it out is deferred until pdf_write_font_resource.
- */
+ * We always generate ToUnicode for simple fonts, because
+ * we can't detemine in advance, which glyphs the font actually uses.
+ * The decision about writing it out is deferred until pdf_write_font_resource.
+ */
code = pdf_add_ToUnicode(pdev, font, pdfont, glyph, ch, &gnstr);
if(code < 0)
return code;
pet->glyph = glyph;
- pet->str = gnstr;
- return 0;
+ return pdf_copy_string_to_encoding(pdev, &gnstr, pet);
}
/*
@@ -725,7 +724,10 @@ process_text_estimate_bbox(pdf_text_enum_t *pte, gs_font_base *font,
return code;
}
if (pte->text.operation & TEXT_REPLACE_WIDTHS) {
- gs_text_replaced_width(&pte->text, xy_index++, &tpt);
+ code = gs_text_replaced_width(&pte->text, xy_index++, &tpt);
+ if (code < 0)
+ return code;
+
gs_distance_transform(tpt.x, tpt.y, &ctm_only(pte->pgs), &wanted);
} else {
gs_distance_transform(info.width[WMode].x,
diff --git a/devices/vector/gdevpdtf.c b/devices/vector/gdevpdtf.c
index 0972e02d..0b714198 100644
--- a/devices/vector/gdevpdtf.c
+++ b/devices/vector/gdevpdtf.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
@@ -39,8 +39,6 @@
/* GC descriptors */
public_st_pdf_font_resource();
-private_st_pdf_encoding1();
-private_st_pdf_encoding_element();
private_st_pdf_standard_font();
private_st_pdf_standard_font_element();
private_st_pdf_outline_fonts();
@@ -66,9 +64,6 @@ case 7: switch (pdfont->FontType) {
ENUM_RETURN(pdfont->u.simple.Encoding);
}
case 8: switch (pdfont->FontType) {
- case ft_composite:
- return (pdfont->u.type0.cmap_is_standard ? ENUM_OBJ(0) :
- ENUM_CONST_STRING(&pdfont->u.type0.CMapName));
case ft_encrypted:
case ft_encrypted2:
case ft_TrueType:
@@ -82,6 +77,7 @@ case 8: switch (pdfont->FontType) {
case ft_CID_encrypted:
case ft_CID_TrueType:
ENUM_RETURN(pdfont->u.cidfont.v);
+ case ft_composite:
default:
ENUM_RETURN(0);
}
@@ -141,8 +137,6 @@ RELOC_PTRS_WITH(pdf_font_resource_reloc_ptrs, pdf_font_resource_t *pdfont)
RELOC_VAR(pdfont->cmap_ToUnicode);
switch (pdfont->FontType) {
case ft_composite:
- if (!pdfont->u.type0.cmap_is_standard)
- RELOC_CONST_STRING_VAR(pdfont->u.type0.CMapName);
RELOC_VAR(pdfont->u.type0.DescendantFont);
break;
case ft_PCL_user_defined:
@@ -456,6 +450,11 @@ int font_resource_free(gx_device_pdf *pdev, pdf_font_resource_t *pdfont)
}
switch(pdfont->FontType) {
case ft_composite:
+ if (pdfont->u.type0.CMapName_data != NULL) {
+ gs_free_object(pdev->memory->non_gc_memory, (byte *)pdfont->u.type0.CMapName_data, "font_resource_free(CMapName)");
+ pdfont->u.type0.CMapName_data = NULL;
+ pdfont->u.type0.CMapName_size = 0;
+ }
break;
case ft_PCL_user_defined:
case ft_MicroType:
@@ -464,6 +463,9 @@ int font_resource_free(gx_device_pdf *pdev, pdf_font_resource_t *pdfont)
case ft_PDF_user_defined:
case ft_GL2_531:
if(pdfont->u.simple.Encoding) {
+ int ix;
+ for (ix = 0; ix <= 255;ix++)
+ gs_free_object(pdev->pdf_memory->non_gc_memory, pdfont->u.simple.Encoding[ix].data, "Free copied glyph name string");
gs_free_object(pdev->pdf_memory, pdfont->u.simple.Encoding, "Free simple Encoding");
pdfont->u.simple.Encoding = 0;
}
@@ -486,6 +488,14 @@ int font_resource_free(gx_device_pdf *pdev, pdf_font_resource_t *pdfont)
break;
case ft_CID_encrypted:
case ft_CID_TrueType:
+ if(pdfont->u.cidfont.Widths2) {
+ gs_free_object(pdev->pdf_memory, pdfont->u.cidfont.Widths2, "Free CIDFont Widths2 array");
+ pdfont->u.cidfont.Widths2 = NULL;
+ }
+ if(pdfont->u.cidfont.v) {
+ gs_free_object(pdev->pdf_memory, pdfont->u.cidfont.v, "Free CIDFont v array");
+ pdfont->u.cidfont.v = NULL;
+ }
if(pdfont->u.cidfont.used2) {
gs_free_object(pdev->pdf_memory, pdfont->u.cidfont.used2, "Free CIDFont used2");
pdfont->u.cidfont.used2 = 0;
@@ -497,6 +507,9 @@ int font_resource_free(gx_device_pdf *pdev, pdf_font_resource_t *pdfont)
break;
default:
if(pdfont->u.simple.Encoding) {
+ int ix;
+ for (ix = 0; ix <= 255;ix++)
+ gs_free_object(pdev->pdf_memory->non_gc_memory, pdfont->u.simple.Encoding[ix].data, "Free copied glyph name string");
gs_free_object(pdev->pdf_memory, pdfont->u.simple.Encoding, "Free simple Encoding");
pdfont->u.simple.Encoding = 0;
}
@@ -593,10 +606,7 @@ font_resource_encoded_alloc(gx_device_pdf *pdev, pdf_font_resource_t **ppfres,
gs_id rid, font_type ftype,
pdf_font_write_contents_proc_t write_contents)
{
- pdf_encoding_element_t *Encoding =
- gs_alloc_struct_array(pdev->pdf_memory, 256, pdf_encoding_element_t,
- &st_pdf_encoding_element,
- "font_resource_encoded_alloc");
+ pdf_encoding_element_t *Encoding = (pdf_encoding_element_t *)gs_alloc_bytes(pdev->pdf_memory, 256 * sizeof(pdf_encoding_element_t), "font_resource_encoded_alloc");
gs_point *v = (gs_point *)gs_alloc_byte_array(pdev->pdf_memory,
256, sizeof(gs_point), "pdf_font_simple_alloc");
pdf_font_resource_t *pdfont;
@@ -953,6 +963,7 @@ pdf_compute_BaseFont(gx_device_pdf *pdev, pdf_font_resource_t *pdfont, bool fini
pdf_font_descriptor_embedding(pdfont->FontDescriptor)
) {
int code;
+ gs_font_base *pbfont = pdf_font_resource_font(pdfont, false);
if (pdfont->FontDescriptor)
code = pdf_add_subset_prefix(pdev, &fname, pdfont->used, pdfont->count, pdf_fontfile_hash(pdfont->FontDescriptor));
@@ -962,8 +973,12 @@ pdf_compute_BaseFont(gx_device_pdf *pdev, pdf_font_resource_t *pdfont, bool fini
if (code < 0)
return code;
pdfont->BaseFont = fname;
+
/* Don't write a UID for subset fonts. */
- uid_set_invalid(&pdf_font_resource_font(pdfont, false)->UID);
+ if (uid_is_XUID(&pbfont->UID)) {
+ uid_free(&pbfont->UID, pbfont->memory, "gs_font_finalize");
+ }
+ uid_set_invalid(&pbfont->UID);
}
if (pdfont->FontType != ft_composite && pdsubf->FontDescriptor)
*pdf_font_descriptor_name(pdsubf->FontDescriptor) = fname;
@@ -982,8 +997,17 @@ pdf_font_type0_alloc(gx_device_pdf *pdev, pdf_font_resource_t **ppfres,
ft_composite, 0, pdf_write_contents_type0);
if (code >= 0) {
+ byte *chars = NULL;
+
(*ppfres)->u.type0.DescendantFont = DescendantFont;
- (*ppfres)->u.type0.CMapName = *CMapName;
+
+ chars = gs_alloc_bytes(pdev->pdf_memory->non_gc_memory, CMapName->size, "pdf_font_resource_t(CMapName)");
+ if (chars == 0)
+ return_error(gs_error_VMerror);
+ memcpy(chars, CMapName->data, CMapName->size);
+ (*ppfres)->u.type0.CMapName_data = chars;
+ (*ppfres)->u.type0.CMapName_size = CMapName->size;
+
(*ppfres)->u.type0.font_index = 0;
code = pdf_compute_BaseFont(pdev, *ppfres, false);
}
@@ -1206,7 +1230,8 @@ pdf_convert_truetype_font(gx_device_pdf *pdev, pdf_resource_t *pres)
if (code < 0)
return 0;
pdfont->u.cidfont.CIDSystemInfo_id = pdev->IdentityCIDSystemInfo_id;
- gs_sprintf(pdfont0->u.type0.Encoding_name, "%ld 0 R", pdf_resource_id(pdev->OneByteIdentityH));
+ gs_snprintf(pdfont0->u.type0.Encoding_name, sizeof(pdfont0->u.type0.Encoding_name),
+ "%ld 0 R", pdf_resource_id(pdev->OneByteIdentityH));
/* Move ToUnicode : */
pdfont0->res_ToUnicode = pdfont->res_ToUnicode; pdfont->res_ToUnicode = 0;
pdfont0->cmap_ToUnicode = pdfont->cmap_ToUnicode; pdfont->cmap_ToUnicode = 0;
diff --git a/devices/vector/gdevpdtf.h b/devices/vector/gdevpdtf.h
index f13c0eac..5a1a57dd 100644
--- a/devices/vector/gdevpdtf.h
+++ b/devices/vector/gdevpdtf.h
@@ -117,13 +117,30 @@ typedef int (*pdf_font_write_contents_proc_t)
*/
typedef struct pdf_encoding_element_s {
gs_glyph glyph;
- gs_const_string str;
+ byte *data;
+ uint size;
bool is_difference; /* true if must be written in Differences */
} pdf_encoding_element_t;
+
+static inline int pdf_copy_string_to_encoding(gx_device_pdf *pdev, gs_const_string *gnstr, pdf_encoding_element_t *pet)
+{
+ byte *p = NULL;
+
+ p = gs_alloc_bytes(pdev->pdf_memory->non_gc_memory, gnstr->size, "pdf_copy_string_to_encoding");
+ if (p == NULL)
+ return_error(gs_error_VMerror);
+ memcpy(p, gnstr->data, gnstr->size);
+ if (pet->data != NULL)
+ gs_free_object(pdev->pdf_memory->non_gc_memory, pet->data, "pdf_copy_string_to_encoding free existing glyph name");
+ pet->data = p;
+ pet->size = gnstr->size;
+ return 0;
+}
+
#define private_st_pdf_encoding1() /* gdevpdtf.c */\
gs_private_st_const_strings1(st_pdf_encoding1,\
pdf_encoding_element_t, "pdf_encoding_element_t",\
- pdf_encoding1_enum_ptrs, pdf_encoding1_reloc_ptrs, str)
+ pdf_encoding1_enum_ptrs, pdf_encoding1_reloc_ptrs, bah)
#define private_st_pdf_encoding_element() /* gdevpdtf.c */\
gs_private_st_element(st_pdf_encoding_element, pdf_encoding_element_t,\
"pdf_encoding_element_t[]", pdf_encoding_elt_enum_ptrs,\
@@ -227,8 +244,8 @@ struct pdf_font_resource_s {
sizeof(long) * 8 / 3 + 1 + 4 /* <id> 0 R */
) + 1 /* \0 terminator */
];
- gs_const_string CMapName; /* copied from the original CMap, */
- /* or references the table of standard names */
+ byte *CMapName_data;
+ uint CMapName_size;
uint font_index; /* The index of the descendent font in the source CMap. */
bool cmap_is_standard;
int WMode; /* of CMap */
diff --git a/devices/vector/gdevpdti.c b/devices/vector/gdevpdti.c
index d1b39e99..45a56082 100644
--- a/devices/vector/gdevpdti.c
+++ b/devices/vector/gdevpdti.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
@@ -292,10 +292,11 @@ pdf_attach_charproc(gx_device_pdf * pdev, pdf_font_resource_t *pdfont, pdf_char_
pcpo->char_name.data = 0;
pcpo->char_name.size = 0;
} else {
- pcpo->char_name.data = gs_alloc_bytes(pdev->pdf_memory->non_gc_memory, gnstr->size, "storage for charproc name");
- memcpy(pcpo->char_name.data, gnstr->data, gnstr->size);
+ if (gnstr->size > 0) {
+ pcpo->char_name.data = gs_alloc_bytes(pdev->pdf_memory->non_gc_memory, gnstr->size, "storage for charproc name");
+ memcpy(pcpo->char_name.data, gnstr->data, gnstr->size);
+ }
pcpo->char_name.size = gnstr->size;
-// pcpo->char_name = *gnstr;
}
pcpo->duplicate_char_name = duplicate_char_name;
return 0;
@@ -335,7 +336,7 @@ pdf_begin_char_proc(gx_device_pdf * pdev, int w, int h, int x_width,
int code;
/* This code added to store PCL bitmap glyphs in type 3 fonts where possible */
gs_glyph glyph = GS_NO_GLYPH;
- gs_const_string *str = NULL;
+ gs_const_string str2, *str = NULL;
gs_show_enum *show_enum = (gs_show_enum *)pdev->pte;
pdf_encoding_element_t *pet = 0;
/* Since this is for text searching, its only useful if the character code
@@ -406,15 +407,17 @@ pdf_begin_char_proc(gx_device_pdf * pdev, int w, int h, int x_width,
* then we need to give up, something about the font or text is not acceptable
* (see various comments above).
*/
- if (pet && pet->glyph != GS_NO_GLYPH && !(pet->str.size == 7 &&
- !strncmp((const char *)pet->str.data, ".notdef", 7))) {
+ if (pet && pet->glyph != GS_NO_GLYPH && !(pet->size == 7 &&
+ !strncmp((const char *)pet->data, ".notdef", 7))) {
if (char_code < font->u.simple.FirstChar)
font->u.simple.FirstChar = char_code;
if ((int)char_code > font->u.simple.LastChar)
font->u.simple.LastChar = char_code;
base->FontBBox.q.x = max(base->FontBBox.q.x, w);
base->FontBBox.q.y = max(base->FontBBox.q.y, y_offset + h);
- str = &pet->str;
+ str2.data = pet->data;
+ str2.size = pet->size;
+ str = &str2;
glyph = pet->glyph;
/* This is to work around a weird Acrobat bug. If the Encoding of a type 3
* (possibly other types) is simply a standard encoding (eg WinAnsiEncoding)
@@ -1065,13 +1068,12 @@ complete_adding_char(gx_device_pdf *pdev, gs_font *font,
pdfont->u.simple.v[ch].y = pcp->v.x;
}
pet->glyph = glyph;
- pet->str = *gnstr;
pet->is_difference = true;
if (pdfont->u.simple.LastChar < (int)ch)
pdfont->u.simple.LastChar = (int)ch;
if (pdfont->u.simple.FirstChar > (int)ch)
pdfont->u.simple.FirstChar = (int)ch;
- return 0;
+ return pdf_copy_string_to_encoding(pdev, (gs_const_string *)gnstr, pet);
}
static int
@@ -1212,7 +1214,7 @@ pdf_add_resource(gx_device_pdf *pdev, cos_dict_t *pcd, const char *key, pdf_reso
if (code < 0)
return code;
}
- gs_sprintf(buf, "%ld 0 R\n", pres->object->id);
+ gs_snprintf(buf, sizeof(buf), "%ld 0 R\n", pres->object->id);
if (v != NULL) {
if (v->value_type != COS_VALUE_OBJECT &&
v->value_type != COS_VALUE_RESOURCE)
diff --git a/devices/vector/gdevpdtt.c b/devices/vector/gdevpdtt.c
index 3091a18d..98ce8892 100644
--- a/devices/vector/gdevpdtt.c
+++ b/devices/vector/gdevpdtt.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
@@ -114,7 +114,7 @@ pdf_text_set_cache(gs_text_enum_t *pte, const double *pw,
* NOT the identity, but we want the cache device values to be in
* font co-ordinate space, so we need to undo that scale here.
*/
- if (pdev->PS_accumulator){
+ if (pdev->PS_accumulator || pdev->Scaled_accumulator){
gs_matrix_scale(&ctm_only(pte->pgs), .01, .01, &m);
gs_distance_transform(pw[0], pw[1], &m, &pdev->char_width);
} else {
@@ -133,7 +133,7 @@ pdf_text_set_cache(gs_text_enum_t *pte, const double *pw,
* NOT the identity, but we want the cache device values to be in
* font co-ordinate space, so we need to undo that scale here.
*/
- if (pdev->PS_accumulator){
+ if (pdev->PS_accumulator || pdev->Scaled_accumulator){
gs_matrix_scale(&ctm_only(pte->pgs), .01, .01, &m);
gs_distance_transform(pw[0], pw[1], &m, &pdev->char_width);
} else {
@@ -214,7 +214,7 @@ pdf_text_set_cache(gs_text_enum_t *pte, const double *pw,
* needs to be in the 100x100 space so that it doesn't clip
* out marking operations.
*/
- if (pdev->PS_accumulator)
+ if (pdev->PS_accumulator || pdev->Scaled_accumulator)
gs_matrix_scale(&ctm_only(penum_s->pgs), .01, .01, &m);
else
m = ctm_only(penum_s->pgs);
@@ -225,7 +225,7 @@ pdf_text_set_cache(gs_text_enum_t *pte, const double *pw,
pw1[i] = p.x;
pw1[i + 1] = p.y;
}
- if (!pdev->PS_accumulator)
+ if (!pdev->PS_accumulator && !pdev->Scaled_accumulator)
code = pdf_set_charproc_attrs(pdev, pte->current_font,
pw1, narg, control, penum->returned.current_char, false);
else
@@ -1114,11 +1114,10 @@ pdf_is_compatible_encoding(gx_device_pdf *pdev, pdf_font_resource_t *pdfont,
if (pfont->data.FMapType == fmap_CMap) {
const gs_cmap_t *pcmap = pfont->data.CMap;
- const gs_const_string *s0 = &pdfont->u.type0.CMapName;
const gs_const_string *s1 = &pcmap->CMapName;
- return (s0->size == s1->size &&
- !memcmp(s0->data, s1->data, s0->size));
+ return (pdfont->u.type0.CMapName_size == s1->size &&
+ !memcmp(pdfont->u.type0.CMapName_data, s1->data, pdfont->u.type0.CMapName_size));
}
}
return false;
@@ -1283,9 +1282,9 @@ pdf_find_type0_font_resource(gx_device_pdf *pdev, const pdf_font_resource_t *pds
*/
if (pdfont->BaseFont.size != pdsubf->BaseFont.size)
continue;
- if (pdfont->u.type0.CMapName.size != CMapName->size)
+ if (pdfont->u.type0.CMapName_size != CMapName->size)
continue;
- if (memcmp(pdfont->u.type0.CMapName.data, CMapName->data, CMapName->size))
+ if (memcmp(pdfont->u.type0.CMapName_data, CMapName->data, CMapName->size))
continue;
}
@@ -2290,9 +2289,16 @@ int
pdf_obtain_parent_type0_font_resource(gx_device_pdf *pdev, pdf_font_resource_t *pdsubf,
uint font_index, const gs_const_string *CMapName, pdf_font_resource_t **pdfont)
{
+ gs_const_string s1;
+
+ if (pdsubf->u.cidfont.parent != 0) {
+ s1.data = pdsubf->u.cidfont.parent->u.type0.CMapName_data;
+ s1.size = pdsubf->u.cidfont.parent->u.type0.CMapName_size;
+ }
+
if (pdsubf->u.cidfont.parent != 0 &&
font_index == pdsubf->u.cidfont.parent->u.type0.font_index &&
- strings_equal(CMapName, &pdsubf->u.cidfont.parent->u.type0.CMapName))
+ strings_equal(CMapName, &s1))
*pdfont = pdsubf->u.cidfont.parent;
else {
/*
@@ -2868,7 +2874,7 @@ pdf_choose_output_char_code(gx_device_pdf *pdev, pdf_text_enum_t *penum, gs_char
}
static int
-pdf_choose_output_glyph_name(gx_device_pdf *pdev, pdf_text_enum_t *penum, gs_const_string *gnstr, gs_glyph glyph)
+pdf_choose_output_glyph_name(gx_device_pdf *pdev, pdf_text_enum_t *penum, gs_const_string *gnstr, gs_glyph glyph, bool *cleanup)
{
if (penum->orig_font->FontType == ft_composite || penum->orig_font->procs.glyph_name(penum->orig_font, glyph, gnstr) < 0
|| (penum->orig_font->FontType > 42 && gnstr->size == 7 && strcmp((const char *)gnstr->data, ".notdef")== 0)) {
@@ -2887,9 +2893,10 @@ pdf_choose_output_glyph_name(gx_device_pdf *pdev, pdf_text_enum_t *penum, gs_con
p = (byte *)gs_alloc_string(pdev->pdf_memory, gnstr->size, "pdf_text_set_cache");
if (p == NULL)
return_error(gs_error_VMerror);
- gs_sprintf(buf, "g%04x", (unsigned int)(glyph & 0xFFFF));
+ gs_snprintf(buf, sizeof(buf), "g%04x", (unsigned int)(glyph & 0xFFFF));
memcpy(p, buf, 5);
gnstr->data = p;
+ *cleanup = true;
}
return 0;
}
@@ -3041,6 +3048,12 @@ static int install_charproc_accumulator(gx_device_pdf *pdev, gs_text_enum_t *pte
executed gsave, so we are safe to change CTM now.
Note that BuildChar may change CTM before calling setcachedevice. */
gs_make_identity(&m);
+ if (penum->current_font->FontType == ft_PDF_user_defined) {
+ pdev->width *= 100;
+ pdev->height *= 100;
+ gs_matrix_scale(&m, 100, 100, &m);
+ pdev->Scaled_accumulator = 1;
+ }
gs_matrix_fixed_from_matrix(&penum->pgs->ctm, &m);
/* Choose a character code to use with the charproc. */
@@ -3074,10 +3087,11 @@ static int complete_charproc(gx_device_pdf *pdev, gs_text_enum_t *pte,
{
gs_const_string gnstr;
int code;
+ bool cleanup = false;
if (pte_default->returned.current_glyph == GS_NO_GLYPH)
return_error(gs_error_undefined);
- code = pdf_choose_output_glyph_name(pdev, penum, &gnstr, pte_default->returned.current_glyph);
+ code = pdf_choose_output_glyph_name(pdev, penum, &gnstr, pte_default->returned.current_glyph, &cleanup);
if (code < 0) {
return code;
}
@@ -3109,26 +3123,30 @@ static int complete_charproc(gx_device_pdf *pdev, gs_text_enum_t *pte,
stream_puts(pdev->strm, "0 0 0 0 0 0 d1\n");
}
- if (was_PS_type3) {
+ if (was_PS_type3 || pdev->Scaled_accumulator) {
/* See below, we scaled the device height and width to prevent
* clipping of the CharProc operations, now we need to undo that.
*/
pdev->width /= 100;
pdev->height /= 100;
+ pdev->Scaled_accumulator = 0;
}
code = pdf_end_charproc_accum(pdev, penum->current_font, penum->cgp,
pte_default->returned.current_glyph, penum->output_char_code, &gnstr);
if (code < 0)
- return code;
+ goto exit;
pdev->accumulating_charproc = false;
penum->charproc_accum = false;
code = gx_default_text_restore_state(pte_default);
if (code < 0)
- return code;
+ goto exit;
gs_text_release(NULL, pte_default, "pdf_text_process");
penum->pte_default = 0;
- return 0;
+exit:
+ if (cleanup)
+ gs_free_string(pdev->pdf_memory, (byte *)gnstr.data, gnstr.size, "pdf_text_set_cache free working name");
+ return code;
}
/* Nasty hackery. The PCL 'stick font' is drawn by constructing a path, and then stroking it.
@@ -3449,7 +3467,8 @@ pdf_text_process(gs_text_enum_t *pte)
/* We need a special 'initial matrix' method for stick fonts,
* See pdf_type3_get_initial_matrix above.
*/
- pdev->procs.get_initial_matrix = pdf_type3_get_initial_matrix;
+ if (penum->current_font->FontType != ft_PDF_user_defined)
+ pdev->procs.get_initial_matrix = pdf_type3_get_initial_matrix;
pdev->pte = (gs_text_enum_t *)penum; /* CAUTION: See comment in gdevpdfx.h . */
/* In case of error, text_process will restore back to the enumerator 'level'
@@ -3524,7 +3543,7 @@ pdf_text_process(gs_text_enum_t *pte)
/* end of code copied from show_cache_setup */
/* This copied from set_cache */
- code = gx_alloc_char_bits(pte->current_font->dir, dev, NULL,
+ code = gx_alloc_char_bits(pte->current_font->dir, dev,
0, 0, &log2_scale, 1, &cc);
if (code < 0)
return code;
diff --git a/devices/vector/gdevpdtv.c b/devices/vector/gdevpdtv.c
index 47b9d798..a9df5e82 100644
--- a/devices/vector/gdevpdtv.c
+++ b/devices/vector/gdevpdtv.c
@@ -12,7 +12,6 @@
Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato,
CA 94945, U.S.A., +1(415)492-9861, for further information.
*/
-
/*
* This file contains substantial parts of toolbin/encs2c.ps,
* which generated the remainder of the file mechanically from
@@ -23,6 +22,9 @@
* This source file is maintained manually under source code control,
* however its content should be regenerated by using encs2c.ps
* if changes are required.
+ * You should not manually alter this file! If you regenerate it using
+ * encs2c.ps you must regenerate all 4 files; base/gscedata.[c|h]
+ * and devices/vector/gdevpdtv.[c|h]
*/
#include "gdevpdtv.h"
@@ -65,7 +67,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
28,
-3,
+0,
0,
0,
0,
@@ -89,7 +91,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
12,
-192,
+0,
0,
0,
0,
@@ -97,7 +99,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
60,
-1,
+0,
3,
0,
0,
@@ -129,7 +131,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
92,
-49,
+51,
0,
0,
0,
@@ -153,7 +155,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
76,
-4,
+0,
0,
192,
0,
@@ -161,7 +163,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
12,
-0,
+1,
1,
0,
3,
@@ -193,7 +195,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
12,
-4,
+5,
48,
0,
0,
@@ -313,7 +315,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
12,
-4,
+192,
0,
0,
0,
@@ -354,7 +356,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
60,
4,
-1,
+0,
0,
0,
0,
@@ -369,7 +371,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
60,
-64,
+0,
0,
48,
0,
@@ -393,7 +395,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
12,
-12,
+0,
12,
0,
0,
@@ -418,7 +420,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
28,
48,
-3,
+1,
0,
3,
0,
@@ -433,7 +435,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
28,
-0,
+4,
48,
0,
0,
@@ -473,7 +475,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-12,
+4,
192,
0,
0,
@@ -513,7 +515,8 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-4,
+12,
+0,
0,
0,
0,
@@ -537,7 +540,6 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-192,
12,
0,
0,
@@ -553,7 +555,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-4,
+0,
0,
4,
0,
@@ -593,7 +595,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-4,
+76,
48,
48,
0,
@@ -633,7 +635,8 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-12,
+4,
+0,
0,
0,
0,
@@ -649,7 +652,6 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-64,
192,
0,
0,
@@ -673,7 +675,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-12,
+4,
51,
0,
0,
@@ -713,7 +715,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-12,
+4,
0,
0,
0,
@@ -761,7 +763,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-0,
+192,
0,
4,
0,
@@ -802,7 +804,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
48,
-1,
+3,
1,
0,
0,
@@ -817,7 +819,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-64,
+0,
0,
48,
0,
@@ -833,7 +835,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-4,
+12,
16,
0,
0,
@@ -866,14 +868,14 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-3,
+1,
4,
0,
0,
0,
0,
0,
-12,
+76,
0,
0,
0,
@@ -930,7 +932,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-1,
+3,
16,
0,
0,
@@ -953,7 +955,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-0,
+4,
0,
0,
0,
@@ -985,7 +987,6 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-64,
0,
0,
0,
@@ -993,7 +994,8 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-52,
+0,
+60,
17,
1,
0,
@@ -1041,7 +1043,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-112,
+48,
12,
16,
0,
@@ -1073,7 +1075,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-4,
+0,
48,
12,
0,
@@ -1097,7 +1099,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-192,
+64,
0,
0,
0,
@@ -1122,7 +1124,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-3,
+1,
0,
0,
0,
@@ -1153,7 +1155,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-68,
+12,
48,
16,
0,
@@ -1186,7 +1188,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
48,
-13,
+15,
1,
0,
0,
@@ -1233,7 +1235,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-12,
+4,
16,
0,
0,
@@ -1250,7 +1252,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-3,
+1,
0,
0,
0,
@@ -1313,7 +1315,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-12,
+4,
51,
0,
0,
@@ -1377,7 +1379,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-48,
+240,
3,
17,
0,
@@ -1433,7 +1435,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-4,
+76,
0,
0,
0,
@@ -1442,7 +1444,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-192,
+195,
0,
0,
0,
@@ -1473,7 +1475,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-60,
+12,
60,
1,
0,
@@ -1489,7 +1491,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-64,
+0,
0,
28,
0,
@@ -1506,15 +1508,14 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-3,
0,
0,
0,
0,
0,
0,
-12,
0,
+4,
0,
0,
0,
@@ -1522,6 +1523,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
+48,
0,
0,
0,
@@ -1545,7 +1547,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-192,
+64,
12,
0,
0,
@@ -1553,7 +1555,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-12,
+4,
48,
0,
0,
@@ -1570,7 +1572,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-1,
+3,
3,
0,
0,
@@ -1593,15 +1595,15 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-4,
-0,
12,
0,
+12,
0,
0,
0,
0,
0,
+64,
0,
48,
0,
@@ -1617,9 +1619,8 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-48,
-204,
0,
+204,
0,
0,
0,
@@ -1634,7 +1635,8 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-48,
+12,
+49,
0,
0,
0,
@@ -1673,7 +1675,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-0,
+12,
0,
0,
0,
@@ -1713,7 +1715,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-112,
+52,
16,
48,
0,
@@ -1769,7 +1771,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-0,
+64,
0,
0,
0,
@@ -1825,7 +1827,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-0,
+192,
0,
48,
0,
@@ -1881,7 +1883,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-64,
+0,
192,
0,
0,
@@ -1937,7 +1939,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-192,
+0,
0,
48,
0,
@@ -1993,7 +1995,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-192,
+64,
0,
0,
0,
@@ -2049,7 +2051,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-64,
+48,
12,
51,
0,
@@ -2105,7 +2107,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-64,
+0,
0,
0,
0,
@@ -2145,7 +2147,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
192,
-48,
+0,
192,
3,
0,
@@ -2161,7 +2163,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-192,
+64,
0,
48,
0,
@@ -2193,7 +2195,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
192,
-0,
+48,
52,
0,
0,
@@ -2217,7 +2219,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-64,
+192,
0,
12,
0,
@@ -2241,7 +2243,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
192,
-48,
+0,
0,
3,
0,
@@ -2273,7 +2275,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-0,
+192,
48,
48,
0,
@@ -2329,7 +2331,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-0,
+64,
0,
0,
0,
@@ -2337,7 +2339,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
192,
-0,
+48,
12,
3,
0,
@@ -2385,7 +2387,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
192,
-112,
+64,
0,
48,
0,
@@ -2441,7 +2443,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-0,
+192,
0,
0,
0,
@@ -2497,7 +2499,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-0,
+64,
192,
48,
0,
@@ -2665,7 +2667,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-0,
+64,
0,
0,
0,
@@ -2817,7 +2819,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-0,
+48,
0,
1,
0,
@@ -2865,7 +2867,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-48,
+0,
0,
0,
0,
@@ -3009,7 +3011,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-0,
+48,
0,
0,
0,
@@ -3057,7 +3059,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-48,
+0,
12,
16,
0,
@@ -3201,7 +3203,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-0,
+48,
68,
3,
0,
@@ -3297,10 +3299,9 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-48,
0,
-3,
0,
+3,
0,
0,
0,
@@ -3346,6 +3347,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
+48,
12,
0,
0,
@@ -3393,7 +3395,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-1,
+0,
0,
3,
0,
@@ -3425,7 +3427,6 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-3,
0,
0,
0,
@@ -3441,7 +3442,8 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-48,
+0,
+0,
0,
0,
0,
@@ -3521,7 +3523,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-3,
+1,
0,
0,
0,
@@ -3553,7 +3555,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-1,
+3,
192,
0,
0,
@@ -3617,8 +3619,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-3,
-0,
+1,
0,
0,
0,
@@ -3634,6 +3635,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
+48,
12,
0,
0,
@@ -3649,7 +3651,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-1,
+3,
0,
0,
0,
@@ -3681,7 +3683,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-51,
+3,
0,
1,
0,
@@ -3713,7 +3715,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-3,
+1,
0,
0,
0,
@@ -3777,7 +3779,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-49,
+51,
12,
1,
0,
@@ -3809,7 +3811,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-0,
+3,
0,
0,
0,
@@ -3841,7 +3843,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-0,
+1,
0,
0,
0,
@@ -3921,7 +3923,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-0,
+48,
4,
0,
0,
@@ -3969,7 +3971,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-48,
+0,
0,
1,
0,
@@ -4113,6 +4115,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
+48,
0,
0,
0,
@@ -4161,7 +4164,6 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-16,
0,
3,
0,
@@ -4209,6 +4211,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
+16,
0,
0,
0,
@@ -4257,7 +4260,6 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-48,
192,
3,
0,
@@ -4353,8 +4355,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-16,
-0,
+48,
0,
0,
0,
@@ -4402,6 +4403,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
+16,
0,
0,
0,
@@ -4497,7 +4499,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-48,
+0,
0,
0,
0,
@@ -4689,7 +4691,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-16,
+48,
0,
0,
0,
@@ -4737,7 +4739,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-48,
+16,
0,
3,
0,
@@ -4881,7 +4883,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-0,
+48,
0,
0,
0,
@@ -4977,7 +4979,6 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-48,
0,
0,
0,
@@ -5026,6 +5027,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
+48,
0,
3,
0,
@@ -5073,7 +5075,6 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-48,
0,
0,
0,
@@ -5121,7 +5122,8 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-16,
+0,
+48,
0,
3,
0,
@@ -5217,7 +5219,7 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
-0,
+16,
0,
3,
0,
@@ -5265,6 +5267,54 @@ const unsigned char gs_c_pdf_glyph_type[] = {
0,
0,
0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
16,
0,
0,
diff --git a/devices/vector/gdevpdtv.h b/devices/vector/gdevpdtv.h
index 54db170c..0cccd412 100644
--- a/devices/vector/gdevpdtv.h
+++ b/devices/vector/gdevpdtv.h
@@ -12,7 +12,6 @@
Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato,
CA 94945, U.S.A., +1(415)492-9861, for further information.
*/
-
/*
* This file contains substantial parts of toolbin/encs2c.ps,
* which generated the remainder of the file mechanically from
@@ -23,12 +22,15 @@
* This source file is maintained manually under source code control,
* however its content should be regenerated by using encs2c.ps
* if changes are required.
+ * You should not manually alter this file! If you regenerate it using
+ * encs2c.ps you must regenerate all 4 files; base/gscedata.[c|h]
+ * and devices/vector/gdevpdtv.[c|h]
*/
#ifndef gdevpdtv_INCLUDED
#define gdevpdtv_INCLUDED
-#define GS_C_PDF_MAX_GOOD_GLYPH 21894
+#define GS_C_PDF_MAX_GOOD_GLYPH 22086
#define GS_C_PDF_GOOD_GLYPH_MASK 1
#define GS_C_PDF_GOOD_NON_SYMBOL_MASK 2
diff --git a/devices/vector/gdevpdtw.c b/devices/vector/gdevpdtw.c
index 0647db66..907c7f0c 100644
--- a/devices/vector/gdevpdtw.c
+++ b/devices/vector/gdevpdtw.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
@@ -78,9 +78,13 @@ pdf_different_encoding_element(const pdf_font_resource_t *pdfont, int ch, int en
if (code < 0)
return code; /* Must not happen */
- if (glyph1 != GS_NO_GLYPH)
- if (!strings_equal(&str, &pdfont->u.simple.Encoding[ch].str))
+ if (glyph1 != GS_NO_GLYPH) {
+ gs_const_string str2;
+ str2.data = pdfont->u.simple.Encoding[ch].data;
+ str2.size = pdfont->u.simple.Encoding[ch].size;
+ if (!strings_equal(&str, &str2))
return 1;
+ }
}
return 0;
}
@@ -120,7 +124,7 @@ pdf_simple_font_needs_ToUnicode(const pdf_font_resource_t *pdfont)
*/
return true;
if (!pdfont->TwoByteToUnicode)
- return true;
+ return false;
for (ch = 0; ch < 256; ++ch) {
pdf_encoding_element_t *pet = &pdfont->u.simple.Encoding[ch];
@@ -129,9 +133,9 @@ pdf_simple_font_needs_ToUnicode(const pdf_font_resource_t *pdfont)
if (glyph == GS_NO_GLYPH)
continue;
if (glyph < gs_c_min_std_encoding_glyph || glyph >= GS_MIN_CID_GLYPH) {
- if (pet->str.size == 0)
+ if (pet->size == 0)
return true;
- glyph = gs_c_name_glyph(pet->str.data, pet->str.size);
+ glyph = gs_c_name_glyph(pet->data, pet->size);
if (glyph == GS_NO_GLYPH)
return true;
}
@@ -176,12 +180,12 @@ pdf_write_encoding(gx_device_pdf *pdev, const pdf_font_resource_t *pdfont, long
* Enforce writing differences against that.
*/
if (pdfont->used[ch >> 3] & 0x80 >> (ch & 7))
- if (pdfont->u.simple.Encoding[ch].str.size)
+ if (pdfont->u.simple.Encoding[ch].size)
code = 1;
}
if (code) {
- const byte *d = pdfont->u.simple.Encoding[ch].str.data;
- int i, l = pdfont->u.simple.Encoding[ch].str.size;
+ const byte *d = pdfont->u.simple.Encoding[ch].data;
+ int i, l = pdfont->u.simple.Encoding[ch].size;
if (pdev->HavePDFWidths) {
for (i = 0; i + sl < l; i++)
@@ -881,7 +885,7 @@ pdf_write_OneByteIdentityH(gx_device_pdf *pdev)
code = cos_dict_put_string_copy(pcd, "/CMapName", "/OneByteIdentityH");
if (code < 0)
return code;
- gs_sprintf(buf, "%ld 0 R", pdev->IdentityCIDSystemInfo_id);
+ gs_snprintf(buf, sizeof(buf), "%ld 0 R", pdev->IdentityCIDSystemInfo_id);
code = cos_dict_put_string_copy(pcd, "/CIDSystemInfo", buf);
if (code < 0)
return code;
diff --git a/devices/vector/gdevpsf1.c b/devices/vector/gdevpsf1.c
index 672ce241..c045c714 100644
--- a/devices/vector/gdevpsf1.c
+++ b/devices/vector/gdevpsf1.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
@@ -663,12 +663,12 @@ write_Private(stream *s, gs_font_type1 *pfont,
gs_free_object(pfont->memory, SubrsWithMM, "free Subrs record");
return code;
}
- gs_sprintf(buf, "dup %d %u -| ", i, code);
+ gs_snprintf(buf, sizeof(buf), "dup %d %u -| ", i, code);
stream_puts(s, buf);
write_CharString(s, stripped, code);
gs_free_object(pfont->memory, stripped, "free Subrs copy for OtherSubrs");
} else {
- gs_sprintf(buf, "dup %d %u -| ", i, gdata.bits.size);
+ gs_snprintf(buf, sizeof(buf), "dup %d %u -| ", i, gdata.bits.size);
stream_puts(s, buf);
write_CharString(s, gdata.bits.data, gdata.bits.size);
}
diff --git a/devices/vector/gdevpsf2.c b/devices/vector/gdevpsf2.c
index 4c56c450..a6db8b5b 100644
--- a/devices/vector/gdevpsf2.c
+++ b/devices/vector/gdevpsf2.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
@@ -274,7 +274,7 @@ cff_put_real(cff_writer_t *pcw, double f)
byte b = 0xff;
const char *p;
- gs_sprintf(str, "%g", f);
+ gs_snprintf(str, sizeof(str), "%g", f);
sputc(pcw->strm, CD_REAL);
for (p = str; ; ++p) {
int digit;
@@ -1213,17 +1213,21 @@ psf_write_type2_font(stream *s, gs_font_type1 *pfont, int options,
std_string_items = (cff_string_item_t *)gs_alloc_bytes(pfont->memory,
(MAX_CFF_STD_STRINGS + number_of_strings) * sizeof(cff_string_item_t),
"psf_write_type2_font");
- if (std_string_items == NULL || subset.glyphs.subset_data == NULL)
- return_error(gs_error_VMerror);
+ if (std_string_items == NULL || subset.glyphs.subset_data == NULL) {
+ code = gs_note_error(gs_error_VMerror);
+ goto error;
+ }
string_items = std_string_items + MAX_CFF_STD_STRINGS;
/* Get subset glyphs. */
code = psf_get_type1_glyphs(&subset.glyphs, pfont, subset_glyphs,
subset_size);
if (code < 0)
- return code;
- if (subset.glyphs.notdef == GS_NO_GLYPH)
- return_error(gs_error_rangecheck); /* notdef is required */
+ goto error;
+ if (subset.glyphs.notdef == GS_NO_GLYPH) {
+ code = gs_note_error(gs_error_rangecheck); /* notdef is required */
+ goto error;
+ }
/* If we're writing Type 2 CharStrings, don't encrypt them. */
if (options & WRITE_TYPE2_CHARSTRINGS) {
@@ -1274,8 +1278,10 @@ psf_write_type2_font(stream *s, gs_font_type1 *pfont, int options,
psf_enumerate_glyphs_reset(&genum);
while ((code = psf_enumerate_glyphs_next(&genum, &glyph)) != 1)
if (code == 0) {
- if (num_glyphs == number_of_glyphs)
- return_error(gs_error_limitcheck);
+ if (num_glyphs == number_of_glyphs){
+ code = gs_note_error(gs_error_limitcheck);
+ goto error;
+ }
subset.glyphs.subset_data[num_glyphs++] = glyph;
}
subset.glyphs.subset_size =
@@ -1347,7 +1353,7 @@ psf_write_type2_font(stream *s, gs_font_type1 *pfont, int options,
if (code == gs_error_undefined)
continue;
if (code < 0)
- return code;
+ goto error;
charset_size += 2;
}
@@ -1380,7 +1386,7 @@ psf_write_type2_font(stream *s, gs_font_type1 *pfont, int options,
/* Compute the size of the CharStrings Index. */
code = cff_write_CharStrings_offsets(&writer, &genum, &charstrings_count);
if (code < 0)
- return code;
+ goto error;
charstrings_size = (uint)code;
/* Compute the size of the (local) Subrs Index. */
@@ -1424,8 +1430,10 @@ psf_write_type2_font(stream *s, gs_font_type1 *pfont, int options,
Subrs_offset = Private_size; /* relative to Private Dict */
write:
- if(check_ioerror(writer.strm))
- return_error(gs_error_ioerror);
+ if(check_ioerror(writer.strm)) {
+ code = gs_note_error(gs_error_ioerror);
+ goto error;
+ }
start_pos = stell(writer.strm);
/* Write the header, setting offset_size. */
cff_write_header(&writer, End_offset);
@@ -1446,14 +1454,18 @@ psf_write_type2_font(stream *s, gs_font_type1 *pfont, int options,
/* Write the strings Index. */
cff_put_Index(&writer, &writer.strings);
- if(check_ioerror(writer.strm))
- return_error(gs_error_ioerror);
+ if(check_ioerror(writer.strm)){
+ code = gs_note_error(gs_error_ioerror);
+ goto error;
+ }
/* Write the GSubrs Index, if any, checking the offset. */
offset = stell(writer.strm) - start_pos;
if_debug2m('l', s->memory, "[l]GSubrs = %u => %u\n", GSubrs_offset, offset);
- if (offset > GSubrs_offset)
- return_error(gs_error_rangecheck);
+ if (offset > GSubrs_offset) {
+ code = gs_note_error(gs_error_rangecheck);
+ goto error;
+ }
GSubrs_offset = offset;
if (gsubrs_count == 0 || cff_convert_charstrings(&writer, pbfont))
cff_put_Index_header(&writer, 0, 0);
@@ -1468,26 +1480,34 @@ psf_write_type2_font(stream *s, gs_font_type1 *pfont, int options,
/* Write the CharStrings Index, checking the offset. */
offset = stell(writer.strm) - start_pos;
- if (offset > CharStrings_offset)
- return_error(gs_error_rangecheck);
+ if (offset > CharStrings_offset) {
+ code = gs_note_error(gs_error_rangecheck);
+ goto error;
+ }
CharStrings_offset = offset;
cff_write_CharStrings(&writer, &genum, charstrings_count,
charstrings_size);
- if(check_ioerror(writer.strm))
- return_error(gs_error_ioerror);
+ if(check_ioerror(writer.strm)) {
+ code = gs_note_error(gs_error_ioerror);
+ goto error;
+ }
/* Write the Private Dict, checking the offset. */
offset = stell(writer.strm) - start_pos;
- if (offset > Private_offset)
- return_error(gs_error_rangecheck);
+ if (offset > Private_offset) {
+ code = gs_note_error(gs_error_rangecheck);
+ goto error;
+ }
Private_offset = offset;
cff_write_Private(&writer, (subrs_size == 0 ? 0 : Subrs_offset), pfont);
Private_size = stell(writer.strm) - start_pos - offset;
/* Write the Subrs Index, checking the offset. */
offset = stell(writer.strm) - (start_pos + Private_offset);
- if (offset > Subrs_offset)
- return_error(gs_error_rangecheck);
+ if (offset > Subrs_offset) {
+ code = gs_note_error(gs_error_rangecheck);
+ goto error;
+ }
Subrs_offset = offset;
if (cff_convert_charstrings(&writer, pbfont))
cff_put_Index_header(&writer, 0, 0);
@@ -1495,11 +1515,15 @@ psf_write_type2_font(stream *s, gs_font_type1 *pfont, int options,
cff_write_Subrs(&writer, subrs_count, subrs_size, pfont, false);
/* Check the final offset. */
- if(check_ioerror(writer.strm))
- return_error(gs_error_ioerror);
+ if(check_ioerror(writer.strm)) {
+ code = gs_note_error(gs_error_ioerror);
+ goto error;
+ }
offset = stell(writer.strm) - start_pos;
- if (offset > End_offset)
- return_error(gs_error_rangecheck);
+ if (offset > End_offset) {
+ code = gs_note_error(gs_error_rangecheck);
+ goto error;
+ }
if (offset == End_offset) {
/* The iteration has converged. Write the result. */
if (writer.strm == &poss) {
@@ -1516,6 +1540,12 @@ psf_write_type2_font(stream *s, gs_font_type1 *pfont, int options,
gs_free_object(pfont->memory, std_string_items, "psf_write_type2_font");
gs_free_object(pfont->memory, subset.glyphs.subset_data, "psf_write_type2_font");
return 0;
+
+error:
+ gs_free_object(pfont->memory, std_string_items, "psf_write_type2_font");
+ gs_free_object(pfont->memory, subset.glyphs.subset_data, "psf_write_type2_font");
+ subset.glyphs.subset_data = NULL;
+ return code;
}
/* Write the CFF definition of a CIDFontType 0 font (CIDFont). */
diff --git a/devices/vector/gdevtxtw.c b/devices/vector/gdevtxtw.c
index cbe2b19e..5c885f5f 100644
--- a/devices/vector/gdevtxtw.c
+++ b/devices/vector/gdevtxtw.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
@@ -647,20 +647,20 @@ static int simple_text_output(gx_device_txtwrite_t *tdev)
return 0;
}
-static int escaped_Unicode (unsigned short Unicode, char *Buf)
+static int escaped_Unicode (unsigned short Unicode, char Buf[32])
{
switch (Unicode)
{
- case 0x3C: gs_sprintf(Buf, "&lt;"); break;
- case 0x3E: gs_sprintf(Buf, "&gt;"); break;
- case 0x26: gs_sprintf(Buf, "&amp;"); break;
- case 0x22: gs_sprintf(Buf, "&quot;"); break;
- case 0x27: gs_sprintf(Buf, "&apos;"); break;
+ case 0x3C: gs_snprintf(Buf, 32, "&lt;"); break;
+ case 0x3E: gs_snprintf(Buf, 32, "&gt;"); break;
+ case 0x26: gs_snprintf(Buf, 32, "&amp;"); break;
+ case 0x22: gs_snprintf(Buf, 32, "&quot;"); break;
+ case 0x27: gs_snprintf(Buf, 32, "&apos;"); break;
default:
if (Unicode >= 32 && Unicode <= 127)
- gs_sprintf(Buf, "%c", Unicode);
+ gs_snprintf(Buf, 32, "%c", Unicode);
else
- gs_sprintf(Buf, "&#x%x;", Unicode);
+ gs_snprintf(Buf, 32, "&#x%x;", Unicode);
break;
}
@@ -683,13 +683,13 @@ static int decorated_text_output(gx_device_txtwrite_t *tdev)
x_entry = tdev->PageData.unsorted_text_list;
while (x_entry) {
next_x = x_entry->next;
- gs_sprintf(TextBuffer, "<span bbox=\"%0.0f %0.0f %0.0f %0.0f\" font=\"%s\" size=\"%0.4f\">\n", x_entry->start.x, x_entry->start.y,
+ gs_snprintf(TextBuffer, sizeof(TextBuffer), "<span bbox=\"%0.0f %0.0f %0.0f %0.0f\" font=\"%s\" size=\"%0.4f\">\n", x_entry->start.x, x_entry->start.y,
x_entry->end.x, x_entry->end.y, x_entry->FontName,x_entry->size);
gp_fwrite(TextBuffer, 1, strlen(TextBuffer), tdev->file);
xpos = x_entry->start.x;
for (i=0;i<x_entry->Unicode_Text_Size;i++) {
- escaped_Unicode(x_entry->Unicode_Text[i], (char *)&Escaped);
- gs_sprintf(TextBuffer, "<char bbox=\"%0.0f %0.0f %0.0f %0.0f\" c=\"%s\"/>\n", xpos,
+ escaped_Unicode(x_entry->Unicode_Text[i], Escaped);
+ gs_snprintf(TextBuffer, sizeof(TextBuffer), "<char bbox=\"%0.0f %0.0f %0.0f %0.0f\" c=\"%s\"/>\n", xpos,
x_entry->start.y, xpos + x_entry->Widths[i], x_entry->end.y, Escaped);
gp_fwrite(TextBuffer, 1, strlen(TextBuffer), tdev->file);
xpos += x_entry->Widths[i];
@@ -806,13 +806,13 @@ static int decorated_text_output(gx_device_txtwrite_t *tdev)
gp_fwrite("<line>\n", sizeof(unsigned char), 7, tdev->file);
x_entry = block_line->x_ordered_list;
while(x_entry) {
- gs_sprintf(TextBuffer, "<span bbox=\"%0.0f %0.0f %0.0f %0.0f\" font=\"%s\" size=\"%0.4f\">\n", x_entry->start.x, x_entry->start.y,
+ gs_snprintf(TextBuffer, sizeof(TextBuffer), "<span bbox=\"%0.0f %0.0f %0.0f %0.0f\" font=\"%s\" size=\"%0.4f\">\n", x_entry->start.x, x_entry->start.y,
x_entry->end.x, x_entry->end.y, x_entry->FontName,x_entry->size);
gp_fwrite(TextBuffer, 1, strlen(TextBuffer), tdev->file);
xpos = x_entry->start.x;
for (i=0;i<x_entry->Unicode_Text_Size;i++) {
- escaped_Unicode(x_entry->Unicode_Text[i], (char *)&Escaped);
- gs_sprintf(TextBuffer, "<char bbox=\"%0.0f %0.0f %0.0f %0.0f\" c=\"%s\"/>\n", xpos,
+ escaped_Unicode(x_entry->Unicode_Text[i], Escaped);
+ gs_snprintf(TextBuffer, sizeof(TextBuffer), "<char bbox=\"%0.0f %0.0f %0.0f %0.0f\" c=\"%s\"/>\n", xpos,
x_entry->start.y, xpos + x_entry->Widths[i], x_entry->end.y, Escaped);
gp_fwrite(TextBuffer, 1, strlen(TextBuffer), tdev->file);
xpos += x_entry->Widths[i];
@@ -1483,6 +1483,7 @@ txtwrite_process_plain_text(gs_text_enum_t *pte)
uint operation = pte->text.operation;
txt_glyph_widths_t widths;
gs_point wanted; /* user space */
+ float glyph_width;
for (i=pte->index;i<pte->text.size;i++) {
gs_point dpt = {0,0};
@@ -1516,7 +1517,29 @@ txtwrite_process_plain_text(gs_text_enum_t *pte)
if (code < 0)
return code;
+ /* Calculate glyph_width from the **original** glyph metrics, not the overriding
+ * advance width (if TEXT_REPLACE_WIDTHS is set below)
+ */
txt_char_widths_to_uts(pte->orig_font, &widths); /* convert design->text space */
+ glyph_width = widths.real_width.xy.x * penum->text_state->size;
+
+ if (pte->text.operation & TEXT_REPLACE_WIDTHS)
+ {
+ gs_point tpt;
+
+ /* We are applying a width override, from x/y/xyshow. This could be from
+ * a PostScript file, or it could be from a PDF file where we have a font
+ * with a FontMatrix which is neither horizontal nor vertical.
+ */
+ code = gs_text_replaced_width(&pte->text, pte->xy_index++, &tpt);
+ if (code < 0)
+ return_error(gs_error_unregistered);
+
+ widths.Width.w = widths.real_width.w = tpt.x;
+ widths.Width.xy.x = widths.real_width.xy.x = tpt.x;
+ widths.Width.xy.y = widths.real_width.xy.y = tpt.y;
+ }
+
gs_distance_transform(widths.real_width.xy.x * penum->text_state->size,
widths.real_width.xy.y * penum->text_state->size,
&penum->text_state->matrix, &wanted);
@@ -1524,7 +1547,7 @@ txtwrite_process_plain_text(gs_text_enum_t *pte)
pte->returned.total_width.y += wanted.y;
penum->Widths[penum->TextBufferIndex] = wanted.x;
penum->Advs[penum->TextBufferIndex] = wanted.x;
- penum->GlyphWidths[penum->TextBufferIndex] = widths.real_width.xy.x * penum->text_state->size;
+ penum->GlyphWidths[penum->TextBufferIndex] = glyph_width;
penum->SpanDeltaX[penum->TextBufferIndex] = widths.real_width.xy.x * penum->text_state->size;
if (pte->text.operation & TEXT_ADD_TO_ALL_WIDTHS) {
diff --git a/devices/vector/gdevxps.c b/devices/vector/gdevxps.c
index c946f322..1ab854be 100644
--- a/devices/vector/gdevxps.c
+++ b/devices/vector/gdevxps.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
@@ -960,7 +960,7 @@ write_str_to_current_page(gx_device_xps *xps, const char *str)
char buf[128]; /* easily enough to accommodate the string and a page number */
/* we're one ahead of the page count */
- int code = gs_sprintf(buf, page_template, xps->page_count+1);
+ int code = gs_snprintf(buf, sizeof(buf), page_template, xps->page_count+1);
if (code < 0)
return gs_rethrow_code(code);
@@ -1011,7 +1011,7 @@ close_page_relationship(gx_device_xps *xps)
const char *rels_template = "Documents/1/Pages/_rels/%d.fpage.rels";
char buf[128]; /* easily enough to accommodate the string and a page number */
- int code = gs_sprintf(buf, rels_template, xps->page_count + 1);
+ int code = gs_snprintf(buf, sizeof(buf), rels_template, xps->page_count + 1);
if (code < 0)
return gs_rethrow_code(code);
@@ -1029,7 +1029,7 @@ write_page_relationship(gx_device_xps* xps)
int count = 0;
xps_relations_t *rel = xps->relations_head;
- int code = gs_sprintf(buf, rels_template, xps->page_count + 1);
+ int code = gs_snprintf(buf, sizeof(buf), rels_template, xps->page_count + 1);
if (code < 0)
return gs_rethrow_code(code);
@@ -1037,7 +1037,7 @@ write_page_relationship(gx_device_xps* xps)
fmt = "<Relationship Target = \"/%s\" Id = \"R%d\" Type = %s/>\n";
while (rel) {
- gs_sprintf(line, fmt, rel->relation, count, rels_req_type);
+ gs_snprintf(line, sizeof(line), fmt, rel->relation, count, rels_req_type);
write_str_to_zip_file(xps, buf, line);
rel = rel->next;
count++;
@@ -1350,7 +1350,7 @@ xps_beginpage(gx_device_vector *vdev)
{
const char *template = "<PageContent Source=\"Pages/%d.fpage\" />";
/* Note page count is 1 less than the current page */
- code = gs_sprintf(buf, template, xps->page_count + 1);
+ code = gs_snprintf(buf, sizeof(buf), template, xps->page_count + 1);
if (code < 0)
return gs_rethrow_code(code);
@@ -1364,7 +1364,7 @@ xps_beginpage(gx_device_vector *vdev)
{
const char *page_size_template = "<FixedPage Width=\"%d\" Height=\"%d\" "
"xmlns=\"http://schemas.microsoft.com/xps/2005/06\" xml:lang=\"en-US\">\n";
- code = gs_sprintf(buf, page_size_template,
+ code = gs_snprintf(buf, sizeof(buf), page_size_template,
(int)(xps->MediaSize[0] * 4.0/3.0), /* pts -> 1/96 inch */
(int)(xps->MediaSize[1] * 4.0/3.0));
if (code < 0)
@@ -1375,7 +1375,7 @@ xps_beginpage(gx_device_vector *vdev)
}
{
const char *canvas_template = "<Canvas RenderTransform=\"%g,%g,%g,%g,%g,%g\">\n";
- code = gs_sprintf(buf, canvas_template,
+ code = gs_snprintf(buf, sizeof(buf), canvas_template,
96.0/xps->HWResolution[0], 0.0, 0.0,
96.0/xps->HWResolution[1], 0.0, 0.0);
if (code < 0)
@@ -1507,7 +1507,7 @@ xps_finish_image_path(gx_device_vector *vdev)
write_str_to_current_page(xps, "\t<Path.Fill>\n");
write_str_to_current_page(xps, "\t\t<ImageBrush ");
fmt = "ImageSource = \"{ColorConvertedBitmap /%s /%s}\" Viewbox=\"%d, %d, %d, %d\" ViewboxUnits = \"Absolute\" Viewport = \"%d, %d, %d, %d\" ViewportUnits = \"Absolute\" TileMode = \"None\" >\n";
- gs_sprintf(line, fmt, xps->xps_pie->file_name, xps->xps_pie->icc_name,
+ gs_snprintf(line, sizeof(line), fmt, xps->xps_pie->file_name, xps->xps_pie->icc_name,
0, 0, xps->xps_pie->width, xps->xps_pie->height, 0, 0,
xps->xps_pie->width, xps->xps_pie->height);
write_str_to_current_page(xps, line);
@@ -1517,7 +1517,7 @@ xps_finish_image_path(gx_device_vector *vdev)
write_str_to_current_page(xps, "\t\t\t<ImageBrush.Transform>\n");
fmt = "\t\t\t\t<MatrixTransform Matrix = \"%g,%g,%g,%g,%g,%g\" />\n";
matrix = xps->xps_pie->mat;
- gs_sprintf(line, fmt,
+ gs_snprintf(line, sizeof(line), fmt,
matrix.xx, matrix.xy, matrix.yx, matrix.yy, matrix.tx, matrix.ty);
write_str_to_current_page(xps, line);
write_str_to_current_page(xps, "\t\t\t</ImageBrush.Transform>\n");
@@ -1559,7 +1559,7 @@ xps_dorect(gx_device_vector *vdev, fixed x0, fixed y0,
if (image_brush_fill(type, xps->filltype)) {
/* Do the path data */
fmt = "<Path Data=\"M %g, %g L %g, %g %g, %g %g, %g Z\" >\n";
- gs_sprintf(line, fmt,
+ gs_snprintf(line, sizeof(line), fmt,
fixed2float(x0), fixed2float(y0),
fixed2float(x0), fixed2float(y1),
fixed2float(x1), fixed2float(y1),
@@ -1573,7 +1573,7 @@ xps_dorect(gx_device_vector *vdev, fixed x0, fixed y0,
/* NB - F0 should be changed for a different winding type */
fmt = "Fill=\"#%06X\" Data=\"M %g,%g V %g H %g V %g Z\" ";
c = xps->fillcolor & 0xffffffL;
- gs_sprintf(line, fmt, c,
+ gs_snprintf(line, sizeof(line), fmt, c,
fixed2float(x0), fixed2float(y0),
fixed2float(y1), fixed2float(x1),
fixed2float(y0));
@@ -1584,7 +1584,7 @@ xps_dorect(gx_device_vector *vdev, fixed x0, fixed y0,
write_str_to_current_page(xps, "<Path ");
fmt = "Stroke=\"#%06X\" Data=\"M %g,%g V %g H %g V %g Z\" ";
c = xps->strokecolor & 0xffffffL;
- gs_sprintf(line, fmt, c,
+ gs_snprintf(line, sizeof(line), fmt, c,
fixed2float(x0), fixed2float(y0),
fixed2float(y1), fixed2float(x1),
fixed2float(y0));
@@ -1593,7 +1593,7 @@ xps_dorect(gx_device_vector *vdev, fixed x0, fixed y0,
if (type & gx_path_type_stroke) {
/* NB format width. */
fmt = "StrokeThickness=\"%g\" ";
- gs_sprintf(line, fmt, xps->linewidth);
+ gs_snprintf(line, sizeof(line), fmt, xps->linewidth);
write_str_to_current_page(xps, line);
}
write_str_to_current_page(xps, "/>\n");
@@ -1653,7 +1653,7 @@ xps_beginpath(gx_device_vector *vdev, gx_path_type_t type)
fmt = "Fill=\"#%06X\" Data=\"";
else
fmt = "Stroke=\"#%06X\" Data=\"";
- gs_sprintf(line, fmt, c);
+ gs_snprintf(line, sizeof(line), fmt, c);
write_str_to_current_page(xps, line);
}
else {
@@ -1680,7 +1680,7 @@ xps_moveto(gx_device_vector *vdev, double x0, double y0,
return 0;
}
- gs_sprintf(line, " M %g,%g", x, y);
+ gs_snprintf(line, sizeof(line), " M %g,%g", x, y);
write_str_to_current_page(xps, line);
if_debug1m('_', xps->memory, "xps_moveto %s", line);
return 0;
@@ -1700,7 +1700,7 @@ xps_lineto(gx_device_vector *vdev, double x0, double y0,
if_debug1m('_', xps->memory, "xps_lineto: type not supported %x\n", type);
return 0;
}
- gs_sprintf(line, " L %g,%g", x, y);
+ gs_snprintf(line, sizeof(line), " L %g,%g", x, y);
write_str_to_current_page(xps, line);
if_debug1m('_', xps->memory, "xps_lineto %s\n", line);
return 0;
@@ -1720,7 +1720,7 @@ xps_curveto(gx_device_vector *vdev, double x0, double y0,
return 0;
}
- gs_sprintf(line, " C %g,%g %g,%g %g,%g", x1, y1,
+ gs_snprintf(line, sizeof(line), " C %g,%g %g,%g %g,%g", x1, y1,
x2,y2,x3,y3);
write_str_to_current_page(xps,line);
if_debug1m('_', xps->memory, "xps_curveto %s\n", line);
@@ -1766,7 +1766,7 @@ xps_endpath(gx_device_vector *vdev, gx_path_type_t type)
} else if (type & gx_path_type_stroke) {
/* NB format width. */
fmt = "\" StrokeThickness=\"%g\" />\n";
- gs_sprintf(line, fmt, xps->linewidth);
+ gs_snprintf(line, sizeof(line), fmt, xps->linewidth);
write_str_to_current_page(xps, line);
} else { /* fill */
/* close the path data attribute */