📄 t1load.c
字号:
#include <ftconfig.h>#include <ftdebug.h>#include <t1types.h>#include <t1tokens.h>#include <t1parse.h>#include <stdio.h>#undef FT_COMPONENT#define FT_COMPONENT trace_t1load typedef T1_Error (*T1_Parse_Func)( T1_Parser* parser );/*************************************************************************//* *//* <Function> Init_T1_Parser *//* *//* <Description> *//* Initialise a given parser object to build a given T1_Face *//* *//* <Input> *//* parser :: handle to the newly built parser object *//* face :: handle to target T1 face object *//* */ LOCAL_FUNC void Init_T1_Parser( T1_Parser* parser, T1_Face face, T1_Tokenizer tokenizer ) { parser->error = 0; parser->face = face; parser->tokenizer = tokenizer; parser->top = parser->stack; parser->limit = parser->stack + T1_MAX_STACK_DEPTH; parser->state_index = 0; parser->state_stack[0] = dict_none; parser->encoding_type = t1_encoding_none; parser->encoding_names = 0; parser->encoding_offsets = 0; parser->encoding_lengths = 0; parser->dump_tokens = 0; face->type1.lenIV = 4; /* XXX : is it sure ?? */ }/*************************************************************************//* *//* <Function> Next_T1_Token *//* *//* <Description> *//* grabs the next significant token from a parser's input stream. *//* this function ignores a number of tokens, and translates *//* alternate forms into their common ones.. *//* *//* <Input> *//* parser :: handle to source parser *//* *//* <Output> *//* token :: the extracted token descriptor *//* *//* <Return> *//* Error code. 0 means success *//* */ LOCAL_FUNC T1_Error Next_T1_Token( T1_Parser* parser, T1_Token* token ) { T1_Error error; T1_Tokenizer tokzer = parser->tokenizer; L1: error = Read_Token( tokzer ); if (error) return error; /* We now must ignore a number of tokens like "dup", "executeonly", */ /* "readonly", etc... */ *token = tokzer->token; if ( token->kind == tok_keyword ) switch( token->kind2 ) { case key_dup: case key_execonly: case key_readonly: case key_noaccess: case key_userdict: /* do nothing - loop */ goto L1; /* We also translate some other keywords from their alternative */ /* to their "normal" form.. */ case key_NP_alternate: token->kind2 = key_NP; break; case key_RD_alternate: token->kind2 = key_RD; break; case key_ND_alternate: token->kind2 = key_ND; break; default: ; } /* Dump the token when requested. This feature is only available */ /* in the 'error' and 'trace' debug levels.. */#if defined( FT_DEBUG_LEVEL_ERROR ) || defined( FT_DEBUG_LEVEL_TRACE ) if ( parser->dump_tokens ) { T1_String temp_string[128]; T1_Int len; len = token->len; if ( len > 127 ) len = 127; strncpy( temp_string, (T1_String*)tokzer->base + token->start, len ); temp_string[len] = '\0'; FT_ERROR(( "%s\n", temp_string )); }#endif return T1_Err_Ok; } static T1_Error Expect_Keyword( T1_Parser* parser, T1_TokenType keyword ) { T1_Token token; T1_Error error; error = Next_T1_Token( parser, &token ); if (error) goto Exit; if ( token.kind != tok_keyword || token.kind2 != keyword ) { error = T1_Err_Syntax_Error; FT_ERROR(( "T1.Parse: keyword '%s' expected.\n", t1_keywords[ keyword - key_first_ ] )); } Exit: return error; } static T1_Error Expect_Keyword2( T1_Parser* parser, T1_TokenType keyword1, T1_TokenType keyword2 ) { T1_Token token; T1_Error error; error = Next_T1_Token( parser, &token ); if (error) goto Exit; if ( token.kind != tok_keyword || ( token.kind2 != keyword1 && token.kind2 != keyword2 ) ) { error = T1_Err_Syntax_Error; FT_ERROR(( "T1.Parse: keyword '%s' or '%s' expected.\n", t1_keywords[ keyword1 - key_first_ ], t1_keywords[ keyword2 - key_first_ ] )); } Exit: return error; } static void Parse_Encoding( T1_Parser* parser ) { T1_Token* token = parser->top+1; FT_Memory memory = parser->face->root.memory; T1_Encoding* encode = &parser->face->type1.encoding; T1_Error error = 0; if (token->kind == tok_keyword && (token->kind2 == key_StandardEncoding || token->kind2 == key_ExpertEncoding ) ) { encode->num_chars = 256; encode->code_first = 32; encode->code_last = 255; if ( ALLOC_ARRAY( encode->char_index, 256, T1_Short ) ) goto Exit; encode->char_name = 0; /* no need to store glyph names */ /* Now copy the encoding */ switch (token->kind2) { case key_ExpertEncoding : parser->encoding_type = t1_encoding_expert; default : parser->encoding_type = t1_encoding_standard; break; } } else { FT_ERROR(( "T1.Parse_Encoding: invalid encoding type\n" )); error = T1_Err_Syntax_Error; } Exit: parser->error = error; } /**********************************************************************/ /* */ /* */ /* IMPLEMENTATION OF THE "DEF" KEYWORD DEPENDING ON */ /* CURRENT DICTIONARY STATE */ /* */ /* */ /**********************************************************************//**************************************************************************//* *//* <Function> Do_Def_Font *//* *//* <Description> *//* This function performs a 'def' when in the Font dictionary *//* Its purpose is to build the T1_Face attributes directly from *//* the stream.. *//* *//* <Input> *//* parser :: handle to current parser. *//* *//* <Return> *//* Error code. 0 means success *//* */ static T1_Error Do_Def_Font( T1_Parser* parser ) { T1_Token* top = parser->top; T1_Face face = parser->face; T1_Font* type1 = &face->type1; switch ( top[0].kind2 ) { case imm_FontName: /* in some cases, the /FontName is an immediate like */ /* /TimesNewRoman. In this case, we simply copy the */ /* token string (without the /).. */ if (top[1].kind == tok_immediate) { FT_Memory memory = parser->tokenizer->memory; T1_Error error; T1_Int len = top[1].len; if ( ALLOC( type1->font_name, len+1 ) ) { parser->error = error; return error; } MEM_Copy( type1->font_name, parser->tokenizer->base + top[1].start, len ); type1->font_name[len] = '\0'; } else type1->font_name = CopyString( parser ); break; case imm_Encoding: Parse_Encoding( parser ); break; case imm_PaintType: type1->paint_type = (T1_Byte)CopyInteger( parser ); break; case imm_FontType: type1->font_type = (T1_Byte)CopyInteger( parser ); break; case imm_FontMatrix: CopyMatrix( parser, &type1->font_matrix ); break; case imm_FontBBox: CopyBBox( parser, &type1->font_bbox ); break; case imm_UniqueID: type1->unique_id = CopyInteger( parser ); break; case imm_StrokeWidth: type1->stroke_width = CopyInteger( parser ); break; case imm_FontID: type1->font_id = CopyInteger( parser ); break; default: /* ignore all other things */ parser->error = T1_Err_Ok; } return parser->error; }/**************************************************************************//* *//* <Function> Do_Def_FontInfo *//* *//* <Description> *//* This function performs a 'def' when in the FontInfo dictionary *//* Its purpose is to build the T1_FontInfo structure directly from *//* the stream.. *//* *//* <Input> *//* parser :: handle to current parser. *//* *//* <Return> *//* Error code. 0 means success *//* */ static T1_Error Do_Def_FontInfo( T1_Parser* parser ) { T1_Token* top = parser->top; T1_Font* info = &parser->face->type1; switch ( top[0].kind2 ) { case imm_version: info->version = CopyString( parser ); break; case imm_Notice: info->notice = CopyString( parser ); break; case imm_FullName: info->full_name = CopyString( parser ); break; case imm_FamilyName: info->family_name = CopyString( parser ); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -