graphicsdeviceinterface/bitgdi/tbit/TAlphaBlend.cpp
changeset 0 5d03bc08d59c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicsdeviceinterface/bitgdi/tbit/TAlphaBlend.cpp	Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,1038 @@
+// Copyright (c) 2004-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 <hal.h>
+#include <e32math.h>
+#include "TAlphaBlend.h"
+
+
+const TInt KWidth = 10;//Used in alpha blending tests
+const TInt KHeight = 3;//Used in alpha blending tests
+const TInt KMaximumAttempts = 2;	// Allow retries on some tests, due to spurious InfoPrints 
+TBool iExtraLogging1=EFalse;		//Used to trigger logging at times the test fails
+TBool iExtraLogging2=EFalse;		//Used to trigger logging at times the test fails
+
+CTAlphaBlending::CTAlphaBlending(CTestStep* aStep):
+	CTGraphicsBase(aStep),
+	iDevice(NULL),
+	iGc(NULL)
+	{
+	}
+
+CTAlphaBlending::~CTAlphaBlending()
+	{
+	DeleteGraphicsContext();
+	DeleteScreenDevice();
+	}
+
+void CTAlphaBlending::RunTestCaseL(TInt aCurTestCase)
+	{
+	((CTAlphaBlendingStep*)iStep)->SetTestStepID(KUnknownSYMTestCaseIDName);
+	switch(aCurTestCase)
+		{
+	case 1:
+		((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0024"));
+		INFO_PRINTF1(_L("Alpha blending"));
+		TestAlphaBlendingL();
+		break;		
+	case 2:
+/**
+@SYMTestCaseID		GRAPHICS-BITGDI-0114
+*/
+		((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0114"));
+		INFO_PRINTF1(_L("Alpha blending 2"));
+		TestAlphaBlending2L();
+		break;
+	case 3:
+		((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0085"));
+ 		INFO_PRINTF1(_L("Alpha blending Correctness test 16MU 16MA"));
+ 		TestAlphaBlendCorrect(EColor16MU, EColor16MU);
+ 		break;
+ 	case 4:
+ 		((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0097"));
+ 		INFO_PRINTF1(_L("Alpha plot test"));
+		TestAlphaBlendingPlotL();
+		break;
+	case 5:
+/**
+@SYMTestCaseID		GRAPHICS-BITGDI-0115
+*/
+		((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0115"));
+		INFO_PRINTF1(_L("Draw bitmap blending"));
+		DoDrawBitmapTestsL();
+		break;
+	case 6:
+		//DEF118268
+		((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0085"));
+		INFO_PRINTF1(_L("Alpha blending Correctness test 16M 16MA"));
+		TestAlphaBlendCorrect(EColor16M, EColor16MA);
+		break;
+	case 7:
+		((CTAlphaBlendingStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName);
+		((CTAlphaBlendingStep*)iStep)->CloseTMSGraphicsStep();
+		TestComplete();
+		break;
+		}
+	((CTAlphaBlendingStep*)iStep)->RecordTestResultL();
+	}
+
+TInt CTAlphaBlending::CreateScreenDevice(TDisplayMode aDisplayMode, CFbsBitGc::TGraphicsOrientation aOrientation)
+	{
+	DeleteGraphicsContext();
+	DeleteScreenDevice();
+	TRAPD(err, iDevice = CFbsScreenDevice::NewL(_L("scdv"), aDisplayMode));
+	if(err == KErrNotSupported)
+		{
+		return err;
+		}
+	TEST2(err, KErrNone);
+	err = iDevice->CreateContext((CGraphicsContext*&)iGc);
+	TEST2(err, KErrNone);
+	if (!iGc->SetOrientation(aOrientation))
+		{
+		return(KErrNotSupported);
+		}
+	iGc->SetUserDisplayMode(aDisplayMode);
+	iDevice->ChangeScreenDevice(NULL);
+	iDevice->SetAutoUpdate(EFalse);
+	return err;
+	}
+
+void CTAlphaBlending::DeleteScreenDevice()
+	{
+	delete iDevice;
+	iDevice = NULL;
+	}
+
+void CTAlphaBlending::DeleteGraphicsContext()
+	{
+	delete iGc;
+	iGc = NULL;
+	}
+
+// returns the pixel colour from the provided bitmap in aarrggbb format
+// if pixel is outside the bitmaps limits return top left pixel
+TUint32 CTAlphaBlending::GetRawPixel(CFbsBitmap* aBitmap, TPoint aPos)
+	{
+	TBitmapUtil bmpUtil(aBitmap);	
+	TUint32 value = 0;
+	ASSERT(aPos.iX>=0 && aPos.iY>=0);
+	ASSERT(aPos.iX<aBitmap->SizeInPixels().iWidth && aPos.iY<aBitmap->SizeInPixels().iHeight);
+	bmpUtil.Begin(aPos);
+	value = bmpUtil.GetPixel();
+	bmpUtil.End();
+	return value;	
+	}
+
+/**
+@SYMTestCaseID		GRAPHICS-BITGDI-0097
+
+@SYMDEF             DEF113229
+
+@SYMTestCaseDesc    CDrawThirtyTwoBppBitmapCommon::WriteRgb did not change the dest alpha value to 255 when 
+					the dest alpha was >0 and <255 and the a soure pen had an alpha of 255	
+
+@SYMTestPriority    Normal
+
+@SYMTestStatus      Implemented
+
+@SYMTestActions     Creates a bitmap, clears it to black (destination) 50% opaque then plots a series of points 
+					with a 100% opaque pen on it. Tests the resultant alpha value.
+
+@SYMTestExpectedResults Final alpha value should be 255
+**/
+void CTAlphaBlending::TestAlphaBlendingPlotL()
+	{
+	const TSize KRectSize(100,100);
+	const TRect KTargetRect(TPoint(0,0), KRectSize);
+		
+	// create the target bitmap
+	CFbsBitmap* destBmp = new (ELeave) CFbsBitmap;
+	CleanupStack::PushL(destBmp);
+	User::LeaveIfError(destBmp->Create(KRectSize, EColor16MA));
+	destBmp->SetSizeInTwips(KRectSize);
+	
+	// create bitmap device and graphics context
+	CFbsBitmapDevice* destBmpDevice = CFbsBitmapDevice::NewL(destBmp);
+	CleanupStack::PushL(destBmpDevice);
+	CFbsBitGc* destGc = NULL;
+	User::LeaveIfError(destBmpDevice->CreateContext(destGc));
+	CleanupStack::PushL(destGc);
+	destGc->SetPenStyle(CGraphicsContext::ENullPen);
+	destGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
+		
+	TDisplayMode screenMode = EColor16MA;
+	TInt err = CreateScreenDevice(screenMode);
+	if (err != KErrNone)
+		{
+		screenMode = EColor64K;
+		err = CreateScreenDevice(screenMode);
+		}
+	
+	if(err==KErrNone)
+		{
+		const TInt KSqrMin=45;
+		const TInt KSqrMax=55;
+						
+		iGc->SetUserDisplayMode(screenMode);
+		destGc->SetBrushColor(TRgb(0,0,0,127));
+		destGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
+		destGc->Clear(KTargetRect);
+
+		// copy over to screen dc for anyone watching
+		iGc->BitBlt(TPoint(0,0), destBmp, KTargetRect);
+		iDevice->Update();
+		
+		// set the pen colour to white and plot some points
+		destGc->SetDrawMode(CGraphicsContext::EDrawModePEN);
+		destGc->SetPenStyle(CGraphicsContext::ESolidPen);
+		destGc->SetPenColor(TRgb(0,70,130,255));
+		for( TInt y=KSqrMin;y<=KSqrMax;y++)
+			{
+			for( TInt x=KSqrMin;x<=KSqrMax;x++)
+				{
+				destGc->Plot(TPoint(x,y));
+				}
+			}
+			
+		// copy over to screen dc for anyone watching
+		iGc->BitBlt(TPoint(0,0), destBmp, KTargetRect);
+		iDevice->Update();
+		
+		TUint32 actualValue=0;
+		// check the resulting values alpha values are 0xFF in the square we drew
+		for( TInt y=KSqrMin;y<=KSqrMax;y++)
+			{
+			for( TInt x=KSqrMin;x<=KSqrMax;x++)
+				{
+				actualValue = GetRawPixel(destBmp, TPoint(x,y));
+				if( (actualValue&0xFF000000) != 0xFF000000 )
+					{
+					TEST(EFalse);
+					INFO_PRINTF2(_L("TestAlphaBlendingPlotL() ***FAILED*** - expected alpha value 0xFF got %d "),((actualValue&0xFF000000)>>24));
+					}
+				}
+			}
+		}
+		CleanupStack::PopAndDestroy(3); //destGc,destBmpDevice,destBmp
+	}
+
+/**
+  @SYMTestCaseID GRAPHICS-BITGDI-0024
+ 
+  @SYMDEF             
+
+  @SYMTestCaseDesc 
+   
+	System, GT0173 System Libraries, BITGDI support required for semi-transparent windows
+	DEF039083 - Using BitBltMasked to do alpha-blending only works if your brush style is "null"
+	DEF039409 - Wrong part of Alpha Bitmap is used when there is a clipping region 
+	DEF039669 - The UserDisplayMode is not honoured during the AlphaBlendBitmap function. 
+	REQ3413 Second overload of CFbsBitGc's AlphaBlendBitmaps - "Supply a second overload of 
+	CFbsBitGc's AlphaBlendBitmaps function, but with one of the source bitmaps being passed 
+	as a CFbsBitGc object, so that the screen can be used as a source."
+
+  @SYMTestPriority High
+
+  @SYMTestStatus Implemented
+
+  @SYMTestActions 
+  	
+  	Tests alpha blending - for all display modes, some brush styles, user display modes, 
+	different positions on the screen.
+  
+	Shadow/fade mode is no more tested, because the existing BitBltMasked() and the new 
+	AlphaBlendBitmaps() methods treat it a different way - see MAlphaBlend interface in
+	ScreenDriver component.
+
+  @SYMTestExpectedResults Test should perform graphics operations succesfully. 
+*/
+
+void CTAlphaBlending::TestAlphaBlendingL()
+	{
+	TPoint originPt(0, 0);
+	TPoint destPt(0, 0);
+	TRect scrRc1(0, 0, KWidth, KHeight);
+	TPoint srcPt2(0, 0);
+	TPoint alphaPt(0, 0);
+	//
+	//If we compare CFbsBitGc::BitBltMasked() aguments with CFbsBitGc::AlphaBlending() arguments,
+	//we will see that AlphaBlending() has more arguments than BitBltMasked() - 
+	//srcPt2, alphaPt. To make it possible - the comparison between these two methods,
+	//we have to change aAlphaPt and aSrcPt2 values accordingly with the changes of scrRc1 value.
+	//
+	//test 1 - the origin is moved
+	originPt = TPoint(97, 33);
+	DoAlphaBlendingTestsL(originPt, destPt, scrRc1, srcPt2, alphaPt);
+#if !defined(__X86GCC__)	//These test take too long to run in X86GCC
+	//test 2 - the origin is (0, 0)
+	originPt = TPoint(0, 0);
+	DoAlphaBlendingTestsL(originPt, destPt, scrRc1, srcPt2, alphaPt);
+	//test 3 - scrRect1 is not (0, 0, KWidth, KHeight)
+	scrRc1 = TRect(3, 1, KWidth, KHeight);
+	alphaPt = TPoint(3, 1);
+	DoAlphaBlendingTestsL(originPt, destPt, scrRc1, srcPt2, alphaPt);
+	//test 4 - restore scrRc1 and alphaPt, move the destination point
+	scrRc1 = TRect(0, 0, KWidth, KHeight);
+	alphaPt = TPoint(0, 0);
+	destPt = TPoint(13, 17);
+	iExtraLogging1=ETrue;
+	DoAlphaBlendingTestsL(originPt, destPt, scrRc1, srcPt2, alphaPt);
+	iExtraLogging1=EFalse;
+#endif	//__X86GCC__
+	}
+
+void CTAlphaBlending::DoDrawBitmapTestsL()
+	{
+	TDisplayMode modes[] = {EColor16MA, EColor16MAP, EColor16MU, EColor16M, EColor256, EColor4K, EColor64K, 
+						   EGray256, EGray16, EGray4, EGray2, EColor16};
+	const TInt KNumTestDisplayModes=sizeof(modes)/sizeof(modes[0]);
+	for(TInt modeIndex=0;modeIndex<KNumTestDisplayModes;modeIndex++)
+		{
+		TDisplayMode screenMode=modes[modeIndex];
+		if (CreateScreenDevice(screenMode)!=KErrNone)
+			continue;
+		DoDrawBitmapTestL(screenMode);
+		}
+	}
+
+void CTAlphaBlending::DoDrawBitmapTestL(TDisplayMode aTestDisplayMode)
+	{
+	iGc->Reset();
+	TBool alphaSupported=(aTestDisplayMode==EColor16MA || aTestDisplayMode==EColor16MAP);
+	TSize screenSize=iDevice->SizeInPixels();
+//
+	const TInt KNumTestSrcSizes=4;
+	const TSize testSrcSizes[KNumTestSrcSizes]={TSize(2,2),TSize(20,10),TSize(200,5),TSize(55,555)};
+	for(TInt srcSizeIndex=0;srcSizeIndex<KNumTestSrcSizes;srcSizeIndex++)
+		{
+		TSize srcSize(testSrcSizes[srcSizeIndex]);
+//
+		CFbsBitmap* srcBmp=new(ELeave) CFbsBitmap;
+		CleanupStack::PushL(srcBmp);
+		User::LeaveIfError(srcBmp->Create(srcSize,aTestDisplayMode));
+		CFbsBitmapDevice* srcDevice = CFbsBitmapDevice::NewL(srcBmp);
+		CleanupStack::PushL(srcDevice);
+		CFbsBitGc* srcGc=NULL;
+		User::LeaveIfError(srcDevice->CreateContext(srcGc));
+		CleanupStack::PushL(srcGc);
+//
+		CFbsBitmap* srcAlpha=new(ELeave) CFbsBitmap;
+		CleanupStack::PushL(srcAlpha);
+		User::LeaveIfError(srcAlpha->Create(srcSize,aTestDisplayMode));
+		CFbsBitmapDevice* srcAlphaDevice = CFbsBitmapDevice::NewL(srcAlpha);
+		CleanupStack::PushL(srcAlphaDevice);
+		CFbsBitGc* srcAlphaGc=NULL;
+		User::LeaveIfError(srcAlphaDevice->CreateContext(srcAlphaGc));
+		CleanupStack::PushL(srcAlphaGc);
+		srcAlphaGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
+//
+		CFbsBitmap* srcMask=new(ELeave) CFbsBitmap;
+		CleanupStack::PushL(srcMask);
+		User::LeaveIfError(srcMask->Create(srcSize,EGray256));
+		CFbsBitmapDevice* srcMaskDevice = CFbsBitmapDevice::NewL(srcMask);
+		CleanupStack::PushL(srcMaskDevice);
+		CFbsBitGc* srcMaskGc=NULL;
+		User::LeaveIfError(srcMaskDevice->CreateContext(srcMaskGc));
+		CleanupStack::PushL(srcMaskGc);
+//
+		TInt maxX=srcSize.iWidth-1;
+		TInt maxY=srcSize.iHeight-1;
+		for(TInt yLoop=0;yLoop<srcSize.iHeight;yLoop++)
+			{
+			for(TInt xLoop=0;xLoop<srcSize.iWidth;xLoop++)
+				{
+				TPoint plotPos(xLoop,yLoop);
+				TRgb pen(xLoop*255/maxX,yLoop*255/maxY,(xLoop+yLoop)*128/(maxX+maxY));
+				srcGc->SetPenColor(pen);
+				srcGc->Plot(plotPos);
+				TInt alpha=(xLoop+yLoop)*255/(maxX+maxY);
+				pen.SetAlpha(alpha);
+				srcAlphaGc->SetBrushColor(pen);
+				srcAlphaGc->Clear(TRect(plotPos,TSize(1,1)));
+				srcMaskGc->SetPenColor(TRgb::Gray256(alpha));
+				srcMaskGc->Plot(plotPos);
+				}
+			}
+		const TInt KNumTestTargSizes=5;
+		const TSize testTargSizes[KNumTestTargSizes]={TSize(0,0), TSize(20,1),TSize(30,20),TSize(200,31),TSize(55,5)};
+		for(TInt targSizeIndex=0;targSizeIndex<KNumTestSrcSizes;targSizeIndex++)
+			{
+			TSize targSize(testTargSizes[targSizeIndex]);
+			if (targSizeIndex==0)
+				{
+				targSize=srcSize;	// Special case with no scaling
+				if (targSize.iWidth>screenSize.iWidth)
+					targSize.iWidth=screenSize.iWidth;
+				TInt maxHeight=screenSize.iHeight/3;
+				if (targSize.iHeight>maxHeight)
+					targSize.iHeight=maxHeight;
+				}
+//
+			CFbsBitmap* targBmp=new(ELeave) CFbsBitmap;
+			CleanupStack::PushL(targBmp);
+			User::LeaveIfError(targBmp->Create(targSize,aTestDisplayMode));
+			CFbsBitmapDevice* targBmpDevice = CFbsBitmapDevice::NewL(targBmp);
+			CleanupStack::PushL(targBmpDevice);
+			CFbsBitGc* targGc=NULL;
+			User::LeaveIfError(targBmpDevice->CreateContext(targGc));
+			CleanupStack::PushL(targGc);
+//
+			CFbsBitmap* targMask=new(ELeave) CFbsBitmap;
+			CleanupStack::PushL(targMask);
+			User::LeaveIfError(targMask->Create(targSize,EGray256));
+			CFbsBitmapDevice* targMaskDevice = CFbsBitmapDevice::NewL(targMask);
+			CleanupStack::PushL(targMaskDevice);
+			CFbsBitGc* targMaskGc=NULL;
+			User::LeaveIfError(targMaskDevice->CreateContext(targMaskGc));
+			CleanupStack::PushL(targMaskGc);
+//
+			TPoint drawPos;
+			TRect testRect1(targSize);
+			iGc->Clear();
+// First we pre-stretch the source and mask bitmaps into temp bitmaps
+			targGc->DrawBitmap(TRect(targSize),srcBmp);
+			targMaskGc->DrawBitmap(TRect(targSize),srcMask);
+// Then blend them onto the screen with a call to BitBltMasked
+			iGc->BitBltMasked(drawPos,targBmp,TRect(targSize),targMask,EFalse);
+			drawPos.iY+=targSize.iHeight;
+			TRect testRect2(drawPos,targSize);
+// Next we combine the stretching and masking with one call to DrawBitmapMasked,
+// this should give the same end result.
+			iGc->DrawBitmapMasked(testRect2,srcBmp,TRect(srcSize),srcMask,EFalse);
+			TRect testRect3;
+			if (alphaSupported)
+				{
+// Finally if alpha blending supported we stretch and blend, again to achieve the exact same end result
+// as the two previous calls. This was specificially done to catch DEF116427.
+				drawPos.iY+=targSize.iHeight;
+				testRect3=TRect(drawPos,targSize);
+				iGc->DrawBitmap(testRect3,srcAlpha);
+				}
+//Use this just to check what we've put in the test bitmaps
+/*
+			drawPos.iY+=targSize.iHeight+1;
+			iGc->BitBlt(drawPos,srcBmp);
+			drawPos.iY+=srcSize.iHeight+1;
+			iGc->BitBlt(drawPos,srcMask);
+			drawPos.iY+=srcSize.iHeight+1;
+			if (alphaSupported)
+				iGc->BitBlt(drawPos,srcAlpha);
+*/
+		   	iDevice->Update();
+			TBool ret1=iDevice->RectCompare(testRect1,*iDevice,testRect2);
+		   	TBool ret2=alphaSupported?iDevice->RectCompare(testRect1,*iDevice,testRect3):ETrue;
+			if (!ret1 || !ret2)
+				{
+				INFO_PRINTF4(_L("DrawBitmapTest, ret1=%d, ret2=%d, Screen mode=%d"),ret1,ret2,aTestDisplayMode);
+				TEST(EFalse);
+				}
+			CleanupStack::PopAndDestroy(3,targMask);
+			CleanupStack::PopAndDestroy(3,targBmp);
+			}
+		CleanupStack::PopAndDestroy(3,srcMask);
+		CleanupStack::PopAndDestroy(3,srcAlpha);
+		CleanupStack::PopAndDestroy(3,srcBmp);
+		}
+	}
+
+//Tests alpha blending - for all display modes, some brush styles, user display modes, 
+//different positions on the screen.
+void CTAlphaBlending::DoAlphaBlendingTestsL(const TPoint& aOrigin,
+										const TPoint& aDestPt, 
+										const TRect& aSrcRc1, 
+										const TPoint& aScrPt2,
+										const TPoint& aAlphaPt)
+	{
+	TBuf<128> buf;
+	_LIT(KLog,"Origin=(%d,%d) DestPt=(%d,%d) SrcRect=(%d,%d,%d,%d) ScrPt=(%d,%d) AlphaPt=(%d,%d)");
+	buf.Format(KLog,aOrigin.iX,aOrigin.iY,aDestPt.iX,aDestPt.iY,aSrcRc1.iTl.iX,aSrcRc1.iTl.iY
+						,aSrcRc1.iBr.iX,aSrcRc1.iBr.iY,aScrPt2.iX,aScrPt2.iY,aAlphaPt.iX,aAlphaPt.iY);
+	INFO_PRINTF1(buf);
+	TDisplayMode mode[] = {EColor16MA, EColor16MAP, EColor16MU, EColor16M, EColor256, EColor4K, EColor64K,
+						   EGray256, EGray16, EGray4, EGray2, EColor16};
+	CFbsBitmap* screenBmp = NULL;
+	CFbsBitmap* srcBmp = NULL;
+	CFbsBitmap* alphaBmp = NULL;
+	CGraphicsContext::TBrushStyle brushStyle[] = {CGraphicsContext::ENullBrush, CGraphicsContext::ESolidBrush};
+	for(TInt i=0;i<TInt(sizeof(mode)/sizeof(mode[0]));i++)
+		{
+		for(TInt orientation=0;orientation<=CFbsBitGc::EGraphicsOrientationRotated270;orientation++)
+			{
+			if (CreateScreenDevice(mode[i],(CFbsBitGc::TGraphicsOrientation)orientation) != KErrNone)
+				{
+				continue;
+				}
+			iExtraLogging2=(iExtraLogging1 && mode[i]==11);
+	 		INFO_PRINTF3(_L("Mode=%d, Orientation=%d"), mode[i], orientation);
+			CreateAlphaBlendingBitmapsLC(screenBmp, srcBmp, alphaBmp, mode[i]);
+			for(TInt j=0;j<TInt(sizeof(brushStyle)/sizeof(brushStyle[0]));j++)
+				{
+				if(mode[i] == EGray4 && brushStyle[j] == CGraphicsContext::ESolidBrush)
+					{
+					//When the display mode is EGray4 - Flicker-free blitting is not enabled.
+					//The screen will be filled with 0xFF color, which is not the same color used by
+					//the test - 0x00. And BitBltMasked and AlphaBlendBitmaps will produce different results.
+					continue;
+					}
+				iGc->SetOrigin(aOrigin);
+				iGc->SetBrushStyle(brushStyle[j]);
+				TDisplayMode userDisplayMode[] = {EColor16MA, EColor16MAP, EColor16MU, EColor16M, EColor256, 
+												  EColor4K, EColor64K, EGray256, 
+												  EGray16, EGray4, EGray2, EColor16};
+				for(TInt l=0;l<TInt(sizeof(userDisplayMode)/sizeof(userDisplayMode[0]));l++)
+					{
+					iGc->SetUserDisplayMode(userDisplayMode[l]);
+					TSize scrDevSize = iDevice->SizeInPixels();
+					TRect clipRc[] = {TRect(0, 0, scrDevSize.iWidth, scrDevSize.iHeight),
+										TRect(0, 1, scrDevSize.iWidth, scrDevSize.iHeight), // Tests Y clipping only
+										TRect(5, 0, scrDevSize.iWidth, scrDevSize.iHeight), // Tests X clipping only
+										TRect(5, 1, scrDevSize.iWidth, scrDevSize.iHeight),
+										TRect(3, 0, 14, 23)};//14 and 23 values are not accidental! 
+															 //Sometimes the method is called with aDestPt(13, 17).
+					for(TInt k=0;k<TInt(sizeof(clipRc)/sizeof(clipRc[0]));k++)
+						{
+						if (iExtraLogging2)
+							{
+							_LIT(KLog,"  BrushStyle=%d UserDisplayMode=%d ClipRect=(%d,%d,%d,%d)");
+			 				INFO_PRINTF7(KLog,j,l,clipRc[k].iTl.iX,clipRc[k].iTl.iY,clipRc[k].iBr.iX,clipRc[k].iBr.iY);
+							}
+						iGc->Clear();
+						iGc->SetClippingRect(clipRc[k]);
+						DoAlphaBlendingTestL(screenBmp, srcBmp, alphaBmp, aDestPt, aSrcRc1, aScrPt2, aAlphaPt);
+						iGc->CancelClippingRect();
+						}
+					}//end of - for(TInt l=0;l<TInt(sizeof(userDisplayMode)/sizeof(userDisplayMode[0]));l++)
+				iGc->SetOrientation(CFbsBitGc::EGraphicsOrientationNormal);
+				}
+			DestroyAlphaBlendingBitmaps(screenBmp, srcBmp, alphaBmp);
+			}//end of - for(TInt j=0;j<TInt(sizeof(brushStyle)/sizeof(brushStyle[0]));j++)
+		}//end of - for(TInt i=0;i<TInt(sizeof(mode)/sizeof(mode[0]));i++)
+	}
+
+//The method compares results of two alpha blending methods:
+//iGc->BitBltMasked() and iGc->AlphaBlendBitmaps().
+//To make that possible, aScreenBmp is copied to the screen before the call of
+//iGc->BitBltMasked().
+void CTAlphaBlending::DoAlphaBlendingTestL(CFbsBitmap* aScreenBmp, 
+									   const CFbsBitmap* aSrcBmp, 
+									   const CFbsBitmap* aAlphaBmp,
+									   const TPoint& aDestPt, 
+									   const TRect& aSrcRc1, 
+									   const TPoint& aSrcPt2,
+									   const TPoint& aAlphaPt)
+	{
+	_LIT(KScreenBmpFile, "C:\\BMP_DATA.DAT");
+	iGc->SetShadowMode(EFalse);
+   	TInt i;
+   	TInt res = -1;
+	TSize scrDevSize = iDevice->SizeInPixels();
+	TInt allocatedSize = scrDevSize.iWidth * scrDevSize.iHeight * 2;
+	TRect screenBmpRc;
+   	//The screen alpha blended data after calling of BitBltMasked() - will be filled after the call
+	TUint8* screenBmpDestData1 = new (ELeave) TUint8[allocatedSize];
+	CleanupStack::PushL(screenBmpDestData1);
+   	//The screen alpha blended data after calling of AlphaBlendingBitmaps() - will be filled after the call
+	TUint8* screenBmpDestData2 = new (ELeave) TUint8[allocatedSize];
+	CleanupStack::PushL(screenBmpDestData2);
+	// Allow an effective restart of the test, since sometimes there are spurious
+	// InfoPrints that affect the comparisons.
+	for (TInt attempt = 0; res && (attempt < KMaximumAttempts); attempt++)
+		{
+		//Fill the blocks with some default value
+		Mem::Fill(screenBmpDestData1, allocatedSize, 0xCA);
+		Mem::Fill(screenBmpDestData2, allocatedSize, 0xCA);
+	   	//Check screen bitmap size
+	   	TSize screenBmpSize = aScreenBmp->SizeInPixels();
+	   	if ((screenBmpSize.iWidth != KWidth) || (screenBmpSize.iHeight != KHeight))
+	   		{
+	   		_LIT(KScreenErr,"DoAlphaBlendingTestL test: w:%d!=%d || h:%d!=%d");
+	   		INFO_PRINTF5(KScreenErr, screenBmpSize.iWidth, KWidth, screenBmpSize.iHeight, KHeight);
+	   		TEST(EFalse);
+	   		}
+		//  Alpha blending using CFbsBitGc::BitBltMasked  //
+		if (iExtraLogging2)
+			{
+			_LIT(KLog1,"    CFbsBitGc::BitBltMasked test");
+			INFO_PRINTF1(KLog1);
+			}
+		//Screen bitmap rectangle
+		screenBmpRc.SetRect(aDestPt, TSize(aSrcRc1.Width(), aSrcRc1.Height()));
+		
+		//Save screen bitmap 
+		TInt saveAttempts = 5;
+		TInt err = aScreenBmp->Save(KScreenBmpFile);
+		while ((err != KErrNone) && saveAttempts--)
+			{
+			// Retry the save
+			_LIT(KSaveRetry,"DoAlphaBlendingTestL: Bitmap save failed, retrying.");
+			INFO_PRINTF1(KSaveRetry);
+			User::After(10000); 
+			err = aScreenBmp->Save(KScreenBmpFile);
+			}
+		User::LeaveIfError(err);
+		
+		User::LeaveIfError(aScreenBmp->Resize(TSize(aSrcRc1.Width(), aSrcRc1.Height())));
+		//Draw screen bitmap
+	   	iGc->Clear();
+		iGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
+		iGc->DrawBitmap(screenBmpRc, aScreenBmp);
+	   	iDevice->Update();
+	   	//Do BitBltMasked()
+	   	iGc->BitBltMasked(aDestPt, aSrcBmp, aSrcRc1, aAlphaBmp, EFalse);
+	   	iDevice->Update();
+		//Get screen data and write the data to screenBmpDestData1.
+		for(i=0;i<scrDevSize.iHeight;i++)
+	   		{
+			TPtr8 p(screenBmpDestData1 + i * scrDevSize.iWidth * 2, scrDevSize.iWidth * 2, scrDevSize.iWidth * 2);
+			iDevice->GetScanLine(p, TPoint(0, i), scrDevSize.iWidth, EColor64K);
+	   		}
+		//  Alpha blending using explicit form of CFbsBitGc::AlphaBlendBitmaps  //
+		if (iExtraLogging2)
+			{
+			_LIT(KLog2,"    CFbsBitGc::AlphaBlendBitmaps explicit test");
+			INFO_PRINTF1(KLog2); 
+			}
+		//Clear screen
+	   	iGc->Clear();
+	   	iDevice->Update();
+		//Load screen bitmap 
+		User::LeaveIfError(aScreenBmp->Load(KScreenBmpFile));
+	   	//Do AlphaBlendBitmaps()
+	   	User::LeaveIfError(iGc->AlphaBlendBitmaps(aDestPt, aSrcBmp, aScreenBmp, aSrcRc1, 
+													aSrcPt2, aAlphaBmp, aAlphaPt));
+	   	iDevice->Update();
+		//Get screen data and write the data to screenBmpDestData2.
+		for(i=0;i<scrDevSize.iHeight;i++)
+	   		{
+			TPtr8 p(screenBmpDestData2 + i * scrDevSize.iWidth * 2, scrDevSize.iWidth * 2, scrDevSize.iWidth * 2);
+			iDevice->GetScanLine(p, TPoint(0, i), scrDevSize.iWidth, EColor64K);
+	   		}
+		//Compare screen bitmaps //
+		res = Mem::Compare(screenBmpDestData1, allocatedSize, screenBmpDestData2, allocatedSize);
+
+		// colour comparison tolerance between RGB565 components.
+		const TInt KColourComparisonTolerance = 2;
+		if (res)
+			{
+			TBool testPassed = ETrue;
+			// strict byte-for-byte comparison of the pixel maps could have failed because blending algorithms may  
+			// differ slightly, but actual resulting colours may be close enough
+			for (int byteNumber = 0; byteNumber < allocatedSize; byteNumber+=2)
+				{
+				// find any RGB565 value that doesn't match and examine each component
+				if ( *(TUint16*)(screenBmpDestData1 + byteNumber) != *(TUint16*)(screenBmpDestData2 + byteNumber))
+					{
+					TUint16 Rgb1 = *(TUint16*)(screenBmpDestData1 + byteNumber);
+					TUint16 Rgb2 = *(TUint16*)(screenBmpDestData2 + byteNumber);
+					
+					TInt16 Red1 = (Rgb1 & 0xF800) >> 11;
+					TInt16 Red2 = (Rgb2 & 0xF800) >> 11;
+					TInt16 DiffRed = Abs(Red1 - Red2);
+					
+					TInt16 Green1 = (Rgb1 & 0x07E0) >> 5;
+					TInt16 Green2 = (Rgb2 & 0x07E0) >> 5;
+					TInt16 DiffGreen = Abs(Green1 - Green2);
+					
+					TInt16 Blue1 = (Rgb1 & 0x001F);
+					TInt16 Blue2 = (Rgb2 & 0x001F);
+					TInt16 DiffBlue = Abs(Blue1 - Blue2);
+					
+					// is any difference is outside the tolerance break out signaling test failure
+					if (DiffRed > KColourComparisonTolerance || 
+						DiffGreen > KColourComparisonTolerance || 
+						DiffBlue > KColourComparisonTolerance)
+						{
+						testPassed = EFalse;
+						break;
+						}
+					}
+				}
+			if (testPassed)
+				{
+				res = 0;
+				}
+			}
+		
+		if (res && (attempt < KMaximumAttempts - 1))
+			{
+			INFO_PRINTF1(_L("Memory comparison 1 failed, retrying"));
+			// Skip to next attempt
+			continue;
+			}
+		TEST(res == 0);
+
+		//  Alpha blending using implicit form of CFbsBitGc::AlphaBlendBitmaps  //
+		if (iExtraLogging2)
+			{
+			_LIT(KLog3,"    CFbsBitGc::AlphaBlendBitmaps implicit test");
+			INFO_PRINTF1(KLog3);
+			}
+		//Clear screen
+	   	iGc->Clear();
+	   	iDevice->Update();
+		//Draw screen bitmap (it's already loaded)
+		User::LeaveIfError(aScreenBmp->Resize(TSize(aSrcRc1.Width(), aSrcRc1.Height())));
+		iGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
+		iGc->DrawBitmap(screenBmpRc, aScreenBmp);
+	   	iDevice->Update();
+	   	//Do AlphaBlendBitmaps()
+	   	User::LeaveIfError(iGc->AlphaBlendBitmaps(aDestPt, aSrcBmp, aSrcRc1, aAlphaBmp, aSrcRc1.iTl));
+	   	iDevice->Update();
+		//Get screen data and write the data to screenBmpDestData2.
+		for(i=0;i<scrDevSize.iHeight;i++)
+	   		{
+			TPtr8 p(screenBmpDestData2 + i * scrDevSize.iWidth * 2, scrDevSize.iWidth * 2, scrDevSize.iWidth * 2);
+			iDevice->GetScanLine(p, TPoint(0, i), scrDevSize.iWidth, EColor64K);
+	   		}
+		//Compare screen bitmaps //
+		if (iExtraLogging2)
+			{
+			_LIT(KLog4,"    Compare Screen Bitmaps");
+			INFO_PRINTF1(KLog4);
+			}
+		res = Mem::Compare(screenBmpDestData1, allocatedSize, screenBmpDestData2, allocatedSize);
+
+		if (res && (attempt < KMaximumAttempts - 1))
+			{
+			INFO_PRINTF1(_L("Memory comparison 2 failed, retrying"));
+			}
+		
+		// Reload the screen bitmap as it was before:
+		User::LeaveIfError(aScreenBmp->Load(KScreenBmpFile));
+		}
+	TEST(res == 0);
+	
+	//Destroy the allocated memory blocks
+	CleanupStack::PopAndDestroy(2);//screenBmpDestData1 & screenBmpDestData2
+	}
+
+void CTAlphaBlending::CreateAlphaBlendingBitmapsLC(CFbsBitmap*& aScreenBmp, 
+											   CFbsBitmap*& aSrcBmp, 
+											   CFbsBitmap*& aAlphaBmp,
+											   TDisplayMode aMode)
+	{
+	TInt i;
+	TSize size(KWidth, KHeight);
+	//The screen data
+	TUint8 screenBmpSrcData[KHeight][KWidth * 3 + 2] = // "+ 2" - every row is aligned to a 32 bit boundary
+		{//0               1                 2                 3                 4                 5                 6                 7                 8                 9     
+		{0x00, 0x00, 0x00, 0x20, 0x21, 0x22, 0x30, 0x31, 0x32, 0x40, 0x41, 0x42, 0x50, 0x51, 0x51, 0x60, 0x61, 0x62, 0x70, 0x71, 0x72, 0x80, 0x81, 0x82, 0x90, 0x91, 0x92, 0xA0, 0xA1, 0xA2, 0x00, 0x00},
+		{0x19, 0x18, 0x17, 0x29, 0x28, 0x27, 0x39, 0x38, 0x37, 0x49, 0x48, 0x47, 0x59, 0x58, 0x57, 0x69, 0x68, 0x67, 0x79, 0x78, 0x77, 0x89, 0x88, 0x87, 0x99, 0x98, 0x97, 0xA9, 0xA8, 0xA7, 0x00, 0x00},
+		{0x1F, 0x1E, 0x1D, 0x2F, 0x2E, 0x2D, 0x3F, 0x3E, 0x3D, 0x4F, 0x4E, 0x4D, 0x5F, 0x5E, 0x5D, 0x6F, 0x6E, 0x6D, 0x7F, 0x7E, 0x7D, 0x8F, 0x8E, 0x8D, 0x9F, 0x9E, 0x9D, 0xAF, 0xAE, 0xAD, 0x00, 0x00}
+		};
+	//The source bitmap data
+	TUint8 srcBmpData[KHeight][KWidth * 3 + 2] = // "+ 2" - every row is aligned to a 32 bit boundary
+		{//0               1                 2                 3                 4                 5                 6                 7                 8                 9     
+		{0x32, 0x67, 0xA2, 0x11, 0x34, 0x67, 0xC5, 0xA3, 0x91, 0x01, 0xB3, 0xA8, 0xF3, 0x3F, 0x1E, 0x88, 0x11, 0x12, 0xAE, 0xEE, 0x9A, 0x56, 0x12, 0x81, 0xB4, 0xCA, 0x91, 0xFF, 0x1A, 0x2A, 0x00, 0x00},
+		{0x02, 0xB1, 0xE2, 0xAA, 0xBB, 0x13, 0x22, 0xA8, 0xC3, 0x75, 0x8D, 0xFF, 0xA4, 0xAB, 0x00, 0xC5, 0xA6, 0x22, 0xBB, 0x09, 0xC1, 0x97, 0x25, 0xC6, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x00, 0x00},
+		{0x32, 0x50, 0x76, 0x27, 0xCC, 0x45, 0x81, 0xE5, 0xE9, 0xB7, 0xCD, 0x11, 0x32, 0xB1, 0x23, 0xFF, 0x71, 0x11, 0xCC, 0xAA, 0xF2, 0x98, 0x13, 0x8C, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, 0x00}
+		};
+	//The alpha bitmap data
+	TUint8 alphaBmpData[KHeight][KWidth + 2] = // "+ 2" - every row is aligned to a 32 bit boundary
+		{//0   1     2     3     4     5     6     7     8     9     
+		{0x68, 0x68, 0x68, 0xAC, 0xD9, 0xB2, 0x8F, 0x11, 0xA0, 0xC1, 0x00, 0x00},
+		{0x71, 0x5A, 0xF6, 0xEE, 0xF9, 0xE5, 0x06, 0x4C, 0xBB, 0x7B, 0x00, 0x00},
+		{0x9F, 0x99, 0x45, 0x17, 0xA8, 0xF5, 0xFF, 0xD2, 0x22, 0x1D, 0x00, 0x00}
+		};
+
+	if(aMode == EColor16MU)
+		{
+		
+		TInt buffer_size = KWidth * 4 ;
+		TUint8* buffer = new(ELeave) TUint8[buffer_size];
+		TPtr8 source_ptr(buffer, buffer_size, buffer_size);
+
+		//Screen bitmap
+		aScreenBmp = new (ELeave) CFbsBitmap;
+		CleanupStack::PushL(aScreenBmp);
+		User::LeaveIfError(aScreenBmp->Create(size, aMode));
+		for(i=0; i<KHeight; i++)
+			{
+			TUint8* bufCur = buffer;
+			TUint8* bufSrcCur = screenBmpSrcData[i];
+			TUint8* bufSrcEnd = bufSrcCur + KWidth * 3;
+			while(bufSrcCur < bufSrcEnd)
+				{
+				*bufCur++ = *bufSrcCur++;
+				*bufCur++ = *bufSrcCur++;
+				*bufCur++ = *bufSrcCur++;
+				*bufCur++ = 0xff;
+				}
+			aScreenBmp->SetScanLine(source_ptr, i);
+			}
+			
+		//Source bitmap
+		aSrcBmp = new (ELeave) CFbsBitmap;
+		CleanupStack::PushL(aSrcBmp);
+		User::LeaveIfError(aSrcBmp->Create(size, aMode));
+		for(i=0; i<KHeight; i++)
+			{
+			TUint8* bufCur = buffer;
+			TUint8* bufSrcCur = srcBmpData[i];
+			TUint8* bufSrcEnd = bufSrcCur + KWidth * 3;
+			while(bufSrcCur < bufSrcEnd)
+				{
+				*bufCur++ = *bufSrcCur++;
+				*bufCur++ = *bufSrcCur++;
+				*bufCur++ = *bufSrcCur++;
+				*bufCur++ = 0xff;
+				}
+			aSrcBmp->SetScanLine(source_ptr, i);
+			}
+			
+			
+		//Alpha bitmap
+		aAlphaBmp = new (ELeave) CFbsBitmap;
+		CleanupStack::PushL(aAlphaBmp);
+		User::LeaveIfError(aAlphaBmp->Create(size, EGray256));
+		for(i=0;i<KHeight;i++)
+			{
+			TPtr8 p(alphaBmpData[i], KWidth * 3, KWidth * 3);
+			aAlphaBmp->SetScanLine(p, i);
+			}
+			
+		delete [] buffer;	
+		}
+	else
+		{
+		//Screen bitmap
+		aScreenBmp = new (ELeave) CFbsBitmap;
+		CleanupStack::PushL(aScreenBmp);
+		User::LeaveIfError(aScreenBmp->Create(size, aMode));
+		for(i=0;i<KHeight;i++)
+			{
+			TPtr8 p(screenBmpSrcData[i], KWidth * 3, KWidth * 3);
+			aScreenBmp->SetScanLine(p, i);
+			}
+		//Source bitmap
+		aSrcBmp = new (ELeave) CFbsBitmap;
+		CleanupStack::PushL(aSrcBmp);
+		User::LeaveIfError(aSrcBmp->Create(size, aMode));
+		for(i=0;i<KHeight;i++)
+			{
+			TPtr8 p(srcBmpData[i], KWidth * 3, KWidth * 3);
+			aSrcBmp->SetScanLine(p, i);
+			}
+		//Alpha bitmap
+		aAlphaBmp = new (ELeave) CFbsBitmap;
+		CleanupStack::PushL(aAlphaBmp);
+		User::LeaveIfError(aAlphaBmp->Create(size, EGray256));
+		for(i=0;i<KHeight;i++)
+			{
+			TPtr8 p(alphaBmpData[i], KWidth * 3, KWidth * 3);
+			aAlphaBmp->SetScanLine(p, i);
+			}
+		}	
+	}
+
+void CTAlphaBlending::DestroyAlphaBlendingBitmaps(CFbsBitmap*& aScreenBmp, 
+											  CFbsBitmap*& aSrcBmp, 
+											  CFbsBitmap*& aAlphaBmp)
+	{
+	CleanupStack::PopAndDestroy(aAlphaBmp);
+	aAlphaBmp = NULL;
+	CleanupStack::PopAndDestroy(aSrcBmp);
+	aSrcBmp = NULL;
+	CleanupStack::PopAndDestroy(aScreenBmp);
+	aScreenBmp = NULL;
+	}
+
+//The test doesn't check anything. It is for debugging only.
+void CTAlphaBlending::TestAlphaBlending2L()
+	{
+	static const TDisplayMode modeList[] = {
+			EColor64K, EColor256, EColor16MAP, EColor16MA, EColor16MU, EColor4K
+	};
+	const TInt KNumTestDisplayModes=sizeof(modeList)/sizeof(modeList[0]);
+	for(TInt orientation=0;orientation<=CFbsBitGc::EGraphicsOrientationRotated270;orientation++)
+		{
+		CFbsBitmap* srcBmp = NULL;
+		CFbsBitmap* alphaBmp = NULL;
+		TInt err = KErrNotSupported;
+		// Try several modes
+		for (TInt modeIndex = 0; (err != KErrNone) && modeIndex < KNumTestDisplayModes; modeIndex++)
+			{
+			err = CreateScreenDevice(modeList[modeIndex],(CFbsBitGc::TGraphicsOrientation)orientation);
+			}
+		if (err == KErrNotSupported)
+			{
+			// Orientation not supported, try next one
+			continue;
+			}
+		TInt j;
+		//The source bitmap data
+		TUint8 srcBmpData[100];
+		for(j=0;j<100;j++)
+			{
+			srcBmpData[j] = 0xAA;
+			}
+		//The alpha bitmap data
+		TUint8 alphaBmpData[20];
+		for(j=0;j<20;j++)
+			{
+			alphaBmpData[j] = TUint8(j);
+			}
+		//Source bitmap
+		srcBmp = new (ELeave) CFbsBitmap;
+		CleanupStack::PushL(srcBmp);
+		User::LeaveIfError(srcBmp->Create(TSize(100, 1), EColor256));
+		TPtr8 p1(srcBmpData, 100, 100);
+		srcBmp->SetScanLine(p1, 0);
+		//Alpha bitmap
+		alphaBmp = new (ELeave) CFbsBitmap;
+		CleanupStack::PushL(alphaBmp);
+		User::LeaveIfError(alphaBmp->Create(TSize(20, 1), EGray256));
+		TPtr8 p2(alphaBmpData, 20, 20);
+		alphaBmp->SetScanLine(p2, 0);
+		//Do BitBltMasked()
+		iGc->BitBltMasked(TPoint(20, 20), srcBmp, TRect(10, 0, 100, 1), alphaBmp, EFalse);
+		iDevice->Update();
+		iGc->SetOrientation(CFbsBitGc::EGraphicsOrientationNormal);
+		//
+		CleanupStack::PopAndDestroy(alphaBmp);
+		CleanupStack::PopAndDestroy(srcBmp);
+		}
+	}
+
+TUint32 AlphaBlend(TUint32 aDestPixel, TUint32 aSrcPixel, TUint8 aMask)
+ 	{
+ 	TUint32 dr = (aDestPixel & 0x00FF0000) >> 16;
+ 	TUint32 dg = (aDestPixel & 0x0000FF00) >> 8;
+ 	TUint32 db = aDestPixel & 0x000000FF;
+ 	
+ 	TUint32 sr = (aSrcPixel & 0x00FF0000) >> 16;
+ 	TUint32 sg = (aSrcPixel & 0x0000FF00) >> 8;
+ 	TUint32 sb = aSrcPixel & 0x000000FF;
+ 	
+ 	TUint32 rr = (aMask * sr)/255 + ((0xFF - aMask) * dr)/255;
+ 	TUint32 rg = (aMask * sg)/255 + ((0xFF - aMask) * dg)/255;
+ 	TUint32 rb = (aMask * sb)/255 + ((0xFF - aMask) * db)/255;
+ 	
+ 	return(rr << 16 | rg << 8 | rb | 0xff000000);
+ 	}
+ 
+inline TUint32 OptimizedBlend32(TInt aPrimaryRed,TInt aPrimaryGreen,TInt aPrimaryBlue,TUint32 aSecondary,TUint8 aAlphaValue)
+ 	{
+  
+  	if(aAlphaValue == 0xff)
+ 		{
+ 		return (aPrimaryBlue + (aPrimaryGreen<<8) + (aPrimaryRed<<16)) | 0xff000000;
+  		}
+  	else
+  		{
+  		const TUint32 alphaValue = (aAlphaValue << 8) + aAlphaValue;
+  
+  		const TInt r2 = (aSecondary & 0x00ff0000) >> 16;
+  		const TInt g2 = (aSecondary & 0x0000ff00) >> 8;
+  		const TInt b2 = aSecondary & 0x000000ff;
+  
+  		const TInt r3 = ((alphaValue * (aPrimaryRed   - r2)) >> 16) + r2;
+ 		const TInt g3 = ((alphaValue * (aPrimaryGreen - g2)) >> 16) + g2;
+ 		const TInt b3 = ((alphaValue * (aPrimaryBlue  - b2)) >> 16) + b2;
+ 
+ 		return (b3 & 0xFF) | ((g3<<8) & 0xFF00) | ((r3<<16) & 0xFF0000) | 0xFF000000;
+  		}
+  	}
+
+
+/**
+  @SYMTestCaseID GRAPHICS-BITGDI-0085
+ 
+  @SYMDEF             
+
+  @SYMTestCaseDesc 
+   
+  @SYMTestPriority High
+
+  @SYMTestStatus Implemented
+
+  @SYMTestActions 
+ 
+  @SYMTestExpectedResults 
+*/  	
+// This tests the correctness of the results of alpha-blending with EColor16MA
+void CTAlphaBlending::TestAlphaBlendCorrect(TDisplayMode /* aScreenMode */, TDisplayMode /* aBitmapMode */)
+ 	{
+ 	// test data
+ 	TUint32 top = 0xFFCCEE55;
+ 	TUint32 beneath = 0xFFEEAA66;
+ 	TUint8 alpha = 0xF0;
+ 	
+ 	TInt maxDiff = 0;
+ 	
+ 	for(TInt i = 0; i < 100000; i++)
+ 		{
+ 		top = Math::Random();
+ 		beneath = Math::Random();
+ 		alpha = Math::Random();
+ 		TUint32 res1 = AlphaBlend(beneath, top, alpha);
+ 		TUint32 res2 = OptimizedBlend32((top >> 16) & 0xFF,(top >>8) & 0xFF,(top & 0xFF),beneath, alpha);
+ 		
+ 		if(res1 != res2)
+ 			{
+ 			TInt diff = 0;
+ 			TInt diff1 = res1 & 0xFF;
+ 			TInt diff2 = res2 & 0xFF;
+ 			
+ 			diff = diff1 - diff2;
+ 			
+ 			if(diff < 0)
+ 				diff*=-1;
+ 				
+ 			if(diff > maxDiff)
+ 				maxDiff = diff;
+ 				
+ 			diff1 = (res1 >> 8) & 0xFF;
+ 			diff2 = (res2 >> 8) & 0xFF;
+ 			
+ 			diff = diff1 - diff2;
+ 			
+ 			if(diff < 0)
+ 				diff*=-1;
+ 				
+ 			if(diff > maxDiff)
+ 				maxDiff = diff;
+ 			
+ 			
+ 			diff1 = (res1 >> 16) & 0xFF;
+ 			diff2 = (res2 >> 16) & 0xFF;
+ 			
+ 			diff = diff1 - diff2;
+ 			
+ 			if(diff < 0)
+ 				diff*=-1;
+ 				
+ 			if(diff > maxDiff)
+ 				maxDiff = diff;
+ 			
+ 			}
+ 		}
+	
+ 	INFO_PRINTF1(_L("Results:"));
+ 		
+ 	if(maxDiff)
+ 		INFO_PRINTF2(_L("Max Diff = %i"), maxDiff);
+ 	else
+ 		INFO_PRINTF1(_L("Results are identical"));
+  	}
+
+//--------------
+__CONSTRUCT_STEP__(AlphaBlending)
+
+void CTAlphaBlendingStep::TestSetupL()
+	{
+	}
+