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