sl@0: /* sl@0: * Copyright (c) 2006-2010 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: sl@0: sl@0: #ifndef __OPENFONTS_PRIVATE_H__ sl@0: #define __OPENFONTS_PRIVATE_H__ sl@0: sl@0: #include sl@0: #include sl@0: sl@0: class COpenFontShaperCacheEntry; sl@0: sl@0: /* MSB is set to indicate a glyph code rather than a unicode value sl@0: This is used for extracting the code value */ sl@0: #define GLYPH_CODE(code) (code & 0x7fffffff) sl@0: sl@0: /** COpenFontFile owned container for extra data. May be extended without affecting Binary Compatibility. sl@0: sl@0: @internalComponent sl@0: */ sl@0: sl@0: class TOpenFontFileData sl@0: { sl@0: public: sl@0: CFontStore* iFontStore; // pointer to the CFontStore instance that loaded the COpenFontFile sl@0: }; sl@0: sl@0: /** sl@0: Note: this class must be self-contained, since instances are added to an RHexTree, sl@0: that is, it must be possible to destroy instances simply with RHeap::Free(). sl@0: @internalComponent sl@0: */ sl@0: class COpenFontGlyph sl@0: { sl@0: public: sl@0: static COpenFontGlyph* New(RHeap* aHeap, TInt aCode, TInt aGlyphIndex, sl@0: const TOpenFontCharMetrics& aMetrics, const TDesC8& aBitmap); sl@0: inline static void Delete(RHeap* aHeap, COpenFontGlyph* aGlyph); sl@0: inline const TUint8* Bitmap() const; sl@0: sl@0: protected: sl@0: COpenFontGlyph(TInt aCode, TInt aGlyphIndex, const TOpenFontCharMetrics& aMetrics) sl@0: : iCode(aCode), iGlyphIndex(aGlyphIndex), iMetrics(aMetrics), iBitmapOffset(0) {} sl@0: ~COpenFontGlyph() {} sl@0: void SetBitmap(const TAny* aBitmap); sl@0: sl@0: public: sl@0: const TInt iCode; // the Unicode value of the character sl@0: const TInt iGlyphIndex; // the glyph index sl@0: const TOpenFontCharMetrics iMetrics; // the metrics sl@0: sl@0: private: sl@0: // an offset from this COpenFontGlyph object to a pointer to the run-length-encoded bitmap, sl@0: // calculated as (bitmapPointer)-(this) sl@0: TInt iBitmapOffset; sl@0: }; sl@0: sl@0: /** sl@0: * Template for offset implementation of pointer array sl@0: @internalComponent sl@0: */ sl@0: template sl@0: class ROffsetArray sl@0: { sl@0: public: sl@0: ROffsetArray(); sl@0: TInt Create(RHeap* aHeap, TInt aCount); sl@0: void Close(RHeap* aHeap); sl@0: TInt Count() const; sl@0: T* operator[](TInt aIndex) const; sl@0: void SetAt(TInt aIndex, T* aEntry); sl@0: private: sl@0: TInt iOffset; sl@0: TInt iCount; sl@0: }; sl@0: sl@0: sl@0: /** sl@0: The per-font glyph cache. For now, just the members that used to be directly in sl@0: COpenFont. Now it is a private class it can be elaborated to do character-to-glyph-index sl@0: mapping when that is needed. sl@0: sl@0: @internalComponent sl@0: */ sl@0: class COpenFontGlyphCache sl@0: { sl@0: public: sl@0: COpenFontGlyphCache(RHeap* aHeap) sl@0: : iGlyphTreeById(aHeap), sl@0: iGlyphTreeByUnicode(aHeap), sl@0: iGlyphCacheMemory(0), sl@0: iShaperCacheSentinel(NULL), sl@0: iShapingInfoCacheMemory(0), sl@0: iNumberOfShaperCacheEntries(0) sl@0: {} sl@0: TShapeHeader* SearchShaperCache(TInt aSessionHandle, TFontShapeFunctionParameters*& aParams); sl@0: TShapeHeader* Insert(TInt aSessionHandle, RHeap* aHeap, CShaper::TInput aInput, TShapeHeader* aShapeHeader, TInt& aAddedBytes); sl@0: TInt DeleteLeastRecentlyUsedEntry(RHeap* aHeap); sl@0: TBool ShaperCacheIsEmpty(); sl@0: sl@0: public: sl@0: RHexTree iGlyphTreeById; // a hex tree of glyphs indexed by glyph ID sl@0: RHexTree iGlyphTreeByUnicode; // a hex tree of glyphs indexed by Unicode code point sl@0: TInt iGlyphCacheMemory; // memory used by the glyph tree in bytes sl@0: COpenFontShaperCacheEntry* iShaperCacheSentinel; sl@0: TInt iShapingInfoCacheMemory; sl@0: TInt iNumberOfShaperCacheEntries; sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: class COpenFontSessionCacheEntry: public COpenFontGlyph sl@0: { sl@0: public: sl@0: static COpenFontSessionCacheEntry* New(RHeap* aHeap, const COpenFont* aFont, TInt aCode, TInt aGlyphIndex, sl@0: const TOpenFontCharMetrics& aMetrics, const TDesC8& aBitmap); sl@0: inline static void Delete(RHeap* aHeap, COpenFontSessionCacheEntry* aEntry); sl@0: inline const COpenFont* Font()const; sl@0: sl@0: private: sl@0: inline COpenFontSessionCacheEntry(const COpenFont* aFont, TInt aCode, TInt aGlyphIndex, const TOpenFontCharMetrics& aMetrics); sl@0: ~COpenFontSessionCacheEntry(); sl@0: sl@0: private: sl@0: TInt iFontOffset; // offset of the font that contains this glyph, (not owned by this class!) sl@0: }; sl@0: sl@0: /** sl@0: A glyph cache for a particular session. sl@0: Because session caches are not shared they can shrink as well as grow. sl@0: sl@0: @internalComponent sl@0: */ sl@0: class COpenFontSessionCache sl@0: { sl@0: friend class COpenFontSessionCacheList; sl@0: public: sl@0: static COpenFontSessionCache* NewL(RHeap* aHeap, TInt aSessionHandle, TInt aEntries); sl@0: void Delete(RHeap* aHeap); sl@0: sl@0: TInt SessionHandle() { return iSessionHandle; } sl@0: const COpenFontGlyph* Glyph(const COpenFont* aFont, TInt aCode, TInt& aIndex) const; sl@0: void Insert(RHeap* aHeap, COpenFontSessionCacheEntry* aEntry, TInt aIndex); sl@0: sl@0: private: sl@0: COpenFontSessionCache(TInt aSessionHandle); sl@0: ~COpenFontSessionCache(); sl@0: private: sl@0: TInt iSessionHandle; sl@0: TInt64 iRandomSeed; sl@0: ROffsetArray iEntryArray; sl@0: }; sl@0: sl@0: sl@0: class TFontTableGlyphOutlineCacheMemMonitor sl@0: { sl@0: public: sl@0: TFontTableGlyphOutlineCacheMemMonitor(); sl@0: void Inc(TInt aBytes); sl@0: void Dec(TInt aBytes); sl@0: TInt GetMemUsage(); sl@0: private: sl@0: TInt iBytes; sl@0: }; sl@0: sl@0: struct TCacheUserInfo { sl@0: TInt iSessionHandle; sl@0: TInt iRefCount; sl@0: TCacheUserInfo(TInt aSessionHandle, TInt aRefCount = 0): sl@0: iSessionHandle(aSessionHandle), iRefCount(aRefCount) { } sl@0: }; sl@0: sl@0: class CFontTableCache; sl@0: sl@0: class CFontTableCacheItem sl@0: { sl@0: friend class CFontTableCache ; sl@0: sl@0: public: sl@0: CFontTableCacheItem(TUid &aFileUid, const TUint32 aTag, sl@0: TInt aOffset, TInt aLength); sl@0: ~CFontTableCacheItem(); sl@0: sl@0: TInt DecRefCount(TInt aSessionHandle); sl@0: TInt IncRefCount(TInt aSessionHandle); sl@0: sl@0: TBool HasOutstandingRefCount(); sl@0: TInt FindUser(TInt aSessionHandle, TInt *id); sl@0: sl@0: #ifdef _DEBUG sl@0: void SetUser(RPointerArray users) sl@0: { sl@0: TInt len = users.Count(); sl@0: for( TInt i = 0; i < len ; i++ ) sl@0: { sl@0: iUsers.Append(users[i]); sl@0: } sl@0: } sl@0: #endif sl@0: sl@0: private: sl@0: CFontTableCacheItem(const CFontTableCacheItem &); // disallow copy construction. sl@0: CFontTableCacheItem& operator =(const CFontTableCacheItem &); // disallow assignment. sl@0: sl@0: TUid iFileUid; sl@0: TUint32 iTag; sl@0: sl@0: sl@0: TInt iOffset; sl@0: TInt iLength; sl@0: RPointerArray iUsers; sl@0: }; sl@0: sl@0: sl@0: class CFontTableCache sl@0: { sl@0: public: sl@0: CFontTableCache(RHeap* aHeap, TFontTableGlyphOutlineCacheMemMonitor& aMon); sl@0: ~CFontTableCache(); sl@0: TInt Append(TUid aFileUid, TUint32 aTag, sl@0: TAny*& aContent, TInt aLength); sl@0: TInt Find(TUid aFileUid, TUint32 aTag, TAny*& aContent, TInt& aLength, TInt* id); sl@0: TInt IncRefCount(TUid FileUid, TUint32 aTag, TInt aSessionHandle); sl@0: TInt DecRefCount(TUid aFileUid, TUint32 aTag, TInt aSessionHandle); sl@0: TBool HasOutstandingRefCount(); sl@0: TBool HasOutstandingRefCountWithUid(TUid aFileUid); sl@0: void CleanupCacheOnFbsSessionTermination(TInt aSessionHandle); sl@0: void CleanupCacheOnOpenFontFileRemoval(COpenFontFile*); sl@0: #ifdef _DEBUG sl@0: void SetFontItem(RPointerArray cacheItems) sl@0: { sl@0: TInt len = cacheItems.Count(); sl@0: for(TInt i = 0; i < len; i++) sl@0: { sl@0: iCacheItems.Append(cacheItems[i]); sl@0: } sl@0: } sl@0: #endif sl@0: sl@0: private: sl@0: CFontTableCache(const CFontTableCache &); // no copy construction. sl@0: CFontTableCache& operator =(const CFontTableCache &); // no assignment. sl@0: #ifdef _DEBUG sl@0: TInt GetCacheState(const char *func); sl@0: #endif sl@0: sl@0: TFontTableGlyphOutlineCacheMemMonitor &iCacheMemMon; sl@0: RHeap *iHeap; sl@0: RPointerArray iCacheItems; sl@0: }; sl@0: sl@0: sl@0: class TUnhintedOutlineCache; sl@0: sl@0: class TUnhintedOutlineId sl@0: { sl@0: public: sl@0: TUnhintedOutlineId(TUid aFileUid, TInt aFaceIndex, TUint aId); sl@0: TUid iFileUid; sl@0: TInt iFaceIndex; sl@0: TUint iId; sl@0: }; sl@0: sl@0: class COutlineCacheItem { sl@0: friend class CUnhintedOutlineCache; sl@0: friend class CHintedOutlineCache; sl@0: sl@0: public: sl@0: COutlineCacheItem(TInt aOffset, TInt aLength); sl@0: ~COutlineCacheItem() ; sl@0: sl@0: TInt DecRefCount(TInt aSessionHandle); sl@0: TInt IncRefCount(TInt aSessionHandle); sl@0: #ifdef _DEBUG sl@0: void SetUser(RPointerArray users) sl@0: { sl@0: TInt len = users.Count(); sl@0: for( TInt i = 0; i < len ; i++ ) sl@0: { sl@0: iUsers.Append(users[i]); sl@0: } sl@0: } sl@0: #endif sl@0: sl@0: private: sl@0: TInt FindUser(TInt aSessionHandle, TInt *id); sl@0: sl@0: sl@0: TInt iOffset; sl@0: TInt iLength; sl@0: RPointerArray iUsers; sl@0: }; sl@0: sl@0: class CUnhintedOutlineCache { sl@0: public: sl@0: CUnhintedOutlineCache(RHeap* aHeap, TFontTableGlyphOutlineCacheMemMonitor& aMon); sl@0: TInt Find(const TUnhintedOutlineId &aOutlineId, TAny*& aData, TInt& aLength); sl@0: TInt IncRefCount(const TUnhintedOutlineId& aOutlineId, TInt aSessionHandle); sl@0: TInt DecRefCount(const TUnhintedOutlineId& aOutlineId, TInt aSessionHandle); sl@0: TInt CacheUnhintedOutline(const TUnhintedOutlineId& aOutlineId, sl@0: TAny * const aData, const TInt aLength, TAny*& aOutline, TInt &aLen); sl@0: TInt CleanupCacheOnOpenFontFileRemoval(COpenFontFile* aFontFile); sl@0: TInt CleanupCacheOnFbsSessionTermination(TInt aSessionHandle); sl@0: #ifdef _DEBUG sl@0: TInt GetCacheState(const char *func); sl@0: #endif sl@0: ~CUnhintedOutlineCache(); sl@0: sl@0: #ifdef _DEBUG sl@0: void SetUnHintedItem(TUnhintedOutlineId id, COutlineCacheItem* item) sl@0: { sl@0: iItemIdMap.Insert(id, item); sl@0: } sl@0: #endif sl@0: sl@0: private: sl@0: // disallow assignment and copy-construction sl@0: CUnhintedOutlineCache(const CUnhintedOutlineCache &); sl@0: CUnhintedOutlineCache& operator =(const CUnhintedOutlineCache &); sl@0: sl@0: static TUint32 IdHash(const TUnhintedOutlineId& aOutlineId); sl@0: static TBool IdIdentity(const TUnhintedOutlineId& id1, const TUnhintedOutlineId& id2); sl@0: sl@0: TFontTableGlyphOutlineCacheMemMonitor& iCacheMemMon; sl@0: RHeap* iHeap; sl@0: RHashMap iItemIdMap; // map the identity to an index in 'iCacheItems'. sl@0: }; sl@0: sl@0: class CHintedOutlineCache; sl@0: sl@0: class THintedOutlineId sl@0: { sl@0: public: sl@0: THintedOutlineId(COpenFont* aFont, TUint aId); sl@0: COpenFont *iFont; sl@0: TUint iId; sl@0: }; sl@0: sl@0: sl@0: class CHintedOutlineCache { sl@0: public: sl@0: CHintedOutlineCache(RHeap* aHeap, TFontTableGlyphOutlineCacheMemMonitor& aMon); sl@0: TInt Find(const THintedOutlineId& aOutlineId, TAny*& aData, TInt& aLength); sl@0: TInt IncRefCount(const THintedOutlineId& aOutlineId, TInt aSessionHandle); sl@0: TInt DecRefCount(const THintedOutlineId& aOutlineId, TInt aSessionHandle); sl@0: TInt CacheHintedOutline(const THintedOutlineId& aOutlineId, sl@0: TAny* aData, TInt aLength, TAny*& aOutline, TInt& aLen); sl@0: TInt CleanupCacheOnOpenFontRemoval(COpenFont* aFont); sl@0: TInt CleanupCacheOnFbsSessionTermination(TInt aSessionHandle); sl@0: #ifdef _DEBUG sl@0: TInt GetCacheState(const char *func); sl@0: void SetHintedItem(THintedOutlineId id, COutlineCacheItem* item) sl@0: { sl@0: iItemIdMap.Insert(id, item); sl@0: } sl@0: RHashMap GetHintedMap() sl@0: { sl@0: return iItemIdMap; sl@0: } sl@0: #endif sl@0: sl@0: private: sl@0: // disallow assignment and copy-construction sl@0: CHintedOutlineCache(const CHintedOutlineCache &); sl@0: CHintedOutlineCache& operator =(const CHintedOutlineCache &); sl@0: static TUint32 IdHash(const THintedOutlineId& aOutlineId); sl@0: static TBool IdIdentity(const THintedOutlineId& id1, const THintedOutlineId& id2); sl@0: sl@0: TFontTableGlyphOutlineCacheMemMonitor& iCacheMemMon; sl@0: RHeap* iHeap; sl@0: RHashMap iItemIdMap; // map the identity to an index in 'iCacheItems'. sl@0: }; sl@0: sl@0: sl@0: // inline functions sl@0: sl@0: inline void COpenFontGlyph::Delete(RHeap* aHeap, COpenFontGlyph* aGlyph) sl@0: { sl@0: aHeap->Free(aGlyph); sl@0: } sl@0: sl@0: /** sl@0: @return A pointer to the bitmap data stored with this glyph, or NULL sl@0: if no bitmap has been stored with this glyph. sl@0: */ sl@0: inline const TUint8* COpenFontGlyph::Bitmap() const sl@0: { sl@0: if (iBitmapOffset) sl@0: { sl@0: return reinterpret_cast(PtrAdd(this, iBitmapOffset)); sl@0: } sl@0: return NULL; sl@0: } sl@0: sl@0: inline COpenFontSessionCacheEntry::COpenFontSessionCacheEntry(const COpenFont* aFont, TInt aCode, TInt aGlyphIndex,const TOpenFontCharMetrics& aMetrics) : sl@0: COpenFontGlyph(aCode, aGlyphIndex, aMetrics) sl@0: { sl@0: iFontOffset = aFont ? reinterpret_cast(aFont) - reinterpret_cast(this) : 0; sl@0: } sl@0: sl@0: inline void COpenFontSessionCacheEntry::Delete(RHeap* aHeap, COpenFontSessionCacheEntry* aEntry) sl@0: { sl@0: COpenFontGlyph::Delete(aHeap, aEntry); sl@0: } sl@0: sl@0: inline const COpenFont* COpenFontSessionCacheEntry::Font() const sl@0: { sl@0: if (iFontOffset) sl@0: { sl@0: return reinterpret_cast (PtrAdd(this, iFontOffset)); sl@0: } sl@0: return NULL; sl@0: } sl@0: sl@0: #endif // __OPENFONTSPRIVATE_H__