📄 cffgload.c
字号:
/***************************************************************************//* *//* cffgload.c *//* *//* OpenType Glyph Loader (body). *//* *//* Copyright 1996-2001 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 <ft2build.h>#include FT_INTERNAL_DEBUG_H#include FT_INTERNAL_CALC_H#include FT_INTERNAL_STREAM_H#include FT_INTERNAL_SFNT_H#include FT_OUTLINE_H#include FT_TRUETYPE_TAGS_H#include FT_INTERNAL_POSTSCRIPT_HINTS_H#include "cffobjs.h"#include "cffload.h"#include "cffgload.h"#include "cfferrs.h" /*************************************************************************/ /* */ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ /* messages during execution. */ /* */#undef FT_COMPONENT#define FT_COMPONENT trace_cffgload typedef enum CFF_Operator_ { cff_op_unknown = 0, cff_op_rmoveto, cff_op_hmoveto, cff_op_vmoveto, cff_op_rlineto, cff_op_hlineto, cff_op_vlineto, cff_op_rrcurveto, cff_op_hhcurveto, cff_op_hvcurveto, cff_op_rcurveline, cff_op_rlinecurve, cff_op_vhcurveto, cff_op_vvcurveto, cff_op_flex, cff_op_hflex, cff_op_hflex1, cff_op_flex1, cff_op_endchar, cff_op_hstem, cff_op_vstem, cff_op_hstemhm, cff_op_vstemhm, cff_op_hintmask, cff_op_cntrmask, cff_op_dotsection, /* deprecated, acts as no-op */ cff_op_abs, cff_op_add, cff_op_sub, cff_op_div, cff_op_neg, cff_op_random, cff_op_mul, cff_op_sqrt, cff_op_blend, cff_op_drop, cff_op_exch, cff_op_index, cff_op_roll, cff_op_dup, cff_op_put, cff_op_get, cff_op_store, cff_op_load, cff_op_and, cff_op_or, cff_op_not, cff_op_eq, cff_op_ifelse, cff_op_callsubr, cff_op_callgsubr, cff_op_return, /* do not remove */ cff_op_max } CFF_Operator;#define CFF_COUNT_CHECK_WIDTH 0x80#define CFF_COUNT_EXACT 0x40#define CFF_COUNT_CLEAR_STACK 0x20 static const FT_Byte cff_argument_counts[] = { 0, /* unknown */ 2 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, /* rmoveto */ 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, 0 | CFF_COUNT_CLEAR_STACK, /* rlineto */ 0 | CFF_COUNT_CLEAR_STACK, 0 | CFF_COUNT_CLEAR_STACK, 0 | CFF_COUNT_CLEAR_STACK, /* rrcurveto */ 0 | CFF_COUNT_CLEAR_STACK, 0 | CFF_COUNT_CLEAR_STACK, 0 | CFF_COUNT_CLEAR_STACK, 0 | CFF_COUNT_CLEAR_STACK, 0 | CFF_COUNT_CLEAR_STACK, 0 | CFF_COUNT_CLEAR_STACK, 13, /* flex */ 7, 9, 11, 0 | CFF_COUNT_CHECK_WIDTH, /* endchar */ 2 | CFF_COUNT_CHECK_WIDTH, /* hstem */ 2 | CFF_COUNT_CHECK_WIDTH, 2 | CFF_COUNT_CHECK_WIDTH, 2 | CFF_COUNT_CHECK_WIDTH, 0 | CFF_COUNT_CHECK_WIDTH, /* hintmask */ 0 | CFF_COUNT_CHECK_WIDTH, /* cntrmask */ 0, /* dotsection */ 1, /* abs */ 2, 2, 2, 1, 0, 2, 1, 1, /* blend */ 1, /* drop */ 2, 1, 2, 1, 2, /* put */ 1, 4, 3, 2, /* and */ 2, 1, 2, 4, 1, /* callsubr */ 1, 0 }; /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /********** *********/ /********** *********/ /********** GENERIC CHARSTRING PARSING *********/ /********** *********/ /********** *********/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* <Function> */ /* CFF_Builder_Init */ /* */ /* <Description> */ /* Initializes a given glyph builder. */ /* */ /* <InOut> */ /* builder :: A pointer to the glyph builder to initialize. */ /* */ /* <Input> */ /* face :: The current face object. */ /* */ /* size :: The current size object. */ /* */ /* glyph :: The current glyph object. */ /* */ static void CFF_Builder_Init( CFF_Builder* builder, TT_Face face, CFF_Size size, CFF_GlyphSlot glyph, FT_Bool hinting ) { builder->path_begun = 0; builder->load_points = 1; builder->face = face; builder->glyph = glyph; builder->memory = face->root.memory; if ( glyph ) { FT_GlyphLoader* loader = glyph->root.internal->loader; builder->loader = loader; builder->base = &loader->base.outline; builder->current = &loader->current.outline; FT_GlyphLoader_Rewind( loader ); builder->hints_globals = 0; builder->hints_funcs = 0; if ( hinting && size ) { builder->hints_globals = size->internal; builder->hints_funcs = glyph->root.internal->glyph_hints; } } if ( size ) { builder->scale_x = size->metrics.x_scale; builder->scale_y = size->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; } /*************************************************************************/ /* */ /* <Function> */ /* CFF_Builder_Done */ /* */ /* <Description> */ /* Finalizes a given glyph builder. Its contents can still be used */ /* after the call, but the function saves important information */ /* within the corresponding glyph slot. */ /* */ /* <Input> */ /* builder :: A pointer to the glyph builder to finalize. */ /* */ static void CFF_Builder_Done( CFF_Builder* builder ) { CFF_GlyphSlot glyph = builder->glyph; if ( glyph ) glyph->root.outline = *builder->base; } /*************************************************************************/ /* */ /* <Function> */ /* cff_compute_bias */ /* */ /* <Description> */ /* Computes the bias value in dependence of the number of glyph */ /* subroutines. */ /* */ /* <Input> */ /* num_subrs :: The number of glyph subroutines. */ /* */ /* <Return> */ /* The bias value. */ static FT_Int cff_compute_bias( FT_UInt num_subrs ) { FT_Int result; if ( num_subrs < 1240 ) result = 107; else if ( num_subrs < 33900U ) result = 1131; else result = 32768U; return result; } /*************************************************************************/ /* */ /* <Function> */ /* CFF_Init_Decoder */ /* */ /* <Description> */ /* Initializes a given glyph decoder. */ /* */ /* <InOut> */ /* decoder :: A pointer to the glyph builder to initialize. */ /* */ /* <Input> */ /* face :: The current face object. */ /* */ /* size :: The current size object. */ /* */ /* slot :: The current glyph object. */ /* */ FT_LOCAL_DEF void CFF_Init_Decoder( CFF_Decoder* decoder, TT_Face face, CFF_Size size, CFF_GlyphSlot slot, FT_Bool hinting ) { CFF_Font* cff = (CFF_Font*)face->extra.data; /* clear everything */ MEM_Set( decoder, 0, sizeof ( *decoder ) ); /* initialize builder */ CFF_Builder_Init( &decoder->builder, face, size, slot, hinting ); /* initialize Type2 decoder */ decoder->num_globals = cff->num_global_subrs; decoder->globals = cff->global_subrs; decoder->globals_bias = cff_compute_bias( decoder->num_globals ); } /* this function is used to select the locals subrs array */ FT_LOCAL_DEF void CFF_Prepare_Decoder( CFF_Decoder* decoder, FT_UInt glyph_index ) { CFF_Font* cff = (CFF_Font*)decoder->builder.face->extra.data; CFF_SubFont* sub = &cff->top_font; /* manage CID fonts */ if ( cff->num_subfonts >= 1 ) { FT_Byte fd_index = CFF_Get_FD( &cff->fd_select, glyph_index ); sub = cff->subfonts[fd_index]; } decoder->num_locals = sub->num_local_subrs; decoder->locals = sub->local_subrs; decoder->locals_bias = cff_compute_bias( decoder->num_locals ); decoder->glyph_width = sub->private_dict.default_width; decoder->nominal_width = sub->private_dict.nominal_width; } /* check that there is enough room for `count' more points */ static FT_Error check_points( CFF_Builder* builder, FT_Int count ) { return FT_GlyphLoader_Check_Points( builder->loader, count, 0 ); } /* add a new point, do not check space */ static void add_point( CFF_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 >> 16; point->y = y >> 16; *control = (FT_Byte)( flag ? FT_Curve_Tag_On : FT_Curve_Tag_Cubic ); builder->last = *point; } outline->n_points++; } /* check space for a new on-curve point, then add it */ static FT_Error add_point1( CFF_Builder* builder, FT_Pos x, FT_Pos y ) { FT_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 FT_Error add_contour( CFF_Builder* builder ) { FT_Outline* outline = builder->current; FT_Error error;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -