From 212aee0d6ec8bcae84c3278e6f786d01044dea7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wu=2C=20Chia-I=20=28=E5=90=B3=E4=BD=B3=E4=B8=80=29?= Date: Sun, 15 Jan 2006 06:24:53 +0000 Subject: [PATCH] * 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). --- ChangeLog | 14 +++++ include/freetype/internal/ftobjs.h | 9 +++ src/base/ftobjs.c | 15 +++++ src/bdf/bdfdrivr.c | 8 ++- src/cff/cffgload.c | 32 +++++++--- src/cid/cidgload.c | 9 +-- src/pcf/pcfdrivr.c | 4 ++ src/truetype/ttgload.c | 96 ++++++++++++------------------ src/type1/t1gload.c | 10 ++-- src/winfonts/winfnt.c | 3 + 10 files changed, 124 insertions(+), 76 deletions(-) diff --git a/ChangeLog b/ChangeLog index e8a7c6726..29f26c9fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2006-01-15 Chia-I Wu + + * 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 * src/bdf/bdfdrivr.c (BDF_Glyph_Load), src/pcf/pcfdrivr.c diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h index 0a6c3163b..a6c6aae24 100644 --- a/include/freetype/internal/ftobjs.h +++ b/include/freetype/internal/ftobjs.h @@ -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). diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index cbb466c1c..34b1f959d 100644 --- 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 ) diff --git a/src/bdf/bdfdrivr.c b/src/bdf/bdfdrivr.c index 64b6e1ff1..a70f8a2bb 100644 --- a/src/bdf/bdfdrivr.c +++ b/src/bdf/bdfdrivr.c @@ -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; } diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c index 2f9c6124d..417eb4dc7 100644 --- 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; - - 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 ); } } diff --git a/src/cid/cidgload.c b/src/cid/cidgload.c index 12d749d50..eaf6a1afa 100644 --- 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 ); } } diff --git a/src/pcf/pcfdrivr.c b/src/pcf/pcfdrivr.c index 0bb1f770e..f28854be9 100644 --- a/src/pcf/pcfdrivr.c +++ b/src/pcf/pcfdrivr.c @@ -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: diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c index 6701471ac..6b28c7dab 100644 --- 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,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; } diff --git a/src/type1/t1gload.c b/src/type1/t1gload.c index 88c57da3f..050c4f079 100644 --- 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 */ diff --git a/src/winfonts/winfnt.c b/src/winfonts/winfnt.c index c20d3bfe9..376fde346 100644 --- 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; }