os/graphics/graphicsdeviceinterface/screendriver/sbit/BMDRAW2.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 1997-2009 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
sl@0
    18
GLREF_D const TUint32 wordlutab[256];
sl@0
    19
sl@0
    20
const TInt KBitsPerPixel = 2;
sl@0
    21
const TInt KPixelsPerByte = 4;
sl@0
    22
const TInt KPixelsPerWord = 16;
sl@0
    23
sl@0
    24
//Initializes iSize, iDrawRect, iLongWidth, iScanlineWords data members.
sl@0
    25
//It should be called every time when iSize is going to be changed - from Construct().
sl@0
    26
//@param aSize Physical screen size in pixels.
sl@0
    27
//@panic EScreenDriverPanicInvalidSize - Invalid aSize parameter. This might happen if the 
sl@0
    28
//device is scaled and the scaling origin goes outside physical drawing rectangle.
sl@0
    29
void CDrawTwoBppBitmap::SetSize(const TSize& aSize) 
sl@0
    30
	{
sl@0
    31
	CDrawBitmap::SetSize(aSize);
sl@0
    32
	__ASSERT_DEBUG(iSize == aSize, User::Invariant());
sl@0
    33
	iLongWidth = (iSize.iWidth + (KPixelsPerWord - 1)) & ~(KPixelsPerWord - 1);
sl@0
    34
	iScanLineWords = iLongWidth / KPixelsPerWord;
sl@0
    35
	}
sl@0
    36
 
sl@0
    37
TInt CDrawTwoBppBitmap::Construct(TSize aSize)
sl@0
    38
	{
sl@0
    39
	return Construct(aSize, ((aSize.iWidth + (KPixelsPerWord - 1)) & ~(KPixelsPerWord - 1)) / KPixelsPerByte);
sl@0
    40
	}
sl@0
    41
sl@0
    42
TInt CDrawTwoBppBitmap::Construct(TSize aSize, TInt aStride)
sl@0
    43
	{
sl@0
    44
	iBits = NULL;
sl@0
    45
	iDispMode = EGray4;
sl@0
    46
	CDrawBitmap::SetSize(aSize);
sl@0
    47
	__ASSERT_DEBUG(iSize == aSize, User::Invariant());
sl@0
    48
	if (aStride & 3)
sl@0
    49
		return KErrArgument;
sl@0
    50
	iLongWidth = aStride * KPixelsPerByte;
sl@0
    51
	if (iLongWidth < aSize.iWidth)
sl@0
    52
		return KErrArgument;
sl@0
    53
	iScanLineWords = aStride >> 2;
sl@0
    54
	TInt size = 1 + (Max(aSize.iWidth,aSize.iHeight) >> 2);
sl@0
    55
	if(size < 0)
sl@0
    56
		return KErrArgument;
sl@0
    57
	iScanLineBuffer = (TUint32*)(User::Heap().Alloc(size));
sl@0
    58
	if (iScanLineBuffer == NULL)
sl@0
    59
		return KErrNoMemory;
sl@0
    60
	return KErrNone;
sl@0
    61
	}
sl@0
    62
sl@0
    63
void CDrawTwoBppBitmap::Shadow(TRgb& aColor)
sl@0
    64
	{
sl@0
    65
	if (iShadowMode & EFade)
sl@0
    66
		aColor = TRgb::_Gray256(FadeGray(aColor._Gray16() * 17));
sl@0
    67
sl@0
    68
	if (iShadowMode & EShadow)
sl@0
    69
		{
sl@0
    70
		TInt gray16 = aColor._Gray16();
sl@0
    71
		gray16 = Max(gray16 - 5,0);
sl@0
    72
		aColor = TRgb::_Gray16(gray16);
sl@0
    73
		}
sl@0
    74
	}
sl@0
    75
sl@0
    76
TUint32 CDrawTwoBppBitmap::ColorInt(TRgb aColor) const
sl@0
    77
	{
sl@0
    78
	TUint32 colorWord = aColor._Gray4();
sl@0
    79
sl@0
    80
	colorWord |= colorWord << 2;
sl@0
    81
	colorWord |= colorWord << 4;
sl@0
    82
	colorWord |= colorWord << 8;
sl@0
    83
	colorWord |= colorWord << 16;
sl@0
    84
sl@0
    85
	return colorWord;
sl@0
    86
	}
sl@0
    87
sl@0
    88
void CDrawTwoBppBitmap::HashInt(TUint32& aInt1,TUint32& aInt2,TRgb aColor,TInt aX,TInt aY) const
sl@0
    89
	{
sl@0
    90
	TUint32 int1 = Hash(aColor._Gray16(),aX,aY);
sl@0
    91
	TUint32 int2 = Hash(aColor._Gray16(),aX + 1,aY);
sl@0
    92
	aInt1 = (int1 >> 2) | (int2 & 0xc);
sl@0
    93
sl@0
    94
	aInt1 |= aInt1 << 4;
sl@0
    95
	aInt1 |= aInt1 << 8;
sl@0
    96
	aInt1 |= aInt1 << 16;
sl@0
    97
sl@0
    98
	int1 = Hash(aColor._Gray16(),aX,aY + 1);
sl@0
    99
	int2 = Hash(aColor._Gray16(),aX + 1,aY + 1);
sl@0
   100
	aInt2 = (int1 >> 2) | (int2 & 0xc);
sl@0
   101
sl@0
   102
	aInt2 |= aInt2 << 4;
sl@0
   103
	aInt2 |= aInt2 << 8;
sl@0
   104
	aInt2 |= aInt2 << 16;
sl@0
   105
	}
sl@0
   106
sl@0
   107
void CDrawTwoBppBitmap::InvertBuffer(TInt aLength,TUint32* aBuffer)
sl@0
   108
	{
sl@0
   109
	const TUint32* const limit = aBuffer + ((aLength + KPixelsPerWord - 1) / KPixelsPerWord);
sl@0
   110
sl@0
   111
	while (aBuffer < limit)
sl@0
   112
		*aBuffer++ ^= 0xffffffff;
sl@0
   113
	}
sl@0
   114
sl@0
   115
void CDrawTwoBppBitmap::MapColors(const TRect& aRect,const TRgb* aColors,TInt aNumPairs,TBool aMapForwards)
sl@0
   116
	{
sl@0
   117
	__ASSERT_DEBUG(aRect.iTl.iX>=0 && aRect.iBr.iX<=iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds));
sl@0
   118
	__ASSERT_DEBUG(aRect.iTl.iY>=0 && aRect.iBr.iY<=iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds));
sl@0
   119
	__ASSERT_DEBUG(aColors,Panic(EScreenDriverPanicNullPointer));
sl@0
   120
	__ASSERT_DEBUG(aNumPairs>0,Panic(EScreenDriverPanicZeroLength));
sl@0
   121
sl@0
   122
	const TInt offset = aMapForwards ? 0 : 1;
sl@0
   123
	TUint32* colorMap;
sl@0
   124
	TUint32 evenColorMap[4];
sl@0
   125
	TUint32 oddColorMap[4];
sl@0
   126
sl@0
   127
	for (TInt colorIndex = 0; colorIndex <= 3; colorIndex++)
sl@0
   128
		{
sl@0
   129
		evenColorMap[colorIndex] = ColorInt(TRgb::_Gray4(colorIndex));
sl@0
   130
		oddColorMap[colorIndex] = evenColorMap[colorIndex];
sl@0
   131
		}
sl@0
   132
sl@0
   133
	for (TInt index = 0; index < 4; index++)
sl@0
   134
		{
sl@0
   135
		for (TInt paircount = 0; paircount < aNumPairs; paircount++)
sl@0
   136
			{
sl@0
   137
			if (aColors[(paircount * 2) + offset]._Gray4() == index)
sl@0
   138
				{
sl@0
   139
				HashInt(evenColorMap[index],oddColorMap[index],aColors[(paircount * 2) + 1 - offset],0,0);
sl@0
   140
				break;
sl@0
   141
				}
sl@0
   142
			}
sl@0
   143
		}
sl@0
   144
sl@0
   145
	TInt x = aRect.iTl.iX;
sl@0
   146
	TInt y = aRect.iTl.iY;
sl@0
   147
	TInt startLong = (aRect.iTl.iX + KPixelsPerWord - 1) & (~0xf);
sl@0
   148
	TInt finishLong = aRect.iBr.iX & (~0xf);
sl@0
   149
	TInt startShift = (startLong - x) * KBitsPerPixel;
sl@0
   150
	TInt finishShift = (KPixelsPerWord - aRect.iBr.iX + finishLong) * KBitsPerPixel;
sl@0
   151
	TUint32* base = ScanLine(y);
sl@0
   152
	TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
sl@0
   153
	TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
sl@0
   154
sl@0
   155
	if (y & 1)
sl@0
   156
		colorMap = oddColorMap;
sl@0
   157
	else
sl@0
   158
		colorMap = evenColorMap;
sl@0
   159
sl@0
   160
	if (finishLong < startLong)
