* include/freetype/internal/ftobjs.h (ft_fake_vertical_metrics),

src/base/ftobjs.c (ft_fake_vertical_metrics): New function to fake the
vertical metrics.

* src/cff/cffgload.c, src/cid/cidgload.c, src/pcf/pcfdrivr.c,
src/type1/t1gload.c, src/winfonts/winfnt.c: Fake the vertical metrics.
The fake metrics is monotone.

* src/truetype/ttgload.c (compute_glyph_metrics): Some fixes and
formattings in vertical metrics faking.  There are still rooms for
improvements (and so do the CFF module).
This commit is contained in:
Wu, Chia-I (吳佳一) 2006-01-15 06:24:53 +00:00
parent e5ff059f7f
commit 212aee0d6e
10 changed files with 124 additions and 76 deletions

View File

@ -1,3 +1,17 @@
2006-01-15 Chia-I Wu <b90201047@ntu.edu.tw>
* include/freetype/internal/ftobjs.h (ft_fake_vertical_metrics),
src/base/ftobjs.c (ft_fake_vertical_metrics): New function to fake the
vertical metrics.
* src/cff/cffgload.c, src/cid/cidgload.c, src/pcf/pcfdrivr.c,
src/type1/t1gload.c, src/winfonts/winfnt.c: Fake the vertical metrics.
The fake metrics is monotone.
* src/truetype/ttgload.c (compute_glyph_metrics): Some fixes and
formattings in vertical metrics faking. There are still rooms for
improvements (and so do the CFF module).
2006-01-15 Chia-I Wu <b90201047@ntu.edu.tw>
* src/bdf/bdfdrivr.c (BDF_Glyph_Load), src/pcf/pcfdrivr.c

View File

@ -461,6 +461,15 @@ FT_BEGIN_HEADER
FT_ULong* index );
/*
* Use the horizontal metrics to fake the vertical metrics.
* If `advance' is zero, it is also faked.
*/
FT_BASE( void )
ft_fake_vertical_metrics( FT_Glyph_Metrics* metrics,
FT_Pos advance );
/*
* Free the bitmap of a given glyphslot when needed
* (i.e., only when it was allocated with ft_glyphslot_alloc_bitmap).

View File

@ -2039,6 +2039,21 @@
}
/* documentation is in ftobjs.h */
FT_BASE_DEF( void )
ft_fake_vertical_metrics( FT_Glyph_Metrics* metrics,
FT_Pos advance )
{
if ( !advance )
advance = metrics->height * 12 / 10;
metrics->vertBearingX = -( metrics->width / 2 );
metrics->vertBearingY = ( advance - metrics->height ) / 2;
metrics->vertAdvance = advance;
}
static void
ft_recompute_scaled_metrics( FT_Face face,
FT_Size_Metrics* metrics )

View File

@ -702,13 +702,19 @@ THE SOFTWARE.
slot->bitmap_left = glyph.bbx.x_offset;
slot->bitmap_top = glyph.bbx.ascent;
/* FZ XXX: TODO: vertical metrics */
slot->metrics.horiAdvance = glyph.dwidth << 6;
slot->metrics.horiBearingX = glyph.bbx.x_offset << 6;
slot->metrics.horiBearingY = glyph.bbx.ascent << 6;
slot->metrics.width = bitmap->width << 6;
slot->metrics.height = bitmap->rows << 6;
/*
* XXX DWIDTH1 and VVECTOR should be parsed and
* used here, provided such fonts do exist.
*/
ft_fake_vertical_metrics( &slot->metrics,
face->bdffont->bbx.height << 6 );
Exit:
return error;
}

View File

@ -2602,6 +2602,7 @@
FT_BBox cbox;
FT_Glyph_Metrics* metrics = &glyph->root.metrics;
FT_Vector advance;
FT_Bool has_vertical_info;
/* copy the _unscaled_ advance width */
@ -2609,17 +2610,12 @@
glyph->root.linearHoriAdvance = decoder.glyph_width;
glyph->root.internal->glyph_transformed = 0;
/* make up vertical ones */
metrics->vertAdvance = 0;
metrics->vertBearingX = 0;
metrics->vertBearingY = 0;
glyph->root.linearVertAdvance = 0;
has_vertical_info = ( face->vertical_info &&
face->vertical.number_Of_VMetrics > 0 &&
face->vertical.long_metrics != 0 );
/* get the vertical metrics from the vtmx table if we have one */
if ( face->vertical_info &&
face->vertical.number_Of_VMetrics > 0 &&
face->vertical.long_metrics != 0 )
if ( has_vertical_info )
{
FT_Short vertBearingY = 0;
FT_UShort vertAdvance = 0;
@ -2630,6 +2626,18 @@
metrics->vertBearingY = vertBearingY;
metrics->vertAdvance = vertAdvance;
}
else
{
/* make up vertical ones */
if ( face->os2.version != 0xFFFFU )
metrics->vertAdvance = (FT_Pos)( face->os2.sTypoAscender -
face->os2.sTypoDescender );
else
metrics->vertAdvance = (FT_Pos)( face->horizontal.Ascender -
face->horizontal.Descender );
}
glyph->root.linearVertAdvance = metrics->vertAdvance;
glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;
@ -2687,6 +2695,12 @@
metrics->horiBearingX = cbox.xMin;
metrics->horiBearingY = cbox.yMax;
if ( has_vertical_info )
metrics->vertBearingX = -metrics->width / 2;
else
ft_fake_vertical_metrics( metrics,
metrics->vertAdvance );
}
}

