@@ -189,5 +189,5 @@ bool HasAntialiasedFonts()
#if !defined(_WIN32) && !defined(__APPLE__) && !defined(WITH_FONTCONFIG) && !defined(WITH_COCOA)
bool SetFallbackFont(FontCacheSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback) { return false; }
bool SetFallbackFont(FontCacheSettings *settings, const std::string &language_isocode, int winlangid, MissingGlyphSearcher *callback) { return false; }
#endif /* !defined(_WIN32) && !defined(__APPLE__) && !defined(WITH_FONTCONFIG) && !defined(WITH_COCOA) */
@@ -37,6 +37,6 @@ FT_Error GetFontByFaceName(const char *f
* @param callback The function to call to check for missing glyphs.
* @return true if a font has been set, false otherwise.
*/
bool SetFallbackFont(struct FontCacheSettings *settings, const char *language_isocode, int winlangid, class MissingGlyphSearcher *callback);
bool SetFallbackFont(struct FontCacheSettings *settings, const std::string &language_isocode, int winlangid, class MissingGlyphSearcher *callback);
#endif
@@ -24,28 +24,26 @@
#include "safeguards.h"
bool SetFallbackFont(FontCacheSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback)
bool SetFallbackFont(FontCacheSettings *settings, const std::string &language_isocode, int winlangid, MissingGlyphSearcher *callback)
{
/* Determine fallback font using CoreText. This uses the language isocode
* to find a suitable font. CoreText is available from 10.5 onwards. */
char lang[16];
if (strcmp(language_isocode, "zh_TW") == 0) {
std::string lang;
if (language_isocode == "zh_TW") {
/* Traditional Chinese */
strecpy(lang, "zh-Hant", lastof(lang));
} else if (strcmp(language_isocode, "zh_CN") == 0) {
lang = "zh-Hant";
} else if (language_isocode == "zh_CN") {
/* Simplified Chinese */
strecpy(lang, "zh-Hans", lastof(lang));
lang = "zh-Hans";
} else {
/* Just copy the first part of the isocode. */
strecpy(lang, language_isocode, lastof(lang));
char *sep = strchr(lang, '_');
if (sep != nullptr) *sep = '\0';
lang = language_isocode.substr(0, language_isocode.find('_'));
}
/* Create a font descriptor matching the wanted language and latin (english) glyphs.
* Can't use CFAutoRelease here for everything due to the way the dictionary has to be created. */
CFStringRef lang_codes[2];
lang_codes[0] = CFStringCreateWithCString(kCFAllocatorDefault, lang, kCFStringEncodingUTF8);
lang_codes[0] = CFStringCreateWithCString(kCFAllocatorDefault, lang.c_str(), kCFStringEncodingUTF8);
lang_codes[1] = CFSTR("en");
CFArrayRef lang_arr = CFArrayCreate(kCFAllocatorDefault, (const void **)lang_codes, lengthof(lang_codes), &kCFTypeArrayCallBacks);
CFAutoRelease<CFDictionaryRef> lang_attribs(CFDictionaryCreate(kCFAllocatorDefault, const_cast<const void **>(reinterpret_cast<const void *const *>(&kCTFontLanguagesAttribute)), (const void **)&lang_arr, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
@@ -95,7 +95,7 @@ FT_Error GetFontByFaceName(const char *f
return err;
bool ret = false;
@@ -107,13 +107,10 @@ bool SetFallbackFont(FontCacheSettings *
/* Fontconfig doesn't handle full language isocodes, only the part
* before the _ of e.g. en_GB is used, so "remove" everything after
* the _. */
seprintf(lang, lastof(lang), ":lang=%s", language_isocode);
char *split = strchr(lang, '_');
if (split != nullptr) *split = '\0';
std::string lang = language_isocode.substr(0, language_isocode.find('_'));
/* First create a pattern to match the wanted language. */
FcPattern *pat = FcNameParse((FcChar8 *)lang);
FcPattern *pat = FcNameParse((const FcChar8 *)lang.c_str());
/* We only want to know the filename. */
FcObjectSet *os = FcObjectSetBuild(FC_FILE, FC_SPACING, FC_SLANT, FC_WEIGHT, nullptr);
/* Get the list of filenames matching the wanted language. */
@@ -88,7 +88,7 @@ static int CALLBACK EnumFontCallback(con
return 0; // stop enumerating
Debug(fontcache, 1, "Trying fallback fonts");
EFCParam langInfo;
Status change: