* 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:
parent
e5ff059f7f
commit
212aee0d6e
14
ChangeLog
14
ChangeLog
@ -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
|
||||
|
@ -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).
|
||||
|
@ -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 )
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user