2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://floralicense.org/license/
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an AS IS BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file FGrp_TextTextColumn.cpp
20 * @brief This is the implementation file for TextColumn class.
24 #include <FBaseSysLog.h>
25 #include "FGrp_CanvasImpl.h"
26 #include "FGrp_TextCommon.h"
27 #include "FGrp_TextTextComposite.h"
28 #include "FGrp_TextTextLine.h"
29 #include "FGrp_TextTextColumn.h"
30 #include "FGrp_TextTextUtility.h"
32 using namespace Tizen::Base::Utility;
34 namespace Tizen { namespace Graphics
40 struct ChangeActionEventInfo
42 TextColumn::ChangeAction action;
44 int changedTextLength;
47 TextColumn::TextColumn(TextComposite* pCompositeText)
50 __displayLineCount = 0;
51 __firstDisplayLineIndex = 0;
52 __firstDisplayPositionY = -1;
54 __slidingPosition = 0;
55 __pCompositeText = pCompositeText;
56 __textChangeAction = TEXT_CHANGE_INSERT;
57 __setChangeAction = false;
58 __pCachedLineNode = null;
59 __cachedLineIndex = 0;
60 __cachedLinePositionY = 0;
61 __chagedStartTextIndex = 0;
62 __changedTextLength = 0;
63 __changedStartLineIndex = 0;
64 __changedLastLineIndex = 0;
65 __prevLineIndexBeforeChangedStartLine = 0;
66 __nextLineIndexAfterChangedLastLine = 0;
67 __textOffsetOfNextLineAfterChangedLine = 0;
68 __currentLineIndexToAddDuringCompose = 0;
69 __isComposeDone = false;
71 __pLines = new (std::nothrow) SimpleList;
74 TextSimpleList::Init(__pLines);
77 __pTextChangeActionList = new (std::nothrow) SimpleList;
78 if (__pTextChangeActionList)
80 TextSimpleList::Init(__pTextChangeActionList);
83 __pKeepLines = new (std::nothrow) SimpleList;
86 TextSimpleList::Init(__pKeepLines);
90 __insertedLineCountDuringCompose = 0;
93 TextColumn::~TextColumn(void)
104 RemoveAllKeepLines();
109 if (__pTextChangeActionList)
111 RemoveAllChangeActions();
112 delete __pTextChangeActionList;
113 __pTextChangeActionList = null;
118 TextColumn::GetRegion(int textIndex, int textLength, int& width, int& height) const
120 result r = E_SUCCESS;
125 int totalLength = __pCompositeText->GetTextLength();
127 if (textIndex != 0 || textLength != totalLength)
129 return __pCompositeText->GetRegion(textIndex, textLength, width, height);
132 Rectangle lineBounds;
133 SimpleNode* pTextLineNode = null;
134 TextLine* pTextLine = null;
136 pTextLineNode = TextSimpleList::GetFirstNode(__pLines);
137 while (pTextLineNode)
139 pTextLine = static_cast < TextLine* >(pTextLineNode->pObject);
142 , r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
144 lineBounds = pTextLine->GetBounds();
146 width = Math::Max(width, lineBounds.width);
147 height += lineBounds.height;
149 pTextLineNode = pTextLineNode->pNext;
156 TextColumn::GetHeight(int textIndex) const
160 return GetTotalHeight();
163 return __pCompositeText->GetHeight(textIndex);
167 TextColumn::Draw(_CanvasImpl& canvasImpl, Rectangle& displayRect, int startTextIndex, int textLength,
168 const TextObjectAlignment alignment, const TextObjectActionType action)
170 result r = E_SUCCESS;
171 TextLine* pTextLine = null;
172 SimpleNode* pTextLineNode = null;
173 TextObjectActionType lineAction = TEXT_OBJECT_ACTION_TYPE_NONE;
174 Rectangle lineBounds;
176 __displayLineCount = 0;
179 pTextLineNode = TextSimpleList::GetNthNode(__pLines, __firstDisplayLineIndex);
180 if (pTextLineNode == null)
185 pTextLine = static_cast < TextLine* >(pTextLineNode->pObject);
188 , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
190 if (__pLines->nodeCount < pTextLine->GetIndex())
195 lineBounds = pTextLine->GetBounds();
197 if (__firstDisplayPositionY != lineBounds.y)
199 displayRect.y -= __firstDisplayPositionY - lineBounds.y;
200 displayRect.height += __firstDisplayPositionY - lineBounds.y;
201 __displayHeight -= __firstDisplayPositionY - lineBounds.y;
204 while (pTextLineNode != null && 0 <= displayRect.height)
206 if (action == TEXT_OBJECT_ACTION_TYPE_ABBREV)
208 TextLine* pNextTextLine = null;
209 if (pTextLineNode->pNext == null)
211 pNextTextLine = null;
215 pNextTextLine = static_cast < TextLine* >(pTextLineNode->pNext->pObject);
218 if (pNextTextLine == null)
220 if (pTextLine->GetTextOffset() + pTextLine->GetTextLength() < __pCompositeText->GetTextLength())
222 lineAction = TEXT_OBJECT_ACTION_TYPE_ABBREV;
227 Rectangle nextLineBounds;
228 if (__pLines->nodeCount < pNextTextLine->GetIndex())
233 nextLineBounds = pNextTextLine->GetBounds();
234 if (displayRect.height < (lineBounds.height + nextLineBounds.height))
236 lineAction = TEXT_OBJECT_ACTION_TYPE_ABBREV;
241 int lineLength = pTextLine->GetTextLength();
243 TextObjectAlignment horizontalAlignment = (TextObjectAlignment)(alignment & TEXT_ALIGNMASK_HORIZ);
244 r = pTextLine->Draw(canvasImpl, displayRect, 0, lineLength, horizontalAlignment, lineAction);
247 , r, r, "[%s] Propagating.", GetErrorMessage(r));
249 __displayLineCount++;
251 if (lineBounds.height <= displayRect.height)
253 displayRect.height -= lineBounds.height;
254 displayRect.y += lineBounds.height;
255 __displayHeight += lineBounds.height;
259 lineBounds.height += displayRect.height;
263 if (lineAction == TEXT_OBJECT_ACTION_TYPE_ABBREV)
268 pTextLineNode = pTextLineNode->pNext;
269 if (pTextLineNode == null)
274 pTextLine = static_cast < TextLine* >(pTextLineNode->pObject);
277 , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
279 if (__pLines->nodeCount < pTextLine->GetIndex())
284 lineBounds = pTextLine->GetBounds();
291 TextColumn::GetTextLength(void) const
293 return __pCompositeText->GetTextLength();
297 TextColumn::GetLineIndexAtTextIndex(int textIndex) const
299 SimpleNode* pTextLineNode = null;
300 TextLine* pTextLine = null;
304 int lineEndType = TEXT_RETBY_NORMAL;
306 pTextLineNode = TextSimpleList::GetFirstNode(__pLines);
307 if (textIndex == 0 && (pTextLineNode != null))
312 while (pTextLineNode)
314 pTextLine = static_cast < TextLine* >(pTextLineNode->pObject);
317 , -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
319 lineOffset = pTextLine->GetTextOffset();
320 lineLength = pTextLine->GetTextLength();
321 lineEndType = pTextLine->GetEndType();
323 if (lineOffset <= textIndex)
325 if (textIndex < lineOffset + lineLength)
332 pTextLineNode = pTextLineNode->pNext;
335 if (__pCompositeText->GetTextLength() == textIndex)
337 return lineIndex - 1;
344 TextColumn::GetLineIndexAtPositionY(int y)
346 SimpleNode* pTextLineNode = null;
347 TextLine* pTextLine = null;
350 Rectangle lineBounds;
352 if (GetTotalLineCount() == 0)
357 if (__pCachedLineNode == null)
359 pTextLineNode = TextSimpleList::GetFirstNode(__pLines);
360 while (pTextLineNode)
362 pTextLine = static_cast < TextLine* >(pTextLineNode->pObject);
365 , -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
367 lineBounds = pTextLine->GetBounds();
369 if (y >= lineBounds.y && y < lineBounds.y + lineBounds.height)
371 __pCachedLineNode = pTextLineNode;
372 __cachedLineIndex = lineIndex;
373 __cachedLinePositionY = lineBounds.y;
378 pTextLineNode = pTextLineNode->pNext;
383 bool searchForward = true;
385 if (__cachedLinePositionY < y)
387 searchForward = true;
389 else if (y < __cachedLinePositionY)
391 searchForward = false;
395 return __cachedLineIndex;
398 pTextLineNode = __pCachedLineNode;
399 lineIndex = __cachedLineIndex;
400 while (pTextLineNode)
402 pTextLine = static_cast < TextLine* >(pTextLineNode->pObject);
405 , -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
407 lineBounds = pTextLine->GetBounds();
409 if (y >= lineBounds.y && y < lineBounds.y + lineBounds.height)
411 __pCachedLineNode = pTextLineNode;
412 __cachedLineIndex = lineIndex;
413 __cachedLinePositionY = lineBounds.y;
421 pTextLineNode = pTextLineNode->pNext;
426 pTextLineNode = pTextLineNode->pPrev;
435 TextColumn::GetTotalHeight(void) const
437 SimpleNode* pTextLineNode = null;
438 TextLine* pTextLine = null;
439 Rectangle lineBounds;
442 pTextLineNode = TextSimpleList::GetFirstNode(__pLines);
443 while (pTextLineNode)
445 pTextLine = static_cast < TextLine* >(pTextLineNode->pObject);
448 , 0, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
450 lineBounds = pTextLine->GetBounds();
452 height += lineBounds.height;
453 pTextLineNode = pTextLineNode->pNext;
460 TextColumn::GetLineHeightAt(int index) const
462 TextLine* pTextLine = null;
463 pTextLine = static_cast < TextLine* >(TextSimpleList::GetNthObject(__pLines, index));
467 , 0, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
470 lineRect = pTextLine->GetBounds();
472 return lineRect.height;
476 TextColumn::GetTextLengthAt(int lineIndex) const
478 TextLine* pTextLine = null;
480 pTextLine = static_cast < TextLine* >(TextSimpleList::GetNthObject(__pLines, lineIndex));
483 , 0, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
485 return pTextLine->GetTextLength();
489 TextColumn::GetFirstTextIndexAt(int lineIndex) const
491 TextLine* pTextLine = null;
493 pTextLine = static_cast < TextLine* >(TextSimpleList::GetNthObject(__pLines, lineIndex));
496 , 0, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
498 return pTextLine->GetTextOffset();
502 TextColumn::Append(TextLine* pTextLine)
506 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
508 TextSimpleList::AppendObject(__pLines, pTextLine);
515 TextColumn::RemoveAllLines(void)
517 TextLine* pTextLine = null;
521 pTextLine = static_cast < TextLine* >(TextSimpleList::DeleteNthObject(__pLines, 0));
522 if (pTextLine == null)
531 __totalLineCount = 0;
537 TextColumn::Remove(TextLine* pTextLine)
541 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
543 int index = pTextLine->GetIndex();
545 SimpleNode* pNode = TextSimpleList::GetNthNode(__pLines, index);
548 , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get node.");
550 bool r = TextSimpleList::DeleteNode(__pLines, pNode);
562 TextColumn::GetTextLine(int lineIndex) const
565 , 0 <= lineIndex || lineIndex < __totalLineCount
566 , null, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
568 TextLine* pTextLine = static_cast < TextLine* >(TextSimpleList::GetNthObject(__pLines, lineIndex));
574 TextColumn::SetChangeAction(ChangeAction changeAction, int textIndex, int textLength)
577 , changeAction == TEXT_CHANGE_INSERT || changeAction == TEXT_CHANGE_REMOVE || changeAction == TEXT_CHANGE_UNKONWN
578 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
582 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
584 int textIndexBeforeChanged = textIndex;
585 int textLengthBeforeChanged = textLength;
586 int textIndexAfterChanged = 0;
587 int textLengthAfterChanged = 0;
589 ChangeActionEventInfo* pChangeActionEventInfo = null;
590 SimpleNode* pCurrentChangeActionEventInfoNode = null;
591 ChangeActionEventInfo* pCurrentChangeActionEventInfo = null;
592 int currentChangeActionEventInfoIndex = 0;
594 pCurrentChangeActionEventInfoNode = TextSimpleList::GetFirstNode(__pTextChangeActionList);
595 if (pCurrentChangeActionEventInfoNode)
597 pCurrentChangeActionEventInfo = static_cast < ChangeActionEventInfo* >(pCurrentChangeActionEventInfoNode->pObject);
600 while (pCurrentChangeActionEventInfo)
602 bool isLineInserted = false;
603 bool isActionCollapsed = false;
604 ActionProcessResult actionEventResult = DoProcessTextAction(changeAction, textIndexBeforeChanged,
605 textLengthBeforeChanged, pCurrentChangeActionEventInfo, textIndexAfterChanged, textLengthAfterChanged);
607 switch (actionEventResult)
610 isLineInserted = true;
613 case MERGE_AND_BEFORE_ACTION:
614 isLineInserted = true;
615 textLengthBeforeChanged = textLengthAfterChanged;
619 textIndexBeforeChanged = textIndexAfterChanged;
623 textLengthBeforeChanged = -1;
626 case MERGE_AND_AFTER_ACTION:
627 textIndexBeforeChanged = textIndexAfterChanged;
628 textLengthBeforeChanged = textLengthAfterChanged;
631 case COLLAPSE_ACTION:
632 isActionCollapsed = true;
633 textLengthBeforeChanged = textLengthAfterChanged;
640 if (isActionCollapsed)
642 TextSimpleList::DeleteNthObject(__pTextChangeActionList, currentChangeActionEventInfoIndex);
643 delete pCurrentChangeActionEventInfo;
644 pCurrentChangeActionEventInfo = null;
646 if (textLengthBeforeChanged == 0)
648 textLengthBeforeChanged = -1;
652 pCurrentChangeActionEventInfoNode = TextSimpleList::GetNthNode(__pTextChangeActionList,
653 currentChangeActionEventInfoIndex);
654 if (pCurrentChangeActionEventInfoNode)
656 pCurrentChangeActionEventInfo = static_cast < ChangeActionEventInfo* >(pCurrentChangeActionEventInfoNode->pObject);
664 pChangeActionEventInfo = new (std::nothrow)ChangeActionEventInfo;
666 , pChangeActionEventInfo
667 , E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
669 pChangeActionEventInfo->action = changeAction;
670 pChangeActionEventInfo->changedTextIndex = textIndexBeforeChanged;
671 pChangeActionEventInfo->changedTextLength = textLengthBeforeChanged;
672 TextSimpleList::InsertObject(__pTextChangeActionList, pChangeActionEventInfo,
673 currentChangeActionEventInfoIndex);
675 textLengthBeforeChanged = -1;
679 if (textLengthBeforeChanged < 0)
684 pCurrentChangeActionEventInfo = null;
686 currentChangeActionEventInfoIndex++;
687 pCurrentChangeActionEventInfoNode = pCurrentChangeActionEventInfoNode->pNext;
688 if (pCurrentChangeActionEventInfoNode)
690 pCurrentChangeActionEventInfo = static_cast < ChangeActionEventInfo* >(pCurrentChangeActionEventInfoNode->pObject);
694 if (0 <= textLengthBeforeChanged)
696 pChangeActionEventInfo = new (std::nothrow)ChangeActionEventInfo;
698 , pChangeActionEventInfo
699 , E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
701 pChangeActionEventInfo->action = changeAction;
702 pChangeActionEventInfo->changedTextIndex = textIndexBeforeChanged;
703 pChangeActionEventInfo->changedTextLength = textLengthBeforeChanged;
704 TextSimpleList::AppendObject(__pTextChangeActionList, pChangeActionEventInfo);
707 __setChangeAction = true;
713 TextColumn::GetChangedStrStartIndex(void) const
717 , -1, E_INVALID_STATE, "[E_INVALID_STATE] This instance is set change action list yet.");
719 ChangeActionEventInfo* pChangeActionEventInfo = null;
720 pChangeActionEventInfo = static_cast < ChangeActionEventInfo* >(TextSimpleList::GetFirstObject(__pTextChangeActionList));
722 if (pChangeActionEventInfo == null)
727 return pChangeActionEventInfo->changedTextIndex;
731 TextColumn::PrepareCompose(void)
733 __isComposeDone = false;
734 __pCachedLineNode = null;
736 if (!__setChangeAction)
739 __currentLineIndexToAddDuringCompose = 0;
740 __textOffsetOfNextLineAfterChangedLine = -1;
745 result r = E_SUCCESS;
746 int textChangedStartIndex = 0;
747 int textChangedEndIndex = 0;
748 int textChangedLength = 0;
749 bool hasETCAction = false;
751 r = GetTextChangedInfo(textChangedStartIndex, textChangedEndIndex, textChangedLength, hasETCAction);
754 , , r, "[%s] Propagating.", GetErrorMessage(r));
756 r = UpdateCompositionInfo(textChangedStartIndex, textChangedEndIndex, textChangedLength, hasETCAction);
759 , , r, "[%s] Propagating.", GetErrorMessage(r));
761 if (__changedLastLineIndex != -1)
764 , __changedStartLineIndex != -1
765 , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to update information.");
767 int count = __changedLastLineIndex - __changedStartLineIndex + 1;
769 KeepLines( __changedStartLineIndex, count);
770 RemoveLines(__changedStartLineIndex, count);
774 if (__changedStartLineIndex == -1)
777 __currentLineIndexToAddDuringCompose = 0;
781 KeepLines( __prevLineIndexBeforeChangedStartLine, __totalLineCount - __prevLineIndexBeforeChangedStartLine);
783 RemoveLinesFrom(__changedStartLineIndex);
784 __changedLastLineIndex = __changedStartLineIndex;
788 if (__prevLineIndexBeforeChangedStartLine >= 0)
790 __currentLineIndexToAddDuringCompose = __prevLineIndexBeforeChangedStartLine + 1;
794 __currentLineIndexToAddDuringCompose = 0;
801 __currentLineIndexToAddDuringCompose = 0;
802 __textOffsetOfNextLineAfterChangedLine = -1;
803 __nextLineIndexAfterChangedLastLine = -1;
809 TextColumn::AddLineDuringCompose(TextLine* pTextLine)
813 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
815 if (!__setChangeAction)
817 SimpleNode* pTextLineNode = TextSimpleList::InsertObject(__pLines, pTextLine, __currentLineIndexToAddDuringCompose);
818 if (pTextLineNode == null)
826 pTextLine->SetIndex(__currentLineIndexToAddDuringCompose);
827 __currentLineIndexToAddDuringCompose++;
833 TextSimpleList::InsertObject(__pLines, pTextLine, __currentLineIndexToAddDuringCompose);
835 pTextLine->SetIndex(__currentLineIndexToAddDuringCompose);
836 __currentLineIndexToAddDuringCompose++;
837 __insertedLineCountDuringCompose++;
840 if (__textOffsetOfNextLineAfterChangedLine == -1)
845 int lineOffset = pTextLine->GetTextOffset();
846 int lineLength = pTextLine->GetTextLength();
847 int lineEndType = pTextLine->GetEndType();
849 if (lineOffset + lineLength == __textOffsetOfNextLineAfterChangedLine)
851 TextElementType nextObjectType = __pCompositeText->GetObjectType(__textOffsetOfNextLineAfterChangedLine);
853 if (nextObjectType == TEXT_ELEMENT_TYPE_TEXT || nextObjectType == TEXT_ELEMENT_TYPE_CUTLINK ||
854 nextObjectType == TEXT_ELEMENT_TYPE_NONE)
856 if (lineEndType == TEXT_RETBY_LINEFEED)
858 __isComposeDone = true;
863 if (lineEndType == TEXT_RETBY_LINEFEED)
867 __isComposeDone = true;
872 __isComposeDone = true;
881 TextColumn::IsComposeDone(void)
883 return __isComposeDone;
887 TextColumn::FinishCompose(bool isUpdateSweepInfo)
889 __setChangeAction = false;
890 __isComposeDone = true;
892 RemoveAllChangeActions();
894 if (__nextLineIndexAfterChangedLastLine < 0)
896 if (isUpdateSweepInfo)
901 RemoveAllKeepLines();
902 __insertedLineCountDuringCompose = 0;
907 int changedTextLength = __changedTextLength;
909 SimpleNode* pTextLineNode = null;
910 TextLine* pTextLine = null;
911 Rectangle lineBounds;
913 if (__currentLineIndexToAddDuringCompose == 0)
915 if (isUpdateSweepInfo)
920 RemoveAllKeepLines();
921 __insertedLineCountDuringCompose = 0;
926 pTextLineNode = TextSimpleList::GetNthNode(__pLines, __currentLineIndexToAddDuringCompose - 1);
929 , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line node.");
931 pTextLine = static_cast < TextLine* >(pTextLineNode->pObject);
934 , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
936 lineBounds = pTextLine->GetBounds();
937 int nextLineY = lineBounds.y + lineBounds.height;
939 pTextLineNode = TextSimpleList::GetNthNode(__pLines, __currentLineIndexToAddDuringCompose);
941 while (pTextLineNode != null)
943 pTextLine = static_cast < TextLine* >(pTextLineNode->pObject);
946 , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
948 int lineOffset = pTextLine->GetTextOffset();
949 lineOffset += changedTextLength;
950 lineBounds = pTextLine->GetBounds();
951 lineBounds.y = nextLineY;
952 nextLineY += lineBounds.height;
954 pTextLine->SetTextOffset(lineOffset);
955 pTextLine->SetBounds(lineBounds);
956 pTextLine->SetIndex(__currentLineIndexToAddDuringCompose);
957 __currentLineIndexToAddDuringCompose++;
959 pTextLineNode = pTextLineNode->pNext;
962 if (isUpdateSweepInfo)
967 RemoveAllKeepLines();
968 __insertedLineCountDuringCompose = 0;
974 TextColumn::GetPrevLineChangedStartLine(void) const
978 , null, E_INVALID_STATE, "[E_INVALID_STATE] This instance is set change action list yet.");
980 if (__prevLineIndexBeforeChangedStartLine < 0)
985 TextLine* pTextLine = GetTextLine(__prevLineIndexBeforeChangedStartLine);
988 , null, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
990 SetLastResult(E_SUCCESS);
996 TextColumn::RemoveLines(int lineIndex, int lineCount)
999 , 0 <= lineIndex || lineCount <= __totalLineCount
1000 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1002 SimpleNode* pNextTextLineNode = null;
1003 SimpleNode* pTextLineNode = null;
1004 TextLine* pTextLine = null;
1007 pTextLineNode = TextSimpleList::GetNthNode(__pLines, lineIndex);
1009 while ((pTextLineNode != null) && (count < lineCount))
1011 pTextLine = static_cast < TextLine* >(pTextLineNode->pObject);
1012 pNextTextLineNode = pTextLineNode->pNext;
1014 TextSimpleList::DeleteNode(__pLines, pTextLineNode);
1016 if (pTextLine != null)
1023 pTextLineNode = pNextTextLineNode;
1026 __totalLineCount -= count;
1032 TextColumn::GetChangeActionEventCount(void) const
1034 return __pTextChangeActionList->nodeCount;
1038 TextColumn::RemoveLinesFrom(int lineIndex)
1040 SysTryReturn(NID_GRP
1042 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1044 TextLine* pTextLine = null;
1047 pTextLine = static_cast < TextLine* >(TextSimpleList::DeleteNthObject(__pLines, lineIndex));
1051 pTextLine = static_cast < TextLine* >(TextSimpleList::DeleteNthObject(__pLines, lineIndex));
1055 __totalLineCount -= count;
1061 TextColumn::RemoveAllChangeActions(void)
1063 ChangeActionEventInfo* pChangeActionEventInfo = null;
1065 pChangeActionEventInfo = static_cast < ChangeActionEventInfo* >(TextSimpleList::DeleteNthObject(__pTextChangeActionList, 0));
1066 while (pChangeActionEventInfo)
1068 delete pChangeActionEventInfo;
1069 pChangeActionEventInfo = static_cast < ChangeActionEventInfo* >(TextSimpleList::DeleteNthObject(__pTextChangeActionList, 0));
1074 TextColumn::GetTextChangedInfo(int& changedStartTextIndex, int& changedEndTextIndex, int& changedTextLength,
1075 bool& existUnkownAction) const
1077 SimpleNode* pChangeActionEventNode = null;
1078 ChangeActionEventInfo* pChangeActionEventInfo = null;
1080 pChangeActionEventNode = TextSimpleList::GetFirstNode(__pTextChangeActionList);
1081 SysTryReturn(NID_GRP
1082 , pChangeActionEventNode
1083 , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get change action event information node.");
1085 pChangeActionEventInfo = static_cast < ChangeActionEventInfo* >(pChangeActionEventNode->pObject);
1086 SysTryReturn(NID_GRP
1087 , pChangeActionEventInfo
1088 , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get change action event information.");
1090 changedTextLength = 0;
1091 changedStartTextIndex = -1;
1092 changedEndTextIndex = -1;
1093 existUnkownAction = false;
1095 while (pChangeActionEventInfo)
1097 switch (pChangeActionEventInfo->action)
1099 case TEXT_CHANGE_INSERT:
1100 if (changedStartTextIndex == -1)
1102 changedStartTextIndex = pChangeActionEventInfo->changedTextIndex;
1104 changedTextLength += pChangeActionEventInfo->changedTextLength;
1105 changedEndTextIndex = pChangeActionEventInfo->changedTextIndex;
1108 case TEXT_CHANGE_REMOVE:
1109 if (changedStartTextIndex == -1)
1111 changedStartTextIndex = pChangeActionEventInfo->changedTextIndex;
1113 changedTextLength -= pChangeActionEventInfo->changedTextLength;
1114 changedEndTextIndex = pChangeActionEventInfo->changedTextIndex + pChangeActionEventInfo->changedTextLength;
1117 case TEXT_CHANGE_UNKONWN:
1118 existUnkownAction = true;
1119 if (changedStartTextIndex == -1)
1121 changedStartTextIndex = pChangeActionEventInfo->changedTextIndex;
1130 pChangeActionEventNode = pChangeActionEventNode->pNext;
1131 if (pChangeActionEventNode == null)
1136 pChangeActionEventInfo = static_cast < ChangeActionEventInfo* >(pChangeActionEventNode->pObject);
1143 TextColumn::UpdateCompositionInfo(int changedStartTextIndex, int changedEndTextIndex, int changedTextLength,
1144 bool existUnkownAction)
1146 __chagedStartTextIndex = changedStartTextIndex;
1147 __changedTextLength = changedTextLength;
1149 int firstChangedLineIndex = GetLineIndexAtTextIndex(__chagedStartTextIndex);
1150 if (firstChangedLineIndex == -1)
1152 if (__chagedStartTextIndex + __changedTextLength >= __pCompositeText->GetTextLength())
1154 firstChangedLineIndex = __totalLineCount - 1;
1158 firstChangedLineIndex = -1;
1162 __changedStartLineIndex = firstChangedLineIndex;
1164 if (__changedStartLineIndex == -1)
1166 __nextLineIndexAfterChangedLastLine = -1;
1167 __textOffsetOfNextLineAfterChangedLine = -1;
1168 __changedLastLineIndex = -1;
1169 __prevLineIndexBeforeChangedStartLine = -1;
1173 __prevLineIndexBeforeChangedStartLine = __changedStartLineIndex - 1;
1175 if (__changedStartLineIndex == __totalLineCount - 1)
1177 __nextLineIndexAfterChangedLastLine = -1;
1178 __textOffsetOfNextLineAfterChangedLine = -1;
1179 __changedLastLineIndex = -1;
1183 if (existUnkownAction)
1185 __changedLastLineIndex = __totalLineCount - 1;
1186 __nextLineIndexAfterChangedLastLine = -1;
1187 __textOffsetOfNextLineAfterChangedLine = -1;
1191 int lastChangedLineIndex = GetLineIndexAtTextIndex(changedEndTextIndex);
1192 if (lastChangedLineIndex == -1)
1194 __changedLastLineIndex = __totalLineCount - 1;
1195 __nextLineIndexAfterChangedLastLine = -1;
1196 __textOffsetOfNextLineAfterChangedLine = -1;
1200 int nextLineIndexAfterChangedLineCandidate = lastChangedLineIndex;
1202 __nextLineIndexAfterChangedLastLine = -1;
1204 SimpleNode* pTextLineNode = null;
1205 TextLine* pTextLine = null;
1207 pTextLineNode = TextSimpleList::GetNthNode(__pLines, nextLineIndexAfterChangedLineCandidate);
1208 while (pTextLineNode)
1210 pTextLine = static_cast < TextLine* >(pTextLineNode->pObject);
1211 SysTryReturn(NID_GRP
1213 , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
1215 int lineEndType = pTextLine->GetEndType();
1216 if ((lineEndType == TEXT_RETBY_LINEFEED) && (pTextLine->GetTextLength() != 0))
1218 pTextLineNode = pTextLineNode->pNext;
1219 if (pTextLineNode == null)
1224 pTextLine = static_cast < TextLine* >(pTextLineNode->pObject);
1225 SysTryReturn(NID_GRP
1227 , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
1229 __nextLineIndexAfterChangedLastLine = nextLineIndexAfterChangedLineCandidate + 1;
1233 pTextLineNode = pTextLineNode->pNext;
1234 nextLineIndexAfterChangedLineCandidate++;
1237 if (__nextLineIndexAfterChangedLastLine > 0)
1239 __textOffsetOfNextLineAfterChangedLine = pTextLine->GetTextOffset();
1240 __textOffsetOfNextLineAfterChangedLine += __changedTextLength;
1241 __changedLastLineIndex = __nextLineIndexAfterChangedLastLine - 1;
1245 __textOffsetOfNextLineAfterChangedLine = -1;
1246 __changedLastLineIndex = __totalLineCount - 1;
1252 TextColumn::ActionProcessResult
1253 TextColumn::DoProcessTextAction(ChangeAction inputAction, int textIndex, int textLength,
1254 ChangeActionEventInfo* pCurrentStrActionEventInfo, int& changedStartTextIndex,
1255 int& strOutputChangedNum)
1257 switch (inputAction)
1259 case TextColumn::TEXT_CHANGE_INSERT:
1261 switch (pCurrentStrActionEventInfo->action)
1263 case TextColumn::TEXT_CHANGE_INSERT:
1264 return DoProcessInsertThroughInsert(textIndex, textLength, pCurrentStrActionEventInfo,
1265 changedStartTextIndex);
1267 case TextColumn::TEXT_CHANGE_REMOVE:
1268 return DoProcessInsertThroughRemove(textIndex, pCurrentStrActionEventInfo, changedStartTextIndex);
1270 case TextColumn::TEXT_CHANGE_UNKONWN:
1271 changedStartTextIndex = textIndex;
1272 return DoProcessInsertThroughUnkown(textIndex, pCurrentStrActionEventInfo);
1280 case TextColumn::TEXT_CHANGE_REMOVE:
1282 switch (pCurrentStrActionEventInfo->action)
1284 case TextColumn::TEXT_CHANGE_INSERT:
1285 return DoProcessRemoveThroughInsert(textIndex, textLength, pCurrentStrActionEventInfo,
1286 changedStartTextIndex, strOutputChangedNum);
1288 case TextColumn::TEXT_CHANGE_REMOVE:
1289 return DoProcessRemoveThroughRemove(textIndex, pCurrentStrActionEventInfo, changedStartTextIndex);
1291 case TextColumn::TEXT_CHANGE_UNKONWN:
1292 changedStartTextIndex = textIndex;
1293 return DoProcessRemoveThroughUnkown(textIndex, pCurrentStrActionEventInfo);
1301 case TextColumn::TEXT_CHANGE_UNKONWN:
1303 switch (pCurrentStrActionEventInfo->action)
1305 case TextColumn::TEXT_CHANGE_INSERT:
1306 return DoProcessUnkownThroughInsert(textIndex, pCurrentStrActionEventInfo, changedStartTextIndex);
1308 case TextColumn::TEXT_CHANGE_REMOVE:
1309 return DoProcessUnkownThroughRemove(textIndex, pCurrentStrActionEventInfo, changedStartTextIndex);
1311 case TextColumn::TEXT_CHANGE_UNKONWN:
1312 changedStartTextIndex = textIndex;
1313 return DoProcessUnknownThroughUnknown(textIndex, pCurrentStrActionEventInfo);
1325 return ERROR_ACTION;
1328 TextColumn::ActionProcessResult
1329 TextColumn::DoProcessUnknownThroughUnknown(int textIndex, ChangeActionEventInfo* pCurrentActionEventInfo)
1331 if (textIndex < pCurrentActionEventInfo->changedTextIndex)
1333 return BEFORE_ACTION;
1335 else if (textIndex == pCurrentActionEventInfo->changedTextIndex)
1337 return MERGE_ACTION;
1341 return AFTER_ACTION;
1345 TextColumn::ActionProcessResult
1346 TextColumn::DoProcessUnkownThroughInsert(int textIndex, ChangeActionEventInfo* pCurrentActionEventInfo,
1347 int& changedStartTextIndex)
1349 if (textIndex < pCurrentActionEventInfo->changedTextIndex)
1351 changedStartTextIndex = textIndex;
1352 return BEFORE_ACTION;
1355 if (textIndex < pCurrentActionEventInfo->changedTextIndex + pCurrentActionEventInfo->changedTextLength)
1357 changedStartTextIndex = pCurrentActionEventInfo->changedTextIndex;
1358 return BEFORE_ACTION;
1361 changedStartTextIndex = textIndex - pCurrentActionEventInfo->changedTextLength;
1362 return AFTER_ACTION;
1365 TextColumn::ActionProcessResult
1366 TextColumn::DoProcessUnkownThroughRemove(int textIndex, ChangeActionEventInfo* pCurrentActionEventInfo,
1367 int& changedStartTextIndex)
1369 if (textIndex < pCurrentActionEventInfo->changedTextIndex)
1371 changedStartTextIndex = textIndex;
1372 return BEFORE_ACTION;
1375 changedStartTextIndex = textIndex + pCurrentActionEventInfo->changedTextLength;
1376 return AFTER_ACTION;
1379 TextColumn::ActionProcessResult
1380 TextColumn::DoProcessInsertThroughUnkown(int textIndex, ChangeActionEventInfo* pCurrentActionEventInfo)
1382 if (textIndex < pCurrentActionEventInfo->changedTextIndex)
1384 return BEFORE_ACTION;
1387 return AFTER_ACTION;
1390 TextColumn::ActionProcessResult
1391 TextColumn::DoProcessInsertThroughInsert(int textIndex, int textLength, ChangeActionEventInfo* pCurrentActionEventInfo,
1392 int& changedStartTextIndex)
1394 if (textIndex < pCurrentActionEventInfo->changedTextIndex)
1396 return BEFORE_ACTION;
1399 if (textIndex <= pCurrentActionEventInfo->changedTextIndex + pCurrentActionEventInfo->changedTextLength)
1401 pCurrentActionEventInfo->changedTextLength += textLength;
1402 return MERGE_ACTION;
1405 changedStartTextIndex = textIndex - pCurrentActionEventInfo->changedTextLength;
1406 return AFTER_ACTION;
1409 TextColumn::ActionProcessResult
1410 TextColumn::DoProcessInsertThroughRemove(int textIndex, ChangeActionEventInfo* pCurrentActionEventInfo,
1411 int& changedStartTextIndex)
1413 if (textIndex < pCurrentActionEventInfo->changedTextIndex)
1415 return BEFORE_ACTION;
1418 changedStartTextIndex = textIndex + pCurrentActionEventInfo->changedTextLength;
1419 return AFTER_ACTION;
1422 TextColumn::ActionProcessResult
1423 TextColumn::DoProcessRemoveThroughUnkown(int textIndex, ChangeActionEventInfo* pCurrentActionEventInfo)
1425 if (textIndex < pCurrentActionEventInfo->changedTextIndex)
1427 return BEFORE_ACTION;
1430 return AFTER_ACTION;
1433 TextColumn::ActionProcessResult
1434 TextColumn::DoProcessRemoveThroughInsert(int textIndex, int textLength,
1435 ChangeActionEventInfo* pCurrentActionEventInfo, int& changedStartTextIndex,
1436 int& strOutputChangedNum)
1438 if (textIndex + textLength <= pCurrentActionEventInfo->changedTextIndex)
1440 return BEFORE_ACTION;
1443 if (textIndex >= pCurrentActionEventInfo->changedTextIndex + pCurrentActionEventInfo->changedTextLength)
1445 changedStartTextIndex = textIndex - pCurrentActionEventInfo->changedTextLength;
1447 return AFTER_ACTION;
1450 if ((textIndex <= pCurrentActionEventInfo->changedTextIndex) &&
1451 (textIndex + textLength >= pCurrentActionEventInfo->changedTextIndex +
1452 pCurrentActionEventInfo->changedTextLength))
1454 changedStartTextIndex = textIndex;
1455 strOutputChangedNum = textLength - pCurrentActionEventInfo->changedTextLength;
1457 return COLLAPSE_ACTION;
1460 if ((textIndex >= pCurrentActionEventInfo->changedTextIndex) &&
1461 (textIndex + textLength <= pCurrentActionEventInfo->changedTextIndex +
1462 pCurrentActionEventInfo->changedTextLength))
1464 pCurrentActionEventInfo->changedTextLength -= textLength;
1465 return MERGE_ACTION;
1468 if ((textIndex < pCurrentActionEventInfo->changedTextIndex) &&
1469 (textIndex + textLength > pCurrentActionEventInfo->changedTextIndex))
1471 int mergedLength = textIndex + textLength - pCurrentActionEventInfo->changedTextIndex;
1472 pCurrentActionEventInfo->changedTextLength -= mergedLength;
1473 strOutputChangedNum -= mergedLength;
1474 return MERGE_AND_BEFORE_ACTION;
1477 if ((textIndex >= pCurrentActionEventInfo->changedTextIndex) &&
1478 (textIndex < pCurrentActionEventInfo->changedTextIndex + pCurrentActionEventInfo->changedTextLength))
1480 int mergedLength = pCurrentActionEventInfo->changedTextIndex + pCurrentActionEventInfo->changedTextLength
1482 pCurrentActionEventInfo->changedTextLength -= mergedLength;
1483 changedStartTextIndex = textIndex + 1;
1484 strOutputChangedNum -= mergedLength;
1485 return MERGE_AND_AFTER_ACTION;
1488 return ERROR_ACTION;
1491 TextColumn::ActionProcessResult
1492 TextColumn::DoProcessRemoveThroughRemove(int textIndex, ChangeActionEventInfo* pCurrentActionEventInfo,
1493 int& changedStartTextIndex)
1495 if (textIndex < pCurrentActionEventInfo->changedTextIndex)
1497 return BEFORE_ACTION;
1500 changedStartTextIndex += pCurrentActionEventInfo->changedTextLength;
1501 return AFTER_ACTION;
1505 TextColumn::GetTotalLineCount(void) const
1507 return __totalLineCount;
1511 TextColumn::GetDisplayLineCount(void) const
1513 return __displayLineCount;
1517 TextColumn::SetDisplayLineCount(int displayLineCount)
1519 __displayLineCount = displayLineCount;
1523 TextColumn::SetFirstDisplayLineIndex(int lineIndex)
1525 __firstDisplayLineIndex = lineIndex;
1529 TextColumn::GetFirstDisplayLineIndex(void) const
1531 return __firstDisplayLineIndex;
1535 TextColumn::SetFirstDisplayPositionY(int y)
1537 __firstDisplayPositionY = y;
1541 TextColumn::GetFirstDisplayPositionY(void) const
1543 return __firstDisplayPositionY;
1547 TextColumn::SetDisplayHeight(int height)
1549 __displayHeight = height;
1553 TextColumn::GetDisplayHeight(void) const
1555 return __displayHeight;
1559 TextColumn::GetTextLineNode(int lineIndex) const
1561 return TextSimpleList::GetNthNode(__pLines, lineIndex);
1565 TextColumn::SetSlidingDimension(Dimension& slidingDimension)
1567 SysTryReturn(NID_GRP
1568 , slidingDimension.width >= 0 && slidingDimension.height >=0
1569 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1571 __slidingDimension = slidingDimension;
1577 TextColumn::GetSlidingDimension(void) const
1579 return __slidingDimension;
1583 TextColumn::SetSlidingPosition(int slidingPosition)
1585 __slidingPosition = slidingPosition;
1589 TextColumn::GetSlidingPosition(void) const
1591 return __slidingPosition;
1595 TextColumn::SetChangedStartLineIndex(int changedStartLineIndex)
1597 __changedStartLineIndex = changedStartLineIndex;
1601 TextColumn::GetChangedStartLineIndex(void) const
1603 return __changedStartLineIndex;
1607 TextColumn::SetChangedLastLineIndex(int changedLastLineIndex)
1609 __changedLastLineIndex = changedLastLineIndex;
1613 TextColumn::GetChangedLastLineIndex(void) const
1615 return __changedLastLineIndex;
1619 TextColumn::ForwardAnalyze(int startTextIndex, int textLength, int maxWidth, TextObjectWrapType wrap,
1620 int& actualLength, int& width, int& height)
1626 TextColumn::RemoveAllKeepLines(void)
1628 SysTryReturn(NID_GRP
1630 , E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] This instance is not constructed yet.");
1632 TextLine* pTextLine = null;
1636 pTextLine = static_cast < TextLine* >(TextSimpleList::DeleteNthObject(__pKeepLines, 0));
1637 if (pTextLine == null)
1646 __keepLineCount = 0;
1652 TextColumn::UpdateSweepInfoFirstLine(void)
1654 TextObjectSweepInfo textSweepInfo;
1655 __pCompositeText->GetTextSweepInfo(textSweepInfo);
1659 SimpleNode* pTextLineNode = null;
1660 TextLine* pTextLine;
1661 int sweepLineCount = 0;
1662 int insertedLineCount = 0;
1664 pTextLineNode = TextSimpleList::GetFirstNode(__pLines);
1666 while (pTextLineNode != null)
1668 pTextLine = static_cast < TextLine* >(pTextLineNode->pObject);
1669 pTextLine->GetRegion(0, pTextLine->GetTextLength(), lineSize.width, lineSize.height);
1670 width += lineSize.width;
1672 insertedLineCount++;
1674 pTextLineNode = pTextLineNode->pNext;
1677 textSweepInfo.isValid = true;
1678 textSweepInfo.sweepType = ((1 < sweepLineCount) ? TEXT_OBJECT_SWEEP_TYPE_FORWARD : TEXT_OBJECT_SWEEP_TYPE_KEYINPUT);
1679 textSweepInfo.anchorLineIndex = 0;
1680 textSweepInfo.sweepRegionStartLineIndex = 0;
1681 textSweepInfo.sweepRegionLineCount = sweepLineCount;
1682 textSweepInfo.widthChanged = width;
1683 textSweepInfo.insertedLineCount = insertedLineCount;
1684 textSweepInfo.deletedLineCount = 0;
1686 __pCompositeText->UpdateTextSweepInfo(&textSweepInfo);
1692 TextColumn::UpdateSweepInfo(void)
1694 if (TextSimpleList::IsEmpty(__pKeepLines))
1696 return UpdateSweepInfoFirstLine();
1699 TextObjectSweepInfo textSweepInfo;
1700 __pCompositeText->GetTextSweepInfo(textSweepInfo);
1702 SimpleNode* pOldTextLineNode = null;
1703 SimpleNode* pNewTextLineNode = null;
1704 TextLine* pOldTextLine = null;
1705 TextLine* pNewTextLine = null;
1706 Dimension oldLineSize;
1707 Dimension newLineSize;
1708 int oldLineWidth = 0;
1709 int newLineWidth = 0;
1710 int sweepLineCount = 0;
1711 int changedStartLineIndex = 0;
1712 int insertedLineCount = 0;
1713 int deleteLineCount = 0;
1715 int anchorLineIndex = GetLineIndexAtTextIndex(textSweepInfo.anchorTextIndex);
1716 if (anchorLineIndex == -1)
1718 anchorLineIndex = GetTotalLineCount() - 1;
1721 int widthChanged = 0;
1722 TextObjectSweepType sweepType = TEXT_OBJECT_SWEEP_TYPE_INVALID;
1724 pOldTextLineNode = TextSimpleList::GetFirstNode(__pKeepLines);
1725 if (pOldTextLineNode == null)
1730 pOldTextLine = static_cast < TextLine* >(pOldTextLineNode->pObject);
1731 changedStartLineIndex = pOldTextLine->GetIndex();
1732 pNewTextLineNode = TextSimpleList::GetNthNode(__pLines, changedStartLineIndex);
1734 while (pOldTextLineNode || pNewTextLineNode)
1736 TextObjectSweepComposeLineInfo textSweepComposeLineInfo;
1738 if (pOldTextLineNode == null)
1740 pNewTextLine = static_cast < TextLine* >(pNewTextLineNode->pObject);
1742 if (pNewTextLine->GetIndex() >= changedStartLineIndex + __insertedLineCountDuringCompose)
1747 pNewTextLine->GetRegion(0, pNewTextLine->GetTextLength(), newLineSize.width, newLineSize.height);
1749 newLineWidth += newLineSize.width;
1751 insertedLineCount++;
1753 textSweepComposeLineInfo.isValid = true;
1754 textSweepComposeLineInfo.prevLineTextOffset = 0;
1755 textSweepComposeLineInfo.prevLineTextLength = 0;
1756 textSweepComposeLineInfo.prevLineWidth = 0;
1757 textSweepComposeLineInfo.currentLineTextOffset = pNewTextLine->GetTextOffset();
1758 textSweepComposeLineInfo.currentLineTextLength = pNewTextLine->GetTextLength();
1759 textSweepComposeLineInfo.currentLineWidth = newLineSize.width;
1761 pNewTextLine->SetSweepComposeInfo(textSweepComposeLineInfo);
1763 sweepType = TEXT_OBJECT_SWEEP_TYPE_FORWARD;
1765 pNewTextLineNode = pNewTextLineNode->pNext;
1767 else if (pNewTextLineNode == null)
1769 pOldTextLine = static_cast < TextLine* >(pOldTextLineNode->pObject);
1770 pOldTextLine->GetRegion(0, pOldTextLine->GetTextLength(), oldLineSize.width, oldLineSize.height);
1772 oldLineWidth += oldLineSize.width;
1775 sweepType = TEXT_OBJECT_SWEEP_TYPE_BACKWARD;
1777 pOldTextLineNode = pOldTextLineNode->pNext;
1781 pOldTextLine = static_cast < TextLine* >(pOldTextLineNode->pObject);
1782 pNewTextLine = static_cast < TextLine* >(pNewTextLineNode->pObject);
1784 if (pNewTextLine->GetIndex() > changedStartLineIndex + __insertedLineCountDuringCompose)
1786 pOldTextLine->GetRegion(0, pOldTextLine->GetTextLength(), oldLineSize.width, oldLineSize.height);
1788 oldLineWidth += oldLineSize.width;
1791 sweepType = TEXT_OBJECT_SWEEP_TYPE_BACKWARD;
1793 pOldTextLineNode = pOldTextLineNode->pNext;
1794 pNewTextLineNode = pNewTextLineNode->pNext;
1799 pOldTextLine->GetRegion(0, pOldTextLine->GetTextLength(), oldLineSize.width, oldLineSize.height);
1800 pNewTextLine->GetRegion(0, pNewTextLine->GetTextLength(), newLineSize.width, newLineSize.height);
1802 if ((oldLineSize.width == newLineSize.width) && (pOldTextLine->GetTextLength() == pNewTextLine->GetTextLength()))
1804 if (pNewTextLine->GetIndex() == changedStartLineIndex)
1806 changedStartLineIndex++;
1815 oldLineWidth += oldLineSize.width;
1816 newLineWidth += newLineSize.width;
1819 textSweepComposeLineInfo.isValid = true;
1820 textSweepComposeLineInfo.prevLineTextOffset = pOldTextLine->GetTextOffset();
1821 textSweepComposeLineInfo.prevLineTextLength = pOldTextLine->GetTextLength();
1822 textSweepComposeLineInfo.prevLineWidth = oldLineSize.width;
1823 textSweepComposeLineInfo.currentLineTextOffset = pNewTextLine->GetTextOffset();
1824 textSweepComposeLineInfo.currentLineTextLength = pNewTextLine->GetTextLength();
1825 textSweepComposeLineInfo.currentLineWidth = newLineSize.width;
1826 pNewTextLine->SetSweepComposeInfo(textSweepComposeLineInfo);
1829 pOldTextLineNode = pOldTextLineNode->pNext;
1830 pNewTextLineNode = pNewTextLineNode->pNext;
1834 widthChanged = newLineWidth - oldLineWidth;
1836 if (sweepLineCount == 1)
1838 sweepType = TEXT_OBJECT_SWEEP_TYPE_KEYINPUT;
1841 if (sweepType == TEXT_OBJECT_SWEEP_TYPE_INVALID)
1843 sweepType = ((oldLineSize.width < newLineSize.width) ? TEXT_OBJECT_SWEEP_TYPE_FORWARD : TEXT_OBJECT_SWEEP_TYPE_BACKWARD);
1846 if (anchorLineIndex == -1)
1848 anchorLineIndex = pNewTextLine->GetIndex();
1851 textSweepInfo.isValid = true;
1852 textSweepInfo.sweepType = sweepType;
1853 textSweepInfo.anchorLineIndex = anchorLineIndex;
1854 textSweepInfo.sweepRegionStartLineIndex = changedStartLineIndex;
1855 textSweepInfo.sweepRegionLineCount = sweepLineCount;
1856 textSweepInfo.widthChanged = widthChanged;
1857 textSweepInfo.insertedLineCount = insertedLineCount;
1858 textSweepInfo.deletedLineCount = deleteLineCount;
1860 __pCompositeText->UpdateTextSweepInfo(&textSweepInfo);
1866 TextColumn::KeepLines(int lineIndex, int lineCount)
1868 SimpleNode* pTextLineNode = null;
1869 SimpleNode* pNextTextLineNode = null;
1870 TextLine* pTextLine = null;
1871 TextLine* pKeepTextLine = null;
1872 int deletedLineCount = 0;
1880 pTextLineNode = TextSimpleList::GetNthNode(__pLines, lineIndex);
1882 while ((pTextLineNode != null) && (deletedLineCount < lineCount))
1884 pTextLine = static_cast < TextLine* >(pTextLineNode->pObject);
1885 pKeepTextLine = pTextLine->CopyN();
1887 pNextTextLineNode = pTextLineNode->pNext;
1889 TextSimpleList::AppendObject(__pKeepLines, pKeepTextLine);
1893 pTextLineNode = pNextTextLineNode;
1896 __keepLineCount += deletedLineCount;
1902 TextColumn::SetKeyInputLine(int changedStartlineIndex, int lineCount)
1904 int keyInputTextIndex = 0;
1905 int keyInputTextLength = 0;
1907 SimpleNode* pTextLineNode = null;
1908 TextLine* pTextLine = null;
1909 int changedLineCount = lineCount;
1911 __pCompositeText->GetRange(keyInputTextIndex, keyInputTextLength);
1913 pTextLineNode = TextSimpleList::GetNthNode(__pLines, changedStartlineIndex);
1914 while (pTextLineNode != null && changedLineCount)
1916 pTextLine = static_cast < TextLine* >(pTextLineNode->pObject);
1918 if (pTextLine->GetTextOffset() <= keyInputTextIndex && keyInputTextIndex < pTextLine->GetTextOffset() + pTextLine->GetTextLength())
1920 pTextLine->NotifyLineChanged(true);
1921 pTextLine->SetKeyInputOffset(keyInputTextIndex - pTextLine->GetTextOffset());
1922 pTextLine->SetKeyInputLength(keyInputTextLength);
1929 pTextLineNode = pTextLineNode->pNext;
1936 TextColumn::CompareDeletedLine(void)
1938 result r = E_SUCCESS;
1940 SimpleNode* pOldTextLineNode = null;
1941 SimpleNode* pNewTextLineNode = null;
1942 TextLine* pOldTextLine = null;
1943 TextLine* pNewTextLine = null;
1945 Dimension newLineSize;
1946 Dimension oldLineSize;
1947 int sweepResult = 0;
1950 int prevLineSweepIn = 0;
1951 int prevLineSweepOut = 0;
1952 int changedStartLineIndex = 0;
1953 int keyInputWidth = 0;
1955 if (TextSimpleList::GetCount(__pKeepLines) == 0)
1957 return E_SUCCESS; // E_SUCCESS right??
1960 keyInputWidth = __pCompositeText->GetWorkWidth();
1961 pOldTextLineNode = TextSimpleList::GetFirstNode(__pKeepLines);
1962 SysTryReturn(NID_GRP
1964 , E_SYSTEM, E_SYSTEM
1965 , "[E_SYSTEM] Fail to get text line node.");
1967 pOldTextLine = static_cast < TextLine* >(pOldTextLineNode->pObject);
1968 changedStartLineIndex = pOldTextLine->GetIndex();
1969 pNewTextLineNode = TextSimpleList::GetNthNode(__pLines, changedStartLineIndex);
1970 SysTryReturn(NID_GRP
1972 , E_INVALID_STATE, E_INVALID_STATE
1973 , "[E_INVALID_STATE] This instance is not constructed yet. changedStartLineIndex = %d", changedStartLineIndex);
1975 r = SetKeyInputLine(changedStartLineIndex, TextSimpleList::GetCount(__pLines) - changedStartLineIndex);
1976 SysTryReturn(NID_GRP
1978 , r, r, "[%s] Propagating.", GetErrorMessage(r));
1980 pOldTextLine = static_cast < TextLine* >(pOldTextLineNode->pObject);
1981 pNewTextLine = static_cast < TextLine* >(pNewTextLineNode->pObject);
1983 pOldTextLine->GetRegion(0, pOldTextLine->GetTextLength(), oldLineSize.width, oldLineSize.height);
1984 pNewTextLine->GetRegion(0, pNewTextLine->GetTextLength(), newLineSize.width, newLineSize.height);
1987 if (oldLineSize.width == newLineSize.width)
1989 sweepResult = NOT_CHANGED;
1991 pNewTextLine->SetKeyInputResult(sweepResult);
1992 pNewTextLine->SetSweepIn(0);
1993 pNewTextLine->SetSweepOut(0);
1995 pOldTextLineNode = pOldTextLineNode->pNext;
1996 pNewTextLineNode = pNewTextLineNode->pNext;
1998 if (pOldTextLineNode && pNewTextLineNode)
2001 pOldTextLine = static_cast < TextLine* >(pOldTextLineNode->pObject);
2002 pNewTextLine = static_cast < TextLine* >(pNewTextLineNode->pObject);
2004 pOldTextLine->GetRegion(0, pOldTextLine->GetTextLength(), oldLineSize.width, oldLineSize.height);
2005 pNewTextLine->GetRegion(0, pNewTextLine->GetTextLength(), newLineSize.width, newLineSize.height);
2007 if (0 < keyInputWidth)
2009 sweepResult = FORWARD_SWEEP;
2012 sweepOut = oldLineSize.width - newLineSize.width;
2013 if (pNewTextLine->isChanged())
2015 sweepOut += keyInputWidth;
2018 pNewTextLine->SetKeyInputResult(sweepResult);
2019 pNewTextLine->SetSweepIn(sweepIn);
2020 pNewTextLine->SetSweepOut(sweepOut);
2024 sweepResult = BACKWARD_SWEEP;
2026 sweepIn = newLineSize.width - oldLineSize.width;
2028 if (pNewTextLine->isChanged())
2030 sweepIn -= keyInputWidth;
2033 pNewTextLine->SetKeyInputResult(sweepResult);
2034 pNewTextLine->SetSweepIn(sweepIn);
2035 pNewTextLine->SetSweepOut(sweepOut);
2039 else if (oldLineSize.width < newLineSize.width)
2041 sweepResult = BACKWARD_SWEEP;
2043 sweepIn = newLineSize.width - oldLineSize.width;
2045 if (pNewTextLine->isChanged())
2047 sweepIn -= keyInputWidth;
2050 pNewTextLine->SetKeyInputResult(sweepResult);
2051 pNewTextLine->SetSweepIn(sweepIn);
2052 pNewTextLine->SetSweepOut(sweepOut);
2056 sweepResult = FORWARD_SWEEP;
2059 sweepOut = oldLineSize.width - newLineSize.width;
2060 if (pNewTextLine->isChanged())
2062 sweepOut += keyInputWidth;
2065 pNewTextLine->SetKeyInputResult(sweepResult);
2066 pNewTextLine->SetSweepIn(sweepIn);
2067 pNewTextLine->SetSweepOut(sweepOut);
2070 pOldTextLineNode = TextSimpleList::GetFirstNode(__pKeepLines);
2071 SysTryReturn(NID_GRP
2073 , E_SYSTEM, E_SYSTEM
2074 , "[E_SYSTEM] Fail to get text line node.");
2076 pNewTextLineNode = TextSimpleList::GetNthNode(__pLines, changedStartLineIndex);
2077 SysTryReturn(NID_GRP
2079 , E_SYSTEM, E_SYSTEM
2080 , "[E_SYSTEM] Fail to get text line node.");
2082 prevLineSweepIn = pNewTextLine->GetSweepIn();
2083 prevLineSweepOut = pNewTextLine->GetSweepOut();
2085 pOldTextLineNode = pOldTextLineNode->pNext;
2086 pNewTextLineNode = pNewTextLineNode->pNext;
2088 switch (sweepResult)
2090 case BACKWARD_SWEEP:
2091 while (pOldTextLineNode != null && pNewTextLineNode != null)
2093 pOldTextLine = static_cast < TextLine* >(pOldTextLineNode->pObject);
2094 pNewTextLine = static_cast < TextLine* >(pNewTextLineNode->pObject);
2096 pOldTextLine->GetRegion(0, pOldTextLine->GetTextLength(), oldLineSize.width, oldLineSize.height);
2097 pNewTextLine->GetRegion(0, pNewTextLine->GetTextLength(), newLineSize.width, newLineSize.height);
2099 if (oldLineSize.width == newLineSize.width)
2101 if (pOldTextLine->GetTextLength() == pNewTextLine->GetTextLength())
2103 pNewTextLine->SetKeyInputResult(NOT_CHANGED);
2104 pNewTextLine->SetSweepIn(0);
2105 pNewTextLine->SetSweepOut(0);
2111 sweepIn = newLineSize.width - oldLineSize.width + prevLineSweepIn;
2112 sweepOut = prevLineSweepIn;
2114 if (pNewTextLine->isChanged())
2116 sweepIn -= keyInputWidth;
2119 pNewTextLine->SetKeyInputResult(BACKWARD_SWEEP);
2120 pNewTextLine->SetSweepIn(sweepIn);
2121 pNewTextLine->SetSweepOut(sweepOut);
2123 prevLineSweepIn = pNewTextLine->GetSweepIn();
2124 pOldTextLineNode = pOldTextLineNode->pNext;
2125 pNewTextLineNode = pNewTextLineNode->pNext;
2131 while (pNewTextLineNode != null)
2133 if (pOldTextLineNode == null)
2135 pNewTextLine = static_cast < TextLine* >(pNewTextLineNode->pObject);
2137 pNewTextLine->SetKeyInputResult(FORWARD_SWEEP);
2138 pNewTextLine->SetSweepIn(prevLineSweepOut);
2139 pNewTextLine->SetSweepOut(0);
2144 pOldTextLine = static_cast < TextLine* >(pOldTextLineNode->pObject);
2145 pNewTextLine = static_cast < TextLine* >(pNewTextLineNode->pObject);
2147 pOldTextLine->GetRegion(0, pOldTextLine->GetTextLength(), oldLineSize.width, oldLineSize.height);
2148 pNewTextLine->GetRegion(0, pNewTextLine->GetTextLength(), newLineSize.width, newLineSize.height);
2150 if (oldLineSize.width == newLineSize.width)
2152 if (pOldTextLine->GetTextLength() == pNewTextLine->GetTextLength())
2154 pNewTextLine->SetKeyInputResult(NOT_CHANGED);
2155 pNewTextLine->SetSweepIn(0);
2156 pNewTextLine->SetSweepOut(0);
2162 sweepIn = prevLineSweepOut;
2163 sweepOut = oldLineSize.width - newLineSize.width + prevLineSweepOut;
2165 if (pNewTextLine->isChanged())
2167 sweepOut += keyInputWidth;
2170 pNewTextLine->SetKeyInputResult(FORWARD_SWEEP);
2171 pNewTextLine->SetSweepIn(sweepIn);
2172 pNewTextLine->SetSweepOut(sweepOut);
2174 prevLineSweepOut = pNewTextLine->GetSweepOut();
2175 pOldTextLineNode = pOldTextLineNode->pNext;
2176 pNewTextLineNode = pNewTextLineNode->pNext;
2190 }}} // Tizen::Graphics::Text