📄 t1load.c
字号:
{
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_PS_DELIM( 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 provides */
/* different outlines depending on the resolution it is */
/* possible to get here twice */
if ( loader->num_glyphs )
continue;
error = T1_Add_Table( name_table, n, cur, len + 1 );
if ( error )
goto Fail;
/* add a trailing zero to the name table */
name_table->elements[n][len] = '\0';
/* record index of /.notdef */
if ( *cur == '.' &&
ft_strcmp( ".notdef",
(const char*)(name_table->elements[n]) ) == 0 )
{
notdef_index = n;
notdef_found = 1;
}
if ( face->type1.private_dict.lenIV >= 0 &&
n < num_glyphs + TABLE_EXTEND )
{
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( code_table, n,
temp + face->type1.private_dict.lenIV, size );
FT_FREE( temp );
}
else
error = T1_Add_Table( code_table, n, base, size );
if ( error )
goto Fail;
n++;
}
}
if ( loader->num_glyphs )
return;
else
loader->num_glyphs = n;
/* if /.notdef is found but does not occupy index 0, do our magic. */
if ( ft_strcmp( (const char*)".notdef",
(const char*)name_table->elements[0] ) &&
notdef_found )
{
/* Swap glyph in index 0 with /.notdef glyph. First, add index 0 */
/* name and code entries to swap_table. Then place notdef_index */
/* name and code entries into swap_table. Then swap name and code */
/* entries at indices notdef_index and 0 using values stored in */
/* swap_table. */
/* Index 0 name */
error = T1_Add_Table( swap_table, 0,
name_table->elements[0],
name_table->lengths [0] );
if ( error )
goto Fail;
/* Index 0 code */
error = T1_Add_Table( swap_table, 1,
code_table->elements[0],
code_table->lengths [0] );
if ( error )
goto Fail;
/* Index notdef_index name */
error = T1_Add_Table( swap_table, 2,
name_table->elements[notdef_index],
name_table->lengths [notdef_index] );
if ( error )
goto Fail;
/* Index notdef_index code */
error = T1_Add_Table( swap_table, 3,
code_table->elements[notdef_index],
code_table->lengths [notdef_index] );
if ( error )
goto Fail;
error = T1_Add_Table( name_table, notdef_index,
swap_table->elements[0],
swap_table->lengths [0] );
if ( error )
goto Fail;
error = T1_Add_Table( code_table, notdef_index,
swap_table->elements[1],
swap_table->lengths [1] );
if ( error )
goto Fail;
error = T1_Add_Table( name_table, 0,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -