Added exception when the argument is invalid
[platform/framework/native/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 Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0/
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 "FGrpCoordinateSystem.h"
27 #include "FGrp_FontImpl.h"
28 #include "FGrp_CanvasImpl.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_Screen.h"
40 #include "FGrp_CoordinateSystemUtils.h"
41
42 namespace // unnamed
43 {
44         const int DEFAULT_FONT_SIZE = 42;
45 }
46
47 #define IF_NOT_CONSTRUCTED(code) if (this->__pCompositeText == null || this->__pTextColumn == null) \
48         { \
49                 code; \
50         }
51
52 #define Release(x) \
53         if (x) \
54         { \
55                 delete x; \
56                 x = null; \
57         }
58
59 using namespace Tizen::Base::Utility;
60 using namespace Tizen::Base;
61
62 namespace Tizen { namespace Graphics
63 {
64
65 namespace _Text
66 {
67
68 TextObject::TextObject(void)
69 {
70         __action = TEXT_OBJECT_ACTION_TYPE_NONE;
71         __align = (TextObjectAlignment)(TEXT_OBJECT_ALIGNMENT_LEFT | TEXT_OBJECT_ALIGNMENT_TOP);
72         __wrap = TEXT_OBJECT_WRAP_TYPE_NONE;
73         __isActionOn = false;
74         __isChanged = false;
75         __pCompositeText = null;
76         __pDefaultFont = null;
77         __defaultForegroundColor = Color::GetColor(COLOR_ID_BLACK);
78         __defaultBackgroundColor = Color::GetColor(COLOR_ID_WHITE);
79         __defaultOutlineColor = Color::GetColor(COLOR_ID_WHITE);
80         __isAlternateLookEnabled = false;
81         __pTextColumn = null;
82         __textObjectEllipsisType = TEXT_OBJECT_ELLIPSIS_TYPE_TAIL;
83         __isFirstDisplayPositionYChanged = false;
84         __rect.x = 0;
85         __rect.y = 0;
86         __rect.width = 0;
87         __rect.height = 0;
88         __repeatCount = 0;
89         __slidingGap = CoordinateSystem::ConvertToLogicalX(30.0f);
90         __slidingStep = CoordinateSystem::ConvertToLogicalX(2.0f);
91         __linkViewModeEnabled = false;
92         __isUrlLinkColorDefined = false;
93         __isEmailLinkColorDefined = false;
94         __isPhoneNumberLinkColorDefined = false;
95         __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_URL_NORMAL] = Color::GetColor(COLOR_ID_BLUE);
96         __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_URL_SELECT] = Color::GetColor(COLOR_ID_BLUE);
97         __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_EMAIL_NORMAL] = Color::GetColor(COLOR_ID_BLUE);
98         __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_EMAIL_SELECT] = Color::GetColor(COLOR_ID_BLUE);
99         __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_PHONE_NUMBER_NORMAL] = Color::GetColor(COLOR_ID_BLUE);
100         __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_PHONE_NUMBER_SELECT] = Color::GetColor(COLOR_ID_BLUE);
101         __bidiHint = TEXT_BIDI_HINT_NONE;
102         __isDisplayBoundsExpandEnabled = false;
103
104         __sweepInfo.isValid = false;
105         __sweepInfo.sweepType = TEXT_OBJECT_SWEEP_TYPE_NONE;
106         __sweepInfo.sweepEventType = TEXT_OBJECT_SWEEP_EVENT_NONE;
107         __sweepInfo.anchorTextIndex = 0;
108         __sweepInfo.anchorLineIndex = 0;
109         __sweepInfo.prevAnchorLineIndex = 0;
110         __sweepInfo.sweepRegionStartLineIndex = 0;
111         __sweepInfo.sweepRegionLineCount = 0;
112         __sweepInfo.insertedLineCount = 0;
113         __sweepInfo.deletedLineCount = 0;
114         __sweepInfo.widthChanged = 0;
115 }
116
117 TextObject::~TextObject(void)
118 {
119         Release(__pCompositeText);
120         Release(__pTextColumn);
121         Release(__pDefaultFont);
122 }
123
124 result
125 TextObject::Construct(void)
126 {
127         result r = E_SUCCESS;
128
129         __action = TEXT_OBJECT_ACTION_TYPE_NONE;
130         __align = (TextObjectAlignment)(TEXT_OBJECT_ALIGNMENT_LEFT | TEXT_OBJECT_ALIGNMENT_TOP);
131         __wrap = TEXT_OBJECT_WRAP_TYPE_WORD;
132         __isActionOn = false;
133         __isChanged = false;
134         __defaultForegroundColor = Color::GetColor(COLOR_ID_BLACK);
135         __defaultBackgroundColor = Color::GetColor(COLOR_ID_WHITE);
136         __defaultOutlineColor = Color::GetColor(COLOR_ID_WHITE);
137         __isAlternateLookEnabled = false;
138         __linkViewModeEnabled = false;
139         __bidiHint = TEXT_BIDI_HINT_NONE;
140
141         __pCompositeText = new (std::nothrow)TextComposite();
142         SysTryCatch(NID_GRP, __pCompositeText, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
143
144         __pTextColumn = new (std::nothrow)TextColumn(__pCompositeText);
145         SysTryCatch(NID_GRP, __pTextColumn, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
146
147         __pDefaultFont = new (std::nothrow)Font();
148         SysTryCatch(NID_GRP, __pDefaultFont, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
149
150         r = __pDefaultFont->Construct(FONT_STYLE_PLAIN, DEFAULT_FONT_SIZE);
151         SysTryCatch(NID_GRP, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Fail to set font.");
152
153         __pCompositeText->SetWrap(__wrap);
154         __pCompositeText->SetTextSweepInfo(&__sweepInfo);
155
156         return E_SUCCESS;
157
158 CATCH:
159         Release(__pDefaultFont);
160         Release(__pCompositeText);
161         Release(__pTextColumn);
162
163         return r;
164 }
165
166 result
167 TextObject::Construct(const Rectangle& rect)
168 {
169         result r = E_SUCCESS;
170
171         __action = TEXT_OBJECT_ACTION_TYPE_NONE;
172         __align = (TextObjectAlignment)(TEXT_OBJECT_ALIGNMENT_LEFT | TEXT_OBJECT_ALIGNMENT_TOP);
173         __wrap = TEXT_OBJECT_WRAP_TYPE_WORD;
174         __isActionOn = false;
175         __isChanged = false;
176         __defaultForegroundColor = Color::GetColor(COLOR_ID_BLACK);
177         __defaultBackgroundColor = Color::GetColor(COLOR_ID_WHITE);
178         __defaultOutlineColor = Color::GetColor(COLOR_ID_WHITE);
179         __isAlternateLookEnabled = false;
180         __linkViewModeEnabled = false;
181         __bidiHint = TEXT_BIDI_HINT_NONE;
182         __rect = _CoordinateSystemUtils::ConvertToFloat(rect);
183
184         __pCompositeText = new (std::nothrow)TextComposite();
185         SysTryCatch(NID_GRP, __pCompositeText, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
186
187         __pTextColumn = new (std::nothrow)TextColumn(__pCompositeText);
188         SysTryCatch(NID_GRP, __pTextColumn, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
189
190         __pDefaultFont = new (std::nothrow)Font();
191         SysTryCatch(NID_GRP, __pTextColumn, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
192
193         r = __pDefaultFont->Construct(FONT_STYLE_PLAIN, DEFAULT_FONT_SIZE);
194         SysTryCatch(NID_GRP, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Fail to set font.");
195
196         __pCompositeText->SetWrap(__wrap);
197         __pCompositeText->SetTextSweepInfo(&__sweepInfo);
198
199         return E_SUCCESS;
200
201 CATCH:
202         Release(__pDefaultFont);
203         Release(__pCompositeText);
204         Release(__pTextColumn);
205
206         return r;
207 }
208
209 result
210 TextObject::Construct(const FloatRectangle& rect)
211 {
212         result r = E_SUCCESS;
213
214         __action = TEXT_OBJECT_ACTION_TYPE_NONE;
215         __align = (TextObjectAlignment)(TEXT_OBJECT_ALIGNMENT_LEFT | TEXT_OBJECT_ALIGNMENT_TOP);
216         __wrap = TEXT_OBJECT_WRAP_TYPE_WORD;
217         __isActionOn = false;
218         __isChanged = false;
219         __defaultForegroundColor = Color::GetColor(COLOR_ID_BLACK);
220         __defaultBackgroundColor = Color::GetColor(COLOR_ID_WHITE);
221         __defaultOutlineColor = Color::GetColor(COLOR_ID_WHITE);
222         __isAlternateLookEnabled = false;
223         __linkViewModeEnabled = false;
224         __bidiHint = TEXT_BIDI_HINT_NONE;
225         __rect = rect;
226
227         __pCompositeText = new (std::nothrow)TextComposite();
228         SysTryCatch(NID_GRP, __pCompositeText, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
229
230         __pTextColumn = new (std::nothrow)TextColumn(__pCompositeText);
231         SysTryCatch(NID_GRP, __pTextColumn, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
232
233         __pDefaultFont = new (std::nothrow)Font();
234         SysTryCatch(NID_GRP, __pTextColumn, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
235
236         r = __pDefaultFont->Construct(FONT_STYLE_PLAIN, DEFAULT_FONT_SIZE);
237         SysTryCatch(NID_GRP, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Fail to set font.");
238
239         __pCompositeText->SetWrap(__wrap);
240         __pCompositeText->SetTextSweepInfo(&__sweepInfo);
241
242         return E_SUCCESS;
243
244 CATCH:
245         Release(__pDefaultFont);
246         Release(__pCompositeText);
247         Release(__pTextColumn);
248
249         return r;
250 }
251
252 TextObject*
253 TextObject::CloneN(void)
254 {
255         IF_NOT_CONSTRUCTED(return null);
256
257         result r = E_SUCCESS;
258         TextObject* pTextObject = null;
259         TextElement* pTextElement = null;
260         TextElement* pCloneTextElement = null;
261         int count = __pCompositeText->GetElementCount();
262
263         pTextObject = new (std::nothrow)TextObject();
264         SysTryReturn(NID_GRP, pTextObject, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
265
266         r = pTextObject->Construct();
267         SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
268
269         for (int i=0; i < count; i++)
270         {
271                 pTextElement = __pCompositeText->GetElementAtElementIndex(i);
272                 SysTryCatch(NID_GRP, pTextElement, , E_SYSTEM, "[E_SYSTEM] Fail to get text element.");
273
274                 pCloneTextElement = pTextElement->CloneN(SET_ALLVALUE_CLONE,0);
275                 pTextObject->AppendElement(*pCloneTextElement);
276         }
277
278         SetLastResult(E_SUCCESS);
279
280         return pTextObject;
281
282 CATCH:
283         Release(pTextObject);
284
285         return null;
286 }
287
288 result
289 TextObject::Draw(_CanvasImpl& canvasImpl)
290 {
291         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
292
293         if (__rect.width == 0.0f || __rect.height == 0.0f)
294         {
295                 return E_SUCCESS;
296         }
297
298         result r = E_SUCCESS;
299         TextLine* pTextLine = null;
300         FloatRectangle clipRect;
301         FloatRectangle lineBounds;
302         FloatRectangle targetBounds;
303         float totalHeight = 0;
304         float slidingWidth = 0;
305
306         SysTryReturn(NID_GRP, __rect.width > 0.0f && __rect.height > 0.0f, E_INVALID_STATE, E_INVALID_STATE
307                         , "[E_INVALID_STATE] This instance is not constructed yet. (width = %0.6f, height = %0.6f)", __rect.width, __rect.height);
308
309         TextBidiHint bidiHint = _GetTextBidiHint();
310         _SetTextBidiHint(__bidiHint);
311
312         r = Compose();
313         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
314
315         if (__pTextColumn->GetTotalLineCount() <= 1)
316         {
317                 __pTextColumn->SetFirstDisplayLineIndex(0);
318                 __pTextColumn->SetFirstDisplayPositionY(0.0f);
319         }
320
321         targetBounds = __rect;
322
323         if (__action == TEXT_OBJECT_ACTION_TYPE_SLIDE_LEFT)
324         {
325                 if (__pTextColumn->GetTotalLineCount() == 0)
326                 {
327                         return E_SUCCESS;
328                 }
329
330                 totalHeight = TextUtility::GetFontMaxHeightF(__pDefaultFont);
331         }
332         else
333         {
334                 totalHeight = __pTextColumn->GetTotalHeightF();
335         }
336
337         if (totalHeight == 0)
338         {
339                 return E_SUCCESS;
340         }
341
342         if (totalHeight < targetBounds.height)
343         {
344                 switch (__align & TEXT_ALIGNMASK_VERT)
345                 {
346                 case TEXT_OBJECT_ALIGNMENT_TOP:
347                         // fall through
348                 default:
349                         break;
350
351                 case TEXT_OBJECT_ALIGNMENT_MIDDLE:
352                         targetBounds.y += (targetBounds.height - totalHeight) / 2.0f;
353                         break;
354
355                 case TEXT_OBJECT_ALIGNMENT_BOTTOM:
356                         targetBounds.y += targetBounds.height - totalHeight;
357                         break;
358                 }
359         }
360         else
361         {
362                 if (targetBounds.height < totalHeight)
363                 {
364                         if (__action == TEXT_OBJECT_ACTION_TYPE_ABBREV)
365                         {
366                                 int i = 0;
367                                 int lineCount = __pTextColumn->GetTotalLineCount();
368
369                                 if (lineCount == 1)
370                                 {
371                                         totalHeight = targetBounds.height;
372                                 }
373                                 else
374                                 {
375                                         float lineHeight = __pTextColumn->GetLineHeightAtF(0);
376
377                                         if (targetBounds.height < lineHeight)
378                                         {
379                                                 totalHeight = targetBounds.height;
380                                         }
381                                         else
382                                         {
383                                                 lineHeight = 0;
384
385                                                 for (i = 0; i < lineCount; i++)
386                                                 {
387                                                         lineHeight += __pTextColumn->GetLineHeightAtF(i);
388                                                         if (targetBounds.height < lineHeight)
389                                                         {
390                                                                 lineHeight -= __pTextColumn->GetLineHeightAtF(i);
391                                                                 break;
392                                                         }
393                                                 }
394
395                                                 totalHeight = lineHeight;
396                                         }
397                                 }
398                         }
399                         else
400                         {
401                                 goto CONTINUE_PROC;
402                         }
403                 }
404                 else
405                 {
406                         goto CONTINUE_PROC;
407                 }
408
409                 switch (__align & TEXT_ALIGNMASK_VERT)
410                 {
411                 case TEXT_OBJECT_ALIGNMENT_TOP:
412                         // fall through
413                 default:
414                         break;
415
416                 case TEXT_OBJECT_ALIGNMENT_MIDDLE:
417                         targetBounds.y += (targetBounds.height - totalHeight) / 2.0f;
418                         break;
419
420                 case TEXT_OBJECT_ALIGNMENT_BOTTOM:
421                         targetBounds.y += targetBounds.height - totalHeight;
422                         break;
423                 }
424                 targetBounds.height = totalHeight;
425         }
426
427 CONTINUE_PROC:
428         FloatRectangle finalClipRect;
429         clipRect = canvasImpl.GetClipBoundsF();
430
431         finalClipRect.x = (clipRect.x > __rect.x) ? clipRect.x : __rect.x;
432         finalClipRect.y = (clipRect.y > __rect.y) ? clipRect.y: __rect.y;
433         finalClipRect.width = (clipRect.x + clipRect.width > __rect.x + __rect.width) ? (__rect.x + __rect.width) - finalClipRect.x : (clipRect.x + clipRect.width) - finalClipRect.x;
434         finalClipRect.height = (clipRect.y + clipRect.height > __rect.y + __rect.height) ? (__rect.y + __rect.height) - finalClipRect.y : (clipRect.y + clipRect.height) - finalClipRect.y;
435
436         if (__isDisplayBoundsExpandEnabled == true)
437         {
438                 finalClipRect.y = clipRect.y;
439                 finalClipRect.height = clipRect.height;
440         }
441
442         SysTryReturn(NID_GRP, 0.0f <= finalClipRect.width && 0.0f <= finalClipRect.height, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get clip rectangle.");
443
444         canvasImpl.SetClipBounds(finalClipRect);
445
446         switch (__action)
447         {
448         case TEXT_OBJECT_ACTION_TYPE_SLIDE_LEFT:
449                 pTextLine = __pTextColumn->GetTextLine(0);
450                 SysTryReturn(NID_GRP, pTextLine, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
451
452                 lineBounds = pTextLine->GetBoundsF();
453                 __pTextColumn->SetDisplayLineCount(1);
454                 __pTextColumn->SetDisplayHeight(lineBounds.height);
455
456                 slidingWidth = (__pTextColumn->GetSlidingDimension().width > __rect.width) ? __pTextColumn->GetSlidingDimension().width : __rect.width;
457
458                 if (__isActionOn)
459                 {
460                         FloatRectangle slidingRect;
461
462                         targetBounds.width = lineBounds.width;
463                         targetBounds.height = lineBounds.height;
464
465                         slidingRect = targetBounds;
466
467                         slidingRect.x += __pTextColumn->GetSlidingPositionF();
468                         FloatDimension slidingDim = __pTextColumn->GetSlidingDimensionF();
469                         slidingRect.width = slidingDim.width;
470                         slidingRect.height = slidingDim.height;
471
472                         __pCompositeText->Draw(canvasImpl, slidingRect, 0, __pCompositeText->GetTextLength(),
473                                         (TextObjectAlignment)(__align & TEXT_ALIGNMASK_HORIZ), TEXT_OBJECT_ACTION_TYPE_NONE);
474
475                         slidingRect.x += slidingDim.width + __slidingGap;
476                         if (slidingRect.x < targetBounds.x + targetBounds.width)
477                         {
478                                 slidingRect.width = targetBounds.x + targetBounds.width - slidingRect.x;
479                                 __pCompositeText->Draw(canvasImpl, slidingRect, 0, __pCompositeText->GetTextLength()
480                                                 ,(TextObjectAlignment)(__align & TEXT_ALIGNMASK_HORIZ), TEXT_OBJECT_ACTION_TYPE_NONE);
481                         }
482                 }
483                 else
484                 {
485                         pTextLine->Draw(canvasImpl, targetBounds, 0, pTextLine->GetTextLength(),
486                                         (TextObjectAlignment)(__align & TEXT_ALIGNMASK_HORIZ), TEXT_OBJECT_ACTION_TYPE_NONE);
487                 }
488                 break;
489
490         case TEXT_OBJECT_ACTION_TYPE_SLIDE_UP:
491         {
492                 FloatRectangle slidingRect = targetBounds;
493                 slidingRect.y += __pTextColumn->GetSlidingPositionF();
494
495                 int lineCount = __pTextColumn->GetTotalLineCount();
496                 for (int i = 0; i < lineCount; i++)
497                 {
498                         pTextLine = __pTextColumn->GetTextLine(i);
499                         if (pTextLine != null)
500                         {
501                                 lineBounds = pTextLine->GetBoundsF();
502                                 slidingRect.height = lineBounds.height;
503                                 if ((slidingRect.y + slidingRect.height >= targetBounds.y) && (slidingRect.y < targetBounds.y + targetBounds.height))
504                                 {
505                                         pTextLine->Draw(canvasImpl, slidingRect, 0, pTextLine->GetTextLength(),
506                                                         (TextObjectAlignment)(__align & TEXT_ALIGNMASK_HORIZ), TEXT_OBJECT_ACTION_TYPE_NONE);
507                                 }
508                         }
509                         slidingRect.y += slidingRect.height;
510                 }
511         }
512                 break;
513
514         case TEXT_OBJECT_ACTION_TYPE_ABBREV:
515                 if (__pCompositeText->IsTextAbbreviationEnabled())
516                 {
517                         __pCompositeText->DrawAbbrev(canvasImpl, targetBounds, __align);
518                 }
519                 else
520                 {
521                         DrawByLine(canvasImpl, targetBounds);
522                 }
523                 break;
524
525         case TEXT_OBJECT_ACTION_TYPE_NONE:
526                 // fall through
527         default:
528                 DrawByLine(canvasImpl, targetBounds);
529                 break;
530         }
531
532         canvasImpl.SetClipBounds(clipRect);
533         _SetTextBidiHint(bidiHint);
534
535         return E_SUCCESS;
536 }
537
538 result
539 TextObject::GetChangedLineRange(int& startChangedLineIndex, int& endChangedLineIndex)
540 {
541         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
542
543         result r = E_SUCCESS;
544
545         r = Compose();
546         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
547
548         startChangedLineIndex = __sweepInfo.sweepRegionStartLineIndex;
549         endChangedLineIndex =  __sweepInfo.sweepRegionStartLineIndex + __sweepInfo.sweepRegionLineCount - 1;
550
551         return E_SUCCESS;
552 }
553
554 result
555 TextObject::DrawLine(_CanvasImpl& canvasImpl, int lineIndex)
556 {
557         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
558
559         SysTryReturn(NID_GRP, lineIndex >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
560
561         result r = E_SUCCESS;
562         TextLine* pTextLine = null;
563         FloatRectangle lineBounds;
564         float firstDisplayY = __pTextColumn->GetFirstDisplayPositionYF();
565
566         TextBidiHint bidiHint = _GetTextBidiHint();
567         _SetTextBidiHint(__bidiHint);
568
569         r = Compose();
570         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
571
572         pTextLine = __pTextColumn->GetTextLine(lineIndex);
573         if (pTextLine == null)
574         {
575                 SysLog(NID_GRP, "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d, total line count = %d)"
576                                 , lineIndex, __pTextColumn->GetTotalLineCount());
577
578                 return E_INVALID_ARG;
579         }
580
581         lineBounds = pTextLine->GetBoundsF();
582         lineBounds.y = lineBounds.y - firstDisplayY + __rect.y;
583
584         int length = pTextLine->GetTextLength();
585         pTextLine->Draw(canvasImpl, lineBounds, 0, length, __align, TEXT_OBJECT_ACTION_TYPE_NONE);
586
587         _SetTextBidiHint(bidiHint);
588
589         return E_SUCCESS;
590 }
591
592 result
593 TextObject::DrawWithOffset(_CanvasImpl& canvasImpl)
594 {
595         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
596
597         SysTryReturn(NID_GRP, __isActionOn, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Action is off.");
598
599         float slidingStartIndex = __pTextColumn->GetSlidingPositionF();
600         FloatDimension slidingDim = __pTextColumn->GetSlidingDimensionF();
601
602         switch (__action)
603         {
604         case TEXT_OBJECT_ACTION_TYPE_SLIDE_LEFT:
605                 if (__rect.width < slidingDim.width)
606                 {
607                         slidingDim.width = (slidingDim.width > __rect.width) ? slidingDim.width: __rect.width;
608
609                         if (__slidingStep < slidingStartIndex + slidingDim.width + __slidingGap)
610                         {
611                                 slidingStartIndex -= __slidingStep;
612                         }
613                         else
614                         {
615                                 slidingStartIndex += slidingDim.width + __slidingGap;
616
617                                 __repeatCount++;
618                         }
619                 }
620                 else
621                 {
622                         if (0.0f < slidingStartIndex + slidingDim.width)
623                         {
624                                 slidingStartIndex -= __slidingStep;
625                         }
626                         else
627                         {
628                                 slidingStartIndex = __rect.width + __slidingGap + slidingStartIndex;
629                         }
630                 }
631                 __pTextColumn->SetSlidingPosition(slidingStartIndex);
632                 break;
633
634         case TEXT_OBJECT_ACTION_TYPE_SLIDE_UP:
635                 if (slidingStartIndex + slidingDim.height >= 0.0f)
636                 {
637                         slidingStartIndex -= __slidingStep;
638                 }
639                 else
640                 {
641                         slidingStartIndex = __rect.height;
642                 }
643                 __pTextColumn->SetSlidingPosition(slidingStartIndex);
644                 break;
645
646         case TEXT_OBJECT_ACTION_TYPE_ABBREV:
647                 // fall through
648         case TEXT_OBJECT_ACTION_TYPE_NONE:
649                 // fall through
650         default:
651                 break;
652         }
653
654         return Draw(canvasImpl);
655 }
656
657 result
658 TextObject::UpdateChangedInfo(int startTextIndex, int textLength)
659 {
660         result r = E_SUCCESS;
661
662         if (startTextIndex >= 0)
663         {
664                 r = __pTextColumn->SetChangeAction(TextColumn::TEXT_CHANGE_UNKONWN, startTextIndex, 0);
665                 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
666         }
667
668         __isChanged = true;
669
670         if (IsPartialComposingModeEnabled())
671         {
672                 __pCompositeText->InitPartialComposeMode();
673         }
674
675         return E_SUCCESS;
676 }
677
678 bool
679 TextObject::IsChanged(void) const
680 {
681         IF_NOT_CONSTRUCTED(return false);
682
683         return __isChanged;
684 }
685
686 result
687 TextObject::SetPartialComposingModeEnabled(bool enable)
688 {
689         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
690
691         __pCompositeText->SetPartialComposingModeEnabled(enable);
692
693         return E_SUCCESS;
694 }
695
696 bool
697 TextObject::IsPartialComposingModeEnabled(void) const
698 {
699         IF_NOT_CONSTRUCTED(return false);
700
701         return __pCompositeText->IsPartialComposingModeEnabled();
702 }
703
704 result
705 TextObject::Compose(void)
706 {
707         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
708
709         SysTryReturn(NID_GRP, __rect.width >= 0.0f && __rect.height >= 0.0f, E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] This instance is not constructed yet.");
710
711         TextBidiHint bidiHint = _GetTextBidiHint();
712         _SetTextBidiHint(__bidiHint);
713
714         int lineCount = 0;
715         FloatRectangle rect = __rect;
716         FloatRectangle lineBounds;
717
718         if (__pCompositeText->IsPartialComposingModeEnabled())
719         {
720                 if (__pCompositeText->IsComposeDone() || !__isFirstDisplayPositionYChanged)
721                 {
722                         if (GetTotalLineCount() != 0)
723                         {
724                                 return E_SUCCESS;
725                         }
726                 }
727         }
728         else
729         {
730                 if (!__isChanged || __pTextColumn->GetChangeActionEventCount() == 0)
731                 {
732                         return E_SUCCESS;
733                 }
734         }
735
736         __isActionOn = false;
737
738         if (__pTextColumn->GetTotalLineCount() == 0)
739         {
740                 __pTextColumn->SetChangeAction(TextColumn::TEXT_CHANGE_UNKONWN, 0, 0);
741                 __pTextColumn->SetFirstDisplayLineIndex(0);
742                 __pTextColumn->SetFirstDisplayPositionY(0.0f);
743                 __pTextColumn->SetFirstDisplayPositionX(0.0f);
744         }
745
746         ResetSweepInfo();
747         lineCount = __pCompositeText->Compose(rect, __pTextColumn);
748
749         switch (__action)
750         {
751         case TEXT_OBJECT_ACTION_TYPE_SLIDE_LEFT:
752         {
753                 TextLine* pTextLine = __pTextColumn->GetTextLine(0);
754                 if (pTextLine != null)
755                 {
756                         FloatRectangle lineBounds = pTextLine->GetBoundsF();
757                         int lineLength = pTextLine->GetTextLength();
758                         int totalLength = __pCompositeText->GetTextLength();
759
760                         if (lineLength < totalLength || __rect.width < lineBounds.width)
761                         {
762                                 __isActionOn = true;
763                                 __pTextColumn->SetSlidingPosition(0.0f);
764
765                                 FloatDimension slidingDim;
766                                 FloatDimension lineTextSize;
767
768                                 __pCompositeText->GetRegion(0, totalLength, slidingDim.width, slidingDim.height);
769                                 pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
770                                 lineBounds = pTextLine->GetBoundsF();
771
772                                 __pTextColumn->SetSlidingDimension(slidingDim);
773
774                                 lineBounds.height = slidingDim.height;
775                                 lineTextSize.width = lineBounds.width;
776
777                                 pTextLine->SetBounds(lineBounds);
778                                 pTextLine->SetRegion(lineTextSize.width, lineTextSize.height);
779                         }
780                 }
781         }
782         break;
783
784         case TEXT_OBJECT_ACTION_TYPE_SLIDE_UP:
785         {
786                 __pTextColumn->SetSlidingPosition(0.0f);
787
788                 float totalHeight = __pTextColumn->GetTotalHeightF();
789                 FloatDimension slidingDim;
790                 slidingDim.width = __rect.width;
791                 slidingDim.height = totalHeight;
792
793                 __pTextColumn->SetSlidingDimension(slidingDim);
794
795                 if (__rect.height < totalHeight)
796                 {
797                         __isActionOn = true;
798                 }
799         }
800         break;
801
802         case TEXT_OBJECT_ACTION_TYPE_ABBREV:
803                 // fall through
804         case TEXT_OBJECT_ACTION_TYPE_NONE:
805                 // fall through
806         default:
807                 break;
808         }
809
810         __isChanged = false;
811
812         _SetTextBidiHint(bidiHint);
813
814         return E_SUCCESS;
815 }
816
817 int
818 TextObject::GetText(wchar_t* pCopiedText, int textLength) const
819 {
820         IF_NOT_CONSTRUCTED(return -1);
821
822         SysTryReturn(NID_GRP, pCopiedText, -1, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
823         SysTryReturn(NID_GRP, textLength > 0, -1, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
824
825         int textElementCount = 0;
826         int totalLength = 0;
827         int outLength = textLength;
828         int copiedLength = 0;
829         TextElement* pTextElement = null;
830         wchar_t* pSrcText = null;
831         wchar_t* pDstText = null;
832
833         textElementCount = __pCompositeText->GetElementCount();
834         pDstText = pCopiedText;
835
836         for (int i = 0; i < textElementCount && totalLength < outLength; i++)
837         {
838                 pTextElement = __pCompositeText->GetElementAtElementIndex(i);
839                 if (pTextElement == null)
840                 {
841                         return totalLength;
842                 }
843
844                 TextElementType objectType = pTextElement->GetType();
845                 if (objectType == TEXT_ELEMENT_TYPE_TEXT || objectType == TEXT_ELEMENT_TYPE_CUTLINK)
846                 {
847                         int elementTextLength = pTextElement->GetTextLength();
848                         TextSimple* pSimpleText = dynamic_cast < TextSimple* >(pTextElement);
849                         if (pSimpleText != null)
850                         {
851                                 copiedLength = (elementTextLength > outLength - totalLength) ? outLength - totalLength : elementTextLength;
852                                 SysTryReturn(NID_GRP, 0 <= copiedLength, -1, E_SYSTEM, "[E_SYSTEM] Fail to string copy.");
853
854                                 pSrcText = (wchar_t*)pSimpleText->GetText();
855
856                                 result r = TextUtility::CopyText(pDstText, pSrcText, copiedLength);
857                                 SysTryReturn(NID_GRP, r == E_SUCCESS, -1, r, "[%s] Propagating.", GetErrorMessage(r));
858
859                                 pDstText += copiedLength;
860                                 totalLength += copiedLength;
861                         }
862                 }
863         }
864
865         SetLastResult(E_SUCCESS);
866
867         return totalLength;
868 }
869
870 result
871 TextObject::SetFirstDisplayLineIndex(int lineIndex)
872 {
873         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
874
875         if (lineIndex == 0 && __pTextColumn->GetTotalLineCount() == 0)
876         {
877                 return E_SUCCESS;
878         }
879
880         result r = E_SUCCESS;
881         FloatRectangle lineBounds;
882         TextLine* pTextLine = null;
883         float firstDisplayPositionY = 0.0f;
884         float rollbackFirstDisplayPositionY = 0.0f;
885         int rollbackFirstDisplayLineIndex = 0;
886
887         rollbackFirstDisplayPositionY = __pTextColumn->GetFirstDisplayPositionYF();
888         rollbackFirstDisplayLineIndex = __pTextColumn->GetFirstDisplayLineIndex();
889
890         __pTextColumn->SetFirstDisplayLineIndex(lineIndex);
891
892         pTextLine = __pTextColumn->GetTextLine(lineIndex);
893         SysTryCatch(NID_GRP, pTextLine, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text element.");
894
895         lineBounds = pTextLine->GetBoundsF();
896         firstDisplayPositionY = lineBounds.y;
897
898         __pTextColumn->SetFirstDisplayPositionY(firstDisplayPositionY);
899
900         return E_SUCCESS;
901
902 CATCH:
903         __pTextColumn->SetFirstDisplayLineIndex(rollbackFirstDisplayLineIndex);
904         __pTextColumn->SetFirstDisplayPositionY(rollbackFirstDisplayPositionY);
905
906         return r;
907 }
908
909 result
910 TextObject::SetFirstDisplayPositionX(int x)
911 {
912         return SetFirstDisplayPositionX(_CoordinateSystemUtils::ConvertToFloat(x));
913 }
914
915 result
916 TextObject::SetFirstDisplayPositionX(float x)
917 {
918         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
919         SysTryReturn(NID_GRP, __wrap == TEXT_OBJECT_WRAP_TYPE_NONE
920                 , E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] The argument is invalid.");
921
922         TextLine* pTextLine = __pTextColumn->GetTextLine(0);
923         SysTryReturn(NID_GRP, pTextLine, -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
924
925         FloatRectangle lineBounds = pTextLine->GetBoundsF();
926
927         if (x < 0)
928         {
929                 x = 0;
930         }
931
932         __pTextColumn->SetFirstDisplayPositionX(x);
933
934         return E_SUCCESS;
935 }
936
937 int
938 TextObject::GetFirstDisplayPositionX(void) const
939 {
940         return _CoordinateSystemUtils::ConvertToInteger(GetFirstDisplayPositionXF());
941 }
942
943 float
944 TextObject::GetFirstDisplayPositionXF(void) const
945 {
946         IF_NOT_CONSTRUCTED(return -1);
947
948         return __pTextColumn->GetFirstDisplayPositionX();
949 }
950
951 result
952 TextObject::SetFirstDisplayPositionY(int y)
953 {
954         return SetFirstDisplayPositionY(_CoordinateSystemUtils::ConvertToFloat(y));
955 }
956
957 result
958 TextObject::SetFirstDisplayPositionY(float y)
959 {
960         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
961
962         result r = E_SUCCESS;
963
964         if (IsPartialComposingModeEnabled())
965         {
966                 __isFirstDisplayPositionYChanged = true;
967
968                 if (__pCompositeText->GetTotalComposedHeight() <= (y + __rect.height))
969                 {
970                         __pCompositeText->SetComposePartialLimitHeight(y + __rect.height - GetTotalComposedHeight());
971
972                         r = Compose();
973                         SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
974                 }
975         }
976
977         __isFirstDisplayPositionYChanged = false;
978         __pTextColumn->SetFirstDisplayPositionY(y);
979
980         return E_SUCCESS;
981
982 CATCH:
983         __isFirstDisplayPositionYChanged = false;
984         return r;
985 }
986
987 int
988 TextObject::GetMaxLineHeight(void) const
989 {
990         return _CoordinateSystemUtils::ConvertToInteger(GetMaxLineHeightF());
991 }
992
993 float
994 TextObject::GetMaxLineHeightF(void) const
995 {
996         IF_NOT_CONSTRUCTED(return -1);
997
998         float lineMaxHeight = __pCompositeText->GetMaxLineHeightF();
999         float fontMaxHeight = TextUtility::GetFontMaxHeightF(__pDefaultFont);
1000
1001         return (lineMaxHeight > fontMaxHeight) ? lineMaxHeight: fontMaxHeight;
1002 }
1003
1004 bool
1005 TextObject::IsDisplayedAtStartPosition(void) const
1006 {
1007         IF_NOT_CONSTRUCTED(return false);
1008
1009         float firstDisplayPositionY = __pTextColumn->GetFirstDisplayPositionYF();
1010
1011         bool isDisplayedAtStartPosition = (firstDisplayPositionY == 0.0f) ? true : false;
1012
1013         return isDisplayedAtStartPosition;
1014 }
1015
1016 bool
1017 TextObject::IsDisplayedAtEndPosition(void) const
1018 {
1019         IF_NOT_CONSTRUCTED(return false);
1020
1021         float totalHeight = 0.0f;
1022         float firstDisplayPositionY = 0.0f;
1023
1024         firstDisplayPositionY = __pTextColumn->GetFirstDisplayPositionYF();
1025         totalHeight = __pTextColumn->GetTotalHeightF();
1026
1027         bool isDisplayedAtEndPosition = ((totalHeight - firstDisplayPositionY) <= __rect.height) ? true : false;
1028
1029         return isDisplayedAtEndPosition;
1030 }
1031
1032 bool
1033 TextObject::IsDisplayedFirstLine(void) const
1034 {
1035         IF_NOT_CONSTRUCTED(return false);
1036
1037         float firstDisplayPositionY = __pTextColumn->GetFirstDisplayPositionYF();
1038         float firstLineHeight = GetLineHeightAtF(0);
1039
1040         bool isDisplayedFirstLine = false;
1041         if(firstDisplayPositionY == 0.0f || firstDisplayPositionY < firstLineHeight)
1042         {
1043                 isDisplayedFirstLine = true;
1044         }
1045
1046         return isDisplayedFirstLine;
1047 }
1048
1049 bool
1050 TextObject::IsDisplayedLastLine(void) const
1051 {
1052         IF_NOT_CONSTRUCTED(return false);
1053
1054         float totalHeight = 0.0f;
1055         float firstDisplayPositionY = 0.0f;
1056         bool isDisplayedLastLine = false;
1057
1058         firstDisplayPositionY = __pTextColumn->GetFirstDisplayPositionYF();
1059         totalHeight = __pTextColumn->GetTotalHeightF();
1060
1061         float lastLineHeight = GetLineHeightAtF(GetTotalLineCount()-1);
1062
1063         float remainingHeight = totalHeight - firstDisplayPositionY;
1064         if (remainingHeight - __rect.height < lastLineHeight || remainingHeight <= __rect.height)
1065         {
1066                 isDisplayedLastLine = true;
1067         }
1068
1069         return isDisplayedLastLine;
1070 }
1071
1072 result
1073 TextObject::SetAction(TextObjectActionType action)
1074 {
1075         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1076
1077         SysTryReturn(NID_GRP, TEXT_OBJECT_ACTION_TYPE_NONE <= action && action < TEXT_OBJECT_ACTION_TYPE_MAX
1078                 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1079
1080         if (__action != action)
1081         {
1082                 if ((__action == TEXT_OBJECT_ACTION_TYPE_NONE && action == TEXT_OBJECT_ACTION_TYPE_ABBREV) ||
1083                         (__action == TEXT_OBJECT_ACTION_TYPE_ABBREV && action == TEXT_OBJECT_ACTION_TYPE_NONE))
1084                 {
1085                         __action = action;
1086                         UpdateChangedInfo(0, 0);
1087                 }
1088                 else
1089                 {
1090                         __action = action;
1091                         UpdateChangedInfo(0, 0);
1092                 }
1093
1094                 __repeatCount = 0;
1095         }
1096
1097         bool isAbbreviationEnable = (__action == TEXT_OBJECT_ACTION_TYPE_ABBREV) ? true : false;
1098         __pCompositeText->SetTextAbbreviationEnabled(isAbbreviationEnable);
1099
1100         return E_SUCCESS;
1101 }
1102
1103 result
1104 TextObject::SetAlignment(TextObjectAlignment alignment)
1105 {
1106         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1107
1108         SysTryReturn(NID_GRP, TEXT_OBJECT_ALIGNMENT_LEFT <= alignment && alignment < TEXT_OBJECT_ALIGNMENT_INVALID
1109                 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. alignment(%d)", alignment);
1110
1111         if (__align != alignment)
1112         {
1113                 __align = alignment;
1114                 UpdateChangedInfo(0, 0);
1115         }
1116
1117         return E_SUCCESS;
1118 }
1119
1120 result
1121 TextObject::SetBounds(const Rectangle& rect)
1122 {
1123         return SetBounds(_CoordinateSystemUtils::ConvertToFloat(rect));
1124 }
1125
1126 result
1127 TextObject::SetBounds(const FloatRectangle& rect)
1128 {
1129         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1130
1131         SysTryReturn(NID_GRP, (rect.width >= 0.0f) && (rect.height >= 0.0f), E_OUT_OF_RANGE, E_OUT_OF_RANGE
1132                         , "[E_OUT_OF_RANGE] The given rectangle(width:%0.6f,height:%0.6f) is out of range.\n", rect.width, rect.height);
1133
1134         if (__rect.width != rect.width)
1135         {
1136                 UpdateChangedInfo(0, 0);
1137         }
1138
1139         __rect = rect;
1140
1141         return E_SUCCESS;
1142 }
1143
1144 result
1145 TextObject::SetLineSpace(int lineSpacing)
1146 {
1147         return SetLineSpace(_CoordinateSystemUtils::ConvertToFloat(lineSpacing));
1148 }
1149
1150 result
1151 TextObject::SetLineSpace(float lineSpacing)
1152 {
1153         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1154
1155         SysTryReturn(NID_GRP, lineSpacing >= 0.0f, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. lineSpacing(%0.6f)", lineSpacing);
1156
1157         if (__pCompositeText->GetLineSpace() != lineSpacing)
1158         {
1159                 __pCompositeText->SetLineSpace(lineSpacing);
1160                 __isChanged = true;
1161         }
1162
1163         return E_SUCCESS;
1164 }
1165
1166 result
1167 TextObject::SetElementVerticalAlignment(TextObjectAlignment alignment)
1168 {
1169         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1170
1171         SysTryReturn(NID_GRP
1172                         , (alignment & TEXT_OBJECT_ALIGNMENT_TOP) || (alignment & TEXT_OBJECT_ALIGNMENT_MIDDLE) || (alignment & TEXT_OBJECT_ALIGNMENT_BOTTOM) || (alignment & TEXT_OBJECT_ALIGNMENT_BASELINE)
1173                 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. alignment(%d)", alignment);
1174
1175         if (__pCompositeText->GetElementVerticalAlignment() == alignment)
1176         {
1177                 return E_SUCCESS;
1178         }
1179
1180         __pCompositeText->SetElementVerticalAlignment(alignment);
1181         __isChanged = true;
1182
1183         return E_SUCCESS;
1184 }
1185
1186 Dimension
1187 TextObject::GetTextExtent(int startTextIndex, int textLength) const
1188 {
1189         return _CoordinateSystemUtils::ConvertToInteger(GetTextExtentF(startTextIndex,textLength));
1190 }
1191
1192 FloatDimension
1193 TextObject::GetTextExtentF(int startTextIndex, int textLength) const
1194 {
1195         IF_NOT_CONSTRUCTED(return FloatDimension(-1, -1));
1196
1197         TextBidiHint bidiHint = _GetTextBidiHint();
1198         _SetTextBidiHint(__bidiHint);
1199
1200         FloatDimension textSize;
1201         result r = __pCompositeText->GetRegion(startTextIndex, textLength, textSize.width, textSize.height);
1202         SysTryReturn(NID_GRP, r == E_SUCCESS, FloatDimension(-1, -1), r, "[%s] Propagating.", GetErrorMessage(r));
1203
1204         _SetTextBidiHint(bidiHint);
1205
1206         SetLastResult(E_SUCCESS);
1207
1208         return textSize;
1209 }
1210
1211 Dimension
1212 TextObject::GetTextExtent(void) const
1213 {
1214         return _CoordinateSystemUtils::ConvertToInteger(GetTextExtentF());
1215 }
1216
1217 FloatDimension
1218 TextObject::GetTextExtentF(void) const
1219 {
1220         IF_NOT_CONSTRUCTED(return FloatDimension(-1, -1));
1221
1222         TextBidiHint bidiHint = _GetTextBidiHint();
1223         _SetTextBidiHint(__bidiHint);
1224
1225         TextLine* pTextLine = null;
1226         FloatDimension textSize(0.0f, 0.0f);
1227         FloatDimension lineSize(0.0f, 0.0f);
1228         int lineCount = GetTotalLineCount();
1229
1230         for (int i = 0; i < lineCount; i++)
1231         {
1232                 pTextLine = __pTextColumn->GetTextLine(i);
1233                 SysTryReturn(NID_GRP, pTextLine, FloatDimension(-1, -1), E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
1234
1235                 pTextLine->GetRegion(0, pTextLine->GetTextLength(), lineSize.width, lineSize.height);
1236
1237                 if (textSize.width < lineSize.width)
1238                 {
1239                         textSize.width = lineSize.width;
1240                 }
1241         }
1242
1243         textSize.height = GetTotalHeightF();
1244
1245         _SetTextBidiHint(bidiHint);
1246
1247         SetLastResult(E_SUCCESS);
1248
1249         return textSize;
1250 }
1251
1252 result
1253 TextObject::AppendElement(TextElement& textElement)
1254 {
1255         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1256
1257         result r = E_SUCCESS;
1258         TextElementType objecType = textElement.GetType();
1259         if (objecType == TEXT_ELEMENT_TYPE_CUTLINK)
1260         {
1261                 TextCutLink* pLinkText = dynamic_cast < TextCutLink* >(&textElement);
1262                 if (pLinkText != null)
1263                 {
1264                         switch (pLinkText->GetCutLinkType())
1265                         {
1266                         case LINK_TYPE_URL:
1267                                 if (__isUrlLinkColorDefined)
1268                                 {
1269                                         pLinkText->SetUserColor(__linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_URL_NORMAL], __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_URL_SELECT]);
1270                                 }
1271                                 break;
1272
1273                         case LINK_TYPE_EMAIL:
1274                                 if (__isEmailLinkColorDefined)
1275                                 {
1276                                         pLinkText->SetUserColor(__linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_EMAIL_NORMAL], __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_EMAIL_SELECT]);
1277                                 }
1278                                 break;
1279
1280                         case LINK_TYPE_TEL_NUM:
1281                                 if (__isPhoneNumberLinkColorDefined)
1282                                 {
1283                                         pLinkText->SetUserColor(__linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_PHONE_NUMBER_NORMAL],
1284                                                         __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_PHONE_NUMBER_SELECT]);
1285                                 }
1286                                 break;
1287
1288                         default:
1289                                 break;
1290                         }
1291                 }
1292         }
1293
1294         int textIndex = __pCompositeText->GetTextLength();
1295         int elementTextLength = textElement.GetTextLength();
1296
1297         r = __pCompositeText->AppendElement(textElement);
1298         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
1299
1300         int elementCount = __pCompositeText->GetElementCount();
1301         if (elementCount > 0)
1302         {
1303                 __pCompositeText->Optimize(elementCount-1, elementCount-1);
1304         }
1305
1306         if (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE)
1307         {
1308                 UpdateChangedInfo(0, 0);
1309         }
1310         else
1311         {
1312                 NotifyTextAdded(textIndex, elementTextLength);
1313         }
1314
1315         return r;
1316 }
1317
1318 result
1319 TextObject::InsertElementAt(int textIndex, TextElement& textElement)
1320 {
1321         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1322
1323         result r = E_SUCCESS;
1324         TextElementType objecType = textElement.GetType();
1325
1326         if (objecType == TEXT_ELEMENT_TYPE_CUTLINK)
1327         {
1328                 TextCutLink* pLinkText = dynamic_cast < TextCutLink* >(&textElement);
1329                 if (pLinkText != null)
1330                 {
1331                         switch (pLinkText->GetCutLinkType())
1332                         {
1333                         case LINK_TYPE_URL:
1334                                 if (__isUrlLinkColorDefined)
1335                                 {
1336                                         pLinkText->SetUserColor(__linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_URL_NORMAL],
1337                                                         __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_URL_SELECT]);
1338                                 }
1339                                 break;
1340
1341                         case LINK_TYPE_EMAIL:
1342                                 if (__isEmailLinkColorDefined)
1343                                 {
1344                                         pLinkText->SetUserColor(__linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_EMAIL_NORMAL],
1345                                                         __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_EMAIL_SELECT]);
1346                                 }
1347                                 break;
1348
1349                         case LINK_TYPE_TEL_NUM:
1350                                 if (__isPhoneNumberLinkColorDefined)
1351                                 {
1352                                         pLinkText->SetUserColor(__linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_PHONE_NUMBER_NORMAL],
1353                                                         __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_PHONE_NUMBER_SELECT]);
1354                                 }
1355                                 break;
1356
1357                         default:
1358                                 break;
1359                         }
1360                 }
1361         }
1362
1363         r = __pCompositeText->InsertElementAt(textElement, textIndex);
1364         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Fail to insert element.", GetErrorMessage(r));
1365
1366         int elementIndex = __pCompositeText->GetElementIndexOf(textElement);
1367         if (elementIndex != -1)
1368         {
1369                 __pCompositeText->Optimize(elementIndex, elementIndex);
1370         }
1371
1372         if (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE)
1373         {
1374                 UpdateChangedInfo(0, 0);
1375         }
1376         else
1377         {
1378                 NotifyTextAdded(textIndex, textElement.GetTextLength());
1379         }
1380
1381         return r;
1382 }
1383
1384 result
1385 TextObject::RemoveAll(bool deallocate)
1386 {
1387         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1388
1389         result r = __pTextColumn->RemoveAllLines();
1390         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
1391
1392         r = __pCompositeText->RemoveAllElements(deallocate);
1393         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
1394
1395         UpdateChangedInfo(0);
1396
1397         __isActionOn = false;
1398
1399         return r;
1400 }
1401
1402 result
1403 TextObject::Remove(int startTextIndex, int textLength)
1404 {
1405         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1406
1407         SysTryReturn(NID_GRP, startTextIndex >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1408
1409         result r = __pTextColumn->RemoveAllLines();
1410         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
1411
1412         r = __pCompositeText->Remove(startTextIndex, textLength);
1413         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
1414
1415         UpdateChangedInfo(0);
1416
1417         return r;
1418 }
1419
1420 result
1421 TextObject::RemoveElement(TextElement& textElement, bool deallocate)
1422 {
1423         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1424
1425         result r = E_SUCCESS;
1426         int elementIndex = 0;
1427         int textIndex = 0;
1428         int elementTextLength = 0;
1429         TextElement* pCurrentTextElement = null;
1430
1431         elementIndex = __pCompositeText->GetElementIndexOf(textElement);
1432         SysTryReturn(NID_GRP, 0 <= elementIndex, E_INVALID_ARG, E_INVALID_ARG, "[E_SYSTEM] The argument is invalid.");
1433
1434         for (int i = 0; i < elementIndex; i++)
1435         {
1436                 pCurrentTextElement = __pCompositeText->GetElementAtElementIndex(i);
1437                 if (pCurrentTextElement != null)
1438                 {
1439                         textIndex += pCurrentTextElement->GetTextLength();
1440                 }
1441         }
1442
1443         elementTextLength = textElement.GetTextLength();
1444
1445         r = __pCompositeText->RemoveElementAt(elementIndex, deallocate);
1446         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
1447
1448         NotifyTextDeleted(textIndex, elementTextLength);
1449
1450         if (__pCompositeText->GetElementCount() == 0 || GetTextLength() == 0)
1451         {
1452                 __pTextColumn->RemoveAllLines();
1453         }
1454
1455         return r;
1456 }
1457
1458 TextElement*
1459 TextObject::GetElementAtTextIndex(int textIndex) const
1460 {
1461         IF_NOT_CONSTRUCTED(return null);
1462
1463         TextElement* pTextElement = null;
1464         int elementTextLength = 0;
1465         int textIndexFromElementOffset = 0;
1466         int elementIndex = 0;
1467         int elementOffset = 0;
1468
1469         pTextElement = __pCompositeText->GetElementAtTextIndex(textIndex, elementOffset, elementIndex, elementTextLength,textIndexFromElementOffset);
1470         SysTryCatch(NID_GRP, pTextElement, , E_SYSTEM, "[E_SYSTEM] Fail to get text element.");
1471
1472         SetLastResult(E_SUCCESS);
1473         return pTextElement;
1474
1475 CATCH:
1476         elementOffset = 0;
1477         elementIndex = 0;
1478         return null;
1479 }
1480
1481 result
1482 TextObject::SetFont(Font* pFont, int startTextIndex, int textLength)
1483 {
1484         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1485
1486         SysTryReturn(NID_GRP, pFont, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. pFont is null.");
1487         SysTryReturn(NID_GRP, startTextIndex >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1488
1489         result r = E_SUCCESS;
1490         Font* pTmpFont = null;
1491
1492         pTmpFont = _FontImpl::CloneN(const_cast < Font& >(*pFont));
1493         r = GetLastResult();
1494         SysTryReturn(NID_GRP, pTmpFont, r, r, "[%s] Propagating.", GetErrorMessage(r));
1495
1496         Release(__pDefaultFont);
1497
1498         __pDefaultFont = pTmpFont;
1499
1500         __pCompositeText->SetRange(startTextIndex, textLength);
1501         r = __pCompositeText->SetFont(__pDefaultFont);
1502         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
1503
1504         UpdateChangedInfo(__pCompositeText->GetWorkStart(), 0);
1505
1506         return E_SUCCESS;
1507 }
1508
1509 const Font*
1510 TextObject::GetFont(int textIndex) const
1511 {
1512         IF_NOT_CONSTRUCTED(return null);
1513
1514         Font* pFont = __pCompositeText->GetFont(textIndex);
1515         if (pFont == null)
1516         {
1517                 pFont = __pDefaultFont;
1518         }
1519
1520         SetLastResult(E_SUCCESS);
1521         return pFont;
1522 }
1523
1524 result
1525 TextObject::SetDefaultFontSize(int size)
1526 {
1527         return SetDefaultFontSize(_CoordinateSystemUtils::ConvertToFloat(size));
1528 }
1529
1530 result
1531 TextObject::SetDefaultFontSize(float size)
1532 {
1533         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1534
1535         _FontImpl::GetInstance(*__pDefaultFont)->SetSize(size);
1536
1537         return E_SUCCESS;
1538 }
1539
1540 int
1541 TextObject::GetDefaultFontSize(void) const
1542 {
1543         return _CoordinateSystemUtils::ConvertToInteger(GetDefaultFontSizeF());
1544 }
1545
1546 float
1547 TextObject::GetDefaultFontSizeF(void) const
1548 {
1549         IF_NOT_CONSTRUCTED(return -1);
1550
1551         return _FontImpl::GetInstance(*__pDefaultFont)->GetSizeF();
1552 }
1553
1554 result
1555 TextObject::SetFontSize(int size, int startTextIndex, int textLength)
1556 {
1557         return SetFontSize(_CoordinateSystemUtils::ConvertToFloat(size), startTextIndex, textLength);
1558 }
1559
1560 result
1561 TextObject::SetFontSize(float size, int startTextIndex, int textLength)
1562 {
1563         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1564
1565         SysTryReturn(NID_GRP
1566                 , startTextIndex >= 0
1567                 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1568
1569         __pCompositeText->SetRange(startTextIndex, textLength);
1570         __pCompositeText->SetFontSize(size);
1571         UpdateChangedInfo(0, 0);
1572
1573         return E_SUCCESS;
1574 }
1575
1576 int
1577 TextObject::GetFontSize(int textIndex) const
1578 {
1579         return _CoordinateSystemUtils::ConvertToInteger(GetFontSizeF(textIndex));
1580 }
1581
1582 float
1583 TextObject::GetFontSizeF(int textIndex) const
1584 {
1585         IF_NOT_CONSTRUCTED(return -1);
1586
1587         SysTryReturn(NID_GRP
1588                 , textIndex >= 0
1589                 , -1, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1590
1591         return __pCompositeText->GetFontSizeF(textIndex);
1592 }
1593
1594 result
1595 TextObject::SetDefaultFontStyle(int style)
1596 {
1597         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1598
1599         _FontImpl::GetInstance(*__pDefaultFont)->SetStyle(style);
1600
1601         return E_SUCCESS;
1602 }
1603
1604 int
1605 TextObject::GetDefaultFontStyle(void) const
1606 {
1607         IF_NOT_CONSTRUCTED(return FONT_STYLE_MIN);
1608
1609         return _FontImpl::GetInstance(*__pDefaultFont)->GetStyle();
1610 }
1611
1612 result
1613 TextObject::SetFontStyle(int style, int startTextIndex, int textLength)
1614 {
1615         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1616
1617         SysTryReturn(NID_GRP
1618                 , startTextIndex >= 0
1619                 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1620
1621         __pCompositeText->SetRange(startTextIndex, textLength);
1622         __pCompositeText->SetFontStyle(style);
1623         UpdateChangedInfo(0, 0);
1624
1625         return E_SUCCESS;
1626 }
1627
1628 int
1629 TextObject::GetFontStyle(int textIndex) const
1630 {
1631         IF_NOT_CONSTRUCTED(return -1);
1632
1633         SysTryReturn(NID_GRP
1634                 , textIndex >= 0
1635                 , FONT_STYLE_MIN, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1636
1637         return __pCompositeText->GetFontStyle(textIndex);
1638 }
1639
1640 result
1641 TextObject::SetDefaultForegroundColor(const Color& color)
1642 {
1643         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1644
1645         __defaultForegroundColor = color;
1646
1647         return E_SUCCESS;
1648 }
1649
1650 Color
1651 TextObject::GetDefaultForegroundColor(void) const
1652 {
1653         IF_NOT_CONSTRUCTED(return Color::GetColor(COLOR_ID_BLACK));
1654
1655         return __defaultForegroundColor;
1656 }
1657
1658 result
1659 TextObject::SetForegroundColor(const Color& color, int startTextIndex, int textLength)
1660 {
1661         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1662
1663         SysTryReturn(NID_GRP, startTextIndex >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1664
1665         __defaultForegroundColor = color;
1666
1667         __pCompositeText->SetRange(startTextIndex, textLength);
1668         __pCompositeText->SetForegroundColor(color);
1669
1670         return E_SUCCESS;
1671 }
1672
1673 Color
1674 TextObject::GetForegroundColor(int textIndex) const
1675 {
1676         IF_NOT_CONSTRUCTED(return Color::GetColor(COLOR_ID_BLACK));
1677
1678         SysTryReturn(NID_GRP, textIndex >= 0, __defaultForegroundColor, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1679
1680         return __pCompositeText->GetForegroundColor(textIndex);
1681 }
1682
1683 result
1684 TextObject::SetBackgroundColor(const Color& color, int startTextIndex, int textLength)
1685 {
1686         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1687
1688         SysTryReturn(NID_GRP, startTextIndex >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1689
1690         __defaultBackgroundColor = color;
1691
1692         __pCompositeText->SetRange(startTextIndex, textLength);
1693         __pCompositeText->SetBackgroundColor(color);
1694
1695         return E_SUCCESS;
1696 }
1697
1698 Color
1699 TextObject::GetBackgroundColor(int textIndex) const
1700 {
1701         IF_NOT_CONSTRUCTED(return Color::GetColor(COLOR_ID_BLACK));
1702
1703         SysTryReturn(NID_GRP, textIndex >= 0, __defaultBackgroundColor, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1704
1705         return __pCompositeText->GetBackgroundColor(textIndex);
1706 }
1707
1708 result
1709 TextObject::SetOutlineColor(const Color& color, int startTextIndex, int textLength)
1710 {
1711         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1712
1713         SysTryReturn(NID_GRP, startTextIndex >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1714
1715         __defaultOutlineColor = color;
1716
1717         __pCompositeText->SetRange(startTextIndex, textLength);
1718         __pCompositeText->SetOutlineColor(color);
1719
1720         return E_SUCCESS;
1721 }
1722
1723 Color
1724 TextObject::GetOutlineColor(int textIndex) const
1725 {
1726         IF_NOT_CONSTRUCTED(return Color::GetColor(COLOR_ID_BLACK));
1727
1728         SysTryReturn(NID_GRP, textIndex >= 0, __defaultOutlineColor, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1729
1730         return __pCompositeText->GetOutlineColor(textIndex);
1731 }
1732
1733 result
1734 TextObject::SetBlockColor(const Color& color)
1735 {
1736         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1737
1738         __pCompositeText->SetBlockColor(color);
1739
1740         return E_SUCCESS;
1741 }
1742
1743 Color
1744 TextObject::GetBlockColor(void) const
1745 {
1746         IF_NOT_CONSTRUCTED(return Color::GetColor(COLOR_ID_BLACK));
1747
1748         return __pCompositeText->GetBlockColor();
1749 }
1750
1751 result
1752 TextObject::SetDisplayBitmap(const Bitmap* pBitmap, int startTextIndex, int textLength)
1753 {
1754         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1755
1756         SysTryReturn(NID_GRP, startTextIndex >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1757
1758         __pCompositeText->SetRange(startTextIndex, textLength);
1759         __pCompositeText->SetDisplayBitmap(pBitmap);
1760         UpdateChangedInfo(0, 0);
1761
1762         return E_SUCCESS;
1763 }
1764
1765 const Bitmap*
1766 TextObject::GetDisplayBitmap(int textIndex) const
1767 {
1768         IF_NOT_CONSTRUCTED(return null);
1769
1770         return __pCompositeText->GetDisplayBitmap(textIndex);
1771 }
1772
1773 result
1774 TextObject::SetWrap(TextObjectWrapType wrap)
1775 {
1776         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1777
1778         if (__wrap == wrap)
1779         {
1780                 return E_SUCCESS;
1781         }
1782
1783         result r = __pCompositeText->SetWrap(wrap);
1784         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
1785
1786         __wrap = wrap;
1787         UpdateChangedInfo(0, 0);
1788
1789         return E_SUCCESS;
1790 }
1791
1792 result
1793 TextObject::InsertElementAt(int textIndex, Bitmap& bitmap, TextElementSourceType sourceType)
1794 {
1795         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1796
1797         TextImage* pImageText = new (std::nothrow)TextImage(bitmap, sourceType, (TextObjectAlignment)(TEXT_OBJECT_ALIGNMENT_LEFT | TEXT_OBJECT_ALIGNMENT_TOP));
1798         SysTryReturn(NID_GRP, pImageText, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
1799
1800         int addedTextLength = pImageText->GetTextLength();
1801         __pCompositeText->InsertElementAt(*pImageText, textIndex);
1802         int startTextIndex = __pCompositeText->GetWorkStart();
1803         NotifyTextAdded(startTextIndex, addedTextLength);
1804
1805         return E_SUCCESS;
1806 }
1807
1808 result
1809 TextObject::AppendElement(Bitmap& bitmap, TextElementSourceType sourceType)
1810 {
1811         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1812
1813         result r = E_SUCCESS;
1814         TextImage* pImageText = new (std::nothrow)TextImage(bitmap, sourceType, (TextObjectAlignment)(TEXT_OBJECT_ALIGNMENT_LEFT | TEXT_OBJECT_ALIGNMENT_TOP));
1815         SysTryReturn(NID_GRP, pImageText, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
1816
1817         r = __pCompositeText->AppendElement(*pImageText);
1818         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
1819
1820         int startTextIndex = __pCompositeText->GetWorkStart();
1821         int elementTextLength = pImageText->GetTextLength();
1822
1823         NotifyTextAdded(startTextIndex, elementTextLength);
1824
1825         return E_SUCCESS;
1826 }
1827
1828 result
1829 TextObject::SetAlternateLookEnabled(bool enable)
1830 {
1831         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1832
1833         TextElement* pTextElement = null;
1834
1835         __isAlternateLookEnabled = enable;
1836         int elementCount = __pCompositeText->GetElementCount();
1837
1838         for (int i = 0; i < elementCount; i++)
1839         {
1840                 pTextElement = __pCompositeText->GetElementAtElementIndex(i);
1841                 if (pTextElement != null)
1842                 {
1843                         pTextElement->SetAlternateLookEnabled(enable);
1844                 }
1845         }
1846
1847         return E_SUCCESS;
1848 }
1849
1850 result
1851 TextObject::SetAlternativeForegroundColor(const Color& color)
1852 {
1853         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1854
1855         TextElement* pTextElement = null;
1856         int elementCount = __pCompositeText->GetElementCount();
1857
1858         for (int i = 0; i < elementCount; i++)
1859         {
1860                 pTextElement = __pCompositeText->GetElementAtElementIndex(i);
1861                 SysTryReturn(NID_GRP, pTextElement, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text element.");
1862
1863                 pTextElement->SetAlternativeForegroundColor(color);
1864         }
1865
1866         return E_SUCCESS;
1867 }
1868
1869 result
1870 TextObject::ChangeTextOffset(wchar_t* pText, int textIndex, int gap)
1871 {
1872         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1873
1874         result r = E_SUCCESS;
1875         int elementStartTextIndex = 0;
1876         int elementIndex = 0;
1877         int elementTextLength = 0;
1878         int textIndexFromElementOffset = 0;
1879
1880         TextElement* pTextElement = __pCompositeText->GetElementAtTextIndex(textIndex, elementStartTextIndex,
1881                         elementIndex, elementTextLength, textIndexFromElementOffset);
1882
1883         SysTryReturn(NID_GRP, pTextElement, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text element.");
1884
1885         r = __pCompositeText->ChangeTextOffset(pText, elementIndex, gap);
1886         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
1887
1888         return E_SUCCESS;
1889 }
1890
1891 result
1892 TextObject::NotifyTextChanged(wchar_t* pText, int textOffset, int textLength, int gap)
1893 {
1894         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
1895
1896         result r = E_SUCCESS;
1897         int startTextIndex = __pCompositeText->GetWorkStart();
1898         r = __pCompositeText->NotifyTextChanged(pText, textOffset, textLength, gap, __pDefaultFont,
1899                                                                    __defaultForegroundColor, __defaultBackgroundColor, __defaultOutlineColor);
1900
1901         SysTryCatch(NID_GRP, r == E_SUCCESS, , E_SYSTEM, "[E_SYSTEM] Fail to update change information.");
1902
1903         if (__wrap != TEXT_OBJECT_WRAP_TYPE_NONE)
1904         {
1905                 if (gap > 0)
1906                 {
1907                         NotifyTextAdded(startTextIndex, gap);
1908                         if (gap == 1)
1909                         {
1910                                 InputText(startTextIndex);
1911                         }
1912                 }
1913                 else if (gap < 0)
1914                 {
1915                         NotifyTextDeleted(startTextIndex, -gap);
1916
1917                         if (gap == -1)
1918                         {
1919                                 RemoveText(startTextIndex);
1920                         }
1921                 }
1922                 else
1923                 {
1924                         UpdateChangedInfo(startTextIndex, 0);
1925
1926                         ChangeText(startTextIndex);
1927                 }
1928         }
1929         else
1930         {
1931                 UpdateChangedInfo(startTextIndex, 0);
1932         }
1933
1934         return E_SUCCESS;
1935
1936 CATCH:
1937         if (__pCompositeText->GetElementCount() == 0)
1938         {
1939                 RemoveAll();
1940                 TextSimple* pSimpleText = new (std::nothrow)TextSimple(pText, textLength, TEXT_ELEMENT_SOURCE_TYPE_EXTERNAL);
1941                 AppendElement(*pSimpleText);
1942
1943                 SetCursorIndex(0);
1944                 UpdateChangedInfo(0, 0);
1945         }
1946
1947         return E_SUCCESS;
1948 }
1949
1950 int
1951 TextObject::GetTextIndexFromPosition(int x, int y, bool cursorMode) const
1952 {
1953         return GetTextIndexFromPosition(_CoordinateSystemUtils::ConvertToFloat(x), _CoordinateSystemUtils::ConvertToFloat(y), cursorMode);
1954 }
1955
1956 int
1957 TextObject::GetTextIndexFromPosition(float x, float y, bool cursorMode) const
1958 {
1959         IF_NOT_CONSTRUCTED(return -1);
1960
1961         int lineCount = __pTextColumn->GetTotalLineCount();
1962         if (lineCount <= 0)
1963         {
1964                 return -1;
1965         }
1966
1967         if (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE)
1968         {
1969                 return GetTextIndexFromPositionInNoneWrap(x, y, !cursorMode);
1970         }
1971         else
1972         {
1973                 return GetTextIndexFromPositionInWrap(x, y, !cursorMode);
1974         }
1975 }
1976
1977 int
1978 TextObject::GetTextIndexFromPosition(float x, float y, int& row, int& column, bool cursorMode) const
1979 {
1980         IF_NOT_CONSTRUCTED(return -1);
1981
1982         int lineCount = __pTextColumn->GetTotalLineCount();
1983         if (lineCount <= 0)
1984         {
1985                 return -1;
1986         }
1987
1988         if (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE)
1989         {
1990                 return GetTextIndexFromPositionInNoneWrap(x, y, row, column, !cursorMode);
1991         }
1992         else
1993         {
1994                 return GetTextIndexFromPositionInWrap(x, y, row, column, !cursorMode);
1995         }
1996 }
1997
1998 int
1999 TextObject::GetTextIndexFromPositionAtLine(int lineIndex, int x, bool cursorMode) const
2000 {
2001         return GetTextIndexFromPositionAtLine(lineIndex, _CoordinateSystemUtils::ConvertToFloat(x), cursorMode);
2002 }
2003
2004 int
2005 TextObject::GetTextIndexFromPositionAtLine(int lineIndex, float x, bool cursorMode) const
2006 {
2007         IF_NOT_CONSTRUCTED(return -1);
2008
2009         SysTryReturn(NID_GRP, lineIndex >= 0, -1, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
2010
2011         TextLine* pTextLine = __pTextColumn->GetTextLine(lineIndex);
2012         SysTryReturn(NID_GRP, pTextLine, -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
2013
2014         int lineOffset = pTextLine->GetTextOffset();
2015         int lineLength = pTextLine->GetTextLength();
2016         int length = 0;
2017         TextElementType objectType;
2018         FloatRectangle lineBounds = pTextLine->GetBoundsF();
2019         FloatDimension lineTextSize;
2020         pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
2021
2022         switch (__align & TEXT_ALIGNMASK_HORIZ)
2023         {
2024         case TEXT_OBJECT_ALIGNMENT_LEFT:
2025                 break;
2026
2027         case TEXT_OBJECT_ALIGNMENT_CENTER:
2028                 x -= (lineBounds.width - lineTextSize.width) / 2.0f;
2029                 break;
2030
2031         case TEXT_OBJECT_ALIGNMENT_RIGHT:
2032                 x -= (lineBounds.width - lineTextSize.width);
2033                 break;
2034         }
2035
2036         x = (x < 0.0f) ? 0.0f : x;
2037         __pCompositeText->SetWrap(TEXT_OBJECT_WRAP_TYPE_NONE);
2038
2039         int endType = 0;
2040
2041         if (cursorMode)
2042         {
2043                 __pCompositeText->ForwardAnalyzeWithFocusedObjectType(lineOffset, lineLength, x, length, objectType);
2044         }
2045         else
2046         {
2047                 endType = __pCompositeText->ForwardAnalyzeInNoneCursorMode(lineOffset, lineLength, x, length);
2048         }
2049
2050         __pCompositeText->SetWrap(__wrap);
2051
2052         if (!cursorMode)
2053         {
2054                 if (endType == -1)
2055                 {
2056                         return -1;
2057                 }
2058         }
2059
2060         int index = pTextLine->GetTextOffset() + length;
2061         if (pTextLine->GetEndType() == TEXT_RETBY_LINEFEED && lineLength == length && pTextLine->GetTextOffset() < index)
2062         {
2063                 index--;
2064         }
2065
2066         if (index != GetTextLength() && index == lineOffset + lineLength)
2067         {
2068                 TextElement* pTextElement = GetElementAtTextIndex(index-1);
2069                 if (pTextElement != null)
2070                 {
2071                         const TextSimple* pSimpleText = dynamic_cast <const TextSimple*>(pTextElement);
2072                         if (pSimpleText != null)
2073                         {
2074                                 const wchar_t* pText = pSimpleText->GetText();
2075                                 SysTryReturn(NID_GRP, pText, -1, E_SYSTEM, "[E_SYSTEM] Fail to get text.");
2076
2077                                 int i = index - 1 - pSimpleText->GetTextOffset();
2078                                 SysTryReturn(NID_GRP, i >= 0 && i < pSimpleText->GetTextLength(), -1, E_OUT_OF_RANGE
2079                                                 , "[E_OUT_OF_RANGE] text index(%d) must greater than 0 and must be less than total string length(%d)",i, pSimpleText->GetTextLength());
2080
2081                                 if (pText[i] == L' ' || pText[i] == TEXT_JAPANESE_SPACE)
2082                                 {
2083                                         index--;
2084                                 }
2085                         }
2086                 }
2087         }
2088
2089         SetLastResult(E_SUCCESS);
2090
2091         return index;
2092 }
2093
2094 result
2095 TextObject::SetFirstDisplayLineIndexFromTextIndex(int textIndex)
2096 {
2097         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
2098
2099         if (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE)
2100         {
2101                 return SetFirstDisplayLineIndexFromTextIndexInNoneWrap(textIndex);
2102         }
2103         else
2104         {
2105                 return SetFirstDisplayLineIndexFromTextIndexInWrap(textIndex);
2106         }
2107 }
2108
2109 result
2110 TextObject::SetCutLinkViewMode(bool enable)
2111 {
2112         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
2113
2114         if (__linkViewModeEnabled == enable)
2115         {
2116                 return E_SUCCESS;
2117         }
2118
2119         __linkViewModeEnabled = enable;
2120         return E_SUCCESS;
2121 }
2122
2123 int
2124 TextObject::GetCutLinkIndexFromPositionData(int x, int y) const
2125 {
2126         return GetCutLinkIndexFromPositionData(_CoordinateSystemUtils::ConvertToFloat(x), _CoordinateSystemUtils::ConvertToFloat(y));
2127 }
2128
2129 int
2130 TextObject::GetCutLinkIndexFromPositionData(float x, float y) const
2131 {
2132         IF_NOT_CONSTRUCTED(return -1);
2133
2134         result r = E_SUCCESS;
2135
2136         TextBidiHint bidiHint = _GetTextBidiHint();
2137         _SetTextBidiHint(__bidiHint);
2138
2139         int lineCount = __pTextColumn->GetTotalLineCount();
2140         if (lineCount <= 0)
2141         {
2142                 return -1;
2143         }
2144
2145         int textIndex = 0;
2146
2147         if (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE)
2148         {
2149                 textIndex = GetTextIndexFromPositionInNoneWrap(x, y, false);
2150         }
2151         else
2152         {
2153                 textIndex = GetTextIndexFromPositionInWrap(x, y, false);
2154         }
2155
2156         if (textIndex < 0)
2157         {
2158                 return -1;
2159         }
2160
2161         float width = 0.0f;
2162         float height = 0.0f;
2163         FloatPoint absPoint;
2164         FloatPoint relPoint;
2165
2166         if (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE)
2167         {
2168                 r = GetTextPositionInfoInNoneWrapAt(textIndex, width, height, absPoint.x, absPoint.y, relPoint.x, relPoint.y);
2169         }
2170         else
2171         {
2172                 r = GetTextPositionInfoInWrapAt(textIndex, width, height, absPoint.x, absPoint.y, relPoint.x, relPoint.y);
2173         }
2174         SysTryReturn(NID_GRP, r == E_SUCCESS, -1, r, "[%s] Propagating.", GetErrorMessage(r));
2175         SysTryReturn(NID_GRP, y + __rect.y >= relPoint.y, -1, E_SYSTEM, "[E_SYSTEM] Fail to get text position information");
2176
2177         int elementIndex =  __pCompositeText->GetCutLinkElementIndexAt(textIndex);
2178
2179         _SetTextBidiHint(bidiHint);
2180
2181         return elementIndex;
2182 }
2183
2184 TextElement*
2185 TextObject::GetCutLinkElementAtCutLinkElementIndex(int linkIndex) const
2186 {
2187         IF_NOT_CONSTRUCTED(return null);
2188
2189         return __pCompositeText->GetCutLinkElementAtCutLinkElementIndex(linkIndex);
2190 }
2191
2192 result
2193 TextObject::SetCutLinkColor(LinkType linkType, const Color& color, const Color& colorInSelect)
2194 {
2195         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
2196
2197         SysTryReturn(NID_GRP, LINK_TYPE_NONE < linkType && linkType < LINK_TYPE_MAX, E_INVALID_ARG, E_INVALID_ARG
2198                         , "[E_INVALID_ARG] The argument is invalid.");
2199
2200         switch (linkType)
2201         {
2202         case LINK_TYPE_URL:
2203                 __isUrlLinkColorDefined = true;
2204                 __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_URL_NORMAL] = color;
2205                 __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_URL_SELECT] = colorInSelect;
2206                 break;
2207
2208         case LINK_TYPE_EMAIL:
2209                 __isEmailLinkColorDefined = true;
2210                 __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_EMAIL_NORMAL] = color;
2211                 __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_EMAIL_SELECT] = colorInSelect;
2212                 break;
2213
2214         case LINK_TYPE_TEL_NUM:
2215                 __isPhoneNumberLinkColorDefined = true;
2216                 __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_PHONE_NUMBER_NORMAL] = color;
2217                 __linkColor[TEXT_OBJECT_LINK_COLOR_TYPE_PHONE_NUMBER_SELECT] = colorInSelect;
2218                 break;
2219
2220         default:
2221                 break;
2222         }
2223
2224         int totalCutlinkTextCount = __pCompositeText->GetCutLinkElementCount();
2225         for (int i = 0; i < totalCutlinkTextCount; i++)
2226         {
2227                 TextCutLink* pCutlinkText = dynamic_cast < TextCutLink* >(__pCompositeText->GetCutLinkElementAtCutLinkElementIndex(i));
2228                 SysTryReturn(NID_GRP, pCutlinkText, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to convert to cutlink element.");
2229
2230                 if (pCutlinkText->GetCutLinkType() == linkType)
2231                 {
2232                         pCutlinkText->SetUserColor(color, colorInSelect);
2233                 }
2234         }
2235
2236         return E_SUCCESS;
2237 }
2238
2239 result
2240 TextObject::ResetCutLinkColor(LinkType linkType)
2241 {
2242         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
2243
2244         SysTryReturn(NID_GRP, LINK_TYPE_NONE < linkType && linkType < LINK_TYPE_MAX, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
2245
2246         switch (linkType)
2247         {
2248         case LINK_TYPE_URL:
2249                 __isUrlLinkColorDefined = false;
2250                 break;
2251
2252         case LINK_TYPE_EMAIL:
2253                 __isEmailLinkColorDefined = false;
2254                 break;
2255
2256         case LINK_TYPE_TEL_NUM:
2257                 __isPhoneNumberLinkColorDefined = false;
2258                 break;
2259
2260         default:
2261                 break;
2262         }
2263
2264         int totalCutlinkTextCount = __pCompositeText->GetCutLinkElementCount();
2265         for (int i = 0; i < totalCutlinkTextCount; i++)
2266         {
2267                 TextCutLink* pCutlinkText = dynamic_cast < TextCutLink* >(__pCompositeText->GetCutLinkElementAtCutLinkElementIndex(i));
2268                 SysTryReturn(NID_GRP, pCutlinkText, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to convert to cutlink element.");
2269
2270                 if (pCutlinkText->GetCutLinkType() == linkType)
2271                 {
2272                         pCutlinkText->ResetUserColor();
2273                 }
2274         }
2275
2276         return E_SUCCESS;
2277 }
2278
2279 result
2280 TextObject::GetCutLinkBounds(int cutLinkIndex, Point& startPoint, Point& endPoint) const
2281 {
2282         FloatPoint startPointF = _CoordinateSystemUtils::ConvertToFloat(startPoint);
2283         FloatPoint endPointF =  _CoordinateSystemUtils::ConvertToFloat(endPoint);
2284
2285         result r = GetCutLinkBounds(cutLinkIndex, startPointF, endPointF);
2286         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
2287
2288         startPoint = _CoordinateSystemUtils::ConvertToInteger(startPointF);
2289         endPoint = _CoordinateSystemUtils::ConvertToInteger(endPointF);
2290
2291         return E_SUCCESS;
2292 }
2293
2294 result
2295 TextObject::GetCutLinkBounds(int cutLinkIndex, FloatPoint& startPoint, FloatPoint& endPoint) const
2296 {
2297         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
2298
2299         result r = E_SUCCESS;
2300         int textIndex = 0;
2301         int textLength = 0;
2302         float width = 0.0f;
2303         float heigth = 0.0f;
2304         FloatPoint tempPoint;
2305
2306         r = __pCompositeText->GetCutLinkObjectInfo(cutLinkIndex, textIndex, textLength);
2307         SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
2308
2309         if (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE)
2310         {
2311                 r = GetTextPositionInfoInNoneWrapAt(textIndex, width, heigth, tempPoint.x, tempPoint.y, startPoint.x, startPoint.y);
2312                 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
2313
2314                 r = GetTextPositionInfoInNoneWrapAt(textIndex + textLength - 1, width, heigth, tempPoint.x, tempPoint.y, endPoint.x, endPoint.y);
2315                 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
2316         }
2317         else
2318         {
2319                 r = GetTextPositionInfoInWrapAt(textIndex, width, heigth, tempPoint.x, tempPoint.y, startPoint.x, startPoint.y);
2320                 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
2321
2322                 r = GetTextPositionInfoInWrapAt(textIndex + textLength - 1, width, heigth, tempPoint.x, tempPoint.y, endPoint.x, endPoint.y);
2323                 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
2324         }
2325
2326         endPoint.x = endPoint.x + width;
2327         endPoint.y = endPoint.y + heigth;
2328
2329         return E_SUCCESS;
2330
2331 CATCH:
2332         startPoint.x = -1;
2333         startPoint.y = -1;
2334         endPoint.x = -1;
2335         endPoint.y = -1;
2336
2337         return r;
2338 }
2339
2340 result
2341 TextObject::GetTextPositionInfoAt(int textIndex, int& width, int& height, int& absX, int& absY, int& logicalX, int& logicalY) const
2342 {
2343         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
2344
2345         float widthF = _CoordinateSystemUtils::ConvertToFloat(width);
2346         float heightF =  _CoordinateSystemUtils::ConvertToFloat(height);
2347         float absXF = _CoordinateSystemUtils::ConvertToFloat(absX);
2348         float absYF = _CoordinateSystemUtils::ConvertToFloat(absY);
2349         float logicalXF = _CoordinateSystemUtils::ConvertToFloat(logicalX);
2350         float logicalYF = _CoordinateSystemUtils::ConvertToFloat(logicalY);
2351
2352         result r = GetTextPositionInfoAt(textIndex, widthF, heightF, absXF, absYF, logicalXF, logicalYF);
2353         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
2354
2355         width = _CoordinateSystemUtils::ConvertToInteger(widthF);
2356         height = _CoordinateSystemUtils::ConvertToInteger(heightF);
2357         absX = _CoordinateSystemUtils::ConvertToInteger(absXF);
2358         absY = _CoordinateSystemUtils::ConvertToInteger(absYF);
2359         logicalX = _CoordinateSystemUtils::ConvertToInteger(logicalXF);
2360         logicalY = _CoordinateSystemUtils::ConvertToInteger(logicalYF);
2361
2362         return E_SUCCESS;
2363 }
2364
2365 result
2366 TextObject::GetTextPositionInfoAt(int textIndex, float& width, float& height, float& absX, float& absY, float& logicalX, float& logicalY) const
2367 {
2368         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
2369
2370         result r = E_SUCCESS;
2371         TextBidiHint bidiHint = _GetTextBidiHint();
2372         _SetTextBidiHint(__bidiHint);
2373
2374         int lineCount = __pTextColumn->GetTotalLineCount();
2375
2376         if (lineCount < 1)
2377         {
2378                 _FontImpl* pFont = _FontImpl::GetInstance(*__pDefaultFont);
2379                 SysTryReturn(NID_GRP, pFont, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get native font instance.");
2380
2381                 float maxHeight = TextUtility::GetFontMaxHeightF(pFont);
2382                 float posX = 0.0f;
2383                 float posY = 0.0f;
2384                 absX = 0.0f;
2385                 absY = 0.0f;
2386
2387                 if (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE)
2388                 {
2389                         switch (__align & TEXT_ALIGNMASK_VERT)
2390                         {
2391                         case TEXT_OBJECT_ALIGNMENT_TOP:
2392                                 break;
2393
2394                         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
2395                                 posY += (__rect.height - maxHeight) / 2.0f;
2396                                 break;
2397
2398                         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
2399                                 posY += (__rect.height - maxHeight);
2400                                 break;
2401                         }
2402                         logicalY = __rect.y + posY;
2403
2404                         switch (__align & TEXT_ALIGNMASK_HORIZ)
2405                         {
2406                         case TEXT_OBJECT_ALIGNMENT_LEFT:
2407                                 break;
2408
2409                         case TEXT_OBJECT_ALIGNMENT_CENTER:
2410                                 posX += __rect.width / 2.0f;
2411                                 break;
2412
2413                         case TEXT_OBJECT_ALIGNMENT_RIGHT:
2414                                 posX += __rect.width;
2415                                 break;
2416                         }
2417                         logicalX = __rect.x + posX;
2418                 }
2419                 else
2420                 {
2421                         float lineHeight = maxHeight + __pCompositeText->GetLineSpaceF();
2422                         TextObjectAlignment alignment = __pCompositeText->GetElementVerticalAlignment();
2423                         switch (alignment & TEXT_ALIGNMASK_VERT)
2424                         {
2425                         case TEXT_OBJECT_ALIGNMENT_TOP:
2426                                 // fall through
2427                         default:
2428                                 break;
2429
2430                         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
2431                                 posY += (lineHeight - maxHeight) / 2.0f;
2432                                 break;
2433
2434                         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
2435                                 posY += lineHeight - maxHeight;
2436                                 break;
2437                         }
2438
2439                         switch (__align & TEXT_ALIGNMASK_HORIZ)
2440                         {
2441                         case TEXT_OBJECT_ALIGNMENT_LEFT:
2442                                 break;
2443
2444                         case TEXT_OBJECT_ALIGNMENT_CENTER:
2445                                 posX += __rect.width / 2.0f;
2446                                 break;
2447
2448                         case TEXT_OBJECT_ALIGNMENT_RIGHT:
2449                                 posX += __rect.width;
2450                                 break;
2451                         }
2452
2453                         logicalX = posX + __rect.x;
2454                         logicalY = posY + __rect.y;
2455                 }
2456
2457                 width = 0.0f;
2458                 height = maxHeight;
2459                 absX = posX;
2460                 absY = posY;
2461         }
2462         else
2463         {
2464                 r = (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE) ? GetTextPositionInfoInNoneWrapAt(textIndex, width, height, absX, absY, logicalX, logicalY)
2465                                 : GetTextPositionInfoInWrapAt(textIndex, width, height, absX, absY, logicalX, logicalY);
2466                 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
2467         }
2468
2469         _SetTextBidiHint(bidiHint);
2470
2471         return E_SUCCESS;
2472 }
2473
2474 result
2475 TextObject::GetTextPositionInfoAt(int row, int column, float& width, float& height, float& absX, float& absY, float& logicalX, float& logicalY) const
2476 {
2477         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
2478
2479         result r = E_SUCCESS;
2480         TextBidiHint bidiHint = _GetTextBidiHint();
2481         _SetTextBidiHint(__bidiHint);
2482
2483         int lineCount = __pTextColumn->GetTotalLineCount();
2484
2485         if (lineCount < 1)
2486         {
2487                 _FontImpl* pFont = _FontImpl::GetInstance(*__pDefaultFont);
2488                 SysTryReturn(NID_GRP, pFont, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get native font instance.");
2489
2490                 float maxHeight = TextUtility::GetFontMaxHeightF(pFont);
2491                 float posX = 0.0f;
2492                 float posY = 0.0f;
2493                 absX = 0.0f;
2494                 absY = 0.0f;
2495
2496                 if (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE)
2497                 {
2498                         switch (__align & TEXT_ALIGNMASK_VERT)
2499                         {
2500                         case TEXT_OBJECT_ALIGNMENT_TOP:
2501                                 break;
2502
2503                         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
2504                                 posY += (__rect.height - maxHeight) / 2.0f;
2505                                 break;
2506
2507                         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
2508                                 posY += (__rect.height - maxHeight);
2509                                 break;
2510                         }
2511                         logicalY = __rect.y + posY;
2512
2513                         switch (__align & TEXT_ALIGNMASK_HORIZ)
2514                         {
2515                         case TEXT_OBJECT_ALIGNMENT_LEFT:
2516                                 break;
2517
2518                         case TEXT_OBJECT_ALIGNMENT_CENTER:
2519                                 posX += __rect.width / 2.0f;
2520                                 break;
2521
2522                         case TEXT_OBJECT_ALIGNMENT_RIGHT:
2523                                 posX += __rect.width;
2524                                 break;
2525                         }
2526                         logicalX = __rect.x + posX;
2527                 }
2528                 else
2529                 {
2530                         float lineHeight = maxHeight + __pCompositeText->GetLineSpaceF();
2531                         TextObjectAlignment alignment = __pCompositeText->GetElementVerticalAlignment();
2532                         switch (alignment & TEXT_ALIGNMASK_VERT)
2533                         {
2534                         case TEXT_OBJECT_ALIGNMENT_TOP:
2535                                 // fall through
2536                         default:
2537                                 break;
2538
2539                         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
2540                                 posY += (lineHeight - maxHeight) / 2.0f;
2541                                 break;
2542
2543                         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
2544                                 posY += lineHeight - maxHeight;
2545                                 break;
2546                         }
2547
2548                         switch (__align & TEXT_ALIGNMASK_HORIZ)
2549                         {
2550                         case TEXT_OBJECT_ALIGNMENT_LEFT:
2551                                 break;
2552
2553                         case TEXT_OBJECT_ALIGNMENT_CENTER:
2554                                 posX += __rect.width / 2.0f;
2555                                 break;
2556
2557                         case TEXT_OBJECT_ALIGNMENT_RIGHT:
2558                                 posX += __rect.width;
2559                                 break;
2560                         }
2561
2562                         logicalX = posX + __rect.x;
2563                         logicalY = posY + __rect.y;
2564                 }
2565
2566                 width = 0.0f;
2567                 height = maxHeight;
2568                 absX = posX;
2569                 absY = posY;
2570         }
2571         else
2572         {
2573                 r = (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE) ? GetTextPositionInfoInNoneWrapAt(row, column, width, height, absX, absY, logicalX, logicalY)
2574                                 : GetTextPositionInfoInWrapAt(row, column, width, height, absX, absY, logicalX, logicalY);
2575                 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
2576         }
2577
2578         _SetTextBidiHint(bidiHint);
2579
2580         return E_SUCCESS;
2581 }
2582
2583 result
2584 TextObject::GetBlockTextPositionInfoAt(int textIndex, int& width, int& height, int& absX, int& absY, int& logicalX, int& logicalY) const
2585 {
2586         float widthF = _CoordinateSystemUtils::ConvertToFloat(width);
2587         float heightF =  _CoordinateSystemUtils::ConvertToFloat(height);
2588         float absXF = _CoordinateSystemUtils::ConvertToFloat(absX);
2589         float absYF = _CoordinateSystemUtils::ConvertToFloat(absY);
2590         float logicalXF = _CoordinateSystemUtils::ConvertToFloat(logicalX);
2591         float logicalYF = _CoordinateSystemUtils::ConvertToFloat(logicalY);
2592
2593         result r = GetBlockTextPositionInfoAt(textIndex, widthF, heightF, absXF, absYF, logicalXF, logicalYF);
2594         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
2595
2596         width = _CoordinateSystemUtils::ConvertToInteger(widthF);
2597         height = _CoordinateSystemUtils::ConvertToInteger(heightF);
2598         absX = _CoordinateSystemUtils::ConvertToInteger(absXF);
2599         absY = _CoordinateSystemUtils::ConvertToInteger(absYF);
2600         logicalX = _CoordinateSystemUtils::ConvertToInteger(logicalXF);
2601         logicalY = _CoordinateSystemUtils::ConvertToInteger(logicalYF);
2602
2603         return E_SUCCESS;
2604 }
2605
2606 result
2607 TextObject::GetBlockTextPositionInfoAt(int textIndex, float& width, float& height, float& absX, float& absY, float& logicalX, float& logicalY) const
2608 {
2609         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
2610
2611         result r = E_SUCCESS;
2612         TextBidiHint bidiHint = _GetTextBidiHint();
2613         _SetTextBidiHint(__bidiHint);
2614
2615         int lineCount = __pTextColumn->GetTotalLineCount();
2616
2617         if (lineCount < 1)
2618         {
2619                 _FontImpl* pFont =_FontImpl::GetInstance(*__pDefaultFont);
2620                 SysTryReturn(NID_GRP, pFont, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get native font instance.");
2621
2622                 float maxHeight = TextUtility::GetFontMaxHeightF(pFont);
2623                 float posX = 0.0f;
2624                 float posY = 0.0f;
2625                 absX = 0.0f;
2626                 absY = 0.0f;
2627
2628                 if (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE)
2629                 {
2630                         switch (__align & TEXT_ALIGNMASK_VERT)
2631                         {
2632                         case TEXT_OBJECT_ALIGNMENT_TOP:
2633                                 break;
2634
2635                         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
2636                                 posY += (__rect.height - maxHeight) / 2.0f;
2637                                 break;
2638
2639                         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
2640                                 posY += (__rect.height - maxHeight);
2641                                 break;
2642                         }
2643                         logicalY = __rect.y + posY;
2644
2645                         switch (__align & TEXT_ALIGNMASK_HORIZ)
2646                         {
2647                         case TEXT_OBJECT_ALIGNMENT_LEFT:
2648                                 break;
2649
2650                         case TEXT_OBJECT_ALIGNMENT_CENTER:
2651                                 posX += __rect.width / 2.0f;
2652                                 break;
2653
2654                         case TEXT_OBJECT_ALIGNMENT_RIGHT:
2655                                 posX += __rect.width;
2656                                 break;
2657                         }
2658                         logicalX = __rect.x + posX;
2659                 }
2660                 else
2661                 {
2662                         float lineHeight = maxHeight + __pCompositeText->GetLineSpace();
2663                         TextObjectAlignment alignment = __pCompositeText->GetElementVerticalAlignment();
2664                         switch (alignment & TEXT_ALIGNMASK_VERT)
2665                         {
2666                         case TEXT_OBJECT_ALIGNMENT_TOP:
2667                                 // fall through
2668                         default:
2669                                 break;
2670
2671                         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
2672                                 posY += (lineHeight - maxHeight) / 2.0f;
2673                                 break;
2674
2675                         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
2676                                 posY += lineHeight - maxHeight;
2677                                 break;
2678                         }
2679
2680                         logicalX = __rect.x;
2681                         logicalY = posY + __rect.y;
2682                 }
2683
2684                 width = 0.0f;
2685                 height = maxHeight;
2686                 absX = posX;
2687                 absY = posY;
2688         }
2689         else
2690         {
2691                 r = (__wrap == TEXT_OBJECT_WRAP_TYPE_NONE) ? GetTextPositionInfoInNoneWrapAt(textIndex, width, height, absX, absY, logicalX, logicalY)
2692                                 : GetBlockTextPositionInfoInWrapAt(textIndex, width, height, absX, absY, logicalX, logicalY);
2693                 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
2694         }
2695
2696         _SetTextBidiHint(bidiHint);
2697
2698         return E_SUCCESS;
2699 }
2700
2701 result
2702 TextObject::SetTextObjectEllipsisType(TextObjectEllipsisType type)
2703 {
2704         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
2705
2706         SysTryReturn(NID_GRP, TEXT_OBJECT_ELLIPSIS_TYPE_INVALID < type && type < TEXT_OBJECT_ELLIPSIS_TYPE_MAX
2707                 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
2708
2709         __textObjectEllipsisType = type;
2710         __pCompositeText->SetTextObjectEllipsisType(type);
2711
2712         return E_SUCCESS;
2713 }
2714
2715 result
2716 TextObject::NotifyTextAdded(int textIndex, int textLength)
2717 {
2718         result r = E_SUCCESS;
2719
2720         r = __pTextColumn->SetChangeAction(TextColumn::TEXT_CHANGE_INSERT, textIndex, textLength);
2721         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
2722
2723         __isChanged = true;
2724
2725         return E_SUCCESS;
2726 }
2727
2728 result
2729 TextObject::NotifyTextDeleted(int textIndex, int textLength)
2730 {
2731         result r = E_SUCCESS;
2732
2733         r = __pTextColumn->SetChangeAction(TextColumn::TEXT_CHANGE_REMOVE, textIndex, textLength);
2734         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
2735
2736         __isChanged = true;
2737
2738         return E_SUCCESS;
2739 }
2740
2741 result
2742 TextObject::DrawByLine(_CanvasImpl& canvasImpl, const Rectangle& displayRect)
2743 {
2744         return DrawByLine(canvasImpl, _CoordinateSystemUtils::ConvertToFloat(displayRect));
2745 }
2746
2747 result
2748 TextObject::DrawByLine(_CanvasImpl& canvasImpl, const FloatRectangle& displayRect)
2749 {
2750         FloatRectangle targetBounds = displayRect;
2751
2752         return __pTextColumn->Draw(canvasImpl, targetBounds, 0, __pTextColumn->GetTextLength(), __align, __action);
2753 }
2754
2755 int
2756 TextObject::GetTextIndexFromPositionInWrap(int x, int y, bool cursorMode) const
2757 {
2758         return GetTextIndexFromPositionInWrap(_CoordinateSystemUtils::ConvertToFloat(x), _CoordinateSystemUtils::ConvertToFloat(y), cursorMode);
2759 }
2760
2761 int
2762 TextObject::GetTextIndexFromPositionInWrap(float x, float y, bool cursorMode) const
2763 {
2764         TextLine* pTextLine = null;
2765         FloatRectangle lineBounds;
2766         int firstDisplayLineIndex = __pTextColumn->GetFirstDisplayLineIndex();
2767         float firstDisplayPositionY = __pTextColumn->GetFirstDisplayPositionYF();
2768         int lineCount = __pTextColumn->GetTotalLineCount();
2769         int lineIndex = 0;
2770         float totalHeight = __pTextColumn->GetTotalHeightF();
2771
2772         TextBidiHint bidiHint = _GetTextBidiHint();
2773         _SetTextBidiHint(__bidiHint);
2774
2775         switch (__align & TEXT_ALIGNMASK_VERT)
2776         {
2777         case TEXT_OBJECT_ALIGNMENT_TOP:
2778                 break;
2779
2780         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
2781                 y -= (__rect.height - totalHeight) / 2.0f;
2782                 break;
2783
2784         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
2785                 y -= (__rect.height - totalHeight);
2786                 break;
2787         }
2788
2789         for (lineIndex = firstDisplayLineIndex; lineIndex < lineCount; lineIndex++)
2790         {
2791                 pTextLine = __pTextColumn->GetTextLine(lineIndex);
2792                 SysTryReturn(NID_GRP, pTextLine, -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
2793
2794                 lineBounds = pTextLine->GetBoundsF();
2795
2796                 if (lineIndex == firstDisplayLineIndex)
2797                 {
2798                         if (y < lineBounds.y - firstDisplayPositionY)
2799                         {
2800                                 return -1;
2801                         }
2802                 }
2803
2804                 if ((lineBounds.y - firstDisplayPositionY <= y) && (y < lineBounds.y + lineBounds.height - firstDisplayPositionY))
2805                 {
2806                         break;
2807                 }
2808
2809                 if (lineIndex == lineCount - 1)
2810                 {
2811                         if (cursorMode)
2812                         {
2813                                 return pTextLine->GetTextLength() + pTextLine->GetTextOffset();
2814                         }
2815                         else
2816                         {
2817                                 return -1;
2818                         }
2819                 }
2820         }
2821
2822         SysTryReturn(NID_GRP, pTextLine, -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
2823
2824         int lineLength = pTextLine->GetTextLength();
2825         Dimension lineTextSize;
2826         pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
2827
2828         switch (__align & TEXT_ALIGNMASK_HORIZ)
2829         {
2830         case TEXT_OBJECT_ALIGNMENT_LEFT:
2831                 break;
2832
2833         case TEXT_OBJECT_ALIGNMENT_CENTER:
2834                 x -= (lineBounds.width - lineTextSize.width) / 2.0f;
2835                 break;
2836
2837         case TEXT_OBJECT_ALIGNMENT_RIGHT:
2838                 x -= (lineBounds.width - lineTextSize.width);
2839                 break;
2840         }
2841
2842         if (x < 0.0f)
2843         {
2844                 x = 0.0f;
2845         }
2846
2847         int index = pTextLine->GetTextIndexFromPosition(x);
2848
2849         _SetTextBidiHint(bidiHint);
2850
2851         SetLastResult(E_SUCCESS);
2852
2853         return index;
2854 }
2855
2856 int
2857 TextObject::GetTextIndexFromPositionInWrap(float x, float y, int& row, int& column, bool cursorMode) const
2858 {
2859         TextLine* pTextLine = null;
2860         FloatRectangle lineBounds;
2861         int firstDisplayLineIndex = __pTextColumn->GetFirstDisplayLineIndex();
2862         float firstDisplayPositionY = __pTextColumn->GetFirstDisplayPositionYF();
2863         int lineCount = __pTextColumn->GetTotalLineCount();
2864         int lineIndex = 0;
2865         float totalHeight = __pTextColumn->GetTotalHeightF();
2866
2867         TextBidiHint bidiHint = _GetTextBidiHint();
2868         _SetTextBidiHint(__bidiHint);
2869
2870         switch (__align & TEXT_ALIGNMASK_VERT)
2871         {
2872         case TEXT_OBJECT_ALIGNMENT_TOP:
2873                 break;
2874
2875         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
2876                 y -= (__rect.height - totalHeight) / 2.0f;
2877                 break;
2878
2879         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
2880                 y -= (__rect.height - totalHeight);
2881                 break;
2882         }
2883
2884         for (lineIndex = firstDisplayLineIndex; lineIndex < lineCount; lineIndex++)
2885         {
2886                 pTextLine = __pTextColumn->GetTextLine(lineIndex);
2887                 SysTryReturn(NID_GRP, pTextLine, -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
2888
2889                 lineBounds = pTextLine->GetBoundsF();
2890
2891                 if (lineIndex == firstDisplayLineIndex)
2892                 {
2893                         if (y < lineBounds.y - firstDisplayPositionY)
2894                         {
2895                                 return -1;
2896                         }
2897                 }
2898
2899                 if ((lineBounds.y - firstDisplayPositionY <= y) && (y < lineBounds.y + lineBounds.height - firstDisplayPositionY))
2900                 {
2901                         break;
2902                 }
2903
2904                 if (lineIndex == lineCount - 1)
2905                 {
2906                         if (cursorMode)
2907                         {
2908                                 return pTextLine->GetTextLength() + pTextLine->GetTextOffset();
2909                         }
2910                         else
2911                         {
2912                                 return -1;
2913                         }
2914                 }
2915         }
2916
2917         SysTryReturn(NID_GRP, pTextLine, -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
2918
2919         int lineLength = pTextLine->GetTextLength();
2920         Dimension lineTextSize;
2921         pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
2922
2923         switch (__align & TEXT_ALIGNMASK_HORIZ)
2924         {
2925         case TEXT_OBJECT_ALIGNMENT_LEFT:
2926                 break;
2927
2928         case TEXT_OBJECT_ALIGNMENT_CENTER:
2929                 x -= (lineBounds.width - lineTextSize.width) / 2.0f;
2930                 break;
2931
2932         case TEXT_OBJECT_ALIGNMENT_RIGHT:
2933                 x -= (lineBounds.width - lineTextSize.width);
2934                 break;
2935         }
2936
2937         if (x < 0.0f)
2938         {
2939                 x = 0.0f;
2940         }
2941
2942         int index = pTextLine->GetTextIndexFromPosition(x);
2943         row = pTextLine->GetIndex();
2944         column = index - pTextLine->GetTextOffset();
2945
2946         int endType = pTextLine->GetEndType();
2947         if (endType == TEXT_RETBY_LINEFEED && column == lineLength)
2948         {
2949                 index -= 1;
2950                 column -= 1;
2951         }
2952
2953         _SetTextBidiHint(bidiHint);
2954
2955         SetLastResult(E_SUCCESS);
2956
2957         return index;
2958 }
2959
2960 int
2961 TextObject::GetTextIndexFromPositionInNoneWrap(int x, int y, bool cursorMode) const
2962 {
2963         return GetTextIndexFromPositionInNoneWrap(_CoordinateSystemUtils::ConvertToFloat(x), _CoordinateSystemUtils::ConvertToFloat(y), cursorMode);
2964 }
2965
2966 int
2967 TextObject::GetTextIndexFromPositionInNoneWrap(float x, float y, bool cursorMode) const
2968 {
2969         FloatDimension lineTextSize;
2970         FloatRectangle lineBounds;
2971         int lineOffset = 0;
2972         int lineLength = 0;
2973         float firstDisplayPositionX = __pTextColumn->GetFirstDisplayPositionX();
2974         TextLine* pTextLine = null;
2975
2976         pTextLine = __pTextColumn->GetTextLine(0);
2977         SysTryReturn(NID_GRP, pTextLine, -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
2978
2979         TextBidiHint bidiHint = _GetTextBidiHint();
2980         _SetTextBidiHint(__bidiHint);
2981
2982         lineOffset = pTextLine->GetTextOffset();
2983         lineLength = pTextLine->GetTextLength();
2984         lineBounds = pTextLine->GetBoundsF();
2985         pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
2986
2987         x += firstDisplayPositionX;
2988
2989         switch (__align & TEXT_ALIGNMASK_HORIZ)
2990         {
2991         case TEXT_OBJECT_ALIGNMENT_LEFT:
2992                 break;
2993
2994         case TEXT_OBJECT_ALIGNMENT_CENTER:
2995                 x -= (lineBounds.width - lineTextSize.width) / 2.0f;
2996                 break;
2997
2998         case TEXT_OBJECT_ALIGNMENT_RIGHT:
2999                 x -= (lineBounds.width - lineTextSize.width);
3000                 break;
3001         }
3002
3003         switch (__align & TEXT_ALIGNMASK_VERT)
3004         {
3005         case TEXT_OBJECT_ALIGNMENT_TOP:
3006                 break;
3007
3008         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
3009                 y -= (__rect.height - lineTextSize.height) / 2.0f;
3010                 break;
3011
3012         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
3013                 y -= (__rect.height - lineTextSize.height);
3014                 break;
3015         }
3016
3017         if (x < 0.0f)
3018         {
3019                 x = 0.0f;
3020         }
3021
3022         int index = pTextLine->GetTextIndexFromPosition(x);
3023
3024         _SetTextBidiHint(bidiHint);
3025
3026         SetLastResult(E_SUCCESS);
3027         return index;
3028 }
3029
3030 int
3031 TextObject::GetTextIndexFromPositionInNoneWrap(float x, float y, int& row, int& column, bool cursorMode) const
3032 {
3033         FloatDimension lineTextSize;
3034         FloatRectangle lineBounds;
3035         int lineOffset = 0;
3036         int lineLength = 0;
3037         float firstDisplayPositionX = __pTextColumn->GetFirstDisplayPositionX();
3038         TextLine* pTextLine = null;
3039
3040         pTextLine = __pTextColumn->GetTextLine(0);
3041         SysTryReturn(NID_GRP, pTextLine, -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
3042
3043         TextBidiHint bidiHint = _GetTextBidiHint();
3044         _SetTextBidiHint(__bidiHint);
3045
3046         lineOffset = pTextLine->GetTextOffset();
3047         lineLength = pTextLine->GetTextLength();
3048         lineBounds = pTextLine->GetBoundsF();
3049         pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
3050
3051         x += firstDisplayPositionX;
3052
3053         switch (__align & TEXT_ALIGNMASK_HORIZ)
3054         {
3055         case TEXT_OBJECT_ALIGNMENT_LEFT:
3056                 break;
3057
3058         case TEXT_OBJECT_ALIGNMENT_CENTER:
3059                 x -= (lineBounds.width - lineTextSize.width) / 2.0f;
3060                 break;
3061
3062         case TEXT_OBJECT_ALIGNMENT_RIGHT:
3063                 x -= (lineBounds.width - lineTextSize.width);
3064                 break;
3065         }
3066
3067         switch (__align & TEXT_ALIGNMASK_VERT)
3068         {
3069         case TEXT_OBJECT_ALIGNMENT_TOP:
3070                 break;
3071
3072         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
3073                 y -= (__rect.height - lineTextSize.height) / 2.0f;
3074                 break;
3075
3076         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
3077                 y -= (__rect.height - lineTextSize.height);
3078                 break;
3079         }
3080
3081         if (x < 0.0f)
3082         {
3083                 x = 0.0f;
3084         }
3085
3086         int index = pTextLine->GetTextIndexFromPosition(x);
3087         row = 0;
3088         column = index;
3089
3090         _SetTextBidiHint(bidiHint);
3091
3092         SetLastResult(E_SUCCESS);
3093         return index;
3094 }
3095
3096 result
3097 TextObject::SetFirstDisplayLineIndexFromTextIndexInWrap(int textIndex)
3098 {
3099         result r = E_SUCCESS;
3100         FloatRectangle lineBounds;
3101         float firstDisplayPositionY = 0.0f;
3102         int currentTextIndex = textIndex;
3103         int firstDisplayLineIndex = 0;
3104         int lineIndex = 0;
3105         int lineCount = 0;
3106         float remainingHeight = 0.0f;
3107         TextLine* pTextLine = null;
3108         bool isChanged = false;
3109
3110         lineCount = __pTextColumn->GetTotalLineCount();
3111         lineIndex = __pTextColumn->GetLineIndexAtTextIndex(currentTextIndex);
3112         firstDisplayLineIndex = __pTextColumn->GetFirstDisplayLineIndex();
3113
3114         if (lineIndex == -1 && 0 < currentTextIndex && currentTextIndex == __pCompositeText->GetTextLength())
3115         {
3116                 currentTextIndex--;
3117                 lineIndex = __pTextColumn->GetLineIndexAtTextIndex(currentTextIndex);
3118         }
3119
3120         pTextLine = __pTextColumn->GetTextLine(lineIndex);
3121         SysTryReturn(NID_GRP, pTextLine, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
3122
3123         lineBounds = pTextLine->GetBoundsF();
3124
3125         if (firstDisplayLineIndex < lineIndex)
3126         {
3127                 TextLine* pTextLine = null;
3128                 int currentLineIndex = 0;
3129                 int displayLineCount = 0;
3130
3131                 currentLineIndex = firstDisplayLineIndex;
3132                 pTextLine = __pTextColumn->GetTextLine(currentLineIndex);
3133                 SysTryReturn(NID_GRP, pTextLine, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
3134
3135                 remainingHeight = __rect.height;
3136
3137                 while ((remainingHeight != 0.0f) && firstDisplayLineIndex < lineCount)
3138                 {
3139                         if (remainingHeight < 0.0f)
3140                         {
3141                                 break;
3142                         }
3143
3144                         lineBounds = pTextLine->GetBoundsF();
3145
3146                         remainingHeight -= lineBounds.height;
3147                         displayLineCount++;
3148                         currentLineIndex++;
3149
3150                         pTextLine = __pTextColumn->GetTextLine(currentLineIndex);
3151                         if (pTextLine == null)
3152                         {
3153                                 break;
3154                         }
3155                 }
3156
3157                 if (lineIndex < firstDisplayLineIndex + displayLineCount)
3158                 {
3159                         if (0.0f < remainingHeight && 0 < firstDisplayLineIndex)
3160                         {
3161                                 pTextLine = __pTextColumn->GetTextLine(firstDisplayLineIndex - 1);
3162                                 SysTryReturn(NID_GRP, pTextLine, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
3163
3164                                 while (remainingHeight && pTextLine)
3165                                 {
3166                                         lineBounds = pTextLine->GetBoundsF();
3167                                         remainingHeight -= lineBounds.height;
3168
3169                                         if (remainingHeight < 0.0f)
3170                                         {
3171                                                 firstDisplayPositionY = lineBounds.y + remainingHeight;
3172                                                 displayLineCount++;
3173                                                 firstDisplayLineIndex--;
3174                                                 break;
3175                                         }
3176                                         else
3177                                         {
3178                                                 firstDisplayPositionY = lineBounds.y;
3179                                         }
3180
3181                                         displayLineCount++;
3182                                         firstDisplayLineIndex--;
3183
3184                                         pTextLine = __pTextColumn->GetTextLine(firstDisplayLineIndex - 1);
3185                                 }
3186
3187                                 isChanged = true;
3188                         }
3189                         else if (remainingHeight < 0.0f && (lineIndex == firstDisplayLineIndex + displayLineCount - 1))
3190                         {
3191                                 pTextLine = __pTextColumn->GetTextLine(lineIndex);
3192                                 SysTryReturn(NID_GRP, pTextLine, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
3193
3194                                 lineBounds = pTextLine->GetBoundsF();
3195                                 remainingHeight = __rect.height;
3196
3197                                 firstDisplayLineIndex = lineIndex;
3198                                 firstDisplayPositionY = lineBounds.y;
3199                                 remainingHeight -= lineBounds.height;
3200
3201                                 int currentLineIndex = lineIndex - 1;
3202                                 pTextLine = __pTextColumn->GetTextLine(currentLineIndex);
3203
3204                                 while ((pTextLine != null) && 0 < firstDisplayLineIndex && 0.0f < remainingHeight)
3205                                 {
3206                                         lineBounds = pTextLine->GetBoundsF();
3207
3208                                         if (remainingHeight < lineBounds.height)
3209                                         {
3210                                                 firstDisplayLineIndex--;
3211                                                 firstDisplayPositionY = lineBounds.y + (lineBounds.height - remainingHeight);
3212                                                 break;
3213                                         }
3214                                         else
3215                                         {
3216                                                 remainingHeight -= lineBounds.height;
3217                                                 firstDisplayLineIndex--;
3218                                                 firstDisplayPositionY = lineBounds.y;
3219                                                 currentLineIndex--;
3220                                                 pTextLine = __pTextColumn->GetTextLine(currentLineIndex);
3221                                         }
3222                                 }
3223                                 isChanged = true;
3224                         }
3225                 }
3226                 else
3227                 {
3228                         pTextLine = __pTextColumn->GetTextLine(lineIndex);
3229                         SysTryReturn(NID_GRP, pTextLine, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
3230
3231                         lineBounds = pTextLine->GetBoundsF();
3232
3233                         remainingHeight = __rect.height;
3234
3235                         firstDisplayLineIndex = lineIndex;
3236                         firstDisplayPositionY = lineBounds.y;
3237                         remainingHeight -= lineBounds.height;
3238
3239                         int currentLineIndex = lineIndex - 1;
3240                         pTextLine = __pTextColumn->GetTextLine(currentLineIndex);
3241
3242                         while (pTextLine && 0 < firstDisplayLineIndex && 0.0f < remainingHeight)
3243                         {
3244                                 lineBounds = pTextLine->GetBoundsF();
3245
3246                                 if (remainingHeight < lineBounds.height)
3247                                 {
3248                                         firstDisplayLineIndex--;
3249                                         firstDisplayPositionY = lineBounds.y + (lineBounds.height - remainingHeight);
3250                                         break;
3251                                 }
3252                                 else
3253                                 {
3254                                         remainingHeight -= lineBounds.height;
3255                                         firstDisplayLineIndex--;
3256                                         firstDisplayPositionY = lineBounds.y;
3257                                         currentLineIndex--;
3258                                         pTextLine = __pTextColumn->GetTextLine(currentLineIndex);
3259                                 }
3260                         }
3261                         isChanged = true;
3262                 }
3263         }
3264         else
3265         {
3266                 lineBounds = pTextLine->GetBoundsF();
3267                 firstDisplayLineIndex = lineIndex;
3268                 firstDisplayPositionY = lineBounds.y;
3269                 isChanged = true;
3270         }
3271
3272         if (isChanged == true)
3273         {
3274                 __pTextColumn->SetFirstDisplayLineIndex(firstDisplayLineIndex);
3275                 __pTextColumn->SetFirstDisplayPositionY(firstDisplayPositionY);
3276         }
3277
3278         return E_SUCCESS;
3279 }
3280
3281 result
3282 TextObject::SetFirstDisplayLineIndexFromTextIndexInNoneWrap(int textIndex)
3283 {
3284         int lineOffset = 0;
3285         int lineEndIndex = 0;
3286         int lineLength = 0;
3287         int count = 0;
3288         float firstDisplayPositionX = __pTextColumn->GetFirstDisplayPositionX();
3289         FloatRectangle lineBounds;
3290         FloatDimension lineTextSize;
3291         FloatDimension currentLinetextSize;
3292         FloatDimension prevTextSize;
3293
3294         _FontImpl* pFont = _FontImpl::GetInstance(*__pDefaultFont);
3295         SysTryReturn(NID_GRP, pFont, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get native font instance.");
3296
3297         TextLine* pTextLine = __pTextColumn->GetTextLine(0);
3298         SysTryReturn(NID_GRP, pTextLine, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
3299
3300         lineOffset = pTextLine->GetTextOffset();
3301         lineLength = pTextLine->GetTextLength();
3302         lineEndIndex = pTextLine->GetTextOffset() + pTextLine->GetTextLength();
3303         lineBounds = pTextLine->GetBoundsF();
3304
3305         pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
3306
3307         __pCompositeText->ForwardAnalyze(lineOffset, textIndex, lineBounds.width, __wrap, count, currentLinetextSize.width, currentLinetextSize.height);
3308
3309         if (0 < textIndex)
3310         {
3311                 __pCompositeText->ForwardAnalyze(lineOffset, textIndex - 1, lineBounds.width,__wrap, count, prevTextSize.width, prevTextSize.height);
3312         }
3313
3314         if (prevTextSize.width < firstDisplayPositionX)
3315         {
3316                 SetFirstDisplayPositionX(prevTextSize.width);
3317
3318                 pTextLine->SetBounds(lineBounds);
3319                 pTextLine->SetRegion(lineTextSize.width, lineTextSize.height);
3320                 pTextLine->SetTextLength(lineLength);
3321                 __pCompositeText->GetTextExtentList(pTextLine);
3322         }
3323         else if (firstDisplayPositionX + __rect.width <= currentLinetextSize.width) // 글자가 display 영역 뒤로 계속 쓸 때
3324         {
3325                 float tempWidth = 0.0f;
3326                 float tempHeight = 0.0f;
3327                 int textCount = 0;
3328
3329                 __pCompositeText->ForwardAnalyze(0, textIndex, lineBounds.width, __wrap, textCount, tempWidth, tempHeight);
3330                 SetFirstDisplayPositionX(tempWidth - __rect.width);
3331
3332                 pTextLine->SetBounds(lineBounds);
3333                 pTextLine->SetRegion(lineTextSize.width, lineTextSize.height);
3334                 pTextLine->SetTextOffset(0);
3335                 pTextLine->SetTextLength(lineLength);
3336                 __pCompositeText->GetTextExtentList(pTextLine);
3337         }
3338         else if (lineBounds.width < firstDisplayPositionX + __rect.width && lineLength <= textIndex) // 글 꽉 채운 후 한글자씩 지울 때
3339         {
3340                 float tempWidth = 0.0f;
3341                 float tempHeight = 0.0f;
3342                 int textCount = 0;
3343
3344                 __pCompositeText->ForwardAnalyze(0, textIndex, lineBounds.width, __wrap, textCount, tempWidth, tempHeight);
3345                 SetFirstDisplayPositionX(tempWidth - __rect.width);
3346
3347                 pTextLine->SetBounds(lineBounds);
3348                 pTextLine->SetRegion(lineTextSize.width, lineTextSize.height);
3349                 pTextLine->SetTextOffset(0);
3350                 pTextLine->SetTextLength(lineLength);
3351                 __pCompositeText->GetTextExtentList(pTextLine);
3352         }
3353         else if (lineBounds.width < firstDisplayPositionX + __rect.width) // 글 꽉 채운 후에, 중간에 글자를 지울 때,
3354         {
3355                 float tempWidth = 0.0f;
3356                 float tempHeight = 0.0f;
3357                 int textCount = 0;
3358
3359                 float gap = __rect.width - (lineBounds.width - currentLinetextSize.width);
3360
3361                 __pCompositeText->ForwardAnalyze(0, textIndex, lineBounds.width, __wrap, textCount, tempWidth, tempHeight);
3362                 SetFirstDisplayPositionX(tempWidth - gap);
3363
3364                 pTextLine->SetBounds(lineBounds);
3365                 pTextLine->SetRegion(lineTextSize.width, lineTextSize.height);
3366                 pTextLine->SetTextOffset(0);
3367                 pTextLine->SetTextLength(lineLength);
3368                 __pCompositeText->GetTextExtentList(pTextLine);
3369         }
3370
3371         __pTextColumn->SetFirstDisplayLineIndex(0);
3372         __pTextColumn->SetFirstDisplayPositionY(0.0f);
3373
3374         return E_SUCCESS;
3375 }
3376
3377 result
3378 TextObject::GetTextPositionInfoInWrapAt(int textIndex, int& width, int& height, int& absX, int& absY,
3379                                                                                                                                         int& logicalX, int& logicalY) const
3380 {
3381         float widthF = _CoordinateSystemUtils::ConvertToFloat(width);
3382         float heightF =  _CoordinateSystemUtils::ConvertToFloat(height);
3383         float absXF = _CoordinateSystemUtils::ConvertToFloat(absX);
3384         float absYF = _CoordinateSystemUtils::ConvertToFloat(absY);
3385         float logicalXF = _CoordinateSystemUtils::ConvertToFloat(logicalX);
3386         float logicalYF = _CoordinateSystemUtils::ConvertToFloat(logicalY);
3387
3388         result r = GetTextPositionInfoInWrapAt(textIndex, widthF, heightF, absXF, absYF, logicalXF, logicalYF);
3389         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
3390
3391         width = _CoordinateSystemUtils::ConvertToInteger(widthF);
3392         height = _CoordinateSystemUtils::ConvertToInteger(heightF);
3393         absX = _CoordinateSystemUtils::ConvertToInteger(absXF);
3394         absY = _CoordinateSystemUtils::ConvertToInteger(absYF);
3395         logicalX = _CoordinateSystemUtils::ConvertToInteger(logicalXF);
3396         logicalY = _CoordinateSystemUtils::ConvertToInteger(logicalYF);
3397
3398         return E_SUCCESS;
3399 }
3400
3401 result
3402 TextObject::GetTextPositionInfoInWrapAt(int textIndex, float& width, float& height, float& absX, float& absY,
3403                                                                                                                                         float& logicalX, float& logicalY) const
3404 {
3405         TextLine* pTextLine = null;
3406         FloatRectangle lineBounds;
3407         float firstDisplayPositionY = __pTextColumn->GetFirstDisplayPositionYF();
3408         int lineCount = __pTextColumn->GetTotalLineCount();
3409         int lineIndex = 0;
3410         int lineOffset = 0;
3411         int lineLength = 0;
3412         int textIndexFromLineOffset = 0;
3413         float lineY = 0.0f;
3414         float posX = 0.0f;
3415         float posY = 0.0f;
3416
3417         _FontImpl* pFont = _FontImpl::GetInstance(*__pDefaultFont);
3418         SysTryReturn(NID_GRP, pFont, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get native font instance.");
3419
3420         for (lineIndex = 0; lineIndex < lineCount; lineIndex++)
3421         {
3422                 pTextLine = __pTextColumn->GetTextLine(lineIndex);
3423                 SysTryReturn(NID_GRP, pTextLine, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
3424
3425                 lineBounds = pTextLine->GetBoundsF();
3426                 lineOffset = pTextLine->GetTextOffset();
3427                 lineLength = pTextLine->GetTextLength();
3428
3429                 if (lineOffset <= textIndex && textIndex < lineOffset + lineLength)
3430                 {
3431                         break;
3432                 }
3433
3434                 if (lineIndex + 1 < lineCount)
3435                 {
3436                         lineY += lineBounds.height;
3437                 }
3438         }
3439
3440         SysTryReturn(NID_GRP, pTextLine, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
3441
3442         if (lineIndex == lineCount)
3443         {
3444                 textIndexFromLineOffset = lineLength;
3445         }
3446         else
3447         {
3448                 textIndexFromLineOffset = textIndex - lineOffset;
3449         }
3450
3451         FloatDimension lineTextSize;
3452         pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
3453
3454         if (lineTextSize.height == 0)
3455         {
3456                 lineTextSize.height = TextUtility::GetFontMaxHeightF(pFont);
3457         }
3458
3459         switch (__align & TEXT_ALIGNMASK_HORIZ)
3460         {
3461         case TEXT_OBJECT_ALIGNMENT_LEFT:
3462                 break;
3463
3464         case TEXT_OBJECT_ALIGNMENT_CENTER:
3465                 posX += (lineBounds.width - lineTextSize.width) / 2.0f;
3466                 break;
3467
3468         case TEXT_OBJECT_ALIGNMENT_RIGHT:
3469                 posX += (lineBounds.width - lineTextSize.width);
3470                 break;
3471         }
3472
3473         switch (__align & TEXT_ALIGNMASK_VERT)
3474         {
3475         case TEXT_OBJECT_ALIGNMENT_TOP:
3476                 break;
3477
3478         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
3479                 posY += (__rect.height - __pTextColumn->GetDisplayHeightF()) / 2.0f;
3480                 break;
3481
3482         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
3483                 posY += (__rect.height - __pTextColumn->GetDisplayHeightF());
3484                 break;
3485         }
3486
3487         if (posX < 0.0f)
3488         {
3489                 posX = 0.0f;
3490         }
3491
3492         if (posY < 0.0f)
3493         {
3494                 posY = 0.0f;
3495         }
3496
3497         FloatRectangle textExtent = pTextLine->GetTextExtentF(textIndexFromLineOffset, 1);
3498
3499         if (lineIndex == lineCount)
3500         {
3501                 textExtent.width = 0.0f;
3502         }
3503
3504         if (textIndex >= 1)
3505         {
3506                 Font* pTextFont = __pCompositeText->GetFont(textIndex - 1);
3507                 textExtent.height = TextUtility::GetFontMaxHeightF(pTextFont);
3508         }
3509
3510         if (textExtent.height < 0.0f)
3511         {
3512                 textExtent.height = TextUtility::GetFontMaxHeightF(pFont);
3513         }
3514
3515         TextObjectAlignment alignment = __pCompositeText->GetElementVerticalAlignment();
3516         switch (alignment & TEXT_ALIGNMASK_VERT)
3517         {
3518         case TEXT_OBJECT_ALIGNMENT_TOP:
3519                 // fall through
3520         default:
3521                 break;
3522
3523         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
3524                 lineY = lineY + (lineBounds.height - textExtent.height) / 2.0f;
3525                 break;
3526
3527         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
3528                 lineY = lineY + (lineBounds.height - textExtent.height);
3529                 break;
3530         }
3531
3532         width =  textExtent.width;
3533         height =  textExtent.height;
3534         absX = posX + textExtent.x;
3535         logicalX = absX + __rect.x;
3536         absY = lineY;
3537         logicalY = absY - firstDisplayPositionY + __rect.y + posY;
3538
3539         return E_SUCCESS;
3540 }
3541
3542 result
3543 TextObject::GetTextPositionInfoInWrapAt(int row, int column, float& width, float& height, float& absX, float& absY,
3544                                                                                                                                         float& logicalX, float& logicalY) const
3545 {
3546         TextLine* pTextLine = null;
3547         float firstDisplayPositionY = __pTextColumn->GetFirstDisplayPositionYF();
3548         int lineCount = __pTextColumn->GetTotalLineCount();
3549         float posX = 0.0f;
3550         float posY = 0.0f;
3551
3552         _FontImpl* pFont = _FontImpl::GetInstance(*__pDefaultFont);
3553         SysTryReturn(NID_GRP, pFont, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get native font instance.");
3554
3555         pTextLine = __pTextColumn->GetTextLine(row);
3556         SysTryReturn(NID_GRP, pTextLine, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
3557
3558         FloatRectangle lineBounds = pTextLine->GetBoundsF();
3559         int lineOffset = pTextLine->GetTextOffset();
3560         int lineLength = pTextLine->GetTextLength();
3561         int textIndex = pTextLine->GetTextOffset() + column;
3562         float lineY = lineBounds.y;
3563
3564         SysTryReturn(NID_GRP, lineOffset <= textIndex && textIndex <= lineOffset + lineLength
3565                 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (row = %d, column = %d)", row, column);
3566
3567         FloatDimension lineTextSize;
3568         pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
3569
3570         if (lineTextSize.height == 0)
3571         {
3572                 lineTextSize.height = TextUtility::GetFontMaxHeightF(pFont);
3573         }
3574
3575         switch (__align & TEXT_ALIGNMASK_HORIZ)
3576         {
3577         case TEXT_OBJECT_ALIGNMENT_LEFT:
3578                 break;
3579
3580         case TEXT_OBJECT_ALIGNMENT_CENTER:
3581                 posX += (lineBounds.width - lineTextSize.width) / 2.0f;
3582                 break;
3583
3584         case TEXT_OBJECT_ALIGNMENT_RIGHT:
3585                 posX += (lineBounds.width - lineTextSize.width);
3586                 break;
3587         }
3588
3589         switch (__align & TEXT_ALIGNMASK_VERT)
3590         {
3591         case TEXT_OBJECT_ALIGNMENT_TOP:
3592                 break;
3593
3594         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
3595                 posY += (__rect.height - __pTextColumn->GetDisplayHeightF()) / 2.0f;
3596                 break;
3597
3598         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
3599                 posY += (__rect.height - __pTextColumn->GetDisplayHeightF());
3600                 break;
3601         }
3602
3603         if (posX < 0.0f)
3604         {
3605                 posX = 0.0f;
3606         }
3607
3608         if (posY < 0.0f)
3609         {
3610                 posY = 0.0f;
3611         }
3612
3613         FloatRectangle textExtent = pTextLine->GetTextExtentF(column, 1);
3614
3615         if (row == lineCount)
3616         {
3617                 textExtent.width = 0.0f;
3618         }
3619
3620         if (textIndex >= 1)
3621         {
3622                 Font* pTextFont = __pCompositeText->GetFont(textIndex - 1);
3623                 textExtent.height = TextUtility::GetFontMaxHeightF(pTextFont);
3624         }
3625
3626         if (textExtent.height < 0.0f)
3627         {
3628                 textExtent.height = TextUtility::GetFontMaxHeightF(pFont);
3629         }
3630
3631         TextObjectAlignment alignment = __pCompositeText->GetElementVerticalAlignment();
3632         switch (alignment & TEXT_ALIGNMASK_VERT)
3633         {
3634         case TEXT_OBJECT_ALIGNMENT_TOP:
3635                 // fall through
3636         default:
3637                 break;
3638
3639         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
3640                 lineY = lineY + (lineBounds.height - textExtent.height) / 2.0f;
3641                 break;
3642
3643         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
3644                 lineY = lineY + (lineBounds.height - textExtent.height);
3645                 break;
3646         }
3647
3648         width =  textExtent.width;
3649         height =  textExtent.height;
3650         absX = posX + textExtent.x;
3651         logicalX = absX + __rect.x;
3652         absY = lineY;
3653         logicalY = absY - firstDisplayPositionY + __rect.y + posY;
3654
3655         return E_SUCCESS;
3656 }
3657
3658 result
3659 TextObject::GetBlockTextPositionInfoInWrapAt(int textIndex, int& width, int& height, int& absX, int& absY,
3660                                                                                                                                         int& logicalX, int& logicalY) const
3661 {
3662         float widthF = _CoordinateSystemUtils::ConvertToFloat(width);
3663         float heightF =  _CoordinateSystemUtils::ConvertToFloat(height);
3664         float absXF = _CoordinateSystemUtils::ConvertToFloat(absX);
3665         float absYF = _CoordinateSystemUtils::ConvertToFloat(absY);
3666         float logicalXF = _CoordinateSystemUtils::ConvertToFloat(logicalX);
3667         float logicalYF = _CoordinateSystemUtils::ConvertToFloat(logicalY);
3668
3669         result r = GetBlockTextPositionInfoInWrapAt(textIndex, widthF, heightF, absXF, absYF, logicalXF, logicalYF);
3670         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
3671
3672         width = _CoordinateSystemUtils::ConvertToInteger(widthF);
3673         height = _CoordinateSystemUtils::ConvertToInteger(heightF);
3674         absX = _CoordinateSystemUtils::ConvertToInteger(absXF);
3675         absY = _CoordinateSystemUtils::ConvertToInteger(absYF);
3676         logicalX = _CoordinateSystemUtils::ConvertToInteger(logicalXF);
3677         logicalY = _CoordinateSystemUtils::ConvertToInteger(logicalYF);
3678
3679         return E_SUCCESS;
3680 }
3681
3682 result
3683 TextObject::GetBlockTextPositionInfoInWrapAt(int textIndex, float& width, float& height, float& absX, float& absY,
3684                                                                                                                                         float& logicalX, float& logicalY) const
3685 {
3686         TextLine* pTextLine = null;
3687         FloatRectangle lineBounds;
3688         float firstDisplayPositionY = __pTextColumn->GetFirstDisplayPositionYF();
3689         int lineCount = __pTextColumn->GetTotalLineCount();
3690         int lineIndex = 0;
3691         int lineOffset = 0;
3692         int lineLength = 0;
3693         int textIndexFromLineOffset = 0;
3694         float lineY = 0.0f;
3695         float posX = 0.0f;
3696         float posY = 0.0f;
3697
3698         _FontImpl* pFont = _FontImpl::GetInstance(*__pDefaultFont);
3699         SysTryReturn(NID_GRP, pFont, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get native font instance.");
3700
3701         for (lineIndex = 0; lineIndex < lineCount; lineIndex++)
3702         {
3703                 pTextLine = __pTextColumn->GetTextLine(lineIndex);
3704                 SysTryReturn(NID_GRP, pTextLine, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
3705
3706                 lineBounds = pTextLine->GetBoundsF();
3707                 lineOffset = pTextLine->GetTextOffset();
3708                 lineLength = pTextLine->GetTextLength();
3709
3710                 if (lineOffset <= textIndex && textIndex <= lineOffset + lineLength)
3711                 {
3712                         break;
3713                 }
3714
3715                 if (lineIndex + 1 < lineCount)
3716                 {
3717                         lineY += lineBounds.height;
3718                 }
3719         }
3720
3721         SysTryReturn(NID_GRP, pTextLine, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
3722
3723         if (lineIndex == lineCount)
3724         {
3725                 textIndexFromLineOffset = lineLength;
3726         }
3727         else
3728         {
3729                 textIndexFromLineOffset = textIndex - lineOffset;
3730         }
3731
3732         FloatDimension lineTextSize;
3733         pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
3734
3735         if (lineTextSize.height == 0.0f)
3736         {
3737                 lineTextSize.height = TextUtility::GetFontMaxHeightF(pFont);
3738         }
3739
3740         switch (__align & TEXT_ALIGNMASK_HORIZ)
3741         {
3742         case TEXT_OBJECT_ALIGNMENT_LEFT:
3743                 break;
3744
3745         case TEXT_OBJECT_ALIGNMENT_CENTER:
3746                 posX += (lineBounds.width - lineTextSize.width) / 2.0f;
3747                 break;
3748
3749         case TEXT_OBJECT_ALIGNMENT_RIGHT:
3750                 posX += (lineBounds.width - lineTextSize.width);
3751                 break;
3752         }
3753
3754         switch (__align & TEXT_ALIGNMASK_VERT)
3755         {
3756         case TEXT_OBJECT_ALIGNMENT_TOP:
3757                 break;
3758
3759         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
3760                 posY += (__rect.height - __pTextColumn->GetDisplayHeightF()) / 2.0f;
3761                 break;
3762
3763         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
3764                 posY += (__rect.height - __pTextColumn->GetDisplayHeightF());
3765                 break;
3766         }
3767
3768         if (posX < 0.0f)
3769         {
3770                 posX = 0.0f;
3771         }
3772
3773         if (posY < 0.0f)
3774         {
3775                 posY = 0.0f;
3776         }
3777
3778         FloatRectangle textExtent = pTextLine->GetBlockTextExtentF(textIndexFromLineOffset, 1);
3779
3780         if (lineIndex == lineCount)
3781         {
3782                 textExtent.width = 0.0f;
3783         }
3784
3785         if (textIndex >= 1)
3786         {
3787                 Font* pTextFont = __pCompositeText->GetFont(textIndex - 1);
3788                 textExtent.height = TextUtility::GetFontMaxHeightF(pTextFont);
3789         }
3790
3791         if (textExtent.height < 0)
3792         {
3793                 textExtent.height = TextUtility::GetFontMaxHeightF(pFont);
3794         }
3795
3796         TextObjectAlignment alignment = __pCompositeText->GetElementVerticalAlignment();
3797         switch (alignment & TEXT_ALIGNMASK_VERT)
3798         {
3799         case TEXT_OBJECT_ALIGNMENT_TOP:
3800                 // fall through
3801         default:
3802                 break;
3803
3804         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
3805                 lineY = lineY + (lineBounds.height - textExtent.height) / 2.0f;
3806                 break;
3807
3808         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
3809                 lineY = lineY + (lineBounds.height - textExtent.height);
3810                 break;
3811         }
3812
3813         width =  textExtent.width;
3814         height =  textExtent.height;
3815         absX = posX + textExtent.x;
3816         logicalX = absX + __rect.x;
3817         absY = lineY;
3818         logicalY = absY - firstDisplayPositionY + __rect.y + posY;
3819
3820         return E_SUCCESS;
3821 }
3822
3823 result
3824 TextObject::GetTextPositionInfoInNoneWrapAt(int textIndex, int& width, int& height, int& absX, int& absY,
3825                                                                                                                                 int& logicalX, int& logicalY) const
3826 {
3827         float widthF = _CoordinateSystemUtils::ConvertToFloat(width);
3828         float heightF =  _CoordinateSystemUtils::ConvertToFloat(height);
3829         float absXF = _CoordinateSystemUtils::ConvertToFloat(absX);
3830         float absYF = _CoordinateSystemUtils::ConvertToFloat(absY);
3831         float logicalXF = _CoordinateSystemUtils::ConvertToFloat(logicalX);
3832         float logicalYF = _CoordinateSystemUtils::ConvertToFloat(logicalY);
3833
3834         result r = GetTextPositionInfoInNoneWrapAt(textIndex, widthF, heightF, absXF, absYF, logicalXF, logicalYF);
3835         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
3836
3837         width = _CoordinateSystemUtils::ConvertToInteger(widthF);
3838         height = _CoordinateSystemUtils::ConvertToInteger(heightF);
3839         absX = _CoordinateSystemUtils::ConvertToInteger(absXF);
3840         absY = _CoordinateSystemUtils::ConvertToInteger(absYF);
3841         logicalX = _CoordinateSystemUtils::ConvertToInteger(logicalXF);
3842         logicalY = _CoordinateSystemUtils::ConvertToInteger(logicalYF);
3843
3844         return E_SUCCESS;
3845 }
3846
3847 result
3848 TextObject::GetTextPositionInfoInNoneWrapAt(int textIndex, float& width, float& height, float& absX, float& absY,
3849                                                                                                                                 float& logicalX, float& logicalY) const
3850 {
3851         TextLine* pTextLine = null;
3852         pTextLine = __pTextColumn->GetTextLine(0);
3853         SysTryReturn(NID_GRP, pTextLine, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
3854
3855         int lineLength = pTextLine->GetTextLength();
3856         float firstDisplayPositionX = __pTextColumn->GetFirstDisplayPositionX();
3857         float posX = 0.0f;
3858         float posY = 0.0f;
3859
3860         _FontImpl* pFont = _FontImpl::GetInstance(*__pDefaultFont);
3861         SysTryReturn(NID_GRP, pFont, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get native font instance.");
3862
3863         FloatDimension lineTextSize;
3864         FloatRectangle lineBounds;
3865         lineBounds = pTextLine->GetBoundsF();
3866         pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
3867
3868         if (lineTextSize.height == 0.0f || pTextLine->GetTextLength() == 0.0f)
3869         {
3870                 lineTextSize.height = TextUtility::GetFontMaxHeightF(pFont);
3871         }
3872
3873         switch (__align & TEXT_ALIGNMASK_HORIZ)
3874         {
3875         case TEXT_OBJECT_ALIGNMENT_LEFT:
3876                 break;
3877
3878         case TEXT_OBJECT_ALIGNMENT_CENTER:
3879                 posX += (lineBounds.width - lineTextSize.width) / 2.0f;
3880                 break;
3881
3882         case TEXT_OBJECT_ALIGNMENT_RIGHT:
3883                 posX += (lineBounds.width - lineTextSize.width);
3884                 break;
3885         }
3886
3887         switch (__align & TEXT_ALIGNMASK_VERT)
3888         {
3889         case TEXT_OBJECT_ALIGNMENT_TOP:
3890                 break;
3891
3892         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
3893                 posY += (__rect.height - lineTextSize.height) / 2.0f;
3894                 break;
3895
3896         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
3897                 posY += (__rect.height - lineTextSize.height);
3898                 break;
3899         }
3900
3901         posX = (posX < 0.0f) ? 0.0f : posX;
3902         posY = (posY < 0.0f) ? 0.0f : posY;
3903
3904         FloatRectangle textExtent = pTextLine->GetTextExtentF(textIndex - pTextLine->GetTextOffset(), 1);
3905
3906         if (textIndex >= 1)
3907         {
3908                 Font* pTextFont = __pCompositeText->GetFont(textIndex - 1);
3909                 textExtent.height = TextUtility::GetFontMaxHeightF(pTextFont);
3910         }
3911
3912         if (textExtent.height < 0.0f)
3913         {
3914                 textExtent.height = TextUtility::GetFontMaxHeightF(pFont);
3915         }
3916
3917         TextObjectAlignment alignment = __pCompositeText->GetElementVerticalAlignment();
3918         switch (alignment & TEXT_ALIGNMASK_VERT)
3919         {
3920         case TEXT_OBJECT_ALIGNMENT_TOP:
3921                 // fall through
3922         default:
3923                 break;
3924
3925         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
3926                 posY = posY + (lineBounds.height - textExtent.height) / 2.0f;
3927                 break;
3928
3929         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
3930                 posY = posY + (lineBounds.height - textExtent.height);
3931                 break;
3932         }
3933
3934         absX = posX + textExtent.x - firstDisplayPositionX;
3935         logicalX = (absX >= 0.0f) ? absX + __rect.x : absX;
3936         absY = posY;
3937         logicalY = absY + __rect.y;
3938         width = textExtent.width;
3939         height = textExtent.height;
3940
3941         return E_SUCCESS;
3942 }
3943
3944 result
3945 TextObject::GetTextPositionInfoInNoneWrapAt(int row, int column, float& width, float& height, float& absX, float& absY,
3946                                                                                                                                 float& logicalX, float& logicalY) const
3947 {
3948         TextLine* pTextLine = null;
3949         pTextLine = __pTextColumn->GetTextLine(row);
3950         SysTryReturn(NID_GRP, pTextLine, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
3951
3952         int lineLength = pTextLine->GetTextLength();
3953         float firstDisplayPositionX = __pTextColumn->GetFirstDisplayPositionX();
3954         float posX = 0.0f;
3955         float posY = 0.0f;
3956
3957         SysTryReturn(NID_GRP, 0 <= column && column <= lineLength, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (row = %d, column = %d)", row, column);
3958
3959         _FontImpl* pFont = _FontImpl::GetInstance(*__pDefaultFont);
3960         SysTryReturn(NID_GRP, pFont, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get native font instance.");
3961
3962         FloatDimension lineTextSize;
3963         FloatRectangle lineBounds;
3964         lineBounds = pTextLine->GetBoundsF();
3965         pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
3966
3967         if (lineTextSize.height == 0.0f || pTextLine->GetTextLength() == 0.0f)
3968         {
3969                 lineTextSize.height = TextUtility::GetFontMaxHeightF(pFont);
3970         }
3971
3972         switch (__align & TEXT_ALIGNMASK_HORIZ)
3973         {
3974         case TEXT_OBJECT_ALIGNMENT_LEFT:
3975                 break;
3976
3977         case TEXT_OBJECT_ALIGNMENT_CENTER:
3978                 posX += (lineBounds.width - lineTextSize.width) / 2.0f;
3979                 break;
3980
3981         case TEXT_OBJECT_ALIGNMENT_RIGHT:
3982                 posX += (lineBounds.width - lineTextSize.width);
3983                 break;
3984         }
3985
3986         switch (__align & TEXT_ALIGNMASK_VERT)
3987         {
3988         case TEXT_OBJECT_ALIGNMENT_TOP:
3989                 break;
3990
3991         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
3992                 posY += (__rect.height - lineTextSize.height) / 2.0f;
3993                 break;
3994
3995         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
3996                 posY += (__rect.height - lineTextSize.height);
3997                 break;
3998         }
3999
4000         posX = (posX < 0.0f) ? 0.0f : posX;
4001         posY = (posY < 0.0f) ? 0.0f : posY;
4002
4003         FloatRectangle textExtent = pTextLine->GetTextExtentF(column - pTextLine->GetTextOffset(), 1);
4004
4005         if (column >= 1)
4006         {
4007                 Font* pTextFont = __pCompositeText->GetFont(column - 1);
4008                 textExtent.height = TextUtility::GetFontMaxHeightF(pTextFont);
4009         }
4010
4011         if (textExtent.height < 0.0f)
4012         {
4013                 textExtent.height = TextUtility::GetFontMaxHeightF(pFont);
4014         }
4015
4016         TextObjectAlignment alignment = __pCompositeText->GetElementVerticalAlignment();
4017         switch (alignment & TEXT_ALIGNMASK_VERT)
4018         {
4019         case TEXT_OBJECT_ALIGNMENT_TOP:
4020                 // fall through
4021         default:
4022                 break;
4023
4024         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
4025                 posY = posY + (lineBounds.height - textExtent.height) / 2.0f;
4026                 break;
4027
4028         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
4029                 posY = posY + (lineBounds.height - textExtent.height);
4030                 break;
4031         }
4032
4033         absX = posX + textExtent.x - firstDisplayPositionX;
4034         logicalX = (absX >= 0.0f) ? absX + __rect.x : absX;
4035         absY = posY;
4036         logicalY = absY + __rect.y;
4037         width = textExtent.width;
4038         height = textExtent.height;
4039
4040         return E_SUCCESS;
4041 }
4042
4043 int
4044 TextObject::GetTotalComposedHeight(void) const
4045 {
4046         return _CoordinateSystemUtils::ConvertToInteger(GetTotalComposedHeightF());
4047 }
4048
4049 float
4050 TextObject::GetTotalComposedHeightF(void) const
4051 {
4052         return __pCompositeText->GetTotalComposedHeightF();
4053 }
4054
4055 int
4056 TextObject::GetLineWidthAt(int lineIndex) const
4057 {
4058         return _CoordinateSystemUtils::ConvertToInteger(GetLineWidthAtF(lineIndex));
4059 }
4060
4061 float
4062 TextObject::GetLineWidthAtF(int lineIndex) const
4063 {
4064         IF_NOT_CONSTRUCTED(return -1);
4065
4066         result r = E_SUCCESS;
4067         TextLine* pTextLine = null;
4068         FloatDimension lineTextSize;
4069         int lineLength = 0;
4070
4071         pTextLine = __pTextColumn->GetTextLine(lineIndex);
4072         SysTryCatch(NID_GRP, pTextLine, , E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
4073
4074         lineLength = pTextLine->GetTextLength();
4075         r = pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
4076         SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
4077
4078         SetLastResult(E_SUCCESS);
4079         return lineTextSize.width;
4080
4081 CATCH:
4082         return -1;
4083 }
4084
4085 int
4086 TextObject::GetTotalHeight(void) const
4087 {
4088         return _CoordinateSystemUtils::ConvertToInteger(GetTotalHeightF());
4089 }
4090
4091 float
4092 TextObject::GetTotalHeightF(void) const
4093 {
4094         IF_NOT_CONSTRUCTED(return -1);
4095
4096         float height = 0.0f;
4097         if (IsPartialComposingModeEnabled())
4098         {
4099                 height = __pCompositeText->GetAnalysedTotalHeightF();
4100         }
4101         else
4102         {
4103                 height = __pTextColumn->GetTotalHeightF();
4104         }
4105
4106         return height;
4107 }
4108
4109 int
4110 TextObject::GetElementIndexOf(TextElement& textElement) const
4111 {
4112         IF_NOT_CONSTRUCTED(return -1);
4113
4114         return __pCompositeText->GetElementIndexOf(textElement);
4115 }
4116
4117 result
4118 TextObject::RemoveElementAt(int elementIndex, bool deallocate)
4119 {
4120         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4121
4122         return __pCompositeText->RemoveElementAt(elementIndex, deallocate);
4123 }
4124
4125 result
4126 TextObject::HideFrontSpace(TextObjectSpaceHideType mode)
4127 {
4128         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4129
4130         __pCompositeText->HideFrontSpace(mode);
4131
4132         return E_SUCCESS;
4133 }
4134
4135 result
4136 TextObject::HideRearSpace(TextObjectSpaceHideType mode)
4137 {
4138         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4139
4140         __pCompositeText->HideRearSpace(mode);
4141
4142         return E_SUCCESS;
4143 }
4144
4145 int
4146 TextObject::GetSlidingStep(void) const
4147 {
4148         return _CoordinateSystemUtils::ConvertToInteger(GetSlidingStepF());
4149 }
4150
4151 float
4152 TextObject::GetSlidingStepF(void) const
4153 {
4154         IF_NOT_CONSTRUCTED(return -1.0f);
4155
4156         return __slidingStep;
4157 }
4158
4159
4160 result
4161 TextObject::SetSlidingStep(int slidingStep)
4162 {
4163         return SetSlidingStep(_CoordinateSystemUtils::ConvertToFloat(slidingStep));
4164 }
4165
4166 result
4167 TextObject::SetSlidingStep(float slidingStep)
4168 {
4169         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4170
4171         __slidingStep = slidingStep;
4172
4173         return E_SUCCESS;
4174 }
4175
4176 int
4177 TextObject::GetTotalLineCount(void) const
4178 {
4179         IF_NOT_CONSTRUCTED(return -1);
4180
4181         return __pTextColumn->GetTotalLineCount();
4182 }
4183
4184 int
4185 TextObject::GetLineIndexAtTextIndex(int textIndex)  const
4186 {
4187         IF_NOT_CONSTRUCTED(return -1);
4188
4189         return __pTextColumn->GetLineIndexAtTextIndex(textIndex);
4190 }
4191
4192 int
4193 TextObject::GetLineHeightAt(int lineIndex)  const
4194 {
4195         return _CoordinateSystemUtils::ConvertToInteger(GetLineHeightAtF(lineIndex));
4196 }
4197
4198 float
4199 TextObject::GetLineHeightAtF(int lineIndex) const
4200 {
4201         IF_NOT_CONSTRUCTED(return -1);
4202
4203         SysTryReturn(NID_GRP, lineIndex >= 0, -1, E_INVALID_ARG
4204                         , "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
4205
4206         return __pTextColumn->GetLineHeightAtF(lineIndex);
4207 }
4208
4209 int
4210 TextObject::GetDisplayLineCount(void)  const
4211 {
4212         IF_NOT_CONSTRUCTED(return -1);
4213
4214         return __pTextColumn->GetDisplayLineCount();
4215 }
4216
4217 int
4218 TextObject::GetFirstDisplayLineIndex(void) const
4219 {
4220         IF_NOT_CONSTRUCTED(return -1);
4221
4222         return __pTextColumn->GetFirstDisplayLineIndex();
4223 }
4224
4225 int
4226 TextObject::GetFirstDisplayPositionY(void) const
4227 {
4228         return _CoordinateSystemUtils::ConvertToInteger(GetFirstDisplayPositionYF());
4229 }
4230
4231 float
4232 TextObject::GetFirstDisplayPositionYF(void) const
4233 {
4234         IF_NOT_CONSTRUCTED(return -1);
4235
4236         return __pTextColumn->GetFirstDisplayPositionYF();
4237 }
4238
4239 int
4240 TextObject::GetLineIndexAtPositionY(int y) const
4241 {
4242         return GetLineIndexAtPositionY(_CoordinateSystemUtils::ConvertToFloat(y));
4243 }
4244
4245 int
4246 TextObject::GetLineIndexAtPositionY(float y) const
4247 {
4248         IF_NOT_CONSTRUCTED(return -1);
4249
4250         return __pTextColumn->GetLineIndexAtPositionY(y);
4251 }
4252
4253 int
4254 TextObject::GetFirstTextIndexAt(int lineIndex) const
4255 {
4256         IF_NOT_CONSTRUCTED(return -1);
4257
4258         SysTryReturn(NID_GRP, lineIndex >= 0, -1, E_INVALID_ARG
4259                         , "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
4260
4261         return __pTextColumn->GetFirstTextIndexAt(lineIndex);
4262 }
4263
4264 int
4265 TextObject::GetTextLengthAt(int lineIndex) const
4266 {
4267         IF_NOT_CONSTRUCTED(return -1);
4268
4269         SysTryReturn(NID_GRP, lineIndex >= 0, -1, E_INVALID_ARG
4270                         , "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
4271
4272         return __pTextColumn->GetTextLengthAt(lineIndex);
4273 }
4274
4275 Rectangle
4276 TextObject::GetBounds(void) const
4277 {
4278         IF_NOT_CONSTRUCTED(return Rectangle(0, 0, 0, 0));
4279
4280         return _CoordinateSystemUtils::ConvertToInteger(__rect);
4281 }
4282
4283 FloatRectangle
4284 TextObject::GetBoundsF(void) const
4285 {
4286         return __rect;
4287 }
4288
4289 int
4290 TextObject::GetLineSpace(void) const
4291 {
4292         IF_NOT_CONSTRUCTED(return -1);
4293
4294         return _CoordinateSystemUtils::ConvertToInteger(GetLineSpaceF());
4295 }
4296
4297 float
4298 TextObject::GetLineSpaceF(void) const
4299 {
4300         IF_NOT_CONSTRUCTED(return -1);
4301
4302         return __pCompositeText->GetLineSpaceF();
4303 }
4304
4305 int
4306 TextObject::GetTextLength(void) const
4307 {
4308         IF_NOT_CONSTRUCTED(return -1);
4309
4310         return __pCompositeText->GetTextLength();
4311 }
4312
4313 TextObjectAlignment
4314 TextObject::GetElementVerticalAlignment(void) const
4315 {
4316         IF_NOT_CONSTRUCTED(return TEXT_OBJECT_ALIGNMENT_INVALID);
4317
4318         return __pCompositeText->GetElementVerticalAlignment();
4319 }
4320
4321 TextObjectActionType
4322 TextObject::GetAction(void) const
4323 {
4324         IF_NOT_CONSTRUCTED(return TEXT_OBJECT_ACTION_TYPE_NONE);
4325
4326         return __action;
4327 }
4328
4329 TextObjectAlignment
4330 TextObject::GetAlignment(void) const
4331 {
4332         IF_NOT_CONSTRUCTED(return TEXT_OBJECT_ALIGNMENT_INVALID);
4333
4334         return __align;
4335 }
4336
4337 int
4338 TextObject::GetElementCount(void) const
4339 {
4340         IF_NOT_CONSTRUCTED(return -1);
4341
4342         return __pCompositeText->GetElementCount();
4343 }
4344
4345 TextElement*
4346 TextObject::GetElementAtElementIndex(int elementIndex) const
4347 {
4348         IF_NOT_CONSTRUCTED(return null);
4349
4350         return __pCompositeText->GetElementAtElementIndex(elementIndex);
4351 }
4352
4353 result
4354 TextObject::SetRange(int startTextIndex, int textLength)
4355 {
4356         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4357
4358         return __pCompositeText->SetRange(startTextIndex, textLength);
4359 }
4360
4361 void
4362 TextObject::GetRange(int& startTextIndex, int& textLength) const
4363 {
4364         IF_NOT_CONSTRUCTED(return);
4365
4366         return __pCompositeText->GetRange(startTextIndex, textLength);
4367 }
4368
4369 TextObjectWrapType
4370 TextObject::GetWrap(void) const
4371 {
4372         IF_NOT_CONSTRUCTED(return TEXT_OBJECT_WRAP_TYPE_NONE);
4373
4374         return __wrap;
4375 }
4376
4377 result
4378 TextObject::SetCursorIndex(int cursorIndex)
4379 {
4380         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4381
4382         SysTryReturn(NID_GRP, cursorIndex >= 0, E_INVALID_ARG, E_INVALID_ARG
4383                         , "[E_INVALID_ARG] The argument is invalid.");
4384
4385         __pCompositeText->SetCursorIndex(cursorIndex);
4386
4387         return E_SUCCESS;
4388 }
4389
4390 int
4391 TextObject::GetCursorIndex(void) const
4392 {
4393         IF_NOT_CONSTRUCTED(return -1);
4394
4395         return __pCompositeText->GetCursorIndex();
4396 }
4397
4398 result
4399 TextObject::SetBlock(bool enable)
4400 {
4401         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4402
4403         __pCompositeText->SetBlock(enable);
4404
4405         return E_SUCCESS;
4406 }
4407
4408 bool
4409 TextObject::GetBlock(void) const
4410 {
4411         IF_NOT_CONSTRUCTED(return false);
4412
4413         return __pCompositeText->GetBlock();
4414 }
4415
4416 result
4417 TextObject::SetBlockRange(int startTextIndex, int textLength)
4418 {
4419         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4420
4421         result r = E_SUCCESS;
4422         r = __pCompositeText->SetRange(startTextIndex, textLength);
4423         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
4424
4425         return E_SUCCESS;
4426 }
4427
4428 void
4429 TextObject::GetBlockRange(int& startTextIndex, int& textLength)
4430 {
4431         IF_NOT_CONSTRUCTED(return);
4432
4433         __pCompositeText->GetRange(startTextIndex, textLength);
4434 }
4435
4436 bool
4437 TextObject::IsAlternateLookEnabled(void) const
4438 {
4439         IF_NOT_CONSTRUCTED(return false);
4440
4441         return __isAlternateLookEnabled;
4442 }
4443
4444 int
4445 TextObject::GetTotalCutLinkElementCount(void) const
4446 {
4447         IF_NOT_CONSTRUCTED(return -1);
4448
4449         return __pCompositeText->GetCutLinkElementCount();
4450 }
4451
4452 result
4453 TextObject::ChangeCutLinkState(int linkIndex, bool select)
4454 {
4455         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4456
4457         return __pCompositeText->ChangeCutLinkState(linkIndex, select);
4458 }
4459
4460 result
4461 TextObject::ResetAllCutLinkElementsState(void)
4462 {
4463         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4464
4465         return __pCompositeText->ResetAllCutLinkElementsState();
4466 }
4467
4468 bool
4469 TextObject::IsActionOn(void) const
4470 {
4471         IF_NOT_CONSTRUCTED(return false);
4472
4473         return __isActionOn;
4474 }
4475
4476 TextObjectEllipsisType
4477 TextObject::GetTextObjectEllipsisType(void) const
4478 {
4479         IF_NOT_CONSTRUCTED(return TEXT_OBJECT_ELLIPSIS_TYPE_INVALID);
4480
4481         return __textObjectEllipsisType;
4482 }
4483
4484 result
4485 TextObject::ChangeText(int textIndex)
4486 {
4487         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4488
4489         if (__sweepInfo.isValid)
4490         {
4491                 __sweepInfo.isValid = false;
4492                 return E_INVALID_STATE;
4493         }
4494
4495         __sweepInfo.isValid = true;
4496         __sweepInfo.sweepType = TEXT_OBJECT_SWEEP_TYPE_REPLACE;
4497         __sweepInfo.sweepEventType = TEXT_OBJECT_SWEEP_EVENT_INSERT;
4498         __sweepInfo.anchorTextIndex = textIndex;
4499         __sweepInfo.sweepRegionStartLineIndex = GetLineIndexAtTextIndex(textIndex);
4500         __sweepInfo.sweepRegionLineCount = 1;
4501         __sweepInfo.anchorLineIndex = __sweepInfo.sweepRegionStartLineIndex;
4502         __sweepInfo.widthChanged = 0;
4503
4504         __pCompositeText->SetTextSweepInfo(&__sweepInfo);
4505
4506         return E_SUCCESS;
4507 }
4508
4509 result
4510 TextObject::InputText(int textIndex)
4511 {
4512         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4513
4514         if (__sweepInfo.isValid == true)
4515         {
4516                 __sweepInfo.isValid = false;
4517                 return E_INVALID_STATE;
4518         }
4519
4520         __sweepInfo.isValid = true;
4521         __sweepInfo.sweepType = TEXT_OBJECT_SWEEP_TYPE_KEYINPUT;
4522         __sweepInfo.sweepEventType = TEXT_OBJECT_SWEEP_EVENT_INSERT;
4523         __sweepInfo.anchorTextIndex = textIndex;
4524         __sweepInfo.prevAnchorLineIndex = GetLineIndexAtTextIndex(textIndex);
4525
4526         if (__sweepInfo.prevAnchorLineIndex == -1)
4527         {
4528                 __sweepInfo.prevAnchorLineIndex = __pTextColumn->GetTotalLineCount()-1;
4529         }
4530
4531         __pCompositeText->SetTextSweepInfo(&__sweepInfo);
4532
4533         return E_SUCCESS;
4534 }
4535
4536 result
4537 TextObject::RemoveText(int textIndex)
4538 {
4539         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4540
4541         if (__sweepInfo.isValid == true)
4542         {
4543                 __sweepInfo.isValid = false;
4544                 return E_INVALID_STATE;
4545         }
4546
4547         __sweepInfo.isValid = true;
4548         __sweepInfo.sweepEventType = TEXT_OBJECT_SWEEP_EVENT_REMOVE;
4549         __sweepInfo.anchorTextIndex = textIndex;
4550         __sweepInfo.prevAnchorLineIndex = GetLineIndexAtTextIndex(textIndex);
4551
4552         if (__sweepInfo.prevAnchorLineIndex == -1)
4553         {
4554                 __sweepInfo.prevAnchorLineIndex = __pTextColumn->GetTotalLineCount()-1;
4555         }
4556
4557         __pCompositeText->SetTextSweepInfo(&__sweepInfo);
4558
4559         return E_SUCCESS;
4560 }
4561
4562 result
4563 TextObject::ResetSweepInfo(void)
4564 {
4565         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4566
4567         __sweepInfo.isValid = false;
4568
4569         return E_SUCCESS;
4570 }
4571
4572 TextObjectSweepInfo
4573 TextObject::GetSweepInfo(void) const
4574 {
4575         TextObjectSweepInfo textSweepInfo;
4576         textSweepInfo.isValid = false;
4577         textSweepInfo.sweepType = TEXT_OBJECT_SWEEP_TYPE_NONE;
4578         textSweepInfo.sweepEventType = TEXT_OBJECT_SWEEP_EVENT_NONE;
4579         textSweepInfo.anchorTextIndex = -1;
4580         textSweepInfo.anchorLineIndex = -1;
4581         textSweepInfo.prevAnchorLineIndex = -1;
4582         textSweepInfo.sweepRegionStartLineIndex = -1;
4583         textSweepInfo.sweepRegionLineCount = -1;
4584         textSweepInfo.insertedLineCount = -1;
4585         textSweepInfo.deletedLineCount = -1;
4586         textSweepInfo.widthChanged = -1;
4587
4588         IF_NOT_CONSTRUCTED(return textSweepInfo);
4589
4590         textSweepInfo.isValid = __sweepInfo.isValid;
4591         textSweepInfo.sweepType = __sweepInfo.sweepType;
4592         textSweepInfo.sweepEventType = __sweepInfo.sweepEventType;
4593         textSweepInfo.anchorTextIndex = __sweepInfo.anchorTextIndex;
4594         textSweepInfo.anchorLineIndex = __sweepInfo.anchorLineIndex;
4595         textSweepInfo.prevAnchorLineIndex = __sweepInfo.prevAnchorLineIndex;
4596         textSweepInfo.sweepRegionStartLineIndex = __sweepInfo.sweepRegionStartLineIndex;
4597         textSweepInfo.sweepRegionLineCount = __sweepInfo.sweepRegionLineCount;
4598         textSweepInfo.insertedLineCount = __sweepInfo.insertedLineCount;
4599         textSweepInfo.deletedLineCount = __sweepInfo.deletedLineCount;
4600         textSweepInfo.widthChanged = __sweepInfo.widthChanged;
4601
4602         return textSweepInfo;
4603 }
4604
4605 result
4606 TextObject::GetSweepComposeLineInfo(int lineIndex, TextObjectSweepComposeLineInfo& textSweepComposeLineInfo) const
4607 {
4608         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4609
4610         SysTryReturn(NID_GRP, lineIndex >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
4611
4612         TextLine* pTextLine = __pTextColumn->GetTextLine(lineIndex);
4613         SysTryReturn(NID_GRP, pTextLine, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
4614
4615         textSweepComposeLineInfo = pTextLine->GetSweepComposeInfo();
4616
4617         return E_SUCCESS;
4618 }
4619
4620 int
4621 TextObject::GetTextOffsetAtLine(int lineIndex) const
4622 {
4623         IF_NOT_CONSTRUCTED(return -1);
4624
4625         SysTryReturn(NID_GRP, lineIndex >= 0, -1, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
4626
4627         TextLine* pTextLine = __pTextColumn->GetTextLine(lineIndex);
4628         SysTryReturn(NID_GRP, pTextLine, -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
4629
4630         return pTextLine->GetTextOffset();
4631 }
4632
4633 int
4634 TextObject::GetTextLengthAtLine(int lineIndex) const
4635 {
4636         IF_NOT_CONSTRUCTED(return -1);
4637
4638         SysTryReturn(NID_GRP, lineIndex >= 0, -1, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
4639
4640         TextLine* pTextLine = __pTextColumn->GetTextLine(lineIndex);
4641         SysTryReturn(NID_GRP, pTextLine, -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
4642
4643         return pTextLine->GetTextLength();
4644 }
4645
4646 Rectangle
4647 TextObject::GetBoundsAtLine(int lineIndex) const
4648 {
4649         return _CoordinateSystemUtils::ConvertToInteger(GetBoundsAtLineF(lineIndex));
4650 }
4651
4652 FloatRectangle
4653 TextObject::GetBoundsAtLineF(int lineIndex) const
4654 {
4655         IF_NOT_CONSTRUCTED(return FloatRectangle(-1, -1, -1, -1));
4656
4657         SysTryReturn(NID_GRP, lineIndex >= 0, FloatRectangle(-1, -1, -1, -1), E_INVALID_ARG
4658                         , "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
4659
4660         TextLine* pTextLine = __pTextColumn->GetTextLine(lineIndex);
4661         SysTryReturn(NID_GRP, pTextLine, FloatRectangle(-1, -1, -1, -1), E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
4662
4663         FloatRectangle lineBounds = pTextLine->GetBoundsF();
4664
4665         return lineBounds;
4666 }
4667
4668 Point
4669 TextObject::GetDisplayPositionAtLine(int lineIndex, int textIndexFromLineOffset)
4670 {
4671         return _CoordinateSystemUtils::ConvertToInteger(GetDisplayPositionAtLineF(lineIndex, textIndexFromLineOffset));
4672 }
4673
4674 FloatPoint
4675 TextObject::GetDisplayPositionAtLineF(int lineIndex, int textIndexFromLineOffset)
4676 {
4677         IF_NOT_CONSTRUCTED(return FloatPoint(-1.0f, -1.0f));
4678
4679         SysTryReturn(NID_GRP, lineIndex >= 0, FloatPoint(-1.0f, -1.0f), E_INVALID_ARG
4680                         , "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
4681
4682         TextLine* pTextLine = __pTextColumn->GetTextLine(lineIndex);
4683         SysTryReturn(NID_GRP, pTextLine, FloatPoint(-1.0f, -1.0f), E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
4684
4685         int lineOffset = pTextLine->GetTextOffset();
4686         int lineLength = pTextLine->GetTextLength();
4687         FloatDimension lineTextSize;
4688         FloatDimension extentDim;
4689         FloatRectangle lineBounds;
4690         int textCount = 0;
4691
4692         pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
4693         lineBounds = pTextLine->GetBoundsF();
4694
4695         __pCompositeText->ForwardAnalyze(lineOffset, textIndexFromLineOffset, lineTextSize.width, __wrap, textCount, extentDim.width, extentDim.height);
4696
4697         switch (__align & TEXT_ALIGNMASK_HORIZ)
4698         {
4699         case TEXT_OBJECT_ALIGNMENT_LEFT:
4700                 break;
4701
4702         case TEXT_OBJECT_ALIGNMENT_CENTER:
4703                 extentDim.width += (lineBounds.width - lineTextSize.width) / 2.0f;
4704                 break;
4705
4706         case TEXT_OBJECT_ALIGNMENT_RIGHT:
4707                 extentDim.width += (lineBounds.width - lineTextSize.width);
4708                 break;
4709         }
4710
4711         if (extentDim.width < 0.0f)
4712         {
4713                 extentDim.width = 0.0f;
4714         }
4715
4716         return FloatPoint(extentDim.width + __rect.x, lineBounds.y - __pTextColumn->GetFirstDisplayPositionYF() + __rect.y);
4717 }
4718
4719 Tizen::Base::String
4720 TextObject::GetDisplayableText(void)
4721 {
4722         IF_NOT_CONSTRUCTED(return -1);
4723
4724         return __pCompositeText->GetDisplayableText(__rect, __action);
4725 }
4726
4727 bool
4728 TextObject::WordExceedsWidthAt(int lineIndex) const
4729 {
4730         IF_NOT_CONSTRUCTED(return false);
4731
4732         SysTryReturn(NID_GRP, lineIndex >= 0, false, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
4733
4734         TextLine* pTextLine = __pTextColumn->GetTextLine(lineIndex);
4735         SysTryReturn(NID_GRP, pTextLine, false, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
4736
4737         bool hasOneWord = (pTextLine->GetEndType() == TEXT_RETBY_LIMITWIDTH) ? true : false;
4738
4739         return hasOneWord;
4740 }
4741
4742 result
4743 TextObject::SetTextBidiHint(TextBidiHint bidiHint)
4744 {
4745         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4746
4747         switch (bidiHint)
4748         {
4749         case TEXT_BIDI_HINT_NONE:
4750         case TEXT_BIDI_HINT_LTR:
4751         case TEXT_BIDI_HINT_RTL:
4752                 __bidiHint = bidiHint;
4753                 break;
4754         }
4755
4756         return E_SUCCESS;
4757 }
4758
4759 TextBidiHint
4760 TextObject::GetTextBidiHint(void) const
4761 {
4762         IF_NOT_CONSTRUCTED(return TEXT_BIDI_HINT_NONE);
4763
4764         return __bidiHint;
4765 }
4766
4767 result
4768 TextObject::ConvertToRowColumn(int textIndex, int& row, int& column) const
4769 {
4770         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4771
4772         SysTryReturn(NID_GRP, textIndex >= 0 && textIndex <= GetTextLength(), E_INVALID_ARG, E_INVALID_ARG
4773                 , "[E_INVALID_ARG] The argument is invalid. (textIndex = %d)", textIndex);
4774
4775         TextLine* pTextLine = null;
4776         int lineIndex = 0;
4777         int lineOffset = 0;
4778         int lineLength = 0;
4779         int lineCount = GetTotalLineCount();
4780
4781         for (lineIndex = 0; lineIndex < lineCount; lineIndex++)
4782         {
4783                 pTextLine = __pTextColumn->GetTextLine(lineIndex);
4784                 SysTryReturn(NID_GRP, pTextLine, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
4785
4786                 lineOffset = pTextLine->GetTextOffset();
4787                 lineLength = pTextLine->GetTextLength();
4788
4789                 if (lineOffset <= textIndex && textIndex < lineOffset + lineLength)
4790                 {
4791                         break;
4792                 }
4793         }
4794
4795         column = (lineIndex == lineCount) ? lineLength : textIndex - lineOffset;
4796         row = (lineIndex == lineCount) ? lineIndex - 1 : lineIndex;
4797
4798         return E_SUCCESS;
4799 }
4800
4801 int
4802 TextObject::ConvertToTextIndex(int row, int column) const
4803 {
4804         IF_NOT_CONSTRUCTED(return -1);
4805
4806         TextLine* pTextLine = __pTextColumn->GetTextLine(row);
4807         SysTryReturn(NID_GRP, pTextLine, -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
4808
4809         int lineOffset = pTextLine->GetTextOffset();
4810         int lineLength = pTextLine->GetTextLength();
4811
4812         SysTryReturn(NID_GRP, column <= lineLength, -1, E_INVALID_ARG
4813                 , "[E_INVALID_ARG] The argument is invalid. (row = %d, column = %d)", row, column);
4814
4815         SetLastResult(E_SUCCESS);
4816
4817         return lineOffset + column;
4818 }
4819
4820 result
4821 TextObject::SetDisplayBoundsExpandEnabled(bool enable)
4822 {
4823         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4824
4825         __isDisplayBoundsExpandEnabled = enable;
4826
4827         return E_SUCCESS;
4828 }
4829
4830 bool
4831 TextObject::IsDisplayBoundsExpandEnabled(void) const
4832 {
4833         IF_NOT_CONSTRUCTED(return false);
4834
4835         return __isDisplayBoundsExpandEnabled;
4836 }
4837
4838 int
4839 TextObject::GetRepeatCount(void) const
4840 {
4841         IF_NOT_CONSTRUCTED(return -1);
4842
4843         return __repeatCount;
4844 }
4845
4846 }}} // Tizen::Graphics::_Text