📄 t1load.c
字号:
static void parse_blend_design_positions( T1_Face face, T1_Loader loader ) { T1_TokenRec design_tokens[ T1_MAX_MM_DESIGNS ]; FT_Int num_designs; FT_Int num_axis; T1_Parser parser = &loader->parser; FT_Error error = 0; PS_Blend blend; /* get the array of design tokens - compute number of designs */ T1_ToTokenArray( parser, design_tokens, T1_MAX_MM_DESIGNS, &num_designs ); if ( num_designs <= 0 || num_designs > T1_MAX_MM_DESIGNS ) { FT_ERROR(( "parse_blend_design_positions:" )); FT_ERROR(( " incorrect number of designs: %d\n", num_designs )); error = T1_Err_Invalid_File_Format; goto Exit; } { FT_Byte* old_cursor = parser->root.cursor; FT_Byte* old_limit = parser->root.limit; FT_UInt n; blend = face->blend; num_axis = 0; /* make compiler happy */ for ( n = 0; n < (FT_UInt)num_designs; n++ ) { T1_TokenRec axis_tokens[ T1_MAX_MM_DESIGNS ]; T1_Token token; FT_Int axis, n_axis; /* read axis/coordinates tokens */ token = design_tokens + n; parser->root.cursor = token->start - 1; parser->root.limit = token->limit + 1; T1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &n_axis ); if ( n == 0 ) { num_axis = n_axis; error = t1_allocate_blend( face, num_designs, num_axis ); if ( error ) goto Exit; blend = face->blend; } else if ( n_axis != num_axis ) { FT_ERROR(( "parse_blend_design_positions: incorrect table\n" )); error = T1_Err_Invalid_File_Format; goto Exit; } /* now, read each axis token into the design position */ for ( axis = 0; axis < n_axis; axis++ ) { T1_Token token2 = axis_tokens + axis; parser->root.cursor = token2->start; parser->root.limit = token2->limit; blend->design_pos[n][axis] = T1_ToFixed( parser, 0 ); } } loader->parser.root.cursor = old_cursor; loader->parser.root.limit = old_limit; } Exit: loader->parser.root.error = error; } static void parse_blend_design_map( T1_Face face, T1_Loader loader ) { FT_Error error = 0; T1_Parser parser = &loader->parser; PS_Blend blend; T1_TokenRec axis_tokens[T1_MAX_MM_AXIS]; FT_Int n, num_axis; FT_Byte* old_cursor; FT_Byte* old_limit; FT_Memory memory = face->root.memory; T1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &num_axis ); if ( num_axis <= 0 || num_axis > T1_MAX_MM_AXIS ) { FT_ERROR(( "parse_blend_design_map: incorrect number of axes: %d\n", num_axis )); error = T1_Err_Invalid_File_Format; goto Exit; } old_cursor = parser->root.cursor; old_limit = parser->root.limit; error = t1_allocate_blend( face, 0, num_axis ); if ( error ) goto Exit; blend = face->blend; /* now, read each axis design map */ for ( n = 0; n < num_axis; n++ ) { PS_DesignMap map = blend->design_map + n; T1_Token token; FT_Int p, num_points; token = axis_tokens + n; parser->root.cursor = token->start; parser->root.limit = token->limit; /* count the number of map points */ { FT_Byte* ptr = token->start; FT_Byte* limit = token->limit; num_points = 0; for ( ; ptr < limit; ptr++ ) if ( ptr[0] == '[' ) num_points++; } if ( num_points <= 0 || num_points > T1_MAX_MM_MAP_POINTS ) { FT_ERROR(( "parse_blend_design_map: incorrect table\n" )); error = T1_Err_Invalid_File_Format; goto Exit; } /* allocate design map data */ if ( FT_NEW_ARRAY( map->design_points, num_points * 2 ) ) goto Exit; map->blend_points = map->design_points + num_points; map->num_points = (FT_Byte)num_points; for ( p = 0; p < num_points; p++ ) { map->design_points[p] = T1_ToInt( parser ); map->blend_points [p] = T1_ToFixed( parser, 0 ); } } parser->root.cursor = old_cursor; parser->root.limit = old_limit; Exit: parser->root.error = error; } static void parse_weight_vector( T1_Face face, T1_Loader loader ) { FT_Error error = 0; T1_Parser parser = &loader->parser; PS_Blend blend = face->blend; T1_TokenRec master; FT_UInt n; FT_Byte* old_cursor; FT_Byte* old_limit; if ( !blend || blend->num_designs == 0 ) { FT_ERROR(( "parse_weight_vector: too early!\n" )); error = T1_Err_Invalid_File_Format; goto Exit; } T1_ToToken( parser, &master ); if ( master.type != T1_TOKEN_TYPE_ARRAY ) { FT_ERROR(( "parse_weight_vector: incorrect format!\n" )); error = T1_Err_Invalid_File_Format; goto Exit; } old_cursor = parser->root.cursor; old_limit = parser->root.limit; parser->root.cursor = master.start; parser->root.limit = master.limit; for ( n = 0; n < blend->num_designs; n++ ) { 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; } /* the keyword `/shareddict' appears in some multiple master fonts */ /* with a lot of Postscript garbage behind it (that's completely out */ /* of spec!); we detect it and terminate the parsing */ /* */ static void parse_shared_dict( T1_Face face, T1_Loader loader ) { T1_Parser parser = &loader->parser; FT_UNUSED( face ); parser->root.cursor = parser->root.limit; parser->root.error = 0; }#endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */ /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** TYPE 1 SYMBOL PARSING *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* First of all, define the token field static variables. This is a set */ /* of T1_FieldRec variables used later. */ /* */ /*************************************************************************/ 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; 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 int is_space( FT_Byte c ) { return ( c == ' ' || c == '\t' || c == '\r' || c == '\n' ); } static int is_name_char( FT_Byte c ) { /* Note: PostScript allows any non-delimiting, non-whitespace */ /* in a name (PS Ref Manual, 3rd Ed, p31) */ /* PostScript delimiters include (,),<,>,[,],{,},/ and % */ return ( c != '(' && c != ')' && c != '<' && c != '>' && c != '[' && c != ']' && c != '{' && c != '}' && c != '/' && c != '%' && ! is_space( c ) ); } 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 the following format */ /* */ /* `size' [white*] RD white ....... ND */ /* */ T1_Skip_Spaces( parser ); cur = parser->root.cursor; if ( cur < limit && (FT_Byte)( *cur - '0' ) < 10 ) { *size = T1_ToInt( parser ); T1_Skip_Spaces( parser ); T1_Skip_Alpha ( 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 1; } FT_ERROR(( "read_binary_data: invalid size field\n" )); parser->root.error = T1_Err_Invalid_File_Format; return 0; } /* we will now define the routines used 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; 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -