📄 ttcmap0.c
字号:
FT_CALLBACK_DEF( FT_UInt ) tt_cmap4_char_index( TT_CMap cmap, FT_UInt32 char_code ) { FT_Byte* table = cmap->data; FT_UInt result = 0; if ( char_code < 0x10000UL ) { FT_UInt idx, num_segs2; FT_Int delta; FT_UInt code = (FT_UInt)char_code; FT_Byte* p; p = table + 6; num_segs2 = 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 */ { FT_UInt min = 0; FT_UInt max = num_segs2 >> 1; FT_UInt mid, start, end, offset; while ( min < max ) { mid = ( min + max ) >> 1; p = table + 14 + mid * 2; end = TT_NEXT_USHORT( p ); p += num_segs2; start = TT_PEEK_USHORT( p); if ( code < start ) max = mid; else if ( code > end ) min = mid + 1; else { /* we found the segment */ idx = code; p += num_segs2; delta = TT_PEEK_SHORT( p ); p += num_segs2; offset = TT_PEEK_USHORT( p ); if ( offset == 0xFFFFU ) goto Exit; if ( offset != 0 ) { p += offset + 2 * ( idx - start ); idx = TT_PEEK_USHORT( p ); } if ( idx != 0 ) result = (FT_UInt)( idx + delta ) & 0xFFFFU; goto Exit; } } }#else /* 0 - old code */ { FT_UInt n; 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 ); FT_UInt offset; if ( code < start ) break; if ( code <= end ) { idx = code; p = q + num_segs2 - 2; delta = TT_PEEK_SHORT( p ); p += num_segs2; offset = TT_PEEK_USHORT( p ); if ( offset == 0xFFFFU ) goto Exit; if ( offset != 0 ) { p += offset + 2 * ( idx - start ); idx = TT_PEEK_USHORT( p ); } if ( idx != 0 ) result = (FT_UInt)( idx + delta ) & 0xFFFFU; } } }#endif /* 0 */ } Exit: return result; } FT_CALLBACK_DEF( FT_UInt ) tt_cmap4_char_next( TT_CMap cmap, FT_UInt32 *pchar_code ) { FT_Byte* table = cmap->data; FT_UInt32 result = 0; FT_UInt gindex = 0; FT_UInt32 char_code = *pchar_code; FT_Byte* p; FT_UInt code, num_segs2; if ( char_code >= 0xFFFFUL ) goto Exit; code = (FT_UInt)char_code + 1; p = table + 6; num_segs2 = TT_PEEK_USHORT(p) & -2; /* ensure even-ness */#if 1 for (;;) { /* 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 ) { mid = ( min + max ) >> 1; p = table + 14 + mid * 2; end = TT_PEEK_USHORT( p ); if ( end < code ) min = mid + 1; else { hi = mid; max = mid; } } 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 ) { gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU; if ( gindex != 0 ) { result = code; goto Exit; } } code++; } } else if ( offset == 0xFFFFU ) { /* an offset of 0xFFFF means an empty glyph in certain fonts! */ code = end + 1; } else /* offset == 0 */ { gindex = (FT_UInt)( code + delta ) & 0xFFFFU; if ( gindex != 0 ) { result = code; 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 ); 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++; }#endif /* !1 */ Exit: *pchar_code = result; return gindex; } FT_CALLBACK_TABLE_DEF const TT_CMap_ClassRec tt_cmap4_class_rec = { { sizeof ( TT_CMapRec ), (FT_CMap_InitFunc) tt_cmap_init, (FT_CMap_DoneFunc) NULL, (FT_CMap_CharIndexFunc)tt_cmap4_char_index, (FT_CMap_CharNextFunc) tt_cmap4_char_next }, 4, (TT_CMap_ValidateFunc) tt_cmap4_validate };#endif /* TT_CONFIG_CMAP_FORMAT_4 */ /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** FORMAT 6 *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* TABLE OVERVIEW */ /* -------------- */ /* */ /* NAME OFFSET TYPE DESCRIPTION */ /* */ /* format 0 USHORT must be 4 */ /* length 2 USHORT table length in bytes */ /* language 4 USHORT Mac language code */ /* */ /* first 6 USHORT first segment code */ /* count 8 USHORT segment size in chars */ /* glyphIds 10 USHORT[count] glyph ids */ /* */ /* A very simplified segment mapping. */ /* */#ifdef TT_CONFIG_CMAP_FORMAT_6 FT_CALLBACK_DEF( void ) tt_cmap6_validate( FT_Byte* table, FT_Validator valid ) { FT_Byte* p; FT_UInt length, count; if ( table + 10 > valid->limit ) FT_INVALID_TOO_SHORT; p = table + 2; length = TT_NEXT_USHORT( p ); p = table + 8; /* skip language and start index */ count = TT_NEXT_USHORT( p ); if ( table + length > valid->limit || length < 10 + count * 2 ) FT_INVALID_TOO_SHORT; /* check glyph indices */ if ( valid->level >= FT_VALIDATE_TIGHT )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -