Merge "Makes the LTR/RTL alignment of text follow the system language by default...
authorjoogab yun <joogab.yun@samsung.com>
Fri, 9 Jul 2021 01:54:24 +0000 (01:54 +0000)
committerGerrit Code Review <gerrit@review>
Fri, 9 Jul 2021 01:54:24 +0000 (01:54 +0000)
1  2 
dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp
dali-toolkit/internal/controls/text-controls/text-editor-impl.h
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.h
dali-toolkit/internal/controls/text-controls/text-label-impl.cpp
dali-toolkit/internal/controls/text-controls/text-label-impl.h
dali-toolkit/internal/text/text-controller-impl.cpp
dali-toolkit/internal/text/text-model.cpp

@@@ -20,7 -20,6 +20,6 @@@
  
  // EXTERNAL INCLUDES
  #include <dali/devel-api/actors/actor-devel.h>
- #include <dali/devel-api/adaptor-framework/window-devel.h>
  #include <dali/devel-api/common/stage.h>
  #include <dali/devel-api/object/property-helper-devel.h>
  #include <dali/integration-api/adaptor-framework/adaptor.h>
@@@ -698,7 -697,7 +697,7 @@@ void TextEditor::SetProperty(BaseObject
        }
        case Toolkit::DevelTextEditor::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
        {
-         impl.mController->SetMatchSystemLanguageDirection(value.Get<bool>());
+         impl.mController->SetMatchLayoutDirection(value.Get<bool>() ? DevelText::MatchLayoutDirection::LOCALE : DevelText::MatchLayoutDirection::CONTENTS);
          break;
        }
        case Toolkit::DevelTextEditor::Property::MAX_LENGTH:
@@@ -1119,7 -1118,7 +1118,7 @@@ Property::Value TextEditor::GetProperty
        }
        case Toolkit::DevelTextEditor::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
        {
-         value = impl.mController->IsMatchSystemLanguageDirection();
+         value = impl.mController->GetMatchLayoutDirection() != DevelText::MatchLayoutDirection::CONTENTS;
          break;
        }
        case Toolkit::DevelTextEditor::Property::MAX_LENGTH:
@@@ -1272,7 -1271,7 +1271,7 @@@ DevelTextEditor::InputFilteredSignalTyp
    return mInputFilteredSignal;
  }
  
 -Text::ControllerPtr TextEditor::getController()
 +Text::ControllerPtr TextEditor::GetTextController()
  {
    return mController;
  }
@@@ -1376,6 -1375,8 +1375,8 @@@ void TextEditor::OnInitialize(
    Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(stage.GetRootLayer().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
    mController->SetLayoutDirection(layoutDirection);
  
+   self.LayoutDirectionChangedSignal().Connect(this, &TextEditor::OnLayoutDirectionChanged);
    // Forward input events to controller
    EnableGestureDetection(static_cast<GestureType::Value>(GestureType::TAP | GestureType::PAN | GestureType::LONG_PRESS));
    GetTapGestureDetector().SetMaximumTapsRequired(2);
@@@ -1501,15 -1502,8 +1502,8 @@@ void TextEditor::OnRelayout(const Vecto
    Vector2 contentSize(size.x - (padding.start + padding.end), size.y - (padding.top + padding.bottom));
  
    // Support Right-To-Left of padding
-   Dali::LayoutDirection::Type layoutDirection;
-   if(mController->IsMatchSystemLanguageDirection())
-   {
-     layoutDirection = static_cast<Dali::LayoutDirection::Type>(DevelWindow::Get(self).GetRootLayer().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
-   }
-   else
-   {
-     layoutDirection = static_cast<Dali::LayoutDirection::Type>(self.GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
-   }
+   Dali::LayoutDirection::Type layoutDirection = mController->GetLayoutDirection(self);
    if(Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection)
    {
      std::swap(padding.start, padding.end);
@@@ -1813,11 -1807,11 +1807,11 @@@ void TextEditor::TextDeleted(unsigned i
    }
  }
  
 -void TextEditor::CaretMoved(unsigned int position)
 +void TextEditor::CursorMoved(unsigned int position)
  {
    if(Accessibility::IsUp())
    {
 -    Control::Impl::GetAccessibilityObject(Self())->EmitTextCaretMoved(position);
 +    Control::Impl::GetAccessibilityObject(Self())->EmitTextCursorMoved(position);
    }
  }
  
@@@ -2172,6 -2166,11 +2166,11 @@@ void TextEditor::SetEditable(bool edita
    }
  }
  
+ void TextEditor::OnLayoutDirectionChanged(Actor actor, LayoutDirection::Type type)
+ {
+   mController->ChangedLayoutDirection();
+ }
  TextEditor::TextEditor()
  : Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)),
    mAnimationPeriod(0.0f, 0.0f),
@@@ -2201,63 -2200,61 +2200,63 @@@ TextEditor::~TextEditor(
  
  std::string TextEditor::AccessibleImpl::GetName()
  {
 -  auto slf = Toolkit::TextEditor::DownCast(Self());
 -  return slf.GetProperty(Toolkit::TextEditor::Property::TEXT)
 -    .Get<std::string>();
 +  auto self = Toolkit::TextEditor::DownCast(Self());
 +  return self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
  }
  
 -std::string TextEditor::AccessibleImpl::GetText(size_t startOffset,
 -                                                size_t endOffset)
 +std::string TextEditor::AccessibleImpl::GetText(size_t startOffset, size_t endOffset)
  {
    if(endOffset <= startOffset)
 +  {
      return {};
 +  }
  
 -  auto slf = Toolkit::TextEditor::DownCast(Self());
 -  auto txt =
 -    slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
 +  auto self = Toolkit::TextEditor::DownCast(Self());
 +  auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
  
 -  if(startOffset > txt.size() || endOffset > txt.size())
 +  if(startOffset > text.size() || endOffset > text.size())
 +  {
      return {};
 +  }
  
 -  return txt.substr(startOffset, endOffset - startOffset);
 +  return text.substr(startOffset, endOffset - startOffset);
  }
  
  size_t TextEditor::AccessibleImpl::GetCharacterCount()
  {
 -  auto slf = Toolkit::TextEditor::DownCast(Self());
 -  auto txt =
 -    slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
 +  auto self = Toolkit::TextEditor::DownCast(Self());
 +  auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
  
 -  return txt.size();
 +  return text.size();
  }
  
 -size_t TextEditor::AccessibleImpl::GetCaretOffset()
 +size_t TextEditor::AccessibleImpl::GetCursorOffset()
  {
    auto slf = Toolkit::TextEditor::DownCast(Self());
 -  return Dali::Toolkit::GetImpl(slf).getController()->GetCursorPosition();
 +  return Dali::Toolkit::GetImpl(slf).GetTextController()->GetCursorPosition();
  }
  
 -bool TextEditor::AccessibleImpl::SetCaretOffset(size_t offset)
 +bool TextEditor::AccessibleImpl::SetCursorOffset(size_t offset)
  {
    auto slf = Toolkit::TextEditor::DownCast(Self());
    auto txt = slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
    if(offset > txt.size())
 +  {
      return false;
 +  }
  
    auto& slfImpl = Dali::Toolkit::GetImpl(slf);
 -  slfImpl.getController()->ResetCursorPosition(offset);
 +  slfImpl.GetTextController()->ResetCursorPosition(offset);
    slfImpl.RequestTextRelayout();
 +
    return true;
  }
  
 -Dali::Accessibility::Range TextEditor::AccessibleImpl::GetTextAtOffset(
 -  size_t offset, Dali::Accessibility::TextBoundary boundary)
 +Dali::Accessibility::Range TextEditor::AccessibleImpl::GetTextAtOffset( size_t offset, Dali::Accessibility::TextBoundary boundary)
  {
 -  auto slf      = Toolkit::TextEditor::DownCast(Self());
 -  auto txt      = slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
 -  auto txt_size = txt.size();
 +  auto self = Toolkit::TextEditor::DownCast(Self());
 +  auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
 +  auto textSize = text.size();
  
    auto range = Dali::Accessibility::Range{};
  
    {
      case Dali::Accessibility::TextBoundary::CHARACTER:
      {
 -      if(offset < txt_size)
 +      if(offset < textSize)
        {
 -        range.content     = txt[offset];
 +        range.content     = text[offset];
          range.startOffset = offset;
          range.endOffset   = offset + 1;
        }
 +      break;
      }
 -    break;
      case Dali::Accessibility::TextBoundary::WORD:
      case Dali::Accessibility::TextBoundary::LINE:
      {
 -      auto txt_c_string = txt.c_str();
 -      auto breaks       = std::vector<char>(txt_size, 0);
 +      auto textString = text.c_str();
 +      auto breaks = std::vector<char>(textSize, 0);
 +
        if(boundary == Dali::Accessibility::TextBoundary::WORD)
 -        Accessibility::Accessible::FindWordSeparationsUtf8((const utf8_t*)txt_c_string, txt_size, "", breaks.data());
 +      {
 +        Accessibility::Accessible::FindWordSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
 +      }
        else
 -        Accessibility::Accessible::FindLineSeparationsUtf8((const utf8_t*)txt_c_string, txt_size, "", breaks.data());
 +      {
 +        Accessibility::Accessible::FindLineSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
 +      }
 +
        auto index   = 0u;
        auto counter = 0u;
 -      while(index < txt_size && counter <= offset)
 +      while(index < textSize && counter <= offset)
        {
          auto start = index;
          if(breaks[index])
          {
            while(breaks[index])
 +          {
              index++;
 +          }
            counter++;
          }
          else
          {
            if(boundary == Dali::Accessibility::TextBoundary::WORD)
 +          {
              index++;
 +          }
            if(boundary == Dali::Accessibility::TextBoundary::LINE)
 +          {
              counter++;
 +          }
          }
 +
          if((counter > 0) && ((counter - 1) == offset))
          {
 -          range.content     = txt.substr(start, index - start + 1);
 +          range.content     = text.substr(start, index - start + 1);
            range.startOffset = start;
            range.endOffset   = index + 1;
          }
 +
          if(boundary == Dali::Accessibility::TextBoundary::LINE)
 +        {
            index++;
 +        }
        }
 +      break;
      }
 -    break;
      case Dali::Accessibility::TextBoundary::SENTENCE:
      {
 -      /* not supported by efl */
 +      /* not supported by default */
 +      break;
      }
 -    break;
      case Dali::Accessibility::TextBoundary::PARAGRAPH:
      {
        /* Paragraph is not supported by libunibreak library */
 +      break;
      }
 -    break;
      default:
        break;
    }
    return range;
  }
  
 -Dali::Accessibility::Range
 -TextEditor::AccessibleImpl::GetSelection(size_t selectionNum)
 +Dali::Accessibility::Range TextEditor::AccessibleImpl::GetRangeOfSelection(size_t selectionIndex)
  {
    // Since DALi supports only one selection indexes higher than 0 are ignored
 -  if(selectionNum > 0)
 +  if(selectionIndex > 0)
 +  {
      return {};
 +  }
  
 -  auto        slf  = Toolkit::TextEditor::DownCast(Self());
 -  auto        ctrl = Dali::Toolkit::GetImpl(slf).getController();
 -  std::string ret;
 -  ctrl->RetrieveSelection(ret);
 -  auto r = ctrl->GetSelectionIndexes();
 +  auto self  = Toolkit::TextEditor::DownCast(Self());
 +  auto controller = Dali::Toolkit::GetImpl(self).GetTextController();
 +  std::string value{};
 +  controller->RetrieveSelection(value);
 +  auto indices = controller->GetSelectionIndexes();
  
 -  return {static_cast<size_t>(r.first), static_cast<size_t>(r.second), ret};
 +  return {static_cast<size_t>(indices.first), static_cast<size_t>(indices.second), value};
  }
  
 -bool TextEditor::AccessibleImpl::RemoveSelection(size_t selectionNum)
 +bool TextEditor::AccessibleImpl::RemoveSelection(size_t selectionIndex)
  {
    // Since DALi supports only one selection indexes higher than 0 are ignored
 -  if(selectionNum > 0)
 +  if(selectionIndex > 0)
 +  {
      return false;
 +  }
  
 -  auto slf = Toolkit::TextEditor::DownCast(Self());
 -  Dali::Toolkit::GetImpl(slf).getController()->SetSelection(0, 0);
 +  auto self = Toolkit::TextEditor::DownCast(Self());
 +  Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(0, 0);
    return true;
  }
  
 -bool TextEditor::AccessibleImpl::SetSelection(size_t selectionNum,
 -                                              size_t startOffset,
 -                                              size_t endOffset)
 +bool TextEditor::AccessibleImpl::SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset)
  {
    // Since DALi supports only one selection indexes higher than 0 are ignored
 -  if(selectionNum > 0)
 +  if(selectionIndex > 0)
 +  {
      return false;
 +  }
  
 -  auto slf = Toolkit::TextEditor::DownCast(Self());
 -  Dali::Toolkit::GetImpl(slf).getController()->SetSelection(startOffset,
 -                                                            endOffset);
 +  auto self = Toolkit::TextEditor::DownCast(Self());
 +  Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(startOffset, endOffset);
    return true;
  }
  
 -bool TextEditor::AccessibleImpl::CopyText(size_t startPosition,
 -                                          size_t endPosition)
 +bool TextEditor::AccessibleImpl::CopyText(size_t startPosition, size_t endPosition)
  {
    if(endPosition <= startPosition)
 +  {
      return false;
 +  }
  
 -  auto slf = Toolkit::TextEditor::DownCast(Self());
 -  auto txt = slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
 -  Dali::Toolkit::GetImpl(slf).getController()->CopyStringToClipboard(txt.substr(startPosition, endPosition - startPosition));
 +  auto self = Toolkit::TextEditor::DownCast(Self());
 +  auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
 +  Dali::Toolkit::GetImpl(self).GetTextController()->CopyStringToClipboard(text.substr(startPosition, endPosition - startPosition));
  
    return true;
  }
  
 -bool TextEditor::AccessibleImpl::CutText(size_t startPosition,
 -                                         size_t endPosition)
 +bool TextEditor::AccessibleImpl::CutText(size_t startPosition, size_t endPosition)
  {
    if(endPosition <= startPosition)
 +  {
      return false;
 +  }
  
 -  auto slf = Toolkit::TextEditor::DownCast(Self());
 -  auto txt = slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
 -  Dali::Toolkit::GetImpl(slf).getController()->CopyStringToClipboard(txt.substr(startPosition, endPosition - startPosition));
 +  auto self = Toolkit::TextEditor::DownCast(Self());
 +  auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
 +  Dali::Toolkit::GetImpl(self).GetTextController()->CopyStringToClipboard(text.substr(startPosition, endPosition - startPosition));
  
 -  slf.SetProperty(Toolkit::TextEditor::Property::TEXT,
 -                  txt.substr(0, startPosition) + txt.substr(endPosition));
 +  self.SetProperty(Toolkit::TextEditor::Property::TEXT, text.substr(0, startPosition) + text.substr(endPosition));
  
    return true;
  }
  
 -bool TextEditor::AccessibleImpl::DeleteText(size_t startPosition,
 -                                            size_t endPosition)
 +bool TextEditor::AccessibleImpl::DeleteText(size_t startPosition, size_t endPosition)
  {
    if(endPosition <= startPosition)
 +  {
      return false;
 +  }
  
 -  auto slf = Toolkit::TextEditor::DownCast(Self());
 -  auto txt = slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
 +  auto self = Toolkit::TextEditor::DownCast(Self());
 +  auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
  
 -  slf.SetProperty(Toolkit::TextEditor::Property::TEXT,
 -                  txt.substr(0, startPosition) + txt.substr(endPosition));
 +  self.SetProperty(Toolkit::TextEditor::Property::TEXT, text.substr(0, startPosition) + text.substr(endPosition));
  
    return true;
  }
@@@ -2436,12 -2414,12 +2435,12 @@@ Dali::Accessibility::States TextEditor:
  {
    using namespace Dali::Accessibility;
  
 -  auto states              = DevelControl::AccessibleImpl::CalculateStates();
 +  auto states = DevelControl::AccessibleImpl::CalculateStates();
    states[State::EDITABLE]  = true;
    states[State::FOCUSABLE] = true;
  
    Toolkit::Control focusControl = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl();
 -  if(self == focusControl)
 +  if(mSelf == focusControl)
    {
      states[State::FOCUSED] = true;
    }
    return states;
  }
  
 -bool TextEditor::AccessibleImpl::InsertText(size_t      startPosition,
 -                                            std::string text)
 +bool TextEditor::AccessibleImpl::InsertText(size_t startPosition, std::string text)
  {
 -  auto slf = Toolkit::TextEditor::DownCast(Self());
 -  auto txt = slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
 +  auto self = Toolkit::TextEditor::DownCast(Self());
 +  auto insertedText = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
  
 -  txt.insert(startPosition, text);
 +  insertedText.insert(startPosition, text);
  
 -  slf.SetProperty(Toolkit::TextEditor::Property::TEXT, std::move(txt));
 +  self.SetProperty(Toolkit::TextEditor::Property::TEXT, std::move(insertedText));
  
    return true;
  }
  
  bool TextEditor::AccessibleImpl::SetTextContents(std::string newContents)
  {
 -  auto slf = Toolkit::TextEditor::DownCast(Self());
 -  slf.SetProperty(Toolkit::TextEditor::Property::TEXT, std::move(newContents));
 +  auto self = Toolkit::TextEditor::DownCast(Self());
 +  self.SetProperty(Toolkit::TextEditor::Property::TEXT, std::move(newContents));
    return true;
  }
  
@@@ -109,13 -109,6 +109,13 @@@ public
    static bool DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor);
  
    /**
 +   * @brief Gets text controller
 +   *
 +   * @return The text controller
 +   */
 +  Text::ControllerPtr GetTextController();
 +
 +  /**
     * @copydoc TextEditor::TextChangedSignal()
     */
    Toolkit::TextEditor::TextChangedSignalType& TextChangedSignal();
@@@ -216,9 -209,9 +216,9 @@@ private: // From Contro
    void TextDeleted(unsigned int position, unsigned int length, const std::string& content) override;
  
    /**
 -   * @copydoc Text::EditableControlInterface::CaretMoved()
 +   * @copydoc Text::EditableControlInterface::CursorMoved()
     */
 -  void CaretMoved(unsigned int position) override;
 +  void CursorMoved(unsigned int position) override;
  
    /**
     * @copydoc Text::EditableControlInterface::TextChanged()
@@@ -313,6 -306,8 +313,6 @@@ public
     */
    void AnchorClicked(const std::string& href) override;
  
 -  Text::ControllerPtr getController();
 -
  private: // Implementation
    /**
     * @copydoc Dali::Toolkit::Text::Controller::(InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent)
    void OnScrollIndicatorAnimationFinished(Animation& animation);
  
    /**
+   * @brief Callback function for when the layout is changed.
+   * @param[in] actor The actor whose layoutDirection is changed.
+   * @param[in] type  The layoutDirection.
+   */
+   void OnLayoutDirectionChanged(Actor actor, LayoutDirection::Type type);
+   /**
     * Construct a new TextEditor.
     */
    TextEditor();
@@@ -447,89 -449,27 +454,89 @@@ private: // Dat
    bool  mScrollStarted : 1;
    bool  mTextChanged : 1; ///< If true, emits TextChangedSignal in next OnRelayout().
  
 +  /**
 +   * @brief This structure is to connect TextEditor with Accessible functions.
 +   */
    struct AccessibleImpl : public DevelControl::AccessibleImpl,
                            public virtual Dali::Accessibility::Text,
                            public virtual Dali::Accessibility::EditableText
    {
      using DevelControl::AccessibleImpl::AccessibleImpl;
  
 -    std::string           GetName() override;
 -    std::string           GetText(size_t startOffset, size_t endOffset) override;
 -    size_t                GetCharacterCount() override;
 -    size_t                GetCaretOffset() override;
 -    bool                  SetCaretOffset(size_t offset) override;
 -    Accessibility::Range  GetTextAtOffset(size_t offset, Accessibility::TextBoundary boundary) override;
 -    Accessibility::Range  GetSelection(size_t selectionNum) override;
 -    bool                  RemoveSelection(size_t selectionNum) override;
 -    bool                  SetSelection(size_t selectionNum, size_t startOffset, size_t endOffset) override;
 -    bool                  CopyText(size_t startPosition, size_t endPosition) override;
 -    bool                  CutText(size_t startPosition, size_t endPosition) override;
 +    /**
 +     * @copydoc Dali::Accessibility::Accessible::GetName()
 +     */
 +    std::string GetName() override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Text::GetText()
 +     */
 +    std::string GetText(size_t startOffset, size_t endOffset) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Text::GetCharacterCount()
 +     */
 +    size_t GetCharacterCount() override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Text::GetCursorOffset()
 +     */
 +    size_t GetCursorOffset() override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Text::SetCursorOffset()
 +     */
 +    bool SetCursorOffset(size_t offset) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Text::GetTextAtOffset()
 +     */
 +    Accessibility::Range GetTextAtOffset(size_t offset, Accessibility::TextBoundary boundary) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Text::GetRangeOfSelection()
 +     */
 +    Accessibility::Range GetRangeOfSelection(size_t selectionIndex) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Text::RemoveSelection()
 +     */
 +    bool RemoveSelection(size_t selectionIndex) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Text::SetRangeOfSelection()
 +     */
 +    bool SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::EditableText::CopyText()
 +     */
 +    bool CopyText(size_t startPosition, size_t endPosition) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::EditableText::CutText()
 +     */
 +    bool CutText(size_t startPosition, size_t endPosition) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Accessible::GetStates()
 +     */
      Accessibility::States CalculateStates() override;
 -    bool                  InsertText(size_t startPosition, std::string text) override;
 -    bool                  SetTextContents(std::string newContents) override;
 -    bool                  DeleteText(size_t startPosition, size_t endPosition) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::EditableText::InsertText()
 +     */
 +    bool InsertText(size_t startPosition, std::string text) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::EditableText::SetTextContents()
 +     */
 +    bool SetTextContents(std::string newContents) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::EditableText::DeleteText()
 +     */
 +    bool DeleteText(size_t startPosition, size_t endPosition) override;
    };
  };
  
