diff options
| author | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2026-04-15 11:44:16 +0300 |
|---|---|---|
| committer | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2026-04-15 22:27:56 +0300 |
| commit | a49792a88bb06f444c04026764a48d965da270ea (patch) | |
| tree | 4d375a12abba890cf98be0222a332708295a13b3 /indra | |
| parent | 6ee601c642b3a4fa182334eb1ca015d71d6eaedd (diff) | |
Implement lsb_delta and rsb_delta support
By Rye
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llrender/llfontfreetype.cpp | 34 | ||||
| -rw-r--r-- | indra/llrender/llfontfreetype.h | 2 |
2 files changed, 26 insertions, 10 deletions
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index 9b00df2bf6..b35d1f6a35 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -117,6 +117,8 @@ LLFontGlyphInfo::LLFontGlyphInfo(U32 index, EFontGlyphType glyph_type) mYBitmapOffset(0), // Offset to the origin in the bitmap mXBearing(0), // Distance from baseline to left in pixels mYBearing(0), // Distance from baseline to top in pixels + mLsbDelta(0), + mRsbDelta(0), mBitmapEntry(std::make_pair(EFontGlyphType::Unspecified, -1)) // Which bitmap in the bitmap cache contains this glyph { } @@ -132,6 +134,8 @@ LLFontGlyphInfo::LLFontGlyphInfo(const LLFontGlyphInfo& fgi) , mYBitmapOffset(fgi.mYBitmapOffset) , mXBearing(fgi.mXBearing) , mYBearing(fgi.mYBearing) + , mLsbDelta(fgi.mLsbDelta) + , mRsbDelta(fgi.mRsbDelta) { mBitmapEntry = fgi.mBitmapEntry; } @@ -369,17 +373,10 @@ F32 LLFontFreetype::getXKerning(llwchar char_left, llwchar char_right) const //llassert(!mIsFallback); LLFontGlyphInfo* left_glyph_info = getGlyphInfo(char_left, EFontGlyphType::Unspecified);; - U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0; // Kern this puppy. LLFontGlyphInfo* right_glyph_info = getGlyphInfo(char_right, EFontGlyphType::Unspecified); - U32 right_glyph = right_glyph_info ? right_glyph_info->mGlyphIndex : 0; - - FT_Vector delta; - llverify(!FT_Get_Kerning(mFTFace, left_glyph, right_glyph, ft_kerning_unfitted, &delta)); - - // ft_kerning_unfitted mode always returns 26.6 fixed-point values - return (F32)(delta.x * (1.0 / 64.0)); + return getXKerning(left_glyph_info, right_glyph_info); } F32 LLFontFreetype::getXKerning(const LLFontGlyphInfo* left_glyph_info, const LLFontGlyphInfo* right_glyph_info) const @@ -394,8 +391,20 @@ F32 LLFontFreetype::getXKerning(const LLFontGlyphInfo* left_glyph_info, const LL llverify(!FT_Get_Kerning(mFTFace, left_glyph, right_glyph, ft_kerning_unfitted, &delta)); - // ft_kerning_unfitted mode always returns 26.6 fixed-point values - return (F32)(delta.x * (1.0 / 64.0)); + // Apply the FreeType auto-hinter's subpixel side-bearing correction between + // adjacent glyphs. When the hinter has shifted the right side of the left + // glyph or the left side of the right glyph, (rsb_delta - lsb_delta) is the + // sub-pixel nudge that keeps spacing visually even. It combines cleanly with + // the ll_round() that callers apply after kerning: sub-pixel values only + // affect the rounded pen when they cross a half-pixel threshold, matching + // the classic FT_Pos +-32 snap. + S32 delta_correction = 0; + if (left_glyph_info) + delta_correction += left_glyph_info->mRsbDelta; + if (right_glyph_info) + delta_correction -= right_glyph_info->mLsbDelta; + + return (delta.x + delta_correction) * (1.f / 64.f); } bool LLFontFreetype::hasGlyph(llwchar wch) const @@ -540,6 +549,11 @@ LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, l gi->mHeight = height; gi->mXBearing = fontp->mFTFace->glyph->bitmap_left; gi->mYBearing = fontp->mFTFace->glyph->bitmap_top; + // FreeType fills these when the glyph has been auto-hinted; they describe how + // much the hinter nudged the left/right side bearings (in 26.6 pixels). Keep + // them so inter-glyph spacing can be corrected in getXKerning(). + gi->mLsbDelta = (S32)fontp->mFTFace->glyph->lsb_delta; + gi->mRsbDelta = (S32)fontp->mFTFace->glyph->rsb_delta; // Convert these from 26.6 units to float pixels. gi->mXAdvance = fontp->mFTFace->glyph->advance.x / 64.f; gi->mYAdvance = fontp->mFTFace->glyph->advance.y / 64.f; diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h index d2b128e4ce..d2164e8fa2 100644 --- a/indra/llrender/llfontfreetype.h +++ b/indra/llrender/llfontfreetype.h @@ -88,6 +88,8 @@ struct LLFontGlyphInfo S32 mYBitmapOffset; // Offset to the origin in the bitmap S32 mXBearing; // Distance from baseline to left in pixels S32 mYBearing; // Distance from baseline to top in pixels + S32 mLsbDelta; // FreeType subpixel left side bearing delta (26.6 units) + S32 mRsbDelta; // FreeType subpixel right side bearing delta (26.6 units) std::pair<EFontGlyphType, S32> mBitmapEntry; // Which bitmap in the bitmap cache contains this glyph }; |
