os/graphics/graphicsdeviceinterface/screendriver/sbit/BMDRAW24U.CPP
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 2003-2010 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include "BMDRAW.H"
sl@0
    17
#include "BitDrawInterfaceId.h"
sl@0
    18
#include <graphics/lookuptable.h>
sl@0
    19
#include <graphics/blendingalgorithms.h>
sl@0
    20
sl@0
    21
TInt CDrawUTwentyFourBppBitmap::Construct(TSize aSize)
sl@0
    22
	{
sl@0
    23
	return Construct(aSize, aSize.iWidth << 2);
sl@0
    24
	}
sl@0
    25
sl@0
    26
TInt CDrawUTwentyFourBppBitmap::Construct(TSize aSize, TInt aStride)
sl@0
    27
	{
sl@0
    28
	iDispMode = EColor16MU;
sl@0
    29
	return CDrawThirtyTwoBppBitmapCommon::Construct(aSize, aStride);
sl@0
    30
	}
sl@0
    31
sl@0
    32
/**
sl@0
    33
MAlphaBlend::WriteRgbAlphaLine() implementation.
sl@0
    34
@see MAlphaBlend::WriteRgbAlphaLine()
sl@0
    35
*/
sl@0
    36
void CDrawUTwentyFourBppBitmap::WriteRgbAlphaLine(TInt aX, TInt aY, TInt aLength,
sl@0
    37
													const TUint8* aRgbBuffer,
sl@0
    38
													const TUint8* aMaskBuffer,
sl@0
    39
													MAlphaBlend::TShadowing aShadowing,
sl@0
    40
													CGraphicsContext::TDrawMode /*aDrawMode*/)
sl@0
    41
	{
sl@0
    42
	// precondition for this function is that the aRgbBuffer lies on a word boundary
sl@0
    43
    // Assert checks that the pointer is at a word boundary
sl@0
    44
    __ASSERT_DEBUG(!(((TUint)aRgbBuffer) & 0x3), Panic(EScreenDriverPanicInvalidPointer));
sl@0
    45
    
sl@0
    46
	DeOrientate(aX,aY);
sl@0
    47
	TUint32* pixelPtr = PixelAddress(aX,aY);
sl@0
    48
	TUint32* rgbBuffer = (TUint32*)aRgbBuffer;
sl@0
    49
	const TInt pixelPtrInc = PixelAddressIncrement();
sl@0
    50
	const TUint8* maskBufferPtrLimit = aMaskBuffer + aLength;
sl@0
    51
	
sl@0
    52
	if (!(iShadowMode & (EFade | EShadow)) && (iUserDispMode == ENone))
sl@0
    53
		{
sl@0
    54
		while (aMaskBuffer < maskBufferPtrLimit)
sl@0
    55
			{
sl@0
    56
			*pixelPtr = CalcAlphaPixel(*rgbBuffer, *aMaskBuffer, *pixelPtr);
sl@0
    57
			aMaskBuffer++;
sl@0
    58
			pixelPtr += pixelPtrInc;
sl@0
    59
			rgbBuffer++;
sl@0
    60
			}
sl@0
    61
		}
sl@0
    62
	else
sl@0
    63
		{
sl@0
    64
		while (aMaskBuffer < maskBufferPtrLimit)
sl@0
    65
			{
sl@0
    66
			TInt mask = *aMaskBuffer++;
sl@0
    67
			if (mask)
sl@0
    68
				{     
sl@0
    69
				TInt b = aRgbBuffer[0];
sl@0
    70
				TInt g = aRgbBuffer[1];
sl@0
    71
				TInt r = aRgbBuffer[2];
sl@0
    72
				if(aShadowing == MAlphaBlend::EShdwBefore)
sl@0
    73
					{
sl@0
    74
					if (iShadowMode & EFade)
sl@0
    75
						{
sl@0
    76
						r = ((r * iFadeMapFactor) >> 8) + iFadeMapOffset;
sl@0
    77
						g = ((g * iFadeMapFactor) >> 8) + iFadeMapOffset;
sl@0
    78
						b = ((b * iFadeMapFactor) >> 8) + iFadeMapOffset;
sl@0
    79
						}
sl@0
    80
					if (iShadowMode & EShadow)
sl@0
    81
						{
sl@0
    82
						r = (Max(0,r-0x40));
sl@0
    83
						g = (Max(0,g-0x40));
sl@0
    84
						b = (Max(0,b-0x40));
sl@0
    85
						}
sl@0
    86
					}
sl@0
    87
				if (mask != 0xff)
sl@0
    88
					{
sl@0
    89
					// (mask * r + (255 - mask) * value) / 255 =
sl@0
    90
					// ((257 * mask * (r - value)) >> 16) + value
sl@0
    91
					TInt value = *pixelPtr & 0xffffff;
sl@0
    92
					mask = (mask << 8) + mask; // mask = mask * 257
sl@0
    93
					TInt v = value >> 16;
sl@0
    94
					r = ((mask * (r - v)) >> 16) + v;
sl@0
    95
					v = (value >> 8) & 0xff;
sl@0
    96
					g = ((mask * (g - v)) >> 16) + v;
sl@0
    97
					v = value & 0xff;
sl@0
    98
					b = ((mask * (b - v)) >> 16) + v;
sl@0
    99
					}
sl@0
   100
				if(aShadowing == MAlphaBlend::EShdwAfter)
sl@0
   101
					{
sl@0
   102
					if (iShadowMode & EFade)
sl@0
   103
						{  
sl@0
   104
						r = ((r * iFadeMapFactor) >> 8) + iFadeMapOffset;
sl@0
   105
						g = ((g * iFadeMapFactor) >> 8) + iFadeMapOffset;
sl@0
   106
						b = ((b * iFadeMapFactor) >> 8) + iFadeMapOffset;            
sl@0
   107
						}
sl@0
   108
					if (iShadowMode & EShadow)
sl@0
   109
						{
sl@0
   110
						r = (Max(0,r-0x40));
sl@0
   111
						g = (Max(0,g-0x40));
sl@0
   112
						b = (Max(0,b-0x40));                  
sl@0
   113
						}
sl@0
   114
					}
sl@0
   115
				// Convert colour if an incompatible UserDisplayMode is being used
sl@0
   116
				CDrawBitmap::MapColorToUserDisplayMode(r,g,b);
sl@0
   117
				*pixelPtr = (r<<16) | (g<<8) | b | 0xff000000;
sl@0
   118
				}
sl@0
   119
			aRgbBuffer += 4;
sl@0
   120
			pixelPtr += pixelPtrInc;
sl@0
   121
			}
sl@0
   122
		}
sl@0
   123
	}
sl@0
   124
sl@0
   125
void CDrawUTwentyFourBppBitmap::ReadLine(TInt aX, TInt aY, TInt aLength, TAny* aBuffer, TDisplayMode aDispMode) const
sl@0
   126
	{
sl@0
   127
	if (aDispMode == EColor16MAP)
sl@0
   128
		{
sl@0
   129
		DeOrientate(aX, aY);
sl@0
   130
		CDrawThirtyTwoBppBitmapCommon::ReadLine(aX, aY, aLength, aBuffer);
sl@0
   131
		
sl@0
   132
		//Overwrite unused byte with 0xff to produce valid 16MAP data
sl@0
   133
		TUint8* alphaptr = (TUint8*) aBuffer+3;
sl@0
   134
		TUint8* bufEnd = (TUint8*) aBuffer + (aLength << 2);
sl@0
   135
		while (alphaptr < bufEnd)
sl@0
   136
			{
sl@0
   137
			*alphaptr = 0xff;
sl@0
   138
			alphaptr+=4;
sl@0
   139
			}
sl@0
   140
		
sl@0
   141
		return;
sl@0
   142
		}
sl@0
   143
	CDrawBitmap::ReadLine(aX, aY, aLength, aBuffer, aDispMode);
sl@0
   144
	}
sl@0
   145
sl@0
   146
void CDrawUTwentyFourBppBitmap::BlendRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
sl@0
   147
	{
sl@0
   148
	const TInt sourceAlpha = aColor.Alpha();
sl@0
   149
	if (sourceAlpha==255)// opaque
sl@0
   150
		{
sl@0
   151
		WriteRgbMulti(aX,aY,aLength,aHeight,aColor);
sl@0
   152
		return;
sl@0
   153
		}
sl@0
   154
	if (sourceAlpha==0)// transparent
sl@0
   155
		return;
sl@0
   156
sl@0
   157
	TUint32* pixelPtr = PixelAddress(aX,aY);
sl@0
   158
	TUint32* pixelRowPtrLimit = pixelPtr + (aHeight * iScanLineWords);
sl@0
   159
	TUint32* pixelPtrLimit = pixelPtr + aLength;
sl@0
   160
sl@0
   161
	const TUint32 sourceInternal=aColor.Internal();
sl@0
   162
	const TUint32 s_rb = sourceInternal & 0x00FF00FF;
sl@0
   163
	const TUint32 s_g = (sourceInternal & 0xFF00) >> 8;
sl@0
   164
	const TUint32 mask2 = sourceAlpha | (sourceAlpha << 16);
sl@0
   165
	while (pixelPtr < pixelRowPtrLimit)
sl@0
   166
		{
sl@0
   167
		for (TUint32* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
sl@0
   168
			{
sl@0
   169
			const TUint32 d = *tempPixelPtr;
sl@0
   170
			const TUint32 d_rb = d & 0x00FF00FF;
sl@0
   171
			const TUint32 rb = ((((sourceAlpha * ((0x01000100 + s_rb) - d_rb)) >> 8) + d_rb) - mask2) & 0x00FF00FF;
sl@0
   172
sl@0
   173
			const TInt d_g = (d & 0xFF00) >> 8;
sl@0
   174
			const TInt g = ((sourceAlpha * (s_g - d_g)) >> 8) + d_g;
sl@0
   175
	
sl@0
   176
			*tempPixelPtr = rb | (g<<8) | 0xff000000;
sl@0
   177
			}
sl@0
   178
sl@0
   179
		pixelPtr += iScanLineWords;
sl@0
   180
		pixelPtrLimit += iScanLineWords;
sl@0
   181
		}
sl@0
   182
	}
sl@0
   183
sl@0
   184
void CDrawUTwentyFourBppBitmap::BlendLine(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
sl@0
   185
	{
sl@0
   186
	TUint32* pixelPtr = PixelAddress(aX,aY);
sl@0
   187
sl@0
   188
	const TUint32* bufferPtrLimit = aBuffer + aLength;
sl@0
   189
	const TInt pixelPtrInc = (iOrientation == EOrientationNormal) ? 1 : PixelAddressIncrement();
sl@0
   190
				
sl@0
   191
	while (aBuffer < bufferPtrLimit)
sl@0
   192
		{
sl@0
   193
		if((*aBuffer &0xFF000000) == 0xFF000000)
sl@0
   194
			{
sl@0
   195
			*pixelPtr = *aBuffer;
sl@0
   196
			}
sl@0
   197
		else if((*aBuffer & 0xFF000000))
sl@0
   198
			{	
sl@0
   199
			// specialization of pre-multiplied blending when the destination alpha is always 255
sl@0
   200
			const TUint32 src_rb = *aBuffer & 0x00FF00FF;
sl@0
   201
			const TUint32 src_g = *aBuffer & 0x0000FF00;
sl@0
   202
			const TUint32 mask = 0x100 - (*aBuffer >> 24);
sl@0
   203
			TUint32 dst_rb = *pixelPtr & 0x00FF00FF;
sl@0
   204
			TUint32 dst_g = *pixelPtr & 0x0000FF00;
sl@0
   205
			dst_rb = (src_rb + ((mask * dst_rb) >> 8)) & 0x00FF00FF;
sl@0
   206
			dst_g = (src_g + ((mask * dst_g) >> 8)) & 0x0000FF00;
sl@0
   207
			*pixelPtr = 0xFF000000 | dst_rb | dst_g;
sl@0
   208
			}
sl@0
   209
			
sl@0
   210
		aBuffer++;
sl@0
   211
		pixelPtr += pixelPtrInc;
sl@0
   212
		}
sl@0
   213
	}
sl@0
   214
sl@0
   215
TRgb CDrawUTwentyFourBppBitmap::RgbColor(TUint32 aColor) const
sl@0
   216
	{
sl@0
   217
	return TRgb::_Color16MU(aColor);
sl@0
   218
	}
sl@0
   219
sl@0
   220
TUint32 CDrawUTwentyFourBppBitmap::Color(const TRgb& aColor)
sl@0
   221
	{
sl@0
   222
	return aColor._Color16MA() | 0xff000000;	
sl@0
   223
	}
sl@0
   224
sl@0
   225
sl@0
   226
// Copies an EColor64K pixel to an EColor16MU screen
sl@0
   227
FORCEINLINE static void CopyPixel(const TUint16*& aSrcPtr, TUint32*& aDestPtr, TInt aPixelPtrInc, const TUint32* aHighAdd, const TUint16* aLowAdd)
sl@0
   228
	{
sl@0
   229
	*aDestPtr = aHighAdd[(*aSrcPtr) >> 8] | aLowAdd[(*aSrcPtr) & 0xff];
sl@0
   230
	aDestPtr += aPixelPtrInc;
sl@0
   231
	aSrcPtr++;
sl@0
   232
	}
sl@0
   233
sl@0
   234
sl@0
   235
// Copies two EColor64K pixels to an EColor16MU screen
sl@0
   236
FORCEINLINE static void CopyTwoPixels(const TUint32*& aSrcPtr, TUint32*& aDestPtr, TInt aPixelPtrInc, const TUint32* aHighAdd, const TUint16* aLowAdd)
sl@0
   237
	{
sl@0
   238
	const TUint16* scanPtr = reinterpret_cast<const TUint16*&>(aSrcPtr);
sl@0
   239
	*aDestPtr = aHighAdd[(*scanPtr) >> 8] | aLowAdd[(*scanPtr) & 0xff];
sl@0
   240
 	aDestPtr += aPixelPtrInc;
sl@0
   241
	scanPtr++;
sl@0
   242
	*aDestPtr = aHighAdd[(*scanPtr) >> 8] | aLowAdd[(*scanPtr) & 0xff];
sl@0
   243
 	aDestPtr += aPixelPtrInc;
sl@0
   244
 	aSrcPtr++;
sl@0
   245
	}
sl@0
   246
sl@0
   247
sl@0
   248
// Copies an EColor16MU pixel to an EColor16MU screen if necessary.
sl@0
   249
FORCEINLINE static void ProcessMaskPixel(const TUint32*& aSrcPtr, const TUint32 aMaskWord, TUint32& aSingleBitMask, TUint32*& aDestPtr, TInt aPixelPtrInc)
sl@0
   250
	{
sl@0
   251
	if (aMaskWord & aSingleBitMask)
sl@0
   252
		{
sl@0
   253
		*aDestPtr = *aSrcPtr;
sl@0
   254
		}
sl@0
   255
	aSrcPtr++;
sl@0
   256
	aDestPtr += aPixelPtrInc;
sl@0
   257
	aSingleBitMask <<= 1;
sl@0
   258
	}
sl@0
   259
sl@0
   260
sl@0
   261
// Copies an EColor64K pixel to an EColor16MU screen if necessary.	
sl@0
   262
FORCEINLINE static void ProcessMaskPixel(const TUint16*& aSrcPtr, const TUint32 aMaskWord, TUint32& aSingleBitMask, TUint32*& aDestPtr, TInt aPixelPtrInc, const TUint32* aHighAdd, const TUint16* aLowAdd)
sl@0
   263
	{	
sl@0
   264
	if (aMaskWord & aSingleBitMask)
sl@0
   265
		{
sl@0
   266
		*aDestPtr = aHighAdd[(*aSrcPtr) >> 8] | aLowAdd[(*aSrcPtr) & 0xff];
sl@0
   267
		}
sl@0
   268
	aSrcPtr++;
sl@0
   269
	aDestPtr += aPixelPtrInc;
sl@0
   270
	aSingleBitMask <<= 1;
sl@0
   271
	}
sl@0
   272
sl@0
   273
sl@0
   274
// Alpha-blends an EColor16MU pixel to an EColor16MU screen using a fixed mask value.
sl@0
   275
FORCEINLINE static void BlendAlphaPixel(const TUint32*& aSrcPtr, const TUint8 aMask, TUint32*& aDestPtr, TInt aPixelPtrInc)
sl@0
   276
	{
sl@0
   277
	const TUint32 s = *aSrcPtr++;
sl@0
   278
	const TUint32 d = *aDestPtr;
sl@0
   279
	
sl@0
   280
	// (a)  (mask * src + (255 - mask) * dest) / 255           This ideal formula
sl@0
   281
	// (b)  ((mask * (src - dest)) >> 8) + dest                A faster approximation to (a)
sl@0
   282
	// (c)  ((mask * (256 + src - dest) >> 8) + dest - mask    Equivalent to (b) but can be used on multiple colors at a time
sl@0
   283
sl@0
   284
	const TUint32 s_rb = s & 0x00FF00FF;
sl@0
   285
	const TUint32 d_rb = d & 0x00FF00FF;
sl@0
   286
	const TUint32 mask2 = aMask | (aMask << 16);
sl@0
   287
	const TUint32 rb = ((((aMask * ((0x01000100 + s_rb) - d_rb)) >> 8) + d_rb) - mask2) & 0x00FF00FF;
sl@0
   288
sl@0
   289
	const TInt s_g = (s & 0xFF00) >> 8;
sl@0
   290
	const TInt d_g = (d & 0xFF00) >> 8;
sl@0
   291
	const TInt g = ((aMask * (s_g - d_g)) >> 8) + d_g;
sl@0
   292
	
sl@0
   293
	*aDestPtr = rb | (g<<8) | 0xff000000;
sl@0
   294
	aDestPtr += aPixelPtrInc;
sl@0
   295
	}
sl@0
   296
sl@0
   297
sl@0
   298
// Alpha-blends an EColor16MU pixel to an EColor16MU screen if necessary.	
sl@0
   299
FORCEINLINE static void ProcessAlphaPixel(const TUint32*& aSrcPtr, const TUint8*& aMaskPtr, TUint32*& aDestPtr, TInt aPixelPtrInc)
sl@0
   300
	{
sl@0
   301
	const TInt mask = *aMaskPtr++;
sl@0
   302
sl@0
   303
	if (!mask)
sl@0
   304
		{
sl@0
   305
		// pixel is masked
sl@0
   306
		aSrcPtr++;
sl@0
   307
		aDestPtr += aPixelPtrInc;
sl@0
   308
		}
sl@0
   309
	else if (mask == 0xFF)
sl@0
   310
		{
sl@0
   311
		// pixel is unmasked
sl@0
   312
		*aDestPtr = *aSrcPtr++;
sl@0
   313
		aDestPtr += aPixelPtrInc;
sl@0
   314
		}
sl@0
   315
	else
sl@0
   316
		{
sl@0
   317
		BlendAlphaPixel(aSrcPtr, mask, aDestPtr, aPixelPtrInc);
sl@0
   318
		}
sl@0
   319
	}
sl@0
   320
	
sl@0
   321
sl@0
   322
// Alpha-blends an EColor64K pixel to an EColor16MU screen using a fixed mask value.
sl@0
   323
FORCEINLINE static void BlendAlphaPixel(const TUint16*& aSrcPtr, const TUint8 aMask, TUint32*& aDestPtr, TInt aPixelPtrInc)
sl@0
   324
	{
sl@0
   325
	const TUint32 s = *aSrcPtr++;
sl@0
   326
	const TUint32 d = *aDestPtr;
sl@0
   327
	
sl@0
   328
	// convert the source EColor64K red / blue pixels to EColor16MU
sl@0
   329
	// the top two bits in EColor64K are used to fill the bottom two bits in EColor16MU
sl@0
   330
	
sl@0
   331
	const TUint32 s_rb = ((s & 0xF800) << 8) | ((s & 0xE000) << 3) | ((s & 0x1F) << 3) | ((s & 0x1C) >>2);	
sl@0
   332
	const TUint32 d_rb = d & 0x00FF00FF;
sl@0
   333
	const TUint32 mask2 = aMask | (aMask << 16);
sl@0
   334
	const TUint32 rb = ((((aMask * ((0x01000100 + s_rb) - d_rb)) >> 8) + d_rb) - mask2) & 0x00FF00FF;
sl@0
   335
	
sl@0
   336
	// convert the source EColor64K green pixel to EColor16MU
sl@0
   337
	const TInt s_g = ((s & 0x07E0) >> 3) | ((s & 0x0600) >> 9);
sl@0
   338
	const TInt d_g = (d & 0xFF00) >> 8;
sl@0
   339
	const TInt g = ((aMask * (s_g - d_g)) >> 8) + d_g;
sl@0
   340
	
sl@0
   341
	*aDestPtr = rb | (g<<8) | 0xff000000;
sl@0
   342
	aDestPtr += aPixelPtrInc;
sl@0
   343
	}
sl@0
   344
sl@0
   345
	
sl@0
   346
// Alpha-blends an EColor64K pixel to an EColor16MU screen if necessary.	
sl@0
   347
FORCEINLINE static void ProcessAlphaPixel(const TUint16*& aSrcPtr, const TUint8*& aMaskPtr, TUint32*& aDestPtr, TInt aPixelPtrInc, const TUint32* aHighAdd, const TUint16* aLowAdd)
sl@0
   348
	{
sl@0
   349
	const TInt mask = *aMaskPtr++;
sl@0
   350
sl@0
   351
	if (!mask)
sl@0
   352
		{
sl@0
   353
		// pixel is masked
sl@0
   354
		aSrcPtr++;
sl@0
   355
		aDestPtr += aPixelPtrInc;
sl@0
   356
		}
sl@0
   357
	else if (mask == 0xFF) 
sl@0
   358
		{
sl@0
   359
		// pixel is unmasked
sl@0
   360
		CopyPixel(aSrcPtr, aDestPtr, aPixelPtrInc, aHighAdd, aLowAdd);
sl@0
   361
		}
sl@0
   362
	else
sl@0
   363
		{
sl@0
   364
		BlendAlphaPixel(aSrcPtr, mask, aDestPtr, aPixelPtrInc);
sl@0
   365
		}
sl@0
   366
	}
sl@0
   367
sl@0
   368
sl@0
   369
/**
sl@0
   370
CDrawUTwentyFourBppBitmap::WriteAlphaLineEx() implementation.
sl@0
   371
@internalTechnology
sl@0
   372
@see MFastBlit::WriteAlphaLineEx()
sl@0
   373
*/
sl@0
   374
void CDrawUTwentyFourBppBitmap::WriteAlphaLineEx(TInt aX, TInt aY, TInt aLength, TInt aSrcX,
sl@0
   375
													const TUint32* aSrcPtr,  TDisplayMode aSrcFormat,
sl@0
   376
													TInt aMaskX, const TUint32* aMaskPtr,
sl@0
   377
													MAlphaBlend::TShadowing aShadowing)
sl@0
   378
	{
sl@0
   379
	// Only certain pixel formats are supported.  Caller should check this.
sl@0
   380
	__ASSERT_DEBUG(aSrcFormat ==EColor16MU || aSrcFormat ==EColor64K, User::Invariant());
sl@0
   381
	
sl@0
   382
	DeOrientate(aX,aY);
sl@0
   383
	TUint32* pixelPtr = PixelAddress(aX,aY);
sl@0
   384
	const TInt pixelPtrInc = PixelAddressIncrement();
sl@0
   385
	
sl@0
   386
	if (aSrcFormat==EColor16MU)
sl@0
   387
		{		
sl@0
   388
		if (!(iShadowMode & EFade) && !(iShadowMode & EShadow) && ((iUserDispMode==ENone) || (iUserDispMode==EColor16MU)) )
sl@0
   389
			{
sl@0
   390
			aSrcPtr += aSrcX;
sl@0
   391
			const TUint32* maskWordPtr = aMaskPtr + (aMaskX >> 2);
sl@0
   392
			const TInt startBit = aMaskX & 0x3;
sl@0
   393
			
sl@0
   394
			if (startBit)
sl@0
   395
				{
sl@0
   396
				// Process initial incomplete mask word
sl@0
   397
				const TUint32 maskWord = *maskWordPtr++;
sl@0
   398
				TInt numPix = Min(aLength, 4 - startBit);  // number of pixels to process from the first word of the mask
sl@0
   399
				aLength -= numPix;
sl@0
   400
				
sl@0
   401
				if (!maskWord)
sl@0
   402
					{
sl@0
   403
					// maskWord is fully masked - skip the pixels
sl@0
   404
					aSrcPtr += numPix;
sl@0
   405
					pixelPtr += pixelPtrInc * numPix;
sl@0
   406
					}
sl@0
   407
				else if (maskWord == 0xFFFFFFFF)
sl@0
   408
					{
sl@0
   409
					// maskWord is fully unmasked - copy the pixels
sl@0
   410
					while (numPix--)
sl@0
   411
						{
sl@0
   412
						*pixelPtr = *aSrcPtr++;
sl@0
   413
						pixelPtr += pixelPtrInc;
sl@0
   414
						}
sl@0
   415
					}
sl@0
   416
				else
sl@0
   417
					{
sl@0
   418
					// At least one of the pixels needs to be blended
sl@0
   419
					const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(&maskWord);
sl@0
   420
					maskPtr8 += startBit;
sl@0
   421
					while (numPix--)
sl@0
   422
						{
sl@0
   423
						ProcessAlphaPixel(aSrcPtr, maskPtr8, pixelPtr, pixelPtrInc);
sl@0
   424
						}
sl@0
   425
					}
sl@0
   426
				}
sl@0
   427
			
sl@0
   428
			TInt numMaskWords = aLength >> 2;
sl@0
   429
			aLength &= 0x3;
sl@0
   430
			while (numMaskWords--)
sl@0
   431
				{
sl@0
   432
				// Process a complete mask word - 4 pixels
sl@0
   433
				const TUint32 maskWord = *maskWordPtr++;
sl@0
   434
				
sl@0
   435
				if (!maskWord)
sl@0
   436
					{
sl@0
   437
					// maskWord is fully masked - skip 4 pixels
sl@0
   438
					aSrcPtr += 4;
sl@0
   439
					pixelPtr += pixelPtrInc << 2;
sl@0
   440
					}
sl@0
   441
				else if (maskWord == 0xFFFFFFFF)
sl@0
   442
					{
sl@0
   443
					// maskWord is fully unmasked - copy 4 pixels
sl@0
   444
					*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   445
					*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   446
					*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   447
					*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   448
					}
sl@0
   449
				else
sl@0
   450
					{	
sl@0
   451
					// At least one of the 4 pixels needs to be blended
sl@0
   452
					const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(&maskWord);
sl@0
   453
sl@0
   454
					if (maskPtr8[0] && (maskPtr8[0] != 0xFF) &&
sl@0
   455
						maskPtr8[1] && (maskPtr8[1] != 0xFF) &&
sl@0
   456
						maskPtr8[2] && (maskPtr8[2] != 0xFF) &&
sl@0
   457
						maskPtr8[3] && (maskPtr8[3] != 0xFF))
sl@0
   458
						{
sl@0
   459
						// Blend all 4 pixels inline
sl@0
   460
						BlendAlphaPixel(aSrcPtr, maskPtr8[0], pixelPtr, pixelPtrInc);
sl@0
   461
						BlendAlphaPixel(aSrcPtr, maskPtr8[1], pixelPtr, pixelPtrInc);
sl@0
   462
						BlendAlphaPixel(aSrcPtr, maskPtr8[2], pixelPtr, pixelPtrInc);
sl@0
   463
						BlendAlphaPixel(aSrcPtr, maskPtr8[3], pixelPtr, pixelPtrInc);
sl@0
   464
						}
sl@0
   465
					else
sl@0
   466
						{
sl@0
   467
						ProcessAlphaPixel(aSrcPtr, maskPtr8, pixelPtr, pixelPtrInc);
sl@0
   468
						ProcessAlphaPixel(aSrcPtr, maskPtr8, pixelPtr, pixelPtrInc);
sl@0
   469
						ProcessAlphaPixel(aSrcPtr, maskPtr8, pixelPtr, pixelPtrInc);
sl@0
   470
						ProcessAlphaPixel(aSrcPtr, maskPtr8, pixelPtr, pixelPtrInc);
sl@0
   471
						}
sl@0
   472
					}
sl@0
   473
				}
sl@0
   474
sl@0
   475
			if (aLength)
sl@0
   476
				{
sl@0
   477
				const TUint32 maskWord = *maskWordPtr;
sl@0
   478
				if (!maskWord)
sl@0
   479
					{
sl@0
   480
					// maskWord is fully masked - skip the pixels
sl@0
   481
					return;
sl@0
   482
					}
sl@0
   483
				if (maskWord == 0xFFFFFFFF)
sl@0
   484
					{
sl@0
   485
					// maskWord is fully unmasked - copy the pixels
sl@0
   486
					while (aLength--)
sl@0
   487
						{
sl@0
   488
						*pixelPtr = *aSrcPtr++;
sl@0
   489
						pixelPtr += pixelPtrInc;
sl@0
   490
						}
sl@0
   491
					}
sl@0
   492
				else
sl@0
   493
					{
sl@0
   494
					// At least one of the pixels needs to be blended
sl@0
   495
					const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(&maskWord);
sl@0
   496
					while (aLength--)
sl@0
   497
						{
sl@0
   498
						ProcessAlphaPixel(aSrcPtr, maskPtr8, pixelPtr, pixelPtrInc);
sl@0
   499
						}
sl@0
   500
					}
sl@0
   501
				}
sl@0
   502
			}
sl@0
   503
		else
sl@0
   504
			{
sl@0
   505
			// Non-optimised path including shadowing and UserDisplayMode conversion
sl@0
   506
			const TUint8* srcPtr8  = reinterpret_cast<const TUint8*>(aSrcPtr + aSrcX);
sl@0
   507
			const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(aMaskPtr) + aMaskX;
sl@0
   508
			
sl@0
   509
			while (aLength--)
sl@0
   510
				{
sl@0
   511
				TInt mask = *maskPtr8++;
sl@0
   512
				if (mask)
sl@0
   513
					{
sl@0
   514
					TInt b = srcPtr8[0];
sl@0
   515
					TInt g = srcPtr8[1];
sl@0
   516
					TInt r = srcPtr8[2];
sl@0
   517
					if(aShadowing == MAlphaBlend::EShdwBefore)
sl@0
   518
						{
sl@0
   519
						if (iShadowMode & EFade)
sl@0
   520
							{
sl@0
   521
							r = ((r * iFadeMapFactor) >> 8) + iFadeMapOffset;
sl@0
   522
							g = ((g * iFadeMapFactor) >> 8) + iFadeMapOffset;
sl@0
   523
							b = ((b * iFadeMapFactor) >> 8) + iFadeMapOffset;
sl@0
   524
							}
sl@0
   525
						if (iShadowMode & EShadow)
sl@0
   526
							{
sl@0
   527
							r = (Max(0,r-0x40));
sl@0
   528
							g = (Max(0,g-0x40));
sl@0
   529
							b = (Max(0,b-0x40));
sl@0
   530
							}
sl@0
   531
						}
sl@0
   532
					if (mask != 0xff)
sl@0
   533
						{
sl@0
   534
						// (mask * r + (255 - mask) * value) / 255 =
sl@0
   535
						// ((257 * mask * (r - value)) >> 16) + value
sl@0
   536
						TInt value = *pixelPtr & 0xffffff;
sl@0
   537
						mask = (mask << 8) + mask; // mask = mask * 257
sl@0
   538
						TInt v = value >> 16;
sl@0
   539
						r = ((mask * (r - v)) >> 16) + v;
sl@0
   540
						v = (value >> 8) & 0xff;
sl@0
   541
						g = ((mask * (g - v)) >> 16) + v;
sl@0
   542
						v = value & 0xff;
sl@0
   543
						b = ((mask * (b - v)) >> 16) + v;
sl@0
   544
						}
sl@0
   545
					if(aShadowing == MAlphaBlend::EShdwAfter)
sl@0
   546
						{
sl@0
   547
						if (iShadowMode & EFade)
sl@0
   548
							{  
sl@0
   549
							r = ((r * iFadeMapFactor) >> 8) + iFadeMapOffset;
sl@0
   550
							g = ((g * iFadeMapFactor) >> 8) + iFadeMapOffset;
sl@0
   551
							b = ((b * iFadeMapFactor) >> 8) + iFadeMapOffset;            
sl@0
   552
							}
sl@0
   553
						if (iShadowMode & EShadow)
sl@0
   554
							{
sl@0
   555
							r = (Max(0,r-0x40));
sl@0
   556
							g = (Max(0,g-0x40));
sl@0
   557
							b = (Max(0,b-0x40));
sl@0
   558
							}
sl@0
   559
						}
sl@0
   560
					// Convert colour if an incompatible UserDisplayMode is being used
sl@0
   561
					CDrawBitmap::MapColorToUserDisplayMode(r,g,b);
sl@0
   562
					*pixelPtr = (r<<16) | (g<<8) | b | 0xff000000;
sl@0
   563
					}
sl@0
   564
				pixelPtr += pixelPtrInc;
sl@0
   565
				srcPtr8 += 4;
sl@0
   566
				}
sl@0
   567
			}
sl@0
   568
		return;
sl@0
   569
		}
sl@0
   570
	else   // (aSrcFormat==EColor64K)
sl@0
   571
		{
sl@0
   572
		const TUint16* srcPtr16 = reinterpret_cast<const TUint16*>(aSrcPtr) + aSrcX;
sl@0
   573
		
sl@0
   574
		if (!(iShadowMode & EFade) && !(iShadowMode & EShadow) && ((iUserDispMode==ENone) || (iUserDispMode==EColor16MU)))
sl@0
   575
			{			
sl@0
   576
			const TUint16* lowAdd = Convert16to32bppLow();
sl@0
   577
			const TUint32* highAdd = Convert16to32bppHigh();
sl@0
   578
			const TUint32* maskWordPtr = aMaskPtr + (aMaskX >> 2);
sl@0
   579
			const TInt startBit = aMaskX & 0x3;
sl@0
   580
			
sl@0
   581
			if (startBit)
sl@0
   582
				{
sl@0
   583
				// Process initial incomplete mask word
sl@0
   584
				const TUint32 maskWord = *maskWordPtr++;
sl@0
   585
				TInt numPix = Min(aLength, 4 - startBit);  // number of pixels to process from the first word of the mask
sl@0
   586
				aLength -= numPix;
sl@0
   587
				
sl@0
   588
				if (!maskWord)
sl@0
   589
					{
sl@0
   590
					// maskWord is fully masked
sl@0
   591
					srcPtr16 += numPix;
sl@0
   592
					pixelPtr += pixelPtrInc * numPix;
sl@0
   593
					}
sl@0
   594
				else if (maskWord == 0xFFFFFFFF)
sl@0
   595
					{
sl@0
   596
					// maskWord is fully unmasked
sl@0
   597
					while (numPix--)
sl@0
   598
						{
sl@0
   599
						CopyPixel(srcPtr16, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
   600
						}
sl@0
   601
					}
sl@0
   602
				else
sl@0
   603
					{
sl@0
   604
					// At least one of the pixels needs to be blended
sl@0
   605
					const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(&maskWord);
sl@0
   606
					maskPtr8 += startBit;
sl@0
   607
					while (numPix--)
sl@0
   608
						{
sl@0
   609
						ProcessAlphaPixel(srcPtr16, maskPtr8, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
   610
						}
sl@0
   611
					}
sl@0
   612
				}
sl@0
   613
			
sl@0
   614
			TInt numMaskWords = aLength >> 2;
sl@0
   615
			aLength &= 0x3;
sl@0
   616
			while (numMaskWords--)
sl@0
   617
				{
sl@0
   618
				// Process 4 mask pixels
sl@0
   619
				const TUint32 maskWord = *maskWordPtr++;
sl@0
   620
				
sl@0
   621
				if (!maskWord)
sl@0
   622
					{
sl@0
   623
					// maskWord is fully masked - skip 4 pixels
sl@0
   624
					srcPtr16 += 4;
sl@0
   625
					pixelPtr += pixelPtrInc << 2;
sl@0
   626
					}
sl@0
   627
				else if (maskWord == 0xFFFFFFFF)
sl@0
   628
					{
sl@0
   629
					// maskWord is fully unmasked - copy and convert 4 pixels
sl@0
   630
					const TUint32* srcPtr32 = (const TUint32*)srcPtr16;
sl@0
   631
					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
   632
					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
   633
					srcPtr16 = (const TUint16*)srcPtr32;
sl@0
   634
					}
sl@0
   635
				else
sl@0
   636
					{	
sl@0
   637
					// At least one of the 4 pixels needs to be blended
sl@0
   638
					const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(&maskWord);
sl@0
   639
sl@0
   640
					if (maskPtr8[0] && (maskPtr8[0] != 0xFF) &&
sl@0
   641
						maskPtr8[1] && (maskPtr8[1] != 0xFF) &&
sl@0
   642
						maskPtr8[2] && (maskPtr8[2] != 0xFF) &&
sl@0
   643
						maskPtr8[3] && (maskPtr8[3] != 0xFF))
sl@0
   644
						{
sl@0
   645
						// Blend all 4 pixels inline
sl@0
   646
						BlendAlphaPixel(srcPtr16, maskPtr8[0], pixelPtr, pixelPtrInc);
sl@0
   647
						BlendAlphaPixel(srcPtr16, maskPtr8[1], pixelPtr, pixelPtrInc);
sl@0
   648
						BlendAlphaPixel(srcPtr16, maskPtr8[2], pixelPtr, pixelPtrInc);
sl@0
   649
						BlendAlphaPixel(srcPtr16, maskPtr8[3], pixelPtr, pixelPtrInc);
sl@0
   650
						}
sl@0
   651
					else
sl@0
   652
						{
sl@0
   653
						ProcessAlphaPixel(srcPtr16, maskPtr8, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
   654
						ProcessAlphaPixel(srcPtr16, maskPtr8, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
   655
						ProcessAlphaPixel(srcPtr16, maskPtr8, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
   656
						ProcessAlphaPixel(srcPtr16, maskPtr8, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
   657
						}
sl@0
   658
					}
sl@0
   659
				}
sl@0
   660
sl@0
   661
			if (aLength)
sl@0
   662
				{
sl@0
   663
				// Process final incomplete mask word
sl@0
   664
				const TUint32 maskWord = *maskWordPtr;   // this will over-read
sl@0
   665
				if (!maskWord)
sl@0
   666
					{
sl@0
   667
					// maskWord is fully masked	- skip the pixels
sl@0
   668
					return;
sl@0
   669
					}
sl@0
   670
				if (maskWord == 0xFFFFFFFF)
sl@0
   671
					{
sl@0
   672
					// maskWord is fully unmasked - copy and convert the pixels
sl@0
   673
					while (aLength--)
sl@0
   674
						{
sl@0
   675
						CopyPixel(srcPtr16, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
   676
						}
sl@0
   677
					}
sl@0
   678
				else
sl@0
   679
					{
sl@0
   680
					// At least one of the pixels needs to be blended
sl@0
   681
					const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(&maskWord);
sl@0
   682
					while (aLength--)
sl@0
   683
						{
sl@0
   684
						ProcessAlphaPixel(srcPtr16, maskPtr8, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
   685
						}
sl@0
   686
					}
sl@0
   687
				}
sl@0
   688
			}
sl@0
   689
		else
sl@0
   690
			{
sl@0
   691
			// Non-optimised path including shadowing and UserDisplayMode conversion
sl@0
   692
			const TUint8* maskPtr8  = reinterpret_cast<const TUint8*>(aMaskPtr) + aMaskX;
sl@0
   693
			while (aLength--)
sl@0
   694
				{
sl@0
   695
				TInt mask = *maskPtr8++;
sl@0
   696
				if (mask)
sl@0
   697
					{
sl@0
   698
					const TUint32 src = *srcPtr16;
sl@0
   699
					TInt r  = (src & 0xF800) >> 8;
sl@0
   700
					     r |= (src & 0xE000) >>13;
sl@0
   701
					TInt g  = (src & 0x07E0) >> 3;
sl@0
   702
					     g |= (src & 0x0600) >> 9;
sl@0
   703
					TInt b  = (src & 0x001F) << 3;
sl@0
   704
					     b |= (src & 0x001C) >> 2;
sl@0
   705
sl@0
   706
					if(aShadowing == MAlphaBlend::EShdwBefore)
sl@0
   707
						{
sl@0
   708
						if (iShadowMode & EFade)
sl@0
   709
							{
sl@0
   710
							r = ((r * iFadeMapFactor) >> 8) + iFadeMapOffset;
sl@0
   711
							g = ((g * iFadeMapFactor) >> 8) + iFadeMapOffset;
sl@0
   712
							b = ((b * iFadeMapFactor) >> 8) + iFadeMapOffset;
sl@0
   713
							}
sl@0
   714
						if (iShadowMode & EShadow)
sl@0
   715
							{
sl@0
   716
							r = Max(0,r-0x40);
sl@0
   717
							g = Max(0,g-0x40);
sl@0
   718
							b = Max(0,b-0x40);
sl@0
   719
							}
sl@0
   720
						}
sl@0
   721
					if (mask != 0xff)
sl@0
   722
						{
sl@0
   723
						// (mask * r + (255 - mask) * value) / 255 =
sl@0
   724
						// ((257 * mask * (r - value)) >> 16) + value
sl@0
   725
						const TInt value = *pixelPtr & 0xffffff;
sl@0
   726
						mask = (mask << 8) + mask; // mask = mask * 257
sl@0
   727
						TInt v = value >> 16;
sl@0
   728
						r = ((mask * (r - v)) >> 16) + v;
sl@0
   729
						v = (value >> 8) & 0xff;
sl@0
   730
						g = ((mask * (g - v)) >> 16) + v;
sl@0
   731
						v = value & 0xff;
sl@0
   732
						b = ((mask * (b - v)) >> 16) + v;
sl@0
   733
						}
sl@0
   734
					if(aShadowing == MAlphaBlend::EShdwAfter)
sl@0
   735
						{
sl@0
   736
						if (iShadowMode & EFade)
sl@0
   737
							{  
sl@0
   738
							r = ((r * iFadeMapFactor) >> 8) + iFadeMapOffset;
sl@0
   739
							g = ((g * iFadeMapFactor) >> 8) + iFadeMapOffset;
sl@0
   740
							b = ((b * iFadeMapFactor) >> 8) + iFadeMapOffset;            
sl@0
   741
							}
sl@0
   742
						if (iShadowMode & EShadow)
sl@0
   743
							{
sl@0
   744
							r = Max(0,r-0x40);
sl@0
   745
							g = Max(0,g-0x40);
sl@0
   746
							b = Max(0,b-0x40);                  
sl@0
   747
							}
sl@0
   748
						}
sl@0
   749
					// Convert colour if an incompatible UserDisplayMode is being used
sl@0
   750
					CDrawBitmap::MapColorToUserDisplayMode(r,g,b);
sl@0
   751
					*pixelPtr = (r<<16) | (g<<8) | b | 0xff000000;
sl@0
   752
					}
sl@0
   753
				srcPtr16++;
sl@0
   754
				pixelPtr += pixelPtrInc;
sl@0
   755
				}
sl@0
   756
			}
sl@0
   757
		return;
sl@0
   758
		}	
sl@0
   759
	}
sl@0
   760
sl@0
   761
/**
sl@0
   762
CDrawUTwentyFourBppBitmap::WriteMaskLineEx() implementation.
sl@0
   763
@internalTechnology
sl@0
   764
@see MFastBlit::WriteMaskLineEx()
sl@0
   765
*/
sl@0
   766
void CDrawUTwentyFourBppBitmap::WriteMaskLineEx(TInt aX, TInt aY, TInt aLength, TInt aSrcX,
sl@0
   767
													const TUint32* aSrcPtr,  TDisplayMode aSrcFormat,
sl@0
   768
													TInt aMaskX, const TUint32* aMaskPtr, TBool aInvertMask)
sl@0
   769
	{
sl@0
   770
	// Only certain pixel formats are supported.  Caller should check this.
sl@0
   771
	__ASSERT_DEBUG(aSrcFormat ==EColor16MU || aSrcFormat ==EColor64K, User::Invariant());
sl@0
   772
sl@0
   773
	DeOrientate(aX,aY);
sl@0
   774
	TUint32* pixelPtr = PixelAddress(aX,aY);
sl@0
   775
	const TInt pixelPtrInc = PixelAddressIncrement();
sl@0
   776
	const TUint32 invertWord = (aInvertMask ? 0xFFFFFFFF : 0);  // to be XORed with the mask
sl@0
   777
sl@0
   778
	if (aSrcFormat==EColor16MU)
sl@0
   779
		{
sl@0
   780
		aSrcPtr += aSrcX;
sl@0
   781
	
sl@0
   782
		if ((iUserDispMode==ENone) || (iUserDispMode==EColor16MU))
sl@0
   783
			{
sl@0
   784
			const TUint32* maskWordPtr = aMaskPtr + (aMaskX >> 5);
sl@0
   785
			const TInt startBit = aMaskX & 0x1F;
sl@0
   786
sl@0
   787
			if (startBit)
sl@0
   788
				{
sl@0
   789
				// Process initial incomplete mask word
sl@0
   790
				TUint32 maskWord = *maskWordPtr++;
sl@0
   791
				maskWord ^= invertWord;
sl@0
   792
				TInt numPix = Min(aLength, 32 - startBit);  // number of pixels to process from the first word of the mask
sl@0
   793
				aLength -= numPix;
sl@0
   794
sl@0
   795
				if (!maskWord)
sl@0
   796
					{
sl@0
   797
					// maskWord is fully masked - skip the pixels
sl@0
   798
					aSrcPtr += numPix;
sl@0
   799
					pixelPtr += pixelPtrInc * numPix;
sl@0
   800
					}
sl@0
   801
				else if (maskWord == 0xFFFFFFFF)
sl@0
   802
					{
sl@0
   803
					// maskWord is fully unmasked - copy the pixels
sl@0
   804
					while (numPix--)
sl@0
   805
						{
sl@0
   806
						*pixelPtr = *aSrcPtr++;
sl@0
   807
						pixelPtr += pixelPtrInc;
sl@0
   808
						}
sl@0
   809
					}
sl@0
   810
				else
sl@0
   811
					{
sl@0
   812
					// maskWord is partially masked - process each pixel
sl@0
   813
					TUint32 singleBitMask = 1 << startBit;
sl@0
   814
					while (numPix--)
sl@0
   815
						{
sl@0
   816
						ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   817
						}
sl@0
   818
					}
sl@0
   819
				}
sl@0
   820
			
sl@0
   821
			TInt numMaskWords = aLength >> 5;
sl@0
   822
			aLength &= 0x1F;
sl@0
   823
			while (numMaskWords--)
sl@0
   824
				{
sl@0
   825
				// Process a complete mask word (32 pixels)
sl@0
   826
				TUint32 maskWord = *maskWordPtr++;
sl@0
   827
				maskWord ^= invertWord;
sl@0
   828
				
sl@0
   829
				if (!maskWord)
sl@0
   830
					{
sl@0
   831
					// maskWord is fully masked - skip 32 pixels
sl@0
   832
					aSrcPtr += 32;
sl@0
   833
					pixelPtr += pixelPtrInc << 5;
sl@0
   834
					}
sl@0
   835
				else if (maskWord == 0xFFFFFFFF)
sl@0
   836
					{
sl@0
   837
					// maskWord is fully unmasked - copy 32 pixels
sl@0
   838
					if (pixelPtrInc==1)
sl@0
   839
						{
sl@0
   840
						pixelPtr=(TUint32*)Mem::Move(pixelPtr, aSrcPtr, 128);
sl@0
   841
						aSrcPtr+= 32;
sl@0
   842
						}
sl@0
   843
					else
sl@0
   844
						{
sl@0
   845
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   846
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   847
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   848
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   849
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   850
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   851
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   852
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   853
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   854
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   855
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   856
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   857
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   858
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   859
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   860
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   861
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   862
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   863
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   864
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   865
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   866
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   867
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   868
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   869
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   870
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   871
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   872
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   873
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   874
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   875
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   876
						*pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
sl@0
   877
						}
sl@0
   878
					}
sl@0
   879
				else
sl@0
   880
					{	
sl@0
   881
					// maskWord is partially masked - process each of the 32 pixels
sl@0
   882
					TUint32 singleBitMask = 1;
sl@0
   883
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   884
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   885
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   886
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   887
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   888
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   889
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   890
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   891
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   892
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   893
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   894
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   895
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   896
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   897
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   898
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   899
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   900
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   901
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   902
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   903
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   904
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   905
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   906
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   907
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   908
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   909
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   910
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   911
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   912
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   913
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   914
					ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   915
					}
sl@0
   916
				}
sl@0
   917
sl@0
   918
sl@0
   919
			if (aLength)
sl@0
   920
				{
sl@0
   921
				// Process final incomplete mask word
sl@0
   922
				TUint32 maskWord = *maskWordPtr;
sl@0
   923
				maskWord ^= invertWord;
sl@0
   924
				
sl@0
   925
				if (!maskWord)
sl@0
   926
					{
sl@0
   927
					// maskWord is fully masked - skip the pixels
sl@0
   928
					return;
sl@0
   929
					}
sl@0
   930
				if (maskWord == 0xFFFFFFFF)
sl@0
   931
					{
sl@0
   932
					// maskWord is fully unmasked - copy the pixels
sl@0
   933
					while (aLength--)
sl@0
   934
						{
sl@0
   935
						*pixelPtr = *aSrcPtr++;
sl@0
   936
						pixelPtr += pixelPtrInc;
sl@0
   937
						}
sl@0
   938
					}
sl@0
   939
				else
sl@0
   940
					{
sl@0
   941
					// maskWord is partially masked - process each pixel
sl@0
   942
					TUint32 singleBitMask = 1;
sl@0
   943
					while (aLength--)
sl@0
   944
						{
sl@0
   945
						ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
sl@0
   946
						}
sl@0
   947
					}
sl@0
   948
				}
sl@0
   949
			}
sl@0
   950
		else
sl@0
   951
			{
sl@0
   952
			// Non-optimised path.  UserDisplay mode is different to the true display mode
sl@0
   953
			while (aLength--)
sl@0
   954
				{
sl@0
   955
				TUint32 mask = *(aMaskPtr + (aMaskX >> 5)) & (1 << (aMaskX & 0x1F));
sl@0
   956
				if (aInvertMask)
sl@0
   957
					{
sl@0
   958
					mask = !mask;
sl@0
   959
					}
sl@0
   960
				if (mask)
sl@0
   961
					{
sl@0
   962
					TRgb pixel(*aSrcPtr);
sl@0
   963
					MapColorToUserDisplayMode(pixel);
sl@0
   964
					*pixelPtr = pixel.Value();
sl@0
   965
					}
sl@0
   966
				aSrcPtr++;
sl@0
   967
				aMaskX++;
sl@0
   968
				pixelPtr += pixelPtrInc;
sl@0
   969
				}
sl@0
   970
			}
sl@0
   971
		return;
sl@0
   972
		}
sl@0
   973
	else  // (aSrcFormat==EColor64K)
sl@0
   974
		{
sl@0
   975
		const TUint16* srcPtr16 = reinterpret_cast<const TUint16*>(aSrcPtr) + aSrcX;
sl@0
   976
	
sl@0
   977
		if ((iUserDispMode==ENone) || (iUserDispMode==EColor16MU))
sl@0
   978
			{
sl@0
   979
			const TUint16* lowAdd = Convert16to32bppLow();
sl@0
   980
			const TUint32* highAdd = Convert16to32bppHigh();
sl@0
   981
			const TUint32* maskWordPtr = aMaskPtr + (aMaskX >> 5);
sl@0
   982
			const TInt startBit = aMaskX & 0x1F;
sl@0
   983
			
sl@0
   984
			if (startBit)
sl@0
   985
				{
sl@0
   986
				// Process initial incomplete mask word
sl@0
   987
				TUint32 maskWord = *maskWordPtr++;
sl@0
   988
				maskWord ^= invertWord;
sl@0
   989
				TInt numPix = Min(aLength, 32 - startBit);  // number of pixels to process from the first word of the mask
sl@0
   990
				aLength -= numPix;
sl@0
   991
				
sl@0
   992
				if (!maskWord)
sl@0
   993
					{
sl@0
   994
					// maskWord is fully masked	- skip the pixels
sl@0
   995
					srcPtr16 += numPix;
sl@0
   996
					pixelPtr += pixelPtrInc * numPix;
sl@0
   997
					}
sl@0
   998
				else if (maskWord == 0xFFFFFFFF)
sl@0
   999
					{
sl@0
  1000
					// maskWord is fully unmasked - copy and convert the pixels
sl@0
  1001
					while (numPix--)
sl@0
  1002
						{
sl@0
  1003
						CopyPixel(srcPtr16, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1004
						}
sl@0
  1005
					}
sl@0
  1006
				else
sl@0
  1007
					{
sl@0
  1008
					// maskWord is partially masked - process each of the pixels
sl@0
  1009
					TUint32 singleBitMask = 1 << startBit;
sl@0
  1010
					while (numPix--)
sl@0
  1011
						{
sl@0
  1012
						ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1013
						}
sl@0
  1014
					}
sl@0
  1015
				}
sl@0
  1016
			
sl@0
  1017
			TInt numMaskWords = aLength >> 5;
sl@0
  1018
			aLength &= 0x1F;
sl@0
  1019
			while (numMaskWords--)
sl@0
  1020
				{
sl@0
  1021
				// Process complete mask words
sl@0
  1022
				TUint32 maskWord = *maskWordPtr++;
sl@0
  1023
				maskWord ^= invertWord;
sl@0
  1024
				
sl@0
  1025
				if (!maskWord)
sl@0
  1026
					{
sl@0
  1027
					// maskWord is fully masked - skip 32 pixels
sl@0
  1028
					srcPtr16 += 32;
sl@0
  1029
					pixelPtr += pixelPtrInc << 5;
sl@0
  1030
					}
sl@0
  1031
				else if (maskWord == 0xFFFFFFFF)
sl@0
  1032
					{
sl@0
  1033
					// maskWord is fully unmasked - copy and convert 32 pixels
sl@0
  1034
					const TUint32* srcPtr32 = (const TUint32*)srcPtr16;
sl@0
  1035
					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1036
					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1037
					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1038
					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1039
					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1040
					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1041
					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1042
					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1043
					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1044
					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1045
					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1046
					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1047
					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1048
					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1049
					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1050
					CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1051
					srcPtr16 = (const TUint16*)srcPtr32;
sl@0
  1052
					}
sl@0
  1053
				else
sl@0
  1054
					{
sl@0
  1055
					// maskWord is partially masked - process each of the 32 pixels					
sl@0
  1056
					TUint32 singleBitMask = 1;
sl@0
  1057
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1058
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1059
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1060
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1061
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1062
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1063
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1064
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1065
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1066
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1067
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1068
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1069
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1070
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1071
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1072
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1073
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1074
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1075
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1076
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1077
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1078
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1079
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1080
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1081
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1082
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1083
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1084
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1085
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1086
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1087
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1088
					ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1089
					}
sl@0
  1090
				}
sl@0
  1091
			
sl@0
  1092
			if (aLength)
sl@0
  1093
				{
sl@0
  1094
				// Process final incomplete mask word
sl@0
  1095
				TUint32 maskWord = *maskWordPtr;		// this will over-read
sl@0
  1096
				maskWord ^= invertWord;
sl@0
  1097
				
sl@0
  1098
				if (!maskWord)
sl@0
  1099
					{
sl@0
  1100
					// maskWord is masked - skip the pixels
sl@0
  1101
					return;
sl@0
  1102
					}
sl@0
  1103
					
sl@0
  1104
				if (maskWord == 0xFFFFFFFF)
sl@0
  1105
					{
sl@0
  1106
					// maskWord is fully unmasked - copy and convert the pixels
sl@0
  1107
					while (aLength--)
sl@0
  1108
						{
sl@0
  1109
						CopyPixel(srcPtr16, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1110
						}
sl@0
  1111
					}
sl@0
  1112
				else
sl@0
  1113
					{
sl@0
  1114
					// maskWord is partially masked - process each of the pixels
sl@0
  1115
					TUint32 singleBitMask = 1;
sl@0
  1116
					while (aLength--)
sl@0
  1117
						{
sl@0
  1118
						ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
sl@0
  1119
						}
sl@0
  1120
					}
sl@0
  1121
				}
sl@0
  1122
			}
sl@0
  1123
		else
sl@0
  1124
			{
sl@0
  1125
			// Non-optimised - expects aMaskPtr untouched and srcPtr16 to be accurate
sl@0
  1126
			while (aLength--)
sl@0
  1127
				{
sl@0
  1128
				TUint32 mask = *(aMaskPtr + (aMaskX >> 5)) & (1 << (aMaskX & 0x1F));
sl@0
  1129
				if (aInvertMask)
sl@0
  1130
					{
sl@0
  1131
					mask = !mask;
sl@0
  1132
					}
sl@0
  1133
				if (mask)
sl@0
  1134
					{
sl@0
  1135
					const TUint32 src = *srcPtr16;
sl@0
  1136
					TUint32 color = (src & 0xF800) << 8; // R top 5
sl@0
  1137
					color |= (src & 0xE000) << 3; // R bottom 3 
sl@0
  1138
					color |= (src & 0x07E0) << 5; // G top 6
sl@0
  1139
					color |= (src & 0x0600) >> 1; // G bottom 2
sl@0
  1140
					color |= (src & 0x001F) << 3; // B top 5
sl@0
  1141
					color |= (src & 0x001C) >> 2; // B bottom 3
sl@0
  1142
					TRgb pixel(color);
sl@0
  1143
					MapColorToUserDisplayMode(pixel);
sl@0
  1144
					*pixelPtr = pixel.Value();
sl@0
  1145
					}
sl@0
  1146
				pixelPtr += pixelPtrInc;
sl@0
  1147
				srcPtr16++;
sl@0
  1148
				aMaskX++;
sl@0
  1149
				}
sl@0
  1150
			}
sl@0
  1151
		return;
sl@0
  1152
		}
sl@0
  1153
	}
sl@0
  1154
sl@0
  1155
/**
sl@0
  1156
Implementation for CFbsDrawDevice::GetInterface().
sl@0
  1157
Retrieves a pointer to a specified interface of CFbsDrawDevice implementation.
sl@0
  1158
@param aInterfaceId Interface identifier of the interface to be retrieved.
sl@0
  1159
@param aInterface Address of variable that retrieves the specified interface.
sl@0
  1160
@return KErrNone If the interface is supported, KErrNotSupported otherwise.
sl@0
  1161
*/
sl@0
  1162
TInt CDrawUTwentyFourBppBitmap::GetInterface(TInt aInterfaceId, TAny*& aInterface)
sl@0
  1163
	{
sl@0
  1164
	aInterface = NULL;
sl@0
  1165
	TInt ret = KErrNotSupported;
sl@0
  1166
	
sl@0
  1167
	switch (aInterfaceId)
sl@0
  1168
		{
sl@0
  1169
		case KFastBlitInterfaceID:
sl@0
  1170
			{
sl@0
  1171
			aInterface = static_cast<MFastBlit*>(this);
sl@0
  1172
			ret = KErrNone;
sl@0
  1173
			break;
sl@0
  1174
			}
sl@0
  1175
		default:
sl@0
  1176
			{
sl@0
  1177
			return CDrawThirtyTwoBppBitmapCommon::GetInterface(aInterfaceId, aInterface);
sl@0
  1178
			}
sl@0
  1179
		}
sl@0
  1180
		
sl@0
  1181
	return ret;
sl@0
  1182
	}
sl@0
  1183
sl@0
  1184
TInt CDrawUTwentyFourBppBitmap::WriteRgbOutlineAndShadow(TInt aX, TInt aY, const TInt aLength,
sl@0
  1185
														TUint32 aOutlinePenColor, TUint32 aShadowColor,
sl@0
  1186
														TUint32 aFillColor, const TUint8* aDataBuffer)
sl@0
  1187
	{
sl@0
  1188
	DeOrientate(aX,aY);
sl@0
  1189
	TUint32* pixelPtr = PixelAddress(aX,aY);
sl@0
  1190
	const TInt pixelPtrInc = PixelAddressIncrement();
sl@0
  1191
	const TUint8* dataBufferPtrLimit = aDataBuffer + aLength;
sl@0
  1192
	TInt blendedRedColor;
sl@0
  1193
	TInt blendedGreenColor;
sl@0
  1194
	TInt blendedBlueColor;
sl@0
  1195
	TInt blendedAlpha;
sl@0
  1196
	TUint8 index = 0;
sl@0
  1197
	TUint32 finalColor;
sl@0
  1198
	const TUint16* normTable = PtrTo16BitNormalisationTable();
sl@0
  1199
sl@0
  1200
	//Get red color. Equivalent to TRgb::Red()
sl@0
  1201
	const TInt redOutlinePenColor = (aOutlinePenColor & 0xff0000) >> 16;
sl@0
  1202
	const TInt redShadowColor = (aShadowColor & 0xff0000) >> 16;
sl@0
  1203
	const TInt redFillColor = (aFillColor & 0xff0000) >> 16;
sl@0
  1204
sl@0
  1205
	//Get green color. Equivalent to TRgb::Green()
sl@0
  1206
	const TInt greenOutlinePenColor = (aOutlinePenColor & 0xff00) >> 8;
sl@0
  1207
	const TInt greenShadowColor = (aShadowColor & 0xff00) >> 8;
sl@0
  1208
	const TInt greenFillColor = (aFillColor & 0xff00) >> 8;
sl@0
  1209
sl@0
  1210
	//Get blue color. Equivalent to TRgb::Blue()
sl@0
  1211
	const TInt blueOutlinePenColor = aOutlinePenColor & 0xff;
sl@0
  1212
	const TInt blueShadowColor = aShadowColor & 0xff;
sl@0
  1213
	const TInt blueFillColor = aFillColor & 0xff;
sl@0
  1214
sl@0
  1215
	//Get alpha color. Equivalent to TRgb::Alpha()
sl@0
  1216
	const TInt alphaOutlinePenColor = aOutlinePenColor >> 24;
sl@0
  1217
	const TInt alphaShadowColor = aShadowColor >> 24;
sl@0
  1218
	const TInt alphaFillColor = aFillColor >> 24;
sl@0
  1219
sl@0
  1220
	while (aDataBuffer < dataBufferPtrLimit)
sl@0
  1221
		{
sl@0
  1222
		index = *aDataBuffer++;
sl@0
  1223
		if (255 == FourColorBlendLookup[index][KBackgroundColorIndex])
sl@0
  1224
			{
sl@0
  1225
			//background colour
sl@0
  1226
			//No drawing required
sl@0
  1227
			}
sl@0
  1228
		else if (255 == FourColorBlendLookup[index][KFillColorIndex])
sl@0
  1229
			{
sl@0
  1230
			//Use fill colour to draw
sl@0
  1231
			finalColor = aFillColor;
sl@0
  1232
			AlphaBlendPixelToDest((finalColor | 0xff000000), alphaFillColor, pixelPtr);
sl@0
  1233
			}
sl@0
  1234
		else if (255 == FourColorBlendLookup[index][KShadowColorIndex])
sl@0
  1235
			{
sl@0
  1236
			//Use shadow colour to draw
sl@0
  1237
			finalColor = aShadowColor;
sl@0
  1238
			AlphaBlendPixelToDest((finalColor | 0xff000000), alphaShadowColor, pixelPtr);
sl@0
  1239
			}
sl@0
  1240
		else if (255 == FourColorBlendLookup[index][KOutlineColorIndex])
sl@0
  1241
			{
sl@0
  1242
			//Use outline colour to draw
sl@0
  1243
			finalColor = aOutlinePenColor;
sl@0
  1244
			AlphaBlendPixelToDest((finalColor | 0xff000000), alphaOutlinePenColor, pixelPtr);
sl@0
  1245
			}
sl@0
  1246
		else
sl@0
  1247
			{
sl@0
  1248
			blendedRedColor = (redOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] * alphaOutlinePenColor + 
sl@0
  1249
						   		redShadowColor * FourColorBlendLookup[index][KShadowColorIndex] * alphaShadowColor +
sl@0
  1250
						  		redFillColor * FourColorBlendLookup[index][KFillColorIndex] * alphaFillColor) >> 16;
sl@0
  1251
sl@0
  1252
			blendedGreenColor = (greenOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] * alphaOutlinePenColor  + 
sl@0
  1253
								greenShadowColor * FourColorBlendLookup[index][KShadowColorIndex] * alphaShadowColor +
sl@0
  1254
								greenFillColor * FourColorBlendLookup[index][KFillColorIndex] * alphaFillColor) >> 16;
sl@0
  1255
sl@0
  1256
			blendedBlueColor = (blueOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] * alphaOutlinePenColor  + 
sl@0
  1257
								blueShadowColor * FourColorBlendLookup[index][KShadowColorIndex] * alphaShadowColor +
sl@0
  1258
								blueFillColor * FourColorBlendLookup[index][KFillColorIndex] * alphaFillColor) >> 16;
sl@0
  1259
sl@0
  1260
			blendedAlpha = (alphaOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] + 
sl@0
  1261
							alphaShadowColor * FourColorBlendLookup[index][KShadowColorIndex] +
sl@0
  1262
							alphaFillColor * FourColorBlendLookup[index][KFillColorIndex]) >> 8;
sl@0
  1263
sl@0
  1264
			finalColor = PMA2NonPMAPixel((blendedAlpha << 24) | (blendedRedColor << 16) | (blendedGreenColor << 8) | blendedBlueColor, normTable);		
sl@0
  1265
			AlphaBlendPixelToDest(finalColor | 0xff000000, blendedAlpha, pixelPtr);
sl@0
  1266
			}
sl@0
  1267
		pixelPtr += pixelPtrInc;
sl@0
  1268
		}
sl@0
  1269
	return KErrNone;
sl@0
  1270
	}