📄 t1load.c
字号:
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, swap_table->elements[2], swap_table->lengths [2] ); if ( error ) goto Fail; error = T1_Add_Table( code_table, 0, swap_table->elements[3], swap_table->lengths [3] ); if ( error ) goto Fail; } else if ( !notdef_found ) { /* notdef_index is already 0, or /.notdef is undefined in */ /* charstrings dictionary. Worry about /.notdef undefined. */ /* We take index 0 and add it to the end of the table(s) */ /* and add our own /.notdef glyph to index 0. */ /* 0 333 hsbw endchar */ FT_Byte notdef_glyph[] = {0x8B, 0xF7, 0xE1, 0x0D, 0x0E}; char* notdef_name = (char *)".notdef"; error = T1_Add_Table( swap_table, 0, name_table->elements[0], name_table->lengths [0] ); if ( error ) goto Fail; error = T1_Add_Table( swap_table, 1, code_table->elements[0], code_table->lengths [0] ); if ( error ) goto Fail; error = T1_Add_Table( name_table, 0, notdef_name, 8 ); if ( error ) goto Fail; error = T1_Add_Table( code_table, 0, notdef_glyph, 5 ); if ( error ) goto Fail; error = T1_Add_Table( name_table, n, swap_table->elements[0], swap_table->lengths [0] ); if ( error ) goto Fail; error = T1_Add_Table( code_table, n, swap_table->elements[1], swap_table->lengths [1] ); if ( error ) goto Fail;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -