os/graphics/graphicsdeviceinterface/screendriver/sbit/BMDRAW24.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 
    18 //Initializes iSize, iDrawRect, iLongWidth, iScanLineBytes, iScanlineWords data members.
    19 //It should be called every time when iSize is going to be changed - from Construct().
    20 //@param aSize Physical screen size in pixels.
    21 //@panic EScreenDriverPanicInvalidSize - Invalid aSize parameter. This might happen if the 
    22 //device is scaled and the scaling origin goes outside physical drawing rectangle.
    23 void CDrawTwentyFourBppBitmap::SetSize(const TSize& aSize) 
    24 	{
    25 	CDrawBitmap::SetSize(aSize);
    26 	__ASSERT_DEBUG(iSize == aSize, User::Invariant());
    27 	iScanLineBytes = (((iSize.iWidth * 3) + 11) / 12) * 12;
    28 	iLongWidth = iScanLineBytes / 3;
    29 	iScanLineWords = iScanLineBytes / 4;
    30 	}
    31  
    32 TInt CDrawTwentyFourBppBitmap::Construct(TSize aSize)
    33 	{
    34 	return Construct(aSize, (((aSize.iWidth * 3) + 11) / 12) * 12);
    35 	}
    36 
    37 TInt CDrawTwentyFourBppBitmap::Construct(TSize aSize, TInt aStride)
    38 	{
    39 	iBits = NULL;
    40 	iDispMode = EColor16M;
    41 	CDrawBitmap::SetSize(aSize);
    42 	__ASSERT_DEBUG(iSize == aSize, User::Invariant());
    43 	if (aStride % 12)
    44 		return KErrArgument;
    45 	iScanLineBytes = aStride;
    46 	iLongWidth = aStride / 3;
    47 	if (iLongWidth < aSize.iWidth)
    48 		return KErrArgument;
    49 	iScanLineWords = aStride >> 2;
    50 	TInt size = (((Max(aSize.iWidth,aSize.iHeight) * 3) + 11) / 12) * 12;
    51 	if(size < 0)
    52 		return KErrArgument;
    53 	iScanLineBuffer = (TUint32*)(User::Heap().Alloc(size));
    54 	if (iScanLineBuffer == NULL)
    55 		return KErrNoMemory;
    56 	return KErrNone;
    57 	}
    58 
    59 inline TInt CDrawTwentyFourBppBitmap::PixelAddressIncrement() const
    60 	{
    61 	switch (iOrientation)
    62 		{
    63 		case EOrientationNormal:
    64 			return 3;
    65 		case EOrientationRotated90:
    66 			return iScanLineBytes;
    67 		case EOrientationRotated180:
    68 			return -3;
    69 		case EOrientationRotated270:
    70 			return -iScanLineBytes;
    71 		default:
    72 			return 1;
    73 		}
    74 	}
    75 
    76 inline void  CDrawTwentyFourBppBitmap::PixelAddressIncrement(TInt& aPixelInc,TInt& aRowInc) const
    77 	{
    78 	switch (iOrientation)
    79 		{
    80 		case EOrientationNormal:
    81 			aPixelInc = 3;
    82 			aRowInc = iScanLineBytes;
    83 			break;
    84 		case EOrientationRotated90:
    85 			aPixelInc = iScanLineBytes;
    86 			aRowInc = -3;
    87 			break;
    88 		case EOrientationRotated180:
    89 			aPixelInc = -3;
    90 			aRowInc = -iScanLineBytes;
    91 			break;
    92 		case EOrientationRotated270:
    93 			aPixelInc = -iScanLineBytes;
    94 			aRowInc = 3;
    95 			break;
    96 		default:
    97 			aPixelInc = 1;
    98 			aRowInc = 1;
    99 		}
   100 	}
   101 
   102 void CDrawTwentyFourBppBitmap::FadeRgb(TInt& red,TInt& green,TInt& blue)
   103 	{
   104   	blue = ((blue * iFadeMapFactor) >> 8)  + iFadeMapOffset;
   105   	green = ((green * iFadeMapFactor) >> 16) + iFadeMapOffset;
   106   	red = ((red * iFadeMapFactor) >> 8) + iFadeMapOffset; 
   107 	}
   108 
   109 void CDrawTwentyFourBppBitmap::Shadow(TRgb& aColor)
   110 	{
   111 	if (iShadowMode & EFade)
   112 		aColor = CDrawBitmap::FadeRgb(aColor);
   113 
   114 	if (iShadowMode & EShadow)
   115 		{
   116 		TInt r = ShadowComponentInl(aColor.Red());
   117 		TInt g = ShadowComponentInl(aColor.Green());
   118 		TInt b = ShadowComponentInl(aColor.Blue());
   119 		aColor = TRgb(r,g,b);
   120 		}
   121 	}
   122 
   123 void CDrawTwentyFourBppBitmap::Shadow(TInt& red,TInt& green,TInt& blue)
   124   	{
   125   	if (iShadowMode & EFade)
   126   		FadeRgb(red,green,blue);
   127    
   128   	if (iShadowMode & EShadow)
   129 		{
   130   		red = ShadowComponentInl(red);
   131   		green = ShadowComponentInl(green);
   132   		blue = ShadowComponentInl(blue);
   133   		}
   134 	}
   135 
   136 TUint8 CDrawTwentyFourBppBitmap::ShadowAndFade(TInt aComponent)
   137 	{
   138 	if (iShadowMode & EFade)
   139 		aComponent = FadeGray(aComponent);
   140 
   141 	if (iShadowMode & EShadow)
   142 		aComponent = ShadowComponentInl(aComponent);
   143 
   144 	return TUint8(aComponent);
   145 	}
   146 
   147 TUint8 CDrawTwentyFourBppBitmap::ShadowComponentInl(TInt aRgbComponent)
   148 	{
   149 	return TUint8(Max(0,aRgbComponent-0x40));
   150 	}
   151 
   152 TUint8 CDrawTwentyFourBppBitmap::ShadowComponent(TInt aRgbComponent)
   153 	{
   154 	return ShadowComponentInl(aRgbComponent);
   155 	}
   156 
   157 void CDrawTwentyFourBppBitmap::InvertBuffer(TInt aLength,TUint32* aBuffer)
   158 	{
   159 	__ASSERT_DEBUG(aLength>0,Panic(EScreenDriverPanicOutOfBounds));
   160 	__ASSERT_DEBUG(aBuffer,Panic(EScreenDriverPanicNullPointer));
   161 
   162 	TUint8* buffer = (TUint8*)aBuffer;
   163 	TUint8* limit = buffer + (aLength * 3);
   164 
   165 	while (buffer < limit)
   166 		*buffer++ ^= 0xff;
   167 	}
   168 
   169 void CDrawTwentyFourBppBitmap::ReadLine(TInt aX,TInt aY,TInt aLength,TAny* aBuffer) const
   170 	{
   171 	const TUint8* pixelPtr = PixelAddress(aX,aY);
   172 
   173 	if (iOrientation == EOrientationNormal)
   174 		Mem::Copy(aBuffer,pixelPtr,aLength * 3);
   175 	else
   176 		{
   177 		const TInt pixelPtrInc = PixelAddressIncrement();
   178 
   179 		TUint8* bufferPtr = STATIC_CAST(TUint8*,aBuffer);
   180 		const TUint8* bufferPtrLimit = bufferPtr + (aLength * 3);
   181 
   182 		while (bufferPtr < bufferPtrLimit)
   183 			{
   184 			*bufferPtr++ = pixelPtr[0];
   185 			*bufferPtr++ = pixelPtr[1];
   186 			*bufferPtr++ = pixelPtr[2];
   187 			pixelPtr += pixelPtrInc;
   188 			}
   189 		}
   190 	}
   191 
   192 TRgb CDrawTwentyFourBppBitmap::ReadRgbNormal(TInt aX,TInt aY) const
   193 	{
   194 	TUint8* pixelPtr = PixelAddress(aX,aY);
   195 	return TRgb(pixelPtr[2],pixelPtr[1],pixelPtr[0]);
   196 	}
   197 
   198 void CDrawTwentyFourBppBitmap::ShadowArea(const TRect& aRect)
   199 	{
   200 	const TRect rect(DeOrientate(aRect));
   201 
   202 	__ASSERT_DEBUG(rect.iTl.iX>=0 && rect.iBr.iX<=iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds));
   203 	__ASSERT_DEBUG(rect.iTl.iY>=0 && rect.iBr.iY<=iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds));
   204 
   205 	TUint8* pixelPtr = PixelAddress(rect.iTl.iX,rect.iTl.iY);
   206 	TUint8* pixelRowPtrLimit = pixelPtr + (rect.Height() * iScanLineBytes);
   207 
   208 	if (iShadowMode & EFade)
   209 		{
   210 		TUint8* pixelRowPtr = pixelPtr;
   211 		TUint8* pixelPtrLimit = pixelPtr + (rect.Width() * 3);
   212 
   213 		while (pixelRowPtr < pixelRowPtrLimit)
   214 			{
   215 			TUint8* tempPixelPtr = pixelRowPtr;
   216 
   217 			while (tempPixelPtr < pixelPtrLimit)
   218 				{
   219 				*tempPixelPtr = FadeGray(*tempPixelPtr);
   220 				++tempPixelPtr;
   221 				}
   222 
   223 			pixelRowPtr += iScanLineBytes;
   224 			pixelPtrLimit += iScanLineBytes;
   225 			}
   226 		}
   227 
   228 	if (iShadowMode & EShadow)
   229 		{
   230 		TUint8* pixelRowPtr = pixelPtr;
   231 		TUint8* pixelPtrLimit = pixelPtr + (rect.Width() * 3);
   232 
   233 		while (pixelRowPtr < pixelRowPtrLimit)
   234 			{
   235 			TUint8* tempPixelPtr = pixelRowPtr;
   236 
   237 			while (tempPixelPtr < pixelPtrLimit)
   238 				{
   239 				*tempPixelPtr = ShadowComponent(*tempPixelPtr);
   240 				++tempPixelPtr;
   241 				}
   242 
   243 			pixelRowPtr += iScanLineBytes;
   244 			pixelPtrLimit += iScanLineBytes;
   245 			}
   246 		}
   247 	}
   248 
   249 void CDrawTwentyFourBppBitmap::ShadowBuffer(TInt aLength,TUint32* aBuffer)
   250 	{
   251 	__ASSERT_DEBUG(aLength>0,Panic(EScreenDriverPanicZeroLength));
   252 	__ASSERT_DEBUG(aBuffer,Panic(EScreenDriverPanicNullPointer));
   253 
   254 	TUint8* limit = ((TUint8*)aBuffer) + (aLength * 3);
   255 
   256 	if (iShadowMode & EFade)
   257 		{
   258 		TUint8* buffer = (TUint8*)aBuffer;
   259 
   260 		while (buffer < limit)
   261 			{
   262 			*buffer = FadeGray(*buffer);
   263 			++buffer;
   264 			}
   265 		}
   266 
   267 	if (iShadowMode & EShadow)
   268 		{
   269 		TUint8* buffer = (TUint8*)aBuffer;
   270 
   271 		while (buffer < limit)
   272 			{
   273 			*buffer = ShadowComponent(*buffer);
   274 			++buffer;
   275 			}
   276 		}
   277 	}
   278 
   279 void CDrawTwentyFourBppBitmap::WriteRgb(TInt aX,TInt aY,TRgb aColor)
   280 	{
   281 	TUint8* pixelPtr = PixelAddress(aX,aY);
   282 	pixelPtr[0] = TUint8(aColor.Blue());
   283 	pixelPtr[1] = TUint8(aColor.Green());
   284 	pixelPtr[2] = TUint8(aColor.Red());
   285 	}
   286 
   287 void CDrawTwentyFourBppBitmap::WriteBinary(TInt aX,TInt aY,TUint32* aBuffer,TInt aLength,TInt aHeight,TRgb aColor)
   288 	{
   289 	DeOrientate(aX,aY);
   290 
   291 	TInt pixelInc;
   292 	TInt rowInc;
   293 
   294 	PixelAddressIncrement(pixelInc,rowInc);
   295 
   296 	const TUint32* dataLimit = aBuffer + aHeight;
   297 	const TUint32 dataMaskLimit = (aLength < 32) ? 1 << aLength : 0;
   298 
   299 	TUint8* pixelPtr = PixelAddress(aX,aY);
   300 
   301 	const TUint8 r = (TUint8)aColor.Red();
   302 	const TUint8 g = (TUint8)aColor.Green();
   303 	const TUint8 b = (TUint8)aColor.Blue();
   304 
   305 	while (aBuffer < dataLimit)
   306 		{
   307 		TUint32 dataWord = *aBuffer++;
   308 		TUint32 dataMask = 1;
   309 		TUint8* tempPixelPtr = pixelPtr;
   310 
   311 		while (dataMask != dataMaskLimit)
   312 			{
   313 			if(dataWord & dataMask)
   314 				{
   315 				tempPixelPtr[0] = b;
   316 				tempPixelPtr[1] = g;
   317 				tempPixelPtr[2] = r;
   318 				}
   319 
   320 			tempPixelPtr += pixelInc;
   321 			dataMask <<= 1;
   322 			}
   323 
   324 		pixelPtr += rowInc;
   325 		}
   326 	}
   327 
   328 void CDrawTwentyFourBppBitmap::WriteBinaryOp(TInt aX,TInt aY,TUint32* aBuffer,TInt aLength,TInt aHeight,TRgb aColor,CGraphicsContext::TDrawMode aDrawMode)
   329 	{
   330 	if (aLength <= 0)
   331 		return;
   332 
   333 	DeOrientate(aX,aY);
   334 	TUint8* pixelPtr = PixelAddress(aX,aY);
   335 
   336 	const TUint32* dataPtrLimit = aBuffer + aHeight;
   337 	const TUint32 dataMaskLimit = (aLength < 32) ? 1 << aLength : 0;
   338 
   339 	TInt pixelInc;
   340 	TInt rowInc;
   341 
   342 	PixelAddressIncrement(pixelInc,rowInc);
   343 
   344 	const TUint8 r = (TUint8)aColor.Red();
   345 	const TUint8 g = (TUint8)aColor.Green();
   346 	const TUint8 b = (TUint8)aColor.Blue();
   347 
   348 	if (r || g || b)
   349 		{
   350 		while (aBuffer < dataPtrLimit)
   351 			{
   352 			TUint32 dataWord = *aBuffer++;
   353 			TUint32 dataMask = 1;
   354 			TUint8* tempPixelPtr = pixelPtr;
   355 
   356 			while (dataMask != dataMaskLimit)
   357 				{
   358 				if(dataWord & dataMask)
   359 					{
   360 					switch (aDrawMode)
   361 						{
   362 						case CGraphicsContext::EDrawModeXOR:
   363 							tempPixelPtr[0] ^= b;
   364 							tempPixelPtr[1] ^= g;
   365 							tempPixelPtr[2] ^= r;
   366 							break;
   367 						case CGraphicsContext::EDrawModeAND:
   368 							tempPixelPtr[0] &= b;
   369 							tempPixelPtr[1] &= g;
   370 							tempPixelPtr[2] &= r;
   371 							break;
   372 						case CGraphicsContext::EDrawModeOR:
   373 							tempPixelPtr[0] |= b;
   374 							tempPixelPtr[1] |= g;
   375 							tempPixelPtr[2] |= r;
   376 							break;
   377 						default:
   378 							break;
   379 						}
   380 					}
   381 				tempPixelPtr += pixelInc;
   382 				dataMask <<= 1;
   383 				}
   384 
   385 			pixelPtr += rowInc;
   386 			}
   387 		}
   388 	else if (aDrawMode == CGraphicsContext::EDrawModeAND)
   389 		{
   390 		while (aBuffer < dataPtrLimit)
   391 			{
   392 			TUint32 dataWord = *aBuffer++;
   393 			TUint32 dataMask = 1;
   394 			TUint8* tempPixelPtr = pixelPtr;
   395 
   396 			while (dataMask != dataMaskLimit)
   397 				{
   398 				if(dataWord & dataMask)
   399 					{
   400 					tempPixelPtr[0] = 0;
   401 					tempPixelPtr[1] = 0;
   402 					tempPixelPtr[2] = 0;
   403 					}
   404 
   405 				tempPixelPtr += pixelInc;
   406 				dataMask <<= 1;
   407 				}
   408 
   409 			pixelPtr += rowInc;
   410 			}
   411 		}
   412 	}
   413 
   414 void CDrawTwentyFourBppBitmap::WriteBinaryLineVertical(TInt aX,TInt aY,TUint32* aBuffer,TInt aHeight,TRgb aColor,TBool aUp)
   415 	{
   416 	DeOrientate(aX,aY);
   417 
   418 	TInt scanlineByteLength;
   419 
   420 	switch (iOrientation)
   421 		{
   422 		case EOrientationNormal:
   423 			scanlineByteLength = iScanLineBytes;
   424 			break;
   425 		case EOrientationRotated90:
   426 			scanlineByteLength = -3;
   427 			break;
   428 		case EOrientationRotated180:
   429 			scanlineByteLength = -iScanLineBytes;
   430 			break;
   431 		default: // EOrientationRotated270
   432 			scanlineByteLength = 3;
   433 			break;
   434 		}
   435 
   436 	if (aUp)
   437 		scanlineByteLength = -scanlineByteLength;
   438 
   439 	TUint8* pixelPtr = PixelAddress(aX,aY);
   440 	const TUint8* pixelPtrLimit = pixelPtr + (aHeight * scanlineByteLength);
   441 	TUint32 dataWord = *aBuffer;
   442 	TUint32 dataMask = 1;
   443 
   444 	const TUint8 r = (TUint8)aColor.Red();
   445 	const TUint8 g = (TUint8)aColor.Green();
   446 	const TUint8 b = (TUint8)aColor.Blue();
   447 
   448 	while(pixelPtr != pixelPtrLimit)
   449 		{
   450 		if(!dataMask)
   451 			{
   452 			dataMask = 1;
   453 			aBuffer++;
   454 			dataWord = *aBuffer;
   455 			}
   456 
   457 		if(dataWord & dataMask)
   458 			{
   459 			pixelPtr[0] = b;
   460 			pixelPtr[1] = g;
   461 			pixelPtr[2] = r;
   462 			}
   463 
   464 		dataMask <<= 1;
   465 		pixelPtr += scanlineByteLength;
   466 		}
   467 	}
   468 
   469 void CDrawTwentyFourBppBitmap::WriteLine(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
   470 	{
   471 	TUint8* pixelPtr = PixelAddress(aX,aY);
   472 
   473 	if (iOrientation == EOrientationNormal)
   474 		Mem::Copy(pixelPtr,aBuffer,aLength * 3);
   475 	else
   476 		{
   477 		const TInt pixelPtrInc = PixelAddressIncrement();
   478 
   479 		TUint8* bufferPtr = REINTERPRET_CAST(TUint8*,aBuffer);
   480 		TUint8* bufferPtrLimit = bufferPtr + (aLength * 3);
   481 
   482 		while (bufferPtr < bufferPtrLimit)
   483 			{
   484 			pixelPtr[0] = *bufferPtr++;
   485 			pixelPtr[1] = *bufferPtr++;
   486 			pixelPtr[2] = *bufferPtr++;
   487 			pixelPtr += pixelPtrInc;
   488 			}
   489 		}
   490 	}
   491 
   492 void CDrawTwentyFourBppBitmap::WriteLineXOR(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
   493 	{
   494 	TUint8* pixelPtr = PixelAddress(aX,aY);
   495 	const TInt pixelPtrInc = PixelAddressIncrement();
   496 
   497 	TUint8* bufferPtr = REINTERPRET_CAST(TUint8*,aBuffer);
   498 	TUint8* bufferPtrLimit = bufferPtr + (aLength * 3);
   499 
   500 	while (bufferPtr < bufferPtrLimit)
   501 		{
   502 		pixelPtr[0] ^= *bufferPtr++;
   503 		pixelPtr[1] ^= *bufferPtr++;
   504 		pixelPtr[2] ^= *bufferPtr++;
   505 		pixelPtr += pixelPtrInc;
   506 		}
   507 	}
   508 
   509 void CDrawTwentyFourBppBitmap::WriteLineAND(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
   510 	{
   511 	TUint8* pixelPtr = PixelAddress(aX,aY);
   512 	const TInt pixelPtrInc = PixelAddressIncrement();
   513 
   514 	TUint8* bufferPtr = REINTERPRET_CAST(TUint8*,aBuffer);
   515 	TUint8* bufferPtrLimit = bufferPtr + (aLength * 3);
   516 
   517 	while (bufferPtr < bufferPtrLimit)
   518 		{
   519 		pixelPtr[0] &= *bufferPtr++;
   520 		pixelPtr[1] &= *bufferPtr++;
   521 		pixelPtr[2] &= *bufferPtr++;
   522 		pixelPtr += pixelPtrInc;
   523 		}
   524 	}
   525 
   526 void CDrawTwentyFourBppBitmap::WriteLineOR(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
   527 	{
   528 	TUint8* pixelPtr = PixelAddress(aX,aY);
   529 	const TInt pixelPtrInc = PixelAddressIncrement();
   530 
   531 	TUint8* bufferPtr = REINTERPRET_CAST(TUint8*,aBuffer);
   532 	TUint8* bufferPtrLimit = bufferPtr + (aLength * 3);
   533 
   534 	while (bufferPtr < bufferPtrLimit)
   535 		{
   536 		pixelPtr[0] |= *bufferPtr++;
   537 		pixelPtr[1] |= *bufferPtr++;
   538 		pixelPtr[2] |= *bufferPtr++;
   539 		pixelPtr += pixelPtrInc;
   540 		}
   541 	}
   542 
   543 /**
   544 MAlphaBlend::WriteRgbAlphaLine() implementation.
   545 @see MAlphaBlend::WriteRgbAlphaLine()
   546 */
   547 void CDrawTwentyFourBppBitmap::WriteRgbAlphaLine(TInt aX, TInt aY, TInt aLength,
   548                                                  const TUint8* aRgbBuffer,
   549                                                  const TUint8* aMaskBuffer,
   550                                                  MAlphaBlend::TShadowing aShadowing,
   551                                                  CGraphicsContext::TDrawMode /*aDrawMode*/)
   552     {
   553 	DeOrientate(aX,aY);
   554 	TUint8* pixelPtr = PixelAddress(aX,aY);
   555 	const TInt pixelPtrInc = PixelAddressIncrement();
   556 	const TUint8* maskBufferPtrLimit = aMaskBuffer + aLength;
   557 
   558 	while (aMaskBuffer < maskBufferPtrLimit)
   559 		{
   560   		TInt mask = aMaskBuffer[0];
   561           
   562   		if(mask)
   563   			{
   564   			TInt red = aRgbBuffer[2];
   565           	TInt green = aRgbBuffer[1];
   566           	TInt blue = aRgbBuffer[0];
   567           
   568   			if(aShadowing == MAlphaBlend::EShdwBefore)
   569   				{
   570   				Shadow(red,green,blue);
   571   				}
   572   		
   573   			if(aMaskBuffer[0] != 0xff) // Blend 24bpp
   574   				{
   575   				mask = mask * 257;
   576   				red = (((red   - pixelPtr[2]) * mask) >> 16) + pixelPtr[2];
   577   				green = (((green - pixelPtr[1]) * mask) >> 16) + pixelPtr[1];
   578   				blue = (((blue  - pixelPtr[0]) * mask) >> 16) + pixelPtr[0];
   579   				}
   580   
   581   			if(aShadowing == MAlphaBlend::EShdwAfter)
   582   				{
   583   				Shadow(red,green,blue);
   584   				}
   585   			CDrawBitmap::MapColorToUserDisplayMode(red,green,blue);
   586   			pixelPtr[0] = TUint8(blue); 
   587   			pixelPtr[1] = TUint8(green); 
   588   			pixelPtr[2] = TUint8(red);
   589   			}
   590   		pixelPtr += pixelPtrInc;
   591   		aRgbBuffer += 4;
   592   		aMaskBuffer++;
   593 		}
   594     }
   595 
   596 const TUint32 KWordAlignedCount = 4;
   597 const TUint32 KWordAlignedMask = 3;
   598 const TUint32 KFinishEarlyByThree = 3;
   599 
   600 void WriteTwentyFourBppColourAsWords(TUint8& r, TUint8& g, TUint8& b, TUint8* pixelPtr, const TInt byteLength, TUint8* pixelRowPtrLimit, const TInt scanLineBytes)
   601 	{
   602 	TUint8 bgr[3] = 
   603 		{
   604 		b,g,r
   605 		};
   606 	TUint32 bgrb = b+(g<<8)+(r<<16)+(b<<24);
   607 	TUint32 grbg = g+(r<<8)+(b<<16)+(g<<24);
   608 	TUint32 rbgr = r+(b<<8)+(g<<16)+(r<<24);
   609 
   610 	TUint8* pixelPtrLimit = pixelPtr + byteLength;
   611 
   612 	TInt leadingPixels = KWordAlignedCount-((TUint32)pixelPtr)&KWordAlignedMask;
   613 	if (leadingPixels == KWordAlignedCount)
   614 		leadingPixels = 0;
   615 	const TInt trailingPixels = ((TUint32)pixelPtrLimit & KWordAlignedMask);
   616 
   617 	while (pixelPtr < pixelRowPtrLimit)
   618 		{
   619 		TUint8* tempPixelPtr;
   620 		TUint32* tempWordPtr;
   621 		TInt nextOfBgr = 0;
   622 		TUint8* leadingPixelPtrLimit = pixelPtr+leadingPixels;
   623 		for (tempPixelPtr = pixelPtr; tempPixelPtr < leadingPixelPtrLimit; tempPixelPtr++)
   624 			{
   625 			tempPixelPtr[0] = bgr[nextOfBgr++];
   626 			}
   627 
   628 		if (nextOfBgr == (KWordAlignedCount-1))
   629 			nextOfBgr = 0;
   630 
   631 		TUint32* wordPtrLimit = ((TUint32*)(pixelPtrLimit-trailingPixels))-KFinishEarlyByThree;
   632 
   633 		tempWordPtr = (TUint32*)tempPixelPtr;
   634 		switch (nextOfBgr)
   635 			{
   636 		case 1:
   637 			if (tempWordPtr < wordPtrLimit)
   638 				{
   639 				*tempWordPtr++ = grbg;
   640 				nextOfBgr = 2;
   641 				}
   642 			//no break
   643 		case 2:
   644 			if (tempWordPtr < wordPtrLimit)
   645 				{
   646 				*tempWordPtr++ = rbgr;
   647 				nextOfBgr = 0;
   648 				}
   649 			}
   650 
   651 		while (tempWordPtr < wordPtrLimit)
   652 			{
   653 			*tempWordPtr++ = bgrb;
   654 			*tempWordPtr++ = grbg;
   655 			*tempWordPtr++ = rbgr;
   656 			}
   657 
   658 		for (tempPixelPtr = (TUint8*)tempWordPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
   659 			{
   660 			tempPixelPtr[0] = bgr[nextOfBgr++];
   661 			if (nextOfBgr > 2)
   662 				nextOfBgr = 0;
   663 			}
   664 
   665 		pixelPtr += scanLineBytes;
   666 		pixelPtrLimit += scanLineBytes;
   667 		}
   668 	}
   669 
   670 /**
   671 Writes a specific colour to the screen, optimised to use mem fill if the colour is shade of grey
   672 and word aligned access the three possible combinations of the colour bytes.
   673 */
   674 void CDrawTwentyFourBppBitmap::WriteRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
   675 	{
   676 	const TInt scanLineBytes = iScanLineBytes;
   677 	const TInt byteLength = aLength * 3;
   678 
   679 	TUint8* pixelPtr = PixelAddress(aX,aY);
   680 	TUint8* pixelRowPtrLimit = pixelPtr + (aHeight * scanLineBytes);
   681 
   682 	TUint8 r = TUint8(aColor.Red());
   683 	TUint8 g = TUint8(aColor.Green());
   684 	TUint8 b = TUint8(aColor.Blue());
   685 
   686 	if ((r == g) && (g == b))
   687 		{
   688 		while (pixelPtr < pixelRowPtrLimit)
   689 			{
   690 			Mem::Fill(pixelPtr,byteLength,r);
   691 			pixelPtr += scanLineBytes;
   692 			}
   693 		}
   694 	else
   695 		{
   696 		WriteTwentyFourBppColourAsWords(r, g, b, pixelPtr, byteLength, pixelRowPtrLimit, scanLineBytes);
   697 		}
   698 	}
   699 
   700 void CDrawTwentyFourBppBitmap::WriteRgbMultiXOR(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
   701 	{
   702 	TUint8* pixelPtr = PixelAddress(aX,aY);
   703 	TUint8* pixelPtrLimit = pixelPtr + (aLength * 3);
   704 	TUint8* pixelRowPtrLimit = pixelPtr + (aHeight * iScanLineBytes);
   705 
   706 	TUint8 r = TUint8(aColor.Red());
   707 	TUint8 g = TUint8(aColor.Green());
   708 	TUint8 b = TUint8(aColor.Blue());
   709 
   710 	while (pixelPtr < pixelRowPtrLimit)
   711 		{
   712 		for (TUint8* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr += 3)
   713 			{
   714 			tempPixelPtr[0] ^= b;
   715 			tempPixelPtr[1] ^= g;
   716 			tempPixelPtr[2] ^= r;
   717 			}
   718 
   719 		pixelPtr += iScanLineBytes;
   720 		pixelPtrLimit += iScanLineBytes;
   721 		}
   722 	}
   723 
   724 void CDrawTwentyFourBppBitmap::WriteRgbMultiAND(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
   725 	{
   726 	TUint8* pixelPtr = PixelAddress(aX,aY);
   727 	TUint8* pixelPtrLimit = pixelPtr + (aLength * 3);
   728 	TUint8* pixelRowPtrLimit = pixelPtr + (aHeight * iScanLineBytes);
   729 	TUint8 r = TUint8(aColor.Red());
   730 	TUint8 g = TUint8(aColor.Green());
   731 	TUint8 b = TUint8(aColor.Blue());
   732 
   733 	while (pixelPtr < pixelRowPtrLimit)
   734 		{
   735 		for (TUint8* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr += 3)
   736 			{
   737 			tempPixelPtr[0] &= b;
   738 			tempPixelPtr[1] &= g;
   739 			tempPixelPtr[2] &= r;
   740 			}
   741 
   742 		pixelPtr += iScanLineBytes;
   743 		pixelPtrLimit += iScanLineBytes;
   744 		}
   745 	}
   746 
   747 void CDrawTwentyFourBppBitmap::WriteRgbMultiOR(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
   748 	{
   749 	TUint8* pixelPtr = PixelAddress(aX,aY);
   750 	TUint8* pixelPtrLimit = pixelPtr + (aLength * 3);
   751 	TUint8* pixelRowPtrLimit = pixelPtr + (aHeight * iScanLineBytes);
   752 	TUint8 r = TUint8(aColor.Red());
   753 	TUint8 g = TUint8(aColor.Green());
   754 	TUint8 b = TUint8(aColor.Blue());
   755 
   756 	while (pixelPtr < pixelRowPtrLimit)
   757 		{
   758 		for (TUint8* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr += 3)
   759 			{
   760 			tempPixelPtr[0] |= b;
   761 			tempPixelPtr[1] |= g;
   762 			tempPixelPtr[2] |= r;
   763 			}
   764 
   765 		pixelPtr += iScanLineBytes;
   766 		pixelPtrLimit += iScanLineBytes;
   767 		}
   768 	}
   769 
   770 void CDrawTwentyFourBppBitmap::WriteRgbAlphaMulti(TInt aX,TInt aY,TInt aLength,TRgb aColor,const TUint8* aMaskBuffer)
   771 	{
   772 	DeOrientate(aX,aY);
   773 	TUint8* pixelPtr = PixelAddress(aX,aY);
   774 	const TInt pixelPtrInc = PixelAddressIncrement();
   775 	const TUint8* maskBufferPtrLimit = aMaskBuffer + aLength;
   776 
   777 	if (iShadowMode)
   778 		Shadow(aColor);
   779 
   780 	const TInt red = aColor.Red();
   781 	const TInt green = aColor.Green();
   782 	const TInt blue = aColor.Blue();
   783 	while (aMaskBuffer < maskBufferPtrLimit)
   784 		{
   785 		if(aMaskBuffer[0])
   786 			{
   787 			TRgb pixelClr;
   788 	
   789 			if(aMaskBuffer[0] != 0xff)
   790 				{
   791 				pixelClr = AlphaBlend(red, green, blue, TRgb(pixelPtr[2], pixelPtr[1], pixelPtr[0]), aMaskBuffer[0]);
   792 				}
   793 			else
   794 				{
   795 				pixelClr = aColor;	
   796 				}
   797 			
   798 			pixelPtr[0] = TUint8(pixelClr.Blue());
   799 			pixelPtr[1] = TUint8(pixelClr.Green());
   800 			pixelPtr[2] = TUint8(pixelClr.Red());
   801 			}
   802 		pixelPtr += pixelPtrInc;
   803 		aMaskBuffer++;
   804 		}
   805 	}
   806 
   807 void CDrawTwentyFourBppBitmap::MapColorToUserDisplayMode(TRgb& aColor)
   808 	{
   809 	switch (iUserDispMode)
   810 		{
   811 	case EGray2:
   812 		aColor = TRgb::_Gray2(aColor._Gray2());
   813 		break;
   814 	case EGray4:
   815 		aColor = TRgb::_Gray4(aColor._Gray4());
   816 		break;
   817 	case EGray16:
   818 		aColor = TRgb::_Gray16(aColor._Gray16());
   819 		break;
   820 	case EGray256:
   821 		aColor = TRgb::_Gray256(aColor._Gray256());
   822 		break;
   823 	case EColor16:
   824 		aColor = TRgb::Color16(aColor.Color16());
   825 		break;
   826 	case EColor256:
   827 		aColor = TRgb::Color256(aColor.Color256());
   828 		break;
   829 	case EColor4K:
   830 		aColor = TRgb::_Color4K(aColor._Color4K());
   831 		break;
   832 	case EColor64K:
   833 		aColor = TRgb::_Color64K(aColor._Color64K());
   834 		break;
   835 	default:
   836 		break;
   837 		}
   838 	}
   839 
   840 void CDrawTwentyFourBppBitmap::MapBufferToUserDisplayMode(TInt aLength,TUint32* aBuffer)
   841 	{
   842 	TUint8* bufferPtr = (TUint8*)aBuffer;
   843 	const TUint8* bufferLimit = bufferPtr + (aLength * 3);
   844 
   845 	switch (iUserDispMode)
   846 		{
   847 	case EGray2:
   848 		while (bufferPtr < bufferLimit)
   849 			{
   850 			TInt blue = bufferPtr[0];
   851 			TInt green = bufferPtr[1];
   852 			TInt red = bufferPtr[2];
   853 			TRgb color(red,green,blue);
   854 			color = TRgb::_Gray2(color._Gray2());
   855 			bufferPtr[0] = TUint8(color.Blue());
   856 			bufferPtr[1] = TUint8(color.Green());
   857 			bufferPtr[2] = TUint8(color.Red());
   858 			bufferPtr += 3;
   859 			}
   860 		break;
   861 	case EGray4:
   862 		while (bufferPtr < bufferLimit)
   863 			{
   864 			TInt blue = bufferPtr[0];
   865 			TInt green = bufferPtr[1];
   866 			TInt red = bufferPtr[2];
   867 			TRgb color(red,green,blue);
   868 			color = TRgb::_Gray4(color._Gray4());
   869 			bufferPtr[0] = TUint8(color.Blue());
   870 			bufferPtr[1] = TUint8(color.Green());
   871 			bufferPtr[2] = TUint8(color.Red());
   872 			bufferPtr += 3;
   873 			}
   874 		break;
   875 	case EGray16:
   876 		while (bufferPtr < bufferLimit)
   877 			{
   878 			TInt blue = bufferPtr[0];
   879 			TInt green = bufferPtr[1];
   880 			TInt red = bufferPtr[2];
   881 			TRgb color(red,green,blue);
   882 			color = TRgb::_Gray16(color._Gray16());
   883 			bufferPtr[0] = TUint8(color.Blue());
   884 			bufferPtr[1] = TUint8(color.Green());
   885 			bufferPtr[2] = TUint8(color.Red());
   886 			bufferPtr += 3;
   887 			}
   888 		break;
   889 	case EGray256:
   890 		while (bufferPtr < bufferLimit)
   891 			{
   892 			TInt blue = bufferPtr[0];
   893 			TInt green = bufferPtr[1];
   894 			TInt red = bufferPtr[2];
   895 			TRgb color(red,green,blue);
   896 			color = TRgb::_Gray256(color._Gray256());
   897 			bufferPtr[0] = TUint8(color.Blue());
   898 			bufferPtr[1] = TUint8(color.Green());
   899 			bufferPtr[2] = TUint8(color.Red());
   900 			bufferPtr += 3;
   901 			}
   902 		break;
   903 	case EColor16:
   904 		while (bufferPtr < bufferLimit)
   905 			{
   906 			TInt blue = bufferPtr[0];
   907 			TInt green = bufferPtr[1];
   908 			TInt red = bufferPtr[2];
   909 			TRgb color(red,green,blue);
   910 			color = TRgb::Color16(color.Color16());
   911 			bufferPtr[0] = TUint8(color.Blue());
   912 			bufferPtr[1] = TUint8(color.Green());
   913 			bufferPtr[2] = TUint8(color.Red());
   914 			bufferPtr += 3;
   915 			}
   916 		break;
   917 	case EColor256:
   918 		while (bufferPtr < bufferLimit)
   919 			{
   920 			TInt blue = bufferPtr[0];
   921 			TInt green = bufferPtr[1];
   922 			TInt red = bufferPtr[2];
   923 			TRgb color(red,green,blue);
   924 			color = TRgb::Color256(color.Color256());
   925 			bufferPtr[0] = TUint8(color.Blue());
   926 			bufferPtr[1] = TUint8(color.Green());
   927 			bufferPtr[2] = TUint8(color.Red());
   928 			bufferPtr += 3;
   929 			}
   930 		break;
   931 	case EColor4K:
   932 		while (bufferPtr < bufferLimit)
   933 			{
   934 			TInt blue = bufferPtr[0];
   935 			TInt green = bufferPtr[1];
   936 			TInt red = bufferPtr[2];
   937 			TRgb color(red,green,blue);
   938 			color = TRgb::_Color4K(color._Color4K());
   939 			bufferPtr[0] = TUint8(color.Blue());
   940 			bufferPtr[1] = TUint8(color.Green());
   941 			bufferPtr[2] = TUint8(color.Red());
   942 			bufferPtr += 3;
   943 			}
   944 		break;
   945 	case EColor64K:
   946 		while (bufferPtr < bufferLimit)
   947 			{
   948 			TInt blue = bufferPtr[0];
   949 			TInt green = bufferPtr[1];
   950 			TInt red = bufferPtr[2];
   951 			TRgb color(red,green,blue);
   952 			color = TRgb::_Color64K(color._Color64K());
   953 			bufferPtr[0] = TUint8(color.Blue());
   954 			bufferPtr[1] = TUint8(color.Green());
   955 			bufferPtr[2] = TUint8(color.Red());
   956 			bufferPtr += 3;
   957 			}
   958 		break;
   959 	default:
   960 		break;
   961 		}
   962 	}
   963 
   964 TInt CDrawTwentyFourBppBitmap::WriteRgbOutlineAndShadow(TInt aX, TInt aY, const TInt aLength,
   965 														TUint32 aOutlinePenColor, TUint32 aShadowColor,
   966 														TUint32 aFillColor, const TUint8* aDataBuffer)
   967 	{
   968 	DeOrientate(aX,aY);
   969 	TUint8* pixelPtr = PixelAddress(aX,aY);
   970 	const TInt pixelPtrInc = PixelAddressIncrement();
   971 	const TUint8* dataBufferPtrLimit = aDataBuffer + aLength;
   972 	TInt blendedRedColor;
   973 	TInt blendedGreenColor;
   974 	TInt blendedBlueColor;
   975 	TUint8 index = 0;
   976 	TRgb finalColor;
   977 
   978 	TRgb outlinePenColor;
   979 	outlinePenColor.SetInternal(aOutlinePenColor);
   980 	TRgb shadowColor;
   981 	shadowColor.SetInternal(aShadowColor);
   982 	TRgb fillColor;
   983 	fillColor.SetInternal(aFillColor);
   984 
   985 	const TInt redOutlinePenColor = outlinePenColor.Red();
   986 	const TInt redShadowColor = shadowColor.Red();
   987 	const TInt redFillColor = fillColor.Red();
   988 
   989 	const TInt greenOutlinePenColor = outlinePenColor.Green();
   990 	const TInt greenShadowColor = shadowColor.Green();
   991 	const TInt greenFillColor = fillColor.Green();
   992 
   993 	const TInt blueOutlinePenColor = outlinePenColor.Blue();
   994 	const TInt blueShadowColor = shadowColor.Blue();
   995 	const TInt blueFillColor = fillColor.Blue();
   996 	const TInt alpha = aOutlinePenColor >> 24;
   997 
   998 	while (aDataBuffer < dataBufferPtrLimit)
   999 		{
  1000 		index = *aDataBuffer++;
  1001 		if (255 == FourColorBlendLookup[index][KBackgroundColorIndex])
  1002 			{
  1003 			//background colour
  1004 			//No drawing required so move on to next pixel.
  1005 			pixelPtr += pixelPtrInc;
  1006 			continue;
  1007 			}
  1008 		else if (255 == FourColorBlendLookup[index][KFillColorIndex])
  1009 			{
  1010 			//fill colour
  1011 			finalColor.SetInternal(aFillColor);
  1012 			}
  1013 		else if (255 == FourColorBlendLookup[index][KShadowColorIndex])
  1014 			{
  1015 			//Shadow colour
  1016 			finalColor.SetInternal(aShadowColor);
  1017 			}
  1018 		else if (255 == FourColorBlendLookup[index][KOutlineColorIndex])
  1019 			{
  1020 			//Outline colour
  1021 			finalColor.SetInternal(aOutlinePenColor);
  1022 			}
  1023 		else
  1024 			{
  1025 			TRgb backgroundColor = TRgb::_Color16M(TRgb(pixelPtr[2], pixelPtr[1], pixelPtr[0])._Color16M());
  1026 
  1027 			blendedRedColor = (redOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] + 
  1028 						   		redShadowColor * FourColorBlendLookup[index][KShadowColorIndex] +
  1029 						  		redFillColor * FourColorBlendLookup[index][KFillColorIndex] + 
  1030 						  		backgroundColor.Red() * FourColorBlendLookup[index][KBackgroundColorIndex]) >> 8;
  1031 
  1032 			blendedGreenColor = (greenOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] + 
  1033 								greenShadowColor * FourColorBlendLookup[index][KShadowColorIndex] +
  1034 								greenFillColor * FourColorBlendLookup[index][KFillColorIndex] + 
  1035 								backgroundColor.Green() * FourColorBlendLookup[index][KBackgroundColorIndex]) >> 8;
  1036 
  1037 			blendedBlueColor = 	(blueOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] + 
  1038 								blueShadowColor * FourColorBlendLookup[index][KShadowColorIndex] +
  1039 								blueFillColor * FourColorBlendLookup[index][KFillColorIndex] + 
  1040 								backgroundColor.Blue() * FourColorBlendLookup[index][KBackgroundColorIndex]) >> 8;
  1041 
  1042 			if (alpha != 0xff)
  1043 				{
  1044 				TRgb alphablend = AlphaBlend(blendedRedColor, blendedGreenColor, blendedBlueColor, TRgb(pixelPtr[2], pixelPtr[1], pixelPtr[0]), alpha);
  1045 				pixelPtr[0] = TUint8(alphablend.Blue());
  1046 				pixelPtr[1] = TUint8(alphablend.Green());
  1047 				pixelPtr[2] = TUint8(alphablend.Red());
  1048 				}
  1049 			else
  1050 				{
  1051 				//opaque
  1052 				pixelPtr[0] = TUint8(blendedBlueColor);
  1053 				pixelPtr[1] = TUint8(blendedGreenColor);
  1054 				pixelPtr[2] = TUint8(blendedRedColor);
  1055 				}
  1056 			pixelPtr += pixelPtrInc;
  1057 			continue;
  1058 			}
  1059 
  1060 		if (alpha != 0xff)
  1061 			{
  1062 			TRgb alphablend = AlphaBlend(finalColor, TRgb(pixelPtr[2], pixelPtr[1], pixelPtr[0]), alpha);
  1063 			pixelPtr[0] = TUint8(alphablend.Blue());
  1064 			pixelPtr[1] = TUint8(alphablend.Green());
  1065 			pixelPtr[2] = TUint8(alphablend.Red());
  1066 			}
  1067 		else
  1068 			{
  1069 			pixelPtr[0] = TUint8(finalColor.Blue());
  1070 			pixelPtr[1] = TUint8(finalColor.Green());
  1071 			pixelPtr[2] = TUint8(finalColor.Red());
  1072 			}
  1073 		pixelPtr += pixelPtrInc;
  1074 		}
  1075 	return KErrNone;
  1076 	}
  1077 
  1078 void CDrawTwentyFourBppBitmap::BlendRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
  1079 	{
  1080 	const TInt sourceAlpha = aColor.Alpha();
  1081 	
  1082 	if (sourceAlpha == 0xFF) //Fully opaque
  1083 		{
  1084 		WriteRgbMulti(aX,aY,aLength,aHeight,aColor);
  1085 		return;
  1086 		}
  1087 	else if (sourceAlpha == 0x00) //Fully transparent
  1088 		{
  1089 		return;
  1090 		}
  1091 	else //Perform alpha blending
  1092 		{
  1093 		TUint8* pixelPtr = PixelAddress(aX,aY);
  1094 		const TInt pixelPtrInc = PixelAddressIncrement();
  1095 		TUint8* pixelPtrEnd = pixelPtr + (aLength * pixelPtrInc);
  1096 		
  1097 		TUint8 dr;
  1098 		TUint8 dg;
  1099 		TUint8 db;
  1100 		
  1101 		//Perform pre-multiplication on values from aColor
  1102 		const TUint8 pmsr = (sourceAlpha * aColor.Red()) / 255;
  1103 		const TUint8 pmsg = (sourceAlpha * aColor.Green()) / 255;
  1104 		const TUint8 pmsb = (sourceAlpha * aColor.Blue()) / 255;
  1105 		
  1106 		for (TInt ii = 0 ; ii <= aHeight; ii++)
  1107 			{
  1108 			while (pixelPtr != pixelPtrEnd)
  1109 				{
  1110 				dr = pixelPtr[2];
  1111 				dg = pixelPtr[1];
  1112 				db = pixelPtr[0];
  1113 				
  1114 				//Target has no alpha channel so assume to be 0xFF (opaque)
  1115 				pixelPtr[0] = pmsb + ((0xFF-sourceAlpha) * db)/255;
  1116 				pixelPtr[1] = pmsg + ((0xFF-sourceAlpha) * dg)/255;
  1117 				pixelPtr[2] = pmsr + ((0xFF-sourceAlpha) * dr)/255;
  1118 				
  1119 				pixelPtr+=pixelPtrInc;
  1120 				}	
  1121 			pixelPtr = PixelAddress(aX, ii+aY);
  1122 			pixelPtrEnd = pixelPtr + (aLength * pixelPtrInc);
  1123 			}
  1124 		}
  1125 	}