📄 ttcmap.c
字号:
} } last = end; } } return SFNT_Err_Ok; } FT_CALLBACK_DEF( FT_UInt ) tt_cmap8_char_index( TT_CMap cmap, FT_UInt32 char_code ) { FT_Byte* table = cmap->data; FT_UInt result = 0; FT_Byte* p = table + 8204; 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_cmap8_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { FT_UInt32 result = 0; FT_UInt32 char_code = *pchar_code + 1; FT_UInt gindex = 0; FT_Byte* table = cmap->data; FT_Byte* p = table + 8204; FT_UInt32 num_groups = TT_NEXT_ULONG( p ); FT_UInt32 start, end, start_id; p = table + 8208; 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_DEF( FT_Error ) tt_cmap8_get_info( TT_CMap cmap, TT_CMapInfo *cmap_info ) { FT_Byte* p = cmap->data + 8; cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); return SFNT_Err_Ok; } FT_CALLBACK_TABLE_DEF const TT_CMap_ClassRec tt_cmap8_class_rec = { { sizeof ( TT_CMapRec ), (FT_CMap_InitFunc) tt_cmap_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)tt_cmap8_char_index, (FT_CMap_CharNextFunc) tt_cmap8_char_next }, 8, (TT_CMap_ValidateFunc) tt_cmap8_validate, (TT_CMap_Info_GetFunc) tt_cmap8_get_info };#endif /* TT_CONFIG_CMAP_FORMAT_8 */ /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** FORMAT 10 *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* TABLE OVERVIEW */ /* -------------- */ /* */ /* NAME OFFSET TYPE DESCRIPTION */ /* */ /* format 0 USHORT must be 10 */ /* reserved 2 USHORT reserved */ /* length 4 ULONG length in bytes */ /* language 8 ULONG Mac language code */ /* */ /* start 12 ULONG first char in range */ /* count 16 ULONG number of chars in range */ /* glyphIds 20 USHORT[count] glyph indices covered */ /* */#ifdef TT_CONFIG_CMAP_FORMAT_10 FT_CALLBACK_DEF( FT_Error ) tt_cmap10_validate( FT_Byte* table, FT_Validator valid ) { FT_Byte* p = table + 4; FT_ULong length, count; if ( table + 20 > valid->limit ) FT_INVALID_TOO_SHORT; length = TT_NEXT_ULONG( p ); p = table + 16; count = TT_NEXT_ULONG( p ); if ( table + length > valid->limit || length < 20 + count * 2 ) FT_INVALID_TOO_SHORT; /* 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; } } return SFNT_Err_Ok; } 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_DEF( FT_Error ) tt_cmap10_get_info( TT_CMap cmap, TT_CMapInfo *cmap_info ) { FT_Byte* p = cmap->data + 8; cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); return SFNT_Err_Ok; } 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, (TT_CMap_Info_GetFunc) tt_cmap10_get_info };#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 typedef struct TT_CMap12Rec_ { TT_CMapRec cmap; FT_Bool valid; FT_ULong cur_charcode; FT_UInt cur_gindex; FT_ULong cur_group; FT_ULong num_groups; } TT_CMap12Rec, *TT_CMap12; FT_CALLBACK_DEF( FT_Error ) tt_cmap12_init( TT_CMap12 cmap, FT_Byte* table ) { cmap->cmap.data = table; table += 12; cmap->num_groups = FT_PEEK_ULONG( table ); cmap->valid = 0; return SFNT_Err_Ok; } FT_CALLBACK_DEF( FT_Error ) 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; } } return SFNT_Err_Ok; } /* search the index of the charcode next to cmap->cur_charcode */ /* cmap->cur_group should be set up properly by caller */ /* */ static void tt_cmap12_next( TT_CMap12 cmap ) { FT_Byte* p; FT_ULong start, end, start_id, char_code; FT_ULong n; FT_UInt gindex; if ( cmap->cur_charcode >= 0xFFFFFFFFUL ) goto Fail; char_code = cmap->cur_charcode + 1; n = cmap->cur_group; for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) { p = cmap->cmap.data + 16 + 12 * n; start = TT_NEXT_ULONG( p ); end = TT_NEXT_ULONG( p ); start_id = TT_PEEK_ULONG( p ); if ( char_code < start ) char_code = start; for ( ; char_code <= end; char_code++ ) { gindex = (FT_UInt)( start_id + char_code - start );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -