📄 t1load.c
字号:
/**************************************************************************//* *//* <Function> Do_RD_CharStrings *//* *//* <Description> *//* This function performs a 'RD' when in the CharStrings dictionary *//* It simply records the array of bytecodes/charstrings corresponding *//* to the glyph program string. *//* *//* <Input> *//* parser :: handle to current parser. *//* *//* <Return> *//* Error code. 0 means success *//* */ static T1_Error Do_RD_Charstrings( T1_Parser* parser ) { T1_Error error = T1_Err_Ok; T1_Face face = parser->face; T1_Token* top = parser->top; T1_Tokenizer tokzer = parser->tokenizer; T1_Int index, count; /* check the character name argument */ if ( top[0].kind != tok_immediate ) { FT_ERROR(( "T1.Parse.RD: immediate character name expected\n" )); goto Syntax_Error; } /* check the count argument */ if ( top[1].kind != tok_number ) { FT_ERROR(( "T1.Parse.put: number expected\n" )); goto Syntax_Error; } parser->args++; count = (T1_Int)CopyInteger( parser ); error = parser->error; if (error) goto Exit; /* record the glyph name and get the corresponding glyph index */ if ( top[0].kind2 == imm_notdef ) index = 0; else { T1_String temp_name[128]; T1_Token* token = top; T1_Int len = token->len-1; /* copy immediate name */ if (len > 127) len = 127; MEM_Copy( temp_name, parser->tokenizer->base + token->start+1, len ); temp_name[len] = '\0'; index = parser->cur_name++; error = T1_Add_Table( &parser->table, index*2, (T1_Byte*)temp_name, len+1 ); if (error) goto Exit; } /* decrypt and record charstring, then skip them */ { T1_Byte* base = tokzer->base + tokzer->cursor; t1_decrypt( base, count, 4330 ); tokzer->cursor += count; /* skip */ base += face->type1.lenIV; count -= face->type1.lenIV; error = T1_Add_Table( &parser->table, index*2+1, base, count ); } /* consume the closing ND */ if (!error) error = Expect_Keyword( parser, key_ND ); Exit: return error; Syntax_Error: return T1_Err_Syntax_Error; } static T1_Error Expect_Dict_Arguments( T1_Parser* parser, T1_Int num_args, T1_TokenType immediate, T1_DictState new_state, T1_Int *count ) { /* check that we have enough arguments in the stack, including */ /* the 'dict' keyword.. */ if ( parser->top - parser->stack < num_args ) { FT_ERROR(( "T1.Parse.Dict : expecting at least %d arguments", num_args )); goto Syntax_Error; } /* check that we have the correct immediate, if needed */ if ( num_args == 2 ) { if ( parser->top[-2].kind != tok_immediate || parser->top[-2].kind2 != immediate ) { FT_ERROR(( "T1.Parse.Dict : expecting '/%s' dictionary\n", t1_immediates[ immediate - imm_first_ ] )); goto Syntax_Error; } } parser->args = parser->top-1; /* check that the count argument is a number */ if ( parser->args->kind != tok_number ) { FT_ERROR(( "T1.Parse.Dict : expecting numerical count argument for 'dict'\n" )); goto Syntax_Error; } if (count) { *count = CopyInteger( parser ); if (parser->error) return parser->error; } /* save the dictionary state */ parser->state_stack[ ++parser->state_index ] = new_state; /* consume the 'begin' keyword, and clear the stack */ parser->top -= num_args; return Expect_Keyword( parser, key_begin ); Syntax_Error: return T1_Err_Syntax_Error; } static T1_Error Expect_Array_Arguments( T1_Parser* parser ) { T1_Token* top = parser->top; T1_Error error = T1_Err_Ok; T1_DictState new_state; T1_Int count; T1_Face face = parser->face; FT_Memory memory = face->root.memory; /* Check arguments format */ if ( top - parser->stack < 2 ) { FT_ERROR(( "T1.Parse.array: two arguments expected\n" )); error = T1_Err_Stack_Underflow; goto Exit; } parser->top -= 2; top -= 2; parser->args = top + 1; if ( top[0].kind != tok_immediate ) { FT_ERROR(( "T1.Parse.array: first argument must be an immediate name\n" )); goto Syntax_Error; } if ( top[1].kind != tok_number ) { FT_ERROR(( "T1.Parse.array: second argument must be a number\n" )); goto Syntax_Error; } count = (T1_Int)CopyInteger( parser ); /* Is this an array we know about ?? */ switch ( top[0].kind2 ) { case imm_Encoding: { T1_Encoding* encode = &face->type1.encoding; new_state = dict_encoding; encode->code_first = count; encode->code_last = 0; encode->num_chars = count; /* allocate the table of character indexes. The table of */ /* character names is allocated through init_t1_recorder */ if ( ALLOC_ARRAY( encode->char_index, count, T1_Short ) ) return error; error = T1_New_Table( &parser->table, count, memory ); if (error) goto Exit; parser->encoding_type = t1_encoding_array; } break; case imm_Subrs: { new_state = dict_subrs; face->type1.num_subrs = count; error = T1_New_Table( &parser->table, count, memory ); if (error) goto Exit; } break; case imm_CharStrings: new_state = dict_charstrings; break; default: new_state = dict_unknown_array; } parser->state_stack[ ++parser->state_index ] = new_state; Exit: return error; Syntax_Error: return T1_Err_Syntax_Error; } static T1_Error Finalise_Parsing( T1_Parser* parser ) { T1_Face face = parser->face; T1_Font* type1 = &face->type1; FT_Memory memory = face->root.memory; T1_Table* strings = &parser->table; PSNames_Interface* psnames = (PSNames_Interface*)face->psnames; T1_Int num_glyphs; T1_Int n; T1_Error error; num_glyphs = type1->num_glyphs = parser->cur_name; /* allocate glyph names and charstrings arrays */ if ( ALLOC_ARRAY( type1->glyph_names , num_glyphs, T1_String* ) || ALLOC_ARRAY( type1->charstrings , num_glyphs, T1_Byte* ) || ALLOC_ARRAY( type1->charstrings_len, num_glyphs, T1_Int* ) ) return error; /* copy glyph names and charstrings offsets and lengths */ type1->charstrings_block = strings->block; for ( n = 0; n < num_glyphs; n++ ) { type1->glyph_names[n] = (T1_String*)strings->elements[2*n]; type1->charstrings[n] = strings->elements[2*n+1]; type1->charstrings_len[n] = strings->lengths [2*n+1]; } /* now free the old tables */ FREE( strings->elements ); FREE( strings->lengths ); if (!psnames) { FT_ERROR(( "T1.Parse.Finalise : PSNames module missing !!\n" )); return T1_Err_Unimplemented_Feature; } /* Compute encoding if required. */ if (parser->encoding_type == t1_encoding_none) { FT_ERROR(( "T1.Parse.Finalise : no encoding specified in font file\n" )); return T1_Err_Syntax_Error; } { T1_Int n; T1_Encoding* encode = &type1->encoding; encode->code_first = encode->num_chars-1; encode->code_last = 0; for ( n = 0; n < encode->num_chars; n++ ) { T1_String** names; T1_Int index; T1_Int m; switch (parser->encoding_type) { case t1_encoding_standard: index = psnames->adobe_std_encoding[n]; names = 0; break; case t1_encoding_expert: index = psnames->adobe_expert_encoding[n]; names = 0; break; default: index = n; names = (T1_String**)parser->encoding_offsets; } encode->char_index[n] = 0; if (index) { T1_String* name; if (names) name = names[index]; else name = (T1_String*)psnames->adobe_std_strings(index); if ( name ) { T1_Int len = strlen(name); /* lookup glyph index from name */ for ( m = 0; m < num_glyphs; m++ ) { if ( strncmp( type1->glyph_names[m], name, len ) == 0 ) { encode->char_index[n] = m; break; } } if ( n < encode->code_first ) encode->code_first = n; if ( n > encode->code_last ) encode->code_last = n; } } } parser->encoding_type = t1_encoding_none; FREE( parser->encoding_names ); FREE( parser->encoding_lengths ); FREE( parser->encoding_offsets ); } return T1_Err_Ok; } LOCAL_FUNC T1_Error Parse_T1_FontProgram( T1_Parser* parser ) { T1_Error error; T1_Font* type1 = &parser->face->type1; for (;;) { T1_Token token; T1_Token* top; T1_DictState dict_state; T1_Int dict_index;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -