📄 t1load.c
字号:
/* we added a glyph. */ loader->num_glyphs = n + 1; } return; Fail: parser->root.error = error; } /*************************************************************************/ /* */ /* Define the token field static variables. This is a set of */ /* T1_FieldRec variables. */ /* */ /*************************************************************************/ static const T1_FieldRec t1_keywords[] = {#include "t1tokens.h" /* now add the special functions... */ T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix, T1_FIELD_DICT_FONTDICT ) T1_FIELD_CALLBACK( "Encoding", parse_encoding, T1_FIELD_DICT_FONTDICT ) T1_FIELD_CALLBACK( "Subrs", parse_subrs, T1_FIELD_DICT_PRIVATE ) T1_FIELD_CALLBACK( "CharStrings", parse_charstrings, T1_FIELD_DICT_PRIVATE ) T1_FIELD_CALLBACK( "Private", parse_private, T1_FIELD_DICT_FONTDICT )#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT T1_FIELD_CALLBACK( "BlendDesignPositions", parse_blend_design_positions, T1_FIELD_DICT_FONTDICT ) T1_FIELD_CALLBACK( "BlendDesignMap", parse_blend_design_map, T1_FIELD_DICT_FONTDICT ) T1_FIELD_CALLBACK( "BlendAxisTypes", parse_blend_axis_types, T1_FIELD_DICT_FONTDICT ) T1_FIELD_CALLBACK( "WeightVector", parse_weight_vector, T1_FIELD_DICT_FONTDICT ) T1_FIELD_CALLBACK( "BuildCharArray", parse_buildchar, T1_FIELD_DICT_PRIVATE )#endif { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 } };#define T1_FIELD_COUNT \ ( sizeof ( t1_keywords ) / sizeof ( t1_keywords[0] ) ) static FT_Error parse_dict( T1_Face face, T1_Loader loader, FT_Byte* base, FT_Long size ) { T1_Parser parser = &loader->parser; FT_Byte *limit, *start_binary = NULL; FT_Bool have_integer = 0; parser->root.cursor = base; parser->root.limit = base + size; parser->root.error = T1_Err_Ok; limit = parser->root.limit; T1_Skip_Spaces( parser ); while ( parser->root.cursor < limit ) { FT_Byte* cur; cur = parser->root.cursor; /* look for `eexec' */ if ( IS_PS_TOKEN( cur, limit, "eexec" ) ) break; /* look for `closefile' which ends the eexec section */ else if ( IS_PS_TOKEN( cur, limit, "closefile" ) ) break; /* in a synthetic font the base font starts after a */ /* `FontDictionary' token that is placed after a Private dict */ else if ( IS_PS_TOKEN( cur, limit, "FontDirectory" ) ) { if ( loader->keywords_encountered & T1_PRIVATE ) loader->keywords_encountered |= T1_FONTDIR_AFTER_PRIVATE; parser->root.cursor += 13; } /* check whether we have an integer */ else if ( ft_isdigit( *cur ) ) { start_binary = cur; T1_Skip_PS_Token( parser ); if ( parser->root.error ) goto Exit; have_integer = 1; } /* in valid Type 1 fonts we don't see `RD' or `-|' directly */ /* since those tokens are handled by parse_subrs and */ /* parse_charstrings */ else if ( *cur == 'R' && cur + 6 < limit && *(cur + 1) == 'D' && have_integer ) { FT_Long s; FT_Byte* b; parser->root.cursor = start_binary; if ( !read_binary_data( parser, &s, &b ) ) return T1_Err_Invalid_File_Format; have_integer = 0; } else if ( *cur == '-' && cur + 6 < limit && *(cur + 1) == '|' && have_integer ) { FT_Long s; FT_Byte* b; parser->root.cursor = start_binary; if ( !read_binary_data( parser, &s, &b ) ) return T1_Err_Invalid_File_Format; have_integer = 0; } /* look for immediates */ else if ( *cur == '/' && cur + 2 < limit ) { FT_PtrDist len; cur++; parser->root.cursor = cur; T1_Skip_PS_Token( parser ); if ( parser->root.error ) goto Exit; len = parser->root.cursor - cur; if ( len > 0 && len < 22 && parser->root.cursor < limit ) { /* 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_PtrDist)ft_strlen( (const char *)name ) && ft_memcmp( cur, name, len ) == 0 ) { /* We found it -- run the parsing callback! */ /* We record every instance of every field */ /* (until we reach the base font of a */ /* synthetic font) to deal adequately with */ /* multiple master fonts; this is also */ /* necessary because later PostScript */ /* definitions override earlier ones. */ /* Once we encounter `FontDirectory' after */ /* `/Private', we know that this is a synthetic */ /* font; except for `/CharStrings' we are not */ /* interested in anything that follows this */ /* `FontDirectory'. */ /* MM fonts have more than one /Private token at */ /* the top level; let's hope that all the junk */ /* that follows the first /Private token is not */ /* interesting to us. */ /* According to Adobe Tech Note #5175 (CID-Keyed */ /* Font Installation for ATM Software) a `begin' */ /* must be followed by exactly one `end', and */ /* `begin' -- `end' pairs must be accurately */ /* paired. We could use this to distinguish */ /* between the global Private and the Private */ /* dict that is a member of the Blend dict. */ const FT_UInt dict = ( loader->keywords_encountered & T1_PRIVATE ) ? T1_FIELD_DICT_PRIVATE : T1_FIELD_DICT_FONTDICT; if ( !( dict & keyword->dict ) ) { FT_TRACE1(( "parse_dict: found %s but ignoring it " "since it is in the wrong dictionary\n", keyword->ident )); break; } if ( !( loader->keywords_encountered & T1_FONTDIR_AFTER_PRIVATE ) || ft_strcmp( (const char*)name, "CharStrings" ) == 0 ) { parser->root.error = t1_load_keyword( face, loader, keyword ); if ( parser->root.error != T1_Err_Ok ) { if ( FT_ERROR_BASE( parser->root.error ) == FT_Err_Ignore ) parser->root.error = T1_Err_Ok; else return parser->root.error; } } break; } keyword++; } } have_integer = 0; } else { T1_Skip_PS_Token( parser ); if ( parser->root.error ) goto Exit; have_integer = 0; } T1_Skip_Spaces( parser ); } Exit: return parser->root.error; } static void t1_init_loader( T1_Loader loader, T1_Face face ) { FT_UNUSED( face ); FT_MEM_ZERO( loader, 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; loader->keywords_encountered = 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; PS_Private priv = &type1->private_dict; FT_Error error; PSAux_Service psaux = (PSAux_Service)face->psaux; t1_init_loader( &loader, face ); /* default values */ face->ndv_idx = -1; face->cdv_idx = -1; face->len_buildchar = 0; priv->blue_shift = 7; priv->blue_fuzz = 1; priv->lenIV = 4; priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); 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; /* ensure even-ness of `num_blue_values' */ priv->num_blue_values &= ~1;#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT if ( face->blend && face->blend->num_default_design_vector != 0 && face->blend->num_default_design_vector != face->blend->num_axis ) { /* we don't use it currently so just warn, reset, and ignore */ FT_ERROR(( "T1_Open_Face(): /DesignVector contains %u entries " "while there are %u axes.\n", face->blend->num_default_design_vector, face->blend->num_axis )); face->blend->num_default_design_vector = 0; } /* the following can happen for MM instances; we then treat the */ /* font as a normal PS font */ if ( face->blend && ( !face->blend->num_designs || !face->blend->num_axis ) ) T1_Done_Blend( face ); /* another safety check */ if ( face->blend ) { FT_UInt i; for ( i = 0; i < face->blend->num_axis; i++ ) if ( !face->blend->design_map[i].num_points ) { T1_Done_Blend( face ); break; } } if ( face->blend ) { if ( face->len_buildchar > 0 ) { FT_Memory memory = face->root.memory; if ( FT_NEW_ARRAY( face->buildchar, face->len_buildchar ) ) { FT_ERROR(( "T1_Open_Face: cannot allocate BuildCharArray\n" )); face->len_buildchar = 0; goto Exit; } } }#endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */ /* 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; }#ifdef FT_CONFIG_OPTION_INCREMENTAL if ( !face->root.internal->incremental_interface )#endif if ( !loader.charstrings.init ) { FT_ERROR(( "T1_Open_Face: no `/CharStrings' array in face!\n" ));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -