Update contrib.
2 * Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
15 * CTextLayout implementation using the TAGMA text formatting system.
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"
32 #include "OstTraceDefinitions.h"
33 #ifdef OST_TRACE_COMPILER_IN_USE
34 #include "LAYEMUTraces.h"
37 const TInt KMaxExtraLines = 10; // maximum number of lines to format after the current and following lines
38 // before using background formatting
39 // during page down/up, the number of lines that should remain visible after
40 // the scroll, counting from the first line that is not completely visible.
41 // i.e. setting this to 0 means always scroll KMaxProportionOfScreenToScroll.
42 // setting it to 1 means make sure that no lines are ever both partially off the
43 // top/bottom before the scroll and partially visible off the bottom/top after
45 // setting it to any number higher means keep that number -1 lines completely
46 // visible before and after the scroll.
47 const TInt KNumberOfLinesToKeepVisibleDuringScroll = 2;
48 /** maximum scroll proportions in thousandths. This overrides
49 the KNumberOfLinesToKeepVisibleDuringScroll constant.*/
50 const TInt KMaxProportionOfScreenToScroll = 1000;
51 /** minimum scroll proportions in thousandths. This overrides
52 the KNumberOfLinesToKeepVisibleDuringScroll constant.*/
53 const TInt KMinProportionOfScreenToScroll = 600;
57 Constructs an iterator over the text referenced by aSource.
58 @param aSource The source of the text to be iterated over.
60 CTextLayout::TUtf32SourceCache::TUtf32SourceCache(const MTmSource& aSource)
61 : iSource(&aSource), iCurrentViewIndex(-1)
66 Constructs an iterator over the text formatted by aLayout.
67 @param aLayout The formatter of the text to be iterated over.
69 CTextLayout::TUtf32SourceCache::TUtf32SourceCache(const CTextLayout& aLayout)
70 : iSource(aLayout.iSource), iCurrentViewIndex(-1)
75 Gets the specified character without uniting surrogate pairs.
76 @param aIndex The document position to retrieve.
77 @pre 0 <= aIndex && aIndex < {document length}
79 TText CTextLayout::TUtf32SourceCache::GetUtf16(TInt aIndex)
82 if (aIndex < iCurrentViewIndex)
84 iCurrentViewIndex = 0;
85 iSource->GetText(iCurrentViewIndex, iCurrentView, dummy);
87 TInt currentViewEnd = iCurrentViewIndex + iCurrentView.Length();
88 while (currentViewEnd <= aIndex)
90 TInt difference = aIndex - iCurrentViewIndex;
91 TInt newIndex = aIndex - (difference >> 1);
92 iCurrentViewIndex = newIndex < currentViewEnd?
93 currentViewEnd : newIndex;
94 iSource->GetText(iCurrentViewIndex, iCurrentView, dummy);
95 currentViewEnd = iCurrentViewIndex + iCurrentView.Length();
97 return iCurrentView[aIndex - iCurrentViewIndex];
101 Gets the specified character, uniting surrogate pairs if appropriate.
103 The document position to retrive.
105 The character at position aIndex. If aIndex is at the first code of a
106 surrogate pair, the full character is returned. If it is the second of a
107 valid surrogate pair or an unpaired surrogate, the surrogate is returned.
109 TChar CTextLayout::TUtf32SourceCache::GetUtf32(TInt aIndex)
111 TText code = GetUtf16(aIndex);
112 if (TChar::IsHighSurrogate(code) && iSource->DocumentLength() < aIndex + 1)
114 TText code2 = GetUtf16(aIndex + 1);
115 if (TChar::IsLowSurrogate(code2))
116 return TChar::JoinSurrogate(code, code2);
121 /** Allocates and constructs a CTextLayout object. By default, the formatting
122 is set to the entire document (EFFormatAllText).
124 The text needs to be reformatted after a call to this function.
126 @param aDoc Pointer to the MLayDoc implementation that is the source of the
127 text and formatting information. Must not be NULL or a panic occurs.
128 @param aWrapWidth The wrapping width in pixels.
129 @return Pointer to the new CTextLayout object. */
130 EXPORT_C CTextLayout *CTextLayout::NewL(MLayDoc *aLayDoc,TInt aWrapWidth)
132 CTextLayout* t = new(ELeave) CTextLayout;
133 CleanupStack::PushL(t);
134 t->ConstructL(aLayDoc,aWrapWidth);
139 EXPORT_C CTextLayout::CTextLayout():
141 iExcessHeightRequired(0),
143 iBeginRedrawCount(0),
145 iTextViewCursorPos(NULL),
146 iIsWndInExternalRedraw(EFalse),
147 iUnformattedStart(KMaxTInt),
148 iHighlightExtensions(NULL),
153 /** Constructs an object with a text source of aLayDoc and a wrap width of
154 aWrapWidth, with wrapping turned on.
156 EXPORT_C void CTextLayout::ConstructL(MLayDoc *aLayDoc,TInt aWrapWidth)
158 iHighlightExtensions = new(ELeave) TTmHighlightExtensions;
159 CleanupStack::PushL(iHighlightExtensions);
160 iHighlightExtensions->SetAll(0);
162 iText = new(ELeave) CTmTextLayout;
163 CleanupStack::PushL(iHighlightExtensions);
165 iSource = new(ELeave) TLayDocTextSource;
166 iSource->iLayDoc = aLayDoc;
167 SetWrapWidth(aWrapWidth);
168 SetAmountToFormat(EFFormatAllText);
170 CleanupStack::Pop(2);
173 EXPORT_C CTextLayout::~CTextLayout()
175 delete iHighlightExtensions;
176 iHighlightExtensions = NULL;
183 void CTextLayout::SetWindow(RWindow* aWnd)
188 void CTextLayout::SetReadyToRedraw()
190 iReadyToRedraw = ETrue;
193 void CTextLayout::BeginRedraw(const TRect& aRect)
198 if (0 == iBeginRedrawCount++)
203 if (iWnd->GetDrawRect() == TRect::EUninitialized)
205 iWnd->Invalidate(aRect);
206 iWnd->BeginRedraw(aRect);
209 iIsWndInExternalRedraw = ETrue;
214 void CTextLayout::EndRedraw()
219 if (iBeginRedrawCount <= 0)
221 OstTrace0( TRACE_DUMP, CTEXTLAYOUT_ENDREDRAW, "CTextLayout::EndRedraw" );
223 __ASSERT_ALWAYS(iBeginRedrawCount > 0, Panic(EInvalidRedraw));
225 if (0 == --iBeginRedrawCount)
229 if (!iIsWndInExternalRedraw)
232 iRedrawRect = TRect();
235 iIsWndInExternalRedraw = EFalse;
240 void CTextLayout::SetExternalDraw(const TRect& aRect)
242 if (0 != iBeginRedrawCount)
244 OstTrace0( TRACE_FATAL, DUP1_CTEXTLAYOUT_SETEXTERNALDRAW, "EInvalidRedraw" );
246 __ASSERT_ALWAYS(0 == iBeginRedrawCount, Panic(EInvalidRedraw));
251 void CTextLayout::ResetExternalDraw()
253 if (1 != iBeginRedrawCount)
255 OstTrace0( TRACE_FATAL, CTEXTLAYOUT_RESETEXTERNALDRAW, "EInvalidRedraw" );
257 __ASSERT_ALWAYS(1 == iBeginRedrawCount, Panic(EInvalidRedraw));
260 iRedrawRect = TRect();
263 TBool CTextLayout::BeginRedrawCalled() const
265 return iBeginRedrawCount > 0;
269 /** Discards all formatting information. This function is used by the CTextView
270 and the printing classes, but should be called by higher-level classes that
271 need to clean up after any CTextLayout function has caused an out-of-memory
273 EXPORT_C void CTextLayout::DiscardFormat()
279 TInt CTextLayout::SetBandTop()
281 TInt originalBandTop = iBandTop;
282 if (iScrollFlags & EFScrollOnlyToTopsOfLines)
285 if (iText->YPosToLine(iBandTop, line))
286 iBandTop = line.iOuterRect.iTl.iY;
288 return originalBandTop - iBandTop;
291 /** Sets the layout object's source text to aDoc.
293 The text needs to be reformatted after a call to this function.
295 @param aDoc Pointer to the MLayDoc implementation that is the source of the
296 text and formatting information. Must not be NULL or a panic occurs. */
297 EXPORT_C void CTextLayout::SetLayDoc(MLayDoc *aLayDoc)
299 iSource->iLayDoc = aLayDoc;
302 /** Sets the wrap width. If the current format mode is screen mode
303 (CLayoutData::EFScreenMode) aWrapWidth is in pixels, otherwise it is in twips.
305 The text needs to be reformatted after a call to this function.
309 A valid wrap width (>0) must be supplied or the expected amount of formatting will
310 not take place. This could lead to panics when trying to retrieve formatting
311 information that does not exist.
313 @param aWrapWidth The wrap width in pixels or twips. */
314 EXPORT_C void CTextLayout::SetWrapWidth(TInt aWrapWidth)
316 if (iSource->iFormatMode == CLayoutData::EFScreenMode)
317 iSource->iWidth = aWrapWidth;
319 iSource->iWidth = iSource->iFormatDevice->HorizontalTwipsToPixels(aWrapWidth);
322 /** Sets the height of the band in pixels or twips. This is the height of the
323 visible text, or the view window, and it is also the page height for the
324 purposes of scrolling up and down by page. If the current mode is screen mode
325 (CLayoutData::EFScreenMode) or what-you-see-is-what-you-get mode
326 (CLayoutData::EFWysiwygMode), aHeight is in pixels, otherwise it is in twips.
328 The text needs to be reformatted after a call to this function.
332 A valid band height (>0) must be supplied or the expected amount of formatting will
333 not take place. This could lead to panics when trying to retrieve formatting
334 information that does not exist.
336 @param aHeight The band height in pixels or twips. */
337 EXPORT_C void CTextLayout::SetBandHeight(TInt aHeight)
339 iVisibleHeight = aHeight;
340 if (iBandHeight != CLayoutData::EFHeightForFormattingAllText || aHeight < 1)
341 iBandHeight = aHeight;
344 /** Gets the height of the band in pixels or twips.
345 @return The height of the band in pixels or twips. */
346 EXPORT_C TInt CTextLayout::BandHeight() const
348 return VisibleHeightInPixels();
351 /** Sets the device map used for drawing and formatting. This device map is
352 also used for formatting and drawing paragraph labels unless a separate label
353 device map has been set (see SetLabelsDeviceMap()).
355 The text needs to be reformatted after a call to this function.
359 Although the name of the function suggests that only the image device is set,
360 the formatting device is also set.
362 @param aGd The device map used for drawing and formatting. */
363 EXPORT_C void CTextLayout::SetImageDeviceMap(MGraphicsDeviceMap *aDeviceMap)
365 iSource->iImageDevice = aDeviceMap;
366 iSource->iFormatDevice = aDeviceMap;
369 /** Sets the device map used for formatting and drawing paragraph labels. If
370 not set, the device map used for labels will be the same as that used for the
373 The text needs to be reformatted after a call to this function.
375 @param aDeviceMap The device map used for formatting and drawing paragraph
377 EXPORT_C void CTextLayout::SetLabelsDeviceMap(MGraphicsDeviceMap *aDeviceMap)
379 iSource->iLabelsDevice = aDeviceMap;
382 /** Sets whether to format all the text (if aAmountOfFormat is
383 EFFormatAllText), or just the visible band (if aAmountOfFormat is
384 EFFormatBand). If band formatting is selected, enough text is formatted to fill
387 The text needs to be reformatted after a call to this function.
389 @param aAmountOfFormat CTextLayout::EFFormatBand (the default) to format the
390 visible text only. CTextLayout::EFFormatAllText to format all the text in the
392 EXPORT_C void CTextLayout::SetAmountToFormat(TAmountFormatted aAmountOfFormat)
394 if (aAmountOfFormat == EFFormatBand)
395 iBandHeight = iVisibleHeight;
397 iBandHeight = CLayoutData::EFHeightForFormattingAllText;
400 /** Tests whether band formatting is on, as set by
401 CTextLayout::SetAmountToFormat().
402 @return ETrue if band formatting is on, EFalse if not. */
403 EXPORT_C TBool CTextLayout::IsFormattingBand() const
405 return iBandHeight != CLayoutData::EFHeightForFormattingAllText;
408 /** Sets the format mode and wrap width and (for certain format modes only)
409 sets the formatting device.
411 The text needs to be reformatted after a call to this function.
415 If aFormatMode is CLayoutData::EFWysiwygMode or
416 CLayoutData::EFPrintPreviewMode, the format device is set to aFormatDevice,
417 which must not be NULL.
419 If aFormatMode is CLayoutData::EFScreenMode or CLayoutData::EFPrintMode,
420 aFormatDevice is ignored and should be NULL; the format device is set to the
423 The wrap width is set in either twips or pixels using the same rule as for
426 @param aFormatMode The format mode.
427 @param aWrapWidth The wrap width in pixels or twips.
428 @param aFormatDevice The formatting device or NULL, depending on the format
430 EXPORT_C void CTextLayout::SetFormatMode(CLayoutData::TFormatMode aFormatMode,TInt aWrapWidth,
431 MGraphicsDeviceMap* aFormatDevice)
433 if (aFormatMode == CLayoutData::EFWysiwygMode || aFormatMode == CLayoutData::EFPrintPreviewMode)
435 if (aFormatDevice == NULL)
437 OstTrace0( TRACE_FATAL, CTEXTLAYOUT_SETFORMATMODE, "EFormatDeviceNotSet" );
439 __ASSERT_ALWAYS(aFormatDevice != NULL,Panic(EFormatDeviceNotSet));
440 iSource->iFormatDevice = aFormatDevice;
443 iSource->iFormatDevice = iSource->iImageDevice;
444 iSource->iFormatMode = aFormatMode;
445 SetWrapWidth(aWrapWidth);
448 /** Turns wrapping on (if aNoWrapping is EFParagraphsWrappedByDefault) or off
449 (if aNoWrapping is EFAllParagraphsNotWrapped). Overrides the paragraph format
450 when wrapping is turned off -paragraphs are not broken into lines even if the
451 iWrap member of CParaFormat is ETrue. If wrapping is turned on,
452 CParaFormat::iWrap is honoured.
454 The text needs to be reformatted after a call to this function.
456 @param aNoWrapping EFAllParagraphsNotWrapped (the default) to turn wrapping
457 off, EFParagraphsWrappedByDefault to turn wrapping on. */
458 EXPORT_C void CTextLayout::ForceNoWrapping(TBool aNoWrapping)
461 iSource->iFlags &= ~TLayDocTextSource::EWrap;
463 iSource->iFlags |= TLayDocTextSource::EWrap;
466 /** Tests whether wrapping is on or off.
467 @return ETrue if wrapping is on, EFalse if off. */
468 EXPORT_C TBool CTextLayout::IsWrapping() const
470 return (iSource->iFlags & TLayDocTextSource::EWrap) != 0;
473 /** Sets the truncation mode. If truncation is on, lines that exceed the wrap
474 width, either because they have no legal line break, or because wrapping is
475 off, are truncated, and an ellipsis is inserted.
477 @param aOn If ETrue, lines which extend beyond the wrap width are truncated
478 with an ellipsis character. If EFalse, no ellipsis is used. */
479 EXPORT_C void CTextLayout::SetTruncating(TBool aOn)
482 iSource->iFlags |= TLayDocTextSource::ETruncateWithEllipsis;
484 iSource->iFlags &= ~TLayDocTextSource::ETruncateWithEllipsis;
487 /** Tests whether truncation is on (as set by SetTruncating()).
488 @return ETrue if truncation is on, EFalse if not. */
489 EXPORT_C TBool CTextLayout::Truncating() const
491 return (iSource->iFlags & TLayDocTextSource::ETruncateWithEllipsis) != 0;
494 /** Sets the ellipsis character to be used if truncation is on. Specify the
495 value 0xFFFFÂ (the illegal Unicode character) if no ellipsis character should
496 be used. By default, the ellipsis character is 0x2026, the ordinary horizontal
499 @param aEllipsis The Unicode value of the truncating ellipsis character. */
500 EXPORT_C void CTextLayout::SetTruncatingEllipsis(TChar aEllipsis)
502 iSource->iEllipsis = aEllipsis;
505 /** Returns the ellipsis character used when truncation is on. The value 0xFFFF
506 (the illegal Unicode character) means that no ellipsis character is appended to
509 @return The Unicode value of the truncating ellipsis character. */
510 EXPORT_C TChar CTextLayout::TruncatingEllipsis() const
512 return iSource->iEllipsis;
515 /** Sets the width in pixels of the margin in which labels are drawn.
517 The text needs to be reformatted after a call to this function.
519 @param aWidth The width in pixels of the labels margin. */
520 EXPORT_C void CTextLayout::SetLabelsMarginWidth(TInt aWidth)
522 iSource->iLabelsWidth = aWidth;
525 /** Specifies which non-printing characters (e.g. space, paragraph break, etc.)
526 are to be drawn using symbols.
528 The text needs to be reformatted after a call to this function.(because
529 non-printing characters may differ in width from their visible
532 @param aVisibility Indicates which non-printing characters are drawn using
534 EXPORT_C void CTextLayout::SetNonPrintingCharsVisibility(TNonPrintingCharVisibility aVisibility)
536 iSource->iNonPrintingCharVisibility = aVisibility;
539 /** Returns which non-printing characters are drawn using symbols.
540 @return Indicates which non-printing characters are drawn using symbols. */
541 EXPORT_C TNonPrintingCharVisibility CTextLayout::NonPrintingCharsVisibility() const
543 return iSource->iNonPrintingCharVisibility;
546 /** Tests whether background formatting is currently taking place. Background
547 formatting is managed by CTextView, using an active object, when the
548 CTextLayout object is owned by a CTextView object.
550 Not generally useful.
552 @return ETrue if background formatting is currently taking place. EFalse if not.
554 EXPORT_C TBool CTextLayout::IsBackgroundFormatting() const
556 return iUnformattedStart < KMaxTInt;
559 /** CTextView calls this function when background formatting has ended. It
560 allows the CTextLayout object to discard information used only during
561 background formatting.
563 Not generally useful. */
564 EXPORT_C void CTextLayout::NotifyTerminateBackgroundFormatting()
566 iUnformattedStart = KMaxTInt;
570 /** Specifies whether partially displayed lines (at the top and bottom of
571 the view) are to be prevented from being drawn, and whether the top of
572 the display is to be aligned to the nearest line.
574 This function takes effect only when the text is next formatted or
575 scrolled.Note:This function was designed for non-editable text in the
576 Agenda application, and there is an important restriction:
577 CTextView functions that reformat the text after editing must not be used
578 while partial lines are excluded; these functions are
579 CTextView::HandleCharEditL(),
580 CTextView::HandleInsertDeleteL() and
581 CTextView::HandleRangeFormatChangeL().
583 @param aExcludePartialLines ETrue (the default) to exclude partially
584 displayed lines from the view. EFalse to include them.
586 //It did not work, and it was not what the customer wanted. A more comprehensive
587 //solution is being considered.
588 EXPORT_C void CTextLayout::SetExcludePartialLines(TBool) {}
590 /** Tests whether partial lines at the top and bottom of the view are
593 @return ETrue if partial lines are excluded, EFalse if they are displayed.
595 EXPORT_C TBool CTextLayout::ExcludingPartialLines() const
600 /** Sets the percentage by which font heights are increased in order to provide
601 automatic extra spacing (leading) between lines. This amount is set to
602 CLayoutData::EFFontHeightIncreaseFactor, which is 7, when a CTextLayout object
605 The text needs to be reformatted after a call to this function.
607 @param aPercentage Factor by which to increase font heights. */
608 EXPORT_C void CTextLayout::SetFontHeightIncreaseFactor(TInt aPercentage)
610 iSource->iFontHeightIncreaseFactor = aPercentage;
613 /** Returns the font height increase factor as a percentage (i.e. a return
614 value of 7 means that font heights are increased by 7% to provide automatic
615 extra spacing between lines).
617 @return Factor by which font heights are increased. */
618 EXPORT_C TInt CTextLayout::FontHeightIncreaseFactor() const
620 return iSource->iFontHeightIncreaseFactor;
623 /** Sets the minimum line descent in pixels. This amount is set to
624 CLayoutData::EFMinimumLineDescent, which is 3, when a CTextLayout object is
627 The text needs to be reformatted after a call to this function.
629 @param aPixels The minimum line descent in pixels. */
630 EXPORT_C void CTextLayout::SetMinimumLineDescent(TInt aPixels)
632 iSource->iMinimumLineDescent = aPixels;
635 /** Returns the minimum line descent in pixels.
636 @return The minimum line descent in pixels. */
637 EXPORT_C TInt CTextLayout::MinimumLineDescent() const
639 return iSource->iMinimumLineDescent;
642 /** Returns the document length in characters, including all the text, not just
643 the formatted portion, but not including the final paragraph delimiter (the
644 "end-of-text character") if any. Thus the length of an empty document is zero.
646 @return The number of characters in the document */
647 EXPORT_C TInt CTextLayout::DocumentLength() const
649 return iSource->DocumentLength();
652 /** Sets aDocPos to the paragraph start and returns the amount by which aDocPos
653 has changed, as a non-negative number.
655 @param aDocPos A document position. On return, contains the document position
656 of the first character in the paragraph.
657 @return The number of characters skipped in moving to the new document
659 EXPORT_C TInt CTextLayout::ToParagraphStart(TInt& aDocPos) const
661 TInt old_pos = aDocPos;
662 aDocPos = iSource->ParagraphStart(aDocPos);
663 return old_pos - aDocPos;
666 /** Returns the height in pixels of any formatted text above the visible
668 @return The height in pixels of any formatted text above the visible region. */
669 EXPORT_C TInt CTextLayout::PixelsAboveBand() const
674 /** Returns the y coordinate of the bottom of the last formatted line, relative
675 to the top of the visible region.
677 @return The y coordinate of the bottom of the last formatted line. */
678 EXPORT_C TInt CTextLayout::YBottomLastFormattedLine() const
680 return Max(0, iText->LayoutHeight() - iBandTop );
683 /** Returns the height in pixels of the formatted text.
685 @return The height in pixels of all the formatted text. */
686 EXPORT_C TInt CTextLayout::FormattedHeightInPixels() const
688 return iText->LayoutHeight();
691 /** Returns the number of fully or partially visible characters in the visible
694 @param aDocPos On return, contains the document position of the first fully or
695 partially visible character in the band.
696 @return The total number of characters in the band. */
697 EXPORT_C TInt CTextLayout::PosRangeInBand(TInt& aDocPos) const
700 if (!iText->YPosToLine(iBandTop,info))
705 aDocPos = info.iStart;
706 int end = iSource->DocumentLength();
707 //INC085809 - less 1 pixel. Rect edge is actually outside bounds
708 if (iText->YPosToLine(iBandTop + VisibleHeightInPixels() - 1,info))
710 return end - aDocPos;
713 /** Tests whether the document position aDocPos is fully or partially visible.
714 If it is, puts the y coordinate of the left-hand end of the baseline of the
715 line containing aDocPos into aXyPos.
717 @param aDocPos The document position of interest.
718 @param aXyPos On return, contains the y coordinate of the left-hand end of the
719 baseline of the line containing aDocPos.
720 @return ETrue if the position is visible. EFalse if the position is not visible.
722 EXPORT_C TBool CTextLayout::PosInBand(TInt aDocPos,TPoint& aXyPos) const
725 TTmDocPos pos(aDocPos, ETrue);
726 TBool result = PosInBand(pos,&info);
728 aXyPos.iY = info.iBaseline;
732 /** Tests whether the document position aDocPos is fully or partially visible.
733 If it is, puts the y coordinate of the left-hand end of the baseline of the
734 line containing aDocPos into aXyPos.
736 @param aDocPos The document position of interest.
737 @param aXyPos On return, contains the y coordinate of the left-hand end of the
738 baseline of the line containing aDocPos.
739 @return ETrue if the position is visible. EFalse if the position is not visible.
741 EXPORT_C TBool CTextLayout::PosInBand(TTmDocPos aDocPos,TPoint& aXyPos) const
744 TBool result = PosInBand(aDocPos,&info);
746 aXyPos.iY = info.iBaseline;
750 /** Tests whether the document position aDocPos is fully or partially visible.
751 If it is, puts the baseline of the line containing aDocPos into aLineInfo.
753 @param aDocPos The document position of interest.
754 @param aLineInfo On return, contains the baseline of the line containing
757 @return ETrue if the document position aDocPos is fully or partially visible. If
758 so, and if aLineInfo is non-NULL, puts information about the line in aLineInfo.
760 EXPORT_C TBool CTextLayout::PosInBand(const TTmDocPos& aDocPos,TTmLineInfo* aLineInfo) const
763 TTmLineInfo* info_ptr = aLineInfo ? aLineInfo : &dummy;
764 TTagmaForwarder forwarder(*this);
765 if (!forwarder.DocPosToLine(aDocPos,*info_ptr))
767 return info_ptr->iOuterRect.iBr.iY > 0 && info_ptr->iOuterRect.iTl.iY < VisibleHeightInPixels();
770 /** Tests whether the character aDocPos is formatted.
774 If a section of text contains characters p to q, it contains document positions
775 p to q + 1; but this function returns ETrue for positions p to q only, so it
776 refers to characters, not positions. However, it will return ETrue for q if q is
777 the end of the document.
779 @param aDocPos The document position of interest.
780 @return ETrue if the character at the document position specified is formatted.
782 EXPORT_C TBool CTextLayout::PosIsFormatted(TInt aDocPos) const
784 if (aDocPos < iText->StartChar())
786 if (aDocPos >= iText->StartChar() + FormattedLength())
791 /** Gets the document position of the first character in the specified line,
792 counting the first line as line one (not zero) in the band. If the line is
793 after the band, returns the last character position of the band. If there is no
794 formatted text, returns CTextLayout::EFNoCurrentFormat.
796 @param aLineNo Line number in formatted text, counting the first line as line
798 @return The document position of the first character on the line. */
799 EXPORT_C TInt CTextLayout::FirstCharOnLine(TInt aLineNo) const
803 OstTrace0( TRACE_DUMP, CTEXTLAYOUT_FIRSTCHARONLINE, "EInvalidLineNumber" );
805 __ASSERT_DEBUG(aLineNo > 0,Panic(EInvalidLineNumber));
806 if (iText->StartChar() == iText->EndChar())
807 return EFNoCurrentFormat;
810 if (!iText->LineNumberToLine(aLineNo,info))
811 return Min(iText->EndChar(),iSource->DocumentLength());
815 /** Returns the number of formatted characters. This will be one more than
816 expected if the formatted text runs to the end of the document, because it will
817 include the end-of-text character.
819 @return The number of formatted characters in the document. */
820 EXPORT_C TInt CTextLayout::FormattedLength() const
822 return iText->EndChar() - iText->StartChar();
825 /** Returns the document position of the first formatted character.
827 @return The document position of the first formatted character. */
828 EXPORT_C TInt CTextLayout::FirstFormattedPos() const
830 return iText->StartChar();
833 /** Gets the number of formatted lines.
835 @return The number of formatted lines in the document. */
836 EXPORT_C TInt CTextLayout::NumFormattedLines() const
838 return iText->Lines();
841 /** Returns the line number, counting from 0, of the first fully visible line.
843 @return The line number of the first fully visible line. */
844 EXPORT_C TInt CTextLayout::FirstLineInBand() const
847 if (!iText->YPosToLine(iBandTop,info))
849 int line = info.iLineNumber;
850 if (info.iOuterRect.iTl.iY < iBandTop)
855 /** Gets the rectangle enclosing the formatted line that contains or is closest
856 to y coordinate aYPos. If aYPos is above the first formatted line, the
857 rectangle returned is that of the first formatted line. If aYPos is below the
858 last formatted line the rectangle returned is that of the last formatted line.
859 If there is no formatted text, returns CTextLayout::EFNoCurrentFormat.
861 @param aYPos The y coordinate of the line of interest.
862 @param aLine On return, contains the rectangle which encloses the line at
865 @return The line width in pixels. */
866 EXPORT_C TInt CTextLayout::GetLineRect(TInt aYPos,TRect& aRect) const
868 int y = iBandTop + aYPos;
870 // Snap to formatted area.
871 if (y >= iText->LayoutHeight())
872 y = iText->LayoutHeight() - 1;
877 TBool found = iText->YPosToLine(y,info);
880 aRect.SetSize(TSize(0,0));
881 return EFNoCurrentFormat;
884 aRect = info.iOuterRect;
885 aRect.iTl.iX = info.iInnerRect.iTl.iX;
886 aRect.iBr.iX = info.iInnerRect.iBr.iX;
887 aRect.Move(0,-iBandTop);
888 return aRect.Width();
891 /** Returns the height of the paragraph containing aDocPos. If the paragraph is
892 not formatted, returns zero. If the paragraph is partially formatted, returns
893 the height of the formatted part.
895 @param aDocPos A document position within the paragraph of interest.
896 @return The height in pixels of the paragraph. Zero if the paragraph is not
898 EXPORT_C TInt CTextLayout::ParagraphHeight(TInt aDocPos) const
901 GetParagraphRect(TTmDocPos(aDocPos, ETrue), r);
905 /** Returns the rectangle enclosing the paragraph containing aDocPos. If the
906 paragraph is not formatted, returns an empty rectangle. If the paragraph is
907 partially formatted, returns the rectangle enclosing the formatted part.
909 @param aDocPos A document position within the paragraph.
910 @return The rectangle which encloses the paragraph containing aDocPos. */
911 EXPORT_C TRect CTextLayout::ParagraphRectL(TInt aDocPos) const
914 GetParagraphRect(TTmDocPos(aDocPos, ETrue), r);
918 /** Returns the left and right extremes, in layout coordinates, of the
921 @param aLeftX On return, contains the x coordinate of the leftmost point of the
923 @param aRightX On return, contains the x coordinate of the rightmost point of
925 @param aOnlyVisibleLines If ETrue, only scans partially or fully visible lines.
926 If EFalse, scans all the formatted text.
927 @param aIgnoreWrapCharacters If ETrue, does not include wrap characters in the
928 measurement (paragraph delimiters, forced line breaks, etc.). If EFalse,
930 @return EFalse if there is no formatted text, otherwise ETrue. */
931 EXPORT_C TBool CTextLayout::CalculateHorizontalExtremesL(TInt& aLeftX,TInt& aRightX,
932 TBool aOnlyVisibleLines,
933 TBool /*aIgnoreWrapCharacters*/) const
935 return CalculateHorizontalExtremes(aLeftX,aRightX,aOnlyVisibleLines);
936 //+ implement aIgnoreWrapCharacters? not until clearly specified
939 TBool CTextLayout::CalculateHorizontalExtremes(TInt& aLeftX,TInt& aRightX,
940 TBool aOnlyVisibleLines) const
943 int bottom = KMaxTInt;
944 if (aOnlyVisibleLines)
947 bottom = iBandTop + VisibleHeightInPixels();
949 iText->HorizontalExtremes(aLeftX, aRightX, top, bottom);
952 if (aRightX < iSource->iWidth)
953 aRightX = iSource->iWidth;
954 return iText->StartChar() < iText->EndChar();
957 TInt CTextLayout::WrapWidth() const
959 return iSource->iWidth;
962 TBool CTextLayout::GetCursor(const TTmDocPos& aDocPos,TTmCursorPlacement aPlacement,
963 TRect& aLineRect,TPoint& aOrigin,TInt& aWidth,TInt& aAscent,TInt& aDescent) const
966 TBool result = iText->GetCursor(aDocPos,aPlacement,info,aOrigin,aWidth,aAscent,aDescent);
969 aOrigin.iY -= iBandTop;
970 aLineRect = info.iOuterRect;
971 aLineRect.iTl.iX = info.iInnerRect.iTl.iX;
972 aLineRect.iBr.iX = info.iInnerRect.iBr.iX;
973 aLineRect.Move(0,-iBandTop);
978 /** Gets the height (ascent + descent) and ascent of the font of the character
979 at aDocPos, as created using the graphics device map used for drawing (the
980 "image device") and returns them in aHeight and aAscent, after increasing
981 aHeight by the font height increase factor (see SetFontHeightIncreaseFactor()).
983 @param aDocPos A document position.
984 @param aHeight On return contains the height in pixels of the character at
986 @param aAscent On return, contains the ascent in pixels of the character at
988 EXPORT_C void CTextLayout::GetCharacterHeightAndAscentL(TInt aDocPos,TInt& aHeight,TInt& aAscent) const
991 TTmCharFormat format;
992 iSource->GetText(aDocPos,text,format);
994 format.iFontSpec.GetTFontSpec(fs);
995 GetFontHeightAndAscentL(fs,aHeight,aAscent);
998 /** Gets the height (ascent + descent) and ascent of the font specified by
999 aFontSpec, as created using the graphics device map used for drawing (the
1000 "image device") and puts them into aHeight and aAscent, after increasing
1001 aHeight by the font height increase factor (see SetFontHeightIncreaseFactor()).
1003 @param aFontSpec Font specification.
1004 @param aHeight On return, contains the height in pixels of the font.
1005 @param aAscent On return, contains the ascent in pixels of the font. */
1006 EXPORT_C void CTextLayout::GetFontHeightAndAscentL(const TFontSpec& aFontSpec,TInt& aHeight,TInt& aAscent) const
1009 MGraphicsDeviceMap& device = iSource->InterpretDevice();
1010 User::LeaveIfError(device.GetNearestFontInTwips(font,aFontSpec));
1011 aHeight = font->HeightInPixels();
1012 int increase = (iSource->iFontHeightIncreaseFactor * aHeight) / 100;
1013 aHeight += increase;
1014 aAscent = font->AscentInPixels() + increase;
1015 device.ReleaseFont(font);
1018 /** Returns the index of the nearest character in the document to the window
1019 coordinates specified. Sets aPos to the actual position of the intersection
1020 of the line's baseline with the character's edge. If aPos is before the start
1021 of the formatted area, returns the first formatted character; if it is after
1022 the end of the formatted area, returns the position after the last formatted
1023 character, or the end of the document, whichever is less.
1025 This function is deprecated in v7.0s. Use the more powerful FindXYPos() instead.
1027 @param aPos Contains coordinates to convert to a document position. On return,
1028 contains the exact coordinates of the intersection of the line's baseline with
1029 the character edge at the document position.
1030 @param aFlags Three possible values: 0 is the default, and performs the task at
1031 full accuracy (the function returns the document position of the character edge
1032 nearest to the coordinates). CLayoutData::EFWholeLinesOnly examines lines only
1033 and returns the position at the right end of the line if aPos.iX > 0, otherwise
1034 the position at the left end.
1035 @return The document position of the nearest character to the coordinates, or
1036 of the start or end of the line, depending on the value of aFlags. */
1037 EXPORT_C TInt CTextLayout::XyPosToDocPosL(TPoint &aXyPos,TUint) const
1039 if (aXyPos.iY < -iBandTop)
1040 return iText->StartChar();
1041 else if (aXyPos.iY >= iText->LayoutHeight() - iBandTop)
1042 return Min(iText->EndChar(),iSource->DocumentLength());
1043 TTmPosInfo2 pos_info;
1044 TTmLineInfo lineInfo;
1045 FindXyPos(aXyPos,pos_info, &lineInfo);
1046 aXyPos = pos_info.iEdge;
1047 TInt r = pos_info.iDocPos.iPos;
1048 if (!pos_info.iDocPos.iLeadingEdge && lineInfo.iStart != r)
1052 // surrogate support
1056 TTmCharFormat format;
1058 iSource->GetText( r - 1, text, format );
1059 if ( text.Length() > 1 )
1061 TUint highSurrogate = text[0];
1062 TUint lowSurrogate = text[1];
1063 if ( TChar::IsHighSurrogate( highSurrogate ) &&
1064 TChar::IsLowSurrogate( lowSurrogate ) )
1073 /** Finds the document position nearest to aXyPos. If aXyPos is in the
1074 formatted text returns ETrue, otherwise returns EFalse. If ETrue is returned,
1075 places information about the document position in aPosInfo and information
1076 about the line containing the document position in aLineInfo if it is non-NULL.
1078 @param aXyPos Contains coordinates to convert to a document position.
1079 @param aPosInfo Buffer to store information about the document position if the
1080 specified coordinates are located in the formatted text.
1081 @param aLineInfo Buffer to store information about the line if the specified
1082 coordinates are located in the formatted text.
1083 @return ETrue if aXyPos is a formatted position, otherwise EFalse. */
1084 EXPORT_C TBool CTextLayout::FindXyPos(const TPoint& aXyPos,TTmPosInfo2& aPosInfo,TTmLineInfo* aLineInfo) const
1086 TTagmaForwarder forwarder(*this);
1087 TTmLineInfo line_info;
1088 TBool result = forwarder.FindXyPos(aXyPos,aPosInfo,line_info);
1089 if (aLineInfo && result)
1090 *aLineInfo = line_info;
1094 /** Returns the x-y coordinates of the document position aDocPos in aPos. The
1095 return value is ETrue if the position is formatted, or EFalse if it is not, in
1096 which case aPos is undefined.
1098 Deprecated - use the more powerful FindDocPos() instead
1100 @param aDocPos The document position.
1101 @param aPos On return, contains the x-y coordinates of aDocPos.
1102 @param aFlags Two possible values: 0 is the default, and performs the task at
1103 full accuracy, and CLayoutData::EFWholeLinesOnly, which examines lines only and
1104 sets aXyPos.iY only, and cannot leave.
1105 @return ETrue if the document position is formatted, EFalse if not. */
1106 EXPORT_C TBool CTextLayout::DocPosToXyPosL(TInt aDocPos,TPoint& aXyPos,TUint /*aFlags*/) const
1108 TTmDocPos doc_pos(aDocPos, ETrue);
1109 TTmPosInfo2 pos_info;
1110 TBool result = FindDocPos(doc_pos,pos_info);
1111 aXyPos = pos_info.iEdge;
1115 /** Finds the x-y position of the document position aDocPos.
1117 If ETrue is returned, places information about the document position in aPosInfo
1118 and information about the line containing the document position in aLineInfo if
1121 @param aDocPos Contains the document position to check.
1122 @param aPosInfo On return, stores information about the document position if
1123 the position is formatted.
1124 @param aLineInfo Buffer to store the line information if the document position
1126 @return ETrue if aDocPos is in the formatted text, otherwise EFalse. */
1127 EXPORT_C TBool CTextLayout::FindDocPos(const TTmDocPosSpec& aDocPos,TTmPosInfo2& aPosInfo,TTmLineInfo* aLineInfo) const
1129 TTagmaForwarder forwarder(*this);
1130 TTmLineInfo line_info;
1131 TBool result = forwarder.FindDocPos(aDocPos,aPosInfo,line_info);
1132 if (aLineInfo && result)
1133 *aLineInfo = line_info;
1137 /** Finds the next cursor position to aDocPos in the visually ordered line.
1139 @param aDocPos Contains the document position to check.
1140 @param aPosInfo On return, stores information about the document position of
1141 the next cursor position, if ETrue is returned.
1142 @param aToLeft ETrue if the position to the left is to be found, or EFalse if
1143 the position to the right is to be found.
1144 @return EFalse if there is no formatting, or the position is at the end of the
1145 line already. ETrue otherwise. */
1146 EXPORT_C TBool CTextLayout::GetNextVisualCursorPos(
1147 const TTmDocPosSpec& aDocPos, TTmPosInfo2& aPosInfo, TBool aToLeft) const
1149 TTagmaForwarder forwarder(*this);
1150 return forwarder.GetNextVisualCursorPos(aDocPos, aPosInfo, aToLeft);
1153 /** Gets a rectangle enclosing two formatted document positions on the same
1154 line. If the second position is less than the first, or on a different line, it
1155 is taken to indicate the end of the line. This function panics if either
1156 position is unformatted.
1160 CTextLayout must have been set with a valid wrap width and band height before
1161 calling this function, otherwise no formatting will take place and the function
1162 will panic. Wrap width and band height values must be > 0 to be valid.
1164 @param aDocPos1 The first document position on the line.
1165 @param aDocPos2 The second document position on the line.
1166 @return The minimal rectangle, which bounds both positions.
1168 @see SetWrapWidth */
1169 EXPORT_C TRect CTextLayout::GetLineRectL(TInt aDocPos1,TInt aDocPos2) const
1175 if (iText->LayoutHeight() == 0)
1176 return TRect(0,0,0,0);
1178 if (!PosIsFormatted(aDocPos1))
1180 OstTrace0( TRACE_FATAL, CTEXTLAYOUT_GETLINERECTL, "ECharacterNotFormatted" );
1182 __ASSERT_ALWAYS(PosIsFormatted(aDocPos1),Panic(ECharacterNotFormatted));
1183 if (!PosIsFormatted(aDocPos2))
1185 OstTrace0( TRACE_DUMP, DUP1_CTEXTLAYOUT_GETLINERECTL, "ECharacterNotFormatted" );
1187 __ASSERT_DEBUG(PosIsFormatted(aDocPos2),Panic(ECharacterNotFormatted));
1189 TTmDocPosSpec docSpec(aDocPos1, TTmDocPosSpec::ELeading);
1190 TTmPosInfo2 pos_info;
1192 // Finding the leading edge of aDocPos1
1193 FindDocPos(docSpec,pos_info);
1194 point = pos_info.iEdge;
1195 xCoords[0] = point.iX;
1197 // Getthe Line rectangle
1198 GetLineRect(point.iY,rect);
1200 if (rect.iTl.iY > point.iY || rect.iBr.iY < point.iY)
1202 OstTrace0( TRACE_DUMP, DUP2_CTEXTLAYOUT_GETLINERECTL, "EPixelNotInFormattedLine" );
1204 __ASSERT_DEBUG(rect.iTl.iY <= point.iY && rect.iBr.iY >= point.iY,Panic(EPixelNotInFormattedLine));
1206 // Finding the leading edge of aDocPos2
1207 docSpec.iPos = aDocPos2;
1208 TBool isformatted = FindDocPos(docSpec, pos_info);
1209 point = pos_info.iEdge;
1211 // Checks if the aDocPos2 is contained in the same line of the aDocPos1
1212 // Can't use TRect::Contains() here, because TRect::Contains() considers a point located on the right
1213 // hand side or bottom as outside the rectangle, which will has problem when work with RTL text that
1214 // is at the right hand end of a line.
1215 TBool isContained = (point.iX>=rect.iTl.iX && point.iX<=rect.iBr.iX
1216 && point.iY>=rect.iTl.iY && point.iY<=rect.iBr.iY);
1218 RTmParFormat parFormat;
1219 iSource->GetParagraphFormatL(aDocPos1, parFormat);
1221 // The special cases (as indicated in the description):
1222 // When the aDocPos2 is less than the aDocPos1, or not formatted, or on a different line from which the
1223 // aDocPos1 is in, then the function will return the rectangle starting from docPos1's leading edge and
1224 // ending at the end of the line (which is determined by paragraph directionality).
1225 if (aDocPos2 < aDocPos1 || !isformatted || !isContained)
1227 if (parFormat.RightToLeft())
1228 rect.iBr.iX = xCoords[0];
1230 rect.iTl.iX = xCoords[0];
1236 xCoords[1] = point.iX;
1238 // Finding the Trailing edge of (aDocPos1 + 1)
1239 docSpec.iType = TTmDocPosSpec::ETrailing;
1240 docSpec.iPos = aDocPos1 + 1;
1241 FindDocPos(docSpec, pos_info);
1242 xCoords[2] = pos_info.iEdge.iX;
1244 // Finding the Trailing edge of (aDocPos2 + 1)
1245 docSpec.iPos = aDocPos2 + 1;
1246 FindDocPos(docSpec, pos_info);
1247 xCoords[3] = pos_info.iEdge.iX;
1249 rect.iBr.iX = xCoords[0];
1250 rect.iTl.iX = xCoords[0];
1252 // The returned rectangle is generated by (when is not a special case)
1253 // 1) Find the Line rectangle
1255 // - leading edge of docPos1
1256 // - leading edge of docPos2
1257 // - trailing edge of docPos1+1
1258 // - trailing edge of docPos2+1
1259 // 3) Cut the line rectangle at the smallest edge and the largest edge among
1260 // the four edges found in step 2.
1261 for (TInt i = 1; i<4; i++ )
1263 if (rect.iBr.iX < xCoords[i])
1264 rect.iBr.iX = xCoords[i];
1265 if (rect.iTl.iX > xCoords[i])
1266 rect.iTl.iX = xCoords[i];
1273 /** Gets the bounding rectangle of the picture, if any, located at the document
1274 position or coordinates specified, and returns it in aPictureRect.
1276 If aCanScaleOrCrop is non-null, sets aCanScaleOrCrop to indicate
1277 whether the picture can be scaled or cropped.
1278 Returns ETrue if the operation was successful. Returns EFalse otherwise;
1279 that is, if there is no picture at the position, or if the position is unformatted.
1281 @param aDocPos The document position of interest.
1282 @param aXyPos The layout coordinates of interest.
1283 @param aPictureRect On return, contains the rectangle which encloses the
1284 picture located at the position specified.
1285 @param aCanScaleOrCrop If non-NULL and the function returns ETrue, on return,
1286 indicates whether the picture can be scaled or cropped. By default, NULL.
1287 @return ETrue if the operation was successful, (i.e. there is a
1288 picture character at the position, it has been loaded into
1289 memory, and the position is formatted). EFalse if any of these
1290 conditions are not met. */
1291 EXPORT_C TBool CTextLayout::PictureRectangleL(TInt aDocPos,TRect& aPictureRect,TBool* aCanScaleOrCrop) const
1293 if (aDocPos < iText->StartChar() || aDocPos >= iText->EndChar() - 1)
1296 aPictureRect.SetRect(0,0,0,0);
1298 if (iSource->GetPictureSizeInTwipsL(aDocPos,size) != KErrNone)
1302 TTmDocPos pos(aDocPos, ETrue);
1303 TTmPosInfo2 pos_info;
1306 if (!iText->FindDocPos(pos,pos_info,info,subscript))
1309 MGraphicsDeviceMap& device = iSource->InterpretDevice();
1310 size.iWidth = device.HorizontalTwipsToPixels(size.iWidth);
1311 size.iHeight = device.VerticalTwipsToPixels(size.iHeight);
1312 rect.iBr.iY = pos_info.iEdge.iY - iBandTop + subscript;
1313 rect.iTl.iY = rect.iBr.iY - size.iHeight;
1314 if (pos_info.iRightToLeft)
1316 rect.iBr.iX = pos_info.iEdge.iX;
1317 rect.iTl.iX = rect.iBr.iX - size.iWidth;
1321 rect.iTl.iX = pos_info.iEdge.iX;
1322 rect.iBr.iX = rect.iTl.iX + size.iWidth;
1324 /* rect.iTl = pos_info.iEdge;
1325 rect.Move(0,-iBandTop);
1326 rect.iTl.iY -= size.iHeight;
1327 rect.iBr = rect.iTl + size;*/
1328 CPicture* picture = iSource->PictureL(aDocPos);
1332 if (aCanScaleOrCrop)
1333 *aCanScaleOrCrop = picture->Capability().iScalingType != TPictureCapability::ENotScaleable ||
1334 picture->Capability().iIsCroppable;
1335 aPictureRect = rect;
1339 /** Finds if there is a picture at the position under the point aXyPos.
1340 If there is, returns the document position of it, sets the rectangle
1341 occupied in aPictureRect, and whether the picture allows scaling
1342 in aCanScaleOrCrop, if non-null. Note that aXyPos may be outside
1344 @return The document position of the picture found, or KErrNotFound if there
1346 TInt CTextLayout::PictureRectangleAndPosL(const TPoint& aXyPos, TRect& aPictureRect,
1347 TBool* aCanScaleOrCrop) const
1349 TTmPosInfo2 posInfo;
1350 if (!FindXyPos(aXyPos, posInfo))
1351 return KErrNotFound;
1352 TInt doc_pos = posInfo.iDocPos.iPos - (posInfo.iDocPos.iLeadingEdge? 0 : 1);
1353 if (PictureRectangleL(doc_pos, aPictureRect, aCanScaleOrCrop))
1355 return KErrNotFound;
1358 /** Gets the bounding rectangle of the picture (if any) at aXyPos and puts it
1359 in aPictureRect. If aCanScaleOrCrop is non-null sets *aCanScaleOrCrop to
1360 indicate whether the picture can be scaled or cropped. Note that aXyPos
1361 may be outside aPictureRect on a successful return, if the picture does
1362 not occupy the whole of the section of the line it is in.
1363 @return ETrue if the position is formatted and there is a picture there. */
1364 EXPORT_C TBool CTextLayout::PictureRectangleL(const TPoint& aXyPos,
1365 TRect& aPictureRect, TBool* aCanScaleOrCrop) const
1367 return 0 <= PictureRectangleAndPosL(aXyPos, aPictureRect, aCanScaleOrCrop)?
1371 /** Gets the first document position in a line that starts at or below the top
1372 of the visible area. If there is no such line, returns the position after the
1373 last formatted character.
1375 @return The document position of the first character in a line within the
1377 EXPORT_C TInt CTextLayout::FirstDocPosFullyInBand() const
1380 if (!iText->YPosToLine(iBandTop,info))
1381 return iText->EndChar();
1382 if (info.iOuterRect.iTl.iY < iBandTop)
1391 /** This interface is deprecated, and is made available in version 7.0s solely
1392 to provide binary compatibility with Symbian OS v6.1. Developers are strongly
1393 advised not to make use of this API in new applications. In particular, use the
1394 other overload of this function if you need to distinguish between leading and
1395 trailing edge positions.
1397 Do not use if a CTextView object owns this CTextLayout object.
1399 @param aDocPos A valid document position.
1400 @param aYPos The y coordinate at which to display the character at aDocPos. On
1401 return, contains the actual vertical position of the specified part of the
1403 @param aYPosQualifier Controls which part of the line is set to appear at
1405 @param aDiscardFormat If ETrue (EFViewDiscardAllFormat), the text is reformatted
1406 to include aDocPos, otherwise text is formatted only as necessary when bringing
1407 new lines into the visible area.
1408 @return The number of pixels the text was scrolled, may be positive or
1409 negative. A value of CTextLayout::EFScrollRedrawWholeScreen indicates that the
1410 entire visible area, at least, was scrolled, and so there is no point in
1411 blitting text; a full redraw is needed. */
1412 EXPORT_C TInt CTextLayout::SetViewL(TInt aDocPos,TInt& aYPos,TViewYPosQualifier aYPosQualifier,TDiscard aDiscardFormat)
1414 TTmDocPos pos(aDocPos, ETrue);
1415 return SetViewL(pos,aYPos,aYPosQualifier,aDiscardFormat);
1418 /** Changes the top of the visible area so that the line containing aDocPos is
1419 vertically positioned at aYPos. Which part of the line is set to appear at
1420 aYPos (top, baseline, or bottom) is controlled by the TViewYPosQualifier
1421 argument, which also specifies whether the visible area is to be filled and
1422 whether the line should be made fully visible if possible.
1424 Do not use if a CTextView object owns this CTextLayout object.
1426 @param aDocPos A valid document position.
1427 @param aYPos The y coordinate at which to display the character at aDocPos. On
1428 return, contains the actual vertical position of the specified part of the
1430 @param aYPosQualifier Controls which part of the line is set to appear at
1432 @param aDiscardFormat If ETrue (EFViewDiscardAllFormat), the text is reformatted
1433 to include aDocPos, otherwise text is formatted only as necessary when bringing
1434 new lines into the visible area.
1435 @return The number of pixels the text was scrolled, may be positive or
1436 negative. A value of CTextLayout::EFScrollRedrawWholeScreen indicates that the
1437 entire visible area, at least, was scrolled, and so there is no point in
1438 blitting text; a full redraw is needed. */
1439 EXPORT_C TInt CTextLayout::SetViewL(const TTmDocPos& aDocPos, TInt& aYPos,
1440 TViewYPosQualifier aYPosQualifier, TDiscard aDiscardFormat)
1442 if (aDocPos.iPos < 0 || aDocPos.iPos > iSource->DocumentLength())
1443 Panic(EInvalidDocPos);
1446 If the format is to be discarded, or no text has yet been formatted, or if the document position
1447 to be viewed is not formatted, format the band.
1450 TBool all_formatted = FALSE;
1451 TBool pos_is_formatted = iText->DocPosToLine(aDocPos,info);
1452 if (!pos_is_formatted ||
1453 aDiscardFormat == EFViewDiscardAllFormat ||
1454 (iText->StartChar() == iText->EndChar() && iSource->DocumentLength() > 0))
1456 FormatBandL(aDocPos.iPos,aDocPos.iPos);
1457 all_formatted = TRUE;
1458 pos_is_formatted = iText->DocPosToLine(aDocPos,info);
1461 // Find out where the top of the line is.
1462 if (!pos_is_formatted)
1464 int line_top_y = info.iOuterRect.iTl.iY - iBandTop;
1466 // Determine the desired position of the top of the line.
1468 if (aYPosQualifier.iHotSpot == TViewYPosQualifier::EFViewBaseLine)
1469 offset = info.iBaseline - info.iOuterRect.iTl.iY;
1470 else if (aYPosQualifier.iHotSpot == TViewYPosQualifier::EFViewBottomOfLine)
1471 offset = info.iOuterRect.iBr.iY - info.iOuterRect.iTl.iY;
1472 int desired_line_top_y = aYPos - offset;
1474 // Adjust aYPos so that the line is fully visible if desired.
1475 if (aYPosQualifier.iFullyVisible == TViewYPosQualifier::EFViewForceLineFullyVisible)
1477 TInt screenHeight = VisibleHeightInPixels();
1478 TInt lineHeight = info.iOuterRect.Height();
1479 TInt lineAscent = info.iBaseline - info.iOuterRect.iTl.iY;
1480 // If the top of the line is off the top of the screen, and the
1481 // baseline and the top can both fit, make the top of the line flush
1482 // with the top of the screen.
1483 if (lineAscent <= screenHeight
1484 && desired_line_top_y < 0)
1485 desired_line_top_y = 0;
1486 // If the whole line can fit and the bottom if off the bottom of the
1487 // screen, make the bottom flush with the bottom of the screen.
1488 if (lineHeight <= screenHeight
1489 && screenHeight < desired_line_top_y + lineHeight)
1490 desired_line_top_y = screenHeight - lineHeight;
1491 // If the ascent will not fit, or the baseline is off the bottom of
1492 // the screen, move the baseline flush with the bottom of the screen
1493 if (screenHeight < lineAscent
1494 || screenHeight < desired_line_top_y + lineAscent)
1495 desired_line_top_y = screenHeight - lineAscent;
1498 // Scroll the document position to the desired vertical coordinate and update aYPos.
1499 TInt dy = desired_line_top_y - line_top_y;
1502 dy = ScrollL(dy,aYPosQualifier.iFillScreen ? EFDisallowScrollingBlankSpace : EFAllowScrollingBlankSpace);
1504 aYPos = line_top_y + offset;
1506 // Ensure that aYPos is in the line.
1507 if (aYPosQualifier.iHotSpot == TViewYPosQualifier::EFViewBottomOfLine)
1510 return all_formatted ? EFScrollRedrawWholeScreen : dy;
1513 /** Formats enough text to fill the visible band.
1515 Note: Do not use if a CTextView object owns this CTextLayout object. */
1516 EXPORT_C void CTextLayout::FormatBandL()
1522 Format enough text to fill the visible band and include both aStartDocPos and
1523 aEndDocPos. Start at the start of the document if formatting everything, or at
1524 the start of the paragraph containing aStartDocPos if formatting the visible
1527 void CTextLayout::FormatBandL(TInt aStartDocPos,TInt aEndDocPos)
1529 TTmFormatParam param;
1530 InitFormatParam(param);
1531 if (iBandHeight != CLayoutData::EFHeightForFormattingAllText)
1532 param.iStartChar = iSource->ParagraphStart(aStartDocPos);
1533 if (param.iWrapWidth < 1 || param.iMaxHeight < 1)
1535 // Do just a little formatting if the values are illegal.
1536 // This is to prevent the AddParL running with no
1537 // height limit, taking up huge amounts of time, and
1538 // having to return with 0 lines formatted, which
1539 // confuses CEikEdwin.
1540 param.iMaxHeight = 1;
1541 param.iWrapWidth = 1;
1542 iText->SetTextL(*iSource,param);
1545 iText->SetTextL(*iSource,param);
1546 param.iMaxHeight = KMaxTInt;
1548 if(IsFormattingBand() && (iText->EndChar() <= aEndDocPos && iText->EndChar() < iSource->DocumentLength()))
1550 param.iEndChar = Min(aEndDocPos+1,iSource->DocumentLength());
1551 iText->ExtendFormattingDownwardsL(param);
1555 while (iText->EndChar() <= aEndDocPos && iText->EndChar() < iSource->DocumentLength())
1558 AddFormattingAtEndL(param, h, p);
1563 if (iBandHeight != CLayoutData::EFHeightForFormattingAllText)
1565 int visible_height = VisibleHeightInPixels();
1566 while (iText->LayoutHeight() < visible_height)
1569 if (!iText->AddParL(param,TRUE,h,p))
1576 /** Makes sure the line that aYPos is in (if it exists) is covered by the
1578 @param aYPos Y pixel position in window-relative co-ordinates.
1581 EXPORT_C void CTextLayout::ExtendFormattingToCoverYL(TInt aYPos)
1583 TTmFormatParam param;
1584 InitFormatParam(param);
1585 param.iStartChar = iText->StartChar() - 1;
1586 param.iEndChar = iText->EndChar();
1587 param.iMaxHeight = KMaxTInt;
1588 TInt heightIncrease;
1590 while (iBandTop < -aYPos && iText->AddParL(param, ETrue, heightIncrease, p))
1592 iBandTop += heightIncrease;
1593 param.iStartChar = iText->StartChar() - 1;
1595 TInt heightRemaining = iBandTop + aYPos - iText->LayoutHeight() + 1;
1596 if(heightRemaining > 0)
1598 param.iStartChar = iText->EndChar();
1599 param.iEndChar = KMaxTInt;
1600 param.iMaxHeight = heightRemaining;
1601 iText->ExtendFormattingDownwardsL(param);
1605 /** Allows you to increase the formatted text range by specifying a point in the text you
1606 want to increase the range to. Makes sure the line that aDocPos is in (if it exists) is covered by the
1608 @param aDocPos Position in the text you wish to extend the formatting to. e.g. passing in 0 will
1609 increase the formatting range to the very first character entered in the document.
1610 @pre aDocPos is in the range 0...DocumentLength
1611 @post aDocPos has been formatted
1613 EXPORT_C void CTextLayout::ExtendFormattingToCoverPosL(TInt aDocPos)
1615 if (0 > aDocPos || aDocPos > DocumentLength())
1617 OstTrace0( TRACE_DUMP, CTEXTLAYOUT_EXTENDFORMATTINGTOCOVERPOSL, "EInvalidDocPos" );
1619 __ASSERT_DEBUG(0 <= aDocPos && aDocPos <= DocumentLength(),
1620 Panic(EInvalidDocPos));
1621 TTmFormatParam param;
1622 InitFormatParam(param);
1623 param.iStartChar = iText->StartChar();
1624 param.iEndChar = iText->EndChar();
1625 param.iMaxHeight = KMaxTInt;
1626 TInt heightIncrease;
1629 if(pos > 0) // Avoid going into infinite loop.
1633 while ((pos < param.iStartChar) && (iText->AddParL(param, ETrue, heightIncrease, p)))
1635 iBandTop += heightIncrease;
1636 param.iStartChar = iText->StartChar();
1638 param.iEndChar = aDocPos + 1;
1639 if(iText->EndChar() < param.iEndChar)
1641 iText->ExtendFormattingDownwardsL(param);
1643 if ((aDocPos < iText->StartChar()) || (aDocPos > iText->EndChar()))
1645 OstTrace0( TRACE_DUMP, DUP1_CTEXTLAYOUT_EXTENDFORMATTINGTOCOVERPOSL, "ECharacterNotFormatted" );
1647 __ASSERT_DEBUG((aDocPos >= iText->StartChar()) && (aDocPos <= iText->EndChar()),
1648 Panic(ECharacterNotFormatted));
1652 /** Sets the formatted text to begin at the start of the paragraph including
1653 aStartPos and end at aEndPos. Moves the line containing aStartDocPos to the top
1654 of the visible area.
1658 This function is not generally useful; it exists for the convenience of the
1661 Do not use if a CTextView object owns this CTextLayout object.
1663 @param aStartDocPos A document position within the paragraph from which to
1665 @param aEndDocPos Document position at which to end formatting. */
1666 EXPORT_C void CTextLayout::FormatCharRangeL(TInt aStartDocPos,TInt aEndDocPos)
1668 FormatCharRangeL(aStartDocPos,aEndDocPos,0);
1671 void CTextLayout::FormatCharRangeL(TInt aStartDocPos,TInt aEndDocPos,TInt aPixelOffset)
1673 if (aStartDocPos < 0 && aStartDocPos > DocumentLength())
1675 OstTrace0( TRACE_DUMP, CTEXTLAYOUT_FORMATCHARRANGEL, "EInvalidDocPos" );
1677 __ASSERT_DEBUG(aStartDocPos >= 0 && aStartDocPos <= DocumentLength(),Panic(EInvalidDocPos));
1678 if (aEndDocPos < 0 || aEndDocPos > DocumentLength())
1680 OstTrace0( TRACE_DUMP, DUP1_CTEXTLAYOUT_FORMATCHARRANGEL, "EInvalidDocPos" );
1682 __ASSERT_DEBUG(aEndDocPos >= 0 && aEndDocPos <= DocumentLength(),Panic(EInvalidDocPos));
1683 if (aStartDocPos > aEndDocPos)
1685 OstTrace0( TRACE_DUMP, DUP2_CTEXTLAYOUT_FORMATCHARRANGEL, "ENoCharRangeToFormat" );
1687 __ASSERT_DEBUG(aStartDocPos <= aEndDocPos,Panic(ENoCharRangeToFormat));
1689 TTmFormatParam param;
1690 InitFormatParam(param);
1691 param.iStartChar = iSource->ParagraphStart(aStartDocPos);
1692 param.iEndChar = aEndDocPos;
1693 param.iMaxHeight = KMaxTInt;
1694 iText->SetTextL(*iSource,param);
1696 TTmDocPos pos(aStartDocPos, ETrue);
1697 if (iText->DocPosToLine(pos,info))
1698 iBandTop = info.iOuterRect.iTl.iY - aPixelOffset;
1700 iBandTop = 0; //+ raise an exception?
1703 /** A special function to support background formatting by the higher level
1704 CTextView class. It formats the next pending line. The return value is ETrue if
1705 there is more formatting to do. On entry, aBotPixel contains the y coordinate
1706 of the bottom of the formatted text; this is updated by the function.
1710 Not generally useful.
1712 Do not use if a CTextView object owns this CTextLayout object.
1714 @param aBotPixel On entry, contains the y coordinate of the bottom of the
1715 formatted text; this is updated by the function.
1716 @return ETrue if there is more formatting to do. EFalse if not. */
1717 EXPORT_C TBool CTextLayout::FormatNextLineL(TInt& aBottomPixel)
1719 if (iUnformattedStart < KMaxTInt)
1721 TTmFormatParamBase param;
1722 InitFormatParam(param);
1723 param.iMaxHeight = KMaxTInt;
1724 TTmReformatParam reformat_param;
1725 reformat_param.iStartChar = iUnformattedStart;
1726 reformat_param.iMaxExtraLines = KMaxExtraLines;
1727 reformat_param.iParInvalid = iParInvalid;
1728 TTmReformatResult result;
1729 iText->FormatL(param,reformat_param,result);
1731 // If there is no formatting to do, indicate that formatting is complete to the end of the paragraph
1732 if (result.iUnformattedStart == KMaxTInt)
1735 TTmDocPos pos(iUnformattedStart, ETrue);
1736 TBool isFormatted = iText->DocPosToLine(pos,info);
1739 OstTrace0( TRACE_DUMP, CTEXTLAYOUT_FORMATNEXTLINEL, "EPosNotFormatted" );
1741 __ASSERT_DEBUG(isFormatted, Panic(EPosNotFormatted));
1742 isFormatted = iText->ParNumberToLine(info.iParNumber,KMaxTInt,info);
1745 OstTrace0( TRACE_DUMP, DUP1_CTEXTLAYOUT_FORMATNEXTLINEL, "EPosNotFormatted" );
1747 __ASSERT_DEBUG(isFormatted, Panic(EPosNotFormatted));
1748 aBottomPixel = info.iOuterRect.iBr.iY - iBandTop;
1751 // Indicate that formatting is complete up to the lower edge of the current line.
1753 aBottomPixel = result.iRedrawRect.iBr.iY - iBandTop;
1754 iUnformattedStart = result.iUnformattedStart;
1756 return iUnformattedStart < KMaxTInt;
1759 /** Controls the height of a single line, for use by the pagination system
1760 only. Using the format supplied in aParaFormat, determines the height of the
1761 line containing aDocPos and returns it in aHeight. Changes aDocPos to the end
1762 of the line and returns ETrue if that position is not the end of the paragraph.
1766 Not generally useful; it exists for use by the pagination system only.
1768 Do not use if a CTextView object owns this CTextLayout object.
1770 @param aParaFormat Contains paragraph formatting.
1771 @param aDocPos A document position. On return, contains the document position
1772 of the end of the line.
1773 @param aHeight On return, contains the height of the formatted line containing
1775 @param aPageBreak On return, ETrue if the last character on the line is a page
1776 break. EFalse if not.
1777 @return ETrue if the line is not the last line in the paragraph. EFalse if it is
1779 EXPORT_C TBool CTextLayout::FormatLineL(CParaFormat* /*aParaFormat*/,TInt& aDocPos,
1780 TInt& aHeight,TBool& aPageBreak)
1782 // If the line is not formatted, replace the formatted text with the single paragraph containing the line.
1783 if (aDocPos < iText->StartChar() || aDocPos >= iText->EndChar())
1785 TTmFormatParam param;
1786 InitFormatParam(param);
1787 param.iStartChar = iSource->ParagraphStart(aDocPos);
1788 param.iEndChar = iSource->ParagraphEnd(aDocPos);
1789 param.iMaxHeight = KMaxTInt;
1790 iText->SetTextL(*iSource,param);
1793 TTmDocPos pos(aDocPos, ETrue);
1794 if (!iText->DocPosToLine(pos,info))
1795 User::Leave(KErrGeneral);
1796 aHeight = info.iOuterRect.Height();
1797 aDocPos = info.iEnd;
1799 TTmCharFormat format;
1800 iSource->GetText(info.iEnd - 1,text,format);
1801 aPageBreak = text[0] == CEditableText::EPageBreak;
1803 return !(info.iFlags & TTmLineInfo::EParEnd);
1806 /** Scrolls the text up or down by aNumParas paragraphs, disallowing blank
1807 space at the bottom of the visible area if aScrollBlankSpace is
1808 CTextLayout::EFDisallowScrollingBlankSpace.
1810 Do not use if a CTextView object owns this CTextLayout object.
1812 @param aNumParas The number of paragraphs to scroll; may be a positive or
1813 negative value. On return, contains the number of paragraphs not scrolled; that
1814 is the difference between the requested number and the number of paragraphs
1816 @param aScrollBlankSpace Only relevant when scrolling downwards.
1817 CTextLayout::EFAllowScrollingBlankSpace allows blank space to scroll into the
1818 visible area. CTextLayout::EFDisallowScrollingBlankSpace prevents blank space
1819 from scrolling into the visible area.
1820 @pre aPars must not scroll the display beyond the formatted range. If aPars
1821 scrolls beyond the formatted range, this method will leave with the error code
1822 CTextLayout::EPosNotFormatted
1823 @return The number of pixels actually scrolled. */
1824 EXPORT_C TInt CTextLayout::ScrollParagraphsL(TInt& aPars,TAllowDisallow aScrollBlankSpace)
1826 TTmFormatParam param;
1827 InitFormatParam(param);
1828 param.iMaxHeight = KMaxTInt;
1830 int height_increase = 0;
1831 int paragraphs_increase = 0;
1833 int desired_par = 0;
1834 int pixels_to_scroll = 0;
1838 if (iText->YPosToLine(iBandTop,info))
1839 cur_par = info.iParNumber;
1841 User::Leave(EPosNotFormatted);
1842 if (info.iParTop < iBandTop)
1844 desired_par = cur_par - aPars;
1845 while (desired_par < 0 && iText->AddParL(param,TRUE,height_increase,paragraphs_increase))
1847 iBandTop += height_increase;
1848 desired_par += paragraphs_increase;
1850 aPars = -desired_par;
1851 if (desired_par < 0)
1853 if (!iText->ParNumberToLine(desired_par,0,info))
1854 User::Leave(EPosNotFormatted);
1855 pixels_to_scroll = iBandTop - info.iOuterRect.iTl.iY;
1859 int band_bottom = iBandTop + VisibleHeightInPixels();
1861 // Extend formatting until the visible height is filled.
1862 param.iEndChar = KMaxTInt;
1863 param.iMaxHeight = band_bottom - iText->LayoutHeight();
1864 if(param.iMaxHeight > 0)
1866 iText->ExtendFormattingDownwardsL(param);
1869 if (iText->YPosToLine(band_bottom - 1,info))
1870 cur_par = info.iParNumber;
1872 User::Leave(EPosNotFormatted);
1873 if (!((info.iFlags & TTmLineInfo::EParEnd) && info.iOuterRect.iBr.iY == band_bottom))
1875 desired_par = cur_par - aPars;
1876 int last_par = iText->Paragraphs() - 1;
1877 while (desired_par > last_par && iText->AddParL(param, EFalse, height_increase,paragraphs_increase))
1878 last_par += paragraphs_increase;
1879 aPars = last_par - desired_par;
1880 if (desired_par > last_par)
1881 desired_par = last_par;
1882 if (!iText->ParNumberToLine(desired_par,KMaxTInt,info))
1883 iText->AddParL(param, EFalse, height_increase, paragraphs_increase);
1884 if (!iText->ParNumberToLine(desired_par,KMaxTInt,info))
1885 User::Leave(EPosNotFormatted);
1886 pixels_to_scroll = band_bottom - info.iOuterRect.iBr.iY;
1889 return ScrollL(pixels_to_scroll,aScrollBlankSpace);
1892 /** Scrolls the text up or down by aNumLines lines, disallowing blank space at
1893 the bottom of the visible area if aScrollBlankSpace is
1894 CTextLayout::EFDisallowScrollingBlankSpace.
1896 Do not use if a CTextView object owns this CTextLayout object.
1898 @param aNumLines The number of lines to scroll; may be a positive or negative
1899 value. On return, contains the number of lines not scrolled; that is, the
1900 requested number, minus the number actually scrolled.
1901 @param aScrollBlankSpace Only relevant when scrolling downwards.
1902 CTextLayout::EFAllowScrollingBlankSpace allows blank space to scroll into the
1903 visible area. CTextLayout::EFDisallowScrollingBlankSpace prevents blank space
1904 from scrolling into the visible area.
1905 @pre aLines must not scroll the display beyond the formatted range. If aLines
1906 scrolls beyond the formatted range, this method will leave with the error code
1907 CTextLayout::EPosNotFormatted
1908 @return The number of pixels actually scrolled. */
1909 EXPORT_C TInt CTextLayout::ScrollLinesL(TInt& aLines,TAllowDisallow aScrollBlankSpace)
1911 TTmFormatParam param;
1912 InitFormatParam(param);
1913 param.iMaxHeight = KMaxTInt;
1915 int height_increase = 0;
1916 int paragraphs_increase = 0;
1917 int lines_scrolled = aLines;
1918 int visible_height = VisibleHeightInPixels();
1919 if (aLines > 0) // bring aLines lines into view at the top of the display
1921 int desired_top_line_number = 0;
1924 // Find the line number of the first visible line.
1925 TBool partial_line = FALSE;
1926 int top_line_number = 0;
1927 if (iBandTop >= iText->LayoutHeight())
1928 top_line_number = iText->Lines();
1931 if (iText->YPosToLine(iBandTop,info))
1932 top_line_number = info.iLineNumber;
1935 OstTrace0( TRACE_DUMP, DUP1_CTEXTLAYOUT_SCROLLLINESL, "EPosNotFormatted" );
1936 User::Leave(EPosNotFormatted);
1938 partial_line = iBandTop > info.iOuterRect.iTl.iY;
1941 // Find the line number of the desired first visible line.
1942 // Defect fix for INC015850. Changed IF so that if the currently
1943 // visible top line is as tall or taller (due to a large font or picture)
1944 // than the visible height of the view our desired top line remains
1945 // the next one above so that a scroll takes place.
1946 desired_top_line_number = top_line_number - aLines;
1947 if (partial_line && (info.iOuterRect.iBr.iY-info.iOuterRect.iTl.iY < visible_height))
1948 desired_top_line_number++;
1950 // If the desired first visible line number is negative, more lines need to be formatted.
1951 if (desired_top_line_number >= 0)
1953 if (!iText->AddParL(param,TRUE,height_increase,paragraphs_increase))
1955 iBandTop += height_increase;
1958 if (desired_top_line_number < 0)
1960 lines_scrolled += desired_top_line_number;
1961 desired_top_line_number = 0;
1963 aLines -= lines_scrolled;
1966 if (!iText->LineNumberToLine(desired_top_line_number,info))
1968 OstTrace0( TRACE_DUMP, CTEXTLAYOUT_SCROLLLINESL, "EPosNotFormatted" );
1969 User::Leave(EPosNotFormatted);
1971 // if the line to be scrolled to is taller than the screen, we want
1972 // to make sure that the baseline is not scrolled off the screen.
1973 if (visible_height < info.iBaseline - info.iOuterRect.iTl.iY)
1974 return ScrollL(iBandTop + visible_height - info.iBaseline, aScrollBlankSpace);
1975 return ScrollL(iBandTop - info.iOuterRect.iTl.iY,aScrollBlankSpace);
1980 else if (aLines < 0) // bring aLines lines into view at the bottom of the display
1982 if (iScrollFlags & EFScrollOnlyToTopsOfLines)
1984 // If we are restricting scroll to the tops of lines, then lines at
1985 // bottom are irrelevant, so all we do is lose the top line.
1986 if (!iText->YPosToLine(iBandTop, info))
1988 OstTrace0( TRACE_DUMP, DUP2_CTEXTLAYOUT_SCROLLLINESL, "EPosNotFormatted" );
1989 User::Leave(EPosNotFormatted);
1991 return ScrollL(-info.iOuterRect.Height(), aScrollBlankSpace);
1994 int desired_bottom_line_number = 0;
1995 int band_bottom = iBandTop + visible_height;
1996 int last_formatted_line = iText->Lines() - 1;
1998 // Extend formatting until the visible height is filled.
1999 param.iEndChar = KMaxTInt;
2000 param.iMaxHeight = band_bottom - iText->LayoutHeight();
2001 if(param.iMaxHeight > 0)
2003 iText->ExtendFormattingDownwardsL(param);
2007 // Find the line number of the last visible line.
2008 TBool partial_line = FALSE;
2009 int bottom_line_number = 0;
2010 if (iText->YPosToLine(band_bottom - 1,info))
2011 bottom_line_number = info.iLineNumber;
2014 OstTrace0( TRACE_DUMP, DUP3_CTEXTLAYOUT_SCROLLLINESL, "EPosNotFormatted" );
2015 User::Leave(EPosNotFormatted);
2017 partial_line = band_bottom < info.iOuterRect.iBr.iY;
2019 // Find the line number of the desired last visible line.
2020 desired_bottom_line_number = bottom_line_number - aLines;
2022 desired_bottom_line_number--;
2024 // If the desired last visible line number is greater than the last line, more lines need to be formatted.
2025 if (desired_bottom_line_number <= last_formatted_line)
2027 if (!AddFormattingAtEndL(param, height_increase,paragraphs_increase))
2029 last_formatted_line = iText->Lines() - 1;
2032 int shortfall = desired_bottom_line_number - last_formatted_line;
2035 lines_scrolled += shortfall;
2036 desired_bottom_line_number = last_formatted_line;
2038 aLines -= lines_scrolled;
2041 if (!iText->LineNumberToLine(desired_bottom_line_number,info))
2043 OstTrace0( TRACE_DUMP, DUP4_CTEXTLAYOUT_SCROLLLINESL, "EPosNotFormattedL" );
2044 User::Leave(EPosNotFormatted);
2046 return ScrollL(band_bottom - info.iOuterRect.iBr.iY,aScrollBlankSpace);
2055 /** Scrolls the text up or down by aPixels pixels, disallowing blank space at
2056 the bottom of the visible area if aScrollBlankSpace is
2057 CTextLayout::EFDisallowScrollingBlankSpace.
2059 The return value (not aPixels, as you would expect from ScrollParagraphsL() and
2060 ScrollLinesL()) contains the number of pixels not successfully scrolled, that
2061 is, the original value of aPixels, minus the number of pixels actually
2062 scrolled. On return, aPixels is set to the number of pixels actually scrolled.
2064 Do not use if a CTextView object owns this CTextLayout object.
2066 @param aPixels The number of pixels to scroll; may be a positive or negative
2067 value. On return, contains the number of pixels actually scrolled.
2068 @param aScrollBlankSpace Only relevant when scrolling downwards.
2069 CTextLayout::EFAllowScrollingBlankSpace allows blank space to scroll into the
2070 visible area. CTextLayout::EFDisallowScrollingBlankSpace prevents blank space
2071 from scrolling into the visible area.
2072 @return The difference between the requested number of pixels to scroll and the
2073 number of pixels actually scrolled. */
2074 EXPORT_C TInt CTextLayout::ChangeBandTopL(TInt& aPixels,TAllowDisallow aScrollBlankSpace)
2076 int desired_pixels = aPixels;
2077 aPixels = ScrollL(aPixels,aScrollBlankSpace);
2078 return desired_pixels - aPixels;
2083 /** Scrolls the text up or down by aPixels pixels, allowing blank space at
2084 top and bottom of the visible area, which means the scrolling can go beyond the
2085 top or bottom border.
2087 Do not use if a CTextView object owns this CTextLayout object.
2089 @param aPixels The number of pixels to scroll; may be a positive or negative
2090 value. The actual scrolled pixel number is always identical to aPixels*/
2091 EXPORT_C void CTextLayout::ChangeBandTopNoLimitBorderL(TInt aPixels)
2093 ScrollL(aPixels,EFAllowScrollingBlankSpace,ETrue,ETrue);
2098 * Finds a position (in pixels, from the top of the window) where the cursor
2099 * can be such that its line will be fully visible. If this is not possible,
2100 * then return one with its baseline visible. If this is not possible, we don't
2101 * care what the answer is.
2103 TInt CTextLayout::SuggestCursorPos(TInt aCurrentCursorPos) const
2105 int visible_height = VisibleHeightInPixels();
2107 if (iText->YPosToLine(iBandTop + aCurrentCursorPos, info))
2109 TBool currentLineHasBaselineVisible =
2110 (TBool)(iBandTop <= info.iBaseline
2111 && info.iBaseline < iBandTop + visible_height);
2112 TInt tryThisLine = -1;
2113 // find a good line to put the cursor on.
2114 if (info.iOuterRect.iTl.iY < iBandTop)
2117 tryThisLine = info.iLineNumber + 1;
2119 else if (iBandTop + visible_height < info.iOuterRect.iBr.iY)
2121 tryThisLine = info.iLineNumber - 1;
2123 if (0 <= tryThisLine && iText->LineNumberToLine(tryThisLine, info))
2125 if (iBandTop <= info.iOuterRect.iTl.iY
2126 && info.iOuterRect.iBr.iY < iBandTop + visible_height)
2127 // this line fully visible
2128 aCurrentCursorPos = info.iBaseline - iBandTop;
2129 else if (!currentLineHasBaselineVisible
2130 && iBandTop <= info.iBaseline
2131 && info.iBaseline < iBandTop + visible_height)
2132 // not fully visible, but its baseline is, and the original
2133 // line's baseline was not
2134 aCurrentCursorPos = info.iBaseline - iBandTop;
2137 return aCurrentCursorPos;
2140 /** Scrolls up by a page (that is the band height as set by SetBandHeight(), or
2141 half that amount if scrolling over lines taller than this), moving the text
2142 downwards. The current desired vertical cursor position is passed in
2143 aYCursorPos and updated to a new suggested position as near as possible to it,
2144 but within the visible text and on a baseline.
2146 Do not use if a CTextView object owns this CTextLayout object.
2148 @param aYCursorPos The current desired vertical cursor position. On return,
2149 updated to a new suggested position as near as possible to it.
2150 @param aPixelsScrolled On return, contains the number of pixels scrolled. */
2151 EXPORT_C void CTextLayout::PageUpL(TInt& aYCursorPos,TInt& aPixelsScrolled)
2153 // Move the cursor into the visible area.
2154 int visible_height = VisibleHeightInPixels();
2155 if (aYCursorPos < 0)
2157 else if (aYCursorPos > visible_height)
2158 aYCursorPos = visible_height - 1;
2161 // position the top of the screen must be at least as low as
2162 TInt longestScrollTo = iBandTop + visible_height
2163 - visible_height * KMaxProportionOfScreenToScroll/1000;
2164 // position the top of the screen must be at least as high as
2165 TInt shortestScrollTo = iBandTop + visible_height
2166 - visible_height * KMinProportionOfScreenToScroll/1000;
2167 TInt desiredScrollTo = shortestScrollTo;
2168 // find the line at the top of the screen
2169 // (we cannot find the one that includes the first pixel off the screen
2170 // because it might not have been formatted yet)
2171 if (iText->YPosToLine(iBandTop, info))
2173 // subtract one from the line number if this was on the screen
2174 TInt line = info.iLineNumber
2175 - (info.iOuterRect.iTl.iY < iBandTop? 0 : 1)
2176 + KNumberOfLinesToKeepVisibleDuringScroll;
2177 if (iText->LineNumberToLine(Max(0, line), info))
2178 desiredScrollTo = info.iOuterRect.iTl.iY;
2180 if (shortestScrollTo < desiredScrollTo)
2181 desiredScrollTo = shortestScrollTo;
2182 else if (desiredScrollTo < longestScrollTo)
2183 desiredScrollTo = longestScrollTo;
2184 aPixelsScrolled = ScrollL(iBandTop + visible_height - desiredScrollTo,
2185 EFDisallowScrollingBlankSpace);
2186 aYCursorPos = aPixelsScrolled == 0?
2188 : SuggestCursorPos(aYCursorPos);
2191 /** Scrolls down by a page (that is the band height as set by SetBandHeight(),
2192 or half that amount if scrolling over lines taller than this), moving the text
2193 upwards. The current desired vertical cursor position is passed in aYCursorPos
2194 and updated to a new suggested position as near as possible to it, but within
2195 the visible text and on a baseline.
2197 Do not use if a CTextView object owns this CTextLayout object.
2199 @param aYCursorPos The current desired vertical cursor position. On return,
2200 updated to a new suggested position as near as possible to it.
2201 @param aPixelsScrolled On return, contains the number of pixels scrolled - a
2203 EXPORT_C void CTextLayout::PageDownL(TInt& aYCursorPos,TInt& aPixelsScrolled)
2205 // Move the cursor into the visible area.
2206 int visible_height = VisibleHeightInPixels();
2207 if (aYCursorPos < 0)
2209 else if (aYCursorPos > visible_height)
2210 aYCursorPos = visible_height - 1;
2213 // position the bottom of the screen must be at least as high as
2214 TInt longestScrollTo = iBandTop +
2215 visible_height * KMaxProportionOfScreenToScroll/1000;
2216 // position the bottom of the screen must be at least as low as
2217 TInt shortestScrollTo = iBandTop + visible_height * KMinProportionOfScreenToScroll/1000;
2218 TInt desiredScrollTo = shortestScrollTo;
2219 // find the line at the bottom of the screen
2220 // (we cannot find the one that includes the first pixel off the screen
2221 // because it might not have been formatted yet)
2222 if (iText->YPosToLine(iBandTop + visible_height - 1, info))
2224 // add one to the line number if this was on the screen
2225 TInt line = info.iLineNumber
2226 + (iBandTop + visible_height < info.iBaseline? 0 : 1)
2227 - KNumberOfLinesToKeepVisibleDuringScroll;
2228 if (iText->LineNumberToLine(Max(0, line), info))
2229 desiredScrollTo = info.iOuterRect.iBr.iY;
2231 if (desiredScrollTo < shortestScrollTo)
2232 desiredScrollTo = shortestScrollTo;
2233 else if (longestScrollTo < desiredScrollTo)
2234 desiredScrollTo = longestScrollTo;
2235 aPixelsScrolled = ScrollL(iBandTop - desiredScrollTo,
2236 EFDisallowScrollingBlankSpace);
2237 aYCursorPos = aPixelsScrolled == 0?
2239 : SuggestCursorPos(aYCursorPos);
2241 if (-visible_height > aPixelsScrolled)
2243 OstTrace0( TRACE_DUMP, CTEXTLAYOUT_PAGEDOWNL, "EPageScrollError" );
2245 __ASSERT_DEBUG(-visible_height <= aPixelsScrolled,
2246 Panic(EPageScrollError));
2247 if (0 > aYCursorPos || aYCursorPos > visible_height)
2249 OstTrace0( TRACE_DUMP, DUP1_CTEXTLAYOUT_PAGEDOWNL, "EPageScrollError" );
2251 __ASSERT_DEBUG(0 <= aYCursorPos && aYCursorPos <= visible_height,
2252 Panic(EPageScrollError));
2255 /** Reformats to reflect a single character edit.
2257 Do not use if a CTextView object owns this CTextLayout object.
2259 @param aType Indicates the type of edit which has taken place.
2260 CTextLayout::EFCharacterInsert (the default) for a character insertion,
2261 CTextLayout::EFParagraphDelimiter for a paragraph delimiter insertion,
2262 CTextLayout::EFLeftDelete or CTextLayout::EFRightDelete for a character or
2263 paragraph delimiter deletion to the left or right of the document position.
2264 @param aCursorPos The document position at which the edit took place, before
2265 the edit. If this position is not formatted, a panic occurs; it is modified in
2266 accordance with the edit.
2267 @param aGood On return, the y coordinate of the top of the paragraph following
2268 the paragraph which has been edited, before the edit.
2269 @param aFormattedUpTo On return, the y coordinate of the bottom of the
2270 reformatted line or lines, after the edit.
2271 @param aFormattedFrom On return, the vertical layout coordinate of the top of
2272 the reformatted line or lines, after the edit.
2273 @param aScroll The number of pixels by which the text had to be scrolled
2274 (positive means text moved down).
2275 @param aFormatChanged ETrue if text is to be reformatted from the start of the
2276 paragraph the cursor was on before the edit, EFalse if from the start of the
2277 line the cursor was on before the edit.
2278 @return EFalse if no more lines need to be reformatted. ETrue if some more lines
2279 need to be reformatted. */
2280 EXPORT_C TBool CTextLayout::HandleCharEditL(TUint aType,TInt& aCursorPos,TInt& aGood,TInt& aFormatBottom,
2281 TInt& aFormatTop,TInt& aScroll,TBool aFormatFromStartOfPar)
2283 if (iSource->iFormatMode == CLayoutData::EFPrintPreviewMode)
2285 OstTrace0( TRACE_FATAL, DUP2_CTEXTLAYOUT_HANDLECHAREDITL, "EPrintPreviewModeError" );
2287 __ASSERT_ALWAYS(iSource->iFormatMode != CLayoutData::EFPrintPreviewMode,Panic(EPrintPreviewModeError));
2288 if (aType > EFRightDelete)
2290 OstTrace0( TRACE_FATAL, CTEXTLAYOUT_HANDLECHAREDITL, "EBadCharacterEditType" );
2292 __ASSERT_ALWAYS(aType <= EFRightDelete,Panic(EBadCharacterEditType));
2293 if (!(!aFormatFromStartOfPar || aType == EFRightDelete || aType == EFLeftDelete))
2295 OstTrace0( TRACE_FATAL, DUP1_CTEXTLAYOUT_HANDLECHAREDITL, "EBadCharacterEditType" );
2297 __ASSERT_ALWAYS(!aFormatFromStartOfPar || aType == EFRightDelete || aType == EFLeftDelete,Panic(EBadCharacterEditType));
2298 if (aCursorPos < iText->StartChar() || aCursorPos >= iText->EndChar())
2300 OstTrace0( TRACE_FATAL, DUP3_CTEXTLAYOUT_HANDLECHAREDITL, "ECharacterNotFormatted" );
2302 __ASSERT_ALWAYS(aCursorPos >= iText->StartChar() && aCursorPos < iText->EndChar(),Panic(ECharacterNotFormatted));
2304 // Mark the entire paragraph invalid if background formatting is taking place.
2305 iParInvalid = iUnformattedStart != KMaxTInt;
2307 // Cancel any pending background formatting, which has now been invalidated by the change.
2308 iUnformattedStart = KMaxTInt;
2310 // Adjust the cursor position and determine the range of characters to reformat.
2311 TTmReformatParam reformat_param;
2312 reformat_param.iParInvalid = iParInvalid;
2315 case EFCharacterInsert:
2316 case EFParagraphDelimiter:
2318 reformat_param.iStartChar = aCursorPos++;
2319 reformat_param.iNewLength = 1;
2321 // surrogate support
2322 TPtrC textForSurrogate;
2323 TTmCharFormat formatForSurrogate;
2325 iSource->GetText(aCursorPos-1, textForSurrogate, formatForSurrogate);
2326 if ( textForSurrogate.Length() > 1 )
2328 TUint highSurrogate = textForSurrogate[0];
2329 TUint lowSurrogate = textForSurrogate[1];
2330 if ( TChar::IsHighSurrogate( highSurrogate ) && TChar::IsLowSurrogate( lowSurrogate ) )
2332 // if we are inserting a surrogate pair, do not break the pair
2334 reformat_param.iNewLength++;
2341 reformat_param.iStartChar = --aCursorPos;
2342 reformat_param.iOldLength = 1;
2344 // surrogate support
2345 TPtrC textForSurrogate;
2346 TTmCharFormat formatForSurrogate;
2348 if (aCursorPos >= 1)
2350 iSource->GetText(aCursorPos-1, textForSurrogate, formatForSurrogate);
2351 if ( textForSurrogate.Length() > 1 )
2353 TUint highSurrogate = textForSurrogate[0];
2354 TUint lowSurrogate = textForSurrogate[1];
2355 if ( TChar::IsHighSurrogate( highSurrogate ) && TChar::IsLowSurrogate( lowSurrogate ) )
2357 // if we are deleting a surrogate pair, do not break the pair
2358 reformat_param.iStartChar = --aCursorPos;
2359 reformat_param.iOldLength++;
2367 reformat_param.iStartChar = aCursorPos;
2368 reformat_param.iOldLength = 1;
2370 // surrogate support
2371 TPtrC textForSurrogate;
2372 TTmCharFormat formatForSurrogate;
2374 iSource->GetText(aCursorPos, textForSurrogate, formatForSurrogate);
2375 if ( textForSurrogate.Length() > 1 )
2377 TUint highSurrogate = textForSurrogate[0];
2378 TUint lowSurrogate = textForSurrogate[1];
2379 if ( TChar::IsHighSurrogate( highSurrogate ) && TChar::IsLowSurrogate( lowSurrogate ) )
2381 reformat_param.iOldLength++;
2389 // Set up the formatting parameters.
2390 TTmFormatParam param;
2391 InitFormatParam(param);
2392 param.iMaxHeight = KMaxTInt;
2394 // Format the whole band if necessary.
2395 TTmDocPos cursorPos(aCursorPos, EFalse);
2396 if (reformat_param.iStartChar < iText->StartChar() || reformat_param.iStartChar + reformat_param.iOldLength >= iText->EndChar())
2398 FormatBandL(reformat_param.iStartChar,reformat_param.iStartChar + reformat_param.iOldLength);
2400 aFormatBottom = iText->LayoutHeight() - iBandTop;
2401 aGood = aFormatBottom;
2403 ScrollDocPosIntoViewL(cursorPos);
2407 // Reformat the chosen range.
2408 reformat_param.iMaxExtraLines = KMaxExtraLines;
2409 TTmReformatResult result;
2410 iText->FormatL(param,reformat_param,result);
2411 result.iRedrawRect.Move(0,-iBandTop);
2412 iUnformattedStart = result.iUnformattedStart;
2414 // Scroll if necessary and extend the redraw area to include material scrolled into view.
2415 aScroll = ScrollDocPosIntoViewL(cursorPos);
2417 result.iRedrawRect.iBr.iY += aScroll;
2419 result.iRedrawRect.iTl.iY += aScroll;
2421 // Return coordinates.
2422 aFormatTop = result.iRedrawRect.iTl.iY;
2423 aFormatBottom = result.iRedrawRect.iBr.iY;
2424 aGood = result.iUnchangedTop - iBandTop;
2426 // Add new paragraphs if necessary.
2427 int visible_height = VisibleHeightInPixels();
2429 param.iEndChar = KMaxTInt;
2430 param.iMaxHeight = (iBandTop + visible_height) - iText->LayoutHeight();
2431 if(param.iMaxHeight > 0)
2433 iText->ExtendFormattingDownwardsL(param);
2436 //remove formatting from the end if necessary
2437 PruneFormatL(EFalse);
2438 // Return TRUE if more text needs to be formatted.
2439 return iUnformattedStart < KMaxTInt;
2442 /** Reformats to reflect changes to a block of text.
2444 Do not use if a CTextView object owns this CTextLayout object.
2446 @param aSelection The start and new length of the changed block. When
2447 inserting, specify the insertion position. When deleting, specify the position
2448 of the start of the deletion. When reformatting, specify the start and length
2449 of the reformatted block.
2450 @param aOldCharsChanged The old length of the changed block. When inserting,
2451 specify zero. When deleting, specify the number of deleted characters. When
2452 reformatting, specify the number of reformatted characters.
2453 @param aViewChanges On return, contains the top of the reformatted text
2454 (iFormattedFrom), the bottom of the reformatted text (iFormattedTo), the amount
2455 by which the text above the reformatted text has scrolled (iScrollAtTop) and
2456 the amount by which the text below the reformatted text has scrolled
2457 (iScrollAtBottom) (positive values mean the text moves down).
2458 @param aFormatChanged Indicates whether the paragraph format for the first or
2459 last affected paragraph has changed, meaning that the text to be reformatted
2460 must extend out to paragraph boundaries and cannot be restricted to only some
2462 EXPORT_C void CTextLayout::HandleBlockChangeL(TCursorSelection aSelection,TInt aOldLength,
2463 TViewRectChanges& aChanges,TBool aFormatFromStartOfPar)
2465 if (iSource->iFormatMode == CLayoutData::EFPrintPreviewMode)
2467 OstTrace0( TRACE_FATAL, CTEXTLAYOUT_HANDLEBLOCKCHANGEL, "EPrintPreviewModeError" );
2469 __ASSERT_ALWAYS(iSource->iFormatMode != CLayoutData::EFPrintPreviewMode,Panic(EPrintPreviewModeError));
2471 // Do nothing if the selection is outside the formatted range.
2472 if (aSelection.LowerPos() > iText->EndChar() || aSelection.HigherPos() < iText->StartChar())
2474 aChanges.iFormattedFrom = 0;
2475 aChanges.iFormattedTo = 0;
2476 aChanges.iScrollAtTop = 0;
2477 aChanges.iScrollAtBottom = 0;
2481 // Format the whole band if necessary.
2482 TTmDocPos cursorPos(aSelection.iCursorPos,
2483 aSelection.iCursorPos < aSelection.iAnchorPos? ETrue : EFalse);
2484 if (aSelection.LowerPos() < iText->StartChar() || aSelection.LowerPos() + aOldLength >= iText->EndChar())
2486 FormatBandL(aSelection.iCursorPos,aSelection.iCursorPos);
2487 aChanges.iFormattedFrom = 0;
2488 aChanges.iFormattedTo = VisibleHeightInPixels();
2489 aChanges.iScrollAtTop = 0;
2490 aChanges.iScrollAtBottom = 0;
2491 ScrollDocPosIntoViewL(cursorPos);
2495 // Reformat the chosen range.
2496 TTmFormatParam param;
2497 InitFormatParam(param);
2498 param.iMaxHeight = KMaxTInt;
2499 TTmReformatParam reformat_param;
2500 reformat_param.iStartChar = aSelection.LowerPos();
2501 reformat_param.iOldLength = aOldLength;
2502 reformat_param.iNewLength = aSelection.Length();
2503 reformat_param.iParFormatChanged = aFormatFromStartOfPar;
2504 TTmReformatResult result;
2505 iText->FormatL(param,reformat_param,result);
2506 result.iRedrawRect.Move(0,-iBandTop);
2508 // Scroll if necessary.
2510 if(iTextViewCursorPos)
2512 dy = ScrollDocPosIntoViewL(iTextViewCursorPos->TmDocPos());
2513 iTextViewCursorPos = NULL;
2517 dy = ScrollDocPosIntoViewL(cursorPos);
2519 result.iRedrawRect.Move(0,dy);
2521 aChanges.iFormattedFrom = result.iRedrawRect.iTl.iY;
2522 aChanges.iFormattedTo = result.iRedrawRect.iBr.iY;
2523 aChanges.iScrollAtTop = dy;
2524 aChanges.iScrollAtBottom = dy + result.iHeightChange;
2526 // Extend formatting to fill the band if necessary.
2527 int visible_height = VisibleHeightInPixels();
2529 param.iEndChar = KMaxTInt;
2530 param.iMaxHeight = (iBandTop + visible_height) - iText->LayoutHeight();
2531 if(param.iMaxHeight > 0)
2533 iText->ExtendFormattingDownwardsL(param);
2536 //remove formatting from the end if necessary
2537 PruneFormatL(EFalse);
2540 /** Reformats to reflect the addition of one or more complete paragraphs at the
2543 Do not use if a CTextView object owns this CTextLayout object.
2545 @param aFirstPixel On return, the top y coordinate of the added material.
2546 @param aLastPixel On return, the bottom y coordinate of the added material.
2548 EXPORT_C void CTextLayout::HandleAdditionalCharactersAtEndL(TInt& aNewTextTop,TInt& aNewTextBottom)
2550 aNewTextTop = aNewTextBottom = iText->LayoutHeight() - iBandTop;
2551 int format_required = BandHeightInPixels() - aNewTextBottom;
2552 if (format_required > 0)
2554 TTmFormatParam param;
2555 InitFormatParam(param);
2556 param.iMaxHeight = format_required;
2557 TInt oldHeight = iText->LayoutHeight();
2558 iText->ExtendFormattingDownwardsL(param);
2559 aNewTextBottom += (iText->LayoutHeight() - oldHeight);
2563 /** Reformats to reflect changes to the space above and below paragraphs
2564 (CParaFormat::iSpaceBeforeInTwips and iSpaceAfterInTwips).
2566 Do not use if a CTextView object owns this CTextLayout object.
2567 @deprecated 6.1 Use FormatBandL()
2569 EXPORT_C void CTextLayout::ReformatVerticalSpaceL()
2571 // Reformat the whole band; only space above and below paragraphs has changed, but who cares?
2575 /** Temporarily changes the vertical alignment of the text with respect to the
2580 Not generally useful.
2582 Do not use if a CTextView object owns this CTextLayout object.
2584 @param aVerticalAlignment Specifies whether the formatted text should be placed
2585 at the top (CParaFormat::ETopAlign), vertical centre (CParaFormat::ECenterAlign
2586 or CParaFormat::EJustifiedAlign) or bottom (CParaFormat::EBottomAlign) of the
2587 band. CParaFormat::EUnspecifiedAlign or CParaFormat::ECustomAlign may also be
2588 specified. These values cause the baseline of the first formatted line to be
2589 positioned 82% of the way down the band (provided for the Agenda's
2590 application's year view). */
2591 EXPORT_C void CTextLayout::AdjustVerticalAlignment(CParaFormat::TAlignment aVerticalAlignment)
2593 int excess = BandHeight() - FormattedHeightInPixels();
2594 int space_before = 0;
2596 if (IsFormattingBand())
2598 OstTrace0( TRACE_FATAL, CTEXTLAYOUT_ADJUSTVERTICALALIGNMENT, "EMustFormatAllText" );
2600 __ASSERT_ALWAYS(!IsFormattingBand(),Panic(EMustFormatAllText));
2603 switch (aVerticalAlignment)
2605 case CParaFormat::EAbsoluteLeftAlign:
2606 case CParaFormat::ETopAlign:
2608 case CParaFormat::ECenterAlign:
2609 case CParaFormat::EJustifiedAlign:
2610 space_before = excess / 2;
2612 case CParaFormat::EAbsoluteRightAlign:
2613 case CParaFormat::EBottomAlign:
2614 space_before = excess;
2616 case CParaFormat::EUnspecifiedAlign:
2617 case CParaFormat::ECustomAlign:
2618 if (iText->LineNumberToLine(0,info))
2620 space_before = CLayoutData::EFBaseLinePosition * BandHeight() / 100 - info.iBaseline;
2624 space_before = CLayoutData::EFBaseLinePosition * BandHeight() / 100;
2629 iBandTop = -space_before;
2632 static TInt SingleBorderWidthInPixels(const MGraphicsDeviceMap* aGd,const TParaBorder& aBorder,TBool aHoriz)
2634 TInt width = aBorder.iThickness;
2638 width = aGd->VerticalTwipsToPixels(width);
2640 width = aGd->HorizontalTwipsToPixels(width);
2647 /** Draws paragraph borders, optionally with a background colour for the border
2648 and a clip region. Provided for applications that display a menu of border
2649 styles, like a wordprocessor.
2651 @param aGd Provides twip-to-pixel conversion.
2652 @param aGc Graphics context to which to draw the border. Its pen settings are
2653 overridden by the values specified by aBorder and its draw mode is set to
2654 CGraphicsContext::EDrawModePEN.
2655 @param aRect The outer bounds of the border.
2656 @param aBorder Specifies the four sides of the border.
2657 @param aBackground If not null, the background colour, (used between double
2658 border lines, or between dots or dashes).
2659 @param aClipRegion If non-null, specifies a clip region.
2660 @param aDrawRect If non-null, and if aClipRegion is non-null, specifies a
2661 rectangle to be subtracted from the clip region. */
2662 EXPORT_C void CTextLayout::DrawBorders(const MGraphicsDeviceMap* aGd,CGraphicsContext& aGc,const TRect& aBoundingRect,
2663 const TParaBorderArray& aBorder,const TRgb* aBackground,TRegion *aClipRegion,
2664 const TRect* aDrawRect)
2666 TPoint pointTl,pointBr;
2668 TInt * ptrStartLength=NULL; //To stop a warning
2669 TInt * ptrEndLength=NULL; //To stop a warning
2670 TInt * ptrStartWidth=NULL; //To stop a warning
2671 TInt * ptrEndWidth=NULL; //To stop a warning
2672 TInt directionOut=0; //To stop a warning
2673 TInt indexJoint1=0,indexJoint2=0; //To stop a warning
2674 TBool drawAsLine=EFalse;
2676 CGraphicsContext::TPenStyle penStyle[4];
2677 TInt widthInPixels[4];
2679 const MFormParam* form_param = MFormParam::Get();
2681 {for (TInt border=0; border<=3; border++)
2683 TParaBorder::TLineStyle lineStyle=aBorder.iBorder[border].iLineStyle;
2684 if (lineStyle == TParaBorder::ENullLineStyle)
2686 penStyle[border]=CGraphicsContext::ENullPen;
2687 widthInPixels[border]=0;
2692 horiz=(border==CParaFormat::EParaBorderTop || border==CParaFormat::EParaBorderBottom);
2694 widthInPixels[border]=SingleBorderWidthInPixels(aGd,aBorder.iBorder[border],horiz);
2697 if (lineStyle==TParaBorder::ESolid || lineStyle==TParaBorder::EDouble)
2699 penStyle[border]=CGraphicsContext::ESolidPen;
2703 if (lineStyle == TParaBorder::EDashed)
2704 penStyle[border]=CGraphicsContext::EDashedPen;
2705 else if (lineStyle == TParaBorder::EDotted)
2706 penStyle[border]=CGraphicsContext::EDottedPen;
2707 else if (lineStyle == TParaBorder::EDotDash)
2708 penStyle[border]=CGraphicsContext::EDotDashPen;
2709 else if (lineStyle == TParaBorder::EDotDotDash)
2710 penStyle[border]=CGraphicsContext::EDotDotDashPen;
2714 {for (TInt border=0; border<=3; border++)
2716 // Go to next border, if have NULL linestyle.
2717 if (widthInPixels[border]==0)
2720 // Reset clipping region
2721 clipRect.SetSize(TSize(0,0));
2723 // Draw as line if not solid lines.
2725 if (penStyle[border]!=CGraphicsContext::ESolidPen)
2728 pointTl=aBoundingRect.iTl;
2729 pointBr=aBoundingRect.iBr;
2731 if (border==CParaFormat::EParaBorderLeft)
2733 pointBr.iX=pointTl.iX;
2734 ptrStartLength=&pointTl.iY;
2735 ptrEndLength=&pointBr.iY;
2736 ptrStartWidth=&pointTl.iX;
2737 ptrEndWidth=&pointBr.iX;
2739 indexJoint1=CParaFormat::EParaBorderTop;
2740 indexJoint2=CParaFormat::EParaBorderBottom;
2742 if (border == CParaFormat::EParaBorderRight)
2744 pointTl.iX=pointBr.iX;
2745 ptrStartLength=&pointTl.iY;
2746 ptrEndLength=&pointBr.iY;
2747 ptrStartWidth=&pointTl.iX;
2748 ptrEndWidth=&pointBr.iX;
2750 indexJoint1=CParaFormat::EParaBorderTop;
2751 indexJoint2=CParaFormat::EParaBorderBottom;
2753 if (border == CParaFormat::EParaBorderTop)
2755 pointBr.iY=pointTl.iY;
2756 ptrStartLength=&pointTl.iX;
2757 ptrEndLength=&pointBr.iX;
2758 ptrStartWidth=&pointTl.iY;
2759 ptrEndWidth=&pointBr.iY;
2761 indexJoint1=CParaFormat::EParaBorderLeft;
2762 indexJoint2=CParaFormat::EParaBorderRight;
2764 if (border == CParaFormat::EParaBorderBottom)
2766 pointTl.iY=pointBr.iY;
2767 ptrStartLength=&pointTl.iX;
2768 ptrEndLength=&pointBr.iX;
2769 ptrStartWidth=&pointTl.iY;
2770 ptrEndWidth=&pointBr.iY;
2772 indexJoint1=CParaFormat::EParaBorderLeft;
2773 indexJoint2=CParaFormat::EParaBorderRight;
2776 if (!ptrStartWidth || !ptrEndWidth)
2785 (*ptrStartWidth)+=(widthInPixels[border]-1)/2;
2786 (*ptrEndWidth)+=(widthInPixels[border]-1)/2;
2790 (*ptrStartWidth)-=(widthInPixels[border]+2)/2;
2791 (*ptrEndWidth)-=(widthInPixels[border]+2)/2;
2793 (*ptrStartLength)+=(widthInPixels[border]-1)/2;
2794 (*ptrEndLength)-=(widthInPixels[border])/2;
2799 (*ptrEndWidth)+=widthInPixels[border];
2801 (*ptrStartWidth)-=widthInPixels[border];
2804 // Colour of pen as is - NO logical combination with background etc.
2805 aGc.SetDrawMode(CGraphicsContext::EDrawModePEN);
2809 // Must draw lines in background colour first, as have dotted/dashed lines.
2810 aGc.SetPenSize(TSize(widthInPixels[border],widthInPixels[border]));
2813 FormUtil::SetPenColor(form_param,&aGc,*aBackground);
2814 aGc.SetPenStyle(CGraphicsContext::ESolidPen);
2815 aGc.DrawLine(pointTl,pointBr);
2817 FormUtil::SetPenColor(form_param,&aGc,aBorder.iBorder[border].iColor);
2818 aGc.SetPenStyle(penStyle[border]);
2819 aGc.DrawLine(pointTl,pointBr);
2820 (*ptrStartWidth)-=(widthInPixels[border]-1)/2;
2821 (*ptrEndWidth)+=(widthInPixels[border]+2)/2;
2822 (*ptrStartLength)-=(widthInPixels[border]-1)/2;
2823 (*ptrEndLength)+=(widthInPixels[border])/2;
2824 clipRect.SetRect(pointTl,pointBr);
2829 FormUtil::SetBrushColor(form_param,&aGc,aBorder.iBorder[border].iColor);
2830 aGc.SetBrushStyle(CGraphicsContext::ESolidBrush);
2831 aGc.SetPenStyle(CGraphicsContext::ENullPen);
2832 rect.SetRect(pointTl,pointBr);
2837 // Repeat draw, for double border.
2838 if (aBorder.iBorder[border].iLineStyle==TParaBorder::EDouble) // Now have only got solid border, drawn as rect.
2842 OstTrace0( TRACE_DUMP, CTEXTLAYOUT_DRAWBORDERS, "EDrawingBorderError" );
2844 __ASSERT_DEBUG(!drawAsLine,Panic(EDrawingBorderError));
2845 (*ptrStartWidth)-=directionOut*widthInPixels[border];
2846 (*ptrEndWidth)-=directionOut*widthInPixels[border];
2847 (*ptrStartLength)+=widthInPixels[indexJoint1];
2848 (*ptrEndLength)-=widthInPixels[indexJoint2];
2852 rect.SetRect(pointTl,pointBr);
2853 FormUtil::SetBrushColor(form_param,&aGc,*aBackground);
2857 (*ptrStartWidth)-=directionOut*widthInPixels[border];
2858 (*ptrEndWidth)-=directionOut*widthInPixels[border];
2860 if (aBorder.iBorder[indexJoint1].iLineStyle==TParaBorder::EDouble)
2861 (*ptrStartLength)+=widthInPixels[indexJoint1];
2862 if (aBorder.iBorder[indexJoint2].iLineStyle==TParaBorder::EDouble)
2863 (*ptrEndLength)-=widthInPixels[indexJoint2];
2865 rect.SetRect(pointTl,pointBr);
2866 FormUtil::SetBrushColor(form_param,&aGc,aBorder.iBorder[border].iColor);
2868 clipRect.BoundingRect(rect);
2873 aGc.SetPenStyle(CGraphicsContext::ESolidPen);
2874 aGc.SetPenSize(TSize(1,1));
2875 // Should change to BACKGROUND colour.
2877 FormUtil::SetBrushColor(form_param,&aGc,*aBackground);
2878 // If have to clip region, then remove rectangles corresponding to the border region.
2883 clipRect.Intersection(*aDrawRect);
2884 aClipRegion->SubRect(clipRect);
2891 aClipRegion->Tidy();
2892 ((CWindowGc *) &aGc)->SetClippingRegion(*aClipRegion);
2897 /** Draws the text. Draws any lines that intersect aDrawRect, which is
2898 specified in window coordinates. The drawing parameters, including the graphics
2899 context, are given in aDrawTextLayoutContext. If aHighlight is non-null,
2900 highlights (by exclusive-ORing) the specified range of text.
2902 @param aDrawRect The function draw the lines within the visible area, which
2903 intersect this rectangle (which is specified in window coordinates).
2904 @param aDrawTextLayoutContext Provides a graphics context and other parameters
2906 @param aHighlight If not NULL, this range of text is drawn highlighted. */
2907 EXPORT_C void CTextLayout::DrawL(const TRect& aDrawRect,const TDrawTextLayoutContext* aDrawTextLayoutContext,
2908 const TCursorSelection* aHighlight)
2910 // Set the drawing parameters in the MTmSource interface.
2911 iSource->iFormParam = MFormParam::Get();
2912 iSource->iLabelsGutter = aDrawTextLayoutContext->iGutterMarginWidth;
2914 // Calculate the top left corner of the text.
2915 TPoint top_left = aDrawTextLayoutContext->TopLeftText();
2916 top_left.iY -= iBandTop;
2918 // Get the graphics context.
2919 CGraphicsContext* gc = aDrawTextLayoutContext->PrimaryGc();
2922 Clip the draw rectangle to the view rectangle, and clip it further to exclude
2923 a final partial line if necessary.
2925 TRect clip_rect(aDrawRect);
2926 clip_rect.Intersection(aDrawTextLayoutContext->iViewRect);
2929 if (aDrawTextLayoutContext->UseClippingRect())
2931 gc->SetClippingRect(clip_rect);
2934 // Draw the text and background.
2936 TBool isDrawingOnAWindowDC = aDrawTextLayoutContext->UseWindowGc();
2938 if (isDrawingOnAWindowDC)
2940 BeginRedraw(clip_rect);
2943 iText->DrawLayout(*gc,top_left,clip_rect,&aDrawTextLayoutContext->iBackgroundColor,TRUE, aHighlight, iHighlightExtensions);
2945 if (isDrawingOnAWindowDC)
2950 iSource->iFormParam = NULL;
2953 /** Default constructor.
2955 The start and end positions are set to zero - Set() should be called to
2956 initialise the object. */
2957 EXPORT_C CTextLayout::TRangeChange::TRangeChange()
2960 /** Sets the start and end positions and whether the highlighting should be
2963 Called by the non-default constructor. The start and end positions can be
2964 specified in any order.
2966 @param aStart The start of the range.
2967 @param aEnd The end of the range.
2968 @param aChange Whether the highlighting should be set or cleared. */
2969 EXPORT_C void CTextLayout::TRangeChange::Set(TInt aStart, TInt aEnd,
2970 CTextLayout::TRangeChange::TChangeType aChange)
2972 if ((aChange == ESet && aStart < aEnd)
2973 || (!(aChange == ESet) && !(aStart < aEnd)))
2985 /** Constructor with a start and end position and whether the highlighting
2986 in the range should be set or cleared.
2988 The start and end positions can be specified in any order.
2990 @param aStart The start position.
2991 @param aEnd The end position.
2992 @param aChange Specifies whether the highlighting should be set or cleared.
2994 EXPORT_C CTextLayout::TRangeChange::TRangeChange(TInt aStart, TInt aEnd,
2995 CTextLayout::TRangeChange::TChangeType aChange)
2997 Set(aStart, aEnd, aChange);
3000 /** Gets the start and end of the range and whether the highlighting should be
3003 @param aStart On return, the start of the range. This is always the lesser of
3005 @param aEnd On return, the end of the range. This is always the greater of the
3007 @return Specifies whether the highlighting should be set or cleared. */
3008 EXPORT_C CTextLayout::TRangeChange::TChangeType
3009 CTextLayout::TRangeChange::Get(TInt& aStart, TInt& aEnd) const
3022 /** Tests whether the range is not null.
3024 @return ETrue if the range is not of zero length, EFalse if the range is of zero
3026 EXPORT_C TBool CTextLayout::TRangeChange::NonNull() const
3031 /** Clips the range so that its start and end positions are within the minimum
3032 and maximum positions specified.
3034 @param aMin The minimum value for the start and end of the range.
3035 @param aMax The maximum value for the start and end of the range.
3036 @return ETrue if the resulting range is not of zero length, EFalse if it is of
3038 EXPORT_C TBool CTextLayout::TRangeChange::Clip(TInt aMin, TInt aMax)
3051 /** Try to cancel out sections of the ranges that overlap Merges two ranges of
3054 Two successive calls to CTextLayout::Highlight() could cause unecessary flicker
3055 or redrawing if the arguments to each call overlap. For example, if extending a
3056 highlight involved removing the old highlight and then drawing the new one,
3057 this would cause visible flicker. This can be eliminated by calling this
3058 function to remove any overlap between the two ranges. If there is overlap,
3059 this range is set to the result of the merge, and the other range (aBuddy) is
3062 When calling this function, it does not matter whether or not the two ranges
3063 overlap. Also it does not matter which range is the parameter and which is the
3064 calling object. After calling OptimizeWith(), it is guaranteed that the
3065 resulting ranges will not overlap, and they will represent the same change to
3066 the highlight as the original two ranges.
3068 See the code fragment in the class description for TRangeChange for an example
3069 of how this function is used.
3071 @param aBuddy The range of characters to combine with this range. */
3072 EXPORT_C void CTextLayout::TRangeChange::OptimizeWith(TRangeChange& aBuddy)
3074 // we make this have the minimum iA and iB, and aBuddy have the maximum
3077 TInt temp = aBuddy.iA;
3083 TInt temp = aBuddy.iB;
3087 // if they now overlap, we combine them into one and zero the other
3088 if (aBuddy.iB <= iA)
3089 iA = aBuddy.iB = aBuddy.iA;
3090 else if (aBuddy.iA <= iB)
3091 iB = aBuddy.iA = aBuddy.iB;
3095 TBool CTextLayout::TRangeChange::IsJoinedTo(const TRangeChange aRange)
3097 TInt a1 = (iA < iB) ? iA : iB;
3098 TInt b1 = (iA < iB) ? iB : iA;
3099 TInt a2 = (aRange.iA < aRange.iB) ? aRange.iA : aRange.iB;
3100 TInt b2 = (aRange.iA < aRange.iB) ? aRange.iB : aRange.iA;
3102 return a2 <= b1 && a1 <= b2;
3105 void CTextLayout::TRangeChange::Join(const TRangeChange aRange)
3107 TInt a1 = (iA < iB) ? iA : iB;
3108 TInt b1 = (iA < iB) ? iB : iA;
3109 TInt a2 = (aRange.iA < aRange.iB) ? aRange.iA : aRange.iB;
3110 TInt b2 = (aRange.iA < aRange.iB) ? aRange.iB : aRange.iA;
3113 iA = (a1 < a2) ? a1 : a2;
3114 iB = (b1 > b2) ? b1 : b2;
3118 /** Sets or clears a highlight.
3120 If the range of characters to highlight is of zero length, the function has no
3123 The function affects only those lines that intersect aDrawRect, which is
3124 specified in window coordinates. The drawing parameters, including the graphics
3125 context, are given in aDrawTextLayoutContext.
3127 From v7.0, this function replaces InvertRangeL().
3129 This function is not intended to be used to set any part of a highlight already
3130 set, nor to clear any piece of text not highlighted. It is intended to do
3131 either or both of: clear an existing selection, set a new selection. See the
3132 class description for TRangeChange for a code fragment showing how this
3133 function should be used.
3135 @param aHighlight Specifies the range of characters to highlight or from which
3136 to remove the highlight.
3137 @param aDrawRect Only lines which intersect this rectangle are affected
3138 (specified in window coordinates).
3139 @param aDrawTextLayoutContext Provides a graphics context and other drawing
3140 parameters, e.g. the text and background colours for the highlighted region. */
3142 EXPORT_C void CTextLayout::Highlight(const CTextLayout::TRangeChange& aChangeHighlight,
3143 const TRect& aDrawRect, const TDrawTextLayoutContext* aDrawTextLayoutContext)
3145 if (!aChangeHighlight.NonNull())
3148 TRect clip_rect(aDrawRect);
3150 CGraphicsContext* gc = aDrawTextLayoutContext->PrimaryGc();
3151 if (aDrawTextLayoutContext->UseClippingRect())
3152 gc->SetClippingRect(clip_rect);
3155 TInt visible_length = PosRangeInBand(visible_start);
3160 CTextLayout::TRangeChange::TChangeType type = aChangeHighlight.Get(start_pos, end_pos);
3161 start_pos = start_pos < visible_start? visible_start : start_pos;
3162 end_pos = end_pos < visible_start + visible_length? end_pos : start_pos + visible_length;
3163 TCursorSelection selection(start_pos, end_pos);
3165 TPoint top_left = aDrawTextLayoutContext->TopLeftText();
3166 top_left.iY -= iBandTop;
3168 TBool isDrawingOnAWindowDC = aDrawTextLayoutContext->UseWindowGc();
3171 iText->GetUpdateBoundingRect(start_pos, end_pos, top_left, boundingRect);
3172 iHighlightExtensions->AbsExtendRect(boundingRect);
3173 boundingRect.Intersection(clip_rect);
3174 if (! boundingRect.IsEmpty())
3176 if (isDrawingOnAWindowDC)
3178 BeginRedraw(boundingRect);
3180 iText->DrawLayout(*gc, top_left, boundingRect, &aDrawTextLayoutContext->iBackgroundColor, TRUE, &selection, NULL);
3181 if (isDrawingOnAWindowDC)
3188 void CTextLayout::HighlightUsingExtensions(const CTextLayout::TRangeChange& aChangeHighlight,const TRangeChange& aFullHighlight,
3189 const TRect& aDrawRect, const TDrawTextLayoutContext* aDrawTextLayoutContext)
3191 if (!aChangeHighlight.NonNull())
3194 TRect clip_rect(aDrawRect);
3195 clip_rect.Intersection(aDrawTextLayoutContext->TextArea());
3197 CGraphicsContext* gc = aDrawTextLayoutContext->PrimaryGc();
3198 if (aDrawTextLayoutContext->UseClippingRect())
3200 gc->SetClippingRect(clip_rect);
3204 TInt visible_length = PosRangeInBand(visible_start);
3207 CTextLayout::TRangeChange::TChangeType type = aChangeHighlight.Get(start_pos, end_pos);
3208 start_pos = start_pos < visible_start? visible_start : start_pos;
3209 end_pos = end_pos < visible_start + visible_length? end_pos : start_pos + visible_length;
3211 TInt full_start_pos;
3213 (void)aFullHighlight.Get(full_start_pos, full_end_pos);
3214 full_start_pos = full_start_pos < visible_start? visible_start : full_start_pos;
3215 full_end_pos = full_end_pos < visible_start + visible_length? full_end_pos : full_start_pos + visible_length;
3216 TCursorSelection selection(full_start_pos, full_end_pos);
3218 TPoint top_left = aDrawTextLayoutContext->TopLeftText();
3219 top_left.iY -= iBandTop;
3221 TBool isDrawingOnAWindowDC = aDrawTextLayoutContext->UseWindowGc();
3224 iText->GetUpdateBoundingRect(start_pos, end_pos, top_left, boundingRect);
3225 iHighlightExtensions->AbsExtendRect(boundingRect);
3226 boundingRect.Intersection(clip_rect);
3227 if (! boundingRect.IsEmpty())
3229 if (isDrawingOnAWindowDC)
3231 BeginRedraw(boundingRect);
3233 iText->DrawLayout(*gc, top_left, boundingRect, &aDrawTextLayoutContext->iBackgroundColor, TRUE, &selection, iHighlightExtensions);
3234 if (isDrawingOnAWindowDC)
3240 if (aDrawTextLayoutContext->UseClippingRect())
3242 gc->CancelClippingRect();
3246 /** Toggles the selection highlight for the range of text in aHighlight.
3248 Highlights only those lines that intersect aDrawRect, which is specified in
3249 window coordinates. The drawing parameters, including the graphics context, are
3250 given in aDrawTextLayoutContext.
3252 In v7.0 and onwards, this function is deprecated -Highlight() should be used
3255 @param aHighlight The range of characters for which to invert the highlighting.
3256 @param aDrawRect Only lines which intersect this rectangle are affected;
3257 specified in window coordinates.
3258 @param aDrawTextLayoutContext Provides a graphics context and other drawing
3260 EXPORT_C void CTextLayout::InvertRangeL(const TCursorSelection& aHighlight,const TRect& aDrawRect,
3261 const TDrawTextLayoutContext* aDrawTextLayoutContext)
3263 TRangeChange range(aHighlight.iAnchorPos, aHighlight.iCursorPos, TRangeChange::ESet);
3264 HighlightUsingExtensions(range,range,aDrawRect,aDrawTextLayoutContext);
3268 Return the FORM major version number. This function is not generally useful. It
3269 is used in test code and was used while making a transition between this and
3270 the former version of FORM. The return value is always 2.
3272 EXPORT_C TInt CTextLayout::MajorVersion() const
3278 This method allows Form clients to register an object able to
3279 create or return references to customisation objects used within Form for
3280 various tasks e.g. inline text.
3282 Reference to interface provider object to register with Formm.
3284 EXPORT_C void CTextLayout::SetInterfaceProvider( MFormCustomInterfaceProvider* aProvider )
3286 iSource->iInterfaceProvider = aProvider;
3289 /** Gets the width and height of the bounding box of the text, including
3290 indents and margins, when formatted to the specified wrap width.
3292 This is useful for applications like a web browser that need to determine the
3293 minimum width for a piece of text: if you specify zero as the wrap width, the
3294 returned aSize.iWidth contains the minimum width that could be used for the
3295 text without illegal line breaks, and if you specify KMaxTInt for aWrapWidth,
3296 the returned aSize.iHeight contains the minimum height: the height when each
3297 paragraph is a single line of unlimited length.
3299 @param aWrapWidth The wrap width for the bounding box.
3300 @param aSize On return, contains the width and height of the bounding box. */
3301 EXPORT_C void CTextLayout::GetMinimumSizeL(TInt aWrapWidth,TSize& aSize)
3304 //Get the size of the minimal bounding box of the text when formatted to the specified wrap width.
3305 //The width may be greater than aWrapWidth. To find the minimum width for the text,
3306 //pass 0 for aWrapWidth. To find the minimum height, pass KMaxTInt for aWrapWidth.
3308 iText->GetMinimumLayoutSizeL(aWrapWidth,aSize);
3311 /** Gets the width and height of the bounding box of the text, including
3312 indents and margins, when formatted to the specified wrap width.
3314 This is useful for applications like a web browser that need to determine the
3315 minimum width for a piece of text: if you specify zero as the wrap width, the
3316 returned aSize.iWidth contains the minimum width that could be used for the
3317 text, and if you specify KMaxTInt for aWrapWidth, the returned aSize.iHeight
3318 contains the minimum height: the height when each paragraph is a single
3319 line of unlimited length. Use aAllowLegalLineBreaksOnly to set whether or
3320 not illegal line breaks should be considered when determining aSize.
3322 @param aWrapWidth The wrap width for the bounding box.
3323 @param aAllowLegalLineBreaksOnly ETrue to only allow legal line breaks, or EFalse to also allow illegal line breaks.
3324 @param aSize On return, contains the width and height of the bounding box. */
3325 EXPORT_C void CTextLayout::GetMinimumSizeL(TInt aWrapWidth,TBool aAllowLegalLineBreaksOnly,TSize& aSize)
3328 //Get the size of the minimal bounding box of the text when formatted to the specified wrap width.
3329 //The width may be greater than aWrapWidth. To find the minimum width for the text,
3330 //pass 0 for aWrapWidth. To find the minimum height, pass KMaxTInt for aWrapWidth.
3332 iText->GetMinimumLayoutSizeL(aWrapWidth,aAllowLegalLineBreaksOnly,aSize);
3335 /** Sets the custom drawing object, for customising the way text and its
3336 background are drawn.
3338 @param aCustomDraw Pointer to a custom drawing object. */
3339 EXPORT_C void CTextLayout::SetCustomDraw(const MFormCustomDraw* aCustomDraw)
3341 iSource->iCustomDraw = aCustomDraw;
3344 /** Returns a pointer to the current custom drawing implementation. Returns
3345 NULL if custom drawing is not in force.
3347 @return Pointer to the custom drawing object. */
3348 EXPORT_C const MFormCustomDraw* CTextLayout::CustomDraw() const
3350 return iSource->iCustomDraw;
3353 /** Sets custom line breaking.
3355 If this function is not called, default line breaking behaviour is used.
3357 Ownership of the custom line breaking object is not transferred to this object.
3359 @param aCustomWrap A pointer to an object that implements the custom line
3360 breaking interface. Specify NULL to disable custom line breaking. */
3361 EXPORT_C void CTextLayout::SetCustomWrap(const MFormCustomWrap* aCustomWrap)
3363 iSource->iCustomWrap = aCustomWrap;
3366 /** Gets the custom line breaking object, as set using SetCustomWrap().
3368 @return A pointer to the custom line breaking object, or NULL if custom line
3369 breaking is not in effect. */
3370 EXPORT_C const MFormCustomWrap* CTextLayout::CustomWrap() const
3372 return iSource->iCustomWrap;
3379 EXPORT_C void MFormCustomDraw::MFormCustomDraw_Reserved_2()
3383 /** This function is called whenever part of the background of a CTextLayout or
3384 CTextView object needs to be drawn. The default implementation fills
3385 aParam.iDrawRect with the colour specified in aBackground.
3387 The default background colour is contained in aBackground. This is the
3388 background colour of the paragraph if drawing text, or the background colour
3389 specified in the TDrawTextLayoutContext object passed to CTextLayout::DrawL()
3390 if drawing outside the text area.
3392 The rectangle which is drawn by this function, (this may not be the whole of
3393 aParam.iDrawRect) must be returned in aDrawn; areas not drawn by you are
3394 automatically filled using the colour aBackground.
3396 @param aParam Contains the drawing parameters: aParam.iGc is the graphics
3397 context to use. aParam.iMap is the graphics device map, which allows you to
3398 convert between pixels and twips and create fonts. aParam.iTextLayoutTopLeft is
3399 the origin of the text; bitmaps and other graphics must be drawn relative to
3400 this position. aParam.iDrawRect is the area to be drawn; do not draw outside
3402 @param aBackground The default background colour. This is the background colour
3403 of the paragraph if drawing text, or the background colour specified in the
3404 TDrawTextLayoutContext object passed to CTextLayout::DrawL() if drawing outside
3406 @param aDrawn Must return the rectangle you actually draw. This may not be the
3407 whole of aParam.iDrawRect (for instance, if you are drawing a non-tiled bitmap
3408 that occupies only part of aRect). */
3409 EXPORT_C void MFormCustomDraw::DrawBackground(const TParam& aParam,const TRgb& aBackground,TRect& aDrawn) const
3412 c.DrawBackground(aParam.iGc,aParam.iTextLayoutTopLeft,aParam.iDrawRect,aBackground,aDrawn);
3415 /** This function is called after the background has been drawn by
3416 DrawBackground(), and before drawing the text. This function might be used to
3417 draw a ruled line under each line of text.
3419 The default implementation of this function does nothing.
3421 @param aParam Contains the drawing parameters. You should only draw to
3422 aParam.iDrawRect. There is no need to fill aParam.iDrawRect or to indicate the
3424 @param aLineInfo Contains the line metrics: aLineInfo.iOuterLineRect specifies
3425 the bounding rectangle of the line, including margins, indents and automatic
3426 space above and below paragraphs, aLineInfo.iInnerLineRect specifies the bounds
3427 of the text only, aLineInfo.iBaseline specifies the baseline of the text. */
3428 EXPORT_C void MFormCustomDraw::DrawLineGraphics(const TParam& /*aParam*/,const TLineInfo& /*aLineInfo*/) const
3433 /** This function is called to draw the text and its highlighted background, if
3434 any, after bidirectional reordering and other character mappings have taken
3437 The default implementation of this function draws the text with no special
3438 effects and supports standard, round-cornered and shadowed highlighting only.
3439 The text is drawn with the left end of its baseline located at aTextOrigin
3440 after drawing the background, if any, in aParam.iDrawRect.
3442 The main reason to override this function is to apply custom text highlighting,
3443 (for this, aFormat.iFontPresentation.iHighlightStyle should be in the range
3444 EFontHighlightFirstCustomStyle to EFontHighlightLastCustomStyle).
3446 The horizontal spacing between the characters in the text string is increased
3447 by the number of pixels specified in aExtraPixels. The standard way to do this
3448 is by calling CGraphicsContext::SetCharJustification().
3450 The font and other graphics parameters (e.g. pen colour, font style), are
3451 specified in aParam.iGc but a character format container (aFormat) is supplied
3452 so that a different font can be used. Note that any graphics drawn cannot
3453 exceed the bounds of aParam.iDrawRect, so changes are usually restricted to
3454 drawing shadows, outlines, etc. if custom highlighting is in use.
3456 @param aParam Contains the drawing parameters. Drawing can only occur within
3458 @param aLineInfo Contains the line metrics.
3459 @param aFormat Specifies the character formatting to apply to the text,
3460 including the type of text highlighting.
3461 @param aText The text string to be drawn.
3462 @param aTextOrigin The point at which the left end of the baseline of the text
3464 @param aExtraPixels The number of additional pixels to insert between the
3465 characters in the text string, in order to increase its length. */
3466 EXPORT_C void MFormCustomDraw::DrawText(const TParam& aParam,const TLineInfo& aLineInfo,const TCharFormat& aFormat,
3467 const TDesC& aText,const TPoint& aTextOrigin,TInt aExtraPixels) const
3470 info.iOuterRect = aLineInfo.iOuterRect;
3471 info.iInnerRect = aLineInfo.iInnerRect;
3472 info.iBaseline = aLineInfo.iBaseline;
3475 c.DrawText(aParam.iGc,aParam.iTextLayoutTopLeft,aParam.iDrawRect,info,aFormat,
3476 aText,aTextOrigin,aExtraPixels);
3479 EXPORT_C void MFormCustomDraw::DrawText(const TParam& aParam,const TLineInfo& aLineInfo,const TCharFormat& aFormat,
3480 const TDesC& aText,const TInt aStart, const TInt aEnd, const TPoint& aTextOrigin,TInt aExtraPixels) const
3483 info.iOuterRect = aLineInfo.iOuterRect;
3484 info.iInnerRect = aLineInfo.iInnerRect;
3485 info.iBaseline = aLineInfo.iBaseline;
3487 MTmCustomExtension c;
3488 c.DrawText(aParam.iGc,aParam.iTextLayoutTopLeft,aParam.iDrawRect,info,aFormat,
3489 aText,aStart,aEnd,aTextOrigin,aExtraPixels);
3492 /** This function translates logical colours specified in FORM objects into
3493 real colours. The default implementation just returns the default colour that
3494 is passed in and ignores aColorIndex.
3496 Overriding implementations may use aColorIndex in any desired way, either to
3497 replace or modify aDefaultColor. The values used in aColorIndex are taken from
3498 the top byte of a TLogicalRgb object and are thus in the range 0...255. The
3499 TLogicalRgb class defines two reserved values:
3500 TLogicalRgb::ESystemForegroundIndex = 254 and
3501 TLogicalRgb::ESystemBackgroundIndex = 255.
3503 EXPORT_C TRgb MFormCustomDraw::SystemColor(TUint /*aColorIndex*/,TRgb aDefaultColor) const
3505 return aDefaultColor;
3508 void CTextLayout::DrawBackground(CGraphicsContext& aGc,const TPoint& aTopLeft,const TRect& aClipRect,
3509 const TLogicalRgb& aBackground) const
3511 TPoint top_left(aTopLeft);
3512 top_left.iY -= iBandTop;
3513 iText->DrawBackground(aGc,top_left,aClipRect,aBackground);
3516 /** Returns the line break class for a Unicode character.
3518 For convenience, it also gets the range of consecutive characters (if any)
3519 according to the Unicode standard, including aCode, that share the same line
3522 The Unicode line break classes are enumerated in class MTmCustom.
3524 Each character's line break class is obtained using LineBreakClass(). To find
3525 out whether a line break is allowed between two adjacent characters, call
3526 LineBreakPossible() with the line break classes of the two characters as
3527 arguments. For example, the line break class EClLineBreakClass (closing
3528 punctuation) applies to characters such as ")", "]" and ";". Line breaks are
3529 typically allowed after these characters, but not before, so a call to
3530 LineBreakPossible() with the arguments (EAlLineBreakClass, EClLineBreakClass)
3531 would return EFalse in the default implementation, but a call with
3532 (EClLineBreakClass, EAlLineBreakClass) would return ETrue.
3534 @param aCode The Unicode character code of interest.
3535 @param aRangeStart On return, contains the Unicode character code at the start
3536 of the range including aCode that shares the same line break class as aCode.
3537 @param aRangeEnd On return, contains the Unicode character code at the end of
3538 the range including aCode that shares the same line break class as aCode.
3539 @return The line break class assigned to the character. Line break classes are
3540 enumerated in class MTmCustom. */
3541 EXPORT_C TUint MFormCustomWrap::LineBreakClass(TUint aCode,TUint& aRangeStart,TUint& aRangeEnd) const
3543 // Create an instance of MTmCustom and then call the MTmCustom's functions for getting a Line Break class
3546 temp=c.LineBreakClass(aCode,aRangeStart,aRangeEnd);
3550 /** Tests whether a line break is possible between two characters.
3552 If aHaveSpaces is true, the characters are not adjacent one or more space
3553 characters (with a line break class of ESpLineBreakClass) occur between them.
3555 The aPrevClass and aNextClass arguments never have the value ESpLineBreakClass.
3556 Instead, this function is called with the classes of the characters on either
3557 side of the space or run of spaces, (and if so, aHaveSpaces is true). This is
3558 so that line breaks can be prohibited between certain characters with
3559 intervening spaces, for instance an alphabetic character (EAlLineBreakClass,
3560 such as 'a') and a closing bracket, with a space inbetween.
3562 Additionally, the arguments to this function never have a value of
3563 ESaLineBreakClass. For such characters, GetLineBreakInContext() is called
3566 @param aPrevClass The line break class of the previous non-space character.
3567 @param aNextClass The line break class of the next non-space character.
3568 @param aHaveSpaces ETrue if there are one or more space characters (with a line
3569 break class of ESpLineBreakClass) between aPrevClass and aNextClass. EFalse if
3571 @return ETrue if a line break is possible between characters with the two line
3572 break classes, EFalse if not. */
3573 EXPORT_C TBool MFormCustomWrap::LineBreakPossible(TUint aPrevClass,TUint aNextClass,TBool aHaveSpaces) const
3577 temp=c.LineBreakPossible(aPrevClass,aNextClass,aHaveSpaces);
3581 /** Gets the position of the first or last possible line break position in a
3584 This function is called instead of LineBreakPossible() for runs of characters
3585 of class ESaLineBreakClass. It is used for South Asian languages like Thai, Lao
3586 and Khmer that have no spaces between words, so that line breaks must be
3587 calculated using dictionary lookup or a linguistic algorithm.
3589 The default implementation of this function just returns false.
3591 @param aText A string containing characters of class ESaLineBreakClass.
3592 @param aMinBreakPos A position within aText at which to begin searching for a
3593 possible line break position.
3594 @param aMaxBreakPos A position within aText at which to stop searching for a
3595 possible line break position.
3596 @param aForwards If ETrue, the function gets the first possible line break
3597 position (searches forwards from aMinBreakPos); if EFalse, gets the last one
3598 (searches backwards from aMaxBreakPos).
3599 @param aBreakPos On return, the position of the first or last possible line
3600 break within aText. This must be greater than zero and less than aText.Length()
3601 - 1, and must also be in the range aMinBreakPos to aMaxBreakPos.
3602 @return ETrue if a possible line break position is found, EFalse if not. */
3603 EXPORT_C TBool MFormCustomWrap::GetLineBreakInContext(const TDesC& aText,TInt aMinBreakPos,TInt aMaxBreakPos,
3604 TBool aForwards,TInt& aBreakPos) const
3608 temp=c.GetLineBreakInContext(aText,aMinBreakPos,aMaxBreakPos,aForwards,aBreakPos);
3612 /** Tests whether a character can overhang the right margin.
3614 This function can be overridden to customise the line breaking behaviour for
3615 closing punctuation in Japanese. Any characters for which this function returns
3616 ETrue are allowed to overhang the right margin. The rest will be moved to the
3619 The default implementation of this function just returns false.
3621 @param aChar The Unicode character code of interest.
3622 @return ETrue if the character specified can overhang the right margin, EFalse if
3624 EXPORT_C TBool MFormCustomWrap::IsHangingCharacter(TUint aChar) const
3628 temp=c.IsHangingCharacter(aChar);
3632 // Reserved functions are private until they are used
3637 EXPORT_C void MFormCustomWrap::MFormCustomWrap_Reserved_1()
3639 // reserved functions
3641 // Reserved functions are private until they are used.
3647 EXPORT_C void MFormCustomWrap::MFormCustomWrap_Reserved_2()
3649 // reserved functions
3653 TBool CTextLayout::__DbgIsFormattingUpToDate() const
3655 return iUnformattedStart == KMaxTInt;
3659 // TLayDocTextSource stuff begins here.
3660 TLayDocTextSource::TLayDocTextSource():
3667 iFormatMode(CLayoutData::EFScreenMode),
3669 iLabelsDevice(NULL),
3670 iFormatDevice(NULL),
3671 iFontHeightIncreaseFactor(EDefaultFontHeightIncreaseFactor),
3672 iMinimumLineDescent(EDefaultMinimumLineDescent),
3673 iNonPrintingCharVisibility(),
3677 iInterfaceProvider(NULL),
3678 iDrawOpaque(EFalse),
3679 iExcessHeightRequired(0),
3680 iInvisibleCharacterRemapper(NULL)
3684 MGraphicsDeviceMap& TLayDocTextSource::FormatDevice() const
3687 CTextLayout::Panic(CTextLayout::EFormatDeviceNotSet);
3688 if (iLabelsDevice && (iFlags & EUseLabelsDevice))
3689 return *iLabelsDevice;
3691 return *iFormatDevice;
3694 MGraphicsDeviceMap& TLayDocTextSource::InterpretDevice() const
3697 CTextLayout::Panic(CTextLayout::EImageDeviceNotSet);
3698 if (iLabelsDevice && (iFlags & EUseLabelsDevice))
3699 return *iLabelsDevice;
3701 return *iImageDevice;
3704 TInt TLayDocTextSource::DocumentLength() const
3706 return iLayDoc->LdDocumentLength();
3709 void TLayDocTextSource::GetText(TInt aPos,TPtrC& aText,TTmCharFormat& aFormat) const
3712 iLayDoc->GetChars(aText,f,aPos);
3716 void TLayDocTextSource::GetParagraphFormatL(TInt aPos,RTmParFormat& aFormat) const
3719 iLayDoc->GetParagraphFormatL(&f,aPos);
3721 // Labels should not have a forced line height or borders so remove these (this is necessary for Agenda).
3722 if (iFlags & EUseLabelsDevice)
3724 f.iLineSpacingInTwips = 0;
3725 f.iLineSpacingControl = CParaFormat::ELineSpacingAtLeastInTwips;
3726 f.RemoveAllBorders();
3733 TRgb TLayDocTextSource::SystemColor(TUint aColorIndex,TRgb aDefaultColor) const
3736 return iCustomDraw->SystemColor(aColorIndex,aDefaultColor);
3737 else if (iFormParam)
3738 return iFormParam->SystemColor(aColorIndex,aDefaultColor);
3740 return aDefaultColor;
3743 CPicture* TLayDocTextSource::PictureL(TInt aPos) const
3745 return iLayDoc->PictureHandleL(aPos,MLayDoc::EForceLoadTrue);
3748 TInt TLayDocTextSource::GetPictureSizeInTwipsL(TInt aPos,TSize& aSize) const
3750 return iLayDoc->GetPictureSizeInTwips(aSize,aPos);
3753 TInt TLayDocTextSource::ParagraphStart(TInt aPos) const
3755 iLayDoc->LdToParagraphStart(aPos);
3759 TBool TLayDocTextSource::LabelModeSelect(TLabelType aType, TInt aPos)
3761 if (!(iFlags & EUseLabelsDevice) && aType == EParLabel)
3763 // Labels are not allowed on zero-length documents;
3764 // this is required for Agenda (see ER5U defect EDNGASR-482LSF).
3765 if (iLayDoc->LdDocumentLength() == 0)
3768 if (iLayDoc->SelectParagraphLabel(aPos))
3770 iFlags |= EUseLabelsDevice;
3778 void TLayDocTextSource::LabelMetrics(TLabelType aType, TSize& aLabelSize, TInt& aMarginSize) const
3780 if (aType == EParLabel)
3782 aLabelSize.iWidth = iLabelsWidth;
3783 aLabelSize.iHeight = KMaxTInt;
3784 aMarginSize = iLabelsWidth + iLabelsGutter;
3788 aLabelSize.iWidth = 0;
3789 aLabelSize.iHeight = 0;
3794 void TLayDocTextSource::LabelModeCancel()
3796 iLayDoc->CancelSelectLabel();
3797 iFlags &= ~EUseLabelsDevice;
3801 This method is responsible for discovering interface extension objects
3802 requried by Form for the specified interface Uid.
3804 Identifier for the optional interface requried.
3806 Pointer to object supporting the requested interface,
3807 or 0 if not supported.
3809 TAny* TLayDocTextSource::GetExtendedInterface(const TUid& aInterfaceId)
3811 TAny* interfacePtr = 0;
3813 // First check to see if their is an external interface provider
3814 // registered and ask it for the interface.
3815 if (iInterfaceProvider)
3817 interfacePtr = iInterfaceProvider->GetExtendedInterface( aInterfaceId );
3820 // If interface still not supplied check self and parent to provide it
3823 if (aInterfaceId == KFormLabelApiExtensionUid)
3825 return static_cast<MFormLabelApi*>(this);
3827 else if(aInterfaceId == KTmTextDrawExtId)
3829 return static_cast <MTmTextDrawExt*> (this);
3831 else if(aInterfaceId == KTmCustomExtensionUid)
3833 return static_cast <MTmCustomExtension*> (this);
3837 // In this instance, calling the parent class will always return NULL
3838 // but the pattern should be followed by all implementors for safety
3839 return MTmSource::GetExtendedInterface(aInterfaceId);
3843 // Return the interface object or 0 if not supported.
3844 return interfacePtr;
3847 void TLayDocTextSource::SetLineHeight(const TLineHeightParam& aParam,TInt& aAscent,TInt& aDescent) const
3849 // Increase the ascent by the font height increase percentage.
3850 TLineHeightParam p = aParam;
3851 p.iFontMaxAscent += ((p.iFontMaxAscent + p.iFontMaxDescent) * iFontHeightIncreaseFactor) / 100;
3853 // Call the standard SetLineHeight.
3854 MTmSource::SetLineHeight(p,aAscent,aDescent);
3856 // iExcessHeightRequired is used when height of the highest glyph can be
3857 // greater than CFont::AscentInPixels() and in iExactLineSpacing mode
3858 // This value is set via CTextView::SetExcessHeightRequired()
3859 if ( aParam.iExactLineHeight )
3861 aAscent += iExcessHeightRequired;
3862 aDescent -= iExcessHeightRequired;
3865 // Enforce the minimum descent; the following logic is borrowed from CLineLayout::WrapLineL in old FORM.
3866 if (aAscent + aDescent <= iMinimumLineDescent && aDescent == 0)
3871 else if (aDescent < iMinimumLineDescent)
3872 aDescent = iMinimumLineDescent;
3875 Ensure the line is at least 1 pixel high and ascent and descent are non-negative so that assertion
3876 TCursorPosition::GetLineRectL that cursor pos is contained in line rect doesn't fire.
3882 if (aAscent + aDescent == 0)
3886 TBool TLayDocTextSource::CanMap() const
3888 return iFormatMode == CLayoutData::EFScreenMode || iFormatMode == CLayoutData::EFWysiwygMode;
3891 TBool TLayDocTextSource::PageBreakInRange(TInt aStartPos,TInt aEndPos) const
3893 if (CanMap() && iNonPrintingCharVisibility.PageBreaksVisible())
3894 return iLayDoc->EnquirePageBreak(aStartPos,aEndPos - aStartPos);
3899 void TLayDocTextSource::DrawBackground(CGraphicsContext& aGc,const TPoint& aTopLeft,const TRect& aRect,
3900 const TLogicalRgb& aBackground,TRect& aDrawn) const
3905 MFormCustomDraw::TParam param(aGc,InterpretDevice(),aTopLeft,aRect);
3906 TLogicalRgb background = aBackground;
3907 FormUtil::LogicalToActualColor(iFormParam,background);
3908 iCustomDraw->DrawBackground(param,background,aDrawn);
3911 MTmSource::DrawBackground(aGc,aTopLeft,aRect,aBackground,aDrawn);
3914 void TLayDocTextSource::DrawLineGraphics(CGraphicsContext& aGc,const TPoint& aTopLeft,const TRect& aRect,
3915 const TTmLineInfo& aLineInfo) const
3920 MFormCustomDraw::TParam param(aGc,InterpretDevice(),aTopLeft,aRect);
3921 MFormCustomDraw::TLineInfo lineinfo(aLineInfo.iOuterRect,aLineInfo.iInnerRect,aLineInfo.iBaseline);
3922 iCustomDraw->DrawLineGraphics(param,lineinfo);
3925 MTmSource::DrawLineGraphics(aGc,aTopLeft,aRect,aLineInfo);
3929 void TLayDocTextSource::DrawText(CGraphicsContext& aGc,const TPoint& aTopLeft,const TRect& aRect,
3930 const TTmLineInfo& aLineInfo,const TTmCharFormat& aFormat,
3931 const TDesC& aText,const TPoint& aTextOrigin,TInt aExtraPixels) const
3936 MFormCustomDraw::TParam param(aGc,InterpretDevice(),aTopLeft,aRect);
3937 MFormCustomDraw::TLineInfo lineinfo(aLineInfo.iOuterRect,aLineInfo.iInnerRect,aLineInfo.iBaseline);
3939 aFormat.GetTCharFormat(f);
3940 iCustomDraw->DrawText(param,lineinfo,f,aText,aTextOrigin,aExtraPixels);
3943 MTmSource::DrawText(aGc,aTopLeft,aRect,aLineInfo,aFormat,aText,aTextOrigin,aExtraPixels);
3947 void TLayDocTextSource::DrawText(CGraphicsContext& aGc,const TPoint& aTopLeft,const TRect& aRect,
3948 const TTmLineInfo& aLineInfo,const TTmCharFormat& aFormat,
3949 const TDesC& aText,const TInt aStart, const TInt aEnd, const TPoint& aTextOrigin,TInt aExtraPixels) const
3954 MFormCustomDraw::TParam param(aGc,InterpretDevice(),aTopLeft,aRect);
3955 MFormCustomDraw::TLineInfo lineinfo(aLineInfo.iOuterRect,aLineInfo.iInnerRect,aLineInfo.iBaseline);
3957 aFormat.GetTCharFormat(f);
3958 iCustomDraw->DrawText(param,lineinfo,f,aText,aStart,aEnd,aTextOrigin,aExtraPixels);
3961 MTmCustomExtension::DrawText(aGc,aTopLeft,aRect,aLineInfo,aFormat,aText,aStart,aEnd,aTextOrigin,aExtraPixels);
3965 TBool TLayDocTextSource::LineBreakPossible(TUint aPrevClass,TUint aNextClass,TBool aHaveSpaces) const
3970 temp=iCustomWrap->LineBreakPossible(aPrevClass,aNextClass,aHaveSpaces);
3972 temp=MTmSource::LineBreakPossible(aPrevClass,aNextClass,aHaveSpaces);
3976 TUint TLayDocTextSource::LineBreakClass(TUint aCode,TUint& aRangeStart,TUint& aRangeEnd) const
3980 temp=iCustomWrap->LineBreakClass(aCode,aRangeStart,aRangeEnd);
3982 temp=MTmSource::LineBreakClass(aCode,aRangeStart,aRangeEnd);
3987 TBool TLayDocTextSource::GetLineBreakInContext(const TDesC& aText,TInt aMinBreakPos,TInt aMaxBreakPos,
3988 TBool aForwards,TInt& aBreakPos) const
3992 temp=iCustomWrap->GetLineBreakInContext(aText,aMinBreakPos,aMaxBreakPos,aForwards,aBreakPos);
3994 temp=MTmSource::GetLineBreakInContext(aText,aMinBreakPos,aMaxBreakPos,aForwards,aBreakPos);
3998 TBool TLayDocTextSource::IsHangingCharacter(TUint aChar) const
4002 temp=iCustomWrap->IsHangingCharacter(aChar);
4004 temp=MTmSource::IsHangingCharacter(aChar);
4009 TUint TLayDocTextSource::Map(TUint aChar) const
4011 // Check if custom formatting has been installed
4012 if (iInvisibleCharacterRemapper)
4013 { // Then use the supplied custom invisible character remapping
4014 return iInvisibleCharacterRemapper->Remap(aChar, iNonPrintingCharVisibility, *this);
4016 else // Use the default
4017 return MFormCustomInvisibleCharacterRemapper::DefaultMapping(aChar, iNonPrintingCharVisibility, *this);
4020 void TLayDocTextSource::DrawPicture(CGraphicsContext& aGc,
4021 const TPoint& aTextLayoutTopLeft, const TRect& aRect,
4022 MGraphicsDeviceMap& aDevice, const CPicture& aPicture) const
4025 MTmSource::DrawPicture(aGc, aTextLayoutTopLeft, aRect, aDevice, aPicture);
4029 //MTmTextDrawExt implementations
4032 Draws a line. Implements MTmTextDrawExt::DrawLine().
4033 If the opaque drawing mode is active, then the line color will stay unchanged (it will not be
4034 alpha-blended in a case of a transparent window).
4035 @param aGc A reference to a graphics context. If the drawing mode is opaque, then this is a
4036 CWindowGc reference.
4037 @param aPt1 Line start point
4038 @param aPt2 Line end point
4040 void TLayDocTextSource::DrawLine(CGraphicsContext& aGc, const TPoint& aPt1, const TPoint& aPt2) const
4043 aGc.DrawLine(aPt1, aPt2);
4048 Draws a text. Implements MTmTextDrawExt::DrawText().
4049 If the opaque drawing mode is active, then the text color will stay unchanged (it will not be
4050 alpha-blended in a case of a transparent window).
4051 @param aGc A reference to a graphics context. If the drawing mode is opaqe, then this is a
4052 CWindowGc reference.
4053 @param aPt1 Text start point
4055 void TLayDocTextSource::DrawText(CGraphicsContext& aGc, const TDesC& aText, const TPoint& aPt) const
4058 aGc.DrawText(aText, aPt);
4063 Draws a rectangle. Implements MTmTextDrawExt::DrawRect().
4064 If the opaque drawing mode is active, then the rectabgle color will stay unchanged (it will not be
4065 alpha-blended in a case of a transparent window).
4066 @param aGc A reference to a graphics context. If the drawing mode is opaqe, then this is a
4067 CWindowGc reference.
4068 @param aRc Rectangle coordinates
4070 void TLayDocTextSource::DrawRect(CGraphicsContext& aGc, const TRect& aRc) const
4078 Sets opaque drawing mode.
4079 @param aGc A reference to a graphics context. If the drawing mode is opaqe, then this is a
4080 CWindowGc reference.
4082 void TLayDocTextSource::SetOpaque(CGraphicsContext& aGc) const
4086 static_cast <CWindowGc&> (aGc).SetOpaque(ETrue);
4091 Resets opaque drawing mode.
4092 @param aGc A reference to a graphics context. If the drawing mode is opaqe, then this is a
4093 CWindowGc reference.
4095 void TLayDocTextSource::ResetOpaque(CGraphicsContext& aGc) const
4099 static_cast <CWindowGc&> (aGc).SetOpaque(EFalse);
4103 // Private CTextLayout functions start here.
4105 void CTextLayout::Panic(TPanicNumber aNumber)
4107 _LIT(KPanicNumber,"CTextLayout using TAGMA");
4108 User::Panic(KPanicNumber,aNumber);
4111 void CTextLayout::GetParagraphRect(const TTmDocPos& aDocPos,TRect& aRect) const
4113 aRect.SetRect(0,0,0,0);
4114 TTmLineInfo info, info2;
4115 if (!iText->DocPosToLine(aDocPos,info))
4117 aRect = info.iOuterRect;
4118 if (!(info.iFlags & TTmLineInfo::EParStart))
4120 iText->ParNumberToLine(info.iParNumber,0,info2);
4121 aRect.iTl = info2.iOuterRect.iTl;
4123 if (!(info.iFlags & TTmLineInfo::EParEnd))
4125 iText->ParNumberToLine(info.iParNumber,KMaxTInt,info2);
4126 aRect.iBr = info2.iOuterRect.iBr;
4128 aRect.Move(0,-iBandTop);
4132 Scroll aDy pixels (positive = text moves down); return number of pixels
4133 actually scrolled. Create a new formatted band if necessary.
4135 TInt CTextLayout::ScrollL(TInt aDy,TAllowDisallow aScrollBlankSpace,
4136 TBool aTopNoLimitBorder/*=EFalse*/,
4137 TBool aBottomNoLimitBorder/*=EFalse*/)
4139 if ( EFDisallowScrollingBlankSpace == aScrollBlankSpace )
4141 aTopNoLimitBorder = EFalse;
4142 aBottomNoLimitBorder = EFalse;
4144 int old_bandtop = iBandTop;
4145 int desired_bandtop = iBandTop - aDy;
4146 int pixels_scrolled = 0;
4147 int height_increase = 0;
4148 int paragraphs_increase = 0;
4149 TTmFormatParamBase param;
4150 InitFormatParam(param);
4151 // Refuse to scroll if the width is illegal. This prevents
4152 // time being taken in certain situations where it does
4153 // not matter. Once the formatting is capable of
4154 // adding smaller chunks of text at a time, this early-out
4155 // should become unnecessary.
4156 if ((param.iWrapWidth < 1 || param.iMaxHeight < 1)
4157 && param.iFlags & TTmFormatParamBase::EWrap)
4159 param.iMaxHeight = KMaxTInt;
4160 int visible_height = VisibleHeightInPixels();
4161 if (aDy > 0) // text moves down; iBandTop decreases
4163 if (aTopNoLimitBorder)
4164 iBandTop = desired_bandtop;
4166 iBandTop = Max(0,desired_bandtop);//Disallow text scrolled beyond top border
4168 pixels_scrolled = old_bandtop - iBandTop;
4169 while (pixels_scrolled < aDy)
4171 if (!iText->AddParL(param,TRUE,height_increase,paragraphs_increase))
4173 pixels_scrolled += height_increase;
4175 if (pixels_scrolled > aDy)
4177 iBandTop = pixels_scrolled - aDy;
4178 pixels_scrolled = aDy;
4181 else if (aDy < 0) // text moves up; iBandTop increases
4183 if (aBottomNoLimitBorder)
4184 iBandTop = desired_bandtop;
4186 iBandTop = Min(iText->LayoutHeight(),desired_bandtop);//Disallow text scrolled beyond bottom border
4188 pixels_scrolled = old_bandtop - iBandTop;
4189 while (pixels_scrolled > aDy)
4191 if (!AddFormattingAtEndL(param, height_increase,paragraphs_increase))
4193 pixels_scrolled -= height_increase;
4194 if (pixels_scrolled < aDy)
4196 height_increase -= aDy - pixels_scrolled;
4197 pixels_scrolled = aDy;
4199 iBandTop += height_increase;
4202 // Fill in missing part of visible height.
4203 while (iText->LayoutHeight() - iBandTop < visible_height)
4205 if (!AddFormattingAtEndL(param, height_increase,paragraphs_increase))
4210 // Scroll blank space off the display if desired.
4211 if (aScrollBlankSpace == EFDisallowScrollingBlankSpace && iText->LayoutHeight() - iBandTop < visible_height)
4213 int new_bandtop = iText->LayoutHeight() - visible_height;
4214 if (new_bandtop < 0)
4216 pixels_scrolled += iBandTop - new_bandtop;
4217 iBandTop = new_bandtop;
4220 PruneFormatL(aDy < 0);
4221 return pixels_scrolled + SetBandTop();
4224 TInt CTextLayout::ScrollDocPosIntoViewL(const TTmDocPos& aDocPos)
4226 if (aDocPos.iPos > iText->Source()->DocumentLength())
4228 OstTrace0( TRACE_DUMP, CTEXTLAYOUT_SCROLLDOCPOSINTOVIEWL, "EInvalidDocPos" );
4230 __ASSERT_DEBUG(aDocPos.iPos <= iText->Source()->DocumentLength(),
4231 Panic(EInvalidDocPos));
4233 ExtendFormattingToCoverPosL(aDocPos.iPos);
4234 if (!iText->DocPosToLine(aDocPos,info))
4236 if (iText->Source()->DocumentLength() != 0)
4238 OstTrace0( TRACE_DUMP, DUP1_CTEXTLAYOUT_SCROLLDOCPOSINTOVIEWL, "ECharacterNotFormatted" );
4240 __ASSERT_DEBUG(iText->Source()->DocumentLength() == 0,
4241 Panic(ECharacterNotFormatted));
4242 return ScrollL(iBandTop, EFDisallowScrollingBlankSpace);
4244 TRect line_rect = info.iOuterRect;
4245 line_rect.Move(0,-iBandTop);
4246 int visible_height = VisibleHeightInPixels();
4247 // if the line is taller than the screen, we must not scroll the
4248 // baseline off the screen.
4249 if (visible_height < info.iBaseline - info.iOuterRect.iTl.iY)
4250 return ScrollL(iBandTop + visible_height - info.iBaseline,
4251 EFDisallowScrollingBlankSpace);
4252 if (line_rect.iTl.iY < 0)
4253 return ScrollL(-line_rect.iTl.iY, EFDisallowScrollingBlankSpace);
4254 if (line_rect.iBr.iY > visible_height)
4256 int available = line_rect.iTl.iY;
4257 int desired = line_rect.iBr.iY - visible_height;
4259 return ScrollL(-Min(desired,available), EFDisallowScrollingBlankSpace);
4264 EXPORT_C TInt CTextLayout::GetLineNumber(TInt aDocPos)
4267 TTmDocPos pos(aDocPos,TRUE);
4268 if (iText->DocPosToLine(pos,info))
4269 return info.iLineNumber;
4275 Prune the formatted band, if not formatting all the text, to the required size. If aFromStart is ETrue
4276 prune from the start, otherwise prune from the end.
4278 void CTextLayout::PruneFormatL(TBool aFromStart)
4280 if (IsFormattingBand())
4282 int pixels_to_prune = 0;
4284 pixels_to_prune = iBandTop;
4286 pixels_to_prune = iText->LayoutHeight() - iBandTop - BandHeightInPixels();
4287 if (pixels_to_prune <= 0)
4289 TTmFormatParamBase param;
4290 InitFormatParam(param);
4291 int height_decrease = 0;
4294 while (pixels_to_prune > 0 && iText->DeletePar(param,aFromStart,pixels_to_prune,height_decrease))
4296 pixels_to_prune -= height_decrease;
4298 iBandTop -= height_decrease;
4303 if (pixels_to_prune > (iBandHeight/2))
4305 iText->DeleteFormattingFromEndL(param,pixels_to_prune,height_decrease);
4311 /** Sets the hotspot.
4313 @param aHotSpot Which part of the line (top, baseline or bottom) should appear
4314 at a vertical pixel position. */
4315 EXPORT_C void TViewYPosQualifier::SetHotSpot(TPartOfLine aHotSpot)
4317 iHotSpot = aHotSpot;
4320 /** Sets whether blank space should be allowed at the bottom of the view. This
4321 applies if the document is more than one page long and the last line is
4324 @param aFillScreen ETrue (the default) tries to fill the screen, by ensuring
4325 that there is as little blank space as possible at the bottom of the view.
4326 EFalse allows blank space at the bottom. */
4327 EXPORT_C void TViewYPosQualifier::SetFillScreen(TBool aFillScreen)
4329 iFillScreen = aFillScreen;
4332 /** Forces the top line in the view to become fully visible if it is partially
4333 above the top of the view rectangle.
4335 @param aMakeLineFullyVisible EFViewForceLineFullyVisible (the default) forces
4336 the top line to be fully visible EFViewDontForceLineFullyVisible does not. */
4337 EXPORT_C void TViewYPosQualifier::SetMakeLineFullyVisible(TFullyVisible aMakeLineFullyVisible)
4339 iFullyVisible = aMakeLineFullyVisible;
4342 void CTextLayout::InitFormatParam(TTmFormatParamBase& aParam)
4344 aParam.iMaxHeight = BandHeightInPixels();
4345 iSource->iExcessHeightRequired = iExcessHeightRequired;
4347 aParam.iFlags = TTmFormatParamBase::EAtLeastMaxHeight;
4348 aParam.iWrapWidth = iSource->iWidth;
4349 if (iSource->iFlags & TLayDocTextSource::EWrap)
4350 aParam.iFlags |= TTmFormatParamBase::EWrap;
4351 if (iSource->iFlags & TLayDocTextSource::ETruncateWithEllipsis)
4353 aParam.iFlags |= TTmFormatParamBase::ETruncateWithEllipsis;
4354 aParam.iEllipsis = iSource->iEllipsis;
4358 TInt CTextLayout::VisibleHeightInPixels() const
4360 if (iSource->iFormatMode == CLayoutData::EFScreenMode || iSource->iFormatMode == CLayoutData::EFWysiwygMode)
4361 return iVisibleHeight;
4363 return iSource->InterpretDevice().VerticalTwipsToPixels(iVisibleHeight);
4366 TInt CTextLayout::BandHeightInPixels() const
4368 if (iBandHeight == CLayoutData::EFHeightForFormattingAllText)
4369 return CLayoutData::EFHeightForFormattingAllText;
4371 return VisibleHeightInPixels();
4375 Sets offsets for the edges of the selection highlight.
4376 @param aLeftExtension
4377 Number of pixels to move the left edge of the highlight to the left.
4378 @param aRightExtension
4379 Number of pixels to move the right edge of the highlight to the right.
4380 @param aTopExtension
4381 Number of pixels to move the top edge of the highlight to up.
4382 @param aBottomExtension
4383 Number of pixels to move the bottom edge of the highlight down.
4385 EXPORT_C void CTextLayout::SetHighlightExtensions(TInt aLeftExtension,
4386 TInt aRightExtension, TInt aTopExtension, TInt aBottomExtension)
4388 iHighlightExtensions->SetLeftExtension(aLeftExtension);
4389 iHighlightExtensions->SetRightExtension(aRightExtension);
4390 iHighlightExtensions->SetTopExtension(aTopExtension);
4391 iHighlightExtensions->SetBottomExtension(aBottomExtension);
4395 Set the delta required to position the baseline so there is enough
4396 space for the highset glyph in pixels. This is the height of the highest glyph -
4397 CFont::AscentInPixels(). Only used when using TLineSpacingControl::EAttLineSpacingControl.
4399 @param aExcessHeightRequired
4400 Extra height above CFont::AscentInPixels() required for the highest glyph in pixels.
4402 void CTextLayout::SetExcessHeightRequired(TInt aExcessHeightRequired)
4404 iExcessHeightRequired = aExcessHeightRequired;
4408 For any rectangle, aRect, which may be extended, calculate
4409 the "remainder" rectanges when the view rectangle is intersected with the
4410 extended rect and then subtracted.
4411 The remainder rectangles are returned via aRemainderRects, which is required
4412 to be a pointer to an array of 4 TRect's.
4413 aRemainderRects[0] is top remainder, ...[1] is bottom, ...[2] is left, ...[3] is right
4415 void CTextLayout::GetHighlightRemnants(const TRect& aRect, const TDrawTextLayoutContext& aDrawTextLayoutContext,
4416 TRect* aRemainderRects) const
4418 ASSERT(aRemainderRects);
4420 overlap is the portion of the view rect that aRect intersects with
4421 subtract this from the aRect, giving 4 non-overlapping remainder rectangles,
4422 aRemainderRects, any or all of which may be empty. Copied from SubtractRect in TAGMA
4424 TRect overlap(aDrawTextLayoutContext.iViewRect);
4425 overlap.Intersection(aRect);
4426 if (overlap.IsEmpty())
4427 overlap.SetRect(aRect.iTl,aRect.iTl);
4428 aRemainderRects[0] = aRect;
4429 aRemainderRects[0].iBr.iY = overlap.iTl.iY;
4430 aRemainderRects[1] = aRect;
4431 aRemainderRects[1].iTl.iY = overlap.iBr.iY;
4432 aRemainderRects[2] = overlap;
4433 aRemainderRects[2].iTl.iX = aRect.iTl.iX;
4434 aRemainderRects[2].iBr.iX = overlap.iTl.iX;
4435 aRemainderRects[3] = overlap;
4436 aRemainderRects[3].iTl.iX = overlap.iBr.iX;
4437 aRemainderRects[3].iBr.iX = aRect.iBr.iX;
4441 Cleanup method for the opaque flag.
4443 void CTextLayout::ResetOpaque(void* aThis)
4445 ASSERT(aThis != NULL);
4446 CTextLayout* p = reinterpret_cast <CTextLayout*> (aThis);
4447 p->iSource->iDrawOpaque = EFalse;
4451 Sets opaque drawing flag for CTextLayout object. It will used later when the
4452 content/background has to be drawn.
4453 Until the flag is not reseted, the opaque drawing will be used
4454 for all the content except the background - the flag has an useful meaning only for transparent
4456 A TCleanupItem object will be pushed into the Cleanup Stack, which will reset the opaque
4457 flag durring its destruction.
4459 void CTextLayout::SetOpaqueLC()
4461 iSource->iDrawOpaque = ETrue;
4462 CleanupStack::PushL(TCleanupItem(&CTextLayout::ResetOpaque, this));
4465 void FormPanic(TFormPanic aPanic)
4467 _LIT(KFormPanic,"Form");
4468 User::Panic(KFormPanic,aPanic);
4472 Default implementation of mapping invisible character to its specified alternate.
4474 Called by TLayDocTextSource::Map() unless overidden by custom mapping class.
4475 May be called by custom mapping class
4477 Invisible character to be remapped
4478 @param aNonPrintingCharVisibility
4479 Current state of flags showing visibility of invisible characters
4481 Const ref to the calling CLayDocTextSource
4483 The replacement character if remapping has taken place, else return original character
4485 EXPORT_C TUint MFormCustomInvisibleCharacterRemapper::DefaultMapping( TUint aChar, const TNonPrintingCharVisibility aNonPrintingCharVisibility, const TLayDocTextSource& aLayDoc )
4487 // If mapping special characters is possible, use the specified flags.
4488 if (!aNonPrintingCharVisibility.NoneVisible() && aLayDoc.CanMap())
4492 case CEditableText::EParagraphDelimiter:
4493 if (aNonPrintingCharVisibility.ParagraphDelimitersVisible())
4494 return KVisibleParagraphBreak;
4497 case CEditableText::ELineBreak:
4498 if (aNonPrintingCharVisibility.LineBreaksVisible())
4499 return KVisibleLineBreak;
4502 case CEditableText::ENonBreakingSpace:
4503 if (aNonPrintingCharVisibility.NonBreakingSpacesVisible())
4504 return KVisibleNonBreakSpace;
4507 case CEditableText::EPotentialHyphen:
4508 if (aNonPrintingCharVisibility.PotentialHyphensVisible())
4509 return KVisiblePotentialHyphen;
4512 case CEditableText::ENonBreakingHyphen:
4513 if (aNonPrintingCharVisibility.NonBreakingHyphensVisible())
4514 return KVisibleNonBreakHyphen;
4517 case CEditableText::ETabCharacter:
4518 if (aNonPrintingCharVisibility.TabsVisible())
4522 case CEditableText::EPictureCharacter:
4523 return KVisiblePicture;
4525 case 0x200B: // Zero Width Space: the same behaviour as 0x20, while different category from 0x20.
4526 if (aNonPrintingCharVisibility.SpacesVisible())
4527 return KVisibleSpace;
4531 For the moment, treat bidirectional controls as if they were non-break spaces, as far as visibility is
4532 concerned, and map as follows: LRE=<, RLE=>, PDF=currency symbol, LRO=left guillemet, RLO=right guillemet.
4535 if (aNonPrintingCharVisibility.NonBreakingSpacesVisible())
4539 if (aNonPrintingCharVisibility.NonBreakingSpacesVisible())
4543 if (aNonPrintingCharVisibility.NonBreakingSpacesVisible())
4547 if (aNonPrintingCharVisibility.NonBreakingSpacesVisible())
4551 if (aNonPrintingCharVisibility.NonBreakingSpacesVisible())
4556 if (aNonPrintingCharVisibility.SpacesVisible() && TChar(aChar).GetCategory() == TChar::EZsCategory)
4557 return KVisibleSpace;
4562 // If not mapping special characters, or not mapping this particular character, use the default mapping.
4563 return aLayDoc.MTmSource::Map(aChar);
4568 Allows Form clients to register an invisible character remapper object to
4569 customize the visible display of invisible characters such as paragraph marks.
4570 @param aInvisibleCharacterRemapper
4571 Pointer to custom invisible character remapper to use
4573 EXPORT_C void CTextLayout::SetCustomInvisibleCharacterRemapper( MFormCustomInvisibleCharacterRemapper* aInvisibleCharacterRemapper )
4575 iSource->iInvisibleCharacterRemapper = aInvisibleCharacterRemapper;
4579 Allows Form clients to see which character remapper object is currently
4582 EXPORT_C MFormCustomInvisibleCharacterRemapper* CTextLayout::GetCustomInvisibleCharacterRemapper()
4584 return iSource->iInvisibleCharacterRemapper;
4587 /** INC092568: CTextView::SetPendingSelection is not honoured
4588 Sets the cursor position member added for this fix that allows the text layout object
4589 to access any pending selection made by the owning text view object
4590 @param aPos:- pointer to the owning textview's iCursorPos
4592 void CTextLayout::SetTextViewCursorPos(TCursorPosition* aPos)
4594 iTextViewCursorPos = aPos;
4598 This is the function used by CTextLayout when it wants to extend the formatted range downwards.
4599 It just calls CTmTextLayout::AddParL, but restricts the maximum height of the new formatting to the
4600 band height/2. If the next paragraph is bigger than this, AddParL will only format part of that
4601 paragraph, and the formatting will end in the middle of the paragraph.
4603 TBool CTextLayout::AddFormattingAtEndL(TTmFormatParamBase& aFormatParam, TInt& aHeightIncrease, TInt& aParagraphsIncrease)
4605 aFormatParam.iMaxHeight = iBandHeight/2;
4606 return iText->AddParL(aFormatParam, EFalse, aHeightIncrease, aParagraphsIncrease);
4610 Stops or allows text to be drawn. Included to allow users to control visibility
4611 if text is part of an invisible control.
4613 @param aVisible ETrue to make the text visible, EFalse to make it invisible.
4614 @see CCoeControl::MakeVisible()
4616 EXPORT_C void CTextLayout::MakeVisible(TBool aVisible)
4618 iText->MakeVisible(aVisible);