Add offset to text outline 34/310334/2
authorBowon Ryu <bowon.ryu@samsung.com>
Thu, 25 Apr 2024 11:28:13 +0000 (20:28 +0900)
committerBowon Ryu <bowon.ryu@samsung.com>
Fri, 26 Apr 2024 10:02:24 +0000 (19:02 +0900)
Change-Id: I280ed148384325cfa83e2d48fae15a387bc81fcd
Signed-off-by: Bowon Ryu <bowon.ryu@samsung.com>
20 files changed:
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
automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp
dali-toolkit/devel-api/controls/text-controls/text-style-properties-devel.h
dali-toolkit/internal/text/controller/text-controller.cpp
dali-toolkit/internal/text/controller/text-controller.h
dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp
dali-toolkit/internal/text/rendering/text-typesetter.cpp
dali-toolkit/internal/text/rendering/view-model.cpp
dali-toolkit/internal/text/rendering/view-model.h
dali-toolkit/internal/text/text-effects-style.cpp
dali-toolkit/internal/text/text-model-interface.h
dali-toolkit/internal/text/text-model.cpp
dali-toolkit/internal/text/text-model.h
dali-toolkit/internal/text/text-view-interface.h
dali-toolkit/internal/text/text-view.cpp
dali-toolkit/internal/text/text-view.h
dali-toolkit/internal/text/visual-model-impl.cpp
dali-toolkit/internal/text/visual-model-impl.h

index bc75ce0a864e7cb930ce998fdfb8538abe6af8c5..c8db163c18872b62c4dbbf4877ff6694d7382d35 100644 (file)
@@ -1037,6 +1037,7 @@ int UtcDaliTextEditorSetPropertyP(void)
 
   outlineMapSet["color"] = Color::RED;
   outlineMapSet["width"] = 2.0f;
+  outlineMapSet["offset"] = Vector2(0.0f, 0.0f);
 
   editor.SetProperty(TextEditor::Property::OUTLINE, outlineMapSet);
 
index 0e0711fa605f76b84aa402a63108b584cde19706..01cd89ed59403a096661b3b0f1155b6aaa89fd99 100644 (file)
@@ -1103,6 +1103,7 @@ int UtcDaliTextFieldSetPropertyP(void)
 
   outlineMapSet["color"] = Color::RED;
   outlineMapSet["width"] = 2.0f;
+  outlineMapSet["offset"] = Vector2(0.0f, 0.0f);
 
   field.SetProperty(TextField::Property::OUTLINE, outlineMapSet);
 
index dd0b690ac65f8020447903708fda88347fd546c5..47c7369fd026378a73844adae8d42fe1978403d2 100644 (file)
@@ -952,6 +952,7 @@ int UtcDaliToolkitTextLabelSetPropertyP(void)
 
   outlineMapSet["color"] = Color::RED;
   outlineMapSet["width"] = 2.0f;
+  outlineMapSet["offset"] = Vector2(2.0f, 2.0f);
   label.SetProperty(TextLabel::Property::OUTLINE, outlineMapSet);
 
   outlineMapGet = label.GetProperty<Property::Map>(TextLabel::Property::OUTLINE);
@@ -961,11 +962,13 @@ int UtcDaliToolkitTextLabelSetPropertyP(void)
   outlineMapSet.Clear();
   outlineMapSet[Toolkit::DevelText::Outline::Property::COLOR] = Color::BLUE;
   outlineMapSet[Toolkit::DevelText::Outline::Property::WIDTH] = 3.0f;
+  outlineMapSet[Toolkit::DevelText::Outline::Property::OFFSET] = Vector2(3.0f, 3.0f);
+
   label.SetProperty(TextLabel::Property::OUTLINE, outlineMapSet);
 
   outlineMapGet = label.GetProperty<Property::Map>(TextLabel::Property::OUTLINE);
   DALI_TEST_EQUALS(outlineMapGet.Count(), outlineMapSet.Count(), TEST_LOCATION);
-  std::vector<std::string> outlineIndicesConversionTable = {"color", "width"};
+  std::vector<std::string> outlineIndicesConversionTable = {"color", "width", "offset"};
   DALI_TEST_EQUALS(DaliTestCheckMaps(outlineMapGet, outlineMapSet, outlineIndicesConversionTable), true, TEST_LOCATION);
 
   // Check the background property
@@ -1817,6 +1820,7 @@ int UtcDaliToolkitTextlabelTextStyle01(void)
 
   outlineMapSet["color"] = Color::BLUE;
   outlineMapSet["width"] = 2.0f;
+  outlineMapSet["offset"] = "2 2";
   label.SetProperty(TextLabel::Property::OUTLINE, outlineMapSet);
 
   application.SendNotification();
index 5f7d11405cd1776916f17e924a49cd265345156c..bb955c35495c9f672e6e7bce3456289ac7f24c6d 100644 (file)
@@ -1290,7 +1290,7 @@ int UtcDaliVisualGetPropertyMap10(void)
   propertyMap.Insert("underline", underlineMapSet.Add("enable", true).Add("color", Color::GREEN).Add("height", 1).Add("type", Text::Underline::Type::SOLID).Add("dashWidth", 2).Add("dashGap", 1));
 
   Property::Map outlineMapSet;
-  propertyMap.Insert("outline", outlineMapSet.Add("color", Color::YELLOW).Add("width", 1));
+  propertyMap.Insert("outline", outlineMapSet.Add("color", Color::YELLOW).Add("width", 1).Add("offset", Vector2(2.0f, 2.0f)));
 
   Property::Map backgroundMapSet;
   propertyMap.Insert("textBackground", backgroundMapSet.Add("enable", true).Add("color", Color::CYAN));
index e3641f643204310e5c4cf8e3f044b0de5d5ffec4..2e2ed08b16a1bedcb3f43b7c008d123d5da366cc 100644 (file)
@@ -137,7 +137,14 @@ enum
    * @details Name "width", type Property::STRING or Property::FLOAT i.e. "1.0" or 1.f
    * @note Optional. If not provided then the outline is not enabled.
    */
-  WIDTH
+  WIDTH,
+
+  /**
+   * @brief The offset in pixels of the outline.
+   * @details Name "offset", type Property::STRING or Property::VECTOR2. i.e "3.0 3.0" or Vector2( 3.f, 3.f )
+   * @note Optional. If not provided then the outline is not enabled.
+   */
+  OFFSET
 };
 
 } // namespace Property
index 548224b25d376e4ba0715deac1027e5911daded0..20731c4564e4fcc4d371a31402ad41865680b8c9 100644 (file)
@@ -995,6 +995,17 @@ float Controller::GetDashedUnderlineGap() const
   return mImpl->mModel->mVisualModel->GetDashedUnderlineGap();
 }
 
+void Controller::SetOutlineOffset(const Vector2& outlineOffset)
+{
+  mImpl->mModel->mVisualModel->SetOutlineOffset(outlineOffset);
+  mImpl->RequestRelayout();
+}
+
+const Vector2& Controller::GetOutlineOffset() const
+{
+  return mImpl->mModel->mVisualModel->GetOutlineOffset();
+}
+
 void Controller::SetOutlineColor(const Vector4& color)
 {
   mImpl->mModel->mVisualModel->SetOutlineColor(color);
index b8ff325264a6ad0e9ee15dfa213ee3078c772941..53601469bcdc632b9d4526a0f5e033eb6fd8044e 100644 (file)
@@ -1279,6 +1279,20 @@ public: // Default style & Input style
    */
   float GetDashedUnderlineGap() const;
 
+  /**
+   * @brief Set the outline offset.
+   *
+   * @param[in] outlineOffset The outline offset.
+   */
+  void SetOutlineOffset(const Vector2& outlineOffset);
+
+  /**
+   * @brief Retrieve the outline offset.
+   *
+   * @return The outline offset.
+   */
+  const Vector2& GetOutlineOffset() const;
+
   /**
    * @brief Set the outline color.
    *
index 5ccaad0f2942c5d369428d9f6ac6caa7191d5e24..787bcfa48dc3f0a897c70f1a2878fc10cb368de4 100644 (file)
@@ -450,6 +450,7 @@ struct AtlasRenderer::Impl
     const bool       underlineEnabled = view.IsUnderlineEnabled();
     const uint16_t   outlineWidth     = view.GetOutlineWidth();
     const Vector4&   outlineColor(view.GetOutlineColor());
+    const Vector2&   outlineOffset(view.GetOutlineOffset());
     const bool       isOutline            = 0u != outlineWidth;
     const GlyphInfo* hyphens              = view.GetHyphens();
     const Length*    hyphenIndices        = view.GetHyphenIndices();
@@ -656,7 +657,7 @@ struct AtlasRenderer::Impl
 
         if(0u != slot.mImageId) // invalid slot id, glyph has failed to be added to atlas
         {
-          Vector2 positionPlusOutlineOffset = position;
+          Vector2 positionPlusOutlineOffset = position + outlineOffset;
           if(isOutline)
           {
             // Add an offset to the text.
index 1c31199d8e6d7d2422414be9392297e97c7cebca..f83e7e2441563732bfca9f59a915b8e68493c082 100644 (file)
@@ -1149,11 +1149,15 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const uint32_t bufferWidth, con
 
     if(style == Typesetter::STYLE_OUTLINE)
     {
+      const Vector2& outlineOffset = mModel->GetOutlineOffset();
+
       glyphData.horizontalOffset -= outlineWidth;
+      glyphData.horizontalOffset += outlineOffset.x;
       if(lineIndex == 0u)
       {
         // Only need to add the vertical outline offset for the first line
         glyphData.verticalOffset -= outlineWidth;
+        glyphData.verticalOffset += outlineOffset.y;
       }
     }
     else if(style == Typesetter::STYLE_SHADOW)
index 3799fc9fe521d65e63c4d8c71081103153c7e04f..28b4802463eda2c56f928f7a16b976329ecc9737 100644 (file)
@@ -285,6 +285,11 @@ void ViewModel::GetUnderlineRuns(UnderlinedGlyphRun* underlineRuns, UnderlineRun
   mModel->GetUnderlineRuns(underlineRuns, index, numberOfRuns);
 }
 
+const Vector2& ViewModel::GetOutlineOffset() const
+{
+  return mModel->GetOutlineOffset();
+}
+
 const Vector4& ViewModel::GetOutlineColor() const
 {
   return mModel->GetOutlineColor();
index 4de580d1e584b76c7bca366ba8d31b9fb81c899c..e85dbbcfbe66f32588cf800a89033c224bb7d686 100644 (file)
@@ -246,6 +246,11 @@ public:
    */
   void GetUnderlineRuns(UnderlinedGlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns) const override;
 
+  /**
+   * @copydoc ModelInterface::GetOutlineOffset()
+   */
+  const Vector2& GetOutlineOffset() const override;
+
   /**
    * @copydoc ModelInterface::GetOutlineColor()
    */
index 2bf1398406f4ebaa6a1ec5d34128ba2fdeb401f0..60f45d2483c1cbdbc153ed48d80542f199e0b0b1 100644 (file)
@@ -229,7 +229,9 @@ bool ParseOutlineProperties(const Property::Map& underlinePropertiesMap,
                             bool&                colorDefined,
                             Vector4&             color,
                             bool&                widthDefined,
-                            uint16_t&            width)
+                            uint16_t&            width,
+                            bool&                offsetDefined,
+                            Vector2&             offset)
 {
   const unsigned int numberOfItems = underlinePropertiesMap.Count();
 
@@ -250,6 +252,21 @@ bool ParseOutlineProperties(const Property::Map& underlinePropertiesMap,
       widthDefined = true;
       width        = static_cast<uint16_t>(valueGet.second.Get<float>());
     }
+    else if((DevelText::Outline::Property::OFFSET == valueGet.first.indexKey) || (OFFSET_KEY == valueGet.first.stringKey))
+    {
+      /// Offset key.
+      offsetDefined = true;
+
+      if(valueGet.second.GetType() == Dali::Property::STRING)
+      {
+        const std::string offsetStr = valueGet.second.Get<std::string>();
+        StringToVector2(offsetStr.c_str(), offsetStr.size(), offset);
+      }
+      else
+      {
+        offset = valueGet.second.Get<Vector2>();
+      }
+    }
   }
 
   return 0u == numberOfItems;
@@ -752,10 +769,12 @@ bool SetOutlineProperties(ControllerPtr controller, const Property::Value& value
       {
         const Property::Map& propertiesMap = value.Get<Property::Map>();
 
-        bool     colorDefined = false;
+        bool     colorDefined  = false;
         Vector4  color;
-        bool     widthDefined = false;
-        uint16_t width        = 0u;
+        bool     widthDefined  = false;
+        uint16_t width         = 0u;
+        bool     offsetDefined = false;
+        Vector2  offset;
 
         bool empty = true;
 
@@ -776,7 +795,9 @@ bool SetOutlineProperties(ControllerPtr controller, const Property::Value& value
                                          colorDefined,
                                          color,
                                          widthDefined,
-                                         width);
+                                         width,
+                                         offsetDefined,
+                                         offset);
 
           controller->OutlineSetByString(false);
         }
@@ -795,6 +816,12 @@ bool SetOutlineProperties(ControllerPtr controller, const Property::Value& value
             controller->SetOutlineWidth(width);
             update = true;
           }
+
+          if(offsetDefined && (controller->GetOutlineOffset() != offset))
+          {
+            controller->SetOutlineOffset(offset);
+            update = true;
+          }
         }
         else
         {
@@ -835,12 +862,15 @@ void GetOutlineProperties(ControllerPtr controller, Property::Value& value, Effe
         }
         else
         {
-          const Vector4& color = controller->GetOutlineColor();
-          const uint16_t width = controller->GetOutlineWidth();
+          const Vector4& color  = controller->GetOutlineColor();
+          const uint16_t width  = controller->GetOutlineWidth();
+          const Vector2& offset = controller->GetOutlineOffset();
+
 
           Property::Map map;
           map.Insert(COLOR_KEY, color);
           map.Insert(WIDTH_KEY, static_cast<int>(width));
+          map.Insert(OFFSET_KEY, offset);
 
           value = map;
 
index bd34ff8dba632d5de46179b89a0a25f43de2d91a..832753494a81bb7b648fd4c81ec95d6ba1eddf5e 100644 (file)
@@ -321,6 +321,13 @@ public:
    */
   virtual void GetUnderlineRuns(UnderlinedGlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns) const = 0;
 
+  /**
+   * @brief Retrieves the outline offset.
+   *
+   * @return The outline offset.
+   */
+  virtual const Vector2& GetOutlineOffset() const = 0;
+
   /**
    * @brief Retrieve the outline color.
    *
index ae0dd7c06c33ab1fdb2543fd7031a02fd56e337c..0af5d39581597aa6d89c120b6922047b7ff3414a 100644 (file)
@@ -227,6 +227,11 @@ void Model::GetUnderlineRuns(UnderlinedGlyphRun* underlineRuns, UnderlineRunInde
   mVisualModel->GetUnderlineRuns(underlineRuns, index, numberOfRuns);
 }
 
+const Vector2& Model::GetOutlineOffset() const
+{
+  return mVisualModel->GetOutlineOffset();
+}
+
 const Vector4& Model::GetOutlineColor() const
 {
   return mVisualModel->GetOutlineColor();
index e7387842869132d8ad67c58f28a02bcc102358f1..faa38b12cdedac3b2768f2f20c8a1815eddd5d58 100644 (file)
@@ -244,6 +244,11 @@ public:
    */
   void GetUnderlineRuns(UnderlinedGlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns) const override;
 
+  /**
+   * @copydoc ModelInterface::GetOutlineOffset()
+   */
+  const Vector2& GetOutlineOffset() const override;
+
   /**
    * @copydoc ModelInterface::GetOutlineColor()
    */
index 24fcfffacea65619ab2400e3f6d3e49550e47d9f..10ff4ff0b978e0149fb8460ae775408c465b4841 100644 (file)
@@ -247,6 +247,13 @@ public:
                                 UnderlineRunIndex   index,
                                 Length              numberOfRuns) const = 0;
 
+  /**
+   * @brief Retrieves the outline offset.
+   *
+   * @return The outline offset.
+   */
+  virtual const Vector2& GetOutlineOffset() const = 0;
+
   /**
    * @brief Retrieve the outline color.
    *
index d71000b0d7372d6784629fcef23bb7e3090b9700..66d0af9a273f4132f44472e22449a17d696aa52c 100644 (file)
@@ -845,6 +845,18 @@ void View::GetUnderlineRuns(UnderlinedGlyphRun* underlineRuns,
   }
 }
 
+const Vector2& View::GetOutlineOffset() const
+{
+// TODO : We should support outline offset to editable text.
+/*
+  if(mImpl->mVisualModel)
+  {
+    return mImpl->mVisualModel->GetOutlineOffset();
+  }
+*/
+  return Vector2::ZERO;
+}
+
 const Vector4& View::GetOutlineColor() const
 {
   if(mImpl->mVisualModel)
index 5bf55e1f738768d1b36dcf1e478a954d03b54357..9b12d03d71cb0ad225d263c0f0daa994ab675e7f 100644 (file)
@@ -186,6 +186,11 @@ public:
                                 UnderlineRunIndex   index,
                                 Length              numberOfRuns) const;
 
+  /**
+   * @copydoc Dali::Toolkit::Text::ViewInterface::GetOutlineOffset()
+   */
+  const Vector2& GetOutlineOffset() const override;
+
   /**
    * @copydoc Dali::Toolkit::Text::ViewInterface::GetOutlineColor()
    */
index c79e5a964208b75773acb47849c8031cd00ef93b..1d1038369a3d54833841d6e01168307b80695b97 100644 (file)
@@ -381,6 +381,11 @@ void VisualModel::SetUnderlineColor(const Vector4& color)
   mUnderlineColorSet = true;
 }
 
+void VisualModel::SetOutlineOffset(const Vector2& outlineOffset)
+{
+  mOutlineOffset = outlineOffset;
+}
+
 void VisualModel::SetOutlineColor(const Vector4& color)
 {
   mOutlineColor = color;
@@ -506,6 +511,11 @@ const Vector4& VisualModel::GetUnderlineColor() const
   return mUnderlineColor;
 }
 
+const Vector2& VisualModel::GetOutlineOffset() const
+{
+  return mOutlineOffset;
+}
+
 const Vector4& VisualModel::GetOutlineColor() const
 {
   return mOutlineColor;
@@ -665,6 +675,7 @@ VisualModel::VisualModel()
   mStrikethroughColor(Color::BLACK),
   mControlSize(),
   mShadowOffset(),
+  mOutlineOffset(),
   mUnderlineHeight(0.0f),
   mStrikethroughHeight(0.0f),
   mUnderlineType(Text::Underline::SOLID),
index 9dae2cf08275fac0d2568cd969e06398a14f3098..b67172a3f41019df0dd5412f30551a1231c5c4c1 100644 (file)
@@ -383,6 +383,13 @@ public:
    */
   Length GetNumberOfUnderlineRuns() const;
 
+  /**
+   * @brief Sets the text's outline offset.
+   *
+   * @param[in] outlineOffset The outline offset.
+   */
+  void SetOutlineOffset(const Vector2& outlineOffset);
+
   /**
    * @brief Set the outline color.
    *
@@ -390,6 +397,13 @@ public:
    */
   void SetOutlineColor(const Vector4& color);
 
+  /**
+   * @brief Retrieves the text's outline offset.
+   *
+   * @return The text's outline offset.
+   */
+  const Vector2& GetOutlineOffset() const;
+
   /**
    * @brief Retrieve the outline color.
    *
@@ -673,6 +687,7 @@ public:
   Vector4                          mStrikethroughColor;     ///< Color of text background
   Size                             mControlSize;            ///< The size of the UI control.
   Vector2                          mShadowOffset;           ///< Offset for drop shadow, 0 indicates no shadow
+  Vector2                          mOutlineOffset;          ///< Offset for outline
   float                            mUnderlineHeight;        ///< Fixed height for underline to override font metrics.
   float                            mStrikethroughHeight;    ///< Fixed height for strikethrough to override font metrics.
   Text::Underline::Type            mUnderlineType;          ///< The type of the underline.