os/graphics/graphicsdeviceinterface/gdi/sgdi/TFSTORE.CPP
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 1998-2009 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 <gdi.h>
    17 #include "GDIPANIC.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 			GDI_ASSERT_DEBUG_GENERAL((*iFontAccess)[0].iAccessCount > 0, User::Panic(KCTypefaceStore, KErrCorrupt));
    40 			GDI_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 	GDI_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 	GDI_ASSERT_DEBUG_GENERAL(NULL != iFontAccess, User::Panic(KCTypefaceStore, KErrNoMemory));
    83 	if (!aFont)
    84 		return;
    85 	TInt idx = 0;
    86 	GDI_ASSERT_ALWAYS_GENERAL(FindFont(aFont, idx), User::Panic(KCTypefaceStore, KErrNotFound));
    87 	GDI_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 	}