os/graphics/graphicsdeviceinterface/bitgdi/tbit/TAlphaBlend.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #include <hal.h>
    17 #include <e32math.h>
    18 #include "TAlphaBlend.h"
    19 
    20 
    21 const TInt KWidth = 10;//Used in alpha blending tests
    22 const TInt KHeight = 3;//Used in alpha blending tests
    23 const TInt KMaximumAttempts = 2;	// Allow retries on some tests, due to spurious InfoPrints 
    24 TBool iExtraLogging1=EFalse;		//Used to trigger logging at times the test fails
    25 TBool iExtraLogging2=EFalse;		//Used to trigger logging at times the test fails
    26 
    27 CTAlphaBlending::CTAlphaBlending(CTestStep* aStep):
    28 	CTGraphicsBase(aStep),
    29 	iDevice(NULL),
    30 	iGc(NULL)
    31 	{
    32 	}
    33 
    34 CTAlphaBlending::~CTAlphaBlending()
    35 	{
    36 	DeleteGraphicsContext();
    37 	DeleteScreenDevice();
    38 	}
    39 
    40 void CTAlphaBlending::RunTestCaseL(TInt aCurTestCase)
    41 	{
    42 	((CTAlphaBlendingStep*)iStep)->SetTestStepID(KUnknownSYMTestCaseIDName);
    43 	switch(aCurTestCase)
    44 		{
    45 	case 1:
    46 		((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0024"));
    47 		INFO_PRINTF1(_L("Alpha blending"));
    48 		TestAlphaBlendingL();
    49 		break;		
    50 	case 2:
    51 /**
    52 @SYMTestCaseID		GRAPHICS-BITGDI-0114
    53 */
    54 		((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0114"));
    55 		INFO_PRINTF1(_L("Alpha blending 2"));
    56 		TestAlphaBlending2L();
    57 		break;
    58 	case 3:
    59 		((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0085"));
    60  		INFO_PRINTF1(_L("Alpha blending Correctness test 16MU 16MA"));
    61  		TestAlphaBlendCorrect(EColor16MU, EColor16MU);
    62  		break;
    63  	case 4:
    64  		((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0097"));
    65  		INFO_PRINTF1(_L("Alpha plot test"));
    66 		TestAlphaBlendingPlotL();
    67 		break;
    68 	case 5:
    69 /**
    70 @SYMTestCaseID		GRAPHICS-BITGDI-0115
    71 */
    72 		((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0115"));
    73 		INFO_PRINTF1(_L("Draw bitmap blending"));
    74 		DoDrawBitmapTestsL();
    75 		break;
    76 	case 6:
    77 		//DEF118268
    78 		((CTAlphaBlendingStep*)iStep)->SetTestStepID(_L("GRAPHICS-BITGDI-0085"));
    79 		INFO_PRINTF1(_L("Alpha blending Correctness test 16M 16MA"));
    80 		TestAlphaBlendCorrect(EColor16M, EColor16MA);
    81 		break;
    82 	case 7:
    83 		((CTAlphaBlendingStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName);
    84 		((CTAlphaBlendingStep*)iStep)->CloseTMSGraphicsStep();
    85 		TestComplete();
    86 		break;
    87 		}
    88 	((CTAlphaBlendingStep*)iStep)->RecordTestResultL();
    89 	}
    90 
    91 TInt CTAlphaBlending::CreateScreenDevice(TDisplayMode aDisplayMode, CFbsBitGc::TGraphicsOrientation aOrientation)
    92 	{
    93 	DeleteGraphicsContext();
    94 	DeleteScreenDevice();
    95 	TRAPD(err, iDevice = CFbsScreenDevice::NewL(_L("scdv"), aDisplayMode));
    96 	if(err == KErrNotSupported)
    97 		{
    98 		return err;
    99 		}
   100 	TEST2(err, KErrNone);
   101 	err = iDevice->CreateContext((CGraphicsContext*&)iGc);
   102 	TEST2(err, KErrNone);
   103 	if (!iGc->SetOrientation(aOrientation))
   104 		{
   105 		return(KErrNotSupported);
   106 		}
   107 	iGc->SetUserDisplayMode(aDisplayMode);
   108 	iDevice->ChangeScreenDevice(NULL);
   109 	iDevice->SetAutoUpdate(EFalse);
   110 	return err;
   111 	}
   112 
   113 void CTAlphaBlending::DeleteScreenDevice()
   114 	{
   115 	delete iDevice;
   116 	iDevice = NULL;
   117 	}
   118 
   119 void CTAlphaBlending::DeleteGraphicsContext()
   120 	{
   121 	delete iGc;
   122 	iGc = NULL;
   123 	}
   124 
   125 // returns the pixel colour from the provided bitmap in aarrggbb format
   126 // if pixel is outside the bitmaps limits return top left pixel
   127 TUint32 CTAlphaBlending::GetRawPixel(CFbsBitmap* aBitmap, TPoint aPos)
   128 	{
   129 	TBitmapUtil bmpUtil(aBitmap);	
   130 	TUint32 value = 0;
   131 	ASSERT(aPos.iX>=0 && aPos.iY>=0);
   132 	ASSERT(aPos.iX<aBitmap->SizeInPixels().iWidth && aPos.iY<aBitmap->SizeInPixels().iHeight);
   133 	bmpUtil.Begin(aPos);
   134 	value = bmpUtil.GetPixel();
   135 	bmpUtil.End();
   136 	return value;	
   137 	}
   138 
   139 /**
   140 @SYMTestCaseID		GRAPHICS-BITGDI-0097
   141 
   142 @SYMDEF             DEF113229
   143 
   144 @SYMTestCaseDesc    CDrawThirtyTwoBppBitmapCommon::WriteRgb did not change the dest alpha value to 255 when 
   145 					the dest alpha was >0 and <255 and the a soure pen had an alpha of 255	
   146 
   147 @SYMTestPriority    Normal
   148 
   149 @SYMTestStatus      Implemented
   150 
   151 @SYMTestActions     Creates a bitmap, clears it to black (destination) 50% opaque then plots a series of points 
   152 					with a 100% opaque pen on it. Tests the resultant alpha value.
   153 
   154 @SYMTestExpectedResults Final alpha value should be 255
   155 **/
   156 void CTAlphaBlending::TestAlphaBlendingPlotL()
   157 	{
   158 	const TSize KRectSize(100,100);
   159 	const TRect KTargetRect(TPoint(0,0), KRectSize);
   160 		
   161 	// create the target bitmap
   162 	CFbsBitmap* destBmp = new (ELeave) CFbsBitmap;
   163 	CleanupStack::PushL(destBmp);
   164 	User::LeaveIfError(destBmp->Create(KRectSize, EColor16MA));
   165 	destBmp->SetSizeInTwips(KRectSize);
   166 	
   167 	// create bitmap device and graphics context
   168 	CFbsBitmapDevice* destBmpDevice = CFbsBitmapDevice::NewL(destBmp);
   169 	CleanupStack::PushL(destBmpDevice);
   170 	CFbsBitGc* destGc = NULL;
   171 	User::LeaveIfError(destBmpDevice->CreateContext(destGc));
   172 	CleanupStack::PushL(destGc);
   173 	destGc->SetPenStyle(CGraphicsContext::ENullPen);
   174 	destGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
   175 		
   176 	TDisplayMode screenMode = EColor16MA;
   177 	TInt err = CreateScreenDevice(screenMode);
   178 	if (err != KErrNone)
   179 		{
   180 		screenMode = EColor64K;
   181 		err = CreateScreenDevice(screenMode);
   182 		}
   183 	
   184 	if(err==KErrNone)
   185 		{
   186 		const TInt KSqrMin=45;
   187 		const TInt KSqrMax=55;
   188 						
   189 		iGc->SetUserDisplayMode(screenMode);
   190 		destGc->SetBrushColor(TRgb(0,0,0,127));
   191 		destGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
   192 		destGc->Clear(KTargetRect);
   193 
   194 		// copy over to screen dc for anyone watching
   195 		iGc->BitBlt(TPoint(0,0), destBmp, KTargetRect);
   196 		iDevice->Update();
   197 		
   198 		// set the pen colour to white and plot some points
   199 		destGc->SetDrawMode(CGraphicsContext::EDrawModePEN);
   200 		destGc->SetPenStyle(CGraphicsContext::ESolidPen);
   201 		destGc->SetPenColor(TRgb(0,70,130,255));
   202 		for( TInt y=KSqrMin;y<=KSqrMax;y++)
   203 			{
   204 			for( TInt x=KSqrMin;x<=KSqrMax;x++)
   205 				{
   206 				destGc->Plot(TPoint(x,y));
   207 				}
   208 			}
   209 			
   210 		// copy over to screen dc for anyone watching
   211 		iGc->BitBlt(TPoint(0,0), destBmp, KTargetRect);
   212 		iDevice->Update();
   213 		
   214 		TUint32 actualValue=0;
   215 		// check the resulting values alpha values are 0xFF in the square we drew
   216 		for( TInt y=KSqrMin;y<=KSqrMax;y++)
   217 			{
   218 			for( TInt x=KSqrMin;x<=KSqrMax;x++)
   219 				{
   220 				actualValue = GetRawPixel(destBmp, TPoint(x,y));
   221 				if( (actualValue&0xFF000000) != 0xFF000000 )
   222 					{
   223 					TEST(EFalse);
   224 					INFO_PRINTF2(_L("TestAlphaBlendingPlotL() ***FAILED*** - expected alpha value 0xFF got %d "),((actualValue&0xFF000000)>>24));
   225 					}
   226 				}
   227 			}
   228 		}
   229 		CleanupStack::PopAndDestroy(3); //destGc,destBmpDevice,destBmp
   230 	}
   231 
   232 /**
   233   @SYMTestCaseID GRAPHICS-BITGDI-0024
   234  
   235   @SYMDEF             
   236 
   237   @SYMTestCaseDesc 
   238    
   239 	System, GT0173 System Libraries, BITGDI support required for semi-transparent windows
   240 	DEF039083 - Using BitBltMasked to do alpha-blending only works if your brush style is "null"
   241 	DEF039409 - Wrong part of Alpha Bitmap is used when there is a clipping region 
   242 	DEF039669 - The UserDisplayMode is not honoured during the AlphaBlendBitmap function. 
   243 	REQ3413 Second overload of CFbsBitGc's AlphaBlendBitmaps - "Supply a second overload of 
   244 	CFbsBitGc's AlphaBlendBitmaps function, but with one of the source bitmaps being passed 
   245 	as a CFbsBitGc object, so that the screen can be used as a source."
   246 
   247   @SYMTestPriority High
   248 
   249   @SYMTestStatus Implemented
   250 
   251   @SYMTestActions 
   252   	
   253   	Tests alpha blending - for all display modes, some brush styles, user display modes, 
   254 	different positions on the screen.
   255   
   256 	Shadow/fade mode is no more tested, because the existing BitBltMasked() and the new 
   257 	AlphaBlendBitmaps() methods treat it a different way - see MAlphaBlend interface in
   258 	ScreenDriver component.
   259 
   260   @SYMTestExpectedResults Test should perform graphics operations succesfully. 
   261 */
   262 
   263 void CTAlphaBlending::TestAlphaBlendingL()
   264 	{
   265 	TPoint originPt(0, 0);
   266 	TPoint destPt(0, 0);
   267 	TRect scrRc1(0, 0, KWidth, KHeight);
   268 	TPoint srcPt2(0, 0);
   269 	TPoint alphaPt(0, 0);
   270 	//
   271 	//If we compare CFbsBitGc::BitBltMasked() aguments with CFbsBitGc::AlphaBlending() arguments,
   272 	//we will see that AlphaBlending() has more arguments than BitBltMasked() - 
   273 	//srcPt2, alphaPt. To make it possible - the comparison between these two methods,
   274 	//we have to change aAlphaPt and aSrcPt2 values accordingly with the changes of scrRc1 value.
   275 	//
   276 	//test 1 - the origin is moved
   277 	originPt = TPoint(97, 33);
   278 	DoAlphaBlendingTestsL(originPt, destPt, scrRc1, srcPt2, alphaPt);
   279 #if !defined(__X86GCC__)	//These test take too long to run in X86GCC
   280 	//test 2 - the origin is (0, 0)
   281 	originPt = TPoint(0, 0);
   282 	DoAlphaBlendingTestsL(originPt, destPt, scrRc1, srcPt2, alphaPt);
   283 	//test 3 - scrRect1 is not (0, 0, KWidth, KHeight)
   284 	scrRc1 = TRect(3, 1, KWidth, KHeight);
   285 	alphaPt = TPoint(3, 1);
   286 	DoAlphaBlendingTestsL(originPt, destPt, scrRc1, srcPt2, alphaPt);
   287 	//test 4 - restore scrRc1 and alphaPt, move the destination point
   288 	scrRc1 = TRect(0, 0, KWidth, KHeight);
   289 	alphaPt = TPoint(0, 0);
   290 	destPt = TPoint(13, 17);
   291 	iExtraLogging1=ETrue;
   292 	DoAlphaBlendingTestsL(originPt, destPt, scrRc1, srcPt2, alphaPt);
   293 	iExtraLogging1=EFalse;
   294 #endif	//__X86GCC__
   295 	}
   296 
   297 void CTAlphaBlending::DoDrawBitmapTestsL()
   298 	{
   299 	TDisplayMode modes[] = {EColor16MA, EColor16MAP, EColor16MU, EColor16M, EColor256, EColor4K, EColor64K, 
   300 						   EGray256, EGray16, EGray4, EGray2, EColor16};
   301 	const TInt KNumTestDisplayModes=sizeof(modes)/sizeof(modes[0]);
   302 	for(TInt modeIndex=0;modeIndex<KNumTestDisplayModes;modeIndex++)
   303 		{
   304 		TDisplayMode screenMode=modes[modeIndex];
   305 		if (CreateScreenDevice(screenMode)!=KErrNone)
   306 			continue;
   307 		DoDrawBitmapTestL(screenMode);
   308 		}
   309 	}
   310 
   311 void CTAlphaBlending::DoDrawBitmapTestL(TDisplayMode aTestDisplayMode)
   312 	{
   313 	iGc->Reset();
   314 	TBool alphaSupported=(aTestDisplayMode==EColor16MA || aTestDisplayMode==EColor16MAP);
   315 	TSize screenSize=iDevice->SizeInPixels();
   316 //
   317 	const TInt KNumTestSrcSizes=4;
   318 	const TSize testSrcSizes[KNumTestSrcSizes]={TSize(2,2),TSize(20,10),TSize(200,5),TSize(55,555)};
   319 	for(TInt srcSizeIndex=0;srcSizeIndex<KNumTestSrcSizes;srcSizeIndex++)
   320 		{
   321 		TSize srcSize(testSrcSizes[srcSizeIndex]);
   322 //
   323 		CFbsBitmap* srcBmp=new(ELeave) CFbsBitmap;
   324 		CleanupStack::PushL(srcBmp);
   325 		User::LeaveIfError(srcBmp->Create(srcSize,aTestDisplayMode));
   326 		CFbsBitmapDevice* srcDevice = CFbsBitmapDevice::NewL(srcBmp);
   327 		CleanupStack::PushL(srcDevice);
   328 		CFbsBitGc* srcGc=NULL;
   329 		User::LeaveIfError(srcDevice->CreateContext(srcGc));
   330 		CleanupStack::PushL(srcGc);
   331 //
   332 		CFbsBitmap* srcAlpha=new(ELeave) CFbsBitmap;
   333 		CleanupStack::PushL(srcAlpha);
   334 		User::LeaveIfError(srcAlpha->Create(srcSize,aTestDisplayMode));
   335 		CFbsBitmapDevice* srcAlphaDevice = CFbsBitmapDevice::NewL(srcAlpha);
   336 		CleanupStack::PushL(srcAlphaDevice);
   337 		CFbsBitGc* srcAlphaGc=NULL;
   338 		User::LeaveIfError(srcAlphaDevice->CreateContext(srcAlphaGc));
   339 		CleanupStack::PushL(srcAlphaGc);
   340 		srcAlphaGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
   341 //
   342 		CFbsBitmap* srcMask=new(ELeave) CFbsBitmap;
   343 		CleanupStack::PushL(srcMask);
   344 		User::LeaveIfError(srcMask->Create(srcSize,EGray256));
   345 		CFbsBitmapDevice* srcMaskDevice = CFbsBitmapDevice::NewL(srcMask);
   346 		CleanupStack::PushL(srcMaskDevice);
   347 		CFbsBitGc* srcMaskGc=NULL;
   348 		User::LeaveIfError(srcMaskDevice->CreateContext(srcMaskGc));
   349 		CleanupStack::PushL(srcMaskGc);
   350 //
   351 		TInt maxX=srcSize.iWidth-1;
   352 		TInt maxY=srcSize.iHeight-1;
   353 		for(TInt yLoop=0;yLoop<srcSize.iHeight;yLoop++)
   354 			{
   355 			for(TInt xLoop=0;xLoop<srcSize.iWidth;xLoop++)
   356 				{
   357 				TPoint plotPos(xLoop,yLoop);
   358 				TRgb pen(xLoop*255/maxX,yLoop*255/maxY,(xLoop+yLoop)*128/(maxX+maxY));
   359 				srcGc->SetPenColor(pen);
   360 				srcGc->Plot(plotPos);
   361 				TInt alpha=(xLoop+yLoop)*255/(maxX+maxY);
   362 				pen.SetAlpha(alpha);
   363 				srcAlphaGc->SetBrushColor(pen);
   364 				srcAlphaGc->Clear(TRect(plotPos,TSize(1,1)));
   365 				srcMaskGc->SetPenColor(TRgb::Gray256(alpha));
   366 				srcMaskGc->Plot(plotPos);
   367 				}
   368 			}
   369 		const TInt KNumTestTargSizes=5;
   370 		const TSize testTargSizes[KNumTestTargSizes]={TSize(0,0), TSize(20,1),TSize(30,20),TSize(200,31),TSize(55,5)};
   371 		for(TInt targSizeIndex=0;targSizeIndex<KNumTestSrcSizes;targSizeIndex++)
   372 			{
   373 			TSize targSize(testTargSizes[targSizeIndex]);
   374 			if (targSizeIndex==0)
   375 				{
   376 				targSize=srcSize;	// Special case with no scaling
   377 				if (targSize.iWidth>screenSize.iWidth)
   378 					targSize.iWidth=screenSize.iWidth;
   379 				TInt maxHeight=screenSize.iHeight/3;
   380 				if (targSize.iHeight>maxHeight)
   381 					targSize.iHeight=maxHeight;
   382 				}
   383 //
   384 			CFbsBitmap* targBmp=new(ELeave) CFbsBitmap;
   385 			CleanupStack::PushL(targBmp);
   386 			User::LeaveIfError(targBmp->Create(targSize,aTestDisplayMode));
   387 			CFbsBitmapDevice* targBmpDevice = CFbsBitmapDevice::NewL(targBmp);
   388 			CleanupStack::PushL(targBmpDevice);
   389 			CFbsBitGc* targGc=NULL;
   390 			User::LeaveIfError(targBmpDevice->CreateContext(targGc));
   391 			CleanupStack::PushL(targGc);
   392 //
   393 			CFbsBitmap* targMask=new(ELeave) CFbsBitmap;
   394 			CleanupStack::PushL(targMask);
   395 			User::LeaveIfError(targMask->Create(targSize,EGray256));
   396 			CFbsBitmapDevice* targMaskDevice = CFbsBitmapDevice::NewL(targMask);
   397 			CleanupStack::PushL(targMaskDevice);
   398 			CFbsBitGc* targMaskGc=NULL;
   399 			User::LeaveIfError(targMaskDevice->CreateContext(targMaskGc));
   400 			CleanupStack::PushL(targMaskGc);
   401 //
   402 			TPoint drawPos;
   403 			TRect testRect1(targSize);
   404 			iGc->Clear();
   405 // First we pre-stretch the source and mask bitmaps into temp bitmaps
   406 			targGc->DrawBitmap(TRect(targSize),srcBmp);
   407 			targMaskGc->DrawBitmap(TRect(targSize),srcMask);
   408 // Then blend them onto the screen with a call to BitBltMasked
   409 			iGc->BitBltMasked(drawPos,targBmp,TRect(targSize),targMask,EFalse);
   410 			drawPos.iY+=targSize.iHeight;
   411 			TRect testRect2(drawPos,targSize);
   412 // Next we combine the stretching and masking with one call to DrawBitmapMasked,
   413 // this should give the same end result.
   414 			iGc->DrawBitmapMasked(testRect2,srcBmp,TRect(srcSize),srcMask,EFalse);
   415 			TRect testRect3;
   416 			if (alphaSupported)
   417 				{
   418 // Finally if alpha blending supported we stretch and blend, again to achieve the exact same end result
   419 // as the two previous calls. This was specificially done to catch DEF116427.
   420 				drawPos.iY+=targSize.iHeight;
   421 				testRect3=TRect(drawPos,targSize);
   422 				iGc->DrawBitmap(testRect3,srcAlpha);
   423 				}
   424 //Use this just to check what we've put in the test bitmaps
   425 /*
   426 			drawPos.iY+=targSize.iHeight+1;
   427 			iGc->BitBlt(drawPos,srcBmp);
   428 			drawPos.iY+=srcSize.iHeight+1;
   429 			iGc->BitBlt(drawPos,srcMask);
   430 			drawPos.iY+=srcSize.iHeight+1;
   431 			if (alphaSupported)
   432 				iGc->BitBlt(drawPos,srcAlpha);
   433 */
   434 		   	iDevice->Update();
   435 			TBool ret1=iDevice->RectCompare(testRect1,*iDevice,testRect2);
   436 		   	TBool ret2=alphaSupported?iDevice->RectCompare(testRect1,*iDevice,testRect3):ETrue;
   437 			if (!ret1 || !ret2)
   438 				{
   439 				INFO_PRINTF4(_L("DrawBitmapTest, ret1=%d, ret2=%d, Screen mode=%d"),ret1,ret2,aTestDisplayMode);
   440 				TEST(EFalse);
   441 				}
   442 			CleanupStack::PopAndDestroy(3,targMask);
   443 			CleanupStack::PopAndDestroy(3,targBmp);
   444 			}
   445 		CleanupStack::PopAndDestroy(3,srcMask);
   446 		CleanupStack::PopAndDestroy(3,srcAlpha);
   447 		CleanupStack::PopAndDestroy(3,srcBmp);
   448 		}
   449 	}
   450 
   451 //Tests alpha blending - for all display modes, some brush styles, user display modes, 
   452 //different positions on the screen.
   453 void CTAlphaBlending::DoAlphaBlendingTestsL(const TPoint& aOrigin,
   454 										const TPoint& aDestPt, 
   455 										const TRect& aSrcRc1, 
   456 										const TPoint& aScrPt2,
   457 										const TPoint& aAlphaPt)
   458 	{
   459 	TBuf<128> buf;
   460 	_LIT(KLog,"Origin=(%d,%d) DestPt=(%d,%d) SrcRect=(%d,%d,%d,%d) ScrPt=(%d,%d) AlphaPt=(%d,%d)");
   461 	buf.Format(KLog,aOrigin.iX,aOrigin.iY,aDestPt.iX,aDestPt.iY,aSrcRc1.iTl.iX,aSrcRc1.iTl.iY
   462 						,aSrcRc1.iBr.iX,aSrcRc1.iBr.iY,aScrPt2.iX,aScrPt2.iY,aAlphaPt.iX,aAlphaPt.iY);
   463 	INFO_PRINTF1(buf);
   464 	TDisplayMode mode[] = {EColor16MA, EColor16MAP, EColor16MU, EColor16M, EColor256, EColor4K, EColor64K,
   465 						   EGray256, EGray16, EGray4, EGray2, EColor16};
   466 	CFbsBitmap* screenBmp = NULL;
   467 	CFbsBitmap* srcBmp = NULL;
   468 	CFbsBitmap* alphaBmp = NULL;
   469 	CGraphicsContext::TBrushStyle brushStyle[] = {CGraphicsContext::ENullBrush, CGraphicsContext::ESolidBrush};
   470 	for(TInt i=0;i<TInt(sizeof(mode)/sizeof(mode[0]));i++)
   471 		{
   472 		for(TInt orientation=0;orientation<=CFbsBitGc::EGraphicsOrientationRotated270;orientation++)
   473 			{
   474 			if (CreateScreenDevice(mode[i],(CFbsBitGc::TGraphicsOrientation)orientation) != KErrNone)
   475 				{
   476 				continue;
   477 				}
   478 			iExtraLogging2=(iExtraLogging1 && mode[i]==11);
   479 	 		INFO_PRINTF3(_L("Mode=%d, Orientation=%d"), mode[i], orientation);
   480 			CreateAlphaBlendingBitmapsLC(screenBmp, srcBmp, alphaBmp, mode[i]);
   481 			for(TInt j=0;j<TInt(sizeof(brushStyle)/sizeof(brushStyle[0]));j++)
   482 				{
   483 				if(mode[i] == EGray4 && brushStyle[j] == CGraphicsContext::ESolidBrush)
   484 					{
   485 					//When the display mode is EGray4 - Flicker-free blitting is not enabled.
   486 					//The screen will be filled with 0xFF color, which is not the same color used by
   487 					//the test - 0x00. And BitBltMasked and AlphaBlendBitmaps will produce different results.
   488 					continue;
   489 					}
   490 				iGc->SetOrigin(aOrigin);
   491 				iGc->SetBrushStyle(brushStyle[j]);
   492 				TDisplayMode userDisplayMode[] = {EColor16MA, EColor16MAP, EColor16MU, EColor16M, EColor256, 
   493 												  EColor4K, EColor64K, EGray256, 
   494 												  EGray16, EGray4, EGray2, EColor16};
   495 				for(TInt l=0;l<TInt(sizeof(userDisplayMode)/sizeof(userDisplayMode[0]));l++)
   496 					{
   497 					iGc->SetUserDisplayMode(userDisplayMode[l]);
   498 					TSize scrDevSize = iDevice->SizeInPixels();
   499 					TRect clipRc[] = {TRect(0, 0, scrDevSize.iWidth, scrDevSize.iHeight),
   500 										TRect(0, 1, scrDevSize.iWidth, scrDevSize.iHeight), // Tests Y clipping only
   501 										TRect(5, 0, scrDevSize.iWidth, scrDevSize.iHeight), // Tests X clipping only
   502 										TRect(5, 1, scrDevSize.iWidth, scrDevSize.iHeight),
   503 										TRect(3, 0, 14, 23)};//14 and 23 values are not accidental! 
   504 															 //Sometimes the method is called with aDestPt(13, 17).
   505 					for(TInt k=0;k<TInt(sizeof(clipRc)/sizeof(clipRc[0]));k++)
   506 						{
   507 						if (iExtraLogging2)
   508 							{
   509 							_LIT(KLog,"  BrushStyle=%d UserDisplayMode=%d ClipRect=(%d,%d,%d,%d)");
   510 			 				INFO_PRINTF7(KLog,j,l,clipRc[k].iTl.iX,clipRc[k].iTl.iY,clipRc[k].iBr.iX,clipRc[k].iBr.iY);
   511 							}
   512 						iGc->Clear();
   513 						iGc->SetClippingRect(clipRc[k]);
   514 						DoAlphaBlendingTestL(screenBmp, srcBmp, alphaBmp, aDestPt, aSrcRc1, aScrPt2, aAlphaPt);
   515 						iGc->CancelClippingRect();
   516 						}
   517 					}//end of - for(TInt l=0;l<TInt(sizeof(userDisplayMode)/sizeof(userDisplayMode[0]));l++)
   518 				iGc->SetOrientation(CFbsBitGc::EGraphicsOrientationNormal);
   519 				}
   520 			DestroyAlphaBlendingBitmaps(screenBmp, srcBmp, alphaBmp);
   521 			}//end of - for(TInt j=0;j<TInt(sizeof(brushStyle)/sizeof(brushStyle[0]));j++)
   522 		}//end of - for(TInt i=0;i<TInt(sizeof(mode)/sizeof(mode[0]));i++)
   523 	}
   524 
   525 //The method compares results of two alpha blending methods:
   526 //iGc->BitBltMasked() and iGc->AlphaBlendBitmaps().
   527 //To make that possible, aScreenBmp is copied to the screen before the call of
   528 //iGc->BitBltMasked().
   529 void CTAlphaBlending::DoAlphaBlendingTestL(CFbsBitmap* aScreenBmp, 
   530 									   const CFbsBitmap* aSrcBmp, 
   531 									   const CFbsBitmap* aAlphaBmp,
   532 									   const TPoint& aDestPt, 
   533 									   const TRect& aSrcRc1, 
   534 									   const TPoint& aSrcPt2,
   535 									   const TPoint& aAlphaPt)
   536 	{
   537 	_LIT(KScreenBmpFile, "C:\\BMP_DATA.DAT");
   538 	iGc->SetShadowMode(EFalse);
   539    	TInt i;
   540    	TInt res = -1;
   541 	TSize scrDevSize = iDevice->SizeInPixels();
   542 	TInt allocatedSize = scrDevSize.iWidth * scrDevSize.iHeight * 2;
   543 	TRect screenBmpRc;
   544    	//The screen alpha blended data after calling of BitBltMasked() - will be filled after the call
   545 	TUint8* screenBmpDestData1 = new (ELeave) TUint8[allocatedSize];
   546 	CleanupStack::PushL(screenBmpDestData1);
   547    	//The screen alpha blended data after calling of AlphaBlendingBitmaps() - will be filled after the call
   548 	TUint8* screenBmpDestData2 = new (ELeave) TUint8[allocatedSize];
   549 	CleanupStack::PushL(screenBmpDestData2);
   550 	// Allow an effective restart of the test, since sometimes there are spurious
   551 	// InfoPrints that affect the comparisons.
   552 	for (TInt attempt = 0; res && (attempt < KMaximumAttempts); attempt++)
   553 		{
   554 		//Fill the blocks with some default value
   555 		Mem::Fill(screenBmpDestData1, allocatedSize, 0xCA);
   556 		Mem::Fill(screenBmpDestData2, allocatedSize, 0xCA);
   557 	   	//Check screen bitmap size
   558 	   	TSize screenBmpSize = aScreenBmp->SizeInPixels();
   559 	   	if ((screenBmpSize.iWidth != KWidth) || (screenBmpSize.iHeight != KHeight))
   560 	   		{
   561 	   		_LIT(KScreenErr,"DoAlphaBlendingTestL test: w:%d!=%d || h:%d!=%d");
   562 	   		INFO_PRINTF5(KScreenErr, screenBmpSize.iWidth, KWidth, screenBmpSize.iHeight, KHeight);
   563 	   		TEST(EFalse);
   564 	   		}
   565 		//  Alpha blending using CFbsBitGc::BitBltMasked  //
   566 		if (iExtraLogging2)
   567 			{
   568 			_LIT(KLog1,"    CFbsBitGc::BitBltMasked test");
   569 			INFO_PRINTF1(KLog1);
   570 			}
   571 		//Screen bitmap rectangle
   572 		screenBmpRc.SetRect(aDestPt, TSize(aSrcRc1.Width(), aSrcRc1.Height()));
   573 		
   574 		//Save screen bitmap 
   575 		TInt saveAttempts = 5;
   576 		TInt err = aScreenBmp->Save(KScreenBmpFile);
   577 		while ((err != KErrNone) && saveAttempts--)
   578 			{
   579 			// Retry the save
   580 			_LIT(KSaveRetry,"DoAlphaBlendingTestL: Bitmap save failed, retrying.");
   581 			INFO_PRINTF1(KSaveRetry);
   582 			User::After(10000); 
   583 			err = aScreenBmp->Save(KScreenBmpFile);
   584 			}
   585 		User::LeaveIfError(err);
   586 		
   587 		User::LeaveIfError(aScreenBmp->Resize(TSize(aSrcRc1.Width(), aSrcRc1.Height())));
   588 		//Draw screen bitmap
   589 	   	iGc->Clear();
   590 		iGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
   591 		iGc->DrawBitmap(screenBmpRc, aScreenBmp);
   592 	   	iDevice->Update();
   593 	   	//Do BitBltMasked()
   594 	   	iGc->BitBltMasked(aDestPt, aSrcBmp, aSrcRc1, aAlphaBmp, EFalse);
   595 	   	iDevice->Update();
   596 		//Get screen data and write the data to screenBmpDestData1.
   597 		for(i=0;i<scrDevSize.iHeight;i++)
   598 	   		{
   599 			TPtr8 p(screenBmpDestData1 + i * scrDevSize.iWidth * 2, scrDevSize.iWidth * 2, scrDevSize.iWidth * 2);
   600 			iDevice->GetScanLine(p, TPoint(0, i), scrDevSize.iWidth, EColor64K);
   601 	   		}
   602 		//  Alpha blending using explicit form of CFbsBitGc::AlphaBlendBitmaps  //
   603 		if (iExtraLogging2)
   604 			{
   605 			_LIT(KLog2,"    CFbsBitGc::AlphaBlendBitmaps explicit test");
   606 			INFO_PRINTF1(KLog2); 
   607 			}
   608 		//Clear screen
   609 	   	iGc->Clear();
   610 	   	iDevice->Update();
   611 		//Load screen bitmap 
   612 		User::LeaveIfError(aScreenBmp->Load(KScreenBmpFile));
   613 	   	//Do AlphaBlendBitmaps()
   614 	   	User::LeaveIfError(iGc->AlphaBlendBitmaps(aDestPt, aSrcBmp, aScreenBmp, aSrcRc1, 
   615 													aSrcPt2, aAlphaBmp, aAlphaPt));
   616 	   	iDevice->Update();
   617 		//Get screen data and write the data to screenBmpDestData2.
   618 		for(i=0;i<scrDevSize.iHeight;i++)
   619 	   		{
   620 			TPtr8 p(screenBmpDestData2 + i * scrDevSize.iWidth * 2, scrDevSize.iWidth * 2, scrDevSize.iWidth * 2);
   621 			iDevice->GetScanLine(p, TPoint(0, i), scrDevSize.iWidth, EColor64K);
   622 	   		}
   623 		//Compare screen bitmaps //
   624 		res = Mem::Compare(screenBmpDestData1, allocatedSize, screenBmpDestData2, allocatedSize);
   625 
   626 		// colour comparison tolerance between RGB565 components.
   627 		const TInt KColourComparisonTolerance = 2;
   628 		if (res)
   629 			{
   630 			TBool testPassed = ETrue;
   631 			// strict byte-for-byte comparison of the pixel maps could have failed because blending algorithms may  
   632 			// differ slightly, but actual resulting colours may be close enough
   633 			for (int byteNumber = 0; byteNumber < allocatedSize; byteNumber+=2)
   634 				{
   635 				// find any RGB565 value that doesn't match and examine each component
   636 				if ( *(TUint16*)(screenBmpDestData1 + byteNumber) != *(TUint16*)(screenBmpDestData2 + byteNumber))
   637 					{
   638 					TUint16 Rgb1 = *(TUint16*)(screenBmpDestData1 + byteNumber);
   639 					TUint16 Rgb2 = *(TUint16*)(screenBmpDestData2 + byteNumber);
   640 					
   641 					TInt16 Red1 = (Rgb1 & 0xF800) >> 11;
   642 					TInt16 Red2 = (Rgb2 & 0xF800) >> 11;
   643 					TInt16 DiffRed = Abs(Red1 - Red2);
   644 					
   645 					TInt16 Green1 = (Rgb1 & 0x07E0) >> 5;
   646 					TInt16 Green2 = (Rgb2 & 0x07E0) >> 5;
   647 					TInt16 DiffGreen = Abs(Green1 - Green2);
   648 					
   649 					TInt16 Blue1 = (Rgb1 & 0x001F);
   650 					TInt16 Blue2 = (Rgb2 & 0x001F);
   651 					TInt16 DiffBlue = Abs(Blue1 - Blue2);
   652 					
   653 					// is any difference is outside the tolerance break out signaling test failure
   654 					if (DiffRed > KColourComparisonTolerance || 
   655 						DiffGreen > KColourComparisonTolerance || 
   656 						DiffBlue > KColourComparisonTolerance)
   657 						{
   658 						testPassed = EFalse;
   659 						break;
   660 						}
   661 					}
   662 				}
   663 			if (testPassed)
   664 				{
   665 				res = 0;
   666 				}
   667 			}
   668 		
   669 		if (res && (attempt < KMaximumAttempts - 1))
   670 			{
   671 			INFO_PRINTF1(_L("Memory comparison 1 failed, retrying"));
   672 			// Skip to next attempt
   673 			continue;
   674 			}
   675 		TEST(res == 0);
   676 
   677 		//  Alpha blending using implicit form of CFbsBitGc::AlphaBlendBitmaps  //
   678 		if (iExtraLogging2)
   679 			{
   680 			_LIT(KLog3,"    CFbsBitGc::AlphaBlendBitmaps implicit test");
   681 			INFO_PRINTF1(KLog3);
   682 			}
   683 		//Clear screen
   684 	   	iGc->Clear();
   685 	   	iDevice->Update();
   686 		//Draw screen bitmap (it's already loaded)
   687 		User::LeaveIfError(aScreenBmp->Resize(TSize(aSrcRc1.Width(), aSrcRc1.Height())));
   688 		iGc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
   689 		iGc->DrawBitmap(screenBmpRc, aScreenBmp);
   690 	   	iDevice->Update();
   691 	   	//Do AlphaBlendBitmaps()
   692 	   	User::LeaveIfError(iGc->AlphaBlendBitmaps(aDestPt, aSrcBmp, aSrcRc1, aAlphaBmp, aSrcRc1.iTl));
   693 	   	iDevice->Update();
   694 		//Get screen data and write the data to screenBmpDestData2.
   695 		for(i=0;i<scrDevSize.iHeight;i++)
   696 	   		{
   697 			TPtr8 p(screenBmpDestData2 + i * scrDevSize.iWidth * 2, scrDevSize.iWidth * 2, scrDevSize.iWidth * 2);
   698 			iDevice->GetScanLine(p, TPoint(0, i), scrDevSize.iWidth, EColor64K);
   699 	   		}
   700 		//Compare screen bitmaps //
   701 		if (iExtraLogging2)
   702 			{
   703 			_LIT(KLog4,"    Compare Screen Bitmaps");
   704 			INFO_PRINTF1(KLog4);
   705 			}
   706 		res = Mem::Compare(screenBmpDestData1, allocatedSize, screenBmpDestData2, allocatedSize);
   707 
   708 		if (res && (attempt < KMaximumAttempts - 1))
   709 			{
   710 			INFO_PRINTF1(_L("Memory comparison 2 failed, retrying"));
   711 			}
   712 		
   713 		// Reload the screen bitmap as it was before:
   714 		User::LeaveIfError(aScreenBmp->Load(KScreenBmpFile));
   715 		}
   716 	TEST(res == 0);
   717 	
   718 	//Destroy the allocated memory blocks
   719 	CleanupStack::PopAndDestroy(2);//screenBmpDestData1 & screenBmpDestData2
   720 	}
   721 
   722 void CTAlphaBlending::CreateAlphaBlendingBitmapsLC(CFbsBitmap*& aScreenBmp, 
   723 											   CFbsBitmap*& aSrcBmp, 
   724 											   CFbsBitmap*& aAlphaBmp,
   725 											   TDisplayMode aMode)
   726 	{
   727 	TInt i;
   728 	TSize size(KWidth, KHeight);
   729 	//The screen data
   730 	TUint8 screenBmpSrcData[KHeight][KWidth * 3 + 2] = // "+ 2" - every row is aligned to a 32 bit boundary
   731 		{//0               1                 2                 3                 4                 5                 6                 7                 8                 9     
   732 		{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},
   733 		{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},
   734 		{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}
   735 		};
   736 	//The source bitmap data
   737 	TUint8 srcBmpData[KHeight][KWidth * 3 + 2] = // "+ 2" - every row is aligned to a 32 bit boundary
   738 		{//0               1                 2                 3                 4                 5                 6                 7                 8                 9     
   739 		{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},
   740 		{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},
   741 		{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}
   742 		};
   743 	//The alpha bitmap data
   744 	TUint8 alphaBmpData[KHeight][KWidth + 2] = // "+ 2" - every row is aligned to a 32 bit boundary
   745 		{//0   1     2     3     4     5     6     7     8     9     
   746 		{0x68, 0x68, 0x68, 0xAC, 0xD9, 0xB2, 0x8F, 0x11, 0xA0, 0xC1, 0x00, 0x00},
   747 		{0x71, 0x5A, 0xF6, 0xEE, 0xF9, 0xE5, 0x06, 0x4C, 0xBB, 0x7B, 0x00, 0x00},
   748 		{0x9F, 0x99, 0x45, 0x17, 0xA8, 0xF5, 0xFF, 0xD2, 0x22, 0x1D, 0x00, 0x00}
   749 		};
   750 
   751 	if(aMode == EColor16MU)
   752 		{
   753 		
   754 		TInt buffer_size = KWidth * 4 ;
   755 		TUint8* buffer = new(ELeave) TUint8[buffer_size];
   756 		TPtr8 source_ptr(buffer, buffer_size, buffer_size);
   757 
   758 		//Screen bitmap
   759 		aScreenBmp = new (ELeave) CFbsBitmap;
   760 		CleanupStack::PushL(aScreenBmp);
   761 		User::LeaveIfError(aScreenBmp->Create(size, aMode));
   762 		for(i=0; i<KHeight; i++)
   763 			{
   764 			TUint8* bufCur = buffer;
   765 			TUint8* bufSrcCur = screenBmpSrcData[i];
   766 			TUint8* bufSrcEnd = bufSrcCur + KWidth * 3;
   767 			while(bufSrcCur < bufSrcEnd)
   768 				{
   769 				*bufCur++ = *bufSrcCur++;
   770 				*bufCur++ = *bufSrcCur++;
   771 				*bufCur++ = *bufSrcCur++;
   772 				*bufCur++ = 0xff;
   773 				}
   774 			aScreenBmp->SetScanLine(source_ptr, i);
   775 			}
   776 			
   777 		//Source bitmap
   778 		aSrcBmp = new (ELeave) CFbsBitmap;
   779 		CleanupStack::PushL(aSrcBmp);
   780 		User::LeaveIfError(aSrcBmp->Create(size, aMode));
   781 		for(i=0; i<KHeight; i++)
   782 			{
   783 			TUint8* bufCur = buffer;
   784 			TUint8* bufSrcCur = srcBmpData[i];
   785 			TUint8* bufSrcEnd = bufSrcCur + KWidth * 3;
   786 			while(bufSrcCur < bufSrcEnd)
   787 				{
   788 				*bufCur++ = *bufSrcCur++;
   789 				*bufCur++ = *bufSrcCur++;
   790 				*bufCur++ = *bufSrcCur++;
   791 				*bufCur++ = 0xff;
   792 				}
   793 			aSrcBmp->SetScanLine(source_ptr, i);
   794 			}
   795 			
   796 			
   797 		//Alpha bitmap
   798 		aAlphaBmp = new (ELeave) CFbsBitmap;
   799 		CleanupStack::PushL(aAlphaBmp);
   800 		User::LeaveIfError(aAlphaBmp->Create(size, EGray256));
   801 		for(i=0;i<KHeight;i++)
   802 			{
   803 			TPtr8 p(alphaBmpData[i], KWidth * 3, KWidth * 3);
   804 			aAlphaBmp->SetScanLine(p, i);
   805 			}
   806 			
   807 		delete [] buffer;	
   808 		}
   809 	else
   810 		{
   811 		//Screen bitmap
   812 		aScreenBmp = new (ELeave) CFbsBitmap;
   813 		CleanupStack::PushL(aScreenBmp);
   814 		User::LeaveIfError(aScreenBmp->Create(size, aMode));
   815 		for(i=0;i<KHeight;i++)
   816 			{
   817 			TPtr8 p(screenBmpSrcData[i], KWidth * 3, KWidth * 3);
   818 			aScreenBmp->SetScanLine(p, i);
   819 			}
   820 		//Source bitmap
   821 		aSrcBmp = new (ELeave) CFbsBitmap;
   822 		CleanupStack::PushL(aSrcBmp);
   823 		User::LeaveIfError(aSrcBmp->Create(size, aMode));
   824 		for(i=0;i<KHeight;i++)
   825 			{
   826 			TPtr8 p(srcBmpData[i], KWidth * 3, KWidth * 3);
   827 			aSrcBmp->SetScanLine(p, i);
   828 			}
   829 		//Alpha bitmap
   830 		aAlphaBmp = new (ELeave) CFbsBitmap;
   831 		CleanupStack::PushL(aAlphaBmp);
   832 		User::LeaveIfError(aAlphaBmp->Create(size, EGray256));
   833 		for(i=0;i<KHeight;i++)
   834 			{
   835 			TPtr8 p(alphaBmpData[i], KWidth * 3, KWidth * 3);
   836 			aAlphaBmp->SetScanLine(p, i);
   837 			}
   838 		}	
   839 	}
   840 
   841 void CTAlphaBlending::DestroyAlphaBlendingBitmaps(CFbsBitmap*& aScreenBmp, 
   842 											  CFbsBitmap*& aSrcBmp, 
   843 											  CFbsBitmap*& aAlphaBmp)
   844 	{
   845 	CleanupStack::PopAndDestroy(aAlphaBmp);
   846 	aAlphaBmp = NULL;
   847 	CleanupStack::PopAndDestroy(aSrcBmp);
   848 	aSrcBmp = NULL;
   849 	CleanupStack::PopAndDestroy(aScreenBmp);
   850 	aScreenBmp = NULL;
   851 	}
   852 
   853 //The test doesn't check anything. It is for debugging only.
   854 void CTAlphaBlending::TestAlphaBlending2L()
   855 	{
   856 	static const TDisplayMode modeList[] = {
   857 			EColor64K, EColor256, EColor16MAP, EColor16MA, EColor16MU, EColor4K
   858 	};
   859 	const TInt KNumTestDisplayModes=sizeof(modeList)/sizeof(modeList[0]);
   860 	for(TInt orientation=0;orientation<=CFbsBitGc::EGraphicsOrientationRotated270;orientation++)
   861 		{
   862 		CFbsBitmap* srcBmp = NULL;
   863 		CFbsBitmap* alphaBmp = NULL;
   864 		TInt err = KErrNotSupported;
   865 		// Try several modes
   866 		for (TInt modeIndex = 0; (err != KErrNone) && modeIndex < KNumTestDisplayModes; modeIndex++)
   867 			{
   868 			err = CreateScreenDevice(modeList[modeIndex],(CFbsBitGc::TGraphicsOrientation)orientation);
   869 			}
   870 		if (err == KErrNotSupported)
   871 			{
   872 			// Orientation not supported, try next one
   873 			continue;
   874 			}
   875 		TInt j;
   876 		//The source bitmap data
   877 		TUint8 srcBmpData[100];
   878 		for(j=0;j<100;j++)
   879 			{
   880 			srcBmpData[j] = 0xAA;
   881 			}
   882 		//The alpha bitmap data
   883 		TUint8 alphaBmpData[20];
   884 		for(j=0;j<20;j++)
   885 			{
   886 			alphaBmpData[j] = TUint8(j);
   887 			}
   888 		//Source bitmap
   889 		srcBmp = new (ELeave) CFbsBitmap;
   890 		CleanupStack::PushL(srcBmp);
   891 		User::LeaveIfError(srcBmp->Create(TSize(100, 1), EColor256));
   892 		TPtr8 p1(srcBmpData, 100, 100);
   893 		srcBmp->SetScanLine(p1, 0);
   894 		//Alpha bitmap
   895 		alphaBmp = new (ELeave) CFbsBitmap;
   896 		CleanupStack::PushL(alphaBmp);
   897 		User::LeaveIfError(alphaBmp->Create(TSize(20, 1), EGray256));
   898 		TPtr8 p2(alphaBmpData, 20, 20);
   899 		alphaBmp->SetScanLine(p2, 0);
   900 		//Do BitBltMasked()
   901 		iGc->BitBltMasked(TPoint(20, 20), srcBmp, TRect(10, 0, 100, 1), alphaBmp, EFalse);
   902 		iDevice->Update();
   903 		iGc->SetOrientation(CFbsBitGc::EGraphicsOrientationNormal);
   904 		//
   905 		CleanupStack::PopAndDestroy(alphaBmp);
   906 		CleanupStack::PopAndDestroy(srcBmp);
   907 		}
   908 	}
   909 
   910 TUint32 AlphaBlend(TUint32 aDestPixel, TUint32 aSrcPixel, TUint8 aMask)
   911  	{
   912  	TUint32 dr = (aDestPixel & 0x00FF0000) >> 16;
   913  	TUint32 dg = (aDestPixel & 0x0000FF00) >> 8;
   914  	TUint32 db = aDestPixel & 0x000000FF;
   915  	
   916  	TUint32 sr = (aSrcPixel & 0x00FF0000) >> 16;
   917  	TUint32 sg = (aSrcPixel & 0x0000FF00) >> 8;
   918  	TUint32 sb = aSrcPixel & 0x000000FF;
   919  	
   920  	TUint32 rr = (aMask * sr)/255 + ((0xFF - aMask) * dr)/255;
   921  	TUint32 rg = (aMask * sg)/255 + ((0xFF - aMask) * dg)/255;
   922  	TUint32 rb = (aMask * sb)/255 + ((0xFF - aMask) * db)/255;
   923  	
   924  	return(rr << 16 | rg << 8 | rb | 0xff000000);
   925  	}
   926  
   927 inline TUint32 OptimizedBlend32(TInt aPrimaryRed,TInt aPrimaryGreen,TInt aPrimaryBlue,TUint32 aSecondary,TUint8 aAlphaValue)
   928  	{
   929   
   930   	if(aAlphaValue == 0xff)
   931  		{
   932  		return (aPrimaryBlue + (aPrimaryGreen<<8) + (aPrimaryRed<<16)) | 0xff000000;
   933   		}
   934   	else
   935   		{
   936   		const TUint32 alphaValue = (aAlphaValue << 8) + aAlphaValue;
   937   
   938   		const TInt r2 = (aSecondary & 0x00ff0000) >> 16;
   939   		const TInt g2 = (aSecondary & 0x0000ff00) >> 8;
   940   		const TInt b2 = aSecondary & 0x000000ff;
   941   
   942   		const TInt r3 = ((alphaValue * (aPrimaryRed   - r2)) >> 16) + r2;
   943  		const TInt g3 = ((alphaValue * (aPrimaryGreen - g2)) >> 16) + g2;
   944  		const TInt b3 = ((alphaValue * (aPrimaryBlue  - b2)) >> 16) + b2;
   945  
   946  		return (b3 & 0xFF) | ((g3<<8) & 0xFF00) | ((r3<<16) & 0xFF0000) | 0xFF000000;
   947   		}
   948   	}
   949 
   950 
   951 /**
   952   @SYMTestCaseID GRAPHICS-BITGDI-0085
   953  
   954   @SYMDEF             
   955 
   956   @SYMTestCaseDesc 
   957    
   958   @SYMTestPriority High
   959 
   960   @SYMTestStatus Implemented
   961 
   962   @SYMTestActions 
   963  
   964   @SYMTestExpectedResults 
   965 */  	
   966 // This tests the correctness of the results of alpha-blending with EColor16MA
   967 void CTAlphaBlending::TestAlphaBlendCorrect(TDisplayMode /* aScreenMode */, TDisplayMode /* aBitmapMode */)
   968  	{
   969  	// test data
   970  	TUint32 top = 0xFFCCEE55;
   971  	TUint32 beneath = 0xFFEEAA66;
   972  	TUint8 alpha = 0xF0;
   973  	
   974  	TInt maxDiff = 0;
   975  	
   976  	for(TInt i = 0; i < 100000; i++)
   977  		{
   978  		top = Math::Random();
   979  		beneath = Math::Random();
   980  		alpha = Math::Random();
   981  		TUint32 res1 = AlphaBlend(beneath, top, alpha);
   982  		TUint32 res2 = OptimizedBlend32((top >> 16) & 0xFF,(top >>8) & 0xFF,(top & 0xFF),beneath, alpha);
   983  		
   984  		if(res1 != res2)
   985  			{
   986  			TInt diff = 0;
   987  			TInt diff1 = res1 & 0xFF;
   988  			TInt diff2 = res2 & 0xFF;
   989  			
   990  			diff = diff1 - diff2;
   991  			
   992  			if(diff < 0)
   993  				diff*=-1;
   994  				
   995  			if(diff > maxDiff)
   996  				maxDiff = diff;
   997  				
   998  			diff1 = (res1 >> 8) & 0xFF;
   999  			diff2 = (res2 >> 8) & 0xFF;
  1000  			
  1001  			diff = diff1 - diff2;
  1002  			
  1003  			if(diff < 0)
  1004  				diff*=-1;
  1005  				
  1006  			if(diff > maxDiff)
  1007  				maxDiff = diff;
  1008  			
  1009  			
  1010  			diff1 = (res1 >> 16) & 0xFF;
  1011  			diff2 = (res2 >> 16) & 0xFF;
  1012  			
  1013  			diff = diff1 - diff2;
  1014  			
  1015  			if(diff < 0)
  1016  				diff*=-1;
  1017  				
  1018  			if(diff > maxDiff)
  1019  				maxDiff = diff;
  1020  			
  1021  			}
  1022  		}
  1023 	
  1024  	INFO_PRINTF1(_L("Results:"));
  1025  		
  1026  	if(maxDiff)
  1027  		INFO_PRINTF2(_L("Max Diff = %i"), maxDiff);
  1028  	else
  1029  		INFO_PRINTF1(_L("Results are identical"));
  1030   	}
  1031 
  1032 //--------------
  1033 __CONSTRUCT_STEP__(AlphaBlending)
  1034 
  1035 void CTAlphaBlendingStep::TestSetupL()
  1036 	{
  1037 	}
  1038