sl@0
   161
		{
sl@0
   162
		const TUint32 mask = (0xffffffff >> finishShift) & (0xffffffff << (32 - startShift));
sl@0
   163
		const TUint32 invertedMask = ~mask;
sl@0
   164
sl@0
   165
		for (; y < aRect.iBr.iY; y++)
sl@0
   166
			{
sl@0
   167
			TUint32 newcolor = MapInt(pixelPtrLimit[0],colorMap) & mask;
sl@0
   168
sl@0
   169
			pixelPtrLimit[0] &= invertedMask;
sl@0
   170
			pixelPtrLimit[0] |= newcolor;
sl@0
   171
			pixelPtrLimit += iScanLineWords;
sl@0
   172
sl@0
   173
			if (colorMap == oddColorMap)
sl@0
   174
				colorMap = evenColorMap;
sl@0
   175
			else
sl@0
   176
				colorMap = oddColorMap;
sl@0
   177
			}
sl@0
   178
sl@0
   179
		return;
sl@0
   180
		}
sl@0
   181
sl@0
   182
	for (; y < aRect.iBr.iY; y++)
sl@0
   183
		{
sl@0
   184
		if (x < startLong)
sl@0
   185
			{
sl@0
   186
			TUint32 newcolor = MapInt(pixelPtr[-1],colorMap);
sl@0
   187
			pixelPtr[-1] = PasteInt(pixelPtr[-1],newcolor,startShift);
sl@0
   188
			}
sl@0
   189
sl@0
   190
		for (TUint32* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
sl@0
   191
			tempPixelPtr[0] = MapInt(tempPixelPtr[0],colorMap);
sl@0
   192
sl@0
   193
		if (finishLong < aRect.iBr.iX)
sl@0
   194
			{
sl@0
   195
			TUint32 newcolor = MapInt(pixelPtrLimit[0],colorMap);
sl@0
   196
			pixelPtrLimit[0] = PasteInt(newcolor,pixelPtrLimit[0],finishShift);
sl@0
   197
			}
sl@0
   198
sl@0
   199
		base += iScanLineWords;
sl@0
   200
		pixelPtr += iScanLineWords;
sl@0
   201
		pixelPtrLimit += iScanLineWords;
sl@0
   202
sl@0
   203
		if (colorMap == oddColorMap)
sl@0
   204
			colorMap = evenColorMap;
sl@0
   205
		else
sl@0
   206
			colorMap = oddColorMap;
sl@0
   207
		}
sl@0
   208
	}
sl@0
   209
sl@0
   210
TUint32 CDrawTwoBppBitmap::MapInt(TUint32 aInt,TUint32* aColorMap) const
sl@0
   211
	{
sl@0
   212
	TUint32 mask = 3;
sl@0
   213
	TUint32 newInt = 0;
sl@0
   214
sl@0
   215
	while (mask)
sl@0
   216
		{
sl@0
   217
		newInt |= mask & (aColorMap[aInt & 3]);
sl@0
   218
		aInt >>= 2;
sl@0
   219
		mask <<= 2;
sl@0
   220
		}
sl@0
   221
sl@0
   222
	return newInt;
sl@0
   223
	}
sl@0
   224
sl@0
   225
/**	Copies a number of pixels into a word-aligned buffer without format translation.
sl@0
   226
	Note that the byte length to the target buffer is honoured, 
sl@0
   227
 	but the end contents of the last byte are generally overwritten with extra pixel data (or garbage)  
sl@0
   228
 	Note that I am assuming the compiler optimiser will convert all these divides and multiplies into shifts!  
sl@0
   229
@param	aX		x coordinate to start copy from (need not be aligned at all)
sl@0
   230
@param	aY		y coordinate to copy line from	
sl@0
   231
@param	aLength	number of pixels to copy  
sl@0
   232
@param	aBuffer	target word-aligned buffer (but may or may not be word length) 
sl@0
   233
 **/
sl@0
   234
void CDrawTwoBppBitmap::ReadLine(TInt aX,TInt aY,TInt aLength,TAny* aBuffer) const
sl@0
   235
	{
sl@0
   236
	TUint32* pixelPtr = ScanLine(aY);
sl@0
   237
	TInt startLongPix = aX & -KPixelsPerWord;
sl@0
   238
	pixelPtr += startLongPix / KPixelsPerWord;
sl@0
   239
	TUint32* bufferPtr = (TUint32*)aBuffer;
sl@0
   240
	TInt wordsCnt = (aLength+KPixelsPerByte-1) / KPixelsPerWord;		//how many words to write to target
sl@0
   241
	TInt restPixels = aLength - wordsCnt * KPixelsPerWord;				//how many pixels left to copy
sl@0
   242
	TInt bytesCnt = (restPixels+KPixelsPerByte-1) / KPixelsPerByte ;	//how many target bytes to copy
sl@0
   243
	TInt shiftBits = aX - startLongPix;
sl@0
   244
	restPixels=shiftBits+restPixels;	//How many pixels are read from the second word by the final word copy
sl@0
   245
	if (bytesCnt==0 && shiftBits && restPixels<=0)
sl@0
   246
		{
sl@0
   247
		// This correction is required because although a last whole word will be written to the target buffer,
sl@0
   248
		// this special test indicates that the required significant data bits plus the shift 
sl@0
   249
		// add up to one word (or less) to be read. 
sl@0
   250
		// The copy words optimisation used to copy the main body of the line 
sl@0
   251
		// will read from the next location after the copy, 
sl@0
   252
		// but this may not always be accessable memory (on the last scanline)
sl@0
   253
		// The correction is not required if the second word would need to be read anyway.
sl@0
   254
		//eg we want to copy 7 nibbles with a 1 nibble shift (16 color), restpixels would be 0
sl@0
   255
		bytesCnt=4;
sl@0
   256
		wordsCnt--;
sl@0
   257
		}
sl@0
   258
	//How many pixels are read from the second word in the final byte copy?
sl@0
   259
	//If zero (or less) then the second word should not be read in the copy bytes phase
sl@0
   260
	//really this should be an else of the if above, but this gives the same end condition.
sl@0
   261
	//eg we want to copy 5 nibbles with a 2 nibble shift (16 color), restpixels would be -1.
sl@0
   262
	restPixels-=KPixelsPerWord;	
sl@0
   263
	ReadLineCommon(pixelPtr,bufferPtr,wordsCnt,restPixels,bytesCnt,shiftBits*KBitsPerPixel);
sl@0
   264
	}
sl@0
   265
sl@0
   266
sl@0
   267
TRgb CDrawTwoBppBitmap::ReadRgbNormal(TInt aX,TInt aY) const
sl@0
   268
	{
sl@0
   269
	TUint32 colorWord = *(ScanLine(aY) + (aX / KPixelsPerWord));
sl@0
   270
	colorWord >>= ((aX & 0xf) * KBitsPerPixel);
sl@0
   271
	return TRgb::_Gray4(colorWord & 3);
sl@0
   272
	}
sl@0
   273
sl@0
   274
TUint32 CDrawTwoBppBitmap::ShadowWord(TUint32 aWord)
sl@0
   275
	{
sl@0
   276
	TUint32 decrement = (0xaaaaaaaa & aWord) >> 1;
sl@0
   277
	decrement |= (0x55555555 & aWord);  // decrement is OR of each pair of bits
sl@0
   278
	return aWord - decrement; // Only shadow pixels greater than zero (decrement == 1)
sl@0
   279
	}
sl@0
   280
sl@0
   281
TUint32 CDrawTwoBppBitmap::FadeWord(TUint32 aWord)
sl@0
   282
	{
sl@0
   283
	const TInt fadeArray[4] = { FadeGray(0) >> 6, FadeGray(85) >> 6, FadeGray(170) >> 6, FadeGray(255) >> 6 };
sl@0
   284
sl@0
   285
	TUint32 fadedWord = 0;
sl@0
   286
sl@0
   287
	for (TInt bitShift = 0; bitShift < 32; bitShift += 2)
sl@0
   288
		fadedWord |= fadeArray[(aWord >> bitShift) & 3] << bitShift;
sl@0
   289
sl@0
   290
	return fadedWord;
sl@0
   291
	}
sl@0
   292
sl@0
   293
void CDrawTwoBppBitmap::ShadowArea(const TRect& aRect)
sl@0
   294
	{
sl@0
   295
	__ASSERT_DEBUG(aRect.iTl.iX>=0 && aRect.iBr.iX<=iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds));
sl@0
   296
	__ASSERT_DEBUG(aRect.iTl.iY>=0 && aRect.iBr.iY<=iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds));
sl@0
   297
sl@0
   298
	const TInt startLong = (aRect.iTl.iX + KPixelsPerWord - 1) & ~0xf;
sl@0
   299
	const TInt finishLong = aRect.iBr.iX & ~0xf;
sl@0
   300
	const TInt startShift = (startLong - aRect.iTl.iX) * KBitsPerPixel;
sl@0
   301
	const TInt finishShift = (KPixelsPerWord - aRect.iBr.iX + finishLong) * KBitsPerPixel;
sl@0
   302
	TUint32* base = ScanLine(aRect.iTl.iY);
sl@0
   303
sl@0
   304
	if (iShadowMode & EFade)
