textrendering/textformatting/tbox/LAYEMU.CPP
branchRCL_3
changeset 55 336bee5c2d35
parent 54 748ec5531811
equal deleted inserted replaced
54:748ec5531811 55:336bee5c2d35
    27 #include "FRMCONST_PARTNER.H"
    27 #include "FRMCONST_PARTNER.H"
    28 #include "TAGMA_INTERNAL.H"
    28 #include "TAGMA_INTERNAL.H"
    29 #include "FRMTLAY_INTERNAL.H"
    29 #include "FRMTLAY_INTERNAL.H"
    30 #endif
    30 #endif
    31 
    31 
    32 #include "OstTraceDefinitions.h"
       
    33 #ifdef OST_TRACE_COMPILER_IN_USE
       
    34 #include "LAYEMUTraces.h"
       
    35 #endif
       
    36 
       
    37 const TInt KMaxExtraLines = 10; // maximum number of lines to format after the current and following lines
    32 const TInt KMaxExtraLines = 10; // maximum number of lines to format after the current and following lines
    38 								// before using background formatting
    33 								// before using background formatting
    39 // during page down/up, the number of lines that should remain visible after
    34 // during page down/up, the number of lines that should remain visible after
    40 // the scroll, counting from the first line that is not completely visible.
    35 // the scroll, counting from the first line that is not completely visible.
    41 // i.e. setting this to 0 means always scroll KMaxProportionOfScreenToScroll.
    36 // i.e. setting this to 0 means always scroll KMaxProportionOfScreenToScroll.
    50 const TInt KMaxProportionOfScreenToScroll = 1000;
    45 const TInt KMaxProportionOfScreenToScroll = 1000;
    51 /** minimum scroll proportions in thousandths. This overrides
    46 /** minimum scroll proportions in thousandths. This overrides
    52  the KNumberOfLinesToKeepVisibleDuringScroll constant.*/
    47  the KNumberOfLinesToKeepVisibleDuringScroll constant.*/
    53 const TInt KMinProportionOfScreenToScroll = 600;
    48 const TInt KMinProportionOfScreenToScroll = 600;
    54 
    49 
       
    50 /**
       
    51 Tests for a high surrogate.
       
    52 @param a UTF16 value.
       
    53 @return ETrue if argument is a high surrogate.
       
    54 @internalComponent
       
    55 */
       
    56 inline TBool IsHighSurrogate(TText a) { return 0xD800 == (a & 0xFC00); }
       
    57 /**
       
    58 Tests for a low surrogate.
       
    59 @param a UTF16 value.
       
    60 @return ETrue if argument is a high surrogate.
       
    61 @internalComponent
       
    62 */
       
    63 inline TBool IsLowSurrogate(TText a) { return 0xDC00 == (a & 0xFC00); }
       
    64 /**
       
    65 Adds a high surrogate to a low surrogate to create a supplementary character.
       
    66 @param aHigh UTF16 high surrogate.
       
    67 @param aLow UTF16 low surrogate.
       
    68 @return Supplementary character represented by the pair <aHigh, aLow>.
       
    69 @pre aHigh is a high surrogate and aLow is a low surrogate.
       
    70 @internalComponent
       
    71 */
       
    72 inline TChar PairSurrogates(TText aHigh, TText aLow)
       
    73 	{
       
    74 	return ((aHigh - 0xd7f7) << 10) + aLow;
       
    75 	}
    55 
    76 
    56 /**
    77 /**
    57 Constructs an iterator over the text referenced by aSource.
    78 Constructs an iterator over the text referenced by aSource.
    58 @param aSource The source of the text to be iterated over.
    79 @param aSource The source of the text to be iterated over.
    59 */
    80 */
   107 	valid surrogate pair or an unpaired surrogate, the surrogate is returned.
   128 	valid surrogate pair or an unpaired surrogate, the surrogate is returned.
   108 */
   129 */
   109 TChar CTextLayout::TUtf32SourceCache::GetUtf32(TInt aIndex)
   130 TChar CTextLayout::TUtf32SourceCache::GetUtf32(TInt aIndex)
   110 	{
   131 	{
   111 	TText code = GetUtf16(aIndex);
   132 	TText code = GetUtf16(aIndex);
   112 	if (TChar::IsHighSurrogate(code) && iSource->DocumentLength() < aIndex + 1)
   133 	if (IsHighSurrogate(code) && iSource->DocumentLength() < aIndex + 1)
   113 		{
   134 		{
   114 		TText code2 = GetUtf16(aIndex + 1);
   135 		TText code2 = GetUtf16(aIndex + 1);
   115 		if (TChar::IsLowSurrogate(code2))
   136 		if (IsLowSurrogate(code2))
   116 			return TChar::JoinSurrogate(code, code2);
   137 			return PairSurrogates(code, code2);
   117 		}
   138 		}
   118 	return code;
   139 	return code;
   119 	}
   140 	}
   120 
   141 
   121 /** Allocates and constructs a CTextLayout object. By default, the formatting
   142 /** Allocates and constructs a CTextLayout object. By default, the formatting
   213 
   234 
   214 void CTextLayout::EndRedraw()
   235 void CTextLayout::EndRedraw()
   215 	{
   236 	{
   216 	if(!iReadyToRedraw)
   237 	if(!iReadyToRedraw)
   217 		return;
   238 		return;
   218 	
   239 
   219 	if (iBeginRedrawCount <= 0)
       
   220 	    {
       
   221 	    OstTrace0( TRACE_DUMP, CTEXTLAYOUT_ENDREDRAW, "CTextLayout::EndRedraw" );
       
   222 	    }
       
   223 	__ASSERT_ALWAYS(iBeginRedrawCount > 0, Panic(EInvalidRedraw));
   240 	__ASSERT_ALWAYS(iBeginRedrawCount > 0, Panic(EInvalidRedraw));
   224 
   241 
   225 	if (0 == --iBeginRedrawCount)
   242 	if (0 == --iBeginRedrawCount)
   226 		{
   243 		{
   227 		if (NULL != iWnd)
   244 		if (NULL != iWnd)
   237 		}
   254 		}
   238 	}
   255 	}
   239 
   256 
   240 void CTextLayout::SetExternalDraw(const TRect& aRect)
   257 void CTextLayout::SetExternalDraw(const TRect& aRect)
   241 	{
   258 	{
   242 	if (0 != iBeginRedrawCount)
       
   243 	    {
       
   244 	    OstTrace0( TRACE_FATAL, DUP1_CTEXTLAYOUT_SETEXTERNALDRAW, "EInvalidRedraw" );
       
   245 	    }
       
   246 	__ASSERT_ALWAYS(0 == iBeginRedrawCount, Panic(EInvalidRedraw));
   259 	__ASSERT_ALWAYS(0 == iBeginRedrawCount, Panic(EInvalidRedraw));
   247 	iBeginRedrawCount++;
   260 	iBeginRedrawCount++;
   248 	iRedrawRect = aRect;
   261 	iRedrawRect = aRect;
   249 	}
   262 	}
   250 
   263 
   251 void CTextLayout::ResetExternalDraw()
   264 void CTextLayout::ResetExternalDraw()
   252 	{
   265 	{
   253 	if (1 != iBeginRedrawCount)
       
   254 	    {
       
   255 	    OstTrace0( TRACE_FATAL, CTEXTLAYOUT_RESETEXTERNALDRAW, "EInvalidRedraw" );
       
   256 	    }
       
   257 	__ASSERT_ALWAYS(1 == iBeginRedrawCount, Panic(EInvalidRedraw));
   266 	__ASSERT_ALWAYS(1 == iBeginRedrawCount, Panic(EInvalidRedraw));
   258 
   267 
   259 	iBeginRedrawCount--;
   268 	iBeginRedrawCount--;
   260 	iRedrawRect = TRect();
   269 	iRedrawRect = TRect();
   261 	}
   270 	}
   430 EXPORT_C void CTextLayout::SetFormatMode(CLayoutData::TFormatMode aFormatMode,TInt aWrapWidth,
   439 EXPORT_C void CTextLayout::SetFormatMode(CLayoutData::TFormatMode aFormatMode,TInt aWrapWidth,
   431 										 MGraphicsDeviceMap* aFormatDevice)
   440 										 MGraphicsDeviceMap* aFormatDevice)
   432 	{
   441 	{
   433 	if (aFormatMode == CLayoutData::EFWysiwygMode || aFormatMode == CLayoutData::EFPrintPreviewMode)
   442 	if (aFormatMode == CLayoutData::EFWysiwygMode || aFormatMode == CLayoutData::EFPrintPreviewMode)
   434 		{
   443 		{
   435 		if (aFormatDevice == NULL)
       
   436 		    {
       
   437 		    OstTrace0( TRACE_FATAL, CTEXTLAYOUT_SETFORMATMODE, "EFormatDeviceNotSet" );
       
   438 		    }
       
   439 		__ASSERT_ALWAYS(aFormatDevice != NULL,Panic(EFormatDeviceNotSet));
   444 		__ASSERT_ALWAYS(aFormatDevice != NULL,Panic(EFormatDeviceNotSet));
   440 		iSource->iFormatDevice = aFormatDevice;
   445 		iSource->iFormatDevice = aFormatDevice;
   441 		}
   446 		}
   442 	else
   447 	else
   443 		iSource->iFormatDevice = iSource->iImageDevice;
   448 		iSource->iFormatDevice = iSource->iImageDevice;
   675 to the top of the visible region.
   680 to the top of the visible region.
   676 
   681 
   677 @return The y coordinate of the bottom of the last formatted line. */
   682 @return The y coordinate of the bottom of the last formatted line. */
   678 EXPORT_C TInt CTextLayout::YBottomLastFormattedLine() const
   683 EXPORT_C TInt CTextLayout::YBottomLastFormattedLine() const
   679 	{
   684 	{
   680     return Max(0, iText->LayoutHeight() - iBandTop );
   685 	return Max(0, iText->LayoutHeight() - iBandTop );
   681 	}
   686 	}
   682 
   687 
   683 /** Returns the height in pixels of the formatted text.
   688 /** Returns the height in pixels of the formatted text.
   684 
   689 
   685 @return The height in pixels of all the formatted text. */
   690 @return The height in pixels of all the formatted text. */
   796 @param aLineNo Line number in formatted text, counting the first line as line
   801 @param aLineNo Line number in formatted text, counting the first line as line
   797 one.
   802 one.
   798 @return The document position of the first character on the line. */
   803 @return The document position of the first character on the line. */
   799 EXPORT_C TInt CTextLayout::FirstCharOnLine(TInt aLineNo) const
   804 EXPORT_C TInt CTextLayout::FirstCharOnLine(TInt aLineNo) const
   800 	{
   805 	{
   801 	if (aLineNo <= 0)
       
   802 	    {
       
   803 	    OstTrace0( TRACE_DUMP, CTEXTLAYOUT_FIRSTCHARONLINE, "EInvalidLineNumber" );
       
   804 	    }
       
   805 	__ASSERT_DEBUG(aLineNo > 0,Panic(EInvalidLineNumber));
   806 	__ASSERT_DEBUG(aLineNo > 0,Panic(EInvalidLineNumber));
   806 	if (iText->StartChar() == iText->EndChar())
   807 	if (iText->StartChar() == iText->EndChar())
   807 		return EFNoCurrentFormat;
   808 		return EFNoCurrentFormat;
   808 	aLineNo--;
   809 	aLineNo--;
   809 	TTmLineInfo info;
   810 	TTmLineInfo info;
  1058 			iSource->GetText( r - 1, text, format );
  1059 			iSource->GetText( r - 1, text, format );
  1059 			if ( text.Length() > 1 )
  1060 			if ( text.Length() > 1 )
  1060 				{
  1061 				{
  1061 				TUint highSurrogate = text[0];
  1062 				TUint highSurrogate = text[0];
  1062 				TUint lowSurrogate = text[1];
  1063 				TUint lowSurrogate = text[1];
  1063 				if ( TChar::IsHighSurrogate( highSurrogate ) &&
  1064 				if ( IsHighSurrogate( highSurrogate ) &&
  1064 				        TChar::IsLowSurrogate( lowSurrogate ) )
  1065 				     IsLowSurrogate( lowSurrogate ) )
  1065 					--r;
  1066 					--r;
  1066 				}
  1067 				}
  1067 			}
  1068 			}
  1068 		}
  1069 		}
  1069 
  1070 
  1173 	TInt xCoords[4];
  1174 	TInt xCoords[4];
  1174 	
  1175 	
  1175 	if (iText->LayoutHeight() == 0)
  1176 	if (iText->LayoutHeight() == 0)
  1176 		return TRect(0,0,0,0);
  1177 		return TRect(0,0,0,0);
  1177 
  1178 
  1178 	if (!PosIsFormatted(aDocPos1))
       
  1179 	    {
       
  1180 	    OstTrace0( TRACE_FATAL, CTEXTLAYOUT_GETLINERECTL, "ECharacterNotFormatted" );
       
  1181 	    }
       
  1182 	__ASSERT_ALWAYS(PosIsFormatted(aDocPos1),Panic(ECharacterNotFormatted));
  1179 	__ASSERT_ALWAYS(PosIsFormatted(aDocPos1),Panic(ECharacterNotFormatted));
  1183 	if (!PosIsFormatted(aDocPos2))
       
  1184 	    {
       
  1185 	    OstTrace0( TRACE_DUMP, DUP1_CTEXTLAYOUT_GETLINERECTL, "ECharacterNotFormatted" );
       
  1186 	    }
       
  1187 	__ASSERT_DEBUG(PosIsFormatted(aDocPos2),Panic(ECharacterNotFormatted));
  1180 	__ASSERT_DEBUG(PosIsFormatted(aDocPos2),Panic(ECharacterNotFormatted));
  1188 
  1181 
  1189 	TTmDocPosSpec docSpec(aDocPos1, TTmDocPosSpec::ELeading);
  1182 	TTmDocPosSpec docSpec(aDocPos1, TTmDocPosSpec::ELeading);
  1190 	TTmPosInfo2 pos_info;
  1183 	TTmPosInfo2 pos_info;
  1191 	
  1184 	
  1195 	xCoords[0] = point.iX;
  1188 	xCoords[0] = point.iX;
  1196 
  1189 
  1197 	// Getthe Line rectangle
  1190 	// Getthe Line rectangle
  1198 	GetLineRect(point.iY,rect);
  1191 	GetLineRect(point.iY,rect);
  1199 	
  1192 	
  1200 	if (rect.iTl.iY > point.iY || rect.iBr.iY < point.iY)
       
  1201 	    {
       
  1202 	    OstTrace0( TRACE_DUMP, DUP2_CTEXTLAYOUT_GETLINERECTL, "EPixelNotInFormattedLine" );
       
  1203 	    }
       
  1204 	__ASSERT_DEBUG(rect.iTl.iY <= point.iY && rect.iBr.iY >= point.iY,Panic(EPixelNotInFormattedLine));
  1193 	__ASSERT_DEBUG(rect.iTl.iY <= point.iY && rect.iBr.iY >= point.iY,Panic(EPixelNotInFormattedLine));
  1205 	
  1194 	
  1206 	//	Finding the leading edge of aDocPos2
  1195 	//	Finding the leading edge of aDocPos2
  1207 	docSpec.iPos = aDocPos2;
  1196 	docSpec.iPos = aDocPos2;
  1208 	TBool isformatted = FindDocPos(docSpec, pos_info);
  1197 	TBool isformatted = FindDocPos(docSpec, pos_info);
  1545 	iText->SetTextL(*iSource,param);
  1534 	iText->SetTextL(*iSource,param);
  1546 	param.iMaxHeight = KMaxTInt;
  1535 	param.iMaxHeight = KMaxTInt;
  1547 	
  1536 	
  1548 	if(IsFormattingBand() && (iText->EndChar() <= aEndDocPos && iText->EndChar() < iSource->DocumentLength()))
  1537 	if(IsFormattingBand() && (iText->EndChar() <= aEndDocPos && iText->EndChar() < iSource->DocumentLength()))
  1549 		{
  1538 		{
  1550 		param.iEndChar = Min(aEndDocPos+1,iSource->DocumentLength());
  1539 		param.iEndChar = aEndDocPos;
  1551 		iText->ExtendFormattingDownwardsL(param);
  1540 		iText->ExtendFormattingDownwardsL(param);
  1552 		}
  1541 		}
  1553 	else
  1542 	else
  1554 		{
  1543 		{
  1555 		while (iText->EndChar() <= aEndDocPos && iText->EndChar() < iSource->DocumentLength())
  1544 		while (iText->EndChar() <= aEndDocPos && iText->EndChar() < iSource->DocumentLength())
  1610 @pre aDocPos is in the range 0...DocumentLength
  1599 @pre aDocPos is in the range 0...DocumentLength
  1611 @post aDocPos has been formatted
  1600 @post aDocPos has been formatted
  1612 */
  1601 */
  1613 EXPORT_C void CTextLayout::ExtendFormattingToCoverPosL(TInt aDocPos)
  1602 EXPORT_C void CTextLayout::ExtendFormattingToCoverPosL(TInt aDocPos)
  1614 	{
  1603 	{
  1615 	if (0 > aDocPos || aDocPos > DocumentLength())
       
  1616 	    {
       
  1617 	    OstTrace0( TRACE_DUMP, CTEXTLAYOUT_EXTENDFORMATTINGTOCOVERPOSL, "EInvalidDocPos" );
       
  1618 	    }
       
  1619 	__ASSERT_DEBUG(0 <= aDocPos && aDocPos <= DocumentLength(),
  1604 	__ASSERT_DEBUG(0 <= aDocPos && aDocPos <= DocumentLength(),
  1620 			Panic(EInvalidDocPos));
  1605 			Panic(EInvalidDocPos));
  1621 	TTmFormatParam param;
  1606 	TTmFormatParam param;
  1622 	InitFormatParam(param);
  1607 	InitFormatParam(param);
  1623 	param.iStartChar = iText->StartChar();
  1608 	param.iStartChar = iText->StartChar();
  1638 	param.iEndChar = aDocPos + 1;
  1623 	param.iEndChar = aDocPos + 1;
  1639 	if(iText->EndChar() < param.iEndChar)
  1624 	if(iText->EndChar() < param.iEndChar)
  1640 		{
  1625 		{
  1641 		iText->ExtendFormattingDownwardsL(param);
  1626 		iText->ExtendFormattingDownwardsL(param);
  1642 		}
  1627 		}
  1643 	if ((aDocPos < iText->StartChar()) || (aDocPos > iText->EndChar()))
       
  1644 	    {
       
  1645 	    OstTrace0( TRACE_DUMP, DUP1_CTEXTLAYOUT_EXTENDFORMATTINGTOCOVERPOSL, "ECharacterNotFormatted" );
       
  1646 	    }
       
  1647 	__ASSERT_DEBUG((aDocPos >= iText->StartChar()) && (aDocPos <= iText->EndChar()),
  1628 	__ASSERT_DEBUG((aDocPos >= iText->StartChar()) && (aDocPos <= iText->EndChar()),
  1648 			Panic(ECharacterNotFormatted));
  1629 			Panic(ECharacterNotFormatted));
  1649 	}
  1630 	}
  1650 
  1631 
  1651 
  1632 
  1668 	FormatCharRangeL(aStartDocPos,aEndDocPos,0);
  1649 	FormatCharRangeL(aStartDocPos,aEndDocPos,0);
  1669 	}
  1650 	}
  1670 
  1651 
  1671 void CTextLayout::FormatCharRangeL(TInt aStartDocPos,TInt aEndDocPos,TInt aPixelOffset)
  1652 void CTextLayout::FormatCharRangeL(TInt aStartDocPos,TInt aEndDocPos,TInt aPixelOffset)
  1672 	{
  1653 	{
  1673 	if (aStartDocPos < 0 && aStartDocPos > DocumentLength())
       
  1674 	    {
       
  1675 	    OstTrace0( TRACE_DUMP, CTEXTLAYOUT_FORMATCHARRANGEL, "EInvalidDocPos" );
       
  1676 	    }
       
  1677 	__ASSERT_DEBUG(aStartDocPos >= 0 && aStartDocPos <= DocumentLength(),Panic(EInvalidDocPos));
  1654 	__ASSERT_DEBUG(aStartDocPos >= 0 && aStartDocPos <= DocumentLength(),Panic(EInvalidDocPos));
  1678 	if (aEndDocPos < 0 || aEndDocPos > DocumentLength())
       
  1679 	    {
       
  1680 	    OstTrace0( TRACE_DUMP, DUP1_CTEXTLAYOUT_FORMATCHARRANGEL, "EInvalidDocPos" );
       
  1681 	    }
       
  1682 	__ASSERT_DEBUG(aEndDocPos >= 0 && aEndDocPos <= DocumentLength(),Panic(EInvalidDocPos));
  1655 	__ASSERT_DEBUG(aEndDocPos >= 0 && aEndDocPos <= DocumentLength(),Panic(EInvalidDocPos));
  1683 	if (aStartDocPos > aEndDocPos)
       
  1684 	    {
       
  1685 	    OstTrace0( TRACE_DUMP, DUP2_CTEXTLAYOUT_FORMATCHARRANGEL, "ENoCharRangeToFormat" );
       
  1686 	    }
       
  1687 	__ASSERT_DEBUG(aStartDocPos <= aEndDocPos,Panic(ENoCharRangeToFormat));
  1656 	__ASSERT_DEBUG(aStartDocPos <= aEndDocPos,Panic(ENoCharRangeToFormat));
  1688 
  1657 
  1689 	TTmFormatParam param;
  1658 	TTmFormatParam param;
  1690 	InitFormatParam(param);
  1659 	InitFormatParam(param);
  1691 	param.iStartChar = iSource->ParagraphStart(aStartDocPos);
  1660 	param.iStartChar = iSource->ParagraphStart(aStartDocPos);
  1732 		if (result.iUnformattedStart == KMaxTInt)
  1701 		if (result.iUnformattedStart == KMaxTInt)
  1733 			{
  1702 			{
  1734 			TTmLineInfo info;
  1703 			TTmLineInfo info;
  1735 			TTmDocPos pos(iUnformattedStart, ETrue);
  1704 			TTmDocPos pos(iUnformattedStart, ETrue);
  1736 			TBool isFormatted = iText->DocPosToLine(pos,info);
  1705 			TBool isFormatted = iText->DocPosToLine(pos,info);
  1737 			if (!isFormatted)
       
  1738 			    {
       
  1739 			    OstTrace0( TRACE_DUMP, CTEXTLAYOUT_FORMATNEXTLINEL, "EPosNotFormatted" );
       
  1740 			    }
       
  1741 			__ASSERT_DEBUG(isFormatted, Panic(EPosNotFormatted));
  1706 			__ASSERT_DEBUG(isFormatted, Panic(EPosNotFormatted));
  1742 			isFormatted = iText->ParNumberToLine(info.iParNumber,KMaxTInt,info);
  1707 			isFormatted = iText->ParNumberToLine(info.iParNumber,KMaxTInt,info);
  1743 			if (!isFormatted)
       
  1744 			    {
       
  1745 			    OstTrace0( TRACE_DUMP, DUP1_CTEXTLAYOUT_FORMATNEXTLINEL, "EPosNotFormatted" );
       
  1746 			    }
       
  1747 			__ASSERT_DEBUG(isFormatted, Panic(EPosNotFormatted));
  1708 			__ASSERT_DEBUG(isFormatted, Panic(EPosNotFormatted));
  1748 			aBottomPixel = info.iOuterRect.iBr.iY - iBandTop;
  1709 			aBottomPixel = info.iOuterRect.iBr.iY - iBandTop;
  1749 			}
  1710 			}
  1750 
  1711 
  1751 		// Indicate that formatting is complete up to the lower edge of the current line.
  1712 		// Indicate that formatting is complete up to the lower edge of the current line.
  1929 			else
  1890 			else
  1930 				{
  1891 				{
  1931 				if (iText->YPosToLine(iBandTop,info))
  1892 				if (iText->YPosToLine(iBandTop,info))
  1932 					top_line_number = info.iLineNumber;
  1893 					top_line_number = info.iLineNumber;
  1933 				else
  1894 				else
  1934 				    {
       
  1935 					OstTrace0( TRACE_DUMP, DUP1_CTEXTLAYOUT_SCROLLLINESL, "EPosNotFormatted" );
       
  1936 					User::Leave(EPosNotFormatted);
  1895 					User::Leave(EPosNotFormatted);
  1937 					}
       
  1938 				partial_line = iBandTop > info.iOuterRect.iTl.iY;
  1896 				partial_line = iBandTop > info.iOuterRect.iTl.iY;
  1939 				}
  1897 				}
  1940 
  1898 
  1941 			// Find the line number of the desired first visible line.
  1899 			// Find the line number of the desired first visible line.
  1942 			// Defect fix for INC015850. Changed IF so that if the currently
  1900 			// Defect fix for INC015850. Changed IF so that if the currently
  1962 			}
  1920 			}
  1963 		aLines -= lines_scrolled;
  1921 		aLines -= lines_scrolled;
  1964 		if (lines_scrolled)
  1922 		if (lines_scrolled)
  1965 			{
  1923 			{
  1966 			if (!iText->LineNumberToLine(desired_top_line_number,info))
  1924 			if (!iText->LineNumberToLine(desired_top_line_number,info))
  1967 			    {
  1925 				User::Leave(EPosNotFormatted);
  1968 			    OstTrace0( TRACE_DUMP, CTEXTLAYOUT_SCROLLLINESL, "EPosNotFormatted" );
       
  1969 			    User::Leave(EPosNotFormatted);
       
  1970 			    }
       
  1971 			// if the line to be scrolled to is taller than the screen, we want
  1926 			// if the line to be scrolled to is taller than the screen, we want
  1972 			// to make sure that the baseline is not scrolled off the screen.
  1927 			// to make sure that the baseline is not scrolled off the screen.
  1973 			if (visible_height < info.iBaseline - info.iOuterRect.iTl.iY)
  1928 			if (visible_height < info.iBaseline - info.iOuterRect.iTl.iY)
  1974 				return ScrollL(iBandTop + visible_height - info.iBaseline, aScrollBlankSpace);
  1929 				return ScrollL(iBandTop + visible_height - info.iBaseline, aScrollBlankSpace);
  1975 			return ScrollL(iBandTop - info.iOuterRect.iTl.iY,aScrollBlankSpace);
  1930 			return ScrollL(iBandTop - info.iOuterRect.iTl.iY,aScrollBlankSpace);
  1982 		if (iScrollFlags & EFScrollOnlyToTopsOfLines)
  1937 		if (iScrollFlags & EFScrollOnlyToTopsOfLines)
  1983 			{
  1938 			{
  1984 			// If we are restricting scroll to the tops of lines, then lines at
  1939 			// If we are restricting scroll to the tops of lines, then lines at
  1985 			// bottom are irrelevant, so all we do is lose the top line.
  1940 			// bottom are irrelevant, so all we do is lose the top line.
  1986 			if (!iText->YPosToLine(iBandTop, info))
  1941 			if (!iText->YPosToLine(iBandTop, info))
  1987 			    {
  1942 				User::Leave(EPosNotFormatted);
  1988 			    OstTrace0( TRACE_DUMP, DUP2_CTEXTLAYOUT_SCROLLLINESL, "EPosNotFormatted" );
       
  1989 			    User::Leave(EPosNotFormatted);
       
  1990 			    }
       
  1991 			return ScrollL(-info.iOuterRect.Height(), aScrollBlankSpace);
  1943 			return ScrollL(-info.iOuterRect.Height(), aScrollBlankSpace);
  1992 			}
  1944 			}
  1993 
  1945 
  1994 		int desired_bottom_line_number = 0;
  1946 		int desired_bottom_line_number = 0;
  1995 		int band_bottom = iBandTop + visible_height;
  1947 		int band_bottom = iBandTop + visible_height;
  2008 			TBool partial_line = FALSE;
  1960 			TBool partial_line = FALSE;
  2009 			int bottom_line_number = 0;
  1961 			int bottom_line_number = 0;
  2010 			if (iText->YPosToLine(band_bottom - 1,info))
  1962 			if (iText->YPosToLine(band_bottom - 1,info))
  2011 				bottom_line_number = info.iLineNumber;
  1963 				bottom_line_number = info.iLineNumber;
  2012 			else
  1964 			else
  2013 			    {
  1965 				User::Leave(EPosNotFormatted);
  2014 			    OstTrace0( TRACE_DUMP, DUP3_CTEXTLAYOUT_SCROLLLINESL, "EPosNotFormatted" );
       
  2015 			    User::Leave(EPosNotFormatted);
       
  2016 			    }
       
  2017 			partial_line = band_bottom < info.iOuterRect.iBr.iY;
  1966 			partial_line = band_bottom < info.iOuterRect.iBr.iY;
  2018 
  1967 
  2019 			// Find the line number of the desired last visible line.
  1968 			// Find the line number of the desired last visible line.
  2020 			desired_bottom_line_number = bottom_line_number - aLines;
  1969 			desired_bottom_line_number = bottom_line_number - aLines;
  2021 			if (partial_line)
  1970 			if (partial_line)
  2037 			}
  1986 			}
  2038 		aLines -= lines_scrolled;
  1987 		aLines -= lines_scrolled;
  2039 		if (lines_scrolled)
  1988 		if (lines_scrolled)
  2040 			{
  1989 			{
  2041 			if (!iText->LineNumberToLine(desired_bottom_line_number,info))
  1990 			if (!iText->LineNumberToLine(desired_bottom_line_number,info))
  2042 			    {
  1991 				User::Leave(EPosNotFormatted);
  2043 			    OstTrace0( TRACE_DUMP, DUP4_CTEXTLAYOUT_SCROLLLINESL, "EPosNotFormattedL" );
       
  2044 			    User::Leave(EPosNotFormatted);
       
  2045 			    }
       
  2046 			return ScrollL(band_bottom - info.iOuterRect.iBr.iY,aScrollBlankSpace);
  1992 			return ScrollL(band_bottom - info.iOuterRect.iBr.iY,aScrollBlankSpace);
  2047 			}
  1993 			}
  2048 		else
  1994 		else
  2049 			return 0;
  1995 			return 0;
  2050 		}
  1996 		}
  2236 		EFDisallowScrollingBlankSpace);
  2182 		EFDisallowScrollingBlankSpace);
  2237 	aYCursorPos = aPixelsScrolled == 0?
  2183 	aYCursorPos = aPixelsScrolled == 0?
  2238 		visible_height - 1
  2184 		visible_height - 1
  2239 		: SuggestCursorPos(aYCursorPos);
  2185 		: SuggestCursorPos(aYCursorPos);
  2240 
  2186 
  2241 	if (-visible_height > aPixelsScrolled)
       
  2242 	    {
       
  2243 	    OstTrace0( TRACE_DUMP, CTEXTLAYOUT_PAGEDOWNL, "EPageScrollError" );
       
  2244 	    }
       
  2245 	__ASSERT_DEBUG(-visible_height <= aPixelsScrolled,
  2187 	__ASSERT_DEBUG(-visible_height <= aPixelsScrolled,
  2246 		Panic(EPageScrollError));
  2188 		Panic(EPageScrollError));
  2247 	if (0 > aYCursorPos || aYCursorPos > visible_height)
       
  2248 	    {
       
  2249 	    OstTrace0( TRACE_DUMP, DUP1_CTEXTLAYOUT_PAGEDOWNL, "EPageScrollError" );
       
  2250 	    }
       
  2251 	__ASSERT_DEBUG(0 <= aYCursorPos && aYCursorPos <= visible_height,
  2189 	__ASSERT_DEBUG(0 <= aYCursorPos && aYCursorPos <= visible_height,
  2252 		Panic(EPageScrollError));
  2190 		Panic(EPageScrollError));
  2253 	}
  2191 	}
  2254 
  2192 
  2255 /** Reformats to reflect a single character edit.
  2193 /** Reformats to reflect a single character edit.
  2278 @return EFalse if no more lines need to be reformatted. ETrue if some more lines
  2216 @return EFalse if no more lines need to be reformatted. ETrue if some more lines
  2279 need to be reformatted. */
  2217 need to be reformatted. */
  2280 EXPORT_C TBool CTextLayout::HandleCharEditL(TUint aType,TInt& aCursorPos,TInt& aGood,TInt& aFormatBottom,
  2218 EXPORT_C TBool CTextLayout::HandleCharEditL(TUint aType,TInt& aCursorPos,TInt& aGood,TInt& aFormatBottom,
  2281 											TInt& aFormatTop,TInt& aScroll,TBool aFormatFromStartOfPar)
  2219 											TInt& aFormatTop,TInt& aScroll,TBool aFormatFromStartOfPar)
  2282 	{
  2220 	{
  2283 	if (iSource->iFormatMode == CLayoutData::EFPrintPreviewMode)
       
  2284 	    {
       
  2285 	    OstTrace0( TRACE_FATAL, DUP2_CTEXTLAYOUT_HANDLECHAREDITL, "EPrintPreviewModeError" );
       
  2286 	    }
       
  2287 	__ASSERT_ALWAYS(iSource->iFormatMode != CLayoutData::EFPrintPreviewMode,Panic(EPrintPreviewModeError));
  2221 	__ASSERT_ALWAYS(iSource->iFormatMode != CLayoutData::EFPrintPreviewMode,Panic(EPrintPreviewModeError));
  2288 	if (aType > EFRightDelete)
       
  2289 	    {
       
  2290 	    OstTrace0( TRACE_FATAL, CTEXTLAYOUT_HANDLECHAREDITL, "EBadCharacterEditType" );
       
  2291 	    }
       
  2292 	__ASSERT_ALWAYS(aType <= EFRightDelete,Panic(EBadCharacterEditType));
  2222 	__ASSERT_ALWAYS(aType <= EFRightDelete,Panic(EBadCharacterEditType));
  2293 	if (!(!aFormatFromStartOfPar || aType == EFRightDelete || aType == EFLeftDelete))
       
  2294 	    {
       
  2295 	    OstTrace0( TRACE_FATAL, DUP1_CTEXTLAYOUT_HANDLECHAREDITL, "EBadCharacterEditType" );
       
  2296 	    }
       
  2297 	__ASSERT_ALWAYS(!aFormatFromStartOfPar || aType == EFRightDelete || aType == EFLeftDelete,Panic(EBadCharacterEditType));
  2223 	__ASSERT_ALWAYS(!aFormatFromStartOfPar || aType == EFRightDelete || aType == EFLeftDelete,Panic(EBadCharacterEditType));
  2298 	if (aCursorPos < iText->StartChar() || aCursorPos >= iText->EndChar())
       
  2299 	    {
       
  2300 	    OstTrace0( TRACE_FATAL, DUP3_CTEXTLAYOUT_HANDLECHAREDITL, "ECharacterNotFormatted" );
       
  2301 	    }
       
  2302 	__ASSERT_ALWAYS(aCursorPos >= iText->StartChar() && aCursorPos < iText->EndChar(),Panic(ECharacterNotFormatted));
  2224 	__ASSERT_ALWAYS(aCursorPos >= iText->StartChar() && aCursorPos < iText->EndChar(),Panic(ECharacterNotFormatted));
  2303 
  2225 
  2304 	// Mark the entire paragraph invalid if background formatting is taking place.
  2226 	// Mark the entire paragraph invalid if background formatting is taking place.
  2305 	iParInvalid = iUnformattedStart != KMaxTInt;
  2227 	iParInvalid = iUnformattedStart != KMaxTInt;
  2306 
  2228 
  2312 	reformat_param.iParInvalid = iParInvalid;
  2234 	reformat_param.iParInvalid = iParInvalid;
  2313 	switch (aType)
  2235 	switch (aType)
  2314 		{
  2236 		{
  2315 		case EFCharacterInsert:
  2237 		case EFCharacterInsert:
  2316 		case EFParagraphDelimiter:
  2238 		case EFParagraphDelimiter:
  2317 			{
       
  2318 			reformat_param.iStartChar = aCursorPos++;
  2239 			reformat_param.iStartChar = aCursorPos++;
  2319 			reformat_param.iNewLength = 1;
  2240 			reformat_param.iNewLength = 1;
  2320 
       
  2321 			// surrogate support
       
  2322 			TPtrC textForSurrogate;
       
  2323 			TTmCharFormat formatForSurrogate;
       
  2324 		
       
  2325 			iSource->GetText(aCursorPos-1, textForSurrogate, formatForSurrogate);
       
  2326 			if ( textForSurrogate.Length() > 1 )
       
  2327 				{
       
  2328 				TUint highSurrogate = textForSurrogate[0];
       
  2329 				TUint lowSurrogate = textForSurrogate[1];
       
  2330 				if ( TChar::IsHighSurrogate( highSurrogate ) && TChar::IsLowSurrogate( lowSurrogate ) )
       
  2331 					{
       
  2332 					// if we are inserting a surrogate pair, do not break the pair
       
  2333 					aCursorPos++;
       
  2334 					reformat_param.iNewLength++;
       
  2335 					}
       
  2336 				}
       
  2337 			break;
  2241 			break;
  2338 			}
       
  2339 		case EFLeftDelete:
  2242 		case EFLeftDelete:
  2340 			{
       
  2341 			reformat_param.iStartChar = --aCursorPos;
  2243 			reformat_param.iStartChar = --aCursorPos;
  2342 			reformat_param.iOldLength = 1;
  2244 			reformat_param.iOldLength = 1;
  2343 
       
  2344 			// surrogate support
       
  2345 			TPtrC textForSurrogate;
       
  2346 			TTmCharFormat formatForSurrogate;
       
  2347 		
       
  2348 			if (aCursorPos >= 1)
       
  2349 				{
       
  2350 				iSource->GetText(aCursorPos-1, textForSurrogate, formatForSurrogate);
       
  2351 				if ( textForSurrogate.Length() > 1 )
       
  2352 					{
       
  2353 					TUint highSurrogate = textForSurrogate[0];
       
  2354 					TUint lowSurrogate = textForSurrogate[1];
       
  2355 					if ( TChar::IsHighSurrogate( highSurrogate ) && TChar::IsLowSurrogate( lowSurrogate ) )
       
  2356 						{
       
  2357 						// if we are deleting a surrogate pair, do not break the pair
       
  2358 						reformat_param.iStartChar = --aCursorPos;
       
  2359 						reformat_param.iOldLength++;
       
  2360 						}
       
  2361 					}
       
  2362 				}
       
  2363 			break;
  2245 			break;
  2364 			}
       
  2365 		case EFRightDelete:
  2246 		case EFRightDelete:
  2366 			{
       
  2367 			reformat_param.iStartChar = aCursorPos;
  2247 			reformat_param.iStartChar = aCursorPos;
  2368 			reformat_param.iOldLength = 1;
  2248 			reformat_param.iOldLength = 1;
  2369 
       
  2370 			// surrogate support
       
  2371 			TPtrC textForSurrogate;
       
  2372 			TTmCharFormat formatForSurrogate;
       
  2373 		
       
  2374 			iSource->GetText(aCursorPos, textForSurrogate, formatForSurrogate);
       
  2375 			if ( textForSurrogate.Length() > 1 )
       
  2376 				{
       
  2377 				TUint highSurrogate = textForSurrogate[0];
       
  2378 				TUint lowSurrogate = textForSurrogate[1];
       
  2379 				if ( TChar::IsHighSurrogate( highSurrogate ) && TChar::IsLowSurrogate( lowSurrogate ) )
       
  2380 					{
       
  2381 					reformat_param.iOldLength++;
       
  2382 					}
       
  2383 				}
       
  2384 			break;
  2249 			break;
  2385 			}
       
  2386 		default: break;
  2250 		default: break;
  2387 		}
  2251 		}
  2388 
  2252 
  2389 	// Set up the formatting parameters.
  2253 	// Set up the formatting parameters.
  2390 	TTmFormatParam param;
  2254 	TTmFormatParam param;
  2460 must extend out to paragraph boundaries and cannot be restricted to only some
  2324 must extend out to paragraph boundaries and cannot be restricted to only some
  2461 lines. */
  2325 lines. */
  2462 EXPORT_C void CTextLayout::HandleBlockChangeL(TCursorSelection aSelection,TInt aOldLength,
  2326 EXPORT_C void CTextLayout::HandleBlockChangeL(TCursorSelection aSelection,TInt aOldLength,
  2463 											  TViewRectChanges& aChanges,TBool aFormatFromStartOfPar)
  2327 											  TViewRectChanges& aChanges,TBool aFormatFromStartOfPar)
  2464 	{
  2328 	{
  2465 	if (iSource->iFormatMode == CLayoutData::EFPrintPreviewMode)
       
  2466 	    {
       
  2467 	    OstTrace0( TRACE_FATAL, CTEXTLAYOUT_HANDLEBLOCKCHANGEL, "EPrintPreviewModeError" );
       
  2468 	    }
       
  2469 	__ASSERT_ALWAYS(iSource->iFormatMode != CLayoutData::EFPrintPreviewMode,Panic(EPrintPreviewModeError));
  2329 	__ASSERT_ALWAYS(iSource->iFormatMode != CLayoutData::EFPrintPreviewMode,Panic(EPrintPreviewModeError));
  2470 
  2330 
  2471 	// Do nothing if the selection is outside the formatted range.
  2331 	// Do nothing if the selection is outside the formatted range.
  2472 	if (aSelection.LowerPos() > iText->EndChar() || aSelection.HigherPos() < iText->StartChar())
  2332 	if (aSelection.LowerPos() > iText->EndChar() || aSelection.HigherPos() < iText->StartChar())
  2473 		{
  2333 		{
  2590 application's year view). */
  2450 application's year view). */
  2591 EXPORT_C void CTextLayout::AdjustVerticalAlignment(CParaFormat::TAlignment aVerticalAlignment)
  2451 EXPORT_C void CTextLayout::AdjustVerticalAlignment(CParaFormat::TAlignment aVerticalAlignment)
  2592 	{
  2452 	{
  2593 	int excess = BandHeight() - FormattedHeightInPixels();
  2453 	int excess = BandHeight() - FormattedHeightInPixels();
  2594 	int space_before = 0;
  2454 	int space_before = 0;
  2595 	
       
  2596 	if (IsFormattingBand())
       
  2597 	    {
       
  2598 	    OstTrace0( TRACE_FATAL, CTEXTLAYOUT_ADJUSTVERTICALALIGNMENT, "EMustFormatAllText" );
       
  2599 	    }
       
  2600 	__ASSERT_ALWAYS(!IsFormattingBand(),Panic(EMustFormatAllText));
  2455 	__ASSERT_ALWAYS(!IsFormattingBand(),Panic(EMustFormatAllText));
  2601 	TTmLineInfo info;
  2456 	TTmLineInfo info;
  2602 
  2457 
  2603 	switch (aVerticalAlignment)
  2458 	switch (aVerticalAlignment)
  2604 		{
  2459 		{
  2835 			};
  2690 			};
  2836 
  2691 
  2837 // Repeat draw, for double border.
  2692 // Repeat draw, for double border.
  2838 		if (aBorder.iBorder[border].iLineStyle==TParaBorder::EDouble)	 // Now have only got solid border, drawn as rect.
  2693 		if (aBorder.iBorder[border].iLineStyle==TParaBorder::EDouble)	 // Now have only got solid border, drawn as rect.
  2839 			{
  2694 			{
  2840 			if (drawAsLine)
       
  2841 			    {
       
  2842 			    OstTrace0( TRACE_DUMP, CTEXTLAYOUT_DRAWBORDERS, "EDrawingBorderError" );
       
  2843 			    }
       
  2844 			__ASSERT_DEBUG(!drawAsLine,Panic(EDrawingBorderError));
  2695 			__ASSERT_DEBUG(!drawAsLine,Panic(EDrawingBorderError));
  2845 			(*ptrStartWidth)-=directionOut*widthInPixels[border];
  2696 			(*ptrStartWidth)-=directionOut*widthInPixels[border];
  2846 			(*ptrEndWidth)-=directionOut*widthInPixels[border];
  2697 			(*ptrEndWidth)-=directionOut*widthInPixels[border];
  2847 			(*ptrStartLength)+=widthInPixels[indexJoint1];
  2698 			(*ptrStartLength)+=widthInPixels[indexJoint1];
  2848 			(*ptrEndLength)-=widthInPixels[indexJoint2];
  2699 			(*ptrEndLength)-=widthInPixels[indexJoint2];
  4159 	param.iMaxHeight = KMaxTInt;
  4010 	param.iMaxHeight = KMaxTInt;
  4160 	int visible_height = VisibleHeightInPixels();
  4011 	int visible_height = VisibleHeightInPixels();
  4161 	if (aDy > 0)		// text moves down; iBandTop decreases
  4012 	if (aDy > 0)		// text moves down; iBandTop decreases
  4162 		{
  4013 		{
  4163 		if (aTopNoLimitBorder)
  4014 		if (aTopNoLimitBorder)
       
  4015 		    {
  4164 	        iBandTop = desired_bandtop;
  4016 	        iBandTop = desired_bandtop;
       
  4017 		    }
  4165 		else
  4018 		else
  4166 		    iBandTop = Max(0,desired_bandtop);//Disallow text scrolled beyond top border
  4019 		    iBandTop = Max(0,desired_bandtop);//Disallow text scrolled beyond top border
  4167 		
  4020 		
  4168 		pixels_scrolled = old_bandtop - iBandTop;
  4021 		pixels_scrolled = old_bandtop - iBandTop;
  4169 		while (pixels_scrolled < aDy)
  4022 		while (pixels_scrolled < aDy)
  4203 		while (iText->LayoutHeight() - iBandTop < visible_height)
  4056 		while (iText->LayoutHeight() - iBandTop < visible_height)
  4204 			{
  4057 			{
  4205 			if (!AddFormattingAtEndL(param, height_increase,paragraphs_increase))
  4058 			if (!AddFormattingAtEndL(param, height_increase,paragraphs_increase))
  4206 				break;
  4059 				break;
  4207 			}
  4060 			}
       
  4061 		
       
  4062 		// Shift the whole band upwards if we're at the very end of the text
       
  4063 		// and there's no more text to format. This prevents a situation were
       
  4064 		// iText->LayoutHeight() < BandHeightInPixels.
       
  4065 		if ( aBottomNoLimitBorder && iText->LayoutHeight() - iBandTop < visible_height )
       
  4066 		    {
       
  4067 		    if ( iText->EndChar() > iText->Source()->DocumentLength() )
       
  4068 		        {
       
  4069 		        iBandTop = desired_bandtop;
       
  4070 		        return pixels_scrolled;
       
  4071 		        }
       
  4072 		    }
       
  4073 
  4208 		}
  4074 		}
  4209 
  4075 
  4210 	// Scroll blank space off the display if desired.
  4076 	// Scroll blank space off the display if desired.
  4211 	if (aScrollBlankSpace == EFDisallowScrollingBlankSpace && iText->LayoutHeight() - iBandTop < visible_height)
  4077 	if (aScrollBlankSpace == EFDisallowScrollingBlankSpace && iText->LayoutHeight() - iBandTop < visible_height)
  4212 		{
  4078 		{
  4221 	return pixels_scrolled + SetBandTop();
  4087 	return pixels_scrolled + SetBandTop();
  4222 	}
  4088 	}
  4223 
  4089 
  4224 TInt CTextLayout::ScrollDocPosIntoViewL(const TTmDocPos& aDocPos)
  4090 TInt CTextLayout::ScrollDocPosIntoViewL(const TTmDocPos& aDocPos)
  4225 	{
  4091 	{
  4226 	if (aDocPos.iPos > iText->Source()->DocumentLength())
       
  4227 	    {
       
  4228 	    OstTrace0( TRACE_DUMP, CTEXTLAYOUT_SCROLLDOCPOSINTOVIEWL, "EInvalidDocPos" );
       
  4229 	    }
       
  4230 	__ASSERT_DEBUG(aDocPos.iPos <= iText->Source()->DocumentLength(),
  4092 	__ASSERT_DEBUG(aDocPos.iPos <= iText->Source()->DocumentLength(),
  4231 		Panic(EInvalidDocPos));
  4093 		Panic(EInvalidDocPos));
  4232 	TTmLineInfo info;
  4094 	TTmLineInfo info;
  4233 	ExtendFormattingToCoverPosL(aDocPos.iPos);
  4095 	ExtendFormattingToCoverPosL(aDocPos.iPos);
  4234 	if (!iText->DocPosToLine(aDocPos,info))
  4096 	if (!iText->DocPosToLine(aDocPos,info))
  4235 		{
  4097 		{
  4236 		if (iText->Source()->DocumentLength() != 0)
       
  4237 		    {
       
  4238 		    OstTrace0( TRACE_DUMP, DUP1_CTEXTLAYOUT_SCROLLDOCPOSINTOVIEWL, "ECharacterNotFormatted" );
       
  4239 		    }
       
  4240 		__ASSERT_DEBUG(iText->Source()->DocumentLength() == 0,
  4098 		__ASSERT_DEBUG(iText->Source()->DocumentLength() == 0,
  4241 			Panic(ECharacterNotFormatted));
  4099 			Panic(ECharacterNotFormatted));
  4242 		return ScrollL(iBandTop, EFDisallowScrollingBlankSpace);
  4100 		return ScrollL(iBandTop, EFDisallowScrollingBlankSpace);
  4243 		}
  4101 		}
  4244 	TRect line_rect = info.iOuterRect;
  4102 	TRect line_rect = info.iOuterRect;