Changeset - r18413:e892ae4942df
[Not reviewed]
master
0 4 0
rubidium - 13 years ago 2011-11-19 18:43:00
rubidium@openttd.org
(svn r23265) -Codechange: replace the setfallbackfont callback function with a class to call back
4 files changed with 96 insertions and 37 deletions:
0 comments (0 inline, 0 general)
src/fontcache.cpp
Show inline comments
 
@@ -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(con
 
	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 *f
 
	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 *s
 
		}
 
	 }
 

	
 
	callback(NULL);
 
	callback->FindMissingGlyphs(NULL);
 
	return result;
 
}
 

	
 
@@ -683,7 +684,7 @@ static FT_Error GetFontByFaceName(const 
 
	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 *s
 
			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 *s
 

	
 
#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)
src/fontcache.h
Show inline comments
 
@@ -47,7 +47,6 @@ const Sprite *GetGlyph(FontSize size, ui
 
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)(c
 
 * @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
 

	
src/strings.cpp
Show inline comments
 
@@ -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
 
 */
 
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 CheckForMissingGlyphsInLoadedLangua
 
		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));
 

	
src/strings_func.h
Show inline comments
 
@@ -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 */
0 comments (0 inline, 0 general)