[Tizen] Fix bidirectional line info index issue 55/319555/1
authorBowon Ryu <bowon.ryu@samsung.com>
Wed, 12 Feb 2025 05:33:16 +0000 (14:33 +0900)
committerBowon Ryu <bowon.ryu@samsung.com>
Thu, 13 Feb 2025 00:56:56 +0000 (09:56 +0900)
In the RTL case, when text is inserted or removed in the middle of a bidi paragraph,
the character index of line info is not updated,
so there is a problem that the line info is damaged in reorders.

This patch updates the index of line info based on the bidi paragraph info updated in SetBidirectionalInfo.

Change-Id: Ifc1ddfa5f15ce89be967ce57241a093030be323d
Signed-off-by: Bowon Ryu <bowon.ryu@samsung.com>
automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/toolkit-text-utils.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-BidirectionalSupport.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp
dali-toolkit/devel-api/text/text-utils-devel.cpp
dali-toolkit/internal/text/async-text/async-text-loader-impl.cpp
dali-toolkit/internal/text/bidirectional-support.cpp
dali-toolkit/internal/text/bidirectional-support.h
dali-toolkit/internal/text/controller/text-controller-impl-data-clearer.cpp
dali-toolkit/internal/text/controller/text-controller-impl-model-updater.cpp

index efa834e0617a5579d5385775b46fa632c15bc87f..20dcdd495016860e3e6dcb2f9b2d02d9b537592c 100644 (file)
@@ -263,7 +263,8 @@ void CreateTextModel(const std::string&                text,
                        lineBreakInfo,
                        0u,
                        characterCount,
-                       bidirectionalInfo);
+                       bidirectionalInfo,
+                       logicalModel->mBidirectionalLineInfo);
 
   // Create the paragraph info.
   logicalModel->CreateParagraphInfo(0u,
index 90b729f26c779a092e8178e63b43dcc221501e38..2e91f1f965b84e4976e53afcf61c51abf9348203 100644 (file)
@@ -139,7 +139,8 @@ bool SetBidirectionalInfoTest(const SetBidirectionalInfoData& data)
                        logicalModel->mLineBreakInfo,
                        data.startIndex,
                        data.numberOfCharacters,
-                       bidirectionalInfo);
+                       bidirectionalInfo,
+                       logicalModel->mBidirectionalLineInfo);
 
   // 4) Compare with the expected results.
   if(data.numberOfParagraphs != bidirectionalInfo.Count())
index d63762feb18b89800b22b945d786150ad0bc8017..b4ca2efe13a5e36d96b658321fc6c6581d7fba93 100644 (file)
@@ -2734,6 +2734,13 @@ int utcDaliTextEditorEvent06(void)
   DALI_TEST_EQUALS("Hello\nworld\nHello world", editor.GetProperty<std::string>(TextEditor::Property::TEXT), TEST_LOCATION);
 
   // For coverage
