fontservices/fontstore/src/ShaperCache.CPP
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 15 Sep 2010 00:39:40 +0300
branchRCL_3
changeset 18 dd58c6eee052
parent 0 1fb32624e06b
permissions -rw-r--r--
Revision: 201021 Kit: 201035

/*
* Copyright (c) 2006-2009 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: 
*
*/


#include <fntstore.h>
#include <gdi.h>
#include "FNTSTD.H"
#include <graphics/shapeimpl.h>
#include "ShaperCache.H"

//class COpenFontShaperCacheEntry;
COpenFontShaperCacheEntry* COpenFontShaperCacheEntry::New(RHeap* aHeap)
	{
	COpenFontShaperCacheEntry* entry = (COpenFontShaperCacheEntry*)aHeap->Alloc(sizeof(COpenFontShaperCacheEntry));
	if (!entry)
		return NULL;
	new(entry) COpenFontShaperCacheEntry();	
	return entry;
	}
	
COpenFontShaperCacheEntry* COpenFontShaperCacheEntry::New(RHeap* aHeap, CShaper::TInput aInput, TShapeHeader* aShapeHeader)
	{
	COpenFontShaperCacheEntry* entry = (COpenFontShaperCacheEntry*)aHeap->Alloc(sizeof(COpenFontShaperCacheEntry));
	if (!entry)
		return NULL;
	new(entry) COpenFontShaperCacheEntry(aHeap,aInput);
	TInt ret=entry->Construct(aInput,aShapeHeader);
	if (ret!=KErrNone)
		{
		aHeap->Free(entry);
		return NULL;
		}
	return entry;
	}

TInt COpenFontShaperCacheEntry::Construct(CShaper::TInput aInput,TShapeHeader* aShapeHeader)
	{
	// Get some memory for the shape header
	iShapeHeader = (TShapeHeader*)( iHeap->Alloc(
	sizeof(TShapeHeader) + (aShapeHeader->iGlyphCount * 10) + 4));
	if (iShapeHeader==NULL)
		{
		return KErrNoMemory;
		}
	Mem::Copy(iShapeHeader, aShapeHeader,sizeof(TShapeHeader) + (aShapeHeader->iGlyphCount * 10) + 4);
	
	// Get some memory for the input text
	iText = (TUint16*)(iHeap->Alloc(sizeof(TUint16)*aInput.iText->Length()));
	if (iText==NULL)
		{
		iHeap->Free(iShapeHeader);
		return KErrNoMemory;
		}
	TUint16* inputText = (TUint16*)aInput.iText->Ptr();
	Mem::Copy(iText, inputText, sizeof(TUint16)*aInput.iText->Length());
	return KErrNone;
	}
	
/**
Utility function used to free memory taken up by an entry to the cache
@internalTechnology
**/
void COpenFontShaperCacheEntry::Delete(RHeap* aHeap,COpenFontShaperCacheEntry* aCacheEntry)
	{
	if (!aCacheEntry->IsSentinel())
		{
		aHeap->Free(aCacheEntry->iShapeHeader);
		aHeap->Free(aCacheEntry->iText);
		//now free the THandleCount list
		if (aCacheEntry->iHandleRefList)
			{
			THandleCount* ptr=aCacheEntry->iHandleRefList;
			while (ptr)
				{
				THandleCount* next=ptr->iNext;
				aHeap->Free(ptr);
				ptr=next;
				}
			aCacheEntry->iHandleRefList=NULL;
			}
		aHeap->Free(aCacheEntry);
		}
	}

//function to update the ref count for a particular session handle	
TInt COpenFontShaperCacheEntry::IncRefCount(TInt aSessionHandle)
	{
	//get pointer to start of the linked list
	THandleCount* ptr=iHandleRefList;
	THandleCount* last=NULL;
	//loop through existing entries first
	while (ptr)
		{
		if (ptr->iSessionHandle==aSessionHandle)
			{
			ptr->iRefCount++;
			return KErrNone;			
			}
		last=ptr;
		ptr=ptr->iNext;
		}
	// now we have reached the end of the list or we start with empty list
	THandleCount* handle=(THandleCount*)iHeap->Alloc(sizeof(THandleCount));
	if (!handle)
		return KErrNoMemory;
	new (handle)THandleCount(aSessionHandle);
	//if the list is initially empty
	if (!last)
		iHandleRefList=handle;
	else
		last->iNext=handle;
	iHandleRefCount++;
	return KErrNone;	
	}

//function to decrement the ref count for a particular session handle
//aReset here is used to immediately reset the handleCount reference to zero
//and remove from the entry(this will be called in the case when a client session dies
//Note that once the ref count reaches zero the THandleCount entry is automatically
//removed from the list
TInt COpenFontShaperCacheEntry::DecRefCount(TInt aSessionHandle,TBool aReset)
	{
	//get pointer to start of the linked list
	THandleCount* ptr=iHandleRefList;
	THandleCount* last=NULL;
	//loop through existing entries first
	while (ptr)
		{
		if (ptr->iSessionHandle==aSessionHandle)
			{
			if (aReset || ptr->iRefCount==1)
				{
				THandleCount* next=ptr->iNext;
				//delete from first item
				if (last==NULL)
					iHandleRefList=next;
				else
					last->iNext=next;
				iHeap->Free(ptr);
				iHandleRefCount--;			
				return KErrNone;
				}
			ptr->iRefCount--;
			return KErrNone;			
			}
		last=ptr;	
		ptr=ptr->iNext;
		}
	return KErrNotFound;	
	}