[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