graphicsdeviceinterface/bitgdi/tbit/TAlphaBlend.cpp
changeset 0 5d03bc08d59c
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     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