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

leonardo at ghostscript.com leonardo at ghostscript.com
Sun Jul 27 02:38:44 PDT 2008


Author: leonardo
Date: 2008-07-27 02:38:42 -0700 (Sun, 27 Jul 2008)
New Revision: 8881

Modified:
   trunk/gs/src/bfont.h
   trunk/gs/src/gstype42.c
   trunk/gs/src/zfcid1.c
   trunk/gs/src/zfont42.c
Log:
Fix (True Type font loader) : Can't work around unsorted 'loca' when 'loca' is not loaded.

DETAILS :

Bug 689893 "Regression: CID font emulation is broken." 

A work around against unsorted 'loca' and its recent improvements
assume that 'loca' presents in sfnts. It is not true
when a CID font is emulated with a True Type disk font,
because in that case the font machinery delay loading
'loca' and 'glyp' elements until a real request from a document.
For more details see comments added in code.

EXPECTED DIFFERENCES :

None.


Modified: trunk/gs/src/bfont.h
===================================================================
--- trunk/gs/src/bfont.h	2008-07-27 09:29:37 UTC (rev 8880)
+++ trunk/gs/src/bfont.h	2008-07-27 09:38:42 UTC (rev 8881)
@@ -42,7 +42,8 @@
     bf_Encoding_optional = 1,	/* build_gs_font */
     bf_UniqueID_ignored = 4,	/* build_gs_simple_font */
     bf_CharStrings_optional = 8,	/* build_gs_primitive_font */
-    bf_notdef_required = 16	/* build_gs_primitive_font */
+    bf_notdef_required = 16,	/* build_gs_primitive_font */
+    bf_has_font_file = 32   /* build_gs_TrueType_font ( only for gs_type42_font_init) */
 } build_font_options_t;
 
 /* In zbfont.c */

Modified: trunk/gs/src/gstype42.c
===================================================================
--- trunk/gs/src/gstype42.c	2008-07-27 09:29:37 UTC (rev 8880)
+++ trunk/gs/src/gstype42.c	2008-07-27 09:38:42 UTC (rev 8881)
@@ -277,81 +277,96 @@
     pfont->data.get_outline = default_get_outline;
     pfont->data.get_metrics = gs_type42_default_get_metrics;
 
