graphicsdeviceinterface/screendriver/sbit/BMDRAW4C.CPP
changeset 0 5d03bc08d59c
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "BMDRAW.H"
       
    17 
       
    18 const TInt color16ShadowTable[16] = {
       
    19 	0,	0,	0,	0,	0,	2,	3,	4,
       
    20 	11,	12,	13,	0,	0,	0,	1,	14
       
    21 	};
       
    22 
       
    23 const TInt KPixelsPerWord = 8;
       
    24 const TInt KPixelsPerByte = 2;
       
    25 const TInt KBitsPerPixel = 4;
       
    26 
       
    27 // CDrawFourBppBitmapColor
       
    28 
       
    29 //Initializes iSize, iDrawRect, iLongWidth, iScanlineWords data members.
       
    30 //It should be called every time when iSize is going to be changed - from Construct().
       
    31 //@param aSize Physical screen size in pixels.
       
    32 //@panic EScreenDriverPanicInvalidSize - Invalid aSize parameter. This might happen if the 
       
    33 //device is scaled and the scaling origin goes outside physical drawing rectangle.
       
    34 void CDrawFourBppBitmapColor::SetSize(const TSize& aSize) 
       
    35 	{
       
    36 	CDrawBitmap::SetSize(aSize);
       
    37 	__ASSERT_DEBUG(iSize == aSize, User::Invariant());
       
    38 	iLongWidth = (iSize.iWidth + (KPixelsPerWord - 1)) & ~(KPixelsPerWord - 1);
       
    39 	iScanLineWords = iLongWidth / KPixelsPerWord;
       
    40 	}
       
    41  
       
    42 TInt CDrawFourBppBitmapColor::Construct(TSize aSize)
       
    43 	{
       
    44 	return Construct(aSize, ((aSize.iWidth + (KPixelsPerWord - 1)) & ~(KPixelsPerWord - 1)) / KPixelsPerByte);
       
    45 	}
       
    46 
       
    47 TInt CDrawFourBppBitmapColor::Construct(TSize aSize, TInt aStride)
       
    48 	{
       
    49 	iBits = NULL;
       
    50 	iDispMode = EColor16;
       
    51 	CDrawBitmap::SetSize(aSize);
       
    52 	__ASSERT_DEBUG(iSize == aSize, User::Invariant());
       
    53 	if (aStride & 3)
       
    54 		return KErrArgument;
       
    55 	iLongWidth = aStride * KPixelsPerByte;
       
    56 	if (iLongWidth < aSize.iWidth)
       
    57 		return KErrArgument;
       
    58 	iScanLineWords = aStride >> 2;
       
    59 	TInt size = 1 + (Max(aSize.iWidth,aSize.iHeight) >> 1);
       
    60 	if(size < 0)
       
    61 		return KErrArgument;
       
    62 	iScanLineBuffer = (TUint32*)(User::Heap().Alloc(size));
       
    63 	if (iScanLineBuffer == NULL)
       
    64 		return KErrNoMemory;
       
    65 	return KErrNone;
       
    66 	}
       
    67 
       
    68 void CDrawFourBppBitmapColor::Shadow(TRgb& aColor)
       
    69 	{
       
    70 	if (iShadowMode & EFade)
       
    71 		aColor = FadeRgb(TRgb::Color16(aColor.Color16()));
       
    72 
       
    73 	if (iShadowMode & EShadow)
       
    74 		aColor = TRgb::Color16(color16ShadowTable[aColor.Color16()]);
       
    75 	}
       
    76 
       
    77 TUint32 CDrawFourBppBitmapColor::ShadowWord(TUint32 aWord)
       
    78 	{
       
    79 	TUint32 shadowWord = color16ShadowTable[aWord & 0xf];
       
    80 
       
    81 	shadowWord |= color16ShadowTable[(aWord >> 4) & 0xf] << 4;
       
    82 	shadowWord |= color16ShadowTable[(aWord >> 8) & 0xf] << 8;
       
    83 	shadowWord |= color16ShadowTable[(aWord >> 12) & 0xf] << 12;
       
    84 	shadowWord |= color16ShadowTable[(aWord >> 16) & 0xf] << 16;
       
    85 	shadowWord |= color16ShadowTable[(aWord >> 20) & 0xf] << 20;
       
    86 	shadowWord |= color16ShadowTable[(aWord >> 24) & 0xf] << 24;
       
    87 	shadowWord |= color16ShadowTable[(aWord >> 28) & 0xf] << 28;
       
    88 
       
    89 	return shadowWord;
       
    90 	}
       
    91 
       
    92 TUint32 CDrawFourBppBitmapColor::FadeWord(TUint32 aWord)
       
    93 	{
       
    94 	TUint32 fadeWord = FadeRgb(TRgb::Color16(aWord & 0xf)).Color16();
       
    95 
       
    96 	fadeWord |= FadeRgb(TRgb::Color16((aWord >> 4) & 0xf)).Color16() << 4;
       
    97 	fadeWord |= FadeRgb(TRgb::Color16((aWord >> 8) & 0xf)).Color16() << 8;
       
    98 	fadeWord |= FadeRgb(TRgb::Color16((aWord >> 12) & 0xf)).Color16() << 12;
       
    99 	fadeWord |= FadeRgb(TRgb::Color16((aWord >> 16) & 0xf)).Color16() << 16;
       
   100 	fadeWord |= FadeRgb(TRgb::Color16((aWord >> 20) & 0xf)).Color16() << 20;
       
   101 	fadeWord |= FadeRgb(TRgb::Color16((aWord >> 24) & 0xf)).Color16() << 24;
       
   102 	fadeWord |= FadeRgb(TRgb::Color16((aWord >> 28) & 0xf)).Color16() << 28;
       
   103 
       
   104 	return fadeWord;
       
   105 	}
       
   106 
       
   107 TUint32 CDrawFourBppBitmapColor::ColorInt(TRgb aColor) const
       
   108 	{
       
   109 	TUint32 colorWord = aColor.Color16();
       
   110 
       
   111 	colorWord |= colorWord << 4;
       
   112 	colorWord |= colorWord << 8;
       
   113 	colorWord |= colorWord << 16;
       
   114 
       
   115 	return colorWord;
       
   116 	}
       
   117 
       
   118 void CDrawFourBppBitmapColor::InvertBuffer(TInt aLength,TUint32* aBuffer)
       
   119 	{
       
   120 	const TUint32* bufferLimit = aBuffer + ((aLength + KPixelsPerWord - 1) / KPixelsPerWord);
       
   121 
       
   122 	while (aBuffer < bufferLimit)
       
   123 		*aBuffer++ ^= 0xffffffff;
       
   124 	}
       
   125 
       
   126 /**	Copies a number of pixels into a word-aligned buffer without format translation.
       
   127 	Note that the byte length to the target buffer is honoured, 
       
   128  	but the end contents of the last byte are generally overwritten with extra pixel data (or garbage)  
       
   129  	Note that I am assuming the compiler optimiser will convert all these divides and multiplies into shifts!  
       
   130 @param	aX		x coordinate to start copy from (need not be aligned at all)
       
   131 @param	aY		y coordinate to copy line from	
       
   132 @param	aLength	number of pixels to copy  
       
   133 @param	aBuffer	target word-aligned buffer (but may or may not be word length) 
       
   134  **/
       
   135 void CDrawFourBppBitmapColor::ReadLine(TInt aX,TInt aY,TInt aLength,TAny* aBuffer) const
       
   136 	{
       
   137 	TUint32* pixelPtr = ScanLine(aY);
       
   138 	TInt startLongPix = aX & -KPixelsPerWord;
       
   139 	pixelPtr += startLongPix / KPixelsPerWord;
       
   140 	TUint32* bufferPtr = (TUint32*)aBuffer;
       
   141 	TInt wordsCnt = (aLength+KPixelsPerByte-1) / KPixelsPerWord;		//how many words to write to target
       
   142 	TInt restPixels = aLength - wordsCnt * KPixelsPerWord;				//how many pixels left to copy
       
   143 	TInt bytesCnt = (restPixels+KPixelsPerByte-1) / KPixelsPerByte ;	//how many target bytes to copy
       
   144 	TInt shiftBits = aX - startLongPix;
       
   145 	restPixels=shiftBits+restPixels;	//How many pixels are read from the second word by the final word copy
       
   146 	if (bytesCnt==0 && shiftBits && restPixels<=0)
       
   147 		{
       
   148 		// This correction is required because although a last whole word will be written to the target buffer,
       
   149 		// this special test indicates that the required significant data bits plus the shift 
       
   150 		// add up to one word (or less) to be read. 
       
   151 		// The copy words optimisation used to copy the main body of the line 
       
   152 		// will read from the next location after the copy, 
       
   153 		// but this may not always be accessable memory (on the last scanline)
       
   154 		// The correction is not required if the second word would need to be read anyway.
       
   155 		//eg we want to copy 7 nibbles with a 1 nibble shift (16 color), restpixels would be 0
       
   156 		bytesCnt=4;
       
   157 		wordsCnt--;
       
   158 		}
       
   159 	//How many pixels are read from the second word in the final byte copy?
       
   160 	//If zero (or less) then the second word should not be read in the copy bytes phase
       
   161 	//really this should be an else of the if above, but this gives the same end condition.
       
   162 	//eg we want to copy 5 nibbles with a 2 nibble shift (16 color), restpixels would be -1.
       
   163 	restPixels-=KPixelsPerWord;	
       
   164 	ReadLineCommon(pixelPtr,bufferPtr,wordsCnt,restPixels,bytesCnt,shiftBits*KBitsPerPixel);
       
   165 	}
       
   166 
       
   167 
       
   168 TRgb CDrawFourBppBitmapColor::ReadRgbNormal(TInt aX,TInt aY) const
       
   169 	{
       
   170 	TUint32 col = *(ScanLine(aY) + (aX / KPixelsPerWord));
       
   171 	col >>= ((aX & 7) * KBitsPerPixel);
       
   172 	return TRgb::Color16(col & 0xf);
       
   173 	}
       
   174 
       
   175 void CDrawFourBppBitmapColor::ShadowArea(const TRect& aRect)
       
   176 	{
       
   177 	__ASSERT_DEBUG(aRect.iTl.iX>=0 && aRect.iBr.iX<=iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds));
       
   178 	__ASSERT_DEBUG(aRect.iTl.iY>=0 && aRect.iBr.iY<=iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds));
       
   179 
       
   180 	const TInt startLong = (aRect.iTl.iX + KPixelsPerWord - 1) & ~7;
       
   181 	const TInt finishLong = aRect.iBr.iX & ~7;
       
   182 	const TInt startShift = (startLong - aRect.iTl.iX) * KBitsPerPixel;
       
   183 	const TInt finishShift = (KPixelsPerWord - aRect.iBr.iX + finishLong) * KBitsPerPixel;
       
   184 	TUint32* base = ScanLine(aRect.iTl.iY);
       
   185 
       
   186 	if (iShadowMode & EFade)
       
   187 		{
       
   188 		TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
       
   189 		TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
       
   190 
       
   191 		if (finishLong < startLong)
       
   192 			{
       
   193 			const TUint32 mask = (0xffffffff >> finishShift) & (0xffffffff << (32 - startShift));
       
   194 			const TUint32 inverseMask = ~mask;
       
   195 
       
   196 			for (TInt y = aRect.iTl.iY; y < aRect.iBr.iY; y++)
       
   197 				{
       
   198 				const TUint32 faded = FadeWord(pixelPtrLimit[0]) & mask;
       
   199 				pixelPtrLimit[0] &= inverseMask;
       
   200 				pixelPtrLimit[0] |= faded;
       
   201 				pixelPtrLimit += iScanLineWords;
       
   202 				}
       
   203 			}
       
   204 		else
       
   205 			{
       
   206 			for (TInt y = aRect.iTl.iY; y < aRect.iBr.iY; y++)
       
   207 				{
       
   208 				if (aRect.iTl.iX < startLong)
       
   209 					pixelPtr[-1] = PasteInt(pixelPtr[-1],FadeWord(pixelPtr[-1]),startShift);
       
   210 
       
   211 				for (TUint32* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
       
   212 					tempPixelPtr[0] = FadeWord(tempPixelPtr[0]);
       
   213 
       
   214 				if (finishLong < aRect.iBr.iX)
       
   215 					pixelPtrLimit[0] = PasteInt(FadeWord(pixelPtrLimit[0]),pixelPtrLimit[0],finishShift);
       
   216 
       
   217 				pixelPtr += iScanLineWords;
       
   218 				pixelPtrLimit += iScanLineWords;
       
   219 				}
       
   220 			}
       
   221 		}
       
   222 
       
   223 	if (iShadowMode & EShadow)
       
   224 		{
       
   225 		TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
       
   226 		TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
       
   227 
       
   228 		if (finishLong < startLong)
       
   229 			{
       
   230 			const TUint32 mask = (0xffffffff >> finishShift) & (0xffffffff << (32 - startShift));
       
   231 			const TUint32 inverseMask = ~mask;
       
   232 
       
   233 			for (TInt y = aRect.iTl.iY; y < aRect.iBr.iY; y++)
       
   234 				{
       
   235 				TUint32 shadowed = ShadowWord(pixelPtrLimit[0]) & mask;
       
   236 				pixelPtrLimit[0] &= inverseMask;
       
   237 				pixelPtrLimit[0] |= shadowed;
       
   238 				pixelPtrLimit += iScanLineWords;
       
   239 				}
       
   240 			}
       
   241 		else
       
   242 			{
       
   243 			for (TInt y = aRect.iTl.iY; y < aRect.iBr.iY; y++)
       
   244 				{
       
   245 				if (aRect.iTl.iX < startLong)
       
   246 					pixelPtr[-1] = PasteInt(pixelPtr[-1],ShadowWord(pixelPtr[-1]),startShift);
       
   247 
       
   248 				for (TUint32* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
       
   249 					tempPixelPtr[0] = ShadowWord(tempPixelPtr[0]);
       
   250 
       
   251 				if (finishLong < aRect.iBr.iX)
       
   252 					pixelPtrLimit[0] = PasteInt(ShadowWord(pixelPtrLimit[0]),pixelPtrLimit[0],finishShift);
       
   253 
       
   254 				pixelPtr += iScanLineWords;
       
   255 				pixelPtrLimit += iScanLineWords;
       
   256 				}
       
   257 			}
       
   258 		}
       
   259 	}
       
   260 
       
   261 void CDrawFourBppBitmapColor::ShadowBuffer(TInt aLength,TUint32* aBuffer)
       
   262 	{
       
   263 	__ASSERT_DEBUG(aBuffer != NULL,Panic(EScreenDriverPanicInvalidParameter));
       
   264 
       
   265 	const TUint32* bufferLimit = aBuffer + ((aLength + KPixelsPerWord - 1) / KPixelsPerWord);
       
   266 
       
   267 	if (iShadowMode & EFade)
       
   268 		{
       
   269 		for (TUint32* buffer = aBuffer; buffer < bufferLimit; buffer++)
       
   270 			buffer[0] = FadeWord(buffer[0]);
       
   271 		}
       
   272 
       
   273 	if (iShadowMode & EShadow)
       
   274 		{
       
   275 		for (TUint32* buffer = aBuffer; buffer < bufferLimit; buffer++)
       
   276 			buffer[0] = ShadowWord(buffer[0]);
       
   277 		}
       
   278 	}
       
   279 
       
   280 void CDrawFourBppBitmapColor::WriteRgb(TInt aX,TInt aY,TRgb aColor)
       
   281 	{
       
   282 	TUint32* pixelPtr = ScanLine(aY) + (aX / KPixelsPerWord);
       
   283 	const TInt shift = (aX & 7) * KBitsPerPixel;
       
   284 	pixelPtr[0] &= ~(0xf << shift);
       
   285 	pixelPtr[0] |= aColor.Color16() << shift;
       
   286 	}
       
   287 
       
   288 void CDrawFourBppBitmapColor::WriteBinary(TInt aX,TInt aY,TUint32* aData,TInt aLength,TInt aHeight,TRgb aColor)
       
   289 	{
       
   290 	const TInt xLimit = aX + aLength;
       
   291 	const TInt yLimit = aY + aHeight;
       
   292 	const TUint8 color16 = TUint8(aColor.Color16());
       
   293 
       
   294 	for (; aY < yLimit; aY++,aData++)
       
   295 		{
       
   296 		TUint32 dataMask = 1;
       
   297 		TUint8* pixelPtr = (TUint8*)ScanLine(aY);
       
   298 		pixelPtr += aX / 2;
       
   299 
       
   300 		if (color16)
       
   301 			{
       
   302 			for (TInt x = aX; x < xLimit; x++,dataMask <<= 1)
       
   303 				{
       
   304 				if (aData[0] & dataMask)
       
   305 					{
       
   306 					if (x & 1)
       
   307 						pixelPtr[0] = TUint8((color16 << 4) | (pixelPtr[0] & 0x0f));
       
   308 					else
       
   309 						pixelPtr[0] = TUint8((pixelPtr[0] & 0xf0) | color16);
       
   310 					}
       
   311 
       
   312 				if (x & 1)
       
   313 					pixelPtr++;
       
   314 				}
       
   315 			}
       
   316 		else
       
   317 			{
       
   318 			TUint8 bytemask = TUint8((aX & 1) ? 0x0f : 0xf0);
       
   319 
       
   320 			for (TInt x = aX; x < xLimit; x++,dataMask <<= 1,bytemask = (TUint8)~bytemask)
       
   321 				{
       
   322 				if (aData[0] & dataMask)
       
   323 					pixelPtr[0] &= bytemask;
       
   324 
       
   325 				if (x & 1)
       
   326 					pixelPtr++;
       
   327 				}
       
   328 			}
       
   329 		}
       
   330 	}
       
   331 
       
   332 void CDrawFourBppBitmapColor::WriteBinaryOp(TInt aX,TInt aY,TUint32* aData,TInt aLength,TInt aHeight,TRgb aColor,CGraphicsContext::TDrawMode aDrawMode)
       
   333 	{
       
   334 	const TInt xLimit = aX + aLength;
       
   335 	const TInt yLimit = aY + aHeight;
       
   336 	const TInt color16 = aColor.Color16();
       
   337 
       
   338 	for (; aY < yLimit; aY++)
       
   339 		{
       
   340 		TUint32 dataMask = 1;
       
   341 		TUint8* pixelPtr = ((TUint8*)ScanLine(aY)) + (aX / 2);
       
   342 		TUint8 bytemask = TUint8((aX & 1) ? 0x0f : 0xf0);
       
   343 
       
   344 		if (color16)
       
   345 			{
       
   346 			for (TInt x = aX; x < xLimit; x++,dataMask <<= 1,bytemask = (TUint8)~bytemask)
       
   347 				{
       
   348 				if (aData[0] & dataMask)
       
   349 					{
       
   350 					TUint8 pixelColorIndex = TUint8((x & 1) ? color16 << 4 : color16);
       
   351 					if (aDrawMode == CGraphicsContext::EDrawModeXOR)
       
   352 						pixelPtr[0] = (TUint8)(pixelColorIndex ^ pixelPtr[0]);
       
   353 					else if (aDrawMode == CGraphicsContext::EDrawModeAND)
       
   354 						pixelPtr[0] = (TUint8)((pixelColorIndex | bytemask) & pixelPtr[0]);
       
   355 					else if (aDrawMode == CGraphicsContext::EDrawModeOR)
       
   356 						pixelPtr[0] = (TUint8)(pixelColorIndex | pixelPtr[0]);
       
   357 					}
       
   358 
       
   359 				if (x & 1)
       
   360 					pixelPtr++;
       
   361 				}
       
   362 			}
       
   363 		else
       
   364 			{
       
   365 			if (aDrawMode == CGraphicsContext::EDrawModeAND)
       
   366 				{
       
   367 				for (TInt x = aX; x < xLimit; x++,dataMask <<= 1,bytemask = (TUint8)~bytemask)
       
   368 					{
       
   369 					if (aData[0] & dataMask)
       
   370 						pixelPtr[0] &= bytemask;
       
   371 
       
   372 					if (x & 1)
       
   373 						pixelPtr++;
       
   374 					}
       
   375 				}
       
   376 			}
       
   377 
       
   378 		aData++;
       
   379 		}
       
   380 	}
       
   381 
       
   382 void CDrawFourBppBitmapColor::WriteBinaryLineVertical(TInt aX,TInt aY,TUint32* aData,TInt aLength,TRgb aColor,TBool aUp)
       
   383 	{
       
   384 	const TInt yLimit = aY + (aUp ? -aLength : aLength);
       
   385 	TUint32 color16 = aColor.Color16();
       
   386 	const TInt scanLineWords = aUp ? -iScanLineWords : iScanLineWords;
       
   387 	const TInt startWord = aX / KPixelsPerWord;
       
   388 	const TInt startShift = (aX & 7) * KBitsPerPixel;
       
   389 	TUint32* pixelPtr = ScanLine(aY) + startWord;
       
   390 	const TUint32* pixelPtrLimit = ScanLine(yLimit) + startWord;
       
   391 	const TUint32 mask = ~(0xf << startShift);
       
   392 	TUint32 dataMask = 1;
       
   393 
       
   394 	if (color16)
       
   395 		{
       
   396 		color16 <<= startShift;
       
   397 		while (pixelPtr != pixelPtrLimit)
       
   398 			{
       
   399 			if (!dataMask)
       
   400 				{
       
   401 				dataMask = 1;
       
   402 				aData++;
       
   403 				}
       
   404 
       
   405 			if (aData[0] & dataMask)
       
   406 				{
       
   407 				pixelPtr[0] &= mask;
       
   408 				pixelPtr[0] |= color16;
       
   409 				}
       
   410 
       
   411 			dataMask <<= 1;
       
   412 			pixelPtr += scanLineWords;
       
   413 			}
       
   414 		}
       
   415 	else
       
   416 		{
       
   417 		while (pixelPtr != pixelPtrLimit)
       
   418 			{
       
   419 			if (!dataMask)
       
   420 				{
       
   421 				dataMask = 1;
       
   422 				aData++;
       
   423 				}
       
   424 
       
   425 			if (aData[0] & dataMask)
       
   426 				pixelPtr[0] &= mask;
       
   427 
       
   428 			dataMask <<= 1;
       
   429 			pixelPtr += scanLineWords;
       
   430 			}
       
   431 		}
       
   432 	}
       
   433 
       
   434 void CDrawFourBppBitmapColor::WriteLine(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
       
   435 	{
       
   436 	const TInt startLong = (aX + KPixelsPerWord - 1) & (~7);
       
   437 	const TInt finishLong = (aX + aLength) & (~7);
       
   438 	const TInt startShift = (startLong - aX) * KBitsPerPixel;
       
   439 	const TInt startShiftExtra = 32 - startShift;
       
   440 	const TInt finishShift = (KPixelsPerWord - aX - aLength + finishLong) * KBitsPerPixel;
       
   441 	TUint32* base = ScanLine(aY);
       
   442 	TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
       
   443 	TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
       
   444 
       
   445 	if (finishLong < startLong)
       
   446 		{
       
   447 		const TUint32 mask = (0xffffffff >> finishShift) & (0xffffffff << startShiftExtra);
       
   448 
       
   449 		pixelPtrLimit[0] &= ~mask;
       
   450 		pixelPtrLimit[0] |= (aBuffer[0] << startShiftExtra) & mask;
       
   451 		pixelPtrLimit += iScanLineWords;
       
   452 		return;
       
   453 		}
       
   454 
       
   455 	const TInt wordsToCopy = pixelPtrLimit - pixelPtr;
       
   456 
       
   457 	if (startShift > 0)
       
   458 		{
       
   459 		pixelPtr[-1] = PasteInt(pixelPtr[-1],aBuffer[0] << startShiftExtra,startShift);
       
   460 
       
   461 		CopyOffset(pixelPtr,aBuffer,wordsToCopy,startShift);
       
   462 
       
   463 		aBuffer += wordsToCopy;
       
   464 
       
   465 		if (finishLong < aX + aLength)
       
   466 			{
       
   467 			TUint32 first = (aBuffer[0] >> startShift) | (aBuffer[1] << startShiftExtra);
       
   468 			pixelPtrLimit[0] = PasteInt(first,pixelPtrLimit[0],finishShift);
       
   469 			}
       
   470 		}
       
   471 	else
       
   472 		{
       
   473 		Mem::Copy(pixelPtr,aBuffer,wordsToCopy * sizeof(TUint32));
       
   474 
       
   475 		aBuffer += wordsToCopy;
       
   476 
       
   477 		if (finishLong < aX + aLength)
       
   478 			pixelPtrLimit[0] = PasteInt(aBuffer[0],pixelPtrLimit[0],finishShift);
       
   479 		}
       
   480 	}
       
   481 
       
   482 void CDrawFourBppBitmapColor::WriteLineXOR(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
       
   483 	{
       
   484 	const TInt startLong = (aX + KPixelsPerWord - 1) & (~7);
       
   485 	const TInt finishLong = (aX + aLength) & (~7);
       
   486 	const TInt startShift = (startLong - aX) * KBitsPerPixel;
       
   487 	const TInt startShiftExtra = 32 - startShift;
       
   488 	const TInt finishShift = (KPixelsPerWord - aX - aLength + finishLong) * KBitsPerPixel;
       
   489 	TUint32* base = ScanLine(aY);
       
   490 	TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
       
   491 	TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
       
   492 
       
   493 	if (finishLong < startLong)
       
   494 		{
       
   495 		pixelPtrLimit[0] ^= (aBuffer[0] << startShiftExtra) & (0xffffffff >> finishShift);
       
   496 		pixelPtrLimit += iScanLineWords;
       
   497 		return;
       
   498 		}
       
   499 
       
   500 	if (startShift > 0)
       
   501 		{
       
   502 		pixelPtr[-1] ^= PasteInt(0,aBuffer[0] << startShiftExtra,startShift);
       
   503 
       
   504 		while (pixelPtr < pixelPtrLimit)
       
   505 			{
       
   506 			pixelPtr[0] ^= (aBuffer[0] >> startShift) | (aBuffer[1] << startShiftExtra);
       
   507 
       
   508 			pixelPtr++;
       
   509 			aBuffer++;
       
   510 			}
       
   511 
       
   512 		if (finishLong < aX + aLength)
       
   513 			{
       
   514 			TUint32 first = (aBuffer[0] >> startShift) | (aBuffer[1] << startShiftExtra);
       
   515 			pixelPtrLimit[0] ^= PasteInt(first,0,finishShift);
       
   516 			}
       
   517 		}
       
   518 	else
       
   519 		{
       
   520 		while (pixelPtr < pixelPtrLimit)
       
   521 			*pixelPtr++ ^= *aBuffer++;
       
   522 
       
   523 		if (finishLong < aX + aLength)
       
   524 			pixelPtrLimit[0] ^= PasteInt(aBuffer[0],0,finishShift);
       
   525 		}
       
   526 	}
       
   527 
       
   528 void CDrawFourBppBitmapColor::WriteLineAND(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
       
   529 	{
       
   530 	const TInt startLong = (aX + KPixelsPerWord - 1) & (~7);
       
   531 	const TInt finishLong = (aX + aLength) & (~7);
       
   532 	const TInt startShift = (startLong - aX) * KBitsPerPixel;
       
   533 	const TInt startShiftExtra = 32 - startShift;
       
   534 	const TInt finishShift = (KPixelsPerWord - aX - aLength + finishLong) * KBitsPerPixel;
       
   535 	TUint32* base = ScanLine(aY);
       
   536 	TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
       
   537 	TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
       
   538 
       
   539 	if (finishLong < startLong)
       
   540 		{
       
   541 		const TUint32 mask = (0xffffffff >> finishShift) & (0xffffffff << startShiftExtra);
       
   542 
       
   543 		pixelPtrLimit[0] &= (aBuffer[0] << startShiftExtra) | ~mask;
       
   544 		pixelPtrLimit += iScanLineWords;
       
   545 		return;
       
   546 		}
       
   547 
       
   548 	if (startShift > 0)
       
   549 		{
       
   550 		pixelPtr[-1] &= PasteInt(0xffffffff,aBuffer[0] << startShiftExtra,startShift);
       
   551 
       
   552 		while (pixelPtr < pixelPtrLimit)
       
   553 			{
       
   554 			pixelPtr[0] &= (aBuffer[0] >> startShift) | (aBuffer[1] << startShiftExtra);
       
   555 
       
   556 			pixelPtr++;
       
   557 			aBuffer++;
       
   558 			}
       
   559 
       
   560 		if (finishLong < aX + aLength)
       
   561 			{
       
   562 			TUint32 first = (aBuffer[0] >> startShift) | (aBuffer[1] << startShiftExtra);
       
   563 			pixelPtrLimit[0] &= PasteInt(first,0xffffffff,finishShift);
       
   564 			}
       
   565 		}
       
   566 	else
       
   567 		{
       
   568 		while (pixelPtr < pixelPtrLimit)
       
   569 			*pixelPtr++ &= *aBuffer++;
       
   570 
       
   571 		if (finishLong < aX + aLength)
       
   572 			pixelPtrLimit[0] &= PasteInt(aBuffer[0],0xffffffff,finishShift);
       
   573 		}
       
   574 	}
       
   575 
       
   576 void CDrawFourBppBitmapColor::WriteLineOR(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
       
   577 	{
       
   578 	const TInt startLong = (aX + KPixelsPerWord - 1) & (~7);
       
   579 	const TInt finishLong = (aX + aLength) & (~7);
       
   580 	const TInt startShift = (startLong - aX) * KBitsPerPixel;
       
   581 	const TInt startShiftExtra = 32 - startShift;
       
   582 	const TInt finishShift = (KPixelsPerWord - aX - aLength + finishLong) * KBitsPerPixel;
       
   583 	TUint32* base = ScanLine(aY);
       
   584 	TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
       
   585 	TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
       
   586 
       
   587 	if (finishLong < startLong)
       
   588 		{
       
   589 		pixelPtrLimit[0] |= (aBuffer[0] << startShiftExtra) & (0xffffffff >> finishShift);
       
   590 		pixelPtrLimit += iScanLineWords;
       
   591 		return;
       
   592 		}
       
   593 
       
   594 	if (startShift > 0)
       
   595 		{
       
   596 		pixelPtr[-1] |= PasteInt(0,aBuffer[0] << startShiftExtra,startShift);
       
   597 
       
   598 		while (pixelPtr < pixelPtrLimit)
       
   599 			{
       
   600 			pixelPtr[0] |= (aBuffer[0] >> startShift) | (aBuffer[1] << startShiftExtra);
       
   601 
       
   602 			pixelPtr++;
       
   603 			aBuffer++;
       
   604 			}
       
   605 
       
   606 		if (finishLong < aX + aLength)
       
   607 			{
       
   608 			TUint32 first = (aBuffer[0] >> startShift) | (aBuffer[1] << startShiftExtra);
       
   609 			pixelPtrLimit[0] |= PasteInt(first,0,finishShift);
       
   610 			}
       
   611 		}
       
   612 	else
       
   613 		{
       
   614 		while (pixelPtr < pixelPtrLimit)
       
   615 			*pixelPtr++ |= *aBuffer++;
       
   616 
       
   617 		if (finishLong < aX + aLength)
       
   618 			pixelPtrLimit[0] |= PasteInt(aBuffer[0],0,finishShift);
       
   619 		}
       
   620 	}
       
   621 
       
   622 /**
       
   623 MAlphaBlend::WriteRgbAlphaLine() implementation.
       
   624 @see MAlphaBlend::WriteRgbAlphaLine()
       
   625 */
       
   626 void CDrawFourBppBitmapColor::WriteRgbAlphaLine(TInt aX, TInt aY, TInt aLength,
       
   627                                                 const TUint8* aRgbBuffer,
       
   628                                                 const TUint8* aMaskBuffer,
       
   629                                                 MAlphaBlend::TShadowing aShadowing,
       
   630                                                 CGraphicsContext::TDrawMode /*aDrawMode*/)
       
   631     {
       
   632 	TUint8* pixelPtr = REINTERPRET_CAST(TUint8*,ScanLine(aY)) + (aX / 2);
       
   633 	TRgb pixelColor;
       
   634 
       
   635 	if (aX & 1)
       
   636 		{
       
   637         TRgb srcColor(aRgbBuffer[2],aRgbBuffer[1],aRgbBuffer[0]);
       
   638         if(aShadowing == MAlphaBlend::EShdwBefore)
       
   639             {
       
   640 		    Shadow(srcColor);
       
   641             }
       
   642         pixelColor = ::AlphaBlend(srcColor,TRgb::Color16(pixelPtr[0] >> 4),aMaskBuffer[0]);
       
   643         if(aShadowing == MAlphaBlend::EShdwAfter)
       
   644             {
       
   645 		    Shadow(pixelColor);
       
   646             }
       
   647 		MapColorToUserDisplayMode(pixelColor);
       
   648 		pixelPtr[0] &= 0x0f;
       
   649 		pixelPtr[0] |= TUint8(pixelColor.Color16() << 4);
       
   650 
       
   651 		pixelPtr++;
       
   652 		aRgbBuffer += 4;
       
   653 		aMaskBuffer++;
       
   654 		aLength--;
       
   655 		}
       
   656 
       
   657 	const TUint8* pixelPtrLimit = pixelPtr + (aLength / 2);
       
   658 	TRgb pixelColor1, pixelColor2;
       
   659 	
       
   660 	while (pixelPtr < pixelPtrLimit)
       
   661 		{
       
   662         TRgb srcColor1(aRgbBuffer[2],aRgbBuffer[1],aRgbBuffer[0]);
       
   663         if(aShadowing == MAlphaBlend::EShdwBefore)
       
   664             {
       
   665 		    Shadow(srcColor1);
       
   666             }
       
   667         pixelColor1 = ::AlphaBlend(srcColor1,TRgb::Color16(pixelPtr[0] & 0x0f),aMaskBuffer[0]);
       
   668         if(aShadowing == MAlphaBlend::EShdwAfter)
       
   669             {
       
   670 		    Shadow(pixelColor1);
       
   671             }
       
   672 		MapColorToUserDisplayMode(pixelColor1);
       
   673 
       
   674         TRgb srcColor2(aRgbBuffer[6],aRgbBuffer[5],aRgbBuffer[4]);
       
   675         if(aShadowing == MAlphaBlend::EShdwBefore)
       
   676             {
       
   677 		    Shadow(srcColor2);
       
   678             }
       
   679         pixelColor2 = ::AlphaBlend(srcColor2,TRgb::Color16(pixelPtr[0] >> 4),aMaskBuffer[1]);
       
   680         if(aShadowing == MAlphaBlend::EShdwAfter)
       
   681             {
       
   682 		    Shadow(pixelColor2);
       
   683             }
       
   684 		MapColorToUserDisplayMode(pixelColor2);
       
   685 
       
   686 		pixelPtr[0] = TUint8(pixelColor1.Color16());
       
   687 		pixelPtr[0] |= TUint8(pixelColor2.Color16() << 4);
       
   688 
       
   689 		pixelPtr++;
       
   690 		aRgbBuffer += 8;
       
   691 		aMaskBuffer += 2;
       
   692 		}
       
   693 
       
   694 	if (aLength & 1)
       
   695 		{
       
   696         TRgb srcColor(aRgbBuffer[2],aRgbBuffer[1],aRgbBuffer[0]);
       
   697         if(aShadowing == MAlphaBlend::EShdwBefore)
       
   698             {
       
   699 		    Shadow(srcColor);
       
   700             }
       
   701         pixelColor = ::AlphaBlend(srcColor,TRgb::Color16(pixelPtr[0] & 0x0f),aMaskBuffer[0]);
       
   702         if(aShadowing == MAlphaBlend::EShdwAfter)
       
   703             {
       
   704 		    Shadow(pixelColor);
       
   705             }
       
   706 		MapColorToUserDisplayMode(pixelColor);
       
   707 		pixelPtr[0] &= 0xf0;
       
   708 		pixelPtr[0] |= TUint8(pixelColor.Color16());
       
   709 		}
       
   710 	}
       
   711 
       
   712 void CDrawFourBppBitmapColor::WriteRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
       
   713 	{
       
   714 	const TInt startLong = (aX + KPixelsPerWord - 1) & (~7);
       
   715 	const TInt finishLong = (aX + aLength) & (~7);
       
   716 	const TInt startShift = (startLong - aX) * KBitsPerPixel;
       
   717 	const TInt startShiftExtra = 32 - startShift;
       
   718 	const TInt finishShift = (KPixelsPerWord - aX - aLength + finishLong) * KBitsPerPixel;
       
   719 	const TInt yLimit = aY + aHeight;
       
   720 	TUint32 colorWord = ColorInt(aColor);
       
   721 	TUint32* base = ScanLine(aY);
       
   722 	TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
       
   723 	TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
       
   724 
       
   725 	if (finishLong < startLong)
       
   726 		{
       
   727 		TUint32 mask = (0xffffffff >> finishShift) & (0xffffffff << startShiftExtra);
       
   728 		colorWord &= mask;
       
   729 		mask = ~mask;
       
   730 
       
   731 		for (; aY < yLimit; aY++)
       
   732 			{
       
   733 			pixelPtrLimit[0] &= mask;
       
   734 			pixelPtrLimit[0] |= colorWord;
       
   735 			pixelPtrLimit += iScanLineWords;
       
   736 			}
       
   737 		return;
       
   738 		}
       
   739 
       
   740 	for (; aY < yLimit; aY++)
       
   741 		{
       
   742 		if (startShift > 0)
       
   743 			pixelPtr[-1] = PasteInt(pixelPtr[-1],colorWord,startShift);
       
   744 
       
   745 		for (TUint32* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
       
   746 			tempPixelPtr[0] = colorWord;
       
   747 
       
   748 		if (finishLong < aX + aLength)
       
   749 			pixelPtrLimit[0] = PasteInt(colorWord,pixelPtrLimit[0],finishShift);
       
   750 
       
   751 		pixelPtr += iScanLineWords;
       
   752 		pixelPtrLimit += iScanLineWords;
       
   753 		}
       
   754 	}
       
   755 
       
   756 void CDrawFourBppBitmapColor::WriteRgbMultiXOR(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
       
   757 	{
       
   758 	const TInt startLong = (aX + KPixelsPerWord - 1) & (~7);
       
   759 	const TInt finishLong = (aX + aLength) & (~7);
       
   760 	const TInt startShift = (startLong - aX) * KBitsPerPixel;
       
   761 	const TInt startShiftExtra = 32 - startShift;
       
   762 	const TInt finishShift = (KPixelsPerWord - aX - aLength + finishLong) * KBitsPerPixel;
       
   763 	const TInt yLimit = aY + aHeight;
       
   764 	TUint32 colorWord = ColorInt(aColor);
       
   765 	TUint32* base = ScanLine(aY);
       
   766 	TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
       
   767 	TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
       
   768 
       
   769 	if (finishLong < startLong)
       
   770 		{
       
   771 		TUint32 mask = (0xffffffff >> finishShift) & (0xffffffff << startShiftExtra);
       
   772 		colorWord &= mask;
       
   773 
       
   774 		for (; aY < yLimit; aY++)
       
   775 			{
       
   776 			pixelPtrLimit[0] ^= colorWord;
       
   777 			pixelPtrLimit += iScanLineWords;
       
   778 			}
       
   779 		return;
       
   780 		}
       
   781 
       
   782 	for (; aY < yLimit; aY++)
       
   783 		{
       
   784 		if (startShift > 0)
       
   785 			pixelPtr[-1] ^= PasteInt(0,colorWord,startShift);
       
   786 
       
   787 		for (TUint32* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
       
   788 			tempPixelPtr[0] ^= colorWord;
       
   789 
       
   790 		if (finishLong < aX + aLength)
       
   791 			pixelPtrLimit[0] ^= PasteInt(colorWord,0,finishShift);
       
   792 
       
   793 		pixelPtr += iScanLineWords;
       
   794 		pixelPtrLimit += iScanLineWords;
       
   795 		}
       
   796 	}
       
   797 
       
   798 void CDrawFourBppBitmapColor::WriteRgbMultiAND(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
       
   799 	{
       
   800 	const TInt startLong = (aX + KPixelsPerWord - 1) & (~7);
       
   801 	const TInt finishLong = (aX + aLength) & (~7);
       
   802 	const TInt startShift = (startLong - aX) * KBitsPerPixel;
       
   803 	const TInt startShiftExtra = 32 - startShift;
       
   804 	const TInt finishShift = (KPixelsPerWord - aX - aLength + finishLong) * KBitsPerPixel;
       
   805 	const TInt yLimit = aY + aHeight;
       
   806 	TUint32 colorWord = ColorInt(aColor);
       
   807 	TUint32* base = ScanLine(aY);
       
   808 	TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
       
   809 	TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
       
   810 
       
   811 	if (finishLong < startLong)
       
   812 		{
       
   813 		TUint32 mask = (0xffffffff >> finishShift) & (0xffffffff << startShiftExtra);
       
   814 		colorWord &= mask;
       
   815 		colorWord |= ~mask;
       
   816 
       
   817 		for (; aY < yLimit; aY++)
       
   818 			{
       
   819 			pixelPtrLimit[0] &= colorWord;
       
   820 			pixelPtrLimit += iScanLineWords;
       
   821 			}
       
   822 		return;
       
   823 		}
       
   824 
       
   825 	for (; aY < yLimit; aY++)
       
   826 		{
       
   827 		if (startShift > 0)
       
   828 			pixelPtr[-1] &= PasteInt(0xffffffff,colorWord,startShift);
       
   829 
       
   830 		for (TUint32* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
       
   831 			tempPixelPtr[0] &= colorWord;
       
   832 
       
   833 		if (finishLong < aX + aLength)
       
   834 			pixelPtrLimit[0] &= PasteInt(colorWord,0xffffffff,finishShift);
       
   835 
       
   836 		pixelPtr += iScanLineWords;
       
   837 		pixelPtrLimit += iScanLineWords;
       
   838 		}
       
   839 	}
       
   840 
       
   841 void CDrawFourBppBitmapColor::WriteRgbMultiOR(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
       
   842 	{
       
   843 	const TInt startLong = (aX + KPixelsPerWord - 1) & (~7);
       
   844 	const TInt finishLong = (aX + aLength) & (~7);
       
   845 	const TInt startShift = (startLong - aX) * KBitsPerPixel;
       
   846 	const TInt startShiftExtra = 32 - startShift;
       
   847 	const TInt finishShift = (KPixelsPerWord - aX - aLength + finishLong) * KBitsPerPixel;
       
   848 	const TInt yLimit = aY + aHeight;
       
   849 	TUint32 colorWord = ColorInt(aColor);
       
   850 	TUint32* base = ScanLine(aY);
       
   851 	TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
       
   852 	TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
       
   853 
       
   854 	if (finishLong < startLong)
       
   855 		{
       
   856 		TUint32 mask = (0xffffffff >> finishShift) & (0xffffffff << startShiftExtra);
       
   857 		colorWord &= mask;
       
   858 
       
   859 		for (; aY < yLimit; aY++)
       
   860 			{
       
   861 			pixelPtrLimit[0] |= colorWord;
       
   862 			pixelPtrLimit += iScanLineWords;
       
   863 			}
       
   864 		return;
       
   865 		}
       
   866 
       
   867 	for (; aY < yLimit; aY++)
       
   868 		{
       
   869 		if (startShift > 0)
       
   870 			pixelPtr[-1] |= PasteInt(0,colorWord,startShift);
       
   871 
       
   872 		for (TUint32* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
       
   873 			tempPixelPtr[0] |= colorWord;
       
   874 
       
   875 		if (finishLong < aX + aLength)
       
   876 			pixelPtrLimit[0] |= PasteInt(colorWord,0,finishShift);
       
   877 
       
   878 		pixelPtr += iScanLineWords;
       
   879 		pixelPtrLimit += iScanLineWords;
       
   880 		}
       
   881 	}
       
   882 
       
   883 void CDrawFourBppBitmapColor::WriteRgbAlphaMulti(TInt aX,TInt aY,TInt aLength,TRgb aColor,const TUint8* aMaskBuffer)
       
   884 	{
       
   885 	DeOrientate(aX,aY);
       
   886 	TUint8* pixelPtr = REINTERPRET_CAST(TUint8*,ScanLine(aY)) + (aX / 2);
       
   887 	const TBool oddEndCoord = (aX + aLength) & 1;
       
   888 	const TUint8* maskBufferPtrLimit = aMaskBuffer + aLength - (oddEndCoord ? 1 : 0);
       
   889 
       
   890 	if (iShadowMode)
       
   891 		Shadow(aColor);
       
   892 
       
   893 	const TInt red = aColor.Red();
       
   894 	const TInt green = aColor.Green();
       
   895 	const TInt blue = aColor.Blue();
       
   896 	
       
   897 	TRgb pixelColor;
       
   898 	
       
   899 	if (aX & 1)
       
   900 		{
       
   901 		pixelColor = AlphaBlend(red,green,blue,TRgb::Color16(pixelPtr[0] >> 4),aMaskBuffer[0]);
       
   902 		pixelPtr[0] &= 0x0f;
       
   903 		pixelPtr[0] |= TUint8(pixelColor.Color16() << 4);
       
   904 
       
   905 		pixelPtr++;
       
   906 		aMaskBuffer++;
       
   907 		}
       
   908 
       
   909 	TRgb lowerPixelColor, upperPixelColor;
       
   910 	
       
   911 	while (aMaskBuffer < maskBufferPtrLimit)
       
   912 		{
       
   913 		lowerPixelColor = AlphaBlend(red,green,blue,TRgb::Color16(pixelPtr[0] & 0x0f),aMaskBuffer[0]);
       
   914 		upperPixelColor = AlphaBlend(red,green,blue,TRgb::Color16(pixelPtr[0] >> 4),aMaskBuffer[1]);
       
   915 		pixelPtr[0] = TUint8(lowerPixelColor.Color16());
       
   916 		pixelPtr[0] |= TUint8(upperPixelColor.Color16() << 4);
       
   917 
       
   918 		pixelPtr++;
       
   919 		aMaskBuffer += 2;
       
   920 		}
       
   921 
       
   922 	if (oddEndCoord)
       
   923 		{
       
   924 		pixelColor = AlphaBlend(red,green,blue,TRgb::Color16(pixelPtr[0] & 0x0f),aMaskBuffer[0]);
       
   925 		pixelPtr[0] &= 0xf0;
       
   926 		pixelPtr[0] |= TUint8(pixelColor.Color16());
       
   927 		}
       
   928 	}
       
   929 
       
   930 void CDrawFourBppBitmapColor::MapColorToUserDisplayMode(TRgb& aColor)
       
   931 	{
       
   932 	switch (iUserDispMode)
       
   933 		{
       
   934 	case EGray2:
       
   935 		aColor = TRgb::_Gray2(aColor._Gray2());
       
   936 		break;
       
   937 	case EGray4:
       
   938 	case EGray16:// EGray16 can't be done - nearest is EGray4
       
   939 	case EGray256:// EGray256 can't be done - nearest is EGray4
       
   940 		aColor = TRgb::_Gray4(aColor._Gray4());
       
   941 		break;
       
   942 	default:
       
   943 		break;
       
   944 		}
       
   945 	}
       
   946 
       
   947 void CDrawFourBppBitmapColor::MapBufferToUserDisplayMode(TInt aLength,TUint32* aBuffer)
       
   948 	{
       
   949 	TUint8* bufferPtr = (TUint8*)aBuffer;
       
   950 	const TUint8* bufferLimit = bufferPtr + ((aLength + 1) / 2);
       
   951 	TRgb color1, color2;
       
   952 	
       
   953 	switch (iUserDispMode)
       
   954 		{
       
   955 	case EGray2:
       
   956 		while (bufferPtr < bufferLimit)
       
   957 			{
       
   958 			color1 = TRgb::Color16(*bufferPtr & 0xf);
       
   959 			color2 = TRgb::Color16(*bufferPtr >> 4);
       
   960 			color1 = TRgb::_Gray2(color1._Gray2());
       
   961 			color2 = TRgb::_Gray2(color2._Gray2());
       
   962 			*bufferPtr++ = TUint8(color1.Color16() | (color2.Color16() << 4));
       
   963 			}
       
   964 		break;
       
   965 	case EGray4:
       
   966 	case EGray16:// EGray256 can't be done - nearest is EGray4
       
   967 	case EGray256:// EGray256 can't be done - nearest is EGray4
       
   968 		while (bufferPtr < bufferLimit)
       
   969 			{
       
   970 			color1 = TRgb::Color16(*bufferPtr & 0xf);
       
   971 			color2 = TRgb::Color16(*bufferPtr >> 4);
       
   972 			color1 = TRgb::_Gray4(color1._Gray4());
       
   973 			color2 = TRgb::_Gray4(color2._Gray4());
       
   974 			*bufferPtr++ = TUint8(color1.Color16() | (color2.Color16() << 4));
       
   975 			}
       
   976 		break;
       
   977 	default:
       
   978 		break;
       
   979 		}
       
   980 	}
       
   981 
       
   982 TInt CDrawFourBppBitmapColor::WriteRgbOutlineAndShadow(TInt aX, TInt aY, const TInt aLength,
       
   983 														TUint32 aOutlinePenColor, TUint32 aShadowColor,
       
   984 														TUint32 aFillColor, const TUint8* aDataBuffer)
       
   985 	{
       
   986 	//This is non-optimised since this screen mode is rarely used and is usually 
       
   987 	//fast enough without optimisation.
       
   988 	DeOrientate(aX,aY);
       
   989 	TUint8* pixelPtr = REINTERPRET_CAST(TUint8*,ScanLine(aY)) + (aX / 2);
       
   990 	const TBool oddEndCoord = (aX + aLength) & 1;
       
   991 	const TUint8* dataBufferPtrLimit = aDataBuffer + aLength - (oddEndCoord ? 1 : 0);
       
   992 
       
   993 	TUint8 index = 0;
       
   994 	TRgb finalColor;
       
   995 	TRgb lowerPixelColor;
       
   996 	TRgb upperPixelColor;
       
   997 
       
   998 	TRgb outlinePenColor;
       
   999 	outlinePenColor.SetInternal(aOutlinePenColor);
       
  1000 	TRgb shadowColor;
       
  1001 	shadowColor.SetInternal(aShadowColor);
       
  1002 	TRgb fillColor;
       
  1003 	fillColor.SetInternal(aFillColor);
       
  1004 
       
  1005 	const TInt redOutlinePenColor = outlinePenColor.Red();
       
  1006 	const TInt redShadowColor = shadowColor.Red();
       
  1007 	const TInt redFillColor = fillColor.Red();
       
  1008 
       
  1009 	const TInt greenOutlinePenColor = outlinePenColor.Green();
       
  1010 	const TInt greenShadowColor = shadowColor.Green();
       
  1011 	const TInt greenFillColor = fillColor.Green();
       
  1012 
       
  1013 	const TInt blueOutlinePenColor = outlinePenColor.Blue();
       
  1014 	const TInt blueShadowColor = shadowColor.Blue();
       
  1015 	const TInt blueFillColor = fillColor.Blue();
       
  1016 
       
  1017 	if (aX & 1)
       
  1018 		{
       
  1019 		index = *aDataBuffer;
       
  1020 		if (255 != FourColorBlendLookup[index][KBackgroundColorIndex])
       
  1021 			{
       
  1022 			TRgb backgroundColor = TRgb::Color16(pixelPtr[0] >> 4);
       
  1023 			finalColor = BlendFourColors(aOutlinePenColor, aShadowColor, aFillColor,
       
  1024 										redOutlinePenColor, redShadowColor, redFillColor,
       
  1025 										greenOutlinePenColor, greenShadowColor, greenFillColor,
       
  1026 										blueOutlinePenColor, blueShadowColor, blueFillColor,
       
  1027 										backgroundColor, index);
       
  1028 			pixelPtr[0] &= 0x0f;
       
  1029 			pixelPtr[0] |= TUint8(finalColor.Color16() << 4);
       
  1030 			}
       
  1031 		pixelPtr++;
       
  1032 		aDataBuffer++;
       
  1033 		}
       
  1034 
       
  1035 	while (aDataBuffer < dataBufferPtrLimit)
       
  1036 		{
       
  1037 		index = aDataBuffer[0];
       
  1038 		TRgb upperPixelBackgroundColor = TRgb::Color16(pixelPtr[0] >> 4);
       
  1039 		if (255 != FourColorBlendLookup[index][KBackgroundColorIndex])
       
  1040 			{
       
  1041 			TRgb lowerPixelBackgroundColor = TRgb::Color16(pixelPtr[0] & 0x0f );
       
  1042 			lowerPixelColor = BlendFourColors(aOutlinePenColor, aShadowColor, aFillColor,
       
  1043 											redOutlinePenColor, redShadowColor, redFillColor,
       
  1044 											greenOutlinePenColor, greenShadowColor, greenFillColor,
       
  1045 											blueOutlinePenColor, blueShadowColor, blueFillColor,
       
  1046 											lowerPixelBackgroundColor, index);
       
  1047 			pixelPtr[0] = TUint8(lowerPixelColor.Color16());
       
  1048 			}
       
  1049 		
       
  1050 		index = aDataBuffer[1];
       
  1051 		if (255 != FourColorBlendLookup[index][KBackgroundColorIndex])
       
  1052 			{
       
  1053 			upperPixelColor = BlendFourColors(aOutlinePenColor, aShadowColor, aFillColor,
       
  1054 											redOutlinePenColor, redShadowColor, redFillColor,
       
  1055 											greenOutlinePenColor, greenShadowColor, greenFillColor,
       
  1056 											blueOutlinePenColor, blueShadowColor, blueFillColor,
       
  1057 											upperPixelBackgroundColor, index);
       
  1058 			pixelPtr[0] |= TUint8(upperPixelColor.Color16() << 4);
       
  1059 			}
       
  1060 		pixelPtr++;
       
  1061 		aDataBuffer += 2;
       
  1062 		}
       
  1063 
       
  1064 	if (oddEndCoord)
       
  1065 		{
       
  1066 		index = aDataBuffer[0];
       
  1067 		if(255 != FourColorBlendLookup[index][KBackgroundColorIndex])
       
  1068 			{
       
  1069 			TRgb backgroundColor = TRgb::Color16(pixelPtr[0] & 0x0f );
       
  1070 			finalColor = BlendFourColors(aOutlinePenColor, aShadowColor, aFillColor,
       
  1071 										redOutlinePenColor, redShadowColor, redFillColor,
       
  1072 										greenOutlinePenColor, greenShadowColor, greenFillColor,
       
  1073 										blueOutlinePenColor, blueShadowColor, blueFillColor,
       
  1074 										backgroundColor, index);
       
  1075 			pixelPtr[0] &= 0xf0;
       
  1076 			pixelPtr[0] |= TUint8(finalColor.Color16());
       
  1077 			}
       
  1078 		}
       
  1079 	return KErrNone;
       
  1080 	}
       
  1081 
       
  1082 TRgb CDrawFourBppBitmapColor::BlendFourColors(TUint32 aOutlinePenColor, TUint32 aShadowColor, TUint32 aFillColor,
       
  1083 											TInt aRedOutlinePenColor, TInt aRedShadowColor,TInt aRedFillColor,
       
  1084 											TInt aGreenOutlinePenColor, TInt aGreenShadowColor, TInt aGreenFillColor,
       
  1085 											TInt aBlueOutlinePenColor,	TInt aBlueShadowColor,	TInt aBlueFillColor,
       
  1086 											TRgb aBackgroundColor, TUint8 aIndex) const
       
  1087 	{
       
  1088 	TRgb finalColor;
       
  1089 	if (255 == FourColorBlendLookup[aIndex][KFillColorIndex])
       
  1090 		{
       
  1091 		//fill colour
       
  1092 		finalColor.SetInternal(aFillColor);
       
  1093 		}
       
  1094 	else if (255 == FourColorBlendLookup[aIndex][KShadowColorIndex])
       
  1095 		{
       
  1096 		//Shadow colour
       
  1097 		finalColor.SetInternal(aShadowColor);
       
  1098 		}
       
  1099 	else if (255 == FourColorBlendLookup[aIndex][KOutlineColorIndex])
       
  1100 		{
       
  1101 		//Outline colour
       
  1102 		finalColor.SetInternal(aOutlinePenColor);
       
  1103 		}
       
  1104 	else
       
  1105 		{
       
  1106 		TInt blendedRedColor = (aRedOutlinePenColor * FourColorBlendLookup[aIndex][KOutlineColorIndex] + 
       
  1107 						   		aRedShadowColor * FourColorBlendLookup[aIndex][KShadowColorIndex] +
       
  1108 						  		aRedFillColor * FourColorBlendLookup[aIndex][KFillColorIndex] + 
       
  1109 						  		aBackgroundColor.Red() * FourColorBlendLookup[aIndex][KBackgroundColorIndex]) >> 8;
       
  1110 
       
  1111 		TInt blendedGreenColor = (aGreenOutlinePenColor * FourColorBlendLookup[aIndex][KOutlineColorIndex] + 
       
  1112 								aGreenShadowColor * FourColorBlendLookup[aIndex][KShadowColorIndex] +
       
  1113 								aGreenFillColor * FourColorBlendLookup[aIndex][KFillColorIndex] + 
       
  1114 								aBackgroundColor.Green() * FourColorBlendLookup[aIndex][KBackgroundColorIndex]) >> 8;
       
  1115 
       
  1116 		TInt blendedBlueColor = (aBlueOutlinePenColor * FourColorBlendLookup[aIndex][KOutlineColorIndex] + 
       
  1117 								aBlueShadowColor * FourColorBlendLookup[aIndex][KShadowColorIndex] +
       
  1118 								aBlueFillColor * FourColorBlendLookup[aIndex][KFillColorIndex] + 
       
  1119 								aBackgroundColor.Blue() * FourColorBlendLookup[aIndex][KBackgroundColorIndex]) >> 8;
       
  1120 		finalColor = TRgb(blendedRedColor, blendedGreenColor, blendedBlueColor);
       
  1121 		}
       
  1122 	return finalColor;
       
  1123 	}