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