diff options
| author | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2026-07-09 21:08:09 +0300 |
|---|---|---|
| committer | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2026-07-10 15:36:35 +0300 |
| commit | 97b0c99e29a60e858f7328094de7e59e5ad02278 (patch) | |
| tree | bdef608b55990c1adf180f308e7316fcb7b70467 /indra | |
| parent | 2957421ccf58d57b7569fc46913e2787f41c655a (diff) | |
#5966 Fixed width font's numbers
Dejavu used fixed width numbers by default, tweaked fonts to do the same
for inter (when weight > 0).
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llrender/llfontfreetype.cpp | 48 | ||||
| -rw-r--r-- | indra/llrender/llfontfreetype.h | 6 | ||||
| -rw-r--r-- | indra/llrender/llfontgl.cpp | 14 |
3 files changed, 62 insertions, 6 deletions
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index 3c5682dfc9..bc4020a06b 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -109,6 +109,7 @@ LLFontManager::~LLFontManager() LLFontGlyphInfo::LLFontGlyphInfo(U32 index, EFontGlyphType glyph_type) : mGlyphIndex(index), mGlyphType(glyph_type), + mChar(0), mWidth(0), // In pixels mHeight(0), // In pixels mXAdvance(0.f), // In pixels @@ -126,6 +127,7 @@ LLFontGlyphInfo::LLFontGlyphInfo(U32 index, EFontGlyphType glyph_type) LLFontGlyphInfo::LLFontGlyphInfo(const LLFontGlyphInfo& fgi) : mGlyphIndex(fgi.mGlyphIndex) , mGlyphType(fgi.mGlyphType) + , mChar(fgi.mChar) , mWidth(fgi.mWidth) , mHeight(fgi.mHeight) , mXAdvance(fgi.mXAdvance) @@ -150,7 +152,8 @@ LLFontFreetype::LLFontFreetype() mFTFace(nullptr), mRenderGlyphCount(0), mStyle(0), - mPointSize(0) + mPointSize(0), + mMaxDigitWidth(0.0f) { } @@ -343,6 +346,10 @@ F32 LLFontFreetype::getXAdvance(llwchar wch) const LLFontGlyphInfo* gi = getGlyphInfo(wch, EFontGlyphType::Unspecified); if (gi) { + if (wch >= '0' && wch <= '9' && mMaxDigitWidth > 0.0f) + { + return mMaxDigitWidth; + } return gi->mXAdvance; } else @@ -363,6 +370,12 @@ F32 LLFontFreetype::getXAdvance(const LLFontGlyphInfo* glyph) const if (mFTFace == nullptr) return 0.0; + // Use max digit width for tabular numbers + if (mWeight > 0 && glyph->mChar >= '0' && glyph->mChar <= '9' && mMaxDigitWidth > 0.0f) + { + return mMaxDigitWidth; + } + return glyph->mXAdvance; } @@ -384,8 +397,27 @@ F32 LLFontFreetype::getXKerning(const LLFontGlyphInfo* left_glyph_info, const LL if (mFTFace == nullptr) return 0.0; - U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0; - U32 right_glyph = right_glyph_info ? right_glyph_info->mGlyphIndex : 0; + U32 left_glyph = 0; + U32 right_glyph = 0; + + if (left_glyph_info) + { + if (mWeight > 0 && left_glyph_info->mChar >= '0' && left_glyph_info->mChar <= '9') + { + // Disable kerning for digits when using tabular numbers + return 0.0; + } + left_glyph = left_glyph_info->mGlyphIndex; + } + if (right_glyph_info) + { + if (mWeight > 0 && right_glyph_info->mChar >= '0' && right_glyph_info->mChar <= '9') + { + // Disable kerning for digits when using tabular numbers + return 0.0; + } + right_glyph = right_glyph_info->mGlyphIndex; + } FT_Vector delta; @@ -548,6 +580,7 @@ LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, l mFontBitmapCachep->nextOpenPos(width, pos_x, pos_y, bitmap_glyph_type, bitmap_num); LLFontGlyphInfo* gi = new LLFontGlyphInfo(glyph_index, requested_glyph_type); + gi->mChar = wch; gi->mXBitmapOffset = pos_x; gi->mYBitmapOffset = pos_y; gi->mBitmapEntry = std::make_pair(bitmap_glyph_type, bitmap_num); @@ -564,6 +597,14 @@ LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, l gi->mXAdvance = fontp->mFTFace->glyph->advance.x / 64.f; gi->mYAdvance = fontp->mFTFace->glyph->advance.y / 64.f; + if (mWeight > 0 && wch >= '0' && wch <= '9') + { + // Digits are supposed to be preloaded, and buffers + // refresh when new chars get added, so this lazy load + // should not cause any issues. + mMaxDigitWidth = llmax(mMaxDigitWidth, gi->mXAdvance); + } + insertGlyphInfo(wch, gi); if (requested_glyph_type != bitmap_glyph_type) @@ -799,6 +840,7 @@ void LLFontFreetype::resetBitmapCache() } mCharGlyphInfoMap.clear(); mFontBitmapCachep->reset(); + mMaxDigitWidth = 0.0f; // Adding default glyph is skipped for fallback fonts here as well as in loadFace(). // This if was added as fix for EXT-4971. diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h index d2164e8fa2..461e064766 100644 --- a/indra/llrender/llfontfreetype.h +++ b/indra/llrender/llfontfreetype.h @@ -76,6 +76,8 @@ struct LLFontGlyphInfo U32 mGlyphIndex; EFontGlyphType mGlyphType; + llwchar mChar; + // Metrics S32 mWidth; // In pixels @@ -147,6 +149,9 @@ public: F32 getXKerning(llwchar char_left, llwchar char_right) const; // Get the kerning between the two characters F32 getXKerning(const LLFontGlyphInfo* left_glyph_info, const LLFontGlyphInfo* right_glyph_info) const; // Get the kerning between the two characters + F32 getMaxDigitWidth() const { return mMaxDigitWidth; } + S32 getFontWeight() const { return mWeight; } + LLFontGlyphInfo* getGlyphInfo(llwchar wch, EFontGlyphType glyph_type) const; void reset(F32 vert_dpi, F32 horz_dpi); @@ -184,6 +189,7 @@ private: F32 mAscender; F32 mDescender; F32 mLineHeight; + mutable F32 mMaxDigitWidth; LLFT_Face mFTFace; diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 5d99c35047..bb5a12375e 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -345,6 +345,14 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons break; } + // Calculate horizontal offset for tabular numbers (center narrow digits) + F32 x_offset = 0.0f; + if (mFontFreetype->getFontWeight() > 0 && fgi->mChar >= '0' && fgi->mChar <= '9' && mFontFreetype->getMaxDigitWidth() > 0.0f) + { + // use mXAdvance directly here, since we don't want to get max width instead. + x_offset = (mFontFreetype->getMaxDigitWidth() - fgi->mXAdvance) * 0.5f; + } + // Draw the text at the appropriate location //Specify vertices and texture coordinates LLRectf uv_rect((fgi->mXBitmapOffset) * inv_width, @@ -352,9 +360,9 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons (fgi->mXBitmapOffset + fgi->mWidth) * inv_width, (fgi->mYBitmapOffset - PAD_UVY) * inv_height); // snap glyph origin to whole screen pixel - LLRectf screen_rect((F32)ll_round(cur_render_x + (F32)fgi->mXBearing), + LLRectf screen_rect((F32)ll_round(cur_render_x + (F32)fgi->mXBearing + x_offset), (F32)ll_round(cur_render_y + (F32)fgi->mYBearing), - (F32)ll_round(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth, + (F32)ll_round(cur_render_x + (F32)fgi->mXBearing + x_offset) + (F32)fgi->mWidth, (F32)ll_round(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight); if (glyph_count >= GLYPH_BATCH_SIZE) @@ -375,7 +383,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons col, style_to_add, shadow, drop_shadow_strength); chars_drawn++; - cur_x += fgi->mXAdvance; + cur_x += mFontFreetype->getXAdvance(fgi); cur_y += fgi->mYAdvance; llwchar next_char = wstr[i+1]; |
