os/graphics/graphicsdeviceinterface/screendriver/sbit/BMDRAW24U.CPP
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/graphics/graphicsdeviceinterface/screendriver/sbit/BMDRAW24U.CPP	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,1270 @@
     1.4 +// Copyright (c) 2003-2010 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +//
    1.18 +
    1.19 +#include "BMDRAW.H"
    1.20 +#include "BitDrawInterfaceId.h"
    1.21 +#include <graphics/lookuptable.h>
    1.22 +#include <graphics/blendingalgorithms.h>
    1.23 +
    1.24 +TInt CDrawUTwentyFourBppBitmap::Construct(TSize aSize)
    1.25 +	{
    1.26 +	return Construct(aSize, aSize.iWidth << 2);
    1.27 +	}
    1.28 +
    1.29 +TInt CDrawUTwentyFourBppBitmap::Construct(TSize aSize, TInt aStride)
    1.30 +	{
    1.31 +	iDispMode = EColor16MU;
    1.32 +	return CDrawThirtyTwoBppBitmapCommon::Construct(aSize, aStride);
    1.33 +	}
    1.34 +
    1.35 +/**
    1.36 +MAlphaBlend::WriteRgbAlphaLine() implementation.
    1.37 +@see MAlphaBlend::WriteRgbAlphaLine()
    1.38 +*/
    1.39 +void CDrawUTwentyFourBppBitmap::WriteRgbAlphaLine(TInt aX, TInt aY, TInt aLength,
    1.40 +													const TUint8* aRgbBuffer,
    1.41 +													const TUint8* aMaskBuffer,
    1.42 +													MAlphaBlend::TShadowing aShadowing,
    1.43 +													CGraphicsContext::TDrawMode /*aDrawMode*/)
    1.44 +	{
    1.45 +	// precondition for this function is that the aRgbBuffer lies on a word boundary
    1.46 +    // Assert checks that the pointer is at a word boundary
    1.47 +    __ASSERT_DEBUG(!(((TUint)aRgbBuffer) & 0x3), Panic(EScreenDriverPanicInvalidPointer));
    1.48 +    
    1.49 +	DeOrientate(aX,aY);
    1.50 +	TUint32* pixelPtr = PixelAddress(aX,aY);
    1.51 +	TUint32* rgbBuffer = (TUint32*)aRgbBuffer;
    1.52 +	const TInt pixelPtrInc = PixelAddressIncrement();
    1.53 +	const TUint8* maskBufferPtrLimit = aMaskBuffer + aLength;
    1.54 +	
    1.55 +	if (!(iShadowMode & (EFade | EShadow)) && (iUserDispMode == ENone))
    1.56 +		{
    1.57 +		while (aMaskBuffer < maskBufferPtrLimit)
    1.58 +			{
    1.59 +			*pixelPtr = CalcAlphaPixel(*rgbBuffer, *aMaskBuffer, *pixelPtr);
    1.60 +			aMaskBuffer++;
    1.61 +			pixelPtr += pixelPtrInc;
    1.62 +			rgbBuffer++;
    1.63 +			}
    1.64 +		}
    1.65 +	else
    1.66 +		{
    1.67 +		while (aMaskBuffer < maskBufferPtrLimit)
    1.68 +			{
    1.69 +			TInt mask = *aMaskBuffer++;
    1.70 +			if (mask)
    1.71 +				{     
    1.72 +				TInt b = aRgbBuffer[0];
    1.73 +				TInt g = aRgbBuffer[1];
    1.74 +				TInt r = aRgbBuffer[2];
    1.75 +				if(aShadowing == MAlphaBlend::EShdwBefore)
    1.76 +					{
    1.77 +					if (iShadowMode & EFade)
    1.78 +						{
    1.79 +						r = ((r * iFadeMapFactor) >> 8) + iFadeMapOffset;
    1.80 +						g = ((g * iFadeMapFactor) >> 8) + iFadeMapOffset;
    1.81 +						b = ((b * iFadeMapFactor) >> 8) + iFadeMapOffset;
    1.82 +						}
    1.83 +					if (iShadowMode & EShadow)
    1.84 +						{
    1.85 +						r = (Max(0,r-0x40));
    1.86 +						g = (Max(0,g-0x40));
    1.87 +						b = (Max(0,b-0x40));
    1.88 +						}
    1.89 +					}
    1.90 +				if (mask != 0xff)
    1.91 +					{
    1.92 +					// (mask * r + (255 - mask) * value) / 255 =
    1.93 +					// ((257 * mask * (r - value)) >> 16) + value
    1.94 +					TInt value = *pixelPtr & 0xffffff;
    1.95 +					mask = (mask << 8) + mask; // mask = mask * 257
    1.96 +					TInt v = value >> 16;
    1.97 +					r = ((mask * (r - v)) >> 16) + v;
    1.98 +					v = (value >> 8) & 0xff;
    1.99 +					g = ((mask * (g - v)) >> 16) + v;
   1.100 +					v = value & 0xff;
   1.101 +					b = ((mask * (b - v)) >> 16) + v;
   1.102 +					}
   1.103 +				if(aShadowing == MAlphaBlend::EShdwAfter)
   1.104 +					{
   1.105 +					if (iShadowMode & EFade)
   1.106 +						{  
   1.107 +						r = ((r * iFadeMapFactor) >> 8) + iFadeMapOffset;
   1.108 +						g = ((g * iFadeMapFactor) >> 8) + iFadeMapOffset;
   1.109 +						b = ((b * iFadeMapFactor) >> 8) + iFadeMapOffset;            
   1.110 +						}
   1.111 +					if (iShadowMode & EShadow)
   1.112 +						{
   1.113 +						r = (Max(0,r-0x40));
   1.114 +						g = (Max(0,g-0x40));
   1.115 +						b = (Max(0,b-0x40));                  
   1.116 +						}
   1.117 +					}
   1.118 +				// Convert colour if an incompatible UserDisplayMode is being used
   1.119 +				CDrawBitmap::MapColorToUserDisplayMode(r,g,b);
   1.120 +				*pixelPtr = (r<<16) | (g<<8) | b | 0xff000000;
   1.121 +				}
   1.122 +			aRgbBuffer += 4;
   1.123 +			pixelPtr += pixelPtrInc;
   1.124 +			}
   1.125 +		}
   1.126 +	}
   1.127 +
   1.128 +void CDrawUTwentyFourBppBitmap::ReadLine(TInt aX, TInt aY, TInt aLength, TAny* aBuffer, TDisplayMode aDispMode) const
   1.129 +	{
   1.130 +	if (aDispMode == EColor16MAP)
   1.131 +		{
   1.132 +		DeOrientate(aX, aY);
   1.133 +		CDrawThirtyTwoBppBitmapCommon::ReadLine(aX, aY, aLength, aBuffer);
   1.134 +		
   1.135 +		//Overwrite unused byte with 0xff to produce valid 16MAP data
   1.136 +		TUint8* alphaptr = (TUint8*) aBuffer+3;
   1.137 +		TUint8* bufEnd = (TUint8*) aBuffer + (aLength << 2);
   1.138 +		while (alphaptr < bufEnd)
   1.139 +			{
   1.140 +			*alphaptr = 0xff;
   1.141 +			alphaptr+=4;
   1.142 +			}
   1.143 +		
   1.144 +		return;
   1.145 +		}
   1.146 +	CDrawBitmap::ReadLine(aX, aY, aLength, aBuffer, aDispMode);
   1.147 +	}
   1.148 +
   1.149 +void CDrawUTwentyFourBppBitmap::BlendRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
   1.150 +	{
   1.151 +	const TInt sourceAlpha = aColor.Alpha();
   1.152 +	if (sourceAlpha==255)// opaque
   1.153 +		{
   1.154 +		WriteRgbMulti(aX,aY,aLength,aHeight,aColor);
   1.155 +		return;
   1.156 +		}
   1.157 +	if (sourceAlpha==0)// transparent
   1.158 +		return;
   1.159 +
   1.160 +	TUint32* pixelPtr = PixelAddress(aX,aY);
   1.161 +	TUint32* pixelRowPtrLimit = pixelPtr + (aHeight * iScanLineWords);
   1.162 +	TUint32* pixelPtrLimit = pixelPtr + aLength;
   1.163 +
   1.164 +	const TUint32 sourceInternal=aColor.Internal();
   1.165 +	const TUint32 s_rb = sourceInternal & 0x00FF00FF;
   1.166 +	const TUint32 s_g = (sourceInternal & 0xFF00) >> 8;
   1.167 +	const TUint32 mask2 = sourceAlpha | (sourceAlpha << 16);
   1.168 +	while (pixelPtr < pixelRowPtrLimit)
   1.169 +		{
   1.170 +		for (TUint32* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
   1.171 +			{
   1.172 +			const TUint32 d = *tempPixelPtr;
   1.173 +			const TUint32 d_rb = d & 0x00FF00FF;
   1.174 +			const TUint32 rb = ((((sourceAlpha * ((0x01000100 + s_rb) - d_rb)) >> 8) + d_rb) - mask2) & 0x00FF00FF;
   1.175 +
   1.176 +			const TInt d_g = (d & 0xFF00) >> 8;
   1.177 +			const TInt g = ((sourceAlpha * (s_g - d_g)) >> 8) + d_g;
   1.178 +	
   1.179 +			*tempPixelPtr = rb | (g<<8) | 0xff000000;
   1.180 +			}
   1.181 +
   1.182 +		pixelPtr += iScanLineWords;
   1.183 +		pixelPtrLimit += iScanLineWords;
   1.184 +		}
   1.185 +	}
   1.186 +
   1.187 +void CDrawUTwentyFourBppBitmap::BlendLine(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
   1.188 +	{
   1.189 +	TUint32* pixelPtr = PixelAddress(aX,aY);
   1.190 +
   1.191 +	const TUint32* bufferPtrLimit = aBuffer + aLength;
   1.192 +	const TInt pixelPtrInc = (iOrientation == EOrientationNormal) ? 1 : PixelAddressIncrement();
   1.193 +				
   1.194 +	while (aBuffer < bufferPtrLimit)
   1.195 +		{
   1.196 +		if((*aBuffer &0xFF000000) == 0xFF000000)
   1.197 +			{
   1.198 +			*pixelPtr = *aBuffer;
   1.199 +			}
   1.200 +		else if((*aBuffer & 0xFF000000))
   1.201 +			{	
   1.202 +			// specialization of pre-multiplied blending when the destination alpha is always 255
   1.203 +			const TUint32 src_rb = *aBuffer & 0x00FF00FF;
   1.204 +			const TUint32 src_g = *aBuffer & 0x0000FF00;
   1.205 +			const TUint32 mask = 0x100 - (*aBuffer >> 24);
   1.206 +			TUint32 dst_rb = *pixelPtr & 0x00FF00FF;
   1.207 +			TUint32 dst_g = *pixelPtr & 0x0000FF00;
   1.208 +			dst_rb = (src_rb + ((mask * dst_rb) >> 8)) & 0x00FF00FF;
   1.209 +			dst_g = (src_g + ((mask * dst_g) >> 8)) & 0x0000FF00;
   1.210 +			*pixelPtr = 0xFF000000 | dst_rb | dst_g;
   1.211 +			}
   1.212 +			
   1.213 +		aBuffer++;
   1.214 +		pixelPtr += pixelPtrInc;
   1.215 +		}
   1.216 +	}
   1.217 +
   1.218 +TRgb CDrawUTwentyFourBppBitmap::RgbColor(TUint32 aColor) const
   1.219 +	{
   1.220 +	return TRgb::_Color16MU(aColor);
   1.221 +	}
   1.222 +
   1.223 +TUint32 CDrawUTwentyFourBppBitmap::Color(const TRgb& aColor)
   1.224 +	{
   1.225 +	return aColor._Color16MA() | 0xff000000;	
   1.226 +	}
   1.227 +
   1.228 +
   1.229 +// Copies an EColor64K pixel to an EColor16MU screen
   1.230 +FORCEINLINE static void CopyPixel(const TUint16*& aSrcPtr, TUint32*& aDestPtr, TInt aPixelPtrInc, const TUint32* aHighAdd, const TUint16* aLowAdd)
   1.231 +	{
   1.232 +	*aDestPtr = aHighAdd[(*aSrcPtr) >> 8] | aLowAdd[(*aSrcPtr) & 0xff];
   1.233 +	aDestPtr += aPixelPtrInc;
   1.234 +	aSrcPtr++;
   1.235 +	}
   1.236 +
   1.237 +
   1.238 +// Copies two EColor64K pixels to an EColor16MU screen
   1.239 +FORCEINLINE static void CopyTwoPixels(const TUint32*& aSrcPtr, TUint32*& aDestPtr, TInt aPixelPtrInc, const TUint32* aHighAdd, const TUint16* aLowAdd)
   1.240 +	{
   1.241 +	const TUint16* scanPtr = reinterpret_cast<const TUint16*&>(aSrcPtr);
   1.242 +	*aDestPtr = aHighAdd[(*scanPtr) >> 8] | aLowAdd[(*scanPtr) & 0xff];
   1.243 + 	aDestPtr += aPixelPtrInc;
   1.244 +	scanPtr++;
   1.245 +	*aDestPtr = aHighAdd[(*scanPtr) >> 8] | aLowAdd[(*scanPtr) & 0xff];
   1.246 + 	aDestPtr += aPixelPtrInc;
   1.247 + 	aSrcPtr++;
   1.248 +	}
   1.249 +
   1.250 +
   1.251 +// Copies an EColor16MU pixel to an EColor16MU screen if necessary.
   1.252 +FORCEINLINE static void ProcessMaskPixel(const TUint32*& aSrcPtr, const TUint32 aMaskWord, TUint32& aSingleBitMask, TUint32*& aDestPtr, TInt aPixelPtrInc)
   1.253 +	{
   1.254 +	if (aMaskWord & aSingleBitMask)
   1.255 +		{
   1.256 +		*aDestPtr = *aSrcPtr;
   1.257 +		}
   1.258 +	aSrcPtr++;
   1.259 +	aDestPtr += aPixelPtrInc;
   1.260 +	aSingleBitMask <<= 1;
   1.261 +	}
   1.262 +
   1.263 +
   1.264 +// Copies an EColor64K pixel to an EColor16MU screen if necessary.	
   1.265 +FORCEINLINE static void ProcessMaskPixel(const TUint16*& aSrcPtr, const TUint32 aMaskWord, TUint32& aSingleBitMask, TUint32*& aDestPtr, TInt aPixelPtrInc, const TUint32* aHighAdd, const TUint16* aLowAdd)
   1.266 +	{	
   1.267 +	if (aMaskWord & aSingleBitMask)
   1.268 +		{
   1.269 +		*aDestPtr = aHighAdd[(*aSrcPtr) >> 8] | aLowAdd[(*aSrcPtr) & 0xff];
   1.270 +		}
   1.271 +	aSrcPtr++;
   1.272 +	aDestPtr += aPixelPtrInc;
   1.273 +	aSingleBitMask <<= 1;
   1.274 +	}
   1.275 +
   1.276 +
   1.277 +// Alpha-blends an EColor16MU pixel to an EColor16MU screen using a fixed mask value.
   1.278 +FORCEINLINE static void BlendAlphaPixel(const TUint32*& aSrcPtr, const TUint8 aMask, TUint32*& aDestPtr, TInt aPixelPtrInc)
   1.279 +	{
   1.280 +	const TUint32 s = *aSrcPtr++;
   1.281 +	const TUint32 d = *aDestPtr;
   1.282 +	
   1.283 +	// (a)  (mask * src + (255 - mask) * dest) / 255           This ideal formula
   1.284 +	// (b)  ((mask * (src - dest)) >> 8) + dest                A faster approximation to (a)
   1.285 +	// (c)  ((mask * (256 + src - dest) >> 8) + dest - mask    Equivalent to (b) but can be used on multiple colors at a time
   1.286 +
   1.287 +	const TUint32 s_rb = s & 0x00FF00FF;
   1.288 +	const TUint32 d_rb = d & 0x00FF00FF;
   1.289 +	const TUint32 mask2 = aMask | (aMask << 16);
   1.290 +	const TUint32 rb = ((((aMask * ((0x01000100 + s_rb) - d_rb)) >> 8) + d_rb) - mask2) & 0x00FF00FF;
   1.291 +
   1.292 +	const TInt s_g = (s & 0xFF00) >> 8;
   1.293 +	const TInt d_g = (d & 0xFF00) >> 8;
   1.294 +	const TInt g = ((aMask * (s_g - d_g)) >> 8) + d_g;
   1.295 +	
   1.296 +	*aDestPtr = rb | (g<<8) | 0xff000000;
   1.297 +	aDestPtr += aPixelPtrInc;
   1.298 +	}
   1.299 +
   1.300 +
   1.301 +// Alpha-blends an EColor16MU pixel to an EColor16MU screen if necessary.	
   1.302 +FORCEINLINE static void ProcessAlphaPixel(const TUint32*& aSrcPtr, const TUint8*& aMaskPtr, TUint32*& aDestPtr, TInt aPixelPtrInc)
   1.303 +	{
   1.304 +	const TInt mask = *aMaskPtr++;
   1.305 +
   1.306 +	if (!mask)
   1.307 +		{
   1.308 +		// pixel is masked
   1.309 +		aSrcPtr++;
   1.310 +		aDestPtr += aPixelPtrInc;
   1.311 +		}
   1.312 +	else if (mask == 0xFF)
   1.313 +		{
   1.314 +		// pixel is unmasked
   1.315 +		*aDestPtr = *aSrcPtr++;
   1.316 +		aDestPtr += aPixelPtrInc;
   1.317 +		}
   1.318 +	else
   1.319 +		{
   1.320 +		BlendAlphaPixel(aSrcPtr, mask, aDestPtr, aPixelPtrInc);
   1.321 +		}
   1.322 +	}
   1.323 +	
   1.324 +
   1.325 +// Alpha-blends an EColor64K pixel to an EColor16MU screen using a fixed mask value.
   1.326 +FORCEINLINE static void BlendAlphaPixel(const TUint16*& aSrcPtr, const TUint8 aMask, TUint32*& aDestPtr, TInt aPixelPtrInc)
   1.327 +	{
   1.328 +	const TUint32 s = *aSrcPtr++;
   1.329 +	const TUint32 d = *aDestPtr;
   1.330 +	
   1.331 +	// convert the source EColor64K red / blue pixels to EColor16MU
   1.332 +	// the top two bits in EColor64K are used to fill the bottom two bits in EColor16MU
   1.333 +	
   1.334 +	const TUint32 s_rb = ((s & 0xF800) << 8) | ((s & 0xE000) << 3) | ((s & 0x1F) << 3) | ((s & 0x1C) >>2);	
   1.335 +	const TUint32 d_rb = d & 0x00FF00FF;
   1.336 +	const TUint32 mask2 = aMask | (aMask << 16);
   1.337 +	const TUint32 rb = ((((aMask * ((0x01000100 + s_rb) - d_rb)) >> 8) + d_rb) - mask2) & 0x00FF00FF;
   1.338 +	
   1.339 +	// convert the source EColor64K green pixel to EColor16MU
   1.340 +	const TInt s_g = ((s & 0x07E0) >> 3) | ((s & 0x0600) >> 9);
   1.341 +	const TInt d_g = (d & 0xFF00) >> 8;
   1.342 +	const TInt g = ((aMask * (s_g - d_g)) >> 8) + d_g;
   1.343 +	
   1.344 +	*aDestPtr = rb | (g<<8) | 0xff000000;
   1.345 +	aDestPtr += aPixelPtrInc;
   1.346 +	}
   1.347 +
   1.348 +	
   1.349 +// Alpha-blends an EColor64K pixel to an EColor16MU screen if necessary.	
   1.350 +FORCEINLINE static void ProcessAlphaPixel(const TUint16*& aSrcPtr, const TUint8*& aMaskPtr, TUint32*& aDestPtr, TInt aPixelPtrInc, const TUint32* aHighAdd, const TUint16* aLowAdd)
   1.351 +	{
   1.352 +	const TInt mask = *aMaskPtr++;
   1.353 +
   1.354 +	if (!mask)
   1.355 +		{
   1.356 +		// pixel is masked
   1.357 +		aSrcPtr++;
   1.358 +		aDestPtr += aPixelPtrInc;
   1.359 +		}
   1.360 +	else if (mask == 0xFF) 
   1.361 +		{
   1.362 +		// pixel is unmasked
   1.363 +		CopyPixel(aSrcPtr, aDestPtr, aPixelPtrInc, aHighAdd, aLowAdd);
   1.364 +		}
   1.365 +	else
   1.366 +		{
   1.367 +		BlendAlphaPixel(aSrcPtr, mask, aDestPtr, aPixelPtrInc);
   1.368 +		}
   1.369 +	}
   1.370 +
   1.371 +
   1.372 +/**
   1.373 +CDrawUTwentyFourBppBitmap::WriteAlphaLineEx() implementation.
   1.374 +@internalTechnology
   1.375 +@see MFastBlit::WriteAlphaLineEx()
   1.376 +*/
   1.377 +void CDrawUTwentyFourBppBitmap::WriteAlphaLineEx(TInt aX, TInt aY, TInt aLength, TInt aSrcX,
   1.378 +													const TUint32* aSrcPtr,  TDisplayMode aSrcFormat,
   1.379 +													TInt aMaskX, const TUint32* aMaskPtr,
   1.380 +													MAlphaBlend::TShadowing aShadowing)
   1.381 +	{
   1.382 +	// Only certain pixel formats are supported.  Caller should check this.
   1.383 +	__ASSERT_DEBUG(aSrcFormat ==EColor16MU || aSrcFormat ==EColor64K, User::Invariant());
   1.384 +	
   1.385 +	DeOrientate(aX,aY);
   1.386 +	TUint32* pixelPtr = PixelAddress(aX,aY);
   1.387 +	const TInt pixelPtrInc = PixelAddressIncrement();
   1.388 +	
   1.389 +	if (aSrcFormat==EColor16MU)
   1.390 +		{		
   1.391 +		if (!(iShadowMode & EFade) && !(iShadowMode & EShadow) && ((iUserDispMode==ENone) || (iUserDispMode==EColor16MU)) )
   1.392 +			{
   1.393 +			aSrcPtr += aSrcX;
   1.394 +			const TUint32* maskWordPtr = aMaskPtr + (aMaskX >> 2);
   1.395 +			const TInt startBit = aMaskX & 0x3;
   1.396 +			
   1.397 +			if (startBit)
   1.398 +				{
   1.399 +				// Process initial incomplete mask word
   1.400 +				const TUint32 maskWord = *maskWordPtr++;
   1.401 +				TInt numPix = Min(aLength, 4 - startBit);  // number of pixels to process from the first word of the mask
   1.402 +				aLength -= numPix;
   1.403 +				
   1.404 +				if (!maskWord)
   1.405 +					{
   1.406 +					// maskWord is fully masked - skip the pixels
   1.407 +					aSrcPtr += numPix;
   1.408 +					pixelPtr += pixelPtrInc * numPix;
   1.409 +					}
   1.410 +				else if (maskWord == 0xFFFFFFFF)
   1.411 +					{
   1.412 +					// maskWord is fully unmasked - copy the pixels
   1.413 +					while (numPix--)
   1.414 +						{
   1.415 +						*pixelPtr = *aSrcPtr++;
   1.416 +						pixelPtr += pixelPtrInc;
   1.417 +						}
   1.418 +					}
   1.419 +				else
   1.420 +					{
   1.421 +					// At least one of the pixels needs to be blended
   1.422 +					const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(&maskWord);
   1.423 +					maskPtr8 += startBit;
   1.424 +					while (numPix--)
   1.425 +						{
   1.426 +						ProcessAlphaPixel(aSrcPtr, maskPtr8, pixelPtr, pixelPtrInc);
   1.427 +						}
   1.428 +					}
   1.429 +				}
   1.430 +			
   1.431 +			TInt numMaskWords = aLength >> 2;
   1.432 +			aLength &= 0x3;
   1.433 +			while (numMaskWords--)
   1.434 +				{
   1.435 +				// Process a complete mask word - 4 pixels
   1.436 +				const TUint32 maskWord = *maskWordPtr++;
   1.437 +				
   1.438 +				if (!maskWord)
   1.439 +					{
   1.440 +					// maskWord is fully masked - skip 4 pixels
   1.441 +					aSrcPtr += 4;
   1.442 +					pixelPtr += pixelPtrInc << 2;
   1.443 +					}
   1.444 +				else if (maskWord == 0xFFFFFFFF)
   1.445 +					{
   1.446 +					// maskWord is fully unmasked - copy 4 pixels
   1.447 +					*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.448 +					*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.449 +					*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.450 +					*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.451 +					}
   1.452 +				else
   1.453 +					{	
   1.454 +					// At least one of the 4 pixels needs to be blended
   1.455 +					const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(&maskWord);
   1.456 +
   1.457 +					if (maskPtr8[0] && (maskPtr8[0] != 0xFF) &&
   1.458 +						maskPtr8[1] && (maskPtr8[1] != 0xFF) &&
   1.459 +						maskPtr8[2] && (maskPtr8[2] != 0xFF) &&
   1.460 +						maskPtr8[3] && (maskPtr8[3] != 0xFF))
   1.461 +						{
   1.462 +						// Blend all 4 pixels inline
   1.463 +						BlendAlphaPixel(aSrcPtr, maskPtr8[0], pixelPtr, pixelPtrInc);
   1.464 +						BlendAlphaPixel(aSrcPtr, maskPtr8[1], pixelPtr, pixelPtrInc);
   1.465 +						BlendAlphaPixel(aSrcPtr, maskPtr8[2], pixelPtr, pixelPtrInc);
   1.466 +						BlendAlphaPixel(aSrcPtr, maskPtr8[3], pixelPtr, pixelPtrInc);
   1.467 +						}
   1.468 +					else
   1.469 +						{
   1.470 +						ProcessAlphaPixel(aSrcPtr, maskPtr8, pixelPtr, pixelPtrInc);
   1.471 +						ProcessAlphaPixel(aSrcPtr, maskPtr8, pixelPtr, pixelPtrInc);
   1.472 +						ProcessAlphaPixel(aSrcPtr, maskPtr8, pixelPtr, pixelPtrInc);
   1.473 +						ProcessAlphaPixel(aSrcPtr, maskPtr8, pixelPtr, pixelPtrInc);
   1.474 +						}
   1.475 +					}
   1.476 +				}
   1.477 +
   1.478 +			if (aLength)
   1.479 +				{
   1.480 +				const TUint32 maskWord = *maskWordPtr;
   1.481 +				if (!maskWord)
   1.482 +					{
   1.483 +					// maskWord is fully masked - skip the pixels
   1.484 +					return;
   1.485 +					}
   1.486 +				if (maskWord == 0xFFFFFFFF)
   1.487 +					{
   1.488 +					// maskWord is fully unmasked - copy the pixels
   1.489 +					while (aLength--)
   1.490 +						{
   1.491 +						*pixelPtr = *aSrcPtr++;
   1.492 +						pixelPtr += pixelPtrInc;
   1.493 +						}
   1.494 +					}
   1.495 +				else
   1.496 +					{
   1.497 +					// At least one of the pixels needs to be blended
   1.498 +					const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(&maskWord);
   1.499 +					while (aLength--)
   1.500 +						{
   1.501 +						ProcessAlphaPixel(aSrcPtr, maskPtr8, pixelPtr, pixelPtrInc);
   1.502 +						}
   1.503 +					}
   1.504 +				}
   1.505 +			}
   1.506 +		else
   1.507 +			{
   1.508 +			// Non-optimised path including shadowing and UserDisplayMode conversion
   1.509 +			const TUint8* srcPtr8  = reinterpret_cast<const TUint8*>(aSrcPtr + aSrcX);
   1.510 +			const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(aMaskPtr) + aMaskX;
   1.511 +			
   1.512 +			while (aLength--)
   1.513 +				{
   1.514 +				TInt mask = *maskPtr8++;
   1.515 +				if (mask)
   1.516 +					{
   1.517 +					TInt b = srcPtr8[0];
   1.518 +					TInt g = srcPtr8[1];
   1.519 +					TInt r = srcPtr8[2];
   1.520 +					if(aShadowing == MAlphaBlend::EShdwBefore)
   1.521 +						{
   1.522 +						if (iShadowMode & EFade)
   1.523 +							{
   1.524 +							r = ((r * iFadeMapFactor) >> 8) + iFadeMapOffset;
   1.525 +							g = ((g * iFadeMapFactor) >> 8) + iFadeMapOffset;
   1.526 +							b = ((b * iFadeMapFactor) >> 8) + iFadeMapOffset;
   1.527 +							}
   1.528 +						if (iShadowMode & EShadow)
   1.529 +							{
   1.530 +							r = (Max(0,r-0x40));
   1.531 +							g = (Max(0,g-0x40));
   1.532 +							b = (Max(0,b-0x40));
   1.533 +							}
   1.534 +						}
   1.535 +					if (mask != 0xff)
   1.536 +						{
   1.537 +						// (mask * r + (255 - mask) * value) / 255 =
   1.538 +						// ((257 * mask * (r - value)) >> 16) + value
   1.539 +						TInt value = *pixelPtr & 0xffffff;
   1.540 +						mask = (mask << 8) + mask; // mask = mask * 257
   1.541 +						TInt v = value >> 16;
   1.542 +						r = ((mask * (r - v)) >> 16) + v;
   1.543 +						v = (value >> 8) & 0xff;
   1.544 +						g = ((mask * (g - v)) >> 16) + v;
   1.545 +						v = value & 0xff;
   1.546 +						b = ((mask * (b - v)) >> 16) + v;
   1.547 +						}
   1.548 +					if(aShadowing == MAlphaBlend::EShdwAfter)
   1.549 +						{
   1.550 +						if (iShadowMode & EFade)
   1.551 +							{  
   1.552 +							r = ((r * iFadeMapFactor) >> 8) + iFadeMapOffset;
   1.553 +							g = ((g * iFadeMapFactor) >> 8) + iFadeMapOffset;
   1.554 +							b = ((b * iFadeMapFactor) >> 8) + iFadeMapOffset;            
   1.555 +							}
   1.556 +						if (iShadowMode & EShadow)
   1.557 +							{
   1.558 +							r = (Max(0,r-0x40));
   1.559 +							g = (Max(0,g-0x40));
   1.560 +							b = (Max(0,b-0x40));
   1.561 +							}
   1.562 +						}
   1.563 +					// Convert colour if an incompatible UserDisplayMode is being used
   1.564 +					CDrawBitmap::MapColorToUserDisplayMode(r,g,b);
   1.565 +					*pixelPtr = (r<<16) | (g<<8) | b | 0xff000000;
   1.566 +					}
   1.567 +				pixelPtr += pixelPtrInc;
   1.568 +				srcPtr8 += 4;
   1.569 +				}
   1.570 +			}
   1.571 +		return;
   1.572 +		}
   1.573 +	else   // (aSrcFormat==EColor64K)
   1.574 +		{
   1.575 +		const TUint16* srcPtr16 = reinterpret_cast<const TUint16*>(aSrcPtr) + aSrcX;
   1.576 +		
   1.577 +		if (!(iShadowMode & EFade) && !(iShadowMode & EShadow) && ((iUserDispMode==ENone) || (iUserDispMode==EColor16MU)))
   1.578 +			{			
   1.579 +			const TUint16* lowAdd = Convert16to32bppLow();
   1.580 +			const TUint32* highAdd = Convert16to32bppHigh();
   1.581 +			const TUint32* maskWordPtr = aMaskPtr + (aMaskX >> 2);
   1.582 +			const TInt startBit = aMaskX & 0x3;
   1.583 +			
   1.584 +			if (startBit)
   1.585 +				{
   1.586 +				// Process initial incomplete mask word
   1.587 +				const TUint32 maskWord = *maskWordPtr++;
   1.588 +				TInt numPix = Min(aLength, 4 - startBit);  // number of pixels to process from the first word of the mask
   1.589 +				aLength -= numPix;
   1.590 +				
   1.591 +				if (!maskWord)
   1.592 +					{
   1.593 +					// maskWord is fully masked
   1.594 +					srcPtr16 += numPix;
   1.595 +					pixelPtr += pixelPtrInc * numPix;
   1.596 +					}
   1.597 +				else if (maskWord == 0xFFFFFFFF)
   1.598 +					{
   1.599 +					// maskWord is fully unmasked
   1.600 +					while (numPix--)
   1.601 +						{
   1.602 +						CopyPixel(srcPtr16, pixelPtr, pixelPtrInc, highAdd, lowAdd);
   1.603 +						}
   1.604 +					}
   1.605 +				else
   1.606 +					{
   1.607 +					// At least one of the pixels needs to be blended
   1.608 +					const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(&maskWord);
   1.609 +					maskPtr8 += startBit;
   1.610 +					while (numPix--)
   1.611 +						{
   1.612 +						ProcessAlphaPixel(srcPtr16, maskPtr8, pixelPtr, pixelPtrInc, highAdd, lowAdd);
   1.613 +						}
   1.614 +					}
   1.615 +				}
   1.616 +			
   1.617 +			TInt numMaskWords = aLength >> 2;
   1.618 +			aLength &= 0x3;
   1.619 +			while (numMaskWords--)
   1.620 +				{
   1.621 +				// Process 4 mask pixels
   1.622 +				const TUint32 maskWord = *maskWordPtr++;
   1.623 +				
   1.624 +				if (!maskWord)
   1.625 +					{
   1.626 +					// maskWord is fully masked - skip 4 pixels
   1.627 +					srcPtr16 += 4;
   1.628 +					pixelPtr += pixelPtrInc << 2;
   1.629 +					}
   1.630 +				else if (maskWord == 0xFFFFFFFF)
   1.631 +					{
   1.632 +					// maskWord is fully unmasked - copy and convert 4 pixels
   1.633 +					const TUint32* srcPtr32 = (const TUint32*)srcPtr16;
   1.634 +					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
   1.635 +					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
   1.636 +					srcPtr16 = (const TUint16*)srcPtr32;
   1.637 +					}
   1.638 +				else
   1.639 +					{	
   1.640 +					// At least one of the 4 pixels needs to be blended
   1.641 +					const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(&maskWord);
   1.642 +
   1.643 +					if (maskPtr8[0] && (maskPtr8[0] != 0xFF) &&
   1.644 +						maskPtr8[1] && (maskPtr8[1] != 0xFF) &&
   1.645 +						maskPtr8[2] && (maskPtr8[2] != 0xFF) &&
   1.646 +						maskPtr8[3] && (maskPtr8[3] != 0xFF))
   1.647 +						{
   1.648 +						// Blend all 4 pixels inline
   1.649 +						BlendAlphaPixel(srcPtr16, maskPtr8[0], pixelPtr, pixelPtrInc);
   1.650 +						BlendAlphaPixel(srcPtr16, maskPtr8[1], pixelPtr, pixelPtrInc);
   1.651 +						BlendAlphaPixel(srcPtr16, maskPtr8[2], pixelPtr, pixelPtrInc);
   1.652 +						BlendAlphaPixel(srcPtr16, maskPtr8[3], pixelPtr, pixelPtrInc);
   1.653 +						}
   1.654 +					else
   1.655 +						{
   1.656 +						ProcessAlphaPixel(srcPtr16, maskPtr8, pixelPtr, pixelPtrInc, highAdd, lowAdd);
   1.657 +						ProcessAlphaPixel(srcPtr16, maskPtr8, pixelPtr, pixelPtrInc, highAdd, lowAdd);
   1.658 +						ProcessAlphaPixel(srcPtr16, maskPtr8, pixelPtr, pixelPtrInc, highAdd, lowAdd);
   1.659 +						ProcessAlphaPixel(srcPtr16, maskPtr8, pixelPtr, pixelPtrInc, highAdd, lowAdd);
   1.660 +						}
   1.661 +					}
   1.662 +				}
   1.663 +
   1.664 +			if (aLength)
   1.665 +				{
   1.666 +				// Process final incomplete mask word
   1.667 +				const TUint32 maskWord = *maskWordPtr;   // this will over-read
   1.668 +				if (!maskWord)
   1.669 +					{
   1.670 +					// maskWord is fully masked	- skip the pixels
   1.671 +					return;
   1.672 +					}
   1.673 +				if (maskWord == 0xFFFFFFFF)
   1.674 +					{
   1.675 +					// maskWord is fully unmasked - copy and convert the pixels
   1.676 +					while (aLength--)
   1.677 +						{
   1.678 +						CopyPixel(srcPtr16, pixelPtr, pixelPtrInc, highAdd, lowAdd);
   1.679 +						}
   1.680 +					}
   1.681 +				else
   1.682 +					{
   1.683 +					// At least one of the pixels needs to be blended
   1.684 +					const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(&maskWord);
   1.685 +					while (aLength--)
   1.686 +						{
   1.687 +						ProcessAlphaPixel(srcPtr16, maskPtr8, pixelPtr, pixelPtrInc, highAdd, lowAdd);
   1.688 +						}
   1.689 +					}
   1.690 +				}
   1.691 +			}
   1.692 +		else
   1.693 +			{
   1.694 +			// Non-optimised path including shadowing and UserDisplayMode conversion
   1.695 +			const TUint8* maskPtr8  = reinterpret_cast<const TUint8*>(aMaskPtr) + aMaskX;
   1.696 +			while (aLength--)
   1.697 +				{
   1.698 +				TInt mask = *maskPtr8++;
   1.699 +				if (mask)
   1.700 +					{
   1.701 +					const TUint32 src = *srcPtr16;
   1.702 +					TInt r  = (src & 0xF800) >> 8;
   1.703 +					     r |= (src & 0xE000) >>13;
   1.704 +					TInt g  = (src & 0x07E0) >> 3;
   1.705 +					     g |= (src & 0x0600) >> 9;
   1.706 +					TInt b  = (src & 0x001F) << 3;
   1.707 +					     b |= (src & 0x001C) >> 2;
   1.708 +
   1.709 +					if(aShadowing == MAlphaBlend::EShdwBefore)
   1.710 +						{
   1.711 +						if (iShadowMode & EFade)
   1.712 +							{
   1.713 +							r = ((r * iFadeMapFactor) >> 8) + iFadeMapOffset;
   1.714 +							g = ((g * iFadeMapFactor) >> 8) + iFadeMapOffset;
   1.715 +							b = ((b * iFadeMapFactor) >> 8) + iFadeMapOffset;
   1.716 +							}
   1.717 +						if (iShadowMode & EShadow)
   1.718 +							{
   1.719 +							r = Max(0,r-0x40);
   1.720 +							g = Max(0,g-0x40);
   1.721 +							b = Max(0,b-0x40);
   1.722 +							}
   1.723 +						}
   1.724 +					if (mask != 0xff)
   1.725 +						{
   1.726 +						// (mask * r + (255 - mask) * value) / 255 =
   1.727 +						// ((257 * mask * (r - value)) >> 16) + value
   1.728 +						const TInt value = *pixelPtr & 0xffffff;
   1.729 +						mask = (mask << 8) + mask; // mask = mask * 257
   1.730 +						TInt v = value >> 16;
   1.731 +						r = ((mask * (r - v)) >> 16) + v;
   1.732 +						v = (value >> 8) & 0xff;
   1.733 +						g = ((mask * (g - v)) >> 16) + v;
   1.734 +						v = value & 0xff;
   1.735 +						b = ((mask * (b - v)) >> 16) + v;
   1.736 +						}
   1.737 +					if(aShadowing == MAlphaBlend::EShdwAfter)
   1.738 +						{
   1.739 +						if (iShadowMode & EFade)
   1.740 +							{  
   1.741 +							r = ((r * iFadeMapFactor) >> 8) + iFadeMapOffset;
   1.742 +							g = ((g * iFadeMapFactor) >> 8) + iFadeMapOffset;
   1.743 +							b = ((b * iFadeMapFactor) >> 8) + iFadeMapOffset;            
   1.744 +							}
   1.745 +						if (iShadowMode & EShadow)
   1.746 +							{
   1.747 +							r = Max(0,r-0x40);
   1.748 +							g = Max(0,g-0x40);
   1.749 +							b = Max(0,b-0x40);                  
   1.750 +							}
   1.751 +						}
   1.752 +					// Convert colour if an incompatible UserDisplayMode is being used
   1.753 +					CDrawBitmap::MapColorToUserDisplayMode(r,g,b);
   1.754 +					*pixelPtr = (r<<16) | (g<<8) | b | 0xff000000;
   1.755 +					}
   1.756 +				srcPtr16++;
   1.757 +				pixelPtr += pixelPtrInc;
   1.758 +				}
   1.759 +			}
   1.760 +		return;
   1.761 +		}	
   1.762 +	}
   1.763 +
   1.764 +/**
   1.765 +CDrawUTwentyFourBppBitmap::WriteMaskLineEx() implementation.
   1.766 +@internalTechnology
   1.767 +@see MFastBlit::WriteMaskLineEx()
   1.768 +*/
   1.769 +void CDrawUTwentyFourBppBitmap::WriteMaskLineEx(TInt aX, TInt aY, TInt aLength, TInt aSrcX,
   1.770 +													const TUint32* aSrcPtr,  TDisplayMode aSrcFormat,
   1.771 +													TInt aMaskX, const TUint32* aMaskPtr, TBool aInvertMask)
   1.772 +	{
   1.773 +	// Only certain pixel formats are supported.  Caller should check this.
   1.774 +	__ASSERT_DEBUG(aSrcFormat ==EColor16MU || aSrcFormat ==EColor64K, User::Invariant());
   1.775 +
   1.776 +	DeOrientate(aX,aY);
   1.777 +	TUint32* pixelPtr = PixelAddress(aX,aY);
   1.778 +	const TInt pixelPtrInc = PixelAddressIncrement();
   1.779 +	const TUint32 invertWord = (aInvertMask ? 0xFFFFFFFF : 0);  // to be XORed with the mask
   1.780 +
   1.781 +	if (aSrcFormat==EColor16MU)
   1.782 +		{
   1.783 +		aSrcPtr += aSrcX;
   1.784 +	
   1.785 +		if ((iUserDispMode==ENone) || (iUserDispMode==EColor16MU))
   1.786 +			{
   1.787 +			const TUint32* maskWordPtr = aMaskPtr + (aMaskX >> 5);
   1.788 +			const TInt startBit = aMaskX & 0x1F;
   1.789 +
   1.790 +			if (startBit)
   1.791 +				{
   1.792 +				// Process initial incomplete mask word
   1.793 +				TUint32 maskWord = *maskWordPtr++;
   1.794 +				maskWord ^= invertWord;
   1.795 +				TInt numPix = Min(aLength, 32 - startBit);  // number of pixels to process from the first word of the mask
   1.796 +				aLength -= numPix;
   1.797 +
   1.798 +				if (!maskWord)
   1.799 +					{
   1.800 +					// maskWord is fully masked - skip the pixels
   1.801 +					aSrcPtr += numPix;
   1.802 +					pixelPtr += pixelPtrInc * numPix;
   1.803 +					}
   1.804 +				else if (maskWord == 0xFFFFFFFF)
   1.805 +					{
   1.806 +					// maskWord is fully unmasked - copy the pixels
   1.807 +					while (numPix--)
   1.808 +						{
   1.809 +						*pixelPtr = *aSrcPtr++;
   1.810 +						pixelPtr += pixelPtrInc;
   1.811 +						}
   1.812 +					}
   1.813 +				else
   1.814 +					{
   1.815 +					// maskWord is partially masked - process each pixel
   1.816 +					TUint32 singleBitMask = 1 << startBit;
   1.817 +					while (numPix--)
   1.818 +						{
   1.819 +						ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.820 +						}
   1.821 +					}
   1.822 +				}
   1.823 +			
   1.824 +			TInt numMaskWords = aLength >> 5;
   1.825 +			aLength &= 0x1F;
   1.826 +			while (numMaskWords--)
   1.827 +				{
   1.828 +				// Process a complete mask word (32 pixels)
   1.829 +				TUint32 maskWord = *maskWordPtr++;
   1.830 +				maskWord ^= invertWord;
   1.831 +				
   1.832 +				if (!maskWord)
   1.833 +					{
   1.834 +					// maskWord is fully masked - skip 32 pixels
   1.835 +					aSrcPtr += 32;
   1.836 +					pixelPtr += pixelPtrInc << 5;
   1.837 +					}
   1.838 +				else if (maskWord == 0xFFFFFFFF)
   1.839 +					{
   1.840 +					// maskWord is fully unmasked - copy 32 pixels
   1.841 +					if (pixelPtrInc==1)
   1.842 +						{
   1.843 +						pixelPtr=(TUint32*)Mem::Move(pixelPtr, aSrcPtr, 128);
   1.844 +						aSrcPtr+= 32;
   1.845 +						}
   1.846 +					else
   1.847 +						{
   1.848 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.849 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.850 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.851 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.852 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.853 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.854 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.855 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.856 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.857 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.858 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.859 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.860 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.861 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.862 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.863 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.864 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.865 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.866 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.867 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.868 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.869 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.870 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.871 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.872 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.873 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.874 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.875 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.876 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.877 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.878 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.879 +						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
   1.880 +						}
   1.881 +					}
   1.882 +				else
   1.883 +					{	
   1.884 +					// maskWord is partially masked - process each of the 32 pixels
   1.885 +					TUint32 singleBitMask = 1;
   1.886 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.887 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.888 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.889 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.890 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.891 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.892 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.893 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.894 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.895 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.896 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.897 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.898 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.899 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.900 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.901 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.902 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.903 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.904 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.905 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.906 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.907 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.908 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.909 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.910 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.911 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.912 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.913 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.914 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.915 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.916 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.917 +					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.918 +					}
   1.919 +				}
   1.920 +
   1.921 +
   1.922 +			if (aLength)
   1.923 +				{
   1.924 +				// Process final incomplete mask word
   1.925 +				TUint32 maskWord = *maskWordPtr;
   1.926 +				maskWord ^= invertWord;
   1.927 +				
   1.928 +				if (!maskWord)
   1.929 +					{
   1.930 +					// maskWord is fully masked - skip the pixels
   1.931 +					return;
   1.932 +					}
   1.933 +				if (maskWord == 0xFFFFFFFF)
   1.934 +					{
   1.935 +					// maskWord is fully unmasked - copy the pixels
   1.936 +					while (aLength--)
   1.937 +						{
   1.938 +						*pixelPtr = *aSrcPtr++;
   1.939 +						pixelPtr += pixelPtrInc;
   1.940 +						}
   1.941 +					}
   1.942 +				else
   1.943 +					{
   1.944 +					// maskWord is partially masked - process each pixel
   1.945 +					TUint32 singleBitMask = 1;
   1.946 +					while (aLength--)
   1.947 +						{
   1.948 +						ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
   1.949 +						}
   1.950 +					}
   1.951 +				}
   1.952 +			}
   1.953 +		else
   1.954 +			{
   1.955 +			// Non-optimised path.  UserDisplay mode is different to the true display mode
   1.956 +			while (aLength--)
   1.957 +				{
   1.958 +				TUint32 mask = *(aMaskPtr + (aMaskX >> 5)) & (1 << (aMaskX & 0x1F));
   1.959 +				if (aInvertMask)
   1.960 +					{
   1.961 +					mask = !mask;
   1.962 +					}
   1.963 +				if (mask)
   1.964 +					{
   1.965 +					TRgb pixel(*aSrcPtr);
   1.966 +					MapColorToUserDisplayMode(pixel);
   1.967 +					*pixelPtr = pixel.Value();
   1.968 +					}
   1.969 +				aSrcPtr++;
   1.970 +				aMaskX++;
   1.971 +				pixelPtr += pixelPtrInc;
   1.972 +				}
   1.973 +			}
   1.974 +		return;
   1.975 +		}
   1.976 +	else  // (aSrcFormat==EColor64K)
   1.977 +		{
   1.978 +		const TUint16* srcPtr16 = reinterpret_cast<const TUint16*>(aSrcPtr) + aSrcX;
   1.979 +	
   1.980 +		if ((iUserDispMode==ENone) || (iUserDispMode==EColor16MU))
   1.981 +			{
   1.982 +			const TUint16* lowAdd = Convert16to32bppLow();
   1.983 +			const TUint32* highAdd = Convert16to32bppHigh();
   1.984 +			const TUint32* maskWordPtr = aMaskPtr + (aMaskX >> 5);
   1.985 +			const TInt startBit = aMaskX & 0x1F;
   1.986 +			
   1.987 +			if (startBit)
   1.988 +				{
   1.989 +				// Process initial incomplete mask word
   1.990 +				TUint32 maskWord = *maskWordPtr++;
   1.991 +				maskWord ^= invertWord;
   1.992 +				TInt numPix = Min(aLength, 32 - startBit);  // number of pixels to process from the first word of the mask
   1.993 +				aLength -= numPix;
   1.994 +				
   1.995 +				if (!maskWord)
   1.996 +					{
   1.997 +					// maskWord is fully masked	- skip the pixels
   1.998 +					srcPtr16 += numPix;
   1.999 +					pixelPtr += pixelPtrInc * numPix;
  1.1000 +					}
  1.1001 +				else if (maskWord == 0xFFFFFFFF)
  1.1002 +					{
  1.1003 +					// maskWord is fully unmasked - copy and convert the pixels
  1.1004 +					while (numPix--)
  1.1005 +						{
  1.1006 +						CopyPixel(srcPtr16, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1007 +						}
  1.1008 +					}
  1.1009 +				else
  1.1010 +					{
  1.1011 +					// maskWord is partially masked - process each of the pixels
  1.1012 +					TUint32 singleBitMask = 1 << startBit;
  1.1013 +					while (numPix--)
  1.1014 +						{
  1.1015 +						ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1016 +						}
  1.1017 +					}
  1.1018 +				}
  1.1019 +			
  1.1020 +			TInt numMaskWords = aLength >> 5;
  1.1021 +			aLength &= 0x1F;
  1.1022 +			while (numMaskWords--)
  1.1023 +				{
  1.1024 +				// Process complete mask words
  1.1025 +				TUint32 maskWord = *maskWordPtr++;
  1.1026 +				maskWord ^= invertWord;
  1.1027 +				
  1.1028 +				if (!maskWord)
  1.1029 +					{
  1.1030 +					// maskWord is fully masked - skip 32 pixels
  1.1031 +					srcPtr16 += 32;
  1.1032 +					pixelPtr += pixelPtrInc << 5;
  1.1033 +					}
  1.1034 +				else if (maskWord == 0xFFFFFFFF)
  1.1035 +					{
  1.1036 +					// maskWord is fully unmasked - copy and convert 32 pixels
  1.1037 +					const TUint32* srcPtr32 = (const TUint32*)srcPtr16;
  1.1038 +					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1039 +					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1040 +					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1041 +					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1042 +					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1043 +					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1044 +					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1045 +					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1046 +					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1047 +					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1048 +					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1049 +					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1050 +					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1051 +					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1052 +					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1053 +					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1054 +					srcPtr16 = (const TUint16*)srcPtr32;
  1.1055 +					}
  1.1056 +				else
  1.1057 +					{
  1.1058 +					// maskWord is partially masked - process each of the 32 pixels					
  1.1059 +					TUint32 singleBitMask = 1;
  1.1060 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1061 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1062 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1063 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1064 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1065 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1066 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1067 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1068 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1069 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1070 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1071 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1072 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1073 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1074 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1075 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1076 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1077 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1078 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1079 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1080 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1081 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1082 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1083 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1084 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1085 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1086 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1087 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1088 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1089 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1090 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1091 +					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1092 +					}
  1.1093 +				}
  1.1094 +			
  1.1095 +			if (aLength)
  1.1096 +				{
  1.1097 +				// Process final incomplete mask word
  1.1098 +				TUint32 maskWord = *maskWordPtr;		// this will over-read
  1.1099 +				maskWord ^= invertWord;
  1.1100 +				
  1.1101 +				if (!maskWord)
  1.1102 +					{
  1.1103 +					// maskWord is masked - skip the pixels
  1.1104 +					return;
  1.1105 +					}
  1.1106 +					
  1.1107 +				if (maskWord == 0xFFFFFFFF)
  1.1108 +					{
  1.1109 +					// maskWord is fully unmasked - copy and convert the pixels
  1.1110 +					while (aLength--)
  1.1111 +						{
  1.1112 +						CopyPixel(srcPtr16, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1113 +						}
  1.1114 +					}
  1.1115 +				else
  1.1116 +					{
  1.1117 +					// maskWord is partially masked - process each of the pixels
  1.1118 +					TUint32 singleBitMask = 1;
  1.1119 +					while (aLength--)
  1.1120 +						{
  1.1121 +						ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
  1.1122 +						}
  1.1123 +					}
  1.1124 +				}
  1.1125 +			}
  1.1126 +		else
  1.1127 +			{
  1.1128 +			// Non-optimised - expects aMaskPtr untouched and srcPtr16 to be accurate
  1.1129 +			while (aLength--)
  1.1130 +				{
  1.1131 +				TUint32 mask = *(aMaskPtr + (aMaskX >> 5)) & (1 << (aMaskX & 0x1F));
  1.1132 +				if (aInvertMask)
  1.1133 +					{
  1.1134 +					mask = !mask;
  1.1135 +					}
  1.1136 +				if (mask)
  1.1137 +					{
  1.1138 +					const TUint32 src = *srcPtr16;
  1.1139 +					TUint32 color = (src & 0xF800) << 8; // R top 5
  1.1140 +					color |= (src & 0xE000) << 3; // R bottom 3 
  1.1141 +					color |= (src & 0x07E0) << 5; // G top 6
  1.1142 +					color |= (src & 0x0600) >> 1; // G bottom 2
  1.1143 +					color |= (src & 0x001F) << 3; // B top 5
  1.1144 +					color |= (src & 0x001C) >> 2; // B bottom 3
  1.1145 +					TRgb pixel(color);
  1.1146 +					MapColorToUserDisplayMode(pixel);
  1.1147 +					*pixelPtr = pixel.Value();
  1.1148 +					}
  1.1149 +				pixelPtr += pixelPtrInc;
  1.1150 +				srcPtr16++;
  1.1151 +				aMaskX++;
  1.1152 +				}
  1.1153 +			}
  1.1154 +		return;
  1.1155 +		}
  1.1156 +	}
  1.1157 +
  1.1158 +/**
  1.1159 +Implementation for CFbsDrawDevice::GetInterface().
  1.1160 +Retrieves a pointer to a specified interface of CFbsDrawDevice implementation.
  1.1161 +@param aInterfaceId Interface identifier of the interface to be retrieved.
  1.1162 +@param aInterface Address of variable that retrieves the specified interface.
  1.1163 +@return KErrNone If the interface is supported, KErrNotSupported otherwise.
  1.1164 +*/
  1.1165 +TInt CDrawUTwentyFourBppBitmap::GetInterface(TInt aInterfaceId, TAny*& aInterface)
  1.1166 +	{
  1.1167 +	aInterface = NULL;
  1.1168 +	TInt ret = KErrNotSupported;
  1.1169 +	
  1.1170 +	switch (aInterfaceId)
  1.1171 +		{
  1.1172 +		case KFastBlitInterfaceID:
  1.1173 +			{
  1.1174 +			aInterface = static_cast<MFastBlit*>(this);
  1.1175 +			ret = KErrNone;
  1.1176 +			break;
  1.1177 +			}
  1.1178 +		default:
  1.1179 +			{
  1.1180 +			return CDrawThirtyTwoBppBitmapCommon::GetInterface(aInterfaceId, aInterface);
  1.1181 +			}
  1.1182 +		}
  1.1183 +		
  1.1184 +	return ret;
  1.1185 +	}
  1.1186 +
  1.1187 +TInt CDrawUTwentyFourBppBitmap::WriteRgbOutlineAndShadow(TInt aX, TInt aY, const TInt aLength,
  1.1188 +														TUint32 aOutlinePenColor, TUint32 aShadowColor,
  1.1189 +														TUint32 aFillColor, const TUint8* aDataBuffer)
  1.1190 +	{
  1.1191 +	DeOrientate(aX,aY);
  1.1192 +	TUint32* pixelPtr = PixelAddress(aX,aY);
  1.1193 +	const TInt pixelPtrInc = PixelAddressIncrement();
  1.1194 +	const TUint8* dataBufferPtrLimit = aDataBuffer + aLength;
  1.1195 +	TInt blendedRedColor;
  1.1196 +	TInt blendedGreenColor;
  1.1197 +	TInt blendedBlueColor;
  1.1198 +	TInt blendedAlpha;
  1.1199 +	TUint8 index = 0;
  1.1200 +	TUint32 finalColor;
  1.1201 +	const TUint16* normTable = PtrTo16BitNormalisationTable();
  1.1202 +
  1.1203 +	//Get red color. Equivalent to TRgb::Red()
  1.1204 +	const TInt redOutlinePenColor = (aOutlinePenColor & 0xff0000) >> 16;
  1.1205 +	const TInt redShadowColor = (aShadowColor & 0xff0000) >> 16;
  1.1206 +	const TInt redFillColor = (aFillColor & 0xff0000) >> 16;
  1.1207 +
  1.1208 +	//Get green color. Equivalent to TRgb::Green()
  1.1209 +	const TInt greenOutlinePenColor = (aOutlinePenColor & 0xff00) >> 8;
  1.1210 +	const TInt greenShadowColor = (aShadowColor & 0xff00) >> 8;
  1.1211 +	const TInt greenFillColor = (aFillColor & 0xff00) >> 8;
  1.1212 +
  1.1213 +	//Get blue color. Equivalent to TRgb::Blue()
  1.1214 +	const TInt blueOutlinePenColor = aOutlinePenColor & 0xff;
  1.1215 +	const TInt blueShadowColor = aShadowColor & 0xff;
  1.1216 +	const TInt blueFillColor = aFillColor & 0xff;
  1.1217 +
  1.1218 +	//Get alpha color. Equivalent to TRgb::Alpha()
  1.1219 +	const TInt alphaOutlinePenColor = aOutlinePenColor >> 24;
  1.1220 +	const TInt alphaShadowColor = aShadowColor >> 24;
  1.1221 +	const TInt alphaFillColor = aFillColor >> 24;
  1.1222 +
  1.1223 +	while (aDataBuffer < dataBufferPtrLimit)
  1.1224 +		{
  1.1225 +		index = *aDataBuffer++;
  1.1226 +		if (255 == FourColorBlendLookup[index][KBackgroundColorIndex])
  1.1227 +			{
  1.1228 +			//background colour
  1.1229 +			//No drawing required
  1.1230 +			}
  1.1231 +		else if (255 == FourColorBlendLookup[index][KFillColorIndex])
  1.1232 +			{
  1.1233 +			//Use fill colour to draw
  1.1234 +			finalColor = aFillColor;
  1.1235 +			AlphaBlendPixelToDest((finalColor | 0xff000000), alphaFillColor, pixelPtr);
  1.1236 +			}
  1.1237 +		else if (255 == FourColorBlendLookup[index][KShadowColorIndex])
  1.1238 +			{
  1.1239 +			//Use shadow colour to draw
  1.1240 +			finalColor = aShadowColor;
  1.1241 +			AlphaBlendPixelToDest((finalColor | 0xff000000), alphaShadowColor, pixelPtr);
  1.1242 +			}
  1.1243 +		else if (255 == FourColorBlendLookup[index][KOutlineColorIndex])
  1.1244 +			{
  1.1245 +			//Use outline colour to draw
  1.1246 +			finalColor = aOutlinePenColor;
  1.1247 +			AlphaBlendPixelToDest((finalColor | 0xff000000), alphaOutlinePenColor, pixelPtr);
  1.1248 +			}
  1.1249 +		else
  1.1250 +			{
  1.1251 +			blendedRedColor = (redOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] * alphaOutlinePenColor + 
  1.1252 +						   		redShadowColor * FourColorBlendLookup[index][KShadowColorIndex] * alphaShadowColor +
  1.1253 +						  		redFillColor * FourColorBlendLookup[index][KFillColorIndex] * alphaFillColor) >> 16;
  1.1254 +
  1.1255 +			blendedGreenColor = (greenOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] * alphaOutlinePenColor  + 
  1.1256 +								greenShadowColor * FourColorBlendLookup[index][KShadowColorIndex] * alphaShadowColor +
  1.1257 +								greenFillColor * FourColorBlendLookup[index][KFillColorIndex] * alphaFillColor) >> 16;
  1.1258 +
  1.1259 +			blendedBlueColor = (blueOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] * alphaOutlinePenColor  + 
  1.1260 +								blueShadowColor * FourColorBlendLookup[index][KShadowColorIndex] * alphaShadowColor +
  1.1261 +								blueFillColor * FourColorBlendLookup[index][KFillColorIndex] * alphaFillColor) >> 16;
  1.1262 +
  1.1263 +			blendedAlpha = (alphaOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] + 
  1.1264 +							alphaShadowColor * FourColorBlendLookup[index][KShadowColorIndex] +
  1.1265 +							alphaFillColor * FourColorBlendLookup[index][KFillColorIndex]) >> 8;
  1.1266 +
  1.1267 +			finalColor = PMA2NonPMAPixel((blendedAlpha << 24) | (blendedRedColor << 16) | (blendedGreenColor << 8) | blendedBlueColor, normTable);		
  1.1268 +			AlphaBlendPixelToDest(finalColor | 0xff000000, blendedAlpha, pixelPtr);
  1.1269 +			}
  1.1270 +		pixelPtr += pixelPtrInc;
  1.1271 +		}
  1.1272 +	return KErrNone;
  1.1273 +	}