Merge "Fixed Cache for AnimatedVectorImageVisual" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / controller / text-controller.cpp
1 /*
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-toolkit/internal/text/controller/text-controller.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
23 #include <dali/devel-api/adaptor-framework/window-devel.h>
24 #include <dali/integration-api/debug.h>
25 #include <memory.h>
26 #include <cmath>
27 #include <limits>
28
29 // INTERNAL INCLUDES
30 #include <dali-toolkit/devel-api/text/text-enumerations-devel.h>
31 #include <dali-toolkit/internal/text/controller/text-controller-background-actor.h>
32 #include <dali-toolkit/internal/text/controller/text-controller-event-handler.h>
33 #include <dali-toolkit/internal/text/controller/text-controller-impl.h>
34 #include <dali-toolkit/internal/text/controller/text-controller-input-font-handler.h>
35 #include <dali-toolkit/internal/text/controller/text-controller-input-properties.h>
36 #include <dali-toolkit/internal/text/controller/text-controller-placeholder-handler.h>
37 #include <dali-toolkit/internal/text/controller/text-controller-relayouter.h>
38 #include <dali-toolkit/internal/text/controller/text-controller-spannable-handler.h>
39 #include <dali-toolkit/internal/text/controller/text-controller-text-updater.h>
40 #include <dali-toolkit/internal/text/text-editable-control-interface.h>
41 #include <dali-toolkit/internal/text/text-geometry.h>
42 namespace
43 {
44 #if defined(DEBUG_ENABLED)
45 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS");
46 #endif
47
48 const char* EMPTY_STRING = "";
49 const char* MIME_TYPE_TEXT_PLAIN = "text/plain;charset=utf-8";
50
51 template<typename Type>
52 void EnsureCreated(Type*& object)
53 {
54   if(!object)
55   {
56     object = new Type();
57   }
58 }
59
60 template<typename Type>
61 void EnsureCreated(std::unique_ptr<Type>& object)
62 {
63   if(!object)
64   {
65     object = std::unique_ptr<Type>(new Type());
66   }
67 }
68
69 template<typename Type, typename Arg1>
70 void EnsureCreated(Type*& object, Arg1 arg1)
71 {
72   if(!object)
73   {
74     object = new Type(arg1);
75   }
76 }
77
78 template<typename Type, typename Arg1, typename Arg2>
79 void EnsureCreated(Type*& object, Arg1 arg1, Arg2 arg2)
80 {
81   if(!object)
82   {
83     object = new Type(arg1, arg2);
84   }
85 }
86
87 float GetDpi()
88 {
89   static uint32_t horizontalDpi = 0u;
90   static uint32_t verticalDpi   = 0u;
91
92   // TODO : How can we know when fontClient DPI changed case?
93   if(DALI_UNLIKELY(horizontalDpi == 0u))
94   {
95     Dali::TextAbstraction::FontClient fontClient = Dali::TextAbstraction::FontClient::Get();
96     fontClient.GetDpi(horizontalDpi, verticalDpi);
97   }
98   return static_cast<float>(horizontalDpi);
99 }
100
101 float ConvertPixelToPoint(float pixel)
102 {
103   return pixel * 72.0f / GetDpi();
104 }
105
106 float ConvertPointToPixel(float point)
107 {
108   // Pixel size = Point size * DPI / 72.f
109   return point * GetDpi() / 72.0f;
110 }
111
112 void UpdateCursorPosition(Dali::Toolkit::Text::EventData* eventData)
113 {
114   if(eventData && Dali::Toolkit::Text::EventData::IsEditingState(eventData->mState))
115   {
116     // Update the cursor position if it's in editing mode
117     eventData->mDecoratorUpdated     = true;
118     eventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font size is updated.
119   }
120 }
121
122 } // namespace
123
124 namespace Dali::Toolkit::Text
125 {
126 void Controller::EnableTextInput(DecoratorPtr decorator, InputMethodContext& inputMethodContext)
127 {
128   if(!decorator)
129   {
130     delete mImpl->mEventData;
131     mImpl->mEventData = NULL;
132
133     // Nothing else to do.
134     return;
135   }
136
137   EnsureCreated(mImpl->mEventData, decorator, inputMethodContext);
138 }
139
140 void Controller::SetGlyphType(TextAbstraction::GlyphType glyphType)
141 {
142   // Metrics for bitmap & vector based glyphs are different
143   mImpl->mMetrics->SetGlyphType(glyphType);
144
145   // Clear the font-specific data
146   mImpl->ClearFontData();
147
148   mImpl->RequestRelayout();
149 }
150
151 void Controller::SetMarkupProcessorEnabled(bool enable)
152 {
153   if(enable != mImpl->mMarkupProcessorEnabled)
154   {
155     //If Text was already set, call the SetText again for enabling or disabling markup
156     mImpl->mMarkupProcessorEnabled = enable;
157     std::string text;
158     GetText(text);
159     SetText(text);
160   }
161
162   mImpl->mModel->mVisualModel->SetMarkupProcessorEnabled(enable);
163 }
164
165 bool Controller::IsMarkupProcessorEnabled() const
166 {
167   return mImpl->mMarkupProcessorEnabled;
168 }
169
170 bool Controller::HasAnchors() const
171 {
172   return (mImpl->mMarkupProcessorEnabled && mImpl->mModel->mLogicalModel->mAnchors.Count() && mImpl->IsShowingRealText());
173 }
174
175 void Controller::SetAutoScrollEnabled(bool enable)
176 {
177   DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled[%s] SingleBox[%s]-> [%p]\n", (enable) ? "true" : "false", (mImpl->mLayoutEngine.GetLayout() == Layout::Engine::SINGLE_LINE_BOX) ? "true" : "false", this);
178   mImpl->SetAutoScrollEnabled(enable);
179 }
180
181 void Controller::SetAutoScrollMaxTextureExceeded(bool exceed)
182 {
183   mImpl->mIsAutoScrollMaxTextureExceeded = exceed;
184 }
185
186 bool Controller::IsAutoScrollEnabled() const
187 {
188   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::IsAutoScrollEnabled[%s]\n", mImpl->mIsAutoScrollEnabled ? "true" : "false");
189   return mImpl->mIsAutoScrollEnabled;
190 }
191
192 CharacterDirection Controller::GetAutoScrollDirection() const
193 {
194   return mImpl->mIsTextDirectionRTL;
195 }
196
197 float Controller::GetAutoScrollLineAlignment() const
198 {
199   float offset = 0.f;
200   if(mImpl->mModel->mVisualModel && (0u != mImpl->mModel->mVisualModel->mLines.Count()))
201   {
202     offset = (*mImpl->mModel->mVisualModel->mLines.Begin()).alignmentOffset;
203   }
204   return offset;
205 }
206
207 void Controller::SetHorizontalScrollEnabled(bool enable)
208 {
209   if(mImpl->mEventData && mImpl->mEventData->mDecorator)
210   {
211     mImpl->mEventData->mDecorator->SetHorizontalScrollEnabled(enable);
212   }
213 }
214
215 bool Controller::IsHorizontalScrollEnabled() const
216 {
217   return mImpl->mEventData && mImpl->mEventData->mDecorator && mImpl->mEventData->mDecorator->IsHorizontalScrollEnabled();
218 }
219
220 void Controller::SetVerticalScrollEnabled(bool enable)
221 {
222   if(mImpl->mEventData && mImpl->mEventData->mDecorator)
223   {
224     mImpl->mEventData->mDecorator->SetVerticalScrollEnabled(enable);
225   }
226 }
227
228 bool Controller::IsVerticalScrollEnabled() const
229 {
230   return mImpl->mEventData && mImpl->mEventData->mDecorator && mImpl->mEventData->mDecorator->IsVerticalScrollEnabled();
231 }
232
233 void Controller::SetSmoothHandlePanEnabled(bool enable)
234 {
235   if(mImpl->mEventData && mImpl->mEventData->mDecorator)
236   {
237     mImpl->mEventData->mDecorator->SetSmoothHandlePanEnabled(enable);
238   }
239 }
240
241 bool Controller::IsSmoothHandlePanEnabled() const
242 {
243   return mImpl->mEventData && mImpl->mEventData->mDecorator && mImpl->mEventData->mDecorator->IsSmoothHandlePanEnabled();
244 }
245
246 void Controller::SetMaximumNumberOfCharacters(Length maxCharacters)
247 {
248   mImpl->mMaximumNumberOfCharacters = maxCharacters;
249 }
250
251 int Controller::GetMaximumNumberOfCharacters()
252 {
253   return mImpl->mMaximumNumberOfCharacters;
254 }
255
256 void Controller::SetEnableCursorBlink(bool enable)
257 {
258   mImpl->SetEnableCursorBlink(enable);
259 }
260
261 bool Controller::GetEnableCursorBlink() const
262 {
263   return mImpl->mEventData && mImpl->mEventData->mCursorBlinkEnabled;
264 }
265
266 void Controller::SetMultiLineEnabled(bool enable)
267 {
268   mImpl->SetMultiLineEnabled(enable);
269 }
270
271 bool Controller::IsMultiLineEnabled() const
272 {
273   return Layout::Engine::MULTI_LINE_BOX == mImpl->mLayoutEngine.GetLayout();
274 }
275
276 void Controller::SetHorizontalAlignment(Text::HorizontalAlignment::Type alignment)
277 {
278   mImpl->SetHorizontalAlignment(alignment);
279 }
280
281 Text::HorizontalAlignment::Type Controller::GetHorizontalAlignment() const
282 {
283   return mImpl->mModel->mHorizontalAlignment;
284 }
285
286 void Controller::SetVerticalAlignment(VerticalAlignment::Type alignment)
287 {
288   mImpl->SetVerticalAlignment(alignment);
289 }
290
291 VerticalAlignment::Type Controller::GetVerticalAlignment() const
292 {
293   return mImpl->mModel->mVerticalAlignment;
294 }
295
296 bool Controller::IsIgnoreSpacesAfterText() const
297 {
298   return mImpl->mModel->mIgnoreSpacesAfterText;
299 }
300
301 void Controller::SetIgnoreSpacesAfterText(bool ignore)
302 {
303   mImpl->mModel->mIgnoreSpacesAfterText = ignore;
304 }
305
306 void Controller::ChangedLayoutDirection()
307 {
308   mImpl->mIsLayoutDirectionChanged = true;
309 }
310
311 void Controller::ResetFontAndStyleData()
312 {
313   mImpl->ResetFontAndStyleData();
314 }
315
316 void Controller::SetMatchLayoutDirection(DevelText::MatchLayoutDirection type)
317 {
318   mImpl->mModel->mMatchLayoutDirection = type;
319 }
320
321 DevelText::MatchLayoutDirection Controller::GetMatchLayoutDirection() const
322 {
323   return mImpl->mModel->mMatchLayoutDirection;
324 }
325
326 void Controller::SetLayoutDirection(Dali::LayoutDirection::Type layoutDirection)
327 {
328   mImpl->mLayoutDirection = layoutDirection;
329 }
330
331 Dali::LayoutDirection::Type Controller::GetLayoutDirection(Dali::Actor& actor) const
332 {
333   return mImpl->GetLayoutDirection(actor);
334 }
335
336 bool Controller::IsShowingRealText() const
337 {
338   return mImpl->IsShowingRealText();
339 }
340
341 void Controller::SetLineWrapMode(Text::LineWrap::Mode lineWrapMode)
342 {
343   mImpl->SetLineWrapMode(lineWrapMode);
344 }
345
346 Text::LineWrap::Mode Controller::GetLineWrapMode() const
347 {
348   return mImpl->mModel->mLineWrapMode;
349 }
350
351 void Controller::SetTextElideEnabled(bool enabled)
352 {
353   mImpl->mModel->mElideEnabled = enabled;
354   mImpl->mModel->mVisualModel->SetTextElideEnabled(enabled);
355 }
356
357 bool Controller::IsTextElideEnabled() const
358 {
359   return mImpl->mModel->mElideEnabled;
360 }
361
362 void Controller::SetTextFitEnabled(bool enabled)
363 {
364   mImpl->mTextFitEnabled = enabled;
365 }
366
367 bool Controller::IsTextFitEnabled() const
368 {
369   return mImpl->mTextFitEnabled;
370 }
371
372 void Controller::SetTextFitChanged(bool changed)
373 {
374   mImpl->mTextFitChanged = changed;
375 }
376
377 bool Controller::IsTextFitChanged() const
378 {
379   return mImpl->mTextFitChanged;
380 }
381
382 void Controller::SetCurrentLineSize(float lineSize)
383 {
384   mImpl->mCurrentLineSize = lineSize;
385 }
386
387 float Controller::GetCurrentLineSize() const
388 {
389   return mImpl->mCurrentLineSize;
390 }
391
392 void Controller::SetTextFitMinSize(float minSize, FontSizeType type)
393 {
394   mImpl->mTextFitMinSize = (type == POINT_SIZE) ? minSize : ConvertPixelToPoint(minSize);
395 }
396
397 float Controller::GetTextFitMinSize() const
398 {
399   return mImpl->mTextFitMinSize;
400 }
401
402 void Controller::SetTextFitMaxSize(float maxSize, FontSizeType type)
403 {
404   mImpl->mTextFitMaxSize = (type == POINT_SIZE) ? maxSize : ConvertPixelToPoint(maxSize);
405 }
406
407 float Controller::GetTextFitMaxSize() const
408 {
409   return mImpl->mTextFitMaxSize;
410 }
411
412 void Controller::SetTextFitStepSize(float step, FontSizeType type)
413 {
414   mImpl->mTextFitStepSize = (type == POINT_SIZE) ? step : ConvertPixelToPoint(step);
415 }
416
417 float Controller::GetTextFitStepSize() const
418 {
419   return mImpl->mTextFitStepSize;
420 }
421
422 void Controller::SetTextFitContentSize(Vector2 size)
423 {
424   mImpl->mTextFitContentSize = size;
425 }
426
427 Vector2 Controller::GetTextFitContentSize() const
428 {
429   return mImpl->mTextFitContentSize;
430 }
431
432 float Controller::GetTextFitPointSize() const
433 {
434   return mImpl->mFontDefaults ? mImpl->mFontDefaults->mFitPointSize : 0.0f;
435 }
436
437 void Controller::SetTextFitLineSize(float lineSize)
438 {
439   mImpl->mTextFitLineSize = lineSize;
440 }
441
442 void Controller::SetTextFitArrayEnabled(bool enabled)
443 {
444   mImpl->mTextFitArrayEnabled = enabled;
445   mImpl->ClearFontData();
446   mImpl->RequestRelayout();
447 }
448
449 bool Controller::IsTextFitArrayEnabled() const
450 {
451   return mImpl->mTextFitArrayEnabled;
452 }
453
454 void Controller::SetTextFitArray(std::vector<Toolkit::DevelTextLabel::FitOption>& fitOptions)
455 {
456   mImpl->mTextFitArray = fitOptions;
457 }
458
459 std::vector<Toolkit::DevelTextLabel::FitOption>& Controller::GetTextFitArray()
460 {
461   return mImpl->mTextFitArray;
462 }
463
464 void Controller::SetPlaceholderTextElideEnabled(bool enabled)
465 {
466   PlaceholderHandler::SetPlaceholderTextElideEnabled(*this, enabled);
467 }
468
469 bool Controller::IsPlaceholderTextElideEnabled() const
470 {
471   return PlaceholderHandler::IsPlaceholderTextElideEnabled(*this);
472 }
473
474 void Controller::SetSelectionEnabled(bool enabled)
475 {
476   mImpl->mEventData->mSelectionEnabled = enabled;
477 }
478
479 bool Controller::IsSelectionEnabled() const
480 {
481   return mImpl->mEventData->mSelectionEnabled;
482 }
483
484 void Controller::SetShiftSelectionEnabled(bool enabled)
485 {
486   mImpl->mEventData->mShiftSelectionFlag = enabled;
487 }
488
489 bool Controller::IsShiftSelectionEnabled() const
490 {
491   return mImpl->mEventData->mShiftSelectionFlag;
492 }
493
494 void Controller::SetGrabHandleEnabled(bool enabled)
495 {
496   mImpl->mEventData->mGrabHandleEnabled = enabled;
497 }
498
499 bool Controller::IsGrabHandleEnabled() const
500 {
501   return mImpl->mEventData->mGrabHandleEnabled;
502 }
503
504 void Controller::SetGrabHandlePopupEnabled(bool enabled)
505 {
506   mImpl->mEventData->mGrabHandlePopupEnabled = enabled;
507 }
508
509 bool Controller::IsGrabHandlePopupEnabled() const
510 {
511   return mImpl->mEventData->mGrabHandlePopupEnabled;
512 }
513
514 void Controller::SetText(const std::string& text)
515 {
516   TextUpdater::SetText(*this, text);
517 }
518
519 void Controller::GetText(std::string& text) const
520 {
521   mImpl->GetText(text);
522 }
523
524 Length Controller::GetNumberOfCharacters() const
525 {
526   return mImpl->GetNumberOfCharacters();
527 }
528
529 void Controller::SetSpannedText(const Text::Spanned& spannedText)
530 {
531   SpannableHandler::SetSpannedText(*this, spannedText);
532 }
533
534 void Controller::SetPlaceholderText(PlaceholderType type, const std::string& text)
535 {
536   PlaceholderHandler::SetPlaceholderText(*this, type, text);
537 }
538
539 void Controller::GetPlaceholderText(PlaceholderType type, std::string& text) const
540 {
541   PlaceholderHandler::GetPlaceholderText(*this, type, text);
542 }
543
544 void Controller::UpdateAfterFontChange(const std::string& newDefaultFont)
545 {
546   mImpl->UpdateAfterFontChange(newDefaultFont);
547 }
548
549 void Controller::RetrieveSelection(std::string& selectedText) const
550 {
551   mImpl->RetrieveSelection(selectedText, false);
552 }
553
554 void Controller::SetSelection(int start, int end)
555 {
556   mImpl->SetSelection(start, end);
557 }
558
559 std::pair<int, int> Controller::GetSelectionIndexes() const
560 {
561   return mImpl->GetSelectionIndexes();
562 }
563
564 void Controller::CopyStringToClipboard(const std::string& source)
565 {
566   mImpl->CopyStringToClipboard(source);
567 }
568
569 void Controller::SendSelectionToClipboard(bool deleteAfterSending)
570 {
571   mImpl->SendSelectionToClipboard(deleteAfterSending);
572 }
573
574 void Controller::SetDefaultFontFamily(const std::string& defaultFontFamily)
575 {
576   EnsureCreated(mImpl->mFontDefaults);
577
578   if(mImpl->mFontDefaults->mFontDescription.family != defaultFontFamily)
579   {
580     mImpl->mFontDefaults->mFontDescription.family = defaultFontFamily;
581     DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetDefaultFontFamily %s\n", defaultFontFamily.c_str());
582     mImpl->mFontDefaults->familyDefined = !defaultFontFamily.empty();
583
584     // Update the cursor position if it's in editing mode
585     UpdateCursorPosition(mImpl->mEventData);
586
587     // Clear the font-specific data
588     mImpl->ClearFontData();
589
590     mImpl->RequestRelayout();
591   }
592 }
593
594 std::string Controller::GetDefaultFontFamily() const
595 {
596   return mImpl->mFontDefaults ? mImpl->mFontDefaults->mFontDescription.family : EMPTY_STRING;
597 }
598
599 void Controller::SetPlaceholderFontFamily(const std::string& placeholderTextFontFamily)
600 {
601   PlaceholderHandler::SetPlaceholderFontFamily(*this, placeholderTextFontFamily);
602 }
603
604 std::string Controller::GetPlaceholderFontFamily() const
605 {
606   return PlaceholderHandler::GetPlaceholderFontFamily(*this);
607 }
608
609 void Controller::SetDefaultFontWeight(FontWeight weight)
610 {
611   EnsureCreated(mImpl->mFontDefaults);
612
613   mImpl->mFontDefaults->mFontDescription.weight = weight;
614   mImpl->mFontDefaults->weightDefined           = true;
615
616   // Update the cursor position if it's in editing mode
617   UpdateCursorPosition(mImpl->mEventData);
618
619   // Clear the font-specific data
620   mImpl->ClearFontData();
621
622   mImpl->RequestRelayout();
623 }
624
625 bool Controller::IsDefaultFontWeightDefined() const
626 {
627   return mImpl->mFontDefaults && mImpl->mFontDefaults->weightDefined;
628 }
629
630 FontWeight Controller::GetDefaultFontWeight() const
631 {
632   return mImpl->mFontDefaults ? mImpl->mFontDefaults->mFontDescription.weight : TextAbstraction::FontWeight::NORMAL;
633 }
634
635 void Controller::SetPlaceholderTextFontWeight(FontWeight weight)
636 {
637   PlaceholderHandler::SetPlaceholderTextFontWeight(*this, weight);
638 }
639
640 bool Controller::IsPlaceholderTextFontWeightDefined() const
641 {
642   return PlaceholderHandler::IsPlaceholderTextFontWeightDefined(*this);
643 }
644
645 FontWeight Controller::GetPlaceholderTextFontWeight() const
646 {
647   return PlaceholderHandler::GetPlaceholderTextFontWeight(*this);
648 }
649
650 void Controller::SetDefaultFontWidth(FontWidth width)
651 {
652   EnsureCreated(mImpl->mFontDefaults);
653
654   mImpl->mFontDefaults->mFontDescription.width = width;
655   mImpl->mFontDefaults->widthDefined           = true;
656
657   // Update the cursor position if it's in editing mode
658   UpdateCursorPosition(mImpl->mEventData);
659
660   // Clear the font-specific data
661   mImpl->ClearFontData();
662
663   mImpl->RequestRelayout();
664 }
665
666 bool Controller::IsDefaultFontWidthDefined() const
667 {
668   return mImpl->mFontDefaults && mImpl->mFontDefaults->widthDefined;
669 }
670
671 FontWidth Controller::GetDefaultFontWidth() const
672 {
673   return mImpl->mFontDefaults ? mImpl->mFontDefaults->mFontDescription.width : TextAbstraction::FontWidth::NORMAL;
674 }
675
676 void Controller::SetPlaceholderTextFontWidth(FontWidth width)
677 {
678   PlaceholderHandler::SetPlaceholderTextFontWidth(*this, width);
679 }
680
681 bool Controller::IsPlaceholderTextFontWidthDefined() const
682 {
683   return PlaceholderHandler::IsPlaceholderTextFontWidthDefined(*this);
684 }
685
686 FontWidth Controller::GetPlaceholderTextFontWidth() const
687 {
688   return PlaceholderHandler::GetPlaceholderTextFontWidth(*this);
689 }
690
691 void Controller::SetDefaultFontSlant(FontSlant slant)
692 {
693   EnsureCreated(mImpl->mFontDefaults);
694
695   mImpl->mFontDefaults->mFontDescription.slant = slant;
696   mImpl->mFontDefaults->slantDefined           = true;
697
698   // Update the cursor position if it's in editing mode
699   UpdateCursorPosition(mImpl->mEventData);
700
701   // Clear the font-specific data
702   mImpl->ClearFontData();
703
704   mImpl->RequestRelayout();
705 }
706
707 bool Controller::IsDefaultFontSlantDefined() const
708 {
709   return mImpl->mFontDefaults && mImpl->mFontDefaults->slantDefined;
710 }
711
712 FontSlant Controller::GetDefaultFontSlant() const
713 {
714   return mImpl->mFontDefaults ? mImpl->mFontDefaults->mFontDescription.slant : TextAbstraction::FontSlant::NORMAL;
715 }
716
717 void Controller::SetPlaceholderTextFontSlant(FontSlant slant)
718 {
719   PlaceholderHandler::SetPlaceholderTextFontSlant(*this, slant);
720 }
721
722 bool Controller::IsPlaceholderTextFontSlantDefined() const
723 {
724   return PlaceholderHandler::IsPlaceholderTextFontSlantDefined(*this);
725 }
726
727 FontSlant Controller::GetPlaceholderTextFontSlant() const
728 {
729   return PlaceholderHandler::GetPlaceholderTextFontSlant(*this);
730 }
731
732 void Controller::SetFontSizeScale(float scale)
733 {
734   mImpl->mFontSizeScale = scale;
735
736   // No relayout is required
737   if(!mImpl->mFontSizeScaleEnabled) return;
738
739   // Update the cursor position if it's in editing mode
740   UpdateCursorPosition(mImpl->mEventData);
741
742   // Clear the font-specific data
743   mImpl->ClearFontData();
744
745   mImpl->RequestRelayout();
746 }
747
748 float Controller::GetFontSizeScale() const
749 {
750   return mImpl->mFontDefaults ? mImpl->mFontSizeScale : 1.0f;
751 }
752
753 void Controller::SetFontSizeScaleEnabled(bool enabled)
754 {
755   mImpl->mFontSizeScaleEnabled = enabled;
756
757   // Update the cursor position if it's in editing mode
758   UpdateCursorPosition(mImpl->mEventData);
759
760   // Clear the font-specific data
761   mImpl->ClearFontData();
762
763   mImpl->RequestRelayout();
764 }
765
766 bool Controller::IsFontSizeScaleEnabled() const
767 {
768   return mImpl->mFontSizeScaleEnabled;
769 }
770
771 void Controller::SetDefaultFontSize(float fontSize, FontSizeType type)
772 {
773   EnsureCreated(mImpl->mFontDefaults);
774
775   mImpl->mFontDefaults->mDefaultPointSize = (type == POINT_SIZE) ? fontSize : ConvertPixelToPoint(fontSize);
776   mImpl->mFontDefaults->sizeDefined       = true;
777
778   // Update the cursor position if it's in editing mode
779   UpdateCursorPosition(mImpl->mEventData);
780
781   // Clear the font-specific data
782   mImpl->ClearFontData();
783
784   mImpl->RequestRelayout();
785 }
786
787 float Controller::GetDefaultFontSize(FontSizeType type) const
788 {
789   if(mImpl->mFontDefaults)
790   {
791     return (type == POINT_SIZE) ? mImpl->mFontDefaults->mDefaultPointSize : ConvertPointToPixel(mImpl->mFontDefaults->mDefaultPointSize);
792   }
793   return 0.0f;
794 }
795
796 void Controller::SetPlaceholderTextFontSize(float fontSize, FontSizeType type)
797 {
798   PlaceholderHandler::SetPlaceholderTextFontSize(*this, fontSize, type);
799 }
800
801 float Controller::GetPlaceholderTextFontSize(FontSizeType type) const
802 {
803   return PlaceholderHandler::GetPlaceholderTextFontSize(*this, type);
804 }
805
806 void Controller::SetDefaultColor(const Vector4& color)
807 {
808   mImpl->SetDefaultColor(color);
809 }
810
811 const Vector4& Controller::GetDefaultColor() const
812 {
813   return mImpl->mTextColor;
814 }
815
816 void Controller::SetAnchorColor(const Vector4& color)
817 {
818   mImpl->SetAnchorColor(color);
819 }
820
821 const Vector4& Controller::GetAnchorColor() const
822 {
823   return mImpl->GetAnchorColor();
824 }
825
826 void Controller::SetAnchorClickedColor(const Vector4& color)
827 {
828   mImpl->SetAnchorClickedColor(color);
829 }
830
831 const Vector4& Controller::GetAnchorClickedColor() const
832 {
833   return mImpl->GetAnchorClickedColor();
834 }
835
836 void Controller::SetDisabledColorOpacity(float opacity)
837 {
838   mImpl->mDisabledColorOpacity = opacity;
839 }
840
841 float Controller::GetDisabledColorOpacity() const
842 {
843   return mImpl->mDisabledColorOpacity;
844 }
845
846 void Controller::SetUserInteractionEnabled(bool enabled)
847 {
848   mImpl->SetUserInteractionEnabled(enabled);
849 }
850
851 bool Controller::IsUserInteractionEnabled() const
852 {
853   return mImpl->mIsUserInteractionEnabled;
854 }
855
856 void Controller::SetPlaceholderTextColor(const Vector4& textColor)
857 {
858   PlaceholderHandler::SetPlaceholderTextColor(*this, textColor);
859 }
860
861 const Vector4& Controller::GetPlaceholderTextColor() const
862 {
863   return PlaceholderHandler::GetPlaceholderTextColor(*this);
864 }
865
866 void Controller::SetShadowOffset(const Vector2& shadowOffset)
867 {
868   mImpl->mModel->mVisualModel->SetShadowOffset(shadowOffset);
869   mImpl->RequestRelayout();
870 }
871
872 const Vector2& Controller::GetShadowOffset() const
873 {
874   return mImpl->mModel->mVisualModel->GetShadowOffset();
875 }
876
877 void Controller::SetShadowColor(const Vector4& shadowColor)
878 {
879   mImpl->mModel->mVisualModel->SetShadowColor(shadowColor);
880   mImpl->RequestRelayout();
881 }
882
883 const Vector4& Controller::GetShadowColor() const
884 {
885   return mImpl->mModel->mVisualModel->GetShadowColor();
886 }
887
888 void Controller::SetShadowBlurRadius(const float& shadowBlurRadius)
889 {
890   if(fabsf(GetShadowBlurRadius() - shadowBlurRadius) > Math::MACHINE_EPSILON_1)
891   {
892     mImpl->mModel->mVisualModel->SetShadowBlurRadius(shadowBlurRadius);
893     mImpl->RequestRelayout();
894   }
895 }
896
897 const float& Controller::GetShadowBlurRadius() const
898 {
899   return mImpl->mModel->mVisualModel->GetShadowBlurRadius();
900 }
901
902 void Controller::SetUnderlineColor(const Vector4& color)
903 {
904   mImpl->mModel->mVisualModel->SetUnderlineColor(color);
905   mImpl->RequestRelayout();
906 }
907
908 const Vector4& Controller::GetUnderlineColor() const
909 {
910   return mImpl->mModel->mVisualModel->GetUnderlineColor();
911 }
912
913 void Controller::SetUnderlineEnabled(bool enabled)
914 {
915   mImpl->mModel->mVisualModel->SetUnderlineEnabled(enabled);
916   mImpl->RequestRelayout();
917 }
918
919 bool Controller::IsUnderlineEnabled() const
920 {
921   return mImpl->mModel->mVisualModel->IsUnderlineEnabled();
922 }
923
924 void Controller::SetUnderlineHeight(float height)
925 {
926   mImpl->mModel->mVisualModel->SetUnderlineHeight(height);
927   mImpl->RequestRelayout();
928 }
929
930 float Controller::GetUnderlineHeight() const
931 {
932   return mImpl->mModel->mVisualModel->GetUnderlineHeight();
933 }
934
935 void Controller::SetUnderlineType(Text::Underline::Type type)
936 {
937   mImpl->mModel->mVisualModel->SetUnderlineType(type);
938
939   mImpl->RequestRelayout();
940 }
941
942 Text::Underline::Type Controller::GetUnderlineType() const
943 {
944   return mImpl->mModel->mVisualModel->GetUnderlineType();
945 }
946
947 void Controller::SetDashedUnderlineWidth(float width)
948 {
949   mImpl->mModel->mVisualModel->SetDashedUnderlineWidth(width);
950
951   mImpl->RequestRelayout();
952 }
953
954 float Controller::GetDashedUnderlineWidth() const
955 {
956   return mImpl->mModel->mVisualModel->GetDashedUnderlineWidth();
957 }
958
959 void Controller::SetDashedUnderlineGap(float gap)
960 {
961   mImpl->mModel->mVisualModel->SetDashedUnderlineGap(gap);
962
963   mImpl->RequestRelayout();
964 }
965
966 float Controller::GetDashedUnderlineGap() const
967 {
968   return mImpl->mModel->mVisualModel->GetDashedUnderlineGap();
969 }
970
971 void Controller::SetOutlineColor(const Vector4& color)
972 {
973   mImpl->mModel->mVisualModel->SetOutlineColor(color);
974   mImpl->RequestRelayout();
975 }
976
977 const Vector4& Controller::GetOutlineColor() const
978 {
979   return mImpl->mModel->mVisualModel->GetOutlineColor();
980 }
981
982 void Controller::SetOutlineWidth(uint16_t width)
983 {
984   mImpl->mModel->mVisualModel->SetOutlineWidth(width);
985   mImpl->RequestRelayout();
986 }
987
988 uint16_t Controller::GetOutlineWidth() const
989 {
990   return mImpl->mModel->mVisualModel->GetOutlineWidth();
991 }
992
993 void Controller::SetBackgroundColor(const Vector4& color)
994 {
995   mImpl->mModel->mVisualModel->SetBackgroundColor(color);
996   mImpl->RequestRelayout();
997 }
998
999 const Vector4& Controller::GetBackgroundColor() const
1000 {
1001   return mImpl->mModel->mVisualModel->GetBackgroundColor();
1002 }
1003
1004 void Controller::SetBackgroundEnabled(bool enabled)
1005 {
1006   mImpl->mModel->mVisualModel->SetBackgroundEnabled(enabled);
1007   mImpl->RequestRelayout();
1008 }
1009
1010 bool Controller::IsBackgroundEnabled() const
1011 {
1012   return mImpl->mModel->mVisualModel->IsBackgroundEnabled();
1013 }
1014
1015 void Controller::SetDefaultEmbossProperties(const std::string& embossProperties)
1016 {
1017   EnsureCreated(mImpl->mEmbossDefaults);
1018   mImpl->mEmbossDefaults->properties = embossProperties;
1019 }
1020
1021 std::string Controller::GetDefaultEmbossProperties() const
1022 {
1023   return mImpl->mEmbossDefaults ? mImpl->mEmbossDefaults->properties : EMPTY_STRING;
1024 }
1025
1026 void Controller::SetDefaultOutlineProperties(const std::string& outlineProperties)
1027 {
1028   EnsureCreated(mImpl->mOutlineDefaults);
1029   mImpl->mOutlineDefaults->properties = outlineProperties;
1030 }
1031
1032 std::string Controller::GetDefaultOutlineProperties() const
1033 {
1034   return mImpl->mOutlineDefaults ? mImpl->mOutlineDefaults->properties : EMPTY_STRING;
1035 }
1036
1037 bool Controller::SetDefaultLineSpacing(float lineSpacing)
1038 {
1039   return mImpl->SetDefaultLineSpacing(lineSpacing);
1040 }
1041
1042 float Controller::GetDefaultLineSpacing() const
1043 {
1044   return mImpl->mLayoutEngine.GetDefaultLineSpacing();
1045 }
1046
1047 bool Controller::SetDefaultLineSize(float lineSize)
1048 {
1049   return mImpl->SetDefaultLineSize(lineSize);
1050 }
1051
1052 float Controller::GetDefaultLineSize() const
1053 {
1054   return mImpl->mLayoutEngine.GetDefaultLineSize();
1055 }
1056
1057 bool Controller::SetRelativeLineSize(float relativeLineSize)
1058 {
1059   return mImpl->SetRelativeLineSize(relativeLineSize);
1060 }
1061
1062 float Controller::GetRelativeLineSize() const
1063 {
1064   return mImpl->GetRelativeLineSize();
1065 }
1066
1067 void Controller::SetInputColor(const Vector4& color)
1068 {
1069   InputProperties::SetInputColor(*this, color);
1070 }
1071
1072 const Vector4& Controller::GetInputColor() const
1073 {
1074   return InputProperties::GetInputColor(*this);
1075 }
1076
1077 void Controller::SetInputFontFamily(const std::string& fontFamily)
1078 {
1079   InputFontHandler::SetInputFontFamily(*this, fontFamily);
1080 }
1081
1082 std::string Controller::GetInputFontFamily() const
1083 {
1084   return InputFontHandler::GetInputFontFamily(*this);
1085 }
1086
1087 void Controller::SetInputFontWeight(FontWeight weight)
1088 {
1089   InputFontHandler::SetInputFontWeight(*this, weight);
1090 }
1091
1092 bool Controller::IsInputFontWeightDefined() const
1093 {
1094   return InputFontHandler::IsInputFontWeightDefined(*this);
1095 }
1096
1097 FontWeight Controller::GetInputFontWeight() const
1098 {
1099   return InputFontHandler::GetInputFontWeight(*this);
1100 }
1101
1102 void Controller::SetInputFontWidth(FontWidth width)
1103 {
1104   InputFontHandler::SetInputFontWidth(*this, width);
1105 }
1106
1107 bool Controller::IsInputFontWidthDefined() const
1108 {
1109   return InputFontHandler::IsInputFontWidthDefined(*this);
1110 }
1111
1112 FontWidth Controller::GetInputFontWidth() const
1113 {
1114   return InputFontHandler::GetInputFontWidth(*this);
1115 }
1116
1117 void Controller::SetInputFontSlant(FontSlant slant)
1118 {
1119   InputFontHandler::SetInputFontSlant(*this, slant);
1120 }
1121
1122 bool Controller::IsInputFontSlantDefined() const
1123 {
1124   return InputFontHandler::IsInputFontSlantDefined(*this);
1125 }
1126
1127 FontSlant Controller::GetInputFontSlant() const
1128 {
1129   return InputFontHandler::GetInputFontSlant(*this);
1130 }
1131
1132 void Controller::SetInputFontPointSize(float size)
1133 {
1134   InputFontHandler::SetInputFontPointSize(*this, size);
1135 }
1136
1137 float Controller::GetInputFontPointSize() const
1138 {
1139   return InputFontHandler::GetInputFontPointSize(*this);
1140 }
1141
1142 void Controller::SetInputLineSpacing(float lineSpacing)
1143 {
1144   InputProperties::SetInputLineSpacing(*this, lineSpacing);
1145 }
1146
1147 float Controller::GetInputLineSpacing() const
1148 {
1149   return InputProperties::GetInputLineSpacing(*this);
1150 }
1151
1152 void Controller::SetInputShadowProperties(const std::string& shadowProperties)
1153 {
1154   InputProperties::SetInputShadowProperties(*this, shadowProperties);
1155 }
1156
1157 std::string Controller::GetInputShadowProperties() const
1158 {
1159   return InputProperties::GetInputShadowProperties(*this);
1160 }
1161
1162 void Controller::SetInputUnderlineProperties(const std::string& underlineProperties)
1163 {
1164   InputProperties::SetInputUnderlineProperties(*this, underlineProperties);
1165 }
1166
1167 std::string Controller::GetInputUnderlineProperties() const
1168 {
1169   return InputProperties::GetInputUnderlineProperties(*this);
1170 }
1171
1172 void Controller::SetInputEmbossProperties(const std::string& embossProperties)
1173 {
1174   InputProperties::SetInputEmbossProperties(*this, embossProperties);
1175 }
1176
1177 std::string Controller::GetInputEmbossProperties() const
1178 {
1179   return InputProperties::GetInputEmbossProperties(*this);
1180 }
1181
1182 void Controller::SetInputOutlineProperties(const std::string& outlineProperties)
1183 {
1184   InputProperties::SetInputOutlineProperties(*this, outlineProperties);
1185 }
1186
1187 std::string Controller::GetInputOutlineProperties() const
1188 {
1189   return InputProperties::GetInputOutlineProperties(*this);
1190 }
1191
1192 void Controller::SetInputModePassword(bool passwordInput)
1193 {
1194   InputProperties::SetInputModePassword(*this, passwordInput);
1195 }
1196
1197 bool Controller::IsInputModePassword()
1198 {
1199   return InputProperties::IsInputModePassword(*this);
1200 }
1201
1202 void Controller::SetNoTextDoubleTapAction(NoTextTap::Action action)
1203 {
1204   if(mImpl->mEventData)
1205   {
1206     mImpl->mEventData->mDoubleTapAction = action;
1207   }
1208 }
1209
1210 Controller::NoTextTap::Action Controller::GetNoTextDoubleTapAction() const
1211 {
1212   return mImpl->mEventData ? mImpl->mEventData->mDoubleTapAction : NoTextTap::NO_ACTION;
1213 }
1214
1215 void Controller::SetNoTextLongPressAction(NoTextTap::Action action)
1216 {
1217   if(mImpl->mEventData)
1218   {
1219     mImpl->mEventData->mLongPressAction = action;
1220   }
1221 }
1222
1223 Controller::NoTextTap::Action Controller::GetNoTextLongPressAction() const
1224 {
1225   return mImpl->mEventData ? mImpl->mEventData->mLongPressAction : NoTextTap::NO_ACTION;
1226 }
1227
1228 bool Controller::IsUnderlineSetByString()
1229 {
1230   return mImpl->mUnderlineSetByString;
1231 }
1232
1233 void Controller::UnderlineSetByString(bool setByString)
1234 {
1235   mImpl->mUnderlineSetByString = setByString;
1236 }
1237
1238 bool Controller::IsShadowSetByString()
1239 {
1240   return mImpl->mShadowSetByString;
1241 }
1242
1243 void Controller::ShadowSetByString(bool setByString)
1244 {
1245   mImpl->mShadowSetByString = setByString;
1246 }
1247
1248 bool Controller::IsOutlineSetByString()
1249 {
1250   return mImpl->mOutlineSetByString;
1251 }
1252
1253 void Controller::OutlineSetByString(bool setByString)
1254 {
1255   mImpl->mOutlineSetByString = setByString;
1256 }
1257
1258 bool Controller::IsFontStyleSetByString()
1259 {
1260   return mImpl->mFontStyleSetByString;
1261 }
1262
1263 void Controller::FontStyleSetByString(bool setByString)
1264 {
1265   mImpl->mFontStyleSetByString = setByString;
1266 }
1267
1268 void Controller::SetStrikethroughHeight(float height)
1269 {
1270   mImpl->mModel->mVisualModel->SetStrikethroughHeight(height);
1271
1272   mImpl->RequestRelayout();
1273 }
1274
1275 float Controller::GetStrikethroughHeight() const
1276 {
1277   return mImpl->mModel->mVisualModel->GetStrikethroughHeight();
1278 }
1279
1280 void Controller::SetStrikethroughColor(const Vector4& color)
1281 {
1282   mImpl->mModel->mVisualModel->SetStrikethroughColor(color);
1283
1284   mImpl->RequestRelayout();
1285 }
1286
1287 const Vector4& Controller::GetStrikethroughColor() const
1288 {
1289   return mImpl->mModel->mVisualModel->GetStrikethroughColor();
1290 }
1291
1292 void Controller::SetStrikethroughEnabled(bool enabled)
1293 {
1294   mImpl->mModel->mVisualModel->SetStrikethroughEnabled(enabled);
1295
1296   mImpl->RequestRelayout();
1297 }
1298
1299 bool Controller::IsStrikethroughEnabled() const
1300 {
1301   return mImpl->mModel->mVisualModel->IsStrikethroughEnabled();
1302 }
1303
1304 void Controller::SetInputStrikethroughProperties(const std::string& strikethroughProperties)
1305 {
1306   if(NULL != mImpl->mEventData)
1307   {
1308     mImpl->mEventData->mInputStyle.strikethroughProperties = strikethroughProperties;
1309   }
1310 }
1311
1312 std::string Controller::GetInputStrikethroughProperties() const
1313 {
1314   return (NULL != mImpl->mEventData) ? mImpl->mEventData->mInputStyle.strikethroughProperties : EMPTY_STRING;
1315 }
1316
1317 bool Controller::IsStrikethroughSetByString()
1318 {
1319   return mImpl->mStrikethroughSetByString;
1320 }
1321
1322 void Controller::StrikethroughSetByString(bool setByString)
1323 {
1324   mImpl->mStrikethroughSetByString = setByString;
1325 }
1326
1327 Layout::Engine& Controller::GetLayoutEngine()
1328 {
1329   return mImpl->mLayoutEngine;
1330 }
1331
1332 View& Controller::GetView()
1333 {
1334   return mImpl->mView;
1335 }
1336
1337 Vector3 Controller::GetNaturalSize()
1338 {
1339   return Relayouter::GetNaturalSize(*this);
1340 }
1341
1342 bool Controller::CheckForTextFit(float pointSize, Size& layoutSize)
1343 {
1344   return Relayouter::CheckForTextFit(*this, pointSize, layoutSize);
1345 }
1346
1347 void Controller::FitPointSizeforLayout(Size layoutSize)
1348 {
1349   Relayouter::FitPointSizeforLayout(*this, layoutSize);
1350 }
1351
1352 void Controller::FitArrayPointSizeforLayout(Size layoutSize)
1353 {
1354   Relayouter::FitArrayPointSizeforLayout(*this, layoutSize);
1355 }
1356
1357 float Controller::GetHeightForWidth(float width)
1358 {
1359   return Relayouter::GetHeightForWidth(*this, width);
1360 }
1361
1362 int Controller::GetLineCount(float width)
1363 {
1364   GetHeightForWidth(width);
1365   return mImpl->mModel->GetNumberOfLines();
1366 }
1367
1368 const ModelInterface* Controller::GetTextModel() const
1369 {
1370   return mImpl->mModel.Get();
1371 }
1372
1373 float Controller::GetScrollAmountByUserInput()
1374 {
1375   float scrollAmount = 0.0f;
1376
1377   if(NULL != mImpl->mEventData && mImpl->mEventData->mCheckScrollAmount)
1378   {
1379     scrollAmount                          = mImpl->mModel->mScrollPosition.y - mImpl->mModel->mScrollPositionLast.y;
1380     mImpl->mEventData->mCheckScrollAmount = false;
1381   }
1382   return scrollAmount;
1383 }
1384
1385 bool Controller::GetTextScrollInfo(float& scrollPosition, float& controlHeight, float& layoutHeight)
1386 {
1387   const Vector2& layout = mImpl->mModel->mVisualModel->GetLayoutSize();
1388   bool           isScrolled;
1389
1390   controlHeight  = mImpl->mModel->mVisualModel->mControlSize.height;
1391   layoutHeight   = layout.height;
1392   scrollPosition = mImpl->mModel->mScrollPosition.y;
1393   isScrolled     = !Equals(mImpl->mModel->mScrollPosition.y, mImpl->mModel->mScrollPositionLast.y, Math::MACHINE_EPSILON_1);
1394   return isScrolled;
1395 }
1396
1397 void Controller::SetHiddenInputOption(const Property::Map& options)
1398 {
1399   EnsureCreated<HiddenText, Controller*>(mImpl->mHiddenInput, this);
1400   mImpl->mHiddenInput->SetProperties(options);
1401 }
1402
1403 void Controller::GetHiddenInputOption(Property::Map& options)
1404 {
1405   if(mImpl->mHiddenInput)
1406   {
1407     mImpl->mHiddenInput->GetProperties(options);
1408   }
1409 }
1410
1411 void Controller::SetInputFilterOption(const Property::Map& options)
1412 {
1413   EnsureCreated(mImpl->mInputFilter);
1414   mImpl->mInputFilter->SetProperties(options);
1415 }
1416
1417 void Controller::GetInputFilterOption(Property::Map& options)
1418 {
1419   if(mImpl->mInputFilter)
1420   {
1421     mImpl->mInputFilter->GetProperties(options);
1422   }
1423 }
1424
1425 void Controller::SetPlaceholderProperty(const Property::Map& map)
1426 {
1427   PlaceholderHandler::SetPlaceholderProperty(*this, map);
1428 }
1429
1430 void Controller::GetPlaceholderProperty(Property::Map& map)
1431 {
1432   PlaceholderHandler::GetPlaceholderProperty(*this, map);
1433 }
1434
1435 Toolkit::DevelText::TextDirection::Type Controller::GetTextDirection()
1436 {
1437   // Make sure the model is up-to-date before layouting
1438   EventHandler::ProcessModifyEvents(*this);
1439
1440   return mImpl->GetTextDirection();
1441 }
1442
1443 Toolkit::DevelText::VerticalLineAlignment::Type Controller::GetVerticalLineAlignment() const
1444 {
1445   return mImpl->mModel->GetVerticalLineAlignment();
1446 }
1447
1448 void Controller::SetVerticalLineAlignment(Toolkit::DevelText::VerticalLineAlignment::Type alignment)
1449 {
1450   mImpl->mModel->mVerticalLineAlignment = alignment;
1451 }
1452
1453 Toolkit::DevelText::EllipsisPosition::Type Controller::GetEllipsisPosition() const
1454 {
1455   return mImpl->mModel->GetEllipsisPosition();
1456 }
1457
1458 void Controller::SetEllipsisPosition(Toolkit::DevelText::EllipsisPosition::Type ellipsisPosition)
1459 {
1460   mImpl->mModel->mEllipsisPosition = ellipsisPosition;
1461   mImpl->mModel->mVisualModel->SetEllipsisPosition(ellipsisPosition);
1462 }
1463
1464 void Controller::SetCharacterSpacing(float characterSpacing)
1465 {
1466   mImpl->mModel->mVisualModel->SetCharacterSpacing(characterSpacing);
1467
1468   mImpl->RelayoutAllCharacters();
1469   mImpl->RequestRelayout();
1470 }
1471
1472 const float Controller::GetCharacterSpacing() const
1473 {
1474   return mImpl->mModel->mVisualModel->GetCharacterSpacing();
1475 }
1476
1477 Controller::UpdateTextType Controller::Relayout(const Size& size, Dali::LayoutDirection::Type layoutDirection)
1478 {
1479   return Relayouter::Relayout(*this, size, layoutDirection);
1480 }
1481
1482 void Controller::RequestRelayout()
1483 {
1484   mImpl->RequestRelayout();
1485 }
1486
1487 Vector<Vector2> Controller::GetTextSize(CharacterIndex startIndex, CharacterIndex endIndex)
1488 {
1489   Vector<Vector2> sizesList;
1490   Vector<Vector2> positionsList;
1491
1492   GetTextGeometry(mImpl->mModel, startIndex, endIndex, sizesList, positionsList);
1493   return sizesList;
1494 }
1495
1496 Vector<Vector2> Controller::GetTextPosition(CharacterIndex startIndex, CharacterIndex endIndex)
1497 {
1498   Vector<Vector2> sizesList;
1499   Vector<Vector2> positionsList;
1500
1501   GetTextGeometry(mImpl->mModel, startIndex, endIndex, sizesList, positionsList);
1502   return positionsList;
1503 }
1504
1505 Rect<float> Controller::GetLineBoundingRectangle(const uint32_t lineIndex)
1506 {
1507   return GetLineBoundingRect(mImpl->mModel, lineIndex);
1508 }
1509
1510 Rect<float> Controller::GetCharacterBoundingRectangle(const uint32_t charIndex)
1511 {
1512   return GetCharacterBoundingRect(mImpl->mModel, charIndex);
1513 }
1514
1515 int Controller::GetCharacterIndexAtPosition(float visualX, float visualY)
1516 {
1517   return GetCharIndexAtPosition(mImpl->mModel, visualX, visualY);
1518 }
1519
1520 Rect<> Controller::GetTextBoundingRectangle(CharacterIndex startIndex, CharacterIndex endIndex)
1521 {
1522   Vector<Vector2> sizeList;
1523   Vector<Vector2> positionList;
1524
1525   GetTextGeometry(mImpl->mModel, startIndex, endIndex, sizeList, positionList);
1526
1527   if(sizeList.Empty() || sizeList.Size() != positionList.Size())
1528   {
1529     return {0, 0, 0, 0};
1530   }
1531
1532   auto controlWidth = mImpl->mModel->mVisualModel->mControlSize.width;
1533   auto minX         = positionList[0].x;
1534   auto minY         = positionList[0].y;
1535   auto maxRight     = positionList[0].x + sizeList[0].x;
1536   auto maxBottom    = positionList[0].y + sizeList[0].y;
1537
1538   for(unsigned int i = 1; i < sizeList.Size(); i++)
1539   {
1540     minX      = std::min(minX, positionList[i].x);
1541     minY      = std::min(minY, positionList[i].y);
1542     maxRight  = std::max(maxRight, positionList[i].x + sizeList[i].x);
1543     maxBottom = std::max(maxBottom, positionList[i].y + sizeList[i].y);
1544   }
1545
1546   if(minX < 0.0f)
1547   {
1548     minX = 0.0f;
1549   }
1550
1551   if(maxRight > controlWidth)
1552   {
1553     maxRight = controlWidth;
1554   }
1555
1556   return {minX, minY, maxRight - minX, maxBottom - minY};
1557 }
1558
1559 bool Controller::IsInputStyleChangedSignalsQueueEmpty()
1560 {
1561   return mImpl->IsInputStyleChangedSignalsQueueEmpty();
1562 }
1563
1564 void Controller::ProcessInputStyleChangedSignals()
1565 {
1566   mImpl->ProcessInputStyleChangedSignals();
1567 }
1568
1569 void Controller::KeyboardFocusGainEvent()
1570 {
1571   EventHandler::KeyboardFocusGainEvent(*this);
1572 }
1573
1574 void Controller::KeyboardFocusLostEvent()
1575 {
1576   EventHandler::KeyboardFocusLostEvent(*this);
1577 }
1578
1579 bool Controller::KeyEvent(const Dali::KeyEvent& keyEvent)
1580 {
1581   return EventHandler::KeyEvent(*this, keyEvent);
1582 }
1583
1584 void Controller::AnchorEvent(float x, float y)
1585 {
1586   EventHandler::AnchorEvent(*this, x, y);
1587 }
1588
1589 void Controller::TapEvent(unsigned int tapCount, float x, float y)
1590 {
1591   EventHandler::TapEvent(*this, tapCount, x, y);
1592 }
1593
1594 void Controller::PanEvent(GestureState state, const Vector2& displacement)
1595 {
1596   EventHandler::PanEvent(*this, state, displacement);
1597 }
1598
1599 void Controller::LongPressEvent(GestureState state, float x, float y)
1600 {
1601   EventHandler::LongPressEvent(*this, state, x, y);
1602 }
1603
1604 void Controller::SelectEvent(float x, float y, SelectionType selectType)
1605 {
1606   EventHandler::SelectEvent(*this, x, y, selectType);
1607 }
1608
1609 void Controller::SetTextSelectionRange(const uint32_t* start, const uint32_t* end)
1610 {
1611   if(mImpl->mEventData)
1612   {
1613     mImpl->mEventData->mCheckScrollAmount     = true;
1614     mImpl->mEventData->mIsLeftHandleSelected  = true;
1615     mImpl->mEventData->mIsRightHandleSelected = true;
1616     mImpl->SetTextSelectionRange(start, end);
1617     mImpl->RequestRelayout();
1618     EventHandler::KeyboardFocusGainEvent(*this);
1619   }
1620 }
1621
1622 Uint32Pair Controller::GetTextSelectionRange() const
1623 {
1624   return mImpl->GetTextSelectionRange();
1625 }
1626
1627 CharacterIndex Controller::GetPrimaryCursorPosition() const
1628 {
1629   return mImpl->GetPrimaryCursorPosition();
1630 }
1631
1632 bool Controller::SetPrimaryCursorPosition(CharacterIndex index, bool focused)
1633 {
1634   if(mImpl->mEventData)
1635   {
1636     mImpl->mEventData->mCheckScrollAmount     = true;
1637     mImpl->mEventData->mIsLeftHandleSelected  = true;
1638     mImpl->mEventData->mIsRightHandleSelected = true;
1639     mImpl->mEventData->mCheckScrollAmount     = true;
1640     if(mImpl->SetPrimaryCursorPosition(index, focused) && focused)
1641     {
1642       EventHandler::KeyboardFocusGainEvent(*this);
1643       return true;
1644     }
1645   }
1646   return false;
1647 }
1648
1649 void Controller::SelectWholeText()
1650 {
1651   EventHandler::SelectEvent(*this, 0.f, 0.f, SelectionType::ALL);
1652 }
1653
1654 void Controller::SelectNone()
1655 {
1656   EventHandler::SelectEvent(*this, 0.f, 0.f, SelectionType::NONE);
1657 }
1658
1659 void Controller::SelectText(const uint32_t start, const uint32_t end)
1660 {
1661   EventHandler::SelectEvent(*this, start, end, SelectionType::RANGE);
1662 }
1663
1664 string Controller::GetSelectedText() const
1665 {
1666   return mImpl->GetSelectedText();
1667 }
1668
1669 string Controller::CopyText()
1670 {
1671   return mImpl->CopyText();
1672 }
1673
1674 string Controller::CutText()
1675 {
1676   return mImpl->CutText();
1677 }
1678
1679 void Controller::PasteClipboardItemEvent(uint32_t id, const char* mimeType, const char* data)
1680 {
1681   // Upon receiving the data, it is important to disconnect the signal
1682   // to avoid potential unintended pasting caused by subsequent requests.
1683   mImpl->mClipboard.DataReceivedSignal().Disconnect(this, &Controller::PasteClipboardItemEvent);
1684
1685   // If the id is 0u, it is an invalid response.
1686   // text-controller allows only plain text type.
1687   if(id != 0u && !strncmp(mimeType, MIME_TYPE_TEXT_PLAIN, strlen(MIME_TYPE_TEXT_PLAIN)))
1688   {
1689     EventHandler::PasteClipboardItemEvent(*this, data);
1690   }
1691 }
1692
1693 void Controller::PasteText()
1694 {
1695   if(mImpl->EnsureClipboardCreated())
1696   {
1697     // Connect the signal before calling GetData() of the clipboard.
1698     mImpl->mClipboard.DataReceivedSignal().Connect(this, &Controller::PasteClipboardItemEvent);
1699
1700     // Request clipboard service to retrieve an item.
1701     uint id = mImpl->mClipboard.GetData(MIME_TYPE_TEXT_PLAIN);
1702     if(id == 0u)
1703     {
1704       // If the return id is 0u, the signal is not emitted, we must disconnect signal here.
1705       mImpl->mClipboard.DataReceivedSignal().Disconnect(this, &Controller::PasteClipboardItemEvent);
1706     }
1707   }
1708 }
1709
1710 InputMethodContext::CallbackData Controller::OnInputMethodContextEvent(InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent)
1711 {
1712   return EventHandler::OnInputMethodContextEvent(*this, inputMethodContext, inputMethodContextEvent);
1713 }
1714
1715 void Controller::GetTargetSize(Vector2& targetSize)
1716 {
1717   targetSize = mImpl->mModel->mVisualModel->mControlSize;
1718 }
1719
1720 void Controller::AddDecoration(Actor& actor, DecorationType type, bool needsClipping)
1721 {
1722   if(mImpl->mEditableControlInterface)
1723   {
1724     mImpl->mEditableControlInterface->AddDecoration(actor, type, needsClipping);
1725   }
1726 }
1727
1728 bool Controller::IsEditable() const
1729 {
1730   return mImpl->IsEditable();
1731 }
1732
1733 void Controller::SetEditable(bool editable)
1734 {
1735   mImpl->SetEditable(editable);
1736 }
1737
1738 void Controller::ScrollBy(Vector2 scroll)
1739 {
1740   mImpl->ScrollBy(scroll);
1741 }
1742
1743 bool Controller::IsScrollable(const Vector2& displacement)
1744 {
1745   return mImpl->IsScrollable(displacement);
1746 }
1747
1748 float Controller::GetHorizontalScrollPosition()
1749 {
1750   return mImpl->GetHorizontalScrollPosition();
1751 }
1752
1753 float Controller::GetVerticalScrollPosition()
1754 {
1755   return mImpl->GetVerticalScrollPosition();
1756 }
1757
1758 void Controller::DecorationEvent(HandleType handleType, HandleState state, float x, float y)
1759 {
1760   EventHandler::DecorationEvent(*this, handleType, state, x, y);
1761 }
1762
1763 void Controller::TextPopupButtonTouched(Dali::Toolkit::TextSelectionPopup::Buttons button)
1764 {
1765   EventHandler::TextPopupButtonTouched(*this, button);
1766 }
1767
1768 void Controller::DisplayTimeExpired()
1769 {
1770   mImpl->mEventData->mUpdateCursorPosition = true;
1771   // Apply modifications to the model
1772   mImpl->mOperationsPending = ALL_OPERATIONS;
1773
1774   mImpl->RequestRelayout();
1775 }
1776
1777 void Controller::ResetCursorPosition(CharacterIndex cursorIndex)
1778 {
1779   // Reset the cursor position
1780   if(NULL != mImpl->mEventData)
1781   {
1782     mImpl->mEventData->mPrimaryCursorPosition = cursorIndex;
1783
1784     // Update the cursor if it's in editing mode.
1785     if(EventData::IsEditingState(mImpl->mEventData->mState))
1786     {
1787       mImpl->mEventData->mUpdateCursorPosition = true;
1788     }
1789   }
1790 }
1791
1792 CharacterIndex Controller::GetCursorPosition()
1793 {
1794   return mImpl->mEventData ? mImpl->mEventData->mPrimaryCursorPosition : 0;
1795 }
1796
1797 void Controller::SetControlInterface(ControlInterface* controlInterface)
1798 {
1799   mImpl->mControlInterface = controlInterface;
1800 }
1801
1802 void Controller::SetAnchorControlInterface(AnchorControlInterface* anchorControlInterface)
1803 {
1804   mImpl->mAnchorControlInterface = anchorControlInterface;
1805 }
1806
1807 bool Controller::ShouldClearFocusOnEscape() const
1808 {
1809   return mImpl->mShouldClearFocusOnEscape;
1810 }
1811
1812 Actor Controller::CreateBackgroundActor()
1813 {
1814   return CreateControllerBackgroundActor(mImpl->mView, mImpl->mModel->mVisualModel, mImpl->mModel->mLogicalModel, mImpl->mShaderBackground);
1815 }
1816
1817 void Controller::GetAnchorActors(std::vector<Toolkit::TextAnchor>& anchorActors)
1818 {
1819   mImpl->GetAnchorActors(anchorActors);
1820 }
1821
1822 int Controller::GetAnchorIndex(size_t characterOffset)
1823 {
1824   return mImpl->GetAnchorIndex(characterOffset);
1825 }
1826
1827 Controller::Controller(ControlInterface*           controlInterface,
1828                        EditableControlInterface*   editableControlInterface,
1829                        SelectableControlInterface* selectableControlInterface,
1830                        AnchorControlInterface*     anchorControlInterface)
1831 : mImpl(new Controller::Impl(controlInterface, editableControlInterface, selectableControlInterface, anchorControlInterface))
1832 {
1833 }
1834
1835 Controller::~Controller()
1836 {
1837 }
1838
1839 } // namespace Dali::Toolkit::Text