OpenTTD Source: src/fontcache/truetypefontcache.cpp Source File

OpenTTD Source 14.0-beta3

truetypefontcache.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 <http://www.gnu.org/licenses/>.
6 */
7
10 #include "../stdafx.h"
11 #include "../debug.h"
12 #include "../fontcache.h"
13 #include "../blitter/factory.hpp"
14 #include "../core/bitmath_func.hpp"
15 #include "../gfx_layout.h"
16 #include "truetypefontcache.h"
17
18 #include "../safeguards.h"
19
25 TrueTypeFontCache::TrueTypeFontCache(FontSize fs, int pixels) : FontCache(fs), req_size(pixels), glyph_to_sprite(nullptr)
26 {
27 }
28
32 TrueTypeFontCache::~TrueTypeFontCache()
33 {
34 /* Virtual functions get called statically in destructors, so make it explicit to remove any confusion. */
35 this->TrueTypeFontCache::ClearFontCache();
36
37 for (auto &iter : this->font_tables) {
38 free(iter.second.second);
39 }
40 }
41
45 void TrueTypeFontCache::ClearFontCache()
46 {
47 if (this->glyph_to_sprite == nullptr) return;
48
49 for (int i = 0; i < 256; i++) {
50 if (this->glyph_to_sprite[i] == nullptr) continue;
51
52 for (int j = 0; j < 256; j++) {
53 if (this->glyph_to_sprite[i][j].duplicate) continue;
54 free(this->glyph_to_sprite[i][j].sprite);
55 }
56
57 free(this->glyph_to_sprite[i]);
58 }
59
60 free(this->glyph_to_sprite);
61 this->glyph_to_sprite = nullptr;
62
63 Layouter::ResetFontCache(this->fs);
64 }
65
66
67 TrueTypeFontCache::GlyphEntry *TrueTypeFontCache::GetGlyphPtr(GlyphID key)
68 {
69 if (this->glyph_to_sprite == nullptr) return nullptr;
70 if (this->glyph_to_sprite[GB(key, 8, 8)] == nullptr) return nullptr;
71 return &this->glyph_to_sprite[GB(key, 8, 8)][GB(key, 0, 8)];
72 }
73
74 void TrueTypeFontCache::SetGlyphPtr(GlyphID key, const GlyphEntry *glyph, bool duplicate)
75 {
76 if (this->glyph_to_sprite == nullptr) {
77 Debug(fontcache, 3, "Allocating root glyph cache for size {}", this->fs);
78 this->glyph_to_sprite = CallocT<GlyphEntry*>(256);
79 }
80
81 if (this->glyph_to_sprite[GB(key, 8, 8)] == nullptr) {
82 Debug(fontcache, 3, "Allocating glyph cache for range 0x{:02X}00, size {}", GB(key, 8, 8), this->fs);
83 this->glyph_to_sprite[GB(key, 8, 8)] = CallocT<GlyphEntry>(256);
84 }
85
86 Debug(fontcache, 4, "Set glyph for unicode character 0x{:04X}, size {}", key, this->fs);
87 this->glyph_to_sprite[GB(key, 8, 8)][GB(key, 0, 8)].sprite = glyph->sprite;
88 this->glyph_to_sprite[GB(key, 8, 8)][GB(key, 0, 8)].width = glyph->width;
89 this->glyph_to_sprite[GB(key, 8, 8)][GB(key, 0, 8)].duplicate = duplicate;
90 }
91
92 bool TrueTypeFontCache::GetDrawGlyphShadow()
93 {
94 return this->fs == FS_NORMAL && GetFontAAState(FS_NORMAL);
95 }
96
97 uint TrueTypeFontCache::GetGlyphWidth(GlyphID key)
98 {
99 if ((key & SPRITE_GLYPH) != 0) return this->parent->GetGlyphWidth(key);
100
101 GlyphEntry *glyph = this->GetGlyphPtr(key);
102 if (glyph == nullptr || glyph->sprite == nullptr) {
103 this->GetGlyph(key);
104 glyph = this->GetGlyphPtr(key);
105 }
106
107 return glyph->width;
108 }
109
110 const Sprite *TrueTypeFontCache::GetGlyph(GlyphID key)
111 {
112 if ((key & SPRITE_GLYPH) != 0) return this->parent->GetGlyph(key);
113
114 /* Check for the glyph in our cache */
115 GlyphEntry *glyph = this->GetGlyphPtr(key);
116 if (glyph != nullptr && glyph->sprite != nullptr) return glyph->sprite;
117
118 if (key == 0) {
119 GlyphID question_glyph = this->MapCharToGlyph('?');
120 if (question_glyph == 0) {
121 /* The font misses the '?' character. Use built-in sprite.
122 * Note: We cannot use the baseset as this also has to work in the bootstrap GUI. */
123 #define CPSET { 0, 0, 0, 0, 1 }
124 #define CP___ { 0, 0, 0, 0, 0 }
125 static SpriteLoader::CommonPixel builtin_questionmark_data[10 * 8] = {
126 CP___, CP___, CPSET, CPSET, CPSET, CPSET, CP___, CP___,
127 CP___, CPSET, CPSET, CP___, CP___, CPSET, CPSET, CP___,
128 CP___, CP___, CP___, CP___, CP___, CPSET, CPSET, CP___,
129 CP___, CP___, CP___, CP___, CPSET, CPSET, CP___, CP___,
130 CP___, CP___, CP___, CPSET, CPSET, CP___, CP___, CP___,
131 CP___, CP___, CP___, CPSET, CPSET, CP___, CP___, CP___,
132 CP___, CP___, CP___, CPSET, CPSET, CP___, CP___, CP___,
133 CP___, CP___, CP___, CP___, CP___, CP___, CP___, CP___,
134 CP___, CP___, CP___, CPSET, CPSET, CP___, CP___, CP___,
135 CP___, CP___, CP___, CPSET, CPSET, CP___, CP___, CP___,
136 };
137 #undef CPSET
138 #undef CP___
139 static const SpriteLoader::SpriteCollection builtin_questionmark = {{ {
140 10, // height
141 8, // width
142 0, // x_offs
143 0, // y_offs
144 SpriteType::Font,
145 SCC_PAL,
146 builtin_questionmark_data
147 } }};
148
149 Sprite *spr = BlitterFactory::GetCurrentBlitter()->Encode(builtin_questionmark, SimpleSpriteAlloc);
150 assert(spr != nullptr);
151 GlyphEntry new_glyph;
152 new_glyph.sprite = spr;
153 new_glyph.width = spr->width + (this->fs != FS_NORMAL);
154 this->SetGlyphPtr(key, &new_glyph, false);
155 return new_glyph.sprite;
156 } else {
157 /* Use '?' for missing characters. */
158 this->GetGlyph(question_glyph);
159 glyph = this->GetGlyphPtr(question_glyph);
160 this->SetGlyphPtr(key, glyph, true);
161 return glyph->sprite;
162 }
163 }
164
165 return this->InternalGetGlyph(key, GetFontAAState(this->fs));
166 }
167
168 const void *TrueTypeFontCache::GetFontTable(uint32_t tag, size_t &length)
169 {
170 const auto iter = this->font_tables.find(tag);
171 if (iter != this->font_tables.end()) {
172 length = iter->second.first;
173 return iter->second.second;
174 }
175
176 const void *result = this->InternalGetFontTable(tag, length);
177
178 this->font_tables[tag] = std::pair<size_t, const void *>(length, result);
179 return result;
180 }
SCC_PAL
@ SCC_PAL
Sprite has palette data.
Definition: spriteloader.hpp:25
TrueTypeFontCache::GlyphEntry::sprite
Sprite * sprite
The loaded sprite.
Definition: truetypefontcache.h:35
TrueTypeFontCache::GetFontTable
const void * GetFontTable(uint32_t tag, size_t &length) override
Read a font table from the font.
Definition: truetypefontcache.cpp:168
TrueTypeFontCache::font_tables
FontTable font_tables
Cached font tables.
Definition: truetypefontcache.h:31
TrueTypeFontCache::~TrueTypeFontCache
virtual ~TrueTypeFontCache()
Free everything that was allocated for this font cache.
Definition: truetypefontcache.cpp:32
TrueTypeFontCache::GlyphEntry::duplicate
bool duplicate
Whether this glyph entry is a duplicate, i.e. may this be freed?
Definition: truetypefontcache.h:37
TrueTypeFontCache::glyph_to_sprite
GlyphEntry ** glyph_to_sprite
The glyph cache.
Definition: truetypefontcache.h:53
GB
constexpr static debug_inline uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
Definition: bitmath_func.hpp:32
TrueTypeFontCache::GlyphEntry
Container for information about a glyph.
Definition: truetypefontcache.h:34
Layouter::ResetFontCache
static void ResetFontCache(FontSize size)
Reset cached font information.
Definition: gfx_layout.cpp:351
TrueTypeFontCache::GetGlyphWidth
uint GetGlyphWidth(GlyphID key) override
Get the width of the glyph with the given key.
Definition: truetypefontcache.cpp:97
SpriteType::Font
@ Font
A sprite used for fonts.
TrueTypeFontCache::GetDrawGlyphShadow
bool GetDrawGlyphShadow() override
Do we need to draw a glyph shadow?
Definition: truetypefontcache.cpp:92
SpriteLoader::SpriteCollection
std::array< Sprite, ZOOM_LVL_END > SpriteCollection
Type defining a collection of sprites, one for each zoom level.
Definition: spriteloader.hpp:71
Debug
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
Definition: debug.h:37
FS_NORMAL
@ FS_NORMAL
Index of the normal font in the font tables.
Definition: gfx_type.h:203
free
void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: stdafx.h:379
SpriteLoader::CommonPixel
Definition of a common pixel in OpenTTD's realm.
Definition: spriteloader.hpp:34
Sprite::width
uint16_t width
Width of the sprite.
Definition: spritecache.h:19
BlitterFactory::GetCurrentBlitter
static Blitter * GetCurrentBlitter()
Get the current active blitter (always set by calling SelectBlitter).
Definition: factory.hpp:138
truetypefontcache.h
GlyphID
uint32_t GlyphID
Glyphs are characters from a font.
Definition: fontcache.h:17
FontCache::fs
const FontSize fs
The size of the font.
Definition: fontcache.h:25
FontCache::GetGlyphWidth
virtual uint GetGlyphWidth(GlyphID key)=0
Get the width of the glyph with the given key.
FontCache::MapCharToGlyph
virtual GlyphID MapCharToGlyph(char32_t key, bool fallback=true)=0
Map a character into a glyph.
FontCache
Font cache for basic fonts.
Definition: fontcache.h:21
FontCache::GetGlyph
virtual const Sprite * GetGlyph(GlyphID key)=0
Get the glyph (sprite) of the given key.
FontCache::parent
FontCache * parent
The parent of this font cache.
Definition: fontcache.h:24
TrueTypeFontCache::ClearFontCache
void ClearFontCache() override
Reset cached glyphs.
Definition: truetypefontcache.cpp:45
TrueTypeFontCache::TrueTypeFontCache
TrueTypeFontCache(FontSize fs, int pixels)
Create a new TrueTypeFontCache.
Definition: truetypefontcache.cpp:25
TrueTypeFontCache::GlyphEntry::width
byte width
The width of the glyph.
Definition: truetypefontcache.h:36
FontSize
FontSize
Available font sizes.
Definition: gfx_type.h:202
TrueTypeFontCache::GetGlyph
const Sprite * GetGlyph(GlyphID key) override
Get the glyph (sprite) of the given key.
Definition: truetypefontcache.cpp:110
SimpleSpriteAlloc
void * SimpleSpriteAlloc(size_t size)
Sprite allocator simply using malloc.
Definition: spritecache.cpp:880
Sprite
Data structure describing a sprite.
Definition: spritecache.h:17
SpriteEncoder::Encode
virtual Sprite * Encode(const SpriteLoader::SpriteCollection &sprite, AllocatorProc *allocator)=0
Convert a sprite from the loader to our own format.