Spannable-Core: Add SpannableString and ForegroundColorSpan 06/282806/13
authorssabah <s.sabah@samsung.com>
Wed, 14 Sep 2022 10:26:48 +0000 (13:26 +0300)
committerssabah <s.sabah@samsung.com>
Mon, 7 Nov 2022 10:38:28 +0000 (13:38 +0300)
  Create core module for Spannable
  - Interfaces: CharacterSequence, Spanned, Spannable, BaseSpan
  - Classes: SpannableString, ForegroundColorSpan, Range
  - APIs:
    - Vector<uint32_t> GetCharacters() const;
    - uint32_t GetNumberOfCharacters() const;
    - std::string ToString() const;
    - bool AttachSpan(const Dali::Toolkit::Text::BaseSpan& styleSpan, const Dali::Toolkit::Text::Range& range);
    - bool DetachSpan(const Dali::Toolkit::Text::BaseSpan& styleSpan);
    - std::vector<Dali::Toolkit::Text::BaseSpan> GetAllSpans() const;
    - void RetrieveAllSpansAndRanges(std::vector<Dali::Toolkit::Text::BaseSpan>& spans, std::vector<Dali::Toolkit::Text::Range>& ranges) const;

//Example:

    Dali::Toolkit::Text::SpannableString ss = Dali::Toolkit::Text::SpannableString::New("Hello مرحبا");

    auto chars = ss.GetCharacters();
    auto num   = ss.GetNumberOfCharacters();
    auto str   = ss.ToString();

    auto greenSpan = Dali::Toolkit::Text::ForegroundColorSpan::New(Color::GREEN);

    auto isAddedGreen = ss.AttachSpan(
      greenSpan,
      Dali::Toolkit::Text::Range::New(5u, 7u));

    auto isAddedBlue = ss.AttachSpan(
      Dali::Toolkit::Text::ForegroundColorSpan::New(Color::BLUE),
      Dali::Toolkit::Text::Range::New(4u, 2u));

    auto isAddedRed = ss.AttachSpan(
      Dali::Toolkit::Text::ForegroundColorSpan::New(Color::RED),
      Dali::Toolkit::Text::Range::New(15u, 2u));

    ss.DetachSpan(greenSpan);

    auto spans = ss.GetAllSpans();

    ss.DetachSpan(spans[0]);
    spans = ss.GetAllSpans();

Change-Id: I5e0df43d1a2e2afc8b11aa61d50e28b7e35036a4

37 files changed:
automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/utc-Dali-Text-BaseSpan.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/utc-Dali-Text-ForegroundColorSpan.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/utc-Dali-Text-Range.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/utc-Dali-Text-SpannableString.cpp [new file with mode: 0644]
dali-toolkit/devel-api/file.list
dali-toolkit/devel-api/text/character-sequence.cpp [new file with mode: 0644]
dali-toolkit/devel-api/text/character-sequence.h [new file with mode: 0644]
dali-toolkit/devel-api/text/range.cpp [new file with mode: 0644]
dali-toolkit/devel-api/text/range.h [new file with mode: 0644]
dali-toolkit/devel-api/text/spannable-string.cpp [new file with mode: 0644]
dali-toolkit/devel-api/text/spannable-string.h [new file with mode: 0644]
dali-toolkit/devel-api/text/spannable.cpp [new file with mode: 0644]
dali-toolkit/devel-api/text/spannable.h [new file with mode: 0644]
dali-toolkit/devel-api/text/spanned.cpp [new file with mode: 0644]
dali-toolkit/devel-api/text/spanned.h [new file with mode: 0644]
dali-toolkit/devel-api/text/spans/base-span.cpp [new file with mode: 0644]
dali-toolkit/devel-api/text/spans/base-span.h [new file with mode: 0644]
dali-toolkit/devel-api/text/spans/foreground-color-span.cpp [new file with mode: 0644]
dali-toolkit/devel-api/text/spans/foreground-color-span.h [new file with mode: 0644]
dali-toolkit/internal/file.list
dali-toolkit/internal/text/spannable/span-ranges-container-impl.cpp [new file with mode: 0644]
dali-toolkit/internal/text/spannable/span-ranges-container-impl.h [new file with mode: 0644]
dali-toolkit/internal/text/spannable/spannable-impl.cpp [new file with mode: 0644]
dali-toolkit/internal/text/spannable/spannable-impl.h [new file with mode: 0644]
dali-toolkit/internal/text/spannable/spannable-string-impl.cpp [new file with mode: 0644]
dali-toolkit/internal/text/spannable/spannable-string-impl.h [new file with mode: 0644]
dali-toolkit/internal/text/spannable/spanned-impl.cpp [new file with mode: 0644]
dali-toolkit/internal/text/spannable/spanned-impl.h [new file with mode: 0644]
dali-toolkit/internal/text/spannable/spans/base-span-impl.cpp [new file with mode: 0644]
dali-toolkit/internal/text/spannable/spans/base-span-impl.h [new file with mode: 0644]
dali-toolkit/internal/text/spannable/spans/foreground-color-span-impl.cpp [new file with mode: 0644]
dali-toolkit/internal/text/spannable/spans/foreground-color-span-impl.h [new file with mode: 0644]
dali-toolkit/internal/text/string-text/character-sequence-impl.cpp [new file with mode: 0644]
dali-toolkit/internal/text/string-text/character-sequence-impl.h [new file with mode: 0644]
dali-toolkit/internal/text/string-text/range-impl.cpp [new file with mode: 0644]
dali-toolkit/internal/text/string-text/range-impl.h [new file with mode: 0644]

