ref: 212aee0d6ec8bcae84c3278e6f786d01044dea7d
parent: e5ff059f7fc32f43753230396efb62a4ac4c0cc5
author: Wu, Chia-I (吳佳一) <[email protected]>
date: Sun Jan 15 01:24:53 EST 2006
* 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).
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
2006-01-15 Chia-I Wu <[email protected]>
+ * 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 <[email protected]>
+
* src/bdf/bdfdrivr.c (BDF_Glyph_Load), src/pcf/pcfdrivr.c
(PCF_Glyph_Load), src/winfonts/winfnt.c (FNT_Load_Glyph): Don't set
the linear advance fields as they are only for the outline glyphs.
--- a/include/freetype/internal/ftobjs.h
+++ b/include/freetype/internal/ftobjs.h
@@ -461,6 +461,15 @@
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).
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -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 )
--- a/src/bdf/bdfdrivr.c
+++ b/src/bdf/bdfdrivr.c
@@ -702,12 +702,18 @@
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;
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -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;
+ has_vertical_info = ( face->vertical_info &&
+ face->vertical.number_Of_VMetrics > 0 &&
+ face->vertical.long_metrics != 0 );
- glyph->root.linearVertAdvance = 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,7 +2626,19 @@
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;
glyph->root.outline.flags = 0;
@@ -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 );
}
}
--- a/src/cid/cidgload.c
+++ b/src/cid/cidgload.c
@@ -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 );
}
}
--- a/src/pcf/pcfdrivr.c
+++ b/src/pcf/pcfdrivr.c
@@ -531,6 +531,10 @@
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:
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -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,51 +1703,44 @@
/* 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? */
@@ -1758,28 +1747,19 @@
#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;
}
--- a/src/type1/t1gload.c
+++ b/src/type1/t1gload.c
@@ -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 */
--- a/src/winfonts/winfnt.c
+++ b/src/winfonts/winfnt.c
@@ -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;
}