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