fix wrong cursor position in TextField 25/254125/1
authorBowon Ryu <bowon.ryu@samsung.com>
Tue, 23 Feb 2021 07:01:06 +0000 (16:01 +0900)
committerBowon Ryu <bowon.ryu@samsung.com>
Tue, 23 Feb 2021 07:46:35 +0000 (16:46 +0900)
When the placeholder font size is bigger/smaller than default font size,
the cursor is positioned incorrectly.

this is because mScrollPosition.y is calculated based on layoutSize.height at CalculateVerticalOffset().
(this is not based on cursor height.
in issue situation, layoutSize.height is bigger/smaller than defaultFontLineHeight.)

This patch prevents the wrong positioning of cursor when the layoutSize.height is bigger/smaller than defaultFontLineHeight.
And update the glyphPositions using recalculated offset.

This issue only occurs with placeholder + single line text control. (vertical alignment)

I hope this modification does not affect the calculation of other texts.
So, update the glyphPositions in CalculateVerticalOffset().

Change-Id: I031635bb8c5ed790700d89de4b046515bff5bf73
Signed-off-by: Bowon Ryu <bowon.ryu@samsung.com>
dali-toolkit/internal/text/text-controller-relayouter.cpp

index 2b362c0..8888859 100644 (file)
@@ -636,14 +636,27 @@ bool Controller::Relayouter::DoRelayout(Controller& controller, const Size& size
 
 void Controller::Relayouter::CalculateVerticalOffset(Controller& controller, const Size& controlSize)
 {
-  Controller::Impl& impl       = *controller.mImpl;
-  ModelPtr&         model      = impl.mModel;
-  Size              layoutSize = model->mVisualModel->GetLayoutSize();
+  Controller::Impl& impl          = *controller.mImpl;
+  ModelPtr&         model         = impl.mModel;
+  VisualModelPtr&   visualModel   = model->mVisualModel;
+  Size              layoutSize    = model->mVisualModel->GetLayoutSize();
+  Size              oldLayoutSize = layoutSize;
+  float             offsetY       = 0.f;
+  bool              needRecalc    = false;
+  float             defaultFontLineHeight = impl.GetDefaultFontLineHeight();
 
   if(fabsf(layoutSize.height) < Math::MACHINE_EPSILON_1000)
   {
     // Get the line height of the default font.
-    layoutSize.height = impl.GetDefaultFontLineHeight();
+    layoutSize.height = defaultFontLineHeight;
+  }
+
+  if (layoutSize.height != defaultFontLineHeight)
+  {
+    // This code prevents the wrong positioning of cursor when the layout size is bigger/smaller than defaultFontLineHeight.
+    // This situation occurs when the size of placeholder text is different from the default text.
+    layoutSize.height = defaultFontLineHeight;
+    needRecalc = true;
   }
 
   switch(model->mVerticalAlignment)
@@ -651,19 +664,34 @@ void Controller::Relayouter::CalculateVerticalOffset(Controller& controller, con
     case VerticalAlignment::TOP:
     {
       model->mScrollPosition.y = 0.f;
+      offsetY = 0.f;
       break;
     }
     case VerticalAlignment::CENTER:
     {
       model->mScrollPosition.y = floorf(0.5f * (controlSize.height - layoutSize.height)); // try to avoid pixel alignment.
+      if (needRecalc) offsetY  = floorf(0.5f * (layoutSize.height - oldLayoutSize.height));
       break;
     }
     case VerticalAlignment::BOTTOM:
     {
       model->mScrollPosition.y = controlSize.height - layoutSize.height;
+      if (needRecalc) offsetY  = layoutSize.height - oldLayoutSize.height;
       break;
     }
   }
+
+  if (needRecalc)
+  {
+    // Update glyphPositions according to recalculation.
+    const Length positionCount = visualModel->mGlyphPositions.Count();
+    Vector<Vector2>& glyphPositions = visualModel->mGlyphPositions;
+    for(Length index = 0u; index < positionCount; index++)
+    {
+      glyphPositions[index].y += offsetY;
+    }
+  }
+
 }
 
 } // namespace Text