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