?? ttgload.c
字號:
Exit: return error; } static void 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 &= -64; bbox.yMin &= -64; bbox.xMax = ( bbox.xMax + 63 ) & -64; bbox.yMax = ( bbox.yMax + 63 ) & -64; } } 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 = ( glyph->metrics.horiAdvance + 32 ) & -64; /* 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 `tsb' and `ah' */ if ( face->vertical_info && face->vertical.number_Of_VMetrics > 0 ) { /* Don't assume that both the vertical header and vertical */ /* metrics are present in the same font :-) */ TT_Get_Metrics( (TT_HoriHeader*)&face->vertical, glyph_index, &top_bearing, &advance_height ); } 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 */ /* */ 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 ); } } /* We must adjust the top_bearing value from the bounding box given */ /* in the glyph header to te 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 &= -64; top = ( top + 63 ) & -64; advance = ( advance + 32 ) & -64; } 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* widths = Get_Advance_Widths( face, size->root.metrics.x_ppem ); if ( widths ) glyph->metrics.horiAdvance = widths[glyph_index] << 6; } /* set glyph dimensions */ glyph->metrics.width = bbox.xMax - bbox.xMin; glyph->metrics.height = bbox.yMax - bbox.yMin; } /*************************************************************************/ /* */ /* <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_UShort glyph_index, FT_UInt 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 = 0; 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, size->strike_index, glyph_index, 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 */ /* return immediately if we only want the embedded bitmaps */ if ( load_flags & FT_LOAD_SBITS_ONLY ) return FT_Err_Invalid_Argument; /* seek to the beginning of the glyph table. For Type 42 fonts */ /* the table might be accessed from a Postscript stream or something */ /* else... */ error = face->goto_table( face, TTAG_glyf, stream, 0 ); if ( error ) { FT_ERROR(( "TT_Load_Glyph: could not access glyph table\n" )); goto Exit; } FT_MEM_SET( &loader, 0, sizeof ( loader ) ); /* update the glyph zone bounds */ { FT_GlyphLoader gloader = FT_FACE_DRIVER(face)->glyph_loader; loader.gloader = gloader; FT_GlyphLoader_Rewind( gloader ); tt_prepare_zone( &loader.zone, &gloader->base, 0, 0 ); tt_prepare_zone( &loader.base, &gloader->base, 0, 0 ); }#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER if ( size ) { /* query new execution context */ loader.exec = size->debug ? size->context : TT_New_Context( face ); if ( !loader.exec ) return TT_Err_Could_Not_Find_Context; TT_Load_Context( loader.exec, face, size ); loader.instructions = loader.exec->glyphIns; /* load default graphics state - if needed */ if ( size->GS.instruct_control & 2 ) loader.exec->GS = tt_default_graphics_state; }#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ /* clear all outline flags, except the `owner' one */ glyph->outline.flags = 0; /* let's initialize the rest of our loader now */ loader.load_flags = load_flags; loader.face = (FT_Face)face; loader.size = (FT_Size)size; loader.glyph = (FT_GlyphSlot)glyph; loader.stream = stream; loader.glyf_offset = FT_STREAM_POS();#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER /* if the cvt program has disabled hinting, the argument */ /* is ignored. */ if ( size && ( size->GS.instruct_control & 1 ) ) loader.load_flags |= FT_LOAD_NO_HINTING;#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ /* Main loading loop */ glyph->format = ft_glyph_format_outline; glyph->num_subglyphs = 0; error = load_truetype_glyph( &loader, glyph_index ); if ( !error ) compute_glyph_metrics( &loader, glyph_index );#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER if ( !size || !size->debug ) TT_Done_Context( loader.exec );#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ /* 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 ( size && size->root.metrics.y_ppem < 24 ) glyph->outline.flags |= ft_outline_high_precision; Exit: return error; }/* END */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -