os/graphics/fbs/fontandbitmapserver/sfbs/FBSTOP.CPP
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 1995-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #include <hal.h>
    17 #include <gdi.h>
    18 #include <fntstore.h>
    19 #include <bitmap.h>
    20 #include <ecom/ecom.h>
    21 #include <graphics/bitmapuid.h>
    22 #include "SERVER.H"
    23 #include "BackGroundCompression.h"
    24 #include "BitwiseBitmap.inl"
    25 #include "bitmapconst.h"
    26 #include <graphics/openfontconstants.h>
    27 #include <graphics/openfontrasterizer.h>
    28 #include <graphics/gdi/glyphsample.h>
    29 #include "glyphatlas.h"
    30 #include "FbsMessage.H"
    31 
    32 // Local utility functions
    33 void ListImplementationsWithRetry(TUid& aInterfaceUid, RImplInfoPtrArray &aImplementationArray, TBool aRomOnly);
    34 
    35 
    36 CFbTop::CFbTop():
    37 	iDefaultLanguageForMetrics(ELangNone)
    38 	{
    39 	}
    40 
    41 CFbTop::~CFbTop()
    42 	{
    43 	if (iConIx)
    44 		{
    45 		iConIx->Remove(iBitmapCon);
    46 		iConIx->Remove(iFontCon);
    47 		}
    48 	// there are no bitmap objects left, so the background compression queue must be empty
    49 	delete iBackgroundCompression;
    50 	delete iMBMCache;
    51 	delete iFontStore;
    52 	iFilesys.Close();
    53 	iHeap->Check();
    54 	__RHEAP_MARKEND(iHeap);
    55 	delete iPile;
    56 	iHeap->Close();
    57 	iChunk.Close();
    58 	iLargeBitmapChunk.Close();
    59 	delete iConIx;
    60 #ifdef SYMBIAN_DEBUG_FBS_LOCKHEAP
    61 	iDebugMutex.Close();
    62 #endif
    63 	iFontNameAlias.ResetAndDestroy();
    64 	iBitmapObjectIndex.Reset();
    65 	delete iGlyphAtlas;
    66 	REComSession::FinalClose();
    67 	}
    68 
    69 CFbTop* CFbTop::NewL()
    70 	{
    71 	CFbTop* pT=new(ELeave) CFbTop;
    72 	CleanupStack::PushL(pT);
    73 	pT->ConstructL();
    74 	CleanupStack::Pop();
    75 	return(pT);
    76 	}
    77 
    78 void CFbTop::ConstructL()
    79 	{
    80 	TInt maxmem = 0;
    81 	HAL::Get(HALData::EMemoryRAM, maxmem);
    82 	ASSERT(maxmem > 0);
    83 	TInt maxHeapSize = Min(maxmem, KFbServSharedHeapMaxSize);
    84 	
    85 	TChunkHeapCreateInfo sharedHeapCreateInfo(KFBSERVInitialHeapSize, maxHeapSize);
    86 	sharedHeapCreateInfo.SetCreateChunk(&KFBSERVSharedChunkName);
    87 	sharedHeapCreateInfo.SetSingleThread(EFalse);
    88 	sharedHeapCreateInfo.SetAlignment(0);
    89 	sharedHeapCreateInfo.SetGrowBy(KMinHeapGrowBy * KFBSERVHeapGrowByMultiplier);
    90 
    91 	if(KFbServWritableDataPagingMode == EFbsWdpPageBitmapDataAndSharedHeapChunksOnly)
    92 		{
    93 		//Request that the shared heap chunk is paged.
    94 		sharedHeapCreateInfo.SetPaging(TChunkHeapCreateInfo::EPaged);
    95 		}
    96 	else
    97 		{
    98 		//Use the creating process's paging attributes.
    99 		sharedHeapCreateInfo.SetPaging(TChunkHeapCreateInfo::EUnspecified);
   100 		}
   101 
   102 	iHeap = UserHeap::ChunkHeap(sharedHeapCreateInfo);
   103 	
   104 	User::LeaveIfError(iChunk.OpenGlobal(KFBSERVSharedChunkName,ETrue));
   105 	TInt virtualSize = CChunkPile::VirtualSize();
   106 	
   107 	TChunkCreateInfo createInfo;
   108 	createInfo.SetDisconnected(0, 0, virtualSize);
   109 	createInfo.SetGlobal(KFBSERVLargeChunkName);
   110 	createInfo.SetOwner(EOwnerProcess);
   111 	createInfo.SetClearByte(0xff); // clear to white on creation
   112 
   113 	if(KFbServWritableDataPagingMode == EFbsWdpPageBitmapDataChunkOnly || 
   114 		KFbServWritableDataPagingMode == EFbsWdpPageBitmapDataAndSharedHeapChunksOnly)
   115 		{
   116 		//Request that large bitmap chunk is paged.
   117 		createInfo.SetPaging(TChunkCreateInfo::EPaged);
   118 		}
   119 	else
   120 		{
   121 		//Use the creating process's paging attributes.
   122 		createInfo.SetPaging(TChunkCreateInfo::EUnspecified);
   123 		}
   124 
   125 	User::LeaveIfError(iLargeBitmapChunk.Create(createInfo));
   126 	__RHEAP_MARK(iHeap);
   127 	iConIx=CObjectConIx::NewL();
   128 	iBitmapCon=iConIx->CreateL();
   129 	iFontCon=iConIx->CreateL();
   130 	User::LeaveIfError(iFilesys.Connect());
   131 #ifdef SYMBIAN_DEBUG_FBS_LOCKHEAP
   132 	User::LeaveIfError(iDebugMutex.CreateGlobal(KFBSERVDebugMutexName));
   133 #endif
   134 	iPile = CChunkPile::NewL(iLargeBitmapChunk);
   135 	iFontStore=CFontStore::NewL(iHeap);
   136 	//Constructing a cache to store the stream ids of the bitmaps from a mbm file.
   137 	//The cache here will store maximum 30 bitmaps before  & maximum 30 after the 
   138 	//current loaded bitmap.These values are chosen as to optimize the boottime performance
   139 	//as we notice during the boottime logs,sequential loading of bitmaps never exceed 30 bitmaps.
   140 	// The cache will also store maximum 5 mbm files. This number must be as low as possible
   141 	// while trying to minimize flushing of the cache due to mbm file switching.
   142 	iMBMCache=new (ELeave) CFbTopStreamIdCache(30,30,5);
   143 
   144 	LoadOpenFontLibraries();
   145 	iFontStore->LoadFontsAtStartupL();
   146 	LoadShaperFactories();
   147 	TRAP_IGNORE(iGlyphAtlas = CGlyphAtlas::NewL(KFbServGlyphAtlasCacheLimit);)
   148 #ifdef _DEBUG
   149 	if (!iGlyphAtlas)
   150 	    {
   151         RDebug::Printf("FBSERV failed to initialize Glyph Atlas");
   152 	    }
   153 #endif
   154 
   155 	// start a new thread for background compression after all the other objects have been created
   156 	iBackgroundCompression = CFbsBackgroundCompression::NewL(*this);
   157 	}
   158 
   159 
   160 
   161 
   162 /*
   163 Load all ECOM implemented rasterizer DLLs.
   164 */
   165 
   166 void CFbTop::LoadOpenFontLibraries()
   167 	{
   168 	RImplInfoPtrArray implementationArray;
   169 	TUid uid = {KUidOpenFontRasterizerPlunginInterface};
   170 
   171 	// get implementation list
   172 	ListImplementationsWithRetry(uid, implementationArray, EFalse);
   173 
   174 	const TInt availCount = implementationArray.Count();
   175 	for (TInt count=0; count < availCount; ++count)
   176 		{
   177 		const CImplementationInformation* info = implementationArray[count];
   178 		// Create & install a rasterizer
   179 		// ignore Leaves, as any necessary cleanup will have already been done through the cleanup stack
   180 		TRAP_IGNORE(SafeInstallOfRasterizerL(info->ImplementationUid()));
   181 		}
   182 	
   183 	// free memory
   184 	implementationArray.ResetAndDestroy();
   185 	}
   186 
   187 
   188 /*
   189 Load all ECOM implemented shaper factory DLLs.
   190 */	
   191 void CFbTop::LoadShaperFactories()
   192 	{
   193 	RImplInfoPtrArray implementationArray;
   194 	TUid uid = {KUidShaperFactoryPlunginInterface};
   195 
   196 	// get implementation list
   197 	ListImplementationsWithRetry(uid, implementationArray, ETrue);
   198 
   199 	const TInt availCount = implementationArray.Count();
   200 	for (TInt count=0;count<availCount;++count)
   201 		{
   202 		const CImplementationInformation* info = implementationArray[count];
   203 		// Create & install a shaper factory
   204 		// ignore Leaves, as any necessary cleanup will have already been done through the cleanup stack
   205 		TRAP_IGNORE(SafeInstallOfShaperFactoryL(info->ImplementationUid()));
   206 		}
   207 
   208 	// free memory
   209 	implementationArray.ResetAndDestroy();
   210 	}
   211 
   212 
   213 void ListImplementationsWithRetry(TUid& aInterfaceUid, RImplInfoPtrArray &aImplementationArray, TBool aRomOnly)
   214 	{
   215 	// Making sure that no race situation arises between FBserv and Ecom
   216 	// If ECom is not ready, give it another chance and try again. if it still doesn't work 
   217 	// after the third try, then it just carries on quietly and fails... 
   218 	for (TInt ecomnotready =0; ecomnotready <3; ecomnotready++)
   219 		{
   220 		TInt ecomError = KErrNone;
   221 		if (aRomOnly)
   222 			{
   223 			TEComResolverParams resParams;
   224 			TRAP(ecomError, REComSession::ListImplementationsL(aInterfaceUid, resParams, KRomOnlyResolverUid, aImplementationArray));
   225 			}
   226 		else
   227 			{ // default resolver
   228 			TRAP(ecomError, REComSession::ListImplementationsL(aInterfaceUid, aImplementationArray));
   229 			}
   230 
   231 		if (!ecomError)
   232 			{
   233 			return;
   234 			}
   235 		else
   236 			{
   237 			User::After(0);
   238 			}
   239 		}
   240 	}
   241 
   242 // utility methods to transfer ownership, or destroy object on failure
   243 void CFbTop::SafeInstallOfRasterizerL(TUid aInterfaceImplUid)
   244 	{
   245 	COpenFontRasterizer* rasterizer = COpenFontRasterizer::NewL(aInterfaceImplUid);
   246 	CleanupStack::PushL(rasterizer);
   247 	// Install it in the font store.
   248 	iFontStore->InstallRasterizerL(rasterizer);
   249 	CleanupStack::Pop(rasterizer);
   250 	}
   251 
   252 
   253 void CFbTop::SafeInstallOfShaperFactoryL(TUid aInterfaceImplUid)
   254 	{
   255 	CShaperFactory* shaperFactory = CShaperFactory::NewL(aInterfaceImplUid);
   256 	CleanupStack::PushL(shaperFactory);
   257 	// Install it in the font store.
   258 	iFontStore->InstallShaperFactoryL(shaperFactory);
   259 	CleanupStack::Pop(shaperFactory);
   260 	}
   261 
   262 /**
   263 Gets the nearest matching font for a given font specification. If the named font cannot be found 
   264 font aliases are checked. 
   265 
   266 @param aFontObjPtr On success this contains the font object that is the closest match.
   267 @param aMessage The font request message.
   268 @param aFontSpec The font spec to match.
   269 @param aMaxHeight The maximum height of the font to match.
   270 @return KErrNone if successful, KErrNotFound if the font is not found, or one of the other System Error codes.
   271  */
   272 TInt CFbTop::GetNearestFont(
   273 	CFontObject*&		aFontObjPtr,
   274 	TFbsMessage			aMessage,
   275 	const TFontSpec&	aFontSpec,
   276 	TInt				aMaxHeight)
   277 	{
   278 #ifdef _DEBUG
   279 	User::Heap().Check();
   280 	iHeap->Check();
   281 #endif
   282 	aFontObjPtr = NULL;
   283 
   284 	TFontSpec fontSpec(aFontSpec);
   285 
   286 	// Check if the font typeface is empty and if so use the system default font if it is set
   287 	if (fontSpec.iTypeface.iName.Length() == 0 && iSystemDefaultFontTypefaceName.Length() != 0)
   288 		{
   289 		fontSpec.iTypeface.iName = iSystemDefaultFontTypefaceName;
   290 		}
   291 
   292 	if (GlyphSample::EScriptDefault == fontSpec.ScriptTypeForMetrics())
   293 		{
   294 		fontSpec.SetScriptTypeForMetrics(iDefaultLanguageForMetrics);
   295 		}
   296 
   297 	// Find the requested font
   298 	TBool familyNameExistsInTypefaceStore = iFontStore->HaveTypefaceFamilyName(fontSpec.iTypeface.iName);
   299 	
   300 	// If the font is not found try finding an alias font
   301 	if (!familyNameExistsInTypefaceStore) 
   302 		{
   303 		TInt aliasIndex = FindFontNameAlias(fontSpec.iTypeface.iName);
   304 		//KErrNotFound is the only error which can be returned
   305 		if (aliasIndex != KErrNotFound)
   306 			{
   307 			fontSpec.iTypeface.iName = *iFontNameAlias[aliasIndex + 1];
   308 			}
   309 		}
   310 
   311 	CFont* font = NULL;
   312 	TInt ret = GetNearestNonAliasedFont(font, aMessage, fontSpec, aMaxHeight);
   313 
   314 	if (ret != KErrNone)
   315 		{
   316 		return ret;
   317 		}
   318 	
   319 	return GetFontObjectFromFont(aFontObjPtr, font);
   320 	}
   321 	
   322 /**
   323 Gets the nearest matching loaded font for a given font specification.
   324 
   325 @param aFont On success this contains the font object that is the closest match.
   326 @param aMessage The font request message.
   327 @param aFontSpec The font spec to match.
   328 @param aMaxHeight The maximum height of the font to match.
   329 @return KErrNone if successful, KErrNotFound if the font is not found, or one of the other System Error codes.
   330 */
   331 TInt CFbTop::GetNearestNonAliasedFont(CFont*& aFont, TFbsMessage aMessage, const TFontSpec&	aFontSpec, TInt	aMaxHeight)
   332 	{
   333 	TInt ret = KErrNotSupported;
   334 	switch (aMessage)
   335 		{
   336 		case EFbsMessGetNearestFontToDesignHeightInTwips:
   337 			{
   338 			ret = iFontStore->GetNearestFontToDesignHeightInTwips(aFont, aFontSpec);
   339 			break;
   340 			}
   341 		case EFbsMessGetNearestFontToDesignHeightInPixels:
   342 			{
   343 			ret = iFontStore->GetNearestFontToDesignHeightInPixels(aFont, aFontSpec);
   344 			break;
   345 			}
   346 		case EFbsMessGetNearestFontToMaxHeightInTwips:
   347 			{
   348 			ret = iFontStore->GetNearestFontToMaxHeightInTwips(aFont, aFontSpec, aMaxHeight);
   349 			break;
   350 			}
   351 		case EFbsMessGetNearestFontToMaxHeightInPixels:
   352 			{
   353 			ret = iFontStore->GetNearestFontToMaxHeightInPixels(aFont, aFontSpec, aMaxHeight);
   354 			break;
   355 			}
   356 		}
   357 	return ret;
   358 	}
   359 
   360 TInt CFbTop::GetFontObjectFromFont(CFontObject*& aFontObjPtr, CFont* aFont)
   361 	{
   362 	// First, check if a CFontObject exists for this CFont.
   363 	// If so, increment its reference count and return it.
   364 	for (TInt ii = iFontCon->Count() - 1; ii >= 0; --ii)
   365 		{
   366 		CFontObject* fontObjPtr = reinterpret_cast<CFontObject*>((*iFontCon)[ii]);
   367 		if (fontObjPtr->iAddressPointer == reinterpret_cast<CBitmapFont*>(aFont))
   368 			{
   369 			aFontObjPtr = fontObjPtr;
   370 			// The CFontObject instance keeps the reference count of the CBitmapFont, 
   371 			// not the font store. There is only one CFontObject instance
   372 			// per CBitmapFont, so to keep the reference count at 1 in the fontstore
   373 			// call ReleaseFont(). 
   374 			iFontStore->ReleaseFont(aFont);
   375 			return fontObjPtr->Open();
   376 			}
   377 		}
   378 	
   379 	// Existing FontObject not found, so create new one.
   380 	CFontObject* fontObjPtr = new CFontObject(iFontStore, iGlyphAtlas);
   381 	if (!fontObjPtr)
   382 		{
   383 		iFontStore->ReleaseFont(aFont);
   384 		return KErrNoMemory;
   385 		}
   386 	
   387 	fontObjPtr->iAddressPointer = reinterpret_cast<CBitmapFont*>(aFont);
   388 	fontObjPtr->iHeightInTwips = ((aFont->HeightInPixels() * iFontStore->iKPixelHeightInTwips) + 667) / 1000;
   389 	TRAPD(ret, iFontCon->AddL(fontObjPtr));
   390 	if (ret != KErrNone)
   391 		{
   392 		fontObjPtr->Close();
   393 		}
   394 	else
   395 		{ // transfer ownership
   396 		aFontObjPtr = fontObjPtr;
   397 		}
   398 	return ret;
   399 	}
   400 
   401 
   402 /** Create a Bitmap Font, from a UID and Algorithmic drawing Style see CFontStore::GetFontById()
   403 @internalComponent
   404 */
   405 TInt CFbTop::GetFontById(CFontObject*& aFontObjPtr,TUid aUid,const TAlgStyle& aAlgStyle)
   406 	{
   407 #ifdef _DEBUG
   408 	User::Heap().Check();
   409 	iHeap->Check();
   410 #endif
   411 	aFontObjPtr=NULL;
   412 	CBitmapFont* font=NULL;
   413 	TInt ret=iFontStore->GetFontById((CFont*&)font,aUid,(TAlgStyle&)aAlgStyle);
   414 	if (ret != KErrNone)
   415 		{
   416 		return ret;
   417 		}
   418 	return GetFontObjectFromFont(aFontObjPtr, font);
   419 	}
   420 
   421 
   422 /** Create a bitmap with the given size, display mode and UID.
   423 
   424 @param aSize Size of the bitmap in pixels.
   425 @param aDispMode Display mode of the bitmap.
   426 @param aUid The UID to use for bitmap creation. This can be:
   427 	- KUidCFbsBitmapCreation for standard bitmaps.
   428 	- The application UID for hardware bitmaps.
   429 	- The data type UID for extended bitmaps.
   430 @param aReplacement If ETrue the bitmap is being created as a replacement
   431 	for a bitmap being made dirty by a resize or compress operation.
   432 @param aDataSize If different from zero, it indicates that the bitmap to create
   433 	is an extended bitmap and specifies the size in bytes of the bitmap.
   434 	If equal to zero, it indicates that the bitmap to create is a standard
   435 	bitmap or a hardware bitmap, depending on the value of aUid, and the size
   436 	in bytes is calculated from the size in pixels and the display mode.
   437 @internalComponent
   438 */
   439 CBitmapObject* CFbTop::CreateBitmapL(const TSize& aSize, TDisplayMode aDispMode, TUid aUid, TBool aReplacement, TInt aDataSize)
   440 	{
   441 #ifdef _DEBUG
   442 	User::Heap().Check();
   443 	iHeap->Check();
   444 #endif
   445 	CBitwiseBitmap* bmp=(CBitwiseBitmap*)iHeap->AllocL(sizeof(CBitwiseBitmap) + sizeof(CBitwiseBitmap::TExtra));
   446 	new(bmp) CBitwiseBitmap(iHeap,iPile);
   447 	CleanupDeletePushL(bmp);  // CBitwiseBitmap is not derived from CBase!
   448 
   449 	if (aDataSize == 0)
   450 		User::LeaveIfError(bmp->Construct(aSize, aDispMode, aUid));
   451 	else
   452 		User::LeaveIfError(bmp->ConstructExtended(aSize, aDispMode, aUid, aDataSize));
   453 	// bmp popped out of the clean-up stack by NewL
   454 	CBitmapObject* bmpObj = CBitmapObject::NewL(*this, bmp, aReplacement);
   455 	if (!aReplacement)
   456 		{
   457 		bmp->Extra()->iSerialNumber = iNextAvailableSerialNumber++;
   458 		}
   459 
   460 	return bmpObj;
   461 	}
   462 
   463 CBitmapObject* CFbTop::LoadBitmapL(const TDesC& aFilename, TInt32 aId, TUint aFileOffset, RFile* aFile, TInt aSessionHandle)
   464 	{
   465 	CBitwiseBitmap* bmp=DoLoadBitmapLC(aFilename, aId, aFileOffset, aFile, aSessionHandle);
   466 	// bmp popped out of the clean-up stack by NewL
   467 	CBitmapObject* bmpObj = CBitmapObject::NewL(*this, bmp, EFalse);
   468 
   469 	return bmpObj;
   470 	}
   471 
   472 _LIT(KZDrive, "z:");
   473 
   474 CBitwiseBitmap* CFbTop::DoLoadBitmapLC(const TDesC& aFilename, TInt32 aId, TUint aFileOffset, RFile* aFile, TInt aSessionHandle)
   475 	{
   476 #ifdef _DEBUG
   477 	User::Heap().Check();
   478 	iHeap->Check();
   479 #endif
   480 	CBitwiseBitmap* bmp=(CBitwiseBitmap*)iHeap->AllocL(sizeof(CBitwiseBitmap) + sizeof(CBitwiseBitmap::TExtra));
   481 	new(bmp) CBitwiseBitmap(iHeap,iPile);
   482 	bmp->Extra()->iSerialNumber = iNextAvailableSerialNumber++;
   483 	CleanupDeletePushL(bmp);  // CBitwiseBitmap is not derived from CBase!
   484 
   485 	if (NULL == aFile)
   486 		{
   487 		// In this case file should be in z: drive
   488 		// so load the bitmap from the mbm cache
   489 		TStreamId streamid(0);
   490 		streamid=iMBMCache->GetStreamIdL(iFilesys,aFilename,aId,aFileOffset,aSessionHandle);
   491 		bmp->ConstructL(iMBMCache->MruFileStore(),streamid);
   492 		}
   493 	else
   494 		{
   495 		//only use the cache when it is Rom File which is read only because when using
   496 		//the cache the file store is always opened as read access until it is replaced by
   497 		//another different file, Trying to write it(RAM file) will cause access violation
   498 		//and therefore we have to split the implementation into two parts one for ROM
   499 		//and one for RAM
   500 		if (aFilename.Left(2).CompareF(KZDrive))
   501 			{
   502 			// File is not in ROFS
   503 			bmp->ConstructL(*aFile,aId,aFileOffset);
   504 			}
   505 		else
   506 			{
   507 			// File is in ROFS
   508 			TStreamId streamid(0);
   509 			streamid=iMBMCache->GetStreamIdL(*aFile,aFilename,aId,aFileOffset,aSessionHandle);
   510 
   511 			bmp->ConstructL(iMBMCache->MruFileStore(),streamid);
   512 			}
   513 		}
   514 	return bmp;
   515 	}
   516 
   517 
   518 /* Similar to LoadBitmap.
   519 This function only performs a load the first time it is called for a
   520 particular bitmap.  Subsequent calls increment a reference counting object.
   521 
   522 Upon return, aBmpObjPtr points to an object containing a pointer to the loaded bitmap.
   523 */
   524 CSharedBitmapObject* CFbTop::ShareBitmapL(TDes& aFilename, TInt32 aId, TUint aFileOffset, RFile* aFile, TInt aSessionHandle)
   525 	{
   526 	TTime modtime(0);
   527 	if (aFilename.Left(2).CompareF(KZDrive))// instead of Compare, CompareF is used to perform folding prior to Compare which is safe with Unicode.
   528 		{
   529 		// file is not in z: drive so it should not be null.
   530 		__ASSERT_DEBUG(aFile != NULL, User::Panic(KFBSERVPanicCategory, KErrBadHandle));
   531 		// File is not in ROM so ModTime is needed to identify it
   532 		User::LeaveIfError(aFile->Modified(modtime));
   533 		}
   534 
   535 	// Creation of the key is performed here so that it can potentially be
   536 	// reused in both object lookup and object creation
   537 	HBufC* key = CSharedBitmapObject::KeyLC(aFilename, aId, modtime);
   538 
   539 	// Calculation of the hash value is performed here so that it can 
   540 	// potentially be reused in both object lookup and object insert.
   541 	const TUint hash = iSharedBitmapObjectHashMap.Hash(*key);    
   542 
   543 	CSharedBitmapObject* bmpObj = iSharedBitmapObjectHashMap.Lookup(*key, hash);
   544 	
   545 	if (bmpObj)
   546 		{
   547 		// Bitmap already in memory
   548 		CleanupStack::PopAndDestroy(key);      // key will not be needed
   549 		User::LeaveIfError(bmpObj->Open());    // increase reference count
   550 		}
   551 	else
   552 		{
   553 		// Bitmap not in memory
   554 		CBitwiseBitmap* bmp = DoLoadBitmapLC(aFilename, aId, aFileOffset, aFile, aSessionHandle);
   555 		// bmp and key popped out of the clean-up stack by NewL
   556 		bmpObj = CSharedBitmapObject::NewL(*this, bmp, key, hash);
   557 		}
   558 
   559 	return bmpObj;
   560 	}
   561 
   562 TInt CFbTop::GetCleanBitmap(CBitmapObject*& aBmpObjPtr)
   563 	{
   564 	while (aBmpObjPtr->CleanBitmap() != NULL)
   565 		{
   566 		aBmpObjPtr = aBmpObjPtr->CleanBitmap();
   567 		}
   568 	if (aBmpObjPtr->IsInCompressionQueue())
   569 		return KErrInUse;
   570 	return KErrNone;
   571 	}
   572 
   573 CBitmapObject* CFbTop::FindBitmap(TInt aHandle)
   574 	{
   575 	TInt index = iBitmapObjectIndex.FindInOrder(aHandle, CBitmapObject::Compare);
   576 	if (index != KErrNotFound)
   577 		return iBitmapObjectIndex[index];
   578 	return NULL;
   579 	}
   580 
   581 TBool CFbTop::ValidFontHandle(TInt aHandle)
   582 	{
   583 	TInt limit=iFontCon->Count();
   584 	for(TInt count=0;count<limit;count++)
   585 		if(aHandle==(TInt)((*iFontCon)[count]))
   586 			return(ETrue);
   587 	return(EFalse);
   588 	}
   589 	
   590 CFontStore* CFbTop::FontStore() const
   591 	{
   592 	return(iFontStore);
   593 	}
   594 
   595 RHeap* CFbTop::Heap() const
   596 	{
   597 	return(iHeap);
   598 	}
   599 
   600 CChunkPile* CFbTop::Pile() const
   601 	{
   602 	return(iPile);
   603 	}
   604 
   605 TInt CFbTop::HeapBase() const
   606 	{
   607 	return(TInt(iChunk.Base()));
   608 	}
   609 
   610 void CFbTop::SetFontNameAliasL(const RMessage2& aMessage)
   611 	{
   612 	const TInt aliasNameLength = aMessage.Int1();
   613 	if (aliasNameLength <= 0)
   614 		return; // No alias name to set
   615 	
   616 	if(aliasNameLength * sizeof(TText) * 2 >= KMaxTInt)
   617 		{
   618 		aMessage.Panic(KFBSERVPanicCategory,KErrArgument);
   619 		return;
   620 		}
   621 		
   622 	HBufC* aliasName = HBufC::NewMaxLC(aliasNameLength);
   623 	TPtr aliasNamePtr(aliasName->Des());
   624 	aMessage.ReadL(0,aliasNamePtr);
   625 
   626 	const TInt aliasIndex = FindFontNameAlias(*aliasName);
   627 
   628 	const TInt fontNameLength = aMessage.Int3();
   629 
   630 	if (fontNameLength > 0)
   631 		{ // Set or change an alias
   632 		HBufC* fontName = HBufC::NewMaxLC(fontNameLength);
   633 		TPtr fontNamePtr(fontName->Des());
   634 		aMessage.ReadL(2,fontNamePtr);
   635 
   636 		if (aliasIndex != KErrNotFound)
   637 			{ // Change an existing alias
   638 			delete iFontNameAlias[aliasIndex + 1];
   639 			iFontNameAlias[aliasIndex + 1] = fontName;
   640 
   641 			CleanupStack::Pop(); // fontName
   642 			CleanupStack::PopAndDestroy(); // aliasName
   643 			}
   644 		else
   645 			{ // Set a new alias
   646 			User::LeaveIfError(iFontNameAlias.Append(aliasName));
   647 			TInt ret = iFontNameAlias.Append(fontName);
   648 			if (ret != KErrNone)
   649 				{
   650 				iFontNameAlias.Remove(iFontNameAlias.Count() - 1);
   651 				User::Leave(ret);
   652 				}
   653 
   654 			CleanupStack::Pop(); // fontName
   655 			CleanupStack::Pop(); // aliasName
   656 			}
   657 		}
   658 	else
   659 		{ // No fontName so delete the alias
   660 		CleanupStack::PopAndDestroy(); // aliasName
   661 		if (aliasIndex != KErrNotFound)
   662 			{
   663 			delete iFontNameAlias[aliasIndex];
   664 			iFontNameAlias.Remove(aliasIndex);
   665 			delete iFontNameAlias[aliasIndex];
   666 			iFontNameAlias.Remove(aliasIndex);
   667 			}
   668 		}
   669 	}
   670 
   671 TInt CFbTop::FindFontNameAlias(const TDesC& aAlias)
   672 	{
   673 	const TInt fontNameAliasCount = iFontNameAlias.Count();
   674 
   675 	for (TInt index = 0; index < fontNameAliasCount; index += 2)
   676 		{
   677 		if ((*iFontNameAlias[index]).CompareF(aAlias)==0)
   678 			{
   679 			return index;
   680 			}
   681 		}
   682 
   683 	return KErrNotFound;
   684 	}
   685 
   686 void CFbTop::SetDefaultLanguageForMetrics(const RMessage2& aMessage)
   687 	{
   688 	iDefaultLanguageForMetrics = static_cast<TLanguage>(aMessage.Int0());
   689 	}
   690 
   691 void CFbTop::CloseFileStores(TInt aSessionHandle)
   692 	{
   693 	iMBMCache->CloseFileStores(aSessionHandle);
   694 	}
   695 
   696 void CFbTop::SetSystemDefaultTypefaceName(const TDesC& aFontTypefaceName)
   697 	{
   698 	iSystemDefaultFontTypefaceName = aFontTypefaceName;
   699 	}
   700 
   701 TInt CFbTop::GetAllBitmapHandles(const RMessage2& aMessage) const
   702 	{
   703 	TPckgBuf<TInt> handleBuffer; // Use this buffer to store the bitmap handles to write to the message buffer
   704 	const TInt numBitmaps = iBitmapObjectIndex.Count();
   705 	TInt ret = KErrNone;
   706 	for (TInt count=0; count<numBitmaps; ++count)
   707 		{
   708 		handleBuffer() = iBitmapObjectIndex[count]->Handle();
   709 		ret = aMessage.Write(0, handleBuffer, KNumBytesPerBitmapHandle * count);
   710 		if (ret!=KErrNone)
   711 			break;
   712 		}	
   713 	return ret;
   714 	}
   715 
   716 void CFbTop::AddClientHelper(TFbClientHelper& aHelper)
   717 	{
   718 	iClientHelpers.AddLast(aHelper);
   719 	}
   720 
   721 void CFbTop::NotifyDirtyBitmap(CBitmapObject& aBmpObj, CFbClient* aClient)
   722 	{
   723 	TDblQueIter<TFbClientHelper> iterator(iClientHelpers);
   724 	TFbClientHelper* helper;
   725 	while ((helper = iterator++) != NULL)
   726 		{
   727 		if (aClient != &helper->iClient)
   728 			helper->iClient.NotifyDirtyBitmap(aBmpObj);
   729 		}
   730 	}
   731 
   732 TInt CFbTop::BitmapConUniqueID() const
   733 	{
   734 	return iBitmapCon->UniqueID();
   735 	}
   736 
   737 TInt CFbTop::FontConUniqueID() const
   738 	{
   739 	return iFontCon->UniqueID();
   740 	}
   741 
   742 CGlyphAtlas* CFbTop::GlyphAtlas() const
   743 	{
   744 	return iGlyphAtlas;
   745 	}