os/textandloc/fontservices/textbase/sgdi/TFSTORE.CPP
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/textandloc/fontservices/textbase/sgdi/TFSTORE.CPP	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,307 @@
     1.4 +// Copyright (c) 1998-2010 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +//
    1.18 +
    1.19 +#include <textbase.h>
    1.20 +#include "TextBasePanic.h"
    1.21 +
    1.22 +_LIT(KCTypefaceStore, "CTypefaceStore");
    1.23 +static const TInt KDefaultNumOfFontAccess = 4;
    1.24 +
    1.25 +//
    1.26 +// CTypefaceStore
    1.27 +//
    1.28 +
    1.29 +EXPORT_C CTypefaceStore::CTypefaceStore()
    1.30 +	{
    1.31 +	}
    1.32 +
    1.33 +
    1.34 +EXPORT_C CTypefaceStore::~CTypefaceStore()
    1.35 +/** Destroys the typeface store and reclaims the memory allocated to it. */
    1.36 +	{
    1.37 +	if (iFontAccess)
    1.38 +		{
    1.39 +		const TInt count = iFontAccess->Count();
    1.40 +		for (TInt i = 0; i < count; i++)
    1.41 +			{
    1.42 +			TEXTBASE_ASSERT_DEBUG_GENERAL((*iFontAccess)[0].iAccessCount > 0, User::Panic(KCTypefaceStore, KErrCorrupt));
    1.43 +			TEXTBASE_ASSERT_DEBUG_GENERAL((*iFontAccess)[0].iAccessCount == 1, User::Panic(KCTypefaceStore, KErrInUse));
    1.44 +			delete (*iFontAccess)[0].iFont;
    1.45 +			iFontAccess->Delete(0);
    1.46 +			}
    1.47 +		delete iFontAccess;
    1.48 +		}
    1.49 +	}
    1.50 +
    1.51 +EXPORT_C void CTypefaceStore::ConstructL()
    1.52 +/** Second phase constructor. */
    1.53 +	{
    1.54 +	iFontAccess = new(ELeave) CArrayFixFlat<TFontAccess>(KDefaultNumOfFontAccess);
    1.55 +	}
    1.56 +
    1.57 +EXPORT_C void CTypefaceStore::AddFontL(CFont* aFont)
    1.58 +/** Adds a hold, by a client of the typeface store, on the specified font.
    1.59 +
    1.60 +If the specified font is not currently accessed by any clients of the typeface store
    1.61 +then the font is added to the font list and the access count set to 1.
    1.62 +If it is currently accessed then the access count for the font is incremented by 1.
    1.63 +
    1.64 +@param aFont Pointer to the device specific font accessed. */
    1.65 +	{
    1.66 +	TEXTBASE_ASSERT_DEBUG_GENERAL(NULL != iFontAccess, User::Panic(KCTypefaceStore, KErrNoMemory));
    1.67 +	if (IncrementFontCount(aFont))
    1.68 +		return;
    1.69 +	TFontAccess fontAccess;
    1.70 +	fontAccess.iAccessCount = 1;
    1.71 +	fontAccess.iFont = aFont;
    1.72 +	iFontAccess->AppendL(fontAccess);
    1.73 +	}
    1.74 +
    1.75 +EXPORT_C void CTypefaceStore::ReleaseFont(CFont* aFont)
    1.76 +/** Releases the hold of a typeface store client on a specified font.
    1.77 +
    1.78 +Decrements the access-count for the specified font by one. If this reduces the access-count 
    1.79 +to zero then the font is no longer needed by any client, and is deleted from 
    1.80 +the typeface store list.
    1.81 +
    1.82 +@param aFont The font to be released by the client. */
    1.83 +	{
    1.84 +	
    1.85 +	TEXTBASE_ASSERT_DEBUG_GENERAL(NULL != iFontAccess, User::Panic(KCTypefaceStore, KErrNoMemory));
    1.86 +	if (!aFont)
    1.87 +		return;
    1.88 +	TInt idx = 0;
    1.89 +	TEXTBASE_ASSERT_ALWAYS_GENERAL(FindFont(aFont, idx), User::Panic(KCTypefaceStore, KErrNotFound));
    1.90 +	TEXTBASE_ASSERT_DEBUG_GENERAL(0 < iFontAccess->At(idx).iAccessCount, User::Panic(KCTypefaceStore, KErrCorrupt));
    1.91 +	iFontAccess->At(idx).iAccessCount--;
    1.92 +	if (0 == iFontAccess->At(idx).iAccessCount)
    1.93 +		{
    1.94 +		CFont *font=iFontAccess->At(idx).iFont;
    1.95 +		iFontAccess->Delete(idx);
    1.96 +		delete font;
    1.97 +		}
    1.98 +	}
    1.99 +
   1.100 +EXPORT_C TBool CTypefaceStore::IncrementFontCount(const CFont* aFont)
   1.101 +/**
   1.102 +Search for the font in iFontAccess and increment its count.
   1.103 +@param aFont Font to search for.
   1.104 +@return ETrue if the specified font is found, EFalse otherwise.
   1.105 +*/
   1.106 +	{
   1.107 +	TInt idx = 0;
   1.108 +	if (FindFont(aFont, idx))
   1.109 +		{
   1.110 +		iFontAccess->At(idx).iAccessCount++;
   1.111 +		return ETrue;
   1.112 +		}
   1.113 +	return EFalse;
   1.114 +	}
   1.115 +
   1.116 +TBool CTypefaceStore::FindFont(const CFont* aFont, TInt& aIdx) const
   1.117 +/**
   1.118 +Search for the font in iFontAccess.
   1.119 +@param aFont Font to search for.
   1.120 +@param aIdx Index of the font found.
   1.121 +@return ETrue if the specified font is found, EFalse with aIdx = -1 otherwise.
   1.122 +*/
   1.123 +	{
   1.124 +	aIdx = -1;
   1.125 +	if (!iFontAccess)
   1.126 +		return EFalse;
   1.127 +	const TInt count = iFontAccess->Count();
   1.128 +	for (TInt i = 0; i < count; i++)
   1.129 +		{
   1.130 +		if ((*iFontAccess)[i].iFont == aFont)
   1.131 +			{
   1.132 +			aIdx = i;
   1.133 +			return ETrue;
   1.134 +			}
   1.135 +		}
   1.136 +	return EFalse;
   1.137 +	}
   1.138 +
   1.139 +EXPORT_C TInt CTypefaceStore::BaselineOffset(TInt aHeight,TFontPrintPosition aPos)
   1.140 +/** Gets the baseline offset, in twips, for any font in subscript or superscript 
   1.141 +form.
   1.142 +
   1.143 +If the print position is normal then zero is returned. If it is superscript 
   1.144 +then the baseline offset returned is a percentage, KSuperscriptOffsetPercentage, 
   1.145 +of aHeight. If it is subscript then the baseline offset returned is a percentage, 
   1.146 +KSubscriptOffsetPercentage, of aHeight.
   1.147 +
   1.148 +@param aHeight The height of a font. 
   1.149 +@param aPos The print position of the required font: superscript, subscript 
   1.150 +or normal. 
   1.151 +@return The baseline offset for the font. */
   1.152 +	{
   1.153 +	TInt offset=0;
   1.154 +	if (aPos==EPrintPosSuperscript)
   1.155 +		offset=KSuperscriptOffsetPercentage*aHeight/100;
   1.156 +	else if (aPos==EPrintPosSubscript)
   1.157 +		offset=KSubscriptOffsetPercentage*aHeight/100;
   1.158 +	return offset;
   1.159 +	}
   1.160 +	 
   1.161 + 
   1.162 +EXPORT_C TInt CTypefaceStore::SuperSubHeight(TInt aHeight,TFontPrintPosition aPos)
   1.163 +/** Gets the height for a font in subscript or superscript form. 
   1.164 +
   1.165 +If the print position is normal then aHeight is returned unchanged. If it 
   1.166 +is superscript or subscript then the height returned is a percentage, KSuperSubScalingPercentage, 
   1.167 +of aHeight.
   1.168 +
   1.169 +@param aHeight The height of a font. 
   1.170 +@param aPos The print position of the font: superscript, subscript or normal.
   1.171 +@return The required height of the font. */
   1.172 +	{
   1.173 +	if(aPos!=EPrintPosNormal)
   1.174 +		aHeight=(KSuperSubScalingPercentage*aHeight)/100;
   1.175 +	return aHeight;
   1.176 +	}
   1.177 +
   1.178 +//
   1.179 +// CFontCache
   1.180 +//
   1.181 + 
   1.182 +EXPORT_C CFontCache::CFontCache():
   1.183 +	CBase(),
   1.184 +	iMaxEntries(KMaxFontCacheEntries)
   1.185 +/** Default constructor.
   1.186 +
   1.187 +This constructs a CFontCache of size KMaxFontCacheEntries. */
   1.188 +	{
   1.189 +	__DECLARE_NAME(_S("CFontCache"));
   1.190 +	}
   1.191 + 
   1.192 +EXPORT_C CFontCache::CFontCache(TInt aMaxEntries):
   1.193 +	CBase(),
   1.194 +	iMaxEntries(aMaxEntries)
   1.195 +/** Constructor specifying the number of cache entries.
   1.196 +
   1.197 +@param aMaxEntries Number of entries for this cache. You must ensure this 
   1.198 +is less than or equal to KMaxFontCacheEntries. */
   1.199 +	{
   1.200 +	__DECLARE_NAME(_S("CFontCache"));
   1.201 +	}
   1.202 +
   1.203 + 
   1.204 +EXPORT_C CFontCache::~CFontCache()
   1.205 +/** Destructor. 
   1.206 +
   1.207 +This destroys the cashe and releases its allocated memory. */
   1.208 +	{
   1.209 +	CFontCacheEntry* entry=iFirst;
   1.210 +	while(entry)
   1.211 +		{
   1.212 +		iFirst=entry->iNext;
   1.213 +		delete entry;
   1.214 +		entry=iFirst;
   1.215 +		}
   1.216 +	}
   1.217 +
   1.218 + 
   1.219 +EXPORT_C CFont* CFontCache::Search(const TFontSpec& aFontSpec)
   1.220 +/** Searches the cache for a specified font. 
   1.221 +
   1.222 +The CFont returned is that which corresponds to the font specification aFontSpec.
   1.223 +
   1.224 +@param aFontSpec The specification of the font to be searched for. 
   1.225 +@return If an entry for the font specification is found in the cache, the pointer 
   1.226 +to the font corresponding to the font specification is returned. Otherwise 
   1.227 +NULL is returned. */
   1.228 +	{
   1.229 +	CFontCacheEntry* entry=iFirst;
   1.230 +	CFontCacheEntry* previous=NULL;
   1.231 +	while(entry)
   1.232 +		{
   1.233 +		if(entry->iSpec==aFontSpec)
   1.234 +			{
   1.235 +			iNumHits++;
   1.236 +			if(previous)
   1.237 +				{
   1.238 +				previous->iNext=entry->iNext;
   1.239 +				entry->iNext=iFirst;
   1.240 +				iFirst=entry;
   1.241 +				}
   1.242 +			return(entry->iFont);
   1.243 +			}
   1.244 +		previous=entry;
   1.245 +		entry=entry->iNext;
   1.246 +		}
   1.247 +	iNumMisses++;
   1.248 +	return(NULL);
   1.249 +	}
   1.250 +
   1.251 + 
   1.252 +EXPORT_C CFont* CFontCache::AddEntryL(CFont* aFont,const TFontSpec& aFontSpec)
   1.253 +/** Adds a font entry to the cache. 
   1.254 +
   1.255 +The font, and the font specification required to extract it from the cache, 
   1.256 +are both specified. If the cache is already full, the font replaces the oldest 
   1.257 +entry already in the cache, which is returned.
   1.258 +
   1.259 +@param aFont The font to be stored in the cache. 
   1.260 +@param aFontSpec The font's corresponding font specification. 
   1.261 +@return If the cache isn't full, NULL is returned. If the cache is full, the 
   1.262 +displaced cache entry is returned. */
   1.263 +	{
   1.264 +	CFontCacheEntry* entry=new(ELeave) CFontCacheEntry(aFont,aFontSpec,iFirst);
   1.265 +	iFirst=entry;
   1.266 +	iNumEntries++;
   1.267 +	if(iNumEntries<=iMaxEntries)
   1.268 +		return(NULL);
   1.269 +	CFontCacheEntry* previous=NULL;
   1.270 +	while(entry->iNext)
   1.271 +		{
   1.272 +		previous=entry;
   1.273 +		entry=entry->iNext;
   1.274 +		}
   1.275 +	CFont* discardfont=entry->iFont;
   1.276 +	delete entry;
   1.277 +	iNumEntries--;
   1.278 +	if(previous)
   1.279 +		previous->iNext=NULL;
   1.280 +	else
   1.281 +		iFirst=NULL;
   1.282 +	return(discardfont);
   1.283 +	}
   1.284 +
   1.285 + 
   1.286 +EXPORT_C CFont* CFontCache::RemoveFirstEntry()
   1.287 +/** Removes the first entry from the font cache and returns it.
   1.288 +
   1.289 +@return The entry removed from the font cache. If the cache is empty, NULL 
   1.290 +is returned. */
   1.291 +	{
   1.292 +	if(iFirst==NULL) return(NULL);
   1.293 +	CFontCacheEntry* entry=iFirst;
   1.294 +	iFirst=entry->iNext;
   1.295 +	CFont* font=entry->iFont;
   1.296 +	delete entry;
   1.297 +	iNumEntries--;
   1.298 +	return(font);
   1.299 +	}
   1.300 +
   1.301 +// CFontCacheEntry
   1.302 +
   1.303 +CFontCache::CFontCacheEntry::CFontCacheEntry(CFont* aFont,const TFontSpec& aFontSpec,CFontCacheEntry* aNext):
   1.304 +	CBase(),
   1.305 +	iFont(aFont),
   1.306 +	iSpec(aFontSpec),
   1.307 +	iNext(aNext)
   1.308 +	{
   1.309 +	__DECLARE_NAME(_S("CFontCacheEntry"));
   1.310 +	}