--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/fontservices/freetypefontrasteriser/test/testharness.cpp Tue Feb 02 02:02:46 2010 +0200
@@ -0,0 +1,518 @@
+/*
+* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include "testharness.h"
+#include <bitdev.h>
+#include <fntstore.h>
+#include <fbs.h>
+#include <test/testexecutestepbase.h>
+#include <graphics/fbsdefs.h>
+
+CTestHarness::CTestHarness(CTestStep* aStep) :
+ iStep(aStep)
+ {
+ iStep -> INFO_PRINTF1(iStep -> TestStepName());
+ }
+
+CTestHarness* CTestHarness::NewL(CTestStep* aStep)
+ {
+ CTestHarness* t = new (ELeave)CTestHarness (aStep);
+ CleanupStack::PushL(t);
+ t->ConstructL();
+ CleanupStack::Pop();
+ return t;
+ }
+
+void CTestHarness::ConstructL()
+ {
+ User::LeaveIfError(FbsStartup());
+
+ RFbsSession::Connect();
+ iFbs = RFbsSession::GetSession();
+ if (iFbs == NULL)
+ User::Leave(KErrGeneral);
+
+ TRAPD(error, iDev = CFbsScreenDevice::NewL(_L("scdv"),EColor16M));
+ if (error == KErrNotSupported)
+ TRAP(error, iDev = CFbsScreenDevice::NewL(_L("scdv"),EColor16MA));
+ if (error == KErrNotSupported)
+ TRAP(error, iDev = CFbsScreenDevice::NewL(_L("scdv"),EColor16MU));
+ if (error == KErrNotSupported)
+ TRAP(error, iDev = CFbsScreenDevice::NewL(_L("scdv"),EColor64K));
+ if (error == KErrNotSupported)
+ TRAP(error, iDev = CFbsScreenDevice::NewL(_L("scdv"),EColor4K));
+ if (error == KErrNotSupported)
+ TRAP(error, iDev = CFbsScreenDevice::NewL(_L("scdv"),EColor256));
+ if (error == KErrNotSupported)
+ TRAP(error, iDev = CFbsScreenDevice::NewL(_L("scdv"),EColor16));
+ if (error == KErrNotSupported)
+ TRAP(error, iDev = CFbsScreenDevice::NewL(_L("scdv"),EGray256));
+ if (error == KErrNotSupported)
+ TRAP(error, iDev = CFbsScreenDevice::NewL(_L("scdv"),EGray16));
+ if (error == KErrNotSupported)
+ TRAP(error, iDev = CFbsScreenDevice::NewL(_L("scdv"),EGray4));
+ if (error == KErrNotSupported)
+ TRAP(error, iDev = CFbsScreenDevice::NewL(_L("scdv"),EGray2));
+ if (error == KErrNotSupported)
+ TRAP(error, iDev = CFbsScreenDevice::NewL(_L("scdv"),EColor16MAP));
+
+ if(error == KErrNone)
+ {
+ iDev->ChangeScreenDevice(NULL);
+ iDev->SetAutoUpdate(ETrue);
+ iDev->CreateContext(iGc);
+
+ TFontSpec fs(_L("DejaVu Sans Condensed"),16);
+ error = iDev->GetNearestFontToDesignHeightInPixels((CFont*&)iStandardFont,fs);
+ if (error)
+ User::Panic(_L("Could not create 16-pixel DejaVu Sans Condensed"),error);
+ }
+ }
+
+CTestHarness::~CTestHarness()
+ {
+ if (iStandardFont)
+ iDev->ReleaseFont(iStandardFont);
+ delete iGc;
+ delete iDev;
+ RFbsSession::Disconnect();
+ }
+
+void CTestHarness::PerformTests()
+ {
+ iStep->INFO_PRINTF1(_L("Test started"));
+
+ TInt typefaces = iDev->NumTypefaces();
+ for (int typeface = 0; typeface < typefaces; typeface++)
+ {
+ TestFont(typeface);
+ }
+
+ iStep->INFO_PRINTF1(_L("Test ended"));
+ }
+
+void CTestHarness::TestFont(TInt aTypeface)
+ {
+ TTypefaceSupport support;
+ iDev->TypefaceSupport(support,aTypeface);
+
+ TBuf<50> testInfo;
+ testInfo.Append(_L("Testing typeface: "));
+ testInfo.Append(support.iTypeface.iName);
+ iStep->INFO_PRINTF1(testInfo);
+
+ const TInt pointsizes = 9;
+ static TInt pointsize[pointsizes] = { 8, 10, 12, 14, 16, 20, 24, 48, 200 };
+ TInt i = 0;
+ for (i = 0; i < (pointsizes-2); i++)
+ {
+ TestFontDisplayAtSize(support, pointsize[i], i & 1);
+ }
+
+ TestFontMetricsDiagram(support, pointsize[i], i & 1);
+ i++;
+
+ TestFontHugeCharacters(support, pointsize[i], i & 1);
+ }
+
+void CTestHarness::TestFontDisplayAtSize(TTypefaceSupport& aSupport, TInt aPointSize, TBool aItalic)
+ {
+ TBuf<50> testInfo;
+ testInfo.Append(_L("Testing font size: "));
+ TBuf<10> num;
+ num.Num(aPointSize);
+ testInfo.Append(num);
+ iStep->INFO_PRINTF1(testInfo);
+
+ TFontSpec fs;
+
+ fs.iTypeface = aSupport.iTypeface;
+ fs.iHeight = aPointSize * 20;
+ if (aItalic)
+ {
+ fs.iFontStyle.SetPosture(EPostureItalic);
+ }
+ iTestFont = NULL;
+ TInt error = iDev->GetNearestFontToDesignHeightInTwips((CFont*&)iTestFont,fs);
+ if (error)
+ User::Panic(_L("Could not create font"),error);
+ if (!iTestFont->IsOpenFont())
+ {
+ iDev->ReleaseFont(iTestFont);
+ iTestFont = NULL;
+ return;
+ }
+ PrintMetrics();
+ DisplayFont();
+ iDev->ReleaseFont(iTestFont);
+ }
+
+void CTestHarness::TestFontMetricsDiagram(TTypefaceSupport& aSupport, TInt aPointSize, TBool aItalic)
+ {
+ TBuf<50> testInfo;
+ testInfo.Append(_L("Testing font metrics: "));
+ TBuf<10> num;
+ num.Num(aPointSize);
+ testInfo.Append(num);
+ iStep->INFO_PRINTF1(testInfo);
+
+ TFontSpec fs;
+ fs.iTypeface = aSupport.iTypeface;
+ fs.iHeight = aPointSize * 20;
+ if (aItalic)
+ {
+ fs.iFontStyle.SetPosture(EPostureItalic);
+ }
+ iTestFont = NULL;
+ TInt error = iDev->GetNearestFontToDesignHeightInTwips((CFont*&)iTestFont,fs);
+ if (error)
+ User::Panic(_L("Could not create font"),error);
+ if (!iTestFont->IsOpenFont())
+ {
+ iDev->ReleaseFont(iTestFont);
+ iTestFont = NULL;
+ return;
+ }
+ PrintMetrics();
+ DrawMetricsDiagram();
+ iDev->ReleaseFont(iTestFont);
+ }
+
+void CTestHarness::TestFontHugeCharacters(TTypefaceSupport& aSupport, TInt aPointSize, TBool aItalic)
+ {
+ TBuf<50> testInfo;
+ testInfo.Append(_L("Testing huge characters: "));
+ TBuf<10> num;
+ num.Num(aPointSize);
+ testInfo.Append(num);
+ iStep->INFO_PRINTF1(testInfo);
+
+ TFontSpec fs;
+ fs.iTypeface = aSupport.iTypeface;
+ fs.iHeight = aPointSize * 20;
+ if (aItalic)
+ fs.iFontStyle.SetPosture(EPostureItalic);
+ iTestFont = NULL;
+ TInt error = iDev->GetNearestFontToDesignHeightInTwips((CFont*&)iTestFont,fs);
+ if (error)
+ User::Panic(_L("Could not create font"),error);
+ if (!iTestFont->IsOpenFont())
+ {
+ iDev->ReleaseFont(iTestFont);
+ iTestFont = NULL;
+ return;
+ }
+ PrintMetrics();
+ DrawHugeCharacters();
+ iDev->ReleaseFont(iTestFont);
+ }
+
+static void Hellenize(TDes16& text)
+ {
+ static const TUint16* roman = (TUint16*)(L"ABGDEZJQIKLMNXOPRVSTUFHCW");
+
+ for (int i = 0; i < text.Length(); i++)
+ for (int j = 0; j < 25; j++)
+ if (roman[j] == text[i])
+ {
+ text[i] = (TUint16)(0x391 + j);
+ break;
+ }
+ else if (roman[j] + 32 == text[i])
+ {
+ text[i] = (TUint16)(0x3B1 + j);
+ break;
+ }
+ }
+
+void CTestHarness::PrintMetrics(TBool isClear)
+ {
+ if(isClear)
+ {
+ Clear();
+ }
+
+ UseFont(iStandardFont);
+ TFontSpec fs = iTestFont->FontSpecInTwips();
+ TOpenFontMetrics metrics;
+ iTestFont->GetFontMetrics(metrics);
+ TOpenFontFaceAttrib attrib;
+ iTestFont->GetFaceAttrib(attrib);
+ TPtrC name = attrib.LocalFullName();
+ iBuffer.Format(_L("%S %dpt size=%d ascent=%d descent=%d maxheight=%d maxdepth=%d maxwidth=%d"),
+ &name,(fs.iHeight + 10) / 20,metrics.Size(),metrics.Ascent(),metrics.Descent(),
+ metrics.MaxHeight(),metrics.MaxDepth(),metrics.MaxWidth());
+ Print(iBuffer);
+ }
+
+void CTestHarness::DisplayFont()
+ {
+ UseFont(iStandardFont);
+ TOpenFontFaceAttrib attrib;
+ iTestFont->GetFaceAttrib(attrib);
+ iBuffer.SetLength(0);
+ if (attrib.HasLatin())
+ iBuffer.Append(_L("Latin, "));
+ if (attrib.HasGreek())
+ iBuffer.Append(_L("Greek, "));
+ if (attrib.HasCyrillic())
+ iBuffer.Append(_L("Cyrillic, "));
+ if (attrib.HasKana())
+ iBuffer.Append(_L("Kana (Japanese syllabaries), "));
+ if (attrib.HasHangul())
+ iBuffer.Append(_L("Hangul (Korean writing system), "));
+ if (attrib.HasCJK())
+ iBuffer.Append(_L("CJK (Chinese, Japanese & Korean ideographs), "));
+ if (iBuffer.Length() == 0)
+ iBuffer.Append(_L("(character sets unknown)"));
+ else
+ iBuffer.SetLength(iBuffer.Length() - 2);
+ Print(iBuffer);
+
+ UseFont(iTestFont);
+
+ // Benchmark the rasterization of Ascii printable characters.
+ const int count = 126 - 33 + 1;
+ iBuffer.SetLength(count);
+ int i;
+ for (i = 0; i < count; i++)
+ iBuffer[i] = (TText)(i + 33);
+ TTime start, end;
+ start.HomeTime();
+ iTestFont->RawTextWidthInPixels(iBuffer);
+ end.HomeTime();
+ TTimeIntervalMicroSeconds time64 = end.MicroSecondsFrom(start);
+ int time = I64INT(time64.Int64());
+
+ start.HomeTime();
+ for (i = 0; i < 100; i++)
+ iTestFont->RawTextWidthInPixels(iBuffer);
+ end.HomeTime();
+ time64 = end.MicroSecondsFrom(start);
+ int overhead = I64INT(time64.Int64()) / 100;
+ time -= overhead;
+ if (time <= 0)
+ time = 1;
+
+ iBuffer.Format(_L("%d characters rasterized per second"),
+ count * 1000000 / time);
+ Print(iBuffer);
+ iBuffer.UpperCase();
+ Print(iBuffer);
+ iBuffer = _L("sm\xf6rg\xe5sbord soup\xe7on na\xefvet\xe9");
+ Print(iBuffer);
+ iBuffer.UpperCase();
+ Print(iBuffer);
+
+ if (attrib.HasGreek())
+ {
+ iBuffer = _L("agjwmetrjsewv mjdeiv eisitw");
+ Hellenize(iBuffer);
+ Print(iBuffer);
+ iBuffer.UpperCase();
+ Print(iBuffer);
+ }
+ if (attrib.HasCyrillic())
+ {
+ iBuffer.SetLength(32);
+ for (int i = 0; i < 32; i++)
+ iBuffer[i] = (TText)(0x430 + i);
+ Print(iBuffer);
+ iBuffer.UpperCase();
+ Print(iBuffer);
+ }
+ if (attrib.HasKana())
+ {
+ iBuffer.SetLength(32);
+ int i;
+ for (i = 0; i < 32; i++)
+ iBuffer[i] = (TText)(0x3041 + i);
+ Print(iBuffer);
+ for (i = 0; i < iBuffer.Length(); i++)
+ iBuffer[i] = (TText)User::Fold(iBuffer[i],TChar::EFoldKana); // fold to katakana
+ Print(iBuffer);
+ }
+ if (attrib.HasHangul())
+ {
+ iBuffer.SetLength(32);
+ for (int i = 0; i < 32; i++)
+ iBuffer[i] = (TText)(0x3131 + i);
+ Print(iBuffer);
+ }
+
+ // Display characters from 4e00 that are found in all 6 encodings given in the Unicode table.
+ if (attrib.HasCJK())
+ {
+ iBuffer.SetLength(15);
+ iBuffer[0] = 0x4e00;
+ iBuffer[1] = 0x4e01;
+ iBuffer[2] = 0x4e03;
+ iBuffer[3] = 0x4e07;
+ iBuffer[4] = 0x4e08;
+ iBuffer[5] = 0x4e09;
+ iBuffer[6] = 0x4e0a;
+ iBuffer[7] = 0x4e0b;
+ iBuffer[8] = 0x4e0d;
+ iBuffer[9] = 0x4e11;
+ iBuffer[10] = 0x4e14;
+ iBuffer[11] = 0x4e15;
+ iBuffer[12] = 0x4e16;
+ iBuffer[13] = 0x4e18;
+ iBuffer[14] = 0x4e19;
+ Print(iBuffer);
+ }
+
+ iGc->DiscardFont();
+ }
+
+void CTestHarness::DrawCharMetrics(TPoint& aPos,TInt aCode)
+ {
+ TOpenFontCharMetrics metrics;
+ const TUint8* bytes;
+ TSize size;
+ iTestFont->GetCharacterData(aCode,metrics,bytes,size);
+ TRect r;
+ r.iTl = aPos;
+ r.iTl.iX += metrics.HorizBearingX();
+ r.iTl.iY += iBaseLine;
+ r.iTl.iY -= metrics.HorizBearingY();
+ r.iBr = r.iTl + TSize(metrics.Width(),metrics.Height());
+ iGc->DrawRect(r);
+ aPos.iX += metrics.HorizAdvance();
+ }
+
+void CTestHarness::DrawMetricsDiagram()
+ {
+ UseFont(iTestFont);
+ iBuffer = _L("Dig my crazy metrics!");
+ iPrintPos.iX += 8;
+ TPoint pos = iPrintPos;
+ Print(iBuffer);
+ TPoint baseline_start = pos;
+ baseline_start.iY += iBaseLine;
+ for (int i = 0; i < iBuffer.Length(); i++)
+ DrawCharMetrics(pos,iBuffer[i]);
+ TPoint baseline_end = pos;
+ baseline_end.iY += iBaseLine;
+ iGc->DrawLine(baseline_start,baseline_end);
+ iGc->DiscardFont();
+ //iTest.Getch();
+ }
+
+void CTestHarness::DrawHugeCharacters()
+ {
+ UseFont(iTestFont);
+ iBuffer = _L("ABC123");
+ TOpenFontCharMetrics metrics;
+ const TUint8* bytes;
+ TSize size;
+ iTestFont->GetCharacterData('A',metrics,bytes,size);
+ iBaseLine = metrics.HorizBearingY();;
+ Print(iBuffer);
+ iGc->DiscardFont();
+ //iTest.Getch();
+ }
+
+void CTestHarness::Clear()
+ {
+ TRect r(iDev->SizeInPixels());
+ iGc->Clear(r);
+ iPrintPos = TPoint(0,0);
+ }
+
+void CTestHarness::Print(const TDesC& aText)
+ {
+ TPoint p = iPrintPos;
+ p.iY += iBaseLine;
+ iGc->DrawText(aText,p);
+ iPrintPos.iX = 0;
+ iPrintPos.iY += iLineHeight;
+ }
+
+void CTestHarness::UseFont(CFbsFont* aFont)
+ {
+ iGc->UseFont(aFont);
+ TOpenFontMetrics metrics;
+ aFont->GetFontMetrics(metrics);
+ iBaseLine = metrics.MaxHeight();
+ iLineHeight = metrics.MaxHeight() + metrics.MaxDepth();
+ }
+
+/*
+@SYMTestCaseID GRAPHICS-FREETYPE-0001
+@SYMTestCaseDesc Supplementary characters rasterization Test
+@SYMTestPriority High
+@SYMTestActions This test checks that the free type rasterizer rasterizes supplementary characters
+properly.
+It prints the descriptor containing supplementary characters with 2 Fonts. One font does not support
+supplementary characters and the other does.
+@SYMTestExpectedResults This step should be executed without error and the user should be able to see the
+above descriptor is displayed as a square with the first font and in the correct shape with the other font.
+@SYMDEF DEF120018 Security issue in FreeType rasterizer! Supplementary characters rendered as BMP
+*/
+void CTestHarness::SurrogateRasterizedTestsL()
+ {
+ // The literal descriptor consisting of common letter 'A' and Supplementary character 0x20000
+ // which is represented by surrogate pair 0xD840 0xDC00
+ _LIT16(KSurrogatePairCode, "A\xD840\xDC00");
+
+ // Testing Fonts: DejaVu Sans Condensed does not support Supplementary character.
+ // Test2 only supports letter "A" and Supplementary character 0x20000
+ TFontSpec fsDejaVuSans(_L("DejaVu Sans Condensed"), 16 * 20);
+ TFontSpec fsTest2(_L("Test2"), 16 * 20);
+
+ Clear();
+
+ // Prints test descriptor with font SwissA
+ iTestFont = NULL;
+ TInt error = iDev->GetNearestFontToDesignHeightInTwips((CFont*&)iTestFont,fsDejaVuSans);
+ iStep->TESTL(KErrNone == error);
+
+ if (!iTestFont->IsOpenFont())
+ {
+ iDev->ReleaseFont(iTestFont);
+ iTestFont = NULL;
+ User::Leave(KErrGeneral);
+ }
+ PrintMetrics(EFalse);
+
+ UseFont(iTestFont);
+ Print(KSurrogatePairCode);
+ iDev->ReleaseFont(iTestFont);
+
+ // Prints test descriptor with font Test2
+ iTestFont = NULL;
+ error = iDev->GetNearestFontToDesignHeightInTwips((CFont*&)iTestFont,fsTest2);
+ iStep->TESTL(KErrNone == error);
+
+ if (!iTestFont->IsOpenFont())
+ {
+ iDev->ReleaseFont(iTestFont);
+ iTestFont = NULL;
+ User::Leave(KErrGeneral);
+ }
+ PrintMetrics(EFalse);
+
+ UseFont(iTestFont);
+ Print(KSurrogatePairCode);
+ iDev->ReleaseFont(iTestFont);
+ iTestFont = NULL;
+
+// User::After(10000000);
+ }
+