📄 t1gload.c
字号:
case op_hlineto: /************************************************/ { FT_TRACE4(( " hlineto" )); if ( start_point( builder, x, y ) ) goto Memory_Error; x += top[0]; goto Add_Line; } case op_hmoveto: /************************************************/ { FT_TRACE4(( " hmoveto" )); x += top[0]; break; } case op_hvcurveto: /**********************************************/ { FT_TRACE4(( " hvcurveto" )); if ( start_point( builder, x, y ) || check_points( builder, 3 ) ) goto Memory_Error; x += top[0]; add_point( builder, x, y, 0 ); x += top[1]; y += top[2]; add_point( builder, x, y, 0 ); y += top[3]; add_point( builder, x, y, 1 ); break; } case op_rlineto: /*************************************************/ { FT_TRACE4(( " rlineto" )); if ( start_point( builder, x, y ) ) goto Memory_Error; x += top[0]; y += top[1]; Add_Line: if (add_point1( builder, x, y )) goto Memory_Error; break; } case op_rmoveto: /*************************************************/ { FT_TRACE4(( " rmoveto" )); x += top[0]; y += top[1]; break; } case op_rrcurveto: /***********************************************/ { FT_TRACE4(( " rcurveto" )); if ( start_point( builder, x, y ) || check_points( builder, 3 ) ) goto Memory_Error; x += top[0]; y += top[1]; add_point( builder, x, y, 0 ); x += top[2]; y += top[3]; add_point( builder, x, y, 0 ); x += top[4]; y += top[5]; add_point( builder, x, y, 1 ); break; } case op_vhcurveto: /**********************************************/ { FT_TRACE4(( " vhcurveto" )); if ( start_point( builder, x, y ) || check_points( builder, 3 ) ) goto Memory_Error; y += top[0]; add_point( builder, x, y, 0 ); x += top[1]; y += top[2]; add_point( builder, x, y, 0 ); x += top[3]; add_point( builder, x, y, 1 ); break; } case op_vlineto: /************************************************/ { FT_TRACE4(( " vlineto" )); if ( start_point( builder, x, y ) ) goto Memory_Error; y += top[0]; goto Add_Line; } case op_vmoveto: /************************************************/ { FT_TRACE4(( " vmoveto" )); y += top[0]; break; } case op_div: /****************************************************/ { FT_TRACE4(( " div" )); if (top[1]) *top++ = top[0] / top[1]; else { FT_ERROR(( "T1.Parse_CharStrings : division by 0\n" )); goto Syntax_Error; } break; } case op_callsubr: /***********************************************/ { T1_Int index; FT_TRACE4(( " callsubr" )); index = top[0]; if ( index < 0 || index >= num_subrs ) { FT_ERROR(( "T1.Parse_CharStrings : invalid subrs index\n" )); goto Syntax_Error; } if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS ) { FT_ERROR(( "T1.Parse_CharStrings : too many nested subrs\n" )); goto Syntax_Error; } zone->cursor = ip; /* save current instruction pointer */ zone++; zone->base = subrs_base[index]; zone->limit = zone->base + subrs_len[index]; zone->cursor = zone->base; if (!zone->base) { FT_ERROR(( "T1.Parse_CharStrings : invoking empty subrs !!\n" )); goto Syntax_Error; } decoder->zone = zone; ip = zone->base; limit = zone->limit; break; } case op_pop: /****************************************************/ { FT_TRACE4(( " pop" )); FT_ERROR(( "T1.Parse_CharStrings : unexpected POP\n" )); goto Syntax_Error; } case op_return: /************************************************/ { FT_TRACE4(( " return" )); if ( zone <= decoder->zones ) { FT_ERROR(( "T1.Parse_CharStrings : unexpected return\n" )); goto Syntax_Error; } zone--; ip = zone->cursor; limit = zone->limit; decoder->zone = zone; break; } case op_dotsection: /*********************************************/ { FT_TRACE4(( " dotsection" )); break; } case op_hstem: /**************************************************/ { FT_TRACE4(( " hstem" )); break; } case op_hstem3: /*************************************************/ { FT_TRACE4(( " hstem3" )); break; } case op_vstem: /**************************************************/ { FT_TRACE4(( " vstem" )); break; } case op_vstem3: /*************************************************/ { FT_TRACE4(( " vstem3" )); break; } case op_setcurrentpoint: /*****************************************/ { FT_TRACE4(( " setcurrentpoint" )); FT_ERROR(( "T1.Parse_CharStrings : unexpected SETCURRENTPOINT\n" )); goto Syntax_Error; } default: FT_ERROR(( "T1.Parse_CharStrings : unhandled opcode %d\n", op )); goto Syntax_Error; } decoder->top = top; } /* general operator processing */ } /* while ip < limit */ FT_TRACE4(( "..end..\n\n" )); return error; Syntax_Error: return T1_Err_Syntax_Error; Stack_Underflow: return T1_Err_Stack_Underflow; Memory_Error: return builder->error; } /**********************************************************************/ /**********************************************************************/ /**********************************************************************/ /********** *********/ /********** *********/ /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ /********** *********/ /********** The following code is in charge of computing *********/ /********** the maximum advance width of the font. It *********/ /********** quickly process each glyph charstring to *********/ /********** extract the value from either a "sbw" or "seac" *********/ /********** operator. *********/ /********** *********/ /**********************************************************************/ /**********************************************************************/ /**********************************************************************/ LOCAL_FUNC T1_Error T1_Compute_Max_Advance( T1_Face face, T1_Int *max_advance ) { T1_Error error; T1_Decoder decoder; T1_Int glyph_index; T1_Font* type1 = &face->type1; *max_advance = 0; /* Initialise load decoder */ T1_Init_Decoder( &decoder ); T1_Init_Builder( &decoder.builder, face, 0, 0 ); decoder.builder.metrics_only = 1; decoder.builder.load_points = 0; /* For each glyph, parse the glyph charstring and extract */ /* the advance width.. */ for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ ) { /* now get load the unscaled outline */ error = T1_Parse_CharStrings( &decoder, type1->charstrings [glyph_index], type1->charstrings_len[glyph_index], type1->num_subrs, type1->subrs, type1->subrs_len ); /* ignore the error if one occured - skip to next glyph */ (void)error; } *max_advance = decoder.builder.advance.x; return T1_Err_Ok; } /**********************************************************************/ /**********************************************************************/ /**********************************************************************/ /********** *********/ /********** *********/ /********** UNHINTED GLYPH LOADER *********/ /********** *********/ /********** The following code is in charge of loading a *********/ /********** single outline. It completely ignores hinting *********/ /********** and is used when FT_LOAD_NO_HINTING is set. *********/ /********** *********/ /**********************************************************************/ /**********************************************************************/ /**********************************************************************/ LOCAL_FUNC T1_Error T1_Load_Glyph( T1_GlyphSlot glyph, T1_Size size, T1_Int glyph_index, T1_Int load_flags ) { T1_Error error; T1_Decoder decoder; T1_Face face = (T1_Face)glyph->root.face; T1_Bool hinting; T1_Font* type1 = &face->type1; glyph->x_scale = size->root.metrics.x_scale; glyph->y_scale = size->root.metrics.y_scale; glyph->root.outline.n_points = 0; glyph->root.outline.n_contours = 0; hinting = ( load_flags & FT_LOAD_NO_SCALE ) == 0 && ( load_flags & FT_LOAD_NO_HINTING ) == 0; glyph->root.format = ft_glyph_format_none; { T1_Init_Decoder( &decoder ); T1_Init_Builder( &decoder.builder, face, size, glyph ); /* now load the unscaled outline */ error = T1_Parse_CharStrings( &decoder, type1->charstrings [glyph_index], type1->charstrings_len[glyph_index], type1->num_subrs, type1->subrs, type1->subrs_len ); /* save new glyph tables */ T1_Done_Builder( &decoder.builder ); } /* Now, set the metrics.. - this is rather simple, as : */ /* the left side bearing is the xMin, and the top side */ /* bearing the yMax.. */ if (!error) { FT_BBox cbox; FT_Glyph_Metrics* metrics = &glyph->root.metrics; FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); /* grid fit the bounding box if necessary */ if (hinting) { cbox.xMin &= -64; cbox.yMin &= -64; cbox.xMax = ( cbox.xMax+63 ) & -64; cbox.yMax = ( cbox.yMax+63 ) & -64; } metrics->width = cbox.xMax - cbox.xMin; metrics->height = cbox.yMax - cbox.yMin; metrics->horiBearingX = cbox.xMin; metrics->horiBearingY = cbox.yMax; /* copy the _unscaled_ advance width */ metrics->horiAdvance = decoder.builder.advance.x; /* make up vertical metrics */ metrics->vertBearingX = 0; metrics->vertBearingY = 0; metrics->vertAdvance = 0; glyph->root.format = ft_glyph_format_outline; glyph->root.outline.flags &= ft_outline_owner; if ( size->root.metrics.y_ppem < 24 ) glyph->root.outline.flags |= ft_outline_high_precision; /* glyph->root.outline.second_pass = TRUE; glyph->root.outline.high_precision = ( size->root.metrics.y_ppem < 24 ); glyph->root.outline.dropout_mode = 2; */ if ( (load_flags & FT_LOAD_NO_SCALE) == 0 ) { /* scale the outline and the metrics */ T1_Int n; FT_Outline* cur = &decoder.builder.base; T1_Vector* vec = cur->points; T1_Fixed x_scale = glyph->x_scale; T1_Fixed y_scale = glyph->y_scale; /* First of all, scale the points */ for ( n = cur->n_points; n > 0; n--, vec++ ) { vec->x = FT_MulFix( vec->x, x_scale ); vec->y = FT_MulFix( vec->y, y_scale ); } /* Then scale the metrics */ metrics->width = FT_MulFix( metrics->width, x_scale ); metrics->height = FT_MulFix( metrics->height, y_scale ); metrics->horiBearingX = FT_MulFix( metrics->horiBearingX, x_scale ); metrics->horiBearingY = FT_MulFix( metrics->horiBearingY, y_scale ); metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale ); metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, x_scale ); } } return error; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -