📄 t1load.c
字号:
if ( !blend || !blend->num_designs ) { error = t1_allocate_blend( face, num_designs, 0 ); if ( error ) goto Exit; blend = face->blend; } else if ( blend->num_designs != (FT_UInt)num_designs ) { FT_ERROR(( "parse_weight_vector:" " /BlendDesignPosition and /WeightVector have\n" )); FT_ERROR(( " " " different number of elements!\n" )); error = T1_Err_Invalid_File_Format; goto Exit; } old_cursor = parser->root.cursor; old_limit = parser->root.limit; for ( n = 0; n < num_designs; n++ ) { token = design_tokens + n; parser->root.cursor = token->start; parser->root.limit = token->limit; blend->default_weight_vector[n] = blend->weight_vector[n] = T1_ToFixed( parser, 0 ); } parser->root.cursor = old_cursor; parser->root.limit = old_limit; Exit: parser->root.error = error; } /* e.g., /BuildCharArray [0 0 0 0 0 0 0 0] def */ /* we're only interested in the number of array elements */ static void parse_buildchar( T1_Face face, T1_Loader loader ) { face->len_buildchar = T1_ToFixedArray( &loader->parser, 0, NULL, 0 ); return; }#endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */ /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** TYPE 1 SYMBOL PARSING *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ static FT_Error t1_load_keyword( T1_Face face, T1_Loader loader, const T1_Field field ) { FT_Error error; void* dummy_object; void** objects; FT_UInt max_objects; PS_Blend blend = face->blend; /* if the keyword has a dedicated callback, call it */ if ( field->type == T1_FIELD_TYPE_CALLBACK ) { field->reader( (FT_Face)face, loader ); error = loader->parser.root.error; goto Exit; } /* now, the keyword is either a simple field, or a table of fields; */ /* we are now going to take care of it */ switch ( field->location ) { case T1_FIELD_LOCATION_FONT_INFO: dummy_object = &face->type1.font_info; objects = &dummy_object; max_objects = 0; if ( blend ) { objects = (void**)blend->font_infos; max_objects = blend->num_designs; } break; case T1_FIELD_LOCATION_PRIVATE: dummy_object = &face->type1.private_dict; objects = &dummy_object; max_objects = 0; if ( blend ) { objects = (void**)blend->privates; max_objects = blend->num_designs; } break; case T1_FIELD_LOCATION_BBOX: dummy_object = &face->type1.font_bbox; objects = &dummy_object; max_objects = 0; if ( blend ) { objects = (void**)blend->bboxes; max_objects = blend->num_designs; } break; case T1_FIELD_LOCATION_LOADER: dummy_object = loader; objects = &dummy_object; max_objects = 0; break; case T1_FIELD_LOCATION_FACE: dummy_object = face; objects = &dummy_object; max_objects = 0; break;#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT case T1_FIELD_LOCATION_BLEND: dummy_object = face->blend; objects = &dummy_object; max_objects = 0; break;#endif default: dummy_object = &face->type1; objects = &dummy_object; max_objects = 0; } if ( field->type == T1_FIELD_TYPE_INTEGER_ARRAY || field->type == T1_FIELD_TYPE_FIXED_ARRAY ) error = T1_Load_Field_Table( &loader->parser, field, objects, max_objects, 0 ); else error = T1_Load_Field( &loader->parser, field, objects, max_objects, 0 ); Exit: return error; } static void parse_private( T1_Face face, T1_Loader loader ) { FT_UNUSED( face ); loader->keywords_encountered |= T1_PRIVATE; } static int read_binary_data( T1_Parser parser, FT_Long* size, FT_Byte** base ) { FT_Byte* cur; FT_Byte* limit = parser->root.limit; /* the binary data has one of the following formats */ /* */ /* `size' [white*] RD white ....... ND */ /* `size' [white*] -| white ....... |- */ /* */ T1_Skip_Spaces( parser ); cur = parser->root.cursor; if ( cur < limit && ft_isdigit( *cur ) ) { *size = T1_ToInt( parser ); T1_Skip_PS_Token( parser ); /* `RD' or `-|' or something else */ /* there is only one whitespace char after the */ /* `RD' or `-|' token */ *base = parser->root.cursor + 1; parser->root.cursor += *size + 1; return !parser->root.error; } FT_ERROR(( "read_binary_data: invalid size field\n" )); parser->root.error = T1_Err_Invalid_File_Format; return 0; } /* We now define the routines to handle the `/Encoding', `/Subrs', */ /* and `/CharStrings' dictionaries. */ static void parse_font_matrix( T1_Face face, 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; (void)T1_ToFixedArray( parser, 6, temp, 3 ); temp_scale = FT_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; FT_Byte* limit = parser->root.limit; PSAux_Service psaux = (PSAux_Service)face->psaux; T1_Skip_Spaces( parser ); cur = parser->root.cursor; 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 or `[', the encoding is an array, */ /* and we must load it now */ if ( ft_isdigit( *cur ) || *cur == '[' ) { 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; FT_Bool only_immediates = 0; /* read the number of entries in the encoding; should be 256 */ if ( *cur == '[' ) { count = 256; only_immediates = 1; parser->root.cursor++; } else count = (FT_Int)T1_ToInt( parser ); T1_Skip_Spaces( parser ); if ( parser->root.cursor >= limit ) 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 need to read records 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. */ /* */ /* Alternatively, if the array is directly given as */ /* */ /* /Encoding [ ... ] */ /* */ /* we only read immediates. */ n = 0; T1_Skip_Spaces( parser ); while ( parser->root.cursor < limit ) { cur = parser->root.cursor; /* we stop when we encounter a `def' or `]' */ if ( *cur == 'd' && cur + 3 < limit ) { if ( cur[1] == 'e' && cur[2] == 'f' && IS_PS_DELIM( cur[3] ) ) { FT_TRACE6(( "encoding end\n" )); cur += 3; break; } } if ( *cur == ']' ) { FT_TRACE6(( "encoding end\n" )); cur++; break; } /* check whether we've found an entry */ if ( ft_isdigit( *cur ) || only_immediates ) { FT_Int charcode; if ( only_immediates ) charcode = n; else { charcode = (FT_Int)T1_ToInt( parser ); T1_Skip_Spaces( parser ); } cur = parser->root.cursor; if ( *cur == '/' && cur + 2 < limit && n < count ) { FT_PtrDist len; cur++; parser->root.cursor = cur; T1_Skip_PS_Token( parser ); if ( parser->root.error ) return; len = parser->root.cursor - cur; parser->root.error = T1_Add_Table( char_table, charcode, cur, len + 1 ); if ( parser->root.error ) return; char_table->elements[charcode][len] = '\0'; n++; } } else T1_Skip_PS_Token( parser ); T1_Skip_Spaces( parser ); } face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY; parser->root.cursor = cur; } /* Otherwise, we should have either `StandardEncoding', */ /* `ExpertEncoding', or `ISOLatin1Encoding' */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -