add support for text feature in runtime

add support for text feature in runtime

Diffs=
20b585bea add support for text feature in runtime (#6674)

Co-authored-by: hernan <hernan@rive.app>
diff --git a/.rive_head b/.rive_head
index cf570cd..66dd24d 100644
--- a/.rive_head
+++ b/.rive_head
@@ -1 +1 @@
-8bca56dcaffd0f563a91f628b0ed432eca71acb5
+20b585bea54a56631527f6379934dd0f4ec2d5af
diff --git a/include/rive/text/text_style.hpp b/include/rive/text/text_style.hpp
index 49efcea..68bdf0b 100644
--- a/include/rive/text/text_style.hpp
+++ b/include/rive/text/text_style.hpp
@@ -18,6 +18,7 @@
 
 class TextVariationHelper;
 class TextStyleAxis;
+class TextStyleFeature;
 class TextStyle : public TextStyleBase, public ShapePaintContainer, public FileAssetReferencer
 {
 private:
@@ -38,6 +39,7 @@
     void draw(Renderer* renderer);
     Core* clone() const override;
     void addVariation(TextStyleAxis* axis);
+    void addFeature(TextStyleFeature* feature);
     void updateVariableFont();
     StatusCode onAddedClean(CoreContext* context) override;
     void onDirty(ComponentDirt dirt) override;
@@ -56,6 +58,8 @@
     std::vector<Font::Coord> m_coords;
     std::vector<TextStyleAxis*> m_variations;
     std::vector<rcp<RenderPaint>> m_paintPool;
+    std::vector<TextStyleFeature*> m_styleFeatures;
+    std::vector<Font::Feature> m_features;
 };
 } // namespace rive
 
diff --git a/include/rive/text/text_style_feature.hpp b/include/rive/text/text_style_feature.hpp
index 73aee8c..fd0bb75 100644
--- a/include/rive/text/text_style_feature.hpp
+++ b/include/rive/text/text_style_feature.hpp
@@ -7,6 +7,7 @@
 class TextStyleFeature : public TextStyleFeatureBase
 {
 public:
+    StatusCode onAddedDirty(CoreContext* context) override;
 };
 } // namespace rive
 
diff --git a/src/text/text_style.cpp b/src/text/text_style.cpp
index a43a1c8..e1b1343 100644
--- a/src/text/text_style.cpp
+++ b/src/text/text_style.cpp
@@ -1,5 +1,6 @@
 #include "rive/text/text_style.hpp"
 #include "rive/text/text_style_axis.hpp"
+#include "rive/text/text_style_feature.hpp"
 #include "rive/renderer.hpp"
 #include "rive/shapes/paint/shape_paint.hpp"
 #include "rive/backboard.hpp"
@@ -36,6 +37,8 @@
 
 void TextStyle::addVariation(TextStyleAxis* axis) { m_variations.push_back(axis); }
 
+void TextStyle::addFeature(TextStyleFeature* feature) { m_styleFeatures.push_back(feature); }
+
 void TextStyle::onDirty(ComponentDirt dirt)
 {
     if ((dirt & ComponentDirt::TextShape) == ComponentDirt::TextShape)
@@ -94,14 +97,19 @@
         // Not ready yet.
         return;
     }
-    if (!m_variations.empty())
+    if (!m_variations.empty() || !m_styleFeatures.empty())
     {
         m_coords.clear();
         for (TextStyleAxis* axis : m_variations)
         {
             m_coords.push_back({axis->tag(), axis->axisValue()});
         }
-        m_variableFont = baseFont->makeAtCoords(m_coords);
+        m_features.clear();
+        for (TextStyleFeature* styleFeature : m_styleFeatures)
+        {
+            m_features.push_back({styleFeature->tag(), styleFeature->featureValue()});
+        }
+        m_variableFont = baseFont->withOptions(m_coords, m_features);
     }
     else
     {
diff --git a/src/text/text_style_feature.cpp b/src/text/text_style_feature.cpp
new file mode 100644
index 0000000..31410a5
--- /dev/null
+++ b/src/text/text_style_feature.cpp
@@ -0,0 +1,20 @@
+#include "rive/text/text_style_feature.hpp"
+#include "rive/text/text_style.hpp"
+#include "rive/container_component.hpp"
+
+using namespace rive;
+
+StatusCode TextStyleFeature::onAddedDirty(CoreContext* context)
+{
+    StatusCode code = Super::onAddedDirty(context);
+    if (code == StatusCode::Ok)
+    {
+        if (!parent()->is<TextStyle>())
+        {
+            return StatusCode::InvalidObject;
+        }
+        auto style = parent()->as<TextStyle>();
+        style->addFeature(this);
+    }
+    return code;
+}
\ No newline at end of file