Update contrib.
2 * Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
15 * Test code for MTmSource functionality
23 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
24 #include "TAGMA_INTERNAL.H"
27 #include "ttmsource.h"
30 #define UNUSED_VAR(a) a = a
32 namespace LocalToTTmSource
34 CTTmSourceStep* TestStep = NULL;
35 #define TESTPOINT(p) TestStep->testpoint(p,(TText8*)__FILE__,__LINE__)
36 #define TESTPRINT(p) TestStep->print(p,(TText8*)__FILE__,__LINE__)
38 using namespace LocalToTTmSource;
40 class TTestGraphicsDeviceMap : public MGraphicsDeviceMap
43 TInt HorizontalTwipsToPixels(TInt a) const { return a; }
44 TInt VerticalTwipsToPixels(TInt a) const { return a; }
45 TInt HorizontalPixelsToTwips(TInt a) const { return a; }
46 TInt VerticalPixelsToTwips(TInt a) const { return a; }
47 TInt GetNearestFontInTwips(CFont*&,const TFontSpec&)
51 void ReleaseFont(CFont*) {}
54 class CTestPicture : public CPicture
58 virtual void Draw(CGraphicsContext&, const TPoint&, const TRect&, MGraphicsDeviceMap*) const {}
59 virtual void ExternalizeL(RWriteStream&) const {}
60 virtual void GetOriginalSizeInTwips(TSize&) const {}
61 virtual TBool LineBreakPossible(TUint aClass,TBool aBeforePicture,TBool aHaveSpaces) const
66 TESTPOINT(aClass == iClassBefore);
67 TESTPOINT(aHaveSpaces == iSpacesBefore);
70 TESTPOINT(aClass == iClassAfter);
71 TESTPOINT(aHaveSpaces == iSpacesAfter);
74 // expected parameters for LineBreakPossible
79 // Results for breaking before/breaking after
82 mutable TInt iRequestCount;
85 class TTestSource : public MTmSource
88 TTestSource() : iPicturePos(-1) {}
89 virtual ~TTestSource() {}
90 MGraphicsDeviceMap& FormatDevice() const { return iGDM; }
91 MGraphicsDeviceMap& InterpretDevice() const { return iGDM; }
92 TInt DocumentLength() const
94 return iText->Length();
96 void GetText(TInt aPos,TPtrC& aText, TTmCharFormat& aFormat) const
100 aText.Set(iText->Mid(aPos));
102 void GetParagraphFormatL(TInt, RTmParFormat& aFormat) const
107 CPicture* PictureL(TInt aPos) const
109 return aPos == iPicturePos? iPicture : 0;
111 TInt ParagraphStart(TInt) const { return 0; }
113 virtual TUint LineBreakClass(TUint aCode, TUint& aRangeStart,
114 TUint& aRangeEnd) const
118 aRangeStart = aRangeEnd = aCode;
119 return ESaLineBreakClass;
121 if ('0' <= aCode && aCode <= '9')
123 aRangeStart = aRangeEnd = aCode;
124 return ELineBreakClasses + aCode - '0';
126 return MTmSource::LineBreakClass(aCode, aRangeStart, aRangeEnd);
129 virtual TBool LineBreakPossible(TUint aPrevClass, TUint aNextClass,
130 TBool aHaveSpaces) const
132 TInt first = static_cast<TInt>(aPrevClass);
133 TInt second = static_cast<TInt>(aNextClass);
134 TInt customCount = 0;
140 if (ELineBreakClasses <= first && first < ELineBreakClasses + 10)
143 TESTPOINT(first - ELineBreakClasses + '0' == FindNextCustomClass());
144 TInt countSpaces = CountSpaces();
145 TESTPOINT(!aHaveSpaces == !countSpaces);
147 if (ELineBreakClasses <= second && second < ELineBreakClasses + 10)
150 TInt c = FindNextCustomClass();
151 TESTPOINT(second - ELineBreakClasses + '0' == c);
153 if (0 == customCount)
154 return MTmSource::LineBreakPossible(aPrevClass, aNextClass, aHaveSpaces);
155 // Between custom and non-custom classes, allow a break only with spaces
156 // or between @ and 5
157 if (1 == customCount)
159 || (first == ESaLineBreakClass && second == ELineBreakClasses + 5)
160 || (second == ESaLineBreakClass && first == ELineBreakClasses + 5);
161 // Allow a break with spaces except after '0' or before '9'
163 return aPrevClass != ELineBreakClasses && aNextClass != ELineBreakClasses + 9;
164 // Allow a break only between a class and the class one more than it.
165 return aPrevClass + 1 == aNextClass;
168 virtual TBool GetLineBreakInContext(
169 const TDesC& aText, TInt aMinBreakPos, TInt aMaxBreakPos,
170 TBool aForwards,TInt& aBreakPos) const
172 TESTPOINT (iDirection == (aForwards? 1 : -1));
173 // The allowable break-points should not include the first
174 // and last characters of the run.
175 TESTPOINT (aMinBreakPos != 0);
176 for (TInt i = aMinBreakPos - 1; i <= aMaxBreakPos; ++i)
177 TESTPOINT('@' == aText[i]);
179 aBreakPos = iText->Ptr() + iSaBreakpoint - aText.Ptr();
180 return aMinBreakPos <= aBreakPos && aBreakPos <= aMaxBreakPos;
183 virtual TBool IsHangingCharacter(TUint aChar) const
185 ++iHangingCharRequestCount;
186 TESTPOINT(aChar == (*iText)[iMaxBreakPos]);
195 TBool GetLineBreakL(const TDesC& aText, TInt aDocPos,
196 TInt aMinBreakPos, TInt aMaxBreakPos, TBool aForwards,
197 TInt& aBreakPos, TInt& aHangingChars, TInt& aBreakPosAfterSpaces) const
200 iMaxBreakPos = aMaxBreakPos;
201 iMinBreakPos = aMinBreakPos;
202 iHangingCharRequestCount = 0;
204 iDirection = aForwards? 1 : -1;
205 iCurrentPos = aForwards? aMinBreakPos : aMaxBreakPos - 1;
206 TBool r = MTmSource::GetLineBreakL(aText, aDocPos,
207 aMinBreakPos, aMaxBreakPos, aForwards,
208 aBreakPos, aHangingChars, aBreakPosAfterSpaces);
211 TESTPOINT(aMinBreakPos <= aBreakPos);
212 TESTPOINT(0 < aBreakPos);
213 TESTPOINT(aBreakPos <= aHangingChars);
214 TESTPOINT(aHangingChars <= aBreakPosAfterSpaces);
215 TESTPOINT(aBreakPos <= aMaxBreakPos);
216 TESTPOINT(aHangingChars == aBreakPos || iHangingChar);
217 // If the direction was backwards, the algorithm should have
218 // checked if a hanging character was allowed.
219 // This condition could be relaxed to allow it not to be checked
220 // if there is no break allowed between the possible hanging
221 // character and the previous character.
222 TESTPOINT(!aForwards || aText.Length() == aMaxBreakPos
223 || 0 < iHangingCharRequestCount);
224 // If the maximum break point was chosen or exceeded, the algorithm
225 // should have checked to find out whether a hanging character is
227 TESTPOINT(aHangingChars < aMaxBreakPos
228 || 0 < iHangingCharRequestCount);
229 // Check that only spaces exist between aHangingChars and
231 for (TInt i = aHangingChars; i != aBreakPosAfterSpaces; ++i)
234 TESTPOINT(ESpLineBreakClass == LineBreakClass(aText[i], n, n));
236 // Check that all the spaces were counted
237 TESTPOINT(aBreakPosAfterSpaces == aText.Length()
238 || aText[aBreakPosAfterSpaces] != ' ');
240 // Find out how many runs of two or more Sa there are, and check that
241 // this matches the number of times that it was requested.
242 TInt minChecked = aMinBreakPos - 1;
243 TInt maxChecked = aMaxBreakPos + 2;
247 maxChecked = aBreakPos + 1;
249 minChecked = aBreakPos - 1;
253 if (aText.Length() < maxChecked)
254 maxChecked = aText.Length();
257 TESTPOINT (maxChecked - minChecked < 2
258 || aText[minChecked] != '@'
259 || aText[minChecked + 1] != '@'
261 || aHangingChars == iSaBreakpoint);
262 for (; minChecked != maxChecked; ++minChecked)
264 if (aText[minChecked] == '@')
275 TESTPOINT(sasSoFar < 2 || aForwards || aHangingChars == iSaBreakpoint);
276 TESTPOINT(runs == iSaRequestCount);
280 TInt FindNextCustomClass() const
282 TInt end = iDirection < 0? -1 : iText->Length();
283 for (; iCurrentPos != end; iCurrentPos += iDirection)
285 TInt c = (*iText)[iCurrentPos];
286 if ('0' <= c && c <= '9')
291 TInt CountSpaces() const
293 TInt end = iDirection < 0? -1 : iText->Length();
295 if (iCurrentPos == end)
297 iCurrentPos += iDirection;
298 for (; iCurrentPos != end; iCurrentPos += iDirection, ++count)
300 TInt c = (*iText)[iCurrentPos];
308 mutable TTestGraphicsDeviceMap iGDM;
309 mutable const TDesC* iText;
310 mutable TInt iMaxBreakPos;
311 mutable TInt iMinBreakPos;
313 mutable TInt iDirection;
314 mutable TInt iCurrentPos;
315 mutable TInt iHangingCharRequestCount;
316 mutable TInt iSaRequestCount;
327 TInt TestLineBreak(const TDesC& aText, TInt aSaBreak, TBool aHangingChar,
328 TInt aMin, TInt aMax, TBool aForwards)
331 aMax = aText.Length();
333 t.iHangingChar = aHangingChar;
334 t.iSaBreakpoint = aSaBreak;
339 return t.GetLineBreakL(aText, 0, aMin, aMax, aForwards, b0, b1, b2)?
343 CTTmSourceStep::CTTmSourceStep()
349 TVerdict CTTmSourceStep::doTestStepL()
351 SetTestStepResult(EPass);
353 TESTPRINT(_L("TTmSource - MTmSource tests"));
354 TESTPRINT(_L(" @SYMTestCaseID:SYSLIB-FORM-LEGACY-TTMSOURCE-0001 Line-Break Tests: "));
356 TEST(-1 == TestLineBreak(_L(""), 0, 0, 0, 0, 0));
357 TEST(-1 == TestLineBreak(_L("5"), 0, 0, 0, 0, 0));
358 TEST(-1 == TestLineBreak(_L("5"), 0, 0, 0, 0, 1));
359 TEST(-1 == TestLineBreak(_L("@"), 1, 0, 0, 0, 0));
360 TEST(1 == TestLineBreak(_L("a b"), 0, 0, 0, 0, 0));
361 TEST(-1 == TestLineBreak(_L("0 0 0 9 9"), 0, 0, 0, 0, 0));
362 TEST(-1 == TestLineBreak(_L("0 0 0 9 9"), 0, 0, 0, 0, 1));
363 TEST(9 == TestLineBreak(_L("4242454445"), 0, 0, 0, 0, 0));
364 TEST(5 == TestLineBreak(_L("4242454445"), 0, 0, 0, 0, 1));
365 TEST(5 == TestLineBreak(_L("hello there"), 0, 0, 0, 0, 0));
366 TEST(5 == TestLineBreak(_L("hello there"), 0, 0, 0, 0, 1));
367 TEST(-1 == TestLineBreak(_L("hel the re"), 0, 0, 5, 7, 0));
368 TEST(-1 == TestLineBreak(_L("hel the re"), 0, 0, 5, 7, 1));
369 TEST(8 == TestLineBreak(_L("hel the re"), 0, 1, 5, 7, 0));
370 TEST(8 == TestLineBreak(_L("hel the re"), 0, 1, 6, 7, 1));
371 TEST(3 == TestLineBreak(_L("@@@@@"), 3, 0, 0, 0, 0));
372 TEST(3 == TestLineBreak(_L("@@@@@"), 3, 0, 0, 0, 1));
373 TEST(5 == TestLineBreak(_L("9999@@@@@00099@@@@gfra"), 5, 0, 5, 0, 0));
374 TEST(5 == TestLineBreak(_L("9999@@@@@00099@@@@gfra"), 5, 0, 5, 0, 1));
375 TEST(16 == TestLineBreak(_L("9999@@@@@00099@@@@gfra"), 16, 0, 0, 0, 0));
376 TEST(16 == TestLineBreak(_L("9999@@@@@00099@@@@gfra"), 16, 0, 0, 0, 1));
377 TEST(5 == TestLineBreak(_L("55@@@55"), 0, 0, 0, 0, 0));
378 TEST(2 == TestLineBreak(_L("55@@@55"), 0, 0, 0, 0, 1));
379 TEST(3 == TestLineBreak(_L("55@55"), 0, 0, 0, 0, 0));
380 TEST(2 == TestLineBreak(_L("55@55"), 0, 0, 0, 0, 1));
382 // Test for DEF046468, which was caused by the TLineBreakIterator constructor accessing past the end of a string
383 TESTPRINT(_L("Line-Break DEF046468 Test:"));
384 // Create a string of 16 chars with a picture code at the 17th position
385 _LIT(KLarsString, "dolor sit amet, \xFFFC");
386 // Create a TPtrC for the 16 character string ( with the picture code after the string in memory )
387 TBufC<20> KTestBuffer(KLarsString);
388 TPtrC KTestString( reinterpret_cast<const TUint16*>(KTestBuffer.Ptr()), 16);
389 // Test the iterator overrun. If iterator accesses past the end of the array, it'll get picture code and crash
390 TEST(9 == TestLineBreak(KTestString,0,0,1,15,0));
392 return TestStepResult();