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