Fix #10490: Allow ships to exit depots if another is not moving at the exit point...
[openttd-github.git] / src / fontcache.cpp
blob2a5772fc3bbc27f48dc641c0a4f112c7ad822ae7
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 <http://www.gnu.org/licenses/>.
6 */
8 /** @file fontcache.cpp Cache for characters from fonts. */
10 #include "stdafx.h"
11 #include "fontcache.h"
12 #include "fontdetection.h"
13 #include "blitter/factory.hpp"
14 #include "gfx_layout.h"
15 #include "fontcache/spritefontcache.h"
16 #include "openttd.h"
17 #include "settings_func.h"
18 #include "strings_func.h"
19 #include "viewport_func.h"
20 #include "window_func.h"
21 #include "fileio_func.h"
23 #include "safeguards.h"
25 /** Default heights for the different sizes of fonts. */
26 static const int _default_font_height[FS_END] = {10, 6, 18, 10};
27 static const int _default_font_ascender[FS_END] = { 8, 5, 15, 8};
29 FontCacheSettings _fcsettings;
31 /**
32 * Create a new font cache.
33 * @param fs The size of the font.
35 FontCache::FontCache(FontSize fs) : parent(FontCache::Get(fs)), fs(fs), height(_default_font_height[fs]),
36 ascender(_default_font_ascender[fs]), descender(_default_font_ascender[fs] - _default_font_height[fs]),
37 units_per_em(1)
39 assert(this->parent == nullptr || this->fs == this->parent->fs);
40 FontCache::caches[this->fs] = this;
41 Layouter::ResetFontCache(this->fs);
44 /** Clean everything up. */
45 FontCache::~FontCache()
47 assert(this->fs == this->parent->fs);
48 FontCache::caches[this->fs] = this->parent;
49 Layouter::ResetFontCache(this->fs);
52 int FontCache::GetDefaultFontHeight(FontSize fs)
54 return _default_font_height[fs];
57 /**
58 * Get the font name of a given font size.
59 * @param fs The font size to look up.
60 * @return The font name.
62 std::string FontCache::GetName(FontSize fs)
64 FontCache *fc = FontCache::Get(fs);
65 if (fc != nullptr) {
66 return fc->GetFontName();
67 } else {
68 return "[NULL]";
73 /**
74 * Get height of a character for a given font size.
75 * @param size Font size to get height of
76 * @return Height of characters in the given font (pixels)
78 int GetCharacterHeight(FontSize size)
80 return FontCache::Get(size)->GetHeight();
84 /* static */ FontCache *FontCache::caches[FS_END];
86 /* static */ void FontCache::InitializeFontCaches()
88 for (FontSize fs = FS_BEGIN; fs != FS_END; fs++) {
89 if (FontCache::caches[fs] == nullptr) new SpriteFontCache(fs); /* FontCache inserts itself into to the cache. */
93 /* Check if a glyph should be rendered with anti-aliasing. */
94 bool GetFontAAState(FontSize size, bool check_blitter)
96 /* AA is only supported for 32 bpp */
97 if (check_blitter && BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 32) return false;
99 return _fcsettings.global_aa || GetFontCacheSubSetting(size)->aa;
102 void SetFont(FontSize fontsize, const std::string &font, uint size, bool aa)
104 FontCacheSubSetting *setting = GetFontCacheSubSetting(fontsize);
105 bool changed = false;
107 if (setting->font != font) {
108 setting->font = font;
109 changed = true;
112 if (setting->size != size) {
113 setting->size = size;
114 changed = true;
117 if (setting->aa != aa) {
118 setting->aa = aa;
119 changed = true;
122 if (!changed) return;
124 if (fontsize != FS_MONO) {
125 /* Try to reload only the modified font. */
126 FontCacheSettings backup = _fcsettings;
127 for (FontSize fs = FS_BEGIN; fs < FS_END; fs++) {
128 if (fs == fontsize) continue;
129 FontCache *fc = FontCache::Get(fs);
130 GetFontCacheSubSetting(fs)->font = fc->HasParent() ? fc->GetFontName() : "";
132 CheckForMissingGlyphs();
133 _fcsettings = backup;
134 } else {
135 InitFontCache(true);
138 LoadStringWidthTable();
139 UpdateAllVirtCoords();
140 ReInitAllWindows(true);
142 if (_save_config) SaveToConfig();
145 #ifdef WITH_FREETYPE
146 extern void LoadFreeTypeFont(FontSize fs);
147 extern void LoadFreeTypeFont(FontSize fs, const std::string &file_name, uint size);
148 extern void UninitFreeType();
149 #elif defined(_WIN32)
150 extern void LoadWin32Font(FontSize fs);
151 extern void LoadWin32Font(FontSize fs, const std::string &file_name, uint size);
152 #elif defined(WITH_COCOA)
153 extern void LoadCoreTextFont(FontSize fs);
154 extern void LoadCoreTextFont(FontSize fs, const std::string &file_name, uint size);
155 #endif
157 static void TryLoadDefaultTrueTypeFont([[maybe_unused]] FontSize fs)
159 #if defined(WITH_FREETYPE) || defined(_WIN32) || defined(WITH_COCOA)
160 std::string font_name{};
161 switch (fs) {
162 case FS_NORMAL:
163 font_name = "OpenTTD-Sans.ttf";
164 break;
165 case FS_SMALL:
166 font_name = "OpenTTD-Small.ttf";
167 break;
168 case FS_LARGE:
169 font_name = "OpenTTD-Serif.ttf";
170 break;
171 case FS_MONO:
172 font_name = "OpenTTD-Mono.ttf";
173 break;
175 default: NOT_REACHED();
178 /* Find font file. */
179 std::string full_font = FioFindFullPath(BASESET_DIR, font_name);
180 if (!full_font.empty()) {
181 int size = FontCache::GetDefaultFontHeight(fs);
182 #ifdef WITH_FREETYPE
183 LoadFreeTypeFont(fs, full_font, size);
184 #elif defined(_WIN32)
185 LoadWin32Font(fs, full_font, size);
186 #elif defined(WITH_COCOA)
187 LoadCoreTextFont(fs, full_font, size);
188 #endif
190 #endif /* defined(WITH_FREETYPE) || defined(_WIN32) || defined(WITH_COCOA) */
194 * (Re)initialize the font cache related things, i.e. load the non-sprite fonts.
195 * @param monospace Whether to initialise the monospace or regular fonts.
197 void InitFontCache(bool monospace)
199 FontCache::InitializeFontCaches();
201 for (FontSize fs = FS_BEGIN; fs < FS_END; fs++) {
202 if (monospace != (fs == FS_MONO)) continue;
204 FontCache *fc = FontCache::Get(fs);
205 if (fc->HasParent()) delete fc;
207 if (!_fcsettings.prefer_sprite && GetFontCacheSubSetting(fs)->font.empty()) {
208 TryLoadDefaultTrueTypeFont(fs);
209 } else {
210 #ifdef WITH_FREETYPE
211 LoadFreeTypeFont(fs);
212 #elif defined(_WIN32)
213 LoadWin32Font(fs);
214 #elif defined(WITH_COCOA)
215 LoadCoreTextFont(fs);
216 #endif
222 * Free everything allocated w.r.t. fonts.
224 void UninitFontCache()
226 for (FontSize fs = FS_BEGIN; fs < FS_END; fs++) {
227 FontCache *fc = FontCache::Get(fs);
228 if (fc->HasParent()) delete fc;
231 #ifdef WITH_FREETYPE
232 UninitFreeType();
233 #endif /* WITH_FREETYPE */
237 * Should any of the active fonts be anti-aliased?
238 * @return True if any of the loaded fonts want anti-aliased drawing.
240 bool HasAntialiasedFonts()
242 for (FontSize fs = FS_BEGIN; fs < FS_END; fs++) {
243 if (!FontCache::Get(fs)->IsBuiltInFont() && GetFontAAState(fs, false)) return true;
246 return false;
249 #if !defined(_WIN32) && !defined(__APPLE__) && !defined(WITH_FONTCONFIG) && !defined(WITH_COCOA)
251 bool SetFallbackFont(FontCacheSettings *, const std::string &, int, MissingGlyphSearcher *) { return false; }
252 #endif /* !defined(_WIN32) && !defined(__APPLE__) && !defined(WITH_FONTCONFIG) && !defined(WITH_COCOA) */