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