From 4399fdc800b2c1376e138ac3985199bb2405d1f4 Mon Sep 17 00:00:00 2001 From: Victor Cebollada Date: Wed, 10 Apr 2019 12:15:58 +0100 Subject: [PATCH] Fix for retrieved metrics. * DALi is not able to correctly layout text for the SNum-3R font. * Enable the SW emboldering as well when the metrics are retrieved. * Use the bounding box of the glyph to correct the retrieved metrics used to layout the text. * A scale factor is applied to the advance metric when a font is emboldened by software as Harfbuzz doesn't do it. * Some code beautify. Change-Id: I3b5167e382654b110177731db191325ce2f01c01 Signed-off-by: Victor Cebollada --- .../text-abstraction/font-client-plugin-impl.cpp | 46 +++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/dali/internal/text/text-abstraction/font-client-plugin-impl.cpp b/dali/internal/text/text-abstraction/font-client-plugin-impl.cpp index 1fb9c67..9b632f5 100755 --- a/dali/internal/text/text-abstraction/font-client-plugin-impl.cpp +++ b/dali/internal/text/text-abstraction/font-client-plugin-impl.cpp @@ -1240,12 +1240,28 @@ bool FontClient::Plugin::GetBitmapMetrics( GlyphInfo* array, else #endif { + // FT_LOAD_DEFAULT causes some issues in the alignment of the glyph inside the bitmap. + // i.e. with the SNum-3R font. + // @todo: add an option to use the FT_LOAD_DEFAULT if required? int error = FT_Load_Glyph( ftFace, glyph.index, FT_LOAD_NO_AUTOHINT ); + // Keep the width of the glyph before doing the software emboldening. + // It will be used to calculate a scale factor to be applied to the + // advance as Harfbuzz doesn't apply any SW emboldening to calculate + // the advance of the glyph. + const float width = static_cast< float >( ftFace->glyph->metrics.width ) * FROM_266; + if( FT_Err_Ok == error ) { + const bool isEmboldeningRequired = glyph.isBoldRequired && !( ftFace->style_flags & FT_STYLE_FLAG_BOLD ); + if( isEmboldeningRequired ) + { + // Does the software bold. + FT_GlyphSlot_Embolden( ftFace->glyph ); + } + glyph.width = static_cast< float >( ftFace->glyph->metrics.width ) * FROM_266; - glyph.height = static_cast< float >( ftFace->glyph->metrics.height ) * FROM_266 ; + glyph.height = static_cast< float >( ftFace->glyph->metrics.height ) * FROM_266; if( horizontal ) { glyph.xBearing += static_cast< float >( ftFace->glyph->metrics.horiBearingX ) * FROM_266; @@ -1256,6 +1272,31 @@ bool FontClient::Plugin::GetBitmapMetrics( GlyphInfo* array, glyph.xBearing += static_cast< float >( ftFace->glyph->metrics.vertBearingX ) * FROM_266; glyph.yBearing += static_cast< float >( ftFace->glyph->metrics.vertBearingY ) * FROM_266; } + + if( isEmboldeningRequired && !Dali::EqualsZero( width ) ) + { + // If the glyph is emboldened by software, the advance is multiplied by a + // scale factor to make it slightly bigger. + glyph.advance *= ( glyph.width / width ); + } + + // Use the bounding box of the bitmap to correct the metrics. + // For some fonts i.e the SNum-3R the metrics need to be corrected, + // otherwise the glyphs 'dance' up and down depending on the + // font's point size. + + FT_Glyph ftGlyph; + error = FT_Get_Glyph( ftFace->glyph, &ftGlyph ); + + FT_BBox bbox; + FT_Glyph_Get_CBox( ftGlyph, FT_GLYPH_BBOX_GRIDFIT, &bbox ); + + const float descender = glyph.height - glyph.yBearing; + glyph.height = ( bbox.yMax - bbox.yMin) * FROM_266; + glyph.yBearing = glyph.height - std::round( descender ); + + // Created FT_Glyph object must be released with FT_Done_Glyph + FT_Done_Glyph( ftGlyph ); } else { @@ -1399,6 +1440,9 @@ void FontClient::Plugin::CreateBitmap( FontId fontId, GlyphIndex glyphIndex, boo else #endif { + // FT_LOAD_DEFAULT causes some issues in the alignment of the glyph inside the bitmap. + // i.e. with the SNum-3R font. + // @todo: add an option to use the FT_LOAD_DEFAULT if required? error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_NO_AUTOHINT ); } if( FT_Err_Ok == error ) -- 2.7.4