First public contribution.
2 * Copyright (c) 2004-2010 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
18 //#include "TCustomWrap.h"
19 #include "TGraphicsContext.h"
27 #include <inlinetext.h>
28 #include "tinlinetext.h"
30 namespace LocalToTInlineText
33 _LIT(KTInlineText, "TInlineText");
34 const TInt KDisplayWidthWide = 202;
35 const TInt KDisplayWidthThin = 102;
36 const TInt KDisplayHeight = 100;
37 const TInt KPictureCharacter = 0xFFFC;
39 CTInLineTextStep* TestStep = NULL;
40 #define TESTPOINT(p) TestStep->testpoint(p,(TText8*)__FILE__,__LINE__)
41 #define TESTPRINT(p) TestStep->print(p,(TText8*)__FILE__,__LINE__)
44 enum TInlineTextPanic { EAccessOutsideText = 1 };
45 void Panic(TInlineTextPanic)
47 User::Panic(_L("TInlineText"), EAccessOutsideText);
50 class CPinkSquare : public CPicture
53 // Size of square in twips.
54 // 600 is 15 pixels using the standard test graphics device at
55 // its default resolution.
56 enum { KWidth = 600, KHeight = 600 };
59 void Draw(CGraphicsContext& aGc, const TPoint& aTopLeft, const TRect& aClipRect, MGraphicsDeviceMap* aMap) const
61 // This picture is a magenta square
62 TPoint size(KWidth, KHeight);
64 size = aMap->TwipsToPixels(size);
65 TRect rect(aTopLeft, aTopLeft + size);
66 aGc.SetClippingRect(aClipRect);
67 aGc.SetDrawMode(CGraphicsContext::EDrawModePEN);
68 aGc.SetPenColor(KRgbMagenta);
69 aGc.SetBrushStyle(CGraphicsContext::ESolidBrush);
70 aGc.SetBrushColor(KRgbMagenta);
73 void ExternalizeL(RWriteStream&) const
75 void GetOriginalSizeInTwips(TSize& a) const
77 a.iWidth = CPinkSquare::KWidth;
78 a.iHeight = CPinkSquare::KHeight;
83 class TDocModel : public MLayDoc
86 TDocModel(const TDesC& aDes)
87 : iDes(&aDes), iParagraphFormat(0)
89 void SetParagraphFormat(CParaFormat* a)
94 TInt LdDocumentLength() const
95 { return iDes->Length(); }
96 TInt LdToParagraphStart(TInt& a) const
99 if (a < LdDocumentLength())
101 a = iDes->Left(a).LocateReverse(0x2029);
102 a = a < 0? 0 : a + 1;
106 void GetParagraphFormatL(CParaFormat* aFormat, TInt) const
108 if (iParagraphFormat)
110 aFormat->CopyL(*iParagraphFormat);
115 tabStop.iTwipsPosition = 1000;
116 tabStop.iType = TTabStop::ELeftTab;
117 aFormat->StoreTabL(tabStop);
119 void GetChars(TPtrC& aView,TCharFormat& aFormat, TInt aStartPos)const
121 __ASSERT_ALWAYS(aStartPos <= LdDocumentLength(), Panic(EAccessOutsideText));
122 __ASSERT_ALWAYS(aStartPos >= 0, Panic(EAccessOutsideText));
126 if (aStartPos == LdDocumentLength())
129 aView.Set(iDes->Mid(aStartPos));
131 TInt GetPictureSizeInTwips(TSize& aSize, TInt aPos) const
133 if ((*iDes)[aPos] != KPictureCharacter)
135 aSize.iWidth = CPinkSquare::KWidth;
136 aSize.iHeight = CPinkSquare::KHeight;
139 CPicture* PictureHandleL(TInt aPos, TForcePictureLoad) const
141 if ((*iDes)[aPos] != KPictureCharacter)
143 return new(ELeave) CPinkSquare;
145 TBool EnquirePageBreak(TInt aPos, TInt aLength)const
147 return iDes->Mid(aPos, aLength).Locate(0x000C) < 0?
150 TBool SelectParagraphLabel(TInt)
152 void CancelSelectLabel()
156 CParaFormat* iParagraphFormat;
159 using namespace LocalToTInlineText;
161 class CTestTextView // slightly naughty
164 static void SetContextForFlickerFreeRedraw(CTextView* aView, CBitmapContext* aContext)
166 aView->iOffScreenContext = aContext;
170 // Utility functions to show contents of test data using test.Printf
172 _LIT(KAddressMarker, "> ");
174 _LIT(KLength, ", Length of Data = %d 16-bit words\r\n");
177 _LIT(KSingleString, "%S\r\n");
178 //_LIT(KDoubleString, "%s <%s>\r\n");
179 //_LIT(KLinefeed, "\r\n");
181 void PrintTestData (const TDesC& aTitle , const TDesC16& aData)
188 TInt length = aData.Length();
193 buffer.Append(aTitle);
194 buffer.Append(KLength);
197 buf.AppendFormat(buffer, length);
200 for (i = 0 ; i < length ; i += 8)
203 buffer.AppendNumFixedWidth(i, EHex, 8);
204 buffer += KAddressMarker;
206 end = ((length-i) >= 8) ? i+8 : length;
208 for (j = i ; j < end ; ++j)
210 buffer.AppendNumFixedWidth(aData[j], EHex, 4);
213 buffer += TPtrC(KSpaces().Ptr(), ((8-(j-i))*5)+4);
215 for (j = i ; j < end ; ++j)
219 buffer.Append(aData[j]);
226 buffer.ZeroTerminate();
228 buf.AppendFormat(KSingleString,buffer.Ptr());
234 void PrintTestData(const TDesC& aTitle, const TText16* aDataBuffer, const TInt aSize)
236 PrintTestData(aTitle, TPtrC16(aDataBuffer, aSize));
239 class CTestInlineTextSource : public CBase, public MTmInlineTextSource
242 static CTestInlineTextSource* NewL(TPtrC aText, TInt aNumChar);
243 ~CTestInlineTextSource();
245 public: // From MTmInlineTextSource
248 Reports the next position into which inline text should be inserted
250 The document position and character edge to start from.
252 The maximum length within which to report inline text.
253 It means that inline text at position X should be reported if
254 aFrom <= X && X < aFrom + aMaxLength.
255 Also report trailing inline text at position aFrom + aMaxLength
256 because it is really attached to the preceding character.
257 Always report only the first inline text position >= aFrom.
259 On exit the position of the next bit of inline text to be inserted.
260 N.B. The position of trailing text following position N and the
261 position of leading text preceding position N+1 are both
262 considered to be N+1 - and the trailing text comes first so if
263 aFrom specifies a leading edge do not report trailing edge
264 inline text unless its position is greater than aFrom.
265 A panic EBadReturnValue will result otherwise.
267 KErrNone if a position is found within the specified range,
268 KErrNotFound otherwise.
270 if KErrNone returned then aFrom <= aNext
271 && GetInlineText(aNext).Length() != 0
272 && (GetInlineText(X).Length() == 0 for all
273 TTmDocPos X such that aFrom < X && X < aNext)
274 else if KErrNotFound returned
275 GetInlineText(X).Length() == 0 for all
276 TTmDocPos X such that aFrom <= X && X < aFrom + aMaxLength
278 virtual TInt GetNextInlineTextPosition(const TTmDocPos& aFrom, TInt aMaxLength, TTmDocPos& aNext);
281 Gets a view of the text to be inserted at aAt.
283 Document position, including character edge, being queried.
285 Any inline text that should be attached to the specified character edge at aAt.
287 virtual TPtrC GetInlineText(const TTmDocPos& aAt);
290 CTestInlineTextSource();
291 void Construct(TPtrC aText, TInt aNumChar);
297 CTestInlineTextSource::CTestInlineTextSource()
301 CTestInlineTextSource* CTestInlineTextSource::NewL(TPtrC aText, TInt aNumChar)
303 CTestInlineTextSource* self= new(ELeave) CTestInlineTextSource();
304 self->Construct(aText, aNumChar);
308 CTestInlineTextSource::~CTestInlineTextSource()
312 void CTestInlineTextSource::Construct(TPtrC aText, TInt aNumChar)
318 // This takes two inputs, each of which is either a real position,
319 // greater than or equal to 0, or KErrNotFound. If both are real
320 // positions then it should return the lower. If one is a real position
321 // then it should be returned. If neither are a real position then
322 // KErrNone is returned. It is all done with pointers to TInts so that
323 // when I get the result I can tell which one it is.
324 TInt* CustomMin(TInt* aPtrPos1, TInt* aPtrPos2)
326 if (*aPtrPos2 == KErrNotFound)
328 if (*aPtrPos1 == KErrNotFound)
330 if (*aPtrPos1 <= *aPtrPos2)
336 TInt CTestInlineTextSource::GetNextInlineTextPosition(const TTmDocPos& aFrom, TInt aMaxLength, TTmDocPos& aNext)
343 _LIT(KSS4, "\x05c0");//Hebrew character to test right-to-left text
344 TInt from = aFrom.iPos;
346 if ((from > 0) && (!aFrom.iLeadingEdge))
347 from2--; // adjustment takes care of not returning trailing edge if at start pos
348 TInt pos1 = iText.Mid(from).Find(KSS1);
349 TInt pos2 = iText.Mid(from2).Find(KSS2);
350 TInt pos3 = iText.Mid(from).Find(KSS3);
351 TInt pos4 = iText.Mid(from2).Find(KSS3);
352 TInt pos5 = iText.Mid(from2).Find(KSS4);
353 if (pos1 >= 0 ) // adjustments so we compare like for like
354 pos1 += from - from2;
356 pos3 += from - from2;
357 // get the smallest real position, if any
358 TInt* ptrPos = CustomMin(CustomMin(&pos1, &pos3), CustomMin(CustomMin(&pos2, &pos4),&pos5));
359 if (pos1 > 0 ) // now adjust back
360 pos1 -= from - from2;
362 pos3 -= from - from2;
363 if (*ptrPos == KErrNotFound)
365 if ((ptrPos == &pos1) || (ptrPos == &pos3))
366 { // it was an A or C with leading text
367 aNext.iPos = *ptrPos + from;
368 aNext.iLeadingEdge = ETrue;
370 else if ((ptrPos == &pos2) || (ptrPos == &pos4))
371 { // it was an B oD with trailing text
372 aNext.iPos = *ptrPos + from2 + 1;
373 aNext.iLeadingEdge = EFalse;
375 else if (ptrPos == &pos5)
376 { // it was an Hebrew char with trailing text
377 aNext.iPos = *ptrPos + from2 + 1;
378 aNext.iLeadingEdge = EFalse;
382 // something has gone horribly wrong
385 if (aNext.iPos - aFrom.iPos > aMaxLength + (aNext.iLeadingEdge ? 0 : 1))
390 TPtrC CTestInlineTextSource::GetInlineText(const TTmDocPos& aAt)
394 if ((aAt.iPos == 0) && (!aAt.iLeadingEdge))
399 _LIT(KSS4, "\x05c0");//Hebrew character to test right-to-left text
402 if ((at2 > 0) && (!aAt.iLeadingEdge))
403 at2--; // adjustment takes care of not returning trailing edge if at start pos
405 TInt pos1 = iText.Mid(at).Find(KSS1);
406 TInt pos2 = iText.Mid(at2).Find(KSS2);
407 TInt pos3 = iText.Mid(at).Find(KSS3);
408 TInt pos4 = iText.Mid(at2).Find(KSS3);
409 TInt pos5 = iText.Mid(at2).Find(KSS4);
413 if ((pos1 == aAt.iPos) && aAt.iLeadingEdge)
421 else if (iNumChar == 2)
432 if ((pos2 + 1 == aAt.iPos) && !aAt.iLeadingEdge)
440 else if (iNumChar == 2)
448 if ((pos3 == 0) || (pos4 == 0))
450 if (((pos3 + at == aAt.iPos) && aAt.iLeadingEdge) || ((pos4 + at2 + 1 == aAt.iPos) && !aAt.iLeadingEdge))
458 else if (iNumChar == 2)
469 if ((pos5 + 1 == aAt.iPos) && !aAt.iLeadingEdge)
474 _LIT(KIS41, "\05be");
477 else if (iNumChar == 2)
479 _LIT(KIS42, "\05be\05be");
488 class CTestFormExtendedInterfaceProvider: public CBase, public MFormCustomInterfaceProvider
491 static CTestFormExtendedInterfaceProvider* NewL(TPtrC aText, TInt aNumChar);
492 ~CTestFormExtendedInterfaceProvider();
493 TAny* GetExtendedInterface(const TUid& aInterfaceId);
496 CTestFormExtendedInterfaceProvider();
497 void ConstructL(TPtrC aText, TInt aNumChar);
500 CTestInlineTextSource* iTestInlineTextSource; // Owned
504 CTestFormExtendedInterfaceProvider::CTestFormExtendedInterfaceProvider()
508 CTestFormExtendedInterfaceProvider* CTestFormExtendedInterfaceProvider::NewL(TPtrC aText, TInt aNumChar)
510 CTestFormExtendedInterfaceProvider* self= new(ELeave) CTestFormExtendedInterfaceProvider();
511 CleanupStack::PushL(self);
512 self->ConstructL(aText, aNumChar);
513 CleanupStack::Pop(); // self
517 CTestFormExtendedInterfaceProvider::~CTestFormExtendedInterfaceProvider()
519 delete iTestInlineTextSource;
522 void CTestFormExtendedInterfaceProvider::ConstructL(TPtrC aText, TInt aNumChar)
524 iTestInlineTextSource = CTestInlineTextSource::NewL(aText, aNumChar);
527 TAny* CTestFormExtendedInterfaceProvider::GetExtendedInterface( const TUid& aInterfaceId )
529 if (aInterfaceId == KInlineTextApiExtensionUid)
531 return static_cast<MTmInlineTextSource*>(iTestInlineTextSource);
539 // When referring to test cases the following shorthand is used:
540 // P Primary text that has inline text (leading and/or trailing) attached
542 // L Leading inline text attached to primary text
543 // T Trailing inline text attached to primary text
544 // X Secondary text that precedes primary text
545 // Y Secondary text that follows primary text
546 // S A special case of P where the primary text is a single character
547 // which has both leading and trailing inline text attached to it
549 // So, for example, X L-P will indicate some normal secondary text,
550 // followed by a <space>, followed by some primary text which will get
551 // leading text added to the start of it.
553 // When defining a test string the following are significant characters:
554 // A An 'A' will get zero or more 'a's of leading text attached to it
555 // B A 'B' will get zero or more 'b's of trailing text attached to it
556 // C A 'C' will get zero or more 'c's of both leading and trailing text
559 // All other characters are used normally.
560 // N.B. Spaces have significance as potential line-breaking points.
562 // So the example X L-P could be implemented as "ij Axyz". The 'A'
563 // indicating that leading inline text should be attatched to it.
565 // All test are carried out 3 times, once with inline text set to add zero
566 // characters for each inline text (i.e. switched off), once with inline
567 // text set to add one character for each inline text and once with inline
568 // text set to add two characters for each inline text.
570 // All tests use a special test graphics device and test graphics context
571 // to enable us to catch the output and use a special "pseudo" test font
572 // where all characters are exactly 10 pixels wide and 10 pixels high (to
573 // make the calculations easier).
575 // General combination tests
577 // These are simple tests, which would take a single line of input on the
578 // display and produce a single line of output on the display (if we
579 // weren't using a special CTestGraphicsContext to catch the output).
580 // These tests check that, without the complications of line-breaking,
581 // inline text is inserted where we expect it to be. This is why a display
582 // that is capable of taking 20 chars on a line is used for these tests.
584 // Future extensions:
585 // These tests could be extended to do similar tests using Right-to-Left
586 // (RtoL) text. This would require the inline text mechanism to be
587 // extended to also use RtoL trigger characters (and inserts). The
588 // expected results would need to take account of the fact that the output
589 // would be in display order rather than buffer order.
593 // These tests check specific cases that involve line-breaking. They
594 // produce more than one line of output, apart from some (not all) cases
595 // when inline text is switched off. To force the line-breaking these
596 // tests use a display that is obly capable of taking 10 chars on a line
597 // is used. Detailed info for each test is given in comments in the test
600 // Future extensions:
601 // These tests could be extended to check the behaviour of truncation and
602 // the insertion of an ellipsis. These tests could also be extended to
603 // include some RtoL examples.
605 static const TInt KTestCases = 18;
606 static const TInt KInlineTextOptions = 3;
607 static const TInt KVariants = 6;
609 static const TPtrC KTestStrings[KTestCases][KInlineTextOptions][KVariants] =
610 { // Start of General Combination tests
922 }, // End of General Combination tests
923 { // Start of Specific tests
925 // primary text with trailing inline text, secondary text secondary
926 // text won't fit on line
952 // secondary text, primary text with trailing inline text trailing
953 // text won't fit and there is no line breaking point inside primary
954 // text and the primary text plus trailing text will fit on next line
981 // secondary text, primary text with trailing inline text primary
982 // text won't fit and there is no line breaking point inside primary
983 // text and the primary text plus trailing text will fit on next line
1001 _S("ijklm uvwxyzB"),
1009 { // Test X L-P-T one
1010 // secondary text, primary text with leading and trailing inline text trailing
1011 // text won't fit and there is no line breaking point inside primary text and
1012 // the leading text plus primary text plus trailing text will fit on the next line
1038 { // Test X L-P-T two
1039 // secondary text, primary text with leading and trailing inline text primary
1040 // text won't fit and there is no line breaking point inside primary text and
1041 // the leading text plus primary text plus trailing text will fit on the next line
1067 { // Test X L-P-T three
1068 //secondary text, primary text with leading and trailing inline text leading
1069 // text won't fit and the leading text plus primary text plus trailing text
1070 // will fit on the next line
1072 _S("ijklmnop AxyzB"),
1080 _S("ijklmnop AxyzB"),
1088 _S("ijklmnop AxyzB"),
1095 } // End of Specific tests
1098 static const TInt KTestCount[KTestCases][KInlineTextOptions] =
1100 { // Start of General Combination tests
1151 1, // Test X L-P-T Y
1156 1, // Test X L-C-T Y
1159 }, // End of General Combination tests
1160 { // Start of Specific tests
1166 1, // Test X P-T one
1171 3, // Test X P-T two
1176 1, // Test X L-P-T one
1181 1, // Test X L-P-T two
1186 3, // Test X L-P-T three
1189 } // End of Specific tests
1192 void DoLineTestL(TDes& aText, CTextLayout* aLayout, CTestGraphicsDevice* aDevice, CTextView* aView, TInt aNumChar, TInt aIndex)
1194 aText = KTestStrings[aIndex][aNumChar][0];
1195 CTestFormExtendedInterfaceProvider* interfaceProvider = CTestFormExtendedInterfaceProvider::NewL(aText, aNumChar); // owned here
1196 aLayout->SetInterfaceProvider(interfaceProvider);
1197 CleanupStack::PushL(interfaceProvider);
1198 aDevice->LineArray().ResetLineArray();
1199 aView->HandleGlobalChangeL();
1200 // now that we've redrawn the actual ooutput (what went through DrawText(), including
1201 // any inline text) has been stored in the LineArray. So we#'ll have a look and see
1202 // if it contains what we expect it to.
1203 // Each line may produce one or more LineArray() entries as there is one created for
1204 // each call to DrawText()
1205 const TTestGCDisplayLine* line1 = 0;
1206 const TTestGCDisplayLine* line2 = 0;
1207 // Find out how many LineArray entries are expected for the output of this test
1208 TInt count = KTestCount[aIndex][aNumChar];
1209 // And test them (in reverse order, because it's easier)
1213 line1 = &(aDevice->LineArray().Line(4));
1214 line2 = aDevice->LineArray().Find(KTestStrings[aIndex][aNumChar][5]);
1215 TESTPOINT(0 != line1);
1216 TESTPOINT(0 != line2);
1217 TESTPOINT(line1->iLineData.Compare(line2->iLineData) == 0);
1219 line1 = &(aDevice->LineArray().Line(3));
1220 line2 = aDevice->LineArray().Find(KTestStrings[aIndex][aNumChar][4]);
1221 TESTPOINT(0 != line1);
1222 TESTPOINT(0 != line2);
1223 TESTPOINT(line1->iLineData.Compare(line2->iLineData) == 0);
1225 line1 = &(aDevice->LineArray().Line(2));
1226 line2 = aDevice->LineArray().Find(KTestStrings[aIndex][aNumChar][3]);
1227 TESTPOINT(0 != line1);
1228 TESTPOINT(0 != line2);
1229 TESTPOINT(line1->iLineData.Compare(line2->iLineData) == 0);
1231 line1 = &(aDevice->LineArray().Line(1));
1232 line2 = aDevice->LineArray().Find(KTestStrings[aIndex][aNumChar][2]);
1233 TESTPOINT(0 != line1);
1234 TESTPOINT(0 != line2);
1235 TESTPOINT(line1->iLineData.Compare(line2->iLineData) == 0);
1237 line1 = &(aDevice->LineArray().Line(0));
1238 line2 = aDevice->LineArray().Find(KTestStrings[aIndex][aNumChar][1]);
1239 TESTPOINT(0 != line1);
1240 TESTPOINT(0 != line2);
1241 // Can't always do a direct comparison of lines because same string
1242 // may appear in more than one line, so compare contents
1243 TESTPOINT(line1->iLineData.Compare(line2->iLineData) == 0);
1245 aLayout->SetInterfaceProvider(NULL);
1246 CleanupStack::PopAndDestroy(interfaceProvider);
1249 void GeneralCombinationTestsTextViewL(TDes& aText, CTextLayout* aLayout, CTestGraphicsDevice* aDevice, CTextView* aView, TInt aNumChar)
1251 // For all tests carried out from here up to 20 chars will fit on a line
1252 TESTPRINT(_L("Test L-P"));
1253 DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 0);
1254 TESTPRINT(_L("Test X L-P"));
1255 DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 1);
1256 TESTPRINT(_L("Test P-T"));
1257 DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 2);
1258 TESTPRINT(_L("Test P-T Y"));
1259 DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 3);
1260 TESTPRINT(_L("Test L-P-T"));
1261 DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 4);
1262 TESTPRINT(_L("Test L-C-T"));
1263 DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 5);
1264 TESTPRINT(_L("Test X L-P-T"));
1265 DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 6);
1266 TESTPRINT(_L("Test X L-C-T"));
1267 DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 7);
1268 TESTPRINT(_L("Test L-P-T Y"));
1269 DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 8);
1270 TESTPRINT(_L("Test L-C-T Y"));
1271 DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 9);
1272 TESTPRINT(_L("Test X L-P-T Y"));
1273 DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 10);
1274 TESTPRINT(_L("Test X L-C-T Y"));
1275 DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 11);
1278 void SpecificTestsTextViewL(TDes& aText, CTextLayout* aLayout, CTestGraphicsDevice* aDevice, CTextView* aView, TInt aNumChar)
1280 // For all tests carried out from here up to 10 chars will fit on a line
1281 TESTPRINT(_L("Test P-T B"));
1282 DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 12);
1283 TESTPRINT(_L("Test X P-T one"));
1284 DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 13);
1285 TESTPRINT(_L("Test X P-T two"));
1286 DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 14);
1287 TESTPRINT(_L("Test X L-P-T one"));
1288 DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 15);
1289 TESTPRINT(_L("Test X L-P-T two"));
1290 DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 16);
1291 TESTPRINT(_L("Test X L-P-T three"));
1292 DoLineTestL(aText, aLayout, aDevice, aView, aNumChar, 17);
1295 void DoLineTestForINC141914L(TDes& aText, CTextLayout* aLayout, CTestGraphicsDevice* aDevice, CTextView* aView)
1298 * This case is to test whether or not inline text will find the correct format after changing the text content.
1299 * In bytecode, there is one value to record the postion(iInlineTextFormat) to which inline text chunk attaches,
1300 * INC141914 is raised because this value is not updated correctly after text change.
1301 * The text string is as the following 3 lines:
1305 * Where the 'b' is the inline text.
1308 * delete 5 leading '1's in the first line,
1310 * delete 5 leading '2's in the second line.
1311 * after the 2 steps, inline text is still able to use iInlineTextFormat to find its attached text string
1313 aText = _S("\x31\x31\x31\x31\x31\x31\x3B\x2029\x32\x32\x32\x32\x32\x32\x3B\x2029\x77\x78\x79\x42\x7A");
1314 CTestFormExtendedInterfaceProvider* interfaceProvider = CTestFormExtendedInterfaceProvider::NewL(aText, 1); // owned here
1315 aLayout->SetInterfaceProvider(interfaceProvider);
1316 CleanupStack::PushL(interfaceProvider);
1317 aDevice->LineArray().ResetLineArray();
1318 aView->HandleGlobalChangeL();
1320 aView->HandleInsertDeleteL(TCursorSelection(0,0),5);
1322 aView->HandleInsertDeleteL(TCursorSelection(3,3),5);
1324 aLayout->SetInterfaceProvider(NULL);
1325 CleanupStack::PopAndDestroy(interfaceProvider);
1328 void DoLineTestForINC143086L(TDes& aText, CTextLayout* aLayout, CTestGraphicsDevice* aDevice, CTextView* aView)
1331 * This case is to test inline text behaviour for right-to-left text
1332 * The text string is as the following characters:
1333 * \x5e0\x5e1\x5e2\x5e3\x5e4\x5c0\x5e5;
1334 * Where the '\x5c0' is the inline text.
1336 aText = _S("\x5e0\x5e1\x5e2\x5e3\x5e4\x5c0\x5e5");
1337 CTestFormExtendedInterfaceProvider* interfaceProvider = CTestFormExtendedInterfaceProvider::NewL(aText, 1); // owned here
1338 aLayout->SetInterfaceProvider(interfaceProvider);
1339 CleanupStack::PushL(interfaceProvider);
1340 aDevice->LineArray().ResetLineArray();
1341 aView->HandleGlobalChangeL();
1343 aLayout->SetInterfaceProvider(NULL);
1344 CleanupStack::PopAndDestroy(interfaceProvider);
1347 // aNumChar determines what kind of inline text is in force
1348 // 0 means no inline text, 1 means insert a single char for
1349 // each possible inline text and 2 means insert two chars
1350 void RunGeneralCombinationTestsL(TInt aNumChar)
1352 CActiveScheduler* scheduler = new(ELeave) CActiveScheduler;
1353 CleanupStack::PushL(scheduler);
1354 CActiveScheduler::Install(scheduler);
1356 TDocModel docModel(text);
1357 // This time make it capable of 20 chars + a couple of spare pixels
1358 // so all of these tests should result in a single line of output
1359 TRect displayRect(0, 0, KDisplayWidthWide, KDisplayHeight);
1360 CTextLayout* layout = CTextLayout::NewL(&docModel, displayRect.Width());
1361 CleanupStack::PushL(layout);
1362 CTestGraphicsDevice* device = CTestGraphicsDevice::NewL(displayRect.Size(), 0);
1363 CleanupStack::PushL(device);
1364 CTextView* view = CTextView::NewL(layout, displayRect, device, device, 0, 0, 0);
1365 CleanupStack::PushL(view);
1366 // This is used to force the use of CTestGraphicsContext instead of a normal one
1367 CWindowGc* offScreenContext;
1368 User::LeaveIfError(device->CreateContext(offScreenContext));
1369 CleanupStack::PushL(offScreenContext);
1370 CTestTextView::SetContextForFlickerFreeRedraw(view, offScreenContext);
1372 GeneralCombinationTestsTextViewL(text, layout, device, view, aNumChar);
1374 CleanupStack::PopAndDestroy(offScreenContext);
1375 CleanupStack::PopAndDestroy(view);
1376 CleanupStack::PopAndDestroy(device);
1377 CleanupStack::PopAndDestroy(layout);
1378 CleanupStack::PopAndDestroy(scheduler);
1381 // aNumChar determines what kind of inline text is in force
1382 // 0 means no inline text, 1 means insert a single char for
1383 // each possible inline text and 2 means insert two chars
1384 void RunSpecificTestsL( TInt aNumChar)
1386 // Note: If you need to move these heap checks any further "in" to focus
1387 // on a specific test then you will have to move all the setup code in as
1388 // well - and still preserve the two different display widths in use
1390 CActiveScheduler* scheduler = new(ELeave) CActiveScheduler;
1391 CleanupStack::PushL(scheduler);
1392 CActiveScheduler::Install(scheduler);
1394 TDocModel docModel(text);
1395 // This time make it capable of 10 chars + a couple of spare pixels
1396 // so that line wrapping will occur
1397 TRect displayRect(0, 0, KDisplayWidthThin, KDisplayHeight);
1398 CTextLayout* layout = CTextLayout::NewL(&docModel, displayRect.Width());
1399 CleanupStack::PushL(layout);
1400 CTestGraphicsDevice* device = CTestGraphicsDevice::NewL(displayRect.Size(), 0);
1401 CleanupStack::PushL(device);
1402 CTextView* view = CTextView::NewL(layout, displayRect, device, device, 0, 0, 0);
1403 CleanupStack::PushL(view);
1404 // This is used to force the use of CTestGraphicsContext instead of a normal one
1405 CWindowGc* offScreenContext;
1406 User::LeaveIfError(device->CreateContext(offScreenContext));
1407 CleanupStack::PushL(offScreenContext);
1408 CTestTextView::SetContextForFlickerFreeRedraw(view, offScreenContext);
1410 SpecificTestsTextViewL(text, layout, device, view, aNumChar);
1412 CleanupStack::PopAndDestroy(offScreenContext);
1413 CleanupStack::PopAndDestroy(view);
1414 CleanupStack::PopAndDestroy(device);
1415 CleanupStack::PopAndDestroy(layout);
1416 CleanupStack::PopAndDestroy(scheduler);
1421 void RunTestsForINC141914L()
1424 CActiveScheduler* scheduler = new(ELeave) CActiveScheduler;
1425 CleanupStack::PushL(scheduler);
1426 CActiveScheduler::Install(scheduler);
1428 TDocModel docModel(text);
1429 // This time make it capable of 10 chars + a couple of spare pixels
1430 // so that line wrapping will occur
1431 TRect displayRect(0, 0, KDisplayWidthWide, KDisplayHeight);
1432 CTextLayout* layout = CTextLayout::NewL(&docModel, displayRect.Width());
1433 CleanupStack::PushL(layout);
1434 CTestGraphicsDevice* device = CTestGraphicsDevice::NewL(displayRect.Size(), 0);
1435 CleanupStack::PushL(device);
1436 CTextView* view = CTextView::NewL(layout, displayRect, device, device, 0, 0, 0);
1437 CleanupStack::PushL(view);
1438 // This is used to force the use of CTestGraphicsContext instead of a normal one
1439 CWindowGc* offScreenContext;
1440 User::LeaveIfError(device->CreateContext(offScreenContext));
1441 CleanupStack::PushL(offScreenContext);
1442 CTestTextView::SetContextForFlickerFreeRedraw(view, offScreenContext);
1444 DoLineTestForINC141914L(text, layout, device, view);
1445 DoLineTestForINC143086L(text, layout, device, view);
1447 CleanupStack::PopAndDestroy(offScreenContext);
1448 CleanupStack::PopAndDestroy(view);
1449 CleanupStack::PopAndDestroy(device);
1450 CleanupStack::PopAndDestroy(layout);
1451 CleanupStack::PopAndDestroy(scheduler);
1455 TVerdict CTInLineTextStep::doTestStepL()
1457 SetTestStepResult(EPass);
1461 TESTPRINT(KTInlineText);
1462 TESTPRINT(_L(" @SYMTestCaseID:SYSLIB-FORM-LEGACY-INLINETEXT-0001 General combination tests - no inline text "));
1463 TInt error = RFbsSession::Connect();
1464 if (error == KErrNotFound)
1467 error = RFbsSession::Connect();
1469 TEST(error == KErrNone);
1470 TRAP(error, RunGeneralCombinationTestsL(0));
1471 TEST(error == KErrNone);
1472 TESTPRINT(_L("General combination tests - single char inline text"));
1473 TRAP(error, RunGeneralCombinationTestsL(1));
1474 TEST(error == KErrNone);
1475 TESTPRINT(_L("General combination tests - multi char inline text"));
1476 TRAP(error, RunGeneralCombinationTestsL(2));
1477 TEST(error == KErrNone);
1478 TESTPRINT(_L("Specific tests - no inline text"));
1479 TRAP(error, RunSpecificTestsL(0));
1480 TEST(error == KErrNone);
1481 TESTPRINT(_L("Specific tests - single char inline text"));
1482 TRAP(error, RunSpecificTestsL(1));
1483 TEST(error == KErrNone);
1484 TESTPRINT(_L("Specific tests - multi char inline text"));
1485 TRAP(error, RunSpecificTestsL(2));
1486 TEST(error == KErrNone);
1488 TESTPRINT(_L("Defect tests - for INC141914"));
1489 TRAP(error, RunTestsForINC141914L());
1490 TEST(error == KErrNone);
1492 RFbsSession::Disconnect();
1494 User::Heap().Check();
1495 return TestStepResult();