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