Add GetLineBoundingRectangle API. 92/282292/25
authorsarajammal <s.al-jammal@partner.samsung.com>
Sun, 25 Sep 2022 15:26:12 +0000 (18:26 +0300)
committersarajammal <s.al-jammal@partner.samsung.com>
Thu, 3 Nov 2022 13:41:02 +0000 (16:41 +0300)
Calculate the line size and position:
- X, the left starting point of the line.
- Y, the left top point of the line.
- Width.
- Height.

Function prototype: GetLineBoundingRectangle(ModelPtr model, uint32_t lineIndex);

Add new API to TextGeometry.

Reference patches:
https://review.tizen.org/gerrit/c/platform/core/uifw/dali-toolkit/+/266891

Change-Id: I742a44bd406bc13d1c3ec35bce3049b467d21962

18 files changed:
automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/test-text-geometry-utils.cpp
automated-tests/src/dali-toolkit/test-text-geometry-utils.h
automated-tests/src/dali-toolkit/utc-Dali-TextGeometry.cpp [new file with mode: 0644]
dali-toolkit/devel-api/file.list
dali-toolkit/devel-api/text/text-geometry-devel.cpp [new file with mode: 0644]
dali-toolkit/devel-api/text/text-geometry-devel.h [new file with mode: 0644]
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/controller/text-controller.cpp
dali-toolkit/internal/text/controller/text-controller.h
dali-toolkit/internal/text/line-run.h
dali-toolkit/internal/text/text-geometry.cpp
dali-toolkit/internal/text/text-geometry.h

index 7076e8a..2cdf4c8 100755 (executable)
@@ -42,6 +42,7 @@ SET(TC_SOURCES
   utc-Dali-TableView.cpp
   utc-Dali-TextEditor.cpp
   utc-Dali-TextField.cpp
+  utc-Dali-TextGeometry.cpp
   utc-Dali-TextLabel.cpp
   utc-Dali-TextSelectionPopup.cpp
   utc-Dali-TextSelectionPopupMirroringLTR.cpp
index b2f0411..6ca87ad 100644 (file)
@@ -34,4 +34,12 @@ void CheckGeometryResult(Vector<Vector2> positionsList, Vector<Vector2> sizeList
   }
 }
 
+void CheckRectGeometryResult(Rect<> rectGeometry, Rect<> expectedRectGeometry)
+{
+  DALI_TEST_EQUALS((float)rectGeometry.x, (float)expectedRectGeometry.x, TEST_LOCATION);
+  DALI_TEST_EQUALS((float)rectGeometry.y, (float)expectedRectGeometry.y, TEST_LOCATION);
+  DALI_TEST_EQUALS((float)rectGeometry.width, (float)expectedRectGeometry.width, TEST_LOCATION);
+  DALI_TEST_EQUALS((float)rectGeometry.height, (float)expectedRectGeometry.height, TEST_LOCATION);
+}
+
 }
\ No newline at end of file
index 4aa2a33..41050eb 100644 (file)
@@ -27,6 +27,7 @@
 namespace TestTextGeometryUtils
 {
 void CheckGeometryResult(Vector<Vector2> positionsList, Vector<Vector2> sizeList, Vector<Vector2> expectedPositions, Vector<Vector2> expectedSizes);
+void CheckRectGeometryResult(Rect<> rectGeometry, Rect<> expectedRectGeometry);
 }
 
 #endif // TOOLKIT_TEXT_GEOMETRY_UTILS_H
diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TextGeometry.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TextGeometry.cpp
new file mode 100644 (file)
index 0000000..34f8d1e
--- /dev/null
@@ -0,0 +1,331 @@
+
+
+/*
+ * Copyright (c) 2022 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <iostream>
+
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/devel-api/controls/text-controls/text-label-devel.h>
+#include <dali-toolkit/devel-api/controls/text-controls/text-field-devel.h>
+#include <dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h>
+#include <dali-toolkit/devel-api/text/bitmap-font.h>
+#include <dali-toolkit/devel-api/text/rendering-backend.h>
+#include <dali-toolkit/devel-api/text/text-enumerations-devel.h>
+#include <dali-toolkit/devel-api/text/text-utils-devel.h>
+#include <dali-toolkit/devel-api/text/text-geometry-devel.h>
+#include "test-text-geometry-utils.h"
+
+using namespace Dali;
+using namespace Toolkit;
+using namespace Text;
+
+void dali_textgeometry_startup(void)
+{
+  test_return_value = TET_UNDEF;
+}
+
+void dali_textgeometry_cleanup(void)
+{
+  test_return_value = TET_PASS;
+}
+
+int UtcDaliTextGeometryGetLineBoundingRectangleLabel(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliTextGeometryGetLineBoundingRectangleLabel");
+
+  TextLabel label = TextLabel::New();
+  DALI_TEST_CHECK(label);
+
+  application.GetScene().Add(label);
+
+  float lineSpacing = -20.f;
+
+  label.SetProperty(Actor::Property::SIZE, Vector2(450.0f, 300.f));
+  label.SetProperty(TextLabel::Property::POINT_SIZE, 10.f);
+  label.SetProperty(DevelTextLabel::Property::LINE_SPACING, lineSpacing);
+  label.SetProperty(TextLabel::Property::MULTI_LINE, true);
+  label.SetProperty(TextLabel::Property::TEXT, "Lorem ipsum dolor sit amet, \n consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
+
+  application.SendNotification();
+  application.Render();
+
+  Rect<> lineGeometry = TextGeometry::GetLineBoundingRectangle(label, 1);
+
+  Rect<> expectedLineGeometry = {0, 16, 420, 16};
+
+  TestTextGeometryUtils::CheckRectGeometryResult(lineGeometry, expectedLineGeometry);
+
+  END_TEST;
+}
+
+int UtcDaliTextGeometryGetLineBoundingRectangleEditor(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliTextGeometryGetLineBoundingRectangleEditor");
+
+  TextEditor editor = TextEditor::New();
+  DALI_TEST_CHECK(editor);
+
+  application.GetScene().Add(editor);
+
+  editor.SetProperty(Actor::Property::SIZE, Vector2(160.0f, 250.f));
+  editor.SetProperty(TextEditor::Property::POINT_SIZE, 10.f);
+  editor.SetProperty(TextEditor::Property::TEXT, "Lorem ipsum dolor sit amet, \n consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
+
+  application.SendNotification();
+  application.Render();
+
+  Rect<> lineGeometry = TextGeometry::GetLineBoundingRectangle(editor, 0);
+
+  Rect<> expectedLineGeometry = {0, 0, 91, 36};
+
+  TestTextGeometryUtils::CheckRectGeometryResult(lineGeometry, expectedLineGeometry);
+
+  END_TEST;
+}
+
+int UtcDaliTextGeometryGetLineBoundingRectangleField(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliTextGeometryGetLineBoundingRectangleField");
+
+  TextField field = TextField::New();
+  DALI_TEST_CHECK(field);
+
+  application.GetScene().Add(field);
+
+  field.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+  field.SetProperty(Actor::Property::SIZE, Vector2(450.0f, 350.f));
+  field.SetProperty(TextField::Property::POINT_SIZE, 10.f);
+  field.SetProperty(TextField::Property::TEXT, "مرحبا بالعالم");
+
+  application.SendNotification();
+  application.Render();
+
+  Rect<> lineGeometry = TextGeometry::GetLineBoundingRectangle(field, 0);
+
+  Rect<> expectedLineGeometry = {0, 0, 163, 36};
+
+  TestTextGeometryUtils::CheckRectGeometryResult(lineGeometry, expectedLineGeometry);
+
+  END_TEST;
+}
+
+int UtcDaliTextGeometryEmptyTextGetLineBoundingRectangleLabel(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliTextGeometryEmptyTextGetLineBoundingRectangleLabel");
+
+  TextLabel label = TextLabel::New();
+  DALI_TEST_CHECK(label);
+
+  application.GetScene().Add(label);
+
+  label.SetProperty(Actor::Property::SIZE, Vector2(450.0f, 300.f));
+  label.SetProperty(TextLabel::Property::POINT_SIZE, 10.f);
+  label.SetProperty(TextLabel::Property::TEXT, "");
+
+  application.SendNotification();
+  application.Render();
+
+  Rect<> lineGeometry = TextGeometry::GetLineBoundingRectangle(label, 0);
+
+  Rect<> expectedLineGeometry = {0, 0, 0, 0};
+
+  TestTextGeometryUtils::CheckRectGeometryResult(lineGeometry, expectedLineGeometry);
+
+  END_TEST;
+}
+
+int UtcDaliTextGeometryLineSpacingPositiveGetLineBoundingRectangleLabel(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliTextGeometryLineSpacingPositiveGetLineBoundingRectangleLabel");
+
+  TextLabel label = TextLabel::New();
+  DALI_TEST_CHECK(label);
+
+  application.GetScene().Add(label);
+
+  float lineSpacing = 20.f;
+
+  label.SetProperty(Actor::Property::SIZE, Vector2(450.0f, 300.f));
+  label.SetProperty(TextLabel::Property::POINT_SIZE, 10.f);
+  label.SetProperty(DevelTextLabel::Property::LINE_SPACING, lineSpacing);
+  label.SetProperty(TextLabel::Property::MULTI_LINE, true);
+  label.SetProperty(TextLabel::Property::TEXT, "Lorem ipsum dolor sit amet, \n consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
+
+  application.SendNotification();
+  application.Render();
+
+  Rect<> lineGeometry = TextGeometry::GetLineBoundingRectangle(label, 1);
+
+  Rect<> expectedLineGeometry = {0, 56, 420, 56};
+
+  TestTextGeometryUtils::CheckRectGeometryResult(lineGeometry, expectedLineGeometry);
+
+  END_TEST;
+}
+
+int UtcDaliTextGeometryWithVerticalLineAlignmentTopGetLineBoundingRectangleLabel(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliTextGeometryWithVerticalLineAlignmentTopGetLineBoundingRectangleLabel");
+
+  TextLabel label = TextLabel::New();
+  DALI_TEST_CHECK(label);
+
+  application.GetScene().Add(label);
+
+  label.SetProperty(Actor::Property::SIZE, Vector2(450.0f, 300.f));
+  label.SetProperty(TextLabel::Property::POINT_SIZE, 10.f);
+  label.SetProperty(TextLabel::Property::MULTI_LINE, true);
+  label.SetProperty(Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "TOP");
+  label.SetProperty(TextLabel::Property::TEXT, "Lorem ipsum dolor sit amet, \n consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
+
+  application.SendNotification();
+  application.Render();
+
+  Rect<> lineGeometry = TextGeometry::GetLineBoundingRectangle(label, 1);
+
+  Rect<> expectedLineGeometry = {0, 36, 420, 36};
+
+  TestTextGeometryUtils::CheckRectGeometryResult(lineGeometry, expectedLineGeometry);
+
+  END_TEST;
+}
+
+int UtcDaliTextGeometryWithVerticalLineAlignmentBottomGetLineBoundingRectangleLabel(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliTextGeometryWithVerticalLineAlignmentBottomGetLineBoundingRectangleLabel");
+
+  TextLabel label = TextLabel::New();
+  DALI_TEST_CHECK(label);
+
+  application.GetScene().Add(label);
+
+  label.SetProperty(Actor::Property::SIZE, Vector2(450.0f, 300.f));
+  label.SetProperty(TextLabel::Property::POINT_SIZE, 10.f);
+  label.SetProperty(TextLabel::Property::MULTI_LINE, true);
+  label.SetProperty(Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "BOTTOM");
+  label.SetProperty(TextLabel::Property::TEXT, "Lorem ipsum dolor sit amet, \n consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
+
+  application.SendNotification();
+  application.Render();
+
+  Rect<> lineGeometry = TextGeometry::GetLineBoundingRectangle(label, 1);
+
+  Rect<> expectedLineGeometry = {0, 36, 420, 36};
+
+  TestTextGeometryUtils::CheckRectGeometryResult(lineGeometry, expectedLineGeometry);
+
+  END_TEST;
+}
+int UtcDaliTextGeometryWithEllipsisMiddleGetLineBoundingRectangleLabel(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliTextGeometryWithEllipsisMiddleGetLineBoundingRectangleLabel");
+
+  TextLabel label = TextLabel::New();
+  DALI_TEST_CHECK(label);
+
+  application.GetScene().Add(label);
+
+  label.SetProperty(Actor::Property::SIZE, Vector2(450.0f, 300.f));
+  label.SetProperty(TextLabel::Property::POINT_SIZE, 10.f);
+  label.SetProperty(TextLabel::Property::MULTI_LINE, true);
+  label.SetProperty(TextLabel::Property::ELLIPSIS, true);
+  label.SetProperty(DevelTextLabel::Property::ELLIPSIS_POSITION, DevelText::EllipsisPosition::MIDDLE);
+  label.SetProperty(TextLabel::Property::TEXT, "Lorem ipsum dolor sit amet, \n consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
+
+  application.SendNotification();
+  application.Render();
+
+  Rect<> lineGeometry = TextGeometry::GetLineBoundingRectangle(label, 1);
+
+  Rect<> expectedLineGeometry = {0, 36, 420, 36};
+
+  TestTextGeometryUtils::CheckRectGeometryResult(lineGeometry, expectedLineGeometry);
+
+  END_TEST;
+}
+
+int UtcDaliTextGeometryWithEllipsisStartGetLineBoundingRectangleLabel(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliTextGeometryWithEllipsisStartGetLineBoundingRectangleLabel");
+
+  TextLabel label = TextLabel::New();
+  DALI_TEST_CHECK(label);
+
+  application.GetScene().Add(label);
+
+  label.SetProperty(Actor::Property::SIZE, Vector2(450.0f, 300.f));
+  label.SetProperty(TextLabel::Property::POINT_SIZE, 10.f);
+  label.SetProperty(TextLabel::Property::MULTI_LINE, true);
+  label.SetProperty(TextLabel::Property::ELLIPSIS, true);
+  label.SetProperty(DevelTextLabel::Property::ELLIPSIS_POSITION, DevelText::EllipsisPosition::START);
+  label.SetProperty(TextLabel::Property::TEXT, "Lorem ipsum dolor sit amet, \n consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
+
+  application.SendNotification();
+  application.Render();
+
+  Rect<> lineGeometry = TextGeometry::GetLineBoundingRectangle(label, 1);
+
+  Rect<> expectedLineGeometry = {0, 36, 420, 36};
+
+  TestTextGeometryUtils::CheckRectGeometryResult(lineGeometry, expectedLineGeometry);
+
+  END_TEST;
+}
+
+int UtcDaliTextGeometryWithEllipsisEndGetLineBoundingRectangleLabel(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliTextGeometryWithEllipsisEndGetLineBoundingRectangleLabel");
+
+  TextLabel label = TextLabel::New();
+  DALI_TEST_CHECK(label);
+
+  application.GetScene().Add(label);
+
+  label.SetProperty(Actor::Property::SIZE, Vector2(450.0f, 300.f));
+  label.SetProperty(TextLabel::Property::POINT_SIZE, 10.f);
+  label.SetProperty(TextLabel::Property::MULTI_LINE, true);
+  label.SetProperty(TextLabel::Property::ELLIPSIS, true);
+  label.SetProperty(DevelTextLabel::Property::ELLIPSIS_POSITION, DevelText::EllipsisPosition::END);
+  label.SetProperty(TextLabel::Property::TEXT, "Lorem ipsum dolor sit amet, \n consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
+
+  application.SendNotification();
+  application.Render();
+
+  Rect<> lineGeometry = TextGeometry::GetLineBoundingRectangle(label, 1);
+
+  Rect<> expectedLineGeometry = {0, 36, 420, 36};
+
+  TestTextGeometryUtils::CheckRectGeometryResult(lineGeometry, expectedLineGeometry);
+
+  END_TEST;
+}
+
+
index b501c9c..e520bd4 100755 (executable)
@@ -71,6 +71,7 @@ SET( devel_api_src_files
   ${devel_api_src_dir}/visual-factory/visual-base.cpp
   ${devel_api_src_dir}/controls/gaussian-blur-view/gaussian-blur-view.cpp
   ${devel_api_src_dir}/drag-drop-detector/drag-and-drop-detector.cpp
+  ${devel_api_src_dir}/text/text-geometry-devel.cpp
 )
 
 # Add devel header files here
@@ -231,6 +232,7 @@ SET( devel_api_text_header_files
   ${devel_api_src_dir}/text/bitmap-font.h
   ${devel_api_src_dir}/text/text-utils-devel.h
   ${devel_api_src_dir}/text/rendering-backend.h
+  ${devel_api_src_dir}/text/text-geometry-devel.h
 )
 
 SET( devel_api_tool_bar_header_files
diff --git a/dali-toolkit/devel-api/text/text-geometry-devel.cpp b/dali-toolkit/devel-api/text/text-geometry-devel.cpp
new file mode 100644 (file)
index 0000000..1afc773
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2022 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/devel-api/text/text-geometry-devel.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/text-controls/text-editor-impl.h>
+#include <dali-toolkit/internal/controls/text-controls/text-label-impl.h>
+#include <dali-toolkit/internal/controls/text-controls/text-field-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace TextGeometry
+{
+
+Rect<float> GetLineBoundingRectangle(TextEditor editor, const uint32_t lineIndex)
+{
+  return GetImpl(editor).GetLineBoundingRectangle(lineIndex);
+}
+
+Rect<float> GetLineBoundingRectangle(TextLabel label, const uint32_t lineIndex)
+{
+  return GetImpl(label).GetLineBoundingRectangle(lineIndex);
+}
+
+Rect<float> GetLineBoundingRectangle(TextField field, const uint32_t lineIndex)
+{
+  return GetImpl(field).GetLineBoundingRectangle(lineIndex);
+}
+
+} //namespace TextGeometry
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/devel-api/text/text-geometry-devel.h b/dali-toolkit/devel-api/text/text-geometry-devel.h
new file mode 100644 (file)
index 0000000..b63f337
--- /dev/null
@@ -0,0 +1,73 @@
+#ifndef DALI_TOOLKIT_TEXT_GEOMETRY_DEVEL_H
+#define DALI_TOOLKIT_TEXT_GEOMETRY_DEVEL_H
+
+/*
+ * Copyright (c) 2022 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+//INTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/text-controls/text-label.h>
+#include <dali-toolkit/public-api/controls/text-controls/text-editor.h>
+#include <dali-toolkit/public-api/controls/text-controls/text-field.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace TextGeometry
+{
+
+  /**
+   * @brief Get the line bounding rectangle.
+   * if the requested index is out of range or the line is not yet rendered, a rect of {0, 0, 0, 0} is returned.
+   *
+   * @param[in] editor the editor controller that contains the line.
+   * @param[in] lineIndex line index to which we want to calculate the geometry for.
+   * @return bounding rectangle.
+   */
+   DALI_TOOLKIT_API Rect<float> GetLineBoundingRectangle(TextEditor editor, const uint32_t lineIndex);
+
+  /**
+   * @brief Get the line bounding rectangle.
+   * if the requested index is out of range or the line is not yet rendered, a rect of {0, 0, 0, 0} is returned.
+   *
+   * @param[in] label the label controller that contains the line.
+   * @param[in] lineIndex line index to which we want to calculate the geometry for.
+   * @return bounding rectangle.
+   */
+   DALI_TOOLKIT_API Rect<float> GetLineBoundingRectangle(TextLabel label, const uint32_t lineIndex);
+
+  /**
+   * @brief Get the line bounding rectangle.
+   * if the requested index is out of range or the line is not yet rendered, a rect of {0, 0, 0, 0} is returned.
+   *
+   * @param[in] field the field controller that contains the line.
+   * @param[in] lineIndex line index to which we want to calculate the geometry for.
+   * @return bounding rectangle.
+   */
+   DALI_TOOLKIT_API Rect<float> GetLineBoundingRectangle(TextField field, const uint32_t lineIndex);
+
+} // namespace TextGeometry
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif //DALI_TOOLKIT_TEXT_GEOMETRY_DEVEL_H
index 7d0f2fe..890b22c 100644 (file)
@@ -364,6 +364,11 @@ Vector<Vector2> TextEditor::GetTextPosition(const uint32_t startIndex, const uin
   return mController->GetTextPosition(startIndex, endIndex);
 }
 
+Rect<float> TextEditor::GetLineBoundingRectangle(const uint32_t lineIndex) const
+{
+  return mController->GetLineBoundingRectangle(lineIndex);
+}
+
 string TextEditor::GetSelectedText() const
 {
   string selectedText = "";
index aaa58f7..0ad18a9 100644 (file)
@@ -358,6 +358,15 @@ public:
   Vector<Vector2> GetTextPosition(const uint32_t startIndex, const uint32_t endIndex) const;
 
   /**
+   * @brief Get the line bounding rectangle.
+   * if the requested index is out of range or the line is not yet rendered, a rect of {0, 0, 0, 0} is returned.
+   *
+   * @param[in] lineIndex line index to which we want to calculate the geometry for.
+   * @return bounding rectangle.
+   */
+  Rect<float> GetLineBoundingRectangle(const uint32_t lineIndex) const;
+
+  /**
    * @copydoc Text::SelectableControlInterface::GetSelectedText()
    */
   string GetSelectedText() const override;
index 15ea363..76d68df 100644 (file)
@@ -1205,6 +1205,11 @@ Vector<Vector2> TextField::GetTextPosition(const uint32_t startIndex, const uint
   return mController->GetTextPosition(startIndex, endIndex);
 }
 
+Rect<float> TextField::GetLineBoundingRectangle(const uint32_t lineIndex) const
+{
+  return mController->GetLineBoundingRectangle(lineIndex);
+}
+
 std::string TextField::TextFieldAccessible::GetName() const
 {
   if(IsHiddenInput())
index bed947d..8e8a01a 100644 (file)
@@ -367,6 +367,15 @@ public:
    */
   Vector<Vector2> GetTextPosition(const uint32_t startIndex, const uint32_t endIndex) const;
 
+  /**
+   * @brief Get the line bounding rectangle.
+   * if the requested index is out of range or the line is not yet rendered, a rect of {0, 0, 0, 0} is returned.
+   *
+   * @param[in] lineIndex line index to which we want to calculate the geometry for.
+   * @return bounding rectangle.
+   */
+  Rect<float> GetLineBoundingRectangle(const uint32_t lineIndex) const;
+
 private: // Implementation
   /**
    * @copydoc Dali::Toolkit::Text::Controller::(InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent)
index d9e413f..cec3d0c 100644 (file)
@@ -1236,6 +1236,11 @@ Vector<Vector2> TextLabel::GetTextPosition(const uint32_t startIndex, const uint
   return mController->GetTextPosition(startIndex, endIndex);
 }
 
+Rect<float> TextLabel::GetLineBoundingRectangle(const uint32_t lineIndex) const
+{
+  return mController->GetLineBoundingRectangle(lineIndex);
+}
+
 std::string TextLabel::TextLabelAccessible::GetNameRaw() const
 {
   return GetWholeText();
index 31167d8..000b6f0 100644 (file)
@@ -125,6 +125,15 @@ public:
    */
   Vector<Vector2> GetTextPosition(const uint32_t startIndex, const uint32_t endIndex) const;
 
+  /**
+   * @brief Get the line bounding rectangle.
+   * if the requested index is out of range or the line is not yet rendered, a rect of {0, 0, 0, 0} is returned.
+   *
+   * @param[in] lineIndex line index to which we want to calculate the geometry for.
+   * @return bounding rectangle.
+   */
+  Rect<float> GetLineBoundingRectangle(const uint32_t lineIndex) const;
+
 private: // From Control
   /**
    * @copydoc Control::OnInitialize()
index b3b55b1..5362804 100644 (file)
@@ -38,7 +38,6 @@
 #include <dali-toolkit/internal/text/controller/text-controller-text-updater.h>
 #include <dali-toolkit/internal/text/text-editable-control-interface.h>
 #include <dali-toolkit/internal/text/text-geometry.h>
-
 namespace
 {
 #if defined(DEBUG_ENABLED)
@@ -1416,6 +1415,11 @@ Vector<Vector2> Controller::GetTextPosition(CharacterIndex startIndex, Character
   return positionsList;
 }
 
+Rect<float> Controller::GetLineBoundingRectangle(const uint32_t lineIndex)
+{
+  return GetLineBoundingRect(mImpl->mModel, lineIndex);
+}
+
 Rect<> Controller::GetTextBoundingRectangle(CharacterIndex startIndex, CharacterIndex endIndex)
 {
   Vector<Vector2> sizeList;
index 09305d2..25185ad 100644 (file)
@@ -1733,6 +1733,15 @@ public: // Queries & retrieves.
   Vector<Vector2> GetTextPosition(CharacterIndex startIndex, CharacterIndex endIndex);
 
   /**
+   * @brief Get the line bounding rectangle.
+   * if the requested index is out of range or the line is not yet rendered, a rect of {0, 0, 0, 0} is returned.
+   *
+   * @param[in] lineIndex line index to which we want to calculate the geometry for.
+   * @return bounding rectangle.
+   */
+  Rect<float> GetLineBoundingRectangle(const uint32_t lineIndex);
+
+  /**
    * @brief Gets the bounding box of a specific text range.
    *
    * @param[in] startIndex start index of the text requested to get bounding box to.
index c0bb095..ac2e29d 100644 (file)
@@ -56,6 +56,14 @@ struct LineRun
  */
 float GetLineHeight(const LineRun lineRun, bool isLastLine);
 
+/**
+ * @brief Get the line width for the specified line run.
+ *
+ * @param[in] lineRun The line runs to get the width for.
+ * @return the width of the line.
+ */
+float GetLineWidth(const LineRun& lineRun);
+
 } // namespace Text
 
 } // namespace Toolkit
