mirror of https://github.com/OpenTTD/OpenTTD
(svn r23265) -Codechange: replace the setfallbackfont callback function with a class to call back
parent
32b28bb868
commit
447884fddb
|
@ -13,6 +13,7 @@
|
|||
#include "fontcache.h"
|
||||
#include "blitter/factory.hpp"
|
||||
#include "core/math_func.hpp"
|
||||
#include "strings_func.h"
|
||||
|
||||
#include "table/sprites.h"
|
||||
#include "table/control_codes.h"
|
||||
|
@ -289,7 +290,7 @@ err1:
|
|||
struct EFCParam {
|
||||
FreeTypeSettings *settings;
|
||||
LOCALESIGNATURE locale;
|
||||
SetFallbackFontCallback *callback;
|
||||
MissingGlyphSearcher *callback;
|
||||
};
|
||||
|
||||
static int CALLBACK EnumFontCallback(const ENUMLOGFONTEX *logfont, const NEWTEXTMETRICEX *metric, DWORD type, LPARAM lParam)
|
||||
|
@ -349,12 +350,12 @@ static int CALLBACK EnumFontCallback(const ENUMLOGFONTEX *logfont, const NEWTEXT
|
|||
strecpy(info->settings->small_font, font_name, lastof(info->settings->small_font));
|
||||
strecpy(info->settings->medium_font, font_name, lastof(info->settings->medium_font));
|
||||
strecpy(info->settings->large_font, font_name, lastof(info->settings->large_font));
|
||||
if (info->callback(NULL)) return 1;
|
||||
if (info->callback->FindMissingGlyphs(NULL)) return 1;
|
||||
DEBUG(freetype, 1, "Fallback font: %s (%s)", font_name, english_name);
|
||||
return 0; // stop enumerating
|
||||
}
|
||||
|
||||
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, SetFallbackFontCallback *callback)
|
||||
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback)
|
||||
{
|
||||
DEBUG(freetype, 1, "Trying fallback fonts");
|
||||
EFCParam langInfo;
|
||||
|
@ -428,12 +429,12 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
|
|||
return err;
|
||||
}
|
||||
|
||||
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, SetFallbackFontCallback *callback)
|
||||
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback)
|
||||
{
|
||||
const char *str;
|
||||
bool result = false;
|
||||
|
||||
callback(&str);
|
||||
callback->FindMissingGlyphs(&str);
|
||||
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
|
||||
if (MacOSVersionIsAtLeast(10, 5, 0)) {
|
||||
|
@ -609,7 +610,7 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i
|
|||
}
|
||||
}
|
||||
|
||||
callback(NULL);
|
||||
callback->FindMissingGlyphs(NULL);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -683,7 +684,7 @@ static FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
|
|||
return err;
|
||||
}
|
||||
|
||||
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, SetFallbackFontCallback *callback)
|
||||
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback)
|
||||
{
|
||||
if (!FcInit()) return false;
|
||||
|
||||
|
@ -722,7 +723,7 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i
|
|||
strecpy(settings->medium_font, (const char*)file, lastof(settings->medium_font));
|
||||
strecpy(settings->large_font, (const char*)file, lastof(settings->large_font));
|
||||
|
||||
bool missing = callback(NULL);
|
||||
bool missing = callback->FindMissingGlyphs(NULL);
|
||||
DEBUG(freetype, 1, "Font \"%s\" misses%s glyphs", file, missing ? "" : " no");
|
||||
|
||||
if (!missing) {
|
||||
|
@ -741,7 +742,7 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i
|
|||
|
||||
#else /* without WITH_FONTCONFIG */
|
||||
FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) {return FT_Err_Cannot_Open_Resource;}
|
||||
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, SetFallbackFontCallback *callback) { return false; }
|
||||
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback) { return false; }
|
||||
#endif /* WITH_FONTCONFIG */
|
||||
|
||||
static void SetFontGeometry(FT_Face face, FontSize size, int pixels)
|
||||
|
|
|
@ -47,7 +47,6 @@ const Sprite *GetGlyph(FontSize size, uint32 key);
|
|||
uint GetGlyphWidth(FontSize size, uint32 key);
|
||||
bool GetDrawGlyphShadow();
|
||||
|
||||
typedef bool (SetFallbackFontCallback)(const char **);
|
||||
/**
|
||||
* We would like to have a fallback font as the current one
|
||||
* doesn't contain all characters we need.
|
||||
|
@ -58,7 +57,7 @@ typedef bool (SetFallbackFontCallback)(const char **);
|
|||
* @param callback The function to call to check for missing glyphs.
|
||||
* @return true if a font has been set, false otherwise.
|
||||
*/
|
||||
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, SetFallbackFontCallback *callback);
|
||||
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, class MissingGlyphSearcher *callback);
|
||||
|
||||
#else
|
||||
|
||||
|
|
|
@ -1750,46 +1750,75 @@ const char *GetCurrentLanguageIsoCode()
|
|||
* @return If glyphs are missing, return \c true, else return \false.
|
||||
* @post If \c true is returned and str is not NULL, *str points to a string that is found to contain at least one missing glyph.
|
||||
*/
|
||||
static bool FindMissingGlyphs(const char **str)
|
||||
bool MissingGlyphSearcher::FindMissingGlyphs(const char **str)
|
||||
{
|
||||
#ifdef WITH_FREETYPE
|
||||
UninitFreeType();
|
||||
InitFreeType();
|
||||
#endif
|
||||
const Sprite *question_mark[FS_END];
|
||||
FontSize size;
|
||||
|
||||
for (size = FS_BEGIN; size < FS_END; size++) {
|
||||
for (FontSize size = FS_BEGIN; size < FS_END; size++) {
|
||||
question_mark[size] = GetGlyph(size, '?');
|
||||
}
|
||||
|
||||
for (uint i = 0; i != 32; i++) {
|
||||
for (uint j = 0; j < _langtab_num[i]; j++) {
|
||||
size = FS_NORMAL;
|
||||
const char *text = _langpack_offs[_langtab_start[i] + j];
|
||||
if (str != NULL) *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 (c == SCC_TINYFONT) {
|
||||
size = FS_SMALL;
|
||||
} else if (c == SCC_BIGFONT) {
|
||||
size = FS_LARGE;
|
||||
} else if (!IsInsideMM(c, SCC_SPRITE_START, SCC_SPRITE_END) && IsPrintable(c) && !IsTextDirectionChar(c) && c != '?' && GetGlyph(size, c) == question_mark[size]) {
|
||||
/* The character is printable, but not in the normal font. This is the case we were testing for. */
|
||||
return true;
|
||||
}
|
||||
this->Reset();
|
||||
for (const char *text = this->NextString(); text != NULL; text = this->NextString()) {
|
||||
FontSize size = this->DefaultSize();
|
||||
if (str != NULL) *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 (c == SCC_TINYFONT) {
|
||||
size = FS_SMALL;
|
||||
} else if (c == SCC_BIGFONT) {
|
||||
size = FS_LARGE;
|
||||
} else if (!IsInsideMM(c, SCC_SPRITE_START, SCC_SPRITE_END) && IsPrintable(c) && !IsTextDirectionChar(c) && c != '?' && GetGlyph(size, c) == question_mark[size]) {
|
||||
/* The character is printable, but not in the normal font. This is the case we were testing for. */
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Helper for searching through the language pack. */
|
||||
class LanguagePackGlyphSearcher : public MissingGlyphSearcher {
|
||||
uint i; ///< Iterator for the primary language tables.
|
||||
uint j; ///< Iterator for the secondary language tables.
|
||||
|
||||
/* virtual */ void Reset()
|
||||
{
|
||||
this->i = 0;
|
||||
this->j = 0;
|
||||
}
|
||||
|
||||
FontSize DefaultSize()
|
||||
{
|
||||
return FS_NORMAL;
|
||||
}
|
||||
|
||||
const char *NextString()
|
||||
{
|
||||
if (this->i >= 32) return NULL;
|
||||
|
||||
const char *ret = _langpack_offs[_langtab_start[i] + j];
|
||||
|
||||
this->j++;
|
||||
while (this->j >= _langtab_num[this->i] && this->i < 32) {
|
||||
i++;
|
||||
j = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Check whether the currently loaded language pack
|
||||
* uses characters that the currently loaded font
|
||||
|
@ -1803,7 +1832,8 @@ static bool FindMissingGlyphs(const char **str)
|
|||
*/
|
||||
void CheckForMissingGlyphsInLoadedLanguagePack(bool base_font)
|
||||
{
|
||||
bool bad_font = !base_font || FindMissingGlyphs(NULL);
|
||||
LanguagePackGlyphSearcher searcher;
|
||||
bool bad_font = !base_font || searcher.FindMissingGlyphs(NULL);
|
||||
#ifdef WITH_FREETYPE
|
||||
if (bad_font) {
|
||||
/* We found an unprintable character... lets try whether we can find
|
||||
|
@ -1811,7 +1841,7 @@ void CheckForMissingGlyphsInLoadedLanguagePack(bool base_font)
|
|||
FreeTypeSettings backup;
|
||||
memcpy(&backup, &_freetype, sizeof(backup));
|
||||
|
||||
bad_font = !SetFallbackFont(&_freetype, _langpack->isocode, _langpack->winlangid, &FindMissingGlyphs);
|
||||
bad_font = !SetFallbackFont(&_freetype, _langpack->isocode, _langpack->winlangid, &searcher);
|
||||
|
||||
memcpy(&_freetype, &backup, sizeof(backup));
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "strings_type.h"
|
||||
#include "string_type.h"
|
||||
#include "gfx_type.h"
|
||||
|
||||
class StringParameters {
|
||||
StringParameters *parent; ///< If not NULL, this instance references data from this parent instance.
|
||||
|
@ -196,6 +197,34 @@ const char *GetCurrentLanguageIsoCode();
|
|||
|
||||
int CDECL StringIDSorter(const StringID *a, const StringID *b);
|
||||
|
||||
/**
|
||||
* A searcher for missing glyphs.
|
||||
*/
|
||||
class MissingGlyphSearcher {
|
||||
public:
|
||||
/** Make sure everything gets destructed right. */
|
||||
virtual ~MissingGlyphSearcher() {}
|
||||
|
||||
/**
|
||||
* Get the next string to search through.
|
||||
* @return The next string or NULL if there is none.
|
||||
*/
|
||||
virtual const char *NextString() = 0;
|
||||
|
||||
/**
|
||||
* Get the default (font) size of the string.
|
||||
* @return The font size.
|
||||
*/
|
||||
virtual FontSize DefaultSize() = 0;
|
||||
|
||||
/**
|
||||
* Reset the search, i.e. begin from the beginning again.
|
||||
*/
|
||||
virtual void Reset() = 0;
|
||||
|
||||
bool FindMissingGlyphs(const char **str);
|
||||
};
|
||||
|
||||
void CheckForMissingGlyphsInLoadedLanguagePack(bool base_font = true);
|
||||
|
||||
#endif /* STRINGS_FUNC_H */
|
||||
|
|
Loading…
Reference in New Issue