--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textrendering/textformatting/test/src/TInterpreter.cpp Tue Feb 02 02:02:46 2010 +0200
@@ -0,0 +1,314 @@
+/*
+* Copyright (c) 2003-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:
+* TInterpreter.cpp unit tests for RTmBoundingRectInterpreter
+*
+*/
+
+
+#include "TestPicture.h"
+#include "TestLayout.h"
+#include "TGraphicsContext.h"
+#include "TMINTERP.H"
+
+#include <txtrich.h>
+#include <e32test.h>
+
+_LIT(KLeftToRight1, "abc \x5D0 def abc \x5D0\x5D1\x5D2 \x5D0\x5D1\x5D2 xyz abc a\tb\tc\td\te.");
+_LIT(KLeftToRight2, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
+_LIT(KContingentBreak, "\xFFFC");
+
+/**
+Checks if one region is a subset of another.
+@param aRegion
+ The potential superset.
+@param aPotentialSubset
+ The potential subset.
+@return
+ ETrue if and only if aPotentialSubset is contained within aRegion.
+@internalComponent
+*/
+TBool IsSubsetL(const TRegion& aRegion, const TRegion& aPotentialSubset)
+ {
+ RRegion sub;
+ sub.Copy(aPotentialSubset);
+ sub.SubRegion(aRegion);
+ if (sub.CheckError())
+ User::Leave(KErrNoMemory);
+ return sub.IsEmpty();
+ }
+
+/**
+Checks if two regions are equal.
+@param aA First region.
+@param aB Second region.
+@return
+ ETrue if the regions are equal, false otherwise.
+@internalComponent
+*/
+TBool RegionsEqualL(const TRegion& aA, const TRegion& aB)
+ {
+ return IsSubsetL(aA, aB) && IsSubsetL(aB, aA);
+ }
+
+/**
+Gets the region corresponding to the selection. Builds it up by adding
+selections together. The selections are at (n * aStartStep, aEnd + n *
+aEndStep) for n <- {0, 1, 2...}. The iteration ends when either the start would
+be beyond the length of the document or when the start is at 0 and the end is
+beyond the length of the document.
+@param aRegion Returns the region.
+@param aLayout The layout to get the selection of.
+@param aStartStep How different the starts of successive selections are.
+@param aEnd The end of the first selection.
+@param aEndStep How different the ends of the successive selections are.
+
+@internalComponent
+*/
+void GetSelectionL(TRegion& aRegion, CTestTmTextLayout& aLayout,
+ TInt aStartStep, TInt aEnd, TInt aEndStep)
+ {
+ aRegion.Clear();
+ TRect rect;
+ TInt documentLength = aLayout.Source().DocumentLength();
+ TInt start = 0;
+ while (start < documentLength && !(documentLength < aEnd && start == 0))
+ {
+ TTmInterpreterParam param(aLayout.Layout());
+ RTmBoundingRectInterpreter interp(aLayout.Source(), param);
+ if (interp.FirstRect(start, aEnd, rect))
+ {
+ aRegion.AddRect(rect);
+ while (interp.NextRect(rect))
+ aRegion.AddRect(rect);
+ }
+ start += aStartStep;
+ aEnd += aEndStep;
+ interp.Close();
+ }
+ if (aRegion.CheckError())
+ User::Leave(KErrNoMemory);
+ }
+
+/**
+Tests RTmBoundingRectInterpreter for a particular piece of text.
+@internalComponent
+*/
+void TestTextL(RTest& aTest, CTestTmTextLayout& aLayout)
+ {
+ RRegion region1;
+ RRegion region2;
+ RRegion region3;
+ CleanupClosePushL(region1);
+ CleanupClosePushL(region2);
+ CleanupClosePushL(region3);
+
+ GetSelectionL(region1, aLayout, 1, 1, 1);
+ GetSelectionL(region2, aLayout, 0, 1, 1);
+ GetSelectionL(region3, aLayout, 0, aLayout.Source().DocumentLength(), 1);
+
+ aTest(RegionsEqualL(region1, region2));
+ aTest(RegionsEqualL(region1, region3));
+
+ CleanupStack::PopAndDestroy(®ion3);
+ CleanupStack::PopAndDestroy(®ion2);
+ CleanupStack::PopAndDestroy(®ion1);
+ }
+
+
+void TestsL(RTest& aTest)
+ {
+ CParaFormatLayer* paraLayer = CParaFormatLayer::NewL();
+ CleanupStack::PushL(paraLayer);
+ CCharFormatLayer* charLayer = CCharFormatLayer::NewL();
+ CleanupStack::PushL(charLayer);
+ CRichText* richText = CRichText::NewL(paraLayer, charLayer);
+ CleanupStack::PushL(richText);
+
+ aTest.Next(_L("RTmBoundingRectInterpreter consistency of coverage"));
+ richText->Reset();
+ richText->InsertL(0, KLeftToRight1);
+ CTestTmTextLayout* text1 = CTestTmTextLayout::NewLC(*richText, 100);
+ TSize pictureSize(15, 15);
+ CTestPicture* picture = new (ELeave) CTestPicture;
+ picture->SetSizeInPixels( pictureSize, text1->Device() );
+ TPictureHeader pictureHeader;
+ pictureHeader.iPicture = picture;
+ pictureHeader.iSize = pictureSize;
+ richText->InsertL(19, pictureHeader);
+ TTmReformatParam param;
+ param.iStartChar = 19;
+ param.iOldLength = 0;
+ param.iNewLength = 1;
+ param.iMaxExtraLines = KMaxTInt;
+ param.iParFormatChanged = ETrue;
+ param.iParInvalid = EFalse;
+ TTmReformatResult out;
+ text1->FormatL(param, out);
+ TestTextL(aTest, *text1);
+
+ //Test for finding text chunks adjoining a given document position
+ text1->TestAdjacentChunks();
+
+ CleanupStack::PopAndDestroy(text1);
+ CleanupStack::PopAndDestroy(richText);
+ CleanupStack::PopAndDestroy(charLayer);
+ CleanupStack::PopAndDestroy(paraLayer);
+ }
+
+
+/**
+@SYMTestCaseID SYSLIB-FORM-UT-1591
+@SYMTestCaseDesc Tests to make sure when contingent line breaks, "\xFFFC", are inserted into richtext
+ (with and without a picture attached) and FormatL is called it does not lead to a
+ panic in 'IsLegalBreakBeforeL' or 'IsLegalBreakAfterL'.
+@SYMTestPriority High
+@SYMTestActions Insert some richtext, then insert a TPictureHeader into the text (which inserts a
+ contingent line break), then call FormatL. Then insert just a contingent line break,
+ with no TPictureHeader associated with it and call FormatL (for IsLegalBreakAfterL).
+ Then repeat the process, but making sure the text is scanned in the opposite
+ direction, so IsLegalBreakBeforeL is called.
+@SYMTestExpectedResults Test must not fail
+@SYMDEF DEF077884
+*/
+
+void Def077884L(RTest& aTest)
+ {
+ TInt testStartLength = 52;
+ TInt testEndLength = 56;
+
+ CParaFormatLayer* paraLayer = CParaFormatLayer::NewL();
+ CleanupStack::PushL(paraLayer);
+ CCharFormatLayer* charLayer = CCharFormatLayer::NewL();
+ CleanupStack::PushL(charLayer);
+ CRichText* richText = CRichText::NewL(paraLayer, charLayer);
+ CleanupStack::PushL(richText);
+
+ aTest.Next(_L(" @SYMTestCaseID:SYSLIB-FORM-UT-1591 DEF077884: TSourcePictureBreaker crashes when picture not found. "));
+
+
+ richText->Reset();
+
+ richText->InsertL(0, KLeftToRight2);
+
+ aTest(testStartLength == richText->DocumentLength());
+
+ CTestTmTextLayout* text1 = CTestTmTextLayout::NewLC(*richText, 100);
+
+ TTmReformatResult out;
+ TTmReformatParam param;
+ param.iStartChar = 0;
+ param.iOldLength = 0;
+ param.iNewLength = 1;
+ param.iMaxExtraLines = KMaxTInt;
+ param.iParFormatChanged = ETrue;
+ param.iParInvalid = EFalse;
+
+ richText->InsertL(14, KContingentBreak); // Insert a contingent linebreak with no picture
+
+ text1->FormatL(param, out); // Scans the text from right to left.
+
+
+ TSize pictureSize(100, 100);
+ CTestPicture* picture = new (ELeave) CTestPicture;
+ picture->SetSizeInPixels(pictureSize, text1->Device());
+
+ TPictureHeader pictureHeader;
+ pictureHeader.iPicture = picture;
+ pictureHeader.iSize = pictureSize;
+
+ richText->InsertL(15, pictureHeader); // Insert a contingent linebreak with picture
+
+ param.iOldLength = 1;
+ param.iNewLength = 2;
+
+ text1->FormatL(param, out); // Scans the text from right to left.
+
+
+ TTmFormatParam formatParam;
+ formatParam.iFlags = 0;
+ // iFlags now need to be set to make sure the text is scanned in the opposite direction when
+ // FormatL is called.
+ formatParam.iFlags = formatParam.iFlags | TTmFormatParamBase::ELegalLineBreaksOnly;
+ formatParam.iFlags = formatParam.iFlags | TTmFormatParamBase::EWrap;
+ formatParam.iWrapWidth = 12;
+ formatParam.iMaxHeight = 100;
+ formatParam.iMaxLines = 10;
+ formatParam.iEllipsis = 0xFFFF;
+ formatParam.iStartChar = 0;
+ formatParam.iEndChar = 50;
+ formatParam.iLineInPar = 0;
+
+ param.iOldLength = 2;
+ param.iNewLength = 3;
+
+ CTmTextLayout* text2 = new (ELeave) CTmTextLayout;
+
+ text2->SetTextL(text1->Source(),formatParam);
+
+ richText->InsertL(28, KContingentBreak); // Insert a contingent linebreak with no picture
+
+ text2->FormatL(formatParam, param, out); // Scans the text from left to right.
+
+
+ CTestPicture* picture2 = new (ELeave) CTestPicture;
+ picture2->SetSizeInPixels( pictureSize, text1->Device() );
+
+ TPictureHeader pictureHeader2;
+ pictureHeader2.iPicture = picture2;
+ pictureHeader2.iSize = pictureSize;
+
+ richText->InsertL(34, pictureHeader2); // Insert a contingent linebreak with picture
+
+ param.iOldLength = 3;
+ param.iNewLength = 4;
+
+ text2->FormatL(formatParam, param, out); // Scans the text from left to right.
+
+
+ TestTextL(aTest, *text1);
+
+ aTest(testEndLength == richText->DocumentLength());
+
+ CleanupStack::PopAndDestroy(text1);
+ CleanupStack::PopAndDestroy(richText);
+ CleanupStack::PopAndDestroy(charLayer);
+ CleanupStack::PopAndDestroy(paraLayer);
+ }
+
+/**
+Tests RTmBoundingRectInterpreter.
+@internalComponent
+*/
+void RunTestsL(RTest& aTest)
+ {
+ TestsL(aTest);
+ Def077884L(aTest);
+ }
+
+/**
+Tests RTmBoundingRectInterpreter.
+@internalComponent
+*/
+TInt E32Main()
+ {
+ RTest rtest(_L("TInterpreter unit"));
+ CTrapCleanup* TrapCleanup = CTrapCleanup::New();
+ rtest.Start(_L("Start TInterpreter.exe Tests"));
+ TRAPD(err, RunTestsL(rtest));
+ rtest.End();
+ delete TrapCleanup;
+ return err;
+ }
+