textrendering/textformatting/tbox/FRMTVIEW.CPP
changeset 0 1fb32624e06b
child 40 91ef7621b7fc
equal deleted inserted replaced
-1:000000000000 0:1fb32624e06b
       
     1 /*
       
     2 * Copyright (c) 1997-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 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "FRMTLAY.H"
       
    20 #include "FRMTVIEW.H"
       
    21 #include "FRMCONST.H"
       
    22 
       
    23 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    24 #include "FRMCONST_INTERNAL.H"
       
    25 #include "FRMCONST_PARTNER.H"
       
    26 #include "TAGMA_INTERNAL.H"
       
    27 #endif
       
    28 
       
    29 /** Reports whether a character is a virama (indic vowel-killer,
       
    30 used for joining syllables together) or not.
       
    31 @param aCharacter The character.
       
    32 @return ETrue if aCharacter is a virama.
       
    33 @internalComponent */
       
    34 TBool IsVirama(TChar aCharacter)
       
    35 	{
       
    36 	// Unicode combining class 9 indicates a virama
       
    37 	return aCharacter.GetCombiningClass() == 9;
       
    38 	}
       
    39 
       
    40 /**
       
    41 Reports whether a character is a graphical spacing character or not.
       
    42 @param aCharacter Unicode UTF32 character to test.
       
    43 @return ETrue if it is both graphical and not a combining mark.
       
    44 @internalComponent
       
    45 */
       
    46 TBool IsGraphicalSpacing(TChar aCharacter)
       
    47 	{
       
    48 	TChar::TCategory cat = aCharacter.GetCategory();
       
    49 	switch (cat & 0xF0)
       
    50 		{
       
    51 	case TChar::EAlphaGroup:
       
    52 	case TChar::ELetterOtherGroup:
       
    53 	case TChar::ELetterModifierGroup:
       
    54 	case TChar::ENumberGroup:
       
    55 	case TChar::EPunctuationGroup:
       
    56 	case TChar::ESymbolGroup:
       
    57 		return ETrue;
       
    58 	default:
       
    59 		return EFalse;
       
    60 		}
       
    61 	}
       
    62 
       
    63 TCursor::TCursor(TCursorPosition& aCursorPos,RScreenDisplay& aDisplay):
       
    64 	iDisplay(aDisplay),
       
    65 	iCursorPos(aCursorPos),
       
    66 	iVisible(FALSE),
       
    67 	iFlash(TRUE),
       
    68 	iLineCursor(EFCursorInvisible),
       
    69 	iTextCursor(EFCursorInvisible),
       
    70 	iLineCursorBitmap(NULL),
       
    71 	iAscent(-1),
       
    72 	iDescent(-1),
       
    73 	iWeight(ETextCursorWeight),
       
    74 	iType(TTextCursor::ETypeRectangle),
       
    75 	iXorColor(ETextCursorInvertColor),
       
    76 	iPlacement(ECursorVertical)
       
    77 	{
       
    78 	}
       
    79 
       
    80 void TCursor::SetLineCursorBitmap(const CFbsBitmap* aLineCursorBitmap)
       
    81 	{
       
    82 	iLineCursorBitmap=aLineCursorBitmap;
       
    83 	}
       
    84 
       
    85 /**
       
    86 Sets the selection highlight to have its edges moved by the specified number of pixels.
       
    87 Problems with highlights appearing in the wrong place may be due to incorrect 
       
    88 font metrics, and would not be fixed in general with a call to this function.
       
    89 @param aLeftExtension
       
    90 	Number of pixels to the left to move the left of the highlight.
       
    91 @param aRightExtension
       
    92 	Number of pixels to the right to move the right of the highlight.
       
    93 @param aTopExtension
       
    94 	Number of pixels to the up to move the top of the highlight.
       
    95 @param aBottomExtension
       
    96 	Number of pixels to the down to move the bottom of the highlight.
       
    97 */
       
    98 EXPORT_C void CTextView::SetHighlightExtensions(TInt aLeftExtension,
       
    99 	TInt aRightExtension, TInt aTopExtension, TInt aBottomExtension)
       
   100 	{
       
   101 	iLayout->SetHighlightExtensions(aLeftExtension, aRightExtension,
       
   102 		aTopExtension, aBottomExtension);
       
   103 	}
       
   104 
       
   105 /**
       
   106 Set the delta required to position the baseline so there is enough
       
   107 space for the highset glyph in pixels.  This is the height of the highest glyph - 
       
   108 CFont::AscentInPixels().  Only used when using TLineSpacingControl::EAttLineSpacingControl.
       
   109 By default zero.
       
   110 @param aExcessHeightRequired
       
   111 	Extra height above CFont::AscentInPixels() required for the highest glyph in pixels.
       
   112 */
       
   113 EXPORT_C void CTextView::SetExcessHeightRequired(TInt aExcessHeightRequired)
       
   114 	{
       
   115 	iLayout->SetExcessHeightRequired( aExcessHeightRequired );
       
   116 	}
       
   117 
       
   118 void TCursor::SetVisibility(TVisibility aLineCursor,TVisibility aTextCursor)
       
   119 	{
       
   120 	TUint cursorsToDraw=EFNeitherCursor;
       
   121 
       
   122 	if (aLineCursor==EFCursorFlashing)
       
   123 		aLineCursor=EFCursorVisible;
       
   124 	if (iLineCursor!=aLineCursor)
       
   125 		{
       
   126 		iLineCursor=aLineCursor;
       
   127 		cursorsToDraw|=EFLineCursor;
       
   128 		}
       
   129 	if (iTextCursor!=aTextCursor)
       
   130 		{
       
   131 		iTextCursor=aTextCursor;
       
   132 		cursorsToDraw|=EFTextCursor;
       
   133 		}
       
   134 	Draw(cursorsToDraw);
       
   135 	}
       
   136 
       
   137 // Change the cursor type and redraw it.
       
   138 void TCursor::SetType(TTextCursor::EType aType)
       
   139 	{
       
   140 	if (aType != TTextCursor::ETypeNone)
       
   141 		{
       
   142 		iType = aType;
       
   143 		Draw(EFTextCursor);
       
   144 		}
       
   145 	}
       
   146 
       
   147 // Change the cursor placement and redraw it.
       
   148 void TCursor::SetPlacement(TTmCursorPlacement aPlacement)
       
   149 	{
       
   150 	iPlacement = aPlacement;
       
   151 	Draw(EFTextCursor);
       
   152 	}
       
   153    
       
   154 /** Sets the ascent and descent of the text cursor in pixels and redraw it. To
       
   155 use the ascent or descent of the adjacent character pass a value of -1. */
       
   156 void TCursor::SetAscentAndDescent(TInt aAscent,TInt aDescent)
       
   157 	{
       
   158 	iAscent = aAscent;
       
   159 	iDescent = aDescent;
       
   160 	Draw(EFTextCursor);
       
   161 	}
       
   162 
       
   163 /** Changes the cursor weight and redraws it.*/
       
   164 void TCursor::SetWeight(TInt aWeight)
       
   165 	{
       
   166 	if (aWeight > 0)
       
   167 		{
       
   168 		iWeight = aWeight;
       
   169 		Draw(EFTextCursor);
       
   170 		}
       
   171 	}
       
   172 
       
   173 /** Sets the flashing state of the cursor and redraws it. */
       
   174 void TCursor::SetFlash(TBool aEnabled)
       
   175 	{
       
   176 	iFlash = aEnabled;
       
   177 	Draw(EFTextCursor);
       
   178 	}
       
   179 
       
   180 /** Sets the XOR colour of the cursor and redraws it. */
       
   181 void TCursor::SetXorColor(TRgb aColor)
       
   182 	{
       
   183 	iXorColor = aColor;
       
   184 	Draw(EFTextCursor);
       
   185 	}
       
   186 
       
   187 /** Sets the cursor so that when it is next drawn its metrics will match those
       
   188 of adjacent text: cancels any overriding metrics. Does not redraw. */
       
   189 void TCursor::MatchCursorHeightToAdjacentChar()
       
   190 	{
       
   191 	iAscent = iDescent = -1;
       
   192 	}
       
   193 
       
   194 /** Draws the specified cursors. */
       
   195 void TCursor::Draw(TUint aCursors)
       
   196 	{
       
   197 	TPoint caret_origin;
       
   198 	TInt caret_width, caret_ascent, caret_descent;
       
   199 	TBool cursorsVisible = iCursorPos.GetCursor((TTmCursorPlacement)iPlacement,
       
   200 											    caret_origin,caret_width,caret_ascent,caret_descent);
       
   201 	caret_origin += iDisplay.TopLeftTextArea();
       
   202 
       
   203 	if (aCursors & EFTextCursor)
       
   204 		{
       
   205 		if (cursorsVisible && (iTextCursor != EFCursorInvisible) && !iCursorPos.IsNewPictureFrame())
       
   206 			{
       
   207 			if (iTextCursor == EFCursorVisible)
       
   208 				RemoveTextCursor();
       
   209 			else
       
   210 				{
       
   211 				int ascent = 0;
       
   212 				int descent = 0;
       
   213 				int width = 0;
       
   214 
       
   215 				if (iPlacement == ECursorVertical)
       
   216 					{
       
   217 					if (iAscent >= 0)
       
   218 						ascent = iAscent;
       
   219 					else
       
   220 						ascent = caret_ascent;
       
   221 					ascent += iFirstExtension;
       
   222 					if (iDescent >= 0)
       
   223 						descent = iDescent;
       
   224 					else
       
   225 						descent = caret_descent;
       
   226 					descent += iSecondExtension;
       
   227 					width = iWeight;
       
   228 					// Adjust which side the cursor hangs around the origin
       
   229 					// based on the sign of the 'width' from tagma.
       
   230 					if (caret_width<0)
       
   231 						caret_origin.iX -= iWeight;
       
   232 
       
   233 					}
       
   234 				else
       
   235 					{
       
   236 					ascent = 0;
       
   237 					descent = iWeight;
       
   238 					// Adjust which side the cursor hangs around the origin
       
   239 					// based on the sign of the 'width' from tagma and set the
       
   240 					// drawn width to the abs(width) value tagma has given us.
       
   241 					if (caret_width < 0)
       
   242 						{
       
   243 						width = -caret_width;
       
   244 						caret_origin.iX -= width; 
       
   245 						}
       
   246 					else
       
   247 						width = caret_width;
       
   248 					caret_origin.iX -= iFirstExtension;
       
   249 					width += (iFirstExtension + iSecondExtension);
       
   250 					}
       
   251 				DrawTextCursor(caret_origin,width,ascent,descent);
       
   252 				}
       
   253 			}
       
   254 		else
       
   255 			RemoveTextCursor();
       
   256 		}
       
   257 	if (iDisplay.IsLineCursor() && (aCursors&EFLineCursor))
       
   258 		{
       
   259 		if (cursorsVisible && (iLineCursor != EFCursorInvisible))
       
   260 			DrawLineCursor(caret_origin.iY);
       
   261 		else
       
   262 			RemoveLineCursor();
       
   263 		}
       
   264 	}
       
   265 
       
   266 void TCursor::DrawLineCursor(TInt aHeight)
       
   267 	{
       
   268 	__ASSERT_ALWAYS(iLineCursorBitmap,FormPanic(EFLineCursorBitmapNotSet));
       
   269 	TRect cursorMargin=iDisplay.LineCursorMargin();
       
   270 	TRect bitmapRect;
       
   271 	
       
   272 	bitmapRect.iTl.iX=cursorMargin.iTl.iX+ELineCursorToLabelGap;
       
   273 	bitmapRect.iBr.iX=bitmapRect.iTl.iX+iLineCursorBitmap->SizeInPixels().iWidth;
       
   274 	bitmapRect.iBr.iY=aHeight;
       
   275 	bitmapRect.iTl.iY=aHeight-iLineCursorBitmap->SizeInPixels().iHeight;
       
   276 
       
   277 	iDisplay.SetRects(RScreenDisplay::EFClipLineCursor);
       
   278 	iDisplay.ActivateContext();
       
   279 	iDisplay.ResetClippingRect();
       
   280 
       
   281 	if (iDisplay.UseWindowGc() && NULL != iDisplay.Layout())
       
   282 		{
       
   283 		iDisplay.Layout()->BeginRedraw(cursorMargin);
       
   284 		}
       
   285 
       
   286 	TRegionFix<4> clearRegion(cursorMargin);
       
   287 	clearRegion.SubRect(bitmapRect);
       
   288 
       
   289 	for (TUint ii=0; ii<(TUint)clearRegion.Count(); ii++)
       
   290 		{
       
   291 		iDisplay.ClearRect(clearRegion.RectangleList()[ii]);
       
   292 		}
       
   293 
       
   294 	iDisplay.BlastBitmap(bitmapRect.iTl,iLineCursorBitmap,TRect(TPoint(0,0),bitmapRect.Size()));
       
   295 	if (iDisplay.UseWindowGc() && NULL != iDisplay.Layout())
       
   296 		{
       
   297 		iDisplay.Layout()->EndRedraw();
       
   298 		}
       
   299 	
       
   300 	iDisplay.DeactivateContext();
       
   301 	}
       
   302 
       
   303 void TCursor::RemoveLineCursor()
       
   304 	{
       
   305 	TRect cursorMargin=iDisplay.LineCursorMargin();
       
   306 	iDisplay.SetRects(RScreenDisplay::EFClipLineCursor);
       
   307 	iDisplay.ActivateContext();
       
   308 	iDisplay.ResetClippingRect();
       
   309 
       
   310 	if (iDisplay.UseWindowGc() && NULL != iDisplay.Layout())
       
   311 		{
       
   312 		iDisplay.Layout()->BeginRedraw(cursorMargin);
       
   313 		}
       
   314 	iDisplay.ClearRect(cursorMargin);
       
   315 	if (iDisplay.UseWindowGc() && NULL != iDisplay.Layout())
       
   316 		{
       
   317 		iDisplay.Layout()->EndRedraw();
       
   318 		}
       
   319 
       
   320 	iDisplay.DeactivateContext();
       
   321 	}
       
   322 
       
   323 /** Draws the text cursor. */
       
   324 void TCursor::DrawTextCursor(TPoint aOrigin,TInt aWidth,TInt aAscent,TInt aDescent)
       
   325 	{
       
   326 	TTextCursor cursor;
       
   327  	cursor.iType = iType;
       
   328 	cursor.iHeight = aAscent + aDescent;
       
   329 	cursor.iAscent = aAscent;
       
   330 	cursor.iWidth = aWidth;
       
   331 	cursor.iFlags = iFlash ? 0 : TTextCursor::EFlagNoFlash;
       
   332 	if (iPlacement == ECursorVertical)
       
   333 		cursor.iFlags |= TTextCursor::EFlagClipVertical;
       
   334 	if (iPlacement == ECursorUnderlineNext || iPlacement == ECursorUnderlinePrev)
       
   335 		cursor.iFlags |= TTextCursor::EFlagClipHorizontal;
       
   336 	cursor.iColor = iXorColor;
       
   337 	iDisplay.SetTextCursor(aOrigin,cursor);
       
   338 	iVisible = TRUE;
       
   339 	}
       
   340 
       
   341 /** Removes the text cursor only if it is currently visible in this window. */
       
   342 void TCursor::RemoveTextCursor()
       
   343 	{
       
   344 	if (iVisible)
       
   345 		{
       
   346 		iDisplay.RemoveTextCursor();
       
   347 		iVisible = FALSE;
       
   348 		}
       
   349 	}
       
   350 
       
   351 void TCursor::SetExtensions(TInt aFirstExtension, TInt aSecondExtension)
       
   352 	{
       
   353 	TBool redraw=EFalse;
       
   354 	if (aFirstExtension!=iFirstExtension)
       
   355 		{
       
   356 		iFirstExtension=aFirstExtension;
       
   357 		redraw=ETrue;
       
   358 		}
       
   359 	if (aSecondExtension!=iSecondExtension)
       
   360 		{
       
   361 		iSecondExtension=aSecondExtension;
       
   362 		redraw=ETrue;
       
   363 		}
       
   364 	if( redraw)
       
   365 		Draw(EFTextCursor);
       
   366 	}
       
   367 
       
   368 /** Allocates and constructs a CTextView object.
       
   369 
       
   370 @param aLayout Pointer to the layout object referenced by the text view. Must 
       
   371 not be NULL or a panic occurs. 
       
   372 @param aDisplay The rectangle in which text is displayed (the "view rectangle"). 
       
   373 
       
   374 @param aGd Bitmapped graphics device to draw to, e.g. the screen. 
       
   375 @param aDeviceMap The device map used for drawing and formatting. 
       
   376 @param aWin The window to draw to. Should not be NULL. 
       
   377 @param aGroupWin Window group. Must be provided if a text cursor is to be displayed. 
       
   378 It can be NULL if you don't need a text cursor. 
       
   379 @param aSession Pointer to the window server session. 
       
   380 @return Pointer to the new CTextView object. */
       
   381 EXPORT_C CTextView *CTextView::NewL(CTextLayout *aLayout,const TRect &aDisplay,CBitmapDevice *aGd,
       
   382 									MGraphicsDeviceMap *aDeviceMap,RWindow *aWin,RWindowGroup *aGroupWin,
       
   383 									RWsSession *aSession)
       
   384 	{
       
   385 	CTextView* self = new(ELeave) CTextView();
       
   386   	CleanupStack::PushL(self);
       
   387 	self->ConstructL(aLayout,aDisplay,aGd,aDeviceMap,aWin,aGroupWin,aSession);
       
   388 	CleanupStack::Pop();
       
   389 	return self;
       
   390 	}
       
   391 
       
   392 /** Called when system is idle. Use to do background formatting. Enters OOM
       
   393 state before leaving */
       
   394 EXPORT_C TInt CTextView::IdleL(TAny *aSelf)
       
   395 	{
       
   396 
       
   397 	if (((CTextView *) aSelf)->NoMemoryCheckL())
       
   398 		return EFalse;
       
   399 	return ((CTextView *) aSelf)->NextLineL();
       
   400 	}
       
   401 
       
   402 EXPORT_C CTextView::CTextView():
       
   403 	iDisplay(&iDrawTextLayoutContext),
       
   404 	iCursor(iCursorPos,iDisplay),
       
   405 	iCursorPos(),
       
   406 	iFlags(EFEverythingVisible | EFFlickerFreeRedraw | EFTextVisible),
       
   407 	iHorizontalScroll(EFNoPreviousHorizontalScroll),
       
   408 	iContextIsNavigation(ETrue)
       
   409 	{
       
   410 	__ASSERT_DEBUG(EFMemoryOK != EFRecovering,FormPanic(EFSystemConstantsChanged));
       
   411 	}
       
   412 
       
   413 EXPORT_C void CTextView::ConstructL(CTextLayout *aLayout,const TRect &aDisplay,CBitmapDevice *aGd,
       
   414 									MGraphicsDeviceMap *aDeviceMap,RWindow *aWin,RWindowGroup *aGroupWin,
       
   415 									RWsSession *aSession)
       
   416 	{
       
   417 	__ASSERT_ALWAYS(aLayout,FormPanic(EFInvalidLayout));
       
   418 	iHorizontalScrollJump=EFDefaultHorizontalScrollJump;
       
   419 	iWrap = CIdle::NewL(EFBackgroundFormattingPriority);
       
   420 	SetLayout(aLayout);
       
   421 	SetViewRect(aDisplay);
       
   422 	SetDisplayContextL(aGd,aWin,aGroupWin,aSession);
       
   423 	// Tell the Layout classes about the Graphics Device
       
   424 	aLayout->SetImageDeviceMap(aDeviceMap);
       
   425 	iDrawTextLayoutContext.SetDrawToEveryPixel(ETrue);
       
   426 	}
       
   427 
       
   428 EXPORT_C CTextView::~CTextView()
       
   429 	{
       
   430 	delete iPictureFrame;
       
   431 	delete iWrap;
       
   432 	DestroyWindowServerObjects();
       
   433 	}
       
   434 
       
   435 /** Changes the text layout object used by the text view.
       
   436 
       
   437 @param aLayout Pointer to the text layout object used by the text view. Must 
       
   438 not be NULL or a panic occurs. */
       
   439 EXPORT_C void CTextView::SetLayout(CTextLayout *aLayout)
       
   440 	{
       
   441 	__ASSERT_ALWAYS(aLayout,FormPanic(EFInvalidLayout));
       
   442 	iLayout = aLayout;
       
   443 	iCursorPos.SetLayout(aLayout);
       
   444 	iDisplay.SetLayout(aLayout);
       
   445 	}
       
   446 
       
   447 /** Changes the window server handles which the display uses. Any of the parameters 
       
   448 can be NULL in which case they are not changed.
       
   449 
       
   450 @param aGd Pointer to the bitmapped graphics device to draw to. 
       
   451 @param aWin Pointer to the view window. 
       
   452 @param aGroupWin Pointer to the window group. 
       
   453 @param aSession Pointer to the window server session. */
       
   454 EXPORT_C void CTextView::SetDisplayContextL(CBitmapDevice * aGd,RWindow *aWin,RWindowGroup *aGroupWin,RWsSession *aSession)
       
   455 	{
       
   456 	if (aSession)
       
   457 		iDisplay.SetWindowsServer(aSession);
       
   458 	if (aGroupWin)
       
   459 		iDisplay.SetWindowGroup(aGroupWin);
       
   460 	if (aWin)
       
   461 		{
       
   462 		iDisplay.SetWindow(aWin);
       
   463 		iLayout->SetWindow(aWin);
       
   464 		}
       
   465 	if (aGd)
       
   466 		iDisplay.SetGraphicsDeviceL(aGd);
       
   467 	}
       
   468 
       
   469 /** Sets the rectangle in which the text is displayed.
       
   470 
       
   471 
       
   472 Note:
       
   473 
       
   474 A valid band height (>0) must be supplied(i.e. aViewRect.Tl.iY coordinate must be lower than the aViewRect.Br.iY coordinate) or the expected amount of formatting will not take place. This could lead to panics when trying to retrieve formatting information that does not exist.
       
   475 
       
   476 @param aDisplay The view rectangle. */
       
   477 EXPORT_C void CTextView::SetViewRect(const TRect &aViewRect)
       
   478 	{
       
   479 	iDrawTextLayoutContext.iViewRect = aViewRect;
       
   480 	iLayout->SetBandHeight(aViewRect.Height());
       
   481 
       
   482 	TRect oldViewRect = iDrawTextLayoutContext.iViewRect;
       
   483 
       
   484 	iDrawTextLayoutContext.iViewRect = aViewRect;
       
   485 	iLayout->SetBandHeight(aViewRect.Height());
       
   486 
       
   487 	if (NULL != iDisplay.Window() && ! oldViewRect.IsEmpty())
       
   488 		{
       
   489 		iDisplay.Window()->Invalidate(oldViewRect);
       
   490 		}
       
   491 	}
       
   492 
       
   493 
       
   494 // deprecated, planning to remove
       
   495 EXPORT_C void CTextView::AlterViewRect(const TRect &aViewRect)
       
   496 	{
       
   497 	iReducedDrawingAreaRect = aViewRect;
       
   498 	}
       
   499 
       
   500 /** Sets the label and line cursor margin widths. 
       
   501 
       
   502 Does not redraw.
       
   503 
       
   504 @param aLabels The width in pixels of the label margin. 
       
   505 @param aLineCursor The width in pixels of the line cursor margin. */
       
   506 EXPORT_C void CTextView::SetMarginWidths(TInt aLabels,TInt aLineCursor)
       
   507 	{
       
   508 	iDrawTextLayoutContext.iLabelMarginWidth = aLabels;
       
   509 	iDrawTextLayoutContext.iGutterMarginWidth = aLineCursor;
       
   510 	iLayout->SetLabelsMarginWidth(aLabels);
       
   511 	}
       
   512 
       
   513 /** Gets the label and line cursor margin widths in pixels.
       
   514 
       
   515 @param aLabels On return contains the width in pixels of the label margin. 
       
   516 @param aLineCursor On return contains the width in pixels of the line cursor 
       
   517 margin. */
       
   518 EXPORT_C void CTextView::MarginWidths(TInt& aLabels,TInt& aLineCursor) const
       
   519 	{
       
   520 	aLineCursor = iDrawTextLayoutContext.iGutterMarginWidth;
       
   521 	aLabels = iDrawTextLayoutContext.iLabelMarginWidth;
       
   522 	}
       
   523 
       
   524 /** Removes a selection, and redraws the affected part of the screen.
       
   525 
       
   526 Any background formatting is forced to complete first. */
       
   527 EXPORT_C void CTextView::CancelSelectionL()
       
   528 	{
       
   529 	TCursorSelection selection;
       
   530 
       
   531 	NoMemoryCheckL();
       
   532 	iCursorPos.GetSelection(selection);
       
   533 	TBool isPictureFrame=iCursorPos.IsPictureFrame();
       
   534 	if (selection.Length()>0)
       
   535 		{
       
   536 		iCursorPos.CancelHighlight();
       
   537 		if (!SelectionVisible())
       
   538 			return;
       
   539 		iDisplay.SetRects(RScreenDisplay::EFClipExtendedTextArea);		
       
   540 		iDisplay.ActivateContext();
       
   541 		iDisplay.ResetClippingRect();
       
   542 		if (isPictureFrame)
       
   543 			{
       
   544 			RedrawPictureFrameRectL(selection.LowerPos()); // iCursorPos.CancelHighlight() was called, so the picture will be redrawn without frame
       
   545 			DrawCursor(TCursor::EFTextCursor);
       
   546 			}
       
   547 		else
       
   548 			{
       
   549 			CTextLayout::TRangeChange clear_range(selection.iAnchorPos, selection.iCursorPos,CTextLayout::TRangeChange::EClear);
       
   550 	       	CTextLayout::TRangeChange original(selection.iCursorPos,selection.iCursorPos,CTextLayout::TRangeChange::ESet);
       
   551 		   	HighlightUsingExtensions(clear_range, original);
       
   552 			}
       
   553 		}
       
   554 		iDisplay.DeactivateContext();
       
   555 	}
       
   556 
       
   557 /** This function should not be used. This function is used in TTextView to
       
   558 test a fix for a defect.
       
   559 @internalTechnology */
       
   560 EXPORT_C CBitmapContext* CTextView::BitmapContext()
       
   561 	{
       
   562 	return iDisplay.BitmapContext();
       
   563 	}
       
   564 
       
   565 /** Calculates which of two document positions would be considered more left or
       
   566 more right, depending on the value of aDirection.
       
   567 
       
   568 @param aStart First document position to compare.
       
   569 @param aEnd Second document position to compare.
       
   570 @param aDirection If EVisualLeft, the function returns the left-most of aStart
       
   571 and aEnd. If EVisualRight, the function returns the right-most.
       
   572 @return The left-most of aStart and aEnd if aDirection was EVisualLeft;
       
   573 otherwise, the right-most. */
       
   574 EXPORT_C const TTmDocPos& CTextView::VisualEndOfRunL(
       
   575 	const TTmDocPos& aStart, const TTmDocPos& aEnd,
       
   576 	TCursorPosition::TVisualEnd aDirection)
       
   577 	{
       
   578 	return iCursorPos.VisualEndOfRunL(aStart, aEnd, aDirection);
       
   579 	}
       
   580 
       
   581 /** Gets the cursor position as a TTmDocPos.
       
   582 
       
   583 @param aPos On return, the cursor position. */
       
   584 EXPORT_C void CTextView::GetCursorPos(TTmDocPos& aPos) const
       
   585 	{
       
   586 	aPos = iCursorPos.TmDocPos();
       
   587 	}
       
   588 
       
   589 /** Un-draws a selection, redraws the affected part of the screen. The cursor
       
   590 selection remains as before. Analogous to CancelSelectionL(), but leaves the
       
   591 cursor selection untouched. This function should be called before calling
       
   592 CTextView::SetPendingSelection() _and_ SetHighlightExtensions has been used to
       
   593 extend the size of the highlight. Any background formatting is forced to
       
   594 complete first. */
       
   595 EXPORT_C void CTextView::ClearSelectionL()
       
   596 	{
       
   597 	TCursorSelection selection;
       
   598 
       
   599 	NoMemoryCheckL();
       
   600 	iCursorPos.GetSelection(selection);
       
   601 	TBool isPictureFrame=iCursorPos.IsPictureFrame();
       
   602 	if (selection.Length()>0)
       
   603 		{
       
   604 		iCursorPos.CancelHighlight();
       
   605 		DoClearSelectionL(selection,isPictureFrame);
       
   606 		iDisplay.DeactivateContext();
       
   607 		}
       
   608 	}
       
   609 
       
   610 void CTextView::DoClearSelectionL(const TCursorSelection& aSelection, TBool aIsPictureFrame)
       
   611 	{
       
   612 	if (!SelectionVisible())
       
   613 		return;
       
   614 	iDisplay.SetRects(RScreenDisplay::EFClipExtendedTextArea);
       
   615 	iDisplay.ActivateContext();
       
   616 	iDisplay.ResetClippingRect();
       
   617 	if (aIsPictureFrame)
       
   618 		{
       
   619 		RedrawPictureFrameRectL(aSelection.LowerPos()); // iCursorPos.CancelHighlight() was called, so the picture will be redrawn without frame
       
   620 		DrawCursor(TCursor::EFTextCursor);
       
   621 		}
       
   622 	else
       
   623 		{
       
   624 		iDisplay.SetRects(RScreenDisplay::EFClipExtendedTextArea);
       
   625 		iDisplay.ResetClippingRect();
       
   626 		CTextLayout::TRangeChange clear_range(aSelection.iAnchorPos, aSelection.iCursorPos,CTextLayout::TRangeChange::EClear);
       
   627 		CTextLayout::TRangeChange new_range(aSelection.iCursorPos,aSelection.iCursorPos,CTextLayout::TRangeChange::ESet);
       
   628 		HighlightUsingExtensions(clear_range,new_range);
       
   629 		}
       
   630 	}
       
   631 
       
   632 /** Used to correct the display after a cursor move type call Enters OOM before
       
   633 leaving */
       
   634 TInt CTextView::DrawAfterCursorMoveL(TInt aVerticalScrollBy)
       
   635 	{
       
   636 	TInt horizontalScrollBy = CheckHorizontalScroll(iCursorPos.TmDocPos());
       
   637 	
       
   638 	DrawWithPreviousHighlight();
       
   639 
       
   640 	if (0 != aVerticalScrollBy || 0 != horizontalScrollBy)
       
   641 		{
       
   642 		ScrollDisplayL();
       
   643 		}
       
   644 	else
       
   645 		{
       
   646 		DrawCursor();
       
   647 		}
       
   648 
       
   649 	DrawWithCurrentHighlight();
       
   650 
       
   651 	return horizontalScrollBy;
       
   652 	}
       
   653 
       
   654 /** Sets a selection. The selection is highlighted unless selection visibility
       
   655 has been unset. Any existing selection is cancelled. If necessary, the view is
       
   656 scrolled and redrawn.
       
   657 
       
   658 Any background formatting is forced to complete first.
       
   659 
       
   660 @param aSelection Specifies the start and end positions of the selection.
       
   661 @return The number of pixels scrolled in the x (horizontal) and y (vertical)
       
   662 directions. */
       
   663 EXPORT_C TPoint CTextView::SetSelectionL(const TCursorSelection& aSelection)
       
   664 	{
       
   665 	iContextIsNavigation = ETrue;
       
   666 	TCursorSelection oldSelection;
       
   667 	TBool isPictureFrame=iCursorPos.IsPictureFrame();
       
   668 	TInt scrollBy=0;		//To avoid warning
       
   669 
       
   670 	NoMemoryCheckL();
       
   671 	FinishBackgroundFormattingL();
       
   672 	iCursorPos.GetSelection(oldSelection);
       
   673 	iCursor.MatchCursorHeightToAdjacentChar();
       
   674 	__ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate(),FormPanic(EFFormatOutOfDate));
       
   675 	TRAPD(err,scrollBy=iCursorPos.SetSelectionL(aSelection));
       
   676 	if (err)
       
   677 		NoMemoryL(err);
       
   678 	TInt horizScrollBy=DrawAfterCursorMoveL(scrollBy);
       
   679 	iDisplay.SetRects(RScreenDisplay::EFClipTextArea);
       
   680 	iDisplay.ActivateContext();
       
   681 	iDisplay.ResetClippingRect();
       
   682 	if (SelectionVisible())
       
   683 		{
       
   684 		CTextLayout::TRangeChange old;
       
   685 		CTextLayout::TRangeChange select;
       
   686 		if (isPictureFrame)
       
   687 			{
       
   688 			iCursorPos.DontDrawOldPictureFrame();
       
   689 			RedrawPictureFrameRectL(oldSelection.LowerPos()); // this will erase the old picture frame
       
   690 			DrawCursor(TCursor::EFTextCursor);
       
   691 			}
       
   692 		else
       
   693 			{
       
   694 			old.Set(oldSelection.iAnchorPos, oldSelection.iCursorPos,
       
   695 				CTextLayout::TRangeChange::EClear);
       
   696 			}
       
   697 
       
   698 		if (iCursorPos.IsNewPictureFrame())
       
   699 			{
       
   700 			RedrawPictureFrameRectL(aSelection.LowerPos());	// this will draw the new picture frame
       
   701 			}
       
   702 		else
       
   703 			{
       
   704 			select.Set(aSelection.iAnchorPos, aSelection.iCursorPos,
       
   705 				CTextLayout::TRangeChange::ESet);
       
   706 			}
       
   707 
       
   708 		CTextLayout::TRangeChange original;
       
   709 		original = select;
       
   710 		select.OptimizeWith(old);
       
   711 		iDisplay.SetRects(RScreenDisplay::EFClipExtendedTextArea);
       
   712 		iDisplay.ResetClippingRect();
       
   713 
       
   714 		if (select.IsJoinedTo(old))
       
   715 			{
       
   716 			select.Join(old);
       
   717 			HighlightUsingExtensions(select,original);
       
   718 			}
       
   719 		else
       
   720 			{
       
   721 			HighlightUsingExtensions(old,original);
       
   722 			HighlightUsingExtensions(select, original);
       
   723 			}
       
   724 		}
       
   725 	iDisplay.DeactivateContext();
       
   726 	return TPoint(horizScrollBy,scrollBy);
       
   727 	}
       
   728 
       
   729 /** Sets the bitmap to be used as a line cursor. This function must be called
       
   730 before attempting to draw the line cursor. Use SetCursorVisibilityL() to make
       
   731 the line cursor visible.
       
   732 @param aLineCursorBitmap The bitmap which represents the line cursor. */
       
   733 EXPORT_C void CTextView::SetLineCursorBitmap(const CFbsBitmap* aLineCursorBitmap)
       
   734 	{
       
   735 	iCursor.SetLineCursorBitmap(aLineCursorBitmap);
       
   736 	}
       
   737 
       
   738 /** Sets the height and ascent of the text cursor to the values contained in
       
   739 aFontSpec and redraws it.
       
   740 
       
   741 Note:
       
   742 
       
   743 The values set by this function are temporary. If the cursor is subsequently
       
   744 moved, it reverts to being based on the preceding character (unless at the
       
   745 start of a paragraph, in which case, it is based on the following character).
       
   746 
       
   747 @param aFontSpec Specifies a height and ascent to which to set the text cursor.
       
   748 */
       
   749 EXPORT_C void CTextView::MatchCursorHeightL(const TFontSpec& aFontSpec)
       
   750 	{
       
   751 	
       
   752 	TInt fontHeight = 0;
       
   753 	TInt fontAscent = 0;
       
   754 	TRAPD(err,iLayout->GetFontHeightAndAscentL(aFontSpec,fontHeight,fontAscent));
       
   755 	if (!err)
       
   756 		iCursor.SetAscentAndDescent(fontAscent,fontHeight - fontAscent);
       
   757 	User::LeaveIfError(err);
       
   758 	}
       
   759 
       
   760 /** Gets the current selection.
       
   761 @return The current selection. */
       
   762 EXPORT_C TCursorSelection CTextView::Selection() const
       
   763 	{
       
   764 	TCursorSelection selection;
       
   765 	
       
   766 	iCursorPos.GetSelection(selection);
       
   767 	return selection;
       
   768 	}
       
   769 
       
   770 /** Tests whether there is a picture with a picture frame at the current cursor
       
   771 position. If there is, the aPictureFrameRect and aDocPos arguments are set to
       
   772 contain the picture frame rectangle and the document position of the picture,
       
   773 respectively.
       
   774 
       
   775 @param aPictureFrameRect If the function returns true, on return contains the
       
   776 picture frame rectangle.
       
   777 @param aDocPos If the function returns true, on return contains the document
       
   778 position of the picture.
       
   779 @return ETrue if there is a picture with a picture frame at the current cursor
       
   780 position. EFalse if not. */
       
   781 EXPORT_C TBool CTextView::IsPictureFrameSelected(TRect& aPictureFrameRect,TInt& aDocPos) const
       
   782 	{
       
   783 	if (iCursorPos.IsPictureFrame())
       
   784 		{
       
   785 		__ASSERT_DEBUG(iPictureFrame,FormPanic(EFNoPictureFrame));
       
   786 		aPictureFrameRect=iPictureFrame->Rect();
       
   787 		aDocPos=Selection().LowerPos();
       
   788 		return ETrue;
       
   789 		}
       
   790 	return EFalse;
       
   791 	}
       
   792 
       
   793 /** Gets the bounding rectangle of the picture, if any, located at the document
       
   794 position or x,y coordinates specified, and returns it in aPictureRect.
       
   795 
       
   796 If aCanScaleOrCrop is non-null, sets aCanScaleOrCrop to indicate 
       
   797 whether the picture can be scaled or cropped. Returns true if the
       
   798 operation was successful. Returns false otherwise; that is, if there is no
       
   799 picture at the position, or if the position is unformatted.
       
   800 
       
   801 @param aDocPos The document position of interest.
       
   802 @param aXyPos The window coordinates of interest.
       
   803 @param aPictureRect	On return, contains the rectangle which encloses the picture 
       
   804 located at the position specified.
       
   805 @param aCanScaleOrCrop If non null and the function returns true, indicates 
       
   806 whether the picture can be scaled or cropped. By default, null.
       
   807 @return ETrue if the operation was successful, (i.e. there is a picture 
       
   808 character at the position, it has been loaded into memory, and the position is
       
   809 formatted). EFalse if any of these conditions are not met. */
       
   810 EXPORT_C TBool CTextView::GetPictureRectangleL(TInt aDocPos,TRect& aPictureRect,TBool* aCanScaleOrCrop/*=NULL*/) const
       
   811 	{
       
   812 	TBool isPicture=iLayout->PictureRectangleL(aDocPos,aPictureRect,aCanScaleOrCrop);
       
   813 	
       
   814 	iDrawTextLayoutContext.TextToWindow(aPictureRect);
       
   815 	return isPicture;
       
   816 	}
       
   817 
       
   818 /** Returns EFalse if the specified position is not contained within a
       
   819 formatted picture.
       
   820 */
       
   821 EXPORT_C TBool CTextView::GetPictureRectangleL(TPoint aXyPos,TRect& aPictureRect,TBool* aCanScaleOrCrop/*=NULL*/)
       
   822 	{
       
   823 	iDrawTextLayoutContext.WindowToText(aXyPos);
       
   824 	TBool isPicture=EFalse;
       
   825 	TRAPD(err,
       
   826 		isPicture = iLayout->PictureRectangleL(aXyPos, aPictureRect, aCanScaleOrCrop));
       
   827 	if (err)
       
   828 		NoMemoryL(err);
       
   829 	iDrawTextLayoutContext.TextToWindow(aPictureRect);
       
   830 	return isPicture;
       
   831 	}
       
   832 
       
   833 /** Gets the index of the nearest character in the document to the window coordinates
       
   834 specified. The function first identifies the line which contains, or is nearest 
       
   835 to, the vertical coordinate. Then it identifies the character in that line 
       
   836 closest to the horizontal coordinate.
       
   837 
       
   838 @param aPoint Window coordinates. On return, contains the window coordinates 
       
   839 of the nearest character to the point. 
       
   840 @return Index of the nearest character in the document to specified window coordinates. */
       
   841 EXPORT_C TInt CTextView::XyPosToDocPosL(TPoint& aPoint)
       
   842 	{
       
   843 	NoMemoryCheckL();
       
   844 	FinishBackgroundFormattingL();
       
   845 	__ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate(),FormPanic(EFFormatOutOfDate));
       
   846 
       
   847 	iDrawTextLayoutContext.WindowToText(aPoint);
       
   848 	TInt pos = iLayout->XyPosToDocPosL(aPoint);
       
   849 	iDrawTextLayoutContext.TextToWindow(aPoint);
       
   850 	return pos;
       
   851 	}
       
   852 
       
   853 /** Gets the window coordinates of the character located at the specified document 
       
   854 position. If the document position specified has not been formatted, the function 
       
   855 returns a value of false.
       
   856 
       
   857 @param aDocPos The document position. 
       
   858 @param aPoint On return, contains the window coordinates of aDocPos. This value 
       
   859 is undefined if the position has not been formatted. 
       
   860 @return True if the document position is formatted, false if not. */
       
   861 EXPORT_C TBool CTextView::DocPosToXyPosL(TInt aDocPos,TPoint& aPoint)
       
   862 	{
       
   863 	NoMemoryCheckL();
       
   864 	FinishBackgroundFormattingL();
       
   865 	__ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate(),FormPanic(EFFormatOutOfDate));
       
   866 	iLayout->ExtendFormattingToCoverPosL(aDocPos);
       
   867 	TTmPosInfo2 pos_info;
       
   868 	TTmDocPosSpec pos(aDocPos,
       
   869 		aDocPos == iLayout->DocumentLength()?
       
   870 		TTmDocPosSpec::ETrailing : TTmDocPosSpec::ELeading);
       
   871 	TBool in_format = iLayout->FindDocPos(pos, pos_info);
       
   872 	aPoint = pos_info.iEdge;
       
   873 	iDrawTextLayoutContext.TextToWindow(aPoint);
       
   874 	return in_format;
       
   875 	}
       
   876 
       
   877 /** Gets the document position of of the nearest character edge to the window coordinates 
       
   878 specified.
       
   879 
       
   880 @param aXyPos The window coordinates to investigate. 
       
   881 @param aPosInfo If non-null, on return contains information about the position 
       
   882 located in the text. 
       
   883 @param aLineInfo If non-null, on return contains information on the line that 
       
   884 the position is in. 
       
   885 @return ETrue if the position was in the text and aPosInfo and aLineInfo have 
       
   886 been set. */
       
   887 EXPORT_C TBool CTextView::FindXyPosL(const TPoint& aXyPos, TTmPosInfo2& aPosInfo, TTmLineInfo* aLineInfo)
       
   888 	{
       
   889 	TPoint pos = aXyPos;
       
   890 	iDrawTextLayoutContext.WindowToText(pos);
       
   891 	iLayout->ExtendFormattingToCoverYL(pos.iY);
       
   892 	return iLayout->FindXyPos(pos, aPosInfo, aLineInfo);
       
   893 	}
       
   894 
       
   895 /** Finds the x-y position of the document position aDocPos. 
       
   896 
       
   897 If aDocPos is formatted, TRUE is returned and aPosInfo returns information 
       
   898 about the document position and aLineInfo returns information about the line 
       
   899 containing the document position, if it is non-null. 
       
   900 
       
   901 @param aDocPos The document position to investigate. 
       
   902 @param aPosInfo If non-null, on return, contains information about the document 
       
   903 position.
       
   904 @param aLineInfo If non-null, on return, contains information on the line that 
       
   905 the position is in.
       
   906 @return ETrue if the position was in the text and aPosInfo and aLineInfo have 
       
   907 been set; EFalse otherwise. */
       
   908 EXPORT_C TBool CTextView::FindDocPosL(const TTmDocPosSpec& aDocPos,TTmPosInfo2& aPosInfo,TTmLineInfo* aLineInfo)
       
   909 	{
       
   910 	TTagmaForwarder forwarder;
       
   911 	forwarder.InitL(this);
       
   912 	iLayout->ExtendFormattingToCoverPosL(aDocPos.iPos);
       
   913 	TTmLineInfo line_info;
       
   914 	TBool result = forwarder.FindDocPos(aDocPos,aPosInfo,line_info);
       
   915 	if (aLineInfo)
       
   916 		*aLineInfo = line_info;
       
   917 	return result;
       
   918 	}
       
   919 
       
   920 /**
       
   921 Returns a selection for which characters should be deleted in a forwards delete.
       
   922 @return
       
   923 	A selection for which characters should be deleted in a forwards delete.
       
   924 */	
       
   925 EXPORT_C TCursorSelection CTextView::GetForwardDeletePositionL()
       
   926 	{
       
   927 	TCursorSelection selection = Selection();
       
   928 	if (selection.Length() != 0)
       
   929 		return selection;
       
   930 	iLayout->ExtendFormattingToCoverPosL(Min(selection.iCursorPos + 1, iLayout->DocumentLength()));
       
   931 	TInt anchor = iLayout->TagmaTextLayout().FindNextPos(selection.iCursorPos);
       
   932 	if (anchor < 0)
       
   933 		{
       
   934 		selection.iAnchorPos = iLayout->DocumentLength();
       
   935 		return selection;
       
   936 		}
       
   937 
       
   938 	__ASSERT_DEBUG(selection.iCursorPos < anchor, User::Invariant());
       
   939 	__ASSERT_DEBUG(selection.Length() == 0, User::Invariant());
       
   940 
       
   941 	// Now we have found the next formatted position. However, this
       
   942 	// may have skipped a ligature. We should only delete the first character
       
   943 	// in any ligature.
       
   944 	// However, an indic syllable (glued together with viramas) should be
       
   945 	// deleted all in one go.
       
   946 	CTextLayout::TUtf32SourceCache sourceCache(*iLayout);
       
   947 	TInt graphicalSpacingCharactersFound = 0;
       
   948 	TBool ignoreNextSpacingCharacter = EFalse;
       
   949 	for (TInt i = selection.iCursorPos; i != anchor; ++i)
       
   950 		{
       
   951 		__ASSERT_DEBUG(i < anchor, User::Invariant());
       
   952 		TChar c = sourceCache.GetUtf32(i);
       
   953 		if ( IsGraphicalSpacing(c) )
       
   954 			{
       
   955 			if (!ignoreNextSpacingCharacter)
       
   956 				{
       
   957 				if (graphicalSpacingCharactersFound != 0)
       
   958 					{
       
   959 					// Found two graphical spacing characters: don't
       
   960 					// include the second
       
   961 					selection.iAnchorPos = i;
       
   962 					return selection;
       
   963 					}
       
   964 				++graphicalSpacingCharactersFound;
       
   965 				}
       
   966 			else
       
   967 				ignoreNextSpacingCharacter = EFalse;
       
   968 			}
       
   969 		else if (IsVirama(c))
       
   970 			{
       
   971 			// virama joins a graphical spacing character to the
       
   972 			// previous character, so the second one doesn't count.
       
   973 			ignoreNextSpacingCharacter = ETrue;
       
   974 			}
       
   975 		}
       
   976 	selection.iAnchorPos = anchor;
       
   977 	return selection;
       
   978 	}
       
   979 
       
   980 /** Returns a selection for which characters should be deleted in a backwards
       
   981 delete.
       
   982 @return
       
   983 	A selection for which characters should be deleted in a backwards delete.
       
   984 */
       
   985 
       
   986 EXPORT_C TCursorSelection CTextView::GetBackwardDeletePositionL()
       
   987 	{
       
   988 	TCursorSelection selection = Selection();
       
   989 	if (selection.Length() != 0)
       
   990 		return selection;
       
   991 
       
   992 	TInt anchor = KErrNotFound;
       
   993 	TTmDocPos docPos;
       
   994 	GetCursorPos(docPos);
       
   995 	// loop through each previous line in case there are only zero width
       
   996 	// chars before the cursor on this line. In practice, the following loop
       
   997 	// should only ever iterate twice at most, because you can never have
       
   998 	// more than one continuous line of zero-width characters (think about it)
       
   999 	while (anchor==KErrNotFound && docPos.iPos > 0)
       
  1000 		{ 
       
  1001 		anchor = iLayout->TagmaTextLayout().FindPreviousPos(docPos.iPos);
       
  1002 		if (anchor==KErrNotFound) // no non-zero-width character before
       
  1003 			{                     // this position on this line
       
  1004 			// get first doc position on line then extend formatting to the one before
       
  1005 			TTmPosInfo2 dummy;
       
  1006 		   	TTmLineInfo currentLineInfo;
       
  1007 		   	iLayout->FindDocPos(docPos, dummy, &currentLineInfo);
       
  1008 		   	docPos.iPos = currentLineInfo.iStart;
       
  1009 			iLayout->ExtendFormattingToCoverPosL(Max(docPos.iPos - 1, 0));
       
  1010 			}
       
  1011 		}
       
  1012 	if (anchor==KErrNotFound)
       
  1013 		{
       
  1014 		selection.iAnchorPos = 0;
       
  1015 		return selection;
       
  1016 		}
       
  1017 
       
  1018 	__ASSERT_DEBUG(anchor < selection.iCursorPos, User::Invariant());
       
  1019 	__ASSERT_DEBUG(selection.Length() == 0, User::Invariant());
       
  1020 
       
  1021 	// If this cluster is a ligature, it needs to be split.
       
  1022 	// Note that an indic syllable (where consonants are glued
       
  1023 	// together with viramas) does not count as a ligature.
       
  1024 	CTextLayout::TUtf32SourceCache sourceCache(*iLayout);
       
  1025 	for (TInt i = selection.iCursorPos - 1; anchor < i; --i)
       
  1026 		{
       
  1027 		if ( IsGraphicalSpacing(sourceCache.GetUtf32(i)) )
       
  1028 			{
       
  1029 			if ( !IsVirama(sourceCache.GetUtf32(i-1)) )
       
  1030 				{
       
  1031 				// Found two possible start points: cut to the last.
       
  1032 				selection.iAnchorPos = i;
       
  1033 				return selection;
       
  1034 				}
       
  1035 			}
       
  1036 		}
       
  1037 	// Not a ligature
       
  1038 	selection.iAnchorPos = anchor;
       
  1039 	return selection;
       
  1040 	}
       
  1041 
       
  1042 /** Returns the rectangle enclosing the paragraph containing aDocPos. If the
       
  1043 paragraph is not formatted, returns an empty rectangle. If the paragraph is
       
  1044 partially formatted, returns the rectangle enclosing the formatted part.
       
  1045 
       
  1046 @param aDocPos A document position within the paragraph.
       
  1047 @return The rectangle which encloses the paragraph containing aDocPos. */
       
  1048 EXPORT_C TRect CTextView::ParagraphRectL(TInt aDocPos) const
       
  1049 	{
       
  1050 	TRect r;
       
  1051 	TTmDocPos pos(aDocPos,
       
  1052 		aDocPos == iLayout->DocumentLength()? EFalse : ETrue);
       
  1053 	iLayout->GetParagraphRect(pos,r);
       
  1054 	iDrawTextLayoutContext.TextToWindow(r);
       
  1055 	return r;
       
  1056 	}
       
  1057 
       
  1058 /** Formats the next line for background formatting, returns True if more to do
       
  1059 Enters OOM state before leaving */
       
  1060 TBool CTextView::NextLineL()
       
  1061 	{
       
  1062 	TBool moreToDo=EFalse;
       
  1063 
       
  1064 	if (IsFormatting())
       
  1065 		{
       
  1066 		TInt formattedFrom=iFormattedUpTo;
       
  1067 
       
  1068 		TRAPD(err,moreToDo=iLayout->FormatNextLineL(iFormattedUpTo));
       
  1069 		if (err)
       
  1070 			NoMemoryL(err);
       
  1071 		NotifyReformatL();
       
  1072 		TInt displayTo=iDrawTextLayoutContext.DisplayHeight();
       
  1073 		TBool drawAllLines=(iHorizontalScroll==EFPreviousHorizontalScroll && !moreToDo);
       
  1074 		if (iFormattedUpTo<displayTo && !drawAllLines)
       
  1075 			displayTo=iFormattedUpTo;
       
  1076 		DisplayNewLinesL(formattedFrom,displayTo);
       
  1077 		if (!moreToDo)
       
  1078 			{
       
  1079 			if (!drawAllLines)
       
  1080 				CheckScrollUpL();
       
  1081 			iHorizontalScroll=EFNoPreviousHorizontalScroll;
       
  1082 			}
       
  1083 		}
       
  1084 	return moreToDo;
       
  1085  	}
       
  1086 
       
  1087 /** Draws good parts of the screen that have recently been formatted by
       
  1088 background formatting. Enters OOM before leaving. */
       
  1089 void CTextView::DisplayNewLinesL(TInt aFrom,TInt aTo)
       
  1090 	{
       
  1091 	__ASSERT_DEBUG(!iNoMemory,FormPanic(EFNoMemory));
       
  1092 	if (aTo>iGood)
       
  1093 		{
       
  1094 		ScrollTextL(aTo - iGood,iGood,0,FALSE);
       
  1095 		iGood=aTo;
       
  1096 		}
       
  1097 	iDisplay.SetRects(RScreenDisplay::EFClipViewRect);
       
  1098 	DisplayLineRangeL(aFrom,aTo);
       
  1099 	DrawCursor();
       
  1100 	}
       
  1101 
       
  1102 void CTextView::DrawCursor(TUint aCursors)
       
  1103 	{
       
  1104 	iCursor.Draw(aCursors);
       
  1105 	}
       
  1106 
       
  1107 /** Scrolls the screen up if necessary following background formatting. Enters
       
  1108 OOM state before leaving */
       
  1109 void CTextView::CheckScrollUpL()
       
  1110 	{
       
  1111 	if (iFormattedUpTo<iGood)
       
  1112 		{
       
  1113 		TInt height=iDrawTextLayoutContext.DisplayHeight();
       
  1114 		
       
  1115 		if (height>iGood)
       
  1116 			{
       
  1117 			TInt scroll=iFormattedUpTo-iGood;
       
  1118 			ScrollTextL(scroll,iGood,0,FALSE);
       
  1119 			//invalidate the area from the bottom of the last formatted line 
       
  1120 			//to the bottom of view rect
       
  1121   			iDisplay.SetInvalidRect(iFormattedUpTo-height);						
       
  1122 			iFormattedUpTo+=height-iGood;
       
  1123 			iDisplay.SetRects(RScreenDisplay::EFClipViewRect|RScreenDisplay::EFClipInvalid);
       
  1124 			DrawTextL(iFormattedUpTo);
       
  1125 			}
       
  1126 		else if (height>iFormattedUpTo)
       
  1127 			{
       
  1128 			iDisplay.SetRects(RScreenDisplay::EFClipViewRect);
       
  1129 			DrawTextL(iFormattedUpTo);
       
  1130 			}
       
  1131 		}
       
  1132 	}
       
  1133 
       
  1134 /**
       
  1135 CheckHorizontalScroll's job is to take the cursor position in aDocPos and
       
  1136 ensure it is visible in the view. It does this by calculating the horizontal
       
  1137 scroll neccessary and adjusts the iTextStartX (left text margin) attribute of
       
  1138 the view member iDrawTextLayoutContext. This change (if any) would be reflected
       
  1139 in the next re-draw.
       
  1140 
       
  1141 This functionality is required when the layout is in non-screen/window wrapped
       
  1142 mode (ie. wysiwyg mode) and the cursor is out of view to the left or the right
       
  1143 (say if the user has horizontally scrolled) and either a cursor movement
       
  1144 happens or a char is inserted or deleted by the user. The end result is the
       
  1145 view jumps back to the cursor so the user can see when change/movement was
       
  1146 made.
       
  1147 
       
  1148 When the layout format is set to screen mode this functionality may still be
       
  1149 required as paragraphs with wrapping turned off can break the margins. Even
       
  1150 with wrapping turned on, spaces and hanging characters can break margins;
       
  1151 however it is usually considered ugly to allow the screen to scroll to follow
       
  1152 the cursor in these situations.
       
  1153 
       
  1154 @param aDocPos Cusror position to base calculations on
       
  1155 @post Drawing layout context updated with new horizontal scroll position
       
  1156 @return Amount left margin (horizontal scroll) adjusted by or 0 if none
       
  1157 */
       
  1158 TInt CTextView::CheckHorizontalScroll (const TTmDocPos& aDocPos)
       
  1159 	{
       
  1160 	/* Here are the requirements for this function:
       
  1161 
       
  1162 	(1) Areas beyond the text +10% of the window width +iHorizontalScrollJump
       
  1163 	must not be shown if the text edge is beyond its normal bounds, 
       
  1164 	except that 
       
  1165 		a distance of (window width - text width) beyond the texts
       
  1166 		bounds may be shown if this is positive.  
       
  1167 	or
       
  1168 		If this is not positive then a small amount of padding 
       
  1169 		(windowWidth - iLayout->WrapWidth) is allowed.
       
  1170 
       
  1171 	(2) The cursor must be 10% of the window's width away from the window's
       
  1172 	edge if the text is wider than the window.
       
  1173 
       
  1174 	(3) In all cases where (1) and (2) do not force otherwise, the scroll
       
  1175 	amount must be a multiple of iHorizontalScrollJump.
       
  1176 
       
  1177 	(4) The screen must scroll the minimum amount allowed by requirements (1),
       
  1178 	(2) and (3).
       
  1179 	*/
       
  1180 	TInt windowWidth = iDrawTextLayoutContext.TextArea().Width();
       
  1181 	// Scroll position is the position on the screen at which the text
       
  1182 	// has its X coordinate
       
  1183 	TInt currentScrollPosition = iDrawTextLayoutContext.iTextStartX;
       
  1184 	TInt rightTextEdge;
       
  1185 	TInt leftTextEdge;
       
  1186 	iLayout->CalculateHorizontalExtremes(leftTextEdge, rightTextEdge, ETrue);
       
  1187 
       
  1188 	TInt maximumScrollPosition = -leftTextEdge;
       
  1189 	TInt minimumScrollPosition = windowWidth - rightTextEdge;
       
  1190 	TInt padding = maximumScrollPosition < minimumScrollPosition?
       
  1191 		minimumScrollPosition - maximumScrollPosition : 
       
  1192 			((windowWidth - iLayout->WrapWidth() > 0) ? windowWidth - iLayout->WrapWidth() : 0);
       
  1193 
       
  1194 	TInt buffer = windowWidth / 10;
       
  1195 	TInt textWrapWidth = iLayout->WrapWidth();
       
  1196 	// loosen the bounds by 10% of the window width + iHorizontalScrollJump
       
  1197 	// if the text is beyond them
       
  1198 	TInt leftAllowance = leftTextEdge < 0?
       
  1199 		buffer + iHorizontalScrollJump : 0;
       
  1200 	TInt rightAllowance = textWrapWidth < rightTextEdge?
       
  1201 		buffer + iHorizontalScrollJump : 0;
       
  1202 	maximumScrollPosition += Max(leftAllowance, padding);
       
  1203 	minimumScrollPosition -= Max(rightAllowance, padding);
       
  1204 
       
  1205 	// requirement (2) sets the preferred min and max
       
  1206 	TInt preferredMinimumScrollPosition = minimumScrollPosition;
       
  1207 	TInt preferredMaximumScrollPosition = maximumScrollPosition;
       
  1208 	if (windowWidth < rightTextEdge - leftTextEdge)
       
  1209 		{
       
  1210 		TTmPosInfo2 posInfo;
       
  1211 		iLayout->FindDocPos(aDocPos, posInfo);
       
  1212 		TInt cursorWithinTextX = posInfo.iEdge.iX;
       
  1213 		
       
  1214 		preferredMinimumScrollPosition = buffer - cursorWithinTextX;
       
  1215 		preferredMaximumScrollPosition = windowWidth - buffer - cursorWithinTextX;
       
  1216 
       
  1217 		// keep the preferred max and min within range
       
  1218 		preferredMinimumScrollPosition = Max(preferredMinimumScrollPosition, minimumScrollPosition);
       
  1219 		preferredMinimumScrollPosition = Min(preferredMinimumScrollPosition, maximumScrollPosition);
       
  1220 		
       
  1221 		preferredMaximumScrollPosition = Max(preferredMaximumScrollPosition, minimumScrollPosition);
       
  1222 		preferredMaximumScrollPosition = Min(preferredMaximumScrollPosition, maximumScrollPosition);
       
  1223 		}
       
  1224 
       
  1225 	// Easy out if no scrolling will do
       
  1226 	if (preferredMinimumScrollPosition <= currentScrollPosition
       
  1227 		&& currentScrollPosition <= preferredMaximumScrollPosition)
       
  1228 		return 0;
       
  1229 
       
  1230 	TInt suggestedPosition = currentScrollPosition;
       
  1231 	// Otherwise scrolling is either to just greater than the minimum or
       
  1232 	// just greater than the maximum.
       
  1233 	if (currentScrollPosition < preferredMinimumScrollPosition)
       
  1234 		{
       
  1235 		TInt jump = preferredMinimumScrollPosition - currentScrollPosition
       
  1236 			 + iHorizontalScrollJump - 1;
       
  1237 		jump = (jump / iHorizontalScrollJump) * iHorizontalScrollJump;
       
  1238 		suggestedPosition = Min(currentScrollPosition + jump,
       
  1239 			preferredMaximumScrollPosition);
       
  1240 		}
       
  1241 	else
       
  1242 		{
       
  1243 		TInt jump = currentScrollPosition - preferredMaximumScrollPosition
       
  1244 			 + iHorizontalScrollJump - 1;
       
  1245 		jump = (jump / iHorizontalScrollJump) * iHorizontalScrollJump;
       
  1246 		suggestedPosition = Max(currentScrollPosition - jump,
       
  1247 			preferredMinimumScrollPosition);
       
  1248 		}
       
  1249 
       
  1250 	TInt delta = suggestedPosition - iDrawTextLayoutContext.iTextStartX;
       
  1251 	iDrawTextLayoutContext.iTextStartX = suggestedPosition;
       
  1252 
       
  1253 	return delta;
       
  1254 	}
       
  1255 
       
  1256 /** Reformats the whole document, or just the visible text, if formatting is
       
  1257 set to the band only (see CTextLayout::SetAmountToFormat()).
       
  1258 
       
  1259 Notes:
       
  1260 
       
  1261 Reformatting the entire document may be time consuming, so only use this
       
  1262 function if necessary.
       
  1263 
       
  1264 This function does not redraw the reformatted text. */
       
  1265 EXPORT_C void CTextView::FormatTextL()
       
  1266 	{
       
  1267 
       
  1268 	iCursor.MatchCursorHeightToAdjacentChar();
       
  1269 	iLayout->DiscardFormat();
       
  1270 	if (iNoMemory)
       
  1271 		{
       
  1272 		iNoMemory=EFRecovering;
       
  1273 		RecreateWindowServerObjectsL();
       
  1274 		}
       
  1275 	TRAPD(err,iLayout->FormatBandL());
       
  1276 	if (err)
       
  1277 		NoMemoryL(err);
       
  1278 	NotifyReformatL();
       
  1279 	iNoMemory=EFMemoryOK;
       
  1280 	}
       
  1281 
       
  1282 void CTextView::ResetOffScreenBitmapContext(TAny* aTextView)
       
  1283 	{
       
  1284 	CTextView* that = reinterpret_cast<CTextView*>(aTextView);
       
  1285 	that->iOffScreenContext = 0;
       
  1286 	}
       
  1287 
       
  1288 void CTextView::ResetExternalDraw(TAny* aTextView)
       
  1289 	{
       
  1290 	CTextView* that = reinterpret_cast<CTextView*>(aTextView);
       
  1291 	that->iLayout->ResetExternalDraw();
       
  1292 	}
       
  1293 
       
  1294 /** Draws the text to a rectangle.
       
  1295 
       
  1296 Draw to a specific GC rather than the stored one. This is essential when
       
  1297 drawing CTextView objects that are embedded inside others, as happens for
       
  1298 editable text controls in WEB (the outermost WEB object is a CTextView, which
       
  1299 has embedded controls that own CEikEdwins, and these own CTextView objects).
       
  1300 @param aRect
       
  1301 	Rectangle to which the text is drawn, normally the view rectangle.
       
  1302 @param aGc
       
  1303 	Graphics context to be drawn to. Flicker-free redrawing will not be applied,
       
  1304 	so this parameter should not be a window gc if flickering is to be avoided.
       
  1305 	Notice that the fonts drawn to this context will be taken from the graphics
       
  1306 	device map given to the constructor of this object or in subsequent calls to
       
  1307 	CTextLayout::SetImageDeviceMap. If such fonts cannot be used with this bitmap
       
  1308 	context, the behaviour is undefined.
       
  1309 */
       
  1310 EXPORT_C void CTextView::DrawL(TRect aRect, CBitmapContext& aGc)
       
  1311 	{
       
  1312 	NoMemoryCheckL();
       
  1313 	iOffScreenContext = &aGc;
       
  1314 	CleanupStack::PushL(TCleanupItem(ResetOffScreenBitmapContext, this));
       
  1315 	DrawL(aRect);
       
  1316 	if (!iDisplay.IsLineCursor())
       
  1317 		DrawCursor();
       
  1318 	CleanupStack::PopAndDestroy();
       
  1319 	}
       
  1320 
       
  1321 /** Draws the text to a rectangle. Enters OOM state before leaving.
       
  1322 RWindow::BeginRedraw() should always be called before calling this function,
       
  1323 for the window that the textview draws to.
       
  1324 
       
  1325 @param aRect Rectangle to which the text is drawn, normally the view rectangle.
       
  1326 */
       
  1327 EXPORT_C void CTextView::DrawL(TRect aRect)
       
  1328 	{		//make sure exactly the correct bits are drawn ### eg line cursor etc.
       
  1329     TRect rect(iDrawTextLayoutContext.iViewRect);
       
  1330     TInt start=iFormattedUpTo;
       
  1331 
       
  1332 	if (NoMemoryCheckL())
       
  1333 		{
       
  1334         iDisplay.Invalidate(rect);
       
  1335 		return;
       
  1336 		}
       
  1337  
       
  1338 	if (!(iFlags & EFTextVisible))
       
  1339 		return;
       
  1340 	
       
  1341 	TRect drawRect(aRect);
       
  1342 	iDrawTextLayoutContext.WindowToText(drawRect);
       
  1343 	iLayout->SetReadyToRedraw();
       
  1344 	iLayout->SetExternalDraw(drawRect); // view coordinates
       
  1345 
       
  1346 	FinishBackgroundFormattingL();
       
  1347     if (start<iFormattedUpTo)
       
  1348 		{
       
  1349         rect.iTl.iY=start;
       
  1350         rect.iBr.iY=iFormattedUpTo;
       
  1351         iDisplay.Invalidate(rect);
       
  1352 	    }
       
  1353 	__ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate(),FormPanic(EFFormatOutOfDate));
       
  1354 	iDisplay.SetInvalidRect(aRect);
       
  1355 	iDrawTextLayoutContext.WindowToText(aRect);
       
  1356 	iDisplay.SetRects(RScreenDisplay::EFClipViewRect|RScreenDisplay::EFClipInvalid);
       
  1357 
       
  1358 	CleanupStack::PushL(TCleanupItem(ResetExternalDraw, this));
       
  1359 
       
  1360 	DrawTextL(aRect.iTl.iY,aRect.iBr.iY);
       
  1361 
       
  1362 	CleanupStack::PopAndDestroy();
       
  1363 	}
       
  1364 
       
  1365 /** Clears the specified number of pixels from the bottom of the screen. Enters
       
  1366 OOM state before leaving. */
       
  1367 void CTextView::ClearRectAtBottom(TInt aHeight)
       
  1368 	{
       
  1369 	iDisplay.AddRects(RScreenDisplay::EFClipViewRect);
       
  1370 	iDisplay.ActivateContext();
       
  1371 	iDisplay.ResetClippingRect();
       
  1372 	TRect rect(ViewRect());
       
  1373 	rect.iTl.iY += aHeight;
       
  1374 
       
  1375 	iLayout->BeginRedraw(rect);
       
  1376 	iDisplay.ClearRect(rect);
       
  1377 	iLayout->EndRedraw();
       
  1378 
       
  1379 	iDisplay.DeactivateContext();
       
  1380 	}
       
  1381 
       
  1382 void CTextView::DrawTextL(TInt aFromHeight,TInt aToHeight)
       
  1383 	{
       
  1384 	TInt layHeight=iLayout->YBottomLastFormattedLine();
       
  1385 	TInt winHeight=iDrawTextLayoutContext.DisplayHeight();
       
  1386 
       
  1387 	if (layHeight>winHeight)
       
  1388 		layHeight=winHeight;
       
  1389 	if (layHeight<aToHeight)
       
  1390 		aToHeight=layHeight;
       
  1391 	DisplayLineRangeL(aFromHeight,aToHeight);
       
  1392 	if (layHeight<winHeight && layHeight==aToHeight)		//Only last line has been drawn
       
  1393 		ClearRectAtBottom(layHeight);		//Must be done last as it changes the flags in RScreenDisplay
       
  1394 	DrawCursor();
       
  1395 	}
       
  1396 
       
  1397  
       
  1398 
       
  1399 /** Reformats and redraws the view in response to a single key press. The
       
  1400 precise amount of text to be reformatted is controlled by the second parameter.
       
  1401 
       
  1402 @param aType Indicates the type of edit which has taken place.
       
  1403 CTextLayout::EFCharacterInsert (the default) for a character insertion,
       
  1404 CTextLayout::EFParagraphDelimiter for a paragraph delimiter insertion,
       
  1405 CTextLayout::EFLeftDelete or CTextLayout::EFRightDelete for a character or
       
  1406 paragraph delimiter deletion to the left or right of the cursor position.
       
  1407 @param aFormatChanged ETrue if text is to be reformatted from the start of the
       
  1408 paragraph the cursor was on before the edit, EFalse if from the start of the
       
  1409 line the cursor was on before the edit.
       
  1410 @return The number of pixels by which the text had to be scrolled vertically
       
  1411 (positive means text moved down). */
       
  1412 EXPORT_C TInt CTextView::HandleCharEditL(TUint aType/*=EFCharacterInsert*/
       
  1413 	,TBool aFormatChanged/*=EFalse*/)
       
  1414 	{
       
  1415 	iContextIsNavigation = EFalse;
       
  1416 	TInt good = 0;
       
  1417 	TInt formattedFrom = 0;   
       
  1418 	TInt from = 0;
       
  1419  	TBool formatting = IsFormatting();
       
  1420 	TBool moreToDo = ETrue;
       
  1421 
       
  1422 	__ASSERT_DEBUG(!iCursorPos.IsSelection(),FormPanic(EFSelectionCannotCharEdit));
       
  1423 	__ASSERT_DEBUG(aType<=CTextLayout::EFRightDelete,FormPanic(EFBadCharacterEditType));
       
  1424 	__ASSERT_DEBUG(!aFormatChanged || aType==CTextLayout::EFRightDelete 
       
  1425 							|| aType==CTextLayout::EFLeftDelete,FormPanic(EFBadCharacterEditType));
       
  1426 	TBool recovered=NoMemoryCheckL();
       
  1427 	iCursor.MatchCursorHeightToAdjacentChar();
       
  1428 	TPoint dummyPoint;
       
  1429 	__ASSERT_DEBUG(iLayout->PosInBand(iCursorPos.TmDocPos(),dummyPoint)
       
  1430 		|| !formatting, FormPanic(EFBackgroundFormatting));
       
  1431 	TTmDocPos doc_pos = iCursorPos.TmDocPos();
       
  1432 	if ((!formatting && !iLayout->PosInBand(doc_pos,dummyPoint)) || recovered)
       
  1433 		{
       
  1434 		TInt y=0;
       
  1435 		switch (aType)
       
  1436 			{
       
  1437 		case CTextLayout::EFCharacterInsert:
       
  1438 			doc_pos.iLeadingEdge = EFalse;
       
  1439 			++doc_pos.iPos;
       
  1440 			break;
       
  1441 		case CTextLayout::EFParagraphDelimiter:
       
  1442 			++doc_pos.iPos;
       
  1443 			doc_pos.iLeadingEdge = ETrue;
       
  1444 			break;
       
  1445 		case CTextLayout::EFLeftDelete:
       
  1446 			--doc_pos.iPos;
       
  1447 			doc_pos.iLeadingEdge = EFalse;
       
  1448 			break;
       
  1449 		default:
       
  1450 			doc_pos.iLeadingEdge = EFalse;
       
  1451 			break;
       
  1452 			}
       
  1453 		iCursorPos.SetDocPos(doc_pos);
       
  1454 
       
  1455 		if (recovered)
       
  1456 			return 0;
       
  1457 		else
       
  1458 			return ViewTopOfLineL(iCursorPos.TmDocPos(),y,CTextView::EFViewDiscardAllFormat).iY;
       
  1459 		}
       
  1460 	TInt scroll = 0;
       
  1461 	TRAPD(err,moreToDo = iLayout->HandleCharEditL(aType,doc_pos.iPos,good,iFormattedUpTo,formattedFrom,
       
  1462 												  scroll,aFormatChanged));
       
  1463 
       
  1464 	doc_pos.iLeadingEdge =
       
  1465 		aType == CTextLayout::EFParagraphDelimiter?
       
  1466 		ETrue : EFalse;
       
  1467 	if (doc_pos.iPos == 0)
       
  1468 		doc_pos.iLeadingEdge = EFalse;
       
  1469 
       
  1470 	// If this document position will not yield a cursor, try the leading edge
       
  1471 	if (!doc_pos.iLeadingEdge)
       
  1472 		{
       
  1473 		TRect line;
       
  1474 		TPoint origin;
       
  1475 		TInt width, ascent, descent;
       
  1476 		if (!iLayout->GetCursor(doc_pos, ECursorVertical,
       
  1477 			line, origin, width, ascent, descent))
       
  1478 			doc_pos.iLeadingEdge = ETrue;
       
  1479 		}
       
  1480 	iCursorPos.SetDocPos(doc_pos);
       
  1481 	if (err)
       
  1482 		NoMemoryL(err);
       
  1483 	NotifyReformatL();
       
  1484 	if (formatting==EFalse)
       
  1485 		{
       
  1486 		iGood=good;
       
  1487 		if (moreToDo)
       
  1488 			StartIdleObject();
       
  1489 		}
       
  1490 	formattedFrom=Max(formattedFrom,0);
       
  1491 	TInt to=Min(iFormattedUpTo,iDrawTextLayoutContext.DisplayHeight());
       
  1492 #if defined(_DEBUG)
       
  1493 	TInt oldFormattedFrom = formattedFrom;
       
  1494 #endif
       
  1495 	if (scroll<0 && formattedFrom>0)
       
  1496 		ScrollRect(scroll,from,formattedFrom);
       
  1497 	__ASSERT_DEBUG(from==0 && formattedFrom==oldFormattedFrom,FormPanic(EFScrollCurtailed));
       
  1498 	if (to>=formattedFrom)
       
  1499 		DisplayNewLinesL(formattedFrom,to);
       
  1500 	if (!moreToDo)
       
  1501 		CheckScrollUpL();
       
  1502 	iCursorPos.UpdateLatentPosition();
       
  1503 	TInt horizScrollBy=CheckHorizontalScroll(iCursorPos.TmDocPos());	// Have had to put at end, because sometimes format all above
       
  1504 	if (horizScrollBy!=0)
       
  1505 		{
       
  1506 		ScrollDisplayL();
       
  1507 		if (moreToDo)
       
  1508 			iHorizontalScroll=EFPreviousHorizontalScroll;
       
  1509 		}
       
  1510 	return scroll;
       
  1511 	}
       
  1512 
       
  1513 /** Reformats after a change to part of the text contents. Enters OOM state
       
  1514 before leaving. */
       
  1515 TPoint CTextView::HandleBlockChangeL(TCursorSelection aSelection,TInt aOldCharsChanged
       
  1516 	,TBool aFormatChanged)
       
  1517 	{
       
  1518 	TViewRectChanges viewChanges;
       
  1519 	TCursorSelection selection;
       
  1520 
       
  1521 	iCursorPos.GetSelection(selection);
       
  1522 	TRAPD(err,iLayout->HandleBlockChangeL(aSelection,aOldCharsChanged,viewChanges,aFormatChanged));
       
  1523 	if (err)
       
  1524 		NoMemoryL(err);
       
  1525 	NotifyReformatL();
       
  1526 	__ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate(),FormPanic(EFFormatOutOfDate));
       
  1527 
       
  1528 	TInt from=0;	
       
  1529 	TInt to=iDrawTextLayoutContext.DisplayHeight();
       
  1530 	TInt horizScrollBy=CheckHorizontalScroll(iCursorPos.TmDocPos());
       
  1531 	if (horizScrollBy!=0)
       
  1532 		{
       
  1533 		TInt yBot=iLayout->YBottomLastFormattedLine();
       
  1534 		viewChanges.iFormattedFrom=0;
       
  1535 		if (yBot<to)
       
  1536 			to=yBot;
       
  1537 		viewChanges.iFormattedTo=to;
       
  1538 		}
       
  1539 	else
       
  1540 		{
       
  1541 		iDisplay.SetRects(RScreenDisplay::EFClipViewRect);
       
  1542 		iDisplay.ActivateContext();
       
  1543 		iDisplay.ResetClippingRect();
       
  1544 		if (viewChanges.iScrollAtBottom>0 && viewChanges.iFormattedTo<to)
       
  1545  			ScrollRect(viewChanges.iScrollAtBottom,viewChanges.iFormattedTo,to);
       
  1546 		if (viewChanges.iScrollAtTop!=0 && viewChanges.iFormattedFrom>0)
       
  1547 			ScrollRect(viewChanges.iScrollAtTop,from,viewChanges.iFormattedFrom);
       
  1548 		if (viewChanges.iScrollAtBottom<0 && viewChanges.iFormattedTo<to)
       
  1549 			ScrollRect(viewChanges.iScrollAtBottom,viewChanges.iFormattedTo,to);
       
  1550 		iDisplay.DeactivateContext();
       
  1551 		}
       
  1552 	iDisplay.SetRects(RScreenDisplay::EFClipViewRect);
       
  1553 	__ASSERT_DEBUG(from<=viewChanges.iFormattedFrom || from<=0,FormPanic(EFScrollError));
       
  1554 	__ASSERT_DEBUG(to>=viewChanges.iFormattedTo || to>=iDrawTextLayoutContext.DisplayHeight(),FormPanic(EFScrollError));
       
  1555 	if (from>0)
       
  1556 		DisplayLineRangeL(0,from);
       
  1557 	DisplayLineRangeL(viewChanges.iFormattedFrom,viewChanges.iFormattedTo);
       
  1558 	if (to<iDrawTextLayoutContext.DisplayHeight())
       
  1559 		DrawTextL(to);
       
  1560 	else
       
  1561 		DrawCursor();
       
  1562 	iCursorPos.UpdateLatentPosition();
       
  1563 	TInt vertScroll=viewChanges.iScrollAtTop;
       
  1564 	if (selection.LowerPos()!=selection.iCursorPos)
       
  1565 		vertScroll=viewChanges.iScrollAtBottom;
       
  1566 	__ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate(),FormPanic(EFFormatOutOfDate));
       
  1567 	return TPoint(horizScrollBy,vertScroll);
       
  1568 	}
       
  1569 
       
  1570 /** Makes a selection, but without updating the view.
       
  1571 
       
  1572 This function would only be used before calling CTextView::HandleRangeFormatChangeL() 
       
  1573 or HandleInsertDeleteL() to make a selection which will become visible (if 
       
  1574 selection visibility is on) after the change handling function has returned.
       
  1575 
       
  1576 @param aSelection The range to be selected after calling CTextView::HandleRangeFormatChangeL() 
       
  1577 or HandleInsertDeleteL(). */
       
  1578 EXPORT_C void CTextView::SetPendingSelection(const TCursorSelection& aSelection)
       
  1579 	{
       
  1580 	iCursorPos.SetPendingSelection(aSelection);
       
  1581 	}
       
  1582 
       
  1583 /** Reformats and redraws the view after changes to the character or paragraph
       
  1584 formatting of a block of text. Reformatting can take place either from the
       
  1585 start of the line or the start of the paragraph containing the cursor position,
       
  1586 depending on aFormatChanged.
       
  1587 
       
  1588 Can be used in combination with SetPendingSelection() to set a selection which
       
  1589 should remain after the function has returned.
       
  1590 
       
  1591 Note:
       
  1592 
       
  1593 A panic occurs if partial lines are excluded from the view (see
       
  1594 CTextLayout::ExcludingPartialLines()).
       
  1595 
       
  1596 Any background formatting is forced to complete first.
       
  1597 
       
  1598 @param aSelection Indicates the text range which has been reformatted.
       
  1599 @param aFormatChanged ETrue if text is to be reformatted from the start of the
       
  1600 paragraph the cursor was on before the edit, EFalse if from the start of the
       
  1601 line the cursor was on before the edit.
       
  1602 @return The number of pixels scrolled horizontally and vertically. */
       
  1603 EXPORT_C TPoint CTextView::HandleRangeFormatChangeL(TCursorSelection aSelection
       
  1604 	,TBool aFormatChanged/*=EFalse*/)
       
  1605 	{
       
  1606 	if (NoMemoryCheckL() || (!aFormatChanged && aSelection.Length()==0))
       
  1607 		return TPoint(0,0);
       
  1608 	FinishBackgroundFormattingL();
       
  1609 	iCursor.MatchCursorHeightToAdjacentChar();
       
  1610 	if (!iLayout->PosIsFormatted(iCursorPos.DocPos()))
       
  1611 		{
       
  1612 		TInt y=0;
       
  1613 		return ViewTopOfLineL(iCursorPos.TmDocPos(),y,CTextView::EFViewDiscardAllFormat);
       
  1614 		}
       
  1615 	return HandleBlockChangeL(aSelection,aSelection.Length(),aFormatChanged);
       
  1616 	}
       
  1617 
       
  1618 /** Reformats and redraws the view after inserting, deleting or replacing a
       
  1619 block of text.
       
  1620 
       
  1621 Can be used in combination with SetPendingSelection() to set a selection which
       
  1622 should remain after the function has returned.
       
  1623 
       
  1624 Notes:
       
  1625 
       
  1626 If inserting or deleting a single character, use CTextView::HandleCharEditL()
       
  1627 instead.
       
  1628 
       
  1629 A panic occurs if partial lines are excluded from the view (see
       
  1630 CTextLayout::ExcludingPartialLines()).
       
  1631 
       
  1632 @param aSelection The start and new length of the changed block. If this
       
  1633 function is being used to handle deletion only, this argument should be of
       
  1634 length zero and its start position should be the beginning of the deletion.
       
  1635 @param aDeletedChars The number of deleted characters. Specify zero if this
       
  1636 function is being used to handle insertion only.
       
  1637 @param aFormatChanged ETrue if text is to be reformatted from the start of the
       
  1638 paragraph the cursor was on before the edit, EFalse if from the start of the
       
  1639 line the cursor was on before the edit.
       
  1640 @return The number of pixels scrolled horizontally and vertically. */
       
  1641 EXPORT_C TPoint CTextView::HandleInsertDeleteL(TCursorSelection aSelection,TInt aDeletedChars
       
  1642 	,TBool aFormatChanged/*=EFalse*/)
       
  1643 	{
       
  1644 	iContextIsNavigation = EFalse;
       
  1645 	TInt docPos=aSelection.LowerPos();
       
  1646 	if (NoMemoryCheckL())
       
  1647 		return TPoint(0,CTextLayout::EFScrollRedrawWholeScreen);
       
  1648 	if (IsFormatting())
       
  1649 		{
       
  1650 		TViewYPosQualifier yPosQualifier;
       
  1651 		TPoint scroll;
       
  1652 		iCursorPos.SetPendingSelection(aSelection);
       
  1653 		scroll=DoHandleGlobalChangeL(yPosQualifier,EFViewDiscardAllFormat);
       
  1654 		return scroll;
       
  1655 		}
       
  1656 	iCursor.MatchCursorHeightToAdjacentChar();
       
  1657 	if (aSelection.iCursorPos!=aSelection.LowerPos())
       
  1658 		docPos+=aDeletedChars;
       
  1659 	if (!iLayout->PosIsFormatted(docPos))
       
  1660 		{
       
  1661 		TInt y=0;
       
  1662 		TTmDocPos pos(aSelection.iCursorPos, EFalse);
       
  1663 		if (pos.iPos == 0)
       
  1664 			pos.iLeadingEdge = ETrue;
       
  1665 		return ViewTopOfLineL(pos,y,CTextView::EFViewDiscardAllFormat);
       
  1666 		}
       
  1667 	return HandleBlockChangeL(aSelection,aDeletedChars,aFormatChanged);
       
  1668 	}
       
  1669 
       
  1670 /** Moves the text cursor to a new document position. The view is scrolled so
       
  1671 that the line containing the new cursor position is at the top, or the bottom,
       
  1672 if the scroll direction was downwards.
       
  1673 
       
  1674 Any background formatting is forced to complete first.
       
  1675 
       
  1676 @param aDocPos
       
  1677 	The new document position of the text cursor.
       
  1678 @param aDragSelectOn
       
  1679 	ETrue if the region between the old and new cursor positions should be
       
  1680 	selected, EFalse if not. If ETrue, any existing selection remains selected,
       
  1681 	so that this function can be used to extend or shorten a selected region.
       
  1682 	EFalse cancels any existing selection.
       
  1683 @return
       
  1684 	The number of pixels scrolled horizontally and vertically. */
       
  1685 EXPORT_C TPoint CTextView::SetDocPosL(const TTmDocPos& aDocPos,TBool aDragSelectOn)
       
  1686 	{
       
  1687 	iContextIsNavigation = ETrue;
       
  1688 	TInt vertical_scroll = 0;
       
  1689 	NoMemoryCheckL();
       
  1690 	FinishBackgroundFormattingL();
       
  1691 	iCursor.MatchCursorHeightToAdjacentChar();
       
  1692 	__ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate(),FormPanic(EFFormatOutOfDate));
       
  1693 	TTmDocPos pos(aDocPos);
       
  1694 	if (pos.iPos < 0)
       
  1695 		{
       
  1696 		pos.iPos = 0;
       
  1697 		pos.iLeadingEdge = EFalse;
       
  1698 		}
       
  1699 	else
       
  1700 		{
       
  1701 		TInt doc_length = iLayout->DocumentLength();
       
  1702 		if (pos.iPos > doc_length)
       
  1703 			{
       
  1704 			pos.iPos = doc_length;
       
  1705 			pos.iLeadingEdge = ETrue;
       
  1706 			}
       
  1707 		}
       
  1708 	TRAPD(error,vertical_scroll = iCursorPos.SetDocPosL(aDragSelectOn,pos));
       
  1709 	if (error)
       
  1710 		NoMemoryL(error);
       
  1711 	TInt horizontal_scroll = DrawAfterCursorMoveL(vertical_scroll);
       
  1712 	if (iCursorPos.IsSelectionToDraw())
       
  1713 		UpdateHighlightL();
       
  1714 	return TPoint(horizontal_scroll,vertical_scroll);
       
  1715 	}
       
  1716 
       
  1717  
       
  1718 /** Moves the text cursor to a new document position. The view is scrolled so
       
  1719 that the line containing the new cursor position is at the top, or the bottom,
       
  1720 if the scroll direction was downwards.
       
  1721 
       
  1722 Any background formatting is forced to complete first.
       
  1723 
       
  1724 @param aDocPos
       
  1725 	The new document position of the text cursor.
       
  1726 @param aDragSelectOn
       
  1727 	ETrue if the region between the old and new cursor positions should be
       
  1728 	selected, EFalse if not. If ETrue, any existing selection remains selected,
       
  1729 	so that this function can be used to extend or shorten a selected region.
       
  1730 	EFalse cancels any existing selection.
       
  1731 @return
       
  1732 	The number of pixels scrolled horizontally and vertically. */
       
  1733 EXPORT_C TPoint CTextView::SetDocPosL(TInt aDocPos,TBool aDragSelectOn)
       
  1734 	{
       
  1735 	TTmDocPos pos(aDocPos,
       
  1736 		aDocPos == iLayout->DocumentLength()? EFalse : ETrue);
       
  1737 	return SetDocPosL(pos,aDragSelectOn);
       
  1738 	}
       
  1739 
       
  1740 /** Moves the text cursor to a new document position. The view is scrolled so
       
  1741 that the line containing the new cursor position is at the top, or the bottom,
       
  1742 if the scroll direction was downwards.
       
  1743 
       
  1744 Any background formatting is forced to complete first.
       
  1745 
       
  1746 @param aDocPos
       
  1747 	The new document position of the text cursor.
       
  1748 @param aDragSelectOn
       
  1749 	ETrue if the region between the old and new cursor positions should be
       
  1750 	selected, EFalse if not. If ETrue, any existing selection remains selected,
       
  1751 	so that this function can be used to extend or shorten a selected region.
       
  1752 	EFalse cancels any existing selection.
       
  1753 @return
       
  1754 	The number of pixels scrolled horizontally and vertically. */
       
  1755 EXPORT_C TPoint CTextView::SetDocPosL(const TTmDocPosSpec& aDocPos,TBool aDragSelectOn)
       
  1756 	{
       
  1757 	TTmDocPos pos(aDocPos.iPos, aDocPos.iType == TTmDocPosSpec::ELeading);
       
  1758 	return SetDocPosL(pos, aDragSelectOn);
       
  1759 	}
       
  1760 
       
  1761 /** Moves the text cursor to the nearest point on the screen to the x,y coordinates 
       
  1762 specified.
       
  1763 
       
  1764 Any background formatting is forced to complete first.
       
  1765 
       
  1766 @param aPos The window coordinates to which to move the text cursor. 
       
  1767 @param aDragSelectOn ETrue if the region between the old and new cursor positions 
       
  1768 should be selected, EFalse if not. If ETrue, any existing selection remains 
       
  1769 selected, so that this function can be used to extend or shorten a selected 
       
  1770 region.EFalse cancels any existing selection. 
       
  1771 @param aPictureRect On return, a pointer to the rectangle enclosing the picture 
       
  1772 at position aPos. If there is no picture at this position, returns NULL.
       
  1773 @param aPictureFrameEdges On return, indicates whether aPos is located within 
       
  1774 the active region around a picture edge. The active region is the region inside 
       
  1775 which the cursor can be used to resize the picture. A value of zero indicates 
       
  1776 that aPos is not within this region. Otherwise, this value indicates which 
       
  1777 active region aPos is located in. For more information, see TFrameOverlay::TEdges. 
       
  1778 
       
  1779 @return The number of pixels scrolled horizontally and vertically. */
       
  1780 EXPORT_C TPoint CTextView::SetXyPosL(TPoint aPos,TBool aDragSelectOn,TRect*& aPictureRect,TInt& aPictureFrameEdges)
       
  1781 	{
       
  1782 	iContextIsNavigation = ETrue;
       
  1783 	NoMemoryCheckL();
       
  1784 	FinishBackgroundFormattingL();
       
  1785 	iCursor.MatchCursorHeightToAdjacentChar();
       
  1786 	__ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate(),FormPanic(EFFormatOutOfDate));
       
  1787 	aPictureFrameEdges=TFrameOverlay::ENoEdges;
       
  1788 	if (iPictureFrame && iCursorPos.IsPictureFrame() && SelectionVisible())
       
  1789 		{
       
  1790 		aPictureFrameEdges=iPictureFrame->XyPosToEdges(aPos);
       
  1791 		if (aPictureFrameEdges!=TFrameOverlay::ENoEdges && iDrawTextLayoutContext.TextArea().Contains(aPos))
       
  1792 			{
       
  1793 			aPos=iPictureFrame->Rect().Center();
       
  1794 			aPictureRect=CONST_CAST(TRect*,&iPictureFrame->RefRect());
       
  1795 			return TPoint(0,0);
       
  1796 			}
       
  1797 		}
       
  1798 	iDrawTextLayoutContext.WindowToText(aPos);
       
  1799 	TInt scrollBy=0;		//To stop warning
       
  1800 	TRAPD(err,scrollBy=iCursorPos.SetXyPosL(aDragSelectOn,aPos,(iFlags & EFPictureFrameEnabled)));
       
  1801 	// Have we just moved over a picture?
       
  1802 	if(iCursorPos.IsPictureFrame()|| iCursorPos.IsNewPictureFrame())
       
  1803 		UpdatePictureFrameL();
       
  1804 
       
  1805 	if (err)
       
  1806 		NoMemoryL(err);
       
  1807 	TInt horizScrollBy=DrawAfterCursorMoveL(scrollBy);
       
  1808 	if (iCursorPos.IsSelectionToDraw())
       
  1809 		UpdateHighlightL();
       
  1810 	if (iCursorPos.IsPictureFrame() && SelectionVisible())		//Should the rectangle be returned when there is color dimming #JD# The way it is written here it will not be
       
  1811 		aPictureRect=CONST_CAST(TRect*,&iPictureFrame->RefRect());
       
  1812 	else
       
  1813 		aPictureRect=NULL;
       
  1814 	return TPoint(horizScrollBy,scrollBy);
       
  1815 	}
       
  1816 
       
  1817 /** Scrolls the view either horizontally or vertically and does a redraw.
       
  1818 
       
  1819 Any background formatting is forced to complete first.
       
  1820 
       
  1821 @param aMovement Controls the direction and the amount of scroll. 
       
  1822 @param aScrollBlankSpace CTextLayout::EFAllowScrollingBlankSpace allows blank 
       
  1823 space to scroll into the visible area (applies when scrolling horizontally 
       
  1824 as well as vertically), CTextLayout::EFDisallowScrollingBlankSpace prevents 
       
  1825 blank space from scrolling into the visible area. 
       
  1826 @pre aMovement must not scroll the display beyond the formatted range. If aMovement
       
  1827 scrolls beyond the formatted range, this method will leave with the error code
       
  1828 CTextLayout::EPosNotFormatted
       
  1829 @return The number of pixels scrolled */
       
  1830 EXPORT_C TInt CTextView::ScrollDisplayL(TCursorPosition::TMovementType aMovement
       
  1831 					,CTextLayout::TAllowDisallow aScrollBlankSpace/*=EFDisallowScrollingBlankSpace*/)
       
  1832 	{
       
  1833 	TInt pixels=0;		//To stop warning
       
  1834 
       
  1835 	NoMemoryCheckL();
       
  1836 	__ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate(),FormPanic(EFFormatOutOfDate));
       
  1837 	FinishBackgroundFormattingL();
       
  1838 	__ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate(),FormPanic(EFFormatOutOfDate));
       
  1839 	TRAPD(err,pixels=DoScrollDisplayL(aMovement,aScrollBlankSpace));
       
  1840 	if (err)
       
  1841 		{
       
  1842 		if (err == CTextLayout::EPosNotFormatted)
       
  1843 			User::Leave(err);
       
  1844 		else
       
  1845 			NoMemoryL(err);
       
  1846 		}
       
  1847 	return pixels;
       
  1848 	}
       
  1849 
       
  1850 TInt CTextView::DoHorizontalScrollDisplayL(TCursorPosition::TMovementType aMovement
       
  1851 	,CTextLayout::TAllowDisallow aScrollBlankSpace)
       
  1852 	{
       
  1853 	TInt pixels=0;
       
  1854 	TInt leftX,rightX;
       
  1855 
       
  1856 	CalculateHorizontalExtremes(leftX,rightX,ETrue);
       
  1857 	TInt rightEdgeScroll=iDrawTextLayoutContext.TextArea().Width()-rightX;
       
  1858 	switch (aMovement)
       
  1859 		{
       
  1860 	case TCursorPosition::EFLeft:
       
  1861 		pixels=iHorizontalScrollJump;
       
  1862 		if (aScrollBlankSpace==CTextLayout::EFDisallowScrollingBlankSpace)
       
  1863 			pixels=Min(pixels,Max(-leftX,0));
       
  1864 		break;
       
  1865 	case TCursorPosition::EFRight:
       
  1866 		pixels=-iHorizontalScrollJump;
       
  1867 		if (aScrollBlankSpace==CTextLayout::EFDisallowScrollingBlankSpace)
       
  1868 			pixels=Max(pixels,Min(rightEdgeScroll,0));
       
  1869 		break;
       
  1870 	case TCursorPosition::EFLineBeg:
       
  1871 		pixels=-leftX;
       
  1872 		break;
       
  1873 	case TCursorPosition::EFLineEnd:
       
  1874 		pixels=rightEdgeScroll;
       
  1875 		break;
       
  1876 	default:
       
  1877 		#if defined(_DEBUG)
       
  1878 			FormPanic(EFInvalidScrollingType)
       
  1879 		#endif
       
  1880 		;
       
  1881 		}
       
  1882 	SetLeftTextMargin(LeftTextMargin()-pixels);
       
  1883 
       
  1884 	if (0 != pixels)
       
  1885 		{
       
  1886 		ScrollDisplayL();
       
  1887 		}
       
  1888 	else
       
  1889 		{
       
  1890 		DrawCursor();
       
  1891 		}
       
  1892 
       
  1893 	return pixels;
       
  1894 	}
       
  1895 
       
  1896 TInt CTextView::DoScrollDisplayL(TCursorPosition::TMovementType aMovement,
       
  1897 								 CTextLayout::TAllowDisallow aScrollBlankSpace)
       
  1898 	{
       
  1899 	TInt pixels = 0;
       
  1900 	TInt lines = 0;
       
  1901 	TInt cursor_pos = 0;
       
  1902 
       
  1903 	switch (aMovement)
       
  1904 		{
       
  1905 		case TCursorPosition::EFLeft:
       
  1906 		case TCursorPosition::EFRight:
       
  1907 		case TCursorPosition::EFLineBeg:
       
  1908 		case TCursorPosition::EFLineEnd:
       
  1909 			return DoHorizontalScrollDisplayL(aMovement,aScrollBlankSpace);
       
  1910 
       
  1911 		case TCursorPosition::EFLineUp:
       
  1912 			lines = 1;
       
  1913 			break;
       
  1914 
       
  1915 		case TCursorPosition::EFLineDown:
       
  1916 			lines = -1;
       
  1917 			break;
       
  1918 
       
  1919 		case TCursorPosition::EFPageUp:
       
  1920 			iLayout->PageUpL(cursor_pos,pixels);
       
  1921 			break;
       
  1922 
       
  1923 		case TCursorPosition::EFPageDown:
       
  1924 			cursor_pos = iDrawTextLayoutContext.DisplayHeight() - 1;
       
  1925 			iLayout->PageDownL(cursor_pos,pixels);
       
  1926 			break;
       
  1927 
       
  1928 		default:
       
  1929 			break;
       
  1930 		}
       
  1931 
       
  1932 	if (lines)
       
  1933 		pixels = iLayout->ScrollLinesL(lines,aScrollBlankSpace);
       
  1934 
       
  1935 	if (pixels)
       
  1936 		{
       
  1937 		iCursorPos.TextMoveVertically();
       
  1938 		ScrollDisplayL();
       
  1939 		}
       
  1940 
       
  1941 	return pixels;
       
  1942 	}
       
  1943 
       
  1944 /** Moves the text cursor in the direction and manner specified. If necessary,
       
  1945 the view is scrolled so that the line containing the new cursor position is
       
  1946 visible.
       
  1947 
       
  1948 Any background formatting is forced to complete first.
       
  1949 
       
  1950 @param aMovement The direction and manner in which to move the cursor. On
       
  1951 return set to the actual cursor movement. The actual cursor movement may be
       
  1952 different from the one requested if for example the desired cursor movement is
       
  1953 upwards and the cursor is already on the top line. In this case, this argument
       
  1954 will return TCursorPosition::EFLineBeg. A return value of
       
  1955 TCursorPosition::EFNoMovement indicates that no cursor movement took place.
       
  1956 @param aDragSelectOn ETrue if the region between the old and new cursor
       
  1957 positions should be selected, EFalse if not. If ETrue, any existing selection
       
  1958 remains selected, so that this function can be used to extend or shorten a
       
  1959 selected region. EFalse cancels any existing selection.
       
  1960 @return The number of pixels scrolled horizontally and vertically. */
       
  1961 EXPORT_C TPoint CTextView::MoveCursorL(TCursorPosition::TMovementType& aMovement,TBool aDragSelectOn)
       
  1962 	{
       
  1963 	iContextIsNavigation = ETrue;
       
  1964 	NoMemoryCheckL();
       
  1965 	FinishBackgroundFormattingL();
       
  1966 	__ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate(),FormPanic(EFFormatOutOfDate));
       
  1967 	iCursor.MatchCursorHeightToAdjacentChar();
       
  1968 	return DoMoveCursorL(aDragSelectOn, aMovement,
       
  1969 		iFlags & EFPictureFrameEnabled);
       
  1970 	}
       
  1971 
       
  1972 TPoint CTextView::DoMoveCursorL(TBool aDragSelectOn,TCursorPosition::TMovementType& aMovement
       
  1973 	,TBool aAllowPictureFrame)
       
  1974 	{
       
  1975 	TInt scrollBy=0;		//To avoid complier warning
       
  1976 
       
  1977 	TRAPD(err,scrollBy=iCursorPos.MoveL(aDragSelectOn,aMovement,aAllowPictureFrame));
       
  1978 	// Have we just moved over a picture?
       
  1979 	if(iCursorPos.IsPictureFrame()|| iCursorPos.IsNewPictureFrame())
       
  1980 		UpdatePictureFrameL();
       
  1981 
       
  1982 	if (err)
       
  1983 		NoMemoryL(err);
       
  1984 	TInt horizScrollBy=DrawAfterCursorMoveL(scrollBy);
       
  1985 	if (iCursorPos.IsSelectionToDraw())
       
  1986 		UpdateHighlightL();
       
  1987 	return TPoint(horizScrollBy,scrollBy);
       
  1988 	}
       
  1989 
       
  1990 /** Scrolls the view vertically by a number of pixels, disallowing blank space
       
  1991 from scrolling into the bottom of the visible area. Redraws the newly visible
       
  1992 lines.
       
  1993 
       
  1994 Any background formatting is forced to complete first.
       
  1995 
       
  1996 @param aDeltaY
       
  1997 	The number of pixels to scroll; may be a positive or negative value. On
       
  1998 	return, contains the number of pixels actually scrolled. Positive values
       
  1999 	move the text down, negative move it up. */
       
  2000 EXPORT_C void CTextView::ScrollDisplayPixelsL(TInt& aDeltaY)
       
  2001 	{
       
  2002 
       
  2003 	NoMemoryCheckL();
       
  2004 	FinishBackgroundFormattingL();
       
  2005 	TRAPD(err,iLayout->ChangeBandTopL(aDeltaY));
       
  2006 	if (err)
       
  2007 		NoMemoryL(err);
       
  2008 
       
  2009 	if (0 != aDeltaY)
       
  2010 		{
       
  2011 		ScrollDisplayL();
       
  2012 		}
       
  2013 	else
       
  2014 		{
       
  2015 		DrawCursor();
       
  2016 		}
       
  2017 	} 
       
  2018 
       
  2019 /** Scrolls the view vertically by a number of pixels, allowing blank space
       
  2020 from scrolling into both top and bottom of the visible area, which means the 
       
  2021 scrolling can go beyond the top or bottom border. Redraws the newly visible
       
  2022 lines.
       
  2023 
       
  2024 Any background formatting is forced to complete first.
       
  2025 
       
  2026 @param aDeltaY
       
  2027     The number of pixels to scroll; may be a positive or negative value. On
       
  2028     return, contains the number of pixels actually scrolled. Positive values
       
  2029     move the text down, negative move it up. */
       
  2030 EXPORT_C void CTextView::ScrollDisplayPixelsNoLimitBorderL(TInt aDeltaY)
       
  2031     {
       
  2032     NoMemoryCheckL();
       
  2033     FinishBackgroundFormattingL();
       
  2034     TRAPD(err,iLayout->ChangeBandTopNoLimitBorderL(aDeltaY));
       
  2035     if (err)
       
  2036         NoMemoryL(err);
       
  2037 
       
  2038     if (0 != aDeltaY)
       
  2039         {
       
  2040         ScrollDisplayL();
       
  2041         }
       
  2042     else
       
  2043         {
       
  2044         DrawCursor();
       
  2045         }
       
  2046     } 
       
  2047 
       
  2048 /** Scrolls the view vertically by a number of wholly or partially visible
       
  2049 lines, disallowing blank space at the bottom of the visible area if
       
  2050 aScrollBlankSpace is CTextLayout::EFDisallowScrollingBlankSpace. Redraws the
       
  2051 newly visible lines.
       
  2052 
       
  2053 Any background formatting is forced to complete first.
       
  2054 
       
  2055 @param aDeltaLines
       
  2056 	The number of lines to scroll; may be a positive or negative value.
       
  2057 	Positive values move the text down, negative move it up. On return,
       
  2058 	contains the number of lines not scrolled; that is, the requested number,
       
  2059 	minus the number actually scrolled.
       
  2060 @param aScrollBlankSpace
       
  2061 	Only relevant when scrolling downwards.
       
  2062 	CTextLayout::EFAllowScrollingBlankSpace allows blank space to scroll into
       
  2063 	the visible area. CTextLayout::EFDisallowScrollingBlankSpace prevents blank
       
  2064 	space from scrolling into the visible area.
       
  2065 @pre aDeltaLines must not scroll the display beyond the formatted range. If aDeltaLines
       
  2066 	scrolls beyond the formatted range, this method will leave with the error code
       
  2067 	CTextLayout::EPosNotFormatted
       
  2068 @return The number of pixels scrolled.
       
  2069 */
       
  2070 EXPORT_C TInt CTextView::ScrollDisplayLinesL(TInt& aDeltaLines
       
  2071 					,CTextLayout::TAllowDisallow aScrollBlankSpace/*=EFDisallowScrollingBlankSpace*/)
       
  2072 	{
       
  2073 	TInt pixels=0;
       
  2074 
       
  2075 	NoMemoryCheckL();
       
  2076 	FinishBackgroundFormattingL();
       
  2077 	TRAPD(err,pixels=iLayout->ScrollLinesL(aDeltaLines,aScrollBlankSpace));
       
  2078 	if (err)
       
  2079  		{
       
  2080  		if (err == CTextLayout::EPosNotFormatted)
       
  2081  			User::Leave(err);
       
  2082  		else
       
  2083  			NoMemoryL(err);
       
  2084  		}
       
  2085 
       
  2086 	if (0 != pixels)
       
  2087 		{
       
  2088 		ScrollDisplayL();
       
  2089 		}
       
  2090 	else
       
  2091 		{
       
  2092 		DrawCursor();
       
  2093 		}
       
  2094 
       
  2095 	return pixels;
       
  2096 	} 
       
  2097 
       
  2098 /** Scrolls the view by a number of wholly or partially visible paragraphs
       
  2099 disallowing blank space at the bottom of the visible area if aScrollBlankSpace
       
  2100 is CTextLayout::EFDisallowScrollingBlankSpace. Redraws the newly visible
       
  2101 paragraphs.
       
  2102 
       
  2103 Any background formatting is forced to complete first.
       
  2104 
       
  2105 @param aDeltaParas
       
  2106 	The number of paragraphs to scroll; may be a positive or negative value;
       
  2107 	positive values move the text down, negative move it up. On return,
       
  2108 	contains the number of paragraphs not scrolled; that is the difference
       
  2109 	between the requested number and the number of paragraphs actually
       
  2110 	scrolled.
       
  2111 @param aScrollBlankSpace
       
  2112 	Only relevant when scrolling downwards.
       
  2113 	CTextLayout::EFAllowScrollingBlankSpace allows blank space to scroll into
       
  2114 	the visible area. CTextLayout::EFDisallowScrollingBlankSpace prevents blank
       
  2115 	space from scrolling into the visible area.
       
  2116 @pre aDeltaParas must not scroll the display beyond the formatted range. If aDeltaParas
       
  2117 	scrolls beyond the formatted range, this method will leave with the error code
       
  2118 	CTextLayout::EPosNotFormatted
       
  2119 @return The number of pixels scrolled. */
       
  2120 EXPORT_C TInt CTextView::ScrollDisplayParagraphsL(TInt& aDeltaParas
       
  2121 					,CTextLayout::TAllowDisallow aScrollBlankSpace/*=EFDisallowScrollingBlankSpace*/)
       
  2122 	{
       
  2123 	TInt pixels=0;
       
  2124 
       
  2125 	NoMemoryCheckL();
       
  2126 	FinishBackgroundFormattingL();
       
  2127 	TRAPD(err,pixels=iLayout->ScrollParagraphsL(aDeltaParas,aScrollBlankSpace));
       
  2128 	if (err)
       
  2129  		{
       
  2130  		if (err == CTextLayout::EPosNotFormatted)
       
  2131  			User::Leave(err);
       
  2132  		else
       
  2133  			NoMemoryL(err);
       
  2134  		}
       
  2135 
       
  2136 	if (0 != pixels)
       
  2137 		{
       
  2138 		ScrollDisplayL();
       
  2139 		}
       
  2140 	else
       
  2141 		{
       
  2142 		DrawCursor();
       
  2143 		}
       
  2144 
       
  2145 	return pixels;
       
  2146 	}
       
  2147 
       
  2148 /** Returns the left and right extremes, in window coordinates, of the formatted 
       
  2149 text.
       
  2150 
       
  2151 @param aLeftX On return, contains the x coordinate of the leftmost point of 
       
  2152 the formatted text. 
       
  2153 @param aRightX On return, contains the x coordinate of the rightmost point 
       
  2154 of the formatted text. 
       
  2155 @param aOnlyVisibleLines If ETrue, only scans partially or fully visible lines. 
       
  2156 If EFalse, scans all the formatted text. */
       
  2157 EXPORT_C void CTextView::CalculateHorizontalExtremesL(TInt& aLeftX,TInt& aRightX,TBool aOnlyVisibleLines)
       
  2158 	{
       
  2159 
       
  2160 	CalculateHorizontalExtremes(aLeftX,aRightX,aOnlyVisibleLines);
       
  2161 	}
       
  2162 
       
  2163 void CTextView::CalculateHorizontalExtremes(TInt& aLeftX,TInt& aRightX,TBool aOnlyVisibleLines)
       
  2164 	{
       
  2165 	iLayout->CalculateHorizontalExtremes(aLeftX,aRightX,aOnlyVisibleLines);
       
  2166 	aLeftX += iDrawTextLayoutContext.iTextStartX;
       
  2167 	aRightX += iDrawTextLayoutContext.iTextStartX;
       
  2168 	}
       
  2169 
       
  2170 /** Scroll the display below point aFrom by aScrollX.
       
  2171 
       
  2172 aScrollY>0 ==> text moves down.
       
  2173 
       
  2174 aScrollX>0 ==> text moves right.
       
  2175 
       
  2176 aFrom is relative to the text area of the window.
       
  2177 
       
  2178 aScrollBackground determines whether the background can scroll along with the text.
       
  2179 
       
  2180 Enters OOM before leaving */
       
  2181 void CTextView::ScrollTextL(TInt aScrollY,TInt aFrom,TInt aScrollX,TBool aScrollBackground)
       
  2182 	{
       
  2183 	TRect rect;
       
  2184 	TInt height=iDrawTextLayoutContext.DisplayHeight();
       
  2185 
       
  2186 	__ASSERT_DEBUG(aScrollX!=0 || aScrollY!=0,FormPanic(EFScrollByZero2));
       
  2187 	__ASSERT_DEBUG(aFrom==0 || aScrollX==0,FormPanic(EFScrollError));       //Can only scroll the whole of the ViewRect Horizontally
       
  2188 	if (aScrollX==0)
       
  2189 		rect=iDrawTextLayoutContext.iViewRect;
       
  2190 	else
       
  2191 		rect=iDrawTextLayoutContext.TextArea();
       
  2192 
       
  2193 	if (iReducedDrawingAreaRect.Height())
       
  2194 		{
       
  2195 		rect.Intersection(iReducedDrawingAreaRect);
       
  2196 		}
       
  2197 
       
  2198 	if (iReducedDrawingAreaRect.Height())
       
  2199 		rect.Intersection(iReducedDrawingAreaRect);
       
  2200 
       
  2201 	if (ExtendedHighlightExists())
       
  2202 		{
       
  2203 		AdjustRectForScrolling(rect,aScrollY,aScrollX);
       
  2204 		}
       
  2205 	
       
  2206 	ScrollRect(rect,aScrollY,aFrom,aScrollX,aScrollBackground);
       
  2207 	if (aScrollX!=0 && aScrollY!=0)
       
  2208 		{
       
  2209 		rect=iDrawTextLayoutContext.TotalMargin();
       
  2210 		ScrollRect(rect,aScrollY,0,0,aScrollBackground);
       
  2211 		}
       
  2212 
       
  2213 	if (iHeightNotDrawn>0 && aScrollY<0 && height+aScrollY>=aFrom)
       
  2214 		{
       
  2215 		iDisplay.SetRects(RScreenDisplay::EFClipViewRect);
       
  2216 		DisplayLineRangeL(aScrollY+height-iHeightNotDrawn,aScrollY+height);
       
  2217 		}
       
  2218 	}
       
  2219 
       
  2220 
       
  2221 /** Scroll part of the view rect.
       
  2222 @param aScrollY
       
  2223 	Number of pixels downwards to scroll
       
  2224 @param aFrom
       
  2225 	First line visible after the scroll.
       
  2226 @param aTo
       
  2227 	Last line visible after the scroll.
       
  2228 */
       
  2229 void CTextView::ScrollRect(TInt aScrollY,TInt& aFrom,TInt& aTo)
       
  2230 	{
       
  2231 	TRect rect=ViewRect();
       
  2232 
       
  2233 	if (ExtendedHighlightExists())
       
  2234 		{
       
  2235 		AdjustRectForScrolling(rect,aScrollY,0);
       
  2236 		}
       
  2237 
       
  2238 	TInt top=rect.iTl.iY;
       
  2239 
       
  2240 	__ASSERT_DEBUG(aTo>=0 && aTo>aFrom,FormPanic(EFScrollError));
       
  2241 	aFrom-=aScrollY;
       
  2242 	if (aFrom>0)
       
  2243 		{
       
  2244 		rect.iTl.iY+=aFrom;
       
  2245 		if (aFrom>=iDrawTextLayoutContext.DisplayHeight())
       
  2246 			{
       
  2247 			aFrom+=aScrollY;
       
  2248 			aTo=aFrom;
       
  2249 			return;
       
  2250 			}
       
  2251 		}
       
  2252 	aTo+=top-aScrollY;
       
  2253 	if (aTo<rect.iBr.iY)
       
  2254 		{
       
  2255 		rect.iBr.iY=aTo;
       
  2256 		if (aTo<=top)
       
  2257 			{
       
  2258 			aTo-=top-aScrollY;
       
  2259 			aFrom=aTo;
       
  2260 			return;
       
  2261 			}
       
  2262 		}
       
  2263 	iDisplay.Scroll(rect,TPoint(0,aScrollY),FALSE);
       
  2264 	aFrom=rect.iTl.iY+aScrollY-top;
       
  2265 	aTo=rect.iBr.iY+aScrollY-top;
       
  2266 	}
       
  2267 
       
  2268 /**  Scroll part of the view rect */
       
  2269 void CTextView::ScrollRect(TRect& aRect,TInt aScrollY,TInt aFrom,TInt aScrollX,TBool aScrollBackground)
       
  2270 	{
       
  2271 
       
  2272 	aFrom=aFrom<0?0:aFrom;
       
  2273 	if (aScrollY+aFrom<0)
       
  2274 		aRect.iTl.iY-=aScrollY;
       
  2275 	else
       
  2276 		{
       
  2277 		aRect.iTl.iY+=aFrom;
       
  2278 		if (aScrollY>0)
       
  2279 			aRect.iBr.iY-=aScrollY;
       
  2280 		}
       
  2281 	if (aScrollX<0)
       
  2282 		aRect.iTl.iX-=aScrollX;
       
  2283 	else
       
  2284 		aRect.iBr.iX-=aScrollX;
       
  2285 	iDisplay.SetRects(RScreenDisplay::EFClipViewRect);
       
  2286 	iDisplay.ActivateContext();
       
  2287 	iDisplay.ResetClippingRect();
       
  2288 	iDisplay.Scroll(aRect,TPoint(aScrollX,aScrollY),aScrollBackground);
       
  2289 	iDisplay.DeactivateContext();
       
  2290 	}
       
  2291 
       
  2292 /** Scroll the display and redraw the missing lines.*/
       
  2293 void CTextView::ScrollDisplayL()
       
  2294 	{
       
  2295 	iDisplay.SetRects(RScreenDisplay::EFClipViewRect);
       
  2296 	DrawTextL();
       
  2297 	}
       
  2298 
       
  2299 /** Sets the visibility of the line and text cursors.
       
  2300 
       
  2301 Notes:
       
  2302 
       
  2303 A group window must have been provided before a text cursor can be drawn.
       
  2304 
       
  2305 Before making the line cursor visible, a line cursor bitmap must have been 
       
  2306 provided (see SetLineCursorBitmap()).
       
  2307 
       
  2308 @param aLineCursor Sets whether the line cursor should be displayed. For possible 
       
  2309 values, see the TCursor::TVisibility enumeration. 
       
  2310 @param aTextCursor Sets whether the text cursor should be displayed and if 
       
  2311 so, whether it should flash. For possible values, see the TCursor::TVisibility 
       
  2312 enumeration. */
       
  2313 EXPORT_C void CTextView::SetCursorVisibilityL(TUint aLineCursor,TUint aTextCursor)
       
  2314 	{
       
  2315 	__ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate() ||
       
  2316 				   (aLineCursor==TCursor::EFCursorInvisible && aTextCursor==TCursor::EFCursorInvisible),
       
  2317 				   FormPanic(EFFormatOutOfDate));
       
  2318 	NoMemoryCheckL();
       
  2319 	iCursor.SetVisibility((TCursor::TVisibility)aLineCursor,(TCursor::TVisibility)aTextCursor);
       
  2320 	}
       
  2321 
       
  2322 /** Sets whether the text and pictures within a selection should be highlighted. 
       
  2323 If necessary, the view is redrawn.
       
  2324 
       
  2325 An example of when this function may need to be used is when a control loses 
       
  2326 or gains focus.
       
  2327 
       
  2328 @param aSelectionVisible ETrue for highlighted selection. EFalse for unhighlighted 
       
  2329 selection. */
       
  2330 EXPORT_C void CTextView::SetSelectionVisibilityL(TBool aVisible)
       
  2331 	{
       
  2332 
       
  2333 	NoMemoryCheckL();
       
  2334 	TBool needInverting=((!aVisible)!=(!(iFlags & EFSelectionVisible))); //Extra '!' needed to cope with aVisible>1
       
  2335 	if (needInverting && !iDrawTextLayoutContext.TextOverrideColor() && (iFlags & EFTextVisible))
       
  2336 		{
       
  2337 	 	TCursorSelection selection;
       
  2338 
       
  2339 		__ASSERT_DEBUG(iLayout->__DbgIsFormattingUpToDate(),FormPanic(EFFormatOutOfDate));
       
  2340 		iFlags |= EFSelectionVisible;
       
  2341 		iCursorPos.GetSelection(selection);
       
  2342 		TBool isPictureFrame=iCursorPos.IsPictureFrame();
       
  2343 		iDisplay.SetRects(RScreenDisplay::EFClipTextArea);
       
  2344 		iDisplay.ActivateContext();
       
  2345 		iDisplay.ResetClippingRect();
       
  2346 		if (selection.Length()>0)
       
  2347 			{
       
  2348 			if (isPictureFrame)
       
  2349 				{
       
  2350 				iCursorPos.DontDrawOldPictureFrame();
       
  2351 				RedrawPictureFrameRectL(selection.LowerPos());
       
  2352 				DrawCursor(TCursor::EFTextCursor);
       
  2353 				}
       
  2354 			else
       
  2355 				{
       
  2356 				CTextLayout::TRangeChange select(selection.iAnchorPos, selection.iCursorPos,
       
  2357 					aVisible? CTextLayout::TRangeChange::ESet : CTextLayout::TRangeChange::EClear);
       
  2358 				iDisplay.SetRects(RScreenDisplay::EFClipExtendedTextArea);
       
  2359 				iDisplay.ResetClippingRect();
       
  2360 				HighlightUsingExtensions(select,select);
       
  2361 				}
       
  2362 			}
       
  2363 		iDisplay.DeactivateContext();
       
  2364 		}
       
  2365 	if (aVisible)
       
  2366 		iFlags |= EFSelectionVisible;
       
  2367 	else
       
  2368 		iFlags &= ~EFSelectionVisible;
       
  2369 	}
       
  2370 
       
  2371 /** Sets whether a picture frame should be displayed when the text cursor is located 
       
  2372 at a picture character.
       
  2373 
       
  2374 Note:
       
  2375 
       
  2376 If a picture frame is currently displayed, and aEnabled is EFalse, a redraw 
       
  2377 takes place, so that the frame is removed.
       
  2378 
       
  2379 @param aEnabled True to enable picture frames, false to disable them. */
       
  2380 EXPORT_C void CTextView::EnablePictureFrameL(TBool aEnabled)
       
  2381 	{
       
  2382 
       
  2383 	NoMemoryCheckL();
       
  2384 	if (aEnabled)
       
  2385 		iFlags |= EFPictureFrameEnabled;
       
  2386 	else
       
  2387 		iFlags &= ~EFPictureFrameEnabled;
       
  2388 	if (iCursorPos.IsPictureFrame() && !aEnabled)
       
  2389 		CancelSelectionL();
       
  2390 	}
       
  2391 
       
  2392 /** Returns if the selection is currently visible.
       
  2393 
       
  2394 In particular, the selection is invisible if the text color has been
       
  2395 overridden. */
       
  2396 EXPORT_C TBool CTextView::SelectionVisible() const
       
  2397 	{
       
  2398 	return ((!iDrawTextLayoutContext.TextOverrideColor())
       
  2399  		&& (iFlags & EFSelectionVisible) && (iFlags & EFTextVisible));
       
  2400 	}
       
  2401 
       
  2402 TPoint CTextView::ViewTopOfLineL(const TTmDocPos& aDocPos,TInt& aYPos,CTextView::TDiscard aDiscardFormat,
       
  2403 								 TDoHorizontalScroll aHorizontalScroll)
       
  2404 	{
       
  2405 	TViewYPosQualifier yPosQualifier;
       
  2406 	yPosQualifier.SetHotSpot(TViewYPosQualifier::EFViewTopOfLine);
       
  2407 	return ViewL(aDocPos,aYPos,yPosQualifier,aDiscardFormat,aHorizontalScroll);
       
  2408 	}
       
  2409 
       
  2410 TPoint CTextView::ViewL(const TTmDocPos& aDocPos,TInt& aYPos,TViewYPosQualifier aYPosQualifier,
       
  2411 						CTextView::TDiscard aDiscardFormat,TDoHorizontalScroll aHorizontalScroll)
       
  2412 	{
       
  2413 	CTextLayout::TDiscard discardFormat=CTextLayout::EFViewDontDiscardFormat;
       
  2414 	TInt scrollBy = 0;
       
  2415 	
       
  2416 	if (aDiscardFormat==EFViewDiscardAllFormat || aDiscardFormat==EFViewDiscardAllNoRedraw)
       
  2417 		discardFormat=CTextLayout::EFViewDiscardAllFormat;
       
  2418 	if (IsFormatting())
       
  2419 		{
       
  2420 		if (discardFormat==CTextLayout::EFViewDontDiscardFormat)
       
  2421 			FinishBackgroundFormattingL();
       
  2422 		else
       
  2423 			{
       
  2424 			iWrap->Cancel();
       
  2425 			iLayout->NotifyTerminateBackgroundFormatting();
       
  2426 			}
       
  2427 		}
       
  2428 	TRAPD(err,scrollBy=iLayout->SetViewL(aDocPos,aYPos,aYPosQualifier,discardFormat));
       
  2429 	if (err)
       
  2430 		NoMemoryL(err);
       
  2431 	NotifyReformatL();
       
  2432 	if (aDiscardFormat==EFViewDontDiscardFullRedraw)
       
  2433 		scrollBy=CTextLayout::EFScrollRedrawWholeScreen;
       
  2434 	TInt horizScrollBy=0;
       
  2435 	if (aHorizontalScroll)
       
  2436 		horizScrollBy=CheckHorizontalScroll(aDocPos);
       
  2437 	if (aDiscardFormat!=EFViewDiscardAllNoRedraw)
       
  2438 		{
       
  2439 		if (0 != scrollBy || 0 != horizScrollBy)
       
  2440 			{
       
  2441 			ScrollDisplayL();
       
  2442 			}
       
  2443 		else
       
  2444 			{
       
  2445 			DrawCursor();
       
  2446 			}
       
  2447 		}
       
  2448 	iCursorPos.UpdateLatentPosition();
       
  2449 	return TPoint(horizScrollBy,scrollBy);
       
  2450 	}
       
  2451 
       
  2452 /** Moves the view vertically and redraws, so that the top of the specified line 
       
  2453 is located flush with the top of the view rectangle.
       
  2454 
       
  2455 Note:
       
  2456 
       
  2457 Line numbering is relative to formatted text only and the first formatted 
       
  2458 line is numbered one.
       
  2459 
       
  2460 @param aLineNo The number of the line to be displayed at the top of the view 
       
  2461 rectangle.
       
  2462 @return The number of pixels the text was scrolled, may be positive or negative. 
       
  2463 A value of CTextLayout::EFScrollRedrawWholeScreen indicates that the entire 
       
  2464 visible area, at least, was scrolled. */
       
  2465 EXPORT_C TPoint CTextView::SetViewLineAtTopL(TInt aLineNo)
       
  2466 	{
       
  2467 	NoMemoryCheckL();
       
  2468 	TTmDocPos pos(iLayout->FirstCharOnLine(aLineNo), ETrue);
       
  2469 	TInt pixel = 0;
       
  2470 	return ViewTopOfLineL(pos,pixel,CTextView::EFViewDontDiscardFormat,EFNoHorizontalScroll);
       
  2471 	}
       
  2472 
       
  2473 /**  Sets the vertical position of the view, so that the line containing
       
  2474 aDocPos is located as close as possible to the vertical window coordinate 
       
  2475 aYPos.
       
  2476 
       
  2477 Which part of the line is set to appear at aYPos (top, baseline, or bottom) 
       
  2478 is controlled by aYPosQualifier, which also specifies whether the visible 
       
  2479 area is to be filled and whether the line should be made fully visible if 
       
  2480 possible.
       
  2481 
       
  2482 @param aDocPos The document position. Must be valid or a panic occurs.
       
  2483 @param aYPos The y coordinate at which to position the character at aDocPos. 
       
  2484 On return, contains the actual vertical window coordinate at which the document
       
  2485 position has been set.
       
  2486 @param aYPosQualifier Controls which part of the line should appear at aYPos.
       
  2487 @param aDiscardFormat If EFViewDiscardAllFormat or EFViewDiscardAllNoRedraw 
       
  2488 the text is reformatted to include aDocPos, otherwise text is formatted 
       
  2489 only as necessary when bringing new lines into the visible area. 
       
  2490 If EFViewDiscardAllNoRedraw, no redraw takes place.
       
  2491 @return The number of pixels scrolled horizontally and vertically. The 
       
  2492 vertical coordinate may have a value of CTextLayout::EFScrollRedrawWholeScreen.
       
  2493 This indicates that the entire visible area, at least, was scrolled, and 
       
  2494 so a full redraw was needed. */
       
  2495 EXPORT_C TPoint CTextView::SetViewL(TInt aDocPos,TInt& aYPos,TViewYPosQualifier aYPosQualifier,
       
  2496 									TDiscard aDiscardFormat,TDoHorizontalScroll aDoHorizontalScroll)
       
  2497 	{
       
  2498 	if (NoMemoryCheckL())
       
  2499 		aDiscardFormat = CTextView::EFViewDontDiscardFullRedraw;
       
  2500 	__ASSERT_ALWAYS(aDocPos >= 0 && aDocPos <= iLayout->DocumentLength(),FormPanic(EFInvalidDocPos));
       
  2501 	aYPos -= TopViewRect();
       
  2502 	TTmDocPos pos(aDocPos,
       
  2503 		aDocPos == iLayout->DocumentLength()? EFalse : ETrue);
       
  2504 	TPoint scroll = ViewL(pos,aYPos,aYPosQualifier,aDiscardFormat,aDoHorizontalScroll);
       
  2505 	aYPos += TopViewRect();
       
  2506 	return scroll;
       
  2507 	}
       
  2508 
       
  2509 /** Finds the base line height of the cursor pos */
       
  2510 TInt CTextView::CalculateBaseLinePos(TTmDocPos& aDocPos)
       
  2511 	{
       
  2512  	TInt y=iGood;			//The height to put the cursor at to recovery from OOM
       
  2513 
       
  2514 	aDocPos = iCursorPos.TmDocPos();
       
  2515 	if (!iNoMemory)
       
  2516 		{
       
  2517 		TPoint xy(0,0);
       
  2518 		if (!iLayout->PosInBand(aDocPos,xy))
       
  2519 			{
       
  2520 			xy.SetXY(0,0);
       
  2521 			TTmPosInfo2 pos_info;
       
  2522 			iLayout->FindXyPos(xy,pos_info);
       
  2523 			aDocPos = pos_info.iDocPos;
       
  2524 			xy = pos_info.iEdge;
       
  2525 			}
       
  2526 		y=xy.iY;
       
  2527 		}
       
  2528 	return y;
       
  2529 	}
       
  2530 
       
  2531 /** Discards and reformats keeping the cursor at the same height on the screen
       
  2532 if possible. Enters OOM state before leaving */
       
  2533 TPoint CTextView::DoHandleGlobalChangeL(TViewYPosQualifier aYPosQualifier,CTextView::TDiscard aDiscard)
       
  2534 	{
       
  2535 	TTmDocPos docPos;
       
  2536 	TInt y = CalculateBaseLinePos(docPos);
       
  2537 	TCursorSelection selection;
       
  2538 	TTmDocPos docLen(iLayout->DocumentLength(),FALSE);
       
  2539 	const TInt visHeight=iDrawTextLayoutContext.iViewRect.Height();
       
  2540 	TRect cursorLine;
       
  2541 
       
  2542 	iLayout->GetLineRect(y,cursorLine);
       
  2543 	switch (aYPosQualifier.iHotSpot)
       
  2544 		{
       
  2545 	case TViewYPosQualifier::EFViewTopOfLine:
       
  2546 		y=cursorLine.iTl.iY;
       
  2547 		break;
       
  2548 	case TViewYPosQualifier::EFViewBottomOfLine:
       
  2549 		y=cursorLine.iBr.iY-1;
       
  2550 	default:;
       
  2551 		}
       
  2552 	if (aYPosQualifier.iFullyVisible==TViewYPosQualifier::EFViewDontForceLineFullyVisible)
       
  2553 		{
       
  2554 		if (y<0)
       
  2555 			{
       
  2556 UseBottom:
       
  2557 			y=(cursorLine.iBr.iY>visHeight ? visHeight:cursorLine.iBr.iY)-1;
       
  2558 			aYPosQualifier.iHotSpot=TViewYPosQualifier::EFViewBottomOfLine;
       
  2559 			}
       
  2560 		else if (y>=visHeight)
       
  2561 			{
       
  2562 			if (cursorLine.iTl.iY<0)
       
  2563 				goto UseBottom;		//else UseTop
       
  2564  			y=cursorLine.iTl.iY;
       
  2565 			aYPosQualifier.iHotSpot=TViewYPosQualifier::EFViewTopOfLine;
       
  2566 			}
       
  2567 		}
       
  2568 	if (docPos > docLen)
       
  2569 		docPos = docLen;
       
  2570 	iCursorPos.GetSelection(selection);	
       
  2571 	if (selection.LowerPos() > docLen.iPos)
       
  2572 		{
       
  2573 		iCursorPos.CancelHighlight();
       
  2574 		iCursorPos.SetDocPos(docLen);
       
  2575 		}
       
  2576 	else if (selection.HigherPos() > docLen.iPos)
       
  2577 		{
       
  2578 		iCursorPos.CancelHighlight();
       
  2579 		iCursorPos.SetDocPos(docLen);
       
  2580 		}
       
  2581 	return ViewL(docPos,y,aYPosQualifier,aDiscard);
       
  2582 	}
       
  2583 
       
  2584 /** Reformats and redraws the view after a global change has been made to the
       
  2585 layout. Examples of global layout changes include changing the format mode, the
       
  2586 wrap width, or the visibility of nonprinting characters.
       
  2587 
       
  2588 Forces any background formatting to complete.
       
  2589 
       
  2590 @param aYPosQualifier Specifies whether the visible area is to be filled and
       
  2591 whether the top line should be made fully visible if possible. */
       
  2592 EXPORT_C void CTextView::HandleGlobalChangeL(TViewYPosQualifier aYPosQualifier)
       
  2593 	{
       
  2594 	CTextView::TDiscard discard=EFViewDiscardAllFormat;
       
  2595 
       
  2596 	if (NoMemoryCheckL())
       
  2597 		discard=EFViewDontDiscardFullRedraw;
       
  2598 	DoHandleGlobalChangeL(aYPosQualifier,discard);
       
  2599 	}
       
  2600 
       
  2601 /** Reformats the view after a global change has been made to the layout, but
       
  2602 without causing a redraw. Examples of global layout changes include changing
       
  2603 the format mode, the wrap width, or the visibility of nonprinting characters.
       
  2604 
       
  2605 Forces any background formatting to complete.
       
  2606 
       
  2607 @param aYPosQualifier Specifies whether the visible area is to be filled and
       
  2608 whether the top line should be made fully visible if possible. */
       
  2609 EXPORT_C void CTextView::HandleGlobalChangeNoRedrawL(TViewYPosQualifier aYPosQualifier)
       
  2610 	{
       
  2611 	CTextView::TDiscard discard=EFViewDiscardAllNoRedraw;
       
  2612 
       
  2613 	if (NoMemoryCheckL())
       
  2614 		return;
       
  2615 	DoHandleGlobalChangeL(aYPosQualifier,discard);
       
  2616 	}
       
  2617 
       
  2618 /** Reformats and redraws to reflect the addition of one or more complete
       
  2619 paragraphs at the end of the text. For instance, it may be used where
       
  2620 information is being found by an active object and appended to a document.
       
  2621 
       
  2622 Note:
       
  2623 
       
  2624 This function should not be used to handle the situation where text is added to
       
  2625 the final paragraph. In this case, use HandleInsertDeleteL() or
       
  2626 HandleCharEditL() instead. */
       
  2627 EXPORT_C void CTextView::HandleAdditionalCharactersAtEndL()
       
  2628 	{
       
  2629 	__ASSERT_DEBUG(!IsFormatting(),FormPanic(EFBackgroundFormatting));
       
  2630 	if (!NoMemoryCheckL())
       
  2631 		{
       
  2632 		TInt from = 0;
       
  2633 		TInt to = 0;
       
  2634 		TRAPD(err,iLayout->HandleAdditionalCharactersAtEndL(from,to));
       
  2635 		if (err)
       
  2636 			NoMemoryL(err);
       
  2637 		NotifyReformatL();
       
  2638 		iDisplay.SetRects(RScreenDisplay::EFClipViewRect);
       
  2639 		DisplayLineRangeL(from,to);
       
  2640 		}
       
  2641 	}
       
  2642 
       
  2643 /** Forces completion of background formatting.
       
  2644 
       
  2645 This is called automatically by all CTextView functions which depend on the
       
  2646 formatting being up to date. */
       
  2647 EXPORT_C void CTextView::FinishBackgroundFormattingL()
       
  2648 	{
       
  2649 	while (NextLineL()) {}
       
  2650 	}
       
  2651 
       
  2652 void CTextView::UpdateHighlightL()
       
  2653 	//
       
  2654 	//Correct the highlight after a cursor movement
       
  2655 	//Enters OOM before leaving
       
  2656 	//
       
  2657 	{
       
  2658 	if (!SelectionVisible())
       
  2659 		return;
       
  2660 
       
  2661 	TCursorSelection oldSelection;
       
  2662 	TCursorSelection newSelection;
       
  2663   	DrawWithPreviousHighlight();
       
  2664 	iCursorPos.GetSelection(oldSelection);
       
  2665 	TBool oldPictureFrame = iCursorPos.IsPictureFrame();
       
  2666 	DrawWithCurrentHighlight();
       
  2667  	iCursorPos.GetSelection(newSelection);
       
  2668 
       
  2669 	if (newSelection.LowerPos()==oldSelection.LowerPos()
       
  2670 		&& iCursorPos.DrawOldPictureFrame() && iCursorPos.DrawNewPictureFrame())
       
  2671 		{
       
  2672  		iCursorPos.DontDrawOldPictureFrame();
       
  2673 		return;
       
  2674 		}
       
  2675 
       
  2676 	iDisplay.SetRects(RScreenDisplay::EFClipTextArea);
       
  2677 	iDisplay.ActivateContext();
       
  2678 	iDisplay.ResetClippingRect();
       
  2679 
       
  2680 	if (iCursorPos.DrawOldPictureFrame())
       
  2681 		{
       
  2682 		RedrawPictureFrameRectL(oldSelection.LowerPos()); // DrawWithCurrentHighlight() was called, so it will hide the old picture frame
       
  2683  		iCursorPos.DontDrawOldPictureFrame();
       
  2684 		}
       
  2685 	if (iCursorPos.DrawHighlight())
       
  2686 		{
       
  2687 		TCursorSelection select;
       
  2688 		iCursorPos.GetOldSelection(select);
       
  2689 		CTextLayout::TRangeChange old;
       
  2690 		if (!oldPictureFrame)
       
  2691 			old.Set(select.iAnchorPos, select.iCursorPos,
       
  2692 				CTextLayout::TRangeChange::EClear);
       
  2693 		iCursorPos.GetSelection(select);
       
  2694 		CTextLayout::TRangeChange now;
       
  2695 		if (!iCursorPos.IsNewPictureFrame())
       
  2696 			now.Set(select.iAnchorPos, select.iCursorPos,
       
  2697 				CTextLayout::TRangeChange::ESet);
       
  2698 		CTextLayout::TRangeChange original;
       
  2699 		original=now;
       
  2700 		now.OptimizeWith(old);
       
  2701 		iDisplay.SetRects(RScreenDisplay::EFClipExtendedTextArea);
       
  2702 		iDisplay.ResetClippingRect();
       
  2703 
       
  2704 		if (now.IsJoinedTo(old))
       
  2705 			{
       
  2706 			now.Join(old);
       
  2707 			HighlightUsingExtensions(now,original);
       
  2708 			}
       
  2709 		else
       
  2710 			{
       
  2711 			HighlightUsingExtensions(old,original);
       
  2712 			HighlightUsingExtensions(now,original);
       
  2713 			}
       
  2714 		}
       
  2715 	if (iCursorPos.DrawNewPictureFrame())
       
  2716 		{
       
  2717  		RedrawPictureFrameRectL(newSelection.LowerPos()); // DrawWithCurrentHighlight() was called, so it will draw the new picture frame
       
  2718 		}
       
  2719 	iDisplay.DeactivateContext();
       
  2720 	}
       
  2721 
       
  2722 void CTextView::HighlightUsingExtensions(CTextLayout::TRangeChange aOptimizedRange, CTextLayout::TRangeChange aOriginalRange)
       
  2723 	{
       
  2724 	TInt visPos;
       
  2725 	TInt visLen=iLayout->PosRangeInBand(visPos);
       
  2726 
       
  2727 	__ASSERT_DEBUG(visLen>=0,FormPanic(EFNoMemory));  //  Shouldn't be in OOM here.
       
  2728 	__ASSERT_DEBUG(SelectionVisible(),FormPanic(EFSelectionNotVisible));
       
  2729 
       
  2730 	if (!aOptimizedRange.Clip(visPos, visPos + visLen))
       
  2731 		return;
       
  2732 	(void)aOriginalRange.Clip(visPos, visPos + visLen);
       
  2733 
       
  2734 	// Added to reduce the area drawn to allow layout to work consistently
       
  2735 	TRect drawArea = iDisplay.ClippingRect();
       
  2736 	if (iReducedDrawingAreaRect.Height())
       
  2737 		drawArea.Intersection(iReducedDrawingAreaRect);
       
  2738 	iLayout->HighlightUsingExtensions(aOptimizedRange,aOriginalRange,drawArea, &iDrawTextLayoutContext);
       
  2739 	}
       
  2740 
       
  2741 
       
  2742 /** Gets called after the cursor moved to a picture, creates the picture frame if it has not been created
       
  2743 	and updates its state.
       
  2744 */
       
  2745 void CTextView::UpdatePictureFrameL()
       
  2746 	{
       
  2747 	TCursorSelection selection;
       
  2748 	iCursorPos.GetSelection(selection);
       
  2749 
       
  2750 	TInt pos = selection.LowerPos();
       
  2751 	TRect rect;
       
  2752 	
       
  2753 	TInt err = FALSE;
       
  2754 	TBool canScaleOrCrop = FALSE;
       
  2755 
       
  2756 	if (!iPictureFrame)
       
  2757 		{
       
  2758 		TRAP(err,iPictureFrame=new(ELeave) TFrameOverlay());
       
  2759 		}
       
  2760 
       
  2761 	TBool isPicture=EFalse;
       
  2762 	if (!err)
       
  2763 		{
       
  2764 		TRAP(err,isPicture=iLayout->PictureRectangleL(pos,rect,&canScaleOrCrop))
       
  2765 		if(!isPicture)
       
  2766 			__ASSERT_DEBUG(isPicture,FormPanic(EFNoPictureFrame));
       
  2767 		}
       
  2768 	if (err)
       
  2769 		NoMemoryL(err);
       
  2770 	
       
  2771 	iPictureFrame->SetFlags(TFrameOverlay::EFrameOverlayFlagBlobsInternal);
       
  2772 	if (canScaleOrCrop)
       
  2773 		{
       
  2774 		iPictureFrame->SetVisibleBlobWidthInPixels(EFFrameVisibleBlobWidth);
       
  2775 		iPictureFrame->SetActiveBlobWidthInPixels(EFFrameActiveBlobWidth);
       
  2776 		iPictureFrame->ClearFlags(TFrameOverlay::EFrameOverlayFlagShowBorder);
       
  2777 		}
       
  2778 	else
       
  2779 		{
       
  2780 		iPictureFrame->SetVisibleBlobWidthInPixels(0);
       
  2781 		iPictureFrame->SetActiveBlobWidthInPixels(0);
       
  2782 		iPictureFrame->SetFlags(TFrameOverlay::EFrameOverlayFlagShowBorder);
       
  2783 		}
       
  2784 	iDrawTextLayoutContext.TextToWindow(rect);
       
  2785 	iPictureFrame->SetRect(rect);
       
  2786 
       
  2787 	}
       
  2788 
       
  2789 
       
  2790 
       
  2791 /** Shows or hides the picture frame at specified location, redrawing the picture frame rect.
       
  2792 It assumes that: 1)iCursorPos.iFlags has been correctly updated to specify the visibility of
       
  2793 				   the picture frame.
       
  2794 				 2)the picture frame object has been created and initialised.
       
  2795 				 3)Gc has already been activated.
       
  2796 Enters OOM before leaving.
       
  2797 */
       
  2798 void CTextView::RedrawPictureFrameRectL(TInt aPos)
       
  2799 	{
       
  2800 	TRect drawRect;
       
  2801 	if(iLayout->PictureRectangleL(aPos,drawRect))
       
  2802 		{
       
  2803 		iDrawTextLayoutContext.TextToWindow(drawRect);
       
  2804 		drawRect.Intersection(iDrawTextLayoutContext.iViewRect);
       
  2805 		TBool callBeginEndRedraw = iDrawTextLayoutContext.UseWindowGc() && ! iLayout->BeginRedrawCalled();
       
  2806 		if (callBeginEndRedraw)
       
  2807 			{
       
  2808 			iLayout->BeginRedraw(drawRect);
       
  2809 			}
       
  2810 		// since drawRect contains the picture, it calls DrawPictureFrameL()
       
  2811 		TRAPD(err,DrawTextSupportL(drawRect,NULL));
       
  2812 		if (callBeginEndRedraw)
       
  2813 			{
       
  2814 			iLayout->EndRedraw();
       
  2815 			}
       
  2816 
       
  2817 		if (err)
       
  2818 			{
       
  2819 			NoMemoryL(err);		//Gc's are deleted
       
  2820 			}
       
  2821 		}
       
  2822 	}
       
  2823 	
       
  2824 
       
  2825  
       
  2826 /*
       
  2827 Draws a focus frame around a picture. 
       
  2828 It assumes that:  1) cursor is sitting on a picture frame (iCursorPos.IsPictureFrame==ETrue)	
       
  2829 				  2) the picture frame object has been created and initialised
       
  2830  				  3) BeginRedraw() has already been called
       
  2831 					 and the background already has been drawn. So we can use the EDrawModePEN 
       
  2832 					 without problems. 
       
  2833 */
       
  2834 void CTextView::DrawPictureFrameL(TRect& aClipRect)
       
  2835 	{
       
  2836 	__ASSERT_DEBUG(iCursorPos.IsPictureFrame(),FormPanic(EFNoPictureFrame));
       
  2837 	TCursorSelection selection;
       
  2838 	iCursorPos.GetSelection(selection);
       
  2839 	if(iLayout->PosIsFormatted(selection.LowerPos()))
       
  2840 		{
       
  2841 		aClipRect.Intersection(iDrawTextLayoutContext.TextArea());
       
  2842 		iDrawTextLayoutContext.PrimaryGc()->SetClippingRect(aClipRect);
       
  2843 		TRect rect;
       
  2844 		TInt pos = selection.LowerPos();
       
  2845 		rect = iPictureFrame->RefRect();
       
  2846 		TRect lineRect=iLayout->GetLineRectL(pos, pos);
       
  2847 		iDrawTextLayoutContext.TextToWindow(lineRect);
       
  2848 		lineRect.iTl.iX=iDrawTextLayoutContext.TextArea().iTl.iX;
       
  2849 		lineRect.iBr.iX=iDrawTextLayoutContext.TextArea().iBr.iX;
       
  2850 		lineRect.Intersection(aClipRect);
       
  2851 		if (rect.iTl.iY<iDrawTextLayoutContext.iViewRect.iBr.iY-iHeightNotDrawn)
       
  2852 			{
       
  2853 			iDisplay.DrawPictureFrame(iPictureFrame, lineRect);
       
  2854 			}
       
  2855 		}
       
  2856 	}
       
  2857 
       
  2858 /** Enters the OOM state. */
       
  2859 void CTextView::NoMemoryL(TInt aError)
       
  2860 	{
       
  2861 	__ASSERT_DEBUG(iNoMemory!=EFOutOfMemory,FormPanic(EFNoMemory));
       
  2862 	iLayout->DiscardFormat();
       
  2863 	if (iNoMemory==EFMemoryOK)
       
  2864 		{
       
  2865 		TTmPosInfo2 pos_info;
       
  2866 		if (iLayout->FindDocPos(iCursorPos.TmDocPos(),pos_info))
       
  2867 			iGood = pos_info.iEdge.iY;
       
  2868 		if (iGood < 0 || iGood >= ViewRect().Height())
       
  2869 			iGood = 0;
       
  2870 		}
       
  2871 	iNoMemory=EFOutOfMemory;
       
  2872 	DrawWithCurrentHighlight();
       
  2873 	DestroyWindowServerObjects();
       
  2874 	User::Leave(aError);
       
  2875 	}
       
  2876 
       
  2877 void CTextView::DestroyWindowServerObjects()
       
  2878 	{
       
  2879 	iDisplay.Close();
       
  2880 	}
       
  2881 
       
  2882 /** Return True if successfully recovered from being out of memory Enters OOM
       
  2883 before leaving */
       
  2884 TBool CTextView::NoMemoryCheckL()
       
  2885 	{
       
  2886 	TBool recovered=iNoMemory;
       
  2887 
       
  2888 	__ASSERT_DEBUG(iNoMemory!=EFRecovering,FormPanic(EFRecoverNoMemory));
       
  2889 	if (iNoMemory)
       
  2890 		RecoverNoMemoryL();
       
  2891 	return recovered;
       
  2892 	}
       
  2893 
       
  2894 /** Make an attempt to recover from no system memory
       
  2895 Enters OOM before leaving */
       
  2896 void CTextView::RecoverNoMemoryL()
       
  2897 	{
       
  2898 
       
  2899 	__ASSERT_DEBUG(iNoMemory==EFOutOfMemory,FormPanic(EFRecoverNoMemory));
       
  2900 	iNoMemory=EFRecovering;
       
  2901 	RecreateWindowServerObjectsL();
       
  2902 	TTmDocPos end(iLayout->DocumentLength(), EFalse);
       
  2903 	TTmDocPos pos = iCursorPos.TmDocPos();
       
  2904 	if (pos.iPos > end.iPos)
       
  2905 		iCursorPos.SetDocPos(end);
       
  2906 	ViewL(iCursorPos.TmDocPos(),iGood);
       
  2907 	__ASSERT_DEBUG(iNoMemory==EFRecovering,FormPanic(EFNoMemory));
       
  2908 	iNoMemory=EFMemoryOK;
       
  2909 	iGood=0;
       
  2910 	if (iLayout->FormattedHeightInPixels() < iLayout->BandHeight() && iLayout->FirstDocPosFullyInBand()>0)
       
  2911 		{
       
  2912 		TInt scroll=iLayout->BandHeight()-iLayout->YBottomLastFormattedLine();
       
  2913 		ScrollDisplayPixelsL(scroll);
       
  2914 		}
       
  2915 	}
       
  2916 
       
  2917 void CTextView::RecreateWindowServerObjectsL()
       
  2918 	{
       
  2919 	TRAPD(err,iDisplay.CreateContextL());
       
  2920 	if (err)
       
  2921 		NoMemoryL(err);
       
  2922 	}
       
  2923 
       
  2924 /** Sets the number of pixels by which a horizontal scroll jump will cause the
       
  2925 view to scroll. To carry out a horizontal scroll, use ScrollDisplayL().
       
  2926 
       
  2927 @param aScrollJump The number of pixels by which a horizontal scroll jump will
       
  2928 cause the view to scroll. Must be a positive value or a panic occurs. */
       
  2929 EXPORT_C void CTextView::SetHorizontalScrollJump(TInt aScrollJump)
       
  2930 	{
       
  2931 	__ASSERT_ALWAYS(aScrollJump>=0,FormPanic(EFInvalidJumpValue));
       
  2932 	__ASSERT_DEBUG(aScrollJump<EFUnreasonablyLargeHorizontalScrollJump
       
  2933 																	,FormPanic(EFInvalidJumpValue));
       
  2934 	iHorizontalScrollJump=aScrollJump;
       
  2935 	}
       
  2936 
       
  2937 /** Sets the left text margin width in pixels.
       
  2938 
       
  2939 The left text margin width is the distance between the text and the left edge
       
  2940 of the page. Increasing the left text margin width causes text to move
       
  2941 leftwards and decreasing the left text margin width causes text to move
       
  2942 rightwards.
       
  2943 
       
  2944 Does not redraw.
       
  2945 
       
  2946 @param aLeftMargin The left text margin width in pixels. */
       
  2947 EXPORT_C void CTextView::SetLeftTextMargin(TInt aLeftMargin)
       
  2948 	{
       
  2949 	iDrawTextLayoutContext.iTextStartX=-aLeftMargin;
       
  2950 	}
       
  2951 
       
  2952 /** Gets the left text margin width in pixels.
       
  2953 
       
  2954 @return The left text margin width in pixels. */
       
  2955 EXPORT_C TInt CTextView::LeftTextMargin() const
       
  2956 	{
       
  2957 	return -iDrawTextLayoutContext.iTextStartX;
       
  2958 	}
       
  2959 
       
  2960 /** Sets the pending horizontal text cursor position. This is the horizontal
       
  2961 coordinate to which the text cursor is moved after a scroll up or down by a
       
  2962 line or a page.
       
  2963 
       
  2964 @param aLatentX The horizontal coordinate to which the text cursor should be
       
  2965 moved after a line or page scroll. */
       
  2966 EXPORT_C void CTextView::SetLatentXPosition(TInt aLatentX)
       
  2967 	{
       
  2968 	aLatentX-=iDrawTextLayoutContext.TopLeftText().iX;
       
  2969 	iCursorPos.UpdateLatentX(aLatentX);
       
  2970 	}
       
  2971 
       
  2972 /** Sets the horizontal extent of the view rectangle to fill with paragraph
       
  2973 fill colour (CParaFormat::iFillColor).
       
  2974 
       
  2975 Does not redraw.
       
  2976 
       
  2977 @param aFillTextOnly If true, the region filled with paragraph fill colour is
       
  2978 the area within the paragraph's bounding rectangle only (see ParagraphRectL()).
       
  2979 If false, the filled region includes the left text margin, if one has been set.
       
  2980 By default, false. */
       
  2981 EXPORT_C void CTextView::SetParagraphFillTextOnly(TBool aFillTextOnly)
       
  2982 	{
       
  2983 	iDrawTextLayoutContext.SetParagraphFillTextOnly(aFillTextOnly);
       
  2984 	}
       
  2985 
       
  2986 /** Sets the text cursor's type and weight and redraws it. If the cursor's
       
  2987 placement is vertical (ECursorVertical), the weight is the width of the cursor.
       
  2988 If the placement is horizontal, the weight is the height of the cursor.
       
  2989 
       
  2990 @param aType The text cursor type.
       
  2991 @param aWidth The weight in pixels of the text cursor. Specify zero (the
       
  2992 default) to leave the current weight unchanged. */
       
  2993 EXPORT_C void CTextView::SetCursorWidthTypeL(TTextCursor::EType aType,TInt aWidth/*=0*/)
       
  2994 	{
       
  2995 	iCursor.SetType(aType);
       
  2996 	iCursor.SetWeight(aWidth);
       
  2997 	}
       
  2998 
       
  2999 /** Sets the text cursor's placement (its shape and position relative to the
       
  3000 insertion position) and redraws it.
       
  3001 
       
  3002 @param aPlacement The text cursor's placement */
       
  3003 EXPORT_C void CTextView::SetCursorPlacement(TTmCursorPlacement aPlacement)
       
  3004 	{
       
  3005 	iCursor.SetPlacement(aPlacement);
       
  3006 	}
       
  3007 
       
  3008 /** Sets the weight of the text cursor and redraws it.
       
  3009 
       
  3010 If the cursor's placement is vertical (ECursorVertical), the weight is the
       
  3011 width of the cursor. If the placement is horizontal, the weight is the height
       
  3012 of the cursor. Has no effect if the weight value specified is zero or less.
       
  3013 
       
  3014 @param aWeight The weight in pixels of the text cursor. */
       
  3015 EXPORT_C void CTextView::SetCursorWeight(TInt aWeight)
       
  3016 	{
       
  3017 	iCursor.SetWeight(aWeight);
       
  3018 	}
       
  3019 
       
  3020  
       
  3021 EXPORT_C void CTextView::SetCursorFlash(TBool aEnabled)
       
  3022 /** Sets the flashing state of the text cursor and redraws it.
       
  3023 
       
  3024 @param aEnabled ETrue for a flashing cursor, EFalse for a non-flashing cursor.
       
  3025 */
       
  3026 	{
       
  3027 	iCursor.SetFlash(aEnabled);
       
  3028 	}
       
  3029 
       
  3030 /** Sets the text cursor's colour and redraws it. The cursor is drawn using an
       
  3031 Exclusive OR draw mode which ensures that the cursor's colour is different from
       
  3032 the background colour.
       
  3033 
       
  3034 @param aColor The text cursor's colour. */
       
  3035 EXPORT_C void CTextView::SetCursorXorColor(TRgb aColor)
       
  3036 	{
       
  3037 	iCursor.SetXorColor(aColor);
       
  3038 	}
       
  3039 
       
  3040 /** Sets the height and ascent of the text cursor to be the same as an adjacent
       
  3041 character and redraws it. By default, the values are set to be based on the
       
  3042 preceding character.
       
  3043 
       
  3044 @param aBasedOn EFCharacterBefore to base the height and ascent of the text
       
  3045 cursor on the preceding character. EFCharacterAfter to base them on the
       
  3046 following character. */
       
  3047 EXPORT_C void CTextView::MatchCursorHeightToAdjacentChar(TBeforeAfter /*aBasedOn*/)
       
  3048 	{
       
  3049 	iCursor.MatchCursorHeightToAdjacentChar();
       
  3050 	}
       
  3051 
       
  3052 /** Overrides the text colour, so that when redrawn, all text has the colour
       
  3053 specified, rather than the colour which is set in the text object. When text is
       
  3054 in this overridden state, no highlighting is visible. To return the text colour
       
  3055 to its original state, call this function again with an argument of NULL. This
       
  3056 also has the effect that if selection visibility is set, any highlighting will
       
  3057 be made visible again.
       
  3058 
       
  3059 Does not do a redraw.
       
  3060 
       
  3061 @param aOverrideColor If not NULL, overrides the text colour. */
       
  3062 EXPORT_C void CTextView::SetTextColorOverride(const TRgb* aOverrideColor)
       
  3063 	{
       
  3064 	iDrawTextLayoutContext.SetTextColorOverride(aOverrideColor);
       
  3065 	}
       
  3066 
       
  3067 /** Sets the background colour for the view rectangle.
       
  3068 
       
  3069 Does not redraw.
       
  3070 
       
  3071 @param aColor The background colour. */
       
  3072 EXPORT_C void CTextView::SetBackgroundColor(TRgb aColor)
       
  3073 	{
       
  3074 	iDrawTextLayoutContext.iBackgroundColor=aColor;
       
  3075 	}
       
  3076 
       
  3077 /** Gets the rectangle in which the text is displayed.
       
  3078 
       
  3079 @return The view rectangle. */
       
  3080 EXPORT_C const TRect& CTextView::ViewRect() const
       
  3081 	{
       
  3082 
       
  3083 	return iDrawTextLayoutContext.iViewRect;
       
  3084 	}
       
  3085 
       
  3086 /** Gets the number of pixels by which a horizontal scroll jump will cause the 
       
  3087 view to scroll. On construction, the default horizontal scroll jump value 
       
  3088 is set to 20 pixels.
       
  3089 
       
  3090 @return The number of pixels by which a horizontal scroll jump will cause 
       
  3091 the view to scroll. */
       
  3092 EXPORT_C TInt CTextView::HorizontalScrollJump() const
       
  3093 	{
       
  3094 
       
  3095 	return iHorizontalScrollJump;
       
  3096 	}
       
  3097 
       
  3098 /** Starts the Idle Object if not in the middle of drawing para borders. */
       
  3099 void CTextView::StartIdleObject()
       
  3100 	{
       
  3101 
       
  3102 	if (!iWrap->IsActive())
       
  3103 		iWrap->Start(TCallBack(CTextView::IdleL,this));
       
  3104 	}
       
  3105 
       
  3106 class RDrawTextSupport
       
  3107 	{
       
  3108 public:
       
  3109 	/** Constructor. Ownership of aBitmap is passed.
       
  3110 	*/
       
  3111 	RDrawTextSupport(RScreenDisplay* aScreenDisplay,
       
  3112 		TDrawTextLayoutContext* aLayoutContext,
       
  3113 		CFbsBitmap* aBitmap)
       
  3114 		: iScreenGc(0), iScreenDisplay(aScreenDisplay),
       
  3115 		iLayoutContext(aLayoutContext),
       
  3116 		iDevice(0), iGc(0), iBitmap(aBitmap)
       
  3117 		{
       
  3118 		iLayoutContextDrawMode = aLayoutContext->DrawMode();
       
  3119 		iScreenGc = iScreenDisplay->BitmapContext();
       
  3120 		}
       
  3121 	void ConstructL(CBitmapContext* aOffScreenContext)
       
  3122 		{
       
  3123 		if (aOffScreenContext)
       
  3124 			{
       
  3125 			iScreenDisplay->SetBitmapContext(aOffScreenContext);
       
  3126 			}
       
  3127 		else
       
  3128 			{
       
  3129 			// Create the device and graphics context.
       
  3130 			iDevice = CFbsBitmapDevice::NewL(iBitmap);
       
  3131 			CFbsBitGc* bitGc;
       
  3132 			User::LeaveIfError(iDevice->CreateContext(bitGc));
       
  3133 			iGc = bitGc;
       
  3134 			iScreenDisplay->SetBitmapContext(iGc);
       
  3135 
       
  3136 			// Set the twips size of the bitmap to match the screen so that
       
  3137 			// background bitmaps are blitted at the right size.
       
  3138 			iBitmap->SetSizeInTwips(iScreenGc->Device());
       
  3139 			}
       
  3140 		iLayoutContext->SetBitmapGc(iScreenDisplay->BitmapContext());
       
  3141 		}
       
  3142 	void Close()
       
  3143 		{
       
  3144 		iScreenDisplay->SetBitmapContext(iScreenGc);
       
  3145 		iLayoutContext->SetGc(iScreenGc);
       
  3146 		iLayoutContext->SetDrawMode(iLayoutContextDrawMode);
       
  3147 		delete iGc; iGc = NULL;
       
  3148 		delete iDevice; iDevice = NULL;
       
  3149 		delete iBitmap; iBitmap = NULL;
       
  3150 		}
       
  3151 private:
       
  3152 	CBitmapContext* iScreenGc;
       
  3153 	RScreenDisplay* iScreenDisplay;
       
  3154 	TDrawTextLayoutContext* iLayoutContext;
       
  3155 	CFbsBitmapDevice* iDevice;
       
  3156 	CBitmapContext* iGc;
       
  3157 	CFbsBitmap* iBitmap;
       
  3158 	TUint iLayoutContextDrawMode;
       
  3159 	};
       
  3160 
       
  3161 /**
       
  3162 Draws the text. Depending on the opaque mode ("iDrawOpaque" value) and graphics context
       
  3163 type, the method calls either DoDrawTextSupportL() or DoDrawTextSupportOpaqueL().
       
  3164 The additional graphics context type check has to be done, because currently only 
       
  3165 CWindowGc graphics context implementation supports opaque drawing.
       
  3166 
       
  3167 Does not enter OOM state.
       
  3168 */
       
  3169 void CTextView::DrawTextSupportL(const TRect& aScreenDrawRect,
       
  3170 								 const TCursorSelection* aHighlight)
       
  3171     {
       
  3172 	// Anything to do?
       
  3173 	if( aScreenDrawRect.IsEmpty()||!(iFlags & EFTextVisible) )
       
  3174 		return;
       
  3175 	    
       
  3176 	if(iDisplay.Window() && iDrawOpaque
       
  3177 		&& !iOffScreenContext)
       
  3178 		{
       
  3179 		// It is a CWindowGc and opaque drawing mode
       
  3180 		iLayout->SetOpaqueLC();
       
  3181 		DoDrawTextSupportOpaqueL(aScreenDrawRect, aHighlight);
       
  3182 		CleanupStack::PopAndDestroy();//iLayout->SetOpaqueLC() operation
       
  3183 		}
       
  3184 	else
       
  3185 		{
       
  3186 		DoDrawTextSupportL(aScreenDrawRect, aHighlight);
       
  3187 		}
       
  3188 	}
       
  3189 
       
  3190 
       
  3191 /**
       
  3192 Draws the text, using an offscreen bitmap to avoid flicker if possible.
       
  3193 All text drawing is done by this function except in printing.
       
  3194 
       
  3195 Does not enter OOM state.
       
  3196 */
       
  3197 
       
  3198 void CTextView::DoDrawTextSupportL(const TRect& aScreenDrawRect,
       
  3199 								   const TCursorSelection* aHighlight)
       
  3200 	{
       
  3201 	// extend the screen draw rect for any extended highlights
       
  3202 	TRect screenDrawRect(aScreenDrawRect);
       
  3203 	iLayout->HighlightExtensions().ExtendRect(screenDrawRect);
       
  3204 	screenDrawRect.Intersection(iDisplay.ClippingRect());
       
  3205 
       
  3206 	
       
  3207 	//	Create an offscreen bitmap. Although Window server bitmaps are quicker to bilt,
       
  3208 	//	but using it need introduce static_cast, which may make code fragile. So we just 
       
  3209 	//	use CFbsBitmaps.
       
  3210 	
       
  3211 	CFbsBitmap* bitmap = NULL;
       
  3212 	int error = 0;
       
  3213 	if ((iFlags & EFFlickerFreeRedraw) && !iOffScreenContext)
       
  3214 		{
       
  3215 		TDisplayMode displayMode = iDisplay.Window()?
       
  3216 			iDisplay.Window()->DisplayMode()
       
  3217 			: iDisplay.BitmapDevice()->DisplayMode();
       
  3218 
       
  3219 		// We are going to make the bitmap size the size from (0,0) on
       
  3220 		// the screen to the bottom right of the drawing area.
       
  3221 		// This is because if we only make it exactly the size we need,
       
  3222 		// the DrawBackground code does not know how to align the bitmap
       
  3223 		// in some cases:
       
  3224 		// 1) where the bitmap doesn't scroll with the text
       
  3225 		// 2) where the bitmap is to be stretched in a way that depends
       
  3226 		// on the co-ordinates it is being stretched to.
       
  3227 		TSize bitmapSize(screenDrawRect.iBr.iX, screenDrawRect.iBr.iY);
       
  3228 		bitmap = new CFbsBitmap;
       
  3229 		if (bitmap)
       
  3230 			{
       
  3231 			error = bitmap->Create(bitmapSize, displayMode);
       
  3232 			}
       
  3233 		}
       
  3234 
       
  3235 	TBool isDrawingOnABitmap = NULL != bitmap || NULL != iOffScreenContext;
       
  3236 
       
  3237 	CBitmapContext* screen_gc = iDisplay.BitmapContext();
       
  3238 	RDrawTextSupport support(&iDisplay, &iDrawTextLayoutContext, bitmap);
       
  3239 	CleanupClosePushL(support);
       
  3240 	if (error)
       
  3241 		User::Leave(error);
       
  3242 
       
  3243 	// If we are flicker-free drawing (and there was enough memory for it) or
       
  3244 	// drawing to an off screen bitmap for some other reason, set up
       
  3245 	// iDrawTextLayoutContext to temporarily point to the appropriate place
       
  3246 	if (isDrawingOnABitmap)
       
  3247 		{
       
  3248 		support.ConstructL(iOffScreenContext);
       
  3249 		}
       
  3250 
       
  3251 	// Draw the text.
       
  3252 	iLayout->DrawL(screenDrawRect, &iDrawTextLayoutContext, aHighlight);
       
  3253 
       
  3254 	// Draw picture frame if applicable
       
  3255 	TBool pictureFrame = SelectionVisible() && iCursorPos.IsPictureFrame();
       
  3256 	if (pictureFrame)
       
  3257 		{
       
  3258 		DrawPictureFrameL(screenDrawRect);
       
  3259 		}
       
  3260 
       
  3261 	if (NULL != bitmap)
       
  3262 		{
       
  3263 		if (NULL == iOffScreenContext)
       
  3264 			{
       
  3265 			iLayout->BeginRedraw(screenDrawRect);
       
  3266 			}	
       
  3267 
       
  3268 		// Copy the drawn rectangle from the offscreen bitmap (if present)
       
  3269 		// to the screen.
       
  3270 		screen_gc->BitBlt(screenDrawRect.iTl, bitmap, screenDrawRect);
       
  3271 
       
  3272 		if (NULL == iOffScreenContext)
       
  3273 			{
       
  3274 			iLayout->EndRedraw();
       
  3275 			}
       
  3276 		}
       
  3277 
       
  3278 	if (pictureFrame)
       
  3279 		{
       
  3280 		DrawCursor(TCursor::EFTextCursor);
       
  3281 		}
       
  3282 
       
  3283 	// Puts iDrawTextLayoutContext back to point to the real screen
       
  3284 	CleanupStack::PopAndDestroy(&support);
       
  3285 	}
       
  3286 
       
  3287 /*
       
  3288 Draws the text, when opaque drawing mode is "ON" and the used graphics context type is
       
  3289 CWindowGc.
       
  3290 */
       
  3291 void CTextView::DoDrawTextSupportOpaqueL(const TRect& aScreenDrawRect,
       
  3292 										 const TCursorSelection* aHighlight)
       
  3293 	{
       
  3294 	// extend the screen draw rect for any extended highlights
       
  3295 	TRect screenDrawRect(aScreenDrawRect);
       
  3296 	iLayout->HighlightExtensions().ExtendRect(screenDrawRect);
       
  3297 
       
  3298 	iLayout->BeginRedraw(screenDrawRect);
       
  3299 	iLayout->DrawL(screenDrawRect, &iDrawTextLayoutContext, aHighlight);
       
  3300 
       
  3301 	// Draw picture frame if applicable
       
  3302 	TBool pictureFrame = SelectionVisible() && iCursorPos.IsPictureFrame();
       
  3303 	if (pictureFrame)
       
  3304 		{
       
  3305 		DrawPictureFrameL(screenDrawRect);
       
  3306 		DrawCursor(TCursor::EFTextCursor);
       
  3307 		}
       
  3308 
       
  3309 	iLayout->EndRedraw();
       
  3310 	}
       
  3311 
       
  3312 /** Draws text from aFrom to aTo.
       
  3313 
       
  3314 Enters OOM state before leaving.
       
  3315 @param aFrom Top screen Y co-ordinate to draw (inclusive of aFrom)
       
  3316 @param aTo Bottom screen Y co-ordinate to draw (exclusive of aTo)
       
  3317 */
       
  3318 void CTextView::DisplayLineRangeL(TInt aFrom,TInt aTo)
       
  3319 	{
       
  3320 	TCursorSelection* highlight=NULL;
       
  3321 	TCursorSelection selection;
       
  3322 
       
  3323 	iCursorPos.GetSelection(selection);
       
  3324 	TBool pictureFrame=iCursorPos.IsPictureFrame();
       
  3325 
       
  3326 	TRect drawRect=iDisplay.ClippingRect();
       
  3327 
       
  3328 	drawRect.iTl.iY=Max(aFrom+ViewRect().iTl.iY,drawRect.iTl.iY);
       
  3329 	drawRect.iBr.iY=Min(aTo+ViewRect().iTl.iY,drawRect.iBr.iY);
       
  3330 
       
  3331 	if (SelectionVisible() && selection.Length()>0 && !pictureFrame)
       
  3332 		highlight=&selection;
       
  3333 
       
  3334 	iDisplay.ActivateContext(iDrawTextLayoutContext.PrimaryGc());
       
  3335 	TRAPD(err,DrawTextSupportL(drawRect,highlight));
       
  3336 	if (err)
       
  3337 		NoMemoryL(err);		//Gc's are deleted
       
  3338 	
       
  3339 	iDisplay.DeactivateContext(iDrawTextLayoutContext.PrimaryGc());
       
  3340 	iHeightNotDrawn=0;
       
  3341 	}
       
  3342 
       
  3343 EXPORT_C const TRect& CTextView::AlteredViewRect() const
       
  3344 	{
       
  3345 	return iReducedDrawingAreaRect;
       
  3346 	}
       
  3347 
       
  3348 
       
  3349 EXPORT_C void CTextView::SetCursorExtensions(TInt aFirstExtension, TInt aSecondExtension)
       
  3350 	{
       
  3351 	iCursor.SetExtensions(aFirstExtension,aSecondExtension);
       
  3352 	}
       
  3353 
       
  3354 TBool CTextView::ExtendedHighlightExists() const
       
  3355 	{
       
  3356 	ASSERT(iLayout);
       
  3357 	if (SelectionVisible() && iLayout->HighlightExtensions().Extends())
       
  3358 		{
       
  3359 		TCursorSelection selection;
       
  3360 		iCursorPos.GetSelection(selection);
       
  3361 		if (selection.Length()>0)
       
  3362 			return ETrue;
       
  3363 		}
       
  3364 	return EFalse;
       
  3365 	}
       
  3366 
       
  3367 
       
  3368 // When scrolling, we also want to include any highlight extensions within the scroll area.
       
  3369 void CTextView::AdjustRectForScrolling(TRect &aRect, TInt aScrollY, TInt aScrollX) const
       
  3370 	{
       
  3371 	ASSERT(iLayout);
       
  3372 	const TTmHighlightExtensions& extensions=iLayout->HighlightExtensions();
       
  3373 	ASSERT(extensions.Extends() && SelectionVisible());
       
  3374 
       
  3375 	if (aScrollY==0)
       
  3376 		{
       
  3377 		// scrolling horizontally, so we include top and bottom extensions
       
  3378 		if (extensions.TopExtension()>0)
       
  3379 			aRect.iTl.iY-=extensions.TopExtension();
       
  3380 		if (extensions.BottomExtension()>0)
       
  3381 			aRect.iBr.iY+=extensions.BottomExtension();
       
  3382 		}
       
  3383 	if (aScrollX==0)
       
  3384 		{
       
  3385 		// scrolling vertically, so we include left and right extensions
       
  3386 		if (extensions.LeftExtension()>0)
       
  3387 			aRect.iTl.iX-=extensions.LeftExtension();
       
  3388 		if (extensions.RightExtension()>0)
       
  3389 			aRect.iBr.iX+=extensions.RightExtension();
       
  3390 		}
       
  3391 	}
       
  3392 
       
  3393 
       
  3394 
       
  3395 /**
       
  3396 Returns whether the two hints passed in are the opposites of each other.
       
  3397 @param aHint1 First hint.
       
  3398 @param aHint2 Second hint.
       
  3399 @return ETrue if the two hints are the reversals of each other.
       
  3400 @internalComponent
       
  3401 */
       
  3402 TBool PositioningHintsReversed(TCursorPosition::TPosHint aHint1,
       
  3403 	TCursorPosition::TPosHint aHint2)
       
  3404 	{
       
  3405 	if (aHint1 == TCursorPosition::EInsertStrongL2R
       
  3406 		&& aHint2 == TCursorPosition::EInsertStrongR2L)
       
  3407 		return ETrue;
       
  3408 	if (aHint1 == TCursorPosition::EInsertStrongR2L
       
  3409 		&& aHint2 == TCursorPosition::EInsertStrongL2R)
       
  3410 		return ETrue;
       
  3411 	return EFalse;
       
  3412 	}
       
  3413 
       
  3414 /**
       
  3415 This method allows clients of CTextView to provided a cursor positioning hint
       
  3416 (as defined in TCursorPosition::TPosHint) to the Cursor Navigation
       
  3417 Policy object currently in use in this view.
       
  3418 
       
  3419 This information can be used by the CNP object to resolve problems such as
       
  3420 visual cursor positioning ambiguity in bidirectional text.
       
  3421 @param aHint
       
  3422 	Cursor position hint provided by client of CTextView.
       
  3423 @post
       
  3424 	The hint is stored for use in subsequent cursor movement.
       
  3425 */
       
  3426 EXPORT_C void CTextView::SetCursorPositioningHintL(
       
  3427 	TCursorPosition::TPosHint aHint)
       
  3428 	{
       
  3429 	if (!PositioningHintsReversed(aHint, iCursorPos.PositioningHint()))
       
  3430 		{
       
  3431 		iCursorPos.SetPositioningHint(aHint);
       
  3432 		return;
       
  3433 		}
       
  3434 	iCursorPos.SetPositioningHint(aHint);
       
  3435 
       
  3436 	const CTmTextLayout& layout = iLayout->TagmaTextLayout();
       
  3437 	TTmPosInfo2 posInfo;
       
  3438 	TTmLineInfo lineInfo;
       
  3439 	if (!layout.FindDocPos(iCursorPos.TmDocPos(), posInfo, lineInfo))
       
  3440 		return;
       
  3441 	TBool preferRightToLeft =
       
  3442 		aHint == TCursorPosition::EInsertStrongR2L?
       
  3443 		ETrue : EFalse;
       
  3444 	if (iContextIsNavigation)
       
  3445 		{
       
  3446 		// Navigation: keep the visual position the same but maybe change the
       
  3447 		// logical position
       
  3448 		TTmPosInfo2 posInfoLeft;
       
  3449 		TTmPosInfo2 posInfoRight;
       
  3450 		if (!layout.FindXyPosWithDisambiguation(posInfo.iEdge,
       
  3451 			posInfoLeft, posInfoRight, lineInfo))
       
  3452 			return;
       
  3453 		TBool posInfoRightGood = preferRightToLeft?
       
  3454 			posInfoRight.iRightToLeft : !posInfoRight.iRightToLeft;
       
  3455 		if (posInfoRightGood)
       
  3456 			posInfoLeft = posInfoRight;
       
  3457 		SetDocPosL(posInfoLeft.iDocPos, EFalse);
       
  3458 		}
       
  3459 	else
       
  3460 		{
       
  3461 		// Editing: keep the logical position the same but maybe change the
       
  3462 		// visual position
       
  3463 		TBool posInfoGood = preferRightToLeft?
       
  3464 			posInfo.iRightToLeft :  !posInfo.iRightToLeft;
       
  3465 		if (posInfoGood)
       
  3466 			return;
       
  3467 
       
  3468 		// Cursor is not currently attatched to text of the correct
       
  3469 		// directionality. We shall try attatching to the one in the other
       
  3470 		// direction.
       
  3471 		TTmDocPosSpec spec;
       
  3472 		spec.iPos = posInfo.iDocPos.iPos;
       
  3473 		spec.iType = posInfo.iDocPos.iLeadingEdge?
       
  3474 			TTmDocPosSpec::ETrailing : TTmDocPosSpec::ELeading;
       
  3475 		if (!layout.FindDocPos(spec, posInfo, lineInfo))
       
  3476 			return;
       
  3477 		posInfoGood = preferRightToLeft?
       
  3478 			posInfo.iRightToLeft :  !posInfo.iRightToLeft;
       
  3479 		if (posInfoGood)
       
  3480 			SetDocPosL(posInfo.iDocPos, EFalse);
       
  3481 		iContextIsNavigation = EFalse;
       
  3482 		}
       
  3483 	}
       
  3484 
       
  3485 /**
       
  3486 Sets and unsets an opaque flag on the text view's window. 
       
  3487 @param aDrawOpaque If true, opaque drawing mode is switched on. 
       
  3488 If false, normal drawing will be used.
       
  3489 */
       
  3490 EXPORT_C void CTextView::SetOpaque(TBool aDrawOpaque)
       
  3491 	{
       
  3492 	iDrawOpaque = aDrawOpaque;
       
  3493    	}
       
  3494 
       
  3495 /** 
       
  3496 Stops or allows text to be drawn.  Included to allow users to control visibility
       
  3497 if text is part of an invisible control.
       
  3498 
       
  3499 @param aVisible		ETrue to make the text visible, EFalse to make it invisible.
       
  3500 @see CCoeControl::MakeVisible()
       
  3501 */
       
  3502 EXPORT_C void CTextView::MakeVisible(TBool aVisible)
       
  3503 	{
       
  3504 	if(aVisible)
       
  3505 		{
       
  3506 		iFlags |= EFTextVisible;
       
  3507 		}
       
  3508 	else
       
  3509 		{
       
  3510 		iFlags &= ~EFTextVisible;
       
  3511 		}
       
  3512 	iLayout->MakeVisible(aVisible);
       
  3513 	}