Tizen 2.1 base
[framework/osp/uifw.git] / src / graphics / text / FGrp_TextTextObject.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 //     http://floralicense.org/license/
10 //
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.
16 //
17
18 /*
19  * @file        FGrp_TextTextObject.cpp
20  * @brief       This is the implementation file for TextObject class.
21  */
22
23 #include <new>
24 #include <FGrpBitmap.h>
25 #include <FBaseSysLog.h>
26 #include "FGrp_FontImpl.h"
27 #include "../FGrp_Font.h"
28 #include "../FGrp_Canvas.h"
29 #include "../FGrp_ResUtil.h"
30 #include "FGrp_TextTextObject.h"
31 #include "FGrp_TextTextElement.h"
32 #include "FGrp_TextTextSimple.h"
33 #include "FGrp_TextTextImage.h"
34 #include "FGrp_TextTextCutLink.h"
35 #include "FGrp_TextTextComposite.h"
36 #include "FGrp_TextTextLine.h"
37 #include "FGrp_TextTextColumn.h"
38 #include "FGrp_TextTextUtility.h"
39 #include "FGrp_TextTextWidthManager.h"
40 #include "FGrp_Screen.h"
41
42 #define IF_NOT_CONSTRUCTED(code) if (this->__pCompositeText == null || this->__pTextColumn == null) \
43         { \
44                 code; \
45         }
46
47 using namespace Tizen::Base::Utility;
48 using namespace Tizen::Base;
49
50 namespace Tizen { namespace Graphics
51 {
52
53 namespace _Text
54 {
55
56 TextObject::TextObject(void)
57 {
58         __action = TEXT_OBJECT_ACTION_TYPE_NONE;
59         __align = (TextObjectAlignment)(TEXT_OBJECT_ALIGNMENT_LEFT | TEXT_OBJECT_ALIGNMENT_TOP);
60         __wrap = TEXT_OBJECT_WRAP_TYPE_NONE;
61         __isActionOn = false;
62         __isChanged = false;
63         __pCompositeText = null;
64         __pDefaultFont = null;
65         __defaultForegroundColor = Color::GetColor(COLOR_ID_BLACK);
66         __defaultBackgroundColor = Color::GetColor(COLOR_ID_WHITE);
67         __defaultOutlineColor = Color::GetColor(COLOR_ID_WHITE);
68         __isAlternateLookEnabled = false;
69         __pTextColumn = null;
70         __textObjectEllipsisType = TEXT_OBJECT_ELLIPSIS_TYPE_TAIL;
71         __isFirstDisplayPositionYChanged = false;
72         __rect.x = 0;
73         __rect.y = 0;
74         __rect.width = 0;
75         __rect.height = 0;
76         __pcRect.x = 0;
77         __pcRect.y = 0;
78         __pcRect.width = 0;
79         __pcRect.height = 0;
80         __slidingGap = 30;
81         __slidingStep = 2;
82         __pTextWidthManager = null;
83         __linkViewModeEnabled = false;
84         __isUrlLinkColorDefined = false;
85         __isEmailLinkColorDefined = false;
86         __isPhoneNumberLinkColorDefined = false;
87         __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_URL_NORMAL] = Color::GetColor(COLOR_ID_BLUE);
88         __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_URL_SELECT] = Color::GetColor(COLOR_ID_BLUE);
89         __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_EMAIL_NORMAL] = Color::GetColor(COLOR_ID_BLUE);
90         __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_EMAIL_SELECT] = Color::GetColor(COLOR_ID_BLUE);
91         __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_PHONE_NUMBER_NORMAL] = Color::GetColor(COLOR_ID_BLUE);
92         __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_PHONE_NUMBER_SELECT] = Color::GetColor(COLOR_ID_BLUE);
93
94         __sweepInfo.isValid = false;
95         __sweepInfo.sweepType = TEXT_OBJECT_SWEEP_TYPE_NONE;
96         __sweepInfo.sweepEventType = TEXT_OBJECT_SWEEP_EVENT_INSERT;
97         __sweepInfo.anchorTextIndex = 0;
98         __sweepInfo.anchorLineIndex = 0;
99         __sweepInfo.prevAnchorLineIndex = 0;
100         __sweepInfo.sweepRegionStartLineIndex = 0;
101         __sweepInfo.sweepRegionLineCount = 0;
102         __sweepInfo.insertedLineCount = 0;
103         __sweepInfo.deletedLineCount = 0;
104         __sweepInfo.widthChanged = 0;
105 }
106
107 TextObject::~TextObject(void)
108 {
109         if (__pCompositeText)
110         {
111                 delete __pCompositeText;
112                 __pCompositeText = null;
113         }
114
115         if (__pTextColumn)
116         {
117                 delete __pTextColumn;
118                 __pTextColumn = null;
119         }
120
121         if (__pTextWidthManager)
122         {
123                 delete __pTextWidthManager;
124                 __pTextWidthManager = null;
125         }
126
127         if (__pDefaultFont)
128         {
129                 delete __pDefaultFont;
130                 __pDefaultFont = null;
131         }
132 }
133
134 result
135 TextObject::Construct(void)
136 {
137         result r = E_SUCCESS;
138
139         __action = TEXT_OBJECT_ACTION_TYPE_NONE;
140         __align = (TextObjectAlignment)(TEXT_OBJECT_ALIGNMENT_LEFT | TEXT_OBJECT_ALIGNMENT_TOP);
141         __wrap = TEXT_OBJECT_WRAP_TYPE_WORD;
142         __isActionOn = false;
143         __isChanged = false;
144         __defaultForegroundColor = Color::GetColor(COLOR_ID_BLACK);
145         __defaultBackgroundColor = Color::GetColor(COLOR_ID_WHITE);
146         __defaultOutlineColor = Color::GetColor(COLOR_ID_WHITE);
147         __slidingStep = 2;
148         __isAlternateLookEnabled = false;
149         __linkViewModeEnabled = false;
150         __pTextWidthManager = null;
151
152         __pCompositeText = new (std::nothrow)TextComposite();
153         SysTryCatch(NID_GRP
154                 , __pCompositeText
155                 , r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
156
157         __pTextColumn = new (std::nothrow)TextColumn(__pCompositeText);
158         SysTryCatch(NID_GRP
159                 , __pTextColumn
160                 , r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
161
162         __pDefaultFont = new (std::nothrow)Font();
163         SysTryCatch(NID_GRP
164                 , __pTextColumn
165                 , r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
166
167         r = __pDefaultFont->Construct(FONT_STYLE_PLAIN, 20);
168         SysTryCatch(NID_GRP
169                 , r == E_SUCCESS
170                 , , E_SYSTEM, "[E_SYSTEM] Fail to set font.");
171
172         __pCompositeText->SetWrap(__wrap);
173         __pCompositeText->SetTextSweepInfo(&__sweepInfo);
174
175         return E_SUCCESS;
176
177 CATCH:
178         if (__pDefaultFont)
179         {
180                 delete __pDefaultFont;
181                 __pDefaultFont = null;
182         }
183
184         if (__pCompositeText)
185         {
186                 delete __pCompositeText;
187                 __pCompositeText = null;
188         }
189
190         if (__pTextColumn)
191         {
192                 delete __pTextColumn;
193                 __pTextColumn = null;
194         }
195
196         if (__pTextWidthManager)
197         {
198                 delete __pTextWidthManager;
199                 __pTextWidthManager = null;
200         }
201
202         return r;
203 }
204
205 result
206 TextObject::Construct(const Rectangle& rect)
207 {
208         result r = E_SUCCESS;
209
210         __action = TEXT_OBJECT_ACTION_TYPE_NONE;
211         __align = (TextObjectAlignment)(TEXT_OBJECT_ALIGNMENT_LEFT | TEXT_OBJECT_ALIGNMENT_TOP);
212         __wrap = TEXT_OBJECT_WRAP_TYPE_WORD;
213         __isActionOn = false;
214         __isChanged = false;
215         __defaultForegroundColor = Color::GetColor(COLOR_ID_BLACK);
216         __defaultBackgroundColor = Color::GetColor(COLOR_ID_WHITE);
217         __defaultOutlineColor = Color::GetColor(COLOR_ID_WHITE);
218         __slidingStep = 2;
219         __isAlternateLookEnabled = false;
220         __linkViewModeEnabled = false;
221         __pTextWidthManager = null;
222         __rect = rect;
223         __pcRect.x = _ResUtil::ConvertToPhyCoord(rect.x);
224         __pcRect.y = _ResUtil::ConvertToPhyCoord(rect.y);
225         __pcRect.width = _ResUtil::ConvertToPhyCoordWidth(rect.width);
226         __pcRect.height = _ResUtil::ConvertToPhyCoordHeight(rect.height);
227
228         __pCompositeText = new (std::nothrow)TextComposite();
229         SysTryCatch(NID_GRP
230                 , __pCompositeText
231                 , r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
232
233         __pTextColumn = new (std::nothrow)TextColumn(__pCompositeText);
234         SysTryCatch(NID_GRP
235                 , __pTextColumn
236                 , r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
237
238         __pDefaultFont = new (std::nothrow)Font();
239         SysTryCatch(NID_GRP
240                 , __pTextColumn
241                 , r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
242
243         r = __pDefaultFont->Construct(FONT_STYLE_PLAIN, 20);
244         SysTryCatch(NID_GRP
245                 , r == E_SUCCESS
246                 , , E_SYSTEM, "[E_SYSTEM] Fail to set font.");
247
248         __pCompositeText->SetWrap(__wrap);
249         __pCompositeText->SetTextSweepInfo(&__sweepInfo);
250
251         return E_SUCCESS;
252
253 CATCH:
254         if (__pDefaultFont)
255         {
256                 delete __pDefaultFont;
257                 __pDefaultFont = null;
258         }
259
260         if (__pCompositeText)
261         {
262                 delete __pCompositeText;
263                 __pCompositeText = null;
264         }
265
266         if (__pTextColumn)
267         {
268                 delete __pTextColumn;
269                 __pTextColumn = null;
270         }
271
272         if (__pTextWidthManager)
273         {
274                 delete __pTextWidthManager;
275                 __pTextWidthManager = null;
276         }
277
278         return r;
279 }
280
281 TextObject*
282 TextObject::CloneN(void)
283 {
284         IF_NOT_CONSTRUCTED(return null);
285
286         result r = E_SUCCESS;
287         TextObject* pTextObject = null;
288         TextElement* pTextElement = null;
289         TextElement* pCloneTextElement = null;
290         int count = __pCompositeText->GetElementCount();
291
292         pTextObject = new (std::nothrow)TextObject();
293         SysTryReturn(NID_GRP
294                 , pTextObject
295                 , null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
296
297         r = pTextObject->Construct();
298         SysTryCatch(NID_GRP
299                 , r == E_SUCCESS
300                 , , r, "[%s] Propagating.", GetErrorMessage(r));
301
302         for (int i=0; i < count; i++)
303         {
304                 pTextElement = __pCompositeText->GetElementAtElementIndex(i);
305                 SysTryCatch(NID_GRP
306                         , pTextElement
307                         , , E_SYSTEM, "[E_SYSTEM] Fail to get text element.");
308
309                 pCloneTextElement = pTextElement->CloneN(SET_ALLVALUE_CLONE,0);
310                 pTextObject->AppendElement(*pCloneTextElement);
311         }
312
313         SetLastResult(E_SUCCESS);
314
315         return pTextObject;
316
317 CATCH:
318         delete pTextObject;
319         pTextObject = null;
320
321         return null;
322 }
323
324 result
325 TextObject::Draw(_CanvasImpl& canvasImpl)
326 {
327         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
328
329         if (__pcRect.width == 0 || __pcRect.height == 0)
330         {
331                 return E_SUCCESS;
332         }
333
334         result r = E_SUCCESS;
335         TextLine* pTextLine = null;
336         Rectangle clipRect;
337         Rectangle lineBounds;
338         Rectangle targetBounds;
339         int totalHeight = 0;
340         int slidingWidth = 0;
341
342         SysTryReturn(NID_GRP
343                         , __pcRect.width > 0 && __pcRect.height > 0
344                         , E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] This instance is not constructed yet. (width = %d, height = %d)", __pcRect.width, __pcRect.height);
345
346         _Canvas* pCanvas = _Canvas::GetInstance(canvasImpl);
347         SysTryReturn(NID_GRP
348                         , pCanvas
349                         , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
350
351         r = Compose();
352         SysTryReturn(NID_GRP
353                 , r == E_SUCCESS
354                 , r, r, "[%s] Propagating.", GetErrorMessage(r));
355
356         if (__pTextColumn->GetTotalLineCount() <= 1)
357         {
358                 __pTextColumn->SetFirstDisplayLineIndex(0);
359                 __pTextColumn->SetFirstDisplayPositionY(0);
360         }
361
362         targetBounds = __pcRect;
363
364         if (__action == TEXT_OBJECT_ACTION_TYPE_SLIDE_LEFT)
365         {
366                 if (__pTextColumn->GetTotalLineCount() == 0)
367                 {
368                         return E_SUCCESS;
369                 }
370
371                 totalHeight = TextUtility::GetFontMaxHeight(__pDefaultFont);
372         }
373         else
374         {
375                 totalHeight = __pTextColumn->GetTotalHeight();
376         }
377
378         if (totalHeight == 0)
379         {
380                 return E_SUCCESS;
381         }
382
383         if (totalHeight < targetBounds.height)
384         {
385                 switch (__align & TEXT_ALIGNMASK_VERT)
386                 {
387                 case TEXT_OBJECT_ALIGNMENT_TOP:
388                         // fall through
389                 default:
390                         break;
391
392                 case TEXT_OBJECT_ALIGNMENT_MIDDLE:
393                         targetBounds.y += (targetBounds.height - totalHeight) / 2;
394                         break;
395
396                 case TEXT_OBJECT_ALIGNMENT_BOTTOM:
397                         targetBounds.y += targetBounds.height - totalHeight;
398                         break;
399                 }
400         }
401         else
402         {
403                 if (targetBounds.height < totalHeight)
404                 {
405                         if (__action == TEXT_OBJECT_ACTION_TYPE_ABBREV)
406                         {
407                                 int i = 0;
408                                 int lineCount = __pTextColumn->GetTotalLineCount();
409
410                                 if (lineCount == 1)
411                                 {
412                                         totalHeight = targetBounds.height;
413                                 }
414                                 else
415                                 {
416                                         int lineHeight = __pTextColumn->GetLineHeightAt(0);
417
418                                         if (targetBounds.height < lineHeight)
419                                         {
420                                                 totalHeight = targetBounds.height;
421                                         }
422                                         else
423                                         {
424                                                 lineHeight = 0;
425
426                                                 for (i = 0; i < lineCount; i++)
427                                                 {
428                                                         lineHeight += __pTextColumn->GetLineHeightAt(i);
429                                                         if (targetBounds.height < lineHeight)
430                                                         {
431                                                                 lineHeight -= __pTextColumn->GetLineHeightAt(i);
432                                                                 break;
433                                                         }
434                                                 }
435                                                 totalHeight = lineHeight;
436                                         }
437                                 }
438                         }
439                         else
440                         {
441                                 goto CONTINUE_PROC;
442                         }
443                 }
444                 else
445                 {
446                         goto CONTINUE_PROC;
447                 }
448
449                 switch (__align & TEXT_ALIGNMASK_VERT)
450                 {
451                 case TEXT_OBJECT_ALIGNMENT_TOP:
452                         // fall through
453                 default:
454                         break;
455
456                 case TEXT_OBJECT_ALIGNMENT_MIDDLE:
457                         targetBounds.y += (targetBounds.height - totalHeight) / 2;
458                         break;
459
460                 case TEXT_OBJECT_ALIGNMENT_BOTTOM:
461                         targetBounds.y += targetBounds.height - totalHeight;
462                         break;
463                 }
464                 targetBounds.height = totalHeight;
465         }
466
467 CONTINUE_PROC:
468         Rectangle finalClipRect;
469         clipRect = pCanvas->GetClipBounds();
470
471         finalClipRect.x = Math::Max(clipRect.x, targetBounds.x);
472         finalClipRect.y = Math::Max(clipRect.y, targetBounds.y);
473         finalClipRect.width = Math::Min(clipRect.x + clipRect.width, targetBounds.x + targetBounds.width) - finalClipRect.x;
474         finalClipRect.height = Math::Min(clipRect.y + clipRect.height, targetBounds.y + targetBounds.height) - finalClipRect.y;
475
476         SysTryReturn(NID_GRP
477                 , 0 <= finalClipRect.width && 0 <= finalClipRect.height
478                 , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get clip rectangle.");
479
480         pCanvas->SetClipBounds(finalClipRect);
481
482         switch (__action)
483         {
484         case TEXT_OBJECT_ACTION_TYPE_SLIDE_LEFT:
485                 pTextLine = __pTextColumn->GetTextLine(0);
486                 SysTryReturn(NID_GRP
487                         , pTextLine
488                         , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
489
490                 lineBounds = pTextLine->GetBounds();
491                 __pTextColumn->SetDisplayLineCount(1);
492                 __pTextColumn->SetDisplayHeight(lineBounds.height);
493
494                 slidingWidth = Math::Max(__pTextColumn->GetSlidingDimension().width, __pcRect.width);
495
496                 if (__isActionOn)
497                 {
498                         Rectangle slidingRect;
499
500                         targetBounds.width = lineBounds.width;
501                         targetBounds.height = lineBounds.height;
502
503                         pCanvas->SetClipBounds(targetBounds);
504
505                         slidingRect = targetBounds;
506
507                         slidingRect.x += __pTextColumn->GetSlidingPosition();
508                         Dimension slidingDim = __pTextColumn->GetSlidingDimension();
509                         slidingRect.width = slidingDim.width;
510                         slidingRect.height = slidingDim.height;
511
512                         __pCompositeText->Draw(canvasImpl, slidingRect, 0, __pCompositeText->GetTextLength(),
513                                         (TextObjectAlignment)(__align & TEXT_ALIGNMASK_HORIZ), TEXT_OBJECT_ACTION_TYPE_NONE);
514
515                         slidingRect.x += slidingDim.width + __slidingGap;
516                         if (slidingRect.x < targetBounds.x + targetBounds.width)
517                         {
518                                 slidingRect.width = targetBounds.x + targetBounds.width - slidingRect.x;
519
520                                 __pCompositeText->Draw(canvasImpl, slidingRect, 0, __pCompositeText->GetTextLength(),
521                                                 (TextObjectAlignment)(__align & TEXT_ALIGNMASK_HORIZ), TEXT_OBJECT_ACTION_TYPE_NONE);
522                         }
523                 }
524                 else
525                 {
526                         pTextLine->Draw(canvasImpl, targetBounds, 0, pTextLine->GetTextLength(),
527                                         (TextObjectAlignment)(__align & TEXT_ALIGNMASK_HORIZ), TEXT_OBJECT_ACTION_TYPE_NONE);
528                 }
529                 break;
530
531         case TEXT_OBJECT_ACTION_TYPE_SLIDE_UP:
532         {
533                 Rectangle slidingRect = targetBounds;
534                 slidingRect.y += __pTextColumn->GetSlidingPosition();
535
536                 int lineCount = __pTextColumn->GetTotalLineCount();
537                 for (int i = 0; i < lineCount; i++)
538                 {
539                         pTextLine = __pTextColumn->GetTextLine(i);
540                         if (pTextLine != null)
541                         {
542                                 lineBounds = pTextLine->GetBounds();
543                                 slidingRect.height = lineBounds.height;
544                                 if ((slidingRect.y + slidingRect.height >= targetBounds.y) &&
545                                                 (slidingRect.y < targetBounds.y + targetBounds.height))
546                                 {
547                                         pTextLine->Draw(canvasImpl, slidingRect, 0, pTextLine->GetTextLength(),
548                                                         (TextObjectAlignment)(__align & TEXT_ALIGNMASK_HORIZ), TEXT_OBJECT_ACTION_TYPE_NONE);
549                                 }
550                         }
551                         slidingRect.y += slidingRect.height;
552                 }
553         }
554                 break;
555
556         case TEXT_OBJECT_ACTION_TYPE_ABBREV:
557                 if (__pCompositeText->IsTextAbbreviationEnabled())
558                 {
559                         __pCompositeText->DrawAbbrev(canvasImpl, targetBounds, __align);
560                 }
561                 else
562                 {
563                         DrawByLine(canvasImpl, targetBounds);
564                 }
565                 break;
566
567         case TEXT_OBJECT_ACTION_TYPE_NONE:
568                 // fall through
569         default:
570                 DrawByLine(canvasImpl, targetBounds);
571                 break;
572         }
573
574         pCanvas->SetClipBounds(clipRect);
575
576         return E_SUCCESS;
577 }
578
579 result
580 TextObject::GetChangedLineRange(int& startChangedLineIndex, int& endChangedLineIndex)
581 {
582         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
583
584         result r = E_SUCCESS;
585
586         r = Compose();
587         SysTryReturn(NID_GRP
588                 , r == E_SUCCESS
589                 , r, r, "[%s] Propagating.", GetErrorMessage(r));
590
591         startChangedLineIndex = __sweepInfo.sweepRegionStartLineIndex;
592         endChangedLineIndex =  __sweepInfo.sweepRegionStartLineIndex + __sweepInfo.sweepRegionLineCount - 1;
593
594         return E_SUCCESS;
595 }
596
597 result
598 TextObject::DrawLine(_CanvasImpl& canvasImpl, int lineIndex)
599 {
600         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
601
602         SysTryReturn(NID_GRP
603                         , lineIndex >= 0
604                         , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
605
606         result r = E_SUCCESS;
607         TextLine* pTextLine = null;
608         Rectangle lineBounds;
609         int firstDisplayY = __pTextColumn->GetFirstDisplayPositionY();
610
611         r = Compose();
612         SysTryReturn(NID_GRP
613                 , r == E_SUCCESS
614                 , r, r, "[%s] Propagating.", GetErrorMessage(r));
615
616         pTextLine = __pTextColumn->GetTextLine(lineIndex);
617         if (pTextLine == null)
618         {
619                 SysLog(NID_GRP, "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d, total line count = %d)"
620                                 , lineIndex, __pTextColumn->GetTotalLineCount());
621
622                 return E_INVALID_ARG;
623         }
624
625         lineBounds = pTextLine->GetBounds();
626         lineBounds.y = lineBounds.y - firstDisplayY + __rect.y;
627
628         int length = pTextLine->GetTextLength();
629         pTextLine->Draw(canvasImpl, lineBounds, 0, length, __align, TEXT_OBJECT_ACTION_TYPE_NONE);
630
631         return E_SUCCESS;
632 }
633
634 result
635 TextObject::DrawWithOffset(_CanvasImpl& canvasImpl)
636 {
637         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
638
639         SysTryReturn(NID_GRP
640                         , __isActionOn
641                         , E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Action is off.");
642
643         int slidingStartIndex = __pTextColumn->GetSlidingPosition();
644         Dimension slidingDim = __pTextColumn->GetSlidingDimension();
645
646         switch (__action)
647         {
648         case TEXT_OBJECT_ACTION_TYPE_SLIDE_LEFT:
649                 if (__pcRect.width < slidingDim.width)
650                 {
651                         slidingDim.width = Math::Max(slidingDim.width, __pcRect.width);
652
653                         if (__slidingStep < slidingStartIndex + slidingDim.width + __slidingGap)
654                         {
655                                 slidingStartIndex -= __slidingStep;
656                         }
657                         else
658                         {
659                                 slidingStartIndex += slidingDim.width + __slidingGap;
660                         }
661                 }
662                 else
663                 {
664                         if (0 < slidingStartIndex + slidingDim.width)
665                         {
666                                 slidingStartIndex -= __slidingStep;
667                         }
668                         else
669                         {
670                                 slidingStartIndex = __pcRect.width + __slidingGap + slidingStartIndex;
671                         }
672                 }
673                 __pTextColumn->SetSlidingPosition(slidingStartIndex);
674                 break;
675
676         case TEXT_OBJECT_ACTION_TYPE_SLIDE_UP:
677                 if (slidingStartIndex + slidingDim.height >= 0)
678                 {
679                         slidingStartIndex -= __slidingStep;
680                 }
681                 else
682                 {
683                         slidingStartIndex = __pcRect.height;
684                 }
685                 __pTextColumn->SetSlidingPosition(slidingStartIndex);
686                 break;
687
688         case TEXT_OBJECT_ACTION_TYPE_ABBREV:
689                 // fall through
690         case TEXT_OBJECT_ACTION_TYPE_NONE:
691                 // fall through
692         default:
693                 break;
694         }
695
696         return Draw(canvasImpl);
697 }
698
699 result
700 TextObject::UpdateChangedInfo(int startTextIndex, int textLength, bool initTextWidthManager)
701 {
702         result r = E_SUCCESS;
703
704         if (startTextIndex >= 0)
705         {
706                 r = __pTextColumn->SetChangeAction(TextColumn::TEXT_CHANGE_UNKONWN, startTextIndex, 0);
707                 SysTryReturn(NID_GRP
708                         , r == E_SUCCESS
709                         , r, r, "[%s] Propagating.", GetErrorMessage(r));
710
711                 if (__pCompositeText->IsWidthManagerEnabled() && __pTextWidthManager && initTextWidthManager)
712                 {
713                         __pTextWidthManager->Finalize();
714                         if (__wrap == TEXT_OBJECT_WRAP_TYPE_WORD)
715                         {
716                                 __pTextWidthManager->Initialize(__pCompositeText->GetTextLength());
717                         }
718                 }
719         }
720
721         __isChanged = true;
722
723         if (IsPartialComposingModeEnabled())
724         {
725                 __pCompositeText->InitPartialComposeMode();
726         }
727
728         return E_SUCCESS;
729 }
730
731 bool
732 TextObject::IsChanged(void) const
733 {
734         IF_NOT_CONSTRUCTED(return false);
735
736         return __isChanged;
737 }
738
739 result
740 TextObject::SetPartialComposingModeEnabled(bool enable)
741 {
742         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
743
744         __pCompositeText->SetPartialComposingModeEnabled(enable);
745
746         return E_SUCCESS;
747 }
748
749 bool
750 TextObject::IsPartialComposingModeEnabled(void) const
751 {
752         IF_NOT_CONSTRUCTED(return false);
753
754         return __pCompositeText->IsPartialComposingModeEnabled();
755 }
756
757 result
758 TextObject::Compose(void)
759 {
760         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
761
762         int lineCount = 0;
763         Rectangle rect;
764         Rectangle lineBounds;
765
766         SysTryReturn(NID_GRP
767                         , __pcRect.width >= 0 && __pcRect.height >= 0
768                         , E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] This instance is not constructed yet.");
769
770         rect = __pcRect;
771
772         if (__pCompositeText->IsPartialComposingModeEnabled())
773         {
774                 if (__pCompositeText->IsComposeDone() || !__isFirstDisplayPositionYChanged)
775                 {
776                         if (GetTotalLineCount() != 0)
777                         {
778                                 return E_SUCCESS;
779                         }
780                 }
781         }
782         else
783         {
784                 if (!__isChanged || __pTextColumn->GetChangeActionEventCount() == 0)
785                 {
786                         return E_SUCCESS;
787                 }
788         }
789
790         __isActionOn = false;
791
792         if (__pTextColumn->GetTotalLineCount() == 0)
793         {
794                 __pTextColumn->SetChangeAction(TextColumn::TEXT_CHANGE_UNKONWN, 0, 0);
795                 __pTextColumn->SetFirstDisplayLineIndex(0);
796                 __pTextColumn->SetFirstDisplayPositionY(0);
797         }
798
799         ResetSweepInfo();
800         lineCount = __pCompositeText->Compose(rect, __pTextColumn);
801
802         switch (__action)
803         {
804         case TEXT_OBJECT_ACTION_TYPE_SLIDE_LEFT:
805         {
806                 TextLine* pTextLine = __pTextColumn->GetTextLine(0);
807                 if (pTextLine != null)
808                 {
809                         int lineLength = pTextLine->GetTextLength();
810                         int totalLength = __pCompositeText->GetTextLength();
811
812                         if (lineLength < totalLength)
813                         {
814                                 __isActionOn = true;
815                                 __pTextColumn->SetSlidingPosition(0);
816
817                                 Dimension slidingDim;
818                                 Dimension lineTextSize;
819
820                                 __pCompositeText->GetRegion(0, totalLength, slidingDim.width, slidingDim.height);
821                                 pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
822                                 lineBounds = pTextLine->GetBounds();
823
824                                 __pTextColumn->SetSlidingDimension(slidingDim);
825
826                                 lineBounds.height = slidingDim.height;
827                                 lineTextSize.width = lineBounds.width;
828
829                                 pTextLine->SetBounds(lineBounds);
830                                 pTextLine->SetRegion(lineTextSize.width, lineTextSize.height);
831                         }
832                 }
833         }
834         break;
835
836         case TEXT_OBJECT_ACTION_TYPE_SLIDE_UP:
837         {
838                 __pTextColumn->SetSlidingPosition(0);
839
840                 int totalHeight = __pTextColumn->GetTotalHeight();
841                 Dimension slidingDim;
842                 slidingDim.width = __pcRect.width;
843                 slidingDim.height = totalHeight;
844
845                 __pTextColumn->SetSlidingDimension(slidingDim);
846
847                 if (__pcRect.height < totalHeight)
848                 {
849                         __isActionOn = true;
850                 }
851         }
852         break;
853
854         case TEXT_OBJECT_ACTION_TYPE_ABBREV:
855                 // fall through
856         case TEXT_OBJECT_ACTION_TYPE_NONE:
857                 // fall through
858         default:
859                 break;
860         }
861
862         __isChanged = false;
863
864         return E_SUCCESS;
865 }
866
867 int
868 TextObject::GetText(wchar_t* pCopiedText, int textLength) const
869 {
870         IF_NOT_CONSTRUCTED(return -1);
871
872         SysTryReturn(NID_GRP
873                         , pCopiedText
874                         , -1, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
875
876         SysTryReturn(NID_GRP
877                         , textLength > 0
878                         , -1, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
879
880         int textElementCount = 0;
881         int totalLength = 0;
882         int outLength = textLength;
883         int copiedLength = 0;
884         TextElement* pTextElement = null;
885         wchar_t* pSrcText = null;
886         wchar_t* pDstText = null;
887
888         textElementCount = __pCompositeText->GetElementCount();
889         pDstText = pCopiedText;
890
891         for (int i = 0; i < textElementCount && totalLength < outLength; i++)
892         {
893                 pTextElement = __pCompositeText->GetElementAtElementIndex(i);
894                 if (pTextElement == null)
895                 {
896                         return totalLength;
897                 }
898
899                 TextElementType objectType = pTextElement->GetType();
900                 if (objectType == TEXT_ELEMENT_TYPE_TEXT || objectType == TEXT_ELEMENT_TYPE_CUTLINK)
901                 {
902                         int elementTextLength = pTextElement->GetTextLength();
903                         TextSimple* pSimpleText = dynamic_cast < TextSimple* >(pTextElement);
904                         if (pSimpleText != null)
905                         {
906                                 copiedLength = (elementTextLength > outLength - totalLength) ? outLength - totalLength : elementTextLength;
907                                 SysTryReturn(NID_GRP
908                                                 , 0 <= copiedLength
909                                                 , -1, E_SYSTEM, "[E_SYSTEM] Fail to string copy.");
910
911                                 pSrcText = (wchar_t*)pSimpleText->GetText();
912
913                                 result r = TextUtility::CopyText(pDstText, pSrcText, copiedLength);
914                                 SysTryReturn(NID_GRP
915                                         , r == E_SUCCESS
916                                         , -1, r, "[%s] Propagating.", GetErrorMessage(r));
917
918                                 pDstText += copiedLength;
919                                 totalLength += copiedLength;
920                         }
921                 }
922         }
923
924         SetLastResult(E_SUCCESS);
925
926         return totalLength;
927 }
928
929 result
930 TextObject::SetFirstDisplayLineIndex(int lineIndex)
931 {
932         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
933
934         result r = E_SUCCESS;
935         Rectangle lineBounds;
936         TextLine* pTextLine = null;
937         int firstDisplayPositionY = 0;
938         int rollbackFirstDisplayPositionY = 0;
939         int rollbackFirstDisplayLineIndex = 0;
940
941         rollbackFirstDisplayPositionY = __pTextColumn->GetFirstDisplayPositionY();
942         rollbackFirstDisplayLineIndex = __pTextColumn->GetFirstDisplayLineIndex();
943
944         __pTextColumn->SetFirstDisplayLineIndex(lineIndex);
945
946         pTextLine = __pTextColumn->GetTextLine(lineIndex);
947         SysTryCatch(NID_GRP
948                 , pTextLine
949                 , r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text element.");
950
951         lineBounds = pTextLine->GetBounds();
952         firstDisplayPositionY = lineBounds.y;
953
954         __pTextColumn->SetFirstDisplayPositionY(firstDisplayPositionY);
955
956         return E_SUCCESS;
957
958 CATCH:
959         __pTextColumn->SetFirstDisplayLineIndex(rollbackFirstDisplayLineIndex);
960         __pTextColumn->SetFirstDisplayPositionY(rollbackFirstDisplayPositionY);
961
962         return r;
963 }
964
965 result
966 TextObject::SetFirstDisplayPositionY(int lcY)
967 {
968         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
969
970         result r = E_SUCCESS;
971
972         int pcY = _ResUtil::ConvertToPhyCoord(lcY);
973         if (IsPartialComposingModeEnabled())
974         {
975                 __isFirstDisplayPositionYChanged = true;
976
977                 if (__pCompositeText->GetTotalComposedHeight() <= (pcY + __pcRect.height))
978                 {
979                         __pCompositeText->SetComposePartialLimitHeight(pcY + __pcRect.height - GetTotalComposedHeight());
980
981                         r = Compose();
982                         SysTryCatch(NID_GRP
983                                 , r == E_SUCCESS
984                                 , , r, "[%s] Propagating.", GetErrorMessage(r));
985                 }
986         }
987
988         __isFirstDisplayPositionYChanged = false;
989         __pTextColumn->SetFirstDisplayPositionY(pcY);
990
991         return E_SUCCESS;
992
993 CATCH:
994         __isFirstDisplayPositionYChanged = false;
995         return r;
996 }
997
998 int
999 TextObject::GetMaxLineHeight(void) const
1000 {
1001         IF_NOT_CONSTRUCTED(return -1);
1002
1003         int pcMaxHeight = __pCompositeText->GetMaxLineHeight();
1004         pcMaxHeight = Math::Max(pcMaxHeight, TextUtility::GetFontMaxHeight(__pDefaultFont));
1005         int lcMaxHeight = _ResUtil::ConvertToVirCoord(pcMaxHeight);
1006
1007         return lcMaxHeight;
1008 }
1009
1010 bool
1011 TextObject::IsDisplayedAtStartPosition(void) const
1012 {
1013         IF_NOT_CONSTRUCTED(return false);
1014
1015         int firstDisplayPositionY = __pTextColumn->GetFirstDisplayPositionY();
1016         if (firstDisplayPositionY == 0)
1017         {
1018                 return true;
1019         }
1020         else
1021         {
1022                 return false;
1023         }
1024 }
1025
1026 bool
1027 TextObject::IsDisplayedAtEndPosition(void) const
1028 {
1029         IF_NOT_CONSTRUCTED(return false);
1030
1031         int totalHeight = 0;
1032         int firstDisplayPositionY = 0;
1033
1034         firstDisplayPositionY = __pTextColumn->GetFirstDisplayPositionY();
1035         totalHeight = __pTextColumn->GetTotalHeight();
1036
1037         if ((totalHeight - firstDisplayPositionY) <= __pcRect.height)
1038         {
1039                 return true;
1040         }
1041         else
1042         {
1043                 return false;
1044         }
1045 }
1046
1047 result
1048 TextObject::SetAction(TextObjectActionType action)
1049 {
1050         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1051
1052         SysTryReturn(NID_GRP
1053                 , TEXT_OBJECT_ACTION_TYPE_NONE <= action && action < TEXT_OBJECT_ACTION_TYPE_MAX
1054                 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1055
1056         if (__action != action)
1057         {
1058                 if ((__action == TEXT_OBJECT_ACTION_TYPE_NONE && action == TEXT_OBJECT_ACTION_TYPE_ABBREV) ||
1059                         (__action == TEXT_OBJECT_ACTION_TYPE_ABBREV && action == TEXT_OBJECT_ACTION_TYPE_NONE))
1060                 {
1061                         __action = action;
1062                         UpdateChangedInfo(0, 0);
1063                 }
1064                 else
1065                 {
1066                         __action = action;
1067                         UpdateChangedInfo(0, 0);
1068                 }
1069         }
1070         if (__action == TEXT_OBJECT_ACTION_TYPE_ABBREV)
1071         {
1072                 __pCompositeText->SetTextAbbreviationEnabled(true);
1073         }
1074         else
1075         {
1076                 __pCompositeText->SetTextAbbreviationEnabled(false);
1077         }
1078
1079         return E_SUCCESS;
1080 }
1081
1082 result
1083 TextObject::SetAlignment(TextObjectAlignment alignment)
1084 {
1085         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1086
1087         SysTryReturn(NID_GRP
1088                 , TEXT_OBJECT_ALIGNMENT_LEFT <= alignment && alignment < TEXT_OBJECT_ALIGNMENT_INVALID
1089                 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. alignment(%d)", alignment);
1090
1091         if (__align != alignment)
1092         {
1093                 __align = alignment;
1094                 UpdateChangedInfo(0, 0);
1095         }
1096
1097         return E_SUCCESS;
1098 }
1099
1100 result
1101 TextObject::SetBounds(const Rectangle& lcRect)
1102 {
1103         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1104
1105         SysTryReturn(NID_GRP
1106                 , (lcRect.width >= 0) && (lcRect.height >= 0)
1107                 , E_OUT_OF_RANGE, E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] The given rectangle(width:%d,height:%d) is out of range.\n", lcRect.width, lcRect.height);
1108
1109         if (__rect.width != lcRect.width)
1110         {
1111                 UpdateChangedInfo(0, 0, false);
1112         }
1113
1114         __rect = lcRect;
1115
1116         if (_ResUtil::NeedToConvertCoord())
1117         {
1118                 __pcRect.x = _ResUtil::ConvertToPhyCoord(__rect.x);
1119                 __pcRect.y = _ResUtil::ConvertToPhyCoord(__rect.y);
1120                 __pcRect.width = _ResUtil::ConvertToPhyCoordWidth(__rect.width);
1121
1122                 // temporary code for tizen 2.0
1123                 if (_Screen::GetWidth() == 600)
1124                 {
1125                         __pcRect.width++;
1126                 }
1127
1128                 __pcRect.height = _ResUtil::ConvertToPhyCoordHeight(__rect.height);
1129         }
1130         else
1131         {
1132                 __pcRect = __rect;
1133         }
1134
1135         return E_SUCCESS;
1136 }
1137
1138 result
1139 TextObject::SetLineSpace(int lcLineSpacing)
1140 {
1141         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1142
1143         SysTryReturn(NID_GRP
1144                 , lcLineSpacing >= 0
1145                 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1146
1147         int pcLineSpacing = _ResUtil::ConvertToPhyCoord(lcLineSpacing);
1148
1149         if (__pCompositeText->GetLineSpace() != pcLineSpacing)
1150         {
1151                 __pCompositeText->SetLineSpace(pcLineSpacing);
1152                 __isChanged = true;
1153         }
1154
1155         return E_SUCCESS;
1156 }
1157
1158 result
1159 TextObject::SetElementVerticalAlignment(TextObjectAlignment alignment)
1160 {
1161         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1162
1163         SysTryReturn(NID_GRP
1164                 , (alignment & TEXT_OBJECT_ALIGNMENT_TOP) || (alignment & TEXT_OBJECT_ALIGNMENT_MIDDLE) || (alignment & TEXT_OBJECT_ALIGNMENT_BOTTOM) || (alignment & TEXT_OBJECT_ALIGNMENT_BASELINE)
1165                 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. alignment(%d)", alignment);
1166
1167         if (__pCompositeText->GetElementVerticalAlignment() == alignment)
1168         {
1169                 return E_SUCCESS;
1170         }
1171
1172         __pCompositeText->SetElementVerticalAlignment(alignment);
1173         __isChanged = true;
1174
1175         return E_SUCCESS;
1176 }
1177
1178 Dimension
1179 TextObject::GetTextExtent(int startTextIndex, int textLength) const
1180 {
1181         IF_NOT_CONSTRUCTED(return Dimension(-1, -1));
1182
1183         Dimension pcTextSize;
1184         result r = __pCompositeText->GetRegion(startTextIndex, textLength, pcTextSize.width, pcTextSize.height);
1185         SysTryReturn(NID_GRP
1186                 , r == E_SUCCESS
1187                 , Dimension(-1, -1), r, "[%s] Propagating.", GetErrorMessage(r));
1188
1189         Dimension lcTextSize;
1190         lcTextSize.width = _ResUtil::ConvertToVirCoord(pcTextSize.width);
1191         lcTextSize.height = _ResUtil::ConvertToVirCoord(pcTextSize.height);
1192
1193         SetLastResult(E_SUCCESS);
1194
1195         return lcTextSize;
1196 }
1197
1198 result
1199 TextObject::AppendElement(TextElement& textElement)
1200 {
1201         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1202
1203         result r = E_SUCCESS;
1204         TextElementType objecType = textElement.GetType();
1205         if (objecType == TEXT_ELEMENT_TYPE_CUTLINK)
1206         {
1207                 TextCutLink* pLinkText = dynamic_cast < TextCutLink* >(&textElement);
1208                 if (pLinkText != null)
1209                 {
1210                         switch (pLinkText->GetCutLinkType())
1211                         {
1212                         case LINK_TYPE_URL:
1213                                 if (__isUrlLinkColorDefined)
1214                                 {
1215                                         pLinkText->SetUserColor(__linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_URL_NORMAL], __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_URL_SELECT]);
1216                                 }
1217                                 break;
1218
1219                         case LINK_TYPE_EMAIL:
1220                                 if (__isEmailLinkColorDefined)
1221                                 {
1222                                         pLinkText->SetUserColor(__linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_EMAIL_NORMAL], __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_EMAIL_SELECT]);
1223                                 }
1224                                 break;
1225
1226                         case LINK_TYPE_TEL_NUM:
1227                                 if (__isPhoneNumberLinkColorDefined)
1228                                 {
1229                                         pLinkText->SetUserColor(__linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_PHONE_NUMBER_NORMAL],
1230                                                         __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_PHONE_NUMBER_SELECT]);
1231                                 }
1232                                 break;
1233
1234                         default:
1235                                 break;
1236                         }
1237                 }
1238         }
1239
1240         int textIndex = __pCompositeText->GetTextLength();
1241         int elementTextLength = textElement.GetTextLength();
1242
1243         r = __pCompositeText->AppendElement(textElement);
1244         SysTryReturn(NID_GRP
1245                 , r == E_SUCCESS
1246                 , r, r, "[%s] Propagating.", GetErrorMessage(r));
1247
1248         int elementCount = __pCompositeText->GetElementCount();
1249         if (elementCount > 0)
1250         {
1251                 __pCompositeText->Optimize(elementCount-1, elementCount-1);
1252         }
1253
1254         if (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE)
1255         {
1256                 UpdateChangedInfo(0, 0);
1257         }
1258         else
1259         {
1260                 NotifyTextAdded(textIndex, elementTextLength);
1261         }
1262
1263         return r;
1264 }
1265
1266 result
1267 TextObject::InsertElementAt(int textIndex, TextElement& textElement)
1268 {
1269         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1270
1271         result r = E_SUCCESS;
1272         TextElementType objecType = textElement.GetType();
1273
1274         if (objecType == TEXT_ELEMENT_TYPE_CUTLINK)
1275         {
1276                 TextCutLink* pLinkText = dynamic_cast < TextCutLink* >(&textElement);
1277                 if (pLinkText != null)
1278                 {
1279                         switch (pLinkText->GetCutLinkType())
1280                         {
1281                         case LINK_TYPE_URL:
1282                                 if (__isUrlLinkColorDefined)
1283                                 {
1284                                         pLinkText->SetUserColor(__linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_URL_NORMAL],
1285                                                         __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_URL_SELECT]);
1286                                 }
1287                                 break;
1288
1289                         case LINK_TYPE_EMAIL:
1290                                 if (__isEmailLinkColorDefined)
1291                                 {
1292                                         pLinkText->SetUserColor(__linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_EMAIL_NORMAL],
1293                                                         __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_EMAIL_SELECT]);
1294                                 }
1295                                 break;
1296
1297                         case LINK_TYPE_TEL_NUM:
1298                                 if (__isPhoneNumberLinkColorDefined)
1299                                 {
1300                                         pLinkText->SetUserColor(__linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_PHONE_NUMBER_NORMAL],
1301                                                         __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_PHONE_NUMBER_SELECT]);
1302                                 }
1303                                 break;
1304
1305                         default:
1306                                 break;
1307                         }
1308                 }
1309         }
1310
1311         r = __pCompositeText->InsertElementAt(textElement, textIndex);
1312         SysTryReturn(NID_GRP
1313                 , r == E_SUCCESS
1314                 , r, r, "[%s] Fail to insert element.", GetErrorMessage(r));
1315
1316         int elementIndex = __pCompositeText->GetElementIndexOf(textElement);
1317         if (elementIndex != -1)
1318         {
1319                 __pCompositeText->Optimize(elementIndex, elementIndex);
1320         }
1321
1322         if (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE)
1323         {
1324                 UpdateChangedInfo(0, 0);
1325         }
1326         else
1327         {
1328                 NotifyTextAdded(textIndex, textElement.GetTextLength());
1329         }
1330
1331         return r;
1332 }
1333
1334 result
1335 TextObject::RemoveAll(bool deallocate)
1336 {
1337         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1338
1339         result r = __pTextColumn->RemoveAllLines();
1340         SysTryReturn(NID_GRP
1341                 , r == E_SUCCESS
1342                 , r, r, "[%s] Propagating.", GetErrorMessage(r));
1343
1344         r = __pCompositeText->RemoveAllElements(deallocate);
1345         SysTryReturn(NID_GRP
1346                 , r == E_SUCCESS
1347                 , r, r, "[%s] Propagating.", GetErrorMessage(r));
1348
1349         UpdateChangedInfo(0);
1350
1351         __isActionOn = false;
1352
1353         return r;
1354 }
1355
1356 result
1357 TextObject::RemoveElement(TextElement& textElement, bool deallocate)
1358 {
1359         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1360
1361         result r = E_SUCCESS;
1362         int elementIndex = 0;
1363         int textIndex = 0;
1364         int elementTextLength = 0;
1365         TextElement* pCurrentTextElement = null;
1366
1367         elementIndex = __pCompositeText->GetElementIndexOf(textElement);
1368         SysTryReturn(NID_GRP
1369                 , 0 <= elementIndex
1370                 , E_INVALID_ARG, E_INVALID_ARG, "[E_SYSTEM] The argument is invalid.");
1371
1372         for (int i = 0; i < elementIndex; i++)
1373         {
1374                 pCurrentTextElement = __pCompositeText->GetElementAtElementIndex(i);
1375                 if (pCurrentTextElement != null)
1376                 {
1377                         textIndex += pCurrentTextElement->GetTextLength();
1378                 }
1379         }
1380
1381         elementTextLength = textElement.GetTextLength();
1382
1383         r = __pCompositeText->RemoveElementAt(elementIndex, deallocate);
1384         SysTryReturn(NID_GRP
1385                 , r == E_SUCCESS
1386                 , r, r, "[%s] Propagating.", GetErrorMessage(r));
1387
1388         NotifyTextDeleted(textIndex, elementTextLength);
1389
1390         if (__pCompositeText->GetElementCount() == 0 || GetTextLength() == 0)
1391         {
1392                 __pTextColumn->RemoveAllLines();
1393         }
1394
1395         return r;
1396 }
1397
1398 TextElement*
1399 TextObject::GetElementAtTextIndex(int textIndex) const
1400 {
1401         IF_NOT_CONSTRUCTED(return null);
1402
1403         TextElement* pTextElement = null;
1404         int elementTextLength = 0;
1405         int textIndexFromElementOffset = 0;
1406         int elementIndex = 0;
1407         int elementOffset = 0;
1408
1409         pTextElement = __pCompositeText->GetElementAtTextIndex(textIndex, elementOffset, elementIndex, elementTextLength,
1410                                                                                                                           textIndexFromElementOffset);
1411         SysTryCatch(NID_GRP
1412                 , pTextElement
1413                 , , E_SYSTEM, "[E_SYSTEM] Fail to get text element.");
1414
1415         SetLastResult(E_SUCCESS);
1416         return pTextElement;
1417
1418 CATCH:
1419         elementOffset = 0;
1420         elementIndex = 0;
1421         return null;
1422 }
1423
1424 result
1425 TextObject::SetFont(Font* pFont, int startTextIndex, int textLength)
1426 {
1427         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1428
1429         SysTryReturn(NID_GRP
1430                 , pFont
1431                 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1432
1433         SysTryReturn(NID_GRP
1434                 , startTextIndex >= 0
1435                 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1436
1437         result r = E_SUCCESS;
1438         Font* pTmpFont = null;
1439
1440         pTmpFont = _FontImpl::CloneN(const_cast < Font& >(*pFont));
1441         r = GetLastResult();
1442         SysTryReturn(NID_GRP
1443                 , pTmpFont
1444                 , r, r, "[%s] Propagating.", GetErrorMessage(r));
1445
1446         if (__pDefaultFont)
1447         {
1448                 delete __pDefaultFont;
1449                 __pDefaultFont = null;
1450         }
1451         __pDefaultFont = pTmpFont;
1452
1453         __pCompositeText->SetRange(startTextIndex, textLength);
1454         r = __pCompositeText->SetFont(pFont);
1455         SysTryReturn(NID_GRP
1456                 , r == E_SUCCESS
1457                 , r, r, "[%s] Propagating.", GetErrorMessage(r));
1458
1459         UpdateChangedInfo(__pCompositeText->GetWorkStart(), 0);
1460
1461         return E_SUCCESS;
1462 }
1463
1464 const Font*
1465 TextObject::GetFont(int textIndex) const
1466 {
1467         IF_NOT_CONSTRUCTED(return null);
1468
1469         Font* pFont = __pCompositeText->GetFont(textIndex);
1470         if (pFont == null)
1471         {
1472                 pFont = __pDefaultFont;
1473         }
1474
1475         SetLastResult(E_SUCCESS);
1476         return pFont;
1477 }
1478
1479 result
1480 TextObject::SetForegroundColor(const Color& color, int startTextIndex, int textLength)
1481 {
1482         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1483
1484         SysTryReturn(NID_GRP
1485                 , startTextIndex >= 0
1486                 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1487
1488         __defaultForegroundColor = color;
1489
1490         __pCompositeText->SetRange(startTextIndex, textLength);
1491         __pCompositeText->SetForegroundColor(color);
1492
1493         return E_SUCCESS;
1494 }
1495
1496 Color
1497 TextObject::GetForegroundColor(int textIndex) const
1498 {
1499         IF_NOT_CONSTRUCTED(return Color::GetColor(COLOR_ID_BLACK));
1500
1501         SysTryReturn(NID_GRP
1502                 , textIndex >= 0
1503                 , __defaultForegroundColor, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1504
1505         return __pCompositeText->GetForegroundColor(textIndex);
1506 }
1507
1508 result
1509 TextObject::SetBackgroundColor(const Color& color, int startTextIndex, int textLength)
1510 {
1511         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1512
1513         SysTryReturn(NID_GRP
1514                 , startTextIndex >= 0
1515                 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1516
1517         __defaultBackgroundColor = color;
1518
1519         __pCompositeText->SetRange(startTextIndex, textLength);
1520         __pCompositeText->SetBackgroundColor(color);
1521
1522         return E_SUCCESS;
1523 }
1524
1525 Color
1526 TextObject::GetBackgroundColor(int textIndex) const
1527 {
1528         IF_NOT_CONSTRUCTED(return Color::GetColor(COLOR_ID_BLACK));
1529
1530         SysTryReturn(NID_GRP
1531                 , textIndex >= 0
1532                 , __defaultBackgroundColor, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1533
1534         return __pCompositeText->GetBackgroundColor(textIndex);
1535 }
1536
1537 result
1538 TextObject::SetOutlineColor(const Color& color, int startTextIndex, int textLength)
1539 {
1540         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1541
1542         SysTryReturn(NID_GRP
1543                 , startTextIndex >= 0
1544                 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1545
1546         __defaultOutlineColor = color;
1547
1548         __pCompositeText->SetRange(startTextIndex, textLength);
1549         __pCompositeText->SetOutlineColor(color);
1550
1551         return E_SUCCESS;
1552 }
1553
1554 Color
1555 TextObject::GetOutlineColor(int textIndex) const
1556 {
1557         IF_NOT_CONSTRUCTED(return Color::GetColor(COLOR_ID_BLACK));
1558
1559         SysTryReturn(NID_GRP
1560                 , textIndex >= 0
1561                 , __defaultOutlineColor, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1562
1563         return __pCompositeText->GetOutlineColor(textIndex);
1564 }
1565
1566 result
1567 TextObject::SetBlockColor(const Color& color)
1568 {
1569         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1570
1571         __pCompositeText->SetBlockColor(color);
1572
1573         return E_SUCCESS;
1574 }
1575
1576 Color
1577 TextObject::GetBlockColor(void) const
1578 {
1579         IF_NOT_CONSTRUCTED(return Color::GetColor(COLOR_ID_BLACK));
1580
1581         return __pCompositeText->GetBlockColor();
1582 }
1583
1584 result
1585 TextObject::SetWrap(TextObjectWrapType wrap)
1586 {
1587         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1588
1589         result r = E_SUCCESS;
1590
1591         if (__wrap == wrap)
1592         {
1593                 return E_SUCCESS;
1594         }
1595
1596         r = __pCompositeText->SetWrap(wrap);
1597         SysTryReturn(NID_GRP
1598                 , r == E_SUCCESS
1599                 , r, r, "[%s] Propagating.", GetErrorMessage(r));
1600
1601         __wrap = wrap;
1602         UpdateChangedInfo(0, 0);
1603
1604         return E_SUCCESS;
1605 }
1606
1607 result
1608 TextObject::InsertElementAt(int textIndex, Bitmap& bitmap, TextElementSourceType sourceType)
1609 {
1610         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1611
1612         TextImage* pImageText = null;
1613         int addedTextLength = 0;
1614         int startTextIndex = 0;
1615
1616         pImageText = new (std::nothrow)TextImage(bitmap, sourceType, null, (TextObjectAlignment)(TEXT_OBJECT_ALIGNMENT_LEFT | TEXT_OBJECT_ALIGNMENT_TOP));
1617         SysTryReturn(NID_GRP
1618                 , pImageText
1619                 , E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
1620
1621         addedTextLength = pImageText->GetTextLength();
1622         __pCompositeText->InsertElementAt(*pImageText, textIndex);
1623         startTextIndex = __pCompositeText->GetWorkStart();
1624         NotifyTextAdded(startTextIndex, addedTextLength);
1625
1626         return E_SUCCESS;
1627 }
1628
1629 result
1630 TextObject::AppendElement(Bitmap& bitmap, TextElementSourceType sourceType)
1631 {
1632         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1633
1634         result r = E_SUCCESS;
1635         TextImage* pImageText = null;
1636
1637         pImageText = new (std::nothrow)TextImage(bitmap, sourceType, null, (TextObjectAlignment)(TEXT_OBJECT_ALIGNMENT_LEFT | TEXT_OBJECT_ALIGNMENT_TOP));
1638         SysTryReturn(NID_GRP
1639                 , pImageText
1640                 , E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
1641
1642         r = __pCompositeText->AppendElement(*pImageText);
1643         SysTryReturn(NID_GRP
1644                 , r == E_SUCCESS
1645                 , r, r, "[%s] Propagating.", GetErrorMessage(r));
1646
1647         int startTextIndex = __pCompositeText->GetWorkStart();
1648         int elementTextLength = pImageText->GetTextLength();
1649
1650         NotifyTextAdded(startTextIndex, elementTextLength);
1651
1652         return E_SUCCESS;
1653 }
1654
1655 result
1656 TextObject::SetAlternateLookEnabled(bool enable)
1657 {
1658         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1659
1660         int elementCount = 0;
1661         TextElement* pTextElement = null;
1662
1663         __isAlternateLookEnabled = enable;
1664         elementCount = __pCompositeText->GetElementCount();
1665
1666         for (int i = 0; i < elementCount; i++)
1667         {
1668                 pTextElement = __pCompositeText->GetElementAtElementIndex(i);
1669                 if (pTextElement != null)
1670                 {
1671                         pTextElement->SetAlternateLookEnabled(enable);
1672                 }
1673         }
1674
1675         return E_SUCCESS;
1676 }
1677
1678 result
1679 TextObject::SetAlternativeForegroundColor(const Color& color)
1680 {
1681         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1682
1683         int elementCount = 0;
1684         TextElement* pTextElement = null;
1685
1686         elementCount = __pCompositeText->GetElementCount();
1687
1688         for (int i = 0; i < elementCount; i++)
1689         {
1690                 pTextElement = __pCompositeText->GetElementAtElementIndex(i);
1691                 SysTryReturn(NID_GRP
1692                         , pTextElement
1693                         , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text element.");
1694
1695                 pTextElement->SetAlternativeForegroundColor(color);
1696         }
1697
1698         return E_SUCCESS;
1699 }
1700
1701 result
1702 TextObject::ChangeTextOffset(wchar_t* pText, int textIndex, int gap)
1703 {
1704         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1705
1706         result r = E_SUCCESS;
1707         int elementStartTextIndex = 0;
1708         int elementIndex = 0;
1709         int elementTextLength = 0;
1710         int textIndexFromElementOffset = 0;
1711
1712         TextElement* pTextElement = __pCompositeText->GetElementAtTextIndex(textIndex, elementStartTextIndex,
1713                         elementIndex, elementTextLength, textIndexFromElementOffset);
1714
1715         SysTryReturn(NID_GRP
1716                 , pTextElement
1717                 , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text element.");
1718
1719         r = __pCompositeText->ChangeTextOffset(pText, elementIndex, gap);
1720         SysTryReturn(NID_GRP
1721                 , r == E_SUCCESS
1722                 , r, r, "[%s] Propagating.", GetErrorMessage(r));
1723
1724         return E_SUCCESS;
1725 }
1726
1727 result
1728 TextObject::NotifyTextChanged(wchar_t* pText, int textOffset, int textLength, int gap)
1729 {
1730         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1731
1732         result r = E_SUCCESS;
1733         int startTextIndex = 0;
1734
1735         r = __pCompositeText->NotifyTextChanged(pText, textOffset, textLength, gap, __pDefaultFont,
1736                                                                    __defaultForegroundColor, __defaultBackgroundColor, __defaultOutlineColor);
1737
1738         SysTryCatch(NID_GRP
1739                 , r == E_SUCCESS
1740                 , , E_SYSTEM, "[E_SYSTEM] Fail to update change information.");
1741
1742         startTextIndex = __pCompositeText->GetWorkStart();
1743
1744         if (__wrap != TEXT_OBJECT_WRAP_TYPE_NONE)
1745         {
1746                 if (gap > 0)
1747                 {
1748                         NotifyTextAdded(startTextIndex, gap);
1749                         if (gap == 1)
1750                         {
1751                                 InputText(startTextIndex);
1752                         }
1753                 }
1754                 else if (gap < 0)
1755                 {
1756                         NotifyTextDeleted(startTextIndex, -gap);
1757
1758                         if (gap == -1)
1759                         {
1760                                 RemoveText(startTextIndex);
1761                         }
1762                 }
1763                 else
1764                 {
1765                         UpdateChangedInfo(startTextIndex, 0);
1766
1767                         ChangeText(startTextIndex);
1768                 }
1769         }
1770         else
1771         {
1772                 UpdateChangedInfo(startTextIndex, 0);
1773         }
1774
1775         return E_SUCCESS;
1776
1777 CATCH:
1778         if (__pCompositeText->GetElementCount() == 0)
1779         {
1780                 RemoveAll();
1781                 TextSimple* pSimpleText = new (std::nothrow)TextSimple(pText, textLength, TEXT_ELEMENT_SOURCE_TYPE_EXTERNAL);
1782                 AppendElement(*pSimpleText);
1783
1784                 SetCursorIndex(0);
1785                 UpdateChangedInfo(0, 0);
1786         }
1787
1788         return E_SUCCESS;
1789 }
1790
1791 int
1792 TextObject::GetTextIndexFromPosition(int lcX, int lcY, bool cursorMode) const
1793 {
1794         IF_NOT_CONSTRUCTED(return -1);
1795
1796         int lineCount = __pTextColumn->GetTotalLineCount();
1797         if (lineCount <= 0)
1798         {
1799                 return -1;
1800         }
1801
1802         int pcX = _ResUtil::ConvertToPhyCoord(lcX);
1803         int pcY = _ResUtil::ConvertToPhyCoord(lcY);
1804
1805         if (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE)
1806         {
1807                 return GetTextIndexFromPositionInNoneWrap(pcX, pcY, !cursorMode);
1808         }
1809         else
1810         {
1811                 return GetTextIndexFromPositionInWrap(pcX, pcY, !cursorMode);
1812         }
1813 }
1814
1815 int
1816 TextObject::GetTextIndexFromPositionAtLine(int lineIndex, int lcX, bool cursorMode) const
1817 {
1818         IF_NOT_CONSTRUCTED(return -1);
1819
1820         SysTryReturn(NID_GRP
1821                         , lineIndex >= 0
1822                         , -1, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
1823
1824         TextLine* pTextLine = __pTextColumn->GetTextLine(lineIndex);
1825         SysTryReturn(NID_GRP
1826                         , pTextLine
1827                         , -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
1828
1829         int pcX = _ResUtil::ConvertToPhyCoord(lcX);
1830         int lineOffset = pTextLine->GetTextOffset();
1831         int lineLength = pTextLine->GetTextLength();
1832         int length = 0;
1833         TextElementType objectType;
1834         Rectangle lineBounds = pTextLine->GetBounds();
1835         Dimension lineTextSize;
1836         pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
1837
1838         switch (__align & TEXT_ALIGNMASK_HORIZ)
1839         {
1840         case TEXT_OBJECT_ALIGNMENT_LEFT:
1841                 break;
1842
1843         case TEXT_OBJECT_ALIGNMENT_CENTER:
1844                 pcX -= (lineBounds.width - lineTextSize.width) / 2;
1845                 break;
1846
1847         case TEXT_OBJECT_ALIGNMENT_RIGHT:
1848                 pcX -= (lineBounds.width - lineTextSize.width);
1849                 break;
1850         }
1851
1852         if (pcX < 0)
1853         {
1854                 pcX = 0;
1855         }
1856
1857         __pCompositeText->SetWrap(TEXT_OBJECT_WRAP_TYPE_NONE);
1858
1859         int endType = 0;
1860
1861         if (cursorMode)
1862         {
1863                 __pCompositeText->ForwardAnalyzeWithFocusedObjectType(lineOffset, lineLength, pcX, length, objectType);
1864         }
1865         else
1866         {
1867                 endType = __pCompositeText->ForwardAnalyzeInNoneCursorMode(lineOffset, lineLength, pcX, length);
1868         }
1869
1870         __pCompositeText->SetWrap(__wrap);
1871
1872         if (!cursorMode)
1873         {
1874                 if (endType == -1)
1875                 {
1876                         return -1;
1877                 }
1878         }
1879
1880         int index = pTextLine->GetTextOffset() + length;
1881         if (pTextLine->GetEndType() == TEXT_RETBY_LINEFEED && lineLength == length && pTextLine->GetTextOffset() < index)
1882         {
1883                 index--;
1884         }
1885
1886         if (index != GetTextLength() && index == lineOffset + lineLength)
1887         {
1888                 TextElement* pTextElement = GetElementAtTextIndex(index-1);
1889                 if (pTextElement != null)
1890                 {
1891                         const TextSimple* pSimpleText = dynamic_cast <const TextSimple*>(pTextElement);
1892                         if (pSimpleText != null)
1893                         {
1894                                 const wchar_t* pText = pSimpleText->GetText();
1895                                 SysTryReturn(NID_GRP
1896                                         , pText
1897                                         , -1, E_SYSTEM, "[E_SYSTEM] Fail to get text.");
1898
1899                                 int i = index - 1 - pSimpleText->GetTextOffset();
1900                                 SysTryReturn(NID_GRP
1901                                         , i >= 0 && i < pSimpleText->GetTextLength()
1902                                         , -1, E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] text index(%d) must greater than 0 and must be less than total string length(%d)",i, pSimpleText->GetTextLength());
1903
1904                                 if (pText[i] == L' ')
1905                                 {
1906                                         index--;
1907                                 }
1908                         }
1909                 }
1910         }
1911
1912         SetLastResult(E_SUCCESS);
1913
1914         return index;
1915 }
1916
1917 result
1918 TextObject::SetFirstDisplayLineIndexFromTextIndex(int textIndex)
1919 {
1920         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1921
1922         if (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE)
1923         {
1924                 return SetFirstDisplayLineIndexFromTextIndexInNoneWrap(textIndex);
1925         }
1926         else
1927         {
1928                 return SetFirstDisplayLineIndexFromTextIndexInWrap(textIndex);
1929         }
1930 }
1931
1932 result
1933 TextObject::SetCutLinkViewMode(bool enable)
1934 {
1935         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1936
1937         if (__linkViewModeEnabled == enable)
1938         {
1939                 return E_SUCCESS;
1940         }
1941
1942         __linkViewModeEnabled = enable;
1943         return E_SUCCESS;
1944 }
1945
1946 int
1947 TextObject::GetCutLinkIndexFromPositionData(int lcX, int lcY) const
1948 {
1949         IF_NOT_CONSTRUCTED(return -1);
1950
1951         result r = E_SUCCESS;
1952         int lineCount = __pTextColumn->GetTotalLineCount();
1953         if (lineCount <= 0)
1954         {
1955                 return -1;
1956         }
1957
1958         int textIndex = 0;
1959         int pcX = _ResUtil::ConvertToPhyCoord(lcX);
1960         int pcY = _ResUtil::ConvertToPhyCoord(lcY);
1961
1962         if (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE)
1963         {
1964                 textIndex = GetTextIndexFromPositionInNoneWrap(pcX, pcY, false);
1965         }
1966         else
1967         {
1968                 textIndex = GetTextIndexFromPositionInWrap(pcX, pcY, false);
1969         }
1970
1971         if (textIndex < 0)
1972         {
1973                 return -1;
1974         }
1975
1976         int width = 0;
1977         int height = 0;
1978         Point absPoint;
1979         Point relPoint;
1980         if (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE)
1981         {
1982                 r = GetTextPositionInfoInNoneWrapAt(textIndex, width, height, absPoint.x, absPoint.y, relPoint.x, relPoint.y);
1983         }
1984         else
1985         {
1986                 r = GetTextPositionInfoInWrapAt(textIndex, width, height, absPoint.x, absPoint.y, relPoint.x, relPoint.y);
1987         }
1988         SysTryReturn(NID_GRP
1989                 , r == E_SUCCESS
1990                 , -1, r, "[%s] Propagating.", GetErrorMessage(r));
1991
1992         SysTryReturn(NID_GRP
1993                 , pcY + __pcRect.y >= relPoint.y
1994                 , -1, E_SYSTEM, "[E_SYSTEM] Fail to get text position information");
1995
1996         return __pCompositeText->GetCutLinkElementIndexAt(textIndex);
1997 }
1998
1999 TextElement*
2000 TextObject::GetCutLinkElementAtCutLinkElementIndex(int linkIndex) const
2001 {
2002         IF_NOT_CONSTRUCTED(return null);
2003
2004         return __pCompositeText->GetCutLinkElementAtCutLinkElementIndex(linkIndex);
2005 }
2006
2007 result
2008 TextObject::SetCutLinkColor(LinkType linkType, const Color& color, const Color& colorInSelect)
2009 {
2010         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
2011
2012         SysTryReturn(NID_GRP
2013                 , LINK_TYPE_NONE < linkType && linkType < LINK_TYPE_MAX
2014                 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
2015
2016         switch (linkType)
2017         {
2018         case LINK_TYPE_URL:
2019                 __isUrlLinkColorDefined = true;
2020                 __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_URL_NORMAL] = color;
2021                 __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_URL_SELECT] = colorInSelect;
2022                 break;
2023
2024         case LINK_TYPE_EMAIL:
2025                 __isEmailLinkColorDefined = true;
2026                 __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_EMAIL_NORMAL] = color;
2027                 __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_EMAIL_SELECT] = colorInSelect;
2028                 break;
2029
2030         case LINK_TYPE_TEL_NUM:
2031                 __isPhoneNumberLinkColorDefined = true;
2032                 __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_PHONE_NUMBER_NORMAL] = color;
2033                 __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_PHONE_NUMBER_SELECT] = colorInSelect;
2034                 break;
2035
2036         default:
2037                 break;
2038         }
2039
2040         int totalCutlinkTextCount = __pCompositeText->GetCutLinkElementCount();
2041         for (int i = 0; i < totalCutlinkTextCount; i++)
2042         {
2043                 TextCutLink* pCutlinkText = dynamic_cast < TextCutLink* >(__pCompositeText->GetCutLinkElementAtCutLinkElementIndex(i));
2044                 SysTryReturn(NID_GRP
2045                         , pCutlinkText
2046                         , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to convert to cutlink element.");
2047
2048                 if (pCutlinkText->GetCutLinkType() == linkType)
2049                 {
2050                         pCutlinkText->SetUserColor(color, colorInSelect);
2051                 }
2052         }
2053
2054         return E_SUCCESS;
2055 }
2056
2057 result
2058 TextObject::ResetCutLinkColor(LinkType linkType)
2059 {
2060         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
2061
2062         SysTryReturn(NID_GRP
2063                 , LINK_TYPE_NONE < linkType && linkType < LINK_TYPE_MAX
2064                 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
2065
2066         switch (linkType)
2067         {
2068         case LINK_TYPE_URL:
2069                 __isUrlLinkColorDefined = false;
2070                 break;
2071
2072         case LINK_TYPE_EMAIL:
2073                 __isEmailLinkColorDefined = false;
2074                 break;
2075
2076         case LINK_TYPE_TEL_NUM:
2077                 __isPhoneNumberLinkColorDefined = false;
2078                 break;
2079
2080         default:
2081                 break;
2082         }
2083
2084         int totalCutlinkTextCount = __pCompositeText->GetCutLinkElementCount();
2085         for (int i = 0; i < totalCutlinkTextCount; i++)
2086         {
2087                 TextCutLink* pCutlinkText = dynamic_cast < TextCutLink* >(__pCompositeText->GetCutLinkElementAtCutLinkElementIndex(i));
2088                 SysTryReturn(NID_GRP
2089                         , pCutlinkText
2090                         , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to convert to cutlink element.");
2091
2092                 if (pCutlinkText->GetCutLinkType() == linkType)
2093                 {
2094                         pCutlinkText->ResetUserColor();
2095                 }
2096         }
2097
2098         return E_SUCCESS;
2099 }
2100
2101 result
2102 TextObject::GetCutLinkBounds(int cutLinkIndex, Point& startPoint, Point& endPoint) const
2103 {
2104         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
2105
2106         result r = E_SUCCESS;
2107         int textIndex = 0;
2108         int textLength = 0;
2109         int width = 0;
2110         int heigth = 0;
2111         Point tempPoint;
2112
2113         r = __pCompositeText->GetCutLinkObjectInfo(cutLinkIndex, textIndex, textLength);
2114         SysTryCatch(NID_GRP
2115                 , r == E_SUCCESS
2116                 , , r, "[%s] Propagating.", GetErrorMessage(r));
2117
2118         if (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE)
2119         {
2120                 r = GetTextPositionInfoInNoneWrapAt(textIndex, width, heigth, tempPoint.x, tempPoint.y, startPoint.x, startPoint.y);
2121                 SysTryCatch(NID_GRP
2122                         , r == E_SUCCESS
2123                         , , r, "[%s] Propagating.", GetErrorMessage(r));
2124
2125                 r = GetTextPositionInfoInNoneWrapAt(textIndex + textLength - 1, width, heigth, tempPoint.x, tempPoint.y, endPoint.x, endPoint.y);
2126                 SysTryCatch(NID_GRP
2127                         , r == E_SUCCESS
2128                         , , r, "[%s] Propagating.", GetErrorMessage(r));
2129         }
2130         else
2131         {
2132                 r = GetTextPositionInfoInWrapAt(textIndex, width, heigth, tempPoint.x, tempPoint.y, startPoint.x, startPoint.y);
2133                 SysTryCatch(NID_GRP
2134                         , r == E_SUCCESS
2135                         , , r, "[%s] Propagating.", GetErrorMessage(r));
2136
2137                 r = GetTextPositionInfoInWrapAt(textIndex + textLength - 1, width, heigth, tempPoint.x, tempPoint.y, endPoint.x, endPoint.y);
2138                 SysTryCatch(NID_GRP
2139                         , r == E_SUCCESS
2140                         , , r, "[%s] Propagating.", GetErrorMessage(r));
2141         }
2142
2143         endPoint.x = endPoint.x + width;
2144         endPoint.y = endPoint.y + heigth;
2145
2146         if (_ResUtil::NeedToConvertCoord())
2147         {
2148                 startPoint.x = _ResUtil::ConvertToVirCoord(startPoint.x);
2149                 startPoint.y = _ResUtil::ConvertToVirCoord(startPoint.y);
2150                 endPoint.x = _ResUtil::ConvertToVirCoord(endPoint.x);
2151                 endPoint.y = _ResUtil::ConvertToVirCoord(endPoint.y);
2152         }
2153
2154         return E_SUCCESS;
2155
2156 CATCH:
2157         startPoint.x = -1;
2158         startPoint.y = -1;
2159         endPoint.x = -1;
2160         endPoint.y = -1;
2161
2162         return r;
2163 }
2164
2165 result
2166 TextObject::GetTextPositionInfoAt(int textIndex, int& width, int& height, int& absX, int& absY, int& logicalX, int& logicalY) const
2167 {
2168         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
2169
2170         result r = E_SUCCESS;
2171         int lineCount = __pTextColumn->GetTotalLineCount();
2172
2173         if (lineCount < 1)
2174         {
2175                 _Font* pFont = _Font::GetInstance(*_FontImpl::GetInstance(*__pDefaultFont));
2176                 SysTryReturn(NID_GRP
2177                                 , pFont
2178                                 , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get native font instance.");
2179                 int maxHeight = TextUtility::GetFontMaxHeight(pFont);
2180
2181                 int posX = 0;
2182                 int posY = 0;
2183                 absX = 0;
2184                 absY = 0;
2185
2186                 if (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE)
2187                 {
2188                         switch (__align & TEXT_ALIGNMASK_VERT)
2189                         {
2190                         case TEXT_OBJECT_ALIGNMENT_TOP:
2191                                 break;
2192
2193                         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
2194                                 posY += (__pcRect.height - maxHeight) / 2;
2195                                 break;
2196
2197                         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
2198                                 posY += (__pcRect.height - maxHeight);
2199                                 break;
2200                         }
2201                         logicalY = __pcRect.y + posY;
2202
2203                         switch (__align & TEXT_ALIGNMASK_HORIZ)
2204                         {
2205                         case TEXT_OBJECT_ALIGNMENT_LEFT:
2206                                 break;
2207
2208                         case TEXT_OBJECT_ALIGNMENT_CENTER:
2209                                 posX += __pcRect.width / 2;
2210                                 break;
2211
2212                         case TEXT_OBJECT_ALIGNMENT_RIGHT:
2213                                 posX += __pcRect.width;
2214                                 break;
2215                         }
2216                         logicalX = __pcRect.x + posX;
2217                 }
2218                 else
2219                 {
2220                         int lineHeight = maxHeight + __pCompositeText->GetLineSpace();
2221                         TextObjectAlignment alignment = __pCompositeText->GetElementVerticalAlignment();
2222                         switch (alignment & TEXT_ALIGNMASK_VERT)
2223                         {
2224                         case TEXT_OBJECT_ALIGNMENT_TOP:
2225                                 // fall through
2226                         default:
2227                                 break;
2228
2229                         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
2230                                 posY += (lineHeight - maxHeight) / 2;
2231                                 break;
2232
2233                         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
2234                                 posY += lineHeight - maxHeight;
2235                                 break;
2236                         }
2237
2238                         logicalX = __pcRect.x;
2239                         logicalY = posY + __pcRect.y;
2240                 }
2241
2242                 width = 0;
2243                 height = maxHeight;
2244                 absX = posX;
2245                 absY = posY;
2246         }
2247         else
2248         {
2249                 if (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE)
2250                 {
2251                         r = GetTextPositionInfoInNoneWrapAt(textIndex, width, height, absX, absY, logicalX, logicalY);
2252                 }
2253                 else
2254                 {
2255                         r = GetTextPositionInfoInWrapAt(textIndex, width, height, absX, absY, logicalX, logicalY);
2256                 }
2257
2258                 SysTryReturn(NID_GRP
2259                         , r == E_SUCCESS
2260                         , r, r, "[%s] Propagating.", GetErrorMessage(r));
2261         }
2262
2263         if (_ResUtil::NeedToConvertCoord())
2264         {
2265                 width = _ResUtil::ConvertToVirCoord(width);
2266                 height = _ResUtil::ConvertToVirCoord(height);
2267                 absX = _ResUtil::ConvertToVirCoord(absX);
2268                 absY = _ResUtil::ConvertToVirCoord(absY);
2269                 logicalX = _ResUtil::ConvertToVirCoord(logicalX);
2270                 logicalY = _ResUtil::ConvertToVirCoord(logicalY);
2271         }
2272
2273         return E_SUCCESS;
2274 }
2275
2276 result
2277 TextObject::SetTextObjectEllipsisType(TextObjectEllipsisType type)
2278 {
2279         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
2280
2281         SysTryReturn(NID_GRP
2282                 , TEXT_OBJECT_ELLIPSIS_TYPE_INVALID < type && type < TEXT_OBJECT_ELLIPSIS_TYPE_MAX
2283                 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
2284
2285         __textObjectEllipsisType = type;
2286         __pCompositeText->SetTextObjectEllipsisType(type);
2287
2288         return E_SUCCESS;
2289 }
2290
2291 result
2292 TextObject::NotifyTextAdded(int textIndex, int textLength)
2293 {
2294         result r = E_SUCCESS;
2295
2296         r = __pTextColumn->SetChangeAction(TextColumn::TEXT_CHANGE_INSERT, textIndex, textLength);
2297         SysTryReturn(NID_GRP
2298                 , r == E_SUCCESS
2299                 , r, r, "[%s] Propagating.", GetErrorMessage(r));
2300
2301         if ((__pCompositeText->IsWidthManagerEnabled() == true) && (__wrap == TEXT_OBJECT_WRAP_TYPE_WORD))
2302         {
2303                 __pTextWidthManager->InformTextInsert(textIndex, textLength);
2304         }
2305
2306         __isChanged = true;
2307
2308         return E_SUCCESS;
2309 }
2310
2311 result
2312 TextObject::NotifyTextDeleted(int textIndex, int textLength)
2313 {
2314         result r = E_SUCCESS;
2315
2316         r = __pTextColumn->SetChangeAction(TextColumn::TEXT_CHANGE_REMOVE, textIndex, textLength);
2317         SysTryReturn(NID_GRP
2318                 , r == E_SUCCESS
2319                 , r, r, "[%s] Propagating.", GetErrorMessage(r));
2320
2321         if ((__pCompositeText->IsWidthManagerEnabled() == true) && (__wrap == TEXT_OBJECT_WRAP_TYPE_WORD))
2322         {
2323                 if (__wrap == TEXT_OBJECT_WRAP_TYPE_WORD)
2324                 {
2325                         __pTextWidthManager->InformTextRemove(textIndex, textLength);
2326                 }
2327         }
2328         __isChanged = true;
2329
2330         return E_SUCCESS;
2331 }
2332
2333 result
2334 TextObject::DrawByLine(_CanvasImpl& canvasImpl, const Rectangle& displayRect)
2335 {
2336         Rectangle targetBounds = displayRect;
2337
2338         return __pTextColumn->Draw(canvasImpl, targetBounds, 0, __pTextColumn->GetTextLength(), __align, __action);
2339 }
2340
2341 int
2342 TextObject::GetTextIndexFromPositionInWrap(int pcX, int pcY, bool cursorMode) const
2343 {
2344         TextLine* pTextLine = null;
2345         Rectangle lineBounds;
2346         int firstDisplayLineIndex = __pTextColumn->GetFirstDisplayLineIndex();
2347         int firstDisplayPositionY = __pTextColumn->GetFirstDisplayPositionY();
2348         int lineCount = __pTextColumn->GetTotalLineCount();
2349         int lineIndex = 0;
2350         TextElementType objectType;
2351
2352         int totalHeight = __pTextColumn->GetTotalHeight();
2353
2354         switch (__align & TEXT_ALIGNMASK_VERT)
2355         {
2356         case TEXT_OBJECT_ALIGNMENT_TOP:
2357                 break;
2358
2359         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
2360                 pcY -= (__pcRect.height - totalHeight) / 2;
2361                 break;
2362
2363         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
2364                 pcY -= (__pcRect.height - totalHeight);
2365                 break;
2366         }
2367
2368         for (lineIndex = firstDisplayLineIndex; lineIndex < lineCount; lineIndex++)
2369         {
2370                 pTextLine = __pTextColumn->GetTextLine(lineIndex);
2371                 SysTryReturn(NID_GRP
2372                         , pTextLine
2373                         , -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
2374
2375                 lineBounds = pTextLine->GetBounds();
2376
2377                 if (lineIndex == firstDisplayLineIndex)
2378                 {
2379                         if (pcY < lineBounds.y - firstDisplayPositionY)
2380                         {
2381                                 return -1;
2382                         }
2383                 }
2384
2385                 if ((lineBounds.y - firstDisplayPositionY <= pcY) && (pcY < lineBounds.y + lineBounds.height - firstDisplayPositionY))
2386                 {
2387                         break;
2388                 }
2389
2390                 if (lineIndex == lineCount - 1)
2391                 {
2392                         if (cursorMode)
2393                         {
2394                                 return pTextLine->GetTextLength() + pTextLine->GetTextOffset();
2395                         }
2396                         else
2397                         {
2398                                 return -1;
2399                         }
2400                 }
2401         }
2402
2403         SysTryReturn(NID_GRP
2404                 , pTextLine
2405                 , -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
2406
2407         int lineOffset = pTextLine->GetTextOffset();
2408         int lineLength = pTextLine->GetTextLength();
2409         int length = 0;
2410         Dimension lineTextSize;
2411         pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
2412
2413         switch (__align & TEXT_ALIGNMASK_HORIZ)
2414         {
2415         case TEXT_OBJECT_ALIGNMENT_LEFT:
2416                 break;
2417
2418         case TEXT_OBJECT_ALIGNMENT_CENTER:
2419                 pcX -= (lineBounds.width - lineTextSize.width) / 2;
2420                 break;
2421
2422         case TEXT_OBJECT_ALIGNMENT_RIGHT:
2423                 pcX -= (lineBounds.width - lineTextSize.width);
2424                 break;
2425         }
2426
2427         if (pcX < 0)
2428         {
2429                 pcX = 0;
2430         }
2431
2432         __pCompositeText->SetWrap(TEXT_OBJECT_WRAP_TYPE_NONE);
2433
2434         int endType = 0;
2435
2436         if (cursorMode)
2437         {
2438                 __pCompositeText->ForwardAnalyzeWithFocusedObjectType(lineOffset, lineLength, pcX, length, objectType);
2439         }
2440         else
2441         {
2442                 endType = __pCompositeText->ForwardAnalyzeInNoneCursorMode(lineOffset, lineLength, pcX, length);
2443         }
2444
2445         __pCompositeText->SetWrap(__wrap);
2446
2447         if (!cursorMode)
2448         {
2449                 if (endType == -1)
2450                 {
2451                         return -1;
2452                 }
2453         }
2454
2455         int index = pTextLine->GetTextOffset() + length;
2456         if (pTextLine->GetEndType() == TEXT_RETBY_LINEFEED && lineLength == length && pTextLine->GetTextOffset() < index)
2457         {
2458                 index--;
2459         }
2460
2461         if (index != GetTextLength() && index == lineOffset + lineLength)
2462         {
2463                 TextElement* pTextElement = GetElementAtTextIndex(index-1);
2464                 if (pTextElement != null)
2465                 {
2466                         const TextSimple* pSimpleText = dynamic_cast <const TextSimple*>(pTextElement);
2467                         if (pSimpleText != null)
2468                         {
2469                                 const wchar_t* pText = pSimpleText->GetText();
2470                                 SysTryReturn(NID_GRP
2471                                         , pText
2472                                         , -1, E_SYSTEM, "[E_SYSTEM] Fail to get text.");
2473
2474                                 int i = index - 1 - pSimpleText->GetTextOffset();
2475                                 SysTryReturn(NID_GRP
2476                                         , i >= 0 && i < pSimpleText->GetTextLength()
2477                                         , -1, E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] text index(%d) must greater than 0 and must be less than total string length(%d)",i, pSimpleText->GetTextLength());
2478
2479                                 if (pText[i] == L' ')
2480                                 {
2481                                         index--;
2482                                 }
2483                         }
2484                 }
2485         }
2486
2487         SetLastResult(E_SUCCESS);
2488
2489         return index;
2490 }
2491
2492 int
2493 TextObject::GetTextIndexFromPositionInNoneWrap(int x, int y, bool cursorMode) const
2494 {
2495         Dimension lineTextSize;
2496         Rectangle lineBounds;
2497         int lineOffset = 0;
2498         int lineLength = 0;
2499         TextLine* pTextLine = null;
2500
2501         pTextLine = __pTextColumn->GetTextLine(0);
2502         SysTryReturn(NID_GRP
2503                 , pTextLine
2504                 , -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
2505
2506         lineOffset = pTextLine->GetTextOffset();
2507         lineLength = pTextLine->GetTextLength();
2508         lineBounds = pTextLine->GetBounds();
2509         pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
2510
2511         switch (__align & TEXT_ALIGNMASK_HORIZ)
2512         {
2513         case TEXT_OBJECT_ALIGNMENT_LEFT:
2514                 break;
2515
2516         case TEXT_OBJECT_ALIGNMENT_CENTER:
2517                 x -= (lineBounds.width - lineTextSize.width) / 2;
2518                 break;
2519
2520         case TEXT_OBJECT_ALIGNMENT_RIGHT:
2521                 x -= (lineBounds.width - lineTextSize.width);
2522                 break;
2523         }
2524
2525         switch (__align & TEXT_ALIGNMASK_VERT)
2526         {
2527         case TEXT_OBJECT_ALIGNMENT_TOP:
2528                 break;
2529
2530         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
2531                 y -= (__pcRect.height - lineTextSize.height) / 2;
2532                 break;
2533
2534         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
2535                 y -= (__pcRect.height - lineTextSize.height);
2536                 break;
2537         }
2538
2539         if (x < 0)
2540         {
2541                 x = 0;
2542         }
2543
2544         int length = 0;
2545         TextElementType objectType = TEXT_ELEMENT_TYPE_TEXT;
2546
2547         int endType = 0;
2548
2549         if (cursorMode)
2550         {
2551                 __pCompositeText->ForwardAnalyzeWithFocusedObjectType(lineOffset, lineLength, x, length, objectType);
2552         }
2553         else
2554         {
2555                 endType = __pCompositeText->ForwardAnalyzeInNoneCursorMode(lineOffset, lineLength, x, length);
2556         }
2557
2558         if (!cursorMode)
2559         {
2560                 if (endType == -1)
2561                 {
2562                         return -1;
2563                 }
2564         }
2565
2566         lineOffset = length + pTextLine->GetTextOffset();
2567
2568         SetLastResult(E_SUCCESS);
2569         return lineOffset;
2570 }
2571
2572 result
2573 TextObject::SetFirstDisplayLineIndexFromTextIndexInWrap(int textIndex)
2574 {
2575         result r = E_SUCCESS;
2576         Rectangle lineBounds;
2577         int firstDisplayPositionY = 0;
2578         int currentTextIndex = textIndex;
2579         int firstDisplayLineIndex = 0;
2580         int lineIndex = 0;
2581         int lineCount = 0;
2582         int remainingHeight = 0;
2583         TextLine* pTextLine = null;
2584         bool isChanged = false;
2585
2586         lineCount = __pTextColumn->GetTotalLineCount();
2587         lineIndex = __pTextColumn->GetLineIndexAtTextIndex(currentTextIndex);
2588         firstDisplayLineIndex = __pTextColumn->GetFirstDisplayLineIndex();
2589
2590         if (lineIndex == -1 && 0 < currentTextIndex && currentTextIndex == __pCompositeText->GetTextLength())
2591         {
2592                 currentTextIndex--;
2593                 lineIndex = __pTextColumn->GetLineIndexAtTextIndex(currentTextIndex);
2594         }
2595
2596         pTextLine = __pTextColumn->GetTextLine(lineIndex);
2597         SysTryReturn(NID_GRP
2598                 , pTextLine
2599                 , r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
2600
2601         lineBounds = pTextLine->GetBounds();
2602
2603         if (firstDisplayLineIndex < lineIndex)
2604         {
2605                 TextLine* pTextLine = null;
2606                 int currentLineIndex = 0;
2607                 int displayLineCount = 0;
2608
2609                 currentLineIndex = firstDisplayLineIndex;
2610                 pTextLine = __pTextColumn->GetTextLine(currentLineIndex);
2611                 SysTryReturn(NID_GRP
2612                         , pTextLine
2613                         , r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
2614
2615                 remainingHeight = __pcRect.height;
2616
2617                 while ((remainingHeight != 0) && firstDisplayLineIndex < lineCount)
2618                 {
2619                         if (remainingHeight < 0)
2620                         {
2621                                 break;
2622                         }
2623
2624                         lineBounds = pTextLine->GetBounds();
2625
2626                         remainingHeight -= lineBounds.height;
2627
2628                         displayLineCount++;
2629                         currentLineIndex++;
2630
2631                         pTextLine = __pTextColumn->GetTextLine(currentLineIndex);
2632                         if (pTextLine == null)
2633                         {
2634                                 break;
2635                         }
2636                 }
2637
2638                 if (lineIndex < firstDisplayLineIndex + displayLineCount)
2639                 {
2640                         if (0 < remainingHeight && 0 < firstDisplayLineIndex)
2641                         {
2642                                 pTextLine = __pTextColumn->GetTextLine(firstDisplayLineIndex - 1);
2643                                 SysTryReturn(NID_GRP
2644                                         , pTextLine
2645                                         , r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
2646
2647                                 while (remainingHeight && pTextLine)
2648                                 {
2649                                         lineBounds = pTextLine->GetBounds();
2650                                         remainingHeight -= lineBounds.height;
2651
2652                                         if (remainingHeight < 0)
2653                                         {
2654                                                 firstDisplayPositionY = lineBounds.y + remainingHeight;
2655                                                 displayLineCount++;
2656                                                 firstDisplayLineIndex--;
2657                                                 break;
2658                                         }
2659                                         else
2660                                         {
2661                                                 firstDisplayPositionY = lineBounds.y;
2662                                         }
2663
2664                                         displayLineCount++;
2665                                         firstDisplayLineIndex--;
2666
2667                                         pTextLine = __pTextColumn->GetTextLine(firstDisplayLineIndex - 1);
2668                                 }
2669
2670                                 isChanged = true;
2671                         }
2672                         else if (remainingHeight < 0 && (lineIndex == firstDisplayLineIndex + displayLineCount - 1))
2673                         {
2674                                 pTextLine = __pTextColumn->GetTextLine(lineIndex);
2675                                 SysTryReturn(NID_GRP
2676                                         , pTextLine
2677                                         , r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
2678
2679                                 lineBounds = pTextLine->GetBounds();
2680                                 remainingHeight = __pcRect.height;
2681
2682                                 firstDisplayLineIndex = lineIndex;
2683                                 firstDisplayPositionY = lineBounds.y;
2684                                 remainingHeight -= lineBounds.height;
2685
2686                                 int currentLineIndex = lineIndex - 1;
2687                                 pTextLine = __pTextColumn->GetTextLine(currentLineIndex);
2688
2689                                 while ((pTextLine != null) && 0 < firstDisplayLineIndex && 0 < remainingHeight)
2690                                 {
2691                                         lineBounds = pTextLine->GetBounds();
2692
2693                                         if (remainingHeight < lineBounds.height)
2694                                         {
2695                                                 firstDisplayLineIndex--;
2696                                                 firstDisplayPositionY = lineBounds.y + (lineBounds.height - remainingHeight);
2697                                                 break;
2698                                         }
2699                                         else
2700                                         {
2701                                                 remainingHeight -= lineBounds.height;
2702                                                 firstDisplayLineIndex--;
2703                                                 firstDisplayPositionY = lineBounds.y;
2704                                                 currentLineIndex--;
2705                                                 pTextLine = __pTextColumn->GetTextLine(currentLineIndex);
2706                                         }
2707                                 }
2708                                 isChanged = true;
2709                         }
2710                 }
2711                 else
2712                 {
2713                         pTextLine = __pTextColumn->GetTextLine(lineIndex);
2714                         SysTryReturn(NID_GRP
2715                                 , pTextLine
2716                                 , r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
2717
2718                         lineBounds = pTextLine->GetBounds();
2719
2720                         remainingHeight = __pcRect.height;
2721
2722                         firstDisplayLineIndex = lineIndex;
2723                         firstDisplayPositionY = lineBounds.y;
2724                         remainingHeight -= lineBounds.height;
2725
2726                         int currentLineIndex = lineIndex - 1;
2727                         pTextLine = __pTextColumn->GetTextLine(currentLineIndex);
2728
2729                         while (pTextLine && 0 < firstDisplayLineIndex && 0 < remainingHeight)
2730                         {
2731                                 lineBounds = pTextLine->GetBounds();
2732
2733                                 if (remainingHeight < lineBounds.height)
2734                                 {
2735                                         firstDisplayLineIndex--;
2736                                         firstDisplayPositionY = lineBounds.y + (lineBounds.height - remainingHeight);
2737                                         break;
2738                                 }
2739                                 else
2740                                 {
2741                                         remainingHeight -= lineBounds.height;
2742                                         firstDisplayLineIndex--;
2743                                         firstDisplayPositionY = lineBounds.y;
2744                                         currentLineIndex--;
2745                                         pTextLine = __pTextColumn->GetTextLine(currentLineIndex);
2746                                 }
2747                         }
2748                         isChanged = true;
2749                 }
2750         }
2751         else
2752         {
2753                 lineBounds = pTextLine->GetBounds();
2754                 firstDisplayLineIndex = lineIndex;
2755                 firstDisplayPositionY = lineBounds.y;
2756                 isChanged = true;
2757         }
2758
2759         if (isChanged == true)
2760         {
2761                 __pTextColumn->SetFirstDisplayLineIndex(firstDisplayLineIndex);
2762                 __pTextColumn->SetFirstDisplayPositionY(firstDisplayPositionY);
2763         }
2764
2765         return E_SUCCESS;
2766 }
2767
2768 result
2769 TextObject::SetFirstDisplayLineIndexFromTextIndexInNoneWrap(int textIndex)
2770 {
2771         result r = E_SUCCESS;
2772         int currentTextIndex = textIndex;
2773         int lineOffset = 0;
2774         int lineEndIndex = 0;
2775         int lineLength = 0;
2776         Rectangle lineBounds;
2777         Dimension lineTextSize;
2778
2779         _Font* pFont = _Font::GetInstance(*_FontImpl::GetInstance(*__pDefaultFont));
2780         SysTryReturn(NID_GRP
2781                         , pFont
2782                         , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get native font instance.");
2783
2784         TextLine* pTextLine = __pTextColumn->GetTextLine(0);
2785         SysTryReturn(NID_GRP
2786                 , pTextLine
2787                 , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
2788
2789         lineOffset = pTextLine->GetTextOffset();
2790         lineLength = pTextLine->GetTextLength();
2791         lineEndIndex = pTextLine->GetTextOffset() + pTextLine->GetTextLength();
2792
2793         lineBounds = pTextLine->GetBounds();
2794         pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
2795
2796         if (currentTextIndex < pTextLine->GetTextOffset() + 1)
2797         {
2798                 lineOffset = currentTextIndex;
2799                 pTextLine->SetTextOffset(lineOffset);
2800                 lineOffset = pTextLine->GetTextOffset();
2801                 if (lineOffset > 0)
2802                 {
2803                         lineOffset--;
2804                         pTextLine->SetTextOffset(lineOffset);
2805                 }
2806
2807                 __pCompositeText->ForwardAnalyze(lineOffset, __pCompositeText->GetTextLength() - lineOffset, lineBounds.width,
2808                                                                                 __wrap, lineLength, lineTextSize.width, lineTextSize.height);
2809
2810                 lineBounds.height = Math::Max(lineBounds.height, lineTextSize.height);
2811                 if (lineBounds.height == 0)
2812                 {
2813                         lineBounds.height = TextUtility::GetFontMaxHeight(pFont);
2814                 }
2815
2816                 pTextLine->SetBounds(lineBounds);
2817                 pTextLine->SetRegion(lineTextSize.width, lineTextSize.height);
2818                 pTextLine->SetTextLength(lineLength);
2819
2820         }
2821         else if (lineEndIndex <= currentTextIndex)
2822         {
2823                 int gapWidth = 0;
2824                 int gapHeight = 0;
2825                 int textCount = 0;
2826                 int tempWidth = 0;
2827
2828                 r = __pCompositeText->GetRegion(lineEndIndex, currentTextIndex - lineEndIndex, gapWidth, gapHeight);
2829                 SysTryReturn(NID_GRP
2830                         , r == E_SUCCESS
2831                         , r, r, "[%s] Propagating.", GetErrorMessage(r));
2832
2833                 gapWidth -= lineBounds.width - lineTextSize.width;
2834
2835                 __pCompositeText->ForwardAnalyze(lineOffset, __pCompositeText->GetTextLength() - lineOffset, gapWidth, __wrap,
2836                                 textCount, tempWidth, gapHeight);
2837
2838                 if (tempWidth < gapWidth)
2839                 {
2840                         lineOffset += (textCount + 1);
2841                 }
2842                 else
2843                 {
2844                         lineOffset += textCount;
2845                 }
2846
2847                 __pCompositeText->ForwardAnalyze(lineOffset, __pCompositeText->GetTextLength() - lineOffset, lineBounds.width,
2848                                                                                 __wrap, lineLength, lineTextSize.width, lineTextSize.height);
2849
2850                 lineBounds.height = Math::Max(lineBounds.height, lineTextSize.height);
2851                 if (lineBounds.height == 0)
2852                 {
2853                         lineBounds.height = TextUtility::GetFontMaxHeight(pFont);
2854                 }
2855
2856                 pTextLine->SetBounds(lineBounds);
2857                 pTextLine->SetRegion(lineTextSize.width, lineTextSize.height);
2858                 pTextLine->SetTextOffset(lineOffset);
2859                 pTextLine->SetTextLength(lineLength);
2860         }
2861
2862         __pTextColumn->SetFirstDisplayLineIndex(0);
2863         __pTextColumn->SetFirstDisplayPositionY(0);
2864
2865         return E_SUCCESS;
2866 }
2867
2868 result
2869 TextObject::GetTextPositionInfoInWrapAt(int textIndex, int& width, int& height, int& absX, int& absY,
2870                                                                                                                                         int& logicalX, int& logicalY) const
2871 {
2872         TextLine* pTextLine = null;
2873         Rectangle lineBounds;
2874
2875         int firstDisplayPositionY = __pTextColumn->GetFirstDisplayPositionY();
2876         int lineCount = __pTextColumn->GetTotalLineCount();
2877         int lineIndex = 0;
2878         int lineOffset = 0;
2879         int lineLength = 0;
2880         int textIndexFromLineOffset = 0;
2881         int lineY = 0;
2882         int posX = 0;
2883         int posY = 0;
2884
2885         _Font* pFont = _Font::GetInstance(*_FontImpl::GetInstance(*__pDefaultFont));
2886         SysTryReturn(NID_GRP
2887                         , pFont
2888                         , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get native font instance.");
2889
2890         for (lineIndex = 0; lineIndex < lineCount; lineIndex++)
2891         {
2892                 pTextLine = __pTextColumn->GetTextLine(lineIndex);
2893                 SysTryReturn(NID_GRP
2894                         , pTextLine
2895                         , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
2896
2897                 lineBounds = pTextLine->GetBounds();
2898                 lineOffset = pTextLine->GetTextOffset();
2899                 lineLength = pTextLine->GetTextLength();
2900
2901                 if (lineOffset <= textIndex && textIndex < lineOffset + lineLength)
2902                 {
2903                         break;
2904                 }
2905
2906                 if (lineIndex + 1 < lineCount)
2907                 {
2908                         lineY += lineBounds.height;
2909                 }
2910         }
2911
2912         SysTryReturn(NID_GRP
2913                 , pTextLine
2914                 , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
2915
2916         if (lineIndex == lineCount)
2917         {
2918                 textIndexFromLineOffset = lineLength;
2919         }
2920         else
2921         {
2922                 textIndexFromLineOffset = textIndex - lineOffset;
2923         }
2924
2925         Dimension lineTextSize;
2926         pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
2927
2928         if (lineTextSize.height == 0)
2929         {
2930                 lineTextSize.height = TextUtility::GetFontMaxHeight(pFont);
2931         }
2932
2933         switch (__align & TEXT_ALIGNMASK_HORIZ)
2934         {
2935         case TEXT_OBJECT_ALIGNMENT_LEFT:
2936                 break;
2937
2938         case TEXT_OBJECT_ALIGNMENT_CENTER:
2939                 posX += (lineBounds.width - lineTextSize.width) / 2;
2940                 break;
2941
2942         case TEXT_OBJECT_ALIGNMENT_RIGHT:
2943                 posX += (lineBounds.width - lineTextSize.width);
2944                 break;
2945         }
2946
2947         switch (__align & TEXT_ALIGNMASK_VERT)
2948         {
2949         case TEXT_OBJECT_ALIGNMENT_TOP:
2950                 break;
2951
2952         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
2953                 posY += (__pcRect.height - __pTextColumn->GetDisplayHeight()) / 2;
2954                 break;
2955
2956         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
2957                 posY += (__pcRect.height - __pTextColumn->GetDisplayHeight());
2958                 break;
2959         }
2960
2961         if (posX < 0)
2962         {
2963                 posX = 0;
2964         }
2965
2966         if (posY < 0)
2967         {
2968                 posY = 0;
2969         }
2970
2971         int length = 0;
2972         int tempWidth = 0;
2973         int tempHeight = 0;
2974
2975         __pCompositeText->SetWrap(TEXT_OBJECT_WRAP_TYPE_NONE);
2976
2977         if (0 < textIndexFromLineOffset)
2978         {
2979                 __pCompositeText->ForwardAnalyze(lineOffset, textIndexFromLineOffset, lineTextSize.width, TEXT_OBJECT_WRAP_TYPE_NONE,
2980                                                                                 length, tempWidth, tempHeight);
2981
2982                 posX += tempWidth;
2983         }
2984
2985         if (textIndex >= 1)
2986         {
2987                 Font* pTextFont = __pCompositeText->GetFont(textIndex - 1);
2988                 tempHeight = TextUtility::GetFontMaxHeight(pTextFont);
2989         }
2990
2991         if (lineIndex == lineCount)
2992         {
2993                 tempWidth = 0;
2994         }
2995
2996         __pCompositeText->SetWrap(__wrap);
2997
2998         if (tempHeight == 0)
2999         {
3000                 tempHeight = TextUtility::GetFontMaxHeight(pFont);
3001         }
3002
3003         TextObjectAlignment alignment = __pCompositeText->GetElementVerticalAlignment();
3004         switch (alignment & TEXT_ALIGNMASK_VERT)
3005         {
3006         case TEXT_OBJECT_ALIGNMENT_TOP:
3007                 // fall through
3008         default:
3009                 break;
3010
3011         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
3012                 lineY = lineY + (lineBounds.height - tempHeight) / 2;
3013                 break;
3014
3015         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
3016                 lineY = lineY + (lineBounds.height - tempHeight);
3017                 break;
3018         }
3019
3020         width = tempWidth;
3021         height = tempHeight;
3022         absX = posX;
3023         absY = lineY;
3024         logicalY = lineY - firstDisplayPositionY + __pcRect.y + posY;
3025         logicalX = posX + __pcRect.x;
3026
3027         return E_SUCCESS;
3028 }
3029
3030 result
3031 TextObject::GetTextPositionInfoInNoneWrapAt(int textIndex, int& width, int& height, int& absX, int& absY,
3032                                                                                                                                 int& logicalX, int& logicalY) const
3033 {
3034         TextLine* pTextLine = null;
3035         pTextLine = __pTextColumn->GetTextLine(0);
3036         SysTryReturn(NID_GRP
3037                 , pTextLine
3038                 , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
3039
3040         int lineOffset = pTextLine->GetTextOffset();
3041         int lineLength = pTextLine->GetTextLength();
3042         int posX = 0;
3043         int posY = 0;
3044         int displaposYX = 0;
3045         int length = 0;
3046         int tempWidth = 0;
3047         int tempHeight = 0;
3048
3049         _Font* pFont = _Font::GetInstance(*_FontImpl::GetInstance(*__pDefaultFont));
3050         SysTryReturn(NID_GRP
3051                         , pFont
3052                         , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get native font instance.");
3053
3054         Dimension lineTextSize;
3055         Rectangle lineBounds;
3056         lineBounds = pTextLine->GetBounds();
3057         pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
3058
3059         if (lineTextSize.height == 0 || pTextLine->GetTextLength() == 0)
3060         {
3061                 lineTextSize.height = TextUtility::GetFontMaxHeight(pFont);
3062         }
3063
3064         switch (__align & TEXT_ALIGNMASK_HORIZ)
3065         {
3066         case TEXT_OBJECT_ALIGNMENT_LEFT:
3067                 break;
3068
3069         case TEXT_OBJECT_ALIGNMENT_CENTER:
3070                 posX += (lineBounds.width - lineTextSize.width) / 2;
3071                 break;
3072
3073         case TEXT_OBJECT_ALIGNMENT_RIGHT:
3074                 posX += (lineBounds.width - lineTextSize.width);
3075                 break;
3076         }
3077
3078         switch (__align & TEXT_ALIGNMASK_VERT)
3079         {
3080         case TEXT_OBJECT_ALIGNMENT_TOP:
3081                 break;
3082
3083         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
3084                 posY += (__pcRect.height - lineTextSize.height) / 2;
3085                 break;
3086
3087         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
3088                 posY += (__pcRect.height - lineTextSize.height);
3089                 break;
3090         }
3091
3092         if (posX < 0)
3093         {
3094                 posX = 0;
3095         }
3096         if (posY < 0)
3097         {
3098                 posY = 0;
3099         }
3100
3101         if (lineOffset > 0)
3102         {
3103                 int tempHeight = 0;
3104                 __pCompositeText->ForwardAnalyze(0, lineOffset, Integer::VALUE_MAX, __wrap, length, displaposYX, tempHeight);
3105         }
3106         else
3107         {
3108                 displaposYX = 0;
3109         }
3110
3111         if (textIndex >= __pCompositeText->GetTextLength())
3112         {
3113                 __pCompositeText->ForwardAnalyze(0, __pCompositeText->GetTextLength(), 0x00ffffff, __wrap, length, tempWidth, tempHeight);
3114
3115                 absX = tempWidth;
3116                 logicalX = tempWidth - displaposYX + __pcRect.x + posX;
3117
3118                 __pCompositeText->ForwardAnalyze(textIndex - 1, 1, 0x00ffffff, __wrap, length, tempWidth, tempHeight);
3119
3120                 TextObjectAlignment alignment = __pCompositeText->GetElementVerticalAlignment();
3121                 switch (alignment & TEXT_ALIGNMASK_VERT)
3122                 {
3123                 case TEXT_OBJECT_ALIGNMENT_TOP:
3124                         // fall through
3125                 default:
3126                         break;
3127
3128                 case TEXT_OBJECT_ALIGNMENT_MIDDLE:
3129                         posY = posY + (lineBounds.height - tempHeight) / 2;
3130                         break;
3131
3132                 case TEXT_OBJECT_ALIGNMENT_BOTTOM:
3133                         posY = posY + (lineBounds.height - tempHeight);
3134                         break;
3135                 }
3136
3137                 width = 0;
3138                 height = tempHeight;
3139                 absY = posY;
3140                 logicalY = __pcRect.y + posY;
3141         }
3142         else
3143         {
3144                 __pCompositeText->ForwardAnalyze(0, textIndex, 0x00ffffff, __wrap, length, tempWidth, tempHeight);
3145
3146                 absX = tempWidth;
3147                 absY = posY;
3148                 logicalX = tempWidth - displaposYX + __pcRect.x + posX;
3149
3150                 __pCompositeText->ForwardAnalyze(textIndex - 1, 1, 0x00ffffff, __wrap, length, tempWidth, tempHeight);
3151
3152                 if (textIndex == __pCompositeText->GetTextLength())
3153                 {
3154                         tempWidth = 0;
3155                 }
3156
3157                 if (tempHeight == 0)
3158                 {
3159                         tempHeight = TextUtility::GetFontMaxHeight(pFont);
3160                 }
3161
3162                 TextObjectAlignment alignment = __pCompositeText->GetElementVerticalAlignment();
3163                 switch (alignment & TEXT_ALIGNMASK_VERT)
3164                 {
3165                 case TEXT_OBJECT_ALIGNMENT_TOP:
3166                         // fall through
3167                 default:
3168                         break;
3169
3170                 case TEXT_OBJECT_ALIGNMENT_MIDDLE:
3171                         posY = posY + (lineBounds.height - tempHeight) / 2;
3172                         break;
3173
3174                 case TEXT_OBJECT_ALIGNMENT_BOTTOM:
3175                         posY = posY + (lineBounds.height - tempHeight);
3176                         break;
3177                 }
3178
3179                 logicalY = __pcRect.y + posY;
3180                 width = tempWidth;
3181                 height = tempHeight;
3182         }
3183
3184         return E_SUCCESS;
3185 }
3186
3187 int
3188 TextObject::GetTotalComposedHeight(void) const
3189 {
3190         return __pCompositeText->GetTotalComposedHeight();
3191 }
3192
3193 int
3194 TextObject::GetLineWidthAt(int lineIndex) const
3195 {
3196         IF_NOT_CONSTRUCTED(return -1);
3197
3198         result r = E_SUCCESS;
3199         TextLine* pTextLine = null;
3200         Dimension lineTextSize;
3201         int lineLength = 0;
3202         int pcWidth = 0;
3203         int lcWidth = 0;
3204
3205         pTextLine = __pTextColumn->GetTextLine(lineIndex);
3206         SysTryCatch(NID_GRP
3207                 , pTextLine
3208                 , , E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
3209
3210         lineLength = pTextLine->GetTextLength();
3211         r = pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
3212         SysTryReturn(NID_GRP
3213                 , r == E_SUCCESS
3214                 , r, r, "[%s] Propagating.", GetErrorMessage(r));
3215
3216         pcWidth = lineTextSize.width;
3217         lcWidth = _ResUtil::ConvertToVirCoord(pcWidth);
3218
3219         SetLastResult(E_SUCCESS);
3220         return lcWidth;
3221
3222 CATCH:
3223         return -1;
3224 }
3225
3226 int
3227 TextObject::GetTotalHeight(void) const
3228 {
3229         IF_NOT_CONSTRUCTED(return -1);
3230
3231         int pcHeight = 0;
3232         if (IsPartialComposingModeEnabled())
3233         {
3234                 pcHeight = __pCompositeText->GetAnalysedTotalHeight();
3235         }
3236         else
3237         {
3238                 pcHeight = __pTextColumn->GetTotalHeight();
3239         }
3240
3241         int lcHeight = _ResUtil::ConvertToVirCoord(pcHeight);
3242
3243         return lcHeight;
3244 }
3245
3246 int
3247 TextObject::GetElementIndexOf(TextElement& textElement) const
3248 {
3249         IF_NOT_CONSTRUCTED(return -1);
3250
3251         return __pCompositeText->GetElementIndexOf(textElement);
3252 }
3253
3254 result
3255 TextObject::RemoveElementAt(int elementIndex, bool deallocate)
3256 {
3257         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
3258
3259         return __pCompositeText->RemoveElementAt(elementIndex, deallocate);
3260 }
3261
3262 result
3263 TextObject::HideFrontSpace(TextObjectSpaceHideType mode)
3264 {
3265         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
3266
3267         __pCompositeText->HideFrontSpace(mode);
3268
3269         return E_SUCCESS;
3270 }
3271
3272 result
3273 TextObject::HideRearSpace(TextObjectSpaceHideType mode)
3274 {
3275         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
3276
3277         __pCompositeText->HideRearSpace(mode);
3278
3279         return E_SUCCESS;
3280 }
3281
3282 int
3283 TextObject::GetSlidingStep(void) const
3284 {
3285         IF_NOT_CONSTRUCTED(return -1);
3286
3287         int lcSlidingStep = _ResUtil::ConvertToVirCoord(__slidingStep);
3288
3289         return lcSlidingStep;
3290 }
3291
3292 result
3293 TextObject::SetSlidingStep(int lcSlidingStep)
3294 {
3295         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
3296
3297         int pcSlidingStep = _ResUtil::ConvertToPhyCoord(lcSlidingStep);
3298
3299         __slidingStep = pcSlidingStep;
3300
3301         return E_SUCCESS;
3302 }
3303
3304 int
3305 TextObject::GetTotalLineCount(void) const
3306 {
3307         IF_NOT_CONSTRUCTED(return -1);
3308
3309         return __pTextColumn->GetTotalLineCount();
3310 }
3311
3312 int
3313 TextObject::GetLineIndexAtTextIndex(int textIndex)  const
3314 {
3315         IF_NOT_CONSTRUCTED(return -1);
3316
3317         return __pTextColumn->GetLineIndexAtTextIndex(textIndex);
3318 }
3319
3320 int
3321 TextObject::GetLineHeightAt(int lineIndex)  const
3322 {
3323         IF_NOT_CONSTRUCTED(return -1);
3324
3325         SysTryReturn(NID_GRP
3326                         , lineIndex >= 0
3327                         , -1, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
3328
3329         int pcHeight = __pTextColumn->GetLineHeightAt(lineIndex);
3330         int lcHeight = _ResUtil::ConvertToVirCoord(pcHeight);
3331
3332         return lcHeight;
3333 }
3334
3335 int
3336 TextObject::GetDisplayLineCount(void)  const
3337 {
3338         IF_NOT_CONSTRUCTED(return -1);
3339
3340         return __pTextColumn->GetDisplayLineCount();
3341 }
3342
3343 int
3344 TextObject::GetFirstDisplayLineIndex(void) const
3345 {
3346         IF_NOT_CONSTRUCTED(return -1);
3347
3348         return __pTextColumn->GetFirstDisplayLineIndex();
3349 }
3350
3351 int
3352 TextObject::GetFirstDisplayPositionY(void) const
3353 {
3354         IF_NOT_CONSTRUCTED(return -1);
3355
3356         int pcFirstDisplayPositionY = __pTextColumn->GetFirstDisplayPositionY();
3357         int lcFirstDisplayPositionY = _ResUtil::ConvertToVirCoord(pcFirstDisplayPositionY);
3358
3359         return lcFirstDisplayPositionY;
3360 }
3361
3362 int
3363 TextObject::GetLineIndexAtPositionY(int lcY) const
3364 {
3365         IF_NOT_CONSTRUCTED(return -1);
3366
3367         int pcY = _ResUtil::ConvertToPhyCoord(lcY);
3368
3369         return __pTextColumn->GetLineIndexAtPositionY(pcY);
3370 }
3371
3372 int
3373 TextObject::GetFirstTextIndexAt(int lineIndex) const
3374 {
3375         IF_NOT_CONSTRUCTED(return -1);
3376
3377         SysTryReturn(NID_GRP
3378                         , lineIndex >= 0
3379                         , -1, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
3380
3381         return __pTextColumn->GetFirstTextIndexAt(lineIndex);
3382 }
3383
3384 int
3385 TextObject::GetTextLengthAt(int lineIndex) const
3386 {
3387         IF_NOT_CONSTRUCTED(return -1);
3388
3389         SysTryReturn(NID_GRP
3390                         , lineIndex >= 0
3391                         , -1, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
3392
3393         return __pTextColumn->GetTextLengthAt(lineIndex);
3394 }
3395
3396 Rectangle
3397 TextObject::GetBounds(void) const
3398 {
3399         IF_NOT_CONSTRUCTED(return Rectangle(0,0,0,0));
3400
3401         return __rect;
3402 }
3403
3404 int
3405 TextObject::GetLineSpace(void) const
3406 {
3407         IF_NOT_CONSTRUCTED(return -1);
3408
3409         int pcLineSpacing = __pCompositeText->GetLineSpace();
3410         int lcLineSpacing = _ResUtil::ConvertToVirCoord(pcLineSpacing);
3411
3412         return lcLineSpacing;
3413 }
3414
3415 int
3416 TextObject::GetTextLength(void) const
3417 {
3418         IF_NOT_CONSTRUCTED(return -1);
3419
3420         return __pCompositeText->GetTextLength();
3421 }
3422
3423 TextObjectAlignment
3424 TextObject::GetElementVerticalAlignment(void) const
3425 {
3426         IF_NOT_CONSTRUCTED(return TEXT_OBJECT_ALIGNMENT_INVALID);
3427
3428         return __pCompositeText->GetElementVerticalAlignment();
3429 }
3430
3431 TextObjectActionType
3432 TextObject::GetAction(void) const
3433 {
3434         IF_NOT_CONSTRUCTED(return TEXT_OBJECT_ACTION_TYPE_NONE);
3435
3436         return __action;
3437 }
3438
3439 TextObjectAlignment
3440 TextObject::GetAlignment(void) const
3441 {
3442         IF_NOT_CONSTRUCTED(return TEXT_OBJECT_ALIGNMENT_INVALID);
3443
3444         return __align;
3445 }
3446
3447 int
3448 TextObject::GetElementCount(void) const
3449 {
3450         IF_NOT_CONSTRUCTED(return -1);
3451
3452         return __pCompositeText->GetElementCount();
3453 }
3454
3455 TextElement*
3456 TextObject::GetElementAtElementIndex(int elementIndex) const
3457 {
3458         IF_NOT_CONSTRUCTED(return null);
3459
3460         return __pCompositeText->GetElementAtElementIndex(elementIndex);
3461 }
3462
3463 result
3464 TextObject::SetRange(int startTextIndex, int textLength)
3465 {
3466         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
3467
3468         return __pCompositeText->SetRange(startTextIndex, textLength);
3469 }
3470
3471 void
3472 TextObject::GetRange(int& startTextIndex, int& textLength) const
3473 {
3474         IF_NOT_CONSTRUCTED(return);
3475
3476         return __pCompositeText->GetRange(startTextIndex, textLength);
3477 }
3478
3479 TextObjectWrapType
3480 TextObject::GetWrap(void) const
3481 {
3482         IF_NOT_CONSTRUCTED(return TEXT_OBJECT_WRAP_TYPE_NONE);
3483
3484         return __wrap;
3485 }
3486
3487 result
3488 TextObject::SetCursorIndex(int cursorIndex)
3489 {
3490         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
3491
3492         SysTryReturn(NID_GRP
3493                 , cursorIndex >= 0
3494                 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
3495
3496         __pCompositeText->SetCursorIndex(cursorIndex);
3497
3498         return E_SUCCESS;
3499 }
3500
3501 int
3502 TextObject::GetCursorIndex(void) const
3503 {
3504         IF_NOT_CONSTRUCTED(return -1);
3505
3506         return __pCompositeText->GetCursorIndex();
3507 }
3508
3509 result
3510 TextObject::SetBlock(bool enable)
3511 {
3512         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
3513
3514         __pCompositeText->SetBlock(enable);
3515
3516         return E_SUCCESS;
3517 }
3518
3519 bool
3520 TextObject::GetBlock(void) const
3521 {
3522         IF_NOT_CONSTRUCTED(return false);
3523
3524         return __pCompositeText->GetBlock();
3525 }
3526
3527 result
3528 TextObject::SetBlockRange(int startTextIndex, int textLength)
3529 {
3530         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
3531
3532         result r = E_SUCCESS;
3533         r = __pCompositeText->SetRange(startTextIndex, textLength);
3534         SysTryReturn(NID_GRP
3535                 , r == E_SUCCESS
3536                 , r, r, "[%s] Propagating.", GetErrorMessage(r));
3537
3538         return E_SUCCESS;
3539 }
3540
3541 void
3542 TextObject::GetBlockRange(int& startTextIndex, int& textLength)
3543 {
3544         IF_NOT_CONSTRUCTED(return);
3545
3546         __pCompositeText->GetRange(startTextIndex, textLength);
3547 }
3548
3549 bool
3550 TextObject::IsAlternateLookEnabled(void) const
3551 {
3552         IF_NOT_CONSTRUCTED(return false);
3553
3554         return __isAlternateLookEnabled;
3555 }
3556
3557 int
3558 TextObject::GetTotalCutLinkElementCount(void) const
3559 {
3560         IF_NOT_CONSTRUCTED(return -1);
3561
3562         return __pCompositeText->GetCutLinkElementCount();
3563 }
3564
3565 result
3566 TextObject::ChangeCutLinkState(int linkIndex, bool select)
3567 {
3568         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
3569
3570         return __pCompositeText->ChangeCutLinkState(linkIndex, select);
3571 }
3572
3573 result
3574 TextObject::ResetAllCutLinkElementsState(void)
3575 {
3576         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
3577
3578         return __pCompositeText->ResetAllCutLinkElementsState();
3579 }
3580
3581 bool
3582 TextObject::IsActionOn(void) const
3583 {
3584         IF_NOT_CONSTRUCTED(return false);
3585
3586         return __isActionOn;
3587 }
3588
3589 TextObjectEllipsisType
3590 TextObject::GetTextObjectEllipsisType(void) const
3591 {
3592         IF_NOT_CONSTRUCTED(return TEXT_OBJECT_ELLIPSIS_TYPE_INVALID);
3593
3594         return __textObjectEllipsisType;
3595 }
3596
3597 result
3598 TextObject::SetWidthManagerEnabled(bool enable)
3599 {
3600         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
3601
3602         if (__pCompositeText->IsWidthManagerEnabled() == enable)
3603         {
3604                 return E_SUCCESS;
3605         }
3606
3607         if (enable)
3608         {
3609                 __pTextWidthManager = new (std::nothrow)TextWidthManager(__pCompositeText);
3610                 SysTryReturn(NID_GRP
3611                         , __pTextWidthManager
3612                         , E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
3613
3614                 __pCompositeText->SetTextWidthManager(__pTextWidthManager);
3615                 __pTextWidthManager->Initialize(__pCompositeText->GetTextLength());
3616         }
3617         else
3618         {
3619                 if (__pTextWidthManager)
3620                 {
3621                         delete __pTextWidthManager;
3622                         __pTextWidthManager = null;
3623                 }
3624         }
3625
3626         __pCompositeText->SetWidthManagerEnabled(enable);
3627
3628         return E_SUCCESS;
3629 }
3630
3631 bool
3632 TextObject::IsWidthManagerEnabled(void) const
3633 {
3634         IF_NOT_CONSTRUCTED(return false);
3635
3636         return __pCompositeText->IsWidthManagerEnabled();
3637 }
3638
3639 result
3640 TextObject::ChangeText(int textIndex)
3641 {
3642         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
3643
3644         if (__sweepInfo.isValid)
3645         {
3646                 __sweepInfo.isValid = false;
3647                 return E_INVALID_STATE;
3648         }
3649
3650         __sweepInfo.isValid = true;
3651         __sweepInfo.sweepType = TEXT_OBJECT_SWEEP_TYPE_REPLACE;
3652         __sweepInfo.sweepEventType = TEXT_OBJECT_SWEEP_EVENT_INSERT;
3653         __sweepInfo.anchorTextIndex = textIndex;
3654         __sweepInfo.sweepRegionStartLineIndex = GetLineIndexAtTextIndex(textIndex);
3655         __sweepInfo.sweepRegionLineCount = 1;
3656         __sweepInfo.anchorLineIndex = __sweepInfo.sweepRegionStartLineIndex;
3657         __sweepInfo.widthChanged = 0;
3658
3659         __pCompositeText->SetTextSweepInfo(&__sweepInfo);
3660
3661         return E_SUCCESS;
3662 }
3663
3664 result
3665 TextObject::InputText(int textIndex)
3666 {
3667         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
3668
3669         if (__sweepInfo.isValid == true)
3670         {
3671                 __sweepInfo.isValid = false;
3672                 return E_INVALID_STATE;
3673         }
3674
3675         __sweepInfo.isValid = true;
3676         __sweepInfo.sweepType = TEXT_OBJECT_SWEEP_TYPE_KEYINPUT;
3677         __sweepInfo.sweepEventType = TEXT_OBJECT_SWEEP_EVENT_INSERT;
3678         __sweepInfo.anchorTextIndex = textIndex;
3679         __sweepInfo.prevAnchorLineIndex = GetLineIndexAtTextIndex(textIndex);
3680
3681         if (__sweepInfo.prevAnchorLineIndex == -1)
3682         {
3683                 __sweepInfo.prevAnchorLineIndex = __pTextColumn->GetTotalLineCount()-1;
3684         }
3685
3686         __pCompositeText->SetTextSweepInfo(&__sweepInfo);
3687
3688         return E_SUCCESS;
3689 }
3690
3691 result
3692 TextObject::RemoveText(int textIndex)
3693 {
3694         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
3695
3696         if (__sweepInfo.isValid == true)
3697         {
3698                 __sweepInfo.isValid = false;
3699                 return E_INVALID_STATE;
3700         }
3701
3702         __sweepInfo.isValid = true;
3703         __sweepInfo.sweepEventType = TEXT_OBJECT_SWEEP_EVENT_REMOVE;
3704         __sweepInfo.anchorTextIndex = textIndex;
3705         __sweepInfo.prevAnchorLineIndex = GetLineIndexAtTextIndex(textIndex);
3706
3707         if (__sweepInfo.prevAnchorLineIndex == -1)
3708         {
3709                 __sweepInfo.prevAnchorLineIndex = __pTextColumn->GetTotalLineCount()-1;
3710         }
3711
3712         __pCompositeText->SetTextSweepInfo(&__sweepInfo);
3713
3714         return E_SUCCESS;
3715 }
3716
3717 result
3718 TextObject::ResetSweepInfo(void)
3719 {
3720         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
3721
3722         __sweepInfo.isValid = false;
3723
3724         return E_SUCCESS;
3725 }
3726
3727 TextObjectSweepInfo
3728 TextObject::GetSweepInfo(void) const
3729 {
3730         TextObjectSweepInfo textSweepInfo;
3731         textSweepInfo.isValid = false;
3732         textSweepInfo.sweepType = TEXT_OBJECT_SWEEP_TYPE_NONE;
3733         textSweepInfo.sweepEventType = TEXT_OBJECT_SWEEP_EVENT_NONE;
3734         textSweepInfo.anchorTextIndex = -1;
3735         textSweepInfo.anchorLineIndex = -1;
3736         textSweepInfo.prevAnchorLineIndex = -1;
3737         textSweepInfo.sweepRegionStartLineIndex = -1;
3738         textSweepInfo.sweepRegionLineCount = -1;
3739         textSweepInfo.insertedLineCount = -1;
3740         textSweepInfo.deletedLineCount = -1;
3741         textSweepInfo.widthChanged = -1;
3742
3743         IF_NOT_CONSTRUCTED(return textSweepInfo);
3744
3745         textSweepInfo.isValid = __sweepInfo.isValid;
3746         textSweepInfo.sweepType = __sweepInfo.sweepType;
3747         textSweepInfo.sweepEventType = __sweepInfo.sweepEventType;
3748         textSweepInfo.anchorTextIndex = __sweepInfo.anchorTextIndex;
3749         textSweepInfo.anchorLineIndex = __sweepInfo.anchorLineIndex;
3750         textSweepInfo.prevAnchorLineIndex = __sweepInfo.prevAnchorLineIndex;
3751         textSweepInfo.sweepRegionStartLineIndex = __sweepInfo.sweepRegionStartLineIndex;
3752         textSweepInfo.sweepRegionLineCount = __sweepInfo.sweepRegionLineCount;
3753         textSweepInfo.insertedLineCount = __sweepInfo.insertedLineCount;
3754         textSweepInfo.deletedLineCount = __sweepInfo.deletedLineCount;
3755         textSweepInfo.widthChanged = __sweepInfo.widthChanged;
3756
3757         return textSweepInfo;
3758 }
3759
3760 result
3761 TextObject::GetSweepComposeLineInfo(int lineIndex, TextObjectSweepComposeLineInfo& textSweepComposeLineInfo) const
3762 {
3763         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
3764
3765         SysTryReturn(NID_GRP
3766                         , lineIndex >= 0
3767                         , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
3768
3769         TextLine* pTextLine = __pTextColumn->GetTextLine(lineIndex);
3770         SysTryReturn(NID_GRP
3771                 , pTextLine
3772                 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
3773
3774         textSweepComposeLineInfo = pTextLine->GetSweepComposeInfo();
3775
3776         return E_SUCCESS;
3777 }
3778
3779 int
3780 TextObject::GetTextOffsetAtLine(int lineIndex) const
3781 {
3782         IF_NOT_CONSTRUCTED(return -1);
3783
3784         SysTryReturn(NID_GRP
3785                         , lineIndex >= 0
3786                         , -1, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
3787
3788         TextLine* pTextLine = __pTextColumn->GetTextLine(lineIndex);
3789         SysTryReturn(NID_GRP
3790                         , pTextLine
3791                         , -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
3792
3793         return pTextLine->GetTextOffset();
3794 }
3795
3796 int
3797 TextObject::GetTextLengthAtLine(int lineIndex) const
3798 {
3799         IF_NOT_CONSTRUCTED(return -1);
3800
3801         SysTryReturn(NID_GRP
3802                         , lineIndex >= 0
3803                         , -1, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
3804
3805         TextLine* pTextLine = __pTextColumn->GetTextLine(lineIndex);
3806         SysTryReturn(NID_GRP
3807                         , pTextLine
3808                         , -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
3809
3810         return pTextLine->GetTextLength();
3811 }
3812
3813 Rectangle
3814 TextObject::GetBoundsAtLine(int lineIndex) const
3815 {
3816         IF_NOT_CONSTRUCTED(return Rectangle(-1, -1, -1, -1));
3817
3818         SysTryReturn(NID_GRP
3819                         , lineIndex >= 0
3820                         , Rectangle(-1, -1, -1, -1), E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
3821
3822         TextLine* pTextLine = __pTextColumn->GetTextLine(lineIndex);
3823         SysTryReturn(NID_GRP
3824                         , pTextLine
3825                         , Rectangle(-1, -1, -1, -1), E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
3826
3827         Rectangle lineBounds = pTextLine->GetBounds();
3828
3829         return lineBounds;
3830 }
3831
3832 Point
3833 TextObject::GetDisplayPositionAtLine(int lineIndex, int textIndexFromLineOffset)
3834 {
3835         IF_NOT_CONSTRUCTED(return Point(-1, -1));
3836
3837         SysTryReturn(NID_GRP
3838                         , lineIndex >= 0
3839                         , Point(-1, -1), E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
3840
3841         TextLine* pTextLine = __pTextColumn->GetTextLine(lineIndex);
3842         SysTryReturn(NID_GRP
3843                         , pTextLine
3844                         , Point(-1, -1), E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
3845
3846         int lineOffset = pTextLine->GetTextOffset();
3847         int lineLength = pTextLine->GetTextLength();
3848         Dimension lineTextSize;
3849         Dimension extentDim;
3850         int textCount = 0;
3851         Rectangle lineBounds;
3852
3853         pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
3854         lineBounds = pTextLine->GetBounds();
3855
3856         __pCompositeText->ForwardAnalyze(lineOffset, textIndexFromLineOffset, lineTextSize.width,
3857                         __wrap, textCount, extentDim.width, extentDim.height);
3858
3859         switch (__align & TEXT_ALIGNMASK_HORIZ)
3860         {
3861         case TEXT_OBJECT_ALIGNMENT_LEFT:
3862                 break;
3863
3864         case TEXT_OBJECT_ALIGNMENT_CENTER:
3865                 extentDim.width += (lineBounds.width - lineTextSize.width) / 2;
3866                 break;
3867
3868         case TEXT_OBJECT_ALIGNMENT_RIGHT:
3869                 extentDim.width += (lineBounds.width - lineTextSize.width);
3870                 break;
3871         }
3872
3873         if (extentDim.width < 0)
3874         {
3875                 extentDim.width = 0;
3876         }
3877
3878         return Point(extentDim.width + __rect.x, lineBounds.y - __pTextColumn->GetFirstDisplayPositionY() + __rect.y);
3879 }
3880
3881 }}} // Tizen::Graphics::_Text
3882