summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'devices/vector/gdevpdfd.c')
-rw-r--r--devices/vector/gdevpdfd.c146
1 files changed, 23 insertions, 123 deletions
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;