|
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 * CTextLayout implementation using the TAGMA text formatting system. |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 #include <txtlaydc.h> |
|
21 #include "FRMTLAY.H" |
|
22 #include "FRMCONST.H" |
|
23 #include "FORMUTIL.H" |
|
24 |
|
25 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS |
|
26 #include "FRMCONST_INTERNAL.H" |
|
27 #include "FRMCONST_PARTNER.H" |
|
28 #include "TAGMA_INTERNAL.H" |
|
29 #include "FRMTLAY_INTERNAL.H" |
|
30 #endif |
|
31 |
|
32 const TInt KMaxExtraLines = 10; // maximum number of lines to format after the current and following lines |
|
33 // before using background formatting |
|
34 // during page down/up, the number of lines that should remain visible after |
|
35 // the scroll, counting from the first line that is not completely visible. |
|
36 // i.e. setting this to 0 means always scroll KMaxProportionOfScreenToScroll. |
|
37 // setting it to 1 means make sure that no lines are ever both partially off the |
|
38 // top/bottom before the scroll and partially visible off the bottom/top after |
|
39 // the scroll. |
|
40 // setting it to any number higher means keep that number -1 lines completely |
|
41 // visible before and after the scroll. |
|
42 const TInt KNumberOfLinesToKeepVisibleDuringScroll = 2; |
|
43 /** maximum scroll proportions in thousandths. This overrides |
|
44 the KNumberOfLinesToKeepVisibleDuringScroll constant.*/ |
|
45 const TInt KMaxProportionOfScreenToScroll = 1000; |
|
46 /** minimum scroll proportions in thousandths. This overrides |
|
47 the KNumberOfLinesToKeepVisibleDuringScroll constant.*/ |
|
48 const TInt KMinProportionOfScreenToScroll = 600; |
|
49 |
|
50 /** |
|
51 Tests for a high surrogate. |
|
52 @param a UTF16 value. |
|
53 @return ETrue if argument is a high surrogate. |
|
54 @internalComponent |
|
55 */ |
|
56 inline TBool IsHighSurrogate(TText a) { return 0xD800 == (a & 0xFC00); } |
|
57 /** |
|
58 Tests for a low surrogate. |
|
59 @param a UTF16 value. |
|
60 @return ETrue if argument is a high surrogate. |
|
61 @internalComponent |
|
62 */ |
|
63 inline TBool IsLowSurrogate(TText a) { return 0xDC00 == (a & 0xFC00); } |
|
64 /** |
|
65 Adds a high surrogate to a low surrogate to create a supplementary character. |
|
66 @param aHigh UTF16 high surrogate. |
|
67 @param aLow UTF16 low surrogate. |
|
68 @return Supplementary character represented by the pair <aHigh, aLow>. |
|
69 @pre aHigh is a high surrogate and aLow is a low surrogate. |
|
70 @internalComponent |
|
71 */ |
|
72 inline TChar PairSurrogates(TText aHigh, TText aLow) |
|
73 { |
|
74 return ((aHigh - 0xd7f7) << 10) + aLow; |
|
75 } |
|
76 |
|
77 /** |
|
78 Constructs an iterator over the text referenced by aSource. |
|
79 @param aSource The source of the text to be iterated over. |
|
80 */ |
|
81 CTextLayout::TUtf32SourceCache::TUtf32SourceCache(const MTmSource& aSource) |
|
82 : iSource(&aSource), iCurrentViewIndex(-1) |
|
83 { |
|
84 } |
|
85 |
|
86 /** |
|
87 Constructs an iterator over the text formatted by aLayout. |
|
88 @param aLayout The formatter of the text to be iterated over. |
|
89 */ |
|
90 CTextLayout::TUtf32SourceCache::TUtf32SourceCache(const CTextLayout& aLayout) |
|
91 : iSource(aLayout.iSource), iCurrentViewIndex(-1) |
|
92 { |
|
93 } |
|
94 |
|
95 /** |
|
96 Gets the specified character without uniting surrogate pairs. |
|
97 @param aIndex The document position to retrieve. |
|
98 @pre 0 <= aIndex && aIndex < {document length} |
|
99 */ |
|
100 TText CTextLayout::TUtf32SourceCache::GetUtf16(TInt aIndex) |
|
101 { |
|
102 TTmCharFormat dummy; |
|
103 if (aIndex < iCurrentViewIndex) |
|
104 { |
|
105 iCurrentViewIndex = 0; |
|
106 iSource->GetText(iCurrentViewIndex, iCurrentView, dummy); |
|
107 } |
|
108 TInt currentViewEnd = iCurrentViewIndex + iCurrentView.Length(); |
|
109 while (currentViewEnd <= aIndex) |
|
110 { |
|
111 TInt difference = aIndex - iCurrentViewIndex; |
|
112 TInt newIndex = aIndex - (difference >> 1); |
|
113 iCurrentViewIndex = newIndex < currentViewEnd? |
|
114 currentViewEnd : newIndex; |
|
115 iSource->GetText(iCurrentViewIndex, iCurrentView, dummy); |
|
116 currentViewEnd = iCurrentViewIndex + iCurrentView.Length(); |
|
117 } |
|
118 return iCurrentView[aIndex - iCurrentViewIndex]; |
|
119 } |
|
120 |
|
121 /** |
|
122 Gets the specified character, uniting surrogate pairs if appropriate. |
|
123 @param aIndex |
|
124 The document position to retrive. |
|
125 @return |
|
126 The character at position aIndex. If aIndex is at the first code of a |
|
127 surrogate pair, the full character is returned. If it is the second of a |
|
128 valid surrogate pair or an unpaired surrogate, the surrogate is returned. |
|
129 */ |
|
130 TChar CTextLayout::TUtf32SourceCache::GetUtf32(TInt aIndex) |
|
131 { |
|
132 TText code = GetUtf16(aIndex); |
|
133 if (IsHighSurrogate(code) && iSource->DocumentLength() < aIndex + 1) |
|
134 { |
|
135 TText code2 = GetUtf16(aIndex + 1); |
|
136 if (IsLowSurrogate(code2)) |
|
137 return PairSurrogates(code, code2); |
|
138 } |
|
139 return code; |
|
140 } |
|
141 |
|
142 /** Allocates and constructs a CTextLayout object. By default, the formatting |
|
143 is set to the entire document (EFFormatAllText). |
|
144 |
|
145 The text needs to be reformatted after a call to this function. |
|
146 |
|
147 @param aDoc Pointer to the MLayDoc implementation that is the source of the |
|
148 text and formatting information. Must not be NULL or a panic occurs. |
|
149 @param aWrapWidth The wrapping width in pixels. |
|
150 @return Pointer to the new CTextLayout object. */ |
|
151 EXPORT_C CTextLayout *CTextLayout::NewL(MLayDoc *aLayDoc,TInt aWrapWidth) |
|
152 { |
|
153 CTextLayout* t = new(ELeave) CTextLayout; |
|
154 CleanupStack::PushL(t); |
|
155 t->ConstructL(aLayDoc,aWrapWidth); |
|
156 CleanupStack::Pop(); |
|
157 return t; |
|
158 } |
|
159 |
|
160 EXPORT_C CTextLayout::CTextLayout(): |
|
161 iText(NULL), |
|
162 iExcessHeightRequired(0), |
|
163 iWnd(NULL), |
|
164 iBeginRedrawCount(0), |
|
165 iRedrawRect(), |
|
166 iTextViewCursorPos(NULL), |
|
167 iIsWndInExternalRedraw(EFalse), |
|
168 iUnformattedStart(KMaxTInt), |
|
169 iHighlightExtensions(NULL), |
|
170 iSource(NULL) |
|
171 { |
|
172 } |
|
173 |
|
174 /** Constructs an object with a text source of aLayDoc and a wrap width of |
|
175 aWrapWidth, with wrapping turned on. |
|
176 */ |
|
177 EXPORT_C void CTextLayout::ConstructL(MLayDoc *aLayDoc,TInt aWrapWidth) |
|
178 { |
|
179 iHighlightExtensions = new(ELeave) TTmHighlightExtensions; |
|
180 CleanupStack::PushL(iHighlightExtensions); |
|
181 iHighlightExtensions->SetAll(0); |
|
182 |
|
183 iText = new(ELeave) CTmTextLayout; |
|
184 CleanupStack::PushL(iHighlightExtensions); |
|
185 |
|
186 iSource = new(ELeave) TLayDocTextSource; |
|
187 iSource->iLayDoc = aLayDoc; |
|
188 SetWrapWidth(aWrapWidth); |
|
189 SetAmountToFormat(EFFormatAllText); |
|
190 |
|
191 CleanupStack::Pop(2); |
|
192 } |
|
193 |
|
194 EXPORT_C CTextLayout::~CTextLayout() |
|
195 { |
|
196 delete iHighlightExtensions; |
|
197 iHighlightExtensions = NULL; |
|
198 delete iText; |
|
199 iText = NULL; |
|
200 delete iSource; |
|
201 iSource = NULL; |
|
202 } |
|
203 |
|
204 void CTextLayout::SetWindow(RWindow* aWnd) |
|
205 { |
|
206 iWnd = aWnd; |
|
207 } |
|
208 |
|
209 void CTextLayout::SetReadyToRedraw() |
|
210 { |
|
211 iReadyToRedraw = ETrue; |
|
212 } |
|
213 |
|
214 void CTextLayout::BeginRedraw(const TRect& aRect) |
|
215 { |
|
216 if(!iReadyToRedraw) |
|
217 return; |
|
218 |
|
219 if (0 == iBeginRedrawCount++) |
|
220 { |
|
221 iRedrawRect = aRect; |
|
222 if (NULL != iWnd) |
|
223 { |
|
224 if (iWnd->GetDrawRect() == TRect::EUninitialized) |
|
225 { |
|
226 iWnd->Invalidate(aRect); |
|
227 iWnd->BeginRedraw(aRect); |
|
228 } |
|
229 else |
|
230 iIsWndInExternalRedraw = ETrue; |
|
231 } |
|
232 } |
|
233 } |
|
234 |
|
235 void CTextLayout::EndRedraw() |
|
236 { |
|
237 if(!iReadyToRedraw) |
|
238 return; |
|
239 |
|
240 __ASSERT_ALWAYS(iBeginRedrawCount > 0, Panic(EInvalidRedraw)); |
|
241 |
|
242 if (0 == --iBeginRedrawCount) |
|
243 { |
|
244 if (NULL != iWnd) |
|
245 { |
|
246 if (!iIsWndInExternalRedraw) |
|
247 { |
|
248 iWnd->EndRedraw(); |
|
249 iRedrawRect = TRect(); |
|
250 } |
|
251 else |
|
252 iIsWndInExternalRedraw = EFalse; |
|
253 } |
|
254 } |
|
255 } |
|
256 |
|
257 void CTextLayout::SetExternalDraw(const TRect& aRect) |
|
258 { |
|
259 __ASSERT_ALWAYS(0 == iBeginRedrawCount, Panic(EInvalidRedraw)); |
|
260 iBeginRedrawCount++; |
|
261 iRedrawRect = aRect; |
|
262 } |
|
263 |
|
264 void CTextLayout::ResetExternalDraw() |
|
265 { |
|
266 __ASSERT_ALWAYS(1 == iBeginRedrawCount, Panic(EInvalidRedraw)); |
|
267 |
|
268 iBeginRedrawCount--; |
|
269 iRedrawRect = TRect(); |
|
270 } |
|
271 |
|
272 TBool CTextLayout::BeginRedrawCalled() const |
|
273 { |
|
274 return iBeginRedrawCount > 0; |
|
275 } |
|
276 |
|
277 |
|
278 /** Discards all formatting information. This function is used by the CTextView |
|
279 and the printing classes, but should be called by higher-level classes that |
|
280 need to clean up after any CTextLayout function has caused an out-of-memory |
|
281 exception. */ |
|
282 EXPORT_C void CTextLayout::DiscardFormat() |
|
283 { |
|
284 iText->Clear(); |
|
285 iBandTop = 0; |
|
286 } |
|
287 |
|
288 TInt CTextLayout::SetBandTop() |
|
289 { |
|
290 TInt originalBandTop = iBandTop; |
|
291 if (iScrollFlags & EFScrollOnlyToTopsOfLines) |
|
292 { |
|
293 TTmLineInfo line; |
|
294 if (iText->YPosToLine(iBandTop, line)) |
|
295 iBandTop = line.iOuterRect.iTl.iY; |
|
296 } |
|
297 return originalBandTop - iBandTop; |
|
298 } |
|
299 |
|
300 /** Sets the layout object's source text to aDoc. |
|
301 |
|
302 The text needs to be reformatted after a call to this function. |
|
303 |
|
304 @param aDoc Pointer to the MLayDoc implementation that is the source of the |
|
305 text and formatting information. Must not be NULL or a panic occurs. */ |
|
306 EXPORT_C void CTextLayout::SetLayDoc(MLayDoc *aLayDoc) |
|
307 { |
|
308 iSource->iLayDoc = aLayDoc; |
|
309 } |
|
310 |
|
311 /** Sets the wrap width. If the current format mode is screen mode |
|
312 (CLayoutData::EFScreenMode) aWrapWidth is in pixels, otherwise it is in twips. |
|
313 |
|
314 The text needs to be reformatted after a call to this function. |
|
315 |
|
316 Note: |
|
317 |
|
318 A valid wrap width (>0) must be supplied or the expected amount of formatting will |
|
319 not take place. This could lead to panics when trying to retrieve formatting |
|
320 information that does not exist. |
|
321 |
|
322 @param aWrapWidth The wrap width in pixels or twips. */ |
|
323 EXPORT_C void CTextLayout::SetWrapWidth(TInt aWrapWidth) |
|
324 { |
|
325 if (iSource->iFormatMode == CLayoutData::EFScreenMode) |
|
326 iSource->iWidth = aWrapWidth; |
|
327 else |
|
328 iSource->iWidth = iSource->iFormatDevice->HorizontalTwipsToPixels(aWrapWidth); |
|
329 } |
|
330 |
|
331 /** Sets the height of the band in pixels or twips. This is the height of the |
|
332 visible text, or the view window, and it is also the page height for the |
|
333 purposes of scrolling up and down by page. If the current mode is screen mode |
|
334 (CLayoutData::EFScreenMode) or what-you-see-is-what-you-get mode |
|
335 (CLayoutData::EFWysiwygMode), aHeight is in pixels, otherwise it is in twips. |
|
336 |
|
337 The text needs to be reformatted after a call to this function. |
|
338 |
|
339 Note: |
|
340 |
|
341 A valid band height (>0) must be supplied or the expected amount of formatting will |
|
342 not take place. This could lead to panics when trying to retrieve formatting |
|
343 information that does not exist. |
|
344 |
|
345 @param aHeight The band height in pixels or twips. */ |
|
346 EXPORT_C void CTextLayout::SetBandHeight(TInt aHeight) |
|
347 { |
|
348 iVisibleHeight = aHeight; |
|
349 if (iBandHeight != CLayoutData::EFHeightForFormattingAllText || aHeight < 1) |
|
350 iBandHeight = aHeight; |
|
351 } |
|
352 |
|
353 /** Gets the height of the band in pixels or twips. |
|
354 @return The height of the band in pixels or twips. */ |
|
355 EXPORT_C TInt CTextLayout::BandHeight() const |
|
356 { |
|
357 return VisibleHeightInPixels(); |
|
358 } |
|
359 |
|
360 /** Sets the device map used for drawing and formatting. This device map is |
|
361 also used for formatting and drawing paragraph labels unless a separate label |
|
362 device map has been set (see SetLabelsDeviceMap()). |
|
363 |
|
364 The text needs to be reformatted after a call to this function. |
|
365 |
|
366 Note: |
|
367 |
|
368 Although the name of the function suggests that only the image device is set, |
|
369 the formatting device is also set. |
|
370 |
|
371 @param aGd The device map used for drawing and formatting. */ |
|
372 EXPORT_C void CTextLayout::SetImageDeviceMap(MGraphicsDeviceMap *aDeviceMap) |
|
373 { |
|
374 iSource->iImageDevice = aDeviceMap; |
|
375 iSource->iFormatDevice = aDeviceMap; |
|
376 } |
|
377 |
|
378 /** Sets the device map used for formatting and drawing paragraph labels. If |
|
379 not set, the device map used for labels will be the same as that used for the |
|
380 text. |
|
381 |
|
382 The text needs to be reformatted after a call to this function. |
|
383 |
|
384 @param aDeviceMap The device map used for formatting and drawing paragraph |
|
385 labels. */ |
|
386 EXPORT_C void CTextLayout::SetLabelsDeviceMap(MGraphicsDeviceMap *aDeviceMap) |
|
387 { |
|
388 iSource->iLabelsDevice = aDeviceMap; |
|
389 } |
|
390 |
|
391 /** Sets whether to format all the text (if aAmountOfFormat is |
|
392 EFFormatAllText), or just the visible band (if aAmountOfFormat is |
|
393 EFFormatBand). If band formatting is selected, enough text is formatted to fill |
|
394 the visible height. |
|
395 |
|
396 The text needs to be reformatted after a call to this function. |
|
397 |
|
398 @param aAmountOfFormat CTextLayout::EFFormatBand (the default) to format the |
|
399 visible text only. CTextLayout::EFFormatAllText to format all the text in the |
|
400 document. */ |
|
401 EXPORT_C void CTextLayout::SetAmountToFormat(TAmountFormatted aAmountOfFormat) |
|
402 { |
|
403 if (aAmountOfFormat == EFFormatBand) |
|
404 iBandHeight = iVisibleHeight; |
|
405 else |
|
406 iBandHeight = CLayoutData::EFHeightForFormattingAllText; |
|
407 } |
|
408 |
|
409 /** Tests whether band formatting is on, as set by |
|
410 CTextLayout::SetAmountToFormat(). |
|
411 @return ETrue if band formatting is on, EFalse if not. */ |
|
412 EXPORT_C TBool CTextLayout::IsFormattingBand() const |
|
413 { |
|
414 return iBandHeight != CLayoutData::EFHeightForFormattingAllText; |
|
415 } |
|
416 |
|
417 /** Sets the format mode and wrap width and (for certain format modes only) |
|
418 sets the formatting device. |
|
419 |
|
420 The text needs to be reformatted after a call to this function. |
|
421 |
|
422 Notes: |
|
423 |
|
424 If aFormatMode is CLayoutData::EFWysiwygMode or |
|
425 CLayoutData::EFPrintPreviewMode, the format device is set to aFormatDevice, |
|
426 which must not be NULL. |
|
427 |
|
428 If aFormatMode is CLayoutData::EFScreenMode or CLayoutData::EFPrintMode, |
|
429 aFormatDevice is ignored and should be NULL; the format device is set to the |
|
430 image device. |
|
431 |
|
432 The wrap width is set in either twips or pixels using the same rule as for |
|
433 SetWrapWidth(). |
|
434 |
|
435 @param aFormatMode The format mode. |
|
436 @param aWrapWidth The wrap width in pixels or twips. |
|
437 @param aFormatDevice The formatting device or NULL, depending on the format |
|
438 mode. */ |
|
439 EXPORT_C void CTextLayout::SetFormatMode(CLayoutData::TFormatMode aFormatMode,TInt aWrapWidth, |
|
440 MGraphicsDeviceMap* aFormatDevice) |
|
441 { |
|
442 if (aFormatMode == CLayoutData::EFWysiwygMode || aFormatMode == CLayoutData::EFPrintPreviewMode) |
|
443 { |
|
444 __ASSERT_ALWAYS(aFormatDevice != NULL,Panic(EFormatDeviceNotSet)); |
|
445 iSource->iFormatDevice = aFormatDevice; |
|
446 } |
|
447 else |
|
448 iSource->iFormatDevice = iSource->iImageDevice; |
|
449 iSource->iFormatMode = aFormatMode; |
|
450 SetWrapWidth(aWrapWidth); |
|
451 } |
|
452 |
|
453 /** Turns wrapping on (if aNoWrapping is EFParagraphsWrappedByDefault) or off |
|
454 (if aNoWrapping is EFAllParagraphsNotWrapped). Overrides the paragraph format |
|
455 when wrapping is turned off -paragraphs are not broken into lines even if the |
|
456 iWrap member of CParaFormat is ETrue. If wrapping is turned on, |
|
457 CParaFormat::iWrap is honoured. |
|
458 |
|
459 The text needs to be reformatted after a call to this function. |
|
460 |
|
461 @param aNoWrapping EFAllParagraphsNotWrapped (the default) to turn wrapping |
|
462 off, EFParagraphsWrappedByDefault to turn wrapping on. */ |
|
463 EXPORT_C void CTextLayout::ForceNoWrapping(TBool aNoWrapping) |
|
464 { |
|
465 if (aNoWrapping) |
|
466 iSource->iFlags &= ~TLayDocTextSource::EWrap; |
|
467 else |
|
468 iSource->iFlags |= TLayDocTextSource::EWrap; |
|
469 } |
|
470 |
|
471 /** Tests whether wrapping is on or off. |
|
472 @return ETrue if wrapping is on, EFalse if off. */ |
|
473 EXPORT_C TBool CTextLayout::IsWrapping() const |
|
474 { |
|
475 return (iSource->iFlags & TLayDocTextSource::EWrap) != 0; |
|
476 } |
|
477 |
|
478 /** Sets the truncation mode. If truncation is on, lines that exceed the wrap |
|
479 width, either because they have no legal line break, or because wrapping is |
|
480 off, are truncated, and an ellipsis is inserted. |
|
481 |
|
482 @param aOn If ETrue, lines which extend beyond the wrap width are truncated |
|
483 with an ellipsis character. If EFalse, no ellipsis is used. */ |
|
484 EXPORT_C void CTextLayout::SetTruncating(TBool aOn) |
|
485 { |
|
486 if (aOn) |
|
487 iSource->iFlags |= TLayDocTextSource::ETruncateWithEllipsis; |
|
488 else |
|
489 iSource->iFlags &= ~TLayDocTextSource::ETruncateWithEllipsis; |
|
490 } |
|
491 |
|
492 /** Tests whether truncation is on (as set by SetTruncating()). |
|
493 @return ETrue if truncation is on, EFalse if not. */ |
|
494 EXPORT_C TBool CTextLayout::Truncating() const |
|
495 { |
|
496 return (iSource->iFlags & TLayDocTextSource::ETruncateWithEllipsis) != 0; |
|
497 } |
|
498 |
|
499 /** Sets the ellipsis character to be used if truncation is on. Specify the |
|
500 value 0xFFFFÂ (the illegal Unicode character) if no ellipsis character should |
|
501 be used. By default, the ellipsis character is 0x2026, the ordinary horizontal |
|
502 ellipsis. |
|
503 |
|
504 @param aEllipsis The Unicode value of the truncating ellipsis character. */ |
|
505 EXPORT_C void CTextLayout::SetTruncatingEllipsis(TChar aEllipsis) |
|
506 { |
|
507 iSource->iEllipsis = aEllipsis; |
|
508 } |
|
509 |
|
510 /** Returns the ellipsis character used when truncation is on. The value 0xFFFF |
|
511 (the illegal Unicode character) means that no ellipsis character is appended to |
|
512 truncated text. |
|
513 |
|
514 @return The Unicode value of the truncating ellipsis character. */ |
|
515 EXPORT_C TChar CTextLayout::TruncatingEllipsis() const |
|
516 { |
|
517 return iSource->iEllipsis; |
|
518 } |
|
519 |
|
520 /** Sets the width in pixels of the margin in which labels are drawn. |
|
521 |
|
522 The text needs to be reformatted after a call to this function. |
|
523 |
|
524 @param aWidth The width in pixels of the labels margin. */ |
|
525 EXPORT_C void CTextLayout::SetLabelsMarginWidth(TInt aWidth) |
|
526 { |
|
527 iSource->iLabelsWidth = aWidth; |
|
528 } |
|
529 |
|
530 /** Specifies which non-printing characters (e.g. space, paragraph break, etc.) |
|
531 are to be drawn using symbols. |
|
532 |
|
533 The text needs to be reformatted after a call to this function.(because |
|
534 non-printing characters may differ in width from their visible |
|
535 representations). |
|
536 |
|
537 @param aVisibility Indicates which non-printing characters are drawn using |
|
538 symbols. */ |
|
539 EXPORT_C void CTextLayout::SetNonPrintingCharsVisibility(TNonPrintingCharVisibility aVisibility) |
|
540 { |
|
541 iSource->iNonPrintingCharVisibility = aVisibility; |
|
542 } |
|
543 |
|
544 /** Returns which non-printing characters are drawn using symbols. |
|
545 @return Indicates which non-printing characters are drawn using symbols. */ |
|
546 EXPORT_C TNonPrintingCharVisibility CTextLayout::NonPrintingCharsVisibility() const |
|
547 { |
|
548 return iSource->iNonPrintingCharVisibility; |
|
549 } |
|
550 |
|
551 /** Tests whether background formatting is currently taking place. Background |
|
552 formatting is managed by CTextView, using an active object, when the |
|
553 CTextLayout object is owned by a CTextView object. |
|
554 |
|
555 Not generally useful. |
|
556 |
|
557 @return ETrue if background formatting is currently taking place. EFalse if not. |
|
558 */ |
|
559 EXPORT_C TBool CTextLayout::IsBackgroundFormatting() const |
|
560 { |
|
561 return iUnformattedStart < KMaxTInt; |
|
562 } |
|
563 |
|
564 /** CTextView calls this function when background formatting has ended. It |
|
565 allows the CTextLayout object to discard information used only during |
|
566 background formatting. |
|
567 |
|
568 Not generally useful. */ |
|
569 EXPORT_C void CTextLayout::NotifyTerminateBackgroundFormatting() |
|
570 { |
|
571 iUnformattedStart = KMaxTInt; |
|
572 } |
|
573 |
|
574 |
|
575 /** Specifies whether partially displayed lines (at the top and bottom of |
|
576 the view) are to be prevented from being drawn, and whether the top of |
|
577 the display is to be aligned to the nearest line. |
|
578 |
|
579 This function takes effect only when the text is next formatted or |
|
580 scrolled.Note:This function was designed for non-editable text in the |
|
581 Agenda application, and there is an important restriction: |
|
582 CTextView functions that reformat the text after editing must not be used |
|
583 while partial lines are excluded; these functions are |
|
584 CTextView::HandleCharEditL(), |
|
585 CTextView::HandleInsertDeleteL() and |
|
586 CTextView::HandleRangeFormatChangeL(). |
|
587 |
|
588 @param aExcludePartialLines ETrue (the default) to exclude partially |
|
589 displayed lines from the view. EFalse to include them. |
|
590 @deprecated 7.0 */ |
|
591 //It did not work, and it was not what the customer wanted. A more comprehensive |
|
592 //solution is being considered. |
|
593 EXPORT_C void CTextLayout::SetExcludePartialLines(TBool) {} |
|
594 |
|
595 /** Tests whether partial lines at the top and bottom of the view are |
|
596 currently excluded. |
|
597 |
|
598 @return ETrue if partial lines are excluded, EFalse if they are displayed. |
|
599 @deprecated 7.0 */ |
|
600 EXPORT_C TBool CTextLayout::ExcludingPartialLines() const |
|
601 { |
|
602 return EFalse; |
|
603 } |
|
604 |
|
605 /** Sets the percentage by which font heights are increased in order to provide |
|
606 automatic extra spacing (leading) between lines. This amount is set to |
|
607 CLayoutData::EFFontHeightIncreaseFactor, which is 7, when a CTextLayout object |
|
608 is created. |
|
609 |
|
610 The text needs to be reformatted after a call to this function. |
|
611 |
|
612 @param aPercentage Factor by which to increase font heights. */ |
|
613 EXPORT_C void CTextLayout::SetFontHeightIncreaseFactor(TInt aPercentage) |
|
614 { |
|
615 iSource->iFontHeightIncreaseFactor = aPercentage; |
|
616 } |
|
617 |
|
618 /** Returns the font height increase factor as a percentage (i.e. a return |
|
619 value of 7 means that font heights are increased by 7% to provide automatic |
|
620 extra spacing between lines). |
|
621 |
|
622 @return Factor by which font heights are increased. */ |
|
623 EXPORT_C TInt CTextLayout::FontHeightIncreaseFactor() const |
|
624 { |
|
625 return iSource->iFontHeightIncreaseFactor; |
|
626 } |
|
627 |
|
628 /** Sets the minimum line descent in pixels. This amount is set to |
|
629 CLayoutData::EFMinimumLineDescent, which is 3, when a CTextLayout object is |
|
630 created. |
|
631 |
|
632 The text needs to be reformatted after a call to this function. |
|
633 |
|
634 @param aPixels The minimum line descent in pixels. */ |
|
635 EXPORT_C void CTextLayout::SetMinimumLineDescent(TInt aPixels) |
|
636 { |
|
637 iSource->iMinimumLineDescent = aPixels; |
|
638 } |
|
639 |
|
640 /** Returns the minimum line descent in pixels. |
|
641 @return The minimum line descent in pixels. */ |
|
642 EXPORT_C TInt CTextLayout::MinimumLineDescent() const |
|
643 { |
|
644 return iSource->iMinimumLineDescent; |
|
645 } |
|
646 |
|
647 /** Returns the document length in characters, including all the text, not just |
|
648 the formatted portion, but not including the final paragraph delimiter (the |
|
649 "end-of-text character") if any. Thus the length of an empty document is zero. |
|
650 |
|
651 @return The number of characters in the document */ |
|
652 EXPORT_C TInt CTextLayout::DocumentLength() const |
|
653 { |
|
654 return iSource->DocumentLength(); |
|
655 } |
|
656 |
|
657 /** Sets aDocPos to the paragraph start and returns the amount by which aDocPos |
|
658 has changed, as a non-negative number. |
|
659 |
|
660 @param aDocPos A document position. On return, contains the document position |
|
661 of the first character in the paragraph. |
|
662 @return The number of characters skipped in moving to the new document |
|
663 position. */ |
|
664 EXPORT_C TInt CTextLayout::ToParagraphStart(TInt& aDocPos) const |
|
665 { |
|
666 TInt old_pos = aDocPos; |
|
667 aDocPos = iSource->ParagraphStart(aDocPos); |
|
668 return old_pos - aDocPos; |
|
669 } |
|
670 |
|
671 /** Returns the height in pixels of any formatted text above the visible |
|
672 region. |
|
673 @return The height in pixels of any formatted text above the visible region. */ |
|
674 EXPORT_C TInt CTextLayout::PixelsAboveBand() const |
|
675 { |
|
676 return iBandTop; |
|
677 } |
|
678 |
|
679 /** Returns the y coordinate of the bottom of the last formatted line, relative |
|
680 to the top of the visible region. |
|
681 |
|
682 @return The y coordinate of the bottom of the last formatted line. */ |
|
683 EXPORT_C TInt CTextLayout::YBottomLastFormattedLine() const |
|
684 { |
|
685 return iText->LayoutHeight() - iBandTop; |
|
686 } |
|
687 |
|
688 /** Returns the height in pixels of the formatted text. |
|
689 |
|
690 @return The height in pixels of all the formatted text. */ |
|
691 EXPORT_C TInt CTextLayout::FormattedHeightInPixels() const |
|
692 { |
|
693 return iText->LayoutHeight(); |
|
694 } |
|
695 |
|
696 /** Returns the number of fully or partially visible characters in the visible |
|
697 band. |
|
698 |
|
699 @param aDocPos On return, contains the document position of the first fully or |
|
700 partially visible character in the band. |
|
701 @return The total number of characters in the band. */ |
|
702 EXPORT_C TInt CTextLayout::PosRangeInBand(TInt& aDocPos) const |
|
703 { |
|
704 TTmLineInfo info; |
|
705 if (!iText->YPosToLine(iBandTop,info)) |
|
706 { |
|
707 aDocPos = 0; |
|
708 return 0; |
|
709 } |
|
710 aDocPos = info.iStart; |
|
711 int end = iSource->DocumentLength(); |
|
712 //INC085809 - less 1 pixel. Rect edge is actually outside bounds |
|
713 if (iText->YPosToLine(iBandTop + VisibleHeightInPixels() - 1,info)) |
|
714 end = info.iEnd; |
|
715 return end - aDocPos; |
|
716 } |
|
717 |
|
718 /** Tests whether the document position aDocPos is fully or partially visible. |
|
719 If it is, puts the y coordinate of the left-hand end of the baseline of the |
|
720 line containing aDocPos into aXyPos. |
|
721 |
|
722 @param aDocPos The document position of interest. |
|
723 @param aXyPos On return, contains the y coordinate of the left-hand end of the |
|
724 baseline of the line containing aDocPos. |
|
725 @return ETrue if the position is visible. EFalse if the position is not visible. |
|
726 */ |
|
727 EXPORT_C TBool CTextLayout::PosInBand(TInt aDocPos,TPoint& aXyPos) const |
|
728 { |
|
729 TTmLineInfo info; |
|
730 TTmDocPos pos(aDocPos, ETrue); |
|
731 TBool result = PosInBand(pos,&info); |
|
732 aXyPos.iX = 0; |
|
733 aXyPos.iY = info.iBaseline; |
|
734 return result; |
|
735 } |
|
736 |
|
737 /** Tests whether the document position aDocPos is fully or partially visible. |
|
738 If it is, puts the y coordinate of the left-hand end of the baseline of the |
|
739 line containing aDocPos into aXyPos. |
|
740 |
|
741 @param aDocPos The document position of interest. |
|
742 @param aXyPos On return, contains the y coordinate of the left-hand end of the |
|
743 baseline of the line containing aDocPos. |
|
744 @return ETrue if the position is visible. EFalse if the position is not visible. |
|
745 */ |
|
746 EXPORT_C TBool CTextLayout::PosInBand(TTmDocPos aDocPos,TPoint& aXyPos) const |
|
747 { |
|
748 TTmLineInfo info; |
|
749 TBool result = PosInBand(aDocPos,&info); |
|
750 aXyPos.iX = 0; |
|
751 aXyPos.iY = info.iBaseline; |
|
752 return result; |
|
753 } |
|
754 |
|
755 /** Tests whether the document position aDocPos is fully or partially visible. |
|
756 If it is, puts the baseline of the line containing aDocPos into aLineInfo. |
|
757 |
|
758 @param aDocPos The document position of interest. |
|
759 @param aLineInfo On return, contains the baseline of the line containing |
|
760 aDocPos. |
|
761 |
|
762 @return ETrue if the document position aDocPos is fully or partially visible. If |
|
763 so, and if aLineInfo is non-NULL, puts information about the line in aLineInfo. |
|
764 Otherwise, EFalse */ |
|
765 EXPORT_C TBool CTextLayout::PosInBand(const TTmDocPos& aDocPos,TTmLineInfo* aLineInfo) const |
|
766 { |
|
767 TTmLineInfo dummy; |
|
768 TTmLineInfo* info_ptr = aLineInfo ? aLineInfo : &dummy; |
|
769 TTagmaForwarder forwarder(*this); |
|
770 if (!forwarder.DocPosToLine(aDocPos,*info_ptr)) |
|
771 return FALSE; |
|
772 return info_ptr->iOuterRect.iBr.iY > 0 && info_ptr->iOuterRect.iTl.iY < VisibleHeightInPixels(); |
|
773 } |
|
774 |
|
775 /** Tests whether the character aDocPos is formatted. |
|
776 |
|
777 Note: |
|
778 |
|
779 If a section of text contains characters p to q, it contains document positions |
|
780 p to q + 1; but this function returns ETrue for positions p to q only, so it |
|
781 refers to characters, not positions. However, it will return ETrue for q if q is |
|
782 the end of the document. |
|
783 |
|
784 @param aDocPos The document position of interest. |
|
785 @return ETrue if the character at the document position specified is formatted. |
|
786 EFalse if not. */ |
|
787 EXPORT_C TBool CTextLayout::PosIsFormatted(TInt aDocPos) const |
|
788 { |
|
789 if (aDocPos < iText->StartChar()) |
|
790 return FALSE; |
|
791 if (aDocPos >= iText->StartChar() + FormattedLength()) |
|
792 return FALSE; |
|
793 return TRUE; |
|
794 } |
|
795 |
|
796 /** Gets the document position of the first character in the specified line, |
|
797 counting the first line as line one (not zero) in the band. If the line is |
|
798 after the band, returns the last character position of the band. If there is no |
|
799 formatted text, returns CTextLayout::EFNoCurrentFormat. |
|
800 |
|
801 @param aLineNo Line number in formatted text, counting the first line as line |
|
802 one. |
|
803 @return The document position of the first character on the line. */ |
|
804 EXPORT_C TInt CTextLayout::FirstCharOnLine(TInt aLineNo) const |
|
805 { |
|
806 __ASSERT_DEBUG(aLineNo > 0,Panic(EInvalidLineNumber)); |
|
807 if (iText->StartChar() == iText->EndChar()) |
|
808 return EFNoCurrentFormat; |
|
809 aLineNo--; |
|
810 TTmLineInfo info; |
|
811 if (!iText->LineNumberToLine(aLineNo,info)) |
|
812 return Min(iText->EndChar(),iSource->DocumentLength()); |
|
813 return info.iStart; |
|
814 } |
|
815 |
|
816 /** Returns the number of formatted characters. This will be one more than |
|
817 expected if the formatted text runs to the end of the document, because it will |
|
818 include the end-of-text character. |
|
819 |
|
820 @return The number of formatted characters in the document. */ |
|
821 EXPORT_C TInt CTextLayout::FormattedLength() const |
|
822 { |
|
823 return iText->EndChar() - iText->StartChar(); |
|
824 } |
|
825 |
|
826 /** Returns the document position of the first formatted character. |
|
827 |
|
828 @return The document position of the first formatted character. */ |
|
829 EXPORT_C TInt CTextLayout::FirstFormattedPos() const |
|
830 { |
|
831 return iText->StartChar(); |
|
832 } |
|
833 |
|
834 /** Gets the number of formatted lines. |
|
835 |
|
836 @return The number of formatted lines in the document. */ |
|
837 EXPORT_C TInt CTextLayout::NumFormattedLines() const |
|
838 { |
|
839 return iText->Lines(); |
|
840 } |
|
841 |
|
842 /** Returns the line number, counting from 0, of the first fully visible line. |
|
843 |
|
844 @return The line number of the first fully visible line. */ |
|
845 EXPORT_C TInt CTextLayout::FirstLineInBand() const |
|
846 { |
|
847 TTmLineInfo info; |
|
848 if (!iText->YPosToLine(iBandTop,info)) |
|
849 return 0; |
|
850 int line = info.iLineNumber; |
|
851 if (info.iOuterRect.iTl.iY < iBandTop) |
|
852 line++; |
|
853 return line; |
|
854 } |
|
855 |
|
856 /** Gets the rectangle enclosing the formatted line that contains or is closest |
|
857 to y coordinate aYPos. If aYPos is above the first formatted line, the |
|
858 rectangle returned is that of the first formatted line. If aYPos is below the |
|
859 last formatted line the rectangle returned is that of the last formatted line. |
|
860 If there is no formatted text, returns CTextLayout::EFNoCurrentFormat. |
|
861 |
|
862 @param aYPos The y coordinate of the line of interest. |
|
863 @param aLine On return, contains the rectangle which encloses the line at |
|
864 aYPos. |
|
865 |
|
866 @return The line width in pixels. */ |
|
867 EXPORT_C TInt CTextLayout::GetLineRect(TInt aYPos,TRect& aRect) const |
|
868 { |
|
869 int y = iBandTop + aYPos; |
|
870 |
|
871 // Snap to formatted area. |
|
872 if (y >= iText->LayoutHeight()) |
|
873 y = iText->LayoutHeight() - 1; |
|
874 if (y < 0) |
|
875 y = 0; |
|
876 |
|
877 TTmLineInfo info; |
|
878 TBool found = iText->YPosToLine(y,info); |
|
879 if (!found) |
|
880 { |
|
881 aRect.SetSize(TSize(0,0)); |
|
882 return EFNoCurrentFormat; |
|
883 } |
|
884 |
|
885 aRect = info.iOuterRect; |
|
886 aRect.iTl.iX = info.iInnerRect.iTl.iX; |
|
887 aRect.iBr.iX = info.iInnerRect.iBr.iX; |
|
888 aRect.Move(0,-iBandTop); |
|
889 return aRect.Width(); |
|
890 } |
|
891 |
|
892 /** Returns the height of the paragraph containing aDocPos. If the paragraph is |
|
893 not formatted, returns zero. If the paragraph is partially formatted, returns |
|
894 the height of the formatted part. |
|
895 |
|
896 @param aDocPos A document position within the paragraph of interest. |
|
897 @return The height in pixels of the paragraph. Zero if the paragraph is not |
|
898 formatted. */ |
|
899 EXPORT_C TInt CTextLayout::ParagraphHeight(TInt aDocPos) const |
|
900 { |
|
901 TRect r; |
|
902 GetParagraphRect(TTmDocPos(aDocPos, ETrue), r); |
|
903 return r.Height(); |
|
904 } |
|
905 |
|
906 /** Returns the rectangle enclosing the paragraph containing aDocPos. If the |
|
907 paragraph is not formatted, returns an empty rectangle. If the paragraph is |
|
908 partially formatted, returns the rectangle enclosing the formatted part. |
|
909 |
|
910 @param aDocPos A document position within the paragraph. |
|
911 @return The rectangle which encloses the paragraph containing aDocPos. */ |
|
912 EXPORT_C TRect CTextLayout::ParagraphRectL(TInt aDocPos) const |
|
913 { |
|
914 TRect r; |
|
915 GetParagraphRect(TTmDocPos(aDocPos, ETrue), r); |
|
916 return r; |
|
917 } |
|
918 |
|
919 /** Returns the left and right extremes, in layout coordinates, of the |
|
920 formatted text. |
|
921 |
|
922 @param aLeftX On return, contains the x coordinate of the leftmost point of the |
|
923 formatted text. |
|
924 @param aRightX On return, contains the x coordinate of the rightmost point of |
|
925 the formatted text. |
|
926 @param aOnlyVisibleLines If ETrue, only scans partially or fully visible lines. |
|
927 If EFalse, scans all the formatted text. |
|
928 @param aIgnoreWrapCharacters If ETrue, does not include wrap characters in the |
|
929 measurement (paragraph delimiters, forced line breaks, etc.). If EFalse, |
|
930 includes them. |
|
931 @return EFalse if there is no formatted text, otherwise ETrue. */ |
|
932 EXPORT_C TBool CTextLayout::CalculateHorizontalExtremesL(TInt& aLeftX,TInt& aRightX, |
|
933 TBool aOnlyVisibleLines, |
|
934 TBool /*aIgnoreWrapCharacters*/) const |
|
935 { |
|
936 return CalculateHorizontalExtremes(aLeftX,aRightX,aOnlyVisibleLines); |
|
937 //+ implement aIgnoreWrapCharacters? not until clearly specified |
|
938 } |
|
939 |
|
940 TBool CTextLayout::CalculateHorizontalExtremes(TInt& aLeftX,TInt& aRightX, |
|
941 TBool aOnlyVisibleLines) const |
|
942 { |
|
943 int top = 0; |
|
944 int bottom = KMaxTInt; |
|
945 if (aOnlyVisibleLines) |
|
946 { |
|
947 top = iBandTop; |
|
948 bottom = iBandTop + VisibleHeightInPixels(); |
|
949 } |
|
950 iText->HorizontalExtremes(aLeftX, aRightX, top, bottom); |
|
951 if (0 < aLeftX) |
|
952 aLeftX = 0; |
|
953 if (aRightX < iSource->iWidth) |
|
954 aRightX = iSource->iWidth; |
|
955 return iText->StartChar() < iText->EndChar(); |
|
956 } |
|
957 |
|
958 TInt CTextLayout::WrapWidth() const |
|
959 { |
|
960 return iSource->iWidth; |
|
961 } |
|
962 |
|
963 TBool CTextLayout::GetCursor(const TTmDocPos& aDocPos,TTmCursorPlacement aPlacement, |
|
964 TRect& aLineRect,TPoint& aOrigin,TInt& aWidth,TInt& aAscent,TInt& aDescent) const |
|
965 { |
|
966 TTmLineInfo info; |
|
967 TBool result = iText->GetCursor(aDocPos,aPlacement,info,aOrigin,aWidth,aAscent,aDescent); |
|
968 if (result) |
|
969 { |
|
970 aOrigin.iY -= iBandTop; |
|
971 aLineRect = info.iOuterRect; |
|
972 aLineRect.iTl.iX = info.iInnerRect.iTl.iX; |
|
973 aLineRect.iBr.iX = info.iInnerRect.iBr.iX; |
|
974 aLineRect.Move(0,-iBandTop); |
|
975 } |
|
976 return result; |
|
977 } |
|
978 |
|
979 /** Gets the height (ascent + descent) and ascent of the font of the character |
|
980 at aDocPos, as created using the graphics device map used for drawing (the |
|
981 "image device") and returns them in aHeight and aAscent, after increasing |
|
982 aHeight by the font height increase factor (see SetFontHeightIncreaseFactor()). |
|
983 |
|
984 @param aDocPos A document position. |
|
985 @param aHeight On return contains the height in pixels of the character at |
|
986 aDocPos. |
|
987 @param aAscent On return, contains the ascent in pixels of the character at |
|
988 aDocPos. */ |
|
989 EXPORT_C void CTextLayout::GetCharacterHeightAndAscentL(TInt aDocPos,TInt& aHeight,TInt& aAscent) const |
|
990 { |
|
991 TPtrC text; |
|
992 TTmCharFormat format; |
|
993 iSource->GetText(aDocPos,text,format); |
|
994 TFontSpec fs; |
|
995 format.iFontSpec.GetTFontSpec(fs); |
|
996 GetFontHeightAndAscentL(fs,aHeight,aAscent); |
|
997 } |
|
998 |
|
999 /** Gets the height (ascent + descent) and ascent of the font specified by |
|
1000 aFontSpec, as created using the graphics device map used for drawing (the |
|
1001 "image device") and puts them into aHeight and aAscent, after increasing |
|
1002 aHeight by the font height increase factor (see SetFontHeightIncreaseFactor()). |
|
1003 |
|
1004 @param aFontSpec Font specification. |
|
1005 @param aHeight On return, contains the height in pixels of the font. |
|
1006 @param aAscent On return, contains the ascent in pixels of the font. */ |
|
1007 EXPORT_C void CTextLayout::GetFontHeightAndAscentL(const TFontSpec& aFontSpec,TInt& aHeight,TInt& aAscent) const |
|
1008 { |
|
1009 CFont* font; |
|
1010 MGraphicsDeviceMap& device = iSource->InterpretDevice(); |
|
1011 User::LeaveIfError(device.GetNearestFontInTwips(font,aFontSpec)); |
|
1012 aHeight = font->HeightInPixels(); |
|
1013 int increase = (iSource->iFontHeightIncreaseFactor * aHeight) / 100; |
|
1014 aHeight += increase; |
|
1015 aAscent = font->AscentInPixels() + increase; |
|
1016 device.ReleaseFont(font); |
|
1017 } |
|
1018 |
|
1019 /** Returns the index of the nearest character in the document to the window |
|
1020 coordinates specified. Sets aPos to the actual position of the intersection |
|
1021 of the line's baseline with the character's edge. If aPos is before the start |
|
1022 of the formatted area, returns the first formatted character; if it is after |
|
1023 the end of the formatted area, returns the position after the last formatted |
|
1024 character, or the end of the document, whichever is less. |
|
1025 |
|
1026 This function is deprecated in v7.0s. Use the more powerful FindXYPos() instead. |
|
1027 |
|
1028 @param aPos Contains coordinates to convert to a document position. On return, |
|
1029 contains the exact coordinates of the intersection of the line's baseline with |
|
1030 the character edge at the document position. |
|
1031 @param aFlags Three possible values: 0 is the default, and performs the task at |
|
1032 full accuracy (the function returns the document position of the character edge |
|
1033 nearest to the coordinates). CLayoutData::EFWholeLinesOnly examines lines only |
|
1034 and returns the position at the right end of the line if aPos.iX > 0, otherwise |
|
1035 the position at the left end. |
|
1036 @return The document position of the nearest character to the coordinates, or |
|
1037 of the start or end of the line, depending on the value of aFlags. */ |
|
1038 EXPORT_C TInt CTextLayout::XyPosToDocPosL(TPoint &aXyPos,TUint) const |
|
1039 { |
|
1040 if (aXyPos.iY < -iBandTop) |
|
1041 return iText->StartChar(); |
|
1042 else if (aXyPos.iY >= iText->LayoutHeight() - iBandTop) |
|
1043 return Min(iText->EndChar(),iSource->DocumentLength()); |
|
1044 TTmPosInfo2 pos_info; |
|
1045 TTmLineInfo lineInfo; |
|
1046 FindXyPos(aXyPos,pos_info, &lineInfo); |
|
1047 aXyPos = pos_info.iEdge; |
|
1048 TInt r = pos_info.iDocPos.iPos; |
|
1049 if (!pos_info.iDocPos.iLeadingEdge && lineInfo.iStart != r) |
|
1050 { |
|
1051 r -= 1; |
|
1052 |
|
1053 // surrogate support |
|
1054 if ( r > 0 ) |
|
1055 { |
|
1056 TPtrC text; |
|
1057 TTmCharFormat format; |
|
1058 |
|
1059 iSource->GetText( r - 1, text, format ); |
|
1060 if ( text.Length() > 1 ) |
|
1061 { |
|
1062 TUint highSurrogate = text[0]; |
|
1063 TUint lowSurrogate = text[1]; |
|
1064 if ( IsHighSurrogate( highSurrogate ) && |
|
1065 IsLowSurrogate( lowSurrogate ) ) |
|
1066 --r; |
|
1067 } |
|
1068 } |
|
1069 } |
|
1070 |
|
1071 return r; |
|
1072 } |
|
1073 |
|
1074 /** Finds the document position nearest to aXyPos. If aXyPos is in the |
|
1075 formatted text returns ETrue, otherwise returns EFalse. If ETrue is returned, |
|
1076 places information about the document position in aPosInfo and information |
|
1077 about the line containing the document position in aLineInfo if it is non-NULL. |
|
1078 |
|
1079 @param aXyPos Contains coordinates to convert to a document position. |
|
1080 @param aPosInfo Buffer to store information about the document position if the |
|
1081 specified coordinates are located in the formatted text. |
|
1082 @param aLineInfo Buffer to store information about the line if the specified |
|
1083 coordinates are located in the formatted text. |
|
1084 @return ETrue if aXyPos is a formatted position, otherwise EFalse. */ |
|
1085 EXPORT_C TBool CTextLayout::FindXyPos(const TPoint& aXyPos,TTmPosInfo2& aPosInfo,TTmLineInfo* aLineInfo) const |
|
1086 { |
|
1087 TTagmaForwarder forwarder(*this); |
|
1088 TTmLineInfo line_info; |
|
1089 TBool result = forwarder.FindXyPos(aXyPos,aPosInfo,line_info); |
|
1090 if (aLineInfo && result) |
|
1091 *aLineInfo = line_info; |
|
1092 return result; |
|
1093 } |
|
1094 |
|
1095 /** Returns the x-y coordinates of the document position aDocPos in aPos. The |
|
1096 return value is ETrue if the position is formatted, or EFalse if it is not, in |
|
1097 which case aPos is undefined. |
|
1098 |
|
1099 Deprecated - use the more powerful FindDocPos() instead |
|
1100 |
|
1101 @param aDocPos The document position. |
|
1102 @param aPos On return, contains the x-y coordinates of aDocPos. |
|
1103 @param aFlags Two possible values: 0 is the default, and performs the task at |
|
1104 full accuracy, and CLayoutData::EFWholeLinesOnly, which examines lines only and |
|
1105 sets aXyPos.iY only, and cannot leave. |
|
1106 @return ETrue if the document position is formatted, EFalse if not. */ |
|
1107 EXPORT_C TBool CTextLayout::DocPosToXyPosL(TInt aDocPos,TPoint& aXyPos,TUint /*aFlags*/) const |
|
1108 { |
|
1109 TTmDocPos doc_pos(aDocPos, ETrue); |
|
1110 TTmPosInfo2 pos_info; |
|
1111 TBool result = FindDocPos(doc_pos,pos_info); |
|
1112 aXyPos = pos_info.iEdge; |
|
1113 return result; |
|
1114 } |
|
1115 |
|
1116 /** Finds the x-y position of the document position aDocPos. |
|
1117 |
|
1118 If ETrue is returned, places information about the document position in aPosInfo |
|
1119 and information about the line containing the document position in aLineInfo if |
|
1120 it is non-NULL. |
|
1121 |
|
1122 @param aDocPos Contains the document position to check. |
|
1123 @param aPosInfo On return, stores information about the document position if |
|
1124 the position is formatted. |
|
1125 @param aLineInfo Buffer to store the line information if the document position |
|
1126 is formatted. |
|
1127 @return ETrue if aDocPos is in the formatted text, otherwise EFalse. */ |
|
1128 EXPORT_C TBool CTextLayout::FindDocPos(const TTmDocPosSpec& aDocPos,TTmPosInfo2& aPosInfo,TTmLineInfo* aLineInfo) const |
|
1129 { |
|
1130 TTagmaForwarder forwarder(*this); |
|
1131 TTmLineInfo line_info; |
|
1132 TBool result = forwarder.FindDocPos(aDocPos,aPosInfo,line_info); |
|
1133 if (aLineInfo && result) |
|
1134 *aLineInfo = line_info; |
|
1135 return result; |
|
1136 } |
|
1137 |
|
1138 /** Finds the next cursor position to aDocPos in the visually ordered line. |
|
1139 |
|
1140 @param aDocPos Contains the document position to check. |
|
1141 @param aPosInfo On return, stores information about the document position of |
|
1142 the next cursor position, if ETrue is returned. |
|
1143 @param aToLeft ETrue if the position to the left is to be found, or EFalse if |
|
1144 the position to the right is to be found. |
|
1145 @return EFalse if there is no formatting, or the position is at the end of the |
|
1146 line already. ETrue otherwise. */ |
|
1147 EXPORT_C TBool CTextLayout::GetNextVisualCursorPos( |
|
1148 const TTmDocPosSpec& aDocPos, TTmPosInfo2& aPosInfo, TBool aToLeft) const |
|
1149 { |
|
1150 TTagmaForwarder forwarder(*this); |
|
1151 return forwarder.GetNextVisualCursorPos(aDocPos, aPosInfo, aToLeft); |
|
1152 } |
|
1153 |
|
1154 /** Gets a rectangle enclosing two formatted document positions on the same |
|
1155 line. If the second position is less than the first, or on a different line, it |
|
1156 is taken to indicate the end of the line. This function panics if either |
|
1157 position is unformatted. |
|
1158 |
|
1159 Note: |
|
1160 |
|
1161 CTextLayout must have been set with a valid wrap width and band height before |
|
1162 calling this function, otherwise no formatting will take place and the function |
|
1163 will panic. Wrap width and band height values must be > 0 to be valid. |
|
1164 |
|
1165 @param aDocPos1 The first document position on the line. |
|
1166 @param aDocPos2 The second document position on the line. |
|
1167 @return The minimal rectangle, which bounds both positions. |
|
1168 @see SetBandHeight |
|
1169 @see SetWrapWidth */ |
|
1170 EXPORT_C TRect CTextLayout::GetLineRectL(TInt aDocPos1,TInt aDocPos2) const |
|
1171 { |
|
1172 TRect rect; |
|
1173 TPoint point; |
|
1174 TInt xCoords[4]; |
|
1175 |
|
1176 if (iText->LayoutHeight() == 0) |
|
1177 return TRect(0,0,0,0); |
|
1178 |
|
1179 __ASSERT_ALWAYS(PosIsFormatted(aDocPos1),Panic(ECharacterNotFormatted)); |
|
1180 __ASSERT_DEBUG(PosIsFormatted(aDocPos2),Panic(ECharacterNotFormatted)); |
|
1181 |
|
1182 TTmDocPosSpec docSpec(aDocPos1, TTmDocPosSpec::ELeading); |
|
1183 TTmPosInfo2 pos_info; |
|
1184 |
|
1185 // Finding the leading edge of aDocPos1 |
|
1186 FindDocPos(docSpec,pos_info); |
|
1187 point = pos_info.iEdge; |
|
1188 xCoords[0] = point.iX; |
|
1189 |
|
1190 // Getthe Line rectangle |
|
1191 GetLineRect(point.iY,rect); |
|
1192 |
|
1193 __ASSERT_DEBUG(rect.iTl.iY <= point.iY && rect.iBr.iY >= point.iY,Panic(EPixelNotInFormattedLine)); |
|
1194 |
|
1195 // Finding the leading edge of aDocPos2 |
|
1196 docSpec.iPos = aDocPos2; |
|
1197 TBool isformatted = FindDocPos(docSpec, pos_info); |
|
1198 point = pos_info.iEdge; |
|
1199 |
|
1200 // Checks if the aDocPos2 is contained in the same line of the aDocPos1 |
|
1201 // Can't use TRect::Contains() here, because TRect::Contains() considers a point located on the right |
|
1202 // hand side or bottom as outside the rectangle, which will has problem when work with RTL text that |
|
1203 // is at the right hand end of a line. |
|
1204 TBool isContained = (point.iX>=rect.iTl.iX && point.iX<=rect.iBr.iX |
|
1205 && point.iY>=rect.iTl.iY && point.iY<=rect.iBr.iY); |
|
1206 |
|
1207 RTmParFormat parFormat; |
|
1208 iSource->GetParagraphFormatL(aDocPos1, parFormat); |
|
1209 |
|
1210 // The special cases (as indicated in the description): |
|
1211 // When the aDocPos2 is less than the aDocPos1, or not formatted, or on a different line from which the |
|
1212 // aDocPos1 is in, then the function will return the rectangle starting from docPos1's leading edge and |
|
1213 // ending at the end of the line (which is determined by paragraph directionality). |
|
1214 if (aDocPos2 < aDocPos1 || !isformatted || !isContained) |
|
1215 { |
|
1216 if (parFormat.RightToLeft()) |
|
1217 rect.iBr.iX = xCoords[0]; |
|
1218 else |
|
1219 rect.iTl.iX = xCoords[0]; |
|
1220 |
|
1221 parFormat.Close(); |
|
1222 return rect; |
|
1223 } |
|
1224 |
|
1225 xCoords[1] = point.iX; |
|
1226 |
|
1227 // Finding the Trailing edge of (aDocPos1 + 1) |
|
1228 docSpec.iType = TTmDocPosSpec::ETrailing; |
|
1229 docSpec.iPos = aDocPos1 + 1; |
|
1230 FindDocPos(docSpec, pos_info); |
|
1231 xCoords[2] = pos_info.iEdge.iX; |
|
1232 |
|
1233 // Finding the Trailing edge of (aDocPos2 + 1) |
|
1234 docSpec.iPos = aDocPos2 + 1; |
|
1235 FindDocPos(docSpec, pos_info); |
|
1236 xCoords[3] = pos_info.iEdge.iX; |
|
1237 |
|
1238 rect.iBr.iX = xCoords[0]; |
|
1239 rect.iTl.iX = xCoords[0]; |
|
1240 |
|
1241 // The returned rectangle is generated by (when is not a special case) |
|
1242 // 1) Find the Line rectangle |
|
1243 // 2) Find the: |
|
1244 // - leading edge of docPos1 |
|
1245 // - leading edge of docPos2 |
|
1246 // - trailing edge of docPos1+1 |
|
1247 // - trailing edge of docPos2+1 |
|
1248 // 3) Cut the line rectangle at the smallest edge and the largest edge among |
|
1249 // the four edges found in step 2. |
|
1250 for (TInt i = 1; i<4; i++ ) |
|
1251 { |
|
1252 if (rect.iBr.iX < xCoords[i]) |
|
1253 rect.iBr.iX = xCoords[i]; |
|
1254 if (rect.iTl.iX > xCoords[i]) |
|
1255 rect.iTl.iX = xCoords[i]; |
|
1256 } |
|
1257 |
|
1258 parFormat.Close(); |
|
1259 return rect; |
|
1260 } |
|
1261 |
|
1262 /** Gets the bounding rectangle of the picture, if any, located at the document |
|
1263 position or coordinates specified, and returns it in aPictureRect. |
|
1264 |
|
1265 If aCanScaleOrCrop is non-null, sets aCanScaleOrCrop to indicate |
|
1266 whether the picture can be scaled or cropped. |
|
1267 Returns ETrue if the operation was successful. Returns EFalse otherwise; |
|
1268 that is, if there is no picture at the position, or if the position is unformatted. |
|
1269 |
|
1270 @param aDocPos The document position of interest. |
|
1271 @param aXyPos The layout coordinates of interest. |
|
1272 @param aPictureRect On return, contains the rectangle which encloses the |
|
1273 picture located at the position specified. |
|
1274 @param aCanScaleOrCrop If non-NULL and the function returns ETrue, on return, |
|
1275 indicates whether the picture can be scaled or cropped. By default, NULL. |
|
1276 @return ETrue if the operation was successful, (i.e. there is a |
|
1277 picture character at the position, it has been loaded into |
|
1278 memory, and the position is formatted). EFalse if any of these |
|
1279 conditions are not met. */ |
|
1280 EXPORT_C TBool CTextLayout::PictureRectangleL(TInt aDocPos,TRect& aPictureRect,TBool* aCanScaleOrCrop) const |
|
1281 { |
|
1282 if (aDocPos < iText->StartChar() || aDocPos >= iText->EndChar() - 1) |
|
1283 return FALSE; |
|
1284 |
|
1285 aPictureRect.SetRect(0,0,0,0); |
|
1286 TSize size; |
|
1287 if (iSource->GetPictureSizeInTwipsL(aDocPos,size) != KErrNone) |
|
1288 return FALSE; |
|
1289 |
|
1290 TRect rect; |
|
1291 TTmDocPos pos(aDocPos, ETrue); |
|
1292 TTmPosInfo2 pos_info; |
|
1293 TTmLineInfo info; |
|
1294 TInt subscript; |
|
1295 if (!iText->FindDocPos(pos,pos_info,info,subscript)) |
|
1296 return FALSE; |
|
1297 |
|
1298 MGraphicsDeviceMap& device = iSource->InterpretDevice(); |
|
1299 size.iWidth = device.HorizontalTwipsToPixels(size.iWidth); |
|
1300 size.iHeight = device.VerticalTwipsToPixels(size.iHeight); |
|
1301 rect.iBr.iY = pos_info.iEdge.iY - iBandTop + subscript; |
|
1302 rect.iTl.iY = rect.iBr.iY - size.iHeight; |
|
1303 if (pos_info.iRightToLeft) |
|
1304 { |
|
1305 rect.iBr.iX = pos_info.iEdge.iX; |
|
1306 rect.iTl.iX = rect.iBr.iX - size.iWidth; |
|
1307 } |
|
1308 else |
|
1309 { |
|
1310 rect.iTl.iX = pos_info.iEdge.iX; |
|
1311 rect.iBr.iX = rect.iTl.iX + size.iWidth; |
|
1312 } |
|
1313 /* rect.iTl = pos_info.iEdge; |
|
1314 rect.Move(0,-iBandTop); |
|
1315 rect.iTl.iY -= size.iHeight; |
|
1316 rect.iBr = rect.iTl + size;*/ |
|
1317 CPicture* picture = iSource->PictureL(aDocPos); |
|
1318 if (!picture) |
|
1319 return FALSE; |
|
1320 |
|
1321 if (aCanScaleOrCrop) |
|
1322 *aCanScaleOrCrop = picture->Capability().iScalingType != TPictureCapability::ENotScaleable || |
|
1323 picture->Capability().iIsCroppable; |
|
1324 aPictureRect = rect; |
|
1325 return TRUE; |
|
1326 } |
|
1327 |
|
1328 /** Finds if there is a picture at the position under the point aXyPos. |
|
1329 If there is, returns the document position of it, sets the rectangle |
|
1330 occupied in aPictureRect, and whether the picture allows scaling |
|
1331 in aCanScaleOrCrop, if non-null. Note that aXyPos may be outside |
|
1332 the picture found. |
|
1333 @return The document position of the picture found, or KErrNotFound if there |
|
1334 is none. */ |
|
1335 TInt CTextLayout::PictureRectangleAndPosL(const TPoint& aXyPos, TRect& aPictureRect, |
|
1336 TBool* aCanScaleOrCrop) const |
|
1337 { |
|
1338 TTmPosInfo2 posInfo; |
|
1339 if (!FindXyPos(aXyPos, posInfo)) |
|
1340 return KErrNotFound; |
|
1341 TInt doc_pos = posInfo.iDocPos.iPos - (posInfo.iDocPos.iLeadingEdge? 0 : 1); |
|
1342 if (PictureRectangleL(doc_pos, aPictureRect, aCanScaleOrCrop)) |
|
1343 return doc_pos; |
|
1344 return KErrNotFound; |
|
1345 } |
|
1346 |
|
1347 /** Gets the bounding rectangle of the picture (if any) at aXyPos and puts it |
|
1348 in aPictureRect. If aCanScaleOrCrop is non-null sets *aCanScaleOrCrop to |
|
1349 indicate whether the picture can be scaled or cropped. Note that aXyPos |
|
1350 may be outside aPictureRect on a successful return, if the picture does |
|
1351 not occupy the whole of the section of the line it is in. |
|
1352 @return ETrue if the position is formatted and there is a picture there. */ |
|
1353 EXPORT_C TBool CTextLayout::PictureRectangleL(const TPoint& aXyPos, |
|
1354 TRect& aPictureRect, TBool* aCanScaleOrCrop) const |
|
1355 { |
|
1356 return 0 <= PictureRectangleAndPosL(aXyPos, aPictureRect, aCanScaleOrCrop)? |
|
1357 ETrue : EFalse; |
|
1358 } |
|
1359 |
|
1360 /** Gets the first document position in a line that starts at or below the top |
|
1361 of the visible area. If there is no such line, returns the position after the |
|
1362 last formatted character. |
|
1363 |
|
1364 @return The document position of the first character in a line within the |
|
1365 visible area. */ |
|
1366 EXPORT_C TInt CTextLayout::FirstDocPosFullyInBand() const |
|
1367 { |
|
1368 TTmLineInfo info; |
|
1369 if (!iText->YPosToLine(iBandTop,info)) |
|
1370 return iText->EndChar(); |
|
1371 if (info.iOuterRect.iTl.iY < iBandTop) |
|
1372 return info.iEnd; |
|
1373 else |
|
1374 return info.iStart; |
|
1375 } |
|
1376 |
|
1377 |
|
1378 |
|
1379 |
|
1380 /** This interface is deprecated, and is made available in version 7.0s solely |
|
1381 to provide binary compatibility with Symbian OS v6.1. Developers are strongly |
|
1382 advised not to make use of this API in new applications. In particular, use the |
|
1383 other overload of this function if you need to distinguish between leading and |
|
1384 trailing edge positions. |
|
1385 |
|
1386 Do not use if a CTextView object owns this CTextLayout object. |
|
1387 |
|
1388 @param aDocPos A valid document position. |
|
1389 @param aYPos The y coordinate at which to display the character at aDocPos. On |
|
1390 return, contains the actual vertical position of the specified part of the |
|
1391 line. |
|
1392 @param aYPosQualifier Controls which part of the line is set to appear at |
|
1393 aYPos. |
|
1394 @param aDiscardFormat If ETrue (EFViewDiscardAllFormat), the text is reformatted |
|
1395 to include aDocPos, otherwise text is formatted only as necessary when bringing |
|
1396 new lines into the visible area. |
|
1397 @return The number of pixels the text was scrolled, may be positive or |
|
1398 negative. A value of CTextLayout::EFScrollRedrawWholeScreen indicates that the |
|
1399 entire visible area, at least, was scrolled, and so there is no point in |
|
1400 blitting text; a full redraw is needed. */ |
|
1401 EXPORT_C TInt CTextLayout::SetViewL(TInt aDocPos,TInt& aYPos,TViewYPosQualifier aYPosQualifier,TDiscard aDiscardFormat) |
|
1402 { |
|
1403 TTmDocPos pos(aDocPos, ETrue); |
|
1404 return SetViewL(pos,aYPos,aYPosQualifier,aDiscardFormat); |
|
1405 } |
|
1406 |
|
1407 /** Changes the top of the visible area so that the line containing aDocPos is |
|
1408 vertically positioned at aYPos. Which part of the line is set to appear at |
|
1409 aYPos (top, baseline, or bottom) is controlled by the TViewYPosQualifier |
|
1410 argument, which also specifies whether the visible area is to be filled and |
|
1411 whether the line should be made fully visible if possible. |
|
1412 |
|
1413 Do not use if a CTextView object owns this CTextLayout object. |
|
1414 |
|
1415 @param aDocPos A valid document position. |
|
1416 @param aYPos The y coordinate at which to display the character at aDocPos. On |
|
1417 return, contains the actual vertical position of the specified part of the |
|
1418 line. |
|
1419 @param aYPosQualifier Controls which part of the line is set to appear at |
|
1420 aYPos. |
|
1421 @param aDiscardFormat If ETrue (EFViewDiscardAllFormat), the text is reformatted |
|
1422 to include aDocPos, otherwise text is formatted only as necessary when bringing |
|
1423 new lines into the visible area. |
|
1424 @return The number of pixels the text was scrolled, may be positive or |
|
1425 negative. A value of CTextLayout::EFScrollRedrawWholeScreen indicates that the |
|
1426 entire visible area, at least, was scrolled, and so there is no point in |
|
1427 blitting text; a full redraw is needed. */ |
|
1428 EXPORT_C TInt CTextLayout::SetViewL(const TTmDocPos& aDocPos, TInt& aYPos, |
|
1429 TViewYPosQualifier aYPosQualifier, TDiscard aDiscardFormat) |
|
1430 { |
|
1431 if (aDocPos.iPos < 0 || aDocPos.iPos > iSource->DocumentLength()) |
|
1432 Panic(EInvalidDocPos); |
|
1433 |
|
1434 /* |
|
1435 If the format is to be discarded, or no text has yet been formatted, or if the document position |
|
1436 to be viewed is not formatted, format the band. |
|
1437 */ |
|
1438 TTmLineInfo info; |
|
1439 TBool all_formatted = FALSE; |
|
1440 TBool pos_is_formatted = iText->DocPosToLine(aDocPos,info); |
|
1441 if (!pos_is_formatted || |
|
1442 aDiscardFormat == EFViewDiscardAllFormat || |
|
1443 (iText->StartChar() == iText->EndChar() && iSource->DocumentLength() > 0)) |
|
1444 { |
|
1445 FormatBandL(aDocPos.iPos,aDocPos.iPos); |
|
1446 all_formatted = TRUE; |
|
1447 pos_is_formatted = iText->DocPosToLine(aDocPos,info); |
|
1448 } |
|
1449 |
|
1450 // Find out where the top of the line is. |
|
1451 if (!pos_is_formatted) |
|
1452 return 0; |
|
1453 int line_top_y = info.iOuterRect.iTl.iY - iBandTop; |
|
1454 |
|
1455 // Determine the desired position of the top of the line. |
|
1456 int offset = 0; |
|
1457 if (aYPosQualifier.iHotSpot == TViewYPosQualifier::EFViewBaseLine) |
|
1458 offset = info.iBaseline - info.iOuterRect.iTl.iY; |
|
1459 else if (aYPosQualifier.iHotSpot == TViewYPosQualifier::EFViewBottomOfLine) |
|
1460 offset = info.iOuterRect.iBr.iY - info.iOuterRect.iTl.iY; |
|
1461 int desired_line_top_y = aYPos - offset; |
|
1462 |
|
1463 // Adjust aYPos so that the line is fully visible if desired. |
|
1464 if (aYPosQualifier.iFullyVisible == TViewYPosQualifier::EFViewForceLineFullyVisible) |
|
1465 { |
|
1466 TInt screenHeight = VisibleHeightInPixels(); |
|
1467 TInt lineHeight = info.iOuterRect.Height(); |
|
1468 TInt lineAscent = info.iBaseline - info.iOuterRect.iTl.iY; |
|
1469 // If the top of the line is off the top of the screen, and the |
|
1470 // baseline and the top can both fit, make the top of the line flush |
|
1471 // with the top of the screen. |
|
1472 if (lineAscent <= screenHeight |
|
1473 && desired_line_top_y < 0) |
|
1474 desired_line_top_y = 0; |
|
1475 // If the whole line can fit and the bottom if off the bottom of the |
|
1476 // screen, make the bottom flush with the bottom of the screen. |
|
1477 if (lineHeight <= screenHeight |
|
1478 && screenHeight < desired_line_top_y + lineHeight) |
|
1479 desired_line_top_y = screenHeight - lineHeight; |
|
1480 // If the ascent will not fit, or the baseline is off the bottom of |
|
1481 // the screen, move the baseline flush with the bottom of the screen |
|
1482 if (screenHeight < lineAscent |
|
1483 || screenHeight < desired_line_top_y + lineAscent) |
|
1484 desired_line_top_y = screenHeight - lineAscent; |
|
1485 } |
|
1486 |
|
1487 // Scroll the document position to the desired vertical coordinate and update aYPos. |
|
1488 TInt dy = desired_line_top_y - line_top_y; |
|
1489 if (dy) |
|
1490 { |
|
1491 dy = ScrollL(dy,aYPosQualifier.iFillScreen ? EFDisallowScrollingBlankSpace : EFAllowScrollingBlankSpace); |
|
1492 line_top_y += dy; |
|
1493 aYPos = line_top_y + offset; |
|
1494 |
|
1495 // Ensure that aYPos is in the line. |
|
1496 if (aYPosQualifier.iHotSpot == TViewYPosQualifier::EFViewBottomOfLine) |
|
1497 aYPos--; |
|
1498 } |
|
1499 return all_formatted ? EFScrollRedrawWholeScreen : dy; |
|
1500 } |
|
1501 |
|
1502 /** Formats enough text to fill the visible band. |
|
1503 |
|
1504 Note: Do not use if a CTextView object owns this CTextLayout object. */ |
|
1505 EXPORT_C void CTextLayout::FormatBandL() |
|
1506 { |
|
1507 FormatBandL(0,0); |
|
1508 } |
|
1509 |
|
1510 /** |
|
1511 Format enough text to fill the visible band and include both aStartDocPos and |
|
1512 aEndDocPos. Start at the start of the document if formatting everything, or at |
|
1513 the start of the paragraph containing aStartDocPos if formatting the visible |
|
1514 band only. |
|
1515 */ |
|
1516 void CTextLayout::FormatBandL(TInt aStartDocPos,TInt aEndDocPos) |
|
1517 { |
|
1518 TTmFormatParam param; |
|
1519 InitFormatParam(param); |
|
1520 if (iBandHeight != CLayoutData::EFHeightForFormattingAllText) |
|
1521 param.iStartChar = iSource->ParagraphStart(aStartDocPos); |
|
1522 if (param.iWrapWidth < 1 || param.iMaxHeight < 1) |
|
1523 { |
|
1524 // Do just a little formatting if the values are illegal. |
|
1525 // This is to prevent the AddParL running with no |
|
1526 // height limit, taking up huge amounts of time, and |
|
1527 // having to return with 0 lines formatted, which |
|
1528 // confuses CEikEdwin. |
|
1529 param.iMaxHeight = 1; |
|
1530 param.iWrapWidth = 1; |
|
1531 iText->SetTextL(*iSource,param); |
|
1532 return; |
|
1533 } |
|
1534 iText->SetTextL(*iSource,param); |
|
1535 param.iMaxHeight = KMaxTInt; |
|
1536 |
|
1537 if(IsFormattingBand() && (iText->EndChar() <= aEndDocPos && iText->EndChar() < iSource->DocumentLength())) |
|
1538 { |
|
1539 param.iEndChar = aEndDocPos; |
|
1540 iText->ExtendFormattingDownwardsL(param); |
|
1541 } |
|
1542 else |
|
1543 { |
|
1544 while (iText->EndChar() <= aEndDocPos && iText->EndChar() < iSource->DocumentLength()) |
|
1545 { |
|
1546 int h,p; |
|
1547 AddFormattingAtEndL(param, h, p); |
|
1548 } |
|
1549 } |
|
1550 |
|
1551 |
|
1552 if (iBandHeight != CLayoutData::EFHeightForFormattingAllText) |
|
1553 { |
|
1554 int visible_height = VisibleHeightInPixels(); |
|
1555 while (iText->LayoutHeight() < visible_height) |
|
1556 { |
|
1557 int h,p; |
|
1558 if (!iText->AddParL(param,TRUE,h,p)) |
|
1559 break; |
|
1560 } |
|
1561 } |
|
1562 iBandTop = 0; |
|
1563 } |
|
1564 |
|
1565 /** Makes sure the line that aYPos is in (if it exists) is covered by the |
|
1566 formatting. |
|
1567 @param aYPos Y pixel position in window-relative co-ordinates. |
|
1568 @internalComponent |
|
1569 */ |
|
1570 EXPORT_C void CTextLayout::ExtendFormattingToCoverYL(TInt aYPos) |
|
1571 { |
|
1572 TTmFormatParam param; |
|
1573 InitFormatParam(param); |
|
1574 param.iStartChar = iText->StartChar() - 1; |
|
1575 param.iEndChar = iText->EndChar(); |
|
1576 param.iMaxHeight = KMaxTInt; |
|
1577 TInt heightIncrease; |
|
1578 TInt p; |
|
1579 while (iBandTop < -aYPos && iText->AddParL(param, ETrue, heightIncrease, p)) |
|
1580 { |
|
1581 iBandTop += heightIncrease; |
|
1582 param.iStartChar = iText->StartChar() - 1; |
|
1583 } |
|
1584 TInt heightRemaining = iBandTop + aYPos - iText->LayoutHeight() + 1; |
|
1585 if(heightRemaining > 0) |
|
1586 { |
|
1587 param.iStartChar = iText->EndChar(); |
|
1588 param.iEndChar = KMaxTInt; |
|
1589 param.iMaxHeight = heightRemaining; |
|
1590 iText->ExtendFormattingDownwardsL(param); |
|
1591 } |
|
1592 } |
|
1593 |
|
1594 /** Allows you to increase the formatted text range by specifying a point in the text you |
|
1595 want to increase the range to. Makes sure the line that aDocPos is in (if it exists) is covered by the |
|
1596 formatting. |
|
1597 @param aDocPos Position in the text you wish to extend the formatting to. e.g. passing in 0 will |
|
1598 increase the formatting range to the very first character entered in the document. |
|
1599 @pre aDocPos is in the range 0...DocumentLength |
|
1600 @post aDocPos has been formatted |
|
1601 */ |
|
1602 EXPORT_C void CTextLayout::ExtendFormattingToCoverPosL(TInt aDocPos) |
|
1603 { |
|
1604 __ASSERT_DEBUG(0 <= aDocPos && aDocPos <= DocumentLength(), |
|
1605 Panic(EInvalidDocPos)); |
|
1606 TTmFormatParam param; |
|
1607 InitFormatParam(param); |
|
1608 param.iStartChar = iText->StartChar(); |
|
1609 param.iEndChar = iText->EndChar(); |
|
1610 param.iMaxHeight = KMaxTInt; |
|
1611 TInt heightIncrease; |
|
1612 TInt p; |
|
1613 TInt pos = aDocPos; |
|
1614 if(pos > 0) // Avoid going into infinite loop. |
|
1615 { |
|
1616 pos -= 1; |
|
1617 } |
|
1618 while ((pos < param.iStartChar) && (iText->AddParL(param, ETrue, heightIncrease, p))) |
|
1619 { |
|
1620 iBandTop += heightIncrease; |
|
1621 param.iStartChar = iText->StartChar(); |
|
1622 } |
|
1623 param.iEndChar = aDocPos + 1; |
|
1624 if(iText->EndChar() < param.iEndChar) |
|
1625 { |
|
1626 iText->ExtendFormattingDownwardsL(param); |
|
1627 } |
|
1628 __ASSERT_DEBUG((aDocPos >= iText->StartChar()) && (aDocPos <= iText->EndChar()), |
|
1629 Panic(ECharacterNotFormatted)); |
|
1630 } |
|
1631 |
|
1632 |
|
1633 /** Sets the formatted text to begin at the start of the paragraph including |
|
1634 aStartPos and end at aEndPos. Moves the line containing aStartDocPos to the top |
|
1635 of the visible area. |
|
1636 |
|
1637 Notes: |
|
1638 |
|
1639 This function is not generally useful; it exists for the convenience of the |
|
1640 printing system. |
|
1641 |
|
1642 Do not use if a CTextView object owns this CTextLayout object. |
|
1643 |
|
1644 @param aStartDocPos A document position within the paragraph from which to |
|
1645 begin formatting. |
|
1646 @param aEndDocPos Document position at which to end formatting. */ |
|
1647 EXPORT_C void CTextLayout::FormatCharRangeL(TInt aStartDocPos,TInt aEndDocPos) |
|
1648 { |
|
1649 FormatCharRangeL(aStartDocPos,aEndDocPos,0); |
|
1650 } |
|
1651 |
|
1652 void CTextLayout::FormatCharRangeL(TInt aStartDocPos,TInt aEndDocPos,TInt aPixelOffset) |
|
1653 { |
|
1654 __ASSERT_DEBUG(aStartDocPos >= 0 && aStartDocPos <= DocumentLength(),Panic(EInvalidDocPos)); |
|
1655 __ASSERT_DEBUG(aEndDocPos >= 0 && aEndDocPos <= DocumentLength(),Panic(EInvalidDocPos)); |
|
1656 __ASSERT_DEBUG(aStartDocPos <= aEndDocPos,Panic(ENoCharRangeToFormat)); |
|
1657 |
|
1658 TTmFormatParam param; |
|
1659 InitFormatParam(param); |
|
1660 param.iStartChar = iSource->ParagraphStart(aStartDocPos); |
|
1661 param.iEndChar = aEndDocPos; |
|
1662 param.iMaxHeight = KMaxTInt; |
|
1663 iText->SetTextL(*iSource,param); |
|
1664 TTmLineInfo info; |
|
1665 TTmDocPos pos(aStartDocPos, ETrue); |
|
1666 if (iText->DocPosToLine(pos,info)) |
|
1667 iBandTop = info.iOuterRect.iTl.iY - aPixelOffset; |
|
1668 else |
|
1669 iBandTop = 0; //+ raise an exception? |
|
1670 } |
|
1671 |
|
1672 /** A special function to support background formatting by the higher level |
|
1673 CTextView class. It formats the next pending line. The return value is ETrue if |
|
1674 there is more formatting to do. On entry, aBotPixel contains the y coordinate |
|
1675 of the bottom of the formatted text; this is updated by the function. |
|
1676 |
|
1677 Notes: |
|
1678 |
|
1679 Not generally useful. |
|
1680 |
|
1681 Do not use if a CTextView object owns this CTextLayout object. |
|
1682 |
|
1683 @param aBotPixel On entry, contains the y coordinate of the bottom of the |
|
1684 formatted text; this is updated by the function. |
|
1685 @return ETrue if there is more formatting to do. EFalse if not. */ |
|
1686 EXPORT_C TBool CTextLayout::FormatNextLineL(TInt& aBottomPixel) |
|
1687 { |
|
1688 if (iUnformattedStart < KMaxTInt) |
|
1689 { |
|
1690 TTmFormatParamBase param; |
|
1691 InitFormatParam(param); |
|
1692 param.iMaxHeight = KMaxTInt; |
|
1693 TTmReformatParam reformat_param; |
|
1694 reformat_param.iStartChar = iUnformattedStart; |
|
1695 reformat_param.iMaxExtraLines = KMaxExtraLines; |
|
1696 reformat_param.iParInvalid = iParInvalid; |
|
1697 TTmReformatResult result; |
|
1698 iText->FormatL(param,reformat_param,result); |
|
1699 |
|
1700 // If there is no formatting to do, indicate that formatting is complete to the end of the paragraph |
|
1701 if (result.iUnformattedStart == KMaxTInt) |
|
1702 { |
|
1703 TTmLineInfo info; |
|
1704 TTmDocPos pos(iUnformattedStart, ETrue); |
|
1705 TBool isFormatted = iText->DocPosToLine(pos,info); |
|
1706 __ASSERT_DEBUG(isFormatted, Panic(EPosNotFormatted)); |
|
1707 isFormatted = iText->ParNumberToLine(info.iParNumber,KMaxTInt,info); |
|
1708 __ASSERT_DEBUG(isFormatted, Panic(EPosNotFormatted)); |
|
1709 aBottomPixel = info.iOuterRect.iBr.iY - iBandTop; |
|
1710 } |
|
1711 |
|
1712 // Indicate that formatting is complete up to the lower edge of the current line. |
|
1713 else |
|
1714 aBottomPixel = result.iRedrawRect.iBr.iY - iBandTop; |
|
1715 iUnformattedStart = result.iUnformattedStart; |
|
1716 } |
|
1717 return iUnformattedStart < KMaxTInt; |
|
1718 } |
|
1719 |
|
1720 /** Controls the height of a single line, for use by the pagination system |
|
1721 only. Using the format supplied in aParaFormat, determines the height of the |
|
1722 line containing aDocPos and returns it in aHeight. Changes aDocPos to the end |
|
1723 of the line and returns ETrue if that position is not the end of the paragraph. |
|
1724 |
|
1725 Notes: |
|
1726 |
|
1727 Not generally useful; it exists for use by the pagination system only. |
|
1728 |
|
1729 Do not use if a CTextView object owns this CTextLayout object. |
|
1730 |
|
1731 @param aParaFormat Contains paragraph formatting. |
|
1732 @param aDocPos A document position. On return, contains the document position |
|
1733 of the end of the line. |
|
1734 @param aHeight On return, contains the height of the formatted line containing |
|
1735 aDocPos. |
|
1736 @param aPageBreak On return, ETrue if the last character on the line is a page |
|
1737 break. EFalse if not. |
|
1738 @return ETrue if the line is not the last line in the paragraph. EFalse if it is |
|
1739 the last line. */ |
|
1740 EXPORT_C TBool CTextLayout::FormatLineL(CParaFormat* /*aParaFormat*/,TInt& aDocPos, |
|
1741 TInt& aHeight,TBool& aPageBreak) |
|
1742 { |
|
1743 // If the line is not formatted, replace the formatted text with the single paragraph containing the line. |
|
1744 if (aDocPos < iText->StartChar() || aDocPos >= iText->EndChar()) |
|
1745 { |
|
1746 TTmFormatParam param; |
|
1747 InitFormatParam(param); |
|
1748 param.iStartChar = iSource->ParagraphStart(aDocPos); |
|
1749 param.iEndChar = iSource->ParagraphEnd(aDocPos); |
|
1750 param.iMaxHeight = KMaxTInt; |
|
1751 iText->SetTextL(*iSource,param); |
|
1752 } |
|
1753 TTmLineInfo info; |
|
1754 TTmDocPos pos(aDocPos, ETrue); |
|
1755 if (!iText->DocPosToLine(pos,info)) |
|
1756 User::Leave(KErrGeneral); |
|
1757 aHeight = info.iOuterRect.Height(); |
|
1758 aDocPos = info.iEnd; |
|
1759 TPtrC text; |
|
1760 TTmCharFormat format; |
|
1761 iSource->GetText(info.iEnd - 1,text,format); |
|
1762 aPageBreak = text[0] == CEditableText::EPageBreak; |
|
1763 |
|
1764 return !(info.iFlags & TTmLineInfo::EParEnd); |
|
1765 } |
|
1766 |
|
1767 /** Scrolls the text up or down by aNumParas paragraphs, disallowing blank |
|
1768 space at the bottom of the visible area if aScrollBlankSpace is |
|
1769 CTextLayout::EFDisallowScrollingBlankSpace. |
|
1770 |
|
1771 Do not use if a CTextView object owns this CTextLayout object. |
|
1772 |
|
1773 @param aNumParas The number of paragraphs to scroll; may be a positive or |
|
1774 negative value. On return, contains the number of paragraphs not scrolled; that |
|
1775 is the difference between the requested number and the number of paragraphs |
|
1776 actually scrolled. |
|
1777 @param aScrollBlankSpace Only relevant when scrolling downwards. |
|
1778 CTextLayout::EFAllowScrollingBlankSpace allows blank space to scroll into the |
|
1779 visible area. CTextLayout::EFDisallowScrollingBlankSpace prevents blank space |
|
1780 from scrolling into the visible area. |
|
1781 @pre aPars must not scroll the display beyond the formatted range. If aPars |
|
1782 scrolls beyond the formatted range, this method will leave with the error code |
|
1783 CTextLayout::EPosNotFormatted |
|
1784 @return The number of pixels actually scrolled. */ |
|
1785 EXPORT_C TInt CTextLayout::ScrollParagraphsL(TInt& aPars,TAllowDisallow aScrollBlankSpace) |
|
1786 { |
|
1787 TTmFormatParam param; |
|
1788 InitFormatParam(param); |
|
1789 param.iMaxHeight = KMaxTInt; |
|
1790 TTmLineInfo info; |
|
1791 int height_increase = 0; |
|
1792 int paragraphs_increase = 0; |
|
1793 int cur_par = 0; |
|
1794 int desired_par = 0; |
|
1795 int pixels_to_scroll = 0; |
|
1796 |
|
1797 if (aPars > 0) |
|
1798 { |
|
1799 if (iText->YPosToLine(iBandTop,info)) |
|
1800 cur_par = info.iParNumber; |
|
1801 else |
|
1802 User::Leave(EPosNotFormatted); |
|
1803 if (info.iParTop < iBandTop) |
|
1804 aPars--; |
|
1805 desired_par = cur_par - aPars; |
|
1806 while (desired_par < 0 && iText->AddParL(param,TRUE,height_increase,paragraphs_increase)) |
|
1807 { |
|
1808 iBandTop += height_increase; |
|
1809 desired_par += paragraphs_increase; |
|
1810 } |
|
1811 aPars = -desired_par; |
|
1812 if (desired_par < 0) |
|
1813 desired_par = 0; |
|
1814 if (!iText->ParNumberToLine(desired_par,0,info)) |
|
1815 User::Leave(EPosNotFormatted); |
|
1816 pixels_to_scroll = iBandTop - info.iOuterRect.iTl.iY; |
|
1817 } |
|
1818 else if (aPars < 0) |
|
1819 { |
|
1820 int band_bottom = iBandTop + VisibleHeightInPixels(); |
|
1821 |
|
1822 // Extend formatting until the visible height is filled. |
|
1823 param.iEndChar = KMaxTInt; |
|
1824 param.iMaxHeight = band_bottom - iText->LayoutHeight(); |
|
1825 if(param.iMaxHeight > 0) |
|
1826 { |
|
1827 iText->ExtendFormattingDownwardsL(param); |
|
1828 } |
|
1829 |
|
1830 if (iText->YPosToLine(band_bottom - 1,info)) |
|
1831 cur_par = info.iParNumber; |
|
1832 else |
|
1833 User::Leave(EPosNotFormatted); |
|
1834 if (!((info.iFlags & TTmLineInfo::EParEnd) && info.iOuterRect.iBr.iY == band_bottom)) |
|
1835 aPars++; |
|
1836 desired_par = cur_par - aPars; |
|
1837 int last_par = iText->Paragraphs() - 1; |
|
1838 while (desired_par > last_par && iText->AddParL(param, EFalse, height_increase,paragraphs_increase)) |
|
1839 last_par += paragraphs_increase; |
|
1840 aPars = last_par - desired_par; |
|
1841 if (desired_par > last_par) |
|
1842 desired_par = last_par; |
|
1843 if (!iText->ParNumberToLine(desired_par,KMaxTInt,info)) |
|
1844 iText->AddParL(param, EFalse, height_increase, paragraphs_increase); |
|
1845 if (!iText->ParNumberToLine(desired_par,KMaxTInt,info)) |
|
1846 User::Leave(EPosNotFormatted); |
|
1847 pixels_to_scroll = band_bottom - info.iOuterRect.iBr.iY; |
|
1848 } |
|
1849 |
|
1850 return ScrollL(pixels_to_scroll,aScrollBlankSpace); |
|
1851 } |
|
1852 |
|
1853 /** Scrolls the text up or down by aNumLines lines, disallowing blank space at |
|
1854 the bottom of the visible area if aScrollBlankSpace is |
|
1855 CTextLayout::EFDisallowScrollingBlankSpace. |
|
1856 |
|
1857 Do not use if a CTextView object owns this CTextLayout object. |
|
1858 |
|
1859 @param aNumLines The number of lines to scroll; may be a positive or negative |
|
1860 value. On return, contains the number of lines not scrolled; that is, the |
|
1861 requested number, minus the number actually scrolled. |
|
1862 @param aScrollBlankSpace Only relevant when scrolling downwards. |
|
1863 CTextLayout::EFAllowScrollingBlankSpace allows blank space to scroll into the |
|
1864 visible area. CTextLayout::EFDisallowScrollingBlankSpace prevents blank space |
|
1865 from scrolling into the visible area. |
|
1866 @pre aLines must not scroll the display beyond the formatted range. If aLines |
|
1867 scrolls beyond the formatted range, this method will leave with the error code |
|
1868 CTextLayout::EPosNotFormatted |
|
1869 @return The number of pixels actually scrolled. */ |
|
1870 EXPORT_C TInt CTextLayout::ScrollLinesL(TInt& aLines,TAllowDisallow aScrollBlankSpace) |
|
1871 { |
|
1872 TTmFormatParam param; |
|
1873 InitFormatParam(param); |
|
1874 param.iMaxHeight = KMaxTInt; |
|
1875 TTmLineInfo info; |
|
1876 int height_increase = 0; |
|
1877 int paragraphs_increase = 0; |
|
1878 int lines_scrolled = aLines; |
|
1879 int visible_height = VisibleHeightInPixels(); |
|
1880 if (aLines > 0) // bring aLines lines into view at the top of the display |
|
1881 { |
|
1882 int desired_top_line_number = 0; |
|
1883 for (;;) |
|
1884 { |
|
1885 // Find the line number of the first visible line. |
|
1886 TBool partial_line = FALSE; |
|
1887 int top_line_number = 0; |
|
1888 if (iBandTop >= iText->LayoutHeight()) |
|
1889 top_line_number = iText->Lines(); |
|
1890 else |
|
1891 { |
|
1892 if (iText->YPosToLine(iBandTop,info)) |
|
1893 top_line_number = info.iLineNumber; |
|
1894 else |
|
1895 User::Leave(EPosNotFormatted); |
|
1896 partial_line = iBandTop > info.iOuterRect.iTl.iY; |
|
1897 } |
|
1898 |
|
1899 // Find the line number of the desired first visible line. |
|
1900 // Defect fix for INC015850. Changed IF so that if the currently |
|
1901 // visible top line is as tall or taller (due to a large font or picture) |
|
1902 // than the visible height of the view our desired top line remains |
|
1903 // the next one above so that a scroll takes place. |
|
1904 desired_top_line_number = top_line_number - aLines; |
|
1905 if (partial_line && (info.iOuterRect.iBr.iY-info.iOuterRect.iTl.iY < visible_height)) |
|
1906 desired_top_line_number++; |
|
1907 |
|
1908 // If the desired first visible line number is negative, more lines need to be formatted. |
|
1909 if (desired_top_line_number >= 0) |
|
1910 break; |
|
1911 if (!iText->AddParL(param,TRUE,height_increase,paragraphs_increase)) |
|
1912 break; |
|
1913 iBandTop += height_increase; |
|
1914 } |
|
1915 |
|
1916 if (desired_top_line_number < 0) |
|
1917 { |
|
1918 lines_scrolled += desired_top_line_number; |
|
1919 desired_top_line_number = 0; |
|
1920 } |
|
1921 aLines -= lines_scrolled; |
|
1922 if (lines_scrolled) |
|
1923 { |
|
1924 if (!iText->LineNumberToLine(desired_top_line_number,info)) |
|
1925 User::Leave(EPosNotFormatted); |
|
1926 // if the line to be scrolled to is taller than the screen, we want |
|
1927 // to make sure that the baseline is not scrolled off the screen. |
|
1928 if (visible_height < info.iBaseline - info.iOuterRect.iTl.iY) |
|
1929 return ScrollL(iBandTop + visible_height - info.iBaseline, aScrollBlankSpace); |
|
1930 return ScrollL(iBandTop - info.iOuterRect.iTl.iY,aScrollBlankSpace); |
|
1931 } |
|
1932 else |
|
1933 return 0; |
|
1934 } |
|
1935 else if (aLines < 0) // bring aLines lines into view at the bottom of the display |
|
1936 { |
|
1937 if (iScrollFlags & EFScrollOnlyToTopsOfLines) |
|
1938 { |
|
1939 // If we are restricting scroll to the tops of lines, then lines at |
|
1940 // bottom are irrelevant, so all we do is lose the top line. |
|
1941 if (!iText->YPosToLine(iBandTop, info)) |
|
1942 User::Leave(EPosNotFormatted); |
|
1943 return ScrollL(-info.iOuterRect.Height(), aScrollBlankSpace); |
|
1944 } |
|
1945 |
|
1946 int desired_bottom_line_number = 0; |
|
1947 int band_bottom = iBandTop + visible_height; |
|
1948 int last_formatted_line = iText->Lines() - 1; |
|
1949 |
|
1950 // Extend formatting until the visible height is filled. |
|
1951 param.iEndChar = KMaxTInt; |
|
1952 param.iMaxHeight = band_bottom - iText->LayoutHeight(); |
|
1953 if(param.iMaxHeight > 0) |
|
1954 { |
|
1955 iText->ExtendFormattingDownwardsL(param); |
|
1956 } |
|
1957 for (;;) |
|
1958 { |
|
1959 // Find the line number of the last visible line. |
|
1960 TBool partial_line = FALSE; |
|
1961 int bottom_line_number = 0; |
|
1962 if (iText->YPosToLine(band_bottom - 1,info)) |
|
1963 bottom_line_number = info.iLineNumber; |
|
1964 else |
|
1965 User::Leave(EPosNotFormatted); |
|
1966 partial_line = band_bottom < info.iOuterRect.iBr.iY; |
|
1967 |
|
1968 // Find the line number of the desired last visible line. |
|
1969 desired_bottom_line_number = bottom_line_number - aLines; |
|
1970 if (partial_line) |
|
1971 desired_bottom_line_number--; |
|
1972 |
|
1973 // If the desired last visible line number is greater than the last line, more lines need to be formatted. |
|
1974 if (desired_bottom_line_number <= last_formatted_line) |
|
1975 break; |
|
1976 if (!AddFormattingAtEndL(param, height_increase,paragraphs_increase)) |
|
1977 break; |
|
1978 last_formatted_line = iText->Lines() - 1; |
|
1979 } |
|
1980 |
|
1981 int shortfall = desired_bottom_line_number - last_formatted_line; |
|
1982 if (shortfall > 0) |
|
1983 { |
|
1984 lines_scrolled += shortfall; |
|
1985 desired_bottom_line_number = last_formatted_line; |
|
1986 } |
|
1987 aLines -= lines_scrolled; |
|
1988 if (lines_scrolled) |
|
1989 { |
|
1990 if (!iText->LineNumberToLine(desired_bottom_line_number,info)) |
|
1991 User::Leave(EPosNotFormatted); |
|
1992 return ScrollL(band_bottom - info.iOuterRect.iBr.iY,aScrollBlankSpace); |
|
1993 } |
|
1994 else |
|
1995 return 0; |
|
1996 } |
|
1997 else |
|
1998 return 0; |
|
1999 } |
|
2000 |
|
2001 /** Scrolls the text up or down by aPixels pixels, disallowing blank space at |
|
2002 the bottom of the visible area if aScrollBlankSpace is |
|
2003 CTextLayout::EFDisallowScrollingBlankSpace. |
|
2004 |
|
2005 The return value (not aPixels, as you would expect from ScrollParagraphsL() and |
|
2006 ScrollLinesL()) contains the number of pixels not successfully scrolled, that |
|
2007 is, the original value of aPixels, minus the number of pixels actually |
|
2008 scrolled. On return, aPixels is set to the number of pixels actually scrolled. |
|
2009 |
|
2010 Do not use if a CTextView object owns this CTextLayout object. |
|
2011 |
|
2012 @param aPixels The number of pixels to scroll; may be a positive or negative |
|
2013 value. On return, contains the number of pixels actually scrolled. |
|
2014 @param aScrollBlankSpace Only relevant when scrolling downwards. |
|
2015 CTextLayout::EFAllowScrollingBlankSpace allows blank space to scroll into the |
|
2016 visible area. CTextLayout::EFDisallowScrollingBlankSpace prevents blank space |
|
2017 from scrolling into the visible area. |
|
2018 @return The difference between the requested number of pixels to scroll and the |
|
2019 number of pixels actually scrolled. */ |
|
2020 EXPORT_C TInt CTextLayout::ChangeBandTopL(TInt& aPixels,TAllowDisallow aScrollBlankSpace) |
|
2021 { |
|
2022 int desired_pixels = aPixels; |
|
2023 aPixels = ScrollL(aPixels,aScrollBlankSpace); |
|
2024 return desired_pixels - aPixels; |
|
2025 } |
|
2026 |
|
2027 |
|
2028 |
|
2029 /** Scrolls the text up or down by aPixels pixels, allowing blank space at |
|
2030 top and bottom of the visible area, which means the scrolling can go beyond the |
|
2031 top or bottom border. |
|
2032 |
|
2033 Do not use if a CTextView object owns this CTextLayout object. |
|
2034 |
|
2035 @param aPixels The number of pixels to scroll; may be a positive or negative |
|
2036 value. The actual scrolled pixel number is always identical to aPixels*/ |
|
2037 EXPORT_C void CTextLayout::ChangeBandTopNoLimitBorderL(TInt aPixels) |
|
2038 { |
|
2039 ScrollL(aPixels,EFAllowScrollingBlankSpace,ETrue,ETrue); |
|
2040 } |
|
2041 |
|
2042 |
|
2043 /** |
|
2044 * Finds a position (in pixels, from the top of the window) where the cursor |
|
2045 * can be such that its line will be fully visible. If this is not possible, |
|
2046 * then return one with its baseline visible. If this is not possible, we don't |
|
2047 * care what the answer is. |
|
2048 */ |
|
2049 TInt CTextLayout::SuggestCursorPos(TInt aCurrentCursorPos) const |
|
2050 { |
|
2051 int visible_height = VisibleHeightInPixels(); |
|
2052 TTmLineInfo info; |
|
2053 if (iText->YPosToLine(iBandTop + aCurrentCursorPos, info)) |
|
2054 { |
|
2055 TBool currentLineHasBaselineVisible = |
|
2056 (TBool)(iBandTop <= info.iBaseline |
|
2057 && info.iBaseline < iBandTop + visible_height); |
|
2058 TInt tryThisLine = -1; |
|
2059 // find a good line to put the cursor on. |
|
2060 if (info.iOuterRect.iTl.iY < iBandTop) |
|
2061 { |
|
2062 // try next line |
|
2063 tryThisLine = info.iLineNumber + 1; |
|
2064 } |
|
2065 else if (iBandTop + visible_height < info.iOuterRect.iBr.iY) |
|
2066 { |
|
2067 tryThisLine = info.iLineNumber - 1; |
|
2068 } |
|
2069 if (0 <= tryThisLine && iText->LineNumberToLine(tryThisLine, info)) |
|
2070 { |
|
2071 if (iBandTop <= info.iOuterRect.iTl.iY |
|
2072 && info.iOuterRect.iBr.iY < iBandTop + visible_height) |
|
2073 // this line fully visible |
|
2074 aCurrentCursorPos = info.iBaseline - iBandTop; |
|
2075 else if (!currentLineHasBaselineVisible |
|
2076 && iBandTop <= info.iBaseline |
|
2077 && info.iBaseline < iBandTop + visible_height) |
|
2078 // not fully visible, but its baseline is, and the original |
|
2079 // line's baseline was not |
|
2080 aCurrentCursorPos = info.iBaseline - iBandTop; |
|
2081 } |
|
2082 } |
|
2083 return aCurrentCursorPos; |
|
2084 } |
|
2085 |
|
2086 /** Scrolls up by a page (that is the band height as set by SetBandHeight(), or |
|
2087 half that amount if scrolling over lines taller than this), moving the text |
|
2088 downwards. The current desired vertical cursor position is passed in |
|
2089 aYCursorPos and updated to a new suggested position as near as possible to it, |
|
2090 but within the visible text and on a baseline. |
|
2091 |
|
2092 Do not use if a CTextView object owns this CTextLayout object. |
|
2093 |
|
2094 @param aYCursorPos The current desired vertical cursor position. On return, |
|
2095 updated to a new suggested position as near as possible to it. |
|
2096 @param aPixelsScrolled On return, contains the number of pixels scrolled. */ |
|
2097 EXPORT_C void CTextLayout::PageUpL(TInt& aYCursorPos,TInt& aPixelsScrolled) |
|
2098 { |
|
2099 // Move the cursor into the visible area. |
|
2100 int visible_height = VisibleHeightInPixels(); |
|
2101 if (aYCursorPos < 0) |
|
2102 aYCursorPos = 0; |
|
2103 else if (aYCursorPos > visible_height) |
|
2104 aYCursorPos = visible_height - 1; |
|
2105 |
|
2106 TTmLineInfo info; |
|
2107 // position the top of the screen must be at least as low as |
|
2108 TInt longestScrollTo = iBandTop + visible_height |
|
2109 - visible_height * KMaxProportionOfScreenToScroll/1000; |
|
2110 // position the top of the screen must be at least as high as |
|
2111 TInt shortestScrollTo = iBandTop + visible_height |
|
2112 - visible_height * KMinProportionOfScreenToScroll/1000; |
|
2113 TInt desiredScrollTo = shortestScrollTo; |
|
2114 // find the line at the top of the screen |
|
2115 // (we cannot find the one that includes the first pixel off the screen |
|
2116 // because it might not have been formatted yet) |
|
2117 if (iText->YPosToLine(iBandTop, info)) |
|
2118 { |
|
2119 // subtract one from the line number if this was on the screen |
|
2120 TInt line = info.iLineNumber |
|
2121 - (info.iOuterRect.iTl.iY < iBandTop? 0 : 1) |
|
2122 + KNumberOfLinesToKeepVisibleDuringScroll; |
|
2123 if (iText->LineNumberToLine(Max(0, line), info)) |
|
2124 desiredScrollTo = info.iOuterRect.iTl.iY; |
|
2125 } |
|
2126 if (shortestScrollTo < desiredScrollTo) |
|
2127 desiredScrollTo = shortestScrollTo; |
|
2128 else if (desiredScrollTo < longestScrollTo) |
|
2129 desiredScrollTo = longestScrollTo; |
|
2130 aPixelsScrolled = ScrollL(iBandTop + visible_height - desiredScrollTo, |
|
2131 EFDisallowScrollingBlankSpace); |
|
2132 aYCursorPos = aPixelsScrolled == 0? |
|
2133 0 |
|
2134 : SuggestCursorPos(aYCursorPos); |
|
2135 } |
|
2136 |
|
2137 /** Scrolls down by a page (that is the band height as set by SetBandHeight(), |
|
2138 or half that amount if scrolling over lines taller than this), moving the text |
|
2139 upwards. The current desired vertical cursor position is passed in aYCursorPos |
|
2140 and updated to a new suggested position as near as possible to it, but within |
|
2141 the visible text and on a baseline. |
|
2142 |
|
2143 Do not use if a CTextView object owns this CTextLayout object. |
|
2144 |
|
2145 @param aYCursorPos The current desired vertical cursor position. On return, |
|
2146 updated to a new suggested position as near as possible to it. |
|
2147 @param aPixelsScrolled On return, contains the number of pixels scrolled - a |
|
2148 negative value. */ |
|
2149 EXPORT_C void CTextLayout::PageDownL(TInt& aYCursorPos,TInt& aPixelsScrolled) |
|
2150 { |
|
2151 // Move the cursor into the visible area. |
|
2152 int visible_height = VisibleHeightInPixels(); |
|
2153 if (aYCursorPos < 0) |
|
2154 aYCursorPos = 0; |
|
2155 else if (aYCursorPos > visible_height) |
|
2156 aYCursorPos = visible_height - 1; |
|
2157 |
|
2158 TTmLineInfo info; |
|
2159 // position the bottom of the screen must be at least as high as |
|
2160 TInt longestScrollTo = iBandTop + |
|
2161 visible_height * KMaxProportionOfScreenToScroll/1000; |
|
2162 // position the bottom of the screen must be at least as low as |
|
2163 TInt shortestScrollTo = iBandTop + visible_height * KMinProportionOfScreenToScroll/1000; |
|
2164 TInt desiredScrollTo = shortestScrollTo; |
|
2165 // find the line at the bottom of the screen |
|
2166 // (we cannot find the one that includes the first pixel off the screen |
|
2167 // because it might not have been formatted yet) |
|
2168 if (iText->YPosToLine(iBandTop + visible_height - 1, info)) |
|
2169 { |
|
2170 // add one to the line number if this was on the screen |
|
2171 TInt line = info.iLineNumber |
|
2172 + (iBandTop + visible_height < info.iBaseline? 0 : 1) |
|
2173 - KNumberOfLinesToKeepVisibleDuringScroll; |
|
2174 if (iText->LineNumberToLine(Max(0, line), info)) |
|
2175 desiredScrollTo = info.iOuterRect.iBr.iY; |
|
2176 } |
|
2177 if (desiredScrollTo < shortestScrollTo) |
|
2178 desiredScrollTo = shortestScrollTo; |
|
2179 else if (longestScrollTo < desiredScrollTo) |
|
2180 desiredScrollTo = longestScrollTo; |
|
2181 aPixelsScrolled = ScrollL(iBandTop - desiredScrollTo, |
|
2182 EFDisallowScrollingBlankSpace); |
|
2183 aYCursorPos = aPixelsScrolled == 0? |
|
2184 visible_height - 1 |
|
2185 : SuggestCursorPos(aYCursorPos); |
|
2186 |
|
2187 __ASSERT_DEBUG(-visible_height <= aPixelsScrolled, |
|
2188 Panic(EPageScrollError)); |
|
2189 __ASSERT_DEBUG(0 <= aYCursorPos && aYCursorPos <= visible_height, |
|
2190 Panic(EPageScrollError)); |
|
2191 } |
|
2192 |
|
2193 /** Reformats to reflect a single character edit. |
|
2194 |
|
2195 Do not use if a CTextView object owns this CTextLayout object. |
|
2196 |
|
2197 @param aType Indicates the type of edit which has taken place. |
|
2198 CTextLayout::EFCharacterInsert (the default) for a character insertion, |
|
2199 CTextLayout::EFParagraphDelimiter for a paragraph delimiter insertion, |
|
2200 CTextLayout::EFLeftDelete or CTextLayout::EFRightDelete for a character or |
|
2201 paragraph delimiter deletion to the left or right of the document position. |
|
2202 @param aCursorPos The document position at which the edit took place, before |
|
2203 the edit. If this position is not formatted, a panic occurs; it is modified in |
|
2204 accordance with the edit. |
|
2205 @param aGood On return, the y coordinate of the top of the paragraph following |
|
2206 the paragraph which has been edited, before the edit. |
|
2207 @param aFormattedUpTo On return, the y coordinate of the bottom of the |
|
2208 reformatted line or lines, after the edit. |
|
2209 @param aFormattedFrom On return, the vertical layout coordinate of the top of |
|
2210 the reformatted line or lines, after the edit. |
|
2211 @param aScroll The number of pixels by which the text had to be scrolled |
|
2212 (positive means text moved down). |
|
2213 @param aFormatChanged ETrue if text is to be reformatted from the start of the |
|
2214 paragraph the cursor was on before the edit, EFalse if from the start of the |
|
2215 line the cursor was on before the edit. |
|
2216 @return EFalse if no more lines need to be reformatted. ETrue if some more lines |
|
2217 need to be reformatted. */ |
|
2218 EXPORT_C TBool CTextLayout::HandleCharEditL(TUint aType,TInt& aCursorPos,TInt& aGood,TInt& aFormatBottom, |
|
2219 TInt& aFormatTop,TInt& aScroll,TBool aFormatFromStartOfPar) |
|
2220 { |
|
2221 __ASSERT_ALWAYS(iSource->iFormatMode != CLayoutData::EFPrintPreviewMode,Panic(EPrintPreviewModeError)); |
|
2222 __ASSERT_ALWAYS(aType <= EFRightDelete,Panic(EBadCharacterEditType)); |
|
2223 __ASSERT_ALWAYS(!aFormatFromStartOfPar || aType == EFRightDelete || aType == EFLeftDelete,Panic(EBadCharacterEditType)); |
|
2224 __ASSERT_ALWAYS(aCursorPos >= iText->StartChar() && aCursorPos < iText->EndChar(),Panic(ECharacterNotFormatted)); |
|
2225 |
|
2226 // Mark the entire paragraph invalid if background formatting is taking place. |
|
2227 iParInvalid = iUnformattedStart != KMaxTInt; |
|
2228 |
|
2229 // Cancel any pending background formatting, which has now been invalidated by the change. |
|
2230 iUnformattedStart = KMaxTInt; |
|
2231 |
|
2232 // Adjust the cursor position and determine the range of characters to reformat. |
|
2233 TTmReformatParam reformat_param; |
|
2234 reformat_param.iParInvalid = iParInvalid; |
|
2235 switch (aType) |
|
2236 { |
|
2237 case EFCharacterInsert: |
|
2238 case EFParagraphDelimiter: |
|
2239 reformat_param.iStartChar = aCursorPos++; |
|
2240 reformat_param.iNewLength = 1; |
|
2241 break; |
|
2242 case EFLeftDelete: |
|
2243 reformat_param.iStartChar = --aCursorPos; |
|
2244 reformat_param.iOldLength = 1; |
|
2245 break; |
|
2246 case EFRightDelete: |
|
2247 reformat_param.iStartChar = aCursorPos; |
|
2248 reformat_param.iOldLength = 1; |
|
2249 break; |
|
2250 default: break; |
|
2251 } |
|
2252 |
|
2253 // Set up the formatting parameters. |
|
2254 TTmFormatParam param; |
|
2255 InitFormatParam(param); |
|
2256 param.iMaxHeight = KMaxTInt; |
|
2257 |
|
2258 // Format the whole band if necessary. |
|
2259 TTmDocPos cursorPos(aCursorPos, EFalse); |
|
2260 if (reformat_param.iStartChar < iText->StartChar() || reformat_param.iStartChar + reformat_param.iOldLength >= iText->EndChar()) |
|
2261 { |
|
2262 FormatBandL(reformat_param.iStartChar,reformat_param.iStartChar + reformat_param.iOldLength); |
|
2263 aFormatTop = 0; |
|
2264 aFormatBottom = iText->LayoutHeight() - iBandTop; |
|
2265 aGood = aFormatBottom; |
|
2266 aScroll = 0; |
|
2267 ScrollDocPosIntoViewL(cursorPos); |
|
2268 return FALSE; |
|
2269 } |
|
2270 |
|
2271 // Reformat the chosen range. |
|
2272 reformat_param.iMaxExtraLines = KMaxExtraLines; |
|
2273 TTmReformatResult result; |
|
2274 iText->FormatL(param,reformat_param,result); |
|
2275 result.iRedrawRect.Move(0,-iBandTop); |
|
2276 iUnformattedStart = result.iUnformattedStart; |
|
2277 |
|
2278 // Scroll if necessary and extend the redraw area to include material scrolled into view. |
|
2279 aScroll = ScrollDocPosIntoViewL(cursorPos); |
|
2280 if (aScroll > 0) |
|
2281 result.iRedrawRect.iBr.iY += aScroll; |
|
2282 else |
|
2283 result.iRedrawRect.iTl.iY += aScroll; |
|
2284 |
|
2285 // Return coordinates. |
|
2286 aFormatTop = result.iRedrawRect.iTl.iY; |
|
2287 aFormatBottom = result.iRedrawRect.iBr.iY; |
|
2288 aGood = result.iUnchangedTop - iBandTop; |
|
2289 |
|
2290 // Add new paragraphs if necessary. |
|
2291 int visible_height = VisibleHeightInPixels(); |
|
2292 |
|
2293 param.iEndChar = KMaxTInt; |
|
2294 param.iMaxHeight = (iBandTop + visible_height) - iText->LayoutHeight(); |
|
2295 if(param.iMaxHeight > 0) |
|
2296 { |
|
2297 iText->ExtendFormattingDownwardsL(param); |
|
2298 } |
|
2299 |
|
2300 //remove formatting from the end if necessary |
|
2301 PruneFormatL(EFalse); |
|
2302 // Return TRUE if more text needs to be formatted. |
|
2303 return iUnformattedStart < KMaxTInt; |
|
2304 } |
|
2305 |
|
2306 /** Reformats to reflect changes to a block of text. |
|
2307 |
|
2308 Do not use if a CTextView object owns this CTextLayout object. |
|
2309 |
|
2310 @param aSelection The start and new length of the changed block. When |
|
2311 inserting, specify the insertion position. When deleting, specify the position |
|
2312 of the start of the deletion. When reformatting, specify the start and length |
|
2313 of the reformatted block. |
|
2314 @param aOldCharsChanged The old length of the changed block. When inserting, |
|
2315 specify zero. When deleting, specify the number of deleted characters. When |
|
2316 reformatting, specify the number of reformatted characters. |
|
2317 @param aViewChanges On return, contains the top of the reformatted text |
|
2318 (iFormattedFrom), the bottom of the reformatted text (iFormattedTo), the amount |
|
2319 by which the text above the reformatted text has scrolled (iScrollAtTop) and |
|
2320 the amount by which the text below the reformatted text has scrolled |
|
2321 (iScrollAtBottom) (positive values mean the text moves down). |
|
2322 @param aFormatChanged Indicates whether the paragraph format for the first or |
|
2323 last affected paragraph has changed, meaning that the text to be reformatted |
|
2324 must extend out to paragraph boundaries and cannot be restricted to only some |
|
2325 lines. */ |
|
2326 EXPORT_C void CTextLayout::HandleBlockChangeL(TCursorSelection aSelection,TInt aOldLength, |
|
2327 TViewRectChanges& aChanges,TBool aFormatFromStartOfPar) |
|
2328 { |
|
2329 __ASSERT_ALWAYS(iSource->iFormatMode != CLayoutData::EFPrintPreviewMode,Panic(EPrintPreviewModeError)); |
|
2330 |
|
2331 // Do nothing if the selection is outside the formatted range. |
|
2332 if (aSelection.LowerPos() > iText->EndChar() || aSelection.HigherPos() < iText->StartChar()) |
|
2333 { |
|
2334 aChanges.iFormattedFrom = 0; |
|
2335 aChanges.iFormattedTo = 0; |
|
2336 aChanges.iScrollAtTop = 0; |
|
2337 aChanges.iScrollAtBottom = 0; |
|
2338 return; |
|
2339 } |
|
2340 |
|
2341 // Format the whole band if necessary. |
|
2342 TTmDocPos cursorPos(aSelection.iCursorPos, |
|
2343 aSelection.iCursorPos < aSelection.iAnchorPos? ETrue : EFalse); |
|
2344 if (aSelection.LowerPos() < iText->StartChar() || aSelection.LowerPos() + aOldLength >= iText->EndChar()) |
|
2345 { |
|
2346 FormatBandL(aSelection.iCursorPos,aSelection.iCursorPos); |
|
2347 aChanges.iFormattedFrom = 0; |
|
2348 aChanges.iFormattedTo = VisibleHeightInPixels(); |
|
2349 aChanges.iScrollAtTop = 0; |
|
2350 aChanges.iScrollAtBottom = 0; |
|
2351 ScrollDocPosIntoViewL(cursorPos); |
|
2352 return; |
|
2353 } |
|
2354 |
|
2355 // Reformat the chosen range. |
|
2356 TTmFormatParam param; |
|
2357 InitFormatParam(param); |
|
2358 param.iMaxHeight = KMaxTInt; |
|
2359 TTmReformatParam reformat_param; |
|
2360 reformat_param.iStartChar = aSelection.LowerPos(); |
|
2361 reformat_param.iOldLength = aOldLength; |
|
2362 reformat_param.iNewLength = aSelection.Length(); |
|
2363 reformat_param.iParFormatChanged = aFormatFromStartOfPar; |
|
2364 TTmReformatResult result; |
|
2365 iText->FormatL(param,reformat_param,result); |
|
2366 result.iRedrawRect.Move(0,-iBandTop); |
|
2367 |
|
2368 // Scroll if necessary. |
|
2369 int dy; |
|
2370 if(iTextViewCursorPos) |
|
2371 { |
|
2372 dy = ScrollDocPosIntoViewL(iTextViewCursorPos->TmDocPos()); |
|
2373 iTextViewCursorPos = NULL; |
|
2374 } |
|
2375 else |
|
2376 { |
|
2377 dy = ScrollDocPosIntoViewL(cursorPos); |
|
2378 } |
|
2379 result.iRedrawRect.Move(0,dy); |
|
2380 |
|
2381 aChanges.iFormattedFrom = result.iRedrawRect.iTl.iY; |
|
2382 aChanges.iFormattedTo = result.iRedrawRect.iBr.iY; |
|
2383 aChanges.iScrollAtTop = dy; |
|
2384 aChanges.iScrollAtBottom = dy + result.iHeightChange; |
|
2385 |
|
2386 // Extend formatting to fill the band if necessary. |
|
2387 int visible_height = VisibleHeightInPixels(); |
|
2388 |
|
2389 param.iEndChar = KMaxTInt; |
|
2390 param.iMaxHeight = (iBandTop + visible_height) - iText->LayoutHeight(); |
|
2391 if(param.iMaxHeight > 0) |
|
2392 { |
|
2393 iText->ExtendFormattingDownwardsL(param); |
|
2394 } |
|
2395 |
|
2396 //remove formatting from the end if necessary |
|
2397 PruneFormatL(EFalse); |
|
2398 } |
|
2399 |
|
2400 /** Reformats to reflect the addition of one or more complete paragraphs at the |
|
2401 end of the text. |
|
2402 |
|
2403 Do not use if a CTextView object owns this CTextLayout object. |
|
2404 |
|
2405 @param aFirstPixel On return, the top y coordinate of the added material. |
|
2406 @param aLastPixel On return, the bottom y coordinate of the added material. |
|
2407 */ |
|
2408 EXPORT_C void CTextLayout::HandleAdditionalCharactersAtEndL(TInt& aNewTextTop,TInt& aNewTextBottom) |
|
2409 { |
|
2410 aNewTextTop = aNewTextBottom = iText->LayoutHeight() - iBandTop; |
|
2411 int format_required = BandHeightInPixels() - aNewTextBottom; |
|
2412 if (format_required > 0) |
|
2413 { |
|
2414 TTmFormatParam param; |
|
2415 InitFormatParam(param); |
|
2416 param.iMaxHeight = format_required; |
|
2417 TInt oldHeight = iText->LayoutHeight(); |
|
2418 iText->ExtendFormattingDownwardsL(param); |
|
2419 aNewTextBottom += (iText->LayoutHeight() - oldHeight); |
|
2420 } |
|
2421 } |
|
2422 |
|
2423 /** Reformats to reflect changes to the space above and below paragraphs |
|
2424 (CParaFormat::iSpaceBeforeInTwips and iSpaceAfterInTwips). |
|
2425 |
|
2426 Do not use if a CTextView object owns this CTextLayout object. |
|
2427 @deprecated 6.1 Use FormatBandL() |
|
2428 */ |
|
2429 EXPORT_C void CTextLayout::ReformatVerticalSpaceL() |
|
2430 { |
|
2431 // Reformat the whole band; only space above and below paragraphs has changed, but who cares? |
|
2432 FormatBandL(); |
|
2433 } |
|
2434 |
|
2435 /** Temporarily changes the vertical alignment of the text with respect to the |
|
2436 visible height. |
|
2437 |
|
2438 Notes: |
|
2439 |
|
2440 Not generally useful. |
|
2441 |
|
2442 Do not use if a CTextView object owns this CTextLayout object. |
|
2443 |
|
2444 @param aVerticalAlignment Specifies whether the formatted text should be placed |
|
2445 at the top (CParaFormat::ETopAlign), vertical centre (CParaFormat::ECenterAlign |
|
2446 or CParaFormat::EJustifiedAlign) or bottom (CParaFormat::EBottomAlign) of the |
|
2447 band. CParaFormat::EUnspecifiedAlign or CParaFormat::ECustomAlign may also be |
|
2448 specified. These values cause the baseline of the first formatted line to be |
|
2449 positioned 82% of the way down the band (provided for the Agenda's |
|
2450 application's year view). */ |
|
2451 EXPORT_C void CTextLayout::AdjustVerticalAlignment(CParaFormat::TAlignment aVerticalAlignment) |
|
2452 { |
|
2453 int excess = BandHeight() - FormattedHeightInPixels(); |
|
2454 int space_before = 0; |
|
2455 __ASSERT_ALWAYS(!IsFormattingBand(),Panic(EMustFormatAllText)); |
|
2456 TTmLineInfo info; |
|
2457 |
|
2458 switch (aVerticalAlignment) |
|
2459 { |
|
2460 case CParaFormat::EAbsoluteLeftAlign: |
|
2461 case CParaFormat::ETopAlign: |
|
2462 break; |
|
2463 case CParaFormat::ECenterAlign: |
|
2464 case CParaFormat::EJustifiedAlign: |
|
2465 space_before = excess / 2; |
|
2466 break; |
|
2467 case CParaFormat::EAbsoluteRightAlign: |
|
2468 case CParaFormat::EBottomAlign: |
|
2469 space_before = excess; |
|
2470 break; |
|
2471 case CParaFormat::EUnspecifiedAlign: |
|
2472 case CParaFormat::ECustomAlign: |
|
2473 if (iText->LineNumberToLine(0,info)) |
|
2474 { |
|
2475 space_before = CLayoutData::EFBaseLinePosition * BandHeight() / 100 - info.iBaseline; |
|
2476 } |
|
2477 else |
|
2478 { |
|
2479 space_before = CLayoutData::EFBaseLinePosition * BandHeight() / 100; |
|
2480 } |
|
2481 break; |
|
2482 } |
|
2483 |
|
2484 iBandTop = -space_before; |
|
2485 } |
|
2486 |
|
2487 static TInt SingleBorderWidthInPixels(const MGraphicsDeviceMap* aGd,const TParaBorder& aBorder,TBool aHoriz) |
|
2488 { |
|
2489 TInt width = aBorder.iThickness; |
|
2490 if (width > 0) |
|
2491 { |
|
2492 if (aHoriz) |
|
2493 width = aGd->VerticalTwipsToPixels(width); |
|
2494 else |
|
2495 width = aGd->HorizontalTwipsToPixels(width); |
|
2496 } |
|
2497 else |
|
2498 width = 1; |
|
2499 return width; |
|
2500 } |
|
2501 |
|
2502 /** Draws paragraph borders, optionally with a background colour for the border |
|
2503 and a clip region. Provided for applications that display a menu of border |
|
2504 styles, like a wordprocessor. |
|
2505 |
|
2506 @param aGd Provides twip-to-pixel conversion. |
|
2507 @param aGc Graphics context to which to draw the border. Its pen settings are |
|
2508 overridden by the values specified by aBorder and its draw mode is set to |
|
2509 CGraphicsContext::EDrawModePEN. |
|
2510 @param aRect The outer bounds of the border. |
|
2511 @param aBorder Specifies the four sides of the border. |
|
2512 @param aBackground If not null, the background colour, (used between double |
|
2513 border lines, or between dots or dashes). |
|
2514 @param aClipRegion If non-null, specifies a clip region. |
|
2515 @param aDrawRect If non-null, and if aClipRegion is non-null, specifies a |
|
2516 rectangle to be subtracted from the clip region. */ |
|
2517 EXPORT_C void CTextLayout::DrawBorders(const MGraphicsDeviceMap* aGd,CGraphicsContext& aGc,const TRect& aBoundingRect, |
|
2518 const TParaBorderArray& aBorder,const TRgb* aBackground,TRegion *aClipRegion, |
|
2519 const TRect* aDrawRect) |
|
2520 { |
|
2521 TPoint pointTl,pointBr; |
|
2522 TRect rect; |
|
2523 TInt * ptrStartLength=NULL; //To stop a warning |
|
2524 TInt * ptrEndLength=NULL; //To stop a warning |
|
2525 TInt * ptrStartWidth=NULL; //To stop a warning |
|
2526 TInt * ptrEndWidth=NULL; //To stop a warning |
|
2527 TInt directionOut=0; //To stop a warning |
|
2528 TInt indexJoint1=0,indexJoint2=0; //To stop a warning |
|
2529 TBool drawAsLine=EFalse; |
|
2530 TRect clipRect; |
|
2531 CGraphicsContext::TPenStyle penStyle[4]; |
|
2532 TInt widthInPixels[4]; |
|
2533 TBool horiz; |
|
2534 const MFormParam* form_param = MFormParam::Get(); |
|
2535 |
|
2536 {for (TInt border=0; border<=3; border++) |
|
2537 { |
|
2538 TParaBorder::TLineStyle lineStyle=aBorder.iBorder[border].iLineStyle; |
|
2539 if (lineStyle == TParaBorder::ENullLineStyle) |
|
2540 { |
|
2541 penStyle[border]=CGraphicsContext::ENullPen; |
|
2542 widthInPixels[border]=0; |
|
2543 continue; |
|
2544 } |
|
2545 else |
|
2546 { |
|
2547 horiz=(border==CParaFormat::EParaBorderTop || border==CParaFormat::EParaBorderBottom); |
|
2548 |
|
2549 widthInPixels[border]=SingleBorderWidthInPixels(aGd,aBorder.iBorder[border],horiz); |
|
2550 } |
|
2551 |
|
2552 if (lineStyle==TParaBorder::ESolid || lineStyle==TParaBorder::EDouble) |
|
2553 { |
|
2554 penStyle[border]=CGraphicsContext::ESolidPen; |
|
2555 continue; |
|
2556 } |
|
2557 |
|
2558 if (lineStyle == TParaBorder::EDashed) |
|
2559 penStyle[border]=CGraphicsContext::EDashedPen; |
|
2560 else if (lineStyle == TParaBorder::EDotted) |
|
2561 penStyle[border]=CGraphicsContext::EDottedPen; |
|
2562 else if (lineStyle == TParaBorder::EDotDash) |
|
2563 penStyle[border]=CGraphicsContext::EDotDashPen; |
|
2564 else if (lineStyle == TParaBorder::EDotDotDash) |
|
2565 penStyle[border]=CGraphicsContext::EDotDotDashPen; |
|
2566 |
|
2567 }} |
|
2568 |
|
2569 {for (TInt border=0; border<=3; border++) |
|
2570 { |
|
2571 // Go to next border, if have NULL linestyle. |
|
2572 if (widthInPixels[border]==0) |
|
2573 continue; |
|
2574 |
|
2575 // Reset clipping region |
|
2576 clipRect.SetSize(TSize(0,0)); |
|
2577 |
|
2578 // Draw as line if not solid lines. |
|
2579 |
|
2580 if (penStyle[border]!=CGraphicsContext::ESolidPen) |
|
2581 drawAsLine=ETrue; |
|
2582 |
|
2583 pointTl=aBoundingRect.iTl; |
|
2584 pointBr=aBoundingRect.iBr; |
|
2585 |
|
2586 if (border==CParaFormat::EParaBorderLeft) |
|
2587 { |
|
2588 pointBr.iX=pointTl.iX; |
|
2589 ptrStartLength=&pointTl.iY; |
|
2590 ptrEndLength=&pointBr.iY; |
|
2591 ptrStartWidth=&pointTl.iX; |
|
2592 ptrEndWidth=&pointBr.iX; |
|
2593 directionOut=-1; |
|
2594 indexJoint1=CParaFormat::EParaBorderTop; |
|
2595 indexJoint2=CParaFormat::EParaBorderBottom; |
|
2596 } |
|
2597 if (border == CParaFormat::EParaBorderRight) |
|
2598 { |
|
2599 pointTl.iX=pointBr.iX; |
|
2600 ptrStartLength=&pointTl.iY; |
|
2601 ptrEndLength=&pointBr.iY; |
|
2602 ptrStartWidth=&pointTl.iX; |
|
2603 ptrEndWidth=&pointBr.iX; |
|
2604 directionOut=1; |
|
2605 indexJoint1=CParaFormat::EParaBorderTop; |
|
2606 indexJoint2=CParaFormat::EParaBorderBottom; |
|
2607 } |
|
2608 if (border == CParaFormat::EParaBorderTop) |
|
2609 { |
|
2610 pointBr.iY=pointTl.iY; |
|
2611 ptrStartLength=&pointTl.iX; |
|
2612 ptrEndLength=&pointBr.iX; |
|
2613 ptrStartWidth=&pointTl.iY; |
|
2614 ptrEndWidth=&pointBr.iY; |
|
2615 directionOut=-1; |
|
2616 indexJoint1=CParaFormat::EParaBorderLeft; |
|
2617 indexJoint2=CParaFormat::EParaBorderRight; |
|
2618 } |
|
2619 if (border == CParaFormat::EParaBorderBottom) |
|
2620 { |
|
2621 pointTl.iY=pointBr.iY; |
|
2622 ptrStartLength=&pointTl.iX; |
|
2623 ptrEndLength=&pointBr.iX; |
|
2624 ptrStartWidth=&pointTl.iY; |
|
2625 ptrEndWidth=&pointBr.iY; |
|
2626 directionOut=1; |
|
2627 indexJoint1=CParaFormat::EParaBorderLeft; |
|
2628 indexJoint2=CParaFormat::EParaBorderRight; |
|
2629 } |
|
2630 |
|
2631 if (!ptrStartWidth || !ptrEndWidth) |
|
2632 { |
|
2633 continue; |
|
2634 } |
|
2635 |
|
2636 if (drawAsLine) |
|
2637 { |
|
2638 if (directionOut<0) |
|
2639 { |
|
2640 (*ptrStartWidth)+=(widthInPixels[border]-1)/2; |
|
2641 (*ptrEndWidth)+=(widthInPixels[border]-1)/2; |
|
2642 } |
|
2643 else |
|
2644 { |
|
2645 (*ptrStartWidth)-=(widthInPixels[border]+2)/2; |
|
2646 (*ptrEndWidth)-=(widthInPixels[border]+2)/2; |
|
2647 } |
|
2648 (*ptrStartLength)+=(widthInPixels[border]-1)/2; |
|
2649 (*ptrEndLength)-=(widthInPixels[border])/2; |
|
2650 } |
|
2651 else |
|
2652 { |
|
2653 if (directionOut<0) |
|
2654 (*ptrEndWidth)+=widthInPixels[border]; |
|
2655 else |
|
2656 (*ptrStartWidth)-=widthInPixels[border]; |
|
2657 } |
|
2658 |
|
2659 // Colour of pen as is - NO logical combination with background etc. |
|
2660 aGc.SetDrawMode(CGraphicsContext::EDrawModePEN); |
|
2661 |
|
2662 if (drawAsLine) |
|
2663 { |
|
2664 // Must draw lines in background colour first, as have dotted/dashed lines. |
|
2665 aGc.SetPenSize(TSize(widthInPixels[border],widthInPixels[border])); |
|
2666 if (aBackground) |
|
2667 { |
|
2668 FormUtil::SetPenColor(form_param,&aGc,*aBackground); |
|
2669 aGc.SetPenStyle(CGraphicsContext::ESolidPen); |
|
2670 aGc.DrawLine(pointTl,pointBr); |
|
2671 } |
|
2672 FormUtil::SetPenColor(form_param,&aGc,aBorder.iBorder[border].iColor); |
|
2673 aGc.SetPenStyle(penStyle[border]); |
|
2674 aGc.DrawLine(pointTl,pointBr); |
|
2675 (*ptrStartWidth)-=(widthInPixels[border]-1)/2; |
|
2676 (*ptrEndWidth)+=(widthInPixels[border]+2)/2; |
|
2677 (*ptrStartLength)-=(widthInPixels[border]-1)/2; |
|
2678 (*ptrEndLength)+=(widthInPixels[border])/2; |
|
2679 clipRect.SetRect(pointTl,pointBr); |
|
2680 } |
|
2681 else |
|
2682 { |
|
2683 // Brush |
|
2684 FormUtil::SetBrushColor(form_param,&aGc,aBorder.iBorder[border].iColor); |
|
2685 aGc.SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
2686 aGc.SetPenStyle(CGraphicsContext::ENullPen); |
|
2687 rect.SetRect(pointTl,pointBr); |
|
2688 aGc.DrawRect(rect); |
|
2689 clipRect=rect; |
|
2690 }; |
|
2691 |
|
2692 // Repeat draw, for double border. |
|
2693 if (aBorder.iBorder[border].iLineStyle==TParaBorder::EDouble) // Now have only got solid border, drawn as rect. |
|
2694 { |
|
2695 __ASSERT_DEBUG(!drawAsLine,Panic(EDrawingBorderError)); |
|
2696 (*ptrStartWidth)-=directionOut*widthInPixels[border]; |
|
2697 (*ptrEndWidth)-=directionOut*widthInPixels[border]; |
|
2698 (*ptrStartLength)+=widthInPixels[indexJoint1]; |
|
2699 (*ptrEndLength)-=widthInPixels[indexJoint2]; |
|
2700 |
|
2701 if (aBackground) |
|
2702 { |
|
2703 rect.SetRect(pointTl,pointBr); |
|
2704 FormUtil::SetBrushColor(form_param,&aGc,*aBackground); |
|
2705 aGc.DrawRect(rect); |
|
2706 } |
|
2707 |
|
2708 (*ptrStartWidth)-=directionOut*widthInPixels[border]; |
|
2709 (*ptrEndWidth)-=directionOut*widthInPixels[border]; |
|
2710 |
|
2711 if (aBorder.iBorder[indexJoint1].iLineStyle==TParaBorder::EDouble) |
|
2712 (*ptrStartLength)+=widthInPixels[indexJoint1]; |
|
2713 if (aBorder.iBorder[indexJoint2].iLineStyle==TParaBorder::EDouble) |
|
2714 (*ptrEndLength)-=widthInPixels[indexJoint2]; |
|
2715 |
|
2716 rect.SetRect(pointTl,pointBr); |
|
2717 FormUtil::SetBrushColor(form_param,&aGc,aBorder.iBorder[border].iColor); |
|
2718 aGc.DrawRect(rect); |
|
2719 clipRect.BoundingRect(rect); |
|
2720 }; |
|
2721 |
|
2722 |
|
2723 // Restore defaults |
|
2724 aGc.SetPenStyle(CGraphicsContext::ESolidPen); |
|
2725 aGc.SetPenSize(TSize(1,1)); |
|
2726 // Should change to BACKGROUND colour. |
|
2727 if (aBackground) |
|
2728 FormUtil::SetBrushColor(form_param,&aGc,*aBackground); |
|
2729 // If have to clip region, then remove rectangles corresponding to the border region. |
|
2730 |
|
2731 if (aClipRegion) |
|
2732 { |
|
2733 if (aDrawRect) |
|
2734 clipRect.Intersection(*aDrawRect); |
|
2735 aClipRegion->SubRect(clipRect); |
|
2736 } |
|
2737 |
|
2738 }}; |
|
2739 |
|
2740 if (aClipRegion) |
|
2741 { |
|
2742 aClipRegion->Tidy(); |
|
2743 ((CWindowGc *) &aGc)->SetClippingRegion(*aClipRegion); |
|
2744 } |
|
2745 |
|
2746 } |
|
2747 |
|
2748 /** Draws the text. Draws any lines that intersect aDrawRect, which is |
|
2749 specified in window coordinates. The drawing parameters, including the graphics |
|
2750 context, are given in aDrawTextLayoutContext. If aHighlight is non-null, |
|
2751 highlights (by exclusive-ORing) the specified range of text. |
|
2752 |
|
2753 @param aDrawRect The function draw the lines within the visible area, which |
|
2754 intersect this rectangle (which is specified in window coordinates). |
|
2755 @param aDrawTextLayoutContext Provides a graphics context and other parameters |
|
2756 for the function. |
|
2757 @param aHighlight If not NULL, this range of text is drawn highlighted. */ |
|
2758 EXPORT_C void CTextLayout::DrawL(const TRect& aDrawRect,const TDrawTextLayoutContext* aDrawTextLayoutContext, |
|
2759 const TCursorSelection* aHighlight) |
|
2760 { |
|
2761 // Set the drawing parameters in the MTmSource interface. |
|
2762 iSource->iFormParam = MFormParam::Get(); |
|
2763 iSource->iLabelsGutter = aDrawTextLayoutContext->iGutterMarginWidth; |
|
2764 |
|
2765 // Calculate the top left corner of the text. |
|
2766 TPoint top_left = aDrawTextLayoutContext->TopLeftText(); |
|
2767 top_left.iY -= iBandTop; |
|
2768 |
|
2769 // Get the graphics context. |
|
2770 CGraphicsContext* gc = aDrawTextLayoutContext->PrimaryGc(); |
|
2771 |
|
2772 /* |
|
2773 Clip the draw rectangle to the view rectangle, and clip it further to exclude |
|
2774 a final partial line if necessary. |
|
2775 */ |
|
2776 TRect clip_rect(aDrawRect); |
|
2777 clip_rect.Intersection(aDrawTextLayoutContext->iViewRect); |
|
2778 |
|
2779 |
|
2780 if (aDrawTextLayoutContext->UseClippingRect()) |
|
2781 { |
|
2782 gc->SetClippingRect(clip_rect); |
|
2783 } |
|
2784 |
|
2785 // Draw the text and background. |
|
2786 |
|
2787 TBool isDrawingOnAWindowDC = aDrawTextLayoutContext->UseWindowGc(); |
|
2788 |
|
2789 if (isDrawingOnAWindowDC) |
|
2790 { |
|
2791 BeginRedraw(clip_rect); |
|
2792 } |
|
2793 |
|
2794 iText->DrawLayout(*gc,top_left,clip_rect,&aDrawTextLayoutContext->iBackgroundColor,TRUE, aHighlight, iHighlightExtensions); |
|
2795 |
|
2796 if (isDrawingOnAWindowDC) |
|
2797 { |
|
2798 EndRedraw(); |
|
2799 } |
|
2800 |
|
2801 iSource->iFormParam = NULL; |
|
2802 } |
|
2803 |
|
2804 /** Default constructor. |
|
2805 |
|
2806 The start and end positions are set to zero - Set() should be called to |
|
2807 initialise the object. */ |
|
2808 EXPORT_C CTextLayout::TRangeChange::TRangeChange() |
|
2809 : iA(0), iB(0) {} |
|
2810 |
|
2811 /** Sets the start and end positions and whether the highlighting should be |
|
2812 set or cleared. |
|
2813 |
|
2814 Called by the non-default constructor. The start and end positions can be |
|
2815 specified in any order. |
|
2816 |
|
2817 @param aStart The start of the range. |
|
2818 @param aEnd The end of the range. |
|
2819 @param aChange Whether the highlighting should be set or cleared. */ |
|
2820 EXPORT_C void CTextLayout::TRangeChange::Set(TInt aStart, TInt aEnd, |
|
2821 CTextLayout::TRangeChange::TChangeType aChange) |
|
2822 { |
|
2823 if ((aChange == ESet && aStart < aEnd) |
|
2824 || (!(aChange == ESet) && !(aStart < aEnd))) |
|
2825 { |
|
2826 iA = aStart; |
|
2827 iB = aEnd; |
|
2828 } |
|
2829 else |
|
2830 { |
|
2831 iA = aEnd; |
|
2832 iB = aStart; |
|
2833 } |
|
2834 } |
|
2835 |
|
2836 /** Constructor with a start and end position and whether the highlighting |
|
2837 in the range should be set or cleared. |
|
2838 |
|
2839 The start and end positions can be specified in any order. |
|
2840 |
|
2841 @param aStart The start position. |
|
2842 @param aEnd The end position. |
|
2843 @param aChange Specifies whether the highlighting should be set or cleared. |
|
2844 */ |
|
2845 EXPORT_C CTextLayout::TRangeChange::TRangeChange(TInt aStart, TInt aEnd, |
|
2846 CTextLayout::TRangeChange::TChangeType aChange) |
|
2847 { |
|
2848 Set(aStart, aEnd, aChange); |
|
2849 } |
|
2850 |
|
2851 /** Gets the start and end of the range and whether the highlighting should be |
|
2852 set or cleared. |
|
2853 |
|
2854 @param aStart On return, the start of the range. This is always the lesser of |
|
2855 the two positions. |
|
2856 @param aEnd On return, the end of the range. This is always the greater of the |
|
2857 two positions. |
|
2858 @return Specifies whether the highlighting should be set or cleared. */ |
|
2859 EXPORT_C CTextLayout::TRangeChange::TChangeType |
|
2860 CTextLayout::TRangeChange::Get(TInt& aStart, TInt& aEnd) const |
|
2861 { |
|
2862 if (iA < iB) |
|
2863 { |
|
2864 aStart = iA; |
|
2865 aEnd = iB; |
|
2866 return ESet; |
|
2867 } |
|
2868 aStart = iB; |
|
2869 aEnd = iA; |
|
2870 return EClear; |
|
2871 } |
|
2872 |
|
2873 /** Tests whether the range is not null. |
|
2874 |
|
2875 @return ETrue if the range is not of zero length, EFalse if the range is of zero |
|
2876 length. */ |
|
2877 EXPORT_C TBool CTextLayout::TRangeChange::NonNull() const |
|
2878 { |
|
2879 return iA - iB; |
|
2880 } |
|
2881 |
|
2882 /** Clips the range so that its start and end positions are within the minimum |
|
2883 and maximum positions specified. |
|
2884 |
|
2885 @param aMin The minimum value for the start and end of the range. |
|
2886 @param aMax The maximum value for the start and end of the range. |
|
2887 @return ETrue if the resulting range is not of zero length, EFalse if it is of |
|
2888 zero length. */ |
|
2889 EXPORT_C TBool CTextLayout::TRangeChange::Clip(TInt aMin, TInt aMax) |
|
2890 { |
|
2891 if (iA < aMin) |
|
2892 iA = aMin; |
|
2893 if (iB < aMin) |
|
2894 iB = aMin; |
|
2895 if (aMax < iA) |
|
2896 iA = aMax; |
|
2897 if (aMax < iB) |
|
2898 iB = aMax; |
|
2899 return iA - iB; |
|
2900 } |
|
2901 |
|
2902 /** Try to cancel out sections of the ranges that overlap Merges two ranges of |
|
2903 characters. |
|
2904 |
|
2905 Two successive calls to CTextLayout::Highlight() could cause unecessary flicker |
|
2906 or redrawing if the arguments to each call overlap. For example, if extending a |
|
2907 highlight involved removing the old highlight and then drawing the new one, |
|
2908 this would cause visible flicker. This can be eliminated by calling this |
|
2909 function to remove any overlap between the two ranges. If there is overlap, |
|
2910 this range is set to the result of the merge, and the other range (aBuddy) is |
|
2911 set to zero. |
|
2912 |
|
2913 When calling this function, it does not matter whether or not the two ranges |
|
2914 overlap. Also it does not matter which range is the parameter and which is the |
|
2915 calling object. After calling OptimizeWith(), it is guaranteed that the |
|
2916 resulting ranges will not overlap, and they will represent the same change to |
|
2917 the highlight as the original two ranges. |
|
2918 |
|
2919 See the code fragment in the class description for TRangeChange for an example |
|
2920 of how this function is used. |
|
2921 |
|
2922 @param aBuddy The range of characters to combine with this range. */ |
|
2923 EXPORT_C void CTextLayout::TRangeChange::OptimizeWith(TRangeChange& aBuddy) |
|
2924 { |
|
2925 // we make this have the minimum iA and iB, and aBuddy have the maximum |
|
2926 if (aBuddy.iA < iA) |
|
2927 { |
|
2928 TInt temp = aBuddy.iA; |
|
2929 aBuddy.iA = iA; |
|
2930 iA = temp; |
|
2931 } |
|
2932 if (aBuddy.iB < iB) |
|
2933 { |
|
2934 TInt temp = aBuddy.iB; |
|
2935 aBuddy.iB = iB; |
|
2936 iB = temp; |
|
2937 } |
|
2938 // if they now overlap, we combine them into one and zero the other |
|
2939 if (aBuddy.iB <= iA) |
|
2940 iA = aBuddy.iB = aBuddy.iA; |
|
2941 else if (aBuddy.iA <= iB) |
|
2942 iB = aBuddy.iA = aBuddy.iB; |
|
2943 } |
|
2944 |
|
2945 |
|
2946 TBool CTextLayout::TRangeChange::IsJoinedTo(const TRangeChange aRange) |
|
2947 { |
|
2948 TInt a1 = (iA < iB) ? iA : iB; |
|
2949 TInt b1 = (iA < iB) ? iB : iA; |
|
2950 TInt a2 = (aRange.iA < aRange.iB) ? aRange.iA : aRange.iB; |
|
2951 TInt b2 = (aRange.iA < aRange.iB) ? aRange.iB : aRange.iA; |
|
2952 |
|
2953 return a2 <= b1 && a1 <= b2; |
|
2954 } |
|
2955 |
|
2956 void CTextLayout::TRangeChange::Join(const TRangeChange aRange) |
|
2957 { |
|
2958 TInt a1 = (iA < iB) ? iA : iB; |
|
2959 TInt b1 = (iA < iB) ? iB : iA; |
|
2960 TInt a2 = (aRange.iA < aRange.iB) ? aRange.iA : aRange.iB; |
|
2961 TInt b2 = (aRange.iA < aRange.iB) ? aRange.iB : aRange.iA; |
|
2962 |
|
2963 // type set to ESet |
|
2964 iA = (a1 < a2) ? a1 : a2; |
|
2965 iB = (b1 > b2) ? b1 : b2; |
|
2966 } |
|
2967 |
|
2968 |
|
2969 /** Sets or clears a highlight. |
|
2970 |
|
2971 If the range of characters to highlight is of zero length, the function has no |
|
2972 effect. |
|
2973 |
|
2974 The function affects only those lines that intersect aDrawRect, which is |
|
2975 specified in window coordinates. The drawing parameters, including the graphics |
|
2976 context, are given in aDrawTextLayoutContext. |
|
2977 |
|
2978 From v7.0, this function replaces InvertRangeL(). |
|
2979 |
|
2980 This function is not intended to be used to set any part of a highlight already |
|
2981 set, nor to clear any piece of text not highlighted. It is intended to do |
|
2982 either or both of: clear an existing selection, set a new selection. See the |
|
2983 class description for TRangeChange for a code fragment showing how this |
|
2984 function should be used. |
|
2985 |
|
2986 @param aHighlight Specifies the range of characters to highlight or from which |
|
2987 to remove the highlight. |
|
2988 @param aDrawRect Only lines which intersect this rectangle are affected |
|
2989 (specified in window coordinates). |
|
2990 @param aDrawTextLayoutContext Provides a graphics context and other drawing |
|
2991 parameters, e.g. the text and background colours for the highlighted region. */ |
|
2992 |
|
2993 EXPORT_C void CTextLayout::Highlight(const CTextLayout::TRangeChange& aChangeHighlight, |
|
2994 const TRect& aDrawRect, const TDrawTextLayoutContext* aDrawTextLayoutContext) |
|
2995 { |
|
2996 if (!aChangeHighlight.NonNull()) |
|
2997 return; |
|
2998 |
|
2999 TRect clip_rect(aDrawRect); |
|
3000 |
|
3001 CGraphicsContext* gc = aDrawTextLayoutContext->PrimaryGc(); |
|
3002 if (aDrawTextLayoutContext->UseClippingRect()) |
|
3003 gc->SetClippingRect(clip_rect); |
|
3004 |
|
3005 TInt visible_start; |
|
3006 TInt visible_length = PosRangeInBand(visible_start); |
|
3007 |
|
3008 TInt start_pos; |
|
3009 TInt end_pos; |
|
3010 |
|
3011 CTextLayout::TRangeChange::TChangeType type = aChangeHighlight.Get(start_pos, end_pos); |
|
3012 start_pos = start_pos < visible_start? visible_start : start_pos; |
|
3013 end_pos = end_pos < visible_start + visible_length? end_pos : start_pos + visible_length; |
|
3014 TCursorSelection selection(start_pos, end_pos); |
|
3015 |
|
3016 TPoint top_left = aDrawTextLayoutContext->TopLeftText(); |
|
3017 top_left.iY -= iBandTop; |
|
3018 |
|
3019 TBool isDrawingOnAWindowDC = aDrawTextLayoutContext->UseWindowGc(); |
|
3020 |
|
3021 TRect boundingRect; |
|
3022 iText->GetUpdateBoundingRect(start_pos, end_pos, top_left, boundingRect); |
|
3023 iHighlightExtensions->AbsExtendRect(boundingRect); |
|
3024 boundingRect.Intersection(clip_rect); |
|
3025 if (! boundingRect.IsEmpty()) |
|
3026 { |
|
3027 if (isDrawingOnAWindowDC) |
|
3028 { |
|
3029 BeginRedraw(boundingRect); |
|
3030 } |
|
3031 iText->DrawLayout(*gc, top_left, boundingRect, &aDrawTextLayoutContext->iBackgroundColor, TRUE, &selection, NULL); |
|
3032 if (isDrawingOnAWindowDC) |
|
3033 { |
|
3034 EndRedraw(); |
|
3035 } |
|
3036 } |
|
3037 } |
|
3038 |
|
3039 void CTextLayout::HighlightUsingExtensions(const CTextLayout::TRangeChange& aChangeHighlight,const TRangeChange& aFullHighlight, |
|
3040 const TRect& aDrawRect, const TDrawTextLayoutContext* aDrawTextLayoutContext) |
|
3041 { |
|
3042 if (!aChangeHighlight.NonNull()) |
|
3043 return; |
|
3044 |
|
3045 TRect clip_rect(aDrawRect); |
|
3046 clip_rect.Intersection(aDrawTextLayoutContext->TextArea()); |
|
3047 |
|
3048 CGraphicsContext* gc = aDrawTextLayoutContext->PrimaryGc(); |
|
3049 if (aDrawTextLayoutContext->UseClippingRect()) |
|
3050 { |
|
3051 gc->SetClippingRect(clip_rect); |
|
3052 } |
|
3053 |
|
3054 TInt visible_start; |
|
3055 TInt visible_length = PosRangeInBand(visible_start); |
|
3056 TInt start_pos; |
|
3057 TInt end_pos; |
|
3058 CTextLayout::TRangeChange::TChangeType type = aChangeHighlight.Get(start_pos, end_pos); |
|
3059 start_pos = start_pos < visible_start? visible_start : start_pos; |
|
3060 end_pos = end_pos < visible_start + visible_length? end_pos : start_pos + visible_length; |
|
3061 |
|
3062 TInt full_start_pos; |
|
3063 TInt full_end_pos; |
|
3064 (void)aFullHighlight.Get(full_start_pos, full_end_pos); |
|
3065 full_start_pos = full_start_pos < visible_start? visible_start : full_start_pos; |
|
3066 full_end_pos = full_end_pos < visible_start + visible_length? full_end_pos : full_start_pos + visible_length; |
|
3067 TCursorSelection selection(full_start_pos, full_end_pos); |
|
3068 |
|
3069 TPoint top_left = aDrawTextLayoutContext->TopLeftText(); |
|
3070 top_left.iY -= iBandTop; |
|
3071 |
|
3072 TBool isDrawingOnAWindowDC = aDrawTextLayoutContext->UseWindowGc(); |
|
3073 |
|
3074 TRect boundingRect; |
|
3075 iText->GetUpdateBoundingRect(start_pos, end_pos, top_left, boundingRect); |
|
3076 iHighlightExtensions->AbsExtendRect(boundingRect); |
|
3077 boundingRect.Intersection(clip_rect); |
|
3078 if (! boundingRect.IsEmpty()) |
|
3079 { |
|
3080 if (isDrawingOnAWindowDC) |
|
3081 { |
|
3082 BeginRedraw(boundingRect); |
|
3083 } |
|
3084 iText->DrawLayout(*gc, top_left, boundingRect, &aDrawTextLayoutContext->iBackgroundColor, TRUE, &selection, iHighlightExtensions); |
|
3085 if (isDrawingOnAWindowDC) |
|
3086 { |
|
3087 EndRedraw(); |
|
3088 } |
|
3089 } |
|
3090 |
|
3091 if (aDrawTextLayoutContext->UseClippingRect()) |
|
3092 { |
|
3093 gc->CancelClippingRect(); |
|
3094 } |
|
3095 } |
|
3096 |
|
3097 /** Toggles the selection highlight for the range of text in aHighlight. |
|
3098 |
|
3099 Highlights only those lines that intersect aDrawRect, which is specified in |
|
3100 window coordinates. The drawing parameters, including the graphics context, are |
|
3101 given in aDrawTextLayoutContext. |
|
3102 |
|
3103 In v7.0 and onwards, this function is deprecated -Highlight() should be used |
|
3104 instead. |
|
3105 @deprecated |
|
3106 @param aHighlight The range of characters for which to invert the highlighting. |
|
3107 @param aDrawRect Only lines which intersect this rectangle are affected; |
|
3108 specified in window coordinates. |
|
3109 @param aDrawTextLayoutContext Provides a graphics context and other drawing |
|
3110 parameters. */ |
|
3111 EXPORT_C void CTextLayout::InvertRangeL(const TCursorSelection& aHighlight,const TRect& aDrawRect, |
|
3112 const TDrawTextLayoutContext* aDrawTextLayoutContext) |
|
3113 { |
|
3114 TRangeChange range(aHighlight.iAnchorPos, aHighlight.iCursorPos, TRangeChange::ESet); |
|
3115 HighlightUsingExtensions(range,range,aDrawRect,aDrawTextLayoutContext); |
|
3116 } |
|
3117 |
|
3118 /** |
|
3119 Return the FORM major version number. This function is not generally useful. It |
|
3120 is used in test code and was used while making a transition between this and |
|
3121 the former version of FORM. The return value is always 2. |
|
3122 */ |
|
3123 EXPORT_C TInt CTextLayout::MajorVersion() const |
|
3124 { |
|
3125 return 2; |
|
3126 } |
|
3127 |
|
3128 /** |
|
3129 This method allows Form clients to register an object able to |
|
3130 create or return references to customisation objects used within Form for |
|
3131 various tasks e.g. inline text. |
|
3132 @param aProvider |
|
3133 Reference to interface provider object to register with Formm. |
|
3134 */ |
|
3135 EXPORT_C void CTextLayout::SetInterfaceProvider( MFormCustomInterfaceProvider* aProvider ) |
|
3136 { |
|
3137 iSource->iInterfaceProvider = aProvider; |
|
3138 } |
|
3139 |
|
3140 /** Gets the width and height of the bounding box of the text, including |
|
3141 indents and margins, when formatted to the specified wrap width. |
|
3142 |
|
3143 This is useful for applications like a web browser that need to determine the |
|
3144 minimum width for a piece of text: if you specify zero as the wrap width, the |
|
3145 returned aSize.iWidth contains the minimum width that could be used for the |
|
3146 text without illegal line breaks, and if you specify KMaxTInt for aWrapWidth, |
|
3147 the returned aSize.iHeight contains the minimum height: the height when each |
|
3148 paragraph is a single line of unlimited length. |
|
3149 @since 6.0 |
|
3150 @param aWrapWidth The wrap width for the bounding box. |
|
3151 @param aSize On return, contains the width and height of the bounding box. */ |
|
3152 EXPORT_C void CTextLayout::GetMinimumSizeL(TInt aWrapWidth,TSize& aSize) |
|
3153 { |
|
3154 // |
|
3155 //Get the size of the minimal bounding box of the text when formatted to the specified wrap width. |
|
3156 //The width may be greater than aWrapWidth. To find the minimum width for the text, |
|
3157 //pass 0 for aWrapWidth. To find the minimum height, pass KMaxTInt for aWrapWidth. |
|
3158 // |
|
3159 iText->GetMinimumLayoutSizeL(aWrapWidth,aSize); |
|
3160 } |
|
3161 |
|
3162 /** Gets the width and height of the bounding box of the text, including |
|
3163 indents and margins, when formatted to the specified wrap width. |
|
3164 |
|
3165 This is useful for applications like a web browser that need to determine the |
|
3166 minimum width for a piece of text: if you specify zero as the wrap width, the |
|
3167 returned aSize.iWidth contains the minimum width that could be used for the |
|
3168 text, and if you specify KMaxTInt for aWrapWidth, the returned aSize.iHeight |
|
3169 contains the minimum height: the height when each paragraph is a single |
|
3170 line of unlimited length. Use aAllowLegalLineBreaksOnly to set whether or |
|
3171 not illegal line breaks should be considered when determining aSize. |
|
3172 @since 6.0 |
|
3173 @param aWrapWidth The wrap width for the bounding box. |
|
3174 @param aAllowLegalLineBreaksOnly ETrue to only allow legal line breaks, or EFalse to also allow illegal line breaks. |
|
3175 @param aSize On return, contains the width and height of the bounding box. */ |
|
3176 EXPORT_C void CTextLayout::GetMinimumSizeL(TInt aWrapWidth,TBool aAllowLegalLineBreaksOnly,TSize& aSize) |
|
3177 { |
|
3178 // |
|
3179 //Get the size of the minimal bounding box of the text when formatted to the specified wrap width. |
|
3180 //The width may be greater than aWrapWidth. To find the minimum width for the text, |
|
3181 //pass 0 for aWrapWidth. To find the minimum height, pass KMaxTInt for aWrapWidth. |
|
3182 // |
|
3183 iText->GetMinimumLayoutSizeL(aWrapWidth,aAllowLegalLineBreaksOnly,aSize); |
|
3184 } |
|
3185 |
|
3186 /** Sets the custom drawing object, for customising the way text and its |
|
3187 background are drawn. |
|
3188 @since 6.0 |
|
3189 @param aCustomDraw Pointer to a custom drawing object. */ |
|
3190 EXPORT_C void CTextLayout::SetCustomDraw(const MFormCustomDraw* aCustomDraw) |
|
3191 { |
|
3192 iSource->iCustomDraw = aCustomDraw; |
|
3193 } |
|
3194 |
|
3195 /** Returns a pointer to the current custom drawing implementation. Returns |
|
3196 NULL if custom drawing is not in force. |
|
3197 @since 6.0 |
|
3198 @return Pointer to the custom drawing object. */ |
|
3199 EXPORT_C const MFormCustomDraw* CTextLayout::CustomDraw() const |
|
3200 { |
|
3201 return iSource->iCustomDraw; |
|
3202 } |
|
3203 |
|
3204 /** Sets custom line breaking. |
|
3205 |
|
3206 If this function is not called, default line breaking behaviour is used. |
|
3207 |
|
3208 Ownership of the custom line breaking object is not transferred to this object. |
|
3209 |
|
3210 @param aCustomWrap A pointer to an object that implements the custom line |
|
3211 breaking interface. Specify NULL to disable custom line breaking. */ |
|
3212 EXPORT_C void CTextLayout::SetCustomWrap(const MFormCustomWrap* aCustomWrap) |
|
3213 { |
|
3214 iSource->iCustomWrap = aCustomWrap; |
|
3215 } |
|
3216 |
|
3217 /** Gets the custom line breaking object, as set using SetCustomWrap(). |
|
3218 |
|
3219 @return A pointer to the custom line breaking object, or NULL if custom line |
|
3220 breaking is not in effect. */ |
|
3221 EXPORT_C const MFormCustomWrap* CTextLayout::CustomWrap() const |
|
3222 { |
|
3223 return iSource->iCustomWrap; |
|
3224 } |
|
3225 |
|
3226 /** |
|
3227 @internalAll |
|
3228 @released |
|
3229 */ |
|
3230 EXPORT_C void MFormCustomDraw::MFormCustomDraw_Reserved_2() |
|
3231 { |
|
3232 } |
|
3233 |
|
3234 /** This function is called whenever part of the background of a CTextLayout or |
|
3235 CTextView object needs to be drawn. The default implementation fills |
|
3236 aParam.iDrawRect with the colour specified in aBackground. |
|
3237 |
|
3238 The default background colour is contained in aBackground. This is the |
|
3239 background colour of the paragraph if drawing text, or the background colour |
|
3240 specified in the TDrawTextLayoutContext object passed to CTextLayout::DrawL() |
|
3241 if drawing outside the text area. |
|
3242 |
|
3243 The rectangle which is drawn by this function, (this may not be the whole of |
|
3244 aParam.iDrawRect) must be returned in aDrawn; areas not drawn by you are |
|
3245 automatically filled using the colour aBackground. |
|
3246 |
|
3247 @param aParam Contains the drawing parameters: aParam.iGc is the graphics |
|
3248 context to use. aParam.iMap is the graphics device map, which allows you to |
|
3249 convert between pixels and twips and create fonts. aParam.iTextLayoutTopLeft is |
|
3250 the origin of the text; bitmaps and other graphics must be drawn relative to |
|
3251 this position. aParam.iDrawRect is the area to be drawn; do not draw outside |
|
3252 this rectangle. |
|
3253 @param aBackground The default background colour. This is the background colour |
|
3254 of the paragraph if drawing text, or the background colour specified in the |
|
3255 TDrawTextLayoutContext object passed to CTextLayout::DrawL() if drawing outside |
|
3256 the text area. |
|
3257 @param aDrawn Must return the rectangle you actually draw. This may not be the |
|
3258 whole of aParam.iDrawRect (for instance, if you are drawing a non-tiled bitmap |
|
3259 that occupies only part of aRect). */ |
|
3260 EXPORT_C void MFormCustomDraw::DrawBackground(const TParam& aParam,const TRgb& aBackground,TRect& aDrawn) const |
|
3261 { |
|
3262 MTmCustom c; |
|
3263 c.DrawBackground(aParam.iGc,aParam.iTextLayoutTopLeft,aParam.iDrawRect,aBackground,aDrawn); |
|
3264 } |
|
3265 |
|
3266 /** This function is called after the background has been drawn by |
|
3267 DrawBackground(), and before drawing the text. This function might be used to |
|
3268 draw a ruled line under each line of text. |
|
3269 |
|
3270 The default implementation of this function does nothing. |
|
3271 |
|
3272 @param aParam Contains the drawing parameters. You should only draw to |
|
3273 aParam.iDrawRect. There is no need to fill aParam.iDrawRect or to indicate the |
|
3274 rectangle drawn. |
|
3275 @param aLineInfo Contains the line metrics: aLineInfo.iOuterLineRect specifies |
|
3276 the bounding rectangle of the line, including margins, indents and automatic |
|
3277 space above and below paragraphs, aLineInfo.iInnerLineRect specifies the bounds |
|
3278 of the text only, aLineInfo.iBaseline specifies the baseline of the text. */ |
|
3279 EXPORT_C void MFormCustomDraw::DrawLineGraphics(const TParam& /*aParam*/,const TLineInfo& /*aLineInfo*/) const |
|
3280 { |
|
3281 // do nothing |
|
3282 } |
|
3283 |
|
3284 /** This function is called to draw the text and its highlighted background, if |
|
3285 any, after bidirectional reordering and other character mappings have taken |
|
3286 place. |
|
3287 |
|
3288 The default implementation of this function draws the text with no special |
|
3289 effects and supports standard, round-cornered and shadowed highlighting only. |
|
3290 The text is drawn with the left end of its baseline located at aTextOrigin |
|
3291 after drawing the background, if any, in aParam.iDrawRect. |
|
3292 |
|
3293 The main reason to override this function is to apply custom text highlighting, |
|
3294 (for this, aFormat.iFontPresentation.iHighlightStyle should be in the range |
|
3295 EFontHighlightFirstCustomStyle to EFontHighlightLastCustomStyle). |
|
3296 |
|
3297 The horizontal spacing between the characters in the text string is increased |
|
3298 by the number of pixels specified in aExtraPixels. The standard way to do this |
|
3299 is by calling CGraphicsContext::SetCharJustification(). |
|
3300 |
|
3301 The font and other graphics parameters (e.g. pen colour, font style), are |
|
3302 specified in aParam.iGc but a character format container (aFormat) is supplied |
|
3303 so that a different font can be used. Note that any graphics drawn cannot |
|
3304 exceed the bounds of aParam.iDrawRect, so changes are usually restricted to |
|
3305 drawing shadows, outlines, etc. if custom highlighting is in use. |
|
3306 |
|
3307 @param aParam Contains the drawing parameters. Drawing can only occur within |
|
3308 aParam.iDrawRect. |
|
3309 @param aLineInfo Contains the line metrics. |
|
3310 @param aFormat Specifies the character formatting to apply to the text, |
|
3311 including the type of text highlighting. |
|
3312 @param aText The text string to be drawn. |
|
3313 @param aTextOrigin The point at which the left end of the baseline of the text |
|
3314 should be drawn. |
|
3315 @param aExtraPixels The number of additional pixels to insert between the |
|
3316 characters in the text string, in order to increase its length. */ |
|
3317 EXPORT_C void MFormCustomDraw::DrawText(const TParam& aParam,const TLineInfo& aLineInfo,const TCharFormat& aFormat, |
|
3318 const TDesC& aText,const TPoint& aTextOrigin,TInt aExtraPixels) const |
|
3319 { |
|
3320 TTmLineInfo info; |
|
3321 info.iOuterRect = aLineInfo.iOuterRect; |
|
3322 info.iInnerRect = aLineInfo.iInnerRect; |
|
3323 info.iBaseline = aLineInfo.iBaseline; |
|
3324 |
|
3325 MTmCustom c; |
|
3326 c.DrawText(aParam.iGc,aParam.iTextLayoutTopLeft,aParam.iDrawRect,info,aFormat, |
|
3327 aText,aTextOrigin,aExtraPixels); |
|
3328 } |
|
3329 |
|
3330 EXPORT_C void MFormCustomDraw::DrawText(const TParam& aParam,const TLineInfo& aLineInfo,const TCharFormat& aFormat, |
|
3331 const TDesC& aText,const TInt aStart, const TInt aEnd, const TPoint& aTextOrigin,TInt aExtraPixels) const |
|
3332 { |
|
3333 TTmLineInfo info; |
|
3334 info.iOuterRect = aLineInfo.iOuterRect; |
|
3335 info.iInnerRect = aLineInfo.iInnerRect; |
|
3336 info.iBaseline = aLineInfo.iBaseline; |
|
3337 |
|
3338 MTmCustomExtension c; |
|
3339 c.DrawText(aParam.iGc,aParam.iTextLayoutTopLeft,aParam.iDrawRect,info,aFormat, |
|
3340 aText,aStart,aEnd,aTextOrigin,aExtraPixels); |
|
3341 } |
|
3342 |
|
3343 /** This function translates logical colours specified in FORM objects into |
|
3344 real colours. The default implementation just returns the default colour that |
|
3345 is passed in and ignores aColorIndex. |
|
3346 |
|
3347 Overriding implementations may use aColorIndex in any desired way, either to |
|
3348 replace or modify aDefaultColor. The values used in aColorIndex are taken from |
|
3349 the top byte of a TLogicalRgb object and are thus in the range 0...255. The |
|
3350 TLogicalRgb class defines two reserved values: |
|
3351 TLogicalRgb::ESystemForegroundIndex = 254 and |
|
3352 TLogicalRgb::ESystemBackgroundIndex = 255. |
|
3353 */ |
|
3354 EXPORT_C TRgb MFormCustomDraw::SystemColor(TUint /*aColorIndex*/,TRgb aDefaultColor) const |
|
3355 { |
|
3356 return aDefaultColor; |
|
3357 } |
|
3358 |
|
3359 void CTextLayout::DrawBackground(CGraphicsContext& aGc,const TPoint& aTopLeft,const TRect& aClipRect, |
|
3360 const TLogicalRgb& aBackground) const |
|
3361 { |
|
3362 TPoint top_left(aTopLeft); |
|
3363 top_left.iY -= iBandTop; |
|
3364 iText->DrawBackground(aGc,top_left,aClipRect,aBackground); |
|
3365 } |
|
3366 |
|
3367 /** Returns the line break class for a Unicode character. |
|
3368 |
|
3369 For convenience, it also gets the range of consecutive characters (if any) |
|
3370 according to the Unicode standard, including aCode, that share the same line |
|
3371 break class. |
|
3372 |
|
3373 The Unicode line break classes are enumerated in class MTmCustom. |
|
3374 |
|
3375 Each character's line break class is obtained using LineBreakClass(). To find |
|
3376 out whether a line break is allowed between two adjacent characters, call |
|
3377 LineBreakPossible() with the line break classes of the two characters as |
|
3378 arguments. For example, the line break class EClLineBreakClass (closing |
|
3379 punctuation) applies to characters such as ")", "]" and ";". Line breaks are |
|
3380 typically allowed after these characters, but not before, so a call to |
|
3381 LineBreakPossible() with the arguments (EAlLineBreakClass, EClLineBreakClass) |
|
3382 would return EFalse in the default implementation, but a call with |
|
3383 (EClLineBreakClass, EAlLineBreakClass) would return ETrue. |
|
3384 |
|
3385 @param aCode The Unicode character code of interest. |
|
3386 @param aRangeStart On return, contains the Unicode character code at the start |
|
3387 of the range including aCode that shares the same line break class as aCode. |
|
3388 @param aRangeEnd On return, contains the Unicode character code at the end of |
|
3389 the range including aCode that shares the same line break class as aCode. |
|
3390 @return The line break class assigned to the character. Line break classes are |
|
3391 enumerated in class MTmCustom. */ |
|
3392 EXPORT_C TUint MFormCustomWrap::LineBreakClass(TUint aCode,TUint& aRangeStart,TUint& aRangeEnd) const |
|
3393 { |
|
3394 // Create an instance of MTmCustom and then call the MTmCustom's functions for getting a Line Break class |
|
3395 MTmCustom c; |
|
3396 TUint temp; |
|
3397 temp=c.LineBreakClass(aCode,aRangeStart,aRangeEnd); |
|
3398 return temp; |
|
3399 } |
|
3400 |
|
3401 /** Tests whether a line break is possible between two characters. |
|
3402 |
|
3403 If aHaveSpaces is true, the characters are not adjacent one or more space |
|
3404 characters (with a line break class of ESpLineBreakClass) occur between them. |
|
3405 |
|
3406 The aPrevClass and aNextClass arguments never have the value ESpLineBreakClass. |
|
3407 Instead, this function is called with the classes of the characters on either |
|
3408 side of the space or run of spaces, (and if so, aHaveSpaces is true). This is |
|
3409 so that line breaks can be prohibited between certain characters with |
|
3410 intervening spaces, for instance an alphabetic character (EAlLineBreakClass, |
|
3411 such as 'a') and a closing bracket, with a space inbetween. |
|
3412 |
|
3413 Additionally, the arguments to this function never have a value of |
|
3414 ESaLineBreakClass. For such characters, GetLineBreakInContext() is called |
|
3415 instead. |
|
3416 |
|
3417 @param aPrevClass The line break class of the previous non-space character. |
|
3418 @param aNextClass The line break class of the next non-space character. |
|
3419 @param aHaveSpaces ETrue if there are one or more space characters (with a line |
|
3420 break class of ESpLineBreakClass) between aPrevClass and aNextClass. EFalse if |
|
3421 not. |
|
3422 @return ETrue if a line break is possible between characters with the two line |
|
3423 break classes, EFalse if not. */ |
|
3424 EXPORT_C TBool MFormCustomWrap::LineBreakPossible(TUint aPrevClass,TUint aNextClass,TBool aHaveSpaces) const |
|
3425 { |
|
3426 MTmCustom c; |
|
3427 TBool temp; |
|
3428 temp=c.LineBreakPossible(aPrevClass,aNextClass,aHaveSpaces); |
|
3429 return temp; |
|
3430 } |
|
3431 |
|
3432 /** Gets the position of the first or last possible line break position in a |
|
3433 text string. |
|
3434 |
|
3435 This function is called instead of LineBreakPossible() for runs of characters |
|
3436 of class ESaLineBreakClass. It is used for South Asian languages like Thai, Lao |
|
3437 and Khmer that have no spaces between words, so that line breaks must be |
|
3438 calculated using dictionary lookup or a linguistic algorithm. |
|
3439 |
|
3440 The default implementation of this function just returns false. |
|
3441 |
|
3442 @param aText A string containing characters of class ESaLineBreakClass. |
|
3443 @param aMinBreakPos A position within aText at which to begin searching for a |
|
3444 possible line break position. |
|
3445 @param aMaxBreakPos A position within aText at which to stop searching for a |
|
3446 possible line break position. |
|
3447 @param aForwards If ETrue, the function gets the first possible line break |
|
3448 position (searches forwards from aMinBreakPos); if EFalse, gets the last one |
|
3449 (searches backwards from aMaxBreakPos). |
|
3450 @param aBreakPos On return, the position of the first or last possible line |
|
3451 break within aText. This must be greater than zero and less than aText.Length() |
|
3452 - 1, and must also be in the range aMinBreakPos to aMaxBreakPos. |
|
3453 @return ETrue if a possible line break position is found, EFalse if not. */ |
|
3454 EXPORT_C TBool MFormCustomWrap::GetLineBreakInContext(const TDesC& aText,TInt aMinBreakPos,TInt aMaxBreakPos, |
|
3455 TBool aForwards,TInt& aBreakPos) const |
|
3456 { |
|
3457 MTmCustom c; |
|
3458 TBool temp; |
|
3459 temp=c.GetLineBreakInContext(aText,aMinBreakPos,aMaxBreakPos,aForwards,aBreakPos); |
|
3460 return temp; |
|
3461 } |
|
3462 |
|
3463 /** Tests whether a character can overhang the right margin. |
|
3464 |
|
3465 This function can be overridden to customise the line breaking behaviour for |
|
3466 closing punctuation in Japanese. Any characters for which this function returns |
|
3467 ETrue are allowed to overhang the right margin. The rest will be moved to the |
|
3468 next line. |
|
3469 |
|
3470 The default implementation of this function just returns false. |
|
3471 |
|
3472 @param aChar The Unicode character code of interest. |
|
3473 @return ETrue if the character specified can overhang the right margin, EFalse if |
|
3474 not. */ |
|
3475 EXPORT_C TBool MFormCustomWrap::IsHangingCharacter(TUint aChar) const |
|
3476 { |
|
3477 MTmCustom c; |
|
3478 TBool temp; |
|
3479 temp=c.IsHangingCharacter(aChar); |
|
3480 return temp; |
|
3481 } |
|
3482 |
|
3483 // Reserved functions are private until they are used |
|
3484 /** |
|
3485 @internalAll |
|
3486 @released |
|
3487 */ |
|
3488 EXPORT_C void MFormCustomWrap::MFormCustomWrap_Reserved_1() |
|
3489 { |
|
3490 // reserved functions |
|
3491 } |
|
3492 // Reserved functions are private until they are used. |
|
3493 /** |
|
3494 @internalAll |
|
3495 @released |
|
3496 */ |
|
3497 |
|
3498 EXPORT_C void MFormCustomWrap::MFormCustomWrap_Reserved_2() |
|
3499 { |
|
3500 // reserved functions |
|
3501 } |
|
3502 |
|
3503 #ifdef _DEBUG |
|
3504 TBool CTextLayout::__DbgIsFormattingUpToDate() const |
|
3505 { |
|
3506 return iUnformattedStart == KMaxTInt; |
|
3507 } |
|
3508 #endif |
|
3509 |
|
3510 // TLayDocTextSource stuff begins here. |
|
3511 TLayDocTextSource::TLayDocTextSource(): |
|
3512 iLayDoc(NULL), |
|
3513 iFlags(EWrap), |
|
3514 iWidth(KMaxTInt), |
|
3515 iEllipsis(0x2026), |
|
3516 iLabelsWidth(0), |
|
3517 iLabelsGutter(0), |
|
3518 iFormatMode(CLayoutData::EFScreenMode), |
|
3519 iImageDevice(NULL), |
|
3520 iLabelsDevice(NULL), |
|
3521 iFormatDevice(NULL), |
|
3522 iFontHeightIncreaseFactor(EDefaultFontHeightIncreaseFactor), |
|
3523 iMinimumLineDescent(EDefaultMinimumLineDescent), |
|
3524 iNonPrintingCharVisibility(), |
|
3525 iFormParam(NULL), |
|
3526 iCustomDraw(NULL), |
|
3527 iCustomWrap(NULL), |
|
3528 iInterfaceProvider(NULL), |
|
3529 iDrawOpaque(EFalse), |
|
3530 iExcessHeightRequired(0), |
|
3531 iInvisibleCharacterRemapper(NULL) |
|
3532 { |
|
3533 } |
|
3534 |
|
3535 MGraphicsDeviceMap& TLayDocTextSource::FormatDevice() const |
|
3536 { |
|
3537 if (!iFormatDevice) |
|
3538 CTextLayout::Panic(CTextLayout::EFormatDeviceNotSet); |
|
3539 if (iLabelsDevice && (iFlags & EUseLabelsDevice)) |
|
3540 return *iLabelsDevice; |
|
3541 else |
|
3542 return *iFormatDevice; |
|
3543 } |
|
3544 |
|
3545 MGraphicsDeviceMap& TLayDocTextSource::InterpretDevice() const |
|
3546 { |
|
3547 if (!iImageDevice) |
|
3548 CTextLayout::Panic(CTextLayout::EImageDeviceNotSet); |
|
3549 if (iLabelsDevice && (iFlags & EUseLabelsDevice)) |
|
3550 return *iLabelsDevice; |
|
3551 else |
|
3552 return *iImageDevice; |
|
3553 } |
|
3554 |
|
3555 TInt TLayDocTextSource::DocumentLength() const |
|
3556 { |
|
3557 return iLayDoc->LdDocumentLength(); |
|
3558 } |
|
3559 |
|
3560 void TLayDocTextSource::GetText(TInt aPos,TPtrC& aText,TTmCharFormat& aFormat) const |
|
3561 { |
|
3562 TCharFormat f; |
|
3563 iLayDoc->GetChars(aText,f,aPos); |
|
3564 aFormat = f; |
|
3565 } |
|
3566 |
|
3567 void TLayDocTextSource::GetParagraphFormatL(TInt aPos,RTmParFormat& aFormat) const |
|
3568 { |
|
3569 CParaFormat f; |
|
3570 iLayDoc->GetParagraphFormatL(&f,aPos); |
|
3571 |
|
3572 // Labels should not have a forced line height or borders so remove these (this is necessary for Agenda). |
|
3573 if (iFlags & EUseLabelsDevice) |
|
3574 { |
|
3575 f.iLineSpacingInTwips = 0; |
|
3576 f.iLineSpacingControl = CParaFormat::ELineSpacingAtLeastInTwips; |
|
3577 f.RemoveAllBorders(); |
|
3578 } |
|
3579 |
|
3580 aFormat.CopyL(f); |
|
3581 f.Reset(); |
|
3582 } |
|
3583 |
|
3584 TRgb TLayDocTextSource::SystemColor(TUint aColorIndex,TRgb aDefaultColor) const |
|
3585 { |
|
3586 if (iCustomDraw) |
|
3587 return iCustomDraw->SystemColor(aColorIndex,aDefaultColor); |
|
3588 else if (iFormParam) |
|
3589 return iFormParam->SystemColor(aColorIndex,aDefaultColor); |
|
3590 else |
|
3591 return aDefaultColor; |
|
3592 } |
|
3593 |
|
3594 CPicture* TLayDocTextSource::PictureL(TInt aPos) const |
|
3595 { |
|
3596 return iLayDoc->PictureHandleL(aPos,MLayDoc::EForceLoadTrue); |
|
3597 } |
|
3598 |
|
3599 TInt TLayDocTextSource::GetPictureSizeInTwipsL(TInt aPos,TSize& aSize) const |
|
3600 { |
|
3601 return iLayDoc->GetPictureSizeInTwips(aSize,aPos); |
|
3602 } |
|
3603 |
|
3604 TInt TLayDocTextSource::ParagraphStart(TInt aPos) const |
|
3605 { |
|
3606 iLayDoc->LdToParagraphStart(aPos); |
|
3607 return aPos; |
|
3608 } |
|
3609 |
|
3610 TBool TLayDocTextSource::LabelModeSelect(TLabelType aType, TInt aPos) |
|
3611 { |
|
3612 if (!(iFlags & EUseLabelsDevice) && aType == EParLabel) |
|
3613 { |
|
3614 // Labels are not allowed on zero-length documents; |
|
3615 // this is required for Agenda (see ER5U defect EDNGASR-482LSF). |
|
3616 if (iLayDoc->LdDocumentLength() == 0) |
|
3617 return FALSE; |
|
3618 |
|
3619 if (iLayDoc->SelectParagraphLabel(aPos)) |
|
3620 { |
|
3621 iFlags |= EUseLabelsDevice; |
|
3622 return TRUE; |
|
3623 } |
|
3624 } |
|
3625 |
|
3626 return FALSE; |
|
3627 } |
|
3628 |
|
3629 void TLayDocTextSource::LabelMetrics(TLabelType aType, TSize& aLabelSize, TInt& aMarginSize) const |
|
3630 { |
|
3631 if (aType == EParLabel) |
|
3632 { |
|
3633 aLabelSize.iWidth = iLabelsWidth; |
|
3634 aLabelSize.iHeight = KMaxTInt; |
|
3635 aMarginSize = iLabelsWidth + iLabelsGutter; |
|
3636 } |
|
3637 else |
|
3638 { |
|
3639 aLabelSize.iWidth = 0; |
|
3640 aLabelSize.iHeight = 0; |
|
3641 aMarginSize = 0; |
|
3642 } |
|
3643 } |
|
3644 |
|
3645 void TLayDocTextSource::LabelModeCancel() |
|
3646 { |
|
3647 iLayDoc->CancelSelectLabel(); |
|
3648 iFlags &= ~EUseLabelsDevice; |
|
3649 } |
|
3650 |
|
3651 /** |
|
3652 This method is responsible for discovering interface extension objects |
|
3653 requried by Form for the specified interface Uid. |
|
3654 @param aInterfaceId |
|
3655 Identifier for the optional interface requried. |
|
3656 @return |
|
3657 Pointer to object supporting the requested interface, |
|
3658 or 0 if not supported. |
|
3659 */ |
|
3660 TAny* TLayDocTextSource::GetExtendedInterface(const TUid& aInterfaceId) |
|
3661 { |
|
3662 TAny* interfacePtr = 0; |
|
3663 |
|
3664 // First check to see if their is an external interface provider |
|
3665 // registered and ask it for the interface. |
|
3666 if (iInterfaceProvider) |
|
3667 { |
|
3668 interfacePtr = iInterfaceProvider->GetExtendedInterface( aInterfaceId ); |
|
3669 } |
|
3670 |
|
3671 // If interface still not supplied check self and parent to provide it |
|
3672 if (!interfacePtr) |
|
3673 { |
|
3674 if (aInterfaceId == KFormLabelApiExtensionUid) |
|
3675 { |
|
3676 return static_cast<MFormLabelApi*>(this); |
|
3677 } |
|
3678 else if(aInterfaceId == KTmTextDrawExtId) |
|
3679 { |
|
3680 return static_cast <MTmTextDrawExt*> (this); |
|
3681 } |
|
3682 else if(aInterfaceId == KTmCustomExtensionUid) |
|
3683 { |
|
3684 return static_cast <MTmCustomExtension*> (this); |
|
3685 } |
|
3686 else |
|
3687 { |
|
3688 // In this instance, calling the parent class will always return NULL |
|
3689 // but the pattern should be followed by all implementors for safety |
|
3690 return MTmSource::GetExtendedInterface(aInterfaceId); |
|
3691 } |
|
3692 } |
|
3693 |
|
3694 // Return the interface object or 0 if not supported. |
|
3695 return interfacePtr; |
|
3696 } |
|
3697 |
|
3698 void TLayDocTextSource::SetLineHeight(const TLineHeightParam& aParam,TInt& aAscent,TInt& aDescent) const |
|
3699 { |
|
3700 // Increase the ascent by the font height increase percentage. |
|
3701 TLineHeightParam p = aParam; |
|
3702 p.iFontMaxAscent += ((p.iFontMaxAscent + p.iFontMaxDescent) * iFontHeightIncreaseFactor) / 100; |
|
3703 |
|
3704 // Call the standard SetLineHeight. |
|
3705 MTmSource::SetLineHeight(p,aAscent,aDescent); |
|
3706 |
|
3707 // iExcessHeightRequired is used when height of the highest glyph can be |
|
3708 // greater than CFont::AscentInPixels() and in iExactLineSpacing mode |
|
3709 // This value is set via CTextView::SetExcessHeightRequired() |
|
3710 if ( aParam.iExactLineHeight ) |
|
3711 { |
|
3712 aAscent += iExcessHeightRequired; |
|
3713 aDescent -= iExcessHeightRequired; |
|
3714 } |
|
3715 |
|
3716 // Enforce the minimum descent; the following logic is borrowed from CLineLayout::WrapLineL in old FORM. |
|
3717 if (aAscent + aDescent <= iMinimumLineDescent && aDescent == 0) |
|
3718 { |
|
3719 aDescent = 1; |
|
3720 aAscent--; |
|
3721 } |
|
3722 else if (aDescent < iMinimumLineDescent) |
|
3723 aDescent = iMinimumLineDescent; |
|
3724 |
|
3725 /* |
|
3726 Ensure the line is at least 1 pixel high and ascent and descent are non-negative so that assertion |
|
3727 TCursorPosition::GetLineRectL that cursor pos is contained in line rect doesn't fire. |
|
3728 */ |
|
3729 if (aAscent < 0) |
|
3730 aAscent = 0; |
|
3731 if (aDescent < 0) |
|
3732 aDescent = 0; |
|
3733 if (aAscent + aDescent == 0) |
|
3734 aDescent = 1; |
|
3735 } |
|
3736 |
|
3737 TBool TLayDocTextSource::CanMap() const |
|
3738 { |
|
3739 return iFormatMode == CLayoutData::EFScreenMode || iFormatMode == CLayoutData::EFWysiwygMode; |
|
3740 } |
|
3741 |
|
3742 TBool TLayDocTextSource::PageBreakInRange(TInt aStartPos,TInt aEndPos) const |
|
3743 { |
|
3744 if (CanMap() && iNonPrintingCharVisibility.PageBreaksVisible()) |
|
3745 return iLayDoc->EnquirePageBreak(aStartPos,aEndPos - aStartPos); |
|
3746 else |
|
3747 return FALSE; |
|
3748 } |
|
3749 |
|
3750 void TLayDocTextSource::DrawBackground(CGraphicsContext& aGc,const TPoint& aTopLeft,const TRect& aRect, |
|
3751 const TLogicalRgb& aBackground,TRect& aDrawn) const |
|
3752 { |
|
3753 ResetOpaque(aGc); |
|
3754 if (iCustomDraw) |
|
3755 { |
|
3756 MFormCustomDraw::TParam param(aGc,InterpretDevice(),aTopLeft,aRect); |
|
3757 TLogicalRgb background = aBackground; |
|
3758 FormUtil::LogicalToActualColor(iFormParam,background); |
|
3759 iCustomDraw->DrawBackground(param,background,aDrawn); |
|
3760 } |
|
3761 else |
|
3762 MTmSource::DrawBackground(aGc,aTopLeft,aRect,aBackground,aDrawn); |
|
3763 } |
|
3764 |
|
3765 void TLayDocTextSource::DrawLineGraphics(CGraphicsContext& aGc,const TPoint& aTopLeft,const TRect& aRect, |
|
3766 const TTmLineInfo& aLineInfo) const |
|
3767 { |
|
3768 SetOpaque(aGc); |
|
3769 if (iCustomDraw) |
|
3770 { |
|
3771 MFormCustomDraw::TParam param(aGc,InterpretDevice(),aTopLeft,aRect); |
|
3772 MFormCustomDraw::TLineInfo lineinfo(aLineInfo.iOuterRect,aLineInfo.iInnerRect,aLineInfo.iBaseline); |
|
3773 iCustomDraw->DrawLineGraphics(param,lineinfo); |
|
3774 } |
|
3775 else |
|
3776 MTmSource::DrawLineGraphics(aGc,aTopLeft,aRect,aLineInfo); |
|
3777 ResetOpaque(aGc); |
|
3778 } |
|
3779 |
|
3780 void TLayDocTextSource::DrawText(CGraphicsContext& aGc,const TPoint& aTopLeft,const TRect& aRect, |
|
3781 const TTmLineInfo& aLineInfo,const TTmCharFormat& aFormat, |
|
3782 const TDesC& aText,const TPoint& aTextOrigin,TInt aExtraPixels) const |
|
3783 { |
|
3784 SetOpaque(aGc); |
|
3785 if (iCustomDraw) |
|
3786 { |
|
3787 MFormCustomDraw::TParam param(aGc,InterpretDevice(),aTopLeft,aRect); |
|
3788 MFormCustomDraw::TLineInfo lineinfo(aLineInfo.iOuterRect,aLineInfo.iInnerRect,aLineInfo.iBaseline); |
|
3789 TCharFormat f; |
|
3790 aFormat.GetTCharFormat(f); |
|
3791 iCustomDraw->DrawText(param,lineinfo,f,aText,aTextOrigin,aExtraPixels); |
|
3792 } |
|
3793 else |
|
3794 MTmSource::DrawText(aGc,aTopLeft,aRect,aLineInfo,aFormat,aText,aTextOrigin,aExtraPixels); |
|
3795 ResetOpaque(aGc); |
|
3796 } |
|
3797 |
|
3798 void TLayDocTextSource::DrawText(CGraphicsContext& aGc,const TPoint& aTopLeft,const TRect& aRect, |
|
3799 const TTmLineInfo& aLineInfo,const TTmCharFormat& aFormat, |
|
3800 const TDesC& aText,const TInt aStart, const TInt aEnd, const TPoint& aTextOrigin,TInt aExtraPixels) const |
|
3801 { |
|
3802 SetOpaque(aGc); |
|
3803 if (iCustomDraw) |
|
3804 { |
|
3805 MFormCustomDraw::TParam param(aGc,InterpretDevice(),aTopLeft,aRect); |
|
3806 MFormCustomDraw::TLineInfo lineinfo(aLineInfo.iOuterRect,aLineInfo.iInnerRect,aLineInfo.iBaseline); |
|
3807 TCharFormat f; |
|
3808 aFormat.GetTCharFormat(f); |
|
3809 iCustomDraw->DrawText(param,lineinfo,f,aText,aStart,aEnd,aTextOrigin,aExtraPixels); |
|
3810 } |
|
3811 else |
|
3812 MTmCustomExtension::DrawText(aGc,aTopLeft,aRect,aLineInfo,aFormat,aText,aStart,aEnd,aTextOrigin,aExtraPixels); |
|
3813 ResetOpaque(aGc); |
|
3814 } |
|
3815 |
|
3816 TBool TLayDocTextSource::LineBreakPossible(TUint aPrevClass,TUint aNextClass,TBool aHaveSpaces) const |
|
3817 |
|
3818 { |
|
3819 TBool temp; |
|
3820 if (iCustomWrap) |
|
3821 temp=iCustomWrap->LineBreakPossible(aPrevClass,aNextClass,aHaveSpaces); |
|
3822 else |
|
3823 temp=MTmSource::LineBreakPossible(aPrevClass,aNextClass,aHaveSpaces); |
|
3824 return temp; |
|
3825 } |
|
3826 |
|
3827 TUint TLayDocTextSource::LineBreakClass(TUint aCode,TUint& aRangeStart,TUint& aRangeEnd) const |
|
3828 { |
|
3829 TUint temp; |
|
3830 if (iCustomWrap) |
|
3831 temp=iCustomWrap->LineBreakClass(aCode,aRangeStart,aRangeEnd); |
|
3832 else |
|
3833 temp=MTmSource::LineBreakClass(aCode,aRangeStart,aRangeEnd); |
|
3834 return temp; |
|
3835 } |
|
3836 |
|
3837 |
|
3838 TBool TLayDocTextSource::GetLineBreakInContext(const TDesC& aText,TInt aMinBreakPos,TInt aMaxBreakPos, |
|
3839 TBool aForwards,TInt& aBreakPos) const |
|
3840 { |
|
3841 TBool temp; |
|
3842 if (iCustomWrap) |
|
3843 temp=iCustomWrap->GetLineBreakInContext(aText,aMinBreakPos,aMaxBreakPos,aForwards,aBreakPos); |
|
3844 else |
|
3845 temp=MTmSource::GetLineBreakInContext(aText,aMinBreakPos,aMaxBreakPos,aForwards,aBreakPos); |
|
3846 return temp; |
|
3847 } |
|
3848 |
|
3849 TBool TLayDocTextSource::IsHangingCharacter(TUint aChar) const |
|
3850 { |
|
3851 TBool temp; |
|
3852 if (iCustomWrap) |
|
3853 temp=iCustomWrap->IsHangingCharacter(aChar); |
|
3854 else |
|
3855 temp=MTmSource::IsHangingCharacter(aChar); |
|
3856 return temp; |
|
3857 } |
|
3858 |
|
3859 |
|
3860 TUint TLayDocTextSource::Map(TUint aChar) const |
|
3861 { |
|
3862 // Check if custom formatting has been installed |
|
3863 if (iInvisibleCharacterRemapper) |
|
3864 { // Then use the supplied custom invisible character remapping |
|
3865 return iInvisibleCharacterRemapper->Remap(aChar, iNonPrintingCharVisibility, *this); |
|
3866 } |
|
3867 else // Use the default |
|
3868 return MFormCustomInvisibleCharacterRemapper::DefaultMapping(aChar, iNonPrintingCharVisibility, *this); |
|
3869 } |
|
3870 |
|
3871 void TLayDocTextSource::DrawPicture(CGraphicsContext& aGc, |
|
3872 const TPoint& aTextLayoutTopLeft, const TRect& aRect, |
|
3873 MGraphicsDeviceMap& aDevice, const CPicture& aPicture) const |
|
3874 { |
|
3875 SetOpaque(aGc); |
|
3876 MTmSource::DrawPicture(aGc, aTextLayoutTopLeft, aRect, aDevice, aPicture); |
|
3877 ResetOpaque(aGc); |
|
3878 } |
|
3879 |
|
3880 //MTmTextDrawExt implementations |
|
3881 |
|
3882 /** |
|
3883 Draws a line. Implements MTmTextDrawExt::DrawLine(). |
|
3884 If the opaque drawing mode is active, then the line color will stay unchanged (it will not be |
|
3885 alpha-blended in a case of a transparent window). |
|
3886 @param aGc A reference to a graphics context. If the drawing mode is opaque, then this is a |
|
3887 CWindowGc reference. |
|
3888 @param aPt1 Line start point |
|
3889 @param aPt2 Line end point |
|
3890 */ |
|
3891 void TLayDocTextSource::DrawLine(CGraphicsContext& aGc, const TPoint& aPt1, const TPoint& aPt2) const |
|
3892 { |
|
3893 SetOpaque(aGc); |
|
3894 aGc.DrawLine(aPt1, aPt2); |
|
3895 ResetOpaque(aGc); |
|
3896 } |
|
3897 |
|
3898 /** |
|
3899 Draws a text. Implements MTmTextDrawExt::DrawText(). |
|
3900 If the opaque drawing mode is active, then the text color will stay unchanged (it will not be |
|
3901 alpha-blended in a case of a transparent window). |
|
3902 @param aGc A reference to a graphics context. If the drawing mode is opaqe, then this is a |
|
3903 CWindowGc reference. |
|
3904 @param aPt1 Text start point |
|
3905 */ |
|
3906 void TLayDocTextSource::DrawText(CGraphicsContext& aGc, const TDesC& aText, const TPoint& aPt) const |
|
3907 { |
|
3908 SetOpaque(aGc); |
|
3909 aGc.DrawText(aText, aPt); |
|
3910 ResetOpaque(aGc); |
|
3911 } |
|
3912 |
|
3913 /** |
|
3914 Draws a rectangle. Implements MTmTextDrawExt::DrawRect(). |
|
3915 If the opaque drawing mode is active, then the rectabgle color will stay unchanged (it will not be |
|
3916 alpha-blended in a case of a transparent window). |
|
3917 @param aGc A reference to a graphics context. If the drawing mode is opaqe, then this is a |
|
3918 CWindowGc reference. |
|
3919 @param aRc Rectangle coordinates |
|
3920 */ |
|
3921 void TLayDocTextSource::DrawRect(CGraphicsContext& aGc, const TRect& aRc) const |
|
3922 { |
|
3923 SetOpaque(aGc); |
|
3924 aGc.DrawRect(aRc); |
|
3925 ResetOpaque(aGc); |
|
3926 } |
|
3927 |
|
3928 /** |
|
3929 Sets opaque drawing mode. |
|
3930 @param aGc A reference to a graphics context. If the drawing mode is opaqe, then this is a |
|
3931 CWindowGc reference. |
|
3932 */ |
|
3933 void TLayDocTextSource::SetOpaque(CGraphicsContext& aGc) const |
|
3934 { |
|
3935 if(iDrawOpaque) |
|
3936 { |
|
3937 static_cast <CWindowGc&> (aGc).SetOpaque(ETrue); |
|
3938 } |
|
3939 } |
|
3940 |
|
3941 /** |
|
3942 Resets opaque drawing mode. |
|
3943 @param aGc A reference to a graphics context. If the drawing mode is opaqe, then this is a |
|
3944 CWindowGc reference. |
|
3945 */ |
|
3946 void TLayDocTextSource::ResetOpaque(CGraphicsContext& aGc) const |
|
3947 { |
|
3948 if(iDrawOpaque) |
|
3949 { |
|
3950 static_cast <CWindowGc&> (aGc).SetOpaque(EFalse); |
|
3951 } |
|
3952 } |
|
3953 |
|
3954 // Private CTextLayout functions start here. |
|
3955 |
|
3956 void CTextLayout::Panic(TPanicNumber aNumber) |
|
3957 { |
|
3958 _LIT(KPanicNumber,"CTextLayout using TAGMA"); |
|
3959 User::Panic(KPanicNumber,aNumber); |
|
3960 } |
|
3961 |
|
3962 void CTextLayout::GetParagraphRect(const TTmDocPos& aDocPos,TRect& aRect) const |
|
3963 { |
|
3964 aRect.SetRect(0,0,0,0); |
|
3965 TTmLineInfo info, info2; |
|
3966 if (!iText->DocPosToLine(aDocPos,info)) |
|
3967 return; |
|
3968 aRect = info.iOuterRect; |
|
3969 if (!(info.iFlags & TTmLineInfo::EParStart)) |
|
3970 { |
|
3971 iText->ParNumberToLine(info.iParNumber,0,info2); |
|
3972 aRect.iTl = info2.iOuterRect.iTl; |
|
3973 } |
|
3974 if (!(info.iFlags & TTmLineInfo::EParEnd)) |
|
3975 { |
|
3976 iText->ParNumberToLine(info.iParNumber,KMaxTInt,info2); |
|
3977 aRect.iBr = info2.iOuterRect.iBr; |
|
3978 } |
|
3979 aRect.Move(0,-iBandTop); |
|
3980 } |
|
3981 |
|
3982 /** |
|
3983 Scroll aDy pixels (positive = text moves down); return number of pixels |
|
3984 actually scrolled. Create a new formatted band if necessary. |
|
3985 */ |
|
3986 TInt CTextLayout::ScrollL(TInt aDy,TAllowDisallow aScrollBlankSpace, |
|
3987 TBool aTopNoLimitBorder/*=EFalse*/, |
|
3988 TBool aBottomNoLimitBorder/*=EFalse*/) |
|
3989 { |
|
3990 if ( EFDisallowScrollingBlankSpace == aScrollBlankSpace ) |
|
3991 { |
|
3992 aTopNoLimitBorder = EFalse; |
|
3993 aBottomNoLimitBorder = EFalse; |
|
3994 } |
|
3995 int old_bandtop = iBandTop; |
|
3996 int desired_bandtop = iBandTop - aDy; |
|
3997 int pixels_scrolled = 0; |
|
3998 int height_increase = 0; |
|
3999 int paragraphs_increase = 0; |
|
4000 TTmFormatParamBase param; |
|
4001 InitFormatParam(param); |
|
4002 // Refuse to scroll if the width is illegal. This prevents |
|
4003 // time being taken in certain situations where it does |
|
4004 // not matter. Once the formatting is capable of |
|
4005 // adding smaller chunks of text at a time, this early-out |
|
4006 // should become unnecessary. |
|
4007 if ((param.iWrapWidth < 1 || param.iMaxHeight < 1) |
|
4008 && param.iFlags & TTmFormatParamBase::EWrap) |
|
4009 return 0; |
|
4010 param.iMaxHeight = KMaxTInt; |
|
4011 int visible_height = VisibleHeightInPixels(); |
|
4012 if (aDy > 0) // text moves down; iBandTop decreases |
|
4013 { |
|
4014 if (aTopNoLimitBorder) |
|
4015 iBandTop = desired_bandtop; |
|
4016 else |
|
4017 iBandTop = Max(0,desired_bandtop);//Disallow text scrolled beyond top border |
|
4018 |
|
4019 pixels_scrolled = old_bandtop - iBandTop; |
|
4020 while (pixels_scrolled < aDy) |
|
4021 { |
|
4022 if (!iText->AddParL(param,TRUE,height_increase,paragraphs_increase)) |
|
4023 break; |
|
4024 pixels_scrolled += height_increase; |
|
4025 } |
|
4026 if (pixels_scrolled > aDy) |
|
4027 { |
|
4028 iBandTop = pixels_scrolled - aDy; |
|
4029 pixels_scrolled = aDy; |
|
4030 } |
|
4031 } |
|
4032 else if (aDy < 0) // text moves up; iBandTop increases |
|
4033 { |
|
4034 if (aBottomNoLimitBorder) |
|
4035 iBandTop = desired_bandtop; |
|
4036 else |
|
4037 iBandTop = Min(iText->LayoutHeight(),desired_bandtop);//Disallow text scrolled beyond bottom border |
|
4038 |
|
4039 pixels_scrolled = old_bandtop - iBandTop; |
|
4040 while (pixels_scrolled > aDy) |
|
4041 { |
|
4042 if (!AddFormattingAtEndL(param, height_increase,paragraphs_increase)) |
|
4043 break; |
|
4044 pixels_scrolled -= height_increase; |
|
4045 if (pixels_scrolled < aDy) |
|
4046 { |
|
4047 height_increase -= aDy - pixels_scrolled; |
|
4048 pixels_scrolled = aDy; |
|
4049 } |
|
4050 iBandTop += height_increase; |
|
4051 } |
|
4052 |
|
4053 // Fill in missing part of visible height. |
|
4054 while (iText->LayoutHeight() - iBandTop < visible_height) |
|
4055 { |
|
4056 if (!AddFormattingAtEndL(param, height_increase,paragraphs_increase)) |
|
4057 break; |
|
4058 } |
|
4059 } |
|
4060 |
|
4061 // Scroll blank space off the display if desired. |
|
4062 if (aScrollBlankSpace == EFDisallowScrollingBlankSpace && iText->LayoutHeight() - iBandTop < visible_height) |
|
4063 { |
|
4064 int new_bandtop = iText->LayoutHeight() - visible_height; |
|
4065 if (new_bandtop < 0) |
|
4066 new_bandtop = 0; |
|
4067 pixels_scrolled += iBandTop - new_bandtop; |
|
4068 iBandTop = new_bandtop; |
|
4069 } |
|
4070 |
|
4071 PruneFormatL(aDy < 0); |
|
4072 return pixels_scrolled + SetBandTop(); |
|
4073 } |
|
4074 |
|
4075 TInt CTextLayout::ScrollDocPosIntoViewL(const TTmDocPos& aDocPos) |
|
4076 { |
|
4077 __ASSERT_DEBUG(aDocPos.iPos <= iText->Source()->DocumentLength(), |
|
4078 Panic(EInvalidDocPos)); |
|
4079 TTmLineInfo info; |
|
4080 ExtendFormattingToCoverPosL(aDocPos.iPos); |
|
4081 if (!iText->DocPosToLine(aDocPos,info)) |
|
4082 { |
|
4083 __ASSERT_DEBUG(iText->Source()->DocumentLength() == 0, |
|
4084 Panic(ECharacterNotFormatted)); |
|
4085 return ScrollL(iBandTop, EFDisallowScrollingBlankSpace); |
|
4086 } |
|
4087 TRect line_rect = info.iOuterRect; |
|
4088 line_rect.Move(0,-iBandTop); |
|
4089 int visible_height = VisibleHeightInPixels(); |
|
4090 // if the line is taller than the screen, we must not scroll the |
|
4091 // baseline off the screen. |
|
4092 if (visible_height < info.iBaseline - info.iOuterRect.iTl.iY) |
|
4093 return ScrollL(iBandTop + visible_height - info.iBaseline, |
|
4094 EFDisallowScrollingBlankSpace); |
|
4095 if (line_rect.iTl.iY < 0) |
|
4096 return ScrollL(-line_rect.iTl.iY, EFDisallowScrollingBlankSpace); |
|
4097 if (line_rect.iBr.iY > visible_height) |
|
4098 { |
|
4099 int available = line_rect.iTl.iY; |
|
4100 int desired = line_rect.iBr.iY - visible_height; |
|
4101 if (available > 0) |
|
4102 return ScrollL(-Min(desired,available), EFDisallowScrollingBlankSpace); |
|
4103 } |
|
4104 return 0; |
|
4105 } |
|
4106 |
|
4107 EXPORT_C TInt CTextLayout::GetLineNumber(TInt aDocPos) |
|
4108 { |
|
4109 TTmLineInfo info; |
|
4110 TTmDocPos pos(aDocPos,TRUE); |
|
4111 if (iText->DocPosToLine(pos,info)) |
|
4112 return info.iLineNumber; |
|
4113 return 0; |
|
4114 }; |
|
4115 |
|
4116 |
|
4117 /* |
|
4118 Prune the formatted band, if not formatting all the text, to the required size. If aFromStart is ETrue |
|
4119 prune from the start, otherwise prune from the end. |
|
4120 */ |
|
4121 void CTextLayout::PruneFormatL(TBool aFromStart) |
|
4122 { |
|
4123 if (IsFormattingBand()) |
|
4124 { |
|
4125 int pixels_to_prune = 0; |
|
4126 if (aFromStart) |
|
4127 pixels_to_prune = iBandTop; |
|
4128 else |
|
4129 pixels_to_prune = iText->LayoutHeight() - iBandTop - BandHeightInPixels(); |
|
4130 if (pixels_to_prune <= 0) |
|
4131 return; |
|
4132 TTmFormatParamBase param; |
|
4133 InitFormatParam(param); |
|
4134 int height_decrease = 0; |
|
4135 if(aFromStart) |
|
4136 { |
|
4137 while (pixels_to_prune > 0 && iText->DeletePar(param,aFromStart,pixels_to_prune,height_decrease)) |
|
4138 { |
|
4139 pixels_to_prune -= height_decrease; |
|
4140 if (aFromStart) |
|
4141 iBandTop -= height_decrease; |
|
4142 } |
|
4143 } |
|
4144 else |
|
4145 { |
|
4146 if (pixels_to_prune > (iBandHeight/2)) |
|
4147 { |
|
4148 iText->DeleteFormattingFromEndL(param,pixels_to_prune,height_decrease); |
|
4149 } |
|
4150 } |
|
4151 } |
|
4152 } |
|
4153 |
|
4154 /** Sets the hotspot. |
|
4155 |
|
4156 @param aHotSpot Which part of the line (top, baseline or bottom) should appear |
|
4157 at a vertical pixel position. */ |
|
4158 EXPORT_C void TViewYPosQualifier::SetHotSpot(TPartOfLine aHotSpot) |
|
4159 { |
|
4160 iHotSpot = aHotSpot; |
|
4161 } |
|
4162 |
|
4163 /** Sets whether blank space should be allowed at the bottom of the view. This |
|
4164 applies if the document is more than one page long and the last line is |
|
4165 visible. |
|
4166 |
|
4167 @param aFillScreen ETrue (the default) tries to fill the screen, by ensuring |
|
4168 that there is as little blank space as possible at the bottom of the view. |
|
4169 EFalse allows blank space at the bottom. */ |
|
4170 EXPORT_C void TViewYPosQualifier::SetFillScreen(TBool aFillScreen) |
|
4171 { |
|
4172 iFillScreen = aFillScreen; |
|
4173 } |
|
4174 |
|
4175 /** Forces the top line in the view to become fully visible if it is partially |
|
4176 above the top of the view rectangle. |
|
4177 |
|
4178 @param aMakeLineFullyVisible EFViewForceLineFullyVisible (the default) forces |
|
4179 the top line to be fully visible EFViewDontForceLineFullyVisible does not. */ |
|
4180 EXPORT_C void TViewYPosQualifier::SetMakeLineFullyVisible(TFullyVisible aMakeLineFullyVisible) |
|
4181 { |
|
4182 iFullyVisible = aMakeLineFullyVisible; |
|
4183 } |
|
4184 |
|
4185 void CTextLayout::InitFormatParam(TTmFormatParamBase& aParam) |
|
4186 { |
|
4187 aParam.iMaxHeight = BandHeightInPixels(); |
|
4188 iSource->iExcessHeightRequired = iExcessHeightRequired; |
|
4189 |
|
4190 aParam.iFlags = TTmFormatParamBase::EAtLeastMaxHeight; |
|
4191 aParam.iWrapWidth = iSource->iWidth; |
|
4192 if (iSource->iFlags & TLayDocTextSource::EWrap) |
|
4193 aParam.iFlags |= TTmFormatParamBase::EWrap; |
|
4194 if (iSource->iFlags & TLayDocTextSource::ETruncateWithEllipsis) |
|
4195 { |
|
4196 aParam.iFlags |= TTmFormatParamBase::ETruncateWithEllipsis; |
|
4197 aParam.iEllipsis = iSource->iEllipsis; |
|
4198 } |
|
4199 } |
|
4200 |
|
4201 TInt CTextLayout::VisibleHeightInPixels() const |
|
4202 { |
|
4203 if (iSource->iFormatMode == CLayoutData::EFScreenMode || iSource->iFormatMode == CLayoutData::EFWysiwygMode) |
|
4204 return iVisibleHeight; |
|
4205 else |
|
4206 return iSource->InterpretDevice().VerticalTwipsToPixels(iVisibleHeight); |
|
4207 } |
|
4208 |
|
4209 TInt CTextLayout::BandHeightInPixels() const |
|
4210 { |
|
4211 if (iBandHeight == CLayoutData::EFHeightForFormattingAllText) |
|
4212 return CLayoutData::EFHeightForFormattingAllText; |
|
4213 else |
|
4214 return VisibleHeightInPixels(); |
|
4215 } |
|
4216 |
|
4217 /** |
|
4218 Sets offsets for the edges of the selection highlight. |
|
4219 @param aLeftExtension |
|
4220 Number of pixels to move the left edge of the highlight to the left. |
|
4221 @param aRightExtension |
|
4222 Number of pixels to move the right edge of the highlight to the right. |
|
4223 @param aTopExtension |
|
4224 Number of pixels to move the top edge of the highlight to up. |
|
4225 @param aBottomExtension |
|
4226 Number of pixels to move the bottom edge of the highlight down. |
|
4227 */ |
|
4228 EXPORT_C void CTextLayout::SetHighlightExtensions(TInt aLeftExtension, |
|
4229 TInt aRightExtension, TInt aTopExtension, TInt aBottomExtension) |
|
4230 { |
|
4231 iHighlightExtensions->SetLeftExtension(aLeftExtension); |
|
4232 iHighlightExtensions->SetRightExtension(aRightExtension); |
|
4233 iHighlightExtensions->SetTopExtension(aTopExtension); |
|
4234 iHighlightExtensions->SetBottomExtension(aBottomExtension); |
|
4235 } |
|
4236 |
|
4237 /** |
|
4238 Set the delta required to position the baseline so there is enough |
|
4239 space for the highset glyph in pixels. This is the height of the highest glyph - |
|
4240 CFont::AscentInPixels(). Only used when using TLineSpacingControl::EAttLineSpacingControl. |
|
4241 By default zero. |
|
4242 @param aExcessHeightRequired |
|
4243 Extra height above CFont::AscentInPixels() required for the highest glyph in pixels. |
|
4244 */ |
|
4245 void CTextLayout::SetExcessHeightRequired(TInt aExcessHeightRequired) |
|
4246 { |
|
4247 iExcessHeightRequired = aExcessHeightRequired; |
|
4248 } |
|
4249 |
|
4250 /** |
|
4251 For any rectangle, aRect, which may be extended, calculate |
|
4252 the "remainder" rectanges when the view rectangle is intersected with the |
|
4253 extended rect and then subtracted. |
|
4254 The remainder rectangles are returned via aRemainderRects, which is required |
|
4255 to be a pointer to an array of 4 TRect's. |
|
4256 aRemainderRects[0] is top remainder, ...[1] is bottom, ...[2] is left, ...[3] is right |
|
4257 */ |
|
4258 void CTextLayout::GetHighlightRemnants(const TRect& aRect, const TDrawTextLayoutContext& aDrawTextLayoutContext, |
|
4259 TRect* aRemainderRects) const |
|
4260 { |
|
4261 ASSERT(aRemainderRects); |
|
4262 /* |
|
4263 overlap is the portion of the view rect that aRect intersects with |
|
4264 subtract this from the aRect, giving 4 non-overlapping remainder rectangles, |
|
4265 aRemainderRects, any or all of which may be empty. Copied from SubtractRect in TAGMA |
|
4266 */ |
|
4267 TRect overlap(aDrawTextLayoutContext.iViewRect); |
|
4268 overlap.Intersection(aRect); |
|
4269 if (overlap.IsEmpty()) |
|
4270 overlap.SetRect(aRect.iTl,aRect.iTl); |
|
4271 aRemainderRects[0] = aRect; |
|
4272 aRemainderRects[0].iBr.iY = overlap.iTl.iY; |
|
4273 aRemainderRects[1] = aRect; |
|
4274 aRemainderRects[1].iTl.iY = overlap.iBr.iY; |
|
4275 aRemainderRects[2] = overlap; |
|
4276 aRemainderRects[2].iTl.iX = aRect.iTl.iX; |
|
4277 aRemainderRects[2].iBr.iX = overlap.iTl.iX; |
|
4278 aRemainderRects[3] = overlap; |
|
4279 aRemainderRects[3].iTl.iX = overlap.iBr.iX; |
|
4280 aRemainderRects[3].iBr.iX = aRect.iBr.iX; |
|
4281 } |
|
4282 |
|
4283 /** |
|
4284 Cleanup method for the opaque flag. |
|
4285 */ |
|
4286 void CTextLayout::ResetOpaque(void* aThis) |
|
4287 { |
|
4288 ASSERT(aThis != NULL); |
|
4289 CTextLayout* p = reinterpret_cast <CTextLayout*> (aThis); |
|
4290 p->iSource->iDrawOpaque = EFalse; |
|
4291 } |
|
4292 |
|
4293 /** |
|
4294 Sets opaque drawing flag for CTextLayout object. It will used later when the |
|
4295 content/background has to be drawn. |
|
4296 Until the flag is not reseted, the opaque drawing will be used |
|
4297 for all the content except the background - the flag has an useful meaning only for transparent |
|
4298 editors. |
|
4299 A TCleanupItem object will be pushed into the Cleanup Stack, which will reset the opaque |
|
4300 flag durring its destruction. |
|
4301 */ |
|
4302 void CTextLayout::SetOpaqueLC() |
|
4303 { |
|
4304 iSource->iDrawOpaque = ETrue; |
|
4305 CleanupStack::PushL(TCleanupItem(&CTextLayout::ResetOpaque, this)); |
|
4306 } |
|
4307 |
|
4308 void FormPanic(TFormPanic aPanic) |
|
4309 { |
|
4310 _LIT(KFormPanic,"Form"); |
|
4311 User::Panic(KFormPanic,aPanic); |
|
4312 } |
|
4313 |
|
4314 /** |
|
4315 Default implementation of mapping invisible character to its specified alternate. |
|
4316 |
|
4317 Called by TLayDocTextSource::Map() unless overidden by custom mapping class. |
|
4318 May be called by custom mapping class |
|
4319 @param aChar |
|
4320 Invisible character to be remapped |
|
4321 @param aNonPrintingCharVisibility |
|
4322 Current state of flags showing visibility of invisible characters |
|
4323 @param aLayDoc |
|
4324 Const ref to the calling CLayDocTextSource |
|
4325 @return |
|
4326 The replacement character if remapping has taken place, else return original character |
|
4327 */ |
|
4328 EXPORT_C TUint MFormCustomInvisibleCharacterRemapper::DefaultMapping( TUint aChar, const TNonPrintingCharVisibility aNonPrintingCharVisibility, const TLayDocTextSource& aLayDoc ) |
|
4329 { |
|
4330 // If mapping special characters is possible, use the specified flags. |
|
4331 if (!aNonPrintingCharVisibility.NoneVisible() && aLayDoc.CanMap()) |
|
4332 { |
|
4333 switch (aChar) |
|
4334 { |
|
4335 case CEditableText::EParagraphDelimiter: |
|
4336 if (aNonPrintingCharVisibility.ParagraphDelimitersVisible()) |
|
4337 return KVisibleParagraphBreak; |
|
4338 break; |
|
4339 |
|
4340 case CEditableText::ELineBreak: |
|
4341 if (aNonPrintingCharVisibility.LineBreaksVisible()) |
|
4342 return KVisibleLineBreak; |
|
4343 break; |
|
4344 |
|
4345 case CEditableText::ENonBreakingSpace: |
|
4346 if (aNonPrintingCharVisibility.NonBreakingSpacesVisible()) |
|
4347 return KVisibleNonBreakSpace; |
|
4348 break; |
|
4349 |
|
4350 case CEditableText::EPotentialHyphen: |
|
4351 if (aNonPrintingCharVisibility.PotentialHyphensVisible()) |
|
4352 return KVisiblePotentialHyphen; |
|
4353 break; |
|
4354 |
|
4355 case CEditableText::ENonBreakingHyphen: |
|
4356 if (aNonPrintingCharVisibility.NonBreakingHyphensVisible()) |
|
4357 return KVisibleNonBreakHyphen; |
|
4358 break; |
|
4359 |
|
4360 case CEditableText::ETabCharacter: |
|
4361 if (aNonPrintingCharVisibility.TabsVisible()) |
|
4362 return KVisibleTab; |
|
4363 break; |
|
4364 |
|
4365 case CEditableText::EPictureCharacter: |
|
4366 return KVisiblePicture; |
|
4367 |
|
4368 case 0x200B: // Zero Width Space: the same behaviour as 0x20, while different category from 0x20. |
|
4369 if (aNonPrintingCharVisibility.SpacesVisible()) |
|
4370 return KVisibleSpace; |
|
4371 break; |
|
4372 |
|
4373 /* |
|
4374 For the moment, treat bidirectional controls as if they were non-break spaces, as far as visibility is |
|
4375 concerned, and map as follows: LRE=<, RLE=>, PDF=currency symbol, LRO=left guillemet, RLO=right guillemet. |
|
4376 */ |
|
4377 case 0x202A: // LRE |
|
4378 if (aNonPrintingCharVisibility.NonBreakingSpacesVisible()) |
|
4379 return 0x003C; |
|
4380 break; |
|
4381 case 0x202B: // RLE |
|
4382 if (aNonPrintingCharVisibility.NonBreakingSpacesVisible()) |
|
4383 return 0x003E; |
|
4384 break; |
|
4385 case 0x202C: // PDF |
|
4386 if (aNonPrintingCharVisibility.NonBreakingSpacesVisible()) |
|
4387 return 0x00A4; |
|
4388 break; |
|
4389 case 0x202D: // LRO |
|
4390 if (aNonPrintingCharVisibility.NonBreakingSpacesVisible()) |
|
4391 return 0x00AB; |
|
4392 break; |
|
4393 case 0x202E: // RLO |
|
4394 if (aNonPrintingCharVisibility.NonBreakingSpacesVisible()) |
|
4395 return 0x00BB; |
|
4396 break; |
|
4397 |
|
4398 default: |
|
4399 if (aNonPrintingCharVisibility.SpacesVisible() && TChar(aChar).GetCategory() == TChar::EZsCategory) |
|
4400 return KVisibleSpace; |
|
4401 break; |
|
4402 } |
|
4403 } |
|
4404 |
|
4405 // If not mapping special characters, or not mapping this particular character, use the default mapping. |
|
4406 return aLayDoc.MTmSource::Map(aChar); |
|
4407 } |
|
4408 |
|
4409 |
|
4410 /** |
|
4411 Allows Form clients to register an invisible character remapper object to |
|
4412 customize the visible display of invisible characters such as paragraph marks. |
|
4413 @param aInvisibleCharacterRemapper |
|
4414 Pointer to custom invisible character remapper to use |
|
4415 */ |
|
4416 EXPORT_C void CTextLayout::SetCustomInvisibleCharacterRemapper( MFormCustomInvisibleCharacterRemapper* aInvisibleCharacterRemapper ) |
|
4417 { |
|
4418 iSource->iInvisibleCharacterRemapper = aInvisibleCharacterRemapper; |
|
4419 } |
|
4420 |
|
4421 /** |
|
4422 Allows Form clients to see which character remapper object is currently |
|
4423 registered. |
|
4424 */ |
|
4425 EXPORT_C MFormCustomInvisibleCharacterRemapper* CTextLayout::GetCustomInvisibleCharacterRemapper() |
|
4426 { |
|
4427 return iSource->iInvisibleCharacterRemapper; |
|
4428 } |
|
4429 |
|
4430 /** INC092568: CTextView::SetPendingSelection is not honoured |
|
4431 Sets the cursor position member added for this fix that allows the text layout object |
|
4432 to access any pending selection made by the owning text view object |
|
4433 @param aPos:- pointer to the owning textview's iCursorPos |
|
4434 */ |
|
4435 void CTextLayout::SetTextViewCursorPos(TCursorPosition* aPos) |
|
4436 { |
|
4437 iTextViewCursorPos = aPos; |
|
4438 } |
|
4439 |
|
4440 /** |
|
4441 This is the function used by CTextLayout when it wants to extend the formatted range downwards. |
|
4442 It just calls CTmTextLayout::AddParL, but restricts the maximum height of the new formatting to the |
|
4443 band height/2. If the next paragraph is bigger than this, AddParL will only format part of that |
|
4444 paragraph, and the formatting will end in the middle of the paragraph. |
|
4445 */ |
|
4446 TBool CTextLayout::AddFormattingAtEndL(TTmFormatParamBase& aFormatParam, TInt& aHeightIncrease, TInt& aParagraphsIncrease) |
|
4447 { |
|
4448 aFormatParam.iMaxHeight = iBandHeight/2; |
|
4449 return iText->AddParL(aFormatParam, EFalse, aHeightIncrease, aParagraphsIncrease); |
|
4450 } |
|
4451 |
|
4452 /** |
|
4453 Stops or allows text to be drawn. Included to allow users to control visibility |
|
4454 if text is part of an invisible control. |
|
4455 |
|
4456 @param aVisible ETrue to make the text visible, EFalse to make it invisible. |
|
4457 @see CCoeControl::MakeVisible() |
|
4458 */ |
|
4459 EXPORT_C void CTextLayout::MakeVisible(TBool aVisible) |
|
4460 { |
|
4461 iText->MakeVisible(aVisible); |
|
4462 } |
|
4463 |