View File

@ -343,8 +343,9 @@
cidglyph->internal->glyph_transformed = 0;
/* make up vertical ones */
metrics->vertAdvance = 0;
cidglyph->linearVertAdvance = 0;
metrics->vertAdvance = ( face->cid.font_bbox.yMax -
face->cid.font_bbox.yMin ) >> 16;
cidglyph->linearVertAdvance = metrics->vertAdvance;
cidglyph->format = FT_GLYPH_FORMAT_OUTLINE;
@ -400,8 +401,8 @@
metrics->horiBearingY = cbox.yMax;
/* make up vertical ones */
metrics->vertBearingX = 0;
metrics->vertBearingY = 0;
ft_fake_vertical_metrics( metrics,
metrics->vertAdvance );
}
}

View File

@ -531,6 +531,10 @@ THE SOFTWARE.
metric->leftSideBearing ) << 6;
slot->metrics.height = bitmap->rows << 6;
ft_fake_vertical_metrics( &slot->metrics,
( face->accel.fontAscent +
face->accel.fontDescent ) << 6 );
FT_TRACE4(( " --- ok\n" ));
Exit:

View File

@ -1673,10 +1673,6 @@
/* 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 */
@ -1685,18 +1681,18 @@
if ( face->vertical_info &&
face->vertical.number_Of_VMetrics > 0 )
{
top_bearing = (FT_Short)FT_DivFix( loader->pp3.y - bbox.yMax,
y_scale );
top = (FT_Short)FT_DivFix( loader->pp3.y - bbox.yMax,
y_scale );
if ( loader->pp3.y <= loader->pp4.y )
advance_height = 0;
advance = 0;
else
advance_height = (FT_UShort)FT_DivFix( loader->pp3.y - loader->pp4.y,
y_scale );
advance = (FT_UShort)FT_DivFix( loader->pp3.y - loader->pp4.y,
y_scale );
}
else
{
FT_Short max_height, height;
FT_Pos height;
/* XXX Compute top side bearing and advance height in */
@ -1707,79 +1703,63 @@
/* 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 );
height = (FT_Short)FT_DivFix( bbox.yMax - bbox.yMin,
y_scale );
if ( face->os2.version != 0xFFFFU )
{
/* sTypoDescender is negative */
max_height = (FT_Short)(face->os2.sTypoAscender -
face->os2.sTypoDescender);
top_bearing = (FT_Short)( ( max_height - height ) / 2 );
advance_height = (FT_UShort)( max_height + face->os2.sTypoLineGap );
}
advance = (FT_Pos)( face->os2.sTypoAscender -
face->os2.sTypoDescender );
else
{
max_height = (FT_Short)(face->horizontal.Ascender +
face->horizontal.Descender);
advance = (FT_Pos)( face->horizontal.Ascender -
face->horizontal.Descender );
top_bearing = (FT_Short)( ( max_height - height ) / 2 );
advance_height = (FT_UShort)( max_height +
face->horizontal.Line_Gap );
}
top = ( advance - height ) / 2;
}
#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;
FT_Incremental_InterfaceRec* incr;
FT_Incremental_MetricsRec metrics;
FT_Error error;
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 );
incr = face->root.internal->incremental_interface;
if ( error )
return error;
/* 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_bearing = (FT_Short)metrics.bearing_y;
advance_height = (FT_UShort)metrics.advance;
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_bearing, y_scale );
advance = FT_MulFix( advance_height, y_scale );
top = FT_MulFix( top, y_scale );
advance = FT_MulFix( advance, y_scale );
}
else
{
top = top_bearing;
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;
glyph->metrics.vertBearingX = left;
glyph->metrics.vertBearingX = ( bbox.xMin - bbox.xMax ) / 2;
glyph->metrics.vertBearingY = top;
glyph->metrics.vertAdvance = advance;
}

View File

@ -298,8 +298,10 @@
glyph->root.linearHoriAdvance = decoder.builder.advance.x;
glyph->root.internal->glyph_transformed = 0;
metrics->vertAdvance = 0;
glyph->root.linearVertAdvance = 0;
/* make up vertical ones */
metrics->vertAdvance = ( face->type1.font_bbox.yMax -
face->type1.font_bbox.yMin ) >> 16;
glyph->root.linearVertAdvance = metrics->vertAdvance;
glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;
@ -357,8 +359,8 @@
metrics->horiBearingY = cbox.yMax;
/* make up vertical ones */
metrics->vertBearingX = 0;
metrics->vertBearingY = 0;
ft_fake_vertical_metrics( metrics,
metrics->vertAdvance );
}
/* Set control data to the glyph charstrings. Note that this is */

View File

@ -724,6 +724,9 @@
slot->metrics.horiBearingX = 0;
slot->metrics.horiBearingY = slot->bitmap_top << 6;
ft_fake_vertical_metrics( &slot->metrics,
bitmap->rows << 6 );
Exit:
return error;
}