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