sl@0: // Copyright (c) 1998-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: // sl@0: sl@0: #include sl@0: #include "GDIPANIC.h" sl@0: sl@0: _LIT(KCTypefaceStore, "CTypefaceStore"); sl@0: static const TInt KDefaultNumOfFontAccess = 4; sl@0: sl@0: // sl@0: // CTypefaceStore sl@0: // sl@0: sl@0: EXPORT_C CTypefaceStore::CTypefaceStore() sl@0: { sl@0: } sl@0: sl@0: sl@0: EXPORT_C CTypefaceStore::~CTypefaceStore() sl@0: /** Destroys the typeface store and reclaims the memory allocated to it. */ sl@0: { sl@0: if (iFontAccess) sl@0: { sl@0: const TInt count = iFontAccess->Count(); sl@0: for (TInt i = 0; i < count; i++) sl@0: { sl@0: GDI_ASSERT_DEBUG_GENERAL((*iFontAccess)[0].iAccessCount > 0, User::Panic(KCTypefaceStore, KErrCorrupt)); sl@0: GDI_ASSERT_DEBUG_GENERAL((*iFontAccess)[0].iAccessCount == 1, User::Panic(KCTypefaceStore, KErrInUse)); sl@0: delete (*iFontAccess)[0].iFont; sl@0: iFontAccess->Delete(0); sl@0: } sl@0: delete iFontAccess; sl@0: } sl@0: } sl@0: sl@0: EXPORT_C void CTypefaceStore::ConstructL() sl@0: /** Second phase constructor. */ sl@0: { sl@0: iFontAccess = new(ELeave) CArrayFixFlat(KDefaultNumOfFontAccess); sl@0: } sl@0: sl@0: EXPORT_C void CTypefaceStore::AddFontL(CFont* aFont) sl@0: /** Adds a hold, by a client of the typeface store, on the specified font. sl@0: sl@0: If the specified font is not currently accessed by any clients of the typeface store sl@0: then the font is added to the font list and the access count set to 1. sl@0: If it is currently accessed then the access count for the font is incremented by 1. sl@0: sl@0: @param aFont Pointer to the device specific font accessed. */ sl@0: { sl@0: GDI_ASSERT_DEBUG_GENERAL(NULL != iFontAccess, User::Panic(KCTypefaceStore, KErrNoMemory)); sl@0: if (IncrementFontCount(aFont)) sl@0: return; sl@0: TFontAccess fontAccess; sl@0: fontAccess.iAccessCount = 1; sl@0: fontAccess.iFont = aFont; sl@0: iFontAccess->AppendL(fontAccess); sl@0: } sl@0: sl@0: EXPORT_C void CTypefaceStore::ReleaseFont(CFont* aFont) sl@0: /** Releases the hold of a typeface store client on a specified font. sl@0: sl@0: Decrements the access-count for the specified font by one. If this reduces the access-count sl@0: to zero then the font is no longer needed by any client, and is deleted from sl@0: the typeface store list. sl@0: sl@0: @param aFont The font to be released by the client. */ sl@0: { sl@0: sl@0: GDI_ASSERT_DEBUG_GENERAL(NULL != iFontAccess, User::Panic(KCTypefaceStore, KErrNoMemory)); sl@0: if (!aFont) sl@0: return; sl@0: TInt idx = 0; sl@0: GDI_ASSERT_ALWAYS_GENERAL(FindFont(aFont, idx), User::Panic(KCTypefaceStore, KErrNotFound)); sl@0: GDI_ASSERT_DEBUG_GENERAL(0 < iFontAccess->At(idx).iAccessCount, User::Panic(KCTypefaceStore, KErrCorrupt)); sl@0: iFontAccess->At(idx).iAccessCount--; sl@0: if (0 == iFontAccess->At(idx).iAccessCount) sl@0: { sl@0: CFont *font=iFontAccess->At(idx).iFont; sl@0: iFontAccess->Delete(idx); sl@0: delete font; sl@0: } sl@0: } sl@0: sl@0: EXPORT_C TBool CTypefaceStore::IncrementFontCount(const CFont* aFont) sl@0: /** sl@0: Search for the font in iFontAccess and increment its count. sl@0: @param aFont Font to search for. sl@0: @return ETrue if the specified font is found, EFalse otherwise. sl@0: */ sl@0: { sl@0: TInt idx = 0; sl@0: if (FindFont(aFont, idx)) sl@0: { sl@0: iFontAccess->At(idx).iAccessCount++; sl@0: return ETrue; sl@0: } sl@0: return EFalse; sl@0: } sl@0: sl@0: TBool CTypefaceStore::FindFont(const CFont* aFont, TInt& aIdx) const sl@0: /** sl@0: Search for the font in iFontAccess. sl@0: @param aFont Font to search for. sl@0: @param aIdx Index of the font found. sl@0: @return ETrue if the specified font is found, EFalse with aIdx = -1 otherwise. sl@0: */ sl@0: { sl@0: aIdx = -1; sl@0: if (!iFontAccess) sl@0: return EFalse; sl@0: const TInt count = iFontAccess->Count(); sl@0: for (TInt i = 0; i < count; i++) sl@0: { sl@0: if ((*iFontAccess)[i].iFont == aFont) sl@0: { sl@0: aIdx = i; sl@0: return ETrue; sl@0: } sl@0: } sl@0: return EFalse; sl@0: } sl@0: sl@0: EXPORT_C TInt CTypefaceStore::BaselineOffset(TInt aHeight,TFontPrintPosition aPos) sl@0: /** Gets the baseline offset, in twips, for any font in subscript or superscript sl@0: form. sl@0: sl@0: If the print position is normal then zero is returned. If it is superscript sl@0: then the baseline offset returned is a percentage, KSuperscriptOffsetPercentage, sl@0: of aHeight. If it is subscript then the baseline offset returned is a percentage, sl@0: KSubscriptOffsetPercentage, of aHeight. sl@0: sl@0: @param aHeight The height of a font. sl@0: @param aPos The print position of the required font: superscript, subscript sl@0: or normal. sl@0: @return The baseline offset for the font. */ sl@0: { sl@0: TInt offset=0; sl@0: if (aPos==EPrintPosSuperscript) sl@0: offset=KSuperscriptOffsetPercentage*aHeight/100; sl@0: else if (aPos==EPrintPosSubscript) sl@0: offset=KSubscriptOffsetPercentage*aHeight/100; sl@0: return offset; sl@0: } sl@0: sl@0: sl@0: EXPORT_C TInt CTypefaceStore::SuperSubHeight(TInt aHeight,TFontPrintPosition aPos) sl@0: /** Gets the height for a font in subscript or superscript form. sl@0: sl@0: If the print position is normal then aHeight is returned unchanged. If it sl@0: is superscript or subscript then the height returned is a percentage, KSuperSubScalingPercentage, sl@0: of aHeight. sl@0: sl@0: @param aHeight The height of a font. sl@0: @param aPos The print position of the font: superscript, subscript or normal. sl@0: @return The required height of the font. */ sl@0: { sl@0: if(aPos!=EPrintPosNormal) sl@0: aHeight=(KSuperSubScalingPercentage*aHeight)/100; sl@0: return aHeight; sl@0: } sl@0: sl@0: // sl@0: // CFontCache sl@0: // sl@0: sl@0: EXPORT_C CFontCache::CFontCache(): sl@0: CBase(), sl@0: iMaxEntries(KMaxFontCacheEntries) sl@0: /** Default constructor. sl@0: sl@0: This constructs a CFontCache of size KMaxFontCacheEntries. */ sl@0: { sl@0: __DECLARE_NAME(_S("CFontCache")); sl@0: } sl@0: sl@0: EXPORT_C CFontCache::CFontCache(TInt aMaxEntries): sl@0: CBase(), sl@0: iMaxEntries(aMaxEntries) sl@0: /** Constructor specifying the number of cache entries. sl@0: sl@0: @param aMaxEntries Number of entries for this cache. You must ensure this sl@0: is less than or equal to KMaxFontCacheEntries. */ sl@0: { sl@0: __DECLARE_NAME(_S("CFontCache")); sl@0: } sl@0: sl@0: sl@0: EXPORT_C CFontCache::~CFontCache() sl@0: /** Destructor. sl@0: sl@0: This destroys the cashe and releases its allocated memory. */ sl@0: { sl@0: CFontCacheEntry* entry=iFirst; sl@0: while(entry) sl@0: { sl@0: iFirst=entry->iNext; sl@0: delete entry; sl@0: entry=iFirst; sl@0: } sl@0: } sl@0: sl@0: sl@0: EXPORT_C CFont* CFontCache::Search(const TFontSpec& aFontSpec) sl@0: /** Searches the cache for a specified font. sl@0: sl@0: The CFont returned is that which corresponds to the font specification aFontSpec. sl@0: sl@0: @param aFontSpec The specification of the font to be searched for. sl@0: @return If an entry for the font specification is found in the cache, the pointer sl@0: to the font corresponding to the font specification is returned. Otherwise sl@0: NULL is returned. */ sl@0: { sl@0: CFontCacheEntry* entry=iFirst; sl@0: CFontCacheEntry* previous=NULL; sl@0: while(entry) sl@0: { sl@0: if(entry->iSpec==aFontSpec) sl@0: { sl@0: iNumHits++; sl@0: if(previous) sl@0: { sl@0: previous->iNext=entry->iNext; sl@0: entry->iNext=iFirst; sl@0: iFirst=entry; sl@0: } sl@0: return(entry->iFont); sl@0: } sl@0: previous=entry; sl@0: entry=entry->iNext; sl@0: } sl@0: iNumMisses++; sl@0: return(NULL); sl@0: } sl@0: sl@0: sl@0: EXPORT_C CFont* CFontCache::AddEntryL(CFont* aFont,const TFontSpec& aFontSpec) sl@0: /** Adds a font entry to the cache. sl@0: sl@0: The font, and the font specification required to extract it from the cache, sl@0: are both specified. If the cache is already full, the font replaces the oldest sl@0: entry already in the cache, which is returned. sl@0: sl@0: @param aFont The font to be stored in the cache. sl@0: @param aFontSpec The font's corresponding font specification. sl@0: @return If the cache isn't full, NULL is returned. If the cache is full, the sl@0: displaced cache entry is returned. */ sl@0: { sl@0: CFontCacheEntry* entry=new(ELeave) CFontCacheEntry(aFont,aFontSpec,iFirst); sl@0: iFirst=entry; sl@0: iNumEntries++; sl@0: if(iNumEntries<=iMaxEntries) sl@0: return(NULL); sl@0: CFontCacheEntry* previous=NULL; sl@0: while(entry->iNext) sl@0: { sl@0: previous=entry; sl@0: entry=entry->iNext; sl@0: } sl@0: CFont* discardfont=entry->iFont; sl@0: delete entry; sl@0: iNumEntries--; sl@0: if(previous) sl@0: previous->iNext=NULL; sl@0: else sl@0: iFirst=NULL; sl@0: return(discardfont); sl@0: } sl@0: sl@0: sl@0: EXPORT_C CFont* CFontCache::RemoveFirstEntry() sl@0: /** Removes the first entry from the font cache and returns it. sl@0: sl@0: @return The entry removed from the font cache. If the cache is empty, NULL sl@0: is returned. */ sl@0: { sl@0: if(iFirst==NULL) return(NULL); sl@0: CFontCacheEntry* entry=iFirst; sl@0: iFirst=entry->iNext; sl@0: CFont* font=entry->iFont; sl@0: delete entry; sl@0: iNumEntries--; sl@0: return(font); sl@0: } sl@0: sl@0: // CFontCacheEntry sl@0: sl@0: CFontCache::CFontCacheEntry::CFontCacheEntry(CFont* aFont,const TFontSpec& aFontSpec,CFontCacheEntry* aNext): sl@0: CBase(), sl@0: iFont(aFont), sl@0: iSpec(aFontSpec), sl@0: iNext(aNext) sl@0: { sl@0: __DECLARE_NAME(_S("CFontCacheEntry")); sl@0: }