Mercurial > hg > openttd
changeset 18423:fe86a6bfde45 draft
(svn r23265) -Codechange: replace the setfallbackfont callback function with a class to call back
author | rubidium <rubidium@openttd.org> |
---|---|
date | Sat, 19 Nov 2011 18:43:00 +0000 |
parents | 470aeadadd91 |
children | aeb8d6b635a1 |
files | src/fontcache.cpp src/fontcache.h src/strings.cpp src/strings_func.h |
diffstat | 4 files changed, 96 insertions(+), 37 deletions(-) [+] |
line wrap: on
line diff
--- a/src/fontcache.cpp +++ b/src/fontcache.cpp @@ -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 @@ 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 @@ 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 @@ 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 @@ } } - callback(NULL); + callback->FindMissingGlyphs(NULL); return result; } @@ -683,7 +684,7 @@ 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 @@ 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 @@ #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)
--- a/src/fontcache.h +++ b/src/fontcache.h @@ -47,7 +47,6 @@ 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 @@ * @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
--- a/src/strings.cpp +++ b/src/strings.cpp @@ -1750,46 +1750,75 @@ * @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 @@ */ 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 @@ 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));
--- a/src/strings_func.h +++ b/src/strings_func.h @@ -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 @@ 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 */