graphicstest/uibench/src/tfbsfontrasterizeperf.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 04 Oct 2010 02:31:51 +0300
changeset 194 18f84489a694
permissions -rw-r--r--
Revision: 201039 Kit: 201039

// Copyright (c) 2010 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:
// tfbsfontrasterizeperf.cpp
// 
//

/**
 @file
 @test
 @internalComponent - Internal test code 
*/

#include <hal.h>
#include "tfbsfontrasterizeperf.h"

const TPtrC CTFbsFontRasterizePerf::TCacheTestParam::KLangText[] = {_L("Latin"), _L("Chinese")};

_LIT(KLatinText, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_+-=|:;,.><?0123456789");
// Each of below Chinese text contains 256 Unicode
_LIT16(KChineseText1, "\x554A\x963F\x57C3\x6328\x54CE\x5509\x54C0\x7691\x764C\x853C\x77EE\x827E\x788D\x7231\x9698\x978D\x6C28\x5B89\x4FFA\x6309\x6697\x5CB8\x80FA\x6848\x80AE\x6602\x76CE\x51F9\x6556\x71AC\x7FF1\x8884\x50B2\x5965\x61CA\x6FB3\x82AD\x634C\x6252\x53ED\x5427\x7B06\x516B\x75A4\x5DF4\x62D4\x8DCB\x9776\x628A\x8019\x575D\x9738\x7F62\x7238\x767D\x67CF\x767E\x6446\x4F70\x8D25\x62DC\x7A17\x6591\x73ED\x642C\x6273\x822C\x9881\x677F\x7248\x626E\x62CC\x4F34\x74E3\x534A\x529E\x7ECA\x90A6\x5E2E\x6886\x699C\x8180\x7ED1\x68D2\x78C5\x868C\x9551\x508D\x8C24\x82DE\x80DE\x5305\x8912\x5265\x8584\x96F9\x4FDD\x5821\x9971\x5B9D\x62B1\x62A5\x66B4\x8C79\x9C8D\x7206\x676F\x7891\x60B2\x5351\x5317\x8F88\x80CC\x8D1D\x94A1\x500D\x72C8\x5907\x60EB\x7119\x88AB\x5954\x82EF\x672C\x7B28\x5D29\x7EF7\x752D\x6CF5\x8E66\x8FF8\x903C\x9F3B\x6BD4\x9119\x7B14\x5F7C\x78A7\x84D6\x853D\x6BD5\x6BD9\x6BD6\x5E01\x5E87\x75F9\x95ED\x655D\x5F0A\x5FC5\x8F9F\x58C1\x81C2\x907F\x965B\x97AD\x8FB9\x7F16\x8D2C\x6241\x4FBF\x53D8\x535E\x8FA8\x8FA9\x8FAB\x904D\x6807\x5F6A\x8198\x8868\x9CD6\x618B\x522B\x762A\x5F6C\x658C\x6FD2\x6EE8\x5BBE\x6448\x5175\x51B0\x67C4\x4E19\x79C9\x997C\x70B3\x75C5\x5E76\x73BB\x83E0\x64AD\x62E8\x94B5\x6CE2\x535A\x52C3\x640F\x94C2\x7B94\x4F2F\x5E1B\x8236\x8116\x818A\x6E24\x6CCA\x9A73\x6355\x535C\x54FA\x8865\x57E0\x4E0D\x5E03\x6B65\x7C3F\x90E8\x6016\x64E6\x731C\x88C1\x6750\x624D\x8D22\x776C\x8E29\x91C7\x5F69\x83DC\x8521\x9910\x53C2\x8695\x6B8B\x60ED\x60E8\x707F\x82CD\x8231\x4ED3\x6CA7\x85CF\x64CD\x7CD9\x69FD\x66F9\x8349\x5395\x7B56\x4FA7\x518C\x6D4B\x5C42\x8E6D");
_LIT16(KChineseText2, "\x63D2\x53C9\x832C\x8336\x67E5\x78B4\x643D\x5BDF\x5C94\x5DEE\x8BE7\x62C6\x67F4\x8C7A\x6400\x63BA\x8749\x998B\x8C17\x7F20\x94F2\x4EA7\x9610\x98A4\x660C\x7316\x573A\x5C1D\x5E38\x957F\x507F\x80A0\x5382\x655E\x7545\x5531\x5021\x8D85\x6284\x949E\x671D\x5632\x6F6E\x5DE2\x5435\x7092\x8F66\x626F\x64A4\x63A3\x5F7B\x6F88\x90F4\x81E3\x8FB0\x5C18\x6668\x5FF1\x6C89\x9648\x8D81\x886C\x6491\x79F0\x57CE\x6A59\x6210\x5448\x4E58\x7A0B\x60E9\x6F84\x8BDA\x627F\x901E\x9A8B\x79E4\x5403\x75F4\x6301\x5319\x6C60\x8FDF\x5F1B\x9A70\x803B\x9F7F\x4F88\x5C3A\x8D64\x7FC5\x65A5\x70BD\x5145\x51B2\x866B\x5D07\x5BA0\x62BD\x916C\x7574\x8E0C\x7A20\x6101\x7B79\x4EC7\x7EF8\x7785\x4E11\x81ED\x521D\x51FA\x6A71\x53A8\x8E87\x9504\x96CF\x6EC1\x9664\x695A\x7840\x50A8\x77D7\x6410\x89E6\x5904\x63E3\x5DDD\x7A7F\x693D\x4F20\x8239\x5598\x4E32\x75AE\x7A97\x5E62\x5E8A\x95EF\x521B\x5439\x708A\x6376\x9524\x5782\x6625\x693F\x9187\x5507\x6DF3\x7EAF\x8822\x6233\x7EF0\x75B5\x8328\x78C1\x96CC\x8F9E\x6148\x74F7\x8BCD\x6B64\x523A\x8D50\x6B21\x806A\x8471\x56F1\x5306\x4ECE\x4E1B\x51D1\x7C97\x918B\x7C07\x4FC3\x8E7F\x7BE1\x7A9C\x6467\x5D14\x50AC\x8106\x7601\x7CB9\x6DEC\x7FE0\x6751\x5B58\x5BF8\x78CB\x64AE\x6413\x63AA\x632B\x9519\x642D\x8FBE\x7B54\x7629\x6253\x5927\x5446\x6B79\x50A3\x6234\x5E26\x6B86\x4EE3\x8D37\x888B\x5F85\x902E\x6020\x803D\x62C5\x4E39\x5355\x90F8\x63B8\x80C6\x65E6\x6C2E\x4F46\x60EE\x6DE1\x8BDE\x5F39\x86CB\x5F53\x6321\x515A\x8361\x6863\x5200\x6363\x8E48\x5012\x5C9B\x7977\x5BFC\x5230\x7A3B\x60BC\x9053\x76D7\x5FB7\x5F97\x7684\x8E6C\x706F\x767B\x7B49\x77AA\x51F3");
_LIT16(KChineseText3, "\x9093\x5824\x4F4E\x6EF4\x8FEA\x654C\x7B1B\x72C4\x6DA4\x7FDF\x5AE1\x62B5\x5E95\x5730\x8482\x7B2C\x5E1D\x5F1F\x9012\x7F14\x98A0\x6382\x6EC7\x7898\x70B9\x5178\x975B\x57AB\x7535\x4F43\x7538\x5E97\x60E6\x5960\x6DC0\x6BBF\x7889\x53FC\x96D5\x51CB\x5201\x6389\x540A\x9493\x8C03\x8DCC\x7239\x789F\x8776\x8FED\x8C0D\x53E0\x4E01\x76EF\x53EE\x9489\x9876\x9F0E\x952D\x5B9A\x8BA2\x4E22\x4E1C\x51AC\x8463\x61C2\x52A8\x680B\x4F97\x606B\x51BB\x6D1E\x515C\x6296\x6597\x9661\x8C46\x9017\x75D8\x90FD\x7763\x6BD2\x728A\x72EC\x8BFB\x5835\x7779\x8D4C\x675C\x9540\x809A\x5EA6\x6E21\x5992\x7AEF\x77ED\x953B\x6BB5\x65AD\x7F0E\x5806\x5151\x961F\x5BF9\x58A9\x5428\x8E72\x6566\x987F\x56E4\x949D\x76FE\x9041\x6387\x54C6\x591A\x593A\x579B\x8EB2\x6735\x8DFA\x8235\x5241\x60F0\x5815\x86FE\x5CE8\x9E45\x4FC4\x989D\x8BB9\x5A25\x6076\x5384\x627C\x904F\x9102\x997F\x6069\x800C\x513F\x8033\x5C14\x9975\x6D31\x4E8C\x8D30\x53D1\x7F5A\x7B4F\x4F10\x4E4F\x9600\x6CD5\x73D0\x85E9\x5E06\x756A\x7FFB\x6A0A\x77FE\x9492\x7E41\x51E1\x70E6\x53CD\x8FD4\x8303\x8D29\x72AF\x996D\x6CDB\x574A\x82B3\x65B9\x80AA\x623F\x9632\x59A8\x4EFF\x8BBF\x7EBA\x653E\x83F2\x975E\x5561\x98DE\x80A5\x532A\x8BFD\x5420\x80BA\x5E9F\x6CB8\x8D39\x82AC\x915A\x5429\x6C1B\x5206\x7EB7\x575F\x711A\x6C7E\x7C89\x594B\x4EFD\x5FFF\x6124\x7CAA\x4E30\x5C01\x67AB\x8702\x5CF0\x950B\x98CE\x75AF\x70FD\x9022\x51AF\x7F1D\x8BBD\x5949\x51E4\x4F5B\x5426\x592B\x6577\x80A4\x5B75\x6276\x62C2\x8F90\x5E45\x6C1F\x7B26\x4F0F\x4FD8\x670D\x6D6E\x6DAA\x798F\x88B1\x5F17\x752B\x629A\x8F85\x4FEF\x91DC\x65A7\x812F\x8151\x5E9C\x8150\x8D74");
_LIT16(KChineseText4, "\x526F\x8986\x8D4B\x590D\x5085\x4ED8\x961C\x7236\x8179\x8D1F\x5BCC\x8BA3\x9644\x5987\x7F1A\x5490\x5676\x560E\x8BE5\x6539\x6982\x9499\x76D6\x6E89\x5E72\x7518\x6746\x67D1\x7AFF\x809D\x8D76\x611F\x79C6\x6562\x8D63\x5188\x521A\x94A2\x7F38\x809B\x7EB2\x5C97\x6E2F\x6760\x7BD9\x768B\x9AD8\x818F\x7F94\x7CD5\x641E\x9550\x7A3F\x544A\x54E5\x6B4C\x6401\x6208\x9E3D\x80F3\x7599\x5272\x9769\x845B\x683C\x86E4\x9601\x9694\x94EC\x4E2A\x5404\x7ED9\x6839\x8DDF\x8015\x66F4\x5E9A\x7FB9\x57C2\x803F\x6897\x5DE5\x653B\x529F\x606D\x9F9A\x4F9B\x8EAC\x516C\x5BAB\x5F13\x5DE9\x6C5E\x62F1\x8D21\x5171\x94A9\x52FE\x6C9F\x82DF\x72D7\x57A2\x6784\x8D2D\x591F\x8F9C\x83C7\x5495\x7B8D\x4F30\x6CBD\x5B64\x59D1\x9F13\x53E4\x86CA\x9AA8\x8C37\x80A1\x6545\x987E\x56FA\x96C7\x522E\x74DC\x5250\x5BE1\x6302\x8902\x4E56\x62D0\x602A\x68FA\x5173\x5B98\x51A0\x89C2\x7BA1\x9986\x7F50\x60EF\x704C\x8D2F\x5149\x5E7F\x901B\x7470\x89C4\x572D\x7845\x5F52\x9F9F\x95FA\x8F68\x9B3C\x8BE1\x7678\x6842\x67DC\x8DEA\x8D35\x523D\x8F8A\x6EDA\x68CD\x9505\x90ED\x56FD\x679C\x88F9\x8FC7\x54C8\x9AB8\x5B69\x6D77\x6C26\x4EA5\x5BB3\x9A87\x9163\x61A8\x90AF\x97E9\x542B\x6DB5\x5BD2\x51FD\x558A\x7F55\x7FF0\x64BC\x634D\x65F1\x61BE\x608D\x710A\x6C57\x6C49\x592F\x676D\x822A\x58D5\x568E\x8C6A\x6BEB\x90DD\x597D\x8017\x53F7\x6D69\x5475\x559D\x8377\x83CF\x6838\x79BE\x548C\x4F55\x5408\x76D2\x8C89\x9602\x6CB3\x6DB8\x8D6B\x8910\x9E64\x8D3A\x563F\x9ED1\x75D5\x5F88\x72E0\x6068\x54FC\x4EA8\x6A2A\x8861\x6052\x8F70\x54C4\x70D8\x8679\x9E3F\x6D2A\x5B8F\x5F18\x7EA2\x5589\x4FAF\x7334\x543C\x539A\x5019\x540E\x547C");
_LIT16(KChineseText5, "\x4E4E\x5FFD\x745A\x58F6\x846B\x80E1\x8774\x72D0\x7CCA\x6E56\x5F27\x864E\x552C\x62A4\x4E92\x6CAA\x6237\x82B1\x54D7\x534E\x733E\x6ED1\x753B\x5212\x5316\x8BDD\x69D0\x5F8A\x6000\x6DEE\x574F\x6B22\x73AF\x6853\x8FD8\x7F13\x6362\x60A3\x5524\x75EA\x8C62\x7115\x6DA3\x5BA6\x5E7B\x8352\x614C\x9EC4\x78FA\x8757\x7C27\x7687\x51F0\x60F6\x714C\x6643\x5E4C\x604D\x8C0E\x7070\x6325\x8F89\x5FBD\x6062\x86D4\x56DE\x6BC1\x6094\x6167\x5349\x60E0\x6666\x8D3F\x79FD\x4F1A\x70E9\x6C47\x8BB3\x8BF2\x7ED8\x8364\x660F\x5A5A\x9B42\x6D51\x6DF7\x8C41\x6D3B\x4F19\x706B\x83B7\x6216\x60D1\x970D\x8D27\x7978\x51FB\x573E\x57FA\x673A\x7578\x7A3D\x79EF\x7B95\x808C\x9965\x8FF9\x6FC0\x8BA5\x9E21\x59EC\x7EE9\x7F09\x5409\x6781\x68D8\x8F91\x7C4D\x96C6\x53CA\x6025\x75BE\x6C72\x5373\x5AC9\x7EA7\x6324\x51E0\x810A\x5DF1\x84DF\x6280\x5180\x5B63\x4F0E\x796D\x5242\x60B8\x6D4E\x5BC4\x5BC2\x8BA1\x8BB0\x65E2\x5FCC\x9645\x5993\x7EE7\x7EAA\x5609\x67B7\x5939\x4F73\x5BB6\x52A0\x835A\x988A\x8D3E\x7532\x94BE\x5047\x7A3C\x4EF7\x67B6\x9A7E\x5AC1\x6B7C\x76D1\x575A\x5C16\x7B3A\x95F4\x714E\x517C\x80A9\x8270\x5978\x7F04\x8327\x68C0\x67EC\x78B1\x7877\x62E3\x6361\x7B80\x4FED\x526A\x51CF\x8350\x69DB\x9274\x8DF5\x8D31\x89C1\x952E\x7BAD\x4EF6\x5065\x8230\x5251\x996F\x6E10\x6E85\x6DA7\x5EFA\x50F5\x59DC\x5C06\x6D46\x6C5F\x7586\x848B\x6868\x5956\x8BB2\x5320\x9171\x964D\x8549\x6912\x7901\x7126\x80F6\x4EA4\x90CA\x6D47\x9A84\x5A07\x56BC\x6405\x94F0\x77EB\x4FA5\x811A\x72E1\x89D2\x997A\x7F34\x7EDE\x527F\x6559\x9175\x8F7F\x8F83\x53EB\x7A96\x63ED\x63A5\x7686\x79F8\x8857\x9636\x622A\x52AB\x8282");

static const TInt KFontSizeInPixels[3] = {10, 50, 200};

_LIT(KChineseFontFileName,"z:\\PlatTest\\Graphics\\TestData\\S60SC_C.ttf");
_LIT(KChineseFontName,"MHeiM-C-GB18030-S60");

// for below constants: AntiAliased bitmap type, S60SC_C.ttf,
namespace AntiAliased
    {
    static const TGlyphBitmapType KGlyphBitmapType = EAntiAliasedGlyphBitmap;
    static const TInt KNumberToUseUpGlyphCache_Latin_10 = KLatinText.iTypeLength;
    static const TInt KNumberToUseUpGlyphCache_Latin_50 = 50;
    static const TInt KNumberToUseUpGlyphCache_Latin_200 = 3;
    static const TInt KNumberToUseUpGlyphCache_Chinese_10 = 238;
    static const TInt KNumberToUseUpGlyphCache_Chinese_50 = 15;
    static const TInt KNumberToUseUpGlyphCache_Chinese_200 = 1;
    }

// for below constants: Monochrome bitmap type, S60SC_C.ttf,
namespace MonoChrome
    {
    static const TGlyphBitmapType KGlyphBitmapType = EMonochromeGlyphBitmap;
    static const TInt KNumberToUseUpGlyphCache_Latin_10 = KLatinText.iTypeLength;
    static const TInt KNumberToUseUpGlyphCache_Latin_50 = KLatinText.iTypeLength;
    static const TInt KNumberToUseUpGlyphCache_Latin_200 = 45;
    static const TInt KNumberToUseUpGlyphCache_Chinese_10 = KChineseText1.iTypeLength;
    static const TInt KNumberToUseUpGlyphCache_Chinese_50 = 132;
    static const TInt KNumberToUseUpGlyphCache_Chinese_200 = 10;
    }

//Define file name to load
_LIT(KInputFileLatin1,"z:\\PlatTest\\Graphics\\TestData\\Latin1.txt");
_LIT(KInputFileChinese1,"z:\\PlatTest\\Graphics\\TestData\\Chinese1.txt");
_LIT(KInputFileLatin2,"z:\\PlatTest\\Graphics\\TestData\\Latin2.txt");
_LIT(KInputFileChinese2,"z:\\PlatTest\\Graphics\\TestData\\Chinese2.txt");
_LIT(KInputFileLatin3,"z:\\PlatTest\\Graphics\\TestData\\Latin3.txt");
_LIT(KInputFileChinese3,"z:\\PlatTest\\Graphics\\TestData\\Chinese3.txt");
_LIT(KInputFileLatin4,"z:\\PlatTest\\Graphics\\TestData\\Latin4.txt");
_LIT(KInputFileChinese4,"z:\\PlatTest\\Graphics\\TestData\\Chinese4.txt");

CTFbsFontRasterizePerf::CTFbsFontRasterizePerf()
	{
	SetTestStepName(KTFbsFontRasterizePerfName);
	}

TVerdict CTFbsFontRasterizePerf::doTestStepPreambleL()
	{
	CTe_graphicsperformanceSuiteStepBase::doTestStepPreambleL();
	SetScreenModeL(EColor16MU);
	return TestStepResult();
	}

/**
Override of base class pure virtual
Our implementation only gets called if the base class doTestStepPreambleL() did
not leave. That being the case, the current test result value will be EPass.

@return - TVerdict code
*/
TVerdict CTFbsFontRasterizePerf::doTestStepL()
	{	
    SetTestStepID(_L("GRAPHICS-UI-BENCH-0141"));
    GlyphCacheNotFullL();
    RecordTestResultL();
	
    SetTestStepID(_L("GRAPHICS-UI-BENCH-0142"));
    GlyphCacheFullLSessionCacheNotFullL();
    RecordTestResultL();

    SetTestStepID(_L("GRAPHICS-UI-BENCH-0143"));
    GlyphCacheFullLSessionCacheFullL();
    RecordTestResultL();

    SetTestStepID(_L("GRAPHICS-UI-BENCH-0144"));
    TestItypeRasterizeL();    
    RecordTestResultL();

    SetTestStepID(_L("GRAPHICS-UI-BENCH-0145"));
    TestLoadFontsAtStartupL();
    RecordTestResultL();
    
    SetTestStepID(_L("GRAPHICS-UI-BENCH-0146"));
    FontGetCharacterDataMultiSessionL();
    RecordTestResultL();    

	CloseTMSGraphicsStep();
	return TestStepResult();
	}

/**
 * Glyph cache is not full, and, no cache hit, which means every GetCharacterData() will 
 * call rasterizing via IPC and put the glyph data to glyph cache (MACRO KMaxGlyphCacheMemory=32768 inf fntstore.mmp)
 */
void CTFbsFontRasterizePerf::GlyphCacheNotFullL()
    {    
    CFbsTypefaceStore* ts = CFbsTypefaceStore::NewL(NULL);
    CleanupStack::PushL(ts);

    TCacheTestParam cacheTestParams[] = 
            {
            {KFontSizeInPixels[0], AntiAliased::KGlyphBitmapType, TCacheTestParam::ELatin, KLatinText, 0, AntiAliased::KNumberToUseUpGlyphCache_Latin_10},
            {KFontSizeInPixels[0], MonoChrome::KGlyphBitmapType, TCacheTestParam::ELatin, KLatinText, 0, MonoChrome::KNumberToUseUpGlyphCache_Latin_10},
            {KFontSizeInPixels[1], AntiAliased::KGlyphBitmapType, TCacheTestParam::ELatin, KLatinText, 0, AntiAliased::KNumberToUseUpGlyphCache_Latin_50},
            {KFontSizeInPixels[1], MonoChrome::KGlyphBitmapType, TCacheTestParam::ELatin, KLatinText, 0, MonoChrome::KNumberToUseUpGlyphCache_Latin_50},
            {KFontSizeInPixels[2], AntiAliased::KGlyphBitmapType, TCacheTestParam::ELatin, KLatinText, 0, AntiAliased::KNumberToUseUpGlyphCache_Latin_200},
            {KFontSizeInPixels[2], MonoChrome::KGlyphBitmapType, TCacheTestParam::ELatin, KLatinText, 0, MonoChrome::KNumberToUseUpGlyphCache_Latin_200},
            {KFontSizeInPixels[0], AntiAliased::KGlyphBitmapType, TCacheTestParam::EChinese, KChineseText1, 0, AntiAliased::KNumberToUseUpGlyphCache_Chinese_10},
            {KFontSizeInPixels[0], MonoChrome::KGlyphBitmapType, TCacheTestParam::EChinese, KChineseText1, 0, MonoChrome::KNumberToUseUpGlyphCache_Chinese_10},
            {KFontSizeInPixels[1], AntiAliased::KGlyphBitmapType, TCacheTestParam::EChinese, KChineseText1, 0, AntiAliased::KNumberToUseUpGlyphCache_Chinese_50},
            {KFontSizeInPixels[1], MonoChrome::KGlyphBitmapType, TCacheTestParam::EChinese, KChineseText1, 0, MonoChrome::KNumberToUseUpGlyphCache_Chinese_50},
            {KFontSizeInPixels[2], AntiAliased::KGlyphBitmapType, TCacheTestParam::EChinese, KChineseText1, 0, AntiAliased::KNumberToUseUpGlyphCache_Chinese_200},
            {KFontSizeInPixels[2], MonoChrome::KGlyphBitmapType, TCacheTestParam::EChinese, KChineseText1, 0, MonoChrome::KNumberToUseUpGlyphCache_Chinese_200}            
            };
    
    const TInt KNum = sizeof(cacheTestParams) / sizeof(cacheTestParams[0]); 
    for (TInt i = 0; i < KNum; i++)
        {
        DoCacheTestL(ts, cacheTestParams[i], _L("GlyphCacheNotFullL"));
        }

    CleanupStack::PopAndDestroy(ts);
    }

/**
 * Glyph cache is full but session cache is not full, and, no cache hit, which means every GetCharacterData() will 
 * call rasterizing via IPC and put the glyph data to glyph cache and session cache
 */
void CTFbsFontRasterizePerf::GlyphCacheFullLSessionCacheNotFullL()
    {    
    CFbsTypefaceStore* ts = CFbsTypefaceStore::NewL(NULL);
    CleanupStack::PushL(ts);

    RBuf16 ChineseText;
    ChineseText.Create(256 * 2);
    ChineseText.Append(KChineseText1);
    ChineseText.Append(KChineseText2);
    ChineseText.CleanupClosePushL();
    
    TCacheTestParam cacheTestParams[] = 
            {
            {KFontSizeInPixels[0], AntiAliased::KGlyphBitmapType, TCacheTestParam::ELatin, KLatinText, AntiAliased::KNumberToUseUpGlyphCache_Latin_10, KLatinText.iTypeLength},
            {KFontSizeInPixels[0], MonoChrome::KGlyphBitmapType, TCacheTestParam::ELatin, KLatinText, MonoChrome::KNumberToUseUpGlyphCache_Latin_10, KLatinText.iTypeLength},
            {KFontSizeInPixels[1], AntiAliased::KGlyphBitmapType, TCacheTestParam::ELatin, KLatinText, AntiAliased::KNumberToUseUpGlyphCache_Latin_50, KLatinText.iTypeLength},
            {KFontSizeInPixels[1], MonoChrome::KGlyphBitmapType, TCacheTestParam::ELatin, KLatinText, MonoChrome::KNumberToUseUpGlyphCache_Latin_50, KLatinText.iTypeLength},
            {KFontSizeInPixels[2], AntiAliased::KGlyphBitmapType, TCacheTestParam::ELatin, KLatinText, AntiAliased::KNumberToUseUpGlyphCache_Latin_200, KLatinText.iTypeLength},
            {KFontSizeInPixels[2], MonoChrome::KGlyphBitmapType, TCacheTestParam::ELatin, KLatinText, MonoChrome::KNumberToUseUpGlyphCache_Latin_200, KLatinText.iTypeLength},
            {KFontSizeInPixels[0], AntiAliased::KGlyphBitmapType, TCacheTestParam::EChinese, ChineseText, AntiAliased::KNumberToUseUpGlyphCache_Chinese_10, ChineseText.Length()},
            {KFontSizeInPixels[0], MonoChrome::KGlyphBitmapType, TCacheTestParam::EChinese, ChineseText, MonoChrome::KNumberToUseUpGlyphCache_Chinese_10 * 2, ChineseText.Length()}, // NOTE: to == from makes this test case not run
            {KFontSizeInPixels[1], AntiAliased::KGlyphBitmapType, TCacheTestParam::EChinese, ChineseText, AntiAliased::KNumberToUseUpGlyphCache_Chinese_50, ChineseText.Length()},
            {KFontSizeInPixels[1], MonoChrome::KGlyphBitmapType, TCacheTestParam::EChinese, ChineseText, MonoChrome::KNumberToUseUpGlyphCache_Chinese_50, ChineseText.Length()},
            {KFontSizeInPixels[2], AntiAliased::KGlyphBitmapType, TCacheTestParam::EChinese, ChineseText, AntiAliased::KNumberToUseUpGlyphCache_Chinese_200, ChineseText.Length()},
            {KFontSizeInPixels[2], MonoChrome::KGlyphBitmapType, TCacheTestParam::EChinese, ChineseText, MonoChrome::KNumberToUseUpGlyphCache_Chinese_200, ChineseText.Length()}            
            };
    
    const TInt KNum = sizeof(cacheTestParams) / sizeof(cacheTestParams[0]); 
    for (TInt i = 0; i < KNum; i++)
        {
        DoCacheTestL(ts, cacheTestParams[i], _L("GlyphCacheFullLSessionCacheNotFull"));
        }
    
    CleanupStack::PopAndDestroy(&ChineseText);
    CleanupStack::PopAndDestroy(ts);
    }

void CTFbsFontRasterizePerf::GlyphCacheFullLSessionCacheFullL()
    {    
    CFbsTypefaceStore* ts = CFbsTypefaceStore::NewL(NULL);
    CleanupStack::PushL(ts);

    RBuf16 ChineseText;
    ChineseText.Create(256 * 5);
    ChineseText.Append(KChineseText1);
    ChineseText.Append(KChineseText2);
    ChineseText.Append(KChineseText3);
    ChineseText.Append(KChineseText4);
    ChineseText.Append(KChineseText5);
    ChineseText.CleanupClosePushL();

    TCacheTestParam cacheTestParams[] = 
            {
            {KFontSizeInPixels[1], AntiAliased::KGlyphBitmapType, TCacheTestParam::EChinese, ChineseText, 700, ChineseText.Length()},
            {KFontSizeInPixels[1], MonoChrome::KGlyphBitmapType, TCacheTestParam::EChinese, ChineseText, 700, ChineseText.Length()},
            {KFontSizeInPixels[2], AntiAliased::KGlyphBitmapType, TCacheTestParam::EChinese, ChineseText, 700, ChineseText.Length()},
            {KFontSizeInPixels[2], MonoChrome::KGlyphBitmapType, TCacheTestParam::EChinese, ChineseText, 700, ChineseText.Length()}            
            };
    
    const TInt KNum = sizeof(cacheTestParams) / sizeof(cacheTestParams[0]); 
    for (TInt i = 0; i < KNum; i++)
        {
        DoCacheTestL(ts, cacheTestParams[i], _L("GlyphCacheFullLSessionCacheFullL"));
        }

    CleanupStack::PopAndDestroy(&ChineseText);
    CleanupStack::PopAndDestroy(ts);
    }

void CTFbsFontRasterizePerf::DoCacheTestL(CFbsTypefaceStore* aTs, const TCacheTestParam& aParam, const TDesC& aTestName)
    {
    if ((aParam.iTo - aParam.iFrom) == 0)
        {
        return;
        }

    const TInt KCount= 50;
    const TInt KIters = (aParam.iTo - aParam.iFrom) * KCount;
    TOpenFontCharMetrics metrics;
    const TUint8 *bitmapBytes = NULL;
    TSize bitmapSize;
    CFont* font = NULL;
    TInt err = KErrNone;    
    TInt fontFileId = 0;
    TFontSpec fontSpec(KChineseFontName, aParam.iHeight);
    fontSpec.iFontStyle.SetBitmapType(aParam.iGlyphBitmapType);
    TBuf<48> testName;
    testName.Format(_L("%S_%S_%d_%d"), &aTestName, &aParam.KLangText[aParam.iLang], aParam.iGlyphBitmapType, aParam.iHeight);
    
    iProfiler->SetStoreResultInTimingOrder(EFalse);
    
    iProfiler->InitResults();
    for (TInt count = 0; count < KCount; count++)
        {
        err = aTs->InstallFile(KChineseFontFileName, fontFileId);
        TEST(err == KErrNone);
        
        err = aTs->GetNearestFontToDesignHeightInPixels(font, fontSpec);
        TEST(err == KErrNone);

        for (TInt i = 0; i < aParam.iFrom; i++) // fill cache using the characters before aText[from]
            {
            const CFont::TCharacterDataAvailability availability =
                font->GetCharacterData(aParam.iText[i], metrics, bitmapBytes, bitmapSize);
            TEST(availability == CFont::EAllCharacterData);
            }

        for (TInt i = aParam.iFrom; i < aParam.iTo; i++) // using characters before aText[to] to avoid using glyphCache/sessionCache
            {
            iProfiler->StartTimer();
            const CFont::TCharacterDataAvailability availability =
                font->GetCharacterData(aParam.iText[i], metrics, bitmapBytes, bitmapSize);
            iProfiler->MarkResultSetL();
            TEST(availability == CFont::EAllCharacterData); // May fails due to no enough memory for large size character on emulator 
            }
               
        aTs->ReleaseFont(font);  // Release font, cache will be released also.
        aTs->RemoveFile(fontFileId);
        }
    iProfiler->ResultsAnalysis(testName, 0, 0, 0, KIters);
    }

void CTFbsFontRasterizePerf::TestItypeRasterizeL()
    {
    //
    // create heap and glyph data
    //
    RHeap* heap = UserHeap::ChunkHeap(NULL,0x10000,0x10000);
    if (NULL == heap)
        {
        _LIT(KLog,"Not enough memory to create heap for test");
        INFO_PRINTF1(KLog);
        User::Leave(KErrNoMemory);
        }

    TOpenFontGlyphData* openFontGlyphData = TOpenFontGlyphData::New(heap, 36 * 1024);
    TEST(openFontGlyphData != NULL);

    TBuf<48> testName;
    RBuf16 ChineseText;
    ChineseText.Create(256 * 5);
    ChineseText.Append(KChineseText1);
    ChineseText.Append(KChineseText2);
    ChineseText.Append(KChineseText3);
    ChineseText.Append(KChineseText4);
    ChineseText.Append(KChineseText5);    
    ChineseText.CleanupClosePushL();

    TCacheTestParam cacheTestParams[] = 
            {
            {KFontSizeInPixels[0], AntiAliased::KGlyphBitmapType, TCacheTestParam::ELatin, KLatinText, 0, 0},
            {KFontSizeInPixels[0], MonoChrome::KGlyphBitmapType, TCacheTestParam::ELatin, KLatinText, 0, 0},
            {KFontSizeInPixels[1], AntiAliased::KGlyphBitmapType, TCacheTestParam::ELatin, KLatinText, 0, 0},
            {KFontSizeInPixels[1], MonoChrome::KGlyphBitmapType, TCacheTestParam::ELatin, KLatinText, 0, 0},
            {KFontSizeInPixels[2], AntiAliased::KGlyphBitmapType, TCacheTestParam::ELatin, KLatinText, 0, 0},
            {KFontSizeInPixels[2], MonoChrome::KGlyphBitmapType, TCacheTestParam::ELatin, KLatinText, 0, 0},
            {KFontSizeInPixels[0], AntiAliased::KGlyphBitmapType, TCacheTestParam::EChinese, ChineseText, 0, 0},
            {KFontSizeInPixels[0], MonoChrome::KGlyphBitmapType, TCacheTestParam::EChinese, ChineseText, 0, 0},
            {KFontSizeInPixels[1], AntiAliased::KGlyphBitmapType, TCacheTestParam::EChinese, ChineseText, 0, 0},
            {KFontSizeInPixels[1], MonoChrome::KGlyphBitmapType, TCacheTestParam::EChinese, ChineseText, 0, 0},
            {KFontSizeInPixels[2], AntiAliased::KGlyphBitmapType, TCacheTestParam::EChinese, ChineseText, 0, 0},
            {KFontSizeInPixels[2], MonoChrome::KGlyphBitmapType, TCacheTestParam::EChinese, ChineseText, 0, 0}            
            };
    
    const TInt KNum = sizeof(cacheTestParams) / sizeof(cacheTestParams[0]); 
    for (TInt i = 0; i < KNum; i++)
        {
        DoTestItypeRasterizeL(heap, cacheTestParams[i], openFontGlyphData);        
        }

    CleanupStack::PopAndDestroy(&ChineseText);
    heap->Free(openFontGlyphData);
    heap->Close();    
    }

void CTFbsFontRasterizePerf::DoTestItypeRasterizeL(RHeap* aHeap, const TCacheTestParam& aParam, TOpenFontGlyphData* aGlyphData)
    {
    const TInt KCount = 10;
    const TInt KIters = aParam.iText.Length() * KCount;
    CBitmapFont* font = NULL;
    TFontSpec fontSpec(KChineseFontName, aParam.iHeight);
    fontSpec.iFontStyle.SetBitmapType(aParam.iGlyphBitmapType);
    TBuf<48> testName;
    testName.Format(_L("TestItypeRasterizeL_%S_%d_%d"), &aParam.KLangText[aParam.iLang], aParam.iGlyphBitmapType, aParam.iHeight);

    // Perform the iterations to test
    iProfiler->InitResults();    
    for (TInt count = 0; count < KCount; count++)
        {
        //
        // create CFontStore
        //
        CFontStore* fontStore = CFontStore::NewL(aHeap);
        CleanupStack::PushL(fontStore);
    
        //
        // Install the rasterizer.
        //
        COpenFontRasterizer* rasterizer = COpenFontRasterizer::NewL(TUid::Uid(0x101F7F5E));
        CleanupStack::PushL(rasterizer);
        fontStore->InstallRasterizerL(rasterizer);
        CleanupStack::Pop(rasterizer);
    
        //
        // Add font files
        //    
        TInt ret = KErrNone;
        TUid id1 = TUid::Uid(0);    
        TRAP(ret, id1 = fontStore->AddFileL(KChineseFontFileName));
        TEST(ret==KErrNone);    

        //
        // Create font
        TInt err = fontStore->GetNearestFontToDesignHeightInPixels((CFont*&)font, fontSpec);
        TEST(err == KErrNone);
    
        //
        // rasterize
        //
        for (TInt i = 0; i < aParam.iText.Length(); i++)
            {
            iProfiler->StartTimer();
            font->OpenFont()->RasterizeL(aParam.iText[i], aGlyphData);        
            iProfiler->MarkResultSetL();
            }
        
        //
        // release resources
        //
        fontStore->ReleaseFont(font);
        CleanupStack::PopAndDestroy(fontStore);        
        }
    iProfiler->ResultsAnalysis(testName, 0, 0, 0, KIters);
    REComSession::FinalClose(); //close the ecom session opened by COpenFontRasterizer::NewL()
    }

void CTFbsFontRasterizePerf::TestLoadFontsAtStartupL()
    {
    const TInt KCount = 100;
    RHeap* heap = UserHeap::ChunkHeap(NULL,0x10000,0x10000);
    if (NULL == heap)
        {
        _LIT(KLog,"Not enough memory to create heap for test");
        INFO_PRINTF1(KLog);
        User::Leave(KErrNoMemory);
        }
    
    // Perform the iterations to test
    iProfiler->InitResults();
    for(TInt count=KCount; count>0; --count)
        {
        CFontStore* fontStore = CFontStore::NewL(heap);
        CleanupStack::PushL(fontStore);
    
        // Install the rasterizer.
        COpenFontRasterizer* rasterizer = COpenFontRasterizer::NewL(TUid::Uid(0x101F7F5E));
        CleanupStack::PushL(rasterizer);
        fontStore->InstallRasterizerL(rasterizer);
        CleanupStack::Pop(rasterizer);
    
        iProfiler->StartTimer();
        fontStore->LoadFontsAtStartupL();        
        iProfiler->MarkResultSetL();
        
        CleanupStack::PopAndDestroy(fontStore);        
        }
    iProfiler->ResultsAnalysis(_L("TestLoadFontsAtStartupL"), 0, 0, 0, KCount);
    
    REComSession::FinalClose(); //close the ecom session opened by COpenFontRasterizer::NewL()
    heap->Close();
    }

void CTFbsFontRasterizePerf::FontGetCharacterDataMultiSessionL()
    {
    CFbsTypefaceStore* ts = CFbsTypefaceStore::NewL(NULL);
    CleanupStack::PushL(ts);
    TInt fontFileId = 0;
    TInt err = ts->InstallFile(KChineseFontFileName, fontFileId);
    TEST(err == KErrNone);

    TInt PixelHeightInTwips = 0;
    TMachineInfoV1Buf machineInfoBuffer;
    User::LeaveIfError(UserHal::MachineInfo(machineInfoBuffer));
    const TSize twipSize = machineInfoBuffer().iPhysicalScreenSize;
    const TSize pixelSize = machineInfoBuffer().iDisplaySizeInPixels;
    if (twipSize.iHeight > 0 && pixelSize.iHeight > 0)
        PixelHeightInTwips = twipSize.iHeight * 1000 / pixelSize.iHeight;
    INFO_PRINTF2(_L("KPixelHeightInTwips = %d"),PixelHeightInTwips);

    TFontSpec fontSpec(KChineseFontName, 2);
    fontSpec.iHeight = 200;
    
    fontSpec.iFontStyle.SetBitmapType(AntiAliased::KGlyphBitmapType);    
    INFO_PRINTF1(_L("FontHeight = 200 pixel; BitmapType = AntiAliased - FontGetCharacterDataMultiSession"));
    DoFontGetCharacterDataMultiSessionL(fontSpec);

    fontSpec.iFontStyle.SetBitmapType(MonoChrome::KGlyphBitmapType);    
    INFO_PRINTF1(_L("FontHeight = 200 pixel; BitmapType = MonoChrome - FontGetCharacterDataMultiSession"));
    DoFontGetCharacterDataMultiSessionL(fontSpec);

    
    fontSpec.iHeight = 50;
    
    fontSpec.iFontStyle.SetBitmapType(AntiAliased::KGlyphBitmapType);
    INFO_PRINTF1(_L("FontHeight = 50 pixel; BitmapType = AntiAliased - FontGetCharacterDataMultiSession"));
    DoFontGetCharacterDataMultiSessionL(fontSpec);

    fontSpec.iFontStyle.SetBitmapType(MonoChrome::KGlyphBitmapType);
    INFO_PRINTF1(_L("FontHeight = 50 pixel; BitmapType = MonoChrome - FontGetCharacterDataMultiSession"));
    DoFontGetCharacterDataMultiSessionL(fontSpec);

    ts->RemoveFile(fontFileId);
    CleanupStack::PopAndDestroy(ts);
    }


void CTFbsFontRasterizePerf::DoFontGetCharacterDataMultiSessionL(TFontSpec& aFontSpec)
    {    
    RArray<TPtrC> fileNames;
    CleanupClosePushL(fileNames);
    fileNames.AppendL(TPtrC(KInputFileLatin1));
    fileNames.AppendL(TPtrC(KInputFileChinese1));
    
    const TInt KNumOfThreads = 4;
    
    TMultiThreadPara paras[KNumOfThreads];
    Mem::FillZ(paras,sizeof(TMultiThreadPara) * KNumOfThreads);
    
    RThread workers[KNumOfThreads];
    TRequestStatus statusArray[KNumOfThreads];
    
    // ---  KNumOfThreads Render same input file. (Latin and Chinese)
    for(TInt count=0; count < fileNames.Count(); count++)
        {
        for(TInt i = 0; i < KNumOfThreads; i++)
            {
            paras[i].iSpec = &aFontSpec;
            paras[i].iFileName.Set(fileNames[count]);
            User::LeaveIfError(workers[i].Create(KNullDesC,FontGetCharacterDataThread,0x10000,0x1000,0x10000,reinterpret_cast<TAny *>(&paras[i])));
            statusArray[i] = KRequestPending;
            workers[i].Logon(statusArray[i]);                            
            }
        for(TInt i = 0; i < KNumOfThreads; i++)
            {
            workers[i].Resume();
            }
    
        TBool bFinished = EFalse;
        do{
           User::WaitForAnyRequest();
           bFinished = ETrue;
           for(TInt i = 0; i < KNumOfThreads; i++)
               {
               if(statusArray[i] == KRequestPending)
                   {
                   bFinished = EFalse;
                   }
               else
                   {
                   workers[i].Close();
                   }
               }       
        }while(!bFinished);
        for(TInt i = 0; i < KNumOfThreads; i++)
            {            
            TBuf<128> NameBuf;
            NameBuf.AppendFormat(_L("Font-GetCharacterData-MutiSession-%d"),i);
            _LIT(KVariantMax,"Max");
            _LIT(KVariantMin,"Min");
            _LIT(KVariantMean,"Mean");            
            iProfiler->SqlInsert(&NameBuf,&KVariantMax,&KMicroSeconds,paras[i].iTimeMax);
            iProfiler->SqlInsert(&NameBuf,&KVariantMin,&KMicroSeconds,paras[i].iTimeMin);
            iProfiler->SqlInsert(&NameBuf,&KVariantMean,&KMicroSeconds,paras[i].iMean);
            INFO_PRINTF3(_L("File = %S,Iters = %d"),&paras[i].iFileName, paras[i].iIters);
            }                
        }
    
    // KNumOfThreads Render different input file.
    
    Mem::FillZ(paras,sizeof(TMultiThreadPara) * KNumOfThreads);
    fileNames.Reset();
    // Append num of the files in same script = KNumOfThreads 
    fileNames.AppendL(TPtrC(KInputFileLatin1));
    fileNames.AppendL(TPtrC(KInputFileLatin2));
    fileNames.AppendL(TPtrC(KInputFileLatin3));
    fileNames.AppendL(TPtrC(KInputFileLatin4));
    fileNames.AppendL(TPtrC(KInputFileChinese1));
    fileNames.AppendL(TPtrC(KInputFileChinese2));
    fileNames.AppendL(TPtrC(KInputFileChinese3));
    fileNames.AppendL(TPtrC(KInputFileChinese4));
    
    for (TInt count = 0; count < 2; count++)
        {
        for (TInt i = 0; i < KNumOfThreads; i++)
            {
            paras[i].iSpec = &aFontSpec;
            paras[i].iFileName.Set(fileNames[i + count * KNumOfThreads]);
            User::LeaveIfError(workers[i].Create(KNullDesC,
                    FontGetCharacterDataThread, 0x10000, 0x1000, 0x10000,
                    reinterpret_cast<TAny *> (&paras[i])));
            statusArray[i] = KRequestPending;
            workers[i].Logon(statusArray[i]);
            }
        for (TInt i = 0; i < KNumOfThreads; i++)
            {
            workers[i].Resume();
            }

        TBool bFinished = EFalse;
        do
            {
            User::WaitForAnyRequest();
            bFinished = ETrue;
            for (TInt i = 0; i < KNumOfThreads; i++)
                {
                if (statusArray[i] == KRequestPending)
                    {
                    bFinished = EFalse;
                    }
                else
                    {
                    workers[i].Close();
                    }
                }
            }
        while (!bFinished);
        for (TInt i = 0; i < KNumOfThreads; i++)
            {
            TBuf<128> NameBuf;
            NameBuf.AppendFormat(_L("Font-GetCharacterData-MutiSession-%d"), i);
            _LIT(KVariantMax,"Max");
            _LIT(KVariantMin,"Min");
            _LIT(KVariantMean,"Mean");
            iProfiler->SqlInsert(&NameBuf, &KVariantMax, &KMicroSeconds,
                    paras[i].iTimeMax);
            iProfiler->SqlInsert(&NameBuf, &KVariantMin, &KMicroSeconds,
                    paras[i].iTimeMin);
            iProfiler->SqlInsert(&NameBuf, &KVariantMean, &KMicroSeconds,
                    paras[i].iMean);
            INFO_PRINTF3(_L("File = %S,Iters = %d"),&paras[i].iFileName, paras[i].iIters);
            }
        }
     
    CleanupStack::PopAndDestroy();
    }

TInt CTFbsFontRasterizePerf::FontGetCharacterDataThread(TAny * aPtr)
    {
    // Create cleanup stack
        __UHEAP_MARK;
        CTrapCleanup* cleanup = CTrapCleanup::New();
              
        // Create output console
        TRAPD(createError, FontGetCharacterDataWorkerL((reinterpret_cast<TMultiThreadPara*> (aPtr))));
        if (createError)
            {
            delete cleanup;
            return createError;
            }

        delete cleanup;
        __UHEAP_MARKEND;
        return KErrNone;
    }

void CTFbsFontRasterizePerf::FontGetCharacterDataWorkerL(TMultiThreadPara *aPara)
    {
    User::LeaveIfError(RFbsSession::Connect());    
    CFbsFont* font = NULL;
    CFbsTypefaceStore* ts = CFbsTypefaceStore::NewL(NULL);
    CleanupStack::PushL(ts);

    TFontSpec spec = *aPara->iSpec;

    User::LeaveIfError(ts->GetNearestFontToDesignHeightInPixels((CFont*&) font, spec));

    TUint32 start = 0;
    TUint32 end = 0;
    TInt freq = 0;        
    User::LeaveIfError((HAL::Get(HALData::EFastCounterFrequency, freq)));
    if(freq == 0)
        {
        User::Leave(KErrDivideByZero);
        }
    
    // Load text from file    
    RFs   fs;
    User::LeaveIfError(fs.Connect());
    CleanupClosePushL(fs);
    
    RFile in;      
    User::LeaveIfError(in.Open(fs, aPara->iFileName, EFileShareReadersOnly | EFileStreamText));
    CleanupClosePushL(in);
    
    TFileText content;  
    content.Set(in);
    
    TBool isFirstChar = ETrue;
    TInt64 diffsum = 0;
    
    TBuf<512> buf;
    while(KErrNone == content.Read(buf))
        {
        TOpenFontCharMetrics metrics;
        const TUint8* bitmap;
        TSize bitmapSize;
        for (TInt i = 0; i < buf.Length(); i++)
            {
            CFont::TCharacterDataAvailability ret; 
            start = User::FastCounter();
            ret = font->GetCharacterData(buf[i], metrics, bitmap, bitmapSize);
            end = User::FastCounter();
            ASSERT(ret = CFont::EAllCharacterData);
            TInt64 diff = (1000000 * (TInt64) (end - start)) / (TInt64) freq;
            if(diff == 0)
                {
                diff = 1;
                }
            diffsum += diff;
            ASSERT(diffsum >= 0);
            aPara->iIters++;
            if (isFirstChar)
                {
                aPara->iTimeMax = aPara->iTimeMin = diff;
                isFirstChar = EFalse;
                }
            else
                {
                if (diff > aPara->iTimeMax)
                    {
                    aPara->iTimeMax = diff;
                    }
                if (diff < aPara->iTimeMin)
                    {
                    aPara->iTimeMin = diff;
                    }
                }        
            }
        }
    
    // Write back Iters 
    if(aPara->iIters != 0)
        {
        aPara->iMean = diffsum / aPara->iIters;
        }
    RDebug::Print(_L("diffsum=%Ld"),diffsum);
    
    ts->ReleaseFont(font);
    CleanupStack::PopAndDestroy(3);
    RFbsSession::Disconnect();
    }