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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user