#include "gui_font_factory.h" #ifdef _MSC_VER #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #endif using namespace irr; using namespace gui; using namespace core; namespace { c16 SEPARATOR = '|'; c16 ANTIALIAS = 'a'; c16 TRANSPARENT = 't'; }; bool TrueTypeFontParameters::isValid() { if ( !FileName.size() ) return false; if ( !Size ) return false; return true; } TrueTypeFontFactory::TrueTypeFontFactory(irr::video::IVideoDriver* driver) : Driver(driver) // we do not grab Driver to avoid cyclic references. It will be available anyway. { } TrueTypeFontFactory::~TrueTypeFontFactory() { FontMap::iterator itFont = mFontMap.begin(); for ( ; itFont != mFontMap.end(); ++itFont ) { itFont->second->drop(); } FaceMap::iterator itFace = mFaceMap.begin(); for ( ; itFace != mFaceMap.end(); ++itFace ) { itFace->second->drop(); } } IGUIFont* TrueTypeFontFactory::addGUIFont(const irr::core::string& fontName) { if ( !fontName.size() || !Driver ) return NULL; // We need a new font for each setting, but only a new face when loading a different fontfile irr::core::string fontString(fontName); FontMap::iterator itFont = mFontMap.find(fontString); if (itFont != mFontMap.end() ) return itFont->second; TrueTypeFontParameters parameters = parseFontName(fontName); if ( !parameters.isValid() ) return NULL; // check if the face is already loaded CGUITTFace * face = NULL; FaceMap::iterator itFace = mFaceMap.find(parameters.FileName); if (itFace != mFaceMap.end() ) { face = itFace->second; } // no face loaded if ( !face ) { // make a new face face = new CGUITTFace; if ( !face->load(parameters.FileName) ) { face->drop(); return NULL; } mFaceMap[parameters.FileName] = face; } CGUIFreetypeFont * font = new CGUIFreetypeFont(Driver); if ( !font ) return NULL; font->grab(); // we need to keep a reference here font->attach(face, parameters.Size); font->AntiAlias = parameters.AntiAlias; font->Transparency = parameters.Transparency; mFontMap[fontString] = font; return font; } irr::core::string TrueTypeFontFactory::makeFontName(const TrueTypeFontParameters ¶m) { irr::core::string fontName( param.FileName ); fontName += SEPARATOR; fontName += param.Size; if ( param.AntiAlias ) fontName += ANTIALIAS; if ( param.Transparency ) fontName += TRANSPARENT; return fontName; } //! return the parameters which can be received by parsing the given fontname TrueTypeFontParameters TrueTypeFontFactory::parseFontName(const irr::core::string& fontName) { TrueTypeFontParameters params; if ( !fontName.size() ) return params; u32 pos = 0; // parse filename while ( fontName[pos] && fontName[pos] != SEPARATOR ) ++pos; params.FileName = irr::core::string( fontName.c_str(), pos ); if ( !fontName[pos] ) return params; // parse parameters ++pos; while ( fontName[pos] ) { if ( ::isdigit(fontName[pos]) ) { params.Size = atoi( &(fontName[pos]) ); while ( fontName[pos] && ::isdigit(fontName[pos]) ) ++pos; } else { if ( fontName[pos] == ANTIALIAS ) { params.AntiAlias = true; } else if ( fontName[pos] == TRANSPARENT ) { params.Transparency = true; } ++pos; } } return params; }