📄 ttgload.c
字号:
goto Fail; error = FT_GlyphLoader_CheckPoints( gloader, num_points + 4, 0 ); if ( error ) goto Fail; /* prepare the execution context */ tt_prepare_zone( &exec->pts, &gloader->base, start_point, start_contour ); pts = &exec->pts; pts->n_points = (short)( num_points + 4 ); pts->n_contours = gloader->base.outline.n_contours; /* add phantom points */ pp1 = pts->cur + num_points; pp1[0] = loader->pp1; pp1[1] = loader->pp2; pp1[2] = loader->pp3; pp1[3] = loader->pp4; pts->tags[num_points ] = 0; pts->tags[num_points + 1] = 0; pts->tags[num_points + 2] = 0; pts->tags[num_points + 3] = 0; /* if hinting, round the phantom points */ if ( IS_HINTED( loader->load_flags ) ) { pp1[0].x = FT_PIX_ROUND( loader->pp1.x ); pp1[1].x = FT_PIX_ROUND( loader->pp2.x ); pp1[2].y = FT_PIX_ROUND( loader->pp3.y ); pp1[3].y = FT_PIX_ROUND( loader->pp4.y ); } { FT_UInt k; for ( k = 0; k < num_points; k++ ) pts->tags[k] &= FT_CURVE_TAG_ON; } cur_to_org( num_points + 4, pts ); /* now consider hinting */ if ( IS_HINTED( loader->load_flags ) && n_ins > 0 ) { exec->is_composite = TRUE; error = TT_Run_Context( exec, ((TT_Size)loader->size)->debug ); if ( error && exec->pedantic_hinting ) goto Fail; } /* save glyph origin and advance points */ loader->pp1 = pp1[0]; loader->pp2 = pp1[1]; loader->pp3 = pp1[2]; loader->pp4 = pp1[3]; }#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ } /* end of composite loading */ } else { /* invalid composite count ( negative but not -1 ) */ error = TT_Err_Invalid_Outline; goto Fail; } /***********************************************************************/ /***********************************************************************/ /***********************************************************************/ Fail: if ( opened_frame ) face->forget_glyph_frame( loader ); Exit:#ifdef FT_CONFIG_OPTION_INCREMENTAL if ( glyph_data_loaded ) face->root.internal->incremental_interface->funcs->free_glyph_data( face->root.internal->incremental_interface->object, &glyph_data );#endif return error; } static FT_Error compute_glyph_metrics( TT_Loader loader, FT_UInt glyph_index ) { FT_BBox bbox; TT_Face face = (TT_Face)loader->face; FT_Fixed y_scale; TT_GlyphSlot glyph = loader->glyph; TT_Size size = (TT_Size)loader->size; y_scale = 0x10000L; if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) y_scale = size->root.metrics.y_scale; if ( glyph->format != FT_GLYPH_FORMAT_COMPOSITE ) { glyph->outline.flags &= ~FT_OUTLINE_SINGLE_PASS; /* copy outline to our glyph slot */ FT_GlyphLoader_CopyPoints( glyph->internal->loader, loader->gloader ); glyph->outline = glyph->internal->loader->base.outline; /* translate array so that (0,0) is the glyph's origin */ FT_Outline_Translate( &glyph->outline, -loader->pp1.x, 0 ); FT_Outline_Get_CBox( &glyph->outline, &bbox ); if ( IS_HINTED( loader->load_flags ) ) { /* grid-fit the bounding box */ bbox.xMin = FT_PIX_FLOOR( bbox.xMin ); bbox.yMin = FT_PIX_FLOOR( bbox.yMin ); bbox.xMax = FT_PIX_CEIL( bbox.xMax ); bbox.yMax = FT_PIX_CEIL( bbox.yMax ); } } else bbox = loader->bbox; /* get the device-independent horizontal advance. It is scaled later */ /* by the base layer. */ { FT_Pos advance = loader->linear; /* the flag FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH was introduced to */ /* correctly support DynaLab fonts, which have an incorrect */ /* `advance_Width_Max' field! It is used, to my knowledge, */ /* exclusively in the X-TrueType font server. */ /* */ if ( face->postscript.isFixedPitch && ( loader->load_flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ) == 0 ) advance = face->horizontal.advance_Width_Max; /* we need to return the advance in font units in linearHoriAdvance, */ /* it will be scaled later by the base layer. */ glyph->linearHoriAdvance = advance; } glyph->metrics.horiBearingX = bbox.xMin; glyph->metrics.horiBearingY = bbox.yMax; glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; /* don't forget to hint the advance when we need to */ if ( IS_HINTED( loader->load_flags ) ) glyph->metrics.horiAdvance = FT_PIX_ROUND( glyph->metrics.horiAdvance ); /* Now take care of vertical metrics. In the case where there is */ /* no vertical information within the font (relatively common), make */ /* up some metrics by `hand'... */ { FT_Short top_bearing; /* vertical top side bearing (EM units) */ FT_UShort advance_height; /* vertical advance height (EM units) */ FT_Pos left; /* scaled vertical left side bearing */ FT_Pos top; /* scaled vertical top side bearing */ FT_Pos advance; /* scaled vertical advance height */ /* Get the unscaled top bearing and advance height. */ if ( face->vertical_info && face->vertical.number_Of_VMetrics > 0 ) { advance_height = (FT_UShort)( loader->pp4.y - loader->pp3.y ); top_bearing = (FT_Short)( loader->pp3.y - bbox.yMax ); } else { /* Make up the distances from the horizontal header. */ /* NOTE: The OS/2 values are the only `portable' ones, */ /* which is why we use them, if there is an OS/2 */ /* table in the font. Otherwise, we use the */ /* values defined in the horizontal header. */ /* */ /* NOTE2: The sTypoDescender is negative, which is why */ /* we compute the baseline-to-baseline distance */ /* here with: */ /* ascender - descender + linegap */ /* */ /* NOTE3: This is different from what MS's rasterizer */ /* appears to do when getting default values */ /* for the vertical phantom points. We leave */ /* the old code untouched, but relying on */ /* phantom points alone might be reasonable */ /* (i.e., removing the `if' above). */ if ( face->os2.version != 0xFFFFU ) { top_bearing = (FT_Short)( face->os2.sTypoLineGap / 2 ); advance_height = (FT_UShort)( face->os2.sTypoAscender - face->os2.sTypoDescender + face->os2.sTypoLineGap ); } else { top_bearing = (FT_Short)( face->horizontal.Line_Gap / 2 ); advance_height = (FT_UShort)( face->horizontal.Ascender + face->horizontal.Descender + face->horizontal.Line_Gap ); } }#ifdef FT_CONFIG_OPTION_INCREMENTAL /* If this is an incrementally loaded font see if there are */ /* overriding metrics for this glyph. */ if ( face->root.internal->incremental_interface && face->root.internal->incremental_interface->funcs->get_glyph_metrics ) { FT_Incremental_MetricsRec metrics; FT_Error error = TT_Err_Ok; metrics.bearing_x = 0; metrics.bearing_y = top_bearing; metrics.advance = advance_height; error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( face->root.internal->incremental_interface->object, glyph_index, TRUE, &metrics ); if ( error ) return error; top_bearing = (FT_Short)metrics.bearing_y; advance_height = (FT_UShort)metrics.advance; } /* GWW: Do vertical metrics get loaded incrementally too? */#endif /* FT_CONFIG_OPTION_INCREMENTAL */ /* We must adjust the top_bearing value from the bounding box given */ /* in the glyph header to the bounding box calculated with */ /* FT_Get_Outline_CBox(). */ /* scale the metrics */ if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) ) { top = FT_MulFix( top_bearing + loader->bbox.yMax, y_scale ) - bbox.yMax; advance = FT_MulFix( advance_height, y_scale ); } else { top = top_bearing + loader->bbox.yMax - bbox.yMax; advance = advance_height; } /* set the advance height in design units. It is scaled later by */ /* the base layer. */ glyph->linearVertAdvance = advance_height; /* XXX: for now, we have no better algorithm for the lsb, but it */ /* should work fine. */ /* */ left = ( bbox.xMin - bbox.xMax ) / 2; /* grid-fit them if necessary */ if ( IS_HINTED( loader->load_flags ) ) { left = FT_PIX_FLOOR( left ); top = FT_PIX_CEIL( top ); advance = FT_PIX_ROUND( advance ); } glyph->metrics.vertBearingX = left; glyph->metrics.vertBearingY = top; glyph->metrics.vertAdvance = advance; } /* adjust advance width to the value contained in the hdmx table */ if ( !face->postscript.isFixedPitch && size && IS_HINTED( loader->load_flags ) ) { FT_Byte* widthp = Get_Advance_WidthPtr( face, size->root.metrics.x_ppem, glyph_index ); if ( widthp ) glyph->metrics.horiAdvance = *widthp << 6; } /* set glyph dimensions */ glyph->metrics.width = bbox.xMax - bbox.xMin; glyph->metrics.height = bbox.yMax - bbox.yMin; return 0; } /*************************************************************************/ /* */ /* <Function> */ /* TT_Load_Glyph */ /* */ /* <Description> */ /* A function used to load a single glyph within a given glyph slot, */ /* for a given size. */ /* */ /* <Input> */ /* glyph :: A handle to a target slot object where the glyph */ /* will be loaded. */ /* */ /* size :: A handle to the source face size at which the glyph */ /* must be scaled/loaded. */ /* */ /* glyph_index :: The index of the glyph in the font file. */ /* */ /* load_flags :: A flag indicating what to load for this glyph. The */ /* FT_LOAD_XXX constants can be used to control the */ /* glyph loading process (e.g., whether the outline */ /* should be scaled, whether to load bitmaps or not, */ /* whether to hint the outline, etc). */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ FT_LOCAL_DEF( FT_Error ) TT_Load_Glyph( TT_Size size, TT_GlyphSlot glyph, FT_UInt glyph_index, FT_Int32 load_flags ) { SFNT_Service sfnt; TT_Face face; FT_Stream stream; FT_Error error; TT_LoaderRec loader; face = (TT_Face)glyph->face; sfnt = (SFNT_Service)face->sfnt; stream = face->root.stream; error = TT_Err_Ok; if ( !size || ( load_flags & FT_LOAD_NO_SCALE ) || ( load_flags & FT_LOAD_NO_RECURSE ) ) { size = NULL; load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP; } glyph->num_subglyphs = 0;#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS /* try to load embedded bitmap if any */ /* */ /* XXX: The convention should be emphasized in */ /* the documents because it can be confusing. */ if ( size && size->strike_index != 0xFFFFU && sfnt->load_sbits && ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) { TT_SBit_MetricsRec metrics; error = sfnt->load_sbit_image( face, (FT_ULong)size->strike_index, glyph_index, (FT_Int)load_flags, stream, &glyph->bitmap, &metrics ); if ( !error ) { glyph->outline.n_points = 0; glyph->outline.n_contours = 0; glyph->metrics.width = (FT_Pos)metrics.width << 6; glyph->metrics.height = (FT_Pos)metrics.height << 6; glyph->metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -