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';
/* 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. */
FcObjectSet *os = FcObjectSetBuild(FC_FILE, FC_SPACING, FC_SLANT, FC_WEIGHT, nullptr);
/* Get the list of filenames matching the wanted language. */
@@ -122,6 +123,7 @@ bool SetFallbackFont(FontCacheSettings *settings, const char *language_isocode,
if (fs != nullptr) {
int best_weight = -1;
const char *best_font = nullptr;
int best_missing_glypths = 65536;
for (int i = 0; i < fs->nfont; i++) {
FcPattern *font = fs->fonts[i];
@@ -131,28 +133,31 @@ bool SetFallbackFont(FontCacheSettings *settings, const char *language_isocode,
if (res != FcResultMatch || file == nullptr) {
continue;
}
int missing = 0;
/* Get a font with the right spacing .*/
int value = 0;
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. */
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. */
FcPatternGetInteger(font, FC_WEIGHT, 0, &value);
if (value <= best_weight) continue;
if (value <= best_weight) missing += 1;
callback->SetFontNames(settings, (const char *)file);
bool missing = callback->FindMissingGlyphs();
Debug(fontcache, 1, "Font \"{}\" misses{} glyphs", file, missing ? "" : " no");
missing += callback->FindMissingGlyphs();
Debug(fontcache, 1, "Font \"{}\" misses {} glyphs for lang {}", file, missing, lang);
if (!missing) {
if (missing < best_missing_glypths) {
best_weight = value;
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;
callback->SetFontNames(settings, best_font);
InitFontCache(callback->Monospace());
Debug(fontcache, 1, "Selected font {} for lang {}", best_font, lang);
}
/* 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.
* @return If glyphs are missing, return \c true, else return \c false.
*/
bool MissingGlyphSearcher::FindMissingGlyphs()
int MissingGlyphSearcher::FindMissingGlyphs()
{
InitFontCache(this->Monospace());
const Sprite *question_mark[FS_END];
@@ -2045,6 +2045,7 @@ bool MissingGlyphSearcher::FindMissingGlyphs()
}
this->Reset();
int missing = 0;
for (const char *text = this->NextString(); text != nullptr; text = this->NextString()) {
FontSize size = this->DefaultSize();
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);
return true;
missing++;
}
}
}
return false;
return missing;
}
/** Helper for searching through the language pack. */
@@ -2142,7 +2143,7 @@ void CheckForMissingGlyphs(bool base_font, MissingGlyphSearcher *searcher)
if (bad_font) {
/* We found an unprintable character... lets try whether we can find
* 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;
_fcsettings.mono.os_handle = nullptr;
@@ -2152,17 +2153,19 @@ void CheckForMissingGlyphs(bool base_font, MissingGlyphSearcher *searcher)
_fcsettings = backup;
if (!bad_font && any_font_configured) {
/* If the user configured a bad font, and we found a better one,
* show that we loaded the better font instead of the configured one.
* The colour 'character' might change in the
if (!bad_font) {
/* Show that we loaded fallback font. To do this properly we have
* to set the colour of the string, otherwise we end up with a lot
* of artifacts.* The colour 'character' might change in the
* future, so for safety we just Utf8 Encode it into the string,
* which takes exactly three characters, so it replaces the "XXX"
* 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.");
Utf8Encode(err_str, SCC_YELLOW);
SetDParamStr(0, err_str);
ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_WARNING);
#endif
}
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;
bool FindMissingGlyphs();
int FindMissingGlyphs();
};
void CheckForMissingGlyphs(bool base_font = true, MissingGlyphSearcher *search = nullptr);