1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-23 14:54:30 +01:00

Fix #18433: TTF fonts can not be located when font names are translated

The issue here is that fontconfig may report the name of a given
font face in a language specified by the current locale, while the
OpenRCT2 font code checks the result against an English name.

This fix addresses the issue by temporarily changing the environment
LANG variable to use the default C locale, which should guarantee
English/ASCII names are returned by fontconfig. It uses an RAII
mechanism to ensure that the modified environment variable is restored
to its original value on exiting GetFontPath.
This commit is contained in:
Briar
2025-02-21 07:16:20 -08:00
committed by GitHub
parent a62562dcf8
commit e664bcebb6
2 changed files with 43 additions and 0 deletions

View File

@@ -16,6 +16,7 @@
#include <limits.h>
#include <locale.h>
#include <pwd.h>
#include <stdlib.h>
#include <unistd.h>
#include <vector>
#if defined(__FreeBSD__) || defined(__NetBSD__)
@@ -39,6 +40,43 @@
namespace OpenRCT2::Platform
{
// EnvLangGuard allows us to temporarily set the user's locale
// to the generic C locale, in order to trick fontconfig into
// returning an English font face name, while using RAII to avoid
// changing locale settings in other parts of the program
class EnvLangGuard
{
public:
EnvLangGuard();
~EnvLangGuard();
private:
// GNU recommends scripts/programs set LC_ALL to override
// locales for uniform testing, clearing it after should let
// LANG and other locale settings operate normally
static constexpr const char* _kOverrideVarName{ "LC_ALL" };
static constexpr const char* _kTargetLocale{ "C.UTF-8" };
};
EnvLangGuard::EnvLangGuard()
{
int overwrite = 1;
int result = setenv(_kOverrideVarName, _kTargetLocale, overwrite);
if (result != 0)
{
LOG_VERBOSE("Could not update locale for font selection, some fonts may display incorrectly");
}
}
EnvLangGuard::~EnvLangGuard()
{
int result = unsetenv(_kOverrideVarName);
if (result != 0)
{
LOG_VERBOSE("Could not restore user locale");
}
}
std::string GetFolderPath(SPECIAL_FOLDER folder)
{
switch (folder)
@@ -352,6 +390,10 @@ namespace OpenRCT2::Platform
#ifndef NO_TTF
std::string GetFontPath(const TTFFontDescriptor& font)
{
// set LANG to portable C.UTF-8 so font face names from fontconfig
// are reported in English
EnvLangGuard elg;
LOG_VERBOSE("Looking for font %s with FontConfig.", font.font_name);
FcConfig* config = FcInitLoadConfigAndFonts();
if (!config)