graphicsdeviceinterface/screendriver/tsrc/TLLD.CPP
changeset 0 5d03bc08d59c
child 33 25f95128741d
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 // Copyright (c) 1997-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 <e32math.h>
       
    17 #include <hal.h>
       
    18 #include <bitdraw.h>
       
    19 #include "Tlld.h"
       
    20 #include <bitdrawinterfaceid.h>
       
    21 #include <bmalphablend.h>
       
    22 #include <graphics/lookuptable.h>
       
    23 #include <graphics/blendingalgorithms.h>
       
    24 #include <graphics/gdi/gdiconsts.h>
       
    25 #include "BMDRAW.H"
       
    26 
       
    27 GLREF_C TInt ByteSize(TDisplayMode aDisplayMode,TInt aWidth);
       
    28 
       
    29 TInt KNumberDisplayModes1 = sizeof (TestDisplayMode1) / sizeof (TestDisplayMode1[0]);
       
    30 
       
    31 #if defined(SYMBIAN_USE_FAST_FADING)
       
    32 const TBool KFastFading = ETrue;
       
    33 #else
       
    34 const TBool KFastFading = EFalse;
       
    35 #endif
       
    36 
       
    37 //these are for EColor16MAP testing
       
    38 const TInt KInaccuracyLimit = 15;
       
    39 const TInt KUserDispModes = 2;
       
    40 //The array below is used in CTLowLevel::TestWriteRGBAlpha() to step through display modes,
       
    41 //to ensure adequate test coverage.
       
    42 const TDisplayMode UserDisplayModes[KUserDispModes] =
       
    43 	{
       
    44 	ENone,
       
    45 	EColor16MAP,
       
    46 	};
       
    47 const TInt KMaskFill =3;
       
    48 const TUint32 MaskFill[KMaskFill] =
       
    49 	{
       
    50 	0x00,
       
    51 	0xff,
       
    52 	0x3A,
       
    53 	};
       
    54 
       
    55 TInt DisplayMode2Index(TDisplayMode aMode)
       
    56 	{
       
    57 	TInt i;
       
    58 	for(i=0;i<KNumDispModes;i++)
       
    59 		{
       
    60 		if(TestDisplayMode[i] == aMode)
       
    61 			break;
       
    62 		}
       
    63 	return i;
       
    64 	}
       
    65 
       
    66 inline TInt AbsDiff(TInt aValue1, TInt aValue2)
       
    67 	{
       
    68 	return (aValue1 < aValue2) ? (aValue2-aValue1) : (aValue1-aValue2);
       
    69 	}
       
    70 
       
    71 //CTLowLevel implementation is shared between TLLD and TLLD2 test apps.
       
    72 //The change was made because the original TLLD test app took too much time (over 0.5 hour)
       
    73 //and usually was terminated with a TIMEOUT on LUBBOCK device.
       
    74 CTLowLevel::CTLowLevel(CTestStep* aStep):
       
    75 	CTGraphicsBase(aStep),
       
    76 	iDrawDevice(NULL),
       
    77 	iBits(NULL),
       
    78 	iBuf(NULL),
       
    79 	iDispMode(ENone),
       
    80 	iUserDispMode(ENone),
       
    81 	iOrientation(CFbsDrawDevice::EOrientationNormal),
       
    82 	iSize(TSize(0,0)),
       
    83 	iLongWidth(0),
       
    84 	iTestNo(0),
       
    85 	iIteration(0),
       
    86 	iReportIteration(0),
       
    87 	iTotalReportIterations(0),
       
    88 	iFuzzyMatch(EFalse),
       
    89 	iBlendTestColors(ETrue),
       
    90 	iUseFastFade(EFalse)
       
    91 	{
       
    92 	iColorConvertor[ENone] = &iNullConvertor;
       
    93 	iColorConvertor[EGray2] = &iGray2Convertor;
       
    94 	iColorConvertor[EGray4] = &iGray4Convertor;
       
    95 	iColorConvertor[EGray16] = &iGray16Convertor;
       
    96 	iColorConvertor[EGray256] = &iGray256Convertor;
       
    97 	iColorConvertor[EColor16] = &iColor16Convertor;
       
    98 	iColorConvertor[EColor256] = &iColor256Convertor;
       
    99 	iColorConvertor[EColor4K] = &iColor4KConvertor;
       
   100 	iColorConvertor[EColor64K] = &iColor64KConvertor;
       
   101 	iColorConvertor[EColor16M] = &iColor16MConvertor;
       
   102 	iColorConvertor[ERgb] = &iColor16MConvertor;
       
   103 	iColorConvertor[EColor16MU] = &iColor16MUConvertor;
       
   104 	iColorConvertor[EColor16MA] = &iColor16MAConvertor;
       
   105 	iColorConvertor[EColor16MAP] = &iColor16MAPConvertor;
       
   106 	iOrientation = CFbsDrawDevice::EOrientationNormal;
       
   107 	iOrientationEnd = CFbsDrawDevice::EOrientationRotated90;
       
   108 	}
       
   109 
       
   110 CTLowLevel::~CTLowLevel()
       
   111 	{
       
   112 	Reset();
       
   113 	}
       
   114 
       
   115 void CTLowLevel::Reset()
       
   116 	{
       
   117 	delete iDrawDevice;
       
   118 	iDrawDevice = NULL;
       
   119 
       
   120 	delete iBits;
       
   121 	iBits = NULL;
       
   122 	delete iBuf;
       
   123 	iBuf = NULL;
       
   124 	iDispMode = ENone;
       
   125 	iSize.SetSize(0,0);
       
   126 	iLongWidth = 0;
       
   127 	}
       
   128 
       
   129 void CTLowLevel::RunTestCaseL(TInt aCurTestCase)
       
   130 	{
       
   131     ((CTLowLevelStep*)iStep)->SetTestStepID(KUnknownSYMTestCaseIDName);
       
   132 	switch(aCurTestCase)
       
   133 		{
       
   134 	case 1:
       
   135 		INFO_PRINTF1(_L("Bitmap device EGray2"));
       
   136 /**
       
   137 	@SYMTestCaseID GRAPHICS-SCREENDRIVER-0004
       
   138 */
       
   139 		((CTLowLevelStep*)iStep)->SetTestStepID(_L("GRAPHICS-SCREENDRIVER-0004"));
       
   140 		TestBitmapDraw(EGray2,TSize(128,100));
       
   141 		break;
       
   142 	case 2:
       
   143 		INFO_PRINTF1(_L("Bitmap device EGray4"));
       
   144 /**
       
   145 	@SYMTestCaseID GRAPHICS-SCREENDRIVER-0005
       
   146 */
       
   147 		((CTLowLevelStep*)iStep)->SetTestStepID(_L("GRAPHICS-SCREENDRIVER-0005"));
       
   148 		TestBitmapDraw(EGray4,TSize(112,100));
       
   149 		break;
       
   150 	case 3:
       
   151 		INFO_PRINTF1(_L("Bitmap device EGray16"));
       
   152 /**
       
   153 	@SYMTestCaseID GRAPHICS-SCREENDRIVER-0006
       
   154 */
       
   155 		((CTLowLevelStep*)iStep)->SetTestStepID(_L("GRAPHICS-SCREENDRIVER-0006"));
       
   156 		TestBitmapDraw(EGray16,TSize(104,100));
       
   157 		break;
       
   158 	case 4:
       
   159 		INFO_PRINTF1(_L("Bitmap device EGray256"));
       
   160 /**
       
   161 	@SYMTestCaseID GRAPHICS-SCREENDRIVER-0007
       
   162 */
       
   163 		((CTLowLevelStep*)iStep)->SetTestStepID(_L("GRAPHICS-SCREENDRIVER-0007"));
       
   164 		TestBitmapDraw(EGray256,TSize(104,100));
       
   165 		break;
       
   166 	case 5:
       
   167 		INFO_PRINTF1(_L("Bitmap device EColor16"));
       
   168 /**
       
   169 	@SYMTestCaseID GRAPHICS-SCREENDRIVER-0008
       
   170 */
       
   171 		((CTLowLevelStep*)iStep)->SetTestStepID(_L("GRAPHICS-SCREENDRIVER-0008"));
       
   172 		TestBitmapDraw(EColor16,TSize(104,100));
       
   173 		break;
       
   174 	case 6:
       
   175 		INFO_PRINTF1(_L("Bitmap device EColor256"));
       
   176 /**
       
   177 	@SYMTestCaseID GRAPHICS-SCREENDRIVER-0009
       
   178 */
       
   179 		((CTLowLevelStep*)iStep)->SetTestStepID(_L("GRAPHICS-SCREENDRIVER-0009"));
       
   180 		TestBitmapDraw(EColor256,TSize(102,100));
       
   181 		break;
       
   182 	case 7:
       
   183 		INFO_PRINTF1(_L("Bitmap device EColor4K"));
       
   184 /**
       
   185 	@SYMTestCaseID GRAPHICS-SCREENDRIVER-0010
       
   186 */
       
   187 		((CTLowLevelStep*)iStep)->SetTestStepID(_L("GRAPHICS-SCREENDRIVER-0010"));
       
   188 		TestBitmapDraw(EColor4K,TSize(100,100));
       
   189 		break;
       
   190 	case 8:
       
   191 		INFO_PRINTF1(_L("Bitmap device EColor64K"));
       
   192 /**
       
   193 	@SYMTestCaseID GRAPHICS-SCREENDRIVER-0011
       
   194 */
       
   195 		((CTLowLevelStep*)iStep)->SetTestStepID(_L("GRAPHICS-SCREENDRIVER-0011"));
       
   196 		TestBitmapDraw(EColor64K,TSize(100,100));
       
   197 		break;
       
   198 	case 9:
       
   199 		INFO_PRINTF1(_L("Bitmap device EColor16M"));
       
   200 /**
       
   201 	@SYMTestCaseID GRAPHICS-SCREENDRIVER-0012
       
   202 */
       
   203 		((CTLowLevelStep*)iStep)->SetTestStepID(_L("GRAPHICS-SCREENDRIVER-0012"));
       
   204 		TestBitmapDraw(EColor16M,TSize(102,100));
       
   205 		break;
       
   206 	case 10:
       
   207 		INFO_PRINTF1(_L("Bitmap device EColor16MU"));
       
   208 		iFuzzyMatch=ETrue;
       
   209 /**
       
   210 	@SYMTestCaseID GRAPHICS-SCREENDRIVER-0013
       
   211 */
       
   212 		((CTLowLevelStep*)iStep)->SetTestStepID(_L("GRAPHICS-SCREENDRIVER-0013"));
       
   213 		TestBitmapDraw(EColor16MU,TSize(102,100));
       
   214 		iFuzzyMatch=EFalse;
       
   215 		break;
       
   216 	case 11:
       
   217 		INFO_PRINTF1(_L("Bitmap device EColor16MA"));
       
   218 /**
       
   219 	@SYMTestCaseID GRAPHICS-SCREENDRIVER-0014
       
   220 */
       
   221 		((CTLowLevelStep*)iStep)->SetTestStepID(_L("GRAPHICS-SCREENDRIVER-0014"));
       
   222 		TestBitmapDraw(EColor16MA,TSize(102,100));
       
   223 		break;
       
   224 	case 12:
       
   225 		INFO_PRINTF1(_L("Bitmap device EColor16MAP"));
       
   226 		iFuzzyMatch=ETrue;
       
   227 /**
       
   228 	@SYMTestCaseID GRAPHICS-SCREENDRIVER-0015
       
   229 */
       
   230 		((CTLowLevelStep*)iStep)->SetTestStepID(_L("GRAPHICS-SCREENDRIVER-0015"));
       
   231 		TestBitmapDraw(EColor16MAP,TSize(102,100));
       
   232 		iFuzzyMatch=EFalse;
       
   233 		break;
       
   234 	case 13:
       
   235 		INFO_PRINTF1(_L("User display mode mapping"));
       
   236 /**
       
   237 	@SYMTestCaseID GRAPHICS-SCREENDRIVER-0016
       
   238 */
       
   239 		((CTLowLevelStep*)iStep)->SetTestStepID(_L("GRAPHICS-SCREENDRIVER-0016"));
       
   240 		TestUserDisplayModeMapping();
       
   241 		((CTLowLevelStep*)iStep)->RecordTestResultL();
       
   242 		break;
       
   243 	default:
       
   244 		if(iOrientation <= iOrientationEnd)
       
   245 			{
       
   246 /**
       
   247 	@SYMTestCaseID GRAPHICS-SCREENDRIVER-0017
       
   248 */
       
   249 			((CTLowLevelStep*)iStep)->SetTestStepID(_L("GRAPHICS-SCREENDRIVER-0017"));
       
   250 			INFO_PRINTF2(_L("Screen device : %S"), &DisplayModeNames1[iCurScreenDeviceModeIndex]);
       
   251 			TDisplayMode display = TestDisplayMode1[iCurScreenDeviceModeIndex++];
       
   252 			TestScreenDrawL(display);
       
   253 			if(iCurScreenDeviceModeIndex >= KNumberDisplayModes1)
       
   254 				{
       
   255 				iCurScreenDeviceModeIndex = 0;
       
   256 				iOrientation ++;
       
   257 				}
       
   258 			}
       
   259 		else
       
   260 			{
       
   261             ((CTLowLevelStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName);
       
   262 			((CTLowLevelStep*)iStep)->CloseTMSGraphicsStep();
       
   263 			TestComplete();
       
   264 			((CTLowLevelStep*)iStep)->RecordTestResultL();
       
   265 			}
       
   266 		break;
       
   267 		}
       
   268 	}
       
   269 
       
   270 /* this function is used for likeness matching, using a fixed inaccuracy */
       
   271 void CTLowLevel::CheckMatch(TUint32 aFirst,TUint32 aSecond)
       
   272 	{
       
   273 	TBool fail=EFalse;
       
   274 	if (iFuzzyMatch==EFalse)
       
   275 		fail|=Check(aFirst==aSecond);
       
   276 	else
       
   277 		{
       
   278 		TUint8* val1=static_cast<TUint8*>(static_cast<void*>(&aFirst));
       
   279 		TUint8* val2=static_cast<TUint8*>(static_cast<void*>(&aSecond));
       
   280 		fail|=Check(AbsDiff(*val1,*val2)<KInaccuracyLimit);
       
   281 		fail|=Check(AbsDiff(*(val1+1),*(val2+1))<KInaccuracyLimit);
       
   282 		fail|=Check(AbsDiff(*(val1+2),*(val2+2))<KInaccuracyLimit);
       
   283 		fail|=Check(AbsDiff(*(val1+3),*(val2+3))<KInaccuracyLimit);
       
   284 		}
       
   285 	if (fail)
       
   286 		{
       
   287 		_LIT(KLog,"The values 0x%x and 0x%x don't match, fuzzyMatch=%d (limit=%d)");
       
   288 		INFO_PRINTF5(KLog,aFirst,aSecond,iFuzzyMatch,KInaccuracyLimit);
       
   289 		}
       
   290 	}
       
   291 
       
   292 void CTLowLevel::TestScreenDrawL(TDisplayMode aDisplayMode)
       
   293 	{
       
   294 	TUint startTime=User::TickCount();
       
   295 
       
   296 	Reset();
       
   297 
       
   298 	iDispMode = aDisplayMode;
       
   299 
       
   300 	INFO_PRINTF1(_L("\n"));
       
   301 	INFO_PRINTF2(_L("Testing Screen driver \"%S\""), &(DisplayModeNames[::DisplayMode2Index(aDisplayMode)]));
       
   302 	INFO_PRINTF1(_L("\r\n"));
       
   303 	TInt address = NULL;
       
   304 	TSize size(0,0);
       
   305 
       
   306 	User::LeaveIfError(HAL::Get(KDefaultScreenNo, HALData::EDisplayMemoryAddress,address));
       
   307 	User::LeaveIfError(HAL::Get(KDefaultScreenNo, HALData::EDisplayXPixels,size.iWidth));
       
   308 	User::LeaveIfError(HAL::Get(KDefaultScreenNo, HALData::EDisplayYPixels,size.iHeight));
       
   309 	ASSERT(size.iWidth > 0 && size.iHeight > 0 && address != NULL);
       
   310 
       
   311 	TPckgBuf<TScreenInfoV01> info;
       
   312 	info().iScreenAddressValid = ETrue;
       
   313 	info().iScreenAddress = REINTERPRET_CAST(TAny*,address);
       
   314 	info().iScreenSize = size;
       
   315 
       
   316 	TRAPD(ret,iDrawDevice = CFbsDrawDevice::NewScreenDeviceL(info(),aDisplayMode));
       
   317 
       
   318 	if (ret == KErrNotSupported)
       
   319 		{
       
   320 		INFO_PRINTF1(_L("Not supported\r\n"));
       
   321 		return;
       
   322 		}
       
   323 	else if (ret != KErrNone)
       
   324 		User::Panic(_L("Draw device create"),ret);
       
   325 
       
   326 	iDrawDevice->InitScreen();
       
   327 	iDrawDevice->SetDisplayMode(iDrawDevice);
       
   328 	iDrawDevice->SetAutoUpdate(EFalse);
       
   329 	TBool orientation[4];
       
   330 	iDrawDevice->OrientationsAvailable(orientation);
       
   331 
       
   332 	TBool orientationSupported = iDrawDevice->SetOrientation(CFbsDrawDevice::TOrientation(iOrientation));
       
   333 	if (orientationSupported)
       
   334 		{
       
   335 		Check(orientation[iOrientation]);
       
   336 		if (iOrientation & 1)
       
   337 			iSize = TSize(size.iHeight,size.iWidth);
       
   338 		else
       
   339 			iSize = size;
       
   340 		iLongWidth = LongWidth(iSize.iWidth,aDisplayMode);
       
   341 		Test();
       
   342 		}
       
   343 	else
       
   344 		{
       
   345 		Check(!orientation[iOrientation]);
       
   346 		INFO_PRINTF1(_L("Orientation not supported\r\n"));
       
   347 		}
       
   348 
       
   349 	INFO_PRINTF2(_L("Testing time=%d"), (User::TickCount() - startTime) * 100 / 64);
       
   350 	}
       
   351 
       
   352 void CTLowLevel::TestBitmapDraw(TDisplayMode aDisplayMode,const TSize& aSize)
       
   353 	{
       
   354 	TUint startTime=User::TickCount();
       
   355 	Reset();
       
   356 	iDispMode = aDisplayMode;
       
   357 	iSize = aSize;
       
   358 	iLongWidth = LongWidth(aSize.iWidth,aDisplayMode);
       
   359 	TSize size(0,0);
       
   360 	INFO_PRINTF1(KNullDesC);
       
   361 
       
   362 	const TInt byteSize=ByteSize()*iSize.iHeight;
       
   363 	_LIT(KNoMem,"Not enough memory for bitmap bits");
       
   364 	iBits = new TUint8[byteSize];
       
   365 	if(!iBits)
       
   366 		{
       
   367 		User::Panic(KNoMem,KErrNoMemory);
       
   368 		}
       
   369 
       
   370 	iBuf = new TUint32[byteSize];
       
   371 	if(!iBuf)
       
   372 		{
       
   373 		User::Panic(KNoMem,KErrNoMemory);
       
   374 		}
       
   375 
       
   376 	TPckgBuf<TScreenInfoV01> info;
       
   377 	info().iScreenSize = aSize;
       
   378 	info().iScreenAddress = NULL;
       
   379 	info().iScreenAddressValid = ETrue;
       
   380 
       
   381 	TRAPD(ret, iDrawDevice = CFbsDrawDevice::NewBitmapDeviceL(info(), aDisplayMode, ByteSize() ));
       
   382 	if (ret == KErrNotSupported)
       
   383 		{
       
   384 		INFO_PRINTF1(_L("Not supported\r\n"));
       
   385 		return;
       
   386 		}
       
   387 	else if (ret != KErrNone)
       
   388 	{
       
   389 		User::Panic(_L("Draw device create"),ret);
       
   390 	}
       
   391 	iDrawDevice->SetAutoUpdate(EFalse);
       
   392 	//Initialize the iDrowDevice object, if successful val=KErrNone
       
   393 	TInt val=iDrawDevice->InitScreen();
       
   394 	TEST(val==KErrNone);
       
   395 	iDrawDevice->CFbsDrawDevice::SetBits(iBits);
       
   396 	iDrawDevice->CFbsDrawDevice::ShadowBuffer(10,iBuf);
       
   397 	iDrawDevice->CFbsDrawDevice::SetUserDisplayMode(iDispMode);
       
   398 	iDrawDevice->SetDisplayMode(iDrawDevice);
       
   399 	iDrawDevice->Update();
       
   400 	iDrawDevice->SetUserDisplayMode(iDispMode);
       
   401 	iDrawDevice->SetBits(iBits);
       
   402 	Test();
       
   403 	TBool orientation[4];
       
   404 	iDrawDevice->OrientationsAvailable(orientation);
       
   405 	TBool orientationSupported = iDrawDevice->SetOrientation(CFbsDrawDevice::TOrientation(iOrientation));
       
   406 	if (orientationSupported)
       
   407 		{
       
   408 		Check(orientation[iOrientation]);
       
   409 		if (iOrientation & 1)
       
   410 			iSize = TSize(size.iHeight,size.iWidth);
       
   411 		else
       
   412 			iSize = size;
       
   413 		iLongWidth = LongWidth(iSize.iWidth,aDisplayMode);
       
   414 		}
       
   415 	else
       
   416 		{
       
   417 		Check(!orientation[iOrientation]);
       
   418 		INFO_PRINTF1(_L("Orientation not supported\r\n"));
       
   419 		}
       
   420 	INFO_PRINTF2(_L("Testing time=%d"), (User::TickCount() - startTime) * 100 / 64);
       
   421 	}
       
   422 
       
   423 TInt RgbComponent(TRgb aRgb, TInt aRgbIndex)
       
   424 	{
       
   425 	return(aRgbIndex==0?aRgb.Red():(aRgbIndex==1?aRgb.Green():aRgb.Blue()));
       
   426 	}
       
   427 	
       
   428 TBool CheckNormalizedValue(TRgb aReadCol, TRgb aNormalizedCol1, TRgb aNormalizedCol2, TRgb aNormalizedCol3, TRgb aNormalizedCol4, TInt aRgbIndex)
       
   429 	{
       
   430 	
       
   431 	const TInt KErrorMargin=5;
       
   432 	TInt minCol=Min(RgbComponent(aNormalizedCol1,aRgbIndex),
       
   433 					Min(RgbComponent(aNormalizedCol2,aRgbIndex),
       
   434 						Min(RgbComponent(aNormalizedCol3,aRgbIndex),RgbComponent(aNormalizedCol4,aRgbIndex))))-KErrorMargin;
       
   435 	TInt maxCol=Max(RgbComponent(aNormalizedCol1,aRgbIndex),
       
   436 					Max(RgbComponent(aNormalizedCol2,aRgbIndex),
       
   437 						Max(RgbComponent(aNormalizedCol3,aRgbIndex),RgbComponent(aNormalizedCol4,aRgbIndex))))+KErrorMargin;
       
   438 	TInt readComponent=RgbComponent(aReadCol,aRgbIndex);
       
   439 	return(readComponent>=minCol && readComponent<=maxCol);
       
   440 	}
       
   441 
       
   442 void CTLowLevel::CheckNormalizedRgb(TRgb aReadRgb, TRgb aCheckRgb, TDisplayMode aDevDisplayMode, TDisplayMode aUserDisplayMode, TBool aWriteRgbAlphaLine)
       
   443 	{
       
   444 	TRgb normalized1=aCheckRgb;
       
   445 	Normalize(normalized1,aUserDisplayMode);
       
   446 	if (aDevDisplayMode==EColor16MAP)
       
   447 		{
       
   448 		const TInt KNormalizeErrorMargin=3;
       
   449 		TRgb normalizedPMA1=aCheckRgb;
       
   450 // Allow error margin for blending errors before calculating value normalized to user display mode
       
   451 		normalizedPMA1.SetRed(Min(0xFF,normalizedPMA1.Red()+KNormalizeErrorMargin));
       
   452 		normalizedPMA1.SetGreen(Min(0xFF,normalizedPMA1.Green()+KNormalizeErrorMargin));
       
   453 		normalizedPMA1.SetBlue(Min(0xFF,normalizedPMA1.Blue()+KNormalizeErrorMargin));
       
   454 //
       
   455 		Normalize(normalizedPMA1,aUserDisplayMode);
       
   456 		TRgb normalizedPMA3=normalizedPMA1;
       
   457 		normalizedPMA1=TRgb::Color16MAP(normalizedPMA1.Color16MAP());
       
   458 		TRgb normalizedPMA2=aCheckRgb;
       
   459 		normalizedPMA2=TRgb::Color16MAP(normalizedPMA2.Color16MAP());
       
   460 		normalizedPMA2.SetRed(Max(0,normalizedPMA2.Red()-KNormalizeErrorMargin));
       
   461 		normalizedPMA2.SetGreen(Max(0,normalizedPMA2.Green()-KNormalizeErrorMargin));
       
   462 		normalizedPMA2.SetBlue(Max(0,normalizedPMA2.Blue()-KNormalizeErrorMargin));
       
   463 		Normalize(normalizedPMA2,aUserDisplayMode);
       
   464 		TEST(CheckNormalizedValue(aReadRgb,normalizedPMA1,normalizedPMA2,normalizedPMA3,normalized1,0) &&
       
   465 				CheckNormalizedValue(aReadRgb,normalizedPMA1,normalizedPMA2,normalizedPMA3,normalized1,1) &&
       
   466 				CheckNormalizedValue(aReadRgb,normalizedPMA1,normalizedPMA2,normalizedPMA3,normalized1,2));
       
   467 		}
       
   468 	else
       
   469 		{
       
   470 		if (aDevDisplayMode==EColor64K && aWriteRgbAlphaLine)
       
   471 			{
       
   472 	// In EColor64K the WriteRgbAlphaLine code maps to native display mode first, before mapping to
       
   473 	// user mode then back again to device display mode. So use normalized2 to check for that case
       
   474 			TRgb normalized2=aCheckRgb;
       
   475 			Normalize(normalized2,aDevDisplayMode);
       
   476 			Normalize(normalized2,aUserDisplayMode);
       
   477 			Normalize(normalized2,aDevDisplayMode);
       
   478 			TEST(aReadRgb.Color16MU()==normalized2.Color16MU());
       
   479 			}
       
   480 		else
       
   481 			{
       
   482 			Normalize(normalized1,aDevDisplayMode);
       
   483 			TEST(aReadRgb.Color16MU()==normalized1.Color16MU());
       
   484 			}
       
   485 		}
       
   486 	}
       
   487 	
       
   488 void CTLowLevel::PrepareDestPixel(TDisplayMode aDevDisplayMode, TRgb& aRgb, TInt aDstAlpha)
       
   489 	{
       
   490 	CGraphicsContext::TDrawMode drawMode;
       
   491 	if (aDevDisplayMode==EColor16MAP)
       
   492 		{
       
   493 		aRgb.SetAlpha(aDstAlpha);
       
   494 		drawMode=CGraphicsContext::EDrawModeWriteAlpha;
       
   495 		}
       
   496 	else
       
   497 		{
       
   498 		aRgb.SetAlpha(0xFF);
       
   499 		drawMode=CGraphicsContext::EDrawModePEN;
       
   500 		}
       
   501 	iDrawDevice->WriteRgbMulti(0,0,1,1,aRgb,drawMode);
       
   502 	}
       
   503 
       
   504 void CTLowLevel::CheckMappedRgb(TDisplayMode aDevDisplayMode, TDisplayMode aUserDisplayMode, TRgb aRgb)
       
   505 	{
       
   506 	const TInt KMaxAlphaModes=5;
       
   507 	TInt alphaModeValues[KMaxAlphaModes]={0xFF,0xC0,0x80,0x40,0};
       
   508 	TInt dstAlphaModeCount=aDevDisplayMode==EColor16MAP?KMaxAlphaModes:1;
       
   509 	for(TInt dstAlphaMode=0;dstAlphaMode<dstAlphaModeCount;dstAlphaMode++)
       
   510 		{
       
   511 		TInt dstAlpha=alphaModeValues[dstAlphaMode];
       
   512 		for(TInt alphaMode=0;alphaMode<KMaxAlphaModes;alphaMode++)
       
   513 			{
       
   514 			TInt alpha=alphaModeValues[alphaMode];
       
   515 			if ((aUserDisplayMode==EColor16 || aUserDisplayMode==EColor256) && (alpha!=0xFF || dstAlpha!=0xFF))
       
   516 				continue;	// Mapping to EColor16 or EColor256 with fuzzy blends and PMA losses impossible to check for accurately
       
   517 			PrepareDestPixel(aDevDisplayMode,aRgb,dstAlpha);
       
   518 			aRgb.SetAlpha(alpha);
       
   519 			iDrawDevice->WriteRgb(0,0,aRgb,CGraphicsContext::EDrawModePEN);
       
   520 			TRgb readRgb=iDrawDevice->ReadPixel(0,0);
       
   521 			CheckNormalizedRgb(readRgb,aRgb,aDevDisplayMode,aUserDisplayMode,EFalse);
       
   522 //
       
   523 			PrepareDestPixel(aDevDisplayMode,aRgb,dstAlpha);
       
   524 			iDrawDevice->WriteRgbMulti(0,0,1,1,aRgb,CGraphicsContext::EDrawModePEN);
       
   525 			readRgb=iDrawDevice->ReadPixel(0,0);
       
   526 			CheckNormalizedRgb(readRgb,aRgb,aDevDisplayMode,aUserDisplayMode,EFalse);
       
   527 //
       
   528 			PrepareDestPixel(aDevDisplayMode,aRgb,dstAlpha);
       
   529 			TUint32 writeBuffer[1];
       
   530 			writeBuffer[0]=aRgb.Internal();
       
   531 			TUint8 mask[1]={0xFF};
       
   532 			iDrawDevice->WriteRgbAlphaLine(0,0,1,(TUint8*)writeBuffer,mask,CGraphicsContext::EDrawModePEN);
       
   533 			readRgb=iDrawDevice->ReadPixel(0,0);
       
   534 			CheckNormalizedRgb(readRgb,aRgb,aDevDisplayMode,aUserDisplayMode,ETrue);
       
   535 			}
       
   536 		}
       
   537 	}
       
   538 
       
   539 void CTLowLevel::TestUserDisplayModeMapping()
       
   540 	{
       
   541 	TInt address = NULL;
       
   542 	TSize size;
       
   543 	User::LeaveIfError(HAL::Get(KDefaultScreenNo, HALData::EDisplayMemoryAddress,address));
       
   544 	User::LeaveIfError(HAL::Get(KDefaultScreenNo, HALData::EDisplayXPixels,size.iWidth));
       
   545 	User::LeaveIfError(HAL::Get(KDefaultScreenNo, HALData::EDisplayYPixels,size.iHeight));
       
   546 	ASSERT(size.iWidth > 0 && size.iHeight > 0 && address != NULL);
       
   547 
       
   548 	TPckgBuf<TScreenInfoV01> info;
       
   549 	info().iScreenAddressValid = ETrue;
       
   550 	info().iScreenAddress = REINTERPRET_CAST(TAny*,address);
       
   551 	info().iScreenSize = size;
       
   552 //
       
   553 	for (TInt nDispModeDev = 0; nDispModeDev < KNumDispModes; nDispModeDev++)
       
   554 		{
       
   555 		TDisplayMode dispModeDev = TestDisplayMode[nDispModeDev];
       
   556 		if (!TDisplayModeUtils::IsDisplayModeColor(dispModeDev) || TDisplayModeUtils::NumDisplayModeColors(dispModeDev)<65536)
       
   557 			continue; // Older modes have their quirks we don't want to mess with
       
   558 		Reset();
       
   559 		TRAPD(ret,iDrawDevice = CFbsDrawDevice::NewScreenDeviceL(info(),dispModeDev));
       
   560 		if (ret == KErrNotSupported)
       
   561 			continue;
       
   562 		for (TInt nDispMode = 0; nDispMode < KNumDispModes; nDispMode++)
       
   563 			{
       
   564 			TDisplayMode userDispMode = TestDisplayMode[nDispMode];
       
   565 			INFO_PRINTF3(_L("Testing devMode=%d, userMode=%d"), dispModeDev, userDispMode);
       
   566 			iDrawDevice->SetUserDisplayMode(userDispMode);
       
   567 			TUint rgbVal=0;
       
   568 			FOREVER
       
   569 				{
       
   570 				CheckMappedRgb(dispModeDev,userDispMode,rgbVal);
       
   571 				if (rgbVal==0xFFFFFF)
       
   572 					break;
       
   573 				rgbVal+=0x010305;
       
   574 				if (rgbVal>0xFFFFFF)	// We want to make sure we test 0xFFFFFF as a special case
       
   575 					rgbVal=0xFFFFFF;
       
   576 				}
       
   577 			}
       
   578 		}
       
   579 	}
       
   580 
       
   581 void CTLowLevel::Test()
       
   582 	{
       
   583 	_LIT(KOrientation,"Orientation: %S");
       
   584 	TBuf<32> buf;
       
   585 	buf.Format(KOrientation,&RotationName(iOrientation));
       
   586 	INFO_PRINTF1(buf);
       
   587 
       
   588 	iTestNo = 1;
       
   589 	iIteration = 0;
       
   590 	iReportIteration = 1;
       
   591 	iTotalReportIterations = 1;
       
   592 	TestParams();
       
   593 
       
   594 	iTestNo++;
       
   595 	iIteration = 0;
       
   596 	iReportIteration = 1;
       
   597 	iTotalReportIterations = KNumDispModes;
       
   598 	TestReadLine();
       
   599 
       
   600 	iTestNo++;
       
   601 	iIteration = 0;
       
   602 	iReportIteration = 1;
       
   603 	iTotalReportIterations = KNumShadowModes * KNumDrawModes;
       
   604 	if(KFastFading && (iDispMode == EColor64K ||iDispMode == EColor16MU || iDispMode == EColor16MA || iDispMode == EColor16MAP))
       
   605 		{
       
   606 		iUseFastFade = ETrue;
       
   607 		}
       
   608 	TestWriteRgb();
       
   609 
       
   610 	iTestNo++;
       
   611 	iIteration = 0;
       
   612 	iReportIteration = 1;
       
   613 	TestWriteLine();
       
   614 
       
   615 	iTestNo++;
       
   616 	iIteration = 0;
       
   617 	iReportIteration = 1;
       
   618 	TestWriteBinary();
       
   619 
       
   620 	iTestNo++;
       
   621 	iIteration = 0;
       
   622 	iReportIteration = 1;
       
   623 	iTotalReportIterations = 4;
       
   624 	TestWriteRGBAlpha();
       
   625 
       
   626 	iTestNo++;
       
   627 	iIteration = 0;
       
   628 	iReportIteration = 1;
       
   629 	iTotalReportIterations = KNumShadowModes;
       
   630 	TestShadow();
       
   631 	if(KFastFading && (iDispMode == EColor64K|| iDispMode == EColor16MU || iDispMode == EColor16MA || iDispMode == EColor16MAP))
       
   632 		{
       
   633 		iUseFastFade = EFalse;
       
   634 		}
       
   635 
       
   636 	iTestNo++;
       
   637 	iIteration = 0;
       
   638 	iReportIteration = 1;
       
   639 	iTotalReportIterations = 1;
       
   640 	TestWriteAlphaLineEx();
       
   641 
       
   642 	iTestNo++;
       
   643 	iIteration = 0;
       
   644 	iReportIteration = 1;
       
   645 	iTotalReportIterations = 1;
       
   646 	TestWriteAlphaLineNoShadowEx();
       
   647 
       
   648 	iTestNo++;
       
   649 	iIteration = 0;
       
   650 	iReportIteration = 1;
       
   651 	iTotalReportIterations = 1;
       
   652 	TestWriteMaskLineNoShadowEx();
       
   653 
       
   654 	iTestNo++;
       
   655 	iIteration = 0;
       
   656 	iReportIteration = 1;
       
   657 	iTotalReportIterations = 1;
       
   658 	TRAPD(err,((CTLowLevelStep*)iStep)->RecordTestResultL(););
       
   659     	if (err!=KErrNone)
       
   660     		INFO_PRINTF1(_L("Failed to record test result"));
       
   661 
       
   662 	((CTLowLevelStep*)iStep)->SetTestStepID(_L("GRAPHICS-SCREENDRIVER-0003"));
       
   663 	TestFastBlendBitmapMasked();
       
   664 	TRAPD(err1,((CTLowLevelStep*)iStep)->RecordTestResultL(););
       
   665     	if (err1!=KErrNone)
       
   666     		INFO_PRINTF1(_L("Failed to record test result"));
       
   667 
       
   668 	iTestNo++;
       
   669 	iIteration = 0;
       
   670 	iReportIteration = 1;
       
   671 	iTotalReportIterations = KNumBlendingColors;
       
   672 	((CTLowLevelStep*)iStep)->SetTestStepID(_L("GRAPHICS-SCREENDRIVER-0002"));
       
   673 	TestWriteRgbOutlineAndShadow();
       
   674 	TRAP(err,((CTLowLevelStep*)iStep)->RecordTestResultL(););
       
   675     	if (err!=KErrNone)
       
   676     		INFO_PRINTF1(_L("Failed to record test result"));
       
   677 /**
       
   678 	@SYMTestCaseID GRAPHICS-SCREENDRIVER-0001
       
   679 */
       
   680 	((CTLowLevelStep*)iStep)->SetTestStepID(_L("GRAPHICS-SCREENDRIVER-0001"));
       
   681 	}
       
   682 
       
   683 void CTLowLevel::TestParams()
       
   684 	{
       
   685 	Check(iDrawDevice->SizeInPixels()==iSize);
       
   686 	Check(iDrawDevice->DisplayMode()==iDispMode);
       
   687 	Check(iDrawDevice->LongWidth()==iLongWidth);
       
   688 	Check(iDrawDevice->ScanLineBuffer()!=NULL);
       
   689 	Check(iLongWidth%(iDrawDevice->ScanLineBytes())==0
       
   690 			|| iDrawDevice->ScanLineBytes() == iLongWidth * 2
       
   691 			|| iDrawDevice->ScanLineBytes() == iLongWidth * 3
       
   692 			|| iDrawDevice->ScanLineBytes() == iLongWidth * 4);
       
   693 	TInt hT = iDrawDevice->HorzTwipsPerThousandPixels();
       
   694 	Check(hT >= 0);
       
   695 	TInt vT = iDrawDevice->VertTwipsPerThousandPixels();
       
   696 	Check(vT >= 0);
       
   697 	Report();
       
   698 	}
       
   699 
       
   700 void CTLowLevel::TestReadLine()
       
   701 	{
       
   702 	TInt byteSize = ByteSize();
       
   703 	TUint8* writeBuffer = new TUint8[byteSize];
       
   704 	TUint8* readBuffer = new TUint8[iSize.iWidth * sizeof(TRgb)];
       
   705 	Check(writeBuffer != NULL);
       
   706 	Check(readBuffer != NULL);
       
   707 
       
   708 	for (TInt nDispMode = 0; nDispMode < KNumDispModes; nDispMode++)
       
   709 		{
       
   710 		TDisplayMode dispMode = TestDisplayMode[nDispMode];
       
   711 		iDrawDevice->SetUserDisplayMode(dispMode);
       
   712 
       
   713 		if (dispMode == EColor16MU || dispMode == EColor16MAP || iDispMode == EColor16MU || iDispMode == EColor16MAP)
       
   714 			iFuzzyMatch=ETrue;
       
   715 		else
       
   716 			iFuzzyMatch=EFalse;
       
   717 		for (TInt cnt=0;cnt<2;cnt++)
       
   718 			{
       
   719 			if (cnt==0)  //first time
       
   720 				iDrawDevice->SetUserDisplayMode(dispMode);
       
   721 			else
       
   722 				iDrawDevice->SetUserDisplayMode(iDispMode);
       
   723 
       
   724 			for (TInt nRect = 0; nRect < KNumTestRects; nRect++)
       
   725 				{
       
   726 				TRect rect = TestRect[nRect];
       
   727 				for (TInt yy = rect.iTl.iY; yy < rect.iBr.iY; yy++)
       
   728 					{
       
   729 					Clear(KRgbWhite);
       
   730 
       
   731 					FillBuffer(writeBuffer, byteSize, iDispMode, ETrue);
       
   732 					Mem::FillZ(readBuffer,byteSize);
       
   733 
       
   734 					//we select EDrawModeWriteAlpha because do not test blending here
       
   735 					iDrawDevice->WriteLine(rect.iTl.iX,yy,rect.Width(),(TUint32*)writeBuffer,CGraphicsContext::EDrawModeWriteAlpha);
       
   736 					iDrawDevice->ReadLine(rect.iTl.iX,yy,rect.Width(),(TUint32*)readBuffer,dispMode);
       
   737 
       
   738 					CheckBuffer(writeBuffer,iDispMode,readBuffer,dispMode,rect.Width());
       
   739 
       
   740 					Mem::FillZ(readBuffer,byteSize);
       
   741 
       
   742 					//we select EDrawModeWriteAlpha because do not test blending here
       
   743 					iDrawDevice->WriteLine(iSize.iWidth-rect.Width(),yy,rect.Width(),(TUint32*)writeBuffer,CGraphicsContext::EDrawModeWriteAlpha);
       
   744 					iDrawDevice->ReadLine(iSize.iWidth-rect.Width(),yy,rect.Width(),(TUint32*)readBuffer,dispMode);
       
   745 
       
   746 					CheckBuffer(writeBuffer,iDispMode,readBuffer,dispMode,rect.Width());
       
   747 					iIteration++;
       
   748 					}
       
   749 				}
       
   750 			}
       
   751 		if (iDispMode != EColor16MU && iDispMode != EColor16MAP)
       
   752 			iFuzzyMatch=EFalse;
       
   753 		Report();
       
   754 		}
       
   755 	delete [] writeBuffer;
       
   756 	delete [] readBuffer;
       
   757 	}
       
   758 
       
   759 void CTLowLevel::TestWriteRgb()
       
   760 	{
       
   761 	for (TInt shadowMode = 0; shadowMode < KNumShadowModes; shadowMode++)
       
   762 		{
       
   763 		for (TInt nMode = 0; nMode < KNumDrawModes; nMode++)
       
   764 			{
       
   765 			for (TInt nRect = 0; nRect < KNumTestRects; nRect++)
       
   766 				{
       
   767 				for (TInt nBackColor = 0; nBackColor < KNumTestBackgrounds; nBackColor++)
       
   768 					{
       
   769 					for (TInt nColor = 0; nColor < KNumTestColors; nColor++)
       
   770 						{
       
   771 
       
   772 						//for modes other than EColor16MAP skip the new colours which have alpha, and cause
       
   773 						//test failures.  There are two types of colours which need to be skipped, nColor,
       
   774 						//and nBackColor.  The additional colours were added specificially to test EColor16MAP mode,
       
   775 						//so the test coverage compared to previously is not reduced for non EColor16MAP modes.
       
   776 						if (((nColor>=KMaxNon16Colours)|| (nBackColor>=KMaxNon16BackColours)) && (iDispMode!= EColor16MAP))
       
   777 							continue;
       
   778 
       
   779 						TRgb bakCol = TestBackground[nBackColor];
       
   780 						Clear(bakCol);
       
   781 
       
   782 						CGraphicsContext::TDrawMode dMode = TestDrawMode[nMode];
       
   783 
       
   784 						if ((iDispMode==EColor16MAP)&&(dMode!=CGraphicsContext::EDrawModePEN))
       
   785 							continue;
       
   786 
       
   787 
       
   788 						TRect rect = TestRect[nRect];
       
   789 						TRgb col = TestColor[nColor];
       
   790 
       
   791 						iDrawDevice->CFbsDrawDevice::SetShadowMode(CFbsDrawDevice::TShadowMode(shadowMode));
       
   792 						iDrawDevice->CFbsDrawDevice::SetFadingParameters(100,200);
       
   793 						iDrawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(shadowMode));
       
   794 						iDrawDevice->WriteRgb(rect.iTl.iX,rect.iTl.iY,col,dMode);
       
   795 
       
   796 						CheckRgb(rect.iTl,col,bakCol,dMode,shadowMode);
       
   797 						CheckBackground(TRect(rect.iTl,TSize(1,1)),bakCol);
       
   798 
       
   799 						Clear(bakCol);
       
   800 
       
   801 						iDrawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(shadowMode));
       
   802 						iDrawDevice->WriteRgbMulti(rect.iTl.iX,rect.iTl.iY,rect.Width(),rect.Height(),col,dMode);
       
   803 
       
   804 						CheckRgb(rect,col,bakCol,dMode,shadowMode);
       
   805 						CheckBackground(rect,bakCol);
       
   806 						iIteration++;
       
   807 						}
       
   808 					}
       
   809 				}
       
   810 			Report();
       
   811 			}
       
   812 		}
       
   813 	}
       
   814 
       
   815 void CTLowLevel::TestWriteLine()
       
   816 	{
       
   817 	TInt byteSize = ByteSize();
       
   818 	TUint8* backBuffer = new TUint8[byteSize];
       
   819 	TUint8* writeBuffer = new TUint8[byteSize];
       
   820 	TUint8* copyBuffer = new TUint8[byteSize];
       
   821 	TUint8* readBuffer = new TUint8[byteSize];
       
   822 	Check(backBuffer != NULL);
       
   823 	Check(writeBuffer != NULL);
       
   824 	Check(copyBuffer != NULL);
       
   825 	Check(readBuffer != NULL);
       
   826 
       
   827 	for (TInt shadowMode = 0; shadowMode < KNumShadowModes; shadowMode++)
       
   828 		{
       
   829 		for (TInt nMode = 0; nMode < KNumDrawModes; nMode++)
       
   830 			{
       
   831 			CGraphicsContext::TDrawMode dMode = TestDrawMode[nMode];
       
   832 			for (TInt nRect = 0; nRect < KNumTestRects; nRect++)
       
   833 				{
       
   834 				for (TInt nBackColor = 0; nBackColor < KNumTestBackgrounds; nBackColor++)
       
   835 					{
       
   836 					//skip over new colours with alpha for modes other than EColor16MAP
       
   837 					//these were causing test failures
       
   838 					if ((nBackColor>=KMaxNon16BackColours) && (iDispMode!= EColor16MAP))
       
   839 							continue;
       
   840 
       
   841 					TRgb bakCol = TestBackground[nBackColor];
       
   842 					Clear(bakCol);
       
   843 					TRect rect = TestRect[nRect];
       
   844 					/*TBuf<128> buf;		//Some extra logging that might be useful if this test fails
       
   845 					_LIT(KLog1,"Shadow=%d, DrawMode=%d, Rect=(%d,%d,%d,%d), Color=%d");
       
   846 					buf.Format(KLog1,shadowMode,dMode,rect.iTl.iX,rect.iTl.iY,rect.iBr.iX,rect.iBr.iY,nBackColor);
       
   847 					INFO_PRINTF1(buf);*/
       
   848 					for (TInt yy = rect.iTl.iY; yy < rect.iBr.iY; yy++)
       
   849 						{
       
   850 						iDrawDevice->CFbsDrawDevice::SetShadowMode(CFbsDrawDevice::TShadowMode(shadowMode));
       
   851 						iDrawDevice->CFbsDrawDevice::SetFadingParameters(100,200);
       
   852 						iDrawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(shadowMode));
       
   853 						iDrawDevice->ReadLine(rect.iTl.iX,yy,rect.Width(),(TUint32*)backBuffer,iDispMode);
       
   854 
       
   855 						if (nRect != 7)
       
   856 							{
       
   857 							// make sure the alpha value is 0xFF when not blending the buffer into 16MU destination
       
   858 							TBool noAlpha16MU = dMode != CGraphicsContext::EDrawModePEN;
       
   859 							FillBuffer(writeBuffer, byteSize, iDispMode, noAlpha16MU);
       
   860 							}
       
   861 						else // Special check for losing leading 0s in 1 bpp mode at 31 pixel offset
       
   862 							{
       
   863 							Mem::Fill(writeBuffer,byteSize,0xff);
       
   864 							writeBuffer[0] = 0xfe;
       
   865 							}
       
   866 						Mem::Copy(copyBuffer,writeBuffer,byteSize);
       
   867 						iDrawDevice->WriteLine(rect.iTl.iX,yy,rect.Width(),(TUint32*)writeBuffer,dMode);
       
   868 						Shadow(copyBuffer,byteSize,shadowMode);
       
   869 
       
   870 						Mem::FillZ(readBuffer,byteSize);
       
   871 						iDrawDevice->ReadLine(rect.iTl.iX,yy,rect.Width(),(TUint32*)readBuffer,iDispMode);
       
   872 						CheckLine(copyBuffer,readBuffer,backBuffer,rect.Width(),dMode,iDispMode);
       
   873 
       
   874 						iIteration++;
       
   875 						}
       
   876 					CheckBackground(rect,bakCol);
       
   877 					}
       
   878 				}
       
   879 			Report();
       
   880 			}
       
   881 		}
       
   882 	delete [] backBuffer;
       
   883 	delete [] writeBuffer;
       
   884 	delete [] copyBuffer;
       
   885 	delete [] readBuffer;
       
   886 	}
       
   887 
       
   888 void CTLowLevel::TestWriteBinary()
       
   889 	{
       
   890 	TInt byteSize = ByteSize();
       
   891 	TInt wordSize = (byteSize + 3) / 4;
       
   892 	TUint32* writeBuffer = new TUint32[wordSize];
       
   893 	Check(writeBuffer != NULL);
       
   894 
       
   895 	for (TInt shadowMode = 0; shadowMode < KNumShadowModes; shadowMode++)
       
   896 		{
       
   897 		for (TInt nMode = 0; nMode < KNumDrawModes; nMode++)
       
   898 			{
       
   899 			for (TInt nRect = 0; nRect < KNumTestRects; nRect++)
       
   900 				{
       
   901 				for (TInt nBackColor = 0; nBackColor < KNumTestBackgrounds; nBackColor++)
       
   902 					{
       
   903 					for (TInt nColor = 0; nColor < KNumTestColors; nColor++)
       
   904 						{
       
   905 						if (((nColor>=KMaxNon16Colours)|| (nBackColor>=KMaxNon16BackColours)) && (iDispMode!= EColor16MAP))
       
   906 							continue;
       
   907 
       
   908 						TRect rect = TestRect[nRect];
       
   909 						if (rect.Width() > 32)
       
   910 							{
       
   911 							rect.iBr.iX = rect.iTl.iX + 32;
       
   912 							}
       
   913 						if (rect.Width() < 1)
       
   914 							rect.iBr.iX = rect.iTl.iX + 1;
       
   915 
       
   916 						TRgb bakCol = TestBackground[nBackColor];
       
   917 						TRgb col = TestColor[nColor];
       
   918 						CGraphicsContext::TDrawMode dMode = TestDrawMode[nMode];
       
   919 
       
   920 						if ((iDispMode==EColor16MAP)&&(dMode!=CGraphicsContext::EDrawModePEN))
       
   921 							continue;
       
   922 
       
   923 						Clear(bakCol);
       
   924 						iDrawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(shadowMode));
       
   925 						FillBuffer((TUint8*)writeBuffer, byteSize, EGray2);
       
   926 						iDrawDevice->WriteBinary(rect.iTl.iX,rect.iTl.iY,writeBuffer,rect.Width(),rect.Height(),col,dMode);
       
   927 						CheckBinary(rect,writeBuffer,col,bakCol,dMode,shadowMode,ETrue,EFalse);
       
   928 						CheckBackground(rect,bakCol);
       
   929 
       
   930 						Clear(bakCol);
       
   931 						iDrawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(shadowMode));
       
   932 						FillBuffer((TUint8*)writeBuffer, byteSize, EGray2);
       
   933 						iDrawDevice->WriteBinaryLine(rect.iTl.iX,rect.iTl.iY,writeBuffer,rect.Width(),col,dMode);
       
   934 						CheckBinary(TRect(rect.iTl,TSize(rect.Width(),1)),writeBuffer,col,bakCol,dMode,shadowMode,EFalse,EFalse);
       
   935 						CheckBackground(TRect(rect.iTl.iX,rect.iTl.iY,rect.iBr.iX,rect.iTl.iY + 1),bakCol);
       
   936 
       
   937 						Clear(bakCol);
       
   938 						iDrawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(shadowMode));
       
   939 						FillBuffer((TUint8*)writeBuffer, byteSize, EGray2);
       
   940 						iDrawDevice->WriteBinaryLineVertical(rect.iTl.iX,rect.iTl.iY,writeBuffer,rect.Height(),col,dMode,EFalse);
       
   941 						CheckBinary(TRect(rect.iTl,TSize(1,rect.Height())),writeBuffer,col,bakCol,dMode,shadowMode,EFalse,EFalse);
       
   942 						CheckBackground(TRect(rect.iTl.iX,rect.iTl.iY,rect.iTl.iX + 1,rect.iBr.iY),bakCol);
       
   943 
       
   944 						Clear(bakCol);
       
   945 						iDrawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(shadowMode));
       
   946 						FillBuffer((TUint8*)writeBuffer, byteSize, EGray2);
       
   947 						iDrawDevice->WriteBinaryLineVertical(rect.iTl.iX,rect.iBr.iY - 1,writeBuffer,rect.Height(),col,dMode,ETrue);
       
   948 						CheckBinary(TRect(rect.iTl,TSize(1,rect.Height())),writeBuffer,col,bakCol,dMode,shadowMode,EFalse,ETrue);
       
   949 						CheckBackground(TRect(rect.iTl.iX,rect.iTl.iY,rect.iTl.iX + 1,rect.iBr.iY),bakCol);
       
   950 
       
   951 						iIteration++;
       
   952 						}
       
   953 					}
       
   954 				}
       
   955 			Report();
       
   956 			}
       
   957 		}
       
   958 	delete [] writeBuffer;
       
   959 	}
       
   960 
       
   961 void CTLowLevel::TestWriteAlphaLineEx()
       
   962 	{
       
   963 	TAny* interface = NULL;
       
   964 	TInt err = iDrawDevice->GetInterface(KFastBlitInterfaceID, interface);
       
   965 	if(err == KErrNone)
       
   966 		{
       
   967 		INFO_PRINTF1(_L("START ---->TestWriteAlphaLineEx"));
       
   968 		TSize size = TSize(30,30);
       
   969 		TRect rect = TRect(size);
       
   970 
       
   971 		TUint16* writeBuffer = new TUint16[size.iWidth];
       
   972 		TUint8* maskBuffer =  new TUint8[size.iWidth];
       
   973 
       
   974 		TInt nOffset = sizeof(TUint16)*size.iWidth/2;
       
   975 
       
   976 		Mem::Fill(writeBuffer,nOffset,0xff);
       
   977 		Mem::Fill((((TUint8*)writeBuffer)+nOffset),nOffset,0x00);
       
   978 		Mem::Fill(maskBuffer,size.iWidth/2,0x00);
       
   979 		Mem::Fill((maskBuffer+size.iWidth/2),size.iWidth/2,0xff);
       
   980 
       
   981 		MFastBlit* fastBlit = reinterpret_cast<MFastBlit*>(interface);
       
   982 		Clear(KRgbFadedBlack);
       
   983 		iDrawDevice->SetShadowMode(CFbsDrawDevice::EFade);
       
   984 
       
   985 		for (TInt yy = rect.iTl.iY; yy < rect.iBr.iY; yy++)
       
   986 			{
       
   987 			fastBlit->WriteAlphaLineEx(rect.iTl.iX,yy,rect.Width(),0,(TUint32*)writeBuffer,EColor64K,0,(TUint32*)maskBuffer,MAlphaBlend::EShdwBefore);
       
   988 			iIteration++;
       
   989 			}
       
   990 		CheckRgb(rect,KRgbBlack,KRgbFadedBlack,CGraphicsContext::EDrawModePEN,2);
       
   991 		CheckBackground(rect,KRgbFadedBlack);
       
   992 
       
   993 		Report();
       
   994 		INFO_PRINTF1(_L("END ---->TestWriteAlphaLineEx"));
       
   995 		delete [] writeBuffer;
       
   996 		delete [] maskBuffer;
       
   997 		}
       
   998 	}
       
   999 
       
  1000 void CTLowLevel::TestWriteAlphaLineNoShadowEx()
       
  1001 	{
       
  1002 	TAny* interface = NULL;
       
  1003 	TInt err = iDrawDevice->GetInterface(KFastBlitInterfaceID, interface);
       
  1004 	if(err == KErrNone)
       
  1005 		{
       
  1006 		INFO_PRINTF1(_L("START ---->TestWriteAlphaLineNoShadowEx"));
       
  1007 		TSize size = TSize(30,30);
       
  1008 		TRect rect = TRect(size);
       
  1009 
       
  1010 		TUint16* writeBuffer = new TUint16[size.iWidth];
       
  1011 		Check(writeBuffer != NULL);
       
  1012 		TUint8* maskBuffer =  new TUint8[size.iWidth];
       
  1013 		Check(maskBuffer != NULL);
       
  1014 		TInt nOffset = sizeof(TUint16) * size.iWidth;
       
  1015 
       
  1016 		Mem::Fill(writeBuffer,nOffset,0xff);
       
  1017 		Mem::Fill(maskBuffer,size.iWidth/2,0x8e);
       
  1018 		Mem::Fill((maskBuffer+size.iWidth/2),size.iWidth/2,0xff);
       
  1019 
       
  1020 		MFastBlit* fastBlit = reinterpret_cast<MFastBlit*>(interface);
       
  1021 
       
  1022 		Clear(KRgbWhite);
       
  1023 		for (TInt yy = rect.iTl.iY; yy < rect.iBr.iY; yy++)
       
  1024 			{
       
  1025 			fastBlit->WriteAlphaLineEx(rect.iTl.iX,yy,rect.Width(),0,(TUint32*)writeBuffer,EColor64K,0,(TUint32*)maskBuffer,MAlphaBlend::EShdwBefore);
       
  1026 			iIteration++;
       
  1027 			}
       
  1028 		CheckRgb(rect,KRgbWhite,KRgbWhite,CGraphicsContext::EDrawModePEN,0);
       
  1029 
       
  1030 		Report();
       
  1031 		INFO_PRINTF1(_L("END ---->TestWriteAlphaLineNoShadowEx"));
       
  1032 		delete [] writeBuffer;
       
  1033 		delete [] maskBuffer;
       
  1034 		}
       
  1035 	}
       
  1036 
       
  1037 void CTLowLevel::TestWriteMaskLineNoShadowEx()
       
  1038 	{
       
  1039 	TAny* interface = NULL;
       
  1040 	TInt err = iDrawDevice->GetInterface(KFastBlitInterfaceID, interface);
       
  1041 	if(err == KErrNone)
       
  1042 		{
       
  1043 		INFO_PRINTF1(_L("START ---->TestWriteMaskLineNoShadowEx"));
       
  1044 		TSize size = TSize(30,30);
       
  1045 		TRect rect = TRect(size);
       
  1046 
       
  1047 		TUint16* writeBuffer = new TUint16[size.iWidth];
       
  1048 		Check(writeBuffer != NULL);
       
  1049 		TUint8* maskBuffer =  new TUint8[size.iWidth];
       
  1050 		Check(maskBuffer != NULL);
       
  1051 
       
  1052 		TInt nOffset = sizeof(TUint16) * size.iWidth;
       
  1053 
       
  1054 		Mem::Fill(writeBuffer,nOffset,0xff);
       
  1055 		Mem::Fill(maskBuffer,size.iWidth/2,0x8e);
       
  1056 		Mem::Fill((maskBuffer+size.iWidth/2),size.iWidth/2,0xff);
       
  1057 
       
  1058 		MFastBlit* fastBlit = reinterpret_cast<MFastBlit*>(interface);
       
  1059 
       
  1060 		Clear(KRgbWhite);
       
  1061 		for (TInt yy = rect.iTl.iY; yy < rect.iBr.iY; yy++)
       
  1062 			{
       
  1063 			fastBlit->WriteMaskLineEx(rect.iTl.iX,yy,rect.Width(),0,(TUint32*)writeBuffer,EColor64K,0,(TUint32*)maskBuffer,EFalse);
       
  1064 			iIteration++;
       
  1065 			}
       
  1066 		CheckRgb(rect,KRgbWhite,KRgbWhite,CGraphicsContext::EDrawModePEN,0);
       
  1067 
       
  1068 		Report();
       
  1069 		INFO_PRINTF1(_L("END ---->TestWriteMaskLineNoShadowEx"));
       
  1070 		delete [] writeBuffer;
       
  1071 		delete [] maskBuffer;
       
  1072 		}
       
  1073 	}
       
  1074 
       
  1075 /**
       
  1076 Overwrite the pixel in the buffer with a given mode with a value already in that
       
  1077 mode.
       
  1078 @param aX		The offset in pixels from the start of the buffer.
       
  1079 @param aPtr		The start of the buffer.
       
  1080 @param aMode	The display mode of the buffer.
       
  1081 @param aValue	The new pixel value.
       
  1082 */
       
  1083 void CTLowLevel::WriteBinaryValue(TUint32 aX, TAny* const aPtr, 
       
  1084 		TDisplayMode aMode, TUint32 aValue) const
       
  1085 	{
       
  1086 	TUint32* buffer32 = (TUint32*)aPtr;
       
  1087 	TInt shift;
       
  1088 	TUint32 mask;
       
  1089 
       
  1090 	switch (aMode)
       
  1091 		{
       
  1092 	case EGray2:
       
  1093 		buffer32 += aX >> 5;
       
  1094 		shift = aX & 0x1F;
       
  1095 		mask = 0x1;
       
  1096 		break;
       
  1097 	case EGray4:
       
  1098 		buffer32 += aX >> 4;
       
  1099 		shift = (aX & 0xF) << 1;
       
  1100 		mask = 0x3;
       
  1101 		break;
       
  1102 	case EGray16:
       
  1103 	case EColor16:
       
  1104 		buffer32 += aX >> 3;
       
  1105 		shift = (aX & 0x7) << 2;
       
  1106 		mask = 0xF;
       
  1107 		break;
       
  1108 	case EGray256:
       
  1109 	case EColor256:
       
  1110 		buffer32 += aX >> 2;
       
  1111 		shift = (aX & 0x3) << 3;
       
  1112 		mask = 0xFF;
       
  1113 		break;
       
  1114 	case EColor4K:
       
  1115 		buffer32 += aX >> 1;
       
  1116 		shift = (aX & 0x1) << 4;
       
  1117 		mask = 0xFFF;
       
  1118 		break;
       
  1119 	case EColor64K:
       
  1120 		buffer32 += aX >> 1;
       
  1121 		shift = (aX & 0x1) << 4;
       
  1122 		mask = 0xFFFF;
       
  1123 		break;
       
  1124 	case EColor16M:
       
  1125 		{
       
  1126 		// This mode requires special handling, because shifts and masks
       
  1127 		// won't work.
       
  1128 		TUint8* buffer8 = ((TUint8*)aPtr) + (aX * 3);
       
  1129 		*buffer8++ = aValue & 0xFF;
       
  1130 		*buffer8++ = (aValue >> 8) & 0xFF;
       
  1131 		*buffer8++ = (aValue >> 16) & 0xFF;
       
  1132 		// Return early as the buffer has been updated.
       
  1133 		return;
       
  1134 		}
       
  1135 	case EColor16MU:
       
  1136 		buffer32 += aX;
       
  1137 		shift = 0;
       
  1138 		mask = 0xFFFFFFFF;
       
  1139 		aValue |= 0xFF000000;	// Force alpha to opaque.
       
  1140 		break;
       
  1141 	default:
       
  1142 		buffer32 += aX;
       
  1143 		shift = 0;
       
  1144 		mask = 0xFFFFFFFF;
       
  1145 		break;
       
  1146 		};
       
  1147 
       
  1148 	// Write pixel value into right part of word.
       
  1149 	*buffer32 = (*buffer32 & ~(mask << shift)) | ((aValue & mask) << shift);
       
  1150 	}
       
  1151 
       
  1152 /**
       
  1153 Copy contents of one buffer over another, depending on a per-pixel mask bit.
       
  1154 @param aSrc		Source pixel buffer
       
  1155 @param aSrcMode	Display mode of source
       
  1156 @param aDst		Destination pixel buffer
       
  1157 @param aDstMode	Display mode of destination
       
  1158 @param aMsk		Mask buffer. Must be in EGray2 format
       
  1159 @param aWidth	Number of pixels to copy
       
  1160 @param aInvert	If ETrue, copy source where mask bit is clear, else copy where
       
  1161 	it is set.
       
  1162 */
       
  1163 void CTLowLevel::MaskedBlendBuffer(TAny* aSrc, TDisplayMode aSrcMode, TAny* aDst,
       
  1164 		TDisplayMode aDstMode, TUint32* aMsk, TInt aWidth, TBool aInvert)
       
  1165 	{
       
  1166 	TColorConvertor& srcConvertor = ColorConvertor(aSrcMode);
       
  1167 	TColorConvertor& dstConvertor = ColorConvertor(aDstMode);
       
  1168 
       
  1169 	for (TInt xx = 0; xx < aWidth; xx++)
       
  1170 		{
       
  1171 		TUint32 pixelMask = ExtractBinaryValue(xx, aMsk, EGray2);
       
  1172 		if (aInvert)
       
  1173 			{
       
  1174 			pixelMask = !pixelMask;
       
  1175 			}
       
  1176 
       
  1177 		if (pixelMask)
       
  1178 			{
       
  1179 			TUint32 dst32 = ExtractBinaryValue(xx, (TUint32*)aDst, aDstMode);
       
  1180 			TUint32 src32 = ExtractBinaryValue(xx, (TUint32*)aSrc, aSrcMode);
       
  1181 
       
  1182 			switch (aSrcMode)
       
  1183 				{
       
  1184 				// Only blend for source modes with alpha 
       
  1185 				case EColor16MAP:
       
  1186 				case EColor16MA:
       
  1187 					{
       
  1188 					// Convert source and destination pixel values to 16MAP
       
  1189 					if (aDstMode != EColor16MAP)
       
  1190 						{
       
  1191 						dst32 = dstConvertor.Color(dst32).Color16MAP();
       
  1192 						}
       
  1193 					if (aSrcMode != EColor16MAP)
       
  1194 						{
       
  1195 						src32 = srcConvertor.Color(src32).Color16MAP();
       
  1196 						}
       
  1197 					// Both params must be 16MAP, output is likewise
       
  1198 					dst32 = PMAPixelBlend(dst32, src32);
       
  1199 					// Convert 16MAP to final format
       
  1200 					dst32 = dstConvertor.Index(TRgb::Color16MAP(dst32));
       
  1201 					}
       
  1202 					break;
       
  1203 				// Anything else is a copy (with format conversion) 
       
  1204 				default:
       
  1205 					dst32 = dstConvertor.Index(srcConvertor.Color(src32));
       
  1206 					break;
       
  1207 				}
       
  1208 
       
  1209 			WriteBinaryValue(xx, aDst, aDstMode, dst32);
       
  1210 			}
       
  1211 		}
       
  1212 	}
       
  1213 
       
  1214 /**
       
  1215 Returns the minimum number of bytes to hold the given number of pixels,
       
  1216 rounded up to the next word boundary.
       
  1217 @param aPixels	Number of pixels
       
  1218 @param aMode	Display mode of pixels
       
  1219 @return	Number of bytes to hold pixels
       
  1220 */
       
  1221 TUint32 CTLowLevel::BytesForPixels(TUint32 aPixels, TDisplayMode aMode)
       
  1222 	{
       
  1223 	TUint32 bytes = LongWidth(aPixels, aMode);
       
  1224 
       
  1225 	switch (aMode)
       
  1226 		{
       
  1227 		case EGray2:
       
  1228 			bytes /= 8;
       
  1229 			break;
       
  1230 		case EGray4:
       
  1231 			bytes /= 4;
       
  1232 			break;
       
  1233 		case EGray16:
       
  1234 		case EColor16:
       
  1235 			bytes /= 2;
       
  1236 			break;
       
  1237 		case EColor4K:
       
  1238 		case EColor64K:
       
  1239 			bytes *= 2;
       
  1240 			break;
       
  1241 		case EColor16M:
       
  1242 			bytes *= 3;
       
  1243 			break;
       
  1244 		case EColor16MU:
       
  1245 		case EColor16MA:
       
  1246 		case EColor16MAP:
       
  1247 			bytes *= 4;
       
  1248 			break;
       
  1249 		}
       
  1250 	return bytes;
       
  1251 	}
       
  1252 
       
  1253 /**
       
  1254 Compare the actual blend results with the expected ones, allowing for some
       
  1255 blending errors. Both buffers must be in aMode format
       
  1256 @param aActual		Start of actual results
       
  1257 @param aExpected	Start of expected results
       
  1258 @param aWidth		Number of pixels to check
       
  1259 @param aMode		Display mode of the pixels in the buffers
       
  1260 @param aBlended		ETrue if pixels were blended, EFalse if they were opaque
       
  1261 @return	ETrue if buffers compared OK, EFalse if there was a mismatch.
       
  1262 */
       
  1263 TBool CTLowLevel::CompareBlendMaskResults(TAny* aActual, TAny* aExpected, 
       
  1264 		TUint32 aWidth, TDisplayMode aMode, TBool aBlended, TDisplayMode aSrcMode)
       
  1265 	{
       
  1266 	if (aBlended)
       
  1267 		{
       
  1268 		// There can be blending rounding errors, so allow for these. In general
       
  1269 		// allow for one bit of error, taking into account the precision of
       
  1270 		// each component.
       
  1271 		TInt maxRBErr;
       
  1272 		TInt maxGErr;
       
  1273 		switch (aMode)
       
  1274 			{
       
  1275 			case EColor4K:
       
  1276 				// All components are four bits
       
  1277 				maxRBErr = maxGErr = 17;
       
  1278 				break;
       
  1279 			case EColor64K:
       
  1280 				// Six bits for green, five for the others, so error
       
  1281 				// varies.
       
  1282 				maxRBErr = 9;
       
  1283 				maxGErr = 5;
       
  1284 				break;
       
  1285 			default:
       
  1286 				// For 16MAP, it will be dependent on the alpha value.
       
  1287 				maxRBErr = maxGErr = 1;
       
  1288 				break;
       
  1289 			}
       
  1290 
       
  1291 		// Compare each pixel, allowing for the error in each component.
       
  1292 		for (TInt xx = 0; xx < aWidth; xx++)
       
  1293 			{
       
  1294 			TRgb exp = ExtractRgbValue(xx, (TUint8*)aExpected, aMode);
       
  1295 			TRgb act = ExtractRgbValue(xx, (TUint8*)aActual, aMode);
       
  1296 			
       
  1297 			if (aMode == EColor16MAP)
       
  1298 				{
       
  1299 				// Take into account that components have been premultiplied
       
  1300 				TInt alpha = exp.Alpha();
       
  1301 				if (alpha > 0)
       
  1302 					{
       
  1303 					maxRBErr = maxGErr = (0xFF + alpha - 1) / alpha;
       
  1304 					}
       
  1305 				if (aSrcMode == EColor16MA && (maxGErr < 3 || maxRBErr < 3))
       
  1306 					{
       
  1307 					maxGErr = 3;
       
  1308 					maxRBErr = 3;
       
  1309 					}
       
  1310 				}
       
  1311 			
       
  1312 			if (AbsDiff(exp.Red(), act.Red()) > maxRBErr ||
       
  1313 					AbsDiff(exp.Green(), act.Green()) > maxGErr ||
       
  1314 					AbsDiff(exp.Blue(), act.Blue()) > maxRBErr ||
       
  1315 					exp.Alpha() != act.Alpha())
       
  1316 				{
       
  1317 				INFO_PRINTF4(_L("At %d, expected 0x%08.8x, got 0x%08.8x"), 
       
  1318 						xx, exp.Internal(), act.Internal());
       
  1319 				return EFalse;
       
  1320 				}
       
  1321 			}
       
  1322 		return ETrue;
       
  1323 		}
       
  1324 	else
       
  1325 		{
       
  1326 		// For non-alpha sources there is no blending, so results
       
  1327 		// should be exact.
       
  1328 		TUint32 stride = BytesForPixels(aWidth, aMode);
       
  1329 		return (Mem::Compare((TUint8*)aActual, stride, (TUint8*)aExpected, stride) == 0);
       
  1330 		}
       
  1331 	}
       
  1332 
       
  1333 class TFunctionThread
       
  1334 	{
       
  1335 protected:
       
  1336 	TFunctionThread():iExitHow(ENotStarted)	
       
  1337 		{}
       
  1338 	TInt LaunchThreadFunction(const TDesC& aName);
       
  1339 private:
       
  1340 	static TInt TheThreadFunction(TAny*);
       
  1341 	virtual TInt	ThreadFunctionL()=0;
       
  1342 public:
       
  1343 	enum {
       
  1344 		ENotStarted,
       
  1345 		ERunning,	//should never see this
       
  1346 		EReturn,
       
  1347 		ELeave,
       
  1348 		EPanic,
       
  1349 		ETerminate,
       
  1350 		};
       
  1351 	TInt	iExitHow;
       
  1352 	TInt	iExitCode;	//Currently don't store the panic category string.
       
  1353 	};
       
  1354 
       
  1355 TInt TFunctionThread::LaunchThreadFunction(const TDesC& aName)
       
  1356 	{
       
  1357 	RThread thrd;
       
  1358 	TRequestStatus stat;
       
  1359 	enum { //8kb to 2mb
       
  1360 		KMinHeapSize=0x2000,
       
  1361 		KMaxHeapSize=0x200000
       
  1362 		};
       
  1363 	TInt created=thrd.Create(aName,TheThreadFunction,KDefaultStackSize,KMinHeapSize,KMaxHeapSize,this);
       
  1364 	if (created<KErrNone)
       
  1365 		{
       
  1366 		iExitCode=created;
       
  1367 		return created;
       
  1368 		}
       
  1369 	thrd.SetPriority(EPriorityMuchMore);
       
  1370 	thrd.Logon(stat);
       
  1371 	User::SetJustInTime(EFalse);
       
  1372 	thrd.Resume();
       
  1373 	User::WaitForRequest(stat);
       
  1374 	if ( iExitHow!=ENotStarted || iExitHow==ERunning )
       
  1375 		{
       
  1376 		iExitCode=thrd.ExitReason();
       
  1377 		switch (thrd.ExitType())
       
  1378 			{
       
  1379 			case EExitKill:			iExitHow=EReturn;		break;
       
  1380 			case EExitPanic:		iExitHow=EPanic;		break;
       
  1381 			case EExitTerminate:	iExitHow=ETerminate;	break;
       
  1382 			default:
       
  1383 				ASSERT(EFalse);
       
  1384 			}
       
  1385 		}
       
  1386 	thrd.Close();
       
  1387 	User::SetJustInTime(ETrue);
       
  1388 	return KErrNone;
       
  1389 	}
       
  1390 
       
  1391 TInt TFunctionThread::TheThreadFunction(TAny* aThis)
       
  1392 	{
       
  1393 	TFunctionThread* thisThis=(TFunctionThread*)aThis;
       
  1394 	if (thisThis==NULL)
       
  1395 		{
       
  1396 		User::Panic(_L("NoThis"),0x1);
       
  1397 		}
       
  1398 	thisThis->iExitHow=thisThis->ERunning;
       
  1399 	TInt returnErr = KErrNone;
       
  1400 	TRAPD(leaveErr,returnErr=thisThis->ThreadFunctionL());
       
  1401 	if (leaveErr)
       
  1402 		{
       
  1403 		thisThis->iExitHow=ELeave;
       
  1404 		thisThis->iExitCode=leaveErr;
       
  1405 		return leaveErr;
       
  1406 		}
       
  1407 	else
       
  1408 		{
       
  1409 		thisThis->iExitHow=EReturn;
       
  1410 		thisThis->iExitCode=returnErr;
       
  1411 		return returnErr;
       
  1412 		}
       
  1413 	}
       
  1414 
       
  1415 /** This thread verifies whether a range of memory is accessible 
       
  1416   The range is read sequentially until it panics, or the range is completed.
       
  1417   It is useful to input a range of addresses where some are valid and some fail 
       
  1418   in order to demonstrate an edge against which an algorithm that performs illegal reads can subsequently be tested.
       
  1419   The FailOffset() returned index indicates the offset from the start at which the memory access caused a panic. 
       
  1420  **/
       
  1421 class TTestMemThread:public TFunctionThread
       
  1422 	{
       
  1423 public:
       
  1424 	TTestMemThread(TUint32* aStartAddress,TUint32* aEndAddress);
       
  1425 	TInt FailOffset();
       
  1426 private:
       
  1427 	virtual TInt	ThreadFunctionL();
       
  1428 private:
       
  1429 	TUint32* iStartAddress;
       
  1430 	TUint32* iEndAddress;
       
  1431 	volatile TUint32* iLastAddressTried;
       
  1432 	volatile TUint32  iCopyValueHere;
       
  1433 	
       
  1434 	};
       
  1435 
       
  1436 TTestMemThread::TTestMemThread(TUint32* aStartAddress,TUint32* aEndAddress):
       
  1437 	iStartAddress(aStartAddress),
       
  1438 	iEndAddress(aEndAddress),
       
  1439 	iLastAddressTried(NULL)
       
  1440 	{
       
  1441 	ASSERT(aStartAddress);
       
  1442 	ASSERT(aEndAddress);
       
  1443 	LaunchThreadFunction(_L("MemTest"));
       
  1444 	}
       
  1445 
       
  1446 /**
       
  1447  *	Returns the number of successful memory reads before a panic occurred
       
  1448  * 	Or various error codes if the test didn't run or didn't panic.
       
  1449  * 
       
  1450  **/
       
  1451 TInt TTestMemThread::FailOffset()
       
  1452 	{
       
  1453 	if (iExitHow==EReturn)
       
  1454 		{
       
  1455 		return KErrCompletion;
       
  1456 		}
       
  1457 	else
       
  1458 		{
       
  1459 		if (iExitHow==EPanic)
       
  1460 			{
       
  1461 			if (iLastAddressTried)
       
  1462 				{
       
  1463 				TInt retval=iLastAddressTried-iStartAddress;
       
  1464 				if (iEndAddress-iStartAddress<0)
       
  1465 					{
       
  1466 					retval=-retval;
       
  1467 					}
       
  1468 				if (retval<0)
       
  1469 					{
       
  1470 					return KErrCorrupt;
       
  1471 					}
       
  1472 				else
       
  1473 					{
       
  1474 					return retval;
       
  1475 					}
       
  1476 				}
       
  1477 			else
       
  1478 				{
       
  1479 				return KErrNotFound;
       
  1480 				}
       
  1481 			}
       
  1482 		else
       
  1483 			{
       
  1484 			return KErrGeneral; 
       
  1485 			}
       
  1486 		}
       
  1487 	}
       
  1488 /*
       
  1489  * This thread function allows a test to verify that a particular address range 
       
  1490  * is actually inaccessable.
       
  1491  * I.e. that attempting to read from the given address range causes a panic.
       
  1492  */
       
  1493 TInt TTestMemThread::ThreadFunctionL()
       
  1494 	{
       
  1495 	if (iStartAddress && iEndAddress)
       
  1496 		{
       
  1497 		TInt delta=1;
       
  1498 		if (iStartAddress>iEndAddress)
       
  1499 			{
       
  1500 			delta=-1;
       
  1501 			}
       
  1502 		for (TUint32 volatile* tryAddress=iStartAddress;tryAddress!=iEndAddress;tryAddress+=delta)
       
  1503 			{
       
  1504 			iLastAddressTried=tryAddress;
       
  1505 			iCopyValueHere=*tryAddress;
       
  1506 			}
       
  1507 		return 0;
       
  1508 		}
       
  1509 	return KErrArgument;
       
  1510 	}
       
  1511 
       
  1512 void CTLowLevel::ClosePanicDialogs()
       
  1513 	{
       
  1514 	RWsSession session;
       
  1515 	TInt err = session.Connect();
       
  1516 	TEST(err == KErrNone);
       
  1517 	TInt idFocus = session.GetFocusWindowGroup();
       
  1518 	TWsEvent event;
       
  1519 	event.SetType(EEventKey); //EEventKeyDown
       
  1520 	TKeyEvent* keyEvent = event.Key();
       
  1521 	keyEvent->iCode = EKeyEscape;
       
  1522 	keyEvent->iScanCode = EStdKeyEscape;
       
  1523 	keyEvent->iModifiers = 0;
       
  1524 	TInt theLimit = 50;
       
  1525 	while(idFocus != NULL && (theLimit-- > 0))
       
  1526 		{
       
  1527 		session.SendEventToAllWindowGroups(event);
       
  1528 		TInt idNewFocus = session.GetFocusWindowGroup();
       
  1529 		idFocus=idNewFocus;
       
  1530 		}
       
  1531 	session.Flush();
       
  1532 	session.Close();
       
  1533 	}
       
  1534 
       
  1535 
       
  1536 /**
       
  1537 @SYMTestCaseID GRAPHICS-SCREENDRIVER-0003
       
  1538 @SYMTestCaseDesc Test that FastBlendBitmapMasked masking works correctly
       
  1539 @SYMDEF INC120146 PDEF120693 PDEF120680 INC120742 PDEF121725
       
  1540 @SYMTestPriority High
       
  1541 @SYMTestActions Test actions are:
       
  1542 	Create pseudorandom initial contents, source and mask lines.
       
  1543 	Set a line of the screen to the initial contents.
       
  1544 	Use FastBlendBitmapMasked, with and without inverted bitmask, to write
       
  1545 		source to target.
       
  1546 	Read line contents back.
       
  1547 	Check each pixel is either the initial value, or the source or a blend,
       
  1548 		depending on corresponding mask pixel.
       
  1549 	Repeat this whole sequence with supported source display modes.
       
  1550 	NOTE - wrapped in memory check for edge case defect INC120742
       
  1551 @SYMTestExpectedResults The correct pixel values are set, based on the mask.
       
  1552 */
       
  1553 void CTLowLevel::TestFastBlendBitmapMasked(const TInt aRetry)
       
  1554 	{
       
  1555 	const TInt KRetryAmount = 10;
       
  1556 
       
  1557 	TAny* interface = NULL;
       
  1558 	TInt err = iDrawDevice->GetInterface(KFastBlendInterfaceID, interface);
       
  1559 	if(err == KErrNone)
       
  1560 		{
       
  1561 		if (aRetry == 0)
       
  1562 			{
       
  1563 			INFO_PRINTF1(_L("START ---->TestFastBlendBitmapMasked"));
       
  1564 			}
       
  1565 
       
  1566 		MFastBlend* fastBlend = reinterpret_cast<MFastBlend*>(interface);
       
  1567 		TInt yPos = iSize.iHeight / 2;
       
  1568 		TPoint pt(0,yPos);
       
  1569 		TSize lineSize(iSize.iWidth, 1);
       
  1570 		TRect lineRect(lineSize);
       
  1571 
       
  1572 		TInt destStride = iDrawDevice->ScanLineBytes();
       
  1573  		TInt maskStride = (iSize.iWidth + 7) / 8;
       
  1574 		TInt maskPages = (maskStride/4096+1);
       
  1575 		maskPages+=20;
       
  1576 		// Allocate large enough buffers for all modes
       
  1577 		TAny* source = User::Alloc(iSize.iWidth * 4);
       
  1578 		TAny* expected = User::Alloc(destStride);
       
  1579 		CFbsBitmap testBitmap;
       
  1580 		testBitmap.Create(TSize(1024,maskPages),EColor16MA);
       
  1581 		TUint32* mask = testBitmap.DataAddress()+1024-(maskStride%4096)/4;
       
  1582 		TUint32* slb = iDrawDevice->ScanLineBuffer();
       
  1583 
       
  1584 		Check(source != NULL && expected != NULL && mask != NULL);
       
  1585 
       
  1586 		TUint32* bitmapData=testBitmap.DataAddress();
       
  1587 		SEpocBitmapHeader header1 = testBitmap.Header();
       
  1588 		TUint32* pastBitmapData=bitmapData+((header1.iBitmapSize-header1.iStructSize)>>2);
       
  1589 		mask = pastBitmapData- (maskStride+3)/4;
       
  1590 	
       
  1591 		TBool canGenerateDefectScenario = EFalse;
       
  1592 		TTestMemThread memThread(pastBitmapData-2,pastBitmapData+2);
       
  1593 		TInt failAt=memThread.FailOffset();
       
  1594 		if (failAt<0)
       
  1595 			{
       
  1596 			INFO_PRINTF2(_L("Error generated by test thread! %i - BAD"),failAt);
       
  1597 			}
       
  1598 		else if (failAt<=1)
       
  1599 			{
       
  1600 			INFO_PRINTF1(_L("Bitmap memory is inaccessable - BAD"));
       
  1601 			}
       
  1602 		else if (failAt>2)
       
  1603 			{
       
  1604 			INFO_PRINTF1(_L("Memory after bitmap is accessable - BAD"));
       
  1605 			}
       
  1606 		else
       
  1607 			{
       
  1608 			INFO_PRINTF1(_L("Memory after bitmap is inaccessable - GOOD"));
       
  1609 			canGenerateDefectScenario=ETrue;
       
  1610 			}
       
  1611 		ClosePanicDialogs();
       
  1612 
       
  1613 		if (!canGenerateDefectScenario)
       
  1614 			{
       
  1615 			//if this doesn't work out then the memory allocator is not like it was when the defect was raised!
       
  1616 			//so the test is no longer any good.
       
  1617 			if (aRetry == KRetryAmount)
       
  1618 				{
       
  1619 				INFO_PRINTF2(_L("Failed %d times - Overall test failure"),KRetryAmount);
       
  1620 				Check(EFalse);
       
  1621 				}
       
  1622 			else
       
  1623 				{
       
  1624 				INFO_PRINTF2(_L("RETRYING - attempt %d"),aRetry+2);
       
  1625 				TestFastBlendBitmapMasked(aRetry+1);
       
  1626 				}
       
  1627 			}
       
  1628 		else
       
  1629 			{
       
  1630 			INFO_PRINTF1(_L("Performing test"));
       
  1631 			for (TInt sourceModeIndex = 0; sourceModeIndex < KNumberDisplayModes1; sourceModeIndex++)
       
  1632 			 	{
       
  1633 			 	for (TInt invert = 0; invert < 2; invert++)
       
  1634 			 		{
       
  1635 			 		TDisplayMode sourceMode = TestDisplayMode1[sourceModeIndex];
       
  1636 			 		TInt sourceStride = BytesForPixels(iSize.iWidth, sourceMode);
       
  1637 			 		TBool blended = (sourceMode == EColor16MA || sourceMode == EColor16MAP);
       
  1638 			 		
       
  1639 			 		// Initialise (randomise) the buffers for this iteration
       
  1640 			 		FillBuffer((TUint8*)source, sourceStride, sourceMode, ETrue);
       
  1641 			 		FillBuffer((TUint8*)expected, destStride, iDispMode, ETrue);
       
  1642 			 		FillBuffer((TUint8*)mask, maskStride, EGray2, ETrue);
       
  1643 			 		
       
  1644 			 		// Write out the initial contents
       
  1645 			 		iDrawDevice->WriteLine(0, yPos, iSize.iWidth, (TUint32*)expected,
       
  1646 			 				CGraphicsContext::EDrawModeWriteAlpha);
       
  1647 		
       
  1648 			 		// Fast, masked overwrite, with or without mask inversion
       
  1649 			 		TInt result = fastBlend->FastBlendBitmapMasked(pt, 
       
  1650 			 				(TUint32*)source, sourceStride, lineSize, lineRect,
       
  1651 			 				sourceMode, mask, maskStride, EGray2, lineSize,
       
  1652 			 				TPoint(), invert, CGraphicsContext::EDrawModePEN, 
       
  1653 			 				CFbsDrawDevice::ENoShadow);
       
  1654 
       
  1655 			 		if (result == KErrNotSupported)
       
  1656 			 			{
       
  1657 			 			// Unsupported combination of parameters, move on.
       
  1658 			 			continue;
       
  1659 			 			}
       
  1660 		
       
  1661 			 		// Use mask to blend source with 'expected' to get the expected
       
  1662 			 		// output
       
  1663 			 		MaskedBlendBuffer(source, sourceMode, expected, iDispMode, 
       
  1664 			 				mask, iSize.iWidth, invert);
       
  1665 
       
  1666 			 		// Read back actual output and compare with expected.
       
  1667 			 		iDrawDevice->ReadLine(0, yPos, iSize.iWidth, slb, iDispMode);
       
  1668 
       
  1669 			 		if (!CompareBlendMaskResults(slb, expected, iSize.iWidth,
       
  1670 			 				iDispMode, blended, sourceMode))
       
  1671 			 			{
       
  1672 			 			INFO_PRINTF3(_L("Output mismatch: source mode %S, invert=%d"), 
       
  1673 			 					&DisplayModeNames1[sourceModeIndex], invert);
       
  1674 			 			// Report other details, plus fail the overall test.
       
  1675 			 			Check(EFalse);
       
  1676 			 			}
       
  1677 			 		iIteration++;
       
  1678 			 		}
       
  1679 
       
  1680 			 	}
       
  1681 			TTestMemThread memThreadAfter(pastBitmapData-2,pastBitmapData+2);
       
  1682 			failAt=memThreadAfter.FailOffset();
       
  1683 			if (failAt != 2)
       
  1684 				{
       
  1685 				INFO_PRINTF1(_L("Memory after bitmap is accessable - BAD"));
       
  1686 				if (aRetry >= KRetryAmount)
       
  1687 					{
       
  1688 					INFO_PRINTF2(_L("Failed %d times - Overall test failure"),KRetryAmount);
       
  1689 					Check(EFalse);
       
  1690 					}
       
  1691 				else
       
  1692 					{
       
  1693 					INFO_PRINTF2(_L("RETRYING - attempt %d"),aRetry+2);
       
  1694 					TestFastBlendBitmapMasked(aRetry+1);
       
  1695 					}
       
  1696 				}
       
  1697 			else
       
  1698 				{
       
  1699 				INFO_PRINTF1(_L("Memory after bitmap is inaccessable - GOOD"));
       
  1700 				}
       
  1701 			ClosePanicDialogs();
       
  1702 			}
       
  1703 		if (aRetry == 0)
       
  1704 			{
       
  1705 			INFO_PRINTF1(_L("END ---->TestFastBlendBitmapMasked"));
       
  1706 			Report();
       
  1707 			}
       
  1708 
       
  1709 		User::Free(source);
       
  1710 		User::Free(expected);
       
  1711 		testBitmap.Reset();
       
  1712 		}
       
  1713 	}
       
  1714 
       
  1715 void CTLowLevel::TestWriteRGBAlpha()
       
  1716 	{
       
  1717 	TUint8* writeBuffer = new TUint8[iSize.iWidth * 4];
       
  1718 	TUint8* writeBuffer2 = new TUint8[iSize.iWidth * 4];
       
  1719 	TUint8* maskBuffer = new TUint8[iSize.iWidth];
       
  1720 	Check(writeBuffer != NULL);
       
  1721 	Check(maskBuffer != NULL);
       
  1722 
       
  1723 	TInt nRect;
       
  1724 
       
  1725 	//special test for EColor16MAP
       
  1726 	if (iDispMode == EColor16MAP)
       
  1727 		{
       
  1728 		//mask fill has vaues 0x00, 0xff, and 0x3A.  The mask is used for blending
       
  1729 		for (TInt maskFillCount=0; maskFillCount<KMaskFill;maskFillCount++)
       
  1730 			{
       
  1731 			for (TInt userDispMode=0; userDispMode< KUserDispModes; userDispMode++)
       
  1732 				{
       
  1733 				for (TInt shadowMode = 0; shadowMode < KNumShadowModes; shadowMode++)
       
  1734 					{
       
  1735 					for (nRect = 0; nRect < KNumTestRects; nRect++)
       
  1736 						{
       
  1737 						for (TInt nBackColor = 0; nBackColor < KNumTestBackgrounds; nBackColor++)
       
  1738 							{
       
  1739 							for (TInt nColor = 0; nColor < KNumTestColors; nColor++)
       
  1740 								{
       
  1741 								iDrawDevice->SetUserDisplayMode(UserDisplayModes[userDispMode]);
       
  1742 								iUserDispMode = UserDisplayModes[userDispMode];
       
  1743 								if (iUserDispMode == EColor16MA)
       
  1744 									i16MAUserDispMode = ETrue;
       
  1745 								else
       
  1746 									i16MAUserDispMode = EFalse;
       
  1747 
       
  1748 								TRgb col = TestColor[nColor];
       
  1749 								TUint32 internal = col.Internal();
       
  1750 								TUint32 *writeBuf32 = (TUint32*)writeBuffer;
       
  1751 								TInt cnt;
       
  1752 								//fill the buffer with colour
       
  1753 								for (cnt=0;cnt<iSize.iWidth;cnt++)
       
  1754 									{
       
  1755 									*writeBuf32=internal;
       
  1756 									writeBuf32++;
       
  1757 									}
       
  1758 
       
  1759 								Mem::Fill(maskBuffer,iSize.iWidth,MaskFill[maskFillCount]);
       
  1760 
       
  1761 								TRgb bakCol = TestBackground[nBackColor];
       
  1762 								Clear(bakCol);
       
  1763 								TRect rect = TestRect[nRect];
       
  1764 
       
  1765 								iDrawDevice->CFbsDrawDevice::SetShadowMode(CFbsDrawDevice::TShadowMode(shadowMode));
       
  1766 								iDrawDevice->CFbsDrawDevice::SetFadingParameters(100,200);
       
  1767 								iDrawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(shadowMode));
       
  1768 
       
  1769 								TInt yy;
       
  1770 								for (yy = rect.iTl.iY; yy < rect.iBr.iY; yy++)
       
  1771 									{
       
  1772 									iDrawDevice->WriteRgbAlphaLine(rect.iTl.iX,yy,rect.Width(),writeBuffer,maskBuffer,CGraphicsContext::EDrawModePEN);
       
  1773 									iIteration++;
       
  1774 									}
       
  1775 
       
  1776 								//ensure the colour has the 0xff mask value
       
  1777 								TRgb checkColor;
       
  1778 								//use a combined alpha for the check colour
       
  1779 								TUint32 combinedAlpha = MaskFill[maskFillCount]*((internal&0xff000000)>>24);
       
  1780 								combinedAlpha = ((combinedAlpha <<16) & 0xff000000);
       
  1781 								checkColor.SetInternal((internal&0x00ffffff)|combinedAlpha);
       
  1782 								//check colour is not a PMA colour, but has alpha
       
  1783 								CheckRgb(rect,checkColor,bakCol,CGraphicsContext::EDrawModePEN,CFbsDrawDevice::TShadowMode(shadowMode));
       
  1784 								CheckBackground(rect,bakCol);
       
  1785 
       
  1786 								//the other WriteRgbAlpha line uses the other shadow mode
       
  1787 								TUint32 *writeBuf2 = (TUint32*)writeBuffer2;
       
  1788 								TUint32 buf2val= NonPMA2PMAPixel(bakCol.Internal());
       
  1789 								//fill the buffer with colour
       
  1790 								for (cnt=0;cnt<iSize.iWidth;cnt++)
       
  1791 									{
       
  1792 									*writeBuf2=buf2val;
       
  1793 									writeBuf2++;
       
  1794 									}
       
  1795 
       
  1796 								iDrawDevice->CFbsDrawDevice::SetShadowMode(CFbsDrawDevice::TShadowMode(shadowMode));
       
  1797 								iDrawDevice->CFbsDrawDevice::SetFadingParameters(100,200);
       
  1798 								iDrawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(shadowMode));
       
  1799 
       
  1800 								for (yy = rect.iTl.iY; yy < rect.iBr.iY; yy++)
       
  1801 									{
       
  1802 									iDrawDevice->WriteRgbAlphaLine(rect.iTl.iX,yy,rect.Width(),
       
  1803 										writeBuffer,
       
  1804 										writeBuffer2,
       
  1805 										maskBuffer,
       
  1806 										CGraphicsContext::EDrawModeWriteAlpha);
       
  1807 									iIteration++;
       
  1808 									}
       
  1809 								//require to Shadow After the checkColor, no shadow with a zero mask
       
  1810 								TBool shadowModeChanged = EFalse;
       
  1811 								if (MaskFill[maskFillCount])
       
  1812 									{
       
  1813 									iPostBlendShadow = (TPostShadowMode) shadowMode;
       
  1814 									shadowMode = 0;
       
  1815 									shadowModeChanged = ETrue;
       
  1816 									}
       
  1817 								CheckRgb(rect,checkColor,bakCol,CGraphicsContext::EDrawModePEN,shadowMode);
       
  1818 								if(shadowModeChanged) shadowMode = iPostBlendShadow;
       
  1819 								iPostBlendShadow = ENoPostShadow;
       
  1820 								CheckBackground(rect,bakCol);
       
  1821 
       
  1822 								Clear(bakCol);
       
  1823 
       
  1824 								iDrawDevice->CFbsDrawDevice::SetShadowMode(CFbsDrawDevice::TShadowMode(shadowMode));
       
  1825 								iDrawDevice->CFbsDrawDevice::SetFadingParameters(100,200);
       
  1826 								iDrawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(shadowMode));
       
  1827 
       
  1828 								for (TInt yy2 = rect.iTl.iY; yy2 < rect.iBr.iY; yy2++)
       
  1829 									{
       
  1830 									iDrawDevice->WriteRgbAlphaMulti(rect.iTl.iX,yy2,rect.Width(),col,maskBuffer);
       
  1831 									iIteration++;
       
  1832 									}
       
  1833 
       
  1834 								CheckRgb(rect,checkColor,bakCol,CGraphicsContext::EDrawModePEN,CFbsDrawDevice::TShadowMode(shadowMode));
       
  1835 								CheckBackground(rect,bakCol);
       
  1836 								}
       
  1837 							}
       
  1838 						}
       
  1839 					}
       
  1840 				}
       
  1841 			}
       
  1842 		}
       
  1843 
       
  1844 	Report();
       
  1845 	iDrawDevice->SetUserDisplayMode(iDispMode);
       
  1846 	i16MAUserDispMode = EFalse;
       
  1847 	iUserDispMode = ENone;
       
  1848 	Mem::Fill(writeBuffer,iSize.iWidth * 4,0xff);
       
  1849 	Mem::Fill(maskBuffer,iSize.iWidth,0xff);
       
  1850 
       
  1851 	for (nRect = 0; nRect < KNumTestRects; nRect++)
       
  1852 		{
       
  1853 		for (TInt nBackColor = 0; nBackColor < KNumTestBackgrounds; nBackColor++)
       
  1854 			{
       
  1855 			if ((nBackColor>=KMaxNon16BackColours) && (iDispMode!= EColor16MAP))
       
  1856 				continue;
       
  1857 
       
  1858 			TRgb bakCol = TestBackground[nBackColor];
       
  1859 			Clear(bakCol);
       
  1860 			TRect rect = TestRect[nRect];
       
  1861 
       
  1862 			for (TInt yy = rect.iTl.iY; yy < rect.iBr.iY; yy++)
       
  1863 				{
       
  1864 				iDrawDevice->WriteRgbAlphaLine(rect.iTl.iX,yy,rect.Width(),writeBuffer,maskBuffer,CGraphicsContext::EDrawModePEN);
       
  1865 				iIteration++;
       
  1866 				}
       
  1867 
       
  1868 			CheckRgb(rect,KRgbWhite,bakCol,CGraphicsContext::EDrawModePEN,0);
       
  1869 			CheckBackground(rect,bakCol);
       
  1870 
       
  1871 			Clear(bakCol);
       
  1872 
       
  1873 			for (TInt yy2 = rect.iTl.iY; yy2 < rect.iBr.iY; yy2++)
       
  1874 				{
       
  1875 				iDrawDevice->WriteRgbAlphaMulti(rect.iTl.iX,yy2,rect.Width(),KRgbWhite,maskBuffer);
       
  1876 				iIteration++;
       
  1877 				}
       
  1878 
       
  1879 			CheckRgb(rect,KRgbWhite,bakCol,CGraphicsContext::EDrawModePEN,0);
       
  1880 			CheckBackground(rect,bakCol);
       
  1881 
       
  1882 			}
       
  1883 		}
       
  1884 	Report();
       
  1885 
       
  1886 	Mem::FillZ(writeBuffer,iSize.iWidth * 3);
       
  1887 
       
  1888 	for (nRect = 0; nRect < KNumTestRects; nRect++)
       
  1889 		{
       
  1890 		for (TInt nBackColor = 0; nBackColor < KNumTestBackgrounds; nBackColor++)
       
  1891 			{
       
  1892 			if ((nBackColor>=KMaxNon16BackColours) && (iDispMode!= EColor16MAP))
       
  1893 				continue;
       
  1894 
       
  1895 			//need to fill with 0xff alpha, so blending takes place
       
  1896 			if (iDispMode== EColor16MAP)
       
  1897 				{
       
  1898 				const TUint32 black = 0xff000000;
       
  1899 				TUint32 *writeBuf32 = (TUint32*) writeBuffer;
       
  1900 				for (TInt cnt=0;cnt<iSize.iWidth;cnt++)
       
  1901 					{
       
  1902 					*writeBuf32=black;
       
  1903 					writeBuf32++;
       
  1904 					}
       
  1905 				}
       
  1906 
       
  1907 			TRgb bakCol = TestBackground[nBackColor];
       
  1908 			Clear(bakCol);
       
  1909 			TRect rect = TestRect[nRect];
       
  1910 
       
  1911 			for (TInt yy = rect.iTl.iY; yy < rect.iBr.iY; yy++)
       
  1912 				{
       
  1913 				iDrawDevice->WriteRgbAlphaLine(rect.iTl.iX,yy,rect.Width(),writeBuffer,maskBuffer,CGraphicsContext::EDrawModePEN);
       
  1914 				iIteration++;
       
  1915 				}
       
  1916 
       
  1917 			CheckRgb(rect,KRgbBlack,bakCol,CGraphicsContext::EDrawModePEN,0);
       
  1918 			CheckBackground(rect,bakCol);
       
  1919 
       
  1920 			Clear(bakCol);
       
  1921 
       
  1922 			for (TInt yy2 = rect.iTl.iY; yy2 < rect.iBr.iY; yy2++)
       
  1923 				{
       
  1924 				iDrawDevice->WriteRgbAlphaMulti(rect.iTl.iX,yy2,rect.Width(),KRgbBlack,maskBuffer);
       
  1925 				iIteration++;
       
  1926 				}
       
  1927 
       
  1928 			CheckRgb(rect,KRgbBlack,bakCol,CGraphicsContext::EDrawModePEN,0);
       
  1929 			CheckBackground(rect,bakCol);
       
  1930 			}
       
  1931 		}
       
  1932 	Report();
       
  1933 
       
  1934 	Mem::FillZ(maskBuffer,iSize.iWidth);
       
  1935 
       
  1936 	for (nRect = 0; nRect < KNumTestRects; nRect++)
       
  1937 		{
       
  1938 		for (TInt nBackColor = 0; nBackColor < KNumTestBackgrounds; nBackColor++)
       
  1939 			{
       
  1940 			if ((nBackColor>=KMaxNon16BackColours) && (iDispMode!= EColor16MAP))
       
  1941 				continue;
       
  1942 
       
  1943 			TRgb bakCol = TestBackground[nBackColor];
       
  1944 			Clear(bakCol);
       
  1945 			TRect rect = TestRect[nRect];
       
  1946 
       
  1947 			for (TInt yy = rect.iTl.iY; yy < rect.iBr.iY; yy++)
       
  1948 				{
       
  1949 				iDrawDevice->WriteRgbAlphaLine(rect.iTl.iX,yy,rect.Width(),writeBuffer,maskBuffer,CGraphicsContext::EDrawModePEN);
       
  1950 				iIteration++;
       
  1951 				}
       
  1952 
       
  1953 			TRgb checkColor2=bakCol;
       
  1954 			if (iDispMode == EColor16MAP)
       
  1955 				checkColor2.SetInternal (0);
       
  1956 
       
  1957 			CheckRgb(rect,checkColor2,bakCol,CGraphicsContext::EDrawModePEN,0);
       
  1958 			CheckBackground(rect,bakCol);
       
  1959 
       
  1960 			Clear(bakCol);
       
  1961 
       
  1962 			for (TInt yy2 = rect.iTl.iY; yy2 < rect.iBr.iY; yy2++)
       
  1963 				{
       
  1964 				iDrawDevice->WriteRgbAlphaMulti(rect.iTl.iX,yy2,rect.Width(),KRgbBlack,maskBuffer);
       
  1965 				iIteration++;
       
  1966 				}
       
  1967 
       
  1968 			CheckRgb(rect,checkColor2,bakCol,CGraphicsContext::EDrawModePEN,0);
       
  1969 			CheckBackground(rect,bakCol);
       
  1970 
       
  1971 			}
       
  1972 		}
       
  1973 	Report();
       
  1974 
       
  1975 	Mem::Fill(writeBuffer,iSize.iWidth * 3,0xff);
       
  1976 
       
  1977 	for (nRect = 0; nRect < KNumTestRects; nRect++)
       
  1978 		{
       
  1979 		for (TInt nBackColor = 0; nBackColor < KNumTestBackgrounds; nBackColor++)
       
  1980 			{
       
  1981 			if ((nBackColor>=KMaxNon16BackColours) && (iDispMode!= EColor16MAP))
       
  1982 				continue;
       
  1983 
       
  1984 			TRgb bakCol = TestBackground[nBackColor];
       
  1985 			Clear(bakCol);
       
  1986 			TRect rect = TestRect[nRect];
       
  1987 
       
  1988 			for (TInt yy = rect.iTl.iY; yy < rect.iBr.iY; yy++)
       
  1989 				{
       
  1990 				iDrawDevice->WriteRgbAlphaLine(rect.iTl.iX,yy,rect.Width(),writeBuffer,maskBuffer,CGraphicsContext::EDrawModePEN);
       
  1991 				iIteration++;
       
  1992 				}
       
  1993 			TRgb checkColor3=bakCol;
       
  1994 			if (iDispMode == EColor16MAP)
       
  1995 				checkColor3.SetInternal (0xffffff);
       
  1996 
       
  1997 			CheckRgb(rect,checkColor3,bakCol,CGraphicsContext::EDrawModePEN,0);
       
  1998 			CheckBackground(rect,bakCol);
       
  1999 
       
  2000 			Clear(bakCol);
       
  2001 
       
  2002 			for (TInt yy2 = rect.iTl.iY; yy2 < rect.iBr.iY; yy2++)
       
  2003 				{
       
  2004 				iDrawDevice->WriteRgbAlphaMulti(rect.iTl.iX,yy2,rect.Width(),KRgbWhite,maskBuffer);
       
  2005 				iIteration++;
       
  2006 				}
       
  2007 
       
  2008 			CheckRgb(rect,checkColor3,bakCol,CGraphicsContext::EDrawModePEN,0);
       
  2009 			CheckBackground(rect,bakCol);
       
  2010 			}
       
  2011 		}
       
  2012 	Report();
       
  2013 
       
  2014 	//Extra test for DEF082251
       
  2015 	if (iDispMode==EColor16MU)
       
  2016 		{
       
  2017 		Mem::Fill(maskBuffer,iSize.iWidth,0x7f);
       
  2018 
       
  2019 		for (nRect = 0; nRect < KNumTestRects; nRect++)
       
  2020 			{
       
  2021 			for (TInt nBackColor = 0; nBackColor < KNumTestBackgrounds; nBackColor++)
       
  2022 				{
       
  2023 				TRgb bakCol = TestBackground[nBackColor];
       
  2024 				Clear(bakCol);
       
  2025 				TRect rect=TestRect[nRect];
       
  2026 
       
  2027 				const TInt red = 50;
       
  2028 				const TInt green = 60;
       
  2029 				const TInt blue = 70;
       
  2030 				const TInt alpha = 80;
       
  2031 
       
  2032 				for (TInt yy2 = rect.iTl.iY; yy2 < rect.iBr.iY; yy2++)
       
  2033 					{
       
  2034 					iDrawDevice->WriteRgbAlphaMulti(rect.iTl.iX,yy2,rect.Width(),
       
  2035 					TRgb(red,green,blue,alpha),maskBuffer);
       
  2036 					iIteration++;
       
  2037 					}
       
  2038 
       
  2039 				//work out the color - based on OptimizedBlend32 in the
       
  2040 				//screendriver bmdraw32.cpp
       
  2041 				TInt combinedAlpha = (alpha * 0x7f)>>8;
       
  2042 
       
  2043 				const TUint32 alphaValue = (combinedAlpha << 8) + combinedAlpha;
       
  2044  				TUint32 secondary= bakCol.Value();
       
  2045 
       
  2046  				const TInt r2 = secondary & 0x000000ff;
       
  2047  				const TInt g2 = (secondary & 0x0000ff00) >> 8;
       
  2048  				const TInt b2 = (secondary & 0x00ff0000) >> 16;
       
  2049 
       
  2050  				const TInt r3 = ((alphaValue * (red   - r2)) >> 16) + r2;
       
  2051 				const TInt g3 = ((alphaValue * (green - g2)) >> 16) + g2;
       
  2052 				const TInt b3 = ((alphaValue * (blue  - b2)) >> 16) + b2;
       
  2053 
       
  2054 				TInt result= (b3 & 0xFF) | ((g3<<8) & 0xFF00) | ((r3<<16) & 0xFF0000) | 0xFF000000;
       
  2055 				TRgb resultColor = TRgb(result,0);
       
  2056 
       
  2057 				CheckRgb(rect,resultColor,bakCol,CGraphicsContext::EDrawModePEN,0);
       
  2058 				CheckBackground(rect,bakCol);
       
  2059 				}
       
  2060 			}
       
  2061 			Report();
       
  2062 		}
       
  2063 	delete [] writeBuffer;
       
  2064 	delete [] maskBuffer;
       
  2065 	delete [] writeBuffer2;
       
  2066 	}
       
  2067 
       
  2068 void CTLowLevel::TestShadow()
       
  2069 	{
       
  2070 	for (TInt shadowMode = 0; shadowMode < KNumShadowModes; shadowMode++)
       
  2071 		{
       
  2072 		for (TInt nRect = 0; nRect < KNumTestRects; nRect++)
       
  2073 			{
       
  2074 			for (TInt nColor = 0; nColor < KNumTestColors; nColor++)
       
  2075 				{
       
  2076 				if ((nColor>=KMaxNon16Colours) && (iDispMode!= EColor16MAP))
       
  2077 					continue;
       
  2078 
       
  2079 				TRgb col = TestColor[nColor];
       
  2080 				Clear(col);
       
  2081 
       
  2082 				TRect rect = TestRect[nRect];
       
  2083 
       
  2084 				iDrawDevice->SetShadowMode(CFbsDrawDevice::TShadowMode(shadowMode));
       
  2085 				iDrawDevice->ShadowArea(rect);
       
  2086 
       
  2087 				CheckShadowRgb(rect,col,shadowMode);
       
  2088 
       
  2089 				TRgb checkColor=col;
       
  2090 				if (iDispMode == EColor16MAP)
       
  2091 					{
       
  2092 					checkColor.SetInternal (0); //only want contribution from one colour
       
  2093 					}
       
  2094 
       
  2095 				TRect outside(0,0,iSize.iWidth,rect.iTl.iY);
       
  2096 				if (!outside.IsEmpty())
       
  2097 					CheckRgb(outside,checkColor,col,CGraphicsContext::EDrawModePEN,0);
       
  2098 				outside.SetRect(0,rect.iBr.iY,iSize.iWidth,iSize.iHeight);
       
  2099 				if (!outside.IsEmpty())
       
  2100 					CheckRgb(outside,checkColor,col,CGraphicsContext::EDrawModePEN,0);
       
  2101 				outside.SetRect(0,rect.iTl.iY,rect.iTl.iX,rect.iBr.iY);
       
  2102 				if (!outside.IsEmpty())
       
  2103 					CheckRgb(outside,checkColor,col,CGraphicsContext::EDrawModePEN,0);
       
  2104 				outside.SetRect(rect.iBr.iX,rect.iTl.iY,iSize.iWidth,rect.iBr.iY);
       
  2105 				if (!outside.IsEmpty())
       
  2106 					CheckRgb(outside,checkColor,col,CGraphicsContext::EDrawModePEN,0);
       
  2107 				iIteration++;
       
  2108 				}
       
  2109 			}
       
  2110 		Report();
       
  2111 		}
       
  2112 	}
       
  2113 
       
  2114 /**
       
  2115 	@SYMTestCaseID GRAPHICS-SCREENDRIVER-0002
       
  2116 
       
  2117 	@SYMPREQ PREQ1543
       
  2118 
       
  2119 	@SYMTestCaseDesc This test code tests WriteRgbOutlineAndShadow() which blends the four colours.
       
  2120 	Colours used for blending are outline, shadow, foreground and background.
       
  2121 
       
  2122 	@SYMTestPriority High
       
  2123 
       
  2124 	@SYMTestStatus Implemented
       
  2125 
       
  2126 	@SYMTestActions It compares the colour written by WriteRgbOutlineAndShadow() with colour
       
  2127 	calculated using lookup table provided by Monotype.
       
  2128 	API Calls:
       
  2129 	CDrawBitmap::GetInterface()
       
  2130 	MOutlineAndShadowBlend::WriteRgbOutlineAndShadow()
       
  2131 	CDrawBitmap::ReadLine()
       
  2132 
       
  2133 	@SYMTestExpectedResults Test should pass and colour written by WriteRgbOutlineAndShadow should
       
  2134 	match with the colour calculated through lookup table.
       
  2135 */
       
  2136 void CTLowLevel::TestWriteRgbOutlineAndShadow()
       
  2137 	{
       
  2138 	MOutlineAndShadowBlend* outlineAndShadow = NULL;
       
  2139 	TInt byteSize = ByteSize();
       
  2140 	TUint8* writeBuffer = new TUint8[iSize.iWidth * sizeof(TRgb)];
       
  2141 	TUint8* readBuffer = new TUint8[iSize.iWidth * sizeof(TRgb)];
       
  2142 	TColorConvertor& colorConvertor = ColorConvertor(iDispMode);
       
  2143 	Check(writeBuffer != NULL);
       
  2144 	Check(readBuffer != NULL);
       
  2145 	TInt err = iDrawDevice->GetInterface(KOutlineAndShadowInterfaceID, reinterpret_cast <TAny*&> (outlineAndShadow));
       
  2146 	Check(err == KErrNone);
       
  2147 
       
  2148 	TRect rect = TestRect[0];
       
  2149 	for (TInt nBlendingColors = 0; nBlendingColors < KNumBlendingColors; nBlendingColors++)
       
  2150 		{
       
  2151 		// Select different combinations of colours for testing from the array
       
  2152 		TRgb outlinePenColor = TestOSFBColorsForBlending[nBlendingColors][0];
       
  2153 		TRgb shadowColor = TestOSFBColorsForBlending[nBlendingColors][1];
       
  2154 		TRgb fillColor = TestOSFBColorsForBlending[nBlendingColors][2];
       
  2155 		TRgb backgroundColor = colorConvertor.Color(colorConvertor.Index(TestOSFBColorsForBlending[nBlendingColors][3]));
       
  2156 		Clear(backgroundColor);
       
  2157 		for (TInt yy = rect.iTl.iY; yy < rect.iBr.iY; yy++)
       
  2158 			{
       
  2159 			// Run the test for values from 0 to 255 so that it will cover all the entries
       
  2160 			// of lookup table provided by Monotype
       
  2161 			for (TInt index = 0; index < 256; index++)
       
  2162 				{
       
  2163 				// In case alpha is supported and if alpha value is less than 255 then the colour drawn will be different
       
  2164 				// than the colour specified as it blends with the existing background pixel colour.
       
  2165 				TRgb backgroundColorDrawn= iDrawDevice->ReadPixel(rect.iTl.iX, yy);
       
  2166 
       
  2167 				// Fill zeroes in the readBuffer so that we can make sure that there is no garbage value.
       
  2168 				Mem::FillZ(readBuffer, iSize.iWidth * 3);
       
  2169 
       
  2170 				// We are writing index in writeBuffer to simulate the buffer provided by rasterizer
       
  2171 				// This index should be a value between 0-255, It would be corresponding the entries of lookup table
       
  2172 				Mem::Fill(writeBuffer, iSize.iWidth * 3, index);
       
  2173 
       
  2174 				// Below function blends outline, shadow, foreground and background colours, and writes aLength pixels with new colour
       
  2175 				// starting from aX, aY.
       
  2176 				err = outlineAndShadow->WriteRgbOutlineAndShadow(rect.iTl.iX, yy , rect.Width(), outlinePenColor.Internal(),
       
  2177 																					shadowColor.Internal(),fillColor.Internal(),writeBuffer);
       
  2178 				Check(err == KErrNone);
       
  2179 
       
  2180 				// Read the whole line which has been written by WriteRgbOutlineAndShadow()
       
  2181 				iDrawDevice->ReadLine(rect.iTl.iX, yy, rect.Width(), (TUint32*)readBuffer, iDispMode);
       
  2182 
       
  2183 				// Check colour of each pixel, it should be same as the colour which is calulated manually in CheckBlendedOutlineAndShadow()
       
  2184 				TBool result = CheckBlendedOutlineAndShadow(outlinePenColor, shadowColor, fillColor, backgroundColorDrawn, index, rect.Width(), readBuffer);
       
  2185 				Check(result);
       
  2186 				if (!result)
       
  2187 					{
       
  2188 					Report();
       
  2189 					delete [] writeBuffer;
       
  2190 					delete [] readBuffer;
       
  2191 					return;
       
  2192 					}
       
  2193 
       
  2194 				iIteration++;
       
  2195 				}
       
  2196 			}
       
  2197 		Report();
       
  2198 		}
       
  2199 	delete [] writeBuffer;
       
  2200 	delete [] readBuffer;
       
  2201 	}
       
  2202 
       
  2203 inline TInt CTLowLevel::ByteSize()
       
  2204 	{
       
  2205 	return ::ByteSize(iDispMode,iSize.iWidth);
       
  2206 	}
       
  2207 
       
  2208 TInt CTLowLevel::LongWidth(TInt aWidth,TDisplayMode aDispMode)
       
  2209 	{
       
  2210 	switch (aDispMode)
       
  2211 		{
       
  2212 	case EGray2:
       
  2213 		return (aWidth + 31) & ~31;
       
  2214 	case EGray4:
       
  2215 		return (aWidth + 15) & ~15;
       
  2216 	case EGray16:
       
  2217 	case EColor16:
       
  2218 		return (aWidth + 7) & ~7;
       
  2219 	case EGray256:
       
  2220 	case EColor256:
       
  2221 		return (aWidth + 3) & ~3;
       
  2222 	case EColor4K:
       
  2223 	case EColor64K:
       
  2224 		return (aWidth + 1) & ~1;
       
  2225 	case EColor16M:
       
  2226 		return (((aWidth * 3) + 11) / 12) * 4;
       
  2227 	case EColor16MU:
       
  2228 	case EColor16MA:
       
  2229 	case EColor16MAP:
       
  2230 		return aWidth;
       
  2231 	default:
       
  2232 		break;
       
  2233 		};
       
  2234 	return 0;
       
  2235 	}
       
  2236 
       
  2237 void CTLowLevel::Clear(TRgb aColor)
       
  2238 	{
       
  2239 	iDrawDevice->SetShadowMode(CFbsDrawDevice::ENoShadow);
       
  2240 	iDrawDevice->WriteRgbMulti(0,0,iSize.iWidth,iSize.iHeight,aColor,CGraphicsContext::EDrawModeWriteAlpha);
       
  2241 	}
       
  2242 
       
  2243 /*
       
  2244 Fill aBuffer with aByteSize random bytes in such a way that the result is a
       
  2245 valid scan line buffer for a driver of which the display mode is aDispMode.
       
  2246 If aDispMode is EColor16MU, the alpha bytes will be 0xFF if aNoAlpha16MU is ETrue,
       
  2247 or random bytes if aNoAlpha16MU is EFalse.
       
  2248 */
       
  2249 void CTLowLevel::FillBuffer(TUint8* aBuffer, TInt aByteSize, TDisplayMode aDispMode, TBool aNoAlpha16MU)
       
  2250 	{
       
  2251 	TUint8* bufferLimit = aBuffer + aByteSize;
       
  2252 	TUint8* buffer=aBuffer;
       
  2253 
       
  2254 	TInt64 seed = TInt64(TInt(aBuffer) * aByteSize * aDispMode * User::TickCount());
       
  2255 
       
  2256 	if (aDispMode != EColor16MU || !aNoAlpha16MU)
       
  2257 		{
       
  2258 		while (aBuffer < bufferLimit)
       
  2259 			{
       
  2260 			*aBuffer++ = (TUint8)Math::Rand(seed);
       
  2261 			}
       
  2262 		}
       
  2263 	else
       
  2264 		{
       
  2265 		while (aBuffer < bufferLimit)
       
  2266 			{
       
  2267 			if (TInt(aBuffer) & 3 == 3)
       
  2268 				*aBuffer++ = 0xFF;
       
  2269 			else
       
  2270 				*aBuffer++ = (TUint8)Math::Rand(seed);
       
  2271 			}
       
  2272 		}
       
  2273 	if (aDispMode == EColor16MU && !aNoAlpha16MU || aDispMode == EColor16MAP)
       
  2274 		{
       
  2275 		//need to do the premultiply alpha to ensure that all the colours are valid
       
  2276 		//in the colour space
       
  2277 		for (;buffer < (bufferLimit-3);buffer+=4)
       
  2278 			{
       
  2279 			TUint alpha=*(buffer+3);
       
  2280 			*(buffer)=((*(buffer))* alpha)/255; //do a pre multiply alpha operation
       
  2281 			*(buffer+1)=((*(buffer+1))* alpha)/255;
       
  2282 			*(buffer+2)=((*(buffer+2))* alpha)/255;
       
  2283 			}
       
  2284 		}
       
  2285 
       
  2286 	}
       
  2287 
       
  2288 void CTLowLevel::CheckBuffer(TUint8* aWriteBuffer,TDisplayMode aWriteDispMode,TUint8* aReadBuffer,TDisplayMode aReadDispMode,TInt aPixelLength)
       
  2289 	{
       
  2290 	switch (aWriteDispMode)
       
  2291 		{
       
  2292 	case EGray2:
       
  2293 		CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EGray2);
       
  2294 		break;
       
  2295 	case EGray4:
       
  2296 		if (aReadDispMode == EGray2)
       
  2297 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EGray2);
       
  2298 		else
       
  2299 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EGray4);
       
  2300 		break;
       
  2301 	case EGray16:
       
  2302 		if (aReadDispMode == EGray2)
       
  2303 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EGray2);
       
  2304 		else if (aReadDispMode == EGray4)
       
  2305 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EGray4);
       
  2306 		else if (aReadDispMode == EColor16)
       
  2307 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EColor16);
       
  2308 		else
       
  2309 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EGray16);
       
  2310 		break;
       
  2311 	case EGray256:
       
  2312 		switch (aReadDispMode)
       
  2313 			{
       
  2314 		case EGray2:
       
  2315 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EGray2);
       
  2316 			break;
       
  2317 		case EGray4:
       
  2318 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EGray4);
       
  2319 			break;
       
  2320 		case EGray16:
       
  2321 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EGray16);
       
  2322 			break;
       
  2323 		case EGray256:
       
  2324 		case EColor16M:
       
  2325 		case ERgb:
       
  2326 		case EColor16MU:
       
  2327 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EGray256);
       
  2328 			break;
       
  2329 		case EColor16:
       
  2330 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EColor16);
       
  2331 			break;
       
  2332 		case EColor256:
       
  2333 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EColor256);
       
  2334 			break;
       
  2335 		case EColor4K:
       
  2336 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EColor4K);
       
  2337 			break;
       
  2338 		case EColor64K:
       
  2339 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EColor64K);
       
  2340 			break;
       
  2341 		default:
       
  2342 			break;
       
  2343 			}
       
  2344 		break;
       
  2345 	case EColor16:
       
  2346 		switch (aReadDispMode)
       
  2347 			{
       
  2348 		case EGray2:
       
  2349 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EGray2);
       
  2350 			break;
       
  2351 		case EGray4:
       
  2352 		case EGray16:
       
  2353 		case EGray256:
       
  2354 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EGray4);
       
  2355 			break;
       
  2356 		case EColor16:
       
  2357 		case EColor256:
       
  2358 		case EColor4K:
       
  2359 		case EColor64K:
       
  2360 		case EColor16M:
       
  2361 		case ERgb:
       
  2362 		case EColor16MU:
       
  2363 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EColor16);
       
  2364 			break;
       
  2365 		default:
       
  2366 			break;
       
  2367 			}
       
  2368 		break;
       
  2369 	case EColor256:
       
  2370 		switch (aReadDispMode)
       
  2371 			{
       
  2372 		case EGray2:
       
  2373 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EGray2);
       
  2374 			break;
       
  2375 		case EGray4:
       
  2376 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EGray4);
       
  2377 			break;
       
  2378 		case EGray16:
       
  2379 		case EGray256:
       
  2380 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EGray16);
       
  2381 			break;
       
  2382 		case EColor16:
       
  2383 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EColor16);
       
  2384 			break;
       
  2385 		case EColor256:
       
  2386 		case EColor4K:
       
  2387 		case EColor64K:
       
  2388 		case EColor16M:
       
  2389 		case ERgb:
       
  2390 		case EColor16MU:
       
  2391 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EColor256);
       
  2392 			break;
       
  2393 		default:
       
  2394 			break;
       
  2395 			}
       
  2396 		break;
       
  2397 	case EColor4K:
       
  2398 		switch (aReadDispMode)
       
  2399 			{
       
  2400 		case EGray2:
       
  2401 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EGray2);
       
  2402 			break;
       
  2403 		case EGray4:
       
  2404 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EGray4);
       
  2405 			break;
       
  2406 		case EGray16:
       
  2407 		case EGray256:
       
  2408 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EGray16);
       
  2409 			break;
       
  2410 		case EColor16:
       
  2411 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EColor16);
       
  2412 			break;
       
  2413 		case EColor256:
       
  2414 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EColor256);
       
  2415 			break;
       
  2416 		case EColor4K:
       
  2417 		case EColor64K:
       
  2418 		case EColor16M:
       
  2419 		case ERgb:
       
  2420 		case EColor16MU:
       
  2421 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EColor4K);
       
  2422 			break;
       
  2423 		default:
       
  2424 			break;
       
  2425 			}
       
  2426 		break;
       
  2427 	case EColor64K:
       
  2428 		switch (aReadDispMode)
       
  2429 			{
       
  2430 		case EGray2:
       
  2431 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EGray2);
       
  2432 			break;
       
  2433 		case EGray4:
       
  2434 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EGray4);
       
  2435 			break;
       
  2436 		case EGray16:
       
  2437 		case EGray256:
       
  2438 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EGray16);
       
  2439 			break;
       
  2440 		case EColor16:
       
  2441 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EColor16);
       
  2442 			break;
       
  2443 		case EColor256:
       
  2444 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EColor256);
       
  2445 			break;
       
  2446 		case EColor4K:
       
  2447 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EColor4K);
       
  2448 			break;
       
  2449 		case EColor64K:
       
  2450 		case EColor16M:
       
  2451 		case ERgb:
       
  2452 		case EColor16MU:
       
  2453 			CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,EColor64K);
       
  2454 			break;
       
  2455 		default:
       
  2456 			break;
       
  2457 			}
       
  2458 		break;
       
  2459 	case EColor16M:
       
  2460 	case EColor16MU:
       
  2461 	case EColor16MA:
       
  2462 	case EColor16MAP:
       
  2463 		CheckPixel(aWriteBuffer,aWriteDispMode,aReadBuffer,aReadDispMode,aPixelLength,aReadDispMode);
       
  2464 		break;
       
  2465 	default:
       
  2466 		break;
       
  2467 		};
       
  2468 	}
       
  2469 
       
  2470 void CTLowLevel::CheckPixel(TUint8* aWriteBuffer,TDisplayMode aWriteDispMode,TUint8* aReadBuffer,TDisplayMode aReadDispMode,TInt aPixelLength,TDisplayMode aCompareDispMode)
       
  2471 	{
       
  2472 	TColorConvertor& colorConvertor = ColorConvertor(aCompareDispMode);
       
  2473 
       
  2474 	for (TInt count = 0; count < aPixelLength; count++)
       
  2475 		{
       
  2476 		TRgb writeValue = ExtractRgbValue(count,aWriteBuffer,aWriteDispMode);
       
  2477 		TRgb readValue = ExtractRgbValue(count,aReadBuffer,aReadDispMode);
       
  2478 		CheckMatch(colorConvertor.Index(writeValue),colorConvertor.Index(readValue));
       
  2479 		}
       
  2480 	}
       
  2481 
       
  2482 void CTLowLevel::CheckRgb(const TPoint& aPoint,TRgb aColor,TRgb aBackgroundColor,CGraphicsContext::TDrawMode aDrawMode,TInt aShadowMode)
       
  2483 	{
       
  2484 	TRect rect(aPoint,TSize(1,1));
       
  2485 	iDrawDevice->CFbsDrawDevice::SetDitherOrigin(aPoint);
       
  2486 	CheckRgb(rect,aColor,aBackgroundColor,aDrawMode,aShadowMode);
       
  2487 	}
       
  2488 
       
  2489 void CTLowLevel::CheckRgb(const TRect& aRect,TRgb aColor,TRgb aBackgroundColor,CGraphicsContext::TDrawMode aDrawMode,TInt aShadowMode)
       
  2490 	{
       
  2491 	Shadow(aColor,aShadowMode);
       
  2492 
       
  2493 	if (aDrawMode == CGraphicsContext::EDrawModeNOTPEN)
       
  2494 		aColor = ~aColor;
       
  2495 
       
  2496 	TRgb foreColor[4];
       
  2497 	Normalize(aColor,foreColor);
       
  2498 
       
  2499 	TRgb backColor[4];
       
  2500 	Normalize(aBackgroundColor,backColor);
       
  2501 
       
  2502 	TRgb fore11 = foreColor[0];
       
  2503 	TRgb fore21 = foreColor[1];
       
  2504 	TRgb back11 = backColor[0];
       
  2505 	TRgb back21 = backColor[1];
       
  2506 	TRgb fore12 = foreColor[2];
       
  2507 	TRgb fore22 = foreColor[3];
       
  2508 	TRgb back12 = backColor[2];
       
  2509 	TRgb back22 = backColor[3];
       
  2510 
       
  2511 	TInt startY = aRect.iTl.iY;
       
  2512 	TInt endY = aRect.iBr.iY - 1;
       
  2513 
       
  2514 	if (startY & 1)
       
  2515 		{
       
  2516 		CheckScanline(aRect.iTl.iX,startY,aRect.Width(),fore12,fore22,back12,back22,aDrawMode);
       
  2517 		startY++;
       
  2518 		}
       
  2519 
       
  2520 	for (TInt yy = startY; yy < endY; yy += 2)
       
  2521 		{
       
  2522 		CheckScanline(aRect.iTl.iX,yy,aRect.Width(),fore11,fore21,back11,back21,aDrawMode);
       
  2523 		CheckScanline(aRect.iTl.iX,yy + 1,aRect.Width(),fore12,fore22,back12,back22,aDrawMode);
       
  2524 		}
       
  2525 
       
  2526 	if (aRect.iBr.iY & 1)
       
  2527 		{
       
  2528 		CheckScanline(aRect.iTl.iX,endY,aRect.Width(),fore11,fore21,back11,back21,aDrawMode);
       
  2529 		}
       
  2530 	}
       
  2531 
       
  2532 void CTLowLevel::CheckShadowRgb(const TRect& aRect,TRgb aColor,TInt aShadowMode)
       
  2533 	{
       
  2534 	TRgb foreColor[4];
       
  2535 	Normalize(aColor,foreColor);
       
  2536 
       
  2537 	TRgb fore11 = foreColor[0];
       
  2538 	TRgb fore21 = foreColor[1];
       
  2539 	TRgb fore12 = foreColor[2];
       
  2540 	TRgb fore22 = foreColor[3];
       
  2541 
       
  2542 	Shadow(fore11,aShadowMode & 2);
       
  2543 	Shadow(fore21,aShadowMode & 2);
       
  2544 	Shadow(fore12,aShadowMode & 2);
       
  2545 	Shadow(fore22,aShadowMode & 2);
       
  2546 
       
  2547 	Normalize(fore11);
       
  2548 	Normalize(fore21);
       
  2549 	Normalize(fore12);
       
  2550 	Normalize(fore22);
       
  2551 
       
  2552 	Shadow(fore11,aShadowMode & 1);
       
  2553 	Shadow(fore21,aShadowMode & 1);
       
  2554 	Shadow(fore12,aShadowMode & 1);
       
  2555 	Shadow(fore22,aShadowMode & 1);
       
  2556 
       
  2557 	Normalize(fore11);
       
  2558 	Normalize(fore21);
       
  2559 	Normalize(fore12);
       
  2560 	Normalize(fore22);
       
  2561 
       
  2562 	TInt startY = aRect.iTl.iY;
       
  2563 	TInt endY = aRect.iBr.iY - 1;
       
  2564 
       
  2565 	iDrawDevice->CFbsDrawDevice::ShadowArea(aRect);
       
  2566 
       
  2567 	if (iDispMode== EColor16MAP)
       
  2568 		{
       
  2569 		//No dithering, no blending, just checking for a solid colour
       
  2570 		fore12.SetAlpha(0);//do not want any blending to take place
       
  2571 		fore22.SetAlpha(0);//do not want any blending to take place
       
  2572 		for (TInt yy = startY; yy < endY; yy ++)
       
  2573 			{
       
  2574 			CheckScanline(aRect.iTl.iX,yy,aRect.Width(),fore11,fore11,fore22,fore22,CGraphicsContext::EDrawModePEN);
       
  2575 			}
       
  2576 		return;
       
  2577 		}
       
  2578 
       
  2579 	if (startY & 1)
       
  2580 		{
       
  2581 		CheckScanline(aRect.iTl.iX,startY,aRect.Width(),fore12,fore22,fore12,fore22,CGraphicsContext::EDrawModePEN);
       
  2582 		startY++;
       
  2583 		}
       
  2584 
       
  2585 	for (TInt yy = startY; yy < endY; yy += 2)
       
  2586 		{
       
  2587 		CheckScanline(aRect.iTl.iX,yy,aRect.Width(),fore11,fore21,fore11,fore21,CGraphicsContext::EDrawModePEN);
       
  2588 		CheckScanline(aRect.iTl.iX,yy + 1,aRect.Width(),fore12,fore22,fore12,fore22,CGraphicsContext::EDrawModePEN);
       
  2589 		}
       
  2590 
       
  2591 	if (aRect.iBr.iY & 1)
       
  2592 		{
       
  2593 		CheckScanline(aRect.iTl.iX,endY,aRect.Width(),fore11,fore21,fore11,fore21,CGraphicsContext::EDrawModePEN);
       
  2594 		}
       
  2595 	}
       
  2596 
       
  2597 void CTLowLevel::CheckScanline(TInt aX,TInt aY,TInt aLength,TRgb aFore1,TRgb aFore2,TRgb aBack1,TRgb aBack2,CGraphicsContext::TDrawMode aDrawMode)
       
  2598 	{
       
  2599 	iDrawDevice->ReadLine(aX,aY,aLength,iDrawDevice->ScanLineBuffer(),iDispMode);
       
  2600 
       
  2601 	TUint32 binaryPixel1 = BinaryValue(aFore1,aBack1,aDrawMode);
       
  2602 	TUint32 binaryPixel2 = BinaryValue(aFore2,aBack2,aDrawMode);
       
  2603 	if (aX & 1)
       
  2604 		{
       
  2605 		TUint32 spare = binaryPixel1;
       
  2606 		binaryPixel1 = binaryPixel2;
       
  2607 		binaryPixel2 = spare;
       
  2608 		}
       
  2609 
       
  2610 	TInt extra = aLength & 1;
       
  2611 	aLength &= ~1;
       
  2612 	TInt x = 0;
       
  2613 
       
  2614 	if (iPostBlendShadow)
       
  2615 		{
       
  2616 		PostBlendShadow(binaryPixel1);
       
  2617 		PostBlendShadow(binaryPixel2);
       
  2618 		}
       
  2619 	if (i16MAUserDispMode)
       
  2620 		{
       
  2621 		binaryPixel1 = PMA2NonPMAPixel(binaryPixel1,PtrTo16BitNormalisationTable());
       
  2622 		binaryPixel2 = PMA2NonPMAPixel(binaryPixel1,PtrTo16BitNormalisationTable());
       
  2623 		}
       
  2624 	while (x < aLength)
       
  2625 		{
       
  2626 		TUint32 binaryValue = ExtractBinaryValue(x,iDrawDevice->ScanLineBuffer(),iDispMode);
       
  2627 		CheckMatch(binaryPixel1,binaryValue);
       
  2628 		x++;
       
  2629 
       
  2630 		binaryValue = ExtractBinaryValue(x,iDrawDevice->ScanLineBuffer(),iDispMode);
       
  2631 		CheckMatch(binaryPixel2,binaryValue);
       
  2632 		x++;
       
  2633 		}
       
  2634 	if (extra)
       
  2635 		{
       
  2636 		TUint32 binaryValue = ExtractBinaryValue(x,iDrawDevice->ScanLineBuffer(),iDispMode);
       
  2637 		CheckMatch(binaryPixel1,binaryValue);
       
  2638 		}
       
  2639 	}
       
  2640 
       
  2641 void CTLowLevel::CheckLine(TUint8* aWriteBuffer,TUint8* aReadBuffer,TUint8* aBackBuffer,TInt aPixelLength,CGraphicsContext::TDrawMode aDrawMode,TDisplayMode aDispMode)
       
  2642 	{
       
  2643 	TInt wholeBytes = 0;
       
  2644 	TInt extraBits = 0;
       
  2645 
       
  2646 	switch (aDispMode)
       
  2647 		{
       
  2648 	case EGray2:
       
  2649 		wholeBytes = aPixelLength / 8;
       
  2650 		extraBits = aPixelLength & 7;
       
  2651 		break;
       
  2652 	case EGray4:
       
  2653 		wholeBytes = aPixelLength / 4;
       
  2654 		extraBits = (aPixelLength & 3) * 2;
       
  2655 		break;
       
  2656 	case EGray16:
       
  2657 	case EColor16:
       
  2658 		wholeBytes = aPixelLength / 2;
       
  2659 		extraBits = (aPixelLength & 1) * 4;
       
  2660 		break;
       
  2661 	case EGray256:
       
  2662 	case EColor256:
       
  2663 		wholeBytes = aPixelLength;
       
  2664 		break;
       
  2665 	case EColor4K:
       
  2666 	case EColor64K:
       
  2667 		wholeBytes = aPixelLength * 2;
       
  2668 		break;
       
  2669 	case EColor16M:
       
  2670 		wholeBytes = aPixelLength * 3;
       
  2671 		break;
       
  2672 	case EColor16MU:
       
  2673 	case EColor16MA:
       
  2674 	case EColor16MAP:
       
  2675 		wholeBytes = aPixelLength * 4;
       
  2676 		break;
       
  2677 	default:
       
  2678 		break;
       
  2679 		};
       
  2680 
       
  2681 	TUint8* readLimit = aReadBuffer + wholeBytes;
       
  2682 	TUint8 mask = TUint8(0xff >> (8 - extraBits));
       
  2683 	TInt byteCounter = 0;
       
  2684 
       
  2685 	switch (aDrawMode)
       
  2686 		{
       
  2687 	case CGraphicsContext::EDrawModeAND:
       
  2688 		if (iDispMode==EColor16MAP)
       
  2689 			break; //logical opeations not supported for premultiplied alpha
       
  2690 		for (; aReadBuffer < readLimit; aReadBuffer++, aWriteBuffer++, aBackBuffer++)
       
  2691 			{
       
  2692 			if(!((aDispMode == EColor16MU || aDispMode == EColor16MA || aDispMode == EColor16MAP)
       
  2693 				  && ++byteCounter % 4 == 0))
       
  2694 				Check(*aReadBuffer == (*aWriteBuffer & *aBackBuffer));
       
  2695 			}
       
  2696 		if (extraBits > 0)
       
  2697 			Check((*aReadBuffer & mask) == (*aWriteBuffer & *aBackBuffer & mask));
       
  2698 		break;
       
  2699 	case CGraphicsContext::EDrawModePEN:
       
  2700 		if(aDispMode == EColor16MU || aDispMode == EColor16MA || aDispMode == EColor16MAP)
       
  2701 			{
       
  2702 			for (; aReadBuffer<readLimit; aReadBuffer+=4, aWriteBuffer+=4)
       
  2703 				{
       
  2704 				TBool fail=EFalse;
       
  2705 				Blend(aWriteBuffer,aBackBuffer,aDispMode);
       
  2706 				if (!iFuzzyMatch)
       
  2707 					{
       
  2708 					fail|=Check(AbsDiff(*aReadBuffer,*aWriteBuffer)<2);
       
  2709 					fail|=Check(AbsDiff(*(aReadBuffer+1),*(aWriteBuffer+1))<2);
       
  2710 					fail|=Check(AbsDiff(*(aReadBuffer+2),*(aWriteBuffer+2))<2);
       
  2711 					fail|=Check(AbsDiff(*(aReadBuffer+3),*(aWriteBuffer+3))<2);
       
  2712 					}
       
  2713 				else
       
  2714 					{
       
  2715 					fail|=Check(AbsDiff(*aReadBuffer,*aWriteBuffer)<KInaccuracyLimit);
       
  2716 					fail|=Check(AbsDiff(*(aReadBuffer+1),*(aWriteBuffer+1))<KInaccuracyLimit);
       
  2717 					fail|=Check(AbsDiff(*(aReadBuffer+2),*(aWriteBuffer+2))<KInaccuracyLimit);
       
  2718 					fail|=Check(AbsDiff(*(aReadBuffer+3),*(aWriteBuffer+3))<KInaccuracyLimit);
       
  2719 					}
       
  2720 				if (fail)
       
  2721 					{
       
  2722 					_LIT(KLog,"The values 0x%x and 0x%x don't match, fuzzyMatch=%d (limit=%d), memory 0x%x 0x%x");
       
  2723 					INFO_PRINTF7(KLog,*reinterpret_cast<TUint*>(aReadBuffer),*reinterpret_cast<TUint*>(aWriteBuffer),iFuzzyMatch,KInaccuracyLimit,aReadBuffer,aWriteBuffer);
       
  2724 					}
       
  2725 				}
       
  2726 			}
       
  2727 		else
       
  2728 			{
       
  2729 			for (; aReadBuffer < readLimit; aReadBuffer++, aWriteBuffer++)
       
  2730 				{
       
  2731 				if (Check(*aReadBuffer == *aWriteBuffer))
       
  2732 					{
       
  2733 					_LIT(KLog,"The values 0x%x and 0x%x don't match, memory 0x%x 0x%x");
       
  2734 					INFO_PRINTF5(KLog,*aReadBuffer,*aWriteBuffer,aReadBuffer,aWriteBuffer);
       
  2735 					}
       
  2736 				}
       
  2737 			if (extraBits > 0)
       
  2738 				Check((*aReadBuffer & mask) == (*aWriteBuffer & mask));
       
  2739 			}
       
  2740 		break;
       
  2741 	case CGraphicsContext::EDrawModeNOTPEN:
       
  2742 		if (iDispMode==EColor16MAP)
       
  2743 			break; //logical opeations not supported for premultiplied alpha
       
  2744 		if(aDispMode == EColor16MU || aDispMode == EColor16MA )
       
  2745 			{
       
  2746 			for (; aReadBuffer < readLimit; aReadBuffer +=4, aWriteBuffer+=4)
       
  2747 				{
       
  2748 				*aWriteBuffer ^= 0xff;
       
  2749 				*(aWriteBuffer+1) ^= 0xff;
       
  2750 				*(aWriteBuffer+2) ^= 0xff;
       
  2751 
       
  2752 				Blend(aWriteBuffer,aBackBuffer,aDispMode);
       
  2753 
       
  2754 				if (!iFuzzyMatch)
       
  2755 					{
       
  2756 					Check(AbsDiff(*aReadBuffer, *aWriteBuffer) < 2);
       
  2757 					Check(AbsDiff(*(aReadBuffer+1), *(aWriteBuffer+1)) < 2);
       
  2758 					Check(AbsDiff(*(aReadBuffer+2), *(aWriteBuffer+2)) < 2);
       
  2759 					Check(AbsDiff(*(aReadBuffer+3), *(aWriteBuffer+3)) < 2);
       
  2760 					}
       
  2761 				else
       
  2762 					{
       
  2763 					Check(AbsDiff(*aReadBuffer, *aWriteBuffer) < KInaccuracyLimit);
       
  2764 					Check(AbsDiff(*(aReadBuffer+1), *(aWriteBuffer+1)) < KInaccuracyLimit);
       
  2765 					Check(AbsDiff(*(aReadBuffer+2), *(aWriteBuffer+2)) < KInaccuracyLimit);
       
  2766 					Check(AbsDiff(*(aReadBuffer+3), *(aWriteBuffer+3)) < KInaccuracyLimit);
       
  2767 					}
       
  2768 				}
       
  2769 			}
       
  2770 		else
       
  2771 			{
       
  2772 
       
  2773 			for (; aReadBuffer < readLimit; aReadBuffer++, aWriteBuffer++)
       
  2774 				{
       
  2775 				if(!((aDispMode == EColor16MU || aDispMode == EColor16MA || aDispMode == EColor16MAP) && ++byteCounter % 4 == 0))
       
  2776 					Check(*aReadBuffer == (*aWriteBuffer ^ 0xff));
       
  2777 				}
       
  2778 			if (extraBits > 0)
       
  2779 				Check((*aReadBuffer & mask) == ((*aWriteBuffer ^ 0xff) & mask));
       
  2780 			}
       
  2781 		break;
       
  2782 	case CGraphicsContext::EDrawModeXOR:
       
  2783 		if (iDispMode==EColor16MAP)
       
  2784 			break;//logical opeations not supported for premultiplied alpha
       
  2785 		for (; aReadBuffer < readLimit; aReadBuffer++, aWriteBuffer++, aBackBuffer++)
       
  2786 			{
       
  2787 			if(!((aDispMode == EColor16MU || aDispMode == EColor16MA || aDispMode == EColor16MAP) && ++byteCounter % 4 == 0))
       
  2788 				Check(*aReadBuffer == (*aWriteBuffer ^ *aBackBuffer));
       
  2789 			}
       
  2790 		if (extraBits > 0)
       
  2791 			Check((*aReadBuffer & mask) == ((*aWriteBuffer ^ *aBackBuffer) & mask));
       
  2792 		break;
       
  2793 	case CGraphicsContext::EDrawModeOR:
       
  2794 		if (iDispMode==EColor16MAP)
       
  2795 			break;//logical opeations not supported for premultiplied alpha
       
  2796 		for (; aReadBuffer < readLimit; aReadBuffer++, aWriteBuffer++, aBackBuffer++)
       
  2797 			{
       
  2798 			if(!((aDispMode == EColor16MU || aDispMode == EColor16MA || aDispMode == EColor16MAP) && ++byteCounter % 4 == 0))
       
  2799 				Check(*aReadBuffer == (*aWriteBuffer | *aBackBuffer));
       
  2800 			}
       
  2801 		if (extraBits > 0)
       
  2802 			Check((*aReadBuffer & mask) == ((*aWriteBuffer | *aBackBuffer) & mask));
       
  2803 		break;
       
  2804 	case CGraphicsContext::EDrawModeNOTSCREEN:
       
  2805 		if (iDispMode==EColor16MAP)
       
  2806 			break;//logical opeations not supported for premultiplied alpha
       
  2807 		if (aDispMode != EColor4K)
       
  2808 			{
       
  2809 			for (; aReadBuffer < readLimit; aReadBuffer++, aBackBuffer++)
       
  2810 				{
       
  2811 				if(!((aDispMode == EColor16MU || aDispMode == EColor16MA || aDispMode == EColor16MAP) && ++byteCounter % 4 == 0))
       
  2812 					{
       
  2813 					if (iFuzzyMatch==EFalse)
       
  2814 						Check(*aReadBuffer == (*aBackBuffer ^ 0xff));
       
  2815 					else
       
  2816 						{
       
  2817 						TUint8 vals[3];
       
  2818 						vals[0]=*aReadBuffer;
       
  2819 						//put in some tolerance values, try with +/- 1, to begin with
       
  2820 						if (vals[0]<255)
       
  2821 							vals[1]=vals[0]+1;
       
  2822 						else
       
  2823 							vals[1]=vals[0];
       
  2824 						if (vals[0]>0)
       
  2825 							vals[2]=vals[0]-1;
       
  2826 						else
       
  2827 							vals[2]=vals[0];
       
  2828 						Check((vals[0] == (*aBackBuffer ^ 0xff))||
       
  2829 							  (vals[1] == (*aBackBuffer ^ 0xff))||
       
  2830 							  (vals[2] == (*aBackBuffer ^ 0xff)));
       
  2831 						}
       
  2832 					}
       
  2833 				}
       
  2834 			if (extraBits > 0)
       
  2835 				Check((*aReadBuffer & mask) == ((*aBackBuffer ^ 0xff) & mask));
       
  2836 			}
       
  2837 		else
       
  2838 			{
       
  2839 			while (aReadBuffer < readLimit)
       
  2840 				{
       
  2841 				if (TInt(aReadBuffer) & 1)
       
  2842 					Check(*aReadBuffer++ == (*aBackBuffer++ ^ 0x0f));
       
  2843 				else
       
  2844 					Check(*aReadBuffer++ == (*aBackBuffer++ ^ 0xff));
       
  2845 				}
       
  2846 			}
       
  2847 		break;
       
  2848 	default:
       
  2849 		break;
       
  2850 		};
       
  2851 	}
       
  2852 
       
  2853 void CTLowLevel::CheckBinary(const TRect& aRect,TUint32* aBuffer,TRgb aForeColor,TRgb aBackColor,CGraphicsContext::TDrawMode aDrawMode,TInt aShadowMode,TBool aWrapDataWords,TBool aUp)
       
  2854 	{
       
  2855 	Shadow(aForeColor,aShadowMode);
       
  2856 
       
  2857 	if (aDrawMode == CGraphicsContext::EDrawModeNOTPEN)
       
  2858 		aForeColor = ~aForeColor;
       
  2859 
       
  2860 	TRgb foreColor[4];
       
  2861 	Normalize(aForeColor,foreColor);
       
  2862 
       
  2863 	TRgb backColor[4];
       
  2864 	Normalize(aBackColor,backColor);
       
  2865 
       
  2866 	foreColor[0] = RgbValue(foreColor[0],backColor[0],aDrawMode);
       
  2867 	foreColor[1] = RgbValue(foreColor[1],backColor[1],aDrawMode);
       
  2868 	foreColor[2] = RgbValue(foreColor[2],backColor[2],aDrawMode);
       
  2869 	foreColor[3] = RgbValue(foreColor[3],backColor[3],aDrawMode);
       
  2870 
       
  2871 
       
  2872 	if (iDispMode==EColor16MAP)
       
  2873 		{
       
  2874 		//pre-multiply and unpremultiply
       
  2875 		TInt count;
       
  2876 		for (count=0;count<4;count++)
       
  2877 			{
       
  2878 			TUint32 tempInt;
       
  2879 			tempInt = backColor[count].Color16MAP(); //Now premultiplied
       
  2880 			backColor[count] = TRgb::Color16MAP(tempInt);
       
  2881 			}
       
  2882 		}
       
  2883 
       
  2884 	TUint32 data = *aBuffer++;
       
  2885 	TUint32 mask = 1;
       
  2886 
       
  2887 	TInt yy = (aUp) ? aRect.iBr.iY - 1  : aRect.iTl.iY;
       
  2888 	TInt ylimit = (aUp) ? aRect.iTl.iY - 1 : aRect.iBr.iY;
       
  2889 	TInt yinc = (aUp) ? -1 : 1;
       
  2890 
       
  2891 	TRgb pixelBuffer[KCheckBinaryPixelBufferSize];
       
  2892 	__ASSERT_ALWAYS(aRect.Width() <= KCheckBinaryPixelBufferSize,User::Panic(_L("CheckBinary buffer"),KErrOverflow));
       
  2893 
       
  2894 	for (; yy != ylimit; yy += yinc)
       
  2895 		{
       
  2896 		TInt yoffset = 2 * (yy & 1);
       
  2897 
       
  2898 		iDrawDevice->ReadLine(aRect.iTl.iX,yy,aRect.Width(),pixelBuffer,ERgb);
       
  2899 		TRgb* color = pixelBuffer;
       
  2900 
       
  2901 		for (TInt xx = aRect.iTl.iX; xx < aRect.iBr.iX; xx++)
       
  2902 			{
       
  2903 			if (!mask)
       
  2904 				{
       
  2905 				mask = 1;
       
  2906 				data = *aBuffer++;
       
  2907 				}
       
  2908 
       
  2909 			if (data & mask)
       
  2910 				CheckMatch((*color).Internal(), foreColor[(xx & 1) + yoffset].Internal());
       
  2911 			else
       
  2912 				CheckMatch((*color).Internal(), backColor[(xx & 1) + yoffset].Internal());
       
  2913 
       
  2914 			color++;
       
  2915 			mask <<= 1;
       
  2916 			}
       
  2917 
       
  2918 		if (aWrapDataWords)
       
  2919 			mask = 0;
       
  2920 		}
       
  2921 	}
       
  2922 
       
  2923 void CTLowLevel::CheckBackground(const TRect& aRect,TRgb aBackgroundColor)
       
  2924 	{
       
  2925 	iBlendTestColors= EFalse;
       
  2926 	if (aRect.iTl.iX > 0)
       
  2927 		CheckRgb(TRect(aRect.iTl.iX - 1,aRect.iTl.iY,aRect.iTl.iX,aRect.iBr.iY),aBackgroundColor,aBackgroundColor,CGraphicsContext::EDrawModePEN,0);
       
  2928 	if (aRect.iTl.iY > 0)
       
  2929 		CheckRgb(TRect(aRect.iTl.iX,aRect.iTl.iY - 1,aRect.iBr.iX,aRect.iTl.iY),aBackgroundColor,aBackgroundColor,CGraphicsContext::EDrawModePEN,0);
       
  2930 	if (aRect.iBr.iX < iSize.iWidth - 1)
       
  2931 		CheckRgb(TRect(aRect.iBr.iX,aRect.iTl.iY,aRect.iBr.iX + 1,aRect.iBr.iY),aBackgroundColor,aBackgroundColor,CGraphicsContext::EDrawModePEN,0);
       
  2932 	if (aRect.iBr.iY < iSize.iHeight - 1)
       
  2933 		CheckRgb(TRect(aRect.iTl.iX,aRect.iBr.iY,aRect.iBr.iX,aRect.iBr.iY + 1),aBackgroundColor,aBackgroundColor,CGraphicsContext::EDrawModePEN,0);
       
  2934 	iBlendTestColors= ETrue;
       
  2935 	}
       
  2936 /**
       
  2937 This function is copied as it is from BMDRAW32A.CPP which is used to test WriteRgbOutlineAndShadow for EColor16MA.
       
  2938 It is used in CTLowLevel::CheckBlendedOutlineAndShadow.
       
  2939 @param aBeneath The background pixel colour value
       
  2940 @param aSrcColor The source pixel colour value
       
  2941 @param aAlpha The alpha value
       
  2942 */
       
  2943 FORCEINLINE TUint32 OptimizedBlend32A(TUint32 aBeneath,TUint32 aSrcColor,TUint8 aAlpha)
       
  2944  	{
       
  2945 	if(aAlpha)
       
  2946 		{
       
  2947 		if(aAlpha == 0xff) // opaque, so unchanged
       
  2948 			{
       
  2949 			//Still need to convert source to destination from non-multiplied to pre-multiplied
       
  2950 			//But this code resolves to a copy. The ARM optimiser prefers shifts over big constants.
       
  2951 			return (aSrcColor|(aAlpha<<24));
       
  2952 			}
       
  2953 		else
       
  2954 			{
       
  2955 			//0, 1, 2, 3
       
  2956 			//b, g, rect, alpha
       
  2957 
       
  2958 			const TUint32 srcMult = aAlpha;
       
  2959 			TUint32 destMult = ((255 - aAlpha) * ((aBeneath >> 24)));
       
  2960 			//This gives a slightly more accurate result than ((aBeneath >> 24)+1)
       
  2961 			destMult=destMult+(destMult>>8);
       
  2962 			destMult+= 0x0080;
       
  2963 			destMult >>= 8;
       
  2964 
       
  2965 			TUint32 rb =(((aSrcColor&0x00ff00ff)*srcMult)) + (((aBeneath&0x00ff00ff)*destMult));
       
  2966 			rb = rb+((rb>>8)&0x00ff00ff);
       
  2967 			rb+=0x00800080;
       
  2968 			rb>>=8;
       
  2969 			TUint32 ag = (((aSrcColor&0x0000ff00)*srcMult)) + (((aBeneath&0x0000ff00)*destMult));
       
  2970 			ag>>=8;	 //Note that if alpha is processed here, this shift must be performed before the multiplies
       
  2971 			ag = ag+((ag>>8)&0x00ff00ff);
       
  2972 			ag+=0x00800080;
       
  2973 			TUint32 aa = srcMult+destMult;
       
  2974 			return (rb&0x00ff00ff) | (ag&0x0000ff00) | (aa << 24);
       
  2975 
       
  2976 			}
       
  2977 		}
       
  2978  	else // completely transparent
       
  2979 		{
       
  2980 		return aBeneath;
       
  2981  		}
       
  2982 
       
  2983  	}
       
  2984 
       
  2985 /**
       
  2986 Helper function for TestWriteRgbOutlineAndShadow(). Creates the final colour, blending the outline, shadow,
       
  2987 fill and background colour using lookup table provided by Monotype and compares with the
       
  2988 pixel colour drawn using WriteRgbOutlineAndShadow.
       
  2989 
       
  2990 @param aOutlinePenColor Colour used for drawing outline of font
       
  2991 @param aShadowColor Colour used for drawing shadow of font
       
  2992 @param aFillColor Colour used for filling of font
       
  2993 @param aBackgroundColor Background colour of the pixel
       
  2994 @param aLookupIndex Index of the lookup table to be used for generating final colour
       
  2995 @param aLength Number of pixels to compare the pixel colour with the generated colour
       
  2996 @param aReadBuffer Buffer containing the colours drawn using WriteRgbOutlineAndShadow.This will be used for comparing
       
  2997 @return EFalse if pixel colour doesnt match with the calculated colour, otherwise ETrue on success.
       
  2998 */
       
  2999 TBool CTLowLevel::CheckBlendedOutlineAndShadow(TRgb aOutlinePenColor, TRgb aShadowColor, TRgb aFillColor,
       
  3000 												TRgb aBackgroundColor, TInt aLookupIndex, TInt aLength, TUint8* aReadBuffer)
       
  3001 	{
       
  3002 	TRgb finalColor;
       
  3003 	TInt alpha = aOutlinePenColor.Internal() >> 24;
       
  3004 
       
  3005 	if (255 == FourColorBlendLookup[aLookupIndex][3])
       
  3006 		{
       
  3007 		//background colour
       
  3008 		finalColor.SetInternal(aBackgroundColor.Internal());
       
  3009 
       
  3010 		/*Reset the alpha with background colour alpha as in product code in case of 255 == FourColorBlendLookup[aLookupIndex][3]
       
  3011 		it doesnt draw and leaves the background colour as it is. So the alpha to be checked should be of background colour alpha*/
       
  3012 		alpha = aBackgroundColor.Alpha();
       
  3013 		}
       
  3014 	else if (255 == FourColorBlendLookup[aLookupIndex][2])
       
  3015 		{
       
  3016 		//fill colour
       
  3017 		finalColor.SetInternal(aFillColor.Internal());
       
  3018 		}
       
  3019 	else if (255 == FourColorBlendLookup[aLookupIndex][1])
       
  3020 		{
       
  3021 		//Shadow colour
       
  3022 		finalColor.SetInternal(aShadowColor.Internal());
       
  3023 		}
       
  3024 	else if (255 == FourColorBlendLookup[aLookupIndex][0])
       
  3025 		{
       
  3026 		//Outline colour
       
  3027 		finalColor.SetInternal(aOutlinePenColor.Internal());
       
  3028 		}
       
  3029 	else
       
  3030 		{
       
  3031 		TInt blendedRedColor = (aOutlinePenColor.Red() * FourColorBlendLookup[aLookupIndex][0] +
       
  3032 				  				aShadowColor.Red() * FourColorBlendLookup[aLookupIndex][1] +
       
  3033 				  				aFillColor.Red() * FourColorBlendLookup[aLookupIndex][2] +
       
  3034 				  				aBackgroundColor.Red() * FourColorBlendLookup[aLookupIndex][3]) >> 8;
       
  3035 
       
  3036 		TInt blendedGreenColor = (aOutlinePenColor.Green() * FourColorBlendLookup[aLookupIndex][0] +
       
  3037 							 	aShadowColor.Green() * FourColorBlendLookup[aLookupIndex][1] +
       
  3038 							 	aFillColor.Green() * FourColorBlendLookup[aLookupIndex][2] +
       
  3039 							 	aBackgroundColor.Green() * FourColorBlendLookup[aLookupIndex][3]) >> 8;
       
  3040 
       
  3041 		TInt blendedBlueColor = (aOutlinePenColor.Blue() * FourColorBlendLookup[aLookupIndex][0] +
       
  3042 								aShadowColor.Blue() * FourColorBlendLookup[aLookupIndex][1] +
       
  3043 								aFillColor.Blue() * FourColorBlendLookup[aLookupIndex][2] +
       
  3044 								aBackgroundColor.Blue() * FourColorBlendLookup[aLookupIndex][3]) >> 8;
       
  3045 
       
  3046 		finalColor = TRgb(blendedRedColor, blendedGreenColor, blendedBlueColor);
       
  3047 		}
       
  3048 
       
  3049 	//Set the alpha in the final colour
       
  3050 	finalColor.SetAlpha(alpha);
       
  3051 
       
  3052 	//Alpha blending is not supported for display modes below EColor64K.
       
  3053 	switch(iDispMode)
       
  3054 		{
       
  3055 	case EColor64K:
       
  3056 	case EColor16M:
       
  3057 	case EColor16MU:
       
  3058 		if (alpha != 0xff)
       
  3059 			{
       
  3060 			finalColor = AlphaBlend(finalColor.Red(), finalColor.Green(), finalColor.Blue(), aBackgroundColor.Red(), aBackgroundColor.Green(), aBackgroundColor.Blue(), alpha);
       
  3061 			}
       
  3062 		break;
       
  3063 	case EColor16MA:
       
  3064 		//Just use the background color to draw in case 255 == FourColorBlendLookup[aLookupIndex][3]
       
  3065 		if (255 != FourColorBlendLookup[aLookupIndex][3])
       
  3066 			{
       
  3067 			finalColor.SetInternal(OptimizedBlend32A(aBackgroundColor.Internal(), finalColor.Internal(), alpha));
       
  3068 			}
       
  3069 		break;
       
  3070 	case EColor16MAP:
       
  3071 		//Just use the background color to draw in case 255 == FourColorBlendLookup[aLookupIndex][3]
       
  3072 		if (255 != FourColorBlendLookup[aLookupIndex][3])
       
  3073 			{
       
  3074 			TUint32 color16MAP = finalColor.Internal();
       
  3075 			Convert2PMA(color16MAP);
       
  3076 			finalColor.SetInternal(PMAPixelBlend(aBackgroundColor.Internal(), color16MAP));
       
  3077 			}
       
  3078 		break;
       
  3079 		};
       
  3080 
       
  3081 	Normalize(finalColor);
       
  3082 	TColorConvertor& colorConvertor = ColorConvertor(iDispMode);
       
  3083 	// Check each pixel of the line, it should match with the calculated blended color.
       
  3084 	for (TInt count = 0; count < aLength; count++)
       
  3085 		{
       
  3086 		TRgb readValue = ExtractRgbValue(count, aReadBuffer, iDispMode);
       
  3087 		if (colorConvertor.Index(finalColor) != colorConvertor.Index(readValue))
       
  3088 			{
       
  3089 			return EFalse;
       
  3090 			}
       
  3091 		}
       
  3092 	return ETrue;
       
  3093 	}
       
  3094 
       
  3095 TRgb CTLowLevel::RgbValue(TRgb aFore,TRgb aBack,CGraphicsContext::TDrawMode aDrawMode)
       
  3096 	{
       
  3097 	TUint32 value = BinaryValue(aFore,aBack,aDrawMode);
       
  3098 
       
  3099 	switch (iDispMode)
       
  3100 		{
       
  3101 	case EGray2:
       
  3102 		return TRgb::Gray2(value);
       
  3103 	case EGray4:
       
  3104 		return TRgb::Gray4(value);
       
  3105 	case EGray16:
       
  3106 		return TRgb::Gray16(value);
       
  3107 	case EGray256:
       
  3108 		return TRgb::Gray256(value);
       
  3109 	case EColor16:
       
  3110 		return TRgb::Color16(value);
       
  3111 	case EColor256:
       
  3112 		return TRgb::Color256(value);
       
  3113 	case EColor4K:
       
  3114 		return TRgb::Color4K(value);
       
  3115 	case EColor64K:
       
  3116 		return TRgb::Color64K(value);
       
  3117 	case EColor16M:
       
  3118 		return TRgb::Color16M(value);
       
  3119 	case EColor16MU:
       
  3120 		return TRgb::Color16MU(value);
       
  3121 	case EColor16MA:
       
  3122 		return TRgb::Color16MA(value);
       
  3123 	case EColor16MAP:
       
  3124 		return TRgb::Color16MAP(value);
       
  3125 	default:
       
  3126 		break;
       
  3127 		};
       
  3128 	return KRgbBlack;
       
  3129 	}
       
  3130 
       
  3131 TUint32 CTLowLevel::BinaryValue(TRgb aFore,TRgb aBack,CGraphicsContext::TDrawMode aDrawMode)
       
  3132 	{
       
  3133 	TUint32 f = 0;
       
  3134 	TUint32 b = 0;
       
  3135 	TUint32 notVal = 0;
       
  3136 
       
  3137 	switch (iDispMode)
       
  3138 		{
       
  3139 	case EGray2:
       
  3140 		f = aFore.Gray2();
       
  3141 		b = aBack.Gray2();
       
  3142 		notVal = 1;
       
  3143 		break;
       
  3144 	case EGray4:
       
  3145 		f = aFore.Gray4();
       
  3146 		b = aBack.Gray4();
       
  3147 		notVal = 3;
       
  3148 		break;
       
  3149 	case EGray16:
       
  3150 		f = aFore.Gray16();
       
  3151 		b = aBack.Gray16();
       
  3152 		notVal = 0xf;
       
  3153 		break;
       
  3154 	case EGray256:
       
  3155 		f = aFore.Gray256();
       
  3156 		b = aBack.Gray256();
       
  3157 		notVal = 0xff;
       
  3158 		break;
       
  3159 	case EColor16:
       
  3160 		f = aFore.Color16();
       
  3161 		b = aBack.Color16();
       
  3162 		notVal = 0xf;
       
  3163 		break;
       
  3164 	case EColor256:
       
  3165 		f = aFore.Color256();
       
  3166 		b = aBack.Color256();
       
  3167 		notVal = 0xff;
       
  3168 		break;
       
  3169 	case EColor4K:
       
  3170 		f = aFore.Color4K();
       
  3171 		b = aBack.Color4K();
       
  3172 		notVal = 0xfff;
       
  3173 		break;
       
  3174 	case EColor64K:
       
  3175 		f = aFore.Color64K();
       
  3176 		b = aBack.Color64K();
       
  3177 		notVal = 0xffff;
       
  3178 		break;
       
  3179 	case EColor16M:
       
  3180 		f = aFore.Color16M();
       
  3181 		b = aBack.Color16M();
       
  3182 		notVal = 0xffffff;
       
  3183 		break;
       
  3184 	case EColor16MU:
       
  3185 		f = aFore.Color16MU();
       
  3186 		b = aBack.Color16MU();
       
  3187 		notVal = 0x00ffffff;
       
  3188 		break;
       
  3189 	case EColor16MA:
       
  3190 		f = aFore.Color16MA();
       
  3191 		b = aBack.Color16MA();
       
  3192 		notVal = 0xffffffff;
       
  3193 		break;
       
  3194 	case EColor16MAP:
       
  3195 		f = aFore.Color16MAP();
       
  3196 		b = aBack.Color16MAP();
       
  3197 
       
  3198 		//do not want to blend backgound colours for testing
       
  3199 		if (iBlendTestColors && (aDrawMode&CGraphicsContext::EDrawModePEN))
       
  3200 			{
       
  3201 			Blend((TUint8*)(&f),(TUint8*)(&b),iDispMode);
       
  3202 			}
       
  3203 		notVal = 0xffffffff;
       
  3204 		break;
       
  3205 	default:
       
  3206 		break;
       
  3207 		};
       
  3208 
       
  3209 	switch (aDrawMode)
       
  3210 		{
       
  3211 	case CGraphicsContext::EDrawModeAND:		return f & b;
       
  3212 	case CGraphicsContext::EDrawModePEN:		return f;
       
  3213 	case CGraphicsContext::EDrawModeWriteAlpha:	return f;
       
  3214 	case CGraphicsContext::EDrawModeXOR:		return f ^ b;
       
  3215 	case CGraphicsContext::EDrawModeOR:			return f | b;
       
  3216 	case CGraphicsContext::EDrawModeNOTSCREEN:	return b ^ notVal;
       
  3217 	case CGraphicsContext::EDrawModeNOTPEN:		return f;
       
  3218 	default:
       
  3219 		break;
       
  3220 		};
       
  3221 	return 0;
       
  3222 	}
       
  3223 
       
  3224 TRgb CTLowLevel::ExtractRgbValue(TInt aX,TUint8* aBuffer,TDisplayMode aDispMode)
       
  3225 	{
       
  3226 	TUint32 value = ExtractBinaryValue(aX,(TUint32*)aBuffer,aDispMode);
       
  3227 
       
  3228 	switch (aDispMode)
       
  3229 		{
       
  3230 	case EGray2:
       
  3231 		return TRgb::Gray2(value);
       
  3232 	case EGray4:
       
  3233 		return TRgb::Gray4(value);
       
  3234 	case EGray16:
       
  3235 		return TRgb::Gray16(value);
       
  3236 	case EGray256:
       
  3237 		return TRgb::Gray256(value);
       
  3238 	case EColor16:
       
  3239 		return TRgb::Color16(value);
       
  3240 	case EColor256:
       
  3241 		return TRgb::Color256(value);
       
  3242 	case EColor4K:
       
  3243 		return TRgb::Color4K(value);
       
  3244 	case EColor64K:
       
  3245 		return TRgb::Color64K(value);
       
  3246 	case EColor16M:
       
  3247 		return TRgb::Color16M(value);
       
  3248 	case ERgb:
       
  3249 		return TRgb(value, value>>24);
       
  3250 	case EColor16MU:
       
  3251 		return TRgb::Color16MU(value);
       
  3252 	case EColor16MA:
       
  3253 		return TRgb::Color16MA(value);
       
  3254 	case EColor16MAP:
       
  3255 		return TRgb::Color16MAP(value);
       
  3256 	default:
       
  3257 		break;
       
  3258 		};
       
  3259 	return KRgbBlack;
       
  3260 	}
       
  3261 
       
  3262 TUint32 CTLowLevel::ExtractBinaryValue(TInt aX,TUint32* aBuffer,TDisplayMode aDispMode)
       
  3263 	{
       
  3264 	switch (aDispMode)
       
  3265 		{
       
  3266 	case EGray2:
       
  3267 		return ((*(aBuffer + (aX >> 5))) >> (aX & 0x1f)) & 1;
       
  3268 	case EGray4:
       
  3269 		return ((*(aBuffer + (aX >> 4))) >> ((aX & 0xf) * 2)) & 3;
       
  3270 	case EGray16:
       
  3271 	case EColor16:
       
  3272 		return ((*(aBuffer + (aX >> 3))) >> ((aX & 7) * 4)) & 0xf;
       
  3273 	case EGray256:
       
  3274 	case EColor256:
       
  3275 		return ((*(aBuffer + (aX >> 2))) >> ((aX & 3) * 8)) & 0xff;
       
  3276 	case EColor4K:
       
  3277 		return ((*(aBuffer + (aX >> 1))) >> ((aX & 1) * 16)) & 0xfff;
       
  3278 	case EColor64K:
       
  3279 		return ((*(aBuffer + (aX >> 1))) >> ((aX & 1) * 16)) & 0xffff;
       
  3280 	case EColor16M:
       
  3281 		{
       
  3282 		TUint8* buffer = ((TUint8*)aBuffer) + (aX * 3);
       
  3283 		return *buffer | (*(buffer + 1) << 8) | (*(buffer + 2) << 16);
       
  3284 		}
       
  3285 	case ERgb:
       
  3286 		return *(aBuffer + aX);
       
  3287 	case EColor16MU:
       
  3288 		return *(aBuffer + aX) & 0x00FFFFFF;
       
  3289 	case EColor16MA:
       
  3290 	case EColor16MAP:
       
  3291 		return *(aBuffer + aX);
       
  3292 	default:
       
  3293 		break;
       
  3294 		};
       
  3295 	return 0;
       
  3296 	}
       
  3297 
       
  3298 void CTLowLevel::Normalize(TRgb& aColor)
       
  3299 	{
       
  3300 	return(Normalize(aColor,iDispMode));
       
  3301 	}
       
  3302 
       
  3303 void CTLowLevel::Normalize(TRgb& aColor, TDisplayMode aDispMode)
       
  3304 	{
       
  3305 	switch (aDispMode)
       
  3306 		{
       
  3307 	case EGray2:
       
  3308 		aColor = TRgb::Gray2(aColor.Gray2());
       
  3309 		break;
       
  3310 	case EGray4:
       
  3311 		aColor = TRgb::Gray4(aColor.Gray4());
       
  3312 		break;
       
  3313 	case EGray16:
       
  3314 		aColor = TRgb::Gray16(aColor.Gray16());
       
  3315 		break;
       
  3316 	case EGray256:
       
  3317 		aColor = TRgb::Gray256(aColor.Gray256());
       
  3318 		break;
       
  3319 	case EColor16:
       
  3320 		aColor = TRgb::Color16(aColor.Color16());
       
  3321 		break;
       
  3322 	case EColor256:
       
  3323 		aColor = TRgb::Color256(aColor.Color256());
       
  3324 		break;
       
  3325 	case EColor4K:
       
  3326 		aColor = TRgb::Color4K(aColor.Color4K());
       
  3327 		break;
       
  3328 	case EColor64K:
       
  3329 		aColor = TRgb::Color64K(aColor.Color64K());
       
  3330 		break;
       
  3331 	case EColor16M:
       
  3332 		aColor = TRgb::Color16M(aColor.Color16M());
       
  3333 		break;
       
  3334 	case EColor16MU:
       
  3335 		aColor = TRgb::Color16MU(aColor.Color16MU());
       
  3336 		break;
       
  3337 	case EColor16MA:
       
  3338 		aColor = TRgb::Color16MA(aColor.Color16MA());
       
  3339 		break;
       
  3340 	case EColor16MAP:
       
  3341 		//do nothing, because TRGb is already unpremultiplied
       
  3342 		break;
       
  3343 	default:
       
  3344 		break;
       
  3345 		};
       
  3346 	}
       
  3347 
       
  3348 void CTLowLevel::Normalize(TRgb& aColor,TRgb aDitherColors[4])
       
  3349 	{
       
  3350 	switch (iDispMode)
       
  3351 		{
       
  3352 	case EGray2:
       
  3353 		FillArray(TRgb::Gray2(aColor.Gray2()),aDitherColors);
       
  3354 		break;
       
  3355 	case EGray4:
       
  3356 		if (iUserDispMode == EGray2)
       
  3357 			FillArray(TRgb::Gray2(aColor.Gray2()),aDitherColors);
       
  3358 		else
       
  3359 			{
       
  3360 			TInt gray16 = aColor.Gray16();
       
  3361 			aDitherColors[0] = TRgb::Gray4(ditherlutab[gray16][0]);
       
  3362 			aDitherColors[1] = TRgb::Gray4(ditherlutab[gray16][1]);
       
  3363 			aDitherColors[2] = TRgb::Gray4(ditherlutab[gray16][2]);
       
  3364 			aDitherColors[3] = TRgb::Gray4(ditherlutab[gray16][3]);
       
  3365 			}
       
  3366 		break;
       
  3367 	case EGray16:
       
  3368 		if (iUserDispMode == EGray2)
       
  3369 			FillArray(TRgb::Gray2(aColor.Gray2()),aDitherColors);
       
  3370 		else if (iUserDispMode == EGray4)
       
  3371 			{
       
  3372 			TInt gray16 = aColor.Gray16();
       
  3373 			aDitherColors[0] = TRgb::Gray4(ditherlutab[gray16][0]);
       
  3374 			aDitherColors[1] = TRgb::Gray4(ditherlutab[gray16][1]);
       
  3375 			aDitherColors[2] = TRgb::Gray4(ditherlutab[gray16][2]);
       
  3376 			aDitherColors[3] = TRgb::Gray4(ditherlutab[gray16][3]);
       
  3377 			}
       
  3378 		else
       
  3379 			FillArray(TRgb::Gray16(aColor.Gray16()),aDitherColors);
       
  3380 		break;
       
  3381 	case EGray256:
       
  3382 		FillArray(TRgb::Gray256(aColor.Gray256()),aDitherColors);
       
  3383 		break;
       
  3384 	case EColor16:
       
  3385 		FillArray(TRgb::Color16(aColor.Color16()),aDitherColors);
       
  3386 		break;
       
  3387 	case EColor256:
       
  3388 		FillArray(TRgb::Color256(aColor.Color256()),aDitherColors);
       
  3389 		break;
       
  3390 	case EColor4K:
       
  3391 		FillArray(TRgb::Color4K(aColor.Color4K()),aDitherColors);
       
  3392 		break;
       
  3393 	case EColor64K:
       
  3394 		FillArray(TRgb::Color64K(aColor.Color64K()),aDitherColors);
       
  3395 		break;
       
  3396 	case EColor16M:
       
  3397 	case EColor16MU:
       
  3398 	case EColor16MA:
       
  3399 	case EColor16MAP:
       
  3400 		FillArray(aColor,aDitherColors);
       
  3401 		break;
       
  3402 	default:
       
  3403 		break;
       
  3404 		};
       
  3405 	}
       
  3406 
       
  3407 void CTLowLevel::FillArray(TRgb aColor,TRgb aArray[4])
       
  3408 	{
       
  3409 	aArray[0] = aColor;
       
  3410 	aArray[1] = aColor;
       
  3411 	aArray[2] = aColor;
       
  3412 	aArray[3] = aColor;
       
  3413 	}
       
  3414 
       
  3415 
       
  3416 void CTLowLevel::PostBlendShadow(TUint32 &aPmaColor)
       
  3417 	{
       
  3418 	//this function should only be called for PMA colours
       
  3419 	const TInt alpha = aPmaColor >> 24;
       
  3420 	TUint32 value = aPmaColor & 0x00ffffff;
       
  3421 
       
  3422 	if (iPostBlendShadow & CFbsDrawDevice::EFade)
       
  3423 		{
       
  3424 #if defined(SYMBIAN_USE_FAST_FADING)
       
  3425 		TUint32 fast_fade_offset = ((SYMBIAN_USE_FAST_FADING & 0xff) * alpha) >>8;
       
  3426 		fast_fade_offset = fast_fade_offset | (fast_fade_offset << 8) | (fast_fade_offset <<16);
       
  3427 		value = ((value >> 1) & ~0x00808080) + (fast_fade_offset);
       
  3428 		value = value | (((TUint32)alpha)<<24);
       
  3429 #else
       
  3430 	/*
       
  3431 	here blackmap = 200,
       
  3432 		 whitemap = 100
       
  3433 	iFadeMapFactor = aWhiteMap - aBlackMap + 1;
       
  3434 	iFadeMapOffset = aBlackMap;
       
  3435 	*/
       
  3436 
       
  3437 		const TInt fadeMapOffset = ((alpha * 0x7f) >> 8) & 0xff;
       
  3438 		const TInt wordFadeMapOffset = ((fadeMapOffset) << 16) | (fadeMapOffset);
       
  3439 		const TInt rb = ((((value & 0x00ff00ff) * 0x7f) >> 8) + wordFadeMapOffset) & 0x00ff00ff;
       
  3440 	  	const TInt g = ((((value & 0x0000ff00) * 0x7f) >> 16) + fadeMapOffset) << 8;
       
  3441 		value = rb | g | (((TUint32)alpha)<<24);
       
  3442 #endif
       
  3443 		}
       
  3444 
       
  3445 	if (iPostBlendShadow & CFbsDrawDevice::EShadow)
       
  3446 		{
       
  3447 		TInt alpha = (aPmaColor>>24);
       
  3448 		TInt red = (value>>16)&0xff;
       
  3449 		TInt green = (value>>8)&0xff;
       
  3450 		TInt blue = value &0xff;
       
  3451 
       
  3452 		TInt shadow= (alpha*0x40)>>8;
       
  3453 		red = Max(0,red-shadow);
       
  3454 		green = Max (0,green-shadow);
       
  3455 		blue = Max (0,blue-shadow);
       
  3456 		value = (((TUint32)alpha)<<24)|(((TUint32)red)<<16)|(((TUint32)green)<<8)|((TUint32)blue);
       
  3457 		}
       
  3458 	aPmaColor = value;
       
  3459 	}
       
  3460 
       
  3461 void CTLowLevel::Shadow(TRgb& aColor,TInt aShadowMode)
       
  3462 	{
       
  3463 	if (aShadowMode & 2)
       
  3464 		{
       
  3465 		switch (iDrawDevice->DisplayMode())
       
  3466 			{
       
  3467 		case EGray2:
       
  3468 			aColor = TRgb::Gray256(FadeGray(aColor.Gray2() * 255));
       
  3469 			break;
       
  3470 		case EGray4:
       
  3471 		case EGray16:
       
  3472 			aColor = TRgb::Gray256(FadeGray(aColor.Gray16() * 17));
       
  3473 			break;
       
  3474 		case EGray256:
       
  3475 			aColor = TRgb::Gray256(FadeGray(aColor.Gray256()));
       
  3476 			break;
       
  3477 		case EColor16:
       
  3478 			aColor = FadeRgb(TRgb::Color16(aColor.Color16()));
       
  3479 			break;
       
  3480 		case EColor256:
       
  3481 			aColor = FadeRgb(TRgb::Color256(aColor.Color256()));
       
  3482 			break;
       
  3483 		case EColor4K:
       
  3484 			aColor = FadeRgb(TRgb::Color4K(aColor.Color4K()));
       
  3485 			break;
       
  3486 		case EColor64K:
       
  3487 			aColor = FadeRgb(TRgb::Color64K(aColor.Color64K()),KFastFading && iUseFastFade);
       
  3488 			break;
       
  3489 		case EColor16M:
       
  3490 			aColor = FadeRgb(TRgb::Color16M(aColor.Color16M()));
       
  3491 			break;
       
  3492 		case EColor16MU:
       
  3493 			aColor = FadeRgb(TRgb::Color16MU(aColor.Color16MU()),KFastFading && iUseFastFade);
       
  3494 			break;
       
  3495 		case EColor16MA:
       
  3496 			aColor = FadeRgb(TRgb::Color16MA(aColor.Color16MA()),KFastFading && iUseFastFade);
       
  3497 			break;
       
  3498 		case EColor16MAP:
       
  3499 			aColor = FadeRgb(TRgb::Color16MAP(aColor.Color16MAP()),KFastFading && iUseFastFade);
       
  3500 			break;
       
  3501 		default:
       
  3502 			break;
       
  3503 			};
       
  3504 		}
       
  3505 
       
  3506 	if (aShadowMode & 1)
       
  3507 		{
       
  3508 		switch (iDrawDevice->DisplayMode())
       
  3509 			{
       
  3510 		case EGray2:
       
  3511 			aColor = KRgbBlack;
       
  3512 			break;
       
  3513 		case EGray4:
       
  3514 		case EGray16:
       
  3515 			aColor = TRgb::Gray16(Max(0,aColor.Gray16()-5));
       
  3516 			break;
       
  3517 		case EGray256:
       
  3518 			aColor = TRgb::Gray256(Max(0,aColor.Gray256()-85));
       
  3519 			break;
       
  3520 		case EColor16:
       
  3521 			{
       
  3522 			TInt color = aColor.Color16();
       
  3523 			if (color == 15) color--;
       
  3524 			else if (color == 14) color = 1;
       
  3525 			else if (color > 7) color += 3;
       
  3526 			else if (color > 4) color -= 3;
       
  3527 			else color = 0;
       
  3528 			aColor = TRgb::Color16(color);
       
  3529 			}
       
  3530 			break;
       
  3531 		case EColor256:
       
  3532 			{
       
  3533 			aColor = TRgb::Color256(aColor.Color256());
       
  3534 			TInt red = aColor.Red();
       
  3535 			TInt green = aColor.Green();
       
  3536 			TInt blue = aColor.Blue();
       
  3537 			red = Max(0,red-0x33);
       
  3538 			green = Max(0,green-0x33);
       
  3539 			blue = Max(0,blue-0x33);
       
  3540 			aColor = TRgb(red,green,blue);
       
  3541 			}
       
  3542 			break;
       
  3543 		case EColor4K:
       
  3544 			{
       
  3545 			TInt color = aColor.Color4K();
       
  3546 			TInt red = (color & 0xf00) >> 8;
       
  3547 			TInt green = (color & 0x0f0) >> 4;
       
  3548 			TInt blue = color & 0x00f;
       
  3549 
       
  3550 			red = Max(0,red-5);
       
  3551 			green = Max(0,green-5);
       
  3552 			blue = Max(0,blue-5);
       
  3553 
       
  3554 			aColor = TRgb::Color4K((red << 8) | (green << 4) | blue);
       
  3555 			}
       
  3556 			break;
       
  3557 		case EColor64K:
       
  3558 			{
       
  3559 			TInt color = aColor.Color64K();
       
  3560 			TInt red = (color & 0xf800) >> 11;
       
  3561 			TInt green = (color & 0x07e0) >> 5;
       
  3562 			TInt blue = color & 0x001f;
       
  3563 
       
  3564 			red = Max(0,red-8);
       
  3565 			green = Max(0,green-16);
       
  3566 			blue = Max(0,blue-8);
       
  3567 
       
  3568 			aColor = TRgb::Color64K((red << 11) | (green << 5) | blue);
       
  3569 			}
       
  3570 			break;
       
  3571 		case EColor16M:
       
  3572 		case EColor16MU:
       
  3573 		case EColor16MA:
       
  3574 		case EColor16MAP:
       
  3575 			{
       
  3576 			TInt red = aColor.Red();
       
  3577 			TInt green = aColor.Green();
       
  3578 			TInt blue = aColor.Blue();
       
  3579 			red = Max(0,red-0x40);
       
  3580 			green = Max(0,green-0x40);
       
  3581 			blue = Max(0,blue-0x40);
       
  3582 			aColor = TRgb(red,green,blue,aColor.Alpha());
       
  3583 			}
       
  3584 			break;
       
  3585 		default:
       
  3586 			break;
       
  3587 			};
       
  3588 		}
       
  3589 	}
       
  3590 
       
  3591 void CTLowLevel::Blend(TUint8* aBuffer,TUint8* aBufferDest, TDisplayMode aDispMode)
       
  3592 	{
       
  3593 	TUint32* buffer = reinterpret_cast<TUint32*> (aBuffer);
       
  3594 	TUint32* bufferDest = reinterpret_cast<TUint32*> (aBufferDest);
       
  3595 	TInt mask = (*buffer & 0xff000000) >> 24;
       
  3596 	TRgb rgbDest;
       
  3597 
       
  3598 	switch(aDispMode)
       
  3599 		{
       
  3600 	case EColor16MU:
       
  3601 		{
       
  3602 		// src + ((255 - mask) * dest) / 255
       
  3603 		if(mask!=255)
       
  3604 			{
       
  3605 			rgbDest=TRgb::Color16MU(*bufferDest);
       
  3606 			if(mask)
       
  3607 				{
       
  3608 				TRgb rgbSrc=TRgb::Color16MU(*buffer);
       
  3609 				rgbDest.SetRed(rgbSrc.Red() + ((255 - mask) * rgbDest.Red()) / 255);
       
  3610 				rgbDest.SetGreen(rgbSrc.Green() + ((255 - mask) * rgbDest.Green()) / 255);
       
  3611 				rgbDest.SetBlue(rgbSrc.Blue() + ((255 - mask) * rgbDest.Blue()) / 255);
       
  3612 				}
       
  3613 			*buffer=rgbDest.Internal();
       
  3614 			}
       
  3615 		}
       
  3616 		break;
       
  3617 	case EColor16MA:
       
  3618 		{
       
  3619 		// (mask * src + (255 - mask) * dest) / 255
       
  3620 		if(mask!=255)
       
  3621 			{
       
  3622 			rgbDest=TRgb::Color16MA(*bufferDest);
       
  3623 			if(mask)
       
  3624 				{
       
  3625 				TRgb rgbSrc=TRgb::Color16MA(*buffer);
       
  3626 				rgbDest.SetRed((mask * rgbSrc.Red() + (255 - mask) * rgbDest.Red()) / 255);
       
  3627 				rgbDest.SetGreen((mask * rgbSrc.Green() + (255 - mask) * rgbDest.Green()) / 255);
       
  3628 				rgbDest.SetBlue((mask * rgbSrc.Blue() + (255 - mask) * rgbDest.Blue()) / 255);
       
  3629 				}
       
  3630 			*buffer=rgbDest.Internal();
       
  3631 			}
       
  3632 		}
       
  3633 		break;
       
  3634 	case EColor16MAP:
       
  3635 		{
       
  3636 		/*
       
  3637 		* Blend function uses the Porter Duff composition equation
       
  3638 		* This blends two pixels with alphas:
       
  3639 		* Ar  = As  + Ad * (1 - As) (Blended Alpha)
       
  3640 		* Cr = Cs + Cd(1 - As) (Blended Colour)
       
  3641 		* Cr = Cs + Cd(255-As)/255 : for alpha 0-255
       
  3642 		* where Ar = alpha result
       
  3643 		* where Cr = colour result
       
  3644 		* where Cs = source colour
       
  3645 		* where Cd = destination colour
       
  3646 		* The function assumes that the mask buffer is the alpha value of the source pixel.
       
  3647 		*/
       
  3648 		if(mask!=255)
       
  3649 			{
       
  3650 			rgbDest=TRgb::Color16MA(*bufferDest);
       
  3651 			if(mask)
       
  3652 				{
       
  3653 				TInt destAlpha = (*bufferDest & 0xff000000) >> 24;
       
  3654 				TInt sourceAlpha = (*buffer & 0xff000000) >> 24;
       
  3655 				TRgb rgbSrc;
       
  3656 				rgbSrc.SetInternal(*buffer);
       
  3657 				rgbDest.SetInternal(*bufferDest);
       
  3658 				TInt resultAlpha = sourceAlpha +((255-sourceAlpha)*destAlpha)/255;
       
  3659 				rgbDest.SetRed(rgbSrc.Red() + ((255 - sourceAlpha) * rgbDest.Red()) / 255);
       
  3660 				rgbDest.SetGreen(rgbSrc.Green() + ((255 - sourceAlpha) * rgbDest.Green()) / 255);
       
  3661 				rgbDest.SetBlue(rgbSrc.Blue() + ((255 - sourceAlpha) * rgbDest.Blue())/ 255);
       
  3662 				rgbDest.SetAlpha(resultAlpha);
       
  3663 				}
       
  3664 			*buffer=rgbDest.Internal();
       
  3665 			}
       
  3666 		}
       
  3667 		break;
       
  3668 	default: break;
       
  3669 		}
       
  3670 	}
       
  3671 
       
  3672 void CTLowLevel::Shadow(TUint8* aBuffer,TInt aByteLength,TInt aShadowMode)
       
  3673 	{
       
  3674 	TUint8* buffer = aBuffer;
       
  3675 	const TUint8* bufferLimit = aBuffer + aByteLength;
       
  3676 
       
  3677 	if (aShadowMode & 2)
       
  3678 		{
       
  3679 		switch (iDrawDevice->DisplayMode())
       
  3680 			{
       
  3681 		case EGray2:
       
  3682 			while (buffer < bufferLimit)
       
  3683 				*buffer++ = 0xff;
       
  3684 			break;
       
  3685 		case EGray4:
       
  3686 			while (buffer < bufferLimit)
       
  3687 				{
       
  3688 				TInt first = FadeGray((buffer[0] & 0x03) * 85) >> 6;
       
  3689 				TInt second = FadeGray(((buffer[0] >> 2) & 0x03) * 85) >> 6;
       
  3690 				TInt third = FadeGray(((buffer[0] >> 4) & 0x03) * 85) >> 6;
       
  3691 				TInt fourth = FadeGray(((buffer[0] >> 6) & 0x03) * 85) >> 6;
       
  3692 				*buffer++ = TUint8(first | (second << 2) | (third << 4) | (fourth << 6));
       
  3693 				}
       
  3694 			break;
       
  3695 		case EGray16:
       
  3696 			while (buffer < bufferLimit)
       
  3697 				{
       
  3698 				TInt low = FadeGray((buffer[0] & 0x0f) * 17) >> 4;
       
  3699 				TInt high = FadeGray((buffer[0] >> 4) * 17) >> 4;
       
  3700 				*buffer++ = TUint8((high << 4) | low);
       
  3701 				}
       
  3702 			break;
       
  3703 		case EGray256:
       
  3704 			while (buffer < bufferLimit)
       
  3705 				*buffer++ = FadeGray(*buffer);
       
  3706 			break;
       
  3707 		case EColor16:
       
  3708 			while (buffer < bufferLimit)
       
  3709 				{
       
  3710 				TInt low = FadeRgb(TRgb::Color16(buffer[0] & 0x0f)).Color16();
       
  3711 				TInt high = FadeRgb(TRgb::Color16(buffer[0] >> 4)).Color16();
       
  3712 				*buffer++ = TUint8((high << 4) | low);
       
  3713 				}
       
  3714 			break;
       
  3715 		case EColor256:
       
  3716 			while (buffer < bufferLimit)
       
  3717 				*buffer++ = TUint8(FadeRgb(TRgb::Color256(buffer[0])).Color256());
       
  3718 			break;
       
  3719 		case EColor4K:
       
  3720 			while (buffer < bufferLimit)
       
  3721 				{
       
  3722 				TInt color4K = FadeRgb(TRgb::Color4K(buffer[0] | (buffer[1] << 8))).Color4K();
       
  3723 				buffer[0] = TUint8(color4K);
       
  3724 				buffer[1] = TUint8(color4K >> 8);
       
  3725 				buffer += 2;
       
  3726 				}
       
  3727 			break;
       
  3728 		case EColor64K:
       
  3729 			while (buffer < bufferLimit)
       
  3730 				{
       
  3731 				TInt color64K = FadeRgb(TRgb::Color64K(buffer[0] | (buffer[1] << 8)),ETrue).Color64K();
       
  3732 				buffer[0] = TUint8(color64K);
       
  3733 				buffer[1] = TUint8(color64K >> 8);
       
  3734 				buffer += 2;
       
  3735 				}
       
  3736 			break;
       
  3737 		case EColor16M:
       
  3738 			{
       
  3739 			while (buffer < bufferLimit)
       
  3740 				*buffer++ = FadeGray(buffer[0]);
       
  3741 			}
       
  3742 			break;
       
  3743 		case EColor16MU:
       
  3744 			{
       
  3745 			TUint32* buffer32 = reinterpret_cast <TUint32*> (buffer);
       
  3746 			TUint32* bufferLimit32 = buffer32 + aByteLength / 4;
       
  3747 			while (buffer32 < bufferLimit32)
       
  3748 				{
       
  3749 				// scanline buffer for 16MU driver is pre-multiplied
       
  3750 				TRgb color = FadeRgb(TRgb::Color16MAP(*buffer32),ETrue);
       
  3751 				// avoid rounding errors with EDrawModeAND etc.
       
  3752 				*buffer32++ = color.Alpha() == 255 ? color.Internal() : color.Color16MAP();
       
  3753 				}
       
  3754 			}
       
  3755 			break;
       
  3756 		case EColor16MA:
       
  3757 			{
       
  3758 			TUint32* buffer32 = reinterpret_cast <TUint32*> (buffer);
       
  3759 			TUint32* bufferLimit32 = buffer32 + aByteLength / 4;
       
  3760 			while (buffer32 < bufferLimit32)
       
  3761 				{
       
  3762 				TRgb color = FadeRgb(TRgb::Color16MA(*buffer32),ETrue);
       
  3763 				*buffer32++ = color.Color16MA();
       
  3764 				}
       
  3765 			}
       
  3766 			break;
       
  3767 		case EColor16MAP:
       
  3768 			{
       
  3769 			TUint32* buffer32 = reinterpret_cast <TUint32*> (buffer);
       
  3770 			TUint32* bufferLimit32 = buffer32 + aByteLength / 4;
       
  3771 			while (buffer32 < bufferLimit32)
       
  3772 				{
       
  3773 				TRgb color = FadeRgb(TRgb::Color16MAP(*buffer32),ETrue);
       
  3774 				*buffer32++ = color.Color16MAP();
       
  3775 				}
       
  3776 			}
       
  3777 			break;
       
  3778 		default:
       
  3779 			break;
       
  3780 			}
       
  3781 		}
       
  3782 
       
  3783 	buffer = aBuffer;
       
  3784 
       
  3785 	if (aShadowMode & 1)
       
  3786 		{
       
  3787 		switch (iDrawDevice->DisplayMode())
       
  3788 			{
       
  3789 		case EGray2:
       
  3790 			while (buffer < bufferLimit)
       
  3791 				{
       
  3792 				*buffer++ = 0;
       
  3793 				}
       
  3794 			break;
       
  3795 		case EGray4:
       
  3796 			while (buffer < bufferLimit)
       
  3797 				{
       
  3798 				TInt first = buffer[0] & 0x03;
       
  3799 				TInt second = buffer[0] & 0x0c;
       
  3800 				TInt third = buffer[0] & 0x30;
       
  3801 				TInt fourth = buffer[0] & 0xc0;
       
  3802 				first = Max(0,first-1);
       
  3803 				second = Max(0,second-4);
       
  3804 				third = Max(0,third-16);
       
  3805 				fourth = Max(0,fourth-64);
       
  3806 				*buffer++ = TUint8(fourth | third | second | first);
       
  3807 				}
       
  3808 			break;
       
  3809 		case EGray16:
       
  3810 			while (buffer < bufferLimit)
       
  3811 				{
       
  3812 				TInt low = buffer[0] & 0x0f;
       
  3813 				TInt high = buffer[0] >> 4;
       
  3814 				low = Max(0,low-5);
       
  3815 				high = Max(0,high-5);
       
  3816 				*buffer++ = TUint8((high << 4) | low);
       
  3817 				}
       
  3818 			break;
       
  3819 		case EGray256:
       
  3820 			while (buffer < bufferLimit)
       
  3821 				{
       
  3822 				buffer[0] = TUint8(Max(0,buffer[0]-85));
       
  3823 				buffer++;
       
  3824 				}
       
  3825 			break;
       
  3826 		case EColor16:
       
  3827 			while (buffer < bufferLimit)
       
  3828 				{
       
  3829 				TInt low = buffer[0] & 0x0f;
       
  3830 				TInt high = buffer[0] >> 4;
       
  3831 				if (low == 15) low = 14;
       
  3832 				else if (low == 14) low = 1;
       
  3833 				else if (low >= 11) low = 0;
       
  3834 				else if (low >= 8) low += 3;
       
  3835 				else if (low >= 5) low -= 3;
       
  3836 				else low = 0;
       
  3837 				if (high == 15) high = 14;
       
  3838 				else if (high == 14) high = 1;
       
  3839 				else if (high >= 11) high = 0;
       
  3840 				else if (high >= 8) high += 3;
       
  3841 				else if (high >= 5) high -= 3;
       
  3842 				else high = 0;
       
  3843 				*buffer++ = TUint8((high << 4) | low);
       
  3844 				}
       
  3845 			break;
       
  3846 		case EColor256:
       
  3847 			while (buffer < bufferLimit)
       
  3848 				{
       
  3849 				TRgb color(TRgb::Color256(buffer[0]));
       
  3850 				TInt red = color.Red();
       
  3851 				TInt green = color.Green();
       
  3852 				TInt blue = color.Blue();
       
  3853 				red = Max(0,red-0x33);
       
  3854 				green = Max(0,green-0x33);
       
  3855 				blue = Max(0,blue-0x33);
       
  3856 				*buffer++ = TUint8(TRgb(red,green,blue).Color256());
       
  3857 				}
       
  3858 			break;
       
  3859 		case EColor4K:
       
  3860 			while (buffer < bufferLimit)
       
  3861 				{
       
  3862 				TInt data = (buffer[1] << 8) | buffer[0];
       
  3863 				TInt red = (data & 0xf00) >> 8;
       
  3864 				TInt green = (data & 0x0f0) >> 4;
       
  3865 				TInt blue = data & 0x00f;
       
  3866 				red = Max(0,red-5);
       
  3867 				green = Max(0,green-5);
       
  3868 				blue = Max(0,blue-5);
       
  3869 				data = (red << 8) | (green << 4) | blue;
       
  3870 				buffer[0] = TUint8(data);
       
  3871 				buffer[1] = TUint8(data >> 8);
       
  3872 				buffer += 2;
       
  3873 				}
       
  3874 			break;
       
  3875 		case EColor64K:
       
  3876 			while (buffer < bufferLimit)
       
  3877 				{
       
  3878 				TInt data = (buffer[1] << 8) | buffer[0];
       
  3879 				TInt red = (data & 0xf800) >> 11;
       
  3880 				TInt green = (data & 0x07e0) >> 5;
       
  3881 				TInt blue = data & 0x001f;
       
  3882 				red = Max(0,red-8);
       
  3883 				green = Max(0,green-16);
       
  3884 				blue = Max(0,blue-8);
       
  3885 				data = (red << 11) | (green << 5) | blue;
       
  3886 				buffer[0] = TUint8(data);
       
  3887 				buffer[1] = TUint8(data >> 8);
       
  3888 				buffer += 2;
       
  3889 				}
       
  3890 			break;
       
  3891 		case EColor16M:
       
  3892 			while (buffer < bufferLimit)
       
  3893 				{
       
  3894 				buffer[0] = TUint8(Max(0,buffer[0]-0x40));
       
  3895 				buffer++;
       
  3896 				}
       
  3897 			break;
       
  3898 		case EColor16MU:
       
  3899 			{
       
  3900 			TUint32* buffer32 = reinterpret_cast <TUint32*> (buffer);
       
  3901 			TUint32* bufferLimit32 = buffer32 + aByteLength / 4;
       
  3902 			while (buffer32 < bufferLimit32)
       
  3903 				{
       
  3904 				// scanline buffer for 16MU driver is pre-multiplied
       
  3905 				TRgb color = TRgb::Color16MAP(*buffer32);
       
  3906 				color = TRgb(Max(0,color.Red()-0x40),Max(0,color.Green()-0x40),Max(0,color.Blue()-0x40), color.Alpha());
       
  3907 				// avoid rounding errors with EDrawModeAND etc.
       
  3908 				*buffer32++ = color.Alpha() == 255 ? color.Internal() : color.Color16MAP();
       
  3909 				}
       
  3910 			}
       
  3911 			break;
       
  3912 		case EColor16MA:
       
  3913 			{
       
  3914 			TUint32* buffer32 = reinterpret_cast <TUint32*> (buffer);
       
  3915 			TUint32* bufferLimit32 = buffer32 + aByteLength / 4;
       
  3916 			while (buffer32 < bufferLimit32)
       
  3917 				{
       
  3918 				TRgb color = TRgb::Color16MA(*buffer32);
       
  3919 				color = TRgb(Max(0,color.Red()-0x40),Max(0,color.Green()-0x40),Max(0,color.Blue()-0x40), color.Alpha());
       
  3920 				*buffer32++ = color.Color16MA();
       
  3921 				}
       
  3922 			}
       
  3923 			break;
       
  3924 		case EColor16MAP:
       
  3925 			{
       
  3926 			TUint32* buffer32 = reinterpret_cast <TUint32*> (buffer);
       
  3927 			TUint32* bufferLimit32 = buffer32 + aByteLength / 4;
       
  3928 			while (buffer32 < bufferLimit32)
       
  3929 				{
       
  3930 				TRgb color = TRgb::Color16MAP(*buffer32);
       
  3931 				color = TRgb(Max(0,color.Red()-0x40),Max(0,color.Green()-0x40),Max(0,color.Blue()-0x40), color.Alpha());
       
  3932 				*buffer32++ = color.Color16MAP();
       
  3933 				}
       
  3934 			}
       
  3935 			break;
       
  3936 		default:
       
  3937 			break;
       
  3938 			}
       
  3939 		}
       
  3940 	}
       
  3941 
       
  3942 TUint8 CTLowLevel::FadeGray(TInt aGray256)
       
  3943 	{
       
  3944 	return TUint8((aGray256 >> 1) + 128);
       
  3945 	}
       
  3946 
       
  3947 /**
       
  3948 A test code function for Fading colour values.
       
  3949 @param aColor Colour value for which faded colour is needed.
       
  3950 @param aFastFade Used to check whether Fast Fading method is required or not.
       
  3951 		aFastFade flag should be true only when there is a corresponding Fast Fading
       
  3952 		implementation in product code and the fading method uses the Fast Fading method.
       
  3953 @return TRgb Faded colour value.
       
  3954 */
       
  3955 TRgb CTLowLevel::FadeRgb(TRgb aColor, TBool aFastFade/*=EFalse*/)
       
  3956 	{
       
  3957 	if(aFastFade)
       
  3958 		{
       
  3959 #if defined(SYMBIAN_USE_FAST_FADING)
       
  3960 		TUint32 value = ((aColor.Internal() >> 1) & ~0x00808080) + SYMBIAN_USE_FAST_FADING;
       
  3961 		TInt alpha = aColor.Alpha();
       
  3962 		return TRgb(value, alpha);
       
  3963 #endif
       
  3964 		}
       
  3965 	TInt red = (aColor.Red() >> 1) + 128;
       
  3966 	TInt green = (aColor.Green() >> 1) + 128;
       
  3967 	TInt blue = (aColor.Blue() >> 1) + 128;
       
  3968 	TInt alpha = aColor.Alpha();
       
  3969 	return TRgb(red,green,blue,alpha);
       
  3970 	}
       
  3971 
       
  3972 TColorConvertor& CTLowLevel::ColorConvertor(TDisplayMode aDisplayMode)
       
  3973 	{
       
  3974 	return *iColorConvertor[aDisplayMode];
       
  3975 	}
       
  3976 
       
  3977 void CTLowLevel::Report()
       
  3978 	{
       
  3979 	INFO_PRINTF4(_L("Test %d: %d/%d"),iTestNo,iReportIteration,iTotalReportIterations);
       
  3980 	if (iReportIteration < iTotalReportIterations)
       
  3981 		iReportIteration++;
       
  3982 	}
       
  3983 
       
  3984 inline TBool CTLowLevel::Check(TBool aValue)
       
  3985 	{
       
  3986 	if (iLastFailTestNo!=iIteration)
       
  3987 		{
       
  3988 		if (!aValue)
       
  3989 			{
       
  3990 			_LIT(KLog,"Test %d, iteration %d failed  iDispMode %d  iUserDispMode %d  iOrientation %d");
       
  3991 			INFO_PRINTF6(KLog,iTestNo,iIteration,iDispMode,iUserDispMode,iOrientation);
       
  3992 			iLastFailTestNo=iIteration;
       
  3993 			}
       
  3994 		TEST(aValue);
       
  3995 		}
       
  3996 	return !aValue;
       
  3997 	}
       
  3998 
       
  3999 //-----------
       
  4000 CTLowLevel1::CTLowLevel1(CTestStep* aStep):
       
  4001 	CTLowLevel(aStep)
       
  4002 	{
       
  4003 	iOrientation = CFbsDrawDevice::EOrientationRotated180;
       
  4004 	iOrientationEnd = CFbsDrawDevice::EOrientationRotated270;
       
  4005 	}
       
  4006 
       
  4007 void CTLowLevel1::RunTestCaseL(TInt /*aCurTestCase*/)
       
  4008 	{
       
  4009 	if(iOrientation <= iOrientationEnd)
       
  4010 		{
       
  4011 		INFO_PRINTF2(_L("Screen device : %S"), &DisplayModeNames1[iCurScreenDeviceModeIndex]);
       
  4012 		TDisplayMode display = TestDisplayMode1[iCurScreenDeviceModeIndex++];
       
  4013 /**
       
  4014 	@SYMTestCaseID GRAPHICS-SCREENDRIVER-0018
       
  4015 */
       
  4016 		((CTLowLevelStep*)iStep)->SetTestStepID(_L("GRAPHICS-SCREENDRIVER-0018"));
       
  4017 		TestScreenDrawL(display);
       
  4018 		if(iCurScreenDeviceModeIndex >= KNumberDisplayModes1)
       
  4019 			{
       
  4020 			iCurScreenDeviceModeIndex = 0;
       
  4021 			iOrientation ++;
       
  4022 			}
       
  4023 		((CTLowLevelStep*)iStep)->RecordTestResultL();
       
  4024 		}
       
  4025 	else
       
  4026 		{
       
  4027 		((CTLowLevelStep*)iStep)->CloseTMSGraphicsStep();
       
  4028 		TestComplete();
       
  4029 		}
       
  4030 	}
       
  4031 
       
  4032 //--------------
       
  4033 __CONSTRUCT_STEP__(LowLevel)
       
  4034 
       
  4035 __CONSTRUCT_STEP__(LowLevel1)