From 7a0c35c334071add846da643dd32f5eb083d75d6 Mon Sep 17 00:00:00 2001 From: Radek Dutkiewicz Date: Sun, 8 Mar 2020 13:14:16 +0000 Subject: [PATCH] Added glyph position compensation after autohinting This improves glyph spacing by subtracting glyph position deltas from glyph advance generated by forced autohinting --- include/SFML/Graphics/Glyph.hpp | 2 ++ src/SFML/Graphics/Font.cpp | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/include/SFML/Graphics/Glyph.hpp b/include/SFML/Graphics/Glyph.hpp index 5c6048aa..0e62aa65 100644 --- a/include/SFML/Graphics/Glyph.hpp +++ b/include/SFML/Graphics/Glyph.hpp @@ -52,6 +52,8 @@ public: // Member data //////////////////////////////////////////////////////////// float advance; //!< Offset to move horizontally to the next character + int lsb_delta; //!< Left offset after forced autohint. Internally used by getKerning() + int rsb_delta; //!< Right offset after forced autohint. Internally used by getKerning() FloatRect bounds; //!< Bounding rectangle of the glyph, in coordinates relative to the baseline IntRect textureRect; //!< Texture coordinates of the glyph inside the font's texture }; diff --git a/src/SFML/Graphics/Font.cpp b/src/SFML/Graphics/Font.cpp index b3d474c1..7ef2067f 100644 --- a/src/SFML/Graphics/Font.cpp +++ b/src/SFML/Graphics/Font.cpp @@ -40,6 +40,7 @@ #include FT_STROKER_H #include #include +#include namespace @@ -389,16 +390,21 @@ float Font::getKerning(Uint32 first, Uint32 second, unsigned int characterSize) FT_UInt index1 = FT_Get_Char_Index(face, first); FT_UInt index2 = FT_Get_Char_Index(face, second); + // Retrieve position compensation deltas generated by FT_LOAD_FORCE_AUTOHINT flag + float firstRsbDelta = getGlyph(first, characterSize, false).rsb_delta; + float secondLsbDelta = getGlyph(second, characterSize, false).lsb_delta; + // Get the kerning vector FT_Vector kerning; - FT_Get_Kerning(face, index1, index2, FT_KERNING_DEFAULT, &kerning); + FT_Get_Kerning(face, index1, index2, FT_KERNING_UNFITTED, &kerning); // X advance is already in pixels for bitmap fonts if (!FT_IS_SCALABLE(face)) return static_cast(kerning.x); - // Return the X advance - return static_cast(kerning.x) / static_cast(1 << 6); + // Combine kerning with compensation deltas and return the X advance + // Flooring is required as we use FT_KERNING_UNFITTED flag which is not quantized in 64 based grid + return std::floor((secondLsbDelta - firstRsbDelta + static_cast(kerning.x) + 32) / static_cast(1 << 6)); } else { @@ -624,6 +630,9 @@ Glyph Font::loadGlyph(Uint32 codePoint, unsigned int characterSize, bool bold, f if (bold) glyph.advance += static_cast(weight) / static_cast(1 << 6); + glyph.lsb_delta = face->glyph->lsb_delta; + glyph.rsb_delta = face->glyph->rsb_delta; + int width = bitmap.width; int height = bitmap.rows;