You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
5.5 KiB

/*==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 <http://www.gnu.org/licenses/>.
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 );
}