b8ac36adbc03865cad18469b6c4f1578675fe419
[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         _FontImpl* pFont = _FontImpl::GetInstance(*__pDefaultFont);
3958         SysTryReturn(NID_GRP, pFont, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get native font instance.");
3959
3960         FloatDimension lineTextSize;
3961         FloatRectangle lineBounds;
3962         lineBounds = pTextLine->GetBoundsF();
3963         pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
3964
3965         if (lineTextSize.height == 0.0f || pTextLine->GetTextLength() == 0.0f)
3966         {
3967                 lineTextSize.height = TextUtility::GetFontMaxHeightF(pFont);
3968         }
3969
3970         switch (__align & TEXT_ALIGNMASK_HORIZ)
3971         {
3972         case TEXT_OBJECT_ALIGNMENT_LEFT:
3973                 break;
3974
3975         case TEXT_OBJECT_ALIGNMENT_CENTER:
3976                 posX += (lineBounds.width - lineTextSize.width) / 2.0f;
3977                 break;
3978
3979         case TEXT_OBJECT_ALIGNMENT_RIGHT:
3980                 posX += (lineBounds.width - lineTextSize.width);
3981                 break;
3982         }
3983
3984         switch (__align & TEXT_ALIGNMASK_VERT)
3985         {
3986         case TEXT_OBJECT_ALIGNMENT_TOP:
3987                 break;
3988
3989         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
3990                 posY += (__rect.height - lineTextSize.height) / 2.0f;
3991                 break;
3992
3993         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
3994                 posY += (__rect.height - lineTextSize.height);
3995                 break;
3996         }
3997
3998         posX = (posX < 0.0f) ? 0.0f : posX;
3999         posY = (posY < 0.0f) ? 0.0f : posY;
4000
4001         FloatRectangle textExtent = pTextLine->GetTextExtentF(column - pTextLine->GetTextOffset(), 1);
4002
4003         if (column >= 1)
4004         {
4005                 Font* pTextFont = __pCompositeText->GetFont(column - 1);
4006                 textExtent.height = TextUtility::GetFontMaxHeightF(pTextFont);
4007         }
4008
4009         if (textExtent.height < 0.0f)
4010         {
4011                 textExtent.height = TextUtility::GetFontMaxHeightF(pFont);
4012         }
4013
4014         TextObjectAlignment alignment = __pCompositeText->GetElementVerticalAlignment();
4015         switch (alignment & TEXT_ALIGNMASK_VERT)
4016         {
4017         case TEXT_OBJECT_ALIGNMENT_TOP:
4018                 // fall through
4019         default:
4020                 break;
4021
4022         case TEXT_OBJECT_ALIGNMENT_MIDDLE:
4023                 posY = posY + (lineBounds.height - textExtent.height) / 2.0f;
4024                 break;
4025
4026         case TEXT_OBJECT_ALIGNMENT_BOTTOM:
4027                 posY = posY + (lineBounds.height - textExtent.height);
4028                 break;
4029         }
4030
4031         absX = posX + textExtent.x - firstDisplayPositionX;
4032         logicalX = (absX >= 0.0f) ? absX + __rect.x : absX;
4033         absY = posY;
4034         logicalY = absY + __rect.y;
4035         width = textExtent.width;
4036         height = textExtent.height;
4037
4038         return E_SUCCESS;
4039 }
4040
4041 int
4042 TextObject::GetTotalComposedHeight(void) const
4043 {
4044         return _CoordinateSystemUtils::ConvertToInteger(GetTotalComposedHeightF());
4045 }
4046
4047 float
4048 TextObject::GetTotalComposedHeightF(void) const
4049 {
4050         return __pCompositeText->GetTotalComposedHeightF();
4051 }
4052
4053 int
4054 TextObject::GetLineWidthAt(int lineIndex) const
4055 {
4056         return _CoordinateSystemUtils::ConvertToInteger(GetLineWidthAtF(lineIndex));
4057 }
4058
4059 float
4060 TextObject::GetLineWidthAtF(int lineIndex) const
4061 {
4062         IF_NOT_CONSTRUCTED(return -1);
4063
4064         result r = E_SUCCESS;
4065         TextLine* pTextLine = null;
4066         FloatDimension lineTextSize;
4067         int lineLength = 0;
4068
4069         pTextLine = __pTextColumn->GetTextLine(lineIndex);
4070         SysTryCatch(NID_GRP, pTextLine, , E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
4071
4072         lineLength = pTextLine->GetTextLength();
4073         r = pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
4074         SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
4075
4076         SetLastResult(E_SUCCESS);
4077         return lineTextSize.width;
4078
4079 CATCH:
4080         return -1;
4081 }
4082
4083 int
4084 TextObject::GetTotalHeight(void) const
4085 {
4086         return _CoordinateSystemUtils::ConvertToInteger(GetTotalHeightF());
4087 }
4088
4089 float
4090 TextObject::GetTotalHeightF(void) const
4091 {
4092         IF_NOT_CONSTRUCTED(return -1);
4093
4094         float height = 0.0f;
4095         if (IsPartialComposingModeEnabled())
4096         {
4097                 height = __pCompositeText->GetAnalysedTotalHeightF();
4098         }
4099         else
4100         {
4101                 height = __pTextColumn->GetTotalHeightF();
4102         }
4103
4104         return height;
4105 }
4106
4107 int
4108 TextObject::GetElementIndexOf(TextElement& textElement) const
4109 {
4110         IF_NOT_CONSTRUCTED(return -1);
4111
4112         return __pCompositeText->GetElementIndexOf(textElement);
4113 }
4114
4115 result
4116 TextObject::RemoveElementAt(int elementIndex, bool deallocate)
4117 {
4118         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4119
4120         return __pCompositeText->RemoveElementAt(elementIndex, deallocate);
4121 }
4122
4123 result
4124 TextObject::HideFrontSpace(TextObjectSpaceHideType mode)
4125 {
4126         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4127
4128         __pCompositeText->HideFrontSpace(mode);
4129
4130         return E_SUCCESS;
4131 }
4132
4133 result
4134 TextObject::HideRearSpace(TextObjectSpaceHideType mode)
4135 {
4136         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4137
4138         __pCompositeText->HideRearSpace(mode);
4139
4140         return E_SUCCESS;
4141 }
4142
4143 int
4144 TextObject::GetSlidingStep(void) const
4145 {
4146         return _CoordinateSystemUtils::ConvertToInteger(GetSlidingStepF());
4147 }
4148
4149 float
4150 TextObject::GetSlidingStepF(void) const
4151 {
4152         IF_NOT_CONSTRUCTED(return -1.0f);
4153
4154         return __slidingStep;
4155 }
4156
4157
4158 result
4159 TextObject::SetSlidingStep(int slidingStep)
4160 {
4161         return SetSlidingStep(_CoordinateSystemUtils::ConvertToFloat(slidingStep));
4162 }
4163
4164 result
4165 TextObject::SetSlidingStep(float slidingStep)
4166 {
4167         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4168
4169         __slidingStep = slidingStep;
4170
4171         return E_SUCCESS;
4172 }
4173
4174 int
4175 TextObject::GetTotalLineCount(void) const
4176 {
4177         IF_NOT_CONSTRUCTED(return -1);
4178
4179         return __pTextColumn->GetTotalLineCount();
4180 }
4181
4182 int
4183 TextObject::GetLineIndexAtTextIndex(int textIndex)  const
4184 {
4185         IF_NOT_CONSTRUCTED(return -1);
4186
4187         return __pTextColumn->GetLineIndexAtTextIndex(textIndex);
4188 }
4189
4190 int
4191 TextObject::GetLineHeightAt(int lineIndex)  const
4192 {
4193         return _CoordinateSystemUtils::ConvertToInteger(GetLineHeightAtF(lineIndex));
4194 }
4195
4196 float
4197 TextObject::GetLineHeightAtF(int lineIndex) const
4198 {
4199         IF_NOT_CONSTRUCTED(return -1);
4200
4201         SysTryReturn(NID_GRP, lineIndex >= 0, -1, E_INVALID_ARG
4202                         , "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
4203
4204         return __pTextColumn->GetLineHeightAtF(lineIndex);
4205 }
4206
4207 int
4208 TextObject::GetDisplayLineCount(void)  const
4209 {
4210         IF_NOT_CONSTRUCTED(return -1);
4211
4212         return __pTextColumn->GetDisplayLineCount();
4213 }
4214
4215 int
4216 TextObject::GetFirstDisplayLineIndex(void) const
4217 {
4218         IF_NOT_CONSTRUCTED(return -1);
4219
4220         return __pTextColumn->GetFirstDisplayLineIndex();
4221 }
4222
4223 int
4224 TextObject::GetFirstDisplayPositionY(void) const
4225 {
4226         return _CoordinateSystemUtils::ConvertToInteger(GetFirstDisplayPositionYF());
4227 }
4228
4229 float
4230 TextObject::GetFirstDisplayPositionYF(void) const
4231 {
4232         IF_NOT_CONSTRUCTED(return -1);
4233
4234         return __pTextColumn->GetFirstDisplayPositionYF();
4235 }
4236
4237 int
4238 TextObject::GetLineIndexAtPositionY(int y) const
4239 {
4240         return GetLineIndexAtPositionY(_CoordinateSystemUtils::ConvertToFloat(y));
4241 }
4242
4243 int
4244 TextObject::GetLineIndexAtPositionY(float y) const
4245 {
4246         IF_NOT_CONSTRUCTED(return -1);
4247
4248         return __pTextColumn->GetLineIndexAtPositionY(y);
4249 }
4250
4251 int
4252 TextObject::GetFirstTextIndexAt(int lineIndex) const
4253 {
4254         IF_NOT_CONSTRUCTED(return -1);
4255
4256         SysTryReturn(NID_GRP, lineIndex >= 0, -1, E_INVALID_ARG
4257                         , "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
4258
4259         return __pTextColumn->GetFirstTextIndexAt(lineIndex);
4260 }
4261
4262 int
4263 TextObject::GetTextLengthAt(int lineIndex) const
4264 {
4265         IF_NOT_CONSTRUCTED(return -1);
4266
4267         SysTryReturn(NID_GRP, lineIndex >= 0, -1, E_INVALID_ARG
4268                         , "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
4269
4270         return __pTextColumn->GetTextLengthAt(lineIndex);
4271 }
4272
4273 Rectangle
4274 TextObject::GetBounds(void) const
4275 {
4276         IF_NOT_CONSTRUCTED(return Rectangle(0, 0, 0, 0));
4277
4278         return _CoordinateSystemUtils::ConvertToInteger(__rect);
4279 }
4280
4281 FloatRectangle
4282 TextObject::GetBoundsF(void) const
4283 {
4284         return __rect;
4285 }
4286
4287 int
4288 TextObject::GetLineSpace(void) const
4289 {
4290         IF_NOT_CONSTRUCTED(return -1);
4291
4292         return _CoordinateSystemUtils::ConvertToInteger(GetLineSpaceF());
4293 }
4294
4295 float
4296 TextObject::GetLineSpaceF(void) const
4297 {
4298         IF_NOT_CONSTRUCTED(return -1);
4299
4300         return __pCompositeText->GetLineSpaceF();
4301 }
4302
4303 int
4304 TextObject::GetTextLength(void) const
4305 {
4306         IF_NOT_CONSTRUCTED(return -1);
4307
4308         return __pCompositeText->GetTextLength();
4309 }
4310
4311 TextObjectAlignment
4312 TextObject::GetElementVerticalAlignment(void) const
4313 {
4314         IF_NOT_CONSTRUCTED(return TEXT_OBJECT_ALIGNMENT_INVALID);
4315
4316         return __pCompositeText->GetElementVerticalAlignment();
4317 }
4318
4319 TextObjectActionType
4320 TextObject::GetAction(void) const
4321 {
4322         IF_NOT_CONSTRUCTED(return TEXT_OBJECT_ACTION_TYPE_NONE);
4323
4324         return __action;
4325 }
4326
4327 TextObjectAlignment
4328 TextObject::GetAlignment(void) const
4329 {
4330         IF_NOT_CONSTRUCTED(return TEXT_OBJECT_ALIGNMENT_INVALID);
4331
4332         return __align;
4333 }
4334
4335 int
4336 TextObject::GetElementCount(void) const
4337 {
4338         IF_NOT_CONSTRUCTED(return -1);
4339
4340         return __pCompositeText->GetElementCount();
4341 }
4342
4343 TextElement*
4344 TextObject::GetElementAtElementIndex(int elementIndex) const
4345 {
4346         IF_NOT_CONSTRUCTED(return null);
4347
4348         return __pCompositeText->GetElementAtElementIndex(elementIndex);
4349 }
4350
4351 result
4352 TextObject::SetRange(int startTextIndex, int textLength)
4353 {
4354         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4355
4356         return __pCompositeText->SetRange(startTextIndex, textLength);
4357 }
4358
4359 void
4360 TextObject::GetRange(int& startTextIndex, int& textLength) const
4361 {
4362         IF_NOT_CONSTRUCTED(return);
4363
4364         return __pCompositeText->GetRange(startTextIndex, textLength);
4365 }
4366
4367 TextObjectWrapType
4368 TextObject::GetWrap(void) const
4369 {
4370         IF_NOT_CONSTRUCTED(return TEXT_OBJECT_WRAP_TYPE_NONE);
4371
4372         return __wrap;
4373 }
4374
4375 result
4376 TextObject::SetCursorIndex(int cursorIndex)
4377 {
4378         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4379
4380         SysTryReturn(NID_GRP, cursorIndex >= 0, E_INVALID_ARG, E_INVALID_ARG
4381                         , "[E_INVALID_ARG] The argument is invalid.");
4382
4383         __pCompositeText->SetCursorIndex(cursorIndex);
4384
4385         return E_SUCCESS;
4386 }
4387
4388 int
4389 TextObject::GetCursorIndex(void) const
4390 {
4391         IF_NOT_CONSTRUCTED(return -1);
4392
4393         return __pCompositeText->GetCursorIndex();
4394 }
4395
4396 result
4397 TextObject::SetBlock(bool enable)
4398 {
4399         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4400
4401         __pCompositeText->SetBlock(enable);
4402
4403         return E_SUCCESS;
4404 }
4405
4406 bool
4407 TextObject::GetBlock(void) const
4408 {
4409         IF_NOT_CONSTRUCTED(return false);
4410
4411         return __pCompositeText->GetBlock();
4412 }
4413
4414 result
4415 TextObject::SetBlockRange(int startTextIndex, int textLength)
4416 {
4417         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4418
4419         result r = E_SUCCESS;
4420         r = __pCompositeText->SetRange(startTextIndex, textLength);
4421         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
4422
4423         return E_SUCCESS;
4424 }
4425
4426 void
4427 TextObject::GetBlockRange(int& startTextIndex, int& textLength)
4428 {
4429         IF_NOT_CONSTRUCTED(return);
4430
4431         __pCompositeText->GetRange(startTextIndex, textLength);
4432 }
4433
4434 bool
4435 TextObject::IsAlternateLookEnabled(void) const
4436 {
4437         IF_NOT_CONSTRUCTED(return false);
4438
4439         return __isAlternateLookEnabled;
4440 }
4441
4442 int
4443 TextObject::GetTotalCutLinkElementCount(void) const
4444 {
4445         IF_NOT_CONSTRUCTED(return -1);
4446
4447         return __pCompositeText->GetCutLinkElementCount();
4448 }
4449
4450 result
4451 TextObject::ChangeCutLinkState(int linkIndex, bool select)
4452 {
4453         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4454
4455         return __pCompositeText->ChangeCutLinkState(linkIndex, select);
4456 }
4457
4458 result
4459 TextObject::ResetAllCutLinkElementsState(void)
4460 {
4461         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4462
4463         return __pCompositeText->ResetAllCutLinkElementsState();
4464 }
4465
4466 bool
4467 TextObject::IsActionOn(void) const
4468 {
4469         IF_NOT_CONSTRUCTED(return false);
4470
4471         return __isActionOn;
4472 }
4473
4474 TextObjectEllipsisType
4475 TextObject::GetTextObjectEllipsisType(void) const
4476 {
4477         IF_NOT_CONSTRUCTED(return TEXT_OBJECT_ELLIPSIS_TYPE_INVALID);
4478
4479         return __textObjectEllipsisType;
4480 }
4481
4482 result
4483 TextObject::ChangeText(int textIndex)
4484 {
4485         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4486
4487         if (__sweepInfo.isValid)
4488         {
4489                 __sweepInfo.isValid = false;
4490                 return E_INVALID_STATE;
4491         }
4492
4493         __sweepInfo.isValid = true;
4494         __sweepInfo.sweepType = TEXT_OBJECT_SWEEP_TYPE_REPLACE;
4495         __sweepInfo.sweepEventType = TEXT_OBJECT_SWEEP_EVENT_INSERT;
4496         __sweepInfo.anchorTextIndex = textIndex;
4497         __sweepInfo.sweepRegionStartLineIndex = GetLineIndexAtTextIndex(textIndex);
4498         __sweepInfo.sweepRegionLineCount = 1;
4499         __sweepInfo.anchorLineIndex = __sweepInfo.sweepRegionStartLineIndex;
4500         __sweepInfo.widthChanged = 0;
4501
4502         __pCompositeText->SetTextSweepInfo(&__sweepInfo);
4503
4504         return E_SUCCESS;
4505 }
4506
4507 result
4508 TextObject::InputText(int textIndex)
4509 {
4510         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4511
4512         if (__sweepInfo.isValid == true)
4513         {
4514                 __sweepInfo.isValid = false;
4515                 return E_INVALID_STATE;
4516         }
4517
4518         __sweepInfo.isValid = true;
4519         __sweepInfo.sweepType = TEXT_OBJECT_SWEEP_TYPE_KEYINPUT;
4520         __sweepInfo.sweepEventType = TEXT_OBJECT_SWEEP_EVENT_INSERT;
4521         __sweepInfo.anchorTextIndex = textIndex;
4522         __sweepInfo.prevAnchorLineIndex = GetLineIndexAtTextIndex(textIndex);
4523
4524         if (__sweepInfo.prevAnchorLineIndex == -1)
4525         {
4526                 __sweepInfo.prevAnchorLineIndex = __pTextColumn->GetTotalLineCount()-1;
4527         }
4528
4529         __pCompositeText->SetTextSweepInfo(&__sweepInfo);
4530
4531         return E_SUCCESS;
4532 }
4533
4534 result
4535 TextObject::RemoveText(int textIndex)
4536 {
4537         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4538
4539         if (__sweepInfo.isValid == true)
4540         {
4541                 __sweepInfo.isValid = false;
4542                 return E_INVALID_STATE;
4543         }
4544
4545         __sweepInfo.isValid = true;
4546         __sweepInfo.sweepEventType = TEXT_OBJECT_SWEEP_EVENT_REMOVE;
4547         __sweepInfo.anchorTextIndex = textIndex;
4548         __sweepInfo.prevAnchorLineIndex = GetLineIndexAtTextIndex(textIndex);
4549
4550         if (__sweepInfo.prevAnchorLineIndex == -1)
4551         {
4552                 __sweepInfo.prevAnchorLineIndex = __pTextColumn->GetTotalLineCount()-1;
4553         }
4554
4555         __pCompositeText->SetTextSweepInfo(&__sweepInfo);
4556
4557         return E_SUCCESS;
4558 }
4559
4560 result
4561 TextObject::ResetSweepInfo(void)
4562 {
4563         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4564
4565         __sweepInfo.isValid = false;
4566
4567         return E_SUCCESS;
4568 }
4569
4570 TextObjectSweepInfo
4571 TextObject::GetSweepInfo(void) const
4572 {
4573         TextObjectSweepInfo textSweepInfo;
4574         textSweepInfo.isValid = false;
4575         textSweepInfo.sweepType = TEXT_OBJECT_SWEEP_TYPE_NONE;
4576         textSweepInfo.sweepEventType = TEXT_OBJECT_SWEEP_EVENT_NONE;
4577         textSweepInfo.anchorTextIndex = -1;
4578         textSweepInfo.anchorLineIndex = -1;
4579         textSweepInfo.prevAnchorLineIndex = -1;
4580         textSweepInfo.sweepRegionStartLineIndex = -1;
4581         textSweepInfo.sweepRegionLineCount = -1;
4582         textSweepInfo.insertedLineCount = -1;
4583         textSweepInfo.deletedLineCount = -1;
4584         textSweepInfo.widthChanged = -1;
4585
4586         IF_NOT_CONSTRUCTED(return textSweepInfo);
4587
4588         textSweepInfo.isValid = __sweepInfo.isValid;
4589         textSweepInfo.sweepType = __sweepInfo.sweepType;
4590         textSweepInfo.sweepEventType = __sweepInfo.sweepEventType;
4591         textSweepInfo.anchorTextIndex = __sweepInfo.anchorTextIndex;
4592         textSweepInfo.anchorLineIndex = __sweepInfo.anchorLineIndex;
4593         textSweepInfo.prevAnchorLineIndex = __sweepInfo.prevAnchorLineIndex;
4594         textSweepInfo.sweepRegionStartLineIndex = __sweepInfo.sweepRegionStartLineIndex;
4595         textSweepInfo.sweepRegionLineCount = __sweepInfo.sweepRegionLineCount;
4596         textSweepInfo.insertedLineCount = __sweepInfo.insertedLineCount;
4597         textSweepInfo.deletedLineCount = __sweepInfo.deletedLineCount;
4598         textSweepInfo.widthChanged = __sweepInfo.widthChanged;
4599
4600         return textSweepInfo;
4601 }
4602
4603 result
4604 TextObject::GetSweepComposeLineInfo(int lineIndex, TextObjectSweepComposeLineInfo& textSweepComposeLineInfo) const
4605 {
4606         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4607
4608         SysTryReturn(NID_GRP, lineIndex >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
4609
4610         TextLine* pTextLine = __pTextColumn->GetTextLine(lineIndex);
4611         SysTryReturn(NID_GRP, pTextLine, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
4612
4613         textSweepComposeLineInfo = pTextLine->GetSweepComposeInfo();
4614
4615         return E_SUCCESS;
4616 }
4617
4618 int
4619 TextObject::GetTextOffsetAtLine(int lineIndex) const
4620 {
4621         IF_NOT_CONSTRUCTED(return -1);
4622
4623         SysTryReturn(NID_GRP, lineIndex >= 0, -1, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
4624
4625         TextLine* pTextLine = __pTextColumn->GetTextLine(lineIndex);
4626         SysTryReturn(NID_GRP, pTextLine, -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
4627
4628         return pTextLine->GetTextOffset();
4629 }
4630
4631 int
4632 TextObject::GetTextLengthAtLine(int lineIndex) const
4633 {
4634         IF_NOT_CONSTRUCTED(return -1);
4635
4636         SysTryReturn(NID_GRP, lineIndex >= 0, -1, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
4637
4638         TextLine* pTextLine = __pTextColumn->GetTextLine(lineIndex);
4639         SysTryReturn(NID_GRP, pTextLine, -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
4640
4641         return pTextLine->GetTextLength();
4642 }
4643
4644 Rectangle
4645 TextObject::GetBoundsAtLine(int lineIndex) const
4646 {
4647         return _CoordinateSystemUtils::ConvertToInteger(GetBoundsAtLineF(lineIndex));
4648 }
4649
4650 FloatRectangle
4651 TextObject::GetBoundsAtLineF(int lineIndex) const
4652 {
4653         IF_NOT_CONSTRUCTED(return FloatRectangle(-1, -1, -1, -1));
4654
4655         SysTryReturn(NID_GRP, lineIndex >= 0, FloatRectangle(-1, -1, -1, -1), E_INVALID_ARG
4656                         , "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
4657
4658         TextLine* pTextLine = __pTextColumn->GetTextLine(lineIndex);
4659         SysTryReturn(NID_GRP, pTextLine, FloatRectangle(-1, -1, -1, -1), E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
4660
4661         FloatRectangle lineBounds = pTextLine->GetBoundsF();
4662
4663         return lineBounds;
4664 }
4665
4666 Point
4667 TextObject::GetDisplayPositionAtLine(int lineIndex, int textIndexFromLineOffset)
4668 {
4669         return _CoordinateSystemUtils::ConvertToInteger(GetDisplayPositionAtLineF(lineIndex, textIndexFromLineOffset));
4670 }
4671
4672 FloatPoint
4673 TextObject::GetDisplayPositionAtLineF(int lineIndex, int textIndexFromLineOffset)
4674 {
4675         IF_NOT_CONSTRUCTED(return FloatPoint(-1.0f, -1.0f));
4676
4677         SysTryReturn(NID_GRP, lineIndex >= 0, FloatPoint(-1.0f, -1.0f), E_INVALID_ARG
4678                         , "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
4679
4680         TextLine* pTextLine = __pTextColumn->GetTextLine(lineIndex);
4681         SysTryReturn(NID_GRP, pTextLine, FloatPoint(-1.0f, -1.0f), E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
4682
4683         int lineOffset = pTextLine->GetTextOffset();
4684         int lineLength = pTextLine->GetTextLength();
4685         FloatDimension lineTextSize;
4686         FloatDimension extentDim;
4687         FloatRectangle lineBounds;
4688         int textCount = 0;
4689
4690         pTextLine->GetRegion(0, lineLength, lineTextSize.width, lineTextSize.height);
4691         lineBounds = pTextLine->GetBoundsF();
4692
4693         __pCompositeText->ForwardAnalyze(lineOffset, textIndexFromLineOffset, lineTextSize.width, __wrap, textCount, extentDim.width, extentDim.height);
4694
4695         switch (__align & TEXT_ALIGNMASK_HORIZ)
4696         {
4697         case TEXT_OBJECT_ALIGNMENT_LEFT:
4698                 break;
4699
4700         case TEXT_OBJECT_ALIGNMENT_CENTER:
4701                 extentDim.width += (lineBounds.width - lineTextSize.width) / 2.0f;
4702                 break;
4703
4704         case TEXT_OBJECT_ALIGNMENT_RIGHT:
4705                 extentDim.width += (lineBounds.width - lineTextSize.width);
4706                 break;
4707         }
4708
4709         if (extentDim.width < 0.0f)
4710         {
4711                 extentDim.width = 0.0f;
4712         }
4713
4714         return FloatPoint(extentDim.width + __rect.x, lineBounds.y - __pTextColumn->GetFirstDisplayPositionYF() + __rect.y);
4715 }
4716
4717 Tizen::Base::String
4718 TextObject::GetDisplayableText(void)
4719 {
4720         IF_NOT_CONSTRUCTED(return -1);
4721
4722         return __pCompositeText->GetDisplayableText(__rect, __action);
4723 }
4724
4725 bool
4726 TextObject::WordExceedsWidthAt(int lineIndex) const
4727 {
4728         IF_NOT_CONSTRUCTED(return false);
4729
4730         SysTryReturn(NID_GRP, lineIndex >= 0, false, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid. (lineIndex = %d)", lineIndex);
4731
4732         TextLine* pTextLine = __pTextColumn->GetTextLine(lineIndex);
4733         SysTryReturn(NID_GRP, pTextLine, false, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
4734
4735         bool hasOneWord = (pTextLine->GetEndType() == TEXT_RETBY_LIMITWIDTH) ? true : false;
4736
4737         return hasOneWord;
4738 }
4739
4740 result
4741 TextObject::SetTextBidiHint(TextBidiHint bidiHint)
4742 {
4743         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4744
4745         switch (bidiHint)
4746         {
4747         case TEXT_BIDI_HINT_NONE:
4748         case TEXT_BIDI_HINT_LTR:
4749         case TEXT_BIDI_HINT_RTL:
4750                 __bidiHint = bidiHint;
4751                 break;
4752         }
4753
4754         return E_SUCCESS;
4755 }
4756
4757 TextBidiHint
4758 TextObject::GetTextBidiHint(void) const
4759 {
4760         IF_NOT_CONSTRUCTED(return TEXT_BIDI_HINT_NONE);
4761
4762         return __bidiHint;
4763 }
4764
4765 result
4766 TextObject::ConvertToRowColumn(int textIndex, int& row, int& column) const
4767 {
4768         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4769
4770         SysTryReturn(NID_GRP, textIndex >= 0 && textIndex <= GetTextLength(), E_INVALID_ARG, E_INVALID_ARG
4771                 , "[E_INVALID_ARG] The argument is invalid. (textIndex = %d)", textIndex);
4772
4773         TextLine* pTextLine = null;
4774         int lineIndex = 0;
4775         int lineOffset = 0;
4776         int lineLength = 0;
4777         int lineCount = GetTotalLineCount();
4778
4779         for (lineIndex = 0; lineIndex < lineCount; lineIndex++)
4780         {
4781                 pTextLine = __pTextColumn->GetTextLine(lineIndex);
4782                 SysTryReturn(NID_GRP, pTextLine, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
4783
4784                 lineOffset = pTextLine->GetTextOffset();
4785                 lineLength = pTextLine->GetTextLength();
4786
4787                 if (lineOffset <= textIndex && textIndex < lineOffset + lineLength)
4788                 {
4789                         break;
4790                 }
4791         }
4792
4793         column = (lineIndex == lineCount) ? lineLength : textIndex - lineOffset;
4794         row = (lineIndex == lineCount) ? lineIndex - 1 : lineIndex;
4795
4796         return E_SUCCESS;
4797 }
4798
4799 int
4800 TextObject::ConvertToTextIndex(int row, int column) const
4801 {
4802         IF_NOT_CONSTRUCTED(return -1);
4803
4804         TextLine* pTextLine = __pTextColumn->GetTextLine(row);
4805         SysTryReturn(NID_GRP, pTextLine, -1, E_SYSTEM, "[E_SYSTEM] Fail to get text line.");
4806
4807         int lineOffset = pTextLine->GetTextOffset();
4808         int lineLength = pTextLine->GetTextLength();
4809
4810         SysTryReturn(NID_GRP, column <= lineLength, -1, E_INVALID_ARG
4811                 , "[E_INVALID_ARG] The argument is invalid. (row = %d, column = %d)", row, column);
4812
4813         SetLastResult(E_SUCCESS);
4814
4815         return lineOffset + column;
4816 }
4817
4818 result
4819 TextObject::SetDisplayBoundsExpandEnabled(bool enable)
4820 {
4821         IF_NOT_CONSTRUCTED(return E_INVALID_STATE);
4822
4823         __isDisplayBoundsExpandEnabled = enable;
4824
4825         return E_SUCCESS;
4826 }
4827
4828 bool
4829 TextObject::IsDisplayBoundsExpandEnabled(void) const
4830 {
4831         IF_NOT_CONSTRUCTED(return false);
4832
4833         return __isDisplayBoundsExpandEnabled;
4834 }
4835
4836 int
4837 TextObject::GetRepeatCount(void) const
4838 {
4839         IF_NOT_CONSTRUCTED(return -1);
4840
4841         return __repeatCount;
4842 }
4843
4844 }}} // Tizen::Graphics::_Text