diff --git a/stepmania/src/Font.cpp b/stepmania/src/Font.cpp index 7a98c0d343..0c61f35d39 100644 --- a/stepmania/src/Font.cpp +++ b/stepmania/src/Font.cpp @@ -28,9 +28,9 @@ FontPage::FontPage() m_pTexture = NULL; } -void FontPage::Load( const CString &TexturePath, const FontPageSettings &cfg ) +void FontPage::Load( const FontPageSettings &cfg ) { - m_sTexturePath = TexturePath; + m_sTexturePath = cfg.TexturePath; // load texture m_sTexturePath.MakeLower(); @@ -76,10 +76,10 @@ void FontPage::Load( const CString &TexturePath, const FontPageSettings &cfg ) * and ascender. */ if(cfg.Baseline != -1 && cfg.Top == -1) RageException::Throw("Font %s has Baseline but no Top; must have both or neither", - TexturePath.GetString()); + m_sTexturePath.GetString()); if(cfg.Baseline == -1 && cfg.Top != -1) RageException::Throw("Font %s has Baseline but no Top; must have both or neither", - TexturePath.GetString()); + m_sTexturePath.GetString()); int baseline=0; if(cfg.Baseline == -1 && cfg.Top == -1) @@ -103,7 +103,7 @@ void FontPage::Load( const CString &TexturePath, const FontPageSettings &cfg ) SetExtraPixels(cfg.DrawExtraPixelsLeft, cfg.DrawExtraPixelsRight); LOG->Trace("Font %s: height %i, baseline %i ( == top %i)", - TexturePath.GetString(), height, baseline, baseline-height); + m_sTexturePath.GetString(), height, baseline, baseline-height); } void FontPage::SetTextureCoords(const vector &widths) @@ -226,20 +226,37 @@ Font::Font() //LOG->Trace( "Font::LoadFromFontName(%s)", sASCIITexturePath.GetString() ); m_iRefCount = 1; + def = NULL; } Font::~Font() +{ + Unload(); +} + +void Font::Unload() { unsigned i; for(i = 0; i < pages.size(); ++i) delete pages[i]; - - /* Free any fonts that we merged into us. */ + pages.clear(); + + /* Free any fonts that we merged into us. These aren't managed by + * FontManager (we own them), so just delete them. */ for(i = 0; i < merged_fonts.size(); ++i) - FONT->UnloadFont(merged_fonts[i]); + delete merged_fonts[i]; + merged_fonts.clear(); + + m_iCharToGlyph.clear(); + def = NULL; + path.clear(); + + /* Don't clear the refcount. We've unloaded, but that doesn't mean things + * aren't still pointing to us. */ } + void Font::AddPage(FontPage *fp) { pages.push_back(fp); diff --git a/stepmania/src/Font.h b/stepmania/src/Font.h index c10b68fe46..79fcf065ba 100644 --- a/stepmania/src/Font.h +++ b/stepmania/src/Font.h @@ -34,7 +34,10 @@ struct glyph { RectF rect; }; -struct FontPageSettings { +struct FontPageSettings +{ + CString TexturePath; + int DrawExtraPixelsLeft, DrawExtraPixelsRight, AddToAllWidths, @@ -74,7 +77,7 @@ public: FontPage(); ~FontPage(); - void Load( const CString &sASCIITexturePath, const FontPageSettings &cfg ); + void Load( const FontPageSettings &cfg ); /* Page-global properties. */ int height; @@ -110,6 +113,8 @@ public: /* Steal all of a font's pages. */ void MergeFont(Font *f); + void Unload(); + /* Load font-wide settings. */ void CapsOnly(); diff --git a/stepmania/src/FontManager.cpp b/stepmania/src/FontManager.cpp index 133d852a5c..62a75ea013 100644 --- a/stepmania/src/FontManager.cpp +++ b/stepmania/src/FontManager.cpp @@ -32,17 +32,12 @@ FontManager::FontManager() FontManager::~FontManager() { - /* It's not safe to delete fonts that still have references left, because fonts - * will also release other fonts when they're deleted (we'd have to make sure - * to delete top-level fonts first). Since this should never happen anyway, - * and we only delete FontManager when we're shutting down, let's just warn - * about font leaks and not actually free them. */ for( std::map::iterator i = m_mapPathToFont.begin(); i != m_mapPathToFont.end(); ++i) { Font* pFont = i->second; LOG->Trace( "FONT LEAK: '%s', RefCount = %d.", i->first.GetString(), pFont->m_iRefCount ); -// delete pFont; + delete pFont; } } @@ -63,9 +58,39 @@ bool FontManager::ExtractGameGlyph(longchar ch, int &c, Game &g) return true; } - -void FontManager::LoadFontPageSettings(FontPageSettings &cfg, IniFile &ini, const CString &PageName, int NumFrames) +#if 0 +void FontManager::ReloadFonts() { + map m_mapPathToFont; + + for(map::iterator i = m_mapPathToFont.begin(); + i != m_mapPathToFont.end(); ++i) + { + CString path = i->first; + Font *f = i->second; + f->Unload(); + f->Load(f); + +// i-> + + } + + + +} +#endif + +void FontManager::LoadFontPageSettings(FontPageSettings &cfg, IniFile &ini, const CString &TexturePath, const CString &PageName, CString sChars) +{ + cfg.TexturePath = TexturePath; + + /* If we have any characters to map, add them. */ + for( unsigned n=0; nTrace("Loading font page '%s' settings from page name '%s'", + TexturePath.GetString(), PageName.GetString()); + ini.GetValueI( PageName, "DrawExtraPixelsLeft", cfg.DrawExtraPixelsLeft ); ini.GetValueI( PageName, "DrawExtraPixelsRight", cfg.DrawExtraPixelsRight ); ini.GetValueI( PageName, "AddToAllWidths", cfg.AddToAllWidths ); @@ -151,12 +180,7 @@ void FontManager::LoadFontPageSettings(FontPageSettings &cfg, IniFile &ini, cons 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", - ini.GetPath().GetString(), frame, NumFrames ); - - cfg.CharToGlyphNo[c] = frame; + cfg.CharToGlyphNo[c] = atoi(data); continue; } #if 0 @@ -312,7 +336,7 @@ Font *FontManager::LoadFontInt(const CString &sFontOrTextureFilePath, CString sC { LoadingDefaultFont = true; CString path = THEME->GetPathTo("Fonts", "default font"); - pFont->MergeFont(FONT->LoadFont(path)); + pFont->MergeFont(LoadFontInt(path, "")); LoadingDefaultFont = false; } @@ -320,7 +344,7 @@ Font *FontManager::LoadFontInt(const CString &sFontOrTextureFilePath, CString sC for(unsigned i = 0; i < ImportList.size(); ++i) { CString path = THEME->GetPathTo("Fonts", ImportList[i]); - pFont->MergeFont(FONT->LoadFont(path)); + pFont->MergeFont(LoadFontInt(path, "")); } } @@ -329,30 +353,26 @@ Font *FontManager::LoadFontInt(const CString &sFontOrTextureFilePath, CString sC { FontPage *fp = new FontPage; - int frames = RageTexture::GetFrameCountFromFileName(TexturePaths[i]); - /* Grab the page name, eg "foo" from "Normal [foo].png". */ CString pagename = GetPageNameFromFileName(TexturePaths[i]); /* Load settings for this page from the INI. */ FontPageSettings cfg; - - /* If we have any characters to map, add them. */ - for( unsigned n=0; nLoad(TexturePaths[i], cfg); + fp->Load(cfg); /* Expect at least as many frames as we have premapped characters. */ - if( unsigned(fp->m_pTexture->GetNumFrames()) < sChars.size() ) - RageException::Throw( "The font '%s' has %d frames; expected at least %i frames.", - fp->m_pTexture->GetNumFrames(), sChars.size() ); + /* Make sure that we don't map characters to frames we don't actually + * have. This can happen if the font is too small for an sChars. */ + for(map::const_iterator it = fp->m_iCharToGlyphNo.begin(); + it != fp->m_iCharToGlyphNo.end(); ++it) + { + if(it->second < fp->m_pTexture->GetNumFrames()) continue; /* OK */ + RageException::Throw( "The font '%s' maps %s to frame %i, but the font only has %i frames.", + TexturePaths[i].GetString(), WcharDisplayText(wchar_t(it->first)).GetString(), it->second, fp->m_pTexture->GetNumFrames() ); + } LOG->Trace("Adding page %s (%s) to %s; %i glyphs", TexturePaths[i].GetString(), pagename.GetString(), @@ -408,7 +428,7 @@ Font* FontManager::LoadFont( const CString &sFontOrTextureFilePath, CString sCha InitCharAliases(); // Convert the path to lowercase so that we don't load duplicates. - // Really, this does not solve the duplicate problem. We could have to copies + // Really, this does not solve the duplicate problem. We could have two copies // of the same bitmap if there are equivalent but different paths // (e.g. "graphics\blah.png" and "..\stepmania\graphics\blah.png" ). diff --git a/stepmania/src/FontManager.h b/stepmania/src/FontManager.h index 1113ffc85e..c284ed97b2 100644 --- a/stepmania/src/FontManager.h +++ b/stepmania/src/FontManager.h @@ -47,7 +47,7 @@ protected: map m_mapPathToFont; static Font *LoadFontInt(const CString &sFontOrTextureFilePath, CString sChars); static CString GetPageNameFromFileName(const CString &fn); - static void LoadFontPageSettings(FontPageSettings &cfg, IniFile &ini, const CString &PageName, int NumFrames); + static void LoadFontPageSettings(FontPageSettings &cfg, IniFile &ini, const CString &TexturePath, const CString &PageName, CString sChars); static void GetFontPaths(const CString &sFontOrTextureFilePath, CStringArray &TexturePaths, CString &IniPath); static void InitCharAliases();