textrendering/textformatting/test/src/TGraphemeIterator.cpp
branchRCL_3
changeset 16 748ec5531811
parent 0 1fb32624e06b
child 17 336bee5c2d35
equal deleted inserted replaced
10:f902e87c146f 16:748ec5531811
     1 /*
     1 /*
     2 * Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 * Copyright (c) 2003-2010 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     4 * This component and the accompanying materials are made available
     5 * under the terms of "Eclipse Public License v1.0"
     5 * under the terms of "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
    19 
    19 
    20 #include "TestLayout.h"
    20 #include "TestLayout.h"
    21 #include "TGraphicsContext.h"
    21 #include "TGraphicsContext.h"
    22 #include "TMINTERP.H"
    22 #include "TMINTERP.H"
    23 
    23 
    24 #include <e32test.h>
    24 #include "tgraphemeiterator.h"
       
    25 
       
    26 namespace LocalToTGraphemeIterator
       
    27 {
       
    28 CTGraphemeIteratorStep* TestStep;
       
    29 #define TESTPOINT(p) TestStep->testpoint(p,(TText8*)__FILE__,__LINE__)
       
    30 #define TESTPRINT(p) TestStep->print(p,(TText8*)__FILE__,__LINE__)
    25 
    31 
    26 struct TTransliteration
    32 struct TTransliteration
    27 	{
    33     {
    28 	const TText* iString;
    34     const TText* iString;
    29 	TInt iChar;
    35     TInt iChar;
    30 	};
    36     };
    31 static const TTransliteration KArabicTransliteration[] =
    37 static const TTransliteration KArabicTransliteration[] =
    32 	{
    38     {
    33 	{ reinterpret_cast<const TText*>(L"?"), 0x61F },
    39     { reinterpret_cast<const TText*>(L"?"), 0x61F },
    34 	{ reinterpret_cast<const TText*>(L"`"), 0x621 },	// in-line hamza
    40     { reinterpret_cast<const TText*>(L"`"), 0x621 },    // in-line hamza
    35 	{ reinterpret_cast<const TText*>(L"a"), 0x627 },	// alif
    41     { reinterpret_cast<const TText*>(L"a"), 0x627 },    // alif
    36 	{ reinterpret_cast<const TText*>(L"b"), 0x628 },
    42     { reinterpret_cast<const TText*>(L"b"), 0x628 },
    37 	{ reinterpret_cast<const TText*>(L"A"), 0x629 },	// teh marbuta
    43     { reinterpret_cast<const TText*>(L"A"), 0x629 },    // teh marbuta
    38 	{ reinterpret_cast<const TText*>(L"t"), 0x62A },
    44     { reinterpret_cast<const TText*>(L"t"), 0x62A },
    39 	{ reinterpret_cast<const TText*>(L"th"), 0x62B },
    45     { reinterpret_cast<const TText*>(L"th"), 0x62B },
    40 	{ reinterpret_cast<const TText*>(L"j"), 0x62C },
    46     { reinterpret_cast<const TText*>(L"j"), 0x62C },
    41 	{ reinterpret_cast<const TText*>(L"H"), 0x62D },	// hah
    47     { reinterpret_cast<const TText*>(L"H"), 0x62D },    // hah
    42 	{ reinterpret_cast<const TText*>(L"kh"), 0x62E },
    48     { reinterpret_cast<const TText*>(L"kh"), 0x62E },
    43 	{ reinterpret_cast<const TText*>(L"d"), 0x62F },
    49     { reinterpret_cast<const TText*>(L"d"), 0x62F },
    44 	{ reinterpret_cast<const TText*>(L"dh"), 0x630 },
    50     { reinterpret_cast<const TText*>(L"dh"), 0x630 },
    45 	{ reinterpret_cast<const TText*>(L"r"), 0x631 },
    51     { reinterpret_cast<const TText*>(L"r"), 0x631 },
    46 	{ reinterpret_cast<const TText*>(L"z"), 0x632 },
    52     { reinterpret_cast<const TText*>(L"z"), 0x632 },
    47 	{ reinterpret_cast<const TText*>(L"s"), 0x633 },
    53     { reinterpret_cast<const TText*>(L"s"), 0x633 },
    48 	{ reinterpret_cast<const TText*>(L"sh"), 0x634 },
    54     { reinterpret_cast<const TText*>(L"sh"), 0x634 },
    49 	{ reinterpret_cast<const TText*>(L"S"), 0x635 },
    55     { reinterpret_cast<const TText*>(L"S"), 0x635 },
    50 	{ reinterpret_cast<const TText*>(L"D"), 0x636 },
    56     { reinterpret_cast<const TText*>(L"D"), 0x636 },
    51 	{ reinterpret_cast<const TText*>(L"T"), 0x637 },
    57     { reinterpret_cast<const TText*>(L"T"), 0x637 },
    52 	{ reinterpret_cast<const TText*>(L"Z"), 0x638 },	// zah
    58     { reinterpret_cast<const TText*>(L"Z"), 0x638 },    // zah
    53 	{ reinterpret_cast<const TText*>(L"'"), 0x639 },	// ain
    59     { reinterpret_cast<const TText*>(L"'"), 0x639 },    // ain
    54 	{ reinterpret_cast<const TText*>(L"g"), 0x63A },
    60     { reinterpret_cast<const TText*>(L"g"), 0x63A },
    55 	{ reinterpret_cast<const TText*>(L"_"), 0x640 },	// kashida
    61     { reinterpret_cast<const TText*>(L"_"), 0x640 },    // kashida
    56 	{ reinterpret_cast<const TText*>(L"f"), 0x641 },
    62     { reinterpret_cast<const TText*>(L"f"), 0x641 },
    57 	{ reinterpret_cast<const TText*>(L"q"), 0x642 },
    63     { reinterpret_cast<const TText*>(L"q"), 0x642 },
    58 	{ reinterpret_cast<const TText*>(L"k"), 0x643 },
    64     { reinterpret_cast<const TText*>(L"k"), 0x643 },
    59 	{ reinterpret_cast<const TText*>(L"l"), 0x644 },	// lam
    65     { reinterpret_cast<const TText*>(L"l"), 0x644 },    // lam
    60 	{ reinterpret_cast<const TText*>(L"m"), 0x645 },
    66     { reinterpret_cast<const TText*>(L"m"), 0x645 },
    61 	{ reinterpret_cast<const TText*>(L"n"), 0x646 },
    67     { reinterpret_cast<const TText*>(L"n"), 0x646 },
    62 	{ reinterpret_cast<const TText*>(L"h"), 0x647 },	// heh
    68     { reinterpret_cast<const TText*>(L"h"), 0x647 },    // heh
    63 	{ reinterpret_cast<const TText*>(L"w"), 0x648 },
    69     { reinterpret_cast<const TText*>(L"w"), 0x648 },
    64 	{ reinterpret_cast<const TText*>(L"y"), 0x64A },
    70     { reinterpret_cast<const TText*>(L"y"), 0x64A },
    65 	{ reinterpret_cast<const TText*>(L"^F"), 0x64B },	// fathatan
    71     { reinterpret_cast<const TText*>(L"^F"), 0x64B },   // fathatan
    66 	{ reinterpret_cast<const TText*>(L"^D"), 0x64C },	// dammatan
    72     { reinterpret_cast<const TText*>(L"^D"), 0x64C },   // dammatan
    67 	{ reinterpret_cast<const TText*>(L"^K"), 0x64D },	// kasratan
    73     { reinterpret_cast<const TText*>(L"^K"), 0x64D },   // kasratan
    68 	{ reinterpret_cast<const TText*>(L"^f"), 0x64E },	// fatha
    74     { reinterpret_cast<const TText*>(L"^f"), 0x64E },   // fatha
    69 	{ reinterpret_cast<const TText*>(L"^d"), 0x64F },	// damma
    75     { reinterpret_cast<const TText*>(L"^d"), 0x64F },   // damma
    70 	{ reinterpret_cast<const TText*>(L"^k"), 0x650 },	// kasra
    76     { reinterpret_cast<const TText*>(L"^k"), 0x650 },   // kasra
    71 	{ reinterpret_cast<const TText*>(L"^s"), 0x651 },	// shadda
    77     { reinterpret_cast<const TText*>(L"^s"), 0x651 },   // shadda
    72 	{ reinterpret_cast<const TText*>(L"^h"), 0x652 },	// sukun
    78     { reinterpret_cast<const TText*>(L"^h"), 0x652 },   // sukun
    73 	{ reinterpret_cast<const TText*>(L"^~"), 0x653 },	// maddah
    79     { reinterpret_cast<const TText*>(L"^~"), 0x653 },   // maddah
    74 	{ reinterpret_cast<const TText*>(L"^`"), 0x654 },	// hamza above
    80     { reinterpret_cast<const TText*>(L"^`"), 0x654 },   // hamza above
    75 	{ reinterpret_cast<const TText*>(L"_`"), 0x653 },	// hamza below
    81     { reinterpret_cast<const TText*>(L"_`"), 0x653 },   // hamza below
    76 	{ reinterpret_cast<const TText*>(L"0"), 0x660 },
    82     { reinterpret_cast<const TText*>(L"0"), 0x660 },
    77 	{ reinterpret_cast<const TText*>(L"1"), 0x661 },
    83     { reinterpret_cast<const TText*>(L"1"), 0x661 },
    78 	{ reinterpret_cast<const TText*>(L"2"), 0x662 },
    84     { reinterpret_cast<const TText*>(L"2"), 0x662 },
    79 	{ reinterpret_cast<const TText*>(L"3"), 0x663 },
    85     { reinterpret_cast<const TText*>(L"3"), 0x663 },
    80 	{ reinterpret_cast<const TText*>(L"4"), 0x664 },
    86     { reinterpret_cast<const TText*>(L"4"), 0x664 },
    81 	{ reinterpret_cast<const TText*>(L"5"), 0x665 },
    87     { reinterpret_cast<const TText*>(L"5"), 0x665 },
    82 	{ reinterpret_cast<const TText*>(L"6"), 0x666 },
    88     { reinterpret_cast<const TText*>(L"6"), 0x666 },
    83 	{ reinterpret_cast<const TText*>(L"7"), 0x667 },
    89     { reinterpret_cast<const TText*>(L"7"), 0x667 },
    84 	{ reinterpret_cast<const TText*>(L"8"), 0x668 },
    90     { reinterpret_cast<const TText*>(L"8"), 0x668 },
    85 	{ reinterpret_cast<const TText*>(L"9"), 0x669 }
    91     { reinterpret_cast<const TText*>(L"9"), 0x669 }
    86 	};
    92     };
       
    93 }
       
    94 using namespace LocalToTGraphemeIterator;
    87 
    95 
    88 TText TransliterateSingle(const TText*& aInput, const TText* aEnd)
    96 TText TransliterateSingle(const TText*& aInput, const TText* aEnd)
    89 	{
    97 	{
    90 	const TInt tableSize =
    98 	const TInt tableSize =
    91 		sizeof(KArabicTransliteration)/sizeof(KArabicTransliteration[0]);
    99 		sizeof(KArabicTransliteration)/sizeof(KArabicTransliteration[0]);
   145 
   153 
   146 /**
   154 /**
   147 Tests RTmGraphemeEdgeIterator::DocPosMatches for this document position and
   155 Tests RTmGraphemeEdgeIterator::DocPosMatches for this document position and
   148 edge.
   156 edge.
   149 */
   157 */
   150 void TestDocPosMatchesCase(RTest& aTest,
   158 void TestDocPosMatchesCase(const TTmGraphemeEdgeInfo& aEdgeInfo,
   151 	const TTmGraphemeEdgeInfo& aEdgeInfo,
       
   152 	TTmDocPosSpec& aPosSpec,
   159 	TTmDocPosSpec& aPosSpec,
   153 	RTmGraphemeEdgeIterator::TGraphemeMatch aExpectedMatchType)
   160 	RTmGraphemeEdgeIterator::TGraphemeMatch aExpectedMatchType)
   154 	{
   161 	{
   155 	TInt start = aEdgeInfo.iPos.iDocPos.iPos;
   162 	TInt start = aEdgeInfo.iPos.iDocPos.iPos;
   156 	TInt end = start;
   163 	TInt end = start;
   160 		{
   167 		{
   161 		start -= aEdgeInfo.iCodePoints - 1;
   168 		start -= aEdgeInfo.iCodePoints - 1;
   162 		++end;
   169 		++end;
   163 		}
   170 		}
   164 	aPosSpec.iPos = start - 1;
   171 	aPosSpec.iPos = start - 1;
   165 	aTest(RTmGraphemeEdgeIterator::DocPosMatches(aPosSpec, aEdgeInfo)
   172 	TESTPOINT(RTmGraphemeEdgeIterator::DocPosMatches(aPosSpec, aEdgeInfo)
   166 		== RTmGraphemeEdgeIterator::ENoMatch);
   173 		== RTmGraphemeEdgeIterator::ENoMatch);
   167 	for (TInt i = start; i != end; ++i)
   174 	for (TInt i = start; i != end; ++i)
   168 		{
   175 		{
   169 		aPosSpec.iPos = i;
   176 		aPosSpec.iPos = i;
   170 		aTest(RTmGraphemeEdgeIterator::DocPosMatches(aPosSpec, aEdgeInfo)
   177 		TESTPOINT(RTmGraphemeEdgeIterator::DocPosMatches(aPosSpec, aEdgeInfo)
   171 			== aExpectedMatchType);
   178 			== aExpectedMatchType);
   172 		}
   179 		}
   173 	aPosSpec.iPos = end;
   180 	aPosSpec.iPos = end;
   174 	aTest(RTmGraphemeEdgeIterator::DocPosMatches(aPosSpec, aEdgeInfo)
   181 	TESTPOINT(RTmGraphemeEdgeIterator::DocPosMatches(aPosSpec, aEdgeInfo)
   175 		== RTmGraphemeEdgeIterator::ENoMatch);
   182 		== RTmGraphemeEdgeIterator::ENoMatch);
   176 	}
   183 	}
   177 
   184 
   178 /**
   185 /**
   179 Tests RTmGraphemeEdgeIterator::DocPosMatches for this edge and all relevant
   186 Tests RTmGraphemeEdgeIterator::DocPosMatches for this edge and all relevant
   180 document position specifications.
   187 document position specifications.
   181 */
   188 */
   182 void TestDocPosMatchesAllSpecs(RTest& aTest,
   189 void TestDocPosMatchesAllSpecs(const TTmGraphemeEdgeInfo& aEdgeInfo)
   183 	const TTmGraphemeEdgeInfo& aEdgeInfo)
       
   184 	{
   190 	{
   185 	TTmDocPosSpec posSpec;
   191 	TTmDocPosSpec posSpec;
   186 	RTmGraphemeEdgeIterator::TGraphemeMatch expected;
   192 	RTmGraphemeEdgeIterator::TGraphemeMatch expected;
   187 	posSpec.iType = TTmDocPosSpec::ELeftToRight;
   193 	posSpec.iType = TTmDocPosSpec::ELeftToRight;
   188 	expected = aEdgeInfo.iPos.iRightToLeft?
   194 	expected = aEdgeInfo.iPos.iRightToLeft?
   189 		RTmGraphemeEdgeIterator::EPositionOnly
   195 		RTmGraphemeEdgeIterator::EPositionOnly
   190 		: RTmGraphemeEdgeIterator::ETotalMatch;
   196 		: RTmGraphemeEdgeIterator::ETotalMatch;
   191 	TestDocPosMatchesCase(aTest, aEdgeInfo, posSpec, expected);
   197 	TestDocPosMatchesCase(aEdgeInfo, posSpec, expected);
   192 	posSpec.iType = TTmDocPosSpec::ERightToLeft;
   198 	posSpec.iType = TTmDocPosSpec::ERightToLeft;
   193 	expected = aEdgeInfo.iPos.iRightToLeft?
   199 	expected = aEdgeInfo.iPos.iRightToLeft?
   194 		RTmGraphemeEdgeIterator::ETotalMatch
   200 		RTmGraphemeEdgeIterator::ETotalMatch
   195 		: RTmGraphemeEdgeIterator::EPositionOnly;
   201 		: RTmGraphemeEdgeIterator::EPositionOnly;
   196 	TestDocPosMatchesCase(aTest, aEdgeInfo, posSpec, expected);
   202 	TestDocPosMatchesCase(aEdgeInfo, posSpec, expected);
   197 	posSpec.iType = TTmDocPosSpec::ETrailing;
   203 	posSpec.iType = TTmDocPosSpec::ETrailing;
   198 	expected = aEdgeInfo.iPos.iDocPos.iLeadingEdge?
   204 	expected = aEdgeInfo.iPos.iDocPos.iLeadingEdge?
   199 		RTmGraphemeEdgeIterator::ENoMatch
   205 		RTmGraphemeEdgeIterator::ENoMatch
   200 		: RTmGraphemeEdgeIterator::ETotalMatch;
   206 		: RTmGraphemeEdgeIterator::ETotalMatch;
   201 	TestDocPosMatchesCase(aTest, aEdgeInfo, posSpec, expected);
   207 	TestDocPosMatchesCase(aEdgeInfo, posSpec, expected);
   202 	posSpec.iType = TTmDocPosSpec::ELeading;
   208 	posSpec.iType = TTmDocPosSpec::ELeading;
   203 	expected = aEdgeInfo.iPos.iDocPos.iLeadingEdge?
   209 	expected = aEdgeInfo.iPos.iDocPos.iLeadingEdge?
   204 		RTmGraphemeEdgeIterator::ETotalMatch
   210 		RTmGraphemeEdgeIterator::ETotalMatch
   205 		: RTmGraphemeEdgeIterator::ENoMatch;
   211 		: RTmGraphemeEdgeIterator::ENoMatch;
   206 	TestDocPosMatchesCase(aTest, aEdgeInfo, posSpec, expected);
   212 	TestDocPosMatchesCase(aEdgeInfo, posSpec, expected);
   207 	}
   213 	}
   208 
   214 
   209 /**
   215 /**
   210 Tests RTmGraphemeEdgeIterator::DocPosMatches for a variety of edges and
   216 Tests RTmGraphemeEdgeIterator::DocPosMatches for a variety of edges and
   211 positions.
   217 positions.
   212 */
   218 */
   213 void TestDocPosMatches(RTest& aTest)
   219 void TestDocPosMatches()
   214 	{
   220 	{
   215 	TTmGraphemeEdgeInfo edgeInfo;
   221 	TTmGraphemeEdgeInfo edgeInfo;
   216 	edgeInfo.iPos.iDocPos.iPos = 5;
   222 	edgeInfo.iPos.iDocPos.iPos = 5;
   217 	for (edgeInfo.iCodePoints = 1; edgeInfo.iCodePoints <= 3;
   223 	for (edgeInfo.iCodePoints = 1; edgeInfo.iCodePoints <= 3;
   218 		++edgeInfo.iCodePoints)
   224 		++edgeInfo.iCodePoints)
   219 		{
   225 		{
   220 		edgeInfo.iPos.iDocPos.iLeadingEdge = ETrue;
   226 		edgeInfo.iPos.iDocPos.iLeadingEdge = ETrue;
   221 		edgeInfo.iPos.iRightToLeft = EFalse;
   227 		edgeInfo.iPos.iRightToLeft = EFalse;
   222 		TestDocPosMatchesAllSpecs(aTest, edgeInfo);
   228 		TestDocPosMatchesAllSpecs(edgeInfo);
   223 		edgeInfo.iPos.iDocPos.iLeadingEdge = EFalse;
   229 		edgeInfo.iPos.iDocPos.iLeadingEdge = EFalse;
   224 		TestDocPosMatchesAllSpecs(aTest, edgeInfo);
   230 		TestDocPosMatchesAllSpecs(edgeInfo);
   225 		edgeInfo.iPos.iRightToLeft = ETrue;
   231 		edgeInfo.iPos.iRightToLeft = ETrue;
   226 		TestDocPosMatchesAllSpecs(aTest, edgeInfo);
   232 		TestDocPosMatchesAllSpecs(edgeInfo);
   227 		edgeInfo.iPos.iDocPos.iLeadingEdge = ETrue;
   233 		edgeInfo.iPos.iDocPos.iLeadingEdge = ETrue;
   228 		TestDocPosMatchesAllSpecs(aTest, edgeInfo);
   234 		TestDocPosMatchesAllSpecs(edgeInfo);
   229 		}
   235 		}
   230 	}
   236 	}
   231 
   237 
   232 enum TEdgeType { ETrail, ELead };
   238 enum TEdgeType { ETrail, ELead };
   233 enum TEdgeRelationship { EEdgeDifferent, EEdgeSame, EEdgeNewline };
   239 enum TEdgeRelationship { EEdgeDifferent, EEdgeSame, EEdgeNewline };
   549 	}
   555 	}
   550 
   556 
   551 /**
   557 /**
   552 Tests that the edge information matches the expected edge.
   558 Tests that the edge information matches the expected edge.
   553 */
   559 */
   554 void TestExpectedEdge(RTest& aTest, const TTmPosInfo2& aEdgeInfo,
   560 void TestExpectedEdge(const TTmPosInfo2& aEdgeInfo,
   555 	const TEdge* aExpected)
   561 	const TEdge* aExpected)
   556 	{
   562 	{
   557 	aTest(aEdgeInfo.iRightToLeft?
   563 	TESTPOINT(aEdgeInfo.iRightToLeft?
   558 		aExpected->iRightToLeft : !aExpected->iRightToLeft);
   564 		aExpected->iRightToLeft : !aExpected->iRightToLeft);
   559 	aTest(aEdgeInfo.iDocPos.iPos == aExpected->iPos);
   565 	TESTPOINT(aEdgeInfo.iDocPos.iPos == aExpected->iPos);
   560 	aTest(aEdgeInfo.iDocPos.iLeadingEdge?
   566 	TESTPOINT(aEdgeInfo.iDocPos.iLeadingEdge?
   561 		aExpected->iLeading : !aExpected->iLeading);
   567 		aExpected->iLeading : !aExpected->iLeading);
   562 	}
   568 	}
   563 
   569 
   564 /**
   570 /**
   565 Tests that the edge information matches one of the expected edges.
   571 Tests that the edge information matches one of the expected edges.
   566 */
   572 */
   567 void TestEdgeExists(RTest& aTest, const TTmPosInfo2& aEdgeInfo,
   573 void TestEdgeExists(const TTmPosInfo2& aEdgeInfo,
   568 	const TEdge* aExpected, TInt aNumExpected)
   574 	const TEdge* aExpected, TInt aNumExpected)
   569 	{
   575 	{
   570 	TTmDocPos pos(aEdgeInfo.iDocPos);
   576 	TTmDocPos pos(aEdgeInfo.iDocPos);
   571 	const TEdge* edge = FindExpectedEdge(pos, aExpected, aNumExpected);
   577 	const TEdge* edge = FindExpectedEdge(pos, aExpected, aNumExpected);
   572 	aTest(edge != 0);
   578 	TESTPOINT(edge != 0);
   573 	TestExpectedEdge(aTest, aEdgeInfo, edge);
   579 	TestExpectedEdge(aEdgeInfo, edge);
   574 	}
   580 	}
   575 
   581 
   576 /**
   582 /**
   577 Tests that the visual position matches one of the expected edges.
   583 Tests that the visual position matches one of the expected edges.
   578 */
   584 */
   579 void TestVisualPositionExists(RTest& aTest, const TTmVisualDocPos& aPos,
   585 void TestVisualPositionExists(const TTmVisualDocPos& aPos,
   580 	const TEdge* aExpected, TInt aNumExpected)
   586 	const TEdge* aExpected, TInt aNumExpected)
   581 	{
   587 	{
   582 	aTest(aPos.Ambiguity() != TTmVisualDocPos::ENotFound);
   588     TESTPOINT(aPos.Ambiguity() != TTmVisualDocPos::ENotFound);
   583 	TTmDocPos posLeft(aPos.LeftEdge().iDocPos);
   589 	TTmDocPos posLeft(aPos.LeftEdge().iDocPos);
   584 	const TEdge* left = FindExpectedEdge(posLeft, aExpected, aNumExpected);
   590 	const TEdge* left = FindExpectedEdge(posLeft, aExpected, aNumExpected);
   585 	TestExpectedEdge(aTest, aPos.LeftEdge(), left);
   591 	TestExpectedEdge(aPos.LeftEdge(), left);
   586 	TTmDocPos posRight(aPos.RightEdge().iDocPos);
   592 	TTmDocPos posRight(aPos.RightEdge().iDocPos);
   587 	const TEdge* right = FindExpectedEdge(posRight, aExpected, aNumExpected);
   593 	const TEdge* right = FindExpectedEdge(posRight, aExpected, aNumExpected);
   588 	TestExpectedEdge(aTest, aPos.RightEdge(), right);
   594 	TestExpectedEdge(aPos.RightEdge(), right);
   589 	aTest( (aPos.Ambiguity() == TTmVisualDocPos::EAmbiguous
   595 	TESTPOINT( (aPos.Ambiguity() == TTmVisualDocPos::EAmbiguous
   590 			&& left->iAmbiguity && right->iAmbiguity)
   596 			&& left->iAmbiguity && right->iAmbiguity)
   591 		|| (aPos.Ambiguity() != TTmVisualDocPos::EAmbiguous
   597 		|| (aPos.Ambiguity() != TTmVisualDocPos::EAmbiguous
   592 			&& !left->iAmbiguity && !right->iAmbiguity) );
   598 			&& !left->iAmbiguity && !right->iAmbiguity) );
   593 	aTest(ExpectedEdgesCoincide(left, right));
   599 	TESTPOINT(ExpectedEdgesCoincide(left, right));
   594 	}
   600 	}
   595 
   601 
   596 /**
   602 /**
   597 Tests that a RTmGraphemeEdgeIterator iterates through all the positions in a
   603 Tests that a RTmGraphemeEdgeIterator iterates through all the positions in a
   598 line from left to right.
   604 line from left to right.
   599 */
   605 */
   600 void TestLayoutSimplePass(RTest& aTest, CTestTmTextLayout& aLayout,
   606 void TestLayoutSimplePass(CTestTmTextLayout& aLayout,
   601 	const TEdge* aExpected, TInt aNumExpected)
   607 	const TEdge* aExpected, TInt aNumExpected)
   602 	{
   608 	{
   603 	CTmTextLayout& layout = aLayout.Layout();
   609 	CTmTextLayout& layout = aLayout.Layout();
   604 	TTmInterpreterParam interpParam(layout);
   610 	TTmInterpreterParam interpParam(layout);
   605 	RTmGeneralInterpreter interp(aLayout.Source(), interpParam);
   611 	RTmGeneralInterpreter interp(aLayout.Source(), interpParam);
   608 	it.Begin(interp);
   614 	it.Begin(interp);
   609 	TTmPosInfo2 last = it.GetInfo();
   615 	TTmPosInfo2 last = it.GetInfo();
   610 	for (TInt i = 0; i != aNumExpected; ++i)
   616 	for (TInt i = 0; i != aNumExpected; ++i)
   611 		{
   617 		{
   612 		const TEdge& expected = aExpected[i];
   618 		const TEdge& expected = aExpected[i];
   613 		aTest(expected.iPos == last.iDocPos.iPos);
   619 		TESTPOINT(expected.iPos == last.iDocPos.iPos);
   614 		aTest(expected.iLeading == last.iDocPos.iLeadingEdge);
   620 		TESTPOINT(expected.iLeading == last.iDocPos.iLeadingEdge);
   615 		it.Next();
   621 		it.Next();
   616 		if (it.AtEnd())
   622 		if (it.AtEnd())
   617 			{
   623 			{
   618 			aTest(expected.iNext == EEdgeNewline);
   624             TESTPOINT(expected.iNext == EEdgeNewline);
   619 			while (interp.Op() != TTmInterpreter::EOpLine && interp.Next())
   625 			while (interp.Op() != TTmInterpreter::EOpLine && interp.Next())
   620 				{}
   626 				{}
   621 			if (i + 1 != aNumExpected)
   627 			if (i + 1 != aNumExpected)
   622 				{
   628 				{
   623 				it.Begin(interp);
   629 				it.Begin(interp);
   625 				}
   631 				}
   626 			}
   632 			}
   627 		else
   633 		else
   628 			{
   634 			{
   629 			TTmPosInfo2 thisOne = it.GetInfo();
   635 			TTmPosInfo2 thisOne = it.GetInfo();
   630 			TestEdgeExists(aTest, thisOne, aExpected, aNumExpected);
   636 			TestEdgeExists(thisOne, aExpected, aNumExpected);
   631 			aTest(expected.iNext != EEdgeNewline);
   637 			TESTPOINT(expected.iNext != EEdgeNewline);
   632 			if (expected.iNext == EEdgeSame)
   638 			if (expected.iNext == EEdgeSame)
   633 				aTest(last.iEdge.iX == thisOne.iEdge.iX);
   639 			    TESTPOINT(last.iEdge.iX == thisOne.iEdge.iX);
   634 			else if (expected.iNext == EEdgeDifferent)
   640 			else if (expected.iNext == EEdgeDifferent)
   635 				aTest(last.iEdge.iX != thisOne.iEdge.iX);
   641 			    TESTPOINT(last.iEdge.iX != thisOne.iEdge.iX);
   636 			last = thisOne;
   642 			last = thisOne;
   637 			}
   643 			}
   638 		}
   644 		}
   639 	it.Close();
   645 	it.Close();
   640 	interp.Close();
   646 	interp.Close();
   642 
   648 
   643 /**
   649 /**
   644 Tests that FindXPos returns the edge 'closest' to the input co-ordinate
   650 Tests that FindXPos returns the edge 'closest' to the input co-ordinate
   645 where there is no ambiguity.
   651 where there is no ambiguity.
   646 */
   652 */
   647 void TestLayoutFindXPosEdges(RTest& aTest, TInt aLine,
   653 void TestLayoutFindXPosEdges(TInt aLine,
   648 	CTestTmTextLayout& aLayout,
   654 	CTestTmTextLayout& aLayout,
   649 	const TEdge* aExpected, TInt aNumExpected)
   655 	const TEdge* aExpected, TInt aNumExpected)
   650 	{
   656 	{
   651 	CTmTextLayout& layout = aLayout.Layout();
   657 	CTmTextLayout& layout = aLayout.Layout();
   652 	TTmInterpreterParam interpParam(layout);
   658 	TTmInterpreterParam interpParam(layout);
   670 				RTmGeneralInterpreter interp(aLayout.Source(), interpParam);
   676 				RTmGeneralInterpreter interp(aLayout.Source(), interpParam);
   671 				interp.LineNumberToLine(aLine);
   677 				interp.LineNumberToLine(aLine);
   672 				RTmGraphemeEdgeIterator it;
   678 				RTmGraphemeEdgeIterator it;
   673 				it.Begin(interp);
   679 				it.Begin(interp);
   674 				it.FindXPos(posInfo.iEdge.iX, visPos);
   680 				it.FindXPos(posInfo.iEdge.iX, visPos);
   675 				aTest(visPos.Ambiguity() != TTmVisualDocPos::EAmbiguous);
   681 				TESTPOINT(visPos.Ambiguity() != TTmVisualDocPos::EAmbiguous);
   676 				aTest(visPos.Ambiguity() != TTmVisualDocPos::ENotFound);
   682 				TESTPOINT(visPos.Ambiguity() != TTmVisualDocPos::ENotFound);
   677 				aTest(visPos.LeftEdge().iDocPos.iPos == expectedL.iPos);
   683 				TESTPOINT(visPos.LeftEdge().iDocPos.iPos == expectedL.iPos);
   678 				aTest(visPos.LeftEdge().iDocPos.iLeadingEdge?
   684 				TESTPOINT(visPos.LeftEdge().iDocPos.iLeadingEdge?
   679 					expectedL.iLeading : !expectedL.iLeading);
   685 					expectedL.iLeading : !expectedL.iLeading);
   680 				it.Close();
   686 				it.Close();
   681 				interp.Close();
   687 				interp.Close();
   682 				}
   688 				}
   683 			if (!expectedR.iAmbiguity)
   689 			if (!expectedR.iAmbiguity)
   689 				RTmGeneralInterpreter interp(aLayout.Source(), interpParam);
   695 				RTmGeneralInterpreter interp(aLayout.Source(), interpParam);
   690 				interp.LineNumberToLine(aLine);
   696 				interp.LineNumberToLine(aLine);
   691 				RTmGraphemeEdgeIterator it;
   697 				RTmGraphemeEdgeIterator it;
   692 				it.Begin(interp);
   698 				it.Begin(interp);
   693 				it.FindXPos(posInfo.iEdge.iX - 1, visPos);
   699 				it.FindXPos(posInfo.iEdge.iX - 1, visPos);
   694 				aTest(visPos.Ambiguity() != TTmVisualDocPos::EAmbiguous);
   700 				TESTPOINT(visPos.Ambiguity() != TTmVisualDocPos::EAmbiguous);
   695 				aTest(visPos.Ambiguity() != TTmVisualDocPos::ENotFound);
   701 				TESTPOINT(visPos.Ambiguity() != TTmVisualDocPos::ENotFound);
   696 				aTest(visPos.LeftEdge().iDocPos.iPos == expectedR.iPos);
   702 				TESTPOINT(visPos.LeftEdge().iDocPos.iPos == expectedR.iPos);
   697 				aTest(visPos.LeftEdge().iDocPos.iLeadingEdge?
   703 				TESTPOINT(visPos.LeftEdge().iDocPos.iLeadingEdge?
   698 					expectedR.iLeading : !expectedR.iLeading);
   704 					expectedR.iLeading : !expectedR.iLeading);
   699 				it.Close();
   705 				it.Close();
   700 				interp.Close();
   706 				interp.Close();
   701 				}
   707 				}
   702 			}
   708 			}
   705 
   711 
   706 /**
   712 /**
   707 Tests that RTmGraphemeEdgeIterator::FindXPos finds document positions that
   713 Tests that RTmGraphemeEdgeIterator::FindXPos finds document positions that
   708 match the positions they are supposed to be in.
   714 match the positions they are supposed to be in.
   709 */
   715 */
   710 void TestLayoutFindXPos(RTest& aTest, TInt aLine,
   716 void TestLayoutFindXPos(TInt aLine,
   711 	CTestTmTextLayout& aLayout,
   717 	CTestTmTextLayout& aLayout,
   712 	const TEdge* aExpected, TInt aNumExpected)
   718 	const TEdge* aExpected, TInt aNumExpected)
   713 	{
   719 	{
   714 	TInt lastLeftX = KMinTInt;
   720 	TInt lastLeftX = KMinTInt;
   715 	TInt lastRightX = KMinTInt;
   721 	TInt lastRightX = KMinTInt;
   722 		RTmGeneralInterpreter interp(aLayout.Source(), interpParam);
   728 		RTmGeneralInterpreter interp(aLayout.Source(), interpParam);
   723 		interp.LineNumberToLine(aLine);
   729 		interp.LineNumberToLine(aLine);
   724 		RTmGraphemeEdgeIterator it;
   730 		RTmGraphemeEdgeIterator it;
   725 		it.Begin(interp);
   731 		it.Begin(interp);
   726 		it.FindXPos(x, visPos);
   732 		it.FindXPos(x, visPos);
   727 		TestVisualPositionExists(aTest, visPos, aExpected, aNumExpected);
   733 		TestVisualPositionExists(visPos, aExpected, aNumExpected);
   728 		aTest(visPos.Ambiguity() != TTmVisualDocPos::ENotFound);
   734 		TESTPOINT(visPos.Ambiguity() != TTmVisualDocPos::ENotFound);
   729 		aTest(visPos.LeftEdge().iEdge.iX <= visPos.RightEdge().iEdge.iX);
   735 		TESTPOINT(visPos.LeftEdge().iEdge.iX <= visPos.RightEdge().iEdge.iX);
   730 		aTest(visPos.Ambiguity() == TTmVisualDocPos::EAmbiguous
   736 		TESTPOINT(visPos.Ambiguity() == TTmVisualDocPos::EAmbiguous
   731 			|| visPos.LeftEdge().iEdge.iX == visPos.RightEdge().iEdge.iX);
   737 			|| visPos.LeftEdge().iEdge.iX == visPos.RightEdge().iEdge.iX);
   732 		aTest(lastLeftX <= visPos.LeftEdge().iEdge.iX);
   738 		TESTPOINT(lastLeftX <= visPos.LeftEdge().iEdge.iX);
   733 		if (lastLeftX == visPos.LeftEdge().iEdge.iX)
   739 		if (lastLeftX == visPos.LeftEdge().iEdge.iX)
   734 			{
   740 			{
   735 			aTest(lastRightX == visPos.RightEdge().iEdge.iX);
   741             TESTPOINT(lastRightX == visPos.RightEdge().iEdge.iX);
   736 			while (aExpected->iPos != visPos.LeftEdge().iDocPos.iPos
   742 			while (aExpected->iPos != visPos.LeftEdge().iDocPos.iPos
   737 				|| aExpected->iLeading != visPos.LeftEdge().iDocPos.iLeadingEdge)
   743 				|| aExpected->iLeading != visPos.LeftEdge().iDocPos.iLeadingEdge)
   738 				{
   744 				{
   739 				aTest(aExpected->iNext == EEdgeSame);
   745                 TESTPOINT(aExpected->iNext == EEdgeSame);
   740 				aTest(0 < aNumExpected);
   746                 TESTPOINT(0 < aNumExpected);
   741 				++aExpected;
   747 				++aExpected;
   742 				--aNumExpected;
   748 				--aNumExpected;
   743 				}
   749 				}
   744 			}
   750 			}
   745 		else
   751 		else
   746 			{
   752 			{
   747 			aTest(lastRightX <= visPos.LeftEdge().iEdge.iX);
   753             TESTPOINT(lastRightX <= visPos.LeftEdge().iEdge.iX);
   748 			while (aExpected->iPos != visPos.LeftEdge().iDocPos.iPos
   754 			while (aExpected->iPos != visPos.LeftEdge().iDocPos.iPos
   749 				|| aExpected->iLeading != visPos.LeftEdge().iDocPos.iLeadingEdge)
   755 				|| aExpected->iLeading != visPos.LeftEdge().iDocPos.iLeadingEdge)
   750 				{
   756 				{
   751 				aTest(0 < aNumExpected);
   757                 TESTPOINT(0 < aNumExpected);
   752 				++aExpected;
   758 				++aExpected;
   753 				--aNumExpected;
   759 				--aNumExpected;
   754 				}
   760 				}
   755 			}
   761 			}
   756 		if (interp.LineInfo().iInnerRect.iBr.iX + 120 < x)
   762 		if (interp.LineInfo().iInnerRect.iBr.iX + 120 < x)
   758 		it.Close();
   764 		it.Close();
   759 		interp.Close();
   765 		interp.Close();
   760 		}
   766 		}
   761 	while (aExpected->iNext != EEdgeNewline)
   767 	while (aExpected->iNext != EEdgeNewline)
   762 		{
   768 		{
   763 		aTest(aExpected->iNext == EEdgeSame);
   769         TESTPOINT(aExpected->iNext == EEdgeSame);
   764 		aTest(0 < aNumExpected);
   770         TESTPOINT(0 < aNumExpected);
   765 		++aExpected;
   771 		++aExpected;
   766 		--aNumExpected;
   772 		--aNumExpected;
   767 		}
   773 		}
   768 	}
   774 	}
   769 
   775 
   788 
   794 
   789 /**
   795 /**
   790 Tests that RTmGraphemeEdgeIterator::FindEdge finds the edges in the layout with
   796 Tests that RTmGraphemeEdgeIterator::FindEdge finds the edges in the layout with
   791 specifications of leading or trailing edges.
   797 specifications of leading or trailing edges.
   792 */
   798 */
   793 void TestLayoutFindEdgesInVisualOrder(RTest& aTest, TInt aLine,
   799 void TestLayoutFindEdgesInVisualOrder(TInt aLine,
   794 	CTestTmTextLayout& aLayout,
   800 	CTestTmTextLayout& aLayout,
   795 	const TEdge* aExpected, TInt aNumExpected)
   801 	const TEdge* aExpected, TInt aNumExpected)
   796 	{
   802 	{
   797 	TInt lastX = KMinTInt;
   803 	TInt lastX = KMinTInt;
   798 	TBool sameExpected = EFalse;
   804 	TBool sameExpected = EFalse;
   800 	while (aNumExpected != 0)
   806 	while (aNumExpected != 0)
   801 		{
   807 		{
   802 		TTmDocPosSpec posSpec(aExpected->iPos, aExpected->iLeading?
   808 		TTmDocPosSpec posSpec(aExpected->iPos, aExpected->iLeading?
   803 			TTmDocPosSpec::ELeading : TTmDocPosSpec::ETrailing);
   809 			TTmDocPosSpec::ELeading : TTmDocPosSpec::ETrailing);
   804 		FindEdgeFromLayout(aLayout, aLine, posSpec, posInfo);
   810 		FindEdgeFromLayout(aLayout, aLine, posSpec, posInfo);
   805 		TestEdgeExists(aTest, posInfo, aExpected, aNumExpected);
   811 		TestEdgeExists(posInfo, aExpected, aNumExpected);
   806 		aTest(aExpected->iLeading?
   812 		TESTPOINT(aExpected->iLeading?
   807 			posInfo.iDocPos.iLeadingEdge : !posInfo.iDocPos.iLeadingEdge);
   813 			posInfo.iDocPos.iLeadingEdge : !posInfo.iDocPos.iLeadingEdge);
   808 		aTest(aExpected->iPos == posInfo.iDocPos.iPos);
   814 		TESTPOINT(aExpected->iPos == posInfo.iDocPos.iPos);
   809 		aTest(sameExpected || posInfo.iEdge.iX != lastX);
   815 		TESTPOINT(sameExpected || posInfo.iEdge.iX != lastX);
   810 		aTest(!sameExpected || posInfo.iEdge.iX == lastX);
   816 		TESTPOINT(!sameExpected || posInfo.iEdge.iX == lastX);
   811 		lastX = posInfo.iEdge.iX;
   817 		lastX = posInfo.iEdge.iX;
   812 		sameExpected = aExpected->iNext == EEdgeSame? ETrue : EFalse;
   818 		sameExpected = aExpected->iNext == EEdgeSame? ETrue : EFalse;
   813 		++aExpected;
   819 		++aExpected;
   814 		--aNumExpected;
   820 		--aNumExpected;
   815 		}
   821 		}
   817 
   823 
   818 /**
   824 /**
   819 Tests that RTmGraphemeEdgeIterator::FindEdge finds the edges in the layout with
   825 Tests that RTmGraphemeEdgeIterator::FindEdge finds the edges in the layout with
   820 specifications of directionality.
   826 specifications of directionality.
   821 */
   827 */
   822 void TestLayoutFindEdgesByDirectionality(RTest& aTest, TInt aLine,
   828 void TestLayoutFindEdgesByDirectionality(TInt aLine,
   823 	CTestTmTextLayout& aLayout,
   829 	CTestTmTextLayout& aLayout,
   824 	const TEdge* aExpected, TInt aNumExpected)
   830 	const TEdge* aExpected, TInt aNumExpected)
   825 	{
   831 	{
   826 	TInt lineStart;
   832 	TInt lineStart;
   827 	TInt lineEnd;
   833 	TInt lineEnd;
   834 		TBool rToLFound = FindEdgeFromLayout(aLayout, aLine, rToLPosSpec, rToLPosInfo);
   840 		TBool rToLFound = FindEdgeFromLayout(aLayout, aLine, rToLPosSpec, rToLPosInfo);
   835 		TTmDocPosSpec lToRPosSpec(pos, TTmDocPosSpec::ELeftToRight);
   841 		TTmDocPosSpec lToRPosSpec(pos, TTmDocPosSpec::ELeftToRight);
   836 		TBool lToRFound = FindEdgeFromLayout(aLayout, aLine, lToRPosSpec, lToRPosInfo);
   842 		TBool lToRFound = FindEdgeFromLayout(aLayout, aLine, lToRPosSpec, lToRPosInfo);
   837 		if (!lToRFound)
   843 		if (!lToRFound)
   838 			{
   844 			{
   839 			aTest(!rToLFound);
   845             TESTPOINT(!rToLFound);
   840 			aTest(pos < lineStart || lineEnd <= pos);
   846             TESTPOINT(pos < lineStart || lineEnd <= pos);
   841 			}
   847 			}
   842 		else
   848 		else
   843 			{
   849 			{
   844 			aTest(rToLFound);
   850             TESTPOINT(rToLFound);
   845 			TestEdgeExists(aTest, rToLPosInfo, aExpected, aNumExpected);
   851 			TestEdgeExists(rToLPosInfo, aExpected, aNumExpected);
   846 			TestEdgeExists(aTest, lToRPosInfo, aExpected, aNumExpected);
   852 			TestEdgeExists(lToRPosInfo, aExpected, aNumExpected);
   847 			// Now find the nearest edges in the expected range
   853 			// Now find the nearest edges in the expected range
   848 			TTmDocPosSpec trailingPosSpec(pos, TTmDocPosSpec::ETrailing);
   854 			TTmDocPosSpec trailingPosSpec(pos, TTmDocPosSpec::ETrailing);
   849 			const TEdge* trailingExpected
   855 			const TEdge* trailingExpected
   850 				= FindExpectedEdge(trailingPosSpec, aExpected, aNumExpected);
   856 				= FindExpectedEdge(trailingPosSpec, aExpected, aNumExpected);
   851 			TTmDocPosSpec leadingPosSpec(pos, TTmDocPosSpec::ELeading);
   857 			TTmDocPosSpec leadingPosSpec(pos, TTmDocPosSpec::ELeading);
   857 				leadingExpected = trailingExpected;
   863 				leadingExpected = trailingExpected;
   858 			const TEdge* rToLPosEdge
   864 			const TEdge* rToLPosEdge
   859 				= FindExpectedEdge(rToLPosInfo.iDocPos, aExpected, aNumExpected);
   865 				= FindExpectedEdge(rToLPosInfo.iDocPos, aExpected, aNumExpected);
   860 			const TEdge* lToRPosEdge
   866 			const TEdge* lToRPosEdge
   861 				= FindExpectedEdge(lToRPosInfo.iDocPos, aExpected, aNumExpected);
   867 				= FindExpectedEdge(lToRPosInfo.iDocPos, aExpected, aNumExpected);
   862 			aTest(leadingExpected != 0);
   868 			TESTPOINT(leadingExpected != 0);
   863 			aTest(trailingExpected != 0);
   869 			TESTPOINT(trailingExpected != 0);
   864 			aTest(ExpectedEdgesCoincide(leadingExpected, rToLPosEdge)
   870 			TESTPOINT(ExpectedEdgesCoincide(leadingExpected, rToLPosEdge)
   865 				|| ExpectedEdgesCoincide(trailingExpected, rToLPosEdge));
   871 				|| ExpectedEdgesCoincide(trailingExpected, rToLPosEdge));
   866 			aTest(ExpectedEdgesCoincide(leadingExpected, lToRPosEdge)
   872 			TESTPOINT(ExpectedEdgesCoincide(leadingExpected, lToRPosEdge)
   867 				|| ExpectedEdgesCoincide(trailingExpected, lToRPosEdge));
   873 				|| ExpectedEdgesCoincide(trailingExpected, lToRPosEdge));
   868 			// Also check that the "found" ones are at least as good as the
   874 			// Also check that the "found" ones are at least as good as the
   869 			// "expected" ones.
   875 			// "expected" ones.
   870 			aTest(rToLPosInfo.iRightToLeft
   876 			TESTPOINT(rToLPosInfo.iRightToLeft
   871 				|| (!leadingExpected->iRightToLeft && !trailingExpected->iRightToLeft));
   877 				|| (!leadingExpected->iRightToLeft && !trailingExpected->iRightToLeft));
   872 			aTest(!lToRPosInfo.iRightToLeft
   878 			TESTPOINT(!lToRPosInfo.iRightToLeft
   873 				|| (leadingExpected->iRightToLeft && trailingExpected->iRightToLeft));
   879 				|| (leadingExpected->iRightToLeft && trailingExpected->iRightToLeft));
   874 			}
   880 			}
   875 		}
   881 		}
   876 	}
   882 	}
   877 
   883 
   878 /**
   884 /**
   879 Tests RTmGraphemeEdgeIterator::FindEdgeRightwards or
   885 Tests RTmGraphemeEdgeIterator::FindEdgeRightwards or
   880 RTmGraphemeEdgeIterator::FindEdgeLeftwards.
   886 RTmGraphemeEdgeIterator::FindEdgeLeftwards.
   881 */
   887 */
   882 void TestLayoutFindEdgesLeftRight(RTest& aTest, TInt aLine,
   888 void TestLayoutFindEdgesLeftRight(TInt aLine,
   883 	CTestTmTextLayout& aLayout, TBool aRightwards,
   889 	CTestTmTextLayout& aLayout, TBool aRightwards,
   884 	const TEdge* aExpected, TInt aNumExpected)
   890 	const TEdge* aExpected, TInt aNumExpected)
   885 	{
   891 	{
   886 	TInt lineStart;
   892 	TInt lineStart;
   887 	TInt lineEnd;
   893 	TInt lineEnd;
   960 			interp.Close();
   966 			interp.Close();
   961 
   967 
   962 			// Does what we got match what we expect?
   968 			// Does what we got match what we expect?
   963 			if (!leadingExpected)
   969 			if (!leadingExpected)
   964 				{
   970 				{
   965 				aTest(result == RTmGraphemeEdgeIterator::ENone);
   971                 TESTPOINT(result == RTmGraphemeEdgeIterator::ENone);
   966 				}
   972 				}
   967 			else
   973 			else
   968 				{
   974 				{
   969 				aTest(result == RTmGraphemeEdgeIterator::ENearestOnly
   975                 TESTPOINT(result == RTmGraphemeEdgeIterator::ENearestOnly
   970 					|| result == RTmGraphemeEdgeIterator::ENearestAndNext);
   976 					|| result == RTmGraphemeEdgeIterator::ENearestAndNext);
   971 				TTmDocPosSpec nearestPos(nearest.iDocPos);
   977 				TTmDocPosSpec nearestPos(nearest.iDocPos);
   972 				const TEdge* nearestEdge
   978 				const TEdge* nearestEdge
   973 					= FindExpectedEdge(nearestPos, aExpected, aNumExpected);
   979 					= FindExpectedEdge(nearestPos, aExpected, aNumExpected);
   974 				TestExpectedEdge(aTest, nearest, nearestEdge);
   980 				TestExpectedEdge(nearest, nearestEdge);
   975 				const TEdge* matchingEdge = leadingExpected;
   981 				const TEdge* matchingEdge = leadingExpected;
   976 				if (posSpec.iType == TTmDocPosSpec::ELeading)
   982 				if (posSpec.iType == TTmDocPosSpec::ELeading)
   977 					aTest(ExpectedEdgesCoincide(leadingExpected, nearestEdge));
   983 				    TESTPOINT(ExpectedEdgesCoincide(leadingExpected, nearestEdge));
   978 				else if (posSpec.iType == TTmDocPosSpec::ETrailing)
   984 				else if (posSpec.iType == TTmDocPosSpec::ETrailing)
   979 					{
   985 					{
   980 					aTest(ExpectedEdgesCoincide(trailingExpected, nearestEdge));
   986                     TESTPOINT(ExpectedEdgesCoincide(trailingExpected, nearestEdge));
   981 					matchingEdge = trailingExpected;
   987 					matchingEdge = trailingExpected;
   982 					}
   988 					}
   983 				else
   989 				else
   984 					{
   990 					{
   985 					aTest(ExpectedEdgesCoincide(leadingExpected, nearestEdge)
   991                     TESTPOINT(ExpectedEdgesCoincide(leadingExpected, nearestEdge)
   986 						|| ExpectedEdgesCoincide(trailingExpected, nearestEdge));
   992 						|| ExpectedEdgesCoincide(trailingExpected, nearestEdge));
   987 					if (ExpectedEdgesCoincide(trailingExpected, nearestEdge))
   993 					if (ExpectedEdgesCoincide(trailingExpected, nearestEdge))
   988 						matchingEdge = trailingExpected;
   994 						matchingEdge = trailingExpected;
   989 					TBool directionalitiesMatch = leadingExpected->iRightToLeft?
   995 					TBool directionalitiesMatch = leadingExpected->iRightToLeft?
   990 						trailingExpected->iRightToLeft : !trailingExpected->iRightToLeft;
   996 						trailingExpected->iRightToLeft : !trailingExpected->iRightToLeft;
   991 					TBool foundCorrectDirectionality
   997 					TBool foundCorrectDirectionality
   992 						= posSpec.iType == TTmDocPosSpec::ERightToLeft?
   998 						= posSpec.iType == TTmDocPosSpec::ERightToLeft?
   993 							nearest.iRightToLeft : !nearest.iRightToLeft;
   999 							nearest.iRightToLeft : !nearest.iRightToLeft;
   994 					aTest(foundCorrectDirectionality || directionalitiesMatch);
  1000 					TESTPOINT(foundCorrectDirectionality || directionalitiesMatch);
   995 					}
  1001 					}
   996 
  1002 
   997 				// Find next edge in expected list
  1003 				// Find next edge in expected list
   998 				const TEdge* e = matchingEdge;
  1004 				const TEdge* e = matchingEdge;
   999 				const TEdge* end = aRightwards?
  1005 				const TEdge* end = aRightwards?
  1006 					if (!ExpectedEdgesCoincide(e, matchingEdge))
  1012 					if (!ExpectedEdgesCoincide(e, matchingEdge))
  1007 						nextExpected = e;
  1013 						nextExpected = e;
  1008 					}
  1014 					}
  1009 				}
  1015 				}
  1010 			if (!nextExpected)
  1016 			if (!nextExpected)
  1011 				aTest(result == RTmGraphemeEdgeIterator::ENone
  1017 			    TESTPOINT(result == RTmGraphemeEdgeIterator::ENone
  1012 					|| result == RTmGraphemeEdgeIterator::ENearestOnly);
  1018 					|| result == RTmGraphemeEdgeIterator::ENearestOnly);
  1013 			else
  1019 			else
  1014 				{
  1020 				{
  1015 				aTest(result == RTmGraphemeEdgeIterator::ENearestAndNext);
  1021                 TESTPOINT(result == RTmGraphemeEdgeIterator::ENearestAndNext);
  1016 				TestVisualPositionExists(aTest, next, aExpected, aNumExpected);
  1022 				TestVisualPositionExists(next, aExpected, aNumExpected);
  1017 				aTest(next.Ambiguity() != TTmVisualDocPos::ENotFound);
  1023 				TESTPOINT(next.Ambiguity() != TTmVisualDocPos::ENotFound);
  1018 				TTmDocPosSpec nextPosLeft(next.LeftEdge().iDocPos);
  1024 				TTmDocPosSpec nextPosLeft(next.LeftEdge().iDocPos);
  1019 				aTest(ExpectedEdgesCoincide(nextExpected,
  1025 				TESTPOINT(ExpectedEdgesCoincide(nextExpected,
  1020 					FindExpectedEdge(nextPosLeft, aExpected, aNumExpected)));
  1026 					FindExpectedEdge(nextPosLeft, aExpected, aNumExpected)));
  1021 				TTmDocPosSpec nextPosRight(next.RightEdge().iDocPos);
  1027 				TTmDocPosSpec nextPosRight(next.RightEdge().iDocPos);
  1022 				aTest(ExpectedEdgesCoincide(nextExpected,
  1028 				TESTPOINT(ExpectedEdgesCoincide(nextExpected,
  1023 					FindExpectedEdge(nextPosRight, aExpected, aNumExpected)));
  1029 					FindExpectedEdge(nextPosRight, aExpected, aNumExpected)));
  1024 				}
  1030 				}
  1025 			it.Close();
  1031 			it.Close();
  1026 			}
  1032 			}
  1027 		}
  1033 		}
  1028 	}
  1034 	}
  1029 
  1035 
  1030 /**
  1036 /**
  1031 Tests RTmGraphemeEdgeIterator::FindEdgeRightwards.
  1037 Tests RTmGraphemeEdgeIterator::FindEdgeRightwards.
  1032 */
  1038 */
  1033 void TestLayoutFindEdgesRightwards(RTest& aTest, TInt aLine,
  1039 void TestLayoutFindEdgesRightwards(TInt aLine,
  1034 	CTestTmTextLayout& aLayout,
  1040 	CTestTmTextLayout& aLayout,
  1035 	const TEdge* aExpected, TInt aNumExpected)
  1041 	const TEdge* aExpected, TInt aNumExpected)
  1036 	{
  1042 	{
  1037 	TestLayoutFindEdgesLeftRight(aTest, aLine, aLayout, ETrue,
  1043 	TestLayoutFindEdgesLeftRight(aLine, aLayout, ETrue,
  1038 		aExpected, aNumExpected);
  1044 		aExpected, aNumExpected);
  1039 	}
  1045 	}
  1040 
  1046 
  1041 /**
  1047 /**
  1042 Tests RTmGraphemeEdgeIterator::FindEdgeLeftwards.
  1048 Tests RTmGraphemeEdgeIterator::FindEdgeLeftwards.
  1043 */
  1049 */
  1044 void TestLayoutFindEdgesLeftwards(RTest& aTest, TInt aLine,
  1050 void TestLayoutFindEdgesLeftwards(TInt aLine,
  1045 	CTestTmTextLayout& aLayout,
  1051 	CTestTmTextLayout& aLayout,
  1046 	const TEdge* aExpected, TInt aNumExpected)
  1052 	const TEdge* aExpected, TInt aNumExpected)
  1047 	{
  1053 	{
  1048 	TestLayoutFindEdgesLeftRight(aTest, aLine, aLayout, EFalse,
  1054 	TestLayoutFindEdgesLeftRight(aLine, aLayout, EFalse,
  1049 		aExpected, aNumExpected);
  1055 		aExpected, aNumExpected);
  1050 	}
  1056 	}
  1051 
  1057 
  1052 /**
  1058 /**
  1053 Tests RTmGraphemeEdgeIterator::NextPosition. Expected behaviour is to find the
  1059 Tests RTmGraphemeEdgeIterator::NextPosition. Expected behaviour is to find the
  1054 smallest number 'n' that is a position in the same line greater than the input 'i',
  1060 smallest number 'n' that is a position in the same line greater than the input 'i',
  1055 where the positions <i, leading> and <n, trailing> are not coincident.
  1061 where the positions <i, leading> and <n, trailing> are not coincident.
  1056 */
  1062 */
  1057 void TestLayoutFindEdgesForwards(RTest& aTest, TInt aLine,
  1063 void TestLayoutFindEdgesForwards(TInt aLine,
  1058 	CTestTmTextLayout& aLayout,
  1064 	CTestTmTextLayout& aLayout,
  1059 	const TEdge* aExpected, TInt aNumExpected)
  1065 	const TEdge* aExpected, TInt aNumExpected)
  1060 	{
  1066 	{
  1061 	TInt lineStart;
  1067 	TInt lineStart;
  1062 	TInt lineEnd;
  1068 	TInt lineEnd;
  1081 				aExpected, aNumExpected);
  1087 				aExpected, aNumExpected);
  1082 			TTmDocPosSpec out(result, TTmDocPosSpec::ETrailing);
  1088 			TTmDocPosSpec out(result, TTmDocPosSpec::ETrailing);
  1083 			const TEdge* outEdge = FindExpectedEdge(out,
  1089 			const TEdge* outEdge = FindExpectedEdge(out,
  1084 				aExpected, aNumExpected);
  1090 				aExpected, aNumExpected);
  1085 			// ...and test that we failed.
  1091 			// ...and test that we failed.
  1086 			aTest(!inEdge || inEdge->iPos <= i);
  1092 			TESTPOINT(!inEdge || inEdge->iPos <= i);
  1087 			aTest(!outEdge || outEdge->iPos <= i);
  1093 			TESTPOINT(!outEdge || outEdge->iPos <= i);
  1088 			}
  1094 			}
  1089 		else
  1095 		else
  1090 			{
  1096 			{
  1091 			aTest(i < result);
  1097             TESTPOINT(i < result);
  1092 			TTmDocPosSpec in(i, TTmDocPosSpec::ELeading);
  1098 			TTmDocPosSpec in(i, TTmDocPosSpec::ELeading);
  1093 			const TEdge* inEdge = FindExpectedEdge(in,
  1099 			const TEdge* inEdge = FindExpectedEdge(in,
  1094 				aExpected, aNumExpected);
  1100 				aExpected, aNumExpected);
  1095 			TTmDocPosSpec out(result, TTmDocPosSpec::ETrailing);
  1101 			TTmDocPosSpec out(result, TTmDocPosSpec::ETrailing);
  1096 			const TEdge* outEdge = FindExpectedEdge(out,
  1102 			const TEdge* outEdge = FindExpectedEdge(out,
  1097 				aExpected, aNumExpected);
  1103 				aExpected, aNumExpected);
  1098 			aTest(outEdge != 0);
  1104 			TESTPOINT(outEdge != 0);
  1099 			if (inEdge)
  1105 			if (inEdge)
  1100 				{
  1106 				{
  1101 				aTest(lineStart <= i);
  1107                 TESTPOINT(lineStart <= i);
  1102 				aTest(!ExpectedEdgesCoincide(inEdge, outEdge));
  1108                 TESTPOINT(!ExpectedEdgesCoincide(inEdge, outEdge));
  1103 				for (TInt j = i + 1; j != result; ++j)
  1109 				for (TInt j = i + 1; j != result; ++j)
  1104 					{
  1110 					{
  1105 					TTmDocPosSpec between(j, TTmDocPosSpec::ETrailing);
  1111 					TTmDocPosSpec between(j, TTmDocPosSpec::ETrailing);
  1106 					const TEdge* betweenEdge = FindExpectedEdge(between,
  1112 					const TEdge* betweenEdge = FindExpectedEdge(between,
  1107 						aExpected, aNumExpected);
  1113 						aExpected, aNumExpected);
  1108 					aTest(betweenEdge != 0);
  1114 					TESTPOINT(betweenEdge != 0);
  1109 					// Test that, if there actually is a <j, trailing> edge, it is
  1115 					// Test that, if there actually is a <j, trailing> edge, it is
  1110 					// coincident with <i, leading>. If the edge does not exist
  1116 					// coincident with <i, leading>. If the edge does not exist
  1111 					// it does not matter. We can find out if it exists by checking
  1117 					// it does not matter. We can find out if it exists by checking
  1112 					// whether the returned expected edge has the same position
  1118 					// whether the returned expected edge has the same position
  1113 					// we asked for.
  1119 					// we asked for.
  1114 					aTest(ExpectedEdgesCoincide(inEdge, betweenEdge)
  1120 					TESTPOINT(ExpectedEdgesCoincide(inEdge, betweenEdge)
  1115 						|| j != betweenEdge->iPos);
  1121 						|| j != betweenEdge->iPos);
  1116 					}
  1122 					}
  1117 				}
  1123 				}
  1118 			else
  1124 			else
  1119 				{
  1125 				{
  1120 				// before the start means finding the first trailing edge
  1126 				// before the start means finding the first trailing edge
  1121 				aTest (i < lineStart);
  1127 				TESTPOINT (i < lineStart);
  1122 				TInt leastTrailingEdge = KMaxTInt;
  1128 				TInt leastTrailingEdge = KMaxTInt;
  1123 				for (const TEdge* e = aExpected; e != aExpected + aNumExpected;
  1129 				for (const TEdge* e = aExpected; e != aExpected + aNumExpected;
  1124 					++e)
  1130 					++e)
  1125 					{
  1131 					{
  1126 					if (!e->iLeading && e->iPos < leastTrailingEdge)
  1132 					if (!e->iLeading && e->iPos < leastTrailingEdge)
  1127 						leastTrailingEdge = e->iPos;
  1133 						leastTrailingEdge = e->iPos;
  1128 					}
  1134 					}
  1129 				aTest(leastTrailingEdge == result);
  1135 				TESTPOINT(leastTrailingEdge == result);
  1130 				}
  1136 				}
  1131 			}
  1137 			}
  1132 		it.Close();
  1138 		it.Close();
  1133 		}
  1139 		}
  1134 	}
  1140 	}
  1136 /**
  1142 /**
  1137 Tests RTmGraphemeEdgeIterator::PreviousPosition. Expected behaviour is to find the
  1143 Tests RTmGraphemeEdgeIterator::PreviousPosition. Expected behaviour is to find the
  1138 largest number 'n' that is a position in the same line smaller than the input 'i',
  1144 largest number 'n' that is a position in the same line smaller than the input 'i',
  1139 where the positions <i, trailing> and <n, leading> are not coincident.
  1145 where the positions <i, trailing> and <n, leading> are not coincident.
  1140 */
  1146 */
  1141 void TestLayoutFindEdgesBackwards(RTest& aTest, TInt aLine,
  1147 void TestLayoutFindEdgesBackwards(TInt aLine,
  1142 	CTestTmTextLayout& aLayout,
  1148 	CTestTmTextLayout& aLayout,
  1143 	const TEdge* aExpected, TInt aNumExpected)
  1149 	const TEdge* aExpected, TInt aNumExpected)
  1144 	{
  1150 	{
  1145 	TInt lineStart;
  1151 	TInt lineStart;
  1146 	TInt lineEnd;
  1152 	TInt lineEnd;
  1159 		if (result == KErrNotFound)
  1165 		if (result == KErrNotFound)
  1160 			{
  1166 			{
  1161 			// Must be at or before the line's beginning.
  1167 			// Must be at or before the line's beginning.
  1162 			// Could possibly be that there are no leading edges in the line, but
  1168 			// Could possibly be that there are no leading edges in the line, but
  1163 			// we'll ignore that possibility.
  1169 			// we'll ignore that possibility.
  1164 			aTest(i <= lineStart);
  1170 			TESTPOINT(i <= lineStart);
  1165 			}
  1171 			}
  1166 		else
  1172 		else
  1167 			{
  1173 			{
  1168 			aTest(result < i);
  1174 			TESTPOINT(result < i);
  1169 			TTmDocPosSpec out(result, TTmDocPosSpec::ELeading);
  1175 			TTmDocPosSpec out(result, TTmDocPosSpec::ELeading);
  1170 			const TEdge* outEdge = FindExpectedEdge(out,
  1176 			const TEdge* outEdge = FindExpectedEdge(out,
  1171 				aExpected, aNumExpected);
  1177 				aExpected, aNumExpected);
  1172 			aTest(outEdge != 0);
  1178 			TESTPOINT(outEdge != 0);
  1173 			TTmDocPosSpec in(i, TTmDocPosSpec::ETrailing);
  1179 			TTmDocPosSpec in(i, TTmDocPosSpec::ETrailing);
  1174 			const TEdge* inEdge = FindExpectedEdge(in,
  1180 			const TEdge* inEdge = FindExpectedEdge(in,
  1175 				aExpected, aNumExpected);
  1181 				aExpected, aNumExpected);
  1176 			// if we could not find a trailing edge at this number, then we
  1182 			// if we could not find a trailing edge at this number, then we
  1177 			// were beyond the end of the line.
  1183 			// were beyond the end of the line.
  1178 			if (inEdge && !inEdge->iLeading)
  1184 			if (inEdge && !inEdge->iLeading)
  1179 				{
  1185 				{
  1180 				aTest(inEdge != 0);
  1186 				TESTPOINT(inEdge != 0);
  1181 				aTest(!ExpectedEdgesCoincide(inEdge, outEdge));
  1187 				TESTPOINT(!ExpectedEdgesCoincide(inEdge, outEdge));
  1182 				for (TInt j = result + 1; j != i; ++j)
  1188 				for (TInt j = result + 1; j != i; ++j)
  1183 					{
  1189 					{
  1184 					TTmDocPosSpec between(j, TTmDocPosSpec::ELeading);
  1190 					TTmDocPosSpec between(j, TTmDocPosSpec::ELeading);
  1185 					const TEdge* betweenEdge = FindExpectedEdge(between,
  1191 					const TEdge* betweenEdge = FindExpectedEdge(between,
  1186 						aExpected, aNumExpected);
  1192 						aExpected, aNumExpected);
  1187 					aTest(betweenEdge != 0);
  1193 					TESTPOINT(betweenEdge != 0);
  1188 					// Test that, if there actually is a <j, trailing> edge, it is
  1194 					// Test that, if there actually is a <j, trailing> edge, it is
  1189 					// coincident with <i, leading>. If the edge does not exist
  1195 					// coincident with <i, leading>. If the edge does not exist
  1190 					// it does not matter. We can find out if it exists by checking
  1196 					// it does not matter. We can find out if it exists by checking
  1191 					// whether the returned expected edge has the same position
  1197 					// whether the returned expected edge has the same position
  1192 					// we asked for.
  1198 					// we asked for.
  1193 					aTest(ExpectedEdgesCoincide(inEdge, betweenEdge)
  1199 					TESTPOINT(ExpectedEdgesCoincide(inEdge, betweenEdge)
  1194 						|| j != betweenEdge->iPos);
  1200 						|| j != betweenEdge->iPos);
  1195 					}
  1201 					}
  1196 				}
  1202 				}
  1197 			else
  1203 			else
  1198 				{
  1204 				{
  1202 					++e)
  1208 					++e)
  1203 					{
  1209 					{
  1204 					if (e->iLeading && greatestLeadingEdge < e->iPos)
  1210 					if (e->iLeading && greatestLeadingEdge < e->iPos)
  1205 						greatestLeadingEdge = e->iPos;
  1211 						greatestLeadingEdge = e->iPos;
  1206 					}
  1212 					}
  1207 				aTest(greatestLeadingEdge == result);
  1213 				TESTPOINT(greatestLeadingEdge == result);
  1208 				}
  1214 				}
  1209 			}
  1215 			}
  1210 		it.Close();
  1216 		it.Close();
  1211 		}
  1217 		}
  1212 	}
  1218 	}
  1213 
  1219 
  1214 typedef void FTestLine(RTest& aTest, TInt aLine,
  1220 typedef void FTestLine(TInt aLine,
  1215 	CTestTmTextLayout& aLayout,
  1221 	CTestTmTextLayout& aLayout,
  1216 	const TEdge* aExpected, TInt aNumExpected);
  1222 	const TEdge* aExpected, TInt aNumExpected);
  1217 
  1223 
  1218 /**
  1224 /**
  1219 Runs a particular test for each line in the input data.
  1225 Runs a particular test for each line in the input data.
  1220 */
  1226 */
  1221 void TestEachLine(RTest& aTest, FTestLine* aFn,
  1227 void TestEachLine(FTestLine* aFn,
  1222 	CTestTmTextLayout& aLayout, const TEdge* aExpected, TInt aNumExpected)
  1228 	CTestTmTextLayout& aLayout, const TEdge* aExpected, TInt aNumExpected)
  1223 	{
  1229 	{
  1224 	TInt line = 0;
  1230 	TInt line = 0;
  1225 	TInt start = 0;
  1231 	TInt start = 0;
  1226 	for (TInt end = 1; end != aNumExpected; ++end)
  1232 	for (TInt end = 1; end != aNumExpected; ++end)
  1227 		{
  1233 		{
  1228 		if (aExpected[end - 1].iNext == EEdgeNewline)
  1234 		if (aExpected[end - 1].iNext == EEdgeNewline)
  1229 			{
  1235 			{
  1230 			aFn(aTest, line, aLayout, aExpected + start, end - start);
  1236 			aFn(line, aLayout, aExpected + start, end - start);
  1231 			start = end;
  1237 			start = end;
  1232 			++line;
  1238 			++line;
  1233 			}
  1239 			}
  1234 		}
  1240 		}
  1235 	}
  1241 	}
  1236 
  1242 
  1237 /**
  1243 /**
  1238 Tests TTmGraphemeIterator and supporting functionality for the specified
  1244 Tests TTmGraphemeIterator and supporting functionality for the specified
  1239 layout.
  1245 layout.
  1240 */
  1246 */
  1241 void TestLayoutL(RTest& aTest, CTestTmTextLayout& aLayout,
  1247 void TestLayoutL(CTestTmTextLayout& aLayout,
  1242 	const TEdge* aExpected, TInt aNumExpected)
  1248 	const TEdge* aExpected, TInt aNumExpected)
  1243 	{
  1249 	{
  1244 	aTest.Start(_L("Simple iteration"));
  1250 	TESTPRINT(_L("Simple iteration"));
  1245 	TestLayoutSimplePass(aTest, aLayout, aExpected, aNumExpected);
  1251 	TestLayoutSimplePass(aLayout, aExpected, aNumExpected);
  1246 	aTest.Next(_L("FindXPos"));
  1252 	TESTPRINT(_L("FindXPos"));
  1247 	TestEachLine(aTest, TestLayoutFindXPos,
  1253 	TestEachLine(TestLayoutFindXPos,
  1248 		aLayout, aExpected, aNumExpected);
  1254 		aLayout, aExpected, aNumExpected);
  1249 	aTest.Next(_L("FindXPos (unambiguous edges)"));
  1255 	TESTPRINT(_L("FindXPos (unambiguous edges)"));
  1250 	TestEachLine(aTest, TestLayoutFindXPosEdges,
  1256 	TestEachLine(TestLayoutFindXPosEdges,
  1251 		aLayout, aExpected, aNumExpected);
  1257 		aLayout, aExpected, aNumExpected);
  1252 	aTest.Next(_L("FindEdge"));
  1258 	TESTPRINT(_L("FindEdge"));
  1253 	TestEachLine(aTest, TestLayoutFindEdgesInVisualOrder,
  1259 	TestEachLine(TestLayoutFindEdgesInVisualOrder,
  1254 		aLayout, aExpected, aNumExpected);
  1260 		aLayout, aExpected, aNumExpected);
  1255 	TestEachLine(aTest, TestLayoutFindEdgesByDirectionality,
  1261 	TestEachLine(TestLayoutFindEdgesByDirectionality,
  1256 		aLayout, aExpected, aNumExpected);
  1262 		aLayout, aExpected, aNumExpected);
  1257 	aTest.Next(_L("FindEdgeRightwards"));
  1263 	TESTPRINT(_L("FindEdgeRightwards"));
  1258 	TestEachLine(aTest, TestLayoutFindEdgesRightwards,
  1264 	TestEachLine(TestLayoutFindEdgesRightwards,
  1259 		aLayout, aExpected, aNumExpected);
  1265 		aLayout, aExpected, aNumExpected);
  1260 	aTest.Next(_L("FindEdgeLeftwards"));
  1266 	TESTPRINT(_L("FindEdgeLeftwards"));
  1261 	TestEachLine(aTest, TestLayoutFindEdgesLeftwards,
  1267 	TestEachLine(TestLayoutFindEdgesLeftwards,
  1262 		aLayout, aExpected, aNumExpected);
  1268 		aLayout, aExpected, aNumExpected);
  1263 	aTest.Next(_L("NextPosition"));
  1269 	TESTPRINT(_L("NextPosition"));
  1264 	TestEachLine(aTest, TestLayoutFindEdgesForwards,
  1270 	TestEachLine(TestLayoutFindEdgesForwards,
  1265 		aLayout, aExpected, aNumExpected);
  1271 		aLayout, aExpected, aNumExpected);
  1266 	aTest.Next(_L("PreviousPosition"));
  1272 	TESTPRINT(_L("PreviousPosition"));
  1267 	TestEachLine(aTest, TestLayoutFindEdgesBackwards,
  1273 	TestEachLine(TestLayoutFindEdgesBackwards,
  1268 		aLayout, aExpected, aNumExpected);
  1274 		aLayout, aExpected, aNumExpected);
  1269 	aTest.End();
       
  1270 	}
  1275 	}
  1271 
  1276 
  1272 /**
  1277 /**
  1273 Tests TTmGraphemeIterator and supporting functionality for each piece of text.
  1278 Tests TTmGraphemeIterator and supporting functionality for each piece of text.
  1274 */
  1279 */
  1275 void RunTestsL(RTest& aTest)
  1280 TVerdict CTGraphemeIteratorStep::doTestStepL()
  1276 	{
  1281 	{
  1277 	aTest.Start(_L(" @SYMTestCaseID:SYSLIB-FORM-LEGACY-GRAPHEMEITERATOR-0001 DocPosMatches "));
  1282     SetTestStepResult(EPass);
  1278 	TestDocPosMatches(aTest);
  1283     TestStep = this;
  1279 	aTest.Next(_L("Simple Latin"));
  1284     TESTPRINT(_L("RTmGraphemeEdgeIterator unit"));
       
  1285     
       
  1286     TESTPRINT(_L(" @SYMTestCaseID:SYSLIB-FORM-LEGACY-GRAPHEMEITERATOR-0001 DocPosMatches "));
       
  1287 	TestDocPosMatches();
       
  1288 	TESTPRINT(_L("Simple Latin"));
  1280 	CTestTmTextLayout* latin1 = CTestTmTextLayout::NewLC(
  1289 	CTestTmTextLayout* latin1 = CTestTmTextLayout::NewLC(
  1281 		KLatin1, 100, Transliterate);
  1290 		KLatin1, 100, Transliterate);
  1282 	TestLayoutL(aTest, *latin1, KLatin1Edges,
  1291 	TestLayoutL( *latin1, KLatin1Edges,
  1283 		sizeof(KLatin1Edges)/sizeof(KLatin1Edges[0]));
  1292 		sizeof(KLatin1Edges)/sizeof(KLatin1Edges[0]));
  1284 	CleanupStack::PopAndDestroy(latin1);
  1293 	CleanupStack::PopAndDestroy(latin1);
  1285 
  1294 
  1286 	aTest.Next(_L("Simple Arabic"));
  1295 	TESTPRINT(_L("Simple Arabic"));
  1287 	CTestTmTextLayout* arabic1 = CTestTmTextLayout::NewLC(
  1296 	CTestTmTextLayout* arabic1 = CTestTmTextLayout::NewLC(
  1288 		KArabic1, 100, Transliterate);
  1297 		KArabic1, 100, Transliterate);
  1289 	TestLayoutL(aTest, *arabic1, KArabic1Edges,
  1298 	TestLayoutL(*arabic1, KArabic1Edges,
  1290 		sizeof(KArabic1Edges)/sizeof(KArabic1Edges[0]));
  1299 		sizeof(KArabic1Edges)/sizeof(KArabic1Edges[0]));
  1291 	CleanupStack::PopAndDestroy(arabic1);
  1300 	CleanupStack::PopAndDestroy(arabic1);
  1292 
  1301 
  1293 	aTest.Next(_L("Latin with combining marks and zero width characters"));
  1302 	TESTPRINT(_L("Latin with combining marks and zero width characters"));
  1294 	CTestTmTextLayout* combiners1 = CTestTmTextLayout::NewLC(
  1303 	CTestTmTextLayout* combiners1 = CTestTmTextLayout::NewLC(
  1295 		KCombiners1, 20, Transliterate);
  1304 		KCombiners1, 20, Transliterate);
  1296 	TestLayoutL(aTest, *combiners1, KCombiners1Edges,
  1305 	TestLayoutL(*combiners1, KCombiners1Edges,
  1297 		sizeof(KCombiners1Edges)/sizeof(KCombiners1Edges[0]));
  1306 		sizeof(KCombiners1Edges)/sizeof(KCombiners1Edges[0]));
  1298 	CleanupStack::PopAndDestroy(combiners1);
  1307 	CleanupStack::PopAndDestroy(combiners1);
  1299 
  1308 
  1300 	aTest.Next(_L("Bidirectional text with combining marks"));
  1309 	TESTPRINT(_L("Bidirectional text with combining marks"));
  1301 	CTestTmTextLayout* bidi1 = CTestTmTextLayout::NewLC(
  1310 	CTestTmTextLayout* bidi1 = CTestTmTextLayout::NewLC(
  1302 		KBidi1, 60, Transliterate);
  1311 		KBidi1, 60, Transliterate);
  1303 	TestLayoutL(aTest, *bidi1, KBidi1Edges,
  1312 	TestLayoutL( *bidi1, KBidi1Edges,
  1304 		sizeof(KBidi1Edges)/sizeof(KBidi1Edges[0]));
  1313 		sizeof(KBidi1Edges)/sizeof(KBidi1Edges[0]));
  1305 	CleanupStack::PopAndDestroy(bidi1);
  1314 	CleanupStack::PopAndDestroy(bidi1);
  1306 
  1315 
  1307 	aTest.Next(_L("Bidirectional text with combining marks and 'amtriguity'"));
  1316 	TESTPRINT(_L("Bidirectional text with combining marks and 'amtriguity'"));
  1308 	CTestTmTextLayout* bidi2 = CTestTmTextLayout::NewLC(
  1317 	CTestTmTextLayout* bidi2 = CTestTmTextLayout::NewLC(
  1309 		KBidi2, 60, Transliterate);
  1318 		KBidi2, 60, Transliterate);
  1310 	TestLayoutL(aTest, *bidi2, KBidi2Edges,
  1319 	TestLayoutL(*bidi2, KBidi2Edges,
  1311 		sizeof(KBidi2Edges)/sizeof(KBidi2Edges[0]));
  1320 		sizeof(KBidi2Edges)/sizeof(KBidi2Edges[0]));
  1312 	CleanupStack::PopAndDestroy(bidi2);
  1321 	CleanupStack::PopAndDestroy(bidi2);
  1313 
  1322 
  1314 	aTest.Next(_L("Small paragraphs of alternating directionality"));
  1323 	TESTPRINT(_L("Small paragraphs of alternating directionality"));
  1315 	CTestTmTextLayout* paragraphs1 = CTestTmTextLayout::NewLC(
  1324 	CTestTmTextLayout* paragraphs1 = CTestTmTextLayout::NewLC(
  1316 		KParagraphs1, 20, Transliterate);
  1325 		KParagraphs1, 20, Transliterate);
  1317 	TestLayoutL(aTest, *paragraphs1, KParagraphs1Edges,
  1326 	TestLayoutL(*paragraphs1, KParagraphs1Edges,
  1318 		sizeof(KParagraphs1Edges)/sizeof(KParagraphs1Edges[0]));
  1327 		sizeof(KParagraphs1Edges)/sizeof(KParagraphs1Edges[0]));
  1319 	CleanupStack::PopAndDestroy(paragraphs1);
  1328 	CleanupStack::PopAndDestroy(paragraphs1);
  1320 
  1329 
  1321 	aTest.Next(_L("Lines ending over or next to embedded runs"));
  1330 	TESTPRINT(_L("Lines ending over or next to embedded runs"));
  1322 	CTestTmTextLayout* embedded1 = CTestTmTextLayout::NewLC(
  1331 	CTestTmTextLayout* embedded1 = CTestTmTextLayout::NewLC(
  1323 		KEmbedded1, 20, Transliterate);
  1332 		KEmbedded1, 20, Transliterate);
  1324 	TestLayoutL(aTest, *embedded1, KEmbedded1Edges,
  1333 	TestLayoutL( *embedded1, KEmbedded1Edges,
  1325 		sizeof(KEmbedded1Edges)/sizeof(KEmbedded1Edges[0]));
  1334 		sizeof(KEmbedded1Edges)/sizeof(KEmbedded1Edges[0]));
  1326 	CleanupStack::PopAndDestroy(embedded1);
  1335 	CleanupStack::PopAndDestroy(embedded1);
  1327 
  1336 
  1328 	aTest.End();
  1337 	return TestStepResult();
  1329 	}
  1338 	}
  1330 
  1339 
  1331 /**
       
  1332 Tests TTmGraphemeIterator and supporting functionality.
       
  1333 */
       
  1334 TInt E32Main()
       
  1335 	{
       
  1336 	RTest rtest(_L("RTmGraphemeEdgeIterator unit"));
       
  1337 	CTrapCleanup* TrapCleanup = CTrapCleanup::New();
       
  1338 	rtest.Title();
       
  1339 	TRAPD(err, RunTestsL(rtest));
       
  1340 	rtest.Close();
       
  1341 	delete TrapCleanup;
       
  1342 	return err;
       
  1343 	}
       
  1344