Support Underline to Markup using underlined-character-run
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / text-controller.cpp
1 /*
2  * Copyright (c) 2021 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/text-controller.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23 #include <memory.h>
24 #include <cmath>
25 #include <limits>
26
27 // INTERNAL INCLUDES
28 #include <dali-toolkit/internal/text/text-controller-event-handler.h>
29 #include <dali-toolkit/internal/text/text-controller-impl.h>
30 #include <dali-toolkit/internal/text/text-controller-input-font-handler.h>
31 #include <dali-toolkit/internal/text/text-controller-placeholder-handler.h>
32 #include <dali-toolkit/internal/text/text-controller-relayouter.h>
33 #include <dali-toolkit/internal/text/text-controller-text-updater.h>
34 #include <dali-toolkit/internal/text/text-editable-control-interface.h>
35
36 namespace
37 {
38 #if defined(DEBUG_ENABLED)
39 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS");
40 #endif
41
42 constexpr float MAX_FLOAT = std::numeric_limits<float>::max();
43
44 const std::string EMPTY_STRING("");
45
46 int ConvertPixelToPint(float pixel)
47 {
48   unsigned int                      horizontalDpi = 0u;
49   unsigned int                      verticalDpi   = 0u;
50   Dali::TextAbstraction::FontClient fontClient    = Dali::TextAbstraction::FontClient::Get();
51   fontClient.GetDpi(horizontalDpi, verticalDpi);
52
53   return (pixel * 72.f) / static_cast<float>(horizontalDpi);
54 }
55
56 } // namespace
57
58 namespace Dali
59 {
60 namespace Toolkit
61 {
62 namespace Text
63 {
64 // public : Constructor.
65
66 ControllerPtr Controller::New()
67 {
68   return ControllerPtr(new Controller());
69 }
70
71 ControllerPtr Controller::New(ControlInterface* controlInterface)
72 {
73   return ControllerPtr(new Controller(controlInterface));
74 }
75
76 ControllerPtr Controller::New(ControlInterface*           controlInterface,
77                               EditableControlInterface*   editableControlInterface,
78                               SelectableControlInterface* selectableControlInterface,
79                               AnchorControlInterface*     anchorControlInterface)
80 {
81   return ControllerPtr(new Controller(controlInterface,
82                                       editableControlInterface,
83                                       selectableControlInterface,
84                                       anchorControlInterface));
85 }
86
87 // public : Configure the text controller.
88
89 void Controller::EnableTextInput(DecoratorPtr decorator, InputMethodContext& inputMethodContext)
90 {
91   if(!decorator)
92   {
93     delete mImpl->mEventData;
94     mImpl->mEventData = NULL;
95
96     // Nothing else to do.
97     return;
98   }
99
100   if(NULL == mImpl->mEventData)
101   {
102     mImpl->mEventData = new EventData(decorator, inputMethodContext);
103   }
104 }
105
106 void Controller::SetGlyphType(TextAbstraction::GlyphType glyphType)
107 {
108   // Metrics for bitmap & vector based glyphs are different
109   mImpl->mMetrics->SetGlyphType(glyphType);
110
111   // Clear the font-specific data
112   ClearFontData();
113
114   mImpl->RequestRelayout();
115 }
116
117 void Controller::SetMarkupProcessorEnabled(bool enable)
118 {
119   if(enable != mImpl->mMarkupProcessorEnabled)
120   {
121     //If Text was already set, call the SetText again for enabling or disabling markup
122     mImpl->mMarkupProcessorEnabled = enable;
123     std::string text;
124     GetText(text);
125     SetText(text);
126   }
127
128   mImpl->mModel->mVisualModel->SetMarkupProcessorEnabled(enable);
129 }
130
131 bool Controller::IsMarkupProcessorEnabled() const
132 {
133   return mImpl->mMarkupProcessorEnabled;
134 }
135
136 void Controller::SetAutoScrollEnabled(bool enable)
137 {
138   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);
139
140   if(mImpl->mLayoutEngine.GetLayout() == Layout::Engine::SINGLE_LINE_BOX)
141   {
142     if(enable)
143     {
144       DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled for SINGLE_LINE_BOX\n");
145       mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
146                                                               LAYOUT |
147                                                               ALIGN |
148                                                               UPDATE_LAYOUT_SIZE |
149                                                               UPDATE_DIRECTION |
150                                                               REORDER);
151     }
152     else
153     {
154       DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled Disabling autoscroll\n");
155       mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
156                                                               LAYOUT |
157                                                               ALIGN |
158                                                               UPDATE_LAYOUT_SIZE |
159                                                               REORDER);
160     }
161
162     mImpl->mIsAutoScrollEnabled = enable;
163     mImpl->RequestRelayout();
164   }
165   else
166   {
167     DALI_LOG_WARNING("Attempted AutoScrolling on a non SINGLE_LINE_BOX, request ignored\n");
168     mImpl->mIsAutoScrollEnabled = false;
169   }
170 }
171
172 bool Controller::IsAutoScrollEnabled() const
173 {
174   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::IsAutoScrollEnabled[%s]\n", mImpl->mIsAutoScrollEnabled ? "true" : "false");
175
176   return mImpl->mIsAutoScrollEnabled;
177 }
178
179 CharacterDirection Controller::GetAutoScrollDirection() const
180 {
181   return mImpl->mIsTextDirectionRTL;
182 }
183
184 float Controller::GetAutoScrollLineAlignment() const
185 {
186   float offset = 0.f;
187
188   if(mImpl->mModel->mVisualModel &&
189      (0u != mImpl->mModel->mVisualModel->mLines.Count()))
190   {
191     offset = (*mImpl->mModel->mVisualModel->mLines.Begin()).alignmentOffset;
192   }
193
194   return offset;
195 }
196
197 void Controller::SetHorizontalScrollEnabled(bool enable)
198 {
199   if((NULL != mImpl->mEventData) &&
200      mImpl->mEventData->mDecorator)
201   {
202     mImpl->mEventData->mDecorator->SetHorizontalScrollEnabled(enable);
203   }
204 }
205 bool Controller::IsHorizontalScrollEnabled() const
206 {
207   if((NULL != mImpl->mEventData) &&
208      mImpl->mEventData->mDecorator)
209   {
210     return mImpl->mEventData->mDecorator->IsHorizontalScrollEnabled();
211   }
212
213   return false;
214 }
215
216 void Controller::SetVerticalScrollEnabled(bool enable)
217 {
218   if((NULL != mImpl->mEventData) &&
219      mImpl->mEventData->mDecorator)
220   {
221     if(mImpl->mEventData->mDecorator)
222     {
223       mImpl->mEventData->mDecorator->SetVerticalScrollEnabled(enable);
224     }
225   }
226 }
227
228 bool Controller::IsVerticalScrollEnabled() const
229 {
230   if((NULL != mImpl->mEventData) &&
231      mImpl->mEventData->mDecorator)
232   {
233     return mImpl->mEventData->mDecorator->IsVerticalScrollEnabled();
234   }
235
236   return false;
237 }
238
239 void Controller::SetSmoothHandlePanEnabled(bool enable)
240 {
241   if((NULL != mImpl->mEventData) &&
242      mImpl->mEventData->mDecorator)
243   {
244     mImpl->mEventData->mDecorator->SetSmoothHandlePanEnabled(enable);
245   }
246 }
247
248 bool Controller::IsSmoothHandlePanEnabled() const
249 {
250   if((NULL != mImpl->mEventData) &&
251      mImpl->mEventData->mDecorator)
252   {
253     return mImpl->mEventData->mDecorator->IsSmoothHandlePanEnabled();
254   }
255
256   return false;
257 }
258
259 void Controller::SetMaximumNumberOfCharacters(Length maxCharacters)
260 {
261   mImpl->mMaximumNumberOfCharacters = maxCharacters;
262 }
263
264 int Controller::GetMaximumNumberOfCharacters()
265 {
266   return mImpl->mMaximumNumberOfCharacters;
267 }
268
269 void Controller::SetEnableCursorBlink(bool enable)
270 {
271   DALI_ASSERT_DEBUG(NULL != mImpl->mEventData && "TextInput disabled");
272
273   if(NULL != mImpl->mEventData)
274   {
275     mImpl->mEventData->mCursorBlinkEnabled = enable;
276
277     if(!enable &&
278        mImpl->mEventData->mDecorator)
279     {
280       mImpl->mEventData->mDecorator->StopCursorBlink();
281     }
282   }
283 }
284
285 bool Controller::GetEnableCursorBlink() const
286 {
287   if(NULL != mImpl->mEventData)
288   {
289     return mImpl->mEventData->mCursorBlinkEnabled;
290   }
291
292   return false;
293 }
294
295 void Controller::SetMultiLineEnabled(bool enable)
296 {
297   const Layout::Engine::Type layout = enable ? Layout::Engine::MULTI_LINE_BOX : Layout::Engine::SINGLE_LINE_BOX;
298
299   if(layout != mImpl->mLayoutEngine.GetLayout())
300   {
301     // Set the layout type.
302     mImpl->mLayoutEngine.SetLayout(layout);
303
304     // Set the flags to redo the layout operations
305     const OperationsMask layoutOperations = static_cast<OperationsMask>(LAYOUT |
306                                                                         UPDATE_LAYOUT_SIZE |
307                                                                         ALIGN |
308                                                                         REORDER);
309
310     mImpl->mTextUpdateInfo.mFullRelayoutNeeded = true;
311     mImpl->mOperationsPending                  = static_cast<OperationsMask>(mImpl->mOperationsPending | layoutOperations);
312
313     // Need to recalculate natural size
314     mImpl->mRecalculateNaturalSize = true;
315
316     mImpl->RequestRelayout();
317   }
318 }
319
320 bool Controller::IsMultiLineEnabled() const
321 {
322   return Layout::Engine::MULTI_LINE_BOX == mImpl->mLayoutEngine.GetLayout();
323 }
324
325 void Controller::SetHorizontalAlignment(Text::HorizontalAlignment::Type alignment)
326 {
327   if(alignment != mImpl->mModel->mHorizontalAlignment)
328   {
329     // Set the alignment.
330     mImpl->mModel->mHorizontalAlignment = alignment;
331
332     // Set the flag to redo the alignment operation.
333     mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | ALIGN);
334
335     if(mImpl->mEventData)
336     {
337       mImpl->mEventData->mUpdateAlignment = true;
338
339       // Update the cursor if it's in editing mode
340       if(EventData::IsEditingState(mImpl->mEventData->mState))
341       {
342         mImpl->ChangeState(EventData::EDITING);
343         mImpl->mEventData->mUpdateCursorPosition = true;
344       }
345     }
346
347     mImpl->RequestRelayout();
348   }
349 }
350
351 Text::HorizontalAlignment::Type Controller::GetHorizontalAlignment() const
352 {
353   return mImpl->mModel->mHorizontalAlignment;
354 }
355
356 void Controller::SetVerticalAlignment(VerticalAlignment::Type alignment)
357 {
358   if(alignment != mImpl->mModel->mVerticalAlignment)
359   {
360     // Set the alignment.
361     mImpl->mModel->mVerticalAlignment = alignment;
362
363     mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | ALIGN);
364
365     mImpl->RequestRelayout();
366   }
367 }
368
369 VerticalAlignment::Type Controller::GetVerticalAlignment() const
370 {
371   return mImpl->mModel->mVerticalAlignment;
372 }
373
374 bool Controller::IsIgnoreSpacesAfterText() const
375 {
376   return mImpl->mModel->mIgnoreSpacesAfterText;
377 }
378
379 void Controller::SetIgnoreSpacesAfterText(bool ignore)
380 {
381   mImpl->mModel->mIgnoreSpacesAfterText = ignore;
382 }
383
384 bool Controller::IsMatchSystemLanguageDirection() const
385 {
386   return mImpl->mModel->mMatchSystemLanguageDirection;
387 }
388
389 void Controller::SetMatchSystemLanguageDirection(bool match)
390 {
391   mImpl->mModel->mMatchSystemLanguageDirection = match;
392 }
393
394 void Controller::SetLayoutDirection(Dali::LayoutDirection::Type layoutDirection)
395 {
396   mImpl->mLayoutDirection = layoutDirection;
397 }
398
399 bool Controller::IsShowingRealText() const
400 {
401   return mImpl->IsShowingRealText();
402 }
403
404 void Controller::SetLineWrapMode(Text::LineWrap::Mode lineWrapMode)
405 {
406   if(lineWrapMode != mImpl->mModel->mLineWrapMode)
407   {
408     // Set the text wrap mode.
409     mImpl->mModel->mLineWrapMode = lineWrapMode;
410
411     // Update Text layout for applying wrap mode
412     mImpl->mOperationsPending                          = static_cast<OperationsMask>(mImpl->mOperationsPending |
413                                                             ALIGN |
414                                                             LAYOUT |
415                                                             UPDATE_LAYOUT_SIZE |
416                                                             REORDER);
417     mImpl->mTextUpdateInfo.mCharacterIndex             = 0u;
418     mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters;
419     mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd    = mImpl->mModel->mLogicalModel->mText.Count();
420
421     // Request relayout
422     mImpl->RequestRelayout();
423   }
424 }
425
426 Text::LineWrap::Mode Controller::GetLineWrapMode() const
427 {
428   return mImpl->mModel->mLineWrapMode;
429 }
430
431 void Controller::SetTextElideEnabled(bool enabled)
432 {
433   mImpl->mModel->mElideEnabled = enabled;
434 }
435
436 bool Controller::IsTextElideEnabled() const
437 {
438   return mImpl->mModel->mElideEnabled;
439 }
440
441 void Controller::SetTextFitEnabled(bool enabled)
442 {
443   mImpl->mTextFitEnabled = enabled;
444 }
445
446 bool Controller::IsTextFitEnabled() const
447 {
448   return mImpl->mTextFitEnabled;
449 }
450
451 void Controller::SetTextFitMinSize(float minSize, FontSizeType type)
452 {
453   switch(type)
454   {
455     case POINT_SIZE:
456     {
457       mImpl->mTextFitMinSize = minSize;
458       break;
459     }
460     case PIXEL_SIZE:
461     {
462       mImpl->mTextFitMinSize = ConvertPixelToPint(minSize);
463       break;
464     }
465   }
466 }
467
468 float Controller::GetTextFitMinSize() const
469 {
470   return mImpl->mTextFitMinSize;
471 }
472
473 void Controller::SetTextFitMaxSize(float maxSize, FontSizeType type)
474 {
475   switch(type)
476   {
477     case POINT_SIZE:
478     {
479       mImpl->mTextFitMaxSize = maxSize;
480       break;
481     }
482     case PIXEL_SIZE:
483     {
484       mImpl->mTextFitMaxSize = ConvertPixelToPint(maxSize);
485       break;
486     }
487   }
488 }
489
490 float Controller::GetTextFitMaxSize() const
491 {
492   return mImpl->mTextFitMaxSize;
493 }
494
495 void Controller::SetTextFitStepSize(float step, FontSizeType type)
496 {
497   switch(type)
498   {
499     case POINT_SIZE:
500     {
501       mImpl->mTextFitStepSize = step;
502       break;
503     }
504     case PIXEL_SIZE:
505     {
506       mImpl->mTextFitStepSize = ConvertPixelToPint(step);
507       break;
508     }
509   }
510 }
511
512 float Controller::GetTextFitStepSize() const
513 {
514   return mImpl->mTextFitStepSize;
515 }
516
517 void Controller::SetTextFitContentSize(Vector2 size)
518 {
519   mImpl->mTextFitContentSize = size;
520 }
521
522 Vector2 Controller::GetTextFitContentSize() const
523 {
524   return mImpl->mTextFitContentSize;
525 }
526
527 void Controller::SetPlaceholderTextElideEnabled(bool enabled)
528 {
529   PlaceholderHandler::SetPlaceholderTextElideEnabled(*this, enabled);
530 }
531
532 bool Controller::IsPlaceholderTextElideEnabled() const
533 {
534   return PlaceholderHandler::IsPlaceholderTextElideEnabled(*this);
535 }
536
537 void Controller::SetSelectionEnabled(bool enabled)
538 {
539   mImpl->mEventData->mSelectionEnabled = enabled;
540 }
541
542 bool Controller::IsSelectionEnabled() const
543 {
544   return mImpl->mEventData->mSelectionEnabled;
545 }
546
547 void Controller::SetShiftSelectionEnabled(bool enabled)
548 {
549   mImpl->mEventData->mShiftSelectionFlag = enabled;
550 }
551
552 bool Controller::IsShiftSelectionEnabled() const
553 {
554   return mImpl->mEventData->mShiftSelectionFlag;
555 }
556
557 void Controller::SetGrabHandleEnabled(bool enabled)
558 {
559   mImpl->mEventData->mGrabHandleEnabled = enabled;
560 }
561
562 bool Controller::IsGrabHandleEnabled() const
563 {
564   return mImpl->mEventData->mGrabHandleEnabled;
565 }
566
567 void Controller::SetGrabHandlePopupEnabled(bool enabled)
568 {
569   mImpl->mEventData->mGrabHandlePopupEnabled = enabled;
570 }
571
572 bool Controller::IsGrabHandlePopupEnabled() const
573 {
574   return mImpl->mEventData->mGrabHandlePopupEnabled;
575 }
576
577 // public : Update
578
579 void Controller::SetText(const std::string& text)
580 {
581   TextUpdater::SetText(*this, text);
582 }
583
584 void Controller::GetText(std::string& text) const
585 {
586   if(!mImpl->IsShowingPlaceholderText())
587   {
588     // Retrieves the text string.
589     mImpl->GetText(0u, text);
590   }
591   else
592   {
593     DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::GetText %p empty (but showing placeholder)\n", this);
594   }
595 }
596
597 void Controller::SetPlaceholderText(PlaceholderType type, const std::string& text)
598 {
599   PlaceholderHandler::SetPlaceholderText(*this, type, text);
600 }
601
602 void Controller::GetPlaceholderText(PlaceholderType type, std::string& text) const
603 {
604   PlaceholderHandler::GetPlaceholderText(*this, type, text);
605 }
606
607 void Controller::UpdateAfterFontChange(const std::string& newDefaultFont)
608 {
609   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::UpdateAfterFontChange\n");
610
611   if(!mImpl->mFontDefaults->familyDefined) // If user defined font then should not update when system font changes
612   {
613     DALI_LOG_INFO(gLogFilter, Debug::Concise, "Controller::UpdateAfterFontChange newDefaultFont(%s)\n", newDefaultFont.c_str());
614     mImpl->mFontDefaults->mFontDescription.family = newDefaultFont;
615
616     ClearFontData();
617
618     mImpl->RequestRelayout();
619   }
620 }
621
622 void Controller::RetrieveSelection(std::string& selectedText) const
623 {
624   mImpl->RetrieveSelection(selectedText, false);
625 }
626
627 void Controller::SetSelection(int start, int end)
628 {
629   mImpl->SetSelection(start, end);
630 }
631
632 std::pair<int, int> Controller::GetSelectionIndexes() const
633 {
634   return mImpl->GetSelectionIndexes();
635 }
636
637 void Controller::CopyStringToClipboard(const std::string& source)
638 {
639   mImpl->CopyStringToClipboard(source);
640 }
641
642 void Controller::SendSelectionToClipboard(bool deleteAfterSending)
643 {
644   mImpl->SendSelectionToClipboard(deleteAfterSending);
645 }
646
647 // public : Default style & Input style
648
649 void Controller::SetDefaultFontFamily(const std::string& defaultFontFamily)
650 {
651   if(NULL == mImpl->mFontDefaults)
652   {
653     mImpl->mFontDefaults = new FontDefaults();
654   }
655
656   mImpl->mFontDefaults->mFontDescription.family = defaultFontFamily;
657   DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetDefaultFontFamily %s\n", defaultFontFamily.c_str());
658   mImpl->mFontDefaults->familyDefined = !defaultFontFamily.empty();
659
660   if(mImpl->mEventData)
661   {
662     // Update the cursor position if it's in editing mode
663     if(EventData::IsEditingState(mImpl->mEventData->mState))
664     {
665       mImpl->mEventData->mDecoratorUpdated     = true;
666       mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font family is updated.
667     }
668   }
669
670   // Clear the font-specific data
671   ClearFontData();
672
673   mImpl->RequestRelayout();
674 }
675
676 const std::string& Controller::GetDefaultFontFamily() const
677 {
678   if(NULL != mImpl->mFontDefaults)
679   {
680     return mImpl->mFontDefaults->mFontDescription.family;
681   }
682
683   return EMPTY_STRING;
684 }
685
686 void Controller::SetPlaceholderFontFamily(const std::string& placeholderTextFontFamily)
687 {
688   PlaceholderHandler::SetPlaceholderFontFamily(*this, placeholderTextFontFamily);
689 }
690
691 const std::string& Controller::GetPlaceholderFontFamily() const
692 {
693   return PlaceholderHandler::GetPlaceholderFontFamily(*this);
694 }
695
696 void Controller::SetDefaultFontWeight(FontWeight weight)
697 {
698   if(NULL == mImpl->mFontDefaults)
699   {
700     mImpl->mFontDefaults = new FontDefaults();
701   }
702
703   mImpl->mFontDefaults->mFontDescription.weight = weight;
704   mImpl->mFontDefaults->weightDefined           = true;
705
706   if(mImpl->mEventData)
707   {
708     // Update the cursor position if it's in editing mode
709     if(EventData::IsEditingState(mImpl->mEventData->mState))
710     {
711       mImpl->mEventData->mDecoratorUpdated     = true;
712       mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font weight is updated.
713     }
714   }
715
716   // Clear the font-specific data
717   ClearFontData();
718
719   mImpl->RequestRelayout();
720 }
721
722 bool Controller::IsDefaultFontWeightDefined() const
723 {
724   if(NULL != mImpl->mFontDefaults)
725   {
726     return mImpl->mFontDefaults->weightDefined;
727   }
728
729   return false;
730 }
731
732 FontWeight Controller::GetDefaultFontWeight() const
733 {
734   if(NULL != mImpl->mFontDefaults)
735   {
736     return mImpl->mFontDefaults->mFontDescription.weight;
737   }
738
739   return TextAbstraction::FontWeight::NORMAL;
740 }
741
742 void Controller::SetPlaceholderTextFontWeight(FontWeight weight)
743 {
744   PlaceholderHandler::SetPlaceholderTextFontWeight(*this, weight);
745 }
746
747 bool Controller::IsPlaceholderTextFontWeightDefined() const
748 {
749   return PlaceholderHandler::IsPlaceholderTextFontWeightDefined(*this);
750   ;
751 }
752
753 FontWeight Controller::GetPlaceholderTextFontWeight() const
754 {
755   return PlaceholderHandler::GetPlaceholderTextFontWeight(*this);
756 }
757
758 void Controller::SetDefaultFontWidth(FontWidth width)
759 {
760   if(NULL == mImpl->mFontDefaults)
761   {
762     mImpl->mFontDefaults = new FontDefaults();
763   }
764
765   mImpl->mFontDefaults->mFontDescription.width = width;
766   mImpl->mFontDefaults->widthDefined           = true;
767
768   if(mImpl->mEventData)
769   {
770     // Update the cursor position if it's in editing mode
771     if(EventData::IsEditingState(mImpl->mEventData->mState))
772     {
773       mImpl->mEventData->mDecoratorUpdated     = true;
774       mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font width is updated.
775     }
776   }
777
778   // Clear the font-specific data
779   ClearFontData();
780
781   mImpl->RequestRelayout();
782 }
783
784 bool Controller::IsDefaultFontWidthDefined() const
785 {
786   if(NULL != mImpl->mFontDefaults)
787   {
788     return mImpl->mFontDefaults->widthDefined;
789   }
790
791   return false;
792 }
793
794 FontWidth Controller::GetDefaultFontWidth() const
795 {
796   if(NULL != mImpl->mFontDefaults)
797   {
798     return mImpl->mFontDefaults->mFontDescription.width;
799   }
800
801   return TextAbstraction::FontWidth::NORMAL;
802 }
803
804 void Controller::SetPlaceholderTextFontWidth(FontWidth width)
805 {
806   PlaceholderHandler::SetPlaceholderTextFontWidth(*this, width);
807 }
808
809 bool Controller::IsPlaceholderTextFontWidthDefined() const
810 {
811   return PlaceholderHandler::IsPlaceholderTextFontWidthDefined(*this);
812 }
813
814 FontWidth Controller::GetPlaceholderTextFontWidth() const
815 {
816   return PlaceholderHandler::GetPlaceholderTextFontWidth(*this);
817 }
818
819 void Controller::SetDefaultFontSlant(FontSlant slant)
820 {
821   if(NULL == mImpl->mFontDefaults)
822   {
823     mImpl->mFontDefaults = new FontDefaults();
824   }
825
826   mImpl->mFontDefaults->mFontDescription.slant = slant;
827   mImpl->mFontDefaults->slantDefined           = true;
828
829   if(mImpl->mEventData)
830   {
831     // Update the cursor position if it's in editing mode
832     if(EventData::IsEditingState(mImpl->mEventData->mState))
833     {
834       mImpl->mEventData->mDecoratorUpdated     = true;
835       mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font slant is updated.
836     }
837   }
838
839   // Clear the font-specific data
840   ClearFontData();
841
842   mImpl->RequestRelayout();
843 }
844
845 bool Controller::IsDefaultFontSlantDefined() const
846 {
847   if(NULL != mImpl->mFontDefaults)
848   {
849     return mImpl->mFontDefaults->slantDefined;
850   }
851   return false;
852 }
853
854 FontSlant Controller::GetDefaultFontSlant() const
855 {
856   if(NULL != mImpl->mFontDefaults)
857   {
858     return mImpl->mFontDefaults->mFontDescription.slant;
859   }
860
861   return TextAbstraction::FontSlant::NORMAL;
862 }
863
864 void Controller::SetPlaceholderTextFontSlant(FontSlant slant)
865 {
866   PlaceholderHandler::SetPlaceholderTextFontSlant(*this, slant);
867 }
868
869 bool Controller::IsPlaceholderTextFontSlantDefined() const
870 {
871   return PlaceholderHandler::IsPlaceholderTextFontSlantDefined(*this);
872 }
873
874 FontSlant Controller::GetPlaceholderTextFontSlant() const
875 {
876   return PlaceholderHandler::GetPlaceholderTextFontSlant(*this);
877 }
878
879 void Controller::SetFontSizeScale(float scale)
880 {
881   mImpl->mFontSizeScale = scale;
882
883   if(mImpl->mEventData)
884   {
885     // Update the cursor position if it's in editing mode
886     if(EventData::IsEditingState(mImpl->mEventData->mState))
887     {
888       mImpl->mEventData->mDecoratorUpdated     = true;
889       mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font size is updated.
890     }
891   }
892
893   // Clear the font-specific data
894   ClearFontData();
895
896   mImpl->RequestRelayout();
897 }
898
899 float Controller::GetFontSizeScale() const
900 {
901   if(nullptr != mImpl->mFontDefaults)
902   {
903     return mImpl->mFontSizeScale;
904   }
905
906   return 1.f;
907 }
908
909 void Controller::SetDefaultFontSize(float fontSize, FontSizeType type)
910 {
911   if(NULL == mImpl->mFontDefaults)
912   {
913     mImpl->mFontDefaults = new FontDefaults();
914   }
915
916   switch(type)
917   {
918     case POINT_SIZE:
919     {
920       mImpl->mFontDefaults->mDefaultPointSize = fontSize;
921       mImpl->mFontDefaults->sizeDefined       = true;
922       break;
923     }
924     case PIXEL_SIZE:
925     {
926       // Point size = Pixel size * 72.f / DPI
927       unsigned int                horizontalDpi = 0u;
928       unsigned int                verticalDpi   = 0u;
929       TextAbstraction::FontClient fontClient    = TextAbstraction::FontClient::Get();
930       fontClient.GetDpi(horizontalDpi, verticalDpi);
931
932       mImpl->mFontDefaults->mDefaultPointSize = (fontSize * 72.f) / static_cast<float>(horizontalDpi);
933       mImpl->mFontDefaults->sizeDefined       = true;
934       break;
935     }
936   }
937
938   if(mImpl->mEventData)
939   {
940     // Update the cursor position if it's in editing mode
941     if(EventData::IsEditingState(mImpl->mEventData->mState))
942     {
943       mImpl->mEventData->mDecoratorUpdated     = true;
944       mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font size is updated.
945     }
946   }
947
948   // Clear the font-specific data
949   ClearFontData();
950
951   mImpl->RequestRelayout();
952 }
953
954 float Controller::GetDefaultFontSize(FontSizeType type) const
955 {
956   float value = 0.0f;
957   if(NULL != mImpl->mFontDefaults)
958   {
959     switch(type)
960     {
961       case POINT_SIZE:
962       {
963         value = mImpl->mFontDefaults->mDefaultPointSize;
964         break;
965       }
966       case PIXEL_SIZE:
967       {
968         // Pixel size = Point size * DPI / 72.f
969         unsigned int                horizontalDpi = 0u;
970         unsigned int                verticalDpi   = 0u;
971         TextAbstraction::FontClient fontClient    = TextAbstraction::FontClient::Get();
972         fontClient.GetDpi(horizontalDpi, verticalDpi);
973
974         value = mImpl->mFontDefaults->mDefaultPointSize * static_cast<float>(horizontalDpi) / 72.f;
975         break;
976       }
977     }
978     return value;
979   }
980
981   return value;
982 }
983
984 void Controller::SetPlaceholderTextFontSize(float fontSize, FontSizeType type)
985 {
986   PlaceholderHandler::SetPlaceholderTextFontSize(*this, fontSize, type);
987 }
988
989 float Controller::GetPlaceholderTextFontSize(FontSizeType type) const
990 {
991   return PlaceholderHandler::GetPlaceholderTextFontSize(*this, type);
992 }
993
994 void Controller::SetDefaultColor(const Vector4& color)
995 {
996   mImpl->mTextColor = color;
997
998   if(!mImpl->IsShowingPlaceholderText())
999   {
1000     mImpl->mModel->mVisualModel->SetTextColor(color);
1001
1002     mImpl->mModel->mLogicalModel->mColorRuns.Clear();
1003
1004     mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | COLOR);
1005
1006     mImpl->RequestRelayout();
1007   }
1008 }
1009
1010 const Vector4& Controller::GetDefaultColor() const
1011 {
1012   return mImpl->mTextColor;
1013 }
1014
1015 void Controller::SetPlaceholderTextColor(const Vector4& textColor)
1016 {
1017   PlaceholderHandler::SetPlaceholderTextColor(*this, textColor);
1018 }
1019
1020 const Vector4& Controller::GetPlaceholderTextColor() const
1021 {
1022   return PlaceholderHandler::GetPlaceholderTextColor(*this);
1023 }
1024
1025 void Controller::SetShadowOffset(const Vector2& shadowOffset)
1026 {
1027   mImpl->mModel->mVisualModel->SetShadowOffset(shadowOffset);
1028
1029   mImpl->RequestRelayout();
1030 }
1031
1032 const Vector2& Controller::GetShadowOffset() const
1033 {
1034   return mImpl->mModel->mVisualModel->GetShadowOffset();
1035 }
1036
1037 void Controller::SetShadowColor(const Vector4& shadowColor)
1038 {
1039   mImpl->mModel->mVisualModel->SetShadowColor(shadowColor);
1040
1041   mImpl->RequestRelayout();
1042 }
1043
1044 const Vector4& Controller::GetShadowColor() const
1045 {
1046   return mImpl->mModel->mVisualModel->GetShadowColor();
1047 }
1048
1049 void Controller::SetShadowBlurRadius(const float& shadowBlurRadius)
1050 {
1051   if(fabsf(GetShadowBlurRadius() - shadowBlurRadius) > Math::MACHINE_EPSILON_1)
1052   {
1053     mImpl->mModel->mVisualModel->SetShadowBlurRadius(shadowBlurRadius);
1054
1055     mImpl->RequestRelayout();
1056   }
1057 }
1058
1059 const float& Controller::GetShadowBlurRadius() const
1060 {
1061   return mImpl->mModel->mVisualModel->GetShadowBlurRadius();
1062 }
1063
1064 void Controller::SetUnderlineColor(const Vector4& color)
1065 {
1066   mImpl->mModel->mVisualModel->SetUnderlineColor(color);
1067
1068   mImpl->RequestRelayout();
1069 }
1070
1071 const Vector4& Controller::GetUnderlineColor() const
1072 {
1073   return mImpl->mModel->mVisualModel->GetUnderlineColor();
1074 }
1075
1076 void Controller::SetUnderlineEnabled(bool enabled)
1077 {
1078   mImpl->mModel->mVisualModel->SetUnderlineEnabled(enabled);
1079
1080   mImpl->RequestRelayout();
1081 }
1082
1083 bool Controller::IsUnderlineEnabled() const
1084 {
1085   return mImpl->mModel->mVisualModel->IsUnderlineEnabled();
1086 }
1087
1088 void Controller::SetUnderlineHeight(float height)
1089 {
1090   mImpl->mModel->mVisualModel->SetUnderlineHeight(height);
1091
1092   mImpl->RequestRelayout();
1093 }
1094
1095 float Controller::GetUnderlineHeight() const
1096 {
1097   return mImpl->mModel->mVisualModel->GetUnderlineHeight();
1098 }
1099
1100 void Controller::SetOutlineColor(const Vector4& color)
1101 {
1102   mImpl->mModel->mVisualModel->SetOutlineColor(color);
1103
1104   mImpl->RequestRelayout();
1105 }
1106
1107 const Vector4& Controller::GetOutlineColor() const
1108 {
1109   return mImpl->mModel->mVisualModel->GetOutlineColor();
1110 }
1111
1112 void Controller::SetOutlineWidth(uint16_t width)
1113 {
1114   mImpl->mModel->mVisualModel->SetOutlineWidth(width);
1115
1116   mImpl->RequestRelayout();
1117 }
1118
1119 uint16_t Controller::GetOutlineWidth() const
1120 {
1121   return mImpl->mModel->mVisualModel->GetOutlineWidth();
1122 }
1123
1124 void Controller::SetBackgroundColor(const Vector4& color)
1125 {
1126   mImpl->mModel->mVisualModel->SetBackgroundColor(color);
1127
1128   mImpl->RequestRelayout();
1129 }
1130
1131 const Vector4& Controller::GetBackgroundColor() const
1132 {
1133   return mImpl->mModel->mVisualModel->GetBackgroundColor();
1134 }
1135
1136 void Controller::SetBackgroundEnabled(bool enabled)
1137 {
1138   mImpl->mModel->mVisualModel->SetBackgroundEnabled(enabled);
1139
1140   mImpl->RequestRelayout();
1141 }
1142
1143 bool Controller::IsBackgroundEnabled() const
1144 {
1145   return mImpl->mModel->mVisualModel->IsBackgroundEnabled();
1146 }
1147
1148 void Controller::SetDefaultEmbossProperties(const std::string& embossProperties)
1149 {
1150   if(NULL == mImpl->mEmbossDefaults)
1151   {
1152     mImpl->mEmbossDefaults = new EmbossDefaults();
1153   }
1154
1155   mImpl->mEmbossDefaults->properties = embossProperties;
1156 }
1157
1158 const std::string& Controller::GetDefaultEmbossProperties() const
1159 {
1160   if(NULL != mImpl->mEmbossDefaults)
1161   {
1162     return mImpl->mEmbossDefaults->properties;
1163   }
1164
1165   return EMPTY_STRING;
1166 }
1167
1168 void Controller::SetDefaultOutlineProperties(const std::string& outlineProperties)
1169 {
1170   if(NULL == mImpl->mOutlineDefaults)
1171   {
1172     mImpl->mOutlineDefaults = new OutlineDefaults();
1173   }
1174
1175   mImpl->mOutlineDefaults->properties = outlineProperties;
1176 }
1177
1178 const std::string& Controller::GetDefaultOutlineProperties() const
1179 {
1180   if(NULL != mImpl->mOutlineDefaults)
1181   {
1182     return mImpl->mOutlineDefaults->properties;
1183   }
1184
1185   return EMPTY_STRING;
1186 }
1187
1188 bool Controller::SetDefaultLineSpacing(float lineSpacing)
1189 {
1190   if(std::fabs(lineSpacing - mImpl->mLayoutEngine.GetDefaultLineSpacing()) > Math::MACHINE_EPSILON_1000)
1191   {
1192     mImpl->mLayoutEngine.SetDefaultLineSpacing(lineSpacing);
1193     mImpl->mRecalculateNaturalSize = true;
1194     return true;
1195   }
1196   return false;
1197 }
1198
1199 float Controller::GetDefaultLineSpacing() const
1200 {
1201   return mImpl->mLayoutEngine.GetDefaultLineSpacing();
1202 }
1203
1204 bool Controller::SetDefaultLineSize(float lineSize)
1205 {
1206   if(std::fabs(lineSize - mImpl->mLayoutEngine.GetDefaultLineSize()) > Math::MACHINE_EPSILON_1000)
1207   {
1208     mImpl->mLayoutEngine.SetDefaultLineSize(lineSize);
1209     mImpl->mRecalculateNaturalSize = true;
1210     return true;
1211   }
1212   return false;
1213 }
1214
1215 float Controller::GetDefaultLineSize() const
1216 {
1217   return mImpl->mLayoutEngine.GetDefaultLineSize();
1218 }
1219
1220 void Controller::SetInputColor(const Vector4& color)
1221 {
1222   if(NULL != mImpl->mEventData)
1223   {
1224     mImpl->mEventData->mInputStyle.textColor      = color;
1225     mImpl->mEventData->mInputStyle.isDefaultColor = false;
1226
1227     if(EventData::SELECTING == mImpl->mEventData->mState || EventData::EDITING == mImpl->mEventData->mState || EventData::INACTIVE == mImpl->mEventData->mState)
1228     {
1229       const bool handlesCrossed = mImpl->mEventData->mLeftSelectionPosition > mImpl->mEventData->mRightSelectionPosition;
1230
1231       // Get start and end position of selection
1232       const CharacterIndex startOfSelectedText  = handlesCrossed ? mImpl->mEventData->mRightSelectionPosition : mImpl->mEventData->mLeftSelectionPosition;
1233       const Length         lengthOfSelectedText = (handlesCrossed ? mImpl->mEventData->mLeftSelectionPosition : mImpl->mEventData->mRightSelectionPosition) - startOfSelectedText;
1234
1235       // Add the color run.
1236       const VectorBase::SizeType numberOfRuns = mImpl->mModel->mLogicalModel->mColorRuns.Count();
1237       mImpl->mModel->mLogicalModel->mColorRuns.Resize(numberOfRuns + 1u);
1238
1239       ColorRun& colorRun                       = *(mImpl->mModel->mLogicalModel->mColorRuns.Begin() + numberOfRuns);
1240       colorRun.color                           = color;
1241       colorRun.characterRun.characterIndex     = startOfSelectedText;
1242       colorRun.characterRun.numberOfCharacters = lengthOfSelectedText;
1243
1244       // Request to relayout.
1245       mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | COLOR);
1246       mImpl->RequestRelayout();
1247
1248       mImpl->mTextUpdateInfo.mCharacterIndex             = startOfSelectedText;
1249       mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText;
1250       mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd    = lengthOfSelectedText;
1251     }
1252   }
1253 }
1254
1255 const Vector4& Controller::GetInputColor() const
1256 {
1257   if(NULL != mImpl->mEventData)
1258   {
1259     return mImpl->mEventData->mInputStyle.textColor;
1260   }
1261
1262   // Return the default text's color if there is no EventData.
1263   return mImpl->mTextColor;
1264 }
1265
1266 void Controller::SetInputFontFamily(const std::string& fontFamily)
1267 {
1268   InputFontHandler::SetInputFontFamily(*this, fontFamily);
1269 }
1270
1271 const std::string& Controller::GetInputFontFamily() const
1272 {
1273   return InputFontHandler::GetInputFontFamily(*this);
1274 }
1275
1276 void Controller::SetInputFontWeight(FontWeight weight)
1277 {
1278   InputFontHandler::SetInputFontWeight(*this, weight);
1279 }
1280
1281 bool Controller::IsInputFontWeightDefined() const
1282 {
1283   return InputFontHandler::IsInputFontWeightDefined(*this);
1284 }
1285
1286 FontWeight Controller::GetInputFontWeight() const
1287 {
1288   return InputFontHandler::GetInputFontWeight(*this);
1289 }
1290
1291 void Controller::SetInputFontWidth(FontWidth width)
1292 {
1293   InputFontHandler::SetInputFontWidth(*this, width);
1294 }
1295
1296 bool Controller::IsInputFontWidthDefined() const
1297 {
1298   return InputFontHandler::IsInputFontWidthDefined(*this);
1299 }
1300
1301 FontWidth Controller::GetInputFontWidth() const
1302 {
1303   return InputFontHandler::GetInputFontWidth(*this);
1304 }
1305
1306 void Controller::SetInputFontSlant(FontSlant slant)
1307 {
1308   InputFontHandler::SetInputFontSlant(*this, slant);
1309 }
1310
1311 bool Controller::IsInputFontSlantDefined() const
1312 {
1313   return InputFontHandler::IsInputFontSlantDefined(*this);
1314 }
1315
1316 FontSlant Controller::GetInputFontSlant() const
1317 {
1318   return InputFontHandler::GetInputFontSlant(*this);
1319 }
1320
1321 void Controller::SetInputFontPointSize(float size)
1322 {
1323   InputFontHandler::SetInputFontPointSize(*this, size);
1324 }
1325
1326 float Controller::GetInputFontPointSize() const
1327 {
1328   return InputFontHandler::GetInputFontPointSize(*this);
1329 }
1330
1331 void Controller::SetInputLineSpacing(float lineSpacing)
1332 {
1333   if(NULL != mImpl->mEventData)
1334   {
1335     mImpl->mEventData->mInputStyle.lineSpacing          = lineSpacing;
1336     mImpl->mEventData->mInputStyle.isLineSpacingDefined = true;
1337   }
1338 }
1339
1340 float Controller::GetInputLineSpacing() const
1341 {
1342   if(NULL != mImpl->mEventData)
1343   {
1344     return mImpl->mEventData->mInputStyle.lineSpacing;
1345   }
1346
1347   return 0.f;
1348 }
1349
1350 void Controller::SetInputShadowProperties(const std::string& shadowProperties)
1351 {
1352   if(NULL != mImpl->mEventData)
1353   {
1354     mImpl->mEventData->mInputStyle.shadowProperties = shadowProperties;
1355   }
1356 }
1357
1358 const std::string& Controller::GetInputShadowProperties() const
1359 {
1360   if(NULL != mImpl->mEventData)
1361   {
1362     return mImpl->mEventData->mInputStyle.shadowProperties;
1363   }
1364
1365   return EMPTY_STRING;
1366 }
1367
1368 void Controller::SetInputUnderlineProperties(const std::string& underlineProperties)
1369 {
1370   if(NULL != mImpl->mEventData)
1371   {
1372     mImpl->mEventData->mInputStyle.underlineProperties = underlineProperties;
1373   }
1374 }
1375
1376 const std::string& Controller::GetInputUnderlineProperties() const
1377 {
1378   if(NULL != mImpl->mEventData)
1379   {
1380     return mImpl->mEventData->mInputStyle.underlineProperties;
1381   }
1382
1383   return EMPTY_STRING;
1384 }
1385
1386 void Controller::SetInputEmbossProperties(const std::string& embossProperties)
1387 {
1388   if(NULL != mImpl->mEventData)
1389   {
1390     mImpl->mEventData->mInputStyle.embossProperties = embossProperties;
1391   }
1392 }
1393
1394 const std::string& Controller::GetInputEmbossProperties() const
1395 {
1396   if(NULL != mImpl->mEventData)
1397   {
1398     return mImpl->mEventData->mInputStyle.embossProperties;
1399   }
1400
1401   return GetDefaultEmbossProperties();
1402 }
1403
1404 void Controller::SetInputOutlineProperties(const std::string& outlineProperties)
1405 {
1406   if(NULL != mImpl->mEventData)
1407   {
1408     mImpl->mEventData->mInputStyle.outlineProperties = outlineProperties;
1409   }
1410 }
1411
1412 const std::string& Controller::GetInputOutlineProperties() const
1413 {
1414   if(NULL != mImpl->mEventData)
1415   {
1416     return mImpl->mEventData->mInputStyle.outlineProperties;
1417   }
1418
1419   return GetDefaultOutlineProperties();
1420 }
1421
1422 void Controller::SetInputModePassword(bool passwordInput)
1423 {
1424   if(NULL != mImpl->mEventData)
1425   {
1426     mImpl->mEventData->mPasswordInput = passwordInput;
1427   }
1428 }
1429
1430 bool Controller::IsInputModePassword()
1431 {
1432   if(NULL != mImpl->mEventData)
1433   {
1434     return mImpl->mEventData->mPasswordInput;
1435   }
1436   return false;
1437 }
1438
1439 void Controller::SetNoTextDoubleTapAction(NoTextTap::Action action)
1440 {
1441   if(NULL != mImpl->mEventData)
1442   {
1443     mImpl->mEventData->mDoubleTapAction = action;
1444   }
1445 }
1446
1447 Controller::NoTextTap::Action Controller::GetNoTextDoubleTapAction() const
1448 {
1449   NoTextTap::Action action = NoTextTap::NO_ACTION;
1450
1451   if(NULL != mImpl->mEventData)
1452   {
1453     action = mImpl->mEventData->mDoubleTapAction;
1454   }
1455
1456   return action;
1457 }
1458
1459 void Controller::SetNoTextLongPressAction(NoTextTap::Action action)
1460 {
1461   if(NULL != mImpl->mEventData)
1462   {
1463     mImpl->mEventData->mLongPressAction = action;
1464   }
1465 }
1466
1467 Controller::NoTextTap::Action Controller::GetNoTextLongPressAction() const
1468 {
1469   NoTextTap::Action action = NoTextTap::NO_ACTION;
1470
1471   if(NULL != mImpl->mEventData)
1472   {
1473     action = mImpl->mEventData->mLongPressAction;
1474   }
1475
1476   return action;
1477 }
1478
1479 bool Controller::IsUnderlineSetByString()
1480 {
1481   return mImpl->mUnderlineSetByString;
1482 }
1483
1484 void Controller::UnderlineSetByString(bool setByString)
1485 {
1486   mImpl->mUnderlineSetByString = setByString;
1487 }
1488
1489 bool Controller::IsShadowSetByString()
1490 {
1491   return mImpl->mShadowSetByString;
1492 }
1493
1494 void Controller::ShadowSetByString(bool setByString)
1495 {
1496   mImpl->mShadowSetByString = setByString;
1497 }
1498
1499 bool Controller::IsOutlineSetByString()
1500 {
1501   return mImpl->mOutlineSetByString;
1502 }
1503
1504 void Controller::OutlineSetByString(bool setByString)
1505 {
1506   mImpl->mOutlineSetByString = setByString;
1507 }
1508
1509 bool Controller::IsFontStyleSetByString()
1510 {
1511   return mImpl->mFontStyleSetByString;
1512 }
1513
1514 void Controller::FontStyleSetByString(bool setByString)
1515 {
1516   mImpl->mFontStyleSetByString = setByString;
1517 }
1518
1519 // public : Queries & retrieves.
1520
1521 Layout::Engine& Controller::GetLayoutEngine()
1522 {
1523   return mImpl->mLayoutEngine;
1524 }
1525
1526 View& Controller::GetView()
1527 {
1528   return mImpl->mView;
1529 }
1530
1531 Vector3 Controller::GetNaturalSize()
1532 {
1533   return Relayouter::GetNaturalSize(*this);
1534 }
1535
1536 bool Controller::CheckForTextFit(float pointSize, Size& layoutSize)
1537 {
1538   return Relayouter::CheckForTextFit(*this, pointSize, layoutSize);
1539 }
1540
1541 void Controller::FitPointSizeforLayout(Size layoutSize)
1542 {
1543   Relayouter::FitPointSizeforLayout(*this, layoutSize);
1544 }
1545
1546 float Controller::GetHeightForWidth(float width)
1547 {
1548   return Relayouter::GetHeightForWidth(*this, width);
1549 }
1550
1551 int Controller::GetLineCount(float width)
1552 {
1553   GetHeightForWidth(width);
1554   int numberofLines = mImpl->mModel->GetNumberOfLines();
1555   return numberofLines;
1556 }
1557
1558 const ModelInterface* const Controller::GetTextModel() const
1559 {
1560   return mImpl->mModel.Get();
1561 }
1562
1563 float Controller::GetScrollAmountByUserInput()
1564 {
1565   float scrollAmount = 0.0f;
1566
1567   if(NULL != mImpl->mEventData && mImpl->mEventData->mCheckScrollAmount)
1568   {
1569     scrollAmount                          = mImpl->mModel->mScrollPosition.y - mImpl->mModel->mScrollPositionLast.y;
1570     mImpl->mEventData->mCheckScrollAmount = false;
1571   }
1572   return scrollAmount;
1573 }
1574
1575 bool Controller::GetTextScrollInfo(float& scrollPosition, float& controlHeight, float& layoutHeight)
1576 {
1577   const Vector2& layout = mImpl->mModel->mVisualModel->GetLayoutSize();
1578   bool           isScrolled;
1579
1580   controlHeight  = mImpl->mModel->mVisualModel->mControlSize.height;
1581   layoutHeight   = layout.height;
1582   scrollPosition = mImpl->mModel->mScrollPosition.y;
1583   isScrolled     = !Equals(mImpl->mModel->mScrollPosition.y, mImpl->mModel->mScrollPositionLast.y, Math::MACHINE_EPSILON_1);
1584   return isScrolled;
1585 }
1586
1587 void Controller::SetHiddenInputOption(const Property::Map& options)
1588 {
1589   if(NULL == mImpl->mHiddenInput)
1590   {
1591     mImpl->mHiddenInput = new HiddenText(this);
1592   }
1593   mImpl->mHiddenInput->SetProperties(options);
1594 }
1595
1596 void Controller::GetHiddenInputOption(Property::Map& options)
1597 {
1598   if(NULL != mImpl->mHiddenInput)
1599   {
1600     mImpl->mHiddenInput->GetProperties(options);
1601   }
1602 }
1603
1604 void Controller::SetPlaceholderProperty(const Property::Map& map)
1605 {
1606   PlaceholderHandler::SetPlaceholderProperty(*this, map);
1607 }
1608
1609 void Controller::GetPlaceholderProperty(Property::Map& map)
1610 {
1611   PlaceholderHandler::GetPlaceholderProperty(*this, map);
1612 }
1613
1614 Toolkit::DevelText::TextDirection::Type Controller::GetTextDirection()
1615 {
1616   // Make sure the model is up-to-date before layouting
1617   ProcessModifyEvents();
1618
1619   if(mImpl->mUpdateTextDirection)
1620   {
1621     // Operations that can be done only once until the text changes.
1622     const OperationsMask onlyOnceOperations = static_cast<OperationsMask>(CONVERT_TO_UTF32 |
1623                                                                           GET_SCRIPTS |
1624                                                                           VALIDATE_FONTS |
1625                                                                           GET_LINE_BREAKS |
1626                                                                           BIDI_INFO |
1627                                                                           SHAPE_TEXT |
1628                                                                           GET_GLYPH_METRICS);
1629
1630     // Set the update info to relayout the whole text.
1631     mImpl->mTextUpdateInfo.mParagraphCharacterIndex     = 0u;
1632     mImpl->mTextUpdateInfo.mRequestedNumberOfCharacters = mImpl->mModel->mLogicalModel->mText.Count();
1633
1634     // Make sure the model is up-to-date before layouting
1635     mImpl->UpdateModel(onlyOnceOperations);
1636
1637     Vector3 naturalSize;
1638     DoRelayout(Size(MAX_FLOAT, MAX_FLOAT),
1639                static_cast<OperationsMask>(onlyOnceOperations |
1640                                            LAYOUT | REORDER | UPDATE_DIRECTION),
1641                naturalSize.GetVectorXY());
1642
1643     // Do not do again the only once operations.
1644     mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending & ~onlyOnceOperations);
1645
1646     // Clear the update info. This info will be set the next time the text is updated.
1647     mImpl->mTextUpdateInfo.Clear();
1648
1649     // FullRelayoutNeeded should be true because DoRelayout is MAX_FLOAT, MAX_FLOAT.
1650     mImpl->mTextUpdateInfo.mFullRelayoutNeeded = true;
1651
1652     mImpl->mUpdateTextDirection = false;
1653   }
1654
1655   return mImpl->mIsTextDirectionRTL ? Toolkit::DevelText::TextDirection::RIGHT_TO_LEFT : Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT;
1656 }
1657
1658 Toolkit::DevelText::VerticalLineAlignment::Type Controller::GetVerticalLineAlignment() const
1659 {
1660   return mImpl->mModel->GetVerticalLineAlignment();
1661 }
1662
1663 void Controller::SetVerticalLineAlignment(Toolkit::DevelText::VerticalLineAlignment::Type alignment)
1664 {
1665   mImpl->mModel->mVerticalLineAlignment = alignment;
1666 }
1667
1668 // public : Relayout.
1669
1670 Controller::UpdateTextType Controller::Relayout(const Size& size, Dali::LayoutDirection::Type layoutDirection)
1671 {
1672   return Relayouter::Relayout(*this, size, layoutDirection);
1673 }
1674
1675 void Controller::RequestRelayout()
1676 {
1677   mImpl->RequestRelayout();
1678 }
1679
1680 // public : Input style change signals.
1681
1682 bool Controller::IsInputStyleChangedSignalsQueueEmpty()
1683 {
1684   return (NULL == mImpl->mEventData) || (0u == mImpl->mEventData->mInputStyleChangedQueue.Count());
1685 }
1686
1687 void Controller::ProcessInputStyleChangedSignals()
1688 {
1689   if(NULL == mImpl->mEventData)
1690   {
1691     // Nothing to do.
1692     return;
1693   }
1694
1695   for(Vector<InputStyle::Mask>::ConstIterator it    = mImpl->mEventData->mInputStyleChangedQueue.Begin(),
1696                                               endIt = mImpl->mEventData->mInputStyleChangedQueue.End();
1697       it != endIt;
1698       ++it)
1699   {
1700     const InputStyle::Mask mask = *it;
1701
1702     if(NULL != mImpl->mEditableControlInterface)
1703     {
1704       // Emit the input style changed signal.
1705       mImpl->mEditableControlInterface->InputStyleChanged(mask);
1706     }
1707   }
1708
1709   mImpl->mEventData->mInputStyleChangedQueue.Clear();
1710 }
1711
1712 // public : Text-input Event Queuing.
1713
1714 void Controller::KeyboardFocusGainEvent()
1715 {
1716   EventHandler::KeyboardFocusGainEvent(*this);
1717 }
1718
1719 void Controller::KeyboardFocusLostEvent()
1720 {
1721   EventHandler::KeyboardFocusLostEvent(*this);
1722 }
1723
1724 bool Controller::KeyEvent(const Dali::KeyEvent& keyEvent)
1725 {
1726   return EventHandler::KeyEvent(*this, keyEvent);
1727 }
1728
1729 void Controller::AnchorEvent(float x, float y)
1730 {
1731   EventHandler::AnchorEvent(*this, x, y);
1732 }
1733
1734 void Controller::TapEvent(unsigned int tapCount, float x, float y)
1735 {
1736   EventHandler::TapEvent(*this, tapCount, x, y);
1737 }
1738
1739 void Controller::PanEvent(GestureState state, const Vector2& displacement)
1740 {
1741   EventHandler::PanEvent(*this, state, displacement);
1742 }
1743
1744 void Controller::LongPressEvent(GestureState state, float x, float y)
1745 {
1746   EventHandler::LongPressEvent(*this, state, x, y);
1747 }
1748
1749 void Controller::SelectEvent(float x, float y, SelectionType selectType)
1750 {
1751   EventHandler::SelectEvent(*this, x, y, selectType);
1752 }
1753
1754 void Controller::SetTextSelectionRange(const uint32_t* start, const uint32_t* end)
1755 {
1756   if(mImpl->mEventData)
1757   {
1758     mImpl->mEventData->mCheckScrollAmount     = true;
1759     mImpl->mEventData->mIsLeftHandleSelected  = true;
1760     mImpl->mEventData->mIsRightHandleSelected = true;
1761     mImpl->SetTextSelectionRange(start, end);
1762     mImpl->RequestRelayout();
1763     KeyboardFocusGainEvent();
1764   }
1765 }
1766
1767 Uint32Pair Controller::GetTextSelectionRange() const
1768 {
1769   return mImpl->GetTextSelectionRange();
1770 }
1771
1772 CharacterIndex Controller::GetPrimaryCursorPosition() const
1773 {
1774   return mImpl->GetPrimaryCursorPosition();
1775 }
1776
1777 bool Controller::SetPrimaryCursorPosition(CharacterIndex index)
1778 {
1779   if(mImpl->mEventData)
1780   {
1781     mImpl->mEventData->mCheckScrollAmount     = true;
1782     mImpl->mEventData->mIsLeftHandleSelected  = true;
1783     mImpl->mEventData->mIsRightHandleSelected = true;
1784     mImpl->mEventData->mCheckScrollAmount     = true;
1785     if(mImpl->SetPrimaryCursorPosition(index))
1786     {
1787       KeyboardFocusGainEvent();
1788       return true;
1789     }
1790   }
1791   return false;
1792 }
1793
1794 void Controller::SelectWholeText()
1795 {
1796   SelectEvent(0.f, 0.f, SelectionType::ALL);
1797 }
1798
1799 void Controller::SelectNone()
1800 {
1801   SelectEvent(0.f, 0.f, SelectionType::NONE);
1802 }
1803
1804 string Controller::GetSelectedText() const
1805 {
1806   string text;
1807   if(EventData::SELECTING == mImpl->mEventData->mState)
1808   {
1809     mImpl->RetrieveSelection(text, false);
1810   }
1811   return text;
1812 }
1813
1814 InputMethodContext::CallbackData Controller::OnInputMethodContextEvent(InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent)
1815 {
1816   return EventHandler::OnInputMethodContextEvent(*this, inputMethodContext, inputMethodContextEvent);
1817 }
1818
1819 void Controller::PasteClipboardItemEvent()
1820 {
1821   EventHandler::PasteClipboardItemEvent(*this);
1822 }
1823
1824 // protected : Inherit from Text::Decorator::ControllerInterface.
1825
1826 void Controller::GetTargetSize(Vector2& targetSize)
1827 {
1828   targetSize = mImpl->mModel->mVisualModel->mControlSize;
1829 }
1830
1831 void Controller::AddDecoration(Actor& actor, bool needsClipping)
1832 {
1833   if(NULL != mImpl->mEditableControlInterface)
1834   {
1835     mImpl->mEditableControlInterface->AddDecoration(actor, needsClipping);
1836   }
1837 }
1838
1839 bool Controller::IsEditable() const
1840 {
1841   return mImpl->IsEditable();
1842 }
1843
1844 void Controller::SetEditable(bool editable)
1845 {
1846   mImpl->SetEditable(editable);
1847   if(mImpl->mEventData && mImpl->mEventData->mDecorator)
1848   {
1849     mImpl->mEventData->mDecorator->SetEditable(editable);
1850   }
1851 }
1852
1853 void Controller::ScrollBy(Vector2 scroll)
1854 {
1855   if(mImpl->mEventData && (fabs(scroll.x) > Math::MACHINE_EPSILON_0 || fabs(scroll.y) > Math::MACHINE_EPSILON_0))
1856   {
1857     const Vector2& layoutSize    = mImpl->mModel->mVisualModel->GetLayoutSize();
1858     const Vector2  currentScroll = mImpl->mModel->mScrollPosition;
1859
1860     scroll.x = -scroll.x;
1861     scroll.y = -scroll.y;
1862
1863     if(fabs(scroll.x) > Math::MACHINE_EPSILON_0)
1864     {
1865       mImpl->mModel->mScrollPosition.x += scroll.x;
1866       mImpl->ClampHorizontalScroll(layoutSize);
1867     }
1868
1869     if(fabs(scroll.y) > Math::MACHINE_EPSILON_0)
1870     {
1871       mImpl->mModel->mScrollPosition.y += scroll.y;
1872       mImpl->ClampVerticalScroll(layoutSize);
1873     }
1874
1875     if(mImpl->mModel->mScrollPosition != currentScroll)
1876     {
1877       mImpl->mEventData->mDecorator->UpdatePositions(mImpl->mModel->mScrollPosition - currentScroll);
1878       mImpl->RequestRelayout();
1879     }
1880   }
1881 }
1882
1883 float Controller::GetHorizontalScrollPosition()
1884 {
1885   if(mImpl->mEventData)
1886   {
1887     //scroll values are negative internally so we convert them to positive numbers
1888     return -mImpl->mModel->mScrollPosition.x;
1889   }
1890   return 0;
1891 }
1892
1893 float Controller::GetVerticalScrollPosition()
1894 {
1895   if(mImpl->mEventData)
1896   {
1897     //scroll values are negative internally so we convert them to positive numbers
1898     return -mImpl->mModel->mScrollPosition.y;
1899   }
1900   return 0;
1901 }
1902
1903 void Controller::DecorationEvent(HandleType handleType, HandleState state, float x, float y)
1904 {
1905   EventHandler::DecorationEvent(*this, handleType, state, x, y);
1906 }
1907
1908 // protected : Inherit from TextSelectionPopup::TextPopupButtonCallbackInterface.
1909
1910 void Controller::TextPopupButtonTouched(Dali::Toolkit::TextSelectionPopup::Buttons button)
1911 {
1912   EventHandler::TextPopupButtonTouched(*this, button);
1913 }
1914
1915 void Controller::DisplayTimeExpired()
1916 {
1917   mImpl->mEventData->mUpdateCursorPosition = true;
1918   // Apply modifications to the model
1919   mImpl->mOperationsPending = ALL_OPERATIONS;
1920
1921   mImpl->RequestRelayout();
1922 }
1923
1924 // private : Update.
1925
1926 void Controller::InsertText(const std::string& text, Controller::InsertType type)
1927 {
1928   TextUpdater::InsertText(*this, text, type);
1929 }
1930
1931 void Controller::PasteText(const std::string& stringToPaste)
1932 {
1933   TextUpdater::PasteText(*this, stringToPaste);
1934 }
1935
1936 bool Controller::RemoveText(int                  cursorOffset,
1937                             int                  numberOfCharacters,
1938                             UpdateInputStyleType type)
1939 {
1940   return TextUpdater::RemoveText(*this, cursorOffset, numberOfCharacters, type);
1941 }
1942
1943 bool Controller::RemoveSelectedText()
1944 {
1945   return TextUpdater::RemoveSelectedText(*this);
1946 }
1947
1948 void Controller::InsertTextAnchor(int            numberOfCharacters,
1949                                   CharacterIndex previousCursorIndex)
1950 {
1951   TextUpdater::InsertTextAnchor(*this, numberOfCharacters, previousCursorIndex);
1952 }
1953
1954 void Controller::RemoveTextAnchor(int            cursorOffset,
1955                                   int            numberOfCharacters,
1956                                   CharacterIndex previousCursorIndex)
1957 {
1958   TextUpdater::RemoveTextAnchor(*this, cursorOffset, numberOfCharacters, previousCursorIndex);
1959 }
1960
1961 // private : Relayout.
1962
1963 bool Controller::DoRelayout(const Size&    size,
1964                             OperationsMask operationsRequired,
1965                             Size&          layoutSize)
1966 {
1967   return Relayouter::DoRelayout(*this, size, operationsRequired, layoutSize);
1968 }
1969
1970 void Controller::CalculateVerticalOffset(const Size& controlSize)
1971 {
1972   Relayouter::CalculateVerticalOffset(*this, controlSize);
1973 }
1974
1975 // private : Events.
1976
1977 void Controller::ProcessModifyEvents()
1978 {
1979   EventHandler::ProcessModifyEvents(*this);
1980 }
1981
1982 void Controller::TextReplacedEvent()
1983 {
1984   EventHandler::TextReplacedEvent(*this);
1985 }
1986
1987 void Controller::TextInsertedEvent()
1988 {
1989   EventHandler::TextInsertedEvent(*this);
1990 }
1991
1992 void Controller::TextDeletedEvent()
1993 {
1994   EventHandler::TextDeletedEvent(*this);
1995 }
1996
1997 bool Controller::DeleteEvent(int keyCode)
1998 {
1999   return EventHandler::DeleteEvent(*this, keyCode);
2000 }
2001
2002 // private : Helpers.
2003
2004 void Controller::ResetText()
2005 {
2006   TextUpdater::ResetText(*this);
2007 }
2008
2009 void Controller::ShowPlaceholderText()
2010 {
2011   PlaceholderHandler::ShowPlaceholderText(*this);
2012 }
2013
2014 void Controller::ClearFontData()
2015 {
2016   if(mImpl->mFontDefaults)
2017   {
2018     mImpl->mFontDefaults->mFontId = 0u; // Remove old font ID
2019   }
2020
2021   // Set flags to update the model.
2022   mImpl->mTextUpdateInfo.mCharacterIndex             = 0u;
2023   mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters;
2024   mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd    = mImpl->mModel->mLogicalModel->mText.Count();
2025
2026   mImpl->mTextUpdateInfo.mClearAll           = true;
2027   mImpl->mTextUpdateInfo.mFullRelayoutNeeded = true;
2028   mImpl->mRecalculateNaturalSize             = true;
2029
2030   mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
2031                                                           VALIDATE_FONTS |
2032                                                           SHAPE_TEXT |
2033                                                           BIDI_INFO |
2034                                                           GET_GLYPH_METRICS |
2035                                                           LAYOUT |
2036                                                           UPDATE_LAYOUT_SIZE |
2037                                                           REORDER |
2038                                                           ALIGN);
2039 }
2040
2041 void Controller::ClearStyleData()
2042 {
2043   mImpl->mModel->mLogicalModel->mColorRuns.Clear();
2044   mImpl->mModel->mLogicalModel->ClearFontDescriptionRuns();
2045 }
2046
2047 void Controller::ResetCursorPosition(CharacterIndex cursorIndex)
2048 {
2049   // Reset the cursor position
2050   if(NULL != mImpl->mEventData)
2051   {
2052     mImpl->mEventData->mPrimaryCursorPosition = cursorIndex;
2053
2054     // Update the cursor if it's in editing mode.
2055     if(EventData::IsEditingState(mImpl->mEventData->mState))
2056     {
2057       mImpl->mEventData->mUpdateCursorPosition = true;
2058     }
2059   }
2060 }
2061
2062 CharacterIndex Controller::GetCursorPosition()
2063 {
2064   if(!mImpl->mEventData)
2065     return 0;
2066
2067   return mImpl->mEventData->mPrimaryCursorPosition;
2068 }
2069
2070 void Controller::ResetScrollPosition()
2071 {
2072   if(NULL != mImpl->mEventData)
2073   {
2074     // Reset the scroll position.
2075     mImpl->mModel->mScrollPosition                = Vector2::ZERO;
2076     mImpl->mEventData->mScrollAfterUpdatePosition = true;
2077   }
2078 }
2079
2080 void Controller::SetControlInterface(ControlInterface* controlInterface)
2081 {
2082   mImpl->mControlInterface = controlInterface;
2083 }
2084
2085 void Controller::SetAnchorControlInterface(AnchorControlInterface* anchorControlInterface)
2086 {
2087   mImpl->mAnchorControlInterface = anchorControlInterface;
2088 }
2089
2090 bool Controller::ShouldClearFocusOnEscape() const
2091 {
2092   return mImpl->mShouldClearFocusOnEscape;
2093 }
2094
2095 Actor Controller::CreateBackgroundActor()
2096 {
2097   return mImpl->CreateBackgroundActor();
2098 }
2099
2100 // private : Private contructors & copy operator.
2101
2102 Controller::Controller()
2103 : Controller(nullptr, nullptr, nullptr, nullptr)
2104 {
2105 }
2106
2107 Controller::Controller(ControlInterface* controlInterface)
2108 : Controller(controlInterface, nullptr, nullptr, nullptr)
2109 {
2110 }
2111
2112 Controller::Controller(ControlInterface*           controlInterface,
2113                        EditableControlInterface*   editableControlInterface,
2114                        SelectableControlInterface* selectableControlInterface,
2115                        AnchorControlInterface*     anchorControlInterface)
2116 : mImpl(new Controller::Impl(controlInterface, editableControlInterface, selectableControlInterface, anchorControlInterface))
2117 {
2118 }
2119
2120 // The copy constructor and operator are left unimplemented.
2121
2122 // protected : Destructor.
2123
2124 Controller::~Controller()
2125 {
2126   delete mImpl;
2127 }
2128
2129 } // namespace Text
2130
2131 } // namespace Toolkit
2132
2133 } // namespace Dali