sl@0: /* sl@0: * Copyright (c) 2006-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: sl@0: sl@0: #include sl@0: #include sl@0: #include "FNTSTD.H" sl@0: #include sl@0: #include "ShaperCache.H" sl@0: sl@0: //class COpenFontShaperCacheEntry; sl@0: COpenFontShaperCacheEntry* COpenFontShaperCacheEntry::New(RHeap* aHeap) sl@0: { sl@0: COpenFontShaperCacheEntry* entry = (COpenFontShaperCacheEntry*)aHeap->Alloc(sizeof(COpenFontShaperCacheEntry)); sl@0: if (!entry) sl@0: return NULL; sl@0: new(entry) COpenFontShaperCacheEntry(); sl@0: return entry; sl@0: } sl@0: sl@0: COpenFontShaperCacheEntry* COpenFontShaperCacheEntry::New(RHeap* aHeap, CShaper::TInput aInput, TShapeHeader* aShapeHeader) sl@0: { sl@0: COpenFontShaperCacheEntry* entry = (COpenFontShaperCacheEntry*)aHeap->Alloc(sizeof(COpenFontShaperCacheEntry)); sl@0: if (!entry) sl@0: return NULL; sl@0: new(entry) COpenFontShaperCacheEntry(aHeap,aInput); sl@0: TInt ret=entry->Construct(aInput,aShapeHeader); sl@0: if (ret!=KErrNone) sl@0: { sl@0: aHeap->Free(entry); sl@0: return NULL; sl@0: } sl@0: return entry; sl@0: } sl@0: sl@0: TInt COpenFontShaperCacheEntry::Construct(CShaper::TInput aInput,TShapeHeader* aShapeHeader) sl@0: { sl@0: // Get some memory for the shape header sl@0: iShapeHeader = (TShapeHeader*)( iHeap->Alloc( sl@0: sizeof(TShapeHeader) + (aShapeHeader->iGlyphCount * 10) + 4)); sl@0: if (iShapeHeader==NULL) sl@0: { sl@0: return KErrNoMemory; sl@0: } sl@0: Mem::Copy(iShapeHeader, aShapeHeader,sizeof(TShapeHeader) + (aShapeHeader->iGlyphCount * 10) + 4); sl@0: sl@0: // Get some memory for the input text sl@0: iText = (TUint16*)(iHeap->Alloc(sizeof(TUint16)*aInput.iText->Length())); sl@0: if (iText==NULL) sl@0: { sl@0: iHeap->Free(iShapeHeader); sl@0: return KErrNoMemory; sl@0: } sl@0: TUint16* inputText = (TUint16*)aInput.iText->Ptr(); sl@0: Mem::Copy(iText, inputText, sizeof(TUint16)*aInput.iText->Length()); sl@0: return KErrNone; sl@0: } sl@0: sl@0: /** sl@0: Utility function used to free memory taken up by an entry to the cache sl@0: @internalTechnology sl@0: **/ sl@0: void COpenFontShaperCacheEntry::Delete(RHeap* aHeap,COpenFontShaperCacheEntry* aCacheEntry) sl@0: { sl@0: if (!aCacheEntry->IsSentinel()) sl@0: { sl@0: aHeap->Free(aCacheEntry->iShapeHeader); sl@0: aHeap->Free(aCacheEntry->iText); sl@0: //now free the THandleCount list sl@0: if (aCacheEntry->iHandleRefList) sl@0: { sl@0: THandleCount* ptr=aCacheEntry->iHandleRefList; sl@0: while (ptr) sl@0: { sl@0: THandleCount* next=ptr->iNext; sl@0: aHeap->Free(ptr); sl@0: ptr=next; sl@0: } sl@0: aCacheEntry->iHandleRefList=NULL; sl@0: } sl@0: aHeap->Free(aCacheEntry); sl@0: } sl@0: } sl@0: sl@0: //function to update the ref count for a particular session handle sl@0: TInt COpenFontShaperCacheEntry::IncRefCount(TInt aSessionHandle) sl@0: { sl@0: //get pointer to start of the linked list sl@0: THandleCount* ptr=iHandleRefList; sl@0: THandleCount* last=NULL; sl@0: //loop through existing entries first sl@0: while (ptr) sl@0: { sl@0: if (ptr->iSessionHandle==aSessionHandle) sl@0: { sl@0: ptr->iRefCount++; sl@0: return KErrNone; sl@0: } sl@0: last=ptr; sl@0: ptr=ptr->iNext; sl@0: } sl@0: // now we have reached the end of the list or we start with empty list sl@0: THandleCount* handle=(THandleCount*)iHeap->Alloc(sizeof(THandleCount)); sl@0: if (!handle) sl@0: return KErrNoMemory; sl@0: new (handle)THandleCount(aSessionHandle); sl@0: //if the list is initially empty sl@0: if (!last) sl@0: iHandleRefList=handle; sl@0: else sl@0: last->iNext=handle; sl@0: iHandleRefCount++; sl@0: return KErrNone; sl@0: } sl@0: sl@0: //function to decrement the ref count for a particular session handle sl@0: //aReset here is used to immediately reset the handleCount reference to zero sl@0: //and remove from the entry(this will be called in the case when a client session dies sl@0: //Note that once the ref count reaches zero the THandleCount entry is automatically sl@0: //removed from the list sl@0: TInt COpenFontShaperCacheEntry::DecRefCount(TInt aSessionHandle,TBool aReset) sl@0: { sl@0: //get pointer to start of the linked list sl@0: THandleCount* ptr=iHandleRefList; sl@0: THandleCount* last=NULL; sl@0: //loop through existing entries first sl@0: while (ptr) sl@0: { sl@0: if (ptr->iSessionHandle==aSessionHandle) sl@0: { sl@0: if (aReset || ptr->iRefCount==1) sl@0: { sl@0: THandleCount* next=ptr->iNext; sl@0: //delete from first item sl@0: if (last==NULL) sl@0: iHandleRefList=next; sl@0: else sl@0: last->iNext=next; sl@0: iHeap->Free(ptr); sl@0: iHandleRefCount--; sl@0: return KErrNone; sl@0: } sl@0: ptr->iRefCount--; sl@0: return KErrNone; sl@0: } sl@0: last=ptr; sl@0: ptr=ptr->iNext; sl@0: } sl@0: return KErrNotFound; sl@0: } sl@0: