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