?? cffload.c
字號(hào):
{
if ( idx->stream )
{
FT_Stream stream = idx->stream;
FT_Memory memory = stream->memory;
if ( idx->bytes )
FT_FRAME_RELEASE( idx->bytes );
FT_FREE( idx->offsets );
FT_MEM_ZERO( idx, sizeof ( *idx ) );
}
}
/* allocate a table containing pointers to an index's elements */
static FT_Error
cff_index_get_pointers( CFF_Index idx,
FT_Byte*** table )
{
FT_Error error = CFF_Err_Ok;
FT_Memory memory = idx->stream->memory;
FT_ULong n, offset, old_offset;
FT_Byte** t;
*table = 0;
if ( idx->count > 0 && !FT_NEW_ARRAY( t, idx->count + 1 ) )
{
old_offset = 1;
for ( n = 0; n <= idx->count; n++ )
{
offset = idx->offsets[n];
if ( !offset )
offset = old_offset;
t[n] = idx->bytes + offset - 1;
old_offset = offset;
}
*table = t;
}
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_ULong off1, off2 = 0;
off1 = idx->offsets[element];
if ( off1 )
{
do
{
element++;
off2 = idx->offsets[element];
} while ( off2 == 0 && element < idx->count );
if ( !off2 )
off1 = 0;
}
/* 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 */
FT_Stream stream = idx->stream;
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 void
cff_charset_done( CFF_Charset charset,
FT_Stream stream )
{
FT_Memory memory = stream->memory;
FT_FREE( charset->sids );
FT_FREE( charset->cids );
charset->format = 0;
charset->offset = 0;
}
static FT_Error
cff_charset_load( CFF_Charset charset,
FT_UInt num_glyphs,
FT_Stream stream,
FT_ULong base_offset,
FT_ULong offset,
FT_Bool invert )
{
FT_Memory memory = stream->memory;
FT_Error error = CFF_Err_Ok;
FT_UShort glyph_sid;
/* If the the offset is greater than 2, we have to parse the */
/* charset table. */
if ( offset > 2 )
{
FT_UInt j;
charset->offset = base_offset + offset;
/* Get the format of the table. */
if ( FT_STREAM_SEEK( charset->offset ) ||
FT_READ_BYTE( charset->format ) )
goto Exit;
/* Allocate memory for sids. */
if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
goto Exit;
/* assign the .notdef glyph */
charset->sids[0] = 0;
switch ( charset->format )
{
case 0:
if ( num_glyphs > 0 )
{
if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) )
goto Exit;
for ( j = 1; j < num_glyphs; j++ )
charset->sids[j] = FT_GET_USHORT();
FT_FRAME_EXIT();
}
break;
case 1:
case 2:
{
FT_UInt nleft;
FT_UInt i;
j = 1;
while ( j < num_glyphs )
{
/* Read the first glyph sid of the range. */
if ( FT_READ_USHORT( glyph_sid ) )
goto Exit;
/* Read the number of glyphs in the range. */
if ( charset->format == 2 )
{
if ( FT_READ_USHORT( nleft ) )
goto Exit;
}
else
{
if ( FT_READ_BYTE( nleft ) )
goto Exit;
}
/* Fill in the range of sids -- `nleft + 1' glyphs. */
for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ )
charset->sids[j] = glyph_sid;
}
}
break;
default:
FT_ERROR(( "cff_charset_load: invalid table format!\n" ));
error = CFF_Err_Invalid_File_Format;
goto Exit;
}
}
else
{
/* Parse default tables corresponding to offset == 0, 1, or 2. */
/* CFF specification intimates the following: */
/* */
/* In order to use a predefined charset, the following must be */
/* true: The charset constructed for the glyphs in the font's */
/* charstrings dictionary must match the predefined charset in */
/* the first num_glyphs. */
charset->offset = offset; /* record charset type */
switch ( (FT_UInt)offset )
{
case 0:
if ( num_glyphs > 229 )
{
FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
"predefined charset (Adobe ISO-Latin)!\n" ));
error = CFF_Err_Invalid_File_Format;
goto Exit;
}
/* Allocate memory for sids. */
if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
goto Exit;
/* Copy the predefined charset into the allocated memory. */
FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs );
break;
case 1:
if ( num_glyphs > 166 )
{
FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
"predefined charset (Adobe Expert)!\n" ));
error = CFF_Err_Invalid_File_Format;
goto Exit;
}
/* Allocate memory for sids. */
if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
goto Exit;
/* Copy the predefined charset into the allocated memory. */
FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs );
break;
case 2:
if ( num_glyphs > 87 )
{
FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
"predefined charset (Adobe Expert Subset)!\n" ));
error = CFF_Err_Invalid_File_Format;
goto Exit;
}
/* Allocate memory for sids. */
if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
goto Exit;
/* Copy the predefined charset into the allocated memory. */
FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs );
break;
default:
error = CFF_Err_Invalid_File_Format;
goto Exit;
}
}
/* we have to invert the `sids' array for subsetted CID-keyed fonts */
if ( invert )
{
FT_UInt i;
FT_UShort max_cid = 0;
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;
FT_MEM_ZERO( charset->cids, sizeof ( FT_UShort ) * max_cid );
for ( i = 0; i < num_glyphs; i++ )
charset->cids[charset->sids[i]] = (FT_UShort)i;
charset->max_cid = max_cid;
}
Exit:
/* Clean up if there was an error. */
if ( error )
{
FT_FREE( charset->sids );
FT_FREE( charset->cids );
charset->format = 0;
charset->offset = 0;
charset->sids = 0;
}
return error;
}
static void
cff_encoding_done( CFF_Encoding encoding )
{
encoding->format = 0;
encoding->offset = 0;
encoding->count = 0;
}
static FT_Error
cff_encoding_load( CFF_Encoding encoding,
CFF_Charset charset,
FT_UInt num_glyphs,
FT_Stream stream,
FT_ULong base_offset,
FT_ULong offset )
{
FT_Error error = CFF_Err_Ok;
FT_UInt count;
FT_UInt j;
FT_UShort glyph_sid;
FT_UInt glyph_code;
/* Check for charset->sids. If we do not have this, we fail. */
if ( !charset->sids )
{
error = CFF_Err_Invalid_File_Format;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -