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
////////////////////////////////////////////////////////////
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
};

View File

@ -40,6 +40,7 @@
#include FT_STROKER_H
#include <cstdlib>
#include <cstring>
#include <cmath>
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<float>(kerning.x);
// Return the X advance
return static_cast<float>(kerning.x) / static_cast<float>(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<float>(kerning.x) + 32) / static_cast<float>(1 << 6));
}
else
{
@ -624,6 +630,9 @@ Glyph Font::loadGlyph(Uint32 codePoint, unsigned int characterSize, bool bold, f
if (bold)
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 height = bitmap.rows;