📄 ttcmap.c
字号:
FT_INVALID_TOO_SHORT;
is32 = table + 12;
p = is32 + 8192; /* skip `is32' array */
num_groups = TT_NEXT_ULONG( p );
if ( p + num_groups * 12 > valid->limit )
FT_INVALID_TOO_SHORT;
/* check groups, they must be in increasing order */
{
FT_UInt32 n, start, end, start_id, count, last = 0;
for ( n = 0; n < num_groups; n++ )
{
FT_UInt hi, lo;
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;
count = (FT_UInt32)( end - start + 1 );
if ( start & ~0xFFFFU )
{
/* start_hi != 0; check that is32[i] is 1 for each i in */
/* the `hi' and `lo' of the range [start..end] */
for ( ; count > 0; count--, start++ )
{
hi = (FT_UInt)( start >> 16 );
lo = (FT_UInt)( start & 0xFFFFU );
if ( (is32[hi >> 3] & ( 0x80 >> ( hi & 7 ) ) ) == 0 )
FT_INVALID_DATA;
if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) == 0 )
FT_INVALID_DATA;
}
}
else
{
/* start_hi == 0; check that is32[i] is 0 for each i in */
/* the range [start..end] */
/* end_hi cannot be != 0! */
if ( end & ~0xFFFFU )
FT_INVALID_DATA;
for ( ; count > 0; count--, start++ )
{
lo = (FT_UInt)( start & 0xFFFFU );
if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) != 0 )
FT_INVALID_DATA;
}
}
}
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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -