[gs-cvs] rev 7881 - trunk/gs/src

leonardo at ghostscript.com leonardo at ghostscript.com
Tue Apr 24 20:28:32 PDT 2007


Author: leonardo
Date: 2007-04-24 20:28:32 -0700 (Tue, 24 Apr 2007)
New Revision: 7881

Modified:
   trunk/gs/src/gstype42.c
Log:
Fix (TT fonts) : Allow 'loca' elements to be broken into parts with 'sfnts' strings.

DETAILS : 

Bug 689038 "GS doesn't display T42 font correctly.".

The Type 42 specification reads that 'sfnts' strings must not break TT tables.
Exactly, "the strings must begin at TrueType table boundaries, or
at individual glyph boundaries within the glyf table".
However the test case is another example when a 3d party software 
"LilyPond 2.11.10" doesn't follow this constraint. 
We prefer to handle such font data, 
because we have not enough control for fonts in wild.

The new function gs_type42_read_data is factored out
from the old code of default_get_outline.
Due to that we believe that the change to default_get_outline
is algorithmically equivalent.

This patch does not propagate error codes from
gs_type42_read_data in get_glyph_offset. 
This is done intentionally for keeping the patch simpler, 
and for keeping the behavior closer to the old one. 
It simplifies the regression testing.
Propagating the error codes should be a next step.

EXPECTED DIFFERENCES :

None.


Modified: trunk/gs/src/gstype42.c
===================================================================
--- trunk/gs/src/gstype42.c	2007-04-24 16:21:21 UTC (rev 7880)
+++ trunk/gs/src/gstype42.c	2007-04-25 03:28:32 UTC (rev 7881)
@@ -69,22 +69,41 @@
 
 GS_NOTIFY_PROC(gs_len_glyphs_release);
 
+/* Read data from sfnts. */
+private int
+gs_type42_read_data(gs_font_type42 * pfont, ulong pos, uint length, byte *buf)
+{
+    int (*string_proc)(gs_font_type42 *, ulong, uint, const byte **) =
+	pfont->data.string_proc;
+    uint left = length;
+    const byte *data;
+    int code;
+
+    do {
+	code = (*string_proc)(pfont, (ulong)(pos + length - left), left, &data);
+	if (code < 0) 
+	    return code;
+	if (code == 0) 
+	    code = left;
+	memcpy(buf + length - left, data, code);
+	left -= code;
+    } while (left);
+    return 0;
+}
+
 /* Get the offset to a glyph using the loca table */
 private inline ulong
 get_glyph_offset(gs_font_type42 *pfont, uint glyph_index) 
 {
-    int (*string_proc)(gs_font_type42 *, ulong, uint, const byte **) =
-	pfont->data.string_proc;
-    const byte *ploca;
     ulong result;
-    int code;		/* hidden variable used by ACCESS */
+    byte buf[4];
 
     if (pfont->data.indexToLocFormat) {
-	ACCESS(pfont->data.loca + glyph_index * 4, 4, ploca);
-	result = u32(ploca);
+	gs_type42_read_data(pfont, pfont->data.loca + glyph_index * 4, 4, buf);
+	result = u32(buf);
     } else {
-	ACCESS(pfont->data.loca + glyph_index * 2, 2, ploca);
-	result = (ulong) U16(ploca) << 1;
+	gs_type42_read_data(pfont, pfont->data.loca + glyph_index * 2, 2, buf);
+	result = (ulong) U16(buf) << 1;
     }
     return result;
 }
@@ -511,24 +530,15 @@
 	     * Perhaps we can handle it (with a low performance),
 	     * making a contiguous copy.
 	     */
-	    uint left = glyph_length;
 
 	    /* 'code' is the returned length */
 	    buf = (byte *)gs_alloc_string(pgd->memory, glyph_length, "default_get_outline");
 	    if (buf == 0)
 		return_error(gs_error_VMerror);
 	    gs_glyph_data_from_string(pgd, buf, glyph_length, (gs_font *)pfont);
-	    for (;;) {
-		memcpy(buf + glyph_length - left, data, code);
-		if (!(left -= code))
-		    return 0;
-		code = (*string_proc)(pfont, (ulong)(pfont->data.glyf + glyph_start + 
-		              glyph_length - left), left, &data);
-		if (code < 0) 
-		    return code;
-		if (code == 0) 
-		    code = left;
-	    }
+	    memcpy(buf, data, code);
+	    return gs_type42_read_data(pfont, pfont->data.glyf + glyph_start + code, 
+				       glyph_length - code, buf + code);
 	}
     }
     return 0;



More information about the gs-cvs mailing list