/*==LICENSE==* CyanWorlds.com Engine - MMOG client, server and tools Copyright (C) 2011 Cyan Worlds, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . You can contact Cyan Worlds, Inc. by email legal@cyan.com or by snail mail at: Cyan Worlds, Inc. 14617 N Newport Hwy Mead, WA 99021 *==LICENSE==*/ /////////////////////////////////////////////////////////////////////////////// // // // plFontCache Class Header // // Generic cache lib for our plFonts. Basically just a simple plFont // // manager. // // // // Cyan, Inc. // // // //// Version History ////////////////////////////////////////////////////////// // // // 3.12.2003 mcn - Created. // // // /////////////////////////////////////////////////////////////////////////////// #include "plFontCache.h" #include "plFont.h" #include "../plStatusLog/plStatusLog.h" #include "../plFile/hsFiles.h" #include "../pnMessage/plRefMsg.h" #include "hsResMgr.h" #include "../pnKeyedObject/plUoid.h" char *plFontCache::kCustFontExtension = ".prf"; plFontCache *plFontCache::fInstance = nil; plFontCache::plFontCache() { fCustFontDir = nil; RegisterAs( kFontCache_KEY ); fInstance = this; } plFontCache::~plFontCache() { Clear(); delete [] fCustFontDir; fInstance = nil; } plFontCache &plFontCache::GetInstance( void ) { return *fInstance; } void plFontCache::Clear( void ) { } plFont *plFontCache::GetFont( const char *face, UInt8 size, UInt32 fontFlags ) { UInt32 i, currIdx = (UInt32)-1; int currDeltaSize = 100000; char toFind[ 256 ]; strcpy( toFind, face ); strlwr( toFind ); for( i = 0; i < fCache.GetCount(); i++ ) { char thisOne[ 256 ]; strcpy( thisOne, fCache[ i ]->GetFace() ); strlwr( thisOne ); if( strncmp( thisOne, toFind, strlen( toFind ) ) == 0 && ( fCache[ i ]->GetFlags() == fontFlags ) ) { int delta = fCache[ i ]->GetSize() - size; if( delta < 0 ) delta = -delta; if( delta < currDeltaSize ) { currDeltaSize = delta; currIdx = i; } } } if( currIdx != (UInt32)-1 ) { //if( currDeltaSize > 0 ) // plStatusLog::AddLineS( "pipeline.log", "Warning: plFontCache is matching %s %d (requested %s %d)", fCache[ currIdx ]->GetFace(), fCache[ currIdx ]->GetSize(), face, size ); return fCache[ currIdx ]; } // If we failed, it's possible we have a face saved as "Times", for example, and someone's // asking for "Times New Roman", so strip all but the first word from our font and try the search again char *c = strchr( toFind, ' ' ); if( c != nil ) { *c = 0; return GetFont( toFind, size, fontFlags ); } else if( fontFlags != 0 ) { // Hmm, well ok, just to be nice, try without our flags plFont *f = GetFont( toFind, size, 0 ); if( f != nil ) { //plStatusLog::AddLineS( "pipeline.log", "Warning: plFontCache is substituting %s %d regular (flags 0x%x could not be matched)", f->GetFace(), f->GetSize(), fontFlags ); return f; } } //plStatusLog::AddLineS( "pipeline.log", "Warning: plFontCache was unable to match %s %d (0x%x)", face, size, fontFlags ); return nil; } void plFontCache::LoadCustomFonts( const char *dir ) { delete [] fCustFontDir; fCustFontDir = ( dir != nil ) ? hsStrcpy( dir ) : nil; ILoadCustomFonts(); } void plFontCache::ILoadCustomFonts( void ) { if( fCustFontDir == nil ) return; // Iterate through all the custom fonts in our dir hsFolderIterator iter( fCustFontDir ); char fileName[ kFolderIterator_MaxPath ]; hsFolderIterator iter2( fCustFontDir ); while( iter2.NextFileSuffix( ".p2f" ) ) { iter2.GetPathAndName( fileName ); plFont *font = TRACKED_NEW plFont; if( !font->LoadFromP2FFile( fileName ) ) delete font; else { char keyName[ 512 ]; if( font->GetKey() == nil ) { sprintf( keyName, "%s-%d", font->GetFace(), font->GetSize() ); hsgResMgr::ResMgr()->NewKey( keyName, font, plLocation::kGlobalFixedLoc ); } hsgResMgr::ResMgr()->AddViaNotify( font->GetKey(), TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, 0, -1 ), plRefFlags::kActiveRef ); //plStatusLog::AddLineS( "pipeline.log", "FontCache: Added custom font %s", keyName ); } } } hsBool plFontCache::MsgReceive( plMessage* pMsg ) { plGenRefMsg *ref = plGenRefMsg::ConvertNoRef( pMsg ); if( ref != nil ) { if( ref->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest | plRefMsg::kOnReplace ) ) { fCache.Append( plFont::ConvertNoRef( ref->GetRef() ) ); } else { plFont *font = plFont::ConvertNoRef( ref->GetRef() ); UInt32 idx = fCache.Find( font ); if( idx != fCache.kMissingIndex ) fCache.Remove( idx ); } return true; } return hsKeyedObject::MsgReceive( pMsg ); }