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