graphicstest/uibench/src/tfbsfontrasterizeperf.cpp
changeset 194 18f84489a694
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicstest/uibench/src/tfbsfontrasterizeperf.cpp	Mon Oct 04 02:31:51 2010 +0300
@@ -0,0 +1,713 @@
+// 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();
+    }