@@@ -21,7 -21,6 +21,6 @@@
  // EXTERNAL INCLUDES
  #include <dali/devel-api/actors/actor-devel.h>
  #include <dali/devel-api/adaptor-framework/key-devel.h>
- #include <dali/devel-api/adaptor-framework/window-devel.h>
  #include <dali/devel-api/common/stage.h>
  #include <dali/devel-api/object/property-helper-devel.h>
  #include <dali/integration-api/debug.h>
@@@ -696,7 -695,7 +695,7 @@@ void TextField::SetProperty(BaseObject
        }
        case Toolkit::DevelTextField::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
        {
-         impl.mController->SetMatchSystemLanguageDirection(value.Get<bool>());
+         impl.mController->SetMatchLayoutDirection(value.Get<bool>() ? DevelText::MatchLayoutDirection::LOCALE : DevelText::MatchLayoutDirection::CONTENTS);
          break;
        }
        case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE_POPUP:
@@@ -1081,7 -1080,7 +1080,7 @@@ Property::Value TextField::GetProperty(
        }
        case Toolkit::DevelTextField::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
        {
-         value = impl.mController->IsMatchSystemLanguageDirection();
+         value = impl.mController->GetMatchLayoutDirection() != DevelText::MatchLayoutDirection::CONTENTS;
          break;
        }
        case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE_POPUP:
