os/graphics/graphicsdeviceinterface/screendriver/sbit/BMDRAW.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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