📄 ttgload.c.old
字号:
{
FT_Pos height;
/* XXX Compute top side bearing and advance height in */
/* Get_VMetrics instead of here. */
/* 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. */
height = (FT_Short)FT_DivFix( bbox.yMax - bbox.yMin,
y_scale );
if ( face->os2.version != 0xFFFFU )
advance = (FT_Pos)( face->os2.sTypoAscender -
face->os2.sTypoDescender );
else
advance = (FT_Pos)( face->horizontal.Ascender -
face->horizontal.Descender );
top = ( advance - height ) / 2;
}
#ifdef FT_CONFIG_OPTION_INCREMENTAL
{
FT_Incremental_InterfaceRec* incr;
FT_Incremental_MetricsRec metrics;
FT_Error error;
incr = face->root.internal->incremental_interface;
/* If this is an incrementally loaded font see if there are */
/* overriding metrics for this glyph. */
if ( incr && incr->funcs->get_glyph_metrics )
{
metrics.bearing_x = 0;
metrics.bearing_y = top;
metrics.advance = advance;
error = incr->funcs->get_glyph_metrics( incr->object,
glyph_index,
TRUE,
&metrics );
if ( error )
return error;
top = metrics.bearing_y;
advance = metrics.advance;
}
}
/* GWW: Do vertical metrics get loaded incrementally too? */
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
glyph->linearVertAdvance = advance;
/* scale the metrics */
if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) )
{
top = FT_MulFix( top, y_scale );
advance = FT_MulFix( advance, y_scale );
}
/* XXX: for now, we have no better algorithm for the lsb, but it */
/* should work fine. */
/* */
glyph->metrics.vertBearingX = ( bbox.xMin - bbox.xMax ) / 2;
glyph->metrics.vertBearingY = top;
glyph->metrics.vertAdvance = advance;
}
/* adjust advance width to the value contained in the hdmx table */
if ( !face->postscript.isFixedPitch &&
IS_HINTED( loader->load_flags ) )
{
FT_Byte* widthp;
widthp = tt_face_get_device_metrics( 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;
}
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
static FT_Error
load_sbit_image( TT_Size size,
TT_GlyphSlot glyph,
FT_UInt glyph_index,
FT_Int32 load_flags )
{
TT_Face face;
SFNT_Service sfnt;
FT_Stream stream;
FT_Error error;
TT_SBit_MetricsRec metrics;
face = (TT_Face)glyph->face;
sfnt = (SFNT_Service)face->sfnt;
stream = face->root.stream;
error = sfnt->load_sbit_image( face,
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;
glyph->metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6;
glyph->metrics.horiAdvance = (FT_Pos)metrics.horiAdvance << 6;
glyph->metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6;
glyph->metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6;
glyph->metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6;
glyph->format = FT_GLYPH_FORMAT_BITMAP;
if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
{
glyph->bitmap_left = metrics.vertBearingX;
glyph->bitmap_top = metrics.vertBearingY;
}
else
{
glyph->bitmap_left = metrics.horiBearingX;
glyph->bitmap_top = metrics.horiBearingY;
}
}
return error;
}
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
static FT_Error
tt_loader_init( TT_Loader loader,
TT_Size size,
TT_GlyphSlot glyph,
FT_Int32 load_flags )
{
TT_Face face;
FT_Stream stream;
face = (TT_Face)glyph->face;
stream = face->root.stream;
FT_MEM_ZERO( loader, sizeof ( TT_LoaderRec ) );
#ifdef TT_USE_BYTECODE_INTERPRETER
/* load execution context */
if ( IS_HINTED( load_flags ) )
{
TT_ExecContext exec;
FT_Bool grayscale;
if ( !size->cvt_ready )
{
FT_Error error = tt_size_ready_bytecode( size );
if ( error )
return error;
}
/* query new execution context */
exec = size->debug ? size->context
: ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
if ( !exec )
return TT_Err_Could_Not_Find_Context;
grayscale =
FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != FT_RENDER_MODE_MONO );
TT_Load_Context( exec, face, size );
/* a change from mono to grayscale rendering (and vice versa) */
/* requires a re-execution of the CVT program */
if ( grayscale != exec->grayscale )
{
FT_UInt i;
exec->grayscale = grayscale;
for ( i = 0; i < size->cvt_size; i++ )
size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
tt_size_run_prep( size );
}
/* see if the cvt program has disabled hinting */
if ( exec->GS.instruct_control & 1 )
load_flags |= FT_LOAD_NO_HINTING;
/* load default graphics state - if needed */
if ( exec->GS.instruct_control & 2 )
exec->GS = tt_default_graphics_state;
exec->pedantic_hinting = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
loader->exec = exec;
loader->instructions = exec->glyphIns;
}
#endif /* TT_USE_BYTECODE_INTERPRETER */
/* seek to the beginning of the glyph table. For Type 42 fonts */
/* the table might be accessed from a Postscript stream or something */
/* else... */
#ifdef FT_CONFIG_OPTION_INCREMENTAL
if ( face->root.internal->incremental_interface )
loader->glyf_offset = 0;
else
#endif
{
FT_Error error = face->goto_table( face, TTAG_glyf, stream, 0 );
if ( error )
{
FT_ERROR(( "TT_Load_Glyph: could not access glyph table\n" ));
return error;
}
loader->glyf_offset = FT_STREAM_POS();
}
/* get face's glyph loader */
{
FT_GlyphLoader gloader = glyph->internal->loader;
FT_GlyphLoader_Rewind( gloader );
loader->gloader = gloader;
}
loader->load_flags = load_flags;
loader->face = (FT_Face)face;
loader->size = (FT_Size)size;
loader->glyph = (FT_GlyphSlot)glyph;
loader->stream = stream;
return TT_Err_Ok;
}
/*************************************************************************/
/* */
/* <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 )
{
TT_Face face;
FT_Stream stream;
FT_Error error;
TT_LoaderRec loader;
face = (TT_Face)glyph->face;
stream = face->root.stream;
error = TT_Err_Ok;
#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->strike_index != 0xFFFFFFFFUL &&
( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
{
error = load_sbit_image( size, glyph, glyph_index, load_flags );
if ( !error )
return TT_Err_Ok;
}
#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
/* if FT_LOAD_NO_SCALE is not set, `ttmetrics' must be valid */
if ( !( load_flags & FT_LOAD_NO_SCALE ) && !size->ttmetrics.valid )
return TT_Err_Invalid_Size_Handle;
if ( load_flags & FT_LOAD_SBITS_ONLY )
return TT_Err_Invalid_Argument;
error = tt_loader_init( &loader, size, glyph, load_flags );
if ( error )
return error;
glyph->format = FT_GLYPH_FORMAT_OUTLINE;
glyph->num_subglyphs = 0;
glyph->outline.flags = 0;
/* Main loading loop */
error = load_truetype_glyph( &loader, glyph_index, 0 );
if ( !error )
{
if ( glyph->format == FT_GLYPH_FORMAT_COMPOSITE )
{
glyph->num_subglyphs = loader.gloader->base.num_subglyphs;
glyph->subglyphs = loader.gloader->base.subglyphs;
}
else
{
glyph->outline = loader.gloader->base.outline;
glyph->outline.flags &= ~FT_OUTLINE_SINGLE_PASS;
/* In case bit 1 of the `flags' field in the `head' table isn't */
/* set, translate array so that (0,0) is the glyph's origin. */
if ( ( face->header.Flags & 2 ) == 0 && loader.pp1.x )
FT_Outline_Translate( &glyph->outline, -loader.pp1.x, 0 );
}
compute_glyph_metrics( &loader, glyph_index );
}
/* Set the `high precision' bit flag. */
/* This is _critical_ to get correct output for monochrome */
/* TrueType glyphs at all sizes using the bytecode interpreter. */
/* */
if ( !( load_flags & FT_LOAD_NO_SCALE ) &&
size->root.metrics.y_ppem < 24 )
glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
return error;
}
/* END */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -