Paragraph tag is used as block of text start & end with new-line (implicitly).
The paragraph tag is nedded to support styles on paragraph level in markup. They are attributes for paragraph tag like: Align, Direction (LTR, RTL), Wrap, etc.
Example:
Text:
"Before paragraph <p>first paragraph</p><p>second paragraph</p><p>new line \n third paragraph</p>After paragraph"
Output:
============================
| Before paragraph |
| first paragraph |
| second paragraph |
| new line |
| third paragraph |
| After paragraph |
============================
How to apply it in TextEditor:
textEditor.SetProperty(TextEditor::Property::ENABLE_MARKUP, true);
textEditor.SetProperty(TextEditor::Property::TEXT, "text one <p>Paragraph two</p> text three <p>Paragraph four</p> text five");
How to apply it in TextLabel:
textLabel.SetProperty(TextLabel::Property::MULTI_LINE, true);
textLabel.SetProperty(TextLabel::Property::ENABLE_MARKUP, true);
textLabel.SetProperty(TextLabel::Property::TEXT, "text one <p>Paragraph two</p> text three <p>Paragraph four</p> text five");
Change-Id: Icee044db488d82646758ccc59a23ce896a3e28c7
SET(TC_SOURCES
utc-Dali-AddOns.cpp
utc-Dali-BidirectionalSupport.cpp
+ utc-Dali-BoundedParagraph-Functions.cpp
utc-Dali-ColorConversion.cpp
utc-Dali-Control-internal.cpp
utc-Dali-DebugRendering.cpp
logicalModel->mAnchors,
logicalModel->mUnderlinedCharacterRuns,
logicalModel->mBackgroundColorRuns,
- logicalModel->mStrikethroughCharacterRuns);
+ logicalModel->mStrikethroughCharacterRuns,
+ logicalModel->mBoundedParagraphRuns);
Length textSize = 0u;
const uint8_t* utf8 = NULL;
--- /dev/null
+/*
+ * 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 <iostream>
+
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/bounded-paragraph-helper-functions.h>
+#include <dali-toolkit/internal/text/bounded-paragraph-run.h>
+#include <dali-toolkit/internal/text/character-set-conversion.h>
+
+using namespace Dali;
+using namespace Toolkit;
+using namespace Text;
+
+struct BoundedParagraphData
+{
+ CharacterIndex characterIndex;
+ Length numberOfCharacters;
+};
+
+struct TestCaseData
+{
+ std::string description; ///< Description of the test.
+ std::string text; ///< The text.
+ CharacterIndex firstIndexOfRemovedCharacters; ///< The first index of removed characters.
+ int numberOfRemovedCharacters; ///< The number of removed characters.
+ Length numberOfBoundedParagraphs; ///< The number of bounded paragraphs before merging.
+ BoundedParagraphData* boundedParagraphs; ///< The bounded paragraphs info before merging.
+ Length numberOfExpectedBoundedParagraphs; ///< The number of expected bounded paragraphs after merging.
+ BoundedParagraphData* expectedBoundedParagraphs; ///< The expected bounded paragraphs info after merging.
+};
+
+void CreateBoundedParagraphRunsFromBoundedParagraphData(
+ Vector<BoundedParagraphRun>& boundedParagraphRuns,
+ const BoundedParagraphData* boundedParagraphs,
+ const Length& numberOfBoundedParagraphs)
+{
+ boundedParagraphRuns.Clear();
+
+ if(boundedParagraphs != nullptr)
+ {
+ for(Length index = 0u; index < numberOfBoundedParagraphs; index++)
+ {
+ BoundedParagraphRun boundedParagraphRun;
+ boundedParagraphRun.characterRun.characterIndex = boundedParagraphs[index].characterIndex;
+ boundedParagraphRun.characterRun.numberOfCharacters = boundedParagraphs[index].numberOfCharacters;
+
+ boundedParagraphRuns.PushBack(boundedParagraphRun);
+ }
+ }
+}
+
+bool MergeBoundedParagraphRunsTest(TestCaseData testCase)
+{
+ // 1) Convert boundedParagraphs to vector of BoundedParagraphRun
+ Vector<BoundedParagraphRun> boundedParagraphRuns;
+ CreateBoundedParagraphRunsFromBoundedParagraphData(boundedParagraphRuns, testCase.boundedParagraphs, testCase.numberOfBoundedParagraphs);
+
+ // 2) Convert expectedBoundedParagraphs to vector of BoundedParagraphRun
+ Vector<BoundedParagraphRun> expectedBoundedParagraphRuns;
+ CreateBoundedParagraphRunsFromBoundedParagraphData(expectedBoundedParagraphRuns, testCase.expectedBoundedParagraphs, testCase.numberOfExpectedBoundedParagraphs);
+
+ // 3) Convert string text to vector of character utf32
+ Vector<Character> utf32Text;
+ utf32Text.Resize(testCase.text.size());
+ const uint32_t numberOfCharacters = (testCase.text.size() == 0) ? 0 : Utf8ToUtf32(reinterpret_cast<const uint8_t* const>(testCase.text.c_str()), testCase.text.size(), &utf32Text[0u]);
+ utf32Text.Resize(numberOfCharacters);
+
+ // 4) Call MergeBoundedParagraphRunsWhenRemoveCharacters
+ MergeBoundedParagraphRunsWhenRemoveCharacters(utf32Text, testCase.firstIndexOfRemovedCharacters, testCase.numberOfRemovedCharacters, boundedParagraphRuns);
+
+ // 5) Verify actual with expected
+ if(testCase.numberOfExpectedBoundedParagraphs != boundedParagraphRuns.Count())
+ {
+ std::cout << " Different number of bounded paragraph runs after merging: " << boundedParagraphRuns.Count() << ", expected : " << testCase.numberOfExpectedBoundedParagraphs << std::endl;
+ return false;
+ }
+
+ for(unsigned int index = 0u; index < testCase.numberOfExpectedBoundedParagraphs; ++index)
+ {
+ if(expectedBoundedParagraphRuns[index].characterRun.characterIndex != boundedParagraphRuns[index].characterRun.characterIndex)
+ {
+ std::cout << " Different bounded paragraph runs after merging, index : " << index << std::endl;
+ std::cout << " Different characterIndex, actual: " << boundedParagraphRuns[index].characterRun.characterIndex
+ << ", expected : " << expectedBoundedParagraphRuns[index].characterRun.characterIndex << std::endl;
+ return false;
+ }
+
+ if(expectedBoundedParagraphRuns[index].characterRun.numberOfCharacters != boundedParagraphRuns[index].characterRun.numberOfCharacters)
+ {
+ std::cout << " Different bounded paragraph runs after merging, index : " << index << std::endl;
+ std::cout << " Different numberOfCharacters, actual: " << boundedParagraphRuns[index].characterRun.numberOfCharacters
+ << ", expected : " << expectedBoundedParagraphRuns[index].characterRun.numberOfCharacters << std::endl;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+int UtcDaliMergeBoundedParagraphRunsWhenRemoveCharacters(void)
+{
+ tet_infoline(" UtcDaliMergeBoundedParagraphRunsWhenRemoveCharacters ");
+
+ BoundedParagraphData boundedParagraphs01[] = {{10u, 14u}, {37u, 15u}};
+ BoundedParagraphData expectedBoundedParagraphs01[] = {{10u, 42u}};
+
+ BoundedParagraphData boundedParagraphs02[] = {{10u, 14u}, {37u, 15u}};
+ BoundedParagraphData expectedBoundedParagraphs02[] = {{37u, 15u}};
+
+ BoundedParagraphData boundedParagraphs03[] = {{10u, 14u}, {37u, 15u}};
+ BoundedParagraphData expectedBoundedParagraphs03[] = {{10u, 14u}, {37u, 20u}};
+
+ BoundedParagraphData boundedParagraphs04[] = {{10u, 14u}, {37u, 15u}};
+ BoundedParagraphData expectedBoundedParagraphs04[] = {{10u, 14u}, {37u, 15u}};
+
+ BoundedParagraphData boundedParagraphs05[] = {{10u, 14u}, {37u, 15u}};
+ BoundedParagraphData expectedBoundedParagraphs05[] = {{10u, 14u}, {37u, 15u}};
+
+ BoundedParagraphData boundedParagraphs06[] = {{10u, 14u}, {37u, 15u}, {64u, 14u}};
+ BoundedParagraphData expectedBoundedParagraphs06[] = {{10u, 68u}};
+
+ TestCaseData testCases[] =
+ {
+ {
+
+ "test-case 01",
+ "text one \nParagraph two\n text three \nParagraph four\n text five",
+ 20u,
+ -26,
+ 2u,
+ boundedParagraphs01,
+ 1u,
+ expectedBoundedParagraphs01
+
+ },
+
+ {
+
+ "test-case 02",
+ "text one \nParagraph two\n text three \nParagraph four\n text five",
+ 5u,
+ -5,
+ 2u,
+ boundedParagraphs02,
+ 1u,
+ expectedBoundedParagraphs02
+
+ },
+
+ {
+
+ "test-case 03",
+ "text one \nParagraph two\n text three \nParagraph four\n text five",
+ 47u,
+ -10,
+ 2u,
+ boundedParagraphs03,
+ 2u,
+ expectedBoundedParagraphs03
+
+ },
+
+ {
+
+ "test-case 04",
+ "text one \nParagraph two\n text three \nParagraph four\n text five",
+ 10u,
+ -9,
+ 2u,
+ boundedParagraphs04,
+ 2u,
+ expectedBoundedParagraphs04
+
+ },
+
+ {
+
+ "test-case 05",
+ "text one \nParagraph two\n text three \nParagraph four\n text five",
+ 25u,
+ -4,
+ 2u,
+ boundedParagraphs05,
+ 2u,
+ expectedBoundedParagraphs05
+
+ },
+
+ {
+
+ "test-case 06",
+ "text one \nParagraph two\n text three \nParagraph four\n text five \nParagraph six\n text seven",
+ 10u,
+ -63,
+ 3u,
+ boundedParagraphs06,
+ 1u,
+ expectedBoundedParagraphs06
+
+ },
+
+ };
+
+ const unsigned int numberOfTests = 6u;
+
+ for(unsigned int index = 0u; index < numberOfTests; ++index)
+ {
+ ToolkitTestApplication application;
+ tet_infoline(testCases[index].description.c_str());
+
+ if(!MergeBoundedParagraphRunsTest(testCases[index]))
+ {
+ tet_result(TET_FAIL);
+ }
+ }
+
+ tet_result(TET_PASS);
+ END_TEST;
+}
\ No newline at end of file
Vector<UnderlinedCharacterRun> underlinedCharacterRuns;
Vector<ColorRun> backgroundColorRuns;
Vector<StrikethroughCharacterRun> strikethroughCharacterRuns;
- MarkupProcessData markupProcessData(colorRuns, fontRuns, items, anchors, underlinedCharacterRuns, backgroundColorRuns, strikethroughCharacterRuns);
+ Vector<BoundedParagraphRun> boundedParagraphRuns;
+ MarkupProcessData markupProcessData(colorRuns, fontRuns, items, anchors, underlinedCharacterRuns, backgroundColorRuns, strikethroughCharacterRuns, boundedParagraphRuns);
ProcessMarkupString(data.xHTMLEntityString, markupProcessData);
for(Vector<EmbeddedItem>::Iterator it = items.Begin(),
DALI_TEST_EQUALS(numberOfStrikethroughRuns, expectedNumberOfStrikethroughGlyphs, TEST_LOCATION);
END_TEST;
+}
+
+int UtcDaliTextEditorMarkupParagraphTag(void)
+
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliTextEditorMarkupParagraphTag ");
+
+ TextEditor textEditor = TextEditor::New();
+ application.GetScene().Add(textEditor);
+
+ textEditor.SetProperty(TextEditor::Property::TEXT, "text one <p>Paragraph two</p> text three <p>Paragraph four</p> text five");
+ textEditor.SetProperty(TextEditor ::Property::ENABLE_MARKUP, true);
+
+ application.SendNotification();
+ application.Render();
+
+ uint32_t expectedNumberOfBoundedParagraphRuns = 2u;
+
+ Toolkit::Internal::TextEditor& textEditorImpl = GetImpl(textEditor);
+ const Text::Length numberOfBoundedParagraphRuns = textEditorImpl.GetTextController()->GetTextModel()->GetNumberOfBoundedParagraphRuns();
+ DALI_TEST_EQUALS(numberOfBoundedParagraphRuns, expectedNumberOfBoundedParagraphRuns, TEST_LOCATION);
+
+ const Vector<BoundedParagraphRun>& boundedParagraphRuns = textEditorImpl.GetTextController()->GetTextModel()->GetBoundedParagraphRuns();
+
+ //<p>Paragraph two</p>
+ DALI_TEST_EQUALS(boundedParagraphRuns[0u].characterRun.characterIndex, 10u, TEST_LOCATION);
+ DALI_TEST_EQUALS(boundedParagraphRuns[0u].characterRun.numberOfCharacters, 14u, TEST_LOCATION);
+
+ //<p>Paragraph four</p>
+ DALI_TEST_EQUALS(boundedParagraphRuns[1u].characterRun.characterIndex, 37u, TEST_LOCATION);
+ DALI_TEST_EQUALS(boundedParagraphRuns[1u].characterRun.numberOfCharacters, 15u, TEST_LOCATION);
+
+ END_TEST;
}
\ No newline at end of file
DALI_TEST_EQUALS(numberOfStrikethroughRuns, expectedNumberOfStrikethroughGlyphs, TEST_LOCATION);
END_TEST;
+}
+
+int UtcDaliTextLabelMarkupParagraphTag(void)
+
+{
+ ToolkitTestApplication application;
+
+ tet_infoline(" UtcDaliTextLabelMarkupParagraphTag ");
+ TextLabel textLabel = TextLabel::New();
+
+ application.GetScene().Add(textLabel);
+
+ textLabel.SetProperty(TextLabel::Property::TEXT, "text one <p>Paragraph two</p> text three <p>Paragraph four</p> text five");
+ textLabel.SetProperty(TextLabel ::Property::ENABLE_MARKUP, true);
+ textLabel.SetProperty(TextLabel::Property::MULTI_LINE, true);
+
+ application.SendNotification();
+ application.Render();
+
+ uint32_t expectedNumberOfBoundedParagraphRuns = 2u;
+
+ Toolkit::Internal::TextLabel& textLabelImpl = GetImpl(textLabel);
+ const Text::Length numberOfBoundedParagraphRuns = textLabelImpl.GetTextController()->GetTextModel()->GetNumberOfBoundedParagraphRuns();
+ DALI_TEST_EQUALS(numberOfBoundedParagraphRuns, expectedNumberOfBoundedParagraphRuns, TEST_LOCATION);
+
+ const Vector<BoundedParagraphRun>& boundedParagraphRuns = textLabelImpl.GetTextController()->GetTextModel()->GetBoundedParagraphRuns();
+
+ //<p>Paragraph two</p>
+ DALI_TEST_EQUALS(boundedParagraphRuns[0u].characterRun.characterIndex, 10u, TEST_LOCATION);
+ DALI_TEST_EQUALS(boundedParagraphRuns[0u].characterRun.numberOfCharacters, 14u, TEST_LOCATION);
+
+ //<p>Paragraph four</p>
+ DALI_TEST_EQUALS(boundedParagraphRuns[1u].characterRun.characterIndex, 37u, TEST_LOCATION);
+ DALI_TEST_EQUALS(boundedParagraphRuns[1u].characterRun.numberOfCharacters, 15u, TEST_LOCATION);
+
+ END_TEST;
}
\ No newline at end of file
END_TEST;
}
+
+int UtcDaliToolkitTexteditorParagraphTag(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTexteditorParagraphTag");
+ TextEditor editorNewlineSeparator = TextEditor::New();
+ TextEditor editorParagraphTag = TextEditor::New();
+ DALI_TEST_CHECK(editorNewlineSeparator);
+ DALI_TEST_CHECK(editorParagraphTag);
+
+ application.GetScene().Add(editorNewlineSeparator);
+ application.GetScene().Add(editorParagraphTag);
+
+ //Same utterance uses new-line to split paragraphs should give similar results for paragraph tag.
+ editorNewlineSeparator.SetProperty(TextEditor::Property::ENABLE_MARKUP, true);
+ editorNewlineSeparator.SetProperty(Actor::Property::SIZE, Vector2(100.f, 50.f));
+ editorNewlineSeparator.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+ editorNewlineSeparator.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ editorNewlineSeparator.SetProperty(TextEditor::Property::TEXT, "test paragraph tag \ntest paragraph tag \ntest paragraph tag ");
+
+ editorParagraphTag.SetProperty(TextEditor::Property::ENABLE_MARKUP, true);
+ editorParagraphTag.SetProperty(Actor::Property::SIZE, Vector2(100.f, 50.f));
+ editorParagraphTag.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+ editorParagraphTag.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ editorParagraphTag.SetProperty(TextEditor::Property::TEXT, "test paragraph tag <p>test paragraph tag </p>test paragraph tag ");
+
+ application.SendNotification();
+ application.Render();
+
+ Vector3 textNaturalSizeNewlineSeparator = editorNewlineSeparator.GetNaturalSize();
+ Vector3 textNaturalSizeParagraphTag = editorParagraphTag.GetNaturalSize();
+
+ DALI_TEST_EQUALS(textNaturalSizeNewlineSeparator, textNaturalSizeParagraphTag, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ END_TEST;
+}
\ No newline at end of file
application.Render();
END_TEST;
+}
+
+int UtcDaliToolkitTextfieldParagraphTag(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTextfieldParagraphTag");
+ TextField fieldNewlineSeparator = TextField::New();
+ TextField fieldParagraphTag = TextField::New();
+ DALI_TEST_CHECK(fieldNewlineSeparator);
+ DALI_TEST_CHECK(fieldParagraphTag);
+
+ application.GetScene().Add(fieldNewlineSeparator);
+ application.GetScene().Add(fieldParagraphTag);
+
+ //Same utterance uses new-line to split paragraphs should give similar results for paragraph tag.
+ fieldNewlineSeparator.SetProperty(TextField::Property::ENABLE_MARKUP, true);
+ fieldNewlineSeparator.SetProperty(Actor::Property::SIZE, Vector2(100.f, 50.f));
+ fieldNewlineSeparator.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+ fieldNewlineSeparator.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ fieldNewlineSeparator.SetProperty(TextField::Property::TEXT, "test paragraph tag \ntest paragraph tag \ntest paragraph tag ");
+
+ fieldParagraphTag.SetProperty(TextField::Property::ENABLE_MARKUP, true);
+ fieldParagraphTag.SetProperty(Actor::Property::SIZE, Vector2(100.f, 50.f));
+ fieldParagraphTag.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+ fieldParagraphTag.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ fieldParagraphTag.SetProperty(TextField::Property::TEXT, "test paragraph tag <p>test paragraph tag </p>test paragraph tag ");
+
+ application.SendNotification();
+ application.Render();
+
+ Vector3 textNaturalSizeNewlineSeparator = fieldNewlineSeparator.GetNaturalSize();
+ Vector3 textNaturalSizeParagraphTag = fieldParagraphTag.GetNaturalSize();
+
+ DALI_TEST_EQUALS(textNaturalSizeNewlineSeparator, textNaturalSizeParagraphTag, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ END_TEST;
}
\ No newline at end of file
application.Render();
END_TEST;
+}
+
+int UtcDaliToolkitTextlabelParagraphTag(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTextlabelParagraphTag");
+ TextLabel labelNewlineSeparator = TextLabel::New();
+ TextLabel labelParagraphTag = TextLabel::New();
+ DALI_TEST_CHECK(labelNewlineSeparator);
+ DALI_TEST_CHECK(labelParagraphTag);
+
+ application.GetScene().Add(labelNewlineSeparator);
+ application.GetScene().Add(labelParagraphTag);
+
+ //Same utterance uses new-line to split paragraphs should give similar results for paragraph tag.
+ labelNewlineSeparator.SetProperty(TextLabel::Property::MULTI_LINE, true);
+ labelNewlineSeparator.SetProperty(TextLabel::Property::ELLIPSIS, false);
+ labelNewlineSeparator.SetProperty(TextLabel::Property::ENABLE_MARKUP, true);
+ labelNewlineSeparator.SetProperty(Actor::Property::SIZE, Vector2(100.f, 50.f));
+ labelNewlineSeparator.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+ labelNewlineSeparator.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ labelNewlineSeparator.SetProperty(TextLabel::Property::TEXT, "test paragraph tag \ntest paragraph tag \ntest paragraph tag ");
+
+ labelParagraphTag.SetProperty(TextLabel::Property::MULTI_LINE, true);
+ labelParagraphTag.SetProperty(TextLabel::Property::ELLIPSIS, false);
+ labelParagraphTag.SetProperty(TextLabel::Property::ENABLE_MARKUP, true);
+ labelParagraphTag.SetProperty(Actor::Property::SIZE, Vector2(100.f, 50.f));
+ labelParagraphTag.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+ labelParagraphTag.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ labelParagraphTag.SetProperty(TextLabel::Property::TEXT, "test paragraph tag <p>test paragraph tag </p>test paragraph tag ");
+
+ application.SendNotification();
+ application.Render();
+
+ Vector3 textNaturalSizeNewlineSeparator = labelNewlineSeparator.GetNaturalSize();
+ Vector3 textNaturalSizeParagraphTag = labelParagraphTag.GetNaturalSize();
+
+ DALI_TEST_EQUALS(textNaturalSizeNewlineSeparator, textNaturalSizeParagraphTag, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ END_TEST;
}
\ No newline at end of file
textModel->mLogicalModel->mAnchors,
textModel->mLogicalModel->mUnderlinedCharacterRuns,
textModel->mLogicalModel->mBackgroundColorRuns,
- textModel->mLogicalModel->mStrikethroughCharacterRuns);
+ textModel->mLogicalModel->mStrikethroughCharacterRuns,
+ textModel->mLogicalModel->mBoundedParagraphRuns);
if(textParameters.markupEnabled)
{
${toolkit_src_dir}/image-loader/image-url-impl.cpp
${toolkit_src_dir}/styling/style-manager-impl.cpp
${toolkit_src_dir}/text/bidirectional-support.cpp
+ ${toolkit_src_dir}/text/bounded-paragraph-helper-functions.cpp
${toolkit_src_dir}/text/character-set-conversion.cpp
${toolkit_src_dir}/text/color-segmentation.cpp
${toolkit_src_dir}/text/cursor-helper-functions.cpp
--- /dev/null
+/*
+ * 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.
+ *
+ */
+
+// FILE HEADER
+#include <dali-toolkit/internal/text/bounded-paragraph-helper-functions.h>
+
+// INTERNAL INCLUDES
+#include <dali/devel-api/text-abstraction/script.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+void MergeBoundedParagraphRunsWhenRemoveCharacters(const Vector<Character>& text,
+ const CharacterIndex& index,
+ const int& numberOfCharacters,
+ Vector<BoundedParagraphRun>& boundedParagraphRuns)
+{
+ // This works on boundedParagraphRuns before applying on them the changes of the removed characters.
+ // Update to merge only when characters have been removed.
+ if(numberOfCharacters >= 0)
+ {
+ return;
+ }
+
+ //No runs to merge
+ if(boundedParagraphRuns.Count() == 0u)
+ {
+ return;
+ }
+
+ const Length numberOfRemovedCharacters = (Length)(-1 * numberOfCharacters);
+ const Length totalNumberOfCharacters = text.Count();
+ const CharacterIndex& firstIndexOfRemovedCharacters = index;
+ const CharacterIndex lastIndexOfRemovedCharacters = ((firstIndexOfRemovedCharacters + numberOfRemovedCharacters) > 0u) ? (firstIndexOfRemovedCharacters + numberOfRemovedCharacters - 1u) : firstIndexOfRemovedCharacters; // Note: Length is uint32. Extra validation to avoid a potential defects.
+
+ Length numberOfRuns = boundedParagraphRuns.Count();
+ Length firstRunIndexToUpdate = 0;
+ Length lastRunIndexToUpdate = 0;
+ bool noNeedToMerge = false;
+
+ // Find the first boundedParagraphRuns that is possible to be updated.
+ while(firstRunIndexToUpdate < numberOfRuns)
+ {
+ const CharacterIndex startCharIndex = boundedParagraphRuns[firstRunIndexToUpdate].characterRun.characterIndex;
+ const CharacterIndex endCharIndex = boundedParagraphRuns[firstRunIndexToUpdate].characterRun.GetEndCharacterIndex();
+
+ // In-case the paragraph separator of the plain text (before the current bounded paragraph) is removed.
+ // In-case the start index of the current bounded paragraph is between start and end indices of removed characters.
+ // In-case the end index of the current bounded paragraph is between start and end indices of removed characters.
+ if((startCharIndex == lastIndexOfRemovedCharacters + 1u) ||
+ ((firstIndexOfRemovedCharacters <= startCharIndex) && (startCharIndex <= lastIndexOfRemovedCharacters)) ||
+ ((firstIndexOfRemovedCharacters <= endCharIndex) && (endCharIndex <= lastIndexOfRemovedCharacters)))
+ {
+ break;
+ }
+ else if(lastIndexOfRemovedCharacters + 1u < startCharIndex)
+ { // The whole removed characters are exist before the remaining bounded paragraphs.
+ noNeedToMerge = true;
+ break;
+ }
+ firstRunIndexToUpdate++;
+ }
+
+ // There is no run was affected by the removed characters.
+ if(noNeedToMerge || (firstRunIndexToUpdate == numberOfRuns))
+ {
+ return;
+ }
+
+ // Find the last boundedParagraphRuns that is possible to be updated.
+ lastRunIndexToUpdate = firstRunIndexToUpdate;
+ while(lastRunIndexToUpdate < numberOfRuns - 1u)
+ {
+ const CharacterIndex startCharIndex = boundedParagraphRuns[lastRunIndexToUpdate].characterRun.characterIndex;
+ const CharacterIndex endCharIndex = boundedParagraphRuns[lastRunIndexToUpdate].characterRun.GetEndCharacterIndex();
+
+ if((lastIndexOfRemovedCharacters < endCharIndex) ||
+ (lastIndexOfRemovedCharacters + 1u <= startCharIndex))
+ {
+ break;
+ }
+
+ lastRunIndexToUpdate++;
+ }
+
+ // Remove all boundedParagraphRun between firstRunIndexToUpdate and lastRunIndexToUpdate
+ // At least one boundedParagraphRun between firstRunIndexToUpdate and lastRunIndexToUpdate
+ if(firstRunIndexToUpdate + 1u < lastRunIndexToUpdate)
+ {
+ Length runIndexToDelete = firstRunIndexToUpdate + 1u;
+
+ while(runIndexToDelete < lastRunIndexToUpdate)
+ {
+ Dali::Vector<BoundedParagraphRun>::Iterator paragraphToDelete = boundedParagraphRuns.Begin() + (runIndexToDelete);
+ boundedParagraphRuns.Remove(paragraphToDelete);
+
+ lastRunIndexToUpdate--;
+ numberOfRuns--;
+ }
+ }
+
+ CharacterIndex endCharIndexFirstRun = boundedParagraphRuns[firstRunIndexToUpdate].characterRun.GetEndCharacterIndex();
+ ;
+ if(firstRunIndexToUpdate == lastRunIndexToUpdate)
+ {
+ if(endCharIndexFirstRun < lastIndexOfRemovedCharacters)
+ {
+ boundedParagraphRuns[firstRunIndexToUpdate].characterRun.numberOfCharacters += (lastIndexOfRemovedCharacters - endCharIndexFirstRun);
+ }
+ }
+ else
+ {
+ CharacterIndex startCharIndexLastRun = boundedParagraphRuns[lastRunIndexToUpdate].characterRun.characterIndex;
+ boundedParagraphRuns[firstRunIndexToUpdate].characterRun.numberOfCharacters += ((startCharIndexLastRun - endCharIndexFirstRun) > 0u) ? (startCharIndexLastRun - endCharIndexFirstRun - 1u) : 0u; // Note: Length is uint32. Extra validation to avoid a potential defects.
+
+ CharacterIndex endCharIndexLastRun = boundedParagraphRuns[lastRunIndexToUpdate].characterRun.GetEndCharacterIndex();
+
+ if(endCharIndexLastRun < lastIndexOfRemovedCharacters)
+ {
+ boundedParagraphRuns[lastRunIndexToUpdate].characterRun.numberOfCharacters += (lastIndexOfRemovedCharacters - endCharIndexLastRun);
+ }
+ }
+
+ // Each endCharIndex for boundedParagraphRun is a paragraph separator.
+ // If not then keep adding characters until find paragraph separator.
+ Length runIndex = firstRunIndexToUpdate;
+ while(runIndex <= lastRunIndexToUpdate)
+ {
+ CharacterIndex endCharIndex = boundedParagraphRuns[runIndex].characterRun.GetEndCharacterIndex();
+
+ // The remaining text was not affected.
+ if(endCharIndex > lastIndexOfRemovedCharacters)
+ {
+ break;
+ }
+
+ // Reference for numberOfCharacters in current run to update it
+ CharacterIndex& numberOfCharactersInRun = boundedParagraphRuns[runIndex].characterRun.numberOfCharacters;
+
+ // In-case arrived to the start of the next run and there is no paragraph separator.
+ // Merging the next run with the current run. Removing the next run.
+ if((runIndex + 1u < numberOfRuns) &&
+ (endCharIndex <= lastIndexOfRemovedCharacters) &&
+ ((lastIndexOfRemovedCharacters + 1u) < totalNumberOfCharacters) &&
+ (!TextAbstraction::IsNewParagraph(*(text.Begin() + lastIndexOfRemovedCharacters + 1u))))
+ {
+ numberOfCharactersInRun += boundedParagraphRuns[runIndex + 1u].characterRun.numberOfCharacters;
+
+ Dali::Vector<BoundedParagraphRun>::Iterator paragraphToDelete = boundedParagraphRuns.Begin() + (runIndex + 1u);
+ boundedParagraphRuns.Remove(paragraphToDelete);
+
+ numberOfRuns--;
+ lastRunIndexToUpdate--;
+
+ continue;
+ }
+
+ runIndex++;
+ }
+
+ // Each startCharIndex-1u for boundedParagraphRun is a paragraph separator.
+ // If not then remove boundedParagraphRun.
+ if(numberOfRuns > 0u &&
+ firstIndexOfRemovedCharacters > 0u &&
+ boundedParagraphRuns[firstRunIndexToUpdate].characterRun.characterIndex > 0u)
+ {
+ const CharacterIndex startCharIndex = boundedParagraphRuns[firstRunIndexToUpdate].characterRun.characterIndex;
+
+ if(firstIndexOfRemovedCharacters <= startCharIndex && startCharIndex <= lastIndexOfRemovedCharacters + 1u)
+ {
+ // Verify the paragraph separator before the first run to update
+ // In-case the paragraph separator is removed before the boundedParagraphRun.
+ // Remove the boundedParagraphRun.
+ if((!TextAbstraction::IsNewParagraph(*(text.Begin() + firstIndexOfRemovedCharacters - 1u))) &&
+ (!TextAbstraction::IsNewParagraph(*(text.Begin() + startCharIndex))))
+ {
+ Dali::Vector<BoundedParagraphRun>::Iterator paragraphToDelete = boundedParagraphRuns.Begin() + (firstRunIndexToUpdate);
+ boundedParagraphRuns.Remove(paragraphToDelete);
+ }
+ }
+ }
+}
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
\ No newline at end of file
--- /dev/null
+#ifndef DALI_TOOLKIT_TEXT_BOUNDED_PARAGRAPH_HELPER_FUNCTIONS_H
+#define DALI_TOOLKIT_TEXT_BOUNDED_PARAGRAPH_HELPER_FUNCTIONS_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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/bounded-paragraph-run.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+/**
+ * @brief Merge BoundedParagraphRun when the paragraph separator has been removed.
+ * Adding the next characters until arrived to a paragraph separator.
+ * Or merging with the next BoundedParagraphRun and removing the next BoundedParagraphRun.
+ *
+ * @param[in] text Vector of UTF-32 characters.
+ * @param[in] index Index to the first character updated.
+ * @param[in] numberOfCharacters The number of the removed characters.
+ * @param[inout] boundedParagraphRuns The bounded paragraph runs.
+ *
+ */
+void MergeBoundedParagraphRunsWhenRemoveCharacters(const Vector<Character>& text,
+ const CharacterIndex& index,
+ const int& numberOfCharacters,
+ Vector<BoundedParagraphRun>& boundedParagraphRuns);
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_BOUNDED_PARAGRAPH_HELPER_FUNCTIONS_H
--- /dev/null
+#ifndef DALI_TOOLKIT_TEXT_BOUNDED_PARAGRAPH_RUN_H
+#define DALI_TOOLKIT_TEXT_BOUNDED_PARAGRAPH_RUN_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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/math/vector2.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/character-run.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+/**
+ * @brief BoundedParagraphRun
+ *
+ * In terms of the bidirectional algorithm, a 'paragraph' is understood as a run of characters between Paragraph Separators or appropriate Newline Functions.
+ * A 'paragraph' may also be determined by higher-level protocols like a mark-up tag.
+ * Bounded-paragraph is a pragraph that have been bounded by explicit tags like a mark-up tag.
+ * Bounded-paragraph could contain multi paragraphs that have been breaked by Paragraph Separators or appropriate Newline Functions.
+ * This will be used to handle information for the attributes of markup tag. Like TextAlign, TextDirection, TextIndent, LineHeight, etc.
+ */
+struct BoundedParagraphRun
+{
+ CharacterRun characterRun; ///< The initial character index within the whole text and the number of characters of the run.
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_BOUNDED_PARAGRAPH_RUN_H
CharacterIndex characterIndex; ///< Index to the first character.
Length numberOfCharacters; ///< Number of characters in the run.
+
+ //Methods
+
+ /**
+ * @brief Calculate the end index in run.
+ * @return the end character index in run.
+ */
+ CharacterIndex GetEndCharacterIndex() const
+ {
+ DALI_ASSERT_DEBUG(!((0u == numberOfCharacters) && (characterIndex > 0u)) &&
+ "Toolkit::Text::CharacterRun. NumberOfCharacters should be greater than zero");
+
+ // Note: Length is uint32. Extra validation to avoid a potential defects.
+ return (numberOfCharacters == 0u ? 0u : (characterIndex + numberOfCharacters - 1u));
+ }
};
} // namespace Text
#include <dali-toolkit/internal/text/logical-model-impl.h>
// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/bounded-paragraph-helper-functions.h>
#include <dali-toolkit/internal/text/input-style.h>
#include <dali-toolkit/internal/text/text-run-container.h>
// Free memory allocated for the font family name.
FreeFontFamilyNames(removedFontDescriptionRuns);
+
+ // Process the bounded paragraph runs
+ MergeBoundedParagraphRunsWhenRemoveCharacters(mText,
+ index,
+ numberOfCharacters,
+ mBoundedParagraphRuns);
+
+ Vector<BoundedParagraphRun> removedBoundedParagraphRuns;
+ UpdateCharacterRuns<BoundedParagraphRun>(index,
+ numberOfCharacters,
+ totalNumberOfCharacters,
+ mBoundedParagraphRuns,
+ removedBoundedParagraphRuns);
}
void LogicalModel::RetrieveStyle(CharacterIndex index, InputStyle& style)
}
}
+Length LogicalModel::GetNumberOfBoundedParagraphRuns() const
+{
+ return mBoundedParagraphRuns.Count();
+}
+
+const Vector<BoundedParagraphRun>& LogicalModel::GetBoundedParagraphRuns() const
+{
+ return mBoundedParagraphRuns;
+}
+
void LogicalModel::ClearEmbeddedImages()
{
FreeEmbeddedItems(mEmbeddedItems);
#include <dali-toolkit/internal/text/anchor.h>
#include <dali-toolkit/internal/text/bidirectional-line-info-run.h>
#include <dali-toolkit/internal/text/bidirectional-paragraph-info-run.h>
+#include <dali-toolkit/internal/text/bounded-paragraph-run.h>
#include <dali-toolkit/internal/text/color-run.h>
#include <dali-toolkit/internal/text/embedded-item.h>
#include <dali-toolkit/internal/text/font-description-run.h>
Length numberOfCharacters,
Vector<ParagraphRunIndex>& paragraphs);
+ /**
+ * @brief Retrieves the number of bounded paragraph runs.
+ *
+ * @return The number of bounded paragraph runs.
+ */
+ Length GetNumberOfBoundedParagraphRuns() const;
+
+ /**
+ * @brief Retrieves the reference for bounded paragraph runs.
+ *
+ * @return The reference for bounded paragraph runs.
+ */
+ const Vector<BoundedParagraphRun>& GetBoundedParagraphRuns() const;
+
// Embedded images
/**
Vector<Anchor> mAnchors;
Vector<UnderlinedCharacterRun> mUnderlinedCharacterRuns; ///< The underlined character run from markup-processor
Vector<StrikethroughCharacterRun> mStrikethroughCharacterRuns; ///< The strikethrough character run from markup-processor
+ Vector<BoundedParagraphRun> mBoundedParagraphRuns; ///< The bounded paragraph is used to handle a paragraph mark-up tag and it's attributes. Like TextAlign, TextDirection, TextIndent, LineHeight, etc.
BidirectionalLineRunIndex mBidirectionalLineIndex; ///< The last fetched bidirectional line info.
};
const std::string XHTML_BACKGROUND_TAG("background");
const std::string XHTML_SPAN_TAG("span");
const std::string XHTML_STRIKETHROUGH_TAG("s");
+const std::string XHTML_PARAGRAPH_TAG("p");
const char LESS_THAN = '<';
const char GREATER_THAN = '>';
const char HEX_CODE = 'x';
const char WHITE_SPACE = 0x20; // ASCII value of the white space.
+const char NEW_LINE = 0x0A; // ASCII value of the newline.
// Range 1 0x0u < XHTML_DECIMAL_ENTITY_RANGE <= 0xD7FFu
// Range 2 0xE000u < XHTML_DECIMAL_ENTITY_RANGE <= 0xFFFDu
}
/**
+ * @brief Initializes a bounded-paragraph character run to its defaults.
+ *
+ * @param[in,out] boundedParagraphRun The bounded paragraphRun run to initialize.
+ */
+void Initialize(BoundedParagraphRun& boundedParagraphRun)
+{
+ boundedParagraphRun.characterRun.characterIndex = 0u;
+ boundedParagraphRun.characterRun.numberOfCharacters = 0u;
+}
+
+/**
* @brief Splits the tag string into the tag name and its attributes.
*
* The attributes are stored in a vector in the tag.
}
/**
+ * @brief Processes the paragraph-tag
+ *
+ * @param[in/out] markupProcessData The markup process data
+ * @param[in] tag The current tag
+ * @param[in] isEndBuffer Whether the end of buffer
+ * @param[in/out] characterIndex The current character index
+ */
+void ProcessParagraphTag(
+ MarkupProcessData& markupProcessData,
+ const Tag tag,
+ bool isEndBuffer,
+ CharacterIndex& characterIndex)
+{
+ if((characterIndex > 0 &&
+ markupProcessData.markupProcessedText[characterIndex - 1u] != NEW_LINE) &&
+ (!(tag.isEndTag && isEndBuffer)))
+ {
+ // Insert new-line character at the start and end of paragraph.
+ markupProcessData.markupProcessedText.append(1u, NEW_LINE);
+ ++characterIndex;
+ }
+}
+
+/**
* @brief Processes the anchor tag
*
* @param[in/out] markupProcessData The markup process data
* @param[in] colorRunIndex The color run index
* @param[in] underlinedCharacterRunIndex The underlined character run index
* @param[in] backgroundRunIndex The background run index
+ * @param[in] boundedParagraphRunIndex The bounded paragraph run index
+ *
*/
-void ResizeModelVectors(MarkupProcessData& markupProcessData, const RunIndex fontRunIndex, const RunIndex colorRunIndex, const RunIndex underlinedCharacterRunIndex, const RunIndex backgroundRunIndex)
+void ResizeModelVectors(MarkupProcessData& markupProcessData,
+ const RunIndex fontRunIndex,
+ const RunIndex colorRunIndex,
+ const RunIndex underlinedCharacterRunIndex,
+ const RunIndex backgroundRunIndex,
+ const RunIndex boundedParagraphRunIndex)
{
markupProcessData.fontRuns.Resize(fontRunIndex);
markupProcessData.colorRuns.Resize(colorRunIndex);
markupProcessData.underlinedCharacterRuns.Resize(underlinedCharacterRunIndex);
markupProcessData.backgroundColorRuns.Resize(backgroundRunIndex);
+ markupProcessData.boundedParagraphRuns.Resize(boundedParagraphRunIndex);
#ifdef DEBUG_ENABLED
for(unsigned int i = 0; i < colorRunIndex; ++i)
RunIndex underlinedCharacterRunIndex = 0u;
RunIndex backgroundRunIndex = 0u;
RunIndex strikethroughCharacterRunIndex = 0u;
+ RunIndex boundedParagraphRunIndex = 0u;
// check tag reference
int colorTagReference = 0u;
int backgroundTagReference = 0u;
int spanTagReference = 0u;
int sTagReference = 0u;
+ int pTagReference = 0u;
// Give an initial default value to the model's vectors.
markupProcessData.colorRuns.Reserve(DEFAULT_VECTOR_SIZE);
ProcessTagForRun<StrikethroughCharacterRun>(
markupProcessData.strikethroughCharacterRuns, styleStack, tag, characterIndex, strikethroughCharacterRunIndex, sTagReference, [](const Tag& tag, StrikethroughCharacterRun& run) { ProcessStrikethroughTag(tag, run); });
} // <s></s>
+ else if(TokenComparison(XHTML_PARAGRAPH_TAG, tag.buffer, tag.length))
+ {
+ ProcessParagraphTag(markupProcessData, tag, (markupStringBuffer == markupStringEndBuffer), characterIndex);
+ ProcessTagForRun<BoundedParagraphRun>(
+ markupProcessData.boundedParagraphRuns, styleStack, tag, characterIndex, boundedParagraphRunIndex, pTagReference, [](const Tag& tag, BoundedParagraphRun& run) {});
+ } // <p></p>
} // end if( IsTag() )
else if(markupStringBuffer < markupStringEndBuffer)
{
}
// Resize the model's vectors.
- ResizeModelVectors(markupProcessData, fontRunIndex, colorRunIndex, underlinedCharacterRunIndex, backgroundRunIndex);
+ ResizeModelVectors(markupProcessData, fontRunIndex, colorRunIndex, underlinedCharacterRunIndex, backgroundRunIndex, boundedParagraphRunIndex);
}
} // namespace Text
// INTERNAL INCLUDES
#include <dali-toolkit/internal/text/anchor.h>
+#include <dali-toolkit/internal/text/bounded-paragraph-run.h>
#include <dali-toolkit/internal/text/color-run.h>
#include <dali-toolkit/internal/text/embedded-item.h>
#include <dali-toolkit/internal/text/font-description-run.h>
Vector<Anchor>& anchors,
Vector<UnderlinedCharacterRun>& underlinedCharacterRuns,
Vector<ColorRun>& backgroundColorRuns,
- Vector<StrikethroughCharacterRun>& strikethroughCharacterRuns)
+ Vector<StrikethroughCharacterRun>& strikethroughCharacterRuns,
+ Vector<BoundedParagraphRun>& boundedParagraphRuns)
: colorRuns(colorRuns),
fontRuns(fontRuns),
items(items),
underlinedCharacterRuns(underlinedCharacterRuns),
backgroundColorRuns(backgroundColorRuns),
strikethroughCharacterRuns(strikethroughCharacterRuns),
+ boundedParagraphRuns(boundedParagraphRuns),
markupProcessedText()
{
}
Vector<UnderlinedCharacterRun>& underlinedCharacterRuns; ///< The underlined character runs.
Vector<ColorRun>& backgroundColorRuns; ///< The background color runs.
Vector<StrikethroughCharacterRun>& strikethroughCharacterRuns; ///< The strikethrough character runs.
+ Vector<BoundedParagraphRun>& boundedParagraphRuns; ///< The bounded paragraph runs
std::string markupProcessedText; ///< The mark-up string.
};
mModel->GetStrikethroughRuns(strikethroughRuns, index, numberOfRuns);
}
+Length ViewModel::GetNumberOfBoundedParagraphRuns() const
+{
+ return mModel->GetNumberOfBoundedParagraphRuns();
+}
+
+const Vector<BoundedParagraphRun>& ViewModel::GetBoundedParagraphRuns() const
+{
+ return mModel->GetBoundedParagraphRuns();
+}
+
} // namespace Text
} // namespace Toolkit
// INTERNAL INCLUDES
#include <dali-toolkit/devel-api/text/text-enumerations-devel.h>
+#include <dali-toolkit/internal/text/bounded-paragraph-run.h>
#include <dali-toolkit/internal/text/text-model-interface.h>
#include <dali-toolkit/public-api/text/text-enumerations.h>
Length GetNumberOfStrikethroughRuns() const override;
/**
+ * @copydoc ModelInterface::GetNumberOfBoundedParagraphRuns()
+ */
+ virtual Length GetNumberOfBoundedParagraphRuns() const override;
+
+ /**
+ * @copydoc ModelInterface::GetBoundedParagraphRuns()
+ */
+ virtual const Vector<BoundedParagraphRun>& GetBoundedParagraphRuns() const override;
+
+ /**
* @copydoc ModelInterface::GetStrikethroughRuns()
*/
void GetStrikethroughRuns(StrikethroughGlyphRun* strikethroughRuns, StrikethroughRunIndex index, Length numberOfRuns) const override;
logicalModel->mAnchors,
logicalModel->mUnderlinedCharacterRuns,
logicalModel->mBackgroundColorRuns,
- logicalModel->mStrikethroughCharacterRuns);
+ logicalModel->mStrikethroughCharacterRuns,
+ logicalModel->mBoundedParagraphRuns);
Length textSize = 0u;
const uint8_t* utf8 = NULL;
// INTERNAL INCLUDES
#include <dali-toolkit/devel-api/text/text-enumerations-devel.h>
+#include <dali-toolkit/internal/text/bounded-paragraph-run.h>
#include <dali-toolkit/internal/text/line-run.h>
#include <dali-toolkit/internal/text/script-run.h>
#include <dali-toolkit/internal/text/strikethrough-glyph-run.h>
virtual Length GetNumberOfStrikethroughRuns() const = 0;
/**
+ * @brief Retrieves the number of bounded paragraph runs.
+ *
+ * @return The number of bounded paragraph runs.
+ */
+ virtual Length GetNumberOfBoundedParagraphRuns() const = 0;
+
+ /**
+ * @brief Retrieves the reference for bounded paragraph runs.
+ *
+ * @return The reference for bounded paragraph runs.
+ */
+ virtual const Vector<BoundedParagraphRun>& GetBoundedParagraphRuns() const = 0;
+
+ /**
* @brief Retrieves the strikethrough runs.
*
* @param[out] strikethroughRuns Pointer to a buffer where the strikethrough runs are copied.
return mVisualModel->GetNumberOfStrikethroughRuns();
}
+Length Model::GetNumberOfBoundedParagraphRuns() const
+{
+ return mLogicalModel->GetNumberOfBoundedParagraphRuns();
+}
+
+const Vector<BoundedParagraphRun>& Model::GetBoundedParagraphRuns() const
+{
+ return mLogicalModel->GetBoundedParagraphRuns();
+}
+
void Model::GetStrikethroughRuns(StrikethroughGlyphRun* strikethroughRuns, StrikethroughRunIndex index, Length numberOfRuns) const
{
mVisualModel->GetStrikethroughRuns(strikethroughRuns, index, numberOfRuns);
#include <dali/public-api/object/ref-object.h>
// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/bounded-paragraph-run.h>
#include <dali-toolkit/internal/text/logical-model-impl.h>
#include <dali-toolkit/internal/text/text-model-interface.h>
#include <dali-toolkit/internal/text/visual-model-impl.h>
*/
void GetStrikethroughRuns(StrikethroughGlyphRun* strikethroughRuns, StrikethroughRunIndex index, Length numberOfRuns) const override;
+ /**
+ * @copydoc ModelInterface::GetNumberOfBoundedParagraphRuns()
+ */
+ virtual Length GetNumberOfBoundedParagraphRuns() const override;
+
+ /**
+ * @copydoc ModelInterface::GetBoundedParagraphRuns()
+ */
+ virtual const Vector<BoundedParagraphRun>& GetBoundedParagraphRuns() const override;
+
private: // Private contructors & copy operator.
/**
* @brief Private constructor.
// INTERNAL INCLUDES
#include <dali-toolkit/devel-api/text/text-enumerations-devel.h>
+#include <dali-toolkit/internal/text/bounded-paragraph-run.h>
#include <dali-toolkit/internal/text/text-definitions.h>
#include <dali-toolkit/internal/text/underlined-glyph-run.h>
#include <dali-toolkit/public-api/text/text-enumerations.h>
virtual Length GetNumberOfStrikethroughRuns() const = 0;
/**
+ * @brief Retrieves the number of bounded paragraph runs.
+ *
+ * @return The number of bounded paragraph runs.
+ */
+ virtual Length GetNumberOfBoundedParagraphRuns() const = 0;
+
+ /**
+ * @brief Retrieves the reference for bounded paragraph runs.
+ *
+ * @return The reference for bounded paragraph runs.
+ */
+ virtual const Vector<BoundedParagraphRun>& GetBoundedParagraphRuns() const = 0;
+
+ /**
* @brief Retrieves the strikethrough runs.
*
* @param[out] strikethroughRuns Pointer to a buffer where the strikethrough runs are copied.
}
}
+Length View::GetNumberOfBoundedParagraphRuns() const
+{
+ if(mImpl->mLogicalModel)
+ {
+ return mImpl->mLogicalModel->GetNumberOfBoundedParagraphRuns();
+ }
+
+ return 0u;
+}
+
+const Vector<BoundedParagraphRun>& View::GetBoundedParagraphRuns() const
+{
+ return mImpl->mLogicalModel->GetBoundedParagraphRuns();
+}
+
const float View::GetCharacterSpacing() const
{
return (mImpl->mVisualModel) ? mImpl->mVisualModel->GetCharacterSpacing() : 0.f;
*/
// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/bounded-paragraph-run.h>
#include <dali-toolkit/internal/text/logical-model-impl.h>
#include <dali-toolkit/internal/text/text-view-interface.h>
#include <dali-toolkit/internal/text/visual-model-impl.h>
Length numberOfRuns) const;
/**
+ * @copydoc Dali::Toolkit::Text::ViewInterface::GetNumberOfBoundedParagraphRuns()
+ */
+ virtual Length GetNumberOfBoundedParagraphRuns() const;
+
+ /**
+ * @copydoc Dali::Toolkit::Text::ViewInterface::GetBoundedParagraphRuns()
+ */
+ virtual const Vector<BoundedParagraphRun>& GetBoundedParagraphRuns() const;
+
+ /**
* @copydoc Dali::Toolkit::Text::ViewInterface::GetCharacterSpacing()
*/
const float GetCharacterSpacing() const override;