index 2cdf4c8..bf9d8f8 100755 (executable)
@@ -40,6 +40,10 @@ SET(TC_SOURCES
   utc-Dali-SlideTransition.cpp
   utc-Dali-Slider.cpp
   utc-Dali-TableView.cpp
+  utc-Dali-Text-BaseSpan.cpp
+  utc-Dali-Text-ForegroundColorSpan.cpp
+  utc-Dali-Text-Range.cpp
+  utc-Dali-Text-SpannableString.cpp
   utc-Dali-TextEditor.cpp
   utc-Dali-TextField.cpp
   utc-Dali-TextGeometry.cpp
diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Text-BaseSpan.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Text-BaseSpan.cpp
new file mode 100644 (file)
index 0000000..d7d1e15
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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/text/spans/foreground-color-span.h>
+
+using namespace Dali;
+using namespace Toolkit;
+
+int UtcDaliToolkitTextBaseSpanDownCast(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextBaseSpanDownCast");
+
+  BaseHandle baseHandel = Text::ForegroundColorSpan::New(Color::GREEN);
+  DALI_TEST_CHECK(baseHandel);
+
+  Text::BaseSpan baseSpan = Text::BaseSpan::DownCast(baseHandel);
+  DALI_TEST_CHECK(baseSpan);
+
+  END_TEST;
+}
diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Text-ForegroundColorSpan.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Text-ForegroundColorSpan.cpp
new file mode 100644 (file)
index 0000000..653684a
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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/text/spans/foreground-color-span.h>
+
+using namespace Dali;
+using namespace Toolkit;
+
+int UtcDaliToolkitTextForegroundColorSpanNew(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextForegroundColorSpanNew");
+
+  auto greenSpan = Text::ForegroundColorSpan::New(Color::GREEN);
+  DALI_TEST_CHECK(greenSpan);
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextGetForegroundColor(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextGetForegroundColor");
+
+  auto greenSpan = Text::ForegroundColorSpan::New(Color::GREEN);
+  DALI_TEST_CHECK(greenSpan);
+  DALI_TEST_EQUALS(Color::GREEN, greenSpan.GetForegroundColor(), TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextIsForegroundColorDefined(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextIsForegroundColorDefined");
+
+  auto greenSpan = Text::ForegroundColorSpan::New(Color::GREEN);
+  DALI_TEST_CHECK(greenSpan);
+  DALI_TEST_EQUALS(true, greenSpan.IsForegroundColorDefined(), TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextForegroundColorSpanDownCast(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextForegroundColorSpanDownCast");
+
+  Text::BaseSpan baseSpan = Text::ForegroundColorSpan::New(Color::GREEN);
+  DALI_TEST_CHECK(baseSpan);
+
+  Text::ForegroundColorSpan greenSpan = Text::ForegroundColorSpan::DownCast(baseSpan);
+  DALI_TEST_CHECK(greenSpan);
+
+  END_TEST;
+}
diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Text-Range.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Text-Range.cpp
new file mode 100644 (file)
index 0000000..dabfca8
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * 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/text/range.h>
+
+using namespace Dali;
+using namespace Toolkit;
+
+int UtcDaliToolkitTextRangeNew(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextRangeNew");
+
+  auto range15to20 = Dali::Toolkit::Text::Range::New(15u, 20u);
+  DALI_TEST_CHECK(range15to20);
+
+  auto range25to20 = Dali::Toolkit::Text::Range::New(25u, 20u);
+  DALI_TEST_CHECK(range25to20);
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextRangeGetStartIndex(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextRangeGetStartIndex");
+
+  auto range15to20 = Dali::Toolkit::Text::Range::New(15u, 20u);
+  DALI_TEST_CHECK(range15to20);
+  DALI_TEST_EQUALS(15u, range15to20.GetStartIndex(), TEST_LOCATION);
+
+  auto range25to20 = Dali::Toolkit::Text::Range::New(25u, 20u);
+  DALI_TEST_CHECK(range25to20);
+  DALI_TEST_EQUALS(20u, range25to20.GetStartIndex(), TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextRangeGetEndIndex(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextRangeGetEndIndex");
+
+  auto range15to20 = Dali::Toolkit::Text::Range::New(15u, 20u);
+  DALI_TEST_CHECK(range15to20);
+  DALI_TEST_EQUALS(20u, range15to20.GetEndIndex(), TEST_LOCATION);
+
+  auto range25to20 = Dali::Toolkit::Text::Range::New(25u, 20u);
+  DALI_TEST_CHECK(range25to20);
+  DALI_TEST_EQUALS(25u, range25to20.GetEndIndex(), TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextRangeGetNumberOfIndices(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextRangeGetNumberOfIndices");
+
+  auto range15to20 = Dali::Toolkit::Text::Range::New(15u, 20u);
+  DALI_TEST_CHECK(range15to20);
+  DALI_TEST_EQUALS(6u, range15to20.GetNumberOfIndices(), TEST_LOCATION);
+
+  auto range25to20 = Dali::Toolkit::Text::Range::New(25u, 20u);
+  DALI_TEST_CHECK(range25to20);
+  DALI_TEST_EQUALS(6u, range25to20.GetNumberOfIndices(), TEST_LOCATION);
+
+  END_TEST;
+}
\ No newline at end of file
diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Text-SpannableString.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Text-SpannableString.cpp
new file mode 100644 (file)
index 0000000..1b0d19f
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ * 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/text/spannable-string.h>
+#include <dali-toolkit/devel-api/text/spans/foreground-color-span.h>
+
+using namespace Dali;
+using namespace Toolkit;
+
+int UtcDaliToolkitTextSpannableStringNew(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextSpannableStringNew");
+
+  Text::SpannableString spannableString = Text::SpannableString::New("Hello مرحبا");
+
+  DALI_TEST_CHECK(spannableString);
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextSpannableStringGetCharacters(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextSpannableStringGetCharacters");
+
+  Text::SpannableString spannableString = Text::SpannableString::New("Hello مرحبا");
+  DALI_TEST_CHECK(spannableString);
+
+  Vector<uint32_t> expectedChars;
+  expectedChars.PushBack('H');
+  expectedChars.PushBack('e');
+  expectedChars.PushBack('l');
+  expectedChars.PushBack('l');
+  expectedChars.PushBack('o');
+  expectedChars.PushBack(' ');
+  expectedChars.PushBack(0x0645); //'م'
+  expectedChars.PushBack(0x0631); //'ر'
+  expectedChars.PushBack(0x062D); //'ح'
+  expectedChars.PushBack(0x0628); //'ب'
+  expectedChars.PushBack(0x0627); //'ا'
+
+  auto chars = spannableString.GetCharacters();
+  DALI_TEST_EQUALS(expectedChars.Size(), chars.Size(), TEST_LOCATION);
+
+  for(uint32_t i = 0; i < expectedChars.Size(); i++)
+  {
+    DALI_TEST_EQUALS(expectedChars[i], chars[i], TEST_LOCATION);
+  }
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextSpannableStringGetNumberOfCharacters(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextSpannableStringGetNumberOfCharacters");
+
+  Text::SpannableString spannableString = Text::SpannableString::New("Hello مرحبا");
+  DALI_TEST_CHECK(spannableString);
+
+  DALI_TEST_EQUALS(11u, spannableString.GetNumberOfCharacters(), TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextSpannableStringToString(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextSpannableStringToString");
+  std::string text = "Hello مرحبا";
+
+  Text::SpannableString spannableString = Text::SpannableString::New(text);
+  DALI_TEST_CHECK(spannableString);
+
+  DALI_TEST_EQUALS(text, spannableString.ToString(), TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextSpannableStringAttachSpan(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextSpannableStringAttachSpan");
+
+  Text::SpannableString spannableString = Text::SpannableString::New("Hello مرحبا");
+  DALI_TEST_CHECK(spannableString);
+
+  auto greenSpan = Dali::Toolkit::Text::ForegroundColorSpan::New(Color::GREEN);
+
+  auto isAddedGreen = spannableString.AttachSpan(
+    greenSpan,
+    Dali::Toolkit::Text::Range::New(5u, 7u));
+  DALI_TEST_CHECK(isAddedGreen);
+
+  auto isAddedBlue = spannableString.AttachSpan(
+    Dali::Toolkit::Text::ForegroundColorSpan::New(Color::BLUE),
+    Dali::Toolkit::Text::Range::New(4u, 2u));
+  DALI_TEST_CHECK(isAddedBlue);
+
+  auto isAddedRed = spannableString.AttachSpan(
+    Dali::Toolkit::Text::ForegroundColorSpan::New(Color::RED),
+    Dali::Toolkit::Text::Range::New(15u, 2u));
+  DALI_TEST_CHECK(!isAddedRed);
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextSpannableStringDetachSpan(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextSpannableStringDetachSpan");
+
+  Text::SpannableString spannableString = Text::SpannableString::New("Hello مرحبا");
+  DALI_TEST_CHECK(spannableString);
+
+  auto greenSpan = Dali::Toolkit::Text::ForegroundColorSpan::New(Color::GREEN);
+
+  auto isAddedGreen = spannableString.AttachSpan(
+    greenSpan,
+    Dali::Toolkit::Text::Range::New(5u, 7u));
+  DALI_TEST_CHECK(isAddedGreen);
+
+  auto isAddedBlue = spannableString.AttachSpan(
+    Dali::Toolkit::Text::ForegroundColorSpan::New(Color::BLUE),
+    Dali::Toolkit::Text::Range::New(4u, 2u));
+  DALI_TEST_CHECK(isAddedBlue);
+
+  auto isRemovedGreen = spannableString.DetachSpan(greenSpan);
+  DALI_TEST_CHECK(isRemovedGreen);
+
+  auto isRemovedGreen2 = spannableString.DetachSpan(greenSpan);
+  DALI_TEST_CHECK(!isRemovedGreen2);
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextSpannableStringGetAllSpans(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextSpannableStringGetAllSpans");
+
+  Text::SpannableString spannableString = Text::SpannableString::New("Hello مرحبا");
+  DALI_TEST_CHECK(spannableString);
+
+  auto greenSpan = Dali::Toolkit::Text::ForegroundColorSpan::New(Color::GREEN);
+  spannableString.AttachSpan(
+    greenSpan,
+    Dali::Toolkit::Text::Range::New(5u, 7u));
+
+  auto blueSpan = Dali::Toolkit::Text::ForegroundColorSpan::New(Color::BLUE);
+  spannableString.AttachSpan(
+    blueSpan,
+    Dali::Toolkit::Text::Range::New(4u, 2u));
+
+  auto redSpan = Dali::Toolkit::Text::ForegroundColorSpan::New(Color::RED);
+  spannableString.AttachSpan(
+    redSpan,
+    Dali::Toolkit::Text::Range::New(15u, 2u));
+
+  auto spans = spannableString.GetAllSpans();
+
+  DALI_TEST_EQUALS(2u, spans.size(), TEST_LOCATION);
+
+  DALI_TEST_EQUALS(greenSpan, spans[0], TEST_LOCATION);
+  DALI_TEST_EQUALS(blueSpan, spans[1], TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextSpannableStringRetrieveAllSpansAndRanges(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextSpannableStringRetrieveAllSpansAndRanges");
+
+  Text::SpannableString spannableString = Text::SpannableString::New("Hello مرحبا");
+  DALI_TEST_CHECK(spannableString);
+
+  auto greenSpan  = Dali::Toolkit::Text::ForegroundColorSpan::New(Color::GREEN);
+  auto greenRange = Dali::Toolkit::Text::Range::New(5u, 7u);
+  spannableString.AttachSpan(
+    greenSpan,
+    greenRange);
+
+  auto blueSpan  = Dali::Toolkit::Text::ForegroundColorSpan::New(Color::BLUE);
+  auto blueRange = Dali::Toolkit::Text::Range::New(4u, 2u);
+  spannableString.AttachSpan(
+    blueSpan,
+    blueRange);
+
+  auto redSpan  = Dali::Toolkit::Text::ForegroundColorSpan::New(Color::RED);
+  auto redRange = Dali::Toolkit::Text::Range::New(15u, 2u);
+  spannableString.AttachSpan(
+    redSpan,
+    redRange);
+
+  std::vector<Text::BaseSpan> spans;
+  std::vector<Text::Range>    ranges;
+
+  spannableString.RetrieveAllSpansAndRanges(spans, ranges);
+
+  DALI_TEST_EQUALS(2u, spans.size(), TEST_LOCATION);
+  DALI_TEST_EQUALS(2u, ranges.size(), TEST_LOCATION);
+
+  DALI_TEST_EQUALS(greenSpan, spans[0], TEST_LOCATION);
+  DALI_TEST_EQUALS(blueSpan, spans[1], TEST_LOCATION);
+
+  DALI_TEST_EQUALS(greenRange, ranges[0], TEST_LOCATION);
+  DALI_TEST_EQUALS(blueRange, ranges[1], TEST_LOCATION);
+
+  END_TEST;
+}
\ No newline at end of file
index e520bd4..92a1f3a 100755 (executable)
@@ -60,6 +60,13 @@ SET( devel_api_src_files
   ${devel_api_src_dir}/styling/style-manager-devel.cpp
   ${devel_api_src_dir}/text/bitmap-font.cpp
   ${devel_api_src_dir}/text/text-utils-devel.cpp
+  ${devel_api_src_dir}/text/character-sequence.cpp
+  ${devel_api_src_dir}/text/range.cpp
+  ${devel_api_src_dir}/text/spanned.cpp
+  ${devel_api_src_dir}/text/spannable.cpp
+  ${devel_api_src_dir}/text/spannable-string.cpp
+  ${devel_api_src_dir}/text/spans/base-span.cpp
+  ${devel_api_src_dir}/text/spans/foreground-color-span.cpp
   ${devel_api_src_dir}/transition-effects/cube-transition-cross-effect.cpp
   ${devel_api_src_dir}/transition-effects/cube-transition-effect.cpp
   ${devel_api_src_dir}/transition-effects/cube-transition-fold-effect.cpp
@@ -233,6 +240,13 @@ SET( devel_api_text_header_files
   ${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
+  ${devel_api_src_dir}/text/character-sequence.h
+  ${devel_api_src_dir}/text/range.h
+  ${devel_api_src_dir}/text/spanned.h
+  ${devel_api_src_dir}/text/spannable.h
+  ${devel_api_src_dir}/text/spannable-string.h
+  ${devel_api_src_dir}/text/spans/base-span.h
+  ${devel_api_src_dir}/text/spans/foreground-color-span.h
 )
 
 SET( devel_api_tool_bar_header_files
diff --git a/dali-toolkit/devel-api/text/character-sequence.cpp b/dali-toolkit/devel-api/text/character-sequence.cpp
new file mode 100644 (file)
index 0000000..4d25658
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * 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/character-sequence.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/string-text/character-sequence-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+CharacterSequence::CharacterSequence() = default;
+
+CharacterSequence::CharacterSequence(Internal::CharacterSequence* internal)
+: BaseHandle(internal)
+{
+}
+
+CharacterSequence::CharacterSequence(const CharacterSequence& rhs) = default;
+
+CharacterSequence::CharacterSequence(CharacterSequence&& rhs) = default;
+
+CharacterSequence& CharacterSequence::operator=(const CharacterSequence& rhs) = default;
+
+CharacterSequence& CharacterSequence::operator=(CharacterSequence&& rhs) = default;
+
+CharacterSequence::~CharacterSequence() = default;
+
+//Methods
+
+Vector<uint32_t> CharacterSequence::GetCharacters() const
+{
+  return GetImplementation(*this).GetCharacters();
+}
+
+uint32_t CharacterSequence::GetNumberOfCharacters() const
+{
+  return GetImplementation(*this).GetNumberOfCharacters();
+}
+
+std::string CharacterSequence::ToString() const
+{
+  return GetImplementation(*this).ToString();
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/devel-api/text/character-sequence.h b/dali-toolkit/devel-api/text/character-sequence.h
new file mode 100644 (file)
index 0000000..af996f8
--- /dev/null
@@ -0,0 +1,139 @@
+#ifndef DALI_TOOLKIT_TEXT_CHARACTER_SEQUENCE_H
+#define DALI_TOOLKIT_TEXT_CHARACTER_SEQUENCE_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-toolkit/public-api/dali-toolkit-common.h>
+#include <dali/devel-api/text-abstraction/text-abstraction-definitions.h>
+#include <dali/public-api/object/base-handle.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace Internal DALI_INTERNAL
+{
+class CharacterSequence;
+}
+
+/**
+ * @brief Interface for readable character sequence.
+ * It provides uniform APIs for read-only access to many different kinds of character sequences.
+ *
+ * @note An instance of this class cannot be created.
+ *
+ */
+class DALI_TOOLKIT_API CharacterSequence : public BaseHandle
+{
+public:
+  /**
+   * @brief Creates an uninitialized CharacterSequence handle.
+   *
+   * Calling member functions with an uninitialized CharacterSequence handle is not allowed.
+   */
+  CharacterSequence();
+
+  /**
+   * @brief Copy constructor.
+   *
+   * @param[in] rhs A reference to the copied handle
+   */
+  CharacterSequence(const CharacterSequence& rhs);
+
+  /**
+   * @brief Move constructor.
+   *
+   * @param[in] rhs A reference to the handle to move
+   */
+  CharacterSequence(CharacterSequence&& rhs);
+
+  /**
+   * @brief Assignment operator.
+   *
+   * @param[in] handle A reference to the copied handle
+   * @return A reference to this
+   */
+  CharacterSequence& operator=(const CharacterSequence& handle);
+
+  /**
+   * @brief Move assignment operator.
+   *
+   * @param[in] rhs A reference to the handle to move
+   * @return A reference to this handle
+   */
+  CharacterSequence& operator=(CharacterSequence&& rhs);
+
+  /**
+   * @brief Non virtual destructor.
+   */
+  ~CharacterSequence();
+
+protected:
+  /**
+   * @brief Downcasts to a CharacterSequence handle.
+   * If handle is not a CharacterSequence, the returned handle is left uninitialized.
+   *
+   * @param[in] handle Handle to an object
+   * @return CharacterSequence handle or an uninitialized handle
+   */
+  static CharacterSequence DownCast(BaseHandle handle);
+
+public: // Not intended for application developers
+  /// @cond internal
+  /**
+   * @brief Internal constructor.
+   *
+   * @param[in] characterSequence Pointer to internal CharacterSequence
+   */
+  explicit DALI_INTERNAL CharacterSequence(Internal::CharacterSequence* characterSequence);
+  /// @endcond
+
+public: //Methods
+  /**
+  * @brief Retrive the characters
+  *
+  * @return the utf32 characters.
+  */
+  Vector<uint32_t> GetCharacters() const;
+
+  /**
+  * @brief Retrive number of characters in container
+  *
+  * @return the number of characters.
+  */
+  uint32_t GetNumberOfCharacters() const;
+
+  /**
+  * @brief Retrieve constructed string form Character Sequence.
+  * Copy the characters from container to string
+  *
+  * @return the std string.
+  */
+  std::string ToString() const;
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_CHARACTER_SEQUENCE_H
diff --git a/dali-toolkit/devel-api/text/range.cpp b/dali-toolkit/devel-api/text/range.cpp
new file mode 100644 (file)
index 0000000..faf453f
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * 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/range.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/string-text/range-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+Range Range::New(u_int32_t startIndex, u_int32_t endIndex)
+{
+  return Internal::Range::New(startIndex, endIndex);
+}
+
+Range::Range() = default;
+
+Range::Range(Internal::Range* internal)
+: BaseHandle(internal)
+{
+}
+
+Range::Range(const Range& rhs) = default;
+
+Range::Range(Range&& rhs) = default;
+
+Range& Range::operator=(const Range& rhs) = default;
+
+Range& Range::operator=(Range&& rhs) = default;
+
+Range::~Range() = default;
+
+//Methods
+u_int32_t Range::GetStartIndex() const
+{
+  return GetImplementation(*this).GetStartIndex();
+}
+
+u_int32_t Range::GetEndIndex() const
+{
+  return GetImplementation(*this).GetEndIndex();
+}
+
+u_int32_t Range::GetNumberOfIndices() const
+{
+  return GetImplementation(*this).GetNumberOfIndices();
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/devel-api/text/range.h b/dali-toolkit/devel-api/text/range.h
new file mode 100644 (file)
index 0000000..14538fd
--- /dev/null
@@ -0,0 +1,159 @@
+#ifndef DALI_TOOLKIT_TEXT_RANGE_H
+#define DALI_TOOLKIT_TEXT_RANGE_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-toolkit/public-api/dali-toolkit-common.h>
+#include <dali/public-api/object/base-handle.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace Internal DALI_INTERNAL
+{
+class Range;
+}
+
+/**
+ * @brief Base structure for different text-spans.
+ * The application can attach and detach spans on range of text for text-controller.
+ * Used to modify text style dynamically at runtime on character level.
+ *
+ * A text-span contains set of attributes of specific style for text.
+ *
+ * To receive a particular text-span, the application has to create span through its builder.
+ *
+ * @note An instance of this class cannot be created.
+ *
+ */
+class DALI_TOOLKIT_API Range : public BaseHandle
+{
+public:
+  /**
+   * @brief Create an initialized range.
+   *
+   * @param[in] startIndex the start index of range (included)
+   * @param[in] endIndex the end index of range (included)
+   *
+   * @return A handle to a newly allocated Dali resource
+   */
+  static Range New(u_int32_t startIndex, u_int32_t endIndex);
+
+  /**
+   * @brief Creates an uninitialized Range handle.
+   *
+   * Calling member functions with an uninitialized Range handle is not allowed.
+   */
+  Range();
+
+  /**
+   * @brief Copy constructor.
+   *
+   * @param[in] rhs A reference to the copied handle
+   */
+  Range(const Range& rhs);
+
+  /**
+   * @brief Move constructor.
+   *
+   * @param[in] rhs A reference to the handle to move
+   */
+  Range(Range&& rhs);
+
+  /**
+   * @brief Assignment operator.
+   *
+   * @param[in] handle A reference to the copied handle
+   * @return A reference to this
+   */
+  Range& operator=(const Range& handle);
+
+  /**
+   * @brief Move assignment operator.
+   *
+   * @param[in] rhs A reference to the handle to move
+   * @return A reference to this handle
+   */
+  Range& operator=(Range&& rhs);
+
+  /**
+   * @brief Non virtual destructor.
+   */
+  ~Range();
+
+protected:
+  /**
+   * @brief Downcasts to a Range handle.
+   * If handle is not a Range, the returned handle is left uninitialized.
+   *
+   * @param[in] handle Handle to an object
+   * @return Range handle or an uninitialized handle
+   */
+  static Range DownCast(BaseHandle handle);
+
+public: // Not intended for application developers
+  /// @cond internal
+  /**
+   * @brief Internal constructor.
+   *
+   * @param[in] range Pointer to internal Range
+   */
+  explicit DALI_INTERNAL Range(Internal::Range* range);
+  /// @endcond
+
+public: //Methods
+        /**
+  * @brief Retrive the start index of range
+  * @return the 32-bit unsigned int.
+  */
+  u_int32_t GetStartIndex() const;
+
+  /**
+  * @brief Retrive the end index of range
+  * @return the 32-bit unsigned int.
+  */
+  u_int32_t GetEndIndex() const;
+
+  /**
+  * @brief Retrive the number of indices of range (endIndex - startIndex +1)
+  * @return the 32-bit unsigned int.
+  */
+  u_int32_t GetNumberOfIndices() const;
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+// Allow Range to be treated as a POD type
+template<>
+struct TypeTraits<Dali::Toolkit::Text::Range> : public BasicTypes<Dali::Toolkit::Text::Range>
+{
+  enum
+  {
+    IS_TRIVIAL_TYPE = true
+  };
+};
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_RANGE_H
diff --git a/dali-toolkit/devel-api/text/spannable-string.cpp b/dali-toolkit/devel-api/text/spannable-string.cpp
new file mode 100644 (file)
index 0000000..da85d68
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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/spannable-string.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/spannable/spannable-string-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+SpannableString SpannableString::New(const std::string& text)
+{
+  return Internal::SpannableString::New(text);
+}
+
+SpannableString::SpannableString(Internal::SpannableString* internal)
+: Spannable(internal)
+{
+}
+
+SpannableString::SpannableString(const SpannableString& rhs) = default;
+
+SpannableString::SpannableString(SpannableString&& rhs) = default;
+
+SpannableString& SpannableString::operator=(const SpannableString& rhs) = default;
+
+SpannableString& SpannableString::operator=(SpannableString&& rhs) = default;
+
+SpannableString::~SpannableString() = default;
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/devel-api/text/spannable-string.h b/dali-toolkit/devel-api/text/spannable-string.h
new file mode 100644 (file)
index 0000000..29facdb
--- /dev/null
@@ -0,0 +1,124 @@
+#ifndef DALI_TOOLKIT_TEXT_SPANNABLE_STRING_H
+#define DALI_TOOLKIT_TEXT_SPANNABLE_STRING_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-toolkit/devel-api/text/spannable.h>
+#include <string>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace Internal DALI_INTERNAL
+{
+class SpannableString;
+}
+
+/**
+ * @brief Interface for text that has spans objects attached to ranges of it.
+ * It provides uniform APIs for read-only access to many different kinds of formatted character sequences.
+ *
+ * @note An instance of this class cannot be created.
+ *
+ */
+class DALI_TOOLKIT_API SpannableString : public Spannable
+{
+public:
+  /**
+   * @brief Create an initialized SpannableString.
+   *
+   * @param[in] text the text to be formatted
+   *
+   * @return A handle to a newly allocated Dali resource
+   */
+  static SpannableString New(const std::string& text);
+
+  /**
+   * @brief Creates an uninitialized SpannableString handle.
+   *
+   * Calling member functions with an uninitialized SpannableString handle is not allowed.
+   */
+  SpannableString();
+
+  /**
+   * @brief Copy constructor.
+   *
+   * @param[in] rhs A reference to the copied handle
+   */
+  SpannableString(const SpannableString& rhs);
+
+  /**
+   * @brief Move constructor.
+   *
+   * @param[in] rhs A reference to the handle to move
+   */
+  SpannableString(SpannableString&& rhs);
+
+  /**
+   * @brief Assignment operator.
+   *
+   * @param[in] handle A reference to the copied handle
+   * @return A reference to this
+   */
+  SpannableString& operator=(const SpannableString& handle);
+
+  /**
+   * @brief Move assignment operator.
+   *
+   * @param[in] rhs A reference to the handle to move
+   * @return A reference to this handle
+   */
+  SpannableString& operator=(SpannableString&& rhs);
+
+  /**
+   * @brief Non virtual destructor.
+   */
+  ~SpannableString();
+
+protected:
+  /**
+   * @brief Downcasts to a SpannableString handle.
+   * If handle is not a SpannableString, the returned handle is left uninitialized.
+   *
+   * @param[in] handle Handle to an object
+   * @return SpannableString handle or an uninitialized handle
+   */
+  static SpannableString DownCast(BaseHandle handle);
+
+public: // Not intended for application developers
+  /// @cond internal
+  /**
+   * @brief Internal constructor.
+   *
+   * @param[in] spannableString Pointer to internal SpannableString
+   */
+  explicit DALI_INTERNAL SpannableString(Internal::SpannableString* spannableString);
+  /// @endcond
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_SPANNABLE_STRING_H
diff --git a/dali-toolkit/devel-api/text/spannable.cpp b/dali-toolkit/devel-api/text/spannable.cpp
new file mode 100644 (file)
index 0000000..67228a3
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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/spannable.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/spannable/spannable-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+Spannable::Spannable() = default;
+
+Spannable::Spannable(Internal::Spannable* internal)
+: Spanned(internal)
+{
+}
+
+bool Spannable::AttachSpan(BaseSpan styleSpan, Range range)
+{
+  return GetImplementation(*this).AttachSpan(styleSpan, range);
+}
+
+bool Spannable::DetachSpan(const BaseSpan& styleSpan)
+{
+  return GetImplementation(*this).DetachSpan(styleSpan);
+}
+
+Spannable::Spannable(const Spannable& rhs) = default;
+
+Spannable::Spannable(Spannable&& rhs) = default;
+
+Spannable& Spannable::operator=(const Spannable& rhs) = default;
+
+Spannable& Spannable::operator=(Spannable&& rhs) = default;
+
+Spannable::~Spannable() = default;
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/devel-api/text/spannable.h b/dali-toolkit/devel-api/text/spannable.h
new file mode 100644 (file)
index 0000000..f1e11dd
--- /dev/null
@@ -0,0 +1,137 @@
+#ifndef DALI_TOOLKIT_TEXT_SPANNABLE_H
+#define DALI_TOOLKIT_TEXT_SPANNABLE_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-toolkit/devel-api/text/range.h>
+#include <dali-toolkit/devel-api/text/spanned.h>
+#include <dali-toolkit/devel-api/text/spans/base-span.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace Internal DALI_INTERNAL
+{
+class Spannable;
+}
+
+/**
+ * @brief Interface for text to which spans objects can be attached and detached.
+ * It provides uniform APIs for mutable formatted character sequences.
+ *
+ * @note An instance of this class cannot be created.
+ *
+ */
+class DALI_TOOLKIT_API Spannable : public Spanned
+{
+public:
+  /**
+   * @brief Creates an uninitialized Spannable handle.
+   *
+   * Calling member functions with an uninitialized Spannable handle is not allowed.
+   */
+  Spannable();
+
+  /**
+   * @brief Copy constructor.
+   *
+   * @param[in] rhs A reference to the copied handle
+   */
+  Spannable(const Spannable& rhs);
+
+  /**
+   * @brief Move constructor.
+   *
+   * @param[in] rhs A reference to the handle to move
+   */
+  Spannable(Spannable&& rhs);
+
+  /**
+   * @brief Assignment operator.
+   *
+   * @param[in] handle A reference to the copied handle
+   * @return A reference to this
+   */
+  Spannable& operator=(const Spannable& handle);
+
+  /**
+   * @brief Move assignment operator.
+   *
+   * @param[in] rhs A reference to the handle to move
+   * @return A reference to this handle
+   */
+  Spannable& operator=(Spannable&& rhs);
+
+  /**
+   * @brief Non virtual destructor.
+   */
+  ~Spannable();
+
+public:
+  /**
+   * @brief Add the given style span on the given range of text.
+   *
+   * @param[in] styleSpan The span of style to apply it on range @p range
+   * @param[in] range The range.
+   *
+   * @return true if the @p range is valid on text. Otherwise false
+   */
+  bool AttachSpan(BaseSpan styleSpan, Range range);
+
+  /**
+   * @brief Remove the given style span on all ranges of text.
+   * checks if @p styleSpan exists, and if it does, it's to be removed.
+   *
+   * @param[in] styleSpan The span of style to remove with ranges.
+   *
+   * @return true if the @p styleSpan was exist and removed. Otherwise false
+   */
+  bool DetachSpan(const BaseSpan& styleSpan);
+
+protected:
+  /**
+   * @brief Downcasts to a Spannable handle.
+   * If handle is not a Spannable, the returned handle is left uninitialized.
+   *
+   * @param[in] handle Handle to an object
+   * @return Spannable handle or an uninitialized handle
+   */
+  static Spannable DownCast(BaseHandle handle);
+
+public: // Not intended for application developers
+  /// @cond internal
+  /**
+   * @brief Internal constructor.
+   *
+   * @param[in] spannable Pointer to internal Spannable
+   */
+  explicit DALI_INTERNAL Spannable(Internal::Spannable* spannable);
+  /// @endcond
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_SPANNABLE_H
diff --git a/dali-toolkit/devel-api/text/spanned.cpp b/dali-toolkit/devel-api/text/spanned.cpp
new file mode 100644 (file)
index 0000000..4ad29de
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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/spanned.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/spannable/spanned-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+Spanned::Spanned() = default;
+
+Spanned::Spanned(Internal::Spanned* internal)
+: CharacterSequence(internal)
+{
+}
+
+std::vector<BaseSpan> Spanned::GetAllSpans() const
+{
+  return GetImplementation(*this).GetAllSpans();
+}
+
+void Spanned::RetrieveAllSpansAndRanges(std::vector<BaseSpan>& spans, std::vector<Range>& ranges) const
+{
+  GetImplementation(*this).RetrieveAllSpansAndRanges(spans, ranges);
+}
+
+Spanned::Spanned(const Spanned& rhs) = default;
+
+Spanned::Spanned(Spanned&& rhs) = default;
+
+Spanned& Spanned::operator=(const Spanned& rhs) = default;
+
+Spanned& Spanned::operator=(Spanned&& rhs) = default;
+
+Spanned::~Spanned() = default;
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/devel-api/text/spanned.h b/dali-toolkit/devel-api/text/spanned.h
new file mode 100644 (file)
index 0000000..3d6931d
--- /dev/null
@@ -0,0 +1,133 @@
+#ifndef DALI_TOOLKIT_TEXT_SPANNED_H
+#define DALI_TOOLKIT_TEXT_SPANNED_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-toolkit/devel-api/text/character-sequence.h>
+#include <dali-toolkit/devel-api/text/range.h>
+#include <dali-toolkit/devel-api/text/spans/base-span.h>
+#include <dali/public-api/common/dali-vector.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace Internal DALI_INTERNAL
+{
+class Spanned;
+}
+
+/**
+ * @brief Interface for text that has spans objects attached to ranges of it.
+ * It provides uniform APIs for read-only access to many different kinds of formatted character sequences.
+ *
+ * @note An instance of this class cannot be created.
+ *
+ */
+class DALI_TOOLKIT_API Spanned : public CharacterSequence
+{
+public:
+  /**
+   * @brief Creates an uninitialized Spanned handle.
+   *
+   * Calling member functions with an uninitialized Spanned handle is not allowed.
+   */
+  Spanned();
+
+  /**
+   * @brief Copy constructor.
+   *
+   * @param[in] rhs A reference to the copied handle
+   */
+  Spanned(const Spanned& rhs);
+
+  /**
+   * @brief Move constructor.
+   *
+   * @param[in] rhs A reference to the handle to move
+   */
+  Spanned(Spanned&& rhs);
+
+  /**
+   * @brief Assignment operator.
+   *
+   * @param[in] handle A reference to the copied handle
+   * @return A reference to this
+   */
+  Spanned& operator=(const Spanned& handle);
+
+  /**
+   * @brief Move assignment operator.
+   *
+   * @param[in] rhs A reference to the handle to move
+   * @return A reference to this handle
+   */
+  Spanned& operator=(Spanned&& rhs);
+
+  /**
+   * @brief Non virtual destructor.
+   */
+  ~Spanned();
+
+protected:
+  /**
+   * @brief Downcasts to a Spanned handle.
+   * If handle is not a Spanned, the returned handle is left uninitialized.
+   *
+   * @param[in] handle Handle to an object
+   * @return Spanned handle or an uninitialized handle
+   */
+  static Spanned DownCast(BaseHandle handle);
+
+public:
+  /**
+   * @brief Retrieve all spans.
+   *
+   * @return list of spans
+   */
+  std::vector<BaseSpan> GetAllSpans() const;
+
+  /**
+   * @brief Retrieve all spans and ranges. Two lists are mapped by index.
+   *
+   * @param[out] spans container to clone spans
+   * @param[out] ranges container to clone ranges
+   */
+  void RetrieveAllSpansAndRanges(std::vector<BaseSpan>& spans, std::vector<Range>& ranges) const;
+
+public: // Not intended for application developers
+  /// @cond internal
+  /**
+   * @brief Internal constructor.
+   *
+   * @param[in] spanned Pointer to internal Spanned
+   */
+  explicit DALI_INTERNAL Spanned(Internal::Spanned* spanned);
+  /// @endcond
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_SPANNED_H
diff --git a/dali-toolkit/devel-api/text/spans/base-span.cpp b/dali-toolkit/devel-api/text/spans/base-span.cpp
new file mode 100644 (file)
index 0000000..6afcfd7
--- /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/spans/base-span.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/spannable/spans/base-span-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+BaseSpan::BaseSpan() = default;
+
+BaseSpan::BaseSpan(Internal::BaseSpan* internal)
+: BaseHandle(internal)
+{
+}
+
+BaseSpan::BaseSpan(const BaseSpan& rhs) = default;
+
+BaseSpan::BaseSpan(BaseSpan&& rhs) = default;
+
+BaseSpan& BaseSpan::operator=(const BaseSpan& rhs) = default;
+
+BaseSpan& BaseSpan::operator=(BaseSpan&& rhs) = default;
+
+BaseSpan::~BaseSpan() = default;
+
+BaseSpan BaseSpan::DownCast(BaseHandle handle)
+{
+  return BaseSpan(dynamic_cast<Dali::Toolkit::Text::Internal::BaseSpan*>(handle.GetObjectPtr()));
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/devel-api/text/spans/base-span.h b/dali-toolkit/devel-api/text/spans/base-span.h
new file mode 100644 (file)
index 0000000..535870c
--- /dev/null
@@ -0,0 +1,129 @@
+#ifndef DALI_TOOLKIT_TEXT_BASE_SPAN_H
+#define DALI_TOOLKIT_TEXT_BASE_SPAN_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-toolkit/public-api/dali-toolkit-common.h>
+#include <dali/public-api/object/base-handle.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace Internal DALI_INTERNAL
+{
+class BaseSpan;
+}
+
+/**
+ * @brief Base structure for different text-spans.
+ * The application can attach and detach spans on range of text for text-controller.
+ * Used to modify text style dynamically at runtime on character level.
+ *
+ * A text-span contains set of attributes of specific style for text.
+ *
+ * To receive a particular text-span, the application has to create span through its builder.
+ *
+ * @note An instance of this class cannot be created.
+ *
+ */
+class DALI_TOOLKIT_API BaseSpan : public BaseHandle
+{
+public:
+  /**
+   * @brief Creates an uninitialized BaseSpan handle.
+   *
+   * Calling member functions with an uninitialized BaseSpan handle is not allowed.
+   */
+  BaseSpan();
+
+  /**
+   * @brief Copy constructor.
+   *
+   * @param[in] rhs A reference to the copied handle
+   */
+  BaseSpan(const BaseSpan& rhs);
+
+  /**
+   * @brief Move constructor.
+   *
+   * @param[in] rhs A reference to the handle to move
+   */
+  BaseSpan(BaseSpan&& rhs);
+
+  /**
+   * @brief Assignment operator.
+   *
+   * @param[in] handle A reference to the copied handle
+   * @return A reference to this
+   */
+  BaseSpan& operator=(const BaseSpan& handle);
+
+  /**
+   * @brief Move assignment operator.
+   *
+   * @param[in] rhs A reference to the handle to move
+   * @return A reference to this handle
+   */
+  BaseSpan& operator=(BaseSpan&& rhs);
+
+  /**
+   * @brief Non virtual destructor.
+   */
+  ~BaseSpan();
+
+  /**
+   * @brief Downcasts to a BaseSpan handle.
+   * If handle is not a BaseSpan, the returned handle is left uninitialized.
+   *
+   * @param[in] handle Handle to an object
+   * @return BaseSpan handle or an uninitialized handle
+   */
+  static BaseSpan DownCast(BaseHandle handle);
+
+public: // Not intended for application developers
+  /// @cond internal
+  /**
+   * @brief Internal constructor.
+   *
+   * @param[in] baseSpan Pointer to internal BaseSpan
+   */
+  explicit DALI_INTERNAL BaseSpan(Internal::BaseSpan* baseSpan);
+  /// @endcond
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+// Allow BaseSpan to be treated as a POD type
+template<>
+struct TypeTraits<Dali::Toolkit::Text::BaseSpan> : public BasicTypes<Dali::Toolkit::Text::BaseSpan>
+{
+  enum
+  {
+    IS_TRIVIAL_TYPE = true
+  };
+};
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_BASE_SPAN_H
diff --git a/dali-toolkit/devel-api/text/spans/foreground-color-span.cpp b/dali-toolkit/devel-api/text/spans/foreground-color-span.cpp
new file mode 100644 (file)
index 0000000..a774737
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * 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/spans/foreground-color-span.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/spannable/spans/foreground-color-span-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+ForegroundColorSpan ForegroundColorSpan::New(Vector4 color)
+{
+  return Internal::ForegroundColorSpan::New(color);
+}
+
+ForegroundColorSpan::ForegroundColorSpan(Internal::ForegroundColorSpan* internal)
+: BaseSpan(internal)
+{
+}
+
+ForegroundColorSpan::ForegroundColorSpan() = default;
+
+ForegroundColorSpan::ForegroundColorSpan(const ForegroundColorSpan& rhs) = default;
+
+ForegroundColorSpan::ForegroundColorSpan(ForegroundColorSpan&& rhs) = default;
+
+ForegroundColorSpan& ForegroundColorSpan::operator=(const ForegroundColorSpan& rhs) = default;
+
+ForegroundColorSpan& ForegroundColorSpan::operator=(ForegroundColorSpan&& rhs) = default;
+
+ForegroundColorSpan::~ForegroundColorSpan() = default;
+
+//Methods
+const Vector4 ForegroundColorSpan::GetForegroundColor() const
+{
+  return GetImplementation(*this).GetForegroundColor();
+}
+
+bool ForegroundColorSpan::IsForegroundColorDefined() const
+{
+  return GetImplementation(*this).IsForegroundColorDefined();
+}
+
+ForegroundColorSpan ForegroundColorSpan::DownCast(BaseHandle handle)
+{
+  return ForegroundColorSpan(dynamic_cast<Dali::Toolkit::Text::Internal::ForegroundColorSpan*>(handle.GetObjectPtr()));
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/devel-api/text/spans/foreground-color-span.h b/dali-toolkit/devel-api/text/spans/foreground-color-span.h
new file mode 100644 (file)
index 0000000..f6f8c37
--- /dev/null
@@ -0,0 +1,130 @@
+#ifndef DALI_TOOLKIT_TEXT_FOREGROUND_COLOR_SPAN_H
+#define DALI_TOOLKIT_TEXT_FOREGROUND_COLOR_SPAN_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/devel-api/text/spans/base-span.h>
+#include <dali/public-api/math/vector4.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace Internal DALI_INTERNAL
+{
+class ForegroundColorSpan;
+}
+
+/**
+ * @brief ForegroundColorSpan is a handle to an object that specifies the foreground-color for range of characters.
+ */
+class DALI_TOOLKIT_API ForegroundColorSpan : public BaseSpan
+{
+public:
+  /**
+   * @brief Create an initialized ForegroundColorSpan.
+   *
+   * @param[in] color The foreground color.
+   *
+   * @return A handle to a newly allocated Dali resource
+   */
+  static ForegroundColorSpan New(Vector4 color);
+
+  /**
+   * @brief Creates an uninitialized ForegroundColorSpan handle.
+   *
+   * Calling member functions with an uninitialized ForegroundColorSpan handle is not allowed.
+   */
+  ForegroundColorSpan();
+
+  /**
+   * @brief Copy constructor.
+   * @param[in] rhs A reference to the copied handle
+   */
+  ForegroundColorSpan(const ForegroundColorSpan& rhs);
+
+  /**
+   * @brief Move constructor.
+   * @param[in] rhs A reference to the handle to move
+   */
+  ForegroundColorSpan(ForegroundColorSpan&& rhs);
+
+  /**
+   * @brief Assignment operator.
+   * @param[in] rhs A reference to the copied handle
+   * @return A reference to this
+   */
+  ForegroundColorSpan& operator=(const ForegroundColorSpan& rhs);
+
+  /**
+   * @brief Move assignment operator.
+   * @param[in] rhs A reference to the moved handle
+   * @return A reference to this
+   */
+  ForegroundColorSpan& operator=(ForegroundColorSpan&& rhs);
+
+  /**
+   * @brief Non virtual destructor.
+   */
+  ~ForegroundColorSpan();
+
+  /**
+   * @brief Downcasts to a ForegroundColorSpan handle.
+   * If handle is not a ForegroundColorSpan, the returned handle is left uninitialized.
+   *
+   * @param[in] handle Handle to an object
+   * @return ForegroundColorSpan handle or an uninitialized handle
+   */
+  static ForegroundColorSpan DownCast(BaseHandle handle);
+
+public: //Methods
+  /**
+   * @brief Retrive the foreground-color.
+   *
+   * @return A foreground-color value.
+   */
+  const Vector4 GetForegroundColor() const;
+
+  /**
+   * @brief Retrieve whether the foreground-color is defined.
+   *
+   * @return The return is true if foreground-color is defined, otherwise false.
+   */
+  bool IsForegroundColorDefined() const;
+
+public: // Not intended for application developers
+  /// @cond internal
+  /**
+   * @brief This constructor is used internally to Create an initialized ForegroundColorSpan handle.
+   *
+   * @param[in] colorSpan Pointer to internal ForegroundColorSpan
+   */
+  explicit DALI_INTERNAL ForegroundColorSpan(Internal::ForegroundColorSpan* colorSpan);
+  /// @endcond
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_FOREGROUND_COLOR_SPAN_H
index 2d71f4b..3142983 100644 (file)
@@ -157,6 +157,14 @@ SET( toolkit_src_files
    ${toolkit_src_dir}/text/property-string-parser.cpp
    ${toolkit_src_dir}/text/segmentation.cpp
    ${toolkit_src_dir}/text/shaper.cpp
+   ${toolkit_src_dir}/text/string-text/character-sequence-impl.cpp
+   ${toolkit_src_dir}/text/string-text/range-impl.cpp
+   ${toolkit_src_dir}/text/spannable/spanned-impl.cpp
+   ${toolkit_src_dir}/text/spannable/spannable-impl.cpp
+   ${toolkit_src_dir}/text/spannable/spannable-string-impl.cpp
+   ${toolkit_src_dir}/text/spannable/spans/base-span-impl.cpp
+   ${toolkit_src_dir}/text/spannable/spans/foreground-color-span-impl.cpp
+   ${toolkit_src_dir}/text/spannable/span-ranges-container-impl.cpp
    ${toolkit_src_dir}/text/hyphenator.cpp
    ${toolkit_src_dir}/text/text-enumerations-impl.cpp
    ${toolkit_src_dir}/text/text-effects-style.cpp
diff --git a/dali-toolkit/internal/text/spannable/span-ranges-container-impl.cpp b/dali-toolkit/internal/text/spannable/span-ranges-container-impl.cpp
new file mode 100644 (file)
index 0000000..8d95497
--- /dev/null
@@ -0,0 +1,88 @@
+
+/*
+ * 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-toolkit/internal/text/spannable/span-ranges-container-impl.h>
+#include <map>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace Internal
+{
+struct SpanRangesContainer::Impl
+{
+  std::map<Dali::Toolkit::Text::BaseSpan, Dali::Toolkit::Text::Range> mSpanWithRanges; ///< The list of style-span
+};
+
+SpanRangesContainer::SpanRangesContainer()
+{
+  mImpl = std::make_unique<Impl>();
+}
+
+SpanRangesContainer::~SpanRangesContainer()
+{
+}
+
+void SpanRangesContainer::AddSpan(const Dali::Toolkit::Text::BaseSpan& span, const Dali::Toolkit::Text::Range& range)
+{
+  mImpl->mSpanWithRanges.insert(std::make_pair(span, range));
+}
+
+void SpanRangesContainer::RemoveSpan(const Dali::Toolkit::Text::BaseSpan& span)
+{
+  mImpl->mSpanWithRanges.erase(span);
+}
+
+bool SpanRangesContainer::Contains(const Dali::Toolkit::Text::BaseSpan& span) const
+{
+  std::map<Dali::Toolkit::Text::BaseSpan, Dali::Toolkit::Text::Range>::iterator it = mImpl->mSpanWithRanges.find(span);
+
+  return it != mImpl->mSpanWithRanges.end();
+}
+
+void SpanRangesContainer::GetSpans(std::vector<Dali::Toolkit::Text::BaseSpan>& listOfSpans) const
+{
+  for(std::map<Dali::Toolkit::Text::BaseSpan, Dali::Toolkit::Text::Range>::iterator it = mImpl->mSpanWithRanges.begin();
+      it != mImpl->mSpanWithRanges.end();
+      ++it)
+  {
+    listOfSpans.push_back(it->first);
+  }
+}
+
+void SpanRangesContainer::GetSpansAndRanges(std::vector<Dali::Toolkit::Text::BaseSpan>& spans, std::vector<Dali::Toolkit::Text::Range>& ranges) const
+{
+  for(std::map<Dali::Toolkit::Text::BaseSpan, Dali::Toolkit::Text::Range>::iterator it = mImpl->mSpanWithRanges.begin();
+      it != mImpl->mSpanWithRanges.end();
+      ++it)
+  {
+    spans.push_back(it->first);
+    ranges.push_back(it->second);
+  }
+}
+} // namespace Internal
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/text/spannable/span-ranges-container-impl.h b/dali-toolkit/internal/text/spannable/span-ranges-container-impl.h
new file mode 100644 (file)
index 0000000..f89846e
--- /dev/null
@@ -0,0 +1,136 @@
+#ifndef DALI_TOOLKIT_INTERNAL_TEXT_SPANS_CONTAINER_IMPL_H
+#define DALI_TOOLKIT_INTERNAL_TEXT_SPANS_CONTAINER_IMPL_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-toolkit/devel-api/text/range.h>
+#include <dali-toolkit/devel-api/text/spans/base-span.h>
+#include <dali/public-api/common/dali-vector.h>
+#include <dali/public-api/math/vector4.h>
+#include <memory>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/spannable/spans/base-span-impl.h>
+#include <dali-toolkit/internal/text/string-text/range-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace Internal
+{
+class SpanRangesContainer;
+
+/**
+ * @brief The container for style spans.
+ * This is to isolate the responsibility of container type from the logic of the spanned text.
+ */
+class SpanRangesContainer
+{
+public:
+  /**
+   * @brief Default constructor.
+   */
+  SpanRangesContainer();
+
+  /**
+   * @brief Virtual destructor.
+   *
+   * A reference counted object may only be deleted by calling Unreference()
+   */
+  ~SpanRangesContainer();
+
+  //Methods
+public:
+  /**
+   * @brief Add the span to the list of spans.
+   *
+   * @param[in] span The span of style.
+   * @param[in] range The range.
+   *
+   */
+  void AddSpan(const Dali::Toolkit::Text::BaseSpan& span, const Dali::Toolkit::Text::Range& range);
+
+  /**
+   * @brief Remove the span from the list.
+   *
+   * @param[in] span The span of style.
+   *
+   */
+  void RemoveSpan(const Dali::Toolkit::Text::BaseSpan& span);
+
+  /**
+   * @brief Check if a given @p span is in list
+   *
+   * @param[in] span The span of style.
+   *
+   * @return true if the @p span exists. Otherwise false.
+   */
+  bool Contains(const Dali::Toolkit::Text::BaseSpan& span) const;
+
+  /**
+   * @brief Retrieve all spans.
+   *
+   * @param[out] listOfSpans container to clone spans
+   */
+  void GetSpans(std::vector<Dali::Toolkit::Text::BaseSpan>& listOfSpans) const;
+
+  /**
+   * @brief Retrieve all spans and ranges.
+   *
+   * @param[out] spans container to clone spans
+   * @param[out] ranges container to clone ranges
+   */
+  void GetSpansAndRanges(std::vector<Dali::Toolkit::Text::BaseSpan>& spans, std::vector<Dali::Toolkit::Text::Range>& ranges) const;
+
+  // Removed constructors and assignment operators
+public:                                                                // Constructors
+  SpanRangesContainer(const SpanRangesContainer&) = delete;            ///< Deleted copy constructor
+  SpanRangesContainer(SpanRangesContainer&&)      = delete;            ///< Deleted move constructor
+  SpanRangesContainer& operator=(const SpanRangesContainer&) = delete; ///< Deleted copy assignment operator
+  SpanRangesContainer& operator=(SpanRangesContainer&&) = delete;      ///< Deleted move assignment operator
+
+private:
+  // Data
+  struct Impl;
+  std::unique_ptr<Impl> mImpl{nullptr};
+
+}; // class SpanRangesContainer
+
+} // namespace Internal
+
+} // namespace Text
+
+} // namespace Toolkit
+
+// Allow SpanRangesContainer to be treated as a POD type
+template<>
+struct TypeTraits<Dali::Toolkit::Text::Internal::SpanRangesContainer> : public Dali::BasicTypes<Dali::Toolkit::Text::Internal::SpanRangesContainer>
+{
+  enum
+  {
+    IS_TRIVIAL_TYPE = true
+  };
+};
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_INTERNAL_TEXT_SPANS_CONTAINER_IMPL_H
diff --git a/dali-toolkit/internal/text/spannable/spannable-impl.cpp b/dali-toolkit/internal/text/spannable/spannable-impl.cpp
new file mode 100644 (file)
index 0000000..1a2b01b
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ *
+ */
+
+// HEADER FILE
+#include <dali-toolkit/internal/text/spannable/spannable-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace Internal
+{
+Spannable::Spannable()
+: Spanned()
+{
+}
+
+Spannable::~Spannable()
+{
+}
+
+} // namespace Internal
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/text/spannable/spannable-impl.h b/dali-toolkit/internal/text/spannable/spannable-impl.h
new file mode 100644 (file)
index 0000000..0b56043
--- /dev/null
@@ -0,0 +1,117 @@
+#ifndef DALI_TOOLKIT_INTERNAL_TEXT_SPANNABLE_IMPL_H
+#define DALI_TOOLKIT_INTERNAL_TEXT_SPANNABLE_IMPL_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-toolkit/devel-api/text/spannable.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/spannable/spanned-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace Internal
+{
+class Spannable;
+
+typedef IntrusivePtr<Spannable> SpannablePtr;
+typedef const Spannable*        SpannableConstPtr;
+
+/**
+ * @copydoc Dali::Toolkit::Text::Spannable
+ */
+class Spannable : public Spanned
+{
+public:
+  /**
+   * This constructor is only used by derived classes.
+   */
+  Spannable();
+
+  /**
+   * @brief Virtual destructor.
+   *
+   * A reference counted object may only be deleted by calling Unreference()
+   */
+  virtual ~Spannable() = 0;
+
+  // Removed constructors and assignment operators
+public:
+  Spannable(const Spannable&) = delete;            ///< Deleted copy constructor
+  Spannable(Spannable&&)      = delete;            ///< Deleted move constructor
+  Spannable& operator=(const Spannable&) = delete; ///< Deleted copy assignment operator
+  Spannable& operator=(Spannable&&) = delete;      ///< Deleted move assignment operator
+
+public: //Methods
+  /**
+   * @copydoc Dali::Toolkit::Text::Spannable::AttachSpan()
+   */
+  virtual bool AttachSpan(const Dali::Toolkit::Text::BaseSpan& styleSpan, const Dali::Toolkit::Text::Range& range) = 0;
+
+  /**
+   * @copydoc Dali::Toolkit::Text::Spannable::DetachSpan()
+   */
+  virtual bool DetachSpan(const Dali::Toolkit::Text::BaseSpan& styleSpan) = 0;
+
+}; // class Spannable
+
+} // namespace Internal
+
+/**
+ * Helper methods for public API.
+ */
+inline Internal::Spannable& GetImplementation(Dali::Toolkit::Text::Spannable& spannable)
+{
+  DALI_ASSERT_ALWAYS(spannable && "spannable handle is empty");
+
+  BaseObject& handle = spannable.GetBaseObject();
+
+  return static_cast<Internal::Spannable&>(handle);
+}
+
+inline const Internal::Spannable& GetImplementation(const Dali::Toolkit::Text::Spannable& spannable)
+{
+  DALI_ASSERT_ALWAYS(spannable && "spannable handle is empty");
+
+  const BaseObject& handle = spannable.GetBaseObject();
+
+  return static_cast<const Internal::Spannable&>(handle);
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+// Allow Spannable to be treated as a POD type
+template<>
+struct TypeTraits<Dali::Toolkit::Text::Internal::Spannable> : public Dali::BasicTypes<Dali::Toolkit::Text::Internal::Spannable>
+{
+  enum
+  {
+    IS_TRIVIAL_TYPE = true
+  };
+};
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_INTERNAL_TEXT_SPANNABLE_IMPL_H
diff --git a/dali-toolkit/internal/text/spannable/spannable-string-impl.cpp b/dali-toolkit/internal/text/spannable/spannable-string-impl.cpp
new file mode 100644 (file)
index 0000000..f224889
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * 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/internal/text/spannable/spannable-string-impl.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/character-set-conversion.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace Internal
+{
+struct SpannableString::Impl
+{
+  std::string       mText;       ///< The text (utf8).
+  Vector<Character> mCharacters; ///< The container of characters (utf32).
+  SpanRangesContainer mSpansContainer; ///< The container of spans and ranges
+};
+
+SpannableString::SpannableString(const std::string& text)
+{
+  mImpl                   = std::make_unique<Impl>();
+  mImpl->mText            = text;
+  Length         textSize = 0u;
+  const uint8_t* utf8     = NULL;
+
+  textSize = text.size();
+  utf8     = reinterpret_cast<const uint8_t*>(text.c_str());
+
+  //  Convert text into UTF-32
+  Vector<Character>& utf32Characters = mImpl->mCharacters;
+  utf32Characters.Resize(textSize);
+
+  // Transform a text array encoded in utf8 into an array encoded in utf32.
+  // It returns the actual number of characters.
+  Length characterCount = Utf8ToUtf32(utf8, textSize, utf32Characters.Begin());
+  utf32Characters.Resize(characterCount);
+
+  DALI_ASSERT_DEBUG(textSize >= characterCount && "Invalid UTF32 conversion length");
+}
+
+SpannableString::~SpannableString()
+{
+}
+
+Dali::Toolkit::Text::SpannableString SpannableString::New(const std::string& text)
+{
+  SpannableStringPtr object = new SpannableString(text);
+
+  Dali::Toolkit::Text::SpannableString handle = Dali::Toolkit::Text::SpannableString(object.Get());
+
+  return handle;
+}
+
+//Methods from CharacterSequence
+
+Vector<uint32_t> SpannableString::GetCharacters() const
+{
+  return mImpl->mCharacters;
+}
+
+uint32_t SpannableString::GetNumberOfCharacters() const
+{
+  return mImpl->mCharacters.Count();
+}
+
+std::string SpannableString::ToString() const
+{
+  return mImpl->mText;
+}
+
+//Methods from Spannable
+bool SpannableString::AttachSpan(const Dali::Toolkit::Text::BaseSpan& styleSpan, const Dali::Toolkit::Text::Range& range)
+{
+  if(range.GetStartIndex() < GetNumberOfCharacters() && range.GetEndIndex() < GetNumberOfCharacters())
+  {
+    mImpl->mSpansContainer.AddSpan(styleSpan, range);
+    return true;
+  }
+
+  return false;
+}
+
+bool SpannableString::DetachSpan(const Dali::Toolkit::Text::BaseSpan& styleSpan)
+{
+  if(mImpl->mSpansContainer.Contains(styleSpan))
+  {
+    mImpl->mSpansContainer.RemoveSpan(styleSpan);
+
+    return true;
+  }
+
+  return false;
+}
+
+//Methods from Spanned
+
+std::vector<Dali::Toolkit::Text::BaseSpan> SpannableString::GetAllSpans() const
+{
+  std::vector<Dali::Toolkit::Text::BaseSpan> listOfSpans;
+  mImpl->mSpansContainer.GetSpans(listOfSpans);
+  return listOfSpans;
+}
+
+void SpannableString::RetrieveAllSpansAndRanges(std::vector<Dali::Toolkit::Text::BaseSpan>& spans, std::vector<Dali::Toolkit::Text::Range>& ranges) const
+{
+  mImpl->mSpansContainer.GetSpansAndRanges(spans, ranges);
+}
+
+} // namespace Internal
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/text/spannable/spannable-string-impl.h b/dali-toolkit/internal/text/spannable/spannable-string-impl.h
new file mode 100644 (file)
index 0000000..5ecb823
--- /dev/null
@@ -0,0 +1,159 @@
+#ifndef DALI_TOOLKIT_INTERNAL_TEXT_SPANNABLE_STRING_IMPL_H
+#define DALI_TOOLKIT_INTERNAL_TEXT_SPANNABLE_STRING_IMPL_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-toolkit/devel-api/text/spannable-string.h>
+#include <memory>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/spannable/span-ranges-container-impl.h>
+#include <dali-toolkit/internal/text/spannable/spannable-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace Internal
+{
+class SpannableString;
+
+typedef IntrusivePtr<SpannableString> SpannableStringPtr;
+typedef const SpannableString*        SpannableStringConstPtr;
+
+/**
+ * @copydoc Dali::Toolkit::Text::SpannableString
+ */
+class SpannableString : public Spannable
+{
+public:
+  /**
+   * @brief Creates a new SpannableString.
+   *
+   * @return A public handle to the newly allocated SpannableString.
+   */
+  static Dali::Toolkit::Text::SpannableString New(const std::string& text);
+
+  /**
+   * @brief Destructor
+   *
+   * A reference counted object may only be deleted by calling Unreference()
+   */
+  ~SpannableString() override;
+
+protected:
+  /**
+   * @brief Constructs a new SpannableString.
+   */
+  SpannableString(const std::string& text);
+
+  // Removed constructors and assignment operators
+public:
+  SpannableString(const SpannableString&) = delete;            ///< Deleted copy constructor
+  SpannableString(SpannableString&&)      = delete;            ///< Deleted move constructor
+  SpannableString& operator=(const SpannableString&) = delete; ///< Deleted copy assignment operator
+  SpannableString& operator=(SpannableString&&) = delete;      ///< Deleted move assignment operator
+
+public:
+  //Methods from CharacterSequence
+  /**
+   * @copydoc Dali::Toolkit::Text::CharacterSequence::GetCharacters()
+   */
+  Vector<uint32_t> GetCharacters() const override;
+
+  /**
+   * @copydoc Dali::Toolkit::Text::CharacterSequence::GetNumberOfCharacters()
+   */
+  uint32_t GetNumberOfCharacters() const override;
+
+  /**
+   * @copydoc Dali::Toolkit::Text::CharacterSequence::ToString()
+   */
+  std::string ToString() const override;
+
+  //Methods from Spannable
+  /**
+   * @copydoc Dali::Toolkit::Text::Spannable::AttachSpan()
+   */
+  bool AttachSpan(const Dali::Toolkit::Text::BaseSpan& styleSpan, const Dali::Toolkit::Text::Range& range);
+
+  /**
+   * @copydoc Dali::Toolkit::Text::Spannable::DetachSpan()
+   */
+  bool DetachSpan(const Dali::Toolkit::Text::BaseSpan& styleSpan);
+
+  //Methods from Spanned
+  /**
+   * @copydoc Dali::Toolkit::Text::Spanned::GetAllSpans()
+   */
+  std::vector<Dali::Toolkit::Text::BaseSpan> GetAllSpans() const;
+
+  /**
+   * @copydoc Dali::Toolkit::Text::Spanned::RetrieveAllSpansAndRanges()
+   */
+  void RetrieveAllSpansAndRanges(std::vector<Dali::Toolkit::Text::BaseSpan>& spans, std::vector<Dali::Toolkit::Text::Range>& ranges) const;
+
+private:
+  struct Impl;
+  std::unique_ptr<Impl> mImpl{nullptr};
+
+}; // class SpannableString
+
+} // namespace Internal
+
+/**
+ * Helper methods for public API.
+ */
+inline Internal::SpannableString& GetImplementation(Dali::Toolkit::Text::SpannableString& spannableString)
+{
+  DALI_ASSERT_ALWAYS(spannableString && "spannableString handle is empty");
+
+  BaseObject& handle = spannableString.GetBaseObject();
+
+  return static_cast<Internal::SpannableString&>(handle);
+}
+
+inline const Internal::SpannableString& GetImplementation(const Dali::Toolkit::Text::SpannableString& spannableString)
+{
+  DALI_ASSERT_ALWAYS(spannableString && "spannableString handle is empty");
+
+  const BaseObject& handle = spannableString.GetBaseObject();
+
+  return static_cast<const Internal::SpannableString&>(handle);
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+// Allow SpannableString to be treated as a POD type
+template<>
+struct TypeTraits<Dali::Toolkit::Text::Internal::SpannableString> : public Dali::BasicTypes<Dali::Toolkit::Text::Internal::SpannableString>
+{
+  enum
+  {
+    IS_TRIVIAL_TYPE = true
+  };
+};
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_INTERNAL_TEXT_SPANNABLE_STRING_IMPL_H
diff --git a/dali-toolkit/internal/text/spannable/spanned-impl.cpp b/dali-toolkit/internal/text/spannable/spanned-impl.cpp
new file mode 100644 (file)
index 0000000..5610b92
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ *
+ */
+
+// HEADER FILE
+#include <dali-toolkit/internal/text/spannable/spanned-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace Internal
+{
+Spanned::Spanned()
+: CharacterSequence()
+{
+}
+
+Spanned::~Spanned()
+{
+}
+
+} // namespace Internal
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/text/spannable/spanned-impl.h b/dali-toolkit/internal/text/spannable/spanned-impl.h
new file mode 100644 (file)
index 0000000..4e5a8c7
--- /dev/null
@@ -0,0 +1,118 @@
+#ifndef DALI_TOOLKIT_INTERNAL_TEXT_SPANNED_IMPL_H
+#define DALI_TOOLKIT_INTERNAL_TEXT_SPANNED_IMPL_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-toolkit/devel-api/text/spanned.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/string-text/character-sequence-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace Internal
+{
+class CharacterSequence;
+class Spanned;
+
+typedef IntrusivePtr<Spanned> SpannedPtr;
+typedef const Spanned*        SpannedConstPtr;
+
+/**
+ * @copydoc Dali::Toolkit::Text::Spanned
+ */
+class Spanned : public CharacterSequence
+{
+public:
+  /**
+   * This constructor is only used by derived classes.
+   */
+  Spanned();
+
+  /**
+   * @brief Virtual destructor.
+   *
+   * A reference counted object may only be deleted by calling Unreference()
+   */
+  virtual ~Spanned() = 0;
+
+  // Removed constructors and assignment operators
+public:                                        // Constructors
+  Spanned(const Spanned&) = delete;            ///< Deleted copy constructor
+  Spanned(Spanned&&)      = delete;            ///< Deleted move constructor
+  Spanned& operator=(const Spanned&) = delete; ///< Deleted copy assignment operator
+  Spanned& operator=(Spanned&&) = delete;      ///< Deleted move assignment operator
+
+public: //Methods
+  /**
+   * @copydoc Dali::Toolkit::Text::Spanned::GetAllSpans()
+   */
+  virtual std::vector<Dali::Toolkit::Text::BaseSpan> GetAllSpans() const = 0;
+
+  /**
+   * @copydoc Dali::Toolkit::Text::Spanned::RetrieveAllSpansAndRanges()
+   */
+  virtual void RetrieveAllSpansAndRanges(std::vector<Dali::Toolkit::Text::BaseSpan>& spans, std::vector<Dali::Toolkit::Text::Range>& ranges) const = 0;
+
+}; // class Spanned
+
+} // namespace Internal
+
+/**
+ * Helper methods for public API.
+ */
+inline Internal::Spanned& GetImplementation(Dali::Toolkit::Text::Spanned& spanned)
+{
+  DALI_ASSERT_ALWAYS(spanned && "spanned handle is empty");
+
+  BaseObject& handle = spanned.GetBaseObject();
+
+  return static_cast<Internal::Spanned&>(handle);
+}
+
+inline const Internal::Spanned& GetImplementation(const Dali::Toolkit::Text::Spanned& spanned)
+{
+  DALI_ASSERT_ALWAYS(spanned && "spanned handle is empty");
+
+  const BaseObject& handle = spanned.GetBaseObject();
+
+  return static_cast<const Internal::Spanned&>(handle);
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+// Allow Spanned to be treated as a POD type
+template<>
+struct TypeTraits<Dali::Toolkit::Text::Internal::Spanned> : public Dali::BasicTypes<Dali::Toolkit::Text::Internal::Spanned>
+{
+  enum
+  {
+    IS_TRIVIAL_TYPE = true
+  };
+};
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_INTERNAL_TEXT_SPANNED_IMPL_H
diff --git a/dali-toolkit/internal/text/spannable/spans/base-span-impl.cpp b/dali-toolkit/internal/text/spannable/spans/base-span-impl.cpp
new file mode 100644 (file)
index 0000000..5f6498e
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * 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/internal/text/spannable/spans/base-span-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace Internal
+{
+BaseSpan::BaseSpan()
+{
+}
+
+BaseSpan::~BaseSpan()
+{
+}
+
+} // namespace Internal
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/text/spannable/spans/base-span-impl.h b/dali-toolkit/internal/text/spannable/spans/base-span-impl.h
new file mode 100644 (file)
index 0000000..9a3447c
--- /dev/null
@@ -0,0 +1,110 @@
+#ifndef DALI_TOOLKIT_INTERNAL_TEXT_BASE_SPAN_IMPL_H
+#define DALI_TOOLKIT_INTERNAL_TEXT_BASE_SPAN_IMPL_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 <memory>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/text/spans/base-span.h>
+#include <dali-toolkit/internal/text/text-definitions.h>
+#include <dali/public-api/object/base-object.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+class LogicalModel;
+struct AbstractStyleCharacterRun;
+
+namespace Internal
+{
+class BaseSpan;
+
+using BaseSpanPtr      = IntrusivePtr<BaseSpan>;
+using BaseSpanConstPtr = const BaseSpan*;
+
+/**
+ * @copydoc Dali::Toolkit::Text::BaseSpan
+ */
+class BaseSpan : public BaseObject
+{
+public:
+  BaseSpan(const BaseSpan&) = delete;            ///< Deleted copy constructor
+  BaseSpan(BaseSpan&&)      = delete;            ///< Deleted move constructor
+  BaseSpan& operator=(const BaseSpan&) = delete; ///< Deleted copy assignment operator
+  BaseSpan& operator=(BaseSpan&&) = delete;      ///< Deleted move assignment operator
+
+protected:
+  /**
+   * @brief Default Constructor
+   */
+  BaseSpan();
+
+  /**
+   * @brief Virtual destructor.
+   *
+   * A reference counted object may only be deleted by calling Unreference()
+   */
+  virtual ~BaseSpan();
+
+}; // class BaseSpan
+
+} // namespace Internal
+
+/**
+ * Helper methods for public API.
+ */
+inline Internal::BaseSpan& GetImplementation(Dali::Toolkit::Text::BaseSpan& baseSpan)
+{
+  DALI_ASSERT_ALWAYS(baseSpan && "baseSpan handle is empty");
+
+  BaseObject& handle = baseSpan.GetBaseObject();
+
+  return static_cast<Internal::BaseSpan&>(handle);
+}
+
+inline const Internal::BaseSpan& GetImplementation(const Dali::Toolkit::Text::BaseSpan& baseSpan)
+{
+  DALI_ASSERT_ALWAYS(baseSpan && "baseSpan handle is empty");
+
+  const BaseObject& handle = baseSpan.GetBaseObject();
+
+  return static_cast<const Internal::BaseSpan&>(handle);
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+// Allow BaseSpan to be treated as a POD type
+template<>
+struct TypeTraits<Dali::Toolkit::Text::Internal::BaseSpan> : public Dali::BasicTypes<Dali::Toolkit::Text::Internal::BaseSpan>
+{
+  enum
+  {
+    IS_TRIVIAL_TYPE = true
+  };
+};
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_INTERNAL_TEXT_BASE_SPAN_IMPL_H
diff --git a/dali-toolkit/internal/text/spannable/spans/foreground-color-span-impl.cpp b/dali-toolkit/internal/text/spannable/spans/foreground-color-span-impl.cpp
new file mode 100644 (file)
index 0000000..aaaa9dc
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * 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/internal/text/spannable/spans/foreground-color-span-impl.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/color-run.h>
+#include <dali-toolkit/internal/text/markup-tags-and-attributes.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace Internal
+{
+struct ForegroundColorSpan::Impl
+{
+  Vector4 mForegroundColor;            ///< The foreground-color of the characters.
+  bool    mForegroundColorDefined : 1; ///< Whether the foreground-color is defined.
+};
+
+ForegroundColorSpan::ForegroundColorSpan()
+: BaseSpan()
+{
+  mImpl = std::make_unique<Impl>();
+}
+
+ForegroundColorSpan ::~ForegroundColorSpan()
+{
+}
+
+Dali::Toolkit::Text::ForegroundColorSpan ForegroundColorSpan::New(Vector4 color)
+{
+  ForegroundColorSpanPtr object = new ForegroundColorSpan();
+  object->SetForegroundColor(color);
+
+  Dali::Toolkit::Text::ForegroundColorSpan handle = Dali::Toolkit::Text::ForegroundColorSpan(object.Get());
+
+  return handle;
+}
+
+//Methods
+const Vector4 ForegroundColorSpan::GetForegroundColor() const
+{
+  return mImpl->mForegroundColor;
+}
+
+bool ForegroundColorSpan::IsForegroundColorDefined() const
+{
+  return mImpl->mForegroundColorDefined;
+}
+
+void ForegroundColorSpan::SetForegroundColor(Vector4 color)
+{
+  mImpl->mForegroundColor        = color;
+  mImpl->mForegroundColorDefined = true;
+}
+
+} // namespace Internal
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/text/spannable/spans/foreground-color-span-impl.h b/dali-toolkit/internal/text/spannable/spans/foreground-color-span-impl.h
new file mode 100644 (file)
index 0000000..ae6476c
--- /dev/null
@@ -0,0 +1,121 @@
+#ifndef DALI_TOOLKIT_INTERNAL_TEXT_FOREGROUND_COLOR_SPAN_IMPL_H
+#define DALI_TOOLKIT_INTERNAL_TEXT_FOREGROUND_COLOR_SPAN_IMPL_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-toolkit/devel-api/text/spans/foreground-color-span.h>
+#include <memory>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/spannable/spans/base-span-impl.h>
+#include <dali/public-api/math/vector4.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace Internal
+{
+class ForegroundColorSpan;
+using ForegroundColorSpanPtr = IntrusivePtr<ForegroundColorSpan>;
+
+/**
+ * @copydoc Dali::Toolkit::Text::ForegroundColorSpan
+ */
+class ForegroundColorSpan : public BaseSpan
+{
+public:
+  /**
+   * @brief Creates a new ForegroundColorSpan object.
+   */
+  static Dali::Toolkit::Text::ForegroundColorSpan New(Vector4 color);
+
+  /**
+   * Default Constructor
+   */
+  ForegroundColorSpan();
+
+  ForegroundColorSpan(const ForegroundColorSpan&) = delete;            ///< Deleted copy constructor
+  ForegroundColorSpan(ForegroundColorSpan&&)      = delete;            ///< Deleted move constructor
+  ForegroundColorSpan& operator=(const ForegroundColorSpan&) = delete; ///< Deleted copy assignment operator
+  ForegroundColorSpan& operator=(ForegroundColorSpan&&) = delete;      ///< Deleted move assignment operator
+
+  /**
+   * @brief Destructor
+   *
+   * A reference counted object may only be deleted by calling Unreference()
+   */
+  ~ForegroundColorSpan() override;
+
+public: //Methods
+  /**
+   * @copydoc Dali::Toolkit::Text::ForegroundColorSpan::GetForegroundColor()
+   */
+  const Vector4 GetForegroundColor() const;
+
+  /**
+   * @copydoc Dali::Toolkit::Text::ForegroundColorSpan::IsForegroundColorDefined()
+   */
+  bool IsForegroundColorDefined() const;
+
+public: //Methods. Not intended for application developers
+  /**
+   * @brief Set the foreground-color.
+   *
+   * @param[in] color The foreground-color.
+   */
+  void SetForegroundColor(Vector4 color);
+
+private:
+  struct Impl;
+  std::unique_ptr<Impl> mImpl{nullptr};
+
+}; // class ForegroundColorSpan
+
+} // namespace Internal
+
+// Helpers for public-api forwarding methods
+
+inline Internal::ForegroundColorSpan& GetImplementation(Dali::Toolkit::Text::ForegroundColorSpan& foregroundColorSpan)
+{
+  DALI_ASSERT_ALWAYS(foregroundColorSpan && "foregroundColorSpan handle is empty");
+
+  BaseObject& object = foregroundColorSpan.GetBaseObject();
+
+  return static_cast<Internal::ForegroundColorSpan&>(object);
+}
+
+inline const Internal::ForegroundColorSpan& GetImplementation(const Dali::Toolkit::Text::ForegroundColorSpan& foregroundColorSpan)
+{
+  DALI_ASSERT_ALWAYS(foregroundColorSpan && "foregroundColorSpan handle is empty");
+
+  const BaseObject& object = foregroundColorSpan.GetBaseObject();
+
+  return static_cast<const Internal::ForegroundColorSpan&>(object);
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_INTERNAL_TEXT_FOREGROUND_COLOR_SPAN_IMPL_H
\ No newline at end of file
diff --git a/dali-toolkit/internal/text/string-text/character-sequence-impl.cpp b/dali-toolkit/internal/text/string-text/character-sequence-impl.cpp
new file mode 100644 (file)
index 0000000..10ebe24
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ *
+ */
+
+// HEADER FILE
+#include <dali-toolkit/internal/text/string-text/character-sequence-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace Internal
+{
+CharacterSequence::CharacterSequence()
+: BaseObject()
+{
+}
+
+CharacterSequence::~CharacterSequence()
+{
+}
+
+} // namespace Internal
+} // namespace Text
+} // namespace Toolkit
+} // namespace Dali
diff --git a/dali-toolkit/internal/text/string-text/character-sequence-impl.h b/dali-toolkit/internal/text/string-text/character-sequence-impl.h
new file mode 100644 (file)
index 0000000..d04883b
--- /dev/null
@@ -0,0 +1,124 @@
+#ifndef DALI_TOOLKIT_INTERNAL_TEXT_CHARACTER_SEQUENCE_IMPL_H
+#define DALI_TOOLKIT_INTERNAL_TEXT_CHARACTER_SEQUENCE_IMPL_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-toolkit/devel-api/text/character-sequence.h>
+#include <memory>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/text-definitions.h>
+#include <dali/public-api/object/base-object.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace Internal
+{
+class CharacterSequence;
+
+typedef IntrusivePtr<CharacterSequence> CharacterSequencePtr;
+typedef const CharacterSequence*        CharacterSequenceConstPtr;
+
+/**
+ * @copydoc Dali::Toolkit::Text::CharacterSequence
+ */
+class CharacterSequence : public BaseObject
+{
+public:
+  /**
+   * This constructor is only used by derived classes.
+   */
+  CharacterSequence();
+
+  /**
+   * @brief Virtual destructor.
+   *
+   * A reference counted object may only be deleted by calling Unreference()
+   */
+  virtual ~CharacterSequence() = 0;
+
+  // Removed constructors and assignment operators
+public:
+  CharacterSequence(const CharacterSequence&) = delete;            ///< Deleted copy constructor
+  CharacterSequence(CharacterSequence&&)      = delete;            ///< Deleted move constructor
+  CharacterSequence& operator=(const CharacterSequence&) = delete; ///< Deleted copy assignment operator
+  CharacterSequence& operator=(CharacterSequence&&) = delete;      ///< Deleted move assignment operator
+
+public: //Methods
+  /**
+   * @copydoc Dali::Toolkit::Text::CharacterSequence::GetCharacters()
+   */
+  virtual Vector<uint32_t> GetCharacters() const = 0;
+
+  /**
+   * @copydoc Dali::Toolkit::Text::CharacterSequence::GetNumberOfCharacters()
+   */
+  virtual uint32_t GetNumberOfCharacters() const = 0;
+
+  /**
+   * @copydoc Dali::Toolkit::Text::CharacterSequence::ToString()
+   */
+  virtual std::string ToString() const = 0;
+
+}; // class CharacterSequence
+
+} // namespace Internal
+
+/**
+ * Helper methods for public API.
+ */
+inline Internal::CharacterSequence& GetImplementation(Dali::Toolkit::Text::CharacterSequence& characterSequence)
+{
+  DALI_ASSERT_ALWAYS(characterSequence && "characterSequence handle is empty");
+
+  BaseObject& handle = characterSequence.GetBaseObject();
+
+  return static_cast<Internal::CharacterSequence&>(handle);
+}
+
+inline const Internal::CharacterSequence& GetImplementation(const Dali::Toolkit::Text::CharacterSequence& characterSequence)
+{
+  DALI_ASSERT_ALWAYS(characterSequence && "characterSequence handle is empty");
+
+  const BaseObject& handle = characterSequence.GetBaseObject();
+
+  return static_cast<const Internal::CharacterSequence&>(handle);
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+// Allow AbstractStyleSpan to be treated as a POD type
+template<>
+struct TypeTraits<Dali::Toolkit::Text::Internal::CharacterSequence> : public Dali::BasicTypes<Dali::Toolkit::Text::Internal::CharacterSequence>
+{
+  enum
+  {
+    IS_TRIVIAL_TYPE = true
+  };
+};
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_INTERNAL_TEXT_CHARACTER_SEQUENCE_IMPL_H
diff --git a/dali-toolkit/internal/text/string-text/range-impl.cpp b/dali-toolkit/internal/text/string-text/range-impl.cpp
new file mode 100644 (file)
index 0000000..8090958
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * 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/internal/text/string-text/range-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace Internal
+{
+struct Range::Impl
+{
+  u_int32_t mStartIndex; /// The start index of range
+  u_int32_t mEndIndex;   /// The end index of range
+};
+
+Dali::Toolkit::Text::Range Range::New(u_int32_t startIndex, u_int32_t endIndex)
+{
+  RangePtr object = new Range(startIndex, endIndex);
+
+  Dali::Toolkit::Text::Range handle = Dali::Toolkit::Text::Range(object.Get());
+
+  return handle;
+}
+
+Range::Range(u_int32_t startIndex, u_int32_t endIndex)
+{
+  mImpl = std::make_unique<Impl>();
+
+  mImpl->mStartIndex = startIndex <= endIndex ? startIndex : endIndex;
+  mImpl->mEndIndex   = startIndex >= endIndex ? startIndex : endIndex;
+}
+
+Range::~Range()
+{
+}
+
+u_int32_t Range::GetStartIndex() const
+{
+  return mImpl->mStartIndex;
+}
+
+u_int32_t Range::GetEndIndex() const
+{
+  return mImpl->mEndIndex;
+}
+
+u_int32_t Range::GetNumberOfIndices() const
+{
+  return 1u + ((mImpl->mStartIndex <= mImpl->mEndIndex) ? (mImpl->mEndIndex - mImpl->mStartIndex) : (mImpl->mStartIndex - mImpl->mEndIndex));
+}
+
+} // namespace Internal
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/text/string-text/range-impl.h b/dali-toolkit/internal/text/string-text/range-impl.h
new file mode 100644 (file)
index 0000000..8b0f0d2
--- /dev/null
@@ -0,0 +1,141 @@
+#ifndef DALI_TOOLKIT_INTERNAL_TEXT_RANGE_IMPL_H
+#define DALI_TOOLKIT_INTERNAL_TEXT_RANGE_IMPL_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 <memory>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/text/range.h>
+#include <dali/public-api/object/base-object.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace Internal
+{
+class Range;
+
+typedef IntrusivePtr<Range> RangePtr;
+
+/**
+ * @copydoc Dali::Toolkit::Text::Range
+ */
+class Range : public BaseObject
+{
+public:
+  /**
+   * @brief Creates a new Range.
+   *
+   * @param[in] startIndex the start index of range (included)
+   * @param[in] endIndex the end index of range (included)
+   *
+   * @return A public handle to the newly allocated Range.
+   */
+  static Dali::Toolkit::Text::Range New(u_int32_t startIndex, u_int32_t endIndex);
+
+  /**
+   * @brief Destructor
+   *
+   * A reference counted object may only be deleted by calling Unreference()
+   */
+  ~Range();
+
+protected:
+  /**
+   * @brief Constructs a new Range.
+   *
+   * @param[in] startIndex the start index of range (included)
+   * @param[in] endIndex the end index of range (included)
+   *
+   */
+  Range(u_int32_t startIndex, u_int32_t endIndex);
+
+public: //Methods
+  /**
+   * @copydoc Dali::Toolkit::Text::Range::GetStartIndex()
+   */
+  u_int32_t GetStartIndex() const;
+
+  /**
+   * @copydoc Dali::Toolkit::Text::Range::GetEndIndex()
+   */
+  u_int32_t GetEndIndex() const;
+
+  /**
+   * @copydoc Dali::Toolkit::Text::Range::GetNumberOfIndices()
+   */
+  u_int32_t GetNumberOfIndices() const;
+
+public:
+  Range(const Range&) = delete;            ///< Deleted copy constructor
+  Range(Range&&)      = delete;            ///< Deleted move constructor
+  Range& operator=(const Range&) = delete; ///< Deleted copy assignment operator
+  Range& operator=(Range&&) = delete;      ///< Deleted move assignment operator
+
+private:
+  // Data
+  struct Impl;
+  std::unique_ptr<Impl> mImpl{nullptr};
+
+}; // class Range
+
+} // namespace Internal
+
+/**
+ * Helper methods for public API.
+ */
+inline Internal::Range& GetImplementation(Dali::Toolkit::Text::Range& range)
+{
+  DALI_ASSERT_ALWAYS(range && "range handle is empty");
+
+  BaseObject& handle = range.GetBaseObject();
+
+  return static_cast<Internal::Range&>(handle);
+}
+
+inline const Internal::Range& GetImplementation(const Dali::Toolkit::Text::Range& range)
+{
+  DALI_ASSERT_ALWAYS(range && "range handle is empty");
+
+  const BaseObject& handle = range.GetBaseObject();
+
+  return static_cast<const Internal::Range&>(handle);
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+// Allow Range to be treated as a POD type
+template<>
+struct TypeTraits<Dali::Toolkit::Text::Internal::Range> : public Dali::BasicTypes<Dali::Toolkit::Text::Internal::Range>
+{
+  enum
+  {
+    IS_TRIVIAL_TYPE = true
+  };
+};
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_INTERNAL_TEXT_RANGE_IMPL_H