fbs/fontandbitmapserver/sfbs/FBSCLI.CPP
branchRCL_3
changeset 20 25ffed67c7ef
parent 19 bbf46f59e123
child 21 183e23d95fab
equal deleted inserted replaced
19:bbf46f59e123 20:25ffed67c7ef
    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"
       
    21 #include "SERVER.H"
    20 #include "SERVER.H"
    22 #include "BackGroundCompression.h"
    21 #include "BackGroundCompression.h"
    23 #include <shapeinfo.h>
    22 #include <shapeinfo.h>
    24 #include <graphics/shaperparams.h>
    23 #include <graphics/shaperparams.h>
    25 #include "glyphatlas.h"
       
    26 #include "OstTraceDefinitions.h"
    24 #include "OstTraceDefinitions.h"
    27 #include "fbstrace.h"
    25 #include "fbstrace.h"
    28 #ifdef OST_TRACE_COMPILER_IN_USE
    26 #ifdef OST_TRACE_COMPILER_IN_USE
    29 #include "FBSCLITraces.h"
    27 #include "FBSCLITraces.h"
    30 #endif
    28 #endif
    31 
    29 
    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;
       
    38 
    30 
    39 /** Helper function for converting a pointer to an offset from the passed
    31 /** Helper function for converting a pointer to an offset from the passed
    40 heap base. Use OffsetToPointer() to convert the returned offset back to a
    32 heap base. Use OffsetToPointer() to convert the returned offset back to a
    41 useable pointer.
    33 useable pointer.
    42 @param aAny A pointer to be converted to an offset.
    34 @param aAny A pointer to be converted to an offset.
    45 back to a pointer using the function OffsetToPointer(). 
    37 back to a pointer using the function OffsetToPointer(). 
    46 @see OffsetToPointer()
    38 @see OffsetToPointer()
    47  */
    39  */
    48 LOCAL_C TInt PointerToOffset(const TAny* aAny, TInt aHeapBase)
    40 LOCAL_C TInt PointerToOffset(const TAny* aAny, TInt aHeapBase)
    49 	{
    41 	{
    50 	TInt offset = 0;
       
    51 	if (aAny && aHeapBase)
    42 	if (aAny && aHeapBase)
    52 		{
    43 		{
    53 		offset = reinterpret_cast<TInt>(aAny) - aHeapBase;
    44 		return reinterpret_cast<TInt>(aAny) - aHeapBase;
    54 		}
    45 		}
    55 	return offset;
    46 	return 0;
    56 	}
    47 	}
    57 
    48 
    58 /** Helper function for converting an offset (that was calculated using
    49 /** Helper function for converting an offset (that was calculated using
    59 PointerToOffset()) back to a pointer relative to the passed heap base.
    50 PointerToOffset()) back to a pointer relative to the passed heap base.
    60 @param aOffset The offset to be converted to a pointer.
    51 @param aOffset The offset to be converted to a pointer.
    71 	return NULL;
    62 	return NULL;
    72 	}
    63 	}
    73 
    64 
    74 CFbClient::CFbClient(RHeap* aHeap):
    65 CFbClient::CFbClient(RHeap* aHeap):
    75 	CSession2(),
    66 	CSession2(),
       
    67 	iConnectionHandle(0),
       
    68 	iIx(NULL),
       
    69 	iResourceCount(0),
    76 	iHeap(aHeap)
    70 	iHeap(aHeap)
    77 #ifdef _DEBUG
    71 #ifdef _DEBUG
    78 	,iOwnHeapFailNumber(-1),
    72 	,iOwnHeapFailNumber(-1),
    79 	iSharedHeapFailNumber(-1)
    73 	iSharedHeapFailNumber(-1)
    80 #endif	
    74 #endif	
    81 	{
    75 	{
    82 	}
    76 	}
    83 
    77 
    84 CFbClient* CFbClient::NewL(RHeap* aHeap)
    78 CFbClient* CFbClient::NewL(RHeap* aHeap)
    85 	{
    79 	{
    86 	CFbClient* self = new (ELeave) CFbClient(aHeap);
    80 	CFbClient* c = new(ELeave) CFbClient(aHeap);
    87 	CleanupStack::PushL(self);
    81 	c->iOpenFontGlyphData = TOpenFontGlyphData::New(aHeap,4 * 1024);
    88 	self->ConstructL();
    82 	if (!c->iOpenFontGlyphData)
    89 	CleanupStack::Pop(); // self;
    83 		{
    90 	return self;
    84 		delete c;
    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 		{
       
   102 		User::Leave(KErrNoMemory);
    85 		User::Leave(KErrNoMemory);
   103 		}
    86 		}
       
    87 	return c;
   104 	}
    88 	}
   105 
    89 
   106 CFbClient::~CFbClient()
    90 CFbClient::~CFbClient()
   107 	{
    91 	{
   108 	/*
    92 	/*
   115 		{
    99 		{
   116 		font_store = fbTop->FontStore();
   100 		font_store = fbTop->FontStore();
   117 		}
   101 		}
   118 	
   102 	
   119 	if (font_store)
   103 	if (font_store)
   120 		{
       
   121 		font_store->DeleteSessionCache(iSessionHandle);
   104 		font_store->DeleteSessionCache(iSessionHandle);
   122 		font_store->CleanupCacheOnFbsSessionTermination(iSessionHandle);
   105 	
   123 		
   106 	// If the font store doesn't exist, neither will the shared heap owned by FBSERV.
   124 		// If the font store doesn't exist, neither will the shared heap owned by FBSERV.
   107 	if (font_store)
   125 		iHeap->Free(iOpenFontGlyphData);
   108 		iHeap->Free(iOpenFontGlyphData);
   126 		}
       
   127 	
   109 	
   128 	// delete fonts held by the client
   110 	// delete fonts hold by the client
   129 	delete iIx;
   111 	delete iIx;
   130 	
   112 	
   131 	// delete font files held by the client
   113 	// delete font files hold by the client
   132 	if (iFontFileIndex)
   114     if (iFontFileIndex)
   133 		{
   115         {
   134 		TInt count = iFontFileIndex->Count();
   116         TInt count = iFontFileIndex->Count();
   135 		for (TInt index = 0;index < count; index++)
   117         for (TInt index = 0;index < count; index++)
   136 			{
   118             {
   137 			if (font_store)
   119             if (font_store)
   138 				{
   120                 font_store->RemoveFile(iFontFileIndex->At(0).iUid);
   139 				font_store->RemoveFile(iFontFileIndex->At(0).iUid);
   121             iFontFileIndex->Delete(0);
   140 				}
   122             }
   141 			iFontFileIndex->Delete(0);
   123         delete iFontFileIndex;
   142 			}
   124         }
   143 		delete iFontFileIndex;
   125 
   144 		}
   126 	// Close the buffer used to hold the text thats needs shaping.
   145 
       
   146 	// Close the buffer used to hold the text that needs shaping.
       
   147 	iTextToShape.Close();
   127 	iTextToShape.Close();
   148 
       
   149 	for (TInt i = iGlyphImagesInTransit.Count() - 1; i >= 0; --i)
       
   150 		{
       
   151 		iGlyphImagesInTransit[i].Close();
       
   152 		}
       
   153 	iGlyphImagesInTransit.Close();
       
   154 	}
   128 	}
   155 
   129 
   156 void CFbClient::Init(TUint aConnectionHandle)
   130 void CFbClient::Init(TUint aConnectionHandle)
   157 	{
   131 	{
   158 	iConnectionHandle=aConnectionHandle;
   132 	iConnectionHandle=aConnectionHandle;
   171 
   145 
   172 CFbTop* CFbClient::TopLevelStore()
   146 CFbTop* CFbClient::TopLevelStore()
   173 	{
   147 	{
   174 	CFontBitmapServer* server = FontBitmapServer();
   148 	CFontBitmapServer* server = FontBitmapServer();
   175 	if (server)
   149 	if (server)
   176 		{
       
   177 		return server->TopLevelStore();
   150 		return server->TopLevelStore();
   178 		}
       
   179 	else
   151 	else
   180 		{
       
   181 		return NULL;
   152 		return NULL;
   182 		}
       
   183 	}
   153 	}
   184 
   154 
   185 void CFbClient::CopyFontInfo(CFontObject* aFontObjPtr,TInt aHandle,TFontInfo& aFontInfo)
   155 void CFbClient::CopyFontInfo(CFontObject* aFontObjPtr,TInt aHandle,TFontInfo& aFontInfo)
   186 	{
   156 	{
   187 	CBitmapFont* font=aFontObjPtr->iAddressPointer;
   157 	CBitmapFont* font=aFontObjPtr->iAddressPointer;
   190 	aFontInfo.iAddressOffset=TInt(font)-TopLevelStore()->HeapBase();
   160 	aFontInfo.iAddressOffset=TInt(font)-TopLevelStore()->HeapBase();
   191 	}
   161 	}
   192 
   162 
   193 void CFbClient::ServiceL(const RMessage2& aMessage)
   163 void CFbClient::ServiceL(const RMessage2& aMessage)
   194 	{
   164 	{
   195 
       
   196 #ifdef _DEBUG
   165 #ifdef _DEBUG
   197 	TBool resetOwnHeap=EFalse;
   166 	TBool resetOwnHeap=EFalse;
   198 	TBool resetSharedHeap=EFalse;
   167 	TBool resetSharedHeap=EFalse;
   199 	
   168 	
   200 	//the memory tests have been mostly written to have start and end memory
   169 	//the memory tests have been mostly written to have start and end memory
   222 	if (iHeapCheck)
   191 	if (iHeapCheck)
   223 		{
   192 		{
   224 		__RHEAP_MARK(iHeap);
   193 		__RHEAP_MARK(iHeap);
   225 		}		
   194 		}		
   226 #endif		
   195 #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 		}
       
   235 	
   196 	
   236 	switch(aMessage.Function())
   197 	switch(aMessage.Function())
   237 		{
   198 		{
   238 // client messages
   199 // client messages
   239 	case EFbsMessInit:
   200 	case EFbsMessInit:
   288 	case EFbsMessDefaultLanguageForMetrics:
   249 	case EFbsMessDefaultLanguageForMetrics:
   289 	case EFbsCompress:
   250 	case EFbsCompress:
   290 	case EFbsMessFetchLinkedTypeface:
   251 	case EFbsMessFetchLinkedTypeface:
   291 	case EFbsMessRegisterLinkedTypeface:
   252 	case EFbsMessRegisterLinkedTypeface:
   292 	case EFbsMessUpdateLinkedTypeface:
   253 	case EFbsMessUpdateLinkedTypeface:
   293 
       
   294 #ifdef _DEBUG
   254 #ifdef _DEBUG
   295 		FontBitmapServer()->ProcMessage(aMessage,iSessionHandle,iRet);
   255 		FontBitmapServer()->ProcMessage(aMessage,iSessionHandle,iRet);
   296 #else
   256 #else
   297 		FontBitmapServer()->ProcMessage(aMessage,iSessionHandle);
   257 		FontBitmapServer()->ProcMessage(aMessage,iSessionHandle);
   298 #endif			
   258 #endif			
   313 	case EFbsMessShapeText:
   273 	case EFbsMessShapeText:
   314 	case EFbsMessShapeDelete:
   274 	case EFbsMessShapeDelete:
   315 	case EFbsMessSetTwipsHeight:
   275 	case EFbsMessSetTwipsHeight:
   316 	case EFbsMessGetTwipsHeight:
   276 	case EFbsMessGetTwipsHeight:
   317 	case EFbsSetSystemDefaultTypefaceName:
   277 	case EFbsSetSystemDefaultTypefaceName:
   318 	case EFbsMessGetFontTable:
       
   319 	case EFbsMessReleaseFontTable:
       
   320 	case EFbsMessGetGlyphOutline:
       
   321 	case EFbsMessReleaseGlyphOutline: 
       
   322 #if (_DEBUG)
   278 #if (_DEBUG)
   323 	case EFbsMessSetDuplicateFail:
   279 	case EFbsMessSetDuplicateFail:
   324 #endif
   280 #endif
   325 	case EFbsMessGetGlyphs:
       
   326 	case EFbsMessGetGlyphMetrics:
       
   327 		ProcFontMessage(aMessage);
   281 		ProcFontMessage(aMessage);
   328 		break;
   282 		break;
   329 // bitmap messages
   283 // bitmap messages
   330 	case EFbsMessBitmapCreate:
   284 	case EFbsMessBitmapCreate:
   331 	case EFbsMessBitmapResize:
   285 	case EFbsMessBitmapResize:
   350 		ProcMemMessage(aMessage);
   304 		ProcMemMessage(aMessage);
   351 #else
   305 #else
   352 		aMessage.Complete(KErrNone);
   306 		aMessage.Complete(KErrNone);
   353 #endif	
   307 #endif	
   354 		break;
   308 		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;
       
   380 	default:
   309 	default:
   381 		aMessage.Panic(KFBSERVPanicCategory,KErrArgument);
   310 		aMessage.Panic(KFBSERVPanicCategory,KErrArgument);
   382 		break;
   311 		break;
   383 		}
   312 		}
   384 #ifdef _DEBUG
   313 #ifdef _DEBUG
   442  */
   371  */
   443 TInt CFbClient::HandleMesgFontDuplicate(const RMessage2& aMessage, TBool& aPanicRequired)
   372 TInt CFbClient::HandleMesgFontDuplicate(const RMessage2& aMessage, TBool& aPanicRequired)
   444 	{
   373 	{
   445 #if _DEBUG
   374 #if _DEBUG
   446 	if (iFontDuplicateToFail)
   375 	if (iFontDuplicateToFail)
   447 		{
       
   448 		return KErrNoMemory; //return with this error since this error is possible
   376 		return KErrNoMemory; //return with this error since this error is possible
   449 		}
       
   450 #endif
   377 #endif
   451 	CFontObject* fontptr = (CFontObject*) aMessage.Int0();
   378 	CFontObject* fontptr = (CFontObject*) aMessage.Int0();
   452 	if(!TopLevelStore()->ValidFontHandle((TInt)fontptr))
   379 	if(!TopLevelStore()->ValidFontHandle((TInt)fontptr))
   453 		{
   380 		{
   454 		return KErrUnknown;
   381 		return KErrUnknown;
   455 		}
   382 		}
   456 
   383 
   457 	TPckgBuf<TFontInfo> fontinfo;
   384 	TPckgBuf<TFontInfo> foninfo;
   458 	TInt localhandle = 0;
   385 	TInt localhandle = 0;
   459 	TInt ret = fontptr->Open();
   386 	TInt ret = fontptr->Open();
   460 	if (ret != KErrNone)
   387 	if (ret != KErrNone)
   461 		{
   388 		{
   462 		return ret;
   389 		return ret;
   465 	if (ret != KErrNone)
   392 	if (ret != KErrNone)
   466 		{
   393 		{
   467 		fontptr->Close();
   394 		fontptr->Close();
   468 		return ret;
   395 		return ret;
   469 		}
   396 		}
   470 	CopyFontInfo(fontptr,localhandle,fontinfo());
   397 	CopyFontInfo(fontptr,localhandle,foninfo());
   471 	fontptr->iHeightInTwips = ((fontptr->iAddressPointer->HeightInPixels() * fontptr->iFontStore->iKPixelHeightInTwips) + 667) / 1000;
   398 	fontptr->iHeightInTwips = ((fontptr->iAddressPointer->HeightInPixels() * fontptr->iFontStore->iKPixelHeightInTwips) + 667) / 1000;
   472 	ret = aMessage.Write(1, fontinfo);
   399 	ret = aMessage.Write(1, foninfo);
   473 	if(ret != KErrNone)
   400 	if(ret != KErrNone)
   474 		{
   401 		{
   475 		iIx->Remove(localhandle);
   402 		iIx->Remove(localhandle);
   476 		aPanicRequired = ETrue;
   403 		aPanicRequired = ETrue;
   477 		return ret;
   404 		return ret;
   495 	CFontObject* fontptr = NULL;
   422 	CFontObject* fontptr = NULL;
   496 	TPckgBuf<TFontSpec> pckgFontSpec;
   423 	TPckgBuf<TFontSpec> pckgFontSpec;
   497 	TInt pckgMaxHeight;
   424 	TInt pckgMaxHeight;
   498 	TPckgBuf<TSizeInfo> info;
   425 	TPckgBuf<TSizeInfo> info;
   499 
   426 
   500 	const TFbsMessage fbsMessage = static_cast<TFbsMessage>(aMessage.Function());
   427 	const TFbsMessage	fbsMessage = static_cast<TFbsMessage>(aMessage.Function());
   501 
   428 
   502 	TInt ret = aMessage.Read(0, pckgFontSpec);
   429 	TInt ret = aMessage.Read(0, pckgFontSpec);
   503 	TFontSpec& fontSpec = pckgFontSpec();
   430 	TFontSpec& fontSpec = pckgFontSpec();
   504 	if (ret == KErrNone )
   431 	if (ret == KErrNone )
   505 		{
   432 		{
   506 		TInt length = fontSpec.iTypeface.iName.Length();
   433 		TInt length = fontSpec.iTypeface.iName.Length();
   507 		if((length < 0) || (length > TOpenFontFaceAttribBase::ENameLength))
   434 		if(length < 0 || length > TOpenFontFaceAttribBase::ENameLength)
   508 			{
   435 			{
   509 			aPanicRequired = ETrue;
   436 			aPanicRequired = ETrue;
   510 			return KErrArgument;
   437 			return KErrArgument;
   511 			}	
   438 			}	
   512 		
   439 		
   718 		return ETrue;
   645 		return ETrue;
   719 		}
   646 		}
   720 	return EFalse;
   647 	return EFalse;
   721 	}
   648 	}
   722 
   649 
   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 	}
       
   900 
   650 
   901 /** Handler for EFbsMessFaceAttrib message
   651 /** Handler for EFbsMessFaceAttrib message
   902  @param aMessage Input and output parameters
   652  @param aMessage Input and output parameters
   903  @param aPanicRequired Flag that is set to ETrue if a client panic is required
   653  @param aPanicRequired Flag that is set to ETrue if a client panic is required
   904  @return ETrue if successful, EFalse or any system-wide error code if not successful.
   654  @return ETrue if successful, EFalse or any system-wide error code if not successful.
   912 		aPanicRequired = ETrue;
   662 		aPanicRequired = ETrue;
   913 		return KErrArgument;
   663 		return KErrArgument;
   914 		}
   664 		}
   915 	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
   665 	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
   916 
   666 
   917 	TInt ret = EFalse;
       
   918 	TPckgBuf<TOpenFontFaceAttrib> package;
   667 	TPckgBuf<TOpenFontFaceAttrib> package;
   919 	if ( (bitmapFont != NULL) && (bitmapFont->GetFaceAttrib(package())) )
   668 	if ( (bitmapFont != NULL) && (bitmapFont->GetFaceAttrib(package())) )
   920 		{
   669 		{
   921 		ret = aMessage.Write(1,package);
   670 		TInt ret = aMessage.Write(1,package);
   922 		if (ret == KErrNone)
   671 		if (ret == KErrNone)
   923 			{
   672 			{
   924 			ret = ETrue;
   673 			return ETrue;
   925 			}
   674 			}
   926 		else
   675 		else
   927 			{
   676 			{
   928 			aPanicRequired = ETrue;
   677 			aPanicRequired = ETrue;
   929 			}
   678 			return ret;
   930 		}
   679 			}
   931 	return ret;
   680 		}
       
   681 	return EFalse;
   932 	}
   682 	}
   933 
   683 
   934 
   684 
   935 /** Handler for EFbsMessHasCharacter message
   685 /** Handler for EFbsMessHasCharacter message
   936  @param aMessage Input parameters
   686  @param aMessage Input parameters
   968  */
   718  */
   969 TInt CFbClient::HandleMesgShapeText(const RMessage2& aMessage, TBool& aPanicRequired)
   719 TInt CFbClient::HandleMesgShapeText(const RMessage2& aMessage, TBool& aPanicRequired)
   970 	{
   720 	{
   971 	TInt error = KErrNone;
   721 	TInt error = KErrNone;
   972 	TShapeHeader* shape = 0;
   722 	TShapeHeader* shape = 0;
       
   723 	TPckgBuf<TShapeMessageParameters> sp;
   973 	if (aMessage.GetDesLength(2) != sizeof(TShapeMessageParameters))
   724 	if (aMessage.GetDesLength(2) != sizeof(TShapeMessageParameters))
   974 		{
   725 		{
   975 		aPanicRequired = ETrue;
   726 		aPanicRequired = ETrue;
   976 		return KErrArgument;
   727 		return KErrArgument;
   977 		}
   728 		}
   981 	if(!fontptr)
   732 	if(!fontptr)
   982 		{
   733 		{
   983 		aPanicRequired = ETrue;
   734 		aPanicRequired = ETrue;
   984 		return KErrArgument;
   735 		return KErrArgument;
   985 		}
   736 		}
       
   737 	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
   986 
   738 
   987 	TInt inputTextLength = aMessage.GetDesLength(1);
   739 	TInt inputTextLength = aMessage.GetDesLength(1);
   988 	if (inputTextLength < 0)
   740 	if (inputTextLength < 0)
   989 		{
   741 		{
   990 		error = inputTextLength;
   742 		error = inputTextLength;
   993 		}
   745 		}
   994 	else
   746 	else
   995 		{
   747 		{
   996 		iTextToShape.Zero();
   748 		iTextToShape.Zero();
   997 		if (iTextToShape.MaxLength() < inputTextLength)
   749 		if (iTextToShape.MaxLength() < inputTextLength)
   998 			{
       
   999 			error = iTextToShape.ReAlloc(inputTextLength);
   750 			error = iTextToShape.ReAlloc(inputTextLength);
  1000 			}
       
  1001 		}
   751 		}
  1002 	if (error == KErrNone)
   752 	if (error == KErrNone)
  1003 		{
   753 		{
  1004 		error = aMessage.Read(1, iTextToShape);
   754 		error = aMessage.Read(1, iTextToShape);
  1005 		if (error != KErrNone)
   755 		if (error != KErrNone)
  1006 			{
   756 			{
  1007 			aPanicRequired = ETrue;
   757 			aPanicRequired = ETrue;
  1008 			return error;
   758 			return error;
  1009 			}
   759 			}
  1010 		TPckgBuf<TShapeMessageParameters> sp;
       
  1011 		error = aMessage.Read(2, sp);
   760 		error = aMessage.Read(2, sp);
  1012 		if (error != KErrNone)
   761 		if (error != KErrNone)
  1013 			{
   762 			{
  1014 			aPanicRequired = ETrue;
   763 			aPanicRequired = ETrue;
  1015 			return error;
   764 			return error;
  1016 			}
   765 			}
  1017 		CBitmapFont* bitmapFont = fontptr->iAddressPointer;
       
  1018 		TRAP(error, shape = bitmapFont->ShapeTextL(iTextToShape, iSessionHandle, sp()) );
   766 		TRAP(error, shape = bitmapFont->ShapeTextL(iTextToShape, iSessionHandle, sp()) );
  1019 		if (error == KErrNone)
   767 		if (error == KErrNone)
  1020 			{
   768 			{
  1021 			// Convert the pointer to be passed back to the client to an offset from
   769 			// Convert the pointer to be passed back to the client to an offset from
  1022 			// the heap base so that it can be recreated client side relative to the
   770 			// the heap base so that it can be recreated client side relative to the
  1051 
   799 
  1052 	bitmapFont->DeleteShape(iSessionHandle,shapeheader);
   800 	bitmapFont->DeleteShape(iSessionHandle,shapeheader);
  1053 	return KErrNone;
   801 	return KErrNone;
  1054 	}
   802 	}
  1055 
   803 
  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 
       
  1271 
   804 
  1272 void CFbClient::ProcFontMessage(const RMessage2& aMessage)
   805 void CFbClient::ProcFontMessage(const RMessage2& aMessage)
  1273 	{
   806 	{
  1274 	TInt ret = KErrNone;
   807 	TInt ret = KErrUnknown;
  1275 	TBool panicRequired = EFalse;
   808 	TBool panicRequired = EFalse;
  1276 
   809 
  1277 	switch(aMessage.Function())
   810 	switch(aMessage.Function())
  1278 		{
   811 		{
  1279 		case EFbsMessFontDuplicate:
   812 		case EFbsMessFontDuplicate:
  1376 				ret = KErrTooBig;
   909 				ret = KErrTooBig;
  1377 				}
   910 				}
  1378 
   911 
  1379 			break;
   912 			break;
  1380 			}
   913 			}
  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 			}
       
  1411 
   914 
  1412 #ifdef _DEBUG
   915 #ifdef _DEBUG
  1413 		case EFbsMessSetDuplicateFail:
   916 		case EFbsMessSetDuplicateFail:
  1414 			{
       
  1415 			TInt argument =aMessage.Int0();
   917 			TInt argument =aMessage.Int0();
  1416 			if (argument)
   918 			if (argument)
  1417 				{
   919 				{
  1418 				iFontDuplicateToFail = ETrue;
   920 				iFontDuplicateToFail = ETrue;
  1419 				}
   921 				}
  1421 				{
   923 				{
  1422 				iFontDuplicateToFail = EFalse;
   924 				iFontDuplicateToFail = EFalse;
  1423 				}
   925 				}
  1424 			ret=KErrNone;
   926 			ret=KErrNone;
  1425 			break;
   927 			break;
  1426 			}
       
  1427 #endif
   928 #endif
  1428 		default:
       
  1429 			ret = KErrUnknown;
       
  1430 		}
   929 		}
  1431 
   930 
  1432 	// either have a result or an error code to panic the client with
   931 	// either have a result or an error code to panic the client with
  1433 	if (panicRequired)
   932 	if (panicRequired)
  1434 		{
   933 		{
  1448 
   947 
  1449 void CFbClient::ProcBitmapMessage(const RMessage2 &aMessage)
   948 void CFbClient::ProcBitmapMessage(const RMessage2 &aMessage)
  1450 	{
   949 	{
  1451 	CBitmapObject* bmpptr=NULL;
   950 	CBitmapObject* bmpptr=NULL;
  1452 	TInt localhandle=0;
   951 	TInt localhandle=0;
  1453 	TInt ret = KErrNone;
   952 	TInt ret=KErrUnknown;
  1454 	switch(aMessage.Function())
   953 	switch(aMessage.Function())
  1455 		{
   954 		{
  1456 	case EFbsMessBitmapCreate:
   955 	case EFbsMessBitmapCreate:
  1457 		{
   956 		{
  1458 		TPckgBuf<TBmpSpec> bs;
   957 		TPckgBuf<TBmpSpec> bs;
  1614 			ret=KErrUnknown;
  1113 			ret=KErrUnknown;
  1615 			break;
  1114 			break;
  1616 			}
  1115 			}
  1617 		ret = fbtop->GetCleanBitmap(bmpptr);
  1116 		ret = fbtop->GetCleanBitmap(bmpptr);
  1618 		if (ret != KErrNone)
  1117 		if (ret != KErrNone)
  1619 			{
  1118 			break;
  1620 			break;
       
  1621 			}
       
  1622 		TSize newsize(aMessage.Int1(),aMessage.Int2());
  1119 		TSize newsize(aMessage.Int1(),aMessage.Int2());
  1623  		const TBool compressedInRam = bmpptr->Address()->IsCompressedInRAM();  //It must be set before the resizing is done.
  1120  		const TBool compressedInRam = bmpptr->Address()->IsCompressedInRAM();  //It must be set before the resizing is done.
  1624 		const TDisplayMode dispMode = bmpptr->Address()->DisplayMode();
  1121 		const TDisplayMode dispMode = bmpptr->Address()->DisplayMode();
  1625 		CBitmapObject* newbmpptr = NULL;
  1122 		CBitmapObject* newbmpptr = NULL;
  1626 		TRAP(ret, newbmpptr = fbtop->CreateBitmapL(newsize, dispMode, KUidCFbsBitmapCreation, ETrue));
  1123 		TRAP(ret, newbmpptr = fbtop->CreateBitmapL(newsize, dispMode, KUidCFbsBitmapCreation, ETrue));
  1627 		if (ret != KErrNone)
  1124 		if (ret != KErrNone)
  1628 			{
  1125 			break;
  1629 			break;
       
  1630 			}
       
  1631 		ret = newbmpptr->Address()->CopyData(*bmpptr->Address());
  1126 		ret = newbmpptr->Address()->CopyData(*bmpptr->Address());
  1632 		if (ret != KErrNone)
  1127 		if (ret != KErrNone)
  1633 			{
  1128 			{
  1634 			newbmpptr->Close();
  1129 			newbmpptr->Close();
  1635 			break;
  1130 			break;
  1660 			iIx->Remove(newlocalhandle);
  1155 			iIx->Remove(newlocalhandle);
  1661 			break;
  1156 			break;
  1662 			}
  1157 			}
  1663 		bmpptr->SetCleanBitmap(newbmpptr);
  1158 		bmpptr->SetCleanBitmap(newbmpptr);
  1664 		if (bmpptr->AccessCount() >= 2)
  1159 		if (bmpptr->AccessCount() >= 2)
  1665 			{
       
  1666 			fbtop->NotifyDirtyBitmap(*bmpptr, this);
  1160 			fbtop->NotifyDirtyBitmap(*bmpptr, this);
  1667 			}
       
  1668 		iIx->Remove(localhandle);
  1161 		iIx->Remove(localhandle);
  1669 		TPckgBuf<TBmpHandles> handlebuffer;
  1162 		TPckgBuf<TBmpHandles> handlebuffer;
  1670 		handlebuffer().iHandle = newlocalhandle;
  1163 		handlebuffer().iHandle = newlocalhandle;
  1671 		handlebuffer().iServerHandle = newbmpptr->Handle();
  1164 		handlebuffer().iServerHandle = newbmpptr->Handle();
  1672 		handlebuffer().iAddressOffset = TInt(newbmpptr->Address()) - fbtop->HeapBase();
  1165 		handlebuffer().iAddressOffset = TInt(newbmpptr->Address()) - fbtop->HeapBase();
  1691 		//coverity [check_return]
  1184 		//coverity [check_return]
  1692 		//coverity [unchecked_value]
  1185 		//coverity [unchecked_value]
  1693 		TopLevelStore()->GetCleanBitmap(bmpptr);
  1186 		TopLevelStore()->GetCleanBitmap(bmpptr);
  1694 		ret = bmpptr->Open();
  1187 		ret = bmpptr->Open();
  1695 		if (ret != KErrNone)
  1188 		if (ret != KErrNone)
  1696 			{
  1189 			break;
  1697 			break;
       
  1698 			}
       
  1699 		TPckgBuf<TBmpHandles> handlebuffer;
  1190 		TPckgBuf<TBmpHandles> handlebuffer;
  1700 		TRAP(ret,localhandle=iIx->AddL(bmpptr));
  1191 		TRAP(ret,localhandle=iIx->AddL(bmpptr));
  1701 		if(ret!=KErrNone)
  1192 		if(ret!=KErrNone)
  1702 			{
  1193 			{
  1703 			bmpptr->Close();
  1194 			bmpptr->Close();
  1727 			ret = KErrUnknown;
  1218 			ret = KErrUnknown;
  1728 			break;
  1219 			break;
  1729 			}
  1220 			}
  1730 		ret = fbtop->GetCleanBitmap(bmpptr);
  1221 		ret = fbtop->GetCleanBitmap(bmpptr);
  1731 		if (ret != KErrNone)
  1222 		if (ret != KErrNone)
  1732 			{
  1223 			break;
  1733 			break;
       
  1734 			}
       
  1735 		const TSize size = bmpptr->Address()->SizeInPixels();
  1224 		const TSize size = bmpptr->Address()->SizeInPixels();
  1736 		const TDisplayMode dispMode = bmpptr->Address()->DisplayMode();
  1225 		const TDisplayMode dispMode = bmpptr->Address()->DisplayMode();
  1737 		CBitmapObject* newbmpptr = NULL;
  1226 		CBitmapObject* newbmpptr = NULL;
  1738 		TRAP(ret, newbmpptr = fbtop->CreateBitmapL(size, dispMode, KUidCFbsBitmapCreation, ETrue));
  1227 		TRAP(ret, newbmpptr = fbtop->CreateBitmapL(size, dispMode, KUidCFbsBitmapCreation, ETrue));
  1739 		if (ret != KErrNone)
  1228 		if (ret != KErrNone)
  1740 			{
  1229 			break;
  1741 			break;
       
  1742 			}
       
  1743 		ret = newbmpptr->Address()->CopyData(*bmpptr->Address());
  1230 		ret = newbmpptr->Address()->CopyData(*bmpptr->Address());
  1744 		if (ret != KErrNone)
  1231 		if (ret != KErrNone)
  1745 			{
  1232 			{
  1746 			newbmpptr->Close();
  1233 			newbmpptr->Close();
  1747 			break;
  1234 			break;
  1765 			iIx->Remove(newlocalhandle);
  1252 			iIx->Remove(newlocalhandle);
  1766 			break;
  1253 			break;
  1767 			}
  1254 			}
  1768 		bmpptr->SetCleanBitmap(newbmpptr);
  1255 		bmpptr->SetCleanBitmap(newbmpptr);
  1769 		if (bmpptr->AccessCount() >= 2)
  1256 		if (bmpptr->AccessCount() >= 2)
  1770 			{
       
  1771 			fbtop->NotifyDirtyBitmap(*bmpptr, this);
  1257 			fbtop->NotifyDirtyBitmap(*bmpptr, this);
  1772 			}
       
  1773 		iIx->Remove(localhandle);
  1258 		iIx->Remove(localhandle);
  1774 		TPckgBuf<TBmpHandles> handlebuffer;
  1259 		TPckgBuf<TBmpHandles> handlebuffer;
  1775 		handlebuffer().iHandle = newlocalhandle;
  1260 		handlebuffer().iHandle = newlocalhandle;
  1776 		handlebuffer().iServerHandle = newbmpptr->Handle();
  1261 		handlebuffer().iServerHandle = newbmpptr->Handle();
  1777 		handlebuffer().iAddressOffset = TInt(newbmpptr->Address()) - fbtop->HeapBase();
  1262 		handlebuffer().iAddressOffset = TInt(newbmpptr->Address()) - fbtop->HeapBase();
  1799 			}
  1284 			}
  1800 		ret = fbtop->GetCleanBitmap(bmpptr);
  1285 		ret = fbtop->GetCleanBitmap(bmpptr);
  1801 		if (ret != KErrNone)
  1286 		if (ret != KErrNone)
  1802 			{
  1287 			{
  1803 			if (!async)
  1288 			if (!async)
  1804 				{
       
  1805 				ret = KErrNone;
  1289 				ret = KErrNone;
  1806 				}
       
  1807 			break;
  1290 			break;
  1808 			}
  1291 			}
  1809 		ret = bmpptr->Address()->CheckBackgroundCompressData();
  1292 		ret = bmpptr->Address()->CheckBackgroundCompressData();
  1810 		if (KErrNone == ret)
  1293 		if (KErrNone == ret)
  1811 			{
  1294 			{
  1812 			ret = fbtop->BackgroundCompression()->AddToCompressionQueue(bmpptr, scheme, async ? &aMessage : NULL);
  1295 			ret = fbtop->BackgroundCompression()->AddToCompressionQueue(bmpptr, scheme, async ? &aMessage : NULL);
  1813 			if (ret == KErrNone && async)
  1296 			if (ret == KErrNone && async)
  1814 				{
       
  1815 				return; // do not complete the client's request - that will be done by the background compression thread
  1297 				return; // do not complete the client's request - that will be done by the background compression thread
  1816 				}
       
  1817 			}
  1298 			}
  1818 		if (KErrAlreadyExists == ret)
  1299 		if (KErrAlreadyExists == ret)
  1819 			{
       
  1820 			ret = KErrNone;
  1300 			ret = KErrNone;
  1821 			}
       
  1822 		break;
  1301 		break;
  1823 		}
  1302 		}
  1824 	case EFbsMessBitmapClean:
  1303 	case EFbsMessBitmapClean:
  1825 		{
  1304 		{
  1826 		TInt localhandle = aMessage.Int0();
  1305 		TInt localhandle = aMessage.Int0();
  1831 			ret = KErrUnknown;
  1310 			ret = KErrUnknown;
  1832 			break;
  1311 			break;
  1833 			}
  1312 			}
  1834 		ret = fbtop->GetCleanBitmap(bmpptr);
  1313 		ret = fbtop->GetCleanBitmap(bmpptr);
  1835 		if (ret != KErrNone)
  1314 		if (ret != KErrNone)
  1836 			{
  1315 			break;
  1837 			break;
       
  1838 			}
       
  1839 		ret = bmpptr->Open();
  1316 		ret = bmpptr->Open();
  1840 		if (ret != KErrNone)
  1317 		if (ret != KErrNone)
  1841 			{
  1318 			break;
  1842 			break;
       
  1843 			}
       
  1844 		TInt cleanlocalhandle = 0;
  1319 		TInt cleanlocalhandle = 0;
  1845 		TRAP(ret, cleanlocalhandle = iIx->AddL(bmpptr));
  1320 		TRAP(ret, cleanlocalhandle = iIx->AddL(bmpptr));
  1846 		if (ret != KErrNone)
  1321 		if (ret != KErrNone)
  1847 			{
  1322 			{
  1848 			bmpptr->Close();
  1323 			bmpptr->Close();
  1889 		if (!iHelper->iDirty)
  1364 		if (!iHelper->iDirty)
  1890 			{
  1365 			{
  1891 			iHelper->iMessage = aMessage;
  1366 			iHelper->iMessage = aMessage;
  1892 			return; // do not complete the client's request yet - that will be done when a bitmap becomes dirty
  1367 			return; // do not complete the client's request yet - that will be done when a bitmap becomes dirty
  1893 			}
  1368 			}
       
  1369 		ret = KErrNone;
  1894 		iHelper->iDirty = EFalse;
  1370 		iHelper->iDirty = EFalse;
  1895 		}
  1371 		}
  1896 		break;
  1372 		break;
  1897 	case EFbsMessBitmapCancelNotifyDirty:
  1373 	case EFbsMessBitmapCancelNotifyDirty:
  1898 		{
  1374 		{
  1899 		if (iHelper != NULL && !iHelper->iMessage.IsNull())
  1375 		if (iHelper != NULL && !iHelper->iMessage.IsNull())
  1900 			{
       
  1901 			iHelper->iMessage.Complete(KErrCancel);
  1376 			iHelper->iMessage.Complete(KErrCancel);
  1902 			}
  1377 		ret = KErrNone;
  1903 		}
  1378 		}
  1904 		break;
  1379 		break;
  1905 	default:
       
  1906 		ret = KErrUnknown;
       
  1907 		}
  1380 		}
  1908 		
  1381 		
  1909 	if(!aMessage.IsNull())
  1382 	if(!aMessage.IsNull())
  1910 		{
  1383 		{
  1911 		aMessage.Complete(ret);
  1384 		aMessage.Complete(ret);
  1977 
  1450 
  1978 	// if there is a to-be-completed request for dirty bitmap notification complete it now
  1451 	// if there is a to-be-completed request for dirty bitmap notification complete it now
  1979 	if (iHelper)
  1452 	if (iHelper)
  1980 		{
  1453 		{
  1981 		if (!iHelper->iMessage.IsNull())
  1454 		if (!iHelper->iMessage.IsNull())
  1982 			{
       
  1983 			iHelper->iMessage.Complete(KErrDisconnected);
  1455 			iHelper->iMessage.Complete(KErrDisconnected);
  1984 			}
       
  1985 		iHelper->Deque();
  1456 		iHelper->Deque();
  1986 		delete iHelper;
  1457 		delete iHelper;
  1987 		iHelper = NULL;
  1458 		iHelper = NULL;
  1988 		}
  1459 		}
  1989 
  1460 
  2041 				iHeapCheckFlip=ETrue;
  1512 				iHeapCheckFlip=ETrue;
  2042 				}
  1513 				}
  2043 			break;
  1514 			break;
  2044 		case EFbsMessHeap:
  1515 		case EFbsMessHeap:
  2045 			ret=(TInt)iHeap;
  1516 			ret=(TInt)iHeap;
  2046 			break;
  1517 			break;			
  2047 		default:
       
  2048 			ret = KErrUnknown;
       
  2049 		}
  1518 		}
  2050 	aMessage.Complete(ret);
  1519 	aMessage.Complete(ret);
  2051 	iRet=ret;
  1520 	iRet=ret;
  2052 	}
  1521 	}
  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 	}
       
  2102 #endif
  1522 #endif