This should fix Japanese fonts not working

This commit is contained in:
pelya
2023-05-19 23:06:31 +03:00
committed by Miguel Horta
parent e2f2a4dfa3
commit 9d4e769ab2
3 changed files with 25 additions and 16 deletions

View File

@@ -109,7 +109,8 @@ bool SetFallbackFont(FontCacheSettings *settings, const char *language_isocode,
if (split != nullptr) *split = '\0'; if (split != nullptr) *split = '\0';
/* First create a pattern to match the wanted language. */ /* First create a pattern to match the wanted language. */
FcPattern *pat = FcNameParse((FcChar8 *)lang); //FcPattern *pat = FcNameParse((FcChar8*)lang);
FcPattern *pat = FcPatternCreate();
/* We only want to know the filename. */ /* We only want to know the filename. */
FcObjectSet *os = FcObjectSetBuild(FC_FILE, FC_SPACING, FC_SLANT, FC_WEIGHT, nullptr); FcObjectSet *os = FcObjectSetBuild(FC_FILE, FC_SPACING, FC_SLANT, FC_WEIGHT, nullptr);
/* Get the list of filenames matching the wanted language. */ /* Get the list of filenames matching the wanted language. */
@@ -122,6 +123,7 @@ bool SetFallbackFont(FontCacheSettings *settings, const char *language_isocode,
if (fs != nullptr) { if (fs != nullptr) {
int best_weight = -1; int best_weight = -1;
const char *best_font = nullptr; const char *best_font = nullptr;
int best_missing_glypths = 65536;
for (int i = 0; i < fs->nfont; i++) { for (int i = 0; i < fs->nfont; i++) {
FcPattern *font = fs->fonts[i]; FcPattern *font = fs->fonts[i];
@@ -131,28 +133,31 @@ bool SetFallbackFont(FontCacheSettings *settings, const char *language_isocode,
if (res != FcResultMatch || file == nullptr) { if (res != FcResultMatch || file == nullptr) {
continue; continue;
} }
int missing = 0;
/* Get a font with the right spacing .*/ /* Get a font with the right spacing .*/
int value = 0; int value = 0;
FcPatternGetInteger(font, FC_SPACING, 0, &value); FcPatternGetInteger(font, FC_SPACING, 0, &value);
if (callback->Monospace() != (value == FC_MONO) && value != FC_DUAL) continue; if (callback->Monospace() != (value == FC_MONO) && value != FC_DUAL) missing += 1;
/* Do not use those that explicitly say they're slanted. */ /* Do not use those that explicitly say they're slanted. */
FcPatternGetInteger(font, FC_SLANT, 0, &value); FcPatternGetInteger(font, FC_SLANT, 0, &value);
if (value != 0) continue; if (value != 0) missing += 1;
/* We want the fatter font as they look better at small sizes. */ /* We want the fatter font as they look better at small sizes. */
FcPatternGetInteger(font, FC_WEIGHT, 0, &value); FcPatternGetInteger(font, FC_WEIGHT, 0, &value);
if (value <= best_weight) continue; if (value <= best_weight) missing += 1;
callback->SetFontNames(settings, (const char *)file); callback->SetFontNames(settings, (const char *)file);
bool missing = callback->FindMissingGlyphs(); missing += callback->FindMissingGlyphs();
Debug(fontcache, 1, "Font \"{}\" misses{} glyphs", file, missing ? "" : " no"); Debug(fontcache, 1, "Font \"{}\" misses {} glyphs for lang {}", file, missing, lang);
if (!missing) { if (missing < best_missing_glypths) {
best_weight = value; best_weight = value;
best_font = (const char *)file; best_font = (const char *)file;
best_missing_glypths = missing;
if (missing == 0) break;
} }
} }
@@ -160,6 +165,7 @@ bool SetFallbackFont(FontCacheSettings *settings, const char *language_isocode,
ret = true; ret = true;
callback->SetFontNames(settings, best_font); callback->SetFontNames(settings, best_font);
InitFontCache(callback->Monospace()); InitFontCache(callback->Monospace());
Debug(fontcache, 1, "Selected font {} for lang {}", best_font, lang);
} }
/* Clean up the list of filenames. */ /* Clean up the list of filenames. */

View File

@@ -2035,7 +2035,7 @@ const char *GetCurrentLanguageIsoCode()
* Check whether there are glyphs missing in the current language. * Check whether there are glyphs missing in the current language.
* @return If glyphs are missing, return \c true, else return \c false. * @return If glyphs are missing, return \c true, else return \c false.
*/ */
bool MissingGlyphSearcher::FindMissingGlyphs() int MissingGlyphSearcher::FindMissingGlyphs()
{ {
InitFontCache(this->Monospace()); InitFontCache(this->Monospace());
const Sprite *question_mark[FS_END]; const Sprite *question_mark[FS_END];
@@ -2045,6 +2045,7 @@ bool MissingGlyphSearcher::FindMissingGlyphs()
} }
this->Reset(); this->Reset();
int missing = 0;
for (const char *text = this->NextString(); text != nullptr; text = this->NextString()) { for (const char *text = this->NextString(); text != nullptr; text = this->NextString()) {
FontSize size = this->DefaultSize(); FontSize size = this->DefaultSize();
for (WChar c = Utf8Consume(&text); c != '\0'; c = Utf8Consume(&text)) { for (WChar c = Utf8Consume(&text); c != '\0'; c = Utf8Consume(&text)) {
@@ -2063,11 +2064,11 @@ bool MissingGlyphSearcher::FindMissingGlyphs()
} }
Debug(fontcache, 0, "Font is missing glyphs to display char 0x{:X} in {} font size", (int)c, size_name); Debug(fontcache, 0, "Font is missing glyphs to display char 0x{:X} in {} font size", (int)c, size_name);
return true; missing++;
} }
} }
} }
return false; return missing;
} }
/** Helper for searching through the language pack. */ /** Helper for searching through the language pack. */
@@ -2142,7 +2143,7 @@ void CheckForMissingGlyphs(bool base_font, MissingGlyphSearcher *searcher)
if (bad_font) { if (bad_font) {
/* We found an unprintable character... lets try whether we can find /* We found an unprintable character... lets try whether we can find
* a fallback font that can print the characters in the current language. */ * a fallback font that can print the characters in the current language. */
bool any_font_configured = !_fcsettings.medium.font.empty(); //bool any_font_configured = !_fcsettings.medium.font.empty();
FontCacheSettings backup = _fcsettings; FontCacheSettings backup = _fcsettings;
_fcsettings.mono.os_handle = nullptr; _fcsettings.mono.os_handle = nullptr;
@@ -2152,17 +2153,19 @@ void CheckForMissingGlyphs(bool base_font, MissingGlyphSearcher *searcher)
_fcsettings = backup; _fcsettings = backup;
if (!bad_font && any_font_configured) { if (!bad_font) {
/* If the user configured a bad font, and we found a better one, /* Show that we loaded fallback font. To do this properly we have
* show that we loaded the better font instead of the configured one. * to set the colour of the string, otherwise we end up with a lot
* The colour 'character' might change in the * of artifacts.* The colour 'character' might change in the
* future, so for safety we just Utf8 Encode it into the string, * future, so for safety we just Utf8 Encode it into the string,
* which takes exactly three characters, so it replaces the "XXX" * which takes exactly three characters, so it replaces the "XXX"
* with the colour marker. */ * with the colour marker. */
#if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
static char *err_str = stredup("XXXThe current font is missing some of the characters used in the texts for this language. Using system fallback font instead."); static char *err_str = stredup("XXXThe current font is missing some of the characters used in the texts for this language. Using system fallback font instead.");
Utf8Encode(err_str, SCC_YELLOW); Utf8Encode(err_str, SCC_YELLOW);
SetDParamStr(0, err_str); SetDParamStr(0, err_str);
ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_WARNING); ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_WARNING);
#endif
} }
if (bad_font && base_font) { if (bad_font && base_font) {

View File

@@ -276,7 +276,7 @@ public:
*/ */
virtual void SetFontNames(struct FontCacheSettings *settings, const char *font_name, const void *os_data = nullptr) = 0; virtual void SetFontNames(struct FontCacheSettings *settings, const char *font_name, const void *os_data = nullptr) = 0;
bool FindMissingGlyphs(); int FindMissingGlyphs();
}; };
void CheckForMissingGlyphs(bool base_font = true, MissingGlyphSearcher *search = nullptr); void CheckForMissingGlyphs(bool base_font = true, MissingGlyphSearcher *search = nullptr);