graphicstest/graphicstestharness/textendedbitmapgc/textendedbitmapgc.cpp
author Gareth Stockwell <gareth.stockwell@accenture.com>
Fri, 05 Nov 2010 17:31:20 +0000
branchbug235_bringup_0
changeset 215 097e92a68d68
parent 0 5d03bc08d59c
permissions -rw-r--r--
Added GLES 1.x spinning cube-rendering code to eglbringuptest The coordinate, color and index data are uploaded to server-side buffers by the CGLES1Cube::KhrSetup function. CGLES1Cube::KhrPaint just sets the view matrix and issues a draw command. Which demo to display can be selected by passing its name on the command line, e.g. eglbringuptest vgline eglbringuptest gles1cube If no name is provided, the application defaults to vgline.

// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
//

#include "textendedbitmapgc.h"
#include <s32mem.h>

const TInt KNumBitmapDrawingTests = 10;
const TInt KNumBrushPatternTests = 8;
const TUid KUidExampleExtendedBitmap = {0x10285A78};

/** Constructor.
@param aCallBack Pointer to a valid implementation of MTestHarnessCallBack, to allow logging and 
test status requests to be passed back to the creator of a CTExtendedBitmapGc object.
@param aGc A graphics context to use for all drawing operations.
@param aDrawMode The mode to draw extended bitmaps in, either EDrawFlag or EDrawWhite.
@param aDisplayMode The display mode to use when creating extended bitmaps, this
must be one of EGray256, EColor64K, EColor16MU or EColor16MAP.
@return a pointer to a newly constructed CTExtendedBitmapGc object. 
@leave KErrNotSupported if an unsupported display mode is passed in aDisplayMode.
 */
EXPORT_C CTExtendedBitmapGc* CTExtendedBitmapGc::NewL(MTestHarnessCallBack* aCallBack, 
												CBitmapContext& aGc, 
												TDrawMode aDrawMode,
												TDisplayMode aDisplayMode)
	{	
	CTExtendedBitmapGc* ebgc = new(ELeave) CTExtendedBitmapGc(aCallBack, aGc, aDrawMode);
	CleanupStack::PushL(ebgc);
	ebgc->ConstructL(aDisplayMode);
	CleanupStack::Pop(ebgc);
	return ebgc;
	}

CTExtendedBitmapGc::CTExtendedBitmapGc(MTestHarnessCallBack* aCallBack, 
										CBitmapContext& aGc, 
										TDrawMode aDrawMode) :
iCallBack(aCallBack), iDrawMode(aDrawMode), iGc(aGc), iIsFbs(aGc.IsFbsBitGc())
	{
	}

void CTExtendedBitmapGc::ConstructL(TDisplayMode aDisplayMode)

	{	
	// Check that the display mode chosen is supported by the example rasterizer
	if ((aDisplayMode != EGray256) && (aDisplayMode != EColor64K) && (aDisplayMode != EColor16MU) && (aDisplayMode != EColor16MAP))
		{
		INFO_PRINTF2(_L("Failed to construct CTExtendedBitmapGc with unsupported display mode %d"), aDisplayMode);
		User::Leave(KErrNotSupported);
		}
	iDisplayMode = aDisplayMode; 
	
	// Get a font for use with the DrawText() and DrawTextVertical() tests
	_LIT(KFontName, "DejaVu Sans Condensed");
	TFontSpec fontSpec(KFontName, 75);
	fontSpec.iFontStyle.SetBitmapType(EAntiAliasedGlyphBitmap);
	iCallBack->TestTrue(KErrNone == static_cast<CBitmapDevice*>(iGc.Device())->GetNearestFontToDesignHeightInPixels(iFont, fontSpec));
	iGc.UseFont(iFont);
	}

EXPORT_C CTExtendedBitmapGc::~CTExtendedBitmapGc()
	{
	if(iFont)
		{
		iGc.DiscardFont();
		static_cast<CBitmapDevice*>(iGc.Device())->ReleaseFont(iFont);
		}
	}

