fontservices/fontstore/inc/openfontsprivate.h
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 13 Oct 2010 16:35:09 +0300
branchRCL_3
changeset 69 09b5fcf47b30
parent 60 dd58c6eee052
permissions -rw-r--r--
Revision: 201021 Kit: 201041

/*
* Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: 
*
*/


#ifndef __OPENFONTS_PRIVATE_H__
#define __OPENFONTS_PRIVATE_H__

#include <hextree.h>

class COpenFontShaperCacheEntry;

/* MSB is set to indicate a glyph code rather than a unicode value
   This is used for extracting the code value */
#define GLYPH_CODE(code) (code & 0x7fffffff)

/** COpenFontFile owned container for extra data. May be extended without affecting Binary Compatibility.

 @internalComponent
 */

class TOpenFontFileData
	{
public:
	CFontStore* iFontStore;			// pointer to the CFontStore instance that loaded the COpenFontFile
	};

/**
 Note: this class must be self-contained, since instances are added to an RHexTree,
 that is, it must be possible to destroy instances simply with RHeap::Free().
 @internalComponent
 */
class COpenFontGlyph
	{
public:
    static COpenFontGlyph* New(RHeap* aHeap, TInt aCode, TInt aGlyphIndex,
                               const TOpenFontCharMetrics& aMetrics, const TDesC8& aBitmap);
	inline static void Delete(RHeap* aHeap, COpenFontGlyph* aGlyph);
	inline const TUint8* Bitmap() const;

protected:
	COpenFontGlyph(TInt aCode, TInt aGlyphIndex, const TOpenFontCharMetrics& aMetrics)
		: iCode(aCode), iGlyphIndex(aGlyphIndex), iMetrics(aMetrics), iBitmapOffset(0) {}
	~COpenFontGlyph() {}
	void SetBitmap(const TAny* aBitmap);

public:
	const TInt iCode;						// the Unicode value of the character
	const TInt iGlyphIndex;					// the glyph index
	const TOpenFontCharMetrics iMetrics;	// the metrics

private:
	// an offset from this COpenFontGlyph object to a pointer to the run-length-encoded bitmap, 
	// calculated as (bitmapPointer)-(this)
	TInt iBitmapOffset;
	};

/**
 * Template for offset implementation of pointer array
 @internalComponent
 */
template<class T>
class ROffsetArray
    {
public:
    ROffsetArray();
    TInt Create(RHeap* aHeap, TInt aCount);
    void Close(RHeap* aHeap);
    TInt Count() const;
    T* operator[](TInt aIndex) const;
    void SetAt(TInt aIndex, T* aEntry);
private:
    TInt iOffset;
    TInt iCount;
    };

/**
 The per-font glyph cache. For now, just the members that used to be directly in
 COpenFont. Now it is a private class it can be elaborated to do character-to-glyph-index
 mapping when that is needed.

 @internalComponent
 */
class COpenFontGlyphCache
	{
public:
	COpenFontGlyphCache(RHeap* aHeap)
	  : iGlyphTreeById(aHeap),
		iGlyphTreeByUnicode(aHeap),
		iGlyphCacheMemory(0),
		iShaperCacheSentinel(NULL),
		iShapingInfoCacheMemory(0),
		iNumberOfShaperCacheEntries(0)
		{}
	TShapeHeader* SearchShaperCache(TInt aSessionHandle, TFontShapeFunctionParameters*& aParams);
	TShapeHeader* Insert(TInt aSessionHandle, RHeap* aHeap, CShaper::TInput aInput, TShapeHeader* aShapeHeader, TInt& aAddedBytes);
	TInt DeleteLeastRecentlyUsedEntry(RHeap* aHeap);
	TBool ShaperCacheIsEmpty();
	
public:
	RHexTree<COpenFontGlyph> iGlyphTreeById;				// a hex tree of glyphs indexed by glyph ID
	RHexTree<COpenFontGlyph> iGlyphTreeByUnicode;			// a hex tree of glyphs indexed by Unicode code point
	TInt iGlyphCacheMemory;									// memory used by the glyph tree in bytes
	COpenFontShaperCacheEntry* iShaperCacheSentinel;
	TInt iShapingInfoCacheMemory;
	TInt iNumberOfShaperCacheEntries;	
	};

/**
 @internalComponent
 */
class COpenFontSessionCacheEntry: public COpenFontGlyph
	{
public:
	static COpenFontSessionCacheEntry* New(RHeap* aHeap, const COpenFont* aFont, TInt aCode, TInt aGlyphIndex,
										   const TOpenFontCharMetrics& aMetrics, const TDesC8& aBitmap);
	inline static void Delete(RHeap* aHeap, COpenFontSessionCacheEntry* aEntry);
	inline const COpenFont* Font()const;

private:
	inline COpenFontSessionCacheEntry(const COpenFont* aFont, TInt aCode, TInt aGlyphIndex, const TOpenFontCharMetrics& aMetrics);
	~COpenFontSessionCacheEntry();
public:
    TInt iLastAccess;               // serial number of the last access to the glyph

private: 
    TInt iFontOffset;          // offset of the font that contains this glyph, (not owned by this class!)    
	};

/**
 A glyph cache for a particular session.
 Because session caches are not shared they can shrink as well as grow.

 @internalComponent
 */
class COpenFontSessionCache
    {
public:
    static COpenFontSessionCache* NewL(RHeap* aHeap, TInt aSessionHandle, TInt aEntries);
    void Delete(RHeap* aHeap);
    
    TInt SessionHandle() { return iSessionHandle; }
    const COpenFontGlyph* Glyph(const COpenFont* aFont, TInt aCode, TInt& aIndex);
    void Insert(RHeap* aHeap, COpenFontSessionCacheEntry* aEntry, TInt aIndex);
    
private:
    COpenFontSessionCache(TInt aSessionHandle);
    ~COpenFontSessionCache();
public:
    TInt iSessionHandle;    
    TInt iLastAccess;
    ROffsetArray<COpenFontSessionCacheEntry> iEntryArray;
    };


// inline functions

inline void COpenFontGlyph::Delete(RHeap* aHeap, COpenFontGlyph* aGlyph)
	{
	aHeap->Free(aGlyph);
	}

/**
@return A pointer to the bitmap data stored with this glyph, or NULL
if no bitmap has been stored with this glyph.
 */
inline const TUint8* COpenFontGlyph::Bitmap() const
	{
	if (iBitmapOffset)
		{
		return reinterpret_cast<const TUint8*>(PtrAdd(this, iBitmapOffset));
		}
	return NULL;
	}

inline COpenFontSessionCacheEntry::COpenFontSessionCacheEntry(const COpenFont* aFont, TInt aCode, TInt aGlyphIndex,const TOpenFontCharMetrics& aMetrics) :
    COpenFontGlyph(aCode, aGlyphIndex, aMetrics)
    {
    iFontOffset = aFont ? reinterpret_cast<TInt>(aFont) - reinterpret_cast<TInt>(this) : 0;
    }

inline void COpenFontSessionCacheEntry::Delete(RHeap* aHeap, COpenFontSessionCacheEntry* aEntry)
	{
	COpenFontGlyph::Delete(aHeap, aEntry);
	}

inline const COpenFont* COpenFontSessionCacheEntry::Font() const
    {
    if (iFontOffset)
        {
        return reinterpret_cast<const COpenFont*> (PtrAdd(this, iFontOffset));
        }
    return NULL;
    }

#endif	// __OPENFONTSPRIVATE_H__