diff options
Diffstat (limited to 'src/sfnt/ttcmap.c')
-rw-r--r-- | src/sfnt/ttcmap.c | 84 |
1 files changed, 56 insertions, 28 deletions
diff --git a/src/sfnt/ttcmap.c b/src/sfnt/ttcmap.c index b70b64c..67b6684 100644 --- a/src/sfnt/ttcmap.c +++ b/src/sfnt/ttcmap.c @@ -4,7 +4,7 @@ /* */ /* TrueType character mapping table (cmap) support (body). */ /* */ -/* Copyright 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -134,7 +134,7 @@ FT_UInt gindex = 0; - table += 6; /* go to glyph ids */ + table += 6; /* go to glyph IDs */ while ( ++charcode < 256 ) { gindex = table[charcode]; @@ -260,14 +260,14 @@ /* */ /* * The value of `offset' is read. This is a _byte_ distance from the */ /* location of the `offset' field itself into a slice of the */ - /* `glyph_ids' table. Let's call it `slice' (it's a USHORT[] too). */ + /* `glyph_ids' table. Let's call it `slice' (it is a USHORT[] too). */ /* */ /* * The value `slice[char.lo - first]' is read. If it is 0, there is */ /* no glyph for the charcode. Otherwise, the value of `delta' is */ /* added to it (modulo 65536) to form a new glyph index. */ /* */ /* It is up to the validation routine to check that all offsets fall */ - /* within the glyph ids table (and not within the `subs' table itself or */ + /* within the glyph IDs table (and not within the `subs' table itself or */ /* outside of the CMap). */ /* */ @@ -328,6 +328,10 @@ delta = TT_NEXT_SHORT( p ); offset = TT_NEXT_USHORT( p ); + /* many Dynalab fonts have empty sub-headers */ + if ( code_count == 0 ) + continue; + /* check range within 0..255 */ if ( valid->level >= FT_VALIDATE_PARANOID ) { @@ -342,7 +346,7 @@ if ( ids < glyph_ids || ids + code_count*2 > table + length ) FT_INVALID_OFFSET; - /* check glyph ids */ + /* check glyph IDs */ if ( valid->level >= FT_VALIDATE_TIGHT ) { FT_Byte* limit = p + code_count * 2; @@ -393,7 +397,7 @@ sub = subs; /* jump to first sub-header */ /* check that the sub-header for this byte is 0, which */ - /* indicates that it's really a valid one-byte value */ + /* indicates that it is really a valid one-byte value */ /* Otherwise, return 0 */ /* */ p += char_lo * 2; @@ -621,7 +625,7 @@ /* charcode within the segment is obtained by adding the value of */ /* `idDelta' directly to the charcode, modulo 65536. */ /* */ - /* Otherwise, a glyph index is taken from the glyph ids sub-array for */ + /* Otherwise, a glyph index is taken from the glyph IDs sub-array for */ /* the segment, and the value of `idDelta' is added to it. */ /* */ /* */ @@ -693,6 +697,14 @@ p += num_ranges * 2; offset = FT_PEEK_USHORT( p ); + /* some fonts handle the last segment incorrectly; */ + /* we have to catch it */ + if ( range_index >= num_ranges - 1 && + cmap->cur_start == 0xFFFFU && + cmap->cur_end == 0xFFFFU && + cmap->cur_delta == 0x1U ) + offset = 0; + if ( offset != 0xFFFFU ) { cmap->cur_values = offset ? p + offset : NULL; @@ -831,7 +843,7 @@ /* */ if ( valid->level >= FT_VALIDATE_PARANOID ) { - /* check the values of 'searchRange', 'entrySelector', 'rangeShift' */ + /* check the values of `searchRange', `entrySelector', `rangeShift' */ FT_UInt search_range = TT_NEXT_USHORT( p ); FT_UInt entry_selector = TT_NEXT_USHORT( p ); FT_UInt range_shift = TT_NEXT_USHORT( p ); @@ -858,7 +870,7 @@ offsets = deltas + num_segs * 2; glyph_ids = offsets + num_segs * 2; - /* check last segment, its end count must be FFFF */ + /* check last segment, its end count must be 0xFFFF */ if ( valid->level >= FT_VALIDATE_PARANOID ) { p = ends + ( num_segs - 1 ) * 2; @@ -867,9 +879,9 @@ } { - FT_UInt start, end, offset, n; - FT_UInt last_start = 0, last_end = 0; - FT_Int delta; + FT_UInt start, end, offset, n; + FT_UInt last_start = 0, last_end = 0; + FT_Int delta; FT_Byte* p_start = starts; FT_Byte* p_end = ends; FT_Byte* p_delta = deltas; @@ -911,14 +923,18 @@ { p += offset; /* start of glyph id array */ - /* check that we point within the glyph ids table only */ + /* check that we point within the glyph IDs table only */ if ( valid->level >= FT_VALIDATE_TIGHT ) { if ( p < glyph_ids || p + ( end - start + 1 ) * 2 > table + length ) FT_INVALID_DATA; } - else + /* some fonts handle the last segment incorrectly */ + else if ( n != num_segs - 1 || + !( start == 0xFFFFU && + end == 0xFFFFU && + delta == 0x1U ) ) { if ( p < glyph_ids || p + ( end - start + 1 ) * 2 > valid->limit ) @@ -946,7 +962,7 @@ } else if ( offset == 0xFFFFU ) { - /* Some fonts (erroneously?) use a range offset of 0xFFFF */ + /* some fonts (erroneously?) use a range offset of 0xFFFF */ /* to mean missing glyph in cmap table */ /* */ if ( valid->level >= FT_VALIDATE_PARANOID || @@ -965,9 +981,9 @@ static FT_UInt - tt_cmap4_char_map_linear( TT_CMap cmap, - FT_UInt* pcharcode, - FT_Bool next ) + tt_cmap4_char_map_linear( TT_CMap cmap, + FT_UInt32* pcharcode, + FT_Bool next ) { FT_UInt num_segs2, start, end, offset; FT_Int delta; @@ -1009,6 +1025,12 @@ p += num_segs2; offset = TT_PEEK_USHORT( p ); + /* some fonts handle the last segment incorrectly; */ + /* we have to catch it */ + if ( i >= num_segs - 1 && + start == 0xFFFFU && end == 0xFFFFU && delta == 0x1U ) + offset = 0; + if ( offset == 0xFFFFU ) continue; @@ -1038,9 +1060,9 @@ static FT_UInt - tt_cmap4_char_map_binary( TT_CMap cmap, - FT_UInt* pcharcode, - FT_Bool next ) + tt_cmap4_char_map_binary( TT_CMap cmap, + FT_UInt32* pcharcode, + FT_Bool next ) { FT_UInt num_segs2, start, end, offset; FT_Int delta; @@ -1088,6 +1110,12 @@ p += num_segs2; offset = TT_PEEK_USHORT( p ); + /* some fonts handle the last segment incorrectly; */ + /* we have to catch it */ + if ( mid >= num_segs - 1 && + start == 0xFFFFU && end == 0xFFFFU && delta == 0x1U ) + offset = 0; + /* search the first segment containing `charcode' */ if ( cmap->flags & TT_CMAP_FLAG_OVERLAPPING ) { @@ -1359,7 +1387,7 @@ /* */ /* first 6 USHORT first segment code */ /* count 8 USHORT segment size in chars */ - /* glyphIds 10 USHORT[count] glyph ids */ + /* glyphIds 10 USHORT[count] glyph IDs */ /* */ /* A very simplified segment mapping. */ /* */ @@ -1506,7 +1534,7 @@ /***** *****/ /***** FORMAT 8 *****/ /***** *****/ - /***** It's hard to completely understand what the OpenType spec *****/ + /***** It is hard to completely understand what the OpenType spec *****/ /***** says about this format, but here is my conclusion. *****/ /***** *****/ /***** The purpose of this format is to easily map UTF-16 text to *****/ @@ -1521,7 +1549,7 @@ /***** `char_hi' and `char_lo' must be in the Surrogates Area. *****/ /***** Area. *****/ /***** *****/ - /***** The 'is32' table embedded in the charmap indicates whether a *****/ + /***** The `is32' table embedded in the charmap indicates whether a *****/ /***** given 16-bit value is in the surrogates area or not. *****/ /***** *****/ /***** So, for any given `char_code', we can assert the following: *****/ @@ -1548,7 +1576,7 @@ /* is32 12 BYTE[8192] 32-bitness bitmap */ /* count 8204 ULONG number of groups */ /* */ - /* This header is followed by 'count' groups of the following format: */ + /* This header is followed by `count' groups of the following format: */ /* */ /* start 0 ULONG first charcode */ /* end 4 ULONG last charcode */ @@ -2727,7 +2755,7 @@ FT_UInt tot = 0; - p += 3; /* point to the first 'cnt' field */ + p += 3; /* point to the first `cnt' field */ for ( ; numRanges > 0; numRanges-- ) { tot += 1 + p[0]; @@ -2774,7 +2802,7 @@ } - static FT_UInt* + static FT_UInt32* tt_cmap14_get_nondef_chars( TT_CMap cmap, FT_Byte *p, FT_Memory memory ) @@ -2962,7 +2990,7 @@ (TT_CMap_Info_GetFunc)tt_cmap14_get_info }; -#endif /* TT_CONFIG_CMAP_FORMAT_0 */ +#endif /* TT_CONFIG_CMAP_FORMAT_14 */ static const TT_CMap_Class tt_cmap_classes[] = |