textrendering/textformatting/tbox/LAYEMU.CPP
changeset 0 1fb32624e06b
child 1 e96e8a131979
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/textrendering/textformatting/tbox/LAYEMU.CPP	Tue Feb 02 02:02:46 2010 +0200
@@ -0,0 +1,4463 @@
+/*
+* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+* CTextLayout implementation using the TAGMA text formatting system.
+*
+*/
+
+
+#include <txtlaydc.h>
+#include "FRMTLAY.H"
+#include "FRMCONST.H"
+#include "FORMUTIL.H"
+
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include "FRMCONST_INTERNAL.H"
+#include "FRMCONST_PARTNER.H"
+#include "TAGMA_INTERNAL.H"
+#include "FRMTLAY_INTERNAL.H"
+#endif
+
+const TInt KMaxExtraLines = 10; // maximum number of lines to format after the current and following lines
+								// before using background formatting
+// during page down/up, the number of lines that should remain visible after
+// the scroll, counting from the first line that is not completely visible.
+// i.e. setting this to 0 means always scroll KMaxProportionOfScreenToScroll.
+// setting it to 1 means make sure that no lines are ever both partially off the
+// top/bottom before the scroll and partially visible off the bottom/top after
+// the scroll.
+// setting it to any number higher means keep that number -1 lines completely
+// visible before and after the scroll.
+const TInt KNumberOfLinesToKeepVisibleDuringScroll = 2;
+/** maximum scroll proportions in thousandths. This overrides
+ the KNumberOfLinesToKeepVisibleDuringScroll constant.*/
+const TInt KMaxProportionOfScreenToScroll = 1000;
+/** minimum scroll proportions in thousandths. This overrides
+ the KNumberOfLinesToKeepVisibleDuringScroll constant.*/
+const TInt KMinProportionOfScreenToScroll = 600;
+
+/**
+Tests for a high surrogate.
+@param a UTF16 value.
+@return ETrue if argument is a high surrogate.
+@internalComponent
+*/
+inline TBool IsHighSurrogate(TText a) { return 0xD800 == (a & 0xFC00); }
+/**
+Tests for a low surrogate.
+@param a UTF16 value.
+@return ETrue if argument is a high surrogate.
+@internalComponent
+*/
+inline TBool IsLowSurrogate(TText a) { return 0xDC00 == (a & 0xFC00); }
+/**
+Adds a high surrogate to a low surrogate to create a supplementary character.
+@param aHigh UTF16 high surrogate.
+@param aLow UTF16 low surrogate.
+@return Supplementary character represented by the pair <aHigh, aLow>.
+@pre aHigh is a high surrogate and aLow is a low surrogate.
+@internalComponent
+*/
+inline TChar PairSurrogates(TText aHigh, TText aLow)
+	{
+	return ((aHigh - 0xd7f7) << 10) + aLow;
+	}
+
+/**
+Constructs an iterator over the text referenced by aSource.
+@param aSource The source of the text to be iterated over.
+*/
+CTextLayout::TUtf32SourceCache::TUtf32SourceCache(const MTmSource& aSource)
+	: iSource(&aSource), iCurrentViewIndex(-1)
+	{
+	}
+
+/**
+Constructs an iterator over the text formatted by aLayout.
+@param aLayout The formatter of the text to be iterated over.
+*/
+CTextLayout::TUtf32SourceCache::TUtf32SourceCache(const CTextLayout& aLayout)
+	: iSource(aLayout.iSource), iCurrentViewIndex(-1)
+	{
+	}
+
+/**
+Gets the specified character without uniting surrogate pairs.
+@param aIndex The document position to retrieve.
+@pre 0 <= aIndex && aIndex < {document length}
+*/
+TText CTextLayout::TUtf32SourceCache::GetUtf16(TInt aIndex)
+	{
+	TTmCharFormat dummy;
+	if (aIndex < iCurrentViewIndex)
+		{
+		iCurrentViewIndex = 0;
+		iSource->GetText(iCurrentViewIndex, iCurrentView, dummy);
+		}
+	TInt currentViewEnd = iCurrentViewIndex + iCurrentView.Length();
+	while (currentViewEnd <= aIndex)
+		{
+		TInt difference = aIndex - iCurrentViewIndex;
+		TInt newIndex = aIndex - (difference >> 1);
+		iCurrentViewIndex = newIndex < currentViewEnd?
+			currentViewEnd : newIndex;
+		iSource->GetText(iCurrentViewIndex, iCurrentView, dummy);
+		currentViewEnd = iCurrentViewIndex + iCurrentView.Length();
+		}
+	return iCurrentView[aIndex - iCurrentViewIndex];
+	}
+
+/**
+Gets the specified character, uniting surrogate pairs if appropriate.
+@param aIndex
+	The document position to retrive.
+@return
+	The character at position aIndex. If aIndex is at the first code of a
+	surrogate pair, the full character is returned. If it is the second of a
+	valid surrogate pair or an unpaired surrogate, the surrogate is returned.
+*/
+TChar CTextLayout::TUtf32SourceCache::GetUtf32(TInt aIndex)
+	{
+	TText code = GetUtf16(aIndex);
+	if (IsHighSurrogate(code) && iSource->DocumentLength() < aIndex + 1)
+		{
+		TText code2 = GetUtf16(aIndex + 1);
+		if (IsLowSurrogate(code2))
+			return PairSurrogates(code, code2);
+		}
+	return code;
+	}
+
+/** Allocates and constructs a CTextLayout object. By default, the formatting
+is set to the entire document (EFFormatAllText).
+
+The text needs to be reformatted after a call to this function.
+
+@param aDoc Pointer to the MLayDoc implementation that is the source of the
+text and formatting information. Must not be NULL or a panic occurs.
+@param aWrapWidth The wrapping width in pixels.
+@return Pointer to the new CTextLayout object. */
+EXPORT_C CTextLayout *CTextLayout::NewL(MLayDoc *aLayDoc,TInt aWrapWidth)
+	{
+	CTextLayout* t = new(ELeave) CTextLayout;
+	CleanupStack::PushL(t);
+	t->ConstructL(aLayDoc,aWrapWidth);
+	CleanupStack::Pop();
+	return t;
+	}
+
+EXPORT_C CTextLayout::CTextLayout():
+	iText(NULL),
+	iExcessHeightRequired(0),
+	iWnd(NULL),
+	iBeginRedrawCount(0),
+	iRedrawRect(),
+	iTextViewCursorPos(NULL),
+	iIsWndInExternalRedraw(EFalse),
+	iUnformattedStart(KMaxTInt),
+	iHighlightExtensions(NULL),
+	iSource(NULL)
+	{
+	}
+
+/** Constructs an object with a text source of aLayDoc and a wrap width of
+aWrapWidth, with wrapping turned on.
+*/
+EXPORT_C void CTextLayout::ConstructL(MLayDoc *aLayDoc,TInt aWrapWidth)
+	{
+	iHighlightExtensions = new(ELeave) TTmHighlightExtensions;
+	CleanupStack::PushL(iHighlightExtensions);
+	iHighlightExtensions->SetAll(0);
+	
+	iText = new(ELeave) CTmTextLayout;
+	CleanupStack::PushL(iHighlightExtensions);
+	
+	iSource = new(ELeave) TLayDocTextSource;
+	iSource->iLayDoc = aLayDoc;
+	SetWrapWidth(aWrapWidth);
+	SetAmountToFormat(EFFormatAllText);
+	
+	CleanupStack::Pop(2);
+	}
+
+EXPORT_C CTextLayout::~CTextLayout()
+	{
+	delete iHighlightExtensions;
+	iHighlightExtensions = NULL;
+	delete iText;
+	iText = NULL;
+	delete iSource;
+	iSource = NULL;
+	}
+
+void CTextLayout::SetWindow(RWindow* aWnd)
+	{
+	iWnd = aWnd;
+	}
+
+void CTextLayout::SetReadyToRedraw()
+	{
+	iReadyToRedraw = ETrue;
+	}
+
+void CTextLayout::BeginRedraw(const TRect& aRect)
+	{
+	if(!iReadyToRedraw)
+		return;
+	
+	if (0 == iBeginRedrawCount++)
+		{
+		iRedrawRect = aRect;
+		if (NULL != iWnd)
+			{
+			if (iWnd->GetDrawRect() == TRect::EUninitialized)
+				{
+				iWnd->Invalidate(aRect);
+				iWnd->BeginRedraw(aRect);
+				}
+				else
+					iIsWndInExternalRedraw = ETrue;
+			}
+		}
+	}
+
+void CTextLayout::EndRedraw()
+	{
+	if(!iReadyToRedraw)
+		return;
+
+	__ASSERT_ALWAYS(iBeginRedrawCount > 0, Panic(EInvalidRedraw));
+
+	if (0 == --iBeginRedrawCount)
+		{
+		if (NULL != iWnd)
+			{
+			if (!iIsWndInExternalRedraw)
+				{
+				iWnd->EndRedraw();
+				iRedrawRect = TRect();
+				}
+				else
+					iIsWndInExternalRedraw = EFalse;
+			}
+		}
+	}
+
+void CTextLayout::SetExternalDraw(const TRect& aRect)
+	{
+	__ASSERT_ALWAYS(0 == iBeginRedrawCount, Panic(EInvalidRedraw));
+	iBeginRedrawCount++;
+	iRedrawRect = aRect;
+	}
+
+void CTextLayout::ResetExternalDraw()
+	{
+	__ASSERT_ALWAYS(1 == iBeginRedrawCount, Panic(EInvalidRedraw));
+
+	iBeginRedrawCount--;
+	iRedrawRect = TRect();
+	}
+
+TBool CTextLayout::BeginRedrawCalled() const
+	{
+	return iBeginRedrawCount > 0;
+	}
+
+
+/** Discards all formatting information. This function is used by the CTextView
+and the printing classes, but should be called by higher-level classes that
+need to clean up after any CTextLayout function has caused an out-of-memory
+exception. */
+EXPORT_C void CTextLayout::DiscardFormat()
+	{
+	iText->Clear();
+	iBandTop = 0;
+	}
+
+TInt CTextLayout::SetBandTop()
+	{
+	TInt originalBandTop = iBandTop;
+	if (iScrollFlags & EFScrollOnlyToTopsOfLines)
+		{
+		TTmLineInfo line;
+		if (iText->YPosToLine(iBandTop, line))
+			iBandTop = line.iOuterRect.iTl.iY;
+		}
+	return originalBandTop - iBandTop;
+	}
+
+/** Sets the layout object's source text to aDoc.
+
+The text needs to be reformatted after a call to this function.
+
+@param aDoc Pointer to the MLayDoc implementation that is the source of the
+text and formatting information. Must not be NULL or a panic occurs. */
+EXPORT_C void CTextLayout::SetLayDoc(MLayDoc *aLayDoc)
+	{
+	iSource->iLayDoc = aLayDoc;
+	}
+
+/** Sets the wrap width. If the current format mode is screen mode
+(CLayoutData::EFScreenMode) aWrapWidth is in pixels, otherwise it is in twips.
+
+The text needs to be reformatted after a call to this function.
+
+Note:
+
+A valid wrap width (>0) must be supplied or the expected amount of formatting will 
+not take place. This could lead to panics when trying to retrieve formatting 
+information that does not exist.
+
+@param aWrapWidth The wrap width in pixels or twips. */
+EXPORT_C void CTextLayout::SetWrapWidth(TInt aWrapWidth)
+	{
+	if (iSource->iFormatMode == CLayoutData::EFScreenMode)
+		iSource->iWidth = aWrapWidth;
+	else
+		iSource->iWidth = iSource->iFormatDevice->HorizontalTwipsToPixels(aWrapWidth);
+	}
+
+/** Sets the height of the band in pixels or twips. This is the height of the
+visible text, or the view window, and it is also the page height for the
+purposes of scrolling up and down by page. If the current mode is screen mode 
+(CLayoutData::EFScreenMode) or what-you-see-is-what-you-get mode 
+(CLayoutData::EFWysiwygMode), aHeight is in pixels, otherwise it is in twips.
+
+The text needs to be reformatted after a call to this function. 
+
+Note:
+
+A valid band height (>0) must be supplied or the expected amount of formatting will 
+not take place. This could lead to panics when trying to retrieve formatting 
+information that does not exist.
+
+@param aHeight The band height in pixels or twips. */
+EXPORT_C void CTextLayout::SetBandHeight(TInt aHeight)
+	{
+	iVisibleHeight = aHeight;
+	if (iBandHeight != CLayoutData::EFHeightForFormattingAllText || aHeight < 1)
+		iBandHeight = aHeight;
+	}
+
+/** Gets the height of the band in pixels or twips.
+@return The height of the band in pixels or twips. */
+EXPORT_C TInt CTextLayout::BandHeight() const
+	{
+	return VisibleHeightInPixels();
+	}
+
+/** Sets the device map used for drawing and formatting. This device map is
+also used for formatting and drawing paragraph labels unless a separate label
+device map has been set (see SetLabelsDeviceMap()).
+
+The text needs to be reformatted after a call to this function.
+
+Note:
+
+Although the name of the function suggests that only the image device is set,
+the formatting device is also set.
+
+@param aGd The device map used for drawing and formatting. */
+EXPORT_C void CTextLayout::SetImageDeviceMap(MGraphicsDeviceMap *aDeviceMap)
+	{
+	iSource->iImageDevice = aDeviceMap;
+	iSource->iFormatDevice = aDeviceMap;
+	}
+
+/** Sets the device map used for formatting and drawing paragraph labels. If
+not set, the device map used for labels will be the same as that used for the
+text.
+
+The text needs to be reformatted after a call to this function.
+
+@param aDeviceMap The device map used for formatting and drawing paragraph
+labels. */
+EXPORT_C void CTextLayout::SetLabelsDeviceMap(MGraphicsDeviceMap *aDeviceMap)
+	{
+	iSource->iLabelsDevice = aDeviceMap;
+	}
+
+/** Sets whether to format all the text (if aAmountOfFormat is
+EFFormatAllText), or just the visible band (if aAmountOfFormat is
+EFFormatBand). If band formatting is selected, enough text is formatted to fill
+the visible height.
+
+The text needs to be reformatted after a call to this function.
+
+@param aAmountOfFormat CTextLayout::EFFormatBand (the default) to format the
+visible text only. CTextLayout::EFFormatAllText to format all the text in the
+document. */
+EXPORT_C void CTextLayout::SetAmountToFormat(TAmountFormatted aAmountOfFormat)
+	{
+	if (aAmountOfFormat == EFFormatBand)
+		iBandHeight = iVisibleHeight;
+	else
+		iBandHeight = CLayoutData::EFHeightForFormattingAllText;
+	}
+
+/** Tests whether band formatting is on, as set by
+CTextLayout::SetAmountToFormat().
+@return ETrue if band formatting is on, EFalse if not. */
+EXPORT_C TBool CTextLayout::IsFormattingBand() const
+	{
+	return iBandHeight != CLayoutData::EFHeightForFormattingAllText;
+	}
+
+/** Sets the format mode and wrap width and (for certain format modes only)
+sets the formatting device.
+
+The text needs to be reformatted after a call to this function.
+
+Notes:
+
+If aFormatMode is CLayoutData::EFWysiwygMode or
+CLayoutData::EFPrintPreviewMode, the format device is set to aFormatDevice,
+which must not be NULL.
+
+If aFormatMode is CLayoutData::EFScreenMode or CLayoutData::EFPrintMode,
+aFormatDevice is ignored and should be NULL; the format device is set to the
+image device.
+
+The wrap width is set in either twips or pixels using the same rule as for
+SetWrapWidth().
+
+@param aFormatMode The format mode.
+@param aWrapWidth The wrap width in pixels or twips.
+@param aFormatDevice The formatting device or NULL, depending on the format
+mode. */
+EXPORT_C void CTextLayout::SetFormatMode(CLayoutData::TFormatMode aFormatMode,TInt aWrapWidth,
+										 MGraphicsDeviceMap* aFormatDevice)
+	{
+	if (aFormatMode == CLayoutData::EFWysiwygMode || aFormatMode == CLayoutData::EFPrintPreviewMode)
+		{
+		__ASSERT_ALWAYS(aFormatDevice != NULL,Panic(EFormatDeviceNotSet));
+		iSource->iFormatDevice = aFormatDevice;
+		}
+	else
+		iSource->iFormatDevice = iSource->iImageDevice;
+	iSource->iFormatMode = aFormatMode;
+	SetWrapWidth(aWrapWidth);
+	}
+
+/** Turns wrapping on (if aNoWrapping is EFParagraphsWrappedByDefault) or off
+(if aNoWrapping is EFAllParagraphsNotWrapped). Overrides the paragraph format
+when wrapping is turned off -paragraphs are not broken into lines even if the
+iWrap member of CParaFormat is ETrue. If wrapping is turned on,
+CParaFormat::iWrap is honoured.
+
+The text needs to be reformatted after a call to this function.
+
+@param aNoWrapping EFAllParagraphsNotWrapped (the default) to turn wrapping
+off, EFParagraphsWrappedByDefault to turn wrapping on. */
+EXPORT_C void CTextLayout::ForceNoWrapping(TBool aNoWrapping)
+	{
+	if (aNoWrapping)
+		iSource->iFlags &= ~TLayDocTextSource::EWrap;
+	else
+		iSource->iFlags |= TLayDocTextSource::EWrap;
+	}
+
+/** Tests whether wrapping is on or off.
+@return ETrue if wrapping is on, EFalse if off. */
+EXPORT_C TBool CTextLayout::IsWrapping() const
+	{
+	return (iSource->iFlags & TLayDocTextSource::EWrap) != 0;
+	}
+
+/** Sets the truncation mode. If truncation is on, lines that exceed the wrap
+width, either because they have no legal line break, or because wrapping is
+off, are truncated, and an ellipsis is inserted.
+
+@param aOn If ETrue, lines which extend beyond the wrap width are truncated
+with an ellipsis character. If EFalse, no ellipsis is used. */
+EXPORT_C void CTextLayout::SetTruncating(TBool aOn)
+	{
+	if (aOn)
+		iSource->iFlags |= TLayDocTextSource::ETruncateWithEllipsis;
+	else
+		iSource->iFlags &= ~TLayDocTextSource::ETruncateWithEllipsis;
+	}
+
+/** Tests whether truncation is on (as set by SetTruncating()).
+@return ETrue if truncation is on, EFalse if not. */
+EXPORT_C TBool CTextLayout::Truncating() const
+	{
+	return (iSource->iFlags & TLayDocTextSource::ETruncateWithEllipsis) != 0;
+	}
+
+/** Sets the ellipsis character to be used if truncation is on. Specify the
+value 0xFFFF (the illegal Unicode character) if no ellipsis character should
+be used. By default, the ellipsis character is 0x2026, the ordinary horizontal
+ellipsis.
+
+@param aEllipsis The Unicode value of the truncating ellipsis character. */
+EXPORT_C void CTextLayout::SetTruncatingEllipsis(TChar aEllipsis)
+	{
+	iSource->iEllipsis = aEllipsis;
+	}
+
+/** Returns the ellipsis character used when truncation is on. The value 0xFFFF
+(the illegal Unicode character) means that no ellipsis character is appended to
+truncated text.
+
+@return The Unicode value of the truncating ellipsis character. */
+EXPORT_C TChar CTextLayout::TruncatingEllipsis() const
+	{
+	return iSource->iEllipsis;
+	}
+
+/** Sets the width in pixels of the margin in which labels are drawn.
+
+The text needs to be reformatted after a call to this function.
+
+@param aWidth The width in pixels of the labels margin. */
+EXPORT_C void CTextLayout::SetLabelsMarginWidth(TInt aWidth)
+	{
+	iSource->iLabelsWidth = aWidth;
+	}
+
+/** Specifies which non-printing characters (e.g. space, paragraph break, etc.)
+are to be drawn using symbols.
+
+The text needs to be reformatted after a call to this function.(because
+non-printing characters may differ in width from their visible
+representations).
+
+@param aVisibility Indicates which non-printing characters are drawn using
+symbols. */
+EXPORT_C void CTextLayout::SetNonPrintingCharsVisibility(TNonPrintingCharVisibility aVisibility)
+	{
+	iSource->iNonPrintingCharVisibility = aVisibility;
+	}
+
+/** Returns which non-printing characters are drawn using symbols.
+@return Indicates which non-printing characters are drawn using symbols. */
+EXPORT_C TNonPrintingCharVisibility CTextLayout::NonPrintingCharsVisibility() const
+	{
+	return iSource->iNonPrintingCharVisibility;
+	}
+
+/** Tests whether background formatting is currently taking place. Background
+formatting is managed by CTextView, using an active object, when the
+CTextLayout object is owned by a CTextView object.
+
+Not generally useful.
+
+@return ETrue if background formatting is currently taking place. EFalse if not.
+*/
+EXPORT_C TBool CTextLayout::IsBackgroundFormatting() const
+	{
+	return iUnformattedStart < KMaxTInt;
+	}
+
+/** CTextView calls this function when background formatting has ended. It
+allows the CTextLayout object to discard information used only during
+background formatting.
+
+Not generally useful. */
+EXPORT_C void CTextLayout::NotifyTerminateBackgroundFormatting()
+	{
+	iUnformattedStart = KMaxTInt;
+	}
+
+
+/** Specifies whether partially displayed lines (at the top and bottom of
+the view) are to be prevented from being drawn, and whether the top of
+the display is to be aligned to the nearest line.
+
+This function takes effect only when the text is next formatted or
+scrolled.Note:This function was designed for non-editable text in the
+Agenda application, and there is an important restriction:
+CTextView functions that reformat the text after editing must not be used
+while partial lines are excluded; these functions are 
+CTextView::HandleCharEditL(),
+CTextView::HandleInsertDeleteL() and
+CTextView::HandleRangeFormatChangeL().
+
+@param aExcludePartialLines ETrue (the default) to exclude partially
+displayed lines from the view. EFalse to include them.
+@deprecated 7.0 */
+//It did not work, and it was not what the customer wanted. A more comprehensive
+//solution is being considered.
+EXPORT_C void CTextLayout::SetExcludePartialLines(TBool) {}
+
+/** Tests whether partial lines at the top and bottom of the view are
+currently excluded.
+
+@return ETrue if partial lines are excluded, EFalse if they are displayed.
+@deprecated 7.0 */
+EXPORT_C TBool CTextLayout::ExcludingPartialLines() const
+	{
+	return EFalse;
+	}
+ 
+/** Sets the percentage by which font heights are increased in order to provide
+automatic extra spacing (leading) between lines. This amount is set to
+CLayoutData::EFFontHeightIncreaseFactor, which is 7, when a CTextLayout object
+is created.
+
+The text needs to be reformatted after a call to this function.
+
+@param aPercentage Factor by which to increase font heights. */
+EXPORT_C void CTextLayout::SetFontHeightIncreaseFactor(TInt aPercentage)
+	{
+	iSource->iFontHeightIncreaseFactor = aPercentage;
+	}
+
+/** Returns the font height increase factor as a percentage (i.e. a return
+value of 7 means that font heights are increased by 7% to provide automatic
+extra spacing between lines).
+
+@return Factor by which font heights are increased. */
+EXPORT_C TInt CTextLayout::FontHeightIncreaseFactor() const
+	{
+	return iSource->iFontHeightIncreaseFactor;
+	}
+
+/** Sets the minimum line descent in pixels. This amount is set to
+CLayoutData::EFMinimumLineDescent, which is 3, when a CTextLayout object is
+created.
+
+The text needs to be reformatted after a call to this function.
+
+@param aPixels The minimum line descent in pixels. */
+EXPORT_C void CTextLayout::SetMinimumLineDescent(TInt aPixels)
+	{
+	iSource->iMinimumLineDescent = aPixels;
+	}
+
+/** Returns the minimum line descent in pixels.
+@return The minimum line descent in pixels. */
+EXPORT_C TInt CTextLayout::MinimumLineDescent() const
+	{
+	return iSource->iMinimumLineDescent;
+	}
+
+/** Returns the document length in characters, including all the text, not just
+the formatted portion, but not including the final paragraph delimiter (the
+"end-of-text character") if any. Thus the length of an empty document is zero.
+
+@return The number of characters in the document */
+EXPORT_C TInt CTextLayout::DocumentLength() const
+	{
+	return iSource->DocumentLength();
+	}
+
+/** Sets aDocPos to the paragraph start and returns the amount by which aDocPos
+has changed, as a non-negative number.
+
+@param aDocPos A document position. On return, contains the document position
+of the first character in the paragraph.
+@return The number of characters skipped in moving to the new document
+position. */
+EXPORT_C TInt CTextLayout::ToParagraphStart(TInt& aDocPos) const
+	{
+	TInt old_pos = aDocPos;
+	aDocPos = iSource->ParagraphStart(aDocPos);
+	return old_pos - aDocPos;
+	}
+
+/** Returns the height in pixels of any formatted text above the visible
+region.
+@return The height in pixels of any formatted text above the visible region. */
+EXPORT_C TInt CTextLayout::PixelsAboveBand() const
+	{
+	return iBandTop;
+	}
+
+/** Returns the y coordinate of the bottom of the last formatted line, relative
+to the top of the visible region.
+
+@return The y coordinate of the bottom of the last formatted line. */
+EXPORT_C TInt CTextLayout::YBottomLastFormattedLine() const
+	{
+	return iText->LayoutHeight() - iBandTop;
+	}
+
+/** Returns the height in pixels of the formatted text.
+
+@return The height in pixels of all the formatted text. */
+EXPORT_C TInt CTextLayout::FormattedHeightInPixels() const
+	{
+	return iText->LayoutHeight();
+	}
+
+/** Returns the number of fully or partially visible characters in the visible
+band.
+
+@param aDocPos On return, contains the document position of the first fully or
+partially visible character in the band.
+@return The total number of characters in the band. */
+EXPORT_C TInt CTextLayout::PosRangeInBand(TInt& aDocPos) const
+	{
+	TTmLineInfo info;
+	if (!iText->YPosToLine(iBandTop,info))
+		{
+		aDocPos = 0;
+		return 0;
+		}
+	aDocPos = info.iStart;
+	int end = iSource->DocumentLength();
+	//INC085809 - less 1 pixel. Rect edge is actually outside bounds
+	if (iText->YPosToLine(iBandTop + VisibleHeightInPixels() - 1,info))
+		end = info.iEnd;
+	return end - aDocPos;
+	}
+
+/** Tests whether the document position aDocPos is fully or partially visible.
+If it is, puts the y coordinate of the left-hand end of the baseline of the
+line containing aDocPos into aXyPos.
+
+@param aDocPos The document position of interest.
+@param aXyPos On return, contains the y coordinate of the left-hand end of the
+baseline of the line containing aDocPos.
+@return ETrue if the position is visible. EFalse if the position is not visible.
+*/
+EXPORT_C TBool CTextLayout::PosInBand(TInt aDocPos,TPoint& aXyPos) const
+	{
+	TTmLineInfo info;
+	TTmDocPos pos(aDocPos, ETrue);
+	TBool result = PosInBand(pos,&info);
+	aXyPos.iX = 0;
+	aXyPos.iY = info.iBaseline;
+	return result;
+	}
+
+/** Tests whether the document position aDocPos is fully or partially visible.
+If it is, puts the y coordinate of the left-hand end of the baseline of the
+line containing aDocPos into aXyPos.
+
+@param aDocPos The document position of interest.
+@param aXyPos On return, contains the y coordinate of the left-hand end of the
+baseline of the line containing aDocPos.
+@return ETrue if the position is visible. EFalse if the position is not visible.
+*/
+EXPORT_C TBool CTextLayout::PosInBand(TTmDocPos aDocPos,TPoint& aXyPos) const
+	{
+	TTmLineInfo info;
+	TBool result = PosInBand(aDocPos,&info);
+	aXyPos.iX = 0;
+	aXyPos.iY = info.iBaseline;
+	return result;
+	}
+	
+/** Tests whether the document position aDocPos is fully or partially visible.
+If it is, puts the baseline of the line containing aDocPos into aLineInfo.
+
+@param aDocPos The document position of interest.
+@param aLineInfo On return, contains the baseline of the line containing
+aDocPos.
+
+@return ETrue if the document position aDocPos is fully or partially visible. If
+so, and if aLineInfo is non-NULL, puts information about the line in aLineInfo.
+Otherwise, EFalse */
+EXPORT_C TBool CTextLayout::PosInBand(const TTmDocPos& aDocPos,TTmLineInfo* aLineInfo) const
+	{
+	TTmLineInfo dummy;
+	TTmLineInfo* info_ptr = aLineInfo ? aLineInfo : &dummy;
+	TTagmaForwarder forwarder(*this);
+	if (!forwarder.DocPosToLine(aDocPos,*info_ptr))
+		return FALSE;
+	return info_ptr->iOuterRect.iBr.iY > 0 && info_ptr->iOuterRect.iTl.iY < VisibleHeightInPixels();
+	}
+
+/** Tests whether the character aDocPos is formatted.
+
+Note:
+
+If a section of text contains characters p to q, it contains document positions
+p to q + 1; but this function returns ETrue for positions p to q only, so it
+refers to characters, not positions. However, it will return ETrue for q if q is
+the end of the document.
+
+@param aDocPos The document position of interest.
+@return ETrue if the character at the document position specified is formatted.
+EFalse if not. */
+EXPORT_C TBool CTextLayout::PosIsFormatted(TInt aDocPos) const
+	{
+	if (aDocPos < iText->StartChar())
+		return FALSE;
+	if (aDocPos >= iText->StartChar() + FormattedLength())
+		return FALSE;
+	return TRUE;
+	}
+
+/** Gets the document position of the first character in the specified line,
+counting the first line as line one (not zero) in the band. If the line is
+after the band, returns the last character position of the band. If there is no
+formatted text, returns CTextLayout::EFNoCurrentFormat.
+
+@param aLineNo Line number in formatted text, counting the first line as line
+one.
+@return The document position of the first character on the line. */
+EXPORT_C TInt CTextLayout::FirstCharOnLine(TInt aLineNo) const
+	{
+	__ASSERT_DEBUG(aLineNo > 0,Panic(EInvalidLineNumber));
+	if (iText->StartChar() == iText->EndChar())
+		return EFNoCurrentFormat;
+	aLineNo--;
+	TTmLineInfo info;
+	if (!iText->LineNumberToLine(aLineNo,info))
+		return Min(iText->EndChar(),iSource->DocumentLength());
+	return info.iStart;
+	}
+
+/** Returns the number of formatted characters. This will be one more than
+expected if the formatted text runs to the end of the document, because it will
+include the end-of-text character.
+
+@return The number of formatted characters in the document. */
+EXPORT_C TInt CTextLayout::FormattedLength() const
+	{
+	return iText->EndChar() - iText->StartChar();
+	}
+
+/** Returns the document position of the first formatted character.
+
+@return The document position of the first formatted character. */
+EXPORT_C TInt CTextLayout::FirstFormattedPos() const
+	{
+	return iText->StartChar();
+	}
+
+/** Gets the number of formatted lines.
+
+@return The number of formatted lines in the document. */
+EXPORT_C TInt CTextLayout::NumFormattedLines() const
+	{
+	return iText->Lines();
+	}
+
+/** Returns the line number, counting from 0, of the first fully visible line.
+
+@return The line number of the first fully visible line. */
+EXPORT_C TInt CTextLayout::FirstLineInBand() const
+	{
+	TTmLineInfo info;
+	if (!iText->YPosToLine(iBandTop,info))
+		return 0;
+	int line = info.iLineNumber;
+	if (info.iOuterRect.iTl.iY < iBandTop)
+		line++;
+	return line;
+	}
+
+/** Gets the rectangle enclosing the formatted line that contains or is closest
+to y coordinate aYPos. If aYPos is above the first formatted line, the
+rectangle returned is that of the first formatted line. If aYPos is below the
+last formatted line the rectangle returned is that of the last formatted line.
+If there is no formatted text, returns CTextLayout::EFNoCurrentFormat.
+
+@param aYPos The y coordinate of the line of interest.
+@param aLine On return, contains the rectangle which encloses the line at
+aYPos.
+
+@return The line width in pixels. */
+EXPORT_C TInt CTextLayout::GetLineRect(TInt aYPos,TRect& aRect) const
+	{
+	int y = iBandTop + aYPos;
+
+	// Snap to formatted area.
+	if (y >= iText->LayoutHeight())
+		y = iText->LayoutHeight() - 1;
+	if (y < 0)
+		y = 0;
+
+	TTmLineInfo info;
+	TBool found = iText->YPosToLine(y,info);
+	if (!found)
+		{
+		aRect.SetSize(TSize(0,0));
+		return EFNoCurrentFormat;
+		}
+
+	aRect = info.iOuterRect;
+	aRect.iTl.iX = info.iInnerRect.iTl.iX;
+	aRect.iBr.iX = info.iInnerRect.iBr.iX;
+	aRect.Move(0,-iBandTop);
+	return aRect.Width();
+	}
+
+/** Returns the height of the paragraph containing aDocPos. If the paragraph is
+not formatted, returns zero. If the paragraph is partially formatted, returns
+the height of the formatted part.
+
+@param aDocPos A document position within the paragraph of interest.
+@return The height in pixels of the paragraph. Zero if the paragraph is not
+formatted. */
+EXPORT_C TInt CTextLayout::ParagraphHeight(TInt aDocPos) const
+	{
+	TRect r;
+	GetParagraphRect(TTmDocPos(aDocPos, ETrue), r);
+	return r.Height();
+	}
+
+/** Returns the rectangle enclosing the paragraph containing aDocPos. If the
+paragraph is not formatted, returns an empty rectangle. If the paragraph is
+partially formatted, returns the rectangle enclosing the formatted part.
+
+@param aDocPos A document position within the paragraph.
+@return The rectangle which encloses the paragraph containing aDocPos. */
+EXPORT_C TRect CTextLayout::ParagraphRectL(TInt aDocPos) const
+	{	
+	TRect r;
+	GetParagraphRect(TTmDocPos(aDocPos, ETrue), r);
+	return r;
+	}
+
+/** Returns the left and right extremes, in layout coordinates, of the
+formatted text.
+
+@param aLeftX On return, contains the x coordinate of the leftmost point of the
+formatted text.
+@param aRightX On return, contains the x coordinate of the rightmost point of
+the formatted text.
+@param aOnlyVisibleLines If ETrue, only scans partially or fully visible lines.
+If EFalse, scans all the formatted text.
+@param aIgnoreWrapCharacters If ETrue, does not include wrap characters in the
+measurement (paragraph delimiters, forced line breaks, etc.). If EFalse,
+includes them.
+@return EFalse if there is no formatted text, otherwise ETrue. */
+EXPORT_C TBool CTextLayout::CalculateHorizontalExtremesL(TInt& aLeftX,TInt& aRightX,
+														 TBool aOnlyVisibleLines,
+														 TBool /*aIgnoreWrapCharacters*/) const
+	{
+	return CalculateHorizontalExtremes(aLeftX,aRightX,aOnlyVisibleLines);
+	//+ implement aIgnoreWrapCharacters? not until clearly specified
+	}
+
+TBool CTextLayout::CalculateHorizontalExtremes(TInt& aLeftX,TInt& aRightX,
+											   TBool aOnlyVisibleLines) const
+	{
+	int top = 0;
+	int bottom = KMaxTInt;
+	if (aOnlyVisibleLines)
+		{
+		top = iBandTop;
+		bottom = iBandTop + VisibleHeightInPixels();
+		}
+	iText->HorizontalExtremes(aLeftX, aRightX, top, bottom);
+	if (0 < aLeftX)
+		aLeftX = 0;
+	if (aRightX < iSource->iWidth)
+		aRightX = iSource->iWidth;
+	return iText->StartChar() < iText->EndChar();
+	}
+
+TInt CTextLayout::WrapWidth() const
+	{
+	return iSource->iWidth;
+	}
+
+TBool CTextLayout::GetCursor(const TTmDocPos& aDocPos,TTmCursorPlacement aPlacement,
+							 TRect& aLineRect,TPoint& aOrigin,TInt& aWidth,TInt& aAscent,TInt& aDescent) const
+	{
+	TTmLineInfo info;
+	TBool result = iText->GetCursor(aDocPos,aPlacement,info,aOrigin,aWidth,aAscent,aDescent);
+	if (result)
+		{
+		aOrigin.iY -= iBandTop;
+		aLineRect = info.iOuterRect;
+		aLineRect.iTl.iX = info.iInnerRect.iTl.iX;
+		aLineRect.iBr.iX = info.iInnerRect.iBr.iX;
+		aLineRect.Move(0,-iBandTop);
+		}
+	return result;
+	}
+
+/** Gets the height (ascent + descent) and ascent of the font of the character
+at aDocPos, as created using the graphics device map used for drawing (the
+"image device") and returns them in aHeight and aAscent, after increasing
+aHeight by the font height increase factor (see SetFontHeightIncreaseFactor()).
+
+@param aDocPos A document position.
+@param aHeight On return contains the height in pixels of the character at
+aDocPos.
+@param aAscent On return, contains the ascent in pixels of the character at
+aDocPos. */
+EXPORT_C void CTextLayout::GetCharacterHeightAndAscentL(TInt aDocPos,TInt& aHeight,TInt& aAscent) const
+	{
+	TPtrC text;
+	TTmCharFormat format;
+	iSource->GetText(aDocPos,text,format);
+	TFontSpec fs;
+	format.iFontSpec.GetTFontSpec(fs);
+	GetFontHeightAndAscentL(fs,aHeight,aAscent);
+	}
+
+/** Gets the height (ascent + descent) and ascent of the font specified by
+aFontSpec, as created using the graphics device map used for drawing (the
+"image device") and puts them into aHeight and aAscent, after increasing
+aHeight by the font height increase factor (see SetFontHeightIncreaseFactor()).
+
+@param aFontSpec Font specification.
+@param aHeight On return, contains the height in pixels of the font.
+@param aAscent On return, contains the ascent in pixels of the font. */
+EXPORT_C void CTextLayout::GetFontHeightAndAscentL(const TFontSpec& aFontSpec,TInt& aHeight,TInt& aAscent) const
+	{
+	CFont* font;
+	MGraphicsDeviceMap& device = iSource->InterpretDevice();
+	User::LeaveIfError(device.GetNearestFontInTwips(font,aFontSpec));
+	aHeight = font->HeightInPixels();
+	int increase = (iSource->iFontHeightIncreaseFactor * aHeight) / 100;
+	aHeight += increase;
+	aAscent = font->AscentInPixels() + increase;
+	device.ReleaseFont(font);
+	}
+
+/** Returns the index of the nearest character in the document to the window 
+coordinates specified. Sets aPos to the actual position of the intersection 
+of the line's baseline with the character's edge. If aPos is before the start
+of the formatted area, returns the first formatted character; if it is after 
+the end of the formatted area, returns the position after the last formatted 
+character, or the end of the document, whichever is less.
+
+This function is deprecated in v7.0s. Use the more powerful FindXYPos() instead.
+
+@param aPos Contains coordinates to convert to a document position. On return,
+contains the exact coordinates of the intersection of the line's baseline with
+the character edge at the document position.
+@param aFlags Three possible values: 0 is the default, and performs the task at
+full accuracy (the function returns the document position of the character edge
+nearest to the coordinates). CLayoutData::EFWholeLinesOnly examines lines only
+and returns the position at the right end of the line if aPos.iX > 0, otherwise
+the position at the left end.
+@return The document position of the nearest character to the coordinates, or
+of the start or end of the line, depending on the value of aFlags. */
+EXPORT_C TInt CTextLayout::XyPosToDocPosL(TPoint &aXyPos,TUint) const
+	{
+	if (aXyPos.iY < -iBandTop)
+		return iText->StartChar();
+	else if (aXyPos.iY >= iText->LayoutHeight() - iBandTop)
+		return Min(iText->EndChar(),iSource->DocumentLength());
+	TTmPosInfo2 pos_info;
+	TTmLineInfo lineInfo;
+	FindXyPos(aXyPos,pos_info, &lineInfo);
+	aXyPos = pos_info.iEdge;
+	TInt r = pos_info.iDocPos.iPos;
+	if (!pos_info.iDocPos.iLeadingEdge && lineInfo.iStart != r)
+		{
+		r -= 1;
+
+		//	surrogate support
+		if ( r > 0 )
+			{
+			TPtrC text;
+			TTmCharFormat format;
+
+			iSource->GetText( r - 1, text, format );
+			if ( text.Length() > 1 )
+				{
+				TUint highSurrogate = text[0];
+				TUint lowSurrogate = text[1];
+				if ( IsHighSurrogate( highSurrogate ) &&
+				     IsLowSurrogate( lowSurrogate ) )
+					--r;
+				}
+			}
+		}
+
+	return r;
+	}
+
+/** Finds the document position nearest to aXyPos. If aXyPos is in the
+formatted text returns ETrue, otherwise returns EFalse. If ETrue is returned,
+places information about the document position in aPosInfo and information
+about the line containing the document position in aLineInfo if it is non-NULL.
+
+@param aXyPos Contains coordinates to convert to a document position.
+@param aPosInfo Buffer to store information about the document position if the
+specified coordinates are located in the formatted text.
+@param aLineInfo Buffer to store information about the line if the specified
+coordinates are located in the formatted text.
+@return ETrue if aXyPos is a formatted position, otherwise EFalse. */
+EXPORT_C TBool CTextLayout::FindXyPos(const TPoint& aXyPos,TTmPosInfo2& aPosInfo,TTmLineInfo* aLineInfo) const
+	{
+	TTagmaForwarder forwarder(*this);
+	TTmLineInfo line_info;
+	TBool result = forwarder.FindXyPos(aXyPos,aPosInfo,line_info);
+	if (aLineInfo && result)
+		*aLineInfo = line_info;
+	return result;
+	}
+
+/** Returns the x-y coordinates of the document position aDocPos in aPos. The
+return value is ETrue if the position is formatted, or EFalse if it is not, in
+which case aPos is undefined.
+
+Deprecated - use the more powerful FindDocPos() instead
+
+@param aDocPos The document position.
+@param aPos On return, contains the x-y coordinates of aDocPos.
+@param aFlags Two possible values: 0 is the default, and performs the task at
+full accuracy, and CLayoutData::EFWholeLinesOnly, which examines lines only and
+sets aXyPos.iY only, and cannot leave.
+@return ETrue if the document position is formatted, EFalse if not. */
+EXPORT_C TBool CTextLayout::DocPosToXyPosL(TInt aDocPos,TPoint& aXyPos,TUint /*aFlags*/) const
+	{
+	TTmDocPos doc_pos(aDocPos, ETrue);
+	TTmPosInfo2 pos_info;
+	TBool result = FindDocPos(doc_pos,pos_info);
+	aXyPos = pos_info.iEdge;
+	return result;
+	}
+
+/** Finds the x-y position of the document position aDocPos.
+
+If ETrue is returned, places information about the document position in aPosInfo
+and information about the line containing the document position in aLineInfo if
+it is non-NULL.
+
+@param aDocPos Contains the document position to check.
+@param aPosInfo On return, stores information about the document position if
+the position is formatted.
+@param aLineInfo Buffer to store the line information if the document position
+is formatted.
+@return ETrue if aDocPos is in the formatted text, otherwise EFalse. */
+EXPORT_C TBool CTextLayout::FindDocPos(const TTmDocPosSpec& aDocPos,TTmPosInfo2& aPosInfo,TTmLineInfo* aLineInfo) const
+	{
+	TTagmaForwarder forwarder(*this);
+	TTmLineInfo line_info;
+	TBool result = forwarder.FindDocPos(aDocPos,aPosInfo,line_info);
+	if (aLineInfo && result)
+		*aLineInfo = line_info;
+	return result;
+	}
+
+/** Finds the next cursor position to aDocPos in the visually ordered line.
+
+@param aDocPos Contains the document position to check.
+@param aPosInfo On return, stores information about the document position of
+the next cursor position, if ETrue is returned.
+@param aToLeft ETrue if the position to the left is to be found, or EFalse if
+the position to the right is to be found.
+@return EFalse if there is no formatting, or the position is at the end of the
+line already. ETrue otherwise. */
+EXPORT_C TBool CTextLayout::GetNextVisualCursorPos(
+	const TTmDocPosSpec& aDocPos, TTmPosInfo2& aPosInfo, TBool aToLeft) const
+	{
+	TTagmaForwarder forwarder(*this);
+	return forwarder.GetNextVisualCursorPos(aDocPos, aPosInfo, aToLeft);
+	}
+
+/** Gets a rectangle enclosing two formatted document positions on the same
+line. If the second position is less than the first, or on a different line, it
+is taken to indicate the end of the line. This function panics if either
+position is unformatted.
+
+Note:
+
+CTextLayout must have been set with a valid wrap width and band height before
+calling this function, otherwise no formatting will take place and the function 
+will panic.  Wrap width and band height values must be > 0 to be valid.
+
+@param aDocPos1 The first document position on the line.
+@param aDocPos2 The second document position on the line.
+@return The minimal rectangle, which bounds both positions.
+@see SetBandHeight
+@see SetWrapWidth */
+EXPORT_C TRect CTextLayout::GetLineRectL(TInt aDocPos1,TInt aDocPos2) const
+	{
+	TRect rect;
+	TPoint point;
+	TInt xCoords[4];
+	
+	if (iText->LayoutHeight() == 0)
+		return TRect(0,0,0,0);
+
+	__ASSERT_ALWAYS(PosIsFormatted(aDocPos1),Panic(ECharacterNotFormatted));
+	__ASSERT_DEBUG(PosIsFormatted(aDocPos2),Panic(ECharacterNotFormatted));
+
+	TTmDocPosSpec docSpec(aDocPos1, TTmDocPosSpec::ELeading);
+	TTmPosInfo2 pos_info;
+	
+	// Finding the leading edge of aDocPos1
+	FindDocPos(docSpec,pos_info);
+	point = pos_info.iEdge;
+	xCoords[0] = point.iX;
+
+	// Getthe Line rectangle
+	GetLineRect(point.iY,rect);
+	
+	__ASSERT_DEBUG(rect.iTl.iY <= point.iY && rect.iBr.iY >= point.iY,Panic(EPixelNotInFormattedLine));
+	
+	//	Finding the leading edge of aDocPos2
+	docSpec.iPos = aDocPos2;
+	TBool isformatted = FindDocPos(docSpec, pos_info);
+	point = pos_info.iEdge;
+	
+	// Checks if the aDocPos2 is contained in the same line of the aDocPos1
+	// Can't use TRect::Contains() here, because TRect::Contains() considers a point located on the right  
+	// hand side or bottom as outside the rectangle, which will has problem when work with RTL text that 
+	// is at the right hand end of a line.
+	TBool isContained = (point.iX>=rect.iTl.iX && point.iX<=rect.iBr.iX 
+				&& point.iY>=rect.iTl.iY && point.iY<=rect.iBr.iY);
+
+	RTmParFormat parFormat;
+	iSource->GetParagraphFormatL(aDocPos1, parFormat);
+	
+	//	The special cases (as indicated in the description):
+	//	When the aDocPos2 is less than the aDocPos1, or not formatted, or on a different line from which the  
+	//	aDocPos1 is in, then the function will return the rectangle starting from docPos1's leading edge and
+	//	ending at the end of the line (which is determined by paragraph directionality).
+	if (aDocPos2 < aDocPos1 || !isformatted || !isContained)
+		{
+		if (parFormat.RightToLeft())
+			rect.iBr.iX = xCoords[0];
+		else
+			rect.iTl.iX = xCoords[0];
+		
+		parFormat.Close();
+		return rect;
+		}
+
+	xCoords[1] = point.iX;
+	
+	//	Finding the Trailing edge of (aDocPos1 + 1)
+	docSpec.iType = TTmDocPosSpec::ETrailing;
+	docSpec.iPos = aDocPos1 + 1;
+	FindDocPos(docSpec, pos_info);
+	xCoords[2] = pos_info.iEdge.iX;
+	
+	//	Finding the Trailing edge of (aDocPos2 + 1)
+	docSpec.iPos = aDocPos2 + 1;
+	FindDocPos(docSpec, pos_info);
+	xCoords[3] = pos_info.iEdge.iX;
+	
+	rect.iBr.iX = xCoords[0];
+	rect.iTl.iX = xCoords[0];
+	
+	// The returned rectangle is generated by (when is not a special case)
+	// 1) Find the Line rectangle
+	// 2) Find the:
+	//		- leading edge of docPos1 
+    //		- leading edge of docPos2 
+    //		- trailing edge of docPos1+1 
+    //		- trailing edge of docPos2+1
+	// 3) Cut the line rectangle at the smallest edge and the largest edge among 
+	//	  the four edges found in step 2.
+	for (TInt i = 1; i<4; i++ )
+		{
+		if (rect.iBr.iX < xCoords[i])
+			rect.iBr.iX = xCoords[i];
+		if (rect.iTl.iX > xCoords[i])
+			rect.iTl.iX = xCoords[i];
+		}
+	
+	parFormat.Close();
+	return rect;
+	}
+
+/** Gets the bounding rectangle of the picture, if any, located at the document
+position or coordinates specified, and returns it in aPictureRect.
+
+If aCanScaleOrCrop is non-null, sets aCanScaleOrCrop to indicate 
+whether the picture can be scaled or cropped. 
+Returns ETrue if the operation was successful. Returns EFalse otherwise;
+that is, if there is no picture at the position, or if the position is unformatted.
+
+@param aDocPos The document position of interest.
+@param aXyPos The layout coordinates of interest.
+@param aPictureRect On return, contains the rectangle which encloses the
+picture located at the position specified.
+@param aCanScaleOrCrop If non-NULL and the function returns ETrue, on return,
+indicates whether the picture can be scaled or cropped. By default, NULL.
+@return ETrue if the operation was successful, (i.e. there is a
+picture character at the position, it has been loaded into
+memory, and the position is formatted). EFalse if any of these
+conditions are not met. */
+EXPORT_C TBool CTextLayout::PictureRectangleL(TInt aDocPos,TRect& aPictureRect,TBool* aCanScaleOrCrop) const
+	{
+	if (aDocPos < iText->StartChar() || aDocPos >= iText->EndChar() - 1)
+		return FALSE;
+
+	aPictureRect.SetRect(0,0,0,0);
+	TSize size;
+	if (iSource->GetPictureSizeInTwipsL(aDocPos,size) != KErrNone)
+		return FALSE;
+
+	TRect rect;
+	TTmDocPos pos(aDocPos, ETrue);
+	TTmPosInfo2 pos_info;
+	TTmLineInfo info;
+	TInt subscript;
+	if (!iText->FindDocPos(pos,pos_info,info,subscript))
+		return FALSE;
+
+	MGraphicsDeviceMap& device = iSource->InterpretDevice();
+	size.iWidth = device.HorizontalTwipsToPixels(size.iWidth);
+	size.iHeight = device.VerticalTwipsToPixels(size.iHeight);
+	rect.iBr.iY = pos_info.iEdge.iY - iBandTop + subscript;
+	rect.iTl.iY = rect.iBr.iY - size.iHeight;
+	if (pos_info.iRightToLeft)
+		{
+		rect.iBr.iX = pos_info.iEdge.iX;
+		rect.iTl.iX = rect.iBr.iX - size.iWidth;
+		}
+	else
+		{
+		rect.iTl.iX = pos_info.iEdge.iX;
+		rect.iBr.iX = rect.iTl.iX + size.iWidth;
+		}
+/*	rect.iTl = pos_info.iEdge;
+	rect.Move(0,-iBandTop);
+	rect.iTl.iY -= size.iHeight;
+	rect.iBr = rect.iTl + size;*/
+	CPicture* picture = iSource->PictureL(aDocPos);
+	if (!picture)
+		return FALSE;
+
+	if (aCanScaleOrCrop)
+		*aCanScaleOrCrop = picture->Capability().iScalingType != TPictureCapability::ENotScaleable ||
+						   picture->Capability().iIsCroppable;
+	aPictureRect = rect;
+	return TRUE;
+	}
+
+/** Finds if there is a picture at the position under the point aXyPos.
+If there is, returns the document position of it, sets the rectangle
+occupied in aPictureRect, and whether the picture allows scaling
+in aCanScaleOrCrop, if non-null. Note that aXyPos may be outside
+the picture found.
+@return  The document position of the picture found, or KErrNotFound if there 
+is none. */
+TInt CTextLayout::PictureRectangleAndPosL(const TPoint& aXyPos, TRect& aPictureRect,
+	TBool* aCanScaleOrCrop) const
+	{
+	TTmPosInfo2 posInfo;
+	if (!FindXyPos(aXyPos, posInfo))
+		return KErrNotFound;
+	TInt doc_pos = posInfo.iDocPos.iPos - (posInfo.iDocPos.iLeadingEdge? 0 : 1);
+	if (PictureRectangleL(doc_pos, aPictureRect, aCanScaleOrCrop))
+		return doc_pos;
+	return KErrNotFound;
+	}
+
+/** Gets the bounding rectangle of the picture (if any) at aXyPos and puts it
+in aPictureRect. If aCanScaleOrCrop is non-null sets *aCanScaleOrCrop to
+indicate whether the picture can be scaled or cropped. Note that aXyPos
+may be outside aPictureRect on a successful return, if the picture does
+not occupy the whole of the section of the line it is in.
+@return ETrue if the position is formatted and there is a picture there. */	
+EXPORT_C TBool CTextLayout::PictureRectangleL(const TPoint& aXyPos,
+	TRect& aPictureRect, TBool* aCanScaleOrCrop) const
+	{
+	return 0 <= PictureRectangleAndPosL(aXyPos, aPictureRect, aCanScaleOrCrop)?
+		ETrue : EFalse;
+	}
+
+/** Gets the first document position in a line that starts at or below the top
+of the visible area. If there is no such line, returns the position after the
+last formatted character.
+
+@return The document position of the first character in a line within the
+visible area. */
+EXPORT_C TInt CTextLayout::FirstDocPosFullyInBand() const
+	{
+	TTmLineInfo info;
+	if (!iText->YPosToLine(iBandTop,info))
+		return iText->EndChar();
+	if (info.iOuterRect.iTl.iY < iBandTop)
+		return info.iEnd;
+	else
+		return info.iStart;
+	}
+
+
+ 
+ 
+/** This interface is deprecated, and is made available in version 7.0s solely
+to provide binary compatibility with Symbian OS v6.1. Developers are strongly
+advised not to make use of this API in new applications. In particular, use the
+other overload of this function if you need to distinguish between leading and
+trailing edge positions.
+
+Do not use if a CTextView object owns this CTextLayout object.
+
+@param aDocPos A valid document position.
+@param aYPos The y coordinate at which to display the character at aDocPos. On
+return, contains the actual vertical position of the specified part of the
+line.
+@param aYPosQualifier Controls which part of the line is set to appear at
+aYPos.
+@param aDiscardFormat If ETrue (EFViewDiscardAllFormat), the text is reformatted
+to include aDocPos, otherwise text is formatted only as necessary when bringing
+new lines into the visible area.
+@return The number of pixels the text was scrolled, may be positive or
+negative. A value of CTextLayout::EFScrollRedrawWholeScreen indicates that the
+entire visible area, at least, was scrolled, and so there is no point in
+blitting text; a full redraw is needed. */
+EXPORT_C TInt CTextLayout::SetViewL(TInt aDocPos,TInt& aYPos,TViewYPosQualifier aYPosQualifier,TDiscard aDiscardFormat)
+	{
+	TTmDocPos pos(aDocPos, ETrue);
+	return SetViewL(pos,aYPos,aYPosQualifier,aDiscardFormat);
+	}
+
+/** Changes the top of the visible area so that the line containing aDocPos is
+vertically positioned at aYPos. Which part of the line is set to appear at
+aYPos (top, baseline, or bottom) is controlled by the TViewYPosQualifier
+argument, which also specifies whether the visible area is to be filled and
+whether the line should be made fully visible if possible.
+
+Do not use if a CTextView object owns this CTextLayout object.
+
+@param aDocPos A valid document position.
+@param aYPos The y coordinate at which to display the character at aDocPos. On
+return, contains the actual vertical position of the specified part of the
+line.
+@param aYPosQualifier Controls which part of the line is set to appear at
+aYPos.
+@param aDiscardFormat If ETrue (EFViewDiscardAllFormat), the text is reformatted
+to include aDocPos, otherwise text is formatted only as necessary when bringing
+new lines into the visible area.
+@return The number of pixels the text was scrolled, may be positive or
+negative. A value of CTextLayout::EFScrollRedrawWholeScreen indicates that the
+entire visible area, at least, was scrolled, and so there is no point in
+blitting text; a full redraw is needed. */
+EXPORT_C TInt CTextLayout::SetViewL(const TTmDocPos& aDocPos, TInt& aYPos,
+	TViewYPosQualifier aYPosQualifier, TDiscard aDiscardFormat)
+	{
+	if (aDocPos.iPos < 0 || aDocPos.iPos > iSource->DocumentLength())
+		Panic(EInvalidDocPos);
+
+	/*
+	If the format is to be discarded, or no text has yet been formatted, or if the document position
+	to be viewed is not formatted, format the band.
+	*/
+	TTmLineInfo info;
+	TBool all_formatted = FALSE;
+	TBool pos_is_formatted = iText->DocPosToLine(aDocPos,info);
+	if (!pos_is_formatted ||
+		aDiscardFormat == EFViewDiscardAllFormat ||
+		(iText->StartChar() == iText->EndChar() && iSource->DocumentLength() > 0))
+		{
+		FormatBandL(aDocPos.iPos,aDocPos.iPos);
+		all_formatted = TRUE;
+		pos_is_formatted = iText->DocPosToLine(aDocPos,info);
+		}
+
+	// Find out where the top of the line is.
+	if (!pos_is_formatted)
+		return 0;
+	int line_top_y = info.iOuterRect.iTl.iY - iBandTop;
+
+	// Determine the desired position of the top of the line.
+	int offset = 0;
+	if (aYPosQualifier.iHotSpot == TViewYPosQualifier::EFViewBaseLine)
+		offset = info.iBaseline - info.iOuterRect.iTl.iY;
+	else if (aYPosQualifier.iHotSpot == TViewYPosQualifier::EFViewBottomOfLine)
+		offset = info.iOuterRect.iBr.iY - info.iOuterRect.iTl.iY;
+	int desired_line_top_y = aYPos - offset;
+
+	// Adjust aYPos so that the line is fully visible if desired.
+	if (aYPosQualifier.iFullyVisible == TViewYPosQualifier::EFViewForceLineFullyVisible)
+		{
+		TInt screenHeight = VisibleHeightInPixels();
+		TInt lineHeight = info.iOuterRect.Height();
+		TInt lineAscent = info.iBaseline - info.iOuterRect.iTl.iY;
+		// If the top of the line is off the top of the screen, and the
+		// baseline and the top can both fit, make the top of the line flush
+		// with the top of the screen.
+		if (lineAscent <= screenHeight
+			&& desired_line_top_y < 0)
+			desired_line_top_y = 0;
+		// If the whole line can fit and the bottom if off the bottom of the
+		// screen, make the bottom flush with the bottom of the screen.
+		if (lineHeight <= screenHeight
+			&& screenHeight < desired_line_top_y + lineHeight)
+			desired_line_top_y = screenHeight - lineHeight;
+		// If the ascent will not fit, or the baseline is off the bottom of
+		// the screen, move the baseline flush with the bottom of the screen
+		if (screenHeight < lineAscent
+			|| screenHeight < desired_line_top_y + lineAscent)
+			desired_line_top_y = screenHeight - lineAscent;
+		}
+
+	// Scroll the document position to the desired vertical coordinate and update aYPos.
+	TInt dy = desired_line_top_y - line_top_y;
+	if (dy)
+		{
+		dy = ScrollL(dy,aYPosQualifier.iFillScreen ? EFDisallowScrollingBlankSpace : EFAllowScrollingBlankSpace);
+		line_top_y += dy;
+		aYPos = line_top_y + offset;
+
+		// Ensure that aYPos is in the line.
+		if (aYPosQualifier.iHotSpot == TViewYPosQualifier::EFViewBottomOfLine)
+			aYPos--;
+		}
+	return all_formatted ? EFScrollRedrawWholeScreen : dy;
+	}
+
+/** Formats enough text to fill the visible band.
+
+Note: Do not use if a CTextView object owns this CTextLayout object. */
+EXPORT_C void CTextLayout::FormatBandL()
+	{
+	FormatBandL(0,0);
+	}
+
+/**
+Format enough text to fill the visible band and include both aStartDocPos and
+aEndDocPos. Start at the start of the document if formatting everything, or at
+the start of the paragraph containing aStartDocPos if formatting the visible
+band only.
+*/
+void CTextLayout::FormatBandL(TInt aStartDocPos,TInt aEndDocPos)
+	{
+	TTmFormatParam param;
+	InitFormatParam(param);
+	if (iBandHeight != CLayoutData::EFHeightForFormattingAllText)
+		param.iStartChar = iSource->ParagraphStart(aStartDocPos);
+	if (param.iWrapWidth < 1 || param.iMaxHeight < 1)
+		{
+		// Do just a little formatting if the values are illegal.
+		// This is to prevent the AddParL running with no
+		// height limit, taking up huge amounts of time, and
+		// having to return with 0 lines formatted, which
+		// confuses CEikEdwin.
+		param.iMaxHeight = 1;
+		param.iWrapWidth = 1;
+		iText->SetTextL(*iSource,param);
+		return;
+		}
+	iText->SetTextL(*iSource,param);
+	param.iMaxHeight = KMaxTInt;
+	
+	if(IsFormattingBand() && (iText->EndChar() <= aEndDocPos && iText->EndChar() < iSource->DocumentLength()))
+		{
+		param.iEndChar = aEndDocPos;
+		iText->ExtendFormattingDownwardsL(param);
+		}
+	else
+		{
+		while (iText->EndChar() <= aEndDocPos && iText->EndChar() < iSource->DocumentLength())
+			{
+			int h,p;
+			AddFormattingAtEndL(param, h, p);
+			}
+		}
+	
+
+	if (iBandHeight != CLayoutData::EFHeightForFormattingAllText)
+		{
+		int visible_height = VisibleHeightInPixels();
+		while (iText->LayoutHeight() < visible_height)
+			{
+			int h,p;
+			if (!iText->AddParL(param,TRUE,h,p))
+				break;
+			}
+		}
+	iBandTop = 0;
+	}
+
+/** Makes sure the line that aYPos is in (if it exists) is covered by the
+formatting.
+@param aYPos Y pixel position in window-relative co-ordinates.
+@internalComponent
+*/
+EXPORT_C void CTextLayout::ExtendFormattingToCoverYL(TInt aYPos)
+	{
+	TTmFormatParam param;
+	InitFormatParam(param);
+	param.iStartChar = iText->StartChar() - 1;
+	param.iEndChar = iText->EndChar();
+	param.iMaxHeight = KMaxTInt;
+	TInt heightIncrease;
+	TInt p;
+	while (iBandTop < -aYPos && iText->AddParL(param, ETrue, heightIncrease, p))
+		{
+		iBandTop += heightIncrease;
+		param.iStartChar = iText->StartChar() - 1;
+		}
+	TInt heightRemaining = iBandTop + aYPos - iText->LayoutHeight() + 1;
+	if(heightRemaining > 0)
+		{
+		param.iStartChar = iText->EndChar();
+		param.iEndChar = KMaxTInt;
+		param.iMaxHeight = heightRemaining;
+		iText->ExtendFormattingDownwardsL(param);
+		}
+	}
+
+/** Allows you to increase the formatted text range by specifying a point in the text you
+want to increase the range to. Makes sure the line that aDocPos is in (if it exists) is covered by the
+formatting.
+@param aDocPos Position in the text you wish to extend the formatting to. e.g. passing in 0 will
+increase the formatting range to the very first character entered in the document.
+@pre aDocPos is in the range 0...DocumentLength
+@post aDocPos has been formatted
+*/
+EXPORT_C void CTextLayout::ExtendFormattingToCoverPosL(TInt aDocPos)
+	{
+	__ASSERT_DEBUG(0 <= aDocPos && aDocPos <= DocumentLength(),
+			Panic(EInvalidDocPos));
+	TTmFormatParam param;
+	InitFormatParam(param);
+	param.iStartChar = iText->StartChar();
+	param.iEndChar = iText->EndChar();
+	param.iMaxHeight = KMaxTInt;
+	TInt heightIncrease;
+	TInt p;
+	TInt pos = aDocPos;
+	if(pos > 0)     // Avoid going into infinite loop.
+		{
+		pos -= 1;	
+		}						
+	while ((pos < param.iStartChar) && (iText->AddParL(param, ETrue, heightIncrease, p)))
+		{
+		iBandTop += heightIncrease;
+		param.iStartChar = iText->StartChar();
+		}	
+	param.iEndChar = aDocPos + 1;
+	if(iText->EndChar() < param.iEndChar)
+		{
+		iText->ExtendFormattingDownwardsL(param);
+		}
+	__ASSERT_DEBUG((aDocPos >= iText->StartChar()) && (aDocPos <= iText->EndChar()),
+			Panic(ECharacterNotFormatted));
+	}
+
+
+/** Sets the formatted text to begin at the start of the paragraph including
+aStartPos and end at aEndPos. Moves the line containing aStartDocPos to the top
+of the visible area.
+
+Notes:
+
+This function is not generally useful; it exists for the convenience of the
+printing system.
+
+Do not use if a CTextView object owns this CTextLayout object.
+
+@param aStartDocPos A document position within the paragraph from which to
+begin formatting.
+@param aEndDocPos Document position at which to end formatting. */
+EXPORT_C void CTextLayout::FormatCharRangeL(TInt aStartDocPos,TInt aEndDocPos)
+	{
+	FormatCharRangeL(aStartDocPos,aEndDocPos,0);
+	}
+
+void CTextLayout::FormatCharRangeL(TInt aStartDocPos,TInt aEndDocPos,TInt aPixelOffset)
+	{
+	__ASSERT_DEBUG(aStartDocPos >= 0 && aStartDocPos <= DocumentLength(),Panic(EInvalidDocPos));
+	__ASSERT_DEBUG(aEndDocPos >= 0 && aEndDocPos <= DocumentLength(),Panic(EInvalidDocPos));
+	__ASSERT_DEBUG(aStartDocPos <= aEndDocPos,Panic(ENoCharRangeToFormat));
+
+	TTmFormatParam param;
+	InitFormatParam(param);
+	param.iStartChar = iSource->ParagraphStart(aStartDocPos);
+	param.iEndChar = aEndDocPos;
+	param.iMaxHeight = KMaxTInt;
+	iText->SetTextL(*iSource,param);
+	TTmLineInfo info;
+	TTmDocPos pos(aStartDocPos, ETrue);
+	if (iText->DocPosToLine(pos,info))
+		iBandTop = info.iOuterRect.iTl.iY - aPixelOffset;
+	else
+		iBandTop = 0; //+ raise an exception?
+	}
+
+/** A special function to support background formatting by the higher level
+CTextView class. It formats the next pending line. The return value is ETrue if
+there is more formatting to do. On entry, aBotPixel contains the y coordinate
+of the bottom of the formatted text; this is updated by the function.
+
+Notes:
+
+Not generally useful.
+
+Do not use if a CTextView object owns this CTextLayout object.
+
+@param aBotPixel On entry, contains the y coordinate of the bottom of the
+formatted text; this is updated by the function.
+@return ETrue if there is more formatting to do. EFalse if not. */
+EXPORT_C TBool CTextLayout::FormatNextLineL(TInt& aBottomPixel)
+	{
+	if (iUnformattedStart < KMaxTInt)
+		{
+		TTmFormatParamBase param;
+		InitFormatParam(param);
+		param.iMaxHeight = KMaxTInt;
+		TTmReformatParam reformat_param;
+		reformat_param.iStartChar = iUnformattedStart;
+		reformat_param.iMaxExtraLines = KMaxExtraLines;
+		reformat_param.iParInvalid = iParInvalid;
+		TTmReformatResult result;
+		iText->FormatL(param,reformat_param,result);
+
+		// If there is no formatting to do, indicate that formatting is complete to the end of the paragraph
+		if (result.iUnformattedStart == KMaxTInt)
+			{
+			TTmLineInfo info;
+			TTmDocPos pos(iUnformattedStart, ETrue);
+			TBool isFormatted = iText->DocPosToLine(pos,info);
+			__ASSERT_DEBUG(isFormatted, Panic(EPosNotFormatted));
+			isFormatted = iText->ParNumberToLine(info.iParNumber,KMaxTInt,info);
+			__ASSERT_DEBUG(isFormatted, Panic(EPosNotFormatted));
+			aBottomPixel = info.iOuterRect.iBr.iY - iBandTop;
+			}
+
+		// Indicate that formatting is complete up to the lower edge of the current line.
+		else
+			aBottomPixel = result.iRedrawRect.iBr.iY - iBandTop;
+		iUnformattedStart = result.iUnformattedStart;
+		}
+	return iUnformattedStart < KMaxTInt;
+	}
+
+/** Controls the height of a single line, for use by the pagination system
+only. Using the format supplied in aParaFormat, determines the height of the
+line containing aDocPos and returns it in aHeight. Changes aDocPos to the end
+of the line and returns ETrue if that position is not the end of the paragraph.
+
+Notes:
+
+Not generally useful; it exists for use by the pagination system only.
+
+Do not use if a CTextView object owns this CTextLayout object.
+
+@param aParaFormat Contains paragraph formatting.
+@param aDocPos A document position. On return, contains the document position
+of the end of the line.
+@param aHeight On return, contains the height of the formatted line containing
+aDocPos.
+@param aPageBreak On return, ETrue if the last character on the line is a page
+break. EFalse if not.
+@return ETrue if the line is not the last line in the paragraph. EFalse if it is
+the last line. */
+EXPORT_C TBool CTextLayout::FormatLineL(CParaFormat* /*aParaFormat*/,TInt& aDocPos,
+										TInt& aHeight,TBool& aPageBreak)
+	{
+	// If the line is not formatted, replace the formatted text with the single paragraph containing the line.
+	if (aDocPos < iText->StartChar() || aDocPos >= iText->EndChar())
+		{
+		TTmFormatParam param;
+		InitFormatParam(param);
+		param.iStartChar = iSource->ParagraphStart(aDocPos);
+		param.iEndChar = iSource->ParagraphEnd(aDocPos);
+		param.iMaxHeight = KMaxTInt;
+		iText->SetTextL(*iSource,param);
+		}
+	TTmLineInfo info;
+	TTmDocPos pos(aDocPos, ETrue);
+	if (!iText->DocPosToLine(pos,info))
+		User::Leave(KErrGeneral);
+	aHeight = info.iOuterRect.Height();
+	aDocPos = info.iEnd;
+	TPtrC text;
+	TTmCharFormat format;
+	iSource->GetText(info.iEnd - 1,text,format);
+	aPageBreak = text[0] == CEditableText::EPageBreak;
+
+	return !(info.iFlags & TTmLineInfo::EParEnd);
+	}
+
+/** Scrolls the text up or down by aNumParas paragraphs, disallowing blank
+space at the bottom of the visible area if aScrollBlankSpace is
+CTextLayout::EFDisallowScrollingBlankSpace.
+
+Do not use if a CTextView object owns this CTextLayout object.
+
+@param aNumParas The number of paragraphs to scroll; may be a positive or
+negative value. On return, contains the number of paragraphs not scrolled; that
+is the difference between the requested number and the number of paragraphs
+actually scrolled.
+@param aScrollBlankSpace Only relevant when scrolling downwards.
+CTextLayout::EFAllowScrollingBlankSpace allows blank space to scroll into the
+visible area. CTextLayout::EFDisallowScrollingBlankSpace prevents blank space
+from scrolling into the visible area.
+@pre aPars must not scroll the display beyond the formatted range. If aPars
+scrolls beyond the formatted range, this method will leave with the error code
+CTextLayout::EPosNotFormatted
+@return The number of pixels actually scrolled. */
+EXPORT_C TInt CTextLayout::ScrollParagraphsL(TInt& aPars,TAllowDisallow aScrollBlankSpace)
+	{
+	TTmFormatParam param;
+	InitFormatParam(param);
+	param.iMaxHeight = KMaxTInt;
+	TTmLineInfo info;
+	int height_increase = 0;
+	int paragraphs_increase = 0;
+	int cur_par = 0;
+	int desired_par = 0;
+	int pixels_to_scroll = 0;
+
+	if (aPars > 0)
+		{
+		if (iText->YPosToLine(iBandTop,info))
+			cur_par = info.iParNumber;
+		else
+			User::Leave(EPosNotFormatted);
+		if (info.iParTop < iBandTop)
+			aPars--;
+		desired_par = cur_par - aPars;
+		while (desired_par < 0 && iText->AddParL(param,TRUE,height_increase,paragraphs_increase))
+			{
+			iBandTop += height_increase;
+			desired_par += paragraphs_increase;
+			}
+		aPars = -desired_par;
+		if (desired_par < 0)
+			desired_par = 0;
+		if (!iText->ParNumberToLine(desired_par,0,info))
+			User::Leave(EPosNotFormatted);
+		pixels_to_scroll = iBandTop - info.iOuterRect.iTl.iY;
+		}
+	else if (aPars < 0)
+		{
+		int band_bottom = iBandTop + VisibleHeightInPixels();
+
+		// Extend formatting until the visible height is filled.
+		param.iEndChar = KMaxTInt;
+		param.iMaxHeight = band_bottom - iText->LayoutHeight();
+		if(param.iMaxHeight > 0)
+			{
+			iText->ExtendFormattingDownwardsL(param);
+			}
+
+		if (iText->YPosToLine(band_bottom - 1,info))
+			cur_par = info.iParNumber;
+		else
+			User::Leave(EPosNotFormatted);
+		if (!((info.iFlags & TTmLineInfo::EParEnd) && info.iOuterRect.iBr.iY == band_bottom))
+			aPars++;
+		desired_par = cur_par - aPars;
+		int last_par = iText->Paragraphs() - 1;
+		while (desired_par > last_par && iText->AddParL(param, EFalse, height_increase,paragraphs_increase))
+			last_par += paragraphs_increase;
+		aPars = last_par - desired_par;
+		if (desired_par > last_par)
+			desired_par = last_par;
+		if (!iText->ParNumberToLine(desired_par,KMaxTInt,info))
+			iText->AddParL(param, EFalse, height_increase, paragraphs_increase);
+		if (!iText->ParNumberToLine(desired_par,KMaxTInt,info))
+			User::Leave(EPosNotFormatted);
+		pixels_to_scroll = band_bottom - info.iOuterRect.iBr.iY;
+		}
+
+	return ScrollL(pixels_to_scroll,aScrollBlankSpace);
+	}
+
+/** Scrolls the text up or down by aNumLines lines, disallowing blank space at
+the bottom of the visible area if aScrollBlankSpace is
+CTextLayout::EFDisallowScrollingBlankSpace.
+
+Do not use if a CTextView object owns this CTextLayout object.
+
+@param aNumLines The number of lines to scroll; may be a positive or negative
+value. On return, contains the number of lines not scrolled; that is, the
+requested number, minus the number actually scrolled.
+@param aScrollBlankSpace Only relevant when scrolling downwards.
+CTextLayout::EFAllowScrollingBlankSpace allows blank space to scroll into the
+visible area. CTextLayout::EFDisallowScrollingBlankSpace prevents blank space
+from scrolling into the visible area.
+@pre aLines must not scroll the display beyond the formatted range. If aLines
+scrolls beyond the formatted range, this method will leave with the error code
+CTextLayout::EPosNotFormatted
+@return The number of pixels actually scrolled. */
+EXPORT_C TInt CTextLayout::ScrollLinesL(TInt& aLines,TAllowDisallow aScrollBlankSpace)
+	{
+	TTmFormatParam param;
+	InitFormatParam(param);
+	param.iMaxHeight = KMaxTInt;
+	TTmLineInfo info;
+	int height_increase = 0;
+	int paragraphs_increase = 0;
+	int lines_scrolled = aLines;
+	int visible_height = VisibleHeightInPixels();
+	if (aLines > 0)			// bring aLines lines into view at the top of the display
+		{
+		int desired_top_line_number = 0;
+		for (;;)
+			{
+			// Find the line number of the first visible line.
+			TBool partial_line = FALSE;
+			int top_line_number = 0;
+			if (iBandTop >= iText->LayoutHeight())
+				top_line_number = iText->Lines();
+			else
+				{
+				if (iText->YPosToLine(iBandTop,info))
+					top_line_number = info.iLineNumber;
+				else
+					User::Leave(EPosNotFormatted);
+				partial_line = iBandTop > info.iOuterRect.iTl.iY;
+				}
+
+			// Find the line number of the desired first visible line.
+			// Defect fix for INC015850. Changed IF so that if the currently
+			// visible top line is as tall or taller (due to a large font or picture)
+			// than the visible height of the view our desired top line remains
+			// the next one above so that a scroll takes place.
+			desired_top_line_number = top_line_number - aLines;
+			if (partial_line && (info.iOuterRect.iBr.iY-info.iOuterRect.iTl.iY < visible_height))
+				desired_top_line_number++;
+
+			// If the desired first visible line number is negative, more lines need to be formatted.
+			if (desired_top_line_number >= 0)
+				break;
+			if (!iText->AddParL(param,TRUE,height_increase,paragraphs_increase))
+				break;
+			iBandTop += height_increase;
+			}
+
+		if (desired_top_line_number < 0)
+			{
+			lines_scrolled += desired_top_line_number;
+			desired_top_line_number = 0;
+			}
+		aLines -= lines_scrolled;
+		if (lines_scrolled)
+			{
+			if (!iText->LineNumberToLine(desired_top_line_number,info))
+				User::Leave(EPosNotFormatted);
+			// if the line to be scrolled to is taller than the screen, we want
+			// to make sure that the baseline is not scrolled off the screen.
+			if (visible_height < info.iBaseline - info.iOuterRect.iTl.iY)
+				return ScrollL(iBandTop + visible_height - info.iBaseline, aScrollBlankSpace);
+			return ScrollL(iBandTop - info.iOuterRect.iTl.iY,aScrollBlankSpace);
+			}
+		else
+			return 0;
+		}
+	else if (aLines < 0)	// bring aLines lines into view at the bottom of the display
+		{
+		if (iScrollFlags & EFScrollOnlyToTopsOfLines)
+			{
+			// If we are restricting scroll to the tops of lines, then lines at
+			// bottom are irrelevant, so all we do is lose the top line.
+			if (!iText->YPosToLine(iBandTop, info))
+				User::Leave(EPosNotFormatted);
+			return ScrollL(-info.iOuterRect.Height(), aScrollBlankSpace);
+			}
+
+		int desired_bottom_line_number = 0;
+		int band_bottom = iBandTop + visible_height;
+		int last_formatted_line = iText->Lines() - 1;
+
+		// Extend formatting until the visible height is filled.
+		param.iEndChar = KMaxTInt;
+		param.iMaxHeight = band_bottom - iText->LayoutHeight();
+		if(param.iMaxHeight > 0)
+			{
+			iText->ExtendFormattingDownwardsL(param);
+			}	
+		for (;;)
+			{
+			// Find the line number of the last visible line.
+			TBool partial_line = FALSE;
+			int bottom_line_number = 0;
+			if (iText->YPosToLine(band_bottom - 1,info))
+				bottom_line_number = info.iLineNumber;
+			else
+				User::Leave(EPosNotFormatted);
+			partial_line = band_bottom < info.iOuterRect.iBr.iY;
+
+			// Find the line number of the desired last visible line.
+			desired_bottom_line_number = bottom_line_number - aLines;
+			if (partial_line)
+				desired_bottom_line_number--;
+
+			// If the desired last visible line number is greater than the last line, more lines need to be formatted.
+			if (desired_bottom_line_number <= last_formatted_line)
+				break;
+			if (!AddFormattingAtEndL(param, height_increase,paragraphs_increase))
+				break;
+			last_formatted_line = iText->Lines() - 1;
+			}
+
+		int shortfall = desired_bottom_line_number - last_formatted_line;
+		if (shortfall > 0)
+			{
+			lines_scrolled += shortfall;
+			desired_bottom_line_number = last_formatted_line;
+			}
+		aLines -= lines_scrolled;
+		if (lines_scrolled)
+			{
+			if (!iText->LineNumberToLine(desired_bottom_line_number,info))
+				User::Leave(EPosNotFormatted);
+			return ScrollL(band_bottom - info.iOuterRect.iBr.iY,aScrollBlankSpace);
+			}
+		else
+			return 0;
+		}
+	else
+		return 0;
+	}
+
+/** Scrolls the text up or down by aPixels pixels, disallowing blank space at
+the bottom of the visible area if aScrollBlankSpace is
+CTextLayout::EFDisallowScrollingBlankSpace.
+
+The return value (not aPixels, as you would expect from ScrollParagraphsL() and
+ScrollLinesL()) contains the number of pixels not successfully scrolled, that
+is, the original value of aPixels, minus the number of pixels actually
+scrolled. On return, aPixels is set to the number of pixels actually scrolled.
+
+Do not use if a CTextView object owns this CTextLayout object.
+
+@param aPixels The number of pixels to scroll; may be a positive or negative
+value. On return, contains the number of pixels actually scrolled.
+@param aScrollBlankSpace Only relevant when scrolling downwards.
+CTextLayout::EFAllowScrollingBlankSpace allows blank space to scroll into the
+visible area. CTextLayout::EFDisallowScrollingBlankSpace prevents blank space
+from scrolling into the visible area.
+@return The difference between the requested number of pixels to scroll and the
+number of pixels actually scrolled. */
+EXPORT_C TInt CTextLayout::ChangeBandTopL(TInt& aPixels,TAllowDisallow aScrollBlankSpace)
+	{
+	int desired_pixels = aPixels;
+	aPixels = ScrollL(aPixels,aScrollBlankSpace);
+	return desired_pixels - aPixels;
+	}
+
+
+
+/** Scrolls the text up or down by aPixels pixels, allowing blank space at
+top and bottom of the visible area, which means the scrolling can go beyond the
+top or bottom border.
+
+Do not use if a CTextView object owns this CTextLayout object.
+
+@param aPixels The number of pixels to scroll; may be a positive or negative
+value. The actual scrolled pixel number is always identical to aPixels*/
+EXPORT_C void CTextLayout::ChangeBandTopNoLimitBorderL(TInt aPixels)
+    {
+    ScrollL(aPixels,EFAllowScrollingBlankSpace,ETrue,ETrue);
+    }
+
+
+/**
+ * Finds a position (in pixels, from the top of the window) where the cursor
+ * can be such that its line will be fully visible. If this is not possible,
+ * then return one with its baseline visible. If this is not possible, we don't
+ * care what the answer is.
+ */
+TInt CTextLayout::SuggestCursorPos(TInt aCurrentCursorPos) const
+	{
+	int visible_height = VisibleHeightInPixels();
+	TTmLineInfo info;
+	if (iText->YPosToLine(iBandTop + aCurrentCursorPos, info))
+		{
+		TBool currentLineHasBaselineVisible =
+			(TBool)(iBandTop <= info.iBaseline
+			&& info.iBaseline < iBandTop + visible_height);
+		TInt tryThisLine = -1;
+		// find a good line to put the cursor on.
+		if (info.iOuterRect.iTl.iY < iBandTop)
+			{
+			// try next line
+			tryThisLine = info.iLineNumber + 1;
+			}
+		else if (iBandTop + visible_height < info.iOuterRect.iBr.iY)
+			{
+			tryThisLine = info.iLineNumber - 1;
+			}
+		if (0 <= tryThisLine && iText->LineNumberToLine(tryThisLine, info))
+			{
+			if (iBandTop <= info.iOuterRect.iTl.iY
+				&& info.iOuterRect.iBr.iY < iBandTop + visible_height)
+				// this line fully visible
+				aCurrentCursorPos = info.iBaseline - iBandTop;
+			else if (!currentLineHasBaselineVisible
+				&& iBandTop <= info.iBaseline
+				&& info.iBaseline < iBandTop + visible_height)
+				// not fully visible, but its baseline is, and the original
+				// line's baseline was not
+				aCurrentCursorPos = info.iBaseline - iBandTop;
+			}
+		}
+	return aCurrentCursorPos;
+	}
+
+/** Scrolls up by a page (that is the band height as set by SetBandHeight(), or
+half that amount if scrolling over lines taller than this), moving the text
+downwards. The current desired vertical cursor position is passed in
+aYCursorPos and updated to a new suggested position as near as possible to it,
+but within the visible text and on a baseline.
+
+Do not use if a CTextView object owns this CTextLayout object.
+
+@param aYCursorPos The current desired vertical cursor position. On return,
+updated to a new suggested position as near as possible to it.
+@param aPixelsScrolled On return, contains the number of pixels scrolled. */
+EXPORT_C void CTextLayout::PageUpL(TInt& aYCursorPos,TInt& aPixelsScrolled)
+	{
+	// Move the cursor into the visible area.
+	int visible_height = VisibleHeightInPixels();
+	if (aYCursorPos < 0)
+		aYCursorPos = 0;
+	else if (aYCursorPos > visible_height)
+		aYCursorPos = visible_height - 1;
+
+	TTmLineInfo info;
+	// position the top of the screen must be at least as low as
+	TInt longestScrollTo = iBandTop + visible_height
+		- visible_height * KMaxProportionOfScreenToScroll/1000;
+	// position the top of the screen must be at least as high as
+	TInt shortestScrollTo = iBandTop + visible_height
+		- visible_height * KMinProportionOfScreenToScroll/1000;
+	TInt desiredScrollTo = shortestScrollTo;
+	// find the line at the top of the screen
+	// (we cannot find the one that includes the first pixel off the screen
+	// because it might not have been formatted yet)
+	if  (iText->YPosToLine(iBandTop, info))
+		{
+		// subtract one from the line number if this was on the screen
+		TInt line = info.iLineNumber
+			- (info.iOuterRect.iTl.iY < iBandTop? 0 : 1)
+			+ KNumberOfLinesToKeepVisibleDuringScroll;
+		if (iText->LineNumberToLine(Max(0, line), info))
+			desiredScrollTo = info.iOuterRect.iTl.iY;
+		}
+	if (shortestScrollTo < desiredScrollTo)
+		desiredScrollTo = shortestScrollTo;
+	else if (desiredScrollTo < longestScrollTo)
+		desiredScrollTo = longestScrollTo;
+	aPixelsScrolled = ScrollL(iBandTop + visible_height - desiredScrollTo,
+		EFDisallowScrollingBlankSpace);
+	aYCursorPos = aPixelsScrolled == 0?
+		0
+		: SuggestCursorPos(aYCursorPos);
+	}
+
+/** Scrolls down by a page (that is the band height as set by SetBandHeight(),
+or half that amount if scrolling over lines taller than this), moving the text
+upwards. The current desired vertical cursor position is passed in aYCursorPos
+and updated to a new suggested position as near as possible to it, but within
+the visible text and on a baseline.
+
+Do not use if a CTextView object owns this CTextLayout object.
+
+@param aYCursorPos The current desired vertical cursor position. On return,
+updated to a new suggested position as near as possible to it.
+@param aPixelsScrolled On return, contains the number of pixels scrolled - a
+negative value. */
+EXPORT_C void CTextLayout::PageDownL(TInt& aYCursorPos,TInt& aPixelsScrolled)
+	{
+	// Move the cursor into the visible area.
+	int visible_height = VisibleHeightInPixels();
+	if (aYCursorPos < 0)
+		aYCursorPos = 0;
+	else if (aYCursorPos > visible_height)
+		aYCursorPos = visible_height - 1;
+
+	TTmLineInfo info;
+	// position the bottom of the screen must be at least as high as
+	TInt longestScrollTo = iBandTop +
+		visible_height * KMaxProportionOfScreenToScroll/1000;
+	// position the bottom of the screen must be at least as low as
+	TInt shortestScrollTo = iBandTop + visible_height * KMinProportionOfScreenToScroll/1000;
+	TInt desiredScrollTo = shortestScrollTo;
+	// find the line at the bottom of the screen
+	// (we cannot find the one that includes the first pixel off the screen
+	// because it might not have been formatted yet)
+	if  (iText->YPosToLine(iBandTop + visible_height - 1, info))
+		{
+		// add one to the line number if this was on the screen
+		TInt line = info.iLineNumber
+			+ (iBandTop + visible_height < info.iBaseline? 0 : 1)
+			- KNumberOfLinesToKeepVisibleDuringScroll;
+		if (iText->LineNumberToLine(Max(0, line), info))
+			desiredScrollTo = info.iOuterRect.iBr.iY;
+		}
+	if (desiredScrollTo < shortestScrollTo)
+		desiredScrollTo = shortestScrollTo;
+	else if (longestScrollTo < desiredScrollTo)
+		desiredScrollTo = longestScrollTo;
+	aPixelsScrolled = ScrollL(iBandTop - desiredScrollTo,
+		EFDisallowScrollingBlankSpace);
+	aYCursorPos = aPixelsScrolled == 0?
+		visible_height - 1
+		: SuggestCursorPos(aYCursorPos);
+
+	__ASSERT_DEBUG(-visible_height <= aPixelsScrolled,
+		Panic(EPageScrollError));
+	__ASSERT_DEBUG(0 <= aYCursorPos && aYCursorPos <= visible_height,
+		Panic(EPageScrollError));
+	}
+
+/** Reformats to reflect a single character edit.
+
+Do not use if a CTextView object owns this CTextLayout object.
+
+@param aType Indicates the type of edit which has taken place.
+CTextLayout::EFCharacterInsert (the default) for a character insertion,
+CTextLayout::EFParagraphDelimiter for a paragraph delimiter insertion,
+CTextLayout::EFLeftDelete or CTextLayout::EFRightDelete for a character or
+paragraph delimiter deletion to the left or right of the document position.
+@param aCursorPos The document position at which the edit took place, before
+the edit. If this position is not formatted, a panic occurs; it is modified in
+accordance with the edit.
+@param aGood On return, the y coordinate of the top of the paragraph following
+the paragraph which has been edited, before the edit.
+@param aFormattedUpTo On return, the y coordinate of the bottom of the
+reformatted line or lines, after the edit.
+@param aFormattedFrom On return, the vertical layout coordinate of the top of
+the reformatted line or lines, after the edit.
+@param aScroll The number of pixels by which the text had to be scrolled
+(positive means text moved down).
+@param aFormatChanged ETrue if text is to be reformatted from the start of the
+paragraph the cursor was on before the edit, EFalse if from the start of the
+line the cursor was on before the edit.
+@return EFalse if no more lines need to be reformatted. ETrue if some more lines
+need to be reformatted. */
+EXPORT_C TBool CTextLayout::HandleCharEditL(TUint aType,TInt& aCursorPos,TInt& aGood,TInt& aFormatBottom,
+											TInt& aFormatTop,TInt& aScroll,TBool aFormatFromStartOfPar)
+	{
+	__ASSERT_ALWAYS(iSource->iFormatMode != CLayoutData::EFPrintPreviewMode,Panic(EPrintPreviewModeError));
+	__ASSERT_ALWAYS(aType <= EFRightDelete,Panic(EBadCharacterEditType));
+	__ASSERT_ALWAYS(!aFormatFromStartOfPar || aType == EFRightDelete || aType == EFLeftDelete,Panic(EBadCharacterEditType));
+	__ASSERT_ALWAYS(aCursorPos >= iText->StartChar() && aCursorPos < iText->EndChar(),Panic(ECharacterNotFormatted));
+
+	// Mark the entire paragraph invalid if background formatting is taking place.
+	iParInvalid = iUnformattedStart != KMaxTInt;
+
+	// Cancel any pending background formatting, which has now been invalidated by the change.
+	iUnformattedStart = KMaxTInt;
+
+	// Adjust the cursor position and determine the range of characters to reformat.
+	TTmReformatParam reformat_param;
+	reformat_param.iParInvalid = iParInvalid;
+	switch (aType)
+		{
+		case EFCharacterInsert:
+		case EFParagraphDelimiter:
+			reformat_param.iStartChar = aCursorPos++;
+			reformat_param.iNewLength = 1;
+			break;
+		case EFLeftDelete:
+			reformat_param.iStartChar = --aCursorPos;
+			reformat_param.iOldLength = 1;
+			break;
+		case EFRightDelete:
+			reformat_param.iStartChar = aCursorPos;
+			reformat_param.iOldLength = 1;
+			break;
+		default: break;
+		}
+
+	// Set up the formatting parameters.
+	TTmFormatParam param;
+	InitFormatParam(param);
+	param.iMaxHeight = KMaxTInt;
+
+	// Format the whole band if necessary.
+	TTmDocPos cursorPos(aCursorPos, EFalse);
+	if (reformat_param.iStartChar < iText->StartChar() || reformat_param.iStartChar + reformat_param.iOldLength >= iText->EndChar())
+		{
+		FormatBandL(reformat_param.iStartChar,reformat_param.iStartChar + reformat_param.iOldLength);
+		aFormatTop = 0;
+		aFormatBottom = iText->LayoutHeight() - iBandTop;
+		aGood = aFormatBottom;
+		aScroll = 0;
+		ScrollDocPosIntoViewL(cursorPos);
+		return FALSE;
+		}
+
+	// Reformat the chosen range.
+	reformat_param.iMaxExtraLines = KMaxExtraLines;
+	TTmReformatResult result;
+	iText->FormatL(param,reformat_param,result);
+	result.iRedrawRect.Move(0,-iBandTop);
+	iUnformattedStart = result.iUnformattedStart;
+
+	// Scroll if necessary and extend the redraw area to include material scrolled into view.
+	aScroll = ScrollDocPosIntoViewL(cursorPos);
+	if (aScroll > 0)
+		result.iRedrawRect.iBr.iY += aScroll;
+	else
+		result.iRedrawRect.iTl.iY += aScroll;
+
+	// Return coordinates.
+	aFormatTop = result.iRedrawRect.iTl.iY;
+	aFormatBottom = result.iRedrawRect.iBr.iY;
+	aGood = result.iUnchangedTop - iBandTop;
+
+	// Add new paragraphs if necessary.
+	int visible_height = VisibleHeightInPixels();
+	
+	param.iEndChar = KMaxTInt;
+	param.iMaxHeight = (iBandTop + visible_height) - iText->LayoutHeight();
+	if(param.iMaxHeight > 0)
+		{
+		iText->ExtendFormattingDownwardsL(param);
+		}
+	
+	//remove formatting from the end if necessary
+	PruneFormatL(EFalse);
+	// Return TRUE if more text needs to be formatted.
+	return iUnformattedStart < KMaxTInt;
+	}
+
+/** Reformats to reflect changes to a block of text.
+
+Do not use if a CTextView object owns this CTextLayout object.
+
+@param aSelection The start and new length of the changed block. When
+inserting, specify the insertion position. When deleting, specify the position
+of the start of the deletion. When reformatting, specify the start and length
+of the reformatted block.
+@param aOldCharsChanged The old length of the changed block. When inserting,
+specify zero. When deleting, specify the number of deleted characters. When
+reformatting, specify the number of reformatted characters.
+@param aViewChanges On return, contains the top of the reformatted text
+(iFormattedFrom), the bottom of the reformatted text (iFormattedTo), the amount
+by which the text above the reformatted text has scrolled (iScrollAtTop) and
+the amount by which the text below the reformatted text has scrolled
+(iScrollAtBottom) (positive values mean the text moves down).
+@param aFormatChanged Indicates whether the paragraph format for the first or
+last affected paragraph has changed, meaning that the text to be reformatted
+must extend out to paragraph boundaries and cannot be restricted to only some
+lines. */
+EXPORT_C void CTextLayout::HandleBlockChangeL(TCursorSelection aSelection,TInt aOldLength,
+											  TViewRectChanges& aChanges,TBool aFormatFromStartOfPar)
+	{
+	__ASSERT_ALWAYS(iSource->iFormatMode != CLayoutData::EFPrintPreviewMode,Panic(EPrintPreviewModeError));
+
+	// Do nothing if the selection is outside the formatted range.
+	if (aSelection.LowerPos() > iText->EndChar() || aSelection.HigherPos() < iText->StartChar())
+		{
+		aChanges.iFormattedFrom = 0;
+		aChanges.iFormattedTo = 0;
+		aChanges.iScrollAtTop = 0;
+		aChanges.iScrollAtBottom = 0;
+		return;
+		}
+
+	// Format the whole band if necessary.
+	TTmDocPos cursorPos(aSelection.iCursorPos,
+		aSelection.iCursorPos < aSelection.iAnchorPos? ETrue : EFalse);
+	if (aSelection.LowerPos() < iText->StartChar() || aSelection.LowerPos() + aOldLength >= iText->EndChar())
+		{
+		FormatBandL(aSelection.iCursorPos,aSelection.iCursorPos);
+		aChanges.iFormattedFrom = 0;
+		aChanges.iFormattedTo = VisibleHeightInPixels();
+		aChanges.iScrollAtTop = 0;
+		aChanges.iScrollAtBottom = 0;
+		ScrollDocPosIntoViewL(cursorPos);
+		return;
+		}
+
+	// Reformat the chosen range.
+	TTmFormatParam param;
+	InitFormatParam(param);
+	param.iMaxHeight = KMaxTInt;
+	TTmReformatParam reformat_param;
+	reformat_param.iStartChar = aSelection.LowerPos();
+	reformat_param.iOldLength = aOldLength;
+	reformat_param.iNewLength = aSelection.Length();
+	reformat_param.iParFormatChanged = aFormatFromStartOfPar;
+	TTmReformatResult result;
+	iText->FormatL(param,reformat_param,result);
+	result.iRedrawRect.Move(0,-iBandTop);
+
+	// Scroll if necessary.
+	int dy;
+	if(iTextViewCursorPos)
+		{
+		dy = ScrollDocPosIntoViewL(iTextViewCursorPos->TmDocPos());
+		iTextViewCursorPos = NULL;
+		}
+	else
+		{
+		dy = ScrollDocPosIntoViewL(cursorPos);
+		}
+	result.iRedrawRect.Move(0,dy);
+
+	aChanges.iFormattedFrom = result.iRedrawRect.iTl.iY;
+	aChanges.iFormattedTo = result.iRedrawRect.iBr.iY;
+	aChanges.iScrollAtTop = dy;
+	aChanges.iScrollAtBottom = dy + result.iHeightChange;
+
+	// Extend formatting to fill the band if necessary.
+	int visible_height = VisibleHeightInPixels();
+
+	param.iEndChar = KMaxTInt;
+	param.iMaxHeight = (iBandTop + visible_height) - iText->LayoutHeight();
+	if(param.iMaxHeight > 0)
+		{
+		iText->ExtendFormattingDownwardsL(param);
+		}
+
+	//remove formatting from the end if necessary
+	PruneFormatL(EFalse);
+	}
+
+/** Reformats to reflect the addition of one or more complete paragraphs at the
+end of the text.
+
+Do not use if a CTextView object owns this CTextLayout object.
+
+@param aFirstPixel On return, the top y coordinate of the added material.
+@param aLastPixel On return, the bottom y coordinate of the added material.
+*/
+EXPORT_C void CTextLayout::HandleAdditionalCharactersAtEndL(TInt& aNewTextTop,TInt& aNewTextBottom)
+	{
+	aNewTextTop = aNewTextBottom = iText->LayoutHeight() - iBandTop;
+	int format_required = BandHeightInPixels() - aNewTextBottom;
+	if (format_required > 0)
+		{
+		TTmFormatParam param;
+		InitFormatParam(param);
+		param.iMaxHeight = format_required;
+		TInt oldHeight = iText->LayoutHeight();
+		iText->ExtendFormattingDownwardsL(param);
+		aNewTextBottom += (iText->LayoutHeight() - oldHeight);
+		}
+	}
+
+/** Reformats to reflect changes to the space above and below paragraphs
+(CParaFormat::iSpaceBeforeInTwips and iSpaceAfterInTwips).
+
+Do not use if a CTextView object owns this CTextLayout object.
+@deprecated 6.1 Use FormatBandL()
+*/
+EXPORT_C void CTextLayout::ReformatVerticalSpaceL()
+	{
+	// Reformat the whole band; only space above and below paragraphs has changed, but who cares?
+	FormatBandL();
+	}
+
+/** Temporarily changes the vertical alignment of the text with respect to the
+visible height.
+
+Notes:
+
+Not generally useful.
+
+Do not use if a CTextView object owns this CTextLayout object.
+
+@param aVerticalAlignment Specifies whether the formatted text should be placed
+at the top (CParaFormat::ETopAlign), vertical centre (CParaFormat::ECenterAlign
+or CParaFormat::EJustifiedAlign) or bottom (CParaFormat::EBottomAlign) of the
+band. CParaFormat::EUnspecifiedAlign or CParaFormat::ECustomAlign may also be
+specified. These values cause the baseline of the first formatted line to be
+positioned 82% of the way down the band (provided for the Agenda's
+application's year view). */
+EXPORT_C void CTextLayout::AdjustVerticalAlignment(CParaFormat::TAlignment aVerticalAlignment)
+	{
+	int excess = BandHeight() - FormattedHeightInPixels();
+	int space_before = 0;
+	__ASSERT_ALWAYS(!IsFormattingBand(),Panic(EMustFormatAllText));
+	TTmLineInfo info;
+
+	switch (aVerticalAlignment)
+		{
+		case CParaFormat::EAbsoluteLeftAlign:
+		case CParaFormat::ETopAlign:
+			break;
+		case CParaFormat::ECenterAlign:
+		case CParaFormat::EJustifiedAlign:
+			space_before = excess / 2;
+			break;
+		case CParaFormat::EAbsoluteRightAlign:
+		case CParaFormat::EBottomAlign:
+			space_before = excess;
+			break;
+		case CParaFormat::EUnspecifiedAlign:
+		case CParaFormat::ECustomAlign:
+			if (iText->LineNumberToLine(0,info))
+				{
+				space_before = CLayoutData::EFBaseLinePosition * BandHeight() / 100 - info.iBaseline;
+				}
+			else
+				{
+				space_before = CLayoutData::EFBaseLinePosition * BandHeight() / 100;
+				}
+			break;
+		}
+
+	iBandTop = -space_before;
+	}
+
+static TInt SingleBorderWidthInPixels(const MGraphicsDeviceMap* aGd,const TParaBorder& aBorder,TBool aHoriz)
+	{
+	TInt width = aBorder.iThickness;
+	if (width > 0)
+		{
+		if (aHoriz)
+			width = aGd->VerticalTwipsToPixels(width);
+		else
+			width = aGd->HorizontalTwipsToPixels(width);
+		}
+	else
+		width = 1;
+	return width;
+	}
+
+/** Draws paragraph borders, optionally with a background colour for the border
+and a clip region. Provided for applications that display a menu of border
+styles, like a wordprocessor.
+
+@param aGd Provides twip-to-pixel conversion.
+@param aGc Graphics context to which to draw the border. Its pen settings are
+overridden by the values specified by aBorder and its draw mode is set to
+CGraphicsContext::EDrawModePEN.
+@param aRect The outer bounds of the border.
+@param aBorder Specifies the four sides of the border.
+@param aBackground If not null, the background colour, (used between double
+border lines, or between dots or dashes).
+@param aClipRegion If non-null, specifies a clip region.
+@param aDrawRect If non-null, and if aClipRegion is non-null, specifies a
+rectangle to be subtracted from the clip region. */
+EXPORT_C void CTextLayout::DrawBorders(const MGraphicsDeviceMap* aGd,CGraphicsContext& aGc,const TRect& aBoundingRect,
+									   const TParaBorderArray& aBorder,const TRgb* aBackground,TRegion *aClipRegion,
+									   const TRect* aDrawRect)
+	{
+	TPoint pointTl,pointBr;
+	TRect rect;
+	TInt * ptrStartLength=NULL;			//To stop a warning
+	TInt * ptrEndLength=NULL;			//To stop a warning
+	TInt * ptrStartWidth=NULL;			//To stop a warning
+	TInt * ptrEndWidth=NULL;			//To stop a warning
+	TInt directionOut=0;			//To stop a warning
+	TInt indexJoint1=0,indexJoint2=0;			//To stop a warning
+	TBool drawAsLine=EFalse;
+	TRect clipRect;
+	CGraphicsContext::TPenStyle	penStyle[4];
+	TInt widthInPixels[4];
+	TBool horiz;
+	const MFormParam* form_param = MFormParam::Get();
+		
+	{for (TInt border=0; border<=3; border++)
+		{
+		TParaBorder::TLineStyle lineStyle=aBorder.iBorder[border].iLineStyle;
+		if (lineStyle == TParaBorder::ENullLineStyle)
+			{
+			penStyle[border]=CGraphicsContext::ENullPen;
+			widthInPixels[border]=0;
+			continue;
+			}
+		else
+			{
+			horiz=(border==CParaFormat::EParaBorderTop || border==CParaFormat::EParaBorderBottom);
+
+			widthInPixels[border]=SingleBorderWidthInPixels(aGd,aBorder.iBorder[border],horiz);
+			}
+
+		if (lineStyle==TParaBorder::ESolid || lineStyle==TParaBorder::EDouble)
+			{
+			penStyle[border]=CGraphicsContext::ESolidPen;
+			continue;
+			}
+
+		if (lineStyle == TParaBorder::EDashed)
+			penStyle[border]=CGraphicsContext::EDashedPen;
+		else if (lineStyle == TParaBorder::EDotted)
+			penStyle[border]=CGraphicsContext::EDottedPen;
+		else if (lineStyle == TParaBorder::EDotDash)
+			penStyle[border]=CGraphicsContext::EDotDashPen;
+		else if (lineStyle == TParaBorder::EDotDotDash)
+			penStyle[border]=CGraphicsContext::EDotDotDashPen;
+
+		}}
+
+	{for (TInt border=0; border<=3; border++)
+		{
+// Go to next border, if have NULL linestyle.
+		if (widthInPixels[border]==0)
+			continue;
+
+// Reset clipping region
+		clipRect.SetSize(TSize(0,0));
+
+// Draw as line if not solid lines.
+
+		if (penStyle[border]!=CGraphicsContext::ESolidPen)
+			drawAsLine=ETrue;
+			
+		pointTl=aBoundingRect.iTl;
+		pointBr=aBoundingRect.iBr;
+
+		if (border==CParaFormat::EParaBorderLeft)
+			{
+			pointBr.iX=pointTl.iX;
+			ptrStartLength=&pointTl.iY;
+			ptrEndLength=&pointBr.iY;
+			ptrStartWidth=&pointTl.iX;
+			ptrEndWidth=&pointBr.iX;
+			directionOut=-1;
+			indexJoint1=CParaFormat::EParaBorderTop;
+			indexJoint2=CParaFormat::EParaBorderBottom;
+			}
+		if (border == CParaFormat::EParaBorderRight)
+			{
+			pointTl.iX=pointBr.iX;
+			ptrStartLength=&pointTl.iY;
+			ptrEndLength=&pointBr.iY;
+			ptrStartWidth=&pointTl.iX;
+			ptrEndWidth=&pointBr.iX;
+			directionOut=1;
+			indexJoint1=CParaFormat::EParaBorderTop;
+			indexJoint2=CParaFormat::EParaBorderBottom;
+			}
+		if (border == CParaFormat::EParaBorderTop)
+			{
+			pointBr.iY=pointTl.iY;
+			ptrStartLength=&pointTl.iX;
+			ptrEndLength=&pointBr.iX;
+			ptrStartWidth=&pointTl.iY;
+			ptrEndWidth=&pointBr.iY;
+			directionOut=-1;
+			indexJoint1=CParaFormat::EParaBorderLeft;
+			indexJoint2=CParaFormat::EParaBorderRight;
+			}
+		if (border == CParaFormat::EParaBorderBottom)
+			{
+			pointTl.iY=pointBr.iY;
+			ptrStartLength=&pointTl.iX;
+			ptrEndLength=&pointBr.iX;
+			ptrStartWidth=&pointTl.iY;
+			ptrEndWidth=&pointBr.iY;
+			directionOut=1;
+			indexJoint1=CParaFormat::EParaBorderLeft;
+			indexJoint2=CParaFormat::EParaBorderRight;
+			}
+
+		if (!ptrStartWidth || !ptrEndWidth)
+			{
+			continue;
+			}
+
+		if (drawAsLine)
+			{
+			if (directionOut<0)
+				{
+				(*ptrStartWidth)+=(widthInPixels[border]-1)/2;
+				(*ptrEndWidth)+=(widthInPixels[border]-1)/2;
+				}
+			else
+				{
+				(*ptrStartWidth)-=(widthInPixels[border]+2)/2;
+				(*ptrEndWidth)-=(widthInPixels[border]+2)/2;
+				}
+			(*ptrStartLength)+=(widthInPixels[border]-1)/2;
+			(*ptrEndLength)-=(widthInPixels[border])/2;
+			}
+		else
+			{
+			if (directionOut<0)
+				(*ptrEndWidth)+=widthInPixels[border];
+			else
+				(*ptrStartWidth)-=widthInPixels[border];
+			}
+
+// Colour of pen as is - NO logical combination with background etc.
+		aGc.SetDrawMode(CGraphicsContext::EDrawModePEN);
+
+		if (drawAsLine)
+			{
+// Must draw lines in background colour first, as have dotted/dashed lines.
+			aGc.SetPenSize(TSize(widthInPixels[border],widthInPixels[border]));
+			if (aBackground)
+				{
+				FormUtil::SetPenColor(form_param,&aGc,*aBackground);
+				aGc.SetPenStyle(CGraphicsContext::ESolidPen);
+				aGc.DrawLine(pointTl,pointBr);
+				}
+			FormUtil::SetPenColor(form_param,&aGc,aBorder.iBorder[border].iColor);
+			aGc.SetPenStyle(penStyle[border]);
+			aGc.DrawLine(pointTl,pointBr);
+			(*ptrStartWidth)-=(widthInPixels[border]-1)/2;
+			(*ptrEndWidth)+=(widthInPixels[border]+2)/2;
+			(*ptrStartLength)-=(widthInPixels[border]-1)/2;
+			(*ptrEndLength)+=(widthInPixels[border])/2;
+			clipRect.SetRect(pointTl,pointBr);
+			}
+		else
+			{
+// Brush
+			FormUtil::SetBrushColor(form_param,&aGc,aBorder.iBorder[border].iColor);
+			aGc.SetBrushStyle(CGraphicsContext::ESolidBrush);
+			aGc.SetPenStyle(CGraphicsContext::ENullPen);
+			rect.SetRect(pointTl,pointBr);
+			aGc.DrawRect(rect);
+			clipRect=rect;
+			};
+
+// Repeat draw, for double border.
+		if (aBorder.iBorder[border].iLineStyle==TParaBorder::EDouble)	 // Now have only got solid border, drawn as rect.
+			{
+			__ASSERT_DEBUG(!drawAsLine,Panic(EDrawingBorderError));
+			(*ptrStartWidth)-=directionOut*widthInPixels[border];
+			(*ptrEndWidth)-=directionOut*widthInPixels[border];
+			(*ptrStartLength)+=widthInPixels[indexJoint1];
+			(*ptrEndLength)-=widthInPixels[indexJoint2];
+
+			if (aBackground)
+				{
+				rect.SetRect(pointTl,pointBr);
+				FormUtil::SetBrushColor(form_param,&aGc,*aBackground);
+				aGc.DrawRect(rect);
+				}
+
+			(*ptrStartWidth)-=directionOut*widthInPixels[border];
+			(*ptrEndWidth)-=directionOut*widthInPixels[border];
+
+			if (aBorder.iBorder[indexJoint1].iLineStyle==TParaBorder::EDouble)
+				(*ptrStartLength)+=widthInPixels[indexJoint1];
+			if (aBorder.iBorder[indexJoint2].iLineStyle==TParaBorder::EDouble)
+				(*ptrEndLength)-=widthInPixels[indexJoint2];
+
+			rect.SetRect(pointTl,pointBr);
+			FormUtil::SetBrushColor(form_param,&aGc,aBorder.iBorder[border].iColor);
+			aGc.DrawRect(rect);
+			clipRect.BoundingRect(rect);
+			};
+
+
+// Restore defaults
+		aGc.SetPenStyle(CGraphicsContext::ESolidPen);
+		aGc.SetPenSize(TSize(1,1));
+// Should change to BACKGROUND colour.
+		if (aBackground)
+			FormUtil::SetBrushColor(form_param,&aGc,*aBackground);
+// If have to clip region, then remove rectangles corresponding to the border region.
+
+		if (aClipRegion)
+			{
+			if (aDrawRect)
+				clipRect.Intersection(*aDrawRect);
+			aClipRegion->SubRect(clipRect);
+			}
+
+	}};
+
+	if (aClipRegion)
+		{
+		aClipRegion->Tidy();
+		((CWindowGc *) &aGc)->SetClippingRegion(*aClipRegion);
+		}
+	
+	}
+
+/** Draws the text. Draws any lines that intersect aDrawRect, which is
+specified in window coordinates. The drawing parameters, including the graphics
+context, are given in aDrawTextLayoutContext. If aHighlight is non-null,
+highlights (by exclusive-ORing) the specified range of text.
+
+@param aDrawRect The function draw the lines within the visible area, which
+intersect this rectangle (which is specified in window coordinates).
+@param aDrawTextLayoutContext Provides a graphics context and other parameters
+for the function.
+@param aHighlight If not NULL, this range of text is drawn highlighted. */
+EXPORT_C void CTextLayout::DrawL(const TRect& aDrawRect,const TDrawTextLayoutContext* aDrawTextLayoutContext,
+								 const TCursorSelection* aHighlight)
+	{
+	// Set the drawing parameters in the MTmSource interface.
+	iSource->iFormParam = MFormParam::Get();
+	iSource->iLabelsGutter = aDrawTextLayoutContext->iGutterMarginWidth;
+
+	// Calculate the top left corner of the text.
+	TPoint top_left = aDrawTextLayoutContext->TopLeftText();
+	top_left.iY -= iBandTop;
+
+	// Get the graphics context.
+	CGraphicsContext* gc = aDrawTextLayoutContext->PrimaryGc();
+
+	/*
+	Clip the draw rectangle to the view rectangle, and clip it further to exclude
+	a final partial line if necessary.
+	*/
+	TRect clip_rect(aDrawRect);
+	clip_rect.Intersection(aDrawTextLayoutContext->iViewRect);
+
+
+	if (aDrawTextLayoutContext->UseClippingRect())
+		{
+		gc->SetClippingRect(clip_rect);
+		}
+
+	// Draw the text and background.
+
+	TBool isDrawingOnAWindowDC = aDrawTextLayoutContext->UseWindowGc();
+
+	if (isDrawingOnAWindowDC)
+		{
+		BeginRedraw(clip_rect);
+		}
+
+	iText->DrawLayout(*gc,top_left,clip_rect,&aDrawTextLayoutContext->iBackgroundColor,TRUE, aHighlight, iHighlightExtensions);
+
+	if (isDrawingOnAWindowDC)
+		{
+		EndRedraw();
+		}
+
+	iSource->iFormParam = NULL;
+	}
+	
+/** Default constructor. 
+	
+The start and end positions are set to zero - Set() should be called to 
+initialise the object. */	
+EXPORT_C CTextLayout::TRangeChange::TRangeChange()
+	: iA(0), iB(0) {}
+
+/** Sets the start and end positions and whether the highlighting should be
+set or cleared.
+
+Called by the non-default constructor. The start and end positions can be
+specified in any order.
+
+@param aStart The start of the range.
+@param aEnd The end of the range.
+@param aChange Whether the highlighting should be set or cleared. */
+EXPORT_C void CTextLayout::TRangeChange::Set(TInt aStart, TInt aEnd,
+	CTextLayout::TRangeChange::TChangeType aChange)
+	{
+	if ((aChange == ESet && aStart < aEnd)
+		|| (!(aChange == ESet) && !(aStart < aEnd)))
+		{
+		iA = aStart;
+		iB = aEnd;
+		}
+	else
+		{
+		iA = aEnd;
+		iB = aStart;
+		}
+	}
+
+/** Constructor with a start and end position and whether the highlighting
+in the range should be set or cleared.
+
+The start and end positions can be specified in any order.
+
+@param aStart The start position.
+@param aEnd The end position.
+@param aChange Specifies whether the highlighting should be set or cleared.
+*/
+EXPORT_C CTextLayout::TRangeChange::TRangeChange(TInt aStart, TInt aEnd,
+	CTextLayout::TRangeChange::TChangeType aChange)
+	{
+	Set(aStart, aEnd, aChange);
+	}
+
+/** Gets the start and end of the range and whether the highlighting should be
+set or cleared.
+
+@param aStart On return, the start of the range. This is always the lesser of
+the two positions.
+@param aEnd On return, the end of the range. This is always the greater of the
+two positions.
+@return Specifies whether the highlighting should be set or cleared. */
+EXPORT_C CTextLayout::TRangeChange::TChangeType
+	CTextLayout::TRangeChange::Get(TInt& aStart, TInt& aEnd) const
+	{
+	if (iA < iB)
+		{
+		aStart = iA;
+		aEnd = iB;
+		return ESet;
+		}
+	aStart = iB;
+	aEnd = iA;
+	return EClear;
+	}
+
+/** Tests whether the range is not null.
+
+@return ETrue if the range is not of zero length, EFalse if the range is of zero
+length. */
+EXPORT_C TBool CTextLayout::TRangeChange::NonNull() const
+	{
+	return iA - iB;
+	}
+
+/** Clips the range so that its start and end positions are within the minimum
+and maximum positions specified.
+
+@param aMin The minimum value for the start and end of the range.
+@param aMax The maximum value for the start and end of the range.
+@return ETrue if the resulting range is not of zero length, EFalse if it is of
+zero length. */
+EXPORT_C TBool CTextLayout::TRangeChange::Clip(TInt aMin, TInt aMax)
+	{
+	if (iA < aMin)
+		iA = aMin;
+	if (iB < aMin)
+		iB = aMin;
+	if (aMax < iA)
+		iA = aMax;
+	if (aMax < iB)
+		iB = aMax;
+	return iA - iB;
+	}
+
+/** Try to cancel out sections of the ranges that overlap Merges two ranges of
+ characters.
+
+Two successive calls to CTextLayout::Highlight() could cause unecessary flicker
+or redrawing if the arguments to each call overlap. For example, if extending a
+highlight involved removing the old highlight and then drawing the new one,
+this would cause visible flicker. This can be eliminated by calling this
+function to remove any overlap between the two ranges. If there is overlap,
+this range is set to the result of the merge, and the other range (aBuddy) is
+set to zero.
+
+When calling this function, it does not matter whether or not the two ranges
+overlap. Also it does not matter which range is the parameter and which is the
+calling object. After calling OptimizeWith(), it is guaranteed that the
+resulting ranges will not overlap, and they will represent the same change to
+the highlight as the original two ranges.
+
+See the code fragment in the class description for TRangeChange for an example
+of how this function is used.
+
+@param aBuddy The range of characters to combine with this range. */
+EXPORT_C void CTextLayout::TRangeChange::OptimizeWith(TRangeChange& aBuddy)
+	{
+	// we make this have the minimum iA and iB, and aBuddy have the maximum
+	if (aBuddy.iA < iA)
+		{
+		TInt temp = aBuddy.iA;
+		aBuddy.iA = iA;
+		iA = temp;
+		}
+	if (aBuddy.iB < iB)
+		{
+		TInt temp = aBuddy.iB;
+		aBuddy.iB = iB;
+		iB = temp;
+		}
+	// if they now overlap, we combine them into one and zero the other
+	if (aBuddy.iB <= iA)
+		iA = aBuddy.iB = aBuddy.iA;
+	else if (aBuddy.iA <= iB)
+		iB = aBuddy.iA = aBuddy.iB;
+	}
+
+
+TBool CTextLayout::TRangeChange::IsJoinedTo(const TRangeChange aRange)
+	{
+	TInt a1 = (iA < iB) ? iA : iB;
+	TInt b1 = (iA < iB) ? iB : iA;
+	TInt a2 = (aRange.iA < aRange.iB) ? aRange.iA : aRange.iB;
+	TInt b2 = (aRange.iA < aRange.iB) ? aRange.iB : aRange.iA;
+
+	return a2 <= b1 && a1 <= b2;
+	}
+
+void CTextLayout::TRangeChange::Join(const TRangeChange aRange)
+	{
+	TInt a1 = (iA < iB) ? iA : iB;
+	TInt b1 = (iA < iB) ? iB : iA;
+	TInt a2 = (aRange.iA < aRange.iB) ? aRange.iA : aRange.iB;
+	TInt b2 = (aRange.iA < aRange.iB) ? aRange.iB : aRange.iA;
+
+	// type set to ESet
+	iA = (a1 < a2) ? a1 : a2;
+	iB = (b1 > b2) ? b1 : b2;
+	}
+
+
+/** Sets or clears a highlight.
+
+If the range of characters to highlight is of zero length, the function has no
+effect.
+
+The function affects only those lines that intersect aDrawRect, which is
+specified in window coordinates. The drawing parameters, including the graphics
+context, are given in aDrawTextLayoutContext.
+
+From v7.0, this function replaces InvertRangeL().
+
+This function is not intended to be used to set any part of a highlight already
+set, nor to clear any piece of text not highlighted. It is intended to do
+either or both of: clear an existing selection, set a new selection. See the
+class description for TRangeChange for a code fragment showing how this
+function should be used.
+
+@param aHighlight Specifies the range of characters to highlight or from which
+to remove the highlight.
+@param aDrawRect Only lines which intersect this rectangle are affected
+(specified in window coordinates).
+@param aDrawTextLayoutContext Provides a graphics context and other drawing
+parameters, e.g. the text and background colours for the highlighted region. */
+
+EXPORT_C void CTextLayout::Highlight(const CTextLayout::TRangeChange& aChangeHighlight,
+	const TRect& aDrawRect,	const TDrawTextLayoutContext* aDrawTextLayoutContext)
+	{
+	if (!aChangeHighlight.NonNull())
+		return;
+
+	TRect clip_rect(aDrawRect);
+
+	CGraphicsContext* gc = aDrawTextLayoutContext->PrimaryGc();
+	if (aDrawTextLayoutContext->UseClippingRect())
+		gc->SetClippingRect(clip_rect);
+
+	TInt visible_start;
+	TInt visible_length = PosRangeInBand(visible_start);
+
+	TInt start_pos;
+	TInt end_pos;
+
+	CTextLayout::TRangeChange::TChangeType type = aChangeHighlight.Get(start_pos, end_pos);
+	start_pos = start_pos < visible_start? visible_start : start_pos;
+	end_pos = end_pos < visible_start + visible_length? end_pos : start_pos + visible_length;
+	TCursorSelection selection(start_pos, end_pos);
+
+	TPoint top_left = aDrawTextLayoutContext->TopLeftText();
+	top_left.iY -= iBandTop;
+
+	TBool isDrawingOnAWindowDC = aDrawTextLayoutContext->UseWindowGc();
+
+	TRect boundingRect;
+	iText->GetUpdateBoundingRect(start_pos, end_pos, top_left, boundingRect);
+	iHighlightExtensions->AbsExtendRect(boundingRect);
+	boundingRect.Intersection(clip_rect);
+	if (! boundingRect.IsEmpty())
+		{
+		if (isDrawingOnAWindowDC)
+			{
+			BeginRedraw(boundingRect);
+			}
+		iText->DrawLayout(*gc, top_left, boundingRect, &aDrawTextLayoutContext->iBackgroundColor, TRUE, &selection, NULL);
+		if (isDrawingOnAWindowDC)
+			{
+			EndRedraw();
+			}
+		}
+	}
+
+void CTextLayout::HighlightUsingExtensions(const CTextLayout::TRangeChange& aChangeHighlight,const TRangeChange& aFullHighlight,
+	const TRect& aDrawRect,	const TDrawTextLayoutContext* aDrawTextLayoutContext)
+	{
+	if (!aChangeHighlight.NonNull())
+		return;
+
+	TRect clip_rect(aDrawRect);
+	clip_rect.Intersection(aDrawTextLayoutContext->TextArea());
+
+	CGraphicsContext* gc = aDrawTextLayoutContext->PrimaryGc();
+	if (aDrawTextLayoutContext->UseClippingRect())
+		{
+		gc->SetClippingRect(clip_rect);
+		}
+
+	TInt visible_start;
+	TInt visible_length = PosRangeInBand(visible_start);
+	TInt start_pos;
+	TInt end_pos;
+	CTextLayout::TRangeChange::TChangeType type = aChangeHighlight.Get(start_pos, end_pos);
+	start_pos = start_pos < visible_start? visible_start : start_pos;
+	end_pos = end_pos < visible_start + visible_length? end_pos : start_pos + visible_length;
+
+	TInt full_start_pos;
+	TInt full_end_pos;
+	(void)aFullHighlight.Get(full_start_pos, full_end_pos);
+	full_start_pos = full_start_pos < visible_start? visible_start : full_start_pos;
+	full_end_pos = full_end_pos < visible_start + visible_length? full_end_pos : full_start_pos + visible_length;
+	TCursorSelection selection(full_start_pos, full_end_pos);
+
+	TPoint top_left = aDrawTextLayoutContext->TopLeftText();
+	top_left.iY -= iBandTop;
+
+	TBool isDrawingOnAWindowDC = aDrawTextLayoutContext->UseWindowGc();
+
+	TRect boundingRect;
+	iText->GetUpdateBoundingRect(start_pos, end_pos, top_left, boundingRect);
+	iHighlightExtensions->AbsExtendRect(boundingRect);
+	boundingRect.Intersection(clip_rect);
+	if (! boundingRect.IsEmpty())
+		{
+		if (isDrawingOnAWindowDC)
+			{
+			BeginRedraw(boundingRect);
+			}
+		iText->DrawLayout(*gc, top_left, boundingRect, &aDrawTextLayoutContext->iBackgroundColor, TRUE, &selection, iHighlightExtensions);
+		if (isDrawingOnAWindowDC)
+			{
+			EndRedraw();
+			}
+		}
+
+	if (aDrawTextLayoutContext->UseClippingRect())
+		{
+		gc->CancelClippingRect();
+		}
+	}
+
+/** Toggles the selection highlight for the range of text in aHighlight.
+
+Highlights only those lines that intersect aDrawRect, which is specified in
+window coordinates. The drawing parameters, including the graphics context, are
+given in aDrawTextLayoutContext.
+
+In v7.0 and onwards, this function is deprecated -Highlight() should be used
+instead.
+@deprecated
+@param aHighlight The range of characters for which to invert the highlighting.
+@param aDrawRect Only lines which intersect this rectangle are affected;
+specified in window coordinates.
+@param aDrawTextLayoutContext Provides a graphics context and other drawing
+parameters. */
+EXPORT_C void CTextLayout::InvertRangeL(const TCursorSelection& aHighlight,const TRect& aDrawRect,
+	const TDrawTextLayoutContext* aDrawTextLayoutContext)
+	{
+	TRangeChange range(aHighlight.iAnchorPos, aHighlight.iCursorPos, TRangeChange::ESet);
+	HighlightUsingExtensions(range,range,aDrawRect,aDrawTextLayoutContext);
+	}
+
+/**
+Return the FORM major version number. This function is not generally useful. It
+is used in test code and was used while making a transition between this and
+the former version of FORM. The return value is always 2.
+*/
+EXPORT_C TInt CTextLayout::MajorVersion() const
+	{
+	return 2;
+	}
+
+/**
+This method allows Form clients to register an object able to
+create or return references to customisation objects used within Form for
+various tasks e.g. inline text.
+@param aProvider
+	Reference to interface provider object to register with Formm.
+*/
+EXPORT_C void CTextLayout::SetInterfaceProvider( MFormCustomInterfaceProvider* aProvider ) 
+    {
+    iSource->iInterfaceProvider = aProvider;
+    }
+
+/** Gets the width and height of the bounding box of the text, including
+indents and margins, when formatted to the specified wrap width.
+
+This is useful for applications like a web browser that need to determine the
+minimum width for a piece of text: if you specify zero as the wrap width, the
+returned aSize.iWidth contains the minimum width that could be used for the
+text without illegal line breaks, and if you specify KMaxTInt for aWrapWidth,
+the returned aSize.iHeight contains the minimum height: the height when each
+paragraph is a single line of unlimited length.
+ @since 6.0
+@param aWrapWidth The wrap width for the bounding box.
+@param aSize On return, contains the width and height of the bounding box. */
+EXPORT_C void CTextLayout::GetMinimumSizeL(TInt aWrapWidth,TSize& aSize)
+	{
+	//
+	//Get the size of the minimal bounding box of the text when formatted to the specified wrap width.
+	//The width may be greater than aWrapWidth. To find the minimum width for the text,
+	//pass 0 for aWrapWidth. To find the minimum height, pass KMaxTInt for aWrapWidth.
+	//
+	iText->GetMinimumLayoutSizeL(aWrapWidth,aSize);
+	}
+
+/** Gets the width and height of the bounding box of the text, including
+indents and margins, when formatted to the specified wrap width.
+
+This is useful for applications like a web browser that need to determine the
+minimum width for a piece of text: if you specify zero as the wrap width, the
+returned aSize.iWidth contains the minimum width that could be used for the
+text, and if you specify KMaxTInt for aWrapWidth, the returned aSize.iHeight
+contains the minimum height: the height when each paragraph is a single
+line of unlimited length. Use aAllowLegalLineBreaksOnly to set whether or
+not illegal line breaks should be considered when determining aSize.
+ @since 6.0
+@param aWrapWidth The wrap width for the bounding box.
+@param aAllowLegalLineBreaksOnly ETrue to only allow legal line breaks, or EFalse to also allow illegal line breaks.
+@param aSize On return, contains the width and height of the bounding box. */
+EXPORT_C void CTextLayout::GetMinimumSizeL(TInt aWrapWidth,TBool aAllowLegalLineBreaksOnly,TSize& aSize)
+	{
+	//
+	//Get the size of the minimal bounding box of the text when formatted to the specified wrap width.
+	//The width may be greater than aWrapWidth. To find the minimum width for the text,
+	//pass 0 for aWrapWidth. To find the minimum height, pass KMaxTInt for aWrapWidth.
+	//
+	iText->GetMinimumLayoutSizeL(aWrapWidth,aAllowLegalLineBreaksOnly,aSize);
+	}
+
+/** Sets the custom drawing object, for customising the way text and its
+background are drawn.
+@since 6.0
+@param aCustomDraw Pointer to a custom drawing object. */
+EXPORT_C void CTextLayout::SetCustomDraw(const MFormCustomDraw* aCustomDraw)
+	{
+	iSource->iCustomDraw = aCustomDraw;
+	}
+
+/** Returns a pointer to the current custom drawing implementation. Returns
+NULL if custom drawing is not in force.
+@since 6.0
+@return Pointer to the custom drawing object. */
+EXPORT_C const MFormCustomDraw* CTextLayout::CustomDraw() const
+	{
+	return iSource->iCustomDraw;
+	}
+
+/** Sets custom line breaking.
+
+If this function is not called, default line breaking behaviour is used.
+
+Ownership of the custom line breaking object is not transferred to this object.
+
+@param aCustomWrap A pointer to an object that implements the custom line
+breaking interface. Specify NULL to disable custom line breaking. */
+EXPORT_C void CTextLayout::SetCustomWrap(const MFormCustomWrap* aCustomWrap)
+	{
+	iSource->iCustomWrap = aCustomWrap;
+	}
+
+/** Gets the custom line breaking object, as set using SetCustomWrap().
+
+@return A pointer to the custom line breaking object, or NULL if custom line
+breaking is not in effect. */
+EXPORT_C const MFormCustomWrap* CTextLayout::CustomWrap() const
+	{
+	return iSource->iCustomWrap;
+	}
+
+/**
+@internalAll
+@released
+*/
+EXPORT_C void MFormCustomDraw::MFormCustomDraw_Reserved_2()
+	{
+	}
+
+/** This function is called whenever part of the background of a CTextLayout or
+CTextView object needs to be drawn. The default implementation fills
+aParam.iDrawRect with the colour specified in aBackground.
+
+The default background colour is contained in aBackground. This is the
+background colour of the paragraph if drawing text, or the background colour
+specified in the TDrawTextLayoutContext object passed to CTextLayout::DrawL()
+if drawing outside the text area.
+
+The rectangle which is drawn by this function, (this may not be the whole of
+aParam.iDrawRect) must be returned in aDrawn; areas not drawn by you are
+automatically filled using the colour aBackground.
+
+@param aParam Contains the drawing parameters: aParam.iGc is the graphics
+context to use. aParam.iMap is the graphics device map, which allows you to
+convert between pixels and twips and create fonts. aParam.iTextLayoutTopLeft is
+the origin of the text; bitmaps and other graphics must be drawn relative to
+this position. aParam.iDrawRect is the area to be drawn; do not draw outside
+this rectangle.
+@param aBackground The default background colour. This is the background colour
+of the paragraph if drawing text, or the background colour specified in the
+TDrawTextLayoutContext object passed to CTextLayout::DrawL() if drawing outside
+the text area.
+@param aDrawn Must return the rectangle you actually draw. This may not be the
+whole of aParam.iDrawRect (for instance, if you are drawing a non-tiled bitmap
+that occupies only part of aRect). */
+EXPORT_C void MFormCustomDraw::DrawBackground(const TParam& aParam,const TRgb& aBackground,TRect& aDrawn) const
+	{
+	MTmCustom c;
+	c.DrawBackground(aParam.iGc,aParam.iTextLayoutTopLeft,aParam.iDrawRect,aBackground,aDrawn);
+	}
+
+/** This function is called after the background has been drawn by
+DrawBackground(), and before drawing the text. This function might be used to
+draw a ruled line under each line of text.
+
+The default implementation of this function does nothing.
+
+@param aParam Contains the drawing parameters. You should only draw to
+aParam.iDrawRect. There is no need to fill aParam.iDrawRect or to indicate the
+rectangle drawn.
+@param aLineInfo Contains the line metrics: aLineInfo.iOuterLineRect specifies
+the bounding rectangle of the line, including margins, indents and automatic
+space above and below paragraphs, aLineInfo.iInnerLineRect specifies the bounds
+of the text only, aLineInfo.iBaseline specifies the baseline of the text. */
+EXPORT_C void MFormCustomDraw::DrawLineGraphics(const TParam& /*aParam*/,const TLineInfo& /*aLineInfo*/) const
+	{
+	// do nothing
+	}
+
+/** This function is called to draw the text and its highlighted background, if
+any, after bidirectional reordering and other character mappings have taken
+place.
+
+The default implementation of this function draws the text with no special
+effects and supports standard, round-cornered and shadowed highlighting only.
+The text is drawn with the left end of its baseline located at aTextOrigin
+after drawing the background, if any, in aParam.iDrawRect.
+
+The main reason to override this function is to apply custom text highlighting,
+(for this, aFormat.iFontPresentation.iHighlightStyle should be in the range
+EFontHighlightFirstCustomStyle to EFontHighlightLastCustomStyle).
+
+The horizontal spacing between the characters in the text string is increased
+by the number of pixels specified in aExtraPixels. The standard way to do this
+is by calling CGraphicsContext::SetCharJustification().
+
+The font and other graphics parameters (e.g. pen colour, font style), are
+specified in aParam.iGc but a character format container (aFormat) is supplied
+so that a different font can be used. Note that any graphics drawn cannot
+exceed the bounds of aParam.iDrawRect, so changes are usually restricted to
+drawing shadows, outlines, etc. if custom highlighting is in use.
+
+@param aParam Contains the drawing parameters. Drawing can only occur within
+aParam.iDrawRect.
+@param aLineInfo Contains the line metrics.
+@param aFormat Specifies the character formatting to apply to the text,
+including the type of text highlighting.
+@param aText The text string to be drawn.
+@param aTextOrigin The point at which the left end of the baseline of the text
+should be drawn.
+@param aExtraPixels The number of additional pixels to insert between the
+characters in the text string, in order to increase its length. */
+EXPORT_C void MFormCustomDraw::DrawText(const TParam& aParam,const TLineInfo& aLineInfo,const TCharFormat& aFormat,
+										const TDesC& aText,const TPoint& aTextOrigin,TInt aExtraPixels) const
+	{
+	TTmLineInfo info;
+	info.iOuterRect = aLineInfo.iOuterRect;
+	info.iInnerRect = aLineInfo.iInnerRect;
+	info.iBaseline = aLineInfo.iBaseline;
+
+	MTmCustom c;
+	c.DrawText(aParam.iGc,aParam.iTextLayoutTopLeft,aParam.iDrawRect,info,aFormat,
+			   aText,aTextOrigin,aExtraPixels);
+	}
+
+EXPORT_C void MFormCustomDraw::DrawText(const TParam& aParam,const TLineInfo& aLineInfo,const TCharFormat& aFormat,
+										const TDesC& aText,const TInt aStart, const TInt aEnd, const TPoint& aTextOrigin,TInt aExtraPixels) const
+	{
+	TTmLineInfo info;
+	info.iOuterRect = aLineInfo.iOuterRect;
+	info.iInnerRect = aLineInfo.iInnerRect;
+	info.iBaseline = aLineInfo.iBaseline;
+
+	MTmCustomExtension c;
+	c.DrawText(aParam.iGc,aParam.iTextLayoutTopLeft,aParam.iDrawRect,info,aFormat,
+			   aText,aStart,aEnd,aTextOrigin,aExtraPixels);
+	}
+
+/** This function translates logical colours specified in FORM objects into
+real colours. The default implementation just returns the default colour that
+is passed in and ignores aColorIndex.
+
+Overriding implementations may use aColorIndex in any desired way, either to
+replace or modify aDefaultColor. The values used in aColorIndex are taken from
+the top byte of a TLogicalRgb object and are thus in the range 0...255. The
+TLogicalRgb class defines two reserved values:
+TLogicalRgb::ESystemForegroundIndex = 254 and
+TLogicalRgb::ESystemBackgroundIndex = 255.
+*/
+EXPORT_C TRgb MFormCustomDraw::SystemColor(TUint /*aColorIndex*/,TRgb aDefaultColor) const
+	{
+	return aDefaultColor;
+	}
+
+void CTextLayout::DrawBackground(CGraphicsContext& aGc,const TPoint& aTopLeft,const TRect& aClipRect,
+								 const TLogicalRgb& aBackground) const
+	{
+	TPoint top_left(aTopLeft);
+	top_left.iY -= iBandTop;
+	iText->DrawBackground(aGc,top_left,aClipRect,aBackground);
+	}
+
+/** Returns the line break class for a Unicode character.
+
+For convenience, it also gets the range of consecutive characters (if any)
+according to the Unicode standard, including aCode, that share the same line
+break class.
+
+The Unicode line break classes are enumerated in class MTmCustom.
+
+Each character's line break class is obtained using LineBreakClass(). To find
+out whether a line break is allowed between two adjacent characters, call
+LineBreakPossible() with the line break classes of the two characters as
+arguments. For example, the line break class EClLineBreakClass (closing
+punctuation) applies to characters such as ")", "]" and ";". Line breaks are
+typically allowed after these characters, but not before, so a call to
+LineBreakPossible() with the arguments (EAlLineBreakClass, EClLineBreakClass)
+would return EFalse in the default implementation, but a call with
+(EClLineBreakClass, EAlLineBreakClass) would return ETrue.
+
+@param aCode The Unicode character code of interest.
+@param aRangeStart On return, contains the Unicode character code at the start
+of the range including aCode that shares the same line break class as aCode.
+@param aRangeEnd On return, contains the Unicode character code at the end of
+the range including aCode that shares the same line break class as aCode.
+@return The line break class assigned to the character. Line break classes are
+enumerated in class MTmCustom. */
+ EXPORT_C TUint MFormCustomWrap::LineBreakClass(TUint aCode,TUint& aRangeStart,TUint& aRangeEnd) const
+	{
+	// Create an instance of MTmCustom and then call the MTmCustom's functions for getting a Line Break class 
+	MTmCustom c;
+	TUint temp;
+	temp=c.LineBreakClass(aCode,aRangeStart,aRangeEnd);
+	return temp;
+	}
+
+/** Tests whether a line break is possible between two characters.
+
+If aHaveSpaces is true, the characters are not adjacent one or more space
+characters (with a line break class of ESpLineBreakClass) occur between them.
+
+The aPrevClass and aNextClass arguments never have the value ESpLineBreakClass.
+Instead, this function is called with the classes of the characters on either
+side of the space or run of spaces, (and if so, aHaveSpaces is true). This is
+so that line breaks can be prohibited between certain characters with
+intervening spaces, for instance an alphabetic character (EAlLineBreakClass,
+such as 'a') and a closing bracket, with a space inbetween.
+
+Additionally, the arguments to this function never have a value of
+ESaLineBreakClass. For such characters, GetLineBreakInContext() is called
+instead.
+
+@param aPrevClass The line break class of the previous non-space character.
+@param aNextClass The line break class of the next non-space character.
+@param aHaveSpaces ETrue if there are one or more space characters (with a line
+break class of ESpLineBreakClass) between aPrevClass and aNextClass. EFalse if
+not.
+@return ETrue if a line break is possible between characters with the two line
+break classes, EFalse if not. */
+EXPORT_C TBool MFormCustomWrap::LineBreakPossible(TUint aPrevClass,TUint aNextClass,TBool aHaveSpaces) const
+	{
+	MTmCustom c;
+	TBool temp;
+	temp=c.LineBreakPossible(aPrevClass,aNextClass,aHaveSpaces);
+	return temp;
+	}
+
+/** Gets the position of the first or last possible line break position in a
+text string.
+
+This function is called instead of LineBreakPossible() for runs of characters
+of class ESaLineBreakClass. It is used for South Asian languages like Thai, Lao
+and Khmer that have no spaces between words, so that line breaks must be
+calculated using dictionary lookup or a linguistic algorithm.
+
+The default implementation of this function just returns false.
+
+@param aText A string containing characters of class ESaLineBreakClass.
+@param aMinBreakPos A position within aText at which to begin searching for a
+possible line break position.
+@param aMaxBreakPos A position within aText at which to stop searching for a
+possible line break position.
+@param aForwards If ETrue, the function gets the first possible line break
+position (searches forwards from aMinBreakPos); if EFalse, gets the last one
+(searches backwards from aMaxBreakPos).
+@param aBreakPos On return, the position of the first or last possible line
+break within aText. This must be greater than zero and less than aText.Length()
+- 1, and must also be in the range aMinBreakPos to aMaxBreakPos.
+@return ETrue if a possible line break position is found, EFalse if not. */
+EXPORT_C TBool MFormCustomWrap::GetLineBreakInContext(const TDesC& aText,TInt aMinBreakPos,TInt aMaxBreakPos,
+													  TBool aForwards,TInt& aBreakPos) const
+	{
+	MTmCustom c;
+	TBool temp;
+	temp=c.GetLineBreakInContext(aText,aMinBreakPos,aMaxBreakPos,aForwards,aBreakPos);
+	return temp;
+	}
+
+/** Tests whether a character can overhang the right margin.
+
+This function can be overridden to customise the line breaking behaviour for
+closing punctuation in Japanese. Any characters for which this function returns
+ETrue are allowed to overhang the right margin. The rest will be moved to the
+next line.
+
+The default implementation of this function just returns false.
+
+@param aChar The Unicode character code of interest.
+@return ETrue if the character specified can overhang the right margin, EFalse if
+not. */
+EXPORT_C TBool MFormCustomWrap::IsHangingCharacter(TUint aChar) const
+	{
+	MTmCustom c;
+	TBool temp;
+	temp=c.IsHangingCharacter(aChar);
+	return temp;
+	}
+
+// Reserved functions are private until they are used
+/**
+ @internalAll
+ @released
+ */ 
+EXPORT_C void MFormCustomWrap::MFormCustomWrap_Reserved_1()
+	{
+	// reserved functions
+	}
+// Reserved functions are private until they are used. 
+/**
+ @internalAll
+ @released
+ */
+
+EXPORT_C void MFormCustomWrap::MFormCustomWrap_Reserved_2()
+	{
+	// reserved functions 
+	}
+
+#ifdef _DEBUG
+TBool CTextLayout::__DbgIsFormattingUpToDate() const
+	{
+	return iUnformattedStart == KMaxTInt;
+	}
+#endif
+
+// TLayDocTextSource stuff begins here.
+TLayDocTextSource::TLayDocTextSource():
+	iLayDoc(NULL),
+	iFlags(EWrap),
+	iWidth(KMaxTInt),
+	iEllipsis(0x2026),
+	iLabelsWidth(0),
+	iLabelsGutter(0),
+	iFormatMode(CLayoutData::EFScreenMode),
+	iImageDevice(NULL),
+	iLabelsDevice(NULL),
+	iFormatDevice(NULL),
+	iFontHeightIncreaseFactor(EDefaultFontHeightIncreaseFactor),
+	iMinimumLineDescent(EDefaultMinimumLineDescent),
+	iNonPrintingCharVisibility(),
+	iFormParam(NULL),
+	iCustomDraw(NULL),
+	iCustomWrap(NULL),
+	iInterfaceProvider(NULL),
+	iDrawOpaque(EFalse),
+	iExcessHeightRequired(0),
+	iInvisibleCharacterRemapper(NULL)
+	{
+	}
+
+MGraphicsDeviceMap& TLayDocTextSource::FormatDevice() const
+	{
+	if (!iFormatDevice)
+		CTextLayout::Panic(CTextLayout::EFormatDeviceNotSet);
+	if (iLabelsDevice && (iFlags & EUseLabelsDevice))
+		return *iLabelsDevice;
+	else
+		return *iFormatDevice;
+	}
+
+MGraphicsDeviceMap& TLayDocTextSource::InterpretDevice() const
+	{
+	if (!iImageDevice)
+		CTextLayout::Panic(CTextLayout::EImageDeviceNotSet);
+	if (iLabelsDevice && (iFlags & EUseLabelsDevice))
+		return *iLabelsDevice;
+	else
+		return *iImageDevice;
+	}
+
+TInt TLayDocTextSource::DocumentLength() const
+	{
+	return iLayDoc->LdDocumentLength();
+	}
+
+void TLayDocTextSource::GetText(TInt aPos,TPtrC& aText,TTmCharFormat& aFormat) const
+	{
+	TCharFormat f;
+	iLayDoc->GetChars(aText,f,aPos);
+	aFormat = f;
+	}
+
+void TLayDocTextSource::GetParagraphFormatL(TInt aPos,RTmParFormat& aFormat) const
+	{
+	CParaFormat f;
+	iLayDoc->GetParagraphFormatL(&f,aPos);
+
+	// Labels should not have a forced line height or borders so remove these (this is necessary for Agenda).
+	if (iFlags & EUseLabelsDevice)
+		{
+		f.iLineSpacingInTwips = 0;
+		f.iLineSpacingControl = CParaFormat::ELineSpacingAtLeastInTwips;
+		f.RemoveAllBorders();
+		}
+
+	aFormat.CopyL(f);
+	f.Reset();
+	}
+
+TRgb TLayDocTextSource::SystemColor(TUint aColorIndex,TRgb aDefaultColor) const
+	{
+	if (iCustomDraw)
+		return iCustomDraw->SystemColor(aColorIndex,aDefaultColor);
+	else if (iFormParam)
+		return iFormParam->SystemColor(aColorIndex,aDefaultColor);
+	else
+		return aDefaultColor;
+	}
+
+CPicture* TLayDocTextSource::PictureL(TInt aPos) const
+	{
+	return iLayDoc->PictureHandleL(aPos,MLayDoc::EForceLoadTrue);
+	}
+
+TInt TLayDocTextSource::GetPictureSizeInTwipsL(TInt aPos,TSize& aSize) const
+	{
+	return iLayDoc->GetPictureSizeInTwips(aSize,aPos);
+	}
+
+TInt TLayDocTextSource::ParagraphStart(TInt aPos) const
+	{
+	iLayDoc->LdToParagraphStart(aPos);
+	return aPos;
+	}
+
+TBool TLayDocTextSource::LabelModeSelect(TLabelType aType, TInt aPos)
+	{
+	if (!(iFlags & EUseLabelsDevice) && aType == EParLabel)
+		{
+		// Labels are not allowed on zero-length documents;
+		// this is required for Agenda (see ER5U defect EDNGASR-482LSF).
+		if (iLayDoc->LdDocumentLength() == 0)
+			return FALSE;
+
+		if (iLayDoc->SelectParagraphLabel(aPos))
+			{
+			iFlags |= EUseLabelsDevice;
+			return TRUE;
+			}
+		}
+	
+	return FALSE;
+	}
+
+void TLayDocTextSource::LabelMetrics(TLabelType aType, TSize& aLabelSize, TInt& aMarginSize) const
+	{
+	if (aType == EParLabel)
+		{
+		aLabelSize.iWidth = iLabelsWidth;
+		aLabelSize.iHeight = KMaxTInt;
+		aMarginSize = iLabelsWidth + iLabelsGutter;
+		}
+	else
+		{
+		aLabelSize.iWidth = 0;
+		aLabelSize.iHeight = 0;
+		aMarginSize = 0;
+		}
+	}
+
+void TLayDocTextSource::LabelModeCancel()
+	{
+	iLayDoc->CancelSelectLabel();
+	iFlags &= ~EUseLabelsDevice;
+	}
+
+/**
+This method is responsible for discovering interface extension objects
+requried by Form for the specified interface Uid.
+@param aInterfaceId
+	Identifier for the optional interface requried.
+@return
+	Pointer to object supporting the requested interface, 
+	or 0 if not supported.	
+*/
+TAny* TLayDocTextSource::GetExtendedInterface(const TUid& aInterfaceId)
+	{
+	TAny* interfacePtr = 0;
+
+	// First check to see if their is an external interface provider
+	// registered and ask it for the interface.
+	if (iInterfaceProvider)
+		{
+		interfacePtr = iInterfaceProvider->GetExtendedInterface( aInterfaceId );
+		}
+
+	// If interface still not supplied check self and parent to provide it
+	if (!interfacePtr)
+		{
+		if (aInterfaceId == KFormLabelApiExtensionUid)
+			{
+			return static_cast<MFormLabelApi*>(this);
+			}
+		else if(aInterfaceId == KTmTextDrawExtId)
+			{
+			return static_cast <MTmTextDrawExt*> (this);
+			}
+		else if(aInterfaceId == KTmCustomExtensionUid)
+			{
+			return static_cast <MTmCustomExtension*> (this);
+			}
+		else
+			{
+			// In this instance, calling the parent class will always return NULL
+			// but the pattern should be followed by all implementors for safety
+			return MTmSource::GetExtendedInterface(aInterfaceId);
+			}
+		}
+
+	// Return the interface object or 0 if not supported.
+	return interfacePtr;
+	}
+
+void TLayDocTextSource::SetLineHeight(const TLineHeightParam& aParam,TInt& aAscent,TInt& aDescent) const
+	{
+	// Increase the ascent by the font height increase percentage.
+	TLineHeightParam p = aParam;
+	p.iFontMaxAscent += ((p.iFontMaxAscent + p.iFontMaxDescent) * iFontHeightIncreaseFactor) / 100;
+
+	// Call the standard SetLineHeight.
+	MTmSource::SetLineHeight(p,aAscent,aDescent);
+
+	// iExcessHeightRequired is used when height of the highest glyph can be
+	// greater than CFont::AscentInPixels() and in iExactLineSpacing mode
+	// This value is set via CTextView::SetExcessHeightRequired()
+	if ( aParam.iExactLineHeight )
+		{
+		aAscent += iExcessHeightRequired;
+		aDescent -= iExcessHeightRequired;
+	}
+	
+	// Enforce the minimum descent; the following logic is borrowed from CLineLayout::WrapLineL in old FORM.
+	if (aAscent + aDescent <= iMinimumLineDescent && aDescent == 0)
+		{
+		aDescent = 1;
+		aAscent--;
+		}
+	else if (aDescent < iMinimumLineDescent)
+		aDescent = iMinimumLineDescent;
+
+	/*
+	Ensure the line is at least 1 pixel high and ascent and descent are non-negative so that assertion
+	TCursorPosition::GetLineRectL that cursor pos is contained in line rect doesn't fire.
+	*/
+	if (aAscent < 0)
+		aAscent = 0;
+	if (aDescent < 0)
+		aDescent = 0;
+	if (aAscent + aDescent == 0)
+		aDescent = 1;
+	}
+
+TBool TLayDocTextSource::CanMap() const
+	{
+	return iFormatMode == CLayoutData::EFScreenMode || iFormatMode == CLayoutData::EFWysiwygMode;
+	}
+
+TBool TLayDocTextSource::PageBreakInRange(TInt aStartPos,TInt aEndPos) const
+	{
+	if (CanMap() && iNonPrintingCharVisibility.PageBreaksVisible())
+		return iLayDoc->EnquirePageBreak(aStartPos,aEndPos - aStartPos);
+	else
+		return FALSE;
+	}
+
+void TLayDocTextSource::DrawBackground(CGraphicsContext& aGc,const TPoint& aTopLeft,const TRect& aRect,
+									   const TLogicalRgb& aBackground,TRect& aDrawn) const
+	{
+	ResetOpaque(aGc);
+	if (iCustomDraw)
+		{
+		MFormCustomDraw::TParam param(aGc,InterpretDevice(),aTopLeft,aRect);
+		TLogicalRgb background = aBackground;
+		FormUtil::LogicalToActualColor(iFormParam,background);
+		iCustomDraw->DrawBackground(param,background,aDrawn);
+		}
+	else
+		MTmSource::DrawBackground(aGc,aTopLeft,aRect,aBackground,aDrawn);
+	}
+
+void TLayDocTextSource::DrawLineGraphics(CGraphicsContext& aGc,const TPoint& aTopLeft,const TRect& aRect,
+										 const TTmLineInfo& aLineInfo) const
+	{
+	SetOpaque(aGc);
+	if (iCustomDraw)
+		{
+		MFormCustomDraw::TParam param(aGc,InterpretDevice(),aTopLeft,aRect);
+		MFormCustomDraw::TLineInfo lineinfo(aLineInfo.iOuterRect,aLineInfo.iInnerRect,aLineInfo.iBaseline);
+		iCustomDraw->DrawLineGraphics(param,lineinfo);
+		}
+	else
+		MTmSource::DrawLineGraphics(aGc,aTopLeft,aRect,aLineInfo);
+	ResetOpaque(aGc);
+	}
+
+void TLayDocTextSource::DrawText(CGraphicsContext& aGc,const TPoint& aTopLeft,const TRect& aRect,
+								 const TTmLineInfo& aLineInfo,const TTmCharFormat& aFormat,
+								 const TDesC& aText,const TPoint& aTextOrigin,TInt aExtraPixels) const
+	{
+	SetOpaque(aGc);
+	if (iCustomDraw)
+		{
+		MFormCustomDraw::TParam param(aGc,InterpretDevice(),aTopLeft,aRect);
+		MFormCustomDraw::TLineInfo lineinfo(aLineInfo.iOuterRect,aLineInfo.iInnerRect,aLineInfo.iBaseline);
+		TCharFormat f;
+		aFormat.GetTCharFormat(f);
+		iCustomDraw->DrawText(param,lineinfo,f,aText,aTextOrigin,aExtraPixels);
+		}
+	else
+		MTmSource::DrawText(aGc,aTopLeft,aRect,aLineInfo,aFormat,aText,aTextOrigin,aExtraPixels);
+	ResetOpaque(aGc);
+	}
+
+void TLayDocTextSource::DrawText(CGraphicsContext& aGc,const TPoint& aTopLeft,const TRect& aRect,
+								 const TTmLineInfo& aLineInfo,const TTmCharFormat& aFormat,
+								 const TDesC& aText,const TInt aStart, const TInt aEnd, const TPoint& aTextOrigin,TInt aExtraPixels) const
+	{
+	SetOpaque(aGc);
+	if (iCustomDraw)
+		{
+		MFormCustomDraw::TParam param(aGc,InterpretDevice(),aTopLeft,aRect);
+		MFormCustomDraw::TLineInfo lineinfo(aLineInfo.iOuterRect,aLineInfo.iInnerRect,aLineInfo.iBaseline);
+		TCharFormat f;
+		aFormat.GetTCharFormat(f);
+		iCustomDraw->DrawText(param,lineinfo,f,aText,aStart,aEnd,aTextOrigin,aExtraPixels);
+		}
+	else
+		MTmCustomExtension::DrawText(aGc,aTopLeft,aRect,aLineInfo,aFormat,aText,aStart,aEnd,aTextOrigin,aExtraPixels);
+	ResetOpaque(aGc);
+	}
+
+TBool TLayDocTextSource::LineBreakPossible(TUint aPrevClass,TUint aNextClass,TBool aHaveSpaces) const
+	
+	{
+	TBool temp;
+	if (iCustomWrap)
+		temp=iCustomWrap->LineBreakPossible(aPrevClass,aNextClass,aHaveSpaces);
+	else
+		temp=MTmSource::LineBreakPossible(aPrevClass,aNextClass,aHaveSpaces);
+	return temp;
+	}
+
+TUint TLayDocTextSource::LineBreakClass(TUint aCode,TUint& aRangeStart,TUint& aRangeEnd) const
+	{
+	TUint temp;
+	if (iCustomWrap)
+		temp=iCustomWrap->LineBreakClass(aCode,aRangeStart,aRangeEnd);
+	else
+		temp=MTmSource::LineBreakClass(aCode,aRangeStart,aRangeEnd);
+	return temp;
+	}
+
+
+TBool TLayDocTextSource::GetLineBreakInContext(const TDesC& aText,TInt aMinBreakPos,TInt aMaxBreakPos,
+												 TBool aForwards,TInt& aBreakPos) const
+	{
+	TBool temp;
+	if (iCustomWrap)
+		temp=iCustomWrap->GetLineBreakInContext(aText,aMinBreakPos,aMaxBreakPos,aForwards,aBreakPos);
+	else
+		temp=MTmSource::GetLineBreakInContext(aText,aMinBreakPos,aMaxBreakPos,aForwards,aBreakPos);
+	return temp;
+	}
+
+TBool TLayDocTextSource::IsHangingCharacter(TUint aChar) const
+	{
+	TBool temp;
+	if (iCustomWrap)
+		temp=iCustomWrap->IsHangingCharacter(aChar);
+	else
+		temp=MTmSource::IsHangingCharacter(aChar);
+	return temp;
+	}
+
+
+TUint TLayDocTextSource::Map(TUint aChar) const
+	{
+	// Check if custom formatting has been installed
+	if (iInvisibleCharacterRemapper)
+		{ // Then use the supplied custom invisible character remapping
+		return iInvisibleCharacterRemapper->Remap(aChar, iNonPrintingCharVisibility, *this);
+		}
+	else // Use the default
+		return MFormCustomInvisibleCharacterRemapper::DefaultMapping(aChar, iNonPrintingCharVisibility, *this);
+	}
+
+void TLayDocTextSource::DrawPicture(CGraphicsContext& aGc,
+									const TPoint& aTextLayoutTopLeft, const TRect& aRect,
+									MGraphicsDeviceMap& aDevice, const CPicture& aPicture) const
+	{
+	SetOpaque(aGc);
+	MTmSource::DrawPicture(aGc, aTextLayoutTopLeft, aRect, aDevice, aPicture);
+	ResetOpaque(aGc);
+	}
+
+//MTmTextDrawExt implementations 
+
+/**
+Draws a line. Implements MTmTextDrawExt::DrawLine().
+If the opaque drawing mode is active, then the line color will stay unchanged (it will not be
+alpha-blended in a case of a transparent window).
+@param aGc A reference to a graphics context. If the drawing mode is opaque, then this is a 
+           CWindowGc reference.
+@param aPt1 Line start point
+@param aPt2 Line end point
+*/
+void TLayDocTextSource::DrawLine(CGraphicsContext& aGc, const TPoint& aPt1, const TPoint& aPt2) const
+	{
+	SetOpaque(aGc);
+	aGc.DrawLine(aPt1, aPt2);
+	ResetOpaque(aGc);
+	}
+
+/**
+Draws a text. Implements MTmTextDrawExt::DrawText().
+If the opaque drawing mode is active, then the text color will stay unchanged (it will not be
+alpha-blended in a case of a transparent window).
+@param aGc A reference to a graphics context. If the drawing mode is opaqe, then this is a 
+           CWindowGc reference.
+@param aPt1 Text start point
+*/
+void TLayDocTextSource::DrawText(CGraphicsContext& aGc, const TDesC& aText, const TPoint& aPt) const
+	{
+	SetOpaque(aGc);
+	aGc.DrawText(aText, aPt);
+	ResetOpaque(aGc);
+	}
+
+/**
+Draws a rectangle. Implements MTmTextDrawExt::DrawRect().
+If the opaque drawing mode is active, then the rectabgle color will stay unchanged (it will not be
+alpha-blended in a case of a transparent window).
+@param aGc A reference to a graphics context. If the drawing mode is opaqe, then this is a 
+           CWindowGc reference.
+@param aRc Rectangle coordinates
+*/
+void TLayDocTextSource::DrawRect(CGraphicsContext& aGc, const TRect& aRc) const
+	{
+	SetOpaque(aGc);
+	aGc.DrawRect(aRc);
+	ResetOpaque(aGc);
+	}
+
+/**
+Sets opaque drawing mode.
+@param aGc A reference to a graphics context. If the drawing mode is opaqe, then this is a 
+           CWindowGc reference.
+*/
+void TLayDocTextSource::SetOpaque(CGraphicsContext& aGc) const
+	{
+	if(iDrawOpaque)
+		{
+		static_cast <CWindowGc&> (aGc).SetOpaque(ETrue);
+		}
+	}
+
+/**
+Resets opaque drawing mode.
+@param aGc A reference to a graphics context. If the drawing mode is opaqe, then this is a 
+           CWindowGc reference.
+*/
+void TLayDocTextSource::ResetOpaque(CGraphicsContext& aGc) const
+	{
+	if(iDrawOpaque)
+		{
+		static_cast <CWindowGc&> (aGc).SetOpaque(EFalse);
+		}
+	}
+
+// Private CTextLayout functions start here.
+
+void CTextLayout::Panic(TPanicNumber aNumber)
+	{
+	_LIT(KPanicNumber,"CTextLayout using TAGMA");
+	User::Panic(KPanicNumber,aNumber);
+	}
+
+void CTextLayout::GetParagraphRect(const TTmDocPos& aDocPos,TRect& aRect) const
+	{
+	aRect.SetRect(0,0,0,0);
+	TTmLineInfo info, info2;
+	if (!iText->DocPosToLine(aDocPos,info))
+		return;
+	aRect = info.iOuterRect;
+	if (!(info.iFlags & TTmLineInfo::EParStart))
+		{
+		iText->ParNumberToLine(info.iParNumber,0,info2);
+		aRect.iTl = info2.iOuterRect.iTl;
+		}
+	if (!(info.iFlags & TTmLineInfo::EParEnd))
+		{
+		iText->ParNumberToLine(info.iParNumber,KMaxTInt,info2);
+		aRect.iBr = info2.iOuterRect.iBr;
+		}
+	aRect.Move(0,-iBandTop);
+	}
+
+/**
+Scroll aDy pixels (positive = text moves down); return number of pixels
+actually scrolled. Create a new formatted band if necessary.
+*/
+TInt CTextLayout::ScrollL(TInt aDy,TAllowDisallow aScrollBlankSpace,
+        TBool aTopNoLimitBorder/*=EFalse*/,
+        TBool aBottomNoLimitBorder/*=EFalse*/)
+	{
+	if ( EFDisallowScrollingBlankSpace == aScrollBlankSpace )
+	    {
+	    aTopNoLimitBorder = EFalse;
+	    aBottomNoLimitBorder = EFalse;
+	    }
+	int old_bandtop = iBandTop;
+	int desired_bandtop = iBandTop - aDy;
+	int pixels_scrolled = 0;
+	int height_increase = 0;
+	int paragraphs_increase = 0;
+	TTmFormatParamBase param;
+	InitFormatParam(param);
+	// Refuse to scroll if the width is illegal. This prevents
+	// time being taken in certain situations where it does
+	// not matter. Once the formatting is capable of
+	// adding smaller chunks of text at a time, this early-out
+	// should become unnecessary.
+	if ((param.iWrapWidth < 1 || param.iMaxHeight < 1)
+		&& param.iFlags & TTmFormatParamBase::EWrap)
+		return 0;
+	param.iMaxHeight = KMaxTInt;
+	int visible_height = VisibleHeightInPixels();
+	if (aDy > 0)		// text moves down; iBandTop decreases
+		{
+		if (aTopNoLimitBorder)
+	        iBandTop = desired_bandtop;
+		else
+		    iBandTop = Max(0,desired_bandtop);//Disallow text scrolled beyond top border
+		
+		pixels_scrolled = old_bandtop - iBandTop;
+		while (pixels_scrolled < aDy)
+			{
+			if (!iText->AddParL(param,TRUE,height_increase,paragraphs_increase))
+				break;
+			pixels_scrolled += height_increase;
+			}
+		if (pixels_scrolled > aDy)
+			{
+			iBandTop = pixels_scrolled - aDy;
+			pixels_scrolled = aDy;
+			}
+		}
+	else if (aDy < 0)	// text moves up; iBandTop increases
+		{
+        if (aBottomNoLimitBorder)
+            iBandTop = desired_bandtop;
+        else
+            iBandTop = Min(iText->LayoutHeight(),desired_bandtop);//Disallow text scrolled beyond bottom border
+
+		pixels_scrolled = old_bandtop - iBandTop;
+		while (pixels_scrolled > aDy)
+			{
+			if (!AddFormattingAtEndL(param, height_increase,paragraphs_increase))
+				break;
+			pixels_scrolled -= height_increase;
+			if (pixels_scrolled < aDy)
+				{
+				height_increase -= aDy - pixels_scrolled;
+				pixels_scrolled = aDy;
+				}
+			iBandTop += height_increase;
+			}
+		
+		// Fill in missing part of visible height.
+		while (iText->LayoutHeight() - iBandTop < visible_height)
+			{
+			if (!AddFormattingAtEndL(param, height_increase,paragraphs_increase))
+				break;
+			}
+		}
+
+	// Scroll blank space off the display if desired.
+	if (aScrollBlankSpace == EFDisallowScrollingBlankSpace && iText->LayoutHeight() - iBandTop < visible_height)
+		{
+		int new_bandtop = iText->LayoutHeight() - visible_height;
+		if (new_bandtop < 0)
+			new_bandtop = 0;
+		pixels_scrolled += iBandTop - new_bandtop;
+		iBandTop = new_bandtop;
+		}
+
+	PruneFormatL(aDy < 0);
+	return pixels_scrolled + SetBandTop();
+	}
+
+TInt CTextLayout::ScrollDocPosIntoViewL(const TTmDocPos& aDocPos)
+	{
+	__ASSERT_DEBUG(aDocPos.iPos <= iText->Source()->DocumentLength(),
+		Panic(EInvalidDocPos));
+	TTmLineInfo info;
+	ExtendFormattingToCoverPosL(aDocPos.iPos);
+	if (!iText->DocPosToLine(aDocPos,info))
+		{
+		__ASSERT_DEBUG(iText->Source()->DocumentLength() == 0,
+			Panic(ECharacterNotFormatted));
+		return ScrollL(iBandTop, EFDisallowScrollingBlankSpace);
+		}
+	TRect line_rect = info.iOuterRect;
+	line_rect.Move(0,-iBandTop);
+	int visible_height = VisibleHeightInPixels();
+	// if the line is taller than the screen, we must not scroll the
+	// baseline off the screen.
+	if (visible_height < info.iBaseline - info.iOuterRect.iTl.iY)
+		return ScrollL(iBandTop + visible_height - info.iBaseline,
+			EFDisallowScrollingBlankSpace);
+	if (line_rect.iTl.iY < 0)
+		return ScrollL(-line_rect.iTl.iY, EFDisallowScrollingBlankSpace);
+	if (line_rect.iBr.iY > visible_height)
+		{
+		int available = line_rect.iTl.iY;
+		int desired = line_rect.iBr.iY - visible_height;
+		if (available > 0)
+			return ScrollL(-Min(desired,available), EFDisallowScrollingBlankSpace);
+		}
+	return 0;
+	}
+
+EXPORT_C TInt CTextLayout::GetLineNumber(TInt aDocPos)
+	{
+	TTmLineInfo info;
+	TTmDocPos pos(aDocPos,TRUE);
+	if (iText->DocPosToLine(pos,info))	
+		return info.iLineNumber;
+	return 0;
+	};
+
+
+/*
+Prune the formatted band, if not formatting all the text, to the required size. If aFromStart is ETrue
+prune from the start, otherwise prune from the end.
+*/
+void CTextLayout::PruneFormatL(TBool aFromStart)
+	{
+	if (IsFormattingBand())
+		{
+		int pixels_to_prune = 0;
+		if (aFromStart)
+			pixels_to_prune = iBandTop;
+		else
+			pixels_to_prune = iText->LayoutHeight() - iBandTop - BandHeightInPixels();
+		if (pixels_to_prune <= 0)
+			return;
+		TTmFormatParamBase param;
+		InitFormatParam(param);
+		int height_decrease = 0;
+		if(aFromStart)
+			{
+			while (pixels_to_prune > 0 && iText->DeletePar(param,aFromStart,pixels_to_prune,height_decrease))
+				{
+				pixels_to_prune -= height_decrease;
+				if (aFromStart)
+					iBandTop -= height_decrease;
+				}
+			}
+		else
+			{
+			if (pixels_to_prune > (iBandHeight/2))
+				{
+				iText->DeleteFormattingFromEndL(param,pixels_to_prune,height_decrease);
+				}
+			}
+		}
+	}
+
+/** Sets the hotspot.
+
+@param aHotSpot Which part of the line (top, baseline or bottom) should appear
+at a vertical pixel position. */
+EXPORT_C void TViewYPosQualifier::SetHotSpot(TPartOfLine aHotSpot)
+	{
+	iHotSpot = aHotSpot;
+	}
+
+/** Sets whether blank space should be allowed at the bottom of the view. This
+applies if the document is more than one page long and the last line is
+visible.
+
+@param aFillScreen ETrue (the default) tries to fill the screen, by ensuring
+that there is as little blank space as possible at the bottom of the view.
+EFalse allows blank space at the bottom. */
+EXPORT_C void TViewYPosQualifier::SetFillScreen(TBool aFillScreen)
+	{
+	iFillScreen = aFillScreen;
+	}
+
+/** Forces the top line in the view to become fully visible if it is partially
+above the top of the view rectangle.
+
+@param aMakeLineFullyVisible EFViewForceLineFullyVisible (the default) forces
+the top line to be fully visible EFViewDontForceLineFullyVisible does not. */
+EXPORT_C void TViewYPosQualifier::SetMakeLineFullyVisible(TFullyVisible aMakeLineFullyVisible)
+	{
+	iFullyVisible = aMakeLineFullyVisible;
+	}
+
+void CTextLayout::InitFormatParam(TTmFormatParamBase& aParam)
+	{
+	aParam.iMaxHeight = BandHeightInPixels();
+	iSource->iExcessHeightRequired = iExcessHeightRequired;
+
+	aParam.iFlags = TTmFormatParamBase::EAtLeastMaxHeight;
+	aParam.iWrapWidth = iSource->iWidth;
+	if (iSource->iFlags & TLayDocTextSource::EWrap)
+		aParam.iFlags |= TTmFormatParamBase::EWrap;
+	if (iSource->iFlags & TLayDocTextSource::ETruncateWithEllipsis)
+		{
+		aParam.iFlags |= TTmFormatParamBase::ETruncateWithEllipsis;
+		aParam.iEllipsis = iSource->iEllipsis;
+		}
+	}
+
+TInt CTextLayout::VisibleHeightInPixels() const
+	{
+	if (iSource->iFormatMode == CLayoutData::EFScreenMode || iSource->iFormatMode == CLayoutData::EFWysiwygMode)
+		return iVisibleHeight;
+	else
+		return iSource->InterpretDevice().VerticalTwipsToPixels(iVisibleHeight);
+	}
+
+TInt CTextLayout::BandHeightInPixels() const
+	{
+	if (iBandHeight == CLayoutData::EFHeightForFormattingAllText)
+		return CLayoutData::EFHeightForFormattingAllText;
+	else
+		return VisibleHeightInPixels();
+	}
+
+/**
+Sets offsets for the edges of the selection highlight.
+@param aLeftExtension
+	Number of pixels to move the left edge of the highlight to the left.
+@param aRightExtension
+	Number of pixels to move the right edge of the highlight to the right.
+@param aTopExtension
+	Number of pixels to move the top edge of the highlight to up.
+@param aBottomExtension
+	Number of pixels to move the bottom edge of the highlight down.
+*/
+EXPORT_C void CTextLayout::SetHighlightExtensions(TInt aLeftExtension,
+	TInt aRightExtension, TInt aTopExtension, TInt aBottomExtension)
+	{
+	iHighlightExtensions->SetLeftExtension(aLeftExtension);
+	iHighlightExtensions->SetRightExtension(aRightExtension);
+	iHighlightExtensions->SetTopExtension(aTopExtension);
+	iHighlightExtensions->SetBottomExtension(aBottomExtension);
+	}
+
+/**
+Set the delta required to position the baseline so there is enough
+space for the highset glyph in pixels.  This is the height of the highest glyph - 
+CFont::AscentInPixels().  Only used when using TLineSpacingControl::EAttLineSpacingControl.
+By default zero.
+@param aExcessHeightRequired
+	Extra height above CFont::AscentInPixels() required for the highest glyph in pixels.
+*/
+void CTextLayout::SetExcessHeightRequired(TInt aExcessHeightRequired) 
+	{
+	iExcessHeightRequired = aExcessHeightRequired;
+	}
+
+/**
+For any rectangle, aRect, which may be extended, calculate
+the "remainder" rectanges when the view rectangle is intersected with the
+extended rect and then subtracted.
+The remainder rectangles are returned via aRemainderRects, which is required
+to be a pointer to an array of 4 TRect's.
+aRemainderRects[0] is top remainder, ...[1] is bottom, ...[2] is left, ...[3] is right
+*/
+void CTextLayout::GetHighlightRemnants(const TRect& aRect, const TDrawTextLayoutContext& aDrawTextLayoutContext,
+									   TRect* aRemainderRects) const
+	{
+	ASSERT(aRemainderRects);
+	/*
+	overlap is the portion of the view rect that aRect intersects with
+	subtract this from the aRect, giving 4 non-overlapping remainder rectangles,
+	aRemainderRects, any or all of which may be empty. Copied from SubtractRect in TAGMA
+	*/
+	TRect overlap(aDrawTextLayoutContext.iViewRect);
+	overlap.Intersection(aRect);
+	if (overlap.IsEmpty())
+		overlap.SetRect(aRect.iTl,aRect.iTl);
+	aRemainderRects[0] = aRect;
+	aRemainderRects[0].iBr.iY = overlap.iTl.iY;
+	aRemainderRects[1] = aRect;
+	aRemainderRects[1].iTl.iY = overlap.iBr.iY;
+	aRemainderRects[2] = overlap;
+	aRemainderRects[2].iTl.iX = aRect.iTl.iX;
+	aRemainderRects[2].iBr.iX = overlap.iTl.iX;
+	aRemainderRects[3] = overlap;
+	aRemainderRects[3].iTl.iX = overlap.iBr.iX;
+	aRemainderRects[3].iBr.iX = aRect.iBr.iX;
+	}
+
+/**
+Cleanup method for the opaque flag.
+*/
+void CTextLayout::ResetOpaque(void* aThis)
+	{
+	ASSERT(aThis != NULL);
+	CTextLayout* p = reinterpret_cast <CTextLayout*> (aThis);
+	p->iSource->iDrawOpaque = EFalse;
+	}
+
+/**
+Sets opaque drawing flag for CTextLayout object. It will used later when the 
+content/background has to be drawn.
+Until the flag is not reseted, the opaque drawing will be used 
+for all the content except the background - the flag has an useful meaning only for transparent
+editors.
+A TCleanupItem object will be pushed into the Cleanup Stack, which will reset the opaque
+flag durring its destruction.
+*/
+void CTextLayout::SetOpaqueLC()
+	{
+	iSource->iDrawOpaque = ETrue;
+	CleanupStack::PushL(TCleanupItem(&CTextLayout::ResetOpaque, this));
+	}
+
+void FormPanic(TFormPanic aPanic)
+	{
+	_LIT(KFormPanic,"Form");
+	User::Panic(KFormPanic,aPanic);
+	}
+
+/**
+Default implementation of mapping invisible character to its specified alternate.
+
+Called by TLayDocTextSource::Map() unless overidden by custom mapping class.
+May be called by custom mapping class
+@param aChar
+	Invisible character to be remapped
+@param aNonPrintingCharVisibility
+	Current state of flags showing visibility of invisible characters
+@param aLayDoc
+	Const ref to the calling CLayDocTextSource
+@return
+	The replacement character if remapping has taken place, else return original character
+*/
+EXPORT_C TUint MFormCustomInvisibleCharacterRemapper::DefaultMapping( TUint aChar, const TNonPrintingCharVisibility aNonPrintingCharVisibility, const TLayDocTextSource& aLayDoc )
+	{
+	// If mapping special characters is possible, use the specified flags.
+	if (!aNonPrintingCharVisibility.NoneVisible() && aLayDoc.CanMap())
+		{
+		switch (aChar)
+			{
+			case CEditableText::EParagraphDelimiter:
+				if (aNonPrintingCharVisibility.ParagraphDelimitersVisible())
+					return KVisibleParagraphBreak;
+				break;
+
+			case CEditableText::ELineBreak:
+				if (aNonPrintingCharVisibility.LineBreaksVisible())
+					return KVisibleLineBreak;
+				break;
+
+			case CEditableText::ENonBreakingSpace:
+				if (aNonPrintingCharVisibility.NonBreakingSpacesVisible())
+					return KVisibleNonBreakSpace;
+				break;
+
+			case CEditableText::EPotentialHyphen:
+				if (aNonPrintingCharVisibility.PotentialHyphensVisible())
+					return KVisiblePotentialHyphen;
+				break;
+
+			case CEditableText::ENonBreakingHyphen:
+				if (aNonPrintingCharVisibility.NonBreakingHyphensVisible())
+					return KVisibleNonBreakHyphen;
+				break;
+
+			case CEditableText::ETabCharacter:
+				if (aNonPrintingCharVisibility.TabsVisible())
+					return KVisibleTab;
+				break;
+
+			case CEditableText::EPictureCharacter:
+				return KVisiblePicture;
+
+            case 0x200B:    // Zero Width Space: the same behaviour as 0x20, while different category from 0x20.
+                if (aNonPrintingCharVisibility.SpacesVisible())
+                   return KVisibleSpace;
+                break;
+                   
+			/*
+			For the moment, treat bidirectional controls as if they were non-break spaces, as far as visibility is
+			concerned, and map as follows: LRE=<, RLE=>, PDF=currency symbol, LRO=left guillemet, RLO=right guillemet.
+			*/
+			case 0x202A: // LRE
+				if (aNonPrintingCharVisibility.NonBreakingSpacesVisible())
+					return 0x003C;
+				break;
+			case 0x202B: // RLE
+				if (aNonPrintingCharVisibility.NonBreakingSpacesVisible())
+					return 0x003E;
+				break;
+			case 0x202C: // PDF
+				if (aNonPrintingCharVisibility.NonBreakingSpacesVisible())
+					return 0x00A4;
+				break;
+			case 0x202D: // LRO
+				if (aNonPrintingCharVisibility.NonBreakingSpacesVisible())
+					return 0x00AB;
+				break;
+			case 0x202E: // RLO
+				if (aNonPrintingCharVisibility.NonBreakingSpacesVisible())
+					return 0x00BB;
+				break;
+
+			default:
+				if (aNonPrintingCharVisibility.SpacesVisible() && TChar(aChar).GetCategory() == TChar::EZsCategory)
+					return KVisibleSpace;
+				break;
+			}
+		}
+
+	// If not mapping special characters, or not mapping this particular character, use the default mapping.
+	return aLayDoc.MTmSource::Map(aChar);
+	}
+
+
+/**
+Allows Form clients to register an invisible character remapper object to 
+customize the visible display of invisible characters such as paragraph marks.
+@param aInvisibleCharacterRemapper
+	Pointer to custom invisible character remapper to use
+*/
+EXPORT_C void CTextLayout::SetCustomInvisibleCharacterRemapper( MFormCustomInvisibleCharacterRemapper* aInvisibleCharacterRemapper ) 
+	{
+	iSource->iInvisibleCharacterRemapper = aInvisibleCharacterRemapper;
+	}
+
+/**
+Allows Form clients to see which character remapper object is currently 
+registered.
+*/
+EXPORT_C MFormCustomInvisibleCharacterRemapper* CTextLayout::GetCustomInvisibleCharacterRemapper()
+	{
+	return iSource->iInvisibleCharacterRemapper;
+	}
+
+/** INC092568: CTextView::SetPendingSelection is not honoured
+Sets the cursor position member added for this fix that allows the text layout object
+to access any pending selection made by the owning text view object
+@param aPos:- pointer to the owning textview's iCursorPos
+*/
+void CTextLayout::SetTextViewCursorPos(TCursorPosition* aPos)
+	{
+	iTextViewCursorPos = aPos;
+	}
+
+/**
+This is the function used by CTextLayout when it wants to extend the formatted range downwards. 
+It just calls CTmTextLayout::AddParL, but restricts the maximum height of the new formatting to the 
+band height/2. If the next paragraph is bigger than this, AddParL will only format part of that 
+paragraph, and the formatting will end in the middle of the paragraph.
+*/
+TBool CTextLayout::AddFormattingAtEndL(TTmFormatParamBase& aFormatParam, TInt& aHeightIncrease, TInt& aParagraphsIncrease)
+	{
+	aFormatParam.iMaxHeight = iBandHeight/2;
+	return iText->AddParL(aFormatParam, EFalse, aHeightIncrease, aParagraphsIncrease);
+	}
+	
+/** 
+Stops or allows text to be drawn.  Included to allow users to control visibility
+if text is part of an invisible control.
+
+@param aVisible		ETrue to make the text visible, EFalse to make it invisible.
+@see CCoeControl::MakeVisible()
+*/
+EXPORT_C void CTextLayout::MakeVisible(TBool aVisible)
+	{
+	iText->MakeVisible(aVisible);
+	}
+