Fix default font for CJK and other translations (fix #5210)

Now we use the correct fallback font with its size for non-existent
glyph in the sprite sheet font.
This commit is contained in:
David Capello 2025-06-11 12:49:52 -03:00
parent 68342bdb66
commit af6e8b65c3
8 changed files with 33 additions and 30 deletions

View File

@ -34,14 +34,14 @@
type="spritesheet"
descent="2"
file="aseprite_font.png">
<fallback font="Unicode" size="8" />
<fallback font="Unicode" size="14" />
</font>
<font name="Aseprite Mini"
type="spritesheet"
descent="1"
file="aseprite_mini.png">
<fallback font="Unicode" size="6" />
<fallback font="Unicode" size="10" />
</font>
</fonts>

2
laf

@ -1 +1 @@
Subproject commit 7d30a582e5c8655fab368c4d61f3125855a7b30d
Subproject commit 81478c15f5be116651327e8c615265aa19c78be2

View File

@ -1372,8 +1372,8 @@ private:
if (!item)
return;
const std::string lang = item->langId();
const bool state = (lang == "ar" || lang == "ja" || lang == "ko" || lang == "yue_Hant" ||
lang == "zh_Hans" || lang == "zh_Hant");
const bool state = (lang == "ar" || lang == "ja" || lang == "ko" || lang == "th" ||
lang == "yue_Hant" || lang == "zh_Hans" || lang == "zh_Hant");
fontWarningFiller()->setVisible(state);
fontWarning()->setVisible(state);
layout();

View File

@ -15,6 +15,7 @@
#include "text/font_mgr.h"
#include "text/sprite_sheet_font.h"
#include "ui/manager.h"
#include "ui/scale.h"
#include <set>
@ -87,9 +88,9 @@ text::FontRef FontData::getFont(text::FontMgrRef& fontMgr, float size)
// Load fallback
if (m_fallback) {
text::FontRef fallback = m_fallback->getFont(fontMgr, m_fallbackSize);
text::FontRef fallback = m_fallback->getFont(fontMgr, m_fallbackSize * ui::guiscale());
if (font)
font->setFallback(fallback.get());
font->setFallback(fallback);
else
return fallback; // Don't double-cache the fallback font
}

View File

@ -311,6 +311,9 @@ static FontData* load_font(const XMLElement* xmlFont, const std::string& xmlFile
if (!font && systemStr) {
font = try_to_load_system_font(xmlFont);
}
if (font && nameStr)
font->setName(nameStr);
}
else {
throw base::Exception(
@ -1440,14 +1443,10 @@ void SkinTheme::drawEntryText(ui::Graphics* g, ui::Entry* widget)
IntersectClip clip(g, bounds);
if (clip) {
text::FontMetrics metrics;
widget->font()->metrics(&metrics);
const float baselineShift = -metrics.ascent - widget->textBlob()->baseline();
g->drawTextWithDelegate(std::string(pos, textString.end()), // TODO use a string_view()
colors.text(),
ColorNone,
gfx::Point(bounds.x, bounds.y + baselineShift),
bounds.origin(),
&delegate);
}
}

View File

@ -136,7 +136,7 @@ class StatusBar::Indicators : public HBox {
g->drawText(text(),
textColor,
ColorNone,
Point(rc.x, guiscaled_center(rc.y, rc.h, font()->lineHeight())));
Point(rc.x, guiscaled_center(rc.y, rc.h, textHeight())));
}
}
};

View File

@ -656,10 +656,8 @@ void Theme::measureLayer(const Widget* widget,
}
else {
// We can use Widget::textSize() because we're going to use
// the widget font and, probably, the cached TextBlob width.
text::FontMetrics metrics;
widget->font()->metrics(&metrics);
textSize = gfx::Size(widget->textSize().w, metrics.descent - metrics.ascent);
// the widget font and, probably, the cached TextBlob size.
textSize = widget->textSize();
}
textHint.offset(layer.offset());
@ -1044,7 +1042,8 @@ void Theme::drawMnemonicUnderline(Graphics* g,
decode.next(); // Go to first char
size_t glyphUtf8Begin = 0;
textBlob->visitRuns([g, mnemonicUtf8Pos, pt, &paint, &decode, &glyphUtf8Begin, &text](
float baseline = textBlob->baseline();
textBlob->visitRuns([g, baseline, mnemonicUtf8Pos, pt, &paint, &decode, &glyphUtf8Begin, &text](
text::TextBlob::RunInfo& info) {
for (int i = 0; i < info.glyphCount; ++i, decode.next()) {
// TODO This doesn't work because the TextBlob::RunInfo::clusters is nullptr at this
@ -1061,11 +1060,10 @@ void Theme::drawMnemonicUnderline(Graphics* g,
if (thickness < 1.0f)
thickness = 1.0f;
mnemonicBounds = gfx::RectF(
pt.x + mnemonicBounds.x,
pt.y - metrics.ascent + metrics.underlinePosition * guiscale(),
mnemonicBounds.w,
thickness);
mnemonicBounds = gfx::RectF(pt.x + mnemonicBounds.x,
pt.y + baseline + metrics.underlinePosition * guiscale(),
mnemonicBounds.w,
thickness);
g->drawRect(mnemonicBounds, paint);
break;

View File

@ -965,6 +965,9 @@ int Widget::textWidth() const
int Widget::textHeight() const
{
if (auto blob = textBlob())
return blob->textHeight();
text::FontMetrics metrics;
font()->metrics(&metrics);
return metrics.descent - metrics.ascent;
@ -1896,14 +1899,16 @@ text::ShaperFeatures Widget::onGetTextShaperFeatures() const
float Widget::onGetTextBaseline() const
{
text::FontMetrics metrics;
font()->metrics(&metrics);
// Here we only use the descent+ascent to measure the text height,
// without the metrics.leading part (which is the used to separate
// text lines in a paragraph, but here'd make widgets too big)
const float textHeight = metrics.descent - metrics.ascent;
// Here we use TextBlob::textHeight() which is calculated as
// descent+ascent to measure the text height, without the
// metrics.leading part (which is the used to separate text lines in
// a paragraph, but here'd make widgets too big).
text::TextBlobRef blob = textBlob();
if (!blob)
return 0.0f;
const gfx::Rect rc = clientChildrenBounds();
return guiscaled_center(rc.y, rc.h, textHeight) - metrics.ascent;
return guiscaled_center(rc.y, rc.h, blob->textHeight()) + blob->baseline();
}
void Widget::onDragEnter(DragEvent& e)