📄 ttcmap.c
字号:
break;
}
}
/* end, start, delta, and offset are for the i'th segment */
if ( mid != i )
{
p = cmap->data + 14 + mid * 2;
end = TT_PEEK_USHORT( p );
p += 2 + num_segs2;
start = TT_PEEK_USHORT( p );
p += num_segs2;
delta = TT_PEEK_SHORT( p );
p += num_segs2;
offset = TT_PEEK_USHORT( p );
}
}
else
{
if ( offset == 0xFFFFU )
break;
}
if ( offset )
{
p += offset + ( charcode - start ) * 2;
gindex = TT_PEEK_USHORT( p );
if ( gindex != 0 )
gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU;
}
else
gindex = (FT_UInt)( charcode + delta ) & 0xFFFFU;
break;
}
}
if ( next )
{
TT_CMap4 cmap4 = (TT_CMap4)cmap;
/* if `charcode' is not in any segment, then `mid' is */
/* the segment nearest to `charcode' */
/* */
if ( charcode > end )
{
mid++;
if ( mid == num_segs )
return 0;
}
if ( tt_cmap4_set_range( cmap4, mid ) )
{
if ( gindex )
*pcharcode = charcode;
}
else
{
cmap4->cur_charcode = charcode;
if ( gindex )
cmap4->cur_gindex = gindex;
else
{
cmap4->cur_charcode = charcode;
tt_cmap4_next( cmap4 );
gindex = cmap4->cur_gindex;
}
if ( gindex )
*pcharcode = cmap4->cur_charcode;
}
}
return gindex;
}
FT_CALLBACK_DEF( FT_UInt )
tt_cmap4_char_index( TT_CMap cmap,
FT_UInt32 char_code )
{
if ( char_code >= 0x10000UL )
return 0;
if ( cmap->flags & TT_CMAP_FLAG_UNSORTED )
return tt_cmap4_char_map_linear( cmap, &char_code, 0 );
else
return tt_cmap4_char_map_binary( cmap, &char_code, 0 );
}
FT_CALLBACK_DEF( FT_UInt )
tt_cmap4_char_next( TT_CMap cmap,
FT_UInt32 *pchar_code )
{
FT_UInt gindex;
if ( *pchar_code >= 0xFFFFU )
return 0;
if ( cmap->flags & TT_CMAP_FLAG_UNSORTED )
gindex = tt_cmap4_char_map_linear( cmap, pchar_code, 1 );
else
{
TT_CMap4 cmap4 = (TT_CMap4)cmap;
/* no need to search */
if ( *pchar_code == cmap4->cur_charcode )
{
tt_cmap4_next( cmap4 );
gindex = cmap4->cur_gindex;
if ( gindex )
*pchar_code = cmap4->cur_charcode;
}
else
gindex = tt_cmap4_char_map_binary( cmap, pchar_code, 1 );
}
return gindex;
}
FT_CALLBACK_DEF( FT_Error )
tt_cmap4_get_info( TT_CMap cmap,
TT_CMapInfo *cmap_info )
{
FT_Byte* p = cmap->data + 4;
cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
return SFNT_Err_Ok;
}
FT_CALLBACK_TABLE_DEF
const TT_CMap_ClassRec tt_cmap4_class_rec =
{
{
sizeof ( TT_CMap4Rec ),
(FT_CMap_InitFunc) tt_cmap4_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,
(TT_CMap_Info_GetFunc) tt_cmap4_get_info
};
#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( FT_Error )
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 )
{
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_cmap6_char_index( TT_CMap cmap,
FT_UInt32 char_code )
{
FT_Byte* table = cmap->data;
FT_UInt result = 0;
FT_Byte* p = table + 6;
FT_UInt start = TT_NEXT_USHORT( p );
FT_UInt count = TT_NEXT_USHORT( p );
FT_UInt idx = (FT_UInt)( char_code - start );
if ( idx < count )
{
p += 2 * idx;
result = TT_PEEK_USHORT( p );
}
return result;
}
FT_CALLBACK_DEF( FT_UInt )
tt_cmap6_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 + 6;
FT_UInt start = TT_NEXT_USHORT( p );
FT_UInt count = TT_NEXT_USHORT( p );
FT_UInt idx;
if ( char_code >= 0x10000UL )
goto Exit;
if ( char_code < start )
char_code = start;
idx = (FT_UInt)( char_code - start );
p += 2 * idx;
for ( ; idx < count; idx++ )
{
gindex = TT_NEXT_USHORT( p );
if ( gindex != 0 )
{
result = char_code;
break;
}
char_code++;
}
Exit:
*pchar_code = result;
return gindex;
}
FT_CALLBACK_DEF( FT_Error )
tt_cmap6_get_info( TT_CMap cmap,
TT_CMapInfo *cmap_info )
{
FT_Byte* p = cmap->data + 4;
cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
return SFNT_Err_Ok;
}
FT_CALLBACK_TABLE_DEF
const TT_CMap_ClassRec tt_cmap6_class_rec =
{
{
sizeof ( TT_CMapRec ),
(FT_CMap_InitFunc) tt_cmap_init,
(FT_CMap_DoneFunc) NULL,
(FT_CMap_CharIndexFunc)tt_cmap6_char_index,
(FT_CMap_CharNextFunc) tt_cmap6_char_next
},
6,
(TT_CMap_ValidateFunc) tt_cmap6_validate,
(TT_CMap_Info_GetFunc) tt_cmap6_get_info
};
#endif /* TT_CONFIG_CMAP_FORMAT_6 */
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** FORMAT 8 *****/
/***** *****/
/***** It's 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 *****/
/***** glyph indices. Basically, the `char_code' must be in one of *****/
/***** the following formats: *****/
/***** *****/
/***** - A 16-bit value that isn't part of the Unicode Surrogates *****/
/***** Area (i.e. U+D800-U+DFFF). *****/
/***** *****/
/***** - A 32-bit value, made of two surrogate values, i.e.. if *****/
/***** `char_code = (char_hi << 16) | char_lo', then both *****/
/***** `char_hi' and `char_lo' must be in the Surrogates Area. *****/
/***** Area. *****/
/***** *****/
/***** 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: *****/
/***** *****/
/***** If `char_hi == 0' then we must have `is32[char_lo] == 0'. *****/
/***** *****/
/***** If `char_hi != 0' then we must have both *****/
/***** `is32[char_hi] != 0' and `is32[char_lo] != 0'. *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/* */
/* TABLE OVERVIEW */
/* -------------- */
/* */
/* NAME OFFSET TYPE DESCRIPTION */
/* */
/* format 0 USHORT must be 8 */
/* reserved 2 USHORT reserved */
/* length 4 ULONG length in bytes */
/* language 8 ULONG Mac language code */
/* is32 12 BYTE[8192] 32-bitness bitmap */
/* count 8204 ULONG number of groups */
/* */
/* 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_8
FT_CALLBACK_DEF( FT_Error )
tt_cmap8_validate( FT_Byte* table,
FT_Validator valid )
{
FT_Byte* p = table + 4;
FT_Byte* is32;
FT_UInt32 length;
FT_UInt32 num_groups;
if ( table + 16 + 8192 > valid->limit )
FT_INVALID_TOO_SHORT;
length = TT_NEXT_ULONG( p );
if ( table + length > valid->limit || length < 8208 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -