Merge "Revert "Move Some Devel Properties & APIs to the Public API"" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / text-controller-impl.cpp
index dcb2901..57e51d1 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -70,11 +70,13 @@ namespace Text
 EventData::EventData( DecoratorPtr decorator )
 : mDecorator( decorator ),
   mImfManager(),
 EventData::EventData( DecoratorPtr decorator )
 : mDecorator( decorator ),
   mImfManager(),
+  mPlaceholderFont( NULL ),
   mPlaceholderTextActive(),
   mPlaceholderTextInactive(),
   mPlaceholderTextActive(),
   mPlaceholderTextInactive(),
-  mPlaceholderTextColor( 0.8f, 0.8f, 0.8f, 0.8f ),
+  mPlaceholderTextColor( 0.8f, 0.8f, 0.8f, 0.8f ), // This color has been published in the Public API (placeholder-properties.h).
   mEventQueue(),
   mInputStyleChangedQueue(),
   mEventQueue(),
   mInputStyleChangedQueue(),
+  mPreviousState( INACTIVE ),
   mState( INACTIVE ),
   mPrimaryCursorPosition( 0u ),
   mLeftSelectionPosition( 0u ),
   mState( INACTIVE ),
   mPrimaryCursorPosition( 0u ),
   mLeftSelectionPosition( 0u ),
@@ -82,6 +84,8 @@ EventData::EventData( DecoratorPtr decorator )
   mPreEditStartPosition( 0u ),
   mPreEditLength( 0u ),
   mCursorHookPositionX( 0.f ),
   mPreEditStartPosition( 0u ),
   mPreEditLength( 0u ),
   mCursorHookPositionX( 0.f ),
+  mDoubleTapAction( Controller::NoTextTap::NO_ACTION ),
+  mLongPressAction( Controller::NoTextTap::SHOW_SELECTION_POPUP ),
   mIsShowingPlaceholderText( false ),
   mPreEditFlag( false ),
   mDecoratorUpdated( false ),
   mIsShowingPlaceholderText( false ),
   mPreEditFlag( false ),
   mDecoratorUpdated( false ),
@@ -89,16 +93,23 @@ EventData::EventData( DecoratorPtr decorator )
   mGrabHandleEnabled( true ),
   mGrabHandlePopupEnabled( true ),
   mSelectionEnabled( true ),
   mGrabHandleEnabled( true ),
   mGrabHandlePopupEnabled( true ),
   mSelectionEnabled( true ),
+  mUpdateCursorHookPosition( false ),
   mUpdateCursorPosition( false ),
   mUpdateGrabHandlePosition( false ),
   mUpdateLeftSelectionPosition( false ),
   mUpdateRightSelectionPosition( false ),
   mIsLeftHandleSelected( false ),
   mUpdateCursorPosition( false ),
   mUpdateGrabHandlePosition( false ),
   mUpdateLeftSelectionPosition( false ),
   mUpdateRightSelectionPosition( false ),
   mIsLeftHandleSelected( false ),
+  mIsRightHandleSelected( false ),
   mUpdateHighlightBox( false ),
   mScrollAfterUpdatePosition( false ),
   mScrollAfterDelete( false ),
   mAllTextSelected( false ),
   mUpdateHighlightBox( false ),
   mScrollAfterUpdatePosition( false ),
   mScrollAfterDelete( false ),
   mAllTextSelected( false ),
-  mUpdateInputStyle( false )
+  mUpdateInputStyle( false ),
+  mPasswordInput( false ),
+  mIsPlaceholderPixelSize( false ),
+  mIsPlaceholderElideEnabled( false ),
+  mPlaceholderEllipsisFlag( false ),
+  mShiftSelectionFlag( true )
 {
   mImfManager = ImfManager::Get();
 }
 {
   mImfManager = ImfManager::Get();
 }
@@ -223,10 +234,25 @@ bool Controller::Impl::ProcessInputEvents()
 
       if( mEventData->mScrollAfterUpdatePosition && ( mEventData->mIsLeftHandleSelected ? mEventData->mUpdateLeftSelectionPosition : mEventData->mUpdateRightSelectionPosition ) )
       {
 
       if( mEventData->mScrollAfterUpdatePosition && ( mEventData->mIsLeftHandleSelected ? mEventData->mUpdateLeftSelectionPosition : mEventData->mUpdateRightSelectionPosition ) )
       {
-        CursorInfo& info = mEventData->mIsLeftHandleSelected ? leftHandleInfo : rightHandleInfo;
+        if( mEventData->mIsLeftHandleSelected && mEventData->mIsRightHandleSelected )
+        {
+          CursorInfo& infoLeft = leftHandleInfo;
+
+          const Vector2 currentCursorPositionLeft( infoLeft.primaryPosition.x, infoLeft.lineOffset );
+          ScrollToMakePositionVisible( currentCursorPositionLeft, infoLeft.lineHeight );
+
+          CursorInfo& infoRight = rightHandleInfo;
+
+          const Vector2 currentCursorPositionRight( infoRight.primaryPosition.x, infoRight.lineOffset );
+          ScrollToMakePositionVisible( currentCursorPositionRight, infoRight.lineHeight );
+        }
+        else
+        {
+          CursorInfo& info = mEventData->mIsLeftHandleSelected ? leftHandleInfo : rightHandleInfo;
 
 
-        const Vector2 currentCursorPosition( info.primaryPosition.x, info.lineOffset );
-        ScrollToMakePositionVisible( currentCursorPosition, info.lineHeight );
+          const Vector2 currentCursorPosition( info.primaryPosition.x, info.lineOffset );
+          ScrollToMakePositionVisible( currentCursorPosition, info.lineHeight );
+        }
       }
     }
 
       }
     }
 
@@ -257,6 +283,8 @@ bool Controller::Impl::ProcessInputEvents()
       mEventData->mUpdateLeftSelectionPosition = false;
       mEventData->mUpdateRightSelectionPosition = false;
       mEventData->mUpdateHighlightBox = false;
       mEventData->mUpdateLeftSelectionPosition = false;
       mEventData->mUpdateRightSelectionPosition = false;
       mEventData->mUpdateHighlightBox = false;
+      mEventData->mIsLeftHandleSelected = false;
+      mEventData->mIsRightHandleSelected = false;
     }
 
     mEventData->mScrollAfterUpdatePosition = false;
     }
 
     mEventData->mScrollAfterUpdatePosition = false;
@@ -275,7 +303,7 @@ bool Controller::Impl::ProcessInputEvents()
     const CharacterIndex styleIndex = ( mEventData->mPrimaryCursorPosition > 0u ) ? mEventData->mPrimaryCursorPosition - 1u : 0u;
 
     // Retrieve the style from the style runs stored in the logical model.
     const CharacterIndex styleIndex = ( mEventData->mPrimaryCursorPosition > 0u ) ? mEventData->mPrimaryCursorPosition - 1u : 0u;
 
     // Retrieve the style from the style runs stored in the logical model.
-    mLogicalModel->RetrieveStyle( styleIndex, mEventData->mInputStyle );
+    mModel->mLogicalModel->RetrieveStyle( styleIndex, mEventData->mInputStyle );
 
     // Compare if the input style has changed.
     const bool hasInputStyleChanged = !currentInputStyle.Equal( mEventData->mInputStyle );
 
     // Compare if the input style has changed.
     const bool hasInputStyleChanged = !currentInputStyle.Equal( mEventData->mInputStyle );
@@ -327,8 +355,8 @@ void Controller::Impl::NotifyImfMultiLineStatus()
 {
   if ( mEventData )
   {
 {
   if ( mEventData )
   {
-    LayoutEngine::Layout layout = mLayoutEngine.GetLayout();
-    mEventData->mImfManager.NotifyTextInputMultiLine( layout == LayoutEngine::MULTI_LINE_BOX );
+    Text::Layout::Engine::Type layout = mLayoutEngine.GetLayout();
+    mEventData->mImfManager.NotifyTextInputMultiLine( layout == Text::Layout::Engine::MULTI_LINE_BOX );
   }
 }
 
   }
 }
 
@@ -357,9 +385,9 @@ Length Controller::Impl::GetNumberOfWhiteSpaces( CharacterIndex index ) const
   Length numberOfWhiteSpaces = 0u;
 
   // Get the buffer to the text.
   Length numberOfWhiteSpaces = 0u;
 
   // Get the buffer to the text.
-  Character* utf32CharacterBuffer = mLogicalModel->mText.Begin();
+  Character* utf32CharacterBuffer = mModel->mLogicalModel->mText.Begin();
 
 
-  const Length totalNumberOfCharacters = mLogicalModel->mText.Count();
+  const Length totalNumberOfCharacters = mModel->mLogicalModel->mText.Count();
   for( ; index < totalNumberOfCharacters; ++index, ++numberOfWhiteSpaces )
   {
     if( !TextAbstraction::IsWhiteSpace( *( utf32CharacterBuffer + index ) ) )
   for( ; index < totalNumberOfCharacters; ++index, ++numberOfWhiteSpaces )
   {
     if( !TextAbstraction::IsWhiteSpace( *( utf32CharacterBuffer + index ) ) )
@@ -374,12 +402,12 @@ Length Controller::Impl::GetNumberOfWhiteSpaces( CharacterIndex index ) const
 void Controller::Impl::GetText( CharacterIndex index, std::string& text ) const
 {
   // Get the total number of characters.
 void Controller::Impl::GetText( CharacterIndex index, std::string& text ) const
 {
   // Get the total number of characters.
-  Length numberOfCharacters = mLogicalModel->mText.Count();
+  Length numberOfCharacters = mModel->mLogicalModel->mText.Count();
 
   // Retrieve the text.
   if( 0u != numberOfCharacters )
   {
 
   // Retrieve the text.
   if( 0u != numberOfCharacters )
   {
-    Utf32ToUtf8( mLogicalModel->mText.Begin() + index, numberOfCharacters - index, text );
+    Utf32ToUtf8( mModel->mLogicalModel->mText.Begin() + index, numberOfCharacters - index, text );
   }
 }
 
   }
 }
 
@@ -390,7 +418,7 @@ void Controller::Impl::CalculateTextUpdateIndices( Length& numberOfCharacters )
   mTextUpdateInfo.mStartLineIndex = 0u;
   numberOfCharacters = 0u;
 
   mTextUpdateInfo.mStartLineIndex = 0u;
   numberOfCharacters = 0u;
 
-  const Length numberOfParagraphs = mLogicalModel->mParagraphInfo.Count();
+  const Length numberOfParagraphs = mModel->mLogicalModel->mParagraphInfo.Count();
   if( 0u == numberOfParagraphs )
   {
     mTextUpdateInfo.mParagraphCharacterIndex = 0u;
   if( 0u == numberOfParagraphs )
   {
     mTextUpdateInfo.mParagraphCharacterIndex = 0u;
@@ -414,8 +442,8 @@ void Controller::Impl::CalculateTextUpdateIndices( Length& numberOfCharacters )
       numberOfCharacters = 0u;
       mTextUpdateInfo.mRequestedNumberOfCharacters = mTextUpdateInfo.mNumberOfCharactersToAdd - mTextUpdateInfo.mNumberOfCharactersToRemove;
 
       numberOfCharacters = 0u;
       mTextUpdateInfo.mRequestedNumberOfCharacters = mTextUpdateInfo.mNumberOfCharactersToAdd - mTextUpdateInfo.mNumberOfCharactersToRemove;
 
-      mTextUpdateInfo.mStartGlyphIndex = mVisualModel->mGlyphs.Count();
-      mTextUpdateInfo.mStartLineIndex = mVisualModel->mLines.Count() - 1u;
+      mTextUpdateInfo.mStartGlyphIndex = mModel->mVisualModel->mGlyphs.Count();
+      mTextUpdateInfo.mStartLineIndex = mModel->mVisualModel->mLines.Count() - 1u;
 
       // Nothing else to do;
       return;
 
       // Nothing else to do;
       return;
@@ -434,19 +462,19 @@ void Controller::Impl::CalculateTextUpdateIndices( Length& numberOfCharacters )
     {
       numberOfCharactersToUpdate = ( mTextUpdateInfo.mNumberOfCharactersToRemove > 0u ) ? mTextUpdateInfo.mNumberOfCharactersToRemove : 1u;
     }
     {
       numberOfCharactersToUpdate = ( mTextUpdateInfo.mNumberOfCharactersToRemove > 0u ) ? mTextUpdateInfo.mNumberOfCharactersToRemove : 1u;
     }
-    mLogicalModel->FindParagraphs( mTextUpdateInfo.mCharacterIndex,
-                                   numberOfCharactersToUpdate,
-                                   paragraphsToBeUpdated );
+    mModel->mLogicalModel->FindParagraphs( mTextUpdateInfo.mCharacterIndex,
+                                           numberOfCharactersToUpdate,
+                                           paragraphsToBeUpdated );
   }
 
   if( 0u != paragraphsToBeUpdated.Count() )
   {
     const ParagraphRunIndex firstParagraphIndex = *( paragraphsToBeUpdated.Begin() );
   }
 
   if( 0u != paragraphsToBeUpdated.Count() )
   {
     const ParagraphRunIndex firstParagraphIndex = *( paragraphsToBeUpdated.Begin() );
-    const ParagraphRun& firstParagraph = *( mLogicalModel->mParagraphInfo.Begin() + firstParagraphIndex );
+    const ParagraphRun& firstParagraph = *( mModel->mLogicalModel->mParagraphInfo.Begin() + firstParagraphIndex );
     mTextUpdateInfo.mParagraphCharacterIndex = firstParagraph.characterRun.characterIndex;
 
     ParagraphRunIndex lastParagraphIndex = *( paragraphsToBeUpdated.End() - 1u );
     mTextUpdateInfo.mParagraphCharacterIndex = firstParagraph.characterRun.characterIndex;
 
     ParagraphRunIndex lastParagraphIndex = *( paragraphsToBeUpdated.End() - 1u );
-    const ParagraphRun& lastParagraph = *( mLogicalModel->mParagraphInfo.Begin() + lastParagraphIndex );
+    const ParagraphRun& lastParagraph = *( mModel->mLogicalModel->mParagraphInfo.Begin() + lastParagraphIndex );
 
     if( ( mTextUpdateInfo.mNumberOfCharactersToRemove > 0u ) &&                                            // Some character are removed.
         ( lastParagraphIndex < numberOfParagraphs - 1u ) &&                                                // There is a next paragraph.
 
     if( ( mTextUpdateInfo.mNumberOfCharactersToRemove > 0u ) &&                                            // Some character are removed.
         ( lastParagraphIndex < numberOfParagraphs - 1u ) &&                                                // There is a next paragraph.
@@ -454,7 +482,7 @@ void Controller::Impl::CalculateTextUpdateIndices( Length& numberOfCharacters )
           ( mTextUpdateInfo.mCharacterIndex + mTextUpdateInfo.mNumberOfCharactersToRemove ) ) )
     {
       // The new paragraph character of the last updated paragraph has been removed so is going to be merged with the next one.
           ( mTextUpdateInfo.mCharacterIndex + mTextUpdateInfo.mNumberOfCharactersToRemove ) ) )
     {
       // The new paragraph character of the last updated paragraph has been removed so is going to be merged with the next one.
-      const ParagraphRun& lastParagraph = *( mLogicalModel->mParagraphInfo.Begin() + lastParagraphIndex + 1u );
+      const ParagraphRun& lastParagraph = *( mModel->mLogicalModel->mParagraphInfo.Begin() + lastParagraphIndex + 1u );
 
       numberOfCharacters = lastParagraph.characterRun.characterIndex + lastParagraph.characterRun.numberOfCharacters - mTextUpdateInfo.mParagraphCharacterIndex;
     }
 
       numberOfCharacters = lastParagraph.characterRun.characterIndex + lastParagraph.characterRun.numberOfCharacters - mTextUpdateInfo.mParagraphCharacterIndex;
     }
@@ -465,45 +493,45 @@ void Controller::Impl::CalculateTextUpdateIndices( Length& numberOfCharacters )
   }
 
   mTextUpdateInfo.mRequestedNumberOfCharacters = numberOfCharacters + mTextUpdateInfo.mNumberOfCharactersToAdd - mTextUpdateInfo.mNumberOfCharactersToRemove;
   }
 
   mTextUpdateInfo.mRequestedNumberOfCharacters = numberOfCharacters + mTextUpdateInfo.mNumberOfCharactersToAdd - mTextUpdateInfo.mNumberOfCharactersToRemove;
-  mTextUpdateInfo.mStartGlyphIndex = *( mVisualModel->mCharactersToGlyph.Begin() + mTextUpdateInfo.mParagraphCharacterIndex );
+  mTextUpdateInfo.mStartGlyphIndex = *( mModel->mVisualModel->mCharactersToGlyph.Begin() + mTextUpdateInfo.mParagraphCharacterIndex );
 }
 
 void Controller::Impl::ClearFullModelData( OperationsMask operations )
 {
   if( NO_OPERATION != ( GET_LINE_BREAKS & operations ) )
   {
 }
 
 void Controller::Impl::ClearFullModelData( OperationsMask operations )
 {
   if( NO_OPERATION != ( GET_LINE_BREAKS & operations ) )
   {
-    mLogicalModel->mLineBreakInfo.Clear();
-    mLogicalModel->mParagraphInfo.Clear();
+    mModel->mLogicalModel->mLineBreakInfo.Clear();
+    mModel->mLogicalModel->mParagraphInfo.Clear();
   }
 
   if( NO_OPERATION != ( GET_WORD_BREAKS & operations ) )
   {
   }
 
   if( NO_OPERATION != ( GET_WORD_BREAKS & operations ) )
   {
-    mLogicalModel->mLineBreakInfo.Clear();
+    mModel->mLogicalModel->mLineBreakInfo.Clear();
   }
 
   if( NO_OPERATION != ( GET_SCRIPTS & operations ) )
   {
   }
 
   if( NO_OPERATION != ( GET_SCRIPTS & operations ) )
   {
-    mLogicalModel->mScriptRuns.Clear();
+    mModel->mLogicalModel->mScriptRuns.Clear();
   }
 
   if( NO_OPERATION != ( VALIDATE_FONTS & operations ) )
   {
   }
 
   if( NO_OPERATION != ( VALIDATE_FONTS & operations ) )
   {
-    mLogicalModel->mFontRuns.Clear();
+    mModel->mLogicalModel->mFontRuns.Clear();
   }
 
   }
 
-  if( 0u != mLogicalModel->mBidirectionalParagraphInfo.Count() )
+  if( 0u != mModel->mLogicalModel->mBidirectionalParagraphInfo.Count() )
   {
     if( NO_OPERATION != ( BIDI_INFO & operations ) )
     {
   {
     if( NO_OPERATION != ( BIDI_INFO & operations ) )
     {
-      mLogicalModel->mBidirectionalParagraphInfo.Clear();
-      mLogicalModel->mCharacterDirections.Clear();
+      mModel->mLogicalModel->mBidirectionalParagraphInfo.Clear();
+      mModel->mLogicalModel->mCharacterDirections.Clear();
     }
 
     if( NO_OPERATION != ( REORDER & operations ) )
     {
       // Free the allocated memory used to store the conversion table in the bidirectional line info run.
     }
 
     if( NO_OPERATION != ( REORDER & operations ) )
     {
       // Free the allocated memory used to store the conversion table in the bidirectional line info run.
-      for( Vector<BidirectionalLineInfoRun>::Iterator it = mLogicalModel->mBidirectionalLineInfo.Begin(),
-             endIt = mLogicalModel->mBidirectionalLineInfo.End();
+      for( Vector<BidirectionalLineInfoRun>::Iterator it = mModel->mLogicalModel->mBidirectionalLineInfo.Begin(),
+             endIt = mModel->mLogicalModel->mBidirectionalLineInfo.End();
            it != endIt;
            ++it )
       {
            it != endIt;
            ++it )
       {
@@ -512,28 +540,28 @@ void Controller::Impl::ClearFullModelData( OperationsMask operations )
         free( bidiLineInfo.visualToLogicalMap );
         bidiLineInfo.visualToLogicalMap = NULL;
       }
         free( bidiLineInfo.visualToLogicalMap );
         bidiLineInfo.visualToLogicalMap = NULL;
       }
-      mLogicalModel->mBidirectionalLineInfo.Clear();
+      mModel->mLogicalModel->mBidirectionalLineInfo.Clear();
     }
   }
 
   if( NO_OPERATION != ( SHAPE_TEXT & operations ) )
   {
     }
   }
 
   if( NO_OPERATION != ( SHAPE_TEXT & operations ) )
   {
-    mVisualModel->mGlyphs.Clear();
-    mVisualModel->mGlyphsToCharacters.Clear();
-    mVisualModel->mCharactersToGlyph.Clear();
-    mVisualModel->mCharactersPerGlyph.Clear();
-    mVisualModel->mGlyphsPerCharacter.Clear();
-    mVisualModel->mGlyphPositions.Clear();
+    mModel->mVisualModel->mGlyphs.Clear();
+    mModel->mVisualModel->mGlyphsToCharacters.Clear();
+    mModel->mVisualModel->mCharactersToGlyph.Clear();
+    mModel->mVisualModel->mCharactersPerGlyph.Clear();
+    mModel->mVisualModel->mGlyphsPerCharacter.Clear();
+    mModel->mVisualModel->mGlyphPositions.Clear();
   }
 
   if( NO_OPERATION != ( LAYOUT & operations ) )
   {
   }
 
   if( NO_OPERATION != ( LAYOUT & operations ) )
   {
-    mVisualModel->mLines.Clear();
+    mModel->mVisualModel->mLines.Clear();
   }
 
   if( NO_OPERATION != ( COLOR & operations ) )
   {
   }
 
   if( NO_OPERATION != ( COLOR & operations ) )
   {
-    mVisualModel->mColorIndices.Clear();
+    mModel->mVisualModel->mColorIndices.Clear();
   }
 }
 
   }
 }
 
@@ -544,23 +572,23 @@ void Controller::Impl::ClearCharacterModelData( CharacterIndex startIndex, Chara
   if( NO_OPERATION != ( GET_LINE_BREAKS & operations ) )
   {
     // Clear the line break info.
   if( NO_OPERATION != ( GET_LINE_BREAKS & operations ) )
   {
     // Clear the line break info.
-    LineBreakInfo* lineBreakInfoBuffer = mLogicalModel->mLineBreakInfo.Begin();
+    LineBreakInfo* lineBreakInfoBuffer = mModel->mLogicalModel->mLineBreakInfo.Begin();
 
 
-    mLogicalModel->mLineBreakInfo.Erase( lineBreakInfoBuffer + startIndex,
-                                         lineBreakInfoBuffer + endIndexPlusOne );
+    mModel->mLogicalModel->mLineBreakInfo.Erase( lineBreakInfoBuffer + startIndex,
+                                                 lineBreakInfoBuffer + endIndexPlusOne );
 
     // Clear the paragraphs.
     ClearCharacterRuns( startIndex,
                         endIndex,
 
     // Clear the paragraphs.
     ClearCharacterRuns( startIndex,
                         endIndex,
-                        mLogicalModel->mParagraphInfo );
+                        mModel->mLogicalModel->mParagraphInfo );
   }
 
   if( NO_OPERATION != ( GET_WORD_BREAKS & operations ) )
   {
     // Clear the word break info.
   }
 
   if( NO_OPERATION != ( GET_WORD_BREAKS & operations ) )
   {
     // Clear the word break info.
-    WordBreakInfo* wordBreakInfoBuffer = mLogicalModel->mWordBreakInfo.Begin();
+    WordBreakInfo* wordBreakInfoBuffer = mModel->mLogicalModel->mWordBreakInfo.Begin();
 
 
-    mLogicalModel->mWordBreakInfo.Erase( wordBreakInfoBuffer + startIndex,
+    mModel->mLogicalModel->mWordBreakInfo.Erase( wordBreakInfoBuffer + startIndex,
                                          wordBreakInfoBuffer + endIndexPlusOne );
   }
 
                                          wordBreakInfoBuffer + endIndexPlusOne );
   }
 
@@ -569,7 +597,7 @@ void Controller::Impl::ClearCharacterModelData( CharacterIndex startIndex, Chara
     // Clear the scripts.
     ClearCharacterRuns( startIndex,
                         endIndex,
     // Clear the scripts.
     ClearCharacterRuns( startIndex,
                         endIndex,
-                        mLogicalModel->mScriptRuns );
+                        mModel->mLogicalModel->mScriptRuns );
   }
 
   if( NO_OPERATION != ( VALIDATE_FONTS & operations ) )
   }
 
   if( NO_OPERATION != ( VALIDATE_FONTS & operations ) )
@@ -577,36 +605,36 @@ void Controller::Impl::ClearCharacterModelData( CharacterIndex startIndex, Chara
     // Clear the fonts.
     ClearCharacterRuns( startIndex,
                         endIndex,
     // Clear the fonts.
     ClearCharacterRuns( startIndex,
                         endIndex,
-                        mLogicalModel->mFontRuns );
+                        mModel->mLogicalModel->mFontRuns );
   }
 
   }
 
-  if( 0u != mLogicalModel->mBidirectionalParagraphInfo.Count() )
+  if( 0u != mModel->mLogicalModel->mBidirectionalParagraphInfo.Count() )
   {
     if( NO_OPERATION != ( BIDI_INFO & operations ) )
     {
       // Clear the bidirectional paragraph info.
       ClearCharacterRuns( startIndex,
                           endIndex,
   {
     if( NO_OPERATION != ( BIDI_INFO & operations ) )
     {
       // Clear the bidirectional paragraph info.
       ClearCharacterRuns( startIndex,
                           endIndex,
-                          mLogicalModel->mBidirectionalParagraphInfo );
+                          mModel->mLogicalModel->mBidirectionalParagraphInfo );
 
       // Clear the character's directions.
 
       // Clear the character's directions.
-      CharacterDirection* characterDirectionsBuffer = mLogicalModel->mCharacterDirections.Begin();
+      CharacterDirection* characterDirectionsBuffer = mModel->mLogicalModel->mCharacterDirections.Begin();
 
 
-      mLogicalModel->mCharacterDirections.Erase( characterDirectionsBuffer + startIndex,
-                                                 characterDirectionsBuffer + endIndexPlusOne );
+      mModel->mLogicalModel->mCharacterDirections.Erase( characterDirectionsBuffer + startIndex,
+                                                         characterDirectionsBuffer + endIndexPlusOne );
     }
 
     if( NO_OPERATION != ( REORDER & operations ) )
     {
     }
 
     if( NO_OPERATION != ( REORDER & operations ) )
     {
-      uint32_t startRemoveIndex = mLogicalModel->mBidirectionalLineInfo.Count();
+      uint32_t startRemoveIndex = mModel->mLogicalModel->mBidirectionalLineInfo.Count();
       uint32_t endRemoveIndex = startRemoveIndex;
       ClearCharacterRuns( startIndex,
                           endIndex,
       uint32_t endRemoveIndex = startRemoveIndex;
       ClearCharacterRuns( startIndex,
                           endIndex,
-                          mLogicalModel->mBidirectionalLineInfo,
+                          mModel->mLogicalModel->mBidirectionalLineInfo,
                           startRemoveIndex,
                           endRemoveIndex );
 
                           startRemoveIndex,
                           endRemoveIndex );
 
-      BidirectionalLineInfoRun* bidirectionalLineInfoBuffer = mLogicalModel->mBidirectionalLineInfo.Begin();
+      BidirectionalLineInfoRun* bidirectionalLineInfoBuffer = mModel->mLogicalModel->mBidirectionalLineInfo.Begin();
 
       // Free the allocated memory used to store the conversion table in the bidirectional line info run.
       for( Vector<BidirectionalLineInfoRun>::Iterator it = bidirectionalLineInfoBuffer + startRemoveIndex,
 
       // Free the allocated memory used to store the conversion table in the bidirectional line info run.
       for( Vector<BidirectionalLineInfoRun>::Iterator it = bidirectionalLineInfoBuffer + startRemoveIndex,
@@ -620,8 +648,8 @@ void Controller::Impl::ClearCharacterModelData( CharacterIndex startIndex, Chara
         bidiLineInfo.visualToLogicalMap = NULL;
       }
 
         bidiLineInfo.visualToLogicalMap = NULL;
       }
 
-      mLogicalModel->mBidirectionalLineInfo.Erase( bidirectionalLineInfoBuffer + startRemoveIndex,
-                                                   bidirectionalLineInfoBuffer + endRemoveIndex );
+      mModel->mLogicalModel->mBidirectionalLineInfo.Erase( bidirectionalLineInfoBuffer + startRemoveIndex,
+                                                           bidirectionalLineInfoBuffer + endRemoveIndex );
     }
   }
 }
     }
   }
 }
@@ -632,8 +660,8 @@ void Controller::Impl::ClearGlyphModelData( CharacterIndex startIndex, Character
   const Length numberOfCharactersRemoved = endIndexPlusOne - startIndex;
 
   // Convert the character index to glyph index before deleting the character to glyph and the glyphs per character buffers.
   const Length numberOfCharactersRemoved = endIndexPlusOne - startIndex;
 
   // Convert the character index to glyph index before deleting the character to glyph and the glyphs per character buffers.
-  GlyphIndex* charactersToGlyphBuffer = mVisualModel->mCharactersToGlyph.Begin();
-  Length* glyphsPerCharacterBuffer = mVisualModel->mGlyphsPerCharacter.Begin();
+  GlyphIndex* charactersToGlyphBuffer = mModel->mVisualModel->mCharactersToGlyph.Begin();
+  Length* glyphsPerCharacterBuffer = mModel->mVisualModel->mGlyphsPerCharacter.Begin();
 
   const GlyphIndex endGlyphIndexPlusOne = *( charactersToGlyphBuffer + endIndex ) + *( glyphsPerCharacterBuffer + endIndex );
   const Length numberOfGlyphsRemoved = endGlyphIndexPlusOne - mTextUpdateInfo.mStartGlyphIndex;
 
   const GlyphIndex endGlyphIndexPlusOne = *( charactersToGlyphBuffer + endIndex ) + *( glyphsPerCharacterBuffer + endIndex );
   const Length numberOfGlyphsRemoved = endGlyphIndexPlusOne - mTextUpdateInfo.mStartGlyphIndex;
@@ -642,7 +670,7 @@ void Controller::Impl::ClearGlyphModelData( CharacterIndex startIndex, Character
   {
     // Update the character to glyph indices.
     for( Vector<GlyphIndex>::Iterator it =  charactersToGlyphBuffer + endIndexPlusOne,
   {
     // Update the character to glyph indices.
     for( Vector<GlyphIndex>::Iterator it =  charactersToGlyphBuffer + endIndexPlusOne,
-           endIt =  charactersToGlyphBuffer + mVisualModel->mCharactersToGlyph.Count();
+           endIt =  charactersToGlyphBuffer + mModel->mVisualModel->mCharactersToGlyph.Count();
          it != endIt;
          ++it )
     {
          it != endIt;
          ++it )
     {
@@ -651,23 +679,23 @@ void Controller::Impl::ClearGlyphModelData( CharacterIndex startIndex, Character
     }
 
     // Clear the character to glyph conversion table.
     }
 
     // Clear the character to glyph conversion table.
-    mVisualModel->mCharactersToGlyph.Erase( charactersToGlyphBuffer + startIndex,
-                                            charactersToGlyphBuffer + endIndexPlusOne );
+    mModel->mVisualModel->mCharactersToGlyph.Erase( charactersToGlyphBuffer + startIndex,
+                                                    charactersToGlyphBuffer + endIndexPlusOne );
 
     // Clear the glyphs per character table.
 
     // Clear the glyphs per character table.
-    mVisualModel->mGlyphsPerCharacter.Erase( glyphsPerCharacterBuffer + startIndex,
-                                             glyphsPerCharacterBuffer + endIndexPlusOne );
+    mModel->mVisualModel->mGlyphsPerCharacter.Erase( glyphsPerCharacterBuffer + startIndex,
+                                                     glyphsPerCharacterBuffer + endIndexPlusOne );
 
     // Clear the glyphs buffer.
 
     // Clear the glyphs buffer.
-    GlyphInfo* glyphsBuffer = mVisualModel->mGlyphs.Begin();
-    mVisualModel->mGlyphs.Erase( glyphsBuffer + mTextUpdateInfo.mStartGlyphIndex,
-                                 glyphsBuffer + endGlyphIndexPlusOne );
+    GlyphInfo* glyphsBuffer = mModel->mVisualModel->mGlyphs.Begin();
+    mModel->mVisualModel->mGlyphs.Erase( glyphsBuffer + mTextUpdateInfo.mStartGlyphIndex,
+                                         glyphsBuffer + endGlyphIndexPlusOne );
 
 
-    CharacterIndex* glyphsToCharactersBuffer = mVisualModel->mGlyphsToCharacters.Begin();
+    CharacterIndex* glyphsToCharactersBuffer = mModel->mVisualModel->mGlyphsToCharacters.Begin();
 
     // Update the glyph to character indices.
     for( Vector<CharacterIndex>::Iterator it = glyphsToCharactersBuffer + endGlyphIndexPlusOne,
 
     // Update the glyph to character indices.
     for( Vector<CharacterIndex>::Iterator it = glyphsToCharactersBuffer + endGlyphIndexPlusOne,
-           endIt = glyphsToCharactersBuffer + mVisualModel->mGlyphsToCharacters.Count();
+           endIt = glyphsToCharactersBuffer + mModel->mVisualModel->mGlyphsToCharacters.Count();
          it != endIt;
          ++it )
     {
          it != endIt;
          ++it )
     {
@@ -676,55 +704,55 @@ void Controller::Impl::ClearGlyphModelData( CharacterIndex startIndex, Character
     }
 
     // Clear the glyphs to characters buffer.
     }
 
     // Clear the glyphs to characters buffer.
-    mVisualModel->mGlyphsToCharacters.Erase( glyphsToCharactersBuffer + mTextUpdateInfo.mStartGlyphIndex,
-                                             glyphsToCharactersBuffer  + endGlyphIndexPlusOne );
+    mModel->mVisualModel->mGlyphsToCharacters.Erase( glyphsToCharactersBuffer + mTextUpdateInfo.mStartGlyphIndex,
+                                                     glyphsToCharactersBuffer  + endGlyphIndexPlusOne );
 
     // Clear the characters per glyph buffer.
 
     // Clear the characters per glyph buffer.
-    Length* charactersPerGlyphBuffer = mVisualModel->mCharactersPerGlyph.Begin();
-    mVisualModel->mCharactersPerGlyph.Erase( charactersPerGlyphBuffer + mTextUpdateInfo.mStartGlyphIndex,
-                                             charactersPerGlyphBuffer + endGlyphIndexPlusOne );
+    Length* charactersPerGlyphBuffer = mModel->mVisualModel->mCharactersPerGlyph.Begin();
+    mModel->mVisualModel->mCharactersPerGlyph.Erase( charactersPerGlyphBuffer + mTextUpdateInfo.mStartGlyphIndex,
+                                                     charactersPerGlyphBuffer + endGlyphIndexPlusOne );
 
     // Clear the positions buffer.
 
     // Clear the positions buffer.
-    Vector2* positionsBuffer = mVisualModel->mGlyphPositions.Begin();
-    mVisualModel->mGlyphPositions.Erase( positionsBuffer + mTextUpdateInfo.mStartGlyphIndex,
-                                         positionsBuffer + endGlyphIndexPlusOne );
+    Vector2* positionsBuffer = mModel->mVisualModel->mGlyphPositions.Begin();
+    mModel->mVisualModel->mGlyphPositions.Erase( positionsBuffer + mTextUpdateInfo.mStartGlyphIndex,
+                                                 positionsBuffer + endGlyphIndexPlusOne );
   }
 
   if( NO_OPERATION != ( LAYOUT & operations ) )
   {
     // Clear the lines.
   }
 
   if( NO_OPERATION != ( LAYOUT & operations ) )
   {
     // Clear the lines.
-    uint32_t startRemoveIndex = mVisualModel->mLines.Count();
+    uint32_t startRemoveIndex = mModel->mVisualModel->mLines.Count();
     uint32_t endRemoveIndex = startRemoveIndex;
     ClearCharacterRuns( startIndex,
                         endIndex,
     uint32_t endRemoveIndex = startRemoveIndex;
     ClearCharacterRuns( startIndex,
                         endIndex,
-                        mVisualModel->mLines,
+                        mModel->mVisualModel->mLines,
                         startRemoveIndex,
                         endRemoveIndex );
 
     // Will update the glyph runs.
                         startRemoveIndex,
                         endRemoveIndex );
 
     // Will update the glyph runs.
-    startRemoveIndex = mVisualModel->mLines.Count();
+    startRemoveIndex = mModel->mVisualModel->mLines.Count();
     endRemoveIndex = startRemoveIndex;
     ClearGlyphRuns( mTextUpdateInfo.mStartGlyphIndex,
                     endGlyphIndexPlusOne - 1u,
     endRemoveIndex = startRemoveIndex;
     ClearGlyphRuns( mTextUpdateInfo.mStartGlyphIndex,
                     endGlyphIndexPlusOne - 1u,
-                    mVisualModel->mLines,
+                    mModel->mVisualModel->mLines,
                     startRemoveIndex,
                     endRemoveIndex );
 
     // Set the line index from where to insert the new laid-out lines.
     mTextUpdateInfo.mStartLineIndex = startRemoveIndex;
 
                     startRemoveIndex,
                     endRemoveIndex );
 
     // Set the line index from where to insert the new laid-out lines.
     mTextUpdateInfo.mStartLineIndex = startRemoveIndex;
 
-    LineRun* linesBuffer = mVisualModel->mLines.Begin();
-    mVisualModel->mLines.Erase( linesBuffer + startRemoveIndex,
-                                linesBuffer + endRemoveIndex );
+    LineRun* linesBuffer = mModel->mVisualModel->mLines.Begin();
+    mModel->mVisualModel->mLines.Erase( linesBuffer + startRemoveIndex,
+                                        linesBuffer + endRemoveIndex );
   }
 
   if( NO_OPERATION != ( COLOR & operations ) )
   {
   }
 
   if( NO_OPERATION != ( COLOR & operations ) )
   {
-    if( 0u != mVisualModel->mColorIndices.Count() )
+    if( 0u != mModel->mVisualModel->mColorIndices.Count() )
     {
     {
-      ColorIndex* colorIndexBuffer = mVisualModel->mColorIndices.Begin();
-      mVisualModel->mColorIndices.Erase( colorIndexBuffer + mTextUpdateInfo.mStartGlyphIndex,
-                                         colorIndexBuffer + endGlyphIndexPlusOne );
+      ColorIndex* colorIndexBuffer = mModel->mVisualModel->mColorIndices.Begin();
+      mModel->mVisualModel->mColorIndices.Erase( colorIndexBuffer + mTextUpdateInfo.mStartGlyphIndex,
+                                                 colorIndexBuffer + endGlyphIndexPlusOne );
     }
   }
 }
     }
   }
 }
@@ -747,9 +775,9 @@ void Controller::Impl::ClearModelData( CharacterIndex startIndex, CharacterIndex
   }
 
   // The estimated number of lines. Used to avoid reallocations when layouting.
   }
 
   // The estimated number of lines. Used to avoid reallocations when layouting.
-  mTextUpdateInfo.mEstimatedNumberOfLines = std::max( mVisualModel->mLines.Count(), mLogicalModel->mParagraphInfo.Count() );
+  mTextUpdateInfo.mEstimatedNumberOfLines = std::max( mModel->mVisualModel->mLines.Count(), mModel->mLogicalModel->mParagraphInfo.Count() );
 
 
-  mVisualModel->ClearCaches();
+  mModel->mVisualModel->ClearCaches();
 }
 
 bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
 }
 
 bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
@@ -765,8 +793,16 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
     return false;
   }
 
     return false;
   }
 
-  Vector<Character>& utf32Characters = mLogicalModel->mText;
+  Vector<Character>& srcCharacters = mModel->mLogicalModel->mText;
+  Vector<Character> displayCharacters;
+  bool useHiddenText = false;
+  if ( mHiddenInput && mEventData != NULL && !mEventData->mIsShowingPlaceholderText)
+  {
+    mHiddenInput->Substitute( srcCharacters,displayCharacters );
+    useHiddenText = true;
+  }
 
 
+  Vector<Character>& utf32Characters = useHiddenText ? displayCharacters : srcCharacters;
   const Length numberOfCharacters = utf32Characters.Count();
 
   // Index to the first character of the first paragraph to be updated.
   const Length numberOfCharacters = utf32Characters.Count();
 
   // Index to the first character of the first paragraph to be updated.
@@ -788,7 +824,7 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
   // Whether the model is updated.
   bool updated = false;
 
   // Whether the model is updated.
   bool updated = false;
 
-  Vector<LineBreakInfo>& lineBreakInfo = mLogicalModel->mLineBreakInfo;
+  Vector<LineBreakInfo>& lineBreakInfo = mModel->mLogicalModel->mLineBreakInfo;
   const Length requestedNumberOfCharacters = mTextUpdateInfo.mRequestedNumberOfCharacters;
 
   if( NO_OPERATION != ( GET_LINE_BREAKS & operations ) )
   const Length requestedNumberOfCharacters = mTextUpdateInfo.mRequestedNumberOfCharacters;
 
   if( NO_OPERATION != ( GET_LINE_BREAKS & operations ) )
@@ -805,12 +841,12 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
                       lineBreakInfo );
 
     // Create the paragraph info.
                       lineBreakInfo );
 
     // Create the paragraph info.
-    mLogicalModel->CreateParagraphInfo( startIndex,
-                                        requestedNumberOfCharacters );
+    mModel->mLogicalModel->CreateParagraphInfo( startIndex,
+                                                requestedNumberOfCharacters );
     updated = true;
   }
 
     updated = true;
   }
 
-  Vector<WordBreakInfo>& wordBreakInfo = mLogicalModel->mWordBreakInfo;
+  Vector<WordBreakInfo>& wordBreakInfo = mModel->mLogicalModel->mWordBreakInfo;
   if( NO_OPERATION != ( GET_WORD_BREAKS & operations ) )
   {
     // Retrieves the word break info. The word break info is used to layout the text (where to wrap the text in lines).
   if( NO_OPERATION != ( GET_WORD_BREAKS & operations ) )
   {
     // Retrieves the word break info. The word break info is used to layout the text (where to wrap the text in lines).
@@ -826,8 +862,8 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
   const bool getScripts = NO_OPERATION != ( GET_SCRIPTS & operations );
   const bool validateFonts = NO_OPERATION != ( VALIDATE_FONTS & operations );
 
   const bool getScripts = NO_OPERATION != ( GET_SCRIPTS & operations );
   const bool validateFonts = NO_OPERATION != ( VALIDATE_FONTS & operations );
 
-  Vector<ScriptRun>& scripts = mLogicalModel->mScriptRuns;
-  Vector<FontRun>& validFonts = mLogicalModel->mFontRuns;
+  Vector<ScriptRun>& scripts = mModel->mLogicalModel->mScriptRuns;
+  Vector<FontRun>& validFonts = mModel->mLogicalModel->mFontRuns;
 
   if( getScripts || validateFonts )
   {
 
   if( getScripts || validateFonts )
   {
@@ -847,13 +883,24 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
     if( validateFonts )
     {
       // Validate the fonts set through the mark-up string.
     if( validateFonts )
     {
       // Validate the fonts set through the mark-up string.
-      Vector<FontDescriptionRun>& fontDescriptionRuns = mLogicalModel->mFontDescriptionRuns;
+      Vector<FontDescriptionRun>& fontDescriptionRuns = mModel->mLogicalModel->mFontDescriptionRuns;
 
       // Get the default font's description.
       TextAbstraction::FontDescription defaultFontDescription;
       TextAbstraction::PointSize26Dot6 defaultPointSize = TextAbstraction::FontClient::DEFAULT_POINT_SIZE;
 
       // Get the default font's description.
       TextAbstraction::FontDescription defaultFontDescription;
       TextAbstraction::PointSize26Dot6 defaultPointSize = TextAbstraction::FontClient::DEFAULT_POINT_SIZE;
-      if( NULL != mFontDefaults )
+
+      if( IsShowingPlaceholderText() && mEventData && ( NULL != mEventData->mPlaceholderFont ) )
+      {
+        // If the placeholder font is set specifically, only placeholder font is changed.
+        defaultFontDescription = mEventData->mPlaceholderFont->mFontDescription;
+        if( mEventData->mPlaceholderFont->sizeDefined )
+        {
+          defaultPointSize = mEventData->mPlaceholderFont->mDefaultPointSize * 64u;
+        }
+      }
+      else if( NULL != mFontDefaults )
       {
       {
+        // Set the normal font and the placeholder font.
         defaultFontDescription = mFontDefaults->mFontDescription;
         defaultPointSize = mFontDefaults->mDefaultPointSize * 64u;
       }
         defaultFontDescription = mFontDefaults->mFontDescription;
         defaultPointSize = mFontDefaults->mDefaultPointSize * 64u;
       }
@@ -874,10 +921,10 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
 
   Vector<Character> mirroredUtf32Characters;
   bool textMirrored = false;
 
   Vector<Character> mirroredUtf32Characters;
   bool textMirrored = false;
-  const Length numberOfParagraphs = mLogicalModel->mParagraphInfo.Count();
+  const Length numberOfParagraphs = mModel->mLogicalModel->mParagraphInfo.Count();
   if( NO_OPERATION != ( BIDI_INFO & operations ) )
   {
   if( NO_OPERATION != ( BIDI_INFO & operations ) )
   {
-    Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo = mLogicalModel->mBidirectionalParagraphInfo;
+    Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo = mModel->mLogicalModel->mBidirectionalParagraphInfo;
     bidirectionalInfo.Reserve( numberOfParagraphs );
 
     // Calculates the bidirectional info for the whole paragraph if it contains right to left scripts.
     bidirectionalInfo.Reserve( numberOfParagraphs );
 
     // Calculates the bidirectional info for the whole paragraph if it contains right to left scripts.
@@ -891,7 +938,7 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
     if( 0u != bidirectionalInfo.Count() )
     {
       // Only set the character directions if there is right to left characters.
     if( 0u != bidirectionalInfo.Count() )
     {
       // Only set the character directions if there is right to left characters.
-      Vector<CharacterDirection>& directions = mLogicalModel->mCharacterDirections;
+      Vector<CharacterDirection>& directions = mModel->mLogicalModel->mCharacterDirections;
       GetCharactersDirection( bidirectionalInfo,
                               numberOfCharacters,
                               startIndex,
       GetCharactersDirection( bidirectionalInfo,
                               numberOfCharacters,
                               startIndex,
@@ -911,14 +958,14 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
     else
     {
       // There is no right to left characters. Clear the directions vector.
     else
     {
       // There is no right to left characters. Clear the directions vector.
-      mLogicalModel->mCharacterDirections.Clear();
+      mModel->mLogicalModel->mCharacterDirections.Clear();
     }
     updated = true;
   }
 
     }
     updated = true;
   }
 
-  Vector<GlyphInfo>& glyphs = mVisualModel->mGlyphs;
-  Vector<CharacterIndex>& glyphsToCharactersMap = mVisualModel->mGlyphsToCharacters;
-  Vector<Length>& charactersPerGlyph = mVisualModel->mCharactersPerGlyph;
+  Vector<GlyphInfo>& glyphs = mModel->mVisualModel->mGlyphs;
+  Vector<CharacterIndex>& glyphsToCharactersMap = mModel->mVisualModel->mGlyphsToCharacters;
+  Vector<Length>& charactersPerGlyph = mModel->mVisualModel->mCharactersPerGlyph;
   Vector<GlyphIndex> newParagraphGlyphs;
   newParagraphGlyphs.Reserve( numberOfParagraphs );
 
   Vector<GlyphIndex> newParagraphGlyphs;
   newParagraphGlyphs.Reserve( numberOfParagraphs );
 
@@ -940,8 +987,8 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
                newParagraphGlyphs );
 
     // Create the 'number of glyphs' per character and the glyph to character conversion tables.
                newParagraphGlyphs );
 
     // Create the 'number of glyphs' per character and the glyph to character conversion tables.
-    mVisualModel->CreateGlyphsPerCharacterTable( startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters );
-    mVisualModel->CreateCharacterToGlyphTable( startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters );
+    mModel->mVisualModel->CreateGlyphsPerCharacterTable( startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters );
+    mModel->mVisualModel->CreateCharacterToGlyphTable( startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters );
     updated = true;
   }
 
     updated = true;
   }
 
@@ -968,25 +1015,25 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
   if( NO_OPERATION != ( COLOR & operations ) )
   {
     // Set the color runs in glyphs.
   if( NO_OPERATION != ( COLOR & operations ) )
   {
     // Set the color runs in glyphs.
-    SetColorSegmentationInfo( mLogicalModel->mColorRuns,
-                              mVisualModel->mCharactersToGlyph,
-                              mVisualModel->mGlyphsPerCharacter,
+    SetColorSegmentationInfo( mModel->mLogicalModel->mColorRuns,
+                              mModel->mVisualModel->mCharactersToGlyph,
+                              mModel->mVisualModel->mGlyphsPerCharacter,
                               startIndex,
                               mTextUpdateInfo.mStartGlyphIndex,
                               requestedNumberOfCharacters,
                               startIndex,
                               mTextUpdateInfo.mStartGlyphIndex,
                               requestedNumberOfCharacters,
-                              mVisualModel->mColors,
-                              mVisualModel->mColorIndices );
+                              mModel->mVisualModel->mColors,
+                              mModel->mVisualModel->mColorIndices );
 
     updated = true;
   }
 
   if( ( NULL != mEventData ) &&
       mEventData->mPreEditFlag &&
 
     updated = true;
   }
 
   if( ( NULL != mEventData ) &&
       mEventData->mPreEditFlag &&
-      ( 0u != mVisualModel->mCharactersToGlyph.Count() ) )
+      ( 0u != mModel->mVisualModel->mCharactersToGlyph.Count() ) )
   {
     // Add the underline for the pre-edit text.
   {
     // Add the underline for the pre-edit text.
-    const GlyphIndex* const charactersToGlyphBuffer = mVisualModel->mCharactersToGlyph.Begin();
-    const Length* const glyphsPerCharacterBuffer = mVisualModel->mGlyphsPerCharacter.Begin();
+    const GlyphIndex* const charactersToGlyphBuffer = mModel->mVisualModel->mCharactersToGlyph.Begin();
+    const Length* const glyphsPerCharacterBuffer = mModel->mVisualModel->mGlyphsPerCharacter.Begin();
 
     const GlyphIndex glyphStart = *( charactersToGlyphBuffer + mEventData->mPreEditStartPosition );
     const CharacterIndex lastPreEditCharacter = mEventData->mPreEditStartPosition + ( ( mEventData->mPreEditLength > 0u ) ? mEventData->mPreEditLength - 1u : 0u );
 
     const GlyphIndex glyphStart = *( charactersToGlyphBuffer + mEventData->mPreEditStartPosition );
     const CharacterIndex lastPreEditCharacter = mEventData->mPreEditStartPosition + ( ( mEventData->mPreEditLength > 0u ) ? mEventData->mPreEditLength - 1u : 0u );
@@ -998,11 +1045,11 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
     underlineRun.numberOfGlyphs = 1u + glyphEnd - glyphStart;
 
     // TODO: At the moment the underline runs are only for pre-edit.
     underlineRun.numberOfGlyphs = 1u + glyphEnd - glyphStart;
 
     // TODO: At the moment the underline runs are only for pre-edit.
-    mVisualModel->mUnderlineRuns.PushBack( underlineRun );
+    mModel->mVisualModel->mUnderlineRuns.PushBack( underlineRun );
   }
 
   // The estimated number of lines. Used to avoid reallocations when layouting.
   }
 
   // The estimated number of lines. Used to avoid reallocations when layouting.
-  mTextUpdateInfo.mEstimatedNumberOfLines = std::max( mVisualModel->mLines.Count(), mLogicalModel->mParagraphInfo.Count() );
+  mTextUpdateInfo.mEstimatedNumberOfLines = std::max( mModel->mVisualModel->mLines.Count(), mModel->mLogicalModel->mParagraphInfo.Count() );
 
   // Set the previous number of characters for the next time the text is updated.
   mTextUpdateInfo.mPreviousNumberOfCharacters = numberOfCharacters;
 
   // Set the previous number of characters for the next time the text is updated.
   mTextUpdateInfo.mPreviousNumberOfCharacters = numberOfCharacters;
@@ -1098,13 +1145,16 @@ float Controller::Impl::GetDefaultFontLineHeight()
 
 void Controller::Impl::OnCursorKeyEvent( const Event& event )
 {
 
 void Controller::Impl::OnCursorKeyEvent( const Event& event )
 {
-  if( NULL == mEventData )
+  if( NULL == mEventData || !IsShowingRealText() )
   {
     // Nothing to do if there is no text input.
     return;
   }
 
   int keyCode = event.p1.mInt;
   {
     // Nothing to do if there is no text input.
     return;
   }
 
   int keyCode = event.p1.mInt;
+  bool isShiftModifier = event.p2.mBool;
+
+  CharacterIndex previousPrimaryCursorPosition = mEventData->mPrimaryCursorPosition;
 
   if( Dali::DALI_KEY_CURSOR_LEFT == keyCode )
   {
 
   if( Dali::DALI_KEY_CURSOR_LEFT == keyCode )
   {
@@ -1115,13 +1165,15 @@ void Controller::Impl::OnCursorKeyEvent( const Event& event )
   }
   else if( Dali::DALI_KEY_CURSOR_RIGHT == keyCode )
   {
   }
   else if( Dali::DALI_KEY_CURSOR_RIGHT == keyCode )
   {
-    if( mLogicalModel->mText.Count() > mEventData->mPrimaryCursorPosition )
+    if( mModel->mLogicalModel->mText.Count() > mEventData->mPrimaryCursorPosition )
     {
       mEventData->mPrimaryCursorPosition = CalculateNewCursorIndex( mEventData->mPrimaryCursorPosition );
     }
   }
     {
       mEventData->mPrimaryCursorPosition = CalculateNewCursorIndex( mEventData->mPrimaryCursorPosition );
     }
   }
-  else if( Dali::DALI_KEY_CURSOR_UP == keyCode )
+  else if( Dali::DALI_KEY_CURSOR_UP == keyCode && !isShiftModifier )
   {
   {
+    // Ignore Shift-Up for text selection for now.
+
     // Get first the line index of the current cursor position index.
     CharacterIndex characterIndex = 0u;
 
     // Get first the line index of the current cursor position index.
     CharacterIndex characterIndex = 0u;
 
@@ -1130,31 +1182,34 @@ void Controller::Impl::OnCursorKeyEvent( const Event& event )
       characterIndex = mEventData->mPrimaryCursorPosition - 1u;
     }
 
       characterIndex = mEventData->mPrimaryCursorPosition - 1u;
     }
 
-    const LineIndex lineIndex = mVisualModel->GetLineOfCharacter( characterIndex );
+    const LineIndex lineIndex = mModel->mVisualModel->GetLineOfCharacter( characterIndex );
+    const LineIndex previousLineIndex = ( lineIndex > 0 ? lineIndex - 1u : lineIndex );
 
 
-    if( lineIndex > 0u )
-    {
-      // Retrieve the cursor position info.
-      CursorInfo cursorInfo;
-      GetCursorPosition( mEventData->mPrimaryCursorPosition,
-                         cursorInfo );
+    // Retrieve the cursor position info.
+    CursorInfo cursorInfo;
+    GetCursorPosition( mEventData->mPrimaryCursorPosition,
+                       cursorInfo );
 
 
-      // Get the line above.
-      const LineRun& line = *( mVisualModel->mLines.Begin() + ( lineIndex - 1u ) );
+    // Get the line above.
+    const LineRun& line = *( mModel->mVisualModel->mLines.Begin() + previousLineIndex );
 
 
-      // Get the next hit 'y' point.
-      const float hitPointY = cursorInfo.lineOffset - 0.5f * ( line.ascender - line.descender );
+    // Get the next hit 'y' point.
+    const float hitPointY = cursorInfo.lineOffset - 0.5f * ( line.ascender - line.descender );
 
 
-      // Use the cursor hook position 'x' and the next hit 'y' position to calculate the new cursor index.
-      mEventData->mPrimaryCursorPosition = Text::GetClosestCursorIndex( mVisualModel,
-                                                                        mLogicalModel,
-                                                                        mMetrics,
-                                                                        mEventData->mCursorHookPositionX,
-                                                                        hitPointY );
-    }
+    // Use the cursor hook position 'x' and the next hit 'y' position to calculate the new cursor index.
+    bool matchedCharacter = false;
+    mEventData->mPrimaryCursorPosition = Text::GetClosestCursorIndex( mModel->mVisualModel,
+                                                                      mModel->mLogicalModel,
+                                                                      mMetrics,
+                                                                      mEventData->mCursorHookPositionX,
+                                                                      hitPointY,
+                                                                      CharacterHitTest::TAP,
+                                                                      matchedCharacter );
   }
   }
-  else if(   Dali::DALI_KEY_CURSOR_DOWN == keyCode )
+  else if( Dali::DALI_KEY_CURSOR_DOWN == keyCode && !isShiftModifier )
   {
   {
+    // Ignore Shift-Down for text selection for now.
+
     // Get first the line index of the current cursor position index.
     CharacterIndex characterIndex = 0u;
 
     // Get first the line index of the current cursor position index.
     CharacterIndex characterIndex = 0u;
 
@@ -1163,9 +1218,9 @@ void Controller::Impl::OnCursorKeyEvent( const Event& event )
       characterIndex = mEventData->mPrimaryCursorPosition - 1u;
     }
 
       characterIndex = mEventData->mPrimaryCursorPosition - 1u;
     }
 
-    const LineIndex lineIndex = mVisualModel->GetLineOfCharacter( characterIndex );
+    const LineIndex lineIndex = mModel->mVisualModel->GetLineOfCharacter( characterIndex );
 
 
-    if( lineIndex + 1u < mVisualModel->mLines.Count() )
+    if( lineIndex + 1u < mModel->mVisualModel->mLines.Count() )
     {
       // Retrieve the cursor position info.
       CursorInfo cursorInfo;
     {
       // Retrieve the cursor position info.
       CursorInfo cursorInfo;
@@ -1173,21 +1228,81 @@ void Controller::Impl::OnCursorKeyEvent( const Event& event )
                          cursorInfo );
 
       // Get the line below.
                          cursorInfo );
 
       // Get the line below.
-      const LineRun& line = *( mVisualModel->mLines.Begin() + lineIndex + 1u );
+      const LineRun& line = *( mModel->mVisualModel->mLines.Begin() + lineIndex + 1u );
 
       // Get the next hit 'y' point.
       const float hitPointY = cursorInfo.lineOffset + cursorInfo.lineHeight + 0.5f * ( line.ascender - line.descender );
 
       // Use the cursor hook position 'x' and the next hit 'y' position to calculate the new cursor index.
 
       // Get the next hit 'y' point.
       const float hitPointY = cursorInfo.lineOffset + cursorInfo.lineHeight + 0.5f * ( line.ascender - line.descender );
 
       // Use the cursor hook position 'x' and the next hit 'y' position to calculate the new cursor index.
-      mEventData->mPrimaryCursorPosition = Text::GetClosestCursorIndex( mVisualModel,
-                                                                        mLogicalModel,
+      bool matchedCharacter = false;
+      mEventData->mPrimaryCursorPosition = Text::GetClosestCursorIndex( mModel->mVisualModel,
+                                                                        mModel->mLogicalModel,
                                                                         mMetrics,
                                                                         mEventData->mCursorHookPositionX,
                                                                         mMetrics,
                                                                         mEventData->mCursorHookPositionX,
-                                                                        hitPointY );
+                                                                        hitPointY,
+                                                                        CharacterHitTest::TAP,
+                                                                        matchedCharacter );
     }
   }
 
     }
   }
 
-  mEventData->mUpdateCursorPosition = true;
+  if ( !isShiftModifier && mEventData->mState != EventData::SELECTING )
+  {
+    // Update selection position after moving the cursor
+    mEventData->mLeftSelectionPosition = mEventData->mPrimaryCursorPosition;
+    mEventData->mRightSelectionPosition = mEventData->mPrimaryCursorPosition;
+  }
+
+  if ( isShiftModifier && IsShowingRealText() && mEventData->mShiftSelectionFlag )
+  {
+    // Handle text selection
+    bool selecting = false;
+
+    if ( Dali::DALI_KEY_CURSOR_LEFT == keyCode || Dali::DALI_KEY_CURSOR_RIGHT == keyCode )
+    {
+      // Shift-Left/Right to select the text
+      int cursorPositionDelta = mEventData->mPrimaryCursorPosition - previousPrimaryCursorPosition;
+      if ( cursorPositionDelta > 0 || mEventData->mRightSelectionPosition > 0u ) // Check the boundary
+      {
+        mEventData->mRightSelectionPosition += cursorPositionDelta;
+      }
+      selecting = true;
+    }
+    else if ( mEventData->mLeftSelectionPosition != mEventData->mRightSelectionPosition )
+    {
+      // Show no grab handles and text highlight if Shift-Up/Down pressed but no selected text
+      selecting = true;
+    }
+
+    if ( selecting )
+    {
+      // Notify the cursor position to the imf manager.
+      if( mEventData->mImfManager )
+      {
+        mEventData->mImfManager.SetCursorPosition( mEventData->mPrimaryCursorPosition );
+        mEventData->mImfManager.NotifyCursorPosition();
+      }
+
+      ChangeState( EventData::SELECTING );
+
+      mEventData->mUpdateLeftSelectionPosition = true;
+      mEventData->mUpdateRightSelectionPosition = true;
+      mEventData->mUpdateGrabHandlePosition = true;
+      mEventData->mUpdateHighlightBox = true;
+
+      // Hide the text selection popup if select the text using keyboard instead of moving grab handles
+      if( mEventData->mGrabHandlePopupEnabled )
+      {
+        mEventData->mDecorator->SetPopupActive( false );
+      }
+    }
+  }
+  else
+  {
+    // Handle normal cursor move
+    ChangeState( EventData::EDITING );
+    mEventData->mUpdateCursorPosition = true;
+  }
+
   mEventData->mUpdateInputStyle = true;
   mEventData->mScrollAfterUpdatePosition = true;
 }
   mEventData->mUpdateInputStyle = true;
   mEventData->mScrollAfterUpdatePosition = true;
 }
@@ -1203,17 +1318,21 @@ void Controller::Impl::OnTapEvent( const Event& event )
       if( IsShowingRealText() )
       {
         // Convert from control's coords to text's coords.
       if( IsShowingRealText() )
       {
         // Convert from control's coords to text's coords.
-        const float xPosition = event.p2.mFloat - mScrollPosition.x;
-        const float yPosition = event.p3.mFloat - mScrollPosition.y;
+        const float xPosition = event.p2.mFloat - mModel->mScrollPosition.x;
+        const float yPosition = event.p3.mFloat - mModel->mScrollPosition.y;
 
         // Keep the tap 'x' position. Used to move the cursor.
         mEventData->mCursorHookPositionX = xPosition;
 
 
         // Keep the tap 'x' position. Used to move the cursor.
         mEventData->mCursorHookPositionX = xPosition;
 
-        mEventData->mPrimaryCursorPosition = Text::GetClosestCursorIndex( mVisualModel,
-                                                                          mLogicalModel,
+        // Whether to touch point hits on a glyph.
+        bool matchedCharacter = false;
+        mEventData->mPrimaryCursorPosition = Text::GetClosestCursorIndex( mModel->mVisualModel,
+                                                                          mModel->mLogicalModel,
                                                                           mMetrics,
                                                                           xPosition,
                                                                           mMetrics,
                                                                           xPosition,
-                                                                          yPosition );
+                                                                          yPosition,
+                                                                          CharacterHitTest::TAP,
+                                                                          matchedCharacter );
 
         // When the cursor position is changing, delay cursor blinking
         mEventData->mDecorator->DelayCursorBlink();
 
         // When the cursor position is changing, delay cursor blinking
         mEventData->mDecorator->DelayCursorBlink();
@@ -1223,6 +1342,10 @@ void Controller::Impl::OnTapEvent( const Event& event )
         mEventData->mPrimaryCursorPosition = 0u;
       }
 
         mEventData->mPrimaryCursorPosition = 0u;
       }
 
+      // Update selection position after tapping
+      mEventData->mLeftSelectionPosition = mEventData->mPrimaryCursorPosition;
+      mEventData->mRightSelectionPosition = mEventData->mPrimaryCursorPosition;
+
       mEventData->mUpdateCursorPosition = true;
       mEventData->mUpdateGrabHandlePosition = true;
       mEventData->mScrollAfterUpdatePosition = true;
       mEventData->mUpdateCursorPosition = true;
       mEventData->mUpdateGrabHandlePosition = true;
       mEventData->mScrollAfterUpdatePosition = true;
@@ -1235,6 +1358,20 @@ void Controller::Impl::OnTapEvent( const Event& event )
         mEventData->mImfManager.NotifyCursorPosition();
       }
     }
         mEventData->mImfManager.NotifyCursorPosition();
       }
     }
+    else if( 2u == tapCount )
+    {
+      if( mEventData->mSelectionEnabled )
+      {
+        // Convert from control's coords to text's coords.
+        const float xPosition = event.p2.mFloat - mModel->mScrollPosition.x;
+        const float yPosition = event.p3.mFloat - mModel->mScrollPosition.y;
+
+        // Calculates the logical position from the x,y coords.
+        RepositionSelectionHandles( xPosition,
+                                    yPosition,
+                                    mEventData->mDoubleTapAction );
+      }
+    }
   }
 }
 
   }
 }
 
@@ -1267,13 +1404,13 @@ void Controller::Impl::OnPanEvent( const Event& event )
     }
     case Gesture::Continuing:
     {
     }
     case Gesture::Continuing:
     {
-      const Vector2& layoutSize = mVisualModel->GetLayoutSize();
-      const Vector2 currentScroll = mScrollPosition;
+      const Vector2& layoutSize = mModel->mVisualModel->GetLayoutSize();
+      const Vector2 currentScroll = mModel->mScrollPosition;
 
       if( isHorizontalScrollEnabled )
       {
         const float displacementX = event.p2.mFloat;
 
       if( isHorizontalScrollEnabled )
       {
         const float displacementX = event.p2.mFloat;
-        mScrollPosition.x += displacementX;
+        mModel->mScrollPosition.x += displacementX;
 
         ClampHorizontalScroll( layoutSize );
       }
 
         ClampHorizontalScroll( layoutSize );
       }
@@ -1281,12 +1418,12 @@ void Controller::Impl::OnPanEvent( const Event& event )
       if( isVerticalScrollEnabled )
       {
         const float displacementY = event.p3.mFloat;
       if( isVerticalScrollEnabled )
       {
         const float displacementY = event.p3.mFloat;
-        mScrollPosition.y += displacementY;
+        mModel->mScrollPosition.y += displacementY;
 
         ClampVerticalScroll( layoutSize );
       }
 
 
         ClampVerticalScroll( layoutSize );
       }
 
-      mEventData->mDecorator->UpdatePositions( mScrollPosition - currentScroll );
+      mEventData->mDecorator->UpdatePositions( mModel->mScrollPosition - currentScroll );
       break;
     }
     case Gesture::Finished:
       break;
     }
     case Gesture::Finished:
@@ -1305,10 +1442,25 @@ void Controller::Impl::OnLongPressEvent( const Event& event )
 {
   DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::OnLongPressEvent\n" );
 
 {
   DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::OnLongPressEvent\n" );
 
-  if( EventData::EDITING == mEventData->mState )
+  if( !IsShowingRealText() && ( EventData::EDITING == mEventData->mState ) )
   {
   {
-    ChangeState ( EventData::EDITING_WITH_POPUP );
+    ChangeState( EventData::EDITING_WITH_POPUP );
     mEventData->mDecoratorUpdated = true;
     mEventData->mDecoratorUpdated = true;
+    mEventData->mUpdateInputStyle = true;
+  }
+  else
+  {
+    if( mEventData->mSelectionEnabled )
+    {
+      // Convert from control's coords to text's coords.
+      const float xPosition = event.p2.mFloat - mModel->mScrollPosition.x;
+      const float yPosition = event.p3.mFloat - mModel->mScrollPosition.y;
+
+      // Calculates the logical position from the x,y coords.
+      RepositionSelectionHandles( xPosition,
+                                  yPosition,
+                                  mEventData->mLongPressAction );
+    }
   }
 }
 
   }
 }
 
