os/graphics/graphicsdeviceinterface/screendriver/sbit/BMDRAW8.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #include "BMDRAW.H"
    17 #include "BitDrawInterfaceId.h"
    18 
    19 // CDrawEightBppBitmapCommon
    20 //EColor256 screen/bitmap device might be scaled.
    21 //In this case right-bottom coordinate might go outside the drawing rectangle.
    22 //Then - we need to check that we do not try to draw something outside the drawing rectangle.
    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 CDrawEightBppBitmapCommon::SetSize(const TSize& aSize) 
    30 	{
    31 	CDrawBitmap::SetSize(aSize);
    32 	__ASSERT_DEBUG(iSize == aSize, User::Invariant());
    33 	iLongWidth = (iSize.iWidth + 3) & ~3;
    34 	iScanLineWords = iLongWidth / 4;
    35 	}
    36  
    37 TInt CDrawEightBppBitmapCommon::Construct(TSize aSize, TInt aStride)
    38 	{
    39 	iBits = NULL;
    40 	CDrawBitmap::SetSize(aSize);
    41 	__ASSERT_DEBUG(iSize == aSize, User::Invariant());
    42 	if (aStride & 3)
    43 		return KErrArgument;
    44 	iLongWidth = aStride;
    45 	if (iLongWidth < aSize.iWidth)
    46 		return KErrArgument;
    47 	iScanLineWords = aStride >> 2;
    48 	TInt size = Max(aSize.iWidth,aSize.iHeight);
    49 	if(size < 0)
    50 		return KErrArgument;
    51 	iScanLineBuffer = (TUint32*)(User::Heap().Alloc(size));
    52 	if(iScanLineBuffer == NULL)
    53 		return KErrNoMemory;
    54 	return KErrNone;
    55 	}
    56 
    57 //aX, aY - physical coordinates
    58 TUint8* CDrawEightBppBitmapCommon::PixelAddress(TInt aX,TInt aY) const
    59 	{
    60 	return (TUint8*)iBits + aY * iLongWidth + aX;
    61 	}
    62 
    63 void CDrawEightBppBitmapCommon::InvertBuffer(TInt aLength,TUint32* aBuffer)
    64 	{
    65 	const TUint32* limit = aBuffer + (aLength + 3) / 4;
    66 
    67 	while (aBuffer < limit)
    68 		*aBuffer++ ^= 0xffffffff;
    69 	}
    70 
    71 //CDrawEightBppBitmapCommon::ReadLine() called from CDrawBitmap::ReadLine()
    72 //aX and aY - physical coordinates.
    73 //Reads aLength pixel values and places them in aBuffer.
    74 //aBuffer size should be at least aLength.
    75 void CDrawEightBppBitmapCommon::ReadLine(TInt aX,TInt aY,TInt aLength,TAny* aBuffer) const
    76 	{
    77 	const TUint8* pixelPtr = PixelAddress(aX,aY);
    78 
    79 	if (iOrientation == EOrientationNormal && iScalingOff)
    80 		Mem::Copy(aBuffer,pixelPtr,aLength);
    81 	else
    82 		{
    83 		register TInt pixelPtrInc = LogicalPixelAddressIncrement();
    84 
    85 		TUint8* bufferPtr = static_cast <TUint8*> (aBuffer);
    86 		const TUint8* bufferPtrLimit = bufferPtr + aLength;
    87 
    88 		while (bufferPtr < bufferPtrLimit)
    89 			{
    90 			*bufferPtr++ = *pixelPtr;
    91 			pixelPtr += pixelPtrInc;
    92 			}
    93 		}
    94 	}
    95 
    96 //CDrawEightBppBitmapCommon::WriteRgb() called from exported CDrawBitmap::WriteRgb()
    97 //aX, aY - physical coordinates
    98 void CDrawEightBppBitmapCommon::WriteRgb(TInt aX,TInt aY,TUint8 aPixel)
    99 	{
   100 	register TUint8* pixelAddr = PixelAddress(aX, aY);
   101 	if(iScalingOff)
   102 		{
   103 		*pixelAddr = aPixel;
   104 		}
   105 	else
   106 		{
   107 		const TUint8* bitsStart = reinterpret_cast <const TUint8*> (iBits);
   108 		const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
   109 		const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
   110 		SetPixels(pixelAddr, aPixel, pixelRowPtrLimit, bitsStart, bitsEnd);
   111 		}
   112 	}
   113 
   114 //CDrawEightBppBitmapCommon::WriteBinary() called from exported CDrawBitmap::WriteBinary()
   115 //aX, aY - logical coordinates
   116 //"aData" parameter has "aHeight" 32 bits words
   117 //"aLength" parameter tells how many bits (up to 32) has to be used from each 32 bit word
   118 //This method is used for bitmap font symbols drawing
   119 //One possible optimization: If "no scaling" And "pixelPtrInc == 1" Then
   120 //writing could be made on 32 bits words (they has to be aligned before the operation)
   121 void CDrawEightBppBitmapCommon::WriteBinary(TInt aX,TInt aY,TUint32* aData,TInt aLength,
   122 											TInt aHeight,TUint8 aPixel)
   123 	{
   124 	DeOrientate(aX,aY);//aX, aY - physical coordinates
   125 	TInt pixelInc;
   126 	TInt rowInc;
   127 	SetPixelInc(pixelInc, rowInc);
   128 	const TUint32* dataLimit = aData + aHeight;
   129 	register TUint32 dataMaskLimit = (aLength < 32) ? 1 << aLength : 0;
   130 	TUint8* pixelPtr = PixelAddress(aX,aY);
   131 	const TUint8* bitsStart = reinterpret_cast <const TUint8*> (iBits);
   132 	const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
   133 	TInt orgY = aY;
   134 	while (aData < dataLimit)
   135 		{
   136 		register TUint32 dataWord = *aData++;
   137 		register TUint32 dataMask = 1;
   138 		register TUint8* tempPixelPtr = pixelPtr;
   139 		if(iScalingOff)
   140 			{
   141 			while (dataMask != dataMaskLimit)
   142 				{
   143 				if(dataWord & dataMask)
   144 					{
   145 					*tempPixelPtr = aPixel;
   146 					}
   147 				tempPixelPtr += pixelInc;
   148 				dataMask <<= 1;
   149 				}
   150 			}
   151 		else
   152 			{
   153 			while (dataMask != dataMaskLimit)
   154 				{
   155 				if(dataWord & dataMask)
   156 					{
   157 					const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
   158 					SetPixels(tempPixelPtr, aPixel, pixelRowPtrLimit, bitsStart, bitsEnd);
   159 					}
   160 				tempPixelPtr += pixelInc;
   161 				dataMask <<= 1;
   162 				IncScaledY(aY);
   163 				}
   164 			}
   165 		pixelPtr += rowInc;
   166 		IncScaledY(aY, orgY);
   167 		}
   168 	}
   169 
   170 //CDrawEightBppBitmapCommon::WriteBinaryOp() called from exported CDrawBitmap::WriteBinary()
   171 //aX, aY - logical coordinates
   172 //"aData" parameter has "aHeight" 32 bits words
   173 //"aLength" parameter tells how many bits (up to 32) has to be used from each 32 bit word
   174 //This method is used for bitmap font symbols drawing
   175 //One possible optimization: If "no scaling" And "pixelPtrInc == 1" Then
   176 //writing could be made on 32 bits words (they has to be aligned before the operation)
   177 void CDrawEightBppBitmapCommon::WriteBinaryOp(TInt aX,TInt aY,TUint32* aData,TInt aLength,
   178 											  TInt aHeight,TUint8 aPixel,
   179 											  CGraphicsContext::TDrawMode aDrawMode)
   180 	{
   181 	if(aLength <= 0)
   182 		{
   183 		return;
   184 		}
   185 	DeOrientate(aX,aY);//aX, aY - physical coordinates
   186 	TUint8* pixelPtr = PixelAddress(aX,aY);
   187 	const TUint32* dataPtrLimit = aData + aHeight;
   188 	register TUint32 dataMaskLimit = (aLength < 32) ? 1 << aLength : 0;
   189 	TInt pixelInc;
   190 	TInt rowInc;
   191 	SetPixelInc(pixelInc, rowInc);
   192 	const TUint8* bitsStart = reinterpret_cast <const TUint8*> (iBits);
   193 	const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
   194 	TInt orgY = aY;
   195 	if(aPixel)
   196 		{
   197 		while(aData < dataPtrLimit)
   198 			{
   199 			register TUint32 dataWord = *aData++;
   200 			register TUint32 dataMask = 1;
   201 			register TUint8* tempPixelPtr = pixelPtr;
   202 			if(iScalingOff)
   203 				{
   204 				while(dataMask != dataMaskLimit)
   205 					{
   206 					if(dataWord & dataMask)
   207 						{
   208 						if(aDrawMode==CGraphicsContext::EDrawModeXOR)
   209 							{
   210 							*tempPixelPtr ^= aPixel;
   211 							}
   212 						else if(aDrawMode==CGraphicsContext::EDrawModeAND)
   213 							{
   214 							*tempPixelPtr &= aPixel;
   215 							}
   216 						else if(aDrawMode==CGraphicsContext::EDrawModeOR)
   217 							{
   218 							*tempPixelPtr |= aPixel;
   219 							}
   220 						}
   221 					tempPixelPtr += pixelInc;
   222 					dataMask <<= 1;
   223 					}
   224 				}
   225 			else
   226 				{
   227 				while(dataMask != dataMaskLimit)
   228 					{
   229 					if(dataWord & dataMask)
   230 						{
   231 						const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
   232 						if(aDrawMode==CGraphicsContext::EDrawModeXOR)
   233 							{
   234 							XORPixels(tempPixelPtr, aPixel, pixelRowPtrLimit, bitsStart, bitsEnd);
   235 							}
   236 						else if(aDrawMode==CGraphicsContext::EDrawModeAND)
   237 							{
   238 							ANDPixels(tempPixelPtr, aPixel, pixelRowPtrLimit, bitsStart, bitsEnd);
   239 							}
   240 						else if(aDrawMode==CGraphicsContext::EDrawModeOR)
   241 							{
   242 							ORPixels(tempPixelPtr, aPixel, pixelRowPtrLimit, bitsStart, bitsEnd);
   243 							}
   244 						}
   245 					tempPixelPtr += pixelInc;
   246 					dataMask <<= 1;
   247 					IncScaledY(aY);
   248 					}
   249 				}
   250 			pixelPtr += rowInc;
   251 			IncScaledY(aY, orgY);
   252 			}
   253 		}
   254 	else if(aDrawMode==CGraphicsContext::EDrawModeAND)
   255 		{
   256 		while(aData < dataPtrLimit)
   257 			{
   258 			register TUint32 dataWord = *aData++;
   259 			register TUint32 dataMask = 1;
   260 			register TUint8* tempPixelPtr = pixelPtr;
   261 			if(iScalingOff)
   262 				{
   263 				while(dataMask != dataMaskLimit)
   264 					{
   265 					if(dataWord & dataMask)
   266 						{
   267 						*tempPixelPtr = 0;
   268 						}
   269 					tempPixelPtr += pixelInc;
   270 					dataMask <<= 1;
   271 					}
   272 				}
   273 			else
   274 				{
   275 				while(dataMask != dataMaskLimit)
   276 					{
   277 					if(dataWord & dataMask)
   278 						{
   279 						const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
   280 						SetPixels(tempPixelPtr, TUint8(0), pixelRowPtrLimit, bitsStart, bitsEnd);
   281 						}
   282 					tempPixelPtr += pixelInc;
   283 					dataMask <<= 1;
   284 					}
   285 				}
   286 			pixelPtr += rowInc;
   287 			IncScaledY(aY, orgY);
   288 			}
   289 		}
   290 	}
   291 
   292 //aX, aY - logical coordinates
   293 //"aData" parameter has 32 bits words
   294 //"aLength" parameter tells how many pixels have to be written
   295 //This method is used for bitmap font symbols vertical drawing
   296 //The method should not be called if the scaling is ON!
   297 void CDrawEightBppBitmapCommon::WriteBinaryLineVertical(TInt aX,TInt aY,TUint32* aData,
   298 														TInt aLength,TUint8 aPixel,TBool aUp)
   299 	{
   300 	__ASSERT_DEBUG(iScalingOff, User::Invariant());
   301 
   302 	DeOrientate(aX,aY);//aX, aY - physical coordinates
   303 
   304 	TInt scanlineByteLength;
   305 	switch(iOrientation)
   306 		{
   307 		case EOrientationNormal:
   308 			scanlineByteLength = iLongWidth;
   309 			break;
   310 		case EOrientationRotated90:
   311 			scanlineByteLength = -1;
   312 			break;
   313 		case EOrientationRotated180:
   314 			scanlineByteLength = -iLongWidth;
   315 			break;
   316 		default: // EOrientationRotated270
   317 			scanlineByteLength = 1;
   318 		}
   319 
   320 	if (aUp)
   321 		scanlineByteLength = -scanlineByteLength;
   322 
   323 	register TUint8* pixelPtr = PixelAddress(aX,aY);
   324 	const TUint8* pixelPtrLimit = pixelPtr + aLength * scanlineByteLength;
   325 	register TUint32 dataWord = *aData;
   326 	register TUint32 dataMask = 1;
   327 
   328 	while(pixelPtr != pixelPtrLimit)
   329 		{
   330 		if(!dataMask)
   331 			{
   332 			dataMask = 1;
   333 			aData++;
   334 			dataWord = *aData;
   335 			}
   336 		if(dataWord & dataMask)
   337 			{
   338 			*pixelPtr = aPixel;
   339 			}
   340 		dataMask <<= 1;
   341 		pixelPtr += scanlineByteLength;
   342 		}
   343 	}
   344 
   345 //CDrawEightBppBitmapCommon::WriteLine() called from CDrawBitmap::WriteLine()
   346 //aX and aY - physical coordinates
   347 void CDrawEightBppBitmapCommon::WriteLine(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
   348 	{
   349 	TUint8* pixelPtr = PixelAddress(aX,aY);
   350 	if (iOrientation == EOrientationNormal && iScalingOff)
   351 		{
   352 		Mem::Copy(pixelPtr,aBuffer,aLength);
   353 		}
   354 	else
   355 		{
   356 		register TInt pixelPtrInc = LogicalPixelAddressIncrement();
   357 		TUint8* bufferPtr = reinterpret_cast <TUint8*> (aBuffer);
   358 		const TUint8* bufferPtrLimit = bufferPtr + aLength;
   359 		if(iScalingOff)
   360 			{
   361 			while(bufferPtr < bufferPtrLimit)
   362 				{
   363 				*pixelPtr = *bufferPtr++;
   364 				pixelPtr += pixelPtrInc;
   365 				}
   366 			}
   367 		else
   368 			{
   369 			const TUint8* bitsStart = reinterpret_cast <const TUint8*> (iBits);
   370 			const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
   371 			while(bufferPtr < bufferPtrLimit)
   372 				{
   373 				const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
   374 				SetPixels(pixelPtr, *bufferPtr++, pixelRowPtrLimit, bitsStart, bitsEnd);
   375 				pixelPtr += pixelPtrInc;
   376 				IncScaledY(aY);
   377 				}
   378 			}
   379 		}
   380 	}
   381 
   382 //CDrawEightBppBitmapCommon::WriteLineXOR() called from CDrawBitmap::WriteLine()
   383 //aX and aY - physical coordinates
   384 //One possible optimization: If "no scaling" And "pixelPtrInc == 1" Then
   385 //XOR could be made on 32 bits words (they  has to be aligned before the operation)
   386 void CDrawEightBppBitmapCommon::WriteLineXOR(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
   387 	{
   388 	TUint8* pixelPtr = PixelAddress(aX,aY);
   389 	register TInt pixelPtrInc = LogicalPixelAddressIncrement();
   390 	TUint8* bufferPtr = reinterpret_cast <TUint8*> (aBuffer);
   391 	const TUint8* bufferPtrLimit = bufferPtr + aLength;
   392 	if(iScalingOff)
   393 		{
   394 		while(bufferPtr < bufferPtrLimit)
   395 			{
   396 			*pixelPtr ^= *bufferPtr++;
   397 			pixelPtr += pixelPtrInc;
   398 			}
   399 		}
   400 	else
   401 		{
   402 		const TUint8* bitsStart = reinterpret_cast <const TUint8*> (iBits);
   403 		const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
   404 		while(bufferPtr < bufferPtrLimit)
   405 			{
   406 			const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
   407 			XORPixels(pixelPtr, *bufferPtr++, pixelRowPtrLimit, bitsStart, bitsEnd);
   408 			pixelPtr += pixelPtrInc;
   409 			IncScaledY(aY);
   410 			}
   411 		}
   412 	}
   413 
   414 //CDrawEightBppBitmapCommon::WriteLineAND() called from CDrawBitmap::WriteLine()
   415 //aX and aY - deorientated and scaled
   416 //aLength - not scaled
   417 //One possible optimization: If "no scaling" And "pixelPtrInc == 1" Then
   418 //AND could be made on 32 bits words (they  has to be aligned before the operation)
   419 void CDrawEightBppBitmapCommon::WriteLineAND(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
   420 	{
   421 	TUint8* pixelPtr = PixelAddress(aX,aY);
   422 	register TInt pixelPtrInc = LogicalPixelAddressIncrement();
   423 	TUint8* bufferPtr = reinterpret_cast <TUint8*> (aBuffer);
   424 	const TUint8* bufferPtrLimit = bufferPtr + aLength;
   425 	if(iScalingOff)
   426 		{
   427 		while(bufferPtr < bufferPtrLimit)
   428 			{
   429 			*pixelPtr &= *bufferPtr++;
   430 			pixelPtr += pixelPtrInc;
   431 			}
   432 		}
   433 	else
   434 		{
   435 		const TUint8* bitsStart = reinterpret_cast <const TUint8*> (iBits);
   436 		const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
   437 		while(bufferPtr < bufferPtrLimit)
   438 			{
   439 			const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
   440 			ANDPixels(pixelPtr, *bufferPtr++, pixelRowPtrLimit, bitsStart, bitsEnd);
   441 			pixelPtr += pixelPtrInc;
   442 			IncScaledY(aY);
   443 			}
   444 		}
   445 	}
   446 
   447 //CDrawEightBppBitmapCommon::WriteLineOR() called from CDrawBitmap::WriteLine()
   448 //aX and aY - physical coordinates
   449 //One possible optimization: If "no scaling" And "pixelPtrInc == 1" Then
   450 //OR could be made on 32 bits words (they  has to be aligned before the operation)
   451 void CDrawEightBppBitmapCommon::WriteLineOR(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
   452 	{
   453 	TUint8* pixelPtr = PixelAddress(aX,aY);
   454 	register TInt pixelPtrInc = LogicalPixelAddressIncrement();
   455 	TUint8* bufferPtr = reinterpret_cast <TUint8*> (aBuffer);
   456 	const TUint8* bufferPtrLimit = bufferPtr + aLength;
   457 	if(iScalingOff)
   458 		{
   459 		while(bufferPtr < bufferPtrLimit)
   460 			{
   461 			*pixelPtr |= *bufferPtr++;
   462 			pixelPtr += pixelPtrInc;
   463 			}
   464 		}
   465 	else
   466 		{
   467 		const TUint8* bitsStart = reinterpret_cast <const TUint8*> (iBits);
   468 		const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
   469 		while(bufferPtr < bufferPtrLimit)
   470 			{
   471 			const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
   472 			ORPixels(pixelPtr, *bufferPtr++, pixelRowPtrLimit, bitsStart, bitsEnd);
   473 			pixelPtr += pixelPtrInc;
   474 			IncScaledY(aY);
   475 			}
   476 		}
   477 	}
   478 
   479 //CDrawEightBppBitmapCommon::WriteRgbMulti() called from CDrawBitmap::WriteRgbMulti()
   480 //aX and aY - physical coordinates
   481 //aLength and aRows - physical length and rows
   482 void CDrawEightBppBitmapCommon::WriteRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aRows,
   483 											  TUint8 aPixel)
   484 	{
   485 	register TInt longWidth = iLongWidth;
   486 	TUint8* pixelPtr = PixelAddress(aX,aY);
   487 	const TUint8* pixelRowPtrLimit = pixelPtr + aRows * longWidth;
   488 	register const TUint8* bitsEnd = reinterpret_cast <const TUint8*> (iBits) + iLongWidth * iSize.iHeight;
   489 	if(pixelRowPtrLimit >= bitsEnd)
   490 		{
   491 		pixelRowPtrLimit = bitsEnd;
   492 		}
   493 
   494 	while (pixelPtr < pixelRowPtrLimit)
   495 		{
   496 		Mem::Fill(pixelPtr,aLength,aPixel);
   497 		pixelPtr += longWidth;
   498 		}
   499 	}
   500 
   501 //CDrawEightBppBitmapCommon::WriteRgbMultiXOR() called from CDrawBitmap::WriteRgbMulti()
   502 //aX and aY - physical coordinates
   503 //aLength and aRows - physical length and rows
   504 void CDrawEightBppBitmapCommon::WriteRgbMultiXOR(TInt aX,TInt aY,TInt aLength,TInt aRows,
   505 												 TUint8 aPixel)
   506 	{
   507 	register TInt longWidth = iLongWidth;
   508 	TUint8* pixelPtr = PixelAddress(aX,aY);
   509 	TUint8* pixelPtrLimit = pixelPtr + aLength;
   510 	const TUint8* pixelRowPtrLimit = pixelPtr + aRows * longWidth;
   511 	register const TUint8* bitsEnd = reinterpret_cast <const TUint8*> (iBits) + iLongWidth * iSize.iHeight;
   512 	if(pixelRowPtrLimit >= bitsEnd)
   513 		{
   514 		pixelRowPtrLimit = bitsEnd;
   515 		}
   516 
   517 	while (pixelPtr < pixelRowPtrLimit)
   518 		{
   519 		TUint8* tempPixelPtr = pixelPtr;
   520 
   521 		while (tempPixelPtr < pixelPtrLimit)
   522 			*tempPixelPtr++ ^= aPixel;
   523 
   524 		pixelPtr += longWidth;
   525 		pixelPtrLimit += longWidth;
   526 		}
   527 	}
   528 
   529 //CDrawEightBppBitmapCommon::WriteRgbMultiAND() called from CDrawBitmap::WriteRgbMulti()
   530 //aX and aY - physical coordinates
   531 //aLength and aRows - physical length and rows
   532 void CDrawEightBppBitmapCommon::WriteRgbMultiAND(TInt aX,TInt aY,TInt aLength,TInt aRows,
   533 												 TUint8 aPixel)
   534 	{
   535 	register TInt longWidth = iLongWidth;
   536 	TUint8* pixelPtr = PixelAddress(aX,aY);
   537 	const TUint8* pixelPtrLimit = pixelPtr + aLength;
   538 	const TUint8* pixelRowPtrLimit = pixelPtr + aRows * longWidth;
   539 	register const TUint8* bitsEnd = reinterpret_cast <const TUint8*> (iBits) + iLongWidth * iSize.iHeight;
   540 	if(pixelRowPtrLimit >= bitsEnd)
   541 		{
   542 		pixelRowPtrLimit = bitsEnd;
   543 		}
   544 
   545 	while (pixelPtr < pixelRowPtrLimit)
   546 		{
   547 		TUint8* tempPixelPtr = pixelPtr;
   548 
   549 		while (tempPixelPtr < pixelPtrLimit)
   550 			*tempPixelPtr++ &= aPixel;
   551 
   552 		pixelPtr += longWidth;
   553 		pixelPtrLimit += longWidth;
   554 		}
   555 	}
   556 
   557 //CDrawEightBppBitmapCommon::WriteRgbMultiOR() called from CDrawBitmap::WriteRgbMulti()
   558 //aX and aY - physical coordinates
   559 //aLength and aRows - physical length and rows
   560 void CDrawEightBppBitmapCommon::WriteRgbMultiOR(TInt aX,TInt aY,TInt aLength,TInt aRows,TUint8 aPixel)
   561 	{
   562 	register TInt longWidth = iLongWidth;
   563 	TUint8* pixelPtr = PixelAddress(aX,aY);
   564 	TUint8* pixelPtrLimit = pixelPtr + aLength;
   565 	const TUint8* pixelRowPtrLimit = pixelPtr + aRows * longWidth;
   566 	register const TUint8* bitsEnd = reinterpret_cast <const TUint8*> (iBits) + iLongWidth * iSize.iHeight;
   567 	if(pixelRowPtrLimit >= bitsEnd)
   568 		{
   569 		pixelRowPtrLimit = bitsEnd;
   570 		}
   571 
   572 	while (pixelPtr < pixelRowPtrLimit)
   573 		{
   574 		TUint8* tempPixelPtr = pixelPtr;
   575 
   576 		while (tempPixelPtr < pixelPtrLimit)
   577 			*tempPixelPtr++ |= aPixel;
   578 
   579 		pixelPtr += longWidth;
   580 		pixelPtrLimit += longWidth;
   581 		}
   582 	}
   583 
   584 /**
   585 Implementation for CFbsDrawDevice::GetInterface().
   586 Retrieves a pointer to a specified interface of CFbsDrawDevice implementation.
   587 @param aInterfaceId Interface identifier of the interface to be retrieved.
   588 @param aInterface Address of variable that retrieves the specified interface.
   589 @return KErrNone If the interface is supported, KErrNotSupported otherwise.
   590 */
   591 
   592 TInt CDrawEightBppBitmapCommon::GetInterface(TInt aInterfaceId, TAny*& aInterface)
   593 	{
   594 	aInterface = NULL;
   595 	TInt ret = KErrNotSupported;
   596 	
   597 	if (aInterfaceId == KFastBlit2InterfaceID)
   598 		{
   599 		aInterface = static_cast<MFastBlit2*>(this);
   600 		ret = KErrNone;
   601 		}
   602 	else 
   603 		return CDrawBitmap::GetInterface(aInterfaceId, aInterface);
   604 		
   605 	return ret;
   606 	}
   607 
   608 /**
   609 CDrawEightBppBitmapCommon::WriteBitmapBlock() implementation.
   610 @internalTechnology
   611 @see MFastBlit2::WriteBitmapBlock()
   612 */
   613 TInt CDrawEightBppBitmapCommon::WriteBitmapBlock(const TPoint& aDest,
   614 									CFbsDrawDevice* aSrcDrawDevice,
   615 									const TRect& aSrcRect)
   616 	{
   617 	__ASSERT_DEBUG(aSrcDrawDevice && ((aSrcDrawDevice->DisplayMode()==EColor256) || (aSrcDrawDevice->DisplayMode()==EGray256)), Panic(EScreenDriverPanicInvalidParameter));
   618 	
   619 	TAny* interface=NULL;
   620 	TInt ret = aSrcDrawDevice->GetInterface(KFastBlit2InterfaceID, interface);
   621 	if (ret != KErrNone)
   622 		{
   623 		return KErrNotSupported;
   624 		}
   625 
   626 	TAny* interface1=NULL;
   627 	ret = aSrcDrawDevice->GetInterface(KScalingSettingsInterfaceID, interface1);
   628 	if(ret != KErrNone || (interface1 && !reinterpret_cast<MScalingSettings*>(interface1)->IsScalingOff()))
   629 		{
   630 		return KErrNotSupported;
   631 		}
   632 
   633 	ret = aSrcDrawDevice->GetInterface(KOrientationInterfaceID, interface1);
   634 	if(ret != KErrNone || (interface1 && reinterpret_cast<MDrawDeviceOrientation*>(interface1)->Orientation() != 0))
   635 		{
   636 		return KErrNotSupported;
   637 		}
   638 
   639 	ret = aSrcDrawDevice->GetInterface(KDrawDeviceOriginInterfaceID, interface1);
   640 	if(ret != KErrNone)
   641 		{
   642 		return KErrNotSupported;
   643 		}
   644 	
   645 	if(interface1)
   646 		{
   647 	 	TPoint pt;
   648 	 	reinterpret_cast<MDrawDeviceOrigin*>(interface1)->Get(pt);
   649 	 	if(pt.iX != 0 || pt.iY != 0)
   650 	 		{
   651 			return KErrNotSupported;
   652 	 		}
   653 		}
   654 
   655 	const TUint32* srcBase = reinterpret_cast<MFastBlit2*>(interface)->Bits();
   656 	__ASSERT_DEBUG(srcBase!=NULL, Panic(EScreenDriverPanicInvalidParameter));
   657 	TInt srcStride = aSrcDrawDevice->ScanLineBytes();  
   658 	__ASSERT_DEBUG((srcStride&3)==0, Panic(EScreenDriverPanicInvalidParameter));  // stride is assumed to be a multiple of 4
   659 	TSize srcSize = aSrcDrawDevice->SizeInPixels();
   660 
   661 	return WriteBitmapBlock(aDest, srcBase, srcStride, srcSize, aSrcRect);
   662 	}
   663 
   664 								
   665 /**
   666 CDrawEightBppBitmapCommon::WriteBitmapBlock() implementation.
   667 @internalTechnology
   668 @see MFastBlit2::WriteBitmapBlock()
   669 */													
   670 TInt CDrawEightBppBitmapCommon::WriteBitmapBlock(const TPoint& aDest,
   671 									const TUint32* aSrcBase,
   672 									TInt aSrcStride,
   673 									const TSize& aSrcSize,
   674 									const TRect& aSrcRect)
   675 	{
   676 	__ASSERT_DEBUG(aSrcBase, Panic(EScreenDriverPanicInvalidParameter));
   677 	__ASSERT_DEBUG((aSrcStride&3)==0, Panic(EScreenDriverPanicInvalidParameter));
   678 	__ASSERT_DEBUG(iBits, Panic(EScreenDriverPanicInvalidPointer));
   679 
   680 	if (iShadowMode!=NULL ||
   681     	(iUserDispMode!=NULL && iUserDispMode!=iDispMode) ||
   682     	iOrientation!=EOrientationNormal ||
   683 		!IsScalingOff() ||
   684 		!iOriginIsZero)
   685 		{
   686 		return KErrNotSupported;
   687 		}
   688 	
   689 	__ASSERT_DEBUG(aSrcRect.iTl.iX >= 0, Panic(EScreenDriverPanicOutOfBounds)); 
   690 	__ASSERT_DEBUG(aSrcRect.iTl.iY >= 0, Panic(EScreenDriverPanicOutOfBounds));
   691 	__ASSERT_DEBUG(aSrcRect.iBr.iX <= aSrcSize.iWidth,  Panic(EScreenDriverPanicOutOfBounds));
   692 	__ASSERT_DEBUG(aSrcRect.iBr.iY <= aSrcSize.iHeight, Panic(EScreenDriverPanicOutOfBounds));
   693 	__ASSERT_DEBUG(aDest.iX >= 0, Panic(EScreenDriverPanicOutOfBounds));
   694 	__ASSERT_DEBUG(aDest.iY >= 0, Panic(EScreenDriverPanicOutOfBounds));
   695 	__ASSERT_DEBUG((aDest.iX + aSrcRect.Width())  <= SizeInPixels().iWidth,  Panic(EScreenDriverPanicOutOfBounds));
   696 	__ASSERT_DEBUG((aDest.iY + aSrcRect.Height()) <= SizeInPixels().iHeight, Panic(EScreenDriverPanicOutOfBounds));
   697 	
   698 	const TInt srcStride8 = aSrcStride;
   699 	const TInt dstStride8 = iScanLineWords << 2;
   700 	
   701 	if (aSrcSize.iWidth == aSrcRect.Width() &&
   702 		aSrcSize.iWidth == SizeInPixels().iWidth &&
   703 		srcStride8 == dstStride8)
   704 		{
   705 		// Optimum case - one memcpy
   706 		__ASSERT_DEBUG(aSrcRect.iTl.iX==0 && aDest.iX==0, Panic(EScreenDriverPanicInvalidParameter));  // this is implied by the above conditions
   707 		const TUint32* srcPtr = aSrcBase + (iScanLineWords * aSrcRect.iTl.iY);
   708 		TUint32* dstPtr       = iBits    + (iScanLineWords * aDest.iY);
   709 		const TInt length = aSrcStride * aSrcRect.Height();
   710 		Mem::Move(dstPtr, srcPtr, length);
   711 		return KErrNone;
   712 		}
   713 		
   714 	// Sub-optimal case - one memcpy per line
   715 	const TUint8* srcPtr = (TUint8*)aSrcBase + (srcStride8 * aSrcRect.iTl.iY) + aSrcRect.iTl.iX;
   716 	TUint8* dstPtr       = (TUint8*)iBits    + (dstStride8 * aDest.iY       ) + aDest.iX;
   717 	const TInt length = aSrcRect.Width();
   718 	TInt lines = aSrcRect.Height();
   719 	while (lines--)
   720 		{
   721 		Mem::Copy(dstPtr, srcPtr, length);
   722 		srcPtr += srcStride8;
   723 		dstPtr += dstStride8;
   724 		}
   725 	return KErrNone;
   726 	}
   727 
   728 
   729 /**
   730 CDrawEightBppBitmapCommon::Bits() implementation.
   731 @internalTechnology
   732 @see MFastBlit2::Bits()
   733 */
   734 const TUint32* CDrawEightBppBitmapCommon::Bits() const
   735 	{
   736 	return iBits;
   737 }