+  editor.SetProperty(TextEditor::Property::TEXT, "الاخيرالسطر1\nالاخيرالسطر2\nالاخيرالسطر3\nالاخيرالسطر4");
+  application.SendNotification();
+  application.Render();
+
+  application.ProcessEvent(GenerateKey("d", "", "ㅁ", KEY_D_CODE, 0, 0, Integration::KeyEvent::DOWN, "ㅁ", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+  application.ProcessEvent(GenerateKey("d", "", "ኢ", KEY_D_CODE, 0, 0, Integration::KeyEvent::DOWN, "ኢ", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
+
   application.ProcessEvent(GenerateKey("", "", "", 0, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE));
   application.SendNotification();
   application.Render();
index 483fc3f60c31ab588d13884a8e0d88ad8424894a..8a4153013f39b0ce24385936412af3d0d54922a7 100644 (file)
@@ -314,7 +314,8 @@ void ShapeTextPreprocess(const RendererParameters& textParameters, TextAbstracti
                        lineBreakInfo,
                        0u,
                        numberOfCharacters,
-                       bidirectionalInfo);
+                       bidirectionalInfo,
+                       textModel->mLogicalModel->mBidirectionalLineInfo);
 
   const bool hasBidirectionalText = 0u != bidirectionalInfo.Count();
   if(hasBidirectionalText)
index 8ad19ef51d310a2785fbd84986e616ad3dba92f6..3023b9af504d83a8fcbd209e3cebfcf5d715033f 100644 (file)
@@ -147,6 +147,9 @@ void AsyncTextLoader::ClearTextModelData()
 
     free(bidiLineInfo.visualToLogicalMap);
     bidiLineInfo.visualToLogicalMap = NULL;
+
+    free(bidiLineInfo.visualToLogicalMapSecondHalf);
+    bidiLineInfo.visualToLogicalMapSecondHalf = NULL;
   }
   mTextModel->mLogicalModel->mBidirectionalLineInfo.Clear();
 
@@ -399,6 +402,7 @@ void AsyncTextLoader::Update(AsyncTextParameters& parameters)
                        0u,
                        numberOfCharacters,
                        bidirectionalInfo,
+                       mTextModel->mLogicalModel->mBidirectionalLineInfo,
                        (mTextModel->mMatchLayoutDirection != DevelText::MatchLayoutDirection::CONTENTS),
                        parameters.layoutDirection);
 
index 2b3c87e7766e0fe9095f0779de43a59d576fa9f1..a5700ab8166b73740dfac1a7f3ec314756c8d0ad 100644 (file)
@@ -35,6 +35,7 @@ void SetBidirectionalInfo(TextAbstraction::BidirectionalSupport& bidirectionalSu
                           CharacterIndex                         startIndex,
                           Length                                 numberOfCharacters,
                           Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo,
+                          Vector<BidirectionalLineInfoRun>&      lineInfoRuns,
                           bool                                   matchLayoutDirection,
                           Dali::LayoutDirection::Type            layoutDirection)
 {
@@ -128,6 +129,10 @@ void SetBidirectionalInfo(TextAbstraction::BidirectionalSupport& bidirectionalSu
     }
   }
 
+  // Find the first bidi line index to update.
+  bool                      updateLineInfoRuns  = false;
+  BidirectionalLineRunIndex updateLineInfoIndex = 0u;
+
   // Update indices of the bidi runs.
   for(Vector<BidirectionalParagraphInfoRun>::Iterator it    = bidirectionalInfo.Begin() + bidiInfoIndex,
                                                       endIt = bidirectionalInfo.End();
@@ -136,8 +141,31 @@ void SetBidirectionalInfo(TextAbstraction::BidirectionalSupport& bidirectionalSu
   {
     BidirectionalParagraphInfoRun& run = *it;
 
+    if(!updateLineInfoRuns)
+    {
+      updateLineInfoRuns  = true;
+      updateLineInfoIndex = run.characterRun.characterIndex;
+    }
+
     run.characterRun.characterIndex += numberOfCharacters;
   }
+
+  // Update indices of the bidi line runs.
+  if(updateLineInfoRuns)
+  {
+    bool firstLineFound = false;
+    for(auto& lineInfoRun : lineInfoRuns)
+    {
+      if(lineInfoRun.characterRun.characterIndex == updateLineInfoIndex)
+      {
+        firstLineFound = true;
+      }
+      if(firstLineFound)
+      {
+        lineInfoRun.characterRun.characterIndex += numberOfCharacters;
+      }
+    }
+  }
 }
 
 void ReorderLine(TextAbstraction::BidirectionalSupport& bidirectionalSupport,
index c44e2325939e50cdbd5073387c2a53cdca125872..b4228e81253a34ad7537b442690154407ee7fa3d 100644 (file)
@@ -45,6 +45,7 @@ namespace Text
  * @param[in] startIndex The character from where the bidirectional info is set.
  * @param[in] numberOfCharacters The number of characters.
  * @param[out] bidirectionalInfo Vector with the bidirectional infor for each paragraph.
+ * @param[out] lineInfoRuns Line runs with the visual to logical conversion maps.
  * @param[in] matchLayoutDirection Whether match for layout direction or not.
  * @param[in] layoutDirection The direction of the layout.
  */
@@ -55,6 +56,7 @@ void SetBidirectionalInfo(TextAbstraction::BidirectionalSupport& bidirectionalSu
                           CharacterIndex                         startIndex,
                           Length                                 numberOfCharacters,
                           Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo,
+                          Vector<BidirectionalLineInfoRun>&      lineInfoRuns,
                           bool                                   matchLayoutDirection = false,
                           Dali::LayoutDirection::Type            layoutDirection      = LayoutDirection::LEFT_TO_RIGHT);
 
index 3822fb305ae8f28936c29c8fdf48847e8ef3a23a..a5de333e8d72f152886866a5b2a04d3676c58d63 100644 (file)
@@ -65,6 +65,9 @@ void ControllerImplDataClearer::ClearFullModelData(Controller::Impl& impl, Contr
 
         free(bidiLineInfo.visualToLogicalMap);
         bidiLineInfo.visualToLogicalMap = NULL;
+
+        free(bidiLineInfo.visualToLogicalMapSecondHalf);
+        bidiLineInfo.visualToLogicalMapSecondHalf = NULL;
       }
       model->mLogicalModel->mBidirectionalLineInfo.Clear();
     }
@@ -165,6 +168,9 @@ void ControllerImplDataClearer::ClearCharacterModelData(Controller::Impl& impl,
 
         free(bidiLineInfo.visualToLogicalMap);
         bidiLineInfo.visualToLogicalMap = NULL;
+
+        free(bidiLineInfo.visualToLogicalMapSecondHalf);
+        bidiLineInfo.visualToLogicalMapSecondHalf = NULL;
       }
 
       model->mLogicalModel->mBidirectionalLineInfo.Erase(bidirectionalLineInfoBuffer + startRemoveIndex,
index a87a8704c02bca9c4ad283b0f7056bc4a1e14450..9e710d9b293288dccb58d7e4aade0904d2e6ba05 100644 (file)
@@ -306,6 +306,7 @@ bool ControllerImplModelUpdater::Update(Controller::Impl& impl, OperationsMask o
                          startIndex,
                          requestedNumberOfCharacters,
                          bidirectionalInfo,
+                         impl.mModel->mLogicalModel->mBidirectionalLineInfo,
                          (impl.mModel->mMatchLayoutDirection != DevelText::MatchLayoutDirection::CONTENTS),
                          impl.mLayoutDirection);