1
0
Fork 0

Fix #11966: Remove deferred monospace font-cache initialisation.

It was possible to ask for monospace font dimensions without initialising the monospace font cache, resulting in incorrect dimensions.

The `font` console command is also now able to reinitialise only the changed font instead of all.
pull/11970/head
Peter Nelson 2023-12-17 17:59:59 +00:00
parent d0c753465d
commit 172a98959a
No known key found for this signature in database
GPG Key ID: 8EF8F0A467DF75ED
10 changed files with 70 additions and 65 deletions

View File

@ -2130,7 +2130,7 @@ DEF_CONSOLE_CMD(ConFont)
FontCacheSubSetting *setting = GetFontCacheSubSetting(fs); FontCacheSubSetting *setting = GetFontCacheSubSetting(fs);
/* Make sure all non sprite fonts are loaded. */ /* Make sure all non sprite fonts are loaded. */
if (!setting->font.empty() && !fc->HasParent()) { if (!setting->font.empty() && !fc->HasParent()) {
InitFontCache(fs == FS_MONO); InitFontCache(fs);
fc = FontCache::Get(fs); fc = FontCache::Get(fs);
} }
IConsolePrint(CC_DEFAULT, "{}: \"{}\" {} {} [\"{}\" {} {}]", FontSizeToName(fs), fc->GetFontName(), fc->GetFontSize(), GetFontAAState(fs) ? "aa" : "noaa", setting->font, setting->size, setting->aa ? "aa" : "noaa"); IConsolePrint(CC_DEFAULT, "{}: \"{}\" {} {} [\"{}\" {} {}]", FontSizeToName(fs), fc->GetFontName(), fc->GetFontSize(), GetFontAAState(fs) ? "aa" : "noaa", setting->font, setting->size, setting->aa ? "aa" : "noaa");

View File

@ -121,21 +121,10 @@ void SetFont(FontSize fontsize, const std::string &font, uint size, bool aa)
if (!changed) return; if (!changed) return;
if (fontsize != FS_MONO) { InitFontCache(fontsize);
/* Try to reload only the modified font. */ if (fontsize != FS_MONO) CheckForMissingGlyphs();
FontCacheSettings backup = _fcsettings;
for (FontSize fs = FS_BEGIN; fs < FS_END; fs++) {
if (fs == fontsize) continue;
FontCache *fc = FontCache::Get(fs);
GetFontCacheSubSetting(fs)->font = fc->HasParent() ? fc->GetFontName() : "";
}
CheckForMissingGlyphs();
_fcsettings = backup;
} else {
InitFontCache(true);
}
LoadStringWidthTable(); LoadStringWidthTable(fontsize);
UpdateAllVirtCoords(); UpdateAllVirtCoords();
ReInitAllWindows(true); ReInitAllWindows(true);
@ -191,37 +180,42 @@ static void TryLoadDefaultTrueTypeFont([[maybe_unused]] FontSize fs)
} }
/** /**
* (Re)initialize the font cache related things, i.e. load the non-sprite fonts. * (Re)initialise the font cache related things for a specific font size.
* @param monospace Whether to initialise the monospace or regular fonts. * @param fs Font size to (re)initialise.
*/ */
void InitFontCache(bool monospace) void InitFontCache(FontSize fs)
{
FontCache *fc = FontCache::Get(fs);
if (fc->HasParent()) delete fc;
if (!_fcsettings.prefer_sprite && GetFontCacheSubSetting(fs)->font.empty()) {
TryLoadDefaultTrueTypeFont(fs);
} else {
#ifdef WITH_FREETYPE
LoadFreeTypeFont(fs);
#elif defined(_WIN32)
LoadWin32Font(fs);
#elif defined(WITH_COCOA)
LoadCoreTextFont(fs);
#endif
}
}
/**
* (Re)initialise the font cache related things, i.e. load the non-sprite fonts, for all font sizes.
*/
void InitFontCaches()
{ {
FontCache::InitializeFontCaches(); FontCache::InitializeFontCaches();
for (FontSize fs = FS_BEGIN; fs < FS_END; fs++) { for (FontSize fs = FS_BEGIN; fs < FS_END; fs++) {
if (monospace != (fs == FS_MONO)) continue; InitFontCache(fs);
FontCache *fc = FontCache::Get(fs);
if (fc->HasParent()) delete fc;
if (!_fcsettings.prefer_sprite && GetFontCacheSubSetting(fs)->font.empty()) {
TryLoadDefaultTrueTypeFont(fs);
} else {
#ifdef WITH_FREETYPE
LoadFreeTypeFont(fs);
#elif defined(_WIN32)
LoadWin32Font(fs);
#elif defined(WITH_COCOA)
LoadCoreTextFont(fs);
#endif
}
} }
} }
/** /**
* Free everything allocated w.r.t. fonts. * Free everything allocated w.r.t. fonts.
*/ */
void UninitFontCache() void UninitFontCaches()
{ {
for (FontSize fs = FS_BEGIN; fs < FS_END; fs++) { for (FontSize fs = FS_BEGIN; fs < FS_END; fs++) {
FontCache *fc = FontCache::Get(fs); FontCache *fc = FontCache::Get(fs);

View File

@ -177,10 +177,15 @@ inline void InitializeUnicodeGlyphMap()
} }
} }
inline void ClearFontCache() inline void ClearFontCache(FontSize fs)
{
FontCache::Get(fs)->ClearFontCache();
}
inline void ClearFontCaches()
{ {
for (FontSize fs = FS_BEGIN; fs < FS_END; fs++) { for (FontSize fs = FS_BEGIN; fs < FS_END; fs++) {
FontCache::Get(fs)->ClearFontCache(); ClearFontCache(fs);
} }
} }
@ -240,8 +245,9 @@ inline FontCacheSubSetting *GetFontCacheSubSetting(FontSize fs)
} }
} }
void InitFontCache(bool monospace); void InitFontCaches();
void UninitFontCache(); void InitFontCache(FontSize fs);
void UninitFontCaches();
bool HasAntialiasedFonts(); bool HasAntialiasedFonts();
bool GetFontAAState(FontSize size, bool check_blitter = true); bool GetFontAAState(FontSize size, bool check_blitter = true);

