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 + }