[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