Introduce FONT_VARIATIONS property 53/315453/27
authorANZ1217 <chihun.jeong@samsung.com>
Mon, 25 Nov 2024 04:59:12 +0000 (13:59 +0900)
committerANZ1217 <chihun.jeong@samsung.com>
Mon, 24 Mar 2025 05:58:45 +0000 (14:58 +0900)
Change-Id: Ib302c44c0856eda39a954255a84fa625e79ee048

29 files changed:
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-text-abstraction.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp
dali-toolkit/devel-api/controls/text-controls/text-editor-devel.cpp
dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h
dali-toolkit/devel-api/controls/text-controls/text-field-devel.cpp
dali-toolkit/devel-api/controls/text-controls/text-field-devel.h
dali-toolkit/devel-api/controls/text-controls/text-label-devel.cpp
dali-toolkit/devel-api/controls/text-controls/text-label-devel.h
dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp
dali-toolkit/internal/controls/text-controls/text-editor-impl.h
dali-toolkit/internal/controls/text-controls/text-editor-property-handler.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.h
dali-toolkit/internal/controls/text-controls/text-field-property-handler.cpp
dali-toolkit/internal/controls/text-controls/text-label-impl.cpp
dali-toolkit/internal/controls/text-controls/text-label-impl.h
dali-toolkit/internal/text/async-text/async-text-loader-impl.cpp
dali-toolkit/internal/text/controller/text-controller-impl-model-updater.cpp
dali-toolkit/internal/text/controller/text-controller.cpp
dali-toolkit/internal/text/controller/text-controller.h
dali-toolkit/internal/text/logical-model-impl.h
dali-toolkit/internal/text/multi-language-support-impl.cpp
dali-toolkit/internal/text/multi-language-support-impl.h
dali-toolkit/internal/text/multi-language-support.cpp
dali-toolkit/internal/text/multi-language-support.h
dali-toolkit/internal/text/shaper.cpp
dali-toolkit/internal/text/shaper.h

index e9a12120f1db764ca109aff924abe1cbd910a33d..84a46ea1581ade0f7514b6bf72442f16de81bcf7 100644 (file)
@@ -173,7 +173,7 @@ public:
   {
     return 0;
   }
-  FontId GetFontId(const FontDescription& fontDescription, PointSize26Dot6 pointSize, FaceIndex faceIndex)
+  FontId GetFontId(const FontDescription& fontDescription, PointSize26Dot6 pointSize, FaceIndex faceIndex, Property::Map* variationsMapPtr)
   {
     return 0;
   }
@@ -277,7 +277,7 @@ public:
     }
   }
 
-  Length Shape(TextAbstraction::FontClient& fontClient, unsigned int const* text, unsigned int numChars, unsigned int fontId, Script script)
+  Length Shape(TextAbstraction::FontClient& fontClient, unsigned int const* text, unsigned int numChars, unsigned int fontId, Script script, Property::Map* variationsMapPtr)
   {
     mText     = new unsigned char[numChars];
     mNumChars = numChars;
@@ -477,11 +477,13 @@ FontId FontClient::GetFontId(const FontPath& path, PointSize26Dot6 pointSize, Fa
 
 FontId FontClient::GetFontId(const FontDescription& fontDescription,
                              PointSize26Dot6        pointSize,
-                             FaceIndex              faceIndex)
+                             FaceIndex              faceIndex,
+                             Property::Map*         variationsMapPtr)
 {
   return GetImplementation(*this).GetFontId(fontDescription,
                                             pointSize,
-                                            faceIndex);
+                                            faceIndex,
+                                            variationsMapPtr);
 }
 
 bool FontClient::IsScalable(const FontPath& path)
@@ -640,9 +642,9 @@ void Shaping::GetGlyphs(GlyphInfo* glyphStore, unsigned int* mappingTable)
   GetImplementation(*this).GetGlyphs(glyphStore, mappingTable);
 }
 
-Length Shaping::Shape(TextAbstraction::FontClient& fontClient, unsigned int const* text, unsigned int numChars, unsigned int fontId, Script script)
+Length Shaping::Shape(TextAbstraction::FontClient& fontClient, unsigned int const* text, unsigned int numChars, unsigned int fontId, Script script, Property::Map* variationsMapPtr)
 {
-  return GetImplementation(*this).Shape(fontClient, text, numChars, fontId, script);
+  return GetImplementation(*this).Shape(fontClient, text, numChars, fontId, script, variationsMapPtr);
 }
 
 } // namespace TextAbstraction
index d83c506e90acec768f2ded426559a3d45eb2d872..633c651313dc3e8b188dd99c24a30e3741f3a478 100644 (file)
@@ -119,6 +119,7 @@ const char* const PROPERTY_NAME_INPUT_FILTER                    = "inputFilter";
 
 const char* const PROPERTY_NAME_REMOVE_FRONT_INSET    = "removeFrontInset";
 const char* const PROPERTY_NAME_REMOVE_BACK_INSET     = "removeBackInset";
+const char* const PROPERTY_NAME_FONT_VARIATIONS       = "fontVariations";
 
 const Vector4       PLACEHOLDER_TEXT_COLOR(0.8f, 0.8f, 0.8f, 0.8f);
 const Dali::Vector4 LIGHT_BLUE(0.75f, 0.96f, 1.f, 1.f); // The text highlight color.
@@ -639,6 +640,7 @@ int UtcDaliTextEditorGetPropertyP(void)
   DALI_TEST_CHECK(editor.GetPropertyIndex(PROPERTY_NAME_SELECTION_POPUP_STYLE) == DevelTextEditor::Property::SELECTION_POPUP_STYLE);
   DALI_TEST_CHECK(editor.GetPropertyIndex(PROPERTY_NAME_REMOVE_FRONT_INSET) == DevelTextEditor::Property::REMOVE_FRONT_INSET);
   DALI_TEST_CHECK(editor.GetPropertyIndex(PROPERTY_NAME_REMOVE_BACK_INSET) == DevelTextEditor::Property::REMOVE_BACK_INSET);
+  DALI_TEST_CHECK(editor.GetPropertyIndex(PROPERTY_NAME_FONT_VARIATIONS) == DevelTextEditor::Property::FONT_VARIATIONS);
 
   END_TEST;
 }
@@ -1281,6 +1283,31 @@ int UtcDaliTextEditorSetPropertyP(void)
   editor.SetProperty(DevelTextEditor::Property::REMOVE_BACK_INSET, true);
   DALI_TEST_CHECK(editor.GetProperty<bool>(DevelTextEditor::Property::REMOVE_BACK_INSET));
 
+  // Check font variations property
+  Property::Map fontVariationsMapSet;
+  Property::Map fontVariationsMapGet;
+
+  fontVariationsMapSet.Insert("wght", 400.f);
+  fontVariationsMapSet.Insert("wdth", 100.f);
+  fontVariationsMapSet.Insert("slnt", 0.f);
+  editor.SetProperty(DevelTextEditor::Property::FONT_VARIATIONS, fontVariationsMapSet);
+
+  fontVariationsMapGet = editor.GetProperty<Property::Map>(DevelTextEditor::Property::FONT_VARIATIONS);
+  DALI_TEST_EQUALS(fontVariationsMapSet.Count(), fontVariationsMapGet.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS(DaliTestCheckMaps(fontVariationsMapSet, fontVariationsMapGet), true, TEST_LOCATION);
+
+  // Check font variations ignore invalid values
+  Property::Map invalidFontVariationsMapSet;
+  Property::Map invalidFontVariationsMapGet;
+
+  invalidFontVariationsMapSet.Insert("abcde", 0.f);    // invalid because key length is not 4.
+  invalidFontVariationsMapSet.Insert("abc", 0.f);     // invalid because key length is not 4.
+  invalidFontVariationsMapSet.Insert("abcd", "str");  // invalid because value is not float.
+  editor.SetProperty(DevelTextEditor::Property::FONT_VARIATIONS, invalidFontVariationsMapSet);
+
+  invalidFontVariationsMapGet = editor.GetProperty<Property::Map>(DevelTextEditor::Property::FONT_VARIATIONS);
+  DALI_TEST_EQUALS(invalidFontVariationsMapGet.Count(), 0u, TEST_LOCATION);
+
   application.SendNotification();
   application.Render();
 
@@ -6761,6 +6788,7 @@ int utcDaliTextEditorRemoveFrontInset(void)
 
   END_TEST;
 }
+
 int utcDaliTextEditorRemoveBackInset(void)
 {
   ToolkitTestApplication application;
@@ -6778,3 +6806,70 @@ int utcDaliTextEditorRemoveBackInset(void)
 
   END_TEST;
 }
+
+int utcDaliTextEditorFontVariationsRegister(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" utcDaliTextEditorFontVariationsRegister");
+
+  TextEditor editor = TextEditor::New();
+  DALI_TEST_CHECK(editor);
+
+  application.GetScene().Add(editor);
+  application.SendNotification();
+  application.Render();
+
+  // Invalid key check
+  std::string INVALID_KEY = "invalid";
+  auto invalidFontVariationsIndex = DevelTextEditor::RegisterFontVariationProperty(editor, INVALID_KEY.data());
+  DALI_TEST_CHECK(invalidFontVariationsIndex == Property::INVALID_INDEX);
+
+  application.GetScene().Add(editor);
+  application.SendNotification();
+  application.Render();
+
+  std::string WGHT_KEY = "wght";
+  const float WGHT_VALUE = 100.f;
+  const float WGHT_VALUE_END = 900.f;
+
+  // Check with no previous variations.
+  auto fontVariationsIndex = DevelTextEditor::RegisterFontVariationProperty(editor, WGHT_KEY.data());
+  editor.SetProperty(fontVariationsIndex, WGHT_VALUE);
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK(editor.GetProperty(fontVariationsIndex).Get<float>() == WGHT_VALUE);
+
+  Property::Map fontVariationsGet;
+  fontVariationsGet = editor.GetProperty<Property::Map>(DevelTextEditor::Property::FONT_VARIATIONS);
+
+  DALI_TEST_CHECK(fontVariationsGet.Count() == 1u);
+
+  const KeyValuePair& keyvalue = fontVariationsGet.GetKeyValue(0);
+
+  std::string key = "";
+  if(keyvalue.first.type == Property::Key::STRING)
+  {
+    key = keyvalue.first.stringKey;
+  }
+
+  float value = keyvalue.second.Get<float>();
+
+  DALI_TEST_CHECK(key == WGHT_KEY);
+  DALI_TEST_CHECK(value = WGHT_VALUE);
+
+  application.SendNotification();
+  application.Render();
+
+  // Animation test
+
+  Animation anim = Animation::New(1);
+  anim.AnimateTo(Property(editor, fontVariationsIndex), WGHT_VALUE_END);
+  anim.Play();
+
+  application.SendNotification();
+  application.Render();
+
+  END_TEST;
+}
\ No newline at end of file
index dc304d7db5e0cf96e63680ad10567162630e2b58..bd69725cbb9d734267ed8e62bd140ceaa566f591 100644 (file)
@@ -117,6 +117,7 @@ const char* const PROPERTY_NAME_INPUT_FILTER                    = "inputFilter";
 
 const char* const PROPERTY_NAME_REMOVE_FRONT_INSET    = "removeFrontInset";
 const char* const PROPERTY_NAME_REMOVE_BACK_INSET     = "removeBackInset";
+const char* const PROPERTY_NAME_FONT_VARIATIONS       = "fontVariations";
 
 const Vector4       PLACEHOLDER_TEXT_COLOR(0.8f, 0.8f, 0.8f, 0.8f);
 const Dali::Vector4 LIGHT_BLUE(0.75f, 0.96f, 1.f, 1.f); // The text highlight color.
@@ -648,6 +649,7 @@ int UtcDaliTextFieldGetPropertyP(void)
   DALI_TEST_CHECK(field.GetPropertyIndex(PROPERTY_NAME_SELECTION_POPUP_STYLE) == DevelTextField::Property::SELECTION_POPUP_STYLE);
   DALI_TEST_CHECK(field.GetPropertyIndex(PROPERTY_NAME_REMOVE_FRONT_INSET) == DevelTextField::Property::REMOVE_FRONT_INSET);
   DALI_TEST_CHECK(field.GetPropertyIndex(PROPERTY_NAME_REMOVE_BACK_INSET) == DevelTextField::Property::REMOVE_BACK_INSET);
+  DALI_TEST_CHECK(field.GetPropertyIndex(PROPERTY_NAME_FONT_VARIATIONS) == DevelTextField::Property::FONT_VARIATIONS);
 
   END_TEST;
 }
@@ -1286,6 +1288,30 @@ int UtcDaliTextFieldSetPropertyP(void)
   application.SendNotification();
   application.Render();
 
+  // Check font variations property
+  Property::Map fontVariationsMapSet;
+  Property::Map fontVariationsMapGet;
+
+  fontVariationsMapSet.Insert("wght", 400.f);
+  fontVariationsMapSet.Insert("wdth", 100.f);
+  fontVariationsMapSet.Insert("slnt", 0.f);
+  field.SetProperty(DevelTextField::Property::FONT_VARIATIONS, fontVariationsMapSet);
+
+  fontVariationsMapGet = field.GetProperty<Property::Map>(DevelTextField::Property::FONT_VARIATIONS);
+  DALI_TEST_EQUALS(fontVariationsMapSet.Count(), fontVariationsMapGet.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS(DaliTestCheckMaps(fontVariationsMapSet, fontVariationsMapGet), true, TEST_LOCATION);
+
+  // Check font variations ignore invalid values
+  Property::Map invalidFontVariationsMapSet;
+  Property::Map invalidFontVariationsMapGet;
+
+  invalidFontVariationsMapSet.Insert("abcde", 0.f);    // invalid because key length is not 4.
+  invalidFontVariationsMapSet.Insert("abc", 0.f);     // invalid because key length is not 4.
+  invalidFontVariationsMapSet.Insert("abcd", "str");  // invalid because value is not float.
+  field.SetProperty(DevelTextField::Property::FONT_VARIATIONS, invalidFontVariationsMapSet);
+
+  invalidFontVariationsMapGet = field.GetProperty<Property::Map>(DevelTextField::Property::FONT_VARIATIONS);
+  DALI_TEST_EQUALS(invalidFontVariationsMapGet.Count(), 0u, TEST_LOCATION);
 
   END_TEST;
 }
@@ -6242,3 +6268,70 @@ int utcDaliTextFieldRemoveBackInset(void)
 
   END_TEST;
 }
+
+int utcDaliTextFieldFontVariationsRegister(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" utcDaliTextFieldFontVariationsRegister");
+
+  TextField field = TextField::New();
+  DALI_TEST_CHECK(field);
+
+  application.GetScene().Add(field);
+  application.SendNotification();
+  application.Render();
+
+  // Invalid key check
+  std::string INVALID_KEY = "invalid";
+  auto invalidFontVariationsIndex = DevelTextField::RegisterFontVariationProperty(field, INVALID_KEY.data());
+  DALI_TEST_CHECK(invalidFontVariationsIndex == Property::INVALID_INDEX);
+
+  application.GetScene().Add(field);
+  application.SendNotification();
+  application.Render();
+
+  std::string WGHT_KEY = "wght";
+  const float WGHT_VALUE = 100.f;
+  const float WGHT_VALUE_END = 900.f;
+
+  // Check with no previous variations.
+  auto fontVariationsIndex = DevelTextField::RegisterFontVariationProperty(field, WGHT_KEY.data());
+  field.SetProperty(fontVariationsIndex, WGHT_VALUE);
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK(field.GetProperty(fontVariationsIndex).Get<float>() == WGHT_VALUE);
+
+  Property::Map fontVariationsGet;
+  fontVariationsGet = field.GetProperty<Property::Map>(DevelTextField::Property::FONT_VARIATIONS);
+
+  DALI_TEST_CHECK(fontVariationsGet.Count() == 1u);
+
+  const KeyValuePair& keyvalue = fontVariationsGet.GetKeyValue(0);
+
+  std::string key = "";
+  if(keyvalue.first.type == Property::Key::STRING)
+  {
+    key = keyvalue.first.stringKey;
+  }
+
+  float value = keyvalue.second.Get<float>();
+
+  DALI_TEST_CHECK(key == WGHT_KEY);
+  DALI_TEST_CHECK(value = WGHT_VALUE);
+
+  application.SendNotification();
+  application.Render();
+
+  // Animation test
+
+  Animation anim = Animation::New(1);
+  anim.AnimateTo(Property(field, fontVariationsIndex), WGHT_VALUE_END);
+  anim.Play();
+
+  application.SendNotification();
+  application.Render();
+
+  END_TEST;
+}
\ No newline at end of file
index a86a790e1105bd07c8095a715e05b7ad37166862..772a63743cb2ec584767235961015a2879143d6a 100644 (file)
@@ -88,6 +88,7 @@ const char* const PROPERTY_NAME_RENDER_MODE           = "renderMode";
 const char* const PROPERTY_NAME_MANUAL_RENDERED       = "manualRendered";
 const char* const PROPERTY_NAME_ASYNC_LINE_COUNT      = "asyncLineCount";
 const char* const PROPERTY_NAME_ELLIPSIS_MODE         = "ellipsisMode";
+const char* const PROPERTY_NAME_FONT_VARIATIONS       = "fontVariations";
 
 const std::string  DEFAULT_FONT_DIR("/resources/fonts");
 const unsigned int EMOJI_FONT_SIZE = 3840u; // 60 * 64
@@ -376,6 +377,7 @@ int UtcDaliToolkitTextLabelGetPropertyP(void)
   DALI_TEST_CHECK(label.GetPropertyIndex(PROPERTY_NAME_MANUAL_RENDERED) == DevelTextLabel::Property::MANUAL_RENDERED);
   DALI_TEST_CHECK(label.GetPropertyIndex(PROPERTY_NAME_ASYNC_LINE_COUNT) == DevelTextLabel::Property::ASYNC_LINE_COUNT);
   DALI_TEST_CHECK(label.GetPropertyIndex(PROPERTY_NAME_ELLIPSIS_MODE) == DevelTextLabel::Property::ELLIPSIS_MODE);
+  DALI_TEST_CHECK(label.GetPropertyIndex(PROPERTY_NAME_FONT_VARIATIONS) == DevelTextLabel::Property::FONT_VARIATIONS);
 
   END_TEST;
 }
@@ -1081,6 +1083,31 @@ int UtcDaliToolkitTextLabelSetPropertyP(void)
   label.SetProperty(DevelTextLabel::Property::ELLIPSIS_MODE, Toolkit::DevelText::Ellipsize::AUTO_SCROLL);
   DALI_TEST_EQUALS(label.GetProperty<int>(DevelTextLabel::Property::ELLIPSIS_MODE), static_cast<int>(Toolkit::DevelText::Ellipsize::AUTO_SCROLL), TEST_LOCATION);
 
+  // Check font variations property
+  Property::Map fontVariationsMapSet;
+  Property::Map fontVariationsMapGet;
+
+  fontVariationsMapSet.Insert("wght", 400.f);
+  fontVariationsMapSet.Insert("wdth", 100.f);
+  fontVariationsMapSet.Insert("slnt", 0.f);
+  label.SetProperty(DevelTextLabel::Property::FONT_VARIATIONS, fontVariationsMapSet);
+
+  fontVariationsMapGet = label.GetProperty<Property::Map>(DevelTextLabel::Property::FONT_VARIATIONS);
+  DALI_TEST_EQUALS(fontVariationsMapSet.Count(), fontVariationsMapGet.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS(DaliTestCheckMaps(fontVariationsMapSet, fontVariationsMapGet), true, TEST_LOCATION);
+
+  // Check font variations ignore invalid values
+  Property::Map invalidFontVariationsMapSet;
+  Property::Map invalidFontVariationsMapGet;
+
+  invalidFontVariationsMapSet.Insert("abcde", 0.f);    // invalid because key length is not 4.
+  invalidFontVariationsMapSet.Insert("abc", 0.f);     // invalid because key length is not 4.
+  invalidFontVariationsMapSet.Insert("abcd", "str");  // invalid because value is not float.
+  label.SetProperty(DevelTextLabel::Property::FONT_VARIATIONS, invalidFontVariationsMapSet);
+
+  invalidFontVariationsMapGet = label.GetProperty<Property::Map>(DevelTextLabel::Property::FONT_VARIATIONS);
+  DALI_TEST_EQUALS(invalidFontVariationsMapGet.Count(), 0u, TEST_LOCATION);
+
   application.SendNotification();
   application.Render();
 
@@ -3526,5 +3553,72 @@ int utcDaliTextLabelRemoveBackInset(void)
   DevelTextLabel::SetRemoveBackInset(label, true);
   DALI_TEST_CHECK(DevelTextLabel::IsRemoveBackInset(label));
 
+  END_TEST;
+}
+
+int utcDaliTextLabelFontVariationsRegister(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" utcDaliTextLabelFontVariationsRegister");
+
+  TextLabel label = TextLabel::New();
+  DALI_TEST_CHECK(label);
+
+  application.GetScene().Add(label);
+  application.SendNotification();
+  application.Render();
+
+  // Invalid key check
+  std::string INVALID_KEY = "invalid";
+  auto invalidFontVariationsIndex = DevelTextLabel::RegisterFontVariationProperty(label, INVALID_KEY.data());
+  DALI_TEST_CHECK(invalidFontVariationsIndex == Property::INVALID_INDEX);
+
+  application.GetScene().Add(label);
+  application.SendNotification();
+  application.Render();
+
+  std::string WGHT_KEY = "wght";
+  const float WGHT_VALUE = 100.f;
+  const float WGHT_VALUE_END = 900.f;
+
+  // Check with no previous variations.
+  auto fontVariationsIndex = DevelTextLabel::RegisterFontVariationProperty(label, WGHT_KEY.data());
+  label.SetProperty(fontVariationsIndex, WGHT_VALUE);
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK(label.GetProperty(fontVariationsIndex).Get<float>() == WGHT_VALUE);
+
+  Property::Map fontVariationsGet;
+  fontVariationsGet = label.GetProperty<Property::Map>(DevelTextLabel::Property::FONT_VARIATIONS);
+
+  DALI_TEST_CHECK(fontVariationsGet.Count() == 1u);
+
+  const KeyValuePair& keyvalue = fontVariationsGet.GetKeyValue(0);
+
+  std::string key = "";
+  if(keyvalue.first.type == Property::Key::STRING)
+  {
+    key = keyvalue.first.stringKey;
+  }
+
+  float value = keyvalue.second.Get<float>();
+
+  DALI_TEST_CHECK(key == WGHT_KEY);
+  DALI_TEST_CHECK(value = WGHT_VALUE);
+
+  application.SendNotification();
+  application.Render();
+
+  // Animation test
+
+  Animation anim = Animation::New(1);
+  anim.AnimateTo(Property(label, fontVariationsIndex), WGHT_VALUE_END);
+  anim.Play();
+
+  application.SendNotification();
+  application.Render();
+
   END_TEST;
 }
\ No newline at end of file
index 84a80b7326014251951bd2bbdf97b0eab7b39550..ce3241ee6d54aa7152670074f5d74de875b0ed8c 100644 (file)
@@ -135,6 +135,11 @@ bool IsRemoveBackInset(TextEditor textEditor)
   return GetImpl(textEditor).IsRemoveBackInset();
 }
 
+Dali::Property::Index RegisterFontVariationProperty(TextEditor textEditor, std::string tag)
+{
+  return GetImpl(textEditor).RegisterFontVariationProperty(tag);
+}
+
 } // namespace DevelTextEditor
 
 } // namespace Toolkit
index 183132799140fe40aa32ae648a7210531d07e8cf..ad7b19aaca6f36c434bf1f9402126e3e528bc308 100644 (file)
@@ -19,6 +19,7 @@
  */
 // EXTERNAL INCLUDES
 #include <dali/devel-api/adaptor-framework/input-method-context.h>
+#include <dali/public-api/object/property.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/text-controls/input-filter-properties.h>
@@ -337,6 +338,13 @@ enum Type
    * @details Name "removeBackInset", type Property::BOOLEAN.
    */
   REMOVE_BACK_INSET,
+
+  /**
+   * @brief Enables customization of fonts with variations such as weight and slant.
+   * @details Name "fontVariations", type Property::MAP.
+   * @note This property can be used only when using variable fonts.
+   */
+  FONT_VARIATIONS,
 };
 
 } // namespace Property
@@ -619,6 +627,15 @@ DALI_TOOLKIT_API void SetRemoveBackInset(TextEditor textEditor, const bool remov
  */
 DALI_TOOLKIT_API bool IsRemoveBackInset(TextEditor textEditor);
 
+/**
+ * @brief Registers a new font variation property based on the provided tag.
+ *
+ * @param[in] textEditor The instance of TextEditor.
+ * @param[in] tag A 4-character string representing the variation property tag.
+ * @return The index of the registered variation property. Property::INVALID_INDEX if failed.
+ */
+DALI_TOOLKIT_API Dali::Property::Index RegisterFontVariationProperty(TextEditor textEditor, std::string tag);
+
 
 } // namespace DevelTextEditor
 
index 7f19475a2ca293ece54656416f73178725eb053c..1c3f2beb36ca12fffd66198c8b4338a9e8892992 100644 (file)
@@ -125,6 +125,11 @@ bool IsRemoveBackInset(TextField textField)
   return GetImpl(textField).IsRemoveBackInset();
 }
 
+Dali::Property::Index RegisterFontVariationProperty(TextField textField, std::string tag)
+{
+  return GetImpl(textField).RegisterFontVariationProperty(tag);
+}
+
 } // namespace DevelTextField
 
 } // namespace Toolkit
index 8d368eec78a66e2b401eda349992b2db2a91c8a3..c15f333a64285663c8f0088bb90af618e9f4d7b7 100644 (file)
@@ -19,6 +19,7 @@
  */
 // EXTERNAL INCLUDES
 #include <dali/devel-api/adaptor-framework/input-method-context.h>
+#include <dali/public-api/object/property.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/text-controls/input-filter-properties.h>
@@ -261,6 +262,13 @@ enum
    * @details Name "removeBackInset", type Property::BOOLEAN.
    */
   REMOVE_BACK_INSET,
+
+  /**
+   * @brief Enables customization of fonts with variations such as weight and slant.
+   * @details Name "fontVariations", type Property::MAP.
+   * @note This property can be used only when using variable fonts.
+   */
+  FONT_VARIATIONS,
 };
 
 } // namespace Property
@@ -518,6 +526,15 @@ DALI_TOOLKIT_API void SetRemoveBackInset(TextField textField, const bool remove)
  */
 DALI_TOOLKIT_API bool IsRemoveBackInset(TextField textField);
 
+/**
+ * @brief Registers a new font variation property based on the provided tag.
+ *
+ * @param[in] textField The instance of TextField.
+ * @param[in] tag A 4-character string representing the variation property tag.
+ * @return The index of the registered variation property. Property::INVALID_INDEX if failed.
+ */
+DALI_TOOLKIT_API Dali::Property::Index RegisterFontVariationProperty(TextField textField, std::string tag);
+
 } // namespace DevelTextField
 
 } // namespace Toolkit
index 4cbc390630cb96d9a6ce0a570f3e4c20fd78719a..1ce9454d425cefa10d8ddd4b18002764ba6a2ede 100644 (file)
@@ -130,6 +130,11 @@ int GetLineCount(TextLabel textLabel, float width)
   return GetImpl(textLabel).GetLineCount(width);
 }
 
+Dali::Property::Index RegisterFontVariationProperty(TextLabel textLabel, std::string tag)
+{
+  return GetImpl(textLabel).RegisterFontVariationProperty(tag);
+}
+
 } // namespace DevelTextLabel
 
 } // namespace Toolkit
index c817095bd402b3af1743fbf856827351c9f5b463..ab0bb3a91afa0d6d9a9666d120dc7cde7cbbe89e 100644 (file)
@@ -20,6 +20,7 @@
 
 // EXTERNAL INCLUDES
 #include <dali/public-api/common/vector-wrapper.h>
+#include <dali/public-api/object/property.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/text-controls/text-label.h>
@@ -288,6 +289,13 @@ enum Type
    * @note This property is read-only.
    */
   IS_SCROLLING,
+
+  /**
+   * @brief Enables customization of fonts with variations such as weight and slant.
+   * @details Name "fontVariations", type Property::MAP.
+   * @note This property can be used only when using variable fonts.
+   */
+  FONT_VARIATIONS,
 };
 
 } // namespace Property
@@ -468,6 +476,15 @@ DALI_TOOLKIT_API void RequestAsyncHeightForWidth(TextLabel textLabel, float widt
  */
 DALI_TOOLKIT_API int GetLineCount(TextLabel textLabel, float width);
 
+/**
+ * @brief Registers a new font variation property based on the provided tag.
+ *
+ * @param[in] textLabel The instance of TextLabel.
+ * @param[in] tag A 4-character string representing the variation property tag.
+ * @return The index of the registered variation property. Property::INVALID_INDEX if failed.
+ */
+DALI_TOOLKIT_API Dali::Property::Index RegisterFontVariationProperty(TextLabel textLabel, std::string tag);
+
 /**
  * @brief Anchor clicked signal type.
  *
index 62a1fbcb47a7a46eb80f49fc1b2e8dc8e736a7cf..2b93c1fd15e30b0d2bf7d46bb11ffde003c6b2cd 100644 (file)
@@ -164,6 +164,7 @@ DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "verticalAlignme
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "selectionPopupStyle",                  MAP,       SELECTION_POPUP_STYLE               )
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "removeFrontInset",                     BOOLEAN,   REMOVE_FRONT_INSET                  )
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "removeBackInset",                      BOOLEAN,   REMOVE_BACK_INSET                   )
+DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "fontVariations",                       MAP,       FONT_VARIATIONS                )
 
 DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "textChanged",           SIGNAL_TEXT_CHANGED           )
 DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "inputStyleChanged",     SIGNAL_INPUT_STYLE_CHANGED    )
@@ -722,7 +723,21 @@ void TextEditor::OnPropertySet(Property::Index index, const Property::Value& pro
     }
     default:
     {
-      Control::OnPropertySet(index, propertyValue); // up call to control for non-handled properties
+      if(Self().DoesCustomPropertyExist(index) && mVariationIndexMap.find(index) != mVariationIndexMap.end())
+      {
+        std::string tag = mVariationIndexMap[index];
+        float value = propertyValue.Get<float>();
+
+        Property::Map map;
+        mController->GetVariationsMap(map);
+        map[tag.data()] = value;
+
+        mController->SetVariationsMap(map);
+      }
+      else
+      {
+        Control::OnPropertySet(index, propertyValue); // up call to control for non-handled properties
+      }
       break;
     }
   }
@@ -1393,6 +1408,59 @@ bool TextEditor::IsRemoveBackInset() const
   return mController->IsRemoveBackInset();
 }
 
+Dali::Property::Index TextEditor::RegisterFontVariationProperty(std::string tag)
+{
+  if(tag.length() != 4) // Variable tag must be 4-length string.
+  {
+    DALI_LOG_ERROR("Font Variation Register Failed. The length of tag is not 4.\n");
+    return Property::INVALID_INDEX;
+  }
+
+  Actor self = Self();
+
+  Property::Map variationsMap;
+  mController->GetVariationsMap(variationsMap);
+
+  float variationValue = 0.f;
+  auto tagPtr = variationsMap.Find(tag);
+
+  if(tagPtr)
+  {
+    variationValue = tagPtr->Get<float>();
+  }
+
+  Dali::Property::Index index = self.RegisterProperty(tag.data(), variationValue);
+  if(mVariationIndexMap.find(index) == mVariationIndexMap.end())
+  {
+    PropertyNotification customFontVariationNotification = self.AddPropertyNotification(index, StepCondition(1.0f));
+    // TODO: Make step value customizable by user.
+    customFontVariationNotification.NotifySignal().Connect(this, &TextEditor::OnVariationPropertyNotify);
+
+    mVariationIndexMap[index] = tag;
+    // TODO: Make UnregisterProperty() to remove tag from mVariationIndexMap.
+  }
+
+  return index;
+}
+
+void TextEditor::OnVariationPropertyNotify(PropertyNotification& source)
+{
+  Property::Map map;
+  mController->GetVariationsMap(map);
+
+  for(auto &[index, tag] : mVariationIndexMap)
+  {
+    if(Self().DoesCustomPropertyExist(index))
+    {
+      float value = Self().GetCurrentProperty(index).Get<float>();
+      map[tag.data()] = std::round(value);
+    }
+  }
+
+  // Full Variation Update.
+  mController->SetVariationsMap(map);
+}
+
 TextEditor::TextEditor(ControlBehaviour additionalBehaviour)
 : Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT | additionalBehaviour)),
   mAnimationPeriod(0.0f, 0.0f),
index 89bd2a1988e9a000e3f3a06c2d33e98db3fb3f77..00cf7ebbba8a46813bcdc5ebde8ae7b5950fdb08 100644 (file)
@@ -468,6 +468,14 @@ public:
    */
   bool IsRemoveBackInset() const;
 
+  /**
+   * @brief Registers a new font variation property based on the provided tag.
+   *
+   * @param[in] tag A 4-character string representing the variation property tag.
+   * @return The index of the registered variation property. Property::INVALID_INDEX if failed.
+   */
+  Dali::Property::Index RegisterFontVariationProperty(std::string tag);
+
 private: // Implementation
   /**
    * @copydoc Dali::Toolkit::Text::Controller::(InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent)
@@ -599,6 +607,11 @@ private: // Implementation
   // Needed to synchronize TextAnchor actors with Anchor objects in text's logical model
   void OnAccessibilityStatusChanged();
 
+  /**
+   * @brief Notifies when the font variation property changes to specific value.
+   */
+  void OnVariationPropertyNotify(PropertyNotification& source);
+
 private: // Data
   // Signals
   Toolkit::TextEditor::TextChangedSignalType                mTextChangedSignal;
@@ -612,6 +625,9 @@ private: // Data
   Toolkit::DevelTextEditor::SelectionClearedSignalType      mSelectionClearedSignal;
   Toolkit::DevelTextEditor::SelectionStartedSignalType      mSelectionStartedSignal;
 
+  // for Font Variations
+  std::map<Dali::Property::Index, std::string> mVariationIndexMap;  // Stores [CustomPropertyIndex, tag].
+
   InputMethodContext               mInputMethodContext;
   Text::ControllerPtr              mController;
   Text::RendererPtr                mRenderer;
index edafd6acb0efae5e7cb7e37fc8cc0dd95e2b0c91..c5427e08052b2e04d032241d24d69ccb56d8596b 100644 (file)
@@ -763,6 +763,14 @@ void TextEditor::PropertyHandler::SetProperty(Toolkit::TextEditor textEditor, Pr
       impl.mController->SetRemoveBackInset(remove);
       break;
     }
+    case Toolkit::DevelTextEditor::Property::FONT_VARIATIONS:
+    {
+      const Property::Map variationsMap = value.Get<Property::Map>();
+      impl.mController->SetVariationsMap(variationsMap);
+
+      impl.RequestTextRelayout();
+      break;
+    }
   }
 }
 
@@ -1202,6 +1210,14 @@ Property::Value TextEditor::PropertyHandler::GetProperty(Toolkit::TextEditor tex
       value = impl.mController->IsRemoveBackInset();
       break;
     }
+    case Toolkit::DevelTextEditor::Property::FONT_VARIATIONS:
+    {
+      Property::Map variationsMap;
+      impl.mController->GetVariationsMap(variationsMap);
+
+      value = variationsMap;
+      break;
+    }
   } //switch
   return value;
 }
index 70237504a86775a5022934cbf1684779da8afbaa..f8d130f7b89285d770c0e433e886383a1dbabf1b 100644 (file)
@@ -149,6 +149,7 @@ DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "characterSpacing
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "selectionPopupStyle",              MAP,       SELECTION_POPUP_STYLE               )
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "removeFrontInset",                 BOOLEAN,   REMOVE_FRONT_INSET                  )
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "removeBackInset",                  BOOLEAN,   REMOVE_BACK_INSET                   )
+DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "fontVariations",                   MAP,       FONT_VARIATIONS                )
 
 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "textChanged",           SIGNAL_TEXT_CHANGED           )
 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "maxLengthReached",      SIGNAL_MAX_LENGTH_REACHED     )
@@ -630,7 +631,21 @@ void TextField::OnPropertySet(Property::Index index, const Property::Value& prop
     }
     default:
     {
-      Control::OnPropertySet(index, propertyValue); // up call to control for non-handled properties
+      if(Self().DoesCustomPropertyExist(index) && mVariationIndexMap.find(index) != mVariationIndexMap.end())
+      {
+        std::string tag = mVariationIndexMap[index];
+        float value = propertyValue.Get<float>();
+
+        Property::Map map;
+        mController->GetVariationsMap(map);
+        map[tag.data()] = value;
+
+        mController->SetVariationsMap(map);
+      }
+      else
+      {
+        Control::OnPropertySet(index, propertyValue); // up call to control for non-handled properties
+      }
       break;
     }
   }
@@ -1242,6 +1257,59 @@ bool TextField::IsRemoveBackInset() const
   return mController->IsRemoveBackInset();
 }
 
+Dali::Property::Index TextField::RegisterFontVariationProperty(std::string tag)
+{
+  if(tag.length() != 4) // Variable tag must be 4-length string.
+  {
+    DALI_LOG_ERROR("Font Variation Register Failed. The length of tag is not 4.\n");
+    return Property::INVALID_INDEX;
+  }
+
+  Actor self = Self();
+
+  Property::Map variationsMap;
+  mController->GetVariationsMap(variationsMap);
+
+  float variationValue = 0.f;
+  auto tagPtr = variationsMap.Find(tag);
+
+  if(tagPtr)
+  {
+    variationValue = tagPtr->Get<float>();
+  }
+
+  Dali::Property::Index index = self.RegisterProperty(tag.data(), variationValue);
+  if(mVariationIndexMap.find(index) == mVariationIndexMap.end())
+  {
+    PropertyNotification customFontVariationNotification = self.AddPropertyNotification(index, StepCondition(1.0f));
+    // TODO: Make step value customizable by user.
+    customFontVariationNotification.NotifySignal().Connect(this, &TextField::OnVariationPropertyNotify);
+
+    mVariationIndexMap[index] = tag;
+    // TODO: Make UnregisterProperty() to remove tag from mVariationIndexMap.
+  }
+
+  return index;
+}
+
+void TextField::OnVariationPropertyNotify(PropertyNotification& source)
+{
+  Property::Map map;
+  mController->GetVariationsMap(map);
+
+  for(auto &[index, tag] : mVariationIndexMap)
+  {
+    if(Self().DoesCustomPropertyExist(index))
+    {
+      float value = Self().GetCurrentProperty(index).Get<float>();
+      map[tag.data()] = std::round(value);
+    }
+  }
+
+  // Full Variation Update.
+  mController->SetVariationsMap(map);
+}
+
 std::string TextField::TextFieldAccessible::GetName() const
 {
   if(IsHiddenInput())
index 9a3480a5b122e3712ae5d5a40869224a0cd28360..a3cd26158b3f318fe4920895bab7a697ba05da80 100644 (file)
@@ -145,6 +145,14 @@ public:
    */
   DevelTextField::SelectionStartedSignalType& SelectionStartedSignal();
 
+  /**
+   * @brief Registers a new font variation property based on the provided tag.
+   *
+   * @param[in] tag A 4-character string representing the variation property tag.
+   * @return The index of the registered variation property. Property::INVALID_INDEX if failed.
+   */
+  Dali::Property::Index RegisterFontVariationProperty(std::string tag);
+
 private: // From Control
   /**
    * @copydoc Control::OnInitialize()
@@ -548,6 +556,11 @@ private: // Implementation
   // Needed to synchronize TextAnchor actors with Anchor objects in text's logical model
   void OnAccessibilityStatusChanged();
 
+  /**
+   * @brief Notifies when the font variation property changes to specific value.
+   */
+  void OnVariationPropertyNotify(PropertyNotification& source);
+
 private: // Data
   // Signals
   Toolkit::TextField::TextChangedSignalType                mTextChangedSignal;
@@ -560,6 +573,9 @@ private: // Data
   Toolkit::DevelTextField::SelectionClearedSignalType      mSelectionClearedSignal;
   Toolkit::DevelTextField::SelectionStartedSignalType      mSelectionStartedSignal;
 
+  // for Font Variations
+  std::map<Dali::Property::Index, std::string> mVariationIndexMap;  // Stores [CustomPropertyIndex, tag].
+
   InputMethodContext               mInputMethodContext;
   Text::ControllerPtr              mController;
   Text::RendererPtr                mRenderer;
index 2745a76bb0fe31be4d9e38725a5fb9f5865616ec..2707b224a67a13b127bccad8198c64f12e3ead1f 100644 (file)
@@ -721,6 +721,14 @@ void TextField::PropertyHandler::SetProperty(Toolkit::TextField textField, Prope
       impl.mController->SetRemoveBackInset(remove);
       break;
     }
+    case Toolkit::DevelTextField::Property::FONT_VARIATIONS:
+    {
+      const Property::Map variationsMap = value.Get<Property::Map>();
+      impl.mController->SetVariationsMap(variationsMap);
+
+      impl.RequestTextRelayout();
+      break;
+    }
   }
 }
 
@@ -1118,6 +1126,14 @@ Property::Value TextField::PropertyHandler::GetProperty(Toolkit::TextField textF
       value = impl.mController->IsRemoveBackInset();
       break;
     }
+    case Toolkit::DevelTextField::Property::FONT_VARIATIONS:
+    {
+      Property::Map variationsMap;
+      impl.mController->GetVariationsMap(variationsMap);
+
+      value = variationsMap;
+      break;
+    }
 
   } //switch
   return value;
index f1a5a014fe2001632a9dc6c2238f9f69f66e3771..a60bbb7bf35c8948740dcc1c09f5ebc49a398fb7 100644 (file)
@@ -155,6 +155,7 @@ DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY(Toolkit, TextLabel, "manualRendered",
 DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY(Toolkit, TextLabel, "asyncLineCount",               INTEGER, ASYNC_LINE_COUNT               )
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextLabel, "ellipsisMode",                 INTEGER, ELLIPSIS_MODE                  )
 DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY(Toolkit, TextLabel, "isScrolling",                  BOOLEAN, IS_SCROLLING                   )
+DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextLabel, "fontVariations",               MAP,     FONT_VARIATIONS                )
 
 DALI_ANIMATABLE_PROPERTY_REGISTRATION_WITH_DEFAULT(Toolkit, TextLabel, "textColor",      Color::BLACK,     TEXT_COLOR   )
 DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION(Toolkit,    TextLabel, "textColorRed",   TEXT_COLOR_RED,   TEXT_COLOR, 0)
@@ -705,6 +706,15 @@ void TextLabel::SetProperty(BaseObject* object, Property::Index index, const Pro
         }
         break;
       }
+      case Toolkit::DevelTextLabel::Property::FONT_VARIATIONS:
+      {
+        const Property::Map variationsMap = value.Get<Property::Map>();
+        impl.mController->SetVariationsMap(variationsMap);
+
+        impl.RequestTextRelayout();
+        impl.mIsAsyncRenderNeeded = true;
+        break;
+      }
     }
 
     // Request relayout when text update is needed. It's necessary to call it
@@ -1020,6 +1030,14 @@ Property::Value TextLabel::GetProperty(BaseObject* object, Property::Index index
         value = impl.mTextScroller && impl.mTextScroller->IsScrolling() ? true : false;
         break;
       }
+      case Toolkit::DevelTextLabel::Property::FONT_VARIATIONS:
+      {
+        Property::Map variationsMap;
+        impl.mController->GetVariationsMap(variationsMap);
+
+        value = variationsMap;
+        break;
+      }
     }
   }
 
@@ -1323,7 +1341,21 @@ void TextLabel::OnPropertySet(Property::Index index, const Property::Value& prop
     }
     default:
     {
-      Control::OnPropertySet(index, propertyValue); // up call to control for non-handled properties
+      if(Self().DoesCustomPropertyExist(index) && mVariationIndexMap.find(index) != mVariationIndexMap.end())
+      {
+        std::string tag = mVariationIndexMap[index];
+        float value = propertyValue.Get<float>();
+
+        Property::Map map;
+        mController->GetVariationsMap(map);
+        map[tag.data()] = value;
+
+        mController->SetVariationsMap(map);
+      }
+      else
+      {
+        Control::OnPropertySet(index, propertyValue); // up call to control for non-handled properties
+      }
       break;
     }
   }
@@ -2076,6 +2108,59 @@ void TextLabel::RequestAsyncRenderWithConstraint(float widthConstraint, float he
   mIsAsyncRenderNeeded = false;
 }
 
+Dali::Property::Index TextLabel::RegisterFontVariationProperty(std::string tag)
+{
+  if(tag.length() != 4) // Variable tag must be 4-length string.
+  {
+    DALI_LOG_ERROR("Font Variation Register Failed. The length of tag is not 4.\n");
+    return Property::INVALID_INDEX;
+  }
+
+  Actor self = Self();
+
+  Property::Map variationsMap;
+  mController->GetVariationsMap(variationsMap);
+
+  float variationValue = 0.f;
+  auto tagPtr = variationsMap.Find(tag);
+
+  if(tagPtr)
+  {
+    variationValue = tagPtr->Get<float>();
+  }
+
+  Dali::Property::Index index = self.RegisterProperty(tag.data(), variationValue);
+  if(mVariationIndexMap.find(index) == mVariationIndexMap.end())
+  {
+    PropertyNotification customFontVariationNotification = self.AddPropertyNotification(index, StepCondition(1.0f));
+    // TODO: Make step value customizable by user.
+    customFontVariationNotification.NotifySignal().Connect(this, &TextLabel::OnVariationPropertyNotify);
+
+    mVariationIndexMap[index] = tag;
+    // TODO: Make UnregisterProperty() to remove tag from mVariationIndexMap.
+  }
+
+  return index;
+}
+
+void TextLabel::OnVariationPropertyNotify(PropertyNotification& source)
+{
+  Property::Map map;
+  mController->GetVariationsMap(map);
+
+  for(auto &[index, tag] : mVariationIndexMap)
+  {
+    if(Self().DoesCustomPropertyExist(index))
+    {
+      float value = Self().GetCurrentProperty(index).Get<float>();
+      map[tag.data()] = std::round(value);
+    }
+  }
+
+  // Full Variation Update.
+  mController->SetVariationsMap(map);
+}
+
 std::string TextLabel::TextLabelAccessible::GetNameRaw() const
 {
   return GetWholeText();
index 57835637b44bdeb44e6c2c66371b12ea1164f75f..6c8aa860cea8c3cc2df0eb2971b4646ab088d750 100644 (file)
@@ -299,6 +299,13 @@ public:
    */
   void RequestAsyncHeightForWidth(float width);
 
+  /**
+   * @brief Registers a new font variation property based on the provided tag.
+   *
+   * @param[in] tag A 4-character string representing the variation property tag.
+   * @return The index of the registered variation property. Property::INVALID_INDEX if failed.
+   */
+  Dali::Property::Index RegisterFontVariationProperty(std::string tag);
 
 private: // From Control
   /**
@@ -476,6 +483,11 @@ private:
 
   void OnAccessibilityStatusChanged();
 
+  /**
+   * @brief Notifies when the font variation property changes to specific value.
+   */
+  void OnVariationPropertyNotify(PropertyNotification& source);
+
 private: // Data
   Text::ControllerPtr   mController;
   Text::TextScrollerPtr mTextScroller;
@@ -491,6 +503,8 @@ private: // Data
   Toolkit::DevelTextLabel::AsyncNaturalSizeComputedSignalType mAsyncNaturalSizeComputedSignal;
   Toolkit::DevelTextLabel::AsyncHeightForWidthComputedSignalType mAsyncHeightForWidthComputedSignal;
 
+  // for Font Variations
+  std::map<Dali::Property::Index, std::string> mVariationIndexMap;  // Stores [CustomPropertyIndex, tag].
 
   std::string mLocale;
   Vector2     mSize;
index 23596477512b3ad5c529c512d018c51a1a0372fb..519e72ed63c3112b59092474bda5f1ac4e8f5d2a 100644 (file)
@@ -492,6 +492,12 @@ void AsyncTextLoader::Update(AsyncTextParameters& parameters)
 
   const Vector<Character>& textToShape = mIsTextMirrored ? mirroredUtf32Characters : utf32Characters;
 
+  Property::Map *variationsMapPtr = nullptr;
+  if(!mTextModel->mLogicalModel->mVariationsMap.Empty())
+  {
+    variationsMapPtr = &mTextModel->mLogicalModel->mVariationsMap;
+  }
+
   // Shapes the text.
   ShapeText(mModule.GetShaping(),
             mModule.GetFontClient(),
@@ -505,7 +511,8 @@ void AsyncTextLoader::Update(AsyncTextParameters& parameters)
             glyphs,
             glyphsToCharactersMap,
             charactersPerGlyph,
-            newParagraphGlyphs);
+            newParagraphGlyphs,
+            variationsMapPtr);
 
   // Create the 'number of glyphs' per character and the glyph to character conversion tables.
   mTextModel->mVisualModel->CreateGlyphsPerCharacterTable(0u, 0u, numberOfCharacters);
index dc674ba1f3f6e3292c8c71a4ffd26b10e62fa66e..29d369d76375f2190b246d922ad09adbdf5f1a98 100644 (file)
@@ -282,6 +282,12 @@ bool ControllerImplModelUpdater::Update(Controller::Impl& impl, OperationsMask o
         }
       }
 
+      Property::Map *variationsMapPtr = nullptr;
+      if(!impl.mModel->mLogicalModel->mVariationsMap.Empty())
+      {
+        variationsMapPtr = &impl.mModel->mLogicalModel->mVariationsMap;
+      }
+
       // Validates the fonts. If there is a character with no assigned font it sets a default one.
       // After this call, fonts are validated.
       multilanguageSupport.ValidateFonts(impl.mFontClient,
@@ -293,7 +299,8 @@ bool ControllerImplModelUpdater::Update(Controller::Impl& impl, OperationsMask o
                                          impl.GetFontSizeScale(),
                                          startIndex,
                                          requestedNumberOfCharacters,
-                                         validFonts);
+                                         validFonts,
+                                         variationsMapPtr);
     }
     updated = true;
   }
@@ -377,6 +384,12 @@ bool ControllerImplModelUpdater::Update(Controller::Impl& impl, OperationsMask o
 
     TextAbstraction::Shaping shaping = TextAbstraction::Shaping::Get();
 
+    Property::Map *variationsMapPtr = nullptr;
+    if(!impl.mModel->mLogicalModel->mVariationsMap.Empty())
+    {
+      variationsMapPtr = &impl.mModel->mLogicalModel->mVariationsMap;
+    }
+
     // Shapes the text.
     ShapeText(shaping,
               impl.mFontClient,
@@ -390,7 +403,8 @@ bool ControllerImplModelUpdater::Update(Controller::Impl& impl, OperationsMask o
               glyphs,
               glyphsToCharactersMap,
               charactersPerGlyph,
-              newParagraphGlyphs);
+              newParagraphGlyphs,
+              variationsMapPtr);
 
     // Create the 'number of glyphs' per character and the glyph to character conversion tables.
     impl.mModel->mVisualModel->CreateGlyphsPerCharacterTable(startIndex, impl.mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters);
index e57f4499d6c6071a5fca93d979db1d69d99b1fb1..37332eaf8b75b40d0204148a1365a28655cb849b 100644 (file)
@@ -340,6 +340,38 @@ void Controller::SetTextCutout(bool cutout)
   }
 }
 
+void Controller::GetVariationsMap(Property::Map& map)
+{
+  map = mImpl->mModel->mLogicalModel->mVariationsMap;
+}
+
+void Controller::SetVariationsMap(const Property::Map& map)
+{
+  auto& variationsMap = mImpl->mModel->mLogicalModel->mVariationsMap;
+  variationsMap.Clear();
+
+  std::size_t numberOfItems = map.Count();
+
+  for(std::size_t index = 0; index < numberOfItems; index++)
+  {
+    const KeyValuePair& keyvalue = map.GetKeyValue(index);
+
+    if(keyvalue.first.type == Property::Key::STRING)
+    {
+      float value = 0.f;
+      if(keyvalue.first.stringKey.length() == 4 && keyvalue.second.Get(value)) // Variable tag must be 4-length string.
+      {
+        variationsMap[keyvalue.first.stringKey.data()] = value;
+      }
+    }
+  }
+
+  // Clear the font-specific data
+  mImpl->ClearFontData();
+
+  mImpl->RequestRelayout();
+}
+
 void Controller::ChangedLayoutDirection()
 {
   mImpl->mIsLayoutDirectionChanged = true;
index 162b29911c073d9fba589508eddb4098b0eb0ef4..42ff2121eeb3870c6e1b5bc535d512e4c3f45562 100644 (file)
@@ -1926,6 +1926,18 @@ public: // Queries & retrieves.
    */
   void SetTextCutout(bool cutout);
 
+  /**
+   * @brief Retrieves variation value to model
+   * @param[out] map The value of cutout for the text
+   */
+  void GetVariationsMap(Property::Map& map);
+
+  /**
+   * @brief Sets variation value to model
+   * @param[in] map The value of cutout for the text
+   */
+  void SetVariationsMap(const Property::Map& map);
+
   /**
    * @brief Sets SetMatchLayoutDirection value to model
    * @param[in] match The value of matchLayoutDirection for the text
index dd6de0dfce020a836b221e28af8ccd8962ca7eac..69105b812baa3a1cd2bac82882b8767ab758e684 100644 (file)
@@ -22,6 +22,7 @@
 #include <dali/public-api/common/dali-vector.h>
 #include <dali/public-api/common/intrusive-ptr.h>
 #include <dali/public-api/object/ref-object.h>
+#include <dali/public-api/object/property-map.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/anchor.h>
@@ -273,6 +274,8 @@ public:
   Vector<BoundedParagraphRun>           mBoundedParagraphRuns;          ///< The bounded paragraph is used to handle a paragraph mark-up tag and it's attributes. Like TextAlign, TextDirection, TextIndent, LineHeight, etc.
   Vector<CharacterSpacingCharacterRun>  mCharacterSpacingCharacterRuns; ///< The character-spacing character run from markup-processor.
 
+  Property::Map                         mVariationsMap; ///< The map for variable fonts. it might be replaced by variable map run.
+
   BidirectionalLineRunIndex mBidirectionalLineIndex; ///< The last fetched bidirectional line info.
   bool                      mSpannedTextPlaced : 1;  ///< Whether the spanned-text is placed.
 
index f725d437fddec0fdaabb7014b0d139bafe22b59e..dd5e4e56c6e6db9990b10b7be679d191ebbd0ebd 100644 (file)
@@ -663,7 +663,8 @@ void MultilanguageSupport::ValidateFonts(TextAbstraction::FontClient&
                                          float                                   fontSizeScale,
                                          CharacterIndex                          startIndex,
                                          Length                                  numberOfCharacters,
-                                         Vector<FontRun>&                        fonts)
+                                         Vector<FontRun>&                        fonts,
+                                         Property::Map*                          variationsMapPtr)
 {
   DALI_LOG_INFO(gLogFilter, Debug::General, "-->MultilanguageSupport::ValidateFonts\n");
 
@@ -744,7 +745,8 @@ void MultilanguageSupport::ValidateFonts(TextAbstraction::FontClient&
                           isDefaultFont);
 
     // Get the font for the current character.
-    FontId fontId = fontClient.GetFontId(currentFontDescription, currentFontPointSize);
+    FontId fontId = fontClient.GetFontId(currentFontDescription, currentFontPointSize, 0, variationsMapPtr);
+
     currentFontId = fontId;
 
     // Prevent double-bolding from both markup and style
index 486327168233a9499b7c8e9b99cbf5c79e8b312f..dcedb18e41f8cf71d26b94fd0adff247187cb78a 100644 (file)
@@ -175,7 +175,8 @@ public:
                      float                                   fontSizeScale,
                      CharacterIndex                          startIndex,
                      Length                                  numberOfCharacters,
-                     Vector<FontRun>&                        fonts);
+                     Vector<FontRun>&                        fonts,
+                     Property::Map*                          variationsMapPtr);
 
   /**
    * @brief Callback function for when the locale is changed.
index 00668d0a562c4f9dfebbee0d8d097075a20d3eb5..c996e0faa7b8d455870a235411dacfcbfa3f4b68 100644 (file)
@@ -72,7 +72,8 @@ void MultilanguageSupport::ValidateFonts(TextAbstraction::FontClient&
                                          float                                   fontSizeScale,
                                          CharacterIndex                          startIndex,
                                          Length                                  numberOfCharacters,
-                                         Vector<FontRun>&                        fonts)
+                                         Vector<FontRun>&                        fonts,
+                                         Property::Map*                          variationsMapPtr)
 {
   GetImplementation(*this).ValidateFonts(fontClient,
                                          text,
@@ -83,7 +84,8 @@ void MultilanguageSupport::ValidateFonts(TextAbstraction::FontClient&
                                          fontSizeScale,
                                          startIndex,
                                          numberOfCharacters,
-                                         fonts);
+                                         fonts,
+                                         variationsMapPtr);
 }
 
 const std::string& MultilanguageSupport::GetLocale()
index 223a52ce3226851ee5b90329109b1f7f30def5b7..10aa14c0ccd32e5db5c73cf6dadb8686c6d932f0 100644 (file)
@@ -124,6 +124,7 @@ public:
    * @param[in] startIndex The character from where the font info is set.
    * @param[in] numberOfCharacters The number of characters to set the font.
    * @param[out] fonts The validated fonts.
+   * @param[in] variationsMapPtr The variations used in variable fonts.
    */
   void ValidateFonts(TextAbstraction::FontClient&            fontClient,
                      const Vector<Character>&                text,
@@ -134,7 +135,8 @@ public:
                      float                                   fontSizeScale,
                      CharacterIndex                          startIndex,
                      Length                                  numberOfCharacters,
-                     Vector<FontRun>&                        fonts);
+                     Vector<FontRun>&                        fonts,
+                     Property::Map*                          variationsMapPtr = nullptr);
 
   /**
    * @brief Gets the locale.
index 9a4d7685c8db19765100fe21d510c89c5bd6ef18..617bd33e89be71a8fbaf46e2b2c89c4b359d50fb 100644 (file)
@@ -62,7 +62,8 @@ void ShapeText(TextAbstraction::Shaping&    shaping,
                Vector<GlyphInfo>&           glyphs,
                Vector<CharacterIndex>&      glyphToCharacterMap,
                Vector<Length>&              charactersPerGlyph,
-               Vector<GlyphIndex>&          newParagraphGlyphs)
+               Vector<GlyphIndex>&          newParagraphGlyphs,
+               Property::Map*               variationsMapPtr)
 {
   if(0u == numberOfCharacters)
   {
@@ -212,7 +213,8 @@ void ShapeText(TextAbstraction::Shaping&    shaping,
                                                 textBuffer + previousIndex,
                                                 (currentIndex - previousIndex), // The number of characters to shape.
                                                 currentFontId,
-                                                currentScript);
+                                                currentScript,
+                                                variationsMapPtr);
 
 #if defined(TRACE_ENABLED)
     if(logEnabled)
@@ -260,6 +262,7 @@ void ShapeText(TextAbstraction::Shaping&    shaping,
     {
       // Add the index of the new paragraph glyph to a vector.
       // Their metrics will be updated in a following step.
+      DALI_ASSERT_ALWAYS(glyphIndex > 0u);
       newParagraphGlyphs.PushBack(glyphIndex - 1u);
     }
 
index 671bec9059e9bc23dfd138f20a450caa8f92da3d..c170af53caeebea5ca6b227b8feb5d68594ae7ca 100644 (file)
@@ -52,6 +52,7 @@ class VisualModel;
  * @param[out] glyphToCharacterMap Vector containing the first character in the logical model that each glyph relates to.
  * @param[out] charactersPerGlyph Vector containing the number of characters per glyph.
  * @param[out] newParagraphGlyphs Vector containing the indices to the new paragraph glyphs.
+ * @param[in] variationsMapPtr The variations used in variable fonts.
  */
 void ShapeText(TextAbstraction::Shaping&    shaping,
                TextAbstraction::FontClient& fontClient,
@@ -65,7 +66,8 @@ void ShapeText(TextAbstraction::Shaping&    shaping,
                Vector<GlyphInfo>&           glyphs,
                Vector<CharacterIndex>&      glyphToCharacterMap,
                Vector<Length>&              charactersPerGlyph,
-               Vector<GlyphIndex>&          newParagraphGlyphs);
+               Vector<GlyphIndex>&          newParagraphGlyphs,
+               Property::Map*               variationsMapPtr = nullptr);
 
 } // namespace Text