@@ -1327,15 +1479,18 @@ void Controller::Impl::OnHandleEvent( const Event& event )
   if( HANDLE_PRESSED == state )
   {
     // Convert from decorator's coords to text's coords.
   if( HANDLE_PRESSED == state )
   {
     // Convert from decorator's coords to text's coords.
-    const float xPosition = event.p2.mFloat - mScrollPosition.x;
-    const float yPosition = event.p3.mFloat - mScrollPosition.y;
+    const float xPosition = event.p2.mFloat - mModel->mScrollPosition.x;
+    const float yPosition = event.p3.mFloat - mModel->mScrollPosition.y;
 
     // Need to calculate the handle's new position.
 
     // Need to calculate the handle's new position.
-    const CharacterIndex handleNewPosition = Text::GetClosestCursorIndex( mVisualModel,
-                                                                          mLogicalModel,
+    bool matchedCharacter = false;
+    const CharacterIndex handleNewPosition = Text::GetClosestCursorIndex( mModel->mVisualModel,
+                                                                          mModel->mLogicalModel,
                                                                           mMetrics,
                                                                           xPosition,
                                                                           mMetrics,
                                                                           xPosition,
-                                                                          yPosition );
+                                                                          yPosition,
+                                                                          CharacterHitTest::SCROLL,
+                                                                          matchedCharacter );
 
     if( Event::GRAB_HANDLE_EVENT == event.type )
     {
 
     if( Event::GRAB_HANDLE_EVENT == event.type )
     {
@@ -1372,6 +1527,7 @@ void Controller::Impl::OnHandleEvent( const Event& event )
 
       // Will define the order to scroll the text to match the handle position.
       mEventData->mIsLeftHandleSelected = true;
 
       // Will define the order to scroll the text to match the handle position.
       mEventData->mIsLeftHandleSelected = true;
+      mEventData->mIsRightHandleSelected = false;
     }
     else if( Event::RIGHT_SELECTION_HANDLE_EVENT == event.type )
     {
     }
     else if( Event::RIGHT_SELECTION_HANDLE_EVENT == event.type )
     {
@@ -1392,6 +1548,7 @@ void Controller::Impl::OnHandleEvent( const Event& event )
 
       // Will define the order to scroll the text to match the handle position.
       mEventData->mIsLeftHandleSelected = false;
 
       // Will define the order to scroll the text to match the handle position.
       mEventData->mIsLeftHandleSelected = false;
+      mEventData->mIsRightHandleSelected = true;
     }
   } // end ( HANDLE_PRESSED == state )
   else if( ( HANDLE_RELEASED == state ) ||
     }
   } // end ( HANDLE_PRESSED == state )
   else if( ( HANDLE_RELEASED == state ) ||
@@ -1401,14 +1558,17 @@ void Controller::Impl::OnHandleEvent( const Event& event )
     if( handleStopScrolling || isSmoothHandlePanEnabled )
     {
       // Convert from decorator's coords to text's coords.
     if( handleStopScrolling || isSmoothHandlePanEnabled )
     {
       // Convert from decorator's coords to text's coords.
-      const float xPosition = event.p2.mFloat - mScrollPosition.x;
-      const float yPosition = event.p3.mFloat - mScrollPosition.y;
+      const float xPosition = event.p2.mFloat - mModel->mScrollPosition.x;
+      const float yPosition = event.p3.mFloat - mModel->mScrollPosition.y;
 
 
-      handlePosition = Text::GetClosestCursorIndex( mVisualModel,
-                                                    mLogicalModel,
+      bool matchedCharacter = false;
+      handlePosition = Text::GetClosestCursorIndex( mModel->mVisualModel,
+                                                    mModel->mLogicalModel,
                                                     mMetrics,
                                                     xPosition,
                                                     mMetrics,
                                                     xPosition,
-                                                    yPosition );
+                                                    yPosition,
+                                                    CharacterHitTest::SCROLL,
+                                                    matchedCharacter );
     }
 
     if( Event::GRAB_HANDLE_EVENT == event.type )
     }
 
     if( Event::GRAB_HANDLE_EVENT == event.type )
@@ -1472,17 +1632,17 @@ void Controller::Impl::OnHandleEvent( const Event& event )
   {
     const float xSpeed = event.p2.mFloat;
     const float ySpeed = event.p3.mFloat;
   {
     const float xSpeed = event.p2.mFloat;
     const float ySpeed = event.p3.mFloat;
-    const Vector2& layoutSize = mVisualModel->GetLayoutSize();
-    const Vector2 currentScrollPosition = mScrollPosition;
+    const Vector2& layoutSize = mModel->mVisualModel->GetLayoutSize();
+    const Vector2 currentScrollPosition = mModel->mScrollPosition;
 
 
-    mScrollPosition.x += xSpeed;
-    mScrollPosition.y += ySpeed;
+    mModel->mScrollPosition.x += xSpeed;
+    mModel->mScrollPosition.y += ySpeed;
 
     ClampHorizontalScroll( layoutSize );
     ClampVerticalScroll( layoutSize );
 
     bool endOfScroll = false;
 
     ClampHorizontalScroll( layoutSize );
     ClampVerticalScroll( layoutSize );
 
     bool endOfScroll = false;
-    if( Vector2::ZERO == ( currentScrollPosition - mScrollPosition ) )
+    if( Vector2::ZERO == ( currentScrollPosition - mModel->mScrollPosition ) )
     {
       // Notify the decorator there is no more text to scroll.
       // The decorator won't send more scroll events.
     {
       // Notify the decorator there is no more text to scroll.
       // The decorator won't send more scroll events.
@@ -1507,7 +1667,7 @@ void Controller::Impl::OnHandleEvent( const Event& event )
       if( mEventData->mDecorator->IsHorizontalScrollEnabled() )
       {
         // Position the grag handle close to either the left or right edge.
       if( mEventData->mDecorator->IsHorizontalScrollEnabled() )
       {
         // Position the grag handle close to either the left or right edge.
-        position.x = scrollRightDirection ? 0.f : mVisualModel->mControlSize.width;
+        position.x = scrollRightDirection ? 0.f : mModel->mVisualModel->mControlSize.width;
       }
 
       if( mEventData->mDecorator->IsVerticalScrollEnabled() )
       }
 
       if( mEventData->mDecorator->IsVerticalScrollEnabled() )
@@ -1515,16 +1675,19 @@ void Controller::Impl::OnHandleEvent( const Event& event )
         position.x = mEventData->mCursorHookPositionX;
 
         // Position the grag handle close to either the top or bottom edge.
         position.x = mEventData->mCursorHookPositionX;
 
         // Position the grag handle close to either the top or bottom edge.
-        position.y = scrollBottomDirection ? 0.f : mVisualModel->mControlSize.height;
+        position.y = scrollBottomDirection ? 0.f : mModel->mVisualModel->mControlSize.height;
       }
 
       // Get the new handle position.
       // The grab handle's position is in decorator's coords. Need to transforms to text's coords.
       }
 
       // Get the new handle position.
       // The grab handle's position is in decorator's coords. Need to transforms to text's coords.
-      const CharacterIndex handlePosition = Text::GetClosestCursorIndex( mVisualModel,
-                                                                         mLogicalModel,
+      bool matchedCharacter = false;
+      const CharacterIndex handlePosition = Text::GetClosestCursorIndex( mModel->mVisualModel,
+                                                                         mModel->mLogicalModel,
                                                                          mMetrics,
                                                                          mMetrics,
-                                                                         position.x - mScrollPosition.x,
-                                                                         position.y - mScrollPosition.y );
+                                                                         position.x - mModel->mScrollPosition.x,
+                                                                         position.y - mModel->mScrollPosition.y,
+                                                                         CharacterHitTest::SCROLL,
+                                                                         matchedCharacter );
 
       if( mEventData->mPrimaryCursorPosition != handlePosition )
       {
 
       if( mEventData->mPrimaryCursorPosition != handlePosition )
       {
@@ -1548,7 +1711,7 @@ void Controller::Impl::OnHandleEvent( const Event& event )
       if( mEventData->mDecorator->IsHorizontalScrollEnabled() )
       {
         // Position the selection handle close to either the left or right edge.
       if( mEventData->mDecorator->IsHorizontalScrollEnabled() )
       {
         // Position the selection handle close to either the left or right edge.
-        position.x = scrollRightDirection ? 0.f : mVisualModel->mControlSize.width;
+        position.x = scrollRightDirection ? 0.f : mModel->mVisualModel->mControlSize.width;
       }
 
       if( mEventData->mDecorator->IsVerticalScrollEnabled() )
       }
 
       if( mEventData->mDecorator->IsVerticalScrollEnabled() )
@@ -1556,16 +1719,19 @@ void Controller::Impl::OnHandleEvent( const Event& event )
         position.x = mEventData->mCursorHookPositionX;
 
         // Position the grag handle close to either the top or bottom edge.
         position.x = mEventData->mCursorHookPositionX;
 
         // Position the grag handle close to either the top or bottom edge.
-        position.y = scrollBottomDirection ? 0.f : mVisualModel->mControlSize.height;
+        position.y = scrollBottomDirection ? 0.f : mModel->mVisualModel->mControlSize.height;
       }
 
       // Get the new handle position.
       // The selection handle's position is in decorator's coords. Need to transform to text's coords.
       }
 
       // Get the new handle position.
       // The selection handle's position is in decorator's coords. Need to transform to text's coords.
-      const CharacterIndex handlePosition = Text::GetClosestCursorIndex( mVisualModel,
-                                                                         mLogicalModel,
+      bool matchedCharacter = false;
+      const CharacterIndex handlePosition = Text::GetClosestCursorIndex( mModel->mVisualModel,
+                                                                         mModel->mLogicalModel,
                                                                          mMetrics,
                                                                          mMetrics,
-                                                                         position.x - mScrollPosition.x,
-                                                                         position.y - mScrollPosition.y );
+                                                                         position.x - mModel->mScrollPosition.x,
+                                                                         position.y - mModel->mScrollPosition.y,
+                                                                         CharacterHitTest::SCROLL,
+                                                                         matchedCharacter );
 
       if( leftSelectionHandleEvent )
       {
 
       if( leftSelectionHandleEvent )
       {
@@ -1613,12 +1779,13 @@ void Controller::Impl::OnSelectEvent( const Event& event )
   if( mEventData->mSelectionEnabled )
   {
     // Convert from control's coords to text's coords.
   if( mEventData->mSelectionEnabled )
   {
     // Convert from control's coords to text's coords.
-    const float xPosition = event.p2.mFloat - mScrollPosition.x;
-    const float yPosition = event.p3.mFloat - mScrollPosition.y;
+    const float xPosition = event.p2.mFloat - mModel->mScrollPosition.x;
+    const float yPosition = event.p3.mFloat - mModel->mScrollPosition.y;
 
     // Calculates the logical position from the x,y coords.
     RepositionSelectionHandles( xPosition,
 
     // Calculates the logical position from the x,y coords.
     RepositionSelectionHandles( xPosition,
-                                yPosition );
+                                yPosition,
+                                Controller::NoTextTap::HIGHLIGHT );
   }
 }
 
   }
 }
 
@@ -1637,7 +1804,7 @@ void Controller::Impl::OnSelectAllEvent()
     ChangeState( EventData::SELECTING );
 
     mEventData->mLeftSelectionPosition = 0u;
     ChangeState( EventData::SELECTING );
 
     mEventData->mLeftSelectionPosition = 0u;
-    mEventData->mRightSelectionPosition = mLogicalModel->mText.Count();
+    mEventData->mRightSelectionPosition = mModel->mLogicalModel->mText.Count();
 
     mEventData->mScrollAfterUpdatePosition = true;
     mEventData->mUpdateLeftSelectionPosition = true;
 
     mEventData->mScrollAfterUpdatePosition = true;
     mEventData->mUpdateLeftSelectionPosition = true;
@@ -1661,7 +1828,7 @@ void Controller::Impl::RetrieveSelection( std::string& selectedText, bool delete
   const CharacterIndex startOfSelectedText = handlesCrossed ? mEventData->mRightSelectionPosition : mEventData->mLeftSelectionPosition;
   const Length lengthOfSelectedText = ( handlesCrossed ? mEventData->mLeftSelectionPosition : mEventData->mRightSelectionPosition ) - startOfSelectedText;
 
   const CharacterIndex startOfSelectedText = handlesCrossed ? mEventData->mRightSelectionPosition : mEventData->mLeftSelectionPosition;
   const Length lengthOfSelectedText = ( handlesCrossed ? mEventData->mLeftSelectionPosition : mEventData->mRightSelectionPosition ) - startOfSelectedText;
 
-  Vector<Character>& utf32Characters = mLogicalModel->mText;
+  Vector<Character>& utf32Characters = mModel->mLogicalModel->mText;
   const Length numberOfCharacters = utf32Characters.Count();
 
   // Validate the start and end selection points
   const Length numberOfCharacters = utf32Characters.Count();
 
   // Validate the start and end selection points
@@ -1677,7 +1844,7 @@ void Controller::Impl::RetrieveSelection( std::string& selectedText, bool delete
       currentInputStyle.Copy( mEventData->mInputStyle );
 
       // Set as input style the style of the first deleted character.
       currentInputStyle.Copy( mEventData->mInputStyle );
 
       // Set as input style the style of the first deleted character.
-      mLogicalModel->RetrieveStyle( startOfSelectedText, mEventData->mInputStyle );
+      mModel->mLogicalModel->RetrieveStyle( startOfSelectedText, mEventData->mInputStyle );
 
       // Compare if the input style has changed.
       const bool hasInputStyleChanged = !currentInputStyle.Equal( mEventData->mInputStyle );
 
       // Compare if the input style has changed.
       const bool hasInputStyleChanged = !currentInputStyle.Equal( mEventData->mInputStyle );
@@ -1689,11 +1856,21 @@ void Controller::Impl::RetrieveSelection( std::string& selectedText, bool delete
         mEventData->mInputStyleChangedQueue.PushBack( styleChangedMask );
       }
 
         mEventData->mInputStyleChangedQueue.PushBack( styleChangedMask );
       }
 
-      mLogicalModel->UpdateTextStyleRuns( startOfSelectedText, -static_cast<int>( lengthOfSelectedText ) );
+      mModel->mLogicalModel->UpdateTextStyleRuns( startOfSelectedText, -static_cast<int>( lengthOfSelectedText ) );
 
       // Mark the paragraphs to be updated.
 
       // Mark the paragraphs to be updated.
-      mTextUpdateInfo.mCharacterIndex = startOfSelectedText;
-      mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText;
+      if( Layout::Engine::SINGLE_LINE_BOX == mLayoutEngine.GetLayout() )
+      {
+        mTextUpdateInfo.mCharacterIndex = 0;
+        mTextUpdateInfo.mNumberOfCharactersToRemove = mTextUpdateInfo.mPreviousNumberOfCharacters;
+        mTextUpdateInfo.mNumberOfCharactersToAdd = mTextUpdateInfo.mPreviousNumberOfCharacters - lengthOfSelectedText;
+        mTextUpdateInfo.mClearAll = true;
+      }
+      else
+      {
+        mTextUpdateInfo.mCharacterIndex = startOfSelectedText;
+        mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText;
+      }
 
       // Delete text between handles
       Vector<Character>::Iterator first = utf32Characters.Begin() + startOfSelectedText;
 
       // Delete text between handles
       Vector<Character>::Iterator first = utf32Characters.Begin() + startOfSelectedText;
@@ -1769,15 +1946,15 @@ void Controller::Impl::RepositionSelectionHandles()
 
   mEventData->mDecorator->ClearHighlights();
 
 
   mEventData->mDecorator->ClearHighlights();
 
-  const GlyphIndex* const charactersToGlyphBuffer = mVisualModel->mCharactersToGlyph.Begin();
-  const Length* const glyphsPerCharacterBuffer = mVisualModel->mGlyphsPerCharacter.Begin();
-  const GlyphInfo* const glyphsBuffer = mVisualModel->mGlyphs.Begin();
-  const Vector2* const positionsBuffer = mVisualModel->mGlyphPositions.Begin();
-  const Length* const charactersPerGlyphBuffer = mVisualModel->mCharactersPerGlyph.Begin();
-  const CharacterIndex* const glyphToCharacterBuffer = mVisualModel->mGlyphsToCharacters.Begin();
-  const CharacterDirection* const modelCharacterDirectionsBuffer = ( 0u != mLogicalModel->mCharacterDirections.Count() ) ? mLogicalModel->mCharacterDirections.Begin() : NULL;
+  const GlyphIndex* const charactersToGlyphBuffer = mModel->mVisualModel->mCharactersToGlyph.Begin();
+  const Length* const glyphsPerCharacterBuffer = mModel->mVisualModel->mGlyphsPerCharacter.Begin();
+  const GlyphInfo* const glyphsBuffer = mModel->mVisualModel->mGlyphs.Begin();
+  const Vector2* const positionsBuffer = mModel->mVisualModel->mGlyphPositions.Begin();
+  const Length* const charactersPerGlyphBuffer = mModel->mVisualModel->mCharactersPerGlyph.Begin();
+  const CharacterIndex* const glyphToCharacterBuffer = mModel->mVisualModel->mGlyphsToCharacters.Begin();
+  const CharacterDirection* const modelCharacterDirectionsBuffer = ( 0u != mModel->mLogicalModel->mCharacterDirections.Count() ) ? mModel->mLogicalModel->mCharacterDirections.Begin() : NULL;
 
 
-  const bool isLastCharacter = selectionEnd >= mLogicalModel->mText.Count();
+  const bool isLastCharacter = selectionEnd >= mModel->mLogicalModel->mText.Count();
   const CharacterDirection startDirection = ( ( NULL == modelCharacterDirectionsBuffer ) ? false : *( modelCharacterDirectionsBuffer + selectionStart ) );
   const CharacterDirection endDirection = ( ( NULL == modelCharacterDirectionsBuffer ) ? false : *( modelCharacterDirectionsBuffer + ( selectionEnd - ( isLastCharacter ? 1u : 0u ) ) ) );
 
   const CharacterDirection startDirection = ( ( NULL == modelCharacterDirectionsBuffer ) ? false : *( modelCharacterDirectionsBuffer + selectionStart ) );
   const CharacterDirection endDirection = ( ( NULL == modelCharacterDirectionsBuffer ) ? false : *( modelCharacterDirectionsBuffer + ( selectionEnd - ( isLastCharacter ? 1u : 0u ) ) ) );
 
@@ -1799,14 +1976,14 @@ void Controller::Impl::RepositionSelectionHandles()
   const GlyphIndex glyphEnd = *( charactersToGlyphBuffer + selectionEndMinusOne ) + ( ( numberOfGlyphs > 0 ) ? numberOfGlyphs - 1u : 0u );
 
   // Get the lines where the glyphs are laid-out.
   const GlyphIndex glyphEnd = *( charactersToGlyphBuffer + selectionEndMinusOne ) + ( ( numberOfGlyphs > 0 ) ? numberOfGlyphs - 1u : 0u );
 
   // Get the lines where the glyphs are laid-out.
-  const LineRun* lineRun = mVisualModel->mLines.Begin();
+  const LineRun* lineRun = mModel->mVisualModel->mLines.Begin();
 
   LineIndex lineIndex = 0u;
   Length numberOfLines = 0u;
 
   LineIndex lineIndex = 0u;
   Length numberOfLines = 0u;
-  mVisualModel->GetNumberOfLines( glyphStart,
-                                  1u + glyphEnd - glyphStart,
-                                  lineIndex,
-                                  numberOfLines );
+  mModel->mVisualModel->GetNumberOfLines( glyphStart,
+                                          1u + glyphEnd - glyphStart,
+                                          lineIndex,
+                                          numberOfLines );
   const LineIndex firstLineIndex = lineIndex;
 
   // Create the structure to store some selection box info.
   const LineIndex firstLineIndex = lineIndex;
 
   // Create the structure to store some selection box info.
@@ -1826,11 +2003,11 @@ void Controller::Impl::RepositionSelectionHandles()
   // Retrieve the first line and get the line's vertical offset, the line's height and the index to the last glyph.
 
   // The line's vertical offset of all the lines before the line where the first glyph is laid-out.
   // Retrieve the first line and get the line's vertical offset, the line's height and the index to the last glyph.
 
   // The line's vertical offset of all the lines before the line where the first glyph is laid-out.
-  selectionBoxInfo->lineOffset = CalculateLineOffset( mVisualModel->mLines,
+  selectionBoxInfo->lineOffset = CalculateLineOffset( mModel->mVisualModel->mLines,
                                                       firstLineIndex );
 
   // Transform to decorator's (control) coords.
                                                       firstLineIndex );
 
   // Transform to decorator's (control) coords.
-  selectionBoxInfo->lineOffset += mScrollPosition.y;
+  selectionBoxInfo->lineOffset += mModel->mScrollPosition.y;
 
   lineRun += firstLineIndex;
 
 
   lineRun += firstLineIndex;
 
@@ -1842,11 +2019,11 @@ void Controller::Impl::RepositionSelectionHandles()
 
   // Check if the first glyph is a ligature that must be broken like Latin ff, fi, or Arabic ﻻ, etc which needs special code.
   const Length numberOfCharactersStart = *( charactersPerGlyphBuffer + glyphStart );
 
   // Check if the first glyph is a ligature that must be broken like Latin ff, fi, or Arabic ﻻ, etc which needs special code.
   const Length numberOfCharactersStart = *( charactersPerGlyphBuffer + glyphStart );
-  bool splitStartGlyph = ( numberOfCharactersStart > 1u ) && HasLigatureMustBreak( mLogicalModel->GetScript( selectionStart ) );
+  bool splitStartGlyph = ( numberOfCharactersStart > 1u ) && HasLigatureMustBreak( mModel->mLogicalModel->GetScript( selectionStart ) );
 
   // Check if the last glyph is a ligature that must be broken like Latin ff, fi, or Arabic ﻻ, etc which needs special code.
   const Length numberOfCharactersEnd = *( charactersPerGlyphBuffer + glyphEnd );
 
   // Check if the last glyph is a ligature that must be broken like Latin ff, fi, or Arabic ﻻ, etc which needs special code.
   const Length numberOfCharactersEnd = *( charactersPerGlyphBuffer + glyphEnd );
-  bool splitEndGlyph = ( glyphStart != glyphEnd ) && ( numberOfCharactersEnd > 1u ) && HasLigatureMustBreak( mLogicalModel->GetScript( selectionEndMinusOne ) );
+  bool splitEndGlyph = ( glyphStart != glyphEnd ) && ( numberOfCharactersEnd > 1u ) && HasLigatureMustBreak( mModel->mLogicalModel->GetScript( selectionEndMinusOne ) );
 
   // The number of quads of the selection box.
   const unsigned int numberOfQuads = 1u + ( glyphEnd - glyphStart ) + ( ( numberOfLines > 1u ) ? 2u * numberOfLines : 0u );
 
   // The number of quads of the selection box.
   const unsigned int numberOfQuads = 1u + ( glyphEnd - glyphStart ) + ( ( numberOfLines > 1u ) ? 2u * numberOfLines : 0u );
@@ -1879,7 +2056,7 @@ void Controller::Impl::RepositionSelectionHandles()
       // Calculate the number of characters selected.
       const Length numberOfCharacters = ( glyphStart == glyphEnd ) ? ( selectionEnd - selectionStart ) : ( numberOfCharactersStart - interGlyphIndex );
 
       // Calculate the number of characters selected.
       const Length numberOfCharacters = ( glyphStart == glyphEnd ) ? ( selectionEnd - selectionStart ) : ( numberOfCharactersStart - interGlyphIndex );
 
-      quad.x = lineRun->alignmentOffset + position.x - glyph.xBearing + mScrollPosition.x + glyphAdvance * static_cast<float>( isCurrentRightToLeft ? ( numberOfCharactersStart - interGlyphIndex - numberOfCharacters ) : interGlyphIndex );
+      quad.x = lineRun->alignmentOffset + position.x - glyph.xBearing + mModel->mScrollPosition.x + glyphAdvance * static_cast<float>( isCurrentRightToLeft ? ( numberOfCharactersStart - interGlyphIndex - numberOfCharacters ) : interGlyphIndex );
       quad.y = selectionBoxInfo->lineOffset;
       quad.z = quad.x + static_cast<float>( numberOfCharacters ) * glyphAdvance;
       quad.w = selectionBoxInfo->lineOffset + selectionBoxInfo->lineHeight;
       quad.y = selectionBoxInfo->lineOffset;
       quad.z = quad.x + static_cast<float>( numberOfCharacters ) * glyphAdvance;
       quad.w = selectionBoxInfo->lineOffset + selectionBoxInfo->lineHeight;
@@ -1910,7 +2087,7 @@ void Controller::Impl::RepositionSelectionHandles()
 
       const Length numberOfCharacters = numberOfCharactersEnd - interGlyphIndex;
 
 
       const Length numberOfCharacters = numberOfCharactersEnd - interGlyphIndex;
 
-      quad.x = lineRun->alignmentOffset + position.x - glyph.xBearing + mScrollPosition.x + ( isCurrentRightToLeft ? ( glyphAdvance * static_cast<float>( numberOfCharacters ) ) : 0.f );
+      quad.x = lineRun->alignmentOffset + position.x - glyph.xBearing + mModel->mScrollPosition.x + ( isCurrentRightToLeft ? ( glyphAdvance * static_cast<float>( numberOfCharacters ) ) : 0.f );
       quad.y = selectionBoxInfo->lineOffset;
       quad.z = quad.x + static_cast<float>( interGlyphIndex ) * glyphAdvance;
       quad.w = quad.y + selectionBoxInfo->lineHeight;
       quad.y = selectionBoxInfo->lineOffset;
       quad.z = quad.x + static_cast<float>( interGlyphIndex ) * glyphAdvance;
       quad.w = quad.y + selectionBoxInfo->lineHeight;
@@ -1927,7 +2104,7 @@ void Controller::Impl::RepositionSelectionHandles()
       continue;
     }
 
       continue;
     }
 
-    quad.x = lineRun->alignmentOffset + position.x - glyph.xBearing + mScrollPosition.x;
+    quad.x = lineRun->alignmentOffset + position.x - glyph.xBearing + mModel->mScrollPosition.x;
     quad.y = selectionBoxInfo->lineOffset;
     quad.z = quad.x + glyph.advance;
     quad.w = quad.y + selectionBoxInfo->lineHeight;
     quad.y = selectionBoxInfo->lineOffset;
     quad.z = quad.x + glyph.advance;
     quad.w = quad.y + selectionBoxInfo->lineHeight;
@@ -1943,15 +2120,15 @@ void Controller::Impl::RepositionSelectionHandles()
     // Whether to retrieve the next line.
     if( index == lastGlyphOfLine )
     {
     // Whether to retrieve the next line.
     if( index == lastGlyphOfLine )
     {
-      // Retrieve the next line.
-      ++lineRun;
-
-      // Get the last glyph of the new line.
-      lastGlyphOfLine = lineRun->glyphRun.glyphIndex + lineRun->glyphRun.numberOfGlyphs - 1u;
-
       ++lineIndex;
       if( lineIndex < firstLineIndex + numberOfLines )
       {
       ++lineIndex;
       if( lineIndex < firstLineIndex + numberOfLines )
       {
+        // Retrieve the next line.
+        ++lineRun;
+
+        // Get the last glyph of the new line.
+        lastGlyphOfLine = lineRun->glyphRun.glyphIndex + lineRun->glyphRun.numberOfGlyphs - 1u;
+
         // Keep the offset and height of the current selection box.
         const float currentLineOffset = selectionBoxInfo->lineOffset;
         const float currentLineHeight = selectionBoxInfo->lineHeight;
         // Keep the offset and height of the current selection box.
         const float currentLineOffset = selectionBoxInfo->lineOffset;
         const float currentLineHeight = selectionBoxInfo->lineHeight;
@@ -1992,7 +2169,7 @@ void Controller::Impl::RepositionSelectionHandles()
   if( 1u < numberOfLines )
   {
     // Boxify the first line.
   if( 1u < numberOfLines )
   {
     // Boxify the first line.
-    lineRun = mVisualModel->mLines.Begin() + firstLineIndex;
+    lineRun = mModel->mVisualModel->mLines.Begin() + firstLineIndex;
     const SelectionBoxInfo& firstSelectionBoxLineInfo = *( selectionBoxLinesInfo.Begin() );
 
     bool boxifyBegin = ( LTR != lineRun->direction ) && ( LTR != startDirection );
     const SelectionBoxInfo& firstSelectionBoxLineInfo = *( selectionBoxLinesInfo.Begin() );
 
     bool boxifyBegin = ( LTR != lineRun->direction ) && ( LTR != startDirection );
@@ -2018,7 +2195,7 @@ void Controller::Impl::RepositionSelectionHandles()
     {
       quad.x = firstSelectionBoxLineInfo.maxX;
       quad.y = firstSelectionBoxLineInfo.lineOffset;
     {
       quad.x = firstSelectionBoxLineInfo.maxX;
       quad.y = firstSelectionBoxLineInfo.lineOffset;
-      quad.z = mVisualModel->mControlSize.width;
+      quad.z = mModel->mVisualModel->mControlSize.width;
       quad.w = firstSelectionBoxLineInfo.lineOffset + firstSelectionBoxLineInfo.lineHeight;
 
       // Boxify at the end of the line.
       quad.w = firstSelectionBoxLineInfo.lineOffset + firstSelectionBoxLineInfo.lineHeight;
 
       // Boxify at the end of the line.
@@ -2027,7 +2204,7 @@ void Controller::Impl::RepositionSelectionHandles()
       ++actualNumberOfQuads;
 
       // Update the size of the highlighted text.
       ++actualNumberOfQuads;
 
       // Update the size of the highlighted text.
-      maxHighlightX = mVisualModel->mControlSize.width;
+      maxHighlightX = mModel->mVisualModel->mControlSize.width;
     }
 
     // Boxify the central lines.
     }
 
     // Boxify the central lines.
@@ -2051,7 +2228,7 @@ void Controller::Impl::RepositionSelectionHandles()
 
         quad.x = info.maxX;
         quad.y = info.lineOffset;
 
         quad.x = info.maxX;
         quad.y = info.lineOffset;
-        quad.z = mVisualModel->mControlSize.width;
+        quad.z = mModel->mVisualModel->mControlSize.width;
         quad.w = info.lineOffset + info.lineHeight;
 
         mEventData->mDecorator->AddHighlight( actualNumberOfQuads,
         quad.w = info.lineOffset + info.lineHeight;
 
         mEventData->mDecorator->AddHighlight( actualNumberOfQuads,
@@ -2061,11 +2238,11 @@ void Controller::Impl::RepositionSelectionHandles()
 
       // Update the size of the highlighted text.
       minHighlightX = 0.f;
 
       // Update the size of the highlighted text.
       minHighlightX = 0.f;
-      maxHighlightX = mVisualModel->mControlSize.width;
+      maxHighlightX = mModel->mVisualModel->mControlSize.width;
     }
 
     // Boxify the last line.
     }
 
     // Boxify the last line.
-    lineRun = mVisualModel->mLines.Begin() + firstLineIndex + numberOfLines - 1u;
+    lineRun = mModel->mVisualModel->mLines.Begin() + firstLineIndex + numberOfLines - 1u;
     const SelectionBoxInfo& lastSelectionBoxLineInfo = *( selectionBoxLinesInfo.End() - 1u );
 
     boxifyBegin = ( LTR == lineRun->direction ) && ( LTR == endDirection );
     const SelectionBoxInfo& lastSelectionBoxLineInfo = *( selectionBoxLinesInfo.End() - 1u );
 
     boxifyBegin = ( LTR == lineRun->direction ) && ( LTR == endDirection );
@@ -2091,7 +2268,7 @@ void Controller::Impl::RepositionSelectionHandles()
     {
       quad.x = lastSelectionBoxLineInfo.maxX;
       quad.y = lastSelectionBoxLineInfo.lineOffset;
     {
       quad.x = lastSelectionBoxLineInfo.maxX;
       quad.y = lastSelectionBoxLineInfo.lineOffset;
-      quad.z = mVisualModel->mControlSize.width;
+      quad.z = mModel->mVisualModel->mControlSize.width;
       quad.w = lastSelectionBoxLineInfo.lineOffset + lastSelectionBoxLineInfo.lineHeight;
 
       // Boxify at the end of the line.
       quad.w = lastSelectionBoxLineInfo.lineOffset + lastSelectionBoxLineInfo.lineHeight;
 
       // Boxify at the end of the line.
@@ -2100,7 +2277,7 @@ void Controller::Impl::RepositionSelectionHandles()
       ++actualNumberOfQuads;
 
       // Update the size of the highlighted text.
       ++actualNumberOfQuads;
 
       // Update the size of the highlighted text.
-      maxHighlightX = mVisualModel->mControlSize.width;
+      maxHighlightX = mModel->mVisualModel->mControlSize.width;
     }
   }
 
     }
   }
 
@@ -2115,7 +2292,7 @@ void Controller::Impl::RepositionSelectionHandles()
   const SelectionBoxInfo& firstSelectionBoxLineInfo = *( selectionBoxLinesInfo.Begin() );
   highLightPosition.y = firstSelectionBoxLineInfo.lineOffset;
 
   const SelectionBoxInfo& firstSelectionBoxLineInfo = *( selectionBoxLinesInfo.Begin() );
   highLightPosition.y = firstSelectionBoxLineInfo.lineOffset;
 
-  mEventData->mDecorator->SetHighLightBox( highLightPosition, highLightSize );
+  mEventData->mDecorator->SetHighLightBox( highLightPosition, highLightSize, static_cast<float>( mModel->GetOutlineWidth() ) );
 
   if( !mEventData->mDecorator->IsSmoothHandlePanEnabled() )
   {
 
   if( !mEventData->mDecorator->IsSmoothHandlePanEnabled() )
   {
@@ -2123,22 +2300,22 @@ void Controller::Impl::RepositionSelectionHandles()
     GetCursorPosition( mEventData->mLeftSelectionPosition,
                        primaryCursorInfo );
 
     GetCursorPosition( mEventData->mLeftSelectionPosition,
                        primaryCursorInfo );
 
-    const Vector2 primaryPosition = primaryCursorInfo.primaryPosition + mScrollPosition;
+    const Vector2 primaryPosition = primaryCursorInfo.primaryPosition + mModel->mScrollPosition;
 
     mEventData->mDecorator->SetPosition( LEFT_SELECTION_HANDLE,
                                          primaryPosition.x,
 
     mEventData->mDecorator->SetPosition( LEFT_SELECTION_HANDLE,
                                          primaryPosition.x,
-                                         primaryCursorInfo.lineOffset + mScrollPosition.y,
+                                         primaryCursorInfo.lineOffset + mModel->mScrollPosition.y,
                                          primaryCursorInfo.lineHeight );
 
     CursorInfo secondaryCursorInfo;
     GetCursorPosition( mEventData->mRightSelectionPosition,
                        secondaryCursorInfo );
 
                                          primaryCursorInfo.lineHeight );
 
     CursorInfo secondaryCursorInfo;
     GetCursorPosition( mEventData->mRightSelectionPosition,
                        secondaryCursorInfo );
 
-    const Vector2 secondaryPosition = secondaryCursorInfo.primaryPosition + mScrollPosition;
+    const Vector2 secondaryPosition = secondaryCursorInfo.primaryPosition + mModel->mScrollPosition;
 
     mEventData->mDecorator->SetPosition( RIGHT_SELECTION_HANDLE,
                                          secondaryPosition.x,
 
     mEventData->mDecorator->SetPosition( RIGHT_SELECTION_HANDLE,
                                          secondaryPosition.x,
-                                         secondaryCursorInfo.lineOffset + mScrollPosition.y,
+                                         secondaryCursorInfo.lineOffset + mModel->mScrollPosition.y,
                                          secondaryCursorInfo.lineHeight );
   }
 
                                          secondaryCursorInfo.lineHeight );
   }
 
@@ -2149,7 +2326,7 @@ void Controller::Impl::RepositionSelectionHandles()
   mEventData->mDecoratorUpdated = true;
 }
 
   mEventData->mDecoratorUpdated = true;
 }
 
-void Controller::Impl::RepositionSelectionHandles( float visualX, float visualY )
+void Controller::Impl::RepositionSelectionHandles( float visualX, float visualY, Controller::NoTextTap::Action action )
 {
   if( NULL == mEventData )
   {
 {
   if( NULL == mEventData )
   {
@@ -2163,8 +2340,8 @@ void Controller::Impl::RepositionSelectionHandles( float visualX, float visualY
     return;
   }
 
     return;
   }
 
-  const Length numberOfGlyphs = mVisualModel->mGlyphs.Count();
-  const Length numberOfLines  = mVisualModel->mLines.Count();
+  const Length numberOfGlyphs = mModel->mVisualModel->mGlyphs.Count();
+  const Length numberOfLines  = mModel->mVisualModel->mLines.Count();
   if( ( 0 == numberOfGlyphs ) ||
       ( 0 == numberOfLines ) )
   {
   if( ( 0 == numberOfGlyphs ) ||
       ( 0 == numberOfLines ) )
   {
@@ -2175,16 +2352,18 @@ void Controller::Impl::RepositionSelectionHandles( float visualX, float visualY
   // Find which word was selected
   CharacterIndex selectionStart( 0 );
   CharacterIndex selectionEnd( 0 );
   // Find which word was selected
   CharacterIndex selectionStart( 0 );
   CharacterIndex selectionEnd( 0 );
-  const bool indicesFound = FindSelectionIndices( mVisualModel,
-                                                  mLogicalModel,
+  CharacterIndex noTextHitIndex( 0 );
+  const bool characterHit = FindSelectionIndices( mModel->mVisualModel,
+                                                  mModel->mLogicalModel,
                                                   mMetrics,
                                                   visualX,
                                                   visualY,
                                                   selectionStart,
                                                   mMetrics,
                                                   visualX,
                                                   visualY,
                                                   selectionStart,
-                                                  selectionEnd );
+                                                  selectionEnd,
+                                                  noTextHitIndex );
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "%p selectionStart %d selectionEnd %d\n", this, selectionStart, selectionEnd );
 
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "%p selectionStart %d selectionEnd %d\n", this, selectionStart, selectionEnd );
 
-  if( indicesFound )
+  if( characterHit || ( Controller::NoTextTap::HIGHLIGHT == action ) )
   {
     ChangeState( EventData::SELECTING );
 
   {
     ChangeState( EventData::SELECTING );
 
@@ -2195,14 +2374,30 @@ void Controller::Impl::RepositionSelectionHandles( float visualX, float visualY
     mEventData->mUpdateRightSelectionPosition = true;
     mEventData->mUpdateHighlightBox = true;
 
     mEventData->mUpdateRightSelectionPosition = true;
     mEventData->mUpdateHighlightBox = true;
 
+    // It may happen an IMF commit event arrives before the selection event
+    // if the IMF manager is in pre-edit state. The commit event will set the
+    // mEventData->mUpdateCursorPosition flag to true. If it's not set back
+    // to false, the highlight box won't be updated.
+    mEventData->mUpdateCursorPosition = false;
+
     mEventData->mScrollAfterUpdatePosition = ( mEventData->mLeftSelectionPosition != mEventData->mRightSelectionPosition );
   }
     mEventData->mScrollAfterUpdatePosition = ( mEventData->mLeftSelectionPosition != mEventData->mRightSelectionPosition );
   }
-  else
+  else if( Controller::NoTextTap::SHOW_SELECTION_POPUP == action )
   {
     // Nothing to select. i.e. a white space, out of bounds
   {
     // Nothing to select. i.e. a white space, out of bounds
-    ChangeState( EventData::EDITING );
+    ChangeState( EventData::EDITING_WITH_POPUP );
 
 
-    mEventData->mPrimaryCursorPosition = selectionEnd;
+    mEventData->mPrimaryCursorPosition = noTextHitIndex;
+
+    mEventData->mUpdateCursorPosition = true;
+    mEventData->mUpdateGrabHandlePosition = true;
+    mEventData->mScrollAfterUpdatePosition = true;
+    mEventData->mUpdateInputStyle = true;
+  }
+  else if( Controller::NoTextTap::NO_ACTION == action )
+  {
+    // Nothing to select. i.e. a white space, out of bounds
+    mEventData->mPrimaryCursorPosition = noTextHitIndex;
 
     mEventData->mUpdateCursorPosition = true;
     mEventData->mUpdateGrabHandlePosition = true;
 
     mEventData->mUpdateCursorPosition = true;
     mEventData->mUpdateGrabHandlePosition = true;
@@ -2240,7 +2435,7 @@ void Controller::Impl::SetPopupButtons()
   }
   else if( EventData::EDITING_WITH_POPUP == mEventData->mState )
   {
   }
   else if( EventData::EDITING_WITH_POPUP == mEventData->mState )
   {
-    if( mLogicalModel->mText.Count() && !IsShowingPlaceholderText() )
+    if( mModel->mLogicalModel->mText.Count() && !IsShowingPlaceholderText() )
     {
       buttonsToShow = TextSelectionPopup::Buttons( TextSelectionPopup::SELECT | TextSelectionPopup::SELECT_ALL );
     }
     {
       buttonsToShow = TextSelectionPopup::Buttons( TextSelectionPopup::SELECT | TextSelectionPopup::SELECT_ALL );
     }
@@ -2483,21 +2678,21 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical,
     cursorInfo.lineHeight = GetDefaultFontLineHeight();
     cursorInfo.primaryCursorHeight = cursorInfo.lineHeight;
 
     cursorInfo.lineHeight = GetDefaultFontLineHeight();
     cursorInfo.primaryCursorHeight = cursorInfo.lineHeight;
 
-    switch( mLayoutEngine.GetHorizontalAlignment() )
+    switch( mModel->mHorizontalAlignment )
     {
     {
-      case LayoutEngine::HORIZONTAL_ALIGN_BEGIN:
+      case Text::HorizontalAlignment::BEGIN :
       {
         cursorInfo.primaryPosition.x = 0.f;
         break;
       }
       {
         cursorInfo.primaryPosition.x = 0.f;
         break;
       }
-      case LayoutEngine::HORIZONTAL_ALIGN_CENTER:
+      case Text::HorizontalAlignment::CENTER:
       {
       {
-        cursorInfo.primaryPosition.x = floorf( 0.5f * mVisualModel->mControlSize.width );
+        cursorInfo.primaryPosition.x = floorf( 0.5f * mModel->mVisualModel->mControlSize.width );
         break;
       }
         break;
       }
-      case LayoutEngine::HORIZONTAL_ALIGN_END:
+      case Text::HorizontalAlignment::END:
       {
       {
-        cursorInfo.primaryPosition.x = mVisualModel->mControlSize.width - mEventData->mDecorator->GetCursorWidth();
+        cursorInfo.primaryPosition.x = mModel->mVisualModel->mControlSize.width - mEventData->mDecorator->GetCursorWidth();
         break;
       }
     }
         break;
       }
     }
@@ -2506,13 +2701,25 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical,
     return;
   }
 
     return;
   }
 
-  Text::GetCursorPosition( mVisualModel,
-                           mLogicalModel,
-                           mMetrics,
-                           logical,
+  const bool isMultiLine = ( Layout::Engine::MULTI_LINE_BOX == mLayoutEngine.GetLayout() );
+  GetCursorPositionParameters parameters;
+  parameters.visualModel = mModel->mVisualModel;
+  parameters.logicalModel = mModel->mLogicalModel;
+  parameters.metrics = mMetrics;
+  parameters.logical = logical;
+  parameters.isMultiline = isMultiLine;
+
+  Text::GetCursorPosition( parameters,
                            cursorInfo );
 
                            cursorInfo );
 
-  if( LayoutEngine::MULTI_LINE_BOX == mLayoutEngine.GetLayout() )
+  // Adds Outline offset.
+  const float outlineWidth = static_cast<float>( mModel->GetOutlineWidth() );
+  cursorInfo.primaryPosition.x += outlineWidth;
+  cursorInfo.primaryPosition.y += outlineWidth;
+  cursorInfo.secondaryPosition.x += outlineWidth;
+  cursorInfo.secondaryPosition.y += outlineWidth;
+
+  if( isMultiLine )
   {
     // If the text is editable and multi-line, the cursor position after a white space shouldn't exceed the boundaries of the text control.
 
   {
     // If the text is editable and multi-line, the cursor position after a white space shouldn't exceed the boundaries of the text control.
 
@@ -2524,7 +2731,7 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical,
       cursorInfo.primaryPosition.x = 0.f;
     }
 
       cursorInfo.primaryPosition.x = 0.f;
     }
 
-    const float edgeWidth = mVisualModel->mControlSize.width - static_cast<float>( mEventData->mDecorator->GetCursorWidth() );
+    const float edgeWidth = mModel->mVisualModel->mControlSize.width - static_cast<float>( mEventData->mDecorator->GetCursorWidth() );
     if( cursorInfo.primaryPosition.x > edgeWidth )
     {
       cursorInfo.primaryPosition.x = edgeWidth;
     if( cursorInfo.primaryPosition.x > edgeWidth )
     {
       cursorInfo.primaryPosition.x = edgeWidth;
@@ -2542,18 +2749,18 @@ CharacterIndex Controller::Impl::CalculateNewCursorIndex( CharacterIndex index )
 
   CharacterIndex cursorIndex = mEventData->mPrimaryCursorPosition;
 
 
   CharacterIndex cursorIndex = mEventData->mPrimaryCursorPosition;
 
-  const GlyphIndex* const charactersToGlyphBuffer = mVisualModel->mCharactersToGlyph.Begin();
-  const Length* const charactersPerGlyphBuffer = mVisualModel->mCharactersPerGlyph.Begin();
+  const GlyphIndex* const charactersToGlyphBuffer = mModel->mVisualModel->mCharactersToGlyph.Begin();
+  const Length* const charactersPerGlyphBuffer = mModel->mVisualModel->mCharactersPerGlyph.Begin();
 
   GlyphIndex glyphIndex = *( charactersToGlyphBuffer + index );
   Length numberOfCharacters = *( charactersPerGlyphBuffer + glyphIndex );
 
   if( numberOfCharacters > 1u )
   {
 
   GlyphIndex glyphIndex = *( charactersToGlyphBuffer + index );
   Length numberOfCharacters = *( charactersPerGlyphBuffer + glyphIndex );
 
   if( numberOfCharacters > 1u )
   {
-    const Script script = mLogicalModel->GetScript( index );
+    const Script script = mModel->mLogicalModel->GetScript( index );
     if( HasLigatureMustBreak( script ) )
     {
     if( HasLigatureMustBreak( script ) )
     {
-      // Prevents to jump the whole Latin ligatures like fi, ff, or Arabic ﻻ,  ...
+      // Prevents to jump the whole Latin ligatures like fi, ff, or Arabic ﻻ, ...
       numberOfCharacters = 1u;
     }
   }
       numberOfCharacters = 1u;
     }
   }
@@ -2591,7 +2798,9 @@ void Controller::Impl::UpdateCursorPosition( const CursorInfo& cursorInfo )
     return;
   }
 
     return;
   }
 
-  const Vector2 cursorPosition = cursorInfo.primaryPosition + mScrollPosition;
+  const Vector2 cursorPosition = cursorInfo.primaryPosition + mModel->mScrollPosition;
+
+  mEventData->mDecorator->SetGlyphOffset( PRIMARY_CURSOR, cursorInfo.glyphOffset );
 
   // Sets the cursor position.
   mEventData->mDecorator->SetPosition( PRIMARY_CURSOR,
 
   // Sets the cursor position.
   mEventData->mDecorator->SetPosition( PRIMARY_CURSOR,
@@ -2606,18 +2815,18 @@ void Controller::Impl::UpdateCursorPosition( const CursorInfo& cursorInfo )
     // Sets the grab handle position.
     mEventData->mDecorator->SetPosition( GRAB_HANDLE,
                                          cursorPosition.x,
     // Sets the grab handle position.
     mEventData->mDecorator->SetPosition( GRAB_HANDLE,
                                          cursorPosition.x,
-                                         cursorInfo.lineOffset + mScrollPosition.y,
+                                         cursorInfo.lineOffset + mModel->mScrollPosition.y,
                                          cursorInfo.lineHeight );
   }
 
   if( cursorInfo.isSecondaryCursor )
   {
     mEventData->mDecorator->SetPosition( SECONDARY_CURSOR,
                                          cursorInfo.lineHeight );
   }
 
   if( cursorInfo.isSecondaryCursor )
   {
     mEventData->mDecorator->SetPosition( SECONDARY_CURSOR,
-                                         cursorInfo.secondaryPosition.x + mScrollPosition.x,
-                                         cursorInfo.secondaryPosition.y + mScrollPosition.y,
+                                         cursorInfo.secondaryPosition.x + mModel->mScrollPosition.x,
+                                         cursorInfo.secondaryPosition.y + mModel->mScrollPosition.y,
                                          cursorInfo.secondaryCursorHeight,
                                          cursorInfo.lineHeight );
                                          cursorInfo.secondaryCursorHeight,
                                          cursorInfo.lineHeight );
-    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Secondary cursor position: %f,%f\n", cursorInfo.secondaryPosition.x + mScrollPosition.x, cursorInfo.secondaryPosition.y + mScrollPosition.y );
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Secondary cursor position: %f,%f\n", cursorInfo.secondaryPosition.x + mModel->mScrollPosition.x, cursorInfo.secondaryPosition.y + mModel->mScrollPosition.y );
   }
 
   // Set which cursors are active according the state.
   }
 
   // Set which cursors are active according the state.
@@ -2649,58 +2858,58 @@ void Controller::Impl::UpdateSelectionHandle( HandleType handleType,
     return;
   }
 
     return;
   }
 
-  const Vector2 cursorPosition = cursorInfo.primaryPosition + mScrollPosition;
+  const Vector2 cursorPosition = cursorInfo.primaryPosition + mModel->mScrollPosition;
 
   // Sets the handle's position.
   mEventData->mDecorator->SetPosition( handleType,
                                        cursorPosition.x,
 
   // Sets the handle's position.
   mEventData->mDecorator->SetPosition( handleType,
                                        cursorPosition.x,
-                                       cursorInfo.lineOffset + mScrollPosition.y,
+                                       cursorInfo.lineOffset + mModel->mScrollPosition.y,
                                        cursorInfo.lineHeight );
 
   // If selection handle at start of the text and other at end of the text then all text is selected.
   const CharacterIndex startOfSelection = std::min( mEventData->mLeftSelectionPosition, mEventData->mRightSelectionPosition );
   const CharacterIndex endOfSelection = std::max ( mEventData->mLeftSelectionPosition, mEventData->mRightSelectionPosition );
                                        cursorInfo.lineHeight );
 
   // If selection handle at start of the text and other at end of the text then all text is selected.
   const CharacterIndex startOfSelection = std::min( mEventData->mLeftSelectionPosition, mEventData->mRightSelectionPosition );
   const CharacterIndex endOfSelection = std::max ( mEventData->mLeftSelectionPosition, mEventData->mRightSelectionPosition );
-  mEventData->mAllTextSelected = ( startOfSelection == 0 ) && ( endOfSelection == mLogicalModel->mText.Count() );
+  mEventData->mAllTextSelected = ( startOfSelection == 0 ) && ( endOfSelection == mModel->mLogicalModel->mText.Count() );
 }
 
 void Controller::Impl::ClampHorizontalScroll( const Vector2& layoutSize )
 {
 }
 
 void Controller::Impl::ClampHorizontalScroll( const Vector2& layoutSize )
 {
-  // Clamp between -space & 0.
+  // Clamp between -space & -alignment offset.
 
 
-  if( layoutSize.width > mVisualModel->mControlSize.width )
+  if( layoutSize.width > mModel->mVisualModel->mControlSize.width )
   {
   {
-    const float space = ( layoutSize.width - mVisualModel->mControlSize.width );
-    mScrollPosition.x = ( mScrollPosition.x < -space ) ? -space : mScrollPosition.x;
-    mScrollPosition.x = ( mScrollPosition.x > 0.f ) ? 0.f : mScrollPosition.x;
+    const float space = ( layoutSize.width - mModel->mVisualModel->mControlSize.width ) + mModel->mAlignmentOffset;
+    mModel->mScrollPosition.x = ( mModel->mScrollPosition.x < -space ) ? -space : mModel->mScrollPosition.x;
+    mModel->mScrollPosition.x = ( mModel->mScrollPosition.x > -mModel->mAlignmentOffset ) ? -mModel->mAlignmentOffset : mModel->mScrollPosition.x;
 
     mEventData->mDecoratorUpdated = true;
   }
   else
   {
 
     mEventData->mDecoratorUpdated = true;
   }
   else
   {
-    mScrollPosition.x = 0.f;
+    mModel->mScrollPosition.x = 0.f;
   }
 }
 
 void Controller::Impl::ClampVerticalScroll( const Vector2& layoutSize )
 {
   }
 }
 
 void Controller::Impl::ClampVerticalScroll( const Vector2& layoutSize )
 {
-  if( LayoutEngine::SINGLE_LINE_BOX == mLayoutEngine.GetLayout() )
+  if( Layout::Engine::SINGLE_LINE_BOX == mLayoutEngine.GetLayout() )
   {
     // Nothing to do if the text is single line.
     return;
   }
 
   // Clamp between -space & 0.
   {
     // Nothing to do if the text is single line.
     return;
   }
 
   // Clamp between -space & 0.
-  if( layoutSize.height > mVisualModel->mControlSize.height )
+  if( layoutSize.height > mModel->mVisualModel->mControlSize.height )
   {
   {
-    const float space = ( layoutSize.height - mVisualModel->mControlSize.height );
-    mScrollPosition.y = ( mScrollPosition.y < -space ) ? -space : mScrollPosition.y;
-    mScrollPosition.y = ( mScrollPosition.y > 0.f ) ? 0.f : mScrollPosition.y;
+    const float space = ( layoutSize.height - mModel->mVisualModel->mControlSize.height );
+    mModel->mScrollPosition.y = ( mModel->mScrollPosition.y < -space ) ? -space : mModel->mScrollPosition.y;
+    mModel->mScrollPosition.y = ( mModel->mScrollPosition.y > 0.f ) ? 0.f : mModel->mScrollPosition.y;
 
     mEventData->mDecoratorUpdated = true;
   }
   else
   {
 
     mEventData->mDecoratorUpdated = true;
   }
   else
   {
-    mScrollPosition.y = 0.f;
+    mModel->mScrollPosition.y = 0.f;
   }
 }
 
   }
 }
 
@@ -2713,28 +2922,31 @@ void Controller::Impl::ScrollToMakePositionVisible( const Vector2& position, flo
   const float positionEndY = position.y + lineHeight;
 
   // Transform the position to decorator coords.
   const float positionEndY = position.y + lineHeight;
 
   // Transform the position to decorator coords.
-  const float decoratorPositionBeginX = position.x + mScrollPosition.x;
-  const float decoratorPositionEndX = positionEndX + mScrollPosition.x;
+  const float decoratorPositionBeginX = position.x + mModel->mScrollPosition.x;
+  const float decoratorPositionEndX = positionEndX + mModel->mScrollPosition.x;
 
 
-  const float decoratorPositionBeginY = position.y + mScrollPosition.y;
-  const float decoratorPositionEndY = positionEndY + mScrollPosition.y;
+  const float decoratorPositionBeginY = position.y + mModel->mScrollPosition.y;
+  const float decoratorPositionEndY = positionEndY + mModel->mScrollPosition.y;
 
   if( decoratorPositionBeginX < 0.f )
   {
 
   if( decoratorPositionBeginX < 0.f )
   {
-    mScrollPosition.x = -position.x;
+    mModel->mScrollPosition.x = -position.x;
   }
   }
-  else if( decoratorPositionEndX > mVisualModel->mControlSize.width )
+  else if( decoratorPositionEndX > mModel->mVisualModel->mControlSize.width )
   {
   {
-    mScrollPosition.x = mVisualModel->mControlSize.width - positionEndX;
+    mModel->mScrollPosition.x = mModel->mVisualModel->mControlSize.width - positionEndX;
   }
 
   }
 
-  if( decoratorPositionBeginY < 0.f )
-  {
-    mScrollPosition.y = -position.y;
-  }
-  else if( decoratorPositionEndY > mVisualModel->mControlSize.height )
+  if( Layout::Engine::MULTI_LINE_BOX == mLayoutEngine.GetLayout() )
   {
   {
-    mScrollPosition.y = mVisualModel->mControlSize.height - positionEndY;
+    if( decoratorPositionBeginY < 0.f )
+    {
+      mModel->mScrollPosition.y = -position.y;
+    }
+    else if( decoratorPositionEndY > mModel->mVisualModel->mControlSize.height )
+    {
+      mModel->mScrollPosition.y = mModel->mVisualModel->mControlSize.height - positionEndY;
+    }
   }
 }
 
   }
 }
 
@@ -2743,12 +2955,23 @@ void Controller::Impl::ScrollTextToMatchCursor( const CursorInfo& cursorInfo )
   // Get the current cursor position in decorator coords.
   const Vector2& currentCursorPosition = mEventData->mDecorator->GetPosition( PRIMARY_CURSOR );
 
   // Get the current cursor position in decorator coords.
   const Vector2& currentCursorPosition = mEventData->mDecorator->GetPosition( PRIMARY_CURSOR );
 
+  const LineIndex lineIndex = mModel->mVisualModel->GetLineOfCharacter( mEventData->mPrimaryCursorPosition  );
+
+
+
   // Calculate the offset to match the cursor position before the character was deleted.
   // Calculate the offset to match the cursor position before the character was deleted.
-  mScrollPosition.x = currentCursorPosition.x - cursorInfo.primaryPosition.x;
-  mScrollPosition.y = currentCursorPosition.y - cursorInfo.lineOffset;
+  mModel->mScrollPosition.x = currentCursorPosition.x - cursorInfo.primaryPosition.x;
+
+  //If text control has more than two lines and current line index is not last, calculate scrollpositionY
+  if( mModel->mVisualModel->mLines.Count() > 1u && lineIndex != mModel->mVisualModel->mLines.Count() -1u )
+  {
+    const float currentCursorGlyphOffset = mEventData->mDecorator->GetGlyphOffset( PRIMARY_CURSOR );
+    mModel->mScrollPosition.y = currentCursorPosition.y - cursorInfo.lineOffset - currentCursorGlyphOffset;
+  }
+
 
 
-  ClampHorizontalScroll( mVisualModel->GetLayoutSize() );
-  ClampVerticalScroll( mVisualModel->GetLayoutSize() );
+  ClampHorizontalScroll( mModel->mVisualModel->GetLayoutSize() );
+  ClampVerticalScroll( mModel->mVisualModel->GetLayoutSize() );
 
   // Makes the new cursor position visible if needed.
   ScrollToMakePositionVisible( cursorInfo.primaryPosition, cursorInfo.lineHeight );
 
   // Makes the new cursor position visible if needed.
   ScrollToMakePositionVisible( cursorInfo.primaryPosition, cursorInfo.lineHeight );