summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'devices/vector')
-rw-r--r--devices/vector/gdevagl.c2
-rw-r--r--devices/vector/gdevagl.h7
-rw-r--r--devices/vector/gdevpdf.c56
-rw-r--r--devices/vector/gdevpdfb.c2
-rw-r--r--devices/vector/gdevpdfb.h2
-rw-r--r--devices/vector/gdevpdfc.c11
-rw-r--r--devices/vector/gdevpdfc.h2
-rw-r--r--devices/vector/gdevpdfd.c146
-rw-r--r--devices/vector/gdevpdfe.c2
-rw-r--r--devices/vector/gdevpdfg.c13
-rw-r--r--devices/vector/gdevpdfg.h6
-rw-r--r--devices/vector/gdevpdfi.c20
-rw-r--r--devices/vector/gdevpdfj.c2
-rw-r--r--devices/vector/gdevpdfk.c24
-rw-r--r--devices/vector/gdevpdfm.c2
-rw-r--r--devices/vector/gdevpdfo.c6
-rw-r--r--devices/vector/gdevpdfo.h2
-rw-r--r--devices/vector/gdevpdfp.c2
-rw-r--r--devices/vector/gdevpdfr.c2
-rw-r--r--devices/vector/gdevpdft.c13
-rw-r--r--devices/vector/gdevpdfu.c67
-rw-r--r--devices/vector/gdevpdfv.c2
-rw-r--r--devices/vector/gdevpdfx.h15
-rw-r--r--devices/vector/gdevpdt.c2
-rw-r--r--devices/vector/gdevpdt.h2
-rw-r--r--devices/vector/gdevpdtb.c4
-rw-r--r--devices/vector/gdevpdtb.h2
-rw-r--r--devices/vector/gdevpdtc.c2
-rw-r--r--devices/vector/gdevpdtd.c2
-rw-r--r--devices/vector/gdevpdtd.h2
-rw-r--r--devices/vector/gdevpdte.c4
-rw-r--r--devices/vector/gdevpdtf.c3
-rw-r--r--devices/vector/gdevpdtf.h12
-rw-r--r--devices/vector/gdevpdti.c6
-rw-r--r--devices/vector/gdevpdti.h2
-rw-r--r--devices/vector/gdevpdts.c47
-rw-r--r--devices/vector/gdevpdts.h2
-rw-r--r--devices/vector/gdevpdtt.c2
-rw-r--r--devices/vector/gdevpdtt.h2
-rw-r--r--devices/vector/gdevpdtv.c2
-rw-r--r--devices/vector/gdevpdtv.h2
-rw-r--r--devices/vector/gdevpdtw.c6
-rw-r--r--devices/vector/gdevpdtw.h2
-rw-r--r--devices/vector/gdevpdtx.h2
-rw-r--r--devices/vector/gdevpsdf.h7
-rw-r--r--devices/vector/gdevpsdi.c8
-rw-r--r--devices/vector/gdevpsdp.c93
-rw-r--r--devices/vector/gdevpsds.c8
-rw-r--r--devices/vector/gdevpsds.h2
-rw-r--r--devices/vector/gdevpsdu.c2
-rw-r--r--devices/vector/gdevpsf.h2
-rw-r--r--devices/vector/gdevpsf1.c2
-rw-r--r--devices/vector/gdevpsf2.c4
-rw-r--r--devices/vector/gdevpsfm.c2
-rw-r--r--devices/vector/gdevpsft.c2
-rw-r--r--devices/vector/gdevpsfu.c2
-rw-r--r--devices/vector/gdevpsfx.c2
-rw-r--r--devices/vector/gdevpsu.c2
-rw-r--r--devices/vector/gdevpsu.h2
-rw-r--r--devices/vector/gdevpx.c2
-rw-r--r--devices/vector/gdevtxtw.c199
-rw-r--r--devices/vector/gdevxps.c4
-rw-r--r--devices/vector/opdfread.ps202
-rw-r--r--devices/vector/whitelst.c2
-rw-r--r--devices/vector/whitelst.h2
65 files changed, 646 insertions, 421 deletions
diff --git a/devices/vector/gdevagl.c b/devices/vector/gdevagl.c
index f9428a6e..a551bb38 100644
--- a/devices/vector/gdevagl.c
+++ b/devices/vector/gdevagl.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevagl.h b/devices/vector/gdevagl.h
index e3569226..066eae76 100644
--- a/devices/vector/gdevagl.h
+++ b/devices/vector/gdevagl.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -16,6 +16,9 @@
* Unicode code points.
*/
+#ifndef gdevagl_h_INCLUDED
+#define gdevagl_h_INCLUDED
+
typedef struct single_glyph_list_s {
const char *Glyph;
unsigned short Unicode;
@@ -35,3 +38,5 @@ typedef struct quad_glyph_list_s {
const char *Glyph;
unsigned short Unicode[4];
} quad_glyph_list_t;
+
+#endif
diff --git a/devices/vector/gdevpdf.c b/devices/vector/gdevpdf.c
index b25a4a6a..6752fabb 100644
--- a/devices/vector/gdevpdf.c
+++ b/devices/vector/gdevpdf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -467,6 +467,12 @@ pdf_compute_fileID(gx_device_pdf * pdev)
pdev->KeyLength = KeyLength;
if (code < 0)
return code;
+ /* Generally we would call s_close_filters() here in order to free the data buffer
+ * associated with the MD5 filter, but the data buffer we passed in to s_MD5E_make_stream()
+ * is part of the device structure, so we must *NOT* free that buffer. Therefore we must
+ * instead call sclose(). This confusion over ownership of the stream buffers causes
+ * a lot of problems......
+ */
sclose(s);
gs_free_object(mem, s, "pdf_compute_fileID");
return 0;
@@ -1410,6 +1416,11 @@ pdf_output_page(gx_device * dev, int num_copies, int flush)
gx_device_pdf *const pdev = (gx_device_pdf *) dev;
int code;
+ if (pdev->Eps2Write && pdev->next_page != 0 && !gx_outputfile_is_separate_pages(pdev->fname, dev->memory)) {
+ emprintf(pdev->memory, "\n *** EPS files may not contain multiple pages.\n *** Use of the %%d filename format is required to output pages to multiple EPS files.\n");
+ return_error(gs_error_ioerror);
+ }
+
if (pdev->ForOPDFRead) {
code = pdf_close_page(pdev, num_copies);
if (code < 0)
@@ -2555,6 +2566,7 @@ pdf_close(gx_device * dev)
int64_t start_section, end_section;
char str[256];
pdf_linearisation_t linear_params;
+ bool file_per_page = false;
if (!dev->is_open)
return_error(gs_error_undefined);
@@ -2577,26 +2589,14 @@ pdf_close(gx_device * dev)
* marks.
*/
if (pdev->next_page == 0) {
- /* If we didn't get called from pdf_output_page, and we are doign file-per-page
- * output, then the call from close_device will leave an empty file which we don't
- * want. So here we delete teh file.
- */
- if (!pdev->InOutputPage && gx_outputfile_is_separate_pages(pdev->fname, pdev->memory)) {
- code = gdev_vector_close_file((gx_device_vector *) pdev);
- if (code != 0)
- return code;
- code = pdf_close_files(pdev, 0);
+ file_per_page = !pdev->InOutputPage &&
+ gx_outputfile_is_separate_pages(pdev->fname, pdev->memory);
+ if (!file_per_page) {
+ code = pdf_open_page(pdev, PDF_IN_STREAM);
+
if (code < 0)
return code;
- code = gx_device_delete_output_file((const gx_device *)pdev, pdev->fname);
- if (code != 0)
- return gs_note_error(gs_error_ioerror);
- return code;
}
- code = pdf_open_page(pdev, PDF_IN_STREAM);
-
- if (code < 0)
- return code;
}
if (pdev->contents_id != 0)
pdf_close_page(pdev, 1);
@@ -2945,6 +2945,14 @@ pdf_close(gx_device * dev)
stream_puts(pdev->strm, "%%EOF\n");
}
+ if (pdev->params.PSPageOptions.size) {
+ int ix;
+
+ for (ix = 0; ix < pdev->params.PSPageOptions.size;ix++)
+ gs_free_object(mem->non_gc_memory, (byte *)pdev->params.PSPageOptions.data[ix].data, "freeing old string array copy");
+ gs_free_object(mem->non_gc_memory, (byte *)pdev->params.PSPageOptions.data, "freeing old string array");
+ }
+
if (pdev->Linearise) {
linear_params.LastResource = pdev->next_id - 1;
linear_params.Offsets = (gs_offset_t *)gs_alloc_bytes(pdev->pdf_memory, pdev->next_id * sizeof(gs_offset_t), "temp xref storage");
@@ -3450,6 +3458,18 @@ pdf_close(gx_device * dev)
if (code < 0)
return code;
+ /* If we didn't get called from pdf_output_page, and we are doign file-per-page
+ * output, then the call from close_device will leave an empty file which we don't
+ * want. So here we delete the file.
+ * NOTE: We needed to let it process the whole page in order to make sure everything
+ * got properly freed.
+ */
+ if (file_per_page) {
+ code = gx_device_delete_output_file((const gx_device *)pdev, pdev->fname);
+ if (code != 0)
+ code = gs_note_error(gs_error_ioerror);
+ }
+
pdf_free_pdf_font_cache(pdev);
return code;
}
diff --git a/devices/vector/gdevpdfb.c b/devices/vector/gdevpdfb.c
index e35531d7..20339038 100644
--- a/devices/vector/gdevpdfb.c
+++ b/devices/vector/gdevpdfb.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdfb.h b/devices/vector/gdevpdfb.h
index 5ea7a355..16521e0d 100644
--- a/devices/vector/gdevpdfb.h
+++ b/devices/vector/gdevpdfb.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdfc.c b/devices/vector/gdevpdfc.c
index 259d143c..3a3096c4 100644
--- a/devices/vector/gdevpdfc.c
+++ b/devices/vector/gdevpdfc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -643,6 +643,10 @@ pdf_indexed_color_space(gx_device_pdf *pdev, const gs_gstate * pgs, cos_value_t
}
stream_write(&es, palette, table_size);
gs_free_string(mem, palette, table_size, "pdf_color_space(palette)");
+ /* Another case where we use sclose() and not sclose_filters(), because the
+ * buffer we supplied to s_init_filter is a heap based C object, so we
+ * must not free it.
+ */
sclose(&es);
sflush(&s);
string_used = (uint)stell(&s);
@@ -874,6 +878,11 @@ pdf_color_space_named(gx_device_pdf *pdev, const gs_gstate * pgs,
if (code < 0)
return_error(gs_error_unregistered); /* Must not happen. */
serialized_size = stell(&s);
+ /* I think this is another case where we use sclose() and not sclose_filters().
+ * It seems like we don't actually write anything, but it allows us to find the
+ * length of the serialised data. No buffer hre, so we must no call
+ * s_close_filters() as that will try to free it.
+ */
sclose(&s);
if (serialized_size <= sizeof(serialized0))
serialized = serialized0;
diff --git a/devices/vector/gdevpdfc.h b/devices/vector/gdevpdfc.h
index 69770933..e9056be3 100644
--- a/devices/vector/gdevpdfc.h
+++ b/devices/vector/gdevpdfc.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdfd.c b/devices/vector/gdevpdfd.c
index 1e62bad1..32a6c41b 100644
--- a/devices/vector/gdevpdfd.c
+++ b/devices/vector/gdevpdfd.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -181,20 +181,6 @@ pdf_dorect(gx_device_vector * vdev, fixed x0, fixed y0, fixed x1, fixed y1,
ymin -= d;
ymax += d;
}
- if (pdev->CompatibilityLevel < 1.5) {
- /*
- * Clamp coordinates to avoid tripping over Acrobat Reader's limit
- * of 32K on user coordinate values.
- */
- if (x0 < xmin)
- x0 = xmin;
- if (x1 > xmax)
- x1 = xmax;
- if (y0 < ymin)
- y0 = ymin;
- if (y1 > ymax)
- y1 = ymax;
- }
return psdf_dorect(vdev, x0, y0, x1, y1, type);
}
@@ -236,6 +222,7 @@ const gx_device_vector_procs pdf_vector_procs = {
int
pdf_remember_clip_path(gx_device_pdf * pdev, const gx_clip_path * pcpath)
{
+ int code = 0;
/* Used for skipping redundant clip paths. SF bug #624168. */
if (pdev->clip_path != 0) {
gx_path_free(pdev->clip_path, "pdf clip path");
@@ -247,7 +234,22 @@ pdf_remember_clip_path(gx_device_pdf * pdev, const gx_clip_path * pcpath)
pdev->clip_path = gx_path_alloc(pdev->pdf_memory, "pdf clip path");
if (pdev->clip_path == 0)
return_error(gs_error_VMerror);
- return gx_cpath_to_path((gx_clip_path *)pcpath, pdev->clip_path);
+
+ code = gx_cpath_to_path((gx_clip_path *)pcpath, pdev->clip_path);
+ if (code < 0)
+ return code;
+
+ /* gx_cpath_to_path above ends up going through gx_path_assign_preserve
+ * which specifically states that the segments of the paths (in this case pcpath
+ * and pdev->clip_path) must have been allocated with the same allocator.
+ * If that's not true (eg pdfi running inside GS) then we need to 'unshare'
+ * the path. Otherwise we mauy end up with pcpath being freed and discarded
+ * while the pdfwrite devcie still thinks it has a pointer to it.
+ */
+ if (pcpath->path.memory != pdev->pdf_memory)
+ code = gx_path_unshare(pdev->clip_path);
+
+ return code;
}
/* Check if same clipping path. */
@@ -778,38 +780,6 @@ pdf_put_clip_path(gx_device_pdf * pdev, const gx_clip_path * pcpath)
}
/*
- * Compute the scaling to ensure that user coordinates for a path are within
- * Acrobat's range. Return true if scaling was needed. In this case, the
- * CTM will be multiplied by *pscale, and all coordinates will be divided by
- * *pscale.
- */
-static bool
-make_rect_scaling(const gx_device_pdf *pdev, const gs_fixed_rect *bbox,
- double prescale, double *pscale)
-{
- double bmin, bmax;
-
- if (pdev->CompatibilityLevel > 1.4) {
- *pscale = 1;
- return false;
- }
-
- bmin = min(bbox->p.x / pdev->scale.x, bbox->p.y / pdev->scale.y) * prescale;
- bmax = max(bbox->q.x / pdev->scale.x, bbox->q.y / pdev->scale.y) * prescale;
- if (bmin <= int2fixed(-MAX_USER_COORD) ||
- bmax > int2fixed(MAX_USER_COORD)
- ) {
- /* Rescale the path. */
- *pscale = max(bmin / int2fixed(-MAX_USER_COORD),
- bmax / int2fixed(MAX_USER_COORD));
- return true;
- } else {
- *pscale = 1;
- return false;
- }
-}
-
-/*
* Prepare a fill with a color anc a clipping path.
* Return 1 if there is nothing to paint.
* Changes *box to the clipping box.
@@ -1652,9 +1622,6 @@ gdev_pdf_fill_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath,
return code;
{
stream *s = pdev->strm;
- double scale;
- gs_matrix smat;
- gs_matrix *psmat = NULL;
gs_path_enum cenum;
gdev_vector_dopath_state_t state;
@@ -1667,19 +1634,11 @@ gdev_pdf_fill_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath,
pprintg1(s, "%g i\n", params->flatness);
pdev->state.flatness = params->flatness;
}
- if (make_rect_scaling(pdev, &box1, 1.0, &scale)) {
- gs_make_scaling(pdev->scale.x * scale, pdev->scale.y * scale,
- &smat);
- pdf_put_matrix(pdev, "q ", &smat, "cm\n");
- psmat = &smat;
- }
- code = pdf_write_path(pdev, (gs_path_enum *)&cenum, &state, (gx_path *)ppath, 0, gx_path_type_fill | gx_path_type_optimize, psmat);
+ code = pdf_write_path(pdev, (gs_path_enum *)&cenum, &state, (gx_path *)ppath, 0, gx_path_type_fill | gx_path_type_optimize, NULL);
if (code < 0)
return code;
stream_puts(s, (params->rule < 0 ? "f\n" : "f*\n"));
- if (psmat)
- stream_puts(s, "Q\n");
}
return 0;
}
@@ -1693,10 +1652,9 @@ gdev_pdf_stroke_path(gx_device * dev, const gs_gstate * pgs,
gx_device_pdf *pdev = (gx_device_pdf *) dev;
stream *s;
int code;
- double scale, path_scale;
+ double scale;
bool set_ctm;
gs_matrix mat;
- double prescale = 1;
gs_fixed_rect bbox;
gs_path_enum cenum;
gdev_vector_dopath_state_t state;
@@ -1782,20 +1740,6 @@ gdev_pdf_stroke_path(gx_device * dev, const gs_gstate * pgs,
scale = fabs(pgs->ctm.xx + pgs->ctm.xy + pgs->ctm.yx + pgs->ctm.yy) /* Using the non-zero coeff. */
/ sqrt(2); /* Empirically from Adobe. */
}
- if (set_ctm) {
- /*
- * We want a scaling factor that will bring the largest reasonable
- * user coordinate within bounds. We choose a factor based on the
- * minor axis of the transformation. Thanks to Raph Levien for
- * the following formula.
- */
- double a = mat.xx, b = mat.xy, c = mat.yx, d = mat.yy;
- double u = fabs(a * d - b * c);
- double v = a * a + b * b + c * c + d * d;
- double minor = (sqrt(v + 2 * u) - sqrt(v - 2 * u)) * 0.5;
-
- prescale = (minor == 0 || minor > 1 ? 1 : 1 / minor);
- }
gx_path_bbox(ppath, &bbox);
{
/* Check whether a painting appears inside the clipping box.
@@ -1828,15 +1772,6 @@ gdev_pdf_stroke_path(gx_device * dev, const gs_gstate * pgs,
if (stroke_bbox.q.x < stroke_bbox.p.x || stroke_bbox.q.y < stroke_bbox.p.y)
return 0;
}
- if (make_rect_scaling(pdev, &bbox, prescale, &path_scale)) {
- scale /= path_scale;
- if (set_ctm)
- gs_matrix_scale(&mat, path_scale, path_scale, &mat);
- else {
- gs_make_scaling(path_scale, path_scale, &mat);
- set_ctm = true;
- }
- }
code = gdev_vector_prepare_stroke((gx_device_vector *)pdev, pgs, params,
pdcolor, scale);
if (code < 0)
@@ -1903,8 +1838,7 @@ gdev_pdf_fill_stroke_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath,
} else {
bool set_ctm;
gs_matrix mat;
- double scale, path_scale;
- double prescale = 1;
+ double scale;
gs_fixed_rect bbox;
gs_path_enum cenum;
gdev_vector_dopath_state_t state;
@@ -1918,7 +1852,6 @@ gdev_pdf_fill_stroke_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath,
gx_cpath_outer_box(pcpath, &cbox);
if (cbox.p.x >= cbox.q.x || cbox.p.y >= cbox.q.y)
return 1; /* empty clipping path */
-// *box = cbox;
}
code = pdf_check_soft_mask(pdev, (gs_gstate *)pgs);
if (code < 0)
@@ -1968,20 +1901,6 @@ gdev_pdf_fill_stroke_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath,
scale = fabs(pgs->ctm.xx + pgs->ctm.xy + pgs->ctm.yx + pgs->ctm.yy) /* Using the non-zero coeff. */
/ sqrt(2); /* Empirically from Adobe. */
}
- if (set_ctm) {
- /*
- * We want a scaling factor that will bring the largest reasonable
- * user coordinate within bounds. We choose a factor based on the
- * minor axis of the transformation. Thanks to Raph Levien for
- * the following formula.
- */
- double a = mat.xx, b = mat.xy, c = mat.yx, d = mat.yy;
- double u = fabs(a * d - b * c);
- double v = a * a + b * b + c * c + d * d;
- double minor = (sqrt(v + 2 * u) - sqrt(v - 2 * u)) * 0.5;
-
- prescale = (minor == 0 || minor > 1 ? 1 : 1 / minor);
- }
gx_path_bbox(ppath, &bbox);
{
/* Check whether a painting appears inside the clipping box.
@@ -2014,15 +1933,6 @@ gdev_pdf_fill_stroke_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath,
if (stroke_bbox.q.x < stroke_bbox.p.x || stroke_bbox.q.y < stroke_bbox.p.y)
return 0;
}
- if (make_rect_scaling(pdev, &bbox, prescale, &path_scale)) {
- scale /= path_scale;
- if (set_ctm)
- gs_matrix_scale(&mat, path_scale, path_scale, &mat);
- else {
- gs_make_scaling(path_scale, path_scale, &mat);
- set_ctm = true;
- }
- }
code = pdf_setfillcolor((gx_device_vector *)pdev, pgs, pdcolor_fill);
if (code == gs_error_rangecheck) {
@@ -2077,9 +1987,6 @@ gdev_pdf_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect,
int code;
gs_fixed_rect box1 = *rect, box = box1;
gx_device_pdf *pdev = (gx_device_pdf *) dev;
- double scale;
- gs_matrix smat;
- gs_matrix *psmat = NULL;
const bool convert_to_image = (pdev->CompatibilityLevel <= 1.2 &&
gx_dc_is_pattern2_color(pdcolor));
@@ -2098,16 +2005,9 @@ gdev_pdf_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect,
rect_intersect(box1, box);
if (box1.p.x > box1.q.x || box1.p.y > box1.q.y)
return 0; /* outside the clipping path */
- if (make_rect_scaling(pdev, &box1, 1.0, &scale)) {
- gs_make_scaling(pdev->scale.x * scale, pdev->scale.y * scale, &smat);
- pdf_put_matrix(pdev, "q ", &smat, "cm\n");
- psmat = &smat;
- }
pprintg4(pdev->strm, "%g %g %g %g re f\n",
- fixed2float(box1.p.x) / scale, fixed2float(box1.p.y) / scale,
- fixed2float(box1.q.x - box1.p.x) / scale, fixed2float(box1.q.y - box1.p.y) / scale);
- if (psmat)
- stream_puts(pdev->strm, "Q\n");
+ fixed2float(box1.p.x), fixed2float(box1.p.y),
+ fixed2float(box1.q.x - box1.p.x) , fixed2float(box1.q.y - box1.p.y));
if (pdev->Eps2Write) {
gs_rect *Box;
diff --git a/devices/vector/gdevpdfe.c b/devices/vector/gdevpdfe.c
index 1c540709..f9544c5d 100644
--- a/devices/vector/gdevpdfe.c
+++ b/devices/vector/gdevpdfe.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdfg.c b/devices/vector/gdevpdfg.c
index 0aa93e53..39da7ea4 100644
--- a/devices/vector/gdevpdfg.c
+++ b/devices/vector/gdevpdfg.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -1467,7 +1467,7 @@ int pdf_reset_color(gx_device_pdf * pdev, const gs_gstate * pgs,
* unlike shading patterns we have no fallback.
*/
if (pdev->CompatibilityLevel < 1.2) {
- return_error(gs_error_undefined);
+ return_error(gs_error_undefined);
}
code = pdf_put_colored_pattern(pdev, pdc, pcs,
ppscc, pgs, &pres);
@@ -2426,7 +2426,8 @@ pdf_write_spot_halftone(gx_device_pdf *pdev, const gs_spot_halftone *psht,
if (compare_gx_ht_order_levels(&order,porder))
continue;
if (memcmp(order.bit_data, porder->bit_data,
- order.num_bits * porder->procs->bit_data_elt_size))
+ (size_t)order.num_bits *
+ porder->procs->bit_data_elt_size))
continue;
/* We have a match. */
break;
@@ -2609,7 +2610,7 @@ pdf_get_halftone_component_index(const gs_multiple_halftone *pmht,
return j;
}
static int
-pdf_write_multiple_halftone(gx_device_pdf *pdev,
+pdf_write_multiple_halftone(gx_device_pdf *pdev, gs_gstate *pgs,
const gs_multiple_halftone *pmht,
const gx_device_halftone *pdht, long *pid)
{
@@ -2679,7 +2680,7 @@ pdf_write_multiple_halftone(gx_device_pdf *pdev,
done_Default = true;
}
phtc = &pmht->components[code];
- if ((code = pmht->get_colorname_string(pdev->memory, phtc->cname, &str, &len)) < 0 ||
+ if ((code = pmht->get_colorname_string(pgs, phtc->cname, &str, &len)) < 0 ||
(code = pdf_string_to_cos_name(pdev, str, len, &value)) < 0)
return code;
cos_value_write(&value, pdev);
@@ -2739,7 +2740,7 @@ pdf_update_halftone(gx_device_pdf *pdev, const gs_gstate *pgs,
break;
case ht_type_multiple:
case ht_type_multiple_colorscreen:
- code = pdf_write_multiple_halftone(pdev, &pht->params.multiple,
+ code = pdf_write_multiple_halftone(pdev, (gs_gstate *)pgs, &pht->params.multiple,
pdht, &id);
break;
default:
diff --git a/devices/vector/gdevpdfg.h b/devices/vector/gdevpdfg.h
index e846b1a8..e9faa670 100644
--- a/devices/vector/gdevpdfg.h
+++ b/devices/vector/gdevpdfg.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -347,10 +347,10 @@ int pdf_copy_color_data(gx_device_pdf * pdev, const byte * base, int sourcex,
gs_image_t *pim, pdf_image_writer *piw,
int for_pattern);
-#endif /* gdevpdfg_INCLUDED */
-
/* ---------------- Exported by gdevpdfe.c ---------------- */
/* Write metadata */
int pdf_document_metadata(gx_device_pdf *pdev);
int pdf_get_docinfo_item(gx_device_pdf *pdev, const char *key, char *buf, int buf_length);
+
+#endif /* gdevpdfg_INCLUDED */
diff --git a/devices/vector/gdevpdfi.c b/devices/vector/gdevpdfi.c
index b73ed3d6..c6bdee9d 100644
--- a/devices/vector/gdevpdfi.c
+++ b/devices/vector/gdevpdfi.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -976,7 +976,7 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
const gs_pixel_image_t *pim;
gs_int_rect rect;
gs_image_format_t format;
- const gs_color_space *pcs;
+ gs_color_space *pcs;
int num_components;
pdf_image_enum *pie;
const pdf_color_space_names_t *names;
@@ -1213,6 +1213,7 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
}
pcs = pim->ColorSpace;
+ rc_increment_cs(pcs);
num_components = (is_mask ? 1 : gs_color_space_num_components(pcs));
code = pdf_check_soft_mask(pdev, (gs_gstate *)pgs);
@@ -1238,6 +1239,7 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
* to DeviceGray here.
*/
/* {csrc} make sure this gets freed */
+ rc_decrement(pcs, "pdf_begin_typed_image(pcs)");
pcs = gs_cspace_new_DeviceGray(pdev->memory);
if (pcs == NULL)
code = gs_note_error(gs_error_VMerror);
@@ -1401,9 +1403,6 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
if (pdev->params.TransferFunctionInfo == tfi_Apply && pdev->transfer_not_identity && !is_mask)
pdev->JPEG_PassThrough = 0;
-/* if (pdev->JPEG_PassThrough)
- uncompressed = pie->writer.binary[0].strm;*/
-
/* Code below here deals with setting up the multiple data stream writing.
* We can have up to 4 stream writers, which we keep in an array. We must
* always have at least one which writes the uncompressed stream. If we
@@ -1612,9 +1611,11 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
"pdf_begin_typed_image(image)");
+ rc_decrement(pcs, "pdf_begin_typed_image(pcs)");
return 0;
fail_and_fallback:
+ rc_decrement(pcs, "pdf_begin_typed_image(pcs)");
pdev->JPEG_PassThrough = 0;
gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
"pdf_begin_typed_image(image)");
@@ -1928,7 +1929,14 @@ pdf_image_end_image_data(gx_image_enum_common_t * info, bool draw_last,
/* Clean up any outstanding streams before freeing the enumerator */
while (pie->writer.alt_writer_count-- > 0) {
ecode = psdf_end_binary(&(pie->writer.binary[pie->writer.alt_writer_count]));
- if (ecode < 0 && code >= 0) code = ecode;
+ /* If we are skipping an image (because its clipped out or similar) then we
+ * won't have written any data to it. Some filters (notably the DCTEncode filter)
+ * throw an error (premature EOD) if we close the filter without writing any data to it.
+ * So if we are skipping the image, ignore errors when closing the stream.
+ * Unfortunately we don't set pie->skipping until after begin_typed_image()
+ * or we could avoid a lot of setup....
+ */
+ if (ecode < 0 && code >= 0 && !pie->skipping) code = ecode;
}
gx_image_free_enum(&info);
diff --git a/devices/vector/gdevpdfj.c b/devices/vector/gdevpdfj.c
index 0af81fc2..4c73e171 100644
--- a/devices/vector/gdevpdfj.c
+++ b/devices/vector/gdevpdfj.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdfk.c b/devices/vector/gdevpdfk.c
index 7914c0ee..e48718d1 100644
--- a/devices/vector/gdevpdfk.c
+++ b/devices/vector/gdevpdfk.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -778,9 +778,10 @@ pdf_iccbased_color_space(gx_device_pdf *pdev, const gs_gstate * pgs, cos_value_t
const gs_color_space *pcs, cos_array_t *pca)
{
cos_stream_t * pcstrm;
- int code = 0;
+ int code = 0, code1 = 0;
unsigned char major = 0, minor = 0;
bool downgrade_icc = false;
+ pdf_resource_t *pres = NULL;
/*
* This would arise only in a pdf ==> pdf translation, but we
@@ -864,13 +865,22 @@ pdf_iccbased_color_space(gx_device_pdf *pdev, const gs_gstate * pgs, cos_value_t
pcs->cmm_icc_profile_data->buffer_size);
}
- if (code >= 0)
- code = pdf_finish_iccbased(pdev, pcstrm);
/*
- * The stream has been added to the array: in case of failure, the
- * caller will free the array, so there is no need to free the stream
- * explicitly here.
+ * The stream has been added to the array: However because the stream cos object
+ * has an id (it has to be an indirect object), freeing the colour space won't
+ * free the ICC profile stream. In order to have the stream freed we must add it to
+ * a resource chain; we don't have a resource chain for ICC profiles, so add it to
+ * resourceOther instead. This means it will be among the last objects released.
*/
+ code1 = pdf_alloc_resource(pdev, resourceOther, pcstrm->id, &pres, -1);
+ if (code1 >= 0) {
+ COS_FREE(pres->object, "pdf_iccbased_color_space");
+ pres->object = (cos_object_t *)pcstrm;
+ }
+
+ if (code >= 0)
+ code = pdf_finish_iccbased(pdev, pcstrm);
+
return code;
}
diff --git a/devices/vector/gdevpdfm.c b/devices/vector/gdevpdfm.c
index 6e018aa4..18ea50c5 100644
--- a/devices/vector/gdevpdfm.c
+++ b/devices/vector/gdevpdfm.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdfo.c b/devices/vector/gdevpdfo.c
index 402d290c..70b66c6b 100644
--- a/devices/vector/gdevpdfo.c
+++ b/devices/vector/gdevpdfo.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -1132,6 +1132,10 @@ static int write_key_as_string_encrypted(const gx_device_pdf *pdev, const byte *
memcpy(buffer, str, size);
s_arcfour_process_buffer(&sarc4, buffer, size);
stream_write(&sout, buffer, size);
+ /* Another case where we use sclose() and not s_close_filters(), because the
+ * buffer we supplied to s_init_filter is a heap based C object, so we
+ * must not free it.
+ */
sclose(&sout); /* Writes ')'. */
gs_free_object(pdev->pdf_memory, buffer, "Free encryption buffer");
return 0;
diff --git a/devices/vector/gdevpdfo.h b/devices/vector/gdevpdfo.h
index 0b6ef201..b30e9676 100644
--- a/devices/vector/gdevpdfo.h
+++ b/devices/vector/gdevpdfo.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdfp.c b/devices/vector/gdevpdfp.c
index 2f29dba5..d06e585c 100644
--- a/devices/vector/gdevpdfp.c
+++ b/devices/vector/gdevpdfp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdfr.c b/devices/vector/gdevpdfr.c
index 6d9f7f6f..b0ee06c4 100644
--- a/devices/vector/gdevpdfr.c
+++ b/devices/vector/gdevpdfr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdft.c b/devices/vector/gdevpdft.c
index 46f4d312..a963cb51 100644
--- a/devices/vector/gdevpdft.c
+++ b/devices/vector/gdevpdft.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -107,7 +107,7 @@ pdf_make_group_dict(gx_device_pdf * pdev, const gs_pdf14trans_params_t * pparams
a group color specified.
In this case, the parent group is inherited from
the previous group or the device color space */
- if (pgs != NULL && pparams->group_color != UNKNOWN) {
+ if (pgs != NULL && pparams->group_color_type != UNKNOWN) {
const gs_color_space *cs = gs_currentcolorspace_inline(pgs);
code = pdf_color_space_named(pdev, pgs, &cs_value, NULL, cs,
@@ -274,7 +274,7 @@ pdf_begin_transparency_mask(gs_gstate * pgs, gx_device_pdf * pdev,
const gs_pdf14trans_params_t * pparams)
{
if (pparams->subtype == TRANSPARENCY_MASK_None) {
- int code, id = pgs->soft_mask_id;
+ int code;
pdf_resource_t *pres = 0L;
/* reset the soft mask ID. Apparently this is only used by pdfwrite, if we don't
@@ -284,10 +284,11 @@ pdf_begin_transparency_mask(gs_gstate * pgs, gx_device_pdf * pdev,
pgs->soft_mask_id = 0;
code = pdf_prepare_drawing(pdev, pgs, &pres, false);
if (code == gs_error_interrupt) {
- /* Not in an appropriate context, ignore it but restore
- * the old soft_mask_id. Not sure this is correct, but it works for now.
+ /* */
+ /* Not in an appropriate context. Do not restore the soft_mask_id.
+ Otherwise any group push that occurs following this will use that
+ softmask, which clearly should be NONE here.
*/
- pgs->soft_mask_id = id;
/* ignore return code, we don't care about this graphics state as we aren't
* emitting it anyway
*/
diff --git a/devices/vector/gdevpdfu.c b/devices/vector/gdevpdfu.c
index 05ea7881..e5a9df01 100644
--- a/devices/vector/gdevpdfu.c
+++ b/devices/vector/gdevpdfu.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -568,6 +568,7 @@ int ps2write_dsc_header(gx_device_pdf * pdev, int pages)
if (code < 0)
return code;
}
+ stream_puts(s, "10 dict dup begin\n");
stream_puts(s, "/DSC_OPDFREAD true def\n");
if (pdev->Eps2Write) {
stream_puts(s, "/SetPageSize false def\n");
@@ -577,6 +578,7 @@ int ps2write_dsc_header(gx_device_pdf * pdev, int pages)
stream_puts(s, "/SetPageSize true def\n");
stream_puts(s, "/EPS2Write false def\n");
}
+ stream_puts(s, "end\n");
code = copy_procsets(s, pdev->HaveTrueTypes, false);
if (code < 0)
@@ -626,6 +628,7 @@ pdfwrite_pdf_open_document(gx_device_pdf * pdev)
if (code < 0)
return code;
}
+ stream_puts(s, "10 dict dup begin\n");
stream_puts(s, "/DSC_OPDFREAD false def\n");
code = copy_procsets(s, pdev->HaveTrueTypes, true);
if (code < 0)
@@ -646,6 +649,7 @@ pdfwrite_pdf_open_document(gx_device_pdf * pdev)
stream_puts(s, "/FitPages true def\n");
if(pdev->CenterPages)
stream_puts(s, "/CenterPages true def\n");
+ stream_puts(s, "end\n");
pdev->OPDFRead_procset_length = stell(s);
}
}
@@ -1000,21 +1004,6 @@ pdf_begin_encrypt(gx_device_pdf * pdev, stream **s, gs_id object_id)
*/
}
-/* Remove the encryption filter. */
-void
-pdf_end_encrypt(gx_device_pdf * pdev)
-{
- if (pdev->KeyLength) {
- stream *s = pdev->strm;
- stream *fs = s->strm;
-
- sclose(s);
- gs_free_object(pdev->pdf_memory, s->cbuf, "encrypt buffer");
- gs_free_object(pdev->pdf_memory, s, "encrypt stream");
- pdev->strm = fs;
- }
-}
-
/* Enter stream context. */
static int
none_to_stream(gx_device_pdf * pdev)
@@ -1168,6 +1157,7 @@ stream_to_none(gx_device_pdf * pdev)
stream *s = pdev->strm;
gs_offset_t length;
int code;
+ stream *target;
if (pdev->ResourcesBeforeUsage) {
int code = pdf_exit_substream(pdev);
@@ -1180,22 +1170,16 @@ stream_to_none(gx_device_pdf * pdev)
if (code < 0)
return code;
}
- if (pdev->compression_at_page_start == pdf_compress_Flate) { /* Terminate the filters. */
- stream *fs = s->strm;
-
- if (!pdev->binary_ok) {
- sclose(s); /* Terminate the ASCII85 filter. */
- gs_free_object(pdev->pdf_memory, s->cbuf, "A85E contents buffer");
- gs_free_object(pdev->pdf_memory, s, "A85E contents stream");
- pdev->strm = s = fs;
- fs = s->strm;
- }
- sclose(s); /* Next terminate the compression filter */
- gs_free_object(pdev->pdf_memory, s->cbuf, "zlib buffer");
- gs_free_object(pdev->pdf_memory, s, "zlib stream");
- pdev->strm = fs;
- }
- pdf_end_encrypt(pdev);
+ target = pdev->strm;
+
+ if (pdev->compression_at_page_start == pdf_compress_Flate)
+ target = target->strm;
+ if (!pdev->binary_ok)
+ target = target->strm;
+ if (pdf_end_encrypt(pdev))
+ target = target->strm;
+ s_close_filters(&pdev->strm, target);
+
s = pdev->strm;
length = pdf_stell(pdev) - pdev->contents_pos;
if (pdev->PDFA != 0)
@@ -2014,13 +1998,18 @@ pdf_unclip(gx_device_pdf * pdev)
/* ------ Miscellaneous output ------ */
/* Generate the default Producer string. */
+/* This calculation is also performed for Ghostscript generally
+ * The code is in ghostpdl/base/gsmisc.c printf_program_ident().
+ * Should we change this calculation both sets of code need to be updated.
+ */
void
pdf_store_default_Producer(char buf[PDF_MAX_PRODUCER])
{
- if ((gs_revision % 100) == 0)
- gs_sprintf(buf, "(%s %1.1f)", gs_product, gs_revision / 100.0);
- else
- gs_sprintf(buf, "(%s %1.2f)", gs_product, gs_revision / 100.0);
+ 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);
}
/* Write matrix values. */
@@ -2133,6 +2122,10 @@ pdf_encrypt_encoded_string(const gx_device_pdf *pdev, const byte *str, uint size
break;
}
}
+ /* Another case where we use sclose() and not sclose_filters(), because the
+ * buffer we supplied to s_init_filter is a heap based C object, so we
+ * must not free it.
+ */
sclose(&sout); /* Writes ')'. */
return (int)stell(&sinp) + 1;
}
@@ -2697,7 +2690,7 @@ pdf_function_aux(gx_device_pdf *pdev, const gs_function_t *pfn,
stream_write(writer.strm, ptr, count);
}
code = psdf_end_binary(&writer);
- sclose(s);
+ s_close_filters(&s, s->strm);
}
pdev->strm = save;
if (code < 0)
diff --git a/devices/vector/gdevpdfv.c b/devices/vector/gdevpdfv.c
index 2f71d86a..dd7d4c7c 100644
--- a/devices/vector/gdevpdfv.c
+++ b/devices/vector/gdevpdfv.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdfx.h b/devices/vector/gdevpdfx.h
index 0e43a028..c8b44b46 100644
--- a/devices/vector/gdevpdfx.h
+++ b/devices/vector/gdevpdfx.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -41,7 +41,11 @@
* Windows and Linux fail with coordinates outside +/- 16383. Hence, we
* limit coordinates to 16k, with a little slop.
*/
-#define MAX_USER_COORD 16300
+/* 28/05/2020 This was only being applied to text and a subset of paths. Since
+ * Acrobat 4 is now more than 20 years old, lets just drop support for it. The
+ * PDF specification never had this limit, just Adobe's software.
+ */
+/* #define MAX_USER_COORD 16300 */
/* ---------------- Statically allocated sizes ---------------- */
/* These should really be dynamic.... */
@@ -1168,7 +1172,12 @@ int pdf_copy_data_safe(stream *s, gp_file *file, gs_offset_t position, long coun
/* Add the encryption filter. */
int pdf_begin_encrypt(gx_device_pdf * pdev, stream **s, gs_id object_id);
/* Remove the encryption filter. */
-void pdf_end_encrypt(gx_device_pdf * pdev);
+static int inline pdf_end_encrypt(gx_device_pdf *pdev)
+{
+ if (pdev->KeyLength)
+ return 1;
+ return 0;
+}
/* Initialize encryption. */
int pdf_encrypt_init(const gx_device_pdf * pdev, gs_id object_id, stream_arcfour_state *psarc4);
diff --git a/devices/vector/gdevpdt.c b/devices/vector/gdevpdt.c
index 6a3b5a7f..970dd76a 100644
--- a/devices/vector/gdevpdt.c
+++ b/devices/vector/gdevpdt.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdt.h b/devices/vector/gdevpdt.h
index a4e736db..ee7a1c1e 100644
--- a/devices/vector/gdevpdt.h
+++ b/devices/vector/gdevpdt.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdtb.c b/devices/vector/gdevpdtb.c
index 9caa640e..61961c4a 100644
--- a/devices/vector/gdevpdtb.c
+++ b/devices/vector/gdevpdtb.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -359,7 +359,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%lx", (ulong)copied);
+ gs_sprintf(fnbuf, ".F" PRI_INTPTR, (intptr_t)copied);
font_name.data = (byte *)fnbuf;
font_name.size = strlen(fnbuf);
}
diff --git a/devices/vector/gdevpdtb.h b/devices/vector/gdevpdtb.h
index 1e160eb1..8753aa98 100644
--- a/devices/vector/gdevpdtb.h
+++ b/devices/vector/gdevpdtb.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdtc.c b/devices/vector/gdevpdtc.c
index 95af86ff..5c6da535 100644
--- a/devices/vector/gdevpdtc.c
+++ b/devices/vector/gdevpdtc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdtd.c b/devices/vector/gdevpdtd.c
index 45e2888e..ce6efa05 100644
--- a/devices/vector/gdevpdtd.c
+++ b/devices/vector/gdevpdtd.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdtd.h b/devices/vector/gdevpdtd.h
index 9c3078e2..92e64758 100644
--- a/devices/vector/gdevpdtd.h
+++ b/devices/vector/gdevpdtd.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdte.c b/devices/vector/gdevpdte.c
index 3e7e2237..6f0eb158 100644
--- a/devices/vector/gdevpdte.c
+++ b/devices/vector/gdevpdte.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -160,6 +160,8 @@ pdf_add_ToUnicode(gx_device_pdf *pdev, gs_font *font, pdf_font_resource_t *pdfon
if (pdfont->cmap_ToUnicode != NULL)
gs_cmap_ToUnicode_add_pair(pdfont->cmap_ToUnicode, ch, unicode, length);
+ if (length > 2 && pdfont->u.simple.Encoding != NULL)
+ pdfont->TwoByteToUnicode = 0;
}
if (unicode)
gs_free_object(pdev->memory, unicode, "temporary Unicode array");
diff --git a/devices/vector/gdevpdtf.c b/devices/vector/gdevpdtf.c
index d14fa346..c823b18c 100644
--- a/devices/vector/gdevpdtf.c
+++ b/devices/vector/gdevpdtf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -572,6 +572,7 @@ font_resource_simple_alloc(gx_device_pdf *pdev, pdf_font_resource_t **ppfres,
pfres->u.simple.BaseEncoding = -1;
pfres->u.simple.preferred_encoding_index = -1;
pfres->u.simple.last_reserved_char = -1;
+ pfres->TwoByteToUnicode = 1;
*ppfres = pfres;
return 0;
}
diff --git a/devices/vector/gdevpdtf.h b/devices/vector/gdevpdtf.h
index 4a9e8961..f0006641 100644
--- a/devices/vector/gdevpdtf.h
+++ b/devices/vector/gdevpdtf.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -203,6 +203,15 @@ struct pdf_font_resource_s {
gs_cmap_t *cmap_ToUnicode; /* CMap (not used for CIDFonts) */
gs_glyph_mark_proc_t mark_glyph;
void *mark_glyph_data; /* closure data */
+
+ /* We use this when determining whether we should use an existing ToUnicode
+ * CMap or just use the Encoding, for s aimple font. Even if the Encoding
+ * only uses named glyphs, with names we can understand, the original
+ * ToUnicode may have mapped these in a non-standard way.
+ * See Bug #702201 where the ffi ligature is mapped to 3 code points
+ */
+ int TwoByteToUnicode;
+
union {
struct /*type0*/ {
@@ -253,7 +262,6 @@ struct pdf_font_resource_s {
gs_point *v; /* [256], glyph origin for WMode 1 */
int last_reserved_char; /* Except for synthesised Type 3,
which stores such data in LastChar */
-
gs_glyph standard_glyph_code_for_notdef;
union {
diff --git a/devices/vector/gdevpdti.c b/devices/vector/gdevpdti.c
index 7ba56fd6..0205604a 100644
--- a/devices/vector/gdevpdti.c
+++ b/devices/vector/gdevpdti.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -479,7 +479,9 @@ pdf_end_char_proc(gx_device_pdf * pdev, pdf_stream_position_t * ppos)
stream *s;
gs_offset_t start_pos, end_pos, length;
- pdf_end_encrypt(pdev);
+ if (pdf_end_encrypt(pdev))
+ s_close_filters(&pdev->strm, pdev->strm->strm);
+
s = pdev->strm;
start_pos = ppos->start_pos;
end_pos = stell(s);
diff --git a/devices/vector/gdevpdti.h b/devices/vector/gdevpdti.h
index 65e1efcb..81409e67 100644
--- a/devices/vector/gdevpdti.h
+++ b/devices/vector/gdevpdti.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdts.c b/devices/vector/gdevpdts.c
index 055aeb44..aa41f516 100644
--- a/devices/vector/gdevpdts.c
+++ b/devices/vector/gdevpdts.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -81,11 +81,6 @@ append_text_move(pdf_text_state_t *pts, double dw)
rounded = floor(dw + 0.5);
if (fabs(dw - rounded) < 0.001)
dw = rounded;
- if (dw < -MAX_USER_COORD) {
- /* Acrobat reader 4.0c, 5.0 can't handle big offsets.
- Adobe Reader 6 can. */
- return -1;
- }
if (dw != 0) {
if (count == MAX_TEXT_BUFFER_MOVES)
return -1;
@@ -173,47 +168,11 @@ add_text_delta_move(gx_device_pdf *pdev, const gs_matrix *pmat)
* for the xhow and once for the Width override. Otherwise, we do
* want to use TJ as it makes for smaller files.
*/
- if (pts->can_use_TJ && dnotw == 0 && pts->buffer.count_chars > 0 &&
- /*
- * Acrobat Reader limits the magnitude of user-space
- * coordinates. Also, AR apparently doesn't handle large
- * positive movement values (negative X displacements), even
- * though the PDF Reference says this bug was fixed in AR3.
- *
- * Old revisions used the upper threshold 1000 for tdw,
- * but it appears too big when a font sets a too big
- * character width in setcachedevice. Particularly this happens
- * with a Type 3 font generated by Aldus Freehand 4.0
- * to represent a texture - see bug #687051.
- * The problem is that when the Widths is multiplied
- * to the font size, the viewer represents the result
- * with insufficient fraction bits to represent the precise width.
- * We work around that problem here restricting tdw
- * with a smaller threshold 990. Our intention is to
- * disable Tj when the real glyph width appears smaller
- * than 1% of the width specified in setcachedevice.
- * A Td instruction will be generated instead.
- * Note that the value 990 is arbitrary and may need a
- * further adjustment.
- */
- /* Revised the above. It seems unreasonable to use a fixed
- * value which is not based on the point size, when the problem is
- * caused by a large point size being multiplied by the width. The
- * original fix also caused bitmap fonts (from PCL and other sources)
- * to fail to use kerning, as these fonts are scaled to 1 point and
- * therefore use large kerning values. Instead we check the kerned value
- * multiplied by the point size of the font.
- */
- (tdw >= -MAX_USER_COORD && (tdw * pts->in.size) < MAX_USER_COORD)
- ) {
+ if (pts->can_use_TJ && dnotw == 0 && pts->buffer.count_chars > 0) {
/* Use TJ. */
int code;
- if (tdw < MAX_USER_COORD || pdev->CompatibilityLevel > 1.4)
- code = append_text_move(pts, tdw);
- else
- return -1;
-
+ code = append_text_move(pts, tdw);
if (code >= 0)
goto finish;
}
diff --git a/devices/vector/gdevpdts.h b/devices/vector/gdevpdts.h
index cde7a3c8..b3699eb2 100644
--- a/devices/vector/gdevpdts.h
+++ b/devices/vector/gdevpdts.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdtt.c b/devices/vector/gdevpdtt.c
index f248e998..5884115e 100644
--- a/devices/vector/gdevpdtt.c
+++ b/devices/vector/gdevpdtt.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdtt.h b/devices/vector/gdevpdtt.h
index cf3b7625..9a710151 100644
--- a/devices/vector/gdevpdtt.h
+++ b/devices/vector/gdevpdtt.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdtv.c b/devices/vector/gdevpdtv.c
index eb9a18fe..a16a48d7 100644
--- a/devices/vector/gdevpdtv.c
+++ b/devices/vector/gdevpdtv.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdtv.h b/devices/vector/gdevpdtv.h
index 89502365..5e27ecd1 100644
--- a/devices/vector/gdevpdtv.h
+++ b/devices/vector/gdevpdtv.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdtw.c b/devices/vector/gdevpdtw.c
index be3c874d..6d197bd5 100644
--- a/devices/vector/gdevpdtw.c
+++ b/devices/vector/gdevpdtw.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -119,6 +119,9 @@ pdf_simple_font_needs_ToUnicode(const pdf_font_resource_t *pdfont)
In this circumstance, write the ToUnicode map to get a searchable PDF.
*/
return true;
+ if (!pdfont->TwoByteToUnicode)
+ return true;
+
for (ch = 0; ch < 256; ++ch) {
pdf_encoding_element_t *pet = &pdfont->u.simple.Encoding[ch];
gs_glyph glyph = pet->glyph;
@@ -136,6 +139,7 @@ pdf_simple_font_needs_ToUnicode(const pdf_font_resource_t *pdfont)
if( glyph > GS_C_PDF_MAX_GOOD_GLYPH ||
!(gs_c_pdf_glyph_type[glyph >> 2] & (mask << (( glyph & 3 )<<1) )))
return true;
+
}
return false;
}
diff --git a/devices/vector/gdevpdtw.h b/devices/vector/gdevpdtw.h
index 4ff32453..34feeed2 100644
--- a/devices/vector/gdevpdtw.h
+++ b/devices/vector/gdevpdtw.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpdtx.h b/devices/vector/gdevpdtx.h
index 92374aa0..d5fe6177 100644
--- a/devices/vector/gdevpdtx.h
+++ b/devices/vector/gdevpdtx.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpsdf.h b/devices/vector/gdevpsdf.h
index 5047f43a..a20c61b0 100644
--- a/devices/vector/gdevpsdf.h
+++ b/devices/vector/gdevpsdf.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -194,7 +194,7 @@ extern const stream_template s_zlibE_template;
500000, /* ImageMemory */ \
0, /* LockDistillerParams (false) */ \
0, /* LZWEncodePages (false) */ \
- 1, /* Overprintmode (OPM) */ \
+ 0, /* Overprintmode (OPM) */ \
0, /* PreserveOPIComments (false) */ \
1, /* UseFlateCompression (true) */ \
/* Color processing parameters */\
@@ -332,8 +332,7 @@ extern_st(st_device_psdf);
params.MonoImage.Dict),\
GC_OBJ_ELT2(gx_device_psdf, params.AlwaysEmbed.data,\
params.NeverEmbed.data),\
- GC_CONST_STRING_ELT(gx_device_psdf, params.PSDocOptions),\
- GC_OBJ_ELT(gx_device_psdf, params.PSPageOptions.data)\
+ GC_CONST_STRING_ELT(gx_device_psdf, params.PSDocOptions)\
};\
gs_public_st_basic_super_final(st_device_psdf, gx_device_psdf,\
"gx_device_psdf", device_psdf_ptrs, device_psdf_data,\
diff --git a/devices/vector/gdevpsdi.c b/devices/vector/gdevpsdi.c
index 9c2adb72..f093edf1 100644
--- a/devices/vector/gdevpsdi.c
+++ b/devices/vector/gdevpsdi.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -529,7 +529,7 @@ setup_downsampling(psdf_binary_writer * pbw, const psdf_image_params * pdip,
ss->params.EntireWidthIn = ss->params.WidthIn = ss->params.PatchWidthIn = pim->Width;
ss->params.EntireHeightIn = ss->params.HeightIn = ss->params.PatchHeightIn = pim->Height;
ss->params.EntireWidthOut = ss->params.WidthOut = ss->params.PatchWidthOut = s_Downsample_size_out(pim->Width, factor, false);
- ss->params.EntireHeightOut = ss->params.HeightOut = s_Downsample_size_out(pim->Height, factor, false);
+ ss->params.EntireHeightOut = ss->params.HeightOut = ss->params.PatchHeightOut = ss->params.PatchHeightOut2 = s_Downsample_size_out(pim->Height, factor, false);
/* Bug #697944 The code below to apply the downsampling filter always
* resizes the input data to the filter with 8BPC and then resizes the output back to whatever
@@ -539,8 +539,8 @@ setup_downsampling(psdf_binary_writer * pbw, const psdf_image_params * pdip,
ss->params.BitsPerComponentIn = ss->params.BitsPerComponentOut = 8;
ss->params.spp_interp = ss->params.spp_decode = Colors;
- ss->params.TopMarginIn = ss->params.TopMarginOut = ss->params.LeftMarginIn = ss->params.LeftMarginOut = 0;
- ss->params.src_y_offset = 0;
+ ss->params.TopMarginIn = ss->params.TopMarginOut = ss->params.TopMarginOut2 = ss->params.LeftMarginIn = ss->params.LeftMarginOut = 0;
+ ss->params.src_y_offset = ss->params.pad_y = 0;
ss->params.early_cm = true;
ss->params.MaxValueIn = ss->params.MaxValueOut = (int)pow(2, pdip->Depth);
diff --git a/devices/vector/gdevpsdp.c b/devices/vector/gdevpsdp.c
index bda3fe2a..c8a48ee5 100644
--- a/devices/vector/gdevpsdp.c
+++ b/devices/vector/gdevpsdp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -232,7 +232,7 @@ static const gs_param_item_t psdf_param_items[] = {
/* (DefaultRenderingIntent) */
pi("DetectBlends", gs_param_type_bool, DetectBlends),
pi("DoThumbnails", gs_param_type_bool, DoThumbnails),
- pi("ImageMemory", gs_param_type_long, ImageMemory),
+ pi("ImageMemory", gs_param_type_size_t, ImageMemory),
/* (LockDistillerParams) */
pi("LZWEncodePages", gs_param_type_bool, LZWEncodePages),
pi("OPM", gs_param_type_int, OPM),
@@ -625,6 +625,10 @@ gdev_psdf_get_params(gx_device * dev, gs_param_list * plist)
if (code < 0)
return code;
+ code = param_write_string_array(plist, "PSPageOptions", &pdev->params.PSPageOptions);
+ if (code < 0)
+ return code;
+
code = psdf_write_name(plist, "CannotEmbedFontPolicy",
CannotEmbedFontPolicy_names[(int)pdev->params.CannotEmbedFontPolicy]);
@@ -1040,6 +1044,65 @@ psdf_put_image_params(const gx_device_psdf * pdev, gs_param_list * plist,
return ecode;
}
+/* This is a convenience routine. There doesn't seem to be any way to have a param_string_array
+ * enumerated for garbage collection, and we have (currently) three members of the psdf_distiller_params
+ * structure which store param_string_array. If the interpreter is using garbage collection then there
+ * is the potential for the array, or its contents, to be relocated or freed while we are still
+ * maintaining pointers to them, unless we enumerate the pointers.
+ * Instead, we'll copy the string data from the interpreter, make our own param_string_array, and
+ * manage the memory ourselves. This allows us to move the data into non-GC memory which is preferable
+ * anyway.
+ */
+static int psdf_copy_param_string_array(gs_memory_t *mem, gs_param_list * plist, gs_param_string_array *sa, gs_param_string_array *da)
+{
+ int code;
+
+ if (sa->size > 0) {
+ int ix;
+ byte **dest;
+
+ if (da->data != NULL) {
+ for (ix = 0; ix < da->size;ix++)
+ gs_free_object(mem->non_gc_memory, (byte *)da->data[ix].data, "freeing old string array copy");
+ gs_free_object(mem->non_gc_memory, (byte *)da->data, "freeing old string array");
+ }
+ da->data = (const gs_param_string *)gs_alloc_bytes(mem->non_gc_memory, sa->size * sizeof(gs_param_string), "allocate new string array");
+ if (da->data == NULL)
+ return_error(gs_note_error(gs_error_VMerror));
+ memset((byte *)da->data, 0x00, sa->size * sizeof(gs_param_string));
+ da->size = sa->size;
+ da->persistent = false;
+
+ for(ix=0;ix < sa->size;ix++) {
+ ((gs_param_string *)&da->data[ix])->data = gs_alloc_bytes(mem->non_gc_memory, sa->data[ix].size, "allocate new strings");
+ if (da->data[ix].data == NULL)
+ return_error(gs_note_error(gs_error_VMerror));
+ memcpy((byte *)(da->data[ix].data), sa->data[ix].data, sa->data[ix].size);
+ ((gs_param_string *)&da->data[ix])->size = sa->data[ix].size;
+ ((gs_param_string *)&da->data[ix])->persistent = false;
+ }
+ gs_free_object(plist->memory, (byte *)sa->data, "freeing temporary param string array");
+ sa->data = NULL;
+ sa->size = 0;
+ }
+ return 0;
+}
+
+static int psdf_read_copy_param_string_array(gs_memory_t *mem, gs_param_list * plist, char *Key, gs_param_string_array *da)
+{
+ gs_param_string_array sa;
+ int code;
+
+ code = param_read_embed_array(plist, Key, &sa);
+ if (code < 0)
+ return code;
+
+ if(sa.size)
+ code = psdf_copy_param_string_array(mem, plist, &sa, da);
+
+ return code;
+}
+
/* Put parameters. */
int
gdev_psdf_put_params(gx_device * dev, gs_param_list * plist)
@@ -1076,6 +1139,8 @@ gdev_psdf_put_params(gx_device * dev, gs_param_list * plist)
params.MonoImage.ACSDict = params.MonoImage.Dict = 0;
params.AlwaysEmbed.data = params.NeverEmbed.data = 0;
params.AlwaysEmbed.size = params.AlwaysEmbed.persistent = params.NeverEmbed.size = params.NeverEmbed.persistent = 0;
+ params.PSPageOptions.data = NULL;
+ params.PSPageOptions.size = 0;
}
/* General parameters. */
@@ -1184,6 +1249,7 @@ gdev_psdf_put_params(gx_device * dev, gs_param_list * plist)
&params.AlwaysEmbed, mem, ecode);
ecode = psdf_put_embed_param(plist, "~NeverEmbed", ".NeverEmbed",
&params.NeverEmbed, mem, ecode);
+
params.CannotEmbedFontPolicy = (enum psdf_cannot_embed_font_policy)
psdf_put_enum(plist, "CannotEmbedFontPolicy",
(int)params.CannotEmbedFontPolicy,
@@ -1199,7 +1265,7 @@ gdev_psdf_put_params(gx_device * dev, gs_param_list * plist)
if (code < 0)
goto exit;
- code = param_read_embed_array(plist, "PSPageOptions", &params.PSPageOptions);
+ code = psdf_read_copy_param_string_array(pdev->memory, plist, "PSPageOptions", &params.PSPageOptions);
if (code < 0)
goto exit;
@@ -1208,6 +1274,14 @@ gdev_psdf_put_params(gx_device * dev, gs_param_list * plist)
exit:
if (!(pdev->params.LockDistillerParams && params.LockDistillerParams)) {
/* Only update the device paramters if there was no error */
+ /* If we have any copied param_string_arrays, start by freeing them */
+ if (pdev->params.PSPageOptions.size && params.PSPageOptions.size) {
+ int ix;
+
+ for (ix = 0; ix < pdev->params.PSPageOptions.size;ix++)
+ gs_free_object(mem->non_gc_memory, (byte *)pdev->params.PSPageOptions.data[ix].data, "freeing old string array copy");
+ gs_free_object(mem->non_gc_memory, (byte *)pdev->params.PSPageOptions.data, "freeing old string array");
+ }
pdev->params = params;
} else {
/* We read a bunch of parameters and are now throwing them away. Either because there
@@ -1216,10 +1290,15 @@ exit:
*/
gs_memory_t *stable_mem = gs_memory_stable(mem);
- if (params.NeverEmbed.data != 0)
- gs_free_object(stable_mem, (void *)params.NeverEmbed.data, "free dummy param NeverEmbed");
- if (params.AlwaysEmbed.data != 0)
- gs_free_object(stable_mem, (void *)params.AlwaysEmbed.data, "free dummy param AlwaysEmbed");
+ if (params.PSPageOptions.data != NULL) {
+ int ix;
+
+ for (ix = 0; ix < pdev->params.PSPageOptions.size;ix++)
+ gs_free_object(mem->non_gc_memory, (byte *)pdev->params.PSPageOptions.data[ix].data, "freeing dummy PSPageOptions");
+ gs_free_object(mem->non_gc_memory, (byte *)pdev->params.PSPageOptions.data, "freeing dummy PSPageOptions");
+ params.PSPageOptions.data = NULL;
+ params.PSPageOptions.size = 0;
+ }
if (params.CalCMYKProfile.data != 0)
gs_free_string(stable_mem, (void *)params.CalCMYKProfile.data, params.CalCMYKProfile.size, "free dummy param CalCMYKProfile");
if (params.CalGrayProfile.data != 0)
diff --git a/devices/vector/gdevpsds.c b/devices/vector/gdevpsds.c
index 65bbf544..bc932902 100644
--- a/devices/vector/gdevpsds.c
+++ b/devices/vector/gdevpsds.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -822,7 +822,8 @@ s_Bicubic_data_at(stream_Bicubic_state *const ss, int x, int y, int c)
y = ss->HeightIn - 1;
y -= ss->y_in;
idx = ss->l_size * (y < 0 ? 0 : y) +
- (x < 0 ? 0 : x >= ss->WidthIn ? ss->WidthIn-1 : x) * ss->Colors + c;
+ (size_t)(x < 0 ? 0 : x >= ss->WidthIn ? ss->WidthIn-1 : x) *
+ ss->Colors + c;
return (idx < ss->d_len) ? ss->data[idx] : 0;
}
@@ -952,7 +953,8 @@ s_compr_chooser_set_dimensions(stream_compr_chooser_state * ss, int width,
ss->height = height;
ss->depth = depth;
ss->bits_per_sample = bits_per_sample;
- ss->sample = gs_alloc_bytes(ss->memory, width * depth, "s_compr_chooser_set_dimensions");
+ ss->sample = gs_alloc_bytes(ss->memory, (size_t)width * depth,
+ "s_compr_chooser_set_dimensions");
if (ss->sample == 0)
return_error(gs_error_VMerror);
return 0;
diff --git a/devices/vector/gdevpsds.h b/devices/vector/gdevpsds.h
index 35a756f0..207e54c4 100644
--- a/devices/vector/gdevpsds.h
+++ b/devices/vector/gdevpsds.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpsdu.c b/devices/vector/gdevpsdu.c
index d626358a..c4be6ac0 100644
--- a/devices/vector/gdevpsdu.c
+++ b/devices/vector/gdevpsdu.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpsf.h b/devices/vector/gdevpsf.h
index 275e526d..9105eb86 100644
--- a/devices/vector/gdevpsf.h
+++ b/devices/vector/gdevpsf.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpsf1.c b/devices/vector/gdevpsf1.c
index 7e167b45..feed79eb 100644
--- a/devices/vector/gdevpsf1.c
+++ b/devices/vector/gdevpsf1.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpsf2.c b/devices/vector/gdevpsf2.c
index 985cd25e..3c38e988 100644
--- a/devices/vector/gdevpsf2.c
+++ b/devices/vector/gdevpsf2.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -703,7 +703,7 @@ cff_write_Top_fdarray(cff_writer_t *pcw, gs_font_base *pbfont,
gs_font_info_t info;
cff_get_Top_info_common(pcw, pbfont, false, &info);
- cff_write_Top_common(pcw, pbfont, false, &info);
+ cff_write_Top_common(pcw, pbfont, true, &info);
cff_put_int(pcw, Private_size);
cff_put_int_value(pcw, Private_offset, TOP_Private);
if (pfname->size == 0)
diff --git a/devices/vector/gdevpsfm.c b/devices/vector/gdevpsfm.c
index fea025ef..b38266c2 100644
--- a/devices/vector/gdevpsfm.c
+++ b/devices/vector/gdevpsfm.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpsft.c b/devices/vector/gdevpsft.c
index 970a3149..9bc00312 100644
--- a/devices/vector/gdevpsft.c
+++ b/devices/vector/gdevpsft.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpsfu.c b/devices/vector/gdevpsfu.c
index 157c7bab..e848bdc8 100644
--- a/devices/vector/gdevpsfu.c
+++ b/devices/vector/gdevpsfu.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpsfx.c b/devices/vector/gdevpsfx.c
index b839f9e8..43459327 100644
--- a/devices/vector/gdevpsfx.c
+++ b/devices/vector/gdevpsfx.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpsu.c b/devices/vector/gdevpsu.c
index 094ff945..5e3e5a2b 100644
--- a/devices/vector/gdevpsu.c
+++ b/devices/vector/gdevpsu.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpsu.h b/devices/vector/gdevpsu.h
index 70cceeaf..c62ed8c6 100644
--- a/devices/vector/gdevpsu.h
+++ b/devices/vector/gdevpsu.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevpx.c b/devices/vector/gdevpx.c
index a1fce1b7..5195339f 100644
--- a/devices/vector/gdevpx.c
+++ b/devices/vector/gdevpx.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/gdevtxtw.c b/devices/vector/gdevtxtw.c
index 87f9355d..d46a935e 100644
--- a/devices/vector/gdevtxtw.c
+++ b/devices/vector/gdevtxtw.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -34,6 +34,7 @@
#include "gxdevsop.h"
#include "gzpath.h"
#include "gdevkrnlsclass.h" /* 'standard' built in subclasses, currently First/Last Page and obejct filter */
+#include "gxchar.h"
/* #define TRACE_TXTWRITE 1 */
@@ -73,6 +74,7 @@ typedef struct text_list_entry_s {
gs_point end;
gs_point FontBBox_bottomleft, FontBBox_topright;
float *Widths;
+ float *Advs;
unsigned short *Unicode_Text;
int Unicode_Text_Size;
int render_mode;
@@ -140,10 +142,14 @@ static dev_proc_dev_spec_op(txtwrite_dev_spec_op);
/* Define the text enumerator. */
typedef struct textw_text_enum_s {
gs_text_enum_common;
+ gs_text_enum_t *pte_fallback;
+ double d1_width;
+ bool d1_width_set;
bool charproc_accum;
bool cdevproc_callout;
double cdevproc_result[10];
float *Widths;
+ float *Advs;
unsigned short *TextBuffer;
int TextBufferIndex;
text_list_entry_t *text_state;
@@ -289,7 +295,7 @@ txtwrite_close_device(gx_device * dev)
}
#ifdef TRACE_TXTWRITE
- fclose(tdev->DebugFile);
+ gp_fclose(tdev->DebugFile);
#endif
return code;
}
@@ -339,14 +345,14 @@ static int merge_vertically(gx_device_txtwrite_t *tdev)
to = y_list->x_ordered_list;
from = next->x_ordered_list;
#ifdef TRACE_TXTWRITE
- fprintf(tdev->DebugFile, "\nConsolidating two horizontal lines, line 1:");
+ gp_fprintf(tdev->DebugFile, "\nConsolidating two horizontal lines, line 1:");
debug_x = from;
while (debug_x) {
gp_fprintf(tdev->DebugFile, "\n\t");
gp_fwrite(debug_x->Unicode_Text, sizeof(unsigned short), debug_x->Unicode_Text_Size, tdev->DebugFile);
debug_x = debug_x->next;
}
- fprintf(tdev->DebugFile, "\nConsolidating two horizontal lines, line 2");
+ gp_fprintf(tdev->DebugFile, "\nConsolidating two horizontal lines, line 2");
debug_x = to;
while (debug_x) {
gp_fprintf(tdev->DebugFile, "\n\t");
@@ -384,14 +390,14 @@ static int merge_vertically(gx_device_txtwrite_t *tdev)
}
y_list->x_ordered_list = new_order;
#ifdef TRACE_TXTWRITE
- fprintf(tdev->DebugFile, "\nAfter:");
+ gp_fprintf(tdev->DebugFile, "\nAfter:");
debug_x = new_order;
while (debug_x) {
gp_fprintf(tdev->DebugFile, "\n\t");
gp_fwrite(debug_x->Unicode_Text, sizeof(unsigned short), debug_x->Unicode_Text_Size, tdev->DebugFile);
debug_x = debug_x->next;
}
- fprintf(tdev->DebugFile, "\n");
+ gp_fprintf(tdev->DebugFile, "\n");
#endif
y_list->next = next->next;
if (next->next)
@@ -830,6 +836,46 @@ static int decorated_text_output(gx_device_txtwrite_t *tdev)
return 0;
}
+static int extract_text_output(gx_device_txtwrite_t *tdev)
+{
+ text_list_entry_t* entry;
+ gp_fprintf(tdev->file, "<page>\n");
+ for (entry = tdev->PageData.unsorted_text_list;
+ entry;
+ entry = entry->next
+ ) {
+ float x = entry->start.x;
+ int i;
+ gp_fprintf(tdev->file,
+ "<span bbox=\"%0.4f %0.4f %0.4f %0.4f\" font=\"%s\" size=\"%0.4f\">\n",
+ entry->start.x,
+ entry->start.y,
+ entry->end.x,
+ entry->end.y,
+ entry->FontName,
+ entry->size
+ );
+ for (i=0; i<entry->Unicode_Text_Size; i++) {
+ float x_next = x + entry->Widths[i];
+ char escaped[32];
+ escaped_Unicode(entry->Unicode_Text[i], escaped);
+ gp_fprintf(tdev->file,
+ "<char bbox=\"%0.4f %0.4f %0.4f %0.4f\" c=\"%s\" adv=\"%0.4f\"/>\n",
+ x,
+ entry->start.y,
+ x_next,
+ entry->end.y,
+ escaped,
+ entry->Advs[i]
+ );
+ x = x_next;
+ }
+ gp_fprintf(tdev->file, "</span>\n");
+ }
+ gp_fprintf(tdev->file, "</page>\n");
+ return 0;
+}
+
static int
txtwrite_output_page(gx_device * dev, int num_copies, int flush)
{
@@ -866,6 +912,12 @@ txtwrite_output_page(gx_device * dev, int num_copies, int flush)
return code;
break;
+ case 4:
+ code = extract_text_output(tdev);
+ if (code < 0)
+ return code;
+ break;
+
default:
return gs_note_error(gs_error_rangecheck);
break;
@@ -882,6 +934,7 @@ txtwrite_output_page(gx_device * dev, int num_copies, int flush)
while (x_entry) {
gs_free(tdev->memory, x_entry->Unicode_Text, x_entry->Unicode_Text_Size, sizeof (usnigned short), "txtwrite free text fragment text buffer");
gs_free(tdev->memory, x_entry->Widths, x_entry->Unicode_Text_Size, sizeof (float), "txtwrite free widths array");
+ gs_free(tdev->memory, x_entry->Advs, x_entry->Unicode_Text_Size, sizeof (float), "txtwrite free advs array");
gs_free(tdev->memory, x_entry->FontName, 1, strlen(x_entry->FontName) + 1, "txtwrite free Font Name");
if (x_entry->next) {
x_entry = x_entry->next;
@@ -907,6 +960,7 @@ txtwrite_output_page(gx_device * dev, int num_copies, int flush)
next_x = x_entry->next;
gs_free(tdev->memory, x_entry->Unicode_Text, x_entry->Unicode_Text_Size, sizeof (usnigned short), "txtwrite free unsorted text fragment text buffer");
gs_free(tdev->memory, x_entry->Widths, x_entry->Unicode_Text_Size, sizeof (float), "txtwrite free widths array");
+ gs_free(tdev->memory, x_entry->Advs, x_entry->Unicode_Text_Size, sizeof (float), "txtwrite free advs array");
gs_free(tdev->memory, x_entry->FontName, 1, strlen(x_entry->FontName) + 1, "txtwrite free Font Name");
gs_free(tdev->memory, x_entry, 1, sizeof(text_list_entry_t), "txtwrite free unsorted text fragment");
x_entry = next_x;
@@ -1487,6 +1541,9 @@ get_missing_width(gs_font *font, int wmode, const gs_matrix *scale_c,
FONT_INFO_MISSING_WIDTH, &finfo);
if (code < 0)
return code;
+ if (!(finfo.members & FONT_INFO_MISSING_WIDTH))
+ return_error(gs_error_undefined);
+
if (wmode) {
gs_distance_transform(0.0, -finfo.MissingWidth, scale_c, &pwidths->real_width.xy);
pwidths->Width.xy.x = 0;
@@ -1561,7 +1618,7 @@ txt_glyph_widths(gs_font *font, int wmode, gs_glyph glyph,
&& (code == gs_error_undefined || !(info.members & (GLYPH_INFO_WIDTH0 << wmode)))) {
code = get_missing_width(font, wmode, &scale_c, pwidths);
if (code < 0)
- v.y = 0;
+ return code;
else
v.y = pwidths->Width.v.y;
if (wmode && (ofont->FontType == ft_CID_encrypted ||
@@ -1812,11 +1869,11 @@ static int get_unicode(textw_text_enum_t *penum, gs_font *font, gs_glyph glyph,
#else
b = (char *)Buffer;
u = (char *)unicode;
- while (l >= 0) {
- *b++ = *(u + l);
- l--;
- }
+ for (l=0;l<length;l+=2, u+=2){
+ *b++ = *(u+1);
+ *b++ = *u;
+ }
#endif
gs_free_object(penum->dev->memory, unicode, "free temporary unicode buffer");
return length / sizeof(short);
@@ -1930,27 +1987,33 @@ txtwrite_process_plain_text(gs_text_enum_t *pte)
uint operation = pte->text.operation;
txt_glyph_widths_t widths;
gs_point wanted; /* user space */
- gs_point dpt = {0,0};
- for (i=0;i<pte->text.size;i++) {
+ for (i=pte->index;i<pte->text.size;i++) {
+ gs_point dpt = {0,0};
if (operation & (TEXT_FROM_STRING | TEXT_FROM_BYTES)) {
- ch = pte->text.data.bytes[pte->index++];
+ ch = pte->text.data.bytes[pte->index];
} else if (operation & (TEXT_FROM_CHARS | TEXT_FROM_SINGLE_CHAR)) {
- ch = pte->text.data.chars[pte->index++];
+ 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));
} else {
gdata = &pte->text.data.d_glyph;
- pte->index++;
}
}
glyph = (gdata == NULL ? pte->orig_font->procs.encode_char(pte->orig_font, ch, GLYPH_SPACE_NAME)
: *gdata);
code = txt_glyph_widths(font, font->WMode, glyph, (gs_font *)font, &widths, NULL);
- if (code < 0)
- return code;
+ if (code < 0) {
+ if (penum->d1_width_set) {
+ widths.Width.w = widths.Width.xy.x = widths.real_width.w = widths.real_width.xy.x = penum->d1_width;
+ penum->d1_width = 0;
+ penum->d1_width_set = 0;
+ }
+ else
+ return code;
+ }
penum->cdevproc_callout = false;
code = txt_update_text_state(penum->text_state, (textw_text_enum_t *)pte, pte->orig_font, &font->FontMatrix);
@@ -1963,7 +2026,8 @@ txtwrite_process_plain_text(gs_text_enum_t *pte)
&penum->text_state->matrix, &wanted);
pte->returned.total_width.x += wanted.x;
pte->returned.total_width.y += wanted.y;
- penum->Widths[pte->index - 1] = wanted.x;
+ penum->Widths[penum->TextBufferIndex] = wanted.x;
+ penum->Advs[penum->TextBufferIndex] = wanted.x;
if (pte->text.operation & TEXT_ADD_TO_ALL_WIDTHS) {
gs_point tpt;
@@ -1984,8 +2048,20 @@ txtwrite_process_plain_text(gs_text_enum_t *pte)
pte->returned.total_width.x += dpt.x;
pte->returned.total_width.y += dpt.y;
- penum->TextBufferIndex += get_unicode(penum, (gs_font *)pte->orig_font, glyph, ch, &penum->TextBuffer[penum->TextBufferIndex]);
- penum->Widths[pte->index - 1] += dpt.x;
+ penum->Widths[penum->TextBufferIndex] += dpt.x;
+ code = get_unicode(penum, (gs_font *)pte->orig_font, glyph, ch, &penum->TextBuffer[penum->TextBufferIndex]);
+ /* If a single text code returned multiple Unicode values, then we need to set the
+ * 'extra' code points' widths to 0.
+ */
+ if (code > 1) {
+ memset(&penum->Widths[penum->TextBufferIndex + 1], 0x00, (code - 1) * sizeof(float));
+ memset(&penum->Advs[penum->TextBufferIndex + 1], 0x00, (code - 1) * sizeof(float));
+ }
+ penum->TextBufferIndex += code;
+/* gs_moveto_aux(penum->pgs, gx_current_path(penum->pgs),
+ fixed2float(penum->origin.x) + wanted.x + dpt.x,
+ fixed2float(penum->origin.y) + wanted.y + dpt.y);*/
+ pte->index++;
}
return 0;
}
@@ -2020,7 +2096,7 @@ txt_add_sorted_fragment(gx_device_txtwrite_t *tdev, textw_text_enum_t *penum)
/* Already have text at this y-position */
text_list_entry_t *X_List = Y_List->x_ordered_list;
- while (X_List->next && X_List->start.x < penum->text_state->start.x)
+ while (X_List->next && X_List->start.x <= penum->text_state->start.x)
X_List = X_List->next;
if (X_List->start.x > penum->text_state->start.x) {
@@ -2095,6 +2171,20 @@ txt_add_fragment(gx_device_txtwrite_t *tdev, textw_text_enum_t *penum)
{
text_list_entry_t *unsorted_entry, *t;
+#ifdef TRACE_TXTWRITE
+ gp_fprintf(tdev->DebugFile, "txt_add_fragment: ");
+ gp_fwrite(penum->TextBuffer, sizeof(unsigned short), penum->TextBufferIndex, tdev->DebugFile);
+ gp_fprintf(tdev->DebugFile, "\n");
+ {
+ int i=0;
+ gp_fprintf(tdev->DebugFile, "widths:");
+ for (i=0; i<penum->TextBufferIndex; ++i) {
+ gp_fprintf(tdev->DebugFile, " %f", penum->Widths[i]);
+ }
+ gp_fprintf(tdev->DebugFile, "\n");
+ }
+#endif
+
/* Create a duplicate entry for the unsorted list */
unsorted_entry = (text_list_entry_t *)gs_malloc(tdev->memory->stable_memory, 1,
sizeof(text_list_entry_t), "txtwrite alloc sorted text state");
@@ -2122,8 +2212,14 @@ txt_add_fragment(gx_device_txtwrite_t *tdev, textw_text_enum_t *penum)
penum->TextBufferIndex, sizeof(float), "txtwrite alloc widths array");
if (!penum->text_state->Widths)
return gs_note_error(gs_error_VMerror);
+ penum->text_state->Advs = (float *)gs_malloc(tdev->memory->stable_memory,
+ penum->TextBufferIndex, sizeof(float), "txtwrite alloc widths array");
+ if (!penum->text_state->Advs)
+ return gs_note_error(gs_error_VMerror);
memset(penum->text_state->Widths, 0x00, penum->TextBufferIndex * sizeof(float));
- memcpy(penum->text_state->Widths, penum->Widths, penum->text.size * sizeof(float));
+ memcpy(penum->text_state->Widths, penum->Widths, penum->TextBufferIndex * sizeof(float));
+ memset(penum->text_state->Advs, 0x00, penum->TextBufferIndex * sizeof(float));
+ memcpy(penum->text_state->Advs, penum->Advs, penum->TextBufferIndex * sizeof(float));
unsorted_entry->Unicode_Text = (unsigned short *)gs_malloc(tdev->memory->stable_memory,
penum->TextBufferIndex, sizeof(unsigned short), "txtwrite alloc sorted text buffer");
@@ -2135,8 +2231,14 @@ txt_add_fragment(gx_device_txtwrite_t *tdev, textw_text_enum_t *penum)
penum->TextBufferIndex, sizeof(float), "txtwrite alloc widths array");
if (!unsorted_entry->Widths)
return gs_note_error(gs_error_VMerror);
+ unsorted_entry->Advs = (float *)gs_malloc(tdev->memory->stable_memory,
+ penum->TextBufferIndex, sizeof(float), "txtwrite alloc widths array");
+ if (!unsorted_entry->Advs)
+ return gs_note_error(gs_error_VMerror);
memset(unsorted_entry->Widths, 0x00, penum->TextBufferIndex * sizeof(float));
- memcpy(unsorted_entry->Widths, penum->Widths, penum->text.size * sizeof(float));
+ memcpy(unsorted_entry->Widths, penum->Widths, penum->TextBufferIndex * sizeof(float));
+ memset(unsorted_entry->Advs, 0x00, penum->TextBufferIndex * sizeof(float));
+ memcpy(unsorted_entry->Advs, penum->Advs, penum->TextBufferIndex * sizeof(float));
unsorted_entry->FontName = (char *)gs_malloc(tdev->memory->stable_memory,
(strlen(penum->text_state->FontName) + 1), sizeof(unsigned char), "txtwrite alloc sorted text buffer");
@@ -2175,10 +2277,20 @@ textw_text_process(gs_text_enum_t *pte)
gs_font *font = pte->orig_font;
gs_font_base *font_base = (gs_font_base *)pte->current_font;
int code = 0;
+ gs_text_enum_t *pte_fallback;
if (pte->text.size == 0)
return 0;
+ pte_fallback = penum->pte_fallback;
+ if (pte_fallback) {
+ code = gx_default_text_restore_state(pte_fallback);
+ if (code < 0)
+ return code;
+ gs_text_release(pte_fallback, "txtwrite_text_process");
+ }
+ pte_fallback = penum->pte_fallback = NULL;
+
if (!penum->TextBuffer) {
/* We can get up to 4 Unicode points per glyph, and a glyph can be
* be represented by as little as one byte. So we make a very large
@@ -2192,9 +2304,13 @@ textw_text_process(gs_text_enum_t *pte)
if (!penum->TextBuffer)
return gs_note_error(gs_error_VMerror);
penum->Widths = (float *)gs_malloc(tdev->memory->stable_memory,
- pte->text.size, sizeof(float), "txtwrite temporary widths array");
+ pte->text.size * 4, sizeof(float), "txtwrite temporary widths array");
if (!penum->Widths)
return gs_note_error(gs_error_VMerror);
+ penum->Advs = (float *)gs_malloc(tdev->memory->stable_memory,
+ pte->text.size * 4, sizeof(float), "txtwrite temporary advs array");
+ if (!penum->Advs)
+ return gs_note_error(gs_error_VMerror);
}
{
switch (font->FontType) {
@@ -2217,6 +2333,8 @@ textw_text_process(gs_text_enum_t *pte)
break;
}
if (code == 0) {
+ penum->d1_width = 0;
+ penum->d1_width_set = false;
if (font_base->FontBBox.p.x != font_base->FontBBox.q.x ||
font_base->FontBBox.p.y != font_base->FontBBox.q.y) {
gs_point p0, p1, p2, p3;
@@ -2239,6 +2357,29 @@ textw_text_process(gs_text_enum_t *pte)
return code;
code = txt_add_fragment(tdev, penum);
+ } else {
+ if (code == gs_error_unregistered) /* Debug purpose only. */
+ return code;
+ if (code == gs_error_VMerror)
+ return code;
+ if (code == gs_error_invalidfont) /* Bug 688370. */
+ return code;
+ /* Fall back to the default implementation. */
+ code = gx_default_text_begin(pte->dev, pte->pgs, &pte->text, pte->current_font,
+ pte->path, pte->pdcolor, pte->pcpath, pte->memory, &pte_fallback);
+ if (code < 0)
+ return code;
+ penum->pte_fallback = pte_fallback;
+ gs_text_enum_copy_dynamic(pte_fallback, pte, false);
+
+ code = gs_text_process(pte_fallback);
+ if (code != 0) {
+ penum->returned.current_char = pte_fallback->returned.current_char;
+ penum->returned.current_glyph = pte_fallback->returned.current_glyph;
+ return code;
+ }
+ gs_text_release(pte_fallback, "txtwrite_text_process");
+ penum->pte_fallback = 0;
}
}
return code;
@@ -2271,6 +2412,11 @@ textw_text_set_cache(gs_text_enum_t *pte, const double *pw,
switch (control) {
case TEXT_SET_CHAR_WIDTH:
case TEXT_SET_CACHE_DEVICE:
+ if (penum->pte_fallback != NULL) {
+ penum->d1_width = *pw;
+ penum->d1_width_set = true;
+ return 0;
+ }
return gs_text_set_cache(pte, pw, control);
case TEXT_SET_CACHE_DEVICE2:
if (penum->cdevproc_callout) {
@@ -2355,6 +2501,9 @@ txtwrite_text_begin(gx_device * dev, gs_gstate * pgs,
penum->TextBuffer = NULL;
penum->TextBufferIndex = 0;
penum->Widths = NULL;
+ penum->pte_fallback = NULL;
+ penum->d1_width = 0;
+ penum->d1_width_set = false;
/* The enumerator's text_release method frees this memory */
penum->text_state = (text_list_entry_t *)gs_malloc(tdev->memory->stable_memory, 1,
sizeof(text_list_entry_t), "txtwrite alloc text state");
diff --git a/devices/vector/gdevxps.c b/devices/vector/gdevxps.c
index 5d98c283..8eb26196 100644
--- a/devices/vector/gdevxps.c
+++ b/devices/vector/gdevxps.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -1868,7 +1868,7 @@ xps_begin_image(gx_device *dev, const gs_gstate *pgs,
rc_increment(pcs);
code = dev_proc(dev, get_profile)(dev, &(dev_profile));
/* Just use the "default" profile for now */
- icc_profile = dev_profile->device_profile[0];
+ icc_profile = dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
force8bit = true; /* Output image is 8 bit regardless of source */
} else {
/* An ICC, RGB, CMYK, Gray color space */
diff --git a/devices/vector/opdfread.ps b/devices/vector/opdfread.ps
index cff0498e..e0d6f112 100644
--- a/devices/vector/opdfread.ps
+++ b/devices/vector/opdfread.ps
@@ -1,6 +1,6 @@
%!PS-Adobe-2.0
%
-% Copyright (C) 2001-2019 Artifex Software, Inc.
+% Copyright (C) 2001-2020 Artifex Software, Inc.
% All Rights Reserved.
%
% This software is provided AS-IS with no warranty, either express or
@@ -46,25 +46,44 @@
% ====================== Error handler =======================
% A general error handler prints an error to page.
-currentdict /DSC_OPDFREAD known {
- % See if our notification from ps2write is present. If it is
- % then pick it up. Otherwise define it as false. Used to prevent
- % use of setmatrix at start of each page. The DSC-compliant
- % output from ps2write wraps pages in a save/restore, so we don't
- % need the setmatrix, and it breaks use of psnup with the output.
-
- currentdict /DSC_OPDFREAD get
-}{
- false
+% At this point if we have been written by the (e)ps2write device, there will
+% be a dictionary on the operand stack which contains some flags controlling the
+% later behaviour of this ProcSet. Be aware that this dictionary is present until
+% it is processed by the main dictionary handling at line 155 of this file, it is
+% important to make sure this dictionary is preserved, and remains top of the stack
+% when we reach that point.
+% For safety, the code between now and that point which also uses that configuration
+% information must check to see that the operand stack has at least one operand and that
+% its a dictionary, and must preserve that dictionary if it uses it.
+
+% Determine whether to create a custom error handler.
+% Check to see there's at least one object on the stack,
+% and that said object is a dicitonary. If either is not true
+% then create a custom error handler. If there is a dictionary,
+% assume its the 'global config' dictionary written by ps2write
+% (this should always be true!) and look to see if it has a
+% EPS2Write key. If it does get it. If EPS2Write is true then
+% don't create a custom error handler. If it is false or not present
+% then do create a custom error handler.
+count 0 ne {
+ dup type /dicttype eq {
+ dup /EPS2Write known {
+ dup /EPS2Write get not
+ }
+ {
+ true
+ }ifelse
+ }
+ {
+ true
+ } ifelse
+}
+{
+ true
} ifelse
10 dict begin % A dictionary for local binding
-% This switch used to control paeg independent values, like
-% whether to use InitialMatrix in SetupPageView
-%
-/DSC_OPDFREAD exch def
-
/this currentdict def
/y 720 def
/ebuf 200 string def
@@ -79,63 +98,86 @@ currentdict /DSC_OPDFREAD known {
//this /y 2 copy get 12 sub put
} bind def
-errordict /handleerror
-{ systemdict begin
- $error begin
- newerror
- { (%%[ Error handled by opdfread.ps : ) print errorname //ebuf cvs print (; OffendingCommand: )
- print /command load //ebuf cvs print ( ]%%) = flush
- /newerror false store vmstatus pop pop 0 ne
- { grestoreall
- } if
- errorname (VMerror) ne
- { showpage
- } if
- initgraphics
- 0 720 moveto
- errorname (VMerror) eq
- { //this /ehsave known
- { clear //this /ehsave get restore 2 vmreclaim
+% We only actually create and push the custom error handler if we are not an EPS.
+{
+ errordict /handleerror
+ { systemdict begin
+ $error begin
+ newerror
+ { (%%[ Error handled by opdfread.ps : ) print errorname //ebuf cvs print (; OffendingCommand: )
+ print /command load //ebuf cvs print ( ]%%) = flush
+ /newerror false store vmstatus pop pop 0 ne
+ { grestoreall
} if
- vmstatus exch pop exch pop
- }
- /Courier 12 selectfont
- {
- (ERROR: ) //prnt exec errorname //prnt exec
- (OFFENDING COMMAND: ) //prnt exec
- /command load //prnt exec
- $error /ostack known {
- (%%[STACK:) =
- (STACK:) //prnt exec
- $error /ostack get aload length {
- //newline exec
- dup mark eq {
- (-mark-) dup = show
- } {
- dup type /nametype eq {
- dup xcheck not {
- (/) show
- (/) print
- } if
- } if
- dup = //ebuf cvs show
- } ifelse
- } repeat
+ errorname (VMerror) ne
+ { showpage
} if
- } ifelse
- (%%]%) =
- //systemdict /showpage get exec
- quit
- } if
- end
- end
-} bind readonly put
+ initgraphics
+ 0 720 moveto
+ errorname (VMerror) eq
+ { //this /ehsave known
+ { clear //this /ehsave get restore 2 vmreclaim
+ } if
+ vmstatus exch pop exch pop
+ }
+ /Courier 12 selectfont
+ {
+ (ERROR: ) //prnt exec errorname //prnt exec
+ (OFFENDING COMMAND: ) //prnt exec
+ /command load //prnt exec
+ $error /ostack known {
+ (%%[STACK:) =
+ (STACK:) //prnt exec
+ $error /ostack get aload length {
+ //newline exec
+ dup mark eq {
+ (-mark-) dup = show
+ } {
+ dup type /nametype eq {
+ dup xcheck not {
+ (/) show
+ (/) print
+ } if
+ } if
+ dup = //ebuf cvs show
+ } ifelse
+ } repeat
+ } if
+ } ifelse
+ (%%]%) =
+ //systemdict /showpage get exec
+ quit
+ } if
+ end
+ end
+ } bind readonly put
+} if
end % A dictionary for local binding
-
50 dict begin
+% Read the definitions of various global parameters from the dictionary
+% written at the head of the file by ps2write, and define the parameters
+% in this dictionary. Check first to make sure we have a dictionary on the
+% stack; if we do, assume its the 'global configuration' dictionary.
+count 0 ne {
+ dup type /dicttype eq {
+ {def} forall
+ false
+ }
+ {
+ true
+ } ifelse
+}
+{
+ true
+} ifelse
+
+{
+ ( *** Warning: global definitions dictionary not found, file may be corrupted.\n) print flush
+} if
+
% ===================== Debugging =========================================
/DefaultSwitch % <name> DefaultSwitch -
@@ -4176,7 +4218,10 @@ currentdict end readonly def
} bind def
/ShowText % <string> ShowText -
-{ //GraphicState /TextRenderingMode get 0 eq {
+{
+ //GraphicState /TextRenderingMode get dup 0 eq
+ exch 3 eq not currentfont /FontType get 3 eq and or
+ {
//GraphicState /WordSpacing get 0
32
//GraphicState /CharacterSpacing get 0
@@ -4236,13 +4281,28 @@ currentdict end readonly def
} bind def
/ShowTextBeg % - ShowTextBeg -
-{ //GraphicState /TextRenderingMode get 0 ne {
- currentpoint newpath moveto
- } if
+{
+ //GraphicState /TextRenderingMode get dup 0 ne
+ {
+ 3 ne
+ currentfont /FontType get 3 eq not and {
+ currentpoint newpath moveto
+ } if
+ }
+ {
+ pop
+ } ifelse
} bind def
/ShowTextEnd % - ShowTextEnd -
-{ //GraphicState /TextRenderingMode get
+{
+ //GraphicState /TextRenderingMode get
+ currentfont /FontType get 3 eq {
+ dup 3 ne {
+ pop 0
+ } if
+ }if
+
{ dup 1 eq {
stroke exit
} if
diff --git a/devices/vector/whitelst.c b/devices/vector/whitelst.c
index 652926f4..af4c14fc 100644
--- a/devices/vector/whitelst.c
+++ b/devices/vector/whitelst.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
diff --git a/devices/vector/whitelst.h b/devices/vector/whitelst.h
index 2e562fd8..a566da54 100644
--- a/devices/vector/whitelst.h
+++ b/devices/vector/whitelst.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or