graphicsdeviceinterface/screendriver/sbit/BMDRAW.CPP
changeset 0 5d03bc08d59c
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 // Copyright (c) 1997-2009 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 "BMDRAW.H"
       
    17 #include "BitDrawInterfaceId.h"
       
    18 
       
    19 GLDEF_C void Panic(TScreenDriverPanic aPanicCode)
       
    20 	{
       
    21 	_LIT(KSCDVPanicCategory,"SCDV");
       
    22 	User::Panic(KSCDVPanicCategory,aPanicCode);
       
    23 	}
       
    24 
       
    25 
       
    26 /**
       
    27 Alphablends a pixel.
       
    28 The formula used for that, is:
       
    29 (aPrimary * aAlphaValue + aSecondary * (255 - aAlphaValue)) / 255 - for each color (R,G,B).
       
    30 @param aPrimary RGB color 1.
       
    31 @param aSecondary RGB color 2.
       
    32 @param aAlphaValue Mask.
       
    33 @return Alpha blended value.
       
    34 @internalComponent
       
    35 */
       
    36 TRgb AlphaBlend(TRgb aPrimary, TRgb aSecondary, TInt aAlphaValue)
       
    37     {
       
    38     return ::AlphaBlend(aPrimary.Red(), aPrimary.Green(), aPrimary.Blue(), aSecondary, aAlphaValue);
       
    39     }
       
    40 
       
    41 GLREF_D const TUint8 ditherlutab[16][4];
       
    42 
       
    43 const TInt8 xIncArray[4] = { 1, 0, -1, 0 };
       
    44 const TInt8 yIncArray[4] = { 0, 1, 0, -1 };
       
    45 
       
    46 static CFbsDrawDevice* CreateBitmapDeviceL(const TSize& aSize, TDisplayMode aDispMode, TInt aDataStride)
       
    47 	{
       
    48 	CFbsDrawDevice* drawDevice = NULL;
       
    49 
       
    50 	switch(aDispMode)
       
    51 		{
       
    52 	case EGray2:
       
    53 		drawDevice = new(ELeave) CDrawOneBppBitmap;
       
    54 		CleanupStack::PushL(drawDevice);
       
    55 		User::LeaveIfError(((CDrawOneBppBitmap*)drawDevice)->Construct(aSize, aDataStride));
       
    56 		break;
       
    57 	case EGray4:
       
    58 		drawDevice = new(ELeave) CDrawTwoBppBitmap;
       
    59 		CleanupStack::PushL(drawDevice);
       
    60 		User::LeaveIfError(((CDrawTwoBppBitmap*)drawDevice)->Construct(aSize, aDataStride));
       
    61 		break;
       
    62 	case EGray16:
       
    63 		drawDevice = new(ELeave) CDrawFourBppBitmapGray;
       
    64 		CleanupStack::PushL(drawDevice);
       
    65 		User::LeaveIfError(((CDrawFourBppBitmapGray*)drawDevice)->Construct(aSize, aDataStride));
       
    66 		break;
       
    67 	case EGray256:
       
    68 		drawDevice = new(ELeave) CDrawEightBppBitmapGray;
       
    69 		CleanupStack::PushL(drawDevice);
       
    70 		User::LeaveIfError(((CDrawEightBppBitmapGray*)drawDevice)->Construct(aSize, aDataStride));
       
    71 		break;
       
    72 	case EColor16:
       
    73 		drawDevice = new(ELeave) CDrawFourBppBitmapColor;
       
    74 		CleanupStack::PushL(drawDevice);
       
    75 		User::LeaveIfError(((CDrawFourBppBitmapColor*)drawDevice)->Construct(aSize, aDataStride));
       
    76 		break;
       
    77 	case EColor256:
       
    78 		drawDevice = new(ELeave) CDrawEightBppBitmapColor;
       
    79 		CleanupStack::PushL(drawDevice);
       
    80 		User::LeaveIfError(((CDrawEightBppBitmapColor*)drawDevice)->Construct(aSize, aDataStride));
       
    81 		break;
       
    82 	case EColor4K:
       
    83 		drawDevice = new(ELeave) CDrawTwelveBppBitmap;
       
    84 		CleanupStack::PushL(drawDevice);
       
    85 		User::LeaveIfError(((CDrawTwelveBppBitmap*)drawDevice)->Construct(aSize, aDataStride));
       
    86 		break;
       
    87 	case EColor64K:
       
    88 		drawDevice = new(ELeave) CDrawSixteenBppBitmap;
       
    89 		CleanupStack::PushL(drawDevice);
       
    90 		User::LeaveIfError(((CDrawSixteenBppBitmap*)drawDevice)->Construct(aSize, aDataStride));
       
    91 		break;
       
    92 	case EColor16M:
       
    93 		drawDevice = new(ELeave) CDrawTwentyFourBppBitmap;
       
    94 		CleanupStack::PushL(drawDevice);
       
    95 		User::LeaveIfError(((CDrawTwentyFourBppBitmap*)drawDevice)->Construct(aSize, aDataStride));
       
    96 		break;
       
    97 	case EColor16MU:
       
    98 		drawDevice = new(ELeave) CDrawUTwentyFourBppBitmap;
       
    99 		CleanupStack::PushL(drawDevice);
       
   100 		User::LeaveIfError(((CDrawUTwentyFourBppBitmap*)drawDevice)->Construct(aSize, aDataStride));
       
   101 		break;
       
   102 	case EColor16MA:
       
   103 		drawDevice = new(ELeave) CDrawThirtyTwoBppBitmapAlpha;
       
   104 		CleanupStack::PushL(drawDevice);
       
   105 		User::LeaveIfError(((CDrawThirtyTwoBppBitmapAlpha*)drawDevice)->Construct(aSize, aDataStride));
       
   106 		break;
       
   107 	case EColor16MAP:
       
   108 		drawDevice = new(ELeave) CDrawThirtyTwoBppBitmapAlphaPM;
       
   109 		CleanupStack::PushL(drawDevice);
       
   110 		User::LeaveIfError(((CDrawThirtyTwoBppBitmapAlphaPM*)drawDevice)->Construct(aSize, aDataStride));
       
   111 		break;
       
   112 	default:
       
   113 		Panic(EScreenDriverPanicInvalidDisplayMode);
       
   114 		}
       
   115 	CleanupStack::Pop(drawDevice); // drawDevice
       
   116 	return drawDevice;
       
   117 	}
       
   118 
       
   119 /**
       
   120 @deprecated Use NewBitmapDeviceL(const TSize& aSize, TDisplayMode aDispMode, TInt aDataStride)
       
   121 */
       
   122 EXPORT_C CFbsDrawDevice* CFbsDrawDevice::NewBitmapDeviceL(TScreenInfoV01 aInfo,
       
   123 														  TDisplayMode aDispMode,
       
   124 														  TInt aDataStride)
       
   125 	{
       
   126 	return ::CreateBitmapDeviceL(aInfo.iScreenSize, aDispMode, aDataStride);
       
   127 	}
       
   128 
       
   129 /**
       
   130 Creates a new bitmap device instance, which implements CFbsDrawDevice interface.
       
   131 @param aSize Bitmap device size
       
   132 @param aDispMode Requested display mode
       
   133 @return A pointer to just created bitmap device, which implements CFbsDrawDevice interface
       
   134 @leave KErrNoMemory Not enough memory
       
   135        KErrArgument Invalid aSize value
       
   136 */
       
   137 EXPORT_C CFbsDrawDevice* CFbsDrawDevice::NewBitmapDeviceL(const TSize& aSize,
       
   138 														  TDisplayMode aDispMode,
       
   139 														  TInt aDataStride)
       
   140 	{
       
   141 	return ::CreateBitmapDeviceL(aSize, aDispMode, aDataStride);
       
   142 	}
       
   143 
       
   144 //Logical coordinates will be initialized with the right values, when SetSize() is called.
       
   145 CDrawBitmap::CDrawBitmap()
       
   146 	{
       
   147 	SetDefaults();
       
   148 	TInt err = GetInterface(KAlphaBlendInterfaceID, reinterpret_cast <TAny*&> (iAlphaBlend));
       
   149     //There must be a support for an interface with KAlphaBlendInterfaceID id.
       
   150     __ASSERT_ALWAYS(iAlphaBlend && err == KErrNone, User::Invariant());
       
   151 	}
       
   152 
       
   153 //Scanline width in pixels.
       
   154 //The return value can be greater or equal than iSize.iWidth, because
       
   155 //the scan line memory is allocated in 32-bit words and can be rounded up, if
       
   156 //the display mode allows more than 1 pixel to be stored in a single byte.
       
   157 TInt CDrawBitmap::LongWidth() const
       
   158 	{
       
   159 	//0 or 180 dgrees
       
   160 	if(!(iOrientation & 1))
       
   161 		{
       
   162 		return iLongWidth;
       
   163 		}
       
   164 	//90 or 270 degrees
       
   165 	return iSize.iWidth == 0 ? 0 : iLongWidth * iSize.iHeight / iSize.iWidth;
       
   166 	}
       
   167 
       
   168 TUint32* CDrawBitmap::ScanLineBuffer() const
       
   169 	{
       
   170 	return iScanLineBuffer;
       
   171 	}
       
   172 
       
   173 //Scanline width in bytes
       
   174 TInt CDrawBitmap::ScanLineBytes() const
       
   175 	{
       
   176 	register TInt scanLineBytes = iScanLineWords << 2;
       
   177 	//90 or 270 degrees
       
   178 	if(iOrientation & 1)
       
   179 		{
       
   180 		return iSize.iWidth == 0 ? 0 : scanLineBytes * iSize.iHeight / iSize.iWidth;
       
   181 		}
       
   182 	//0 or 180 degrees
       
   183 	return scanLineBytes;
       
   184 	}
       
   185 
       
   186 /**
       
   187 The method returns screen size in pixels. The orientation is taken into account.
       
   188 Always prefer GetDrawRect() to SizeInPixels() call.
       
   189 GetDrawRect() will take into account possible non-[0,0] top-left corner of the drawing
       
   190 rectangle if the device is scaled.
       
   191 @return TSize Screen size in pixels
       
   192 */
       
   193 TSize CDrawBitmap::SizeInPixels() const
       
   194 	{
       
   195 	//90 or 270 degrees
       
   196 	if(iOrientation & 1)
       
   197 		{
       
   198 		return TSize(iDrawRect.Height(), iDrawRect.Width());
       
   199 		}
       
   200 	//0 or 180 degrees
       
   201 	return iDrawRect.Size();
       
   202 	}
       
   203 
       
   204 //aPoint - logical coordinates
       
   205 void CDrawBitmap::SetDitherOrigin(const TPoint& aPoint)
       
   206 	{
       
   207 	if (iOrientation&1)
       
   208 		{
       
   209 		iDitherOrigin.iX = ::Log2Phys(aPoint.iX,iOrigin.iX,iScalingSettings.iFactorY,iSize.iHeight);
       
   210 		iDitherOrigin.iY = ::Log2Phys(aPoint.iY,iOrigin.iY,iScalingSettings.iFactorX,iSize.iWidth);
       
   211 		}
       
   212 	else
       
   213 		{
       
   214 		iDitherOrigin.iX = ::Log2Phys(aPoint.iX,iOrigin.iX,iScalingSettings.iFactorX,iSize.iWidth);
       
   215 		iDitherOrigin.iY = ::Log2Phys(aPoint.iY,iOrigin.iY,iScalingSettings.iFactorY,iSize.iHeight);
       
   216 		}
       
   217 	}
       
   218 
       
   219 TInt CDrawBitmap::BitsPerPixel(TDisplayMode aDispMode)
       
   220 	{
       
   221 	switch(aDispMode)
       
   222 		{
       
   223 	case EGray2:
       
   224 		return 1;
       
   225 	case EGray4:
       
   226 		return 2;
       
   227 	case EGray16:
       
   228 	case EColor16:
       
   229 		return 4;
       
   230 	case EGray256:
       
   231 	case EColor256:
       
   232 		return 8;
       
   233 	case EColor4K:
       
   234 	case EColor64K:
       
   235 		return 16;
       
   236 	case EColor16M:
       
   237 		return 24;
       
   238 	case EColor16MU:
       
   239 	case EColor16MA:
       
   240 	case EColor16MAP:
       
   241 		return 32;
       
   242 	default:
       
   243 		return 0;
       
   244 		}
       
   245 	}
       
   246 
       
   247 void CDrawBitmap::OrientationsAvailable(TBool aOrientation[4])
       
   248 	{
       
   249 	aOrientation[EOrientationNormal] = ETrue;
       
   250 	aOrientation[EOrientationRotated90] = EFalse;
       
   251 	aOrientation[EOrientationRotated180] = EFalse;
       
   252 	aOrientation[EOrientationRotated270] = EFalse;
       
   253 	}
       
   254 
       
   255 //Works with logical coordinates
       
   256 void CDrawBitmap::Clear()
       
   257 	{
       
   258 	if(iBits)
       
   259 		{
       
   260 		if(iScalingOff && iOriginIsZero)
       
   261 			{
       
   262 			Mem::Fill(iBits, iScanLineWords * 4 * iSize.iHeight, 0xFF);
       
   263 			}
       
   264 		else
       
   265 			{
       
   266 			TShadowMode storedShadowMode = iShadowMode;
       
   267 			iShadowMode = ENoShadow;
       
   268 			TRect drawRect;
       
   269 			GetDrawRect(drawRect);
       
   270 			WriteRgbMulti(drawRect.iTl.iX, drawRect.iTl.iY, drawRect.Width(), drawRect.Height(), KRgbWhite, CGraphicsContext::EDrawModeWriteAlpha);
       
   271 			iShadowMode = storedShadowMode;
       
   272 			}
       
   273 		}
       
   274 	}
       
   275 
       
   276 CDrawBitmap::~CDrawBitmap()
       
   277 	{
       
   278 	if(iScanLineBuffer)
       
   279 		{
       
   280 		User::Free(iScanLineBuffer);
       
   281 		}
       
   282 	}
       
   283 
       
   284 //Works with logical sizes
       
   285 //The new device will accept old device scalling&scaling settings
       
   286 //All graphics contexts, already created by the scaled device, should be
       
   287 //re-activated calling CFbsBitGc::Activate().
       
   288 void CDrawBitmap::CopyOldSettings(CFbsDrawDevice* aDrawDevice)
       
   289 	{
       
   290 	__ASSERT_DEBUG(aDrawDevice, User::Invariant());
       
   291 	//Scaling&Origin settings - their values when scaling&origin are off.
       
   292 	const TPoint KDefaultOrigin(0, 0);
       
   293 	const TInt KDefaultFactorX = 1, KDefaultFactorY = 1;
       
   294 	const TInt KDefaultDivisorX = 1, KDefaultDivisorY = 1;
       
   295 	TPoint origin = KDefaultOrigin;//old device origin
       
   296 	TInt factorX = KDefaultFactorX, factorY = KDefaultFactorY;//old device - X and Y scaling factors
       
   297 	TInt divisorX = KDefaultDivisorX, divisorY = KDefaultDivisorY;//old device - X and Y scaling divisors
       
   298 	//Old device - set default scaling setings.
       
   299 	MScalingSettings* scalingSettings = NULL;
       
   300 	TInt err = aDrawDevice->GetInterface(KScalingSettingsInterfaceID, reinterpret_cast <TAny*&> (scalingSettings));
       
   301 	if(err == KErrNone)
       
   302 		{//There is a support for the interface with KScalingSettingsInterfaceID id.
       
   303 		__ASSERT_DEBUG(scalingSettings, User::Invariant());
       
   304 		scalingSettings->Get(factorX, factorY, divisorX, divisorY);
       
   305 		(void)scalingSettings->Set(KDefaultFactorX, KDefaultFactorY, KDefaultDivisorX, KDefaultDivisorY);
       
   306 		}
       
   307 	//Current device - set default scaling setings.
       
   308 	if(CanBeScaled())
       
   309 		{
       
   310 		(void)Set(KDefaultFactorX, KDefaultFactorY, KDefaultDivisorX, KDefaultDivisorY);
       
   311 		}
       
   312 	//Old device - set default origin.
       
   313 	MDrawDeviceOrigin* originInterface = NULL;
       
   314 	err = aDrawDevice->GetInterface(KDrawDeviceOriginInterfaceID, reinterpret_cast <TAny*&> (originInterface));
       
   315 	if(err == KErrNone)
       
   316 		{//There is a support for the interface with KDrawDeviceOriginInterfaceID id.
       
   317 		__ASSERT_DEBUG(originInterface, User::Invariant());
       
   318 		originInterface->Get(origin);
       
   319 		(void)originInterface->Set(KDefaultOrigin);
       
   320 		}
       
   321 	//Current device - set default origin.
       
   322 	if(CanOriginBeMoved())
       
   323 		{
       
   324 		(void)Set(KDefaultOrigin);
       
   325 		}
       
   326 	//Copy setigns
       
   327 	DoCopyOldSettings(aDrawDevice);
       
   328 	//Old device - restore scaling setings.
       
   329 	if(scalingSettings)
       
   330 		{
       
   331 		(void)scalingSettings->Set(factorX, factorY, divisorX, divisorY);
       
   332 		}
       
   333 	//Old device - restore origin.
       
   334 	if(originInterface)
       
   335 		{
       
   336 		(void)originInterface->Set(origin);
       
   337 		}
       
   338 	//Set current device scaling&origin settings to be the same as
       
   339 	//scaling&origin settings of the old device.
       
   340 	if(CanBeScaled())
       
   341 		{
       
   342 		(void)Set(factorX, factorY, divisorX, divisorY);
       
   343 		}
       
   344 	if(CanOriginBeMoved())
       
   345 		{
       
   346 		(void)Set(origin);
       
   347 		}
       
   348 	}
       
   349 
       
   350 void CDrawBitmap::DoCopyOldSettings(CFbsDrawDevice* aDrawDevice)
       
   351 	{
       
   352 	CDrawBitmap* oldDevice = (CDrawBitmap*)aDrawDevice;
       
   353 	iDitherOrigin = oldDevice->iDitherOrigin;
       
   354 	iShadowMode = oldDevice->iShadowMode;
       
   355 	SetOrientation(oldDevice->iOrientation);
       
   356 	iFadeMapFactor = oldDevice->iFadeMapFactor;
       
   357 	iFadeMapOffset = oldDevice->iFadeMapOffset;
       
   358 
       
   359 	TUint32* destRowPtr = iBits;
       
   360 	TUint32* destRowPtrLimit = iBits;
       
   361 	TInt destRowPtrInc = iScanLineWords;
       
   362 
       
   363 	TInt row = 0;
       
   364 	TInt rowInc = 1;
       
   365 
       
   366 	if (BitsPerPixel(oldDevice->iDispMode) < BitsPerPixel(iDispMode))
       
   367 		{
       
   368 		destRowPtr += (iSize.iHeight - 1) * iScanLineWords;
       
   369 		destRowPtrInc = -destRowPtrInc;
       
   370 		destRowPtrLimit -= iScanLineWords;
       
   371 		row = iSize.iHeight - 1;
       
   372 		rowInc = -1;
       
   373 		}
       
   374 	else
       
   375 		destRowPtrLimit += iSize.iHeight * iScanLineWords;
       
   376 
       
   377 	TOrientation oldOrientation=oldDevice->iOrientation;
       
   378 	oldDevice->SetOrientation(CFbsDrawDevice::EOrientationNormal);
       
   379 	while (destRowPtr != destRowPtrLimit)
       
   380 		{
       
   381 		aDrawDevice->ReadLine(0,row,iSize.iWidth,iScanLineBuffer,iDispMode);
       
   382 		Mem::Copy(destRowPtr,iScanLineBuffer,iScanLineWords << 2);
       
   383 		destRowPtr += destRowPtrInc;
       
   384 		row += rowInc;
       
   385 		}
       
   386 
       
   387 	oldDevice->SetOrientation(oldOrientation);
       
   388 	UpdateRegion(TRect(SizeInPixels()));
       
   389 	Update();
       
   390 	}
       
   391 
       
   392 TUint32 CDrawBitmap::Hash(TUint32 aGray16,TInt aX,TInt aY) const
       
   393 	{
       
   394 	if (iDitherOrigin.iX & 1)
       
   395 		aX++;
       
   396 	if (iDitherOrigin.iY & 1)
       
   397 		aY++;
       
   398 	aX &= 1;
       
   399 	aY &= 1;
       
   400 	return ditherlutab[aGray16][aX + (aY << 1)];
       
   401 	}
       
   402 
       
   403 //aRect - logical coordinates
       
   404 void CDrawBitmap::MapColors(const TRect& aRect, const TRgb* aColors,
       
   405 							TInt aNumPairs, TBool aMapForwards)
       
   406 	{
       
   407 	const TRect rect = DeOrientate(aRect);//deorientation and transformation of coordinates.
       
   408 	//rect - physical coordinates
       
   409 	__ASSERT_DEBUG(rect.iTl.iX >= 0 && rect.iBr.iX <= iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds));
       
   410 	__ASSERT_DEBUG(rect.iTl.iY >= 0 && rect.iBr.iY <= iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds));
       
   411 	__ASSERT_DEBUG(aColors,Panic(EScreenDriverPanicNullPointer));
       
   412 	__ASSERT_DEBUG(aNumPairs > 0,Panic(EScreenDriverPanicZeroLength));
       
   413 
       
   414 	TRgb color;
       
   415 
       
   416 	TInt offset = aMapForwards ? 0 : 1;
       
   417 	TInt scaleX;
       
   418 	TInt scaleY;
       
   419 	if (iOrientation&1)
       
   420 		{
       
   421 		scaleX=iScalingSettings.iFactorY;
       
   422 		scaleY=iScalingSettings.iFactorX;
       
   423 		}
       
   424 	else
       
   425 		{
       
   426 		scaleX=iScalingSettings.iFactorX;
       
   427 		scaleY=iScalingSettings.iFactorY;
       
   428 		}
       
   429 	for(TInt ycoord = rect.iTl.iY; ycoord < rect.iBr.iY; ycoord+=scaleY)
       
   430 		{
       
   431 		for(TInt xcoord = rect.iTl.iX; xcoord < rect.iBr.iX; xcoord+=scaleX)
       
   432 			{
       
   433 			color = ReadRgbNormal(xcoord,ycoord);
       
   434 			for (TInt rgbcount = 0; rgbcount < aNumPairs; rgbcount++)
       
   435 				{
       
   436 				if (color == aColors[(rgbcount << 1) + offset])
       
   437 					{
       
   438 					WriteRgb(xcoord,ycoord,aColors[(rgbcount << 1) + 1 - offset]);
       
   439 					break;
       
   440 					}
       
   441 				}
       
   442 			}
       
   443 		}
       
   444 	}
       
   445 
       
   446 //form an int from the end portion of one and the start portion of another
       
   447 TUint32 CDrawBitmap::PasteInt(TUint32 aFirst,TUint32 aSecond,TInt aOffset) const
       
   448 	{
       
   449 	TUint32 mask=0;
       
   450 	if(aOffset<32) mask=0xffffffff>>aOffset;
       
   451 	aFirst&=mask;
       
   452 	aSecond&=~mask;
       
   453 	return(aFirst|aSecond);
       
   454 	}
       
   455 
       
   456 //returns the address of the start of scanline aY
       
   457 //aY- physical coordinate
       
   458 TUint32* CDrawBitmap::ScanLine(TInt aY) const
       
   459 	{
       
   460 	return iBits + (aY * iScanLineWords);
       
   461 	}
       
   462 
       
   463 void CDrawBitmap::SetBits(TAny* aBits)
       
   464 	{
       
   465 	iBits = STATIC_CAST(TUint32*,aBits);
       
   466 	}
       
   467 
       
   468 TBool CDrawBitmap::SetOrientation(TOrientation aOrientation)
       
   469 	{
       
   470 	if (iOrientation == aOrientation)
       
   471 		return ETrue;
       
   472 
       
   473 	return EFalse;
       
   474 	}
       
   475 
       
   476 void CDrawBitmap::SetFadingParameters(TUint8 aBlackMap,TUint8 aWhiteMap)
       
   477 	{
       
   478 	iFadeMapFactor = aWhiteMap - aBlackMap + 1;
       
   479 	iFadeMapOffset = aBlackMap;
       
   480 	}
       
   481 
       
   482 TRgb CDrawBitmap::FadeRgb(TRgb aColor)
       
   483 	{
       
   484 	TInt value = aColor.Internal();
       
   485 	TInt b = (((value & 0x000000ff) * iFadeMapFactor) >> 8)  + iFadeMapOffset;
       
   486 	TInt g = (((value & 0x0000ff00) * iFadeMapFactor) >> 16) + iFadeMapOffset;
       
   487 	//the multiplication by iFadeMapFactor can overflow into the sign bit, so we shift down in two steps
       
   488 	TInt r = ((((value & 0x00ff0000) >> 16) * iFadeMapFactor) >> 8) + iFadeMapOffset;
       
   489 	TInt a = aColor.Alpha();
       
   490   	return TRgb(r,g,b,a);
       
   491 	}
       
   492 
       
   493  TUint32 CDrawBitmap::FadeRgb(TUint32 aColor)
       
   494   	{
       
   495   	TInt value = aColor;
       
   496 
       
   497   	TInt b = (((value & 0x000000ff) * iFadeMapFactor) >> 8)  + iFadeMapOffset;
       
   498    	TInt g = (((value & 0x0000ff00) * iFadeMapFactor) >> 16) + iFadeMapOffset;
       
   499   	//the multiplication by iFadeMapFactor can overflow into the sign bit, so we shift down in two steps
       
   500    	TInt r = ((((value & 0x00ff0000) >> 16) * iFadeMapFactor) >> 8) + iFadeMapOffset;
       
   501    	TInt a = aColor >> 24;
       
   502    	return (a<<24) | ((r&0xff)<<16) | ((g&0xff)<<8) | (b&0xff);
       
   503     }
       
   504 
       
   505 /**
       
   506 The overloaded function for FadeRgb(TRgb) which works directly with
       
   507 the Red, Green and Blue colour components to increase the performance.
       
   508 @param aRed Red component of colour.
       
   509 @param aGreen Green component of colour.
       
   510 @param aBlue Blue component of colour.
       
   511 */
       
   512 void CDrawBitmap::FadeRgb(TInt& aRed, TInt& aGreen, TInt& aBlue)
       
   513 	{
       
   514 	aRed = ((aRed * iFadeMapFactor) >> 8)  + iFadeMapOffset;
       
   515 	aGreen = ((aGreen * iFadeMapFactor) >> 8)  + iFadeMapOffset;
       
   516 	aBlue = ((aBlue * iFadeMapFactor) >> 8)  + iFadeMapOffset;
       
   517 	}
       
   518 
       
   519 TUint8 CDrawBitmap::FadeGray(TInt aGray256)
       
   520 	{
       
   521 	return STATIC_CAST(TUint8,((aGray256 * iFadeMapFactor) >> 8) + iFadeMapOffset);
       
   522 	}
       
   523 
       
   524 //aX and aY - logical coordinates
       
   525 //aX and aY - deorientated and transformed to physical coordinates after the call
       
   526 void CDrawBitmap::DeOrientate(TInt& aX,TInt& aY) const
       
   527 	{
       
   528 	register TInt physWidth = iSize.iWidth;
       
   529 	register TInt physHeight = iSize.iHeight;
       
   530 	register TInt originX = iOrigin.iX;
       
   531 	register TInt originY = iOrigin.iY;
       
   532 	register TInt scalingFactorX = iScalingSettings.iFactorX;
       
   533 	register TInt scalingFactorY = iScalingSettings.iFactorY;
       
   534 	if(iOrientation & 0x1)
       
   535 		{
       
   536 		aX = ::Log2Phys(aX, originX, scalingFactorY, physHeight);
       
   537 		aY = ::Log2Phys(aY, originY, scalingFactorX, physWidth);
       
   538 		}
       
   539 	else
       
   540 		{
       
   541 		aX = ::Log2Phys(aX, originX, scalingFactorX, physWidth);
       
   542 		aY = ::Log2Phys(aY, originY, scalingFactorY, physHeight);
       
   543 		}
       
   544 
       
   545 	//aX and aY - descaled.
       
   546 	switch(iOrientation)
       
   547 		{
       
   548 		case EOrientationNormal:
       
   549 			{
       
   550 			return;
       
   551 			}
       
   552 		case EOrientationRotated180:
       
   553 			{
       
   554 			aX = physWidth - aX - 1;
       
   555 			aY = physHeight - aY - 1;
       
   556 			break;
       
   557 			}
       
   558 			case EOrientationRotated90:
       
   559 			{
       
   560 			TInt temp = physWidth - aY - 1;
       
   561 			aY = aX;
       
   562 			aX = temp;
       
   563 			break;
       
   564 			}
       
   565 		default: // EOrientationRotated270
       
   566 			{
       
   567 			TInt temp = aY;
       
   568 			aY = physHeight - aX - 1;
       
   569 			aX = temp;
       
   570 			}
       
   571 		}
       
   572 	}
       
   573 
       
   574 //aPoint - logical coordinates
       
   575 //The method returns TPoint object with deorientated and transformed to physical coordinates.
       
   576 TPoint CDrawBitmap::DeOrientate(const TPoint& aPoint) const
       
   577 	{
       
   578 	register TInt physWidth = iSize.iWidth;
       
   579 	register TInt physHeight = iSize.iHeight;
       
   580 	register TInt originX = iOrigin.iX;
       
   581 	register TInt originY = iOrigin.iY;
       
   582 	register TInt scalingFactorX = iScalingSettings.iFactorX;
       
   583 	register TInt scalingFactorY = iScalingSettings.iFactorY;
       
   584 	TPoint physPt;
       
   585 	if(iOrientation & 0x1)
       
   586 		{
       
   587 		physPt.iX = ::Log2Phys(aPoint.iX, originX, scalingFactorY, physHeight);
       
   588 		physPt.iY = ::Log2Phys(aPoint.iY, originY, scalingFactorX, physWidth);
       
   589 		}
       
   590 	else
       
   591 		{
       
   592 		physPt.iX = ::Log2Phys(aPoint.iX, originX, scalingFactorX, physWidth);
       
   593 		physPt.iY = ::Log2Phys(aPoint.iY, originY, scalingFactorY, physHeight);
       
   594 		}
       
   595 
       
   596 	//physPt - descaled
       
   597 	switch(iOrientation)
       
   598 		{
       
   599 		case EOrientationNormal:
       
   600 			{
       
   601 			return physPt;
       
   602 			}
       
   603 		case EOrientationRotated180:
       
   604 			{
       
   605 			return TPoint(physWidth - physPt.iX - 1, physHeight - physPt.iY - 1);
       
   606 			}
       
   607 		case EOrientationRotated90:
       
   608 			{
       
   609 			return TPoint(physWidth - physPt.iY - 1, physPt.iX);
       
   610 			}
       
   611 		// EOrientationRotated270
       
   612 		default:
       
   613 			return TPoint(physPt.iY, physHeight - physPt.iX - 1);
       
   614 		}
       
   615 	}
       
   616 
       
   617 //aRect - logical coordinates
       
   618 //The method returns TRect object with deorientated and transformed to physical coordinates.
       
   619 TRect CDrawBitmap::DeOrientate(const TRect& aRect) const
       
   620 	{
       
   621 	register TInt originX = iOrigin.iX;
       
   622 	register TInt originY = iOrigin.iY;
       
   623 	register TInt scalingFactorX = iScalingSettings.iFactorX;
       
   624 	register TInt scalingFactorY = iScalingSettings.iFactorY;
       
   625 	register TInt physWidth = iSize.iWidth;
       
   626 	register TInt physHeight = iSize.iHeight;
       
   627 	TRect physRect;
       
   628 	if(iOrientation & 0x1)
       
   629 		{
       
   630 		physRect.iTl.iX = ::Log2Phys(aRect.iTl.iX, originX, scalingFactorY, physHeight);
       
   631 		physRect.iTl.iY = ::Log2Phys(aRect.iTl.iY, originY, scalingFactorX, physWidth);
       
   632 		physRect.iBr.iX = ::RBtmLog2Phys(aRect.iBr.iX, originX, scalingFactorY, physHeight);
       
   633 		physRect.iBr.iY = ::RBtmLog2Phys(aRect.iBr.iY, originY, scalingFactorX, physWidth);
       
   634 		}
       
   635 	else
       
   636 		{
       
   637 		physRect.iTl.iX = ::Log2Phys(aRect.iTl.iX, originX, scalingFactorX, physWidth);
       
   638 		physRect.iTl.iY = ::Log2Phys(aRect.iTl.iY, originY, scalingFactorY, physHeight);
       
   639 		physRect.iBr.iX = ::RBtmLog2Phys(aRect.iBr.iX, originX, scalingFactorX, physWidth);
       
   640 		physRect.iBr.iY = ::RBtmLog2Phys(aRect.iBr.iY, originY, scalingFactorY, physHeight);
       
   641 		}
       
   642 
       
   643 	//physRect - descaled
       
   644 	if(iOrientation == EOrientationNormal)
       
   645 		{
       
   646 		return physRect;
       
   647 		}
       
   648 	if (iOrientation == EOrientationRotated180)
       
   649 		{
       
   650 		return TRect(TPoint(physWidth - physRect.iBr.iX, physHeight - physRect.iBr.iY), physRect.Size());
       
   651 		}
       
   652 	TSize altSize(physRect.Height(), physRect.Width());
       
   653 	TPoint altPoint;
       
   654 	if (iOrientation == EOrientationRotated90)
       
   655 		{
       
   656 		altPoint.SetXY(physWidth - physRect.iBr.iY, physRect.iTl.iX);
       
   657 		}
       
   658 	else // EOrientationRotated270
       
   659 		{
       
   660 		altPoint.SetXY(physRect.iTl.iY, physHeight - physRect.iBr.iX);
       
   661 		}
       
   662 	return TRect(altPoint, altSize);
       
   663 	}
       
   664 
       
   665 //aX and aY - logical coordinates
       
   666 TRgb CDrawBitmap::ReadPixel(TInt aX,TInt aY) const
       
   667 	{
       
   668 	DeOrientate(aX, aY);//aX and aY - physical coordinates
       
   669 
       
   670 	__ASSERT_DEBUG(aX >= 0 && aX < iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds));
       
   671 	__ASSERT_DEBUG(aY >= 0 && aY < iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds));
       
   672 
       
   673 	return ReadRgbNormal(aX, aY);
       
   674 	}
       
   675 
       
   676 //aX and aY - logical coordinates
       
   677 void CDrawBitmap::ReadLine(TInt aX,TInt aY,TInt aLength,
       
   678 						   TAny* aBuffer,TDisplayMode aDispMode) const
       
   679 	{
       
   680 	DeOrientate(aX,aY);//aX and aY - physical coordinates
       
   681 
       
   682 	__ASSERT_DEBUG(aX >= 0 && aX < iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds));
       
   683 	__ASSERT_DEBUG(aY >= 0 && aY < iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds));
       
   684 #if defined(_DEBUG)
       
   685 	switch (iOrientation)
       
   686 		{
       
   687 	case EOrientationNormal:
       
   688 		__ASSERT_DEBUG(aX + aLength <= iLongWidth,Panic(EScreenDriverPanicOutOfBounds));
       
   689 		break;
       
   690 	case EOrientationRotated90:
       
   691 		__ASSERT_DEBUG(aY + aLength <= iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds));
       
   692 		break;
       
   693 	case EOrientationRotated180:
       
   694 		__ASSERT_DEBUG(aX - aLength >= -1,Panic(EScreenDriverPanicOutOfBounds));
       
   695 		break;
       
   696 	default: // EOrientationRotated270
       
   697 		__ASSERT_DEBUG(aY - aLength >= -1,Panic(EScreenDriverPanicOutOfBounds));
       
   698 		break;
       
   699 		}
       
   700 #endif
       
   701 	__ASSERT_DEBUG(aLength > 0,Panic(EScreenDriverPanicZeroLength));
       
   702 	__ASSERT_DEBUG(aBuffer,Panic(EScreenDriverPanicNullPointer));
       
   703 
       
   704 	if (aDispMode == iDispMode)
       
   705 		{
       
   706 		ReadLine(aX,aY,aLength,aBuffer);
       
   707 		return;
       
   708 		}
       
   709 
       
   710 	TInt xInc = xIncArray[iOrientation];
       
   711 	TInt yInc = yIncArray[iOrientation];
       
   712 	if(iOrientation & 0x1)
       
   713 		{
       
   714 		xInc*=iScalingSettings.iFactorY;
       
   715 		yInc*=iScalingSettings.iFactorX;
       
   716 		}
       
   717 	else
       
   718 		{
       
   719 		xInc*=iScalingSettings.iFactorX;
       
   720 		yInc*=iScalingSettings.iFactorY;
       
   721 		}
       
   722 
       
   723 	switch (aDispMode)
       
   724 		{
       
   725 		case EGray2:
       
   726 			{
       
   727 			TUint8* bufferPtr = (TUint8*)aBuffer;
       
   728 
       
   729 			while (aLength >= 8)
       
   730 				{
       
   731 				bufferPtr[0] = TUint8(ReadRgbNormal(aX,aY)._Gray2());
       
   732 				aX += xInc; aY += yInc;
       
   733 				bufferPtr[0] |= TUint8(ReadRgbNormal(aX,aY)._Gray2() << 1);
       
   734 				aX += xInc; aY += yInc;
       
   735 				bufferPtr[0] |= TUint8(ReadRgbNormal(aX,aY)._Gray2() << 2);
       
   736 				aX += xInc; aY += yInc;
       
   737 				bufferPtr[0] |= TUint8(ReadRgbNormal(aX,aY)._Gray2() << 3);
       
   738 				aX += xInc; aY += yInc;
       
   739 				bufferPtr[0] |= TUint8(ReadRgbNormal(aX,aY)._Gray2() << 4);
       
   740 				aX += xInc; aY += yInc;
       
   741 				bufferPtr[0] |= TUint8(ReadRgbNormal(aX,aY)._Gray2() << 5);
       
   742 				aX += xInc; aY += yInc;
       
   743 				bufferPtr[0] |= TUint8(ReadRgbNormal(aX,aY)._Gray2() << 6);
       
   744 				aX += xInc; aY += yInc;
       
   745 				bufferPtr[0] |= TUint8(ReadRgbNormal(aX,aY)._Gray2() << 7);
       
   746 				aX += xInc; aY += yInc;
       
   747 				bufferPtr++;
       
   748 				aLength -= 8;
       
   749 				}
       
   750 			TInt bitShift = 0;
       
   751 			TInt bitLimit = aLength;
       
   752 			if (bitShift < bitLimit)
       
   753 				bufferPtr[0] = 0;
       
   754 			while (bitShift < bitLimit)
       
   755 				{
       
   756 				bufferPtr[0] |= TUint8(ReadRgbNormal(aX,aY)._Gray2() << bitShift);
       
   757 				aX += xInc; aY += yInc;
       
   758 				bitShift++;
       
   759 				}
       
   760 			}
       
   761 			break;
       
   762 		case EGray4:
       
   763 			{
       
   764 			TUint8* bufferPtr = REINTERPRET_CAST(TUint8*,aBuffer);
       
   765 
       
   766 			while (aLength > 3)
       
   767 				{
       
   768 				*bufferPtr = TUint8(ReadRgbNormal(aX,aY)._Gray4());
       
   769 				aX += xInc; aY += yInc;
       
   770 				*bufferPtr |= TUint8(ReadRgbNormal(aX,aY)._Gray4() << 2);
       
   771 				aX += xInc; aY += yInc;
       
   772 				*bufferPtr |= TUint8(ReadRgbNormal(aX,aY)._Gray4() << 4);
       
   773 				aX += xInc; aY += yInc;
       
   774 				*bufferPtr++ |= TUint8(ReadRgbNormal(aX,aY)._Gray4() << 6);
       
   775 				aX += xInc; aY += yInc;
       
   776 				aLength -= 4;
       
   777 				}
       
   778 			if (aLength > 0)
       
   779 				{
       
   780 				*bufferPtr = TUint8(ReadRgbNormal(aX,aY)._Gray4());
       
   781 				aX += xInc; aY += yInc;
       
   782 				aLength--;
       
   783 				}
       
   784 			if (aLength > 0)
       
   785 				{
       
   786 				*bufferPtr |= TUint8(ReadRgbNormal(aX,aY)._Gray4() << 2);
       
   787 				aX += xInc; aY += yInc;
       
   788 				aLength--;
       
   789 				}
       
   790 			if (aLength > 0)
       
   791 				*bufferPtr |= TUint8(ReadRgbNormal(aX,aY)._Gray4() << 4);
       
   792 			}
       
   793 			break;
       
   794 		case EGray16:
       
   795 			{
       
   796 			TUint8* bufferPtr = (TUint8*)aBuffer;
       
   797 
       
   798 			while (aLength > 1)
       
   799 				{
       
   800 				*bufferPtr = TUint8(ReadRgbNormal(aX,aY)._Gray16());
       
   801 				aX += xInc; aY += yInc;
       
   802 				*bufferPtr++ |= TUint8(ReadRgbNormal(aX,aY)._Gray16() << 4);
       
   803 				aX += xInc; aY += yInc;
       
   804 				aLength -= 2;
       
   805 				}
       
   806 			if (aLength > 0)
       
   807 				*bufferPtr = TUint8(ReadRgbNormal(aX,aY)._Gray16());
       
   808 			}
       
   809 			break;
       
   810 		case EGray256:
       
   811 			{
       
   812 			TUint8* bufferPtr = (TUint8*)aBuffer;
       
   813 			const TUint8* bufferPtrLimit = bufferPtr + aLength;
       
   814 
       
   815 			while (bufferPtr < bufferPtrLimit)
       
   816 				{
       
   817 				*bufferPtr++ = TUint8(ReadRgbNormal(aX,aY)._Gray256());
       
   818 				aX += xInc; aY += yInc;
       
   819 				}
       
   820 			}
       
   821 			break;
       
   822 		case EColor16:
       
   823 			{
       
   824 			TUint8* bufferPtr = (TUint8*)aBuffer;
       
   825 
       
   826 			while (aLength > 1)
       
   827 				{
       
   828 				*bufferPtr = TUint8(ReadRgbNormal(aX,aY).Color16());
       
   829 				aX += xInc; aY += yInc;
       
   830 				*bufferPtr++ |= TUint8(ReadRgbNormal(aX,aY).Color16() << 4);
       
   831 				aX += xInc; aY += yInc;
       
   832 				aLength -= 2;
       
   833 				}
       
   834 			if (aLength > 0)
       
   835 				*bufferPtr = TUint8(ReadRgbNormal(aX,aY).Color16());
       
   836 			}
       
   837 			break;
       
   838 		case EColor256:
       
   839 			{
       
   840 			TUint8* bufferPtr = (TUint8*)aBuffer;
       
   841 			const TUint8* bufferPtrLimit = bufferPtr + aLength;
       
   842 
       
   843 			while (bufferPtr < bufferPtrLimit)
       
   844 				{
       
   845 				*bufferPtr++ = TUint8(ReadRgbNormal(aX,aY).Color256());
       
   846 				aX += xInc; aY += yInc;
       
   847 				}
       
   848 			}
       
   849 			break;
       
   850 		case EColor4K:
       
   851 			{
       
   852 			TUint16* bufferPtr = (TUint16*)aBuffer;
       
   853 			const TUint16* bufferPtrLimit = bufferPtr + aLength;
       
   854 
       
   855 			while (bufferPtr < bufferPtrLimit)
       
   856 				{
       
   857 				*bufferPtr++ = TUint16(ReadRgbNormal(aX,aY)._Color4K());
       
   858 				aX += xInc; aY += yInc;
       
   859 				}
       
   860 			}
       
   861 			break;
       
   862 		case EColor64K:
       
   863 			{
       
   864 			TUint16* bufferPtr = (TUint16*)aBuffer;
       
   865 			const TUint16* bufferPtrLimit = bufferPtr + aLength;
       
   866 
       
   867 			while (bufferPtr < bufferPtrLimit)
       
   868 				{
       
   869 				*bufferPtr++ = TUint16(ReadRgbNormal(aX,aY)._Color64K());
       
   870 				aX += xInc; aY += yInc;
       
   871 				}
       
   872 			}
       
   873 			break;
       
   874 		case EColor16M:
       
   875 			{
       
   876 			TUint8* bufferPtr = (TUint8*)aBuffer;
       
   877 			const TUint8* bufferPtrLimit = bufferPtr + (aLength * 3);
       
   878 
       
   879 			while (bufferPtr < bufferPtrLimit)
       
   880 				{
       
   881 				TUint32 pixelColorValue = ReadRgbNormal(aX,aY).Internal();
       
   882 				aX += xInc; aY += yInc;
       
   883 				bufferPtr[0] = TUint8(pixelColorValue);
       
   884 				bufferPtr[1] = TUint8(pixelColorValue >> 8);
       
   885 				bufferPtr[2] = TUint8(pixelColorValue >> 16);
       
   886 				bufferPtr += 3;
       
   887 				}
       
   888 			}
       
   889 			break;
       
   890 		case ERgb:
       
   891 			{
       
   892 			TRgb* bufferPtr = (TRgb*)aBuffer;
       
   893 			const TRgb* bufferPtrLimit = bufferPtr + aLength;
       
   894 
       
   895 			while (bufferPtr < bufferPtrLimit)
       
   896 				{
       
   897 				*bufferPtr++ = ReadRgbNormal(aX,aY);
       
   898 				aX += xInc; aY += yInc;
       
   899 				}
       
   900 			}
       
   901 			break;
       
   902 		case EColor16MU:
       
   903 			{
       
   904 			TUint32* bufferPtr = (TUint32*)aBuffer;
       
   905 			const TUint32* bufferPtrLimit = bufferPtr + aLength;
       
   906 
       
   907 			while (bufferPtr < bufferPtrLimit)
       
   908 				{
       
   909 				*bufferPtr++ = ReadRgbNormal(aX,aY)._Color16MU();//BGRA (Blue/Green/Red/Alpha) as little endian bite order
       
   910 				aX += xInc; aY += yInc;
       
   911 				}
       
   912 			}
       
   913 			break;
       
   914 		case EColor16MA:
       
   915 			{
       
   916 			TUint32* bufferPtr = (TUint32*)aBuffer;
       
   917 			const TUint32* bufferPtrLimit = bufferPtr + aLength;
       
   918 
       
   919 			while (bufferPtr < bufferPtrLimit)
       
   920 				{
       
   921 				*bufferPtr++ = ReadRgbNormal(aX,aY)._Color16MA();//BGRA (Blue/Green/Red/Alpha) as little endian bite order
       
   922 				aX += xInc; aY += yInc;
       
   923 				}
       
   924 			}
       
   925 			break;
       
   926 		case EColor16MAP:
       
   927 			{
       
   928 			TUint32* bufferPtr = (TUint32*)aBuffer;
       
   929 			const TUint32* bufferPtrLimit = bufferPtr + aLength;
       
   930 
       
   931 			while (bufferPtr < bufferPtrLimit)
       
   932 				{
       
   933 				*bufferPtr++ = ReadRgbNormal(aX,aY)._Color16MAP();;
       
   934 				aX += xInc; aY += yInc;
       
   935 				}
       
   936 			}
       
   937 			break;
       
   938 		default:
       
   939 			Panic(EScreenDriverPanicInvalidDisplayMode);
       
   940 		}
       
   941 	}
       
   942 
       
   943 //aX, aY - logical coordinates
       
   944 void CDrawBitmap::WriteRgb(TInt aX,TInt aY,TRgb aColor,CGraphicsContext::TDrawMode aDrawMode)
       
   945 	{
       
   946 	register TInt width = -1;
       
   947 	register TInt height = -1;
       
   948 	PreWriteRgb(width, height, aX, aY, aDrawMode);
       
   949 	WriteRgb(width, height, aX, aY, aColor, aDrawMode);
       
   950 	}
       
   951 
       
   952 //aX, aY - logical coordinates
       
   953 void CDrawBitmap::WriteRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aHeight,
       
   954 								TRgb aColor,CGraphicsContext::TDrawMode aDrawMode)
       
   955 	{
       
   956 	const TRect rect = DeOrientate(TRect(aX,aY,aX + aLength,aY + aHeight));//rect - physical coordinates
       
   957 	aX = rect.iTl.iX;
       
   958 	aY = rect.iTl.iY;
       
   959 	aLength = rect.Width();
       
   960 	aHeight = rect.Height();
       
   961 
       
   962 	__ASSERT_DEBUG(aX>=0 && aX+aLength<=iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds));
       
   963 	__ASSERT_DEBUG(aY>=0 && aY+aHeight<=iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds));
       
   964 
       
   965 	MapColorToUserDisplayMode(aColor);
       
   966 	if(iShadowMode)
       
   967 		{
       
   968 		Shadow(aColor);
       
   969 		}
       
   970 	if(aDrawMode&CGraphicsContext::EInvertPen)
       
   971 		{
       
   972 		aColor=~aColor;
       
   973 		}
       
   974 	if(aDrawMode&CGraphicsContext::EPenmode)
       
   975 		{
       
   976 		BlendRgbMulti(aX,aY,aLength,aHeight,aColor);
       
   977 		return;
       
   978 		}
       
   979 	if(aDrawMode&CGraphicsContext::EWriteAlpha)
       
   980 		{
       
   981 		WriteRgbMulti(aX,aY,aLength,aHeight,aColor);
       
   982 		return;
       
   983 		}
       
   984 	if(aDrawMode&CGraphicsContext::EInvertScreen)
       
   985 		{
       
   986 		WriteRgbMultiXOR(aX,aY,aLength,aHeight,KRgbWhite);
       
   987 		}
       
   988 	if(aDrawMode&CGraphicsContext::EXor)
       
   989 		{
       
   990 		WriteRgbMultiXOR(aX,aY,aLength,aHeight,aColor);
       
   991 		}
       
   992 	else if(aDrawMode&CGraphicsContext::EAnd)
       
   993 		{
       
   994 		WriteRgbMultiAND(aX,aY,aLength,aHeight,aColor);
       
   995 		}
       
   996 	else if(aDrawMode&CGraphicsContext::EOr)
       
   997 		{
       
   998 		WriteRgbMultiOR(aX,aY,aLength,aHeight,aColor);
       
   999 		}
       
  1000 	}
       
  1001 
       
  1002 //aX, aY - logical coordinates
       
  1003 void CDrawBitmap::WriteBinary(TInt aX,TInt aY,TUint32* aBuffer,TInt aLength,
       
  1004 							  TInt aHeight,TRgb aColor,CGraphicsContext::TDrawMode aDrawMode)
       
  1005 	{
       
  1006 	TRect drawRect;
       
  1007 	GetDrawRect(drawRect);
       
  1008 	__ASSERT_DEBUG(aX >= drawRect.iTl.iX && (aX + aLength) <= drawRect.iBr.iX, Panic(EScreenDriverPanicOutOfBounds));
       
  1009 	__ASSERT_DEBUG(aY >= drawRect.iTl.iY && (aY + aHeight) <= drawRect.iBr.iY, Panic(EScreenDriverPanicOutOfBounds));
       
  1010 	__ASSERT_DEBUG(aBuffer, Panic(EScreenDriverPanicNullPointer));
       
  1011 	__ASSERT_DEBUG(aLength > 0, Panic(EScreenDriverPanicZeroLength));
       
  1012 	__ASSERT_DEBUG(aLength <= 32, Panic(EScreenDriverPanicOutOfBounds));
       
  1013 
       
  1014 	MapColorToUserDisplayMode(aColor);
       
  1015 	if(iShadowMode)
       
  1016 		Shadow(aColor);
       
  1017 	if(aDrawMode&CGraphicsContext::EInvertPen)
       
  1018 		aColor=~aColor;
       
  1019 	if(aDrawMode&CGraphicsContext::EPenmode)
       
  1020 		{
       
  1021 		WriteBinary(aX,aY,aBuffer,aLength,aHeight,aColor);
       
  1022 		return;
       
  1023 		}
       
  1024 	if(aDrawMode&CGraphicsContext::EInvertScreen)
       
  1025 		WriteBinaryOp(aX,aY,aBuffer,aLength,aHeight,KRgbWhite,CGraphicsContext::EDrawModeXOR);
       
  1026 	if(aDrawMode&CGraphicsContext::ELogicalOp)
       
  1027 		WriteBinaryOp(aX,aY,aBuffer,aLength,aHeight,aColor,(CGraphicsContext::TDrawMode)(aDrawMode&CGraphicsContext::ELogicalOp));
       
  1028 	}
       
  1029 
       
  1030 //aX, aY - logical coordinates
       
  1031 void CDrawBitmap::WriteBinaryLine(TInt aX,TInt aY,TUint32* aBuffer,
       
  1032 								  TInt aLength,TRgb aColor,
       
  1033 								  CGraphicsContext::TDrawMode aDrawMode)
       
  1034 	{
       
  1035 	MapColorToUserDisplayMode(aColor);
       
  1036 	while(aLength>32)
       
  1037 		{
       
  1038 		WriteBinary(aX,aY,aBuffer,32,1,aColor,aDrawMode);
       
  1039 		aX+=32;
       
  1040 		aBuffer++;
       
  1041 		aLength-=32;
       
  1042 		}
       
  1043 	WriteBinary(aX,aY,aBuffer,aLength,1,aColor,aDrawMode);
       
  1044 	}
       
  1045 
       
  1046 //aX, aY - logical coordinates
       
  1047 void CDrawBitmap::WriteBinaryLineVertical(TInt aX,TInt aY,TUint32* aBuffer,
       
  1048 										  TInt aHeight,TRgb aColor,
       
  1049 										  CGraphicsContext::TDrawMode aDrawMode,TBool aUp)
       
  1050 	{
       
  1051 	TRect drawRect;
       
  1052 	GetDrawRect(drawRect);
       
  1053 	__ASSERT_DEBUG(aX >= drawRect.iTl.iX && aX < drawRect.iBr.iX, Panic(EScreenDriverPanicOutOfBounds));
       
  1054 	__ASSERT_DEBUG(aY >= drawRect.iTl.iY, Panic(EScreenDriverPanicOutOfBounds));
       
  1055 	__ASSERT_DEBUG(aUp || (aY + aHeight) <= drawRect.iBr.iY, Panic(EScreenDriverPanicOutOfBounds));
       
  1056 	__ASSERT_DEBUG(!aUp || (aY - aHeight + 1) >= drawRect.iTl.iY, Panic(EScreenDriverPanicOutOfBounds));
       
  1057 	__ASSERT_DEBUG(aBuffer, Panic(EScreenDriverPanicNullPointer));
       
  1058 	__ASSERT_DEBUG(aHeight > 0, Panic(EScreenDriverPanicZeroLength));
       
  1059 
       
  1060 	MapColorToUserDisplayMode(aColor);
       
  1061 	if((aDrawMode & CGraphicsContext::EPenmode) && iScalingOff)
       
  1062 		{
       
  1063 		if(iShadowMode)
       
  1064 			Shadow(aColor);
       
  1065 		if(aDrawMode&CGraphicsContext::EInvertPen)
       
  1066 			aColor=~aColor;
       
  1067 		WriteBinaryLineVertical(aX,aY,aBuffer,aHeight,aColor,aUp);
       
  1068 		return;
       
  1069 		}
       
  1070 
       
  1071 	TUint32 mask = 1;
       
  1072 	TUint32 data = *aBuffer++;
       
  1073 	TInt endrow = aY + (aUp ? -aHeight : aHeight);
       
  1074 	TInt rowInc = aUp ? -1 : 1;
       
  1075 
       
  1076 	while (aY != endrow)
       
  1077 		{
       
  1078 		if (!mask)
       
  1079 			{
       
  1080 			data = *aBuffer++;
       
  1081 			mask = 1;
       
  1082 			}
       
  1083 
       
  1084 		if (data & mask)
       
  1085 			{
       
  1086 			WriteRgb(aX, aY, aColor, aDrawMode);
       
  1087 			}
       
  1088 
       
  1089 		aY += rowInc;
       
  1090 		mask <<= 1;
       
  1091 		}
       
  1092 	}
       
  1093 
       
  1094 //aX, aY - logical coordinates
       
  1095 void CDrawBitmap::WriteLine(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer,
       
  1096 							CGraphicsContext::TDrawMode aDrawMode)
       
  1097 	{
       
  1098 	const TPoint originalPoint(aX,aY);
       
  1099 	DeOrientate(aX,aY);//aX and aY - physical coordinates
       
  1100 
       
  1101 	__ASSERT_DEBUG(aX >= 0,Panic(EScreenDriverPanicOutOfBounds));
       
  1102 	__ASSERT_DEBUG(aY >= 0,Panic(EScreenDriverPanicOutOfBounds));
       
  1103 #if defined(_DEBUG)
       
  1104 	switch (iOrientation)
       
  1105 		{
       
  1106 	case EOrientationNormal:
       
  1107 		__ASSERT_DEBUG(aX + aLength <= iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds));
       
  1108 		break;
       
  1109 	case EOrientationRotated90:
       
  1110 		__ASSERT_DEBUG(aY + aLength <= iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds));
       
  1111 		break;
       
  1112 	case EOrientationRotated180:
       
  1113 		__ASSERT_DEBUG(aX - aLength >= -1,Panic(EScreenDriverPanicOutOfBounds));
       
  1114 		break;
       
  1115 	default: // EOrientationRotated270
       
  1116 		__ASSERT_DEBUG(aY - aLength >= -1,Panic(EScreenDriverPanicOutOfBounds));
       
  1117 		break;
       
  1118 		}
       
  1119 #endif
       
  1120 	__ASSERT_DEBUG(aLength > 0,Panic(EScreenDriverPanicZeroLength));
       
  1121 	__ASSERT_DEBUG(aBuffer,Panic(EScreenDriverPanicNullPointer));
       
  1122 
       
  1123 	MapBufferToUserDisplayMode(aLength,aBuffer);
       
  1124 	if(iShadowMode)
       
  1125 		{
       
  1126 		ShadowBuffer(aLength,aBuffer);
       
  1127 		}
       
  1128 	if(aDrawMode&CGraphicsContext::EInvertPen)
       
  1129 		{
       
  1130 		InvertBuffer(aLength,aBuffer);
       
  1131 		}
       
  1132 	if(aDrawMode&CGraphicsContext::EPenmode)
       
  1133 		{
       
  1134 		BlendLine(aX,aY,aLength,aBuffer);
       
  1135 		return;
       
  1136 		}
       
  1137 	if(aDrawMode&CGraphicsContext::EWriteAlpha)
       
  1138 		{
       
  1139 		WriteLine(aX,aY,aLength,aBuffer);
       
  1140 		return;
       
  1141 		}
       
  1142 	if(aDrawMode&CGraphicsContext::EInvertScreen)
       
  1143 		{
       
  1144 		const TRect rect = DeOrientate(TRect(originalPoint,TSize(aLength,1)));//"rect" - deorientated and scaled
       
  1145 		WriteRgbMultiXOR(rect.iTl.iX,rect.iTl.iY,rect.Width(),rect.Height(),KRgbWhite);
       
  1146 		}
       
  1147 	if(aDrawMode&CGraphicsContext::EXor)
       
  1148 		{
       
  1149 		WriteLineXOR(aX,aY,aLength,aBuffer);
       
  1150 		}
       
  1151 	else if(aDrawMode&CGraphicsContext::EAnd)
       
  1152 		{
       
  1153 		WriteLineAND(aX,aY,aLength,aBuffer);
       
  1154 		}
       
  1155 	else if(aDrawMode&CGraphicsContext::EOr)
       
  1156 		{
       
  1157 		WriteLineOR(aX,aY,aLength,aBuffer);
       
  1158 		}
       
  1159 	}
       
  1160 
       
  1161 TAny* CDrawBitmap::CopyOffset(TAny* aDestination,const TAny* aSource,TInt aWordsToCopy,TInt aSourceBitOffset)
       
  1162 	{
       
  1163 	ASSERT(aSourceBitOffset > 0 && aSourceBitOffset < 32);
       
  1164 
       
  1165 	const TUint32* srcPtr = REINTERPRET_CAST(const TUint32*,aSource);
       
  1166 	TUint32* destPtr = REINTERPRET_CAST(TUint32*,aDestination);
       
  1167 	const TUint32* destPtrLimit = destPtr + aWordsToCopy;
       
  1168 	const TInt sourceBitOffsetComplement = 32 - aSourceBitOffset;
       
  1169 
       
  1170 	TUint32 sourceValue = *srcPtr++;
       
  1171 
       
  1172 	while (destPtr < destPtrLimit)
       
  1173 		{
       
  1174 		TUint32 destValue = sourceValue >> aSourceBitOffset;
       
  1175 		sourceValue = *srcPtr++;
       
  1176 		destValue |= sourceValue << sourceBitOffsetComplement;
       
  1177 		*destPtr++ = destValue;
       
  1178 		}
       
  1179 	return destPtr;
       
  1180 	}
       
  1181 /**	Common code to read a line of pixels where there are >1 pixels per byte.
       
  1182   	The source words must be shifted to fit the target buffer.
       
  1183 @param 	aPixelPtr 	Source location to start copying from (word aligned, last word is safe)
       
  1184 @param	aBufferPtr	Target location to write to (word aligned - may or may not own all last word)
       
  1185 @param	aWordsCnt	Number of source words that can be safely copied
       
  1186 @param	aRestPixels	Number of pixels that must be read from the next word for the final byte copy
       
  1187 @param	aBytesCount	Number of bytes to write from final input word
       
  1188 @param	aShiftBits	Number of bits shifted between input and output words.
       
  1189  **/
       
  1190 void CDrawBitmap::ReadLineCommon(TUint32* aPixelPtr,TUint32* aBufferPtr,TInt aWordsCount,TInt aRestPixels,TInt aBytesCount,TInt aShiftBits)
       
  1191 	{
       
  1192 // 	As many pixels as possible are copied by shifting whole words.
       
  1193 // 	This involves reading two source words, shifting them, 
       
  1194 // 	and merging the result to one target word.
       
  1195 //  	However, two cases mean the last few pixels need to be treated carefully:
       
  1196 //  	1) The target buffer may be a number of bytes, not whole words.
       
  1197 //			The number of pixels to copy defines the number of bytes to copy.
       
  1198 //  	2) The number of pixels to read may mean the last read does not need 
       
  1199 //  	   	to read a second word in order to satisfy the number of pixels requested.
       
  1200 //  	   	This next word may not be mapped, so must not be read!
       
  1201 
       
  1202 	//Are we willing to pay for these asserts for every scanline copy, even in debug?
       
  1203 	__ASSERT_DEBUG(aPixelPtr, User::Invariant());
       
  1204 	__ASSERT_DEBUG(aBufferPtr, User::Invariant());
       
  1205 	__ASSERT_DEBUG(aWordsCount>=0, User::Invariant());
       
  1206 	__ASSERT_DEBUG(aBytesCount<5, User::Invariant());
       
  1207 	__ASSERT_DEBUG(aShiftBits>=0 && aShiftBits<33, User::Invariant());
       
  1208 	
       
  1209 	TUint32 nextpixel;
       
  1210 	if(aWordsCount>0)	
       
  1211 		{
       
  1212 		if (aShiftBits==0)
       
  1213 			{
       
  1214 			while (aWordsCount--)
       
  1215 				{
       
  1216 				*aBufferPtr++ = *aPixelPtr++;
       
  1217 				}
       
  1218 			if (aBytesCount>0)	//I hope the optimiser can concatenate these two tests?
       
  1219 				{
       
  1220 				nextpixel=aPixelPtr[0];
       
  1221 				}
       
  1222 			}
       
  1223 		else
       
  1224 			{
       
  1225 			const TInt shiftBitsExtra = 32 - aShiftBits;
       
  1226 			nextpixel=aPixelPtr[0]; 
       
  1227 			while (aWordsCount--)
       
  1228 				{
       
  1229 				TUint32 prevpixel=nextpixel;
       
  1230 				nextpixel=aPixelPtr[1];	//this must not read forward when it doesn't need to
       
  1231 				aBufferPtr[0] = (prevpixel >> aShiftBits) | (nextpixel << shiftBitsExtra);
       
  1232 
       
  1233 				aPixelPtr++;
       
  1234 				aBufferPtr++;
       
  1235 				}
       
  1236 			}
       
  1237 		}
       
  1238 	else
       
  1239 		{
       
  1240 		nextpixel=aPixelPtr[0];
       
  1241 		}
       
  1242 	
       
  1243 	//deal with the trailing bytes
       
  1244 	if (aBytesCount>0)
       
  1245 		{
       
  1246 		if (aBytesCount==4)
       
  1247 			{
       
  1248 			//The client only requests 4 bytes rather than 1 more word when the requested pixels
       
  1249 			//mean the second word should not be read from.
       
  1250 			//Can also write the result in a single operation!
       
  1251 			aBufferPtr[0]=nextpixel>> aShiftBits;
       
  1252 			}
       
  1253 		else
       
  1254 			{
       
  1255 			if (aRestPixels>0)
       
  1256 				{	
       
  1257 				//do need to read from next word to fill all the requested pixels.
       
  1258 				aWordsCount=(nextpixel >> aShiftBits) | (aPixelPtr[1] << (32 - aShiftBits));
       
  1259 				}
       
  1260 			else
       
  1261 				{	
       
  1262 				//Don't read second word, otherwise might read past end of picture data!
       
  1263 				aWordsCount=(nextpixel >> aShiftBits);	
       
  1264 				}
       
  1265 			TUint8*	bufferPtrChar=reinterpret_cast <TUint8*> (aBufferPtr);
       
  1266 
       
  1267 			//max 3 bytes to store
       
  1268 			if (aBytesCount&2)
       
  1269 				{
       
  1270 				bufferPtrChar[0]=aWordsCount;
       
  1271 				bufferPtrChar[1]=aWordsCount>>8;
       
  1272 				bufferPtrChar+=2;
       
  1273 				aWordsCount>>=16;
       
  1274 				}
       
  1275 			if (aBytesCount&1)
       
  1276 				{
       
  1277 				bufferPtrChar[0]=aWordsCount;
       
  1278 				}
       
  1279 			}
       
  1280 		}
       
  1281 	}
       
  1282 
       
  1283 /**
       
  1284 The method performs an alpha blending of the source data - aRgbBuffer and screen pixels, using
       
  1285 the data from aMaskBuffer buffer as an alpha blending factor.
       
  1286 If the shadowing/fading flag is set, a shadow/fade copy of the source bitmap will be used.
       
  1287 The formula used for that, is:
       
  1288 (C1 * A + C2 * (255 - A)) / 255, where:
       
  1289 - C1 - a pixel from aRgbBuffer;
       
  1290 - C2 - a pixel from the sceen;
       
  1291 - A  - a pixel from aMaskBuffer;
       
  1292 The content of source and mask buffers is preserved.
       
  1293 The calculated alpha blended pixel is written to the destination - the screen or a bitmap.
       
  1294 @param aX Logical X coordinate of the position in the target the result should be drawn to.
       
  1295 @param aY Logical Y coordinate of the position in the target the result should be drawn to.
       
  1296 @param aLength Source data - length in pixels.
       
  1297 @param aRgbBuffer A pointer to a line of the source bitmap data.
       
  1298 @param aMaskBuffer Buffer containing the data which should be used as an
       
  1299                    alpha blending factor.
       
  1300 */
       
  1301 void CDrawBitmap::WriteRgbAlphaLine(TInt aX, TInt aY, TInt aLength,
       
  1302                                     TUint8* aRgbBuffer, TUint8* aMaskBuffer,
       
  1303                                     CGraphicsContext::TDrawMode aDrawMode)
       
  1304 	{
       
  1305 	iAlphaBlend->WriteRgbAlphaLine(aX, aY, aLength, aRgbBuffer, aMaskBuffer,
       
  1306                                    MAlphaBlend::EShdwBefore,
       
  1307                                    aDrawMode);
       
  1308 	}
       
  1309 
       
  1310 /**
       
  1311 The method performs an alpha blending of the source data - aRgbBuffer1 and aBuffer2, using
       
  1312 the data from aMaskBuffer buffer as an alpha blending factor.
       
  1313 If the shadowing/fading flag is set, the resulting pixels will be shadowed/faded.
       
  1314 The formula used for that, is:
       
  1315 (C1 * A + C2 * (255 - A)) / 255, where:
       
  1316 - C1 - a pixel from aRgbBuffer1;
       
  1317 - C2 - a pixel from aBuffer2;
       
  1318 - A  - a pixel from aMaskBuffer;
       
  1319 The content of source and mask buffers is preserved.
       
  1320 The calculated alpha blended pixel is written to the destination - the screen or a bitmap.
       
  1321 @param aX Logical X coordinate of the position in the target the result should be drawn to.
       
  1322 @param aY Logical Y coordinate of the position in the target the result should be drawn to.
       
  1323 @param aLength Source data - length in pixels.
       
  1324 @param aRgbBuffer1 A pointer to a line of the source bitmap data 1.
       
  1325 @param aBuffer2 A pointer to a line of the source bitmap data 2.
       
  1326                 Source bitmap data 2 should be mapped to current display mode
       
  1327 				before the method call.
       
  1328 @param aMaskBuffer Buffer containing the data which should be used as an
       
  1329                    alpha blending factor.
       
  1330 @param aDrawMode Drawing mode
       
  1331 */
       
  1332 void CDrawBitmap::WriteRgbAlphaLine(TInt aX,TInt aY,TInt aLength,
       
  1333 									const TUint8* aRgbBuffer1,
       
  1334 									const TUint8* aBuffer2,
       
  1335 									const TUint8* aMaskBuffer,
       
  1336 									CGraphicsContext::TDrawMode aDrawMode)
       
  1337 	{
       
  1338 	// Save current shadow mode
       
  1339 	TShadowMode temp_mode = iShadowMode;
       
  1340 	iShadowMode = ENoShadow;
       
  1341 	// copy the source data 2 to the screen/bitmap target buffer
       
  1342 	WriteLine(aX, aY, aLength, (TUint32*)aBuffer2, aDrawMode);
       
  1343 	// restore current shadow mode
       
  1344 	iShadowMode = temp_mode;
       
  1345 	// DrawModePen is the only supported operation for blending masks. 
       
  1346 	iAlphaBlend->WriteRgbAlphaLine(aX, aY, aLength, aRgbBuffer1, aMaskBuffer,
       
  1347                                    MAlphaBlend::EShdwAfter, CGraphicsContext::EDrawModePEN);
       
  1348 	}
       
  1349 
       
  1350 //Initializes iSize and iDrawRect data members.
       
  1351 //It should be called every time when iSize is going to be changed - Construct() implementations
       
  1352 //in derived classes.
       
  1353 //The method does not use iOrientation data member.
       
  1354 //@param aSize Physical screen size in pixels.
       
  1355 //@panic EScreenDriverPanicInvalidSize - Invalid aSize parameter. This might happen if the
       
  1356 //device is scaled and the scaling origin goes outside physical drawing rectangle.
       
  1357 void CDrawBitmap::SetSize(const TSize& aSize)
       
  1358 	{
       
  1359 	iSize = aSize;
       
  1360 	InitLogicalCoordinates();
       
  1361 	}
       
  1362 
       
  1363 /**
       
  1364 The method swaps bitmap device's width and height.
       
  1365 For example: if the size is (40, 20), the swapped size will be (20, 40).
       
  1366 The device's content is not preserved.
       
  1367 The method leaves CDrawBitmap object in a consistent state -
       
  1368 scaling settings will be set with their default values (the scaling is switched off),
       
  1369 iDitherOrigin will be set to (0,0), iOrigin to (0,0).
       
  1370 
       
  1371 Note: This method is used internally by BITGDI component. Do not call it!
       
  1372 */
       
  1373 void CDrawBitmap::SwapWidthAndHeight()
       
  1374 	{
       
  1375 	SetDefaults();
       
  1376 	//Swap width and height
       
  1377 	TSize swappedSize(iSize.iHeight, iSize.iWidth);
       
  1378 	//Initialize iSize, iScanLineWords, iLongWidth data members.
       
  1379 	SetSize(swappedSize);
       
  1380 	}
       
  1381 
       
  1382 //This method initializes some of the data members.
       
  1383 //Espetially it switches scaling off, sets iDitherOrigin to (0,0),
       
  1384 //iOrigin to (0,0), iDrawRect to (0,0,0,0). iSize value is preserved.
       
  1385 //Do not forget to update it if adding new data members!
       
  1386 void CDrawBitmap::SetDefaults()
       
  1387 	{
       
  1388 	iLongWidth = 0;
       
  1389 	iDitherOrigin.SetXY(0, 0);
       
  1390 	iFadeMapFactor = 128;
       
  1391 	iFadeMapOffset = 128;
       
  1392 	iScalingSettings = TScalingSettings();
       
  1393 	iOrigin.SetXY(0, 0);
       
  1394 	iScalingOff = ETrue;
       
  1395 	iOriginIsZero = ETrue;
       
  1396 	iDrawRect.SetRect(0, 0, 0, 0);
       
  1397 	}
       
  1398 
       
  1399 /**
       
  1400 Implementation for CFbsDrawDevice::GetInterface().
       
  1401 Retrieves a pointer to a specified interface of CFbsDrawDevice implementation.
       
  1402 @param aInterfaceId Interface identifier of the interface to be retrieved.
       
  1403 @param aInterface Address of variable that retrieves the specified interface.
       
  1404 @return KErrNone If the interface is supported, KErrNotSupported otherwise.
       
  1405 */
       
  1406 TInt CDrawBitmap::GetInterface(TInt aInterfaceId, TAny*& aInterface)
       
  1407 	{
       
  1408 	aInterface = NULL;
       
  1409 	TInt err = KErrNotSupported;
       
  1410 
       
  1411 	switch (aInterfaceId)
       
  1412 		{
       
  1413 		case KScalingSettingsInterfaceID:
       
  1414 			{
       
  1415 			if(CanBeScaled())
       
  1416 				{
       
  1417 				aInterface = static_cast <MScalingSettings*> (this);
       
  1418 				err = KErrNone;
       
  1419 				}
       
  1420 			break;
       
  1421 			}
       
  1422 		case KDrawDeviceOriginInterfaceID:
       
  1423 			{
       
  1424 			if(CanOriginBeMoved())
       
  1425 				{
       
  1426 				aInterface = static_cast <MDrawDeviceOrigin*> (this);
       
  1427 				err = KErrNone;
       
  1428 				}
       
  1429 			break;
       
  1430 			}
       
  1431 		case KAlphaBlendInterfaceID:
       
  1432 			{
       
  1433 			aInterface = static_cast <MAlphaBlend*> (this);
       
  1434 			err = KErrNone;
       
  1435 			break;
       
  1436 			}
       
  1437 		case KOrientationInterfaceID:
       
  1438 			{
       
  1439 			aInterface = static_cast <MDrawDeviceOrientation*> (this);
       
  1440 			err = KErrNone;    		
       
  1441 			break;
       
  1442 			}
       
  1443 		case KOutlineAndShadowInterfaceID:
       
  1444 			{
       
  1445 			aInterface = static_cast <MOutlineAndShadowBlend*> (this);
       
  1446 			err = KErrNone;    		
       
  1447 			break;
       
  1448 			}
       
  1449 		case KFastBlendInterfaceID:
       
  1450 			{
       
  1451 			aInterface = static_cast <MFastBlend*> (this);
       
  1452 			err = KErrNone;
       
  1453 			break;
       
  1454 			}
       
  1455 		}
       
  1456 	
       
  1457 	return err;
       
  1458 	}
       
  1459 
       
  1460 void CDrawBitmap::BlendRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
       
  1461 	{
       
  1462 	WriteRgbMulti(aX,aY,aLength,aHeight,aColor);
       
  1463 	}
       
  1464 
       
  1465 void CDrawBitmap::BlendLine(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
       
  1466 	{
       
  1467 	WriteLine(aX, aY,aLength, aBuffer);
       
  1468 	}
       
  1469 
       
  1470 /**
       
  1471 Convert a RGB pixel into the color associated to the user display mode.
       
  1472 @param aRed red color
       
  1473 @param aGreen green color
       
  1474 @param aBlue blue color
       
  1475 @internalComponent
       
  1476 */
       
  1477 void CDrawBitmap::MapColorToUserDisplayMode(TInt& aRed,TInt& aGreen,TInt& aBlue)
       
  1478 	{
       
  1479 	TUint32 tmpValue;
       
  1480 		
       
  1481 	switch (iUserDispMode)
       
  1482 		{
       
  1483 		case EGray2:
       
  1484 			tmpValue = ((aRed<<1) + aGreen + (aGreen<<2) + aBlue) >> 10;
       
  1485 			if (tmpValue) 	{ aRed = 0xff; aBlue = 0xff; aGreen = 0xff; }
       
  1486 			else			{ aRed = 0x00; aBlue = 0x00; aGreen = 0x00; }
       
  1487 			break;
       
  1488 		case EGray4:
       
  1489 			tmpValue = ((aRed<<1) + aGreen + (aGreen<<2) + aBlue) >> 9;
       
  1490 			tmpValue = tmpValue | (tmpValue << 2) | (tmpValue << 4) | (tmpValue << 6);
       
  1491 			aRed = tmpValue; aGreen = tmpValue; aBlue = tmpValue;
       
  1492 			break;
       
  1493 		case EGray16:
       
  1494 			tmpValue = ((aRed<<1) + aGreen + (aGreen<<2) + aBlue) >> 7;
       
  1495 			tmpValue = tmpValue | (tmpValue << 4);
       
  1496 			aRed = tmpValue; aGreen = tmpValue; aBlue = tmpValue;
       
  1497 			break;
       
  1498 	  	case EGray256:
       
  1499 			tmpValue = ((aRed<<1) + aGreen + (aGreen<<2) + aBlue) >> 3;
       
  1500 	  		aRed = tmpValue; aGreen = tmpValue; aBlue = tmpValue;
       
  1501 	  		break;
       
  1502 	  	case EColor16:
       
  1503 	  		{
       
  1504 	  		TRgb aColor(aRed,aGreen,aBlue);
       
  1505 	  		aColor = TRgb::Color16(aColor.Color16());
       
  1506 	  		aRed = aColor.Red(); aGreen = aColor.Green(); aBlue = aColor.Blue();
       
  1507 	  		break;  		
       
  1508 	  		}
       
  1509 	  	case EColor256:
       
  1510 	  		{
       
  1511 	  		TRgb aColor2(aRed,aGreen,aBlue);
       
  1512 	  		aColor2 = TRgb::Color256(aColor2.Color256());
       
  1513 	  		aRed = aColor2.Red(); aGreen = aColor2.Green(); aBlue = aColor2.Blue();
       
  1514 	  		break;
       
  1515 	  		}
       
  1516 	  	case EColor4K:
       
  1517 	  		aBlue = aBlue  & 0xf0; 	aBlue |= (aBlue >> 4);
       
  1518 	  		aGreen = aGreen  & 0xf0;	aGreen |= (aGreen >> 4);
       
  1519 	  		aRed = aRed  & 0xf0; 		aRed |= (aRed >> 4);
       
  1520 	  		break;
       
  1521 	  	case EColor64K:
       
  1522 	  		aBlue = aBlue  & 0xf8;	aBlue += (aBlue >> 5);
       
  1523 	  		aGreen = aGreen  & 0xfc;	aGreen += (aGreen >> 6);
       
  1524 	  		aRed = aRed  & 0xf8;		aRed += (aRed >> 5);
       
  1525 	  		break;
       
  1526 	  	default:
       
  1527 	  		break;
       
  1528   		}
       
  1529 	}
       
  1530 
       
  1531 /**
       
  1532 CDrawBitmap::Orientation() implementation.
       
  1533 @internalTechnology
       
  1534 @see MDrawDeviceOrientation::Orientation()
       
  1535 */
       
  1536 CFbsDrawDevice::TOrientation CDrawBitmap::Orientation()
       
  1537 	{
       
  1538 	return iOrientation;
       
  1539 	}
       
  1540 
       
  1541 #ifdef __ARMCC__
       
  1542 #ifndef __MARM_THUMB__
       
  1543 #define USE_SCREENDRIVER_ARM_ASM
       
  1544 #endif //__MARM_THUMB__
       
  1545 #endif //__ARMCC__
       
  1546 
       
  1547 #ifdef USE_SCREENDRIVER_ARM_ASM
       
  1548 /**
       
  1549 MemFill - using an unrolled loop to perform the following:
       
  1550 	for (TUint32* tempWordPtr = wordPtr; tempWordPtr < wordPtrLimit; tempWordPtr++)
       
  1551 		{
       
  1552 		*tempWordPtr = colorWord;
       
  1553 		}
       
  1554 */
       
  1555 __asm void MemFillTUint32(TUint32* /*aTrg*/, TInt /*aLength*/, const TUint32 /*aValue*/)
       
  1556 	{
       
  1557 	//r0 - aTrg, r1 - aLength, r2 - aValue
       
  1558 	push     {r1,r3,lr}
       
  1559 	and      r3,r1,#7
       
  1560 	cmp      r3,#7
       
  1561 	addls    pc,pc,r3,LSL #2
       
  1562 	b        mf_switch0
       
  1563 	b        mf_switch0
       
  1564 	b        mf_switch1
       
  1565 	b        mf_switch2
       
  1566 	b        mf_switch3
       
  1567 	b        mf_switch4
       
  1568 	b        mf_switch5
       
  1569 	b        mf_switch6
       
  1570 	b        mf_switch7
       
  1571 mf_switch7
       
  1572 	str      r2,[r0],#4
       
  1573 mf_switch6
       
  1574 	str      r2,[r0],#4
       
  1575 mf_switch5
       
  1576 	str      r2,[r0],#4
       
  1577 mf_switch4
       
  1578 	str      r2,[r0],#4
       
  1579 mf_switch3
       
  1580 	str      r2,[r0],#4
       
  1581 mf_switch2
       
  1582 	str      r2,[r0],#4
       
  1583 mf_switch1
       
  1584 	str      r2,[r0],#4
       
  1585 mf_switch0
       
  1586 
       
  1587 	asr      r1,r1,#3
       
  1588 	cmp      r1,#0
       
  1589 	beq      mf_complete
       
  1590 
       
  1591 	push     {r0,r2,r4-r8}
       
  1592 	mov      r3,r2
       
  1593 	mov      r4,r2
       
  1594     mov      r5,r2
       
  1595     mov      r6,r2
       
  1596 	mov      r7,r2
       
  1597 	mov      r8,r2
       
  1598 	mov      lr,r2
       
  1599 
       
  1600 mf_more
       
  1601 	stmia    r0!,{r2-r8,lr}
       
  1602 	subs     r1,r1,#1
       
  1603 	bgt      mf_more
       
  1604 	pop     {r0,r2,r4-r8}
       
  1605 
       
  1606 mf_complete
       
  1607 	pop     {r1,r3,pc}
       
  1608 	}
       
  1609 
       
  1610 #else //USE_SCREENDRIVER_ARM_ASM
       
  1611 
       
  1612 const TInt KDevideByEightShift = 3;
       
  1613 const TInt KModulusByEightFlag = 7;
       
  1614 
       
  1615 void MemFillTUint32(TUint32* tempWordPtr, TInt aCount,  const TUint32 aValue)
       
  1616 	{
       
  1617 	TInt remainder = aCount & KModulusByEightFlag;
       
  1618 	switch (remainder)
       
  1619 		{
       
  1620 	case 7:
       
  1621 		*tempWordPtr++ = aValue;
       
  1622 	case 6:
       
  1623 		*tempWordPtr++ = aValue;
       
  1624 	case 5:
       
  1625 		*tempWordPtr++ = aValue;
       
  1626 	case 4:
       
  1627 		*tempWordPtr++ = aValue;
       
  1628 	case 3:
       
  1629 		*tempWordPtr++ = aValue;
       
  1630 	case 2:
       
  1631 		*tempWordPtr++ = aValue;
       
  1632 	case 1:
       
  1633 		*tempWordPtr++ = aValue;
       
  1634 		}
       
  1635 	register TUint32 value0 = aValue;
       
  1636 	register TUint32 value1 = aValue;
       
  1637 	register TUint32 value2 = aValue;
       
  1638 	for(TInt times = (aCount >> KDevideByEightShift); times > 0; --times)
       
  1639 		{
       
  1640 		*tempWordPtr++ = value0;
       
  1641 		*tempWordPtr++ = value1;
       
  1642 		*tempWordPtr++ = value2;
       
  1643 		*tempWordPtr++ = aValue;
       
  1644 		*tempWordPtr++ = value0;
       
  1645 		*tempWordPtr++ = value1;
       
  1646 		*tempWordPtr++ = value2;
       
  1647 		*tempWordPtr++ = aValue;
       
  1648 		}
       
  1649 	}
       
  1650 
       
  1651 #endif //USE_SCREENDRIVER_ARM_ASM
       
  1652