(svn r25462) -Codechange: make a better distinction between characters and glyphs

This commit is contained in:
rubidium 2013-06-25 20:20:15 +00:00
parent b4106e686b
commit 092c33be3f
2 changed files with 64 additions and 44 deletions

View File

@ -65,13 +65,14 @@ private:
public: public:
SpriteFontCache(FontSize fs); SpriteFontCache(FontSize fs);
~SpriteFontCache(); ~SpriteFontCache();
virtual SpriteID GetUnicodeGlyph(uint32 key); virtual SpriteID GetUnicodeGlyph(WChar key);
virtual void SetUnicodeGlyph(uint32 key, SpriteID sprite); virtual void SetUnicodeGlyph(WChar key, SpriteID sprite);
virtual void InitializeUnicodeGlyphMap(); virtual void InitializeUnicodeGlyphMap();
virtual void ClearFontCache(); virtual void ClearFontCache();
virtual const Sprite *GetGlyph(uint32 key); virtual const Sprite *GetGlyph(GlyphID key);
virtual uint GetGlyphWidth(uint32 key); virtual uint GetGlyphWidth(GlyphID key);
virtual bool GetDrawGlyphShadow(); virtual bool GetDrawGlyphShadow();
virtual GlyphID MapCharToGlyph(WChar key) { return SPRITE_GLYPH | key; }
}; };
/** /**
@ -91,13 +92,13 @@ SpriteFontCache::~SpriteFontCache()
this->ClearGlyphToSpriteMap(); this->ClearGlyphToSpriteMap();
} }
SpriteID SpriteFontCache::GetUnicodeGlyph(uint32 key) SpriteID SpriteFontCache::GetUnicodeGlyph(GlyphID key)
{ {
if (this->glyph_to_spriteid_map[GB(key, 8, 8)] == NULL) return 0; if (this->glyph_to_spriteid_map[GB(key, 8, 8)] == NULL) return 0;
return this->glyph_to_spriteid_map[GB(key, 8, 8)][GB(key, 0, 8)]; return this->glyph_to_spriteid_map[GB(key, 8, 8)][GB(key, 0, 8)];
} }
void SpriteFontCache::SetUnicodeGlyph(uint32 key, SpriteID sprite) void SpriteFontCache::SetUnicodeGlyph(GlyphID key, SpriteID sprite)
{ {
if (this->glyph_to_spriteid_map == NULL) this->glyph_to_spriteid_map = CallocT<SpriteID*>(256); if (this->glyph_to_spriteid_map == NULL) this->glyph_to_spriteid_map = CallocT<SpriteID*>(256);
if (this->glyph_to_spriteid_map[GB(key, 8, 8)] == NULL) this->glyph_to_spriteid_map[GB(key, 8, 8)] = CallocT<SpriteID>(256); if (this->glyph_to_spriteid_map[GB(key, 8, 8)] == NULL) this->glyph_to_spriteid_map[GB(key, 8, 8)] = CallocT<SpriteID>(256);
@ -155,14 +156,14 @@ void SpriteFontCache::ClearGlyphToSpriteMap()
void SpriteFontCache::ClearFontCache() {} void SpriteFontCache::ClearFontCache() {}
const Sprite *SpriteFontCache::GetGlyph(uint32 key) const Sprite *SpriteFontCache::GetGlyph(GlyphID key)
{ {
SpriteID sprite = this->GetUnicodeGlyph(key); SpriteID sprite = this->GetUnicodeGlyph(key);
if (sprite == 0) sprite = this->GetUnicodeGlyph('?'); if (sprite == 0) sprite = this->GetUnicodeGlyph('?');
return GetSprite(sprite, ST_FONT); return GetSprite(sprite, ST_FONT);
} }
uint SpriteFontCache::GetGlyphWidth(uint32 key) uint SpriteFontCache::GetGlyphWidth(GlyphID key)
{ {
SpriteID sprite = this->GetUnicodeGlyph(key); SpriteID sprite = this->GetUnicodeGlyph(key);
if (sprite == 0) sprite = this->GetUnicodeGlyph('?'); if (sprite == 0) sprite = this->GetUnicodeGlyph('?');
@ -211,19 +212,20 @@ private:
*/ */
GlyphEntry **glyph_to_sprite; GlyphEntry **glyph_to_sprite;
GlyphEntry *GetGlyphPtr(WChar key); GlyphEntry *GetGlyphPtr(GlyphID key);
void SetGlyphPtr(WChar key, const GlyphEntry *glyph, bool duplicate = false); void SetGlyphPtr(GlyphID key, const GlyphEntry *glyph, bool duplicate = false);
public: public:
FreeTypeFontCache(FontSize fs, FT_Face face, int pixels); FreeTypeFontCache(FontSize fs, FT_Face face, int pixels);
~FreeTypeFontCache(); ~FreeTypeFontCache();
virtual SpriteID GetUnicodeGlyph(uint32 key) { return this->parent->GetUnicodeGlyph(key); } virtual SpriteID GetUnicodeGlyph(WChar key) { return this->parent->GetUnicodeGlyph(key); }
virtual void SetUnicodeGlyph(uint32 key, SpriteID sprite) { this->parent->SetUnicodeGlyph(key, sprite); } virtual void SetUnicodeGlyph(WChar key, SpriteID sprite) { this->parent->SetUnicodeGlyph(key, sprite); }
virtual void InitializeUnicodeGlyphMap() { this->parent->InitializeUnicodeGlyphMap(); } virtual void InitializeUnicodeGlyphMap() { this->parent->InitializeUnicodeGlyphMap(); }
virtual void ClearFontCache(); virtual void ClearFontCache();
virtual const Sprite *GetGlyph(uint32 key); virtual const Sprite *GetGlyph(GlyphID key);
virtual uint GetGlyphWidth(uint32 key); virtual uint GetGlyphWidth(GlyphID key);
virtual bool GetDrawGlyphShadow(); virtual bool GetDrawGlyphShadow();
virtual GlyphID MapCharToGlyph(WChar key);
}; };
FT_Library _library = NULL; FT_Library _library = NULL;
@ -379,7 +381,7 @@ void FreeTypeFontCache::ClearFontCache()
this->glyph_to_sprite = NULL; this->glyph_to_sprite = NULL;
} }
FreeTypeFontCache::GlyphEntry *FreeTypeFontCache::GetGlyphPtr(WChar key) FreeTypeFontCache::GlyphEntry *FreeTypeFontCache::GetGlyphPtr(GlyphID key)
{ {
if (this->glyph_to_sprite == NULL) return NULL; if (this->glyph_to_sprite == NULL) return NULL;
if (this->glyph_to_sprite[GB(key, 8, 8)] == NULL) return NULL; if (this->glyph_to_sprite[GB(key, 8, 8)] == NULL) return NULL;
@ -387,7 +389,7 @@ FreeTypeFontCache::GlyphEntry *FreeTypeFontCache::GetGlyphPtr(WChar key)
} }
void FreeTypeFontCache::SetGlyphPtr(WChar key, const GlyphEntry *glyph, bool duplicate) void FreeTypeFontCache::SetGlyphPtr(GlyphID key, const GlyphEntry *glyph, bool duplicate)
{ {
if (this->glyph_to_sprite == NULL) { if (this->glyph_to_sprite == NULL) {
DEBUG(freetype, 3, "Allocating root glyph cache for size %u", this->fs); DEBUG(freetype, 3, "Allocating root glyph cache for size %u", this->fs);
@ -427,14 +429,9 @@ static bool GetFontAAState(FontSize size)
} }
const Sprite *FreeTypeFontCache::GetGlyph(WChar key) const Sprite *FreeTypeFontCache::GetGlyph(GlyphID key)
{ {
assert(IsPrintable(key)); if ((key & SPRITE_GLYPH) != 0) return parent->GetGlyph(key);
/* Bail out for our special characters */
if (key >= SCC_SPRITE_START && key <= SCC_SPRITE_END) {
return parent->GetGlyph(key);
}
/* Check for the glyph in our cache */ /* Check for the glyph in our cache */
GlyphEntry *glyph = this->GetGlyphPtr(key); GlyphEntry *glyph = this->GetGlyphPtr(key);
@ -444,10 +441,10 @@ const Sprite *FreeTypeFontCache::GetGlyph(WChar key)
bool aa = GetFontAAState(this->fs); bool aa = GetFontAAState(this->fs);
FT_UInt glyph_index = FT_Get_Char_Index(this->face, key);
GlyphEntry new_glyph; GlyphEntry new_glyph;
if (glyph_index == 0) { if (key == 0) {
if (key == '?') { GlyphID question_glyph = this->MapCharToGlyph('?');
if (question_glyph == 0) {
/* The font misses the '?' character. Use sprite font. */ /* The font misses the '?' character. Use sprite font. */
SpriteID sprite = this->GetUnicodeGlyph(key); SpriteID sprite = this->GetUnicodeGlyph(key);
Sprite *spr = (Sprite*)GetRawSprite(sprite, ST_FONT, AllocateFont); Sprite *spr = (Sprite*)GetRawSprite(sprite, ST_FONT, AllocateFont);
@ -458,13 +455,13 @@ const Sprite *FreeTypeFontCache::GetGlyph(WChar key)
return new_glyph.sprite; return new_glyph.sprite;
} else { } else {
/* Use '?' for missing characters. */ /* Use '?' for missing characters. */
this->GetGlyph('?'); this->GetGlyph(question_glyph);
glyph = this->GetGlyphPtr('?'); glyph = this->GetGlyphPtr(question_glyph);
this->SetGlyphPtr(key, glyph, true); this->SetGlyphPtr(key, glyph, true);
return glyph->sprite; return glyph->sprite;
} }
} }
FT_Load_Glyph(this->face, glyph_index, FT_LOAD_DEFAULT); FT_Load_Glyph(this->face, key, FT_LOAD_DEFAULT);
FT_Render_Glyph(this->face->glyph, aa ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO); FT_Render_Glyph(this->face->glyph, aa ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO);
/* Despite requesting a normal glyph, FreeType may have returned a bitmap */ /* Despite requesting a normal glyph, FreeType may have returned a bitmap */
@ -518,15 +515,13 @@ const Sprite *FreeTypeFontCache::GetGlyph(WChar key)
bool FreeTypeFontCache::GetDrawGlyphShadow() bool FreeTypeFontCache::GetDrawGlyphShadow()
{ {
return GetFontAAState(FS_NORMAL); return this->fs == FS_NORMAL && GetFontAAState(FS_NORMAL);
} }
uint FreeTypeFontCache::GetGlyphWidth(WChar key) uint FreeTypeFontCache::GetGlyphWidth(GlyphID key)
{ {
if (key >= SCC_SPRITE_START && key <= SCC_SPRITE_END) { if ((key & SPRITE_GLYPH) != 0) return this->parent->GetGlyphWidth(key);
return this->parent->GetGlyphWidth(key);
}
GlyphEntry *glyph = this->GetGlyphPtr(key); GlyphEntry *glyph = this->GetGlyphPtr(key);
if (glyph == NULL || glyph->sprite == NULL) { if (glyph == NULL || glyph->sprite == NULL) {
@ -537,6 +532,17 @@ uint FreeTypeFontCache::GetGlyphWidth(WChar key)
return glyph->width; return glyph->width;
} }
GlyphID FreeTypeFontCache::MapCharToGlyph(WChar key)
{
assert(IsPrintable(key));
if (key >= SCC_SPRITE_START && key <= SCC_SPRITE_END) {
return this->parent->MapCharToGlyph(key);
}
return FT_Get_Char_Index(this->face, key);
}
#endif /* WITH_FREETYPE */ #endif /* WITH_FREETYPE */
/** /**

View File

@ -12,8 +12,13 @@
#ifndef FONTCACHE_H #ifndef FONTCACHE_H
#define FONTCACHE_H #define FONTCACHE_H
#include "string_type.h"
#include "spritecache.h" #include "spritecache.h"
/** Glyphs are characters from a font. */
typedef uint32 GlyphID;
static const GlyphID SPRITE_GLYPH = 1U << 30;
/** Font cache for basic fonts. */ /** Font cache for basic fonts. */
class FontCache { class FontCache {
private: private:
@ -37,14 +42,14 @@ public:
* @param key The key to get the sprite for. * @param key The key to get the sprite for.
* @return The sprite. * @return The sprite.
*/ */
virtual SpriteID GetUnicodeGlyph(uint32 key) = 0; virtual SpriteID GetUnicodeGlyph(WChar key) = 0;
/** /**
* Map a SpriteID to the key * Map a SpriteID to the key
* @param key The key to map to. * @param key The key to map to.
* @param sprite The sprite that is being mapped. * @param sprite The sprite that is being mapped.
*/ */
virtual void SetUnicodeGlyph(uint32 key, SpriteID sprite) = 0; virtual void SetUnicodeGlyph(WChar key, SpriteID sprite) = 0;
/** Initialize the glyph map */ /** Initialize the glyph map */
virtual void InitializeUnicodeGlyphMap() = 0; virtual void InitializeUnicodeGlyphMap() = 0;
@ -57,14 +62,14 @@ public:
* @param key The key to look up. * @param key The key to look up.
* @return The sprite. * @return The sprite.
*/ */
virtual const Sprite *GetGlyph(uint32 key) = 0; virtual const Sprite *GetGlyph(GlyphID key) = 0;
/** /**
* Get the width of the glyph with the given key. * Get the width of the glyph with the given key.
* @param key The key to look up. * @param key The key to look up.
* @return The width. * @return The width.
*/ */
virtual uint GetGlyphWidth(uint32 key) = 0; virtual uint GetGlyphWidth(GlyphID key) = 0;
/** /**
* Do we need to draw a glyph shadow? * Do we need to draw a glyph shadow?
@ -72,6 +77,13 @@ public:
*/ */
virtual bool GetDrawGlyphShadow() = 0; virtual bool GetDrawGlyphShadow() = 0;
/**
* Map a character into a glyph.
* @param key The character.
* @return The glyph ID used to draw the character.
*/
virtual GlyphID MapCharToGlyph(WChar key) = 0;
/** /**
* Get the font cache of a given font size. * Get the font cache of a given font size.
* @param fs The font size to look up. * @param fs The font size to look up.
@ -93,13 +105,13 @@ public:
}; };
/** Get the SpriteID mapped to the given font size and key */ /** Get the SpriteID mapped to the given font size and key */
static inline SpriteID GetUnicodeGlyph(FontSize size, uint32 key) static inline SpriteID GetUnicodeGlyph(FontSize size, WChar key)
{ {
return FontCache::Get(size)->GetUnicodeGlyph(key); return FontCache::Get(size)->GetUnicodeGlyph(key);
} }
/** Map a SpriteID to the font size and key */ /** Map a SpriteID to the font size and key */
static inline void SetUnicodeGlyph(FontSize size, uint32 key, SpriteID sprite) static inline void SetUnicodeGlyph(FontSize size, WChar key, SpriteID sprite)
{ {
FontCache::Get(size)->SetUnicodeGlyph(key, sprite); FontCache::Get(size)->SetUnicodeGlyph(key, sprite);
} }
@ -119,15 +131,17 @@ static inline void ClearFontCache() {
} }
/** Get the Sprite for a glyph */ /** Get the Sprite for a glyph */
static inline const Sprite *GetGlyph(FontSize size, uint32 key) static inline const Sprite *GetGlyph(FontSize size, WChar key)
{ {
return FontCache::Get(size)->GetGlyph(key); FontCache *fc = FontCache::Get(size);
return fc->GetGlyph(fc->MapCharToGlyph(key));
} }
/** Get the width of a glyph */ /** Get the width of a glyph */
static inline uint GetGlyphWidth(FontSize size, uint32 key) static inline uint GetGlyphWidth(FontSize size, WChar key)
{ {
return FontCache::Get(size)->GetGlyphWidth(key); FontCache *fc = FontCache::Get(size);
return fc->GetGlyphWidth(fc->MapCharToGlyph(key));
} }
static inline bool GetDrawGlyphShadow(FontSize size) static inline bool GetDrawGlyphShadow(FontSize size)