View File

@ -1227,20 +1227,25 @@ static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode,
} }
/** /**
* Initialize _stringwidth_table cache * Initialize _stringwidth_table cache for a specific font size.
* @param monospace Whether to load the monospace cache or the normal fonts. * @param fs Font size to initialize stringwidth table for.
*/ */
void LoadStringWidthTable(bool monospace) void LoadStringWidthTable(FontSize fs)
{ {
ClearFontCache(); ClearFontCache(fs);
for (uint i = 0; i != 224; i++) {
for (FontSize fs = monospace ? FS_MONO : FS_BEGIN; fs < (monospace ? FS_END : FS_MONO); fs++) { _stringwidth_table[fs][i] = GetGlyphWidth(fs, i + 32);
for (uint i = 0; i != 224; i++) {
_stringwidth_table[fs][i] = GetGlyphWidth(fs, i + 32);
}
} }
} }
/**
* Initialize _stringwidth_table cache for all font sizes.
*/
void LoadStringWidthTable()
{
for (FontSize fs = FS_BEGIN; fs < FS_END; fs++) LoadStringWidthTable(fs);
}
/** /**
* Return width of character glyph. * Return width of character glyph.
* @param size Font of the character * @param size Font of the character
@ -1827,7 +1832,7 @@ bool AdjustGUIZoom(bool automatic)
if (old_font_zoom != _font_zoom) { if (old_font_zoom != _font_zoom) {
GfxClearFontSpriteCache(); GfxClearFontSpriteCache();
} }
ClearFontCache(); ClearFontCaches();
LoadStringWidthTable(); LoadStringWidthTable();
SetupWidgetDimensions(); SetupWidgetDimensions();

View File

@ -139,7 +139,8 @@ int GetStringHeight(StringID str, int maxw);
int GetStringLineCount(StringID str, int maxw); int GetStringLineCount(StringID str, int maxw);
Dimension GetStringMultiLineBoundingBox(StringID str, const Dimension &suggestion); Dimension GetStringMultiLineBoundingBox(StringID str, const Dimension &suggestion);
Dimension GetStringMultiLineBoundingBox(std::string_view str, const Dimension &suggestion); Dimension GetStringMultiLineBoundingBox(std::string_view str, const Dimension &suggestion);
void LoadStringWidthTable(bool monospace = false); void LoadStringWidthTable();
void LoadStringWidthTable(FontSize fs);
Point GetCharPosInString(std::string_view str, const char *ch, FontSize start_fontsize = FS_NORMAL); Point GetCharPosInString(std::string_view str, const char *ch, FontSize start_fontsize = FS_NORMAL);
ptrdiff_t GetCharAtPosition(std::string_view str, int x, FontSize start_fontsize = FS_NORMAL); ptrdiff_t GetCharAtPosition(std::string_view str, int x, FontSize start_fontsize = FS_NORMAL);

View File

@ -236,7 +236,7 @@ static void RealChangeBlitter(const char *repl_blitter)
/* Clear caches that might have sprites for another blitter. */ /* Clear caches that might have sprites for another blitter. */
VideoDriver::GetInstance()->ClearSystemSprites(); VideoDriver::GetInstance()->ClearSystemSprites();
ClearFontCache(); ClearFontCaches();
GfxClearSpriteCache(); GfxClearSpriteCache();
ReInitAllWindows(false); ReInitAllWindows(false);
} }
@ -318,7 +318,7 @@ void CheckBlitter()
{ {
if (!SwitchNewGRFBlitter()) return; if (!SwitchNewGRFBlitter()) return;
ClearFontCache(); ClearFontCaches();
GfxClearSpriteCache(); GfxClearSpriteCache();
ReInitAllWindows(false); ReInitAllWindows(false);
} }
@ -330,7 +330,7 @@ void GfxLoadSprites()
SwitchNewGRFBlitter(); SwitchNewGRFBlitter();
VideoDriver::GetInstance()->ClearSystemSprites(); VideoDriver::GetInstance()->ClearSystemSprites();
ClearFontCache(); ClearFontCaches();
GfxInitSpriteMem(); GfxInitSpriteMem();
LoadSpriteTables(); LoadSpriteTables();
GfxInitPalettes(); GfxInitPalettes();

