📄 t1load.c
字号:
n++; if ( n >= loader->num_glyphs ) break; } } loader->num_glyphs = n; /* if /.notdef is found but does not occupy index 0, do our magic. */ if ( 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/code to end of table. Then place notdef_index name/code into */ /* index 0. Then take end of table name/code and place it into index */ /* notdef_index. */ error = T1_Add_Table( name_table, n, name_table->elements[0], name_table->lengths [0] ); if ( error ) goto Fail; error = T1_Add_Table( code_table, n, code_table->elements[0], code_table->lengths [0] ); if ( error ) goto Fail; error = T1_Add_Table( name_table, 0, name_table->elements[notdef_index], name_table->lengths [notdef_index] ); if ( error ) goto Fail; error = T1_Add_Table( code_table, 0, code_table->elements[notdef_index], code_table->lengths [notdef_index] ); if ( error ) goto Fail; error = T1_Add_Table( name_table, notdef_index, name_table->elements[n], name_table->lengths [n] ); if ( error ) goto Fail; error = T1_Add_Table( code_table, notdef_index, code_table->elements[n], code_table->lengths [n] ); 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( name_table, n, name_table->elements[0], name_table->lengths [0] ); if ( error ) goto Fail; error = T1_Add_Table( code_table, n, 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; /* we added a glyph. */ loader->num_glyphs = n + 1; } return; Fail: parser->root.error = error; } static const T1_Field t1_keywords[] = {#ifdef FT_FLAT_COMPILE#include "t1tokens.h"#else#include <type1/t1tokens.h>#endif /* now add the special functions... */ T1_FIELD_CALLBACK( "FontName", parse_font_name ) T1_FIELD_CALLBACK( "FontBBox", parse_font_bbox ) T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix ) T1_FIELD_CALLBACK( "Encoding", parse_encoding ) T1_FIELD_CALLBACK( "Subrs", parse_subrs ) T1_FIELD_CALLBACK( "CharStrings", parse_charstrings )#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT T1_FIELD_CALLBACK( "BlendDesignPositions", parse_blend_design_positions ) T1_FIELD_CALLBACK( "BlendDesignMap", parse_blend_design_map ) T1_FIELD_CALLBACK( "BlendAxisTypes", parse_blend_axis_types ) T1_FIELD_CALLBACK( "WeightVector", parse_weight_vector ) T1_FIELD_CALLBACK( "shareddict", parse_shared_dict )#endif { 0, t1_field_cid_info, t1_field_none, 0, 0, 0, 0, 0 } }; static FT_Error parse_dict( T1_Face face, T1_Loader* loader, FT_Byte* base, FT_Long size ) { T1_ParserRec* parser = &loader->parser; parser->root.cursor = base; parser->root.limit = base + size; parser->root.error = 0; { FT_Byte* cur = base; FT_Byte* limit = cur + size; for ( ; cur < limit; cur++ ) { /* look for `FontDirectory', which causes problems on some fonts */ if ( *cur == 'F' && cur + 25 < limit && strncmp( (char*)cur, "FontDirectory", 13 ) == 0 ) { FT_Byte* cur2; /* skip the `FontDirectory' keyword */ cur += 13; cur2 = cur; /* lookup the `known' keyword */ while ( cur < limit && *cur != 'k' && strncmp( (char*)cur, "known", 5 ) ) cur++; if ( cur < limit ) { T1_Token token; /* skip the `known' keyword and the token following it */ cur += 5; loader->parser.root.cursor = cur; T1_ToToken( &loader->parser, &token ); /* if the last token was an array, skip it! */ if ( token.type == t1_token_array ) cur2 = parser->root.cursor; } cur = cur2; } /* look for immediates */ else if ( *cur == '/' && cur + 2 < limit ) { FT_Byte* cur2; FT_Int len; cur++; cur2 = cur; while ( cur2 < limit && is_alpha( *cur2 ) ) cur2++; len = cur2 - cur; if ( len > 0 && len < 22 ) { if ( !loader->fontdata ) { if ( strncmp( (char*)cur, "FontInfo", 8 ) == 0 ) loader->fontdata = 1; } else { /* now, compare the immediate name to the keyword table */ T1_Field* keyword = (T1_Field*)t1_keywords; for (;;) { FT_Byte* name; name = (FT_Byte*)keyword->ident; if ( !name ) break; if ( cur[0] == name[0] && len == (FT_Int)strlen( (const char*)name ) ) { FT_Int n; for ( n = 1; n < len; n++ ) if ( cur[n] != name[n] ) break; if ( n >= len ) { /* we found it -- run the parsing callback! */ parser->root.cursor = cur2; T1_Skip_Spaces( parser ); parser->root.error = t1_load_keyword( face, loader, keyword ); if ( parser->root.error ) return parser->root.error; cur = parser->root.cursor; break; } } keyword++; } } } } } } return parser->root.error; } static void t1_init_loader( T1_Loader* loader, T1_Face face ) { FT_UNUSED( face ); MEM_Set( loader, 0, sizeof ( *loader ) ); loader->num_glyphs = 0; loader->num_chars = 0; /* initialize the tables -- simply set their `init' field to 0 */ loader->encoding_table.init = 0; loader->charstrings.init = 0; loader->glyph_names.init = 0; loader->subrs.init = 0; loader->fontdata = 0; } static void t1_done_loader( T1_Loader* loader ) { T1_ParserRec* parser = &loader->parser; /* finalize tables */ T1_Release_Table( &loader->encoding_table ); T1_Release_Table( &loader->charstrings ); T1_Release_Table( &loader->glyph_names ); T1_Release_Table( &loader->subrs ); /* finalize parser */ T1_Finalize_Parser( parser ); } FT_LOCAL_DEF FT_Error T1_Open_Face( T1_Face face ) { T1_Loader loader; T1_ParserRec* parser; T1_Font* type1 = &face->type1; FT_Error error; PSAux_Interface* psaux = (PSAux_Interface*)face->psaux; t1_init_loader( &loader, face ); /* default lenIV */ type1->private_dict.lenIV = 4; parser = &loader.parser; error = T1_New_Parser( parser, face->root.stream, face->root.memory, psaux ); if ( error ) goto Exit; error = parse_dict( face, &loader, parser->base_dict, parser->base_len ); if ( error ) goto Exit; error = T1_Get_Private_Dict( parser, psaux ); if ( error ) goto Exit; error = parse_dict( face, &loader, parser->private_dict, parser->private_len ); if ( error ) goto Exit; /* now, propagate the subrs, charstrings, and glyphnames tables */ /* to the Type1 data */ type1->num_glyphs = loader.num_glyphs; if ( !loader.subrs.init ) { FT_ERROR(( "T1_Open_Face: no subrs array in face!\n" )); error = T1_Err_Invalid_File_Format; } if ( !loader.charstrings.init ) { FT_ERROR(( "T1_Open_Face: no charstrings array in face!\n" )); error = T1_Err_Invalid_File_Format; } loader.subrs.init = 0; type1->num_subrs = loader.num_subrs; type1->subrs_block = loader.subrs.block; type1->subrs = loader.subrs.elements; type1->subrs_len = loader.subrs.lengths; loader.charstrings.init = 0; type1->charstrings_block = loader.charstrings.block; type1->charstrings = loader.charstrings.elements; type1->charstrings_len = loader.charstrings.lengths; /* we copy the glyph names `block' and `elements' fields; */ /* the `lengths' field must be released later */ type1->glyph_names_block = loader.glyph_names.block; type1->glyph_names = (FT_String**)loader.glyph_names.elements; loader.glyph_names.block = 0; loader.glyph_names.elements = 0; /* we must now build type1.encoding when we have a custom */ /* array.. */ if ( type1->encoding_type == t1_encoding_array ) { FT_Int charcode, index, min_char, max_char; FT_Byte* char_name; FT_Byte* glyph_name; /* OK, we do the following: for each element in the encoding */ /* table, look up the index of the glyph having the same name */ /* the index is then stored in type1.encoding.char_index, and */ /* a the name to type1.encoding.char_name */ min_char = +32000; max_char = -32000; charcode = 0; for ( ; charcode < loader.encoding_table.max_elems; charcode++ ) { type1->encoding.char_index[charcode] = 0; type1->encoding.char_name [charcode] = (char *)".notdef"; char_name = loader.encoding_table.elements[charcode]; if ( char_name ) for ( index = 0; index < type1->num_glyphs; index++ ) { glyph_name = (FT_Byte*)type1->glyph_names[index]; if ( strcmp( (const char*)char_name, (const char*)glyph_name ) == 0 ) { type1->encoding.char_index[charcode] = index; type1->encoding.char_name [charcode] = (char*)glyph_name; /* Change min/max encoded char only if glyph name is */ /* not /.notdef */ if ( strcmp( (const char*)".notdef", (const char*)glyph_name ) != 0 ) { if (charcode < min_char) min_char = charcode; if (charcode > max_char) max_char = charcode; } break; } } } type1->encoding.code_first = min_char; type1->encoding.code_last = max_char; type1->encoding.num_chars = loader.num_chars; } Exit: t1_done_loader( &loader ); return error; }/* END */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -