fbs/fontandbitmapserver/sfbs/FBSCLI.CPP
branchRCL_3
changeset 19 bbf46f59e123
parent 18 57c618273d5c
child 20 25ffed67c7ef
equal deleted inserted replaced
18:57c618273d5c 19:bbf46f59e123
    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 "fbsmessage.h"
    19 #include <graphics/fbsoogmmessage.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"
    24 #include "OstTraceDefinitions.h"
    26 #include "OstTraceDefinitions.h"
    25 #include "fbstrace.h"
    27 #include "fbstrace.h"
    26 #ifdef OST_TRACE_COMPILER_IN_USE
    28 #ifdef OST_TRACE_COMPILER_IN_USE
    27 #include "FBSCLITraces.h"
    29 #include "FBSCLITraces.h"
    28 #endif
    30 #endif
    29 
    31 
       
    32 
       
    33 /**
       
    34 Bitwise mask that sets the MSB to indicate to a font rasterizer
       
    35 that a code is a glyphcode and not a character code
       
    36 */
       
    37 const TUint32 KTreatAsGlyphCodeFlag = 1UL << 31;
    30 
    38 
    31 /** Helper function for converting a pointer to an offset from the passed
    39 /** Helper function for converting a pointer to an offset from the passed
    32 heap base. Use OffsetToPointer() to convert the returned offset back to a
    40 heap base. Use OffsetToPointer() to convert the returned offset back to a
    33 useable pointer.
    41 useable pointer.
    34 @param aAny A pointer to be converted to an offset.
    42 @param aAny A pointer to be converted to an offset.
    37 back to a pointer using the function OffsetToPointer(). 
    45 back to a pointer using the function OffsetToPointer(). 
    38 @see OffsetToPointer()
    46 @see OffsetToPointer()
    39  */
    47  */
    40 LOCAL_C TInt PointerToOffset(const TAny* aAny, TInt aHeapBase)
    48 LOCAL_C TInt PointerToOffset(const TAny* aAny, TInt aHeapBase)
    41 	{
    49 	{
       
    50 	TInt offset = 0;
    42 	if (aAny && aHeapBase)
    51 	if (aAny && aHeapBase)
    43 		{
    52 		{
    44 		return reinterpret_cast<TInt>(aAny) - aHeapBase;
    53 		offset = reinterpret_cast<TInt>(aAny) - aHeapBase;
    45 		}
    54 		}
    46 	return 0;
    55 	return offset;
    47 	}
    56 	}
    48 
    57 
    49 /** Helper function for converting an offset (that was calculated using
    58 /** Helper function for converting an offset (that was calculated using
    50 PointerToOffset()) back to a pointer relative to the passed heap base.
    59 PointerToOffset()) back to a pointer relative to the passed heap base.
    51 @param aOffset The offset to be converted to a pointer.
    60 @param aOffset The offset to be converted to a pointer.
    62 	return NULL;
    71 	return NULL;
    63 	}
    72 	}
    64 
    73 
    65 CFbClient::CFbClient(RHeap* aHeap):
    74 CFbClient::CFbClient(RHeap* aHeap):
    66 	CSession2(),
    75 	CSession2(),
    67 	iConnectionHandle(0),
       
    68 	iIx(NULL),
       
    69 	iResourceCount(0),
       
    70 	iHeap(aHeap)
    76 	iHeap(aHeap)
    71 #ifdef _DEBUG
    77 #ifdef _DEBUG
    72 	,iOwnHeapFailNumber(-1),
    78 	,iOwnHeapFailNumber(-1),
    73 	iSharedHeapFailNumber(-1)
    79 	iSharedHeapFailNumber(-1)
    74 #endif	
    80 #endif	
    75 	{
    81 	{
    76 	}
    82 	}
    77 
    83 
    78 CFbClient* CFbClient::NewL(RHeap* aHeap)
    84 CFbClient* CFbClient::NewL(RHeap* aHeap)
    79 	{
    85 	{
    80 	CFbClient* c = new(ELeave) CFbClient(aHeap);
    86 	CFbClient* self = new (ELeave) CFbClient(aHeap);
    81 	c->iOpenFontGlyphData = TOpenFontGlyphData::New(aHeap,4 * 1024);
    87 	CleanupStack::PushL(self);
    82 	if (!c->iOpenFontGlyphData)
    88 	self->ConstructL();
    83 		{
    89 	CleanupStack::Pop(); // self;
    84 		delete c;
    90 	return self;
       
    91 	}
       
    92 
       
    93 /**
       
    94 Two-phase constructor.
       
    95 @leave KErrNoMemory if TOpenFontGlyphData construction failed.
       
    96 */
       
    97 void CFbClient::ConstructL()
       
    98 	{
       
    99 	iOpenFontGlyphData = TOpenFontGlyphData::New(iHeap, 4 * 1024);
       
   100 	if (!iOpenFontGlyphData)
       
   101 		{
    85 		User::Leave(KErrNoMemory);
   102 		User::Leave(KErrNoMemory);
    86 		}
   103 		}
    87 	return c;
       
    88 	}
   104 	}
    89 
   105 
    90 CFbClient::~CFbClient()
   106 CFbClient::~CFbClient()
    91 	{
   107 	{
    92 	/*
   108 	/*
    99 		{
   115 		{
   100 		font_store = fbTop->FontStore();
   116 		font_store = fbTop->FontStore();
   101 		}
   117 		}
   102 	
   118 	
   103 	if (font_store)
   119 	if (font_store)
       
   120 		{
   104 		font_store->DeleteSessionCache(iSessionHandle);
   121 		font_store->DeleteSessionCache(iSessionHandle);
       
   122 		font_store->CleanupCacheOnFbsSessionTermination(iSessionHandle);
       
   123 		
       
   124 		// If the font store doesn't exist, neither will the shared heap owned by FBSERV.
       
   125 		iHeap->Free(iOpenFontGlyphData);
       
   126 		}
   105 	
   127 	
   106 	// If the font store doesn't exist, neither will the shared heap owned by FBSERV.
   128 	// delete fonts held by the client
   107 	if (font_store)
       
   108 		iHeap->Free(iOpenFontGlyphData);
       
   109 	
       
   110 	// delete fonts hold by the client
       
   111 	delete iIx;
   129 	delete iIx;
   112 	
   130 	
   113 	// delete font files hold by the client
   131 	// delete font files held by the client
   114     if (iFontFileIndex)
   132 	if (iFontFileIndex)
   115         {
   133 		{
   116         TInt count = iFontFileIndex->Count();
   134 		TInt count = iFontFileIndex->Count();
   117         for (TInt index = 0;index < count; index++)
   135 		for (TInt index = 0;index < count; index++)
   118             {
   136 			{
   119             if (font_store)
   137 			if (font_store)
   120                 font_store->RemoveFile(iFontFileIndex->At(0).iUid);
   138 				{
   121             iFontFileIndex->Delete(0);
   139 				font_store->RemoveFile(iFontFileIndex->At(0).iUid);
   122             }
   140 				}
   123         delete iFontFileIndex;
   141 			iFontFileIndex->Delete(0);
   124         }
   142 			}
   125 
   143 		delete iFontFileIndex;
   126 	// Close the buffer used to hold the text thats needs shaping.
   144 		}
       
   145 
       
   146 	// Close the buffer used to hold the text that needs shaping.
   127 	iTextToShape.Close();
   147 	iTextToShape.Close();
       
   148 
       
   149 	for (TInt i = iGlyphImagesInTransit.Count() - 1; i >= 0; --i)
       
   150 		{
       
   151 		iGlyphImagesInTransit[i].Close();
       
   152 		}
       
   153 	iGlyphImagesInTransit.Close();
   128 	}
   154 	}
   129 
   155 
   130 void CFbClient::Init(TUint aConnectionHandle)
   156 void CFbClient::Init(TUint aConnectionHandle)
   131 	{
   157 	{
   132 	iConnectionHandle=aConnectionHandle;
   158 	iConnectionHandle=aConnectionHandle;
   145 
   171 
   146 CFbTop* CFbClient::TopLevelStore()
   172 CFbTop* CFbClient::TopLevelStore()
   147 	{
   173 	{
   148 	CFontBitmapServer* server = FontBitmapServer();
   174 	CFontBitmapServer* server = FontBitmapServer();
   149 	if (server)
   175 	if (server)
       
   176 		{
   150 		return server->TopLevelStore();
   177 		return server->TopLevelStore();
       
   178 		}
   151 	else
   179 	else
       
   180 		{
   152 		return NULL;
   181 		return NULL;
       
   182 		}
   153 	}
   183 	}
   154 
   184 
   155 void CFbClient::CopyFontInfo(CFontObject* aFontObjPtr,TInt aHandle,TFontInfo& aFontInfo)
   185 void CFbClient::CopyFontInfo(CFontObject* aFontObjPtr,TInt aHandle,TFontInfo& aFontInfo)
   156 	{
   186 	{
   157 	CBitmapFont* font=aFontObjPtr->iAddressPointer;
   187 	CBitmapFont* font=aFontObjPtr->iAddressPointer;
   160 	aFontInfo.iAddressOffset=TInt(font)-TopLevelStore()->HeapBase();
   190 	aFontInfo.iAddressOffset=TInt(font)-TopLevelStore()->HeapBase();
   161 	}
   191 	}
   162 
   192 
   163 void CFbClient::ServiceL(const RMessage2& aMessage)
   193 void CFbClient::ServiceL(const RMessage2& aMessage)
   164 	{
   194 	{
       
   195 
   165 #ifdef _DEBUG
   196 #ifdef _DEBUG
   166 	TBool resetOwnHeap=EFalse;
   197 	TBool resetOwnHeap=EFalse;
   167 	TBool resetSharedHeap=EFalse;
   198 	TBool resetSharedHeap=EFalse;
   168 	
   199 	
   169 	//the memory tests have been mostly written to have start and end memory
   200 	//the memory tests have been mostly written to have start and end memory
   191 	if (iHeapCheck)
   222 	if (iHeapCheck)
   192 		{
   223 		{
   193 		__RHEAP_MARK(iHeap);
   224 		__RHEAP_MARK(iHeap);
   194 		}		
   225 		}		
   195 #endif		
   226 #endif		
       
   227 	//Call close on RSgImage handles being used to share glyph data with clients.
       
   228 	//The glyph images are held open to prevent the GlyphAtlas from closing them
       
   229 	//before a client can use them.
       
   230 	for (TInt i = iGlyphImagesInTransit.Count() - 1; i >= 0; --i)
       
   231 		{
       
   232 		iGlyphImagesInTransit[i].Close();
       
   233 		iGlyphImagesInTransit.Remove(i);
       
   234 		}
   196 	
   235 	
   197 	switch(aMessage.Function())
   236 	switch(aMessage.Function())
   198 		{
   237 		{
   199 // client messages
   238 // client messages
   200 	case EFbsMessInit:
   239 	case EFbsMessInit:
   249 	case EFbsMessDefaultLanguageForMetrics:
   288 	case EFbsMessDefaultLanguageForMetrics:
   250 	case EFbsCompress:
   289 	case EFbsCompress:
   251 	case EFbsMessFetchLinkedTypeface:
   290 	case EFbsMessFetchLinkedTypeface:
   252 	case EFbsMessRegisterLinkedTypeface:
   291 	case EFbsMessRegisterLinkedTypeface:
   253 	case EFbsMessUpdateLinkedTypeface:
   292 	case EFbsMessUpdateLinkedTypeface:
       
   293 
   254 #ifdef _DEBUG
   294 #ifdef _DEBUG
   255 		FontBitmapServer()->ProcMessage(aMessage,iSessionHandle,iRet);
   295 		FontBitmapServer()->ProcMessage(aMessage,iSessionHandle,iRet);
   256 #else
   296 #else
   257 		FontBitmapServer()->ProcMessage(aMessage,iSessionHandle);
   297 		FontBitmapServer()->ProcMessage(aMessage,iSessionHandle);
   258 #endif			
   298 #endif			
   273 	case EFbsMessShapeText:
   313 	case EFbsMessShapeText:
   274 	case EFbsMessShapeDelete:
   314 	case EFbsMessShapeDelete:
   275 	case EFbsMessSetTwipsHeight:
   315 	case EFbsMessSetTwipsHeight:
   276 	case EFbsMessGetTwipsHeight:
   316 	case EFbsMessGetTwipsHeight:
   277 	case EFbsSetSystemDefaultTypefaceName:
   317 	case EFbsSetSystemDefaultTypefaceName:
       
   318 	case EFbsMessGetFontTable:
       
   319 	case EFbsMessReleaseFontTable:
       
   320 	case EFbsMessGetGlyphOutline:
       
   321 	case EFbsMessReleaseGlyphOutline: 
   278 #if (_DEBUG)
   322 #if (_DEBUG)
   279 	case EFbsMessSetDuplicateFail:
   323 	case EFbsMessSetDuplicateFail:
   280 #endif
   324 #endif
       
   325 	case EFbsMessGetGlyphs:
       
   326 	case EFbsMessGetGlyphMetrics:
   281 		ProcFontMessage(aMessage);
   327 		ProcFontMessage(aMessage);
   282 		break;
   328 		break;
   283 // bitmap messages
   329 // bitmap messages
   284 	case EFbsMessBitmapCreate:
   330 	case EFbsMessBitmapCreate:
   285 	case EFbsMessBitmapResize:
   331 	case EFbsMessBitmapResize:
   304 		ProcMemMessage(aMessage);
   350 		ProcMemMessage(aMessage);
   305 #else
   351 #else
   306 		aMessage.Complete(KErrNone);
   352 		aMessage.Complete(KErrNone);
   307 #endif	
   353 #endif	
   308 		break;
   354 		break;
       
   355 // Glyph Atlas messages (debug-only)
       
   356 	case EFbsMessAtlasFontCount:
       
   357 	case EFbsMessAtlasGlyphCount:
       
   358 #ifdef _DEBUG
       
   359 		ProcAtlasMessage(aMessage);
       
   360 #else
       
   361 		aMessage.Complete(KErrNotSupported);
       
   362 #endif
       
   363 		break;
       
   364     case EFbsMessOogmNotification:
       
   365 
       
   366         aMessage.Complete( HandleMesgOogmStatus( aMessage ) );
       
   367         break;
       
   368     case EFbsMessGetGlyphCacheMetrics:
       
   369 
       
   370         HandleMesgGlyphCacheMetrics( aMessage );
       
   371         break;
       
   372 
       
   373 //No-op message
       
   374 	case EFbsMessNoOp:
       
   375 #ifdef _DEBUG
       
   376 		iRet = KErrNone;
       
   377 #endif
       
   378 		aMessage.Complete(KErrNone);
       
   379 		break;
   309 	default:
   380 	default:
   310 		aMessage.Panic(KFBSERVPanicCategory,KErrArgument);
   381 		aMessage.Panic(KFBSERVPanicCategory,KErrArgument);
   311 		break;
   382 		break;
   312 		}
   383 		}
   313 #ifdef _DEBUG
   384 #ifdef _DEBUG
   371  */
   442  */
   372 TInt CFbClient::HandleMesgFontDuplicate(const RMessage2& aMessage, TBool& aPanicRequired)
   443 TInt CFbClient::HandleMesgFontDuplicate(const RMessage2& aMessage, TBool& aPanicRequired)
   373 	{
   444 	{
   374 #if _DEBUG
   445 #if _DEBUG
   375 	if (iFontDuplicateToFail)
   446 	if (iFontDuplicateToFail)
       
   447 		{
   376 		return KErrNoMemory; //return with this error since this error is possible
   448 		return KErrNoMemory; //return with this error since this error is possible
       
   449 		}
   377 #endif
   450 #endif
   378 	CFontObject* fontptr = (CFontObject*) aMessage.Int0();
   451 	CFontObject* fontptr = (CFontObject*) aMessage.Int0();
   379 	if(!TopLevelStore()->ValidFontHandle((TInt)fontptr))
   452 	if(!TopLevelStore()->ValidFontHandle((TInt)fontptr))
   380 		{
   453 		{
   381 		return KErrUnknown;
   454 		return KErrUnknown;
   382 		}
   455 		}
   383 
   456 
   384 	TPckgBuf<TFontInfo> foninfo;
   457 	TPckgBuf<TFontInfo> fontinfo;
   385 	TInt localhandle = 0;
   458 	TInt localhandle = 0;
   386 	TInt ret = fontptr->Open();
   459 	TInt ret = fontptr->Open();
   387 	if (ret != KErrNone)
   460 	if (ret != KErrNone)
   388 		{
   461 		{
   389 		return ret;
   462 		return ret;
   392 	if (ret != KErrNone)
   465 	if (ret != KErrNone)
   393 		{
   466 		{
   394 		fontptr->Close();
   467 		fontptr->Close();
   395 		return ret;
   468 		return ret;
   396 		}
   469 		}
   397 	CopyFontInfo(fontptr,localhandle,foninfo());
   470 	CopyFontInfo(fontptr,localhandle,fontinfo());
   398 	fontptr->iHeightInTwips = ((fontptr->iAddressPointer->HeightInPixels() * fontptr->iFontStore->iKPixelHeightInTwips) + 667) / 1000;
   471 	fontptr->iHeightInTwips = ((fontptr->iAddressPointer->HeightInPixels() * fontptr->iFontStore->iKPixelHeightInTwips) + 667) / 1000;
   399 	ret = aMessage.Write(1, foninfo);
   472 	ret = aMessage.Write(1, fontinfo);
   400 	if(ret != KErrNone)
   473 	if(ret != KErrNone)
   401 		{
   474 		{
   402 		iIx->Remove(localhandle);
   475 		iIx->Remove(localhandle);
   403 		aPanicRequired = ETrue;
   476 		aPanicRequired = ETrue;
   404 		return ret;
   477 		return ret;
   422 	CFontObject* fontptr = NULL;
   495 	CFontObject* fontptr = NULL;
   423 	TPckgBuf<TFontSpec> pckgFontSpec;
   496 	TPckgBuf<TFontSpec> pckgFontSpec;
   424 	TInt pckgMaxHeight;
   497 	TInt pckgMaxHeight;
   425 	TPckgBuf<TSizeInfo> info;
   498 	TPckgBuf<TSizeInfo> info;
   426 
   499 
   427 	const TFbsMessage	fbsMessage = static_cast<TFbsMessage>(aMessage.Function());
   500 	const TFbsMessage fbsMessage = static_cast<TFbsMessage>(aMessage.Function());
   428 
   501 
   429 	TInt ret = aMessage.Read(0, pckgFontSpec);
   502 	TInt ret = aMessage.Read(0, pckgFontSpec);
   430 	TFontSpec& fontSpec = pckgFontSpec();
   503 	TFontSpec& fontSpec = pckgFontSpec();
   431 	if (ret == KErrNone )
   504 	if (ret == KErrNone )
   432 		{
   505 		{
   433 		TInt length = fontSpec.iTypeface.iName.Length();
   506 		TInt length = fontSpec.iTypeface.iName.Length();
   434 		if(length < 0 || length > TOpenFontFaceAttribBase::ENameLength)
   507 		if((length < 0) || (length > TOpenFontFaceAttribBase::ENameLength))
   435 			{
   508 			{
   436 			aPanicRequired = ETrue;
   509 			aPanicRequired = ETrue;
   437 			return KErrArgument;
   510 			return KErrArgument;
   438 			}	
   511 			}	
   439 		
   512 		
   645 		return ETrue;
   718 		return ETrue;
   646 		}
   719 		}
   647 	return EFalse;
   720 	return EFalse;
   648 	}
   721 	}
   649 
   722 
       
   723 /** Handler for EFbsMessGetGlyphs message.
       
   724 Reads a batch of up to KMaxGlyphBatchSize glyph codes, and on success returns
       
   725 the corresponding TGlyphImageInfo objects.
       
   726  @param aMessage input parameters
       
   727  @param aPanicRequired flag that is set if a client panic is required
       
   728  @return KErrNone if successful, otherwise any system-wide error code.
       
   729  */
       
   730 TInt CFbClient::HandleMesgGetGlyphs(const RMessage2& aMessage, TBool& aPanicRequired)
       
   731 	{
       
   732 	CFbTop* fbtop = TopLevelStore();
       
   733 	// Previously requested glyphs were closed in ServiceL()
       
   734 	CGlyphAtlas* glyphAtlas = fbtop->GlyphAtlas();
       
   735 	if (!glyphAtlas)
       
   736 		{
       
   737 		return KErrNotSupported;
       
   738 		}
       
   739 	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
       
   740 	if(!fontptr)
       
   741 		{
       
   742 		aPanicRequired = ETrue;
       
   743 		return KErrBadHandle;
       
   744 		}
       
   745 
       
   746 	TUint glyphCodes[KMaxGlyphBatchSize];
       
   747 	TGlyphImageInfo glyphImageInfo[KMaxGlyphBatchSize];
       
   748 	TPckg<TUint[KMaxGlyphBatchSize]> glyphBatchPckg(glyphCodes);
       
   749 
       
   750 	TInt err = aMessage.Read(1, glyphBatchPckg);
       
   751 	if (err != KErrNone)
       
   752 		{
       
   753 		aPanicRequired = ETrue;
       
   754 		return err;
       
   755 		}
       
   756 	TInt glyphCodesCount = glyphBatchPckg.Length() / sizeof(TUint);
       
   757 	if (glyphCodesCount > KMaxGlyphBatchSize)
       
   758 		{
       
   759 		aPanicRequired = ETrue;
       
   760 		return KErrOverflow;
       
   761 		}
       
   762 
       
   763 	TInt glyphsProcessed = 0;
       
   764 	CBitmapFont* font = fontptr->iAddressPointer;
       
   765 	for (; (glyphsProcessed < glyphCodesCount); ++glyphsProcessed)
       
   766 		{
       
   767 		TUint32 glyphCode = glyphCodes[glyphsProcessed];
       
   768 		err = glyphAtlas->GetGlyph(*font, glyphCode, glyphImageInfo[glyphsProcessed]);
       
   769 		// Search for glyph in glyph atlas
       
   770 		if (KErrNone != err)
       
   771 			{
       
   772 			const TUint8* bitmapData = NULL;
       
   773 			TOpenFontCharMetrics metrics;
       
   774 			// search for glyph in font glyph cache and session cache.
       
   775 			if (!font->GetCharacterData(iSessionHandle, glyphCode | KTreatAsGlyphCodeFlag, metrics, bitmapData))
       
   776 				{
       
   777 				// Rasterize the glyph
       
   778 				if(!font->Rasterize(iSessionHandle, glyphCode | KTreatAsGlyphCodeFlag, iOpenFontGlyphData))
       
   779 					{
       
   780 					err = KErrNoMemory;
       
   781 					break;
       
   782 					}
       
   783 				metrics = *(iOpenFontGlyphData->Metrics());
       
   784 				bitmapData = iOpenFontGlyphData->BitmapPointer();
       
   785 				}
       
   786 			CGlyphAtlas::TAddGlyphArgs args(bitmapData, glyphCode, metrics);
       
   787 			err = glyphAtlas->AddGlyph(*font, args, glyphImageInfo[glyphsProcessed]);
       
   788 			}
       
   789 		if ((err == KErrNone) && (glyphImageInfo[glyphsProcessed].iImageId != KSgNullDrawableId))
       
   790 			{
       
   791 			// To prevent other threads closing the glyph image in the glyph atlas 
       
   792 			// before client has had chance to open the drawable id, open a local
       
   793 			// handle to the glyph image for the session, which will be closed either
       
   794 			// next time a request is made or when EFbsMessCloseGlyphs is handled.
       
   795 			RSgImage glyphImage;
       
   796 			err = glyphImage.Open(glyphImageInfo[glyphsProcessed].iImageId);
       
   797 			if (err == KErrNone)
       
   798 				{
       
   799 				err = iGlyphImagesInTransit.Append(glyphImage);
       
   800 				}
       
   801 			}
       
   802 		// If an error occurred during this iteration, abort now before the glyphsProcessed
       
   803 		// counter is incremented, which would give one too many processed glyphs.
       
   804 		if (KErrNone != err)
       
   805 			{
       
   806 			break;
       
   807 			}
       
   808 		}
       
   809 
       
   810 	// Even if there was an error, if at least one glyph was processed successfully
       
   811 	// send that back to the client, and reset the error code.
       
   812 	if (glyphsProcessed > 0)
       
   813 		{
       
   814 		TPckg<TGlyphImageInfo[KMaxGlyphBatchSize]> glyphImageInfoPckg(glyphImageInfo);
       
   815 		glyphImageInfoPckg.SetLength(glyphsProcessed * sizeof(TGlyphImageInfo));
       
   816 		err = aMessage.Write(2, glyphImageInfoPckg);
       
   817 		if (err != KErrNone)
       
   818 			{
       
   819 			aPanicRequired = ETrue;
       
   820 			return err;
       
   821 			}
       
   822 		}
       
   823 	else
       
   824 		{
       
   825 		// No glyphs being returned, so an error code must be returned.
       
   826 		__ASSERT_DEBUG(err != KErrNone, User::Panic(KFBSERVPanicCategory, err));
       
   827 		}
       
   828 	return err;
       
   829 	}
       
   830 
       
   831 /**
       
   832 Handler for EFbsMessGetGlyphMetrics message.
       
   833 Reads an array of glyph codes, and returns the offset from the heap base for the 
       
   834 corresponding metrics object.
       
   835 @pre The glyph codes have already been searched client-side in the font glyph
       
   836 	cache and the session cache.
       
   837 @param aMessage input parameters
       
   838 @param aPanicRequired flag that is set if a client panic is required
       
   839 @return KErrNone if successful, otherwise any system-wide error code.
       
   840  */
       
   841 TInt CFbClient::HandleMesgGetGlyphMetrics(const RMessage2& aMessage, TBool& aPanicRequired)
       
   842 	{
       
   843 	CFbTop* fbtop = TopLevelStore();
       
   844 	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
       
   845 	if(!fontptr)
       
   846 		{
       
   847 		aPanicRequired = ETrue;
       
   848 		return KErrBadHandle;
       
   849 		}
       
   850 	
       
   851 	TInt err = KErrNone;
       
   852 	TUint glyphCodes[KMaxMetricsBatchSize];
       
   853 	TPckg<TUint[KMaxMetricsBatchSize]> glyphBatchPckg(glyphCodes);
       
   854 	err = aMessage.Read(1, glyphBatchPckg);
       
   855 	if (err != KErrNone)
       
   856 		{
       
   857 		aPanicRequired = ETrue;
       
   858 		return err;
       
   859 		}
       
   860 	
       
   861 	TInt numGlyphCodes = glyphBatchPckg.Length() / sizeof(TUint);	
       
   862 	if (numGlyphCodes > KMaxMetricsBatchSize)
       
   863 		{
       
   864 		aPanicRequired = ETrue;
       
   865 		return KErrOverflow;
       
   866 		}
       
   867 	
       
   868 	CBitmapFont* font = fontptr->iAddressPointer;
       
   869 	const TInt heapbase = fbtop->HeapBase();
       
   870 
       
   871 	TInt glyphProcessed;
       
   872 	TInt glyphMetricsOffsets[KMaxMetricsBatchSize];
       
   873 	for (glyphProcessed = 0; (glyphProcessed < numGlyphCodes) && (err == KErrNone); ++glyphProcessed)
       
   874 		{
       
   875 		if (font->Rasterize(iSessionHandle, glyphCodes[glyphProcessed] | KTreatAsGlyphCodeFlag, iOpenFontGlyphData))
       
   876 			{
       
   877 			// Convert all pointers to be passed back to the client to offsets from
       
   878 			// the heap base so that they can be recreated client side relative to the
       
   879 			// client's heap base
       
   880 			glyphMetricsOffsets[glyphProcessed] = PointerToOffset(iOpenFontGlyphData->Metrics(), heapbase);
       
   881 			}
       
   882 		else
       
   883 			{
       
   884 			err = KErrNoMemory;
       
   885 			}
       
   886 		}
       
   887 
       
   888 	if (err == KErrNone)
       
   889 		{
       
   890 		TPckg<TInt[KMaxMetricsBatchSize]> glyphMetricsOffsetsPckg(glyphMetricsOffsets);
       
   891 		glyphMetricsOffsetsPckg.SetLength(glyphProcessed * sizeof(TInt));
       
   892 		err = aMessage.Write(2, glyphMetricsOffsetsPckg);
       
   893 		if (err != KErrNone)
       
   894 			{
       
   895 			aPanicRequired = ETrue;
       
   896 			}
       
   897 		}	
       
   898 	return err;
       
   899 	}
   650 
   900 
   651 /** Handler for EFbsMessFaceAttrib message
   901 /** Handler for EFbsMessFaceAttrib message
   652  @param aMessage Input and output parameters
   902  @param aMessage Input and output parameters
   653  @param aPanicRequired Flag that is set to ETrue if a client panic is required
   903  @param aPanicRequired Flag that is set to ETrue if a client panic is required
   654  @return ETrue if successful, EFalse or any system-wide error code if not successful.
   904  @return ETrue if successful, EFalse or any system-wide error code if not successful.
   662 		aPanicRequired = ETrue;
   912 		aPanicRequired = ETrue;
   663 		return KErrArgument;
   913 		return KErrArgument;
   664 		}
   914 		}
   665 	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
   915 	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
   666 
   916 
       
   917 	TInt ret = EFalse;
   667 	TPckgBuf<TOpenFontFaceAttrib> package;
   918 	TPckgBuf<TOpenFontFaceAttrib> package;
   668 	if ( (bitmapFont != NULL) && (bitmapFont->GetFaceAttrib(package())) )
   919 	if ( (bitmapFont != NULL) && (bitmapFont->GetFaceAttrib(package())) )
   669 		{
   920 		{
   670 		TInt ret = aMessage.Write(1,package);
   921 		ret = aMessage.Write(1,package);
   671 		if (ret == KErrNone)
   922 		if (ret == KErrNone)
   672 			{
   923 			{
   673 			return ETrue;
   924 			ret = ETrue;
   674 			}
   925 			}
   675 		else
   926 		else
   676 			{
   927 			{
   677 			aPanicRequired = ETrue;
   928 			aPanicRequired = ETrue;
   678 			return ret;
   929 			}
   679 			}
   930 		}
   680 		}
   931 	return ret;
   681 	return EFalse;
       
   682 	}
   932 	}
   683 
   933 
   684 
   934 
   685 /** Handler for EFbsMessHasCharacter message
   935 /** Handler for EFbsMessHasCharacter message
   686  @param aMessage Input parameters
   936  @param aMessage Input parameters
   718  */
   968  */
   719 TInt CFbClient::HandleMesgShapeText(const RMessage2& aMessage, TBool& aPanicRequired)
   969 TInt CFbClient::HandleMesgShapeText(const RMessage2& aMessage, TBool& aPanicRequired)
   720 	{
   970 	{
   721 	TInt error = KErrNone;
   971 	TInt error = KErrNone;
   722 	TShapeHeader* shape = 0;
   972 	TShapeHeader* shape = 0;
   723 	TPckgBuf<TShapeMessageParameters> sp;
       
   724 	if (aMessage.GetDesLength(2) != sizeof(TShapeMessageParameters))
   973 	if (aMessage.GetDesLength(2) != sizeof(TShapeMessageParameters))
   725 		{
   974 		{
   726 		aPanicRequired = ETrue;
   975 		aPanicRequired = ETrue;
   727 		return KErrArgument;
   976 		return KErrArgument;
   728 		}
   977 		}
   732 	if(!fontptr)
   981 	if(!fontptr)
   733 		{
   982 		{
   734 		aPanicRequired = ETrue;
   983 		aPanicRequired = ETrue;
   735 		return KErrArgument;
   984 		return KErrArgument;
   736 		}
   985 		}
   737 	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
       
   738 
   986 
   739 	TInt inputTextLength = aMessage.GetDesLength(1);
   987 	TInt inputTextLength = aMessage.GetDesLength(1);
   740 	if (inputTextLength < 0)
   988 	if (inputTextLength < 0)
   741 		{
   989 		{
   742 		error = inputTextLength;
   990 		error = inputTextLength;
   745 		}
   993 		}
   746 	else
   994 	else
   747 		{
   995 		{
   748 		iTextToShape.Zero();
   996 		iTextToShape.Zero();
   749 		if (iTextToShape.MaxLength() < inputTextLength)
   997 		if (iTextToShape.MaxLength() < inputTextLength)
       
   998 			{
   750 			error = iTextToShape.ReAlloc(inputTextLength);
   999 			error = iTextToShape.ReAlloc(inputTextLength);
       
  1000 			}
   751 		}
  1001 		}
   752 	if (error == KErrNone)
  1002 	if (error == KErrNone)
   753 		{
  1003 		{
   754 		error = aMessage.Read(1, iTextToShape);
  1004 		error = aMessage.Read(1, iTextToShape);
   755 		if (error != KErrNone)
  1005 		if (error != KErrNone)
   756 			{
  1006 			{
   757 			aPanicRequired = ETrue;
  1007 			aPanicRequired = ETrue;
   758 			return error;
  1008 			return error;
   759 			}
  1009 			}
       
  1010 		TPckgBuf<TShapeMessageParameters> sp;
   760 		error = aMessage.Read(2, sp);
  1011 		error = aMessage.Read(2, sp);
   761 		if (error != KErrNone)
  1012 		if (error != KErrNone)
   762 			{
  1013 			{
   763 			aPanicRequired = ETrue;
  1014 			aPanicRequired = ETrue;
   764 			return error;
  1015 			return error;
   765 			}
  1016 			}
       
  1017 		CBitmapFont* bitmapFont = fontptr->iAddressPointer;
   766 		TRAP(error, shape = bitmapFont->ShapeTextL(iTextToShape, iSessionHandle, sp()) );
  1018 		TRAP(error, shape = bitmapFont->ShapeTextL(iTextToShape, iSessionHandle, sp()) );
   767 		if (error == KErrNone)
  1019 		if (error == KErrNone)
   768 			{
  1020 			{
   769 			// Convert the pointer to be passed back to the client to an offset from
  1021 			// Convert the pointer to be passed back to the client to an offset from
   770 			// the heap base so that it can be recreated client side relative to the
  1022 			// the heap base so that it can be recreated client side relative to the
   799 
  1051 
   800 	bitmapFont->DeleteShape(iSessionHandle,shapeheader);
  1052 	bitmapFont->DeleteShape(iSessionHandle,shapeheader);
   801 	return KErrNone;
  1053 	return KErrNone;
   802 	}
  1054 	}
   803 
  1055 
       
  1056 TInt CFbClient::HandleMesgReleaseGlyphOutline(const RMessage2& aMessage, TBool& aPanicRequired)
       
  1057 	{
       
  1058 	TInt ret = KErrNone;
       
  1059 	CFbTop* fbtop = TopLevelStore();
       
  1060 	TPckgBuf<TFBSGlyphOutlineParam> params;
       
  1061 	ret = aMessage.Read(0, params);
       
  1062 	if (KErrNone != ret)
       
  1063 		{
       
  1064 		aPanicRequired = ETrue;
       
  1065 		return ret;
       
  1066 		}
       
  1067 	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(params().iHandle, fbtop->FontConUniqueID()));
       
  1068 	if(!fontptr)
       
  1069 		{
       
  1070 		aPanicRequired = ETrue;
       
  1071 		return KErrArgument;
       
  1072 		}
       
  1073 	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
       
  1074 
       
  1075 	TInt count = params().iCount;
       
  1076 	TUint *glyphCodes = (TUint *)User::Alloc(count * sizeof(TUint));
       
  1077 	if (NULL == glyphCodes)
       
  1078 		{
       
  1079 		return KErrNoMemory;
       
  1080 		}
       
  1081 	// copy the glyph codes out of the IPC buffer...
       
  1082 	TPtr8 ptr((TUint8 *)glyphCodes, count * sizeof(TUint), count * sizeof(TUint));
       
  1083 	ret = aMessage.Read(1, ptr);  
       
  1084 
       
  1085 	if (KErrNone == ret)
       
  1086 		{
       
  1087 		bitmapFont->ReleaseGlyphOutlines(count, glyphCodes,  
       
  1088 				params().iHinted, iSessionHandle);
       
  1089 		}
       
  1090 	else 
       
  1091 		{
       
  1092 		aPanicRequired = ETrue;
       
  1093 		}
       
  1094 
       
  1095 	User::Free(glyphCodes);
       
  1096 	return ret;
       
  1097 	}
       
  1098 
       
  1099 TInt CFbClient::HandleMesgGetGlyphOutline(const RMessage2& aMessage, TBool& aPanicRequired) 
       
  1100 	{
       
  1101 	TInt ret = KErrNone;
       
  1102 	CFbTop* fbtop = TopLevelStore();
       
  1103 	TPckgBuf<TFBSGlyphOutlineParam> params;
       
  1104 	ret = aMessage.Read(0, params);
       
  1105 	if (KErrNone != ret)
       
  1106 		{
       
  1107 		aPanicRequired = ETrue;
       
  1108 		return ret;
       
  1109 		}
       
  1110 	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(params().iHandle, fbtop->FontConUniqueID()));
       
  1111 	if(!fontptr)
       
  1112 		{
       
  1113 		aPanicRequired = ETrue;
       
  1114 		return KErrArgument;
       
  1115 		}
       
  1116 	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
       
  1117 
       
  1118 	TInt count = params().iCount;
       
  1119 	TUint* glyphCodes = (TUint *)User::Alloc(count * sizeof(TUint));
       
  1120 	if (NULL == glyphCodes)
       
  1121 		{
       
  1122 		return KErrNoMemory;
       
  1123 		}
       
  1124 	// copy the glyph codes out of the IPC buffer...
       
  1125 	TPtr8 ptr((TUint8 *)glyphCodes, count * sizeof(TUint), count * sizeof(TUint));
       
  1126 	ret = aMessage.Read(1, ptr);
       
  1127 	if (KErrNone != ret)
       
  1128 		{
       
  1129 		User::Free(glyphCodes);
       
  1130 		aPanicRequired = ETrue;
       
  1131 		return ret;
       
  1132 		}
       
  1133 
       
  1134 	TOffsetLen* offsetLens = 
       
  1135 		(TOffsetLen *)User::Alloc(count * sizeof(TOffsetLen));
       
  1136 	if (NULL == offsetLens)
       
  1137 		{
       
  1138 		User::Free(glyphCodes);
       
  1139 		return KErrNoMemory;
       
  1140 		}
       
  1141 
       
  1142 	TInt len = 0;
       
  1143 	TAny* outline = NULL;
       
  1144 	for (TInt i = 0; i < count; ++i)
       
  1145 		{
       
  1146 		bitmapFont->GetGlyphOutline(glyphCodes[i],  
       
  1147 			params().iHinted, outline, len, iSessionHandle);
       
  1148 		
       
  1149 		offsetLens[i].iLen = len;
       
  1150 		offsetLens[i].iOffset = PointerToOffset((outline), fbtop->HeapBase());
       
  1151 		}
       
  1152 	TPtr8 pkg2((TUint8 *)offsetLens, count * sizeof(TOffsetLen), 
       
  1153 			count * sizeof(TOffsetLen));
       
  1154 	ret = aMessage.Write(2, pkg2);
       
  1155 	if (KErrNone != ret)
       
  1156 		{
       
  1157 		aPanicRequired = ETrue;
       
  1158 		}
       
  1159 
       
  1160 	User::Free(glyphCodes);
       
  1161 	User::Free(offsetLens);
       
  1162 	return ret;  
       
  1163 	}
       
  1164 
       
  1165 TInt CFbClient::HandleMesgReleaseFontTable(const RMessage2& aMessage, TBool& aPanicRequired)
       
  1166 	{
       
  1167 	CFbTop* fbtop = TopLevelStore();
       
  1168 	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
       
  1169 	if(!fontptr)
       
  1170 		{
       
  1171 		aPanicRequired = ETrue;
       
  1172 		return KErrArgument;
       
  1173 		}
       
  1174 	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
       
  1175 
       
  1176 	TUint32 tag = aMessage.Int1();
       
  1177 
       
  1178 	bitmapFont->ReleaseFontTable(tag, iSessionHandle);
       
  1179 
       
  1180 	return KErrNone;
       
  1181 	}
       
  1182 
       
  1183 TInt CFbClient::HandleMesgGetFontTable(const RMessage2& aMessage, TBool& aPanicRequired)
       
  1184 	{
       
  1185 	TInt ret = KErrNone;
       
  1186 	CFbTop* fbtop = TopLevelStore();
       
  1187 	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
       
  1188 	if(!fontptr)
       
  1189 		{
       
  1190 		aPanicRequired = ETrue;
       
  1191 		return KErrArgument;
       
  1192 		}
       
  1193 	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
       
  1194 
       
  1195 	TInt len = 0;
       
  1196 	TAny* tablePtr = NULL;
       
  1197 	ret = bitmapFont->GetFontTable((TUint32)aMessage.Int1(), tablePtr, len, iSessionHandle);
       
  1198 
       
  1199 	if (KErrNone == ret) 
       
  1200 		{
       
  1201 		TPckgBuf<TOffsetLen> params;
       
  1202 		params().iLen = len;
       
  1203 		params().iOffset = PointerToOffset(tablePtr, fbtop->HeapBase());
       
  1204 		ret = aMessage.Write(2, params);
       
  1205 		aPanicRequired = (KErrNone != ret);
       
  1206 		}
       
  1207 
       
  1208 	return ret;
       
  1209 	}
       
  1210 
       
  1211 
       
  1212 /**
       
  1213  Called in response to the GoomMonitor framework's call into FbsOogmPlugin.
       
  1214  We wish to either free some GPU memory, or reinstate its normal usage.
       
  1215 
       
  1216 @param  aMessage The IPC message.
       
  1217 @return KErrNone If the value contained in the TFbsOogmMessage enumeration member is meaningful and the glyph atlas is present.
       
  1218         KErrNotSupported if there is no glyph atlas.
       
  1219         KErrUnknown if the value contained in the TFbsOogmMessage enumeration member is not meaningful.
       
  1220  */
       
  1221 TInt CFbClient::HandleMesgOogmStatus( const RMessage2& aMessage )
       
  1222     {
       
  1223     TInt ret = KErrNone;
       
  1224     CGlyphAtlas* glyphAtlas = TopLevelStore()->GlyphAtlas();
       
  1225 
       
  1226     if ( NULL == glyphAtlas )
       
  1227         {
       
  1228         return KErrNotSupported;
       
  1229         }
       
  1230 
       
  1231 
       
  1232     TPckgBuf<TFbsOogmMessage> oogmMessage;
       
  1233     aMessage.Read( 0, oogmMessage );
       
  1234 
       
  1235     switch( oogmMessage().iOogmNotification )
       
  1236         {
       
  1237     case TFbsOogmMessage::EFbsOogmNoAction:
       
  1238         break;
       
  1239 
       
  1240     case TFbsOogmMessage::EFbsOogmLowNotification:
       
  1241         {
       
  1242         glyphAtlas->ReleaseGpuMemory( oogmMessage().iBytesToFree, oogmMessage().iFlags );
       
  1243         }
       
  1244          break;
       
  1245 
       
  1246     case TFbsOogmMessage::EFbsOogmOkayNotification:
       
  1247         {
       
  1248         glyphAtlas->InstateGpuMemory( oogmMessage().iFlags );
       
  1249         }
       
  1250         break;
       
  1251 
       
  1252     default:
       
  1253         ret = KErrUnknown;
       
  1254         break;
       
  1255         }
       
  1256 
       
  1257     return ret;
       
  1258     }
       
  1259 
       
  1260 
       
  1261 void CFbClient::HandleMesgGlyphCacheMetrics( const RMessage2& aMessage )
       
  1262     {
       
  1263     CGlyphAtlas* glyphAtlas = TopLevelStore()->GlyphAtlas();
       
  1264     TPckgBuf<TGlyphCacheMetrics>  metrics;
       
  1265 
       
  1266     glyphAtlas->GetGlyphCacheMetrics( metrics() );
       
  1267 
       
  1268     aMessage.Complete( aMessage.Write(0, metrics) );
       
  1269     }
       
  1270 
   804 
  1271 
   805 void CFbClient::ProcFontMessage(const RMessage2& aMessage)
  1272 void CFbClient::ProcFontMessage(const RMessage2& aMessage)
   806 	{
  1273 	{
   807 	TInt ret = KErrUnknown;
  1274 	TInt ret = KErrNone;
   808 	TBool panicRequired = EFalse;
  1275 	TBool panicRequired = EFalse;
   809 
  1276 
   810 	switch(aMessage.Function())
  1277 	switch(aMessage.Function())
   811 		{
  1278 		{
   812 		case EFbsMessFontDuplicate:
  1279 		case EFbsMessFontDuplicate:
   909 				ret = KErrTooBig;
  1376 				ret = KErrTooBig;
   910 				}
  1377 				}
   911 
  1378 
   912 			break;
  1379 			break;
   913 			}
  1380 			}
       
  1381 		case EFbsMessGetFontTable:
       
  1382 			{
       
  1383 			ret = HandleMesgGetFontTable(aMessage, panicRequired);
       
  1384 			break;
       
  1385 			}
       
  1386 		case EFbsMessGetGlyphOutline:
       
  1387 			{
       
  1388 			ret = HandleMesgGetGlyphOutline(aMessage, panicRequired);
       
  1389 			break;
       
  1390 			}
       
  1391 		case EFbsMessReleaseGlyphOutline:
       
  1392 			{
       
  1393 			ret = HandleMesgReleaseGlyphOutline(aMessage, panicRequired);
       
  1394 			break;
       
  1395 			}
       
  1396 		case EFbsMessReleaseFontTable:
       
  1397 			{
       
  1398 			ret = HandleMesgReleaseFontTable(aMessage, panicRequired);
       
  1399 			break;
       
  1400 			}
       
  1401 		case EFbsMessGetGlyphs:
       
  1402 			{
       
  1403 			ret = HandleMesgGetGlyphs(aMessage, panicRequired);
       
  1404 			break;
       
  1405 			}
       
  1406 		case EFbsMessGetGlyphMetrics:
       
  1407 			{
       
  1408 			ret = HandleMesgGetGlyphMetrics(aMessage, panicRequired);
       
  1409 			break;
       
  1410 			}
   914 
  1411 
   915 #ifdef _DEBUG
  1412 #ifdef _DEBUG
   916 		case EFbsMessSetDuplicateFail:
  1413 		case EFbsMessSetDuplicateFail:
       
  1414 			{
   917 			TInt argument =aMessage.Int0();
  1415 			TInt argument =aMessage.Int0();
   918 			if (argument)
  1416 			if (argument)
   919 				{
  1417 				{
   920 				iFontDuplicateToFail = ETrue;
  1418 				iFontDuplicateToFail = ETrue;
   921 				}
  1419 				}
   923 				{
  1421 				{
   924 				iFontDuplicateToFail = EFalse;
  1422 				iFontDuplicateToFail = EFalse;
   925 				}
  1423 				}
   926 			ret=KErrNone;
  1424 			ret=KErrNone;
   927 			break;
  1425 			break;
       
  1426 			}
   928 #endif
  1427 #endif
       
  1428 		default:
       
  1429 			ret = KErrUnknown;
   929 		}
  1430 		}
   930 
  1431 
   931 	// either have a result or an error code to panic the client with
  1432 	// either have a result or an error code to panic the client with
   932 	if (panicRequired)
  1433 	if (panicRequired)
   933 		{
  1434 		{
   947 
  1448 
   948 void CFbClient::ProcBitmapMessage(const RMessage2 &aMessage)
  1449 void CFbClient::ProcBitmapMessage(const RMessage2 &aMessage)
   949 	{
  1450 	{
   950 	CBitmapObject* bmpptr=NULL;
  1451 	CBitmapObject* bmpptr=NULL;
   951 	TInt localhandle=0;
  1452 	TInt localhandle=0;
   952 	TInt ret=KErrUnknown;
  1453 	TInt ret = KErrNone;
   953 	switch(aMessage.Function())
  1454 	switch(aMessage.Function())
   954 		{
  1455 		{
   955 	case EFbsMessBitmapCreate:
  1456 	case EFbsMessBitmapCreate:
   956 		{
  1457 		{
   957 		TPckgBuf<TBmpSpec> bs;
  1458 		TPckgBuf<TBmpSpec> bs;
  1113 			ret=KErrUnknown;
  1614 			ret=KErrUnknown;
  1114 			break;
  1615 			break;
  1115 			}
  1616 			}
  1116 		ret = fbtop->GetCleanBitmap(bmpptr);
  1617 		ret = fbtop->GetCleanBitmap(bmpptr);
  1117 		if (ret != KErrNone)
  1618 		if (ret != KErrNone)
  1118 			break;
  1619 			{
       
  1620 			break;
       
  1621 			}
  1119 		TSize newsize(aMessage.Int1(),aMessage.Int2());
  1622 		TSize newsize(aMessage.Int1(),aMessage.Int2());
  1120  		const TBool compressedInRam = bmpptr->Address()->IsCompressedInRAM();  //It must be set before the resizing is done.
  1623  		const TBool compressedInRam = bmpptr->Address()->IsCompressedInRAM();  //It must be set before the resizing is done.
  1121 		const TDisplayMode dispMode = bmpptr->Address()->DisplayMode();
  1624 		const TDisplayMode dispMode = bmpptr->Address()->DisplayMode();
  1122 		CBitmapObject* newbmpptr = NULL;
  1625 		CBitmapObject* newbmpptr = NULL;
  1123 		TRAP(ret, newbmpptr = fbtop->CreateBitmapL(newsize, dispMode, KUidCFbsBitmapCreation, ETrue));
  1626 		TRAP(ret, newbmpptr = fbtop->CreateBitmapL(newsize, dispMode, KUidCFbsBitmapCreation, ETrue));
  1124 		if (ret != KErrNone)
  1627 		if (ret != KErrNone)
  1125 			break;
  1628 			{
       
  1629 			break;
       
  1630 			}
  1126 		ret = newbmpptr->Address()->CopyData(*bmpptr->Address());
  1631 		ret = newbmpptr->Address()->CopyData(*bmpptr->Address());
  1127 		if (ret != KErrNone)
  1632 		if (ret != KErrNone)
  1128 			{
  1633 			{
  1129 			newbmpptr->Close();
  1634 			newbmpptr->Close();
  1130 			break;
  1635 			break;
  1155 			iIx->Remove(newlocalhandle);
  1660 			iIx->Remove(newlocalhandle);
  1156 			break;
  1661 			break;
  1157 			}
  1662 			}
  1158 		bmpptr->SetCleanBitmap(newbmpptr);
  1663 		bmpptr->SetCleanBitmap(newbmpptr);
  1159 		if (bmpptr->AccessCount() >= 2)
  1664 		if (bmpptr->AccessCount() >= 2)
       
  1665 			{
  1160 			fbtop->NotifyDirtyBitmap(*bmpptr, this);
  1666 			fbtop->NotifyDirtyBitmap(*bmpptr, this);
       
  1667 			}
  1161 		iIx->Remove(localhandle);
  1668 		iIx->Remove(localhandle);
  1162 		TPckgBuf<TBmpHandles> handlebuffer;
  1669 		TPckgBuf<TBmpHandles> handlebuffer;
  1163 		handlebuffer().iHandle = newlocalhandle;
  1670 		handlebuffer().iHandle = newlocalhandle;
  1164 		handlebuffer().iServerHandle = newbmpptr->Handle();
  1671 		handlebuffer().iServerHandle = newbmpptr->Handle();
  1165 		handlebuffer().iAddressOffset = TInt(newbmpptr->Address()) - fbtop->HeapBase();
  1672 		handlebuffer().iAddressOffset = TInt(newbmpptr->Address()) - fbtop->HeapBase();
  1184 		//coverity [check_return]
  1691 		//coverity [check_return]
  1185 		//coverity [unchecked_value]
  1692 		//coverity [unchecked_value]
  1186 		TopLevelStore()->GetCleanBitmap(bmpptr);
  1693 		TopLevelStore()->GetCleanBitmap(bmpptr);
  1187 		ret = bmpptr->Open();
  1694 		ret = bmpptr->Open();
  1188 		if (ret != KErrNone)
  1695 		if (ret != KErrNone)
  1189 			break;
  1696 			{
       
  1697 			break;
       
  1698 			}
  1190 		TPckgBuf<TBmpHandles> handlebuffer;
  1699 		TPckgBuf<TBmpHandles> handlebuffer;
  1191 		TRAP(ret,localhandle=iIx->AddL(bmpptr));
  1700 		TRAP(ret,localhandle=iIx->AddL(bmpptr));
  1192 		if(ret!=KErrNone)
  1701 		if(ret!=KErrNone)
  1193 			{
  1702 			{
  1194 			bmpptr->Close();
  1703 			bmpptr->Close();
  1218 			ret = KErrUnknown;
  1727 			ret = KErrUnknown;
  1219 			break;
  1728 			break;
  1220 			}
  1729 			}
  1221 		ret = fbtop->GetCleanBitmap(bmpptr);
  1730 		ret = fbtop->GetCleanBitmap(bmpptr);
  1222 		if (ret != KErrNone)
  1731 		if (ret != KErrNone)
  1223 			break;
  1732 			{
       
  1733 			break;
       
  1734 			}
  1224 		const TSize size = bmpptr->Address()->SizeInPixels();
  1735 		const TSize size = bmpptr->Address()->SizeInPixels();
  1225 		const TDisplayMode dispMode = bmpptr->Address()->DisplayMode();
  1736 		const TDisplayMode dispMode = bmpptr->Address()->DisplayMode();
  1226 		CBitmapObject* newbmpptr = NULL;
  1737 		CBitmapObject* newbmpptr = NULL;
  1227 		TRAP(ret, newbmpptr = fbtop->CreateBitmapL(size, dispMode, KUidCFbsBitmapCreation, ETrue));
  1738 		TRAP(ret, newbmpptr = fbtop->CreateBitmapL(size, dispMode, KUidCFbsBitmapCreation, ETrue));
  1228 		if (ret != KErrNone)
  1739 		if (ret != KErrNone)
  1229 			break;
  1740 			{
       
  1741 			break;
       
  1742 			}
  1230 		ret = newbmpptr->Address()->CopyData(*bmpptr->Address());
  1743 		ret = newbmpptr->Address()->CopyData(*bmpptr->Address());
  1231 		if (ret != KErrNone)
  1744 		if (ret != KErrNone)
  1232 			{
  1745 			{
  1233 			newbmpptr->Close();
  1746 			newbmpptr->Close();
  1234 			break;
  1747 			break;
  1252 			iIx->Remove(newlocalhandle);
  1765 			iIx->Remove(newlocalhandle);
  1253 			break;
  1766 			break;
  1254 			}
  1767 			}
  1255 		bmpptr->SetCleanBitmap(newbmpptr);
  1768 		bmpptr->SetCleanBitmap(newbmpptr);
  1256 		if (bmpptr->AccessCount() >= 2)
  1769 		if (bmpptr->AccessCount() >= 2)
       
  1770 			{
  1257 			fbtop->NotifyDirtyBitmap(*bmpptr, this);
  1771 			fbtop->NotifyDirtyBitmap(*bmpptr, this);
       
  1772 			}
  1258 		iIx->Remove(localhandle);
  1773 		iIx->Remove(localhandle);
  1259 		TPckgBuf<TBmpHandles> handlebuffer;
  1774 		TPckgBuf<TBmpHandles> handlebuffer;
  1260 		handlebuffer().iHandle = newlocalhandle;
  1775 		handlebuffer().iHandle = newlocalhandle;
  1261 		handlebuffer().iServerHandle = newbmpptr->Handle();
  1776 		handlebuffer().iServerHandle = newbmpptr->Handle();
  1262 		handlebuffer().iAddressOffset = TInt(newbmpptr->Address()) - fbtop->HeapBase();
  1777 		handlebuffer().iAddressOffset = TInt(newbmpptr->Address()) - fbtop->HeapBase();
  1284 			}
  1799 			}
  1285 		ret = fbtop->GetCleanBitmap(bmpptr);
  1800 		ret = fbtop->GetCleanBitmap(bmpptr);
  1286 		if (ret != KErrNone)
  1801 		if (ret != KErrNone)
  1287 			{
  1802 			{
  1288 			if (!async)
  1803 			if (!async)
       
  1804 				{
  1289 				ret = KErrNone;
  1805 				ret = KErrNone;
       
  1806 				}
  1290 			break;
  1807 			break;
  1291 			}
  1808 			}
  1292 		ret = bmpptr->Address()->CheckBackgroundCompressData();
  1809 		ret = bmpptr->Address()->CheckBackgroundCompressData();
  1293 		if (KErrNone == ret)
  1810 		if (KErrNone == ret)
  1294 			{
  1811 			{
  1295 			ret = fbtop->BackgroundCompression()->AddToCompressionQueue(bmpptr, scheme, async ? &aMessage : NULL);
  1812 			ret = fbtop->BackgroundCompression()->AddToCompressionQueue(bmpptr, scheme, async ? &aMessage : NULL);
  1296 			if (ret == KErrNone && async)
  1813 			if (ret == KErrNone && async)
       
  1814 				{
  1297 				return; // do not complete the client's request - that will be done by the background compression thread
  1815 				return; // do not complete the client's request - that will be done by the background compression thread
       
  1816 				}
  1298 			}
  1817 			}
  1299 		if (KErrAlreadyExists == ret)
  1818 		if (KErrAlreadyExists == ret)
       
  1819 			{
  1300 			ret = KErrNone;
  1820 			ret = KErrNone;
       
  1821 			}
  1301 		break;
  1822 		break;
  1302 		}
  1823 		}
  1303 	case EFbsMessBitmapClean:
  1824 	case EFbsMessBitmapClean:
  1304 		{
  1825 		{
  1305 		TInt localhandle = aMessage.Int0();
  1826 		TInt localhandle = aMessage.Int0();
  1310 			ret = KErrUnknown;
  1831 			ret = KErrUnknown;
  1311 			break;
  1832 			break;
  1312 			}
  1833 			}
  1313 		ret = fbtop->GetCleanBitmap(bmpptr);
  1834 		ret = fbtop->GetCleanBitmap(bmpptr);
  1314 		if (ret != KErrNone)
  1835 		if (ret != KErrNone)
  1315 			break;
  1836 			{
       
  1837 			break;
       
  1838 			}
  1316 		ret = bmpptr->Open();
  1839 		ret = bmpptr->Open();
  1317 		if (ret != KErrNone)
  1840 		if (ret != KErrNone)
  1318 			break;
  1841 			{
       
  1842 			break;
       
  1843 			}
  1319 		TInt cleanlocalhandle = 0;
  1844 		TInt cleanlocalhandle = 0;
  1320 		TRAP(ret, cleanlocalhandle = iIx->AddL(bmpptr));
  1845 		TRAP(ret, cleanlocalhandle = iIx->AddL(bmpptr));
  1321 		if (ret != KErrNone)
  1846 		if (ret != KErrNone)
  1322 			{
  1847 			{
  1323 			bmpptr->Close();
  1848 			bmpptr->Close();
  1364 		if (!iHelper->iDirty)
  1889 		if (!iHelper->iDirty)
  1365 			{
  1890 			{
  1366 			iHelper->iMessage = aMessage;
  1891 			iHelper->iMessage = aMessage;
  1367 			return; // do not complete the client's request yet - that will be done when a bitmap becomes dirty
  1892 			return; // do not complete the client's request yet - that will be done when a bitmap becomes dirty
  1368 			}
  1893 			}
  1369 		ret = KErrNone;
       
  1370 		iHelper->iDirty = EFalse;
  1894 		iHelper->iDirty = EFalse;
  1371 		}
  1895 		}
  1372 		break;
  1896 		break;
  1373 	case EFbsMessBitmapCancelNotifyDirty:
  1897 	case EFbsMessBitmapCancelNotifyDirty:
  1374 		{
  1898 		{
  1375 		if (iHelper != NULL && !iHelper->iMessage.IsNull())
  1899 		if (iHelper != NULL && !iHelper->iMessage.IsNull())
       
  1900 			{
  1376 			iHelper->iMessage.Complete(KErrCancel);
  1901 			iHelper->iMessage.Complete(KErrCancel);
  1377 		ret = KErrNone;
  1902 			}
  1378 		}
  1903 		}
  1379 		break;
  1904 		break;
       
  1905 	default:
       
  1906 		ret = KErrUnknown;
  1380 		}
  1907 		}
  1381 		
  1908 		
  1382 	if(!aMessage.IsNull())
  1909 	if(!aMessage.IsNull())
  1383 		{
  1910 		{
  1384 		aMessage.Complete(ret);
  1911 		aMessage.Complete(ret);
  1450 
  1977 
  1451 	// if there is a to-be-completed request for dirty bitmap notification complete it now
  1978 	// if there is a to-be-completed request for dirty bitmap notification complete it now
  1452 	if (iHelper)
  1979 	if (iHelper)
  1453 		{
  1980 		{
  1454 		if (!iHelper->iMessage.IsNull())
  1981 		if (!iHelper->iMessage.IsNull())
       
  1982 			{
  1455 			iHelper->iMessage.Complete(KErrDisconnected);
  1983 			iHelper->iMessage.Complete(KErrDisconnected);
       
  1984 			}
  1456 		iHelper->Deque();
  1985 		iHelper->Deque();
  1457 		delete iHelper;
  1986 		delete iHelper;
  1458 		iHelper = NULL;
  1987 		iHelper = NULL;
  1459 		}
  1988 		}
  1460 
  1989 
  1512 				iHeapCheckFlip=ETrue;
  2041 				iHeapCheckFlip=ETrue;
  1513 				}
  2042 				}
  1514 			break;
  2043 			break;
  1515 		case EFbsMessHeap:
  2044 		case EFbsMessHeap:
  1516 			ret=(TInt)iHeap;
  2045 			ret=(TInt)iHeap;
  1517 			break;			
  2046 			break;
       
  2047 		default:
       
  2048 			ret = KErrUnknown;
  1518 		}
  2049 		}
  1519 	aMessage.Complete(ret);
  2050 	aMessage.Complete(ret);
  1520 	iRet=ret;
  2051 	iRet=ret;
  1521 	}
  2052 	}
       
  2053 
       
  2054 /**
       
  2055 Processes messages associated with the Glyph Atlas.
       
  2056 @param aMessage The message used to perform IPC to the client.
       
  2057  */
       
  2058 void CFbClient::ProcAtlasMessage(const RMessage2 &aMessage)
       
  2059 	{
       
  2060 	TInt ret = KErrNone;
       
  2061 	CFbTop* fbtop = TopLevelStore();
       
  2062 	CGlyphAtlas* glyphAtlas = fbtop->GlyphAtlas();
       
  2063 	if (!glyphAtlas)
       
  2064 		{
       
  2065 		ret = KErrNotSupported;
       
  2066 		}
       
  2067 	else
       
  2068 		{
       
  2069 		switch(aMessage.Function())
       
  2070 			{
       
  2071 			case EFbsMessAtlasFontCount:
       
  2072 				ret = glyphAtlas->FontCount();
       
  2073 				break;
       
  2074 			case EFbsMessAtlasGlyphCount:
       
  2075 				{
       
  2076 				TInt fontHandle = aMessage.Int0();
       
  2077 				if (fontHandle != 0)
       
  2078 					{
       
  2079 					if (fbtop->ValidFontHandle(fontHandle))
       
  2080 						{
       
  2081 						CFontObject* fontptr = reinterpret_cast<CFontObject*>(fontHandle);
       
  2082 						ret = glyphAtlas->GlyphCount(static_cast<CBitmapFont&>(*(fontptr->iAddressPointer)));
       
  2083 						}
       
  2084 					else
       
  2085 						{
       
  2086 						ret = KErrNotFound;
       
  2087 						}
       
  2088 					}
       
  2089 				else
       
  2090 					{
       
  2091 					ret = glyphAtlas->GlyphCount();
       
  2092 					}
       
  2093 				}
       
  2094 				break;
       
  2095 			default:
       
  2096 				ret = KErrUnknown;
       
  2097 			}
       
  2098 		}
       
  2099 	aMessage.Complete(ret);
       
  2100 	iRet=ret;
       
  2101 	}
  1522 #endif
  2102 #endif