mirror of https://github.com/OpenTTD/OpenTTD
(svn r20296) -Fix: Fallback font selection due to missing glyphs did not work as intended.
parent
edf9b36b81
commit
f0ebe530ad
|
@ -53,6 +53,7 @@ uint GetGlyphWidth(FontSize size, uint32 key);
|
||||||
* @param settings the settings to overwrite the fontname of.
|
* @param settings the settings to overwrite the fontname of.
|
||||||
* @param language_isocode the language, e.g. en_GB.
|
* @param language_isocode the language, e.g. en_GB.
|
||||||
* @param winlangid the language ID windows style.
|
* @param winlangid the language ID windows style.
|
||||||
|
* @param str Sample string.
|
||||||
* @return true if a font has been set, false otherwise.
|
* @return true if a font has been set, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, const char *str);
|
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, const char *str);
|
||||||
|
|
|
@ -1572,6 +1572,38 @@ const char *GetCurrentLanguageIsoCode()
|
||||||
return _langpack->isocode;
|
return _langpack->isocode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether there are glyphs missing in the current language.
|
||||||
|
* @param Pointer to an address for storing the text pointer.
|
||||||
|
* @return If glyphs are missing, return \c true, else return \false.
|
||||||
|
* @pre *str must not be \c NULL.
|
||||||
|
* @post If \c true is returned, *str points to a string that is found to contain at least one missing glyph.
|
||||||
|
*/
|
||||||
|
static bool FindMissingGlyphs(const char **str)
|
||||||
|
{
|
||||||
|
const Sprite *question_mark = GetGlyph(FS_NORMAL, '?');
|
||||||
|
for (uint i = 0; i != 32; i++) {
|
||||||
|
for (uint j = 0; j < _langtab_num[i]; j++) {
|
||||||
|
const char *text = _langpack_offs[_langtab_start[i] + j];
|
||||||
|
*str = text;
|
||||||
|
for (WChar c = Utf8Consume(&text); c != '\0'; c = Utf8Consume(&text)) {
|
||||||
|
if (c == SCC_SETX) {
|
||||||
|
/* SetX is, together with SetXY as special character that
|
||||||
|
* uses the next (two) characters as data points. We have
|
||||||
|
* to skip those, otherwise the UTF8 reading will go haywire. */
|
||||||
|
text++;
|
||||||
|
} else if (c == SCC_SETXY) {
|
||||||
|
text += 2;
|
||||||
|
} else if (IsPrintable(c) && c != '?' && GetGlyph(FS_NORMAL, c) == question_mark) {
|
||||||
|
/* The character is printable, but not in the normal font. This is the case we were testing for. */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether the currently loaded language pack
|
* Check whether the currently loaded language pack
|
||||||
* uses characters that the currently loaded font
|
* uses characters that the currently loaded font
|
||||||
|
@ -1589,39 +1621,18 @@ void CheckForMissingGlyphsInLoadedLanguagePack()
|
||||||
* automatically choose another font. This resets that choice. */
|
* automatically choose another font. This resets that choice. */
|
||||||
UninitFreeType();
|
UninitFreeType();
|
||||||
InitFreeType();
|
InitFreeType();
|
||||||
bool retry = false;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (;;) {
|
const char *str;
|
||||||
const Sprite *question_mark = GetGlyph(FS_NORMAL, '?');
|
bool bad_font = FindMissingGlyphs(&str);
|
||||||
|
|
||||||
for (uint i = 0; i != 32; i++) {
|
|
||||||
for (uint j = 0; j < _langtab_num[i]; j++) {
|
|
||||||
const char *string = _langpack_offs[_langtab_start[i] + j];
|
|
||||||
WChar c;
|
|
||||||
while ((c = Utf8Consume(&string)) != '\0') {
|
|
||||||
if (c == SCC_SETX) {
|
|
||||||
/*
|
|
||||||
* SetX is, together with SetXY as special character that
|
|
||||||
* uses the next (two) characters as data points. We have
|
|
||||||
* to skip those, otherwise the UTF8 reading will go
|
|
||||||
* haywire.
|
|
||||||
*/
|
|
||||||
string++;
|
|
||||||
} else if (c == SCC_SETXY) {
|
|
||||||
string += 2;
|
|
||||||
} else if (IsPrintable(c) && c != '?' && GetGlyph(FS_NORMAL, c) == question_mark) {
|
|
||||||
#ifdef WITH_FREETYPE
|
#ifdef WITH_FREETYPE
|
||||||
if (!retry) {
|
if (bad_font) {
|
||||||
/* We found an unprintable character... lets try whether we can
|
/* We found an unprintable character... lets try whether we can find
|
||||||
* find a fallback font that can print the characters in the
|
* a fallback font that can print the characters in the current language. */
|
||||||
* current language. */
|
|
||||||
retry = true;
|
|
||||||
|
|
||||||
FreeTypeSettings backup;
|
FreeTypeSettings backup;
|
||||||
memcpy(&backup, &_freetype, sizeof(backup));
|
memcpy(&backup, &_freetype, sizeof(backup));
|
||||||
|
|
||||||
bool success = SetFallbackFont(&_freetype, _langpack->isocode, _langpack->winlangid, string);
|
bool success = SetFallbackFont(&_freetype, _langpack->isocode, _langpack->winlangid, str);
|
||||||
if (success) {
|
if (success) {
|
||||||
UninitFreeType();
|
UninitFreeType();
|
||||||
InitFreeType();
|
InitFreeType();
|
||||||
|
@ -1629,28 +1640,25 @@ void CheckForMissingGlyphsInLoadedLanguagePack()
|
||||||
|
|
||||||
memcpy(&_freetype, &backup, sizeof(backup));
|
memcpy(&_freetype, &backup, sizeof(backup));
|
||||||
|
|
||||||
if (success) continue;
|
if (success) {
|
||||||
} else {
|
bad_font = FindMissingGlyphs(&str);
|
||||||
|
if (bad_font) {
|
||||||
/* Our fallback font does miss characters too, so keep the
|
/* Our fallback font does miss characters too, so keep the
|
||||||
* user chosen font as that is more likely to be any good than
|
* user chosen font as that is more likely to be any good than
|
||||||
* the wild guess we made */
|
* the wild guess we made */
|
||||||
UninitFreeType();
|
UninitFreeType();
|
||||||
InitFreeType();
|
InitFreeType();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
/*
|
|
||||||
* The character is printable, but not in the normal font.
|
if (bad_font) {
|
||||||
* This is the case we were testing for. In this case we
|
/* All attempts have failed. Display an error. As we do not want the string to be translated by
|
||||||
* have to show the error. As we do not want the string to
|
* the translators, we 'force' it into the binary and 'load' it via a BindCString. To do this
|
||||||
* be translated by the translators, we 'force' it into the
|
* properly we have to set the colour of the string, otherwise we end up with a lot of artefacts.
|
||||||
* binary and 'load' it via a BindCString. To do this
|
* The colour 'character' might change in the future, so for safety we just Utf8 Encode it into
|
||||||
* properly we have to set the colour of the string,
|
* the string, which takes exactly three characters, so it replaces the "XXX" with the colour marker. */
|
||||||
* otherwise we end up with a lot of artefacts. 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.
|
|
||||||
*/
|
|
||||||
static char *err_str = strdup("XXXThe current font is missing some of the characters used in the texts for this language. Read the readme to see how to solve this.");
|
static char *err_str = strdup("XXXThe current font is missing some of the characters used in the texts for this language. Read the readme to see how to solve this.");
|
||||||
Utf8Encode(err_str, SCC_YELLOW);
|
Utf8Encode(err_str, SCC_YELLOW);
|
||||||
SetDParamStr(0, err_str);
|
SetDParamStr(0, err_str);
|
||||||
|
@ -1660,11 +1668,6 @@ void CheckForMissingGlyphsInLoadedLanguagePack()
|
||||||
LoadStringWidthTable();
|
LoadStringWidthTable();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update the font with cache */
|
/* Update the font with cache */
|
||||||
LoadStringWidthTable();
|
LoadStringWidthTable();
|
||||||
|
|
Loading…
Reference in New Issue