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