Added glyph position compensation after autohinting

This improves glyph spacing by subtracting glyph position deltas from glyph advance generated by forced autohinting
This commit is contained in:
Radek Dutkiewicz 2020-03-08 13:14:16 +00:00 committed by Lukas Dürrenberger
parent 54204058a4
commit 7a0c35c334
2 changed files with 14 additions and 3 deletions

View File

@ -52,6 +52,8 @@ public:
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
float advance; //!< Offset to move horizontally to the next character 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 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 IntRect textureRect; //!< Texture coordinates of the glyph inside the font's texture
}; };

View File

@ -40,6 +40,7 @@
#include FT_STROKER_H #include FT_STROKER_H
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <cmath>
namespace 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 index1 = FT_Get_Char_Index(face, first);
FT_UInt index2 = FT_Get_Char_Index(face, second); 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 // Get the kerning vector
FT_Vector kerning; 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 // X advance is already in pixels for bitmap fonts
if (!FT_IS_SCALABLE(face)) if (!FT_IS_SCALABLE(face))
return static_cast<float>(kerning.x); return static_cast<float>(kerning.x);
// Return the X advance // Combine kerning with compensation deltas and return the X advance
return static_cast<float>(kerning.x) / static_cast<float>(1 << 6); // 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<float>(kerning.x) + 32) / static_cast<float>(1 << 6));
} }
else else
{ {
@ -624,6 +630,9 @@ Glyph Font::loadGlyph(Uint32 codePoint, unsigned int characterSize, bool bold, f
if (bold) if (bold)
glyph.advance += static_cast<float>(weight) / static_cast<float>(1 << 6); glyph.advance += static_cast<float>(weight) / static_cast<float>(1 << 6);
glyph.lsb_delta = face->glyph->lsb_delta;
glyph.rsb_delta = face->glyph->rsb_delta;
int width = bitmap.width; int width = bitmap.width;
int height = bitmap.rows; int height = bitmap.rows;