index 1efae75..09d2c92 100644 (file)
@@ -23,6 +23,8 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/cursor-helper-functions.h>
+#include <dali-toolkit/internal/text/line-run.h>
+#include <dali-toolkit/internal/text/visual-model-impl.h>
 
 using namespace Dali;
 
@@ -268,6 +270,69 @@ void GetTextGeometry(ModelPtr textModel, CharacterIndex startIndex, CharacterInd
   positionsList.PushBack(blockPos);
 }
 
+float GetLineLeft(const LineRun& lineRun)
+{
+  return lineRun.alignmentOffset;
+}
+
+float GetLineTop(const Vector<LineRun>& lines, const LineRun& lineRun)
+{
+  float lineTop = 0;
+  const int numberOfLines = (int)lines.Count();
+
+  int currentLineIndex = 0;
+  Vector<LineRun>::ConstIterator endIt = (&lineRun);
+  for(Vector<LineRun>::Iterator it = lines.Begin();
+      it != endIt;
+      ++it, ++currentLineIndex)
+    {
+      LineRun& line = *it;
+      bool isLastLine  = (currentLineIndex + 1) == numberOfLines;
+      lineTop         += GetLineHeight(line, isLastLine);
+    }
+
+  return lineTop;
+}
+
+float GetLineWidth(const LineRun& lineRun)
+{
+  return lineRun.width;
+}
+
+Rect<float> GetLineBoundingRect(ModelPtr textModel, const uint32_t lineIndex)
+{
+
+  if(textModel->mVisualModel == nullptr)
+  {
+    return {0, 0, 0, 0};
+  }
+
+  Length numberOfLines = textModel->mVisualModel->GetTotalNumberOfLines();
+
+  if(lineIndex >= numberOfLines)
+  {
+    return {0, 0, 0, 0};
+  }
+
+  const Vector<LineRun>& lines   = textModel->mVisualModel->mLines;
+  const LineRun&         lineRun = lines[lineIndex];
+  bool  isFirstLine = lineIndex == 0;
+  bool  isLastLine  = (lineIndex + 1) == numberOfLines;
+
+  // Calculate the Left(lineX) = X position.
+  float lineX = GetLineLeft(lineRun) + textModel->mScrollPosition.x;
+
+  // Calculate the Top(lineY) = PreviousHeights.
+  // If the line is the first line of the text; its top = 0.
+  float lineY = (isFirstLine ? 0 : GetLineTop(lines, lineRun)) + textModel->mScrollPosition.y;
+
+  // The rectangle contains the width and height:
+  float lineWidth  = GetLineWidth(lineRun);
+  float lineHeight = GetLineHeight(lineRun, isLastLine);
+
+  return {lineX, lineY, lineWidth, lineHeight};
+}
+
 } // namespace Text
 
 } // namespace Toolkit
index fb118f0..c783d9b 100644 (file)
  *
  */
 
+// EXTERNAL INCLUDES
+#include <dali/public-api/math/rect.h>
+
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/text-model.h>
-
 namespace Dali
 {
 namespace Toolkit
@@ -40,6 +42,34 @@ namespace Text
    */
 void GetTextGeometry(ModelPtr textModel, CharacterIndex startIndex, CharacterIndex endIndex, Vector<Vector2>& sizesList, Vector<Vector2>& positionsList);
 
+/**
+  * @brief Get the line bounding rectangle.
+  * if the requested index is out of range or the line is not yet rendered, a rect of {0, 0, 0, 0} is returned.
+  *
+  * @param[in] textModel text model containing line info.
+  * @param[in] lineIndex line index to which we want to calculate the geometry for.
+  * @return bounding rectangle.
+  */
+Rect<float> GetLineBoundingRect(ModelPtr textModel, const uint32_t lineIndex);
+
+/**
+  * @brief Get the left point of the line (x).
+  *
+  * @param[in] lineRun the requested line.
+  * @return x point of the line.
+  */
+float GetLineLeft(const LineRun& lineRun);
+
+/**
+  * @brief Get the top point of the line (y).
+  * if the requested line id the first; the top = 0, else the top = the heights of the previouse lines.
+  *
+  * @param[in] lines   the lines in the text controller.
+  * @param[in] lineRun the requested line.
+  * @return y point of the line.
+  */
+float GetLineTop(const Vector<LineRun>& lines, const LineRun& lineRun);
+
 } // namespace Text
 
 } // namespace Toolkit