Support Underline to Markup using underlined-character-run
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / text-controller-impl.cpp
index ec00903..8140c84 100644 (file)
@@ -587,7 +587,7 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired)
   Vector<Character>& srcCharacters = mModel->mLogicalModel->mText;
   Vector<Character>  displayCharacters;
   bool               useHiddenText = false;
   Vector<Character>& srcCharacters = mModel->mLogicalModel->mText;
   Vector<Character>  displayCharacters;
   bool               useHiddenText = false;
-  if(mHiddenInput && mEventData != NULL && !mEventData->mIsShowingPlaceholderText)
+  if(mHiddenInput && mEventData != nullptr && !mEventData->mIsShowingPlaceholderText)
   {
     mHiddenInput->Substitute(srcCharacters, displayCharacters);
     useHiddenText = true;
   {
     mHiddenInput->Substitute(srcCharacters, displayCharacters);
     useHiddenText = true;
@@ -697,7 +697,7 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired)
       TextAbstraction::FontDescription defaultFontDescription;
       TextAbstraction::PointSize26Dot6 defaultPointSize = TextAbstraction::FontClient::DEFAULT_POINT_SIZE * mFontSizeScale;
 
       TextAbstraction::FontDescription defaultFontDescription;
       TextAbstraction::PointSize26Dot6 defaultPointSize = TextAbstraction::FontClient::DEFAULT_POINT_SIZE * mFontSizeScale;
 
-      if(IsShowingPlaceholderText() && mEventData && (NULL != mEventData->mPlaceholderFont))
+      if(IsShowingPlaceholderText() && mEventData && (nullptr != mEventData->mPlaceholderFont))
       {
         // If the placeholder font is set specifically, only placeholder font is changed.
         defaultFontDescription = mEventData->mPlaceholderFont->mFontDescription;
       {
         // If the placeholder font is set specifically, only placeholder font is changed.
         defaultFontDescription = mEventData->mPlaceholderFont->mFontDescription;
@@ -706,7 +706,7 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired)
           defaultPointSize = mEventData->mPlaceholderFont->mDefaultPointSize * mFontSizeScale * 64u;
         }
       }
           defaultPointSize = mEventData->mPlaceholderFont->mDefaultPointSize * mFontSizeScale * 64u;
         }
       }
-      else if(NULL != mFontDefaults)
+      else if(nullptr != mFontDefaults)
       {
         // Set the normal font and the placeholder font.
         defaultFontDescription = mFontDefaults->mFontDescription;
       {
         // Set the normal font and the placeholder font.
         defaultFontDescription = mFontDefaults->mFontDescription;
@@ -807,7 +807,8 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired)
     // Create the 'number of glyphs' per character and the glyph to character conversion tables.
     mModel->mVisualModel->CreateGlyphsPerCharacterTable(startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters);
     mModel->mVisualModel->CreateCharacterToGlyphTable(startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters);
     // Create the 'number of glyphs' per character and the glyph to character conversion tables.
     mModel->mVisualModel->CreateGlyphsPerCharacterTable(startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters);
     mModel->mVisualModel->CreateCharacterToGlyphTable(startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters);
-    updated = true;
+
+   updated = true;
   }
 
   const Length numberOfGlyphs = glyphs.Count() - currentNumberOfGlyphs;
   }
 
   const Length numberOfGlyphs = glyphs.Count() - currentNumberOfGlyphs;
@@ -830,7 +831,7 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired)
     updated = true;
   }
 
     updated = true;
   }
 
-  if((NULL != mEventData) &&
+  if((nullptr != mEventData) &&
      mEventData->mPreEditFlag &&
      (0u != mModel->mVisualModel->mCharactersToGlyph.Count()))
   {
      mEventData->mPreEditFlag &&
      (0u != mModel->mVisualModel->mCharactersToGlyph.Count()))
   {
@@ -858,6 +859,12 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired)
           underlineRun.glyphIndex     = attrData.startIndex + numberOfCommit;
           underlineRun.numberOfGlyphs = numberOfIndices;
           mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
           underlineRun.glyphIndex     = attrData.startIndex + numberOfCommit;
           underlineRun.numberOfGlyphs = numberOfIndices;
           mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
+
+          //Mark-up processor case
+          if(mModel->mVisualModel->IsMarkupProcessorEnabled())
+          {
+            CopyUnderlinedFromLogicalToVisualModels(false);
+          }
           break;
         }
         case Dali::InputMethodContext::PreeditStyle::REVERSE:
           break;
         }
         case Dali::InputMethodContext::PreeditStyle::REVERSE:
@@ -902,6 +909,12 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired)
           underlineRun.glyphIndex     = attrData.startIndex + numberOfCommit;
           underlineRun.numberOfGlyphs = numberOfIndices;
           mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
           underlineRun.glyphIndex     = attrData.startIndex + numberOfCommit;
           underlineRun.numberOfGlyphs = numberOfIndices;
           mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
+
+          //Mark-up processor case
+          if(mModel->mVisualModel->IsMarkupProcessorEnabled())
+          {
+            CopyUnderlinedFromLogicalToVisualModels(false);
+          }
           break;
         }
         case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_2:
           break;
         }
         case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_2:
@@ -917,6 +930,12 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired)
           underlineRun.glyphIndex     = attrData.startIndex + numberOfCommit;
           underlineRun.numberOfGlyphs = numberOfIndices;
           mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
           underlineRun.glyphIndex     = attrData.startIndex + numberOfCommit;
           underlineRun.numberOfGlyphs = numberOfIndices;
           mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
+
+          //Mark-up processor case
+          if(mModel->mVisualModel->IsMarkupProcessorEnabled())
+          {
+            CopyUnderlinedFromLogicalToVisualModels(false);
+          }
           break;
         }
         case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_3:
           break;
         }
         case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_3:
@@ -932,6 +951,12 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired)
           underlineRun.glyphIndex     = attrData.startIndex + numberOfCommit;
           underlineRun.numberOfGlyphs = numberOfIndices;
           mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
           underlineRun.glyphIndex     = attrData.startIndex + numberOfCommit;
           underlineRun.numberOfGlyphs = numberOfIndices;
           mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
+
+          //Mark-up processor case
+          if(mModel->mVisualModel->IsMarkupProcessorEnabled())
+          {
+            CopyUnderlinedFromLogicalToVisualModels(false);
+          }
           break;
         }
         case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_4:
           break;
         }
         case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_4:
@@ -947,6 +972,12 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired)
           underlineRun.glyphIndex     = attrData.startIndex + numberOfCommit;
           underlineRun.numberOfGlyphs = numberOfIndices;
           mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
           underlineRun.glyphIndex     = attrData.startIndex + numberOfCommit;
           underlineRun.numberOfGlyphs = numberOfIndices;
           mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
+
+          //Mark-up processor case
+          if(mModel->mVisualModel->IsMarkupProcessorEnabled())
+          {
+            CopyUnderlinedFromLogicalToVisualModels(false);
+          }
           break;
         }
         case Dali::InputMethodContext::PreeditStyle::NONE:
           break;
         }
         case Dali::InputMethodContext::PreeditStyle::NONE:
@@ -985,6 +1016,21 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired)
     updated = true;
   }
 
     updated = true;
   }
 
+  if((NO_OPERATION != (SHAPE_TEXT & operations)) &&
+      ! ((nullptr != mEventData) &&
+         mEventData->mPreEditFlag &&
+         (0u != mModel->mVisualModel->mCharactersToGlyph.Count())))
+  {
+    //Mark-up processor case
+    if(mModel->mVisualModel->IsMarkupProcessorEnabled())
+    {
+      CopyUnderlinedFromLogicalToVisualModels(true);
+    }
+
+    updated = true;
+  }
+
+
   // The estimated number of lines. Used to avoid reallocations when layouting.
   mTextUpdateInfo.mEstimatedNumberOfLines = std::max(mModel->mVisualModel->mLines.Count(), mModel->mLogicalModel->mParagraphInfo.Count());
 
   // The estimated number of lines. Used to avoid reallocations when layouting.
   mTextUpdateInfo.mEstimatedNumberOfLines = std::max(mModel->mVisualModel->mLines.Count(), mModel->mLogicalModel->mParagraphInfo.Count());
 
