mirror of https://github.com/OpenTTD/OpenTTD
Codechange: Decouple glyph map from SpriteFontCache instances.
This makes the map independent from the SpriteFontCache instances.pull/13303/head
parent
9b55a040ac
commit
6a1625f2d0
|
@ -65,16 +65,6 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual int GetFontSize() const { return this->height; }
|
virtual int GetFontSize() const { return this->height; }
|
||||||
|
|
||||||
/**
|
|
||||||
* Map a SpriteID to the key
|
|
||||||
* @param key The key to map to.
|
|
||||||
* @param sprite The sprite that is being mapped.
|
|
||||||
*/
|
|
||||||
virtual void SetUnicodeGlyph(char32_t key, SpriteID sprite) = 0;
|
|
||||||
|
|
||||||
/** Initialize the glyph map */
|
|
||||||
virtual void InitializeUnicodeGlyphMap() = 0;
|
|
||||||
|
|
||||||
/** Clear the font cache. */
|
/** Clear the font cache. */
|
||||||
virtual void ClearFontCache() = 0;
|
virtual void ClearFontCache() = 0;
|
||||||
|
|
||||||
|
@ -148,20 +138,6 @@ public:
|
||||||
virtual bool IsBuiltInFont() = 0;
|
virtual bool IsBuiltInFont() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Map a SpriteID to the font size and key */
|
|
||||||
inline void SetUnicodeGlyph(FontSize size, char32_t key, SpriteID sprite)
|
|
||||||
{
|
|
||||||
FontCache::Get(size)->SetUnicodeGlyph(key, sprite);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Initialize the glyph map */
|
|
||||||
inline void InitializeUnicodeGlyphMap()
|
|
||||||
{
|
|
||||||
for (FontSize fs = FS_BEGIN; fs < FS_END; fs++) {
|
|
||||||
FontCache::Get(fs)->InitializeUnicodeGlyphMap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void ClearFontCache(FontSizes fontsizes)
|
inline void ClearFontCache(FontSizes fontsizes)
|
||||||
{
|
{
|
||||||
for (FontSize fs : fontsizes) {
|
for (FontSize fs : fontsizes) {
|
||||||
|
@ -232,4 +208,8 @@ void UninitFontCache();
|
||||||
bool GetFontAAState();
|
bool GetFontAAState();
|
||||||
void SetFont(FontSize fontsize, const std::string &font, uint size);
|
void SetFont(FontSize fontsize, const std::string &font, uint size);
|
||||||
|
|
||||||
|
/* Implemented in spritefontcache.cpp */
|
||||||
|
void InitializeUnicodeGlyphMap();
|
||||||
|
void SetUnicodeGlyph(FontSize size, char32_t key, SpriteID sprite);
|
||||||
|
|
||||||
#endif /* FONTCACHE_H */
|
#endif /* FONTCACHE_H */
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
/** @file spritefontcache.cpp Sprite fontcache implementation. */
|
/** @file spritefontcache.cpp Sprite fontcache implementation. */
|
||||||
|
|
||||||
#include "../stdafx.h"
|
#include "../stdafx.h"
|
||||||
|
|
||||||
#include "../fontcache.h"
|
#include "../fontcache.h"
|
||||||
#include "../gfx_layout.h"
|
#include "../gfx_layout.h"
|
||||||
#include "../zoom_func.h"
|
#include "../zoom_func.h"
|
||||||
|
@ -19,7 +20,7 @@
|
||||||
|
|
||||||
#include "../safeguards.h"
|
#include "../safeguards.h"
|
||||||
|
|
||||||
static const int ASCII_LETTERSTART = 32; ///< First printable ASCII letter.
|
static std::array<std::unordered_map<char32_t, SpriteID>, FS_END> _glyph_maps{}; ///< Glyph map for each font size.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scale traditional pixel dimensions to font zoom level, for drawing sprite fonts.
|
* Scale traditional pixel dimensions to font zoom level, for drawing sprite fonts.
|
||||||
|
@ -37,61 +38,23 @@ static int ScaleFontTrad(int value)
|
||||||
*/
|
*/
|
||||||
SpriteFontCache::SpriteFontCache(FontSize fs) : FontCache(fs)
|
SpriteFontCache::SpriteFontCache(FontSize fs) : FontCache(fs)
|
||||||
{
|
{
|
||||||
this->InitializeUnicodeGlyphMap();
|
|
||||||
this->height = ScaleGUITrad(FontCache::GetDefaultFontHeight(this->fs));
|
this->height = ScaleGUITrad(FontCache::GetDefaultFontHeight(this->fs));
|
||||||
this->ascender = (this->height - ScaleFontTrad(FontCache::GetDefaultFontHeight(this->fs))) / 2;
|
this->ascender = (this->height - ScaleFontTrad(FontCache::GetDefaultFontHeight(this->fs))) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get SpriteID associated with a GlyphID.
|
* Get the SpriteID associated with a unicode character.
|
||||||
* @param key Glyph to find.
|
* @param key Character to find.
|
||||||
* @return SpriteID of glyph, or 0 if not present.
|
* @return SpriteID of character, or 0 if not present.
|
||||||
*/
|
*/
|
||||||
SpriteID SpriteFontCache::GetUnicodeGlyph(GlyphID key)
|
SpriteID SpriteFontCache::GetSpriteIDForChar(char32_t key)
|
||||||
{
|
{
|
||||||
const auto found = this->glyph_to_spriteid_map.find(key & ~SPRITE_GLYPH);
|
const auto &glyph_map = _glyph_maps[this->fs];
|
||||||
if (found == std::end(this->glyph_to_spriteid_map)) return 0;
|
|
||||||
return found->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpriteFontCache::SetUnicodeGlyph(char32_t key, SpriteID sprite)
|
auto it = glyph_map.find(key);
|
||||||
{
|
if (it != std::end(glyph_map)) return it->second;
|
||||||
this->glyph_to_spriteid_map[key] = sprite;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpriteFontCache::InitializeUnicodeGlyphMap()
|
return 0;
|
||||||
{
|
|
||||||
/* Clear out existing glyph map if it exists */
|
|
||||||
this->glyph_to_spriteid_map.clear();
|
|
||||||
|
|
||||||
SpriteID base;
|
|
||||||
switch (this->fs) {
|
|
||||||
default: NOT_REACHED();
|
|
||||||
case FS_MONO: // Use normal as default for mono spaced font
|
|
||||||
case FS_NORMAL: base = SPR_ASCII_SPACE; break;
|
|
||||||
case FS_SMALL: base = SPR_ASCII_SPACE_SMALL; break;
|
|
||||||
case FS_LARGE: base = SPR_ASCII_SPACE_BIG; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint i = ASCII_LETTERSTART; i < 256; i++) {
|
|
||||||
SpriteID sprite = base + i - ASCII_LETTERSTART;
|
|
||||||
if (!SpriteExists(sprite)) continue;
|
|
||||||
this->SetUnicodeGlyph(i, sprite);
|
|
||||||
this->SetUnicodeGlyph(i + SCC_SPRITE_START, sprite);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto &unicode_map : _default_unicode_map) {
|
|
||||||
uint8_t key = unicode_map.key;
|
|
||||||
if (key == CLRA) {
|
|
||||||
/* Clear the glyph. This happens if the glyph at this code point
|
|
||||||
* is non-standard and should be accessed by an SCC_xxx enum
|
|
||||||
* entry only. */
|
|
||||||
this->SetUnicodeGlyph(unicode_map.code, 0);
|
|
||||||
} else {
|
|
||||||
SpriteID sprite = base + key - ASCII_LETTERSTART;
|
|
||||||
this->SetUnicodeGlyph(unicode_map.code, sprite);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpriteFontCache::ClearFontCache()
|
void SpriteFontCache::ClearFontCache()
|
||||||
|
@ -103,22 +66,22 @@ void SpriteFontCache::ClearFontCache()
|
||||||
|
|
||||||
const Sprite *SpriteFontCache::GetGlyph(GlyphID key)
|
const Sprite *SpriteFontCache::GetGlyph(GlyphID key)
|
||||||
{
|
{
|
||||||
SpriteID sprite = this->GetUnicodeGlyph(static_cast<char32_t>(key & ~SPRITE_GLYPH));
|
SpriteID sprite = this->GetSpriteIDForChar(static_cast<char32_t>(key & ~SPRITE_GLYPH));
|
||||||
if (sprite == 0) sprite = this->GetUnicodeGlyph('?');
|
if (sprite == 0) sprite = this->GetSpriteIDForChar('?');
|
||||||
return GetSprite(sprite, SpriteType::Font);
|
return GetSprite(sprite, SpriteType::Font);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint SpriteFontCache::GetGlyphWidth(GlyphID key)
|
uint SpriteFontCache::GetGlyphWidth(GlyphID key)
|
||||||
{
|
{
|
||||||
SpriteID sprite = this->GetUnicodeGlyph(static_cast<char32_t>(key & ~SPRITE_GLYPH));
|
SpriteID sprite = this->GetSpriteIDForChar(static_cast<char32_t>(key & ~SPRITE_GLYPH));
|
||||||
if (sprite == 0) sprite = this->GetUnicodeGlyph('?');
|
if (sprite == 0) sprite = this->GetSpriteIDForChar('?');
|
||||||
return SpriteExists(sprite) ? GetSprite(sprite, SpriteType::Font)->width + ScaleFontTrad(this->fs != FS_NORMAL ? 1 : 0) : 0;
|
return SpriteExists(sprite) ? GetSprite(sprite, SpriteType::Font)->width + ScaleFontTrad(this->fs != FS_NORMAL ? 1 : 0) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
GlyphID SpriteFontCache::MapCharToGlyph(char32_t key, [[maybe_unused]] bool allow_fallback)
|
GlyphID SpriteFontCache::MapCharToGlyph(char32_t key, [[maybe_unused]] bool allow_fallback)
|
||||||
{
|
{
|
||||||
assert(IsPrintable(key));
|
assert(IsPrintable(key));
|
||||||
SpriteID sprite = this->GetUnicodeGlyph(key);
|
SpriteID sprite = this->GetSpriteIDForChar(key);
|
||||||
if (sprite == 0) return 0;
|
if (sprite == 0) return 0;
|
||||||
return SPRITE_GLYPH | key;
|
return SPRITE_GLYPH | key;
|
||||||
}
|
}
|
||||||
|
@ -127,3 +90,79 @@ bool SpriteFontCache::GetDrawGlyphShadow()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the SpriteID for a unicode character.
|
||||||
|
* @param fs Font size to set.
|
||||||
|
* @param key Unicode character to set.
|
||||||
|
* @param sprite SpriteID of character.
|
||||||
|
*/
|
||||||
|
void SetUnicodeGlyph(FontSize fs, char32_t key, SpriteID sprite)
|
||||||
|
{
|
||||||
|
_glyph_maps[fs][key] = sprite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the sprite font base sprite index.
|
||||||
|
* @param fs Font size to get base sprite for.
|
||||||
|
* @return Base sprite for font.
|
||||||
|
*/
|
||||||
|
static SpriteID GetSpriteFontBase(FontSize fs)
|
||||||
|
{
|
||||||
|
switch (fs) {
|
||||||
|
default: NOT_REACHED();
|
||||||
|
case FS_MONO: // Use normal as default for mono spaced font
|
||||||
|
case FS_NORMAL: return SPR_ASCII_SPACE;
|
||||||
|
case FS_SMALL: return SPR_ASCII_SPACE_SMALL;
|
||||||
|
case FS_LARGE: return SPR_ASCII_SPACE_BIG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the glyph map for a font size.
|
||||||
|
* This populates the glyph map with the baseset font sprites.
|
||||||
|
* @param fs Font size to initialize.
|
||||||
|
*/
|
||||||
|
void InitializeUnicodeGlyphMap(FontSize fs)
|
||||||
|
{
|
||||||
|
static constexpr int ASCII_LETTERSTART = 32; ///< First printable ASCII letter.
|
||||||
|
|
||||||
|
/* Clear existing glyph map. */
|
||||||
|
_glyph_maps[fs].clear();
|
||||||
|
|
||||||
|
SpriteID base = GetSpriteFontBase(fs);
|
||||||
|
for (uint i = ASCII_LETTERSTART; i < 256; i++) {
|
||||||
|
SpriteID sprite = base + i - ASCII_LETTERSTART;
|
||||||
|
if (!SpriteExists(sprite)) continue;
|
||||||
|
|
||||||
|
/* Map the glyph for normal use. */
|
||||||
|
SetUnicodeGlyph(fs, i, sprite);
|
||||||
|
|
||||||
|
/* Glyphs are also mapped to the first private use area. */
|
||||||
|
SetUnicodeGlyph(fs, i + SCC_SPRITE_START, sprite);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Modify map to move non-standard glyphs to a better unicode codepoint. */
|
||||||
|
for (const auto &unicode_map : _default_unicode_map) {
|
||||||
|
uint8_t key = unicode_map.key;
|
||||||
|
if (key == CLRA) {
|
||||||
|
/* Clear the glyph. This happens if the glyph at this code point
|
||||||
|
* is non-standard and should be accessed by an SCC_xxx enum
|
||||||
|
* entry only. */
|
||||||
|
_glyph_maps[fs].erase(unicode_map.code);
|
||||||
|
} else {
|
||||||
|
SpriteID sprite = base + key - ASCII_LETTERSTART;
|
||||||
|
SetUnicodeGlyph(fs, unicode_map.code, sprite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the glyph map.
|
||||||
|
*/
|
||||||
|
void InitializeUnicodeGlyphMap()
|
||||||
|
{
|
||||||
|
for (FontSize fs = FS_BEGIN; fs < FS_END; fs++) {
|
||||||
|
InitializeUnicodeGlyphMap(fs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
class SpriteFontCache : public FontCache {
|
class SpriteFontCache : public FontCache {
|
||||||
public:
|
public:
|
||||||
SpriteFontCache(FontSize fs);
|
SpriteFontCache(FontSize fs);
|
||||||
void SetUnicodeGlyph(char32_t key, SpriteID sprite) override;
|
|
||||||
void InitializeUnicodeGlyphMap() override;
|
|
||||||
void ClearFontCache() override;
|
void ClearFontCache() override;
|
||||||
const Sprite *GetGlyph(GlyphID key) override;
|
const Sprite *GetGlyph(GlyphID key) override;
|
||||||
uint GetGlyphWidth(GlyphID key) override;
|
uint GetGlyphWidth(GlyphID key) override;
|
||||||
|
@ -28,8 +26,7 @@ public:
|
||||||
bool IsBuiltInFont() override { return true; }
|
bool IsBuiltInFont() override { return true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<GlyphID, SpriteID> glyph_to_spriteid_map{}; ///< Mapping of glyphs to sprite IDs.
|
SpriteID GetSpriteIDForChar(char32_t key);
|
||||||
SpriteID GetUnicodeGlyph(GlyphID key);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* SPRITEFONTCACHE_H */
|
#endif /* SPRITEFONTCACHE_H */
|
||||||
|
|
|
@ -46,8 +46,6 @@ public:
|
||||||
TrueTypeFontCache(FontSize fs, int pixels);
|
TrueTypeFontCache(FontSize fs, int pixels);
|
||||||
virtual ~TrueTypeFontCache();
|
virtual ~TrueTypeFontCache();
|
||||||
int GetFontSize() const override { return this->used_size; }
|
int GetFontSize() const override { return this->used_size; }
|
||||||
void SetUnicodeGlyph(char32_t key, SpriteID sprite) override { this->parent->SetUnicodeGlyph(key, sprite); }
|
|
||||||
void InitializeUnicodeGlyphMap() override { this->parent->InitializeUnicodeGlyphMap(); }
|
|
||||||
const Sprite *GetGlyph(GlyphID key) override;
|
const Sprite *GetGlyph(GlyphID key) override;
|
||||||
void ClearFontCache() override;
|
void ClearFontCache() override;
|
||||||
uint GetGlyphWidth(GlyphID key) override;
|
uint GetGlyphWidth(GlyphID key) override;
|
||||||
|
|
|
@ -21,8 +21,6 @@ public:
|
||||||
this->height = FontCache::GetDefaultFontHeight(this->fs);
|
this->height = FontCache::GetDefaultFontHeight(this->fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetUnicodeGlyph(char32_t, SpriteID) override {}
|
|
||||||
void InitializeUnicodeGlyphMap() override {}
|
|
||||||
void ClearFontCache() override {}
|
void ClearFontCache() override {}
|
||||||
const Sprite *GetGlyph(GlyphID) override { return nullptr; }
|
const Sprite *GetGlyph(GlyphID) override { return nullptr; }
|
||||||
uint GetGlyphWidth(GlyphID) override { return this->height / 2; }
|
uint GetGlyphWidth(GlyphID) override { return this->height / 2; }
|
||||||
|
|
Loading…
Reference in New Issue