View File

@ -308,7 +308,7 @@ static void ShutdownGame()
/* No NewGRFs were loaded when it was still bootstrapping. */ /* No NewGRFs were loaded when it was still bootstrapping. */
if (_game_mode != GM_BOOTSTRAP) ResetNewGRFData(); if (_game_mode != GM_BOOTSTRAP) ResetNewGRFData();
UninitFontCache(); UninitFontCaches();
} }
/** /**
@ -705,7 +705,7 @@ int openttd_main(int argc, char *argv[])
InitializeLanguagePacks(); InitializeLanguagePacks();
/* Initialize the font cache */ /* Initialize the font cache */
InitFontCache(false); InitFontCaches();
/* This must be done early, since functions use the SetWindowDirty* calls */ /* This must be done early, since functions use the SetWindowDirty* calls */
InitWindowSystem(); InitWindowSystem();

View File

@ -169,7 +169,7 @@ bool SetFallbackFont(FontCacheSettings *settings, const std::string &language_is
if (best_font != nullptr) { if (best_font != nullptr) {
ret = true; ret = true;
callback->SetFontNames(settings, best_font, &best_index); callback->SetFontNames(settings, best_font, &best_index);
InitFontCache(callback->Monospace()); InitFontCache(callback->DefaultSize());
} }
/* Clean up the list of filenames. */ /* Clean up the list of filenames. */

View File

@ -764,9 +764,8 @@ struct GameOptionsWindow : Window {
this->SetWidgetDisabledState(WID_GO_GUI_FONT_AA, _fcsettings.prefer_sprite); this->SetWidgetDisabledState(WID_GO_GUI_FONT_AA, _fcsettings.prefer_sprite);
this->SetDirty(); this->SetDirty();
InitFontCache(false); InitFontCaches();
InitFontCache(true); ClearFontCaches();
ClearFontCache();
CheckForMissingGlyphs(); CheckForMissingGlyphs();
SetupWidgetDimensions(); SetupWidgetDimensions();
UpdateAllVirtCoords(); UpdateAllVirtCoords();
@ -779,7 +778,7 @@ struct GameOptionsWindow : Window {
this->SetWidgetLoweredState(WID_GO_GUI_FONT_AA, _fcsettings.global_aa); this->SetWidgetLoweredState(WID_GO_GUI_FONT_AA, _fcsettings.global_aa);
MarkWholeScreenDirty(); MarkWholeScreenDirty();
ClearFontCache(); ClearFontCaches();
break; break;
#endif /* HAS_TRUETYPE_FONT */ #endif /* HAS_TRUETYPE_FONT */

View File

@ -2165,7 +2165,7 @@ const char *GetCurrentLanguageIsoCode()
*/ */
bool MissingGlyphSearcher::FindMissingGlyphs() bool MissingGlyphSearcher::FindMissingGlyphs()
{ {
InitFontCache(this->Monospace()); InitFontCache(this->DefaultSize());
const Sprite *question_mark[FS_END]; const Sprite *question_mark[FS_END];
for (FontSize size = this->Monospace() ? FS_MONO : FS_BEGIN; size < (this->Monospace() ? FS_END : FS_MONO); size++) { for (FontSize size = this->Monospace() ? FS_MONO : FS_BEGIN; size < (this->Monospace() ? FS_END : FS_MONO); size++) {
@ -2301,7 +2301,7 @@ void CheckForMissingGlyphs(bool base_font, MissingGlyphSearcher *searcher)
/* 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 */
InitFontCache(searcher->Monospace()); InitFontCache(searcher->DefaultSize());
} }
} }
#endif #endif
@ -2318,12 +2318,12 @@ void CheckForMissingGlyphs(bool base_font, MissingGlyphSearcher *searcher)
ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_WARNING); ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_WARNING);
/* Reset the font width */ /* Reset the font width */
LoadStringWidthTable(searcher->Monospace()); LoadStringWidthTable(searcher->DefaultSize());
return; return;
} }
/* Update the font with cache */ /* Update the font with cache */
LoadStringWidthTable(searcher->Monospace()); LoadStringWidthTable(searcher->DefaultSize());
#if !(defined(WITH_ICU_I18N) && defined(WITH_HARFBUZZ)) && !defined(WITH_UNISCRIBE) && !defined(WITH_COCOA) #if !(defined(WITH_ICU_I18N) && defined(WITH_HARFBUZZ)) && !defined(WITH_UNISCRIBE) && !defined(WITH_COCOA)
/* /*