graphicsdeviceinterface/screendriver/sbit/BMDRAW16.CPP
changeset 0 5d03bc08d59c
child 33 25f95128741d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicsdeviceinterface/screendriver/sbit/BMDRAW16.CPP	Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,1524 @@
+// 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"
+#include <graphics/lookuptable.h>
+
+#if defined(SYMBIAN_USE_FAST_FADING)
+// 16bpp fast fade - half the contrast and brighten
+const TInt K16bppFastFadeShift = 1;
+const TUint16 K16bppFastFadeMask = 0x8410;
+// Use the 32 -> 16 bit colour convesrion method to get
+// the 16 bit fading constant (K16bppFastFadeOffset)
+// from 32 bit fading constant (SYMBIAN_USE_FAST_FADING).
+const TUint16 K16bppFastFadeOffset = ((SYMBIAN_USE_FAST_FADING & 0x0000f8) >> 3) |
+									((SYMBIAN_USE_FAST_FADING & 0x00fc00) >> 5) |
+									((SYMBIAN_USE_FAST_FADING & 0xf80000) >> 8);
+#endif
+
+// CDrawSixteenBppBitmapCommon
+
+//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 CDrawSixteenBppBitmapCommon::SetSize(const TSize& aSize) 
+	{
+	CDrawBitmap::SetSize(aSize);
+	__ASSERT_DEBUG(iSize == aSize, User::Invariant());
+	iLongWidth = (iSize.iWidth + 1) & ~1;
+	iScanLineWords = iLongWidth >> 1;
+	}
+ 
+TInt CDrawSixteenBppBitmapCommon::Construct(TSize aSize, TInt aStride)
+	{
+	iBits = NULL;
+	CDrawBitmap::SetSize(aSize);
+	__ASSERT_DEBUG(iSize == aSize, User::Invariant());
+	if (aStride & 3)
+		return KErrArgument;
+	iLongWidth = aStride >> 1;
+	if (iLongWidth < aSize.iWidth)
+		return KErrArgument;
+	iScanLineWords = aStride >> 2;
+	TInt size = Max(aSize.iWidth,aSize.iHeight) << 1;
+	if(size < 0)
+		return KErrArgument;
+	iScanLineBuffer = (TUint32*)(User::Heap().Alloc(size));
+	if (iScanLineBuffer == NULL)
+		return KErrNoMemory;
+	return KErrNone;
+	}
+
+TUint16* CDrawSixteenBppBitmapCommon::PixelAddress(TInt aX,TInt aY) const
+	{
+	return(((TUint16*)iBits) + (aY * iLongWidth) + aX);
+	}
+
+void CDrawSixteenBppBitmapCommon::InvertBuffer(TInt aLength,TUint32* aBuffer)
+	{
+	__ASSERT_DEBUG(aLength>0,Panic(EScreenDriverPanicZeroLength));
+	__ASSERT_DEBUG(aBuffer,Panic(EScreenDriverPanicNullPointer));
+
+	const TUint32* limit = aBuffer + ((aLength + 1) >> 1);
+
+	while (aBuffer < limit)
+		*aBuffer++ ^= 0xffffffff;
+	}
+
+void CDrawSixteenBppBitmapCommon::ShadowArea(const TRect& aRect)
+	{
+	const TRect rect(DeOrientate(aRect));
+
+	__ASSERT_DEBUG(rect.iTl.iX>=0 && rect.iBr.iX<=iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds));
+	__ASSERT_DEBUG(rect.iTl.iY>=0 && rect.iBr.iY<=iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds));
+
+	const TInt longWidth = iLongWidth;
+	TUint16* pixelPtr = PixelAddress(rect.iTl.iX,rect.iTl.iY);
+	const TUint16* pixelRowPtrLimit = pixelPtr + (rect.Height() * longWidth);
+
+	if (iShadowMode & EFade)
+		{
+		TUint16* pixelRowPtr = pixelPtr;
+		TUint16* pixelPtrLimit = pixelPtr + rect.Width();
+
+		while (pixelRowPtr < pixelRowPtrLimit)
+			{
+			for (TUint16* tempPixelPtr = pixelRowPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
+				tempPixelPtr[0] = FadeIndex(tempPixelPtr[0]);
+
+			pixelRowPtr += longWidth;
+			pixelPtrLimit += longWidth;
+			}
+		}
+
+	if (iShadowMode & EShadow)
+		{
+		TUint16* pixelRowPtr = pixelPtr;
+		TUint16* pixelPtrLimit = pixelPtr + rect.Width();
+
+		while (pixelRowPtr < pixelRowPtrLimit)
+			{
+			for (TUint16* tempPixelPtr = pixelRowPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
+				tempPixelPtr[0] = ShadowIndex(tempPixelPtr[0]);
+
+			pixelRowPtr += longWidth;
+			pixelPtrLimit += longWidth;
+			}
+		}
+	}
+
+void CDrawSixteenBppBitmapCommon::ShadowBuffer(TInt aLength,TUint32* aBuffer)
+	{
+	__ASSERT_DEBUG(aLength>0,Panic(EScreenDriverPanicZeroLength));
+	__ASSERT_DEBUG(aBuffer,Panic(EScreenDriverPanicNullPointer));
+
+	const TUint16* limit = ((TUint16*)aBuffer) + aLength;
+
+	if (iShadowMode & EFade)
+		{
+		for (TUint16* buffer = (TUint16*)aBuffer; buffer < limit; buffer++)
+			buffer[0] = FadeIndex(buffer[0]);
+		}
+
+	if (iShadowMode & EShadow)
+		{
+		for (TUint16* buffer = (TUint16*)aBuffer; buffer < limit; buffer++)
+			buffer[0] = ShadowIndex(buffer[0]);
+		}
+	}
+
+void CDrawSixteenBppBitmapCommon::ReadLine(TInt aX,TInt aY,TInt aLength,TAny* aBuffer) const
+	{
+	const TUint16* pixelPtr = PixelAddress(aX,aY);
+	if (iOrientation == EOrientationNormal && iScalingOff)
+		Mem::Copy(aBuffer,pixelPtr,aLength * 2);
+	else
+		{
+		const TInt pixelPtrInc = LogicalPixelAddressIncrement();
+		TUint16* bufferPtr = STATIC_CAST(TUint16*,aBuffer);
+		const TUint16* bufferPtrLimit = bufferPtr + aLength;
+		while (bufferPtr < bufferPtrLimit)
+			{
+			*bufferPtr++ = *pixelPtr;
+			pixelPtr += pixelPtrInc;
+			}
+		}
+	}
+
+void CDrawSixteenBppBitmapCommon::WriteBinary(TInt aX,TInt aY,TUint32* aData,TInt aLength,TInt aHeight,TUint16 aColor)
+	{
+	DeOrientate(aX,aY);
+	TInt pixelInc;
+	TInt rowInc;
+	SetPixelInc(pixelInc, rowInc);
+	const TUint32* dataLimit = aData + aHeight;
+	const TUint32 dataMaskLimit = (aLength < 32) ? 1 << aLength : 0;
+	TUint16* pixelPtr = PixelAddress(aX,aY);
+	const TUint16* bitsStart = reinterpret_cast <const TUint16*> (iBits);
+	const TUint16* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
+	TInt orgY = aY;
+	while (aData < dataLimit)
+		{
+		TUint32 dataWord = *aData++;
+		TUint32 dataMask = 1;
+		TUint16* tempPixelPtr = pixelPtr;
+		if (iScalingOff)
+			{
+			while (dataMask != dataMaskLimit)
+				{
+				if(dataWord & dataMask)
+					*tempPixelPtr = aColor;
+
+				tempPixelPtr += pixelInc;
+				dataMask <<= 1;
+				}
+			}
+		else
+			{
+			while (dataMask != dataMaskLimit)
+				{
+				if(dataWord & dataMask)
+					{
+					const TUint16* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
+					SetPixels(tempPixelPtr, aColor, pixelRowPtrLimit, bitsStart, bitsEnd);
+					}
+				tempPixelPtr += pixelInc;
+				dataMask <<= 1;
+				IncScaledY(aY);
+				}
+			}
+		pixelPtr += rowInc;
+		IncScaledY(aY, orgY);		
+		}
+	}
+
+void CDrawSixteenBppBitmapCommon::WriteBinaryOp(TInt aX,TInt aY,TUint32* aData,TInt aLength,TInt aHeight,TUint16 aColor,CGraphicsContext::TDrawMode aDrawMode)
+	{
+	if (aLength <= 0)
+		return;
+
+	DeOrientate(aX,aY);
+	TUint16* pixelPtr = PixelAddress(aX,aY);
+	const TUint32* dataPtrLimit = aData + aHeight;
+	const TUint32 dataMaskLimit = (aLength < 32) ? 1 << aLength : 0;
+	TInt pixelInc;
+	TInt rowInc;
+	SetPixelInc(pixelInc, rowInc);
+	const TUint16* bitsStart = reinterpret_cast <const TUint16*> (iBits);
+	const TUint16* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
+	TInt orgY = aY;
+	if (aColor)
+		{
+		while (aData < dataPtrLimit)
+			{
+			TUint32 dataWord = *aData++;
+			TUint32 dataMask = 1;
+			TUint16* tempPixelPtr = pixelPtr;
+			if (iScalingOff)
+				{
+				while (dataMask != dataMaskLimit)
+					{
+					if(dataWord & dataMask)
+						{
+						if(aDrawMode==CGraphicsContext::EDrawModeXOR)
+							*tempPixelPtr ^= aColor;
+						else if(aDrawMode==CGraphicsContext::EDrawModeAND)
+							*tempPixelPtr &= aColor;
+						else if(aDrawMode==CGraphicsContext::EDrawModeOR)
+							*tempPixelPtr |= aColor;
+						}
+					tempPixelPtr += pixelInc;
+					dataMask <<= 1;
+					}
+				}
+			else
+				{
+				while(dataMask != dataMaskLimit)
+					{
+					if(dataWord & dataMask)
+						{
+						const TUint16* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
+						if(aDrawMode==CGraphicsContext::EDrawModeXOR)
+							{
+							XORPixels(tempPixelPtr, aColor, pixelRowPtrLimit, bitsStart, bitsEnd);
+							}
+						else if(aDrawMode==CGraphicsContext::EDrawModeAND)
+							{
+							ANDPixels(tempPixelPtr, aColor, pixelRowPtrLimit, bitsStart, bitsEnd);
+							}
+						else if(aDrawMode==CGraphicsContext::EDrawModeOR)
+							{
+							ORPixels(tempPixelPtr, aColor, pixelRowPtrLimit, bitsStart, bitsEnd);
+							}
+						}
+					tempPixelPtr += pixelInc;
+					dataMask <<= 1;
+					IncScaledY(aY);
+					}
+				}
+			pixelPtr += rowInc;
+			IncScaledY(aY, orgY);			
+			}
+		}
+	else if(aDrawMode==CGraphicsContext::EDrawModeAND)
+		{
+		while (aData < dataPtrLimit)
+			{
+			TUint32 dataWord = *aData++;
+			TUint32 dataMask = 1;
+			TUint16* tempPixelPtr = pixelPtr;
+			if (iScalingOff)
+				{
+				while (dataMask != dataMaskLimit)
+					{
+					if(dataWord & dataMask)
+						*tempPixelPtr = 0;
+
+					tempPixelPtr += pixelInc;
+					dataMask <<= 1;
+					}
+				}
+			else
+				{
+				while(dataMask != dataMaskLimit)
+					{
+					if(dataWord & dataMask)
+						{
+						const TUint16* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
+						SetPixels(tempPixelPtr, TUint16(0), pixelRowPtrLimit, bitsStart, bitsEnd);
+						}
+					tempPixelPtr += pixelInc;
+					dataMask <<= 1;
+					}
+				}
+			pixelPtr += rowInc;
+			IncScaledY(aY, orgY);			
+			}
+		}
+	}
+
+void CDrawSixteenBppBitmapCommon::WriteBinaryLineVertical(TInt aX,TInt aY,TUint32* aData,TInt aHeight,TUint16 aColor,TBool aUp)
+	{
+	__ASSERT_DEBUG(iScalingOff, User::Invariant());	
+	DeOrientate(aX,aY);
+
+	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;
+
+	TUint16* pixelPtr = PixelAddress(aX,aY);
+	const TUint16* pixelPtrLimit = pixelPtr + (aHeight * scanlineByteLength);
+	TUint32 dataWord = *aData;
+	TUint32 dataMask = 1;
+
+	while(pixelPtr != pixelPtrLimit)
+		{
+		if(!dataMask)
+			{
+			dataMask = 1;
+			aData++;
+			dataWord = *aData;
+			}
+			
+		if(dataWord & dataMask)
+			*pixelPtr = aColor;
+		
+		dataMask <<= 1;
+		pixelPtr += scanlineByteLength;
+		}
+	}
+
+
+void CDrawSixteenBppBitmapCommon::WriteRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aHeight,TUint16 aColor)
+	{
+	const TInt longWidth = iLongWidth;
+	const TInt scanLineWords = iScanLineWords;
+
+	TUint16* pixelPtr = PixelAddress(aX,aY);
+	const TUint16* pixelRowPtrLimit = pixelPtr + (aHeight * longWidth);
+
+	if ((aColor >> 8) == (TUint8)aColor)
+		{
+		while (pixelPtr < pixelRowPtrLimit)
+			{
+			Mem::Fill(pixelPtr,aLength * 2,TUint8(aColor));
+			pixelPtr += longWidth;
+			}
+		}
+	else
+		{
+		const TBool leadingPixel = aX & 1;
+		const TBool trailingPixel = (aX + aLength) & 1;
+		const TUint32 colorWord = (aColor << 16) | aColor;
+
+		TUint16* lastPixelPtr = pixelPtr + aLength - 1;
+		TUint32* wordPtr = REINTERPRET_CAST(TUint32*,pixelPtr + (leadingPixel ? 1 : 0));
+		TUint32* wordPtrLimit = REINTERPRET_CAST(TUint32*,lastPixelPtr + (trailingPixel ? 0 : 1));
+
+		__ASSERT_DEBUG(!(TInt(wordPtr) & 3),Panic(EScreenDriverPanicInvalidPointer));
+		__ASSERT_DEBUG(!(TInt(wordPtrLimit) & 3),Panic(EScreenDriverPanicInvalidPointer));
+
+		if (leadingPixel)
+			{
+			while (pixelPtr < pixelRowPtrLimit)
+				{
+				pixelPtr[0] = aColor;
+				pixelPtr += longWidth;
+				}
+			}
+
+		while (wordPtr < (TUint32*)pixelRowPtrLimit)
+			{
+			MemFillTUint32(wordPtr, wordPtrLimit-wordPtr, colorWord);
+			wordPtr += scanLineWords;
+			wordPtrLimit += scanLineWords;
+			}
+
+		if (trailingPixel)
+			{
+			while (lastPixelPtr < pixelRowPtrLimit)
+				{
+				lastPixelPtr[0] = aColor;
+				lastPixelPtr += longWidth;
+				}
+			}
+		}
+	}
+
+void CDrawSixteenBppBitmapCommon::WriteRgbMultiXOR(TInt aX,TInt aY,TInt aLength,TInt aHeight,TUint16 aColor)
+	{
+	const TInt longWidth = iLongWidth;
+	TUint16* pixelPtr = PixelAddress(aX,aY);
+	TUint16* pixelPtrLimit = pixelPtr + aLength;
+	const TUint16* pixelRowPtrLimit = pixelPtr + (aHeight * longWidth);
+
+	while (pixelPtr < pixelRowPtrLimit)
+		{
+		for (TUint16* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
+			tempPixelPtr[0] ^= aColor;
+
+		pixelPtr += longWidth;
+		pixelPtrLimit += longWidth;
+		}
+	}
+
+void CDrawSixteenBppBitmapCommon::WriteRgbMultiAND(TInt aX,TInt aY,TInt aLength,TInt aHeight,TUint16 aColor)
+	{
+	const TInt longWidth = iLongWidth;
+	TUint16* pixelPtr = PixelAddress(aX,aY);
+	TUint16* pixelPtrLimit = pixelPtr + aLength;
+	const TUint16* pixelRowPtrLimit = pixelPtr + (aHeight * longWidth);
+
+	while (pixelPtr < pixelRowPtrLimit)
+		{
+		for (TUint16* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
+			tempPixelPtr[0] &= aColor;
+
+		pixelPtr += longWidth;
+		pixelPtrLimit += longWidth;
+		}
+	}
+
+void CDrawSixteenBppBitmapCommon::WriteRgbMultiOR(TInt aX,TInt aY,TInt aLength,TInt aHeight,TUint16 aColor)
+	{
+	const TInt longWidth = iLongWidth;
+	TUint16* pixelPtr = PixelAddress(aX,aY);
+	TUint16* pixelPtrLimit = pixelPtr + aLength;
+	const TUint16* pixelRowPtrLimit = pixelPtr + (aHeight * longWidth);
+
+	while (pixelPtr < pixelRowPtrLimit)
+		{
+		for (TUint16* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
+			tempPixelPtr[0] |= aColor;
+
+		pixelPtr += longWidth;
+		pixelPtrLimit += longWidth;
+		}
+	}
+
+void CDrawSixteenBppBitmapCommon::WriteLine(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
+	{
+	TUint16* pixelPtr = PixelAddress(aX,aY);
+	if (iOrientation == EOrientationNormal && iScalingOff)
+		Mem::Copy(pixelPtr,aBuffer,aLength * 2);
+	else
+		{
+		const TInt pixelPtrInc = LogicalPixelAddressIncrement();
+		TUint16* bufferPtr = REINTERPRET_CAST(TUint16*,aBuffer);
+		TUint16* bufferPtrLimit = bufferPtr + aLength;
+		if (iScalingOff)
+			{
+			while (bufferPtr < bufferPtrLimit)
+				{
+				*pixelPtr = *bufferPtr++;
+				pixelPtr += pixelPtrInc;
+				}
+			}
+		else
+			{
+			const TUint16* bitsStart = reinterpret_cast <const TUint16*> (iBits);
+			const TUint16* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
+			while(bufferPtr < bufferPtrLimit)
+				{
+				const TUint16* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
+				SetPixels(pixelPtr, *bufferPtr++, pixelRowPtrLimit, bitsStart, bitsEnd);
+				pixelPtr += pixelPtrInc;
+				IncScaledY(aY);
+				}
+			}
+		}
+	}
+
+void CDrawSixteenBppBitmapCommon::WriteLineXOR(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
+	{
+	TUint16* pixelPtr = PixelAddress(aX,aY);
+	const TInt pixelPtrInc = LogicalPixelAddressIncrement();
+	TUint16* bufferPtr = REINTERPRET_CAST(TUint16*,aBuffer);
+	const TUint16* bufferPtrLimit = bufferPtr + aLength;
+	if (iScalingOff)
+		{
+		while (bufferPtr < bufferPtrLimit)
+			{
+			*pixelPtr ^= *bufferPtr++;
+			pixelPtr += pixelPtrInc;
+			}
+		}
+	else
+		{
+		const TUint16* bitsStart = reinterpret_cast <const TUint16*> (iBits);
+		const TUint16* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
+		while(bufferPtr < bufferPtrLimit)
+			{
+			const TUint16* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
+			XORPixels(pixelPtr, *bufferPtr++, pixelRowPtrLimit, bitsStart, bitsEnd);
+			pixelPtr += pixelPtrInc;
+			IncScaledY(aY);
+			}
+		}
+	}
+
+void CDrawSixteenBppBitmapCommon::WriteLineAND(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
+	{
+	TUint16* pixelPtr = PixelAddress(aX,aY);
+	const TInt pixelPtrInc = LogicalPixelAddressIncrement();
+	TUint16* bufferPtr = REINTERPRET_CAST(TUint16*,aBuffer);
+	const TUint16* bufferPtrLimit = bufferPtr + aLength;
+	if (iScalingOff)
+		{
+		while (bufferPtr < bufferPtrLimit)
+			{
+			*pixelPtr &= *bufferPtr++;
+			pixelPtr += pixelPtrInc;
+			}
+		}
+	else
+		{
+		const TUint16* bitsStart = reinterpret_cast <const TUint16*> (iBits);
+		const TUint16* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
+		while(bufferPtr < bufferPtrLimit)
+			{
+			const TUint16* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
+			ANDPixels(pixelPtr, *bufferPtr++, pixelRowPtrLimit, bitsStart, bitsEnd);
+			pixelPtr += pixelPtrInc;
+			IncScaledY(aY);
+			}
+		}
+	}
+
+void CDrawSixteenBppBitmapCommon::WriteLineOR(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
+	{
+	TUint16* pixelPtr = PixelAddress(aX,aY);
+	const TInt pixelPtrInc = LogicalPixelAddressIncrement();
+	TUint16* bufferPtr = REINTERPRET_CAST(TUint16*,aBuffer);
+	const TUint16* bufferPtrLimit = bufferPtr + aLength;
+	if (iScalingOff)
+		{
+		while (bufferPtr < bufferPtrLimit)
+			{
+			*pixelPtr |= *bufferPtr++;
+			pixelPtr += pixelPtrInc;
+			}
+		}
+	else
+		{
+		const TUint16* bitsStart = reinterpret_cast <const TUint16*> (iBits);
+		const TUint16* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
+		while(bufferPtr < bufferPtrLimit)
+			{
+			const TUint16* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
+			ORPixels(pixelPtr, *bufferPtr++, pixelRowPtrLimit, bitsStart, bitsEnd);
+			pixelPtr += pixelPtrInc;
+			IncScaledY(aY);
+			}
+		}
+	}
+
+/**
+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 CDrawSixteenBppBitmapCommon::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;
+	}
+
+/**
+CDrawSixteenBppBitmapCommon::WriteBitmapBlock() implementation.
+@internalTechnology
+@see MFastBlit2::WriteBitmapBlock()
+*/
+TInt CDrawSixteenBppBitmapCommon::WriteBitmapBlock(const TPoint& aDest,
+									CFbsDrawDevice* aSrcDrawDevice,
+									const TRect& aSrcRect)
+	{
+	__ASSERT_DEBUG(aSrcDrawDevice && ((aSrcDrawDevice->DisplayMode()==EColor64K) || (aSrcDrawDevice->DisplayMode()==EColor4K)), 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);
+	}
+
+								
+/**
+CDrawSixteenBppBitmapCommon::WriteBitmapBlock() implementation.
+@internalTechnology
+@see MFastBlit2::WriteBitmapBlock()
+*/													
+TInt CDrawSixteenBppBitmapCommon::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 srcStride16 = aSrcStride     >> 1;
+	const TInt dstStride16 = iScanLineWords << 1;
+	
+	if (aSrcSize.iWidth == aSrcRect.Width() &&
+		aSrcSize.iWidth == SizeInPixels().iWidth &&
+		srcStride16 == dstStride16)
+		{
+		// 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 TUint16* srcPtr = (TUint16*)aSrcBase + (srcStride16 * aSrcRect.iTl.iY) + aSrcRect.iTl.iX;
+	TUint16* dstPtr       = (TUint16*)iBits    + (dstStride16 * aDest.iY       ) + aDest.iX;
+	const TInt length = aSrcRect.Width() << 1;
+	TInt lines = aSrcRect.Height();
+	while (lines--)
+		{
+		Mem::Copy(dstPtr, srcPtr, length);
+		srcPtr += srcStride16;
+		dstPtr += dstStride16;
+		}
+	return KErrNone;
+	}
+
+/**
+CDrawSixteenBppBitmapCommon::Bits() implementation.
+@internalTechnology
+@see MFastBlit2::Bits()
+*/
+const TUint32* CDrawSixteenBppBitmapCommon::Bits() const
+	{
+	return iBits;
+	}
+
+// CDrawSixteenBppBitmap
+
+TInt CDrawSixteenBppBitmap::Construct(TSize aSize)
+	{
+	return Construct(aSize, ((aSize.iWidth + 1) & ~1) << 1);
+	}
+
+TInt CDrawSixteenBppBitmap::Construct(TSize aSize, TInt aStride)
+	{
+	iDispMode = EColor64K;
+	return CDrawSixteenBppBitmapCommon::Construct(aSize, aStride);
+	}
+
+void CDrawSixteenBppBitmap::Shadow(TRgb& aColor)
+	{
+	if (iShadowMode & EFade)
+		{
+#if defined(SYMBIAN_USE_FAST_FADING)
+		TUint16 color = aColor._Color64K();
+		TInt alpha = aColor.Alpha();
+		color = TUint16(((color >> K16bppFastFadeShift) & ~K16bppFastFadeMask) + K16bppFastFadeOffset);
+		aColor = TRgb::_Color64K(color);
+		aColor.SetAlpha(alpha);
+#else
+		TRgb fadeColor = TRgb::_Color64K(aColor._Color64K());
+		fadeColor.SetAlpha(aColor.Alpha());
+		aColor = FadeRgb(fadeColor);
+#endif
+		}
+
+	if (iShadowMode & EShadow)
+		{
+		TRgb shadowColor = TRgb::_Color64K(ShadowIndex(TUint16(aColor._Color64K())));
+		shadowColor.SetAlpha(aColor.Alpha());
+		aColor = shadowColor;
+		}
+	}
+
+/**
+The overloaded function for Shadow(TRgb) which works directly with
+the Red, Green and Blue colour components to increase the performance.
+@param aRed Red component of colour.
+@param aGreen Green component of colour.
+@param aBlue Blue component of colour.
+*/
+FORCEINLINE void CDrawSixteenBppBitmap::Shadow(TInt& aRed, TInt& aGreen, TInt& aBlue)
+	{
+	if (iShadowMode & EFade)
+		{
+#if defined(SYMBIAN_USE_FAST_FADING)
+		TUint16 color = PackColor64K(aRed, aGreen, aBlue);
+		color = TUint16(((color >> K16bppFastFadeShift) & ~K16bppFastFadeMask) + K16bppFastFadeOffset);
+		UnpackColor64K(color, aRed, aGreen, aBlue);
+#else
+		FadeRgb(aRed, aGreen, aBlue);
+#endif
+		}
+
+	if (iShadowMode & EShadow)
+		{
+		ShadowIndex(aRed, aGreen, aBlue);
+		}
+	}
+
+/**
+The overloaded function for Shadow(TRgb) which works directly with
+16 bit colour instead of TRgb to increase the performance.
+@param a64KColor The 16 bit colour value.
+*/
+FORCEINLINE void CDrawSixteenBppBitmap::Shadow(TUint16& a64KColor)
+	{
+	if (iShadowMode & EFade)
+		{
+#if defined(SYMBIAN_USE_FAST_FADING)
+		a64KColor = TUint16(((a64KColor >> K16bppFastFadeShift) & ~K16bppFastFadeMask) + K16bppFastFadeOffset);
+#else
+		TRgb fadeColor = TRgb::_Color64K(a64KColor);
+		fadeColor.SetAlpha(0xFF);
+		a64KColor = FadeRgb(fadeColor)._Color64K();
+#endif
+		}
+	if (iShadowMode & EShadow)
+		{
+		a64KColor = ShadowIndex(a64KColor);
+		}
+	}
+
+TUint16 CDrawSixteenBppBitmap::ShadowIndex(TUint16 aColor64KIndex)
+	{
+	TInt red = (aColor64KIndex & 0xf800) >> 11;
+	TInt green = (aColor64KIndex & 0x07e0) >> 5;
+	TInt blue = aColor64KIndex & 0x001f;
+
+	red = Max(0,red-8);
+	green = Max(0,green-16);
+	blue = Max(0,blue-8);
+
+	return TUint16((red << 11) | (green << 5) | blue);
+	}
+
+/**
+The overloaded function for ShadowIndex(TUint16) which works directly with
+the Red, Green and Blue colour components to increase the performance.
+@param aRed Red component of colour.
+@param aGreen Green component of colour.
+@param aBlue Blue component of colour.
+*/
+FORCEINLINE void CDrawSixteenBppBitmap::ShadowIndex(TInt& aRed, TInt& aGreen, TInt& aBlue)
+	{
+	aRed = Max(0,aRed-8);
+	aGreen = Max(0,aGreen-16);
+	aBlue = Max(0,aBlue-8);
+	}
+
+TUint16 CDrawSixteenBppBitmap::FadeIndex(TUint16 aColor64KIndex)
+	{
+#if defined(SYMBIAN_USE_FAST_FADING)
+	return TUint16(((aColor64KIndex >> K16bppFastFadeShift) & ~K16bppFastFadeMask) + K16bppFastFadeOffset);
+#else
+	return TUint16(FadeRgb(TRgb::_Color64K(aColor64KIndex))._Color64K());
+#endif
+	}
+
+TRgb CDrawSixteenBppBitmap::ReadRgbNormal(TInt aX,TInt aY) const
+	{
+	return TRgb::_Color64K(*PixelAddress(aX,aY));
+	}
+
+void CDrawSixteenBppBitmap::WriteRgb(TInt aX,TInt aY,TRgb aColor)
+	{
+	register TUint16* pixelAddr = PixelAddress(aX, aY);
+	register TUint16 aPixel = TUint16(aColor._Color64K());
+	
+	const TInt sourceAlpha = aColor.Alpha();	
+
+	if (sourceAlpha==0)
+		return;
+	
+	if (sourceAlpha<0xff)
+		{
+		const TUint32 srcInternal=aColor.Internal();
+		const TUint32 srcRB=srcInternal & 0x00FF00FF;
+		const TUint32 srcG=(srcInternal & 0xFF00) >> 8;
+		aPixel = BlendTo16(srcRB, srcG, sourceAlpha, *pixelAddr);
+		}
+
+	if (iScalingOff)
+		{
+		*pixelAddr = aPixel;
+		}
+	else
+		{
+		const TUint16* bitsStart = reinterpret_cast <const TUint16*> (iBits);
+		const TUint16* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
+		const TUint16* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
+		SetPixels(pixelAddr, aPixel, pixelRowPtrLimit, bitsStart, bitsEnd);
+		}
+	}
+
+void CDrawSixteenBppBitmap::WriteBinary(TInt aX,TInt aY,TUint32* aData,TInt aLength,TInt aHeight,TRgb aColor)
+	{
+	const TInt sourceAlpha = aColor.Alpha();
+	if (sourceAlpha==255)
+		{
+		CDrawSixteenBppBitmapCommon::WriteBinary(aX,aY,aData,aLength,aHeight,(TUint16)aColor._Color64K());
+		return;
+		}
+	if (sourceAlpha==0)
+		return;
+
+	DeOrientate(aX,aY);
+
+	TInt pixelInc;
+	TInt rowInc;
+
+	switch(iOrientation)
+		{
+		case EOrientationNormal:
+			{
+			pixelInc = 1;
+			rowInc = iLongWidth;
+			break;
+			}
+		case EOrientationRotated90:
+			{
+			pixelInc = iLongWidth;
+			rowInc = -1;
+			break;
+			}
+		case EOrientationRotated180:
+			{
+			pixelInc = -1;
+			rowInc = -iLongWidth;
+			break;
+			}
+		default: // EOrientationRotated270
+			{
+			pixelInc = -iLongWidth;
+			rowInc = 1;
+			}
+		}
+
+	const TUint32* dataLimit = aData + aHeight;
+	const TUint32 dataMaskLimit = (aLength < 32) ? 1 << aLength : 0;
+
+	TUint16* pixelPtr = PixelAddress(aX,aY);
+
+	const TUint32 srcInternal=aColor.Internal();
+	const TUint32 srcRB=srcInternal & 0x00FF00FF;
+	const TUint32 srcG=(srcInternal & 0xFF00) >> 8;
+	while (aData < dataLimit)
+		{
+		TUint32 dataWord = *aData++;
+		TUint32 dataMask = 1;
+		TUint16* tempPixelPtr = pixelPtr;
+
+		while (dataMask != dataMaskLimit)
+			{
+			if(dataWord & dataMask)
+				{
+				*tempPixelPtr = BlendTo16(srcRB, srcG, sourceAlpha, *tempPixelPtr);
+				}
+
+			tempPixelPtr += pixelInc;
+			dataMask <<= 1;
+			}
+
+		pixelPtr += rowInc;
+		}
+	}
+
+void CDrawSixteenBppBitmap::WriteBinaryOp(TInt aX,TInt aY,TUint32* aData,TInt aLength,TInt aHeight,TRgb aColor,CGraphicsContext::TDrawMode aDrawMode)
+	{
+	CDrawSixteenBppBitmapCommon::WriteBinaryOp(aX,aY,aData,aLength,aHeight,(TUint16)aColor._Color64K(),aDrawMode);
+	}
+
+void CDrawSixteenBppBitmap::WriteBinaryLineVertical(TInt aX,TInt aY,TUint32* aData,TInt aHeight,TRgb aColor,TBool aUp)
+	{
+	const TInt sourceAlpha = aColor.Alpha();
+	if (sourceAlpha==255)
+		{
+		CDrawSixteenBppBitmapCommon::WriteBinaryLineVertical(aX,aY,aData,aHeight,(TUint16)aColor._Color64K(),aUp);
+		return;
+		}
+	if (sourceAlpha==0)
+		return;
+
+	DeOrientate(aX,aY);
+
+	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;
+
+	TUint16* pixelPtr = PixelAddress(aX,aY);
+	const TUint16* pixelPtrLimit = pixelPtr + (aHeight * scanlineByteLength);
+	TUint32 dataWord = *aData;
+	TUint32 dataMask = 1;
+
+	const TUint32 srcInternal=aColor.Internal();
+	const TUint32 srcRB=srcInternal & 0x00FF00FF;
+	const TUint32 srcG=(srcInternal & 0xFF00) >> 8;
+	while(pixelPtr != pixelPtrLimit)
+		{
+		if(!dataMask)
+			{
+			dataMask = 1;
+			aData++;
+			dataWord = *aData;
+			}
+
+		if(dataWord & dataMask)
+			{
+			*pixelPtr = BlendTo16(srcRB, srcG, sourceAlpha, *pixelPtr);
+			}
+		dataMask <<= 1;
+		pixelPtr += scanlineByteLength;
+		}
+	}
+
+/**
+MAlphaBlend::WriteRgbAlphaLine2() implementation.
+@see MAlphaBlend::WriteRgbAlphaLine2()
+*/
+void CDrawSixteenBppBitmap::WriteRgbAlphaLine(TInt aX, TInt aY, TInt aLength,
+                                              const TUint8* aRgbBuffer,
+                                              const TUint8* aMaskBuffer,
+                                              MAlphaBlend::TShadowing aShadowing,
+                                              CGraphicsContext::TDrawMode /*aDrawMode*/)
+    {
+	DeOrientate(aX,aY);
+	TUint16* pixelPtr = PixelAddress(aX,aY);
+	const TInt pixelPtrInc = LogicalPixelAddressIncrement();
+	const TUint8* maskBufferPtrLimit = aMaskBuffer + aLength;
+	TUint16 pixelColor;
+
+	__ASSERT_DEBUG( (((((TUint)pixelPtr)&1)==0) && ((((TUint)aRgbBuffer)&3)==0)), Panic(EScreenDriverPanicInvalidParameter));
+
+	if (iScalingOff)
+		{
+		if (!(iShadowMode & (EFade | EShadow)) && iUserDispMode == ENone)
+			{
+			TUint32* rgbBuffer32 = (TUint32*)aRgbBuffer;
+			while (aMaskBuffer < maskBufferPtrLimit)
+				{
+				pixelPtr[0] = Blend32To16(rgbBuffer32[0], aMaskBuffer[0], pixelPtr[0]);
+				pixelPtr += pixelPtrInc;
+				rgbBuffer32 ++;
+				aMaskBuffer++;
+				}
+			}
+		else
+			{
+			while (aMaskBuffer < maskBufferPtrLimit)
+				{
+				TInt blue = aRgbBuffer[0];
+				TInt green = aRgbBuffer[1];
+				TInt red = aRgbBuffer[2];
+				if(aShadowing == MAlphaBlend::EShdwBefore)
+					{
+					Shadow(red,green,blue);
+					}
+				pixelColor = ::AlphaBlend(red,green,blue, pixelPtr[0],aMaskBuffer[0]);
+				if(aShadowing == MAlphaBlend::EShdwAfter)
+					{
+					Shadow(pixelColor);
+					}
+				MapColorToUserDisplayMode(pixelColor);
+				pixelPtr[0] = pixelColor;
+
+				pixelPtr += pixelPtrInc;
+				aRgbBuffer += 4;
+				aMaskBuffer++;
+				}
+			}
+		}
+	else
+		{
+		const TUint16* bitsStart = reinterpret_cast <const TUint16*> (iBits);
+		const TUint16* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
+		while (aMaskBuffer < maskBufferPtrLimit)
+			{
+			TInt blue = aRgbBuffer[0];
+			TInt green = aRgbBuffer[1];
+			TInt red = aRgbBuffer[2];
+            if(aShadowing == MAlphaBlend::EShdwBefore)
+                {
+                Shadow(red,green,blue);
+                }
+            pixelColor = ::AlphaBlend(red,green,blue,pixelPtr[0],aMaskBuffer[0]);
+            if(aShadowing == MAlphaBlend::EShdwAfter)
+                {
+		        Shadow(pixelColor);
+                }
+			MapColorToUserDisplayMode(pixelColor);
+			const TUint16* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
+			SetPixels(pixelPtr, pixelColor, pixelRowPtrLimit, bitsStart, bitsEnd);
+			pixelPtr += pixelPtrInc;
+			aRgbBuffer += 4;
+			aMaskBuffer++;
+			IncScaledY(aY);
+			}
+		}
+	}
+
+void CDrawSixteenBppBitmap::WriteRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
+	{
+	CDrawSixteenBppBitmapCommon::WriteRgbMulti(aX,aY,aLength,aHeight,(TUint16)aColor._Color64K());
+	}
+
+void CDrawSixteenBppBitmap::BlendRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
+	{
+	const TInt sourceAlpha = aColor.Alpha();
+	if (sourceAlpha==255)// opaque
+		{
+		CDrawSixteenBppBitmapCommon::WriteRgbMulti(aX,aY,aLength,aHeight,(TUint16)aColor._Color64K());
+		return;
+		}
+	if (sourceAlpha==0)// transparent
+		return;
+
+	const TInt sourceRed = aColor.Red();
+	const TInt sourceGreen = aColor.Green();
+	const TInt sourceBlue = aColor.Blue();
+
+	const TInt longWidth = iLongWidth;
+	TUint16* pixelPtr = PixelAddress(aX,aY);
+	TUint16* pixelPtrLimit = pixelPtr + aLength;
+	const TUint16* pixelRowPtrLimit = pixelPtr + (aHeight * longWidth);
+	const TInt mask=aColor.Alpha();
+	const TUint32 srcInternal=aColor.Internal();
+	const TUint32 srcRB=srcInternal & 0x00FF00FF;
+	const TUint32 srcG=(srcInternal & 0xFF00) >> 8;
+	while (pixelPtr < pixelRowPtrLimit)
+		{
+		for (TUint16* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
+			{
+			*tempPixelPtr = BlendTo16(srcRB, srcG, mask, *tempPixelPtr);
+			}
+		pixelPtr += longWidth;
+		pixelPtrLimit += longWidth;
+		}
+	}
+
+void CDrawSixteenBppBitmap::WriteRgbMultiXOR(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
+	{
+	CDrawSixteenBppBitmapCommon::WriteRgbMultiXOR(aX,aY,aLength,aHeight,(TUint16)aColor._Color64K());
+	}
+
+void CDrawSixteenBppBitmap::WriteRgbMultiAND(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
+	{
+	CDrawSixteenBppBitmapCommon::WriteRgbMultiAND(aX,aY,aLength,aHeight,(TUint16)aColor._Color64K());
+	}
+
+void CDrawSixteenBppBitmap::WriteRgbMultiOR(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
+	{
+	CDrawSixteenBppBitmapCommon::WriteRgbMultiOR(aX,aY,aLength,aHeight,(TUint16)aColor._Color64K());
+	}
+
+void CDrawSixteenBppBitmap::WriteRgbAlphaMulti(TInt aX,TInt aY,TInt aLength,TRgb aColor,const TUint8* aMaskBuffer)
+	{
+	const TInt alpha = aColor.Alpha();
+	if (alpha==0 || aLength<=0)
+		return;
+	DeOrientate(aX,aY);
+	TUint16* pixelPtr = PixelAddress(aX,aY);
+	const TInt pixelPtrInc = LogicalPixelAddressIncrement();
+	const TUint8* maskBufferPtrLimit = aMaskBuffer + aLength;
+
+ 	if (iShadowMode)
+ 		{
+ 		Shadow(aColor);
+ 		}
+ 
+	if (iScalingOff)
+		{
+	    const TUint32 color16bpp=aColor.Color64K();
+		const TUint32 srcInternal=aColor.Internal();
+		const TUint32 srcRB=srcInternal & 0x00FF00FF;
+		const TUint32 srcG=(srcInternal & 0xFF00) >> 8;
+		if (alpha == 0xff)
+			{
+			while (aMaskBuffer < maskBufferPtrLimit)
+				{
+				const TUint32 mask=*aMaskBuffer++;
+				if (mask)
+					{
+					if (mask==0xFF)
+						*pixelPtr = color16bpp;
+					else
+						*pixelPtr = BlendTo16(srcRB, srcG, mask, *pixelPtr);
+					}
+				pixelPtr += pixelPtrInc;
+				}
+			}
+		else
+			{ // pen is semi-transparent, so we must blend using both the mask and pen alpha
+			while (aMaskBuffer < maskBufferPtrLimit)
+				{
+				TUint blendAlpha = alpha;
+				TUint maskAlpha = *aMaskBuffer++;
+				if (maskAlpha)
+					{
+					if (maskAlpha!=0xFF)
+						blendAlpha=((maskAlpha+1) * alpha)>>8;
+					*pixelPtr = BlendTo16(srcRB, srcG, blendAlpha, *pixelPtr);
+					}
+				pixelPtr += pixelPtrInc;
+				}
+			}
+		}
+	else
+		{
+		const TInt red = aColor.Red();
+		const TInt green = aColor.Green();
+		const TInt blue = aColor.Blue();
+		if (alpha == 0xff)
+			{
+			const TUint16* bitsStart = reinterpret_cast <const TUint16*> (iBits);
+			const TUint16* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
+			while(aMaskBuffer < maskBufferPtrLimit)
+				{
+				TUint16 pixelColor = AlphaBlend(red,green,blue, *pixelPtr, *aMaskBuffer);
+				const TUint16* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
+				SetPixels(pixelPtr, pixelColor, pixelRowPtrLimit, bitsStart, bitsEnd);
+				pixelPtr += pixelPtrInc;
+				aMaskBuffer++;
+				IncScaledY(aY);
+				}
+			}
+		else
+			{ // require special handling for different alpha values
+			const TUint16* bitsStart = reinterpret_cast <const TUint16*> (iBits);
+			const TUint16* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
+			while(aMaskBuffer < maskBufferPtrLimit)
+				{
+				const TInt maskAlpha = *aMaskBuffer;
+				const TInt sourceAlpha = alpha * maskAlpha;
+				const TInt inverseAlpha = 255*255 - sourceAlpha;
+
+				TInt pixelRed;
+				TInt pixelGreen;
+				TInt pixelBlue;
+				UnpackColor64K(*pixelPtr, pixelRed, pixelGreen, pixelBlue);
+				TInt blueAfter = TUint8(((blue * sourceAlpha) + (pixelBlue * inverseAlpha)) / (255*255));
+				TInt greenAfter = TUint8(((green * sourceAlpha) + (pixelGreen * inverseAlpha)) / (255*255));
+				TInt redAfter = TUint8(((red * sourceAlpha) + (pixelRed * inverseAlpha)) / (255*255));
+				TUint16 pixelColor = PackColor64K(redAfter, greenAfter, blueAfter);
+
+				const TUint16* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
+				SetPixels(pixelPtr, pixelColor, pixelRowPtrLimit, bitsStart, bitsEnd);
+				pixelPtr += pixelPtrInc;
+				aMaskBuffer++;
+				IncScaledY(aY);
+				}
+			}
+		}
+	}
+
+void CDrawSixteenBppBitmap::MapColorToUserDisplayMode(TRgb& aColor)
+	{
+	switch (iUserDispMode)
+		{
+	case EGray2:
+		aColor = TRgb::_Gray2(aColor._Gray2());
+		break;
+	case EGray4:
+		aColor = TRgb::_Gray4(aColor._Gray4());
+		break;
+	case EGray16:
+		aColor = TRgb::_Gray16(aColor._Gray16());
+		break;
+	case EGray256:
+		aColor = TRgb::_Gray256(aColor._Gray256());
+		break;
+	case EColor16:
+		aColor = TRgb::Color16(aColor.Color16());
+		break;
+	case EColor256:
+		aColor = TRgb::Color256(aColor.Color256());
+		break;
+	case EColor4K:
+		aColor = TRgb::_Color4K(aColor._Color4K());
+		break;
+	default:
+		break;
+		}
+	}
+
+/**
+The overloaded function for MapColorToUserDisplayMode(TRgb) which works directly with
+16 bit colour instead of TRgb to increase the performance.
+@param a64KColor The 16 bit colour value.
+*/
+void CDrawSixteenBppBitmap::MapColorToUserDisplayMode(TUint16& aColor64K)
+	{
+	TRgb color = TRgb::_Color64K(aColor64K);
+
+	switch (iUserDispMode)
+		{
+	case EGray2:
+		{
+		color = TRgb::_Gray2(color._Gray2());
+		}
+		break;
+	case EGray4:
+		{
+		color = TRgb::_Gray4(color._Gray4());
+		}
+		break;
+	case EGray16:
+		{
+		color = TRgb::_Gray16(color._Gray16());
+		}
+		break;
+	case EGray256:
+		{
+		color = TRgb::_Gray256(color._Gray256());
+		}
+		break;
+	case EColor16:
+		{
+		color = TRgb::Color16(color.Color16());
+		}
+		break;
+	case EColor256:
+		{
+		color = TRgb::Color256(color.Color256());
+		}
+		break;
+	case EColor4K:
+		{
+		color = TRgb::_Color4K(color._Color4K());
+		}
+		break;
+	default:
+		break;
+		}
+	aColor64K = color._Color64K();
+	}
+
+void CDrawSixteenBppBitmap::MapBufferToUserDisplayMode(TInt aLength,TUint32* aBuffer)
+	{
+	TUint16* bufferPtr = (TUint16*)aBuffer;
+	const TUint16* bufferLimit = bufferPtr + aLength;
+	TRgb color;
+	
+	switch (iUserDispMode)
+		{
+	case EGray2:
+		while (bufferPtr < bufferLimit)
+			{
+			color = TRgb::_Color64K(*bufferPtr);
+			color = TRgb::_Gray2(color._Gray2());
+			*bufferPtr++ = TUint16(color._Color64K());
+			}
+		break;
+	case EGray4:
+		while (bufferPtr < bufferLimit)
+			{
+			color = TRgb::_Color64K(*bufferPtr);
+			color = TRgb::_Gray4(color._Gray4());
+			*bufferPtr++ = TUint16(color._Color64K());
+			}
+		break;
+	case EGray16:
+		while (bufferPtr < bufferLimit)
+			{
+			color = TRgb::_Color64K(*bufferPtr);
+			color = TRgb::_Gray16(color._Gray16());
+			*bufferPtr++ = TUint16(color._Color64K());
+			}
+		break;
+	case EGray256:
+		while (bufferPtr < bufferLimit)
+			{
+			color = TRgb::_Color64K(*bufferPtr);
+			color = TRgb::_Gray256(color._Gray256());
+			*bufferPtr++ = TUint16(color._Color64K());
+			}
+		break;
+	case EColor16:
+		while (bufferPtr < bufferLimit)
+			{
+			color = TRgb::_Color64K(*bufferPtr);
+			color = TRgb::Color16(color.Color16());
+			*bufferPtr++ = TUint16(color._Color64K());
+			}
+		break;
+	case EColor256:
+		while (bufferPtr < bufferLimit)
+			{
+			color = TRgb::_Color64K(*bufferPtr);
+			color = TRgb::Color256(color.Color256());
+			*bufferPtr++ = TUint16(color._Color64K());
+			}
+		break;
+	case EColor4K:
+		while (bufferPtr < bufferLimit)
+			{
+			color = TRgb::_Color64K(*bufferPtr);
+			color = TRgb::_Color4K(color._Color4K());
+			*bufferPtr++ = TUint16(color._Color64K());
+			}
+		break;
+	default:
+		break;
+		}
+	}
+
+TInt CDrawSixteenBppBitmap::WriteRgbOutlineAndShadow(TInt aX, TInt aY, const TInt aLength, 
+													TUint32 aOutlinePenColor, TUint32 aShadowColor,
+													TUint32 aFillColor, const TUint8* aDataBuffer)
+	{
+	const TInt alpha = aOutlinePenColor >> 24;
+	if (alpha==0 || aLength<=0)
+		return(KErrNone);
+	DeOrientate(aX,aY);
+	TUint16* pixelPtr = PixelAddress(aX,aY);
+	const TInt pixelPtrInc = LogicalPixelAddressIncrement();
+	const TUint8* dataBufferPtrLimit = aDataBuffer + aLength;	
+	TInt blendedRedColor;
+	TInt blendedGreenColor;
+	TInt blendedBlueColor;
+	TUint32 finalColor;
+
+	//Get red color. Equivalent to TRgb::Red()
+	const TInt redOutlinePenColor = (aOutlinePenColor & 0xff0000) >> 16;
+	const TInt redShadowColor = (aShadowColor & 0xff0000) >> 16;
+	const TInt redFillColor = (aFillColor & 0xff0000) >> 16;
+
+	//Get green color. Equivalent to TRgb::Green()
+	const TInt greenOutlinePenColor = (aOutlinePenColor & 0xff00) >> 8;
+	const TInt greenShadowColor = (aShadowColor & 0xff00) >> 8;
+	const TInt greenFillColor = (aFillColor & 0xff00) >> 8;
+
+	//Get blue color. Equivalent to TRgb::Blue()
+	const TInt blueOutlinePenColor = aOutlinePenColor & 0xff;
+	const TInt blueShadowColor = aShadowColor & 0xff;
+	const TInt blueFillColor = aFillColor & 0xff;
+
+	while (aDataBuffer < dataBufferPtrLimit)
+		{
+		TUint8 index = *aDataBuffer++;
+
+		if (255 == FourColorBlendLookup[index][KBackgroundColorIndex])
+			{
+			//background colour
+			//No drawing required so move on to next pixel.
+			pixelPtr += pixelPtrInc;
+			continue;
+			}
+		else if (255 == FourColorBlendLookup[index][KFillColorIndex])
+			{
+			//Use fill colour to draw
+			finalColor = aFillColor;
+			}
+		else if (255 == FourColorBlendLookup[index][KShadowColorIndex])
+			{
+			//Use shadow colour to draw
+			finalColor = aShadowColor;
+			}
+		else if (255 == FourColorBlendLookup[index][KOutlineColorIndex])
+			{
+			//Use outline colour to draw
+			finalColor = aOutlinePenColor;
+			}
+		else
+			{
+			//Get the background pixel colour. Using the lookup table to convert 16 to 32 bit colour
+			blendedRedColor = redOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] + 
+						   		redShadowColor * FourColorBlendLookup[index][KShadowColorIndex] +
+						  		redFillColor * FourColorBlendLookup[index][KFillColorIndex];
+
+			blendedGreenColor = greenOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] + 
+								greenShadowColor * FourColorBlendLookup[index][KShadowColorIndex] +
+								greenFillColor * FourColorBlendLookup[index][KFillColorIndex];
+
+			blendedBlueColor = blueOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] + 
+								blueShadowColor * FourColorBlendLookup[index][KShadowColorIndex] +
+								blueFillColor * FourColorBlendLookup[index][KFillColorIndex];
+
+			TInt backGroundAlpha=FourColorBlendLookup[index][KBackgroundColorIndex];
+			if (backGroundAlpha)
+				{
+				const TUint8* pixelPtr8 = reinterpret_cast<TUint8*>(pixelPtr); 
+				const TUint8 low = *pixelPtr8++;
+				const TUint8 high = *pixelPtr8++;
+				TUint32 backgroundColor = (*(Convert16to32bppHigh() + high)) | (*(Convert16to32bppLow() + low));
+				blendedRedColor += ((backgroundColor & 0xff0000) >> 16) * backGroundAlpha;
+				blendedGreenColor += ((backgroundColor & 0xff00) >> 8) * backGroundAlpha;
+				blendedBlueColor += (backgroundColor & 0xff) * backGroundAlpha;
+				}
+			//Equivalent to TRgb::TRgb(TUint32)
+			finalColor = ((blendedRedColor&0xFF00)<<8) | (blendedGreenColor&0xFF00) | (blendedBlueColor>>8);
+			}
+
+		if (alpha == 0xff)
+			{
+			*pixelPtr = Conv32To16(finalColor);
+			}
+		else
+			{
+			*pixelPtr = Blend32To16NoChecks(finalColor, alpha, *pixelPtr);
+			}
+		pixelPtr += pixelPtrInc;
+		}
+	return KErrNone;
+	}