From b8f4968d9bd0f69721ae4fa7260c59b7a649150f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Wed, 26 Feb 2014 11:24:37 +0100 Subject: [PATCH] app_server: Fixed B_CHAR_SPACING mode. Since fonts are cached with a precision of one digit after the decimal point for the font size, the char spacing values needs to be more precise. They are now in font face units and scaled by the font size during layout. This yields the expected results of the text positioning scaling smoothly along the base line, even though the actual (hinted) glyph shape does not change with each small change of the scale (or font size). --- src/servers/app/font/FontEngine.cpp | 23 +++++++++-------------- src/servers/app/font/GlyphLayoutEngine.h | 5 +++-- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/servers/app/font/FontEngine.cpp b/src/servers/app/font/FontEngine.cpp index c6e269d764..1c56987241 100644 --- a/src/servers/app/font/FontEngine.cpp +++ b/src/servers/app/font/FontEngine.cpp @@ -624,28 +624,23 @@ FontEngine::PrepareGlyph(uint32 glyphIndex) loadFlags |= fGlyphRendering == glyph_ren_subpix ? FT_LOAD_TARGET_LCD : FT_LOAD_TARGET_NORMAL; - if (fHinting) { - // Load without hinting to get precise advance values - // for B_CHAR_SPACING - fLastError = FT_Load_Glyph(fFace, glyphIndex, loadFlags - | FT_LOAD_NO_HINTING); - } else { - fLastError = FT_Load_Glyph(fFace, glyphIndex, loadFlags); - } + // Load unscaled and without hinting to get precise advance values + // for B_CHAR_SPACING + fLastError = FT_Load_Glyph(fFace, glyphIndex, loadFlags + | FT_LOAD_NO_HINTING | FT_LOAD_NO_SCALE); - fPreciseAdvanceX = int26p6_to_dbl(fFace->glyph->advance.x); - fPreciseAdvanceY = int26p6_to_dbl(fFace->glyph->advance.y); + fPreciseAdvanceX = (double)fFace->glyph->advance.x / fFace->units_per_EM; + fPreciseAdvanceY = (double)fFace->glyph->advance.y / fFace->units_per_EM; - if (fHinting) { - // Need to load again with hinting. - fLastError = FT_Load_Glyph(fFace, glyphIndex, loadFlags); - } + // Need to load again with hinting. + fLastError = FT_Load_Glyph(fFace, glyphIndex, loadFlags); if (fLastError != 0) return false; fAdvanceX = int26p6_to_dbl(fFace->glyph->advance.x); fAdvanceY = int26p6_to_dbl(fFace->glyph->advance.y); + fInsetLeft = int26p6_to_dbl(fFace->glyph->metrics.horiBearingX); fInsetRight = int26p6_to_dbl(fFace->glyph->metrics.horiBearingX + fFace->glyph->metrics.width - fFace->glyph->metrics.horiAdvance); diff --git a/src/servers/app/font/GlyphLayoutEngine.h b/src/servers/app/font/GlyphLayoutEngine.h index b1fc624f32..8ed8d198a2 100644 --- a/src/servers/app/font/GlyphLayoutEngine.h +++ b/src/servers/app/font/GlyphLayoutEngine.h @@ -210,6 +210,7 @@ GlyphLayoutEngine::LayoutGlyphs(GlyphConsumer& consumer, double advanceX = 0.0; double advanceY = 0.0; + double size = font.Size(); uint32 lastCharCode = 0; // Needed for kerning in B_STRING_SPACING mode uint32 charCode; @@ -254,8 +255,8 @@ GlyphLayoutEngine::LayoutGlyphs(GlyphConsumer& consumer, } else { // get next increment for pen position if (spacing == B_CHAR_SPACING) { - advanceX = glyph->precise_advance_x; - advanceY = glyph->precise_advance_y; + advanceX = glyph->precise_advance_x * size; + advanceY = glyph->precise_advance_y * size; } else { advanceX = glyph->advance_x; advanceY = glyph->advance_y;