graphicsdeviceinterface/screendriver/sbit/BMDRAW8.CPP
changeset 0 5d03bc08d59c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicsdeviceinterface/screendriver/sbit/BMDRAW8.CPP	Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,737 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "BMDRAW.H"
+#include "BitDrawInterfaceId.h"
+
+// CDrawEightBppBitmapCommon
+//EColor256 screen/bitmap device might be scaled.
+//In this case right-bottom coordinate might go outside the drawing rectangle.
+//Then - we need to check that we do not try to draw something outside the drawing rectangle.
+
+//Initializes iSize, iDrawRect, iLongWidth, iScanlineWords data members.
+//It should be called every time when iSize is going to be changed - from Construct().
+//@param aSize Physical screen size in pixels.
+//@panic EScreenDriverPanicInvalidSize - Invalid aSize parameter. This might happen if the 
+//device is scaled and the scaling origin goes outside physical drawing rectangle.
+void CDrawEightBppBitmapCommon::SetSize(const TSize& aSize) 
+	{
+	CDrawBitmap::SetSize(aSize);
+	__ASSERT_DEBUG(iSize == aSize, User::Invariant());
+	iLongWidth = (iSize.iWidth + 3) & ~3;
+	iScanLineWords = iLongWidth / 4;
+	}
+ 
+TInt CDrawEightBppBitmapCommon::Construct(TSize aSize, TInt aStride)
+	{
+	iBits = NULL;
+	CDrawBitmap::SetSize(aSize);
+	__ASSERT_DEBUG(iSize == aSize, User::Invariant());
+	if (aStride & 3)
+		return KErrArgument;
+	iLongWidth = aStride;
+	if (iLongWidth < aSize.iWidth)
+		return KErrArgument;
+	iScanLineWords = aStride >> 2;
+	TInt size = Max(aSize.iWidth,aSize.iHeight);
+	if(size < 0)
+		return KErrArgument;
+	iScanLineBuffer = (TUint32*)(User::Heap().Alloc(size));
+	if(iScanLineBuffer == NULL)
+		return KErrNoMemory;
+	return KErrNone;
+	}
+
+//aX, aY - physical coordinates
+TUint8* CDrawEightBppBitmapCommon::PixelAddress(TInt aX,TInt aY) const
+	{
+	return (TUint8*)iBits + aY * iLongWidth + aX;
+	}
+
+void CDrawEightBppBitmapCommon::InvertBuffer(TInt aLength,TUint32* aBuffer)
+	{
+	const TUint32* limit = aBuffer + (aLength + 3) / 4;
+
+	while (aBuffer < limit)
+		*aBuffer++ ^= 0xffffffff;
+	}
+
+//CDrawEightBppBitmapCommon::ReadLine() called from CDrawBitmap::ReadLine()
+//aX and aY - physical coordinates.
+//Reads aLength pixel values and places them in aBuffer.
+//aBuffer size should be at least aLength.
+void CDrawEightBppBitmapCommon::ReadLine(TInt aX,TInt aY,TInt aLength,TAny* aBuffer) const
+	{
+	const TUint8* pixelPtr = PixelAddress(aX,aY);
+
+	if (iOrientation == EOrientationNormal && iScalingOff)
+		Mem::Copy(aBuffer,pixelPtr,aLength);
+	else
+		{
+		register TInt pixelPtrInc = LogicalPixelAddressIncrement();
+
+		TUint8* bufferPtr = static_cast <TUint8*> (aBuffer);
+		const TUint8* bufferPtrLimit = bufferPtr + aLength;
+
+		while (bufferPtr < bufferPtrLimit)
+			{
+			*bufferPtr++ = *pixelPtr;
+			pixelPtr += pixelPtrInc;
+			}
+		}
+	}
+
+//CDrawEightBppBitmapCommon::WriteRgb() called from exported CDrawBitmap::WriteRgb()
+//aX, aY - physical coordinates
+void CDrawEightBppBitmapCommon::WriteRgb(TInt aX,TInt aY,TUint8 aPixel)
+	{
+	register TUint8* pixelAddr = PixelAddress(aX, aY);
+	if(iScalingOff)
+		{
+		*pixelAddr = aPixel;
+		}
+	else
+		{
+		const TUint8* bitsStart = reinterpret_cast <const TUint8*> (iBits);
+		const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
+		const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
+		SetPixels(pixelAddr, aPixel, pixelRowPtrLimit, bitsStart, bitsEnd);
+		}
+	}
+
+//CDrawEightBppBitmapCommon::WriteBinary() called from exported CDrawBitmap::WriteBinary()
+//aX, aY - logical coordinates
+//"aData" parameter has "aHeight" 32 bits words
+//"aLength" parameter tells how many bits (up to 32) has to be used from each 32 bit word
+//This method is used for bitmap font symbols drawing
+//One possible optimization: If "no scaling" And "pixelPtrInc == 1" Then
+//writing could be made on 32 bits words (they has to be aligned before the operation)
+void CDrawEightBppBitmapCommon::WriteBinary(TInt aX,TInt aY,TUint32* aData,TInt aLength,
+											TInt aHeight,TUint8 aPixel)
+	{
+	DeOrientate(aX,aY);//aX, aY - physical coordinates
+	TInt pixelInc;
+	TInt rowInc;
+	SetPixelInc(pixelInc, rowInc);
+	const TUint32* dataLimit = aData + aHeight;
+	register TUint32 dataMaskLimit = (aLength < 32) ? 1 << aLength : 0;
+	TUint8* pixelPtr = PixelAddress(aX,aY);
+	const TUint8* bitsStart = reinterpret_cast <const TUint8*> (iBits);
+	const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
+	TInt orgY = aY;
+	while (aData < dataLimit)
+		{
+		register TUint32 dataWord = *aData++;
+		register TUint32 dataMask = 1;
+		register TUint8* tempPixelPtr = pixelPtr;
+		if(iScalingOff)
+			{
+			while (dataMask != dataMaskLimit)
+				{
+				if(dataWord & dataMask)
+					{
+					*tempPixelPtr = aPixel;
+					}
+				tempPixelPtr += pixelInc;
+				dataMask <<= 1;
+				}
+			}
+		else
+			{
+			while (dataMask != dataMaskLimit)
+				{
+				if(dataWord & dataMask)
+					{
+					const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
+					SetPixels(tempPixelPtr, aPixel, pixelRowPtrLimit, bitsStart, bitsEnd);
+					}
+				tempPixelPtr += pixelInc;
+				dataMask <<= 1;
+				IncScaledY(aY);
+				}
+			}
+		pixelPtr += rowInc;
+		IncScaledY(aY, orgY);
+		}
+	}
+
+//CDrawEightBppBitmapCommon::WriteBinaryOp() called from exported CDrawBitmap::WriteBinary()
+//aX, aY - logical coordinates
+//"aData" parameter has "aHeight" 32 bits words
+//"aLength" parameter tells how many bits (up to 32) has to be used from each 32 bit word
+//This method is used for bitmap font symbols drawing
+//One possible optimization: If "no scaling" And "pixelPtrInc == 1" Then
+//writing could be made on 32 bits words (they has to be aligned before the operation)
+void CDrawEightBppBitmapCommon::WriteBinaryOp(TInt aX,TInt aY,TUint32* aData,TInt aLength,
+											  TInt aHeight,TUint8 aPixel,
+											  CGraphicsContext::TDrawMode aDrawMode)
+	{
+	if(aLength <= 0)
+		{
+		return;
+		}
+	DeOrientate(aX,aY);//aX, aY - physical coordinates
+	TUint8* pixelPtr = PixelAddress(aX,aY);
+	const TUint32* dataPtrLimit = aData + aHeight;
+	register TUint32 dataMaskLimit = (aLength < 32) ? 1 << aLength : 0;
+	TInt pixelInc;
+	TInt rowInc;
+	SetPixelInc(pixelInc, rowInc);
+	const TUint8* bitsStart = reinterpret_cast <const TUint8*> (iBits);
+	const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
+	TInt orgY = aY;
+	if(aPixel)
+		{
+		while(aData < dataPtrLimit)
+			{
+			register TUint32 dataWord = *aData++;
+			register TUint32 dataMask = 1;
+			register TUint8* tempPixelPtr = pixelPtr;
+			if(iScalingOff)
+				{
+				while(dataMask != dataMaskLimit)
+					{
+					if(dataWord & dataMask)
+						{
+						if(aDrawMode==CGraphicsContext::EDrawModeXOR)
+							{
+							*tempPixelPtr ^= aPixel;
+							}
+						else if(aDrawMode==CGraphicsContext::EDrawModeAND)
+							{
+							*tempPixelPtr &= aPixel;
+							}
+						else if(aDrawMode==CGraphicsContext::EDrawModeOR)
+							{
+							*tempPixelPtr |= aPixel;
+							}
+						}
+					tempPixelPtr += pixelInc;
+					dataMask <<= 1;
+					}
+				}
+			else
+				{
+				while(dataMask != dataMaskLimit)
+					{
+					if(dataWord & dataMask)
+						{
+						const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
+						if(aDrawMode==CGraphicsContext::EDrawModeXOR)
+							{
+							XORPixels(tempPixelPtr, aPixel, pixelRowPtrLimit, bitsStart, bitsEnd);
+							}
+						else if(aDrawMode==CGraphicsContext::EDrawModeAND)
+							{
+							ANDPixels(tempPixelPtr, aPixel, pixelRowPtrLimit, bitsStart, bitsEnd);
+							}
+						else if(aDrawMode==CGraphicsContext::EDrawModeOR)
+							{
+							ORPixels(tempPixelPtr, aPixel, pixelRowPtrLimit, bitsStart, bitsEnd);
+							}
+						}
+					tempPixelPtr += pixelInc;
+					dataMask <<= 1;
+					IncScaledY(aY);
+					}
+				}
+			pixelPtr += rowInc;
+			IncScaledY(aY, orgY);
+			}
+		}
+	else if(aDrawMode==CGraphicsContext::EDrawModeAND)
+		{
+		while(aData < dataPtrLimit)
+			{
+			register TUint32 dataWord = *aData++;
+			register TUint32 dataMask = 1;
+			register TUint8* tempPixelPtr = pixelPtr;
+			if(iScalingOff)
+				{
+				while(dataMask != dataMaskLimit)
+					{
+					if(dataWord & dataMask)
+						{
+						*tempPixelPtr = 0;
+						}
+					tempPixelPtr += pixelInc;
+					dataMask <<= 1;
+					}
+				}
+			else
+				{
+				while(dataMask != dataMaskLimit)
+					{
+					if(dataWord & dataMask)
+						{
+						const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
+						SetPixels(tempPixelPtr, TUint8(0), pixelRowPtrLimit, bitsStart, bitsEnd);
+						}
+					tempPixelPtr += pixelInc;
+					dataMask <<= 1;
+					}
+				}
+			pixelPtr += rowInc;
+			IncScaledY(aY, orgY);
+			}
+		}
+	}
+
+//aX, aY - logical coordinates
+//"aData" parameter has 32 bits words
+//"aLength" parameter tells how many pixels have to be written
+//This method is used for bitmap font symbols vertical drawing
+//The method should not be called if the scaling is ON!
+void CDrawEightBppBitmapCommon::WriteBinaryLineVertical(TInt aX,TInt aY,TUint32* aData,
+														TInt aLength,TUint8 aPixel,TBool aUp)
+	{
+	__ASSERT_DEBUG(iScalingOff, User::Invariant());
+
+	DeOrientate(aX,aY);//aX, aY - physical coordinates
+
+	TInt scanlineByteLength;
+	switch(iOrientation)
+		{
+		case EOrientationNormal:
+			scanlineByteLength = iLongWidth;
+			break;
+		case EOrientationRotated90:
+			scanlineByteLength = -1;
+			break;
+		case EOrientationRotated180:
+			scanlineByteLength = -iLongWidth;
+			break;
+		default: // EOrientationRotated270
+			scanlineByteLength = 1;
+		}
+
+	if (aUp)
+		scanlineByteLength = -scanlineByteLength;
+
+	register TUint8* pixelPtr = PixelAddress(aX,aY);
+	const TUint8* pixelPtrLimit = pixelPtr + aLength * scanlineByteLength;
+	register TUint32 dataWord = *aData;
+	register TUint32 dataMask = 1;
+
+	while(pixelPtr != pixelPtrLimit)
+		{
+		if(!dataMask)
+			{
+			dataMask = 1;
+			aData++;
+			dataWord = *aData;
+			}
+		if(dataWord & dataMask)
+			{
+			*pixelPtr = aPixel;
+			}
+		dataMask <<= 1;
+		pixelPtr += scanlineByteLength;
+		}
+	}
+
+//CDrawEightBppBitmapCommon::WriteLine() called from CDrawBitmap::WriteLine()
+//aX and aY - physical coordinates
+void CDrawEightBppBitmapCommon::WriteLine(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
+	{
+	TUint8* pixelPtr = PixelAddress(aX,aY);
+	if (iOrientation == EOrientationNormal && iScalingOff)
+		{
+		Mem::Copy(pixelPtr,aBuffer,aLength);
+		}
+	else
+		{
+		register TInt pixelPtrInc = LogicalPixelAddressIncrement();
+		TUint8* bufferPtr = reinterpret_cast <TUint8*> (aBuffer);
+		const TUint8* bufferPtrLimit = bufferPtr + aLength;
+		if(iScalingOff)
+			{
+			while(bufferPtr < bufferPtrLimit)
+				{
+				*pixelPtr = *bufferPtr++;
+				pixelPtr += pixelPtrInc;
+				}
+			}
+		else
+			{
+			const TUint8* bitsStart = reinterpret_cast <const TUint8*> (iBits);
+			const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
+			while(bufferPtr < bufferPtrLimit)
+				{
+				const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
+				SetPixels(pixelPtr, *bufferPtr++, pixelRowPtrLimit, bitsStart, bitsEnd);
+				pixelPtr += pixelPtrInc;
+				IncScaledY(aY);
+				}
+			}
+		}
+	}
+
+//CDrawEightBppBitmapCommon::WriteLineXOR() called from CDrawBitmap::WriteLine()
+//aX and aY - physical coordinates
+//One possible optimization: If "no scaling" And "pixelPtrInc == 1" Then
+//XOR could be made on 32 bits words (they  has to be aligned before the operation)
+void CDrawEightBppBitmapCommon::WriteLineXOR(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
+	{
+	TUint8* pixelPtr = PixelAddress(aX,aY);
+	register TInt pixelPtrInc = LogicalPixelAddressIncrement();
+	TUint8* bufferPtr = reinterpret_cast <TUint8*> (aBuffer);
+	const TUint8* bufferPtrLimit = bufferPtr + aLength;
+	if(iScalingOff)
+		{
+		while(bufferPtr < bufferPtrLimit)
+			{
+			*pixelPtr ^= *bufferPtr++;
+			pixelPtr += pixelPtrInc;
+			}
+		}
+	else
+		{
+		const TUint8* bitsStart = reinterpret_cast <const TUint8*> (iBits);
+		const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
+		while(bufferPtr < bufferPtrLimit)
+			{
+			const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
+			XORPixels(pixelPtr, *bufferPtr++, pixelRowPtrLimit, bitsStart, bitsEnd);
+			pixelPtr += pixelPtrInc;
+			IncScaledY(aY);
+			}
+		}
+	}
+
+//CDrawEightBppBitmapCommon::WriteLineAND() called from CDrawBitmap::WriteLine()
+//aX and aY - deorientated and scaled
+//aLength - not scaled
+//One possible optimization: If "no scaling" And "pixelPtrInc == 1" Then
+//AND could be made on 32 bits words (they  has to be aligned before the operation)
+void CDrawEightBppBitmapCommon::WriteLineAND(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
+	{
+	TUint8* pixelPtr = PixelAddress(aX,aY);
+	register TInt pixelPtrInc = LogicalPixelAddressIncrement();
+	TUint8* bufferPtr = reinterpret_cast <TUint8*> (aBuffer);
+	const TUint8* bufferPtrLimit = bufferPtr + aLength;
+	if(iScalingOff)
+		{
+		while(bufferPtr < bufferPtrLimit)
+			{
+			*pixelPtr &= *bufferPtr++;
+			pixelPtr += pixelPtrInc;
+			}
+		}
+	else
+		{
+		const TUint8* bitsStart = reinterpret_cast <const TUint8*> (iBits);
+		const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
+		while(bufferPtr < bufferPtrLimit)
+			{
+			const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
+			ANDPixels(pixelPtr, *bufferPtr++, pixelRowPtrLimit, bitsStart, bitsEnd);
+			pixelPtr += pixelPtrInc;
+			IncScaledY(aY);
+			}
+		}
+	}
+
+//CDrawEightBppBitmapCommon::WriteLineOR() called from CDrawBitmap::WriteLine()
+//aX and aY - physical coordinates
+//One possible optimization: If "no scaling" And "pixelPtrInc == 1" Then
+//OR could be made on 32 bits words (they  has to be aligned before the operation)
+void CDrawEightBppBitmapCommon::WriteLineOR(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
+	{
+	TUint8* pixelPtr = PixelAddress(aX,aY);
+	register TInt pixelPtrInc = LogicalPixelAddressIncrement();
+	TUint8* bufferPtr = reinterpret_cast <TUint8*> (aBuffer);
+	const TUint8* bufferPtrLimit = bufferPtr + aLength;
+	if(iScalingOff)
+		{
+		while(bufferPtr < bufferPtrLimit)
+			{
+			*pixelPtr |= *bufferPtr++;
+			pixelPtr += pixelPtrInc;
+			}
+		}
+	else
+		{
+		const TUint8* bitsStart = reinterpret_cast <const TUint8*> (iBits);
+		const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
+		while(bufferPtr < bufferPtrLimit)
+			{
+			const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
+			ORPixels(pixelPtr, *bufferPtr++, pixelRowPtrLimit, bitsStart, bitsEnd);
+			pixelPtr += pixelPtrInc;
+			IncScaledY(aY);
+			}
+		}
+	}
+
+//CDrawEightBppBitmapCommon::WriteRgbMulti() called from CDrawBitmap::WriteRgbMulti()
+//aX and aY - physical coordinates
+//aLength and aRows - physical length and rows
+void CDrawEightBppBitmapCommon::WriteRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aRows,
+											  TUint8 aPixel)
+	{
+	register TInt longWidth = iLongWidth;
+	TUint8* pixelPtr = PixelAddress(aX,aY);
+	const TUint8* pixelRowPtrLimit = pixelPtr + aRows * longWidth;
+	register const TUint8* bitsEnd = reinterpret_cast <const TUint8*> (iBits) + iLongWidth * iSize.iHeight;
+	if(pixelRowPtrLimit >= bitsEnd)
+		{
+		pixelRowPtrLimit = bitsEnd;
+		}
+
+	while (pixelPtr < pixelRowPtrLimit)
+		{
+		Mem::Fill(pixelPtr,aLength,aPixel);
+		pixelPtr += longWidth;
+		}
+	}
+
+//CDrawEightBppBitmapCommon::WriteRgbMultiXOR() called from CDrawBitmap::WriteRgbMulti()
+//aX and aY - physical coordinates
+//aLength and aRows - physical length and rows
+void CDrawEightBppBitmapCommon::WriteRgbMultiXOR(TInt aX,TInt aY,TInt aLength,TInt aRows,
+												 TUint8 aPixel)
+	{
+	register TInt longWidth = iLongWidth;
+	TUint8* pixelPtr = PixelAddress(aX,aY);
+	TUint8* pixelPtrLimit = pixelPtr + aLength;
+	const TUint8* pixelRowPtrLimit = pixelPtr + aRows * longWidth;
+	register const TUint8* bitsEnd = reinterpret_cast <const TUint8*> (iBits) + iLongWidth * iSize.iHeight;
+	if(pixelRowPtrLimit >= bitsEnd)
+		{
+		pixelRowPtrLimit = bitsEnd;
+		}
+
+	while (pixelPtr < pixelRowPtrLimit)
+		{
+		TUint8* tempPixelPtr = pixelPtr;
+
+		while (tempPixelPtr < pixelPtrLimit)
+			*tempPixelPtr++ ^= aPixel;
+
+		pixelPtr += longWidth;
+		pixelPtrLimit += longWidth;
+		}
+	}
+
+//CDrawEightBppBitmapCommon::WriteRgbMultiAND() called from CDrawBitmap::WriteRgbMulti()
+//aX and aY - physical coordinates
+//aLength and aRows - physical length and rows
+void CDrawEightBppBitmapCommon::WriteRgbMultiAND(TInt aX,TInt aY,TInt aLength,TInt aRows,
+												 TUint8 aPixel)
+	{
+	register TInt longWidth = iLongWidth;
+	TUint8* pixelPtr = PixelAddress(aX,aY);
+	const TUint8* pixelPtrLimit = pixelPtr + aLength;
+	const TUint8* pixelRowPtrLimit = pixelPtr + aRows * longWidth;
+	register const TUint8* bitsEnd = reinterpret_cast <const TUint8*> (iBits) + iLongWidth * iSize.iHeight;
+	if(pixelRowPtrLimit >= bitsEnd)
+		{
+		pixelRowPtrLimit = bitsEnd;
+		}
+
+	while (pixelPtr < pixelRowPtrLimit)
+		{
+		TUint8* tempPixelPtr = pixelPtr;
+
+		while (tempPixelPtr < pixelPtrLimit)
+			*tempPixelPtr++ &= aPixel;
+
+		pixelPtr += longWidth;
+		pixelPtrLimit += longWidth;
+		}
+	}
+
+//CDrawEightBppBitmapCommon::WriteRgbMultiOR() called from CDrawBitmap::WriteRgbMulti()
+//aX and aY - physical coordinates
+//aLength and aRows - physical length and rows
+void CDrawEightBppBitmapCommon::WriteRgbMultiOR(TInt aX,TInt aY,TInt aLength,TInt aRows,TUint8 aPixel)
+	{
+	register TInt longWidth = iLongWidth;
+	TUint8* pixelPtr = PixelAddress(aX,aY);
+	TUint8* pixelPtrLimit = pixelPtr + aLength;
+	const TUint8* pixelRowPtrLimit = pixelPtr + aRows * longWidth;
+	register const TUint8* bitsEnd = reinterpret_cast <const TUint8*> (iBits) + iLongWidth * iSize.iHeight;
+	if(pixelRowPtrLimit >= bitsEnd)
+		{
+		pixelRowPtrLimit = bitsEnd;
+		}
+
+	while (pixelPtr < pixelRowPtrLimit)
+		{
+		TUint8* tempPixelPtr = pixelPtr;
+
+		while (tempPixelPtr < pixelPtrLimit)
+			*tempPixelPtr++ |= aPixel;
+
+		pixelPtr += longWidth;
+		pixelPtrLimit += longWidth;
+		}
+	}
+
+/**
+Implementation for CFbsDrawDevice::GetInterface().
+Retrieves a pointer to a specified interface of CFbsDrawDevice implementation.
+@param aInterfaceId Interface identifier of the interface to be retrieved.
+@param aInterface Address of variable that retrieves the specified interface.
+@return KErrNone If the interface is supported, KErrNotSupported otherwise.
+*/
+
+TInt CDrawEightBppBitmapCommon::GetInterface(TInt aInterfaceId, TAny*& aInterface)
+	{
+	aInterface = NULL;
+	TInt ret = KErrNotSupported;
+	
+	if (aInterfaceId == KFastBlit2InterfaceID)
+		{
+		aInterface = static_cast<MFastBlit2*>(this);
+		ret = KErrNone;
+		}
+	else 
+		return CDrawBitmap::GetInterface(aInterfaceId, aInterface);
+		
+	return ret;
+	}
+
+/**
+CDrawEightBppBitmapCommon::WriteBitmapBlock() implementation.
+@internalTechnology
+@see MFastBlit2::WriteBitmapBlock()
+*/
+TInt CDrawEightBppBitmapCommon::WriteBitmapBlock(const TPoint& aDest,
+									CFbsDrawDevice* aSrcDrawDevice,
+									const TRect& aSrcRect)
+	{
+	__ASSERT_DEBUG(aSrcDrawDevice && ((aSrcDrawDevice->DisplayMode()==EColor256) || (aSrcDrawDevice->DisplayMode()==EGray256)), Panic(EScreenDriverPanicInvalidParameter));
+	
+	TAny* interface=NULL;
+	TInt ret = aSrcDrawDevice->GetInterface(KFastBlit2InterfaceID, interface);
+	if (ret != KErrNone)
+		{
+		return KErrNotSupported;
+		}
+
+	TAny* interface1=NULL;
+	ret = aSrcDrawDevice->GetInterface(KScalingSettingsInterfaceID, interface1);
+	if(ret != KErrNone || (interface1 && !reinterpret_cast<MScalingSettings*>(interface1)->IsScalingOff()))
+		{
+		return KErrNotSupported;
+		}
+
+	ret = aSrcDrawDevice->GetInterface(KOrientationInterfaceID, interface1);
+	if(ret != KErrNone || (interface1 && reinterpret_cast<MDrawDeviceOrientation*>(interface1)->Orientation() != 0))
+		{
+		return KErrNotSupported;
+		}
+
+	ret = aSrcDrawDevice->GetInterface(KDrawDeviceOriginInterfaceID, interface1);
+	if(ret != KErrNone)
+		{
+		return KErrNotSupported;
+		}
+	
+	if(interface1)
+		{
+	 	TPoint pt;
+	 	reinterpret_cast<MDrawDeviceOrigin*>(interface1)->Get(pt);
+	 	if(pt.iX != 0 || pt.iY != 0)
+	 		{
+			return KErrNotSupported;
+	 		}
+		}
+
+	const TUint32* srcBase = reinterpret_cast<MFastBlit2*>(interface)->Bits();
+	__ASSERT_DEBUG(srcBase!=NULL, Panic(EScreenDriverPanicInvalidParameter));
+	TInt srcStride = aSrcDrawDevice->ScanLineBytes();  
+	__ASSERT_DEBUG((srcStride&3)==0, Panic(EScreenDriverPanicInvalidParameter));  // stride is assumed to be a multiple of 4
+	TSize srcSize = aSrcDrawDevice->SizeInPixels();
+
+	return WriteBitmapBlock(aDest, srcBase, srcStride, srcSize, aSrcRect);
+	}
+
+								
+/**
+CDrawEightBppBitmapCommon::WriteBitmapBlock() implementation.
+@internalTechnology
+@see MFastBlit2::WriteBitmapBlock()
+*/													
+TInt CDrawEightBppBitmapCommon::WriteBitmapBlock(const TPoint& aDest,
+									const TUint32* aSrcBase,
+									TInt aSrcStride,
+									const TSize& aSrcSize,
+									const TRect& aSrcRect)
+	{
+	__ASSERT_DEBUG(aSrcBase, Panic(EScreenDriverPanicInvalidParameter));
+	__ASSERT_DEBUG((aSrcStride&3)==0, Panic(EScreenDriverPanicInvalidParameter));
+	__ASSERT_DEBUG(iBits, Panic(EScreenDriverPanicInvalidPointer));
+
+	if (iShadowMode!=NULL ||
+    	(iUserDispMode!=NULL && iUserDispMode!=iDispMode) ||
+    	iOrientation!=EOrientationNormal ||
+		!IsScalingOff() ||
+		!iOriginIsZero)
+		{
+		return KErrNotSupported;
+		}
+	
+	__ASSERT_DEBUG(aSrcRect.iTl.iX >= 0, Panic(EScreenDriverPanicOutOfBounds)); 
+	__ASSERT_DEBUG(aSrcRect.iTl.iY >= 0, Panic(EScreenDriverPanicOutOfBounds));
+	__ASSERT_DEBUG(aSrcRect.iBr.iX <= aSrcSize.iWidth,  Panic(EScreenDriverPanicOutOfBounds));
+	__ASSERT_DEBUG(aSrcRect.iBr.iY <= aSrcSize.iHeight, Panic(EScreenDriverPanicOutOfBounds));
+	__ASSERT_DEBUG(aDest.iX >= 0, Panic(EScreenDriverPanicOutOfBounds));
+	__ASSERT_DEBUG(aDest.iY >= 0, Panic(EScreenDriverPanicOutOfBounds));
+	__ASSERT_DEBUG((aDest.iX + aSrcRect.Width())  <= SizeInPixels().iWidth,  Panic(EScreenDriverPanicOutOfBounds));
+	__ASSERT_DEBUG((aDest.iY + aSrcRect.Height()) <= SizeInPixels().iHeight, Panic(EScreenDriverPanicOutOfBounds));
+	
+	const TInt srcStride8 = aSrcStride;
+	const TInt dstStride8 = iScanLineWords << 2;
+	
+	if (aSrcSize.iWidth == aSrcRect.Width() &&
+		aSrcSize.iWidth == SizeInPixels().iWidth &&
+		srcStride8 == dstStride8)
+		{
+		// Optimum case - one memcpy
+		__ASSERT_DEBUG(aSrcRect.iTl.iX==0 && aDest.iX==0, Panic(EScreenDriverPanicInvalidParameter));  // this is implied by the above conditions
+		const TUint32* srcPtr = aSrcBase + (iScanLineWords * aSrcRect.iTl.iY);
+		TUint32* dstPtr       = iBits    + (iScanLineWords * aDest.iY);
+		const TInt length = aSrcStride * aSrcRect.Height();
+		Mem::Move(dstPtr, srcPtr, length);
+		return KErrNone;
+		}
+		
+	// Sub-optimal case - one memcpy per line
+	const TUint8* srcPtr = (TUint8*)aSrcBase + (srcStride8 * aSrcRect.iTl.iY) + aSrcRect.iTl.iX;
+	TUint8* dstPtr       = (TUint8*)iBits    + (dstStride8 * aDest.iY       ) + aDest.iX;
+	const TInt length = aSrcRect.Width();
+	TInt lines = aSrcRect.Height();
+	while (lines--)
+		{
+		Mem::Copy(dstPtr, srcPtr, length);
+		srcPtr += srcStride8;
+		dstPtr += dstStride8;
+		}
+	return KErrNone;
+	}
+
+
+/**
+CDrawEightBppBitmapCommon::Bits() implementation.
+@internalTechnology
+@see MFastBlit2::Bits()
+*/
+const TUint32* CDrawEightBppBitmapCommon::Bits() const
+	{
+	return iBits;
+}