fbs/fontandbitmapserver/sfbs/FBSCLI.CPP
changeset 187 9f66f99ee56f
parent 103 2717213c588a
child 160 969102054596
equal deleted inserted replaced
103:2717213c588a 187:9f66f99ee56f
    14 //
    14 //
    15 
    15 
    16 #include <fntstore.h>
    16 #include <fntstore.h>
    17 #include <bitmap.h>
    17 #include <bitmap.h>
    18 #include <openfont.h>
    18 #include <openfont.h>
       
    19 #include <graphics/fbsoogmmessage.h>
    19 #include "FbsMessage.H"
    20 #include "FbsMessage.H"
    20 #include "SERVER.H"
    21 #include "SERVER.H"
    21 #include "BackGroundCompression.h"
    22 #include "BackGroundCompression.h"
    22 #include <shapeinfo.h>
    23 #include <shapeinfo.h>
    23 #include <graphics/shaperparams.h>
    24 #include <graphics/shaperparams.h>
       
    25 #include "glyphatlas.h"
       
    26 
       
    27 
       
    28 /**
       
    29 Bitwise mask that sets the MSB to indicate to a font rasterizer
       
    30 that a code is a glyphcode and not a character code
       
    31 */
       
    32 const TUint32 KTreatAsGlyphCodeFlag = 1UL << 31;
    24 
    33 
    25 /** Helper function for converting a pointer to an offset from the passed
    34 /** Helper function for converting a pointer to an offset from the passed
    26 heap base. Use OffsetToPointer() to convert the returned offset back to a
    35 heap base. Use OffsetToPointer() to convert the returned offset back to a
    27 useable pointer.
    36 useable pointer.
    28 @param aAny A pointer to be converted to an offset.
    37 @param aAny A pointer to be converted to an offset.
    31 back to a pointer using the function OffsetToPointer(). 
    40 back to a pointer using the function OffsetToPointer(). 
    32 @see OffsetToPointer()
    41 @see OffsetToPointer()
    33  */
    42  */
    34 LOCAL_C TInt PointerToOffset(const TAny* aAny, TInt aHeapBase)
    43 LOCAL_C TInt PointerToOffset(const TAny* aAny, TInt aHeapBase)
    35 	{
    44 	{
       
    45 	TInt offset = 0;
    36 	if (aAny && aHeapBase)
    46 	if (aAny && aHeapBase)
    37 		{
    47 		{
    38 		return reinterpret_cast<TInt>(aAny) - aHeapBase;
    48 		offset = reinterpret_cast<TInt>(aAny) - aHeapBase;
    39 		}
    49 		}
    40 	return 0;
    50 	return offset;
    41 	}
    51 	}
    42 
    52 
    43 /** Helper function for converting an offset (that was calculated using
    53 /** Helper function for converting an offset (that was calculated using
    44 PointerToOffset()) back to a pointer relative to the passed heap base.
    54 PointerToOffset()) back to a pointer relative to the passed heap base.
    45 @param aOffset The offset to be converted to a pointer.
    55 @param aOffset The offset to be converted to a pointer.
    56 	return NULL;
    66 	return NULL;
    57 	}
    67 	}
    58 
    68 
    59 CFbClient::CFbClient(RHeap* aHeap):
    69 CFbClient::CFbClient(RHeap* aHeap):
    60 	CSession2(),
    70 	CSession2(),
    61 	iConnectionHandle(0),
       
    62 	iIx(NULL),
       
    63 	iResourceCount(0),
       
    64 	iHeap(aHeap)
    71 	iHeap(aHeap)
    65 #ifdef _DEBUG
    72 #ifdef _DEBUG
    66 	,iOwnHeapFailNumber(-1),
    73 	,iOwnHeapFailNumber(-1),
    67 	iSharedHeapFailNumber(-1)
    74 	iSharedHeapFailNumber(-1)
    68 #endif	
    75 #endif	
    69 	{
    76 	{
    70 	}
    77 	}
    71 
    78 
    72 CFbClient* CFbClient::NewL(RHeap* aHeap)
    79 CFbClient* CFbClient::NewL(RHeap* aHeap)
    73 	{
    80 	{
    74 	CFbClient* c = new(ELeave) CFbClient(aHeap);
    81 	CFbClient* self = new (ELeave) CFbClient(aHeap);
    75 	c->iOpenFontGlyphData = TOpenFontGlyphData::New(aHeap,4 * 1024);
    82 	CleanupStack::PushL(self);
    76 	if (!c->iOpenFontGlyphData)
    83 	self->ConstructL();
    77 		{
    84 	CleanupStack::Pop(); // self;
    78 		delete c;
    85 	return self;
       
    86 	}
       
    87 
       
    88 /**
       
    89 Two-phase constructor.
       
    90 @leave KErrNoMemory if TOpenFontGlyphData construction failed.
       
    91 */
       
    92 void CFbClient::ConstructL()
       
    93 	{
       
    94 	iOpenFontGlyphData = TOpenFontGlyphData::New(iHeap, 4 * 1024);
       
    95 	if (!iOpenFontGlyphData)
       
    96 		{
    79 		User::Leave(KErrNoMemory);
    97 		User::Leave(KErrNoMemory);
    80 		}
    98 		}
    81 	return c;
       
    82 	}
    99 	}
    83 
   100 
    84 CFbClient::~CFbClient()
   101 CFbClient::~CFbClient()
    85 	{
   102 	{
    86 	/*
   103 	/*
   101 		
   118 		
   102 		// If the font store doesn't exist, neither will the shared heap owned by FBSERV.
   119 		// If the font store doesn't exist, neither will the shared heap owned by FBSERV.
   103 		iHeap->Free(iOpenFontGlyphData);
   120 		iHeap->Free(iOpenFontGlyphData);
   104 		}
   121 		}
   105 	
   122 	
   106 	// delete fonts hold by the client
   123 	// delete fonts held by the client
   107 	delete iIx;
   124 	delete iIx;
   108 	
   125 	
   109 	// delete font files hold by the client
   126 	// delete font files held by the client
   110 	if (iFontFileIndex)
   127 	if (iFontFileIndex)
   111 		{
   128 		{
   112 		TInt count = iFontFileIndex->Count();
   129 		TInt count = iFontFileIndex->Count();
   113 		for (TInt index = 0;index < count; index++)
   130 		for (TInt index = 0;index < count; index++)
   114 			{
   131 			{
   115 			if (font_store)
   132 			if (font_store)
       
   133 				{
   116 				font_store->RemoveFile(iFontFileIndex->At(0).iUid);
   134 				font_store->RemoveFile(iFontFileIndex->At(0).iUid);
       
   135 				}
   117 			iFontFileIndex->Delete(0);
   136 			iFontFileIndex->Delete(0);
   118 			}
   137 			}
   119 		delete iFontFileIndex;
   138 		delete iFontFileIndex;
   120 		}
   139 		}
   121 
   140 
   122 	// Close the buffer used to hold the text thats needs shaping.
   141 	// Close the buffer used to hold the text that needs shaping.
   123 	iTextToShape.Close();
   142 	iTextToShape.Close();
       
   143 
       
   144 	for (TInt i = iGlyphImagesInTransit.Count() - 1; i >= 0; --i)
       
   145 		{
       
   146 		iGlyphImagesInTransit[i].Close();
       
   147 		}
       
   148 	iGlyphImagesInTransit.Close();
   124 	}
   149 	}
   125 
   150 
   126 void CFbClient::Init(TUint aConnectionHandle)
   151 void CFbClient::Init(TUint aConnectionHandle)
   127 	{
   152 	{
   128 	iConnectionHandle=aConnectionHandle;
   153 	iConnectionHandle=aConnectionHandle;
   141 
   166 
   142 CFbTop* CFbClient::TopLevelStore()
   167 CFbTop* CFbClient::TopLevelStore()
   143 	{
   168 	{
   144 	CFontBitmapServer* server = FontBitmapServer();
   169 	CFontBitmapServer* server = FontBitmapServer();
   145 	if (server)
   170 	if (server)
       
   171 		{
   146 		return server->TopLevelStore();
   172 		return server->TopLevelStore();
       
   173 		}
   147 	else
   174 	else
       
   175 		{
   148 		return NULL;
   176 		return NULL;
       
   177 		}
   149 	}
   178 	}
   150 
   179 
   151 void CFbClient::CopyFontInfo(CFontObject* aFontObjPtr,TInt aHandle,TFontInfo& aFontInfo)
   180 void CFbClient::CopyFontInfo(CFontObject* aFontObjPtr,TInt aHandle,TFontInfo& aFontInfo)
   152 	{
   181 	{
   153 	CBitmapFont* font=aFontObjPtr->iAddressPointer;
   182 	CBitmapFont* font=aFontObjPtr->iAddressPointer;
   156 	aFontInfo.iAddressOffset=TInt(font)-TopLevelStore()->HeapBase();
   185 	aFontInfo.iAddressOffset=TInt(font)-TopLevelStore()->HeapBase();
   157 	}
   186 	}
   158 
   187 
   159 void CFbClient::ServiceL(const RMessage2& aMessage)
   188 void CFbClient::ServiceL(const RMessage2& aMessage)
   160 	{
   189 	{
       
   190 
   161 #ifdef _DEBUG
   191 #ifdef _DEBUG
   162 	TBool resetOwnHeap=EFalse;
   192 	TBool resetOwnHeap=EFalse;
   163 	TBool resetSharedHeap=EFalse;
   193 	TBool resetSharedHeap=EFalse;
   164 	
   194 	
   165 	//the memory tests have been mostly written to have start and end memory
   195 	//the memory tests have been mostly written to have start and end memory
   187 	if (iHeapCheck)
   217 	if (iHeapCheck)
   188 		{
   218 		{
   189 		__RHEAP_MARK(iHeap);
   219 		__RHEAP_MARK(iHeap);
   190 		}		
   220 		}		
   191 #endif		
   221 #endif		
       
   222 	//Call close on RSgImage handles being used to share glyph data with clients.
       
   223 	//The glyph images are held open to prevent the GlyphAtlas from closing them
       
   224 	//before a client can use them.
       
   225 	for (TInt i = iGlyphImagesInTransit.Count() - 1; i >= 0; --i)
       
   226 		{
       
   227 		iGlyphImagesInTransit[i].Close();
       
   228 		iGlyphImagesInTransit.Remove(i);
       
   229 		}
   192 	
   230 	
   193 	switch(aMessage.Function())
   231 	switch(aMessage.Function())
   194 		{
   232 		{
   195 // client messages
   233 // client messages
   196 	case EFbsMessInit:
   234 	case EFbsMessInit:
   244 	case EFbsMessDefaultLanguageForMetrics:
   282 	case EFbsMessDefaultLanguageForMetrics:
   245 	case EFbsCompress:
   283 	case EFbsCompress:
   246 	case EFbsMessFetchLinkedTypeface:
   284 	case EFbsMessFetchLinkedTypeface:
   247 	case EFbsMessRegisterLinkedTypeface:
   285 	case EFbsMessRegisterLinkedTypeface:
   248 	case EFbsMessUpdateLinkedTypeface:
   286 	case EFbsMessUpdateLinkedTypeface:
       
   287 
   249 #ifdef _DEBUG
   288 #ifdef _DEBUG
   250 		FontBitmapServer()->ProcMessage(aMessage,iSessionHandle,iRet);
   289 		FontBitmapServer()->ProcMessage(aMessage,iSessionHandle,iRet);
   251 #else
   290 #else
   252 		FontBitmapServer()->ProcMessage(aMessage,iSessionHandle);
   291 		FontBitmapServer()->ProcMessage(aMessage,iSessionHandle);
   253 #endif			
   292 #endif			
   275 	case EFbsMessGetGlyphOutline:
   314 	case EFbsMessGetGlyphOutline:
   276 	case EFbsMessReleaseGlyphOutline: 
   315 	case EFbsMessReleaseGlyphOutline: 
   277 #if (_DEBUG)
   316 #if (_DEBUG)
   278 	case EFbsMessSetDuplicateFail:
   317 	case EFbsMessSetDuplicateFail:
   279 #endif
   318 #endif
       
   319 	case EFbsMessGetGlyphs:
       
   320 	case EFbsMessGetGlyphMetrics:
   280 		ProcFontMessage(aMessage);
   321 		ProcFontMessage(aMessage);
   281 		break;
   322 		break;
   282 // bitmap messages
   323 // bitmap messages
   283 	case EFbsMessBitmapCreate:
   324 	case EFbsMessBitmapCreate:
   284 	case EFbsMessBitmapResize:
   325 	case EFbsMessBitmapResize:
   303 		ProcMemMessage(aMessage);
   344 		ProcMemMessage(aMessage);
   304 #else
   345 #else
   305 		aMessage.Complete(KErrNone);
   346 		aMessage.Complete(KErrNone);
   306 #endif	
   347 #endif	
   307 		break;
   348 		break;
       
   349 // Glyph Atlas messages (debug-only)
       
   350 	case EFbsMessAtlasFontCount:
       
   351 	case EFbsMessAtlasGlyphCount:
       
   352 #ifdef _DEBUG
       
   353 		ProcAtlasMessage(aMessage);
       
   354 #else
       
   355 		aMessage.Complete(KErrNotSupported);
       
   356 #endif
       
   357 		break;
       
   358     case EFbsMessOogmNotification:
       
   359 
       
   360         aMessage.Complete( HandleMesgOogmStatus( aMessage ) );
       
   361         break;
       
   362     case EFbsMessGetGlyphCacheMetrics:
       
   363 
       
   364         HandleMesgGlyphCacheMetrics( aMessage );
       
   365         break;
       
   366 
       
   367 //No-op message
       
   368 	case EFbsMessNoOp:
       
   369 #ifdef _DEBUG
       
   370 		iRet = KErrNone;
       
   371 #endif
       
   372 		aMessage.Complete(KErrNone);
       
   373 		break;
   308 	default:
   374 	default:
   309 		aMessage.Panic(KFBSERVPanicCategory,KErrArgument);
   375 		aMessage.Panic(KFBSERVPanicCategory,KErrArgument);
   310 		break;
   376 		break;
   311 		}
   377 		}
   312 #ifdef _DEBUG
   378 #ifdef _DEBUG
   370  */
   436  */
   371 TInt CFbClient::HandleMesgFontDuplicate(const RMessage2& aMessage, TBool& aPanicRequired)
   437 TInt CFbClient::HandleMesgFontDuplicate(const RMessage2& aMessage, TBool& aPanicRequired)
   372 	{
   438 	{
   373 #if _DEBUG
   439 #if _DEBUG
   374 	if (iFontDuplicateToFail)
   440 	if (iFontDuplicateToFail)
       
   441 		{
   375 		return KErrNoMemory; //return with this error since this error is possible
   442 		return KErrNoMemory; //return with this error since this error is possible
       
   443 		}
   376 #endif
   444 #endif
   377 	CFontObject* fontptr = (CFontObject*) aMessage.Int0();
   445 	CFontObject* fontptr = (CFontObject*) aMessage.Int0();
   378 	if(!TopLevelStore()->ValidFontHandle((TInt)fontptr))
   446 	if(!TopLevelStore()->ValidFontHandle((TInt)fontptr))
   379 		{
   447 		{
   380 		return KErrUnknown;
   448 		return KErrUnknown;
   381 		}
   449 		}
   382 
   450 
   383 	TPckgBuf<TFontInfo> foninfo;
   451 	TPckgBuf<TFontInfo> fontinfo;
   384 	TInt localhandle = 0;
   452 	TInt localhandle = 0;
   385 	TInt ret = fontptr->Open();
   453 	TInt ret = fontptr->Open();
   386 	if (ret != KErrNone)
   454 	if (ret != KErrNone)
   387 		{
   455 		{
   388 		return ret;
   456 		return ret;
   391 	if (ret != KErrNone)
   459 	if (ret != KErrNone)
   392 		{
   460 		{
   393 		fontptr->Close();
   461 		fontptr->Close();
   394 		return ret;
   462 		return ret;
   395 		}
   463 		}
   396 	CopyFontInfo(fontptr,localhandle,foninfo());
   464 	CopyFontInfo(fontptr,localhandle,fontinfo());
   397 	fontptr->iHeightInTwips = ((fontptr->iAddressPointer->HeightInPixels() * fontptr->iFontStore->iKPixelHeightInTwips) + 667) / 1000;
   465 	fontptr->iHeightInTwips = ((fontptr->iAddressPointer->HeightInPixels() * fontptr->iFontStore->iKPixelHeightInTwips) + 667) / 1000;
   398 	ret = aMessage.Write(1, foninfo);
   466 	ret = aMessage.Write(1, fontinfo);
   399 	if(ret != KErrNone)
   467 	if(ret != KErrNone)
   400 		{
   468 		{
   401 		iIx->Remove(localhandle);
   469 		iIx->Remove(localhandle);
   402 		aPanicRequired = ETrue;
   470 		aPanicRequired = ETrue;
   403 		return ret;
   471 		return ret;
   420 	CFontObject* fontptr = NULL;
   488 	CFontObject* fontptr = NULL;
   421 	TPckgBuf<TFontSpec> pckgFontSpec;
   489 	TPckgBuf<TFontSpec> pckgFontSpec;
   422 	TInt pckgMaxHeight;
   490 	TInt pckgMaxHeight;
   423 	TPckgBuf<TSizeInfo> info;
   491 	TPckgBuf<TSizeInfo> info;
   424 
   492 
   425 	const TFbsMessage	fbsMessage = static_cast<TFbsMessage>(aMessage.Function());
   493 	const TFbsMessage fbsMessage = static_cast<TFbsMessage>(aMessage.Function());
   426 
   494 
   427 	TInt ret = aMessage.Read(0, pckgFontSpec);
   495 	TInt ret = aMessage.Read(0, pckgFontSpec);
   428 	TFontSpec& fontSpec = pckgFontSpec();
   496 	TFontSpec& fontSpec = pckgFontSpec();
   429 	if (ret == KErrNone )
   497 	if (ret == KErrNone )
   430 		{
   498 		{
   431 		TInt length = fontSpec.iTypeface.iName.Length();
   499 		TInt length = fontSpec.iTypeface.iName.Length();
   432 		if(length < 0 || length > TOpenFontFaceAttribBase::ENameLength)
   500 		if((length < 0) || (length > TOpenFontFaceAttribBase::ENameLength))
   433 			{
   501 			{
   434 			aPanicRequired = ETrue;
   502 			aPanicRequired = ETrue;
   435 			return KErrArgument;
   503 			return KErrArgument;
   436 			}	
   504 			}	
   437 		
   505 		
   642 		return ETrue;
   710 		return ETrue;
   643 		}
   711 		}
   644 	return EFalse;
   712 	return EFalse;
   645 	}
   713 	}
   646 
   714 
       
   715 /** Handler for EFbsMessGetGlyphs message.
       
   716 Reads a batch of up to KMaxGlyphBatchSize glyph codes, and on success returns
       
   717 the corresponding TGlyphImageInfo objects.
       
   718  @param aMessage input parameters
       
   719  @param aPanicRequired flag that is set if a client panic is required
       
   720  @return KErrNone if successful, otherwise any system-wide error code.
       
   721  */
       
   722 TInt CFbClient::HandleMesgGetGlyphs(const RMessage2& aMessage, TBool& aPanicRequired)
       
   723 	{
       
   724 	CFbTop* fbtop = TopLevelStore();
       
   725 	// Previously requested glyphs were closed in ServiceL()
       
   726 	CGlyphAtlas* glyphAtlas = fbtop->GlyphAtlas();
       
   727 	if (!glyphAtlas)
       
   728 		{
       
   729 		return KErrNotSupported;
       
   730 		}
       
   731 	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
       
   732 	if(!fontptr)
       
   733 		{
       
   734 		aPanicRequired = ETrue;
       
   735 		return KErrBadHandle;
       
   736 		}
       
   737 
       
   738 	TUint glyphCodes[KMaxGlyphBatchSize];
       
   739 	TGlyphImageInfo glyphImageInfo[KMaxGlyphBatchSize];
       
   740 	TPckg<TUint[KMaxGlyphBatchSize]> glyphBatchPckg(glyphCodes);
       
   741 
       
   742 	TInt err = aMessage.Read(1, glyphBatchPckg);
       
   743 	if (err != KErrNone)
       
   744 		{
       
   745 		aPanicRequired = ETrue;
       
   746 		return err;
       
   747 		}
       
   748 	TInt glyphCodesCount = glyphBatchPckg.Length() / sizeof(TUint);
       
   749 	if (glyphCodesCount > KMaxGlyphBatchSize)
       
   750 		{
       
   751 		aPanicRequired = ETrue;
       
   752 		return KErrOverflow;
       
   753 		}
       
   754 
       
   755 	TInt glyphsProcessed = 0;
       
   756 	CBitmapFont* font = fontptr->iAddressPointer;
       
   757 	for (; (glyphsProcessed < glyphCodesCount); ++glyphsProcessed)
       
   758 		{
       
   759 		TUint32 glyphCode = glyphCodes[glyphsProcessed];
       
   760 		err = glyphAtlas->GetGlyph(*font, glyphCode, glyphImageInfo[glyphsProcessed]);
       
   761 		// Search for glyph in glyph atlas
       
   762 		if (KErrNone != err)
       
   763 			{
       
   764 			const TUint8* bitmapData = NULL;
       
   765 			TOpenFontCharMetrics metrics;
       
   766 			// search for glyph in font glyph cache and session cache.
       
   767 			if (!font->GetCharacterData(iSessionHandle, glyphCode | KTreatAsGlyphCodeFlag, metrics, bitmapData))
       
   768 				{
       
   769 				// Rasterize the glyph
       
   770 				if(!font->Rasterize(iSessionHandle, glyphCode | KTreatAsGlyphCodeFlag, iOpenFontGlyphData))
       
   771 					{
       
   772 					err = KErrNoMemory;
       
   773 					break;
       
   774 					}
       
   775 				metrics = *(iOpenFontGlyphData->Metrics());
       
   776 				bitmapData = iOpenFontGlyphData->BitmapPointer();
       
   777 				}
       
   778 			CGlyphAtlas::TAddGlyphArgs args(bitmapData, glyphCode, metrics);
       
   779 			err = glyphAtlas->AddGlyph(*font, args, glyphImageInfo[glyphsProcessed]);
       
   780 			}
       
   781 		if ((err == KErrNone) && (glyphImageInfo[glyphsProcessed].iImageId != KSgNullDrawableId))
       
   782 			{
       
   783 			// To prevent other threads closing the glyph image in the glyph atlas 
       
   784 			// before client has had chance to open the drawable id, open a local
       
   785 			// handle to the glyph image for the session, which will be closed either
       
   786 			// next time a request is made or when EFbsMessCloseGlyphs is handled.
       
   787 			RSgImage glyphImage;
       
   788 			err = glyphImage.Open(glyphImageInfo[glyphsProcessed].iImageId);
       
   789 			if (err == KErrNone)
       
   790 				{
       
   791 				err = iGlyphImagesInTransit.Append(glyphImage);
       
   792 				}
       
   793 			}
       
   794 		// If an error occurred during this iteration, abort now before the glyphsProcessed
       
   795 		// counter is incremented, which would give one too many processed glyphs.
       
   796 		if (KErrNone != err)
       
   797 			{
       
   798 			break;
       
   799 			}
       
   800 		}
       
   801 
       
   802 	// Even if there was an error, if at least one glyph was processed successfully
       
   803 	// send that back to the client, and reset the error code.
       
   804 	if (glyphsProcessed > 0)
       
   805 		{
       
   806 		TPckg<TGlyphImageInfo[KMaxGlyphBatchSize]> glyphImageInfoPckg(glyphImageInfo);
       
   807 		glyphImageInfoPckg.SetLength(glyphsProcessed * sizeof(TGlyphImageInfo));
       
   808 		err = aMessage.Write(2, glyphImageInfoPckg);
       
   809 		if (err != KErrNone)
       
   810 			{
       
   811 			aPanicRequired = ETrue;
       
   812 			return err;
       
   813 			}
       
   814 		}
       
   815 	else
       
   816 		{
       
   817 		// No glyphs being returned, so an error code must be returned.
       
   818 		__ASSERT_DEBUG(err != KErrNone, User::Panic(KFBSERVPanicCategory, err));
       
   819 		}
       
   820 	return err;
       
   821 	}
       
   822 
       
   823 /**
       
   824 Handler for EFbsMessGetGlyphMetrics message.
       
   825 Reads an array of glyph codes, and returns the offset from the heap base for the 
       
   826 corresponding metrics object.
       
   827 @pre The glyph codes have already been searched client-side in the font glyph
       
   828 	cache and the session cache.
       
   829 @param aMessage input parameters
       
   830 @param aPanicRequired flag that is set if a client panic is required
       
   831 @return KErrNone if successful, otherwise any system-wide error code.
       
   832  */
       
   833 TInt CFbClient::HandleMesgGetGlyphMetrics(const RMessage2& aMessage, TBool& aPanicRequired)
       
   834 	{
       
   835 	CFbTop* fbtop = TopLevelStore();
       
   836 	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
       
   837 	if(!fontptr)
       
   838 		{
       
   839 		aPanicRequired = ETrue;
       
   840 		return KErrBadHandle;
       
   841 		}
       
   842 	
       
   843 	TInt err = KErrNone;
       
   844 	TUint glyphCodes[KMaxMetricsBatchSize];
       
   845 	TPckg<TUint[KMaxMetricsBatchSize]> glyphBatchPckg(glyphCodes);
       
   846 	err = aMessage.Read(1, glyphBatchPckg);
       
   847 	if (err != KErrNone)
       
   848 		{
       
   849 		aPanicRequired = ETrue;
       
   850 		return err;
       
   851 		}
       
   852 	
       
   853 	TInt numGlyphCodes = glyphBatchPckg.Length() / sizeof(TUint);	
       
   854 	if (numGlyphCodes > KMaxMetricsBatchSize)
       
   855 		{
       
   856 		aPanicRequired = ETrue;
       
   857 		return KErrOverflow;
       
   858 		}
       
   859 	
       
   860 	CBitmapFont* font = fontptr->iAddressPointer;
       
   861 	const TInt heapbase = fbtop->HeapBase();
       
   862 
       
   863 	TInt glyphProcessed;
       
   864 	TInt glyphMetricsOffsets[KMaxMetricsBatchSize];
       
   865 	for (glyphProcessed = 0; (glyphProcessed < numGlyphCodes) && (err == KErrNone); ++glyphProcessed)
       
   866 		{
       
   867 		if (font->Rasterize(iSessionHandle, glyphCodes[glyphProcessed] | KTreatAsGlyphCodeFlag, iOpenFontGlyphData))
       
   868 			{
       
   869 			// Convert all pointers to be passed back to the client to offsets from
       
   870 			// the heap base so that they can be recreated client side relative to the
       
   871 			// client's heap base
       
   872 			glyphMetricsOffsets[glyphProcessed] = PointerToOffset(iOpenFontGlyphData->Metrics(), heapbase);
       
   873 			}
       
   874 		else
       
   875 			{
       
   876 			err = KErrNoMemory;
       
   877 			}
       
   878 		}
       
   879 
       
   880 	if (err == KErrNone)
       
   881 		{
       
   882 		TPckg<TInt[KMaxMetricsBatchSize]> glyphMetricsOffsetsPckg(glyphMetricsOffsets);
       
   883 		glyphMetricsOffsetsPckg.SetLength(glyphProcessed * sizeof(TInt));
       
   884 		err = aMessage.Write(2, glyphMetricsOffsetsPckg);
       
   885 		if (err != KErrNone)
       
   886 			{
       
   887 			aPanicRequired = ETrue;
       
   888 			}
       
   889 		}	
       
   890 	return err;
       
   891 	}
   647 
   892 
   648 /** Handler for EFbsMessFaceAttrib message
   893 /** Handler for EFbsMessFaceAttrib message
   649  @param aMessage Input and output parameters
   894  @param aMessage Input and output parameters
   650  @param aPanicRequired Flag that is set to ETrue if a client panic is required
   895  @param aPanicRequired Flag that is set to ETrue if a client panic is required
   651  @return ETrue if successful, EFalse or any system-wide error code if not successful.
   896  @return ETrue if successful, EFalse or any system-wide error code if not successful.
   659 		aPanicRequired = ETrue;
   904 		aPanicRequired = ETrue;
   660 		return KErrArgument;
   905 		return KErrArgument;
   661 		}
   906 		}
   662 	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
   907 	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
   663 
   908 
       
   909 	TInt ret = EFalse;
   664 	TPckgBuf<TOpenFontFaceAttrib> package;
   910 	TPckgBuf<TOpenFontFaceAttrib> package;
   665 	if ( (bitmapFont != NULL) && (bitmapFont->GetFaceAttrib(package())) )
   911 	if ( (bitmapFont != NULL) && (bitmapFont->GetFaceAttrib(package())) )
   666 		{
   912 		{
   667 		TInt ret = aMessage.Write(1,package);
   913 		ret = aMessage.Write(1,package);
   668 		if (ret == KErrNone)
   914 		if (ret == KErrNone)
   669 			{
   915 			{
   670 			return ETrue;
   916 			ret = ETrue;
   671 			}
   917 			}
   672 		else
   918 		else
   673 			{
   919 			{
   674 			aPanicRequired = ETrue;
   920 			aPanicRequired = ETrue;
   675 			return ret;
   921 			}
   676 			}
   922 		}
   677 		}
   923 	return ret;
   678 	return EFalse;
       
   679 	}
   924 	}
   680 
   925 
   681 
   926 
   682 /** Handler for EFbsMessHasCharacter message
   927 /** Handler for EFbsMessHasCharacter message
   683  @param aMessage Input parameters
   928  @param aMessage Input parameters
   715  */
   960  */
   716 TInt CFbClient::HandleMesgShapeText(const RMessage2& aMessage, TBool& aPanicRequired)
   961 TInt CFbClient::HandleMesgShapeText(const RMessage2& aMessage, TBool& aPanicRequired)
   717 	{
   962 	{
   718 	TInt error = KErrNone;
   963 	TInt error = KErrNone;
   719 	TShapeHeader* shape = 0;
   964 	TShapeHeader* shape = 0;
   720 	TPckgBuf<TShapeMessageParameters> sp;
       
   721 	if (aMessage.GetDesLength(2) != sizeof(TShapeMessageParameters))
   965 	if (aMessage.GetDesLength(2) != sizeof(TShapeMessageParameters))
   722 		{
   966 		{
   723 		aPanicRequired = ETrue;
   967 		aPanicRequired = ETrue;
   724 		return KErrArgument;
   968 		return KErrArgument;
   725 		}
   969 		}
   729 	if(!fontptr)
   973 	if(!fontptr)
   730 		{
   974 		{
   731 		aPanicRequired = ETrue;
   975 		aPanicRequired = ETrue;
   732 		return KErrArgument;
   976 		return KErrArgument;
   733 		}
   977 		}
   734 	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
       
   735 
   978 
   736 	TInt inputTextLength = aMessage.GetDesLength(1);
   979 	TInt inputTextLength = aMessage.GetDesLength(1);
   737 	if (inputTextLength < 0)
   980 	if (inputTextLength < 0)
   738 		{
   981 		{
   739 		error = inputTextLength;
   982 		error = inputTextLength;
   742 		}
   985 		}
   743 	else
   986 	else
   744 		{
   987 		{
   745 		iTextToShape.Zero();
   988 		iTextToShape.Zero();
   746 		if (iTextToShape.MaxLength() < inputTextLength)
   989 		if (iTextToShape.MaxLength() < inputTextLength)
       
   990 			{
   747 			error = iTextToShape.ReAlloc(inputTextLength);
   991 			error = iTextToShape.ReAlloc(inputTextLength);
       
   992 			}
   748 		}
   993 		}
   749 	if (error == KErrNone)
   994 	if (error == KErrNone)
   750 		{
   995 		{
   751 		error = aMessage.Read(1, iTextToShape);
   996 		error = aMessage.Read(1, iTextToShape);
   752 		if (error != KErrNone)
   997 		if (error != KErrNone)
   753 			{
   998 			{
   754 			aPanicRequired = ETrue;
   999 			aPanicRequired = ETrue;
   755 			return error;
  1000 			return error;
   756 			}
  1001 			}
       
  1002 		TPckgBuf<TShapeMessageParameters> sp;
   757 		error = aMessage.Read(2, sp);
  1003 		error = aMessage.Read(2, sp);
   758 		if (error != KErrNone)
  1004 		if (error != KErrNone)
   759 			{
  1005 			{
   760 			aPanicRequired = ETrue;
  1006 			aPanicRequired = ETrue;
   761 			return error;
  1007 			return error;
   762 			}
  1008 			}
       
  1009 		CBitmapFont* bitmapFont = fontptr->iAddressPointer;
   763 		TRAP(error, shape = bitmapFont->ShapeTextL(iTextToShape, iSessionHandle, sp()) );
  1010 		TRAP(error, shape = bitmapFont->ShapeTextL(iTextToShape, iSessionHandle, sp()) );
   764 		if (error == KErrNone)
  1011 		if (error == KErrNone)
   765 			{
  1012 			{
   766 			// Convert the pointer to be passed back to the client to an offset from
  1013 			// Convert the pointer to be passed back to the client to an offset from
   767 			// the heap base so that it can be recreated client side relative to the
  1014 			// the heap base so that it can be recreated client side relative to the
   951 		}
  1198 		}
   952 
  1199 
   953 	return ret;
  1200 	return ret;
   954 	}
  1201 	}
   955 
  1202 
       
  1203 
       
  1204 /**
       
  1205  Called in response to the GoomMonitor framework's call into FbsOogmPlugin.
       
  1206  We wish to either free some GPU memory, or reinstate its normal usage.
       
  1207 
       
  1208 @param  aMessage The IPC message.
       
  1209 @return KErrNone If the value contained in the TFbsOogmMessage enumeration member is meaningful and the glyph atlas is present.
       
  1210         KErrNotSupported if there is no glyph atlas.
       
  1211         KErrUnknown if the value contained in the TFbsOogmMessage enumeration member is not meaningful.
       
  1212  */
       
  1213 TInt CFbClient::HandleMesgOogmStatus( const RMessage2& aMessage )
       
  1214     {
       
  1215     TInt ret = KErrNone;
       
  1216     CGlyphAtlas* glyphAtlas = TopLevelStore()->GlyphAtlas();
       
  1217 
       
  1218     if ( NULL == glyphAtlas )
       
  1219         {
       
  1220         return KErrNotSupported;
       
  1221         }
       
  1222 
       
  1223 
       
  1224     TPckgBuf<TFbsOogmMessage> oogmMessage;
       
  1225     aMessage.Read( 0, oogmMessage );
       
  1226 
       
  1227     switch( oogmMessage().iOogmNotification )
       
  1228         {
       
  1229     case TFbsOogmMessage::EFbsOogmNoAction:
       
  1230         break;
       
  1231 
       
  1232     case TFbsOogmMessage::EFbsOogmLowNotification:
       
  1233         {
       
  1234         glyphAtlas->ReleaseGpuMemory( oogmMessage().iBytesToFree, oogmMessage().iFlags );
       
  1235         }
       
  1236          break;
       
  1237 
       
  1238     case TFbsOogmMessage::EFbsOogmOkayNotification:
       
  1239         {
       
  1240         glyphAtlas->InstateGpuMemory( oogmMessage().iFlags );
       
  1241         }
       
  1242         break;
       
  1243 
       
  1244     default:
       
  1245         ret = KErrUnknown;
       
  1246         break;
       
  1247         }
       
  1248 
       
  1249     return ret;
       
  1250     }
       
  1251 
       
  1252 
       
  1253 void CFbClient::HandleMesgGlyphCacheMetrics( const RMessage2& aMessage )
       
  1254     {
       
  1255     CGlyphAtlas* glyphAtlas = TopLevelStore()->GlyphAtlas();
       
  1256     TPckgBuf<TGlyphCacheMetrics>  metrics;
       
  1257 
       
  1258     glyphAtlas->GetGlyphCacheMetrics( metrics() );
       
  1259 
       
  1260     aMessage.Complete( aMessage.Write(0, metrics) );
       
  1261     }
       
  1262 
       
  1263 
   956 void CFbClient::ProcFontMessage(const RMessage2& aMessage)
  1264 void CFbClient::ProcFontMessage(const RMessage2& aMessage)
   957 	{
  1265 	{
   958 	TInt ret = KErrUnknown;
  1266 	TInt ret = KErrNone;
   959 	TBool panicRequired = EFalse;
  1267 	TBool panicRequired = EFalse;
   960 
  1268 
   961 	switch(aMessage.Function())
  1269 	switch(aMessage.Function())
   962 		{
  1270 		{
   963 		case EFbsMessFontDuplicate:
  1271 		case EFbsMessFontDuplicate:
  1080 		case EFbsMessReleaseFontTable:
  1388 		case EFbsMessReleaseFontTable:
  1081 			{
  1389 			{
  1082 			ret = HandleMesgReleaseFontTable(aMessage, panicRequired);
  1390 			ret = HandleMesgReleaseFontTable(aMessage, panicRequired);
  1083 			break;
  1391 			break;
  1084 			}
  1392 			}
       
  1393 		case EFbsMessGetGlyphs:
       
  1394 			{
       
  1395 			ret = HandleMesgGetGlyphs(aMessage, panicRequired);
       
  1396 			break;
       
  1397 			}
       
  1398 		case EFbsMessGetGlyphMetrics:
       
  1399 			{
       
  1400 			ret = HandleMesgGetGlyphMetrics(aMessage, panicRequired);
       
  1401 			break;
       
  1402 			}
  1085 
  1403 
  1086 #ifdef _DEBUG
  1404 #ifdef _DEBUG
  1087 		case EFbsMessSetDuplicateFail:
  1405 		case EFbsMessSetDuplicateFail:
       
  1406 			{
  1088 			TInt argument =aMessage.Int0();
  1407 			TInt argument =aMessage.Int0();
  1089 			if (argument)
  1408 			if (argument)
  1090 				{
  1409 				{
  1091 				iFontDuplicateToFail = ETrue;
  1410 				iFontDuplicateToFail = ETrue;
  1092 				}
  1411 				}
  1094 				{
  1413 				{
  1095 				iFontDuplicateToFail = EFalse;
  1414 				iFontDuplicateToFail = EFalse;
  1096 				}
  1415 				}
  1097 			ret=KErrNone;
  1416 			ret=KErrNone;
  1098 			break;
  1417 			break;
       
  1418 			}
  1099 #endif
  1419 #endif
       
  1420 		default:
       
  1421 			ret = KErrUnknown;
  1100 		}
  1422 		}
  1101 
  1423 
  1102 	// either have a result or an error code to panic the client with
  1424 	// either have a result or an error code to panic the client with
  1103 	if (panicRequired)
  1425 	if (panicRequired)
  1104 		{
  1426 		{
  1118 
  1440 
  1119 void CFbClient::ProcBitmapMessage(const RMessage2 &aMessage)
  1441 void CFbClient::ProcBitmapMessage(const RMessage2 &aMessage)
  1120 	{
  1442 	{
  1121 	CBitmapObject* bmpptr=NULL;
  1443 	CBitmapObject* bmpptr=NULL;
  1122 	TInt localhandle=0;
  1444 	TInt localhandle=0;
  1123 	TInt ret=KErrUnknown;
  1445 	TInt ret = KErrNone;
  1124 	switch(aMessage.Function())
  1446 	switch(aMessage.Function())
  1125 		{
  1447 		{
  1126 	case EFbsMessBitmapCreate:
  1448 	case EFbsMessBitmapCreate:
  1127 		{
  1449 		{
  1128 		TPckgBuf<TBmpSpec> bs;
  1450 		TPckgBuf<TBmpSpec> bs;
  1281 			ret=KErrUnknown;
  1603 			ret=KErrUnknown;
  1282 			break;
  1604 			break;
  1283 			}
  1605 			}
  1284 		ret = fbtop->GetCleanBitmap(bmpptr);
  1606 		ret = fbtop->GetCleanBitmap(bmpptr);
  1285 		if (ret != KErrNone)
  1607 		if (ret != KErrNone)
  1286 			break;
  1608 			{
       
  1609 			break;
       
  1610 			}
  1287 		TSize newsize(aMessage.Int1(),aMessage.Int2());
  1611 		TSize newsize(aMessage.Int1(),aMessage.Int2());
  1288  		const TBool compressedInRam = bmpptr->Address()->IsCompressedInRAM();  //It must be set before the resizing is done.
  1612  		const TBool compressedInRam = bmpptr->Address()->IsCompressedInRAM();  //It must be set before the resizing is done.
  1289 		const TDisplayMode dispMode = bmpptr->Address()->DisplayMode();
  1613 		const TDisplayMode dispMode = bmpptr->Address()->DisplayMode();
  1290 		CBitmapObject* newbmpptr = NULL;
  1614 		CBitmapObject* newbmpptr = NULL;
  1291 		TRAP(ret, newbmpptr = fbtop->CreateBitmapL(newsize, dispMode, KUidCFbsBitmapCreation, ETrue));
  1615 		TRAP(ret, newbmpptr = fbtop->CreateBitmapL(newsize, dispMode, KUidCFbsBitmapCreation, ETrue));
  1292 		if (ret != KErrNone)
  1616 		if (ret != KErrNone)
  1293 			break;
  1617 			{
       
  1618 			break;
       
  1619 			}
  1294 		ret = newbmpptr->Address()->CopyData(*bmpptr->Address());
  1620 		ret = newbmpptr->Address()->CopyData(*bmpptr->Address());
  1295 		if (ret != KErrNone)
  1621 		if (ret != KErrNone)
  1296 			{
  1622 			{
  1297 			newbmpptr->Close();
  1623 			newbmpptr->Close();
  1298 			break;
  1624 			break;
  1323 			iIx->Remove(newlocalhandle);
  1649 			iIx->Remove(newlocalhandle);
  1324 			break;
  1650 			break;
  1325 			}
  1651 			}
  1326 		bmpptr->SetCleanBitmap(newbmpptr);
  1652 		bmpptr->SetCleanBitmap(newbmpptr);
  1327 		if (bmpptr->AccessCount() >= 2)
  1653 		if (bmpptr->AccessCount() >= 2)
       
  1654 			{
  1328 			fbtop->NotifyDirtyBitmap(*bmpptr, this);
  1655 			fbtop->NotifyDirtyBitmap(*bmpptr, this);
       
  1656 			}
  1329 		iIx->Remove(localhandle);
  1657 		iIx->Remove(localhandle);
  1330 		TPckgBuf<TBmpHandles> handlebuffer;
  1658 		TPckgBuf<TBmpHandles> handlebuffer;
  1331 		handlebuffer().iHandle = newlocalhandle;
  1659 		handlebuffer().iHandle = newlocalhandle;
  1332 		handlebuffer().iServerHandle = newbmpptr->Handle();
  1660 		handlebuffer().iServerHandle = newbmpptr->Handle();
  1333 		handlebuffer().iAddressOffset = TInt(newbmpptr->Address()) - fbtop->HeapBase();
  1661 		handlebuffer().iAddressOffset = TInt(newbmpptr->Address()) - fbtop->HeapBase();
  1351 		//coverity [check_return]
  1679 		//coverity [check_return]
  1352 		//coverity [unchecked_value]
  1680 		//coverity [unchecked_value]
  1353 		TopLevelStore()->GetCleanBitmap(bmpptr);
  1681 		TopLevelStore()->GetCleanBitmap(bmpptr);
  1354 		ret = bmpptr->Open();
  1682 		ret = bmpptr->Open();
  1355 		if (ret != KErrNone)
  1683 		if (ret != KErrNone)
  1356 			break;
  1684 			{
       
  1685 			break;
       
  1686 			}
  1357 		TPckgBuf<TBmpHandles> handlebuffer;
  1687 		TPckgBuf<TBmpHandles> handlebuffer;
  1358 		TRAP(ret,localhandle=iIx->AddL(bmpptr));
  1688 		TRAP(ret,localhandle=iIx->AddL(bmpptr));
  1359 		if(ret!=KErrNone)
  1689 		if(ret!=KErrNone)
  1360 			{
  1690 			{
  1361 			bmpptr->Close();
  1691 			bmpptr->Close();
  1384 			ret = KErrUnknown;
  1714 			ret = KErrUnknown;
  1385 			break;
  1715 			break;
  1386 			}
  1716 			}
  1387 		ret = fbtop->GetCleanBitmap(bmpptr);
  1717 		ret = fbtop->GetCleanBitmap(bmpptr);
  1388 		if (ret != KErrNone)
  1718 		if (ret != KErrNone)
  1389 			break;
  1719 			{
       
  1720 			break;
       
  1721 			}
  1390 		const TSize size = bmpptr->Address()->SizeInPixels();
  1722 		const TSize size = bmpptr->Address()->SizeInPixels();
  1391 		const TDisplayMode dispMode = bmpptr->Address()->DisplayMode();
  1723 		const TDisplayMode dispMode = bmpptr->Address()->DisplayMode();
  1392 		CBitmapObject* newbmpptr = NULL;
  1724 		CBitmapObject* newbmpptr = NULL;
  1393 		TRAP(ret, newbmpptr = fbtop->CreateBitmapL(size, dispMode, KUidCFbsBitmapCreation, ETrue));
  1725 		TRAP(ret, newbmpptr = fbtop->CreateBitmapL(size, dispMode, KUidCFbsBitmapCreation, ETrue));
  1394 		if (ret != KErrNone)
  1726 		if (ret != KErrNone)
  1395 			break;
  1727 			{
       
  1728 			break;
       
  1729 			}
  1396 		ret = newbmpptr->Address()->CopyData(*bmpptr->Address());
  1730 		ret = newbmpptr->Address()->CopyData(*bmpptr->Address());
  1397 		if (ret != KErrNone)
  1731 		if (ret != KErrNone)
  1398 			{
  1732 			{
  1399 			newbmpptr->Close();
  1733 			newbmpptr->Close();
  1400 			break;
  1734 			break;
  1418 			iIx->Remove(newlocalhandle);
  1752 			iIx->Remove(newlocalhandle);
  1419 			break;
  1753 			break;
  1420 			}
  1754 			}
  1421 		bmpptr->SetCleanBitmap(newbmpptr);
  1755 		bmpptr->SetCleanBitmap(newbmpptr);
  1422 		if (bmpptr->AccessCount() >= 2)
  1756 		if (bmpptr->AccessCount() >= 2)
       
  1757 			{
  1423 			fbtop->NotifyDirtyBitmap(*bmpptr, this);
  1758 			fbtop->NotifyDirtyBitmap(*bmpptr, this);
       
  1759 			}
  1424 		iIx->Remove(localhandle);
  1760 		iIx->Remove(localhandle);
  1425 		TPckgBuf<TBmpHandles> handlebuffer;
  1761 		TPckgBuf<TBmpHandles> handlebuffer;
  1426 		handlebuffer().iHandle = newlocalhandle;
  1762 		handlebuffer().iHandle = newlocalhandle;
  1427 		handlebuffer().iServerHandle = newbmpptr->Handle();
  1763 		handlebuffer().iServerHandle = newbmpptr->Handle();
  1428 		handlebuffer().iAddressOffset = TInt(newbmpptr->Address()) - fbtop->HeapBase();
  1764 		handlebuffer().iAddressOffset = TInt(newbmpptr->Address()) - fbtop->HeapBase();
  1449 			}
  1785 			}
  1450 		ret = fbtop->GetCleanBitmap(bmpptr);
  1786 		ret = fbtop->GetCleanBitmap(bmpptr);
  1451 		if (ret != KErrNone)
  1787 		if (ret != KErrNone)
  1452 			{
  1788 			{
  1453 			if (!async)
  1789 			if (!async)
       
  1790 				{
  1454 				ret = KErrNone;
  1791 				ret = KErrNone;
       
  1792 				}
  1455 			break;
  1793 			break;
  1456 			}
  1794 			}
  1457 		ret = bmpptr->Address()->CheckBackgroundCompressData();
  1795 		ret = bmpptr->Address()->CheckBackgroundCompressData();
  1458 		if (KErrNone == ret)
  1796 		if (KErrNone == ret)
  1459 			{
  1797 			{
  1460 			ret = fbtop->BackgroundCompression()->AddToCompressionQueue(bmpptr, scheme, async ? &aMessage : NULL);
  1798 			ret = fbtop->BackgroundCompression()->AddToCompressionQueue(bmpptr, scheme, async ? &aMessage : NULL);
  1461 			if (ret == KErrNone && async)
  1799 			if (ret == KErrNone && async)
       
  1800 				{
  1462 				return; // do not complete the client's request - that will be done by the background compression thread
  1801 				return; // do not complete the client's request - that will be done by the background compression thread
       
  1802 				}
  1463 			}
  1803 			}
  1464 		if (KErrAlreadyExists == ret)
  1804 		if (KErrAlreadyExists == ret)
       
  1805 			{
  1465 			ret = KErrNone;
  1806 			ret = KErrNone;
       
  1807 			}
  1466 		break;
  1808 		break;
  1467 		}
  1809 		}
  1468 	case EFbsMessBitmapClean:
  1810 	case EFbsMessBitmapClean:
  1469 		{
  1811 		{
  1470 		TInt localhandle = aMessage.Int0();
  1812 		TInt localhandle = aMessage.Int0();
  1475 			ret = KErrUnknown;
  1817 			ret = KErrUnknown;
  1476 			break;
  1818 			break;
  1477 			}
  1819 			}
  1478 		ret = fbtop->GetCleanBitmap(bmpptr);
  1820 		ret = fbtop->GetCleanBitmap(bmpptr);
  1479 		if (ret != KErrNone)
  1821 		if (ret != KErrNone)
  1480 			break;
  1822 			{
       
  1823 			break;
       
  1824 			}
  1481 		ret = bmpptr->Open();
  1825 		ret = bmpptr->Open();
  1482 		if (ret != KErrNone)
  1826 		if (ret != KErrNone)
  1483 			break;
  1827 			{
       
  1828 			break;
       
  1829 			}
  1484 		TInt cleanlocalhandle = 0;
  1830 		TInt cleanlocalhandle = 0;
  1485 		TRAP(ret, cleanlocalhandle = iIx->AddL(bmpptr));
  1831 		TRAP(ret, cleanlocalhandle = iIx->AddL(bmpptr));
  1486 		if (ret != KErrNone)
  1832 		if (ret != KErrNone)
  1487 			{
  1833 			{
  1488 			bmpptr->Close();
  1834 			bmpptr->Close();
  1528 		if (!iHelper->iDirty)
  1874 		if (!iHelper->iDirty)
  1529 			{
  1875 			{
  1530 			iHelper->iMessage = aMessage;
  1876 			iHelper->iMessage = aMessage;
  1531 			return; // do not complete the client's request yet - that will be done when a bitmap becomes dirty
  1877 			return; // do not complete the client's request yet - that will be done when a bitmap becomes dirty
  1532 			}
  1878 			}
  1533 		ret = KErrNone;
       
  1534 		iHelper->iDirty = EFalse;
  1879 		iHelper->iDirty = EFalse;
  1535 		}
  1880 		}
  1536 		break;
  1881 		break;
  1537 	case EFbsMessBitmapCancelNotifyDirty:
  1882 	case EFbsMessBitmapCancelNotifyDirty:
  1538 		{
  1883 		{
  1539 		if (iHelper != NULL && !iHelper->iMessage.IsNull())
  1884 		if (iHelper != NULL && !iHelper->iMessage.IsNull())
       
  1885 			{
  1540 			iHelper->iMessage.Complete(KErrCancel);
  1886 			iHelper->iMessage.Complete(KErrCancel);
  1541 		ret = KErrNone;
  1887 			}
  1542 		}
  1888 		}
  1543 		break;
  1889 		break;
       
  1890 	default:
       
  1891 		ret = KErrUnknown;
  1544 		}
  1892 		}
  1545 		
  1893 		
  1546 	if(!aMessage.IsNull())
  1894 	if(!aMessage.IsNull())
  1547 		{
  1895 		{
  1548 		aMessage.Complete(ret);
  1896 		aMessage.Complete(ret);
  1614 
  1962 
  1615 	// if there is a to-be-completed request for dirty bitmap notification complete it now
  1963 	// if there is a to-be-completed request for dirty bitmap notification complete it now
  1616 	if (iHelper)
  1964 	if (iHelper)
  1617 		{
  1965 		{
  1618 		if (!iHelper->iMessage.IsNull())
  1966 		if (!iHelper->iMessage.IsNull())
       
  1967 			{
  1619 			iHelper->iMessage.Complete(KErrDisconnected);
  1968 			iHelper->iMessage.Complete(KErrDisconnected);
       
  1969 			}
  1620 		iHelper->Deque();
  1970 		iHelper->Deque();
  1621 		delete iHelper;
  1971 		delete iHelper;
  1622 		iHelper = NULL;
  1972 		iHelper = NULL;
  1623 		}
  1973 		}
  1624 
  1974 
  1676 				iHeapCheckFlip=ETrue;
  2026 				iHeapCheckFlip=ETrue;
  1677 				}
  2027 				}
  1678 			break;
  2028 			break;
  1679 		case EFbsMessHeap:
  2029 		case EFbsMessHeap:
  1680 			ret=(TInt)iHeap;
  2030 			ret=(TInt)iHeap;
  1681 			break;			
  2031 			break;
       
  2032 		default:
       
  2033 			ret = KErrUnknown;
  1682 		}
  2034 		}
  1683 	aMessage.Complete(ret);
  2035 	aMessage.Complete(ret);
  1684 	iRet=ret;
  2036 	iRet=ret;
  1685 	}
  2037 	}
       
  2038 
       
  2039 /**
       
  2040 Processes messages associated with the Glyph Atlas.
       
  2041 @param aMessage The message used to perform IPC to the client.
       
  2042  */
       
  2043 void CFbClient::ProcAtlasMessage(const RMessage2 &aMessage)
       
  2044 	{
       
  2045 	TInt ret = KErrNone;
       
  2046 	CFbTop* fbtop = TopLevelStore();
       
  2047 	CGlyphAtlas* glyphAtlas = fbtop->GlyphAtlas();
       
  2048 	if (!glyphAtlas)
       
  2049 		{
       
  2050 		ret = KErrNotSupported;
       
  2051 		}
       
  2052 	else
       
  2053 		{
       
  2054 		switch(aMessage.Function())
       
  2055 			{
       
  2056 			case EFbsMessAtlasFontCount:
       
  2057 				ret = glyphAtlas->FontCount();
       
  2058 				break;
       
  2059 			case EFbsMessAtlasGlyphCount:
       
  2060 				{
       
  2061 				TInt fontHandle = aMessage.Int0();
       
  2062 				if (fontHandle != 0)
       
  2063 					{
       
  2064 					if (fbtop->ValidFontHandle(fontHandle))
       
  2065 						{
       
  2066 						CFontObject* fontptr = reinterpret_cast<CFontObject*>(fontHandle);
       
  2067 						ret = glyphAtlas->GlyphCount(static_cast<CBitmapFont&>(*(fontptr->iAddressPointer)));
       
  2068 						}
       
  2069 					else
       
  2070 						{
       
  2071 						ret = KErrNotFound;
       
  2072 						}
       
  2073 					}
       
  2074 				else
       
  2075 					{
       
  2076 					ret = glyphAtlas->GlyphCount();
       
  2077 					}
       
  2078 				}
       
  2079 				break;
       
  2080 			default:
       
  2081 				ret = KErrUnknown;
       
  2082 			}
       
  2083 		}
       
  2084 	aMessage.Complete(ret);
       
  2085 	iRet=ret;
       
  2086 	}
  1686 #endif
  2087 #endif