-    /* Now build the len_glyphs array since 'loca' may not be properly sorted */
-    pfont->data.len_glyphs = (uint *)gs_alloc_byte_array(pfont->memory, loca_size, sizeof(uint),
-						    "gs_type42_font");
-    if (pfont->data.len_glyphs == 0)
-	return_error(gs_error_VMerror);
-    gs_font_notify_register((gs_font *)pfont, gs_len_glyphs_release, (void *)pfont);
- 
-    /* The 'loca' may not be in order, so we construct a glyph length array */
-    /* Since 'loca' is usually sorted, first try the simple linear scan to  */
-    /* avoid the need to perform the more expensive process. */
-    glyph_start = get_glyph_offset(pfont, 0);
-    for (i = 1; i < loca_size; i++) {
-	glyph_offset = get_glyph_offset(pfont, i);
-	glyph_length = glyph_offset - glyph_start;
-	if (glyph_length > 0x80000000)
-	    break;
-	if (glyph_offset > glyph_size)
-	    break;
-	/* out of order loca */
-	pfont->data.len_glyphs[i - 1] = glyph_length;
-	glyph_start = glyph_offset;
-    }
-    if (i < loca_size) {
-        /*
-         * loca was out of order, build the len_glyphs the hard way.      
-	 * For each glyph, we use the next higher or equal
-	 * glyph offset to compute the glyph length.
-	 * It assumes no overlapping and no duplicate glyphs.
-	 */
-	ulong last_glyph_offset = glyph_size;
-	ulong num_valid_loca_elm = loca_size;
-	long last_offset = 0;
-	gs_type42_font_init_sort_t *psort;
-	gs_type42_font_init_sort_t *psortary = 
-	    (gs_type42_font_init_sort_t *)gs_alloc_byte_array(pfont->memory, 
-		loca_size, sizeof(gs_type42_font_init_sort_t), "gs_type42_font_init(sort loca)");
+    if (pfont->FontType == ft_CID_TrueType && pfont->is_resource) {
+	/* This font was load with .load_tt_font_stripped,
+	   (it's only the case when bf_has_font_file is set because font file
+	   presents with True Type - see zbuildfont11).
+	   Can't use get_glyph_offset because 'loca' does not present in sfnt. 
+	   So we skip the unsorted 'loca' check.
 
-	if (psortary == 0)
+	   A better way would be to perform the unsorted loca check
+	   after glyph cache is initialized in zbuildfont11 with gs_glyph_cache__alloc.
+	   But we're doing this fix under a rush of 8.63 release,
+	   so have no time for deeper changes.
+	*/
+	pfont->data.len_glyphs = NULL;
+    } else {
+	/* Now build the len_glyphs array since 'loca' may not be properly sorted */
+	pfont->data.len_glyphs = (uint *)gs_alloc_byte_array(pfont->memory, loca_size, sizeof(uint),
+							"gs_type42_font");
+	if (pfont->data.len_glyphs == 0)
 	    return_error(gs_error_VMerror);
-	/* loca_size > 0 due to condition above, so we always have the 0th element. */
-	psortary->glyph_num = 0;
-	psortary->glyph_offset = get_glyph_offset(pfont, 0);
-	for (i = 1, psort = psortary + 1; i < loca_size; i++, psort++) {
-	    psort->glyph_num = i;
-	    psort->glyph_offset = get_glyph_offset(pfont, i);
-	    psort[-1].glyph_length = psort->glyph_offset - last_offset;
-	    last_offset = psort->glyph_offset;
+	gs_font_notify_register((gs_font *)pfont, gs_len_glyphs_release, (void *)pfont);
+     
+	/* The 'loca' may not be in order, so we construct a glyph length array */
+	/* Since 'loca' is usually sorted, first try the simple linear scan to  */
+	/* avoid the need to perform the more expensive process. */
+	glyph_start = get_glyph_offset(pfont, 0);
+	for (i = 1; i < loca_size; i++) {
+	    glyph_offset = get_glyph_offset(pfont, i);
+	    glyph_length = glyph_offset - glyph_start;
+	    if (glyph_length > 0x80000000)
+		break;
+	    if (glyph_offset > glyph_size)
+		break;
+	    /* out of order loca */
+	    pfont->data.len_glyphs[i - 1] = glyph_length;
+	    glyph_start = glyph_offset;
 	}
-	psort[-1].glyph_length = 0; /* Dummy element. */
-	qsort(psortary, loca_size, sizeof(gs_type42_font_init_sort_t), gs_type42_font_init_compare);
-	while (num_valid_loca_elm > 0 && psortary[num_valid_loca_elm - 1].glyph_offset > glyph_size)
-	    num_valid_loca_elm --;
-	if (0 == num_valid_loca_elm)
-	    return_error(gs_error_invalidfont);
-	for (i = num_valid_loca_elm; i--;) {
-	    long old_length;
+	if (i < loca_size) {
+	    /*
+	     * loca was out of order, build the len_glyphs the hard way.      
+	     * For each glyph, we use the next higher or equal
+	     * glyph offset to compute the glyph length.
+	     * It assumes no overlapping and no duplicate glyphs.
+	     */
+	    ulong last_glyph_offset = glyph_size;
+	    ulong num_valid_loca_elm = loca_size;
+	    long last_offset = 0;
+	    gs_type42_font_init_sort_t *psort;
+	    gs_type42_font_init_sort_t *psortary = 
+		(gs_type42_font_init_sort_t *)gs_alloc_byte_array(pfont->memory, 
+		    loca_size, sizeof(gs_type42_font_init_sort_t), "gs_type42_font_init(sort loca)");
 
-	    psort = psortary + i;
-	    old_length = psort->glyph_length;
-	    if (old_length < 0 || old_length > 2000 /*  arbitrary */) {
-		pfont->data.len_glyphs[psort->glyph_num] = last_glyph_offset - psort->glyph_offset;
-		/* Note the new length may be so big as old_length. */
-	    } else
-		pfont->data.len_glyphs[psort->glyph_num] = old_length;
-	    last_glyph_offset = psort->glyph_offset;
+	    if (psortary == 0)
+		return_error(gs_error_VMerror);
+	    /* loca_size > 0 due to condition above, so we always have the 0th element. */
+	    psortary->glyph_num = 0;
+	    psortary->glyph_offset = get_glyph_offset(pfont, 0);
+	    for (i = 1, psort = psortary + 1; i < loca_size; i++, psort++) {
+		psort->glyph_num = i;
+		psort->glyph_offset = get_glyph_offset(pfont, i);
+		psort[-1].glyph_length = psort->glyph_offset - last_offset;
+		last_offset = psort->glyph_offset;
+	    }
+	    psort[-1].glyph_length = 0; /* Dummy element. */
+	    qsort(psortary, loca_size, sizeof(gs_type42_font_init_sort_t), gs_type42_font_init_compare);
+	    while (num_valid_loca_elm > 0 && psortary[num_valid_loca_elm - 1].glyph_offset > glyph_size)
+		num_valid_loca_elm --;
+	    if (0 == num_valid_loca_elm)
+		return_error(gs_error_invalidfont);
+	    for (i = num_valid_loca_elm; i--;) {
+		long old_length;
+
+		psort = psortary + i;
+		old_length = psort->glyph_length;
+		if (old_length < 0 || old_length > 2000 /*  arbitrary */) {
+		    pfont->data.len_glyphs[psort->glyph_num] = last_glyph_offset - psort->glyph_offset;
+		    /* Note the new length may be so big as old_length. */
+		} else
+		    pfont->data.len_glyphs[psort->glyph_num] = old_length;
+		last_glyph_offset = psort->glyph_offset;
+	    }
+	    for (i = num_valid_loca_elm; i < loca_size; i++) {
+		psort = psortary + i;
+		pfont->data.len_glyphs[psort->glyph_num] = 0;
+	    }
+	    /* Well the last element of len_glyphs is never used.
+	       We compute it because we're interesting whether it is not zero sometimes. 
+	       To know that, set a conditional breakpoint at the next statement.
+	     */
+	    gs_free_object(pfont->memory, psortary, "gs_type42_font_init(sort loca)");
 	}
-	for (i = num_valid_loca_elm; i < loca_size; i++) {
-	    psort = psortary + i;
-	    pfont->data.len_glyphs[psort->glyph_num] = 0;
-	}
-	/* Well the last element of len_glyphs is never used.
-	   We compute it because we're interesting whether it is not zero sometimes. 
-	   To know that, set a conditional breakpoint at the next statement.
-	 */
-	gs_free_object(pfont->memory, psortary, "gs_type42_font_init(sort loca)");
     }
     /*
      * If the font doesn't have a valid FontBBox, compute one from the

Modified: trunk/gs/src/zfcid1.c
===================================================================
--- trunk/gs/src/zfcid1.c	2008-07-27 09:29:37 UTC (rev 8880)
+++ trunk/gs/src/zfcid1.c	2008-07-27 09:38:42 UTC (rev 8881)
@@ -338,7 +338,8 @@
 				  (const char *)0, "%Type11BuildGlyph",
 				  bf_Encoding_optional |
 				  bf_UniqueID_ignored |
-				  bf_CharStrings_optional);
+				  bf_CharStrings_optional |
+				  (pfile != NULL ? bf_has_font_file : 0));
     if (code < 0)
 	return code;
     pfcid = (gs_font_cid2 *)pfont;

Modified: trunk/gs/src/zfont42.c
===================================================================
--- trunk/gs/src/zfont42.c	2008-07-27 09:29:37 UTC (rev 8880)
+++ trunk/gs/src/zfont42.c	2008-07-27 09:38:42 UTC (rev 8881)
@@ -79,6 +79,7 @@
     ref_assign(&pdata->u.type42.GlyphDirectory, &GlyphDirectory);
     pfont->data.string_proc = z42_string_proc;
     pfont->data.proc_data = (char *)pdata;
+    pfont->is_resource = (options & bf_has_font_file ? true : false);
     code = gs_type42_font_init(pfont, 0);
     if (code < 0)
 	return code;



More information about the gs-cvs mailing list