os/textandloc/textrendering/textformatting/test/src/TInlineText.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/textandloc/textrendering/textformatting/test/src/TInlineText.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,1496 @@
     1.4 +/*
     1.5 +* Copyright (c) 2004-2010 Nokia Corporation and/or its subsidiary(-ies).
     1.6 +* All rights reserved.
     1.7 +* This component and the accompanying materials are made available
     1.8 +* under the terms of "Eclipse Public License v1.0"
     1.9 +* which accompanies this distribution, and is available
    1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.11 +*
    1.12 +* Initial Contributors:
    1.13 +* Nokia Corporation - initial contribution.
    1.14 +*
    1.15 +* Contributors:
    1.16 +*
    1.17 +* Description: 
    1.18 +*
    1.19 +*/
    1.20 +
    1.21 +//#include "TCustomWrap.h"
    1.22 +#include "TGraphicsContext.h"
    1.23 +#include <e32std.h>
    1.24 +#include <e32test.h>
    1.25 +#include <frmtlay.h>
    1.26 +#include <frmtview.h>
    1.27 +#include <txtlaydc.h>
    1.28 +#include <fbs.h>
    1.29 +#include <w32std.h>
    1.30 +#include <inlinetext.h>
    1.31 +#include "tinlinetext.h"
    1.32 +
    1.33 +namespace LocalToTInlineText
    1.34 +{
    1.35 +
    1.36 +_LIT(KTInlineText, "TInlineText");
    1.37 +const TInt KDisplayWidthWide = 202;
    1.38 +const TInt KDisplayWidthThin = 102;
    1.39 +const TInt KDisplayHeight = 100;
    1.40 +const TInt KPictureCharacter = 0xFFFC;
    1.41 +
    1.42 +CTInLineTextStep* TestStep = NULL;
    1.43 +#define TESTPOINT(p) TestStep->testpoint(p,(TText8*)__FILE__,__LINE__)
    1.44 +#define TESTPRINT(p) TestStep->print(p,(TText8*)__FILE__,__LINE__)
    1.45 +
    1.46 +
    1.47 +enum TInlineTextPanic { EAccessOutsideText = 1 };
    1.48 +void Panic(TInlineTextPanic)
    1.49 +    {
    1.50 +    User::Panic(_L("TInlineText"), EAccessOutsideText);
    1.51 +    }
    1.52 +
    1.53 +class CPinkSquare : public CPicture
    1.54 +	{
    1.55 +public:
    1.56 +	// Size of square in twips.
    1.57 +	// 600 is 15 pixels using the standard test graphics device at
    1.58 +	// its default resolution.
    1.59 +	enum { KWidth = 600, KHeight = 600 };
    1.60 +	CPinkSquare()
    1.61 +		{}
    1.62 +	void Draw(CGraphicsContext& aGc, const TPoint& aTopLeft, const TRect& aClipRect, MGraphicsDeviceMap* aMap) const
    1.63 +		{
    1.64 +		// This picture is a magenta square
    1.65 +		TPoint size(KWidth, KHeight);
    1.66 +		if (aMap)
    1.67 +			size = aMap->TwipsToPixels(size);
    1.68 +		TRect rect(aTopLeft, aTopLeft + size);
    1.69 +		aGc.SetClippingRect(aClipRect);
    1.70 +		aGc.SetDrawMode(CGraphicsContext::EDrawModePEN);
    1.71 +		aGc.SetPenColor(KRgbMagenta);
    1.72 +		aGc.SetBrushStyle(CGraphicsContext::ESolidBrush);
    1.73 +		aGc.SetBrushColor(KRgbMagenta);
    1.74 +		aGc.DrawRect(rect);
    1.75 +		}
    1.76 +	void ExternalizeL(RWriteStream&) const
    1.77 +		{}
    1.78 +	void GetOriginalSizeInTwips(TSize& a) const
    1.79 +		{
    1.80 +		a.iWidth = CPinkSquare::KWidth;
    1.81 +		a.iHeight = CPinkSquare::KHeight;
    1.82 +		}
    1.83 +	};
    1.84 +
    1.85 +_LIT(KEnd, "\x2029");
    1.86 +class TDocModel : public MLayDoc
    1.87 +	{
    1.88 +public:
    1.89 +	TDocModel(const TDesC& aDes)
    1.90 +	 :	iDes(&aDes), iParagraphFormat(0)
    1.91 +		{}
    1.92 +	void SetParagraphFormat(CParaFormat* a)
    1.93 +		{
    1.94 +		iParagraphFormat = a;
    1.95 +		}
    1.96 +	// From MLayDoc
    1.97 +	TInt LdDocumentLength() const
    1.98 +		{ return iDes->Length(); }
    1.99 +	TInt LdToParagraphStart(TInt& a) const
   1.100 +		{
   1.101 +		TInt curr = a;
   1.102 +		if (a < LdDocumentLength())
   1.103 +			{
   1.104 +			a = iDes->Left(a).LocateReverse(0x2029);
   1.105 +			a = a < 0? 0 : a + 1;
   1.106 +			}
   1.107 +		return curr - a;
   1.108 +		}
   1.109 +	void GetParagraphFormatL(CParaFormat* aFormat, TInt) const
   1.110 +		{
   1.111 +		if (iParagraphFormat)
   1.112 +			{
   1.113 +			aFormat->CopyL(*iParagraphFormat);
   1.114 +			return;
   1.115 +			}
   1.116 +		aFormat->Reset();
   1.117 +		TTabStop tabStop;
   1.118 +		tabStop.iTwipsPosition = 1000;
   1.119 +		tabStop.iType = TTabStop::ELeftTab;
   1.120 +		aFormat->StoreTabL(tabStop);
   1.121 +		}
   1.122 +	void GetChars(TPtrC& aView,TCharFormat& aFormat, TInt aStartPos)const
   1.123 +		{
   1.124 +        __ASSERT_ALWAYS(aStartPos <= LdDocumentLength(), Panic(EAccessOutsideText));
   1.125 +        __ASSERT_ALWAYS(aStartPos >= 0, Panic(EAccessOutsideText));
   1.126 +        
   1.127 +		TCharFormat cf;
   1.128 +		aFormat = cf;
   1.129 +		if (aStartPos == LdDocumentLength())
   1.130 +			aView.Set(KEnd);
   1.131 +		else
   1.132 +			aView.Set(iDes->Mid(aStartPos));
   1.133 +		}
   1.134 +	TInt GetPictureSizeInTwips(TSize& aSize, TInt aPos) const
   1.135 +		{
   1.136 +		if ((*iDes)[aPos] != KPictureCharacter)
   1.137 +			return KErrNotFound;
   1.138 +		aSize.iWidth = CPinkSquare::KWidth;
   1.139 +		aSize.iHeight = CPinkSquare::KHeight;
   1.140 +		return KErrNone;
   1.141 +		}
   1.142 +	CPicture* PictureHandleL(TInt aPos, TForcePictureLoad) const
   1.143 +		{
   1.144 +		if ((*iDes)[aPos] != KPictureCharacter)
   1.145 +			return 0;
   1.146 +		return new(ELeave) CPinkSquare;
   1.147 +		}
   1.148 +	TBool EnquirePageBreak(TInt aPos, TInt aLength)const
   1.149 +		{
   1.150 +		return iDes->Mid(aPos, aLength).Locate(0x000C) < 0?
   1.151 +			EFalse : ETrue;
   1.152 +		}
   1.153 +	TBool SelectParagraphLabel(TInt)
   1.154 +		{ return EFalse; }
   1.155 +	void CancelSelectLabel()
   1.156 +		{}
   1.157 +private:
   1.158 +	const TDesC* iDes;
   1.159 +	CParaFormat* iParagraphFormat;
   1.160 +	};
   1.161 +}
   1.162 +using namespace LocalToTInlineText;
   1.163 +
   1.164 +class CTestTextView	// slightly naughty
   1.165 +	{
   1.166 +public:
   1.167 +	static void SetContextForFlickerFreeRedraw(CTextView* aView, CBitmapContext* aContext)
   1.168 +		{
   1.169 +		aView->iOffScreenContext = aContext;
   1.170 +		}
   1.171 +	};
   1.172 +
   1.173 +// Utility functions to show contents of test data using test.Printf
   1.174 +
   1.175 +_LIT(KAddressMarker, "> ");
   1.176 +_LIT(KSpace, " ");
   1.177 +_LIT(KLength, ", Length of Data = %d 16-bit words\r\n");
   1.178 +_LIT(KSpaces, "                                                                      ");
   1.179 +_LIT(KPeriod, ".");
   1.180 +_LIT(KSingleString, "%S\r\n");
   1.181 +//_LIT(KDoubleString, "%s <%s>\r\n");
   1.182 +//_LIT(KLinefeed, "\r\n");
   1.183 +
   1.184 +void PrintTestData (const TDesC& aTitle , const TDesC16& aData)
   1.185 +	{
   1.186 +
   1.187 +	TInt i;
   1.188 +	TInt j;
   1.189 +	TInt end;
   1.190 +
   1.191 +	TInt length = aData.Length();
   1.192 +
   1.193 +	TBuf<80> buffer;
   1.194 +
   1.195 +	buffer.Zero();
   1.196 +	buffer.Append(aTitle);
   1.197 +	buffer.Append(KLength);
   1.198 +
   1.199 +	TBuf<256> buf;
   1.200 +	buf.AppendFormat(buffer, length);
   1.201 +	TESTPRINT(buf);
   1.202 +
   1.203 +	for (i = 0 ; i < length ; i += 8)
   1.204 +		{
   1.205 +		buffer.Zero();
   1.206 +		buffer.AppendNumFixedWidth(i, EHex, 8);
   1.207 +		buffer += KAddressMarker;
   1.208 +
   1.209 +		end = ((length-i) >= 8) ? i+8 : length;
   1.210 +
   1.211 +		for (j = i ; j < end ; ++j)
   1.212 +			{
   1.213 +			buffer.AppendNumFixedWidth(aData[j], EHex, 4);
   1.214 +			buffer += KSpace;
   1.215 +			}
   1.216 +		buffer += TPtrC(KSpaces().Ptr(), ((8-(j-i))*5)+4);
   1.217 +
   1.218 +		for (j = i ; j < end ; ++j)
   1.219 +			{
   1.220 +			if (aData[j] >= 32)
   1.221 +				{
   1.222 +				buffer.Append(aData[j]);
   1.223 +				}
   1.224 +			else
   1.225 +				{
   1.226 +				buffer += KPeriod;
   1.227 +				}
   1.228 +			}
   1.229 +		buffer.ZeroTerminate();
   1.230 +		buf.Zero();
   1.231 +		buf.AppendFormat(KSingleString,buffer.Ptr());
   1.232 +		TESTPRINT(buf);		
   1.233 +		}
   1.234 +
   1.235 +	}
   1.236 +
   1.237 +void PrintTestData(const TDesC& aTitle, const TText16* aDataBuffer, const TInt aSize)
   1.238 +	{
   1.239 +	PrintTestData(aTitle, TPtrC16(aDataBuffer, aSize));
   1.240 +	}
   1.241 +
   1.242 +class CTestInlineTextSource : public CBase, public MTmInlineTextSource
   1.243 +	{
   1.244 +public:
   1.245 +	static CTestInlineTextSource* NewL(TPtrC aText, TInt aNumChar);
   1.246 +	~CTestInlineTextSource();
   1.247 +
   1.248 +public: // From MTmInlineTextSource
   1.249 +
   1.250 +	/**
   1.251 +	Reports the next position into which inline text should be inserted
   1.252 +	@param aFrom
   1.253 +		The document position and character edge to start from.
   1.254 +	@param aMaxLength
   1.255 +		The maximum length within which to report inline text.
   1.256 +		It means that inline text at position X should be reported if
   1.257 +		aFrom <= X && X < aFrom + aMaxLength.
   1.258 +		Also report trailing inline text at position aFrom + aMaxLength
   1.259 +		because it is really attached to the preceding character.
   1.260 +		Always report only the first inline text position >= aFrom.
   1.261 +	@param aNext
   1.262 +		On exit the position of the next bit of inline text to be inserted.
   1.263 +		N.B. The position of trailing text following position N and the
   1.264 +		position of leading text preceding position N+1 are both
   1.265 +		considered to be N+1 - and the trailing text comes first so if
   1.266 +		aFrom specifies a leading edge do not report trailing edge
   1.267 +		inline text unless its position is greater than aFrom.
   1.268 +		A panic EBadReturnValue will result otherwise.
   1.269 +	@return
   1.270 +		KErrNone if a position is found within the specified range,
   1.271 +		KErrNotFound otherwise.
   1.272 +	@post
   1.273 +		if KErrNone returned then aFrom <= aNext
   1.274 +		&& GetInlineText(aNext).Length() != 0
   1.275 +		&& (GetInlineText(X).Length() == 0 for all
   1.276 +		TTmDocPos X such that aFrom < X && X < aNext)
   1.277 +		else if KErrNotFound returned
   1.278 +		GetInlineText(X).Length() == 0 for all
   1.279 +		TTmDocPos X such that aFrom <= X && X < aFrom + aMaxLength
   1.280 +	*/
   1.281 +	virtual TInt GetNextInlineTextPosition(const TTmDocPos& aFrom, TInt aMaxLength, TTmDocPos& aNext);
   1.282 +
   1.283 +	/**
   1.284 +	Gets a view of the text to be inserted at aAt.
   1.285 +	@param aAt
   1.286 +		Document position, including character edge, being queried.
   1.287 +	@return
   1.288 +		Any inline text that should be attached to the specified character edge at aAt.
   1.289 +	*/
   1.290 +	virtual TPtrC GetInlineText(const TTmDocPos& aAt);
   1.291 +
   1.292 +private:
   1.293 +	CTestInlineTextSource();
   1.294 +	void Construct(TPtrC aText, TInt aNumChar);
   1.295 +	TPtrC iNullText;
   1.296 +	TPtrC iText;
   1.297 +	TInt iNumChar;
   1.298 +	};
   1.299 +
   1.300 +CTestInlineTextSource::CTestInlineTextSource()
   1.301 +	{
   1.302 +	}
   1.303 +
   1.304 +CTestInlineTextSource* CTestInlineTextSource::NewL(TPtrC aText, TInt aNumChar)
   1.305 +	{
   1.306 +	CTestInlineTextSource* self= new(ELeave) CTestInlineTextSource();
   1.307 +	self->Construct(aText, aNumChar);
   1.308 +	return self;
   1.309 +	}
   1.310 +
   1.311 +CTestInlineTextSource::~CTestInlineTextSource()
   1.312 +	{
   1.313 +	}
   1.314 +
   1.315 +void CTestInlineTextSource::Construct(TPtrC aText, TInt aNumChar)
   1.316 +	{
   1.317 +	iText.Set(aText);
   1.318 +	iNumChar = aNumChar;
   1.319 +	}
   1.320 +
   1.321 +// This takes two inputs, each of which is either a real position,
   1.322 +// greater than or equal to 0, or KErrNotFound. If both are real
   1.323 +// positions then it should return the lower. If one is a real position
   1.324 +// then it should be returned. If neither are a real position then
   1.325 +// KErrNone is returned. It is all done with pointers to TInts so that
   1.326 +// when I get the result I can tell which one it is.
   1.327 +TInt* CustomMin(TInt* aPtrPos1, TInt* aPtrPos2)
   1.328 +	{
   1.329 +	if (*aPtrPos2 == KErrNotFound)
   1.330 +		return aPtrPos1;
   1.331 +	if (*aPtrPos1 == KErrNotFound)
   1.332 +		return aPtrPos2;
   1.333 +	if (*aPtrPos1 <= *aPtrPos2)
   1.334 +		return aPtrPos1;
   1.335 +	else
   1.336 +		return aPtrPos2;
   1.337 +	}
   1.338 +
   1.339 +TInt CTestInlineTextSource::GetNextInlineTextPosition(const TTmDocPos& aFrom, TInt aMaxLength, TTmDocPos& aNext)
   1.340 +	{
   1.341 +	if (iNumChar == 0)
   1.342 +		return KErrNotFound;
   1.343 +	_LIT(KSS1, "A");
   1.344 +	_LIT(KSS2, "B");
   1.345 +    _LIT(KSS3, "C");
   1.346 +    _LIT(KSS4, "\x05c0");//Hebrew character to test right-to-left text
   1.347 +	TInt from = aFrom.iPos;
   1.348 +	TInt from2 = from;
   1.349 +	if ((from > 0) && (!aFrom.iLeadingEdge))
   1.350 +		from2--; // adjustment takes care of not returning trailing edge if at start pos
   1.351 +	TInt pos1 = iText.Mid(from).Find(KSS1);
   1.352 +	TInt pos2 = iText.Mid(from2).Find(KSS2);
   1.353 +	TInt pos3 = iText.Mid(from).Find(KSS3);
   1.354 +    TInt pos4 = iText.Mid(from2).Find(KSS3);
   1.355 +    TInt pos5 = iText.Mid(from2).Find(KSS4);
   1.356 +	if (pos1 >= 0 ) // adjustments so we compare like for like
   1.357 +		pos1 += from - from2;
   1.358 +	if (pos3 >= 0 )
   1.359 +		pos3 += from - from2;
   1.360 +	// get the smallest real position, if any
   1.361 +	TInt* ptrPos = CustomMin(CustomMin(&pos1, &pos3), CustomMin(CustomMin(&pos2, &pos4),&pos5));
   1.362 +	if (pos1 > 0 ) // now adjust back
   1.363 +		pos1 -= from - from2;
   1.364 +	if (pos3 > 0 )
   1.365 +		pos3 -= from - from2;
   1.366 +	if (*ptrPos == KErrNotFound)
   1.367 +		return KErrNotFound;
   1.368 +	if ((ptrPos == &pos1) || (ptrPos == &pos3))
   1.369 +		{ // it was an A or C with leading text
   1.370 +		aNext.iPos = *ptrPos + from;
   1.371 +		aNext.iLeadingEdge = ETrue;
   1.372 +		}
   1.373 +	else if ((ptrPos == &pos2) || (ptrPos == &pos4))
   1.374 +		{ // it was an B oD with trailing text
   1.375 +		aNext.iPos = *ptrPos + from2 + 1;
   1.376 +		aNext.iLeadingEdge = EFalse;
   1.377 +		}
   1.378 +    else if (ptrPos == &pos5)
   1.379 +        { // it was an Hebrew char with trailing text
   1.380 +        aNext.iPos = *ptrPos + from2 + 1;
   1.381 +        aNext.iLeadingEdge = EFalse;
   1.382 +        }
   1.383 +	else
   1.384 +		{
   1.385 +		// something has gone horribly wrong
   1.386 +		return KErrNotFound;
   1.387 +		}
   1.388 +	if (aNext.iPos - aFrom.iPos > aMaxLength + (aNext.iLeadingEdge ? 0 : 1))
   1.389 +		return KErrNotFound;
   1.390 +	return KErrNone;
   1.391 +	}
   1.392 +
   1.393 +TPtrC CTestInlineTextSource::GetInlineText(const TTmDocPos& aAt)
   1.394 +	{
   1.395 +	if (iNumChar == 0)
   1.396 +		return iNullText;
   1.397 +	if ((aAt.iPos == 0) && (!aAt.iLeadingEdge))
   1.398 +		return iNullText;
   1.399 +	_LIT(KSS1, "A");
   1.400 +	_LIT(KSS2, "B");
   1.401 +	_LIT(KSS3, "C");
   1.402 +    _LIT(KSS4, "\x05c0");//Hebrew character to test right-to-left text
   1.403 +	TInt at = aAt.iPos;
   1.404 +	TInt at2 = at;
   1.405 +	if ((at2 > 0) && (!aAt.iLeadingEdge))
   1.406 +		at2--; // adjustment takes care of not returning trailing edge if at start pos
   1.407 +
   1.408 +	TInt pos1 = iText.Mid(at).Find(KSS1);
   1.409 +	TInt pos2 = iText.Mid(at2).Find(KSS2);
   1.410 +	TInt pos3 = iText.Mid(at).Find(KSS3);
   1.411 +	TInt pos4 = iText.Mid(at2).Find(KSS3);
   1.412 +    TInt pos5 = iText.Mid(at2).Find(KSS4);
   1.413 +	if (pos1 == 0)
   1.414 +		{
   1.415 +		pos1 += at;
   1.416 +		if ((pos1 == aAt.iPos) && aAt.iLeadingEdge)
   1.417 +			{
   1.418 +			TPtrC tPtrC;
   1.419 +			if (iNumChar == 1)
   1.420 +				{
   1.421 +				_LIT(KIS11, "a");
   1.422 +				tPtrC.Set(KIS11);
   1.423 +				}
   1.424 +			else if (iNumChar == 2)
   1.425 +				{
   1.426 +				_LIT(KIS12, "aa");
   1.427 +				tPtrC.Set(KIS12);
   1.428 +				}
   1.429 +			return tPtrC;
   1.430 +			}
   1.431 +		}
   1.432 +	if (pos2 == 0)
   1.433 +		{
   1.434 +		pos2 += at2;
   1.435 +		if ((pos2 + 1 == aAt.iPos) && !aAt.iLeadingEdge)
   1.436 +			{
   1.437 +			TPtrC tPtrC;
   1.438 +			if (iNumChar == 1)
   1.439 +				{
   1.440 +				_LIT(KIS21, "b");
   1.441 +				tPtrC.Set(KIS21);
   1.442 +				}
   1.443 +			else if (iNumChar == 2)
   1.444 +				{
   1.445 +				_LIT(KIS22, "bb");
   1.446 +				tPtrC.Set(KIS22);
   1.447 +				}
   1.448 +			return tPtrC;
   1.449 +			}
   1.450 +		}
   1.451 +	if ((pos3 == 0) || (pos4 == 0))
   1.452 +		{
   1.453 +		if (((pos3 + at == aAt.iPos) && aAt.iLeadingEdge) || ((pos4 + at2 + 1 == aAt.iPos) && !aAt.iLeadingEdge))
   1.454 +			{
   1.455 +			TPtrC tPtrC;
   1.456 +			if (iNumChar == 1)
   1.457 +				{
   1.458 +				_LIT(KIS31, "c");
   1.459 +				tPtrC.Set(KIS31);
   1.460 +				}
   1.461 +			else if (iNumChar == 2)
   1.462 +				{
   1.463 +				_LIT(KIS32, "cc");
   1.464 +				tPtrC.Set(KIS32);
   1.465 +				}
   1.466 +			return tPtrC;
   1.467 +			}
   1.468 +		}
   1.469 +    if (pos5 == 0)
   1.470 +        {
   1.471 +        pos5 += at2;
   1.472 +        if ((pos5 + 1 == aAt.iPos) && !aAt.iLeadingEdge)
   1.473 +            {
   1.474 +            TPtrC tPtrC;
   1.475 +            if (iNumChar == 1)
   1.476 +                {
   1.477 +                _LIT(KIS41, "\05be");
   1.478 +                tPtrC.Set(KIS41);
   1.479 +                }
   1.480 +            else if (iNumChar == 2)
   1.481 +                {
   1.482 +                _LIT(KIS42, "\05be\05be");
   1.483 +                tPtrC.Set(KIS42);
   1.484 +                }
   1.485 +            return tPtrC;
   1.486 +            }
   1.487 +        }
   1.488 +	return iNullText;
   1.489 +	}
   1.490 +
   1.491 +class CTestFormExtendedInterfaceProvider: public CBase, public MFormCustomInterfaceProvider
   1.492 +	{
   1.493 +public:
   1.494 +	static CTestFormExtendedInterfaceProvider* NewL(TPtrC aText, TInt aNumChar);
   1.495 +	~CTestFormExtendedInterfaceProvider();
   1.496 +	TAny* GetExtendedInterface(const TUid& aInterfaceId);
   1.497 +
   1.498 +private:
   1.499 +	CTestFormExtendedInterfaceProvider();
   1.500 +	void ConstructL(TPtrC aText, TInt aNumChar);
   1.501 +
   1.502 +private:
   1.503 +	CTestInlineTextSource* iTestInlineTextSource; // Owned
   1.504 +	};
   1.505 +
   1.506 +
   1.507 +CTestFormExtendedInterfaceProvider::CTestFormExtendedInterfaceProvider()
   1.508 +	{
   1.509 +	}
   1.510 +
   1.511 +CTestFormExtendedInterfaceProvider* CTestFormExtendedInterfaceProvider::NewL(TPtrC aText, TInt aNumChar)
   1.512 +	{
   1.513 +	CTestFormExtendedInterfaceProvider* self= new(ELeave) CTestFormExtendedInterfaceProvider();
   1.514 +	CleanupStack::PushL(self);
   1.515 +	self->ConstructL(aText, aNumChar);
   1.516 +	CleanupStack::Pop(); // self
   1.517 +	return self;
   1.518 +	}
   1.519 +
   1.520 +CTestFormExtendedInterfaceProvider::~CTestFormExtendedInterfaceProvider()
   1.521 +	{
   1.522 +	delete iTestInlineTextSource;
   1.523 +	}
   1.524 +
   1.525 +void CTestFormExtendedInterfaceProvider::ConstructL(TPtrC aText, TInt aNumChar)
   1.526 +	{
   1.527 +	iTestInlineTextSource = CTestInlineTextSource::NewL(aText, aNumChar);
   1.528 +	}
   1.529 +
   1.530 +TAny* CTestFormExtendedInterfaceProvider::GetExtendedInterface( const TUid& aInterfaceId )
   1.531 +	{
   1.532 +	if (aInterfaceId == KInlineTextApiExtensionUid)
   1.533 +		{
   1.534 +		return static_cast<MTmInlineTextSource*>(iTestInlineTextSource);
   1.535 +		}
   1.536 +	else
   1.537 +		{
   1.538 +		return NULL;
   1.539 +		}
   1.540 +	}
   1.541 +
   1.542 +// When referring to test cases the following shorthand is used:
   1.543 +// P  Primary text that has inline text (leading and/or trailing) attached
   1.544 +//    to it
   1.545 +// L  Leading inline text attached to primary text
   1.546 +// T  Trailing inline text attached to primary text
   1.547 +// X  Secondary text that precedes primary text
   1.548 +// Y  Secondary text that follows primary text
   1.549 +// S  A special case of P where the primary text is a single character
   1.550 +//    which has both leading and trailing inline text attached to it
   1.551 +//
   1.552 +// So, for example, X L-P will indicate some normal secondary text,
   1.553 +// followed by a <space>, followed by some primary text which will get
   1.554 +// leading text added to the start of it.
   1.555 +//
   1.556 +// When defining a test string the following are significant characters:
   1.557 +// A  An 'A' will get zero or more 'a's of leading text attached to it
   1.558 +// B  A 'B' will get zero or more 'b's of trailing text attached to it
   1.559 +// C  A 'C' will get zero or more 'c's of both leading and trailing text
   1.560 +//    attached to it
   1.561 +//
   1.562 +// All other characters are used normally.
   1.563 +// N.B. Spaces have significance as potential line-breaking points.
   1.564 +//
   1.565 +// So the example X L-P could be implemented as "ij Axyz". The 'A'
   1.566 +// indicating that leading inline text should be attatched to it.
   1.567 +//
   1.568 +// All test are carried out 3 times, once with inline text set to add zero
   1.569 +// characters for each inline text (i.e. switched off), once with inline
   1.570 +// text set to add one character for each inline text and once with inline
   1.571 +// text set to add two characters for each inline text.
   1.572 +//
   1.573 +// All tests use a special test graphics device and test graphics context
   1.574 +// to enable us to catch the output and use a special "pseudo" test font
   1.575 +// where all characters are exactly 10 pixels wide and 10 pixels high (to
   1.576 +// make the calculations easier).
   1.577 +//
   1.578 +// General combination tests
   1.579 +//
   1.580 +// These are simple tests, which would take a single line of input on the
   1.581 +// display and produce a single line of output on the display (if we
   1.582 +// weren't using a special CTestGraphicsContext to catch the output).
   1.583 +// These tests check that, without the complications of line-breaking,
   1.584 +// inline text is inserted where we expect it to be. This is why a display
   1.585 +// that is capable of taking 20 chars on a line is used for these tests.
   1.586 +//
   1.587 +// Future extensions:
   1.588 +// These tests could be extended to do similar tests using Right-to-Left
   1.589 +// (RtoL) text. This would require the inline text mechanism to be
   1.590 +// extended to also use RtoL trigger characters (and inserts). The
   1.591 +// expected results would need to take account of the fact that the output
   1.592 +// would be in display order rather than buffer order.
   1.593 +//
   1.594 +// Specific tests
   1.595 +//
   1.596 +// These tests check specific cases that involve line-breaking. They
   1.597 +// produce more than one line of output, apart from some (not all) cases
   1.598 +// when inline text is switched off. To force the line-breaking these
   1.599 +// tests use a display that is obly capable of taking 10 chars on a line
   1.600 +// is used. Detailed info for each test is given in comments in the test
   1.601 +// data.
   1.602 +//
   1.603 +// Future extensions:
   1.604 +// These tests could be extended to check the behaviour of truncation and
   1.605 +// the insertion of an ellipsis. These tests could also be extended to
   1.606 +// include some RtoL examples.
   1.607 +
   1.608 +static const TInt KTestCases = 18;
   1.609 +static const TInt KInlineTextOptions = 3;
   1.610 +static const TInt KVariants = 6;
   1.611 +
   1.612 +static const TPtrC KTestStrings[KTestCases][KInlineTextOptions][KVariants] =
   1.613 +	{	// Start of General Combination tests
   1.614 +		{	// Test L-P
   1.615 +			{
   1.616 +			_S("Axyz"),
   1.617 +			_S("Axyz"),
   1.618 +			_S(""),
   1.619 +			_S(""),
   1.620 +			_S(""),
   1.621 +			_S("")
   1.622 +			},
   1.623 +			{
   1.624 +			_S("Axyz"),
   1.625 +			_S("a"),
   1.626 +			_S("Axyz"),
   1.627 +			_S(""),
   1.628 +			_S(""),
   1.629 +			_S("")
   1.630 +			},
   1.631 +			{
   1.632 +			_S("Axyz"),
   1.633 +			_S("aa"),
   1.634 +			_S("Axyz"),
   1.635 +			_S(""),
   1.636 +			_S(""),
   1.637 +			_S("")
   1.638 +			}
   1.639 +		},
   1.640 +		{	// Test X L-P
   1.641 +			{
   1.642 +			_S("ij Axyz"),
   1.643 +			_S("ij Axyz"),
   1.644 +			_S(""),
   1.645 +			_S(""),
   1.646 +			_S(""),
   1.647 +			_S("")
   1.648 +			},
   1.649 +			{
   1.650 +			_S("ij Axyz"),
   1.651 +			_S("ij "),
   1.652 +			_S("a"),
   1.653 +			_S("Axyz"),
   1.654 +			_S(""),
   1.655 +			_S("")
   1.656 +			},
   1.657 +			{
   1.658 +			_S("ij Axyz"),
   1.659 +			_S("ij "),
   1.660 +			_S("aa"),
   1.661 +			_S("Axyz"),
   1.662 +			_S(""),
   1.663 +			_S("")
   1.664 +			}
   1.665 +		},
   1.666 +		{	// Test P-T
   1.667 +			{
   1.668 +			_S("xyzB"),
   1.669 +			_S("xyzB"),
   1.670 +			_S(""),
   1.671 +			_S(""),
   1.672 +			_S(""),
   1.673 +			_S("")
   1.674 +			},
   1.675 +			{
   1.676 +			_S("xyzB"),
   1.677 +			_S("xyzB"),
   1.678 +			_S("b"),
   1.679 +			_S(""),
   1.680 +			_S(""),
   1.681 +			_S("")
   1.682 +			},
   1.683 +			{
   1.684 +			_S("xyzB"),
   1.685 +			_S("xyzB"),
   1.686 +			_S("bb"),
   1.687 +			_S(""),
   1.688 +			_S(""),
   1.689 +			_S("")
   1.690 +			}
   1.691 +		},
   1.692 +		{	// Test P-T Y
   1.693 +			{
   1.694 +			_S("xyzB pq"),
   1.695 +			_S("xyzB pq"),
   1.696 +			_S(""),
   1.697 +			_S(""),
   1.698 +			_S(""),
   1.699 +			_S("")
   1.700 +			},
   1.701 +			{
   1.702 +			_S("xyzB pq"),
   1.703 +			_S("xyzB"),
   1.704 +			_S("b"),
   1.705 +			_S(" pq"),
   1.706 +			_S(""),
   1.707 +			_S("")
   1.708 +			},
   1.709 +			{
   1.710 +			_S("xyzB pq"),
   1.711 +			_S("xyzB"),
   1.712 +			_S("bb"),
   1.713 +			_S(" pq"),
   1.714 +			_S(""),
   1.715 +			_S("")
   1.716 +			}
   1.717 +		},
   1.718 +		{	// Test L-P-T
   1.719 +			{
   1.720 +			_S("AxyzB"),
   1.721 +			_S("AxyzB"),
   1.722 +			_S(""),
   1.723 +			_S(""),
   1.724 +			_S(""),
   1.725 +			_S("")
   1.726 +			},
   1.727 +			{
   1.728 +			_S("AxyzB"),
   1.729 +			_S("a"),
   1.730 +			_S("AxyzB"),
   1.731 +			_S("b"),
   1.732 +			_S(""),
   1.733 +			_S("")
   1.734 +			},
   1.735 +			{
   1.736 +			_S("AxyzB"),
   1.737 +			_S("aa"),
   1.738 +			_S("AxyzB"),
   1.739 +			_S("bb"),
   1.740 +			_S(""),
   1.741 +			_S("")
   1.742 +			}
   1.743 +		},
   1.744 +		{	// Test L-C-T
   1.745 +			{
   1.746 +			_S("C"),
   1.747 +			_S("C"),
   1.748 +			_S(""),
   1.749 +			_S(""),
   1.750 +			_S(""),
   1.751 +			_S("")
   1.752 +			},
   1.753 +			{
   1.754 +			_S("C"),
   1.755 +			_S("c"),
   1.756 +			_S("C"),
   1.757 +			_S("c"),
   1.758 +			_S(""),
   1.759 +			_S("")
   1.760 +			},
   1.761 +			{
   1.762 +			_S("C"),
   1.763 +			_S("cc"),
   1.764 +			_S("C"),
   1.765 +			_S("cc"),
   1.766 +			_S(""),
   1.767 +			_S("")
   1.768 +			}
   1.769 +		},
   1.770 +		{	// Test X L-P-T
   1.771 +			{
   1.772 +			_S("ij AxyzB"),
   1.773 +			_S("ij AxyzB"),
   1.774 +			_S(""),
   1.775 +			_S(""),
   1.776 +			_S(""),
   1.777 +			_S("")
   1.778 +			},
   1.779 +			{
   1.780 +			_S("ij AxyzB"),
   1.781 +			_S("ij "),
   1.782 +			_S("a"),
   1.783 +			_S("AxyzB"),
   1.784 +			_S("b"),
   1.785 +			_S("")
   1.786 +			},
   1.787 +			{
   1.788 +			_S("ij AxyzB"),
   1.789 +			_S("ij "),
   1.790 +			_S("aa"),
   1.791 +			_S("AxyzB"),
   1.792 +			_S("bb"),
   1.793 +			_S("")
   1.794 +			}
   1.795 +		},
   1.796 +		{	// Test X L-C-T
   1.797 +			{
   1.798 +			_S("ij C"),
   1.799 +			_S("ij C"),
   1.800 +			_S(""),
   1.801 +			_S(""),
   1.802 +			_S(""),
   1.803 +			_S("")
   1.804 +			},
   1.805 +			{
   1.806 +			_S("ij C"),
   1.807 +			_S("ij "),
   1.808 +			_S("c"),
   1.809 +			_S("C"),
   1.810 +			_S("c"),
   1.811 +			_S("")
   1.812 +			},
   1.813 +			{
   1.814 +			_S("ij C"),
   1.815 +			_S("ij "),
   1.816 +			_S("cc"),
   1.817 +			_S("C"),
   1.818 +			_S("cc"),
   1.819 +			_S("")
   1.820 +			}
   1.821 +		},
   1.822 +		{	// Test L-P-T Y
   1.823 +			{
   1.824 +			_S("AxyzB pq"),
   1.825 +			_S("AxyzB pq"),
   1.826 +			_S(""),
   1.827 +			_S(""),
   1.828 +			_S(""),
   1.829 +			_S("")
   1.830 +			},
   1.831 +			{
   1.832 +			_S("AxyzB pq"),
   1.833 +			_S("a"),
   1.834 +			_S("AxyzB"),
   1.835 +			_S("b"),
   1.836 +			_S(" pq"),
   1.837 +			_S("")
   1.838 +			},
   1.839 +			{
   1.840 +			_S("AxyzB pq"),
   1.841 +			_S("aa"),
   1.842 +			_S("AxyzB"),
   1.843 +			_S("bb"),
   1.844 +			_S(" pq"),
   1.845 +			_S("")
   1.846 +			}
   1.847 +		},
   1.848 +		{	// Test L-C-T Y
   1.849 +			{
   1.850 +			_S("C pq"),
   1.851 +			_S("C pq"),
   1.852 +			_S(""),
   1.853 +			_S(""),
   1.854 +			_S(""),
   1.855 +			_S("")
   1.856 +			},
   1.857 +			{
   1.858 +			_S("C pq"),
   1.859 +			_S("c"),
   1.860 +			_S("C"),
   1.861 +			_S("c"),
   1.862 +			_S(" pq"),
   1.863 +			_S("")
   1.864 +			},
   1.865 +			{
   1.866 +			_S("C pq"),
   1.867 +			_S("cc"),
   1.868 +			_S("C"),
   1.869 +			_S("cc"),
   1.870 +			_S(" pq"),
   1.871 +			_S("")
   1.872 +			}
   1.873 +		},
   1.874 +		{	// Test X L-P-T Y
   1.875 +			{
   1.876 +			_S("ij AxyzB pq"),
   1.877 +			_S("ij AxyzB pq"),
   1.878 +			_S(""),
   1.879 +			_S(""),
   1.880 +			_S(""),
   1.881 +			_S("")
   1.882 +			},
   1.883 +			{
   1.884 +			_S("ij AxyzB pq"),
   1.885 +			_S("ij "),
   1.886 +			_S("a"),
   1.887 +			_S("AxyzB"),
   1.888 +			_S("b"),
   1.889 +			_S(" pq")
   1.890 +			},
   1.891 +			{
   1.892 +			_S("ij AxyzB pq"),
   1.893 +			_S("ij "),
   1.894 +			_S("aa"),
   1.895 +			_S("AxyzB"),
   1.896 +			_S("bb"),
   1.897 +			_S(" pq")
   1.898 +			}
   1.899 +		},
   1.900 +		{	// Test X L-C-T Y
   1.901 +			{
   1.902 +			_S("ij C pq"),
   1.903 +			_S("ij C pq"),
   1.904 +			_S(""),
   1.905 +			_S(""),
   1.906 +			_S(""),
   1.907 +			_S("")
   1.908 +			},
   1.909 +			{
   1.910 +			_S("ij C pq"),
   1.911 +			_S("ij "),
   1.912 +			_S("c"),
   1.913 +			_S("C"),
   1.914 +			_S("c"),
   1.915 +			_S(" pq")
   1.916 +			},
   1.917 +			{
   1.918 +			_S("ij C pq"),
   1.919 +			_S("ij "),
   1.920 +			_S("cc"),
   1.921 +			_S("C"),
   1.922 +			_S("cc"),
   1.923 +			_S(" pq")
   1.924 +			}
   1.925 +		},	// End of General Combination tests
   1.926 +		{	// Start of Specific tests
   1.927 +			{	// Test P-T Y
   1.928 +				// primary text with trailing inline text, secondary text secondary
   1.929 +				// text won't fit on line
   1.930 +			_S("wxyzB pqrstuv"),
   1.931 +			_S("wxyzB"),
   1.932 +			_S(" "),
   1.933 +			_S("pqrstuv"),
   1.934 +			_S(""),
   1.935 +			_S("")
   1.936 +			},
   1.937 +			{
   1.938 +			_S("wxyzB pqrstuv"),
   1.939 +			_S("wxyzB"),
   1.940 +			_S("b"),
   1.941 +			_S(" "),
   1.942 +			_S("pqrstuv"),
   1.943 +			_S("")
   1.944 +			},
   1.945 +			{
   1.946 +			_S("wxyzB pqrstuv"),
   1.947 +			_S("wxyzB"),
   1.948 +			_S("bb"),
   1.949 +			_S(" "),
   1.950 +			_S("pqrstuv"),
   1.951 +			_S("")
   1.952 +			}
   1.953 +		},
   1.954 +		{	// Test X P-T one
   1.955 +			// secondary text, primary text with trailing inline text trailing
   1.956 +			// text won't fit and there is no line breaking point inside primary
   1.957 +			// text and the primary text plus trailing text will fit on next line
   1.958 +			{
   1.959 +			_S("ijklm xyzB"),
   1.960 +			_S("ijklm xyzB"),
   1.961 +			_S(""),
   1.962 +			_S(""),
   1.963 +			_S(""),
   1.964 +			_S("")
   1.965 +			},
   1.966 +			{
   1.967 +			_S("ijklm xyzB"),
   1.968 +			_S("ijklm"),
   1.969 +			_S(" "),
   1.970 +			_S("xyzB"),
   1.971 +			_S("b"),
   1.972 +			_S("")
   1.973 +			},
   1.974 +			{
   1.975 +			_S("ijklm xyzB"),
   1.976 +			_S("ijklm"),
   1.977 +			_S(" "),
   1.978 +			_S("xyzB"),
   1.979 +			_S("bb"),
   1.980 +			_S("")
   1.981 +			}
   1.982 +		},
   1.983 +		{	// Test X P-T two
   1.984 +			// secondary text, primary text with trailing inline text primary
   1.985 +			// text won't fit and there is no line breaking point inside primary
   1.986 +			// text and the primary text plus trailing text will fit on next line
   1.987 +			{
   1.988 +			_S("ijklm uvwxyzB"),
   1.989 +			_S("ijklm"),
   1.990 +			_S(" "),
   1.991 +			_S("uvwxyzB"),
   1.992 +			_S(""),
   1.993 +			_S("")
   1.994 +			},
   1.995 +			{
   1.996 +			_S("ijklm uvwxyzB"),
   1.997 +			_S("ijklm"),
   1.998 +			_S(" "),
   1.999 +			_S("uvwxyzB"),
  1.1000 +			_S("b"),
  1.1001 +			_S("")
  1.1002 +			},
  1.1003 +			{
  1.1004 +			_S("ijklm uvwxyzB"),
  1.1005 +			_S("ijklm"),
  1.1006 +			_S(" "),
  1.1007 +			_S("uvwxyzB"),
  1.1008 +			_S("bb"),
  1.1009 +			_S("")
  1.1010 +			}
  1.1011 +		},
  1.1012 +		{	// Test X L-P-T one
  1.1013 +			// secondary text, primary text with leading and trailing inline text trailing
  1.1014 +			// text won't fit and there is no line breaking point inside primary text and
  1.1015 +			// the leading text plus primary text plus trailing text will fit on the next line
  1.1016 +			{
  1.1017 +			_S("ij AwxyzB"),
  1.1018 +			_S("ij AwxyzB"),
  1.1019 +			_S(""),
  1.1020 +			_S(""),
  1.1021 +			_S(""),
  1.1022 +			_S("")
  1.1023 +			},
  1.1024 +			{
  1.1025 +			_S("ij AwxyzB"),
  1.1026 +			_S("ij"),
  1.1027 +			_S(" "),
  1.1028 +			_S("a"),
  1.1029 +			_S("AwxyzB"),
  1.1030 +			_S("b")
  1.1031 +			},
  1.1032 +			{
  1.1033 +			_S("ij AwxyzB"),
  1.1034 +			_S("ij"),
  1.1035 +			_S(" "),
  1.1036 +			_S("aa"),
  1.1037 +			_S("AwxyzB"),
  1.1038 +			_S("bb")
  1.1039 +			}
  1.1040 +		},
  1.1041 +		{	// Test X L-P-T two
  1.1042 +			// secondary text, primary text with leading and trailing inline text primary
  1.1043 +			// text won't fit and there is no line breaking point inside primary text and
  1.1044 +			// the leading text plus primary text plus trailing text will fit on the next line
  1.1045 +			{
  1.1046 +			_S("ijkl AxyzB"),
  1.1047 +			_S("ijkl AxyzB"),
  1.1048 +			_S(""),
  1.1049 +			_S(""),
  1.1050 +			_S(""),
  1.1051 +			_S("")
  1.1052 +			},
  1.1053 +			{
  1.1054 +			_S("ijkl AxyzB"),
  1.1055 +			_S("ijkl"),
  1.1056 +			_S(" "),
  1.1057 +			_S("a"),
  1.1058 +			_S("AxyzB"),
  1.1059 +			_S("b")
  1.1060 +			},
  1.1061 +			{
  1.1062 +			_S("ijkl AxyzB"),
  1.1063 +			_S("ijkl"),
  1.1064 +			_S(" "),
  1.1065 +			_S("aa"),
  1.1066 +			_S("AxyzB"),
  1.1067 +			_S("bb"),
  1.1068 +			}
  1.1069 +		},
  1.1070 +		{	// Test X L-P-T three
  1.1071 +			//secondary text, primary text with leading and trailing inline text leading
  1.1072 +			// text won't fit and the leading text plus primary text plus trailing text
  1.1073 +			// will fit on the next line
  1.1074 +			{
  1.1075 +			_S("ijklmnop AxyzB"),
  1.1076 +			_S("ijklmnop"),
  1.1077 +			_S(" "),
  1.1078 +			_S("AxyzB"),
  1.1079 +			_S(""),
  1.1080 +			_S("")
  1.1081 +			},
  1.1082 +			{
  1.1083 +			_S("ijklmnop AxyzB"),
  1.1084 +			_S("ijklmnop"),
  1.1085 +			_S(" "),
  1.1086 +			_S("a"),
  1.1087 +			_S("AxyzB"),
  1.1088 +			_S("b")
  1.1089 +			},
  1.1090 +			{
  1.1091 +			_S("ijklmnop AxyzB"),
  1.1092 +			_S("ijklmnop"),
  1.1093 +			_S(" "),
  1.1094 +			_S("aa"),
  1.1095 +			_S("AxyzB"),
  1.1096 +			_S("bb")
  1.1097 +			}
  1.1098 +		}	// End of Specific tests
  1.1099 +	};
  1.1100 +
  1.1101 +static const TInt KTestCount[KTestCases][KInlineTextOptions] =
  1.1102 +	{
  1.1103 +		{	// Start of General Combination tests
  1.1104 +		1,	// Test L-P
  1.1105 +		2,
  1.1106 +		2
  1.1107 +		},
  1.1108 +		{
  1.1109 +		1,	// Test X L-P
  1.1110 +		3,
  1.1111 +		3
  1.1112 +		},
  1.1113 +		{
  1.1114 +		1,	// Test P-T
  1.1115 +		2,
  1.1116 +		2
  1.1117 +		},
  1.1118 +		{
  1.1119 +		1,	// Test P-T Y
  1.1120 +		3,
  1.1121 +		3
  1.1122 +		},
  1.1123 +		{
  1.1124 +		1,	// Test L-P-T
  1.1125 +		3,
  1.1126 +		3
  1.1127 +		},
  1.1128 +		{
  1.1129 +		1,	// Test L-C-T
  1.1130 +		3,
  1.1131 +		3
  1.1132 +		},
  1.1133 +		{
  1.1134 +		1,	// Test X L-P-T
  1.1135 +		4,
  1.1136 +		4
  1.1137 +		},
  1.1138 +		{
  1.1139 +		1,	// Test X L-C-T
  1.1140 +		4,
  1.1141 +		4
  1.1142 +		},
  1.1143 +		{
  1.1144 +		1,	// Test L-P-T Y
  1.1145 +		4,
  1.1146 +		4
  1.1147 +		},
  1.1148 +		{
  1.1149 +		1,	// Test L-C-T Y
  1.1150 +		4,
  1.1151 +		4
  1.1152 +		},
  1.1153 +		{
  1.1154 +		1,	// Test X L-P-T Y
  1.1155 +		5,
  1.1156 +		5
  1.1157 +		},
  1.1158 +		{
  1.1159 +		1,	// Test X L-C-T Y
  1.1160 +		5,
  1.1161 +		5
  1.1162 +		},	// End of General Combination tests
  1.1163 +		{	// Start of Specific tests
  1.1164 +		3,	// Test P-T B
  1.1165 +		4,
  1.1166 +		4
  1.1167 +		},
  1.1168 +		{
  1.1169 +		1,	// Test X P-T one
  1.1170 +		4,
  1.1171 +		4
  1.1172 +		},
  1.1173 +		{
  1.1174 +		3,	// Test X P-T two
  1.1175 +		4,
  1.1176 +		4
  1.1177 +		},
  1.1178 +		{
  1.1179 +		1,	// Test X L-P-T one
  1.1180 +		5,
  1.1181 +		5
  1.1182 +		},
  1.1183 +		{
  1.1184 +		1,	// Test X L-P-T two
  1.1185 +		5,
  1.1186 +		5
  1.1187 +		},
  1.1188 +		{
  1.1189 +		3,	// Test X L-P-T three
  1.1190 +		5,
  1.1191 +		5
  1.1192 +		}	// End of Specific tests
  1.1193 +	};
  1.1194 +
  1.1195 +void DoLineTestL(TDes& aText, CTextLayout* aLayout, CTestGraphicsDevice* aDevice, CTextView* aView, TInt aNumChar, TInt aIndex)
  1.1196 +	{
  1.1197 +	aText = KTestStrings[aIndex][aNumChar][0];
  1.1198 +	CTestFormExtendedInterfaceProvider* interfaceProvider = CTestFormExtendedInterfaceProvider::NewL(aText, aNumChar); // owned here
  1.1199 +	aLayout->SetInterfaceProvider(interfaceProvider);
  1.1200 +	CleanupStack::PushL(interfaceProvider);
  1.1201 +	aDevice->LineArray().ResetLineArray();
  1.1202 +	aView->HandleGlobalChangeL();
  1.1203 +	// now that we've redrawn the actual ooutput (what went through DrawText(), including
  1.1204 +	// any inline text) has been stored in the LineArray. So we#'ll have a look and see
  1.1205 +	// if it contains what we expect it to.
  1.1206 +	// Each line may produce one or more LineArray() entries as there is one created for
  1.1207 +	// each call to DrawText()
  1.1208 +	const TTestGCDisplayLine* line1 = 0;
  1.1209 +	const TTestGCDisplayLine* line2 = 0;
  1.1210 +	// Find out how many LineArray entries are expected for the output of this test
  1.1211 +	TInt count = KTestCount[aIndex][aNumChar];
  1.1212 +	// And test them (in reverse order, because it's easier)
  1.1213 +	switch (count)
  1.1214 +		{
  1.1215 +	case 5:
  1.1216 +		line1 = &(aDevice->LineArray().Line(4));
  1.1217 +		line2 = aDevice->LineArray().Find(KTestStrings[aIndex][aNumChar][5]);
  1.1218 +		TESTPOINT(0 != line1);
  1.1219 +		TESTPOINT(0 != line2);
  1.1220 +		TESTPOINT(line1->iLineData.Compare(line2->iLineData) == 0);
  1.1221 +	case 4:
  1.1222 +		line1 = &(aDevice->LineArray().Line(3));
  1.1223 +		line2 = aDevice->LineArray().Find(KTestStrings[aIndex][aNumChar][4]);
  1.1224 +		TESTPOINT(0 != line1);
  1.1225 +		TESTPOINT(0 != line2);
  1.1226 +		TESTPOINT(line1->iLineData.Compare(line2->iLineData) == 0);
  1.1227 +	case 3:
  1.1228 +		line1 = &(aDevice->LineArray().Line(2));
  1.1229 +		line2 = aDevice->LineArray().Find(KTestStrings[aIndex][aNumChar][3]);
  1.1230 +		TESTPOINT(0 != line1);
  1.1231 +		TESTPOINT(0 != line2);
  1.1232 +		TESTPOINT(line1->iLineData.Compare(line2->iLineData) == 0);
  1.1233 +	case 2:
  1.1234 +		line1 = &(aDevice->LineArray().Line(1));
  1.1235 +		line2 = aDevice->LineArray().Find(KTestStrings[aIndex][aNumChar][2]);
  1.1236 +		TESTPOINT(0 != line1);
  1.1237 +		TESTPOINT(0 != line2);
  1.1238 +		TESTPOINT(line1->iLineData.Compare(line2->iLineData) == 0);
  1.1239 +	case 1:
  1.1240 +		line1 = &(aDevice->LineArray().Line(0));
  1.1241 +		line2 = aDevice->LineArray().Find(KTestStrings[aIndex][aNumChar][1]);
  1.1242 +		TESTPOINT(0 != line1);
  1.1243 +		TESTPOINT(0 != line2);
  1.1244 +		// Can't always do a direct comparison of lines because same string
  1.1245 +		// may appear in more than one line, so compare contents
  1.1246 +		TESTPOINT(line1->iLineData.Compare(line2->iLineData) == 0);
  1.1247 +		}
  1.1248 +	aLayout->SetInterfaceProvider(NULL);
  1.1249 +	CleanupStack::PopAndDestroy(interfaceProvider);
  1.1250 +	}
  1.1251 +
  1.1252 +void GeneralCombinationTestsTextViewL(TDes& aText, CTextLayout* aLayout, CTestGraphicsDevice* aDevice, CTextView* aView, TInt aNumChar)
  1.1253 +	{
  1.1254 +	// For all tests carried out from here up to 20 chars will fit on a line
  1.1255 +	TESTPRINT(_L("Test L-P"));
  1.1256 +	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 0);
  1.1257 +	TESTPRINT(_L("Test X L-P"));
  1.1258 +	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 1);
  1.1259 +	TESTPRINT(_L("Test P-T"));
  1.1260 +	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 2);
  1.1261 +	TESTPRINT(_L("Test P-T Y"));
  1.1262 +	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 3);
  1.1263 +	TESTPRINT(_L("Test L-P-T"));
  1.1264 +	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 4);
  1.1265 +	TESTPRINT(_L("Test L-C-T"));
  1.1266 +	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 5);
  1.1267 +	TESTPRINT(_L("Test X L-P-T"));
  1.1268 +	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 6);
  1.1269 +	TESTPRINT(_L("Test X L-C-T"));
  1.1270 +	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 7);
  1.1271 +	TESTPRINT(_L("Test L-P-T Y"));
  1.1272 +	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 8);
  1.1273 +	TESTPRINT(_L("Test L-C-T Y"));
  1.1274 +	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 9);
  1.1275 +	TESTPRINT(_L("Test X L-P-T Y"));
  1.1276 +	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 10);
  1.1277 +	TESTPRINT(_L("Test X L-C-T Y"));
  1.1278 +	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 11);
  1.1279 +	}
  1.1280 +
  1.1281 +void SpecificTestsTextViewL(TDes& aText, CTextLayout* aLayout, CTestGraphicsDevice* aDevice, CTextView* aView, TInt aNumChar)
  1.1282 +	{
  1.1283 +	// For all tests carried out from here up to 10 chars will fit on a line
  1.1284 +    TESTPRINT(_L("Test P-T B"));
  1.1285 +	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 12);
  1.1286 +	TESTPRINT(_L("Test X P-T one"));
  1.1287 +	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 13);
  1.1288 +	TESTPRINT(_L("Test X P-T two"));
  1.1289 +	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 14);
  1.1290 +	TESTPRINT(_L("Test X L-P-T one"));
  1.1291 +	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 15);
  1.1292 +	TESTPRINT(_L("Test X L-P-T two"));
  1.1293 +	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 16);
  1.1294 +	TESTPRINT(_L("Test X L-P-T three"));
  1.1295 +	DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 17);
  1.1296 +	}
  1.1297 +
  1.1298 +void DoLineTestForINC141914L(TDes& aText, CTextLayout* aLayout, CTestGraphicsDevice* aDevice, CTextView* aView)
  1.1299 +    {
  1.1300 +    /*
  1.1301 +     * This case is to test whether or not inline text will find the correct format after changing the text content.
  1.1302 +     * In bytecode, there is one value to record the postion(iInlineTextFormat) to which inline text chunk attaches,
  1.1303 +     * INC141914 is raised because this value is not updated correctly after text change.
  1.1304 +     * The text string is as the following 3 lines:
  1.1305 +     * 111111;
  1.1306 +     * 222222;
  1.1307 +     * wxyBbz
  1.1308 +     * Where the 'b' is the inline text.
  1.1309 +     * 
  1.1310 +     * 1st step:
  1.1311 +     * delete 5 leading '1's in the first line,
  1.1312 +     * 2nd step:
  1.1313 +     * delete 5 leading '2's in the second line.
  1.1314 +     * after the 2 steps, inline text is still able to use iInlineTextFormat to find its attached text string
  1.1315 +    */
  1.1316 +    aText = _S("\x31\x31\x31\x31\x31\x31\x3B\x2029\x32\x32\x32\x32\x32\x32\x3B\x2029\x77\x78\x79\x42\x7A");
  1.1317 +    CTestFormExtendedInterfaceProvider* interfaceProvider = CTestFormExtendedInterfaceProvider::NewL(aText, 1); // owned here
  1.1318 +    aLayout->SetInterfaceProvider(interfaceProvider);
  1.1319 +    CleanupStack::PushL(interfaceProvider);
  1.1320 +    aDevice->LineArray().ResetLineArray();
  1.1321 +    aView->HandleGlobalChangeL();
  1.1322 +    aText.Delete(0,5);
  1.1323 +    aView->HandleInsertDeleteL(TCursorSelection(0,0),5);
  1.1324 +    aText.Delete(3,5);
  1.1325 +    aView->HandleInsertDeleteL(TCursorSelection(3,3),5);
  1.1326 + 
  1.1327 +    aLayout->SetInterfaceProvider(NULL);
  1.1328 +    CleanupStack::PopAndDestroy(interfaceProvider);
  1.1329 +    }
  1.1330 +
  1.1331 +void DoLineTestForINC143086L(TDes& aText, CTextLayout* aLayout, CTestGraphicsDevice* aDevice, CTextView* aView)
  1.1332 +    {
  1.1333 +    /*
  1.1334 +     * This case is to test inline text behaviour for right-to-left text 
  1.1335 +     * The text string is as the following characters:
  1.1336 +     * \x5e0\x5e1\x5e2\x5e3\x5e4\x5c0\x5e5;
  1.1337 +     * Where the '\x5c0' is the inline text.
  1.1338 +     */
  1.1339 +    aText = _S("\x5e0\x5e1\x5e2\x5e3\x5e4\x5c0\x5e5");
  1.1340 +    CTestFormExtendedInterfaceProvider* interfaceProvider = CTestFormExtendedInterfaceProvider::NewL(aText, 1); // owned here
  1.1341 +    aLayout->SetInterfaceProvider(interfaceProvider);
  1.1342 +    CleanupStack::PushL(interfaceProvider);
  1.1343 +    aDevice->LineArray().ResetLineArray();
  1.1344 +    aView->HandleGlobalChangeL();
  1.1345 + 
  1.1346 +    aLayout->SetInterfaceProvider(NULL);
  1.1347 +    CleanupStack::PopAndDestroy(interfaceProvider);
  1.1348 +    }
  1.1349 +
  1.1350 +// aNumChar determines what kind of inline text is in force
  1.1351 +// 0 means no inline text, 1 means insert a single char for
  1.1352 +// each possible inline text and 2 means insert two chars
  1.1353 +void RunGeneralCombinationTestsL(TInt aNumChar)
  1.1354 +	{
  1.1355 +	CActiveScheduler* scheduler = new(ELeave) CActiveScheduler;
  1.1356 +	CleanupStack::PushL(scheduler);
  1.1357 +	CActiveScheduler::Install(scheduler);
  1.1358 +	TBuf<100> text;
  1.1359 +	TDocModel docModel(text);
  1.1360 +	// This time make it capable of 20 chars + a couple of spare pixels
  1.1361 +	// so all of these tests should result in a single line of output
  1.1362 +	TRect displayRect(0, 0, KDisplayWidthWide, KDisplayHeight);
  1.1363 +	CTextLayout* layout = CTextLayout::NewL(&docModel, displayRect.Width());
  1.1364 +	CleanupStack::PushL(layout);
  1.1365 +	CTestGraphicsDevice* device = CTestGraphicsDevice::NewL(displayRect.Size(), 0);
  1.1366 +	CleanupStack::PushL(device);
  1.1367 +	CTextView* view = CTextView::NewL(layout, displayRect, device, device, 0, 0, 0);
  1.1368 +	CleanupStack::PushL(view);
  1.1369 +	// This is used to force the use of CTestGraphicsContext instead of a normal one
  1.1370 +	CWindowGc* offScreenContext;
  1.1371 +	User::LeaveIfError(device->CreateContext(offScreenContext));
  1.1372 +	CleanupStack::PushL(offScreenContext);
  1.1373 +	CTestTextView::SetContextForFlickerFreeRedraw(view, offScreenContext);
  1.1374 +
  1.1375 +	GeneralCombinationTestsTextViewL(text, layout, device, view, aNumChar);
  1.1376 +
  1.1377 +	CleanupStack::PopAndDestroy(offScreenContext);
  1.1378 +	CleanupStack::PopAndDestroy(view);
  1.1379 +	CleanupStack::PopAndDestroy(device);
  1.1380 +	CleanupStack::PopAndDestroy(layout);
  1.1381 +	CleanupStack::PopAndDestroy(scheduler);
  1.1382 +	}
  1.1383 +
  1.1384 +// aNumChar determines what kind of inline text is in force
  1.1385 +// 0 means no inline text, 1 means insert a single char for
  1.1386 +// each possible inline text and 2 means insert two chars
  1.1387 +void RunSpecificTestsL( TInt aNumChar)
  1.1388 +	{
  1.1389 +	// Note: If you need to move these heap checks any further "in" to focus
  1.1390 +	// on a specific test then you will have to move all the setup code in as
  1.1391 +	// well - and still preserve the two different display widths in use
  1.1392 +	__UHEAP_MARK;
  1.1393 +	CActiveScheduler* scheduler = new(ELeave) CActiveScheduler;
  1.1394 +	CleanupStack::PushL(scheduler);
  1.1395 +	CActiveScheduler::Install(scheduler);
  1.1396 +	TBuf<100> text;
  1.1397 +	TDocModel docModel(text);
  1.1398 +	// This time make it capable of 10 chars + a couple of spare pixels
  1.1399 +	// so that line wrapping will occur
  1.1400 +	TRect displayRect(0, 0, KDisplayWidthThin, KDisplayHeight);
  1.1401 +	CTextLayout* layout = CTextLayout::NewL(&docModel, displayRect.Width());
  1.1402 +	CleanupStack::PushL(layout);
  1.1403 +	CTestGraphicsDevice* device = CTestGraphicsDevice::NewL(displayRect.Size(), 0);
  1.1404 +	CleanupStack::PushL(device);
  1.1405 +	CTextView* view = CTextView::NewL(layout, displayRect, device, device, 0, 0, 0);
  1.1406 +	CleanupStack::PushL(view);
  1.1407 +	// This is used to force the use of CTestGraphicsContext instead of a normal one
  1.1408 +	CWindowGc* offScreenContext;
  1.1409 +	User::LeaveIfError(device->CreateContext(offScreenContext));
  1.1410 +	CleanupStack::PushL(offScreenContext);
  1.1411 +	CTestTextView::SetContextForFlickerFreeRedraw(view, offScreenContext);
  1.1412 +
  1.1413 +	SpecificTestsTextViewL(text, layout, device, view, aNumChar);
  1.1414 +
  1.1415 +	CleanupStack::PopAndDestroy(offScreenContext);
  1.1416 +	CleanupStack::PopAndDestroy(view);
  1.1417 +	CleanupStack::PopAndDestroy(device);
  1.1418 +	CleanupStack::PopAndDestroy(layout);
  1.1419 +	CleanupStack::PopAndDestroy(scheduler);
  1.1420 +	__UHEAP_MARKEND;
  1.1421 +	}
  1.1422 +
  1.1423 +
  1.1424 +void RunTestsForINC141914L()
  1.1425 +    {
  1.1426 +    __UHEAP_MARK;
  1.1427 +    CActiveScheduler* scheduler = new(ELeave) CActiveScheduler;
  1.1428 +    CleanupStack::PushL(scheduler);
  1.1429 +    CActiveScheduler::Install(scheduler);
  1.1430 +    TBuf<100> text;
  1.1431 +    TDocModel docModel(text);
  1.1432 +    // This time make it capable of 10 chars + a couple of spare pixels
  1.1433 +    // so that line wrapping will occur
  1.1434 +    TRect displayRect(0, 0, KDisplayWidthWide, KDisplayHeight);
  1.1435 +    CTextLayout* layout = CTextLayout::NewL(&docModel, displayRect.Width());
  1.1436 +    CleanupStack::PushL(layout);
  1.1437 +    CTestGraphicsDevice* device = CTestGraphicsDevice::NewL(displayRect.Size(), 0);
  1.1438 +    CleanupStack::PushL(device);
  1.1439 +    CTextView* view = CTextView::NewL(layout, displayRect, device, device, 0, 0, 0);
  1.1440 +    CleanupStack::PushL(view);
  1.1441 +    // This is used to force the use of CTestGraphicsContext instead of a normal one 
  1.1442 +    CWindowGc* offScreenContext;
  1.1443 +    User::LeaveIfError(device->CreateContext(offScreenContext));
  1.1444 +    CleanupStack::PushL(offScreenContext);
  1.1445 +    CTestTextView::SetContextForFlickerFreeRedraw(view, offScreenContext);
  1.1446 +
  1.1447 +    DoLineTestForINC141914L(text, layout, device, view);
  1.1448 +    DoLineTestForINC143086L(text, layout, device, view);
  1.1449 +
  1.1450 +    CleanupStack::PopAndDestroy(offScreenContext);
  1.1451 +    CleanupStack::PopAndDestroy(view);
  1.1452 +    CleanupStack::PopAndDestroy(device);
  1.1453 +    CleanupStack::PopAndDestroy(layout);
  1.1454 +    CleanupStack::PopAndDestroy(scheduler);
  1.1455 +    __UHEAP_MARKEND;
  1.1456 +    }
  1.1457 +
  1.1458 +TVerdict CTInLineTextStep::doTestStepL()
  1.1459 +	{
  1.1460 +    SetTestStepResult(EPass);
  1.1461 +    TestStep = this;
  1.1462 +    
  1.1463 +	__UHEAP_MARK;
  1.1464 +	TESTPRINT(KTInlineText);
  1.1465 +	TESTPRINT(_L(" @SYMTestCaseID:SYSLIB-FORM-LEGACY-INLINETEXT-0001 General combination tests - no inline text "));
  1.1466 +	TInt error = RFbsSession::Connect();
  1.1467 +	if (error == KErrNotFound)
  1.1468 +		{
  1.1469 +		FbsStartup();
  1.1470 +		error = RFbsSession::Connect();
  1.1471 +		}
  1.1472 +	TEST(error == KErrNone);
  1.1473 +	TRAP(error, RunGeneralCombinationTestsL(0));
  1.1474 +	TEST(error == KErrNone);
  1.1475 +	TESTPRINT(_L("General combination tests - single char inline text"));
  1.1476 +	TRAP(error, RunGeneralCombinationTestsL(1));
  1.1477 +	TEST(error == KErrNone);
  1.1478 +	TESTPRINT(_L("General combination tests - multi char inline text"));
  1.1479 +	TRAP(error, RunGeneralCombinationTestsL(2));
  1.1480 +	TEST(error == KErrNone);
  1.1481 +	TESTPRINT(_L("Specific tests - no inline text"));
  1.1482 +	TRAP(error, RunSpecificTestsL(0));
  1.1483 +	TEST(error == KErrNone);
  1.1484 +	TESTPRINT(_L("Specific tests - single char inline text"));
  1.1485 +	TRAP(error, RunSpecificTestsL(1));
  1.1486 +	TEST(error == KErrNone);
  1.1487 +	TESTPRINT(_L("Specific tests - multi char inline text"));
  1.1488 +	TRAP(error, RunSpecificTestsL(2));
  1.1489 +	TEST(error == KErrNone);
  1.1490 +	
  1.1491 +    TESTPRINT(_L("Defect tests - for INC141914"));
  1.1492 +    TRAP(error, RunTestsForINC141914L());
  1.1493 +    TEST(error == KErrNone);
  1.1494 +    
  1.1495 +	RFbsSession::Disconnect();
  1.1496 +	__UHEAP_MARKEND;
  1.1497 +	User::Heap().Check();
  1.1498 +	return TestStepResult();
  1.1499 +	}