graphicstest/uibench/src/tfbsglyphdata.cpp
changeset 187 9f66f99ee56f
child 136 62bb7c97884c
equal deleted inserted replaced
103:2717213c588a 187:9f66f99ee56f
       
     1 // Copyright (c) 2009-2010 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 /**
       
    17  @file
       
    18  @test
       
    19  @internalComponent - Internal Symbian test code 
       
    20 */
       
    21 
       
    22 #include <graphics/fbsglyphdataiterator.h>
       
    23 #include <graphics/fbsglyphmetricsarray.h>
       
    24 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
       
    25 #include <sgresource/sgimage.h>
       
    26 #include <egl/egl.h>
       
    27 #include <vg/openvg.h>
       
    28 typedef EGLBoolean (*TvgCreateEGLImageTargetKHRTypefPtr) (VGeglImageKHR image);
       
    29 #endif
       
    30 #include "tfbsglyphdata.h"
       
    31 
       
    32 // When defined Hindi language tests are not run. 
       
    33 #define UIBENCH_NO_HINDI
       
    34 
       
    35 // Size of EGLSurface used for rendering to, in pixels.
       
    36 const TSize KEglTargetSize(512, 512);
       
    37 
       
    38 CTFbsGlyphData::CTFbsGlyphData()
       
    39 	{
       
    40 	SetTestStepName(KTFbsGlyphData);
       
    41 	}
       
    42 
       
    43 CTFbsGlyphData::~CTFbsGlyphData()
       
    44 	{
       
    45 	}
       
    46 
       
    47 TVerdict CTFbsGlyphData::doTestStepPreambleL()
       
    48     {
       
    49 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
       
    50     User::LeaveIfError(iFbs.Connect());
       
    51 	User::LeaveIfError(iSgDriver.Open());
       
    52 #endif
       
    53     return CTe_graphicsperformanceSuiteStepBase::doTestStepPreambleL();
       
    54     }
       
    55 
       
    56 TVerdict CTFbsGlyphData::doTestStepPostambleL()
       
    57     {
       
    58 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
       
    59     iSgDriver.Close();
       
    60     iFbs.Disconnect();
       
    61 #endif
       
    62     return CTe_graphicsperformanceSuiteStepBase::doTestStepPostambleL();
       
    63     }
       
    64 
       
    65 TVerdict CTFbsGlyphData::doTestStepL()
       
    66 	{
       
    67 #ifndef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
       
    68     INFO_PRINTF1(_L("CTFbsGlyphData can only be run with SgImage 'Lite'"));
       
    69     return TestStepResult();
       
    70 #else
       
    71 	SetTestStepID(_L("GRAPHICS-UI-BENCH-0178"));
       
    72 	GlyphMetricsArrayL(ETestLanguageLatin, ETrue, 1000);
       
    73 	RecordTestResultL();
       
    74 
       
    75 	SetTestStepID(_L("GRAPHICS-UI-BENCH-0179"));
       
    76 	GlyphMetricsArrayL(ETestLanguageLatin, EFalse, 50000);
       
    77 	RecordTestResultL();
       
    78 	
       
    79 #ifndef UIBENCH_NO_HINDI
       
    80     // Tests 180 and 181 require a CMap table in order to convert CharacterCodes to GlyphCodes.
       
    81 	SetTestStepID(_L("GRAPHICS-UI-BENCH-0180"));
       
    82 	GlyphMetricsArrayL(ETestLanguageHindi, ETrue, 25);
       
    83 	RecordTestResultL();
       
    84 	
       
    85 	SetTestStepID(_L("GRAPHICS-UI-BENCH-0181"));
       
    86 	GlyphMetricsArrayL(ETestLanguageHindi, EFalse, 50000);
       
    87 	RecordTestResultL();
       
    88 #endif
       
    89 	
       
    90 	SetTestStepID(_L("GRAPHICS-UI-BENCH-0182"));
       
    91 	GlyphMetricsQuerySingleGlyphL();
       
    92 	RecordTestResultL();
       
    93 	
       
    94 	SetTestStepID(_L("GRAPHICS-UI-BENCH-0183"));
       
    95 	GlyphDataIteratorOpenL(ETestLanguageLatin, ETrue, 50);
       
    96 	RecordTestResultL();
       
    97 
       
    98 	SetTestStepID(_L("GRAPHICS-UI-BENCH-0184"));
       
    99 	GlyphDataIteratorOpenL(ETestLanguageLatin, EFalse, 500);
       
   100 	RecordTestResultL();
       
   101 	
       
   102 #ifndef UIBENCH_NO_HINDI
       
   103     // Tests 185 and 186 require a CMap table in order to convert CharacterCodes to GlyphCodes.
       
   104 	SetTestStepID(_L("GRAPHICS-UI-BENCH-0185"));
       
   105 	GlyphDataIteratorOpenL(ETestLanguageHindi, ETrue, 10);
       
   106 	RecordTestResultL();
       
   107 	
       
   108 	SetTestStepID(_L("GRAPHICS-UI-BENCH-0186"));
       
   109 	GlyphDataIteratorOpenL(ETestLanguageHindi, EFalse, 5000);
       
   110 	RecordTestResultL();
       
   111 #endif	
       
   112 	
       
   113 	SetTestStepID(_L("GRAPHICS-UI-BENCH-0187"));
       
   114 	GlyphDataIteratorOpenSingleFontL();
       
   115 	RecordTestResultL();
       
   116 	
       
   117 	SetTestStepID(_L("GRAPHICS-UI-BENCH-0188"));
       
   118 	GlyphMetricsQueryUnrasterizedL();
       
   119 	RecordTestResultL();
       
   120 	
       
   121 	SetTestStepID(_L("GRAPHICS-UI-BENCH-0189"));
       
   122 	GlyphMetricsQueryPreRasterizedL();
       
   123 	RecordTestResultL();
       
   124 	
       
   125 	SetTestStepID(_L("GRAPHICS-UI-BENCH-0190"));
       
   126 	GlyphRenderingL();
       
   127 	RecordTestResultL();
       
   128 
       
   129 	return TestStepResult();
       
   130 #endif
       
   131     }
       
   132 
       
   133 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
       
   134 /**
       
   135 @SYMTestCaseID GRAPHICS-UI-BENCH-0178...0181
       
   136 
       
   137 @SYMTestType UT
       
   138 
       
   139 @SYMPREQ PREQ2678
       
   140 
       
   141 @SYMTestCaseDesc 
       
   142 Measures the performance of calling RFbsGlyphMetricsArray::Get() with different sample data.
       
   143 The sample data can be a single word, or a very long array of glyphs, in latin or non-latin
       
   144 alphabets. At each repetition a different font is used, cycled over nine fonts, to reduce the
       
   145 effect of having cached glyphs.
       
   146 
       
   147 @SYMTestActions
       
   148 i. Create some sample fonts to cycle through. 
       
   149 ii. Load sample data from config file, specified by aSampleDataKey.
       
   150 iii. Create RFbsGlyphMetricsArray, open on sample data.
       
   151 iv. For each repetition, call RFbsGlyphMetricsArray::Get(), adjusting font at each repetition.
       
   152 v. Measure time from from first to last repetition.
       
   153 
       
   154 @param aLanguage The language this test will use.
       
   155 @param aLongData If ETrue, tells the test to use the long sample data string for the test, EFalse
       
   156 	will make the test use the short string data.
       
   157 @param aReps The number of times to repeat the test.
       
   158 */
       
   159 void CTFbsGlyphData::GlyphMetricsArrayL(TTestLanguage aLanguage, TBool aLongData, TInt aReps)
       
   160 	{
       
   161 	TBuf<128> KTestName;
       
   162 	TPtrC KTestVariant = ConfigKeyNameL(aLanguage, aLongData);
       
   163 	KTestName.Format(_L("GlyphMetricsArray %S"), &KTestVariant);
       
   164 	
       
   165 	// Create some test fonts using the font factory.
       
   166 	CTFontFactory* fontFactory = CTFontFactory::NewLC();
       
   167 	fontFactory->CreateFontsL(aLanguage, 9);
       
   168 
       
   169 	// Load the sample string data from the config file.
       
   170 	TInt numGlyphCodes = 0;
       
   171 	TUint* glyphCodes;
       
   172 	LoadConfigSampleDataL(aLanguage, aLongData, glyphCodes, numGlyphCodes);
       
   173 
       
   174 	// Run the test.
       
   175 	TInt err = KErrNone;
       
   176 	RFbsGlyphMetricsArray array;
       
   177 	CleanupClosePushL(array);
       
   178 	iProfiler->InitResults();
       
   179 	for (TInt rep = aReps; (rep != 0) && (err == KErrNone); --rep)
       
   180 		{
       
   181 		err = array.Get(*(fontFactory->NextFont()), glyphCodes, numGlyphCodes);
       
   182 		}
       
   183 	iProfiler->MarkResultSetL();
       
   184 	TESTE(err == KErrNone, err);
       
   185 	iProfiler->ResultsAnalysisGlyphRate(KTestName, 0, 0, 0, aReps, numGlyphCodes);
       
   186 	
       
   187 	CleanupStack::PopAndDestroy(2); // array, fontFactory
       
   188 	delete [] glyphCodes;
       
   189 	}
       
   190 
       
   191 /**
       
   192 @SYMTestCaseID GRAPHICS-UI-BENCH-0182
       
   193 
       
   194 @SYMTestType UT
       
   195 
       
   196 @SYMPREQ PREQ2678
       
   197 
       
   198 @SYMTestCaseDesc 
       
   199 Measures the performance of calling RFbsGlyphDataIterator::Get() with a single glyph,
       
   200 versus CFont::GetCharacterData(). Using a single glyph code is a very common use case.
       
   201 The glyph and the font is changed at each iteration.
       
   202 
       
   203 @SYMTestActions
       
   204 i. Create some sample fonts to cycle through. 
       
   205 ii. Create RFbsGlyphMetricsArray.
       
   206 iii. For each repetition, call RFbsGlyphMetricsArray::Get(), adjusting the glyph at 
       
   207 	each iteration.
       
   208 iv. Measure time from from first to last iteration.
       
   209 v. Repeat steps iii. and iv. with CFont::GetCharacterData().
       
   210 */
       
   211 void CTFbsGlyphData::GlyphMetricsQuerySingleGlyphL()
       
   212 	{
       
   213 	_LIT(KTestName, "GlyphMetricsQuerySingleGlyph");
       
   214 	const TInt KNumIterations = 50000;
       
   215 	TInt err = KErrNone;
       
   216 	TBuf<128> KTestNameVariant;
       
   217 
       
   218 	// Create some test fonts using the font factory.
       
   219 	CTFontFactory* fontFactory = CTFontFactory::NewLC();
       
   220 	
       
   221 	// Run the test for RFbsGlyphMetricsArray, with a different character 
       
   222 	// and font for each iteration.
       
   223 	KTestNameVariant.Format(_L("%S RFbsGlyphMetricsArray"), &KTestName);
       
   224 	fontFactory->CreateFontsL(ETestLanguageLatin, 9);
       
   225 	RFbsGlyphMetricsArray array;
       
   226 	CleanupClosePushL(array);
       
   227 	iProfiler->InitResults();
       
   228 	for (TInt rep = KNumIterations; rep != 0 && (err == KErrNone); --rep)
       
   229 		{
       
   230 		const TUint KGlyphCode = 32 + (rep % 96);
       
   231 		err = array.Get(*(fontFactory->NextFont()), &KGlyphCode, 1);
       
   232 		}
       
   233 	iProfiler->MarkResultSetL();
       
   234 	TESTE(err == KErrNone, err);
       
   235 	CleanupStack::PopAndDestroy(1); // array
       
   236 	iProfiler->ResultsAnalysisGlyphRate(KTestNameVariant, 0, 0, 0, KNumIterations, 1);
       
   237 	fontFactory->ReleaseFonts();
       
   238 	
       
   239 	// Run the test for GetCharacterData(), with a different character
       
   240 	// and font for each iteration.
       
   241 	KTestNameVariant.Format(_L("%S GetCharacterData"), &KTestName);
       
   242 	fontFactory->CreateFontsL(ETestLanguageLatin, 9);
       
   243 	TOpenFontCharMetrics metrics;
       
   244 	const TUint8* bitmapData = NULL;
       
   245 	TSize bitmapSize;
       
   246 	iProfiler->InitResults();
       
   247 	for (TInt rep = KNumIterations; rep != 0; --rep)
       
   248 		{
       
   249 		const TUint KGlyphCode = 32 + (rep % 96);
       
   250 		fontFactory->NextFont()->GetCharacterData(KGlyphCode, metrics, bitmapData, bitmapSize);
       
   251 		}
       
   252 	iProfiler->MarkResultSetL();
       
   253 	iProfiler->ResultsAnalysisGlyphRate(KTestNameVariant, 0, 0, 0, KNumIterations, 1);
       
   254 	
       
   255 	CleanupStack::PopAndDestroy(1); // fontFactory
       
   256 	}
       
   257 
       
   258 /**
       
   259 @SYMTestCaseID GRAPHICS-UI-BENCH-0183...0186
       
   260 
       
   261 @SYMTestType UT
       
   262 
       
   263 @SYMPREQ PREQ2678
       
   264 
       
   265 @SYMTestCaseDesc 
       
   266 Measures the performance of calling RFbsGlyphDataIterator::Open() with different 
       
   267 sample data, and iterating through the data with RFbsGlyphDataIterator::Next(). 
       
   268 The sample data can be a single word, or a very long array of glyphs,
       
   269 in various languages. At each repetition a different font is used, cycled
       
   270 over nine fonts.
       
   271 
       
   272 @SYMTestActions
       
   273 i. Create some sample fonts to cycle through. 
       
   274 ii. Create RFbsGlyphDataIterator.
       
   275 iii. For each repetition, call RFbsGlyphDataIterator::Open(), adjusting the glyph at each 
       
   276 	iteration. The font is changed at each repetition.
       
   277 iv. Measure time from from first to last repetition.
       
   278 
       
   279 @param aLanguage The language this test will use.
       
   280 @param aLongData If ETrue, tells the test to use the long sample data string for the test, EFalse
       
   281 	will make the test use the short string data.
       
   282 @param aReps The number of times to repeat the test.
       
   283  */
       
   284 void CTFbsGlyphData::GlyphDataIteratorOpenL(TTestLanguage aLanguage, TBool aLongData, TInt aReps)
       
   285 	{
       
   286 	TBuf<128> KTestName;
       
   287 	TPtrC KTestVariant = ConfigKeyNameL(aLanguage, aLongData);
       
   288 	KTestName.Format(_L("GlyphDataIteratorOpen %S"), &KTestVariant);
       
   289 	
       
   290 	// Create some test fonts using the font factory.
       
   291 	CTFontFactory* fontFactory = CTFontFactory::NewLC();
       
   292 	fontFactory->CreateFontsL(aLanguage, 9);
       
   293 	
       
   294 	// Load the sample string data from the config file.
       
   295 	TInt numGlyphCodes = 0;
       
   296 	TUint* glyphCodes;
       
   297 	LoadConfigSampleDataL(aLanguage, aLongData, glyphCodes, numGlyphCodes);
       
   298 
       
   299 	// Run the test.
       
   300 	TInt err = KErrNotFound;
       
   301 	RFbsGlyphDataIterator iter;
       
   302 	CleanupClosePushL(iter);
       
   303 	iProfiler->InitResults();
       
   304 	for (TInt rep = aReps; (rep != 0) && (err == KErrNotFound); --rep)
       
   305 		{
       
   306 		err = iter.Open(*(fontFactory->NextFont()), glyphCodes, numGlyphCodes);
       
   307 		for (; err == KErrNone; err = iter.Next())
       
   308 			{
       
   309 			// no operation
       
   310 			}
       
   311 		iter.Close();
       
   312 		}
       
   313 	iProfiler->MarkResultSetL();
       
   314 	TESTE(err == KErrNotFound, err);
       
   315 
       
   316 	CleanupStack::PopAndDestroy(2); // iter, fontFactory
       
   317 	iProfiler->ResultsAnalysisGlyphRate(KTestName, 0, 0, 0, aReps, numGlyphCodes);
       
   318 	delete [] glyphCodes;
       
   319 	}
       
   320 
       
   321 /**
       
   322 @SYMTestCaseID GRAPHICS-UI-BENCH-0187
       
   323 
       
   324 @SYMTestType UT
       
   325 
       
   326 @SYMPREQ PREQ2678
       
   327 
       
   328 @SYMTestCaseDesc 
       
   329 Measures the performance of calling RFbsGlyphDataIterator::Open() with different 
       
   330 lengthed arrays but the same font. The sample data is a long array of characters.
       
   331 
       
   332 @SYMTestActions
       
   333 i. Create a single test font 
       
   334 ii. Create RFbsGlyphDataIterator.
       
   335 iii. Pass an array to RFbsGlyphDataIterator::Open(), starting with a single glyph.
       
   336 	For each iteration, increase the length of the array by one until the entire
       
   337 	string has been opened.
       
   338 iv. Measure the time to perform all the iterations.
       
   339 
       
   340 @param aSampleDataKey The string key to lookup under the GlyphArraySampleText section of the 
       
   341 	config file where the sample data is read.
       
   342 @param aReps The number of times to repeat the test.
       
   343  */
       
   344 void CTFbsGlyphData::GlyphDataIteratorOpenSingleFontL()
       
   345 	{
       
   346 	_LIT(KTestName, "GlyphDataIteratorOpenSingleFont");
       
   347 	// A cap on the max number of iterations to complete.
       
   348 	const TInt KMaxNumIterations = 200;
       
   349 #ifndef UIBENCH_NO_HINDI
       
   350     const TTestLanguage KTestLanguage = ETestLanguageHindi;
       
   351 #else
       
   352     const TTestLanguage KTestLanguage = ETestLanguageLatin;
       
   353 #endif
       
   354 	
       
   355 	// Create some test fonts using the font factory.
       
   356 	CTFontFactory* fontFactory = CTFontFactory::NewLC();
       
   357 	fontFactory->CreateFontsL(KTestLanguage, 1);
       
   358 	CFbsFont* font = fontFactory->NextFont();
       
   359 	
       
   360 	// Load the sample string data from the config file.
       
   361 	TInt numGlyphCodes = 0;
       
   362 	TUint* glyphCodes;
       
   363 	LoadConfigSampleDataL(KTestLanguage, ETrue, glyphCodes, numGlyphCodes); 
       
   364 	
       
   365 	const TInt KNumRepetitions = Min<TInt>(numGlyphCodes - 1, KMaxNumIterations);
       
   366 	RFbsGlyphDataIterator iter;
       
   367 	CleanupClosePushL(iter);
       
   368 	TInt iterErr = KErrNone;
       
   369 	TInt glyphCount = 0;
       
   370 	iProfiler->InitResults();
       
   371 	for (glyphCount = 1; (glyphCount < KNumRepetitions); ++glyphCount)
       
   372 		{
       
   373 		iterErr = iter.Open(*font, glyphCodes, glyphCount);
       
   374 		for (; iterErr == KErrNone; iterErr = iter.Next())
       
   375 			{
       
   376 			// no operation
       
   377 			}
       
   378 		iter.Close();
       
   379 		}
       
   380 	iProfiler->MarkResultSetL();
       
   381 	TEST(glyphCount == KNumRepetitions);
       
   382 	TESTE(iterErr == KErrNotFound, iterErr);
       
   383 	
       
   384 	const TInt KAvgNumCharsPerIteration = KNumRepetitions/2;
       
   385 	iProfiler->ResultsAnalysisGlyphRate(KTestName, 0, 0, 0, KNumRepetitions, KAvgNumCharsPerIteration);
       
   386 	
       
   387 	CleanupStack::PopAndDestroy(2); // iter, fontFactory
       
   388 	delete [] glyphCodes;
       
   389 	}
       
   390 /**
       
   391 @SYMTestCaseID GRAPHICS-UI-BENCH-0188
       
   392 
       
   393 @SYMTestType UT
       
   394 
       
   395 @SYMPREQ PREQ2678
       
   396 
       
   397 @SYMTestCaseDesc 
       
   398 Measures the performance of querying the TOpenFontCharMetrics using the different
       
   399 available APIs. RFbsGlyphMetricsArray, RFbsGlyphDataIterator, and CFont::GetCharacterData()
       
   400 are compared against each other, using the same fonts, and same sample data.
       
   401 This test uses glyphs that have not been rasterized before, therefore for certain
       
   402 APIs this will mean rasterizing the glyphs.
       
   403 
       
   404 @SYMTestActions
       
   405 i. Load sample text data from config file.
       
   406 ii. For each of RFbsGlyphMetricsArray, RFbsGlyphDataIterator, and CFont::GetCharacterData():
       
   407 	1. Create 50 new fonts.
       
   408 	2. Run the test, calling the necessary API once per font/loop.
       
   409 	3. For GetCharacterData() and RFbsGlyphDataIterator(), cycle through each glyph
       
   410 		to ensure all metrics have been retrieved. This is not necessary for 
       
   411 		RFbsGlyphMetricsArray.
       
   412 	4. Measure time between first and last font/loop.
       
   413 	5. Destroy test fonts so that next test has to re-rasterize the glyphs.	
       
   414 
       
   415 @SYMTestExpectedResults
       
   416 Since this test uses non-rasterized fonts, RFbsGlyphMetricsArray should be faster than
       
   417 GetCharacterData() and RFbsGlyphDataIterator, which both rasterize the glyphs in order to 
       
   418 get their metrics information.
       
   419  */
       
   420 void CTFbsGlyphData::GlyphMetricsQueryUnrasterizedL()
       
   421 	{
       
   422 	_LIT(KTestName, "GlyphMetricsQueryUnrasterized");
       
   423 	TBuf<128> KTestNameVariant;
       
   424 	const TInt KNumFonts = 50;
       
   425 	const TTestLanguage KTestLanguage = ETestLanguageLatin;
       
   426 	
       
   427 	// Load the sample string data from the config file. Both the iterator and the
       
   428 	// array will use this same sample data.
       
   429 	TInt numGlyphCodes = 0;
       
   430 	TUint* glyphCodes;
       
   431 	LoadConfigSampleDataL(KTestLanguage, ETrue, glyphCodes, numGlyphCodes); 
       
   432 	
       
   433 	// Create some test fonts using the font factory.
       
   434 	CTFontFactory* fontFactory = CTFontFactory::NewLC();
       
   435 	
       
   436 	// First do the test for the iterator. To ensure fair comparison with
       
   437 	// RFbsGlyphMetricsArray, cycle through each iteration to ensure the metrics
       
   438 	// for each glyph is found.
       
   439 	KTestNameVariant.Format(_L("%S RFbsGlyphDataIterator"), &KTestName);
       
   440 	fontFactory->CreateFontsL(KTestLanguage, KNumFonts);
       
   441 	RFbsGlyphDataIterator iter;
       
   442 	CleanupClosePushL(iter);
       
   443 	TInt iterErr = KErrNone;
       
   444 	TInt rep = 0;
       
   445 	iProfiler->InitResults();
       
   446 	for (rep = KNumFonts; (rep != 0); --rep)
       
   447 		{
       
   448 		iterErr = iter.Open(*(fontFactory->NextFont()), glyphCodes, numGlyphCodes);
       
   449 		for (; iterErr == KErrNone; iterErr = iter.Next())
       
   450 			{
       
   451 			// no operation
       
   452 			}
       
   453 		iter.Close();
       
   454 		}
       
   455 	iProfiler->MarkResultSetL();
       
   456 	TEST(rep == 0);
       
   457 	TESTE(iterErr == KErrNotFound, iterErr);
       
   458 	CleanupStack::PopAndDestroy(1); // iter		
       
   459 	iProfiler->ResultsAnalysisGlyphRate(KTestNameVariant, 0, 0, 0, KNumFonts, numGlyphCodes);
       
   460 	
       
   461 	// Second, do the test for the array. This should be faster.
       
   462 	// Destroy the fonts and re-create them so that they have to be re-rasterized
       
   463 	// for a fair comparison.
       
   464 	TInt arrayErr = KErrNone;
       
   465 	KTestNameVariant.Format(_L("%S RFbsGlyphMetricsArray"), &KTestName);
       
   466 	fontFactory->ReleaseFonts();
       
   467 	fontFactory->CreateFontsL(KTestLanguage, KNumFonts);
       
   468 	RFbsGlyphMetricsArray array;
       
   469 	CleanupClosePushL(array);
       
   470 	iProfiler->InitResults();	
       
   471 	for (TInt rep = KNumFonts; (rep != 0) && (arrayErr == KErrNone); --rep)
       
   472 		{
       
   473 		arrayErr = array.Get(*(fontFactory->NextFont()), glyphCodes, numGlyphCodes);
       
   474 		}
       
   475 	iProfiler->MarkResultSetL();
       
   476 	CleanupStack::PopAndDestroy(1); // array
       
   477 	TEST(rep == 0);
       
   478 	TESTE(arrayErr == KErrNone, arrayErr);
       
   479 	iProfiler->ResultsAnalysisGlyphRate(KTestNameVariant, 0, 0, 0, KNumFonts, numGlyphCodes);
       
   480 	
       
   481 	// Third, do the test using GetCharacterData() to get the metrics.
       
   482 	// Destroy the fonts and re-create them so that they have to be re-rasterized
       
   483 	// for a fair comparison.
       
   484 	KTestNameVariant.Format(_L("%S GetCharacterData"), &KTestName);
       
   485 	fontFactory->ReleaseFonts();
       
   486 	fontFactory->CreateFontsL(KTestLanguage, KNumFonts);	
       
   487 	iProfiler->InitResults();
       
   488 	const TUint8* bitmapData = NULL;
       
   489 	TSize bitmapSize;
       
   490 	TOpenFontCharMetrics metrics;	
       
   491 	for (TInt rep = KNumFonts; (rep != 0); --rep)
       
   492 		{
       
   493 		CFbsFont* font = fontFactory->NextFont(); 
       
   494 		for (TInt glyphIndex = 0; glyphIndex < numGlyphCodes; glyphIndex++)
       
   495 			{
       
   496 			font->GetCharacterData(glyphCodes[glyphIndex], metrics, bitmapData, bitmapSize);
       
   497 			}
       
   498 		}
       
   499 	iProfiler->MarkResultSetL();
       
   500 	iProfiler->ResultsAnalysisGlyphRate(KTestNameVariant, 0, 0, 0, KNumFonts, numGlyphCodes);
       
   501 	
       
   502 	CleanupStack::PopAndDestroy(1); // fontFactory
       
   503 	delete [] glyphCodes;
       
   504 	}
       
   505 
       
   506 /**
       
   507 @SYMTestCaseID GRAPHICS-UI-BENCH-0189
       
   508 
       
   509 @SYMTestType UT
       
   510 
       
   511 @SYMPREQ PREQ2678
       
   512 
       
   513 @SYMTestCaseDesc 
       
   514 Measures the performance of querying the TOpenFontCharMetrics using the different
       
   515 available APIs. RFbsGlyphMetricsArray, RFbsGlyphDataIterator, and CFont::GetCharacterData()
       
   516 are compared against each other, using the same fonts, and same sample data.
       
   517 This test uses glyphs that have already been rasterized, thereby possibly reducing the 
       
   518 extra overhead this has.
       
   519 
       
   520 @SYMTestActions
       
   521 i. Load sample text data from config file.
       
   522 ii. Create test font.
       
   523 iii. Pre-rasterize glyphs using RFbsGlyphDataIterator. This will rasterize the glyphs 
       
   524 	and cause them to be cached for use by all the APIs tested here.
       
   525 iv. For each of RFbsGlyphMetricsArray, RFbsGlyphDataIterator, and CFont::GetCharacterData():
       
   526 	1. Begin the loop, calling the necessary API once per font/loop.
       
   527 	2. For each glyph, request the glyph metrics.
       
   528 	3. Measure time between first and last font/loop.
       
   529 v. Destroy test font.
       
   530 
       
   531 @SYMTestExpectedResults
       
   532 All results should be improved over GlyphMetricsQueryUnrasterized (GRAPHICS-UI-BENCH-0187).
       
   533 since no rasterizing should take place during these tests.
       
   534  */
       
   535 void CTFbsGlyphData::GlyphMetricsQueryPreRasterizedL()
       
   536 	{
       
   537 	_LIT(KTestName, "GlyphMetricsQueryPreRasterized");
       
   538 	TBuf<128> KTestNameVariant;
       
   539 	const TInt KNumIterations = 500;
       
   540 	const TTestLanguage KTestLanguage = ETestLanguageLatin;
       
   541 		
       
   542 	TInt numGlyphCodes = 0;
       
   543 	TUint* glyphCodes;
       
   544 	LoadConfigSampleDataL(KTestLanguage, ETrue, glyphCodes, numGlyphCodes); 
       
   545 	
       
   546 	// Create a test font using the font factory.
       
   547 	CTFontFactory* fontFactory = CTFontFactory::NewLC();
       
   548 	fontFactory->CreateFontsL(ETestLanguageLatin, 1);	
       
   549 	CFbsFont* font = fontFactory->NextFont();
       
   550 	
       
   551 	TInt iterErr = KErrNone;
       
   552 	TInt rep = 0;
       
   553 	// Rasterize the glyphs first.
       
   554 	RFbsGlyphDataIterator iter;
       
   555 	CleanupClosePushL(iter);
       
   556 	for (rep = KNumIterations; (rep != 0) ; --rep)
       
   557 		{
       
   558 		iterErr = iter.Open(*font, glyphCodes, numGlyphCodes);
       
   559 		for (; iterErr == KErrNone; iterErr = iter.Next())
       
   560 			{
       
   561 			// no operation
       
   562 			}
       
   563 		iter.Close();
       
   564 		}
       
   565 	TEST(rep == 0);
       
   566 	TESTE(iterErr == KErrNotFound, iterErr);
       
   567 	
       
   568 	TOpenFontCharMetrics metrics;
       
   569 		
       
   570 	// First do the test for the iterator. To ensure fair comparison with
       
   571 	// RFbsGlyphMetricsArray, cycle through each iteration to ensure the metrics
       
   572 	// for each glyph is found.
       
   573 	iterErr = KErrNone;
       
   574 	KTestNameVariant.Format(_L("%S RFbsGlyphDataIterator"), &KTestName);
       
   575 	iProfiler->InitResults();
       
   576 	for (TInt rep = KNumIterations; (rep != 0); --rep)
       
   577 		{
       
   578 		for (iterErr = iter.Open(*font, glyphCodes, numGlyphCodes); iterErr == KErrNone; iterErr = iter.Next())
       
   579 			{
       
   580 			metrics = iter.Metrics();
       
   581 			}
       
   582 		iter.Close();
       
   583 		}
       
   584 	iProfiler->MarkResultSetL();
       
   585 	TESTE(iterErr == KErrNotFound, iterErr);
       
   586 	CleanupStack::PopAndDestroy(1); // iter
       
   587 	iProfiler->ResultsAnalysisGlyphRate(KTestNameVariant, 0, 0, 0, KNumIterations, numGlyphCodes);
       
   588 	
       
   589 	
       
   590 	// Second, do the test for the array. This should be faster.
       
   591 	TInt arrayErr = KErrNone;
       
   592 	KTestNameVariant.Format(_L("%S RFbsGlyphMetricsArray"), &KTestName);
       
   593 	RFbsGlyphMetricsArray array;
       
   594 	CleanupClosePushL(array);
       
   595 	iProfiler->InitResults();
       
   596 	for (TInt rep = KNumIterations; (rep != 0) && (arrayErr == KErrNone); --rep)
       
   597 		{
       
   598 		arrayErr = array.Get(*font, glyphCodes, numGlyphCodes);
       
   599 		for (TInt i = 0; i < numGlyphCodes; ++i)
       
   600 			{
       
   601 			metrics = array[i];
       
   602 			}
       
   603 		}
       
   604 	iProfiler->MarkResultSetL();
       
   605 	TESTE(arrayErr == KErrNone, arrayErr);
       
   606 	CleanupStack::PopAndDestroy(1); // array
       
   607 	iProfiler->ResultsAnalysisGlyphRate(KTestNameVariant, 0, 0, 0, KNumIterations, numGlyphCodes);
       
   608 	
       
   609 	
       
   610 	// Third, do the test using GetCharacterData() to get the metrics.
       
   611 	KTestNameVariant.Format(_L("%S GetCharacterData"), &KTestName);
       
   612 	const TUint8* bitmapData;
       
   613 	TSize bitmapSize;
       
   614 
       
   615 	iProfiler->InitResults();
       
   616 	for (TInt rep = KNumIterations; (rep != 0); --rep)
       
   617 		{
       
   618 		for (TInt glyphIndex = 0; glyphIndex < numGlyphCodes; glyphIndex++)
       
   619 			{
       
   620 			font->GetCharacterData(glyphCodes[glyphIndex], metrics, bitmapData, bitmapSize);
       
   621 			}
       
   622 		}
       
   623 	iProfiler->MarkResultSetL();
       
   624 	iProfiler->ResultsAnalysisGlyphRate(KTestNameVariant, 0, 0, 0, KNumIterations, numGlyphCodes);
       
   625 	
       
   626 	CleanupStack::PopAndDestroy(1); // fontFactory
       
   627 	delete [] glyphCodes;
       
   628 	}
       
   629 
       
   630 /**
       
   631 @SYMTestCaseID GRAPHICS-UI-BENCH-0190
       
   632 
       
   633 @SYMTestType UT
       
   634 
       
   635 @SYMPREQ PREQ2678
       
   636 
       
   637 @SYMTestCaseDesc 
       
   638 Measures the end-to-end performance of using Khronos APIs to render glyphs using the
       
   639 RFbsGlyphDataIterator API. Positioning is very basic and is not reflective of a production-
       
   640 quality text-rendering algorithm, but serves as a useful benchmark of the overall
       
   641 text-rendering performance using this API.
       
   642 
       
   643 @SYMTestActions
       
   644 i. Create a sample font to use. 
       
   645 ii. Create a RSgImage to be used as a target for Khronos API rendering.
       
   646 iii. Set-up EGL and OpenVG.
       
   647 iv. Construct RFbsGlyphDataIterator, and open on sample data. At each iteration:
       
   648 	1. Create an EGLImage from the RSgImage.
       
   649 	2. Create a VGImage from the EGLImage.
       
   650 	3. Render the VGImage using vgDrawImage().
       
   651 	4. Destroy VGImage.
       
   652 	5. Destroy EGLImage.
       
   653 	6. Advance the current rendering position for the next glyph, ensuring that every glyph
       
   654 	will be within the bounds of the target surface.
       
   655 v. Measure time from from first to last iteration.
       
   656 */
       
   657 void CTFbsGlyphData::GlyphRenderingL()
       
   658 	{
       
   659 	_LIT(KTestName, "GlyphRendering");
       
   660 	const TInt KNumIterations = 500;
       
   661 #ifndef UIBENCH_NO_HINDI
       
   662     const TTestLanguage KTestLanguage = ETestLanguageHindi;
       
   663 #else
       
   664     const TTestLanguage KTestLanguage = ETestLanguageLatin;
       
   665 #endif
       
   666 	
       
   667 	// Create some test fonts using the font factory.
       
   668 	CTFontFactory* fontFactory = CTFontFactory::NewLC();
       
   669 	fontFactory->CreateFontsL(KTestLanguage, 1, 20);
       
   670 	CFbsFont* font = fontFactory->NextFont();
       
   671 	const TInt KFontHeightInPixels = font->HeightInPixels();
       
   672 
       
   673 	// Create RSgImage to be used as OpenVG Pixmap Surface
       
   674 
       
   675 	RSgImage target;
       
   676 	TInt err = target.Create(TSgImageInfo(KEglTargetSize, ESgPixelFormatARGB_8888_PRE, ESgUsageBitOpenVgSurface));
       
   677 	TESTL(err == KErrNone);
       
   678 	CleanupClosePushL(target);
       
   679 	
       
   680 	// Initialize EGL/OpenVG for rendering.
       
   681 	EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
       
   682 	if (display == EGL_NO_DISPLAY)
       
   683 		{
       
   684 		ERR_PRINTF2(_L("Failed to get EGLDisplay. [eglError=%X]"), eglGetError());
       
   685 		User::Leave(KErrGeneral);
       
   686 		}
       
   687 	TESTL(display != EGL_NO_DISPLAY);
       
   688 	if (EGL_FALSE == eglInitialize(display, NULL, NULL))
       
   689 		{
       
   690 		ERR_PRINTF2(_L("Failed to initialize EGLDisplay. [eglError=%X]"), eglGetError());
       
   691 		User::Leave(KErrGeneral);
       
   692 		}
       
   693 	eglBindAPI(EGL_OPENVG_API);
       
   694 	
       
   695 	EGLint imageAttribs[] =
       
   696 	    {
       
   697 	    EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, 
       
   698 	    EGL_NONE
       
   699 	    };
       
   700 	EGLint configAttribs[] = 
       
   701 		{
       
   702 		EGL_MATCH_NATIVE_PIXMAP, (EGLint)&target,
       
   703 		EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
       
   704 		EGL_SURFACE_TYPE, EGL_PIXMAP_BIT | EGL_VG_ALPHA_FORMAT_PRE_BIT, 
       
   705 		EGL_NONE
       
   706 		};
       
   707 	
       
   708 	const EGLint KPixmapAttribsVgAlphaFormatPre[] = 
       
   709 	    {
       
   710 	    EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_PRE,
       
   711 	    EGL_NONE
       
   712 	    };
       
   713 		
       
   714 	EGLint configId = 0;
       
   715 	EGLint numConfigs = 0;
       
   716 	if (EGL_FALSE == eglChooseConfig(display, configAttribs, &configId, 1, &numConfigs) || numConfigs == 0)
       
   717 		{
       
   718 		ERR_PRINTF3(_L("Failed to find suitable EGLConfig. [eglError=%X, configs=%d]"), eglGetError(), numConfigs);
       
   719 		User::Leave(KErrGeneral);
       
   720 		}
       
   721 	EGLContext context = eglCreateContext(display, configId, EGL_NO_CONTEXT, NULL);
       
   722 	if (context == EGL_NO_CONTEXT)
       
   723 		{
       
   724 		ERR_PRINTF2(_L("Failed to create EGLContext. [eglError=%X]"), eglGetError());
       
   725 		User::Leave(KErrGeneral);
       
   726 		}
       
   727 	EGLSurface surface = eglCreatePixmapSurface(display, configId, &target, KPixmapAttribsVgAlphaFormatPre);
       
   728 	if (EGL_FALSE == eglMakeCurrent(display, surface, surface, context))
       
   729 		{
       
   730 		ERR_PRINTF2(_L("Failed to create make surface and context current. [eglError=%X]"), eglGetError());
       
   731 		eglDestroyContext(display, context);
       
   732 		User::Leave(KErrGeneral);
       
   733 		}
       
   734 	
       
   735 	// Load the necessary EGL extensions...
       
   736 	TvgCreateEGLImageTargetKHRTypefPtr vgCreateImageTargetKHR;
       
   737 	PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;
       
   738 	PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR;
       
   739 	eglCreateImageKHR = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR"));
       
   740 	eglDestroyImageKHR = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR"));
       
   741 	vgCreateImageTargetKHR = reinterpret_cast<TvgCreateEGLImageTargetKHRTypefPtr>(eglGetProcAddress("vgCreateEGLImageTargetKHR"));
       
   742 	if (!eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateImageTargetKHR)
       
   743 		{
       
   744 		ERR_PRINTF1(_L("Failed to get EGL Image extension functions."));
       
   745 		User::Leave(KErrNotSupported);
       
   746 		}
       
   747 	// Now we have an OpenVG window to render to!
       
   748 	
       
   749 	TInt numGlyphCodes = 0;
       
   750 	TUint* glyphCodes;
       
   751 	LoadConfigSampleDataL(KTestLanguage, EFalse, glyphCodes, numGlyphCodes); 
       
   752 
       
   753 	// Set up an identity matrix compatible with the Symbian co-ordinate system.
       
   754 	vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
       
   755 	vgScale(1.f, -1.f);
       
   756 	vgTranslate(0, -KFontHeightInPixels);	
       
   757 	VGfloat vgIdentityMatrix[16];
       
   758 	vgGetMatrix(vgIdentityMatrix);
       
   759 	
       
   760 	RFbsGlyphDataIterator iter;
       
   761 	CleanupClosePushL(iter);
       
   762 		
       
   763 	// Render some glyphs.
       
   764 	TInt iterErr = KErrNone;
       
   765 	TInt rep = 0;
       
   766 	vgClear(0, 0, KEglTargetSize.iWidth, KEglTargetSize.iHeight);
       
   767 	TPoint glyphOrigin(0, 0);
       
   768 	iProfiler->InitResults();
       
   769 	for (rep = 0; rep < KNumIterations; rep++)
       
   770 		{
       
   771 		iterErr = iter.Open(*font, glyphCodes, numGlyphCodes);
       
   772 		for (;iterErr == KErrNone; iterErr = iter.Next())
       
   773 			{
       
   774 			const TOpenFontCharMetrics& metrics = iter.Metrics();
       
   775 			const RSgImage& glyphSgImage = iter.Image();
       
   776 			EGLImageKHR eglImage = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, 
       
   777 					reinterpret_cast<EGLClientBuffer>(&glyphSgImage), imageAttribs);
       
   778 			VGImage vgImage = vgCreateImageTargetKHR(eglImage);
       
   779 			
       
   780 			// wrapped text placement.			
       
   781 			TInt horizAdvance = metrics.HorizAdvance();
       
   782 			if (glyphOrigin.iX + horizAdvance >= KEglTargetSize.iWidth)
       
   783 				{
       
   784 				vgLoadMatrix(vgIdentityMatrix);
       
   785 				glyphOrigin.iX = 0;
       
   786 				glyphOrigin.iY -= KFontHeightInPixels;
       
   787 				if (glyphOrigin.iY - KFontHeightInPixels < -KEglTargetSize.iHeight)
       
   788 					{
       
   789 					glyphOrigin.iY = 0;
       
   790 					}
       
   791 				vgTranslate(glyphOrigin.iX, glyphOrigin.iY);
       
   792 				}
       
   793 			
       
   794 			vgDrawImage(vgImage);
       
   795 			vgDestroyImage(vgImage);
       
   796 			eglDestroyImageKHR(display, eglImage);
       
   797 				
       
   798 			// Move to next glyph position.
       
   799 			glyphOrigin.iX += horizAdvance;
       
   800 			vgTranslate(horizAdvance, 0);
       
   801 			}
       
   802 		iter.Close();
       
   803 		eglSwapBuffers(display, surface);
       
   804 		}
       
   805 	iProfiler->MarkResultSetL();
       
   806 	iProfiler->ResultsAnalysisGlyphRate(KTestName, 0, 0, 0, KNumIterations, numGlyphCodes);
       
   807 	TEST(rep == KNumIterations);
       
   808 	TESTE(iterErr == KErrNotFound, iterErr);	
       
   809 	WriteTargetOutput(KTestName());
       
   810 	
       
   811 	eglDestroySurface(display, surface);
       
   812 	eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
       
   813 	eglTerminate(display);
       
   814 	eglReleaseThread();
       
   815 	
       
   816 	CleanupStack::PopAndDestroy(3); // iter, target, fontFactory
       
   817 	delete [] glyphCodes;
       
   818 	}
       
   819 #endif
       
   820 
       
   821 /**
       
   822 Captures the EGL Surface (it is assumed to be an OpenVG surface) to a 256-grey CFbsBitmap,
       
   823 used when sanity-checking bitmaps are enabled. 
       
   824 */
       
   825 CFbsBitmap* CTFbsGlyphData::GetTargetAsBitmapL()
       
   826 	{
       
   827 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
       
   828 	// For debugging purposes only.
       
   829 	// Capture the final state of the EGL Pixmap surface as an mbm.
       
   830 	TSize KTargetSize;
       
   831 	const TSize KBufferSize = KEglTargetSize;
       
   832 	const TInt KDataStride = KEglTargetSize.iWidth;
       
   833 	
       
   834 	TUint8* imageBuffer = reinterpret_cast<TUint8*>(User::AllocZ(KBufferSize.iHeight * KDataStride));
       
   835 	CFbsBitmap* bitmap = new (ELeave) CFbsBitmap();
       
   836 	CleanupStack::PushL(bitmap);
       
   837 	User::LeaveIfError(bitmap->Create(KBufferSize, EGray256));
       
   838 	vgReadPixels(imageBuffer, KDataStride, VG_A_8, 0, 0, KBufferSize.iWidth, KBufferSize.iHeight);
       
   839 	TUint8* buf = imageBuffer;
       
   840 	bitmap->BeginDataAccess();
       
   841 	TUint8* dataAddress = reinterpret_cast<TUint8*>(bitmap->DataAddress());
       
   842 	const TInt dataStride = bitmap->DataStride();	
       
   843 	for (TInt scanline = 0; scanline < KBufferSize.iHeight; scanline++)
       
   844 		{
       
   845 		Mem::Copy(dataAddress, buf, KBufferSize.iWidth);
       
   846 		dataAddress += dataStride;
       
   847 		buf += KBufferSize.iWidth;
       
   848 		}
       
   849 	bitmap->EndDataAccess(EFalse);
       
   850 	User::Free(imageBuffer);
       
   851 	CleanupStack::Pop(1); // bitmap
       
   852 	return bitmap;
       
   853 #else
       
   854 	return NULL;
       
   855 #endif
       
   856 	}
       
   857 
       
   858 /**
       
   859 Utility method. Loads sample glyph code data from the config ini file
       
   860 into a TUint array.
       
   861 @param aKey The key string to look for when loading the sample data from the config file
       
   862 @param aGlyphCodes On success, holds an array of glyph codes, to be freed by the caller.
       
   863 @param aNumGlyphCodes On success, holds the count of the glyph code array.
       
   864 @leave KErrNotFound if the test data cannot be found or is empty in the config file.
       
   865  */
       
   866 void CTFbsGlyphData::LoadConfigSampleDataL(TTestLanguage aLanguage, TBool aLongData, TUint*& aGlyphCodes, TInt& aNumGlyphCodes)
       
   867 	{
       
   868 	// The name of the section in the config file to look-up the sample data
       
   869 	_LIT(KConfigFileSampleData, "GlyphDataSampleText");
       
   870 	
       
   871 	TBuf<32> keyName = ConfigKeyNameL(aLanguage, aLongData);
       
   872 	
       
   873 	// Load the sample string data from the config file.
       
   874 	TPtrC sampleText;
       
   875 	TESTL(GetStringFromConfig(KConfigFileSampleData, keyName, sampleText));
       
   876 	aNumGlyphCodes = sampleText.Length();
       
   877 	if (aNumGlyphCodes <= 0)
       
   878 		{
       
   879 		User::Leave(KErrNotFound);
       
   880 		}
       
   881 	aGlyphCodes = new(ELeave) TUint[aNumGlyphCodes];
       
   882 	for (TInt code = 0; code < aNumGlyphCodes; ++code)
       
   883 		{
       
   884 		aGlyphCodes[code] = sampleText[code]; 
       
   885 		}
       
   886 	}
       
   887 
       
   888 /**
       
   889 Creates the name of the key to look for in the config file for the test
       
   890 with the specified parameters.
       
   891 @param aLanguage The language the test will use.
       
   892 @param aLongData Whether to use long or short sample data.
       
   893 @return A descriptor value of the language.
       
   894 @leave KErrNotSupported if aLanguage is not recognised.
       
   895  */
       
   896 TBufC<32> CTFbsGlyphData::ConfigKeyNameL(TTestLanguage aLanguage, TBool aLongData)
       
   897 	{
       
   898 	if (aLanguage < 0 || aLanguage > 1)
       
   899 		{
       
   900 		User::Leave(KErrNotSupported);
       
   901 		}
       
   902 	TBuf<32> langName[2];
       
   903 	langName[ETestLanguageLatin].Append(_L("Latin"));
       
   904 	langName[ETestLanguageHindi].Append(_L("Hindi"));	
       
   905 	langName[aLanguage].Append((aLongData) ? _L("Long") : _L("Short"));
       
   906 	return langName[aLanguage];
       
   907 	}
       
   908 
       
   909 /**
       
   910 Font factory.
       
   911 Utiltiy class for providing fonts for the performance tests.
       
   912 */
       
   913 
       
   914 CTFontFactory::CTFontFactory()
       
   915 	{
       
   916 	}
       
   917 
       
   918 CTFontFactory::~CTFontFactory()
       
   919 	{
       
   920 	ReleaseFonts();
       
   921 	delete iTs;
       
   922 	}
       
   923 
       
   924 /**
       
   925 @return A new Font Factory ready to create fonts.
       
   926 */
       
   927 CTFontFactory* CTFontFactory::NewLC()
       
   928 	{
       
   929 	CTFontFactory* fontFactory = new (ELeave) CTFontFactory();
       
   930 	CleanupStack::PushL(fontFactory);
       
   931 	fontFactory->iTs = static_cast<CFbsTypefaceStore*>(CFbsTypefaceStore::NewL(NULL));
       
   932 	return fontFactory;
       
   933 	}
       
   934 
       
   935 /**
       
   936 Creates a number of fonts for use by tests. All the fonts are created up-front so 
       
   937 that NextFont() can be called as a very lightweight call, so it can be used inside
       
   938 tests with minimal impact.
       
   939 Once fonts are created, the factory must not be destroyed until the fonts it created
       
   940 are finished with.
       
   941 @param aLanaugeMask Which language needs to be supported by the returned fonts.
       
   942 @param aNumFonts The number of fonts to create
       
   943 @param aStartSizeInPixels The lower bound font height of the fonts that are created. All
       
   944 	fonts will be at least as big as this value.
       
   945 */
       
   946 void CTFontFactory::CreateFontsL(TTestLanguage aLanguageMask, TInt aNumFonts, TInt aStartSizeInPixels)
       
   947 	{
       
   948 	ReleaseFonts();
       
   949 	
       
   950 	RArray <TPtrC> typefaceNames;
       
   951 	CleanupClosePushL(typefaceNames);
       
   952 	switch(aLanguageMask)
       
   953 		{
       
   954 		case ETestLanguageHindi:	
       
   955 			User::LeaveIfError(typefaceNames.Reserve(1));
       
   956 			typefaceNames.Append(_L("Devanagari OT Eval"));
       
   957 			break;
       
   958 		case ETestLanguageLatin:
       
   959 			User::LeaveIfError(typefaceNames.Reserve(3));
       
   960 			typefaceNames.Append(_L("DejaVu Sans Condensed"));
       
   961 			typefaceNames.Append(_L("DejaVu Serif"));
       
   962 			typefaceNames.Append(_L("DejaVu Sans Mono"));
       
   963 			break;
       
   964 		default:
       
   965 			User::Leave(KErrNotSupported);
       
   966 		}
       
   967 	const TInt KNumTypefaces = typefaceNames.Count();
       
   968 		
       
   969 	iFont = new CFbsFont*[aNumFonts];
       
   970 	for (TInt count = 0; count < aNumFonts; ++count)
       
   971 		{
       
   972 		// After every KNumTypefaces font, increase size by 5.
       
   973 		TInt size = aStartSizeInPixels + (5 *(count / KNumTypefaces));
       
   974 		TPtrC typefaceName = typefaceNames[count % KNumTypefaces];
       
   975 		TFontSpec fontSpec(typefaceName, size);
       
   976 		User::LeaveIfError(iTs->GetNearestFontToDesignHeightInPixels((CFont*&)iFont[count], fontSpec));
       
   977 		++iNumFonts;
       
   978 		}
       
   979 	iCurFont = -1;
       
   980 	CleanupStack::PopAndDestroy(1); // typefaceNames
       
   981 	}
       
   982 /**
       
   983 Releases all created fonts and frees associated memory.
       
   984 */
       
   985 void CTFontFactory::ReleaseFonts()
       
   986 	{
       
   987 	for (TInt font = 0; font < iNumFonts; ++font)
       
   988 		{
       
   989 		iTs->ReleaseFont(iFont[font]);
       
   990 		}
       
   991 	delete [] iFont;
       
   992 	iFont = NULL;
       
   993 	iNumFonts = 0;
       
   994 	}
       
   995 
       
   996 /**
       
   997 @return The next font to be used. If it reaches the last font, the next font will
       
   998 	cycle back around to the first font.
       
   999 */
       
  1000 CFbsFont* CTFontFactory::NextFont()
       
  1001 	{
       
  1002 	return iFont[++iCurFont%iNumFonts];
       
  1003 	}