/** Test case calling function used to test drawing of Extended Bitmaps on graphics contexts.
Utilised by GRAPHICS-BITGDI-0103 to test with CFbsBitGc, and by GRAPHICS-WSERV-0493 with CWindowGc.
@param aCaseNumber Case number to run
 */
EXPORT_C void CTExtendedBitmapGc::RunTestCaseL(TInt aCurTestCase)
	{
	--aCurTestCase;
	switch(aCurTestCase / KNumBitmapDrawingTests)
		{
	case 0:
		TestBitmapDrawingL(EFalse, EVerticalStripe, aCurTestCase % KNumBitmapDrawingTests);	
		break;
	case 1:
		TestBitmapDrawingL(EFalse, EHorizontalStripe, aCurTestCase % KNumBitmapDrawingTests);	
		break;
	case 2:
		TestBitmapDrawingL(ETrue, EVerticalStripe, aCurTestCase % KNumBitmapDrawingTests);	
		break;
	case 3:
		TestBitmapDrawingL(ETrue, EHorizontalStripe, aCurTestCase % KNumBitmapDrawingTests);	
		break;
	default:
		{
		TInt brushCase = aCurTestCase - (4 * KNumBitmapDrawingTests);
		if(brushCase < KNumBrushPatternTests)
			{
			TestBrushPatternL(brushCase);
			}
		else
			{
			// Finished tests
			iCallBack->TestComplete();
			}
		}
		}
	}

/** Test case function used to test drawing of Extended Bitmaps on graphics contexts.
Utilised by GRAPHICS-BITGDI-0103 to test with CFbsBitGc, and by GRAPHICS-WSERV-0493 with CWindowGc.
@param aTestRegionOfInterest ETrue if to set a region of interest before drawing, EFalse not to
@param aStripeStyle Direction to draw the flag stripes, when rasterizer is present
@param aCaseNumber Case number to run - between 0 and (KNumBitmapDrawingTests - 1)
 */
void CTExtendedBitmapGc::TestBitmapDrawingL(TBool aTestRegionOfInterest, TStripeStyle aStripeStyle, TInt aCaseNumber)
	{
	_LIT(KVertical, "vertical");
	_LIT(KHorizontal, "horizontal");	
	_LIT(KRegionNotSet, "not set");
	_LIT(KRegionSet, "set");
	const TPtrC KStripeStyle[2] = {KVertical(), KHorizontal()};
	const TPtrC KRegionStyle[2] = {KRegionNotSet(), KRegionSet()};
	const TInt KNumColors = 3;
	const TRgb KColors[KNumColors] = {TRgb(0,255,255), TRgb(255,0,255), TRgb(255,255,0)};

	const TRgb KMaskColors[KNumColors] = {KRgbBlack, KRgbWhite, KRgbBlack};
	const TRgb KAlphaColors[KNumColors] = {KRgbDarkGray, KRgbGray, KRgbDarkGray};
	const TStripeStyle KMaskBitmapStripeStyle = EVerticalStripe;
	const TStripeStyle KAlphaBitmapStripeStyle = EHorizontalStripe;

	TInt dataSize = sizeof(KColors)+sizeof(TUint8); // estimate the data size
	TUint8* data = new(ELeave) TUint8[dataSize];
	CleanupStack::PushL(data);
	
	const TSize scrSize = iGc.Device()->SizeInPixels();	

	// Decide what size the bitmaps should be
	TRect extendedRect;
	extendedRect.SetRect(10,10,(scrSize.iWidth>>1)-10,scrSize.iHeight-10);
	TRect standardRect(extendedRect);
	standardRect.Move(scrSize.iWidth>>1,0);
	const TSize sizeInPixels(extendedRect.Width(),extendedRect.Height());

	// Rects used for scaling tests
	TRect scaledExtendedRect = extendedRect;
	scaledExtendedRect.SetWidth(sizeInPixels.iWidth*3/4);
	scaledExtendedRect.SetHeight(sizeInPixels.iHeight*3/5);
	TRect scaledStandardRect = standardRect;
	scaledStandardRect.SetWidth(sizeInPixels.iWidth*3/4);
	scaledStandardRect.SetHeight(sizeInPixels.iHeight*3/5);

	// Positions for drawing extended and normal bitmaps
	TPoint bmpExPos(10,10);
	TPoint bmpNmlPos(10+(scrSize.iWidth>>1),10);

	// Use black and white vertical stripes as the data for the mask
	WriteExtendedBitmapInfoL(data, dataSize, KMaskColors, KMaskBitmapStripeStyle);

	// Create an extended bitmap to use as a mask
	CFbsBitmap* bmpMaskEx = new(ELeave) CFbsBitmap;
	CleanupStack::PushL(bmpMaskEx);
	TInt err = bmpMaskEx->CreateExtendedBitmap(sizeInPixels, iDisplayMode, KUidExampleExtendedBitmap, data, dataSize);
	iCallBack->TestTrue(err == KErrNone);

	// Create a normal mask bitmap to use when testing the extended mask bitmap above
	CFbsBitmap* bmpMaskNml;
	CreateTestBitmapLC(bmpMaskNml, sizeInPixels, iDisplayMode, KRgbBlack, KRgbWhite, KRgbBlack, KMaskBitmapStripeStyle);

	// Use dark grey and grey horizontal stripes as the data for the alpha bitmap
	WriteExtendedBitmapInfoL(data, dataSize, KAlphaColors, KAlphaBitmapStripeStyle);

	// Create an EGray256 extended bitmap to use when alpha blending
	CFbsBitmap* bmpAlphaEx = new(ELeave) CFbsBitmap;
	CleanupStack::PushL(bmpAlphaEx);
	err = bmpAlphaEx->CreateExtendedBitmap(sizeInPixels, EGray256, KUidExampleExtendedBitmap, data, dataSize);
	iCallBack->TestTrue(err == KErrNone);

	// Create a normal EGray256 alpha bitmap to use when testing the extended alpha bitmap above
	CFbsBitmap* bmpAlphaNml;
	CreateTestBitmapLC(bmpAlphaNml, sizeInPixels, EGray256, KRgbDarkGray, KRgbGray, KRgbDarkGray, KAlphaBitmapStripeStyle);

	// Create a clipping region and a clipping rect, making sure the shape of the region
	// that is set is the same on both sides of the screen
	const TInt KStripeSize = ((scrSize.iWidth>=300)&&(scrSize.iHeight>=100))?50:30;
	TRegionFix<8> clippingRegion;
	clippingRegion.AddRect(TRect(TPoint(0,0), TSize(scrSize.iWidth,KStripeSize)));
	clippingRegion.AddRect(TRect(TPoint(0,scrSize.iHeight>>1), TSize(scrSize.iWidth,KStripeSize)));
	clippingRegion.AddRect(TRect(TPoint(KStripeSize,0), TSize(KStripeSize<<1,scrSize.iHeight)));
	clippingRegion.AddRect(TRect(TPoint((scrSize.iWidth>>1)+KStripeSize,0), TSize(KStripeSize<<1,scrSize.iHeight)));
	iCallBack->TestTrue(clippingRegion.CheckError() == EFalse);
	TRect clippingRect(TPoint(0,KStripeSize>>1), TSize(scrSize.iWidth,scrSize.iHeight-KStripeSize));

	// Write the colours to be used in the extended bitmap to the extended bitmap data,
	// we run the tests one with horizontal stripes and once with vertical stripes
	WriteExtendedBitmapInfoL(data, dataSize, KColors, aStripeStyle);

	// Create an extended bitmap
	CFbsBitmap* bmpEx = new(ELeave) CFbsBitmap;
	CleanupStack::PushL(bmpEx);
	err = bmpEx->CreateExtendedBitmap(sizeInPixels, iDisplayMode, KUidExampleExtendedBitmap, data, dataSize);
	iCallBack->TestTrue(err == KErrNone);

	// Create a normal bitmap to use when testing the extended bitmap above
	CFbsBitmap* bmpNml;
	CreateTestBitmapLC(bmpNml, sizeInPixels, iDisplayMode, KColors[0], KColors[1], KColors[2], aStripeStyle);

	// Clear to red
	iGc.SetBrushColor(KRgbRed);
	iGc.Clear();

	if (aTestRegionOfInterest)
		{
		iGc.SetClippingRegion(clippingRegion);
		iGc.SetClippingRect(clippingRect);
		}

	// Draw the extended bitmap(s) on the left side of the screen and the normal bitmap(s) on the
	// right side of the screen in each case
	switch (aCaseNumber)
		{
		case 0:
			{
			INFO_PRINTF3(_L("Stripe style %S. Region of interest %S"), &KStripeStyle[aStripeStyle], &KRegionStyle[aTestRegionOfInterest]);
			INFO_PRINTF1(_L("... BitBlt()"));
			iGc.BitBlt(bmpExPos, bmpEx);
			iGc.BitBlt(bmpNmlPos, bmpNml);
			break;
			}
		case 1:
			{
			INFO_PRINTF1(_L("... BitBltMasked()"));
			iGc.BitBltMasked(bmpExPos, bmpEx, sizeInPixels, bmpMaskEx, EFalse);
			iGc.BitBltMasked(bmpNmlPos, bmpNml, sizeInPixels, bmpMaskNml, EFalse);
			break;
			}
		case 2:
			{
			INFO_PRINTF1(_L("... DrawBitmap()"));
			iGc.DrawBitmap(extendedRect, bmpEx);
			iGc.DrawBitmap(standardRect, bmpNml);
			break;
			}
		case 3:
			{
			INFO_PRINTF1(_L("... DrawBitmap() with scaling"));
			iGc.DrawBitmap(scaledExtendedRect, bmpEx);
			iGc.DrawBitmap(scaledStandardRect, bmpNml);
			break;
			}
		case 4:
			{
			INFO_PRINTF1(_L("... DrawBitmapMasked()"));
			iGc.DrawBitmapMasked(extendedRect, bmpEx, sizeInPixels, bmpMaskEx, EFalse);
			iGc.DrawBitmapMasked(standardRect, bmpNml, sizeInPixels, bmpMaskNml, EFalse);
			break;
			}
		case 5:
			{
			INFO_PRINTF1(_L("... DrawBitmapMasked() with scaling"));
			iGc.DrawBitmapMasked(scaledExtendedRect, bmpEx, sizeInPixels, bmpMaskEx, EFalse);
			iGc.DrawBitmapMasked(scaledStandardRect, bmpNml, sizeInPixels, bmpMaskNml, EFalse);
			break;
			}
		case 6:
			{
			if(iIsFbs)
				{
				CFbsBitGc& fbsGc = static_cast<CFbsBitGc&>(iGc);
				INFO_PRINTF1(_L("... AlphaBlendBitmaps() - 1"));
				iCallBack->TestTrue(fbsGc.AlphaBlendBitmaps(bmpExPos, bmpEx, bmpMaskEx, sizeInPixels, TPoint(0,0), bmpAlphaEx, TPoint(0,0)) == KErrNone);
				iCallBack->TestTrue(fbsGc.AlphaBlendBitmaps(bmpNmlPos, bmpNml, bmpMaskNml, sizeInPixels, TPoint(0,0), bmpAlphaNml, TPoint(0,0)) == KErrNone);
				}
			break;
			}
		case 7:
			{
			if(iIsFbs)
				{
				CFbsBitGc& fbsGc = static_cast<CFbsBitGc&>(iGc);
				INFO_PRINTF1(_L("... AlphaBlendBitmaps() - 1 with offset"));
				iCallBack->TestTrue(fbsGc.AlphaBlendBitmaps(bmpExPos, bmpEx, bmpMaskEx, TSize(sizeInPixels.iWidth-5, sizeInPixels.iHeight-10), TPoint(5,10), bmpAlphaEx, TPoint(3,2)) == KErrNone);
				iCallBack->TestTrue(fbsGc.AlphaBlendBitmaps(bmpNmlPos, bmpNml, bmpMaskNml, TSize(sizeInPixels.iWidth-5, sizeInPixels.iHeight-10), TPoint(5,10), bmpAlphaNml, TPoint(3,2)) == KErrNone);
				}
			break;
			}
		case 8:
			{
			INFO_PRINTF1(_L("... AlphaBlendBitmaps() - 2"));
			iCallBack->TestTrue(iGc.AlphaBlendBitmaps(bmpExPos, bmpEx, sizeInPixels, bmpAlphaEx, TPoint(0,0)) == KErrNone);
			iCallBack->TestTrue(iGc.AlphaBlendBitmaps(bmpNmlPos, bmpNml, sizeInPixels, bmpAlphaNml, TPoint(0,0)) == KErrNone);
			break;
			}
		case 9:
			{
			INFO_PRINTF1(_L("... AlphaBlendBitmaps() - 2 with offset"));
			iCallBack->TestTrue(iGc.AlphaBlendBitmaps(bmpExPos, bmpEx, TSize(sizeInPixels.iWidth-16, sizeInPixels.iHeight-7), bmpAlphaEx, TPoint(16,7)) == KErrNone);
			iCallBack->TestTrue(iGc.AlphaBlendBitmaps(bmpNmlPos, bmpNml, TSize(sizeInPixels.iWidth-16, sizeInPixels.iHeight-7), bmpAlphaNml, TPoint(16,7)) == KErrNone);
			break;
			}
		default:
			{
			// Should not be reached
			iCallBack->TestTrue(EFalse);
			}
			break;
		}

	if (aTestRegionOfInterest)
		{
		// Cancel clipping rectangle and region if necessary
		iGc.CancelClippingRegion();
		iGc.CancelClippingRect();
		}
		
	CleanupStack::PopAndDestroy(7, data);
	}

/** Test case function used to test the use of Extended Bitmaps as brush patterns within graphics contexts.
Utilised by GRAPHICS-BITGDI-0103 to test with CFbsBitGc, and by GRAPHICS-WSERV-0493 with CWindowGc.
@param aCaseNumber Case number to run - between 0 and (KNumBrushPatternTests - 1)
 */
void CTExtendedBitmapGc::TestBrushPatternL(TInt aCaseNumber)
	{	
	const TInt KNumColors = 3;
	const TRgb KColors[KNumColors] = {TRgb(0,255,255), TRgb(255,0,255), TRgb(255,255,0)};
	const TSize KBrushSize(63,63);		
	TInt dataSize = sizeof(KColors)+sizeof(TUint8); // estimate the data size
	TUint8* data = new(ELeave) TUint8[dataSize];
	CleanupStack::PushL(data);	
	
	// Write the colours to be used in the extended bitmap to the data	
	WriteExtendedBitmapInfoL(data, dataSize, KColors, EHorizontalStripe);	
	
	// Create the extended bitmap to be used a a brush
	CFbsBitmap* extendedBmp = new(ELeave) CFbsBitmap;
	CleanupStack::PushL(extendedBmp);
	TInt err = extendedBmp->CreateExtendedBitmap(KBrushSize, iDisplayMode, KUidExampleExtendedBitmap, data, dataSize);
	iCallBack->TestTrue(err == KErrNone);
	
	// Create the standard bitmap to also be used as a brush
	CFbsBitmap* standardBmp = new(ELeave) CFbsBitmap;
	CleanupStack::PushL(standardBmp);
	err = standardBmp->Create(KBrushSize, iDisplayMode);
	iCallBack->TestTrue(err == KErrNone);
	
	// Create a bitmap device and a context so that the flag pattern can be drawn on
	// the standard bitmap
	CFbsBitmapDevice* bitDev = CFbsBitmapDevice::NewL(standardBmp);
	CleanupStack::PushL(bitDev);
	CFbsBitGc* bitGc;
	err = bitDev->CreateContext(bitGc);
	iCallBack->TestTrue(err == KErrNone);
	CleanupStack::PushL(bitGc);
	
	// Draw the flag pattern to the standard bitmap if the draw mode is EDrawFlag, 
	// leave as white otehrwise
	if (iDrawMode == EDrawFlag)
		{
		bitGc->SetPenStyle(CGraphicsContext::ENullPen);
		bitGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
		for (TInt i = 0; i < KNumColors; i++)
			{
			bitGc->SetBrushColor(KColors[i]);
			bitGc->DrawRect(TRect(0,(KBrushSize.iHeight/3)*i,KBrushSize.iWidth,(KBrushSize.iHeight/3)*(i+1)));	
			}
		}	
	CleanupStack::PopAndDestroy(2, bitDev);
	
	// Create a screen device and a context to draw to
	TSize scrSize = iGc.Device()->SizeInPixels();
		
	TRect extendedShapeSize;
	extendedShapeSize.SetRect(10,10,(scrSize.iWidth>>1)-10,scrSize.iHeight-10);
	TRect standardShapeSize(extendedShapeSize);
	standardShapeSize.Move(scrSize.iWidth>>1,0);

	TInt baseline = extendedShapeSize.Height() / 2 + iFont->AscentInPixels() / 2;
	
	iGc.SetBrushColor(KRgbBlue);
	iGc.Clear();
	iGc.SetBrushColor(KRgbWhite);		
	iGc.UseBrushPattern(extendedBmp);
	iGc.SetBrushStyle(CGraphicsContext::EPatternedBrush);		
	
	switch (aCaseNumber)
		{
		case 0: //DrawPie()
			{
			INFO_PRINTF1(_L("Testing brush patterns with an extended bitmap"));
			INFO_PRINTF1(_L("... DrawPie()"));
			iGc.DrawPie(extendedShapeSize, TPoint(extendedShapeSize.iTl.iX,0), TPoint(extendedShapeSize.iBr.iX,0));				
			iGc.UseBrushPattern(standardBmp);					
			iGc.DrawPie(standardShapeSize, TPoint(standardShapeSize.iTl.iX,0), TPoint(standardShapeSize.iBr.iX,0));				
			break;
			}
		case 1: // DrawRoundRect()
			{
			INFO_PRINTF1(_L("... DrawRoundRect()"));
			iGc.DrawRoundRect(extendedShapeSize, TSize(10,10));				
			iGc.UseBrushPattern(standardBmp);				
			iGc.DrawRoundRect(standardShapeSize, TSize(10,10));
			break;
			}
		case 2: // DrawPolygon() 
			{
			INFO_PRINTF1(_L("... DrawPolygon() 1"));
			const TInt KNumPoints = 3;
			CArrayFix<TPoint>* points = new(ELeave) CArrayFixFlat<TPoint>(KNumPoints);
			CleanupStack::PushL(points);
			points->AppendL(TPoint(extendedShapeSize.iTl.iX,extendedShapeSize.iTl.iY)); 
			points->AppendL(TPoint(extendedShapeSize.iBr.iX,extendedShapeSize.iBr.iY));
			points->AppendL(TPoint(extendedShapeSize.iTl.iX,extendedShapeSize.iBr.iY));
			iGc.DrawPolygon(points, CGraphicsContext::EWinding);
			iGc.UseBrushPattern(standardBmp);				
			iGc.SetOrigin(TPoint(standardShapeSize.iTl.iX-10,0));
			iGc.DrawPolygon(points, CGraphicsContext::EWinding);
			iGc.SetOrigin(TPoint(0,0));
			CleanupStack::PopAndDestroy(points);				
			break;
			}
		case 3: // DrawPolygon()
			{
			INFO_PRINTF1(_L("... DrawPolygon() 2"));
			const TInt KNumPoints = 3;
			TPoint* points = static_cast<TPoint*>(User::AllocL(sizeof(TPoint)*KNumPoints));
			CleanupStack::PushL(points);
			points[0] = TPoint(extendedShapeSize.iBr.iX,extendedShapeSize.iTl.iY); 
			points[1] = TPoint(extendedShapeSize.iBr.iX,extendedShapeSize.iBr.iY);
			points[2] = TPoint(extendedShapeSize.iTl.iX,extendedShapeSize.iBr.iY/2);
			iGc.DrawPolygon(points, KNumPoints, CGraphicsContext::EWinding);
			iGc.UseBrushPattern(standardBmp);				
			iGc.SetOrigin(TPoint(standardShapeSize.iTl.iX-10,0));
			iGc.DrawPolygon(points, KNumPoints, CGraphicsContext::EWinding);
			iGc.SetOrigin(TPoint(0,0));		
			CleanupStack::PopAndDestroy(points);
			break;
			}
		case 4: // DrawEllipse()
			{
			INFO_PRINTF1(_L("... DrawEllipse()"));
			iGc.DrawEllipse(extendedShapeSize);
			iGc.UseBrushPattern(standardBmp);				
			iGc.DrawEllipse(standardShapeSize);
			break;
			}
		case 5: // DrawRect()
			{
			INFO_PRINTF1(_L("... DrawRect()"));
			iGc.DrawRect(extendedShapeSize);				
			iGc.UseBrushPattern(standardBmp);				
			iGc.DrawRect(standardShapeSize);
			break;
			}
		case 6: // DrawText()
			{
			INFO_PRINTF1(_L("... DrawText()"));			
			iGc.DrawText(_L("HELLO"), extendedShapeSize, baseline);
			iGc.UseBrushPattern(standardBmp);
			iGc.DrawText(_L("HELLO"), standardShapeSize, baseline);
			break;
			}
		case 7: // DrawTextVertical()
			{				
			INFO_PRINTF1(_L("... DrawTextVertical()"));																		
			iGc.DrawTextVertical(_L("HELLO"), extendedShapeSize, baseline, EFalse);
			iGc.UseBrushPattern(standardBmp);
			iGc.DrawTextVertical(_L("HELLO"), standardShapeSize, baseline, EFalse);
			break;
			}
		default:
			{
			// Should not be reached
			iCallBack->TestTrue(EFalse);
			}
		}			
	CleanupStack::PopAndDestroy(3, data);
	}

/** Helper method for creating  and filling striped bitmaps equivalent to the extended bitmaps used in the test 
CTExtendedBitmap::TestBitmapDrawingL().
@param aBmpRet The newly created bitmap.
@param aSize The size of the bitmap to create.
@param aDisplayMode The display mode of the bitmap to create.
@param aColor1 The colour of the first stripe.
@param aColor2 The colour of the second stripe.
@param aColor3 The colour of the third stripe.
@param aStripeStyle Horizontal or vertical stripes, 0 for vertical stripe, 1 for horizontal stripes.
@return KErrNone if the bitmap was created successfully and returned in aBmpRet, one of the system
wide error codes otherwise. 
@post Leaves aBmpRet on the clean up stack if it is created successfully 
 */
void CTExtendedBitmapGc::CreateTestBitmapLC(CFbsBitmap*& aBmpRet,
										const TSize& aSize,
										TDisplayMode aDisplayMode, 
										const TRgb& aColor1, 
										const TRgb& aColor2, 
										const TRgb& aColor3,
										TStripeStyle aStripeStyle)
	{
	const TInt KNumColors = 3;
	TRgb colors[3] = {aColor1, aColor2, aColor3};
	
	CFbsBitmap* bmp = new(ELeave) CFbsBitmap;
	CleanupStack::PushL(bmp); // This gets left on the cleanup stack when the function returns
	TInt err = bmp->Create(aSize, aDisplayMode);	
	User::LeaveIfError(err);
		
	CFbsBitmapDevice* bmpDev = CFbsBitmapDevice::NewL(bmp);	
	CleanupStack::PushL(bmpDev);	
	CFbsBitGc* gc;
	err = bmpDev->CreateContext(gc);
	User::LeaveIfError(err);
	CleanupStack::PushL(gc);
	
	// Only draw stripes onto the test bitmap if the draw mode is EDrawFlag, otherwise
	// it should be left as cleared to white
	if (iDrawMode == EDrawFlag)
		{
		TInt outerStripeSize;												
		TInt middleStripeSize;							
		TRect stripeRect[3];
		
		if (aStripeStyle == EHorizontalStripe)
			{
			outerStripeSize = aSize.iHeight/3;												
			middleStripeSize = aSize.iHeight-(outerStripeSize<<1);							
			stripeRect[0] = TRect(TPoint(0,0), TSize(aSize.iWidth,outerStripeSize));
			stripeRect[1] = TRect(TPoint(0,outerStripeSize), TSize(aSize.iWidth,middleStripeSize));
			stripeRect[2] = TRect(TPoint(0,outerStripeSize+middleStripeSize), TSize(aSize.iWidth,outerStripeSize));
			}
		else if (aStripeStyle == EVerticalStripe)
			{
			outerStripeSize = aSize.iWidth/3;												
			middleStripeSize = aSize.iWidth-(outerStripeSize<<1);							
			stripeRect[0] = TRect(TPoint(0,0), TSize(outerStripeSize,aSize.iHeight));
			stripeRect[1] = TRect(TPoint(outerStripeSize,0), TSize(middleStripeSize,aSize.iHeight));
			stripeRect[2] = TRect(TPoint(outerStripeSize+middleStripeSize,0), TSize(outerStripeSize,aSize.iHeight));
			}
		else
			{
			INFO_PRINTF2(_L("Unsupported stripe style passed to CTExtendedBitmap::CreateTestBitmapLC: %d"), aStripeStyle);
			User::Leave(KErrArgument);
			}
		
		for (TInt i = 0; i < KNumColors; i++)
			{
			gc->SetBrushColor(colors[i]);
			gc->SetPenStyle(CGraphicsContext::ENullPen);
			gc->SetBrushStyle(CGraphicsContext::ESolidBrush);			
			gc->DrawRect(stripeRect[i]);
			}		
		}
	
	// Only pop the bitmap device and the gc, the created bitmap is left on the cleanup stack
	CleanupStack::PopAndDestroy(2, bmpDev); 	
	
	aBmpRet = bmp; 	
	}

