diff --git a/stepmania/src/Font.cpp b/stepmania/src/Font.cpp index 89e787337f..1df24c819f 100644 --- a/stepmania/src/Font.cpp +++ b/stepmania/src/Font.cpp @@ -5,7 +5,7 @@ Desc: See header. - Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Copyright (c) 2001-2003 by the person(s) listed below. All rights reserved. Chris Danford Glenn Maynard ----------------------------------------------------------------------------- diff --git a/stepmania/src/Font.h b/stepmania/src/Font.h index 7c741fa5c1..c9aafdd844 100644 --- a/stepmania/src/Font.h +++ b/stepmania/src/Font.h @@ -15,8 +15,10 @@ #include "IniFile.h" struct glyph { + RageTexture *Texture; + /* Number of pixels to advance horizontally after drawing this character. */ - float advance; + float hadvance, vadvance; /* Size of the actual rendered character. */ float width, height; @@ -28,35 +30,55 @@ struct glyph { RectF rect; }; -class Font +class FontPage { public: - Font( const CString &sASCIITexturePath ); - Font( const CString &sTexturePath, const CString& sChars ); - ~Font(); - void Init(); + RageTexture* m_pTexture; + + CString m_sTexturePath; + + /* All glyphs in this list will point to m_pTexture. */ + vector glyphs; + + map m_iCharToGlyphNo; + + FontPage(); + ~FontPage(); int GetLineWidthInSourcePixels( const CString &szLine ); int GetLineHeightInSourcePixels( const CString &szLine ); - int m_iRefCount; - - CString m_sTexturePath; - - vector glyphs; - - RageTexture* m_pTexture; - bool m_bCapitalsOnly; - int m_iLineSpacing; - - map m_iCharToFrameNo; - - const glyph &GetGlyph( int frameNo ) const { return glyphs[frameNo]; } + void Load( const CString &sASCIITexturePath, IniFile &ini ); private: void SetExtraPixels(int DrawExtraPixelsLeft, int DrawExtraPixelsRight); - void SetTextureCoords(const vector &widths); - void Load( const CString &sASCIITexturePath, IniFile &ini ); + void SetTextureCoords(const vector &widths, int LineSpacing); +}; + +class Font +{ +public: + int m_iRefCount; + CString path; + map m_iCharToGlyph; + + Font(); + + RageTexture *GetGlyphTexture( int c ); + const glyph &GetGlyph( int c ) const; + + int GetLineWidthInSourcePixels( const CString &szLine ); + int GetLineHeightInSourcePixels( const CString &szLine ); + + /* Add a FontPage to this font. */ + void AddPage(FontPage *fp); + + /* Load font-wide settings. */ + void LoadINI(IniFile &ini); + +private: + vector pages; + }; #endif diff --git a/stepmania/src/FontManager.cpp b/stepmania/src/FontManager.cpp index 4800dd0e5b..17bfe302a1 100644 --- a/stepmania/src/FontManager.cpp +++ b/stepmania/src/FontManager.cpp @@ -57,67 +57,89 @@ Font* FontManager::LoadFont( CString sFontOrTextureFilePath, CString sChars ) // of the same bitmap if there are equivalent but different paths // (e.g. "graphics\blah.png" and "..\stepmania\graphics\blah.png" ). - Font* pFont = NULL; - - std::map::iterator p = m_mapPathToFont.find(sFontOrTextureFilePath); + map::iterator p = m_mapPathToFont.find(sFontOrTextureFilePath); if(p != m_mapPathToFont.end()) { // LOG->Trace( ssprintf("FontManager: The Font '%s' now has %d references.", sFontFilePath.GetString(), pFont->m_iRefCount) ); - pFont=p->second; + Font *pFont=p->second; pFont->m_iRefCount++; + return pFont; } - else // the texture is not already loaded - { - CString sDrive, sDir, sFName, sExt; - splitpath( false, sFontOrTextureFilePath, sDrive, sDir, sFName, sExt ); + + // the texture is not already loaded + CString sDrive, sDir, sFName, sExt; + splitpath( false, sFontOrTextureFilePath, sDrive, sDir, sFName, sExt ); - if( sChars == "" ) - pFont = (Font*) new Font( sFontOrTextureFilePath ); - else - pFont = (Font*) new Font( sFontOrTextureFilePath, sChars ); + Font* pFont = new Font; + + + FontPage *fp = new FontPage; + IniFile ini; + + int expect; + if( sChars == "" ) + { + /* Default to 0..255. */ + for( int i=0; i<256; i++ ) + fp->m_iCharToGlyphNo[i] = i; + + // Find .ini widths path from texture path + CString sDir, sFileName, sExtension; + splitrelpath( sFontOrTextureFilePath, sDir, sFileName, sExtension ); + const CString sIniPath = sDir + sFileName + ".ini"; + + ini.SetPath( sIniPath ); + ini.ReadFile(); + ini.RenameKey("Char Widths", "main"); + expect = 256; + } + else + { + /* Map characters to frames; we don't actually have an INI. */ + for( int i=0; im_iCharToGlyphNo[c] = i; + } + expect = sChars.GetLength(); + } + + fp->Load(sFontOrTextureFilePath, ini); + if( fp->m_pTexture->GetNumFrames() != expect ) + RageException::Throw( "The font '%s' has %d frames; expected %i frames.", + fp->m_pTexture->GetNumFrames(), expect ); // LOG->Trace( "FontManager: Loading '%s' from disk.", sFontFilePath.GetString()); - m_mapPathToFont[sFontOrTextureFilePath] = pFont; - } + pFont->AddPage(fp); + m_mapPathToFont[sFontOrTextureFilePath] = pFont; + + pFont->LoadINI(ini); return pFont; } -bool FontManager::IsFontLoaded( CString sFontFilePath ) +void FontManager::UnloadFont( Font *fp ) { - sFontFilePath.MakeLower(); - - return m_mapPathToFont.find(sFontFilePath) != m_mapPathToFont.end(); -} - -void FontManager::UnloadFont( CString sFontFilePath ) -{ - sFontFilePath.MakeLower(); - // LOG->Trace( "FontManager::UnloadTexture(%s).", sFontFilePath.GetString() ); - if( sFontFilePath == "" ) + for( std::map::iterator i = m_mapPathToFont.begin(); + i != m_mapPathToFont.end(); ++i) { -// LOG->Trace( "FontManager::UnloadTexture(): tried to Unload a blank" ); - return; - } + if(i->second == fp) + { + i->second->m_iRefCount--; - Font* pFont; - std::map::iterator p = m_mapPathToFont.find(sFontFilePath); - if(p == m_mapPathToFont.end()) - RageException::Throw( "Tried to Unload a font that wasn't loaded. '%s'", sFontFilePath.GetString() ); - - pFont=p->second; - pFont->m_iRefCount--; - if( pFont->m_iRefCount != 0 ) - { -// LOG->Trace( "FontManager: '%s' will not be deleted. It still has %d references.", sFontFilePath.GetString(), pFont->m_iRefCount ); - return; - } - - // There are no more references to this texture. + if( fp->m_iRefCount == 0 ) + { + delete i->second; // free the texture + m_mapPathToFont.erase( i ); // and remove the key in the map + } // LOG->Trace( "FontManager: '%s' will be deleted. It has %d references.", sFontFilePath.GetString(), pFont->m_iRefCount ); - SAFE_DELETE( pFont ); // free the texture - m_mapPathToFont.erase( p ); // and remove the key in the map + return; + } + + } + + RageException::Throw( "Unloaded an unknown font (%p)", fp ); } diff --git a/stepmania/src/FontManager.h b/stepmania/src/FontManager.h index b15cbaf75f..2169abf669 100644 --- a/stepmania/src/FontManager.h +++ b/stepmania/src/FontManager.h @@ -25,12 +25,11 @@ public: ~FontManager(); Font* LoadFont( CString sFontOrTextureFilePath, CString sChars = "" ); - bool IsFontLoaded( CString sFontPath ); - void UnloadFont( CString sFontPath ); + void UnloadFont( Font *fp ); protected: // map from file name to a texture holder - std::map m_mapPathToFont; + map m_mapPathToFont; }; extern FontManager* FONT; // global and accessable from anywhere in our program diff --git a/stepmania/src/MenuTimer.cpp b/stepmania/src/MenuTimer.cpp index d30be0a97a..05442c6253 100644 --- a/stepmania/src/MenuTimer.cpp +++ b/stepmania/src/MenuTimer.cpp @@ -33,7 +33,8 @@ MenuTimer::MenuTimer() m_textDigit1.TurnShadowOff(); m_textDigit2.TurnShadowOff(); - float fCharWidth = (float)m_textDigit1.m_pFont->m_pTexture->GetSourceFrameWidth(); + const glyph &g = m_textDigit1.m_pFont->GetGlyph('0'); + float fCharWidth = (float)g.Texture->GetSourceFrameWidth(); m_textDigit1.SetXY( -fCharWidth/2, 0 ); m_textDigit2.SetXY( +fCharWidth/2, 0 );