📄 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>#undef FT_COMPONENT#define FT_COMPONENT trace_t1gload typedef enum T1_Operator_ { op_none = 0, op_endchar, op_hsbw, op_seac, op_sbw, op_closepath, op_hlineto, op_hmoveto, op_hvcurveto, op_rlineto, op_rmoveto, op_rrcurveto, op_vhcurveto, op_vlineto, op_vmoveto, op_dotsection, op_hstem, op_hstem3, op_vstem, op_vstem3, op_div, op_callothersubr, op_callsubr, op_pop, op_return, op_setcurrentpoint, op_max /* never remove this one */ } T1_Operator; static const T1_Int t1_args_count[ op_max ] = { 0, /* none */ 0, /* endchar */ 2, /* hsbw */ 5, /* seac */ 4, /* sbw */ 0, /* closepath */ 1, /* hlineto */ 1, /* hmoveto */ 4, /* hvcurveto */ 2, /* rlineto */ 2, /* rmoveto */ 6, /* rrcurveto */ 4, /* vhcurveto */ 1, /* vlineto */ 1, /* vmoveto */ 0, /* dotsection */ 2, /* hstem */ 6, /* hstem3 */ 2, /* vstem */ 6, /* vstem3 */ 2, /* div */ -1, /* callothersubr */ 1, /* callsubr */ 0, /* pop */ 0, /* return */ 2 /* setcurrentpoint */ }; /**********************************************************************/ /**********************************************************************/ /**********************************************************************/ /********** *********/ /********** *********/ /********** 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 * *********************************************************************/ LOCAL_FUNC void T1_Init_Builder( T1_Builder* builder, T1_Face face, T1_Size size, T1_GlyphSlot glyph ) { builder->path_begun = 0; builder->load_points = 1; builder->face = face; 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; }/********************************************************************* * * <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 * *********************************************************************/ LOCAL_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 ) { 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) ); } /* check that there is enough room for "count" more points */ static T1_Error check_points( T1_Builder* builder, T1_Int count ) { FT_Outline* base = &builder->base; FT_Outline* outline = &builder->current; if (!builder->load_points) return T1_Err_Ok; count += base->n_points + outline->n_points; /* realloc points table if necessary */ if ( count >= builder->max_points ) { T1_Error error; FT_Memory memory = builder->memory; T1_Int increment = outline->points - base->points; T1_Int current = builder->max_points; while ( builder->max_points < count ) builder->max_points += 8; if ( REALLOC_ARRAY( base->points, current, builder->max_points, T1_Vector ) || REALLOC_ARRAY( base->tags, current, builder->max_points, T1_Byte ) ) { builder->error = error; return error; } outline->points = base->points + increment; outline->tags = base->tags + increment; } return T1_Err_Ok; } /* add a new point, do not check room */ static void add_point( T1_Builder* builder, FT_Pos x, FT_Pos y, FT_Byte flag ) { FT_Outline* outline = &builder->current; if (builder->load_points) { FT_Vector* point = outline->points + outline->n_points; FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; point->x = x; point->y = y; *control = ( flag ? FT_Curve_Tag_On : FT_Curve_Tag_Cubic ); builder->last = *point; } outline->n_points++; } /* check room for a new on-curve point, then add it */ static T1_Error add_point1( T1_Builder* builder, FT_Pos x, FT_Pos y ) { T1_Error error; error = check_points(builder,1); if (!error) add_point( builder, x, y, 1 ); return error; } /* check room for a new contour, then add it */ static T1_Error add_contour( T1_Builder* builder ) { FT_Outline* base = &builder->base; FT_Outline* outline = &builder->current; if (!builder->load_points) { outline->n_contours++; return T1_Err_Ok; } /* realloc contours array if necessary */ if ( base->n_contours + outline->n_contours >= builder->max_contours && builder->load_points ) { T1_Error error; FT_Memory memory = builder->memory; T1_Int increment = outline->contours - base->contours; T1_Int current = builder->max_contours; builder->max_contours += 4; if ( REALLOC_ARRAY( base->contours, current, builder->max_contours, T1_Short ) ) { builder->error = error; return error; } outline->contours = base->contours + increment; } if (outline->n_contours > 0) outline->contours[ outline->n_contours-1 ] = outline->n_points-1; outline->n_contours++; return T1_Err_Ok; } /* if a path was begun, add its first on-curve point */ static T1_Error start_point( T1_Builder* builder, T1_Pos x, T1_Pos y ) { /* test wether we're building a new contour */ if (!builder->path_begun) { T1_Error error; builder->path_begun = 1; error = add_contour( builder ); if (error) return error; } return add_point1( builder, x, y ); } /* close the current contour */ static void close_contour( T1_Builder* builder ) { FT_Outline* outline = &builder->current; if ( outline->n_contours > 0 ) outline->contours[outline->n_contours-1] = outline->n_points-1; }/********************************************************************* * * <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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -