fbs/fontandbitmapserver/tfbs/tfonttableandglyph.cpp
changeset 36 01a6848ebfd7
child 45 36b2e23a8629
equal deleted inserted replaced
0:5d03bc08d59c 36:01a6848ebfd7
       
     1 // Copyright (c) 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 #include <gdi.h>
       
    17 #include <fbs.h> 
       
    18 #include <e32test.h>
       
    19 #include <e32property.h>
       
    20 #include <graphics/openfontconstants.h>
       
    21 #include <graphics/openfontrasterizer.h>
       
    22 #include <graphics/gdi/gdiplatapi.h>
       
    23 #include "fbsmessage.h"
       
    24 #include "tfonttableandglyph.h"
       
    25 
       
    26 //global variable
       
    27 _LIT16(KTestFontFile, "C:\\DejaVuSans.ttf");
       
    28 _LIT16(KTestFontFaceName, "DejaVu Sans");
       
    29 
       
    30 _LIT16(KTestFontFile2, "C:\\DejaVuSerif.ttf");
       
    31 _LIT16(KTestFontFaceName2, "DejaVu Serif");
       
    32 
       
    33 static void LoadOpenFontLibraries(CFontStore* aFontStore);
       
    34 
       
    35 LOCAL_C const TInt KFontHeight = 12;
       
    36 LOCAL_C const TInt KInvalidGlyphId = 0xffff;
       
    37 
       
    38 CTFontAndGlyph::CTFontAndGlyph(CTestStep* aStep) :
       
    39     CTGraphicsBase(aStep),
       
    40     iBmp(NULL),
       
    41     iBmp2(NULL),
       
    42     iDevice(NULL),
       
    43     iDevice2(NULL),
       
    44     iFont(NULL),
       
    45     iFont2(NULL),
       
    46     iFontStore(NULL),
       
    47     iFontSpec(KTestFontFaceName, KFontHeight),
       
    48     iFontSpec2(KTestFontFaceName2, KFontHeight)
       
    49     {
       
    50         // a null constructor
       
    51     }
       
    52 
       
    53 CTFontAndGlyph::~CTFontAndGlyph()
       
    54     {
       
    55     CleanEnv();
       
    56     }
       
    57 
       
    58 void CTFontAndGlyph::RunTestCaseL(TInt aCurTestCase)
       
    59     {
       
    60     ((CTFontAndGlyphStep*)iStep)->SetTestStepID(KUnknownSYMTestCaseIDName);
       
    61     
       
    62     switch(aCurTestCase)
       
    63         {
       
    64     case 1:
       
    65         ((CTFontAndGlyphStep*)iStep)->SetTestStepID(_L("TI18N-GDI-CIT-4079"));
       
    66         INFO_PRINTF1(_L("GetHintedGlyphById"));
       
    67         GetHintedGlyphById(); 
       
    68         break;
       
    69         
       
    70     case 2:
       
    71         ((CTFontAndGlyphStep*)iStep)->SetTestStepID(_L("TI18N-GDI-CIT-4080"));
       
    72         INFO_PRINTF1(_L("GetUnHintedGlyphById"));
       
    73         GetUnHintedGlyphById();
       
    74         break;
       
    75                
       
    76     case 3:
       
    77         ((CTFontAndGlyphStep*)iStep)->SetTestStepID(_L("TI18N-GDI-CIT-4081"));
       
    78         INFO_PRINTF1(_L("GetHintedGlyphByWrongId"));
       
    79         GetHintedGlyphByWrongId();
       
    80         break;   
       
    81         
       
    82     case 4:
       
    83         ((CTFontAndGlyphStep*)iStep)->SetTestStepID(_L("TI18N-GDI-CIT-4082"));
       
    84         INFO_PRINTF1(_L("GetGlyphWithNoMem"));
       
    85         GetGlyphWithNoMem();
       
    86         break; 
       
    87         
       
    88     case 5:
       
    89         ((CTFontAndGlyphStep*)iStep)->SetTestStepID(_L("TI18N-GDI-CIT-4083"));
       
    90         INFO_PRINTF1(_L("GetFontTable"));
       
    91         GetFontTable();
       
    92         break;         
       
    93         
       
    94         
       
    95     case 6:
       
    96         ((CTFontAndGlyphStep*)iStep)->SetTestStepID(_L("TI18N-GDI-CIT-4084"));
       
    97         INFO_PRINTF1(_L("GetFontTableByWrongTag"));
       
    98         GetFontTableByWrongTag();
       
    99         break;        
       
   100 
       
   101     case 7:
       
   102         ((CTFontAndGlyphStep*)iStep)->SetTestStepID(_L("TI18N-GDI-CIT-4085"));
       
   103         INFO_PRINTF1(_L("GetFontTableWithNoMem"));
       
   104         GetFontTableWithNoMem();
       
   105         break;    
       
   106         
       
   107     case 8:
       
   108         ((CTFontAndGlyphStep*)iStep)->SetTestStepID(_L("TI18N-GDI-CIT-4089"));
       
   109         INFO_PRINTF1(_L("GlyphOutlineIteratorPanics"));
       
   110         GlyphOutlineIteratorPanics();
       
   111         break;   
       
   112         
       
   113     case 9:
       
   114         ((CTFontAndGlyphStep*)iStep)->SetTestStepID(_L("TI18N-GDI-CIT-4090"));
       
   115         INFO_PRINTF1(_L("WDPAndSMPSafeTest"));
       
   116         SMPAndWDPSafeTest();
       
   117         break;
       
   118         
       
   119     case 10:
       
   120         ((CTFontAndGlyphStep*)iStep)->SetTestStepID(_L("TI18N-GDI-CIT-4087"));
       
   121         INFO_PRINTF1(_L("TestFbsFontHandleIsZeroForFont"));
       
   122         TestFbsFontHandleIsZeroForFont();
       
   123         break;  
       
   124 
       
   125     case 11:
       
   126         ((CTFontAndGlyphStep*)iStep)->SetTestStepID(_L("TI18N-GDI-CIT-4088"));
       
   127         INFO_PRINTF1(_L("TestFbsFontHandleIsZeroForGlyph"));
       
   128         TestFbsFontHandleIsZeroForGlyph();
       
   129         break;   
       
   130         
       
   131     case 12:
       
   132         ((CTFontAndGlyphStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName);
       
   133         ((CTFontAndGlyphStep*)iStep)->CloseTMSGraphicsStep();
       
   134         TestComplete();
       
   135         break;
       
   136     default:
       
   137         INFO_PRINTF1(_L("Invalid test case id found."));
       
   138         }    
       
   139         ((CTFontAndGlyphStep*)iStep)->RecordTestResultL();
       
   140     }
       
   141 
       
   142 
       
   143 /**
       
   144     @SYMTestCaseID    TI18N-GDI-CIT-4083
       
   145     @SYMTestCaseDesc    Get font table. 
       
   146     @SYMTestActions    Get font table using the new RFontTable class and test
       
   147     the return value.
       
   148     @SYMTestExpectedResults  Open() returns KErrNone. TableContent returns the
       
   149     table content. 
       
   150 */
       
   151 void CTFontAndGlyph::GetFontTable()
       
   152     {
       
   153     __UHEAP_MARK;
       
   154     RFontTable fontTable;
       
   155     TInt err = fontTable.Open(*iFont, 0x68656164);  
       
   156     TEST(err == KErrNone);
       
   157     TUint32* tablePtr = (TUint32*)fontTable.TableContent();     
       
   158     TEST(tablePtr != NULL);
       
   159     TEST(tablePtr[3] == 0xF53C0F5F);   //magic number is correct
       
   160     RFontTable fontTableInCache;
       
   161     err = fontTableInCache.Open(*iFont, 0x68656164);  
       
   162     TEST(err == KErrNone);
       
   163     TUint32* tablePtr2 = (TUint32*)fontTableInCache.TableContent();  
       
   164     TEST(tablePtr2[3] == 0xF53C0F5F);
       
   165     TEST(tablePtr == tablePtr2);
       
   166     
       
   167     RFontTable fontTable2;
       
   168     err = fontTable2.Open(*iFont2, 0x68656164);  
       
   169     TEST(err == KErrNone);
       
   170     tablePtr = (TUint32*)fontTable2.TableContent();     
       
   171     TEST(tablePtr != NULL);
       
   172     TEST(tablePtr[3] == 0xF53C0F5F);   //magic number is correct
       
   173     RFontTable fontTableInCache2;
       
   174     err = fontTableInCache2.Open(*iFont2, 0x68656164);  
       
   175     TEST(err == KErrNone);
       
   176     tablePtr2 = (TUint32*)fontTableInCache2.TableContent();  
       
   177     TEST(tablePtr2[3] == 0xF53C0F5F);
       
   178     TEST(tablePtr == tablePtr2);
       
   179     
       
   180     fontTableInCache.Close();
       
   181     fontTable.Close();
       
   182     fontTableInCache2.Close();
       
   183     fontTable2.Close();
       
   184     __UHEAP_MARKEND;
       
   185     }
       
   186 
       
   187 
       
   188 /**
       
   189     @SYMTestCaseID    TI18N-GDI-CIT-4084
       
   190     @SYMTestCaseDesc    Get font table, providing an invalid tag. 
       
   191     @SYMTestActions    Get font table, providing an invalid tag (0). 
       
   192     Test the return value.
       
   193     @SYMTestExpectedResults    Open() returns KErrNotFound.
       
   194 */
       
   195 void CTFontAndGlyph::GetFontTableByWrongTag()
       
   196     {
       
   197     __UHEAP_MARK;
       
   198     RFontTable fontTableForWrongID;
       
   199     TInt err = fontTableForWrongID.Open(*iFont, 0);  
       
   200     fontTableForWrongID.Close(); 
       
   201     TEST(KErrNotFound == err); 
       
   202     __UHEAP_MARKEND;
       
   203     }
       
   204 
       
   205 
       
   206 /**
       
   207     @SYMTestCaseID    TI18N-GDI-CIT-4085
       
   208     @SYMTestCaseDesc    Get font table, when system is OOM. 
       
   209     @SYMTestActions    Get font table, simulate OOM conditions using debug macros,
       
   210      and test return value.
       
   211     @SYMTestExpectedResults    Open() returns KErrNoMemory. TableContent() and 
       
   212     TableLength() return NULL/0.
       
   213 */
       
   214 void CTFontAndGlyph::GetFontTableWithNoMem()
       
   215     {
       
   216 #ifdef _DEBUG 
       
   217     __UHEAP_MARK;
       
   218     RFontTable aFontTableForMem;
       
   219     RFbsSession *fbsSession = RFbsSession::GetSession();
       
   220     fbsSession->SendCommand(EFbsMessSetHeapFail, RFbsSession::EHeapFailTypeHeapMemory, 1);
       
   221     TInt err = aFontTableForMem.Open(*iFont, 0x68656164); /* 'head' in ascii (hex) */
       
   222     TEST(KErrNoMemory == err);
       
   223     TEST(0 == aFontTableForMem.TableLength());
       
   224     TEST(0 == aFontTableForMem.TableContent());
       
   225     aFontTableForMem.Close();
       
   226     fbsSession->SendCommand(EFbsMessSetHeapReset, RFbsSession::EHeapFailTypeHeapMemory);
       
   227     __UHEAP_MARKEND;
       
   228 #else
       
   229     INFO_PRINTF1(_L("Skipping test GetFontTableWithNoMem in release mode")); 
       
   230 #endif
       
   231     }
       
   232 
       
   233 
       
   234 /**
       
   235     @SYMTestCaseID    TI18N-GDI-CIT-4082
       
   236     @SYMTestCaseDesc    Get glyph outline when system is out of memory.
       
   237     @SYMTestActions    Get  glyph outline. Simulate OOM faliures using debug
       
   238     macros to check if the program logic is correct.
       
   239     @SYMTestExpectedResults    Open() always returns KErrNoMemory.
       
   240 */
       
   241 void CTFontAndGlyph::GetGlyphWithNoMem()
       
   242     {
       
   243 #ifdef _DEBUG 
       
   244     __UHEAP_MARK;
       
   245     RFbsSession *fbsSession = RFbsSession::GetSession();
       
   246     
       
   247     TUint glyphIndex[] = {4, 4, KInvalidGlyphId};  
       
   248     __UHEAP_FAILNEXT(1);
       
   249     RGlyphOutlineIterator it1;    
       
   250     TInt err = it1.Open(*iFont, glyphIndex, sizeof(glyphIndex)/sizeof(glyphIndex[0]), ETrue);
       
   251     TEST(err == KErrNoMemory);
       
   252     it1.Close(); 
       
   253     
       
   254     __UHEAP_FAILNEXT(2);
       
   255     RGlyphOutlineIterator it2;
       
   256     err = it2.Open(*iFont, glyphIndex, sizeof(glyphIndex)/sizeof(glyphIndex[0]));
       
   257     TEST(err == KErrNoMemory);
       
   258     TEST(KErrNotFound == it2.Next());
       
   259     it2.Close(); 
       
   260     
       
   261     __UHEAP_FAILNEXT(3);
       
   262     RGlyphOutlineIterator it3;
       
   263     err = it3.Open(*iFont, glyphIndex, sizeof(glyphIndex)/sizeof(glyphIndex[0]), ETrue);
       
   264     TEST(err == KErrNoMemory);
       
   265     TEST(KErrNotFound == it2.Next());
       
   266     it3.Close(); 
       
   267     
       
   268     RGlyphOutlineIterator it4;  
       
   269     fbsSession = RFbsSession::GetSession();
       
   270     fbsSession->SendCommand(EFbsMessSetHeapFail, RFbsSession::EHeapFailTypeServerMemory, 1);
       
   271     err = it4.Open(*iFont, glyphIndex, sizeof(glyphIndex)/sizeof(glyphIndex[0])); 
       
   272     TEST(KErrNoMemory == err);
       
   273     TEST(KErrNotFound == it2.Next());
       
   274     fbsSession->SendCommand(EFbsMessSetHeapReset, RFbsSession::EHeapFailTypeServerMemory);
       
   275     it4.Close();
       
   276     
       
   277     __UHEAP_FAILNEXT(4);
       
   278     RGlyphOutlineIterator it5;
       
   279     err = it5.Open(*iFont, glyphIndex, sizeof(glyphIndex)/sizeof(glyphIndex[0]));
       
   280     TEST(err == KErrNoMemory);
       
   281     TEST(KErrNotFound == it2.Next());
       
   282     it5.Close();
       
   283     __UHEAP_MARKEND;
       
   284 #else
       
   285     INFO_PRINTF1(_L("Skipping test GetGlyphWithNoMem in release mode"));
       
   286 #endif
       
   287     }
       
   288 
       
   289 
       
   290 /**
       
   291     @SYMTestCaseID    TI18N-GDI-CIT-4079
       
   292     @SYMTestCaseDesc    Get hinted glyph outline
       
   293     @SYMTestActions    Get hinted glyph outline for glyph 4 and 65536. 
       
   294     Pass NULL for the 'aCodes' argument, and 0 for the 'aCount' to test 
       
   295     param validation. Check return values in each situation.
       
   296     @SYMTestExpectedResults    Open() returns KErrNone. Outline() returns a 
       
   297     valid pointer to the string representing the outline. OutlineLength() returns
       
   298     the corresponding string length.
       
   299 */
       
   300 void CTFontAndGlyph::GetHintedGlyphById()
       
   301     {
       
   302     __UHEAP_MARK;
       
   303     RGlyphOutlineIterator glyphIterator1;
       
   304     TUint glyphIndex[] = {4, 4, KInvalidGlyphId};  //two 4 to ensure the 2nd glyph is in cache.
       
   305     TInt err = glyphIterator1.Open(*iFont, glyphIndex, sizeof(glyphIndex)/sizeof(glyphIndex[0]), ETrue);
       
   306     TEST(err == KErrNone);  
       
   307     TInt len1 = glyphIterator1.OutlineLength();   
       
   308     const TUint8* ptr1 = glyphIterator1.Outline();
       
   309     TInt end = glyphIterator1.Next();
       
   310     const TUint8* ptr2 = glyphIterator1.Outline();
       
   311     TInt len2= glyphIterator1.OutlineLength(); 
       
   312     TEST(len1 > 0);  
       
   313     TEST(ptr1 != NULL);
       
   314     TEST(ptr1 == ptr2);  
       
   315     TEST(len1 == len2); 
       
   316         
       
   317     RGlyphOutlineIterator glyphIterator1b;  // for font file 2
       
   318     TUint glyphIndex_2[] = {0x41, 0x41, KInvalidGlyphId}; 
       
   319     err = glyphIterator1b.Open(*iFont2, glyphIndex_2, 
       
   320             sizeof(glyphIndex_2)/sizeof(glyphIndex_2[0]), ETrue);
       
   321     TEST(err == KErrNone);  
       
   322     len1 = glyphIterator1b.OutlineLength();   
       
   323     ptr1 = glyphIterator1b.Outline();
       
   324     end = glyphIterator1b.Next();
       
   325     ptr2 = glyphIterator1b.Outline();
       
   326     len2= glyphIterator1b.OutlineLength(); 
       
   327     TEST(len1 > 0);  
       
   328     TEST(ptr1 != NULL);
       
   329     TEST(ptr1 == ptr2);  
       
   330     TEST(len1 == len2); 
       
   331     
       
   332     end = glyphIterator1.Next();    
       
   333     len1 = glyphIterator1.OutlineLength(); 
       
   334     ptr1 = glyphIterator1.Outline();
       
   335     // for the invalid glyph id, len1<0 indicates an error.
       
   336     TEST(NULL == ptr1);
       
   337     TEST(len1 < 0);
       
   338     end = glyphIterator1.Next();
       
   339     TEST(KErrNotFound == end);
       
   340     // calling Outline() or OutlineLength() causes panic if Next() 
       
   341     // returns KErrNotFound
       
   342     glyphIterator1.Close();
       
   343 
       
   344     end = glyphIterator1b.Next();    
       
   345     len1 = glyphIterator1b.OutlineLength(); 
       
   346     ptr1 = glyphIterator1b.Outline();
       
   347     // for the invalid glyph id, len1<0 indicates an error.
       
   348     TEST(NULL == ptr1);
       
   349     TEST(len1 < 0);
       
   350     end = glyphIterator1b.Next();
       
   351     TEST(KErrNotFound == end);
       
   352     // calling Outline() or OutlineLength() causes panic if Next() 
       
   353     // returns KErrNotFound
       
   354     glyphIterator1b.Close();
       
   355     
       
   356     RGlyphOutlineIterator glyphIterator3;
       
   357     err = glyphIterator3.Open(*iFont, glyphIndex, 0, ETrue);
       
   358     TEST(KErrArgument == err);
       
   359     TEST(KErrNotFound == glyphIterator3.Next());
       
   360     glyphIterator3.Close();  
       
   361     
       
   362     RGlyphOutlineIterator glyphIterator4;
       
   363     err = glyphIterator4.Open(*iFont, NULL, sizeof(glyphIndex)/sizeof(glyphIndex[0]), ETrue);
       
   364     TEST(KErrArgument == err);
       
   365     TEST(KErrNotFound == glyphIterator4.Next());
       
   366     glyphIterator4.Close(); 
       
   367     __UHEAP_MARKEND;
       
   368     }
       
   369 
       
   370 
       
   371 /**
       
   372     @SYMTestCaseID    TI18N-GDI-CIT-4081
       
   373     @SYMTestCaseDesc    Get hinted glyph outline, passing in invalid IDs.
       
   374     @SYMTestActions    Get hinted glyph outline, passing in invalid IDs. Check 
       
   375     the return values.
       
   376     @SYMTestExpectedResults    Open() returns KErrNone. Outline() returns NULL.
       
   377     OutlineLength() returns KErrGeneral.
       
   378 */
       
   379 void CTFontAndGlyph::GetHintedGlyphByWrongId()
       
   380     {
       
   381     __UHEAP_MARK;
       
   382     RGlyphOutlineIterator glyphIterator;
       
   383     TUint glyphIndex[] = {KInvalidGlyphId, KInvalidGlyphId};  
       
   384     TInt err = glyphIterator.Open(*iFont, glyphIndex, sizeof(glyphIndex)/sizeof(glyphIndex[0]), ETrue);
       
   385     TEST(err == KErrNone);  
       
   386     const TUint8* ptr = glyphIterator.Outline();
       
   387     TInt len = glyphIterator.OutlineLength();
       
   388     TEST(KErrGeneral == len);
       
   389     TEST(ptr == NULL);
       
   390     TInt ret = glyphIterator.Next();
       
   391     TEST(KErrNone == ret);
       
   392     glyphIterator.Close();
       
   393     __UHEAP_MARKEND;
       
   394     }
       
   395 
       
   396 
       
   397 /**
       
   398     @SYMTestCaseID    TI18N-GDI-CIT-4080
       
   399     @SYMTestCaseDesc    Get unhinted glyph outline
       
   400     @SYMTestActions    Get unhinted glyph outline for glyph 4 and 5. 
       
   401     @SYMTestExpectedResults    Open() returns KErrNone. Outline() and 
       
   402     OutlineLength() returns the outline string and corresponding length.
       
   403 */
       
   404 void CTFontAndGlyph::GetUnHintedGlyphById()
       
   405     {
       
   406     __UHEAP_MARK;
       
   407     RGlyphOutlineIterator glyphIterator2;
       
   408     TUint glyphIndex[] = {4, 4, 5};  //two '4' to ensure the 2nd is in cache.
       
   409     TInt err = glyphIterator2.Open(*iFont, glyphIndex, sizeof(glyphIndex)/sizeof(glyphIndex[0]), EFalse);
       
   410     TEST(err == KErrNone);   
       
   411     const TUint8* ptr1 = glyphIterator2.Outline();
       
   412     TInt len1 = glyphIterator2.OutlineLength();     
       
   413     err = glyphIterator2.Next();
       
   414     TEST(err == KErrNone);
       
   415     const TUint8* ptr2 = glyphIterator2.Outline();
       
   416     TInt len2= glyphIterator2.OutlineLength(); 
       
   417     err = glyphIterator2.Next();
       
   418     TEST(err == KErrNone);
       
   419     TEST(len1 > 0);  
       
   420     TEST(ptr1 == ptr2); 
       
   421     TEST(ptr1 != NULL);
       
   422     TEST(len1 == len2);      
       
   423     
       
   424     RGlyphOutlineIterator glyphIterator2b;  // for the 2nd font file
       
   425     TUint glyphIndex2[] = {0x41, 0x41, 0x42}; 
       
   426     err = glyphIterator2b.Open(*iFont2, glyphIndex2, 
       
   427             sizeof(glyphIndex2)/sizeof(glyphIndex2[0]), EFalse);
       
   428     TEST(err == KErrNone);   
       
   429     ptr1 = glyphIterator2b.Outline();
       
   430     len1 = glyphIterator2b.OutlineLength();     
       
   431     err = glyphIterator2b.Next();
       
   432     TEST(err == KErrNone);
       
   433     ptr2 = glyphIterator2b.Outline();
       
   434     len2= glyphIterator2b.OutlineLength(); 
       
   435     err = glyphIterator2b.Next();
       
   436     TEST(err == KErrNone);
       
   437     TEST(len1 > 0);  
       
   438     TEST(ptr1 == ptr2); 
       
   439     TEST(ptr1 != NULL);
       
   440     TEST(len1 == len2);
       
   441     
       
   442     glyphIterator2.Close();
       
   443     glyphIterator2b.Close();
       
   444     __UHEAP_MARKEND;
       
   445     }
       
   446 
       
   447 /**
       
   448     @SYMTestCaseID    TI18N-GDI-CIT-4087
       
   449     @SYMTestCaseDesc    Pass invalid font handle to FBS when getting font table.
       
   450     @SYMTestActions    Pass invalid font handle to FBS when getting font table.
       
   451         And check the return value.
       
   452     @SYMTestExpectedResults    Open returns KErrNotFound.
       
   453 */
       
   454 void CTFontAndGlyph::TestFbsFontHandleIsZeroForFont() 
       
   455     {
       
   456     __UHEAP_MARK;
       
   457     CFbsTestForFont* fbsFont = reinterpret_cast<CFbsTestForFont*> (iFont);
       
   458     TEST(NULL != fbsFont);
       
   459     fbsFont->SetHandle(0);
       
   460     TInt handle = fbsFont->Handle();
       
   461     CFbsTestForFont tempFsbFont;
       
   462     tempFsbFont.Duplicate(handle);
       
   463     tempFsbFont.SetHandle(0);    
       
   464     RFontTable ft1;
       
   465     TInt err = ft1.Open(tempFsbFont, 0x11667730);
       
   466     TEST(err == KErrNotFound);
       
   467     ft1.Close(); 
       
   468     __UHEAP_MARKEND;
       
   469     }
       
   470 
       
   471 /**
       
   472     @SYMTestCaseID    TI18N-GDI-CIT-4088
       
   473     @SYMTestCaseDesc    Pass invalid font handle to FBS when getting glyph outline.
       
   474     @SYMTestActions    Pass invalid font handle to FBS when getting glyph outline.
       
   475         And check the return value.
       
   476     @SYMTestExpectedResults    Open() returns KErrNotFound.
       
   477 */
       
   478 void CTFontAndGlyph::TestFbsFontHandleIsZeroForGlyph() 
       
   479     {
       
   480     __UHEAP_MARK;
       
   481     CFbsTestForFont* fbsFont = reinterpret_cast<CFbsTestForFont*> (iFont);
       
   482     TEST(NULL != fbsFont);
       
   483     TInt handle = fbsFont->Handle();
       
   484     CFbsTestForFont tempFsbFont;
       
   485     tempFsbFont.Duplicate(handle);
       
   486     tempFsbFont.SetHandle(0);     
       
   487     RGlyphOutlineIterator glyphIterator1;
       
   488     TUint glyphIndex[] = {1, 1, KInvalidGlyphId}; 
       
   489     TInt err = glyphIterator1.Open(tempFsbFont, glyphIndex, sizeof(glyphIndex)/sizeof(glyphIndex[0]), ETrue);
       
   490     TEST(err == KErrNotFound);
       
   491     glyphIterator1.Close();    
       
   492     __UHEAP_MARKEND;
       
   493     }
       
   494 
       
   495 static TInt OutlinePanicThread(TAny* /* ptr */)
       
   496     {   
       
   497     CTrapCleanup* trapCleanup=CTrapCleanup::New();
       
   498     RGlyphOutlineIterator it;
       
   499     it.Outline();
       
   500     delete trapCleanup;
       
   501     return 0;
       
   502     }
       
   503 
       
   504 static TInt OutlineLengthPanicThread(TAny* /* ptr */)
       
   505     {   
       
   506     CTrapCleanup* trapCleanup=CTrapCleanup::New();
       
   507     RGlyphOutlineIterator it;
       
   508     it.OutlineLength();
       
   509     delete trapCleanup;
       
   510     return 0;
       
   511     }
       
   512 
       
   513 void CTFontAndGlyph::OutlinePanics(TInt (*aThreadFun)(TAny*))
       
   514     {   
       
   515     __UHEAP_MARK;
       
   516     RThread thread;
       
   517     TThreadFunction fun(aThreadFun);
       
   518     TAny* ptr = NULL;
       
   519     thread.Create(_L("RGlyphOutlineIterator"), fun, 0x1000, 0x20000, 0x20000, ptr);
       
   520     
       
   521     TRequestStatus status;
       
   522     thread.Logon(status);
       
   523     thread.Resume();
       
   524     User::WaitForRequest(status);
       
   525     
       
   526     TInt err = thread.ExitReason();
       
   527     TEST(err == 0);
       
   528     TExitCategoryName name = thread.ExitCategory();
       
   529     TEST(name == _L("GDI"));    
       
   530     thread.Close();
       
   531     __UHEAP_MARKEND;
       
   532     }
       
   533 
       
   534 
       
   535 void CTFontAndGlyph::OutlineLengthPanics(TInt (*aThreadFun)(TAny*))
       
   536     {   
       
   537     __UHEAP_MARK;
       
   538     RThread thread;
       
   539     TThreadFunction fun(aThreadFun);
       
   540     TAny* ptr = NULL;
       
   541     thread.Create(_L("RGlyphOutlineLengthIterator"), fun, 0x1000, 0x20000, 0x20000, ptr);
       
   542     
       
   543     TRequestStatus status;
       
   544     thread.Logon(status);
       
   545     thread.Resume();  
       
   546     User::WaitForRequest(status);
       
   547     
       
   548     TInt err = thread.ExitReason();
       
   549     TEST(err == 0);
       
   550     TExitCategoryName name = thread.ExitCategory();
       
   551     TEST(name == _L("GDI"));
       
   552     thread.Close();
       
   553     __UHEAP_MARKEND;
       
   554     }
       
   555 
       
   556 /**
       
   557     @SYMTestCaseID    TI18N-GDI-CIT-4089
       
   558     @SYMTestCaseDesc    Try to get glyph outline's length and content when 
       
   559         the glyph is not found in font file.
       
   560     @SYMTestActions    Try to get glyph outline's length and content when 
       
   561         the glyph is not found in font file. This should cause a client panic.
       
   562     @SYMTestExpectedResults    Both cases exit with ExitCategory 'GDI' and 
       
   563     reason code 0.
       
   564 */
       
   565 void CTFontAndGlyph::GlyphOutlineIteratorPanics()
       
   566     {
       
   567     __UHEAP_MARK;
       
   568     OutlinePanics(OutlinePanicThread);
       
   569     OutlineLengthPanics(OutlineLengthPanicThread);
       
   570     __UHEAP_MARKEND;
       
   571     }
       
   572 
       
   573 void CTFontAndGlyph::ConstructL()
       
   574     {    
       
   575     INFO_PRINTF1(_L("Calling CTFontAndGlyph::ConstructL()"));
       
   576     iFontStore = CFontStore::NewL(&User::Heap());
       
   577     LoadOpenFontLibraries(iFontStore);
       
   578     iFontStore->iKPixelWidthInTwips = 11860;
       
   579     iBmp = new (ELeave) CFbsBitmap;
       
   580     User::LeaveIfError(iBmp->Create(TSize(100,100),EGray2));
       
   581     iDevice = CFbsBitmapDevice::NewL(iBmp);
       
   582     iUid = iFontStore->AddFileL(KTestFontFile);
       
   583     TInt err = iDevice->GetNearestFontToMaxHeightInTwips(iFont,iFontSpec,0);
       
   584     if (KErrNone != err)
       
   585         {
       
   586         iFontStore->RemoveFile(iUid);
       
   587         User::Leave(err);
       
   588         }   
       
   589     
       
   590     iBmp2 = new (ELeave) CFbsBitmap;  
       
   591     User::LeaveIfError(iBmp2->Create(TSize(100,100),EGray2));
       
   592     iDevice2 = CFbsBitmapDevice::NewL(iBmp2);
       
   593     iUid2 = iFontStore->AddFileL(KTestFontFile2);
       
   594     err = iDevice2->GetNearestFontToMaxHeightInTwips(iFont2,iFontSpec2,0);    
       
   595     if (KErrNone != err)
       
   596         {
       
   597         iFontStore->RemoveFile(iUid);
       
   598         iFontStore->RemoveFile(iUid2);
       
   599         User::Leave(err);
       
   600         }
       
   601     }
       
   602 
       
   603 void CTFontAndGlyph::CleanEnv()
       
   604     {
       
   605     iDevice->ReleaseFont(iFont); 
       
   606     delete iDevice;
       
   607     delete iBmp;
       
   608     iFontStore->RemoveFile(iUid);
       
   609     
       
   610     iDevice2->ReleaseFont(iFont2); 
       
   611     delete iDevice2;
       
   612     delete iBmp2;
       
   613     iFontStore->RemoveFile(iUid2);
       
   614     
       
   615     delete iFontStore;
       
   616     iDevice = NULL;
       
   617     iBmp = NULL;
       
   618     iFontStore = NULL;
       
   619     
       
   620     iDevice2 = NULL;
       
   621     iBmp2 = NULL;
       
   622     
       
   623     REComSession::FinalClose();
       
   624     }
       
   625 
       
   626 //--------------
       
   627 CTFontAndGlyphStep::CTFontAndGlyphStep()
       
   628     {
       
   629     SetTestStepName(KTFontTableAndGlyphStep);
       
   630     }
       
   631 
       
   632 CTGraphicsBase* CTFontAndGlyphStep::CreateTestL()
       
   633     {
       
   634     return new (ELeave) CTFontAndGlyph(this);
       
   635     }
       
   636 
       
   637 static void LoadOpenFontLibraries(CFontStore* aFontStore)
       
   638     {
       
   639 
       
   640     RImplInfoPtrArray implementationArray;
       
   641     TInt error;
       
   642     TInt ecomerror;
       
   643     TInt ecomnotready;
       
   644     TUid uid = {KUidOpenFontRasterizerPlunginInterface};
       
   645 
       
   646     // Making sure that no race situation arises
       
   647     // If ECom is not ready, give it another chance and try again. if it still doesn't work 
       
   648     // after the third try, then it just carries on quietly and fails... 
       
   649     for (ecomnotready =0; ecomnotready <3; ecomnotready++)
       
   650         {
       
   651         TRAP(ecomerror,REComSession::ListImplementationsL(uid,implementationArray));
       
   652         if (!ecomerror)
       
   653             {
       
   654             break;
       
   655             }
       
   656         else
       
   657             {
       
   658             ecomerror = 0;  
       
   659             User::After(0);
       
   660             }
       
   661         }
       
   662 
       
   663     const TInt availCount = implementationArray.Count();
       
   664     for (TInt count=0;count<availCount;++count)
       
   665         {
       
   666         const CImplementationInformation* info = implementationArray[count];
       
   667         TUid rasterizerUid = info->ImplementationUid();
       
   668         // Create a rasterizer
       
   669         COpenFontRasterizer* rasterizer=0;
       
   670         TRAP(error,rasterizer = COpenFontRasterizer::NewL(rasterizerUid));
       
   671         if (!error)
       
   672             {
       
   673             // Install it in the font store.
       
   674             TRAP(error,aFontStore->InstallRasterizerL(rasterizer));
       
   675             if (error)
       
   676                 {
       
   677                 RDebug::Printf("tfonttableandglyph: failed to load rasterizer."); 
       
   678                 delete rasterizer;
       
   679                 }
       
   680             }
       
   681         }
       
   682     
       
   683     implementationArray.ResetAndDestroy();
       
   684     }
       
   685 
       
   686 static TInt SMPAndWDPSafeTestFun(TAny* /*aParam*/)
       
   687     {
       
   688     CFbsBitmapDevice* device1 = NULL;
       
   689     CFont* font;
       
   690     TInt err = 0;
       
   691     CTrapCleanup* trapCleanup=CTrapCleanup::New();
       
   692     
       
   693     err = RFbsSession::Connect();    
       
   694     if(err != KErrNone)
       
   695         User::Panic(_L("FbsSession connection error"), -1);    
       
   696   
       
   697     CFbsBitmap* bmp = NULL;
       
   698     TRAPD(ret1, bmp = new (ELeave) CFbsBitmap);
       
   699     if (bmp == NULL)
       
   700         User::Panic(_L("new CFbsBitmap error"), -1);
       
   701     err = bmp->Create(TSize(100,100),EGray2);
       
   702     if(err != KErrNone)
       
   703             User::Panic(_L("bitmap creation error"), -1);
       
   704     TRAP(err,device1 = CFbsBitmapDevice::NewL(bmp));
       
   705     if(err != KErrNone)
       
   706         User::Panic(_L("fbs device new error"), -1);
       
   707     TFontSpec fontSpec(KTestFontFaceName,KFontHeight); 
       
   708     err = device1->GetNearestFontToMaxHeightInTwips(font,fontSpec,0);  
       
   709     if(err != KErrNone)
       
   710         User::Panic(_L("Get CFont error"), -1);
       
   711     
       
   712     err = KErrNone; 
       
   713     for(TInt i = 0; i < 100; i++)
       
   714     {
       
   715     RFontTable fontTable;
       
   716     err = fontTable.Open(*font, 0x68656164);
       
   717     if (KErrNone != err)
       
   718         {
       
   719         User::Panic(_L("Font table opening failed with error"), err);
       
   720         }
       
   721     TUint32* ptr = (TUint32*)fontTable.TableContent();
       
   722     if (ptr == NULL)
       
   723         {
       
   724         User::Panic(_L("Font table content NULL"), -1);
       
   725         }
       
   726     fontTable.Close();
       
   727     }
       
   728 
       
   729     delete device1;
       
   730     delete bmp;
       
   731     delete trapCleanup;
       
   732     device1 = NULL;
       
   733     bmp = NULL;
       
   734     return err;
       
   735     }
       
   736 
       
   737 /**
       
   738     @SYMTestCaseID    TI18N-GDI-CIT-4090
       
   739     @SYMTestCaseDesc    Test if the new code is SMP and WDP safe. 
       
   740     @SYMTestActions    Create two threads to access the new interfaces concurrently.
       
   741     @SYMTestExpectedResults    The threads run to the end correctly. All the
       
   742     Open() operations succeed.
       
   743 */
       
   744 void CTFontAndGlyph::SMPAndWDPSafeTest()
       
   745     {
       
   746     RThread thread1;
       
   747     RThread thread2;
       
   748     TThreadFunction fun(SMPAndWDPSafeTestFun);
       
   749     
       
   750     TInt ret1 = thread1.Create(_L("SMPAndWDPSafeThread1"), fun, 0x2000, 0x20000, 0x80000, iFontStore);
       
   751 	TEST(KErrNone == ret1);
       
   752     TInt ret2 = thread2.Create(_L("SMPAndWDPSafeThread2"), fun, 0x2000, 0x20000, 0x80000, iFontStore);
       
   753 	TEST(KErrNone == ret2);
       
   754     
       
   755     TRequestStatus status1;
       
   756     TRequestStatus status2;
       
   757     thread1.Logon(status1);
       
   758     thread2.Logon(status2);
       
   759     thread1.Resume(); 
       
   760     thread2.Resume(); 
       
   761     User::WaitForRequest(status1);
       
   762     User::WaitForRequest(status2);
       
   763     
       
   764     TEST(EExitKill == thread1.ExitType());
       
   765     TEST(KErrNone == thread1.ExitReason());
       
   766     TEST(EExitKill == thread2.ExitType());
       
   767     TEST(KErrNone == thread2.ExitReason());
       
   768     
       
   769     thread1.Close();
       
   770     thread2.Close();
       
   771     }