@@@ -1301,6 -1300,8 +1300,8 @@@ void TextField::OnInitialize(
    Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(stage.GetRootLayer().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
    mController->SetLayoutDirection(layoutDirection);
  
+   self.LayoutDirectionChangedSignal().Connect(this, &TextField::OnLayoutDirectionChanged);
    // Forward input events to controller
    EnableGestureDetection(static_cast<GestureType::Value>(GestureType::TAP | GestureType::PAN | GestureType::LONG_PRESS));
    GetTapGestureDetector().SetMaximumTapsRequired(2);
@@@ -1413,15 -1414,8 +1414,8 @@@ void TextField::OnRelayout(const Vector
    Vector2 contentSize(size.x - (padding.start + padding.end), size.y - (padding.top + padding.bottom));
  
    // Support Right-To-Left of padding
-   Dali::LayoutDirection::Type layoutDirection;
-   if(mController->IsMatchSystemLanguageDirection())
-   {
-     layoutDirection = static_cast<Dali::LayoutDirection::Type>(DevelWindow::Get(self).GetRootLayer().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
-   }
-   else
-   {
-     layoutDirection = static_cast<Dali::LayoutDirection::Type>(self.GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
-   }
+   Dali::LayoutDirection::Type layoutDirection = mController->GetLayoutDirection(self);
    if(Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection)
    {
      std::swap(padding.start, padding.end);
    }
  }
  
 -Text::ControllerPtr TextField::getController()
 +Text::ControllerPtr TextField::GetTextController()
  {
    return mController;
  }
@@@ -1746,11 -1740,11 +1740,11 @@@ void TextField::TextDeleted(unsigned in
    }
  }
  
 -void TextField::CaretMoved(unsigned int position)
 +void TextField::CursorMoved(unsigned int position)
  {
    if(Accessibility::IsUp())
    {
 -    Control::Impl::GetAccessibilityObject(Self())->EmitTextCaretMoved(position);
 +    Control::Impl::GetAccessibilityObject(Self())->EmitTextCursorMoved(position);
    }
  }
  
@@@ -1956,6 -1950,11 +1950,11 @@@ bool TextField::OnTouched(Actor actor, 
    return false;
  }
  
+ void TextField::OnLayoutDirectionChanged(Actor actor, LayoutDirection::Type type)
+ {
+   mController->ChangedLayoutDirection();
+ }
  void TextField::OnIdleSignal()
  {
    // Emits the change of input style signals.
@@@ -1988,64 -1987,60 +1987,64 @@@ TextField::~TextField(
  
  std::string TextField::AccessibleImpl::GetName()
  {
 -  auto slf = Toolkit::TextField::DownCast(Self());
 -  return slf.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
 +  auto self = Toolkit::TextField::DownCast(Self());
 +  return self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
  }
  
 -std::string TextField::AccessibleImpl::GetText(size_t startOffset,
 -                                               size_t endOffset)
 +std::string TextField::AccessibleImpl::GetText(size_t startOffset, size_t endOffset)
  {
    if(endOffset <= startOffset)
 +  {
      return {};
 +  }
  
 -  auto slf = Toolkit::TextField::DownCast(Self());
 -  auto txt =
 -    slf.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
 +  auto self = Toolkit::TextField::DownCast(Self());
 +  auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
  
 -  if(startOffset > txt.size() || endOffset > txt.size())
 +  if(startOffset > text.size() || endOffset > text.size())
 +  {
      return {};
 +  }
  
 -  return txt.substr(startOffset, endOffset - startOffset);
 +  return text.substr(startOffset, endOffset - startOffset);
  }
  
  size_t TextField::AccessibleImpl::GetCharacterCount()
  {
 -  auto slf = Toolkit::TextField::DownCast(Self());
 -  auto txt =
 -    slf.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
 +  auto self = Toolkit::TextField::DownCast(Self());
 +  auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
  
 -  return txt.size();
 +  return text.size();
  }
  
 -size_t TextField::AccessibleImpl::GetCaretOffset()
 +size_t TextField::AccessibleImpl::GetCursorOffset()
  {
 -  auto slf = Toolkit::TextField::DownCast(Self());
 -  return Dali::Toolkit::GetImpl(slf).getController()->GetCursorPosition();
 +  auto self = Toolkit::TextField::DownCast(Self());
 +  return Dali::Toolkit::GetImpl(self).GetTextController()->GetCursorPosition();
  }
  
 -bool TextField::AccessibleImpl::SetCaretOffset(size_t offset)
 +bool TextField::AccessibleImpl::SetCursorOffset(size_t offset)
  {
 -  auto slf = Toolkit::TextField::DownCast(Self());
 -  auto txt = slf.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
 -  if(offset > txt.size())
 +  auto self = Toolkit::TextField::DownCast(Self());
 +  auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
 +  if(offset > text.size())
 +  {
      return false;
 +  }
 +
 +  auto& selfImpl = Dali::Toolkit::GetImpl(self);
 +  selfImpl.GetTextController()->ResetCursorPosition(offset);
 +  selfImpl.RequestTextRelayout();
  
 -  auto& slfImpl = Dali::Toolkit::GetImpl(slf);
 -  slfImpl.getController()->ResetCursorPosition(offset);
 -  slfImpl.RequestTextRelayout();
    return true;
  }
  
  Dali::Accessibility::Range TextField::AccessibleImpl::GetTextAtOffset(
    size_t offset, Dali::Accessibility::TextBoundary boundary)
  {
 -  auto slf      = Toolkit::TextField::DownCast(Self());
 -  auto txt      = slf.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
 -  auto txt_size = txt.size();
 +  auto self = Toolkit::TextField::DownCast(Self());
 +  auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
 +  auto textSize = text.size();
  
    auto range = Dali::Accessibility::Range{};
  
    {
      case Dali::Accessibility::TextBoundary::CHARACTER:
      {
 -      if(offset < txt_size)
 +      if(offset < textSize)
        {
 -        range.content     = txt[offset];
 +        range.content     = text[offset];
          range.startOffset = offset;
          range.endOffset   = offset + 1;
        }
 +      break;
      }
 -    break;
      case Dali::Accessibility::TextBoundary::WORD:
      case Dali::Accessibility::TextBoundary::LINE:
      {
 -      auto txt_c_string = txt.c_str();
 -      auto breaks       = std::vector<char>(txt_size, 0);
 +      auto textString = text.c_str();
 +      auto breaks = std::vector<char>(textSize, 0);
 +
        if(boundary == Dali::Accessibility::TextBoundary::WORD)
 -        Accessibility::Accessible::FindWordSeparationsUtf8((const utf8_t*)txt_c_string, txt_size, "", breaks.data());
 +      {
 +        Accessibility::Accessible::FindWordSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
 +      }
        else
 -        Accessibility::Accessible::FindLineSeparationsUtf8((const utf8_t*)txt_c_string, txt_size, "", breaks.data());
 +      {
 +        Accessibility::Accessible::FindLineSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
 +      }
 +
        auto index   = 0u;
        auto counter = 0u;
 -      while(index < txt_size && counter <= offset)
 +      while(index < textSize && counter <= offset)
        {
          auto start = index;
          if(breaks[index])
          {
            while(breaks[index])
 +          {
              index++;
 +          }
            counter++;
          }
          else
          {
            if(boundary == Dali::Accessibility::TextBoundary::WORD)
 +          {
              index++;
 +          }
            if(boundary == Dali::Accessibility::TextBoundary::LINE)
 +          {
              counter++;
 +          }
          }
 +
          if((counter > 0) && ((counter - 1) == offset))
          {
 -          range.content     = txt.substr(start, index - start + 1);
 +          range.content     = text.substr(start, index - start + 1);
            range.startOffset = start;
            range.endOffset   = index + 1;
          }
 +
          if(boundary == Dali::Accessibility::TextBoundary::LINE)
 +        {
            index++;
 +        }
        }
 +      break;
      }
 -    break;
      case Dali::Accessibility::TextBoundary::SENTENCE:
      {
 -      /* not supported by efl */
 +      /* not supported by default */
 +      break;
      }
 -    break;
      case Dali::Accessibility::TextBoundary::PARAGRAPH:
      {
        /* Paragraph is not supported by libunibreak library */
 +      break;
      }
 -    break;
      default:
        break;
    }
    return range;
  }
  
 -Dali::Accessibility::Range
 -TextField::AccessibleImpl::GetSelection(size_t selectionNum)
 +Dali::Accessibility::Range TextField::AccessibleImpl::GetRangeOfSelection(size_t selectionIndex)
  {
    // Since DALi supports only one selection indexes higher than 0 are ignored
 -  if(selectionNum > 0)
 +  if(selectionIndex > 0)
 +  {
      return {};
 +  }
  
 -  auto        slf  = Toolkit::TextField::DownCast(Self());
 -  auto        ctrl = Dali::Toolkit::GetImpl(slf).getController();
 -  std::string ret;
 -  ctrl->RetrieveSelection(ret);
 -  auto r = ctrl->GetSelectionIndexes();
 +  auto self  = Toolkit::TextField::DownCast(Self());
 +  auto controller = Dali::Toolkit::GetImpl(self).GetTextController();
 +  std::string value{};
 +  controller->RetrieveSelection(value);
 +  auto indices = controller->GetSelectionIndexes();
  
 -  return {static_cast<size_t>(r.first), static_cast<size_t>(r.second), ret};
 +  return {static_cast<size_t>(indices.first), static_cast<size_t>(indices.second), value};
  }
  
 -bool TextField::AccessibleImpl::RemoveSelection(size_t selectionNum)
 +bool TextField::AccessibleImpl::RemoveSelection(size_t selectionIndex)
  {
    // Since DALi supports only one selection indexes higher than 0 are ignored
 -  if(selectionNum > 0)
 +  if(selectionIndex > 0)
 +  {
      return false;
 +  }
  
 -  auto slf = Toolkit::TextField::DownCast(Self());
 -  Dali::Toolkit::GetImpl(slf).getController()->SetSelection(0, 0);
 +  auto self = Toolkit::TextField::DownCast(Self());
 +  Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(0, 0);
    return true;
  }
  
 -bool TextField::AccessibleImpl::SetSelection(size_t selectionNum,
 -                                             size_t startOffset,
 -                                             size_t endOffset)
 +bool TextField::AccessibleImpl::SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset)
  {
    // Since DALi supports only one selection indexes higher than 0 are ignored
 -  if(selectionNum > 0)
 +  if(selectionIndex > 0)
 +  {
      return false;
 +  }
  
 -  auto slf = Toolkit::TextField::DownCast(Self());
 -  Dali::Toolkit::GetImpl(slf).getController()->SetSelection(startOffset,
 -                                                            endOffset);
 +  auto self = Toolkit::TextField::DownCast(Self());
 +  Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(startOffset, endOffset);
    return true;
  }
  
 -bool TextField::AccessibleImpl::CopyText(size_t startPosition,
 -                                         size_t endPosition)
 +bool TextField::AccessibleImpl::CopyText(size_t startPosition, size_t endPosition)
  {
    if(endPosition <= startPosition)
 +  {
      return false;
 +  }
  
 -  auto slf = Toolkit::TextField::DownCast(Self());
 -  auto txt = slf.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
 -  Dali::Toolkit::GetImpl(slf).getController()->CopyStringToClipboard(txt.substr(startPosition, endPosition - startPosition));
 +  auto self = Toolkit::TextField::DownCast(Self());
 +  auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
 +  Dali::Toolkit::GetImpl(self).GetTextController()->CopyStringToClipboard(text.substr(startPosition, endPosition - startPosition));
  
    return true;
  }
  
 -bool TextField::AccessibleImpl::CutText(size_t startPosition,
 -                                        size_t endPosition)
 +bool TextField::AccessibleImpl::CutText(size_t startPosition, size_t endPosition)
  {
    if(endPosition <= startPosition)
 +  {
      return false;
 +  }
  
 -  auto slf = Toolkit::TextField::DownCast(Self());
 -  auto txt = slf.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
 -  Dali::Toolkit::GetImpl(slf).getController()->CopyStringToClipboard(txt.substr(startPosition, endPosition - startPosition));
 +  auto self = Toolkit::TextField::DownCast(Self());
 +  auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
 +  Dali::Toolkit::GetImpl(self).GetTextController()->CopyStringToClipboard(text.substr(startPosition, endPosition - startPosition));
  
 -  slf.SetProperty(Toolkit::TextField::Property::TEXT,
 -                  txt.substr(0, startPosition) + txt.substr(endPosition));
 +  self.SetProperty(Toolkit::TextField::Property::TEXT, text.substr(0, startPosition) + text.substr(endPosition));
  
    return true;
  }
  
 -bool TextField::AccessibleImpl::DeleteText(size_t startPosition,
 -                                           size_t endPosition)
 +bool TextField::AccessibleImpl::DeleteText(size_t startPosition, size_t endPosition)
  {
    if(endPosition <= startPosition)
 +  {
      return false;
 +  }
  
 -  auto slf = Toolkit::TextField::DownCast(Self());
 -  auto txt = slf.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
 +  auto self = Toolkit::TextField::DownCast(Self());
 +  auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
  
 -  slf.SetProperty(Toolkit::TextField::Property::TEXT,
 -                  txt.substr(0, startPosition) + txt.substr(endPosition));
 +  self.SetProperty(Toolkit::TextField::Property::TEXT, text.substr(0, startPosition) + text.substr(endPosition));
  
    return true;
  }
@@@ -2230,7 -2206,7 +2229,7 @@@ Dali::Accessibility::States TextField::
    states[State::FOCUSABLE] = true;
  
    Toolkit::Control focusControl = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl();
 -  if(self == focusControl)
 +  if(mSelf == focusControl)
    {
      states[State::FOCUSED] = true;
    }
    return states;
  }
  
 -bool TextField::AccessibleImpl::InsertText(size_t      startPosition,
 -                                           std::string text)
 +bool TextField::AccessibleImpl::InsertText(size_t startPosition, std::string text)
  {
 -  auto slf = Toolkit::TextField::DownCast(Self());
 -  auto txt = slf.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
 +  auto self = Toolkit::TextField::DownCast(Self());
 +  auto insertedText = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
  
 -  txt.insert(startPosition, text);
 +  insertedText.insert(startPosition, text);
  
 -  slf.SetProperty(Toolkit::TextField::Property::TEXT, std::move(txt));
 +  self.SetProperty(Toolkit::TextField::Property::TEXT, std::move(insertedText));
  
    return true;
  }
  
  bool TextField::AccessibleImpl::SetTextContents(std::string newContents)
  {
 -  auto slf = Toolkit::TextField::DownCast(Self());
 -  slf.SetProperty(Toolkit::TextField::Property::TEXT, std::move(newContents));
 +  auto self = Toolkit::TextField::DownCast(Self());
 +  self.SetProperty(Toolkit::TextField::Property::TEXT, std::move(newContents));
    return true;
  }
  
@@@ -90,13 -90,6 +90,13 @@@ public
    static bool DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor);
  
    /**
 +   * @brief Gets text controller
 +   *
 +   * @return The text controller
 +   */
 +  Text::ControllerPtr GetTextController();
 +
 +  /**
     * @copydoc TextField::TextChangedSignal()
     */
    Toolkit::TextField::TextChangedSignalType& TextChangedSignal();
     */
    DevelTextField::InputFilteredSignalType& InputFilteredSignal();
  
 -  Text::ControllerPtr getController();
 -
  private: // From Control
    /**
     * @copydoc Control::OnInitialize()
    void TextDeleted(unsigned int position, unsigned int length, const std::string& content) override;
  
    /**
 -   * @copydoc Text::EditableControlInterface::CaretMoved()
 +   * @copydoc Text::EditableControlInterface::CursorMoved()
     */
 -  void CaretMoved(unsigned int position) override;
 +  void CursorMoved(unsigned int position) override;
  
    /**
     * @copydoc Text::EditableControlInterface::TextChanged()
@@@ -338,6 -333,13 +338,13 @@@ private: // Implementatio
    void EmitTextChangedSignal();
  
    /**
+    * @brief Callback function for when the layout is changed.
+    * @param[in] actor The actor whose layoutDirection is changed.
+    * @param[in] type  The layoutDirection.
+    */
+   void OnLayoutDirectionChanged(Actor actor, LayoutDirection::Type type);
+   /**
     * Construct a new TextField.
     */
    TextField();
    // Connection needed to re-render text, when a Text Field returns to the scene.
    void OnSceneConnect(Dali::Actor actor);
  
 -public: // For UTC only
 -  Text::ControllerPtr GetTextController()
 -  {
 -    return mController;
 -  }
 -
  private: // Data
    // Signals
    Toolkit::TextField::TextChangedSignalType        mTextChangedSignal;
    bool  mTextChanged : 1; ///< If true, emits TextChangedSignal in next OnRelayout().
  
  protected:
 +  /**
 +   * @brief This structure is to connect TextField with Accessible functions.
 +   */
    struct AccessibleImpl : public DevelControl::AccessibleImpl,
                            public virtual Dali::Accessibility::Text,
                            public virtual Dali::Accessibility::EditableText
    {
      using DevelControl::AccessibleImpl::AccessibleImpl;
  
 -    std::string           GetName() override;
 -    std::string           GetText(size_t startOffset, size_t endOffset) override;
 -    size_t                GetCharacterCount() override;
 -    size_t                GetCaretOffset() override;
 -    bool                  SetCaretOffset(size_t offset) override;
 -    Accessibility::Range  GetTextAtOffset(size_t offset, Accessibility::TextBoundary boundary) override;
 -    Accessibility::Range  GetSelection(size_t selectionNum) override;
 -    bool                  RemoveSelection(size_t selectionNum) override;
 -    bool                  SetSelection(size_t selectionNum, size_t startOffset, size_t endOffset) override;
 -    bool                  CopyText(size_t startPosition, size_t endPosition) override;
 -    bool                  CutText(size_t startPosition, size_t endPosition) override;
 +    /**
 +     * @copydoc Dali::Accessibility::Accessible::GetName()
 +     */
 +    std::string GetName() override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Text::GetText()
 +     */
 +    std::string GetText(size_t startOffset, size_t endOffset) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Text::GetCharacterCount()
 +     */
 +    size_t GetCharacterCount() override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Text::GetCursorOffset()
 +     */
 +    size_t GetCursorOffset() override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Text::SetCursorOffset()
 +     */
 +    bool SetCursorOffset(size_t offset) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Text::GetTextAtOffset()
 +     */
 +    Accessibility::Range GetTextAtOffset(size_t offset, Accessibility::TextBoundary boundary) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Text::GetRangeOfSelection()
 +     */
 +    Accessibility::Range GetRangeOfSelection(size_t selectionIndex) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Text::RemoveSelection()
 +     */
 +    bool RemoveSelection(size_t selectionIndex) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Text::SetRangeOfSelection()
 +     */
 +    bool SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::EditableText::CopyText()
 +     */
 +    bool CopyText(size_t startPosition, size_t endPosition) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::EditableText::CutText()
 +     */
 +    bool CutText(size_t startPosition, size_t endPosition) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Accessible::GetStates()
 +     */
      Accessibility::States CalculateStates() override;
 -    bool                  InsertText(size_t startPosition, std::string text) override;
 -    bool                  SetTextContents(std::string newContents) override;
 -    bool                  DeleteText(size_t startPosition, size_t endPosition) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::EditableText::InsertText()
 +     */
 +    bool InsertText(size_t startPosition, std::string text) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::EditableText::SetTextContents()
 +     */
 +    bool SetTextContents(std::string newContents) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::EditableText::DeleteText()
 +     */
 +    bool DeleteText(size_t startPosition, size_t endPosition) override;
    };
  };
  
@@@ -21,7 -21,6 +21,6 @@@
  // EXTERNAL INCLUDES
  #include <dali/devel-api/actors/actor-devel.h>
  #include <dali/devel-api/adaptor-framework/image-loading.h>
- #include <dali/devel-api/adaptor-framework/window-devel.h>
  #include <dali/devel-api/common/stage.h>
  #include <dali/devel-api/object/property-helper-devel.h>
  #include <dali/integration-api/debug.h>
@@@ -457,7 -456,7 +456,7 @@@ void TextLabel::SetProperty(BaseObject
        }
        case Toolkit::DevelTextLabel::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
        {
-         impl.mController->SetMatchSystemLanguageDirection(value.Get<bool>());
+         impl.mController->SetMatchLayoutDirection(value.Get<bool>() ? DevelText::MatchLayoutDirection::LOCALE : DevelText::MatchLayoutDirection::CONTENTS);
          break;
        }
        case Toolkit::DevelTextLabel::Property::TEXT_FIT:
    }
  }
  
 -Text::ControllerPtr TextLabel::getController()
 +Text::ControllerPtr TextLabel::GetTextController()
  {
    return mController;
  }
@@@ -688,7 -687,7 +687,7 @@@ Property::Value TextLabel::GetProperty(
        }
        case Toolkit::DevelTextLabel::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
        {
-         value = impl.mController->IsMatchSystemLanguageDirection();
+         value = impl.mController->GetMatchLayoutDirection() != DevelText::MatchLayoutDirection::CONTENTS;
          break;
        }
        case Toolkit::DevelTextLabel::Property::TEXT_FIT:
@@@ -786,6 -785,8 +785,8 @@@ void TextLabel::OnInitialize(
    Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(stage.GetRootLayer().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
    mController->SetLayoutDirection(layoutDirection);
  
+   self.LayoutDirectionChangedSignal().Connect(this, &TextLabel::OnLayoutDirectionChanged);
    // Forward input events to controller
    EnableGestureDetection(static_cast<GestureType::Value>(GestureType::TAP));
    GetTapGestureDetector().SetMaximumTapsRequired(1);
@@@ -899,8 -900,10 +900,10 @@@ void TextLabel::OnRelayout(const Vector
  {
    DALI_LOG_INFO(gLogFilter, Debug::General, "TextLabel::OnRelayout\n");
  
+   Actor self = Self();
    Extents padding;
-   padding = Self().GetProperty<Extents>(Toolkit::Control::Property::PADDING);
+   padding = self.GetProperty<Extents>(Toolkit::Control::Property::PADDING);
  
    Vector2 contentSize(size.x - (padding.start + padding.end), size.y - (padding.top + padding.bottom));
  
    }
  
    // Support Right-To-Left
-   Dali::LayoutDirection::Type layoutDirection;
-   if(mController->IsMatchSystemLanguageDirection())
-   {
-     layoutDirection = static_cast<Dali::LayoutDirection::Type>(DevelWindow::Get(Self()).GetRootLayer().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
-   }
-   else
-   {
-     layoutDirection = static_cast<Dali::LayoutDirection::Type>(Self().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
-   }
+   Dali::LayoutDirection::Type layoutDirection = mController->GetLayoutDirection(self);
    const Text::Controller::UpdateTextType updateTextType = mController->Relayout(contentSize, layoutDirection);
  
    if((Text::Controller::NONE_UPDATED != (Text::Controller::MODEL_UPDATED & updateTextType)) || mTextUpdateNeeded)
@@@ -1048,6 -1044,11 +1044,11 @@@ void TextLabel::ScrollingFinished(
    RequestTextRelayout();
  }
  
+ void TextLabel::OnLayoutDirectionChanged(Actor actor, LayoutDirection::Type type)
+ {
+   mController->ChangedLayoutDirection();
+ }
  TextLabel::TextLabel()
  : Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)),
    mRenderingBackend(DEFAULT_RENDERING_BACKEND),
@@@ -1061,8 -1062,8 +1062,8 @@@ TextLabel::~TextLabel(
  
  std::string TextLabel::AccessibleImpl::GetNameRaw()
  {
 -  auto slf = Toolkit::TextLabel::DownCast(Self());
 -  return slf.GetProperty(Toolkit::TextLabel::Property::TEXT).Get<std::string>();
 +  auto self = Toolkit::TextLabel::DownCast(Self());
 +  return self.GetProperty(Toolkit::TextLabel::Property::TEXT).Get<std::string>();
  }
  
  Property::Index TextLabel::AccessibleImpl::GetNamePropertyIndex()
    return Toolkit::TextLabel::Property::TEXT;
  }
  
 -std::string TextLabel::AccessibleImpl::GetText(size_t startOffset,
 -                                               size_t endOffset)
 +std::string TextLabel::AccessibleImpl::GetText(size_t startOffset, size_t endOffset)
  {
    if(endOffset <= startOffset)
 +  {
      return {};
 +  }
  
 -  auto slf = Toolkit::TextLabel::DownCast(Self());
 -  auto txt =
 -    slf.GetProperty(Toolkit::TextLabel::Property::TEXT).Get<std::string>();
 +  auto self = Toolkit::TextLabel::DownCast(Self());
 +  auto text = self.GetProperty(Toolkit::TextLabel::Property::TEXT).Get<std::string>();
  
 -  if(startOffset > txt.size() || endOffset > txt.size())
 +  if(startOffset > text.size() || endOffset > text.size())
 +  {
      return {};
 +  }
  
 -  return txt.substr(startOffset, endOffset - startOffset);
 +  return text.substr(startOffset, endOffset - startOffset);
  }
  
  size_t TextLabel::AccessibleImpl::GetCharacterCount()
  {
 -  auto slf = Toolkit::TextLabel::DownCast(Self());
 -  auto txt =
 -    slf.GetProperty(Toolkit::TextLabel::Property::TEXT).Get<std::string>();
 +  auto self = Toolkit::TextLabel::DownCast(Self());
 +  auto text = self.GetProperty(Toolkit::TextLabel::Property::TEXT).Get<std::string>();
  
 -  return txt.size();
 +  return text.size();
  }
  
 -size_t TextLabel::AccessibleImpl::GetCaretOffset()
 +size_t TextLabel::AccessibleImpl::GetCursorOffset()
  {
    return {};
  }
  
 -bool TextLabel::AccessibleImpl::SetCaretOffset(size_t offset)
 +bool TextLabel::AccessibleImpl::SetCursorOffset(size_t offset)
  {
    return {};
  }
  
 -Dali::Accessibility::Range TextLabel::AccessibleImpl::GetTextAtOffset(
 -  size_t offset, Dali::Accessibility::TextBoundary boundary)
 +Dali::Accessibility::Range TextLabel::AccessibleImpl::GetTextAtOffset(size_t offset, Dali::Accessibility::TextBoundary boundary)
  {
 -  auto slf      = Toolkit::TextLabel::DownCast(Self());
 -  auto txt      = slf.GetProperty(Toolkit::TextLabel::Property::TEXT).Get<std::string>();
 -  auto txt_size = txt.size();
 +  auto self = Toolkit::TextLabel::DownCast(Self());
 +  auto text = self.GetProperty(Toolkit::TextLabel::Property::TEXT).Get<std::string>();
 +  auto textSize = text.size();
  
    auto range = Dali::Accessibility::Range{};
  
    {
      case Dali::Accessibility::TextBoundary::CHARACTER:
      {
 -      if(offset < txt_size)
 +      if(offset < textSize)
        {
 -        range.content     = txt[offset];
 +        range.content     = text[offset];
          range.startOffset = offset;
          range.endOffset   = offset + 1;
        }
 +      break;
      }
 -    break;
      case Dali::Accessibility::TextBoundary::WORD:
      case Dali::Accessibility::TextBoundary::LINE:
      {
 -      auto txt_c_string = txt.c_str();
 -      auto breaks       = std::vector<char>(txt_size, 0);
 +      auto textString = text.c_str();
 +      auto breaks = std::vector<char>(textSize, 0);
 +
        if(boundary == Dali::Accessibility::TextBoundary::WORD)
 -        Accessibility::Accessible::FindWordSeparationsUtf8((const utf8_t*)txt_c_string, txt_size, "", breaks.data());
 +      {
 +        Accessibility::Accessible::FindWordSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
 +      }
        else
 -        Accessibility::Accessible::FindLineSeparationsUtf8((const utf8_t*)txt_c_string, txt_size, "", breaks.data());
 -      auto index   = 0u;
 +      {
 +        Accessibility::Accessible::FindLineSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
 +      }
 +
 +      auto index = 0u;
        auto counter = 0u;
 -      while(index < txt_size && counter <= offset)
 +      while(index < textSize && counter <= offset)
        {
          auto start = index;
          if(breaks[index])
          {
            while(breaks[index])
 +          {
              index++;
 +          }
            counter++;
          }
          else
          {
            if(boundary == Dali::Accessibility::TextBoundary::WORD)
 +          {
              index++;
 +          }
            if(boundary == Dali::Accessibility::TextBoundary::LINE)
 +          {
              counter++;
 +          }
          }
 +
          if((counter > 0) && ((counter - 1) == offset))
          {
 -          range.content     = txt.substr(start, index - start + 1);
 +          range.content     = text.substr(start, index - start + 1);
            range.startOffset = start;
            range.endOffset   = index + 1;
          }
 +
          if(boundary == Dali::Accessibility::TextBoundary::LINE)
 +        {
            index++;
 +        }
        }
 +      break;
      }
 -    break;
      case Dali::Accessibility::TextBoundary::SENTENCE:
      {
 -      /* not supported by efl */
 +      /* not supported by default */
 +      break;
      }
 -    break;
      case Dali::Accessibility::TextBoundary::PARAGRAPH:
      {
        /* Paragraph is not supported by libunibreak library */
 +      break;
      }
 -    break;
      default:
        break;
    }
    return range;
  }
  
 -Dali::Accessibility::Range
 -TextLabel::AccessibleImpl::GetSelection(size_t selectionNum)
 +Dali::Accessibility::Range TextLabel::AccessibleImpl::GetRangeOfSelection(size_t selectionIndex)
  {
    // Since DALi supports only one selection indexes higher than 0 are ignored
 -  if(selectionNum > 0)
 +  if(selectionIndex > 0)
 +  {
      return {};
 +  }
  
 -  auto        slf  = Toolkit::TextLabel::DownCast(Self());
 -  auto        ctrl = Dali::Toolkit::GetImpl(slf).getController();
 -  std::string ret;
 -  ctrl->RetrieveSelection(ret);
 -  auto r = ctrl->GetSelectionIndexes();
 +  auto self  = Toolkit::TextLabel::DownCast(Self());
 +  auto controller = Dali::Toolkit::GetImpl(self).GetTextController();
 +  std::string value{};
 +  controller->RetrieveSelection(value);
 +  auto indices = controller->GetSelectionIndexes();
  
 -  return {static_cast<size_t>(r.first), static_cast<size_t>(r.second), ret};
 +  return {static_cast<size_t>(indices.first), static_cast<size_t>(indices.second), value};
  }
  
 -bool TextLabel::AccessibleImpl::RemoveSelection(size_t selectionNum)
 +bool TextLabel::AccessibleImpl::RemoveSelection(size_t selectionIndex)
  {
    // Since DALi supports only one selection indexes higher than 0 are ignored
 -  if(selectionNum > 0)
 +  if(selectionIndex > 0)
 +  {
      return false;
 +  }
  
 -  auto slf = Toolkit::TextLabel::DownCast(Self());
 -  Dali::Toolkit::GetImpl(slf).getController()->SetSelection(0, 0);
 +  auto self = Toolkit::TextLabel::DownCast(Self());
 +  Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(0, 0);
    return true;
  }
  
 -bool TextLabel::AccessibleImpl::SetSelection(size_t selectionNum,
 -                                             size_t startOffset,
 -                                             size_t endOffset)
 +bool TextLabel::AccessibleImpl::SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset)
  {
    // Since DALi supports only one selection indexes higher than 0 are ignored
 -  if(selectionNum > 0)
 +  if(selectionIndex > 0)
 +  {
      return false;
 +  }
  
 -  auto slf = Toolkit::TextLabel::DownCast(Self());
 -  Dali::Toolkit::GetImpl(slf).getController()->SetSelection(startOffset,
 -                                                            endOffset);
 +  auto self = Toolkit::TextLabel::DownCast(Self());
 +  Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(startOffset, endOffset);
    return true;
  }
  
@@@ -86,12 -86,7 +86,12 @@@ public
     */
    static bool DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor);
  
 -  Text::ControllerPtr getController();
 +  /**
 +   * @brief Gets text controller
 +   *
 +   * @return The text controller
 +   */
 +  Text::ControllerPtr GetTextController();
  
  private: // From Control
    /**
@@@ -182,6 -177,13 +182,13 @@@ private
      return mTextScroller;
    }
  
+   /**
+    * @brief Callback function for when the layout is changed.
+    * @param[in] actor The actor whose layoutDirection is changed.
+    * @param[in] type  The layoutDirection.
+    */
+   void OnLayoutDirectionChanged(Actor actor, LayoutDirection::Type type);
  private: // Data
    Text::ControllerPtr   mController;
    Text::TextScrollerPtr mTextScroller;
    bool mTextUpdateNeeded : 1;
  
  protected:
 +  /**
 +   * @brief This structure is to connect TextLabel with Accessible functions.
 +   */
    struct AccessibleImpl : public DevelControl::AccessibleImpl,
                            public virtual Dali::Accessibility::Text
    {
      using DevelControl::AccessibleImpl::AccessibleImpl;
  
 -    std::string          GetText(size_t startOffset, size_t endOffset) override;
 -    size_t               GetCharacterCount() override;
 -    size_t               GetCaretOffset() override;
 -    bool                 SetCaretOffset(size_t offset) override;
 +    /**
 +     * @copydoc Dali::Accessibility::Text::GetText()
 +     */
 +    std::string GetText(size_t startOffset, size_t endOffset) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Text::GetCharacterCount()
 +     */
 +    size_t GetCharacterCount() override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Text::GetCursorOffset()
 +     */
 +    size_t GetCursorOffset() override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Text::SetCursorOffset()
 +     */
 +    bool SetCursorOffset(size_t offset) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Text::GetTextAtOffset()
 +     */
      Accessibility::Range GetTextAtOffset(size_t offset, Accessibility::TextBoundary boundary) override;
 -    Accessibility::Range GetSelection(size_t selectionNum) override;
 -    bool                 RemoveSelection(size_t selectionNum) override;
 -    bool                 SetSelection(size_t selectionNum, size_t startOffset, size_t endOffset) override;
 -    std::string          GetNameRaw() override;
 -    Property::Index      GetNamePropertyIndex() override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Text::GetRangeOfSelection()
 +     */
 +    Accessibility::Range GetRangeOfSelection(size_t selectionIndex) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Text::RemoveSelection()
 +     */
 +    bool RemoveSelection(size_t selectionIndex) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Text::SetRangeOfSelection()
 +     */
 +    bool SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset) override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Text::GetNameRaw()
 +     */
 +    std::string GetNameRaw() override;
 +
 +    /**
 +     * @copydoc Dali::Accessibility::Text::GetNamePropertyIndex()
 +     */
 +    Property::Index GetNamePropertyIndex() override;
    };
  };
  
@@@ -797,7 -797,7 +797,7 @@@ bool Controller::Impl::UpdateModel(Oper
                           startIndex,
                           requestedNumberOfCharacters,
                           bidirectionalInfo,
-                          mModel->mMatchSystemLanguageDirection,
+                          (mModel->mMatchLayoutDirection != DevelText::MatchLayoutDirection::CONTENTS),
                           mLayoutDirection);
  
      if(0u != bidirectionalInfo.Count())
@@@ -1737,7 -1737,7 +1737,7 @@@ void Controller::Impl::GetCursorPositio
      cursorInfo.primaryCursorHeight = cursorInfo.lineHeight;
  
      bool isRTL = false;
-     if(mModel->mMatchSystemLanguageDirection)
+     if(mModel->mMatchLayoutDirection != DevelText::MatchLayoutDirection::CONTENTS)
      {
        isRTL = mLayoutDirection == LayoutDirection::RIGHT_TO_LEFT;
      }
@@@ -2106,10 -2106,8 +2106,10 @@@ Actor Controller::Impl::CreateBackgroun
  
        // Get the background color of the character.
        // The color index zero is reserved for the default background color (i.e. Color::TRANSPARENT)
 -      const ColorIndex backgroundColorIndex = (nullptr == backgroundColorsBuffer) ? 0u : *(backgroundColorIndicesBuffer + i);
 -      const Vector4&   backgroundColor      = (0u == backgroundColorIndex) ? defaultBackgroundColor : *(backgroundColorsBuffer + backgroundColorIndex - 1u);
 +      const bool       isMarkupBackground       = mView.IsMarkupBackgroundColorSet();
 +      const ColorIndex backgroundColorIndex     = isMarkupBackground ? *(backgroundColorIndicesBuffer + i) : 0u;
 +      const bool       isDefaultBackgroundColor = (0u == backgroundColorIndex);
 +      const Vector4&   backgroundColor          = isDefaultBackgroundColor ? defaultBackgroundColor : *(backgroundColorsBuffer + backgroundColorIndex - 1u);
  
        mModel->mVisualModel->GetNumberOfLines(i, 1, lineIndex, numberOfLines);
        Length lineHeight = lineRun[lineIndex].ascender + -(lineRun[lineIndex].descender) + lineRun[lineIndex].lineSpacing;
@@@ -129,7 -129,7 +129,7 @@@ const ColorIndex* const Model::GetBackg
  
  bool const Model::IsMarkupBackgroundColorSet() const
  {
 -  return (mVisualModel->mBackgroundColorIndices.Count() > 0);
 +  return (mVisualModel->mBackgroundColors.Count() > 0);
  }
  
  const Vector4& Model::GetDefaultColor() const
@@@ -229,14 -229,17 +229,17 @@@ Model::Model(
    mAlignmentOffset(0.0f),
    mElideEnabled(false),
    mIgnoreSpacesAfterText(true),
-   mMatchSystemLanguageDirection(true)
+   mMatchLayoutDirection(DevelText::MatchLayoutDirection::INHERIT)
  {
    mLogicalModel = LogicalModel::New();
    mVisualModel  = VisualModel::New();
  
    // Check environment variable for DALI_MATCH_SYSTEM_LANGUAGE_DIRECTION
-   auto match                    = Dali::EnvironmentVariable::GetEnvironmentVariable(DALI_ENV_MATCH_SYSTEM_LANGUAGE_DIRECTION);
-   mMatchSystemLanguageDirection = match ? (std::atoi(match) == 0 ? false : true) : mMatchSystemLanguageDirection;
+   auto match = Dali::EnvironmentVariable::GetEnvironmentVariable(DALI_ENV_MATCH_SYSTEM_LANGUAGE_DIRECTION);
+   if(match && (std::atoi(match) == 0))
+   {
+     mMatchLayoutDirection = DevelText::MatchLayoutDirection::CONTENTS;
+   }
  }
  
  Model::~Model()