sl@0
   305
		{
sl@0
   306
		if (finishLong < startLong)
sl@0
   307
			{
sl@0
   308
			TUint32* pixelPtr = base + (finishLong / KPixelsPerWord);
sl@0
   309
			const TUint32* const pixelPtrRowLimit = pixelPtr + (aRect.Height() * iScanLineWords);
sl@0
   310
sl@0
   311
			const TUint32 mask = (0xffffffff >> finishShift) & (0xffffffff << (32 - startShift));
sl@0
   312
			const TUint32 inverseMask = ~mask;
sl@0
   313
sl@0
   314
			while (pixelPtr < pixelPtrRowLimit)
sl@0
   315
				{
sl@0
   316
				TUint32 shadowed = FadeWord(pixelPtr[0]) & mask;
sl@0
   317
sl@0
   318
				pixelPtr[0] &= inverseMask;
sl@0
   319
				pixelPtr[0] |= shadowed;
sl@0
   320
sl@0
   321
				pixelPtr += iScanLineWords;
sl@0
   322
				}
sl@0
   323
			}
sl@0
   324
		else
sl@0
   325
			{
sl@0
   326
			TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
sl@0
   327
			TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
sl@0
   328
			const TUint32* const pixelPtrRowLimit = pixelPtr + (aRect.Height() * iScanLineWords);
sl@0
   329
sl@0
   330
			while (pixelPtr < pixelPtrRowLimit)
sl@0
   331
				{
sl@0
   332
				if (aRect.iTl.iX < startLong)
sl@0
   333
					pixelPtr[-1] = PasteInt(pixelPtr[-1],FadeWord(pixelPtr[-1]),startShift);
sl@0
   334
sl@0
   335
				for (TUint32* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
sl@0
   336
					tempPixelPtr[0] = FadeWord(tempPixelPtr[0]);
sl@0
   337
sl@0
   338
				if (finishLong < aRect.iBr.iX)
sl@0
   339
					pixelPtrLimit[0] = PasteInt(FadeWord(pixelPtrLimit[0]),pixelPtrLimit[0],finishShift);
sl@0
   340
sl@0
   341
				pixelPtr += iScanLineWords;
sl@0
   342
				pixelPtrLimit += iScanLineWords;
sl@0
   343
				}
sl@0
   344
			}
sl@0
   345
		}
sl@0
   346
sl@0
   347
	if (iShadowMode & EShadow)
sl@0
   348
		{
sl@0
   349
		if (finishLong < startLong)
sl@0
   350
			{
sl@0
   351
			TUint32* pixelPtr = base + (finishLong / KPixelsPerWord);
sl@0
   352
			const TUint32* const pixelPtrRowLimit = pixelPtr + (aRect.Height() * iScanLineWords);
sl@0
   353
sl@0
   354
			const TUint32 mask = (0xffffffff >> finishShift) & (0xffffffff << (32 - startShift));
sl@0
   355
			const TUint32 inverseMask = ~mask;
sl@0
   356
sl@0
   357
			while (pixelPtr < pixelPtrRowLimit)
sl@0
   358
				{
sl@0
   359
				TUint32 shadowed = ShadowWord(pixelPtr[0]) & mask;
sl@0
   360
sl@0
   361
				pixelPtr[0] &= inverseMask;
sl@0
   362
				pixelPtr[0] |= shadowed;
sl@0
   363
sl@0
   364
				pixelPtr += iScanLineWords;
sl@0
   365
				}
sl@0
   366
			}
sl@0
   367
		else
sl@0
   368
			{
sl@0
   369
			TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
sl@0
   370
			TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
sl@0
   371
			const TUint32* const pixelPtrRowLimit = pixelPtr + (aRect.Height() * iScanLineWords);
sl@0
   372
sl@0
   373
			while (pixelPtr < pixelPtrRowLimit)
sl@0
   374
				{
sl@0
   375
				if (aRect.iTl.iX < startLong)
sl@0
   376
					pixelPtr[-1] = PasteInt(pixelPtr[-1],ShadowWord(pixelPtr[-1]),startShift);
sl@0
   377
sl@0
   378
				for (TUint32* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
sl@0
   379
					tempPixelPtr[0] = ShadowWord(tempPixelPtr[0]);
sl@0
   380
sl@0
   381
				if (finishLong < aRect.iBr.iX)
sl@0
   382
					pixelPtrLimit[0] = PasteInt(ShadowWord(pixelPtrLimit[0]),pixelPtrLimit[0],finishShift);
sl@0
   383
sl@0
   384
				pixelPtr += iScanLineWords;
sl@0
   385
				pixelPtrLimit += iScanLineWords;
sl@0
   386
				}
sl@0
   387
			}
sl@0
   388
		}
sl@0
   389
	}
sl@0
   390
sl@0
   391
void CDrawTwoBppBitmap::ShadeBuffer(TInt aLength,TUint32* aBuffer)
sl@0
   392
	{
sl@0
   393
	const TUint32* limit = aBuffer + ((aLength + KPixelsPerWord - 1) / KPixelsPerWord);
sl@0
   394
sl@0
   395
	while (aBuffer < limit)
sl@0
   396
		{
sl@0
   397
		TUint32 secondbit = (0xaaaaaaaa & aBuffer[0]);
sl@0
   398
		*aBuffer++ = secondbit | (secondbit >> 1);
sl@0
   399
		}
sl@0
   400
	}
sl@0
   401
sl@0
   402
void CDrawTwoBppBitmap::ShadowBuffer(TInt aLength,TUint32* aBuffer)
sl@0
   403
	{
sl@0
   404
	__ASSERT_DEBUG(aBuffer != NULL,Panic(EScreenDriverPanicInvalidParameter));
sl@0
   405
sl@0
   406
	const TUint32* limit = aBuffer + ((aLength + KPixelsPerWord - 1) / KPixelsPerWord);
sl@0
   407
sl@0
   408
	if (iShadowMode & EFade)
sl@0
   409
		{
sl@0
   410
		for (TUint32* buffer = aBuffer; buffer < limit; buffer++)
sl@0
   411
			buffer[0] = FadeWord(buffer[0]);
sl@0
   412
		}
sl@0
   413
sl@0
   414
	if (iShadowMode & EShadow)
sl@0
   415
		{
sl@0
   416
		for (TUint32* buffer = aBuffer; buffer < limit; buffer++)
sl@0
   417
			buffer[0] = ShadowWord(buffer[0]);
sl@0
   418
		}
sl@0
   419
	}
sl@0
   420
sl@0
   421
void CDrawTwoBppBitmap::WriteRgb(TInt aX,TInt aY,TRgb aColor)
sl@0
   422
	{
sl@0
   423
	TInt col=0;
sl@0
   424
sl@0
   425
	if (iUserDispMode != EGray2)
sl@0
   426
		col = Hash(aColor._Gray16(),aX,aY) >> 2;
sl@0
   427
	else
sl@0
   428
		{
sl@0
   429
		if (aColor._Gray2())
sl@0
   430
			col = 3;
sl@0
   431
		}
sl@0
   432
sl@0
   433
	TUint32* pixelPtr = ScanLine(aY) + (aX / KPixelsPerWord);
sl@0
   434
	const TInt shift = (aX & 0xf) * KBitsPerPixel;
sl@0
   435
	pixelPtr[0] &= ~(3 << shift);
sl@0
   436
	pixelPtr[0] |= col << shift;
sl@0
   437
	}
sl@0
   438
sl@0
   439
void CDrawTwoBppBitmap::WriteBinary(TInt aX,TInt aY,TUint32* aData,TInt aLength,TInt aHeight,TRgb aColor)
sl@0
   440
	{
sl@0
   441
	if (iUserDispMode == EGray2)
sl@0
   442
		aColor = TRgb::_Gray2(aColor._Gray2());
sl@0
   443
sl@0
   444
	const TBool monoText = (aColor == KRgbBlack);
sl@0
   445
sl@0
   446
	const TInt previousLong = aX & (~0xf);
sl@0
   447
	const TInt bitShift = (aX - previousLong) * KBitsPerPixel;
sl@0
   448
	const TBool secondwordenable = (aX + aLength) > (previousLong + KPixelsPerWord);
sl@0
   449
	TUint32* pixelPtr = ScanLine(aY) + (aX / KPixelsPerWord);
sl@0
   450
	const TInt mask = 0xffffffff >> (32 - aLength);
sl@0
   451
	TUint32* datalimit = aData + aHeight;
sl@0
   452
sl@0
   453
	if (monoText && !secondwordenable)
sl@0
   454
		{
sl@0
   455
		while (aData < datalimit)
sl@0
   456
			{
sl@0
   457
			TUint32 dataitem = *aData++;
sl@0
   458
			dataitem &= mask;
sl@0
   459
			TUint32 firsthalf = wordlutab[dataitem & 0xff];
sl@0
   460
			firsthalf |= wordlutab[(dataitem >> 8) & 0xff] << 16;
sl@0
   461
			*pixelPtr &= ~(firsthalf << bitShift);
sl@0
   462
			pixelPtr += iScanLineWords;
sl@0
   463
			}
sl@0
   464
		return;
sl@0
   465
		}
sl@0
   466
sl@0
   467
	const TInt reverseshift = 32 - bitShift;
sl@0
   468
	const TBool thirdwordenable = (aX + aLength) > (previousLong + 32);
sl@0
   469
sl@0
   470
	if (monoText)
sl@0
   471
		{
sl@0
   472
		while (aData < datalimit)
sl@0
   473
			{
sl@0
   474
			TUint32 dataitem = *aData++;
sl@0
   475
			dataitem &= mask;
sl@0
   476
			TUint32 firsthalf = wordlutab[dataitem & 0xff];
sl@0
   477
			dataitem >>= 8;
sl@0
   478
			firsthalf |= wordlutab[dataitem & 0xff] << 16;
sl@0
   479
			dataitem >>= 8;
sl@0
   480
			TUint32 secondhalf = wordlutab[dataitem & 0xff];
sl@0
   481
			dataitem >>= 8;
sl@0
   482
			secondhalf |= wordlutab[dataitem & 0xff] << 16;
sl@0
   483
			const TUint32 firstword = firsthalf << bitShift;
sl@0
   484
			TUint32 secondword = secondhalf << bitShift;
sl@0
   485
			TUint32 thirdword = 0;
sl@0
   486
sl@0
   487
			if (bitShift)
sl@0
   488
				{
sl@0
   489
				secondword |= firsthalf >> reverseshift;
sl@0
   490
				thirdword = secondhalf >> reverseshift;
sl@0
   491
				}
sl@0
   492
sl@0
   493
			pixelPtr[0] &= ~firstword;
sl@0
   494
			pixelPtr[1] &= ~secondword;
sl@0
   495
			pixelPtr[2] &= ~thirdword;
sl@0
   496
			pixelPtr += iScanLineWords;
sl@0
   497
			}
sl@0
   498
		}
sl@0
   499
	else
sl@0
   500
		{
sl@0
   501
		TUint32 colorWord1,colorWord2;
sl@0
   502
		HashInt(colorWord1,colorWord2,aColor,0,aY);
sl@0
   503
		TUint32 colorWord = colorWord1;
sl@0
   504
sl@0
   505
		while (aData < datalimit)
sl@0
   506
			{
sl@0
   507
			TUint32 dataitem = *aData++;
sl@0
   508
			dataitem &= mask;
sl@0
   509
			TUint32 firsthalf = wordlutab[dataitem & 0xff];
sl@0
   510
			dataitem >>= 8;
sl@0
   511
			firsthalf |= wordlutab[dataitem & 0xff] << 16;
sl@0
   512
			dataitem >>= 8;
sl@0
   513
			TUint32 secondhalf = wordlutab[dataitem & 0xff];
sl@0
   514
			dataitem >>= 8;
sl@0
   515
			secondhalf |= wordlutab[dataitem & 0xff] << 16;
sl@0
   516
			TUint32 firstword = firsthalf << bitShift;
sl@0
   517
			TUint32 secondword = secondhalf << bitShift;
sl@0
   518
			TUint32 thirdword = 0;
sl@0
   519
sl@0
   520
			if (bitShift)
sl@0
   521
				{
sl@0
   522
				secondword |= firsthalf >> reverseshift;
sl@0
   523
				thirdword = secondhalf >> reverseshift;
sl@0
   524
				}
sl@0
   525
sl@0
   526
			pixelPtr[0] &= ~firstword;
sl@0
   527
			if (secondwordenable)
sl@0
   528
				pixelPtr[1] &= ~secondword;
sl@0
   529
			if (thirdwordenable)
sl@0
   530
				pixelPtr[2] &= ~thirdword;
sl@0
   531
sl@0
   532
			if (colorWord)
sl@0
   533
				{
sl@0
   534
				pixelPtr[0] |= firstword & colorWord;
sl@0
   535
				if (secondwordenable)
sl@0
   536
					pixelPtr[1] |= secondword & colorWord;
sl@0
   537
				if (thirdwordenable)
sl@0
   538
					pixelPtr[2] |= thirdword & colorWord;
sl@0
   539
				}
sl@0
   540
sl@0
   541
			if (colorWord == colorWord1)
sl@0
   542
				colorWord = colorWord2;
sl@0
   543
			else
sl@0
   544
				colorWord = colorWord1;
sl@0
   545
sl@0
   546
			pixelPtr += iScanLineWords;
sl@0
   547
			}
sl@0
   548
		}
sl@0
   549
	}
sl@0
   550
sl@0
   551
void CDrawTwoBppBitmap::WriteBinaryOp(TInt aX,TInt aY,TUint32* aData,TInt aLength,TInt aHeight,TRgb aColor,CGraphicsContext::TDrawMode aDrawMode)
sl@0
   552
	{
sl@0
   553
	if (iUserDispMode == EGray2)
sl@0
   554
		aColor = TRgb::_Gray2(aColor._Gray2());
sl@0
   555
sl@0
   556
	TUint32 colorWord1,colorWord2;
sl@0
   557
	HashInt(colorWord1,colorWord2,aColor,0,aY);
sl@0
   558
	TUint32 colorWord = colorWord1;
sl@0
   559
	TUint32* pixelPtr = ScanLine(aY) + (aX / KPixelsPerWord);
sl@0
   560
	const TUint32* pixelPtrLimit = ScanLine(aY + aHeight) + (aX / KPixelsPerWord);
sl@0
   561
	const TUint32 initialMask = (3 << ((aX & 0xf) * KBitsPerPixel));
sl@0
   562
sl@0
   563
	if (colorWord1 || colorWord2)
sl@0
   564
		{
sl@0
   565
		while (pixelPtr < pixelPtrLimit)
sl@0
   566
			{
sl@0
   567
			TUint32 dataMask = 1;
sl@0
   568
			TUint32 mask = initialMask;
sl@0
   569
			TUint32* tempPixelPtr = pixelPtr;
sl@0
   570
sl@0
   571
			for (TInt count = 0; count < aLength; count++,dataMask <<= 1,mask <<= 2)
sl@0
   572
				{
sl@0
   573
				if (!mask)
sl@0
   574
					{
sl@0
   575
					mask = 3;
sl@0
   576
					tempPixelPtr++;
sl@0
   577
					}
sl@0
   578
sl@0
   579
				if (aData[0] & dataMask)
sl@0
   580
					{
sl@0
   581
					if (aDrawMode == CGraphicsContext::EDrawModeXOR)
sl@0
   582
						tempPixelPtr[0] ^= mask & colorWord;
sl@0
   583
					else if (aDrawMode == CGraphicsContext::EDrawModeAND)
sl@0
   584
						tempPixelPtr[0] &= (mask & colorWord) | ~mask;
sl@0
   585
					else if (aDrawMode == CGraphicsContext::EDrawModeOR)
sl@0
   586
						tempPixelPtr[0] |= mask & colorWord;
sl@0
   587
					}
sl@0
   588
				}
sl@0
   589
sl@0
   590
			aData++;
sl@0
   591
			pixelPtr += iScanLineWords;
sl@0
   592
			colorWord = (colorWord == colorWord1) ? colorWord2 : colorWord1;
sl@0
   593
			}
sl@0
   594
		}
sl@0
   595
	else
sl@0
   596
		{
sl@0
   597
		if (aDrawMode == CGraphicsContext::EDrawModeAND)
sl@0
   598
			{
sl@0
   599
			while (pixelPtr < pixelPtrLimit)
sl@0
   600
				{
sl@0
   601
				TUint32 dataMask = 1;
sl@0
   602
				TUint32 mask = initialMask;
sl@0
   603
				TUint32* tempPixelPtr = pixelPtr;
sl@0
   604
sl@0
   605
				for (TInt count = 0; count < aLength; count++,dataMask <<= 1,mask <<= 2)
sl@0
   606
					{
sl@0
   607
					if (!mask)
sl@0
   608
						{
sl@0
   609
						mask = 3;
sl@0
   610
						tempPixelPtr++;
sl@0
   611
						}
sl@0
   612
sl@0
   613
					if (aData[0] & dataMask)
sl@0
   614
						tempPixelPtr[0] &= ~mask;
sl@0
   615
					}
sl@0
   616
sl@0
   617
				aData++;
sl@0
   618
				pixelPtr += iScanLineWords;
sl@0
   619
				}
sl@0
   620
			}
sl@0
   621
		}
sl@0
   622
	}
sl@0
   623
sl@0
   624
void CDrawTwoBppBitmap::WriteBinaryLineVertical(TInt aX,TInt aY,TUint32* aData,TInt aHeight,TRgb aColor,TBool aUp)
sl@0
   625
	{
sl@0
   626
	if (iUserDispMode == EGray2)
sl@0
   627
		aColor = TRgb::_Gray2(aColor._Gray2());
sl@0
   628
sl@0
   629
	TUint32 col1 = Hash(aColor._Gray16(),aX,aY) / 4;
sl@0
   630
	TUint32 col2 = Hash(aColor._Gray16(),aX,aY + 1) / 4;
sl@0
   631
	const TInt yLimit = aY + (aUp ? -aHeight : aHeight);
sl@0
   632
	const TInt scanlinediff = aUp ? -iScanLineWords : iScanLineWords;
sl@0
   633
	const TInt startWord = aX / KPixelsPerWord;
sl@0
   634
	const TInt startShift = (aX & 0xf) * KBitsPerPixel;
sl@0
   635
	TUint32* pixelPtr = ScanLine(aY) + startWord;
sl@0
   636
	TUint32* pixelPtrLimit = ScanLine(yLimit) + startWord;
sl@0
   637
	const TUint32 mask = ~(3 << startShift);
sl@0
   638
	TUint32 dataMask = 1;
sl@0
   639
sl@0
   640
	if (col1 || col2)
sl@0
   641
		{
sl@0
   642
		col1 <<= startShift;
sl@0
   643
		col2 <<= startShift;
sl@0
   644
		TUint32 col = col1;
sl@0
   645
sl@0
   646
		while (pixelPtr != pixelPtrLimit)
sl@0
   647
			{
sl@0
   648
			if (!dataMask)
sl@0
   649
				{
sl@0
   650
				dataMask = 1;
sl@0
   651
				aData++;
sl@0
   652
				}
sl@0
   653
sl@0
   654
			if (aData[0] & dataMask)
sl@0
   655
				{
sl@0
   656
				pixelPtr[0] &= mask;
sl@0
   657
				pixelPtr[0] |= col;
sl@0
   658
				}
sl@0
   659
sl@0
   660
			dataMask <<= 1;
sl@0
   661
			pixelPtr += scanlinediff;
sl@0
   662
			col = (col == col2) ? col1 : col2;
sl@0
   663
			}
sl@0
   664
		}
sl@0
   665
	else
sl@0
   666
		{
sl@0
   667
		while (pixelPtr != pixelPtrLimit)
sl@0
   668
			{
sl@0
   669
			if (!dataMask)
sl@0
   670
				{
sl@0
   671
				dataMask = 1;
sl@0
   672
				aData++;
sl@0
   673
				}
sl@0
   674
sl@0
   675
			if (aData[0] & dataMask)
sl@0
   676
				pixelPtr[0] &= mask;
sl@0
   677
sl@0
   678
			dataMask <<= 1;
sl@0
   679
			pixelPtr += scanlinediff;
sl@0
   680
			}
sl@0
   681
		}
sl@0
   682
	}
sl@0
   683
sl@0
   684
void CDrawTwoBppBitmap::WriteLine(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
sl@0
   685
	{
sl@0
   686
	if (iUserDispMode == EGray2)
sl@0
   687
		ShadeBuffer(aLength,(TUint32*)aBuffer);
sl@0
   688
sl@0
   689
	const TInt startLong = (aX + KPixelsPerWord - 1) & (~0xf);
sl@0
   690
	const TInt finishLong = (aX + aLength) & (~0xf);
sl@0
   691
	TUint32* base = ScanLine(aY);
sl@0
   692
	const TInt startShift = (startLong - aX) * KBitsPerPixel;
sl@0
   693
	const TInt startShiftExtra = 32 - startShift;
sl@0
   694
	const TInt finishShift = (KPixelsPerWord - aX - aLength + finishLong) * KBitsPerPixel;
sl@0
   695
	TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
sl@0
   696
	TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
sl@0
   697
sl@0
   698
	if (finishLong < startLong)
sl@0
   699
		{
sl@0
   700
		const TUint32 mask = (0xffffffff >> finishShift) & (0xffffffff << startShiftExtra);
sl@0
   701
		pixelPtrLimit[0] &= ~mask;
sl@0
   702
		pixelPtrLimit[0] |= (aBuffer[0] << startShiftExtra) & mask;
sl@0
   703
		return;
sl@0
   704
		}
sl@0
   705
sl@0
   706
	const TInt wordsToCopy = pixelPtrLimit - pixelPtr;
sl@0
   707
sl@0
   708
	if (startShift > 0)
sl@0
   709
		{
sl@0
   710
		pixelPtr[-1] &= 0xffffffff >> startShift;
sl@0
   711
		pixelPtr[-1] |= aBuffer[0] << startShiftExtra;
sl@0
   712
sl@0
   713
		CopyOffset(pixelPtr,aBuffer,wordsToCopy,startShift);
sl@0
   714
		aBuffer += wordsToCopy;
sl@0
   715
sl@0
   716
		if (finishLong < aX + aLength)
sl@0
   717
			{
sl@0
   718
			TUint32 first = (aBuffer[0] >> startShift) | (aBuffer[1] << startShiftExtra);
sl@0
   719
			pixelPtrLimit[0] = PasteInt(first,pixelPtrLimit[0],finishShift);
sl@0
   720
			}
sl@0
   721
		}
sl@0
   722
	else
sl@0
   723
		{
sl@0
   724
		Mem::Copy(pixelPtr,aBuffer,wordsToCopy * sizeof(TUint32));
sl@0
   725
		aBuffer += wordsToCopy;
sl@0
   726
sl@0
   727
		if (finishLong < aX + aLength)
sl@0
   728
			pixelPtrLimit[0] = PasteInt(aBuffer[0],pixelPtrLimit[0],finishShift);
sl@0
   729
		}
sl@0
   730
	}
sl@0
   731
sl@0
   732
void CDrawTwoBppBitmap::WriteLineXOR(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
sl@0
   733
	{
sl@0
   734
	if (iUserDispMode == EGray2)
sl@0
   735
		ShadeBuffer(aLength,(TUint32*)aBuffer);
sl@0
   736
sl@0
   737
	const TInt startLong = (aX + KPixelsPerWord - 1) & (~0xf);
sl@0
   738
	const TInt finishLong = (aX + aLength) & (~0xf);
sl@0
   739
	TUint32* base = ScanLine(aY);
sl@0
   740
	const TInt startShift = (startLong - aX) * KBitsPerPixel;
sl@0
   741
	const TInt startShiftExtra = 32 - startShift;
sl@0
   742
	const TInt finishShift = (KPixelsPerWord - aX - aLength + finishLong) * KBitsPerPixel;
sl@0
   743
	TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
sl@0
   744
	TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
sl@0
   745
sl@0
   746
	if (finishLong < startLong)
sl@0
   747
		{
sl@0
   748
		const TUint32 mask = (0xffffffff >> finishShift) & (0xffffffff << startShiftExtra);
sl@0
   749
		pixelPtrLimit[0] ^= (aBuffer[0] << startShiftExtra) & mask;
sl@0
   750
		return;
sl@0
   751
		}
sl@0
   752
sl@0
   753
	if (startShift > 0)
sl@0
   754
		{
sl@0
   755
		pixelPtr[-1] ^= aBuffer[0] << startShiftExtra;
sl@0
   756
sl@0
   757
		while (pixelPtr < pixelPtrLimit)
sl@0
   758
			{
sl@0
   759
			pixelPtr[0] ^= (aBuffer[0] >> startShift) | (aBuffer[1] << startShiftExtra);
sl@0
   760
sl@0
   761
			pixelPtr++;
sl@0
   762
			aBuffer++;
sl@0
   763
			}
sl@0
   764
sl@0
   765
		if (finishLong < aX + aLength)
sl@0
   766
			{
sl@0
   767
			TUint32 first = (aBuffer[0] >> startShift) | (aBuffer[1] << startShiftExtra);
sl@0
   768
			pixelPtrLimit[0] ^= PasteInt(first,0,finishShift);
sl@0
   769
			}
sl@0
   770
		}
sl@0
   771
	else
sl@0
   772
		{
sl@0
   773
		while (pixelPtr < pixelPtrLimit)
sl@0
   774
			*pixelPtr++ ^= *aBuffer++;
sl@0
   775
sl@0
   776
		if (finishLong < aX + aLength)
sl@0
   777
			pixelPtrLimit[0] ^= PasteInt(aBuffer[0],0,finishShift);
sl@0
   778
		}
sl@0
   779
	}
sl@0
   780
sl@0
   781
void CDrawTwoBppBitmap::WriteLineAND(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
sl@0
   782
	{
sl@0
   783
	if (iUserDispMode == EGray2)
sl@0
   784
		ShadeBuffer(aLength,(TUint32*)aBuffer);
sl@0
   785
sl@0
   786
	const TInt startLong = (aX + KPixelsPerWord - 1) & (~0xf);
sl@0
   787
	const TInt finishLong = (aX + aLength) & (~0xf);
sl@0
   788
	TUint32* base = ScanLine(aY);
sl@0
   789
	const TInt startShift = (startLong - aX) * KBitsPerPixel;
sl@0
   790
	const TInt startShiftExtra = 32 - startShift;
sl@0
   791
	const TInt finishShift = (KPixelsPerWord - aX - aLength + finishLong) * KBitsPerPixel;
sl@0
   792
	TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
sl@0
   793
	TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
sl@0
   794
sl@0
   795
	if (finishLong < startLong)
sl@0
   796
		{
sl@0
   797
		const TUint32 mask = (0xffffffff >> finishShift) & (0xffffffff << startShiftExtra);
sl@0
   798
		pixelPtrLimit[0] &= (aBuffer[0] << startShiftExtra) | ~mask;
sl@0
   799
		return;
sl@0
   800
		}
sl@0
   801
sl@0
   802
	if (startShift > 0)
sl@0
   803
		{
sl@0
   804
		pixelPtr[-1] &= (aBuffer[0] << startShiftExtra) | (0xffffffff >> startShift);
sl@0
   805
sl@0
   806
		while (pixelPtr < pixelPtrLimit)
sl@0
   807
			{
sl@0
   808
			pixelPtr[0] &= (aBuffer[0] >> startShift) | (aBuffer[1] << startShiftExtra);
sl@0
   809
sl@0
   810
			pixelPtr++;
sl@0
   811
			aBuffer++;
sl@0
   812
			}
sl@0
   813
sl@0
   814
		if (finishLong < aX + aLength)
sl@0
   815
			{
sl@0
   816
			TUint32 first = (aBuffer[0] >> startShift) | (aBuffer[1] << startShiftExtra);
sl@0
   817
			pixelPtrLimit[0] &= PasteInt(first,0xffffffff,finishShift);
sl@0
   818
			}
sl@0
   819
		}
sl@0
   820
	else
sl@0
   821
		{
sl@0
   822
		while (pixelPtr < pixelPtrLimit)
sl@0
   823
			*pixelPtr++ &= *aBuffer++;
sl@0
   824
sl@0
   825
		if (finishLong < aX + aLength)
sl@0
   826
			pixelPtrLimit[0] &= PasteInt(aBuffer[0],0xffffffff,finishShift);
sl@0
   827
		}
sl@0
   828
	}
sl@0
   829
sl@0
   830
void CDrawTwoBppBitmap::WriteLineOR(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
sl@0
   831
	{
sl@0
   832
	if (iUserDispMode == EGray2)
sl@0
   833
		ShadeBuffer(aLength,(TUint32*)aBuffer);
sl@0
   834
sl@0
   835
	const TInt startLong = (aX + KPixelsPerWord - 1) & (~0xf);
sl@0
   836
	const TInt finishLong = (aX + aLength) & (~0xf);
sl@0
   837
	TUint32* base = ScanLine(aY);
sl@0
   838
	const TInt startShift = (startLong - aX) * KBitsPerPixel;
sl@0
   839
	const TInt startShiftExtra = 32 - startShift;
sl@0
   840
	const TInt finishShift = (KPixelsPerWord - aX - aLength + finishLong) * KBitsPerPixel;
sl@0
   841
	TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
sl@0
   842
	TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
sl@0
   843
sl@0
   844
	if (finishLong < startLong)
sl@0
   845
		{
sl@0
   846
		const TUint32 mask = (0xffffffff >> finishShift) & (0xffffffff << startShiftExtra);
sl@0
   847
		pixelPtrLimit[0] |= (aBuffer[0] << startShiftExtra) & mask;
sl@0
   848
		return;
sl@0
   849
		}
sl@0
   850
sl@0
   851
	if (startShift > 0)
sl@0
   852
		{
sl@0
   853
		pixelPtr[-1] |= aBuffer[0] << startShiftExtra;
sl@0
   854
sl@0
   855
		while (pixelPtr < pixelPtrLimit)
sl@0
   856
			{
sl@0
   857
			pixelPtr[0] |= (aBuffer[0] >> startShift) | (aBuffer[1] << startShiftExtra);
sl@0
   858
sl@0
   859
			pixelPtr++;
sl@0
   860
			aBuffer++;
sl@0
   861
			}
sl@0
   862
sl@0
   863
		if (finishLong < aX + aLength)
sl@0
   864
			{
sl@0
   865
			TUint32 first = (aBuffer[0] >> startShift) | (aBuffer[1] << startShiftExtra);
sl@0
   866
			pixelPtrLimit[0] |= PasteInt(first,0,finishShift);
sl@0
   867
			}
sl@0
   868
		}
sl@0
   869
	else
sl@0
   870
		{
sl@0
   871
		while (pixelPtr < pixelPtrLimit)
sl@0
   872
			*pixelPtr++ |= *aBuffer++;
sl@0
   873
sl@0
   874
		if (finishLong < aX + aLength)
sl@0
   875
			pixelPtrLimit[0] |= PasteInt(aBuffer[0],0,finishShift);
sl@0
   876
		}
sl@0
   877
	}
sl@0
   878
sl@0
   879
/**
sl@0
   880
MAlphaBlend::WriteRgbAlphaLine() implementation.
sl@0
   881
@see MAlphaBlend::WriteRgbAlphaLine()
sl@0
   882
*/
sl@0
   883
void CDrawTwoBppBitmap::WriteRgbAlphaLine(TInt aX, TInt aY, TInt aLength,
sl@0
   884
                                          const TUint8* aRgbBuffer,
sl@0
   885
                                          const TUint8* aMaskBuffer,
sl@0
   886
                                          MAlphaBlend::TShadowing aShadowing,
sl@0
   887
                                          CGraphicsContext::TDrawMode /*aDrawMode*/)
sl@0
   888
    {
sl@0
   889
	TUint8* pixelPtr = REINTERPRET_CAST(TUint8*,ScanLine(aY)) + (aX / 4);
sl@0
   890
	const TUint8* maskBufferPtrLimit = aMaskBuffer + aLength;
sl@0
   891
	TInt bitOffset = (aX & 3) * KBitsPerPixel;
sl@0
   892
	TRgb pixelClr;
sl@0
   893
sl@0
   894
	while (aMaskBuffer < maskBufferPtrLimit)
sl@0
   895
		{
sl@0
   896
        TRgb srcColor(aRgbBuffer[2],aRgbBuffer[1],aRgbBuffer[0]);
sl@0
   897
        if(aShadowing == MAlphaBlend::EShdwBefore)
sl@0
   898
            {
sl@0
   899
		    Shadow(srcColor);
sl@0
   900
            }
sl@0
   901
		TInt pixelValue = ((pixelPtr[0] >> bitOffset) & 0x03) * (255 - aMaskBuffer[0]);
sl@0
   902
		const TInt srceValue = (((srcColor.Red() << 1) + 
sl@0
   903
                                  srcColor.Green() + (srcColor.Green() << 2) + 
sl@0
   904
                                  srcColor.Blue()) >> 9) * aMaskBuffer[0];
sl@0
   905
sl@0
   906
		pixelValue += srceValue;
sl@0
   907
		pixelValue /= 255;
sl@0
   908
sl@0
   909
		pixelClr = TRgb::_Gray4(pixelValue);
sl@0
   910
        if(aShadowing == MAlphaBlend::EShdwAfter)
sl@0
   911
            {
sl@0
   912
		    Shadow(pixelClr);
sl@0
   913
            }
sl@0
   914
		MapColorToUserDisplayMode(pixelClr);
sl@0
   915
sl@0
   916
		pixelPtr[0] &= ~(3 << bitOffset);
sl@0
   917
		pixelPtr[0] |= TUint8(pixelClr._Gray4() << bitOffset);
sl@0
   918
sl@0
   919
		bitOffset += 2;
sl@0
   920
		if (bitOffset == 8)
sl@0
   921
			{
sl@0
   922
			bitOffset = 0;
sl@0
   923
			pixelPtr++;
sl@0
   924
			}
sl@0
   925
sl@0
   926
		aRgbBuffer += 4;
sl@0
   927
		aMaskBuffer++;
sl@0
   928
		}
sl@0
   929
	}
sl@0
   930
sl@0
   931
void CDrawTwoBppBitmap::WriteRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
sl@0
   932
	{
sl@0
   933
	if (iUserDispMode == EGray2)
sl@0
   934
		aColor = TRgb::_Gray2(aColor._Gray2());
sl@0
   935
sl@0
   936
	const TInt startLong = (aX + KPixelsPerWord - 1)&(~0xf);
sl@0
   937
	const TInt finishLong = (aX + aLength) & (~0xf);
sl@0
   938
	const TInt yLimit = aY + aHeight;
sl@0
   939
	TUint32 colorWord1,colorWord2;
sl@0
   940
sl@0
   941
	if (aColor._Gray16() % 5 != 0)
sl@0
   942
		HashInt(colorWord1,colorWord2,aColor,startLong,aY);
sl@0
   943
	else
sl@0
   944
		colorWord1 = colorWord2 = ColorInt(aColor);
sl@0
   945
sl@0
   946
	TUint32 colorWord = colorWord1;
sl@0
   947
	const TInt startShift = (startLong - aX) * KBitsPerPixel;
sl@0
   948
	const TInt finishShift = (KPixelsPerWord - aX - aLength + finishLong) * KBitsPerPixel;
sl@0
   949
	TUint32* base = ScanLine(aY);
sl@0
   950
	TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
sl@0
   951
	TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
sl@0
   952
sl@0
   953
	if (finishLong < startLong)
sl@0
   954
		{
sl@0
   955
		const TUint32 mask = (0xffffffff >> finishShift) & (0xffffffff << (32 - startShift));
sl@0
   956
		const TUint32 invertedMask = ~mask;
sl@0
   957
		colorWord &= mask;
sl@0
   958
		colorWord1 &= mask;
sl@0
   959
		colorWord2 &= mask;
sl@0
   960
sl@0
   961
		for (; aY < yLimit; aY++)
sl@0
   962
			{
sl@0
   963
			pixelPtrLimit[0] &= invertedMask;
sl@0
   964
			pixelPtrLimit[0] |= colorWord;
sl@0
   965
sl@0
   966
			pixelPtrLimit += iScanLineWords;
sl@0
   967
			colorWord = (colorWord == colorWord2) ? colorWord1 : colorWord2;
sl@0
   968
			}
sl@0
   969
		return;
sl@0
   970
		}
sl@0
   971
sl@0
   972
	const TBool extra = (finishLong < aX + aLength);
sl@0
   973
sl@0
   974
	for (; aY < yLimit; aY++)
sl@0
   975
		{
sl@0
   976
		if (startShift > 0)
sl@0
   977
			pixelPtr[-1] = PasteInt(pixelPtr[-1],colorWord,startShift);
sl@0
   978
sl@0
   979
		for (TUint32* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
sl@0
   980
			tempPixelPtr[0] = colorWord;
sl@0
   981
sl@0
   982
		if (extra)
sl@0
   983
			pixelPtrLimit[0] = PasteInt(colorWord,pixelPtrLimit[0],finishShift);
sl@0
   984
sl@0
   985
		pixelPtr += iScanLineWords;
sl@0
   986
		pixelPtrLimit += iScanLineWords;
sl@0
   987
		colorWord = (colorWord == colorWord2) ? colorWord1 : colorWord2;
sl@0
   988
		}
sl@0
   989
	}
sl@0
   990
sl@0
   991
void CDrawTwoBppBitmap::WriteRgbMultiXOR(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
sl@0
   992
	{
sl@0
   993
	if (iUserDispMode == EGray2)
sl@0
   994
		aColor = TRgb::_Gray2(aColor._Gray2());
sl@0
   995
sl@0
   996
	const TInt startLong = (aX + KPixelsPerWord - 1)&(~0xf);
sl@0
   997
	const TInt finishLong = (aX + aLength) & (~0xf);
sl@0
   998
	const TInt yLimit = aY + aHeight;
sl@0
   999
	TUint32 colorWord1,colorWord2;
sl@0
  1000
sl@0
  1001
	if (aColor._Gray16() % 5 != 0)
sl@0
  1002
		HashInt(colorWord1,colorWord2,aColor,startLong,aY);
sl@0
  1003
	else
sl@0
  1004
		colorWord1 = colorWord2 = ColorInt(aColor);
sl@0
  1005
sl@0
  1006
	TUint32 colorWord = colorWord1;
sl@0
  1007
	const TInt startShift = (startLong - aX) * KBitsPerPixel;
sl@0
  1008
	const TInt finishShift = (KPixelsPerWord - aX - aLength + finishLong) * KBitsPerPixel;
sl@0
  1009
	TUint32* base = ScanLine(aY);
sl@0
  1010
	TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
sl@0
  1011
	TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
sl@0
  1012
sl@0
  1013
	if (finishLong < startLong)
sl@0
  1014
		{
sl@0
  1015
		const TUint32 mask = (0xffffffff >> finishShift) & (0xffffffff << (32 - startShift));
sl@0
  1016
		colorWord &= mask;
sl@0
  1017
		colorWord1 &= mask;
sl@0
  1018
		colorWord2 &= mask;
sl@0
  1019
sl@0
  1020
		for (; aY < yLimit; aY++)
sl@0
  1021
			{
sl@0
  1022
			pixelPtrLimit[0] ^= colorWord;
sl@0
  1023
sl@0
  1024
			pixelPtrLimit += iScanLineWords;
sl@0
  1025
			colorWord = (colorWord == colorWord2) ? colorWord1 : colorWord2;
sl@0
  1026
			}
sl@0
  1027
		return;
sl@0
  1028
		}
sl@0
  1029
sl@0
  1030
	const TBool extra = (finishLong < aX + aLength);
sl@0
  1031
sl@0
  1032
	for (; aY < yLimit; aY++)
sl@0
  1033
		{
sl@0
  1034
		if (startShift > 0)
sl@0
  1035
			pixelPtr[-1] ^= PasteInt(0,colorWord,startShift);
sl@0
  1036
sl@0
  1037
		for (TUint32* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
sl@0
  1038
			tempPixelPtr[0] ^= colorWord;
sl@0
  1039
sl@0
  1040
		if (extra)
sl@0
  1041
			pixelPtrLimit[0] ^= PasteInt(colorWord,0,finishShift);
sl@0
  1042
sl@0
  1043
		pixelPtr += iScanLineWords;
sl@0
  1044
		pixelPtrLimit += iScanLineWords;
sl@0
  1045
		colorWord = (colorWord == colorWord2) ? colorWord1 : colorWord2;
sl@0
  1046
		}
sl@0
  1047
	}
sl@0
  1048
sl@0
  1049
void CDrawTwoBppBitmap::WriteRgbMultiAND(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
sl@0
  1050
	{
sl@0
  1051
	if (iUserDispMode == EGray2)
sl@0
  1052
		aColor = TRgb::_Gray2(aColor._Gray2());
sl@0
  1053
sl@0
  1054
	const TInt startLong = (aX + KPixelsPerWord - 1)&(~0xf);
sl@0
  1055
	const TInt finishLong = (aX + aLength) & (~0xf);
sl@0
  1056
	const TInt yLimit = aY + aHeight;
sl@0
  1057
	TUint32 colorWord1,colorWord2;
sl@0
  1058
sl@0
  1059
	if (aColor._Gray16() % 5 != 0)
sl@0
  1060
		HashInt(colorWord1,colorWord2,aColor,startLong,aY);
sl@0
  1061
	else
sl@0
  1062
		colorWord1 = colorWord2 = ColorInt(aColor);
sl@0
  1063
sl@0
  1064
	TUint32 colorWord = colorWord1;
sl@0
  1065
	const TInt startShift = (startLong - aX) * KBitsPerPixel;
sl@0
  1066
	const TInt finishShift = (KPixelsPerWord - aX - aLength + finishLong) * KBitsPerPixel;
sl@0
  1067
	TUint32* base = ScanLine(aY);
sl@0
  1068
	TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
sl@0
  1069
	TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
sl@0
  1070
sl@0
  1071
	if (finishLong < startLong)
sl@0
  1072
		{
sl@0
  1073
		const TUint32 mask = (0xffffffff >> finishShift) & (0xffffffff << (32 - startShift));
sl@0
  1074
		const TUint32 invertedMask = ~mask;
sl@0
  1075
		colorWord &= mask;
sl@0
  1076
		colorWord1 &= mask;
sl@0
  1077
		colorWord2 &= mask;
sl@0
  1078
sl@0
  1079
		for (; aY < yLimit; aY++)
sl@0
  1080
			{
sl@0
  1081
			pixelPtrLimit[0] &= colorWord | invertedMask;
sl@0
  1082
sl@0
  1083
			pixelPtrLimit += iScanLineWords;
sl@0
  1084
			colorWord = (colorWord == colorWord2) ? colorWord1 : colorWord2;
sl@0
  1085
			}
sl@0
  1086
		return;
sl@0
  1087
		}
sl@0
  1088
sl@0
  1089
	const TBool extra = (finishLong < aX + aLength);
sl@0
  1090
sl@0
  1091
	for (; aY < yLimit; aY++)
sl@0
  1092
		{
sl@0
  1093
		if (startShift > 0)
sl@0
  1094
			pixelPtr[-1] &= PasteInt(0xffffffff,colorWord,startShift);
sl@0
  1095
sl@0
  1096
		for (TUint32* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
sl@0
  1097
			tempPixelPtr[0] &= colorWord;
sl@0
  1098
sl@0
  1099
		if (extra)
sl@0
  1100
			pixelPtrLimit[0] &= PasteInt(colorWord,0xffffffff,finishShift);
sl@0
  1101
sl@0
  1102
		pixelPtr += iScanLineWords;
sl@0
  1103
		pixelPtrLimit += iScanLineWords;
sl@0
  1104
		colorWord = (colorWord == colorWord2) ? colorWord1 : colorWord2;
sl@0
  1105
		}
sl@0
  1106
	}
sl@0
  1107
sl@0
  1108
void CDrawTwoBppBitmap::WriteRgbMultiOR(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
sl@0
  1109
	{
sl@0
  1110
	if (iUserDispMode == EGray2)
sl@0
  1111
		aColor = TRgb::_Gray2(aColor._Gray2());
sl@0
  1112
sl@0
  1113
	const TInt startLong = (aX + KPixelsPerWord - 1)&(~0xf);
sl@0
  1114
	const TInt finishLong = (aX + aLength) & (~0xf);
sl@0
  1115
	const TInt yLimit = aY + aHeight;
sl@0
  1116
	TUint32 colorWord1,colorWord2;
sl@0
  1117
sl@0
  1118
	if (aColor._Gray16() % 5 != 0)
sl@0
  1119
		HashInt(colorWord1,colorWord2,aColor,startLong,aY);
sl@0
  1120
	else
sl@0
  1121
		colorWord1 = colorWord2 = ColorInt(aColor);
sl@0
  1122
sl@0
  1123
	TUint32 colorWord = colorWord1;
sl@0
  1124
	const TInt startShift = (startLong - aX) * KBitsPerPixel;
sl@0
  1125
	const TInt finishShift = (KPixelsPerWord - aX - aLength + finishLong) * KBitsPerPixel;
sl@0
  1126
	TUint32* base = ScanLine(aY);
sl@0
  1127
	TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
sl@0
  1128
	TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
sl@0
  1129
sl@0
  1130
	if (finishLong < startLong)
sl@0
  1131
		{
sl@0
  1132
		const TUint32 mask = (0xffffffff >> finishShift) & (0xffffffff << (32 - startShift));
sl@0
  1133
		colorWord &= mask;
sl@0
  1134
		colorWord1 &= mask;
sl@0
  1135
		colorWord2 &= mask;
sl@0
  1136
sl@0
  1137
		for (; aY < yLimit; aY++)
sl@0
  1138
			{
sl@0
  1139
			pixelPtrLimit[0] |= colorWord;
sl@0
  1140
sl@0
  1141
			pixelPtrLimit += iScanLineWords;
sl@0
  1142
			colorWord = (colorWord == colorWord2) ? colorWord1 : colorWord2;
sl@0
  1143
			}
sl@0
  1144
		return;
sl@0
  1145
		}
sl@0
  1146
sl@0
  1147
	const TBool extra = (finishLong < aX + aLength);
sl@0
  1148
sl@0
  1149
	for (; aY < yLimit; aY++)
sl@0
  1150
		{
sl@0
  1151
		if (startShift > 0)
sl@0
  1152
			pixelPtr[-1] |= PasteInt(0,colorWord,startShift);
sl@0
  1153
sl@0
  1154
		for (TUint32* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
sl@0
  1155
			tempPixelPtr[0] |= colorWord;
sl@0
  1156
sl@0
  1157
		if (extra)
sl@0
  1158
			pixelPtrLimit[0] |= PasteInt(colorWord,0,finishShift);
sl@0
  1159
sl@0
  1160
		pixelPtr += iScanLineWords;
sl@0
  1161
		pixelPtrLimit += iScanLineWords;
sl@0
  1162
		colorWord = (colorWord == colorWord2) ? colorWord1 : colorWord2;
sl@0
  1163
		}
sl@0
  1164
	}
sl@0
  1165
sl@0
  1166
void CDrawTwoBppBitmap::WriteRgbAlphaMulti(TInt aX,TInt aY,TInt aLength,TRgb aColor,const TUint8* aMaskBuffer)
sl@0
  1167
	{
sl@0
  1168
	DeOrientate(aX,aY);
sl@0
  1169
	TUint8* pixelPtr = REINTERPRET_CAST(TUint8*,ScanLine(aY)) + (aX / 4);
sl@0
  1170
	TInt pixelOffset = (aX & 3) * 2;
sl@0
  1171
	const TUint8* maskBufferPtrLimit = aMaskBuffer + aLength;
sl@0
  1172
sl@0
  1173
	if (iShadowMode)
sl@0
  1174
		Shadow(aColor);
sl@0
  1175
sl@0
  1176
	const TInt gray = aColor._Gray256();
sl@0
  1177
	TRgb pixelColor;
sl@0
  1178
	
sl@0
  1179
	while (aMaskBuffer < maskBufferPtrLimit)
sl@0
  1180
		{
sl@0
  1181
		const TInt pixelGray256Value = ((pixelPtr[0] >> pixelOffset) & 3) * 85;
sl@0
  1182
		pixelColor = TRgb::_Gray256(((gray * aMaskBuffer[0]) + ((255 - aMaskBuffer[0]) * pixelGray256Value)) / 255);
sl@0
  1183
		pixelPtr[0] &= ~(3 << pixelOffset);
sl@0
  1184
		pixelPtr[0] |= pixelColor._Gray4() << pixelOffset;
sl@0
  1185
sl@0
  1186
		pixelOffset += 2;
sl@0
  1187
		if (pixelOffset >= 8)
sl@0
  1188
			{
sl@0
  1189
			pixelPtr++;
sl@0
  1190
			pixelOffset = 0;
sl@0
  1191
			}
sl@0
  1192
		aMaskBuffer++;
sl@0
  1193
		}
sl@0
  1194
	}
sl@0
  1195
sl@0
  1196
void CDrawTwoBppBitmap::MapColorToUserDisplayMode(TRgb& aColor)
sl@0
  1197
	{
sl@0
  1198
	if (iUserDispMode == EGray2)
sl@0
  1199
		aColor = TRgb::_Gray2(aColor._Gray2());
sl@0
  1200
	}
sl@0
  1201
sl@0
  1202
void CDrawTwoBppBitmap::MapBufferToUserDisplayMode(TInt aLength,TUint32* aBuffer)
sl@0
  1203
	{
sl@0
  1204
	if (iUserDispMode == EGray2)
sl@0
  1205
		{
sl@0
  1206
		TUint8* bufferPtr = (TUint8*)aBuffer;
sl@0
  1207
		const TUint8* bufferLimit = bufferPtr + ((aLength + 3) / 4);
sl@0
  1208
sl@0
  1209
		while (bufferPtr < bufferLimit)
sl@0
  1210
			{
sl@0
  1211
			TUint8 value = TUint8(*bufferPtr & 0xaa);
sl@0
  1212
			*bufferPtr++ = TUint8(value | (value >> 1));
sl@0
  1213
			}
sl@0
  1214
		}
sl@0
  1215
	}
sl@0
  1216
sl@0
  1217
TInt CDrawTwoBppBitmap::WriteRgbOutlineAndShadow(TInt aX, TInt aY, const TInt aLength,
sl@0
  1218
												TUint32 aOutlinePenColor, TUint32 aShadowColor,
sl@0
  1219
												TUint32 aFillColor, const TUint8* aDataBuffer)
sl@0
  1220
	{
sl@0
  1221
	//This is non-optimised since this screen mode is rarely used and is usually 
sl@0
  1222
	//fast enough without optimisation.
sl@0
  1223
	DeOrientate(aX,aY);
sl@0
  1224
	TUint8* pixelPtr = REINTERPRET_CAST(TUint8*,ScanLine(aY)) + (aX / 4);
sl@0
  1225
	TInt pixelOffset = (aX & 3) * 2;
sl@0
  1226
	const TUint8* dataBufferPtrLimit = aDataBuffer + aLength;
sl@0
  1227
sl@0
  1228
	TInt blendedRedColor;
sl@0
  1229
	TInt blendedGreenColor;
sl@0
  1230
	TInt blendedBlueColor;
sl@0
  1231
	TUint8 index = 0;
sl@0
  1232
	TRgb finalColor;
sl@0
  1233
sl@0
  1234
	TRgb outlinePenColor;
sl@0
  1235
	outlinePenColor.SetInternal(aOutlinePenColor);
sl@0
  1236
	TRgb shadowColor;
sl@0
  1237
	shadowColor.SetInternal(aShadowColor);
sl@0
  1238
	TRgb fillColor;
sl@0
  1239
	fillColor.SetInternal(aFillColor);
sl@0
  1240
sl@0
  1241
	const TInt redOutlinePenColor = outlinePenColor.Red();
sl@0
  1242
	const TInt redShadowColor = shadowColor.Red();
sl@0
  1243
	const TInt redFillColor = fillColor.Red();
sl@0
  1244
sl@0
  1245
	const TInt greenOutlinePenColor = outlinePenColor.Green();
sl@0
  1246
	const TInt greenShadowColor = shadowColor.Green();
sl@0
  1247
	const TInt greenFillColor = fillColor.Green();
sl@0
  1248
sl@0
  1249
	const TInt blueOutlinePenColor = outlinePenColor.Blue();
sl@0
  1250
	const TInt blueShadowColor = shadowColor.Blue();
sl@0
  1251
	const TInt blueFillColor = fillColor.Blue();
sl@0
  1252
	
sl@0
  1253
	while (aDataBuffer < dataBufferPtrLimit)
sl@0
  1254
		{
sl@0
  1255
		index = *aDataBuffer++;
sl@0
  1256
		if (255 == FourColorBlendLookup[index][KBackgroundColorIndex])
sl@0
  1257
			{
sl@0
  1258
			//background colour
sl@0
  1259
			//No drawing required so move on to next pixel.
sl@0
  1260
			pixelOffset += 2;
sl@0
  1261
			if (pixelOffset >= 8)
sl@0
  1262
				{
sl@0
  1263
				pixelPtr++;
sl@0
  1264
				pixelOffset = 0;
sl@0
  1265
				}
sl@0
  1266
			continue;
sl@0
  1267
			}
sl@0
  1268
		else if (255 == FourColorBlendLookup[index][KFillColorIndex])
sl@0
  1269
			{
sl@0
  1270
			//fill colour
sl@0
  1271
			finalColor.SetInternal(aFillColor);
sl@0
  1272
			}
sl@0
  1273
		else if (255 == FourColorBlendLookup[index][KShadowColorIndex])
sl@0
  1274
			{
sl@0
  1275
			//Shadow colour
sl@0
  1276
			finalColor.SetInternal(aShadowColor);
sl@0
  1277
			}
sl@0
  1278
		else if (255 == FourColorBlendLookup[index][KOutlineColorIndex])
sl@0
  1279
			{
sl@0
  1280
			//Outline colour
sl@0
  1281
			finalColor.SetInternal(aOutlinePenColor);
sl@0
  1282
			}
sl@0
  1283
		else
sl@0
  1284
			{
sl@0
  1285
			TRgb backgroundColor = TRgb::_Gray4((pixelPtr[0] >> pixelOffset) & 3);
sl@0
  1286
			blendedRedColor = (redOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] + 
sl@0
  1287
						   		redShadowColor * FourColorBlendLookup[index][KShadowColorIndex] +
sl@0
  1288
						  		redFillColor * FourColorBlendLookup[index][KFillColorIndex] + 
sl@0
  1289
						  		backgroundColor.Red() * FourColorBlendLookup[index][KBackgroundColorIndex]) >> 8;
sl@0
  1290
sl@0
  1291
			blendedGreenColor = (greenOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] + 
sl@0
  1292
								greenShadowColor * FourColorBlendLookup[index][KShadowColorIndex] +
sl@0
  1293
								greenFillColor * FourColorBlendLookup[index][KFillColorIndex] + 
sl@0
  1294
								backgroundColor.Green() * FourColorBlendLookup[index][KBackgroundColorIndex]) >> 8;
sl@0
  1295
sl@0
  1296
			blendedBlueColor = (blueOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] + 
sl@0
  1297
								blueShadowColor * FourColorBlendLookup[index][KShadowColorIndex] +
sl@0
  1298
								blueFillColor * FourColorBlendLookup[index][KFillColorIndex] + 
sl@0
  1299
								backgroundColor.Blue() * FourColorBlendLookup[index][KBackgroundColorIndex]) >> 8;
sl@0
  1300
sl@0
  1301
			finalColor = TRgb(blendedRedColor, blendedGreenColor, blendedBlueColor);
sl@0
  1302
			}
sl@0
  1303
		
sl@0
  1304
		//Clear the relevant bits.
sl@0
  1305
		pixelPtr[0] &= ~(3 << pixelOffset);
sl@0
  1306
		pixelPtr[0] |= (finalColor._Gray4() << pixelOffset);
sl@0
  1307
		pixelOffset += 2;
sl@0
  1308
		
sl@0
  1309
		if (pixelOffset >= 8)
sl@0
  1310
			{
sl@0
  1311
			pixelPtr++;
sl@0
  1312
			pixelOffset = 0;
sl@0
  1313
			}
sl@0
  1314
		}
sl@0
  1315
	return KErrNone;
sl@0
  1316
	}