os/graphics/fbs/fontandbitmapserver/sfbs/SERVER.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 <fntstore.h>
    17 #include <bitmap.h>
    18 #include "FBSVER.H"
    19 #include "SERVER.H"
    20 #include "BackGroundCompression.h"
    21 #include "linkedfonts.h"
    22 #include "BitwiseBitmap.inl"
    23 
    24 const TInt KFbsPriority = 0;
    25 const TInt KFbsGoomMonitorSid = 0x10207218;
    26 // Setup security policies
    27 const TInt KRanges[] = 
    28 	{
    29 	0,
    30 	EFbsMessShutdown,
    31 	EFbsMessClose,
    32 	EFbsSetSystemDefaultTypefaceName,
    33 	EFbsGetAllBitmapHandles,
    34 	EFbsMessUnused1,
    35 	EFbsMessUnused2,
    36 	EFbsMessRegisterLinkedTypeface,
    37 	EFbsMessFetchLinkedTypeface,
    38 	EFbsMessUpdateLinkedTypeface,
    39 	EFbsMessGetFontTable,
    40     EFbsMessOogmNotification,
    41     EFbsMessGetGlyphCacheMetrics,
    42 	};
    43 
    44 const TUint KRangeCount = sizeof(KRanges)/sizeof(TInt);
    45 const TUint8 KElementsIndex[KRangeCount] = 
    46 	{
    47 	0,
    48 	3, // For EFbsMessShutdown
    49 	0,
    50 	1, // For EFbsSetSystemDefaultTypefaceName
    51 	2, // For EFbsGetAllBitmapHandles
    52 	0, // ECapability_None for EFbsMessUnused1
    53 	0, // ECapability_None for EFbsMessUnused2 and beyond
    54 	1, // ECapabilityWriteDeviceData for EFbsMessRegisterLinkedTypeface
    55 	2, // ECapabilityReadDeviceData for EFbsMessFetchLinkedTypeface
    56 	1, // ECapabilityWriteDeviceData for EFbsMessUpdateLinkedTypeface
    57 	0, // ECapability_None for EFbsMessGetFontTable and beyond
    58     4, // SID for EFbsMessOogmNotification.
    59     0, // For EFbsMessGetGlyphCacheMetrics and on.
    60 	};
    61 
    62 const CPolicyServer::TPolicyElement KElements[] = 
    63 	{
    64 	{_INIT_SECURITY_POLICY_C1(ECapability_None), CPolicyServer::EFailClient},
    65 	{_INIT_SECURITY_POLICY_C1(ECapabilityWriteDeviceData), CPolicyServer::EFailClient},
    66 	{_INIT_SECURITY_POLICY_C1(ECapabilityReadDeviceData), CPolicyServer::EFailClient},
    67 	{_INIT_SECURITY_POLICY_C1(ECapabilityPowerMgmt), CPolicyServer::EFailClient},
    68 	{_INIT_SECURITY_POLICY_S0(KFbsGoomMonitorSid), CPolicyServer::EFailClient}
    69  	};
    70 
    71 const CPolicyServer::TPolicy KFbsPolicy =
    72 	{
    73 	CPolicyServer::EAlwaysPass, //specifies all connect attempts should pass
    74 	KRangeCount,
    75 	KRanges,
    76 	KElementsIndex,
    77 	KElements,
    78 	};
    79 
    80 CFontBitmapServer::CFontBitmapServer():
    81 	CPolicyServer(KFbsPriority, KFbsPolicy)
    82 	{
    83 	}
    84 
    85 CFontBitmapServer::~CFontBitmapServer()
    86 	{
    87 	delete iTopLevelStore;
    88 	iTopLevelStore = NULL;	// so that CFBClient::~CFbClient can avoid using this pointer;
    89 							// it may be called inside CFontBitmapServer::~CFontBitmapServer
    90 	}
    91 
    92 CFontBitmapServer* CFontBitmapServer::NewL()
    93 	{
    94 	CFontBitmapServer* self = new(ELeave) CFontBitmapServer;
    95 	CleanupStack::PushL(self);
    96 	self->ConstructL();
    97 	CleanupStack::Pop(); //self
    98 	return self;
    99 	}
   100 
   101 /**
   102 Two-phase constructor.
   103 */
   104 void CFontBitmapServer::ConstructL()
   105 	{
   106 	iTopLevelStore=CFbTop::NewL();
   107 	
   108 	// If fbserv data paging is configured as unpaged, automatically pin client descriptors 
   109 	if(!RProcess().DefaultDataPaged())
   110 		{
   111 		SetPinClientDescriptors(ETrue);
   112 		}
   113 	StartL(KFBSERVGlobalThreadName);
   114 	}
   115 
   116 CFbTop* CFontBitmapServer::TopLevelStore()
   117 	{
   118 	return(iTopLevelStore);
   119 	}
   120 
   121 CSession2* CFontBitmapServer::NewSessionL(const TVersion& aVersion,const RMessage2& /*aMessage*/ ) const
   122 	{
   123 	TVersion v(KFbsMajorVersionNumber,KFbsMinorVersionNumber,KFbsBuildVersionNumber);
   124 	if(!User::QueryVersionSupported(v,aVersion))
   125 		User::Leave(KErrNotSupported);
   126 
   127 	CSession2* pSession2 = CFbClient::NewL(iTopLevelStore->Heap());
   128 	return pSession2;
   129 	}
   130 
   131 TInt CFontBitmapServer::Init()
   132 	{
   133 	return(iConnectionId++);
   134 	}
   135 
   136 
   137 TInt CFontBitmapServer::HandleMesgTypefaceSupport(const RMessage2& aMessage, TBool& aClientPanicRequired)
   138 	{
   139 	TTypefaceSupport tfi;
   140 	TPckgBuf<TTypefaceSupport> ttipckg(tfi);
   141 	TPckgBuf<TSize> pixelSize;
   142 	TInt index=aMessage.Int0();
   143 	TInt limit=iTopLevelStore->FontStore()->NumTypefaces();
   144 	if(index < 0 || index > limit)
   145 		{
   146 		return KErrArgument;
   147 		}
   148 	TInt ret = aMessage.Read(2, pixelSize);
   149 	if (ret != KErrNone)
   150 		{
   151 		return ret;
   152 		}
   153 	iTopLevelStore->FontStore()->iKPixelHeightInTwips = pixelSize().iHeight;
   154 	iTopLevelStore->FontStore()->iKPixelWidthInTwips = pixelSize().iWidth;
   155 	iTopLevelStore->FontStore()->TypefaceSupport(ttipckg(),index);
   156 	ret = aMessage.Write(1,ttipckg);
   157 	if(ret!=KErrNone)
   158 		{
   159 		aClientPanicRequired = ETrue;
   160 		}
   161 	return ret;
   162 	}
   163 
   164 
   165 TInt CFontBitmapServer::HandleMesgFontHeight(const RMessage2& aMessage, TBool aInTwips)
   166 	{
   167 	TInt typefaceindex = aMessage.Int0();
   168 	TInt fontsize = aMessage.Int1();
   169 
   170 	if(typefaceindex < 0)
   171 		{
   172 		aMessage.Panic(KFBSERVPanicCategory,KErrArgument);
   173 		return KErrArgument;
   174 		}
   175 	
   176 	// pixel size (used to be set in a separate call)
   177 	TPckgBuf<TSize> size;
   178 	TInt ret = aMessage.Read(2, size);
   179 	if (ret != KErrNone)
   180 		{
   181 		return ret;
   182 		}
   183 		
   184 	if(size().iHeight <=  0 || size().iWidth < 0)
   185 		{
   186 		aMessage.Panic(KFBSERVPanicCategory,KErrArgument);
   187 		return KErrArgument;
   188 		}
   189 			
   190 	iTopLevelStore->FontStore()->iKPixelHeightInTwips = size().iHeight;
   191 	iTopLevelStore->FontStore()->iKPixelWidthInTwips = size().iWidth;
   192 	if (aInTwips)
   193 		{
   194 		return iTopLevelStore->FontStore()->FontHeightInTwips(typefaceindex,fontsize);
   195 		}
   196 	else
   197 		{
   198 		return iTopLevelStore->FontStore()->FontHeightInPixels(typefaceindex,fontsize);
   199 		}
   200 	}
   201 
   202 
   203 #ifdef _DEBUG
   204 //aRet is used in debug builds to allow the server to know if the call was successful.
   205 //On success there should be no panics from out of memory testing, since memory
   206 //may have been genuinely allocated.
   207 void CFontBitmapServer::ProcMessage(const RMessage2& aMessage, TInt aSession, TInt& aRet)
   208 #else
   209 void CFontBitmapServer::ProcMessage(const RMessage2& aMessage, TInt aSession)
   210 #endif
   211 	{
   212     TInt ret=KErrNone;
   213 	TBool clientPanicRequired = EFalse;
   214 #ifdef _DEBUG
   215 	TInt num=0;
   216 #endif
   217 	switch (aMessage.Function())
   218 		{
   219 	case EFbsMessShutdown:
   220 		CActiveScheduler::Stop();
   221 		break;
   222 	case EFbsMessNumTypefaces:
   223 		ret=iTopLevelStore->FontStore()->NumTypefaces();
   224 		break;
   225 	case EFbsMessTypefaceSupport:
   226 		ret = HandleMesgTypefaceSupport(aMessage, clientPanicRequired);
   227 		break;
   228 
   229 	case EFbsMessFontHeightInTwips:
   230 		ret = HandleMesgFontHeight(aMessage, ETrue);
   231 		break;
   232 
   233 	case EFbsMessFontHeightInPixels:
   234 		ret = HandleMesgFontHeight(aMessage, EFalse);
   235 		break;
   236 
   237 	case EFbsMessSetPixelHeight:
   238 		iTopLevelStore->FontStore()->iKPixelWidthInTwips=aMessage.Int0();
   239 		iTopLevelStore->FontStore()->iKPixelHeightInTwips=aMessage.Int1();
   240 		break;
   241 #ifdef _DEBUG
   242 	case EFbsMessDefaultAllocFail:
   243 		num=aMessage.Int0();
   244 		if(num) __UHEAP_FAILNEXT(num);
   245 		else __UHEAP_RESET;
   246 		break;
   247 	case EFbsMessDefaultMark:
   248 		__UHEAP_MARK;
   249 		break;
   250 	case EFbsMessDefaultMarkEnd:
   251 		num=aMessage.Int0();
   252 		if(num) __UHEAP_MARKENDC(num);
   253 		else __UHEAP_MARKEND;
   254 		break;
   255 	case EFbsMessUserAllocFail:
   256 		num=aMessage.Int0();
   257 		if(num) __RHEAP_FAILNEXT(iTopLevelStore->Heap(),num);
   258 		else __RHEAP_RESET(iTopLevelStore->Heap());
   259 		break;
   260 	case EFbsMessUserMark:
   261 		__RHEAP_MARK(iTopLevelStore->Heap());
   262 		break;
   263 	case EFbsMessUserMarkEnd:
   264 		num=aMessage.Int0();
   265 		if(num) __RHEAP_MARKENDC(iTopLevelStore->Heap(),num);
   266 		else __RHEAP_MARKEND(iTopLevelStore->Heap());
   267 		break;
   268 #endif
   269 	case EFbsMessHeapCheck:
   270 		iTopLevelStore->Heap()->Check();
   271 		User::Heap().Check();
   272 		break;
   273 	case EFbsMessSetDefaultGlyphBitmapType:
   274 		iTopLevelStore->FontStore()->SetDefaultBitmapType((TGlyphBitmapType)aMessage.Int0());
   275 		break;
   276 	case EFbsMessGetDefaultGlyphBitmapType:
   277 		ret = iTopLevelStore->FontStore()->DefaultBitmapType();
   278 		break;
   279 	case EFbsMessFontNameAlias:
   280 		TRAP(ret, iTopLevelStore->SetFontNameAliasL(aMessage));
   281 		break;
   282 	case EFbsMessGetHeapSizes:
   283 		TRAP(ret, GetHeapSizesL(aMessage));
   284 		break;
   285 	case EFbsMessDefaultLanguageForMetrics:
   286 		iTopLevelStore->SetDefaultLanguageForMetrics(aMessage);
   287 		break;
   288 	case EFbsCompress:
   289 		iTopLevelStore->BackgroundCompression()->CompressAll();
   290 		break;
   291 	case EFbsMessRegisterLinkedTypeface:
   292 		{
   293 		TPckgBuf<TLinkedTypefaceSpecificationArgs> buf;
   294 		ret=aMessage.Read(0,buf);
   295 		if (ret==KErrNone)
   296 			{
   297 			//Id used by original font linking; now unused.
   298 			TInt id;
   299 			ret=iTopLevelStore->FontStore()->CreateLinkedTypeface(buf(),aSession,id);
   300 			}
   301 		}
   302 		break;
   303 	case EFbsMessFetchLinkedTypeface:
   304 			{
   305 			TBuf<KMaxTypefaceNameLength> name;
   306 			ret = aMessage.GetDesLength(0);
   307 				
   308 			if (ret < 0) 
   309 				break;
   310 				
   311 			if (ret > KMaxTypefaceNameLength)
   312 				{
   313 				clientPanicRequired = ETrue;
   314 				ret = KErrTooBig;
   315 				break;
   316 				}
   317 				
   318 			ret = aMessage.Read(0,name);
   319 	
   320 			TLinkedTypefaceSpecificationArgs spec;
   321 				
   322 			spec.iName = name;
   323 				
   324 			if (ret==KErrNone)
   325 				{
   326 				TRAP(ret, iTopLevelStore->FontStore()->GetLinkedTypefaceL(spec));
   327 	
   328 				if (ret == KErrNone)
   329 					{
   330 					TPckgBuf<TLinkedTypefaceSpecificationArgs> specArgs = spec;					
   331 					ret = aMessage.Write(2,specArgs);
   332 					}
   333 				}
   334 			}
   335 		break;
   336 		case EFbsMessUpdateLinkedTypeface:
   337 			{
   338 			TPckgBuf<TLinkedTypefaceSpecificationArgs> buf;
   339 			ret=aMessage.Read(0,buf);
   340 			if (ret==KErrNone)
   341 				{
   342 				TRAP(ret, iTopLevelStore->FontStore()->UpdateLinkedTypefaceL(buf()));
   343 				}
   344 			}
   345 		break;
   346 	}
   347 
   348 	if (clientPanicRequired)
   349 		{
   350 		aMessage.Panic(KFBSERVPanicCategory,ret);
   351 		}
   352 	else
   353 		{
   354 		if(!aMessage.IsNull())
   355 			{
   356 			aMessage.Complete(ret);
   357 			}		
   358 		}
   359 
   360 #ifdef _DEBUG
   361 	aRet=ret;
   362 #endif	
   363 
   364 	}
   365 
   366 /**
   367 Returns the current sizes of the FBServ default heap, the heap for large bitmaps, 
   368 and the heap for small bitmaps.
   369 
   370 Not supported in release builds.
   371 
   372 @internalComponent
   373 @test
   374 @param aMessage Encapsulates references to integers supplied by the caller, which will on return contain the sizes of the default heap, heap for small bitmaps, and heap for large bitmaps.
   375 @leave KErrNotSupported when used in release mode.
   376 */
   377 #ifdef _DEBUG
   378 void CFontBitmapServer::GetHeapSizesL(const RMessage2& aMessage)
   379 	{
   380 	TPckgBuf<THeapSizes> data;
   381 	TInt defaultHeapSize = 0;
   382 	TInt smallBmpHeapSize = 0;		
   383 	TInt bigBmpHeapSize = 0;		
   384 	
   385 	User::Heap().AllocSize(defaultHeapSize);
   386 	bigBmpHeapSize = iTopLevelStore->iLargeBitmapChunk.Size();
   387 	iTopLevelStore->Heap()->AllocSize(smallBmpHeapSize);
   388 	
   389 	data().iDefault = defaultHeapSize;
   390 	data().iBig = bigBmpHeapSize;
   391 	data().iSmall = smallBmpHeapSize;
   392 	
   393 	aMessage.WriteL(0, data);
   394 	}
   395 #else
   396 void CFontBitmapServer::GetHeapSizesL(const RMessage2&)
   397 	{
   398 	User::Leave(KErrNotSupported);	
   399 	}	
   400 #endif
   401 
   402 
   403 CFontObject::CFontObject(CFontStore* aFontStore, CGlyphAtlas* aGlyphAtlas):
   404 	CObject(),
   405 	iFontStore(aFontStore),
   406 	iGlyphAtlas(aGlyphAtlas)
   407 	{
   408 	}
   409 
   410 CFontObject::~CFontObject()
   411 	{
   412 	if (AccessCount()==1)
   413 		{
   414 		Dec();
   415 		}
   416 	iFontStore->ReleaseFont(iAddressPointer);
   417 	if (iGlyphAtlas)
   418 		{
   419 		iGlyphAtlas->FontReleased(*iAddressPointer);
   420 		}
   421 	}
   422 
   423 // CBitmapObject constructor - takes ownership of aBmp
   424 CBitmapObject::CBitmapObject(CFbTop& aFbTop, CBitwiseBitmap* aBmp):
   425 	CObject(),
   426 	iFbTop(&aFbTop),
   427 	iAddressPointer(aBmp)
   428 	{
   429 	__ASSERT_DEBUG(iAddressPointer, User::Invariant());
   430 	}
   431 
   432 /** Second-phase constructor of reference counting objects for bitmaps.
   433 Adds the CBitmapObject to the bitmap object container and, if it is not a
   434 replacement for a dirty bitmap, assigns a server-wide handle to it and adds
   435 it to the server's bitmap index. When a replacement bitmap is attached to
   436 the corresponding dirty bitmap with a call to SetCleanBitmap(), then it is
   437 assigned the same server-wide handle as the bitmap to be replaced.
   438 
   439 @param aReplacement If ETrue the bitmap is being created as a replacement
   440 	for a bitmap being made dirty by a resize or compress operation.
   441 @internalComponent
   442 */
   443 void CBitmapObject::ConstructL(TBool aReplacement)
   444 	{
   445 	iFbTop->iBitmapCon->AddL(this);
   446 	if (!aReplacement)
   447 		{
   448 		iHandle = reinterpret_cast<TInt>(this);
   449 		while (iFbTop->iBitmapObjectIndex.FindInOrder(this, Compare) != KErrNotFound)
   450 			{
   451 			++iHandle;
   452 			}
   453 		User::LeaveIfError(iFbTop->iBitmapObjectIndex.InsertInOrder(this, Compare));
   454 		}
   455 	}
   456 
   457 void CleanupBitmapObject(TAny* aPtr)
   458 	{
   459 	CBitmapObject* ptr = static_cast<CBitmapObject*>(aPtr);	
   460 	ptr->Close();
   461 	}
   462 
   463 /** Create a reference counting object for a new bitmap.
   464 
   465 @param aFbTop Reference to the CFbTop singleton.
   466 @param aBmp Bitmap to be attached to the new reference counting object.
   467 	The bitmap must have been pushed on the clean-up stack and it will be
   468 	popped out of the stack by this function. Ownership will be transferred
   469 	to the reference counting object.
   470 @param aReplacement If ETrue the bitmap is being created as a replacement
   471 	for a bitmap being made dirty by a resize or compress operation.
   472 @internalComponent
   473 */
   474 CBitmapObject* CBitmapObject::NewL(CFbTop& aFbTop, CBitwiseBitmap* aBmp, TBool aReplacement)
   475 	{
   476 	CBitmapObject* bmpObj = new(ELeave) CBitmapObject(aFbTop, aBmp);
   477 	CleanupStack::Pop(aBmp); // aBmp is owned now by bmpObj
   478 	TCleanupItem bitmapObjectCleanupItem(CleanupBitmapObject, bmpObj);
   479 	CleanupStack::PushL(bitmapObjectCleanupItem);
   480 	bmpObj->ConstructL(aReplacement);
   481 	CleanupStack::Pop(bmpObj);
   482 	return bmpObj;
   483 	}
   484 
   485 CBitmapObject::~CBitmapObject()
   486 	{
   487 	iFbTop->BackgroundCompression()->RemoveFromCompressionQueue(this);
   488 	// the associated clean bitmap object cannot possibly be now in the background compression queue
   489 	if (iHandle)
   490 		{
   491 		if (Owner() == NULL)
   492 			{
   493 			TInt index = iFbTop->iBitmapObjectIndex.FindInOrder(this, Compare);
   494 			if (index != KErrNotFound)
   495 				{
   496 				if (iCleanBitmap)
   497 					{
   498 					iFbTop->iBitmapObjectIndex[index] = iCleanBitmap;
   499 					}
   500 				else
   501 					{
   502 					iFbTop->iBitmapObjectIndex.Remove(index);
   503 					}
   504 				}
   505 			}
   506 		if (iCleanBitmap != NULL)
   507 			{
   508 			iCleanBitmap->SetOwner(NULL);
   509 			iCleanBitmap->Close();
   510 			}
   511 		}
   512 	delete iAddressPointer;
   513 	}
   514 
   515 void CBitmapObject::SetCleanBitmap(CBitmapObject* aNewBmpObj)
   516 	{
   517 	__ASSERT_DEBUG(iHandle, User::Invariant());
   518 	__ASSERT_DEBUG(iCleanBitmap == NULL, User::Invariant());
   519 	__ASSERT_DEBUG(aNewBmpObj->Owner() == NULL, User::Invariant());
   520 	__ASSERT_DEBUG(aNewBmpObj->iHandle == 0, User::Invariant());
   521 	__ASSERT_DEBUG(aNewBmpObj->iCleanBitmap == NULL, User::Invariant());
   522 	iCleanBitmap = aNewBmpObj;
   523 	aNewBmpObj->SetOwner(this);
   524 	aNewBmpObj->iHandle = iHandle;
   525 	iAddressPointer->iSettings.SetDirtyBitmap();
   526 	aNewBmpObj->iAddressPointer->Extra()->iSerialNumber = iAddressPointer->Extra()->iSerialNumber;
   527 	aNewBmpObj->iAddressPointer->Extra()->iTouchCount = iAddressPointer->Extra()->iTouchCount + 1;
   528 	}
   529 
   530 void CBitmapObject::Close()
   531 	{
   532 	if ((iCleanBitmap != NULL) && (Owner() != NULL) && (AccessCount() == 2))
   533 		{
   534 		static_cast<CBitmapObject*>(Owner())->iCleanBitmap = iCleanBitmap;
   535 		iCleanBitmap->SetOwner(Owner());
   536 		iHandle = 0;
   537 		Dec();
   538 		}
   539 	CObject::Close();
   540 	}
   541 
   542 TInt CBitmapObject::Compare(const CBitmapObject& aBmpObj1, const CBitmapObject& aBmpObj2)
   543 	{
   544 	return aBmpObj1.iHandle - aBmpObj2.iHandle;
   545 	}
   546 
   547 TInt CBitmapObject::Compare(const TInt* aHandle, const CBitmapObject& aBmpObj)
   548 	{
   549 	return *aHandle - aBmpObj.iHandle;
   550 	}
   551 
   552 // CSharedBitmapObject constructor - takes ownership of aBmp and aKey
   553 CSharedBitmapObject::CSharedBitmapObject(CFbTop& aFbTop, CBitwiseBitmap* aBmp, TDesC* aKey):
   554 	CBitmapObject(aFbTop, aBmp),
   555 	iKey(aKey)
   556 	{
   557 	__ASSERT_DEBUG(iKey, User::Invariant());	
   558 	}
   559 
   560 /** Second-phase constructor of reference counting objects for bitmaps
   561 loaded to share from a file. Adds the CSharedBitmapObject to the bitmap
   562 object container, assigns a server-wide handle to it and adds it to the
   563 server's bitmap index and to the server's shared bitmap hash map.
   564 
   565 @param aHash Hash value of the key associated with the bitmap.
   566 @internalComponent
   567 */
   568 void CSharedBitmapObject::ConstructL(TUint aHash)
   569 	{
   570 	CBitmapObject::ConstructL(EFalse);
   571 	iFbTop->iSharedBitmapObjectHashMap.Insert(*this, aHash);
   572 	}
   573 
   574 /** Create a reference counting object for a bitmap loaded to share from a file.
   575 
   576 @param aFbTop Reference to the CFbTop singleton.
   577 @param aBmp Bitmap to be attached to the new reference counting object.
   578 	The bitmap must have been pushed on the clean-up stack and it will be
   579 	popped out of the stack by this function. Ownership will be transferred
   580 	to the reference counting object.
   581 @param aKey Key associated with the bitmap. The key must have been pushed on
   582 	the clean-up stack and it will be popped out of the stack by this function.
   583 	Ownership will be transferred to the reference counting object.
   584 @param aHash Hash value of the key associated with the bitmap.
   585 @internalComponent
   586 */
   587 CSharedBitmapObject* CSharedBitmapObject::NewL(CFbTop& aFbTop, CBitwiseBitmap* aBmp, TDesC* aKey, TUint aHash)
   588 	{
   589 	CSharedBitmapObject* bmpObj = new(ELeave) CSharedBitmapObject(aFbTop, aBmp, aKey);
   590 	CleanupStack::Pop(2, aKey); // aBmp and aKey are owned now by bmpObj
   591 	TCleanupItem bitmapObjectCleanupItem(CleanupBitmapObject, bmpObj);
   592 	CleanupStack::PushL(bitmapObjectCleanupItem);
   593 	bmpObj->ConstructL(aHash);
   594 	CleanupStack::Pop(bmpObj);
   595 	return bmpObj;
   596 	}
   597 
   598 CSharedBitmapObject::~CSharedBitmapObject()
   599 	{
   600 	iFbTop->iSharedBitmapObjectHashMap.Remove(*this);
   601 	delete iKey;
   602 	}
   603 
   604 // Constructs a single key object from constituent parts that uniquely identify a bitmap
   605 HBufC* CSharedBitmapObject::KeyLC(const TDesC& aFileName, TInt aId, const TTime& aModTime)
   606 	{
   607 	static const TInt K16BitSizeOfTInt  = sizeof(TInt) /sizeof(TUint16);
   608 	static const TInt K16BitSizeOfTTime = sizeof(TTime)/sizeof(TUint16);
   609 	
   610 	HBufC* key = HBufC::NewLC(K16BitSizeOfTInt + K16BitSizeOfTTime + aFileName.Length());
   611 	
   612 	TPtr keyPtr = key->Des();
   613 	
   614 	keyPtr.Append(reinterpret_cast<const TUint16*>(&aId),      K16BitSizeOfTInt);
   615 	keyPtr.Append(reinterpret_cast<const TUint16*>(&aModTime), K16BitSizeOfTTime);
   616 	keyPtr.Append(aFileName);
   617 
   618 	return key;
   619 	}