fontservices/fontstore/src/OPENFONT.CPP
branchRCL_3
changeset 5 e96e8a131979
parent 0 1fb32624e06b
child 11 6971d1c87c9a
equal deleted inserted replaced
0:1fb32624e06b 5:e96e8a131979
    29 
    29 
    30 const TInt KSessionCacheEntries = 512;
    30 const TInt KSessionCacheEntries = 512;
    31 const TInt KDefaultSlantFactor = 20480;
    31 const TInt KDefaultSlantFactor = 20480;
    32 const TInt KOneIn16Dot16FixedPointFormat = 65536;
    32 const TInt KOneIn16Dot16FixedPointFormat = 65536;
    33 
    33 
    34 #ifdef FNTSTORE_SUPPORT_FMM
    34 template<class T>
    35 class TPointerArrayBaseOffset
    35 ROffsetArray<T>::ROffsetArray()
    36 	{
    36     : iOffset(0), iCount(0)
    37 public:
    37     {}
    38 	TInt iCount;
    38 
    39 	TAny** iEntries;
    39 template<class T>
    40 	TInt iAllocated;
    40 TInt ROffsetArray<T>::Create(RHeap* aHeap, TInt aCount)
    41 	TInt iGranularity;
    41     {
    42 	};
    42     if (iOffset != 0)
    43 
    43         {
    44 /*RArrayGlyphEntries*/
    44         return KErrAlreadyExists;
    45 
    45         }
    46 inline const COpenFontGlyphTreeEntry& RArrayGlyphEntries::operator[](TInt anIndex) const
    46     TAny* p = aHeap->AllocZ(aCount * sizeof(TInt));
    47 	{
    47     if (p == NULL)
    48 	return *Entry(anIndex);
    48         {
    49 	}
    49         return KErrNoMemory;
    50 
    50         }
    51 inline COpenFontGlyphTreeEntry& RArrayGlyphEntries::operator[](TInt anIndex)
    51     iOffset = (TInt)p - (TInt)this;
    52 	{
    52     iCount = aCount;
    53 	return *const_cast<COpenFontGlyphTreeEntry*>(Entry(anIndex));
    53     return KErrNone;
    54 	}
    54     }
    55 
    55 
    56 inline const COpenFontGlyphTreeEntry* RArrayGlyphEntries::Entry(TInt anIndex) const
    56 template<class T>
    57 	{
    57 void ROffsetArray<T>::Close(RHeap* aHeap)
    58 	return reinterpret_cast<const COpenFontGlyphTreeEntry*>(PtrAdd(EntryMemberOffSet()[anIndex],reinterpret_cast<TInt>(this)));
    58     {
    59 	}
    59     if (iOffset != 0)
    60 
    60         {
    61 inline COpenFontGlyphTreeEntry** RArrayGlyphEntries::EntryMemberOffSet() const
    61         aHeap->Free(PtrAdd(this, iOffset));
    62 	{
    62         }
    63 	return reinterpret_cast<COpenFontGlyphTreeEntry**>(iEntriesOffset+reinterpret_cast<TInt>(this));
    63     iOffset = 0;
    64 	}
    64     iCount = 0;
    65 
    65     }
    66 inline TAny** RArrayGlyphEntries::EntryMember() const
    66 
    67 	{
    67 template<class T>
    68 	return reinterpret_cast<const TPointerArrayBaseOffset*>(this)->iEntries;
    68 TInt ROffsetArray<T>::Count() const
    69 	}
    69     {
    70 
    70     return iCount;
    71 TInt RArrayGlyphEntries::Append(COpenFontGlyphTreeEntry& anEntry)
    71     }
    72 	{		
    72 
    73 	TInt err = RArray<TInt>::Append(reinterpret_cast<TInt>(&anEntry)-reinterpret_cast<TInt>(this));
    73 template<class T>
    74 	if (err == KErrNone)
    74 T* ROffsetArray<T>::operator[](TInt aIndex) const
    75 		{
    75     {
    76 		iEntriesOffset=reinterpret_cast<TInt>(EntryMember())-reinterpret_cast<TInt>(this);
    76     TInt e = ((TInt*)PtrAdd(this, iOffset))[aIndex];
    77 		}
    77     return e != 0 ? (T*)PtrAdd(this, e) : NULL;
    78 	return err;
    78     }
    79 	}
    79 
    80 #endif // FNTSTORE_SUPPORT_FMM
    80 template<class T>
       
    81 void ROffsetArray<T>::SetAt(TInt aIndex, T* aEntry)
       
    82     {
       
    83     ((TInt*)PtrAdd(this, iOffset))[aIndex] = aEntry ? (TInt)aEntry - (TInt)this : 0;
       
    84     }
       
    85 
    81 
    86 
    82 /*COpenFontGlyphCache*/
    87 /*COpenFontGlyphCache*/
    83 
    88 
    84 TShapeHeader* COpenFontGlyphCache::SearchShaperCache(TInt aSessionHandle, TFontShapeFunctionParameters*& aParams)
    89 TShapeHeader* COpenFontGlyphCache::SearchShaperCache(TInt aSessionHandle, TFontShapeFunctionParameters*& aParams)
    85 	{
    90 	{
   147 	TInt heapSizeBefAloc = 0;
   152 	TInt heapSizeBefAloc = 0;
   148 	aHeap->AllocSize(heapSizeBefAloc);
   153 	aHeap->AllocSize(heapSizeBefAloc);
   149 
   154 
   150 	COpenFontShaperCacheEntry* new_entry;
   155 	COpenFontShaperCacheEntry* new_entry;
   151 	new_entry = COpenFontShaperCacheEntry::New(aHeap, aInput, aShapeHeader);
   156 	new_entry = COpenFontShaperCacheEntry::New(aHeap, aInput, aShapeHeader);
   152 	if (new_entry)
   157 	if (new_entry != NULL)
   153 		{
   158 		{
   154 		// increase the reference count for this
   159 		// increase the reference count for this
   155 		TInt ret=new_entry->IncRefCount(aSessionHandle);
   160 		TInt ret=new_entry->IncRefCount(aSessionHandle);
   156 		if (ret != KErrNone)
   161 		if (ret != KErrNone)
   157 			{
   162 			{
   219 	return 0;
   224 	return 0;
   220 	}
   225 	}
   221 
   226 
   222 TInt COpenFont::DecrementCachedRefCount(TInt aSessionHandle, TShapeHeader* aShapeHeader, TBool aResetAll)
   227 TInt COpenFont::DecrementCachedRefCount(TInt aSessionHandle, TShapeHeader* aShapeHeader, TBool aResetAll)
   223 	{
   228 	{
   224 #ifdef FNTSTORE_SUPPORT_FMM
       
   225 	COpenFontShaperCacheEntry* ptr=NULL;
   229 	COpenFontShaperCacheEntry* ptr=NULL;
   226 	COpenFontGlyphCache* glyphCache=GetGlyphCache();
   230 	COpenFontGlyphCache* glyphCache=GetGlyphCache();
   227 	if (glyphCache)
   231 	if (glyphCache != NULL)
   228 		ptr=glyphCache->iShaperCacheSentinel;
   232 		ptr=glyphCache->iShaperCacheSentinel;
   229 	if (!ptr)
   233 	if (ptr == NULL)
   230 		return KErrNone;
   234 		return KErrNone;
   231 #else
       
   232 	if (!iGlyphCache || !(iGlyphCache->iShaperCacheSentinel))
       
   233 		return KErrNone;
       
   234 
       
   235 	COpenFontShaperCacheEntry* ptr=iGlyphCache->iShaperCacheSentinel;
       
   236 	COpenFontGlyphCache* glyphCache=iGlyphCache;
       
   237 #endif // FNTSTORE_SUPPORT_FMM
       
   238 
   235 
   239 	TInt ret = KErrNotFound;
   236 	TInt ret = KErrNotFound;
   240 	CFontStore* thisFontStore = File()->GetFontStore();
   237 	CFontStore* thisFontStore = File()->GetFontStore();
   241 	TInt allocBefDec = 0;
   238 	TInt allocBefDec = 0;
   242 	TInt allocAfterDec = 0;
   239 	TInt allocAfterDec = 0;
   243 	TInt deletedBytes = 0;
   240 	TInt deletedBytes = 0;
   244 
   241 
   245 	// loop through the cache entry to decrement the ref count for a particular session	
   242 	// loop through the cache entry to decrement the ref count for a particular session	
   246 	while (ptr->iNext)
   243 	while (ptr->iNext != NULL)
   247 		{
   244 		{
   248 		if (aResetAll)
   245 		if (aResetAll)
   249 			{
   246 			{
   250 			// we want to reset any cache that has a matching the session handle
   247 			// we want to reset any cache that has a matching the session handle
   251 			// i.e. here we dont care about which TShapeHeader and hence we can
   248 			// i.e. here we dont care about which TShapeHeader and hence we can
   262 			glyphCache->iShapingInfoCacheMemory -= deletedBytes;
   259 			glyphCache->iShapingInfoCacheMemory -= deletedBytes;
   263 			thisFontStore->SetShaperCacheMemUsage(thisFontStore->GetShaperCacheMemUsage() - deletedBytes);
   260 			thisFontStore->SetShaperCacheMemUsage(thisFontStore->GetShaperCacheMemUsage() - deletedBytes);
   264 
   261 
   265 			ret=KErrNone;
   262 			ret=KErrNone;
   266 			}
   263 			}
   267 		else if (ptr->iShapeHeader && ptr->iShapeHeader==aShapeHeader)
   264 		else if (ptr->iShapeHeader != NULL && ptr->iShapeHeader==aShapeHeader)
   268 			{
   265 			{
   269 			// Always update the memory usage of the cache as decreasing the ref count 
   266 			// Always update the memory usage of the cache as decreasing the ref count 
   270 			// releases memory
   267 			// releases memory
   271 			iHeap->AllocSize(allocBefDec);
   268 			iHeap->AllocSize(allocBefDec);
   272 
   269 
   333 							}
   330 							}
   334 						}
   331 						}
   335 					j++;
   332 					j++;
   336 					}
   333 					}
   337 				i++;
   334 				i++;
   338 				}
   335                 }
   339 			}
   336             }
   340 			
   337 
   341 		// If deleted bytes are still less than the required one delete from this font
   338         // If deleted bytes are still less than the required one delete from this font
   342 #ifdef FNTSTORE_SUPPORT_FMM
   339         COpenFontGlyphCache* glyphCache = GetGlyphCache();
   343 		COpenFontGlyphCache* glyphCache = GetGlyphCache();
   340         if (glyphCache != NULL)
   344 #else
   341             {
   345 		COpenFontGlyphCache* glyphCache = iGlyphCache;
   342             while (totalDeletedBytes < aBytesNeeded && !glyphCache->ShaperCacheIsEmpty())
   346 #endif // FNTSTORE_SUPPORT_FMM
   343                 {
   347 		while (totalDeletedBytes < aBytesNeeded && !glyphCache->ShaperCacheIsEmpty())
   344                 tempDeletedBytes = glyphCache->DeleteLeastRecentlyUsedEntry(iHeap);
   348 			{				
   345                 if (tempDeletedBytes == 0)
   349 			tempDeletedBytes = glyphCache->DeleteLeastRecentlyUsedEntry(iHeap);
   346                     break;
   350 			if ( tempDeletedBytes == 0)
   347                 totalDeletedBytes += tempDeletedBytes;
   351 				break;
   348                 }
   352 			totalDeletedBytes += tempDeletedBytes;
   349             }   //if(glyphCache)
   353 			}
   350         }   //if(aBytesNeeded <= KMaxShaperSesssionCacheMemory)
   354 		}
       
   355 		
   351 		
   356 	// Update the global CFontStore cache memory count
   352 	// Update the global CFontStore cache memory count
   357 	if (totalDeletedBytes > 0)
   353 	if (totalDeletedBytes > 0)
   358 		{
   354 		{
   359 		thisFontStore->SetShaperCacheMemUsage(thisFontStore->GetShaperCacheMemUsage() - totalDeletedBytes);
   355 		thisFontStore->SetShaperCacheMemUsage(thisFontStore->GetShaperCacheMemUsage() - totalDeletedBytes);
   374 	input.iFlags = 0;
   370 	input.iFlags = 0;
   375 	input.iSessionHandle = aSessionHandle;
   371 	input.iSessionHandle = aSessionHandle;
   376 	input.iReserved1 = 0;
   372 	input.iReserved1 = 0;
   377 
   373 
   378 	CFontStore* thisFontStore = File()->GetFontStore();
   374 	CFontStore* thisFontStore = File()->GetFontStore();
   379 
   375 	
   380 	// Create the glyph cache if it doesnt already exist.
   376 	// Create the glyph cache if it doesn't already exist.
   381 	// This call can only come from FBSERV
   377     // This call can only come from FBSERV
   382 	if (iGlyphCache == NULL)
   378     COpenFontGlyphCache* glyphCache = GetGlyphCache();
   383 		{
   379     if (glyphCache == NULL)
   384 		iGlyphCache = (COpenFontGlyphCache*)iHeap->Alloc(sizeof(COpenFontGlyphCache));
   380         {
   385 		if (iGlyphCache == NULL) // no memory
   381         glyphCache = (COpenFontGlyphCache*) iHeap->Alloc(sizeof(COpenFontGlyphCache));
   386 			{
   382         if (glyphCache == NULL) // no memory
   387 			return NULL;
   383             {
   388 			}
   384             return NULL;
   389 		new(iGlyphCache) COpenFontGlyphCache;
   385             }
   390 		}
   386         new (glyphCache) COpenFontGlyphCache;
   391 	// If there is no sentinel present, i.e. new cache
   387         SetGlyphCache(glyphCache);
   392 	if (iGlyphCache->iShaperCacheSentinel == NULL)
   388         }
   393 		{
   389     // If there is no sentinel present, i.e. new cache
   394 		// Create a sentinel
   390     if (glyphCache->iShaperCacheSentinel == NULL)
   395 		iGlyphCache->iShaperCacheSentinel = COpenFontShaperCacheEntry::New(iHeap);
   391         {
   396 		if (!iGlyphCache->iShaperCacheSentinel)
   392         // Create a sentinel
   397 			{
   393         glyphCache->iShaperCacheSentinel = COpenFontShaperCacheEntry::New(iHeap);
   398 			// no memory
   394         if (glyphCache->iShaperCacheSentinel == NULL)
   399 			return NULL;
   395             {
   400 			}
   396             // no memory
   401 		iGlyphCache->iShaperCacheSentinel->iNext = iGlyphCache->iShaperCacheSentinel;
   397             return NULL;
   402 		iGlyphCache->iShaperCacheSentinel->iPrevious = iGlyphCache->iShaperCacheSentinel;
   398             }
   403 		iGlyphCache->iNumberOfShaperCacheEntries = 1;
   399         glyphCache->iShaperCacheSentinel->iNext = glyphCache->iShaperCacheSentinel;
   404 		}
   400         glyphCache->iShaperCacheSentinel->iPrevious = glyphCache->iShaperCacheSentinel;
   405 
   401         glyphCache->iNumberOfShaperCacheEntries = 1;
   406 	// Before inserting into this cache, check if it was empty.
   402         }
   407 	// If empty, then increment the global cache count signifying one more cache is active
   403 
   408 	if (iGlyphCache->ShaperCacheIsEmpty())
   404     // Before inserting into this cache, check if it was empty.
   409 		{
   405     // If empty, then increment the global cache count signifying one more cache is active
   410 		thisFontStore->IncNumShaperCaches();
   406     if (glyphCache->ShaperCacheIsEmpty())
   411 		}
   407         {
       
   408         thisFontStore->IncNumShaperCaches();
       
   409         }
   412 
   410 
   413 	TInt addedBytes = 0;
   411 	TInt addedBytes = 0;
   414 	TShapeHeader* cached_header = NULL;
   412 	TShapeHeader* cached_header = NULL;
   415 
   413 
   416 	// Insert a new entry and return the newly inserted TShapeHeader entry
   414 	// Insert a new entry and return the newly inserted TShapeHeader entry
   417 	cached_header = iGlyphCache->Insert(aSessionHandle, iHeap, input, aShapeHeader, addedBytes);
   415 	cached_header = glyphCache->Insert(aSessionHandle, iHeap, input, aShapeHeader, addedBytes);
   418 	if (cached_header == NULL)
   416 	if (cached_header == NULL)
   419 		return NULL;
   417 		return NULL;
   420 
   418 
   421 	// If the memory used by all the caches is greater than KMaxShaperSesssionCacheMemory, then
   419 	// If the memory used by all the caches is greater than KMaxShaperSesssionCacheMemory, then
   422 	// free some memory by releasing the same amount of memory that was just added
   420 	// free some memory by releasing the same amount of memory that was just added
   430 	return cached_header;
   428 	return cached_header;
   431 	}
   429 	}
   432 
   430 
   433 TShapeHeader* COpenFont::GetShapedData(TInt aSessionHandle, TFontShapeFunctionParameters* aParams)
   431 TShapeHeader* COpenFont::GetShapedData(TInt aSessionHandle, TFontShapeFunctionParameters* aParams)
   434 	{
   432 	{
   435 	if (iGlyphCache == NULL)
   433     COpenFontGlyphCache* glyphCache = GetGlyphCache();
       
   434 	if (glyphCache == NULL)
   436 		return NULL;
   435 		return NULL;
   437 
   436 
   438 	TShapeHeader* cachedHeader = NULL;
   437 	TShapeHeader* cachedHeader = NULL;
   439 	CFontStore* thisFontStore = File()->GetFontStore();
   438 	CFontStore* thisFontStore = File()->GetFontStore();
   440 
   439 
   441 	// Always update the memory usage of the cache as increasing the reference count of a found header uses up memory
   440 	// Always update the memory usage of the cache as increasing the reference count of a found header uses up memory
   442 	TInt allocBefInc = 0;
   441 	TInt allocBefInc = 0;
   443 	TInt allocAfterInc = 0;
   442 	TInt allocAfterInc = 0;
   444 	iHeap->AllocSize(allocBefInc);
   443 	iHeap->AllocSize(allocBefInc);
   445 	
   444 
   446 #ifdef FNTSTORE_SUPPORT_FMM
       
   447 	COpenFontGlyphCache* glyphCache = GetGlyphCache();
       
   448 #else
       
   449 	COpenFontGlyphCache* glyphCache = iGlyphCache;
       
   450 #endif // FNTSTORE_SUPPORT_FMM
       
   451 	cachedHeader = glyphCache->SearchShaperCache(aSessionHandle,aParams);
   445 	cachedHeader = glyphCache->SearchShaperCache(aSessionHandle,aParams);
   452 	
   446 	
   453 	iHeap->AllocSize(allocAfterInc);
   447 	iHeap->AllocSize(allocAfterInc);
   454 	TInt addedBytes = allocAfterInc - allocBefInc;
   448 	TInt addedBytes = allocAfterInc - allocBefInc;
   455 	glyphCache->iShapingInfoCacheMemory += addedBytes;
   449 	glyphCache->iShapingInfoCacheMemory += addedBytes;
   480 @param aSessionCacheList The session cache list.
   474 @param aSessionCacheList The session cache list.
   481 @param aFile A pointer to the COpenFontFile object creating this COpenFont. 
   475 @param aFile A pointer to the COpenFontFile object creating this COpenFont. 
   482 e.g. when creating a COpenFont the COpenFontFile derived object would pass 
   476 e.g. when creating a COpenFont the COpenFontFile derived object would pass 
   483 it this.
   477 it this.
   484 */
   478 */
   485 #ifdef FNTSTORE_SUPPORT_FMM
       
   486 EXPORT_C COpenFont::COpenFont(RHeap* aHeap,COpenFontSessionCacheList* aSessionCacheList,
   479 EXPORT_C COpenFont::COpenFont(RHeap* aHeap,COpenFontSessionCacheList* aSessionCacheList,
   487 							  COpenFontFile* aFile):
   480 							  COpenFontFile* aFile):
   488 	iHeap(aHeap),
   481 	iHeap(aHeap),
   489 	iShaper(NULL),
   482 	iShaper(NULL),
   490 	iFile(aFile),
   483 	iFaceIndex(0)
   491 	iFaceIndex(0),
       
   492 	iSessionCacheList(aSessionCacheList)
       
   493 	{	
   484 	{	
   494 	iStartingThis=reinterpret_cast<TInt>(this);
   485     SetFile(aFile);
   495 	}
   486     SetSessionCacheList(aSessionCacheList);
   496 #else
   487 	}
   497 EXPORT_C COpenFont::COpenFont(RHeap* aHeap,COpenFontSessionCacheList* aSessionCacheList, COpenFontFile* aFile)
       
   498  :	iHeap(aHeap),
       
   499 	iShaper(NULL),
       
   500 	iFile(aFile),
       
   501 	iFaceIndex(0),
       
   502 	iSessionCacheList(aSessionCacheList),
       
   503 	iReserved(NULL)
       
   504 	{
       
   505 
       
   506 	}
       
   507 #endif // FNTSTORE_SUPPORT_FMM
       
   508 
   488 
   509 /**
   489 /**
   510 C++ constructor taking shared heap, session cache list, font file and face 
   490 C++ constructor taking shared heap, session cache list, font file and face 
   511 index as parameters.
   491 index as parameters.
   512 
   492 
   519 @param aFile A pointer to the COpenFontFile object creating this COpenFont. 
   499 @param aFile A pointer to the COpenFontFile object creating this COpenFont. 
   520 e.g. when creating a COpenFont the COpenFontFile derived object would pass 
   500 e.g. when creating a COpenFont the COpenFontFile derived object would pass 
   521 it this.
   501 it this.
   522 @param aFaceIndex The index of the typeface within the font file aFile.
   502 @param aFaceIndex The index of the typeface within the font file aFile.
   523 */
   503 */
   524 #ifdef FNTSTORE_SUPPORT_FMM
       
   525 EXPORT_C COpenFont::COpenFont(RHeap* aHeap,COpenFontSessionCacheList* aSessionCacheList, COpenFontFile* aFile,TInt aFaceIndex) :
   504 EXPORT_C COpenFont::COpenFont(RHeap* aHeap,COpenFontSessionCacheList* aSessionCacheList, COpenFontFile* aFile,TInt aFaceIndex) :
   526  	iHeap(aHeap),
   505  	iHeap(aHeap),
   527 	iShaper(NULL),
   506 	iShaper(NULL),
   528 	iFile(aFile),
   507 	iFaceIndex(aFaceIndex)
   529 	iFaceIndex(aFaceIndex),
   508 	{
   530 	iSessionCacheList(aSessionCacheList)
   509     SetFile(aFile);
   531 	{
   510     SetSessionCacheList(aSessionCacheList);
   532 	iStartingThis=reinterpret_cast<TInt>(this);
   511 	}
   533 	}
       
   534 #else
       
   535 EXPORT_C COpenFont::COpenFont(RHeap* aHeap,COpenFontSessionCacheList* aSessionCacheList, COpenFontFile* aFile,TInt aFaceIndex)
       
   536  :	iHeap(aHeap),
       
   537 	iShaper(NULL),
       
   538 	iFile(aFile),
       
   539 	iFaceIndex(aFaceIndex),
       
   540 	iSessionCacheList(aSessionCacheList),
       
   541 	iReserved(NULL)
       
   542 	{
       
   543 
       
   544 	}
       
   545 #endif // FNTSTORE_SUPPORT_FMM
       
   546 
   512 
   547 /**
   513 /**
   548 Destructor
   514 Destructor
   549 
   515 
   550 This function frees all memory owned by the object, including the session 
   516 This function frees all memory owned by the object, including the session 
   555 	//Delete the shaper
   521 	//Delete the shaper
   556 	delete iShaper;
   522 	delete iShaper;
   557 
   523 
   558 	File()->GetFontStore()->CleanupCacheOnOpenFontRemoval(this);
   524 	File()->GetFontStore()->CleanupCacheOnOpenFontRemoval(this);
   559 	
   525 	
   560 	if (iGlyphCache)
   526 	COpenFontGlyphCache* glyphCache = GetGlyphCache();
       
   527 	if (glyphCache != NULL)
   561 		{
   528 		{
   562 		COpenFontGlyphTreeEntry* next = NULL;
   529 		COpenFontGlyphTreeEntry* next = NULL;
   563 #ifdef FNTSTORE_SUPPORT_FMM
   530 		for (COpenFontGlyphTreeEntry* g = glyphCache->iGlyphList; g != NULL; g = next)
   564 		TInt ii;
       
   565 		RArrayGlyphEntries& glyphArray=iGlyphCache->iGlyphArray;
       
   566 		for (ii=glyphArray.Count()-1;ii>=0;--ii)
       
   567 			{
       
   568 			next=&glyphArray[ii];
       
   569 			COpenFontGlyph::Delete(iHeap,next);
       
   570 			}
       
   571 		iGlyphCache->iGlyphArray.Close();
       
   572 #else
       
   573 		for (COpenFontGlyphTreeEntry* g = iGlyphCache->iGlyphList; g; g = next)
       
   574 			{
   531 			{
   575 			next = g->iNext;
   532 			next = g->iNext;
   576 			COpenFontGlyph::Delete(iHeap, g);
   533 			COpenFontGlyph::Delete(iHeap, g);
   577 			}
   534 			}
   578 #endif // FNTSTORE_SUPPORT_FMM
       
   579 
   535 
   580 		// Delete the shaper cache as well
   536 		// Delete the shaper cache as well
   581 		if (iGlyphCache->iShaperCacheSentinel)
   537 		if (glyphCache->iShaperCacheSentinel)
   582 			{
   538 			{
   583 			COpenFontShaperCacheEntry* previous  = NULL;
   539 			COpenFontShaperCacheEntry* previous  = NULL;
   584 			COpenFontShaperCacheEntry* si = iGlyphCache->iShaperCacheSentinel->iPrevious;
   540 			COpenFontShaperCacheEntry* si = glyphCache->iShaperCacheSentinel->iPrevious;
   585 			TInt heapBefore = 0;
   541 			TInt heapBefore = 0;
   586 			TInt heapAfter = 0;
   542 			TInt heapAfter = 0;
   587 			iHeap->AllocSize(heapBefore);
   543 			iHeap->AllocSize(heapBefore);
   588 			while (iGlyphCache->iNumberOfShaperCacheEntries > 0)
   544 			while (glyphCache->iNumberOfShaperCacheEntries > 0)
   589 				{
   545 				{
   590 				previous = si->iPrevious;
   546 				previous = si->iPrevious;
   591 				COpenFontShaperCacheEntry::Delete(iHeap, si);
   547 				COpenFontShaperCacheEntry::Delete(iHeap, si);
   592 				si = previous;
   548 				si = previous;
   593 				iGlyphCache->iNumberOfShaperCacheEntries--;
   549 				glyphCache->iNumberOfShaperCacheEntries--;
   594 				}
   550 				}
   595 			iHeap->AllocSize(heapAfter);
   551 			iHeap->AllocSize(heapAfter);
   596 			File()->GetFontStore()->SetShaperCacheMemUsage(File()->GetFontStore()->GetShaperCacheMemUsage() - (heapBefore - heapAfter));
   552 			File()->GetFontStore()->SetShaperCacheMemUsage(File()->GetFontStore()->GetShaperCacheMemUsage() - (heapBefore - heapAfter));
   597 			File()->GetFontStore()->DecNumShaperCaches();
   553 			File()->GetFontStore()->DecNumShaperCaches();
   598 			}
   554 			}
   599 
   555 
   600 		iHeap->Free(iGlyphCache);
   556 		iHeap->Free(glyphCache);
   601 		}
   557 		}
   602 	if (iSessionCacheList)	
   558 	COpenFontSessionCacheList* sessionCacheList = SessionCacheList();
   603 		iSessionCacheList->DeleteFontGlyphs(iHeap, this);
   559     if (sessionCacheList != NULL)
   604 	if (iFile)
   560         {
   605 		iFile->RemoveFontFromList(this);
   561         sessionCacheList->DeleteFontGlyphs(iHeap, this);
       
   562         }
       
   563     COpenFontFile* file = File();
       
   564     if (file != NULL)
       
   565         {
       
   566         file->RemoveFontFromList(this);
       
   567         }
   606 	}
   568 	}
   607 
   569 
   608 COpenFontGlyph::~COpenFontGlyph()
   570 COpenFontGlyph::~COpenFontGlyph()
   609 	{
   571 	{
   610 	}
   572 	}
   611 
   573 
   612 void COpenFontGlyph::Delete(RHeap* aHeap, COpenFontGlyph* aGlyph)
   574 void COpenFontGlyph::Delete(RHeap* aHeap, COpenFontGlyph* aGlyph)
   613 	{
   575 	{
   614 	if (aGlyph)
   576 	if (aGlyph != NULL)
   615 		{
   577 		{
   616 #ifdef FNTSTORE_SUPPORT_FMM
       
   617 		aHeap->Free(aGlyph->Bitmap());
   578 		aHeap->Free(aGlyph->Bitmap());
   618 #else
       
   619 		aHeap->Free(aGlyph->iBitmap);
       
   620 #endif // FNTSTORE_SUPPORT_FMM
       
   621 		aHeap->Free(aGlyph);
   579 		aHeap->Free(aGlyph);
   622 		}
   580 		}
   623 	}
   581 	}
   624 
   582 
   625 EXPORT_C void COpenFont::operator delete(TAny *aFont)
   583 EXPORT_C void COpenFont::operator delete(TAny *aFont)
   626 	{
   584 	{
   627 	if(aFont)
   585 	if(aFont != NULL)
   628 		{
   586 		{
   629 		COpenFont* f = (COpenFont*)aFont;
   587 		COpenFont* f = (COpenFont*)aFont;
   630 		if (f->iHeap)
   588 		if (f->iHeap)
   631 			f->iHeap->Free(aFont);
   589 			f->iHeap->Free(aFont);
   632 		}
   590 		}
   645 
   603 
   646 @return
   604 @return
   647 	ETrue if aGlyphData contains valid data (that is, if aGlyphData->Bitmap()
   605 	ETrue if aGlyphData contains valid data (that is, if aGlyphData->Bitmap()
   648 	and aGlyphData->Metrics() are valid), EFalse otherwise.
   606 	and aGlyphData->Metrics() are valid), EFalse otherwise.
   649 */
   607 */
   650 #ifdef FNTSTORE_SUPPORT_FMM
       
   651 TBool COpenFont::Rasterize(TInt aSessionHandle, TInt aCode,
   608 TBool COpenFont::Rasterize(TInt aSessionHandle, TInt aCode,
   652 	TOpenFontGlyphData* aGlyphData)
   609 	TOpenFontGlyphData* aGlyphData)
   653 	{
   610 	{
   654 	// create the cache if it doesn't exisit. As this call can only come from
   611 	// create the cache if it doesn't exisit. As this call can only come from
   655 	// FBSERV if the chunk has to be resized then no panic will happen.
   612 	// FBSERV if the chunk has to be resized then no panic will happen.
   656 	if (iGlyphCache == NULL)
   613     COpenFontGlyphCache* glyphCache = GetGlyphCache();
   657 		{
   614 	if (glyphCache == NULL)
   658 		iGlyphCache = (COpenFontGlyphCache*)iHeap->Alloc(sizeof(COpenFontGlyphCache));
   615 		{
   659 		if (iGlyphCache == NULL) // no memory
   616         glyphCache = (COpenFontGlyphCache*)iHeap->Alloc(sizeof(COpenFontGlyphCache));
       
   617 		if (glyphCache == NULL) // no memory
   660 			{
   618 			{
   661 			return EFalse;
   619 			return EFalse;
   662 			}
   620 			}
   663 		new(iGlyphCache) COpenFontGlyphCache;
   621 		new(glyphCache) COpenFontGlyphCache;
       
   622 		SetGlyphCache(glyphCache);
   664 		}
   623 		}
   665 
   624 
   666 	// Look in the Font Cache	
   625 	// Look in the Font Cache	
   667 	TInt* nodeInsertPtr = NULL;	
   626 	TInt* nodeInsertPtr = NULL;	
   668 	const COpenFontGlyph* g = FontCacheGlyph(aCode, nodeInsertPtr);		 	
   627 	const COpenFontGlyph* g = FontCacheGlyph(aCode, nodeInsertPtr);		 	
   669 
   628 
   670 	// If it is not found there look in the session cache.
   629 	// If it is not found there look in the session cache.
   671 	COpenFontSessionCache* cache = NULL;
   630 	COpenFontSessionCache* cache = NULL;
   672 	TInt index = 0;
   631 	TInt index = 0;
   673 	if (!g)
   632 	if (g == NULL)
   674 		{
   633 		{
   675 		g = SessionCacheGlyph(iHeap, aSessionHandle, aCode, cache, index, EFalse);
   634 		g = SessionCacheGlyph(iHeap, aSessionHandle, aCode, cache, index, EFalse);
   676 		}
   635 		}
   677 
   636 
   678 	// If it has already been rasterized return it.
   637 	// If it has already been rasterized return it.
   679 	if (g)
   638 	if (g != NULL)
   680 		{
   639 		{
   681 		if (aGlyphData)
   640 		if (aGlyphData != NULL)
   682 			{
   641 			{
   683 			aGlyphData->SetMetricsPointer(&g->iMetrics);
   642 			aGlyphData->SetMetricsPointer(&g->iMetrics);
   684 			aGlyphData->SetBitmapPointer(g->Bitmap());
   643 			aGlyphData->SetBitmapPointer(g->Bitmap());
   685 			}
   644 			}
   686 
   645 
   701 	const TOpenFontGlyphData* cur_glyph_data = temp_glyph_data ? temp_glyph_data : aGlyphData;
   660 	const TOpenFontGlyphData* cur_glyph_data = temp_glyph_data ? temp_glyph_data : aGlyphData;
   702 	const COpenFontGlyph* new_glyph = NULL;
   661 	const COpenFontGlyph* new_glyph = NULL;
   703 
   662 
   704 	// If the maximum per-font cache memory will not be exceeded, put the glyph into the font cache.
   663 	// If the maximum per-font cache memory will not be exceeded, put the glyph into the font cache.
   705 	TInt bytes = sizeof(COpenFontGlyphTreeEntry) + cur_glyph_data->BytesNeeded();	
   664 	TInt bytes = sizeof(COpenFontGlyphTreeEntry) + cur_glyph_data->BytesNeeded();	
   706 	if(iGlyphCache && bytes + iGlyphCache->iGlyphCacheMemory <= KMaxGlyphCacheMemory)
   665 	if(glyphCache != NULL && bytes + glyphCache->iGlyphCacheMemory <= KMaxGlyphCacheMemory)
   707 		{
   666 		{
   708 		COpenFontGlyphTreeEntry* new_entry = COpenFontGlyphTreeEntry::New(iHeap, aCode, cur_glyph_data->GlyphIndex(), *cur_glyph_data->Metrics(), cur_glyph_data->Bitmap());
   667 		COpenFontGlyphTreeEntry* new_entry = COpenFontGlyphTreeEntry::New(iHeap, aCode, cur_glyph_data->GlyphIndex(), *cur_glyph_data->Metrics(), cur_glyph_data->Bitmap());
   709 		new_glyph=new_entry;
   668 		new_glyph=new_entry;
   710 		if(new_entry)
   669 		if (new_entry != NULL)
   711 			{
   670             {
   712 			// Insert new entry into the delete list 
   671             // Add the glyph to a leaf node using the nodeInsertPtr that was returned by FontCacheGlyph()
   713 			error = iGlyphCache->iGlyphArray.Append(*new_entry);
   672             // This is the first node if the glyph cache is empty. This updates the cache atomically.
   714 			if (error == KErrNone)
   673             *nodeInsertPtr = PointerToThisOffset(new_entry);
   715 				{
   674 
   716 				if(!iGlyphCache->iGlyphTreeOffset)
   675             // If new_entry is not the first in the cache, set the previous 
   717 					{
   676             // entry to link to this so that a linked-list of entries can be
   718 					// First entry in tree
   677             // maintained to simplify deletion.
   719 					iGlyphCache->iGlyphTreeOffset = PointerToThisOffset(new_entry);
   678             COpenFontGlyphTreeEntry* tree = static_cast<COpenFontGlyphTreeEntry*> (ThisOffsetToPointer(glyphCache->iGlyphTreeOffset));
   720 					}	
   679             if (new_entry != tree)
   721 				else if (nodeInsertPtr)
   680                 {
   722 					{
   681                 while (tree->iNext != NULL)
   723 					// Add the glyph to a leaf node using the nodeInsertPtr that was returned by FontCacheGlyph()
   682                     {
   724 					*nodeInsertPtr = PointerToThisOffset(new_entry);
   683                     tree = tree->iNext;
   725 					}
   684                     }
   726 				else 
   685                 tree->iNext = new_entry;
   727 					{
   686                 }
   728 					// Failed to add the glyph to the glyph tree, remove it from the delete array.
   687             else
   729 					// (The glyph is deleted below).
   688                 {
   730 					iGlyphCache->iGlyphArray.Remove(iGlyphCache->iGlyphArray.Count()-1);					
   689                 // First entry in tree, initialise iGlyphList
   731 					error = KErrGeneral;
   690                 glyphCache->iGlyphList = new_entry;
   732 					}
   691                 }
   733 				}
   692 
   734 			if (error != KErrNone)
   693             glyphCache->iGlyphCacheMemory += bytes;
   735 				{
   694             }//if (new_entry)
   736 				COpenFontGlyph::Delete(iHeap,new_entry);
       
   737 				}
       
   738 			else
       
   739 				{
       
   740 				iGlyphCache->iGlyphCacheMemory += bytes;
       
   741 				}		
       
   742 			}
       
   743 		}
   695 		}
   744 	else
   696 	else
   745 		{
   697 		{
   746 		error = KErrGeneral;
   698 		error = KErrGeneral;
   747 		}
   699 		}
   748 
   700 
   749 	// Otherwise put the glyph into the per-session cache.
   701 	// Otherwise put the glyph into the per-session cache.
   750 	if (error != KErrNone)
   702 	if (error != KErrNone)
   751 		{
   703 		{
   752 		// If the session cache is not yet known find it or create one.
   704 		// If the session cache is not yet known find it or create one.
   753 		if (!cache)
   705 		if (cache == NULL)
   754 			{
   706 			{
   755 			SessionCacheGlyph(iHeap, aSessionHandle, aCode, cache, index, TRUE);
   707 			SessionCacheGlyph(iHeap, aSessionHandle, aCode, cache, index, TRUE);
   756 			}
   708 			}
   757 		if (!cache)
   709 		if (cache == NULL)
   758 			{			
   710 			{			
   759 			return EFalse;
   711 			return EFalse;
   760 			}
   712 			}
   761 
   713 
   762 		COpenFontSessionCacheEntry* new_entry =
   714 		COpenFontSessionCacheEntry* new_entry =
   763 			COpenFontSessionCacheEntry::New(iHeap, this, aCode, cur_glyph_data->GlyphIndex(), *cur_glyph_data->Metrics(), cur_glyph_data->Bitmap());
   715 			COpenFontSessionCacheEntry::New(iHeap, this, aCode, cur_glyph_data->GlyphIndex(), *cur_glyph_data->Metrics(), cur_glyph_data->Bitmap());
   764 		new_glyph = new_entry;
   716 		new_glyph = new_entry;
   765 		if (new_entry)
   717 		if (new_entry != NULL)
   766 			{
   718 			{
   767 			cache->Insert(iHeap, new_entry, index);
   719 			cache->Insert(iHeap, new_entry, index);
   768 			}
   720 			}
   769 		}
   721 		}
   770 
   722 
   771 	if (temp_glyph_data)
   723 	if (temp_glyph_data != NULL)
   772 		{
   724 		{
   773 		iHeap->Free(temp_glyph_data);
   725 		iHeap->Free(temp_glyph_data);
   774         }
   726         }
   775         
   727         
   776     // Fix up the returned glyph data pointers to point to the actual data.
   728     // Fix up the returned glyph data pointers to point to the actual data.
   777     if (!new_glyph)
   729     if (new_glyph == NULL)
   778         glyph_data_valid = FALSE;
   730         glyph_data_valid = EFalse;
   779     else if (aGlyphData)
   731     else if (aGlyphData != NULL)
   780         {
   732         {
   781         aGlyphData->SetMetricsPointer(&new_glyph->iMetrics);
   733         aGlyphData->SetMetricsPointer(&new_glyph->iMetrics);
   782         aGlyphData->SetBitmapPointer(new_glyph->Bitmap());
   734         aGlyphData->SetBitmapPointer(new_glyph->Bitmap());
   783         }
   735         }
   784 
   736 
   785 	return glyph_data_valid;
   737 	return glyph_data_valid;
   786 	}
   738 	}
   787 #else
       
   788 TBool COpenFont::Rasterize(TInt aSessionHandle, TInt aCode,
       
   789 	TOpenFontGlyphData* aGlyphData)
       
   790 	{
       
   791 	// First look in the font cache.
       
   792 	COpenFontGlyphTreeEntry** node_ptr = NULL;
       
   793 	// create the cache if it doesn't exisit. As this call can only come from
       
   794 	// FBSERV if the chunk has to be resized then no panic will happen.
       
   795 	if (iGlyphCache == NULL)
       
   796 		{
       
   797 		iGlyphCache = (COpenFontGlyphCache*)iHeap->Alloc(sizeof(COpenFontGlyphCache));
       
   798 		if (iGlyphCache == NULL) // no memory
       
   799 			{
       
   800 			return FALSE;
       
   801 			}
       
   802 		new(iGlyphCache) COpenFontGlyphCache;
       
   803 		}
       
   804 	
       
   805 	// Look in the fontcache. Do not expect to find a glyph here. However, 
       
   806 	// it is called again so that a node pointer is found where the new glyph
       
   807 	// will be placed when added to the font cache.
       
   808 	const COpenFontGlyph* glyph = FontCacheGlyph(aCode, node_ptr);
       
   809 	if (glyph)
       
   810 		{
       
   811 		// Do not expect it to get here, since the font cache has already been searched client-side,
       
   812 		// prior to calling Rasterize(). However, just in case it does find a match, use it.
       
   813 		if (aGlyphData)
       
   814 			{
       
   815 			aGlyphData->SetMetricsPointer(&glyph->iMetrics);
       
   816 			aGlyphData->SetBitmapPointer(glyph->iBitmap);
       
   817 			}
       
   818 		return TRUE;
       
   819 		}
       
   820 		
       
   821 	// Rasterize the glyph.
       
   822 	TOpenFontGlyphData* temp_glyph_data = NULL;
       
   823 	TInt error = KErrNone;
       
   824 	TRAP(error, RasterizeHelperL(aCode, aGlyphData, temp_glyph_data));
       
   825 	if (error)
       
   826 		{
       
   827 		iHeap->Free(temp_glyph_data);
       
   828 		return FALSE;
       
   829 		}
       
   830 
       
   831 	TBool glyph_data_valid = TRUE;
       
   832 	const TOpenFontGlyphData* cur_glyph_data = temp_glyph_data ? temp_glyph_data : aGlyphData;
       
   833 	const COpenFontGlyph* new_glyph = NULL;
       
   834 
       
   835 	// If the maximum per-font cache memory will not be exceeded, put the glyph into the font cache.
       
   836 	TInt bytes = sizeof(COpenFontGlyphTreeEntry) + cur_glyph_data->BytesNeeded();
       
   837 	if (iGlyphCache && node_ptr && bytes + iGlyphCache->iGlyphCacheMemory <= KMaxGlyphCacheMemory)
       
   838 		{
       
   839 		COpenFontGlyphTreeEntry* new_entry = COpenFontGlyphTreeEntry::New(iHeap, aCode, cur_glyph_data->GlyphIndex(), *cur_glyph_data->Metrics(), cur_glyph_data->Bitmap());
       
   840 		new_glyph = new_entry;
       
   841 		if (new_entry)
       
   842 			{
       
   843 			*node_ptr = new_entry;	// update the cache atomically
       
   844 
       
   845 			// Insert new entry into the delete list 
       
   846 
       
   847 			COpenFontGlyphTreeEntry* start = iGlyphCache->iGlyphTree;
       
   848 			COpenFontGlyphTreeEntry* tree = start;
       
   849 
       
   850 			if (new_entry != iGlyphCache->iGlyphTree)
       
   851 				{
       
   852 				while (tree->iNext)
       
   853 					{
       
   854 					tree = tree->iNext;
       
   855 					}
       
   856 				tree->iNext = new_entry;
       
   857 				}
       
   858 			else
       
   859 				{
       
   860 				// First entry in tree, initialise iGlyphList
       
   861 				iGlyphCache->iGlyphList = new_entry;
       
   862 				}
       
   863 
       
   864 			iGlyphCache->iGlyphCacheMemory += bytes;
       
   865 			}
       
   866 		}
       
   867 
       
   868 	// Otherwise put the glyph into the per-session cache.
       
   869 	else
       
   870 		{
       
   871 		// If the session cache is not yet known find it or create one.
       
   872 		COpenFontSessionCache* cache = NULL;
       
   873 		TInt index = 0;
       
   874 		SessionCacheGlyph(iHeap, aSessionHandle, aCode, cache, index, TRUE);
       
   875 		if (!cache)
       
   876 			return FALSE;
       
   877 		COpenFontSessionCacheEntry* new_entry =
       
   878 			COpenFontSessionCacheEntry::New(iHeap, this, aCode, cur_glyph_data->GlyphIndex(), *cur_glyph_data->Metrics(), cur_glyph_data->Bitmap());
       
   879 		new_glyph = new_entry;
       
   880 		if (new_entry)
       
   881 			cache->Insert(iHeap, new_entry, index);
       
   882 		}
       
   883 
       
   884 	if (temp_glyph_data)
       
   885 		{
       
   886             iHeap->Free(temp_glyph_data);
       
   887         }
       
   888         
       
   889     // Fix up the returned glyph data pointers to point to the actual data.
       
   890     if (!new_glyph)
       
   891         glyph_data_valid = FALSE;
       
   892     else if (aGlyphData)
       
   893         {
       
   894         aGlyphData->SetMetricsPointer(&new_glyph->iMetrics);
       
   895         aGlyphData->SetBitmapPointer(new_glyph->iBitmap);
       
   896         }
       
   897 
       
   898 	return glyph_data_valid;
       
   899 	}
       
   900 #endif // FNTSTORE_SUPPORT_FMM
       
   901 
   739 
   902 void COpenFont::RasterizeHelperL(TInt aCode, TOpenFontGlyphData* aGlyphData, TOpenFontGlyphData*& aTempGlyphData)
   740 void COpenFont::RasterizeHelperL(TInt aCode, TOpenFontGlyphData* aGlyphData, TOpenFontGlyphData*& aTempGlyphData)
   903 	{
   741 	{
   904 	aTempGlyphData = 0;
   742 	aTempGlyphData = 0;
   905 	MOpenFontShapingExtension* extensionInterface = 0;
   743 	MOpenFontShapingExtension* extensionInterface = 0;
   913 		// get the extension API for RasterizeGlyphL() if available
   751 		// get the extension API for RasterizeGlyphL() if available
   914 		TAny* ext = NULL;
   752 		TAny* ext = NULL;
   915 		ExtendedInterface(KUidOpenFontShapingExtension, ext);
   753 		ExtendedInterface(KUidOpenFontShapingExtension, ext);
   916 		extensionInterface = reinterpret_cast<MOpenFontShapingExtension*>(ext);
   754 		extensionInterface = reinterpret_cast<MOpenFontShapingExtension*>(ext);
   917 
   755 
   918 		if (!extensionInterface)
   756 		if (extensionInterface == NULL)
   919 			// an attempt to rasterize a glyph when the rasterizer does not
   757 			// an attempt to rasterize a glyph when the rasterizer does not
   920 			// support it; best to do nothing
   758 			// support it; best to do nothing
   921 			return;
   759 			return;
   922 		}
   760 		}
   923 	TOpenFontGlyphData* currGlyphData = aGlyphData;
   761 	TOpenFontGlyphData* currGlyphData = aGlyphData;
   924 
   762 
   925 	if (!currGlyphData)
   763 	if (currGlyphData == NULL)
   926 		{
   764 		{
   927 		aTempGlyphData = TOpenFontGlyphData::New(iHeap, 0);
   765 		aTempGlyphData = TOpenFontGlyphData::New(iHeap, 0);
   928 		if (!aTempGlyphData)
   766 		if (!aTempGlyphData)
   929 			User::Leave(KErrNoMemory);
   767 			User::Leave(KErrNoMemory);
   930 		currGlyphData = aTempGlyphData;
   768 		currGlyphData = aTempGlyphData;
   931 		}
   769 		}
   932 
   770 
   933 	if (extensionInterface)
   771 	if (extensionInterface != NULL)
   934 		extensionInterface->RasterizeGlyphL(aCode, currGlyphData);
   772 		extensionInterface->RasterizeGlyphL(aCode, currGlyphData);
   935 	else
   773 	else
   936 		RasterizeL(aCode, currGlyphData);
   774 		RasterizeL(aCode, currGlyphData);
   937 
   775 
   938 	// If the GlyphData object was not large enough, create a temporary one
   776 	// If the GlyphData object was not large enough, create a temporary one
   941 		{
   779 		{
   942 		TInt bytesNeeded = currGlyphData->BytesNeeded();
   780 		TInt bytesNeeded = currGlyphData->BytesNeeded();
   943 		if (aTempGlyphData)
   781 		if (aTempGlyphData)
   944 			iHeap->Free(aTempGlyphData);
   782 			iHeap->Free(aTempGlyphData);
   945 		aTempGlyphData = TOpenFontGlyphData::New(iHeap, bytesNeeded);
   783 		aTempGlyphData = TOpenFontGlyphData::New(iHeap, bytesNeeded);
   946 		if (!aTempGlyphData)
   784 		if (aTempGlyphData == NULL)
   947 			User::Leave(KErrNoMemory);
   785 			User::Leave(KErrNoMemory);
   948 		
   786 		
   949 		currGlyphData = aTempGlyphData;
   787 		currGlyphData = aTempGlyphData;
   950 
   788 
   951 		// If the extension interface was used above, then use again here
   789 		// If the extension interface was used above, then use again here
   952 		if (extensionInterface)
   790 		if (extensionInterface != NULL)
   953 			extensionInterface->RasterizeGlyphL(aCode, currGlyphData);
   791 			extensionInterface->RasterizeGlyphL(aCode, currGlyphData);
   954 		else
   792 		else
   955 			RasterizeL(aCode, currGlyphData);
   793 			RasterizeL(aCode, currGlyphData);
   956 		}
   794 		}
   957 		
   795 		
   991     ExtendedInterface(KUidOpenFontTrueTypeExtension, ext);
   829     ExtendedInterface(KUidOpenFontTrueTypeExtension, ext);
   992     MOpenFontTrueTypeExtension* extensionInterface = 
   830     MOpenFontTrueTypeExtension* extensionInterface = 
   993         reinterpret_cast<MOpenFontTrueTypeExtension*>(ext);
   831         reinterpret_cast<MOpenFontTrueTypeExtension*>(ext);
   994 
   832 
   995     TInt ret = KErrNone;
   833     TInt ret = KErrNone;
   996     if (!extensionInterface)
   834     if (extensionInterface == NULL)
   997         {
   835         {
   998         ret = KErrNotSupported;
   836         ret = KErrNotSupported;
   999         }
   837         }
  1000     else 
   838     else 
  1001         {
   839         {
  1018     ExtendedInterface(KUidOpenFontGlyphOutlineExtension, ext);
   856     ExtendedInterface(KUidOpenFontGlyphOutlineExtension, ext);
  1019     MOpenFontGlyphOutlineExtension *extensionInterface = 
   857     MOpenFontGlyphOutlineExtension *extensionInterface = 
  1020         reinterpret_cast<MOpenFontGlyphOutlineExtension*>(ext);
   858         reinterpret_cast<MOpenFontGlyphOutlineExtension*>(ext);
  1021 
   859 
  1022     TInt ret = KErrNone;
   860     TInt ret = KErrNone;
  1023     if (!extensionInterface)
   861     if (extensionInterface == NULL)
  1024         {
   862         {
  1025         ret = KErrNotSupported;
   863         ret = KErrNotSupported;
  1026         }
   864         }
  1027     else 
   865     else 
  1028         {
   866         {
  1029         ret = extensionInterface->GetGlyphOutline(aCode, ETrue, 
   867         ret = extensionInterface->GetGlyphOutline(aCode, ETrue, 
  1030                 aHinted, aOutline, aLength);
   868                 aHinted, aOutline, aLength);
  1031         }
   869         }
  1032     return ret;
   870     return ret;
  1033     }
   871     }
  1034 #ifdef FNTSTORE_SUPPORT_FMM
   872 
  1035 /** Given the passed pointer aAny, return an offset from it to the "this" pointer
   873 /** Given the passed pointer aAny, return an offset from it to the "this" pointer
  1036 of this COpenFont object.
   874 of this COpenFont object.
  1037 @param aAny A pointer to an object that exists on the shared heap, i.e. the same heap
   875 @param aAny A pointer to an object that exists on the shared heap, i.e. the same heap
  1038 that this CCOpenFont object was created on.
   876 that this CCOpenFont object was created on.
  1039 @return An offset relative to the "this" pointer for this object, this offset can
   877 @return An offset relative to the "this" pointer for this object, this offset can
  1041 @see ThisOffsetToPointer().
   879 @see ThisOffsetToPointer().
  1042 @internalComponent 
   880 @internalComponent 
  1043  */
   881  */
  1044 TInt COpenFont::PointerToThisOffset(const TAny* aAny)
   882 TInt COpenFont::PointerToThisOffset(const TAny* aAny)
  1045 	{
   883 	{
  1046 	if (aAny)
   884 	if (aAny != NULL)
  1047 		{
   885 		{
  1048 		return ((TInt)aAny - (TInt)this);
   886 		return ((TInt)aAny - (TInt)this);
  1049 		}
   887 		}
  1050 	return 0;
   888 	return 0;
  1051 	}
   889 	}
  1063 		{
   901 		{
  1064 		return (TAny*)((TInt)this + aThisOffset);
   902 		return (TAny*)((TInt)this + aThisOffset);
  1065 		}
   903 		}
  1066 	return NULL;
   904 	return NULL;
  1067 	}		
   905 	}		
  1068 #endif // FNTSTORE_SUPPORT_FMM
       
  1069 
   906 
  1070 /**
   907 /**
  1071 A constructor initialised with a TCharacterMetrics object.
   908 A constructor initialised with a TCharacterMetrics object.
  1072 
   909 
  1073 This is the old-style character metrics object. As for other T classes, there 
   910 This is the old-style character metrics object. As for other T classes, there 
  1099 	aMetrics.iAscentInPixels = iHorizBearingY;
   936 	aMetrics.iAscentInPixels = iHorizBearingY;
  1100 	aMetrics.iHeightInPixels = iHeight;
   937 	aMetrics.iHeightInPixels = iHeight;
  1101 	aMetrics.iLeftAdjustInPixels = iHorizBearingX;
   938 	aMetrics.iLeftAdjustInPixels = iHorizBearingX;
  1102 	aMetrics.iMoveInPixels = iHorizAdvance;
   939 	aMetrics.iMoveInPixels = iHorizAdvance;
  1103 	aMetrics.iRightAdjustInPixels = (TInt16)(iHorizAdvance - iHorizBearingX - iWidth);
   940 	aMetrics.iRightAdjustInPixels = (TInt16)(iHorizAdvance - iHorizBearingX - iWidth);
  1104 	return TRUE;
   941 	return ETrue;
  1105 	}
   942 	}
  1106 
   943 
  1107 TBool COpenFont::GetCharacterData(TInt aSessionHandle, TInt aCode, const TOpenFontCharMetrics*& aMetrics, const TUint8*& aBitmap) const
   944 TBool COpenFont::GetCharacterData(TInt aSessionHandle, TInt aCode, const TOpenFontCharMetrics*& aMetrics, const TUint8*& aBitmap) const
  1108 	{
   945 	{
  1109 	const COpenFontGlyph* g = Glyph(aSessionHandle, aCode);
   946 	const COpenFontGlyph* g = Glyph(aSessionHandle, aCode);
  1110 	if (g)
   947 	if (g != NULL)
  1111 		{
   948 		{
  1112 		aMetrics = &g->iMetrics;
   949 		aMetrics = &g->iMetrics;
  1113 #ifdef FNTSTORE_SUPPORT_FMM
       
  1114 		aBitmap = g->Bitmap();
   950 		aBitmap = g->Bitmap();
  1115 #else
   951 		return ETrue;
  1116 		aBitmap = g->iBitmap;
       
  1117 #endif // FNTSTORE_SUPPORT_FMM
       
  1118 		return TRUE;
       
  1119 		}
   952 		}
  1120 	else
   953 	else
  1121 		{
   954 		{
  1122 		aMetrics = NULL;
   955 		aMetrics = NULL;
  1123 		aBitmap = NULL;
   956 		aBitmap = NULL;
  1124 		return FALSE;
   957 		return EFalse;
  1125 		}
   958 		}
  1126 	}
   959 	}
  1127 
   960 
  1128 
   961 
  1129 
   962 
  1130 void COpenFont::OnFileDeleted()
   963 void COpenFont::OnFileDeleted()
  1131 	{
   964 	{
  1132 	iFile = NULL;
   965     iFileOffset = 0;
  1133 	}
   966 	}
  1134 
   967 
  1135 COpenFontGlyphCache* COpenFont::GetGlyphCache()
   968 COpenFontGlyphCache* COpenFont::GetGlyphCache()
  1136 	{
   969 	{
  1137 #ifdef FNTSTORE_SUPPORT_FMM
   970     if (iGlyphCacheOffset == 0)
  1138 	if (iGlyphCache)
   971         {
  1139 		return reinterpret_cast<COpenFontGlyphCache*>(reinterpret_cast<TInt>(iGlyphCache)+Offset());
   972         return NULL;
  1140 #else
   973         }
  1141 	if (iGlyphCache)
   974     return reinterpret_cast<COpenFontGlyphCache*>(PtrAdd(this, iGlyphCacheOffset));
  1142 		return iGlyphCache;
       
  1143 #endif // FNTSTORE_SUPPORT_FMM
       
  1144 	else
       
  1145 		return NULL;
       
  1146 	}
   975 	}
  1147 
   976 
  1148 const COpenFontGlyph* COpenFont::Glyph(TInt aSessionHandle, TInt aCode) const
   977 const COpenFontGlyph* COpenFont::Glyph(TInt aSessionHandle, TInt aCode) const
  1149 	{	
   978 	{	
  1150 #ifdef FNTSTORE_SUPPORT_FMM
       
  1151 	const COpenFontGlyph* glyph = const_cast<COpenFont*>(this)->FontCacheGlyph(aCode);
   979 	const COpenFontGlyph* glyph = const_cast<COpenFont*>(this)->FontCacheGlyph(aCode);
  1152 	if (!glyph)
   980 	if (glyph == NULL)
  1153 		{			
   981 		{			
  1154 		COpenFontSessionCache* cache;
   982 		COpenFontSessionCache* cache;
  1155 		TInt index;
   983 		TInt index;
  1156 		glyph = SessionCacheGlyph(iHeap, aSessionHandle, aCode, cache, index, FALSE);
   984 		glyph = SessionCacheGlyph(iHeap, aSessionHandle, aCode, cache, index, EFalse);
  1157 	}
   985 	}
  1158 
   986 
  1159 	return glyph;
   987 	return glyph;
  1160 #else
       
  1161 	const COpenFontGlyph* g = CONST_CAST(COpenFont*,this)->FontCacheGlyph(aCode);
       
  1162 	if (!g)
       
  1163 		{
       
  1164 		COpenFontSessionCache* cache;
       
  1165 		TInt index;
       
  1166 		g = SessionCacheGlyph(iHeap, aSessionHandle, aCode, cache, index, FALSE);
       
  1167 		}
       
  1168 	return g;
       
  1169 #endif // FNTSTORE_SUPPORT_FMM
       
  1170 	}
   988 	}
  1171 
   989 
  1172 /**
   990 /**
  1173 Is the specified character present in the font?
   991 Is the specified character present in the font?
  1174 */
   992 */
  1175 TBool COpenFont::HasCharacterL(TInt aCode) const
   993 TBool COpenFont::HasCharacterL(TInt aCode) const
  1176 	{
   994 	{
  1177 	COpenFontFile* file = File();
   995 	COpenFontFile* file = File();
  1178 	if (file)
   996 	if (file != NULL)
  1179 		return file->HasUnicodeCharacterL(iFaceIndex, aCode);
   997 		return file->HasUnicodeCharacterL(iFaceIndex, aCode);
  1180 	else
   998 	else
  1181 		return FALSE;
   999 		return EFalse;
  1182 	}
  1000 	}
  1183 
  1001 
  1184 #ifdef FNTSTORE_SUPPORT_FMM
       
  1185 /**
  1002 /**
  1186 Retrieve glyph data from the per-font glyph cache.
  1003 Retrieve glyph data from the per-font glyph cache.
  1187 If it is not found return NULL. 
  1004 If it is not found return NULL. 
  1188 If the cache hasn't been created, then return NULL.
  1005 If the cache hasn't been created, then return NULL.
  1189 Previous versions of this function created the cache, but as this function can potentially
  1006 Previous versions of this function created the cache, but as this function can potentially
  1201 		if (glyphCache->iGlyphTreeOffset)
  1018 		if (glyphCache->iGlyphTreeOffset)
  1202 			{			
  1019 			{			
  1203 			node = static_cast<COpenFontGlyphTreeEntry*>(ThisOffsetToPointer(glyphCache->iGlyphTreeOffset));
  1020 			node = static_cast<COpenFontGlyphTreeEntry*>(ThisOffsetToPointer(glyphCache->iGlyphTreeOffset));
  1204 			}
  1021 			}
  1205 				
  1022 				
  1206 		while (node)
  1023 		while (node != NULL)
  1207 			{
  1024 			{
  1208 			TInt code = node->iCode;
  1025 			TInt code = node->iCode;
  1209 			if(code == aCode)
  1026 			if(code == aCode)
  1210 				{
  1027 				{
  1211 				// Found the glyph
  1028 				// Found the glyph
  1243 	{		
  1060 	{		
  1244 	aNodeInsertPtr = NULL;	
  1061 	aNodeInsertPtr = NULL;	
  1245 
  1062 
  1246 	if (COpenFontGlyphCache* glyphCache = GetGlyphCache())
  1063 	if (COpenFontGlyphCache* glyphCache = GetGlyphCache())
  1247 		{		
  1064 		{		
  1248 		COpenFontGlyphTreeEntry* node = NULL;		
  1065         COpenFontGlyphTreeEntry* node = NULL;
  1249 		if (glyphCache->iGlyphTreeOffset)
  1066         if (glyphCache->iGlyphTreeOffset)
  1250 			{			
  1067             {
  1251 			node = static_cast<COpenFontGlyphTreeEntry*>(ThisOffsetToPointer(glyphCache->iGlyphTreeOffset));
  1068             node = static_cast<COpenFontGlyphTreeEntry*> (ThisOffsetToPointer(glyphCache->iGlyphTreeOffset));
  1252 			}
  1069             }
  1253 				
  1070         else
  1254 		while (node)
  1071             {
       
  1072             aNodeInsertPtr = &glyphCache->iGlyphTreeOffset;
       
  1073             }
       
  1074 
       
  1075         while (node != NULL)
  1255 			{
  1076 			{
  1256 			TInt code = node->iCode;
  1077 			TInt code = node->iCode;
  1257 			if(code == aCode)
  1078 			if(code == aCode)
  1258 				{
  1079 				{
  1259 				// Found the glyph
  1080 				// Found the glyph
  1273 		}
  1094 		}
  1274 
  1095 
  1275 	// No glyph found
  1096 	// No glyph found
  1276 	return NULL;
  1097 	return NULL;
  1277 	}
  1098 	}
  1278 #else
       
  1279 /**
       
  1280 Retrieve glyph data from the per-font glyph cache.
       
  1281 If it is not found return NULL. 
       
  1282 If the cache hasn't been created, then return null.
       
  1283 Previous versions of this function created the cache, but as this function can potentially
       
  1284 run in the context of threads other than FBSERV the alloc could panic if iHeap's chunk had to 
       
  1285 be resized - this is not allowed by the kernel.
       
  1286 The cache is now created in COpenFont::Rasterize which can only be called within the context of FBSERV
       
  1287 */
       
  1288 const COpenFontGlyph* COpenFont::FontCacheGlyph(TInt aCode)
       
  1289 	{
       
  1290 	if (iGlyphCache)
       
  1291 		{					
       
  1292 		COpenFontGlyphTreeEntry* node = iGlyphCache->iGlyphTree;
       
  1293 		while (node)
       
  1294 			{
       
  1295 			if (node->iCode == aCode)
       
  1296 				return node;
       
  1297 			if (node->iCode > aCode)
       
  1298 				node = node->iLeft;
       
  1299 			else
       
  1300 				node = node->iRight;
       
  1301 			}			
       
  1302 		}
       
  1303 	
       
  1304 	return NULL;
       
  1305 	}
       
  1306 
       
  1307 /**
       
  1308 Retrieve glyph data from the per-font glyph cache.
       
  1309 If it is not found return NULL and place the address of the node pointer
       
  1310 to receive a new glyph in aNode. 
       
  1311 If the cache hasn't been created, then return null.
       
  1312 Previous versions of this function created the cache, but as this function can potentially
       
  1313 run in the context of threads other than FBSERV the alloc could panic if iHeap's chunk had to 
       
  1314 be resized - this is not allowed by the kernel.
       
  1315 The cache is now created in COpenFont::Rasterize which can only be called within the context of FBSERV
       
  1316 */
       
  1317 const COpenFontGlyph* COpenFont::FontCacheGlyph(TInt aCode, COpenFontGlyphTreeEntry**& aNode)
       
  1318 	{
       
  1319 	if (!iGlyphCache)
       
  1320 		{
       
  1321 		aNode = NULL;
       
  1322 		return NULL;
       
  1323 		}
       
  1324 
       
  1325 	aNode = &iGlyphCache->iGlyphTree;
       
  1326 	while (*aNode)
       
  1327 		{
       
  1328 		if ((*aNode)->iCode == aCode)
       
  1329 			return *aNode;
       
  1330 		if ((*aNode)->iCode > aCode)
       
  1331 			aNode = &((*aNode)->iLeft);
       
  1332 		else
       
  1333 			aNode = &((*aNode)->iRight);
       
  1334 		}
       
  1335 	
       
  1336 	return NULL;
       
  1337 	}
       
  1338 #endif // FNTSTORE_SUPPORT_FMM
       
  1339 
  1099 
  1340 /** Retrieve glyph data from the session cache. If the glyph is not in the
  1100 /** Retrieve glyph data from the session cache. If the glyph is not in the
  1341 cache, return the cache and glyph index where the glyph data should be put. If
  1101 cache, return the cache and glyph index where the glyph data should be put. If
  1342 there is no session cache, optionally create it.
  1102 there is no session cache, optionally create it.
  1343 
  1103 
  1357 @param aCreate
  1117 @param aCreate
  1358 	If False, creation of a new cache is inhibited
  1118 	If False, creation of a new cache is inhibited
  1359 @return The glyph data, or null if the glyph is not in the cache
  1119 @return The glyph data, or null if the glyph is not in the cache
  1360 @internalComponent
  1120 @internalComponent
  1361 */
  1121 */
  1362 #ifdef FNTSTORE_SUPPORT_FMM
       
  1363 const COpenFontGlyph* COpenFont::SessionCacheGlyph(RHeap* aHeap,
  1122 const COpenFontGlyph* COpenFont::SessionCacheGlyph(RHeap* aHeap,
  1364 	TInt aSessionHandle, TInt aCode, COpenFontSessionCache*& aCache,
  1123 	TInt aSessionHandle, TInt aCode, COpenFontSessionCache*& aCache,
  1365 	TInt& aIndex, TBool aCreate) const
  1124 	TInt& aIndex, TBool aCreate) const
  1366 	{
  1125 	{
  1367 	aIndex = 0;
  1126 	aIndex = 0;
  1374 	    RDebug::Print(_L("COpenFont::SessionCacheGlyphe() can't open SessionCacheSemaphore"));
  1133 	    RDebug::Print(_L("COpenFont::SessionCacheGlyphe() can't open SessionCacheSemaphore"));
  1375 	    return NULL;
  1134 	    return NULL;
  1376 	    }
  1135 	    }
  1377 	sem.Wait();
  1136 	sem.Wait();
  1378 	COpenFontSessionCacheListItem* cacheListStart=cachelist->Start();
  1137 	COpenFontSessionCacheListItem* cacheListStart=cachelist->Start();
  1379 	if(cacheListStart)
  1138 	if(cacheListStart != NULL)
  1380 		{
  1139 		{
  1381 		for (COpenFontSessionCacheListItem* p = cacheListStart; p; p = p->Next())
  1140 		for (COpenFontSessionCacheListItem* p = cacheListStart; p; p = p->Next())
  1382 			{
  1141 			{
  1383 			COpenFontSessionCache* cache=p->Cache();
  1142 			COpenFontSessionCache* cache=p->Cache();
  1384 			if (cache->iSessionHandle == aSessionHandle)
  1143 			if (cache->iSessionHandle == aSessionHandle)
  1397 	if (aCreate)
  1156 	if (aCreate)
  1398 		{
  1157 		{
  1399 		COpenFontSessionCache* new_cache = NULL;
  1158 		COpenFontSessionCache* new_cache = NULL;
  1400 		TRAPD(error, new_cache = COpenFontSessionCache::NewL(aHeap, aSessionHandle, KSessionCacheEntries));
  1159 		TRAPD(error, new_cache = COpenFontSessionCache::NewL(aHeap, aSessionHandle, KSessionCacheEntries));
  1401 		
  1160 		
  1402 		if ((!error) && new_cache)
  1161 		if ((!error) && new_cache != NULL)
  1403 			{
  1162 			{
  1404 			COpenFontSessionCacheListItem* new_item = (COpenFontSessionCacheListItem*)aHeap->Alloc(sizeof(COpenFontSessionCacheListItem));
  1163 			COpenFontSessionCacheListItem* new_item = (COpenFontSessionCacheListItem*)aHeap->Alloc(sizeof(COpenFontSessionCacheListItem));
  1405 			if (!new_item)
  1164 			if (new_item == NULL)
  1406 				{
  1165 				{
  1407 				new_cache->Delete(aHeap);	
  1166 				new_cache->Delete(aHeap);	
  1408 				aHeap->Free(new_cache);
  1167 				aHeap->Free(new_cache);
  1409 				return NULL;
  1168 				return NULL;
  1410 				}
  1169 				}
  1411 
  1170 
  1412 			new(new_item) COpenFontSessionCacheListItem(new_cache);
  1171 			new(new_item) COpenFontSessionCacheListItem(new_cache);
  1413 
  1172 
  1414 			if (prev)
  1173 			if (prev != NULL)
  1415 				{
  1174 				{
  1416 				prev->SetNext(new_item);
  1175 				prev->SetNext(new_item);
  1417 				}
  1176 				}
  1418 			else
  1177 			else
  1419 				{
  1178 				{
  1424 			aIndex = GLYPH_CODE(aCode) % KSessionCacheEntries;
  1183 			aIndex = GLYPH_CODE(aCode) % KSessionCacheEntries;
  1425 			}
  1184 			}
  1426 		}
  1185 		}
  1427 	return NULL;
  1186 	return NULL;
  1428 	}
  1187 	}
  1429 #else
  1188 
  1430 const COpenFontGlyph* COpenFont::SessionCacheGlyph(RHeap* aHeap,
  1189 COpenFontSessionCacheList* COpenFont::SessionCacheList()const
  1431 	TInt aSessionHandle, TInt aCode, COpenFontSessionCache*& aCache,
  1190     {
  1432 	TInt& aIndex, TBool aCreate) const
  1191     if (iSessionCacheListOffset == 0)
  1433 	{
       
  1434 	aCache = NULL;
       
  1435 	aIndex = 0;
       
  1436 	COpenFontSessionCacheListItem* prev = NULL;
       
  1437     RSemaphore sem;
       
  1438     if(KErrNone != sem.OpenGlobal(KSessionCacheSemaphoreName))
       
  1439         {
  1192         {
  1440         RDebug::Print(_L("COpenFont::SessionCacheGlyphe() can't open SessionCacheSemaphore"));
       
  1441         return NULL;
  1193         return NULL;
  1442         }
  1194         }
  1443     sem.Wait();
  1195     return reinterpret_cast<COpenFontSessionCacheList*>(reinterpret_cast<TInt>(this) + iSessionCacheListOffset);
  1444 	for (COpenFontSessionCacheListItem* p = iSessionCacheList->iStart; p; p = p->iNext)
  1196     }
  1445 		{
  1197 
  1446 		if (p->iCache->iSessionHandle == aSessionHandle)
  1198 void COpenFont::SetSessionCacheList(COpenFontSessionCacheList* aSessionCacheList)
  1447 			{
  1199     {
  1448 			aCache = p->iCache;
  1200     iSessionCacheListOffset = aSessionCacheList ? reinterpret_cast<TInt>(aSessionCacheList) - reinterpret_cast<TInt>(this) : NULL;
  1449 		    sem.Signal();
  1201     }
  1450 		    sem.Close();
  1202 
  1451 			return aCache->Glyph(this, aCode, aIndex);
  1203 void COpenFont::SetFile(COpenFontFile* aFile)
  1452 			}
  1204     {
  1453 		prev = p;
  1205     iFileOffset = aFile ? reinterpret_cast<TInt>(aFile) - reinterpret_cast<TInt>(this) : NULL;
  1454 		}
  1206     }
  1455     sem.Signal();
  1207 
  1456 	sem.Close();
  1208 void COpenFont::SetGlyphCache(COpenFontGlyphCache* aGlyphCache)
  1457 	
  1209     {
  1458 	if (aCreate)
  1210     iGlyphCacheOffset = aGlyphCache ? reinterpret_cast<TInt>(aGlyphCache) - reinterpret_cast<TInt>(this) : NULL;
  1459 		{
  1211     }
  1460 		COpenFontSessionCache* new_cache = NULL;
  1212 
  1461 		TRAPD(error, new_cache = COpenFontSessionCache::NewL(aHeap, aSessionHandle, KSessionCacheEntries));
       
  1462 		
       
  1463 		if ((!error) && new_cache)
       
  1464 			{
       
  1465 			COpenFontSessionCacheListItem* new_item = (COpenFontSessionCacheListItem*)aHeap->Alloc(sizeof(COpenFontSessionCacheListItem));
       
  1466 			if (!new_item)
       
  1467 				{
       
  1468 				new_cache->Delete(aHeap);	
       
  1469 				aHeap->Free(new_cache);
       
  1470 				return NULL;
       
  1471 				}
       
  1472 
       
  1473 			new(new_item) COpenFontSessionCacheListItem(new_cache);
       
  1474 
       
  1475 			if (prev)
       
  1476 				prev->iNext = new_item;
       
  1477 			else
       
  1478 				iSessionCacheList->iStart = new_item;
       
  1479 
       
  1480 			aCache = new_cache;
       
  1481 			aIndex = GLYPH_CODE(aCode) % KSessionCacheEntries;
       
  1482 			}
       
  1483 		}
       
  1484 	return NULL;
       
  1485 	}
       
  1486 #endif // FNTSTORE_SUPPORT_FMM
       
  1487 
  1213 
  1488 /**
  1214 /**
  1489 Create a glyph data object on the shared heap, given the code, metrics and the data bytes.
  1215 Create a glyph data object on the shared heap, given the code, metrics and the data bytes.
  1490 The data is copied; ownership remains with the caller.
  1216 The data is copied; ownership remains with the caller.
  1491 */
  1217 */
  1502 	}	
  1228 	}	
  1503 
  1229 
  1504 COpenFontGlyphTreeEntry* COpenFontGlyphTreeEntry::New(RHeap* aHeap, TInt aCode, TInt aGlyphIndex, const TOpenFontCharMetrics& aMetrics, const TDesC8& aBitmap)
  1230 COpenFontGlyphTreeEntry* COpenFontGlyphTreeEntry::New(RHeap* aHeap, TInt aCode, TInt aGlyphIndex, const TOpenFontCharMetrics& aMetrics, const TDesC8& aBitmap)
  1505 	{
  1231 	{
  1506 	COpenFontGlyphTreeEntry* entry = (COpenFontGlyphTreeEntry*)aHeap->Alloc(sizeof(COpenFontGlyphTreeEntry));
  1232 	COpenFontGlyphTreeEntry* entry = (COpenFontGlyphTreeEntry*)aHeap->Alloc(sizeof(COpenFontGlyphTreeEntry));
  1507 	if (!entry)
  1233 	if (entry == NULL)
  1508 		return NULL;
  1234 		return NULL;
  1509 	new(entry) COpenFontGlyphTreeEntry(aCode, aGlyphIndex, aMetrics);
  1235 	new(entry) COpenFontGlyphTreeEntry(aCode, aGlyphIndex, aMetrics);
  1510 	if (!entry->SetBitmap(aHeap, aBitmap))
  1236 	if (!entry->SetBitmap(aHeap, aBitmap))
  1511 		{
  1237 		{
  1512 		aHeap->Free(entry);
  1238 		aHeap->Free(entry);
  1516 	}
  1242 	}
  1517 
  1243 
  1518 COpenFontSessionCacheEntry* COpenFontSessionCacheEntry::New(RHeap* aHeap, const COpenFont* aFont, TInt aCode, TInt aGlyphIndex, const TOpenFontCharMetrics& aMetrics, const TDesC8& aBitmap) 
  1244 COpenFontSessionCacheEntry* COpenFontSessionCacheEntry::New(RHeap* aHeap, const COpenFont* aFont, TInt aCode, TInt aGlyphIndex, const TOpenFontCharMetrics& aMetrics, const TDesC8& aBitmap) 
  1519 	{
  1245 	{
  1520 	COpenFontSessionCacheEntry* entry = (COpenFontSessionCacheEntry*)aHeap->Alloc(sizeof(COpenFontSessionCacheEntry));
  1246 	COpenFontSessionCacheEntry* entry = (COpenFontSessionCacheEntry*)aHeap->Alloc(sizeof(COpenFontSessionCacheEntry));
  1521 	if (!entry)
  1247 	if (entry == NULL)
  1522 		return NULL;
  1248 		return NULL;
  1523 	new(entry) COpenFontSessionCacheEntry(aFont, aCode, aGlyphIndex, aMetrics);
  1249 	new(entry) COpenFontSessionCacheEntry(aFont, aCode, aGlyphIndex, aMetrics);
  1524 	if (!entry->SetBitmap(aHeap, aBitmap))
  1250 	if (!entry->SetBitmap(aHeap, aBitmap))
  1525 		{
  1251 		{
  1526 		aHeap->Free(entry);
  1252 		aHeap->Free(entry);
  1527 		entry = NULL;
  1253 		entry = NULL;
  1528 		}
  1254 		}
  1529 	return entry;
  1255 	return entry;
  1530 	}
  1256 	}
  1531 
       
  1532 #ifdef FNTSTORE_SUPPORT_FMM
       
  1533 
       
  1534 inline COpenFont* COpenFontSessionCacheEntry::Font()const
       
  1535 {
       
  1536 if(iFontOffset)
       
  1537     {
       
  1538     return reinterpret_cast<COpenFont*>(reinterpret_cast<TInt>(this) + iFontOffset);
       
  1539     }
       
  1540 else
       
  1541     return NULL;
       
  1542 }
       
  1543 
  1257 
  1544 /**
  1258 /**
  1545 @return A pointer to the run-length-encoded bitmap stored with this glyph, or NULL
  1259 @return A pointer to the run-length-encoded bitmap stored with this glyph, or NULL
  1546 if no bitmap has been stored with this glyph.
  1260 if no bitmap has been stored with this glyph.
  1547  */
  1261  */
  1548 TUint8* COpenFontGlyph::Bitmap() const
  1262 TUint8* COpenFontGlyph::Bitmap() const
  1549 	{
  1263 	{
  1550 	if (iBitmapOffset)
  1264 	if (iBitmapOffset)
  1551 		{
  1265 		{
  1552 		return (TUint8*)((TInt)this + iBitmapOffset);
  1266 		return reinterpret_cast<TUint8*>(reinterpret_cast<TInt>(this) + iBitmapOffset);
  1553 		}
  1267 		}
  1554 	return NULL;
  1268 	return NULL;
  1555 	}
  1269 	}
  1556 #endif // FNTSTORE_SUPPORT_FMM
       
  1557 
  1270 
  1558 TBool COpenFontGlyph::SetBitmap(RHeap* aHeap, const TDesC8& aBitmap)
  1271 TBool COpenFontGlyph::SetBitmap(RHeap* aHeap, const TDesC8& aBitmap)
  1559 	{
  1272 	{
  1560 	TUint8* bitmap = (TUint8*)aHeap->Alloc(aBitmap.Length());
  1273 	TUint8* bitmap = (TUint8*)aHeap->Alloc(aBitmap.Length());
  1561 	if (!bitmap)
  1274 	if (bitmap == NULL)
  1562 		return FALSE;
  1275 		return EFalse;
  1563 	Mem::Copy(bitmap, aBitmap.Ptr(), aBitmap.Length());	
  1276 	Mem::Copy(bitmap, aBitmap.Ptr(), aBitmap.Length());	
  1564 #ifdef FNTSTORE_SUPPORT_FMM
       
  1565 	aHeap->Free(Bitmap());
  1277 	aHeap->Free(Bitmap());
  1566 	iBitmapOffset = (TInt)bitmap - (TInt)this;
  1278 	iBitmapOffset = reinterpret_cast<TInt>(bitmap) - reinterpret_cast<TInt>(this);
  1567 #else
  1279 	return ETrue;
  1568 	if (iBitmap)
  1280 	}
  1569 		aHeap->Free(iBitmap);
  1281 
  1570 	iBitmap = bitmap;
       
  1571 #endif // FNTSTORE_SUPPORT_FMM
       
  1572 	return TRUE;
       
  1573 	}
       
  1574 #ifdef FNTSTORE_SUPPORT_FMM
       
  1575 COpenFontSessionCache* COpenFontSessionCache::NewL(RHeap* aHeap, TInt aSessionHandle, TInt aEntries)
  1282 COpenFontSessionCache* COpenFontSessionCache::NewL(RHeap* aHeap, TInt aSessionHandle, TInt aEntries)
  1576 	{
  1283 	{
  1577 	COpenFontSessionCache* c = reinterpret_cast<COpenFontSessionCache*>(aHeap->AllocL(sizeof(COpenFontSessionCache)));
       
  1578 	new(c) COpenFontSessionCache(aSessionHandle,aEntries);
       
  1579 	TInt bytes = sizeof(TInt) * aEntries;
       
  1580 	TInt* entry= reinterpret_cast<TInt*>(aHeap->Alloc(bytes));
       
  1581 	Mem::FillZ(entry, bytes);
       
  1582 	if (!entry)
       
  1583 		{
       
  1584 		aHeap->Free(c);
       
  1585 		User::Leave(KErrNoMemory);
       
  1586 		}
       
  1587 	c->iEntryOffset = reinterpret_cast<TInt>(entry) - reinterpret_cast<TInt>(c);
       
  1588 	return c;
       
  1589 	}
       
  1590 #else
       
  1591 COpenFontSessionCache* COpenFontSessionCache::NewL(RHeap* aHeap, TInt aSessionHandle, TInt aEntries)
       
  1592     {
       
  1593     COpenFontSessionCache* c = (COpenFontSessionCache*)aHeap->AllocL(sizeof(COpenFontSessionCache));
  1284     COpenFontSessionCache* c = (COpenFontSessionCache*)aHeap->AllocL(sizeof(COpenFontSessionCache));
  1594     new(c) COpenFontSessionCache(aSessionHandle,aEntries);
  1285     new(c) COpenFontSessionCache(aSessionHandle);
  1595     TInt bytes = sizeof(COpenFontSessionCacheEntry*) * aEntries;
  1286     if (c->iEntryArray.Create(aHeap, aEntries) != KErrNone)
  1596     c->iEntry = (COpenFontSessionCacheEntry**)aHeap->Alloc(bytes);
       
  1597     Mem::FillZ(c->iEntry, bytes);
       
  1598     if (!c->iEntry)
       
  1599         {
  1287         {
  1600         aHeap->Free(c);
  1288         aHeap->Free(c);
  1601         User::Leave(KErrNoMemory);
  1289         User::Leave(KErrNoMemory);
  1602         }
  1290         }
  1603     return c;
  1291     return c;
  1604     }
  1292 	}
  1605 #endif //FNTSTORE_SUPPORT_FMM
  1293 
  1606 
  1294 
  1607 #ifdef FNTSTORE_SUPPORT_FMM
       
  1608 void COpenFontSessionCache::Delete(RHeap* aHeap)
  1295 void COpenFontSessionCache::Delete(RHeap* aHeap)
  1609     {
  1296     {
  1610     TInt* e =Entry();
  1297     TInt entries = iEntryArray.Count();
  1611     if(e)
  1298     for (TInt i = 0; i < entries; ++i)
  1612         {
  1299         {
  1613         for (TInt i = 0; i < iEntries; i++, e++)
  1300         COpenFontSessionCacheEntry* e = iEntryArray[i];
       
  1301         if (e != NULL)
  1614             {
  1302             {
  1615             if (ToCOpenFontSessionCacheEntryPointer(*e))
  1303             COpenFont* font=const_cast<COpenFont*>(e->Font());
       
  1304             if (font != NULL)
       
  1305                 font->DecrementCachedRefCount(iSessionHandle,NULL,ETrue);
       
  1306             aHeap->Free(e->Bitmap());
       
  1307             aHeap->Free(e);
       
  1308             }
       
  1309         }
       
  1310     iEntryArray.Close(aHeap);
       
  1311     }
       
  1312 
       
  1313 const COpenFontGlyph* COpenFontSessionCache::Glyph(const COpenFont* aFont, TInt aCode, TInt& aIndex)
       
  1314 	{
       
  1315     aIndex = -1;
       
  1316     TInt oldest = KMaxTInt;
       
  1317     TInt oldest_index = 0;
       
  1318     TInt entries = iEntryArray.Count();
       
  1319     TInt index = GLYPH_CODE(aCode) % entries;   // simple hash function to shorten searches
       
  1320     for (TInt i = 0; i < entries; ++i, ++index)
       
  1321         {
       
  1322         if (index >= entries)
       
  1323             index = 0;
       
  1324         COpenFontSessionCacheEntry* e = iEntryArray[index];
       
  1325         if (e == NULL)
       
  1326             {
       
  1327             if (aIndex == -1)
       
  1328                 aIndex = index;
       
  1329             }
       
  1330         else
       
  1331             { 
       
  1332             if (e->Font() == aFont && e->iCode == aCode)
  1616                 {
  1333                 {
  1617                 COpenFont* font=const_cast<COpenFont*>((ToCOpenFontSessionCacheEntryPointer(*e))->Font());
  1334                 e->iLastAccess = iLastAccess++;
  1618                 if (font)
  1335                 return e;
  1619                     font->DecrementCachedRefCount(iSessionHandle, NULL, ETrue);
  1336                 }
  1620                 aHeap->Free((ToCOpenFontSessionCacheEntryPointer(*e))->Bitmap());
  1337             if (e->iLastAccess < oldest)
  1621                 aHeap->Free(ToCOpenFontSessionCacheEntryPointer(*e));
  1338                 {
       
  1339                 oldest = e->iLastAccess;
       
  1340                 oldest_index = index;
  1622                 }
  1341                 }
  1623             }
  1342             }
  1624         aHeap->Free(Entry());
       
  1625         iEntryOffset = 0;
       
  1626         }
  1343         }
       
  1344     if (aIndex == -1)
       
  1345         aIndex = oldest_index;
       
  1346     return NULL;
       
  1347 	}
       
  1348 
       
  1349 
       
  1350 void COpenFontSessionCache::Insert(RHeap* aHeap, COpenFontSessionCacheEntry* aEntry, TInt aIndex)
       
  1351 	{
       
  1352     if (aIndex < 0 || aIndex >= iEntryArray.Count())
       
  1353         Panic(EFntSessionCacheIndexOutOfRange);
       
  1354     COpenFontGlyph::Delete(aHeap, iEntryArray[aIndex]);
       
  1355     iEntryArray.SetAt(aIndex, aEntry);
       
  1356     aEntry->iLastAccess = iLastAccess++;
       
  1357 	}
       
  1358 
       
  1359 COpenFontSessionCache::COpenFontSessionCache(TInt aSessionHandle):
       
  1360     iSessionHandle(aSessionHandle),
       
  1361     iLastAccess(0)
       
  1362     {    
  1627     }
  1363     }
  1628 #else
       
  1629 void COpenFontSessionCache::Delete(RHeap* aHeap)
       
  1630 	{
       
  1631 	COpenFontSessionCacheEntry** e =iEntry;
       
  1632 	for (TInt i = 0; i < iEntries; i++, e++)
       
  1633 		{
       
  1634 		if (*e)
       
  1635 			{
       
  1636 			COpenFont* font=const_cast<COpenFont*>((*e)->iFont);
       
  1637 			if (font)
       
  1638 				font->DecrementCachedRefCount(iSessionHandle, NULL, ETrue);
       
  1639 			aHeap->Free((*e)->iBitmap);
       
  1640 			aHeap->Free(*e);
       
  1641 			}
       
  1642 		}
       
  1643 	aHeap->Free(iEntry);
       
  1644 	}
       
  1645 #endif //FNTSTORE_SUPPORT_FMM
       
  1646 
       
  1647 const COpenFontGlyph* COpenFontSessionCache::Glyph(const COpenFont* aFont, TInt aCode, TInt& aIndex)
       
  1648 	{
       
  1649 	aIndex = -1;
       
  1650 	TInt oldest = KMaxTInt;
       
  1651 	TInt oldest_index = 0;
       
  1652 	TInt index = GLYPH_CODE(aCode) % iEntries;	// simple hash function to shorten searches
       
  1653 	for (TInt i = 0; i < iEntries; i++, index++)
       
  1654 		{
       
  1655 		if (index >= iEntries)
       
  1656 			index = 0;		
       
  1657 #ifdef FNTSTORE_SUPPORT_FMM
       
  1658 		COpenFontSessionCacheEntry* e = ToCOpenFontSessionCacheEntryPointer(Entry()[index]);
       
  1659 #else
       
  1660 		COpenFontSessionCacheEntry* e = iEntry[index];
       
  1661 #endif		//FNTSTORE_SUPPORT_FMM		
       
  1662 		if (!e)
       
  1663 			{
       
  1664 			if (aIndex == -1)
       
  1665 				aIndex = index;
       
  1666 			}
       
  1667 		else
       
  1668 			{
       
  1669 #ifdef FNTSTORE_SUPPORT_FMM
       
  1670 			if (e->Font() == aFont && e->iCode == aCode)
       
  1671 #else
       
  1672 			if (e->iFont == aFont && e->iCode == aCode)    
       
  1673 #endif //FNTSTORE_SUPPORT_FMM			    
       
  1674 				{
       
  1675 				e->iLastAccess = iLastAccess++;
       
  1676 				return e;
       
  1677 				}
       
  1678 			if (e->iLastAccess < oldest)
       
  1679 				{
       
  1680 				oldest = e->iLastAccess;
       
  1681 				oldest_index = index;
       
  1682 				}
       
  1683 			}
       
  1684 		}
       
  1685 	if (aIndex == -1)
       
  1686 		aIndex = oldest_index;
       
  1687 	return NULL;
       
  1688 	}
       
  1689 
       
  1690 
       
  1691 void COpenFontSessionCache::Insert(RHeap* aHeap, COpenFontSessionCacheEntry* aEntry, TInt aIndex)
       
  1692 	{
       
  1693 	if ((aIndex < 0) || (aIndex > iEntries))
       
  1694 		Panic(EFntSessionCacheIndexOutOfRange);
       
  1695 #ifdef 	FNTSTORE_SUPPORT_FMM
       
  1696 	COpenFontSessionCacheEntry* e = ToCOpenFontSessionCacheEntryPointer(Entry()[aIndex]);
       
  1697 	COpenFontGlyph::Delete(aHeap, e);
       
  1698 	Entry()[aIndex] = reinterpret_cast<TInt>(aEntry) - reinterpret_cast<TInt>(this);
       
  1699 #else
       
  1700 	COpenFontGlyph::Delete(aHeap, iEntry[aIndex]);
       
  1701 	iEntry[aIndex] = aEntry;
       
  1702 #endif  //FNTSTORE_SUPPORT_FMM	
       
  1703 	aEntry->iLastAccess = iLastAccess++;
       
  1704 	}
       
  1705 
       
  1706 COpenFontSessionCache::COpenFontSessionCache(TInt aSessionHandle, TInt aEntries)
       
  1707  :	iSessionHandle(aSessionHandle),  
       
  1708 	iEntries(aEntries),
       
  1709 	iLastAccess(0),
       
  1710 #ifdef  FNTSTORE_SUPPORT_FMM
       
  1711     iEntryOffset(0)
       
  1712 #else 
       
  1713     iEntry(NULL)
       
  1714 #endif  //FNTSTORE_SUPPORT_FMM  
       
  1715 	{
       
  1716 	}
       
  1717 
       
  1718 #ifdef FNTSTORE_SUPPORT_FMM
       
  1719 
       
  1720 inline TInt* COpenFontSessionCache::Entry() const
       
  1721     {
       
  1722     if (iEntryOffset)
       
  1723         {
       
  1724         return reinterpret_cast<TInt*>(reinterpret_cast<TInt>(this) + iEntryOffset);
       
  1725         }
       
  1726     return NULL;
       
  1727     }
       
  1728 
       
  1729 inline COpenFontSessionCacheEntry* COpenFontSessionCache::ToCOpenFontSessionCacheEntryPointer(TInt aOffset)const
       
  1730     {
       
  1731     if(aOffset)
       
  1732         {
       
  1733         return reinterpret_cast<COpenFontSessionCacheEntry*>(reinterpret_cast<TInt>(this) + aOffset);
       
  1734         }
       
  1735     return NULL;
       
  1736     }
       
  1737 
       
  1738 #endif // FNTSTORE_SUPPORT_FMM
       
  1739 
  1364 
  1740 /*COpenFontSessionCacheListItem*/
  1365 /*COpenFontSessionCacheListItem*/
  1741 #ifdef FNTSTORE_SUPPORT_FMM
       
  1742 COpenFontSessionCacheListItem::COpenFontSessionCacheListItem(COpenFontSessionCache* aCache):
  1366 COpenFontSessionCacheListItem::COpenFontSessionCacheListItem(COpenFontSessionCache* aCache):
  1743 	iNextOffset(NULL)
  1367 	iNextOffset(NULL)
  1744 	{
  1368 	{
  1745 	if(aCache)
  1369     if(aCache != NULL)
  1746 		{
  1370         {
  1747 		iCacheOffset = (TInt)aCache - (TInt)this;
  1371         iCacheOffset = reinterpret_cast<TInt>(aCache) - reinterpret_cast<TInt>(this);
  1748 		}
  1372         }
  1749 	else
  1373     else
  1750 		{
  1374         {
  1751 		iCacheOffset = NULL;
  1375         iCacheOffset = NULL;
  1752 		}
  1376         }
  1753 	}
  1377 	}
  1754 
  1378 
  1755 COpenFontSessionCacheListItem::~COpenFontSessionCacheListItem()
  1379 COpenFontSessionCacheListItem::~COpenFontSessionCacheListItem()
  1756 	{
  1380 	{
  1757 	}
  1381 	}
  1758 #endif // FNTSTORE_SUPPORT_FMM
       
  1759 
  1382 
  1760 /** Delete a COpenFontSessionCacheListItem from the passed heap.
  1383 /** Delete a COpenFontSessionCacheListItem from the passed heap.
  1761 
  1384 
  1762 @param aHeap The heap to delete the COpenFontSessionCacheListItem from.
  1385 @param aHeap The heap to delete the COpenFontSessionCacheListItem from.
  1763  */
  1386  */
  1764 void COpenFontSessionCacheListItem::Delete(RHeap* aHeap)
  1387 void COpenFontSessionCacheListItem::Delete(RHeap* aHeap)
  1765 	{
  1388 	{
  1766 #ifdef FNTSTORE_SUPPORT_FMM
  1389     COpenFontSessionCache* cache = Cache();
  1767 	Cache()->Delete(aHeap);	
  1390     if (cache != NULL)
  1768 	aHeap->Free(Cache());
  1391         {
  1769 	iCacheOffset=NULL;
  1392         cache->Delete(aHeap);   
  1770 	iNextOffset=NULL;
  1393         aHeap->Free(cache);
  1771 #else
  1394         }
  1772 	iCache->Delete(aHeap);	
  1395     iCacheOffset=NULL;
  1773 	aHeap->Free(iCache);
  1396     iNextOffset=NULL;
  1774 	iCache=NULL;
       
  1775 #endif // FNTSTORE_SUPPORT_FMM
       
  1776 	}	
  1397 	}	
  1777 
  1398 
  1778 #ifdef FNTSTORE_SUPPORT_FMM
       
  1779 /** Get the next item to this cache list item.
  1399 /** Get the next item to this cache list item.
  1780 
  1400 
  1781 @return A pointer to the next item to this one in the session cache, or NULL
  1401 @return A pointer to the next item to this one in the session cache, or NULL
  1782 if there is no next item.
  1402 if there is no next item.
  1783  */
  1403  */
  1784 COpenFontSessionCacheListItem* COpenFontSessionCacheListItem::Next()
  1404 COpenFontSessionCacheListItem* COpenFontSessionCacheListItem::Next()
  1785 	{
  1405 	{
  1786 	if(iNextOffset)
  1406 	if(iNextOffset)
  1787 		{
  1407 		{
  1788 		COpenFontSessionCacheListItem* next = (COpenFontSessionCacheListItem*)((TInt)this + (TInt)iNextOffset);
  1408 		COpenFontSessionCacheListItem* next = reinterpret_cast<COpenFontSessionCacheListItem*>(reinterpret_cast<TInt>(this) + iNextOffset);
  1789 		return next;
  1409 		return next;
  1790 		}
  1410 		}
  1791 	else
  1411 	else
  1792 		{
  1412 		{
  1793 		return NULL;
  1413 		return NULL;
  1798 
  1418 
  1799 @param aNext Set this cache list item as the next item to this one in the session cache list.
  1419 @param aNext Set this cache list item as the next item to this one in the session cache list.
  1800  */
  1420  */
  1801 void COpenFontSessionCacheListItem::SetNext(COpenFontSessionCacheListItem* aNext)
  1421 void COpenFontSessionCacheListItem::SetNext(COpenFontSessionCacheListItem* aNext)
  1802 	{
  1422 	{
  1803 	if(aNext)
  1423 	if(aNext != NULL)
  1804 		{
  1424 		{
  1805 		iNextOffset = (TInt)aNext - (TInt)this;
  1425 		iNextOffset = reinterpret_cast<TInt>(aNext) - reinterpret_cast<TInt>(this);
  1806 		}
  1426 		}
  1807 	else
  1427 	else
  1808 		{
  1428 		{
  1809 		iNextOffset = NULL;
  1429 		iNextOffset = NULL;
  1810 		}
  1430 		}
  1816  */
  1436  */
  1817 COpenFontSessionCache* COpenFontSessionCacheListItem::Cache()
  1437 COpenFontSessionCache* COpenFontSessionCacheListItem::Cache()
  1818 	{
  1438 	{
  1819 	if(iCacheOffset)
  1439 	if(iCacheOffset)
  1820 		{
  1440 		{
  1821 		COpenFontSessionCache* cache = (COpenFontSessionCache*)((TInt)this + (TInt)iCacheOffset);
  1441 		COpenFontSessionCache* cache = reinterpret_cast<COpenFontSessionCache*>(reinterpret_cast<TInt>(this) + iCacheOffset);
  1822 		return cache;
  1442 		return cache;
  1823 		}
  1443 		}
  1824 	else
  1444 	else
  1825 		{
  1445 		{
  1826 		return NULL;
  1446 		return NULL;
  1833  */
  1453  */
  1834 COpenFontSessionCacheListItem* COpenFontSessionCacheList::Start()
  1454 COpenFontSessionCacheListItem* COpenFontSessionCacheList::Start()
  1835 	{
  1455 	{
  1836 	if(iStartOffset)
  1456 	if(iStartOffset)
  1837 		{
  1457 		{
  1838 		COpenFontSessionCacheListItem* start = (COpenFontSessionCacheListItem*)((TInt)this + (TInt)iStartOffset);
  1458 		COpenFontSessionCacheListItem* start = reinterpret_cast<COpenFontSessionCacheListItem*>(reinterpret_cast<TInt>(this) + iStartOffset);
  1839 		return start;
  1459 		return start;
  1840 		}
  1460 		}
  1841 	else
  1461 	else
  1842 		{
  1462 		{
  1843 		return NULL;
  1463 		return NULL;
  1849 
  1469 
  1850 @param aItem An item to be added to the session cache
  1470 @param aItem An item to be added to the session cache
  1851  */
  1471  */
  1852 void COpenFontSessionCacheList::SetStart(COpenFontSessionCacheListItem* aItem)
  1472 void COpenFontSessionCacheList::SetStart(COpenFontSessionCacheListItem* aItem)
  1853 	{
  1473 	{
  1854 	if(aItem!=NULL)
  1474 	if(aItem != NULL)
  1855 		{
  1475 		{
  1856 		iStartOffset = (TInt)aItem - (TInt)this;
  1476 		iStartOffset = reinterpret_cast<TInt>(aItem) - reinterpret_cast<TInt>(this);
  1857 		}
  1477 		}
  1858 	else
  1478 	else
  1859 		{
  1479 		{
  1860 		iStartOffset = 0;
  1480 		iStartOffset = 0;
  1861 		}
  1481 		}
  1862 	}
  1482 	}
  1863 #endif // FNTSTORE_SUPPORT_FMM
       
  1864 
  1483 
  1865 /** Delete all the items in the session cache if the current cache session handle
  1484 /** Delete all the items in the session cache if the current cache session handle
  1866 matches the passed session handle.
  1485 matches the passed session handle.
  1867 
  1486 
  1868 @param aHeap The heap base of the current process.
  1487 @param aHeap The heap base of the current process.
  1875 	    if(KErrNone != sem.OpenGlobal(KSessionCacheSemaphoreName))
  1494 	    if(KErrNone != sem.OpenGlobal(KSessionCacheSemaphoreName))
  1876 	        {
  1495 	        {
  1877 	        RDebug::Print(_L("COpenFontSessionCacheList::DeleteCache() can't open SessionCacheSemaphore"));
  1496 	        RDebug::Print(_L("COpenFontSessionCacheList::DeleteCache() can't open SessionCacheSemaphore"));
  1878 	        return;
  1497 	        return;
  1879 	        }	    
  1498 	        }	    
  1880 #ifdef FNTSTORE_SUPPORT_FMM
  1499 	    
  1881  	for (COpenFontSessionCacheListItem* curr = Start(); curr; prev = curr, curr = curr->Next())
  1500 	    for (COpenFontSessionCacheListItem* curr = Start(); curr; prev = curr, curr = curr->Next())
  1882 		{
  1501         {
  1883  		if (curr->Cache()->iSessionHandle == aSessionHandle)
  1502         COpenFontSessionCache* cache = curr->Cache();
  1884    			{
  1503         if (cache != NULL && cache->iSessionHandle == aSessionHandle)
  1885    			for(TInt i=0; i<KSessionCacheSemaphoreCount; i++)
  1504             {
  1886    			    {
  1505             for (TInt i = 0; i < KSessionCacheSemaphoreCount; i++)
  1887 				//coverity[lock]
  1506                 {
  1888 				//coverity[double_lock]
  1507                 //coverity[lock]
  1889    			    sem.Wait();
  1508                 //coverity[double_lock]
  1890    			    }
  1509                 sem.Wait();
  1891  			if (curr==Start())
  1510                 }
  1892  				SetStart(curr->Next());
  1511 
  1893  			else
  1512             if (curr == Start())
  1894  				prev->SetNext(curr->Next());
  1513                 SetStart(curr->Next());
  1895  				
  1514             else
  1896    			curr->Delete(aHeap);
  1515                 prev->SetNext(curr->Next());
  1897  			aHeap->Free(curr);
  1516 
  1898  			sem.Signal(KSessionCacheSemaphoreCount);
  1517             curr->Delete(aHeap);
  1899  			sem.Close();
  1518             aHeap->Free(curr);
  1900    			return;
  1519 
  1901    			}
       
  1902 		}
       
  1903 #else
       
  1904 	for (COpenFontSessionCacheListItem* curr = iStart; curr; prev = curr, curr = curr->iNext)
       
  1905 		{
       
  1906 		if (curr->iCache->iSessionHandle == aSessionHandle)
       
  1907 			{
       
  1908             for(TInt i=0; i<KSessionCacheSemaphoreCount; i++)
       
  1909                {
       
  1910                sem.Wait();
       
  1911                }
       
  1912 			if (curr==iStart)
       
  1913 				iStart   = curr->iNext;
       
  1914 			else
       
  1915 				prev->iNext = curr->iNext;
       
  1916 
       
  1917 			curr->Delete(aHeap);
       
  1918 			aHeap->Free(curr);
       
  1919             sem.Signal(KSessionCacheSemaphoreCount);
  1520             sem.Signal(KSessionCacheSemaphoreCount);
  1920             sem.Close();
  1521             sem.Close();
  1921 			return;
  1522             return;
  1922 			}
  1523             }
  1923 		}
  1524         }
  1924 #endif // FNTSTORE_SUPPORT_FMM
  1525 	    sem.Close();
  1925 	}
  1526 	}
  1926 
  1527 
  1927 /** Delete all the items in the current session cache.
  1528 /** Delete all the items in the current session cache.
  1928 
  1529 
  1929 @param aHeap The heap base of the current process.
  1530 @param aHeap The heap base of the current process.
  1934     if(KErrNone != sem.OpenGlobal(KSessionCacheSemaphoreName))
  1535     if(KErrNone != sem.OpenGlobal(KSessionCacheSemaphoreName))
  1935         {
  1536         {
  1936         RDebug::Print(_L("COpenFontSessionCacheList::Delete() can't open SessionCacheSemaphore"));
  1537         RDebug::Print(_L("COpenFontSessionCacheList::Delete() can't open SessionCacheSemaphore"));
  1937         return;
  1538         return;
  1938         }		
  1539         }		
  1939 #ifdef FNTSTORE_SUPPORT_FMM
       
  1940 	COpenFontSessionCacheListItem* cur = Start();
  1540 	COpenFontSessionCacheListItem* cur = Start();
  1941 #else
       
  1942 	COpenFontSessionCacheListItem* cur = iStart;
       
  1943 #endif // FNTSTORE_SUPPORT_FMM
       
  1944 	COpenFontSessionCacheListItem* next = NULL;
  1541 	COpenFontSessionCacheListItem* next = NULL;
  1945 
  1542 
  1946     for(TInt i=0; i<KSessionCacheSemaphoreCount; i++)
  1543     for(TInt i=0; i<KSessionCacheSemaphoreCount; i++)
  1947      {
  1544      {
  1948 	//coverity[lock]
  1545 	//coverity[lock]
  1949 	//coverity[double_lock]
  1546 	//coverity[double_lock]
  1950      sem.Wait();     
  1547      sem.Wait();     
  1951      }
  1548      }
  1952 	while (cur)
  1549 	while (cur != NULL)
  1953 		{
  1550 		{
  1954 #ifdef FNTSTORE_SUPPORT_FMM
       
  1955 		next = cur->Next();
  1551 		next = cur->Next();
  1956 #else
       
  1957 		next = cur->iNext;
       
  1958 #endif // FNTSTORE_SUPPORT_FMM
       
  1959 		cur->Delete(aHeap);
  1552 		cur->Delete(aHeap);
  1960 		aHeap->Free(cur);
  1553 		aHeap->Free(cur);
  1961 		cur = next;
  1554 		cur = next;
  1962 		}
  1555 		}
  1963     sem.Signal(KSessionCacheSemaphoreCount);
  1556     sem.Signal(KSessionCacheSemaphoreCount);
  1973     if(KErrNone != sem.OpenGlobal(KSessionCacheSemaphoreName))
  1566     if(KErrNone != sem.OpenGlobal(KSessionCacheSemaphoreName))
  1974         {
  1567         {
  1975         RDebug::Print(_L("COpenFontSessionCacheList::DeleteFontGlyphs can't global open SessionCacheSemaphore"));
  1568         RDebug::Print(_L("COpenFontSessionCacheList::DeleteFontGlyphs can't global open SessionCacheSemaphore"));
  1976         return;
  1569         return;
  1977         }
  1570         }
  1978     sem.Wait();     
  1571     sem.Wait();      
  1979 #ifdef FNTSTORE_SUPPORT_FMM     
       
  1980 	for (COpenFontSessionCacheListItem* p = Start(); p; p = p->Next())
  1572 	for (COpenFontSessionCacheListItem* p = Start(); p; p = p->Next())
  1981 		{
  1573         {
  1982 		COpenFontSessionCache* cache=p->Cache();
  1574         COpenFontSessionCache* cache = p->Cache();
  1983 		TInt* e = cache->Entry();
  1575         if (cache != NULL)
  1984 		TInt entries = cache->iEntries;
  1576             {
  1985 		for (TInt i = 0; i < entries; i++, e++)
  1577             TInt entries = cache->iEntryArray.Count();
  1986 			{
  1578             for (TInt i = 0; i < entries; ++i)
  1987 			if ((cache->ToCOpenFontSessionCacheEntryPointer(*e)) 
  1579                 {
  1988 			        && ((cache->ToCOpenFontSessionCacheEntryPointer(*e))->Font() == aFont))
  1580                 COpenFontSessionCacheEntry* e = cache->iEntryArray[i];
  1989 				{
  1581                 if (e != NULL && e->Font() == aFont)
  1990 				COpenFontSessionCacheEntry::Delete(aHeap, cache->ToCOpenFontSessionCacheEntryPointer(*e));
  1582                     {
  1991 				*e = 0;
  1583                     COpenFontSessionCacheEntry::Delete(aHeap, e);
  1992 				}
  1584                     cache->iEntryArray.SetAt(i, NULL);
  1993 			}
  1585                     }
  1994 		}
  1586                 }
  1995 #else
  1587             } //if(cache != NULL)
  1996 	for (COpenFontSessionCacheListItem* p = iStart; p; p = p->iNext)
  1588         }
  1997 		{
       
  1998 		COpenFontSessionCacheEntry** e = p->iCache->iEntry;
       
  1999 		TInt entries = p->iCache->iEntries;
       
  2000 		for (TInt i = 0; i < entries; i++, e++)
       
  2001 			{
       
  2002 			if ((*e) && ((*e)->iFont == aFont))
       
  2003 				{
       
  2004 				COpenFontSessionCacheEntry::Delete(aHeap, *e);
       
  2005 				*e = NULL;
       
  2006 				}
       
  2007 			}
       
  2008 		}
       
  2009 #endif // FNTSTORE_SUPPORT_FMM
       
  2010 	
       
  2011 	sem.Signal();
  1589 	sem.Signal();
  2012 	sem.Close();
  1590 	sem.Close();
  2013 	}
  1591 	}
  2014 
  1592 
  2015 /**
  1593 /**
  2119 and the logic is handled in CFontStore::RemoveFile().
  1697 and the logic is handled in CFontStore::RemoveFile().
  2120 */
  1698 */
  2121 EXPORT_C COpenFontFile::~COpenFontFile()
  1699 EXPORT_C COpenFontFile::~COpenFontFile()
  2122 	{
  1700 	{
  2123     CFontStore *fs = GetFontStore();
  1701     CFontStore *fs = GetFontStore();
  2124     if (fs)
  1702     if (fs != NULL)
  2125         {
  1703         {
  2126         fs->CleanupCacheOnOpenFontFileRemoval(this);
  1704         fs->CleanupCacheOnOpenFontFileRemoval(this);
  2127         }
  1705         }
  2128 	delete iData;
  1706 	delete iData;
  2129 	}
  1707 	}
  2538 	(TOpenFontFaceAttrib&)a = aAttrib;
  2116 	(TOpenFontFaceAttrib&)a = aAttrib;
  2539 	}
  2117 	}
  2540 
  2118 
  2541 void COpenFontFile::SetFontStoreL(CFontStore* aFontStore)
  2119 void COpenFontFile::SetFontStoreL(CFontStore* aFontStore)
  2542 	{
  2120 	{
  2543 	if (!iData)
  2121 	if (iData == NULL)
  2544 		{
  2122 		{
  2545 		iData = new (ELeave) TOpenFontFileData;
  2123 		iData = new (ELeave) TOpenFontFileData;
  2546 		}
  2124 		}
  2547 	iData->iFontStore = aFontStore;
  2125 	iData->iFontStore = aFontStore;
  2548 	}
  2126 	}
  2862 	{
  2440 	{
  2863 	if (aBufferSize < 1)
  2441 	if (aBufferSize < 1)
  2864 		aBufferSize = 1;
  2442 		aBufferSize = 1;
  2865 	TInt bytes = sizeof(TOpenFontGlyphData) + aBufferSize - 1;
  2443 	TInt bytes = sizeof(TOpenFontGlyphData) + aBufferSize - 1;
  2866 	TOpenFontGlyphData* g = (TOpenFontGlyphData*)aHeap->Alloc(bytes);
  2444 	TOpenFontGlyphData* g = (TOpenFontGlyphData*)aHeap->Alloc(bytes);
  2867 	if (g)
  2445 	if (g != NULL)
  2868 		{
  2446 		{
  2869 		Mem::FillZ(g, bytes);
  2447 		Mem::FillZ(g, bytes);
  2870 		g->iBitmapBufferSize = aBufferSize;
  2448 		g->iBitmapBufferSize = aBufferSize;
  2871 		}
  2449 		}
  2872 	return g;
  2450 	return g;