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