os/graphics/fbs/fontandbitmapserver/sfbs/FBSBMP.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1995-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #include <s32file.h>
    17 #include <bitmap.h>
    18 #include <graphicsaccelerator.h>
    19 #include <fbs.h>
    20 #include <graphics/bitmapuid.h>
    21 #include "fbsdefs.h"
    22 #include "UTILS.H"
    23 #include "fbshelper.h"
    24 #include "fbsrasterizer.h"
    25 #include "BitwiseBitmap.inl"
    26 #include "FbsMessage.H"
    27 #include "bitmapconst.h"
    28 #include "OstTraceDefinitions.h"
    29 #include "fbstrace.h"
    30 #ifdef OST_TRACE_COMPILER_IN_USE
    31 #include "FBSBMPTraces.h"
    32 #endif
    33 
    34 const TInt KMaxPixelSize = KMaxTInt / 4; // Maximum pixel size to avoid some overflow problems
    35 const TInt KMaxBitmapHandleBufferSize = KNumBytesPerBitmapHandle * 2000; 	// Maximum size of buffer to store all bitmap handles.
    36 
    37 GLREF_C void Panic(TFbsPanic aPanic);
    38 
    39 //If we have to handle RAM located file with an embedded ROM mbm file section - 
    40 //KRomMBMInRamRSC should be ETrue.
    41 //If it is not allowed to do that - KRomMBMInRamRSC should be EFalse.
    42 //The same constant is defined into TDefect test app. It should be changed too.
    43 #pragma warning(disable : 4127)   //conditional expression is constant
    44 LOCAL_D const TBool KRomMBMInRamRSC = EFalse;
    45 
    46 //Cleanup function used by CFbsBitmap::LoadShiftedRomBmpL(...)
    47 LOCAL_D void FreeMem(TAny* aMem)
    48 	{
    49 	delete[] static_cast<TUint8*>(aMem);
    50 	}
    51 
    52 // Fbs style bitmap client class for font bitmap server
    53 /** @publishedAll */
    54 EXPORT_C CFbsBitmap::CFbsBitmap():
    55 	CBase(),
    56 	iFbs(RFbsSession::GetSession()),
    57 	iAddressPointer(NULL),
    58 	iFlags(0),
    59 	iUseCount(0),
    60 	iHandle(0),
    61 	iServerHandle(0)
    62 	{
    63 	}
    64 	
    65 /** Destructor. Calls Reset().
    66 @see Reset()
    67 @publishedAll 
    68 @released
    69 */
    70 EXPORT_C CFbsBitmap::~CFbsBitmap()
    71 	{
    72 	Reset();
    73 	}
    74 	
    75 /** Gets the physical length in bytes of a scanline in memory. 
    76 This is aligned to a 4 byte (DWORD) boundary for performance reasons.
    77 
    78 @param aLength The length of a scanline in pixels. 
    79 @param aDispMode The display mode of the bitmap. 
    80 @return Number of bytes in the scanline in memory. 
    81 @publishedAll 
    82 @released
    83 */
    84 EXPORT_C TInt CFbsBitmap::ScanLineLength(TInt aLength,TDisplayMode aDispMode)
    85 	{
    86 	if (aDispMode == ERgb)
    87 		return aLength * 4;
    88 	else if (aDispMode == ENone)
    89 		return 0;
    90 
    91 	return CBitwiseBitmap::ByteWidth(aLength,aDispMode);
    92 	}
    93 
    94 /** Releases the bitmap's handle from the font and bitmap server and decrements 
    95 its access count.
    96 The server-side bitmap is only deleted when the access count for the bitmap 
    97 decrements to zero. 
    98 @publishedAll
    99 @released
   100 */
   101 EXPORT_C void CFbsBitmap::Reset()
   102 	{
   103     FBS_OST(TInt ssh = (iFbs ? iFbs->ServerSessionHandle() : 0);)
   104     FBS_OST(OstTraceExt4( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_RESET_ENTRY, "> this=0x%08x; iH=0x%08x; iSH=0x%08x; iSSH=0x%08x", (TUint)this, iHandle, iServerHandle, ssh );)
   105 	if (iHandle && !(iFlags & EIsRomBitmap))
   106 		{
   107 		iFbs->SendCommand(EFbsMessClose, iHandle, Handle());
   108 		iFbs->iHelper->RemoveBitmap(*this);
   109 		}
   110 	if (KRomMBMInRamRSC && (iFlags & EIsRomBitmap))
   111 		{
   112 		// If it is a ROM bitmap, we have to check, is it a ROM bitmap located
   113 		// in RAM? If yes, then we have to deallocate the bitmap memory.
   114 		TBool isInRom = EFalse;
   115 		TInt ret = User::IsRomAddress(isInRom, iAddressPointer);
   116 		if (ret == KErrNone && !isInRom)
   117 			delete[] reinterpret_cast<TUint8*>(iAddressPointer);
   118 		}
   119 	iAddressPointer = NULL;
   120 	iFlags = 0;
   121 	iUseCount = 0;
   122 	iHandle = 0;
   123 	iServerHandle = 0;
   124 	FBS_OST(OstTrace1( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_RESET_EXIT, "< this=0x%08x", (TUint)this );)
   125 	}
   126 	
   127 /** Tests whether or not the bitmap is read-only.
   128 @return ETrue if the bitmap is read-only, EFalse otherwise.
   129 @publishedAll
   130 @released
   131 */
   132 EXPORT_C TBool CFbsBitmap::IsRomBitmap() const
   133 	{
   134 	return (iFlags & EIsReadOnlyBitmapMask) > 0;
   135 	}
   136 
   137 /**  Sets the bitmap to use a bitmap image stored in ROM.
   138 @param aRomBitmapPointer Pointer to a bitmap stored in ROM.
   139 @param aBitmapSizeInBytes On return, indicates the size of 
   140 the bitmap in bytes. 
   141 @leave KErrUnknown aRomBitmapPointer is not in ROM, or has an invalid UID.
   142 @publishedAll
   143 @released
   144 */	
   145 EXPORT_C void CFbsBitmap::SetRomBitmapL(CBitwiseBitmap* aRomBitmapPointer,TInt& aBitmapSizeInBytes)
   146     {
   147 	TBool isInRom = EFalse;
   148 	TInt ret = User::IsRomAddress(isInRom,(TAny*)aRomBitmapPointer);
   149 	if (ret != KErrNone || !isInRom || aRomBitmapPointer->Uid() != KCBitwiseBitmapUid)
   150 		User::Leave(KErrUnknown);
   151 
   152 	Reset();
   153 	iAddressPointer = aRomBitmapPointer;
   154 	iFlags = EIsRomBitmap;
   155 	iHandle = 1;
   156 
   157 	User::LeaveIfError(iFbs->AllocScanLineBuffer(aRomBitmapPointer->iByteWidth + 4));
   158 	aBitmapSizeInBytes = Align4(aRomBitmapPointer->iHeader.iBitmapSize + 28);
   159 	}
   160 
   161 CBitwiseBitmap* CFbsBitmap::Address() const
   162 	{
   163 	if (!iHandle)
   164 		return NULL;
   165 	return iAddressPointer;
   166 	}
   167 
   168 EXPORT_C CBitwiseBitmap* CFbsBitmap::CleanAddress() const
   169 	{
   170 	if (!iHandle)
   171 		return NULL;
   172 	// Don't try to clean a dirty bitmap between calls to BeginDataAccess() and EndDataAccess(), i.e. iUseCount > 0
   173 	// ROM bitmaps can never be dirty
   174 	if (!(iFlags & EIsReadOnlyBitmapMask) && iUseCount == 0 && iAddressPointer->iSettings.IsDirtyBitmap())
   175 		{
   176 		TPckgBuf<TBmpHandles> handlebuf;
   177 		TIpcArgs args(iHandle, &handlebuf);
   178 		if (iFbs->SendCommand(EFbsMessBitmapClean, args) == KErrNone)
   179 			{
   180 			const_cast<CFbsBitmap*>(this)->iHandle = handlebuf().iHandle;
   181 			const_cast<CFbsBitmap*>(this)->iServerHandle = handlebuf().iServerHandle;
   182 			const_cast<CFbsBitmap*>(this)->iAddressPointer = (CBitwiseBitmap*)(iFbs->HeapBase() + handlebuf().iAddressOffset);
   183 			}
   184 		}
   185 	return iAddressPointer;
   186 	}
   187 
   188 inline CBitwiseBitmap* CFbsBitmap::BeginDataAccessAndGetCleanAddress(TUint32*& aDataAddress) const
   189 	{
   190 	BeginDataAccess();
   191 	CBitwiseBitmap* bmp = Address();
   192 	// aDataAddress should be consistent with bmp since after the call to BeginDataAccess()
   193 	// the call to DataAddress() will not clean the bitmap again
   194 	aDataAddress = DataAddress();
   195 	return bmp;
   196 	}
   197 
   198 /** Gets the address of the first pixel in the bitmap. 
   199 The first pixel is at the top-left. Access to the pixel data of a bitmap
   200 should be surrounded by calls to BeginDataAccess() and EndDataAccess(),
   201 otherwise performance may be degraded on certain platforms.
   202 
   203 Note: Performing a Resize() or Compress() operation changes the value returned by this function.
   204 @return The address of the first pixel of the bitmap.
   205 @publishedAll
   206 @released
   207 @see CFbsBitmap::BeginDataAccess()
   208 @see CFbsBitmap::EndDataAccess()
   209 */
   210 EXPORT_C TUint32* CFbsBitmap::DataAddress() const
   211 	{
   212 	if(!iHandle) return(NULL);
   213 	CBitwiseBitmap* bmp = CleanAddress();
   214 
   215 	if (!(iFlags & EIsReadOnlyBitmapMask) && (iUseCount == 0))
   216 		bmp->iSettings.SetVolatileBitmap();
   217 		
   218 	if(bmp->iUid.iUid==KCBitwiseBitmapHardwareUid.iUid)   // RHardwareBitmap
   219 		{
   220 		RHardwareBitmap hwb(bmp->iDataOffset);	// iDataOffset = handle for hardware bitmap
   221 		TAcceleratedBitmapInfo info;
   222 		const TInt ret = hwb.GetInfo(info);
   223 		return ret!=KErrNone ? NULL : (reinterpret_cast<TUint32*>(info.iAddress));
   224 		}
   225 
   226 	if (bmp->iHeap == NULL)
   227 		return(reinterpret_cast<TUint32*>((TUint8*)bmp+bmp->iDataOffset));
   228 	return(reinterpret_cast<TUint32*>(iFbs->iLargeBitmapChunk.Base()+bmp->iDataOffset));
   229 	}
   230 
   231 /** Gets the length in bytes between scanlines in memory.
   232 @return The length in bytes between scanlines in memory. 
   233 @internalAll
   234 @released
   235 */
   236 EXPORT_C TInt CFbsBitmap::DataStride() const
   237 	{
   238 	if (!iHandle)
   239 		{
   240 		return 0;
   241 		}
   242 		
   243 	CBitwiseBitmap* bmp = CleanAddress();
   244 	if (bmp==NULL)
   245 		{
   246 		return 0;
   247 		}
   248 		
   249 	return bmp->DataStride();	
   250 	}
   251 
   252 /** Creates a bitmap with the specified size and display mode. The bitmap is 
   253 created on the font and bitmap server's shared heap.
   254 @param aSizeInPixels The size of the bitmap to be created. 
   255 @param aDispMode The display mode of the bitmap to be created. 
   256 @return KErrNone if successful; KErrCouldNotConnect if no connection to the 
   257 font and bitmap server could be made; KErrArgument if either the width or height specified 
   258 in aSizeInPixels are negative or if the requested display mode is invalid; KErrTooBig 
   259 if the requested size is too big. 
   260 @publishedAll
   261 @released
   262 */
   263 EXPORT_C TInt CFbsBitmap::Create(const TSize& aSizeInPixels,TDisplayMode aDispMode)
   264 	{
   265     FBS_OST(OstTraceExt4(GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_CREATE_ENTRY, "> this=0x%08x; w=%d; h=%d; dm=%d", (TUint)this, aSizeInPixels.iWidth, aSizeInPixels.iHeight, aDispMode); ) 
   266 	TInt err = DoCreate(aSizeInPixels,aDispMode,KUidCFbsBitmapCreation);
   267     FBS_OST(TInt ssh = (iFbs ? iFbs->ServerSessionHandle() : 0);)
   268 	FBS_OST(OstTraceExt5(GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_CREATE_EXIT, "< this=0x%08x; err=%d; iH=0x%08x; iSH=0x%08x; iSSH=0x%08x", (TUint)this, err, iHandle, iServerHandle, ssh); )
   269     return err;
   270 	}
   271 
   272 TInt CFbsBitmap::DoCreate(const TSize& aSizeInPixels, TDisplayMode aDispMode, TUid aUid, TInt aDataSize)
   273 	{
   274 	if(!iFbs) return(KErrCouldNotConnect);
   275 	if (aDispMode <= ENone || aDispMode == ERgb || aDispMode >= EColorLast) return KErrArgument;
   276 	if(aSizeInPixels.iWidth<0 || aSizeInPixels.iHeight<0) return(KErrArgument);
   277 	if (aDataSize < 0) return KErrArgument;
   278 	Reset();
   279 	TBmpSpec bmpspec;
   280 	bmpspec.iSizeInPixels=aSizeInPixels;
   281 	bmpspec.iDispMode=aDispMode;
   282 	bmpspec.iHandle = aUid.iUid;	// Use iHandle to pass UID
   283 	bmpspec.iServerHandle = aDataSize;	// Use iServerHandle to pass data size
   284 	TPckgBuf<TBmpSpec> b;
   285 	b=bmpspec;
   286 	TIpcArgs args(&b);
   287 	TInt ret=iFbs->SendCommand(EFbsMessBitmapCreate,args);
   288 	if(ret!=KErrNone) return(ret);
   289 	iHandle=b().iHandle;
   290 	iServerHandle=b().iServerHandle;
   291 	iAddressPointer=(CBitwiseBitmap*)(iFbs->HeapBase()+b().iAddressOffset);
   292 	if (aDataSize > 0) // explicitly specified data size means extended bitmap
   293 		{
   294 		iFlags = EIsExtendedBitmap;
   295 		}
   296 	ret = iFbs->iHelper->AddBitmap(*this);
   297 	if (ret != KErrNone)
   298 		return ret;
   299 	return iFbs->AllocScanLineBuffer(CBitwiseBitmap::ByteWidth(aSizeInPixels.iWidth, aDispMode)+4);
   300 	}
   301 
   302 /** Creates a hardware bitmap with a size and display mode.
   303 @param aSizeInPixels The bitmap's width and height in pixels.
   304 @param aDispMode The bitmap's display mode.
   305 @param aCreatorUid The UID of the application calling this function. This is 
   306 used to allow segregation of the memory used for hardware bitmaps. For instance, 
   307 if a device has video memory attached to display and graphics accelerator 
   308 hardware, this UID is used to determine whether any video memory is pre-allocated 
   309 for that application's use.
   310 @return KErrNone if successful, otherwise one of the system wide error codes. 
   311 These include KErrCouldNotConnect if no connection has been made to the font 
   312 and bitmap server, KErrArgument if either the width or height specified in 
   313 aSizeInPixels are negative or if the requested display mode is invalid, or KErrNotSupported 
   314 if hardware bitmaps are not supported on the device. 
   315 @publishedAll
   316 @released
   317 */
   318 EXPORT_C TInt CFbsBitmap::CreateHardwareBitmap(const TSize& aSizeInPixels,TDisplayMode aDispMode,TUid aCreatorUid)
   319 	{
   320     FBS_OST(OstTraceExt5( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_CREATEHARDWAREBITMAP_ENTRY, "> this=0x%08x; w=%d; h=%d; dm=%d; uid=0x%08x", (TUint)this, aSizeInPixels.iWidth, aSizeInPixels.iHeight, aDispMode, aCreatorUid.iUid);)
   321 	TInt err = DoCreate(aSizeInPixels,aDispMode,aCreatorUid);
   322     FBS_OST(TInt ssh = (iFbs ? iFbs->ServerSessionHandle() : 0);)
   323 	FBS_OST(OstTraceExt5( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_CREATEHARDWAREBITMAP_EXIT, "< this=0x%08x; err=%d; iH=0x%08x; iSH=0x%08x; iSSH=0x%08x", (TUint)this, err, iHandle, iServerHandle, ssh);)
   324 	return err;
   325 	}
   326 
   327 /** Resets the pixel-size of the bitmap.
   328 If the new size is bigger than the old, the original bitmap is still situated 
   329 at (0,0), but pixels outside the range of the old pixel-size are set to zero.
   330 @param aSizeInPixels The new size of the bitmap. 
   331 @return KErrNone if successful; KErrArgument if the new size is illegal; 
   332 KErrGeneral if the bitmap has not yet been created; KErrAccessDenied if the 
   333 bitmap is in ROM or is an extended bitmap; otherwise another of the system-wide error codes. 
   334 @publishedAll
   335 @released
   336 */
   337 EXPORT_C TInt CFbsBitmap::Resize(const TSize& aSizeInPixels)
   338 	{
   339 	if(aSizeInPixels.iWidth<0 || aSizeInPixels.iHeight<0) 
   340 		return(KErrArgument);
   341 	if(aSizeInPixels.iWidth>KMaxPixelSize || aSizeInPixels.iHeight>KMaxPixelSize)
   342 		return(KErrTooBig);	
   343 	if(!iHandle) 
   344 		return(KErrGeneral);
   345 	if (iFlags & EIsReadOnlyBitmapMask)
   346 		return(KErrAccessDenied);	
   347 	TPckgBuf<TBmpHandles> handlebuf;
   348 	TIpcArgs args(iHandle, aSizeInPixels.iWidth, aSizeInPixels.iHeight, &handlebuf);
   349 	TInt err = iFbs->SendCommand(EFbsMessBitmapResize, args);
   350 	if (err != KErrNone)
   351 		return (err);
   352 	iHandle = handlebuf().iHandle;
   353 	iServerHandle = handlebuf().iServerHandle;
   354 	iAddressPointer = (CBitwiseBitmap*)(iFbs->HeapBase() + handlebuf().iAddressOffset);
   355 	return iFbs->AllocScanLineBuffer(CBitwiseBitmap::ByteWidth(aSizeInPixels.iWidth, DisplayMode())+4);
   356 	}
   357 
   358 /** Gets the display mode of the bitmap.
   359 @return The display mode of the bitmap. 
   360 @publishedAll
   361 @released
   362 */
   363 EXPORT_C TDisplayMode CFbsBitmap::DisplayMode() const
   364 	{
   365 	if(iHandle==NULL) return(ENone);
   366 	return CleanAddress()->DisplayMode();
   367 	}
   368 
   369 /** Returns the display mode that was used to create the bitmap.
   370 @return The display mode used to create the bitmap.
   371 @publishedAll
   372 @released
   373 */
   374 EXPORT_C TDisplayMode CFbsBitmap::InitialDisplayMode() const
   375 	{
   376 	if(iHandle == NULL) 
   377 		{
   378 		return ENone;
   379 		}
   380 	return CleanAddress()->InitialDisplayMode();
   381 	}
   382 
   383 /**
   384 Changes the display mode of the bitmap.
   385 The requested display mode cannot be greater (in bpp value) than the initial display mode.
   386 This method cannot leave, for instance because of an out of memory condition. No 
   387 additional memory is allocated or leaving methods called.
   388 The bitmap's content is preserved when converting it to the requested display mode,
   389 but there may be some loss of quality.
   390 @publishedAll
   391 @released
   392 @param aDisplayMode The requested display mode.
   393 @return KErrArgument if the requested mode is invalid, or has a greater bpp value 
   394 than the initial mode. KErrNotSupported if the bitmap is compressed, or is a
   395 ROM bitmap, an extended bitmap or a hardware bitmap. KErrGeneral if the bitmap
   396 handle is NULL. KErrNone if the method call is successful.
   397 @see CFbsBitmap::InitialDisplayMode()
   398 */
   399 EXPORT_C TInt CFbsBitmap::SetDisplayMode(TDisplayMode aDisplayMode)
   400 	{
   401 	if(!iHandle) 
   402 		{
   403 		return KErrGeneral;
   404 		}	
   405 	TUint32* data;
   406 	CBitwiseBitmap* bmp = BeginDataAccessAndGetCleanAddress(data);
   407 	TInt err = bmp->SetDisplayMode(aDisplayMode, data);
   408 	EndDataAccess(EFalse);
   409 	return err;
   410 	}
   411 
   412 /** Duplicates a bitmap.
   413 This function does not create a copy of the bitmap. It just assigns another 
   414 handle to the bitmap in the font and bitmap server, and sets this object's 
   415 handle to that. If the specified bitmap is in the ROM, it just assigns a pointer 
   416 to it.
   417 @param aHandle The handle to an existing bitmap.
   418 @return KErrNone if successful; KErrCouldNotConnect if no connection to the 
   419 font and bitmap server could be made; KErrUnknown if no bitmap could be found 
   420 with the specified handle number.
   421 @publishedAll
   422 @released
   423 @see CFbsBitmap::Handle()
   424 */
   425 EXPORT_C TInt CFbsBitmap::Duplicate(TInt aBitmapHandle)	
   426     {
   427     TInt ret = KErrNone;
   428     FBS_OST(OstTraceExt2( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_DUPLICATE_ENTRY, "> this=0x%08x; iH=0x%08x;", (TUint)this, aBitmapHandle);)
   429 	if(!iFbs) 
   430 		{
   431 		ret = KErrCouldNotConnect;
   432 		FBS_OST(OstTrace1( TRACE_ERROR, CFBSBITMAP_DUPLICATE_ERROR, "! this=0x%08x; !iFbs", (TUint)this);)
   433 		}
   434 	else if(!aBitmapHandle) 
   435 		{
   436 		ret = KErrUnknown;
   437 		FBS_OST(OstTrace1( TRACE_ERROR, CFBSBITMAP_DUPLICATE_ERROR2, "! this=0x%08x; !aBitmapHandle", (TUint)this);)
   438 		}
   439     else
   440         {
   441         TBool isinrom = EFalse;
   442         ret = User::IsRomAddress(isinrom, (TAny*)aBitmapHandle);
   443         if (ret == KErrNone)
   444             {
   445             if (isinrom)
   446                 {
   447                 ret = DuplicateInRom(aBitmapHandle);
   448                 FBS_OST_IF(ret != KErrNone, OstTraceExt2( TRACE_ERROR, CFBSBITMAP_DUPLICATE_ERROR4, "! this=0x%08x; DuplicateInRom() returned %d;", (TUint)this, ret);)
   449                 }
   450             else
   451                 {
   452                 ret = DuplicateInRam(aBitmapHandle);
   453                 FBS_OST_IF(ret != KErrNone, OstTraceExt2( TRACE_ERROR, CFBSBITMAP_DUPLICATE_ERROR5, "! this=0x%08x; DuplicateInRam() returned %d;", (TUint)this, ret);)
   454                 }
   455             }
   456         else 
   457             {
   458             FBS_OST(OstTraceExt2( TRACE_ERROR, CFBSBITMAP_DUPLICATE_ERROR3, "! this=0x%08x; IsRomAddress() returned %d", (TUint)this, ret);)
   459             ret = KErrUnknown;
   460             }
   461         }
   462     FBS_OST(TInt ssh = (iFbs ? iFbs->ServerSessionHandle() : 0);)
   463     FBS_OST(OstTraceExt5( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_DUPLICATE_EXIT, "< this=0x%08x; iH=0x%08x; iSH=0x%08x; ret=%d; iSSH=0x%08x", (TUint)this, iHandle, iServerHandle, ret, ssh);)
   464 	return ret;
   465     }
   466 
   467 /** Duplicates a bitmap where the bitmap handle refers to a rom bitmap.
   468 @param aBitmapHandle A valid Rom bitmap handle.
   469 @return KErrNone on success.
   470  */
   471 TInt CFbsBitmap::DuplicateInRom(TInt aBitmapHandle)
   472     {
   473     TInt ret = KErrNone;
   474     Reset();
   475     TUid uid = ((CBitwiseBitmap*)aBitmapHandle)->Uid();
   476     if (uid != KCBitwiseBitmapUid)
   477         {
   478         FBS_OST(OstTraceExt2( TRACE_ERROR, CFBSBITMAP_DUPLICATEINROM_ERROR, "! this=0x%08x; 0x%08x != KCBitwiseBitmapUid", (TUint)this, (TUint)uid.iUid);)
   479         ret = KErrUnknown;
   480         }
   481     else
   482         {
   483         iAddressPointer = (CBitwiseBitmap*)aBitmapHandle;
   484         iFlags = EIsRomBitmap;
   485         iHandle=1;
   486         ret = iFbs->AllocScanLineBuffer(iAddressPointer->iByteWidth + 4);
   487         FBS_OST_IF(ret!=KErrNone, OstTraceExt2( TRACE_ERROR, CFBSBITMAP_DUPLICATEINROM_ERROR2, "! this=0x%08x; AllocScanLineBuffer() returned %d", (TUint)this, ret);)
   488         }
   489     return ret;
   490     }
   491 
   492 /** Duplicates a bitmap where the bitmap handle refers to a ram bitmap
   493 @param aBitmapHandle A valid Ram bitmap handle.
   494 @return KErrNone on success.
   495  */
   496 TInt CFbsBitmap::DuplicateInRam(TInt aBitmapHandle)
   497     {
   498     TInt ret = KErrNone;
   499     Reset();
   500      
   501     TPckgBuf<TBmpHandles> b;
   502     TIpcArgs args(aBitmapHandle,&b);
   503     ret=iFbs->SendCommand(EFbsMessBitmapDuplicate,args);
   504     FBS_OST_IF(ret!=KErrNone, OstTraceExt2( TRACE_ERROR, CFBSBITMAP_DUPLICATEINRAM_ERROR, "! this=0x%08x; SendCommand(EFbsMessBitmapDuplicate) returned %d", (TUint)this, ret);)
   505     if(ret==KErrNone) 
   506         {
   507         iHandle=b().iHandle;
   508         iServerHandle=b().iServerHandle;
   509         iAddressPointer=(CBitwiseBitmap*)(iFbs->HeapBase()+b().iAddressOffset);
   510         if (iAddressPointer->iUid.iUid != KCBitwiseBitmapUid.iUid && iAddressPointer->iUid.iUid != KCBitwiseBitmapHardwareUid.iUid)
   511             {
   512             iFlags = EIsExtendedBitmap;
   513             }
   514         ret = iFbs->iHelper->AddBitmap(*this);
   515         FBS_OST_IF(ret!=KErrNone, OstTraceExt2( TRACE_ERROR, CFBSBITMAP_DUPLICATEINRAM_ERROR2, "! this=0x%08x; AddBitmap() returned %d", (TUint)this, ret);)
   516         if (ret == KErrNone)
   517             {
   518             ret = iFbs->AllocScanLineBuffer(iAddressPointer->iByteWidth+4);
   519             FBS_OST_IF(ret!=KErrNone, OstTraceExt2( TRACE_ERROR, CFBSBITMAP_DUPLICATEINRAM_ERROR3, "! this=0x%08x; AllocScanLineBuffer() returned %d", (TUint)this, ret);)
   520             }
   521         }
   522     return ret;
   523     }
   524 
   525 /** Loads a specific bitmap from a multi-bitmap file.
   526 The bitmap may be shared by other font and bitmap server clients.
   527 @param aFileName The filename of the multi-bitmap (.mbm) file. 
   528 @param aId The bitmap identifier.
   529 @param aShareIfLoaded Specifies whether or not the loaded bitmap will be made 
   530 available for sharing between font and bitmap server clients. 
   531 @return KErrNone if successful, otherwise another of the system error 
   532 codes. 
   533 @publishedAll
   534 @released
   535 */	
   536 EXPORT_C TInt CFbsBitmap::Load(const TDesC& aFileName,TInt32 aId,TBool aShareIfLoaded)
   537 	{
   538     FBS_OST(OstTraceExt4( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_LOAD_ENTRY, "> this=0x%08x; file=%S, id=0x%08x; share=%d", (TUint)this, aFileName, aId, aShareIfLoaded);)
   539 	TInt err = Load(aFileName,aId,aShareIfLoaded,0);
   540     FBS_OST(OstTraceExt2( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_LOAD_EXIT, "< this=0x%08x; err=%d", (TUint)this, err);)
   541 	return err; 
   542 	}
   543 
   544 /**  Loads a specific bitmap from a multi-bitmap file.
   545 The bitmap may be shared by other font and bitmap server clients.
   546 @param aFileName The filename of the multi-bitmap (.mbm) file.
   547 @param aId The bitmap identifier.
   548 @param aShareIfLoaded  Specifies whether or not the loaded bitmap will be made 
   549 available for sharing between FBSERV clients.
   550 @param aFileOffset Bitmap file section offset within the file.
   551 @return KErrNone if successful, otherwise another of the system error codes.
   552 @publishedAll
   553 @released
   554 */	
   555 EXPORT_C TInt CFbsBitmap::Load(const TDesC& aFileName,TInt32 aId,TBool aShareIfLoaded,TUint aFileOffset)
   556 	{
   557     TInt err = KErrNone;
   558     FBS_OST(OstTraceExt5( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_LOAD2_ENTRY, "> this=0x%08x; file=%S, id=0x%08x; share=%d; off=%d", (TUint)this, aFileName, aId, aShareIfLoaded, aFileOffset);)
   559 	if(!iFbs)
   560 		{
   561         FBS_OST(OstTrace1( TRACE_ERROR, CFBSBITMAP_LOAD2_ERROR, "! this=0x%08x; !iFbs", (TUint)this);)
   562 		err = KErrCouldNotConnect;
   563 		}
   564 	else
   565 	    {
   566         Reset();
   567         TUint32* rompointer = NULL;
   568         //access using filename has the advantage of using rom address lookup cache
   569         IsFileInRom(aFileName, rompointer);
   570         TBool romPointerValid;
   571         err = DoLoadFromRom(rompointer, aId, aFileOffset, romPointerValid);
   572         if(!romPointerValid)
   573             {
   574             _LIT(KResourcePath, "?:\\Resource\\*");
   575             TInt match = aFileName.MatchF(KResourcePath);
   576             //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.
   577             if (match == 0)
   578                 {
   579                 err = DoLoad(aFileName,aId,aShareIfLoaded,aFileOffset);
   580                 FBS_OST_IF(err!=KErrNone, OstTraceExt2( TRACE_ERROR, CFBSBITMAP_LOAD2_ERROR3, "! this=0x%08x; DoLoad returned %d", (TUint)this, err);)
   581                 }
   582             else
   583                 {
   584                 RFile file;
   585                 err = file.Open(iFbs->FileServer(),aFileName,EFileShareReadersOnly);
   586                 if (err==KErrNone)
   587                     {
   588                     err = DoLoad(file,aId,aShareIfLoaded,aFileOffset);
   589                     FBS_OST_IF(err!=KErrNone, OstTraceExt2( TRACE_ERROR, CFBSBITMAP_LOAD2_ERROR4, "! this=0x%08x; DoLoad returned %d", (TUint)this, err);)
   590                     }
   591                 file.Close();
   592                 }
   593             }
   594 	    }
   595     FBS_OST(OstTraceExt2( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_LOAD2_EXIT, "< this=0x%08x; err=%d", (TUint)this, err);)
   596 	return err;
   597 	}
   598 
   599 /** Loads and compresses a specific bitmap from a multi-bitmap file.
   600 The bitmap may be shared by other font and bitmap server clients.
   601 If the bitmap is loaded from ROM then compression is not allowed.
   602 @param aFileName The filename of the multi-bitmap (.mbm) file.
   603 @param aId The bitmap identifier.
   604 @param aShareIfLoaded Specifies whether or not the loaded bitmap will be
   605 made available for sharing between FBSERV clients.
   606 @return KErrNone if successful, otherwise another of the system-wide error 
   607 codes. 
   608 @publishedAll 
   609 @released
   610 */	
   611 EXPORT_C TInt CFbsBitmap::LoadAndCompress(const TDesC& aFileName,TInt32 aId,TBool aShareIfLoaded)
   612     {	
   613     FBS_OST(OstTraceExt4( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_LOADANDCOMPRESS_ENTRY, "> this=0x%08x; file=%S; id=0x%08x; share=%d", (TUint)this, aFileName, aId, aShareIfLoaded);)
   614     TInt ret = LoadAndCompress(aFileName, aId, aShareIfLoaded, 0);
   615     FBS_OST(OstTraceExt2( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_LOADANDCOMPRESS_EXIT, "< this=0x%08x; err=%d", (TUint)this, ret);)
   616     return ret;
   617 	}
   618 
   619 /** Loads and compresses a specific bitmap from a multi-bitmap file.
   620 The bitmap may be shared by other font and bitmap server clients. If the 
   621 bitmap is loaded from ROM then compression is not allowed.
   622 @param aFileName The filename of the multi-bitmap (.mbm) file.
   623 @param aId The bitmap identifier.
   624 @param aShareIfLoaded Specifies whether or not the loaded bitmap will be made 
   625 available for sharing between FBSERV clients.
   626 @param aFileOffset Bitmap file section offset within the file.
   627 @return KErrNone if successful, otherwise another of the system-wide error 
   628 codes. 
   629 @publishedAll 
   630 @released
   631 */	
   632 EXPORT_C TInt CFbsBitmap::LoadAndCompress(const TDesC& aFileName,TInt32 aId,TBool aShareIfLoaded,TUint aFileOffset)
   633     {
   634     FBS_OST(OstTraceExt5( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_LOADANDCOMPRESS2_ENTRY, "> this=0x%08x; file=%S, id=0x%08x; share=%d; off=%d", (TUint)this, aFileName, aId, aShareIfLoaded, aFileOffset);)
   635 	TInt err = Load(aFileName,aId,aShareIfLoaded,aFileOffset);
   636 	if (err == KErrNone)
   637 		{
   638 		err = !(iFlags & EIsRomBitmap) ? Compress() : KErrAccessDenied;
   639 		FBS_OST_IF(err!=KErrNone, OstTraceExt3( TRACE_ERROR, CFBSBITMAP_LOADANDCOMPRESS2_ERROR, "! this=0x%08x; iFlags=0x%08x; err=%d", (TUint)this, (TUint)iFlags, err);)
   640 		}
   641 	FBS_OST(OstTraceExt2( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_LOADANDCOMPRESS2_EXIT, "< this=0x%08x; err=%d", (TUint)this, err);)
   642 	return err;
   643 	}
   644 
   645 /** Saves the bitmap as a direct file store.
   646 The file store overwrites any existing file with the same name.
   647 @param aFilename The name of the file. 
   648 @return KErrNone if successful, KErrNotSupported if this CFbsBitmap is an 
   649 extended bitmap, otherwise another of the system-wide error codes. 
   650 @publishedAll 
   651 @released
   652 */
   653 EXPORT_C TInt CFbsBitmap::Save(const TDesC& aFilename)
   654 	{
   655 	if (!iHandle)
   656 		{
   657 		return(KErrGeneral);
   658 		}
   659 	RFile file;
   660 	TInt ret=file.Replace(iFbs->FileServer(),aFilename,EFileWrite);
   661 	if(ret!=KErrNone) return(ret);
   662 	TRAP(ret,DoSaveL(file));
   663 	file.Close();
   664 	return(ret);
   665 	}
   666 
   667 /** Saves the bitmap as a direct file store using an opened file handle.
   668 The file store overwrites any existing file with the same name.
   669 @param aFile The opened file handle
   670 @return KErrNone if successful, KErrNotSupported if this CFbsBitmap is an 
   671 extended bitmap, otherwise another of the system-wide error codes. 
   672 @publishedAll 
   673 @released
   674 */
   675 EXPORT_C TInt CFbsBitmap::Save(RFile& aFile)
   676 	{
   677 	if (!iHandle)
   678 		{
   679 		return KErrGeneral;
   680 		}
   681 	TRAPD(ret,DoSaveL(aFile));
   682 	return ret;
   683 	}
   684 
   685 void CFbsBitmap::DoSaveL(RFile& aFile)
   686 	{
   687 	CDirectFileStore* filestore=CDirectFileStore::NewLC(aFile); // create from open file
   688 	TUidType uidtype(KDirectFileStoreLayoutUid,KMultiBitmapFileImageUid);
   689 	filestore->SetTypeL(uidtype);
   690 	RStoreWriteStream bmpstream;
   691 	TStreamId bmpstreamid=bmpstream.CreateLC(*filestore); // create bitmap stream
   692 	ExternalizeL(bmpstream);
   693 	bmpstream.CommitL();
   694 	CleanupStack::PopAndDestroy(); // bitmap stream
   695 	RStoreWriteStream rootstream;
   696 	TStreamId rootstreamid=rootstream.CreateLC(*filestore); // create root stream
   697 	rootstream.WriteInt32L(1); // number of bitmaps
   698 	rootstream<<bmpstreamid; // stream id of bitmap
   699 	rootstream.CommitL();
   700 	CleanupStack::PopAndDestroy(); // root stream
   701 	filestore->SetRootL(rootstreamid);
   702 	filestore->CommitL();
   703 	CleanupStack::PopAndDestroy(); // file store
   704 	}
   705 
   706 /** Constructs a multi-bitmap file.
   707 @param aFilename The name of the multi-bitmap file to be created.
   708 @param aNumSources The number of bitmaps to store in the file.
   709 @param aSources  An array of pointers to bitmaps to be stored.
   710 @param aSourceIds An array of identifiers for the bitmaps to be stored. 
   711 @publishedAll
   712 @released
   713 */	
   714 EXPORT_C void CFbsBitmap::StoreL(const TDesC& aFilename,TInt aNumSources,const TDesC* aSources[],TInt32 aSourceIds[])
   715 	{
   716 	CFbsBitmap* bitmap = new(ELeave) CFbsBitmap;
   717 	CleanupStack::PushL(bitmap);
   718 	CDirectFileStore* filestore = CDirectFileStore::ReplaceLC(bitmap->iFbs->FileServer(),aFilename,EFileWrite);
   719 	DoStoreL(filestore,bitmap,aNumSources,aSources,aSourceIds);
   720 	CleanupStack::PopAndDestroy(2,bitmap);	
   721 	}
   722 
   723 /** Constructs a multi-bitmap file using an opened file handle.
   724 @param aFile The opened file handle of multi-bitmap file
   725 @param aNumSources The number of bitmaps to store in the file.
   726 @param aSources  An array of pointers to bitmaps to be stored.
   727 @param aSourceIds An array of identifiers for the bitmaps to be stored. 
   728 @publishedAll
   729 @released
   730 */	
   731 EXPORT_C void CFbsBitmap::StoreL(RFile& aFile,TInt aNumSources,const TDesC* aSources[],TInt32 aSourceIds[])
   732 	{
   733 	CDirectFileStore* filestore = CDirectFileStore::NewLC(aFile);
   734 	DoStoreL(filestore,NULL,aNumSources,aSources,aSourceIds);
   735 	CleanupStack::PopAndDestroy(filestore);	
   736 	}
   737 
   738 /**
   739 @internalComponent
   740 */
   741 void CFbsBitmap::DoStoreL(CDirectFileStore* aFileStore,CFbsBitmap* aBitmap,TInt aNumSources,const TDesC* aSources[],TInt32 aSourceIds[])
   742 	{
   743 	if(aNumSources<1 || aSources==NULL) User::Leave(KErrArgument);
   744 	TInt count=0;
   745 	for(;count<aNumSources;count++)
   746 		if(aSources[count]==NULL) User::Leave(KErrArgument);
   747 	TStreamId* ids=new(ELeave) TStreamId[aNumSources];
   748 	CleanupArrayDeletePushL(ids);
   749 	TInt nPushed=1;
   750 	if (!aBitmap)
   751 		{
   752 		aBitmap=new(ELeave) CFbsBitmap;
   753 		CleanupStack::PushL(aBitmap);
   754 		++nPushed;
   755 		}
   756 	TUidType uidtype(KDirectFileStoreLayoutUid,KMultiBitmapFileImageUid);
   757 	aFileStore->SetTypeL(uidtype);
   758 	for(count=0;count<aNumSources;count++)
   759 		{
   760 		User::LeaveIfError(aBitmap->Load(*aSources[count],aSourceIds[count]));
   761 		RStoreWriteStream bmpstream;
   762 		ids[count]=bmpstream.CreateLC(*aFileStore); // create bitmap stream
   763 		aBitmap->ExternalizeL(bmpstream);
   764 		bmpstream.Close();
   765 		CleanupStack::Pop(); // bitmap stream
   766 		}
   767 	RStoreWriteStream rootstream;
   768 	TStreamId rootstreamid=rootstream.CreateLC(*aFileStore); // create root stream
   769 	rootstream.WriteInt32L(aNumSources); // number of bitmaps
   770 	for(count=0;count<aNumSources;count++)
   771 		rootstream<<ids[count]; // stream ids of bitmaps
   772 	rootstream.Close();
   773 	CleanupStack::Pop(); // root stream
   774 	aFileStore->SetRootL(rootstreamid);
   775 	CleanupStack::PopAndDestroy(nPushed); // ids [and bitmap]
   776 	}
   777 
   778 /** Gets the bitmap's scanline for the specified line starting from the 
   779 specified point.
   780 The dither offset of the bitmap is taken to be TPoint(0,0).
   781 @param aBuf The buffer in which the scanline is returned. 
   782 @param aPoint The start pixel. 
   783 @param aLength The number of pixels to get. 
   784 @param aDispMode Format to be used to write the data to the buffer. 
   785 @publishedAll
   786 @released
   787 */
   788 EXPORT_C void CFbsBitmap::GetScanLine(TDes8& aBuf,const TPoint& aPoint,TInt aLength,TDisplayMode aDispMode) const
   789 	{
   790 	GetScanLine(aBuf,aPoint,aLength,TPoint(0,0),aDispMode);
   791 	}
   792 
   793 /** Gets the bitmap's scanline for the specified line starting from the specified 
   794 point and using the specified dither offset.
   795 @param aBuf The buffer in which the scanline is returned. 
   796 @param aPixel The start pixel. 
   797 @param aLength The number of pixels to get. 
   798 @param aDitherOffset The dither offset of the bitmap. 
   799 @param aDispMode Format to be used to write the data to the buffer. 
   800 @publishedAll 
   801 @released
   802 */
   803 EXPORT_C void CFbsBitmap::GetScanLine(TDes8& aBuf,const TPoint& aPoint,TInt aLength,const TPoint& aDitherOffset,TDisplayMode aDispMode) const
   804 	{
   805 	if(!iHandle) return;
   806 	TUint32* data;
   807 	CBitwiseBitmap* bmp = BeginDataAccessAndGetCleanAddress(data);
   808 	CFbsRasterizer* rasterizer = NULL;
   809 	if ((iFlags & EIsExtendedBitmap) && iFbs)
   810 		{
   811 		rasterizer = iFbs->iHelper->Rasterizer();
   812 		if (rasterizer)
   813 			{
   814 			CFbsRasterizer::TBitmapDesc desc;
   815 			desc.iSizeInPixels = bmp->SizeInPixels();
   816 			desc.iDispMode = bmp->DisplayMode();
   817 			desc.iDataType = bmp->iUid;
   818 			desc.iData = data;
   819 			desc.iDataSize = bmp->iHeader.iBitmapSize - bmp->iHeader.iStructSize;
   820 			rasterizer->BeginBitmap(bmp->Extra()->iSerialNumber, desc, NULL);
   821 			}
   822 		}
   823 	bmp->GetScanLine(aBuf, aPoint, aLength, ETrue, aDitherOffset, aDispMode, data);
   824 	if (rasterizer)
   825 		{
   826 		rasterizer->EndBitmap(bmp->Extra()->iSerialNumber);
   827 		}
   828 	EndDataAccess(ETrue);
   829 	}
   830 
   831 /** Sets the bitmap's horizontal scanline at the specified y co-ordinate to the 
   832 scanline contained in the buffer.
   833 @param aBuf The new scanline to be written to the bitmap. 
   834 @param aY The y co-ordinate of the scanline.
   835 @panic FBSCLI 11 in debug builds if this is a compressed bitmap.
   836 @panic FBSCLI 28 in debug builds if this is a read-only bitmap.
   837 @publishedAll 
   838 @released
   839 */
   840 EXPORT_C void CFbsBitmap::SetScanLine(TDes8& aBuf,TInt aY) const
   841 	{
   842 	if (!iHandle)
   843 		return;	
   844 	if (iFlags & EIsReadOnlyBitmapMask)
   845 		{
   846 		__ASSERT_DEBUG(EFalse, ::Panic(EFbsPanicBitmapReadOnly));
   847 		return;
   848 		}
   849 	TUint32* data;
   850 	CBitwiseBitmap* bmp = BeginDataAccessAndGetCleanAddress(data);
   851 	if (bmp->IsCompressed())
   852 		{
   853 		EndDataAccess(ETrue);
   854 		__ASSERT_DEBUG(EFalse, ::Panic(EFbsBitmapInvalidCompression));
   855 		return;
   856 		}
   857 	data = bmp->ScanLineAddress(data, aY);
   858 	TInt bytewidth = bmp->iByteWidth;
   859 	TInt bytelen=aBuf.Length();
   860 	if(bytelen<bytewidth) bytewidth=bytelen;
   861 	TInt wordlen=bytewidth>>2;
   862 	TUint32* ptr=(TUint32*)aBuf.Ptr();
   863 	TUint32* ptrlim=ptr+wordlen;
   864 	while(ptr<ptrlim)
   865 		*data++=*ptr++;
   866 	TInt limit=wordlen<<2;
   867 	if(limit<bytewidth)
   868 		{
   869 		TUint8* byteptr=(TUint8*)ptrlim;
   870 		TUint8* databyte=(TUint8*)data;
   871 		while(limit<bytewidth)
   872 			{
   873 			*databyte++=*byteptr++;
   874 			limit++;
   875 			}
   876 		}
   877 	EndDataAccess(EFalse);
   878 	}
   879 
   880 /** Gets the bitmap's vertical scanline starting at the specified x co-ordinate.
   881 Note: The method only works for uncompressed bitmaps.
   882 Note: The dither offset of the bitmap is taken to be TPoint(0,0).
   883 @param aBuf The buffer in which the vertical scanline is returned. 
   884 @param aX The x co-ordinate of the vertical scanline. 
   885 @param aDispMode Format to be used to write the data to the buffer. 
   886 @panic FBSCLI 11 in debug builds if this is not an ucompressed bitmap or an extended bitmap.
   887 @publishedAll 
   888 @released
   889 */
   890 EXPORT_C void CFbsBitmap::GetVerticalScanLine(TDes8& aBuf,TInt aX,TDisplayMode aDispMode) const
   891 	{
   892 	GetVerticalScanLine(aBuf,aX,TPoint(0,0),aDispMode);
   893 	}
   894 
   895 /** Gets the bitmap's vertical scanline starting at the specified x co-ordinate 
   896 and using the specified dither offset.
   897 Note: The method only works for uncompressed bitmaps.
   898 @param aBuf The buffer in which the vertical scanline will be returned. 
   899 @param aX The x co-ordinate of the vertical scanline to get. 
   900 @param aDitherOffset The dither offset of the bitmap. 
   901 @param aDispMode Format to be used to write the data to the buffer. 
   902 @panic FBSCLI 11 in debug builds if this is not an ucompressed bitmap or an extended bitmap.
   903 @publishedAll 
   904 @released
   905 */
   906 EXPORT_C void CFbsBitmap::GetVerticalScanLine(TDes8& aBuf,TInt aX,const TPoint& aDitherOffset,TDisplayMode aDispMode) const
   907 	{
   908 	if(!iHandle) return;
   909 	TUint32* data;
   910 	CBitwiseBitmap* bmp = BeginDataAccessAndGetCleanAddress(data);
   911 	CFbsRasterizer* rasterizer = NULL;
   912 	if ((iFlags & EIsExtendedBitmap) && iFbs)
   913 		{
   914 		rasterizer = iFbs->iHelper->Rasterizer();
   915 		if (rasterizer)
   916 			{
   917 			CFbsRasterizer::TBitmapDesc desc;
   918 			desc.iSizeInPixels = bmp->SizeInPixels();
   919 			desc.iDispMode = bmp->DisplayMode();
   920 			desc.iDataType = bmp->iUid;
   921 			desc.iData = data;
   922 			desc.iDataSize = bmp->iHeader.iBitmapSize - bmp->iHeader.iStructSize;
   923 			rasterizer->BeginBitmap(bmp->Extra()->iSerialNumber, desc, NULL);
   924 			}
   925 		}
   926 	bmp->GetVerticalScanLine(aBuf, aX, ETrue, aDitherOffset, aDispMode, data, rasterizer);
   927 	if (rasterizer)
   928 		{
   929 		rasterizer->EndBitmap(bmp->Extra()->iSerialNumber);
   930 		}
   931 	EndDataAccess(ETrue);
   932 	}
   933 
   934 /** Gets the handle number of the bitmap.
   935 The returned value can be used to give another thread access to the bitmap.
   936 @return The handle number of the bitmap. 
   937 @publishedAll 
   938 @released
   939 @see CFbsBitmap::Duplicate()
   940 */
   941 EXPORT_C TInt CFbsBitmap::Handle() const
   942 	{
   943 	if(!iHandle) 
   944 		return(0);
   945 	if (iFlags & EIsRomBitmap)
   946 		return TInt(iAddressPointer);
   947 	else
   948 		return(iServerHandle);
   949 	}
   950 
   951 /** Creates a bitmap header.
   952 This is used when streaming bitmaps to stores.
   953 @return The bitmap header for the bitmap. 
   954 @publishedAll 
   955 @released
   956 */
   957 EXPORT_C SEpocBitmapHeader CFbsBitmap::Header() const
   958 	{
   959 	if (iHandle)
   960 		return CleanAddress()->iHeader;
   961 	SEpocBitmapHeader header;
   962 	return(header);
   963 	}
   964 
   965 /** Converts a horizontal dimension on the graphics device from pixels to twips.
   966 @param aPixels A horizontal dimension on the graphics device in pixels. 
   967 @return A horizontal dimension on the graphics device in twips. 
   968 @publishedAll 
   969 @released
   970 */
   971 EXPORT_C TInt CFbsBitmap::HorizontalPixelsToTwips(TInt aPixels) const
   972 	{
   973 	if(iHandle==NULL) return(0);
   974 	return CleanAddress()->HorizontalPixelsToTwips(aPixels);
   975 	}
   976 
   977 /** Converts a horizontal dimension on the graphics device from twips to pixels.
   978 @param aTwips A horizontal dimension on the graphics device in twips. 
   979 @return A horizontal dimension on the graphics device in pixels. 
   980 @publishedAll 
   981 @released
   982 */
   983 EXPORT_C TInt CFbsBitmap::HorizontalTwipsToPixels(TInt aTwips) const
   984 	{
   985 	if(iHandle==NULL) return(0);
   986 	return CleanAddress()->HorizontalTwipsToPixels(aTwips);
   987 	}
   988 
   989 /** Gets the RGB value of the specified pixel.
   990 Note: The method only works for uncompressed bitmaps and extended bitmaps.
   991 @param aColor On return, the RGB value of the specified pixel. 
   992 @param aPixel The pixel whose colour is to be determined.
   993 @panic FBSCLI 11 in debug builds if this is a compressed bitmap.
   994 @publishedAll 
   995 @released
   996 */
   997 EXPORT_C void CFbsBitmap::GetPixel(TRgb& aColor,const TPoint& aPoint) const
   998 	{
   999 	if(!iHandle) 
  1000 		{
  1001 		return;
  1002 		}	
  1003 	
  1004 	TUint32* data;
  1005 	CBitwiseBitmap* bmp = BeginDataAccessAndGetCleanAddress(data);
  1006 	CFbsRasterizer* rasterizer = NULL;
  1007 	if ((iFlags & EIsExtendedBitmap) && iFbs)
  1008 		{
  1009 		rasterizer = iFbs->iHelper->Rasterizer();
  1010 		if (rasterizer)
  1011 			{
  1012 			CFbsRasterizer::TBitmapDesc desc;
  1013 			desc.iSizeInPixels = bmp->SizeInPixels();
  1014 			desc.iDispMode = bmp->DisplayMode();
  1015 			desc.iDataType = bmp->iUid;
  1016 			desc.iData = data;
  1017 			desc.iDataSize = bmp->iHeader.iBitmapSize - bmp->iHeader.iStructSize;
  1018 			rasterizer->BeginBitmap(bmp->Extra()->iSerialNumber, desc, NULL);
  1019 			}
  1020 		}
  1021 	bmp->GetPixel(aColor, aPoint, data, rasterizer);
  1022 	if (rasterizer)
  1023 		{
  1024 		rasterizer->EndBitmap(bmp->Extra()->iSerialNumber);
  1025 		}
  1026 	EndDataAccess(ETrue);
  1027 	}
  1028 
  1029 /** Gets the pixel-size of the bitmap.
  1030 @return The size of the bitmap, in pixels. 
  1031 @publishedAll 
  1032 @released
  1033 */
  1034 EXPORT_C TSize CFbsBitmap::SizeInPixels() const
  1035 	{
  1036     TSize zero;
  1037 	if(!iHandle) return(zero);
  1038 	return CleanAddress()->SizeInPixels();
  1039 	}
  1040 
  1041 /** Sets the twip-size of the bitmap by converting the bitmaps pixel-size from 
  1042 pixels to twips, using the conversion functions in the specified graphics 
  1043 device map.
  1044 @param aMap The graphics device map to be used for providing pixel to twip 
  1045 conversion. 
  1046 @publishedAll 
  1047 @released
  1048 */
  1049 EXPORT_C void CFbsBitmap::SetSizeInTwips(const MGraphicsDeviceMap* aMap)
  1050 	{
  1051 	if (!iHandle || (iFlags & EIsRomBitmap) || aMap == NULL)
  1052 		return;
  1053 	TSize size=SizeInPixels();
  1054 	size.iWidth=aMap->HorizontalPixelsToTwips(size.iWidth);
  1055 	size.iHeight=aMap->VerticalPixelsToTwips(size.iHeight);
  1056 	iFbs->SetCallBackPtr(&iServerHandle);
  1057 	iFbs->CallBack();
  1058 	// SizeInPixels() called CleanAddress() so call Address() now to make sure we don't clean the bitmap twice
  1059 	Address()->iHeader.iSizeInTwips=size;
  1060 	}
  1061 
  1062 /** Sets the twip-size of the bitmap directly to the specified size.
  1063 @param aSizeInTwips The new size of the bitmap, in twips. 
  1064 @publishedAll 
  1065 @released
  1066 */
  1067 EXPORT_C void CFbsBitmap::SetSizeInTwips(const TSize& aSizeInTwips)
  1068 	{
  1069 	if (!iHandle || (iFlags & EIsRomBitmap))
  1070 		return;
  1071 	iFbs->SetCallBackPtr(&iServerHandle);
  1072 	iFbs->CallBack();
  1073 	CleanAddress()->iHeader.iSizeInTwips = aSizeInTwips;
  1074 	}
  1075 
  1076 /** Externalises the bitmap to the specified stream. Not supported for extended bitmaps.
  1077 @param aStream The write stream. 
  1078 @publishedAll 
  1079 @released
  1080 */
  1081 EXPORT_C void CFbsBitmap::ExternalizeL(RWriteStream& aStream) const
  1082 	{
  1083 	if (!iHandle)
  1084 		User::Leave(KErrGeneral);
  1085 	BeginDataAccess();
  1086 	Address()->ExternalizeL(aStream, *this);	
  1087 	EndDataAccess(ETrue);
  1088 	}
  1089 
  1090 /** Externalises that area of the bitmap contained within a specified 
  1091 rectangular area. Not supported for extended bitmaps.
  1092 @param aStream The write stream
  1093 @param aRect The rectangular area of the bitmap to externalise. The bitmap 
  1094 that is externalized will be of this size. 
  1095 @publishedAll 
  1096 @released
  1097 */
  1098 EXPORT_C void CFbsBitmap::ExternalizeRectangleL(RWriteStream& aStream,const TRect& aRect) const
  1099 	{
  1100 	if (!iHandle)
  1101 		User::Leave(KErrGeneral);
  1102 	BeginDataAccess();
  1103 	Address()->ExternalizeRectangleL(aStream, aRect, *this);
  1104 	EndDataAccess(ETrue);
  1105 	}
  1106 
  1107 /** Internalises a CFbsBitmap from a stream.
  1108 @param aStream The read stream.
  1109 @publishedAll 
  1110 @released
  1111 */
  1112 EXPORT_C void CFbsBitmap::InternalizeL(RReadStream& aStream)
  1113 	{
  1114 	if(!iFbs) User::Leave(KErrCouldNotConnect);
  1115 	Reset();
  1116 	SEpocBitmapHeader header;
  1117 	CBitwiseBitmap::InternalizeHeaderL(aStream,header);
  1118 
  1119 	TDisplayMode dispmode = CBitwiseBitmap::DisplayMode(header.iBitsPerPixel,header.iColor);
  1120 	User::LeaveIfError(Create(header.iSizeInPixels,dispmode));
  1121 
  1122 	TUint32* data;
  1123 	CBitwiseBitmap* bmp=BeginDataAccessAndGetCleanAddress(data);
  1124 	bmp->iHeader=header;
  1125 	TInt bytesize = header.iBitmapSize - header.iStructSize;
  1126 	if (bytesize > 0)
  1127 		{
  1128 		bmp->DoInternalizeL(aStream, bytesize, data);
  1129 		EndDataAccess(EFalse);
  1130 		}
  1131 	else
  1132 		{
  1133 		EndDataAccess(ETrue);
  1134 		}
  1135 	}
  1136 
  1137 EXPORT_C TInt CFbsBitmap::Compress()
  1138  	{
  1139 	return Compress(ERLECompression);
  1140 	}
  1141 
  1142 /** Compresses bitmap in RAM.
  1143 @param aScheme specifies preferred compression type ERLECompression or EPaletteCompression
  1144 @return KErrNone on success, KErrGeneral if the bitmap handle is NULL, KErrAccessDenied if 
  1145 the bitmap is in ROM or it is an extended bitmap, otherwise one of the system wide error codes. 
  1146 @publishedAll 
  1147 @released
  1148 */
  1149 EXPORT_C TInt CFbsBitmap::Compress(TBitmapfileCompressionScheme aScheme)
  1150 	{
  1151  	if (!iHandle)
  1152  		return KErrGeneral;
  1153  	if (iFlags & EIsReadOnlyBitmapMask)
  1154  		return KErrAccessDenied; 	
  1155 	TPckgBuf<TBmpHandles> handlebuf;
  1156 	TIpcArgs args(iHandle, aScheme, &handlebuf);
  1157 	TInt err = iFbs->SendCommand(EFbsMessBitmapCompress, args);
  1158 	if (err != KErrNone)
  1159 		return err;
  1160 	iHandle = handlebuf().iHandle;
  1161 	iServerHandle = handlebuf().iServerHandle;
  1162 	iAddressPointer = (CBitwiseBitmap*)(iFbs->HeapBase() + handlebuf().iAddressOffset);
  1163 	return KErrNone;
  1164 	}
  1165 
  1166 /** Submits the bitmap for asynchronous background compression.
  1167 @param aRequestStatus The request status which will be completed with the appropriate error code after the compression has finished
  1168 The error code will be KErrNone on success, KErrGeneral if the bitmap handle is NULL, KErrAccessDenied if the
  1169 bitmap is in ROM or it is an extended bitmap, otherwise one of the system wide error codes.
  1170 @publishedAll 
  1171 @released
  1172 */
  1173 EXPORT_C void CFbsBitmap::CompressInBackground(TRequestStatus& aRequestStatus)
  1174 	{
  1175 	CompressInBackground(aRequestStatus, ERLECompression);
  1176 	}
  1177 
  1178 /** Submits the bitmap for asynchronous background compression. No notification will be provided when the compression has completed.
  1179 @return KErrNone if the bitmap was successfully submitted to the background compression queue, KErrGeneral if the bitmap handle is NULL, 
  1180 KErrAccessDenied if the bitmap is in ROM or it is an extended bitmap,  otherwise another of the system-wide error codes.
  1181 @publishedAll 
  1182 @released
  1183 */
  1184 EXPORT_C TInt CFbsBitmap::CompressInBackground()
  1185 	{
  1186 	return CompressInBackground(ERLECompression);
  1187 	}
  1188 	
  1189 /** Submits the bitmap for asynchronous background compression.
  1190 @param aRequestStatus The request status which will be completed with the appropriate error code after the compression has finished.
  1191 The error code will be KErrNone on success, KErrGeneral if the bitmap handle is NULL, KErrAccessDenied if the
  1192 bitmap is in ROM or it is an extended bitmap, otherwise one of the system wide error codes.
  1193 @param aScheme Specifies preferred compression type: ERLECompression or EPaletteCompression
  1194 @publishedAll 
  1195 @released
  1196 */
  1197 EXPORT_C void CFbsBitmap::CompressInBackground(TRequestStatus& aRequestStatus, TBitmapfileCompressionScheme aScheme)
  1198 	{
  1199 	TRequestStatus* reqStat = &aRequestStatus;
  1200 	aRequestStatus = KRequestPending;
  1201 	if (!iHandle)
  1202 		User::RequestComplete(reqStat, KErrGeneral);
  1203 	else if (iFlags & EIsReadOnlyBitmapMask)
  1204 		User::RequestComplete(reqStat, KErrAccessDenied);	
  1205 	else
  1206 		{
  1207 		TIpcArgs args(iHandle, aScheme, ETrue);
  1208 		iFbs->SendCommand(EFbsMessBitmapBgCompress, args, aRequestStatus);
  1209 		}
  1210 	}
  1211 
  1212 /** Submits the bitmap for asynchronous background compression. No notification will be provided when the compression has completed.
  1213 @return KErrNone if the bitmap was successfully submitted to the background compression queue, KErrGeneral if the bitmap handle is NULL, 
  1214 KErrAccessDenied if the bitmap is in ROM or it is an extended bitmap, otherwise another of the system-wide error codes.
  1215 @publishedAll 
  1216 @released
  1217 */
  1218 EXPORT_C TInt CFbsBitmap::CompressInBackground(TBitmapfileCompressionScheme aScheme)
  1219 	{
  1220 	if (!iHandle)
  1221 		return KErrGeneral;
  1222 	if (iFlags & EIsReadOnlyBitmapMask)
  1223 		return KErrAccessDenied;	
  1224 	TIpcArgs args(iHandle, aScheme, EFalse);
  1225 	return iFbs->SendCommand(EFbsMessBitmapBgCompress, args);
  1226 	}
  1227 
  1228 /**Tests whether the bitmap located in RAM has been compressed.
  1229 @return ETrue if the bitmap is compressed, EFalse otherwise.
  1230 @publishedAll
  1231 @released
  1232 */	
  1233 EXPORT_C TBool CFbsBitmap::IsCompressedInRAM() const
  1234 	{
  1235 	CBitwiseBitmap* bitmap = CleanAddress();
  1236 	if (bitmap==NULL)
  1237 		{
  1238 		return EFalse;
  1239 		}	
  1240 	return bitmap->IsCompressedInRAM();
  1241 	}
  1242 
  1243 /** Gets the twip-size of the bitmap.
  1244 @return The size of the bitmap, in twips. 
  1245 @publishedAll 
  1246 @released
  1247 */
  1248 EXPORT_C TSize CFbsBitmap::SizeInTwips() const
  1249 	{
  1250     TSize zero;
  1251 	if(iHandle==NULL) return(zero);
  1252 	return CleanAddress()->SizeInTwips();
  1253 	}
  1254 
  1255 /** Converts a vertical dimension on the graphics device from pixels to twips.
  1256 @param aPixels A vertical dimension on the graphics device in pixels. 
  1257 @return A vertical dimension on the graphics device in twips. 
  1258 @publishedAll 
  1259 @released
  1260 */
  1261 EXPORT_C TInt CFbsBitmap::VerticalPixelsToTwips(TInt aPixels) const
  1262 	{
  1263 	if(iHandle==NULL) return(0);
  1264 	return CleanAddress()->VerticalPixelsToTwips(aPixels);
  1265 	}
  1266 
  1267 /** Converts a vertical dimension on the graphics device from twips to pixels.
  1268 @param aTwips A vertical dimension on the graphics device in twips. 
  1269 @return A vertical dimension on the graphics device in pixels. 
  1270 @publishedAll 
  1271 @released
  1272 */
  1273 EXPORT_C TInt CFbsBitmap::VerticalTwipsToPixels(TInt aTwips) const
  1274 	{
  1275 	if(iHandle==NULL) return(0);
  1276 	return CleanAddress()->VerticalTwipsToPixels(aTwips);
  1277 	}
  1278 
  1279 /** Tests whether or not the specified file is in ROM.
  1280 @param aFilename The name of the file. 
  1281 @param aWord On return, contains the address of the file in ROM. 
  1282 @return ETrue if the file is in the ROM; EFalse otherwise. 
  1283 @publishedAll 
  1284 @released
  1285 */
  1286 EXPORT_C TBool CFbsBitmap::IsFileInRom(const TDesC& aFilename,TUint32*& aWord)
  1287 	{
  1288 	RFbsSession* fbs=RFbsSession::GetSession();
  1289 	__ASSERT_ALWAYS(fbs,Panic(EFbsPanicNoConnection));
  1290 	return fbs->LookupBitmapInROM (aFilename, (TAny*&)aWord);
  1291 	}
  1292 
  1293 /** Tests whether or not the specified file is in ROM.
  1294 @param aFile The file handle
  1295 @param aWord On return, contains the address of the file in ROM. 
  1296 @return ETrue if the file is in the ROM; EFalse otherwise. 
  1297 @publishedAll 
  1298 @released
  1299 */
  1300 EXPORT_C TBool CFbsBitmap::IsFileInRom(RFile& aFile,TUint32*& aWord)
  1301 	{
  1302 	// cannot use rom lookup cache as filename is not available
  1303 	// offset must be initialised to zero to indicate beginning of the file
  1304 	aWord = 0;
  1305 	return aFile.Seek(ESeekAddress,(TInt&)aWord)==KErrNone;
  1306 	}
  1307 	
  1308 /** Tests whether or not the bitmap is monochrome.
  1309 Monochrome bitmaps have a display-mode of 1 bit-per-pixel.
  1310 @return ETrue if the bitmap is monochrome; EFalse otherwise. 
  1311 @publishedAll 
  1312 @released
  1313 */
  1314 EXPORT_C TBool CFbsBitmap::IsMonochrome() const
  1315 	{
  1316 	if(!iHandle) return(EFalse);
  1317 	TUint32* data;
  1318 	CBitwiseBitmap* bmp = BeginDataAccessAndGetCleanAddress(data);
  1319 	TBool isMonochrome = bmp->IsMonochrome(data);
  1320 	EndDataAccess(ETrue);
  1321 	return isMonochrome;
  1322 	}
  1323 
  1324 /** Marks the beginning of direct access to the bitmap data.
  1325 This function prepares the bitmap for direct access to its pixel data
  1326 and should be used before calling DataAddress(), otherwise performance
  1327 may be degraded on certain platforms.
  1328 Calls to BeginDataAccess() must be coupled with subsequent calls to EndDataAccess().
  1329 
  1330 @publishedAll
  1331 @released
  1332 @see CFbsBitmap::DataAddress()
  1333 @see CFbsBitmap::EndDataAccess()
  1334 */
  1335 EXPORT_C void CFbsBitmap::BeginDataAccess() const
  1336 	{
  1337     FBS_OST_VERBOSE(OstTrace1(GRAPHICS_CONTROL_FUNCTIONS, CFBSBITMAP_BEGINDATAACCESS_ENTRY, "> this=0x%08x;", (TUint)this););
  1338 	FBS_OST_IF(!iHandle, OstTrace1(TRACE_ERROR, CFBSBITMAP_BEGINDATAACCESS_ERROR, "! this=0x%08x; !iHandle", (TUint)this););
  1339 	
  1340 	if (iHandle)
  1341 	    {
  1342         (void)CleanAddress();	//called for side-effect to make sure bitmap reference is current. Should be low overhead.
  1343         const_cast<CFbsBitmap*>(this)->iUseCount++;
  1344 	    }
  1345     
  1346 	FBS_OST_VERBOSE(OstTraceExt2(GRAPHICS_CONTROL_FUNCTIONS, CFBSBITMAP_BEGINDATAACCESS_EXIT, "< this=0x%08x; iUseCount=%d;", (TUint)this, const_cast<CFbsBitmap*>(this)->iUseCount);)
  1347 	}
  1348 
  1349 /** Marks the end of direct access to the bitmap data.
  1350 Use this function after ending direct access to the bitmap data.
  1351 Calls to EndDataAccess() must correspond to prior calls to BeginDataAccess().
  1352 See BeginDataAccess() for more details.
  1353 
  1354 @param aReadOnly Whether or not the bitmap data has only been read since
  1355                  the corresponding call to BeginDataAccess().
  1356 
  1357 @publishedAll
  1358 @released
  1359 @param aReadOnly True if the bitmap data had only been read.  False if the data has been modified.
  1360 @see CFbsBitmap::BeginDataAccess()
  1361 */
  1362 EXPORT_C void CFbsBitmap::EndDataAccess(TBool aReadOnly) const
  1363 	{
  1364     FBS_OST_VERBOSE(OstTraceExt2(GRAPHICS_CONTROL_FUNCTIONS, CFBSBITMAP_ENDDATAACCESS_ENTRY, "> this=0x%08x; aReadOnly=%d;", (TUint)this, (TUint)aReadOnly);)
  1365     FBS_OST_IF(!iHandle, OstTrace1(TRACE_ERROR, CFBSBITMAP_ENDDATAACCESS_ERROR, "! this=0x%08x; !iHandle", (TUint)this););
  1366     if (iHandle)
  1367         {
  1368         const_cast<CFbsBitmap*>(this)->iUseCount--;
  1369         if (!aReadOnly && !(iFlags & EIsReadOnlyBitmapMask))
  1370             {
  1371             User::LockedInc(iAddressPointer->Extra()->iTouchCount);
  1372             }
  1373         }
  1374     FBS_OST_VERBOSE(OstTraceExt2(GRAPHICS_CONTROL_FUNCTIONS, CFBSBITMAP_ENDDATAACCESS_EXIT, "< this=0x%08x; iUseCount=%d;", (TUint)this, const_cast<CFbsBitmap*>(this)->iUseCount);)
  1375 	}
  1376 
  1377 /** Locks the global bitmap heap.
  1378 This function is deprecated, since it is no longer necessary to lock the global
  1379 bitmap heap to prevent the pixel data from being moved in memory asynchronously,
  1380 as the value returned by DataAddress() can now only change as a result of bitmap
  1381 operations explicitly requested by clients of the Font and Bitmap Server.
  1382 Calls to LockHeap() should be replaced by calls to BeginDataAccess().
  1383 
  1384 Calls to LockHeap() must be coupled with subsequent calls to CFbsBitmap::UnlockHeap().
  1385 Code called between a LockHeap() - UnlockHeap() pair must not include any other calls to
  1386 CFbsBitmap methods, which internally may call CFbsBitmap::LockHeap(). Also, code must
  1387 not leave between a LockHeap() - UnlockHeap() pair.
  1388 @note	IMPORTANT: CFbsBitmap::LockHeap() cannot be used as a means of synchronization between
  1389 threads concurrently accessing bitmap data.
  1390 
  1391 @publishedAll 
  1392 @deprecated
  1393 @see CFbsBitmap::UnlockHeap()
  1394 @see CFbsBitmap::BeginDataAccess()
  1395 */
  1396 EXPORT_C void CFbsBitmap::LockHeap(TBool /*aAlways*/) const
  1397 	{
  1398     FBS_OST(OstTrace1(GRAPHICS_CONTROL_FUNCTIONS, CFBSBITMAP_LOCKHEAP_ENTRY, "> this=0x%08x;", (TUint)this);)
  1399 	BeginDataAccess();
  1400 #ifdef SYMBIAN_DEBUG_FBS_LOCKHEAP
  1401 	//These debug checks now refer to the cleaned data address
  1402     FBS_OST_IF(!iHandle, OstTrace1(TRACE_ERROR, CFBSBITMAP_LOCKHEAP_ERROR, "! this=0x%08x; !iHandle", (TUint)this););
  1403 	if (iHandle && !(iFlags & EIsRomBitmap)) // can't do anything with ROM bitmaps
  1404 		{
  1405 		TThreadId threadId = RThread().Id();
  1406 		iFbs->iHelper->iDebugMutex.Wait();
  1407 		if (iAddressPointer->Extra()->iLockCount++ == 0)
  1408 			{
  1409 			__ASSERT_ALWAYS(iAddressPointer->Extra()->iThreadId == TThreadId(KNullThreadId), Panic(EFbsPanicBadHeapLock));
  1410 			iAddressPointer->Extra()->iThreadId = threadId;
  1411 			}
  1412 		else
  1413 			__ASSERT_ALWAYS(iAddressPointer->Extra()->iThreadId == threadId, Panic(EFbsPanicBadHeapLock));
  1414 		iFbs->iHelper->iDebugMutex.Signal();
  1415 		}
  1416 #endif
  1417 	FBS_OST(OstTrace1(GRAPHICS_CONTROL_FUNCTIONS, CFBSBITMAP_LOCKHEAP_EXIT, "< this=0x%08x;", (TUint)this);)
  1418 	}
  1419 
  1420 /** Unlocks the global heap. 
  1421 This function is deprecated. See LockHeap() for more details.
  1422 Calls to UnlockHeap() should be replaced by calls to EndDataAccess().
  1423 Calls to UnlockHeap() must correspond to prior calls to LockHeap() or LockHeapLC().
  1424 
  1425 @publishedAll 
  1426 @deprecated
  1427 @see CFbsBitmap::LockHeap()
  1428 @see CFbsBitmap::EndDataAccess()
  1429 */
  1430 EXPORT_C void CFbsBitmap::UnlockHeap(TBool /*aAlways*/) const
  1431 	{
  1432     FBS_OST(OstTrace1(GRAPHICS_CONTROL_FUNCTIONS, CFBSBITMAP_UNLOCKHEAP_ENTRY, "> this=0x%08x;", (TUint)this);)
  1433     FBS_OST_IF(!iHandle, OstTrace1(TRACE_ERROR, CFBSBITMAP_UNLOCKHEAP_ERROR, "! this=0x%08x; !iHandle", (TUint)this););
  1434 	if (iHandle)
  1435 	    {
  1436 #ifdef SYMBIAN_DEBUG_FBS_LOCKHEAP
  1437 	    if (!(iFlags & EIsRomBitmap)) // can't do anything with ROM bitmaps
  1438             {
  1439             TThreadId threadId = RThread().Id();
  1440             iFbs->iHelper->iDebugMutex.Wait();
  1441             __ASSERT_ALWAYS(iAddressPointer->Extra()->iLockCount > 0, Panic(EFbsPanicBadHeapLock));
  1442             __ASSERT_ALWAYS(iAddressPointer->Extra()->iThreadId == threadId, Panic(EFbsPanicBadHeapLock));
  1443             if (--iAddressPointer->Extra()->iLockCount == 0)
  1444                 iAddressPointer->Extra()->iThreadId = TThreadId(KNullThreadId);
  1445             iFbs->iHelper->iDebugMutex.Signal();
  1446             }
  1447 #endif
  1448 	    EndDataAccess();
  1449 	    }
  1450 	FBS_OST(OstTrace1(GRAPHICS_CONTROL_FUNCTIONS, CFBSBITMAP_UNLOCKHEAP_EXIT, "< this=0x%08x;", (TUint)this);)
  1451 	}
  1452 
  1453 /** Locks the global bitmap heap, leaving on the clean-up stack a pointer
  1454 to a TCleanupItem that unlocks the heap on deletion.
  1455 Use this function instead of LockHeap() if code may leave between the
  1456 LockHeap() - UnlockHeap() pair. Calls to LockHeapLC() must be coupled with
  1457 subsequent calls to CFbsBitmap::UnlockHeap() or CleanupStack::PopAndDestroy().
  1458 This function is deprecated. See CFbsBitmap::LockHeap() for more details.
  1459 
  1460 @publishedAll 
  1461 @deprecated
  1462 @see CFbsBitmap::LockHeap()
  1463 */
  1464 EXPORT_C void CFbsBitmap::LockHeapLC(TBool /*aAlways*/) const
  1465 	{
  1466     FBS_OST(OstTrace1(GRAPHICS_CONTROL_FUNCTIONS, CFBSBITMAP_LOCKHEAPLC_ENTRY, "> this=0x%08x;", (TUint)this);)
  1467     LockHeap();
  1468 	TCleanupItem cleanitem(CFbsBitmap::UnlockHeap, (TAny*)this);
  1469 	CleanupStack::PushL(cleanitem);
  1470 	FBS_OST(OstTrace1(GRAPHICS_CONTROL_FUNCTIONS, CFBSBITMAP_LOCKHEAPLC_EXIT, "< this=0x%08x;", (TUint)this);)
  1471 	}
  1472 
  1473 EXPORT_C void CFbsBitmap::UnlockHeap(TAny* aFbsBitmap)
  1474 	{
  1475     FBS_OST(OstTrace1(GRAPHICS_CONTROL_FUNCTIONS, CFBSBITMAP_UNLOCKHEAP2_ENTRY, "> bitmap=0x%08x;", (TUint)aFbsBitmap);)
  1476     ((CFbsBitmap*)aFbsBitmap)->UnlockHeap();
  1477     FBS_OST(OstTrace0(GRAPHICS_CONTROL_FUNCTIONS, CFBSBITMAP_UNLOCKHEAP2_EXIT, "<");)
  1478 	}
  1479 
  1480 /** Tests whether the bitmap is volatile.
  1481 A bitmap becomes volatile if CFbsBitmap::DataAdress() is called without
  1482 CFbsBitmap::BeginDataAccess() having been called before and it can become non-volatile
  1483 again if a resizing or compression is performed.
  1484 
  1485 @internalTechnology
  1486 @prototype
  1487 */
  1488 EXPORT_C TBool CFbsBitmap::IsVolatile() const
  1489 	{
  1490 	if (!iHandle)
  1491 		return EFalse;
  1492 	return CleanAddress()->iSettings.IsVolatileBitmap();
  1493 	}
  1494 
  1495 /** Tests how many times the bitmap has been touched.
  1496 A bitmap is touched whenever CFbsBitmap::EndDataAccess() is called with the parameter
  1497 aReadOnly set to EFalse and also whenever a resizing or compression is performed.
  1498 
  1499 @internalTechnology
  1500 @prototype
  1501 @return The number of times the bitmap has been touched.
  1502 */
  1503 EXPORT_C TInt CFbsBitmap::TouchCount() const
  1504 	{
  1505 	if (!iHandle || (iFlags & EIsReadOnlyBitmapMask))
  1506 		return 0; // A read-only bitmap can never be touched.
  1507 	return CleanAddress()->Extra()->iTouchCount;
  1508 	}
  1509 
  1510 /** Returns the serial number of the bitmap
  1511 The serial number is unique to this bitmap.
  1512 The serial number is a signed 64-bit integer, with only the positive values being assigned.
  1513 As ROM bitmaps do not have serial numbers, the serial number will use the negative range
  1514 of values so that ROM bitmap's serial number cannot be the same as a RAM bitmap's.
  1515 ROM bitmap's address pointers are unique to the ROM bitmap, so the serial number will just
  1516 be negative value of the address pointer.
  1517 
  1518 @internalTechnology
  1519 @prototype
  1520 @return The unique serial number for the bitmap
  1521 */
  1522 EXPORT_C TInt64 CFbsBitmap::SerialNumber() const
  1523 	{
  1524 	if (!iHandle)
  1525 		return 0;
  1526 	if (iFlags & EIsRomBitmap)
  1527 		return -TInt64(reinterpret_cast<TUint32>(iAddressPointer));
  1528 	return CleanAddress()->Extra()->iSerialNumber;
  1529 	}
  1530 
  1531 /** Tests whether the bitmap is large.
  1532 @return ETrue if the bitmap is large, EFalse if not. 
  1533 @publishedAll 
  1534 @released
  1535 */
  1536 EXPORT_C TBool CFbsBitmap::IsLargeBitmap() const
  1537 	{
  1538 	CBitwiseBitmap* bitmap = CleanAddress();
  1539 	if (!bitmap)
  1540 		{
  1541 		return EFalse;
  1542 		}
  1543 	return bitmap->IsLargeBitmap();
  1544 	}
  1545 
  1546 /** Returns the handle for the hardware bitmap which this CFbsBitmap is using.
  1547 @return The handle to the hardware bitmap. The handle is NULL if it is not 
  1548 a hardware bitmap. 
  1549 @publishedAll 
  1550 @released
  1551 */
  1552 EXPORT_C TInt CFbsBitmap::HardwareBitmapHandle() const
  1553 	{
  1554 	CBitwiseBitmap* bitmap = CleanAddress();
  1555 	if (!bitmap)
  1556 		{
  1557 		return 0;
  1558 		}
  1559 	return bitmap->HardwareBitmapHandle();
  1560 	}
  1561 
  1562 /** Gets the attributes of the bitmap's palette.
  1563 This is not currently supported.
  1564 @param aModifiable On return, whether or not the palette is modifiable. 
  1565 @param aNumEntries On return, the number of entries in the palette. 
  1566 @publishedAll 
  1567 @released
  1568 */
  1569 EXPORT_C void CFbsBitmap::PaletteAttributes(TBool& aModifiable,TInt& aNumEntries) const
  1570 	{
  1571 	aModifiable=EFalse;
  1572 	aNumEntries=0;
  1573 	}
  1574 
  1575 /** Sets the bitmap's palette.
  1576 This is not currently supported.
  1577 @param aPalette Not used. 
  1578 @publishedAll 
  1579 @released
  1580 */
  1581 EXPORT_C void CFbsBitmap::SetPalette(CPalette* /*aPalette*/)
  1582 	{
  1583 	}
  1584 
  1585 /** Gets the bitmap's palette.
  1586 This is not currently supported.
  1587 @param aPalette Not used. 
  1588 @return KErrNotSupported. 
  1589 @publishedAll 
  1590 @released
  1591 */
  1592 EXPORT_C TInt CFbsBitmap::GetPalette(CPalette*& /*aPalette*/) const
  1593 	{
  1594 	return(KErrNotSupported);
  1595 	}
  1596 
  1597 /**
  1598 @internalComponent
  1599 This method loads a bitmap from an opened file handle.
  1600 
  1601 @param  aFile mbm or rsc file handle (rsc file format: header + rsc
  1602 	data section + mbm file section).
  1603 @param  aId Bitmap ID - should be less than mbm file bitmaps count.
  1604 @param  aShareIfLoaded Specifies whether or not the loaded bitmap will be
  1605     made available for sharing between FBSERV clients.
  1606 @param  aFileOffset mbm file section offset into rsc file.
  1607 @return KErrNone if successful, otherwise another
  1608             of the system-wide error codes.
  1609 */	
  1610 TInt CFbsBitmap::DoLoad(RFile& aFile,TInt32 aId,TBool aShareIfLoaded,TUint aFileOffset)
  1611 	{
  1612 	TInt ret=KErrNone;
  1613 	TPckgBuf<TBmpHandles> handlebuf;
  1614 	TPckgBuf<TLoadBitmapArg> loadBitmapArg;
  1615 	loadBitmapArg().iBitmapId = aId;
  1616 	loadBitmapArg().iShareIfLoaded = TInt(aShareIfLoaded);
  1617 	loadBitmapArg().iFileOffset = aFileOffset;
  1618 	//Getting the RFs Handle(2) and RFile handle(3) into a TIpcArgs into 2nd and 3rd argument
  1619 	TIpcArgs fileargs;
  1620 	ret=aFile.TransferToServer(fileargs,2,3);
  1621 	if (ret!=KErrNone)
  1622 		return ret;	
  1623 	fileargs.Set(0,&handlebuf);
  1624 	fileargs.Set(1,&loadBitmapArg);
  1625 	ret=iFbs->SendCommand(EFbsMessBitmapLoad,fileargs);
  1626 	if(ret!=KErrNone) return(ret);
  1627 	iHandle=handlebuf().iHandle;
  1628 	iServerHandle=handlebuf().iServerHandle;
  1629 	iAddressPointer=(CBitwiseBitmap*)(iFbs->HeapBase()+handlebuf().iAddressOffset);
  1630 	ret = iFbs->iHelper->AddBitmap(*this);
  1631 	if (ret != KErrNone)
  1632 		return ret;
  1633 	return iFbs->AllocScanLineBuffer(iAddressPointer->iByteWidth+4);
  1634 	}
  1635 
  1636 /**
  1637 @internalComponent
  1638 This method loads a bitmap from the mbm or rsc file specified by the filename.
  1639 
  1640 @param  aFileName mbm or rsc file name (rsc file format: header + rsc
  1641 	data section + mbm file section).
  1642 @param  aId Bitmap ID - should be less than mbm file bitmaps count.
  1643 @param  aShareIfLoaded Specifies whether or not the loaded bitmap will be
  1644     made available for sharing between FBSERV clients.
  1645 @param  aFileOffset mbm file section offset into rsc file.
  1646 @return KErrNone if successful, otherwise another
  1647             of the system-wide error codes.
  1648 */
  1649 TInt CFbsBitmap::DoLoad(const TDesC& aFileName,TInt32 aId,TBool aShareIfLoaded,TUint aFileOffset)
  1650 	{
  1651 	TInt ret=KErrNone;
  1652 	TPckgBuf<TBmpHandles> handlebuf;
  1653 	TPckgBuf<TLoadBitmapArg> loadBitmapArg;
  1654 	loadBitmapArg().iBitmapId = aId;
  1655 	loadBitmapArg().iShareIfLoaded = TInt(aShareIfLoaded);
  1656 	loadBitmapArg().iFileOffset = aFileOffset;
  1657 	TIpcArgs fileargs;
  1658 	fileargs.Set(0,&handlebuf);
  1659 	fileargs.Set(1,&loadBitmapArg);
  1660 	fileargs.Set(2,&aFileName);
  1661 	ret=iFbs->SendCommand(EFbsMessBitmapLoadFast,fileargs);
  1662 	if(ret!=KErrNone) return(ret);
  1663 	iHandle=handlebuf().iHandle;
  1664 	iServerHandle=handlebuf().iServerHandle;
  1665 	iAddressPointer=(CBitwiseBitmap*)(iFbs->HeapBase()+handlebuf().iAddressOffset);
  1666 	ret = iFbs->iHelper->AddBitmap(*this);
  1667 	if (ret != KErrNone)
  1668 		return ret;
  1669 	return iFbs->AllocScanLineBuffer(iAddressPointer->iByteWidth+4);
  1670 	}
  1671 
  1672 /**
  1673 @internalComponent
  1674 This method handles very special case when the rsc file is in RAM, but it 
  1675 contains ROM mbm file.  ROM mbm file format is different than RAM mbm file 
  1676 format and ROM mbm file cannot be loaded into RAM using standard techniques 
  1677 (used by CFbsBitmap::DoLoad()). We have to check it is really a ROM mbm file. 
  1678 If it is - we have to allocate the right amount of RAM, read and copy 
  1679 requested ROM bitmap to the allocated RAM.
  1680 
  1681 @leave KErrNotSupported if this is a RAM rsc file with ROM mbm file section, 
  1682 	or any of the RFile related error codes.
  1683 @param aFileName rsc file name (rsc file format: header + rsc data section + 
  1684 	mbm file section).
  1685 @param  aId Bitmap ID - should be less than mbm file bitmaps count.
  1686 @param aFileOffset mbm file section offset into rsc file.
  1687 @return EFalse - this is not a ROM mbm file. ETrue - this is a ROM mbm file 
  1688 			and	requested by aId bitmmap is loaded.
  1689 */	
  1690 TBool CFbsBitmap::LoadShiftedRomBmpL(const TDesC& aFileName, TInt32 aId, TUint aFileOffset)
  1691 	{
  1692 	RFile mbm_file;
  1693 	::CleanupClosePushL(mbm_file);
  1694 	User::LeaveIfError(mbm_file.Open(iFbs->FileServer(), aFileName, EFileRead | EFileShareReadersOnly));
  1695 	TInt pos = static_cast <TInt> (aFileOffset);
  1696 	User::LeaveIfError(mbm_file.Seek(ESeekStart, pos));//move to the beginning of the mbm file section
  1697 	TBuf8<sizeof(CBitwiseBitmap)> buf;
  1698 	//Check if it is a ROM mbm file
  1699 	User::LeaveIfError(mbm_file.Read(buf, sizeof(KMultiBitmapRomImageUid.iUid)));//Bitmap file UID - ROM or RAM
  1700 	TInt32 mbm_uid = *(reinterpret_cast <const TInt32*> (buf.Ptr())); 
  1701 	TBool loaded = EFalse;
  1702 	if(mbm_uid == KMultiBitmapRomImageUid.iUid)
  1703 		{
  1704 		if(!KRomMBMInRamRSC)
  1705 			{
  1706 			User::Leave(KErrNotSupported);
  1707 			}
  1708 		else
  1709 			{
  1710 			User::LeaveIfError(mbm_file.Read(buf, sizeof(TInt32)));//Number of bitmaps
  1711 			TInt32 bmp_cnt = *(reinterpret_cast <const TInt32*> (buf.Ptr()));  
  1712 			if(aId >= bmp_cnt) 
  1713 				{
  1714 				User::Leave(KErrNotFound);
  1715 				}
  1716 			for(TInt i=0;i<aId;i++) //Read bitmap UIDs located before aId.
  1717 				{
  1718 				User::LeaveIfError(mbm_file.Read(buf, sizeof(aId)));
  1719 				}
  1720 			User::LeaveIfError(mbm_file.Read(buf, sizeof(TInt32)));//Read the offset of aId bitmap.
  1721 			TInt bmp_offset = *(reinterpret_cast <const TInt32*> (buf.Ptr())) + TInt(aFileOffset); 
  1722 			pos = static_cast <TInt> (bmp_offset);
  1723 			User::LeaveIfError(mbm_file.Seek(ESeekStart, pos));//move the file pointer to the bitmap
  1724 			User::LeaveIfError(mbm_file.Read(buf, sizeof(CBitwiseBitmap)));//Read CBitwiseBitmap data (without the bitmap data)
  1725 			const CBitwiseBitmap* bmp = reinterpret_cast <const CBitwiseBitmap*> (buf.Ptr());
  1726 			//Calculate bitmap data size, alocate enough memory for the bitmap, copy CBitwiseBitmap
  1727 			//members first, read the bitmap data from the file, copy the data to the allocated memory,
  1728 			//initialize iRomPointer.
  1729 			//If sizeof(CBitwiseBitmap) != real size of CBitwiseBitmap then we could have problems,
  1730 			//because bitmap data won't be copied at the right position.
  1731 			TInt size = bmp->iHeader.iBitmapSize - sizeof(SEpocBitmapHeader) + sizeof(CBitwiseBitmap);
  1732 			TUint8* bmp_mem = new (ELeave) TUint8[size];
  1733 			//There is no need bmp_mem to be aligned, because it is a pointer to a RAM block of memory.
  1734 			TCleanupItem cleanitem(FreeMem, bmp_mem);
  1735 			CleanupStack::PushL(cleanitem);
  1736 			Mem::Copy(bmp_mem, bmp, sizeof(CBitwiseBitmap));
  1737 			TPtr8 pbmp(bmp_mem + sizeof(CBitwiseBitmap), size - sizeof(CBitwiseBitmap));
  1738 			User::LeaveIfError(mbm_file.Read(pbmp, size - sizeof(CBitwiseBitmap)));//read the bitmap data. We've already read the CBitwiseBitmap data.
  1739 			CleanupStack::Pop(bmp_mem);
  1740 			iAddressPointer = reinterpret_cast<CBitwiseBitmap*>(bmp_mem);
  1741 			iFlags = EIsRomBitmap;
  1742 			iHandle = 1;
  1743 			loaded = ETrue;
  1744 			}//end of - if(!KRomMBMInRamRSC) - "else" part
  1745 		}//end of - if(mbm_uid == KMultiBitmapRomImageUid.iUid)
  1746 	CleanupStack::PopAndDestroy();//mbm_file
  1747 	return loaded;
  1748 	}
  1749 
  1750 /**
  1751 Swaps the bitmap's width and height.
  1752 For example, if the bitmap's size is (40, 20), the new size will be (20, 40).
  1753 Bitmap content is not preserved.
  1754 @publishedAll
  1755 @released
  1756 @return KErrNone if the call was successful, KErrGeneral if the bitmap handle is 
  1757 invalid, KErrAccessDenied if the bitmap is in ROM, KErrNotSupported if the bitmap
  1758 is a hardware bitmap or an extended bitmap.
  1759 */
  1760 EXPORT_C TInt CFbsBitmap::SwapWidthAndHeight()
  1761 	{
  1762 	if(!iHandle) 
  1763 		{
  1764 		return KErrGeneral;
  1765 		}	
  1766 	TUint32* data;
  1767 	CBitwiseBitmap* bmp = BeginDataAccessAndGetCleanAddress(data);
  1768 
  1769 	// Check the new bitmap size here then decide whether to swap the bitmap on the 
  1770 	// client side or send it to be done on the server and reallocate memory for it.
  1771 	TInt newWidthInBytes = CBitwiseBitmap::ByteWidth(bmp->iHeader.iSizeInPixels.iHeight, bmp->iSettings.CurrentDisplayMode());
  1772 	TInt64 hugeDataSize = TInt64(bmp->iHeader.iSizeInPixels.iWidth) * TInt64(newWidthInBytes);
  1773 
  1774 	TInt err = KErrNone;
  1775 	// If the size of the new swapped bitmap is less than or equal its original size before the swap,
  1776 	// then we do not need to reallocate memory. The swapping is straight forward.
  1777 	if( I64HIGH(hugeDataSize) == 0 && I64LOW(hugeDataSize) <= TUint(bmp->iHeader.iBitmapSize - bmp->iHeader.iStructSize) )	
  1778 		{
  1779 		err = bmp->SwapWidthAndHeight(data);
  1780 		// Even though used DataAddress() as read-only, need to increment touch count, so indicate that data has been written
  1781 		EndDataAccess(EFalse);
  1782 		}
  1783 	// Otherwise we need to reallocate memory. We do this by using the already exisitng 
  1784 	// Resize() function as a work around- Code Reusability!!
  1785 	else
  1786 		{
  1787 		EndDataAccess(ETrue); // Used DataAddress() to read only.
  1788 		// Resize will increase touch counter
  1789 		err = Resize(TSize(bmp->iHeader.iSizeInPixels.iHeight, bmp->iHeader.iSizeInPixels.iWidth));
  1790 		}
  1791 	return err;
  1792 	}
  1793 	
  1794 /** Gets a pointer to the decompression buffer owned by this thread's FBServ session.
  1795 @param aSize The size in bytes of the scan lines to decompress.
  1796 @return A pointer to the decompression buffer or NULL if there is no FBServ session.
  1797 @internalTechnology
  1798 @released
  1799 */
  1800 EXPORT_C HBufC8* CFbsBitmap::GetDecompressionBuffer(TInt aSize)
  1801 	{
  1802 		RFbsSession* ses=RFbsSession::GetSession();
  1803 		return ses? ses->GetDecompressionBuffer(aSize) : NULL;
  1804 	}
  1805 
  1806 /** Gets a pointer to the rasterizer for extended bitmaps if present.
  1807 @return A pointer to the rasterizer owned by this thread's FBServ session.
  1808 @return NULL if the rasterizer is not present.
  1809 @internalTechnology
  1810 @prototype
  1811 */
  1812 EXPORT_C CFbsRasterizer* CFbsBitmap::Rasterizer()
  1813 	{
  1814 	RFbsSession* session = RFbsSession::GetSession();
  1815 	return session ? session->iHelper->Rasterizer() : NULL;
  1816 	}
  1817 
  1818 /** Loads a specific bitmap from an opened multi-bitmap file handle.
  1819 The bitmap may be shared by other font and bitmap server clients.
  1820 @param aFile The handle of the multi-bitmap (.mbm) file. 
  1821 @param aId The bitmap identifier.
  1822 @param aShareIfLoaded Specifies whether or not the loaded bitmap will be made 
  1823 available for sharing between font and bitmap server clients. 
  1824 @return KErrNone if successful, otherwise another of the system error 
  1825 codes. 
  1826 @publishedAll
  1827 @released
  1828 */	
  1829 EXPORT_C TInt CFbsBitmap::Load(RFile& aFile,TInt32 aId/*=0*/,TBool aShareIfLoaded/*=ETrue*/)
  1830 	{
  1831     FBS_OST(TFullName fileName;)
  1832     FBS_OST(aFile.FullName(fileName);)
  1833     FBS_OST(OstTraceExt4( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_LOAD3_ENTRY, "> this=0x%08x; file=%S; id=0x%08x; share=%d", (TUint)this, fileName, aId, aShareIfLoaded);)
  1834 	TInt ret = Load(aFile,aId,aShareIfLoaded,0);
  1835     FBS_OST(OstTraceExt2( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_LOAD3_EXIT, "< this=0x%08x, ret=%d", (TUint)this, ret);) 
  1836 	return ret;
  1837 	}
  1838 
  1839 /** Loads a specific bitmap from an opened multi-bitmap file handle.
  1840 The bitmap may be shared by other font and bitmap server clients.
  1841 @param aFile The handle of the multi-bitmap (.mbm) file. 
  1842 @param aId The bitmap identifier.
  1843 @param aShareIfLoaded  Specifies whether or not the loaded bitmap will be made 
  1844 available for sharing between FBSERV clients.
  1845 @param aFileOffset Bitmap file section offset within the file.
  1846 @return KErrNone if successful, otherwise another of the system error codes.
  1847 @publishedAll
  1848 @released
  1849 */	
  1850 EXPORT_C TInt CFbsBitmap::Load(RFile& aFile,TInt32 aId,TBool aShareIfLoaded,TUint aFileOffset)
  1851 	{
  1852     TInt err = KErrNone;
  1853     FBS_OST(TFullName fileName;)
  1854     FBS_OST(aFile.FullName(fileName);)
  1855     FBS_OST(OstTraceExt5( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_LOAD4_ENTRY, "> this=0x%08x; file=%S; id=0x%08x; share=%d; off=%d", (TUint)this, fileName, aId, aShareIfLoaded, aFileOffset);)
  1856 	if (!iFbs)
  1857 		{
  1858         FBS_OST(OstTrace1( TRACE_ERROR, CFBSBITMAP_LOAD4_ERROR, "! this=0x%08x; !iFbs", (TUint)this);)
  1859 		err = KErrCouldNotConnect;
  1860 		}
  1861 	else
  1862 	    {
  1863         Reset();
  1864         TUint32* rompointer;
  1865         IsFileInRom(aFile,rompointer);
  1866         TBool romPointerValid;
  1867         err = DoLoadFromRom(rompointer, aId, aFileOffset, romPointerValid);
  1868         if (!romPointerValid)
  1869             {
  1870             err = DoLoad(aFile,aId,aShareIfLoaded,aFileOffset);
  1871             FBS_OST_IF(err!=KErrNone, OstTraceExt2( TRACE_ERROR, CFBSBITMAP_LOAD4_ERROR2, "! this=0x%08x; DoLoad() returned %d", (TUint)this, err);)
  1872             }
  1873 	    }
  1874 	FBS_OST(OstTraceExt2( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_LOAD4_EXIT, "< this=0x%08x; err=%d", (TUint)this, err);)
  1875 	return err;
  1876 	}
  1877 
  1878 /** Loads and compresses a specific bitmap from an opened multi-bitmap file handle.
  1879 The bitmap may be shared by other font and bitmap server clients.
  1880 If the bitmap is loaded from ROM then compression is not allowed.
  1881 @param aFile The handle of the multi-bitmap (.mbm) file. 
  1882 @param aId The bitmap identifier.
  1883 @param aShareIfLoaded Specifies whether or not the loaded bitmap will be
  1884 made available for sharing between FBSERV clients.
  1885 @return KErrNone if successful, otherwise another of the system-wide error 
  1886 codes. 
  1887 @publishedAll 
  1888 @released
  1889 */	
  1890 EXPORT_C TInt CFbsBitmap::LoadAndCompress(RFile& aFile,TInt32 aId/*=0*/,TBool aShareIfLoaded/*=ETrue*/)
  1891 	{
  1892     FBS_OST(TFullName fileName;)
  1893     FBS_OST(aFile.FullName(fileName);)
  1894     FBS_OST(OstTraceExt4( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_LOADANDCOMPRESS3_ENTRY, "> this=0x%08x; file=%S; id=0x%08x; share=%d", (TUint)this, fileName, aId, aShareIfLoaded);)      
  1895 	TInt ret = LoadAndCompress(aFile,aId,aShareIfLoaded,0);
  1896     FBS_OST(OstTraceExt2( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_LOADANDCOMPRESS3_EXIT, "< this=0x%08x; ret=%d", (TUint)this, ret);)
  1897     return ret;
  1898 	}
  1899 
  1900 /** Loads and compresses a specific bitmap from an opened multi-bitmap file handle.
  1901 The bitmap may be shared by other font and bitmap server clients. If the 
  1902 bitmap is loaded from ROM then compression is not allowed.
  1903 @param aFile The handle of the multi-bitmap (.mbm) file. 
  1904 @param aId The bitmap identifier.
  1905 @param aShareIfLoaded Specifies whether or not the loaded bitmap will be made 
  1906 available for sharing between FBSERV clients.
  1907 @param aFileOffset Bitmap file section offset within the file.
  1908 @return KErrNone if successful, otherwise another of the system-wide error 
  1909 codes. 
  1910 @publishedAll 
  1911 @released
  1912 */	
  1913 EXPORT_C TInt CFbsBitmap::LoadAndCompress(RFile& aFile,TInt32 aId,TBool aShareIfLoaded,TUint aFileOffset)
  1914 	{
  1915     FBS_OST(TFullName fileName;)
  1916     FBS_OST(aFile.FullName(fileName);)
  1917     FBS_OST(OstTraceExt4( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_LOADANDCOMPRESS4_ENTRY, "> this=0x%08x; file=%S; id=0x%08x; share=%d", (TUint)this, fileName, aId, aShareIfLoaded);)
  1918 	TInt err = Load(aFile,aId,aShareIfLoaded,aFileOffset);
  1919 	if (err == KErrNone)
  1920 		{
  1921         if (!(iFlags & EIsRomBitmap))
  1922             {
  1923             err = Compress();
  1924             FBS_OST_IF(err!=KErrNone, OstTraceExt2( TRACE_ERROR, CFBSBITMAP_LOADANDCOMPRESS4_ERROR, "! this=0x%08x; Compress() returned %d", (TUint)this, err);)
  1925             }
  1926         else
  1927             {
  1928             err = KErrAccessDenied;
  1929             FBS_OST(OstTraceExt2( TRACE_ERROR, CFBSBITMAP_LOADANDCOMPRESS4_ERROR2, "! this=0x%08x; Cannot compress bitmap in ROM; iFlags=0x%08x", (TUint)this, (TUint)iFlags);)
  1930             }
  1931 		}
  1932 	FBS_OST(OstTraceExt2( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_LOADANDCOMPRESS4_EXIT, "< this=0x%08x; err=%d", (TUint)this, err);)
  1933 	return err;
  1934 	}
  1935 
  1936 /** Gets all the bitmap handles for all the bitmaps stored in the Font Bitmap Server. There is a limit of
  1937 the number of bitmaps that can be retrieved defined by KMaxBitmapHandleBufferSize. If this limit has been
  1938 reached then KErrOverflow will be returned.
  1939 @param aBitmapIdArray returns an array of all the bitmap handles
  1940 @return KErrNone if successful, KErrOverflow if the bitmapBuffer is not large enough to store 
  1941 all the bitmap handles, otherwise another of the system-wide error codes. 
  1942 @capability ReadDeviceData
  1943 @internalComponent
  1944 @released
  1945 */	
  1946 EXPORT_C TInt CFbsBitmap::GetAllBitmapHandles(RArray<TInt>& aBitmapIdArray) const
  1947 	{
  1948 	RBuf8 bitmapBuffer;
  1949 	TInt ret = bitmapBuffer.Create(KMaxBitmapHandleBufferSize);
  1950 	if (ret==KErrNone)
  1951 		{
  1952 		TIpcArgs args(&bitmapBuffer);
  1953 		ret=iFbs->SendCommand(EFbsGetAllBitmapHandles, args);
  1954 		if (ret==KErrNone)
  1955 			{
  1956 			// Convert data returned from server and place into the RArray (aBitmapIdArray)
  1957 			aBitmapIdArray.Reset();
  1958 			TInt* bitmapIdPtr = (TInt*)bitmapBuffer.Ptr();
  1959 			const TInt numBitmapIds = bitmapBuffer.Size() / KNumBytesPerBitmapHandle; // Divide by number of bytes per bitmap handle to get total number of bitmap IDs
  1960 			for (TInt count=0; count<numBitmapIds; ++count)
  1961 				{
  1962 				TInt bitmapId = *bitmapIdPtr++;
  1963 				ret = aBitmapIdArray.Append(bitmapId);
  1964 				if (ret!=KErrNone)
  1965 					break;
  1966 				}
  1967 			}
  1968 		}
  1969 	bitmapBuffer.Close();
  1970 	return ret;
  1971 	}
  1972 
  1973 /**
  1974 @internalComponent
  1975 This method tries to load a bitmap if mbm or rsc file is in ROM.
  1976 
  1977 @param  aRomPointer the address of the file in ROM
  1978 @param  aId a Bitmap ID which should be less than mbm file bitmaps count.
  1979 @param  aFileOffset mbm file section offset into rsc file.
  1980 @param  aRomPointerValid on output it is set to ETrue if aRomPointer points to a valid ROM file or EFalse otherwise.
  1981 @return KErrNone if successful, otherwise another of the system-wide error codes.
  1982 */
  1983 TInt CFbsBitmap::DoLoadFromRom(TUint32* aRomPointer, TInt32 aId, TUint aFileOffset, TBool& aRomPointerValid)
  1984 	{
  1985 	aRomPointerValid = ETrue;
  1986 	if(aRomPointer)
  1987 		{
  1988 		TUint8* temp = reinterpret_cast <TUint8*> (aRomPointer);
  1989 		__ASSERT_DEBUG(!(TUint(temp) & 0x00000003),Panic(EFbsBitmapAlignment));
  1990 		temp += aFileOffset;
  1991 		aRomPointer = reinterpret_cast <TUint32*> (temp);
  1992 		if(TInt32(*aRomPointer)==KMultiBitmapRomImageUid.iUid)
  1993 			{
  1994 			TInt numbitmaps = (TInt)*(aRomPointer+1);
  1995 			if(aId>=numbitmaps)
  1996 				{
  1997 				return(KErrEof);
  1998 				}
  1999 			TInt offset = *(aRomPointer+aId+2);
  2000 			iAddressPointer = (CBitwiseBitmap*)(((TUint8*)aRomPointer) + offset);
  2001 			iFlags = EIsRomBitmap;
  2002 			iHandle = 1;
  2003 			return iFbs->AllocScanLineBuffer(iAddressPointer->iByteWidth + 4);
  2004 			}
  2005 		}
  2006 	aRomPointerValid = EFalse;
  2007 	return KErrNone;
  2008 	}
  2009 
  2010 
  2011 /**
  2012 Creates an extended bitmap. Extended bitmaps are used to store immutable
  2013 data in a platform-specific format. They cannot be used as targets of
  2014 graphics contexts, and modification of their data via DataAddress() or
  2015 TBitmapUtil is not supported and results in undefined behaviour up to
  2016 and including process termination.
  2017 
  2018 Initialisation of the raw data of the new bitmap is carried out by copying 
  2019 the data pointed to by the parameter aData.
  2020 
  2021 Read-only access to the raw data of an extended bitmap is provided by
  2022 DataAddress() and DataSize() in conjunction with BeginDataAccess() and
  2023 EndDataAccess().
  2024 
  2025 Extended bitmaps have a conceptual size in pixels and a conceptual
  2026 display mode for compatibility purposes. The raw data can be independent
  2027 of these properties.
  2028 
  2029 @param aSizeInPixels The conceptual width and height of the new bitmap in pixels.
  2030 @param aDispMode The conceptual display mode of the new bitmap.
  2031 @param aType The UID identifying the data format of the new bitmap. Used by the
  2032              extended bitmap rasterizer to distinguish between different data types.
  2033 @param aData A pointer to the raw data to be stored in the new bitmap.
  2034 @param aDataSize The size in bytes of the raw data to be stored in the new bitmap.
  2035 @return KErrNone if successful; KErrArgument if the width or height specified in
  2036 aSizeInPixels is negative, aDispMode is an invalid display mode, aData is NULL,
  2037 aDataSize is negative or zero, or aDataType is a UID reserved for OS use; KErrTooBig
  2038 if the width or height specified in aSizeInPixels exceeds KMaxTInt/4, or aDataSize
  2039 exceeds KMaxTInt/2; otherwise another of the system-wide error codes.
  2040 @publishedPartner
  2041 @prototype
  2042 @see CFbsBitmap::DataAddress()
  2043 @see CFbsBitmap::DataSize()
  2044 @see CFbsBitmap::BeginDataAccess()
  2045 @see CFbsBitmap::EndDataAccess()
  2046 */
  2047 EXPORT_C TInt CFbsBitmap::CreateExtendedBitmap(const TSize& aSizeInPixels, TDisplayMode aDispMode, TUid aType, const TAny* aData, TInt aDataSize)
  2048 	{
  2049     TInt err;
  2050     FBS_OST(OstTraceExt5( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_CREATEEXTENDEDBITMAP_ENTRY, "> this=0x%08x; w=%d; h=%d; dm=%d; type=0x%08x", (TUint)this, aSizeInPixels.iWidth, aSizeInPixels.iHeight, aDispMode, aType.iUid);)
  2051 	if (!aData || aDataSize == 0)
  2052 		{
  2053         FBS_OST(OstTrace1( TRACE_ERROR, CFBSBITMAP_CREATEEXTENDEDBITMAP_ERROR, "! this=0x%08x; (!aData || aDataSize == 0)", (TUint)this);)
  2054 		err = KErrArgument;
  2055 		}
  2056 	else
  2057 	    {
  2058         err = DoCreate(aSizeInPixels, aDispMode, aType, aDataSize);
  2059         if (err == KErrNone)
  2060             {
  2061             Mem::Copy(iFbs->iLargeBitmapChunk.Base() + iAddressPointer->iDataOffset, aData, aDataSize);
  2062             }
  2063 	    }
  2064 	FBS_OST(OstTraceExt4( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_CREATEEXTENDEDBITMAP_EXIT, "< this=0x%08x; err=%d; iH=0x%08x; iSH=0x%08x", (TUint)this, err, iHandle, iServerHandle);)
  2065 	return err;
  2066 	}
  2067 
  2068 /**
  2069 Creates an extended bitmap. Extended bitmaps are used to store immutable
  2070 data in a platform-specific format. They cannot be used as targets of
  2071 graphics contexts, and modification of their data via DataAddress() or
  2072 TBitmapUtil is not supported and results in undefined behaviour up to
  2073 and including process termination.
  2074 
  2075 Initialisation of the raw data of the new bitmap is carried out by a 
  2076 callback to the MFbsExtendedBitmapInitializer::InitExtendedBitmap() 
  2077 function passed through the parameter aInitializer.
  2078 
  2079 Read-only access to the raw data of an extended bitmap is provided by
  2080 DataAddress() and DataSize() in conjunction with BeginDataAccess() and
  2081 EndDataAccess().
  2082 
  2083 Extended bitmaps have a conceptual size in pixels and a conceptual
  2084 display mode for compatibility purposes. The raw data can be independent
  2085 of these properties.
  2086 
  2087 @param aSizeInPixels The conceptual width and height of the new bitmap in pixels.
  2088 @param aDispMode The conceptual display mode of the new bitmap.
  2089 @param aType The UID identifying the data format of the new bitmap. Used by the
  2090              extended bitmap rasterizer to distinguish between different data types.
  2091 @param aDataSize The size in bytes of the raw data to be stored in the new bitmap.
  2092 @param aInitializer A reference to the initializer of the raw data to be stored in the new bitmap.
  2093 @return KErrNone if successful; KErrArgument if the width or height specified in
  2094 aSizeInPixels is negative, aDispMode is an invalid display mode, aData is NULL,
  2095 aDataSize is negative or zero, or aDataType is a UID reserved for OS use; KErrTooBig
  2096 if the width or height specified in aSizeInPixels exceeds KMaxTInt/4, or aDataSize
  2097 exceeds KMaxTInt/2; otherwise another of the system-wide error codes.
  2098 @publishedPartner
  2099 @prototype
  2100 @see CFbsBitmap::DataAddress()
  2101 @see CFbsBitmap::DataSize()
  2102 @see CFbsBitmap::BeginDataAccess()
  2103 @see CFbsBitmap::EndDataAccess()
  2104 @see MFbsExtendedBitmapInitializer
  2105 */
  2106 EXPORT_C TInt CFbsBitmap::CreateExtendedBitmap(const TSize& aSizeInPixels, TDisplayMode aDispMode, TUid aType, TInt aDataSize, MFbsExtendedBitmapInitializer& aInitializer)
  2107 	{
  2108     TInt err; 
  2109     FBS_OST(OstTraceExt5( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_CREATEEXTENDEDBITMAP2_ENTRY, "> this=0x%08x; w=%d; h=%d; dm=%d; type=0x%08x;", (TUint)this, aSizeInPixels.iWidth, aSizeInPixels.iHeight, aDispMode, aType.iUid);)
  2110 	if (aDataSize == 0)
  2111 		{
  2112         FBS_OST(OstTrace1( TRACE_ERROR, CFBSBITMAP_CREATEEXTENDEDBITMAP2_ERROR, "! this=0x%08x; aDataSize == 0", (TUint)this);)
  2113 		err = KErrArgument;
  2114 		}
  2115 	else
  2116 	    {
  2117         err = DoCreate(aSizeInPixels, aDispMode, aType, aDataSize);
  2118         if (err == KErrNone)
  2119             {
  2120             err = aInitializer.InitExtendedBitmap(iFbs->iLargeBitmapChunk.Base() + iAddressPointer->iDataOffset, aDataSize);
  2121             if (err != KErrNone)
  2122                 {
  2123                 Reset();
  2124                 }
  2125             }
  2126 	    }
  2127 	FBS_OST(OstTraceExt4( GRAPHICS_RESOURCE_MANAGEMENT_FUNCTIONS, CFBSBITMAP_CREATEEXTENDEDBITMAP2_EXIT, "< this=0x%08x; err=%d; iH=0x%08x; iSH=0x%08x", (TUint)this, err, iHandle, iServerHandle);)
  2128 	return err;
  2129 	}
  2130 
  2131 /**
  2132 Gets the UID identifying the data format of an extended bitmap.
  2133 @return The UID identifying the data format of the bitmap or
  2134         KNullUid if the bitmap is not an extended bitmap.
  2135 @publishedPartner
  2136 @prototype
  2137 */
  2138 EXPORT_C TUid CFbsBitmap::ExtendedBitmapType() const
  2139 	{
  2140 	if (iHandle == 0)
  2141 		{
  2142 		return KNullUid;
  2143 		}
  2144 	TUid type = CleanAddress()->iUid;
  2145 	if (type.iUid == KCBitwiseBitmapUid.iUid || type.iUid == KCBitwiseBitmapHardwareUid.iUid)
  2146 		{
  2147 		return KNullUid;
  2148 		}
  2149 	return type;
  2150 	}
  2151 
  2152 /**
  2153 Gets the size in bytes of the bitmap data.
  2154 @return The size in bytes of the bitmap data.
  2155 @publishedPartner
  2156 @prototype
  2157 */
  2158 EXPORT_C TInt CFbsBitmap::DataSize() const
  2159 	{
  2160 	if (iHandle == 0)
  2161 		{
  2162 		return 0;
  2163 		}
  2164 	CBitwiseBitmap* bmp = CleanAddress();
  2165 	return bmp->iHeader.iBitmapSize - bmp->iHeader.iStructSize;
  2166 	}
  2167 
  2168 /**
  2169 Gets a pointer to an extra buffer for general use owned by this thread's FBServ session.
  2170 @param aSize The size of the buffer in bytes
  2171 @return A pointer to the extra buffer if successful or NULL if there is no FBServ session
  2172 @internalTechnology
  2173 @released
  2174 */
  2175 EXPORT_C HBufC8* CFbsBitmap::GetExtraBuffer(TInt aSize)
  2176 	{
  2177 		RFbsSession* ses=RFbsSession::GetSession();
  2178 		return ses? ses->GetExtraBuffer(aSize) : NULL;
  2179 	}