OpenTTD Source 20260421-master-gc2fbc6fdeb
fontcache.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
10#include "stdafx.h"
11#include "fontcache.h"
12#include "blitter/factory.hpp"
13#include "gfx_layout.h"
14#include "openttd.h"
15#include "settings_func.h"
16#include "strings_func.h"
17#include "viewport_func.h"
18#include "window_func.h"
19#include "fileio_func.h"
20
21#include "safeguards.h"
22
24/* static */ const EnumClassIndexContainer<std::array<int, to_underlying(FontSize::End)>, FontSize> FontCache::DEFAULT_FONT_HEIGHT{10, 6, 18, 10};
26/* static */ const EnumClassIndexContainer<std::array<int, to_underlying(FontSize::End)>, FontSize> FontCache::DEFAULT_FONT_ASCENDER{8, 5, 15, 8};
27
28FontCacheSettings _fcsettings;
29
39/* static */ std::unique_ptr<FontCache> FontProviderManager::LoadFont(FontSize fs, FontType fonttype, bool search, const std::string &font_name, const std::any &os_handle)
40{
41 for (auto &provider : FontProviderManager::GetProviders()) {
42 auto fc = provider->LoadFont(fs, fonttype, search, font_name, os_handle);
43 if (fc != nullptr) return fc;
44 }
45
46 return nullptr;
47}
48
56/* static */ bool FontProviderManager::FindFallbackFont(const std::string &language_isocode, MissingGlyphSearcher *callback)
57{
58 return std::ranges::any_of(FontProviderManager::GetProviders(),
59 [&](auto *provider) { return provider->FindFallbackFont(language_isocode, callback); });
60}
61
62int FontCache::GetDefaultFontHeight(FontSize fs)
63{
65}
66
73{
74 FontCache *fc = FontCache::Get(fs);
75 if (fc != nullptr) {
76 return fc->GetFontName();
77 } else {
78 return "[NULL]";
79 }
80}
81
82
89{
90 return FontCache::Get(size)->GetHeight();
91}
92
93
95
100{
102 if (FontCache::Get(fs) != nullptr) continue;
104 }
105}
106
107/* Check if a glyph should be rendered with anti-aliasing. */
108bool GetFontAAState()
109{
110 /* AA is only supported for 32 bpp */
111 if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 32) return false;
112
113 return _fcsettings.global_aa;
114}
115
116void SetFont(FontSize fontsize, const std::string &font, uint size)
117{
118 FontCacheSubSetting *setting = GetFontCacheSubSetting(fontsize);
119 bool changed = false;
120
121 if (setting->font != font) {
122 setting->font = font;
123 changed = true;
124 }
125
126 if (setting->size != size) {
127 setting->size = size;
128 changed = true;
129 }
130
131 if (!changed) return;
132
133 if (fontsize != FontSize::Monospace) {
134 /* Try to reload only the modified font. */
135 FontCacheSettings backup = _fcsettings;
136 for (FontSize fs = FontSize::Begin; fs < FontSize::End; fs++) {
137 if (fs == fontsize) continue;
138 FontCache *fc = FontCache::Get(fs);
139 GetFontCacheSubSetting(fs)->font = fc->HasParent() ? fc->GetFontName() : "";
140 }
142 _fcsettings = std::move(backup);
143 } else {
145 }
146
147 LoadStringWidthTable(fontsize);
149 ReInitAllWindows(true);
150
151 if (_save_config) SaveToConfig();
152}
153
159static bool IsDefaultFont(const FontCacheSubSetting &setting)
160{
161 return setting.font.empty() && !setting.os_handle.has_value();
162}
163
170{
171 const FontCacheSubSetting &setting = *GetFontCacheSubSetting(fs);
172 return IsDefaultFont(setting) ? FontCache::GetDefaultFontHeight(fs) : setting.size;
173}
174
175#if defined(WITH_FREETYPE) || defined(_WIN32) || defined(WITH_COCOA)
181static std::string GetDefaultTruetypeFont(FontSize fs)
182{
183 switch (fs) {
184 case FontSize::Normal: return "OpenTTD-Sans.ttf";
185 case FontSize::Small: return "OpenTTD-Small.ttf";
186 case FontSize::Large: return "OpenTTD-Serif.ttf";
187 case FontSize::Monospace: return "OpenTTD-Mono.ttf";
188 default: NOT_REACHED();
189 }
190}
191#endif /* defined(WITH_FREETYPE) || defined(_WIN32) || defined(WITH_COCOA) */
192
198static std::string GetDefaultTruetypeFontFile([[maybe_unused]] FontSize fs)
199{
200#if defined(WITH_FREETYPE) || defined(_WIN32) || defined(WITH_COCOA)
201 /* Find font file. */
203#else
204 return {};
205#endif /* defined(WITH_FREETYPE) || defined(_WIN32) || defined(WITH_COCOA) */
206}
207
213static std::string GetFontCacheFontName(FontSize fs)
214{
216 if (!settings->font.empty()) return settings->font;
217 if (_fcsettings.prefer_sprite) return {};
219}
220
225/* static */ void FontCache::Register(std::unique_ptr<FontCache> &&fc)
226{
227 if (fc == nullptr) return;
228
229 FontSize fs = fc->fs;
230
231 fc->parent = std::move(FontCache::caches[fs]);
232 FontCache::caches[fs] = std::move(fc);
233}
234
241/* static */ void FontCache::AddFallback(FontSizes fontsizes, std::string_view name, const std::any &os_handle)
242{
243 for (FontSize fs : fontsizes) {
245 GetFontCacheSubSetting(fs)->os_handle = os_handle;
246 }
247}
248
257/* static */ bool FontCache::TryFallback(FontSizes, const std::set<char32_t> &glyphs, const std::string &name, const std::any &os_handle)
258{
259 /* Load the font without registering it. The font size does not matter. */
260 auto fc = FontProviderManager::LoadFont(FontSize::Normal, FontType::TrueType, false, name, os_handle);
261 if (fc == nullptr) return false;
262
263 size_t matching_chars = 0;
264 for (const char32_t &c : glyphs) {
265 if (fc->MapCharToGlyph(c, false) != 0) ++matching_chars;
266 }
267
268 if (matching_chars < glyphs.size()) {
269 Debug(fontcache, 1, "Font \"{}\" misses {} glyphs", name, glyphs.size() - matching_chars);
270 return false;
271 }
272
273 return true;
274}
275
280/* static */ void FontCache::LoadFontCaches(FontSizes fontsizes)
281{
283
284 for (FontSize fs : fontsizes) {
286
287 /* Unload everything except the sprite font cache. */
288 while (FontCache::Get(fs)->HasParent()) {
290 }
291
293
294 std::string font_name = GetFontCacheFontName(fs);
295 if (font_name.empty()) continue;
296
298 }
299}
300
305/* static */ void FontCache::ClearFontCaches(FontSizes fontsizes)
306{
307 for (FontSize fs : fontsizes) {
309 }
310}
311
316{
317 for (auto &fc : FontCache::caches) {
318 fc.reset();
319 }
320}
void UpdateAllVirtCoords()
Update the viewport coordinates of all signs.
static Blitter * GetCurrentBlitter()
Get the current active blitter (always set by calling SelectBlitter).
Definition factory.hpp:139
A sort-of mixin that implements 'at(pos)' and 'operator[](pos)' only for a specific enum class.
Font cache for basic fonts.
Definition fontcache.h:23
virtual std::string GetFontName()=0
Get the name of this font.
int GetHeight() const
Get the height of the font.
Definition fontcache.h:65
virtual void ClearFontCache()=0
Clear the font cache.
static void UninitializeFontCaches()
Free everything allocated w.r.t.
bool HasParent()
Check whether the font cache has a parent.
Definition fontcache.h:148
std::unique_ptr< FontCache > parent
The parent of this font cache.
Definition fontcache.h:26
virtual GlyphID MapCharToGlyph(char32_t key, bool fallback=true)=0
Map a character into a glyph.
static const EnumClassIndexContainer< std::array< int, to_underlying(FontSize::End)>, FontSize > DEFAULT_FONT_ASCENDER
Default unscaled font ascenders.
Definition fontcache.h:26
static const EnumClassIndexContainer< std::array< int, to_underlying(FontSize::End)>, FontSize > DEFAULT_FONT_HEIGHT
Default unscaled font heights.
Definition fontcache.h:24
static void AddFallback(FontSizes fontsizes, std::string_view name, const std::any &os_handle={})
Add a fallback font, with optional OS-specific handle.
static void ClearFontCaches(FontSizes fontsizes)
Clear cached information for the specified font caches.
static void Register(std::unique_ptr< FontCache > &&fc)
Register a FontCache for its font size.
const FontSize fs
The size of the font.
Definition fontcache.h:27
static std::string GetName(FontSize fs)
Get the font name of a given font size.
Definition fontcache.cpp:72
static void LoadFontCaches(FontSizes fontsizes)
(Re)initialize the font cache related things, i.e.
static FontCache * Get(FontSize fs)
Get the font cache of a given font size.
Definition fontcache.h:136
static bool TryFallback(FontSizes fontsizes, const std::set< char32_t > &glyphs, const std::string &name, const std::any &os_handle={})
Test a fallback font, with optional OS-specific handle, for specific glyphs.
static void InitializeFontCaches()
Initialise font caches with the base sprite font cache for all sizes.
Definition fontcache.cpp:99
static EnumClassIndexContainer< std::array< std::unique_ptr< FontCache >, to_underlying(FontSize::End)>, FontSize > caches
All the font caches.
Definition fontcache.h:94
static std::unique_ptr< FontCache > LoadFont(FontSize fs, FontType fonttype, bool search, const std::string &font_name, const std::any &os_handle={})
Try loading a font with any fontcache factory.
Definition fontcache.cpp:39
static bool FindFallbackFont(const std::string &language_isocode, MissingGlyphSearcher *callback)
We would like to have a fallback font as the current one doesn't contain all characters we need.
Definition fontcache.cpp:56
static void ResetFontCache(FontSize size)
Reset cached font information.
A searcher for missing glyphs.
static std::vector< const FontCacheFactory * > & GetProviders()
#define Debug(category, level, format_string,...)
Output a line of debugging information.
Definition debug.h:37
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23).
Definition enum_type.hpp:21
Factory to 'query' all available blitters.
std::string FioFindFullPath(Subdirectory subdir, std::string_view filename)
Find a path to the filename in one of the search directories.
Definition fileio.cpp:146
Functions for standard in/out file operations.
@ Baseset
Subdirectory for all base data (base sets, intro game).
Definition fileio_type.h:96
fluid_settings_t * settings
FluidSynth settings handle.
static std::string GetFontCacheFontName(FontSize fs)
Get font to use for a given font size.
static std::string GetDefaultTruetypeFontFile(FontSize fs)
Get path of default font file for a given font size.
uint GetFontCacheFontSize(FontSize fs)
Get the scalable font size to use for a FontSize.
static bool IsDefaultFont(const FontCacheSubSetting &setting)
Test if a font setting uses the default font.
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Definition fontcache.cpp:88
static std::string GetDefaultTruetypeFont(FontSize fs)
Get name of default font file for a given font size.
Functions to read fonts from files and cache them.
FontType
Different types of font that can be loaded.
Definition fontcache.h:231
@ TrueType
Scalable TrueType fonts.
Definition fontcache.h:233
@ Sprite
Bitmap sprites from GRF files.
Definition fontcache.h:232
FontCacheSubSetting * GetFontCacheSubSetting(FontSize fs)
Get the settings of a given font size.
Definition fontcache.h:214
void LoadStringWidthTable(FontSizes fontsizes)
Initialize _stringwidth_table cache for the specified font sizes.
Definition gfx.cpp:1261
Functions related to laying out the texts.
FontSize
Available font sizes.
Definition gfx_type.h:248
@ Begin
Marker for the first font in the enumeration.
Definition gfx_type.h:255
@ Small
Index of the small font in the font tables.
Definition gfx_type.h:250
@ Large
Index of the large font in the font tables.
Definition gfx_type.h:251
@ End
Marker for the end of the enumerations.
Definition gfx_type.h:254
@ Normal
Index of the normal font in the font tables.
Definition gfx_type.h:249
@ Monospace
Index of the monospaced font in the font tables.
Definition gfx_type.h:252
Some generic types.
A number of safeguards to prevent using unsafe methods.
void SaveToConfig()
Save the values to the configuration file.
Functions related to setting/changing the settings.
Definition of base types and functions in a cross-platform compatible way.
void CheckForMissingGlyphs(MissingGlyphSearcher *searcher)
Check whether the currently loaded language pack uses characters that the currently loaded font does ...
Definition strings.cpp:2387
Functions related to OTTD's strings.
Settings for the four different fonts.
Definition fontcache.h:198
Settings for a single font.
Definition fontcache.h:190
std::any os_handle
Optional native OS font info.
Definition fontcache.h:194
std::string font
The name of the font, or path to the font.
Definition fontcache.h:191
uint size
The (requested) size of the font.
Definition fontcache.h:192
Functions related to (drawing on) viewports.
void ReInitAllWindows(bool zoom_changed)
Re-initialize all windows.
Definition window.cpp:3439
Window functions not directly related to making/drawing windows.