summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'devices/vector')
-rw-r--r--devices/vector/gdevagl.c2
-rw-r--r--devices/vector/gdevagl.h2
-rw-r--r--devices/vector/gdevpdf.c4
-rw-r--r--devices/vector/gdevpdfb.h16
-rw-r--r--devices/vector/gdevpdfd.c203
-rw-r--r--devices/vector/gdevpdfe.c20
-rw-r--r--devices/vector/gdevpdfg.c256
-rw-r--r--devices/vector/gdevpdfg.h9
-rw-r--r--devices/vector/gdevpdfi.c21
-rw-r--r--devices/vector/gdevpdfp.c19
-rw-r--r--devices/vector/gdevpdft.c4
-rw-r--r--devices/vector/gdevpdfu.c4
-rw-r--r--devices/vector/gdevpdfx.h10
-rw-r--r--devices/vector/gdevpdtb.c2
-rw-r--r--devices/vector/gdevpdts.c2
-rw-r--r--devices/vector/gdevpdtt.c4
-rw-r--r--devices/vector/gdevpsdf.h7
-rw-r--r--devices/vector/gdevpsdi.c15
-rw-r--r--devices/vector/gdevpsds.c5
-rw-r--r--devices/vector/gdevpsds.h3
-rw-r--r--devices/vector/gdevpsdu.c2
-rw-r--r--devices/vector/gdevpsu.c5
-rw-r--r--devices/vector/gdevpx.c1
-rw-r--r--devices/vector/gdevtxtw.c201
-rw-r--r--devices/vector/gdevxps.c43
25 files changed, 628 insertions, 232 deletions
diff --git a/devices/vector/gdevagl.c b/devices/vector/gdevagl.c
index b2813e04..f9428a6e 100644
--- a/devices/vector/gdevagl.c
+++ b/devices/vector/gdevagl.c
@@ -4308,5 +4308,5 @@ treble_glyph_list_t TrebleGlyphList[] = {
quad_glyph_list_t QuadGlyphList[] = {
{"rehyehaleflamarabic", {0x0631, 0xFEF3, 0xFE8E, 0x0644}},
- {0x00, {0,0,0}}
+ {0x00, {0,0,0,0}}
};
diff --git a/devices/vector/gdevagl.h b/devices/vector/gdevagl.h
index e509f897..e3569226 100644
--- a/devices/vector/gdevagl.h
+++ b/devices/vector/gdevagl.h
@@ -33,5 +33,5 @@ typedef struct treble_glyph_list_s {
typedef struct quad_glyph_list_s {
const char *Glyph;
- short Unicode[4];
+ unsigned short Unicode[4];
} quad_glyph_list_t;
diff --git a/devices/vector/gdevpdf.c b/devices/vector/gdevpdf.c
index d918d603..b25a4a6a 100644
--- a/devices/vector/gdevpdf.c
+++ b/devices/vector/gdevpdf.c
@@ -1020,6 +1020,7 @@ pdf_close_page(gx_device_pdf * pdev, int num_copies)
page->contents_id = pdev->contents_id;
page->NumCopies_set = pdev->NumCopies_set;
page->NumCopies = pdev->NumCopies;
+ page->UserUnit = pdev->UserUnit;
pdf_record_usage(pdev, pdev->contents_id, pdev->next_page);
pdf_record_usage(pdev, pdev->contents_length_id, pdev->next_page);
pdf_record_usage(pdev, page->Page->id, pdev->next_page);
@@ -1337,6 +1338,9 @@ pdf_write_page(gx_device_pdf *pdev, int page_num)
bleedbox[0], bleedbox[1], bleedbox[2], bleedbox[3]);
}
pdf_print_orientation(pdev, page);
+ if (page->UserUnit != 1)
+ pprintg1(s, "/UserUnit %g\n", page->UserUnit);
+
pprintld1(s, "/Parent %ld 0 R\n", pdev->Pages->id);
if (pdev->ForOPDFRead && pdev->DoNumCopies && !pdev->ProduceDSC) {
if (page->NumCopies_set)
diff --git a/devices/vector/gdevpdfb.h b/devices/vector/gdevpdfb.h
index d000ee96..5ea7a355 100644
--- a/devices/vector/gdevpdfb.h
+++ b/devices/vector/gdevpdfb.h
@@ -98,7 +98,16 @@ const gx_device_pdf PDF_DEVICE_IDENT =
NULL, /* push_transparency_state */
NULL, /* pop_transparency_state */
NULL, /* put_image */
- gdev_pdf_dev_spec_op /* dev_spec_op */
+ gdev_pdf_dev_spec_op, /* dev_spec_op */
+ NULL, /* copy_planes */
+ NULL, /* get_profile */
+ NULL, /* set_graphics_type_tag */
+ NULL, /* strip_copy_rop2 */
+ NULL, /* strip_tile_rect_devn */
+ NULL, /* copy_alpha_hl_color */
+ NULL, /* process_page */
+ NULL, /* transform_pixel_region */
+ gdev_pdf_fill_stroke_path /* fill_stroke_path */
},
psdf_initial_values(PSDF_VERSION_INITIAL, 0 /*false */ ), /* (!ASCII85EncodePages) */
0, /* pdf_font_dir */
@@ -162,9 +171,9 @@ const gx_device_pdf PDF_DEVICE_IDENT =
{-1, -1}, /* page_dsc_info */
0 /*false*/, /* fill_overprint */
0 /*false*/, /* stroke_overprint */
+ 1 /* Absolute Colorimetric */, /* rendering intent */
0 /*false*/, /* remap_fill_coilor */
0 /*false*/, /* remap_stroke_coilor */
- 0, /* overprint_mode */
gs_no_id, /* halftone_id */
{gs_no_id, gs_no_id, gs_no_id, gs_no_id}, /* transfer_ids */
0, /* transfer_not_identity */
@@ -288,7 +297,8 @@ const gx_device_pdf PDF_DEVICE_IDENT =
-1, /* Last Form ID, start with -1 which means 'none' */
0, /* ExtensionMetadata */
0, /* PDFFormName */
- 0 /* PassThroughWriter */
+ 0, /* PassThroughWriter */
+ 1.0 /* UserUnit */
};
#else
diff --git a/devices/vector/gdevpdfd.c b/devices/vector/gdevpdfd.c
index 28c6b01d..1e62bad1 100644
--- a/devices/vector/gdevpdfd.c
+++ b/devices/vector/gdevpdfd.c
@@ -846,7 +846,7 @@ prepare_fill_with_clip(gx_device_pdf *pdev, const gs_gstate * pgs,
if (code < 0)
return code;
}
- code = pdf_prepare_fill(pdev, pgs);
+ code = pdf_prepare_fill(pdev, pgs, false);
if (code < 0)
return code;
return pdf_put_clip_path(pdev, pcpath);
@@ -1743,7 +1743,7 @@ gdev_pdf_stroke_path(gx_device * dev, const gs_gstate * pgs,
code = pdf_open_page(pdev, PDF_IN_STREAM);
if (code < 0)
return code;
- code = pdf_prepare_stroke(pdev, pgs);
+ code = pdf_prepare_stroke(pdev, pgs, false);
if (code == gs_error_rangecheck) {
/* Fallback to the default implermentation for handling
a transparency with CompatibilityLevel<=1.3 . */
@@ -1866,6 +1866,205 @@ gdev_pdf_stroke_path(gx_device * dev, const gs_gstate * pgs,
return 0;
}
+int
+gdev_pdf_fill_stroke_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath,
+ const gx_fill_params *fill_params, const gx_drawing_color *pdcolor_fill,
+ const gx_stroke_params *stroke_params, const gx_drawing_color *pdcolor_stroke,
+ const gx_clip_path *pcpath)
+{
+ gx_device_pdf *pdev = (gx_device_pdf *) dev;
+ int code;
+ bool new_clip;
+ bool have_path;
+
+ have_path = !gx_path_is_void(ppath);
+ if (!have_path) {
+ if (!pdev->vg_initial_set) {
+ /* See lib/gs_pdfwr.ps about "initial graphic state". */
+ pdf_prepare_initial_viewer_state(pdev, pgs);
+ pdf_reset_graphics(pdev);
+ return 0;
+ }
+ }
+
+ /* PostScript doesn't have a fill+stroke primitive, so break it into two operations
+ * PDF 1.2 only has a single overprint setting, we can't be certainto match that
+ * Because our inpu tcould be from a higher level. So be sure and break it into
+ * 2 operations.
+ */
+ if (pdev->ForOPDFRead || pdev->CompatibilityLevel < 1.3) {
+ code = gdev_pdf_fill_path(dev, pgs, ppath, fill_params, pdcolor_fill, pcpath);
+ if (code < 0)
+ return code;
+ gs_swapcolors_quick(pgs);
+ code = gdev_pdf_stroke_path(dev, pgs, ppath, stroke_params, pdcolor_stroke, pcpath);
+ gs_swapcolors_quick(pgs);
+ return code;
+ } else {
+ bool set_ctm;
+ gs_matrix mat;
+ double scale, path_scale;
+ double prescale = 1;
+ gs_fixed_rect bbox;
+ gs_path_enum cenum;
+ gdev_vector_dopath_state_t state;
+ stream *s = pdev->strm;
+ /*
+ * Check for an empty clipping path.
+ */
+ if (pcpath) {
+ gs_fixed_rect cbox;
+
+ 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)
+ return code;
+
+ new_clip = pdf_must_put_clip_path(pdev, pcpath);
+ if (have_path || pdev->context == PDF_IN_NONE || new_clip) {
+ if (new_clip)
+ code = pdf_unclip(pdev);
+ else
+ code = pdf_open_page(pdev, PDF_IN_STREAM);
+ if (code < 0)
+ return code;
+ }
+ code = pdf_prepare_fill_stroke(pdev, pgs, false);
+ if (code < 0)
+ return code;
+
+ code = pdf_put_clip_path(pdev, pcpath);
+ if (code < 0)
+ return code;
+ /*
+ * If the CTM is not uniform, stroke width depends on angle.
+ * We'd like to avoid resetting the CTM, so we check for uniform
+ * CTMs explicitly. Note that in PDF, unlike PostScript, it is
+ * the CTM at the time of the stroke operation, not the CTM at
+ * the time the path was constructed, that is used for transforming
+ * the points of the path; so if we have to reset the CTM, we must
+ * do it before constructing the path, and inverse-transform all
+ * the coordinates.
+ */
+ set_ctm = (bool)gdev_vector_stroke_scaling((gx_device_vector *)pdev,
+ pgs, &scale, &mat);
+ if (set_ctm && ((pgs->ctm.xx == 0 && pgs->ctm.xy == 0) ||
+ (pgs->ctm.yx == 0 && pgs->ctm.yy == 0))) {
+ /* Acrobat Reader 5 and Adobe Reader 6 issues
+ the "Wrong operand type" error with matrices, which have 3 zero coefs.
+ Besides that, we found that Acrobat Reader 4, Acrobat Reader 5
+ and Adobe Reader 6 all store the current path in user space
+ and apply CTM in the time of stroking - See the bug 687901.
+ Therefore a precise conversion of Postscript to PDF isn't possible in this case.
+ Adobe viewers render a line with a constant width instead.
+ At last, with set_ctm == true we need the inverse matrix in
+ gdev_vector_dopath. Therefore we exclude projection matrices
+ (see bug 688363). */
+ set_ctm = false;
+ 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.
+ Doing so after writing the clipping path due to /SP pdfmark
+ uses a special hack with painting outside the clipping box
+ for synchronizing the clipping path (see lib/gs_pdfwr.ps).
+ That hack appeared because there is no way to pass
+ the gs_gstate through gdev_pdf_put_params,
+ which pdfmark is implemented with.
+ */
+ gs_fixed_rect clip_box, stroke_bbox = bbox;
+ gs_point d0, d1;
+ gs_fixed_point p0, p1;
+ fixed bbox_expansion_x, bbox_expansion_y;
+
+ gs_distance_transform(pgs->line_params.half_width, 0, &ctm_only(pgs), &d0);
+ gs_distance_transform(0, pgs->line_params.half_width, &ctm_only(pgs), &d1);
+ p0.x = float2fixed(any_abs(d0.x));
+ p0.y = float2fixed(any_abs(d0.y));
+ p1.x = float2fixed(any_abs(d1.x));
+ p1.y = float2fixed(any_abs(d1.y));
+ bbox_expansion_x = max(p0.x, p1.x) + fixed_1 * 2;
+ bbox_expansion_y = max(p0.y, p1.y) + fixed_1 * 2;
+ stroke_bbox.p.x -= bbox_expansion_x;
+ stroke_bbox.p.y -= bbox_expansion_y;
+ stroke_bbox.q.x += bbox_expansion_x;
+ stroke_bbox.q.y += bbox_expansion_y;
+ gx_cpath_outer_box(pcpath, &clip_box);
+ rect_intersect(stroke_bbox, clip_box);
+ 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) {
+ /* rangecheck means we revert to the equivalent to the default implementation */
+ code = gdev_pdf_fill_path(dev, pgs, ppath, fill_params, pdcolor_fill, pcpath);
+ if (code < 0)
+ return code;
+ /* Swap colors to make sure the pgs colorspace is correct for stroke */
+ gs_swapcolors_quick(pgs);
+ code = gdev_pdf_stroke_path(dev, pgs, ppath, stroke_params, pdcolor_stroke, pcpath);
+ gs_swapcolors_quick(pgs);
+ return code;
+ }
+
+ /* Swap colors to make sure the pgs colorspace is correct for stroke */
+ gs_swapcolors_quick(pgs);
+ code = gdev_vector_prepare_stroke((gx_device_vector *)pdev, pgs, stroke_params,
+ pdcolor_stroke, scale);
+ gs_swapcolors_quick(pgs);
+ if (code < 0) {
+ code = gdev_pdf_fill_path(dev, pgs, ppath, fill_params, pdcolor_fill, pcpath);
+ if (code < 0)
+ return code;
+ return gdev_pdf_stroke_path(dev, pgs, ppath, stroke_params, pdcolor_stroke, pcpath);
+ }
+ if (!pdev->HaveStrokeColor)
+ pdev->saved_fill_color = pdev->saved_stroke_color;
+ if (set_ctm)
+ pdf_put_matrix(pdev, "q ", &mat, "cm\n");
+ if (pgs->line_params.dash.offset != 0 || pgs->line_params.dash.pattern_size != 0)
+ code = pdf_write_path(pdev, (gs_path_enum *)&cenum, &state, (gx_path *)ppath, 0, gx_path_type_stroke | gx_path_type_optimize | gx_path_type_dashed_stroke, (set_ctm ? &mat : (const gs_matrix *)0));
+ else
+ code = pdf_write_path(pdev, (gs_path_enum *)&cenum, &state, (gx_path *)ppath, 0, gx_path_type_stroke | gx_path_type_optimize, (set_ctm ? &mat : (const gs_matrix *)0));
+ if (code < 0)
+ return code;
+ s = pdev->strm;
+ stream_puts(s, (fill_params->rule < 0 ? "B\n" : "B*\n"));
+ stream_puts(s, (set_ctm ? " Q\n" : "\n"));
+ }
+ return 0;
+}
+
/*
The fill_rectangle_hl_color device method.
See gxdevcli.h about return codes.
diff --git a/devices/vector/gdevpdfe.c b/devices/vector/gdevpdfe.c
index 88ca7ac5..1c540709 100644
--- a/devices/vector/gdevpdfe.c
+++ b/devices/vector/gdevpdfe.c
@@ -202,8 +202,13 @@ pdf_xmp_time(char *buf, int buf_length)
time_t t;
char buf1[4+1+2+1+2+1]; /* yyyy-mm-dd\0 */
+#ifdef CLUSTER
+ memset(&t, 0, sizeof(t));
+ memset(&tms, 0, sizeof(tms));
+#else
time(&t);
tms = *localtime(&t);
+#endif
gs_sprintf(buf1,
"%04d-%02d-%02d",
tms.tm_year + 1900, tms.tm_mon + 1, tms.tm_mday);
@@ -646,8 +651,7 @@ pdf_write_document_metadata(gx_device_pdf *pdev, const byte digest[6])
{
pdf_xml_tag_open_beg(s, "rdf:Description");
- pdf_xml_attribute_name(s, "rdf:about");
- pdf_xml_attribute_value(s, instance_uuid);
+ pdf_xml_copy(s, " rdf:about=\"\"");
pdf_xml_attribute_name(s, "xmlns:pdf");
pdf_xml_attribute_value(s, "http://ns.adobe.com/pdf/1.3/");
@@ -684,8 +688,7 @@ pdf_write_document_metadata(gx_device_pdf *pdev, const byte digest[6])
}
pdf_xml_tag_open_beg(s, "rdf:Description");
- pdf_xml_attribute_name(s, "rdf:about");
- pdf_xml_attribute_value(s, instance_uuid);
+ pdf_xml_copy(s, " rdf:about=\"\"");
pdf_xml_attribute_name(s, "xmlns:xmp");
pdf_xml_attribute_value(s, "http://ns.adobe.com/xap/1.0/");
pdf_xml_tag_end(s);
@@ -718,8 +721,7 @@ pdf_write_document_metadata(gx_device_pdf *pdev, const byte digest[6])
pdf_xml_newline(s);
pdf_xml_tag_open_beg(s, "rdf:Description");
- pdf_xml_attribute_name(s, "rdf:about");
- pdf_xml_attribute_value(s, instance_uuid);
+ pdf_xml_copy(s, " rdf:about=\"\"");
pdf_xml_attribute_name(s, "xmlns:xapMM");
pdf_xml_attribute_value(s, "http://ns.adobe.com/xap/1.0/mm/");
pdf_xml_attribute_name(s, "xapMM:DocumentID");
@@ -728,8 +730,7 @@ pdf_write_document_metadata(gx_device_pdf *pdev, const byte digest[6])
pdf_xml_newline(s);
pdf_xml_tag_open_beg(s, "rdf:Description");
- pdf_xml_attribute_name(s, "rdf:about");
- pdf_xml_attribute_value(s, instance_uuid);
+ pdf_xml_copy(s, " rdf:about=\"\"");
pdf_xml_attribute_name(s, "xmlns:dc");
pdf_xml_attribute_value(s, "http://purl.org/dc/elements/1.1/");
pdf_xml_attribute_name(s, "dc:format");
@@ -803,8 +804,7 @@ pdf_write_document_metadata(gx_device_pdf *pdev, const byte digest[6])
pdf_xml_newline(s);
if (pdev->PDFA != 0) {
pdf_xml_tag_open_beg(s, "rdf:Description");
- pdf_xml_attribute_name(s, "rdf:about");
- pdf_xml_attribute_value(s, instance_uuid);
+ pdf_xml_copy(s, " rdf:about=\"\"");
pdf_xml_attribute_name(s, "xmlns:pdfaid");
pdf_xml_attribute_value(s, "http://www.aiim.org/pdfa/ns/id/");
pdf_xml_attribute_name(s, "pdfaid:part");
diff --git a/devices/vector/gdevpdfg.c b/devices/vector/gdevpdfg.c
index bd06b9f1..0aa93e53 100644
--- a/devices/vector/gdevpdfg.c
+++ b/devices/vector/gdevpdfg.c
@@ -75,13 +75,14 @@ pdf_save_viewer_state(gx_device_pdf *pdev, stream *s)
pdev->vgstack[i].transfer_ids[2] = pdev->transfer_ids[2];
pdev->vgstack[i].transfer_ids[3] = pdev->transfer_ids[3];
pdev->vgstack[i].transfer_not_identity = pdev->transfer_not_identity;
- pdev->vgstack[i].opacity_alpha = pdev->state.opacity.alpha;
- pdev->vgstack[i].shape_alpha = pdev->state.shape.alpha;
+ pdev->vgstack[i].strokeconstantalpha = pdev->state.strokeconstantalpha;
+ pdev->vgstack[i].fillconstantalpha = pdev->state.fillconstantalpha;
+ pdev->vgstack[i].alphaisshape = pdev->state.alphaisshape;
pdev->vgstack[i].blend_mode = pdev->state.blend_mode;
pdev->vgstack[i].halftone_id = pdev->halftone_id;
pdev->vgstack[i].black_generation_id = pdev->black_generation_id;
pdev->vgstack[i].undercolor_removal_id = pdev->undercolor_removal_id;
- pdev->vgstack[i].overprint_mode = pdev->overprint_mode;
+ pdev->vgstack[i].overprint_mode = pdev->state.overprint_mode;
pdev->vgstack[i].smoothness = pdev->state.smoothness;
pdev->vgstack[i].flatness = pdev->state.flatness;
pdev->vgstack[i].text_knockout = pdev->state.text_knockout;
@@ -125,13 +126,14 @@ pdf_load_viewer_state(gx_device_pdf *pdev, pdf_viewer_state *s)
pdev->transfer_ids[2] = s->transfer_ids[2];
pdev->transfer_ids[3] = s->transfer_ids[3];
pdev->transfer_not_identity = s->transfer_not_identity;
- pdev->state.opacity.alpha = s->opacity_alpha;
- pdev->state.shape.alpha = s->shape_alpha;
+ pdev->state.strokeconstantalpha = s->strokeconstantalpha;
+ pdev->state.fillconstantalpha = s->fillconstantalpha;
+ pdev->state.alphaisshape = s->alphaisshape;
pdev->state.blend_mode = s->blend_mode;
pdev->halftone_id = s->halftone_id;
pdev->black_generation_id = s->black_generation_id;
pdev->undercolor_removal_id = s->undercolor_removal_id;
- pdev->overprint_mode = s->overprint_mode;
+ pdev->state.overprint_mode = s->overprint_mode;
pdev->state.smoothness = s->smoothness;
pdev->state.flatness = s->flatness;
pdev->state.text_knockout = s->text_knockout;
@@ -209,8 +211,9 @@ pdf_viewer_state_from_gs_gstate_aux(pdf_viewer_state *pvs, const gs_gstate *pgs)
pvs->transfer_ids[1] = (pgs->set_transfer.green != NULL ? pgs->set_transfer.green->id : 0);
pvs->transfer_ids[2] = (pgs->set_transfer.blue != NULL ? pgs->set_transfer.blue->id : 0);
pvs->transfer_ids[3] = (pgs->set_transfer.gray != NULL ? pgs->set_transfer.gray->id : 0);
- pvs->opacity_alpha = pgs->opacity.alpha;
- pvs->shape_alpha = pgs->shape.alpha;
+ pvs->fillconstantalpha = pgs->fillconstantalpha;
+ pvs->strokeconstantalpha = pgs->strokeconstantalpha;
+ pvs->alphaisshape = pgs->alphaisshape;
pvs->blend_mode = pgs->blend_mode;
pvs->halftone_id = (pgs->dev_ht != 0 ? pgs->dev_ht->id : 0);
pvs->black_generation_id = (pgs->black_generation != 0 ? pgs->black_generation->id : 0);
@@ -776,7 +779,7 @@ int convert_DeviceN_alternate(gx_device_pdf * pdev, const gs_gstate * pgs, const
return_error(gs_error_VMerror);
samples = (unsigned int)pow(2, pcs->params.device_n.num_components);
- data_buff = gs_alloc_bytes(pdev->memory, pdev->color_info.num_components * samples, "Convert DeviceN");
+ data_buff = gs_alloc_bytes(pdev->memory, (unsigned long)pdev->color_info.num_components * samples, "Convert DeviceN");
if (data_buff == 0) {
COS_FREE(pca, "convert DeviceN");
return_error(gs_error_VMerror);
@@ -2869,10 +2872,8 @@ pdf_update_transfer(gx_device_pdf *pdev, const gs_gstate *pgs,
*/
static int
pdf_update_alpha(gx_device_pdf *pdev, const gs_gstate *pgs,
- pdf_resource_t **ppres)
+ pdf_resource_t **ppres, bool for_text)
{
- bool ais;
- double alpha;
int code;
if (pdev->state.soft_mask_id != pgs->soft_mask_id) {
@@ -2882,9 +2883,11 @@ pdf_update_alpha(gx_device_pdf *pdev, const gs_gstate *pgs,
code = pdf_open_contents(pdev, PDF_IN_STREAM);
if (code < 0)
return code;
- code = pdf_restore_viewer_state(pdev, pdev->strm);
- if (code < 0)
- return code;
+ if (pdev->vgstack_depth > pdev->vgstack_bottom) {
+ code = pdf_restore_viewer_state(pdev, pdev->strm);
+ if (code < 0)
+ return code;
+ }
}
else{
gs_sprintf(buf, "%ld 0 R", pgs->soft_mask_id);
@@ -2901,44 +2904,27 @@ pdf_update_alpha(gx_device_pdf *pdev, const gs_gstate *pgs,
}
pdev->state.soft_mask_id = pgs->soft_mask_id;
}
- if (pdev->state.opacity.alpha != pgs->opacity.alpha) {
- if (pdev->state.shape.alpha != pgs->shape.alpha) {
- /* We had previously set one of opacity or shape, but we didn't
- * ever need to write the graphcis state out, leaving us with a
- * dangling alpha. We should honour the current state. One of
- * opacity or alpha will be the default (1.0), so use the other.
- */
- pdev->state.opacity.alpha = pgs->opacity.alpha;
- pdev->state.shape.alpha = pgs->shape.alpha;
- if (pgs->opacity.alpha != 1.0) {
- ais = false;
- alpha = pdev->state.opacity.alpha;
- }
- else {
- ais = true;
- alpha = pdev->state.shape.alpha;
- }
- } else {
- ais = false;
- alpha = pdev->state.opacity.alpha = pgs->opacity.alpha;
- }
- } else if (pdev->state.shape.alpha != pgs->shape.alpha) {
- ais = true;
- alpha = pdev->state.shape.alpha = pgs->shape.alpha;
+
+ if (pdev->state.alphaisshape != pgs->alphaisshape ||
+ pdev->state.strokeconstantalpha != pgs->strokeconstantalpha ||
+ pdev->state.fillconstantalpha != pgs->fillconstantalpha) {
+
+ pdev->state.strokeconstantalpha = pgs->strokeconstantalpha;
+ pdev->state.fillconstantalpha = pgs->fillconstantalpha;
+ pdev->state.alphaisshape = pgs->alphaisshape;
+
+ code = pdf_open_gstate(pdev, ppres);
+ if (code < 0)
+ return code;
+ code = cos_dict_put_c_key_bool(resource_dict(*ppres), "/AIS", pgs->alphaisshape);
+ if (code < 0)
+ return code;
+ code = cos_dict_put_c_key_real(resource_dict(*ppres), "/CA", pgs->strokeconstantalpha);
+ if (code < 0)
+ return code;
+ return cos_dict_put_c_key_real(resource_dict(*ppres), "/ca", pgs->fillconstantalpha);
} else
return 0;
- code = pdf_open_gstate(pdev, ppres);
- if (code < 0)
- return code;
- code = cos_dict_put_c_key_bool(resource_dict(*ppres), "/AIS", ais);
- if (code < 0)
- return code;
- /* we never do the 'both' operations (b, B, b*, B*) so we set both */
- /* CA and ca the same so that we stay in sync with state.*.alpha */
- code = cos_dict_put_c_key_real(resource_dict(*ppres), "/CA", alpha);
- if (code < 0)
- return code;
- return cos_dict_put_c_key_real(resource_dict(*ppres), "/ca", alpha);
}
/*
@@ -2946,7 +2932,7 @@ pdf_update_alpha(gx_device_pdf *pdev, const gs_gstate *pgs,
*/
int
pdf_prepare_drawing(gx_device_pdf *pdev, const gs_gstate *pgs,
- pdf_resource_t **ppres)
+ pdf_resource_t **ppres, bool for_text)
{
int code = 0;
int bottom;
@@ -2966,7 +2952,7 @@ pdf_prepare_drawing(gx_device_pdf *pdev, const gs_gstate *pgs,
return code;
pdev->state.blend_mode = pgs->blend_mode;
}
- code = pdf_update_alpha(pdev, pgs, ppres);
+ code = pdf_update_alpha(pdev, pgs, ppres, for_text);
if (code < 0)
return code;
} else {
@@ -2974,8 +2960,8 @@ pdf_prepare_drawing(gx_device_pdf *pdev, const gs_gstate *pgs,
* If the graphics state calls for any transparency functions,
* we can't represent them, so return a rangecheck.
*/
- if (pgs->opacity.alpha != 1 ||
- pgs->shape.alpha != 1)
+ if (pgs->strokeconstantalpha != 1 ||
+ pgs->fillconstantalpha != 1)
return_error(gs_error_rangecheck);
}
/*
@@ -3072,9 +3058,13 @@ pdf_prepare_drawing(gx_device_pdf *pdev, const gs_gstate *pgs,
}
}
}
- if (pdev->CompatibilityLevel >= 1.3 && pdev->sbstack_depth == bottom) {
- if (pdev->overprint_mode != pdev->params.OPM) {
- if (pdev->params.OPM == 1 && pdev->PDFA == 2) {
+ if (pdev->state.overprint_mode != pdev->params.OPM) {
+ if (pdev->params.OPM != pgs->overprint_mode)
+ ((gs_gstate *)pgs)->overprint_mode = pdev->params.OPM;
+ }
+ if (pdev->CompatibilityLevel >= 1.3 /*&& pdev->sbstack_depth == bottom */) {
+ if (pdev->state.overprint_mode != pgs->overprint_mode) {
+ if (pgs->overprint_mode == 1 && pdev->PDFA == 2) {
switch (pdev->PDFACompatibilityPolicy) {
case 0:
emprintf(pdev->memory,
@@ -3085,7 +3075,8 @@ pdf_prepare_drawing(gx_device_pdf *pdev, const gs_gstate *pgs,
case 1:
emprintf(pdev->memory,
"Setting Overprint Mode to 1\n not permitted in PDF/A-2, overprint mode not set\n\n");
- pdev->params.OPM = 0;
+ /* Deliberately breaking const here in order to force the graphics state overprint mode to be unchanged */
+ ((gs_gstate *)pgs)->overprint_mode = pdev->state.overprint_mode;
break;
case 2:
emprintf(pdev->memory,
@@ -3100,14 +3091,14 @@ pdf_prepare_drawing(gx_device_pdf *pdev, const gs_gstate *pgs,
break;
}
}
- if (pdev->overprint_mode != pdev->params.OPM) {
+ if (pdev->state.overprint_mode != pgs->overprint_mode) {
code = pdf_open_gstate(pdev, ppres);
if (code < 0)
return code;
- code = cos_dict_put_c_key_int(resource_dict(*ppres), "/OPM", pdev->params.OPM);
+ code = cos_dict_put_c_key_int(resource_dict(*ppres), "/OPM", pgs->overprint_mode);
if (code < 0)
return code;
- pdev->overprint_mode = pdev->params.OPM;
+ pdev->params.OPM = pdev->state.overprint_mode = pgs->overprint_mode;
}
}
if (pdev->state.smoothness != pgs->smoothness) {
@@ -3136,19 +3127,36 @@ pdf_prepare_drawing(gx_device_pdf *pdev, const gs_gstate *pgs,
/* Update the graphics state for filling. */
int
-pdf_try_prepare_fill(gx_device_pdf *pdev, const gs_gstate *pgs)
+pdf_try_prepare_fill(gx_device_pdf *pdev, const gs_gstate *pgs, bool for_text)
{
pdf_resource_t *pres = 0;
- int code = pdf_prepare_drawing(pdev, pgs, &pres);
+ int code = pdf_prepare_drawing(pdev, pgs, &pres, for_text);
if (code < 0)
return code;
+ if (pdev->rendering_intent != pgs->renderingintent && !pdev->ForOPDFRead) {
+ static const char *const ri_names[] = { "Perceptual", "RelativeColorimetric", "Saturation", "AbsoluteColorimetric" };
+ char buf[32];
+
+ code = pdf_open_gstate(pdev, &pres);
+ if (code < 0)
+ return code;
+
+ buf[0] = '/';
+ strncpy(buf + 1, ri_names[pgs->renderingintent], sizeof(buf) - 2);
+ code = cos_dict_put_string_copy(resource_dict(pres), "/RI", buf);
+ if (code < 0)
+ return code;
+ pdev->rendering_intent = pgs->renderingintent;
+ }
+
/* Update overprint. */
if (pdev->params.PreserveOverprintSettings &&
(pdev->fill_overprint != pgs->overprint ||
pdev->font3) && !pdev->skip_colors
) {
- code = pdf_open_gstate(pdev, &pres);
+ if (pres == 0)
+ code = pdf_open_gstate(pdev, &pres);
if (code < 0)
return code;
/* PDF 1.2 only has a single overprint setting. */
@@ -3167,45 +3175,136 @@ pdf_try_prepare_fill(gx_device_pdf *pdev, const gs_gstate *pgs)
return pdf_end_gstate(pdev, pres);
}
int
-pdf_prepare_fill(gx_device_pdf *pdev, const gs_gstate *pgs)
+pdf_prepare_fill(gx_device_pdf *pdev, const gs_gstate *pgs, bool for_text)
{
int code;
if (pdev->context != PDF_IN_STREAM) {
- code = pdf_try_prepare_fill(pdev, pgs);
+ code = pdf_try_prepare_fill(pdev, pgs, for_text);
if (code != gs_error_interrupt) /* See pdf_open_gstate */
return code;
code = pdf_open_contents(pdev, PDF_IN_STREAM);
if (code < 0)
return code;
}
- return pdf_try_prepare_fill(pdev, pgs);
+ return pdf_try_prepare_fill(pdev, pgs, for_text);
}
/* Update the graphics state for stroking. */
static int
-pdf_try_prepare_stroke(gx_device_pdf *pdev, const gs_gstate *pgs)
+pdf_try_prepare_stroke(gx_device_pdf *pdev, const gs_gstate *pgs, bool for_text)
+{
+ pdf_resource_t *pres = 0;
+ int code = pdf_prepare_drawing(pdev, pgs, &pres, for_text);
+
+ if (code < 0)
+ return code;
+ if (pdev->rendering_intent != pgs->renderingintent && !pdev->ForOPDFRead) {
+ static const char *const ri_names[] = { "Perceptual", "RelativeColorimetric", "Saturation", "AbsoluteColorimetric" };
+ char buf[32];
+
+ code = pdf_open_gstate(pdev, &pres);
+ if (code < 0)
+ return code;
+
+ buf[0] = '/';
+ strncpy(buf + 1, ri_names[pgs->renderingintent], sizeof(buf) - 2);
+ code = cos_dict_put_string_copy(resource_dict(pres), "/RI", buf);
+ if (code < 0)
+ return code;
+ pdev->rendering_intent = pgs->renderingintent;
+ }
+ /* Update overprint, stroke adjustment. */
+ if (pdev->params.PreserveOverprintSettings &&
+ pdev->stroke_overprint != pgs->stroke_overprint &&
+ !pdev->skip_colors
+ ) {
+ if (pres == 0)
+ code = pdf_open_gstate(pdev, &pres);
+ if (code < 0)
+ return code;
+ code = cos_dict_put_c_key_bool(resource_dict(pres), "/OP", pgs->stroke_overprint);
+ if (code < 0)
+ return code;
+ pdev->stroke_overprint = pgs->stroke_overprint;
+
+ /* According to PDF>=1.3 spec, OP also sets op,
+ if there is no /op in same graphic state object.
+ We don't write /op, so monitor the viewer's state here : */
+ pdev->fill_overprint = pgs->stroke_overprint;
+ }
+ if (pdev->state.stroke_adjust != pgs->stroke_adjust) {
+ code = pdf_open_gstate(pdev, &pres);
+ if (code < 0)
+ return code;
+ code = cos_dict_put_c_key_bool(resource_dict(pres), "/SA", pgs->stroke_adjust);
+ if (code < 0)
+ return code;
+ pdev->state.stroke_adjust = pgs->stroke_adjust;
+ }
+ return pdf_end_gstate(pdev, pres);
+}
+int
+pdf_prepare_stroke(gx_device_pdf *pdev, const gs_gstate *pgs, bool for_text)
+{
+ int code;
+
+ if (pdev->context != PDF_IN_STREAM) {
+ code = pdf_try_prepare_stroke(pdev, pgs, for_text);
+ if (code != gs_error_interrupt) /* See pdf_open_gstate */
+ return code;
+ code = pdf_open_contents(pdev, PDF_IN_STREAM);
+ if (code < 0)
+ return code;
+ }
+ return pdf_try_prepare_stroke(pdev, pgs, for_text);
+}
+
+static int
+pdf_try_prepare_fill_stroke(gx_device_pdf *pdev, const gs_gstate *pgs, bool for_text)
{
pdf_resource_t *pres = 0;
- int code = pdf_prepare_drawing(pdev, pgs, &pres);
+ int code = pdf_prepare_drawing(pdev, pgs, &pres, for_text);
if (code < 0)
return code;
+ /* Update overprint. */
+ if (pdev->params.PreserveOverprintSettings &&
+ (pdev->fill_overprint != pgs->overprint ||
+ pdev->stroke_overprint != pgs->stroke_overprint ||
+ pdev->font3) && !pdev->skip_colors
+ ) {
+ code = pdf_open_gstate(pdev, &pres);
+ if (code < 0)
+ return code;
+ /* PDF 1.2 only has a single overprint setting. */
+ if (pdev->CompatibilityLevel < 1.3) {
+ code = cos_dict_put_c_key_bool(resource_dict(pres), "/OP", pgs->overprint);
+ if (code < 0)
+ return code;
+ pdev->stroke_overprint = pgs->overprint;
+ } else {
+ code = cos_dict_put_c_key_bool(resource_dict(pres), "/op", pgs->overprint);
+ if (code < 0)
+ return code;
+ }
+ pdev->fill_overprint = pgs->overprint;
+ }
/* Update overprint, stroke adjustment. */
if (pdev->params.PreserveOverprintSettings &&
- pdev->stroke_overprint != pgs->overprint &&
+ pdev->stroke_overprint != pgs->stroke_overprint &&
!pdev->skip_colors
) {
code = pdf_open_gstate(pdev, &pres);
if (code < 0)
return code;
- code = cos_dict_put_c_key_bool(resource_dict(pres), "/OP", pgs->overprint);
+ code = cos_dict_put_c_key_bool(resource_dict(pres), "/OP", pgs->stroke_overprint);
if (code < 0)
return code;
- pdev->stroke_overprint = pgs->overprint;
+ pdev->stroke_overprint = pgs->stroke_overprint;
if (pdev->CompatibilityLevel < 1.3) {
/* PDF 1.2 only has a single overprint setting. */
- pdev->fill_overprint = pgs->overprint;
+ pdev->fill_overprint = pgs->stroke_overprint;
} else {
/* According to PDF>=1.3 spec, OP also sets op,
if there is no /op in same garphic state object.
@@ -3224,20 +3323,21 @@ pdf_try_prepare_stroke(gx_device_pdf *pdev, const gs_gstate *pgs)
}
return pdf_end_gstate(pdev, pres);
}
+
int
-pdf_prepare_stroke(gx_device_pdf *pdev, const gs_gstate *pgs)
+pdf_prepare_fill_stroke(gx_device_pdf *pdev, const gs_gstate *pgs, bool for_text)
{
int code;
if (pdev->context != PDF_IN_STREAM) {
- code = pdf_try_prepare_stroke(pdev, pgs);
+ code = pdf_try_prepare_fill_stroke(pdev, pgs, for_text);
if (code != gs_error_interrupt) /* See pdf_open_gstate */
return code;
code = pdf_open_contents(pdev, PDF_IN_STREAM);
if (code < 0)
return code;
}
- return pdf_try_prepare_stroke(pdev, pgs);
+ return pdf_try_prepare_fill_stroke(pdev, pgs, for_text);
}
/* Update the graphics state for an image other than an ImageType 1 mask. */
@@ -3248,7 +3348,7 @@ pdf_prepare_image(gx_device_pdf *pdev, const gs_gstate *pgs)
* As it turns out, this requires updating the same parameters as for
* filling.
*/
- return pdf_prepare_fill(pdev, pgs);
+ return pdf_prepare_fill(pdev, pgs, false);
}
/* Update the graphics state for an ImageType 1 mask. */
diff --git a/devices/vector/gdevpdfg.h b/devices/vector/gdevpdfg.h
index ffa7296d..e846b1a8 100644
--- a/devices/vector/gdevpdfg.h
+++ b/devices/vector/gdevpdfg.h
@@ -150,10 +150,11 @@ int pdf_set_drawing_color(gx_device_pdf * pdev, const gs_gstate * pgs,
* Bring the graphics state up to date for a drawing operation.
* (Text uses either fill or stroke.)
*/
-int pdf_try_prepare_fill(gx_device_pdf *pdev, const gs_gstate *pgs);
-int pdf_prepare_drawing(gx_device_pdf *pdev, const gs_gstate *pgs, pdf_resource_t **ppres);
-int pdf_prepare_fill(gx_device_pdf *pdev, const gs_gstate *pgs);
-int pdf_prepare_stroke(gx_device_pdf *pdev, const gs_gstate *pgs);
+int pdf_try_prepare_fill(gx_device_pdf *pdev, const gs_gstate *pgs, bool for_text);
+int pdf_prepare_drawing(gx_device_pdf *pdev, const gs_gstate *pgs, pdf_resource_t **ppres, bool for_text);
+int pdf_prepare_fill(gx_device_pdf *pdev, const gs_gstate *pgs, bool for_text);
+int pdf_prepare_stroke(gx_device_pdf *pdev, const gs_gstate *pgs, bool for_text);
+int pdf_prepare_fill_stroke(gx_device_pdf *pdev, const gs_gstate *pgs, bool for_text);
int pdf_prepare_image(gx_device_pdf *pdev, const gs_gstate *pgs);
int pdf_prepare_imagemask(gx_device_pdf *pdev, const gs_gstate *pgs,
const gx_drawing_color *pdcolor);
diff --git a/devices/vector/gdevpdfi.c b/devices/vector/gdevpdfi.c
index fed96e46..b73ed3d6 100644
--- a/devices/vector/gdevpdfi.c
+++ b/devices/vector/gdevpdfi.c
@@ -1511,7 +1511,7 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
image[0].pixel.ColorSpace = pcs_orig;
image[0].pixel.BitsPerComponent = pim->BitsPerComponent;
code = psdf_setup_image_colors_filter(&pie->writer.binary[0],
- (gx_device_psdf *)pdev, &image[0].pixel, pgs);
+ (gx_device_psdf *)pdev, pim, &image[0].pixel, pgs);
if (code < 0)
goto fail_and_fallback;
image[0].pixel.ColorSpace = pcs_device;
@@ -1556,8 +1556,9 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
goto fail_and_fallback;
} else if (convert_to_process_colors) {
image[1].pixel.ColorSpace = pcs_orig;
+ image[1].pixel.BitsPerComponent = pim->BitsPerComponent;
code = psdf_setup_image_colors_filter(&pie->writer.binary[1],
- (gx_device_psdf *)pdev, &image[1].pixel, pgs);
+ (gx_device_psdf *)pdev, pim, &image[1].pixel, pgs);
if (code < 0) {
goto fail_and_fallback;
}
@@ -1595,9 +1596,13 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
pmat, pgs, force_lossless, in_line);
if (code < 0)
goto fail_and_fallback;
+ /* Bug701972 -- added input_width arg here. For this case, just passing in the same
+ * width as before, so nothing changes. This is an obscure case that isn't tested
+ * on the cluster (note that it requires CompatibilityLevel < 1.3).
+ */
psdf_setup_image_to_mask_filter(&pie->writer.binary[i],
- (gx_device_psdf *)pdev, pim->Width, pim->Height,
- num_components, pim->BitsPerComponent, image[i].type4.MaskColor);
+ (gx_device_psdf *)pdev, pim->Width, pim->Height, pim->Width,
+ num_components, pim->BitsPerComponent, image[i].type4.MaskColor);
code = pdf_begin_image_data_decoded(pdev, num_components, pranges, i,
&image[i].pixel, &cs_value, pie);
if (code < 0)
@@ -1878,7 +1883,7 @@ pdf_image_end_image_data(gx_image_enum_common_t * info, bool draw_last,
pdf_image_enum *pie = (pdf_image_enum *)info;
int height = pie->writer.height;
int data_height = height - pie->rows_left;
- int code = 0;
+ int code = 0, ecode;
if (pie->writer.pres)
((pdf_x_object_t *)pie->writer.pres)->data_height = data_height;
@@ -1920,6 +1925,12 @@ pdf_image_end_image_data(gx_image_enum_common_t * info, bool draw_last,
if (pie->initial_colorspace != pdev->pcm_color_info_index)
pdf_set_process_color_model(pdev, pie->initial_colorspace);
+ /* 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;
+ }
+
gx_image_free_enum(&info);
return code;
}
diff --git a/devices/vector/gdevpdfp.c b/devices/vector/gdevpdfp.c
index df2ff377..2f29dba5 100644
--- a/devices/vector/gdevpdfp.c
+++ b/devices/vector/gdevpdfp.c
@@ -127,6 +127,7 @@ static const gs_param_item_t pdf_param_items[] = {
pi("FastWebView", gs_param_type_bool, Linearise),
pi("NoOutputFonts", gs_param_type_bool, FlattenFonts),
pi("WantsPageLabels", gs_param_type_bool, WantsPageLabels),
+ pi("UserUnit", gs_param_type_float, UserUnit),
#undef pi
gs_param_item_end
};
@@ -237,6 +238,14 @@ gdev_pdf_get_param(gx_device *dev, char *Param, void *list)
if (strcmp(Param, "ForOPDFRead") == 0) {
return(param_write_bool(plist, "ForOPDFRead", &pdev->ForOPDFRead));
}
+ if (strcmp(Param, "PassUserUnit") == 0) {
+ bool dummy;
+ if (pdev->CompatibilityLevel > 1.5)
+ dummy = true;
+ else
+ dummy = false;
+ return(param_write_bool(plist, "PassUserUnit", &dummy));
+ }
if (!pdev->is_ps2write) {
if (strcmp(Param, "pdfmark") == 0){
return(param_write_null(plist, "pdfmark"));
@@ -559,6 +568,16 @@ gdev_pdf_put_params_impl(gx_device * dev, const gx_device_pdf * save_dev, gs_par
if (cl < 1.2) {
pdev->HaveCFF = false;
}
+
+ ecode = param_read_float(plist, "UserUnit", &pdev->UserUnit);
+ if (ecode < 0)
+ goto fail;
+ if (pdev->UserUnit == 0 || (pdev->UserUnit != 1 && pdev->CompatibilityLevel < 1.6)) {
+ ecode = gs_note_error(gs_error_rangecheck);
+ param_signal_error(plist, "UserUnit", ecode);
+ goto fail;
+ }
+
ecode = gdev_psdf_put_params(dev, plist);
if (ecode < 0)
goto fail;
diff --git a/devices/vector/gdevpdft.c b/devices/vector/gdevpdft.c
index e8fb227a..46f4d312 100644
--- a/devices/vector/gdevpdft.c
+++ b/devices/vector/gdevpdft.c
@@ -200,7 +200,7 @@ pdf_begin_transparency_group(gs_gstate * pgs, gx_device_pdf * pdev,
pdf_resource_t *pres, *pres_gstate = NULL;
cos_dict_t *pcd = NULL, *pcd_Resources = NULL;
- code = pdf_prepare_drawing(pdev, pgs, &pres_gstate);
+ code = pdf_prepare_drawing(pdev, pgs, &pres_gstate, false);
if (code < 0)
return code;
code = pdf_end_gstate(pdev, pres_gstate);
@@ -282,7 +282,7 @@ pdf_begin_transparency_mask(gs_gstate * pgs, gx_device_pdf * pdev,
* changed, and so doesn't write out the GState
*/
pgs->soft_mask_id = 0;
- code = pdf_prepare_drawing(pdev, pgs, &pres);
+ 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.
diff --git a/devices/vector/gdevpdfu.c b/devices/vector/gdevpdfu.c
index 0b2b6400..05ea7881 100644
--- a/devices/vector/gdevpdfu.c
+++ b/devices/vector/gdevpdfu.c
@@ -51,7 +51,7 @@
#include "gs_mgl_e.h"
#include "gs_mro_e.h"
-extern single_glyph_list_t *SingleGlyphList;
+extern single_glyph_list_t SingleGlyphList[];
/* Define the size of internal stream buffers. */
/* (This is not a limitation, it only affects performance.) */
@@ -339,7 +339,7 @@ static int write_tt_encodings(stream *s, bool HaveTrueTypes)
if (HaveTrueTypes) {
char Buffer[256];
- single_glyph_list_t *entry = (single_glyph_list_t *)&SingleGlyphList;
+ single_glyph_list_t *entry = SingleGlyphList;
gs_sprintf(Buffer, "/AdobeGlyphList mark\n");
stream_write(s, Buffer, strlen(Buffer));
diff --git a/devices/vector/gdevpdfx.h b/devices/vector/gdevpdfx.h
index b7e00481..0e43a028 100644
--- a/devices/vector/gdevpdfx.h
+++ b/devices/vector/gdevpdfx.h
@@ -326,6 +326,7 @@ typedef struct pdf_page_s {
pdf_page_dsc_info_t dsc_info;
bool NumCopies_set; /* ps2write only. */
int NumCopies; /* ps2write only. */
+ float UserUnit; /* pdfwrite only */
} pdf_page_t;
#define private_st_pdf_page() /* in gdevpdf.c */\
gs_private_st_ptrs2(st_pdf_page, pdf_page_t, "pdf_page_t",\
@@ -479,8 +480,9 @@ struct pdf_font_cache_elem_s {
typedef struct pdf_viewer_state_s {
int transfer_not_identity; /* bitmask */
gs_id transfer_ids[4];
- float opacity_alpha; /* state.opacity.alpha */
- float shape_alpha; /* state.shape.alpha */
+ float strokeconstantalpha;
+ float fillconstantalpha;
+ bool alphaisshape;
gs_blend_mode_t blend_mode; /* state.blend_mode */
gs_id halftone_id;
gs_id black_generation_id;
@@ -618,8 +620,8 @@ struct gx_device_pdf_s {
pdf_page_dsc_info_t page_dsc_info; /* current page */
/* Additional graphics state */
bool fill_overprint, stroke_overprint;
+ int rendering_intent;
bool remap_fill_color, remap_stroke_color;
- int overprint_mode;
gs_id halftone_id;
gs_id transfer_ids[4];
int transfer_not_identity; /* bitmask */
@@ -900,6 +902,7 @@ struct gx_device_pdf_s {
* doing JPEG pass through we write the JPEG data here, and don't write
* anything in the image processing routines.
*/
+ float UserUnit;
};
#define is_in_page(pdev)\
@@ -960,6 +963,7 @@ extern const gx_device_vector_procs pdf_vector_procs;
dev_proc_fill_rectangle(gdev_pdf_fill_rectangle);
dev_proc_fill_path(gdev_pdf_fill_path);
dev_proc_stroke_path(gdev_pdf_stroke_path);
+dev_proc_fill_stroke_path(gdev_pdf_fill_stroke_path);
dev_proc_fillpage(gdev_pdf_fillpage);
/* In gdevpdfi.c */
dev_proc_begin_typed_image(gdev_pdf_begin_typed_image);
diff --git a/devices/vector/gdevpdtb.c b/devices/vector/gdevpdtb.c
index 8c98f4ae..9caa640e 100644
--- a/devices/vector/gdevpdtb.c
+++ b/devices/vector/gdevpdtb.c
@@ -509,7 +509,7 @@ pdf_write_FontFile_entry(gx_device_pdf *pdev, pdf_base_font_t *pbfont)
FontFile_key = "/FontFile2";
break;
default: /* Type 1/2, CIDFontType 0 */
- if (pdev->ResourcesBeforeUsage)
+ if (!pdev->HaveCFF)
FontFile_key = "/FontFile";
else
FontFile_key = "/FontFile3";
diff --git a/devices/vector/gdevpdts.c b/devices/vector/gdevpdts.c
index 8fba9080..055aeb44 100644
--- a/devices/vector/gdevpdts.c
+++ b/devices/vector/gdevpdts.c
@@ -815,7 +815,7 @@ int pdf_set_PaintType0_params (gx_device_pdf *pdev, gs_gstate *pgs, float size,
if (code < 0)
return code;
if (pdev->text->text_state->in.render_mode == ptsv->render_mode){
- code = pdf_prepare_stroke(pdev, pgs);
+ code = pdf_prepare_stroke(pdev, pgs, false);
if (code >= 0)
code = gdev_vector_prepare_stroke((gx_device_vector *)pdev,
pgs, NULL, NULL, 1);
diff --git a/devices/vector/gdevpdtt.c b/devices/vector/gdevpdtt.c
index 2c571de3..f248e998 100644
--- a/devices/vector/gdevpdtt.c
+++ b/devices/vector/gdevpdtt.c
@@ -416,7 +416,7 @@ pdf_prepare_text_drawing(gx_device_pdf *const pdev, gs_text_enum_t *pte)
code = 0;
if (code < 0)
return code;
- code = pdf_prepare_fill(pdev, pgs);
+ code = pdf_prepare_fill(pdev, pgs, true);
if (code < 0)
return code;
}
@@ -2535,7 +2535,7 @@ pdf_set_text_process_state(gx_device_pdf *pdev,
if (code < 0)
return code;
- code = pdf_prepare_stroke(pdev, pgs);
+ code = pdf_prepare_stroke(pdev, pgs, true);
if (code >= 0) {
code = gdev_vector_prepare_stroke((gx_device_vector *)pdev,
pgs, NULL, NULL, 1);
diff --git a/devices/vector/gdevpsdf.h b/devices/vector/gdevpsdf.h
index 959a4143..5047f43a 100644
--- a/devices/vector/gdevpsdf.h
+++ b/devices/vector/gdevpsdf.h
@@ -459,11 +459,14 @@ int psdf_setup_compression_chooser(psdf_binary_writer *pbw,
/* Set up an "image to mask" filter. */
int psdf_setup_image_to_mask_filter(psdf_binary_writer *pbw, gx_device_psdf *pdev,
- int width, int height, int depth, int bits_per_sample, uint *MaskColor);
+ int width, int height, int input_width,
+ int depth, int bits_per_sample, uint *MaskColor);
/* Set up an image colors filter. */
int psdf_setup_image_colors_filter(psdf_binary_writer *pbw,
- gx_device_psdf *pdev, gs_pixel_image_t * pim,
+ gx_device_psdf *pdev,
+ const gs_pixel_image_t *input_pim,
+ gs_pixel_image_t * pim,
const gs_gstate *pgs);
/* ---------------- Symbolic data printing ---------------- */
diff --git a/devices/vector/gdevpsdi.c b/devices/vector/gdevpsdi.c
index 485d685a..9c2adb72 100644
--- a/devices/vector/gdevpsdi.c
+++ b/devices/vector/gdevpsdi.c
@@ -828,7 +828,8 @@ psdf_setup_compression_chooser(psdf_binary_writer *pbw, gx_device_psdf *pdev,
/* Set up an "image to mask" filter. */
int
psdf_setup_image_to_mask_filter(psdf_binary_writer *pbw, gx_device_psdf *pdev,
- int width, int height, int depth, int bits_per_sample, uint *MaskColor)
+ int width, int height, int input_width,
+ int depth, int bits_per_sample, uint *MaskColor)
{
int code;
stream_state *ss = s_alloc_state(pdev->memory, s__image_colors_template.stype,
@@ -842,7 +843,7 @@ psdf_setup_image_to_mask_filter(psdf_binary_writer *pbw, gx_device_psdf *pdev,
if (code < 0)
return code;
s_image_colors_set_dimensions((stream_image_colors_state *)ss,
- width, height, depth, bits_per_sample);
+ width, height, input_width, depth, bits_per_sample);
s_image_colors_set_mask_colors((stream_image_colors_state *)ss, MaskColor);
return 0;
}
@@ -850,7 +851,9 @@ psdf_setup_image_to_mask_filter(psdf_binary_writer *pbw, gx_device_psdf *pdev,
/* Set up an image colors filter. */
int
psdf_setup_image_colors_filter(psdf_binary_writer *pbw,
- gx_device_psdf *pdev, gs_pixel_image_t * pim,
+ gx_device_psdf *pdev,
+ const gs_pixel_image_t *input_pim,
+ gs_pixel_image_t * pim,
const gs_gstate *pgs)
{ /* fixme: currently it's a stub convertion to mask. */
int code;
@@ -866,9 +869,9 @@ psdf_setup_image_colors_filter(psdf_binary_writer *pbw,
if (code < 0)
return code;
s_image_colors_set_dimensions((stream_image_colors_state *)ss,
- pim->Width, pim->Height,
- gs_color_space_num_components(pim->ColorSpace),
- pim->BitsPerComponent);
+ pim->Width, pim->Height, input_pim->Width,
+ gs_color_space_num_components(pim->ColorSpace),
+ pim->BitsPerComponent);
s_image_colors_set_color_space((stream_image_colors_state *)ss,
(gx_device *)pdev, pim->ColorSpace, pgs, pim->Decode);
pim->BitsPerComponent = pdev->color_info.comp_bits[0]; /* Same precision for all components. */
diff --git a/devices/vector/gdevpsds.c b/devices/vector/gdevpsds.c
index 44ba2b4c..65bbf544 100644
--- a/devices/vector/gdevpsds.c
+++ b/devices/vector/gdevpsds.c
@@ -1248,13 +1248,14 @@ s_image_colors_set_mask_colors(stream_image_colors_state * ss, uint *MaskColor)
/* Set image dimensions. */
void
s_image_colors_set_dimensions(stream_image_colors_state * ss,
- int width, int height, int depth, int bits_per_sample)
+ int width, int height, int input_width,
+ int depth, int bits_per_sample)
{
ss->width = width;
ss->height = height;
ss->depth = depth;
ss->bits_per_sample = bits_per_sample;
- ss->row_bits = bits_per_sample * depth * width;
+ ss->row_bits = bits_per_sample * depth * input_width;
ss->raster = bitmap_raster(ss->row_bits);
ss->row_alignment_bytes = 0; /* (ss->raster * 8 - ss->row_bits) / 8) doesn't work. */
}
diff --git a/devices/vector/gdevpsds.h b/devices/vector/gdevpsds.h
index 310072ce..35a756f0 100644
--- a/devices/vector/gdevpsds.h
+++ b/devices/vector/gdevpsds.h
@@ -253,7 +253,8 @@ struct stream_image_transfer_state_s {
stream_image_colors_reloc_ptrs, pcs, pdev, pgs)
void s_image_colors_set_dimensions(stream_image_colors_state * st,
- int width, int height, int depth, int bits_per_sample);
+ int width, int height, int input_width,
+ int depth, int bits_per_sample);
void s_image_colors_set_mask_colors(stream_image_colors_state * ss, uint *MaskColor);
diff --git a/devices/vector/gdevpsdu.c b/devices/vector/gdevpsdu.c
index c86405ec..d626358a 100644
--- a/devices/vector/gdevpsdu.c
+++ b/devices/vector/gdevpsdu.c
@@ -393,6 +393,8 @@ psdf_DCT_filter(gs_param_list *plist /* may be NULL */,
&st_jpeg_compress_data, "zDCTE");
if (jcdp == 0)
return_error(gs_error_VMerror);
+ jcdp->cinfo.mem = NULL;
+ jcdp->cinfo.client_data = NULL;
ss->data.compress = jcdp;
jcdp->memory = ss->jpeg_memory = mem; /* set now for allocation */
if ((code = gs_jpeg_create_compress(ss)) < 0)
diff --git a/devices/vector/gdevpsu.c b/devices/vector/gdevpsu.c
index 10a13d95..094ff945 100644
--- a/devices/vector/gdevpsu.c
+++ b/devices/vector/gdevpsu.c
@@ -186,8 +186,13 @@ psw_begin_file_header(gp_file *f, const gx_device *dev, const gs_rect *pbbox,
time_t t;
struct tm tms;
+#ifdef CLUSTER
+ memset(&t, 0, sizeof(t));
+ memset(&tms, 0, sizeof(tms));
+#else
time(&t);
tms = *localtime(&t);
+#endif
fprintf(f, "%%%%CreationDate: %d/%02d/%02d %02d:%02d:%02d\n",
tms.tm_year + 1900, tms.tm_mon + 1, tms.tm_mday,
tms.tm_hour, tms.tm_min, tms.tm_sec);
diff --git a/devices/vector/gdevpx.c b/devices/vector/gdevpx.c
index 5d2d0edf..a1fce1b7 100644
--- a/devices/vector/gdevpx.c
+++ b/devices/vector/gdevpx.c
@@ -741,6 +741,7 @@ pclxl_write_image_data_RLE(gx_device_pclxl * xdev, const byte * base,
goto nc;
s_RLE_set_defaults_inline(&rlstate);
rlstate.EndOfData = false;
+ rlstate.omitEOD = true;
s_RLE_init_inline(&rlstate);
w.ptr = buf - 1;
w.limit = w.ptr + num_bytes;
diff --git a/devices/vector/gdevtxtw.c b/devices/vector/gdevtxtw.c
index aed535bc..87f9355d 100644
--- a/devices/vector/gdevtxtw.c
+++ b/devices/vector/gdevtxtw.c
@@ -37,10 +37,10 @@
/* #define TRACE_TXTWRITE 1 */
-extern single_glyph_list_t *SingleGlyphList;
-extern double_glyph_list_t *DoubleGlyphList;
-extern treble_glyph_list_t *TrebleGlyphList;
-extern quad_glyph_list_t *QuadGlyphList;
+extern single_glyph_list_t SingleGlyphList[];
+extern double_glyph_list_t DoubleGlyphList[];
+extern treble_glyph_list_t TrebleGlyphList[];
+extern quad_glyph_list_t QuadGlyphList[];
/*
* Define the structure used to return glyph width information. Note that
* there are two different sets of width information: real-number (x,y)
@@ -1046,10 +1046,10 @@ txtwrite_put_params(gx_device * dev, gs_param_list * plist)
{
gx_device_txtwrite_t *tdev = (gx_device_txtwrite_t *) dev;
int ecode = 0;
- int code;
+ int code, old_TextFormat = tdev->TextFormat;
const char *param_name;
gs_param_string ofs;
- bool dummy;
+ bool dummy, open = dev->is_open;
switch (code = param_read_string(plist, (param_name = "OutputFile"), &ofs)) {
case 0:
@@ -1092,12 +1092,6 @@ txtwrite_put_params(gx_device * dev, gs_param_list * plist)
if (code < 0)
return code;
- code = gx_default_put_params(dev, plist);
- if (code < 0)
- return code;
-
- dev->interpolate_control = 0;
-
if (ofs.data != 0) { /* Close the file if it's open. */
if (tdev->file != 0) {
gp_fclose(tdev->file);
@@ -1106,6 +1100,23 @@ txtwrite_put_params(gx_device * dev, gs_param_list * plist)
memcpy(tdev->fname, ofs.data, ofs.size);
tdev->fname[ofs.size] = 0;
}
+
+ /* If we change media size then gs_default_put_params will close
+ * the device if it is open. We don't want it to do that, so set
+ * the device's 'is_open' flag to false, and reset it after we've
+ * processed the params.
+ */
+ if (old_TextFormat == tdev->TextFormat && open)
+ dev->is_open = false;
+
+ code = gx_default_put_params(dev, plist);
+ if (code < 0)
+ return code;
+
+ dev->is_open = open;
+
+ dev->interpolate_control = 0;
+
return 0;
}
@@ -1693,97 +1704,99 @@ static int get_unicode(textw_text_enum_t *penum, gs_font *font, gs_glyph glyph,
length = font->procs.decode_glyph((gs_font *)font, glyph, ch, NULL, 0);
if (length == 0) {
- code = font->procs.glyph_name(font, glyph, &gnstr);
- if (code >= 0 && gnstr.size == 7) {
- if (!memcmp(gnstr.data, "uni", 3)) {
- static const char *hexdigits = "0123456789ABCDEF";
- char *d0 = strchr(hexdigits, gnstr.data[3]);
- char *d1 = strchr(hexdigits, gnstr.data[4]);
- char *d2 = strchr(hexdigits, gnstr.data[5]);
- char *d3 = strchr(hexdigits, gnstr.data[6]);
-
- if (d0 != NULL && d1 != NULL && d2 != NULL && d3 != NULL) {
- *Buffer++ = ((d0 - hexdigits) << 12) + ((d1 - hexdigits) << 8) + ((d2 - hexdigits) << 4) + (d3 - hexdigits);
- return 1;
- }
- }
- }
- if (length == 0) {
- single_glyph_list_t *sentry = (single_glyph_list_t *)&SingleGlyphList;
- double_glyph_list_t *dentry = (double_glyph_list_t *)&DoubleGlyphList;
- treble_glyph_list_t *tentry = (treble_glyph_list_t *)&TrebleGlyphList;
- quad_glyph_list_t *qentry = (quad_glyph_list_t *)&QuadGlyphList;
-
- /* Search glyph to single Unicode value table */
- while (sentry->Glyph != 0) {
- if (sentry->Glyph[0] < gnstr.data[0]) {
- sentry++;
- continue;
- }
- if (sentry->Glyph[0] > gnstr.data[0]){
- break;
- }
- if (strlen(sentry->Glyph) == gnstr.size) {
- if(memcmp(gnstr.data, sentry->Glyph, gnstr.size) == 0) {
- *Buffer = sentry->Unicode;
+ if (glyph != GS_NO_GLYPH) {
+ code = font->procs.glyph_name(font, glyph, &gnstr);
+ if (code >= 0 && gnstr.size == 7) {
+ if (!memcmp(gnstr.data, "uni", 3)) {
+ static const char *hexdigits = "0123456789ABCDEF";
+ char *d0 = strchr(hexdigits, gnstr.data[3]);
+ char *d1 = strchr(hexdigits, gnstr.data[4]);
+ char *d2 = strchr(hexdigits, gnstr.data[5]);
+ char *d3 = strchr(hexdigits, gnstr.data[6]);
+
+ if (d0 != NULL && d1 != NULL && d2 != NULL && d3 != NULL) {
+ *Buffer++ = ((d0 - hexdigits) << 12) + ((d1 - hexdigits) << 8) + ((d2 - hexdigits) << 4) + (d3 - hexdigits);
return 1;
}
}
- sentry++;
}
-
- /* Search glyph to double Unicode value table */
- while (dentry->Glyph != 0) {
- if (dentry->Glyph[0] < gnstr.data[0]) {
- dentry++;
- continue;
- }
- if (dentry->Glyph[0] > gnstr.data[0]){
- break;
- }
- if (strlen(dentry->Glyph) == gnstr.size) {
- if(memcmp(gnstr.data, dentry->Glyph, gnstr.size) == 0) {
- memcpy(Buffer, dentry->Unicode, 2);
- return 2;
+ if (length == 0) {
+ single_glyph_list_t *sentry = SingleGlyphList;
+ double_glyph_list_t *dentry = DoubleGlyphList;
+ treble_glyph_list_t *tentry = TrebleGlyphList;
+ quad_glyph_list_t *qentry = QuadGlyphList;
+
+ /* Search glyph to single Unicode value table */
+ while (sentry->Glyph != 0) {
+ if (sentry->Glyph[0] < gnstr.data[0]) {
+ sentry++;
+ continue;
+ }
+ if (sentry->Glyph[0] > gnstr.data[0]){
+ break;
}
+ if (strlen(sentry->Glyph) == gnstr.size) {
+ if(memcmp(gnstr.data, sentry->Glyph, gnstr.size) == 0) {
+ *Buffer = sentry->Unicode;
+ return 1;
+ }
+ }
+ sentry++;
}
- dentry++;
- }
- /* Search glyph to triple Unicode value table */
- while (tentry->Glyph != 0) {
- if (tentry->Glyph[0] < gnstr.data[0]) {
- tentry++;
- continue;
- }
- if (tentry->Glyph[0] > gnstr.data[0]){
- break;
- }
- if (strlen(tentry->Glyph) == gnstr.size) {
- if(memcmp(gnstr.data, tentry->Glyph, gnstr.size) == 0) {
- memcpy(Buffer, tentry->Unicode, 3);
- return 3;
+ /* Search glyph to double Unicode value table */
+ while (dentry->Glyph != 0) {
+ if (dentry->Glyph[0] < gnstr.data[0]) {
+ dentry++;
+ continue;
+ }
+ if (dentry->Glyph[0] > gnstr.data[0]){
+ break;
+ }
+ if (strlen(dentry->Glyph) == gnstr.size) {
+ if(memcmp(gnstr.data, dentry->Glyph, gnstr.size) == 0) {
+ memcpy(Buffer, dentry->Unicode, 2);
+ return 2;
+ }
}
+ dentry++;
}
- tentry++;
- }
- /* Search glyph to quadruple Unicode value table */
- while (qentry->Glyph != 0) {
- if (qentry->Glyph[0] < gnstr.data[0]) {
- qentry++;
- continue;
- }
- if (qentry->Glyph[0] > gnstr.data[0]){
- break;
+ /* Search glyph to triple Unicode value table */
+ while (tentry->Glyph != 0) {
+ if (tentry->Glyph[0] < gnstr.data[0]) {
+ tentry++;
+ continue;
+ }
+ if (tentry->Glyph[0] > gnstr.data[0]){
+ break;
+ }
+ if (strlen(tentry->Glyph) == gnstr.size) {
+ if(memcmp(gnstr.data, tentry->Glyph, gnstr.size) == 0) {
+ memcpy(Buffer, tentry->Unicode, 3);
+ return 3;
+ }
+ }
+ tentry++;
}
- if (strlen(qentry->Glyph) == gnstr.size) {
- if(memcmp(gnstr.data, qentry->Glyph, gnstr.size) == 0) {
- memcpy(Buffer, qentry->Unicode, 4);
- return 4;
+
+ /* Search glyph to quadruple Unicode value table */
+ while (qentry->Glyph != 0) {
+ if (qentry->Glyph[0] < gnstr.data[0]) {
+ qentry++;
+ continue;
+ }
+ if (qentry->Glyph[0] > gnstr.data[0]){
+ break;
+ }
+ if (strlen(qentry->Glyph) == gnstr.size) {
+ if(memcmp(gnstr.data, qentry->Glyph, gnstr.size) == 0) {
+ memcpy(Buffer, qentry->Unicode, 4);
+ return 4;
+ }
}
+ qentry++;
}
- qentry++;
}
}
*Buffer = fallback;
@@ -1890,8 +1903,8 @@ txtwrite_process_cmap_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, chr, &penum->TextBuffer[penum->TextBufferIndex]);
penum->Widths[penum->TextBufferIndex] += dpt.x;
+ penum->TextBufferIndex += get_unicode(penum, (gs_font *)pte->orig_font, glyph, chr, &penum->TextBuffer[penum->TextBufferIndex]);
break;
case 2: /* end of string */
return 0;
@@ -2109,7 +2122,8 @@ 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);
- memcpy(penum->text_state->Widths, penum->Widths, penum->TextBufferIndex * sizeof(float));
+ memset(penum->text_state->Widths, 0x00, penum->TextBufferIndex * sizeof(float));
+ memcpy(penum->text_state->Widths, penum->Widths, penum->text.size * sizeof(float));
unsorted_entry->Unicode_Text = (unsigned short *)gs_malloc(tdev->memory->stable_memory,
penum->TextBufferIndex, sizeof(unsigned short), "txtwrite alloc sorted text buffer");
@@ -2121,7 +2135,8 @@ 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);
- memcpy(unsorted_entry->Widths, penum->Widths, penum->TextBufferIndex * sizeof(float));
+ memset(unsorted_entry->Widths, 0x00, penum->TextBufferIndex * sizeof(float));
+ memcpy(unsorted_entry->Widths, penum->Widths, penum->text.size * 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");
diff --git a/devices/vector/gdevxps.c b/devices/vector/gdevxps.c
index 71ca1f74..5d98c283 100644
--- a/devices/vector/gdevxps.c
+++ b/devices/vector/gdevxps.c
@@ -152,9 +152,12 @@ typedef struct xps_image_enum_s {
gp_file *fid;
} xps_image_enum_t;
-gs_private_st_suffix_add4(st_xps_image_enum, xps_image_enum_t,
+static void
+xps_image_enum_finalize(const gs_memory_t *cmem, void *vptr);
+
+gs_private_st_suffix_add4_final(st_xps_image_enum, xps_image_enum_t,
"xps_image_enum_t", xps_image_enum_enum_ptrs,
- xps_image_enum_reloc_ptrs, st_vector_image_enum,
+ xps_image_enum_reloc_ptrs, xps_image_enum_finalize, st_vector_image_enum,
buffer, devc_buffer, pcs, pgs);
typedef struct gx_device_xps_s {
@@ -1424,6 +1427,11 @@ xps_finish_image_path(gx_device_vector *vdev)
const char *fmt;
gs_matrix matrix;
+ /* If an error occurs during an image, we can get here after the enumerator
+ * has been freed - if that's the case, just bail out immediately
+ */
+ if (xps->xps_pie == NULL)
+ return;
/* Path is started. Do the image brush image brush and close the path */
write_str_to_current_page(xps, "\t<Path.Fill>\n");
write_str_to_current_page(xps, "\t\t<ImageBrush ");
@@ -2214,17 +2222,6 @@ xps_image_end_image(gx_image_enum_common_t * info, bool draw_last)
code = xps_add_image_relationship(pie);
exit:
- if (pie->pcs != NULL)
- rc_decrement(pie->pcs, "xps_image_end_image (pcs)");
- if (pie->buffer != NULL)
- gs_free_object(pie->memory, pie->buffer, "xps_image_end_image");
- if (pie->devc_buffer != NULL)
- gs_free_object(pie->memory, pie->devc_buffer, "xps_image_end_image");
-
- /* ICC clean up */
- if (pie->icc_link != NULL)
- gsicc_release_link(pie->icc_link);
-
return code;
}
@@ -2485,3 +2482,23 @@ tiff_from_name(gx_device_xps *dev, const char *name, int big_endian, bool usebig
xps_tifsDummyUnmapProc);
return t;
}
+
+static void
+xps_image_enum_finalize(const gs_memory_t *cmem, void *vptr)
+{
+ xps_image_enum_t *xpie = (xps_image_enum_t *)vptr;
+ gx_device_xps *xdev = (gx_device_xps *)xpie->dev;
+
+ xpie->dev = NULL;
+ if (xpie->pcs != NULL)
+ rc_decrement(xpie->pcs, "xps_image_end_image (pcs)");
+ if (xpie->buffer != NULL)
+ gs_free_object(xpie->memory, xpie->buffer, "xps_image_end_image");
+ if (xpie->devc_buffer != NULL)
+ gs_free_object(xpie->memory, xpie->devc_buffer, "xps_image_end_image");
+
+ /* ICC clean up */
+ if (xpie->icc_link != NULL)
+ gsicc_release_link(xpie->icc_link);
+ xdev->xps_pie = NULL;
+}