sl@0: // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0: // All rights reserved.
sl@0: // This component and the accompanying materials are made available
sl@0: // under the terms of "Eclipse Public License v1.0"
sl@0: // which accompanies this distribution, and is available
sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: //
sl@0: // Initial Contributors:
sl@0: // Nokia Corporation - initial contribution.
sl@0: //
sl@0: // Contributors:
sl@0: //
sl@0: // Description:
sl@0: // FONT related functions and the font cache
sl@0: // 
sl@0: //
sl@0: 
sl@0: #include "wsfont.h"
sl@0: 
sl@0: CWsFontCache * CWsFontCache::iSelf = NULL;
sl@0: TDblQue<CWsFbsFont> * CWsFontCache::iList = NULL;
sl@0: 
sl@0: CWsFontCache::CWsFontCache()
sl@0: 	{
sl@0: 	}
sl@0: 
sl@0: CWsFontCache::~CWsFontCache()
sl@0: 	{
sl@0: 	}
sl@0: 
sl@0: void CWsFontCache::CreateInstanceL()
sl@0: 	{
sl@0: 	// The list MUST exist before creation of the cache since the cache
sl@0: 	// contains an array of fonts. When the array is created the fonts add themselves
sl@0: 	// to the list.
sl@0: 	// The list is ordered from newest to oldest font used.
sl@0: 	iList = new (ELeave) TDblQue<CWsFbsFont>(_FOFF(CWsFbsFont,iLink));
sl@0: 	CleanupStack::PushL(iList);
sl@0: 	iSelf = new (ELeave) CWsFontCache;
sl@0: 	CleanupStack::Pop(iList);
sl@0: 	}
sl@0: 
sl@0: void CWsFontCache::DestroyInstance()
sl@0: 	{
sl@0: 	// The cache has to be destroyed first since the fonts are
sl@0: 	// destroyed when the cache's array if destroyed. The fonts 
sl@0: 	// remove themselves from the list
sl@0: 	delete iSelf;
sl@0: 	iSelf = NULL;
sl@0: 	delete iList;
sl@0: 	iList = NULL;
sl@0: 
sl@0: 	}
sl@0: 
sl@0: void CWsFontCache::ReleaseFont(CWsFbsFont *&aFont)
sl@0: 	{
sl@0: 	if (aFont)
sl@0: 		{
sl@0: 		WS_ASSERT_DEBUG(aFont->iCount>0, EWsPanicFontCacheCount);
sl@0: 		// decrease usage count
sl@0: 		aFont->iCount--;
sl@0: 		// when the font reaches zero then the font entry can be reused later
sl@0: 		aFont = NULL;
sl@0: 		}
sl@0: 	}
sl@0: 
sl@0: TBool CWsFontCache::UseFont(CWsFbsFont *&aFont, TInt aHandle)
sl@0: 	{
sl@0: 	ReleaseFont(aFont);
sl@0: 	CWsFbsFont *font = NULL;
sl@0: 
sl@0: 	// The list is ordered from newest to oldest font used.
sl@0: 	TDblQueIter<CWsFbsFont> iter(*iList);
sl@0: 	
sl@0: 	
sl@0: 	// Search for the font from newest to oldest font
sl@0: 	while ((font = iter++) != NULL)
sl@0: 		{
sl@0: 		// if the font handle already exists use existing font
sl@0: 		if (font->Handle() == aHandle)
sl@0: 			{
sl@0: 			break;
sl@0: 			}
sl@0: 		}
sl@0: 
sl@0: 	// Font not found in cache so find an unused entry
sl@0: 	if (!font)
sl@0: 		{
sl@0: 		// Starting search from oldest to newest font unsed
sl@0: 		iter.SetToLast();
sl@0: 		while((font = iter--) != NULL)
sl@0: 			{
sl@0: 			// if you find an unused font then use that font entry
sl@0: 			if (font->iCount == 0)
sl@0: 				{
sl@0: 				break;
sl@0: 				}
sl@0: 			}
sl@0: 		// if an unused font is not found then all fonts are being used and 
sl@0: 		// the font can not be created
sl@0: 		if (!font)
sl@0: 			{
sl@0: 			return(ETrue);	// No room in cache
sl@0: 			}
sl@0: 		// release and reuse the font entry to create a new font
sl@0: 		font->Reset();
sl@0: 		if (font->Duplicate(aHandle) != KErrNone)
sl@0: 			{
sl@0: 			return(EFalse);	// Bad handle, (indicated by aFont=NULL)
sl@0: 			}
sl@0: 		}
sl@0: 	// put font at the font of the list as the font is the newest font
sl@0: 	font->iLink.Deque();
sl@0: 	iList->AddFirst(*font);
sl@0: 	// increase usage count
sl@0: 	font->iCount++;
sl@0: 	aFont = font;
sl@0: 	return(EFalse);
sl@0: 	}
sl@0: 
sl@0: TDblQue<CWsFbsFont>& CWsFontCache::List()
sl@0: 	{
sl@0: 	return *Instance()->iList;
sl@0: 	}
sl@0: 	
sl@0: CWsFbsFont::CWsFbsFont()
sl@0: 	{
sl@0: 	// add itself to the font cache
sl@0: 	CWsFontCache::List().AddLast(*this);
sl@0: 	}
sl@0: 
sl@0: CWsFbsFont::~CWsFbsFont()
sl@0: 	{
sl@0: 	// remove itself from the font cache
sl@0: 	iLink.Deque();
sl@0: 	WS_ASSERT_DEBUG(iCount==0, EWsPanicFontCacheCount);
sl@0: 	}