textrendering/textformatting/test/src/TTagmaImp.cpp
changeset 0 1fb32624e06b
child 51 a7c938434754
equal deleted inserted replaced
-1:000000000000 0:1fb32624e06b
       
     1 /*
       
     2 * Copyright (c) 2001-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 * TTagmaImp.cpp test file for Tagma classes
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 #include "TGraphicsContext.h"
       
    21 #include <e32test.h>
       
    22 #include <e32std.h>
       
    23 #include <coemain.h>
       
    24 #include <gdi.h>
       
    25 #include <txtlaydc.h>
       
    26 #include "TAGMA.H"
       
    27 #include "TMSTD.H"
       
    28 #include "TmLayoutImp.h"
       
    29 #include "TMINTERP.H"
       
    30 #include "TmText.h"
       
    31 #include "InlineText.h"
       
    32 
       
    33 namespace LocalToFile
       
    34 {
       
    35 enum TTagmaImpPanic { EAccessOutsideText = 1 };
       
    36 void Panic(TTagmaImpPanic)
       
    37 	{
       
    38 	User::Panic(_L("TTagmaImp"), EAccessOutsideText);
       
    39 	}
       
    40 RTest test(_L("Tagma internals tests"));
       
    41 
       
    42 const TInt KPictureCharacter = 0xFFFC;
       
    43 
       
    44 class CPinkSquare : public CPicture
       
    45 	{
       
    46 public:
       
    47 	// Size of square in twips.
       
    48 	// 600 is 15 pixels using the standard test graphics device at
       
    49 	// its default resolution.
       
    50 	enum { KWidth = 600, KHeight = 600 };
       
    51 	CPinkSquare() {}
       
    52 	void Draw(CGraphicsContext& aGc, const TPoint& aTopLeft,
       
    53 		const TRect& aClipRect, MGraphicsDeviceMap* aMap) const
       
    54 		{
       
    55 		// This picture is a magenta square
       
    56 		TPoint size(KWidth, KHeight);
       
    57 		if (aMap)
       
    58 			size = aMap->TwipsToPixels(size);
       
    59 		TRect rect(aTopLeft, aTopLeft + size);
       
    60 		aGc.SetClippingRect(aClipRect);
       
    61 		aGc.SetDrawMode(CGraphicsContext::EDrawModePEN);
       
    62 		aGc.SetPenColor(KRgbMagenta);
       
    63 		aGc.SetBrushStyle(CGraphicsContext::ESolidBrush);
       
    64 		aGc.SetBrushColor(KRgbMagenta);
       
    65 		aGc.DrawRect(rect);
       
    66 		}
       
    67 	void ExternalizeL(RWriteStream&) const {}
       
    68 	void GetOriginalSizeInTwips(TSize& a) const
       
    69 		{
       
    70 		a.iWidth = CPinkSquare::KWidth;
       
    71 		a.iHeight = CPinkSquare::KHeight;
       
    72 		}
       
    73 	};
       
    74 
       
    75 _LIT(KEnd, "\x2029");
       
    76 class TDocModel : public MLayDoc
       
    77 	{
       
    78 public:
       
    79 	TDocModel(const TDesC& aDes)
       
    80 		: iDes(&aDes), iParagraphFormat(0) {}
       
    81 	void SetParagraphFormat(CParaFormat* a)
       
    82 		{
       
    83 		iParagraphFormat = a;
       
    84 		}
       
    85 	// From MLayDoc
       
    86 	TInt LdDocumentLength() const { return iDes->Length(); }
       
    87 	TInt LdToParagraphStart(TInt& a) const
       
    88 		{
       
    89 		TInt curr = a;
       
    90 		if (a < LdDocumentLength())
       
    91 			{
       
    92 			a = iDes->Left(a).LocateReverse(0x2029);
       
    93 			a = a < 0? 0 : a + 1;
       
    94 			}
       
    95 		return curr - a;
       
    96 		}
       
    97 	void GetParagraphFormatL(CParaFormat* aFormat, TInt) const
       
    98 		{
       
    99 		if (iParagraphFormat)
       
   100 			{
       
   101 			aFormat->CopyL(*iParagraphFormat);
       
   102 			return;
       
   103 			}
       
   104 		aFormat->Reset();
       
   105 		TTabStop tabStop;
       
   106 		tabStop.iTwipsPosition = 1000;
       
   107 		tabStop.iType = TTabStop::ELeftTab;
       
   108 		aFormat->StoreTabL(tabStop);
       
   109 		}
       
   110 	void GetChars(TPtrC& aView,TCharFormat& aFormat, TInt aStartPos)const
       
   111 		{
       
   112 		TCharFormat cf;
       
   113 		aFormat = cf;
       
   114 		if (aStartPos == LdDocumentLength())
       
   115 			aView.Set(KEnd);
       
   116 		else
       
   117 			aView.Set(iDes->Mid(aStartPos));
       
   118 		}
       
   119 	TInt GetPictureSizeInTwips(TSize& aSize, TInt aPos) const
       
   120 		{
       
   121 		if ((*iDes)[aPos] != KPictureCharacter)
       
   122 			return KErrNotFound;
       
   123 		aSize.iWidth = CPinkSquare::KWidth;
       
   124 		aSize.iHeight = CPinkSquare::KHeight;
       
   125 		return KErrNone;
       
   126 		}
       
   127 	CPicture* PictureHandleL(TInt aPos, TForcePictureLoad) const
       
   128 		{
       
   129 		if ((*iDes)[aPos] != KPictureCharacter)
       
   130 			return 0;
       
   131 		return new(ELeave) CPinkSquare;
       
   132 		}
       
   133 	TBool EnquirePageBreak(TInt aPos, TInt aLength)const
       
   134 		{
       
   135 		return iDes->Mid(aPos, aLength).Locate(0x000C) < 0?
       
   136 			EFalse : ETrue;
       
   137 		}
       
   138 	TBool SelectParagraphLabel(TInt) { return EFalse; }
       
   139 	void CancelSelectLabel() {}
       
   140 private:
       
   141 	const TDesC* iDes;
       
   142 	CParaFormat* iParagraphFormat;
       
   143 	};
       
   144 
       
   145 class THandleTester
       
   146 	{
       
   147 	TInt iProcessHandles;
       
   148 	TInt iThreadHandles;
       
   149 	RTest& iTest;
       
   150 public:
       
   151 	THandleTester(RTest& rt) : iTest(rt)
       
   152 		{
       
   153 		RThread().HandleCount(iProcessHandles, iThreadHandles);
       
   154 		}
       
   155 	~THandleTester()
       
   156 		{
       
   157 		TInt p;
       
   158 		TInt t;
       
   159 		RThread().HandleCount(p, t);
       
   160 // this seems to break at random...
       
   161 //		iTest(p == iProcessHandles);
       
   162 		iTest(t == iThreadHandles);
       
   163 		}
       
   164 	};
       
   165 
       
   166 class CFallableDeviceMap : public CBase, public MGraphicsDeviceMap
       
   167 	{
       
   168 	MGraphicsDeviceMap& iDeviceMap;
       
   169 public:
       
   170 	CFallableDeviceMap(MGraphicsDeviceMap& aDeviceMap) : iDeviceMap(aDeviceMap) {}
       
   171 	TInt HorizontalTwipsToPixels(TInt aTwips) const
       
   172 		{
       
   173 		return iDeviceMap.HorizontalTwipsToPixels(aTwips);
       
   174 		}
       
   175 	TInt VerticalTwipsToPixels(TInt aTwips) const
       
   176 		{
       
   177 		return iDeviceMap.VerticalTwipsToPixels(aTwips);
       
   178 		}
       
   179 	TInt HorizontalPixelsToTwips(TInt aPixels) const
       
   180 		{
       
   181 		return iDeviceMap.HorizontalPixelsToTwips(aPixels);
       
   182 		}
       
   183 	TInt VerticalPixelsToTwips(TInt aPixels) const
       
   184 		{
       
   185 		return iDeviceMap.VerticalPixelsToTwips(aPixels);
       
   186 		}
       
   187 	TInt GetNearestFontInTwips(CFont*& aFont,const TFontSpec& aFontSpec)
       
   188 		{
       
   189 		TInt *i = new TInt;
       
   190 		if (i)
       
   191 			{
       
   192 			delete i;
       
   193 			return iDeviceMap.GetNearestFontInTwips(aFont, aFontSpec);
       
   194 			}
       
   195 		return KErrNoMemory;
       
   196 		}
       
   197 	void ReleaseFont(CFont* aFont)
       
   198 		{
       
   199 		iDeviceMap.ReleaseFont(aFont);
       
   200 		}
       
   201 	};
       
   202 
       
   203 class CTestSource : public CBase, public MTmSource
       
   204 	{
       
   205 	MGraphicsDeviceMap* iDeviceMap;
       
   206 	TPtrC iText;
       
   207 	TTmCharFormat iDefaultCharFormat;
       
   208 	TTmCharFormat iSpecialCharFormat;
       
   209 	TInt iBeginSpecialCharFormat;
       
   210 	TInt iEndSpecialCharFormat;
       
   211 public:
       
   212 	~CTestSource()
       
   213 		{
       
   214 		delete iDeviceMap;
       
   215 		}
       
   216 	CTestSource(const TDesC& aText,
       
   217 		TTmCharFormat aDefault, TTmCharFormat aSpecial,
       
   218 		TInt aBeginSpecialCharFormat, TInt aEndSpecialCharFormat)
       
   219 		: iText(aText),
       
   220 		iDefaultCharFormat(aDefault), iSpecialCharFormat(aSpecial),
       
   221 		iBeginSpecialCharFormat(aBeginSpecialCharFormat),
       
   222 		iEndSpecialCharFormat(aEndSpecialCharFormat)
       
   223 		{
       
   224 		}
       
   225 	void ConstructL(MGraphicsDeviceMap& aDeviceMap)
       
   226 		{
       
   227 		iDeviceMap = new(ELeave) CFallableDeviceMap(aDeviceMap);
       
   228 		}
       
   229 	MGraphicsDeviceMap& FormatDevice() const { return *iDeviceMap; }
       
   230 	MGraphicsDeviceMap& InterpretDevice() const { return *iDeviceMap; }
       
   231 	TInt DocumentLength() const { return iText.Length(); }
       
   232 	void SetText(const TDesC& aStaticText)
       
   233 		{
       
   234 		iText.Set(aStaticText);
       
   235 		}
       
   236 	void GetText(TInt aPos, TPtrC& aText, TTmCharFormat& aFormat) const
       
   237 		{
       
   238 		TInt length = iText.Length()+1;
       
   239 		if (aPos < iBeginSpecialCharFormat)
       
   240 			{
       
   241 			length = iBeginSpecialCharFormat;
       
   242 			aFormat = iDefaultCharFormat;
       
   243 			}
       
   244 		else if (aPos < iEndSpecialCharFormat)
       
   245 			{
       
   246 			length = iEndSpecialCharFormat;
       
   247 			aFormat = iSpecialCharFormat;
       
   248 			}
       
   249 		else
       
   250 			{
       
   251 			aFormat = iDefaultCharFormat;
       
   252 			}
       
   253 		if (aPos == length)
       
   254 			aText.Set(0, 0);
       
   255 		else
       
   256 			aText.Set(&iText[aPos], length - aPos);
       
   257 		}
       
   258 
       
   259 	void GetParagraphFormatL(TInt, RTmParFormat& aFormat) const
       
   260 		{
       
   261 		RTmParFormat defParFormat;
       
   262 		CleanupClosePushL(defParFormat);
       
   263 		aFormat.CopyL(defParFormat);
       
   264 		CleanupStack::PopAndDestroy();
       
   265 		}
       
   266 	TInt ParagraphStart(TInt aPos) const
       
   267 		{
       
   268 		if (aPos <= iText.Length())
       
   269 			aPos = iText.Length() - 1;
       
   270 		TPtrC p(&iText[0], aPos + 1);
       
   271 		TInt delim = p.LocateReverse(TChar(CEditableText::EParagraphDelimiter));
       
   272 		return delim < 0? 0 : delim + 1;
       
   273 		}
       
   274 	CPicture* PictureL(TInt aPos) const
       
   275 		{
       
   276 		// There are no pictures, but we need to check that code never tries to
       
   277 		// take one from beyond the bounds of the text.
       
   278 		__ASSERT_ALWAYS(0 <= aPos, Panic(EAccessOutsideText));
       
   279 		__ASSERT_ALWAYS(aPos < iText.Length(), Panic(EAccessOutsideText));
       
   280 		return 0;
       
   281 		}
       
   282 	};
       
   283 
       
   284 }
       
   285 using namespace LocalToFile;
       
   286 
       
   287 
       
   288 class CTagmaImpTest : public CBase
       
   289 	{
       
   290 public:
       
   291 	CTagmaImpTest() : iDevice(0), iGc(0)
       
   292 		{
       
   293 		}
       
   294 	void ConstructL()
       
   295 		{
       
   296 		TSize size(100, 100);
       
   297 		iDevice = CTestGraphicsDevice::NewL(size, 0);
       
   298 		iDevice->CreateContext(iGc);
       
   299  		}
       
   300  	~CTagmaImpTest()
       
   301  		{
       
   302  		delete iDevice;
       
   303  		}
       
   304 	void ExerciseCTmCodeL();
       
   305 	void AddSome1L(CTmCode& aCode, TInt aStartValue);
       
   306 	TInt AddLotsL(CTmCode& aCode, TInt aAmountToAdd);
       
   307 	TInt InsertSomeL(CTmCode& aCode, TInt aStartValue, TInt aIndex);
       
   308 	TInt InsertLotsL(CTmCode& aCode, TInt aAmountToAdd, TInt aIndex);
       
   309 	TInt CheckLots(CTmCode& aCode, TInt aIndex, TInt aStartValue, TInt aCount);
       
   310 	void CTmCodeOOML();
       
   311 	CTestSource* NewTestSourceLC();
       
   312 	CTmCode* NewFormattedCTmCodeLC(MTmSource&);
       
   313 	void ExerciseFormatL();
       
   314 	void FormatOOML();
       
   315 	void ExerciseRTmTextCacheWidthL();
       
   316 	void RTmTextCacheWidthOOM();
       
   317 	void ExerciseRTmGeneralInterpreterGetDisplayedTextL();
       
   318 	void RTmGeneralInterpreterGetDisplayedTextOOM();
       
   319 	void CTmTextImp_RRunArrayL();
       
   320 	void WEP_55BHBF_DefectL();
       
   321 	void BUR_58FGE8_DefectL();
       
   322 	void EXT_5ATF8D_DefectL();
       
   323 	void INC_044969_DefectL();
       
   324 	void DEF_073838_DefectL();
       
   325 	void PDEF_101464_DefectL();
       
   326 	void DEF101994_DefectL();
       
   327 	void CTmTextImp_BidirectionalAlignmentL();
       
   328 	void ExerciseCopyL();
       
   329 	void ExerciseGetCParaFormatL();
       
   330 	void CustomFormattingL();
       
   331 	void TestChunkContext();
       
   332 	void TestBytecodeLineContext();
       
   333 	void TestBytecodeChunkContext();
       
   334 	void TestL();
       
   335 
       
   336 	void GetIndices(TDes8& aBuf, const CTmTextImp::RRunArray& aRunArray);
       
   337 	// Function to test the API's of CTmTextImp
       
   338 	void TestAPIL();
       
   339 	private:
       
   340 	CTestGraphicsDevice* iDevice;
       
   341 	CGraphicsContext* iGc;
       
   342 	};
       
   343 
       
   344 TInt CTagmaImpTest::CheckLots(CTmCode& aCode, TInt aIndex,
       
   345 	TInt aStartValue, TInt aCount)
       
   346 	{
       
   347 	TTmCodeReader reader(aCode, aIndex, aCode.Size());
       
   348 	for (; aCount; --aCount, aStartValue += 6)
       
   349 		{
       
   350 		TUint8 byte = reader.ReadByte();
       
   351 		TInt num = reader.ReadNumber();
       
   352 		TRect rect = reader.ReadRect();
       
   353 		TRect testRect(aStartValue + 2, aStartValue + 3, aStartValue + 4, aStartValue + 5);
       
   354 		test(byte == static_cast<TUint8>(aStartValue));
       
   355 		test(num == aStartValue + 1);
       
   356 		test(rect == testRect);
       
   357 		}
       
   358 	return reader.CodePos();
       
   359 	}
       
   360 
       
   361 void CTagmaImpTest::AddSome1L(CTmCode& aCode, TInt aStartValue)
       
   362 	{
       
   363 	aCode.AppendByteL(static_cast<TUint8>(aStartValue));
       
   364 	aCode.AppendNumberL(aStartValue + 1);
       
   365 	TRect rect(aStartValue + 2, aStartValue + 3, aStartValue + 4, aStartValue + 5);
       
   366 	aCode.AppendRectL(rect);
       
   367 	}
       
   368 
       
   369 TInt CTagmaImpTest::AddLotsL(CTmCode& aCode, TInt aAmountToAdd)
       
   370 	{
       
   371 	TInt finalSize = aAmountToAdd + aCode.Size();
       
   372 	TInt count = 0;
       
   373 	for (TInt i = 0; aCode.Size() < finalSize; i += 6)
       
   374 		{
       
   375 		AddSome1L(aCode, i);
       
   376 		++count;
       
   377 		}
       
   378 	return count;
       
   379 	}
       
   380 
       
   381 TInt CTagmaImpTest::InsertSomeL(CTmCode& aCode, TInt aStartValue, TInt aIndex)
       
   382 	{
       
   383 	TInt offset = aIndex - aCode.Size();
       
   384 	aCode.InsertByteL(static_cast<TUint8>(aStartValue), aIndex);
       
   385 	aCode.InsertNumberL(aStartValue + 1, aCode.Size() + offset);
       
   386 	TRect rect(aStartValue + 2, aStartValue + 3, aStartValue + 4, aStartValue + 5);
       
   387 	aCode.InsertRectL(rect, aCode.Size() + offset);
       
   388 	return aCode.Size() + offset;
       
   389 	}
       
   390 
       
   391 TInt CTagmaImpTest::InsertLotsL(CTmCode& aCode, TInt aAmountToAdd, TInt aIndex)
       
   392 	{
       
   393 	TInt finalSize = aAmountToAdd + aCode.Size();
       
   394 	TInt count = 0;
       
   395 	for (TInt i = 0; aCode.Size() < finalSize; i += 6)
       
   396 		{
       
   397 		aIndex = InsertSomeL(aCode, i, aIndex);
       
   398 		++count;
       
   399 		}
       
   400 	return count;
       
   401 	}
       
   402 
       
   403 void CTagmaImpTest::ExerciseCTmCodeL()
       
   404 	{
       
   405 	CTmCode* code = new (ELeave) CTmCode;
       
   406 	CleanupStack::PushL(code);
       
   407 	code->CreateBufferL();
       
   408 	TInt count1 = AddLotsL(*code, 400);
       
   409 	TInt size1 = code->Size();
       
   410 	TInt count2 = AddLotsL(*code, 2000);
       
   411 	TInt size2 = code->Size() - size1;
       
   412 	TInt count3 = InsertLotsL(*code, 997, size1);
       
   413 	TInt size3 = code->Size() - size1 - size2;
       
   414 	CheckLots(*code, 0, 0, count1);
       
   415 	CheckLots(*code, size1, 0, count3);
       
   416 	CheckLots(*code, size1 + size3, 0, count2);
       
   417 	CTmCode* code2 = new (ELeave) CTmCode;
       
   418 	CleanupStack::PushL(code2);
       
   419 	code2->CreateBufferL();
       
   420 	TInt count4 = AddLotsL(*code2, 3000);
       
   421 	TInt size4 = code2->Size();
       
   422 	code->ChangeL(size1, size1 + size3, *code2);
       
   423 	CheckLots(*code, 0, 0, count1);
       
   424 	CheckLots(*code, size1, 0, count4);
       
   425 	CheckLots(*code, size1 + size4, 0, count2);
       
   426 	code->Delete(size1, size4);
       
   427 	CheckLots(*code, 0, 0, count1);
       
   428 	CheckLots(*code, size1, 0, count2);
       
   429 	test(code2->Size() == 0);
       
   430 	CleanupStack::PopAndDestroy(code2);
       
   431 	CleanupStack::PopAndDestroy(code);
       
   432 	}
       
   433 
       
   434 void CTagmaImpTest::CTmCodeOOML()
       
   435 	{
       
   436 	ExerciseCTmCodeL();
       
   437 	TInt err;
       
   438 	TInt failAt = 1;
       
   439 	do {
       
   440 		THandleTester h(test);
       
   441 
       
   442 		__UHEAP_MARK;
       
   443 		__UHEAP_SETFAIL(RHeap::EDeterministic, failAt);
       
   444 		TRAP(err, ExerciseCTmCodeL());
       
   445 		__UHEAP_SETFAIL(RHeap::ENone, 0);
       
   446 		__UHEAP_MARKENDC(0);
       
   447 
       
   448 		++failAt;
       
   449 		} while (err == KErrNoMemory);
       
   450 	test(err == KErrNone);
       
   451 	}
       
   452 
       
   453 CTestSource* CTagmaImpTest::NewTestSourceLC()
       
   454 	{
       
   455 	_LIT(KTestText, "Some text for you to format for me.\x2029");
       
   456 	TTmCharFormat defCharFormat(_L("SwissA"), 60);
       
   457 	TTmCharFormat specialCharFormat(_L("Arial"), 50);
       
   458 	CTestSource* source = new(ELeave) CTestSource(KTestText,
       
   459 		defCharFormat, specialCharFormat, 5, 9);
       
   460 	CleanupStack::PushL(source);
       
   461 	source->ConstructL(*iDevice);
       
   462 	return source;
       
   463 	}
       
   464 
       
   465 CTmCode* CTagmaImpTest::NewFormattedCTmCodeLC(MTmSource& aSource)
       
   466 	{
       
   467 	CTmCode* code = new(ELeave) CTmCode;
       
   468 	CleanupStack::PushL(code);
       
   469 	TTmFormatParam formatParam;
       
   470 	formatParam.iStartChar = 0;
       
   471 	formatParam.iEndChar = aSource.DocumentLength();
       
   472 	formatParam.iLineInPar = 0;
       
   473 	formatParam.iWrapWidth = 50;
       
   474 	formatParam.iMaxHeight = KMaxTInt;
       
   475 	formatParam.iMaxLines = KMaxTInt;
       
   476 	formatParam.iFlags = TTmFormatParam::EWrap;
       
   477 	CTmFormatContext::TInfo info;
       
   478 	CTmTextLayout *layout = new(ELeave) CTmTextLayout;
       
   479 	CleanupStack::PushL(layout);
       
   480 	CTmFormatContext::FormatL(aSource, formatParam, *code, info, layout);
       
   481 	CleanupStack::PopAndDestroy(layout);
       
   482 	return code;
       
   483 	}
       
   484 
       
   485 void CTagmaImpTest::ExerciseFormatL()
       
   486 	{
       
   487 	CTestSource* source = NewTestSourceLC();
       
   488 	CTmCode* code = NewFormattedCTmCodeLC(*source);
       
   489 	CleanupStack::PopAndDestroy(code);
       
   490 	CleanupStack::PopAndDestroy(source);
       
   491 	}
       
   492 
       
   493 void CTagmaImpTest::FormatOOML()
       
   494 	{
       
   495 	// dry run- this will help the typeface store to settle down.
       
   496 	ExerciseFormatL();
       
   497 	TInt err;
       
   498 	TInt failAt = 1;
       
   499 	do {
       
   500 		THandleTester h(test);
       
   501 
       
   502 		__UHEAP_MARK;
       
   503 		__UHEAP_SETFAIL(RHeap::EDeterministic, failAt);
       
   504 		TRAP(err, ExerciseFormatL());
       
   505 		__UHEAP_SETFAIL(RHeap::ENone, 0);
       
   506 		__UHEAP_MARKENDC(0);
       
   507 
       
   508 		++failAt;
       
   509 		} while (err == KErrNoMemory);
       
   510 	test(err == KErrNone);
       
   511 	}
       
   512 
       
   513 void CTagmaImpTest::ExerciseRTmTextCacheWidthL()
       
   514 	{
       
   515 	_LIT(KOnions, "How easily happiness starts, slicing onions.\x2029");
       
   516 	TTmCharFormat defCharFormat(_L("SwissA"), 60);
       
   517 	TTmCharFormat specialCharFormat(_L("Arial"), 50);
       
   518 	CTestSource* source = new (ELeave) CTestSource(KOnions,
       
   519 		defCharFormat, specialCharFormat, 11, 20);
       
   520 	CleanupStack::PushL(source);
       
   521 	source->ConstructL(*iDevice);
       
   522 	RTmTextCache textCache(*source, source->FormatDevice());
       
   523 	CleanupClosePushL(textCache);
       
   524 	textCache.TotalWidthL(0, KOnions().Length(), EFalse);
       
   525 	textCache.AdvanceWidthL(0, KOnions().Length(), EFalse);
       
   526 	CleanupStack::PopAndDestroy();
       
   527 	CleanupStack::PopAndDestroy(source);
       
   528 	}
       
   529 
       
   530 void CTagmaImpTest::RTmTextCacheWidthOOM()
       
   531 	{
       
   532 	TInt err;
       
   533 	TInt failAt = 1;
       
   534 	do {
       
   535 		THandleTester h(test);
       
   536 
       
   537 		__UHEAP_MARK;
       
   538 		__UHEAP_SETFAIL(RHeap::EDeterministic, failAt);
       
   539 		TRAP(err, ExerciseRTmTextCacheWidthL());
       
   540 		__UHEAP_SETFAIL(RHeap::ENone, 0);
       
   541 		__UHEAP_MARKENDC(0);
       
   542 
       
   543 		++failAt;
       
   544 		} while (err == KErrNoMemory);
       
   545 	test(err == KErrNone);
       
   546 	}
       
   547 
       
   548 void CTagmaImpTest::ExerciseRTmGeneralInterpreterGetDisplayedTextL()
       
   549 	{
       
   550 	CTestSource* source = NewTestSourceLC();
       
   551 	CTmCode* code = NewFormattedCTmCodeLC(*source);
       
   552 	TTmInterpreterParam param(*code);
       
   553 	param.iCodeStart = 0;
       
   554 	param.iCodeEnd = code->Size();
       
   555 	param.iTextStart = 0;
       
   556 	param.iWidth = 50;
       
   557 	RTmGeneralInterpreter interp(*source, param);
       
   558 	CleanupClosePushL(interp);
       
   559 	TInt needed;
       
   560 	TBuf<50> buf;
       
   561 	interp.GetDisplayedTextL(0, buf,0, needed);
       
   562 	CleanupStack::PopAndDestroy();		// interp.Close()
       
   563 	RTmGeneralInterpreter interp2(*source, param);
       
   564 	CleanupClosePushL(interp2);
       
   565 	interp2.GetDisplayedTextL(1, buf, 0,needed);
       
   566 	CleanupStack::PopAndDestroy();		// interp2.Close()
       
   567 	CleanupStack::PopAndDestroy(code);
       
   568 	CleanupStack::PopAndDestroy(source);
       
   569 	}
       
   570 
       
   571 void CTagmaImpTest::RTmGeneralInterpreterGetDisplayedTextOOM()
       
   572 	{
       
   573 	TInt err;
       
   574 	TInt failAt = 1;
       
   575 	do {
       
   576 		THandleTester h(test);
       
   577 
       
   578 		__UHEAP_MARK;
       
   579 		__UHEAP_SETFAIL(RHeap::EDeterministic, failAt);
       
   580 		TRAP(err, ExerciseRTmGeneralInterpreterGetDisplayedTextL());
       
   581 		__UHEAP_SETFAIL(RHeap::ENone, 0);
       
   582 		__UHEAP_MARKENDC(0);
       
   583 
       
   584 		++failAt;
       
   585 		} while (err == KErrNoMemory);
       
   586 	test(err == KErrNone);
       
   587 	}
       
   588 
       
   589 void CTagmaImpTest::WEP_55BHBF_DefectL()
       
   590 	{
       
   591 	__UHEAP_MARK;
       
   592 	// defect WEP-55BHBF: EikLabels index out of bounds!!!!
       
   593 	// There is a picture character at the end to trick GetLineBreakL
       
   594 	// into looking outside the text for a picture.
       
   595 	_LIT(KHello, "hello\xFFFC");
       
   596 	TPtrC helloSeg(KHello().Ptr(), 5);
       
   597 	CTestSource* source = NewTestSourceLC();
       
   598 
       
   599 	TInt bp, hc, bpas;
       
   600 	source->SetText(helloSeg);
       
   601 	source->GetLineBreakL(helloSeg, 0, 0, 5, ETrue, bp, hc, bpas);
       
   602 	CleanupStack::PopAndDestroy();
       
   603 	__UHEAP_MARKEND;
       
   604 	}
       
   605 
       
   606 /** test code for INC044969 - Word app: Missing words on right of page
       
   607 
       
   608 	When Word is formating a block of text which consists of 8 repeats of
       
   609 	"this is a test " and the line break occurs just after "a", the defect caused the "a"
       
   610 	to disappear, so the line ended with "this is" and the next line started with
       
   611 	"test".
       
   612  */
       
   613 void CTagmaImpTest::INC_044969_DefectL()
       
   614 	{
       
   615 
       
   616 	// create a CTestSource containing the test data
       
   617 	_LIT(KTest, " this is a test this is a test this is a test this is a test this is a test this is a test this is a test this is a test.");
       
   618 	TPtrC testSeg(KTest().Ptr(), KTest().Length() );
       
   619 	CTestSource* source = NewTestSourceLC();
       
   620 	source->SetText(testSeg);
       
   621 
       
   622 	CTmCode* code = new(ELeave) CTmCode;
       
   623 	CleanupStack::PushL(code);
       
   624 
       
   625 	// format the text, a wrap width of 100 should produce
       
   626 	// the required break position of 10 (just after the a of " this is a")
       
   627 	CTmFormatContext::TInfo info;
       
   628 	TTmFormatParam formatParam;
       
   629 	formatParam.iStartChar = 0;
       
   630 	formatParam.iEndChar = source->DocumentLength();
       
   631 	formatParam.iLineInPar = 0;
       
   632 	formatParam.iMaxHeight = KMaxTInt;
       
   633 	formatParam.iMaxLines = KMaxTInt;
       
   634 	formatParam.iFlags = TTmFormatParam::EWrap;
       
   635 	formatParam.iWrapWidth = 100;
       
   636 	CTmTextLayout* layout = new(ELeave) CTmTextLayout;
       
   637 	CleanupStack::PushL(layout);
       
   638 	CTmFormatContext::FormatL(*source, formatParam, *code, info, layout);
       
   639 
       
   640 	// check that format has found the break at 11 characters
       
   641 	// This is at the end of "this is a "
       
   642 	test( info.iFirstLineEndChar == 11 );
       
   643 
       
   644 	// get the text that would be displayed into displayBuffer
       
   645 	TTmInterpreterParam interpreter_param(*code);
       
   646 	interpreter_param.iCodeStart = 0;
       
   647 	interpreter_param.iCodeEnd = code->Size();
       
   648 	interpreter_param.iTextStart = 0;
       
   649 	interpreter_param.iWidth = 50;
       
   650 	RTmGeneralInterpreter interpreter(*source, interpreter_param);
       
   651 	TInt noCharsToDisplay =0;
       
   652 	TBuf<200> displayBuffer;
       
   653 	interpreter.GetDisplayedTextL(0, displayBuffer,0, noCharsToDisplay);
       
   654 
       
   655 	// now check the content of the buffer returned
       
   656 	// The defect caused this buffer to be missing the final 'a'
       
   657 	// from "...this is a" at the end of the line
       
   658 	// When this defect happens noCharsToDisplay != info.iFirstLineEndChar
       
   659 	test( info.iFirstLineEndChar == noCharsToDisplay );
       
   660 	test( displayBuffer[9] == 'a' );
       
   661 
       
   662 	interpreter.Close();
       
   663 	CleanupStack::PopAndDestroy(layout);
       
   664 	CleanupStack::PopAndDestroy(code);   // code 
       
   665 	CleanupStack::PopAndDestroy(source); // source
       
   666 
       
   667 	}
       
   668 
       
   669 /** test code for DEF073838 - Line break problem with WORD
       
   670 
       
   671 	When appending a space to the last line of a Word document, the defect
       
   672 	caused the last word of the line to be moved to a new line as if the space
       
   673 	were part of the word itself. So, if a paragraph ended with the words
       
   674 	"this is a test " and the final space was after the right margin, the line
       
   675 	was broken at the position of the 't' of "test".
       
   676  */
       
   677 void CTagmaImpTest::DEF_073838_DefectL()
       
   678 	{
       
   679 	CTmCode* code = new(ELeave) CTmCode;
       
   680 	CleanupStack::PushL(code);
       
   681 
       
   682 
       
   683 	// 1. format the text, a wrap width of 520 should produce no line breaks.
       
   684 	// 	0x2029 is EParagraphDelimiter
       
   685 	CTestSource* source1 = NewTestSourceLC();
       
   686 
       
   687 	_LIT(KTest1, "Quo usque tandem, Catilina, abutere patientia nostra \x2029");
       
   688 	TPtrC testSeg1(KTest1().Ptr(), KTest1().Length() );
       
   689 	source1->SetText(testSeg1);
       
   690 
       
   691 	CTmFormatContext::TInfo info1;
       
   692 	TTmFormatParam formatParam1;
       
   693 	formatParam1.iStartChar = 0;
       
   694 	formatParam1.iEndChar = source1->DocumentLength();
       
   695 	formatParam1.iLineInPar = 0;
       
   696 	formatParam1.iMaxHeight = KMaxTInt;
       
   697 	formatParam1.iMaxLines = KMaxTInt;
       
   698 	formatParam1.iFlags = TTmFormatParam::EWrap;
       
   699 	formatParam1.iWrapWidth = 520;
       
   700 	CTmTextLayout* layout = new(ELeave) CTmTextLayout;
       
   701 	CleanupStack::PushL(layout);
       
   702 	CTmFormatContext::FormatL(*source1, formatParam1, *code, info1, layout);
       
   703 
       
   704 	// check that format didn't found any breaks
       
   705 	test( info1.iFirstLineEndChar == KTest1().Length());
       
   706 	test( info1.iLastLineStartChar == 0 );
       
   707 	test( info1.iHeight == 12 ); // just 1 line
       
   708 
       
   709 
       
   710 
       
   711 	// 2. now append more than one space and verify that the line is not broken
       
   712 	CTestSource* source2 = NewTestSourceLC();
       
   713 
       
   714 	_LIT(KTest2, "Quo usque tandem, Catilina, abutere patientia nostra        \x2029");
       
   715 	TPtrC testSeg2(KTest2().Ptr(), KTest2().Length() );
       
   716 	source2->SetText(testSeg2);
       
   717 
       
   718 	CTmFormatContext::TInfo info2;
       
   719 	TTmFormatParam formatParam2;
       
   720 	formatParam2.iStartChar = 0;
       
   721 	formatParam2.iEndChar = source2->DocumentLength();
       
   722 	formatParam2.iLineInPar = 0;
       
   723 	formatParam2.iMaxHeight = KMaxTInt;
       
   724 	formatParam2.iMaxLines = KMaxTInt;
       
   725 	formatParam2.iFlags = TTmFormatParam::EWrap;
       
   726 	formatParam2.iWrapWidth = 520;
       
   727 	CTmFormatContext::FormatL(*source2, formatParam2, *code, info2, layout);
       
   728 
       
   729 	// check that format didn't found any breaks
       
   730 	test( info2.iFirstLineEndChar == KTest2().Length());
       
   731 	test( info2.iLastLineStartChar == 0 );
       
   732 	test( info2.iHeight == 12 ); // just 1 line
       
   733 
       
   734 
       
   735 
       
   736 	// 3. now test with page breaks (0x000C) and line breaks (0x2028)
       
   737 	CTestSource* source3 = NewTestSourceLC();
       
   738 
       
   739 	_LIT(KTest3, "Quo usque tandem, Catilina, abutere patientia nostra \x2028Quo usque tandem, Catilina, abutere patientia nostra \x000CQuo usque tandem, Catilina, abutere patientia nostra \x2029");
       
   740 	TPtrC testSeg3(KTest3().Ptr(), KTest3().Length() );
       
   741 	source3->SetText(testSeg3);
       
   742 
       
   743 	CTmFormatContext::TInfo info3;
       
   744 	TTmFormatParam formatParam3;
       
   745 	formatParam3.iStartChar = 0;
       
   746 	formatParam3.iEndChar = source3->DocumentLength();
       
   747 	formatParam3.iLineInPar = 0;
       
   748 	formatParam3.iMaxHeight = KMaxTInt;
       
   749 	formatParam3.iMaxLines = KMaxTInt;
       
   750 	formatParam3.iFlags = TTmFormatParam::EWrap;
       
   751 	formatParam3.iWrapWidth = 520;
       
   752 	CTmFormatContext::FormatL(*source3, formatParam3, *code, info3, layout);
       
   753 
       
   754 	// check that format didn't found any breaks
       
   755 	test( info3.iFirstLineEndChar == 54 );
       
   756 	test( info3.iLastLineStartChar == 108 );
       
   757 	test( info3.iHeight == 36 ); // 3 lines
       
   758 
       
   759 	CleanupStack::PopAndDestroy(source3);
       
   760 	CleanupStack::PopAndDestroy(source2);
       
   761 	CleanupStack::PopAndDestroy(layout); 
       
   762 	CleanupStack::PopAndDestroy(source1);
       
   763 	CleanupStack::PopAndDestroy(code);
       
   764 	}
       
   765 
       
   766 class TTestParLabelSource : public MTmSource, public MFormLabelApi
       
   767 	{
       
   768 	MGraphicsDeviceMap* iDevice;
       
   769 	TPtrC iBody;
       
   770 	TPtrC iLabel;
       
   771 	TPtrC* iCurrent;
       
   772 public:
       
   773 	TTestParLabelSource(MGraphicsDeviceMap* aDevice,
       
   774 		const TDesC& aBody, const TDesC& aLabel)
       
   775 		: iDevice(aDevice)
       
   776 		{
       
   777 		iBody.Set(aBody.Ptr(), aBody.Length());
       
   778 		iLabel.Set(aLabel.Ptr(), aLabel.Length());
       
   779 		iCurrent = &iBody;
       
   780 		}
       
   781 	void Close()
       
   782 		{
       
   783 		}
       
   784 	TInt DocumentLength() const { return iCurrent->Length(); }
       
   785 	MGraphicsDeviceMap& FormatDevice() const
       
   786 		{
       
   787 		return *iDevice;
       
   788 		}
       
   789 	TAny* GetExtendedInterface(const TUid& aInterfaceId)
       
   790 		{
       
   791 		if (aInterfaceId == KFormLabelApiExtensionUid)
       
   792 			{
       
   793 			return static_cast<MFormLabelApi*>(this);
       
   794 			}
       
   795 		else
       
   796 			{
       
   797 			// In this instance, calling the parent class will always return NULL
       
   798 			// but the pattern should be followed by all implementors for safety
       
   799 			return MTmSource::GetExtendedInterface(aInterfaceId);
       
   800 			}
       
   801 		}
       
   802 	void LabelMetrics(TLabelType /*aType*/, TSize& aLabelSize, TInt& aMarginSize) const
       
   803 		{
       
   804 		aLabelSize.iWidth = 100;
       
   805 		aLabelSize.iHeight = 10;
       
   806 		aMarginSize = 10;
       
   807 		}
       
   808 	void GetParagraphFormatL(TInt aPos, RTmParFormat& aFormat) const
       
   809 		{
       
   810 		__ASSERT_ALWAYS(0 <= aPos, User::Invariant());
       
   811 		__ASSERT_ALWAYS(aPos <= iCurrent->Length(), User::Invariant());
       
   812 		const RTmParFormat f;
       
   813 		aFormat.CopyL(f);
       
   814 		}
       
   815 	void GetText(TInt aPos,TPtrC& aText,TTmCharFormat& aFormat) const
       
   816 		{
       
   817 		ASSERT(0 <= aPos);
       
   818 		ASSERT(aPos <= iCurrent->Length());
       
   819 		aText.Set(iCurrent->Ptr() + aPos, iCurrent->Length()+1 - aPos);
       
   820 		TTmCharFormat f;
       
   821 		aFormat = f;
       
   822 		}
       
   823 	MGraphicsDeviceMap& InterpretDevice() const
       
   824 		{
       
   825 		return *iDevice;
       
   826 		}
       
   827 	TInt ParagraphStart(TInt) const { return 0; }
       
   828 	TBool LabelModeSelect(TLabelType,TInt)
       
   829 		{
       
   830 		if (iCurrent == &iLabel)
       
   831 			return EFalse;
       
   832 		iCurrent = &iLabel;
       
   833 		return ETrue;
       
   834 		}
       
   835 	void LabelModeCancel() { iCurrent = &iBody; }
       
   836 	TRgb SystemColor(TUint aColorIndex,TRgb aDefaultColor) const
       
   837 		{
       
   838 		if (aColorIndex == TLogicalRgb::ESystemSelectionForegroundIndex)
       
   839 			return KRgbWhite;
       
   840 		if (aColorIndex == TLogicalRgb::ESystemSelectionBackgroundIndex)
       
   841 			return KRgbRed;
       
   842 		return MTmSource::SystemColor(aColorIndex, aDefaultColor);
       
   843 		}
       
   844 	};
       
   845 
       
   846 void CTagmaImpTest::BUR_58FGE8_DefectL()
       
   847 	{
       
   848 	// Int: Application panic when selecting, Select All from the edit menu
       
   849 	_LIT(KBody, "small\x2029");
       
   850 	_LIT(KLabel, "longer than the body\x2029");
       
   851 	TTestParLabelSource s(iDevice, KBody, KLabel);
       
   852 	CTmTextLayout* lay = new(ELeave) CTmTextLayout;
       
   853 	TTmFormatParam fp;
       
   854 	fp.iWrapWidth = 200;
       
   855 	fp.iEndChar = KBody().Length();
       
   856 	lay->SetTextL(s, fp);
       
   857 	TPoint zero;
       
   858 	TRect clip(0, 0, 200, 200);
       
   859 	lay->HighlightSection(*iGc, zero, 0, KBody().Length(), clip);
       
   860 	s.Close();
       
   861 	}
       
   862 
       
   863 /**
       
   864  * EXT-5ATF8D: "TAGMA - different character formats" The complaint is that
       
   865  * CTmText does not seem to display differently formatted characters in their
       
   866  * different formats. The defect is due to the fact that the function to get
       
   867  * the text from the buffer ignores the length of run of characters, so the
       
   868  * rendering assumes that all the characters are in the same format.
       
   869  * @internalComponent
       
   870  */
       
   871 void CTagmaImpTest::EXT_5ATF8D_DefectL()
       
   872 	{
       
   873 	TTmFormatParamBase formatParam;
       
   874 	CTmTextImp* text = new(ELeave)
       
   875 		CTmTextImp(*iDevice, formatParam);
       
   876 	CleanupStack::PushL(text);
       
   877 
       
   878 	TTmCharFormat cf1;
       
   879 	cf1.iEffects |= TTmCharFormat::EUnderline;
       
   880 	TTmCharFormat cf2;
       
   881 	cf2.iEffects &= ~TTmCharFormat::EUnderline;
       
   882 	RTmParFormat pf1;
       
   883 	CleanupClosePushL(pf1);
       
   884 	pf1.iSpaceAbove = 1;
       
   885 	RTmParFormat pf2;
       
   886 	CleanupClosePushL(pf2);
       
   887 	pf2.iSpaceAbove = 2;
       
   888 	text->InsertL(0, _L("first line\x2029second."), &cf1, &pf1, 0, 0);
       
   889 	text->InsertL(14, _L("t p"), &cf2, &pf2, 0, 0);
       
   890 
       
   891 	TPtrC testText;
       
   892 	TTmCharFormat cft;
       
   893 	RTmParFormat pft;
       
   894 	CleanupClosePushL(pft);
       
   895 
       
   896 	text->GetText(0, testText, cft);
       
   897 	text->GetParagraphFormatL(0, pft);
       
   898 	test(testText.Length() == 14);
       
   899 	test(testText.Compare(_L("first line\x2029sec")) == 0);
       
   900 	test(cft == cf1);
       
   901 	test(pft == pf1);
       
   902 
       
   903 	text->GetText(11, testText, cft);
       
   904 	text->GetParagraphFormatL(11, pft);
       
   905 	test(testText.Length() == 3);
       
   906 	test(testText.Compare(_L("sec")) == 0);
       
   907 	test(cft == cf1);
       
   908 	test(pft == pf2);
       
   909 
       
   910 	text->GetText(14, testText, cft);
       
   911 	text->GetParagraphFormatL(14, pft);
       
   912 	test(testText.Length() == 3);
       
   913 	test(testText.Compare(_L("t p")) == 0);
       
   914 	test(cft == cf2);
       
   915 	test(pft == pf2);
       
   916 
       
   917 	text->GetText(17, testText, cft);
       
   918 	text->GetParagraphFormatL(17, pft);
       
   919 	test(cft == cf1);
       
   920 	test(pft == pf2);
       
   921 
       
   922 	text->GetText(21, testText, cft);
       
   923 	text->GetParagraphFormatL(21, pft);
       
   924 	test(pft == pf2);
       
   925 	CleanupStack::PopAndDestroy(&pft);
       
   926 	CleanupStack::PopAndDestroy(&pf2);
       
   927 	CleanupStack::PopAndDestroy(&pf1);
       
   928 	CleanupStack::PopAndDestroy(text);
       
   929 	}
       
   930 
       
   931 void CTagmaImpTest::GetIndices(TDes8& aBuf, const CTmTextImp::RRunArray& aRunArray)
       
   932 	{
       
   933 	test(aRunArray.Index(0) == aRunArray.Index(1));
       
   934 	aBuf.Zero();
       
   935 	TInt index;
       
   936 	for (TInt i = 1; 0 <= (index = aRunArray.Index(i)); ++i)
       
   937 		{
       
   938 		aBuf.Append('0' + index);
       
   939 		}
       
   940 	}
       
   941 
       
   942 /**
       
   943 @SYMTestCaseID          SYSLIB-FORM-UT-1886
       
   944 @SYMTestCaseDesc        Testing the API's of CTmTextImp: ChangeFormatL, MemoryUsed, SystemColor, CustomizeL
       
   945 @SYMTestPriority        Low
       
   946 @SYMTestActions         Tests by changing the format, checking the memory usage, setting the system colour and Changing the custom formatting
       
   947 @SYMTestExpectedResults Tests must not fail
       
   948 @SYMREQ                 REQ0000
       
   949 */
       
   950 void CTagmaImpTest::TestAPIL()
       
   951 	{
       
   952 	TTmFormatParam formatParam;
       
   953 	CTmTextImp* text = new(ELeave)
       
   954 		CTmTextImp(*iDevice, formatParam);
       
   955 	CleanupStack::PushL(text);
       
   956 	TTmCharFormat cf1;
       
   957 	cf1.iEffects |= TTmCharFormat::EUnderline;
       
   958 	RTmParFormat pf1;
       
   959 	CleanupClosePushL(pf1);
       
   960 	pf1.iSpaceAbove = 1;
       
   961 	text->InsertL(0, _L("Some text"), &cf1, &pf1, 0, 0);
       
   962 
       
   963 	TInt memUsed = text->MemoryUsed();
       
   964 	text->ChangeFormatL(formatParam);
       
   965 	test(text->MemoryUsed()==memUsed);
       
   966 
       
   967 	TTmFormatParam formatParam1;
       
   968 	formatParam1.iStartChar = 0;
       
   969 	formatParam1.iEndChar = 15;
       
   970 	formatParam1.iLineInPar = 0;
       
   971 	formatParam1.iWrapWidth = 50;
       
   972 	formatParam1.iMaxHeight = KMaxTInt;
       
   973 	formatParam1.iMaxLines = KMaxTInt;
       
   974 	formatParam1.iFlags = TTmFormatParam::EWrap;
       
   975 	//Setting the format of the text
       
   976 	text->ChangeFormatL(formatParam1);
       
   977 	//After changing the format, memory used by the text differs from the initial value
       
   978 	test(text->MemoryUsed()!=memUsed);
       
   979 	TRgb color1(100,10,20);
       
   980 	TRgb color2;
       
   981 	//Setting the system colour with an index representing the system background colour
       
   982 	color2 = text->SystemColor(TLogicalRgb::ESystemBackgroundIndex,color1);
       
   983 	test(color2==color1);
       
   984 
       
   985 	_LIT(KBody, "Body");
       
   986 	_LIT(KLabel, "Label, Longer than Body");
       
   987 	TTestParLabelSource sourceLabel(iDevice, KBody, KLabel);
       
   988 	CTmTextLayout* iLayout = new (ELeave) CTmTextLayout;
       
   989 	iLayout->SetTextL(sourceLabel, formatParam);
       
   990 	//Changing the custom formatting
       
   991 	text->CustomizeL(iLayout->Source());
       
   992 
       
   993 	//Setting the system colour with an index representing the system foreground colour
       
   994 	color2 = text->SystemColor(TLogicalRgb::ESystemSelectionForegroundIndex,color1);
       
   995 	test(color2!=color1);
       
   996 	CleanupStack::PopAndDestroy(&pf1);
       
   997 	CleanupStack::PopAndDestroy(text);
       
   998 	}
       
   999 
       
  1000 void CTagmaImpTest::CTmTextImp_RRunArrayL()
       
  1001 	{
       
  1002 	TBuf8<50> indexBuf;
       
  1003 	CTmTextImp::RRunArray ra;
       
  1004 	CleanupClosePushL(ra);
       
  1005 	GetIndices(indexBuf, ra);
       
  1006 	test(0 == indexBuf.Compare(_L8("")));
       
  1007 	ra.Insert(0, 10, 0);
       
  1008 	GetIndices(indexBuf, ra);
       
  1009 	test(0 == indexBuf.Compare(_L8("0000000000")));
       
  1010 	ra.Insert(5, 10, 1);
       
  1011 	GetIndices(indexBuf, ra);
       
  1012 	test(0 == indexBuf.Compare(_L8("00000111111111100000")));
       
  1013 	ra.Delete(13, 4);
       
  1014 	GetIndices(indexBuf, ra);
       
  1015 	test(0 == indexBuf.Compare(_L8("0000011111111000")));
       
  1016 	ra.Delete(2, 12);
       
  1017 	GetIndices(indexBuf, ra);
       
  1018 	test(0 == indexBuf.Compare(_L8("0000")));
       
  1019 	ra.Delete(0, 4);
       
  1020 	GetIndices(indexBuf, ra);
       
  1021 	test(0 == indexBuf.Compare(_L8("")));
       
  1022 	ra.Insert(0, 20, 0);
       
  1023 	ra.Set(5, 10, 1);
       
  1024 	GetIndices(indexBuf, ra);
       
  1025 	test(0 == indexBuf.Compare(_L8("00000111111111100000")));
       
  1026 	ra.Set(6, 4, 2);
       
  1027 	GetIndices(indexBuf, ra);
       
  1028 	test(0 == indexBuf.Compare(_L8("00000122221111100000")));
       
  1029 	ra.Set(10, 4, 3);
       
  1030 	GetIndices(indexBuf, ra);
       
  1031 	test(0 == indexBuf.Compare(_L8("00000122223333100000")));
       
  1032 	ra.Set(9, 2, 1);
       
  1033 	GetIndices(indexBuf, ra);
       
  1034 	test(0 == indexBuf.Compare(_L8("00000122211333100000")));
       
  1035 	ra.Set(6, 1, 1);
       
  1036 	GetIndices(indexBuf, ra);
       
  1037 	test(0 == indexBuf.Compare(_L8("00000112211333100000")));
       
  1038 	ra.Set(8, 1, 1);
       
  1039 	GetIndices(indexBuf, ra);
       
  1040 	test(0 == indexBuf.Compare(_L8("00000112111333100000")));
       
  1041 	ra.Set(7, 1, 1);
       
  1042 	GetIndices(indexBuf, ra);
       
  1043 	test(0 == indexBuf.Compare(_L8("00000111111333100000")));
       
  1044 	ra.Set(7, 2, 2);
       
  1045 	GetIndices(indexBuf, ra);
       
  1046 	test(0 == indexBuf.Compare(_L8("00000112211333100000")));
       
  1047 	ra.Set(1, 19, 1);
       
  1048 	GetIndices(indexBuf, ra);
       
  1049 	test(0 == indexBuf.Compare(_L8("01111111111111111111")));
       
  1050 	CleanupStack::PopAndDestroy(&ra);
       
  1051 	}
       
  1052 
       
  1053 
       
  1054 void CTagmaImpTest::CTmTextImp_BidirectionalAlignmentL()
       
  1055 	{
       
  1056 	ExerciseCopyL();
       
  1057 	ExerciseGetCParaFormatL();
       
  1058 	}
       
  1059 
       
  1060 void CTagmaImpTest::ExerciseCopyL()
       
  1061 	{
       
  1062 	CParaFormat* pF = CParaFormat::NewL();
       
  1063 	CleanupStack::PushL(pF);
       
  1064 	RTmParFormat rPF;
       
  1065 
       
  1066 	test(RTmParFormat::EAlignNormalBidirectional == rPF.iAlignment);
       
  1067 
       
  1068 	rPF.CopyL(*pF);
       
  1069 	test(RTmParFormat::EAlignNormal == rPF.iAlignment);
       
  1070 
       
  1071 	pF->iHorizontalAlignment = CParaFormat::ELeftAlign;
       
  1072 	rPF.CopyL(*pF);
       
  1073 	test(RTmParFormat::EAlignNormal == rPF.iAlignment);
       
  1074 
       
  1075 	pF->iHorizontalAlignment = CParaFormat::ECenterAlign;
       
  1076 	rPF.CopyL(*pF);
       
  1077 	test(RTmParFormat::EAlignCenter == rPF.iAlignment);
       
  1078 
       
  1079 	pF->iHorizontalAlignment = CParaFormat::ERightAlign;
       
  1080 	rPF.CopyL(*pF);
       
  1081 	test(RTmParFormat::EAlignReverse == rPF.iAlignment);
       
  1082 
       
  1083 	pF->iHorizontalAlignment = CParaFormat::EJustifiedAlign;
       
  1084 	rPF.CopyL(*pF);
       
  1085 	test(RTmParFormat::EAlignJustify == rPF.iAlignment);
       
  1086 
       
  1087 	pF->iHorizontalAlignment = CParaFormat::EAbsoluteLeftAlign;
       
  1088 	rPF.CopyL(*pF);
       
  1089 	test(RTmParFormat::EAlignAbsoluteLeft == rPF.iAlignment);
       
  1090 
       
  1091 	pF->iHorizontalAlignment = CParaFormat::EAbsoluteRightAlign;
       
  1092 	rPF.CopyL(*pF);
       
  1093 	test(RTmParFormat::EAlignAbsoluteRight == rPF.iAlignment);
       
  1094 
       
  1095 	rPF.Close();
       
  1096 	CleanupStack::PopAndDestroy(); //pF
       
  1097 	}
       
  1098 
       
  1099 void CTagmaImpTest::ExerciseGetCParaFormatL()
       
  1100 	{
       
  1101 	CParaFormat* pF = CParaFormat::NewL();
       
  1102 	CleanupStack::PushL(pF);
       
  1103 	RTmParFormat rPF;
       
  1104 
       
  1105 	test(pF->iHorizontalAlignment == CParaFormat::ELeftAlign);
       
  1106 
       
  1107 	rPF.iAlignment = RTmParFormat::EAlignNormal;
       
  1108 	rPF.GetCParaFormatL(*pF);
       
  1109 	test(CParaFormat::ELeftAlign == pF->iHorizontalAlignment);
       
  1110 
       
  1111 	rPF.iAlignment = RTmParFormat::EAlignCenter;
       
  1112 	rPF.GetCParaFormatL(*pF);
       
  1113 	test(CParaFormat::ECenterAlign == pF->iHorizontalAlignment);
       
  1114 
       
  1115 	rPF.iAlignment = RTmParFormat::EAlignReverse;
       
  1116 	rPF.GetCParaFormatL(*pF);
       
  1117 	test(CParaFormat::ERightAlign == pF->iHorizontalAlignment);
       
  1118 
       
  1119 	rPF.iAlignment = RTmParFormat::EAlignJustify;
       
  1120 	rPF.GetCParaFormatL(*pF);
       
  1121 	test(CParaFormat::EJustifiedAlign == pF->iHorizontalAlignment);
       
  1122 
       
  1123 	rPF.iAlignment = RTmParFormat::EAlignAbsoluteLeft;
       
  1124 	rPF.GetCParaFormatL(*pF);
       
  1125 	test(CParaFormat::EAbsoluteLeftAlign == pF->iHorizontalAlignment);
       
  1126 
       
  1127 	rPF.iAlignment = RTmParFormat::EAlignAbsoluteRight;
       
  1128 	rPF.GetCParaFormatL(*pF);
       
  1129 	test(CParaFormat::EAbsoluteRightAlign == pF->iHorizontalAlignment);
       
  1130 
       
  1131 	rPF.Close();
       
  1132 	CleanupStack::PopAndDestroy(); // pF
       
  1133 	}
       
  1134 
       
  1135 class TTestCustomFormattingSource : public MTmSource, public MTmInlineTextSource
       
  1136 	{
       
  1137 	MGraphicsDeviceMap* iDevice;
       
  1138 	TInt iCustomFormatType;
       
  1139 	TPtrC iBody;
       
  1140 	TPtrC* iCurrent;
       
  1141 	TPtrC iNullText;
       
  1142 public:
       
  1143 	TTestCustomFormattingSource(MGraphicsDeviceMap* aDevice,
       
  1144 		const TDesC& aBody, TInt aCustomFormatType)
       
  1145 		: iDevice(aDevice)
       
  1146 		{
       
  1147 		iCustomFormatType = aCustomFormatType;
       
  1148 		iBody.Set(aBody.Ptr(), aBody.Length());
       
  1149 		iCurrent = &iBody;
       
  1150 		}
       
  1151 	void Close()
       
  1152 		{
       
  1153 		}
       
  1154 	TInt DocumentLength() const { return iCurrent->Length(); }
       
  1155 	MGraphicsDeviceMap& FormatDevice() const
       
  1156 		{
       
  1157 		return *iDevice;
       
  1158 		}
       
  1159 	TAny* GetExtendedInterface(const TUid& aInterfaceId)
       
  1160 		{
       
  1161 		if (aInterfaceId == KInlineTextApiExtensionUid)
       
  1162 			{
       
  1163 			return static_cast<MTmInlineTextSource*>(this);
       
  1164 			}
       
  1165 		else
       
  1166 			{
       
  1167 			// In this instance, calling the parent class will always return NULL
       
  1168 			// but the pattern should be followed by all implementors for safety
       
  1169 			return MTmSource::GetExtendedInterface(aInterfaceId);
       
  1170 			}
       
  1171 		}
       
  1172 	void GetParagraphFormatL(TInt aPos, RTmParFormat& aFormat) const
       
  1173 		{
       
  1174 		__ASSERT_ALWAYS(0 <= aPos, User::Invariant());
       
  1175 		__ASSERT_ALWAYS(aPos <= iCurrent->Length(), User::Invariant());
       
  1176 		const RTmParFormat f;
       
  1177 		aFormat.CopyL(f);
       
  1178 		}
       
  1179 	void GetText(TInt aPos,TPtrC& aText,TTmCharFormat& aFormat) const
       
  1180 		{
       
  1181 		ASSERT(0 <= aPos);
       
  1182 		ASSERT(aPos <= iCurrent->Length());
       
  1183 		aText.Set(iCurrent->Ptr() + aPos, iCurrent->Length() - aPos);
       
  1184 		TTmCharFormat f;
       
  1185 		aFormat = f;
       
  1186 		}
       
  1187 	MGraphicsDeviceMap& InterpretDevice() const
       
  1188 		{
       
  1189 		return *iDevice;
       
  1190 		}
       
  1191 	TInt ParagraphStart(TInt) const { return 0; }
       
  1192 	TRgb SystemColor(TUint aColorIndex,TRgb aDefaultColor) const
       
  1193 		{
       
  1194 		if (aColorIndex == TLogicalRgb::ESystemSelectionForegroundIndex)
       
  1195 			return KRgbWhite;
       
  1196 		if (aColorIndex == TLogicalRgb::ESystemSelectionBackgroundIndex)
       
  1197 			return KRgbRed;
       
  1198 		return MTmSource::SystemColor(aColorIndex, aDefaultColor);
       
  1199 		}
       
  1200 	TInt GetNextInlineTextPosition(const TTmDocPos& aFrom, TInt aMaxLength, TTmDocPos& aNext)
       
  1201 		{
       
  1202 		if (iCustomFormatType == 0)
       
  1203 			{
       
  1204 			return KErrNotFound;
       
  1205 			}
       
  1206 		else if (iCustomFormatType == 1)
       
  1207 			{
       
  1208 			_LIT(KCFS1, "EPOC");
       
  1209 			TInt from = aFrom.iPos;
       
  1210 			if (from < 4)
       
  1211 				from = 0;
       
  1212 			else
       
  1213 				{ // let's move back to look for the target string
       
  1214 				from -= (aFrom.iLeadingEdge ? 3 : 4); // adjustment takes care of not returning trailing edge if at start pos
       
  1215 				}
       
  1216 			TInt pos = iBody.Mid(from).Find(KCFS1);
       
  1217 			if (pos != KErrNotFound)
       
  1218 				{
       
  1219 				pos += from;
       
  1220 				aNext.iPos = pos + 4; // Adjust by length of string "EPOC"
       
  1221 				aNext.iLeadingEdge = EFalse;
       
  1222 				if (aNext.iPos - aFrom.iPos < aMaxLength + (aNext.iLeadingEdge ? 0 : 1))
       
  1223 					return KErrNotFound;
       
  1224 	 test.Printf(_L("GetPos-InlineTextAt-%d %c-From-%d\n"), aNext.iPos, aNext.iLeadingEdge ? 'L' : 'T', aFrom.iPos);
       
  1225 				return KErrNone;
       
  1226 				}
       
  1227 			return KErrNotFound;
       
  1228 			}
       
  1229 		else if (iCustomFormatType == 2)
       
  1230 			{
       
  1231 			_LIT(KCFS2, "(ABCDEFGHI)");
       
  1232 			TInt from = aFrom.iPos;
       
  1233 			if (from < 7)
       
  1234 				from = 0;
       
  1235 			else
       
  1236 				{ // let's move back to look for the target string
       
  1237 				from -= (aFrom.iLeadingEdge ? 6 : 7); // adjustment takes care of not returning trailing edge if at start pos
       
  1238 				}
       
  1239 			TInt pos = iBody.Mid(from).Find(KCFS2);
       
  1240 			if (pos != KErrNotFound)
       
  1241 				{
       
  1242 				pos += from;
       
  1243 				if (pos + 4 >= aFrom.iPos)
       
  1244 					{ // search position is before the first break space
       
  1245 					aNext.iPos = pos + 4; // adjust to position of first space
       
  1246 					aNext.iLeadingEdge = ETrue;
       
  1247 					if (aNext.iPos - aFrom.iPos < aMaxLength + (aNext.iLeadingEdge ? 0 : 1))
       
  1248 						return KErrNotFound;
       
  1249 	test.Printf(_L("GetPos-InlineTextAt-%d %c-From-%d\n"), aNext.iPos, aNext.iLeadingEdge ? 'L' : 'T', aFrom.iPos);
       
  1250 					return KErrNone;
       
  1251 					}
       
  1252 				// if it gets here search position is after the first break space
       
  1253 				if (pos + 7 >= aFrom.iPos)
       
  1254 					{ // but before the second
       
  1255 					aNext.iPos = pos + 7; // adjust to position of second space
       
  1256 					aNext.iLeadingEdge = EFalse;
       
  1257 					if (aNext.iPos - aFrom.iPos < aMaxLength + (aNext.iLeadingEdge ? 0 : 1))
       
  1258 						return KErrNotFound;
       
  1259 	test.Printf(_L("GetPos-InlineTextAt-%d %c-From-%d\n"), aNext.iPos, aNext.iLeadingEdge ? 'L' : 'T', aFrom.iPos);
       
  1260 					return KErrNone;
       
  1261 					}
       
  1262 				}
       
  1263 			return KErrNotFound;
       
  1264 			}
       
  1265 		return KErrNotFound;
       
  1266 		}
       
  1267 	TPtrC GetInlineText(const TTmDocPos& aAt)
       
  1268 		{
       
  1269 	test.Printf(_L("QueryTextAt-%d %c\n"), aAt.iPos, aAt.iLeadingEdge ? 'L' : 'T');
       
  1270 		if (iCustomFormatType == 0)
       
  1271 			{
       
  1272 			return iNullText;
       
  1273 			}
       
  1274 		else if (iCustomFormatType == 1)
       
  1275 			{
       
  1276 			_LIT(KCFS1, "EPOC");
       
  1277 			TInt at = aAt.iPos;
       
  1278 			if (at < 4)
       
  1279 				at = 0;
       
  1280 			else
       
  1281 				at -= 4; // let's move back to look for the target string
       
  1282 			TInt pos = iBody.Mid(at).Find(KCFS1);
       
  1283 			if (pos != KErrNotFound)
       
  1284 				{
       
  1285 				pos += at;
       
  1286 				if ((pos + 4 == aAt.iPos) && !aAt.iLeadingEdge)
       
  1287 					{
       
  1288 					_LIT(KCFS3, "?");
       
  1289 					TPtrC tPtrC(KCFS3);
       
  1290 	test.Printf(_L("GetText-QuestionMark-%d\n"), aAt.iPos);
       
  1291 					return tPtrC;
       
  1292 					}
       
  1293 				}
       
  1294 			return iNullText;
       
  1295 			}
       
  1296 		else if (iCustomFormatType == 2)
       
  1297 			{
       
  1298 			_LIT(KCFS2, "(ABCDEFGHI)");
       
  1299 			TInt at = aAt.iPos;
       
  1300 			if (at < 7)
       
  1301 				at = 0;
       
  1302 			else
       
  1303 				at -= 7; // let's move back to look for the target string
       
  1304 			TInt pos = iBody.Mid(at).Find(KCFS2);
       
  1305 			if (pos != KErrNotFound)
       
  1306 				{
       
  1307 				pos += at;
       
  1308 				if ((pos + 4 == aAt.iPos) && aAt.iLeadingEdge)
       
  1309 //				if ((pos + 4 == aAt.iPos) && !aAt.iLeadingEdge)
       
  1310 					{ // search position is on the first break space
       
  1311 					_LIT(KCFS4, " ");
       
  1312 					TPtrC tPtrC(KCFS4);
       
  1313 	test.Printf(_L("GetText-Space-%d-L\n"), aAt.iPos);
       
  1314 					return tPtrC;
       
  1315 					}
       
  1316 				// if it gets here search position is not on the first break space
       
  1317 				if ((pos + 7 == aAt.iPos) && !aAt.iLeadingEdge)
       
  1318 					{ // but it is on the second
       
  1319 					_LIT(KCFS4, " ");
       
  1320 					TPtrC tPtrC(KCFS4);
       
  1321 	test.Printf(_L("GetText-Space-%d-T\n"), aAt.iPos);
       
  1322 					return tPtrC;
       
  1323 					}
       
  1324 				}
       
  1325 			return iNullText;
       
  1326 			}
       
  1327 		return iNullText;
       
  1328 		}
       
  1329 	};
       
  1330 
       
  1331 void CTagmaImpTest::CustomFormattingL()
       
  1332 	{
       
  1333 	// Test implementation of CustomFormatting
       
  1334 	// ========
       
  1335 	// Test one
       
  1336 	// ========
       
  1337 	// First test is where inline text is enabled but where there is none to insert
       
  1338 	_LIT(KBody0, "This is a bunch of boring plain text that doesn't get any inline text inserted.\x2029");
       
  1339 	TTestCustomFormattingSource s0(iDevice, KBody0, 0);	// No inline text
       
  1340 	CTmTextLayout* lay0 = new(ELeave) CTmTextLayout;
       
  1341 	TTmFormatParam fp0;
       
  1342 	fp0.iWrapWidth = 200;
       
  1343 	fp0.iEndChar = KBody0().Length();
       
  1344 	lay0->SetTextL(s0, fp0);
       
  1345 	s0.Close();
       
  1346 	// ========
       
  1347 	// Test two
       
  1348 	// ========
       
  1349 	// Second test is where a single inline question mark will be inserted after the word EPOC
       
  1350 	_LIT(KBody1, "With luck the word EPOC will be followed by a question mark\x2029");
       
  1351 	TTestCustomFormattingSource s1(iDevice, KBody1, 1);	// No inline text
       
  1352 	CTmTextLayout* lay1 = new(ELeave) CTmTextLayout;
       
  1353 	TTmFormatParam fp1;
       
  1354 	fp1.iWrapWidth = 200;
       
  1355 	fp1.iEndChar = KBody1().Length();
       
  1356 	lay1->SetTextL(s1, fp1);
       
  1357 	s1.Close();
       
  1358 	// ==========
       
  1359 	// Test three
       
  1360 	// ==========
       
  1361 	// Third test looks for a pair of brackets separated by 9 chars and inserts spaces to
       
  1362 	// split them into three blocks of three chars
       
  1363 	_LIT(KBody2, "Take 9 chars inside brackets (ABCDEFGHI) and split by spaces into 3 x 3.\x2029");
       
  1364 	TTestCustomFormattingSource s2(iDevice, KBody2, 2);	// No inline text
       
  1365 	CTmTextLayout* lay2 = new(ELeave) CTmTextLayout;
       
  1366 	TTmFormatParam fp2;
       
  1367 	fp2.iWrapWidth = 200;
       
  1368 	fp2.iEndChar = KBody2().Length();
       
  1369 	lay2->SetTextL(s2, fp2);
       
  1370 	s2.Close();
       
  1371 	}
       
  1372 
       
  1373 
       
  1374 /**
       
  1375 @SYMTestCaseID 			SYSLIB-FORM-CT-3353
       
  1376 @SYMTestCaseDesc		Test Handling of ZWJ characters in latin text
       
  1377 @SYMTestPriority 		High
       
  1378 @SYMTestActions			Format some Latin strings with ZWJ characters and
       
  1379 						verify the formatted string and length of text.
       
  1380 @SYMTestExpectedResults	The formatted string should exclude the ZWJ character
       
  1381 						and the length of the string should equal the
       
  1382 						number of characters in the original string + 1.
       
  1383 						for the terminator.
       
  1384 						The formatting of the string must not cause a panic.
       
  1385 @SYMDEF PDEF101464
       
  1386  */
       
  1387 void CTagmaImpTest::PDEF_101464_DefectL()
       
  1388 {
       
  1389 	//Latin ZWJ example strings
       
  1390 	_LIT(KLatinZWJ1,"\x200D\x0061\x0062\x0063");
       
  1391 	_LIT(KLatinZWJ2,"\x0061\x0062\x200D\x0063");
       
  1392 	_LIT(KLatinZWJ3,"\x0061\x0062\x0063\x200D");
       
  1393 
       
  1394 	//Expected displayed result from Latin strings - ZJW has no effect
       
  1395 	_LIT(KDisplayedLatinZWJ,"\x0061\x0062\x0063");
       
  1396 	//Expected length is four characters plus terminator
       
  1397 	TInt KExpectedTextLength = 5;
       
  1398 
       
  1399 	CTmText *text = CTmText::NewL(*iDevice,KMaxTInt,FALSE);
       
  1400 	CleanupStack::PushL(text);
       
  1401 
       
  1402 	TBuf<32> buffer;
       
  1403 	TInt needed;
       
  1404 	TInt textLength;
       
  1405 
       
  1406 	//Test the sample text with ZWJ at the beginning of the string
       
  1407 	text->InsertL(0,KLatinZWJ1);
       
  1408 	text->GetDisplayedText(0,buffer,needed);
       
  1409 
       
  1410 	//Verify that the text is formatted correctly
       
  1411 	test(buffer == KDisplayedLatinZWJ);
       
  1412 
       
  1413 	//Verify that the length of the string is as expected
       
  1414 	textLength = (text->EndChar()) - (text->StartChar());
       
  1415 	test(textLength == KExpectedTextLength);
       
  1416 	text->Clear();
       
  1417 
       
  1418 	//Test the sample text with ZWJ in the middle of the string
       
  1419 	text->InsertL(0,KLatinZWJ2);
       
  1420 	text->GetDisplayedText(0,buffer,needed);
       
  1421 
       
  1422 	//Verify that the text is formatted correctly
       
  1423 	test(buffer == KDisplayedLatinZWJ);
       
  1424 
       
  1425 	//Verify that the length of the string is as expected
       
  1426 	textLength = (text->EndChar()) - (text->StartChar());
       
  1427 	test(textLength == KExpectedTextLength);
       
  1428 	text->Clear();
       
  1429 
       
  1430 	//Test the sample text with ZWJ at the end of the string
       
  1431 	text->InsertL(0,KLatinZWJ3);
       
  1432 	text->GetDisplayedText(0,buffer,needed);
       
  1433 
       
  1434 	//Verify that the text is formatted correctly
       
  1435 	test(buffer == KDisplayedLatinZWJ);
       
  1436 
       
  1437 	//Verify that the length of the string is as expected
       
  1438 	textLength = (text->EndChar()) - (text->StartChar());
       
  1439 	test(textLength == KExpectedTextLength);
       
  1440 	text->Clear();
       
  1441 
       
  1442 	CleanupStack::PopAndDestroy(); // text
       
  1443 }
       
  1444 
       
  1445 
       
  1446 
       
  1447 /**
       
  1448 @SYMTestCaseID 			SYSLIB-FORM-CT-3398
       
  1449 @SYMTestCaseDesc		Test Mapping Of Post Unicode 2.0 Characters
       
  1450 @SYMTestPriority 		High
       
  1451 @SYMTestActions			Format some Unicdoe 5.0 characters and test if they have
       
  1452 						been formatted
       
  1453 @SYMTestExpectedResults	The formatted string should include the Unicode 5.0 characters
       
  1454 @SYMDEF DEF101994
       
  1455  */
       
  1456 void CTagmaImpTest::DEF101994_DefectL()
       
  1457 {
       
  1458 	// Kannada and Tamil characters
       
  1459 	_LIT(KKannadaTamil,"\x0CBC\x0CBD\x0BB6\x0BE6\x0BF3\x0BF4\x0BF5\x0BF6\x0BF7\x0BF8\x0BF9\x0BFA");
       
  1460 	//Expected displayed result - all characters should be mapped and displayed
       
  1461 	_LIT(KDisplayedKannadaTamil,"\x0CBC\x0CBD\x0BB6\x0BE6\x0BF3\x0BF4\x0BF5\x0BF6\x0BF7\x0BF8\x0BF9\x0BFA");
       
  1462 	//Expected length is twelve characters plus terminator
       
  1463 	TInt KExpectedTextLength = 13;
       
  1464 
       
  1465 	CTmText *text = CTmText::NewL(*iDevice,KMaxTInt,FALSE);
       
  1466 	CleanupStack::PushL(text);
       
  1467 
       
  1468 	TBuf<32> buffer;
       
  1469 	TInt needed;
       
  1470 	TInt textLength;
       
  1471 
       
  1472 	//Test the sample text the Kananda and Tamil characters
       
  1473 	text->InsertL(0,KKannadaTamil);
       
  1474 	text->GetDisplayedText(0,buffer,needed);
       
  1475 
       
  1476 	//Verify that the text is formatted correctly
       
  1477 	test(buffer == KDisplayedKannadaTamil);
       
  1478 
       
  1479 	//Verify that the length of the string is as expected
       
  1480 	textLength = (text->EndChar()) - (text->StartChar());
       
  1481 	test(textLength == KExpectedTextLength);
       
  1482 	text->Clear();
       
  1483 
       
  1484 	CleanupStack::PopAndDestroy(); // text
       
  1485 }
       
  1486 
       
  1487 	/**
       
  1488 	@SYMTestCaseID 				SYSLIB-FORM-UT-4010
       
  1489 	@SYMTestCaseDesc 			Automated Form testing for Drawing Text with Context
       
  1490 	@SYMTestPriority 			High
       
  1491 	@SYMTestActions  			Format text and check the line context stored in chunks.
       
  1492 	@SYMTestExpectedResults 	Each chunk should contain the correct context based on the script used in the source text.
       
  1493 	@SYMPREQ 					1766: Support Bengali, Tamil and Telugu Scripts
       
  1494 	@SYMREQ 					854: Text I18N Drawing Latin Punctuation along the Indic text baseline
       
  1495 	*/
       
  1496 	void CTagmaImpTest::TestChunkContext()
       
  1497 		{
       
  1498 		TTmChunk chunk;
       
  1499 		TTmChunk::TInfo chunkInfo;
       
  1500 		
       
  1501 		// create a CTestSource containing the test data
       
  1502 		_LIT(KTest, "\x0915\x094d\x0915...abc.");
       
  1503 		TPtrC testSeg(KTest().Ptr(), KTest().Length() );
       
  1504 		CTestSource* source = NewTestSourceLC();
       
  1505 		source->SetText(testSeg);
       
  1506 		
       
  1507 		CTmCode* code = new(ELeave) CTmCode;
       
  1508 		CleanupStack::PushL(code);
       
  1509 		
       
  1510 		// format the text
       
  1511 		TTmFormatParam formatParam;
       
  1512 		formatParam.iStartChar = 0;
       
  1513 		formatParam.iEndChar = source->DocumentLength();
       
  1514 		formatParam.iLineInPar = 0;
       
  1515 		formatParam.iMaxHeight = KMaxTInt;
       
  1516 		formatParam.iMaxLines = KMaxTInt;
       
  1517 		formatParam.iFlags = TTmFormatParam::EWrap;
       
  1518 		formatParam.iWrapWidth = 533;
       
  1519 		CTmTextLayout* layout = new(ELeave) CTmTextLayout;
       
  1520 		CleanupStack::PushL(layout);
       
  1521 		
       
  1522 		CTmFormatContext* formatContext = new CTmFormatContext(*source, formatParam, *code, layout);
       
  1523 		CleanupStack::PushL(formatContext);
       
  1524 		
       
  1525 		chunk.SetL(*formatContext,0,0,10,533,0,chunkInfo);
       
  1526 		TUint context = chunk.iContextCharInByteCode;
       
  1527 		// Test that the first chunk's context has been recognised as not needing supplied context.
       
  1528 		test(0 == context);
       
  1529 		chunk.SetL(*formatContext,3,0,10,533,0,chunkInfo);
       
  1530 		context = chunk.iContextCharInByteCode;
       
  1531 		// Test that the next chunk retains the Hindi context.
       
  1532 		test(2325 == context);
       
  1533 		chunk.SetL(*formatContext,4,0,10,533,0,chunkInfo);
       
  1534 		context = chunk.iContextCharInByteCode;
       
  1535 		// Test that the next chunk retains the Hindi context.
       
  1536 		test(2325 == context);
       
  1537 		chunk.SetL(*formatContext,5,0,10,533,0,chunkInfo);
       
  1538 		context = chunk.iContextCharInByteCode;
       
  1539 		// Test that the next chunk retains the Hindi context.
       
  1540 		test(2325 == context);
       
  1541 		chunk.SetL(*formatContext,6,0,10,533,0,chunkInfo);
       
  1542 		context = chunk.iContextCharInByteCode;
       
  1543 		// Test that the next chunk has been recognised as not needing supplied context.
       
  1544 		test(0 == context);
       
  1545 		chunk.SetL(*formatContext,9,0,10,533,0,chunkInfo);
       
  1546 		context = chunk.iContextCharInByteCode;
       
  1547 		// Test that the next chunk retains the Latin context.
       
  1548 		test(99 == context);
       
  1549 		
       
  1550 		
       
  1551 		CleanupStack::PopAndDestroy(formatContext); // formatContext
       
  1552 		CleanupStack::PopAndDestroy(layout); // layout
       
  1553 		CleanupStack::PopAndDestroy(code);   // code
       
  1554 		CleanupStack::PopAndDestroy(source); // source
       
  1555 		}
       
  1556 	
       
  1557 	/**
       
  1558 	@SYMTestCaseID 				SYSLIB-FORM-UT-4011
       
  1559 	@SYMTestCaseDesc 			Automated Form testing for Drawing Text with Context
       
  1560 	@SYMTestPriority 			High
       
  1561 	@SYMTestActions  			Format text and check the line context from the generated bytecode.
       
  1562 	@SYMTestExpectedResults 	The bytecode should contain the correct context based on the script used in the source text.
       
  1563 	@SYMPREQ 					1766: Support Bengali, Tamil and Telugu Scripts
       
  1564 	@SYMREQ 					854: Text I18N Drawing Latin Punctuation along the Indic text baseline
       
  1565 	*/
       
  1566 	void CTagmaImpTest::TestBytecodeLineContext()
       
  1567 		{
       
  1568 		// create a CTestSource containing the test data
       
  1569 		_LIT(KTest, "abcdefghij..........\x0915\x0915\x0915\x0915\x0915\x0915\x0915\x0915\x0915\x0915..........");
       
  1570 		
       
  1571 		TPtrC testSeg(KTest().Ptr(), KTest().Length());
       
  1572 		CTestSource* source = NewTestSourceLC();
       
  1573 		source->SetText(testSeg);
       
  1574 		CTmCode* code = new(ELeave) CTmCode;
       
  1575 		CleanupStack::PushL(code);
       
  1576 		
       
  1577 		// Format the text.
       
  1578 		CTmFormatContext::TInfo info;
       
  1579 		TTmFormatParam formatParam;
       
  1580 		formatParam.iStartChar = 0;
       
  1581 		formatParam.iEndChar = source->DocumentLength();
       
  1582 		formatParam.iLineInPar = 0;
       
  1583 		formatParam.iMaxHeight = KMaxTInt;
       
  1584 		formatParam.iMaxLines = KMaxTInt;
       
  1585 		formatParam.iFlags = TTmFormatParam::EWrap;
       
  1586 		formatParam.iWrapWidth = 100;
       
  1587 		CTmTextLayout* layout = new(ELeave) CTmTextLayout;
       
  1588 		CleanupStack::PushL(layout);
       
  1589 		CTmFormatContext::FormatL(*source, formatParam, *code, info, layout);
       
  1590 		
       
  1591 		// Set up the interpreter.
       
  1592 		TTmInterpreterParam interpreter_param(*code);
       
  1593 		interpreter_param.iCodeStart = 0;
       
  1594 		interpreter_param.iCodeEnd = code->Size();
       
  1595 		interpreter_param.iTextStart = 0;
       
  1596 		interpreter_param.iWidth = 50;
       
  1597 		RTmGeneralInterpreter interpreter(*source, interpreter_param);
       
  1598 		
       
  1599 		// Expected context per line.
       
  1600 		TInt expectedResults[] = {106, 106, 2325, 2325};
       
  1601 		TInt lines = 0;
       
  1602 		
       
  1603 		// Iterate through lines in bytecode and check the context.
       
  1604 		while (interpreter.Next())
       
  1605 			{
       
  1606 			if (interpreter.Op() == TTmInterpreter::EOpLine)
       
  1607 				{
       
  1608 				test(interpreter.LineContextCharChar() == expectedResults[lines++]);
       
  1609 				}
       
  1610 			interpreter.Skip();
       
  1611 			}
       
  1612 		
       
  1613 		// Test the correct amount of lines have been tested.
       
  1614 		test(4 == lines);
       
  1615 		
       
  1616 		// Close the interpreter and clean up the heap.
       
  1617 		interpreter.Close();
       
  1618 		CleanupStack::PopAndDestroy(layout); // layout
       
  1619 		CleanupStack::PopAndDestroy(code);   // code
       
  1620 		CleanupStack::PopAndDestroy(source); // source
       
  1621 		}
       
  1622 		
       
  1623 	
       
  1624 	/**
       
  1625 	@SYMTestCaseID 				SYSLIB-FORM-UT-4012
       
  1626 	@SYMTestCaseDesc 			Automated Form testing for Drawing Text with Context
       
  1627 	@SYMTestPriority 			High
       
  1628 	@SYMTestActions  			Format text and check the chunk context from the generated bytecode.
       
  1629 	@SYMTestExpectedResults 	Chunks within the bytecode should contain the correct context based on the script used in the source text.
       
  1630 	@SYMPREQ 					1766: Support Bengali, Tamil and Telugu Scripts
       
  1631 	@SYMREQ 					854: Text I18N Drawing Latin Punctuation along the Indic text baseline
       
  1632 	*/
       
  1633 	void CTagmaImpTest::TestBytecodeChunkContext()
       
  1634 		{
       
  1635 		// create a CTestSource containing the test data.
       
  1636 		_LIT(KTest, "a. b\x915.c. \x916.d \x917. chunk");
       
  1637 		TPtrC testSeg(KTest().Ptr(), KTest().Length());
       
  1638 		CTestSource* source = NewTestSourceLC();
       
  1639 		source->SetText(testSeg);
       
  1640 		
       
  1641 		// Create a bytecode object.
       
  1642 		CTmCode* code = new(ELeave) CTmCode;
       
  1643 		CleanupStack::PushL(code);
       
  1644 		
       
  1645 		// Format the text.
       
  1646 		CTmFormatContext::TInfo info;
       
  1647 		TTmFormatParam formatParam;
       
  1648 		formatParam.iStartChar = 0;
       
  1649 		formatParam.iEndChar = source->DocumentLength();
       
  1650 		formatParam.iLineInPar = 0;
       
  1651 		formatParam.iMaxHeight = KMaxTInt;
       
  1652 		formatParam.iMaxLines = KMaxTInt;
       
  1653 		formatParam.iFlags = TTmFormatParam::EWrap;
       
  1654 		formatParam.iWrapWidth = KMaxTInt;
       
  1655 		CTmTextLayout* layout = new(ELeave) CTmTextLayout;
       
  1656 		CleanupStack::PushL(layout);
       
  1657 		CTmFormatContext::FormatL(*source, formatParam, *code, info, layout);
       
  1658 		
       
  1659 		// Set up the interpreter.
       
  1660 		TTmInterpreterParam interpreter_param(*code);
       
  1661 		interpreter_param.iCodeStart = 0;
       
  1662 		interpreter_param.iCodeEnd = code->Size();
       
  1663 		interpreter_param.iTextStart = 0;
       
  1664 		interpreter_param.iWidth = KMaxTInt;
       
  1665 		RTmGeneralInterpreter interpreter(*source, interpreter_param);		
       
  1666 		
       
  1667 		// Expected context per chunk.
       
  1668 		TInt expectedResults[] = {0, 2325, 0};
       
  1669 		TInt chunks = 0;
       
  1670 
       
  1671 		// Make sure we're starting at the begining.
       
  1672 		TBool found = interpreter.LineNumberToLine(0);
       
  1673 		
       
  1674 		// Iterate through the chunks, testing context.
       
  1675 		while (interpreter.Next() && interpreter.Op() != TTmInterpreter::EOpLine)
       
  1676 			{
       
  1677 			TUint32 op = interpreter.Op();
       
  1678 			if (interpreter.Op() == TTmInterpreter::EOpText || interpreter.Op() == TTmInterpreter::EOpSpecialChar)
       
  1679 				{
       
  1680 				test(expectedResults[chunks++] == interpreter.ContextCharChar());
       
  1681 				}
       
  1682 			else
       
  1683 				{
       
  1684 				interpreter.Skip();
       
  1685 				}
       
  1686 			}
       
  1687 		
       
  1688 		// Test that the expected number of chunks were found in the bytecode.
       
  1689 		test(3 == chunks);
       
  1690 		
       
  1691 		// Close the interpreter and clean up the heap.
       
  1692 		interpreter.Close();
       
  1693 		CleanupStack::PopAndDestroy(layout); // layout
       
  1694 		CleanupStack::PopAndDestroy(code);   // code
       
  1695 		CleanupStack::PopAndDestroy(source); // source
       
  1696 		}
       
  1697 
       
  1698 void CTagmaImpTest::TestL()
       
  1699 	{
       
  1700 //	__UHEAP_MARK;
       
  1701 
       
  1702 	test.Start(_L("Regression test: DEF073838")); // Line break problem with WORD
       
  1703 	DEF_073838_DefectL();
       
  1704 
       
  1705 	test.Next(_L("Regression test: INC044969"));
       
  1706 	INC_044969_DefectL();
       
  1707 
       
  1708 	test.Next(_L("CTmTextImp::RRunArray tests"));
       
  1709 	CTmTextImp_RRunArrayL();
       
  1710 
       
  1711 	test.Next(_L("Regression test: BUR-58FGE8"));
       
  1712 	BUR_58FGE8_DefectL();
       
  1713 
       
  1714 	test.Next(_L("Regression test: WEP-55BHBF"));
       
  1715 	WEP_55BHBF_DefectL();
       
  1716 
       
  1717 	test.Next(_L("Regression test: EXT-5ATF8D"));
       
  1718 	EXT_5ATF8D_DefectL();
       
  1719 
       
  1720 	test.Next(_L(" @SYMTestCaseID:SYSLIB-FORM-UT-1886 Test for CTmTextImp API's "));
       
  1721 	TestAPIL();
       
  1722 
       
  1723 	test.Next(_L("CTmCode tests"));
       
  1724 	CTmCodeOOML();
       
  1725 
       
  1726 	test.Next(_L("CTmFormatContext::FormatL tests"));
       
  1727 	FormatOOML();
       
  1728 
       
  1729 	test.Next(_L("RTmTextCache::Width tests"));
       
  1730 	RTmTextCacheWidthOOM();
       
  1731 
       
  1732 	test.Next(_L("RTmGeneralInterpreter::GetDisplayedText tests"));
       
  1733 	RTmGeneralInterpreterGetDisplayedTextOOM();
       
  1734 
       
  1735 	test.Next(_L("Bidirectional alignment tests"));
       
  1736 	CTmTextImp_BidirectionalAlignmentL();
       
  1737 
       
  1738 	test.Next(_L("Custom formatting tests"));
       
  1739 	CustomFormattingL();
       
  1740 
       
  1741 	test.Next(_L(" @SYMTestCaseID:SYSLIB-FORM-CT-3353 Regression test: PDEF101464 "));
       
  1742 	PDEF_101464_DefectL();
       
  1743 
       
  1744 	test.Next(_L(" @SYMTestCaseID:SYSLIB-FORM-CT-3398 Regression test: DEF101994 "));
       
  1745 	DEF101994_DefectL();
       
  1746 	
       
  1747 	test.Next(_L(" @SYMTestCaseID:SYSLIB-FORM-UT-4010 Drawing Text within context: Testing chunk context."));
       
  1748 	TestChunkContext();
       
  1749 	
       
  1750 	test.Next(_L(" @SYMTestCaseID:SYSLIB-FORM-UT-4011 Drawing Text within context: Testing line context within bytecode."));
       
  1751 	TestBytecodeLineContext();
       
  1752 	
       
  1753 	test.Next(_L(" @SYMTestCaseID:SYSLIB-FORM-UT-4012 Drawing Text within context: Testing chunk context within bytecode."));
       
  1754 	TestBytecodeChunkContext();
       
  1755 	
       
  1756 	test.End(); 
       
  1757 	
       
  1758 //	__UHEAP_MARKEND;
       
  1759 	}
       
  1760 
       
  1761 
       
  1762 void RunTestsL()
       
  1763 	{
       
  1764 	CTagmaImpTest* t = new(ELeave) CTagmaImpTest();
       
  1765 	CleanupStack::PushL(t);
       
  1766 	t->ConstructL();
       
  1767 	t->TestL();
       
  1768 	CleanupStack::PopAndDestroy(t);
       
  1769 	}
       
  1770 
       
  1771 TInt E32Main()
       
  1772 	{
       
  1773 	CTrapCleanup* theCleanup =CTrapCleanup::New();
       
  1774 	test.Title();
       
  1775 	TRAPD(err, RunTestsL());
       
  1776 	test.Close();
       
  1777 	delete theCleanup;
       
  1778 	return err;
       
  1779 	}