📄 ttcmap0.c
字号:
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;
}
}
}
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 FT_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
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_DEF( FT_Error )
tt_cmap12_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 FT_Err_Ok;
}
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,
(TT_CMap_Info_GetFunc) tt_cmap12_get_info
};
#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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -