?? t1load.c
字號:
error = T1_Add_Table( code_table, n, base, size ); if ( error ) goto Fail; 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 ( 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; /* we added a glyph. */ loader->num_glyphs = n + 1; } return; Fail: parser->root.error = error; } static const T1_FieldRec t1_keywords[] = {#include "t1tokens.h" /* 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_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0 } }; static FT_Error parse_dict( T1_Face face, T1_Loader loader, FT_Byte* base, FT_Long size ) { T1_Parser 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 && ft_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' && ft_strncmp( (char*)cur, "known", 5 ) ) cur++; if ( cur < limit ) { T1_TokenRec 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_TYPE_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 = (FT_Int)( cur2 - cur ); if ( len > 0 && len < 22 ) { { /* 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)ft_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 ); FT_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->swap_table.init = 0; loader->fontdata = 0; } static void t1_done_loader( T1_Loader loader ) { T1_Parser 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->swap_table ); T1_Release_Table( &loader->subrs ); /* finalize parser */ T1_Finalize_Parser( parser ); } FT_LOCAL_DEF( FT_Error ) T1_Open_Face( T1_Face face ) { T1_LoaderRec loader; T1_Parser parser; T1_Font type1 = &face->type1; FT_Error error; PSAux_Service psaux = (PSAux_Service)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 ) { 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; } if ( !loader.charstrings.init ) { FT_ERROR(( "T1_Open_Face: no charstrings array in face!\n" )); error = T1_Err_Invalid_File_Format; } 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_TYPE_ARRAY ) { FT_Int charcode, idx, 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 ( idx = 0; idx < type1->num_glyphs; idx++ ) { glyph_name = (FT_Byte*)type1->glyph_names[idx]; if ( ft_strcmp( (const char*)char_name, (const char*)glyph_name ) == 0 ) { type1->encoding.char_index[charcode] = (FT_UShort)idx; type1->encoding.char_name [charcode] = (char*)glyph_name; /* Change min/max encoded char only if glyph name is */ /* not /.notdef */ if ( ft_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 + -