📄 t1gload.c
字号:
/******************************************************************* * * t1gload.c 1.0 * * Type1 Glyph Loader. * * Copyright 1996-1999 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used * modified and distributed under the terms of the FreeType project * license, LICENSE.TXT. By continuing to use, modify, or distribute * this file you indicate that you have read the license and * understand and accept it fully. * ******************************************************************/#include <t1gload.h>#include <ftdebug.h>#include <ftstream.h>#ifndef T1_CONFIG_OPTION_DISABLE_HINTER#include <t1hinter.h>#endif /**********************************************************************/ /**********************************************************************/ /**********************************************************************/ /********** *********/ /********** *********/ /********** GENERIC CHARSTRINGS PARSING *********/ /********** *********/ /********** *********/ /**********************************************************************/ /**********************************************************************/ /**********************************************************************//********************************************************************* * * <Function> * T1_Init_Builder * * <Description> * Initialise a given glyph builder. * * <Input> * builder :: glyph builder to initialise * face :: current face object * size :: current size object * glyph :: current glyph object * funcs :: glyph builder functions (or "methods"). * *********************************************************************/ EXPORT_FUNC void T1_Init_Builder( T1_Builder* builder, T1_Face face, T1_Size size, T1_GlyphSlot glyph, const T1_Builder_Funcs* funcs ) { builder->funcs = *funcs; builder->path_begun = 0; builder->load_points = 1; builder->face = face; builder->size = size; builder->glyph = glyph; builder->memory = face->root.memory; if (glyph) { builder->base = glyph->root.outline; builder->max_points = glyph->max_points; builder->max_contours = glyph->max_contours; } if (size) { builder->scale_x = size->root.metrics.x_scale; builder->scale_y = size->root.metrics.y_scale; } builder->pos_x = 0; builder->pos_y = 0; builder->left_bearing.x = 0; builder->left_bearing.y = 0; builder->advance.x = 0; builder->advance.y = 0; builder->base.n_points = 0; builder->base.n_contours = 0; builder->current = builder->base; builder->pass = 0; builder->hint_point = 0; }/********************************************************************* * * <Function> * T1_Done_Builder * * <Description> * Finalise a given glyph builder. Its content can still be * used after the call, but the function saves important information * within the corresponding glyph slot. * * <Input> * builder :: glyph builder to initialise * *********************************************************************/ EXPORT_FUNC void T1_Done_Builder( T1_Builder* builder ) { T1_GlyphSlot glyph = builder->glyph; if (glyph) { glyph->root.outline = builder->base; glyph->max_points = builder->max_points; glyph->max_contours = builder->max_contours; } }/********************************************************************* * * <Function> * T1_Init_Decoder * * <Description> * Initialise a given Type 1 decoder for parsing * * <Input> * decoder :: Type 1 decoder to initialise * funcs :: hinter functions interface * *********************************************************************/ EXPORT_FUNC void T1_Init_Decoder( T1_Decoder* decoder, const T1_Hinter_Funcs* funcs ) { decoder->hinter = *funcs; /* copy hinter interface */ decoder->top = 0; decoder->zone = 0; decoder->flex_state = 0; decoder->num_flex_vectors = 0; /* Clear loader */ MEM_Set( &decoder->builder, 0, sizeof(decoder->builder) ); }/********************************************************************* * * <Function> * lookup_glyph_by_stdcharcode * * <Description> * Lookup a given glyph by its StandardEncoding charcode. Used * to implement the SEAC Type 1 operator. * * <Input> * face :: current face object * charcode :: charcode to look for * * <Return> * glyph index in font face. Returns -1 if the corresponding * glyph wasn't found. * *********************************************************************/ static T1_Int lookup_glyph_by_stdcharcode( T1_Face face, T1_Int charcode ) { T1_Int n; const T1_String* glyph_name; PSNames_Interface* psnames = (PSNames_Interface*)face->psnames; /* check range of standard char code */ if (charcode < 0 || charcode > 255) return -1; glyph_name = psnames->adobe_std_strings( psnames->adobe_std_encoding[charcode]); for ( n = 0; n < face->type1.num_glyphs; n++ ) { T1_String* name = (T1_String*)face->type1.glyph_names[n]; if ( name && strcmp(name,glyph_name) == 0 ) return n; } return -1; }/********************************************************************* * * <Function> * t1operator_seac * * <Description> * Implements the "seac" Type 1 operator for a Type 1 decoder * * <Input> * decoder :: current Type 1 decoder * asb :: accent's side bearing * adx :: horizontal position of accent * ady :: vertical position of accent * bchar :: base character's StandardEncoding charcode * achar :: accent character's StandardEncoding charcode * * <Return> * Error code. 0 means success. * *********************************************************************/ static T1_Error t1operator_seac( T1_Decoder* decoder, T1_Pos asb, T1_Pos adx, T1_Pos ady, T1_Int bchar, T1_Int achar ) { T1_Error error; T1_Face face = decoder->builder.face; T1_Int bchar_index, achar_index, n_base_points; FT_Outline* cur = &decoder->builder.current; FT_Outline* base = &decoder->builder.base; T1_Vector left_bearing, advance; T1_Font* type1 = &face->type1; bchar_index = lookup_glyph_by_stdcharcode( face, bchar ); achar_index = lookup_glyph_by_stdcharcode( face, achar ); if (bchar_index < 0 || achar_index < 0) { FT_ERROR(( "T1.Parse_Seac : invalid seac character code arguments\n" )); return T1_Err_Syntax_Error; } /* First load "bchar" in builder */ /* now load the unscaled outline */ cur->n_points = 0; cur->n_contours = 0; cur->points = base->points + base->n_points; cur->tags = base->tags + base->n_points; cur->contours = base->contours + base->n_contours; error = T1_Parse_CharStrings( decoder, type1->charstrings [bchar_index], type1->charstrings_len[bchar_index], type1->num_subrs, type1->subrs, type1->subrs_len ); if (error) return error; n_base_points = cur->n_points; /* save the left bearing and width of the base character */ /* as they will be erased by the next load.. */ left_bearing = decoder->builder.left_bearing; advance = decoder->builder.advance; decoder->builder.left_bearing.x = 0; decoder->builder.left_bearing.y = 0; /* Now load "achar" on top of */ /* the base outline */ /* */ cur->n_points = 0; cur->n_contours = 0; cur->points = base->points + base->n_points; cur->tags = base->tags + base->n_points; cur->contours = base->contours + base->n_contours; error = T1_Parse_CharStrings( decoder, type1->charstrings [achar_index], type1->charstrings_len[achar_index], type1->num_subrs, type1->subrs, type1->subrs_len ); if (error) return error; /* adjust contours in accented character outline */ { T1_Int n; for ( n = 0; n < cur->n_contours; n++ ) cur->contours[n] += n_base_points; } /* restore the left side bearing and */ /* advance width of the base character */ decoder->builder.left_bearing = left_bearing; decoder->builder.advance = advance; /* Finally, move the accent */ FT_Outline_Translate( cur, adx - asb, ady ); (void)asb; /* ignore this parameter */ return T1_Err_Ok; }/********************************************************************* * * <Function> * t1operator_flex * * <Description> * Implements the "flex" Type 1 operator for a Type 1 decoder * * <Input> * decoder :: current Type 1 decoder * threshold :: threshold * end_x :: position of final flex point * end_y :: position of final flex point * * <Return> * Error code. 0 means success. * *********************************************************************/ static T1_Error t1operator_flex( T1_Decoder* decoder, T1_Pos threshold, T1_Pos end_x, T1_Pos end_y ) { T1_Vector vec; T1_Vector* flex = decoder->flex_vectors; T1_Int n; /* we don't even try to test the threshold in the non-hinting */ /* builder, even if the flex operator is said to be a path */ /* construction statement in the specification. This is better */ /* left to the hinter.. */ flex = decoder->flex_vectors; vec = *flex++; for ( n = 0; n < 6; n++ ) { flex->x += vec.x; flex->y += vec.y; vec = *flex++; } (void)threshold; (void)end_x; (void)end_y; flex = decoder->flex_vectors; return decoder->builder.funcs.rcurve_to( &decoder->builder, flex[0].x, flex[0].y, flex[1].x, flex[1].y, flex[2].x, flex[2].y ) || decoder->builder.funcs.rcurve_to( &decoder->builder, flex[3].x, flex[3].y, flex[4].x, flex[4].y, flex[5].x, flex[5].y ); }/********************************************************************* * * <Function> * T1_Parse_CharStrings * * <Description> * Parses a given Type 1 charstrings program * * <Input> * decoder :: current Type 1 decoder * charstring_base :: base of the charstring stream * charstring_len :: length in bytes of the charstring stream * num_subrs :: number of sub-routines * subrs_base :: array of sub-routines addresses * subrs_len :: array of sub-routines lengths * * <Return> * Error code. 0 means success. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -