Spannable: Add FontSpan 34/285134/4
authorssabah <s.sabah@samsung.com>
Mon, 5 Dec 2022 18:57:43 +0000 (21:57 +0300)
committerssabah <s.sabah@samsung.com>
Wed, 7 Dec 2022 11:47:02 +0000 (14:47 +0300)
FontSpan: Span to change the font properties (FamilyName, Size, Weight, Slant and Width) of characters

This patch should be preceded by the patch below:
https://review.tizen.org/gerrit/c/platform/core/uifw/dali-toolkit/+/285133

Change-Id: I1b85d77ba214b1c37737a435b021f37bb095fd8b

automated-tests/src/dali-toolkit-internal/utc-Dali-Text-TextSpannable.cpp
automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/utc-Dali-Text-FontSpan.cpp [new file with mode: 0644]
dali-toolkit/devel-api/file.list
dali-toolkit/devel-api/text/spans/font-span.cpp [new file with mode: 0644]
dali-toolkit/devel-api/text/spans/font-span.h [new file with mode: 0644]
dali-toolkit/internal/file.list
dali-toolkit/internal/text/spannable/spans/font-span-impl.cpp [new file with mode: 0644]
dali-toolkit/internal/text/spannable/spans/font-span-impl.h [new file with mode: 0644]

index 12d1613..098e660 100644 (file)
 #include <dali-toolkit/dali-toolkit.h>
 #include <dali-toolkit/devel-api/controls/text-controls/text-spannable.h>
 #include <dali-toolkit/devel-api/text/spannable-string.h>
+#include <dali-toolkit/devel-api/text/spans/font-span.h>
 #include <dali-toolkit/devel-api/text/spans/foreground-color-span.h>
+#include <dali-toolkit/devel-api/text/text-enumerations-devel.h>
 #include <dali-toolkit/internal/controls/text-controls/text-editor-impl.h>
 #include <dali-toolkit/internal/controls/text-controls/text-field-impl.h>
 #include <dali-toolkit/internal/controls/text-controls/text-label-impl.h>
+#include <dali-toolkit/internal/text/font-description-run.h>
+#include <dali-toolkit/public-api/text/text-enumerations.h>
 
 using namespace Dali;
 using namespace Toolkit;
 
+namespace
+{
+const std::string DEFAULT_FONT_DIR("/resources/fonts");
+const float PIXEL_FORMAT_64_FACTOR = 64.f; ///< 64.f is used to convert from point size to 26.6 pixel format.
+} // namespace
+
 Text::SpannableString CreateSpannableStringForForegroundColorSpan()
 {
   Text::SpannableString spannableString = Text::SpannableString::New("Hello مرحبا");
@@ -44,6 +54,23 @@ Text::SpannableString CreateSpannableStringForForegroundColorSpan()
   return spannableString;
 }
 
+Text::SpannableString CreateSpannableStringForFontSpan()
+{
+  Text::SpannableString spannableString = Text::SpannableString::New("Hello World");
+  DALI_TEST_CHECK(spannableString);
+
+  auto isAddedFontSpan = spannableString.AttachSpan(
+    Text::FontSpan::New("TizenSans",
+                        45.0f,
+                        Dali::TextAbstraction::FontWeight::BOLD,
+                        Dali::TextAbstraction::FontWidth::SEMI_CONDENSED,
+                        Dali::TextAbstraction::FontSlant::OBLIQUE),
+    Text::Range::New(5u, 7u));
+  DALI_TEST_CHECK(isAddedFontSpan);
+
+  return spannableString;
+}
+
 void CheckColorIndices(const Text::ColorIndex* const colorIndicesBuffer,
                        uint32_t                      numberOfIndices,
                        std::vector<uint32_t>         indicesToCheck,
@@ -128,3 +155,61 @@ int UtcDaliToolkitTextFieldSetSpannedText(void)
 
   END_TEST;
 }
