📄 t1load.c
字号:
{ if ( ALLOC( face->type1.font_name, len + 1 ) ) { parser->root.error = error; return; } MEM_Copy( face->type1.font_name, cur, len ); face->type1.font_name[len] = '\0'; } parser->root.cursor = cur2; } static void parse_font_bbox( T1_Face face, T1_Loader* loader ) { T1_ParserRec* parser = &loader->parser; FT_Short temp[4]; FT_BBox* bbox = &face->type1.font_bbox; (void)T1_ToCoordArray( parser, 4, temp ); bbox->xMin = temp[0]; bbox->yMin = temp[1]; bbox->xMax = temp[2]; bbox->yMax = temp[3]; } static void parse_font_matrix( T1_Face face, T1_Loader* loader ) { T1_ParserRec* parser = &loader->parser; FT_Matrix* matrix = &face->type1.font_matrix; FT_Vector* offset = &face->type1.font_offset; FT_Fixed temp[6]; if ( matrix->xx || matrix->yx ) /* with synthetic fonts, it's possible we get here twice */ return; (void)T1_ToFixedArray( parser, 6, temp, 3 ); /* we need to scale the values by 1.0/temp[3] */ if ( temp[3] != 0x10000L ) { temp[0] = FT_DivFix( temp[0], temp[3] ); temp[1] = FT_DivFix( temp[1], temp[3] ); temp[2] = FT_DivFix( temp[2], temp[3] ); temp[4] = FT_DivFix( temp[4], temp[3] ); temp[5] = FT_DivFix( temp[5], temp[3] ); 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_ParserRec* parser = &loader->parser; FT_Byte* cur = parser->root.cursor; FT_Byte* limit = parser->root.limit; PSAux_Interface* psaux = (PSAux_Interface*)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; /* 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 */ encode->num_chars = count; if ( ALLOC_ARRAY( encode->char_index, count, FT_Short ) || ALLOC_ARRAY( encode->char_name, count, FT_String* ) || ( error = psaux->ps_table_funcs->init( char_table, count, memory ) ) != 0 ) { 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 = 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_array; parser->root.cursor = cur; } /* Otherwise, we should have either `StandardEncoding' or */ /* `ExpertEncoding' */ else { if ( cur + 17 < limit && strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 ) face->type1.encoding_type = t1_encoding_standard; else if ( cur + 15 < limit && strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 ) face->type1.encoding_type = t1_encoding_expert; 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_ParserRec* parser = &loader->parser; PS_Table* table = &loader->subrs; FT_Memory memory = parser->root.memory; FT_Error error; FT_Int n; PSAux_Interface* psaux = (PSAux_Interface*)face->psaux; 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 index, 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 ( strncmp( (char*)parser->root.cursor, "dup", 3 ) != 0 ) break; index = 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 ( 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 ) { psaux->t1_decrypt( base, size, 4330 ); size -= face->type1.private_dict.lenIV; base += face->type1.private_dict.lenIV; } error = T1_Add_Table( table, index, base, size ); if ( error ) goto Fail; } return; Fail: parser->root.error = error; } static void parse_charstrings( T1_Face face, T1_Loader* loader ) { T1_ParserRec* parser = &loader->parser; PS_Table* code_table = &loader->charstrings; PS_Table* name_table = &loader->glyph_names; FT_Memory memory = parser->root.memory; FT_Error error; PSAux_Interface* psaux = (PSAux_Interface*)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, adding space for `swap' at table end */ 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; 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 = 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 ( 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; if ( face->type1.private_dict.lenIV >= 0 ) { psaux->t1_decrypt( base, size, 4330 ); size -= face->type1.private_dict.lenIV; base += face->type1.private_dict.lenIV; } error = T1_Add_Table( code_table, n, base, size ); if ( error ) goto Fail;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -