diff --git a/src/fontcache.cpp b/src/fontcache.cpp --- a/src/fontcache.cpp +++ b/src/fontcache.cpp @@ -65,13 +65,14 @@ private: public: SpriteFontCache(FontSize fs); ~SpriteFontCache(); - virtual SpriteID GetUnicodeGlyph(uint32 key); - virtual void SetUnicodeGlyph(uint32 key, SpriteID sprite); + virtual SpriteID GetUnicodeGlyph(WChar key); + virtual void SetUnicodeGlyph(WChar key, SpriteID sprite); virtual void InitializeUnicodeGlyphMap(); virtual void ClearFontCache(); - virtual const Sprite *GetGlyph(uint32 key); - virtual uint GetGlyphWidth(uint32 key); + virtual const Sprite *GetGlyph(GlyphID key); + virtual uint GetGlyphWidth(GlyphID key); virtual bool GetDrawGlyphShadow(); + virtual GlyphID MapCharToGlyph(WChar key) { return SPRITE_GLYPH | key; } }; /** @@ -91,13 +92,13 @@ SpriteFontCache::~SpriteFontCache() 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; 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(256); if (this->glyph_to_spriteid_map[GB(key, 8, 8)] == NULL) this->glyph_to_spriteid_map[GB(key, 8, 8)] = CallocT(256); @@ -155,14 +156,14 @@ void SpriteFontCache::ClearGlyphToSprite void SpriteFontCache::ClearFontCache() {} -const Sprite *SpriteFontCache::GetGlyph(uint32 key) +const Sprite *SpriteFontCache::GetGlyph(GlyphID key) { SpriteID sprite = this->GetUnicodeGlyph(key); if (sprite == 0) sprite = this->GetUnicodeGlyph('?'); return GetSprite(sprite, ST_FONT); } -uint SpriteFontCache::GetGlyphWidth(uint32 key) +uint SpriteFontCache::GetGlyphWidth(GlyphID key) { SpriteID sprite = this->GetUnicodeGlyph(key); if (sprite == 0) sprite = this->GetUnicodeGlyph('?'); @@ -211,19 +212,20 @@ private: */ GlyphEntry **glyph_to_sprite; - GlyphEntry *GetGlyphPtr(WChar key); - void SetGlyphPtr(WChar key, const GlyphEntry *glyph, bool duplicate = false); + GlyphEntry *GetGlyphPtr(GlyphID key); + void SetGlyphPtr(GlyphID key, const GlyphEntry *glyph, bool duplicate = false); public: FreeTypeFontCache(FontSize fs, FT_Face face, int pixels); ~FreeTypeFontCache(); - virtual SpriteID GetUnicodeGlyph(uint32 key) { return this->parent->GetUnicodeGlyph(key); } - virtual void SetUnicodeGlyph(uint32 key, SpriteID sprite) { this->parent->SetUnicodeGlyph(key, sprite); } + virtual SpriteID GetUnicodeGlyph(WChar key) { return this->parent->GetUnicodeGlyph(key); } + virtual void SetUnicodeGlyph(WChar key, SpriteID sprite) { this->parent->SetUnicodeGlyph(key, sprite); } virtual void InitializeUnicodeGlyphMap() { this->parent->InitializeUnicodeGlyphMap(); } virtual void ClearFontCache(); - virtual const Sprite *GetGlyph(uint32 key); - virtual uint GetGlyphWidth(uint32 key); + virtual const Sprite *GetGlyph(GlyphID key); + virtual uint GetGlyphWidth(GlyphID key); virtual bool GetDrawGlyphShadow(); + virtual GlyphID MapCharToGlyph(WChar key); }; FT_Library _library = NULL; @@ -379,7 +381,7 @@ void FreeTypeFontCache::ClearFontCache() 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[GB(key, 8, 8)] == NULL) return NULL; @@ -387,7 +389,7 @@ FreeTypeFontCache::GlyphEntry *FreeTypeF } -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) { 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)); - - /* Bail out for our special characters */ - if (key >= SCC_SPRITE_START && key <= SCC_SPRITE_END) { - return parent->GetGlyph(key); - } + if ((key & SPRITE_GLYPH) != 0) return parent->GetGlyph(key); /* Check for the glyph in our cache */ GlyphEntry *glyph = this->GetGlyphPtr(key); @@ -444,10 +441,10 @@ const Sprite *FreeTypeFontCache::GetGlyp bool aa = GetFontAAState(this->fs); - FT_UInt glyph_index = FT_Get_Char_Index(this->face, key); GlyphEntry new_glyph; - if (glyph_index == 0) { - if (key == '?') { + if (key == 0) { + GlyphID question_glyph = this->MapCharToGlyph('?'); + if (question_glyph == 0) { /* The font misses the '?' character. Use sprite font. */ SpriteID sprite = this->GetUnicodeGlyph(key); Sprite *spr = (Sprite*)GetRawSprite(sprite, ST_FONT, AllocateFont); @@ -458,13 +455,13 @@ const Sprite *FreeTypeFontCache::GetGlyp return new_glyph.sprite; } else { /* Use '?' for missing characters. */ - this->GetGlyph('?'); - glyph = this->GetGlyphPtr('?'); + this->GetGlyph(question_glyph); + glyph = this->GetGlyphPtr(question_glyph); this->SetGlyphPtr(key, glyph, true); 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); /* Despite requesting a normal glyph, FreeType may have returned a bitmap */ @@ -518,15 +515,13 @@ const Sprite *FreeTypeFontCache::GetGlyp 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) { - return this->parent->GetGlyphWidth(key); - } + if ((key & SPRITE_GLYPH) != 0) return this->parent->GetGlyphWidth(key); GlyphEntry *glyph = this->GetGlyphPtr(key); if (glyph == NULL || glyph->sprite == NULL) { @@ -537,6 +532,17 @@ uint FreeTypeFontCache::GetGlyphWidth(WC 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 */ /**