textrendering/textformatting/test/src/TTmSource.cpp
branchRCL_3
changeset 17 336bee5c2d35
parent 16 748ec5531811
equal deleted inserted replaced
16:748ec5531811 17:336bee5c2d35
     1 /*
     1 /*
     2 * Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 * Copyright (c) 2002-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".
    22 
    22 
    23 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
    23 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
    24 #include "TAGMA_INTERNAL.H"
    24 #include "TAGMA_INTERNAL.H"
    25 #endif
    25 #endif
    26 
    26 
    27 #include "ttmsource.h"
       
    28 
       
    29 
       
    30 #define UNUSED_VAR(a) a = a
    27 #define UNUSED_VAR(a) a = a
    31 
    28 
    32 namespace LocalToTTmSource
    29 CTrapCleanup* TrapCleanup;
    33 {
    30 RTest test(_L("TTmSource - MTmSource tests"));
    34 CTTmSourceStep* TestStep = NULL;
       
    35 #define TESTPOINT(p) TestStep->testpoint(p,(TText8*)__FILE__,__LINE__)
       
    36 #define TESTPRINT(p) TestStep->print(p,(TText8*)__FILE__,__LINE__)
       
    37 }
       
    38 using namespace LocalToTTmSource;
       
    39 
    31 
    40 class TTestGraphicsDeviceMap : public MGraphicsDeviceMap
    32 class TTestGraphicsDeviceMap : public MGraphicsDeviceMap
    41 	{
    33 	{
    42 public:
    34 public:
    43 	TInt HorizontalTwipsToPixels(TInt a) const { return a; }
    35 	TInt HorizontalTwipsToPixels(TInt a) const { return a; }
    61 	virtual TBool LineBreakPossible(TUint aClass,TBool aBeforePicture,TBool aHaveSpaces) const
    53 	virtual TBool LineBreakPossible(TUint aClass,TBool aBeforePicture,TBool aHaveSpaces) const
    62 		{
    54 		{
    63 		++iRequestCount;
    55 		++iRequestCount;
    64 		if (aBeforePicture)
    56 		if (aBeforePicture)
    65 			{
    57 			{
    66             TESTPOINT(aClass == iClassBefore);
    58 			test(aClass == iClassBefore);
    67             TESTPOINT(aHaveSpaces == iSpacesBefore);
    59 			test(aHaveSpaces == iSpacesBefore);
    68 			return iResultBefore;
    60 			return iResultBefore;
    69 			}
    61 			}
    70 		TESTPOINT(aClass == iClassAfter);
    62 		test(aClass == iClassAfter);
    71 		TESTPOINT(aHaveSpaces == iSpacesAfter);
    63 		test(aHaveSpaces == iSpacesAfter);
    72 		return iResultAfter;
    64 		return iResultAfter;
    73 		}
    65 		}
    74 	// expected parameters for LineBreakPossible
    66 	// expected parameters for LineBreakPossible
    75 	TUint iClassBefore;
    67 	TUint iClassBefore;
    76 	TUint iClassAfter;
    68 	TUint iClassAfter;
   138 			second = aPrevClass;
   130 			second = aPrevClass;
   139 			}
   131 			}
   140 		if (ELineBreakClasses <= first && first < ELineBreakClasses + 10)
   132 		if (ELineBreakClasses <= first && first < ELineBreakClasses + 10)
   141 			{
   133 			{
   142 			++customCount;
   134 			++customCount;
   143 			TESTPOINT(first - ELineBreakClasses + '0' == FindNextCustomClass());
   135 			test(first - ELineBreakClasses + '0' == FindNextCustomClass());
   144 			TInt countSpaces = CountSpaces();
   136 			TInt countSpaces = CountSpaces();
   145 			TESTPOINT(!aHaveSpaces == !countSpaces);
   137 			test(!aHaveSpaces == !countSpaces);
   146 			}
   138 			}
   147 		if (ELineBreakClasses <= second && second < ELineBreakClasses + 10)
   139 		if (ELineBreakClasses <= second && second < ELineBreakClasses + 10)
   148 			{
   140 			{
   149 			++customCount;
   141 			++customCount;
   150 			TInt c = FindNextCustomClass();
   142 			TInt c = FindNextCustomClass();
   151 			TESTPOINT(second - ELineBreakClasses + '0' == c);
   143 			test(second - ELineBreakClasses + '0' == c);
   152 			}
   144 			}
   153 		if (0 == customCount)
   145 		if (0 == customCount)
   154 			return MTmSource::LineBreakPossible(aPrevClass, aNextClass, aHaveSpaces);
   146 			return MTmSource::LineBreakPossible(aPrevClass, aNextClass, aHaveSpaces);
   155 		// Between custom and non-custom classes, allow a break only with spaces
   147 		// Between custom and non-custom classes, allow a break only with spaces
   156 		// or between @ and 5
   148 		// or between @ and 5
   167 
   159 
   168 	virtual TBool GetLineBreakInContext(
   160 	virtual TBool GetLineBreakInContext(
   169 		const TDesC& aText, TInt aMinBreakPos, TInt aMaxBreakPos,
   161 		const TDesC& aText, TInt aMinBreakPos, TInt aMaxBreakPos,
   170 		TBool aForwards,TInt& aBreakPos) const
   162 		TBool aForwards,TInt& aBreakPos) const
   171 		{
   163 		{
   172 	    TESTPOINT (iDirection == (aForwards? 1 : -1));
   164 		test (iDirection == (aForwards? 1 : -1));
   173 		// The allowable break-points should not include the first
   165 		// The allowable break-points should not include the first
   174 		// and last characters of the run.
   166 		// and last characters of the run.
   175 	    TESTPOINT (aMinBreakPos != 0);
   167 		test (aMinBreakPos != 0);
   176 		for (TInt i = aMinBreakPos - 1; i <= aMaxBreakPos; ++i)
   168 		for (TInt i = aMinBreakPos - 1; i <= aMaxBreakPos; ++i)
   177 		    TESTPOINT('@' == aText[i]);
   169 			test('@' == aText[i]);
   178 		++iSaRequestCount;
   170 		++iSaRequestCount;
   179 		aBreakPos = iText->Ptr() + iSaBreakpoint - aText.Ptr();
   171 		aBreakPos = iText->Ptr() + iSaBreakpoint - aText.Ptr();
   180 		return aMinBreakPos <= aBreakPos && aBreakPos <= aMaxBreakPos;
   172 		return aMinBreakPos <= aBreakPos && aBreakPos <= aMaxBreakPos;
   181 		}
   173 		}
   182 
   174 
   183 	virtual TBool IsHangingCharacter(TUint aChar) const
   175 	virtual TBool IsHangingCharacter(TUint aChar) const
   184 		{
   176 		{
   185 		++iHangingCharRequestCount;
   177 		++iHangingCharRequestCount;
   186 		TESTPOINT(aChar == (*iText)[iMaxBreakPos]);
   178 		test(aChar == (*iText)[iMaxBreakPos]);
   187 		if (!iHangingChar)
   179 		if (!iHangingChar)
   188 			return EFalse;
   180 			return EFalse;
   189 		if (iDirection < 0)
   181 		if (iDirection < 0)
   190 			++iCurrentPos;
   182 			++iCurrentPos;
   191 		return ETrue;
   183 		return ETrue;
   206 		TBool r = MTmSource::GetLineBreakL(aText, aDocPos,
   198 		TBool r = MTmSource::GetLineBreakL(aText, aDocPos,
   207 			aMinBreakPos, aMaxBreakPos, aForwards,
   199 			aMinBreakPos, aMaxBreakPos, aForwards,
   208 			aBreakPos, aHangingChars, aBreakPosAfterSpaces);
   200 			aBreakPos, aHangingChars, aBreakPosAfterSpaces);
   209 		if (r)
   201 		if (r)
   210 			{
   202 			{
   211             TESTPOINT(aMinBreakPos <= aBreakPos);
   203 			test(aMinBreakPos <= aBreakPos);
   212             TESTPOINT(0 < aBreakPos);
   204 			test(0 < aBreakPos);
   213             TESTPOINT(aBreakPos <= aHangingChars);
   205 			test(aBreakPos <= aHangingChars);
   214             TESTPOINT(aHangingChars <= aBreakPosAfterSpaces);
   206 			test(aHangingChars <= aBreakPosAfterSpaces);
   215             TESTPOINT(aBreakPos <= aMaxBreakPos);
   207 			test(aBreakPos <= aMaxBreakPos);
   216             TESTPOINT(aHangingChars == aBreakPos || iHangingChar);
   208 			test(aHangingChars == aBreakPos || iHangingChar);
   217 			// If the direction was backwards, the algorithm should have
   209 			// If the direction was backwards, the algorithm should have
   218 			// checked if a hanging character was allowed.
   210 			// checked if a hanging character was allowed.
   219 			// This condition could be relaxed to allow it not to be checked
   211 			// This condition could be relaxed to allow it not to be checked
   220 			// if there is no break allowed between the possible hanging
   212 			// if there is no break allowed between the possible hanging
   221 			// character and the previous character.
   213 			// character and the previous character.
   222             TESTPOINT(!aForwards || aText.Length() == aMaxBreakPos
   214 			test(!aForwards || aText.Length() == aMaxBreakPos
   223 				|| 0 < iHangingCharRequestCount);
   215 				|| 0 < iHangingCharRequestCount);
   224 			// If the maximum break point was chosen or exceeded, the algorithm
   216 			// If the maximum break point was chosen or exceeded, the algorithm
   225 			// should have checked to find out whether a hanging character is
   217 			// should have checked to find out whether a hanging character is
   226 			// allowed.
   218 			// allowed.
   227             TESTPOINT(aHangingChars < aMaxBreakPos
   219 			test(aHangingChars < aMaxBreakPos
   228 				|| 0 < iHangingCharRequestCount);
   220 				|| 0 < iHangingCharRequestCount);
   229 			// Check that only spaces exist between aHangingChars and
   221 			// Check that only spaces exist between aHangingChars and
   230 			// aMaxBreakPos
   222 			// aMaxBreakPos
   231 			for (TInt i = aHangingChars; i != aBreakPosAfterSpaces; ++i)
   223 			for (TInt i = aHangingChars; i != aBreakPosAfterSpaces; ++i)
   232 				{
   224 				{
   233 				TUint n;
   225 				TUint n;
   234 				TESTPOINT(ESpLineBreakClass == LineBreakClass(aText[i], n, n));
   226 				test(ESpLineBreakClass == LineBreakClass(aText[i], n, n));
   235 				}
   227 				}
   236 			// Check that all the spaces were counted
   228 			// Check that all the spaces were counted
   237 			TESTPOINT(aBreakPosAfterSpaces == aText.Length()
   229 			test(aBreakPosAfterSpaces == aText.Length()
   238 				|| aText[aBreakPosAfterSpaces] != ' ');
   230 				|| aText[aBreakPosAfterSpaces] != ' ');
   239 			}
   231 			}
   240 		// Find out how many runs of two or more Sa there are, and check that
   232 		// 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.
   233 		// this matches the number of times that it was requested.
   242 		TInt minChecked = aMinBreakPos - 1;
   234 		TInt minChecked = aMinBreakPos - 1;
   252 			minChecked = 0;
   244 			minChecked = 0;
   253 		if (aText.Length() < maxChecked)
   245 		if (aText.Length() < maxChecked)
   254 			maxChecked = aText.Length();
   246 			maxChecked = aText.Length();
   255 		TInt runs = 0;
   247 		TInt runs = 0;
   256 		TInt sasSoFar = 0;
   248 		TInt sasSoFar = 0;
   257 		TESTPOINT (maxChecked - minChecked < 2
   249 		test (maxChecked - minChecked < 2
   258 			|| aText[minChecked] != '@'
   250 			|| aText[minChecked] != '@'
   259 			|| aText[minChecked + 1] != '@'
   251 			|| aText[minChecked + 1] != '@'
   260 			|| !aForwards
   252 			|| !aForwards
   261 			|| aHangingChars == iSaBreakpoint);
   253 			|| aHangingChars == iSaBreakpoint);
   262 		for (; minChecked != maxChecked; ++minChecked)
   254 		for (; minChecked != maxChecked; ++minChecked)
   270 				sasSoFar = 0;
   262 				sasSoFar = 0;
   271 				}
   263 				}
   272 			}
   264 			}
   273 		if (1 < sasSoFar)
   265 		if (1 < sasSoFar)
   274 			++runs;
   266 			++runs;
   275 		TESTPOINT(sasSoFar < 2 || aForwards || aHangingChars == iSaBreakpoint);
   267 		test(sasSoFar < 2 || aForwards || aHangingChars == iSaBreakpoint);
   276 		TESTPOINT(runs == iSaRequestCount);
   268 		test(runs == iSaRequestCount);
   277 		return r;
   269 		return r;
   278 		}
   270 		}
   279 
   271 
   280 	TInt FindNextCustomClass() const
   272 	TInt FindNextCustomClass() const
   281 		{
   273 		{
   338 	b2 = KMaxTInt;
   330 	b2 = KMaxTInt;
   339 	return t.GetLineBreakL(aText, 0, aMin, aMax, aForwards, b0, b1, b2)?
   331 	return t.GetLineBreakL(aText, 0, aMin, aMax, aForwards, b0, b1, b2)?
   340 		b1 : -1;
   332 		b1 : -1;
   341 	}
   333 	}
   342 
   334 
   343 CTTmSourceStep::CTTmSourceStep()
   335 void RunTests()
   344     {
   336 	{
   345     
   337 	test.Title();
   346     }
   338 	test.Start(_L(" @SYMTestCaseID:SYSLIB-FORM-LEGACY-TTMSOURCE-0001 Line-Break Tests: "));
   347 
   339 
   348 
   340 	test(-1 == TestLineBreak(_L(""), 0, 0, 0, 0, 0));
   349 TVerdict CTTmSourceStep::doTestStepL()
   341 	test(-1 == TestLineBreak(_L("5"), 0, 0, 0, 0, 0));
   350 	{
   342 	test(-1 == TestLineBreak(_L("5"), 0, 0, 0, 0, 1));
   351     SetTestStepResult(EPass);
   343 	test(-1 == TestLineBreak(_L("@"), 1, 0, 0, 0, 0));
   352     TestStep = this;
   344 	test(1 == TestLineBreak(_L("a   b"), 0, 0, 0, 0, 0));
   353     TESTPRINT(_L("TTmSource - MTmSource tests"));
   345 	test(-1 == TestLineBreak(_L("0 0 0 9    9"), 0, 0, 0, 0, 0));
   354 	TESTPRINT(_L(" @SYMTestCaseID:SYSLIB-FORM-LEGACY-TTMSOURCE-0001 Line-Break Tests: "));
   346 	test(-1 == TestLineBreak(_L("0 0 0 9    9"), 0, 0, 0, 0, 1));
   355 
   347 	test(9 == TestLineBreak(_L("4242454445"), 0, 0, 0, 0, 0));
   356 	TEST(-1 == TestLineBreak(_L(""), 0, 0, 0, 0, 0));
   348 	test(5 == TestLineBreak(_L("4242454445"), 0, 0, 0, 0, 1));
   357 	TEST(-1 == TestLineBreak(_L("5"), 0, 0, 0, 0, 0));
   349 	test(5 == TestLineBreak(_L("hello there"), 0, 0, 0, 0, 0));
   358 	TEST(-1 == TestLineBreak(_L("5"), 0, 0, 0, 0, 1));
   350 	test(5 == TestLineBreak(_L("hello there"), 0, 0, 0, 0, 1));
   359 	TEST(-1 == TestLineBreak(_L("@"), 1, 0, 0, 0, 0));
   351 	test(-1 == TestLineBreak(_L("hel  the re"), 0, 0, 5, 7, 0));
   360 	TEST(1 == TestLineBreak(_L("a   b"), 0, 0, 0, 0, 0));
   352 	test(-1 == TestLineBreak(_L("hel  the re"), 0, 0, 5, 7, 1));
   361 	TEST(-1 == TestLineBreak(_L("0 0 0 9    9"), 0, 0, 0, 0, 0));
   353 	test(8 == TestLineBreak(_L("hel  the re"), 0, 1, 5, 7, 0));
   362 	TEST(-1 == TestLineBreak(_L("0 0 0 9    9"), 0, 0, 0, 0, 1));
   354 	test(8 == TestLineBreak(_L("hel  the re"), 0, 1, 6, 7, 1));
   363 	TEST(9 == TestLineBreak(_L("4242454445"), 0, 0, 0, 0, 0));
   355 	test(3 == TestLineBreak(_L("@@@@@"), 3, 0, 0, 0, 0));
   364 	TEST(5 == TestLineBreak(_L("4242454445"), 0, 0, 0, 0, 1));
   356 	test(3 == TestLineBreak(_L("@@@@@"), 3, 0, 0, 0, 1));
   365 	TEST(5 == TestLineBreak(_L("hello there"), 0, 0, 0, 0, 0));
   357 	test(5 == TestLineBreak(_L("9999@@@@@00099@@@@gfra"), 5, 0, 5, 0, 0));
   366 	TEST(5 == TestLineBreak(_L("hello there"), 0, 0, 0, 0, 1));
   358 	test(5 == TestLineBreak(_L("9999@@@@@00099@@@@gfra"), 5, 0, 5, 0, 1));
   367 	TEST(-1 == TestLineBreak(_L("hel  the re"), 0, 0, 5, 7, 0));
   359 	test(16 == TestLineBreak(_L("9999@@@@@00099@@@@gfra"), 16, 0, 0, 0, 0));
   368 	TEST(-1 == TestLineBreak(_L("hel  the re"), 0, 0, 5, 7, 1));
   360 	test(16 == TestLineBreak(_L("9999@@@@@00099@@@@gfra"), 16, 0, 0, 0, 1));
   369 	TEST(8 == TestLineBreak(_L("hel  the re"), 0, 1, 5, 7, 0));
   361 	test(5 == TestLineBreak(_L("55@@@55"), 0, 0, 0, 0, 0));
   370 	TEST(8 == TestLineBreak(_L("hel  the re"), 0, 1, 6, 7, 1));
   362 	test(2 == TestLineBreak(_L("55@@@55"), 0, 0, 0, 0, 1));
   371 	TEST(3 == TestLineBreak(_L("@@@@@"), 3, 0, 0, 0, 0));
   363 	test(3 == TestLineBreak(_L("55@55"), 0, 0, 0, 0, 0));
   372 	TEST(3 == TestLineBreak(_L("@@@@@"), 3, 0, 0, 0, 1));
   364 	test(2 == TestLineBreak(_L("55@55"), 0, 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));
       
   381 
   365 
   382 	// Test for DEF046468, which was caused by the TLineBreakIterator constructor accessing past the end of a string
   366 	// Test for DEF046468, which was caused by the TLineBreakIterator constructor accessing past the end of a string
   383 	TESTPRINT(_L("Line-Break DEF046468 Test:"));
   367 	test.Next(_L("Line-Break DEF046468 Test:"));
   384 	// Create a string of 16 chars with a picture code at the 17th position
   368 	// Create a string of 16 chars with a picture code at the 17th position
   385 	_LIT(KLarsString, "dolor sit amet, \xFFFC");
   369 	_LIT(KLarsString, "dolor sit amet, \xFFFC");
   386 	// Create a TPtrC for the 16 character string ( with the picture code after the string in memory )
   370 	// Create a TPtrC for the 16 character string ( with the picture code after the string in memory )
   387 	TBufC<20> KTestBuffer(KLarsString);
   371 	TBufC<20> KTestBuffer(KLarsString);
   388 	TPtrC KTestString( reinterpret_cast<const TUint16*>(KTestBuffer.Ptr()), 16);
   372 	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
   373 	// 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));
   374 	test(9 == TestLineBreak(KTestString,0,0,1,15,0));
   391 	
   375 
   392 	return TestStepResult();
   376 	test.End();
       
   377 	test.Close();
       
   378 
   393 	}
   379 	}
       
   380 
       
   381 TInt E32Main()
       
   382 	{
       
   383 	TrapCleanup = CTrapCleanup::New();
       
   384 	TRAPD(err, RunTests());
       
   385     test(err == KErrNone);
       
   386 	delete TrapCleanup;
       
   387 	return 0;
       
   388 	}