From 22ad9ef0248f4f45e32e2d7c489a73cbec588460 Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Mon, 9 May 2005 22:11:36 +0000 Subject: [PATCH] Handle unsorted SFNT type 4 cmaps correctly (reported by Dirck Blaskey). * src/sfnt/ttcmap.h (TT_CMap): Add member `unsorted'. * src/sfnt/ttcmac.c: Use SFNT_Err_Ok where appropriate. (tt_cmap0_validate, tt_cmap2_validate, tt_cmap6_validate, tt_cmap8_validate, tt_cmap10_validate, tt_cmap12_validate): Use `FT_Error' as return type. (tt_cmap4_validate): Use `FT_Error' as return type. Return error code for unsorted cmap. (tt_cmap4_char_index, tt_cmap4_char_next): Use old code for unsorted cmaps. (tt_face_build_cmaps): Set `unsorted' variable in cmap. Minor formatting. --- ChangeLog | 17 +++ src/autofit/aflatin.c | 14 +- src/base/ftstroke.c | 4 +- src/bdf/bdfdrivr.c | 2 +- src/cache/ftcbasic.c | 6 +- src/cache/ftccmap.c | 2 +- src/cache/ftcmanag.c | 4 +- src/cff/cffload.c | 2 +- src/cid/cidload.c | 14 +- src/lzw/zopen.c | 6 +- src/otvalid/otvgdef.c | 2 +- src/sfnt/sfobjs.c | 2 +- src/sfnt/ttcmap.c | 340 ++++++++++++++++++++++------------------- src/sfnt/ttcmap.h | 3 +- src/sfnt/ttload.c | 34 ++--- src/truetype/ttgxvar.c | 12 +- 16 files changed, 251 insertions(+), 213 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2931ca5b7..2ff56cc55 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2005-05-07 Werner Lemberg + + Handle unsorted SFNT type 4 cmaps correctly (reported by Dirck + Blaskey). + + * src/sfnt/ttcmap.h (TT_CMap): Add member `unsorted'. + * src/sfnt/ttcmac.c: Use SFNT_Err_Ok where appropriate. + + (tt_cmap0_validate, tt_cmap2_validate, tt_cmap6_validate, + tt_cmap8_validate, tt_cmap10_validate, tt_cmap12_validate): Use + `FT_Error' as return type. + (tt_cmap4_validate): Use `FT_Error' as return type. + Return error code for unsorted cmap. + (tt_cmap4_char_index, tt_cmap4_char_next): Use old code for unsorted + cmaps. + (tt_face_build_cmaps): Set `unsorted' variable in cmap. + 2005-05-07 Werner Lemberg * src/truetype/ttpload.c (tt_face_get_location): Fix typo. diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c index 1aef9bb96..35dfe2932 100644 --- a/src/autofit/aflatin.c +++ b/src/autofit/aflatin.c @@ -688,7 +688,7 @@ { /* we are just leaving an edge; record a new segment! */ segment->last = point; - segment->pos = (FT_Short)(( min_pos + max_pos ) >> 1); + segment->pos = (FT_Short)( ( min_pos + max_pos ) >> 1 ); /* a segment is round if either its first or last point */ /* is a control point */ @@ -705,8 +705,8 @@ if ( v > max_pos ) max_pos = v; - segment->min_coord = (FT_Short) min_pos; - segment->max_coord = (FT_Short) max_pos; + segment->min_coord = (FT_Short)min_pos; + segment->max_coord = (FT_Short)max_pos; on_edge = 0; segment = NULL; @@ -732,7 +732,7 @@ if ( error ) goto Exit; - segment->dir = (FT_Char) segment_dir; + segment->dir = (FT_Char)segment_dir; segment->flags = AF_EDGE_NORMAL; min_pos = max_pos = point->u; segment->first = point; @@ -1150,10 +1150,10 @@ edge->dir = AF_DIR_NONE; if ( ups > downs ) - edge->dir = (FT_Char) up_dir; + edge->dir = (FT_Char)up_dir; else if ( ups < downs ) - edge->dir = (FT_Char) -up_dir; + edge->dir = (FT_Char)-up_dir; else if ( ups == downs ) edge->dir = 0; /* both up and down! */ @@ -1232,7 +1232,7 @@ /* zone, check for left edges */ /* */ /* of course, that's for TrueType */ - is_top_blue = (FT_Byte)(( blue->flags & AF_LATIN_BLUE_TOP ) != 0); + is_top_blue = (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_TOP ) != 0 ); is_major_dir = FT_BOOL( edge->dir == axis->major_dir ); /* if it is a top zone, the edge must be against the major */ diff --git a/src/base/ftstroke.c b/src/base/ftstroke.c index 2da2314da..2d8ff7bc5 100644 --- a/src/base/ftstroke.c +++ b/src/base/ftstroke.c @@ -4,7 +4,7 @@ /* */ /* FreeType path stroker (body). */ /* */ -/* Copyright 2002, 2003, 2004 by */ +/* Copyright 2002, 2003, 2004, 2005 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -1425,7 +1425,7 @@ dst_tag[0] &= ~FT_STROKE_TAG_BEGIN_END; else { - FT_Byte ttag = (FT_Byte)(dst_tag[0] & FT_STROKE_TAG_BEGIN_END); + FT_Byte ttag = (FT_Byte)( dst_tag[0] & FT_STROKE_TAG_BEGIN_END ); /* switch begin/end tags if necessary */ diff --git a/src/bdf/bdfdrivr.c b/src/bdf/bdfdrivr.c index b6dd776a7..e14306efd 100644 --- a/src/bdf/bdfdrivr.c +++ b/src/bdf/bdfdrivr.c @@ -2,7 +2,7 @@ FreeType font driver for bdf files - Copyright (C) 2001, 2002, 2003, 2004 by + Copyright (C) 2001, 2002, 2003, 2004, 2005 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/src/cache/ftcbasic.c b/src/cache/ftcbasic.c index b94d90e6b..689cdc61b 100644 --- a/src/cache/ftcbasic.c +++ b/src/cache/ftcbasic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType basic cache interface (body). */ /* */ -/* Copyright 2003, 2004 by */ +/* Copyright 2003, 2004, 2005 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -38,8 +38,8 @@ } FTC_BasicAttrRec, *FTC_BasicAttrs; -#define FTC_BASIC_ATTR_COMPARE( a, b ) \ - FT_BOOL( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) && \ +#define FTC_BASIC_ATTR_COMPARE( a, b ) \ + FT_BOOL( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) && \ (a)->load_flags == (b)->load_flags ) #define FTC_BASIC_ATTR_HASH( a ) \ diff --git a/src/cache/ftccmap.c b/src/cache/ftccmap.c index eb0c19eaf..02b814818 100644 --- a/src/cache/ftccmap.c +++ b/src/cache/ftccmap.c @@ -4,7 +4,7 @@ /* */ /* FreeType CharMap cache (body) */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/cache/ftcmanag.c b/src/cache/ftcmanag.c index 5252c5a76..337bea5f9 100644 --- a/src/cache/ftcmanag.c +++ b/src/cache/ftcmanag.c @@ -4,7 +4,7 @@ /* */ /* FreeType Cache Manager (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -164,7 +164,7 @@ FTC_FaceID face_id = (FTC_FaceID)ftcface_id; - return FT_BOOL(node->scaler.face_id == face_id); + return FT_BOOL( node->scaler.face_id == face_id ); } diff --git a/src/cff/cffload.c b/src/cff/cffload.c index a7740e1e3..237915cfd 100644 --- a/src/cff/cffload.c +++ b/src/cff/cffload.c @@ -4,7 +4,7 @@ /* */ /* OpenType and CFF data/program tables loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/cid/cidload.c b/src/cid/cidload.c index e6ca5ce59..8d96ea6ee 100644 --- a/src/cid/cidload.c +++ b/src/cid/cidload.c @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 font loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -536,11 +536,11 @@ } if ( ft_isdigit( *p ) ) - val = (FT_Byte)(*p - '0'); + val = (FT_Byte)( *p - '0' ); else if ( *p >= 'a' && *p <= 'f' ) - val = (FT_Byte)(*p - 'a'); + val = (FT_Byte)( *p - 'a' ); else if ( *p >= 'A' && *p <= 'F' ) - val = (FT_Byte)(*p - 'A' + 10); + val = (FT_Byte)( *p - 'A' + 10 ); else if ( *p == ' ' || *p == '\t' || *p == '\r' || @@ -563,14 +563,14 @@ } if ( upper_nibble ) - *d = (FT_Byte)(val << 4); + *d = (FT_Byte)( val << 4 ); else { - *d = (FT_Byte)(*d + val); + *d = (FT_Byte)( *d + val ); d++; } - upper_nibble = (FT_Byte)(1 - upper_nibble); + upper_nibble = (FT_Byte)( 1 - upper_nibble ); if ( done ) break; diff --git a/src/lzw/zopen.c b/src/lzw/zopen.c index c21584475..5a3c5bc2b 100644 --- a/src/lzw/zopen.c +++ b/src/lzw/zopen.c @@ -35,7 +35,7 @@ /*- * - * Copyright (c) 2004 + * Copyright (c) 2004, 2005 * Albert Chin-A-Young. * * Modified to work with FreeType's PCF driver. @@ -276,8 +276,8 @@ middle: /* Generate the new entry. */ if ((code = free_ent) < maxmaxcode) { - tab_prefixof(code) = (unsigned short) oldcode; - tab_suffixof(code) = (unsigned char) finchar; + tab_prefixof(code) = (unsigned short)oldcode; + tab_suffixof(code) = (unsigned char)finchar; free_ent = code + 1; } diff --git a/src/otvalid/otvgdef.c b/src/otvalid/otvgdef.c index 9144a76e7..e408c709a 100644 --- a/src/otvalid/otvgdef.c +++ b/src/otvalid/otvgdef.c @@ -4,7 +4,7 @@ /* */ /* OpenType GDEF table validation (body). */ /* */ -/* Copyright 2004 by */ +/* Copyright 2004, 2005 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c index a066df527..16859cc51 100644 --- a/src/sfnt/sfobjs.c +++ b/src/sfnt/sfobjs.c @@ -208,7 +208,7 @@ case TT_MS_ID_SYMBOL_CS: case TT_MS_ID_UNICODE_CS: case TT_MS_ID_UCS_4: - is_english = FT_BOOL(( rec->languageID & 0x3FF ) == 0x009); + is_english = FT_BOOL( ( rec->languageID & 0x3FF ) == 0x009 ); found_win = n; break; diff --git a/src/sfnt/ttcmap.c b/src/sfnt/ttcmap.c index b4b8ef84d..95f9d74f8 100644 --- a/src/sfnt/ttcmap.c +++ b/src/sfnt/ttcmap.c @@ -53,7 +53,7 @@ FT_Byte* table ) { cmap->data = table; - return 0; + return SFNT_Err_Ok; } @@ -81,7 +81,7 @@ #ifdef TT_CONFIG_CMAP_FORMAT_0 - FT_CALLBACK_DEF( void ) + FT_CALLBACK_DEF( FT_Error ) tt_cmap0_validate( FT_Byte* table, FT_Validator valid ) { @@ -106,6 +106,8 @@ FT_INVALID_GLYPH_ID; } } + + return SFNT_Err_Ok; } @@ -266,7 +268,7 @@ #ifdef TT_CONFIG_CMAP_FORMAT_2 - FT_CALLBACK_DEF( void ) + FT_CALLBACK_DEF( FT_Error ) tt_cmap2_validate( FT_Byte* table, FT_Validator valid ) { @@ -355,6 +357,8 @@ } } } + + return SFNT_Err_Ok; } @@ -625,7 +629,7 @@ #ifdef OPT_CMAP4 - typedef struct TT_CMap4Rec_ + typedef struct TT_CMap4Rec_ { TT_CMapRec cmap; FT_UInt32 old_charcode; /* old charcode */ @@ -650,7 +654,7 @@ FT_Byte* p; - cmap->cmap.data = table; + cmap->cmap.data = table; p = table + 2; cmap->table_length = FT_PEEK_USHORT( p ); @@ -662,7 +666,7 @@ cmap->cur_charcode = 0; cmap->cur_gindex = 0; - return 0; + return SFNT_Err_Ok; } @@ -792,7 +796,7 @@ - FT_CALLBACK_DEF( void ) + FT_CALLBACK_DEF( FT_Error ) tt_cmap4_validate( FT_Byte* table, FT_Validator valid ) { @@ -800,6 +804,7 @@ FT_UInt length = TT_NEXT_USHORT( p ); FT_Byte *ends, *starts, *offsets, *deltas, *glyph_ids; FT_UInt num_segs; + FT_Error error = SFNT_Err_Ok; /* in certain fonts, the `length' field is invalid and goes */ @@ -894,10 +899,12 @@ /* unfortunately, some popular Asian fonts present overlapping */ /* ranges in their charmaps */ /* */ - if ( valid->level >= FT_VALIDATE_TIGHT ) + if ( n > 0 && start <= last ) { - if ( n > 0 && start <= last ) + if ( valid->level >= FT_VALIDATE_TIGHT ) FT_INVALID_DATA; + else + error = SFNT_Err_Invalid_CharMap_Format; } if ( offset && offset != 0xFFFFU ) @@ -951,6 +958,8 @@ last = end; } } + + return error; } @@ -972,11 +981,11 @@ p = table + 6; num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 ); /* be paranoid! */ -#if 1 - /* Some fonts have more than 170 segments in their charmaps! */ - /* We changed this function to use a more efficient binary */ - /* search for improving performance */ + if ( !cmap->unsorted ) { + /* Some fonts have more than 170 segments in their charmaps! */ + /* We changed this function to use a more efficient binary */ + /* search for improving performance */ FT_UInt min = 0; FT_UInt max = num_segs2 >> 1; FT_UInt mid, start, end, offset; @@ -1021,9 +1030,7 @@ } } } - -#else /* 0 - old code */ - + else { FT_UInt n; FT_Byte* q; @@ -1066,9 +1073,6 @@ } } } - -#endif /* 0 */ - } Exit: @@ -1111,173 +1115,172 @@ code = (FT_UInt)char_code + 1; p = table + 6; - num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT(p), 2 ); /* ensure even-ness */ + num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 ); /* ensure even-ness */ -#if 1 - - for (;;) + if ( !cmap->unsorted ) { - /* Some fonts have more than 170 segments in their charmaps! */ - /* We changed this function to use a more efficient binary */ - /* search */ - FT_UInt offset; - FT_Int delta; - FT_UInt min = 0; - FT_UInt max = num_segs2 >> 1; - FT_UInt mid, start, end; - FT_UInt hi; - - - /* we begin by finding the segment which end is - closer to our code point */ - hi = max + 1; - while ( min < max ) + for (;;) { - mid = ( min + max ) >> 1; - p = table + 14 + mid * 2; - end = TT_PEEK_USHORT( p ); + /* Some fonts have more than 170 segments in their charmaps! */ + /* We changed this function to use a more efficient binary */ + /* search */ + FT_UInt offset; + FT_Int delta; + FT_UInt min = 0; + FT_UInt max = num_segs2 >> 1; + FT_UInt mid, start, end; + FT_UInt hi; - if ( end < code ) - min = mid + 1; - else + + /* we begin by finding the segment which end is + closer to our code point */ + hi = max + 1; + while ( min < max ) { - hi = mid; - max = mid; - } - } + mid = ( min + max ) >> 1; + p = table + 14 + mid * 2; + end = TT_PEEK_USHORT( p ); - if ( hi > max ) - { - /* the point is behind the last segment; - we will exit right now */ - goto Exit; - } - - p = table + 14 + hi * 2; - end = TT_PEEK_USHORT( p ); - - p += 2 + num_segs2; - start = TT_PEEK_USHORT( p ); - - if ( code < start ) - code = start; - - p += num_segs2; - delta = TT_PEEK_USHORT( p ); - - p += num_segs2; - offset = TT_PEEK_USHORT( p ); - - if ( offset != 0 && offset != 0xFFFFU ) - { - /* parse the glyph ids array for non-zero index */ - p += offset + ( code - start ) * 2; - while ( code <= end ) - { - gindex = TT_NEXT_USHORT( p ); - if ( gindex != 0 ) + if ( end < code ) + min = mid + 1; + else { - gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU; - if ( gindex != 0 ) - { - result = code; -#ifdef OPT_CMAP4 - tt_cmap4_reset( (TT_CMap4)cmap, code, hi ); -#endif - goto Exit; - } + hi = mid; + max = mid; } - code++; } - } - else if ( offset == 0xFFFFU ) - { - /* an offset of 0xFFFF means an empty segment in certain fonts! */ - code = end + 1; - } - else /* offset == 0 */ - { - gindex = (FT_UInt)( code + delta ) & 0xFFFFU; - if ( gindex != 0 ) + + if ( hi > max ) { - result = code; -#ifdef OPT_CMAP4 - tt_cmap4_reset( (TT_CMap4)cmap, code, hi ); -#endif + /* the point is behind the last segment; + we will exit right now */ goto Exit; } - code++; - } - } -#else /* old code -- kept for reference */ - - for ( ;; ) - { - FT_UInt offset, n; - FT_Int delta; - FT_Byte* q; - - - p = table + 14; /* ends table */ - q = table + 16 + num_segs2; /* starts table */ - - for ( n = 0; n < num_segs2; n += 2 ) - { - FT_UInt end = TT_NEXT_USHORT( p ); - FT_UInt start = TT_NEXT_USHORT( q ); + p = table + 14 + hi * 2; + end = TT_PEEK_USHORT( p ); + p += 2 + num_segs2; + start = TT_PEEK_USHORT( p ); if ( code < start ) code = start; - if ( code <= end ) - { - p = q + num_segs2 - 2; - delta = TT_PEEK_SHORT( p ); - p += num_segs2; - offset = TT_PEEK_USHORT( p ); + p += num_segs2; + delta = TT_PEEK_USHORT( p ); - if ( offset != 0 && offset != 0xFFFFU ) + p += num_segs2; + offset = TT_PEEK_USHORT( p ); + + if ( offset != 0 && offset != 0xFFFFU ) + { + /* parse the glyph ids array for non-zero index */ + p += offset + ( code - start ) * 2; + while ( code <= end ) { - /* parse the glyph ids array for non-0 index */ - p += offset + ( code - start ) * 2; - while ( code <= end ) + gindex = TT_NEXT_USHORT( p ); + if ( gindex != 0 ) { - gindex = TT_NEXT_USHORT( p ); + gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU; if ( gindex != 0 ) { - gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU; - if ( gindex != 0 ) - break; + result = code; +#ifdef OPT_CMAP4 + tt_cmap4_reset( (TT_CMap4)cmap, code, hi ); +#endif + goto Exit; } - code++; } + code++; } - else if ( offset == 0xFFFFU ) + } + else if ( offset == 0xFFFFU ) + { + /* an offset of 0xFFFF means an empty segment in certain fonts! */ + code = end + 1; + } + else /* offset == 0 */ + { + gindex = (FT_UInt)( code + delta ) & 0xFFFFU; + if ( gindex != 0 ) { - /* an offset of 0xFFFF means an empty glyph in certain fonts! */ - code = end; - break; + result = code; +#ifdef OPT_CMAP4 + tt_cmap4_reset( (TT_CMap4)cmap, code, hi ); +#endif + goto Exit; } - else - gindex = (FT_UInt)( code + delta ) & 0xFFFFU; - - if ( gindex == 0 ) - break; - - result = code; - goto Exit; + code++; } } - /* loop to next trial charcode */ - if ( code >= 0xFFFFU ) - break; - - code++; } + else + { + for ( ;; ) + { + FT_UInt offset, n; + FT_Int delta; + FT_Byte* q; -#endif /* !1 */ + + p = table + 14; /* ends table */ + q = table + 16 + num_segs2; /* starts table */ + + for ( n = 0; n < num_segs2; n += 2 ) + { + FT_UInt end = TT_NEXT_USHORT( p ); + FT_UInt start = TT_NEXT_USHORT( q ); + + + if ( code < start ) + code = start; + + if ( code <= end ) + { + p = q + num_segs2 - 2; + delta = TT_PEEK_SHORT( p ); + p += num_segs2; + offset = TT_PEEK_USHORT( p ); + + if ( offset != 0 && offset != 0xFFFFU ) + { + /* parse the glyph ids array for non-0 index */ + p += offset + ( code - start ) * 2; + while ( code <= end ) + { + gindex = TT_NEXT_USHORT( p ); + if ( gindex != 0 ) + { + gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU; + if ( gindex != 0 ) + break; + } + code++; + } + } + else if ( offset == 0xFFFFU ) + { + /* an offset of 0xFFFF means an empty glyph in certain fonts! */ + code = end; + break; + } + else + gindex = (FT_UInt)( code + delta ) & 0xFFFFU; + + if ( gindex == 0 ) + break; + + result = code; + goto Exit; + } + } + /* loop to next trial charcode */ + if ( code >= 0xFFFFU ) + break; + + code++; + } + } Exit: *pchar_code = result; @@ -1349,7 +1352,7 @@ #ifdef TT_CONFIG_CMAP_FORMAT_6 - FT_CALLBACK_DEF( void ) + FT_CALLBACK_DEF( FT_Error ) tt_cmap6_validate( FT_Byte* table, FT_Validator valid ) { @@ -1382,6 +1385,8 @@ FT_INVALID_GLYPH_ID; } } + + return SFNT_Err_Ok; } @@ -1535,7 +1540,7 @@ #ifdef TT_CONFIG_CMAP_FORMAT_8 - FT_CALLBACK_DEF( void ) + FT_CALLBACK_DEF( FT_Error ) tt_cmap8_validate( FT_Byte* table, FT_Validator valid ) { @@ -1624,6 +1629,8 @@ last = end; } } + + return SFNT_Err_Ok; } @@ -1757,7 +1764,7 @@ #ifdef TT_CONFIG_CMAP_FORMAT_10 - FT_CALLBACK_DEF( void ) + FT_CALLBACK_DEF( FT_Error ) tt_cmap10_validate( FT_Byte* table, FT_Validator valid ) { @@ -1788,6 +1795,8 @@ FT_INVALID_GLYPH_ID; } } + + return SFNT_Err_Ok; } @@ -1907,7 +1916,7 @@ #ifdef TT_CONFIG_CMAP_FORMAT_12 - FT_CALLBACK_DEF( void ) + FT_CALLBACK_DEF( FT_Error ) tt_cmap12_validate( FT_Byte* table, FT_Validator valid ) { @@ -1954,6 +1963,8 @@ last = end; } } + + return SFNT_Err_Ok; } @@ -2149,6 +2160,7 @@ if ( clazz->format == format ) { volatile TT_ValidatorRec valid; + FT_Error error = SFNT_Err_Ok; ft_validator_init( FT_VALIDATOR( &valid ), cmap, limit, @@ -2159,11 +2171,19 @@ if ( ft_setjmp( FT_VALIDATOR( &valid )->jump_buffer ) == 0 ) { /* validate this cmap sub-table */ - clazz->validate( cmap, FT_VALIDATOR( &valid ) ); + error = clazz->validate( cmap, FT_VALIDATOR( &valid ) ); } if ( valid.validator.error == 0 ) + { (void)FT_CMap_New( (FT_CMap_Class)clazz, cmap, &charmap, NULL ); + + /* it is simpler to directly set the `unsorted' flag instead */ + /* of adding a parameter to FT_CMap_New */ + ((TT_CMap)(face->root.charmaps + [face->root.num_charmaps - 1]))->unsorted = + FT_BOOL( error ); + } else { FT_ERROR(( "tt_face_build_cmaps:" )); @@ -2175,7 +2195,7 @@ } } - return 0; + return SFNT_Err_Ok; } diff --git a/src/sfnt/ttcmap.h b/src/sfnt/ttcmap.h index 8ba60178c..5f758a46d 100644 --- a/src/sfnt/ttcmap.h +++ b/src/sfnt/ttcmap.h @@ -4,7 +4,7 @@ /* */ /* TrueType character mapping table (cmap) support (specification). */ /* */ -/* Copyright 2002, 2003, 2004 by */ +/* Copyright 2002, 2003, 2004, 2005 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -31,6 +31,7 @@ FT_BEGIN_HEADER { FT_CMapRec cmap; FT_Byte* data; /* pointer to in-memory cmap table */ + FT_Bool unsorted; /* for format 4 only */ } TT_CMapRec, *TT_CMap; diff --git a/src/sfnt/ttload.c b/src/sfnt/ttload.c index 8caef37d3..0f9198402 100644 --- a/src/sfnt/ttload.c +++ b/src/sfnt/ttload.c @@ -134,22 +134,22 @@ } - /* In theory, we should check the values of `search_range', */ - /* `entry_selector', and `range_shift' to detect non-SFNT based files */ - /* whose header might also start with 0x100000L (yes, these exist). */ - /* */ - /* Very unfortunately, many TrueType fonts don't have these fields */ - /* set correctly and we must ignore them to support them. An alternative */ - /* way to check the font file is thus to: */ - /* */ - /* - check that `num_tables' is valid */ - /* - look for a "head" table, check its size, and parse it to */ - /* see if its "magic" field is correctly set */ - /* */ - /* When checking directory entries, ignore the tables `glyx' and `locx' */ - /* which are hacked-out versions of `glyf' and `loca' in some PostScript */ - /* Type 42 fonts, and will generally be invalid. */ - /* */ + /* In theory, we should check the values of `search_range', */ + /* `entry_selector', and `range_shift' to detect non-SFNT based files */ + /* whose header might also start with 0x100000L (yes, these exist). */ + /* */ + /* Very unfortunately, many TrueType fonts don't have these fields */ + /* set correctly and we must ignore them to support them. An */ + /* alternative way to check the font file is thus to: */ + /* */ + /* - check that `num_tables' is valid */ + /* - look for a "head" table, check its size, and parse it to */ + /* see if its "magic" field is correctly set */ + /* */ + /* When checking directory entries, ignore the tables `glyx' and `locx' */ + /* which are hacked-out versions of `glyf' and `loca' in some PostScript */ + /* Type 42 fonts, and will generally be invalid. */ + /* */ static FT_Error sfnt_dir_check( FT_Stream stream, FT_ULong offset, @@ -239,7 +239,7 @@ goto Bad_Format; Exit: - return error; + return error; Bad_Format: error = SFNT_Err_Unknown_File_Format; diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c index e6051a289..53cd2a2c7 100644 --- a/src/truetype/ttgxvar.c +++ b/src/truetype/ttgxvar.c @@ -4,7 +4,7 @@ /* */ /* TrueType GX Font Variation loader */ /* */ -/* Copyright 2004 by */ +/* Copyright 2004, 2005 by */ /* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -92,7 +92,7 @@ /* indicates that there is a delta for every point without needing to */ /* enumerate all of them. */ /* */ -#define ALL_POINTS (FT_UShort*)(-1) +#define ALL_POINTS (FT_UShort*)( -1 ) enum @@ -1209,7 +1209,7 @@ } apply = ft_var_apply_tuple( blend, - (FT_UShort) tupleIndex, + (FT_UShort)tupleIndex, tuple_coords, im_start_coords, im_end_coords ); @@ -1238,8 +1238,8 @@ { /* this means that there are deltas for every entry in cvt */ for ( j = 0; j < face->cvt_size; ++j ) - face->cvt[j] = (FT_Short)( face->cvt[j] + FT_MulFix( deltas[j], - apply ) ); + face->cvt[j] = (FT_Short)( face->cvt[j] + + FT_MulFix( deltas[j], apply ) ); } else @@ -1404,7 +1404,7 @@ } apply = ft_var_apply_tuple( blend, - (FT_UShort) tupleIndex, + (FT_UShort)tupleIndex, tuple_coords, im_start_coords, im_end_coords );