/** Helper function for writing colour and stripe information used when creating an extended bitmap to
a write stream.
@param aData A pointer to a buffer that is large enough to write three TRgb colours and one TUint8 to.
@param aDataSize The size of buffer pointed to by aData, the actual size written is returned here
@param aColourArray A pointer to an array of the three colours to be written to the buffer
@param aHorizontalStripe ETrue to use horizontal stripes, EFalse for vertcial stripes
 */
EXPORT_C void CTExtendedBitmapGc::WriteExtendedBitmapInfoL(TUint8* aData,
												TInt& aDataSize,															
												const TRgb* aColorArray, 
												TStripeStyle aStripeStyle)
	{
	const TInt KNumColors = 3;

	// We expect an array of three colours
	if (sizeof(aColorArray) == (sizeof(TRgb)*KNumColors))
		{		
		User::Leave(KErrArgument);
		}
	
	RMemWriteStream ws;
	ws.Open(aData, aDataSize);
	CleanupClosePushL(ws);
	ws << aColorArray[0] << aColorArray[1] << aColorArray[2] << static_cast<TUint8>(aStripeStyle); // horizontal stripe
	aDataSize = ws.Sink()->TellL(MStreamBuf::EWrite).Offset(); // get the actual size written
	CleanupStack::PopAndDestroy(1, &ws);
	}