--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/fbs/fontandbitmapserver/sfbs/FBSBMP.CPP Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,2027 @@
+// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <s32file.h>
+#include <bitmap.h>
+#include <graphicsaccelerator.h>
+#include <fbs.h>
+#include <graphics/bitmapuid.h>
+#include "fbsdefs.h"
+#include "UTILS.H"
+#include "fbshelper.h"
+#include "fbsrasterizer.h"
+#include "BitwiseBitmap.inl"
+#include "fbsmessage.h"
+#include "bitmapconst.h"
+
+const TInt KMaxPixelSize = KMaxTInt / 4; // Maximum pixel size to avoid some overflow problems
+const TInt KMaxBitmapHandleBufferSize = KNumBytesPerBitmapHandle * 2000; // Maximum size of buffer to store all bitmap handles.
+
+GLREF_C void Panic(TFbsPanic aPanic);
+
+//If we have to handle RAM located file with an embedded ROM mbm file section -
+//KRomMBMInRamRSC should be ETrue.
+//If it is not allowed to do that - KRomMBMInRamRSC should be EFalse.
+//The same constant is defined into TDefect test app. It should be changed too.
+#pragma warning(disable : 4127) //conditional expression is constant
+LOCAL_D const TBool KRomMBMInRamRSC = EFalse;
+
+//Cleanup function used by CFbsBitmap::LoadShiftedRomBmpL(...)
+LOCAL_D void FreeMem(TAny* aMem)
+ {
+ delete[] static_cast<TUint8*>(aMem);
+ }
+
+// Fbs style bitmap client class for font bitmap server
+/** @publishedAll */
+EXPORT_C CFbsBitmap::CFbsBitmap():
+ CBase(),
+ iFbs(RFbsSession::GetSession()),
+ iAddressPointer(NULL),
+ iFlags(0),
+ iUseCount(0),
+ iHandle(0),
+ iServerHandle(0)
+ {
+ }
+
+/** Destructor. Calls Reset().
+@see Reset()
+@publishedAll
+@released
+*/
+EXPORT_C CFbsBitmap::~CFbsBitmap()
+ {
+ Reset();
+ }
+
+/** Gets the physical length in bytes of a scanline in memory.
+This is aligned to a 4 byte (DWORD) boundary for performance reasons.
+
+@param aLength The length of a scanline in pixels.
+@param aDispMode The display mode of the bitmap.
+@return Number of bytes in the scanline in memory.
+@publishedAll
+@released
+*/
+EXPORT_C TInt CFbsBitmap::ScanLineLength(TInt aLength,TDisplayMode aDispMode)
+ {
+ if (aDispMode == ERgb)
+ return aLength * 4;
+ else if (aDispMode == ENone)
+ return 0;
+
+ return CBitwiseBitmap::ByteWidth(aLength,aDispMode);
+ }
+
+/** Releases the bitmap's handle from the font and bitmap server and decrements
+its access count.
+The server-side bitmap is only deleted when the access count for the bitmap
+decrements to zero.
+@publishedAll
+@released
+*/
+EXPORT_C void CFbsBitmap::Reset()
+ {
+ if (iHandle && !(iFlags & EIsRomBitmap))
+ {
+ iFbs->SendCommand(EFbsMessClose, iHandle, Handle());
+ iFbs->iHelper->RemoveBitmap(*this);
+ }
+ if (KRomMBMInRamRSC && (iFlags & EIsRomBitmap))
+ {
+ // If it is a ROM bitmap, we have to check, is it a ROM bitmap located
+ // in RAM? If yes, then we have to deallocate the bitmap memory.
+ TBool isInRom = EFalse;
+ TInt ret = User::IsRomAddress(isInRom, iAddressPointer);
+ if (ret == KErrNone && !isInRom)
+ delete[] reinterpret_cast<TUint8*>(iAddressPointer);
+ }
+ iAddressPointer = NULL;
+ iFlags = 0;
+ iUseCount = 0;
+ iHandle = 0;
+ iServerHandle = 0;
+ }
+
+/** Tests whether or not the bitmap is read-only.
+@return ETrue if the bitmap is read-only, EFalse otherwise.
+@publishedAll
+@released
+*/
+EXPORT_C TBool CFbsBitmap::IsRomBitmap() const
+ {
+ return (iFlags & EIsReadOnlyBitmapMask) > 0;
+ }
+
+/** Sets the bitmap to use a bitmap image stored in ROM.
+@param aRomBitmapPointer Pointer to a bitmap stored in ROM.
+@param aBitmapSizeInBytes On return, indicates the size of
+the bitmap in bytes.
+@leave KErrUnknown aRomBitmapPointer is not in ROM, or has an invalid UID.
+@publishedAll
+@released
+*/
+EXPORT_C void CFbsBitmap::SetRomBitmapL(CBitwiseBitmap* aRomBitmapPointer,TInt& aBitmapSizeInBytes)
+ {
+ TBool isInRom = EFalse;
+ TInt ret = User::IsRomAddress(isInRom,(TAny*)aRomBitmapPointer);
+ if (ret != KErrNone || !isInRom || aRomBitmapPointer->Uid() != KCBitwiseBitmapUid)
+ User::Leave(KErrUnknown);
+
+ Reset();
+ iAddressPointer = aRomBitmapPointer;
+ iFlags = EIsRomBitmap;
+ iHandle = 1;
+
+ User::LeaveIfError(iFbs->AllocScanLineBuffer(aRomBitmapPointer->iByteWidth + 4));
+ aBitmapSizeInBytes = Align4(aRomBitmapPointer->iHeader.iBitmapSize + 28);
+ }
+
+CBitwiseBitmap* CFbsBitmap::Address() const
+ {
+ if (!iHandle)
+ return NULL;
+ return iAddressPointer;
+ }
+
+EXPORT_C CBitwiseBitmap* CFbsBitmap::CleanAddress() const
+ {
+ if (!iHandle)
+ return NULL;
+ // Don't try to clean a dirty bitmap between calls to BeginDataAccess() and EndDataAccess(), i.e. iUseCount > 0
+ // ROM bitmaps can never be dirty
+ if (!(iFlags & EIsReadOnlyBitmapMask) && iUseCount == 0 && iAddressPointer->iSettings.IsDirtyBitmap())
+ {
+ TPckgBuf<TBmpHandles> handlebuf;
+ TIpcArgs args(iHandle, &handlebuf);
+ if (iFbs->SendCommand(EFbsMessBitmapClean, args) == KErrNone)
+ {
+ const_cast<CFbsBitmap*>(this)->iHandle = handlebuf().iHandle;
+ const_cast<CFbsBitmap*>(this)->iServerHandle = handlebuf().iServerHandle;
+ const_cast<CFbsBitmap*>(this)->iAddressPointer = (CBitwiseBitmap*)(iFbs->HeapBase() + handlebuf().iAddressOffset);
+ }
+ }
+ return iAddressPointer;
+ }
+
+inline CBitwiseBitmap* CFbsBitmap::BeginDataAccessAndGetCleanAddress(TUint32*& aDataAddress) const
+ {
+ BeginDataAccess();
+ CBitwiseBitmap* bmp = Address();
+ // aDataAddress should be consistent with bmp since after the call to BeginDataAccess()
+ // the call to DataAddress() will not clean the bitmap again
+ aDataAddress = DataAddress();
+ return bmp;
+ }
+
+/** Gets the address of the first pixel in the bitmap.
+The first pixel is at the top-left. Access to the pixel data of a bitmap
+should be surrounded by calls to BeginDataAccess() and EndDataAccess(),
+otherwise performance may be degraded on certain platforms.
+
+Note: Performing a Resize() or Compress() operation changes the value returned by this function.
+@return The address of the first pixel of the bitmap.
+@publishedAll
+@released
+@see CFbsBitmap::BeginDataAccess()
+@see CFbsBitmap::EndDataAccess()
+*/
+EXPORT_C TUint32* CFbsBitmap::DataAddress() const
+ {
+ if(!iHandle) return(NULL);
+ CBitwiseBitmap* bmp = CleanAddress();
+
+ if (!(iFlags & EIsReadOnlyBitmapMask) && (iUseCount == 0))
+ bmp->iSettings.SetVolatileBitmap();
+
+ if(bmp->iUid.iUid==KCBitwiseBitmapHardwareUid.iUid) // RHardwareBitmap
+ {
+ RHardwareBitmap hwb(bmp->iDataOffset); // iDataOffset = handle for hardware bitmap
+ TAcceleratedBitmapInfo info;
+ const TInt ret = hwb.GetInfo(info);
+ return ret!=KErrNone ? NULL : (reinterpret_cast<TUint32*>(info.iAddress));
+ }
+
+ if (bmp->iHeap == NULL)
+ return(reinterpret_cast<TUint32*>((TUint8*)bmp+bmp->iDataOffset));
+ return(reinterpret_cast<TUint32*>(iFbs->iLargeBitmapChunk.Base()+bmp->iDataOffset));
+ }
+
+/** Gets the length in bytes between scanlines in memory.
+@return The length in bytes between scanlines in memory.
+@internalAll
+@released
+*/
+EXPORT_C TInt CFbsBitmap::DataStride() const
+ {
+ if (!iHandle)
+ {
+ return 0;
+ }
+
+ CBitwiseBitmap* bmp = CleanAddress();
+ if (bmp==NULL)
+ {
+ return 0;
+ }
+
+ return bmp->DataStride();
+ }
+
+/** Creates a bitmap with the specified size and display mode. The bitmap is
+created on the font and bitmap server's shared heap.
+@param aSizeInPixels The size of the bitmap to be created.
+@param aDispMode The display mode of the bitmap to be created.
+@return KErrNone if successful; KErrCouldNotConnect if no connection to the
+font and bitmap server could be made; KErrArgument if either the width or height specified
+in aSizeInPixels are negative or if the requested display mode is invalid; KErrTooBig
+if the requested size is too big.
+@publishedAll
+@released
+*/
+EXPORT_C TInt CFbsBitmap::Create(const TSize& aSizeInPixels,TDisplayMode aDispMode)
+ {
+ return DoCreate(aSizeInPixels,aDispMode,KUidCFbsBitmapCreation);
+ }
+
+TInt CFbsBitmap::DoCreate(const TSize& aSizeInPixels, TDisplayMode aDispMode, TUid aUid, TInt aDataSize)
+ {
+ if(!iFbs) return(KErrCouldNotConnect);
+ if (aDispMode <= ENone || aDispMode == ERgb || aDispMode >= EColorLast) return KErrArgument;
+ if(aSizeInPixels.iWidth<0 || aSizeInPixels.iHeight<0) return(KErrArgument);
+ if (aDataSize < 0) return KErrArgument;
+ Reset();
+ TBmpSpec bmpspec;
+ bmpspec.iSizeInPixels=aSizeInPixels;
+ bmpspec.iDispMode=aDispMode;
+ bmpspec.iHandle = aUid.iUid; // Use iHandle to pass UID
+ bmpspec.iServerHandle = aDataSize; // Use iServerHandle to pass data size
+ TPckgBuf<TBmpSpec> b;
+ b=bmpspec;
+ TIpcArgs args(&b);
+ TInt ret=iFbs->SendCommand(EFbsMessBitmapCreate,args);
+ if(ret!=KErrNone) return(ret);
+ iHandle=b().iHandle;
+ iServerHandle=b().iServerHandle;
+ iAddressPointer=(CBitwiseBitmap*)(iFbs->HeapBase()+b().iAddressOffset);
+ if (aDataSize > 0) // explicitly specified data size means extended bitmap
+ {
+ iFlags = EIsExtendedBitmap;
+ }
+ ret = iFbs->iHelper->AddBitmap(*this);
+ if (ret != KErrNone)
+ return ret;
+ return iFbs->AllocScanLineBuffer(CBitwiseBitmap::ByteWidth(aSizeInPixels.iWidth, aDispMode)+4);
+ }
+
+/** Creates a hardware bitmap with a size and display mode.
+@param aSizeInPixels The bitmap's width and height in pixels.
+@param aDispMode The bitmap's display mode.
+@param aCreatorUid The UID of the application calling this function. This is
+used to allow segregation of the memory used for hardware bitmaps. For instance,
+if a device has video memory attached to display and graphics accelerator
+hardware, this UID is used to determine whether any video memory is pre-allocated
+for that application's use.
+@return KErrNone if successful, otherwise one of the system wide error codes.
+These include KErrCouldNotConnect if no connection has been made to the font
+and bitmap server, KErrArgument if either the width or height specified in
+aSizeInPixels are negative or if the requested display mode is invalid, or KErrNotSupported
+if hardware bitmaps are not supported on the device.
+@publishedAll
+@released
+*/
+EXPORT_C TInt CFbsBitmap::CreateHardwareBitmap(const TSize& aSizeInPixels,TDisplayMode aDispMode,TUid aCreatorUid)
+ {
+ return DoCreate(aSizeInPixels,aDispMode,aCreatorUid);
+ }
+
+/** Resets the pixel-size of the bitmap.
+If the new size is bigger than the old, the original bitmap is still situated
+at (0,0), but pixels outside the range of the old pixel-size are set to zero.
+@param aSizeInPixels The new size of the bitmap.
+@return KErrNone if successful; KErrArgument if the new size is illegal;
+KErrGeneral if the bitmap has not yet been created; KErrAccessDenied if the
+bitmap is in ROM or is an extended bitmap; otherwise another of the system-wide error codes.
+@publishedAll
+@released
+*/
+EXPORT_C TInt CFbsBitmap::Resize(const TSize& aSizeInPixels)
+ {
+ if(aSizeInPixels.iWidth<0 || aSizeInPixels.iHeight<0)
+ return(KErrArgument);
+ if(aSizeInPixels.iWidth>KMaxPixelSize || aSizeInPixels.iHeight>KMaxPixelSize)
+ return(KErrTooBig);
+ if(!iHandle)
+ return(KErrGeneral);
+ if (iFlags & EIsReadOnlyBitmapMask)
+ return(KErrAccessDenied);
+ TPckgBuf<TBmpHandles> handlebuf;
+ TIpcArgs args(iHandle, aSizeInPixels.iWidth, aSizeInPixels.iHeight, &handlebuf);
+ TInt err = iFbs->SendCommand(EFbsMessBitmapResize, args);
+ if (err != KErrNone)
+ return (err);
+ iHandle = handlebuf().iHandle;
+ iServerHandle = handlebuf().iServerHandle;
+ iAddressPointer = (CBitwiseBitmap*)(iFbs->HeapBase() + handlebuf().iAddressOffset);
+ return iFbs->AllocScanLineBuffer(CBitwiseBitmap::ByteWidth(aSizeInPixels.iWidth, DisplayMode())+4);
+ }
+
+/** Gets the display mode of the bitmap.
+@return The display mode of the bitmap.
+@publishedAll
+@released
+*/
+EXPORT_C TDisplayMode CFbsBitmap::DisplayMode() const
+ {
+ if(iHandle==NULL) return(ENone);
+ return CleanAddress()->DisplayMode();
+ }
+
+/** Returns the display mode that was used to create the bitmap.
+@return The display mode used to create the bitmap.
+@publishedAll
+@released
+*/
+EXPORT_C TDisplayMode CFbsBitmap::InitialDisplayMode() const
+ {
+ if(iHandle == NULL)
+ {
+ return ENone;
+ }
+ return CleanAddress()->InitialDisplayMode();
+ }
+
+/**
+Changes the display mode of the bitmap.
+The requested display mode cannot be greater (in bpp value) than the initial display mode.
+This method cannot leave, for instance because of an out of memory condition. No
+additional memory is allocated or leaving methods called.
+The bitmap's content is preserved when converting it to the requested display mode,
+but there may be some loss of quality.
+@publishedAll
+@released
+@param aDisplayMode The requested display mode.
+@return KErrArgument if the requested mode is invalid, or has a greater bpp value
+than the initial mode. KErrNotSupported if the bitmap is compressed, or is a
+ROM bitmap, an extended bitmap or a hardware bitmap. KErrGeneral if the bitmap
+handle is NULL. KErrNone if the method call is successful.
+@see CFbsBitmap::InitialDisplayMode()
+*/
+EXPORT_C TInt CFbsBitmap::SetDisplayMode(TDisplayMode aDisplayMode)
+ {
+ if(!iHandle)
+ {
+ return KErrGeneral;
+ }
+ TUint32* data;
+ CBitwiseBitmap* bmp = BeginDataAccessAndGetCleanAddress(data);
+ TInt err = bmp->SetDisplayMode(aDisplayMode, data);
+ EndDataAccess(EFalse);
+ return err;
+ }
+
+/** Duplicates a bitmap.
+This function does not create a copy of the bitmap. It just assigns another
+handle to the bitmap in the font and bitmap server, and sets this object's
+handle to that. If the specified bitmap is in the ROM, it just assigns a pointer
+to it.
+@param aHandle The handle to an existing bitmap.
+@return KErrNone if successful; KErrCouldNotConnect if no connection to the
+font and bitmap server could be made; KErrUnknown if no bitmap could be found
+with the specified handle number.
+@publishedAll
+@released
+@see CFbsBitmap::Handle()
+*/
+EXPORT_C TInt CFbsBitmap::Duplicate(TInt aBitmapHandle)
+ {
+ if(!iFbs)
+ {
+ return(KErrCouldNotConnect);
+ }
+ if(!aBitmapHandle)
+ {
+ return(KErrUnknown);
+ }
+ Reset();
+ TBool isinrom=EFalse;
+ TInt ret=User::IsRomAddress(isinrom,(TAny*)aBitmapHandle);
+ if(ret!=KErrNone)
+ {
+ return(KErrUnknown);
+ }
+ if(isinrom)
+ {
+ if (((CBitwiseBitmap*)aBitmapHandle)->Uid() != KCBitwiseBitmapUid)
+ return(KErrUnknown);
+ iAddressPointer = (CBitwiseBitmap*)aBitmapHandle;
+ iFlags = EIsRomBitmap;
+ iHandle=1;
+ return iFbs->AllocScanLineBuffer(iAddressPointer->iByteWidth + 4);
+ }
+ TPckgBuf<TBmpHandles> b;
+ TIpcArgs args(aBitmapHandle,&b);
+ ret=iFbs->SendCommand(EFbsMessBitmapDuplicate,args);
+ if(ret!=KErrNone)
+ {
+ return(ret);
+ }
+ iHandle=b().iHandle;
+ iServerHandle=b().iServerHandle;
+ iAddressPointer=(CBitwiseBitmap*)(iFbs->HeapBase()+b().iAddressOffset);
+ if (iAddressPointer->iUid.iUid != KCBitwiseBitmapUid.iUid && iAddressPointer->iUid.iUid != KCBitwiseBitmapHardwareUid.iUid)
+ {
+ iFlags = EIsExtendedBitmap;
+ }
+ ret = iFbs->iHelper->AddBitmap(*this);
+ if (ret != KErrNone)
+ {
+ return ret;
+ }
+ return iFbs->AllocScanLineBuffer(iAddressPointer->iByteWidth+4);
+ }
+
+/** Loads a specific bitmap from a multi-bitmap file.
+The bitmap may be shared by other font and bitmap server clients.
+@param aFileName The filename of the multi-bitmap (.mbm) file.
+@param aId The bitmap identifier.
+@param aShareIfLoaded Specifies whether or not the loaded bitmap will be made
+available for sharing between font and bitmap server clients.
+@return KErrNone if successful, otherwise another of the system error
+codes.
+@publishedAll
+@released
+*/
+EXPORT_C TInt CFbsBitmap::Load(const TDesC& aFileName,TInt32 aId,TBool aShareIfLoaded)
+ {
+ return Load(aFileName,aId,aShareIfLoaded,0);
+ }
+
+/** Loads a specific bitmap from a multi-bitmap file.
+The bitmap may be shared by other font and bitmap server clients.
+@param aFileName The filename of the multi-bitmap (.mbm) file.
+@param aId The bitmap identifier.
+@param aShareIfLoaded Specifies whether or not the loaded bitmap will be made
+available for sharing between FBSERV clients.
+@param aFileOffset Bitmap file section offset within the file.
+@return KErrNone if successful, otherwise another of the system error codes.
+@publishedAll
+@released
+*/
+EXPORT_C TInt CFbsBitmap::Load(const TDesC& aFileName,TInt32 aId,TBool aShareIfLoaded,TUint aFileOffset)
+ {
+ if(!iFbs)
+ {
+ return(KErrCouldNotConnect);
+ }
+ Reset();
+ TUint32* rompointer = NULL;
+ //access using filename has the advantage of using rom address lookup cache
+ IsFileInRom(aFileName, rompointer);
+ TBool romPointerValid;
+ TInt err = DoLoadFromRom(rompointer, aId, aFileOffset, romPointerValid);
+ if(romPointerValid)
+ {
+ return err;
+ }
+ _LIT(KResourcePath, "?:\\Resource\\*");
+ TInt match = aFileName.MatchF(KResourcePath);
+ //if the file is in the resource directory we don't need to check capabilities and the file can just be opened on the server side.
+ if (match == 0)
+ {
+ err = DoLoad(aFileName,aId,aShareIfLoaded,aFileOffset);
+ }
+ else
+ {
+ RFile file;
+ err = file.Open(iFbs->FileServer(),aFileName,EFileShareReadersOnly);
+ if (err!=KErrNone)
+ {
+ return err;
+ }
+ err = DoLoad(file,aId,aShareIfLoaded,aFileOffset);
+ file.Close();
+ }
+ return err;
+ }
+
+/** Loads and compresses a specific bitmap from a multi-bitmap file.
+The bitmap may be shared by other font and bitmap server clients.
+If the bitmap is loaded from ROM then compression is not allowed.
+@param aFileName The filename of the multi-bitmap (.mbm) file.
+@param aId The bitmap identifier.
+@param aShareIfLoaded Specifies whether or not the loaded bitmap will be
+made available for sharing between FBSERV clients.
+@return KErrNone if successful, otherwise another of the system-wide error
+codes.
+@publishedAll
+@released
+*/
+EXPORT_C TInt CFbsBitmap::LoadAndCompress(const TDesC& aFileName,TInt32 aId,TBool aShareIfLoaded)
+ {
+ return LoadAndCompress(aFileName, aId, aShareIfLoaded, 0);
+ }
+
+/** Loads and compresses a specific bitmap from a multi-bitmap file.
+The bitmap may be shared by other font and bitmap server clients. If the
+bitmap is loaded from ROM then compression is not allowed.
+@param aFileName The filename of the multi-bitmap (.mbm) file.
+@param aId The bitmap identifier.
+@param aShareIfLoaded Specifies whether or not the loaded bitmap will be made
+available for sharing between FBSERV clients.
+@param aFileOffset Bitmap file section offset within the file.
+@return KErrNone if successful, otherwise another of the system-wide error
+codes.
+@publishedAll
+@released
+*/
+EXPORT_C TInt CFbsBitmap::LoadAndCompress(const TDesC& aFileName,TInt32 aId,TBool aShareIfLoaded,TUint aFileOffset)
+ {
+ TInt err = Load(aFileName,aId,aShareIfLoaded,aFileOffset);
+ if (err == KErrNone)
+ {
+ err = !(iFlags & EIsRomBitmap) ? Compress() : KErrAccessDenied;
+ }
+ return err;
+ }
+
+/** Saves the bitmap as a direct file store.
+The file store overwrites any existing file with the same name.
+@param aFilename The name of the file.
+@return KErrNone if successful, KErrNotSupported if this CFbsBitmap is an
+extended bitmap, otherwise another of the system-wide error codes.
+@publishedAll
+@released
+*/
+EXPORT_C TInt CFbsBitmap::Save(const TDesC& aFilename)
+ {
+ if (!iHandle)
+ {
+ return(KErrGeneral);
+ }
+ RFile file;
+ TInt ret=file.Replace(iFbs->FileServer(),aFilename,EFileWrite);
+ if(ret!=KErrNone) return(ret);
+ TRAP(ret,DoSaveL(file));
+ file.Close();
+ return(ret);
+ }
+
+/** Saves the bitmap as a direct file store using an opened file handle.
+The file store overwrites any existing file with the same name.
+@param aFile The opened file handle
+@return KErrNone if successful, KErrNotSupported if this CFbsBitmap is an
+extended bitmap, otherwise another of the system-wide error codes.
+@publishedAll
+@released
+*/
+EXPORT_C TInt CFbsBitmap::Save(RFile& aFile)
+ {
+ if (!iHandle)
+ {
+ return KErrGeneral;
+ }
+ TRAPD(ret,DoSaveL(aFile));
+ return ret;
+ }
+
+void CFbsBitmap::DoSaveL(RFile& aFile)
+ {
+ CDirectFileStore* filestore=CDirectFileStore::NewLC(aFile); // create from open file
+ TUidType uidtype(KDirectFileStoreLayoutUid,KMultiBitmapFileImageUid);
+ filestore->SetTypeL(uidtype);
+ RStoreWriteStream bmpstream;
+ TStreamId bmpstreamid=bmpstream.CreateLC(*filestore); // create bitmap stream
+ ExternalizeL(bmpstream);
+ bmpstream.CommitL();
+ CleanupStack::PopAndDestroy(); // bitmap stream
+ RStoreWriteStream rootstream;
+ TStreamId rootstreamid=rootstream.CreateLC(*filestore); // create root stream
+ rootstream.WriteInt32L(1); // number of bitmaps
+ rootstream<<bmpstreamid; // stream id of bitmap
+ rootstream.CommitL();
+ CleanupStack::PopAndDestroy(); // root stream
+ filestore->SetRootL(rootstreamid);
+ filestore->CommitL();
+ CleanupStack::PopAndDestroy(); // file store
+ }
+
+/** Constructs a multi-bitmap file.
+@param aFilename The name of the multi-bitmap file to be created.
+@param aNumSources The number of bitmaps to store in the file.
+@param aSources An array of pointers to bitmaps to be stored.
+@param aSourceIds An array of identifiers for the bitmaps to be stored.
+@publishedAll
+@released
+*/
+EXPORT_C void CFbsBitmap::StoreL(const TDesC& aFilename,TInt aNumSources,const TDesC* aSources[],TInt32 aSourceIds[])
+ {
+ CFbsBitmap* bitmap = new(ELeave) CFbsBitmap;
+ CleanupStack::PushL(bitmap);
+ CDirectFileStore* filestore = CDirectFileStore::ReplaceLC(bitmap->iFbs->FileServer(),aFilename,EFileWrite);
+ DoStoreL(filestore,bitmap,aNumSources,aSources,aSourceIds);
+ CleanupStack::PopAndDestroy(2,bitmap);
+ }
+
+/** Constructs a multi-bitmap file using an opened file handle.
+@param aFile The opened file handle of multi-bitmap file
+@param aNumSources The number of bitmaps to store in the file.
+@param aSources An array of pointers to bitmaps to be stored.
+@param aSourceIds An array of identifiers for the bitmaps to be stored.
+@publishedAll
+@released
+*/
+EXPORT_C void CFbsBitmap::StoreL(RFile& aFile,TInt aNumSources,const TDesC* aSources[],TInt32 aSourceIds[])
+ {
+ CDirectFileStore* filestore = CDirectFileStore::NewLC(aFile);
+ DoStoreL(filestore,NULL,aNumSources,aSources,aSourceIds);
+ CleanupStack::PopAndDestroy(filestore);
+ }
+
+/**
+@internalComponent
+*/
+void CFbsBitmap::DoStoreL(CDirectFileStore* aFileStore,CFbsBitmap* aBitmap,TInt aNumSources,const TDesC* aSources[],TInt32 aSourceIds[])
+ {
+ if(aNumSources<1 || aSources==NULL) User::Leave(KErrArgument);
+ TInt count=0;
+ for(;count<aNumSources;count++)
+ if(aSources[count]==NULL) User::Leave(KErrArgument);
+ TStreamId* ids=new(ELeave) TStreamId[aNumSources];
+ CleanupArrayDeletePushL(ids);
+ TInt nPushed=1;
+ if (!aBitmap)
+ {
+ aBitmap=new(ELeave) CFbsBitmap;
+ CleanupStack::PushL(aBitmap);
+ ++nPushed;
+ }
+ TUidType uidtype(KDirectFileStoreLayoutUid,KMultiBitmapFileImageUid);
+ aFileStore->SetTypeL(uidtype);
+ for(count=0;count<aNumSources;count++)
+ {
+ User::LeaveIfError(aBitmap->Load(*aSources[count],aSourceIds[count]));
+ RStoreWriteStream bmpstream;
+ ids[count]=bmpstream.CreateLC(*aFileStore); // create bitmap stream
+ aBitmap->ExternalizeL(bmpstream);
+ bmpstream.Close();
+ CleanupStack::Pop(); // bitmap stream
+ }
+ RStoreWriteStream rootstream;
+ TStreamId rootstreamid=rootstream.CreateLC(*aFileStore); // create root stream
+ rootstream.WriteInt32L(aNumSources); // number of bitmaps
+ for(count=0;count<aNumSources;count++)
+ rootstream<<ids[count]; // stream ids of bitmaps
+ rootstream.Close();
+ CleanupStack::Pop(); // root stream
+ aFileStore->SetRootL(rootstreamid);
+ CleanupStack::PopAndDestroy(nPushed); // ids [and bitmap]
+ }
+
+/** Gets the bitmap's scanline for the specified line starting from the
+specified point.
+The dither offset of the bitmap is taken to be TPoint(0,0).
+@param aBuf The buffer in which the scanline is returned.
+@param aPoint The start pixel.
+@param aLength The number of pixels to get.
+@param aDispMode Format to be used to write the data to the buffer.
+@publishedAll
+@released
+*/
+EXPORT_C void CFbsBitmap::GetScanLine(TDes8& aBuf,const TPoint& aPoint,TInt aLength,TDisplayMode aDispMode) const
+ {
+ GetScanLine(aBuf,aPoint,aLength,TPoint(0,0),aDispMode);
+ }
+
+/** Gets the bitmap's scanline for the specified line starting from the specified
+point and using the specified dither offset.
+@param aBuf The buffer in which the scanline is returned.
+@param aPixel The start pixel.
+@param aLength The number of pixels to get.
+@param aDitherOffset The dither offset of the bitmap.
+@param aDispMode Format to be used to write the data to the buffer.
+@publishedAll
+@released
+*/
+EXPORT_C void CFbsBitmap::GetScanLine(TDes8& aBuf,const TPoint& aPoint,TInt aLength,const TPoint& aDitherOffset,TDisplayMode aDispMode) const
+ {
+ if(!iHandle) return;
+ TUint32* data;
+ CBitwiseBitmap* bmp = BeginDataAccessAndGetCleanAddress(data);
+ CFbsRasterizer* rasterizer = NULL;
+ if ((iFlags & EIsExtendedBitmap) && iFbs)
+ {
+ rasterizer = iFbs->iHelper->Rasterizer();
+ if (rasterizer)
+ {
+ CFbsRasterizer::TBitmapDesc desc;
+ desc.iSizeInPixels = bmp->SizeInPixels();
+ desc.iDispMode = bmp->DisplayMode();
+ desc.iDataType = bmp->iUid;
+ desc.iData = data;
+ desc.iDataSize = bmp->iHeader.iBitmapSize - bmp->iHeader.iStructSize;
+ rasterizer->BeginBitmap(bmp->Extra()->iSerialNumber, desc, NULL);
+ }
+ }
+ bmp->GetScanLine(aBuf, aPoint, aLength, ETrue, aDitherOffset, aDispMode, data);
+ if (rasterizer)
+ {
+ rasterizer->EndBitmap(bmp->Extra()->iSerialNumber);
+ }
+ EndDataAccess(ETrue);
+ }
+
+/** Sets the bitmap's horizontal scanline at the specified y co-ordinate to the
+scanline contained in the buffer.
+@param aBuf The new scanline to be written to the bitmap.
+@param aY The y co-ordinate of the scanline.
+@panic FBSCLI 11 in debug builds if this is a compressed bitmap.
+@panic FBSCLI 28 in debug builds if this is a read-only bitmap.
+@publishedAll
+@released
+*/
+EXPORT_C void CFbsBitmap::SetScanLine(TDes8& aBuf,TInt aY) const
+ {
+ if (!iHandle)
+ return;
+ if (iFlags & EIsReadOnlyBitmapMask)
+ {
+ __ASSERT_DEBUG(EFalse, ::Panic(EFbsPanicBitmapReadOnly));
+ return;
+ }
+ TUint32* data;
+ CBitwiseBitmap* bmp = BeginDataAccessAndGetCleanAddress(data);
+ if (bmp->IsCompressed())
+ {
+ EndDataAccess(ETrue);
+ __ASSERT_DEBUG(EFalse, ::Panic(EFbsBitmapInvalidCompression));
+ return;
+ }
+ data = bmp->ScanLineAddress(data, aY);
+ TInt bytewidth = bmp->iByteWidth;
+ TInt bytelen=aBuf.Length();
+ if(bytelen<bytewidth) bytewidth=bytelen;
+ TInt wordlen=bytewidth>>2;
+ TUint32* ptr=(TUint32*)aBuf.Ptr();
+ TUint32* ptrlim=ptr+wordlen;
+ while(ptr<ptrlim)
+ *data++=*ptr++;
+ TInt limit=wordlen<<2;
+ if(limit<bytewidth)
+ {
+ TUint8* byteptr=(TUint8*)ptrlim;
+ TUint8* databyte=(TUint8*)data;
+ while(limit<bytewidth)
+ {
+ *databyte++=*byteptr++;
+ limit++;
+ }
+ }
+ EndDataAccess(EFalse);
+ }
+
+/** Gets the bitmap's vertical scanline starting at the specified x co-ordinate.
+Note: The method only works for uncompressed bitmaps.
+Note: The dither offset of the bitmap is taken to be TPoint(0,0).
+@param aBuf The buffer in which the vertical scanline is returned.
+@param aX The x co-ordinate of the vertical scanline.
+@param aDispMode Format to be used to write the data to the buffer.
+@panic FBSCLI 11 in debug builds if this is not an ucompressed bitmap or an extended bitmap.
+@publishedAll
+@released
+*/
+EXPORT_C void CFbsBitmap::GetVerticalScanLine(TDes8& aBuf,TInt aX,TDisplayMode aDispMode) const
+ {
+ GetVerticalScanLine(aBuf,aX,TPoint(0,0),aDispMode);
+ }
+
+/** Gets the bitmap's vertical scanline starting at the specified x co-ordinate
+and using the specified dither offset.
+Note: The method only works for uncompressed bitmaps.
+@param aBuf The buffer in which the vertical scanline will be returned.
+@param aX The x co-ordinate of the vertical scanline to get.
+@param aDitherOffset The dither offset of the bitmap.
+@param aDispMode Format to be used to write the data to the buffer.
+@panic FBSCLI 11 in debug builds if this is not an ucompressed bitmap or an extended bitmap.
+@publishedAll
+@released
+*/
+EXPORT_C void CFbsBitmap::GetVerticalScanLine(TDes8& aBuf,TInt aX,const TPoint& aDitherOffset,TDisplayMode aDispMode) const
+ {
+ if(!iHandle) return;
+ TUint32* data;
+ CBitwiseBitmap* bmp = BeginDataAccessAndGetCleanAddress(data);
+ CFbsRasterizer* rasterizer = NULL;
+ if ((iFlags & EIsExtendedBitmap) && iFbs)
+ {
+ rasterizer = iFbs->iHelper->Rasterizer();
+ if (rasterizer)
+ {
+ CFbsRasterizer::TBitmapDesc desc;
+ desc.iSizeInPixels = bmp->SizeInPixels();
+ desc.iDispMode = bmp->DisplayMode();
+ desc.iDataType = bmp->iUid;
+ desc.iData = data;
+ desc.iDataSize = bmp->iHeader.iBitmapSize - bmp->iHeader.iStructSize;
+ rasterizer->BeginBitmap(bmp->Extra()->iSerialNumber, desc, NULL);
+ }
+ }
+ bmp->GetVerticalScanLine(aBuf, aX, ETrue, aDitherOffset, aDispMode, data, rasterizer);
+ if (rasterizer)
+ {
+ rasterizer->EndBitmap(bmp->Extra()->iSerialNumber);
+ }
+ EndDataAccess(ETrue);
+ }
+
+/** Gets the handle number of the bitmap.
+The returned value can be used to give another thread access to the bitmap.
+@return The handle number of the bitmap.
+@publishedAll
+@released
+@see CFbsBitmap::Duplicate()
+*/
+EXPORT_C TInt CFbsBitmap::Handle() const
+ {
+ if(!iHandle)
+ return(0);
+ if (iFlags & EIsRomBitmap)
+ return TInt(iAddressPointer);
+ else
+ return(iServerHandle);
+ }
+
+/** Creates a bitmap header.
+This is used when streaming bitmaps to stores.
+@return The bitmap header for the bitmap.
+@publishedAll
+@released
+*/
+EXPORT_C SEpocBitmapHeader CFbsBitmap::Header() const
+ {
+ if (iHandle)
+ return CleanAddress()->iHeader;
+ SEpocBitmapHeader header;
+ return(header);
+ }
+
+/** Converts a horizontal dimension on the graphics device from pixels to twips.
+@param aPixels A horizontal dimension on the graphics device in pixels.
+@return A horizontal dimension on the graphics device in twips.
+@publishedAll
+@released
+*/
+EXPORT_C TInt CFbsBitmap::HorizontalPixelsToTwips(TInt aPixels) const
+ {
+ if(iHandle==NULL) return(0);
+ return CleanAddress()->HorizontalPixelsToTwips(aPixels);
+ }
+
+/** Converts a horizontal dimension on the graphics device from twips to pixels.
+@param aTwips A horizontal dimension on the graphics device in twips.
+@return A horizontal dimension on the graphics device in pixels.
+@publishedAll
+@released
+*/
+EXPORT_C TInt CFbsBitmap::HorizontalTwipsToPixels(TInt aTwips) const
+ {
+ if(iHandle==NULL) return(0);
+ return CleanAddress()->HorizontalTwipsToPixels(aTwips);
+ }
+
+/** Gets the RGB value of the specified pixel.
+Note: The method only works for uncompressed bitmaps and extended bitmaps.
+@param aColor On return, the RGB value of the specified pixel.
+@param aPixel The pixel whose colour is to be determined.
+@panic FBSCLI 11 in debug builds if this is a compressed bitmap.
+@publishedAll
+@released
+*/
+EXPORT_C void CFbsBitmap::GetPixel(TRgb& aColor,const TPoint& aPoint) const
+ {
+ if(!iHandle)
+ {
+ return;
+ }
+
+ TUint32* data;
+ CBitwiseBitmap* bmp = BeginDataAccessAndGetCleanAddress(data);
+ CFbsRasterizer* rasterizer = NULL;
+ if ((iFlags & EIsExtendedBitmap) && iFbs)
+ {
+ rasterizer = iFbs->iHelper->Rasterizer();
+ if (rasterizer)
+ {
+ CFbsRasterizer::TBitmapDesc desc;
+ desc.iSizeInPixels = bmp->SizeInPixels();
+ desc.iDispMode = bmp->DisplayMode();
+ desc.iDataType = bmp->iUid;
+ desc.iData = data;
+ desc.iDataSize = bmp->iHeader.iBitmapSize - bmp->iHeader.iStructSize;
+ rasterizer->BeginBitmap(bmp->Extra()->iSerialNumber, desc, NULL);
+ }
+ }
+ bmp->GetPixel(aColor, aPoint, data, rasterizer);
+ if (rasterizer)
+ {
+ rasterizer->EndBitmap(bmp->Extra()->iSerialNumber);
+ }
+ EndDataAccess(ETrue);
+ }
+
+/** Gets the pixel-size of the bitmap.
+@return The size of the bitmap, in pixels.
+@publishedAll
+@released
+*/
+EXPORT_C TSize CFbsBitmap::SizeInPixels() const
+ {
+ TSize zero;
+ if(!iHandle) return(zero);
+ return CleanAddress()->SizeInPixels();
+ }
+
+/** Sets the twip-size of the bitmap by converting the bitmaps pixel-size from
+pixels to twips, using the conversion functions in the specified graphics
+device map.
+@param aMap The graphics device map to be used for providing pixel to twip
+conversion.
+@publishedAll
+@released
+*/
+EXPORT_C void CFbsBitmap::SetSizeInTwips(const MGraphicsDeviceMap* aMap)
+ {
+ if (!iHandle || (iFlags & EIsRomBitmap) || aMap == NULL)
+ return;
+ TSize size=SizeInPixels();
+ size.iWidth=aMap->HorizontalPixelsToTwips(size.iWidth);
+ size.iHeight=aMap->VerticalPixelsToTwips(size.iHeight);
+ iFbs->SetCallBackPtr(&iServerHandle);
+ iFbs->CallBack();
+ // SizeInPixels() called CleanAddress() so call Address() now to make sure we don't clean the bitmap twice
+ Address()->iHeader.iSizeInTwips=size;
+ }
+
+/** Sets the twip-size of the bitmap directly to the specified size.
+@param aSizeInTwips The new size of the bitmap, in twips.
+@publishedAll
+@released
+*/
+EXPORT_C void CFbsBitmap::SetSizeInTwips(const TSize& aSizeInTwips)
+ {
+ if (!iHandle || (iFlags & EIsRomBitmap))
+ return;
+ iFbs->SetCallBackPtr(&iServerHandle);
+ iFbs->CallBack();
+ CleanAddress()->iHeader.iSizeInTwips = aSizeInTwips;
+ }
+
+/** Externalises the bitmap to the specified stream. Not supported for extended bitmaps.
+@param aStream The write stream.
+@publishedAll
+@released
+*/
+EXPORT_C void CFbsBitmap::ExternalizeL(RWriteStream& aStream) const
+ {
+ if (!iHandle)
+ User::Leave(KErrGeneral);
+ BeginDataAccess();
+ Address()->ExternalizeL(aStream, *this);
+ EndDataAccess(ETrue);
+ }
+
+/** Externalises that area of the bitmap contained within a specified
+rectangular area. Not supported for extended bitmaps.
+@param aStream The write stream
+@param aRect The rectangular area of the bitmap to externalise. The bitmap
+that is externalized will be of this size.
+@publishedAll
+@released
+*/
+EXPORT_C void CFbsBitmap::ExternalizeRectangleL(RWriteStream& aStream,const TRect& aRect) const
+ {
+ if (!iHandle)
+ User::Leave(KErrGeneral);
+ BeginDataAccess();
+ Address()->ExternalizeRectangleL(aStream, aRect, *this);
+ EndDataAccess(ETrue);
+ }
+
+/** Internalises a CFbsBitmap from a stream.
+@param aStream The read stream.
+@publishedAll
+@released
+*/
+EXPORT_C void CFbsBitmap::InternalizeL(RReadStream& aStream)
+ {
+ if(!iFbs) User::Leave(KErrCouldNotConnect);
+ Reset();
+ SEpocBitmapHeader header;
+ CBitwiseBitmap::InternalizeHeaderL(aStream,header);
+
+ TDisplayMode dispmode = CBitwiseBitmap::DisplayMode(header.iBitsPerPixel,header.iColor);
+ User::LeaveIfError(Create(header.iSizeInPixels,dispmode));
+
+ TUint32* data;
+ CBitwiseBitmap* bmp=BeginDataAccessAndGetCleanAddress(data);
+ bmp->iHeader=header;
+ TInt bytesize = header.iBitmapSize - header.iStructSize;
+ if (bytesize > 0)
+ {
+ bmp->DoInternalizeL(aStream, bytesize, data);
+ EndDataAccess(EFalse);
+ }
+ else
+ {
+ EndDataAccess(ETrue);
+ }
+ }
+
+EXPORT_C TInt CFbsBitmap::Compress()
+ {
+ return Compress(ERLECompression);
+ }
+
+/** Compresses bitmap in RAM.
+@param aScheme specifies preferred compression type ERLECompression or EPaletteCompression
+@return KErrNone on success, KErrGeneral if the bitmap handle is NULL, KErrAccessDenied if
+the bitmap is in ROM or it is an extended bitmap, otherwise one of the system wide error codes.
+@publishedAll
+@released
+*/
+EXPORT_C TInt CFbsBitmap::Compress(TBitmapfileCompressionScheme aScheme)
+ {
+ if (!iHandle)
+ return KErrGeneral;
+ if (iFlags & EIsReadOnlyBitmapMask)
+ return KErrAccessDenied;
+ TPckgBuf<TBmpHandles> handlebuf;
+ TIpcArgs args(iHandle, aScheme, &handlebuf);
+ TInt err = iFbs->SendCommand(EFbsMessBitmapCompress, args);
+ if (err != KErrNone)
+ return err;
+ iHandle = handlebuf().iHandle;
+ iServerHandle = handlebuf().iServerHandle;
+ iAddressPointer = (CBitwiseBitmap*)(iFbs->HeapBase() + handlebuf().iAddressOffset);
+ return KErrNone;
+ }
+
+/** Submits the bitmap for asynchronous background compression.
+@param aRequestStatus The request status which will be completed with the appropriate error code after the compression has finished
+The error code will be KErrNone on success, KErrGeneral if the bitmap handle is NULL, KErrAccessDenied if the
+bitmap is in ROM or it is an extended bitmap, otherwise one of the system wide error codes.
+@publishedAll
+@released
+*/
+EXPORT_C void CFbsBitmap::CompressInBackground(TRequestStatus& aRequestStatus)
+ {
+ CompressInBackground(aRequestStatus, ERLECompression);
+ }
+
+/** Submits the bitmap for asynchronous background compression. No notification will be provided when the compression has completed.
+@return KErrNone if the bitmap was successfully submitted to the background compression queue, KErrGeneral if the bitmap handle is NULL,
+KErrAccessDenied if the bitmap is in ROM or it is an extended bitmap, otherwise another of the system-wide error codes.
+@publishedAll
+@released
+*/
+EXPORT_C TInt CFbsBitmap::CompressInBackground()
+ {
+ return CompressInBackground(ERLECompression);
+ }
+
+/** Submits the bitmap for asynchronous background compression.
+@param aRequestStatus The request status which will be completed with the appropriate error code after the compression has finished.
+The error code will be KErrNone on success, KErrGeneral if the bitmap handle is NULL, KErrAccessDenied if the
+bitmap is in ROM or it is an extended bitmap, otherwise one of the system wide error codes.
+@param aScheme Specifies preferred compression type: ERLECompression or EPaletteCompression
+@publishedAll
+@released
+*/
+EXPORT_C void CFbsBitmap::CompressInBackground(TRequestStatus& aRequestStatus, TBitmapfileCompressionScheme aScheme)
+ {
+ TRequestStatus* reqStat = &aRequestStatus;
+ aRequestStatus = KRequestPending;
+ if (!iHandle)
+ User::RequestComplete(reqStat, KErrGeneral);
+ else if (iFlags & EIsReadOnlyBitmapMask)
+ User::RequestComplete(reqStat, KErrAccessDenied);
+ else
+ {
+ TIpcArgs args(iHandle, aScheme, ETrue);
+ iFbs->SendCommand(EFbsMessBitmapBgCompress, args, aRequestStatus);
+ }
+ }
+
+/** Submits the bitmap for asynchronous background compression. No notification will be provided when the compression has completed.
+@return KErrNone if the bitmap was successfully submitted to the background compression queue, KErrGeneral if the bitmap handle is NULL,
+KErrAccessDenied if the bitmap is in ROM or it is an extended bitmap, otherwise another of the system-wide error codes.
+@publishedAll
+@released
+*/
+EXPORT_C TInt CFbsBitmap::CompressInBackground(TBitmapfileCompressionScheme aScheme)
+ {
+ if (!iHandle)
+ return KErrGeneral;
+ if (iFlags & EIsReadOnlyBitmapMask)
+ return KErrAccessDenied;
+ TIpcArgs args(iHandle, aScheme, EFalse);
+ return iFbs->SendCommand(EFbsMessBitmapBgCompress, args);
+ }
+
+/**Tests whether the bitmap located in RAM has been compressed.
+@return ETrue if the bitmap is compressed, EFalse otherwise.
+@publishedAll
+@released
+*/
+EXPORT_C TBool CFbsBitmap::IsCompressedInRAM() const
+ {
+ CBitwiseBitmap* bitmap = CleanAddress();
+ if (bitmap==NULL)
+ {
+ return EFalse;
+ }
+ return bitmap->IsCompressedInRAM();
+ }
+
+/** Gets the twip-size of the bitmap.
+@return The size of the bitmap, in twips.
+@publishedAll
+@released
+*/
+EXPORT_C TSize CFbsBitmap::SizeInTwips() const
+ {
+ TSize zero;
+ if(iHandle==NULL) return(zero);
+ return CleanAddress()->SizeInTwips();
+ }
+
+/** Converts a vertical dimension on the graphics device from pixels to twips.
+@param aPixels A vertical dimension on the graphics device in pixels.
+@return A vertical dimension on the graphics device in twips.
+@publishedAll
+@released
+*/
+EXPORT_C TInt CFbsBitmap::VerticalPixelsToTwips(TInt aPixels) const
+ {
+ if(iHandle==NULL) return(0);
+ return CleanAddress()->VerticalPixelsToTwips(aPixels);
+ }
+
+/** Converts a vertical dimension on the graphics device from twips to pixels.
+@param aTwips A vertical dimension on the graphics device in twips.
+@return A vertical dimension on the graphics device in pixels.
+@publishedAll
+@released
+*/
+EXPORT_C TInt CFbsBitmap::VerticalTwipsToPixels(TInt aTwips) const
+ {
+ if(iHandle==NULL) return(0);
+ return CleanAddress()->VerticalTwipsToPixels(aTwips);
+ }
+
+/** Tests whether or not the specified file is in ROM.
+@param aFilename The name of the file.
+@param aWord On return, contains the address of the file in ROM.
+@return ETrue if the file is in the ROM; EFalse otherwise.
+@publishedAll
+@released
+*/
+EXPORT_C TBool CFbsBitmap::IsFileInRom(const TDesC& aFilename,TUint32*& aWord)
+ {
+ RFbsSession* fbs=RFbsSession::GetSession();
+ __ASSERT_ALWAYS(fbs,Panic(EFbsPanicNoConnection));
+ return fbs->LookupBitmapInROM (aFilename, (TAny*&)aWord);
+ }
+
+/** Tests whether or not the specified file is in ROM.
+@param aFile The file handle
+@param aWord On return, contains the address of the file in ROM.
+@return ETrue if the file is in the ROM; EFalse otherwise.
+@publishedAll
+@released
+*/
+EXPORT_C TBool CFbsBitmap::IsFileInRom(RFile& aFile,TUint32*& aWord)
+ {
+ // cannot use rom lookup cache as filename is not available
+ // offset must be initialised to zero to indicate beginning of the file
+ aWord = 0;
+ return aFile.Seek(ESeekAddress,(TInt&)aWord)==KErrNone;
+ }
+
+/** Tests whether or not the bitmap is monochrome.
+Monochrome bitmaps have a display-mode of 1 bit-per-pixel.
+@return ETrue if the bitmap is monochrome; EFalse otherwise.
+@publishedAll
+@released
+*/
+EXPORT_C TBool CFbsBitmap::IsMonochrome() const
+ {
+ if(!iHandle) return(EFalse);
+ TUint32* data;
+ CBitwiseBitmap* bmp = BeginDataAccessAndGetCleanAddress(data);
+ TBool isMonochrome = bmp->IsMonochrome(data);
+ EndDataAccess(ETrue);
+ return isMonochrome;
+ }
+
+/** Marks the beginning of direct access to the bitmap data.
+This function prepares the bitmap for direct access to its pixel data
+and should be used before calling DataAddress(), otherwise performance
+may be degraded on certain platforms.
+Calls to BeginDataAccess() must be coupled with subsequent calls to EndDataAccess().
+
+@publishedAll
+@released
+@see CFbsBitmap::DataAddress()
+@see CFbsBitmap::EndDataAccess()
+*/
+EXPORT_C void CFbsBitmap::BeginDataAccess() const
+ {
+ if (!iHandle)
+ return;
+ (void)CleanAddress(); //called for side-effect to make sure bitmap reference is current. Should be low overhead.
+ const_cast<CFbsBitmap*>(this)->iUseCount++;
+ }
+
+/** Marks the end of direct access to the bitmap data.
+Use this function after ending direct access to the bitmap data.
+Calls to EndDataAccess() must correspond to prior calls to BeginDataAccess().
+See BeginDataAccess() for more details.
+
+@param aReadOnly Whether or not the bitmap data has only been read since
+ the corresponding call to BeginDataAccess().
+
+@publishedAll
+@released
+@param aReadOnly True if the bitmap data had only been read. False if the data has been modified.
+@see CFbsBitmap::BeginDataAccess()
+*/
+EXPORT_C void CFbsBitmap::EndDataAccess(TBool aReadOnly) const
+ {
+ if (!iHandle)
+ return;
+ const_cast<CFbsBitmap*>(this)->iUseCount--;
+ if (!aReadOnly && !(iFlags & EIsReadOnlyBitmapMask))
+ User::LockedInc(iAddressPointer->Extra()->iTouchCount);
+ }
+
+/** Locks the global bitmap heap.
+This function is deprecated, since it is no longer necessary to lock the global
+bitmap heap to prevent the pixel data from being moved in memory asynchronously,
+as the value returned by DataAddress() can now only change as a result of bitmap
+operations explicitly requested by clients of the Font and Bitmap Server.
+Calls to LockHeap() should be replaced by calls to BeginDataAccess().
+
+Calls to LockHeap() must be coupled with subsequent calls to CFbsBitmap::UnlockHeap().
+Code called between a LockHeap() - UnlockHeap() pair must not include any other calls to
+CFbsBitmap methods, which internally may call CFbsBitmap::LockHeap(). Also, code must
+not leave between a LockHeap() - UnlockHeap() pair.
+@note IMPORTANT: CFbsBitmap::LockHeap() cannot be used as a means of synchronization between
+threads concurrently accessing bitmap data.
+
+@publishedAll
+@deprecated
+@see CFbsBitmap::UnlockHeap()
+@see CFbsBitmap::BeginDataAccess()
+*/
+EXPORT_C void CFbsBitmap::LockHeap(TBool /*aAlways*/) const
+ {
+ BeginDataAccess();
+#ifdef SYMBIAN_DEBUG_FBS_LOCKHEAP
+ //These debug checks now refer to the cleaned data address
+ if (!iHandle)
+ return;
+ if (!(iFlags & EIsRomBitmap)) // can't do anything with ROM bitmaps
+ {
+ TThreadId threadId = RThread().Id();
+ iFbs->iHelper->iDebugMutex.Wait();
+ if (iAddressPointer->Extra()->iLockCount++ == 0)
+ {
+ __ASSERT_ALWAYS(iAddressPointer->Extra()->iThreadId == TThreadId(KNullThreadId), Panic(EFbsPanicBadHeapLock));
+ iAddressPointer->Extra()->iThreadId = threadId;
+ }
+ else
+ __ASSERT_ALWAYS(iAddressPointer->Extra()->iThreadId == threadId, Panic(EFbsPanicBadHeapLock));
+ iFbs->iHelper->iDebugMutex.Signal();
+ }
+#endif
+ }
+
+/** Unlocks the global heap.
+This function is deprecated. See LockHeap() for more details.
+Calls to UnlockHeap() should be replaced by calls to EndDataAccess().
+Calls to UnlockHeap() must correspond to prior calls to LockHeap() or LockHeapLC().
+
+@publishedAll
+@deprecated
+@see CFbsBitmap::LockHeap()
+@see CFbsBitmap::EndDataAccess()
+*/
+EXPORT_C void CFbsBitmap::UnlockHeap(TBool /*aAlways*/) const
+ {
+#ifdef SYMBIAN_DEBUG_FBS_LOCKHEAP
+ if (!iHandle)
+ return;
+ if (!(iFlags & EIsRomBitmap)) // can't do anything with ROM bitmaps
+ {
+ TThreadId threadId = RThread().Id();
+ iFbs->iHelper->iDebugMutex.Wait();
+ __ASSERT_ALWAYS(iAddressPointer->Extra()->iLockCount > 0, Panic(EFbsPanicBadHeapLock));
+ __ASSERT_ALWAYS(iAddressPointer->Extra()->iThreadId == threadId, Panic(EFbsPanicBadHeapLock));
+ if (--iAddressPointer->Extra()->iLockCount == 0)
+ iAddressPointer->Extra()->iThreadId = TThreadId(KNullThreadId);
+ iFbs->iHelper->iDebugMutex.Signal();
+ }
+#endif
+ EndDataAccess();
+ }
+
+/** Locks the global bitmap heap, leaving on the clean-up stack a pointer
+to a TCleanupItem that unlocks the heap on deletion.
+Use this function instead of LockHeap() if code may leave between the
+LockHeap() - UnlockHeap() pair. Calls to LockHeapLC() must be coupled with
+subsequent calls to CFbsBitmap::UnlockHeap() or CleanupStack::PopAndDestroy().
+This function is deprecated. See CFbsBitmap::LockHeap() for more details.
+
+@publishedAll
+@deprecated
+@see CFbsBitmap::LockHeap()
+*/
+EXPORT_C void CFbsBitmap::LockHeapLC(TBool /*aAlways*/) const
+ {
+ LockHeap();
+ TCleanupItem cleanitem(CFbsBitmap::UnlockHeap, (TAny*)this);
+ CleanupStack::PushL(cleanitem);
+ }
+
+EXPORT_C void CFbsBitmap::UnlockHeap(TAny* aFbsBitmap)
+ {
+ ((CFbsBitmap*)aFbsBitmap)->UnlockHeap();
+ }
+
+/** Tests whether the bitmap is volatile.
+A bitmap becomes volatile if CFbsBitmap::DataAdress() is called without
+CFbsBitmap::BeginDataAccess() having been called before and it can become non-volatile
+again if a resizing or compression is performed.
+
+@internalTechnology
+@prototype
+*/
+EXPORT_C TBool CFbsBitmap::IsVolatile() const
+ {
+ if (!iHandle)
+ return EFalse;
+ return CleanAddress()->iSettings.IsVolatileBitmap();
+ }
+
+/** Tests how many times the bitmap has been touched.
+A bitmap is touched whenever CFbsBitmap::EndDataAccess() is called with the parameter
+aReadOnly set to EFalse and also whenever a resizing or compression is performed.
+
+@internalTechnology
+@prototype
+@return The number of times the bitmap has been touched.
+*/
+EXPORT_C TInt CFbsBitmap::TouchCount() const
+ {
+ if (!iHandle || (iFlags & EIsReadOnlyBitmapMask))
+ return 0; // A read-only bitmap can never be touched.
+ return CleanAddress()->Extra()->iTouchCount;
+ }
+
+/** Returns the serial number of the bitmap
+The serial number is unique to this bitmap.
+The serial number is a signed 64-bit integer, with only the positive values being assigned.
+As ROM bitmaps do not have serial numbers, the serial number will use the negative range
+of values so that ROM bitmap's serial number cannot be the same as a RAM bitmap's.
+ROM bitmap's address pointers are unique to the ROM bitmap, so the serial number will just
+be negative value of the address pointer.
+
+@internalTechnology
+@prototype
+@return The unique serial number for the bitmap
+*/
+EXPORT_C TInt64 CFbsBitmap::SerialNumber() const
+ {
+ if (!iHandle)
+ return 0;
+ if (iFlags & EIsRomBitmap)
+ return -TInt64(reinterpret_cast<TUint32>(iAddressPointer));
+ return CleanAddress()->Extra()->iSerialNumber;
+ }
+
+/** Tests whether the bitmap is large.
+@return ETrue if the bitmap is large, EFalse if not.
+@publishedAll
+@released
+*/
+EXPORT_C TBool CFbsBitmap::IsLargeBitmap() const
+ {
+ CBitwiseBitmap* bitmap = CleanAddress();
+ if (!bitmap)
+ {
+ return EFalse;
+ }
+ return bitmap->IsLargeBitmap();
+ }
+
+/** Returns the handle for the hardware bitmap which this CFbsBitmap is using.
+@return The handle to the hardware bitmap. The handle is NULL if it is not
+a hardware bitmap.
+@publishedAll
+@released
+*/
+EXPORT_C TInt CFbsBitmap::HardwareBitmapHandle() const
+ {
+ CBitwiseBitmap* bitmap = CleanAddress();
+ if (!bitmap)
+ {
+ return 0;
+ }
+ return bitmap->HardwareBitmapHandle();
+ }
+
+/** Gets the attributes of the bitmap's palette.
+This is not currently supported.
+@param aModifiable On return, whether or not the palette is modifiable.
+@param aNumEntries On return, the number of entries in the palette.
+@publishedAll
+@released
+*/
+EXPORT_C void CFbsBitmap::PaletteAttributes(TBool& aModifiable,TInt& aNumEntries) const
+ {
+ aModifiable=EFalse;
+ aNumEntries=0;
+ }
+
+/** Sets the bitmap's palette.
+This is not currently supported.
+@param aPalette Not used.
+@publishedAll
+@released
+*/
+EXPORT_C void CFbsBitmap::SetPalette(CPalette* /*aPalette*/)
+ {
+ }
+
+/** Gets the bitmap's palette.
+This is not currently supported.
+@param aPalette Not used.
+@return KErrNotSupported.
+@publishedAll
+@released
+*/
+EXPORT_C TInt CFbsBitmap::GetPalette(CPalette*& /*aPalette*/) const
+ {
+ return(KErrNotSupported);
+ }
+
+/**
+@internalComponent
+This method loads a bitmap from an opened file handle.
+
+@param aFile mbm or rsc file handle (rsc file format: header + rsc
+ data section + mbm file section).
+@param aId Bitmap ID - should be less than mbm file bitmaps count.
+@param aShareIfLoaded Specifies whether or not the loaded bitmap will be
+ made available for sharing between FBSERV clients.
+@param aFileOffset mbm file section offset into rsc file.
+@return KErrNone if successful, otherwise another
+ of the system-wide error codes.
+*/
+TInt CFbsBitmap::DoLoad(RFile& aFile,TInt32 aId,TBool aShareIfLoaded,TUint aFileOffset)
+ {
+ TInt ret=KErrNone;
+ TPckgBuf<TBmpHandles> handlebuf;
+ TPckgBuf<TLoadBitmapArg> loadBitmapArg;
+ loadBitmapArg().iBitmapId = aId;
+ loadBitmapArg().iShareIfLoaded = TInt(aShareIfLoaded);
+ loadBitmapArg().iFileOffset = aFileOffset;
+ //Getting the RFs Handle(2) and RFile handle(3) into a TIpcArgs into 2nd and 3rd argument
+ TIpcArgs fileargs;
+ ret=aFile.TransferToServer(fileargs,2,3);
+ if (ret!=KErrNone)
+ return ret;
+ fileargs.Set(0,&handlebuf);
+ fileargs.Set(1,&loadBitmapArg);
+ ret=iFbs->SendCommand(EFbsMessBitmapLoad,fileargs);
+ if(ret!=KErrNone) return(ret);
+ iHandle=handlebuf().iHandle;
+ iServerHandle=handlebuf().iServerHandle;
+ iAddressPointer=(CBitwiseBitmap*)(iFbs->HeapBase()+handlebuf().iAddressOffset);
+ ret = iFbs->iHelper->AddBitmap(*this);
+ if (ret != KErrNone)
+ return ret;
+ return iFbs->AllocScanLineBuffer(iAddressPointer->iByteWidth+4);
+ }
+
+/**
+@internalComponent
+This method loads a bitmap from the mbm or rsc file specified by the filename.
+
+@param aFileName mbm or rsc file name (rsc file format: header + rsc
+ data section + mbm file section).
+@param aId Bitmap ID - should be less than mbm file bitmaps count.
+@param aShareIfLoaded Specifies whether or not the loaded bitmap will be
+ made available for sharing between FBSERV clients.
+@param aFileOffset mbm file section offset into rsc file.
+@return KErrNone if successful, otherwise another
+ of the system-wide error codes.
+*/
+TInt CFbsBitmap::DoLoad(const TDesC& aFileName,TInt32 aId,TBool aShareIfLoaded,TUint aFileOffset)
+ {
+ TInt ret=KErrNone;
+ TPckgBuf<TBmpHandles> handlebuf;
+ TPckgBuf<TLoadBitmapArg> loadBitmapArg;
+ loadBitmapArg().iBitmapId = aId;
+ loadBitmapArg().iShareIfLoaded = TInt(aShareIfLoaded);
+ loadBitmapArg().iFileOffset = aFileOffset;
+ TIpcArgs fileargs;
+ fileargs.Set(0,&handlebuf);
+ fileargs.Set(1,&loadBitmapArg);
+ fileargs.Set(2,&aFileName);
+ ret=iFbs->SendCommand(EFbsMessBitmapLoadFast,fileargs);
+ if(ret!=KErrNone) return(ret);
+ iHandle=handlebuf().iHandle;
+ iServerHandle=handlebuf().iServerHandle;
+ iAddressPointer=(CBitwiseBitmap*)(iFbs->HeapBase()+handlebuf().iAddressOffset);
+ ret = iFbs->iHelper->AddBitmap(*this);
+ if (ret != KErrNone)
+ return ret;
+ return iFbs->AllocScanLineBuffer(iAddressPointer->iByteWidth+4);
+ }
+
+/**
+@internalComponent
+This method handles very special case when the rsc file is in RAM, but it
+contains ROM mbm file. ROM mbm file format is different than RAM mbm file
+format and ROM mbm file cannot be loaded into RAM using standard techniques
+(used by CFbsBitmap::DoLoad()). We have to check it is really a ROM mbm file.
+If it is - we have to allocate the right amount of RAM, read and copy
+requested ROM bitmap to the allocated RAM.
+
+@leave KErrNotSupported if this is a RAM rsc file with ROM mbm file section,
+ or any of the RFile related error codes.
+@param aFileName rsc file name (rsc file format: header + rsc data section +
+ mbm file section).
+@param aId Bitmap ID - should be less than mbm file bitmaps count.
+@param aFileOffset mbm file section offset into rsc file.
+@return EFalse - this is not a ROM mbm file. ETrue - this is a ROM mbm file
+ and requested by aId bitmmap is loaded.
+*/
+TBool CFbsBitmap::LoadShiftedRomBmpL(const TDesC& aFileName, TInt32 aId, TUint aFileOffset)
+ {
+ RFile mbm_file;
+ ::CleanupClosePushL(mbm_file);
+ User::LeaveIfError(mbm_file.Open(iFbs->FileServer(), aFileName, EFileRead | EFileShareReadersOnly));
+ TInt pos = static_cast <TInt> (aFileOffset);
+ User::LeaveIfError(mbm_file.Seek(ESeekStart, pos));//move to the beginning of the mbm file section
+ TBuf8<sizeof(CBitwiseBitmap)> buf;
+ //Check if it is a ROM mbm file
+ User::LeaveIfError(mbm_file.Read(buf, sizeof(KMultiBitmapRomImageUid.iUid)));//Bitmap file UID - ROM or RAM
+ TInt32 mbm_uid = *(reinterpret_cast <const TInt32*> (buf.Ptr()));
+ TBool loaded = EFalse;
+ if(mbm_uid == KMultiBitmapRomImageUid.iUid)
+ {
+ if(!KRomMBMInRamRSC)
+ {
+ User::Leave(KErrNotSupported);
+ }
+ else
+ {
+ User::LeaveIfError(mbm_file.Read(buf, sizeof(TInt32)));//Number of bitmaps
+ TInt32 bmp_cnt = *(reinterpret_cast <const TInt32*> (buf.Ptr()));
+ if(aId >= bmp_cnt)
+ {
+ User::Leave(KErrNotFound);
+ }
+ for(TInt i=0;i<aId;i++) //Read bitmap UIDs located before aId.
+ {
+ User::LeaveIfError(mbm_file.Read(buf, sizeof(aId)));
+ }
+ User::LeaveIfError(mbm_file.Read(buf, sizeof(TInt32)));//Read the offset of aId bitmap.
+ TInt bmp_offset = *(reinterpret_cast <const TInt32*> (buf.Ptr())) + TInt(aFileOffset);
+ pos = static_cast <TInt> (bmp_offset);
+ User::LeaveIfError(mbm_file.Seek(ESeekStart, pos));//move the file pointer to the bitmap
+ User::LeaveIfError(mbm_file.Read(buf, sizeof(CBitwiseBitmap)));//Read CBitwiseBitmap data (without the bitmap data)
+ const CBitwiseBitmap* bmp = reinterpret_cast <const CBitwiseBitmap*> (buf.Ptr());
+ //Calculate bitmap data size, alocate enough memory for the bitmap, copy CBitwiseBitmap
+ //members first, read the bitmap data from the file, copy the data to the allocated memory,
+ //initialize iRomPointer.
+ //If sizeof(CBitwiseBitmap) != real size of CBitwiseBitmap then we could have problems,
+ //because bitmap data won't be copied at the right position.
+ TInt size = bmp->iHeader.iBitmapSize - sizeof(SEpocBitmapHeader) + sizeof(CBitwiseBitmap);
+ TUint8* bmp_mem = new (ELeave) TUint8[size];
+ //There is no need bmp_mem to be aligned, because it is a pointer to a RAM block of memory.
+ TCleanupItem cleanitem(FreeMem, bmp_mem);
+ CleanupStack::PushL(cleanitem);
+ Mem::Copy(bmp_mem, bmp, sizeof(CBitwiseBitmap));
+ TPtr8 pbmp(bmp_mem + sizeof(CBitwiseBitmap), size - sizeof(CBitwiseBitmap));
+ User::LeaveIfError(mbm_file.Read(pbmp, size - sizeof(CBitwiseBitmap)));//read the bitmap data. We've already read the CBitwiseBitmap data.
+ CleanupStack::Pop(bmp_mem);
+ iAddressPointer = reinterpret_cast<CBitwiseBitmap*>(bmp_mem);
+ iFlags = EIsRomBitmap;
+ iHandle = 1;
+ loaded = ETrue;
+ }//end of - if(!KRomMBMInRamRSC) - "else" part
+ }//end of - if(mbm_uid == KMultiBitmapRomImageUid.iUid)
+ CleanupStack::PopAndDestroy();//mbm_file
+ return loaded;
+ }
+
+/**
+Swaps the bitmap's width and height.
+For example, if the bitmap's size is (40, 20), the new size will be (20, 40).
+Bitmap content is not preserved.
+@publishedAll
+@released
+@return KErrNone if the call was successful, KErrGeneral if the bitmap handle is
+invalid, KErrAccessDenied if the bitmap is in ROM, KErrNotSupported if the bitmap
+is a hardware bitmap or an extended bitmap.
+*/
+EXPORT_C TInt CFbsBitmap::SwapWidthAndHeight()
+ {
+ if(!iHandle)
+ {
+ return KErrGeneral;
+ }
+ TUint32* data;
+ CBitwiseBitmap* bmp = BeginDataAccessAndGetCleanAddress(data);
+
+ // Check the new bitmap size here then decide whether to swap the bitmap on the
+ // client side or send it to be done on the server and reallocate memory for it.
+ TInt newWidthInBytes = CBitwiseBitmap::ByteWidth(bmp->iHeader.iSizeInPixels.iHeight, bmp->iSettings.CurrentDisplayMode());
+ TInt64 hugeDataSize = TInt64(bmp->iHeader.iSizeInPixels.iWidth) * TInt64(newWidthInBytes);
+
+ TInt err = KErrNone;
+ // If the size of the new swapped bitmap is less than or equal its original size before the swap,
+ // then we do not need to reallocate memory. The swapping is straight forward.
+ if( I64HIGH(hugeDataSize) == 0 && I64LOW(hugeDataSize) <= TUint(bmp->iHeader.iBitmapSize - bmp->iHeader.iStructSize) )
+ {
+ err = bmp->SwapWidthAndHeight(data);
+ // Even though used DataAddress() as read-only, need to increment touch count, so indicate that data has been written
+ EndDataAccess(EFalse);
+ }
+ // Otherwise we need to reallocate memory. We do this by using the already exisitng
+ // Resize() function as a work around- Code Reusability!!
+ else
+ {
+ EndDataAccess(ETrue); // Used DataAddress() to read only.
+ // Resize will increase touch counter
+ err = Resize(TSize(bmp->iHeader.iSizeInPixels.iHeight, bmp->iHeader.iSizeInPixels.iWidth));
+ }
+ return err;
+ }
+
+/** Gets a pointer to the decompression buffer owned by this thread's FBServ session.
+@param aSize The size in bytes of the scan lines to decompress.
+@return A pointer to the decompression buffer or NULL if there is no FBServ session.
+@internalTechnology
+@released
+*/
+EXPORT_C HBufC8* CFbsBitmap::GetDecompressionBuffer(TInt aSize)
+ {
+ RFbsSession* ses=RFbsSession::GetSession();
+ return ses? ses->GetDecompressionBuffer(aSize) : NULL;
+ }
+
+/** Gets a pointer to the rasterizer for extended bitmaps if present.
+@return A pointer to the rasterizer owned by this thread's FBServ session.
+@return NULL if the rasterizer is not present.
+@internalTechnology
+@prototype
+*/
+EXPORT_C CFbsRasterizer* CFbsBitmap::Rasterizer()
+ {
+ RFbsSession* session = RFbsSession::GetSession();
+ return session ? session->iHelper->Rasterizer() : NULL;
+ }
+
+/** Loads a specific bitmap from an opened multi-bitmap file handle.
+The bitmap may be shared by other font and bitmap server clients.
+@param aFile The handle of the multi-bitmap (.mbm) file.
+@param aId The bitmap identifier.
+@param aShareIfLoaded Specifies whether or not the loaded bitmap will be made
+available for sharing between font and bitmap server clients.
+@return KErrNone if successful, otherwise another of the system error
+codes.
+@publishedAll
+@released
+*/
+EXPORT_C TInt CFbsBitmap::Load(RFile& aFile,TInt32 aId/*=0*/,TBool aShareIfLoaded/*=ETrue*/)
+ {
+ return Load(aFile,aId,aShareIfLoaded,0);
+ }
+
+/** Loads a specific bitmap from an opened multi-bitmap file handle.
+The bitmap may be shared by other font and bitmap server clients.
+@param aFile The handle of the multi-bitmap (.mbm) file.
+@param aId The bitmap identifier.
+@param aShareIfLoaded Specifies whether or not the loaded bitmap will be made
+available for sharing between FBSERV clients.
+@param aFileOffset Bitmap file section offset within the file.
+@return KErrNone if successful, otherwise another of the system error codes.
+@publishedAll
+@released
+*/
+EXPORT_C TInt CFbsBitmap::Load(RFile& aFile,TInt32 aId,TBool aShareIfLoaded,TUint aFileOffset)
+ {
+ if (!iFbs)
+ {
+ return(KErrCouldNotConnect);
+ }
+ Reset();
+ TUint32* rompointer;
+ IsFileInRom(aFile,rompointer);
+ TBool romPointerValid;
+ TInt err = DoLoadFromRom(rompointer, aId, aFileOffset, romPointerValid);
+ if (!romPointerValid)
+ {
+ err = DoLoad(aFile,aId,aShareIfLoaded,aFileOffset);
+ }
+ return err;
+ }
+
+/** Loads and compresses a specific bitmap from an opened multi-bitmap file handle.
+The bitmap may be shared by other font and bitmap server clients.
+If the bitmap is loaded from ROM then compression is not allowed.
+@param aFile The handle of the multi-bitmap (.mbm) file.
+@param aId The bitmap identifier.
+@param aShareIfLoaded Specifies whether or not the loaded bitmap will be
+made available for sharing between FBSERV clients.
+@return KErrNone if successful, otherwise another of the system-wide error
+codes.
+@publishedAll
+@released
+*/
+EXPORT_C TInt CFbsBitmap::LoadAndCompress(RFile& aFile,TInt32 aId/*=0*/,TBool aShareIfLoaded/*=ETrue*/)
+ {
+ return LoadAndCompress(aFile,aId,aShareIfLoaded,0);
+ }
+
+/** Loads and compresses a specific bitmap from an opened multi-bitmap file handle.
+The bitmap may be shared by other font and bitmap server clients. If the
+bitmap is loaded from ROM then compression is not allowed.
+@param aFile The handle of the multi-bitmap (.mbm) file.
+@param aId The bitmap identifier.
+@param aShareIfLoaded Specifies whether or not the loaded bitmap will be made
+available for sharing between FBSERV clients.
+@param aFileOffset Bitmap file section offset within the file.
+@return KErrNone if successful, otherwise another of the system-wide error
+codes.
+@publishedAll
+@released
+*/
+EXPORT_C TInt CFbsBitmap::LoadAndCompress(RFile& aFile,TInt32 aId,TBool aShareIfLoaded,TUint aFileOffset)
+ {
+ TInt err = Load(aFile,aId,aShareIfLoaded,aFileOffset);
+ if (err == KErrNone)
+ {
+ err = !(iFlags & EIsRomBitmap) ? Compress() : KErrAccessDenied;
+ }
+ return err;
+ }
+
+/** Gets all the bitmap handles for all the bitmaps stored in the Font Bitmap Server. There is a limit of
+the number of bitmaps that can be retrieved defined by KMaxBitmapHandleBufferSize. If this limit has been
+reached then KErrOverflow will be returned.
+@param aBitmapIdArray returns an array of all the bitmap handles
+@return KErrNone if successful, KErrOverflow if the bitmapBuffer is not large enough to store
+all the bitmap handles, otherwise another of the system-wide error codes.
+@capability ReadDeviceData
+@internalComponent
+@released
+*/
+EXPORT_C TInt CFbsBitmap::GetAllBitmapHandles(RArray<TInt>& aBitmapIdArray) const
+ {
+ RBuf8 bitmapBuffer;
+ TInt ret = bitmapBuffer.Create(KMaxBitmapHandleBufferSize);
+ if (ret==KErrNone)
+ {
+ TIpcArgs args(&bitmapBuffer);
+ ret=iFbs->SendCommand(EFbsGetAllBitmapHandles, args);
+ if (ret==KErrNone)
+ {
+ // Convert data returned from server and place into the RArray (aBitmapIdArray)
+ aBitmapIdArray.Reset();
+ TInt* bitmapIdPtr = (TInt*)bitmapBuffer.Ptr();
+ const TInt numBitmapIds = bitmapBuffer.Size() / KNumBytesPerBitmapHandle; // Divide by number of bytes per bitmap handle to get total number of bitmap IDs
+ for (TInt count=0; count<numBitmapIds; ++count)
+ {
+ TInt bitmapId = *bitmapIdPtr++;
+ ret = aBitmapIdArray.Append(bitmapId);
+ if (ret!=KErrNone)
+ break;
+ }
+ }
+ }
+ bitmapBuffer.Close();
+ return ret;
+ }
+
+/**
+@internalComponent
+This method tries to load a bitmap if mbm or rsc file is in ROM.
+
+@param aRomPointer the address of the file in ROM
+@param aId a Bitmap ID which should be less than mbm file bitmaps count.
+@param aFileOffset mbm file section offset into rsc file.
+@param aRomPointerValid on output it is set to ETrue if aRomPointer points to a valid ROM file or EFalse otherwise.
+@return KErrNone if successful, otherwise another of the system-wide error codes.
+*/
+TInt CFbsBitmap::DoLoadFromRom(TUint32* aRomPointer, TInt32 aId, TUint aFileOffset, TBool& aRomPointerValid)
+ {
+ aRomPointerValid = ETrue;
+ if(aRomPointer)
+ {
+ TUint8* temp = reinterpret_cast <TUint8*> (aRomPointer);
+ __ASSERT_DEBUG(!(TUint(temp) & 0x00000003),Panic(EFbsBitmapAlignment));
+ temp += aFileOffset;
+ aRomPointer = reinterpret_cast <TUint32*> (temp);
+ if(TInt32(*aRomPointer)==KMultiBitmapRomImageUid.iUid)
+ {
+ TInt numbitmaps = (TInt)*(aRomPointer+1);
+ if(aId>=numbitmaps)
+ {
+ return(KErrEof);
+ }
+ TInt offset = *(aRomPointer+aId+2);
+ iAddressPointer = (CBitwiseBitmap*)(((TUint8*)aRomPointer) + offset);
+ iFlags = EIsRomBitmap;
+ iHandle = 1;
+ return iFbs->AllocScanLineBuffer(iAddressPointer->iByteWidth + 4);
+ }
+ }
+ aRomPointerValid = EFalse;
+ return KErrNone;
+ }
+
+
+/**
+Creates an extended bitmap. Extended bitmaps are used to store immutable
+data in a platform-specific format. They cannot be used as targets of
+graphics contexts, and modification of their data via DataAddress() or
+TBitmapUtil is not supported and results in undefined behaviour up to
+and including process termination.
+
+Initialisation of the raw data of the new bitmap is carried out by copying
+the data pointed to by the parameter aData.
+
+Read-only access to the raw data of an extended bitmap is provided by
+DataAddress() and DataSize() in conjunction with BeginDataAccess() and
+EndDataAccess().
+
+Extended bitmaps have a conceptual size in pixels and a conceptual
+display mode for compatibility purposes. The raw data can be independent
+of these properties.
+
+@param aSizeInPixels The conceptual width and height of the new bitmap in pixels.
+@param aDispMode The conceptual display mode of the new bitmap.
+@param aType The UID identifying the data format of the new bitmap. Used by the
+ extended bitmap rasterizer to distinguish between different data types.
+@param aData A pointer to the raw data to be stored in the new bitmap.
+@param aDataSize The size in bytes of the raw data to be stored in the new bitmap.
+@return KErrNone if successful; KErrArgument if the width or height specified in
+aSizeInPixels is negative, aDispMode is an invalid display mode, aData is NULL,
+aDataSize is negative or zero, or aDataType is a UID reserved for OS use; KErrTooBig
+if the width or height specified in aSizeInPixels exceeds KMaxTInt/4, or aDataSize
+exceeds KMaxTInt/2; otherwise another of the system-wide error codes.
+@publishedPartner
+@prototype
+@see CFbsBitmap::DataAddress()
+@see CFbsBitmap::DataSize()
+@see CFbsBitmap::BeginDataAccess()
+@see CFbsBitmap::EndDataAccess()
+*/
+EXPORT_C TInt CFbsBitmap::CreateExtendedBitmap(const TSize& aSizeInPixels, TDisplayMode aDispMode, TUid aType, const TAny* aData, TInt aDataSize)
+ {
+ if (!aData || aDataSize == 0)
+ {
+ return KErrArgument;
+ }
+ TInt err = DoCreate(aSizeInPixels, aDispMode, aType, aDataSize);
+ if (err == KErrNone)
+ {
+ Mem::Copy(iFbs->iLargeBitmapChunk.Base() + iAddressPointer->iDataOffset, aData, aDataSize);
+ }
+ return err;
+ }
+
+/**
+Creates an extended bitmap. Extended bitmaps are used to store immutable
+data in a platform-specific format. They cannot be used as targets of
+graphics contexts, and modification of their data via DataAddress() or
+TBitmapUtil is not supported and results in undefined behaviour up to
+and including process termination.
+
+Initialisation of the raw data of the new bitmap is carried out by a
+callback to the MFbsExtendedBitmapInitializer::InitExtendedBitmap()
+function passed through the parameter aInitializer.
+
+Read-only access to the raw data of an extended bitmap is provided by
+DataAddress() and DataSize() in conjunction with BeginDataAccess() and
+EndDataAccess().
+
+Extended bitmaps have a conceptual size in pixels and a conceptual
+display mode for compatibility purposes. The raw data can be independent
+of these properties.
+
+@param aSizeInPixels The conceptual width and height of the new bitmap in pixels.
+@param aDispMode The conceptual display mode of the new bitmap.
+@param aType The UID identifying the data format of the new bitmap. Used by the
+ extended bitmap rasterizer to distinguish between different data types.
+@param aDataSize The size in bytes of the raw data to be stored in the new bitmap.
+@param aInitializer A reference to the initializer of the raw data to be stored in the new bitmap.
+@return KErrNone if successful; KErrArgument if the width or height specified in
+aSizeInPixels is negative, aDispMode is an invalid display mode, aData is NULL,
+aDataSize is negative or zero, or aDataType is a UID reserved for OS use; KErrTooBig
+if the width or height specified in aSizeInPixels exceeds KMaxTInt/4, or aDataSize
+exceeds KMaxTInt/2; otherwise another of the system-wide error codes.
+@publishedPartner
+@prototype
+@see CFbsBitmap::DataAddress()
+@see CFbsBitmap::DataSize()
+@see CFbsBitmap::BeginDataAccess()
+@see CFbsBitmap::EndDataAccess()
+@see MFbsExtendedBitmapInitializer
+*/
+EXPORT_C TInt CFbsBitmap::CreateExtendedBitmap(const TSize& aSizeInPixels, TDisplayMode aDispMode, TUid aType, TInt aDataSize, MFbsExtendedBitmapInitializer& aInitializer)
+ {
+ if (aDataSize == 0)
+ {
+ return KErrArgument;
+ }
+ TInt err = DoCreate(aSizeInPixels, aDispMode, aType, aDataSize);
+ if (err == KErrNone)
+ {
+ err = aInitializer.InitExtendedBitmap(iFbs->iLargeBitmapChunk.Base() + iAddressPointer->iDataOffset, aDataSize);
+ if (err != KErrNone)
+ {
+ Reset();
+ }
+ }
+ return err;
+ }
+
+/**
+Gets the UID identifying the data format of an extended bitmap.
+@return The UID identifying the data format of the bitmap or
+ KNullUid if the bitmap is not an extended bitmap.
+@publishedPartner
+@prototype
+*/
+EXPORT_C TUid CFbsBitmap::ExtendedBitmapType() const
+ {
+ if (iHandle == 0)
+ {
+ return KNullUid;
+ }
+ TUid type = CleanAddress()->iUid;
+ if (type.iUid == KCBitwiseBitmapUid.iUid || type.iUid == KCBitwiseBitmapHardwareUid.iUid)
+ {
+ return KNullUid;
+ }
+ return type;
+ }
+
+/**
+Gets the size in bytes of the bitmap data.
+@return The size in bytes of the bitmap data.
+@publishedPartner
+@prototype
+*/
+EXPORT_C TInt CFbsBitmap::DataSize() const
+ {
+ if (iHandle == 0)
+ {
+ return 0;
+ }
+ CBitwiseBitmap* bmp = CleanAddress();
+ return bmp->iHeader.iBitmapSize - bmp->iHeader.iStructSize;
+ }
+
+/**
+Gets a pointer to an extra buffer for general use owned by this thread's FBServ session.
+@param aSize The size of the buffer in bytes
+@return A pointer to the extra buffer if successful or NULL if there is no FBServ session
+@internalTechnology
+@released
+*/
+EXPORT_C HBufC8* CFbsBitmap::GetExtraBuffer(TInt aSize)
+ {
+ RFbsSession* ses=RFbsSession::GetSession();
+ return ses? ses->GetExtraBuffer(aSize) : NULL;
+ }