📄 ttgload.c
字号:
y_scale ); } else { 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 + -