--- a/fbs/fontandbitmapserver/sfbs/FBSCLI.CPP Tue Jun 22 15:21:29 2010 +0300
+++ b/fbs/fontandbitmapserver/sfbs/FBSCLI.CPP Tue Jul 20 13:27:44 2010 +0300
@@ -16,11 +16,20 @@
#include <fntstore.h>
#include <bitmap.h>
#include <openfont.h>
+#include <graphics/fbsoogmmessage.h>
#include "FbsMessage.H"
#include "SERVER.H"
#include "BackGroundCompression.h"
#include <shapeinfo.h>
#include <graphics/shaperparams.h>
+#include "glyphatlas.h"
+
+
+/**
+Bitwise mask that sets the MSB to indicate to a font rasterizer
+that a code is a glyphcode and not a character code
+*/
+const TUint32 KTreatAsGlyphCodeFlag = 1UL << 31;
/** Helper function for converting a pointer to an offset from the passed
heap base. Use OffsetToPointer() to convert the returned offset back to a
@@ -33,11 +42,12 @@
*/
LOCAL_C TInt PointerToOffset(const TAny* aAny, TInt aHeapBase)
{
+ TInt offset = 0;
if (aAny && aHeapBase)
{
- return reinterpret_cast<TInt>(aAny) - aHeapBase;
+ offset = reinterpret_cast<TInt>(aAny) - aHeapBase;
}
- return 0;
+ return offset;
}
/** Helper function for converting an offset (that was calculated using
@@ -58,9 +68,6 @@
CFbClient::CFbClient(RHeap* aHeap):
CSession2(),
- iConnectionHandle(0),
- iIx(NULL),
- iResourceCount(0),
iHeap(aHeap)
#ifdef _DEBUG
,iOwnHeapFailNumber(-1),
@@ -71,14 +78,24 @@
CFbClient* CFbClient::NewL(RHeap* aHeap)
{
- CFbClient* c = new(ELeave) CFbClient(aHeap);
- c->iOpenFontGlyphData = TOpenFontGlyphData::New(aHeap,4 * 1024);
- if (!c->iOpenFontGlyphData)
+ CFbClient* self = new (ELeave) CFbClient(aHeap);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(); // self;
+ return self;
+ }
+
+/**
+Two-phase constructor.
+@leave KErrNoMemory if TOpenFontGlyphData construction failed.
+*/
+void CFbClient::ConstructL()
+ {
+ iOpenFontGlyphData = TOpenFontGlyphData::New(iHeap, 4 * 1024);
+ if (!iOpenFontGlyphData)
{
- delete c;
User::Leave(KErrNoMemory);
}
- return c;
}
CFbClient::~CFbClient()
@@ -103,24 +120,32 @@
iHeap->Free(iOpenFontGlyphData);
}
- // delete fonts hold by the client
+ // delete fonts held by the client
delete iIx;
- // delete font files hold by the client
+ // delete font files held by the client
if (iFontFileIndex)
{
TInt count = iFontFileIndex->Count();
for (TInt index = 0;index < count; index++)
{
if (font_store)
+ {
font_store->RemoveFile(iFontFileIndex->At(0).iUid);
+ }
iFontFileIndex->Delete(0);
}
delete iFontFileIndex;
}
- // Close the buffer used to hold the text thats needs shaping.
+ // Close the buffer used to hold the text that needs shaping.
iTextToShape.Close();
+
+ for (TInt i = iGlyphImagesInTransit.Count() - 1; i >= 0; --i)
+ {
+ iGlyphImagesInTransit[i].Close();
+ }
+ iGlyphImagesInTransit.Close();
}
void CFbClient::Init(TUint aConnectionHandle)
@@ -143,9 +168,13 @@
{
CFontBitmapServer* server = FontBitmapServer();
if (server)
+ {
return server->TopLevelStore();
+ }
else
+ {
return NULL;
+ }
}
void CFbClient::CopyFontInfo(CFontObject* aFontObjPtr,TInt aHandle,TFontInfo& aFontInfo)
@@ -158,6 +187,7 @@
void CFbClient::ServiceL(const RMessage2& aMessage)
{
+
#ifdef _DEBUG
TBool resetOwnHeap=EFalse;
TBool resetSharedHeap=EFalse;
@@ -189,6 +219,14 @@
__RHEAP_MARK(iHeap);
}
#endif
+ //Call close on RSgImage handles being used to share glyph data with clients.
+ //The glyph images are held open to prevent the GlyphAtlas from closing them
+ //before a client can use them.
+ for (TInt i = iGlyphImagesInTransit.Count() - 1; i >= 0; --i)
+ {
+ iGlyphImagesInTransit[i].Close();
+ iGlyphImagesInTransit.Remove(i);
+ }
switch(aMessage.Function())
{
@@ -246,6 +284,7 @@
case EFbsMessFetchLinkedTypeface:
case EFbsMessRegisterLinkedTypeface:
case EFbsMessUpdateLinkedTypeface:
+
#ifdef _DEBUG
FontBitmapServer()->ProcMessage(aMessage,iSessionHandle,iRet);
#else
@@ -277,6 +316,8 @@
#if (_DEBUG)
case EFbsMessSetDuplicateFail:
#endif
+ case EFbsMessGetGlyphs:
+ case EFbsMessGetGlyphMetrics:
ProcFontMessage(aMessage);
break;
// bitmap messages
@@ -305,6 +346,31 @@
aMessage.Complete(KErrNone);
#endif
break;
+// Glyph Atlas messages (debug-only)
+ case EFbsMessAtlasFontCount:
+ case EFbsMessAtlasGlyphCount:
+#ifdef _DEBUG
+ ProcAtlasMessage(aMessage);
+#else
+ aMessage.Complete(KErrNotSupported);
+#endif
+ break;
+ case EFbsMessOogmNotification:
+
+ aMessage.Complete( HandleMesgOogmStatus( aMessage ) );
+ break;
+ case EFbsMessGetGlyphCacheMetrics:
+
+ HandleMesgGlyphCacheMetrics( aMessage );
+ break;
+
+//No-op message
+ case EFbsMessNoOp:
+#ifdef _DEBUG
+ iRet = KErrNone;
+#endif
+ aMessage.Complete(KErrNone);
+ break;
default:
aMessage.Panic(KFBSERVPanicCategory,KErrArgument);
break;
@@ -372,7 +438,9 @@
{
#if _DEBUG
if (iFontDuplicateToFail)
+ {
return KErrNoMemory; //return with this error since this error is possible
+ }
#endif
CFontObject* fontptr = (CFontObject*) aMessage.Int0();
if(!TopLevelStore()->ValidFontHandle((TInt)fontptr))
@@ -380,7 +448,7 @@
return KErrUnknown;
}
- TPckgBuf<TFontInfo> foninfo;
+ TPckgBuf<TFontInfo> fontinfo;
TInt localhandle = 0;
TInt ret = fontptr->Open();
if (ret != KErrNone)
@@ -393,9 +461,9 @@
fontptr->Close();
return ret;
}
- CopyFontInfo(fontptr,localhandle,foninfo());
+ CopyFontInfo(fontptr,localhandle,fontinfo());
fontptr->iHeightInTwips = ((fontptr->iAddressPointer->HeightInPixels() * fontptr->iFontStore->iKPixelHeightInTwips) + 667) / 1000;
- ret = aMessage.Write(1, foninfo);
+ ret = aMessage.Write(1, fontinfo);
if(ret != KErrNone)
{
iIx->Remove(localhandle);
@@ -422,14 +490,14 @@
TInt pckgMaxHeight;
TPckgBuf<TSizeInfo> info;
- const TFbsMessage fbsMessage = static_cast<TFbsMessage>(aMessage.Function());
+ const TFbsMessage fbsMessage = static_cast<TFbsMessage>(aMessage.Function());
TInt ret = aMessage.Read(0, pckgFontSpec);
TFontSpec& fontSpec = pckgFontSpec();
if (ret == KErrNone )
{
TInt length = fontSpec.iTypeface.iName.Length();
- if(length < 0 || length > TOpenFontFaceAttribBase::ENameLength)
+ if((length < 0) || (length > TOpenFontFaceAttribBase::ENameLength))
{
aPanicRequired = ETrue;
return KErrArgument;
@@ -644,6 +712,183 @@
return EFalse;
}
+/** Handler for EFbsMessGetGlyphs message.
+Reads a batch of up to KMaxGlyphBatchSize glyph codes, and on success returns
+the corresponding TGlyphImageInfo objects.
+ @param aMessage input parameters
+ @param aPanicRequired flag that is set if a client panic is required
+ @return KErrNone if successful, otherwise any system-wide error code.
+ */
+TInt CFbClient::HandleMesgGetGlyphs(const RMessage2& aMessage, TBool& aPanicRequired)
+ {
+ CFbTop* fbtop = TopLevelStore();
+ // Previously requested glyphs were closed in ServiceL()
+ CGlyphAtlas* glyphAtlas = fbtop->GlyphAtlas();
+ if (!glyphAtlas)
+ {
+ return KErrNotSupported;
+ }
+ CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
+ if(!fontptr)
+ {
+ aPanicRequired = ETrue;
+ return KErrBadHandle;
+ }
+
+ TUint glyphCodes[KMaxGlyphBatchSize];
+ TGlyphImageInfo glyphImageInfo[KMaxGlyphBatchSize];
+ TPckg<TUint[KMaxGlyphBatchSize]> glyphBatchPckg(glyphCodes);
+
+ TInt err = aMessage.Read(1, glyphBatchPckg);
+ if (err != KErrNone)
+ {
+ aPanicRequired = ETrue;
+ return err;
+ }
+ TInt glyphCodesCount = glyphBatchPckg.Length() / sizeof(TUint);
+ if (glyphCodesCount > KMaxGlyphBatchSize)
+ {
+ aPanicRequired = ETrue;
+ return KErrOverflow;
+ }
+
+ TInt glyphsProcessed = 0;
+ CBitmapFont* font = fontptr->iAddressPointer;
+ for (; (glyphsProcessed < glyphCodesCount); ++glyphsProcessed)
+ {
+ TUint32 glyphCode = glyphCodes[glyphsProcessed];
+ err = glyphAtlas->GetGlyph(*font, glyphCode, glyphImageInfo[glyphsProcessed]);
+ // Search for glyph in glyph atlas
+ if (KErrNone != err)
+ {
+ const TUint8* bitmapData = NULL;
+ TOpenFontCharMetrics metrics;
+ // search for glyph in font glyph cache and session cache.
+ if (!font->GetCharacterData(iSessionHandle, glyphCode | KTreatAsGlyphCodeFlag, metrics, bitmapData))
+ {
+ // Rasterize the glyph
+ if(!font->Rasterize(iSessionHandle, glyphCode | KTreatAsGlyphCodeFlag, iOpenFontGlyphData))
+ {
+ err = KErrNoMemory;
+ break;
+ }
+ metrics = *(iOpenFontGlyphData->Metrics());
+ bitmapData = iOpenFontGlyphData->BitmapPointer();
+ }
+ CGlyphAtlas::TAddGlyphArgs args(bitmapData, glyphCode, metrics);
+ err = glyphAtlas->AddGlyph(*font, args, glyphImageInfo[glyphsProcessed]);
+ }
+ if ((err == KErrNone) && (glyphImageInfo[glyphsProcessed].iImageId != KSgNullDrawableId))
+ {
+ // To prevent other threads closing the glyph image in the glyph atlas
+ // before client has had chance to open the drawable id, open a local
+ // handle to the glyph image for the session, which will be closed either
+ // next time a request is made or when EFbsMessCloseGlyphs is handled.
+ RSgImage glyphImage;
+ err = glyphImage.Open(glyphImageInfo[glyphsProcessed].iImageId);
+ if (err == KErrNone)
+ {
+ err = iGlyphImagesInTransit.Append(glyphImage);
+ }
+ }
+ // If an error occurred during this iteration, abort now before the glyphsProcessed
+ // counter is incremented, which would give one too many processed glyphs.
+ if (KErrNone != err)
+ {
+ break;
+ }
+ }
+
+ // Even if there was an error, if at least one glyph was processed successfully
+ // send that back to the client, and reset the error code.
+ if (glyphsProcessed > 0)
+ {
+ TPckg<TGlyphImageInfo[KMaxGlyphBatchSize]> glyphImageInfoPckg(glyphImageInfo);
+ glyphImageInfoPckg.SetLength(glyphsProcessed * sizeof(TGlyphImageInfo));
+ err = aMessage.Write(2, glyphImageInfoPckg);
+ if (err != KErrNone)
+ {
+ aPanicRequired = ETrue;
+ return err;
+ }
+ }
+ else
+ {
+ // No glyphs being returned, so an error code must be returned.
+ __ASSERT_DEBUG(err != KErrNone, User::Panic(KFBSERVPanicCategory, err));
+ }
+ return err;
+ }
+
+/**
+Handler for EFbsMessGetGlyphMetrics message.
+Reads an array of glyph codes, and returns the offset from the heap base for the
+corresponding metrics object.
+@pre The glyph codes have already been searched client-side in the font glyph
+ cache and the session cache.
+@param aMessage input parameters
+@param aPanicRequired flag that is set if a client panic is required
+@return KErrNone if successful, otherwise any system-wide error code.
+ */
+TInt CFbClient::HandleMesgGetGlyphMetrics(const RMessage2& aMessage, TBool& aPanicRequired)
+ {
+ CFbTop* fbtop = TopLevelStore();
+ CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
+ if(!fontptr)
+ {
+ aPanicRequired = ETrue;
+ return KErrBadHandle;
+ }
+
+ TInt err = KErrNone;
+ TUint glyphCodes[KMaxMetricsBatchSize];
+ TPckg<TUint[KMaxMetricsBatchSize]> glyphBatchPckg(glyphCodes);
+ err = aMessage.Read(1, glyphBatchPckg);
+ if (err != KErrNone)
+ {
+ aPanicRequired = ETrue;
+ return err;
+ }
+
+ TInt numGlyphCodes = glyphBatchPckg.Length() / sizeof(TUint);
+ if (numGlyphCodes > KMaxMetricsBatchSize)
+ {
+ aPanicRequired = ETrue;
+ return KErrOverflow;
+ }
+
+ CBitmapFont* font = fontptr->iAddressPointer;
+ const TInt heapbase = fbtop->HeapBase();
+
+ TInt glyphProcessed;
+ TInt glyphMetricsOffsets[KMaxMetricsBatchSize];
+ for (glyphProcessed = 0; (glyphProcessed < numGlyphCodes) && (err == KErrNone); ++glyphProcessed)
+ {
+ if (font->Rasterize(iSessionHandle, glyphCodes[glyphProcessed] | KTreatAsGlyphCodeFlag, iOpenFontGlyphData))
+ {
+ // Convert all pointers to be passed back to the client to offsets from
+ // the heap base so that they can be recreated client side relative to the
+ // client's heap base
+ glyphMetricsOffsets[glyphProcessed] = PointerToOffset(iOpenFontGlyphData->Metrics(), heapbase);
+ }
+ else
+ {
+ err = KErrNoMemory;
+ }
+ }
+
+ if (err == KErrNone)
+ {
+ TPckg<TInt[KMaxMetricsBatchSize]> glyphMetricsOffsetsPckg(glyphMetricsOffsets);
+ glyphMetricsOffsetsPckg.SetLength(glyphProcessed * sizeof(TInt));
+ err = aMessage.Write(2, glyphMetricsOffsetsPckg);
+ if (err != KErrNone)
+ {
+ aPanicRequired = ETrue;
+ }
+ }
+ return err;
+ }
/** Handler for EFbsMessFaceAttrib message
@param aMessage Input and output parameters
@@ -661,21 +906,21 @@
}
CBitmapFont* bitmapFont = fontptr->iAddressPointer;
+ TInt ret = EFalse;
TPckgBuf<TOpenFontFaceAttrib> package;
if ( (bitmapFont != NULL) && (bitmapFont->GetFaceAttrib(package())) )
{
- TInt ret = aMessage.Write(1,package);
+ ret = aMessage.Write(1,package);
if (ret == KErrNone)
{
- return ETrue;
+ ret = ETrue;
}
else
{
aPanicRequired = ETrue;
- return ret;
}
}
- return EFalse;
+ return ret;
}
@@ -717,7 +962,6 @@
{
TInt error = KErrNone;
TShapeHeader* shape = 0;
- TPckgBuf<TShapeMessageParameters> sp;
if (aMessage.GetDesLength(2) != sizeof(TShapeMessageParameters))
{
aPanicRequired = ETrue;
@@ -731,7 +975,6 @@
aPanicRequired = ETrue;
return KErrArgument;
}
- CBitmapFont* bitmapFont = fontptr->iAddressPointer;
TInt inputTextLength = aMessage.GetDesLength(1);
if (inputTextLength < 0)
@@ -744,7 +987,9 @@
{
iTextToShape.Zero();
if (iTextToShape.MaxLength() < inputTextLength)
+ {
error = iTextToShape.ReAlloc(inputTextLength);
+ }
}
if (error == KErrNone)
{
@@ -754,12 +999,14 @@
aPanicRequired = ETrue;
return error;
}
+ TPckgBuf<TShapeMessageParameters> sp;
error = aMessage.Read(2, sp);
if (error != KErrNone)
{
aPanicRequired = ETrue;
return error;
}
+ CBitmapFont* bitmapFont = fontptr->iAddressPointer;
TRAP(error, shape = bitmapFont->ShapeTextL(iTextToShape, iSessionHandle, sp()) );
if (error == KErrNone)
{
@@ -953,9 +1200,70 @@
return ret;
}
+
+/**
+ Called in response to the GoomMonitor framework's call into FbsOogmPlugin.
+ We wish to either free some GPU memory, or reinstate its normal usage.
+
+@param aMessage The IPC message.
+@return KErrNone If the value contained in the TFbsOogmMessage enumeration member is meaningful and the glyph atlas is present.
+ KErrNotSupported if there is no glyph atlas.
+ KErrUnknown if the value contained in the TFbsOogmMessage enumeration member is not meaningful.
+ */
+TInt CFbClient::HandleMesgOogmStatus( const RMessage2& aMessage )
+ {
+ TInt ret = KErrNone;
+ CGlyphAtlas* glyphAtlas = TopLevelStore()->GlyphAtlas();
+
+ if ( NULL == glyphAtlas )
+ {
+ return KErrNotSupported;
+ }
+
+
+ TPckgBuf<TFbsOogmMessage> oogmMessage;
+ aMessage.Read( 0, oogmMessage );
+
+ switch( oogmMessage().iOogmNotification )
+ {
+ case TFbsOogmMessage::EFbsOogmNoAction:
+ break;
+
+ case TFbsOogmMessage::EFbsOogmLowNotification:
+ {
+ glyphAtlas->ReleaseGpuMemory( oogmMessage().iBytesToFree, oogmMessage().iFlags );
+ }
+ break;
+
+ case TFbsOogmMessage::EFbsOogmOkayNotification:
+ {
+ glyphAtlas->InstateGpuMemory( oogmMessage().iFlags );
+ }
+ break;
+
+ default:
+ ret = KErrUnknown;
+ break;
+ }
+
+ return ret;
+ }
+
+
+void CFbClient::HandleMesgGlyphCacheMetrics( const RMessage2& aMessage )
+ {
+ CGlyphAtlas* glyphAtlas = TopLevelStore()->GlyphAtlas();
+ TPckgBuf<TGlyphCacheMetrics> metrics;
+
+ glyphAtlas->GetGlyphCacheMetrics( metrics() );
+
+ aMessage.Complete( aMessage.Write(0, metrics) );
+ }
+
+
void CFbClient::ProcFontMessage(const RMessage2& aMessage)
{
- TInt ret = KErrUnknown;
+ TInt ret = KErrNone;
TBool panicRequired = EFalse;
switch(aMessage.Function())
@@ -1082,9 +1390,20 @@
ret = HandleMesgReleaseFontTable(aMessage, panicRequired);
break;
}
+ case EFbsMessGetGlyphs:
+ {
+ ret = HandleMesgGetGlyphs(aMessage, panicRequired);
+ break;
+ }
+ case EFbsMessGetGlyphMetrics:
+ {
+ ret = HandleMesgGetGlyphMetrics(aMessage, panicRequired);
+ break;
+ }
#ifdef _DEBUG
case EFbsMessSetDuplicateFail:
+ {
TInt argument =aMessage.Int0();
if (argument)
{
@@ -1096,7 +1415,10 @@
}
ret=KErrNone;
break;
+ }
#endif
+ default:
+ ret = KErrUnknown;
}
// either have a result or an error code to panic the client with
@@ -1120,7 +1442,7 @@
{
CBitmapObject* bmpptr=NULL;
TInt localhandle=0;
- TInt ret=KErrUnknown;
+ TInt ret = KErrNone;
switch(aMessage.Function())
{
case EFbsMessBitmapCreate:
@@ -1283,14 +1605,18 @@
}
ret = fbtop->GetCleanBitmap(bmpptr);
if (ret != KErrNone)
+ {
break;
+ }
TSize newsize(aMessage.Int1(),aMessage.Int2());
const TBool compressedInRam = bmpptr->Address()->IsCompressedInRAM(); //It must be set before the resizing is done.
const TDisplayMode dispMode = bmpptr->Address()->DisplayMode();
CBitmapObject* newbmpptr = NULL;
TRAP(ret, newbmpptr = fbtop->CreateBitmapL(newsize, dispMode, KUidCFbsBitmapCreation, ETrue));
if (ret != KErrNone)
+ {
break;
+ }
ret = newbmpptr->Address()->CopyData(*bmpptr->Address());
if (ret != KErrNone)
{
@@ -1325,7 +1651,9 @@
}
bmpptr->SetCleanBitmap(newbmpptr);
if (bmpptr->AccessCount() >= 2)
+ {
fbtop->NotifyDirtyBitmap(*bmpptr, this);
+ }
iIx->Remove(localhandle);
TPckgBuf<TBmpHandles> handlebuffer;
handlebuffer().iHandle = newlocalhandle;
@@ -1353,7 +1681,9 @@
TopLevelStore()->GetCleanBitmap(bmpptr);
ret = bmpptr->Open();
if (ret != KErrNone)
+ {
break;
+ }
TPckgBuf<TBmpHandles> handlebuffer;
TRAP(ret,localhandle=iIx->AddL(bmpptr));
if(ret!=KErrNone)
@@ -1386,13 +1716,17 @@
}
ret = fbtop->GetCleanBitmap(bmpptr);
if (ret != KErrNone)
+ {
break;
+ }
const TSize size = bmpptr->Address()->SizeInPixels();
const TDisplayMode dispMode = bmpptr->Address()->DisplayMode();
CBitmapObject* newbmpptr = NULL;
TRAP(ret, newbmpptr = fbtop->CreateBitmapL(size, dispMode, KUidCFbsBitmapCreation, ETrue));
if (ret != KErrNone)
+ {
break;
+ }
ret = newbmpptr->Address()->CopyData(*bmpptr->Address());
if (ret != KErrNone)
{
@@ -1420,7 +1754,9 @@
}
bmpptr->SetCleanBitmap(newbmpptr);
if (bmpptr->AccessCount() >= 2)
+ {
fbtop->NotifyDirtyBitmap(*bmpptr, this);
+ }
iIx->Remove(localhandle);
TPckgBuf<TBmpHandles> handlebuffer;
handlebuffer().iHandle = newlocalhandle;
@@ -1451,7 +1787,9 @@
if (ret != KErrNone)
{
if (!async)
+ {
ret = KErrNone;
+ }
break;
}
ret = bmpptr->Address()->CheckBackgroundCompressData();
@@ -1459,10 +1797,14 @@
{
ret = fbtop->BackgroundCompression()->AddToCompressionQueue(bmpptr, scheme, async ? &aMessage : NULL);
if (ret == KErrNone && async)
+ {
return; // do not complete the client's request - that will be done by the background compression thread
+ }
}
if (KErrAlreadyExists == ret)
+ {
ret = KErrNone;
+ }
break;
}
case EFbsMessBitmapClean:
@@ -1477,10 +1819,14 @@
}
ret = fbtop->GetCleanBitmap(bmpptr);
if (ret != KErrNone)
+ {
break;
+ }
ret = bmpptr->Open();
if (ret != KErrNone)
+ {
break;
+ }
TInt cleanlocalhandle = 0;
TRAP(ret, cleanlocalhandle = iIx->AddL(bmpptr));
if (ret != KErrNone)
@@ -1530,17 +1876,19 @@
iHelper->iMessage = aMessage;
return; // do not complete the client's request yet - that will be done when a bitmap becomes dirty
}
- ret = KErrNone;
iHelper->iDirty = EFalse;
}
break;
case EFbsMessBitmapCancelNotifyDirty:
{
if (iHelper != NULL && !iHelper->iMessage.IsNull())
+ {
iHelper->iMessage.Complete(KErrCancel);
- ret = KErrNone;
+ }
}
break;
+ default:
+ ret = KErrUnknown;
}
if(!aMessage.IsNull())
@@ -1616,7 +1964,9 @@
if (iHelper)
{
if (!iHelper->iMessage.IsNull())
+ {
iHelper->iMessage.Complete(KErrDisconnected);
+ }
iHelper->Deque();
delete iHelper;
iHelper = NULL;
@@ -1678,7 +2028,58 @@
break;
case EFbsMessHeap:
ret=(TInt)iHeap;
- break;
+ break;
+ default:
+ ret = KErrUnknown;
+ }
+ aMessage.Complete(ret);
+ iRet=ret;
+ }
+
+/**
+Processes messages associated with the Glyph Atlas.
+@param aMessage The message used to perform IPC to the client.
+ */
+void CFbClient::ProcAtlasMessage(const RMessage2 &aMessage)
+ {
+ TInt ret = KErrNone;
+ CFbTop* fbtop = TopLevelStore();
+ CGlyphAtlas* glyphAtlas = fbtop->GlyphAtlas();
+ if (!glyphAtlas)
+ {
+ ret = KErrNotSupported;
+ }
+ else
+ {
+ switch(aMessage.Function())
+ {
+ case EFbsMessAtlasFontCount:
+ ret = glyphAtlas->FontCount();
+ break;
+ case EFbsMessAtlasGlyphCount:
+ {
+ TInt fontHandle = aMessage.Int0();
+ if (fontHandle != 0)
+ {
+ if (fbtop->ValidFontHandle(fontHandle))
+ {
+ CFontObject* fontptr = reinterpret_cast<CFontObject*>(fontHandle);
+ ret = glyphAtlas->GlyphCount(static_cast<CBitmapFont&>(*(fontptr->iAddressPointer)));
+ }
+ else
+ {
+ ret = KErrNotFound;
+ }
+ }
+ else
+ {
+ ret = glyphAtlas->GlyphCount();
+ }
+ }
+ break;
+ default:
+ ret = KErrUnknown;
+ }
}
aMessage.Complete(ret);
iRet=ret;