os/graphics/fbs/fontandbitmapserver/trasterizer/test/trasterizer.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2008-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 "trasterizer.h"
    17 #include "testutils.h"
    18 #include "examplerasterizer.h"
    19 #include <fbs.h>
    20 #include <gdi.h>
    21 #include <s32mem.h>
    22 #include <e32math.h>
    23 #include <e32svr.h>
    24 #include <u32hal.h>
    25 
    26 const TDisplayMode KDisplayModes[] = {EGray256, EColor64K, EColor16MU, EColor16MAP};
    27 const TInt KNumDisplayModes = sizeof(KDisplayModes)/sizeof(KDisplayModes[0]);
    28 const TRgb KStripeColours[3] = {TRgb(255,255,0), TRgb(255,0,255), TRgb(0,255,255)};
    29 
    30 CTRasterizer::CTRasterizer()
    31 	{
    32 	SetTestStepName(KTRasterizerStep);
    33 	}
    34 
    35 /**
    36 @SYMTestCaseID		
    37 	GRAPHICS-FBSERV-RASTERIZER-001
    38 
    39 @SYMTestPriority
    40 	High
    41 
    42 @SYMPREQ
    43 	PREQ2096
    44 
    45 @SYMREQ
    46 	REQ10860
    47 	REQ10861 
    48 	
    49 @SYMTestCaseDesc
    50 	Test that the example rasterizer dll "fbsrasterizer_test.dll" has been loaded.
    51 
    52 @SYMTestActions	
    53 	On the emulator check that the rasterizer setting is "fbsrasterizer_test.dll".
    54 	Get a pointer to the rasterizer.
    55 
    56 @SYMTestExpectedResults
    57 	"fbsrasterizer_test.dll" has been loaded successfully
    58 */
    59 void CTRasterizer::TestLoadRasterizerDllL()
    60 	{
    61 	INFO_PRINTF1(_L("TestLoadRasterizerDll"));
    62 #ifdef __WINS__
    63 	_LIT8(KTestRasterizerName, "fbsrasterizer_test.dll");
    64 	TUint8* rasterizerSetting = NULL;
    65 	UserSvr::HalFunction(EHalGroupEmulator, EEmulatorHalStringProperty, (TAny*)"FBSRASTERIZER_DLL", &rasterizerSetting);
    66 	TESTL(rasterizerSetting != NULL);
    67 	TESTL(TPtrC8(rasterizerSetting).CompareF(KTestRasterizerName) == 0);
    68 #endif
    69 	GetExampleRasterizerL();
    70 	}
    71 
    72 /**
    73 @SYMTestCaseID		
    74 	GRAPHICS-FBSERV-RASTERIZER-002
    75 
    76 @SYMTestPriority
    77 	High
    78 
    79 @SYMPREQ
    80 	PREQ2096
    81 
    82 @SYMREQ
    83 	REQ10860
    84 	REQ10861 
    85 	
    86 @SYMTestCaseDesc
    87 	Test that a scanline retrieved from the example rasterizer is what we expect.
    88 
    89 @SYMTestActions		
    90 	Create an extended bitmap and set its extended data to three colours followed by a TUint8.
    91 	The example rasterizer interprets this data as the three colours in a tricolour flag drawn
    92 	with either horizontal or vertical stripes depending on the value of the TUint8.	
    93 	Draw a scanline of the extended bitmap by calling:
    94 		- CFbsRasterizer::BeginBitmap()
    95 		- CFbsRasterizer::ScanLine()
    96 		- CFbsRasterizer::EndBitmap()
    97 
    98 @SYMTestExpectedResults
    99 	The scan line returned by the example rasterizer should be exactly the same as the
   100 	corresponding scanline in the test data.
   101 */
   102 void CTRasterizer::TestScanLineL()
   103 	{	
   104 	TBuf<32> displayModeDes(TestUtils::DisplayModeToString(iDisplayMode)); 
   105 	INFO_PRINTF2(_L("TestScanLine, display mode %S"), &displayModeDes);
   106 	
   107 	const TInt KNumBeginBitmapCalls = 5;
   108 	
   109 	// Get the example rasterizer
   110 	GetExampleRasterizerL();	
   111 	
   112 	// Test for both stripe styles, 0 for vertical stripes and 1 for horizontal stripes
   113 	for (TInt stripeStyle = 0; stripeStyle < 2; stripeStyle++)
   114 		{
   115 		if (stripeStyle == 0)
   116 			{
   117 			INFO_PRINTF1(_L("... Vertical stripes"));
   118 			}
   119 		else
   120 			{
   121 			INFO_PRINTF1(_L("... Horizontal stripes"));
   122 			}
   123 				
   124 		const TSize sizeInPixels(64,32);
   125 		CFbsBitmap* extendedBitmap = CreateExtendedBitmapLC(KStripeColours, stripeStyle, sizeInPixels);					
   126 			
   127 		// Begin scanline access to the extended bitmap
   128 		CFbsRasterizer::TBitmapDesc bitmapDesc;
   129 		TInt64 bitmapId = extendedBitmap->SerialNumber();
   130 		bitmapDesc.iSizeInPixels = sizeInPixels;
   131 		bitmapDesc.iDispMode = iDisplayMode;
   132 		bitmapDesc.iDataType = KUidExampleExtendedBitmap;
   133 		bitmapDesc.iData = extendedBitmap->DataAddress();
   134 		bitmapDesc.iDataSize = extendedBitmap->DataSize();
   135 		extendedBitmap->BeginDataAccess();
   136 		// test calling BeginBitmap more than once as each additional call should just increment as reference count
   137 		for (TInt i = 0; i < KNumBeginBitmapCalls; i++)
   138 			{			
   139 			iRasterizer->BeginBitmap(bitmapId, bitmapDesc, NULL);
   140 			}				
   141 		
   142 		TInt scanlineLength;
   143 		TPoint startPixel;
   144 		TRgb bufferColour;
   145 		// The width or height of a stripe in the tricolour flag that the extended bitmap rasterizer draws
   146 		TInt stripeSize = (stripeStyle == 0) ? sizeInPixels.iWidth/3 : sizeInPixels.iHeight/3; 				
   147 		for (TInt h = 0; h < sizeInPixels.iHeight; h++)
   148 			{
   149 			// Get a full scanline from the extended bitmap using the rasterizer	
   150 			startPixel = TPoint(0, h);
   151 			scanlineLength = sizeInPixels.iWidth;
   152 			const TUint8* scanline = reinterpret_cast<const TUint8*>(iRasterizer->ScanLine(bitmapId, startPixel, scanlineLength));
   153 			TESTL(scanline != NULL);								
   154 			
   155 			// Make sure each pixel in the scanline is the colour that we expect						
   156 			TRgb compareColour;
   157 			
   158 			for (TInt w = 0; w < scanlineLength; w++)
   159 				{																			
   160 				if (((stripeStyle == 0) && (w < stripeSize)) 
   161 					|| ((stripeStyle == 1) && (h < stripeSize)))
   162 					{					
   163 					compareColour = KStripeColours[0]; // left or top
   164 					}
   165 				else if (((stripeStyle == 0) && (w >= sizeInPixels.iWidth-stripeSize)) 
   166 					|| ((stripeStyle == 1) && (h >= sizeInPixels.iHeight-stripeSize)))
   167 					{
   168 					compareColour = KStripeColours[2]; // right or bottom
   169 					}
   170 				else
   171 					{
   172 					compareColour = KStripeColours[1]; // middle
   173 					}					
   174 				bufferColour = ExtractRgb(scanline, w, iDisplayMode);
   175 				if (((iDisplayMode != EGray256) && (bufferColour != compareColour))
   176 					|| ((iDisplayMode == EGray256) && (bufferColour != TRgb::Gray256(compareColour.Gray256()))))
   177 					{					
   178 					INFO_PRINTF3(_L("Pixel comparison failed for pixel %d,%d"), w, h);
   179 					TEST(EFalse);
   180 					}			
   181 				}							
   182 			}
   183 		
   184 		// End scanline access to the extended bitmap
   185 		for (TInt i = 0; i < KNumBeginBitmapCalls; i++)
   186 			{
   187 			iRasterizer->EndBitmap(bitmapId);			
   188 			}
   189 		extendedBitmap->EndDataAccess();
   190 		
   191 		// Clean up
   192 		CleanupStack::Pop(1, extendedBitmap);
   193 		}
   194 	}
   195 
   196 /**
   197 @SYMTestCaseID		
   198 	GRAPHICS-FBSERV-RASTERIZER-003
   199 
   200 @SYMTestPriority
   201 	High
   202 
   203 @SYMPREQ
   204 	PREQ2096
   205 
   206 @SYMREQ
   207 	REQ10860
   208 	REQ10861 
   209 	
   210 @SYMTestCaseDesc
   211 	Test that we can get scanlines from 3 extended bitmaps simultaneously using the example rasterizer.
   212 
   213 @SYMTestActions	
   214 	Load a normal bitmap.	
   215 	Create 3 extended bitmaps and set their extended data to be vertically striped colours.	
   216 	Draw a scanline of each extended bitmap by calling:
   217 		- CFbsRasterizer::BeginBitmap() for each extended bitmap
   218 		- CFbsRasterizer::ScanLine() for each extended bitmap
   219 		- CFbsRasterizer::EndBitmap() for each extended bitmap
   220 	Compare the first pixel of each scanline and the last pixel of each scanline against the
   221 	expected colour.
   222 
   223 @SYMTestExpectedResults
   224 	The rasterizer should be able to handle rasterizing up to 3 extended bitmaps at once,
   225 	all three scanlines should be returned with no errors.
   226 	The colours compared should match exactly.
   227 */
   228 void CTRasterizer::TestMultipleScanLinesL()
   229 	{
   230 	TBuf<32> displayModeDes(TestUtils::DisplayModeToString(iDisplayMode)); 
   231 	INFO_PRINTF2(_L("TestMultipleScanLines, vertical stripes, display mode %S"), &displayModeDes);
   232 	
   233 	const TInt KNumBitmaps = 3;
   234 	const TInt KBaseSize = 10;			
   235 	RArray<CFbsBitmap*> bitmaps;
   236 	CleanupClosePushL(bitmaps);	
   237 	
   238 	// Get the example rasterizer
   239 	GetExampleRasterizerL();
   240 	
   241 	// Create the three differently sized extended bitmaps each coloured with vertical stripes 
   242 	for (TInt i = 0; i < KNumBitmaps; i++)
   243 		{
   244 		const TSize KSizeInPixels = TSize(KBaseSize*(i+1), KBaseSize*(i+1));			
   245 		CFbsBitmap* extendedBitmap = CreateExtendedBitmapLC(KStripeColours, EFalse, KSizeInPixels);		
   246 		bitmaps.AppendL(extendedBitmap);			
   247 		}
   248 	
   249 	// Begin scanline access to the extended bitmaps
   250 	for (TInt i = 0; i < KNumBitmaps; i++)
   251 		{
   252 		bitmaps[i]->BeginDataAccess();
   253 		
   254 		CFbsRasterizer::TBitmapDesc bitmapDesc;
   255 		TInt64 bitmapId = bitmaps[i]->SerialNumber();
   256 		bitmapDesc.iSizeInPixels = bitmaps[i]->SizeInPixels();
   257 		bitmapDesc.iDispMode = iDisplayMode;
   258 		bitmapDesc.iDataType = KUidExampleExtendedBitmap;
   259 		bitmapDesc.iData = bitmaps[i]->DataAddress();
   260 		bitmapDesc.iDataSize = bitmaps[i]->DataSize();	
   261 		iRasterizer->BeginBitmap(bitmapId, bitmapDesc, NULL);
   262 		}
   263 	
   264 	// Get scanlines from each extended bitmap and check that the first and last pixel in each is the correct colour
   265 	for (TInt h = 0; h < KBaseSize; h++)
   266 		{
   267 		for (TInt i = 0; i < KNumBitmaps; i++)
   268 			{	
   269 			const TUint8* scanline = reinterpret_cast<const TUint8*>(iRasterizer->ScanLine(bitmaps[i]->SerialNumber(), TPoint(0,h), KBaseSize*(i+1)));			
   270 			TESTL(scanline != NULL);					
   271 			
   272 			// Test that the first pixel is the correct colour (the first pixel in each scanline should be KStripeColours[0]
   273 			// as the bitmaps should have all been drawn with vertical stripes with the first stripe being KStripeColours[0]
   274 			TRgb bufferColour = ExtractRgb(scanline, 0, iDisplayMode);			
   275 			if (((iDisplayMode != EGray256) && (bufferColour != KStripeColours[0]))
   276 				|| ((iDisplayMode == EGray256) && (bufferColour != TRgb::Gray256(KStripeColours[0].Gray256()))))	
   277 				{
   278 				INFO_PRINTF3(_L("Pixel comparison failed for bitmap %d, pixel 0,%d"), i, h);
   279 				TEST(EFalse);
   280 				}	
   281 			// The last pixel should be KStripeColours[2]							
   282 			bufferColour = ExtractRgb(scanline, (KBaseSize*(i+1))-1, iDisplayMode);
   283 			if (((iDisplayMode != EGray256) && (bufferColour != KStripeColours[2]))
   284 				|| ((iDisplayMode == EGray256) && (bufferColour != TRgb::Gray256(KStripeColours[2].Gray256()))))	
   285 				{
   286 				INFO_PRINTF4(_L("Pixel comparison failed for bitmap %d, pixel %d,%d"), i, (KBaseSize*(i+1))-1, h);
   287 				TEST(EFalse);
   288 				}
   289 			}
   290 		}
   291 		
   292 	// Unregister each extended bitmap
   293 	for (TInt i = 0; i < KNumBitmaps; i++)
   294 		{					
   295 		iRasterizer->EndBitmap(bitmaps[i]->SerialNumber());
   296 		bitmaps[i]->EndDataAccess();
   297 		}
   298 	
   299 	// Cleanup
   300 	CleanupStack::PopAndDestroy(KNumBitmaps+1);
   301 	}
   302 
   303 /**
   304 @SYMTestCaseID		
   305 	GRAPHICS-FBSERV-RASTERIZER-004
   306 
   307 @SYMTestPriority
   308 	High
   309 
   310 @SYMPREQ
   311 	PREQ2096
   312 
   313 @SYMREQ
   314 	REQ10860
   315 	REQ10861 
   316 	
   317 @SYMTestCaseDesc
   318 	Test that the rasterizer returns portions of scanline correctly
   319 	when a region of interest is specified.
   320 
   321 @SYMTestActions	
   322 	Create an extended bitmap.
   323 	Rasterize it specifying a region of interest that has three regions that roughly
   324 	form a squared off C shape.		
   325 
   326 @SYMTestExpectedResults
   327 	Check that scanlines returned are correct in the specified region of interest.
   328 	(Anything outside the region of interest does not matter).
   329 */
   330 void CTRasterizer::TestRegionOfInterestL()
   331 	{
   332 	TBuf<32> displayModeDes(TestUtils::DisplayModeToString(iDisplayMode)); 
   333 	INFO_PRINTF2(_L("TestRegionOfInterest, horizontal stripes, display mode %S"), &displayModeDes);
   334 	
   335 	// Get the example rasterizer
   336 	GetExampleRasterizerL();	
   337 	
   338 	// Create an extended bitmap with horizontal stripes
   339 	const TSize sizeInPixels(24,24);
   340 	CFbsBitmap* extendedBitmap = CreateExtendedBitmapLC(KStripeColours, ETrue, sizeInPixels);		
   341 	
   342 	// Create a region of interest in the shape of a square with a hole in the middle
   343 	TRegionFix<4> regionOfInterest;
   344 	const TInt KStripeSize = sizeInPixels.iHeight/3;
   345 	const TInt KEdgeOffset = 2;	
   346 	regionOfInterest.AddRect(TRect(TPoint(KEdgeOffset,KEdgeOffset), TSize(sizeInPixels.iWidth-(KEdgeOffset*2),KStripeSize)));	// top of the square
   347 	regionOfInterest.AddRect(TRect(TPoint(KEdgeOffset,sizeInPixels.iHeight-KEdgeOffset-KStripeSize), TSize(sizeInPixels.iWidth-(KEdgeOffset*2),KStripeSize)));	// bottom of the square
   348 	regionOfInterest.AddRect(TRect(TPoint(KEdgeOffset,KEdgeOffset+KStripeSize), TSize(KStripeSize,sizeInPixels.iHeight-(KEdgeOffset*2)-(KStripeSize*2))));	// left of the square
   349 	regionOfInterest.AddRect(TRect(TPoint(sizeInPixels.iWidth-KEdgeOffset-KStripeSize,KEdgeOffset+KStripeSize), TSize(KStripeSize,sizeInPixels.iHeight-(KEdgeOffset*2)-(KStripeSize*2)))); // right of the square		
   350 	TEST(regionOfInterest.CheckError() == EFalse);
   351 		
   352 	// Begin scanline access to the extended bitmap
   353 	CFbsRasterizer::TBitmapDesc bitmapDesc;
   354 	TInt64 bitmapId = extendedBitmap->SerialNumber();
   355 	bitmapDesc.iSizeInPixels = sizeInPixels;
   356 	bitmapDesc.iDispMode = iDisplayMode;
   357 	bitmapDesc.iDataType = KUidExampleExtendedBitmap;
   358 	bitmapDesc.iData = extendedBitmap->DataAddress();
   359 	bitmapDesc.iDataSize = extendedBitmap->DataSize();
   360 	extendedBitmap->BeginDataAccess();
   361 	iRasterizer->BeginBitmap(bitmapId, bitmapDesc, &regionOfInterest);	
   362 	
   363 	TInt scanlineLength;
   364 	TPoint startPixel;
   365 	TRgb bufferColour;
   366 	 			
   367 	for (TInt h = 0; h < sizeInPixels.iHeight; h++)
   368 		{
   369 		// Get scanlines from the extended bitmap using the rasterizer	
   370 		startPixel = TPoint(0, h);
   371 		scanlineLength = sizeInPixels.iWidth;
   372 		const TUint8* scanline = reinterpret_cast<const TUint8*>(iRasterizer->ScanLine(bitmapId, startPixel, scanlineLength));
   373 		TESTL(scanline != NULL);								
   374 		
   375 		// Make sure each pixel in the scanline is the colour that we expect					
   376 		for (TInt w = 0; w < sizeInPixels.iWidth; w++)
   377 			{										
   378 			bufferColour = ExtractRgb(scanline, w, iDisplayMode);
   379 			
   380 			// Pixels that lie inside the region should be set to a flag stripe colour, pixels
   381 			// outside of the region should be white			
   382 			if (regionOfInterest.Contains(TPoint(w,h)))
   383 				{				
   384 				if (((iDisplayMode != EGray256) && (bufferColour != KStripeColours[h/KStripeSize]))
   385 					|| ((iDisplayMode == EGray256) && (bufferColour != TRgb::Gray256(KStripeColours[h/KStripeSize].Gray256()))))
   386 					{
   387 					INFO_PRINTF3(_L("Pixel comparison failed for pixel %d,%d"), w, h);
   388 					TEST(EFalse);
   389 					}			
   390 				}
   391 			else
   392 				{
   393 				if (bufferColour != KRgbWhite)
   394 					{
   395 					INFO_PRINTF3(_L("Pixel comparison failed for pixel %d,%d"), w, h);
   396 					TEST(EFalse);
   397 					}
   398 				}
   399 			}		
   400 		}
   401 	
   402 	// End scanline access to the extended bitmap	
   403 	iRasterizer->EndBitmap(bitmapId);
   404 	extendedBitmap->EndDataAccess();
   405 	
   406 	// Clean up
   407 	CleanupStack::Pop(1, extendedBitmap);
   408 	}
   409 
   410 /**
   411 Override of base class pure virtual
   412 Lists the tests to be run
   413 */
   414 TVerdict CTRasterizer::doTestStepL()
   415 	{
   416 	TestLoadRasterizerDllL();
   417 	
   418 	// Tests that require testing in multiple display modes
   419 	for (TInt i = 0; i < KNumDisplayModes; i++)
   420 		{
   421 		iDisplayMode = KDisplayModes[i];		
   422 				
   423 		TestScanLineL();
   424 		TestMultipleScanLinesL();
   425 		TestRegionOfInterestL();
   426 		}
   427 	
   428 	return TestStepResult();
   429 	}
   430 
   431 /** Helper function for getting a TRgb colour value from a buffer given a pixel offset and 
   432 a display mode.
   433 @param aBuffer A buffer to extract the TRgb from
   434 @param aPixelOffset The pixel position in the buffer to extract the TRgb from
   435 @param aDispMode The display mode of the buffer
   436 @return The TRgb value found at the pixel position specified
   437  */
   438 TRgb CTRasterizer::ExtractRgb(const TUint8* aBuffer, TInt aPixelOffset, TDisplayMode aDispMode)
   439 	{
   440 	switch (aDispMode)
   441 		{
   442 	case EGray2:
   443 		{
   444 		TUint8 byte = *(aBuffer + (aPixelOffset >> 3));
   445 		if (byte & (1 << (aPixelOffset & 7)))
   446 			return KRgbWhite;
   447 		return KRgbBlack;
   448 		}
   449 	case EGray4:
   450 		{
   451 		TUint8 byte = *(aBuffer + (aPixelOffset >> 2));
   452 		byte >>= ((aPixelOffset & 3) << 1);
   453 		return TRgb::Gray4(byte & 3);
   454 		}
   455 	case EGray16:
   456 		{
   457 		TUint8 byte = *(aBuffer + (aPixelOffset >> 1));
   458 		if (aPixelOffset & 1)
   459 			byte >>= 4;
   460 		return TRgb::Gray16(byte & 0xf);
   461 		}
   462 	case EGray256:
   463 		return TRgb::Gray256(*(aBuffer + aPixelOffset));
   464 	case EColor16:
   465 		{
   466 		TUint8 byte = *(aBuffer + (aPixelOffset >> 1));
   467 		if (aPixelOffset & 1)
   468 			byte >>= 4;
   469 		return TRgb::Color16(byte & 0xf);
   470 		}
   471 	case EColor256:
   472 		return TRgb::Color256(*(aBuffer + aPixelOffset));
   473 	case EColor4K:
   474 		{
   475 		TUint16 doubleByte = *(((TUint16*)aBuffer) + aPixelOffset);
   476 		return TRgb::Color4K(doubleByte & 0xfff);
   477 		}
   478 	case EColor64K:
   479 		{
   480 		TUint16 doubleByte = *(((TUint16*)aBuffer) + aPixelOffset);
   481 		return TRgb::Color64K(doubleByte);
   482 		}
   483 	case EColor16M:
   484 		{
   485 		aBuffer += aPixelOffset * 3;
   486 		TInt value = *aBuffer++;
   487 		value |= *aBuffer++ << 8;
   488 		value |= *aBuffer << 16;
   489 		return TRgb::Color16M(value);
   490 		}
   491 	case ERgb:
   492 		return *(((TRgb*)aBuffer) + aPixelOffset);
   493 	case EColor16MU:
   494 		{
   495 		// Note this is | with 0xFF000000 to match the example rasterizer which sets
   496 		// the alpha to 0xFF when drawing using EColor16MU
   497 		return TRgb::Color16MU((*(((TUint32*)aBuffer) + aPixelOffset)) | 0xFF000000);
   498 		}
   499 	case EColor16MA:
   500 		{
   501 		return TRgb::Color16MA(*(((TUint32*)aBuffer) + aPixelOffset));
   502 		}	
   503 	case EColor16MAP:
   504 		{
   505 		return TRgb::_Color16MAP(*(((TUint32*)aBuffer) + aPixelOffset));
   506 		}	
   507 	default:
   508 		break;
   509 		};
   510 	return KRgbBlack;
   511 	}
   512 
   513 /** Helper function for creating an extended bitmap. 
   514 @param aColours A pointer to an array of three colours to use when creating the extended bitmap, 
   515 these colours define the colours used when drawing the stripes in the extended bitmap.
   516 @param aHorizontalStripe ETrue for horizontal stripes, EFalse for vertical stripes.
   517 @param aSizeInPixels The size of the extended bitmap to create.
   518 @return A pointer to a newly created extended bitmap that has been pushed on to the cleanup stack.
   519  */
   520 CFbsBitmap* CTRasterizer::CreateExtendedBitmapLC(const TRgb* aColours, TBool aHorizontalStripe, TSize aSizeInPixels)
   521 	{	
   522 	// Set up the buffer containing the three TRgb values and one TUint8 value that the rasterizer expects
   523 	TInt dataSize = (sizeof(TRgb)*3) + sizeof(TUint8); // estimate the size to be written
   524 	TUint8* data = new (ELeave)TUint8[dataSize];
   525 	CleanupArrayDeletePushL(data);
   526 	RMemWriteStream writeStream;
   527 	writeStream.Open(data, dataSize);
   528 	CleanupClosePushL(writeStream);		
   529 	writeStream << aColours[0]; 		
   530 	writeStream << aColours[1];		
   531 	writeStream << aColours[2];
   532 	TUint8 stripe = aHorizontalStripe; // EFalse is vertical stripes, ETrue is horizontal stripes
   533 	writeStream << stripe;
   534 	dataSize = writeStream.Sink()->TellL(MStreamBuf::EWrite).Offset(); // get the actual size written
   535 	CleanupStack::PopAndDestroy(&writeStream);					
   536 
   537 	CFbsBitmap* extendedBitmap = new(ELeave) CFbsBitmap;
   538 		
   539 	TInt err = extendedBitmap->CreateExtendedBitmap(aSizeInPixels, 
   540 													iDisplayMode,
   541 													KUidExampleExtendedBitmap,
   542 													data,
   543 													dataSize);
   544 	CleanupStack::PopAndDestroy(data);
   545 	CleanupStack::PushL(extendedBitmap);
   546 	TESTL(err == KErrNone);
   547 			
   548 	return extendedBitmap;
   549 	}