@@ -1064,7 +1110,7 @@ void Controller::Impl::RetrieveDefaultInputStyle(InputStyle& inputStyle)
 float Controller::Impl::GetDefaultFontLineHeight()
 {
   FontId defaultFontId = 0u;
 float Controller::Impl::GetDefaultFontLineHeight()
 {
   FontId defaultFontId = 0u;
-  if(NULL == mFontDefaults)
+  if(nullptr == mFontDefaults)
   {
     TextAbstraction::FontDescription fontDescription;
     defaultFontId = mFontClient.GetFontId(fontDescription, TextAbstraction::FontClient::DEFAULT_POINT_SIZE * mFontSizeScale);
   {
     TextAbstraction::FontDescription fontDescription;
     defaultFontId = mFontClient.GetFontId(fontDescription, TextAbstraction::FontClient::DEFAULT_POINT_SIZE * mFontSizeScale);
@@ -1384,7 +1430,7 @@ void Controller::Impl::SetPopupButtons()
 
 void Controller::Impl::ChangeState(EventData::State newState)
 {
 
 void Controller::Impl::ChangeState(EventData::State newState)
 {
-  if(NULL == mEventData)
+  if(nullptr == mEventData)
   {
     // Nothing to do if there is no text input.
     return;
   {
     // Nothing to do if there is no text input.
     return;
@@ -1700,7 +1746,7 @@ void Controller::Impl::GetCursorPosition(CharacterIndex logical,
 
 CharacterIndex Controller::Impl::CalculateNewCursorIndex(CharacterIndex index) const
 {
 
 CharacterIndex Controller::Impl::CalculateNewCursorIndex(CharacterIndex index) const
 {
-  if(NULL == mEventData)
+  if(nullptr == mEventData)
   {
     // Nothing to do if there is no text input.
     return 0u;
   {
     // Nothing to do if there is no text input.
     return 0u;
@@ -1750,7 +1796,7 @@ CharacterIndex Controller::Impl::CalculateNewCursorIndex(CharacterIndex index) c
 void Controller::Impl::UpdateCursorPosition(const CursorInfo& cursorInfo)
 {
   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "-->Controller::UpdateCursorPosition %p\n", this);
 void Controller::Impl::UpdateCursorPosition(const CursorInfo& cursorInfo)
 {
   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "-->Controller::UpdateCursorPosition %p\n", this);
-  if(NULL == mEventData)
+  if(nullptr == mEventData)
   {
     // Nothing to do if there is no text input.
     DALI_LOG_INFO(gLogFilter, Debug::Verbose, "<--Controller::UpdateCursorPosition no event data\n");
   {
     // Nothing to do if there is no text input.
     DALI_LOG_INFO(gLogFilter, Debug::Verbose, "<--Controller::UpdateCursorPosition no event data\n");
@@ -1925,7 +1971,7 @@ void Controller::Impl::ScrollTextToMatchCursor()
 
 void Controller::Impl::RequestRelayout()
 {
 
 void Controller::Impl::RequestRelayout()
 {
-  if(NULL != mControlInterface)
+  if(nullptr != mControlInterface)
   {
     mControlInterface->RequestTextRelayout();
   }
   {
     mControlInterface->RequestTextRelayout();
   }
@@ -2095,6 +2141,32 @@ Actor Controller::Impl::CreateBackgroundActor()
   return actor;
 }
 
   return actor;
 }
 
+void Controller::Impl::CopyUnderlinedFromLogicalToVisualModels(bool shouldClearPreUnderlineRuns)
+{
+    //Underlined character runs for markup-processor
+    const Vector<UnderlinedCharacterRun>& underlinedCharacterRuns = mModel->mLogicalModel->mUnderlinedCharacterRuns;
+    const Vector<GlyphIndex>&             charactersToGlyph       = mModel->mVisualModel->mCharactersToGlyph;
+    const Vector<Length>&                 glyphsPerCharacter      = mModel->mVisualModel->mGlyphsPerCharacter;
+
+    if(shouldClearPreUnderlineRuns)
+    {
+        mModel->mVisualModel->mUnderlineRuns.Clear();
+    }
+
+    for(Vector<UnderlinedCharacterRun>::ConstIterator it = underlinedCharacterRuns.Begin(), endIt = underlinedCharacterRuns.End(); it != endIt; ++it)
+    {
+        CharacterIndex characterIndex = it->characterRun.characterIndex;
+        Length numberOfCharacters = it->characterRun.numberOfCharacters;
+        for(Length index=0u; index<numberOfCharacters; index++)
+        {
+          GlyphRun underlineGlyphRun;
+          underlineGlyphRun.glyphIndex     = charactersToGlyph[characterIndex + index];
+          underlineGlyphRun.numberOfGlyphs = glyphsPerCharacter[characterIndex + index];
+          mModel->mVisualModel->mUnderlineRuns.PushBack(underlineGlyphRun);
+        }
+    }
+}
+
 } // namespace Text
 
 } // namespace Toolkit
 } // namespace Text
 
 } // namespace Toolkit