+
+int UtcDaliToolkitTextLabelSetSpannedText_FontSpan(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextLabelSetSpannedText_FontSpan ");
+
+  // Load some fonts to get the same metrics on different platforms.
+  TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+  fontClient.SetDpi(96u, 96u);
+
+  char*             pathNamePtr = get_current_dir_name();
+  const std::string pathName(pathNamePtr);
+  free(pathNamePtr);
+
+  fontClient.GetFontId(pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf");
+
+  TextLabel textLabel = TextLabel::New();
+  DALI_TEST_CHECK(textLabel);
+  application.GetScene().Add(textLabel);
+
+  Text::SpannableString spannableString = CreateSpannableStringForFontSpan();
+
+  Text::SetSpannedText(textLabel, spannableString);
+
+  application.SendNotification();
+  application.Render();
+
+  Toolkit::Internal::TextLabel&               labelImpl  = GetImpl(textLabel);
+  const Vector<Dali::Toolkit::Text::FontRun>& validFontRuns = labelImpl.GetTextController()->GetTextModel()->GetFontRuns();
+
+  DALI_TEST_EQUALS(validFontRuns.Count(), 3u, TEST_LOCATION);
+
+  DALI_TEST_EQUALS(validFontRuns[0].fontId, validFontRuns[2].fontId, TEST_LOCATION);
+  DALI_TEST_NOT_EQUALS(validFontRuns[0].fontId, validFontRuns[1].fontId, Math::MACHINE_EPSILON_100, TEST_LOCATION);
+
+  DALI_TEST_EQUALS(validFontRuns[1].characterRun.characterIndex, 5u, TEST_LOCATION);
+  DALI_TEST_EQUALS(validFontRuns[1].characterRun.GetEndCharacterIndex(), 7u, TEST_LOCATION);
+  DALI_TEST_EQUALS(validFontRuns[1].isItalicRequired, true, TEST_LOCATION);
+  DALI_TEST_EQUALS(validFontRuns[1].isBoldRequired, true, TEST_LOCATION);
+
+  TextAbstraction::FontDescription spanFontDescription;
+
+  float expectedPointSize = 45.0f * PIXEL_FORMAT_64_FACTOR;
+  float fontPointSize     = fontClient.GetPointSize(validFontRuns[1].fontId);
+  DALI_TEST_EQUALS(fontPointSize, expectedPointSize, TEST_LOCATION);
+
+  const Vector<Dali::Toolkit::Text::FontDescriptionRun>& validFontDescriptionRuns = labelImpl.GetTextController()->GetTextModel()->GetFontDescriptionRuns();
+  DALI_TEST_EQUALS(validFontDescriptionRuns.Count(), 1u, TEST_LOCATION);
+  std::string familyName = validFontDescriptionRuns[0].familyName;
+
+  DALI_TEST_EQUALS(familyName, "TizenSans", TEST_LOCATION);
+  DALI_TEST_EQUALS(validFontDescriptionRuns[0].size, expectedPointSize, TEST_LOCATION);
+  DALI_TEST_EQUALS(validFontDescriptionRuns[0].weight, Dali::TextAbstraction::FontWeight::BOLD, TEST_LOCATION);
+  DALI_TEST_EQUALS(validFontDescriptionRuns[0].width, Dali::TextAbstraction::FontWidth::SEMI_CONDENSED, TEST_LOCATION);
+  DALI_TEST_EQUALS(validFontDescriptionRuns[0].slant, Dali::TextAbstraction::FontSlant::OBLIQUE, TEST_LOCATION);
+
+  END_TEST;
+}
\ No newline at end of file
index bf9d8f8..f4643e3 100755 (executable)
@@ -42,6 +42,7 @@ SET(TC_SOURCES
   utc-Dali-TableView.cpp
   utc-Dali-Text-BaseSpan.cpp
   utc-Dali-Text-ForegroundColorSpan.cpp
+  utc-Dali-Text-FontSpan.cpp
   utc-Dali-Text-Range.cpp
   utc-Dali-Text-SpannableString.cpp
   utc-Dali-TextEditor.cpp
diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Text-FontSpan.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Text-FontSpan.cpp
new file mode 100644 (file)
index 0000000..59312a0
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * 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/font-span.h>
+
+using namespace Dali;
+using namespace Toolkit;
+
+int UtcDaliToolkitTextFontSpanNew(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextFontSpanNew");
+
+  auto fontSpan = Text::FontSpan::New("DejaVu Sans",
+                                      45.0f,
+                                      Dali::TextAbstraction::FontWeight::BOLD,
+                                      Dali::TextAbstraction::FontWidth::CONDENSED,
+                                      Dali::TextAbstraction::FontSlant::ITALIC);
+  DALI_TEST_CHECK(fontSpan);
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextGetFamilyName(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextGetFamilyName");
+
+  auto fontSpan = Text::FontSpan::New("DejaVu Sans",
+                                      45.0f,
+                                      Dali::TextAbstraction::FontWeight::BOLD,
+                                      Dali::TextAbstraction::FontWidth::CONDENSED,
+                                      Dali::TextAbstraction::FontSlant::ITALIC);
+  DALI_TEST_CHECK(fontSpan);
+
+  DALI_TEST_EQUALS("DejaVu Sans", fontSpan.GetFamilyName(), TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextIsFamilyNameDefined(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextIsFamilyNameDefined");
+
+  auto fontSpan = Text::FontSpan::New("DejaVu Sans",
+                                      45.0f,
+                                      Dali::TextAbstraction::FontWeight::BOLD,
+                                      Dali::TextAbstraction::FontWidth::CONDENSED,
+                                      Dali::TextAbstraction::FontSlant::ITALIC);
+  DALI_TEST_CHECK(fontSpan);
+
+  DALI_TEST_EQUALS(true, fontSpan.IsFamilyNameDefined(), TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextGetWeight(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextGetWeight");
+
+  auto fontSpan = Text::FontSpan::New("DejaVu Sans",
+                                      45.0f,
+                                      Dali::TextAbstraction::FontWeight::BOLD,
+                                      Dali::TextAbstraction::FontWidth::CONDENSED,
+                                      Dali::TextAbstraction::FontSlant::ITALIC);
+  DALI_TEST_CHECK(fontSpan);
+
+  DALI_TEST_EQUALS(Dali::TextAbstraction::FontWeight::BOLD, fontSpan.GetWeight(), TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextIsWeightDefined(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextIsWeightDefined");
+
+  auto fontSpan = Text::FontSpan::New("DejaVu Sans",
+                                      45.0f,
+                                      Dali::TextAbstraction::FontWeight::BOLD,
+                                      Dali::TextAbstraction::FontWidth::CONDENSED,
+                                      Dali::TextAbstraction::FontSlant::ITALIC);
+  DALI_TEST_CHECK(fontSpan);
+
+  DALI_TEST_EQUALS(true, fontSpan.IsWeightDefined(), TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextGetWidth(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextGetWidth");
+
+  auto fontSpan = Text::FontSpan::New("DejaVu Sans",
+                                      45.0f,
+                                      Dali::TextAbstraction::FontWeight::BOLD,
+                                      Dali::TextAbstraction::FontWidth::CONDENSED,
+                                      Dali::TextAbstraction::FontSlant::ITALIC);
+  DALI_TEST_CHECK(fontSpan);
+
+  DALI_TEST_EQUALS(Dali::TextAbstraction::FontWidth::CONDENSED, fontSpan.GetWidth(), TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextIsWidthDefined(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextIsWidthDefined");
+
+  auto fontSpan = Text::FontSpan::New("DejaVu Sans",
+                                      45.0f,
+                                      Dali::TextAbstraction::FontWeight::BOLD,
+                                      Dali::TextAbstraction::FontWidth::CONDENSED,
+                                      Dali::TextAbstraction::FontSlant::ITALIC);
+  DALI_TEST_CHECK(fontSpan);
+
+  DALI_TEST_EQUALS(true, fontSpan.IsWidthDefined(), TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextGetSlant(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextGetSlant");
+
+  auto fontSpan = Text::FontSpan::New("DejaVu Sans",
+                                      45.0f,
+                                      Dali::TextAbstraction::FontWeight::BOLD,
+                                      Dali::TextAbstraction::FontWidth::CONDENSED,
+                                      Dali::TextAbstraction::FontSlant::ITALIC);
+  DALI_TEST_CHECK(fontSpan);
+
+  DALI_TEST_EQUALS(Dali::TextAbstraction::FontSlant::ITALIC, fontSpan.GetSlant(), TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextIsSlantDefined(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextIsSlantDefined");
+
+  auto fontSpan = Text::FontSpan::New("DejaVu Sans",
+                                      45.0f,
+                                      Dali::TextAbstraction::FontWeight::BOLD,
+                                      Dali::TextAbstraction::FontWidth::CONDENSED,
+                                      Dali::TextAbstraction::FontSlant::ITALIC);
+  DALI_TEST_CHECK(fontSpan);
+
+  DALI_TEST_EQUALS(true, fontSpan.IsSlantDefined(), TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextGetSize(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextGetSize");
+
+  auto fontSpan = Text::FontSpan::New("DejaVu Sans",
+                                      45.0f,
+                                      Dali::TextAbstraction::FontWeight::BOLD,
+                                      Dali::TextAbstraction::FontWidth::CONDENSED,
+                                      Dali::TextAbstraction::FontSlant::ITALIC);
+  DALI_TEST_CHECK(fontSpan);
+
+  DALI_TEST_EQUALS(45.0f, fontSpan.GetSize(), TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextIsSizeDefined(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextIsSizeDefined");
+
+  auto fontSpan = Text::FontSpan::New("DejaVu Sans",
+                                      45.0f,
+                                      Dali::TextAbstraction::FontWeight::BOLD,
+                                      Dali::TextAbstraction::FontWidth::CONDENSED,
+                                      Dali::TextAbstraction::FontSlant::ITALIC);
+  DALI_TEST_CHECK(fontSpan);
+
+  DALI_TEST_EQUALS(true, fontSpan.IsSizeDefined(), TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliToolkitTextFontSpanDownCast(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextFontSpanDownCast");
+
+  Text::BaseSpan baseSpan = Text::FontSpan::New("DejaVu Sans",
+                                                45.0f,
+                                                Dali::TextAbstraction::FontWeight::BOLD,
+                                                Dali::TextAbstraction::FontWidth::CONDENSED,
+                                                Dali::TextAbstraction::FontSlant::ITALIC);
+  DALI_TEST_CHECK(baseSpan);
+
+  Text::FontSpan greenSpan = Text::FontSpan::DownCast(baseSpan);
+  DALI_TEST_CHECK(greenSpan);
+
+  END_TEST;
+}
index ef347e7..b2ac025 100755 (executable)
@@ -68,6 +68,7 @@ SET( devel_api_src_files
   ${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}/text/spans/font-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
@@ -249,6 +250,7 @@ SET( devel_api_text_header_files
   ${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
+  ${devel_api_src_dir}/text/spans/font-span.h
 )
 
 SET( devel_api_tool_bar_header_files
diff --git a/dali-toolkit/devel-api/text/spans/font-span.cpp b/dali-toolkit/devel-api/text/spans/font-span.cpp
new file mode 100644 (file)
index 0000000..a0eb945
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * 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/font-span.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/spannable/spans/font-span-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+FontSpan FontSpan::New(const std::string                             familyName,
+                       const float                                   sizeInPoints,
+                       const Dali::TextAbstraction::FontWeight::Type weight,
+                       const Dali::TextAbstraction::FontWidth::Type  width,
+                       const Dali::TextAbstraction::FontSlant::Type  slant)
+{
+  return Internal::FontSpan::New(familyName, sizeInPoints, weight, width, slant);
+}
+
+FontSpan::FontSpan(Internal::FontSpan* internal)
+: BaseSpan(internal)
+{
+}
+
+FontSpan::FontSpan() = default;
+
+FontSpan::FontSpan(const FontSpan& rhs) = default;
+
+FontSpan::FontSpan(FontSpan&& rhs) = default;
+
+FontSpan& FontSpan::operator=(const FontSpan& rhs) = default;
+
+FontSpan& FontSpan::operator=(FontSpan&& rhs) = default;
+
+FontSpan::~FontSpan() = default;
+
+//Methods
+const std::string FontSpan::GetFamilyName() const
+{
+  return GetImplementation(*this).GetFamilyName();
+}
+
+bool FontSpan::IsFamilyNameDefined() const
+{
+  return GetImplementation(*this).IsFamilyNameDefined();
+}
+
+const Dali::TextAbstraction::FontWeight::Type FontSpan::GetWeight() const
+{
+  return GetImplementation(*this).GetWeight();
+}
+
+bool FontSpan::IsWeightDefined() const
+{
+  return GetImplementation(*this).IsWeightDefined();
+}
+
+const Dali::TextAbstraction::FontWidth::Type FontSpan::GetWidth() const
+{
+  return GetImplementation(*this).GetWidth();
+}
+
+bool FontSpan::IsWidthDefined() const
+{
+  return GetImplementation(*this).IsWidthDefined();
+}
+
+const Dali::TextAbstraction::FontSlant::Type FontSpan::GetSlant() const
+{
+  return GetImplementation(*this).GetSlant();
+}
+
+bool FontSpan::IsSlantDefined() const
+{
+  return GetImplementation(*this).IsSlantDefined();
+}
+
+const float FontSpan::GetSize() const
+{
+  return GetImplementation(*this).GetSize();
+}
+
+bool FontSpan::IsSizeDefined() const
+{
+  return GetImplementation(*this).IsSizeDefined();
+}
+
+FontSpan FontSpan::DownCast(BaseHandle handle)
+{
+  return FontSpan(dynamic_cast<Dali::Toolkit::Text::Internal::FontSpan*>(handle.GetObjectPtr()));
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/devel-api/text/spans/font-span.h b/dali-toolkit/devel-api/text/spans/font-span.h
new file mode 100644 (file)
index 0000000..6a98c5d
--- /dev/null
@@ -0,0 +1,197 @@
+#ifndef DALI_TOOLKIT_TEXT_FONT_SPAN_H
+#define DALI_TOOLKIT_TEXT_FONT_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/devel-api/text-abstraction/font-list.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/text/spans/base-span.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace Internal DALI_INTERNAL
+{
+class FontSpan;
+}
+
+/**
+ * @brief FontSpan is a handle to an object that specifies the font properties for range of characters.
+ */
+class DALI_TOOLKIT_API FontSpan : public BaseSpan
+{
+public:
+  /**
+   * @brief Create an initialized FontSpan.
+   *
+   * @param[in] familyName The font family name.
+   * @param[in] sizeInPoints The font size.
+   * @param[in] weight The font weight.
+   * @param[in] width The font width.
+   * @param[in] slant The font slant.
+   *
+   * @return A handle to a newly allocated Dali resource
+   */
+  static FontSpan New(const std::string                             familyName,
+                      const float                                   sizeInPoints,
+                      const Dali::TextAbstraction::FontWeight::Type weight,
+                      const Dali::TextAbstraction::FontWidth::Type  width,
+                      const Dali::TextAbstraction::FontSlant::Type  slant);
+
+  /**
+   * @brief Creates an uninitialized FontSpan handle.
+   *
+   * Calling member functions with an uninitialized FontSpan handle is not allowed.
+   */
+  FontSpan();
+
+  /**
+   * @brief Copy constructor.
+   * @param[in] rhs A reference to the copied handle
+   */
+  FontSpan(const FontSpan& rhs);
+
+  /**
+   * @brief Move constructor.
+   * @param[in] rhs A reference to the handle to move
+   */
+  FontSpan(FontSpan&& rhs);
+
+  /**
+   * @brief Assignment operator.
+   * @param[in] rhs A reference to the copied handle
+   * @return A reference to this
+   */
+  FontSpan& operator=(const FontSpan& rhs);
+
+  /**
+   * @brief Move assignment operator.
+   * @param[in] rhs A reference to the moved handle
+   * @return A reference to this
+   */
+  FontSpan& operator=(FontSpan&& rhs);
+
+  /**
+   * @brief Non virtual destructor.
+   */
+  ~FontSpan();
+
+  /**
+   * @brief Downcasts to a FontSpan handle.
+   * If handle is not a FontSpan, the returned handle is left uninitialized.
+   *
+   * @param[in] handle Handle to an object
+   * @return FontSpan handle or an uninitialized handle
+   */
+  static FontSpan DownCast(BaseHandle handle);
+
+public: //Methods
+  /**
+   * @brief Retrive the font family name.
+   *
+   * @return A family name value.
+   */
+  const std::string GetFamilyName() const;
+
+  /**
+   * @brief Retrive the font weight.
+   *
+   * @return A font weight value.
+   */
+  const Dali::TextAbstraction::FontWeight::Type GetWeight() const;
+
+  /**
+   * @brief Retrive the font width.
+   *
+   * @return A font width value.
+   */
+  const Dali::TextAbstraction::FontWidth::Type GetWidth() const;
+
+  /**
+   * @brief Retrive the font slant.
+   *
+   * @return A font slant value.
+   */
+  const Dali::TextAbstraction::FontSlant::Type GetSlant() const;
+
+  /**
+   * @brief Retrive the font size.
+   *
+   * @return A font size value.
+   */
+  const float GetSize() const;
+
+  /**
+   * @brief Retrieve whether the font family name is defined.
+   *
+   * @return The return is true if font family name is defined, otherwise false.
+   */
+  bool IsFamilyNameDefined() const;
+
+  /**
+   * @brief Retrieve whether the font weight is defined.
+   *
+   * @return The return is true if font weight is defined, otherwise false.
+   */
+  bool IsWeightDefined() const;
+
+  /**
+   * @brief Retrieve whether the font width is defined.
+   *
+   * @return The return is true if font width is defined, otherwise false.
+   */
+  bool IsWidthDefined() const;
+
+  /**
+   * @brief Retrieve whether the font slant is defined.
+   *
+   * @return The return is true if font slant is defined, otherwise false.
+   */
+  bool IsSlantDefined() const;
+
+  /**
+   * @brief Retrieve whether the font size is defined.
+   *
+   * @return The return is true if font size is defined, otherwise false.
+   */
+
+  bool IsSizeDefined() const;
+
+public: // Not intended for application developers
+  /// @cond internal
+  /**
+   * @brief This constructor is used internally to Create an initialized FontSpan handle.
+   *
+   * @param[in] fontSpan Pointer to internal FontSpan
+   */
+  explicit DALI_INTERNAL FontSpan(Internal::FontSpan* fontSpan);
+  /// @endcond
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_FONT_SPAN_H
index 698d8a4..96d2a53 100644 (file)
@@ -162,6 +162,7 @@ SET( toolkit_src_files
    ${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/spans/font-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
diff --git a/dali-toolkit/internal/text/spannable/spans/font-span-impl.cpp b/dali-toolkit/internal/text/spannable/spans/font-span-impl.cpp
new file mode 100644 (file)
index 0000000..f22d88a
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * 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/font-span-impl.h>
+
+// EXTERNAL INCLUDES
+#include <dali-toolkit/devel-api/text/spans/font-span.h>
+#include <memory.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/color-run.h>
+#include <dali-toolkit/internal/text/font-description-run.h>
+#include <dali-toolkit/internal/text/markup-tags-and-attributes.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace Internal
+{
+namespace
+{
+const float PIXEL_FORMAT_64_FACTOR = 64.f; ///< 64.f is used to convert from point size to 26.6 pixel format.
+}
+
+struct FontSpan::Impl
+{
+  std::string mFamilyName; ///< The font's family name.
+  Dali::TextAbstraction::FontWeight::Type mWeight;     ///< The font's weight.
+  Dali::TextAbstraction::FontWidth::Type  mWidth;      ///< The font's width.
+  Dali::TextAbstraction::FontSlant::Type  mSlant;      ///< The font's slant.
+  float       mSize;       ///< The font's size.
+
+  bool mFamilyNameDefined : 1; ///< Whether the font's family is defined.
+  bool mWeightDefined : 1;     ///< Whether the font's weight is defined.
+  bool mWidthDefined : 1;      ///< Whether the font's width is defined.
+  bool mSlantDefined : 1;      ///< Whether the font's slant is defined.
+  bool mSizeDefined : 1;       ///< Whether the font's size is defined.
+};
+
+FontSpan::FontSpan()
+: BaseSpan()
+{
+  mImpl = std::make_unique<Impl>();
+}
+
+FontSpan ::~FontSpan()
+{
+}
+
+Dali::Toolkit::Text::FontSpan FontSpan::New(const std::string&                             familyName,
+                                            const float&                                   sizeInPoints,
+                                            const Dali::TextAbstraction::FontWeight::Type& weight,
+                                            const Dali::TextAbstraction::FontWidth::Type&  width,
+                                            const Dali::TextAbstraction::FontSlant::Type&  slant)
+{
+  FontSpanPtr object = new FontSpan();
+  object->SetFamilyName(familyName);
+  object->SetSize(sizeInPoints);
+  object->SetWeight(weight);
+  object->SetWidth(width);
+  object->SetSlant(slant);
+
+  Dali::Toolkit::Text::FontSpan handle = Dali::Toolkit::Text::FontSpan(object.Get());
+
+  return handle;
+}
+
+//Methods
+const std::string FontSpan::GetFamilyName() const
+{
+  return mImpl->mFamilyName;
+}
+
+bool FontSpan::IsFamilyNameDefined() const
+{
+  return mImpl->mFamilyNameDefined;
+}
+
+void FontSpan::SetFamilyName(const std::string& familyName)
+{
+  mImpl->mFamilyName        = familyName;
+  mImpl->mFamilyNameDefined = true;
+}
+
+const Dali::TextAbstraction::FontWeight::Type FontSpan::GetWeight() const
+{
+  return mImpl->mWeight;
+}
+
+bool FontSpan::IsWeightDefined() const
+{
+  return mImpl->mWeightDefined;
+}
+
+void FontSpan::SetWeight(const Dali::TextAbstraction::FontWeight::Type& weight)
+{
+  mImpl->mWeight        = weight;
+  mImpl->mWeightDefined = true;
+}
+
+const Dali::TextAbstraction::FontWidth::Type FontSpan::GetWidth() const
+{
+  return mImpl->mWidth;
+}
+
+bool FontSpan::IsWidthDefined() const
+{
+  return mImpl->mWidthDefined;
+}
+
+void FontSpan::SetWidth(const Dali::TextAbstraction::FontWidth::Type& width)
+{
+  mImpl->mWidth        = width;
+  mImpl->mWidthDefined = true;
+}
+
+const Dali::TextAbstraction::FontSlant::Type FontSpan::GetSlant() const
+{
+  return mImpl->mSlant;
+}
+
+bool FontSpan::IsSlantDefined() const
+{
+  return mImpl->mSlantDefined;
+}
+
+void FontSpan::SetSlant(const Dali::TextAbstraction::FontSlant::Type& slant)
+{
+  mImpl->mSlant        = slant;
+  mImpl->mSlantDefined = true;
+}
+
+const float FontSpan::GetSize() const
+{
+  return mImpl->mSize;
+}
+
+bool FontSpan::IsSizeDefined() const
+{
+  return mImpl->mSizeDefined;
+}
+
+void FontSpan::SetSize(const float& size)
+{
+  mImpl->mSize        = size;
+  mImpl->mSizeDefined = true;
+}
+
+void FontSpan::CreateStyleCharacterRun(IntrusivePtr<LogicalModel>& logicalModel, const Dali::Toolkit::Text::Range& range) const
+{
+  FontDescriptionRun fontRun;
+  fontRun.characterRun.characterIndex     = range.GetStartIndex();
+  fontRun.characterRun.numberOfCharacters = range.GetNumberOfIndices();
+
+  InitializeFontRun(fontRun);
+  ProcessFontFamily(fontRun);
+  ProcessFontSize(fontRun);
+  ProcessFontWeight(fontRun);
+  ProcessFontWidth(fontRun);
+  ProcessFontSlant(fontRun);
+
+  logicalModel->mFontDescriptionRuns.PushBack(fontRun);
+}
+
+void FontSpan::InitializeFontRun(FontDescriptionRun& fontRun) const
+{
+  fontRun.familyName   = NULL;
+  fontRun.familyLength = 0u;
+  fontRun.weight       = TextAbstraction::FontWeight::NORMAL;
+  fontRun.width        = TextAbstraction::FontWidth::NORMAL;
+  fontRun.slant        = TextAbstraction::FontSlant::NORMAL;
+  fontRun.size         = 0u;
+
+  fontRun.familyDefined = false;
+  fontRun.weightDefined = false;
+  fontRun.widthDefined  = false;
+  fontRun.slantDefined  = false;
+  fontRun.sizeDefined   = false;
+}
+
+void FontSpan::ProcessFontFamily(FontDescriptionRun& fontRun) const
+{
+  if(IsFamilyNameDefined())
+  {
+    const std::string& familyName = GetFamilyName();
+    fontRun.familyDefined         = true;
+    fontRun.familyLength          = familyName.length();
+    fontRun.familyName            = new char[fontRun.familyLength];
+    memcpy(fontRun.familyName, familyName.c_str(), fontRun.familyLength);
+    // The memory is freed when the font run is removed from the logical model.
+  }
+}
+
+void FontSpan::ProcessFontSize(FontDescriptionRun& fontRun) const
+{
+  if(IsSizeDefined())
+  {
+    // 64.f is used to convert from point size to 26.6 pixel format.
+    fontRun.size        = static_cast<PointSize26Dot6>(GetSize() * PIXEL_FORMAT_64_FACTOR);
+    fontRun.sizeDefined = true;
+  }
+}
+
+void FontSpan::ProcessFontWeight(FontDescriptionRun& fontRun) const
+{
+  if(IsWeightDefined())
+  {
+    fontRun.weight        = GetWeight();
+    fontRun.weightDefined = true;
+  }
+}
+
+void FontSpan::ProcessFontWidth(FontDescriptionRun& fontRun) const
+{
+  if(IsWidthDefined())
+  {
+    fontRun.width        = GetWidth();
+    fontRun.widthDefined = true;
+  }
+}
+
+void FontSpan::ProcessFontSlant(FontDescriptionRun& fontRun) const
+{
+  if(IsSlantDefined())
+  {
+    fontRun.slant        = GetSlant();
+    fontRun.slantDefined = true;
+  }
+}
+
+} // namespace Internal
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/text/spannable/spans/font-span-impl.h b/dali-toolkit/internal/text/spannable/spans/font-span-impl.h
new file mode 100644 (file)
index 0000000..30306cd
--- /dev/null
@@ -0,0 +1,209 @@
+#ifndef DALI_TOOLKIT_INTERNAL_TEXT_FONT_SPAN_IMPL_H
+#define DALI_TOOLKIT_INTERNAL_TEXT_FONT_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/font-span.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/logical-model-impl.h>
+#include <dali-toolkit/internal/text/spannable/spans/base-span-impl.h>
+#include <dali-toolkit/internal/text/text-definitions.h>
+#include <dali/public-api/math/vector4.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace Internal
+{
+class FontSpan;
+using FontSpanPtr = IntrusivePtr<FontSpan>;
+
+/**
+ * @copydoc Dali::Toolkit::Text::FontSpan
+ */
+class FontSpan : public BaseSpan
+{
+public:
+  /**
+   * @brief Creates a new FontSpan object.
+   */
+  static Dali::Toolkit::Text::FontSpan New(const std::string&                             familyName,
+                                           const float&                                   sizeInPoints,
+                                           const Dali::TextAbstraction::FontWeight::Type& weight,
+                                           const Dali::TextAbstraction::FontWidth::Type&  width,
+                                           const Dali::TextAbstraction::FontSlant::Type&  slant);
+
+  /**
+   * Default Constructor
+   */
+  FontSpan();
+
+  FontSpan(const FontSpan&) = delete;            ///< Deleted copy constructor
+  FontSpan(FontSpan&&)      = delete;            ///< Deleted move constructor
+  FontSpan& operator=(const FontSpan&) = delete; ///< Deleted copy assignment operator
+  FontSpan& operator=(FontSpan&&) = delete;      ///< Deleted move assignment operator
+
+  /**
+   * @brief Destructor
+   *
+   * A reference counted object may only be deleted by calling Unreference()
+   */
+  ~FontSpan() override;
+
+public: //Methods
+public: //Methods
+  /**
+   * @copydoc Dali::Toolkit::Text::FontSpan::GetFamilyName()
+   */
+  const std::string GetFamilyName() const;
+
+  /**
+   * @copydoc Dali::Toolkit::Text::FontSpan::IsFamilyNameDefined()
+   */
+  bool IsFamilyNameDefined() const;
+
+  /**
+   * @copydoc Dali::Toolkit::Text::FontSpan::GetWeight()
+   */
+  const Dali::TextAbstraction::FontWeight::Type GetWeight() const;
+
+  /**
+   * @copydoc Dali::Toolkit::Text::FontSpan::IsWeightDefined()
+   */
+  bool IsWeightDefined() const;
+
+  /**
+   * @copydoc Dali::Toolkit::Text::FontSpan::GetWidth()
+   */
+  const Dali::TextAbstraction::FontWidth::Type GetWidth() const;
+
+  /**
+   * @copydoc Dali::Toolkit::Text::FontSpan::IsWidthDefined()
+   */
+  bool IsWidthDefined() const;
+
+  /**
+   * @copydoc Dali::Toolkit::Text::FontSpan::GetSlant()
+   */
+  const Dali::TextAbstraction::FontSlant::Type GetSlant() const;
+
+  /**
+   * @copydoc Dali::Toolkit::Text::FontSpan::IsSlantDefined()
+   */
+  bool IsSlantDefined() const;
+
+  /**
+   * @copydoc Dali::Toolkit::Text::FontSpan::GetSize()
+   */
+  const float GetSize() const;
+
+  /**
+   * @copydoc Dali::Toolkit::Text::FontSpan::IsSizeDefined()
+   */
+  bool IsSizeDefined() const;
+
+public: //Methods. Not intended for application developers
+  /**
+   * @brief Set the font family name.
+   *
+   * @param[in] familyName The font family name.
+   */
+  void SetFamilyName(const std::string& familyName);
+
+  /**
+   * @brief Set the font weight.
+   *
+   * @param[in] weight The font weight.
+   */
+  void SetWeight(const Dali::TextAbstraction::FontWeight::Type& weight);
+
+  /**
+   * @brief Set the font width.
+   *
+   * @param[in] width The font width.
+   */
+  void SetWidth(const Dali::TextAbstraction::FontWidth::Type& width);
+
+  /**
+   * @brief Set the font slant.
+   *
+   * @param[in] slant The font slant.
+   */
+  void SetSlant(const Dali::TextAbstraction::FontSlant::Type& slant);
+
+  /**
+   * @brief Set the font size.
+   *
+   * @param[in] size The font size.
+   */
+  void SetSize(const float& size);
+
+private: //Methods
+  void InitializeFontRun(FontDescriptionRun& fontRun) const;
+  void ProcessFontFamily(FontDescriptionRun& fontRun) const;
+  void ProcessFontSize(FontDescriptionRun& fontRun) const;
+  void ProcessFontWeight(FontDescriptionRun& fontRun) const;
+  void ProcessFontWidth(FontDescriptionRun& fontRun) const;
+  void ProcessFontSlant(FontDescriptionRun& fontRun) const;
+
+public: //Methods for internal only
+        /**
+   * @copydoc Dali::Toolkit::Text::BaseSpan::CreateStyleCharacterRun
+   */
+  void CreateStyleCharacterRun(IntrusivePtr<LogicalModel>& logicalModel, const Dali::Toolkit::Text::Range& range) const override;
+
+private:
+  struct Impl;
+  std::unique_ptr<Impl> mImpl{nullptr};
+
+}; // class FontSpan
+
+} // namespace Internal
+
+// Helpers for public-api forwarding methods
+
+inline Internal::FontSpan& GetImplementation(Dali::Toolkit::Text::FontSpan& fontSpan)
+{
+  DALI_ASSERT_ALWAYS(fontSpan && "fontSpan handle is empty");
+
+  BaseObject& object = fontSpan.GetBaseObject();
+
+  return static_cast<Internal::FontSpan&>(object);
+}
+
+inline const Internal::FontSpan& GetImplementation(const Dali::Toolkit::Text::FontSpan& fontSpan)
+{
+  DALI_ASSERT_ALWAYS(fontSpan && "fontSpan handle is empty");
+
+  const BaseObject& object = fontSpan.GetBaseObject();
+
+  return static_cast<const Internal::FontSpan&>(object);
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_INTERNAL_TEXT_FONT_SPAN_IMPL_H
\ No newline at end of file