1
0
Fork 0

Codechange: Decouple glyph map from SpriteFontCache instances.

This makes the map independent from the SpriteFontCache instances.
pull/13303/head
Peter Nelson 2024-07-02 08:57:32 +01:00
parent 9b55a040ac
commit 6a1625f2d0
No known key found for this signature in database
GPG Key ID: 8EF8F0A467DF75ED
5 changed files with 96 additions and 84 deletions

View File

@ -65,16 +65,6 @@ public:
*/
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. */
virtual void ClearFontCache() = 0;
@ -148,20 +138,6 @@ public:
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)
{
for (FontSize fs : fontsizes) {
@ -232,4 +208,8 @@ void UninitFontCache();
bool GetFontAAState();
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 */

View File

@ -8,6 +8,7 @@
/** @file spritefontcache.cpp Sprite fontcache implementation. */
#include "../stdafx.h"
#include "../fontcache.h"
#include "../gfx_layout.h"
#include "../zoom_func.h"
@ -19,7 +20,7 @@
#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.
@ -37,61 +38,23 @@ static int ScaleFontTrad(int value)
*/
SpriteFontCache::SpriteFontCache(FontSize fs) : FontCache(fs)
{
this->InitializeUnicodeGlyphMap();
this->height = ScaleGUITrad(FontCache::GetDefaultFontHeight(this->fs));
this->ascender = (this->height - ScaleFontTrad(FontCache::GetDefaultFontHeight(this->fs))) / 2;
}
/**
* Get SpriteID associated with a GlyphID.
* @param key Glyph to find.
* @return SpriteID of glyph, or 0 if not present.
* Get the SpriteID associated with a unicode character.
* @param key Character to find.
* @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);
if (found == std::end(this->glyph_to_spriteid_map)) return 0;
return found->second;
}
const auto &glyph_map = _glyph_maps[this->fs];
void SpriteFontCache::SetUnicodeGlyph(char32_t key, SpriteID sprite)
{
this->glyph_to_spriteid_map[key] = sprite;
}
auto it = glyph_map.find(key);
if (it != std::end(glyph_map)) return it->second;
void SpriteFontCache::InitializeUnicodeGlyphMap()
{
/* 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);
}
}
return 0;
}
void SpriteFontCache::ClearFontCache()
@ -103,22 +66,22 @@ void SpriteFontCache::ClearFontCache()
const Sprite *SpriteFontCache::GetGlyph(GlyphID key)
{
SpriteID sprite = this->GetUnicodeGlyph(static_cast<char32_t>(key & ~SPRITE_GLYPH));
if (sprite == 0) sprite = this->GetUnicodeGlyph('?');
SpriteID sprite = this->GetSpriteIDForChar(static_cast<char32_t>(key & ~SPRITE_GLYPH));
if (sprite == 0) sprite = this->GetSpriteIDForChar('?');
return GetSprite(sprite, SpriteType::Font);
}
uint SpriteFontCache::GetGlyphWidth(GlyphID key)
{
SpriteID sprite = this->GetUnicodeGlyph(static_cast<char32_t>(key & ~SPRITE_GLYPH));
if (sprite == 0) sprite = this->GetUnicodeGlyph('?');
SpriteID sprite = this->GetSpriteIDForChar(static_cast<char32_t>(key & ~SPRITE_GLYPH));
if (sprite == 0) sprite = this->GetSpriteIDForChar('?');
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)
{
assert(IsPrintable(key));
SpriteID sprite = this->GetUnicodeGlyph(key);
SpriteID sprite = this->GetSpriteIDForChar(key);
if (sprite == 0) return 0;
return SPRITE_GLYPH | key;
}
@ -127,3 +90,79 @@ bool SpriteFontCache::GetDrawGlyphShadow()
{
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);
}
}

View File

@ -17,8 +17,6 @@
class SpriteFontCache : public FontCache {
public:
SpriteFontCache(FontSize fs);
void SetUnicodeGlyph(char32_t key, SpriteID sprite) override;
void InitializeUnicodeGlyphMap() override;
void ClearFontCache() override;
const Sprite *GetGlyph(GlyphID key) override;
uint GetGlyphWidth(GlyphID key) override;
@ -28,8 +26,7 @@ public:
bool IsBuiltInFont() override { return true; }
private:
std::unordered_map<GlyphID, SpriteID> glyph_to_spriteid_map{}; ///< Mapping of glyphs to sprite IDs.
SpriteID GetUnicodeGlyph(GlyphID key);
SpriteID GetSpriteIDForChar(char32_t key);
};
#endif /* SPRITEFONTCACHE_H */

View File

@ -46,8 +46,6 @@ public:
TrueTypeFontCache(FontSize fs, int pixels);
virtual ~TrueTypeFontCache();
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;
void ClearFontCache() override;
uint GetGlyphWidth(GlyphID key) override;

View File

@ -21,8 +21,6 @@ public:
this->height = FontCache::GetDefaultFontHeight(this->fs);
}
void SetUnicodeGlyph(char32_t, SpriteID) override {}
void InitializeUnicodeGlyphMap() override {}
void ClearFontCache() override {}
const Sprite *GetGlyph(GlyphID) override { return nullptr; }
uint GetGlyphWidth(GlyphID) override { return this->height / 2; }