diff options
Diffstat (limited to 'devices/vector/gdevpdts.c')
-rw-r--r-- | devices/vector/gdevpdts.c | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/devices/vector/gdevpdts.c b/devices/vector/gdevpdts.c index ec946ac4..4b3de5e1 100644 --- a/devices/vector/gdevpdts.c +++ b/devices/vector/gdevpdts.c @@ -67,7 +67,7 @@ gs_private_st_ptrs2(st_pdf_text_state, pdf_text_state_t, "pdf_text_state_t", * pdf_append_chars.) Requires pts->buffer.count_chars > 0. */ static int -append_text_move(pdf_text_state_t *pts, double dw) +append_text_move(gx_device_pdf *pdev, pdf_text_state_t *pts, double dw) { int count = pts->buffer.count_moves; int pos = pts->buffer.count_chars; @@ -81,6 +81,10 @@ append_text_move(pdf_text_state_t *pts, double dw) rounded = floor(dw + 0.5); if (fabs(dw - rounded) < 0.001) dw = rounded; + if (pdev->PDFA == 1 && dw < -MAX_USER_COORD) { + /* PDF/A-1 limit on co-ordinates */ + return -1; + } if (dw != 0) { if (count == MAX_TEXT_BUFFER_MOVES) return -1; @@ -168,11 +172,47 @@ 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) { + 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) || pdev->PDFA != 1)) + ) { /* Use TJ. */ int code; - code = append_text_move(pts, tdw); + if (tdw < MAX_USER_COORD || pdev->PDFA != 1) + code = append_text_move(pdev, pts, tdw); + else + return -1; + if (code >= 0) goto finish; } |