From a0f664ad353a2e302227ca1a54b67c76ae8d8627 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Mon, 6 Jan 2003 02:50:25 +0000 Subject: [PATCH] more font work --- stepmania/src/BitmapText.cpp | 3 ++ stepmania/src/Font.cpp | 37 ++++++++++---------- stepmania/src/FontManager.cpp | 64 +++++++++++++++++++++++++++++++++-- stepmania/src/FontManager.h | 8 +++++ 4 files changed, 89 insertions(+), 23 deletions(-) diff --git a/stepmania/src/BitmapText.cpp b/stepmania/src/BitmapText.cpp index da2e4d06bb..7ab75e8225 100644 --- a/stepmania/src/BitmapText.cpp +++ b/stepmania/src/BitmapText.cpp @@ -199,6 +199,9 @@ void BitmapText::SetText( CString sText ) m_szText = sText; + ReplaceText(sText, FontManager::CharAliasRepl); + Replace_Unicode_Markers(sText); + /* Break the string into lines. */ m_szTextLines.clear(); m_iLineWidths.clear(); diff --git a/stepmania/src/Font.cpp b/stepmania/src/Font.cpp index 723b1b896b..f3f5ed1032 100644 --- a/stepmania/src/Font.cpp +++ b/stepmania/src/Font.cpp @@ -19,6 +19,7 @@ #include "RageLog.h" #include "RageException.h" #include "FontManager.h" +#include "GameState.h" const longchar Font::DEFAULT_GLYPH = 0xFFFF; @@ -108,7 +109,7 @@ void FontPage::SetTextureCoords(const vector &widths, int LineSpacing) iPixelsToChopOff--; g.width++; } - float fTexCoordsToChopOff = float(iPixelsToChopOff) / m_pTexture->GetSourceWidth(); + float fTexCoordsToChopOff = float(iPixelsToChopOff) / m_pTexture->GetTextureWidth(); g.rect.left += fTexCoordsToChopOff/2; g.rect.right -= fTexCoordsToChopOff/2; @@ -144,8 +145,8 @@ void FontPage::SetExtraPixels(int DrawExtraPixelsLeft, int DrawExtraPixelsRight) float ExtraRight = min( float(DrawExtraPixelsRight), (iFrameWidth-iCharWidth)/2.0f ); /* Move left and expand right. */ - glyphs[i].rect.left -= ExtraLeft / m_pTexture->GetSourceWidth(); - glyphs[i].rect.right += ExtraRight / m_pTexture->GetSourceWidth(); + glyphs[i].rect.left -= ExtraLeft / m_pTexture->GetTextureWidth(); + glyphs[i].rect.right += ExtraRight / m_pTexture->GetTextureWidth(); glyphs[i].hshift -= ExtraLeft; glyphs[i].width += ExtraLeft + ExtraRight; } @@ -222,30 +223,26 @@ void Font::MergeFont(Font *f) const glyph &Font::GetGlyph( longchar c ) const { - map::const_iterator it = m_iCharToGlyph.find(c); + /* See if there's a game-specific version of this character. */ + int gc = FontManager::MakeGameGlyph(c, GAMESTATE->m_CurGame); + map::const_iterator it = m_iCharToGlyph.find(gc); - if(it == m_iCharToGlyph.end()) - { - if(c == Font::DEFAULT_GLYPH) - RageException::Throw( "The default glyph is missing from the font '%s'", path.GetString() ); - return GetGlyph(DEFAULT_GLYPH); - } + /* If there isn't, try the regular character. */ + if(it == m_iCharToGlyph.end()) it = m_iCharToGlyph.find(c); + /* If *that's* missing, use the default glyph. */ + if(it == m_iCharToGlyph.end()) it = m_iCharToGlyph.find(DEFAULT_GLYPH); + + if(it == m_iCharToGlyph.end()) + RageException::Throw( "The default glyph is missing from the font '%s'", path.GetString() ); + return *it->second; } RageTexture *Font::GetGlyphTexture( longchar c ) { - map::iterator it = m_iCharToGlyph.find(c); - - if(it == m_iCharToGlyph.end()) - { - if(c == Font::DEFAULT_GLYPH) - RageException::Throw( "The default glyph is missing from the font '%s'", path.GetString() ); - return GetGlyphTexture(DEFAULT_GLYPH); - } - - return it->second->Texture; + glyph &g = const_cast (GetGlyph(c)); + return g.Texture; } void Font::CapsOnly() diff --git a/stepmania/src/FontManager.cpp b/stepmania/src/FontManager.cpp index ad127df3fe..d2faf35b1b 100644 --- a/stepmania/src/FontManager.cpp +++ b/stepmania/src/FontManager.cpp @@ -19,8 +19,10 @@ #include "RageException.h" #include "RageTimer.h" #include "ThemeManager.h" +#include "GameManager.h" -static map CharAliases; +FontManager::aliasmap FontManager::CharAliases; +map FontManager::CharAliasRepl; FontManager* FONT = NULL; @@ -37,7 +39,24 @@ FontManager::~FontManager() LOG->Trace( "FONT LEAK: '%s', RefCount = %d.", i->first.GetString(), pFont->m_iRefCount ); delete pFont; } +} +/* A longchar is at least 32 bits. If c & 0xFF000000, it's a game-custom + * character; game 0 is 0x01nnnnnn, game 1 is 0x02nnnnnn, and so on. */ +longchar FontManager::MakeGameGlyph(longchar c, Game g) +{ + ASSERT(g >= 0 && g <= 0xFF && c >= 0 && c <= 0xFFFFFF); + return ((g+1) << 24) + c; +} + +bool FontManager::ExtractGameGlyph(longchar ch, int &c, Game &g) +{ + if((ch & 0xFF000000) == 0) return false; /* not a game glyph */ + + g = Game((ch >> 24) - 1); + c = ch & 0xFFFFFF; + + return true; } void FontManager::LoadFontPageSettings(FontPageSettings &cfg, IniFile &ini, const CString &PageName, int NumFrames) @@ -87,14 +106,32 @@ void FontManager::LoadFontPageSettings(FontPageSettings &cfg, IniFile &ini, cons /* "map XXXX=frame" maps a char to a frame. */ if(val.substr(0, 4) == "MAP ") { - /* map CODEPOINT=frame. CODEPOINT can be "U+hexval" or an alias. - * XXX: implement aliases + /* map CODEPOINT=frame. CODEPOINT can be + * 1. U+hexval + * 2. an alias ("kakumei1") + * 3. a game type followed by a game alias, eg "pump menuleft" + * * map 1=2 is the same as * range unicode #1-1=2 */ CString codepoint = val.substr(4); /* "XXXX" */ longchar c; + Game game = GAME_INVALID; + + if(codepoint.find_first_of(' ') != codepoint.npos) + { + /* There's a space; the first word should be a game type. Split it. */ + unsigned pos = codepoint.find_first_of(' '); + CString gamename = codepoint.substr(0, pos); + codepoint = codepoint.substr(pos+1); + + game = GameManager::StringToGameType(gamename); + + if(game == GAME_INVALID) + RageException::Throw( "Font definition '%s' uses unknown game type '%s'", + ini.GetPath().GetString(), gamename.GetString() ); + } if(codepoint.substr(0, 2) == "U+" && IsHexVal(codepoint.substr(2))) sscanf(codepoint.substr(2).c_str(), "%x", &c); @@ -104,6 +141,8 @@ void FontManager::LoadFontPageSettings(FontPageSettings &cfg, IniFile &ini, cons RageException::Throw( "Font definition '%s' has an invalid value '%s'.", ini.GetPath().GetString(), val.GetString() ); + if(game != GAME_INVALID) c = MakeGameGlyph(c, game); + int frame = atoi(data); if(frame >= NumFrames) RageException::Throw( "Font definition '%s' maps to frame %i, but font only has %i frames", @@ -365,6 +404,25 @@ Font* FontManager::LoadFont( const CString &sFontOrTextureFilePath, CString sCha CharAliases["omega"] = 0x03a9; /* Ω */ CharAliases["whiteheart"] = 0x2661; /* ♡ */ CharAliases["blackstar"] = 0x2605; /* ★ */ + + CharAliases["up"] = 0x100000; + CharAliases["down"] = 0x100001; + CharAliases["left"] = 0x100002; + CharAliases["right"] = 0x100003; + CharAliases["menuup"] = 0x100004; + CharAliases["menudown"] = 0x100005; + CharAliases["menuleft"] = 0x100006; + CharAliases["menuright"] = 0x100007; + CharAliases["start"] = 0x100008; + + for(aliasmap::const_iterator i = CharAliases.begin(); i != CharAliases.end(); ++i) + { + CString from = ssprintf("&%s;", i->first.GetString()); + CString to = LcharToUTF8(i->second); + from.MakeUpper(); + CharAliasRepl[from] = to; + LOG->Trace("from '%s' to '%s'", from.GetString(), to.GetString()); + } } // Convert the path to lowercase so that we don't load duplicates. diff --git a/stepmania/src/FontManager.h b/stepmania/src/FontManager.h index ca1fb6e9be..213f905a06 100644 --- a/stepmania/src/FontManager.h +++ b/stepmania/src/FontManager.h @@ -12,6 +12,7 @@ */ #include "Font.h" +#include "Game.h" #include @@ -29,6 +30,13 @@ public: static bool MatchesFont(CString FontName, CString FileName); + static longchar MakeGameGlyph(int c, Game g); + static bool ExtractGameGlyph(longchar ch, int &c, Game &g); + + typedef map aliasmap; + static aliasmap CharAliases; + static map CharAliasRepl; + protected: // map from file name to a texture holder map m_mapPathToFont;