?? t1load.c
字號:
T1_Loader loader ) { T1_Parser parser = &loader->parser; FT_Matrix* matrix = &face->type1.font_matrix; FT_Vector* offset = &face->type1.font_offset; FT_Face root = (FT_Face)&face->root; FT_Fixed temp[6]; FT_Fixed temp_scale; if ( matrix->xx || matrix->yx ) /* with synthetic fonts, it's possible we get here twice */ return; (void)T1_ToFixedArray( parser, 6, temp, 3 ); temp_scale = ABS( temp[3] ); /* Set Units per EM based on FontMatrix values. We set the value to */ /* 1000 / temp_scale, because temp_scale was already multiplied by */ /* 1000 (in t1_tofixed, from psobjs.c). */ root->units_per_EM = (FT_UShort)( FT_DivFix( 1000 * 0x10000L, temp_scale ) >> 16 ); /* we need to scale the values by 1.0/temp_scale */ if ( temp_scale != 0x10000L ) { temp[0] = FT_DivFix( temp[0], temp_scale ); temp[1] = FT_DivFix( temp[1], temp_scale ); temp[2] = FT_DivFix( temp[2], temp_scale ); temp[4] = FT_DivFix( temp[4], temp_scale ); temp[5] = FT_DivFix( temp[5], temp_scale ); temp[3] = 0x10000L; } matrix->xx = temp[0]; matrix->yx = temp[1]; matrix->xy = temp[2]; matrix->yy = temp[3]; /* note that the offsets must be expressed in integer font units */ offset->x = temp[4] >> 16; offset->y = temp[5] >> 16; } static void parse_encoding( T1_Face face, T1_Loader loader ) { T1_Parser parser = &loader->parser; FT_Byte* cur = parser->root.cursor; FT_Byte* limit = parser->root.limit; PSAux_Service psaux = (PSAux_Service)face->psaux; /* skip whitespace */ while ( is_space( *cur ) ) { cur++; if ( cur >= limit ) { FT_ERROR(( "parse_encoding: out of bounds!\n" )); parser->root.error = T1_Err_Invalid_File_Format; return; } } /* if we have a number, then the encoding is an array, */ /* and we must load it now */ if ( (FT_Byte)( *cur - '0' ) < 10 ) { T1_Encoding encode = &face->type1.encoding; FT_Int count, n; PS_Table char_table = &loader->encoding_table; FT_Memory memory = parser->root.memory; FT_Error error; if ( encode->char_index ) /* with synthetic fonts, it's possible we get here twice */ return; /* read the number of entries in the encoding, should be 256 */ count = T1_ToInt( parser ); if ( parser->root.error ) 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 will need to read a record 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. */ /* */ /* We stop when we encounter a `def'. */ cur = parser->root.cursor; limit = parser->root.limit; n = 0; for ( ; cur < limit; ) { FT_Byte c; c = *cur; /* we stop when we encounter a `def' */ if ( c == 'd' && cur + 3 < limit ) { if ( cur[1] == 'e' && cur[2] == 'f' && is_space( cur[-1] ) && is_space( cur[3] ) ) { FT_TRACE6(( "encoding end\n" )); break; } } /* otherwise, we must find a number before anything else */ if ( (FT_Byte)( c - '0' ) < 10 ) { FT_Int charcode; parser->root.cursor = cur; charcode = T1_ToInt( parser ); cur = parser->root.cursor; /* skip whitespace */ while ( cur < limit && is_space( *cur ) ) cur++; if ( cur < limit && *cur == '/' ) { /* bingo, we have an immediate name -- it must be a */ /* character name */ FT_Byte* cur2 = cur + 1; FT_Int len; while ( cur2 < limit && is_alpha( *cur2 ) ) cur2++; len = (FT_Int)( cur2 - cur - 1 ); parser->root.error = T1_Add_Table( char_table, charcode, cur + 1, len + 1 ); char_table->elements[charcode][len] = '\0'; if ( parser->root.error ) return; cur = cur2; } } else cur++; } 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 { FT_ERROR(( "parse_encoding: invalid token!\n" )); parser->root.error = T1_Err_Invalid_File_Format; } } } 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; PSAux_Service psaux = (PSAux_Service)face->psaux; if ( loader->num_subrs ) /* with synthetic fonts, it's possible we get here twice */ return; loader->num_subrs = T1_ToInt( parser ); if ( parser->root.error ) return; /* position the parser right before the `dup' of the first subr */ T1_Skip_Spaces( parser ); T1_Skip_Alpha( parser ); /* `array' */ T1_Skip_Spaces( parser ); /* initialize subrs array */ error = psaux->ps_table_funcs->init( table, loader->num_subrs, memory ); if ( error ) goto Fail; /* the format is simple: */ /* */ /* `index' + binary data */ /* */ for ( n = 0; n < loader->num_subrs; n++ ) { FT_Int 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; 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_Spaces( parser ); T1_Skip_Alpha( parser ); /* `NP' or `I' or `noaccess' */ T1_Skip_Spaces( parser ); if ( ft_strncmp( (char*)parser->root.cursor, "put", 3 ) == 0 ) { T1_Skip_Alpha( parser ); /* skip `put' */ T1_Skip_Spaces( parser ); } /* 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, idx, temp + face->type1.private_dict.lenIV, size ); FT_FREE( temp ); } else error = T1_Add_Table( table, idx, base, size ); if ( error ) goto Fail; } return; Fail: parser->root.error = error; } 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; FT_UInt notdef_index = 0; FT_Byte notdef_found = 0; if ( loader->num_glyphs ) /* with synthetic fonts, it's possible we get here twice */ return; loader->num_glyphs = T1_ToInt( parser ); if ( parser->root.error ) return; /* initialize tables (leaving room for addition of .notdef, */ /* if necessary). */ error = psaux->ps_table_funcs->init( code_table, loader->num_glyphs + 1, memory ); if ( error ) goto Fail; error = psaux->ps_table_funcs->init( name_table, loader->num_glyphs + 1, 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_Int size; FT_Byte* base; /* the format is simple: */ /* `/glyphname' + binary data */ /* */ /* note that we stop when we find a `def' */ /* */ T1_Skip_Spaces( parser ); cur = parser->root.cursor; if ( cur >= limit ) break; /* we stop when we find a `def' or `end' keyword */ if ( *cur == 'd' && cur + 3 < limit && cur[1] == 'e' && cur[2] == 'f' ) break; if ( *cur == 'e' && cur + 3 < limit && cur[1] == 'n' && cur[2] == 'd' ) break; if ( *cur != '/' ) T1_Skip_Alpha( parser ); else { FT_Byte* cur2 = cur + 1; FT_Int len; while ( cur2 < limit && is_alpha( *cur2 ) ) cur2++; len = (FT_Int)( cur2 - cur - 1 ); error = T1_Add_Table( name_table, n, cur + 1, 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 ( ft_strcmp( (const char*)".notdef", (const char*)(name_table->elements[n]) ) == 0 ) { notdef_index = n; notdef_found = 1; } parser->root.cursor = cur2; if ( !read_binary_data( parser, &size, &base ) ) return; { 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
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -