📄 cffload.c
字号:
offset = idx->offsets[n];
if ( !offset )
offset = old_offset;
/* sanity check for invalid offset tables */
else if ( offset < old_offset || offset - 1 >= idx->data_size )
offset = old_offset;
t[n] = idx->bytes + offset - 1;
old_offset = offset;
}
*table = t;
}
Exit:
return error;
}
FT_LOCAL_DEF( FT_Error )
cff_index_access_element( CFF_Index idx,
FT_UInt element,
FT_Byte** pbytes,
FT_ULong* pbyte_len )
{
FT_Error error = CFF_Err_Ok;
if ( idx && idx->count > element )
{
/* compute start and end offsets */
FT_Stream stream = idx->stream;
FT_ULong off1, off2 = 0;
/* load offsets from file or the offset table */
if ( !idx->offsets )
{
FT_ULong pos = element * idx->off_size;
if ( FT_STREAM_SEEK( idx->start + 3 + pos ) )
goto Exit;
off1 = cff_index_read_offset( idx, &error );
if ( error )
goto Exit;
if ( off1 != 0 )
{
do
{
element++;
off2 = cff_index_read_offset( idx, &error );
}
while ( off2 == 0 && element < idx->count );
}
}
else /* use offsets table */
{
off1 = idx->offsets[element];
if ( off1 )
{
do
{
element++;
off2 = idx->offsets[element];
} while ( off2 == 0 && element < idx->count );
}
}
/* access element */
if ( off1 && off2 > off1 )
{
*pbyte_len = off2 - off1;
if ( idx->bytes )
{
/* this index was completely loaded in memory, that's easy */
*pbytes = idx->bytes + off1 - 1;
}
else
{
/* this index is still on disk/file, access it through a frame */
if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) ||
FT_FRAME_EXTRACT( off2 - off1, *pbytes ) )
goto Exit;
}
}
else
{
/* empty index element */
*pbytes = 0;
*pbyte_len = 0;
}
}
else
error = CFF_Err_Invalid_Argument;
Exit:
return error;
}
FT_LOCAL_DEF( void )
cff_index_forget_element( CFF_Index idx,
FT_Byte** pbytes )
{
if ( idx->bytes == 0 )
{
FT_Stream stream = idx->stream;
FT_FRAME_RELEASE( *pbytes );
}
}
FT_LOCAL_DEF( FT_String* )
cff_index_get_name( CFF_Index idx,
FT_UInt element )
{
FT_Memory memory = idx->stream->memory;
FT_Byte* bytes;
FT_ULong byte_len;
FT_Error error;
FT_String* name = 0;
error = cff_index_access_element( idx, element, &bytes, &byte_len );
if ( error )
goto Exit;
if ( !FT_ALLOC( name, byte_len + 1 ) )
{
FT_MEM_COPY( name, bytes, byte_len );
name[byte_len] = 0;
}
cff_index_forget_element( idx, &bytes );
Exit:
return name;
}
FT_LOCAL_DEF( FT_String* )
cff_index_get_sid_string( CFF_Index idx,
FT_UInt sid,
FT_Service_PsCMaps psnames )
{
/* value 0xFFFFU indicates a missing dictionary entry */
if ( sid == 0xFFFFU )
return 0;
/* if it is not a standard string, return it */
if ( sid > 390 )
return cff_index_get_name( idx, sid - 391 );
/* CID-keyed CFF fonts don't have glyph names */
if ( !psnames )
return 0;
/* that's a standard string, fetch a copy from the PSName module */
{
FT_String* name = 0;
const char* adobe_name = psnames->adobe_std_strings( sid );
FT_UInt len;
if ( adobe_name )
{
FT_Memory memory = idx->stream->memory;
FT_Error error;
len = (FT_UInt)ft_strlen( adobe_name );
if ( !FT_ALLOC( name, len + 1 ) )
{
FT_MEM_COPY( name, adobe_name, len );
name[len] = 0;
}
FT_UNUSED( error );
}
return name;
}
}
/*************************************************************************/
/*************************************************************************/
/*** ***/
/*** FD Select table support ***/
/*** ***/
/*************************************************************************/
/*************************************************************************/
static void
CFF_Done_FD_Select( CFF_FDSelect fdselect,
FT_Stream stream )
{
if ( fdselect->data )
FT_FRAME_RELEASE( fdselect->data );
fdselect->data_size = 0;
fdselect->format = 0;
fdselect->range_count = 0;
}
static FT_Error
CFF_Load_FD_Select( CFF_FDSelect fdselect,
FT_UInt num_glyphs,
FT_Stream stream,
FT_ULong offset )
{
FT_Error error;
FT_Byte format;
FT_UInt num_ranges;
/* read format */
if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( format ) )
goto Exit;
fdselect->format = format;
fdselect->cache_count = 0; /* clear cache */
switch ( format )
{
case 0: /* format 0, that's simple */
fdselect->data_size = num_glyphs;
goto Load_Data;
case 3: /* format 3, a tad more complex */
if ( FT_READ_USHORT( num_ranges ) )
goto Exit;
fdselect->data_size = num_ranges * 3 + 2;
Load_Data:
if ( FT_FRAME_EXTRACT( fdselect->data_size, fdselect->data ) )
goto Exit;
break;
default: /* hmm... that's wrong */
error = CFF_Err_Invalid_File_Format;
}
Exit:
return error;
}
FT_LOCAL_DEF( FT_Byte )
cff_fd_select_get( CFF_FDSelect fdselect,
FT_UInt glyph_index )
{
FT_Byte fd = 0;
switch ( fdselect->format )
{
case 0:
fd = fdselect->data[glyph_index];
break;
case 3:
/* first, compare to cache */
if ( (FT_UInt)( glyph_index - fdselect->cache_first ) <
fdselect->cache_count )
{
fd = fdselect->cache_fd;
break;
}
/* then, lookup the ranges array */
{
FT_Byte* p = fdselect->data;
FT_Byte* p_limit = p + fdselect->data_size;
FT_Byte fd2;
FT_UInt first, limit;
first = FT_NEXT_USHORT( p );
do
{
if ( glyph_index < first )
break;
fd2 = *p++;
limit = FT_NEXT_USHORT( p );
if ( glyph_index < limit )
{
fd = fd2;
/* update cache */
fdselect->cache_first = first;
fdselect->cache_count = limit-first;
fdselect->cache_fd = fd2;
break;
}
first = limit;
} while ( p < p_limit );
}
break;
default:
;
}
return fd;
}
/*************************************************************************/
/*************************************************************************/
/*** ***/
/*** CFF font support ***/
/*** ***/
/*************************************************************************/
/*************************************************************************/
static FT_Error
cff_charset_compute_cids( CFF_Charset charset,
FT_UInt num_glyphs,
FT_Memory memory )
{
FT_Error error = FT_Err_Ok;
FT_UInt i;
FT_UShort max_cid = 0;
if ( charset->max_cid > 0 )
goto Exit;
for ( i = 0; i < num_glyphs; i++ )
if ( charset->sids[i] > max_cid )
max_cid = charset->sids[i];
max_cid++;
if ( FT_NEW_ARRAY( charset->cids, max_cid ) )
goto Exit;
for ( i = 0; i < num_glyphs; i++ )
charset->cids[charset->sids[i]] = (FT_UShort)i;
charset->max_cid = max_cid;
charset->num_glyphs = num_glyphs;
Exit:
return error;
}
FT_LOCAL_DEF( FT_UInt )
cff_charset_cid_to_gindex( CFF_Charset charset,
FT_UInt cid )
{
FT_UInt result = 0;
if ( cid < charset->max_cid )
result = charset->cids[cid];
return result;
}
static void
cff_charset_free_cids( CFF_Charset charset,
FT_Memory memory )
{
FT_FREE( charset->cids );
charset->max_cid = 0;
}
static void
cff_charset_done( CFF_Charset charset,
FT_Stream stream )
{
FT_Memory memory = stream->memory;
cff_charset_free_cids( charset, memory );
FT_FREE( charset->sids );
charset->format = 0;
charset->offset = 0;
}
static FT_Error
cff_charset_load( CFF_Charset charset,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -