📄 type1.c
字号:
FT_Error error;
FT_Bool only_immediates = 0;
/* read the number of entries in the encoding; should be 256 */
if ( *cur == '[' )
{
count = 256;
only_immediates = 1;
parser->root.cursor++;
}
else
count = (FT_Int)T1_ToInt( parser );
T1_Skip_Spaces( parser );
if ( parser->root.cursor >= limit )
return;
/* we use a T1_Table to store our charnames */
loader->num_chars = encode->num_chars = count;
if ( FT_NEW_ARRAY( encode->char_index, count ) ||
FT_NEW_ARRAY( encode->char_name, count ) ||
FT_SET_ERROR( psaux->ps_table_funcs->init(
char_table, count, memory ) ) )
{
parser->root.error = error;
return;
}
/* We need to `zero' out encoding_table.elements */
for ( n = 0; n < count; n++ )
{
char* notdef = (char *)".notdef";
T1_Add_Table( char_table, n, notdef, 8 );
}
/* Now we need to read records of the form */
/* */
/* ... charcode /charname ... */
/* */
/* for each entry in our table. */
/* */
/* We simply look for a number followed by an immediate */
/* name. Note that this ignores correctly the sequence */
/* that is often seen in type1 fonts: */
/* */
/* 0 1 255 { 1 index exch /.notdef put } for dup */
/* */
/* used to clean the encoding array before anything else. */
/* */
/* Alternatively, if the array is directly given as */
/* */
/* /Encoding [ ... ] */
/* */
/* we only read immediates. */
n = 0;
T1_Skip_Spaces( parser );
while ( parser->root.cursor < limit )
{
cur = parser->root.cursor;
/* we stop when we encounter a `def' or `]' */
if ( *cur == 'd' && cur + 3 < limit )
{
if ( cur[1] == 'e' &&
cur[2] == 'f' &&
is_space( cur[3] ) )
{
FT_TRACE6(( "encoding end\n" ));
cur += 3;
break;
}
}
if ( *cur == ']' )
{
FT_TRACE6(( "encoding end\n" ));
cur++;
break;
}
/* check whether we've found an entry */
if ( ft_isdigit( *cur ) || only_immediates )
{
FT_Int charcode;
if ( only_immediates )
charcode = n;
else
{
charcode = (FT_Int)T1_ToInt( parser );
T1_Skip_Spaces( parser );
}
cur = parser->root.cursor;
if ( *cur == '/' && cur + 2 < limit && n < count )
{
FT_PtrDist len;
cur++;
parser->root.cursor = cur;
T1_Skip_PS_Token( parser );
if ( parser->root.error )
return;
len = parser->root.cursor - cur;
parser->root.error = T1_Add_Table( char_table, charcode,
cur, len + 1 );
if ( parser->root.error )
return;
char_table->elements[charcode][len] = '\0';
n++;
}
}
else
T1_Skip_PS_Token( parser );
T1_Skip_Spaces( parser );
}
face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY;
parser->root.cursor = cur;
}
/* Otherwise, we should have either `StandardEncoding', */
/* `ExpertEncoding', or `ISOLatin1Encoding' */
else
{
if ( cur + 17 < limit &&
ft_strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 )
face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD;
else if ( cur + 15 < limit &&
ft_strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 )
face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT;
else if ( cur + 18 < limit &&
ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 )
face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1;
else
parser->root.error = T1_Err_Ignore;
}
}
static void
parse_subrs( T1_Face face,
T1_Loader loader )
{
T1_Parser parser = &loader->parser;
PS_Table table = &loader->subrs;
FT_Memory memory = parser->root.memory;
FT_Error error;
FT_Int n, num_subrs;
PSAux_Service psaux = (PSAux_Service)face->psaux;
T1_Skip_Spaces( parser );
/* test for empty array */
if ( parser->root.cursor < parser->root.limit &&
*parser->root.cursor == '[' )
{
T1_Skip_PS_Token( parser );
T1_Skip_Spaces ( parser );
if ( parser->root.cursor >= parser->root.limit ||
*parser->root.cursor != ']' )
parser->root.error = T1_Err_Invalid_File_Format;
return;
}
num_subrs = (FT_Int)T1_ToInt( parser );
/* position the parser right before the `dup' of the first subr */
T1_Skip_PS_Token( parser ); /* `array' */
if ( parser->root.error )
return;
T1_Skip_Spaces( parser );
/* initialize subrs array -- with synthetic fonts it is possible */
/* we get here twice */
if ( !loader->num_subrs )
{
error = psaux->ps_table_funcs->init( table, num_subrs, memory );
if ( error )
goto Fail;
}
/* the format is simple: */
/* */
/* `index' + binary data */
/* */
for ( n = 0; n < num_subrs; n++ )
{
FT_Long idx, size;
FT_Byte* base;
/* If the next token isn't `dup', we are also done. This */
/* happens when there are `holes' in the Subrs array. */
if ( ft_strncmp( (char*)parser->root.cursor, "dup", 3 ) != 0 )
break;
T1_Skip_PS_Token( parser ); /* `dup' */
idx = T1_ToInt( parser );
if ( !read_binary_data( parser, &size, &base ) )
return;
/* The binary string is followed by one token, e.g. `NP' */
/* (bound to `noaccess put') or by two separate tokens: */
/* `noaccess' & `put'. We position the parser right */
/* before the next `dup', if any. */
T1_Skip_PS_Token( parser ); /* `NP' or `|' or `noaccess' */
if ( parser->root.error )
return;
T1_Skip_Spaces ( parser );
if ( ft_strncmp( (char*)parser->root.cursor, "put", 3 ) == 0 )
{
T1_Skip_PS_Token( parser ); /* skip `put' */
T1_Skip_Spaces ( parser );
}
/* with synthetic fonts it is possible we get here twice */
if ( loader->num_subrs )
continue;
/* some fonts use a value of -1 for lenIV to indicate that */
/* the charstrings are unencoded */
/* */
/* thanks to Tom Kacvinsky for pointing this out */
/* */
if ( face->type1.private_dict.lenIV >= 0 )
{
FT_Byte* temp;
/* t1_decrypt() shouldn't write to base -- make temporary copy */
if ( FT_ALLOC( temp, size ) )
goto Fail;
FT_MEM_COPY( temp, base, size );
psaux->t1_decrypt( temp, size, 4330 );
size -= face->type1.private_dict.lenIV;
error = T1_Add_Table( table, (FT_Int)idx,
temp + face->type1.private_dict.lenIV, size );
FT_FREE( temp );
}
else
error = T1_Add_Table( table, (FT_Int)idx, base, size );
if ( error )
goto Fail;
}
if ( !loader->num_subrs )
loader->num_subrs = num_subrs;
return;
Fail:
parser->root.error = error;
}
#define TABLE_EXTEND 5
static void
parse_charstrings( T1_Face face,
T1_Loader loader )
{
T1_Parser parser = &loader->parser;
PS_Table code_table = &loader->charstrings;
PS_Table name_table = &loader->glyph_names;
PS_Table swap_table = &loader->swap_table;
FT_Memory memory = parser->root.memory;
FT_Error error;
PSAux_Service psaux = (PSAux_Service)face->psaux;
FT_Byte* cur;
FT_Byte* limit = parser->root.limit;
FT_Int n, num_glyphs;
FT_UInt notdef_index = 0;
FT_Byte notdef_found = 0;
num_glyphs = (FT_Int)T1_ToInt( parser );
/* some fonts like Optima-Oblique not only define the /CharStrings */
/* array but access it also */
if ( num_glyphs == 0 || parser->root.error )
return;
/* initialize tables, leaving space for addition of .notdef, */
/* if necessary, and a few other glyphs to handle buggy */
/* fonts which have more glyphs than specified. */
/* for some non-standard fonts like `Optima' which provides */
/* different outlines depending on the resolution it is */
/* possible to get here twice */
if ( !loader->num_glyphs )
{
error = psaux->ps_table_funcs->init(
code_table, num_glyphs + 1 + TABLE_EXTEND, memory );
if ( error )
goto Fail;
error = psaux->ps_table_funcs->init(
name_table, num_glyphs + 1 + TABLE_EXTEND, memory );
if ( error )
goto Fail;
/* Initialize table for swapping index notdef_index and */
/* index 0 names and codes (if necessary). */
error = psaux->ps_table_funcs->init( swap_table, 4, memory );
if ( error )
goto Fail;
}
n = 0;
for (;;)
{
FT_Long size;
FT_Byte* base;
/* the format is simple: */
/* `/glyphname' + binary data */
T1_Skip_Spaces( parser );
cur = parser->root.cursor;
if ( cur >= limit )
break;
/* we stop when we find a `def' or `end' keyword */
if ( cur + 3 < limit && is_space( cur[3] ) )
{
if ( cur[0] == 'd' &&
cur[1] == 'e' &&
cur[2] == 'f' )
{
/* There are fonts which have this: */
/* */
/* /CharStrings 118 dict def */
/* Private begin */
/* CharStrings begin */
/* ... */
/* */
/* To catch this we ignore `def' if */
/* no charstring has actually been */
/* seen. */
if ( n )
break;
}
if ( cur[0] == 'e' &&
cur[1] == 'n' &&
cur[2] == 'd' )
break;
}
T1_Skip_PS_Token( parser );
if ( parser->root.error )
return;
if ( *cur == '/' )
{
FT_PtrDist len;
if ( cur + 1 >= limit )
{
error = T1_Err_Invalid_File_Format;
goto Fail;
}
cur++; /* skip `/' */
len = parser->root.cursor - cur;
if ( !read_binary_data( parser, &size, &base ) )
return;
/* for some non-standard fonts like `Optima' which
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -