fontservices/textbase/sgdi/TFSTORE.CPP
changeset 45 662fa7de7023
equal deleted inserted replaced
41:ea44a32a96bc 45:662fa7de7023
       
     1 // Copyright (c) 1998-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <textbase.h>
       
    17 #include "TextBasePanic.h"
       
    18 
       
    19 _LIT(KCTypefaceStore, "CTypefaceStore");
       
    20 static const TInt KDefaultNumOfFontAccess = 4;
       
    21 
       
    22 //
       
    23 // CTypefaceStore
       
    24 //
       
    25 
       
    26 EXPORT_C CTypefaceStore::CTypefaceStore()
       
    27 	{
       
    28 	}
       
    29 
       
    30 
       
    31 EXPORT_C CTypefaceStore::~CTypefaceStore()
       
    32 /** Destroys the typeface store and reclaims the memory allocated to it. */
       
    33 	{
       
    34 	if (iFontAccess)
       
    35 		{
       
    36 		const TInt count = iFontAccess->Count();
       
    37 		for (TInt i = 0; i < count; i++)
       
    38 			{
       
    39 			TEXTBASE_ASSERT_DEBUG_GENERAL((*iFontAccess)[0].iAccessCount > 0, User::Panic(KCTypefaceStore, KErrCorrupt));
       
    40 			TEXTBASE_ASSERT_DEBUG_GENERAL((*iFontAccess)[0].iAccessCount == 1, User::Panic(KCTypefaceStore, KErrInUse));
       
    41 			delete (*iFontAccess)[0].iFont;
       
    42 			iFontAccess->Delete(0);
       
    43 			}
       
    44 		delete iFontAccess;
       
    45 		}
       
    46 	}
       
    47 
       
    48 EXPORT_C void CTypefaceStore::ConstructL()
       
    49 /** Second phase constructor. */
       
    50 	{
       
    51 	iFontAccess = new(ELeave) CArrayFixFlat<TFontAccess>(KDefaultNumOfFontAccess);
       
    52 	}
       
    53 
       
    54 EXPORT_C void CTypefaceStore::AddFontL(CFont* aFont)
       
    55 /** Adds a hold, by a client of the typeface store, on the specified font.
       
    56 
       
    57 If the specified font is not currently accessed by any clients of the typeface store
       
    58 then the font is added to the font list and the access count set to 1.
       
    59 If it is currently accessed then the access count for the font is incremented by 1.
       
    60 
       
    61 @param aFont Pointer to the device specific font accessed. */
       
    62 	{
       
    63 	TEXTBASE_ASSERT_DEBUG_GENERAL(NULL != iFontAccess, User::Panic(KCTypefaceStore, KErrNoMemory));
       
    64 	if (IncrementFontCount(aFont))
       
    65 		return;
       
    66 	TFontAccess fontAccess;
       
    67 	fontAccess.iAccessCount = 1;
       
    68 	fontAccess.iFont = aFont;
       
    69 	iFontAccess->AppendL(fontAccess);
       
    70 	}
       
    71 
       
    72 EXPORT_C void CTypefaceStore::ReleaseFont(CFont* aFont)
       
    73 /** Releases the hold of a typeface store client on a specified font.
       
    74 
       
    75 Decrements the access-count for the specified font by one. If this reduces the access-count 
       
    76 to zero then the font is no longer needed by any client, and is deleted from 
       
    77 the typeface store list.
       
    78 
       
    79 @param aFont The font to be released by the client. */
       
    80 	{
       
    81 	
       
    82 	TEXTBASE_ASSERT_DEBUG_GENERAL(NULL != iFontAccess, User::Panic(KCTypefaceStore, KErrNoMemory));
       
    83 	if (!aFont)
       
    84 		return;
       
    85 	TInt idx = 0;
       
    86 	TEXTBASE_ASSERT_ALWAYS_GENERAL(FindFont(aFont, idx), User::Panic(KCTypefaceStore, KErrNotFound));
       
    87 	TEXTBASE_ASSERT_DEBUG_GENERAL(0 < iFontAccess->At(idx).iAccessCount, User::Panic(KCTypefaceStore, KErrCorrupt));
       
    88 	iFontAccess->At(idx).iAccessCount--;
       
    89 	if (0 == iFontAccess->At(idx).iAccessCount)
       
    90 		{
       
    91 		CFont *font=iFontAccess->At(idx).iFont;
       
    92 		iFontAccess->Delete(idx);
       
    93 		delete font;
       
    94 		}
       
    95 	}
       
    96 
       
    97 EXPORT_C TBool CTypefaceStore::IncrementFontCount(const CFont* aFont)
       
    98 /**
       
    99 Search for the font in iFontAccess and increment its count.
       
   100 @param aFont Font to search for.
       
   101 @return ETrue if the specified font is found, EFalse otherwise.
       
   102 */
       
   103 	{
       
   104 	TInt idx = 0;
       
   105 	if (FindFont(aFont, idx))
       
   106 		{
       
   107 		iFontAccess->At(idx).iAccessCount++;
       
   108 		return ETrue;
       
   109 		}
       
   110 	return EFalse;
       
   111 	}
       
   112 
       
   113 TBool CTypefaceStore::FindFont(const CFont* aFont, TInt& aIdx) const
       
   114 /**
       
   115 Search for the font in iFontAccess.
       
   116 @param aFont Font to search for.
       
   117 @param aIdx Index of the font found.
       
   118 @return ETrue if the specified font is found, EFalse with aIdx = -1 otherwise.
       
   119 */
       
   120 	{
       
   121 	aIdx = -1;
       
   122 	if (!iFontAccess)
       
   123 		return EFalse;
       
   124 	const TInt count = iFontAccess->Count();
       
   125 	for (TInt i = 0; i < count; i++)
       
   126 		{
       
   127 		if ((*iFontAccess)[i].iFont == aFont)
       
   128 			{
       
   129 			aIdx = i;
       
   130 			return ETrue;
       
   131 			}
       
   132 		}
       
   133 	return EFalse;
       
   134 	}
       
   135 
       
   136 EXPORT_C TInt CTypefaceStore::BaselineOffset(TInt aHeight,TFontPrintPosition aPos)
       
   137 /** Gets the baseline offset, in twips, for any font in subscript or superscript 
       
   138 form.
       
   139 
       
   140 If the print position is normal then zero is returned. If it is superscript 
       
   141 then the baseline offset returned is a percentage, KSuperscriptOffsetPercentage, 
       
   142 of aHeight. If it is subscript then the baseline offset returned is a percentage, 
       
   143 KSubscriptOffsetPercentage, of aHeight.
       
   144 
       
   145 @param aHeight The height of a font. 
       
   146 @param aPos The print position of the required font: superscript, subscript 
       
   147 or normal. 
       
   148 @return The baseline offset for the font. */
       
   149 	{
       
   150 	TInt offset=0;
       
   151 	if (aPos==EPrintPosSuperscript)
       
   152 		offset=KSuperscriptOffsetPercentage*aHeight/100;
       
   153 	else if (aPos==EPrintPosSubscript)
       
   154 		offset=KSubscriptOffsetPercentage*aHeight/100;
       
   155 	return offset;
       
   156 	}
       
   157 	 
       
   158  
       
   159 EXPORT_C TInt CTypefaceStore::SuperSubHeight(TInt aHeight,TFontPrintPosition aPos)
       
   160 /** Gets the height for a font in subscript or superscript form. 
       
   161 
       
   162 If the print position is normal then aHeight is returned unchanged. If it 
       
   163 is superscript or subscript then the height returned is a percentage, KSuperSubScalingPercentage, 
       
   164 of aHeight.
       
   165 
       
   166 @param aHeight The height of a font. 
       
   167 @param aPos The print position of the font: superscript, subscript or normal.
       
   168 @return The required height of the font. */
       
   169 	{
       
   170 	if(aPos!=EPrintPosNormal)
       
   171 		aHeight=(KSuperSubScalingPercentage*aHeight)/100;
       
   172 	return aHeight;
       
   173 	}
       
   174 
       
   175 //
       
   176 // CFontCache
       
   177 //
       
   178  
       
   179 EXPORT_C CFontCache::CFontCache():
       
   180 	CBase(),
       
   181 	iMaxEntries(KMaxFontCacheEntries)
       
   182 /** Default constructor.
       
   183 
       
   184 This constructs a CFontCache of size KMaxFontCacheEntries. */
       
   185 	{
       
   186 	__DECLARE_NAME(_S("CFontCache"));
       
   187 	}
       
   188  
       
   189 EXPORT_C CFontCache::CFontCache(TInt aMaxEntries):
       
   190 	CBase(),
       
   191 	iMaxEntries(aMaxEntries)
       
   192 /** Constructor specifying the number of cache entries.
       
   193 
       
   194 @param aMaxEntries Number of entries for this cache. You must ensure this 
       
   195 is less than or equal to KMaxFontCacheEntries. */
       
   196 	{
       
   197 	__DECLARE_NAME(_S("CFontCache"));
       
   198 	}
       
   199 
       
   200  
       
   201 EXPORT_C CFontCache::~CFontCache()
       
   202 /** Destructor. 
       
   203 
       
   204 This destroys the cashe and releases its allocated memory. */
       
   205 	{
       
   206 	CFontCacheEntry* entry=iFirst;
       
   207 	while(entry)
       
   208 		{
       
   209 		iFirst=entry->iNext;
       
   210 		delete entry;
       
   211 		entry=iFirst;
       
   212 		}
       
   213 	}
       
   214 
       
   215  
       
   216 EXPORT_C CFont* CFontCache::Search(const TFontSpec& aFontSpec)
       
   217 /** Searches the cache for a specified font. 
       
   218 
       
   219 The CFont returned is that which corresponds to the font specification aFontSpec.
       
   220 
       
   221 @param aFontSpec The specification of the font to be searched for. 
       
   222 @return If an entry for the font specification is found in the cache, the pointer 
       
   223 to the font corresponding to the font specification is returned. Otherwise 
       
   224 NULL is returned. */
       
   225 	{
       
   226 	CFontCacheEntry* entry=iFirst;
       
   227 	CFontCacheEntry* previous=NULL;
       
   228 	while(entry)
       
   229 		{
       
   230 		if(entry->iSpec==aFontSpec)
       
   231 			{
       
   232 			iNumHits++;
       
   233 			if(previous)
       
   234 				{
       
   235 				previous->iNext=entry->iNext;
       
   236 				entry->iNext=iFirst;
       
   237 				iFirst=entry;
       
   238 				}
       
   239 			return(entry->iFont);
       
   240 			}
       
   241 		previous=entry;
       
   242 		entry=entry->iNext;
       
   243 		}
       
   244 	iNumMisses++;
       
   245 	return(NULL);
       
   246 	}
       
   247 
       
   248  
       
   249 EXPORT_C CFont* CFontCache::AddEntryL(CFont* aFont,const TFontSpec& aFontSpec)
       
   250 /** Adds a font entry to the cache. 
       
   251 
       
   252 The font, and the font specification required to extract it from the cache, 
       
   253 are both specified. If the cache is already full, the font replaces the oldest 
       
   254 entry already in the cache, which is returned.
       
   255 
       
   256 @param aFont The font to be stored in the cache. 
       
   257 @param aFontSpec The font's corresponding font specification. 
       
   258 @return If the cache isn't full, NULL is returned. If the cache is full, the 
       
   259 displaced cache entry is returned. */
       
   260 	{
       
   261 	CFontCacheEntry* entry=new(ELeave) CFontCacheEntry(aFont,aFontSpec,iFirst);
       
   262 	iFirst=entry;
       
   263 	iNumEntries++;
       
   264 	if(iNumEntries<=iMaxEntries)
       
   265 		return(NULL);
       
   266 	CFontCacheEntry* previous=NULL;
       
   267 	while(entry->iNext)
       
   268 		{
       
   269 		previous=entry;
       
   270 		entry=entry->iNext;
       
   271 		}
       
   272 	CFont* discardfont=entry->iFont;
       
   273 	delete entry;
       
   274 	iNumEntries--;
       
   275 	if(previous)
       
   276 		previous->iNext=NULL;
       
   277 	else
       
   278 		iFirst=NULL;
       
   279 	return(discardfont);
       
   280 	}
       
   281 
       
   282  
       
   283 EXPORT_C CFont* CFontCache::RemoveFirstEntry()
       
   284 /** Removes the first entry from the font cache and returns it.
       
   285 
       
   286 @return The entry removed from the font cache. If the cache is empty, NULL 
       
   287 is returned. */
       
   288 	{
       
   289 	if(iFirst==NULL) return(NULL);
       
   290 	CFontCacheEntry* entry=iFirst;
       
   291 	iFirst=entry->iNext;
       
   292 	CFont* font=entry->iFont;
       
   293 	delete entry;
       
   294 	iNumEntries--;
       
   295 	return(font);
       
   296 	}
       
   297 
       
   298 // CFontCacheEntry
       
   299 
       
   300 CFontCache::CFontCacheEntry::CFontCacheEntry(CFont* aFont,const TFontSpec& aFontSpec,CFontCacheEntry* aNext):
       
   301 	CBase(),
       
   302 	iFont(aFont),
       
   303 	iSpec(aFontSpec),
       
   304 	iNext(aNext)
       
   305 	{
       
   306 	__DECLARE_NAME(_S("CFontCacheEntry"));
       
   307 	}