mirror of
https://gitea.wildfiregames.com/0ad/0ad.git
synced 2026-09-21 20:06:40 +00:00
Fix font fallback for regional locale variants
Add short locale (e.g. "zh") as intermediate fallback between the full locale (e.g. "zh_HK") and the global default fonts. Previously, regional variants without explicit font config entries would skip directly to global Latin fonts, causing CJK characters to display as "xxxxx". Reported at: https://wildfiregames.com/forum/topic/141392-0ad-alpah-28-only-show-some-english-words-correctly-most-words-are-xxxxx
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
#include "lib/file/vfs/vfs_path.h"
|
||||
#include "lib/posix/posix.h"
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/containers/StaticVector.h"
|
||||
#include "ps/CStr.h"
|
||||
#include "ps/CStrInternStatic.h"
|
||||
#include "ps/ConfigDB.h"
|
||||
@@ -174,27 +175,39 @@ CFont* CFontManager::LoadFont(CStrIntern fontName, CStrIntern locale)
|
||||
// Check for font configuration or fallback.
|
||||
const std::map<CStr, CConfigValueSet> fontToSearch{[&]
|
||||
{
|
||||
std::vector<std::string> candidateFonts;
|
||||
// 3 types * 2 (bold, italic).
|
||||
candidateFonts.reserve(6);
|
||||
// full locale + short locale + global each with up to 3 styles.
|
||||
PS::StaticVector<std::string, 9> candidateFonts;
|
||||
|
||||
auto addCandidate{ [&](const std::string_view localeName)
|
||||
{
|
||||
std::string localePart{localeName};
|
||||
if (!localePart.empty())
|
||||
localePart.push_back('.');
|
||||
if (fontSpec.bold)
|
||||
candidateFonts.push_back(fmt::format("fonts.{}{}.bold", localePart, fontSpec.type));
|
||||
if (fontSpec.italic)
|
||||
candidateFonts.push_back(fmt::format("fonts.{}{}.italic", localePart, fontSpec.type));
|
||||
candidateFonts.push_back(fmt::format("fonts.{}{}.regular", localePart, fontSpec.type));
|
||||
}};
|
||||
|
||||
// TODO: explicit Locale like RTL or Arabic fonts.
|
||||
// 1. Locale-specific fonts first
|
||||
// 1. Locale-specific fonts first.
|
||||
if (!localeToUse.empty())
|
||||
{
|
||||
if (fontSpec.bold)
|
||||
candidateFonts.push_back(fmt::format("fonts.{}.{}.bold", localeToUse, fontSpec.type));
|
||||
if (fontSpec.italic)
|
||||
candidateFonts.push_back(fmt::format("fonts.{}.{}.italic", localeToUse, fontSpec.type));
|
||||
candidateFonts.push_back(fmt::format("fonts.{}.{}.regular", localeToUse, fontSpec.type));
|
||||
// Full locale first, e.g. zh_TW.
|
||||
addCandidate(localeToUse);
|
||||
|
||||
// Then short locale, e.g. zh.
|
||||
if (const size_t pos{localeToUse.find('_')}; pos != std::string::npos)
|
||||
{
|
||||
const std::string shortLocale{localeToUse.substr(0, pos)};
|
||||
addCandidate(shortLocale);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Then global fonts
|
||||
if (fontSpec.bold)
|
||||
candidateFonts.push_back(fmt::format("fonts.{}.bold", fontSpec.type));
|
||||
if (fontSpec.italic)
|
||||
candidateFonts.push_back(fmt::format("fonts.{}.italic", fontSpec.type));
|
||||
candidateFonts.push_back(fmt::format("fonts.{}.regular", fontSpec.type));
|
||||
const std::string globalLocale{};
|
||||
addCandidate(globalLocale);
|
||||
|
||||
for (const std::string& key : candidateFonts)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user