📄 ttcmap0.c
字号:
/* check glyph indices */ if ( valid->level >= FT_VALIDATE_TIGHT ) { FT_UInt gindex; for ( ; count > 0; count-- ) { gindex = TT_NEXT_USHORT( p ); if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) ) FT_INVALID_GLYPH_ID; } } } FT_CALLBACK_DEF( FT_UInt ) tt_cmap10_char_index( TT_CMap cmap, FT_UInt32 char_code ) { FT_Byte* table = cmap->data; FT_UInt result = 0; FT_Byte* p = table + 12; FT_UInt32 start = TT_NEXT_ULONG( p ); FT_UInt32 count = TT_NEXT_ULONG( p ); FT_UInt32 idx = (FT_ULong)( char_code - start ); if ( idx < count ) { p += 2 * idx; result = TT_PEEK_USHORT( p ); } return result; } FT_CALLBACK_DEF( FT_UInt ) tt_cmap10_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { FT_Byte* table = cmap->data; FT_UInt32 char_code = *pchar_code + 1; FT_UInt gindex = 0; FT_Byte* p = table + 12; FT_UInt32 start = TT_NEXT_ULONG( p ); FT_UInt32 count = TT_NEXT_ULONG( p ); FT_UInt32 idx; if ( char_code < start ) char_code = start; idx = (FT_UInt32)( char_code - start ); p += 2 * idx; for ( ; idx < count; idx++ ) { gindex = TT_NEXT_USHORT( p ); if ( gindex != 0 ) break; char_code++; } *pchar_code = char_code; return gindex; } FT_CALLBACK_TABLE_DEF const TT_CMap_ClassRec tt_cmap10_class_rec = { { sizeof ( TT_CMapRec ), (FT_CMap_InitFunc) tt_cmap_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)tt_cmap10_char_index, (FT_CMap_CharNextFunc) tt_cmap10_char_next }, 10, (TT_CMap_ValidateFunc) tt_cmap10_validate };#endif /* TT_CONFIG_CMAP_FORMAT_10 */ /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** FORMAT 12 *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* TABLE OVERVIEW */ /* -------------- */ /* */ /* NAME OFFSET TYPE DESCRIPTION */ /* */ /* format 0 USHORT must be 12 */ /* reserved 2 USHORT reserved */ /* length 4 ULONG length in bytes */ /* language 8 ULONG Mac language code */ /* count 12 ULONG number of groups */ /* 16 */ /* */ /* This header is followed by `count' groups of the following format: */ /* */ /* start 0 ULONG first charcode */ /* end 4 ULONG last charcode */ /* startId 8 ULONG start glyph id for the group */ /* */#ifdef TT_CONFIG_CMAP_FORMAT_12 FT_CALLBACK_DEF( void ) tt_cmap12_validate( FT_Byte* table, FT_Validator valid ) { FT_Byte* p; FT_ULong length; FT_ULong num_groups; if ( table + 16 > valid->limit ) FT_INVALID_TOO_SHORT; p = table + 4; length = TT_NEXT_ULONG( p ); p = table + 12; num_groups = TT_NEXT_ULONG( p ); if ( table + length > valid->limit || length < 16 + 12 * num_groups ) FT_INVALID_TOO_SHORT; /* check groups, they must be in increasing order */ { FT_ULong n, start, end, start_id, last = 0; for ( n = 0; n < num_groups; n++ ) { start = TT_NEXT_ULONG( p ); end = TT_NEXT_ULONG( p ); start_id = TT_NEXT_ULONG( p ); if ( start > end ) FT_INVALID_DATA; if ( n > 0 && start <= last ) FT_INVALID_DATA; if ( valid->level >= FT_VALIDATE_TIGHT ) { if ( start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ) FT_INVALID_GLYPH_ID; } last = end; } } } FT_CALLBACK_DEF( FT_UInt ) tt_cmap12_char_index( TT_CMap cmap, FT_UInt32 char_code ) { FT_UInt result = 0; FT_Byte* table = cmap->data; FT_Byte* p = table + 12; FT_UInt32 num_groups = TT_NEXT_ULONG( p ); FT_UInt32 start, end, start_id; for ( ; num_groups > 0; num_groups-- ) { start = TT_NEXT_ULONG( p ); end = TT_NEXT_ULONG( p ); start_id = TT_NEXT_ULONG( p ); if ( char_code < start ) break; if ( char_code <= end ) { result = (FT_UInt)( start_id + char_code - start ); break; } } return result; } FT_CALLBACK_DEF( FT_UInt ) tt_cmap12_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { FT_Byte* table = cmap->data; FT_UInt32 result = 0; FT_UInt32 char_code = *pchar_code + 1; FT_UInt gindex = 0; FT_Byte* p = table + 12; FT_UInt32 num_groups = TT_NEXT_ULONG( p ); FT_UInt32 start, end, start_id; p = table + 16; for ( ; num_groups > 0; num_groups-- ) { start = TT_NEXT_ULONG( p ); end = TT_NEXT_ULONG( p ); start_id = TT_NEXT_ULONG( p ); if ( char_code < start ) char_code = start; if ( char_code <= end ) { gindex = (FT_UInt)(char_code - start + start_id); if ( gindex != 0 ) { result = char_code; goto Exit; } } } Exit: *pchar_code = result; return gindex; } FT_CALLBACK_TABLE_DEF const TT_CMap_ClassRec tt_cmap12_class_rec = { { sizeof ( TT_CMapRec ), (FT_CMap_InitFunc) tt_cmap_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)tt_cmap12_char_index, (FT_CMap_CharNextFunc) tt_cmap12_char_next }, 12, (TT_CMap_ValidateFunc) tt_cmap12_validate };#endif /* TT_CONFIG_CMAP_FORMAT_12 */ static const TT_CMap_Class tt_cmap_classes[] = {#ifdef TT_CONFIG_CMAP_FORMAT_0 &tt_cmap0_class_rec,#endif#ifdef TT_CONFIG_CMAP_FORMAT_2 &tt_cmap2_class_rec,#endif#ifdef TT_CONFIG_CMAP_FORMAT_4 &tt_cmap4_class_rec,#endif#ifdef TT_CONFIG_CMAP_FORMAT_6 &tt_cmap6_class_rec,#endif#ifdef TT_CONFIG_CMAP_FORMAT_8 &tt_cmap8_class_rec,#endif#ifdef TT_CONFIG_CMAP_FORMAT_10 &tt_cmap10_class_rec,#endif#ifdef TT_CONFIG_CMAP_FORMAT_12 &tt_cmap12_class_rec,#endif NULL, }; /* parse the `cmap' table and build the corresponding TT_CMap objects */ /* in the current face */ /* */ FT_LOCAL_DEF( FT_Error ) tt_face_build_cmaps( TT_Face face ) { FT_Byte* table = face->cmap_table; FT_Byte* limit = table + face->cmap_size; FT_UInt volatile num_cmaps; FT_Byte* volatile p = table; if ( p + 4 > limit ) return SFNT_Err_Invalid_Table; /* only recognize format 0 */ if ( TT_NEXT_USHORT( p ) != 0 ) { p -= 2; FT_ERROR(( "tt_face_build_cmaps: unsupported `cmap' table format = %d\n", TT_PEEK_USHORT( p ) )); return SFNT_Err_Invalid_Table; } num_cmaps = TT_NEXT_USHORT( p ); for ( ; num_cmaps > 0 && p + 8 <= limit; num_cmaps-- ) { FT_CharMapRec charmap; FT_UInt32 offset; charmap.platform_id = TT_NEXT_USHORT( p ); charmap.encoding_id = TT_NEXT_USHORT( p ); charmap.face = FT_FACE( face ); charmap.encoding = FT_ENCODING_NONE; /* will be filled later */ offset = TT_NEXT_ULONG( p ); if ( offset && table + offset + 2 < limit ) { FT_Byte* cmap = table + offset; volatile FT_UInt format = TT_PEEK_USHORT( cmap ); const TT_CMap_Class* volatile pclazz = tt_cmap_classes; TT_CMap_Class clazz; for ( ; *pclazz; pclazz++ ) { clazz = *pclazz; if ( clazz->format == format ) { volatile TT_ValidatorRec valid; ft_validator_init( FT_VALIDATOR( &valid ), cmap, limit, FT_VALIDATE_DEFAULT ); valid.num_glyphs = (FT_UInt)face->root.num_glyphs; if ( ft_setjmp( FT_VALIDATOR( &valid )->jump_buffer ) == 0 ) { /* validate this cmap sub-table */ clazz->validate( cmap, FT_VALIDATOR( &valid ) ); } if ( valid.validator.error == 0 ) (void)FT_CMap_New( (FT_CMap_Class)clazz, cmap, &charmap, NULL ); else { FT_ERROR(( "tt_face_build_cmaps:" )); FT_ERROR(( " broken cmap sub-table ignored!\n" )); } } } } } return 0; }/* END */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -