|
1 /* |
|
2 * Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * TInterpreter.cpp unit tests for RTmBoundingRectInterpreter |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 #include "TestPicture.h" |
|
21 #include "TestLayout.h" |
|
22 #include "TGraphicsContext.h" |
|
23 #include "TMINTERP.H" |
|
24 |
|
25 #include <txtrich.h> |
|
26 #include <e32test.h> |
|
27 |
|
28 _LIT(KLeftToRight1, "abc \x5D0 def abc \x5D0\x5D1\x5D2 \x5D0\x5D1\x5D2 xyz abc a\tb\tc\td\te."); |
|
29 _LIT(KLeftToRight2, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); |
|
30 _LIT(KContingentBreak, "\xFFFC"); |
|
31 |
|
32 /** |
|
33 Checks if one region is a subset of another. |
|
34 @param aRegion |
|
35 The potential superset. |
|
36 @param aPotentialSubset |
|
37 The potential subset. |
|
38 @return |
|
39 ETrue if and only if aPotentialSubset is contained within aRegion. |
|
40 @internalComponent |
|
41 */ |
|
42 TBool IsSubsetL(const TRegion& aRegion, const TRegion& aPotentialSubset) |
|
43 { |
|
44 RRegion sub; |
|
45 sub.Copy(aPotentialSubset); |
|
46 sub.SubRegion(aRegion); |
|
47 if (sub.CheckError()) |
|
48 User::Leave(KErrNoMemory); |
|
49 return sub.IsEmpty(); |
|
50 } |
|
51 |
|
52 /** |
|
53 Checks if two regions are equal. |
|
54 @param aA First region. |
|
55 @param aB Second region. |
|
56 @return |
|
57 ETrue if the regions are equal, false otherwise. |
|
58 @internalComponent |
|
59 */ |
|
60 TBool RegionsEqualL(const TRegion& aA, const TRegion& aB) |
|
61 { |
|
62 return IsSubsetL(aA, aB) && IsSubsetL(aB, aA); |
|
63 } |
|
64 |
|
65 /** |
|
66 Gets the region corresponding to the selection. Builds it up by adding |
|
67 selections together. The selections are at (n * aStartStep, aEnd + n * |
|
68 aEndStep) for n <- {0, 1, 2...}. The iteration ends when either the start would |
|
69 be beyond the length of the document or when the start is at 0 and the end is |
|
70 beyond the length of the document. |
|
71 @param aRegion Returns the region. |
|
72 @param aLayout The layout to get the selection of. |
|
73 @param aStartStep How different the starts of successive selections are. |
|
74 @param aEnd The end of the first selection. |
|
75 @param aEndStep How different the ends of the successive selections are. |
|
76 |
|
77 @internalComponent |
|
78 */ |
|
79 void GetSelectionL(TRegion& aRegion, CTestTmTextLayout& aLayout, |
|
80 TInt aStartStep, TInt aEnd, TInt aEndStep) |
|
81 { |
|
82 aRegion.Clear(); |
|
83 TRect rect; |
|
84 TInt documentLength = aLayout.Source().DocumentLength(); |
|
85 TInt start = 0; |
|
86 while (start < documentLength && !(documentLength < aEnd && start == 0)) |
|
87 { |
|
88 TTmInterpreterParam param(aLayout.Layout()); |
|
89 RTmBoundingRectInterpreter interp(aLayout.Source(), param); |
|
90 if (interp.FirstRect(start, aEnd, rect)) |
|
91 { |
|
92 aRegion.AddRect(rect); |
|
93 while (interp.NextRect(rect)) |
|
94 aRegion.AddRect(rect); |
|
95 } |
|
96 start += aStartStep; |
|
97 aEnd += aEndStep; |
|
98 interp.Close(); |
|
99 } |
|
100 if (aRegion.CheckError()) |
|
101 User::Leave(KErrNoMemory); |
|
102 } |
|
103 |
|
104 /** |
|
105 Tests RTmBoundingRectInterpreter for a particular piece of text. |
|
106 @internalComponent |
|
107 */ |
|
108 void TestTextL(RTest& aTest, CTestTmTextLayout& aLayout) |
|
109 { |
|
110 RRegion region1; |
|
111 RRegion region2; |
|
112 RRegion region3; |
|
113 CleanupClosePushL(region1); |
|
114 CleanupClosePushL(region2); |
|
115 CleanupClosePushL(region3); |
|
116 |
|
117 GetSelectionL(region1, aLayout, 1, 1, 1); |
|
118 GetSelectionL(region2, aLayout, 0, 1, 1); |
|
119 GetSelectionL(region3, aLayout, 0, aLayout.Source().DocumentLength(), 1); |
|
120 |
|
121 aTest(RegionsEqualL(region1, region2)); |
|
122 aTest(RegionsEqualL(region1, region3)); |
|
123 |
|
124 CleanupStack::PopAndDestroy(®ion3); |
|
125 CleanupStack::PopAndDestroy(®ion2); |
|
126 CleanupStack::PopAndDestroy(®ion1); |
|
127 } |
|
128 |
|
129 |
|
130 void TestsL(RTest& aTest) |
|
131 { |
|
132 CParaFormatLayer* paraLayer = CParaFormatLayer::NewL(); |
|
133 CleanupStack::PushL(paraLayer); |
|
134 CCharFormatLayer* charLayer = CCharFormatLayer::NewL(); |
|
135 CleanupStack::PushL(charLayer); |
|
136 CRichText* richText = CRichText::NewL(paraLayer, charLayer); |
|
137 CleanupStack::PushL(richText); |
|
138 |
|
139 aTest.Next(_L("RTmBoundingRectInterpreter consistency of coverage")); |
|
140 richText->Reset(); |
|
141 richText->InsertL(0, KLeftToRight1); |
|
142 CTestTmTextLayout* text1 = CTestTmTextLayout::NewLC(*richText, 100); |
|
143 TSize pictureSize(15, 15); |
|
144 CTestPicture* picture = new (ELeave) CTestPicture; |
|
145 picture->SetSizeInPixels( pictureSize, text1->Device() ); |
|
146 TPictureHeader pictureHeader; |
|
147 pictureHeader.iPicture = picture; |
|
148 pictureHeader.iSize = pictureSize; |
|
149 richText->InsertL(19, pictureHeader); |
|
150 TTmReformatParam param; |
|
151 param.iStartChar = 19; |
|
152 param.iOldLength = 0; |
|
153 param.iNewLength = 1; |
|
154 param.iMaxExtraLines = KMaxTInt; |
|
155 param.iParFormatChanged = ETrue; |
|
156 param.iParInvalid = EFalse; |
|
157 TTmReformatResult out; |
|
158 text1->FormatL(param, out); |
|
159 TestTextL(aTest, *text1); |
|
160 |
|
161 //Test for finding text chunks adjoining a given document position |
|
162 text1->TestAdjacentChunks(); |
|
163 |
|
164 CleanupStack::PopAndDestroy(text1); |
|
165 CleanupStack::PopAndDestroy(richText); |
|
166 CleanupStack::PopAndDestroy(charLayer); |
|
167 CleanupStack::PopAndDestroy(paraLayer); |
|
168 } |
|
169 |
|
170 |
|
171 /** |
|
172 @SYMTestCaseID SYSLIB-FORM-UT-1591 |
|
173 @SYMTestCaseDesc Tests to make sure when contingent line breaks, "\xFFFC", are inserted into richtext |
|
174 (with and without a picture attached) and FormatL is called it does not lead to a |
|
175 panic in 'IsLegalBreakBeforeL' or 'IsLegalBreakAfterL'. |
|
176 @SYMTestPriority High |
|
177 @SYMTestActions Insert some richtext, then insert a TPictureHeader into the text (which inserts a |
|
178 contingent line break), then call FormatL. Then insert just a contingent line break, |
|
179 with no TPictureHeader associated with it and call FormatL (for IsLegalBreakAfterL). |
|
180 Then repeat the process, but making sure the text is scanned in the opposite |
|
181 direction, so IsLegalBreakBeforeL is called. |
|
182 @SYMTestExpectedResults Test must not fail |
|
183 @SYMDEF DEF077884 |
|
184 */ |
|
185 |
|
186 void Def077884L(RTest& aTest) |
|
187 { |
|
188 TInt testStartLength = 52; |
|
189 TInt testEndLength = 56; |
|
190 |
|
191 CParaFormatLayer* paraLayer = CParaFormatLayer::NewL(); |
|
192 CleanupStack::PushL(paraLayer); |
|
193 CCharFormatLayer* charLayer = CCharFormatLayer::NewL(); |
|
194 CleanupStack::PushL(charLayer); |
|
195 CRichText* richText = CRichText::NewL(paraLayer, charLayer); |
|
196 CleanupStack::PushL(richText); |
|
197 |
|
198 aTest.Next(_L(" @SYMTestCaseID:SYSLIB-FORM-UT-1591 DEF077884: TSourcePictureBreaker crashes when picture not found. ")); |
|
199 |
|
200 |
|
201 richText->Reset(); |
|
202 |
|
203 richText->InsertL(0, KLeftToRight2); |
|
204 |
|
205 aTest(testStartLength == richText->DocumentLength()); |
|
206 |
|
207 CTestTmTextLayout* text1 = CTestTmTextLayout::NewLC(*richText, 100); |
|
208 |
|
209 TTmReformatResult out; |
|
210 TTmReformatParam param; |
|
211 param.iStartChar = 0; |
|
212 param.iOldLength = 0; |
|
213 param.iNewLength = 1; |
|
214 param.iMaxExtraLines = KMaxTInt; |
|
215 param.iParFormatChanged = ETrue; |
|
216 param.iParInvalid = EFalse; |
|
217 |
|
218 richText->InsertL(14, KContingentBreak); // Insert a contingent linebreak with no picture |
|
219 |
|
220 text1->FormatL(param, out); // Scans the text from right to left. |
|
221 |
|
222 |
|
223 TSize pictureSize(100, 100); |
|
224 CTestPicture* picture = new (ELeave) CTestPicture; |
|
225 picture->SetSizeInPixels(pictureSize, text1->Device()); |
|
226 |
|
227 TPictureHeader pictureHeader; |
|
228 pictureHeader.iPicture = picture; |
|
229 pictureHeader.iSize = pictureSize; |
|
230 |
|
231 richText->InsertL(15, pictureHeader); // Insert a contingent linebreak with picture |
|
232 |
|
233 param.iOldLength = 1; |
|
234 param.iNewLength = 2; |
|
235 |
|
236 text1->FormatL(param, out); // Scans the text from right to left. |
|
237 |
|
238 |
|
239 TTmFormatParam formatParam; |
|
240 formatParam.iFlags = 0; |
|
241 // iFlags now need to be set to make sure the text is scanned in the opposite direction when |
|
242 // FormatL is called. |
|
243 formatParam.iFlags = formatParam.iFlags | TTmFormatParamBase::ELegalLineBreaksOnly; |
|
244 formatParam.iFlags = formatParam.iFlags | TTmFormatParamBase::EWrap; |
|
245 formatParam.iWrapWidth = 12; |
|
246 formatParam.iMaxHeight = 100; |
|
247 formatParam.iMaxLines = 10; |
|
248 formatParam.iEllipsis = 0xFFFF; |
|
249 formatParam.iStartChar = 0; |
|
250 formatParam.iEndChar = 50; |
|
251 formatParam.iLineInPar = 0; |
|
252 |
|
253 param.iOldLength = 2; |
|
254 param.iNewLength = 3; |
|
255 |
|
256 CTmTextLayout* text2 = new (ELeave) CTmTextLayout; |
|
257 |
|
258 text2->SetTextL(text1->Source(),formatParam); |
|
259 |
|
260 richText->InsertL(28, KContingentBreak); // Insert a contingent linebreak with no picture |
|
261 |
|
262 text2->FormatL(formatParam, param, out); // Scans the text from left to right. |
|
263 |
|
264 |
|
265 CTestPicture* picture2 = new (ELeave) CTestPicture; |
|
266 picture2->SetSizeInPixels( pictureSize, text1->Device() ); |
|
267 |
|
268 TPictureHeader pictureHeader2; |
|
269 pictureHeader2.iPicture = picture2; |
|
270 pictureHeader2.iSize = pictureSize; |
|
271 |
|
272 richText->InsertL(34, pictureHeader2); // Insert a contingent linebreak with picture |
|
273 |
|
274 param.iOldLength = 3; |
|
275 param.iNewLength = 4; |
|
276 |
|
277 text2->FormatL(formatParam, param, out); // Scans the text from left to right. |
|
278 |
|
279 |
|
280 TestTextL(aTest, *text1); |
|
281 |
|
282 aTest(testEndLength == richText->DocumentLength()); |
|
283 |
|
284 CleanupStack::PopAndDestroy(text1); |
|
285 CleanupStack::PopAndDestroy(richText); |
|
286 CleanupStack::PopAndDestroy(charLayer); |
|
287 CleanupStack::PopAndDestroy(paraLayer); |
|
288 } |
|
289 |
|
290 /** |
|
291 Tests RTmBoundingRectInterpreter. |
|
292 @internalComponent |
|
293 */ |
|
294 void RunTestsL(RTest& aTest) |
|
295 { |
|
296 TestsL(aTest); |
|
297 Def077884L(aTest); |
|
298 } |
|
299 |
|
300 /** |
|
301 Tests RTmBoundingRectInterpreter. |
|
302 @internalComponent |
|
303 */ |
|
304 TInt E32Main() |
|
305 { |
|
306 RTest rtest(_L("TInterpreter unit")); |
|
307 CTrapCleanup* TrapCleanup = CTrapCleanup::New(); |
|
308 rtest.Start(_L("Start TInterpreter.exe Tests")); |
|
309 TRAPD(err, RunTestsL(rtest)); |
|
310 rtest.End(); |
|
311 delete TrapCleanup; |
|
312 return err; |
|
313 } |
|
314 |