OpenTTD Source 20251213-master-g1091fa6071
spritefontcache.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
10#include "../stdafx.h"
11#include "../fontcache.h"
12#include "../gfx_layout.h"
13#include "../spritecache.h"
14#include "../string_func.h"
15#include "../zoom_func.h"
16#include "spritefontcache.h"
17
18#include "../table/sprites.h"
19#include "../table/control_codes.h"
20#include "../table/unicode.h"
21
22#include "../safeguards.h"
23
24static const int ASCII_LETTERSTART = 32;
25
26static std::array<std::unordered_map<char32_t, SpriteID>, FS_END> _char_maps{};
27
33static SpriteID GetUnicodeGlyph(FontSize fs, char32_t key)
34{
35 auto found = _char_maps[fs].find(key);
36 if (found != std::end(_char_maps[fs])) return found->second;
37 return 0;
38}
39
46void SetUnicodeGlyph(FontSize fs, char32_t key, SpriteID sprite)
47{
48 _char_maps[fs][key] = sprite;
49}
50
57{
58 /* Clear out existing glyph map if it exists */
59 _char_maps[fs].clear();
60
61 SpriteID base;
62 switch (fs) {
63 default: NOT_REACHED();
64 case FS_MONO: // Use normal as default for mono spaced font
65 case FS_NORMAL: base = SPR_ASCII_SPACE; break;
66 case FS_SMALL: base = SPR_ASCII_SPACE_SMALL; break;
67 case FS_LARGE: base = SPR_ASCII_SPACE_BIG; break;
68 }
69
70 for (uint i = ASCII_LETTERSTART; i < 256; i++) {
71 SpriteID sprite = base + i - ASCII_LETTERSTART;
72 if (!SpriteExists(sprite)) continue;
73 SetUnicodeGlyph(fs, i, sprite);
74 SetUnicodeGlyph(fs, i + SCC_SPRITE_START, sprite);
75 }
76
77 /* Modify map to move non-standard glyphs to a better unicode codepoint. */
78 for (const auto &unicode_map : _default_unicode_map) {
79 uint8_t key = unicode_map.key;
80 if (key == CLRA) {
81 /* Clear the glyph. This happens if the glyph at this code point
82 * is non-standard and should be accessed by an SCC_xxx enum
83 * entry only. */
84 SetUnicodeGlyph(fs, unicode_map.code, 0);
85 } else {
86 SpriteID sprite = base + key - ASCII_LETTERSTART;
87 if (!SpriteExists(sprite)) continue;
88 SetUnicodeGlyph(fs, unicode_map.code, sprite);
89 }
90 }
91}
92
97{
98 for (FontSize fs = FS_BEGIN; fs < FS_END; fs++) {
100 }
101}
102
108{
109 this->UpdateMetrics();
110}
111
113{
115 this->UpdateMetrics();
116}
117
118void SpriteFontCache::UpdateMetrics()
119{
123 this->scaled_ascender = ScaleFontTrad(DEFAULT_FONT_ASCENDER[this->fs]);
124}
125
126int SpriteFontCache::GetGlyphYOffset()
127{
128 return FontCache::GetFontBaseline(this->fs) - this->scaled_ascender;
129}
130
132{
133 SpriteID sprite = static_cast<SpriteID>(key);
134 if (sprite == 0) sprite = GetUnicodeGlyph(this->fs, '?');
135 return GetSprite(sprite, SpriteType::Font);
136}
137
139{
140 SpriteID sprite = static_cast<SpriteID>(key);
141 if (sprite == 0) sprite = GetUnicodeGlyph(this->fs, '?');
142 return SpriteExists(sprite) ? GetSprite(sprite, SpriteType::Font)->width + ScaleFontTrad(this->fs != FS_NORMAL ? 1 : 0) : 0;
143}
144
146{
147 assert(IsPrintable(key));
148 SpriteID sprite = GetUnicodeGlyph(this->fs, key);
149 if (sprite == 0) return 0;
150 return static_cast<GlyphID>(sprite);
151}
152
154{
155 return false;
156}
157
159public:
160 SpriteFontCacheFactory() : FontCacheFactory("sprite", "Sprite font provider") {}
161
162 std::unique_ptr<FontCache> LoadFont(FontSize fs, FontType fonttype, bool, const std::string &, std::span<const std::byte>) const override
163 {
164 if (fonttype != FontType::Sprite) return nullptr;
165
166 return std::make_unique<SpriteFontCache>(fs);
167 }
168
169 bool FindFallbackFont(const std::string &, FontSizes, class MissingGlyphSearcher *) const override
170 {
171 return false;
172 }
173
174private:
175 static SpriteFontCacheFactory instance;
176};
177
178/* static */ SpriteFontCacheFactory SpriteFontCacheFactory::instance;
Factory for FontCaches.
Definition fontcache.h:304
Font cache for basic fonts.
Definition fontcache.h:32
int height
The height of the font.
Definition fontcache.h:48
const FontSize fs
The size of the font.
Definition fontcache.h:45
static const int DEFAULT_FONT_ASCENDER[FS_END]
Default unscaled font ascenders.
Definition fontcache.h:29
static const int DEFAULT_FONT_HEIGHT[FS_END]
Default unscaled font heights.
Definition fontcache.h:27
int descender
The descender value of the font.
Definition fontcache.h:50
int ascender
The ascender value of the font.
Definition fontcache.h:49
static void ResetFontCache(FontSize fs)
Reset cached font information.
A searcher for missing glyphs.
SpriteFontCache(FontSize fs)
Create a new sprite font cache.
uint GetGlyphWidth(GlyphID key) override
Get the width of the glyph with the given key.
GlyphID MapCharToGlyph(char32_t key) override
Map a character into a glyph.
bool GetDrawGlyphShadow() override
Do we need to draw a glyph shadow?
void ClearFontCache() override
Clear the font cache.
const Sprite * GetGlyph(GlyphID key) override
Get the glyph (sprite) of the given key.
FontType
Different types of font that can be loaded.
Definition fontcache.h:298
@ Sprite
Bitmap sprites from GRF files.
uint32_t GlyphID
Glyphs are characters from a font.
Definition fontcache.h:18
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition gfx_type.h:17
@ Font
A sprite used for fonts.
FontSize
Available font sizes.
Definition gfx_type.h:248
@ FS_MONO
Index of the monospaced font in the font tables.
Definition gfx_type.h:252
@ FS_SMALL
Index of the small font in the font tables.
Definition gfx_type.h:250
@ FS_BEGIN
First font.
Definition gfx_type.h:255
@ FS_NORMAL
Index of the normal font in the font tables.
Definition gfx_type.h:249
@ FS_LARGE
Index of the large font in the font tables.
Definition gfx_type.h:251
void SetUnicodeGlyph(FontSize fs, char32_t key, SpriteID sprite)
Set the SpriteID for a unicode character.
static const int ASCII_LETTERSTART
First printable ASCII letter.
static std::array< std::unordered_map< char32_t, SpriteID >, FS_END > _char_maps
Glyph map for each font size.
void InitializeUnicodeGlyphMap()
Initialize the glyph map.
static SpriteID GetUnicodeGlyph(FontSize fs, char32_t key)
Get SpriteID associated with a character.
Sprite font cache implementation definition.
Data structure describing a sprite.
uint16_t width
Width of the sprite.
static const uint8_t CLRA
Identifier to clear all glyphs at this codepoint.
Definition unicode.h:15
static RectPadding ScaleGUITrad(const RectPadding &r)
Scale a RectPadding to GUI zoom level.
Definition widget.cpp:49
int ScaleFontTrad(int value)
Scale traditional pixel dimensions to font zoom level, for drawing sprite fonts.
Definition zoom_func.h:127