[gs-cvs] rev 8324 - trunk/gs/src
ken at ghostscript.com
ken at ghostscript.com
Fri Oct 26 00:41:31 PDT 2007
Author: ken
Date: 2007-10-26 00:41:30 -0700 (Fri, 26 Oct 2007)
New Revision: 8324
Modified:
trunk/gs/src/gdevpsfx.c
Log:
Fix (pdfwrite): Type 1 CharStrings could be converted to invalid
type 2 CharStrings if the glyph program used implicit start points
for subpaths.
DETAILS:
Bug #689055 "pdfwrite creates a bad Type1C font"
If a type 1 CharString used an implicit point, either the initial point
(0,0) or the point resulting from a closepath, then the type 2 output
code duplicated this. Unfortunately this is illegal in type 2 CharStrings
where each subpath must begin with one of the 'move' instructions.
(gdevpsfx.c) psf_convert_type1_to_type2, create a new boolean variable
'need_moveto' initialised to true. When we encounter a move operation,
set it to false. When we encounter a closepath, set it back to true.
Thus this variable is always true at the beginning of a subpath, and
becomes false as soon as a move instruction is encountered.
While converting type 1 CharStrings, whenever the current instruction is
a line drawing operation, if 'need_moveto' create a move instruction,
taking account of any pending glyph widths.
This is only performed on the second (conversion) pass through the type 1
CharSrtring as we don't need to worry about this during the first (hint
collection) pass.
EXPECTED DIFFERENCES:
None
Modified: trunk/gs/src/gdevpsfx.c
===================================================================
--- trunk/gs/src/gdevpsfx.c 2007-10-26 01:49:56 UTC (rev 8323)
+++ trunk/gs/src/gdevpsfx.c 2007-10-26 07:41:30 UTC (rev 8324)
@@ -423,6 +423,7 @@
cv_stem_hint_table hstem_hints; /* horizontal stem hints */
cv_stem_hint_table vstem_hints; /* vertical stem hints */
bool first = true;
+ bool need_moveto = true;
bool replace_hints = false;
bool hints_changed = false;
enum {
@@ -546,6 +547,40 @@
int i;
fixed mx, my;
+ if (need_moveto && ((c >= cx_rlineto && c <= cx_rrcurveto) ||
+ c == cx_vhcurveto || c == cx_hvcurveto))
+ {
+ mx = my = 0;
+ need_moveto = false;
+ CHECK_OP();
+ if (first) {
+ if (cis.os_count)
+ type2_put_fixed(s, *csp); /* width */
+ mx += cis.lsb.x + mx0, my += cis.lsb.y + my0;
+ first = false;
+ /* We need to move all the stored numeric values up by
+ * one in the stack, eliminating the width, so that later
+ * processing when we handle the drswing operator emits the correct
+ * values. This is different to the 'move' case below.
+ */
+ cis.os_count--;
+ for (i = 0; i < cis.os_count; ++i)
+ cis.ostack[i] = cis.ostack[i+1];
+ }
+ CHECK_HINTS_CHANGED();
+ if (mx == 0) {
+ type2_put_fixed(s, my);
+ depth = 1, prev_op = cx_vmoveto;
+ } else if (my == 0) {
+ type2_put_fixed(s, mx);
+ depth = 1, prev_op = cx_hmoveto;
+ } else {
+ type2_put_fixed(s, mx);
+ type2_put_fixed(s, my);
+ depth = 2, prev_op = cx_rmoveto;
+ }
+ }
+
switch (c) {
default:
if (c < 0)
@@ -590,6 +625,7 @@
HINTS_CHANGED();
continue;
case c1_closepath:
+ need_moveto = true;
continue;
case CE_OFFSET + ce1_setcurrentpoint:
if (first) {
@@ -609,6 +645,7 @@
mx = csp[-1], my = *csp;
POP(2);
move:
+ need_moveto = false;
CHECK_OP();
if (first) {
if (cis.os_count)
More information about the gs-cvs
mailing list