os/textandloc/textrendering/textformatting/test/src/TInlineText.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /*
     2 * Copyright (c) 2004-2010 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     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".
     8 *
     9 * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    11 *
    12 * Contributors:
    13 *
    14 * Description: 
    15 *
    16 */
    17 
    18 //#include "TCustomWrap.h"
    19 #include "TGraphicsContext.h"
    20 #include <e32std.h>
    21 #include <e32test.h>
    22 #include <frmtlay.h>
    23 #include <frmtview.h>
    24 #include <txtlaydc.h>
    25 #include <fbs.h>
    26 #include <w32std.h>
    27 #include <inlinetext.h>
    28 #include "tinlinetext.h"
    29 
    30 namespace LocalToTInlineText
    31 {
    32 
    33 _LIT(KTInlineText, "TInlineText");
    34 const TInt KDisplayWidthWide = 202;
    35 const TInt KDisplayWidthThin = 102;
    36 const TInt KDisplayHeight = 100;
    37 const TInt KPictureCharacter = 0xFFFC;
    38 
    39 CTInLineTextStep* TestStep = NULL;
    40 #define TESTPOINT(p) TestStep->testpoint(p,(TText8*)__FILE__,__LINE__)
    41 #define TESTPRINT(p) TestStep->print(p,(TText8*)__FILE__,__LINE__)
    42 
    43 
    44 enum TInlineTextPanic { EAccessOutsideText = 1 };
    45 void Panic(TInlineTextPanic)
    46     {
    47     User::Panic(_L("TInlineText"), EAccessOutsideText);
    48     }
    49 
    50 class CPinkSquare : public CPicture
    51 	{
    52 public:
    53 	// Size of square in twips.
    54 	// 600 is 15 pixels using the standard test graphics device at
    55 	// its default resolution.
    56 	enum { KWidth = 600, KHeight = 600 };
    57 	CPinkSquare()
    58 		{}
    59 	void Draw(CGraphicsContext& aGc, const TPoint& aTopLeft, const TRect& aClipRect, MGraphicsDeviceMap* aMap) const
    60 		{
    61 		// This picture is a magenta square
    62 		TPoint size(KWidth, KHeight);
    63 		if (aMap)
    64 			size = aMap->TwipsToPixels(size);
    65 		TRect rect(aTopLeft, aTopLeft + size);
    66 		aGc.SetClippingRect(aClipRect);
    67 		aGc.SetDrawMode(CGraphicsContext::EDrawModePEN);
    68 		aGc.SetPenColor(KRgbMagenta);
    69 		aGc.SetBrushStyle(CGraphicsContext::ESolidBrush);
    70 		aGc.SetBrushColor(KRgbMagenta);
    71 		aGc.DrawRect(rect);
    72 		}
    73 	void ExternalizeL(RWriteStream&) const
    74 		{}
    75 	void GetOriginalSizeInTwips(TSize& a) const
    76 		{
    77 		a.iWidth = CPinkSquare::KWidth;
    78 		a.iHeight = CPinkSquare::KHeight;
    79 		}
    80 	};
    81 
    82 _LIT(KEnd, "\x2029");
    83 class TDocModel : public MLayDoc
    84 	{
    85 public:
    86 	TDocModel(const TDesC& aDes)
    87 	 :	iDes(&aDes), iParagraphFormat(0)
    88 		{}
    89 	void SetParagraphFormat(CParaFormat* a)
    90 		{
    91 		iParagraphFormat = a;
    92 		}
    93 	// From MLayDoc
    94 	TInt LdDocumentLength() const
    95 		{ return iDes->Length(); }
    96 	TInt LdToParagraphStart(TInt& a) const
    97 		{
    98 		TInt curr = a;
    99 		if (a < LdDocumentLength())
   100 			{
   101 			a = iDes->Left(a).LocateReverse(0x2029);
   102 			a = a < 0? 0 : a + 1;
   103 			}
   104 		return curr - a;
   105 		}
   106 	void GetParagraphFormatL(CParaFormat* aFormat, TInt) const
   107 		{
   108 		if (iParagraphFormat)
   109 			{
   110 			aFormat->CopyL(*iParagraphFormat);
   111 			return;
   112 			}
   113 		aFormat->Reset();
   114 		TTabStop tabStop;
   115 		tabStop.iTwipsPosition = 1000;
   116 		tabStop.iType = TTabStop::ELeftTab;
   117 		aFormat->StoreTabL(tabStop);
   118 		}
   119 	void GetChars(TPtrC& aView,TCharFormat& aFormat, TInt aStartPos)const
   120 		{
   121         __ASSERT_ALWAYS(aStartPos <= LdDocumentLength(), Panic(EAccessOutsideText));
   122         __ASSERT_ALWAYS(aStartPos >= 0, Panic(EAccessOutsideText));
   123         
   124 		TCharFormat cf;
   125 		aFormat = cf;
   126 		if (aStartPos == LdDocumentLength())
   127 			aView.Set(KEnd);
   128 		else
   129 			aView.Set(iDes->Mid(aStartPos));
   130 		}
   131 	TInt GetPictureSizeInTwips(TSize& aSize, TInt aPos) const
   132 		{
   133 		if ((*iDes)[aPos] != KPictureCharacter)
   134 			return KErrNotFound;
   135 		aSize.iWidth = CPinkSquare::KWidth;
   136 		aSize.iHeight = CPinkSquare::KHeight;
   137 		return KErrNone;
   138 		}
   139 	CPicture* PictureHandleL(TInt aPos, TForcePictureLoad) const
   140 		{
   141 		if ((*iDes)[aPos] != KPictureCharacter)
   142 			return 0;
   143 		return new(ELeave) CPinkSquare;
   144 		}
   145 	TBool EnquirePageBreak(TInt aPos, TInt aLength)const
   146 		{
   147 		return iDes->Mid(aPos, aLength).Locate(0x000C) < 0?
   148 			EFalse : ETrue;
   149 		}
   150 	TBool SelectParagraphLabel(TInt)
   151 		{ return EFalse; }
   152 	void CancelSelectLabel()
   153 		{}
   154 private:
   155 	const TDesC* iDes;
   156 	CParaFormat* iParagraphFormat;
   157 	};
   158 }
   159 using namespace LocalToTInlineText;
   160 
   161 class CTestTextView	// slightly naughty
   162 	{
   163 public:
   164 	static void SetContextForFlickerFreeRedraw(CTextView* aView, CBitmapContext* aContext)
   165 		{
   166 		aView->iOffScreenContext = aContext;
   167 		}
   168 	};
   169 
   170 // Utility functions to show contents of test data using test.Printf
   171 
   172 _LIT(KAddressMarker, "> ");
   173 _LIT(KSpace, " ");
   174 _LIT(KLength, ", Length of Data = %d 16-bit words\r\n");
   175 _LIT(KSpaces, "                                                                      ");
   176 _LIT(KPeriod, ".");
   177 _LIT(KSingleString, "%S\r\n");
   178 //_LIT(KDoubleString, "%s <%s>\r\n");
   179 //_LIT(KLinefeed, "\r\n");
   180 
   181 void PrintTestData (const TDesC& aTitle , const TDesC16& aData)
   182 	{
   183 
   184 	TInt i;
   185 	TInt j;
   186 	TInt end;
   187 
   188 	TInt length = aData.Length();
   189 
   190 	TBuf<80> buffer;
   191 
   192 	buffer.Zero();
   193 	buffer.Append(aTitle);
   194 	buffer.Append(KLength);
   195 
   196 	TBuf<256> buf;
   197 	buf.AppendFormat(buffer, length);
   198 	TESTPRINT(buf);
   199 
   200 	for (i = 0 ; i < length ; i += 8)
   201 		{
   202 		buffer.Zero();
   203 		buffer.AppendNumFixedWidth(i, EHex, 8);
   204 		buffer += KAddressMarker;
   205 
   206 		end = ((length-i) >= 8) ? i+8 : length;
   207 
   208 		for (j = i ; j < end ; ++j)
   209 			{
   210 			buffer.AppendNumFixedWidth(aData[j], EHex, 4);
   211 			buffer += KSpace;
   212 			}
   213 		buffer += TPtrC(KSpaces().Ptr(), ((8-(j-i))*5)+4);
   214 
   215 		for (j = i ; j < end ; ++j)
   216 			{
   217 			if (aData[j] >= 32)
   218 				{
   219 				buffer.Append(aData[j]);
   220 				}
   221 			else
   222 				{
   223 				buffer += KPeriod;
   224 				}
   225 			}
   226 		buffer.ZeroTerminate();
   227 		buf.Zero();
   228 		buf.AppendFormat(KSingleString,buffer.Ptr());
   229 		TESTPRINT(buf);		
   230 		}
   231 
   232 	}
   233 
   234 void PrintTestData(const TDesC& aTitle, const TText16* aDataBuffer, const TInt aSize)
   235 	{
   236 	PrintTestData(aTitle, TPtrC16(aDataBuffer, aSize));
   237 	}
   238 
   239 class CTestInlineTextSource : public CBase, public MTmInlineTextSource
   240 	{
   241 public:
   242 	static CTestInlineTextSource* NewL(TPtrC aText, TInt aNumChar);
   243 	~CTestInlineTextSource();
   244 
   245 public: // From MTmInlineTextSource
   246 
   247 	/**
   248 	Reports the next position into which inline text should be inserted
   249 	@param aFrom
   250 		The document position and character edge to start from.
   251 	@param aMaxLength
   252 		The maximum length within which to report inline text.
   253 		It means that inline text at position X should be reported if
   254 		aFrom <= X && X < aFrom + aMaxLength.
   255 		Also report trailing inline text at position aFrom + aMaxLength
   256 		because it is really attached to the preceding character.
   257 		Always report only the first inline text position >= aFrom.
   258 	@param aNext
   259 		On exit the position of the next bit of inline text to be inserted.
   260 		N.B. The position of trailing text following position N and the
   261 		position of leading text preceding position N+1 are both
   262 		considered to be N+1 - and the trailing text comes first so if
   263 		aFrom specifies a leading edge do not report trailing edge
   264 		inline text unless its position is greater than aFrom.
   265 		A panic EBadReturnValue will result otherwise.
   266 	@return
   267 		KErrNone if a position is found within the specified range,
   268 		KErrNotFound otherwise.
   269 	@post
   270 		if KErrNone returned then aFrom <= aNext
   271 		&& GetInlineText(aNext).Length() != 0
   272 		&& (GetInlineText(X).Length() == 0 for all
   273 		TTmDocPos X such that aFrom < X && X < aNext)
   274 		else if KErrNotFound returned
   275 		GetInlineText(X).Length() == 0 for all
   276 		TTmDocPos X such that aFrom <= X && X < aFrom + aMaxLength
   277 	*/
   278 	virtual TInt GetNextInlineTextPosition(const TTmDocPos& aFrom, TInt aMaxLength, TTmDocPos& aNext);
   279 
   280 	/**
   281 	Gets a view of the text to be inserted at aAt.
   282 	@param aAt
   283 		Document position, including character edge, being queried.
   284 	@return
   285 		Any inline text that should be attached to the specified character edge at aAt.
   286 	*/
   287 	virtual TPtrC GetInlineText(const TTmDocPos& aAt);
   288 
   289 private:
   290 	CTestInlineTextSource();
   291 	void Construct(TPtrC aText, TInt aNumChar);
   292 	TPtrC iNullText;
   293 	TPtrC iText;
   294 	TInt iNumChar;
   295 	};
   296 
   297 CTestInlineTextSource::CTestInlineTextSource()
   298 	{
   299 	}
   300 
   301 CTestInlineTextSource* CTestInlineTextSource::NewL(TPtrC aText, TInt aNumChar)
   302 	{
   303 	CTestInlineTextSource* self= new(ELeave) CTestInlineTextSource();
   304 	self->Construct(aText, aNumChar);
   305 	return self;
   306 	}
   307 
   308 CTestInlineTextSource::~CTestInlineTextSource()
   309 	{
   310 	}
   311 
   312 void CTestInlineTextSource::Construct(TPtrC aText, TInt aNumChar)
   313 	{
   314 	iText.Set(aText);
   315 	iNumChar = aNumChar;
   316 	}
   317 
   318 // This takes two inputs, each of which is either a real position,
   319 // greater than or equal to 0, or KErrNotFound. If both are real
   320 // positions then it should return the lower. If one is a real position
   321 // then it should be returned. If neither are a real position then
   322 // KErrNone is returned. It is all done with pointers to TInts so that
   323 // when I get the result I can tell which one it is.
   324 TInt* CustomMin(TInt* aPtrPos1, TInt* aPtrPos2)
   325 	{
   326 	if (*aPtrPos2 == KErrNotFound)
   327 		return aPtrPos1;
   328 	if (*aPtrPos1 == KErrNotFound)
   329 		return aPtrPos2;
   330 	if (*aPtrPos1 <= *aPtrPos2)
   331 		return aPtrPos1;
   332 	else
   333 		return aPtrPos2;
   334 	}
   335 
   336 TInt CTestInlineTextSource::GetNextInlineTextPosition(const TTmDocPos& aFrom, TInt aMaxLength, TTmDocPos& aNext)
   337 	{
   338 	if (iNumChar == 0)
   339 		return KErrNotFound;
   340 	_LIT(KSS1, "A");
   341 	_LIT(KSS2, "B");
   342     _LIT(KSS3, "C");
   343     _LIT(KSS4, "\x05c0");//Hebrew character to test right-to-left text
   344 	TInt from = aFrom.iPos;
   345 	TInt from2 = from;
   346 	if ((from > 0) && (!aFrom.iLeadingEdge))
   347 		from2--; // adjustment takes care of not returning trailing edge if at start pos
   348 	TInt pos1 = iText.Mid(from).Find(KSS1);
   349 	TInt pos2 = iText.Mid(from2).Find(KSS2);
   350 	TInt pos3 = iText.Mid(from).Find(KSS3);
   351     TInt pos4 = iText.Mid(from2).Find(KSS3);
   352     TInt pos5 = iText.Mid(from2).Find(KSS4);
   353 	if (pos1 >= 0 ) // adjustments so we compare like for like
   354 		pos1 += from - from2;
   355 	if (pos3 >= 0 )
   356 		pos3 += from - from2;
   357 	// get the smallest real position, if any
   358 	TInt* ptrPos = CustomMin(CustomMin(&pos1, &pos3), CustomMin(CustomMin(&pos2, &pos4),&pos5));
   359 	if (pos1 > 0 ) // now adjust back
   360 		pos1 -= from - from2;
   361 	if (pos3 > 0 )
   362 		pos3 -= from - from2;
   363 	if (*ptrPos == KErrNotFound)
   364 		return KErrNotFound;
   365 	if ((ptrPos == &pos1) || (ptrPos == &pos3))
   366 		{ // it was an A or C with leading text
   367 		aNext.iPos = *ptrPos + from;
   368 		aNext.iLeadingEdge = ETrue;
   369 		}
   370 	else if ((ptrPos == &pos2) || (ptrPos == &pos4))
   371 		{ // it was an B oD with trailing text
   372 		aNext.iPos = *ptrPos + from2 + 1;
   373 		aNext.iLeadingEdge = EFalse;
   374 		}
   375     else if (ptrPos == &pos5)
   376         { // it was an Hebrew char with trailing text
   377         aNext.iPos = *ptrPos + from2 + 1;
   378         aNext.iLeadingEdge = EFalse;
   379         }
   380 	else
   381 		{
   382 		// something has gone horribly wrong
   383 		return KErrNotFound;
   384 		}
   385 	if (aNext.iPos - aFrom.iPos > aMaxLength + (aNext.iLeadingEdge ? 0 : 1))
   386 		return KErrNotFound;
   387 	return KErrNone;
   388 	}
   389 
   390 TPtrC CTestInlineTextSource::GetInlineText(const TTmDocPos& aAt)
   391 	{
   392 	if (iNumChar == 0)
   393 		return iNullText;
   394 	if ((aAt.iPos == 0) && (!aAt.iLeadingEdge))
   395 		return iNullText;
   396 	_LIT(KSS1, "A");
   397 	_LIT(KSS2, "B");
   398 	_LIT(KSS3, "C");
   399     _LIT(KSS4, "\x05c0");//Hebrew character to test right-to-left text
   400 	TInt at = aAt.iPos;
   401 	TInt at2 = at;
   402 	if ((at2 > 0) && (!aAt.iLeadingEdge))
   403 		at2--; // adjustment takes care of not returning trailing edge if at start pos
   404 
   405 	TInt pos1 = iText.Mid(at).Find(KSS1);
   406 	TInt pos2 = iText.Mid(at2).Find(KSS2);
   407 	TInt pos3 = iText.Mid(at).Find(KSS3);
   408 	TInt pos4 = iText.Mid(at2).Find(KSS3);
   409     TInt pos5 = iText.Mid(at2).Find(KSS4);
   410 	if (pos1 == 0)
   411 		{
   412 		pos1 += at;
   413 		if ((pos1 == aAt.iPos) && aAt.iLeadingEdge)
   414 			{
   415 			TPtrC tPtrC;
   416 			if (iNumChar == 1)
   417 				{
   418 				_LIT(KIS11, "a");
   419 				tPtrC.Set(KIS11);
   420 				}
   421 			else if (iNumChar == 2)
   422 				{
   423 				_LIT(KIS12, "aa");
   424 				tPtrC.Set(KIS12);
   425 				}
   426 			return tPtrC;
   427 			}
   428 		}
   429 	if (pos2 == 0)
   430 		{
   431 		pos2 += at2;
   432 		if ((pos2 + 1 == aAt.iPos) && !aAt.iLeadingEdge)
   433 			{
   434 			TPtrC tPtrC;
   435 			if (iNumChar == 1)
   436 				{
   437 				_LIT(KIS21, "b");
   438 				tPtrC.Set(KIS21);
   439 				}
   440 			else if (iNumChar == 2)
   441 				{
   442 				_LIT(KIS22, "bb");
   443 				tPtrC.Set(KIS22);
   444 				}
   445 			return tPtrC;
   446 			}
   447 		}
   448 	if ((pos3 == 0) || (pos4 == 0))
   449 		{
   450 		if (((pos3 + at == aAt.iPos) && aAt.iLeadingEdge) || ((pos4 + at2 + 1 == aAt.iPos) && !aAt.iLeadingEdge))
   451 			{
   452 			TPtrC tPtrC;
   453 			if (iNumChar == 1)
   454 				{
   455 				_LIT(KIS31, "c");
   456 				tPtrC.Set(KIS31);
   457 				}
   458 			else if (iNumChar == 2)
   459 				{
   460 				_LIT(KIS32, "cc");
   461 				tPtrC.Set(KIS32);
   462 				}
   463 			return tPtrC;
   464 			}
   465 		}
   466     if (pos5 == 0)
   467         {
   468         pos5 += at2;
   469         if ((pos5 + 1 == aAt.iPos) && !aAt.iLeadingEdge)
   470             {
   471             TPtrC tPtrC;
   472             if (iNumChar == 1)
   473                 {
   474                 _LIT(KIS41, "\05be");
   475                 tPtrC.Set(KIS41);
   476                 }
   477             else if (iNumChar == 2)
   478                 {
   479                 _LIT(KIS42, "\05be\05be");
   480                 tPtrC.Set(KIS42);
   481                 }
   482             return tPtrC;
   483             }
   484         }
   485 	return iNullText;
   486 	}
   487 
   488 class CTestFormExtendedInterfaceProvider: public CBase, public MFormCustomInterfaceProvider
   489 	{
   490 public:
   491 	static CTestFormExtendedInterfaceProvider* NewL(TPtrC aText, TInt aNumChar);
   492 	~CTestFormExtendedInterfaceProvider();
   493 	TAny* GetExtendedInterface(const TUid& aInterfaceId);
   494 
   495 private:
   496 	CTestFormExtendedInterfaceProvider();
   497 	void ConstructL(TPtrC aText, TInt aNumChar);
   498 
   499 private:
   500 	CTestInlineTextSource* iTestInlineTextSource; // Owned
   501 	};
   502 
   503 
   504 CTestFormExtendedInterfaceProvider::CTestFormExtendedInterfaceProvider()
   505 	{
   506 	}
   507 
   508 CTestFormExtendedInterfaceProvider* CTestFormExtendedInterfaceProvider::NewL(TPtrC aText, TInt aNumChar)
   509 	{
   510 	CTestFormExtendedInterfaceProvider* self= new(ELeave) CTestFormExtendedInterfaceProvider();
   511 	CleanupStack::PushL(self);
   512 	self->ConstructL(aText, aNumChar);
   513 	CleanupStack::Pop(); // self
   514 	return self;
   515 	}
   516 
   517 CTestFormExtendedInterfaceProvider::~CTestFormExtendedInterfaceProvider()
   518 	{
   519 	delete iTestInlineTextSource;
   520 	}
   521 
   522 void CTestFormExtendedInterfaceProvider::ConstructL(TPtrC aText, TInt aNumChar)
   523 	{
   524 	iTestInlineTextSource = CTestInlineTextSource::NewL(aText, aNumChar);
   525 	}
   526 
   527 TAny* CTestFormExtendedInterfaceProvider::GetExtendedInterface( const TUid& aInterfaceId )
   528 	{
   529 	if (aInterfaceId == KInlineTextApiExtensionUid)
   530 		{
   531 		return static_cast<MTmInlineTextSource*>(iTestInlineTextSource);
   532 		}
   533 	else
   534 		{
   535 		return NULL;
   536 		}
   537 	}
   538 
   539 // When referring to test cases the following shorthand is used:
   540 // P  Primary text that has inline text (leading and/or trailing) attached
   541 //    to it
   542 // L  Leading inline text attached to primary text
   543 // T  Trailing inline text attached to primary text
   544 // X  Secondary text that precedes primary text
   545 // Y  Secondary text that follows primary text
   546 // S  A special case of P where the primary text is a single character
   547 //    which has both leading and trailing inline text attached to it
   548 //
   549 // So, for example, X L-P will indicate some normal secondary text,
   550 // followed by a <space>, followed by some primary text which will get
   551 // leading text added to the start of it.
   552 //
   553 // When defining a test string the following are significant characters:
   554 // A  An 'A' will get zero or more 'a's of leading text attached to it
   555 // B  A 'B' will get zero or more 'b's of trailing text attached to it
   556 // C  A 'C' will get zero or more 'c's of both leading and trailing text
   557 //    attached to it
   558 //
   559 // All other characters are used normally.
   560 // N.B. Spaces have significance as potential line-breaking points.
   561 //
   562 // So the example X L-P could be implemented as "ij Axyz". The 'A'
   563 // indicating that leading inline text should be attatched to it.
   564 //
   565 // All test are carried out 3 times, once with inline text set to add zero
   566 // characters for each inline text (i.e. switched off), once with inline
   567 // text set to add one character for each inline text and once with inline
   568 // text set to add two characters for each inline text.
   569 //
   570 // All tests use a special test graphics device and test graphics context
   571 // to enable us to catch the output and use a special "pseudo" test font
   572 // where all characters are exactly 10 pixels wide and 10 pixels high (to
   573 // make the calculations easier).
   574 //
   575 // General combination tests
   576 //
   577 // These are simple tests, which would take a single line of input on the
   578 // display and produce a single line of output on the display (if we
   579 // weren't using a special CTestGraphicsContext to catch the output).
   580 // These tests check that, without the complications of line-breaking,
   581 // inline text is inserted where we expect it to be. This is why a display
   582 // that is capable of taking 20 chars on a line is used for these tests.
   583 //
   584 // Future extensions:
   585 // These tests could be extended to do similar tests using Right-to-Left
   586 // (RtoL) text. This would require the inline text mechanism to be
   587 // extended to also use RtoL trigger characters (and inserts). The
   588 // expected results would need to take account of the fact that the output
   589 // would be in display order rather than buffer order.
   590 //
   591 // Specific tests
   592 //
   593 // These tests check specific cases that involve line-breaking. They
   594 // produce more than one line of output, apart from some (not all) cases
   595 // when inline text is switched off. To force the line-breaking these
   596 // tests use a display that is obly capable of taking 10 chars on a line
   597 // is used. Detailed info for each test is given in comments in the test
   598 // data.
   599 //
   600 // Future extensions:
   601 // These tests could be extended to check the behaviour of truncation and
   602 // the insertion of an ellipsis. These tests could also be extended to
   603 // include some RtoL examples.
   604 
   605 static const TInt KTestCases = 18;
   606 static const TInt KInlineTextOptions = 3;
   607 static const TInt KVariants = 6;
   608 
   609 static const TPtrC KTestStrings[KTestCases][KInlineTextOptions][KVariants] =
   610 	{	// Start of General Combination tests
   611 		{	// Test L-P
   612 			{
   613 			_S("Axyz"),
   614 			_S("Axyz"),
   615 			_S(""),
   616 			_S(""),
   617 			_S(""),
   618 			_S("")
   619 			},
   620 			{
   621 			_S("Axyz"),
   622 			_S("a"),
   623 			_S("Axyz"),
   624 			_S(""),
   625 			_S(""),
   626 			_S("")
   627 			},
   628 			{
   629 			_S("Axyz"),
   630 			_S("aa"),
   631 			_S("Axyz"),
   632 			_S(""),
   633 			_S(""),
   634 			_S("")
   635 			}
   636 		},
   637 		{	// Test X L-P
   638 			{
   639 			_S("ij Axyz"),
   640 			_S("ij Axyz"),
   641 			_S(""),
   642 			_S(""),
   643 			_S(""),
   644 			_S("")
   645 			},
   646 			{
   647 			_S("ij Axyz"),
   648 			_S("ij "),
   649 			_S("a"),
   650 			_S("Axyz"),
   651 			_S(""),
   652 			_S("")
   653 			},
   654 			{
   655 			_S("ij Axyz"),
   656 			_S("ij "),
   657 			_S("aa"),
   658 			_S("Axyz"),
   659 			_S(""),
   660 			_S("")
   661 			}
   662 		},
   663 		{	// Test P-T
   664 			{
   665 			_S("xyzB"),
   666 			_S("xyzB"),
   667 			_S(""),
   668 			_S(""),
   669 			_S(""),
   670 			_S("")
   671 			},
   672 			{
   673 			_S("xyzB"),
   674 			_S("xyzB"),
   675 			_S("b"),
   676 			_S(""),
   677 			_S(""),
   678 			_S("")
   679 			},
   680 			{
   681 			_S("xyzB"),
   682 			_S("xyzB"),
   683 			_S("bb"),
   684 			_S(""),
   685 			_S(""),
   686 			_S("")
   687 			}
   688 		},
   689 		{	// Test P-T Y
   690 			{
   691 			_S("xyzB pq"),
   692 			_S("xyzB pq"),
   693 			_S(""),
   694 			_S(""),
   695 			_S(""),
   696 			_S("")
   697 			},
   698 			{
   699 			_S("xyzB pq"),
   700 			_S("xyzB"),
   701 			_S("b"),
   702 			_S(" pq"),
   703 			_S(""),
   704 			_S("")
   705 			},
   706 			{
   707 			_S("xyzB pq"),
   708 			_S("xyzB"),
   709 			_S("bb"),
   710 			_S(" pq"),
   711 			_S(""),
   712 			_S("")
   713 			}
   714 		},
   715 		{	// Test L-P-T
   716 			{
   717 			_S("AxyzB"),
   718 			_S("AxyzB"),
   719 			_S(""),
   720 			_S(""),
   721 			_S(""),
   722 			_S("")
   723 			},
   724 			{
   725 			_S("AxyzB"),
   726 			_S("a"),
   727 			_S("AxyzB"),
   728 			_S("b"),
   729 			_S(""),
   730 			_S("")
   731 			},
   732 			{
   733 			_S("AxyzB"),
   734 			_S("aa"),
   735 			_S("AxyzB"),
   736 			_S("bb"),
   737 			_S(""),
   738 			_S("")
   739 			}
   740 		},
   741 		{	// Test L-C-T
   742 			{
   743 			_S("C"),
   744 			_S("C"),
   745 			_S(""),
   746 			_S(""),
   747 			_S(""),
   748 			_S("")
   749 			},
   750 			{
   751 			_S("C"),
   752 			_S("c"),
   753 			_S("C"),
   754 			_S("c"),
   755 			_S(""),
   756 			_S("")
   757 			},
   758 			{
   759 			_S("C"),
   760 			_S("cc"),
   761 			_S("C"),
   762 			_S("cc"),
   763 			_S(""),
   764 			_S("")
   765 			}
   766 		},
   767 		{	// Test X L-P-T
   768 			{
   769 			_S("ij AxyzB"),
   770 			_S("ij AxyzB"),
   771 			_S(""),
   772 			_S(""),
   773 			_S(""),
   774 			_S("")
   775 			},
   776 			{
   777 			_S("ij AxyzB"),
   778 			_S("ij "),
   779 			_S("a"),
   780 			_S("AxyzB"),
   781 			_S("b"),
   782 			_S("")
   783 			},
   784 			{
   785 			_S("ij AxyzB"),
   786 			_S("ij "),
   787 			_S("aa"),
   788 			_S("AxyzB"),
   789 			_S("bb"),
   790 			_S("")
   791 			}
   792 		},
   793 		{	// Test X L-C-T
   794 			{
   795 			_S("ij C"),
   796 			_S("ij C"),
   797 			_S(""),
   798 			_S(""),
   799 			_S(""),
   800 			_S("")
   801 			},
   802 			{
   803 			_S("ij C"),
   804 			_S("ij "),
   805 			_S("c"),
   806 			_S("C"),
   807 			_S("c"),
   808 			_S("")
   809 			},
   810 			{
   811 			_S("ij C"),
   812 			_S("ij "),
   813 			_S("cc"),
   814 			_S("C"),
   815 			_S("cc"),
   816 			_S("")
   817 			}
   818 		},
   819 		{	// Test L-P-T Y
   820 			{
   821 			_S("AxyzB pq"),
   822 			_S("AxyzB pq"),
   823 			_S(""),
   824 			_S(""),
   825 			_S(""),
   826 			_S("")
   827 			},
   828 			{
   829 			_S("AxyzB pq"),
   830 			_S("a"),
   831 			_S("AxyzB"),
   832 			_S("b"),
   833 			_S(" pq"),
   834 			_S("")
   835 			},
   836 			{
   837 			_S("AxyzB pq"),
   838 			_S("aa"),
   839 			_S("AxyzB"),
   840 			_S("bb"),
   841 			_S(" pq"),
   842 			_S("")
   843 			}
   844 		},
   845 		{	// Test L-C-T Y
   846 			{
   847 			_S("C pq"),
   848 			_S("C pq"),
   849 			_S(""),
   850 			_S(""),
   851 			_S(""),
   852 			_S("")
   853 			},
   854 			{
   855 			_S("C pq"),
   856 			_S("c"),
   857 			_S("C"),
   858 			_S("c"),
   859 			_S(" pq"),
   860 			_S("")
   861 			},
   862 			{
   863 			_S("C pq"),
   864 			_S("cc"),
   865 			_S("C"),
   866 			_S("cc"),
   867 			_S(" pq"),
   868 			_S("")
   869 			}
   870 		},
   871 		{	// Test X L-P-T Y
   872 			{
   873 			_S("ij AxyzB pq"),
   874 			_S("ij AxyzB pq"),
   875 			_S(""),
   876 			_S(""),
   877 			_S(""),
   878 			_S("")
   879 			},
   880 			{
   881 			_S("ij AxyzB pq"),
   882 			_S("ij "),
   883 			_S("a"),
   884 			_S("AxyzB"),
   885 			_S("b"),
   886 			_S(" pq")
   887 			},
   888 			{
   889 			_S("ij AxyzB pq"),
   890 			_S("ij "),
   891 			_S("aa"),
   892 			_S("AxyzB"),
   893 			_S("bb"),
   894 			_S(" pq")
   895 			}
   896 		},
   897 		{	// Test X L-C-T Y
   898 			{
   899 			_S("ij C pq"),
   900 			_S("ij C pq"),
   901 			_S(""),
   902 			_S(""),
   903 			_S(""),
   904 			_S("")
   905 			},
   906 			{
   907 			_S("ij C pq"),
   908 			_S("ij "),
   909 			_S("c"),
   910 			_S("C"),
   911 			_S("c"),
   912 			_S(" pq")
   913 			},
   914 			{
   915 			_S("ij C pq"),
   916 			_S("ij "),
   917 			_S("cc"),
   918 			_S("C"),
   919 			_S("cc"),
   920 			_S(" pq")
   921 			}
   922 		},	// End of General Combination tests
   923 		{	// Start of Specific tests
   924 			{	// Test P-T Y
   925 				// primary text with trailing inline text, secondary text secondary
   926 				// text won't fit on line
   927 			_S("wxyzB pqrstuv"),
   928 			_S("wxyzB"),
   929 			_S(" "),
   930 			_S("pqrstuv"),
   931 			_S(""),
   932 			_S("")
   933 			},
   934 			{
   935 			_S("wxyzB pqrstuv"),
   936 			_S("wxyzB"),
   937 			_S("b"),
   938 			_S(" "),
   939 			_S("pqrstuv"),
   940 			_S("")
   941 			},
   942 			{
   943 			_S("wxyzB pqrstuv"),
   944 			_S("wxyzB"),
   945 			_S("bb"),
   946 			_S(" "),
   947 			_S("pqrstuv"),
   948 			_S("")
   949 			}
   950 		},
   951 		{	// Test X P-T one
   952 			// secondary text, primary text with trailing inline text trailing
   953 			// text won't fit and there is no line breaking point inside primary
   954 			// text and the primary text plus trailing text will fit on next line
   955 			{
   956 			_S("ijklm xyzB"),
   957 			_S("ijklm xyzB"),
   958 			_S(""),
   959 			_S(""),
   960 			_S(""),
   961 			_S("")
   962 			},
   963 			{
   964 			_S("ijklm xyzB"),
   965 			_S("ijklm"),
   966 			_S(" "),
   967 			_S("xyzB"),
   968 			_S("b"),
   969 			_S("")
   970 			},
   971 			{
   972 			_S("ijklm xyzB"),
   973 			_S("ijklm"),
   974 			_S(" "),
   975 			_S("xyzB"),
   976 			_S("bb"),
   977 			_S("")
   978 			}
   979 		},
   980 		{	// Test X P-T two
   981 			// secondary text, primary text with trailing inline text primary
   982 			// text won't fit and there is no line breaking point inside primary
   983 			// text and the primary text plus trailing text will fit on next line
   984 			{
   985 			_S("ijklm uvwxyzB"),
   986 			_S("ijklm"),
   987 			_S(" "),
   988 			_S("uvwxyzB"),
   989 			_S(""),
   990 			_S("")
   991 			},
   992 			{
   993 			_S("ijklm uvwxyzB"),
   994 			_S("ijklm"),
   995 			_S(" "),
   996 			_S("uvwxyzB"),
   997 			_S("b"),
   998 			_S("")
   999 			},
  1000 			{
  1001 			_S("ijklm uvwxyzB"),
  1002 			_S("ijklm"),
  1003 			_S(" "),
  1004 			_S("uvwxyzB"),
  1005 			_S("bb"),
  1006 			_S("")
  1007 			}
  1008 		},
  1009 		{	// Test X L-P-T one
  1010 			// secondary text, primary text with leading and trailing inline text trailing
  1011 			// text won't fit and there is no line breaking point inside primary text and
  1012 			// the leading text plus primary text plus trailing text will fit on the next line
  1013 			{
  1014 			_S("ij AwxyzB"),
  1015 			_S("ij AwxyzB"),
  1016 			_S(""),
  1017 			_S(""),
  1018 			_S(""),
  1019 			_S("")
  1020 			},
  1021 			{
  1022 			_S("ij AwxyzB"),
  1023 			_S("ij"),
  1024 			_S(" "),
  1025 			_S("a"),
  1026 			_S("AwxyzB"),
  1027 			_S("b")
  1028 			},
  1029 			{
  1030 			_S("ij AwxyzB"),
  1031 			_S("ij"),
  1032 			_S(" "),
  1033 			_S("aa"),
  1034 			_S("AwxyzB"),
  1035 			_S("bb")
  1036 			}
  1037 		},
  1038 		{	// Test X L-P-T two
  1039 			// secondary text, primary text with leading and trailing inline text primary
  1040 			// text won't fit and there is no line breaking point inside primary text and
  1041 			// the leading text plus primary text plus trailing text will fit on the next line
  1042 			{
  1043 			_S("ijkl AxyzB"),
  1044 			_S("ijkl AxyzB"),
  1045 			_S(""),
  1046 			_S(""),
  1047 			_S(""),
  1048 			_S("")
  1049 			},
  1050 			{
  1051 			_S("ijkl AxyzB"),
  1052 			_S("ijkl"),
  1053 			_S(" "),
  1054 			_S("a"),
  1055 			_S("AxyzB"),
  1056 			_S("b")
  1057 			},
  1058 			{
  1059 			_S("ijkl AxyzB"),
  1060 			_S("ijkl"),
  1061 			_S(" "),
  1062 			_S("aa"),
  1063 			_S("AxyzB"),
  1064 			_S("bb"),
  1065 			}
  1066 		},
  1067 		{	// Test X L-P-T three
  1068 			//secondary text, primary text with leading and trailing inline text leading
  1069 			// text won't fit and the leading text plus primary text plus trailing text
  1070 			// will fit on the next line
  1071 			{
  1072 			_S("ijklmnop AxyzB"),
  1073 			_S("ijklmnop"),
  1074 			_S(" "),
  1075 			_S("AxyzB"),
  1076 			_S(""),
  1077 			_S("")
  1078 			},
  1079 			{
  1080 			_S("ijklmnop AxyzB"),
  1081 			_S("ijklmnop"),
  1082 			_S(" "),
  1083 			_S("a"),
  1084 			_S("AxyzB"),
  1085 			_S("b")
  1086 			},
  1087 			{
  1088 			_S("ijklmnop AxyzB"),
  1089 			_S("ijklmnop"),
  1090 			_S(" "),
  1091 			_S("aa"),
  1092 			_S("AxyzB"),
  1093 			_S("bb")
  1094 			}
  1095 		}	// End of Specific tests
  1096 	};
  1097 
  1098 static const TInt KTestCount[KTestCases][KInlineTextOptions] =
  1099 	{
  1100 		{	// Start of General Combination tests
  1101 		1,	// Test L-P
  1102 		2,
  1103 		2
  1104 		},
  1105 		{
  1106 		1,	// Test X L-P
  1107 		3,
  1108 		3
  1109 		},
  1110 		{
  1111 		1,	// Test P-T
  1112 		2,
  1113 		2
  1114 		},
  1115 		{
  1116 		1,	// Test P-T Y
  1117 		3,
  1118 		3
  1119 		},
  1120 		{
  1121 		1,	// Test L-P-T
  1122 		3,
  1123 		3
  1124 		},
  1125 		{
  1126 		1,	// Test L-C-T
  1127 		3,
  1128 		3
  1129 		},
  1130 		{
  1131 		1,	// Test X L-P-T
  1132 		4,
  1133 		4
  1134 		},
  1135 		{
  1136 		1,	// Test X L-C-T
  1137 		4,
  1138 		4
  1139 		},
  1140 		{
  1141 		1,	// Test L-P-T Y
  1142 		4,
  1143 		4
  1144 		},
  1145 		{
  1146 		1,	// Test L-C-T Y
  1147 		4,
  1148 		4
  1149 		},
  1150 		{
  1151 		1,	// Test X L-P-T Y
  1152 		5,
  1153 		5
  1154 		},
  1155 		{
  1156 		1,	// Test X L-C-T Y
  1157 		5,
  1158 		5
  1159 		},	// End of General Combination tests
  1160 		{	// Start of Specific tests
  1161 		3,	// Test P-T B
  1162 		4,
  1163 		4
  1164 		},
  1165 		{
  1166 		1,	// Test X P-T one
  1167 		4,
  1168 		4
  1169 		},
  1170 		{
  1171 		3,	// Test X P-T two
  1172 		4,
  1173 		4
  1174 		},
  1175 		{
  1176 		1,	// Test X L-P-T one
  1177 		5,
  1178 		5
  1179 		},
  1180 		{
  1181 		1,	// Test X L-P-T two
  1182 		5,
  1183 		5
  1184 		},
  1185 		{
  1186 		3,	// Test X L-P-T three
  1187 		5,
  1188 		5
  1189 		}	// End of Specific tests
  1190 	};
  1191 
  1192 void DoLineTestL(TDes& aText, CTextLayout* aLayout, CTestGraphicsDevice* aDevice, CTextView* aView, TInt aNumChar, TInt aIndex)
  1193 	{
  1194 	aText = KTestStrings[aIndex][aNumChar][0];
  1195 	CTestFormExtendedInterfaceProvider* interfaceProvider = CTestFormExtendedInterfaceProvider::NewL(aText, aNumChar); // owned here
  1196 	aLayout->SetInterfaceProvider(interfaceProvider);
  1197 	CleanupStack::PushL(interfaceProvider);
  1198 	aDevice->LineArray().ResetLineArray();
  1199 	aView->HandleGlobalChangeL();
  1200 	// now that we've redrawn the actual ooutput (what went through DrawText(), including
  1201 	// any inline text) has been stored in the LineArray. So we#'ll have a look and see
  1202 	// if it contains what we expect it to.
  1203 	// Each line may produce one or more LineArray() entries as there is one created for
  1204 	// each call to DrawText()
  1205 	const TTestGCDisplayLine* line1 = 0;
  1206 	const TTestGCDisplayLine* line2 = 0;
  1207 	// Find out how many LineArray entries are expected for the output of this test
  1208 	TInt count = KTestCount[aIndex][aNumChar];
  1209 	// And test them (in reverse order, because it's easier)
  1210 	switch (count)
  1211 		{
  1212 	case 5:
  1213 		line1 = &(aDevice->LineArray().Line(4));
  1214 		line2 = aDevice->LineArray().Find(KTestStrings[aIndex][aNumChar][5]);
  1215 		TESTPOINT(0 != line1);
  1216 		TESTPOINT(0 != line2);
  1217 		TESTPOINT(line1->iLineData.Compare(line2->iLineData) == 0);
  1218 	case 4:
  1219 		line1 = &(aDevice->LineArray().Line(3));
  1220 		line2 = aDevice->LineArray().Find(KTestStrings[aIndex][aNumChar][4]);
  1221 		TESTPOINT(0 != line1);
  1222 		TESTPOINT(0 != line2);
  1223 		TESTPOINT(line1->iLineData.Compare(line2->iLineData) == 0);
  1224 	case 3:
  1225 		line1 = &(aDevice->LineArray().Line(2));
  1226 		line2 = aDevice->LineArray().Find(KTestStrings[aIndex][aNumChar][3]);
  1227 		TESTPOINT(0 != line1);
  1228 		TESTPOINT(0 != line2);
  1229 		TESTPOINT(line1->iLineData.Compare(line2->iLineData) == 0);
  1230 	case 2:
  1231 		line1 = &(aDevice->LineArray().Line(1));
  1232 		line2 = aDevice->LineArray().Find(KTestStrings[aIndex][aNumChar][2]);
  1233 		TESTPOINT(0 != line1);
  1234 		TESTPOINT(0 != line2);
  1235 		TESTPOINT(line1->iLineData.Compare(line2->iLineData) == 0);
  1236 	case 1:
  1237 		line1 = &(aDevice->LineArray().Line(0));
  1238 		line2 = aDevice->LineArray().Find(KTestStrings[aIndex][aNumChar][1]);
  1239 		TESTPOINT(0 != line1);
  1240 		TESTPOINT(0 != line2);
  1241 		// Can't always do a direct comparison of lines because same string
  1242 		// may appear in more than one line, so compare contents
  1243 		TESTPOINT(line1->iLineData.Compare(line2->iLineData) == 0);
  1244 		}
  1245 	aLayout->SetInterfaceProvider(NULL);
  1246 	CleanupStack::PopAndDestroy(interfaceProvider);
  1247 	}
  1248 
  1249 void GeneralCombinationTestsTextViewL(TDes& aText, CTextLayout* aLayout, CTestGraphicsDevice* aDevice, CTextView* aView, TInt aNumChar)
  1250 	{
  1251 	// For all tests carried out from here up to 20 chars will fit on a line
  1252 	TESTPRINT(_L("Test L-P"));
  1253 	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 0);
  1254 	TESTPRINT(_L("Test X L-P"));
  1255 	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 1);
  1256 	TESTPRINT(_L("Test P-T"));
  1257 	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 2);
  1258 	TESTPRINT(_L("Test P-T Y"));
  1259 	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 3);
  1260 	TESTPRINT(_L("Test L-P-T"));
  1261 	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 4);
  1262 	TESTPRINT(_L("Test L-C-T"));
  1263 	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 5);
  1264 	TESTPRINT(_L("Test X L-P-T"));
  1265 	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 6);
  1266 	TESTPRINT(_L("Test X L-C-T"));
  1267 	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 7);
  1268 	TESTPRINT(_L("Test L-P-T Y"));
  1269 	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 8);
  1270 	TESTPRINT(_L("Test L-C-T Y"));
  1271 	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 9);
  1272 	TESTPRINT(_L("Test X L-P-T Y"));
  1273 	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 10);
  1274 	TESTPRINT(_L("Test X L-C-T Y"));
  1275 	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 11);
  1276 	}
  1277 
  1278 void SpecificTestsTextViewL(TDes& aText, CTextLayout* aLayout, CTestGraphicsDevice* aDevice, CTextView* aView, TInt aNumChar)
  1279 	{
  1280 	// For all tests carried out from here up to 10 chars will fit on a line
  1281     TESTPRINT(_L("Test P-T B"));
  1282 	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 12);
  1283 	TESTPRINT(_L("Test X P-T one"));
  1284 	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 13);
  1285 	TESTPRINT(_L("Test X P-T two"));
  1286 	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 14);
  1287 	TESTPRINT(_L("Test X L-P-T one"));
  1288 	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 15);
  1289 	TESTPRINT(_L("Test X L-P-T two"));
  1290 	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 16);
  1291 	TESTPRINT(_L("Test X L-P-T three"));
  1292 	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 17);
  1293 	}
  1294 
  1295 void DoLineTestForINC141914L(TDes& aText, CTextLayout* aLayout, CTestGraphicsDevice* aDevice, CTextView* aView)
  1296     {
  1297     /*
  1298      * This case is to test whether or not inline text will find the correct format after changing the text content.
  1299      * In bytecode, there is one value to record the postion(iInlineTextFormat) to which inline text chunk attaches,
  1300      * INC141914 is raised because this value is not updated correctly after text change.
  1301      * The text string is as the following 3 lines:
  1302      * 111111;
  1303      * 222222;
  1304      * wxyBbz
  1305      * Where the 'b' is the inline text.
  1306      * 
  1307      * 1st step:
  1308      * delete 5 leading '1's in the first line,
  1309      * 2nd step:
  1310      * delete 5 leading '2's in the second line.
  1311      * after the 2 steps, inline text is still able to use iInlineTextFormat to find its attached text string
  1312     */
  1313     aText = _S("\x31\x31\x31\x31\x31\x31\x3B\x2029\x32\x32\x32\x32\x32\x32\x3B\x2029\x77\x78\x79\x42\x7A");
  1314     CTestFormExtendedInterfaceProvider* interfaceProvider = CTestFormExtendedInterfaceProvider::NewL(aText, 1); // owned here
  1315     aLayout->SetInterfaceProvider(interfaceProvider);
  1316     CleanupStack::PushL(interfaceProvider);
  1317     aDevice->LineArray().ResetLineArray();
  1318     aView->HandleGlobalChangeL();
  1319     aText.Delete(0,5);
  1320     aView->HandleInsertDeleteL(TCursorSelection(0,0),5);
  1321     aText.Delete(3,5);
  1322     aView->HandleInsertDeleteL(TCursorSelection(3,3),5);
  1323  
  1324     aLayout->SetInterfaceProvider(NULL);
  1325     CleanupStack::PopAndDestroy(interfaceProvider);
  1326     }
  1327 
  1328 void DoLineTestForINC143086L(TDes& aText, CTextLayout* aLayout, CTestGraphicsDevice* aDevice, CTextView* aView)
  1329     {
  1330     /*
  1331      * This case is to test inline text behaviour for right-to-left text 
  1332      * The text string is as the following characters:
  1333      * \x5e0\x5e1\x5e2\x5e3\x5e4\x5c0\x5e5;
  1334      * Where the '\x5c0' is the inline text.
  1335      */
  1336     aText = _S("\x5e0\x5e1\x5e2\x5e3\x5e4\x5c0\x5e5");
  1337     CTestFormExtendedInterfaceProvider* interfaceProvider = CTestFormExtendedInterfaceProvider::NewL(aText, 1); // owned here
  1338     aLayout->SetInterfaceProvider(interfaceProvider);
  1339     CleanupStack::PushL(interfaceProvider);
  1340     aDevice->LineArray().ResetLineArray();
  1341     aView->HandleGlobalChangeL();
  1342  
  1343     aLayout->SetInterfaceProvider(NULL);
  1344     CleanupStack::PopAndDestroy(interfaceProvider);
  1345     }
  1346 
  1347 // aNumChar determines what kind of inline text is in force
  1348 // 0 means no inline text, 1 means insert a single char for
  1349 // each possible inline text and 2 means insert two chars
  1350 void RunGeneralCombinationTestsL(TInt aNumChar)
  1351 	{
  1352 	CActiveScheduler* scheduler = new(ELeave) CActiveScheduler;
  1353 	CleanupStack::PushL(scheduler);
  1354 	CActiveScheduler::Install(scheduler);
  1355 	TBuf<100> text;
  1356 	TDocModel docModel(text);
  1357 	// This time make it capable of 20 chars + a couple of spare pixels
  1358 	// so all of these tests should result in a single line of output
  1359 	TRect displayRect(0, 0, KDisplayWidthWide, KDisplayHeight);
  1360 	CTextLayout* layout = CTextLayout::NewL(&docModel, displayRect.Width());
  1361 	CleanupStack::PushL(layout);
  1362 	CTestGraphicsDevice* device = CTestGraphicsDevice::NewL(displayRect.Size(), 0);
  1363 	CleanupStack::PushL(device);
  1364 	CTextView* view = CTextView::NewL(layout, displayRect, device, device, 0, 0, 0);
  1365 	CleanupStack::PushL(view);
  1366 	// This is used to force the use of CTestGraphicsContext instead of a normal one
  1367 	CWindowGc* offScreenContext;
  1368 	User::LeaveIfError(device->CreateContext(offScreenContext));
  1369 	CleanupStack::PushL(offScreenContext);
  1370 	CTestTextView::SetContextForFlickerFreeRedraw(view, offScreenContext);
  1371 
  1372 	GeneralCombinationTestsTextViewL(text, layout, device, view, aNumChar);
  1373 
  1374 	CleanupStack::PopAndDestroy(offScreenContext);
  1375 	CleanupStack::PopAndDestroy(view);
  1376 	CleanupStack::PopAndDestroy(device);
  1377 	CleanupStack::PopAndDestroy(layout);
  1378 	CleanupStack::PopAndDestroy(scheduler);
  1379 	}
  1380 
  1381 // aNumChar determines what kind of inline text is in force
  1382 // 0 means no inline text, 1 means insert a single char for
  1383 // each possible inline text and 2 means insert two chars
  1384 void RunSpecificTestsL( TInt aNumChar)
  1385 	{
  1386 	// Note: If you need to move these heap checks any further "in" to focus
  1387 	// on a specific test then you will have to move all the setup code in as
  1388 	// well - and still preserve the two different display widths in use
  1389 	__UHEAP_MARK;
  1390 	CActiveScheduler* scheduler = new(ELeave) CActiveScheduler;
  1391 	CleanupStack::PushL(scheduler);
  1392 	CActiveScheduler::Install(scheduler);
  1393 	TBuf<100> text;
  1394 	TDocModel docModel(text);
  1395 	// This time make it capable of 10 chars + a couple of spare pixels
  1396 	// so that line wrapping will occur
  1397 	TRect displayRect(0, 0, KDisplayWidthThin, KDisplayHeight);
  1398 	CTextLayout* layout = CTextLayout::NewL(&docModel, displayRect.Width());
  1399 	CleanupStack::PushL(layout);
  1400 	CTestGraphicsDevice* device = CTestGraphicsDevice::NewL(displayRect.Size(), 0);
  1401 	CleanupStack::PushL(device);
  1402 	CTextView* view = CTextView::NewL(layout, displayRect, device, device, 0, 0, 0);
  1403 	CleanupStack::PushL(view);
  1404 	// This is used to force the use of CTestGraphicsContext instead of a normal one
  1405 	CWindowGc* offScreenContext;
  1406 	User::LeaveIfError(device->CreateContext(offScreenContext));
  1407 	CleanupStack::PushL(offScreenContext);
  1408 	CTestTextView::SetContextForFlickerFreeRedraw(view, offScreenContext);
  1409 
  1410 	SpecificTestsTextViewL(text, layout, device, view, aNumChar);
  1411 
  1412 	CleanupStack::PopAndDestroy(offScreenContext);
  1413 	CleanupStack::PopAndDestroy(view);
  1414 	CleanupStack::PopAndDestroy(device);
  1415 	CleanupStack::PopAndDestroy(layout);
  1416 	CleanupStack::PopAndDestroy(scheduler);
  1417 	__UHEAP_MARKEND;
  1418 	}
  1419 
  1420 
  1421 void RunTestsForINC141914L()
  1422     {
  1423     __UHEAP_MARK;
  1424     CActiveScheduler* scheduler = new(ELeave) CActiveScheduler;
  1425     CleanupStack::PushL(scheduler);
  1426     CActiveScheduler::Install(scheduler);
  1427     TBuf<100> text;
  1428     TDocModel docModel(text);
  1429     // This time make it capable of 10 chars + a couple of spare pixels
  1430     // so that line wrapping will occur
  1431     TRect displayRect(0, 0, KDisplayWidthWide, KDisplayHeight);
  1432     CTextLayout* layout = CTextLayout::NewL(&docModel, displayRect.Width());
  1433     CleanupStack::PushL(layout);
  1434     CTestGraphicsDevice* device = CTestGraphicsDevice::NewL(displayRect.Size(), 0);
  1435     CleanupStack::PushL(device);
  1436     CTextView* view = CTextView::NewL(layout, displayRect, device, device, 0, 0, 0);
  1437     CleanupStack::PushL(view);
  1438     // This is used to force the use of CTestGraphicsContext instead of a normal one 
  1439     CWindowGc* offScreenContext;
  1440     User::LeaveIfError(device->CreateContext(offScreenContext));
  1441     CleanupStack::PushL(offScreenContext);
  1442     CTestTextView::SetContextForFlickerFreeRedraw(view, offScreenContext);
  1443 
  1444     DoLineTestForINC141914L(text, layout, device, view);
  1445     DoLineTestForINC143086L(text, layout, device, view);
  1446 
  1447     CleanupStack::PopAndDestroy(offScreenContext);
  1448     CleanupStack::PopAndDestroy(view);
  1449     CleanupStack::PopAndDestroy(device);
  1450     CleanupStack::PopAndDestroy(layout);
  1451     CleanupStack::PopAndDestroy(scheduler);
  1452     __UHEAP_MARKEND;
  1453     }
  1454 
  1455 TVerdict CTInLineTextStep::doTestStepL()
  1456 	{
  1457     SetTestStepResult(EPass);
  1458     TestStep = this;
  1459     
  1460 	__UHEAP_MARK;
  1461 	TESTPRINT(KTInlineText);
  1462 	TESTPRINT(_L(" @SYMTestCaseID:SYSLIB-FORM-LEGACY-INLINETEXT-0001 General combination tests - no inline text "));
  1463 	TInt error = RFbsSession::Connect();
  1464 	if (error == KErrNotFound)
  1465 		{
  1466 		FbsStartup();
  1467 		error = RFbsSession::Connect();
  1468 		}
  1469 	TEST(error == KErrNone);
  1470 	TRAP(error, RunGeneralCombinationTestsL(0));
  1471 	TEST(error == KErrNone);
  1472 	TESTPRINT(_L("General combination tests - single char inline text"));
  1473 	TRAP(error, RunGeneralCombinationTestsL(1));
  1474 	TEST(error == KErrNone);
  1475 	TESTPRINT(_L("General combination tests - multi char inline text"));
  1476 	TRAP(error, RunGeneralCombinationTestsL(2));
  1477 	TEST(error == KErrNone);
  1478 	TESTPRINT(_L("Specific tests - no inline text"));
  1479 	TRAP(error, RunSpecificTestsL(0));
  1480 	TEST(error == KErrNone);
  1481 	TESTPRINT(_L("Specific tests - single char inline text"));
  1482 	TRAP(error, RunSpecificTestsL(1));
  1483 	TEST(error == KErrNone);
  1484 	TESTPRINT(_L("Specific tests - multi char inline text"));
  1485 	TRAP(error, RunSpecificTestsL(2));
  1486 	TEST(error == KErrNone);
  1487 	
  1488     TESTPRINT(_L("Defect tests - for INC141914"));
  1489     TRAP(error, RunTestsForINC141914L());
  1490     TEST(error == KErrNone);
  1491     
  1492 	RFbsSession::Disconnect();
  1493 	__UHEAP_MARKEND;
  1494 	User::Heap().Check();
  1495 	return TestStepResult();
  1496 	}