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 |
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; |