Text fix variable and opacity Fixes issues caught by @JcToon Diffs= 44ef23f7e Text fix variable and opacity (#5017)
diff --git a/.rive_head b/.rive_head index be1933e..a911f6c 100644 --- a/.rive_head +++ b/.rive_head
@@ -1 +1 @@ -3c396d3b8d94b6c628493797c4f2b83938879284 +44ef23f7eba8156a8d1129a18bc948e74c920a6a
diff --git a/include/rive/shapes/shape_paint_container.hpp b/include/rive/shapes/shape_paint_container.hpp index 6771f6b..f5200fa 100644 --- a/include/rive/shapes/shape_paint_container.hpp +++ b/include/rive/shapes/shape_paint_container.hpp
@@ -36,6 +36,8 @@ void invalidateStrokeEffects(); std::unique_ptr<CommandPath> makeCommandPath(PathSpace space); + + void propagateOpacity(float opacity); }; } // namespace rive
diff --git a/include/rive/text/text_style.hpp b/include/rive/text/text_style.hpp index b8825b4..5a61435 100644 --- a/include/rive/text/text_style.hpp +++ b/include/rive/text/text_style.hpp
@@ -14,6 +14,7 @@ class Renderer; class RenderPath; +class TextVariationHelper; class TextStyleAxis; class TextStyle : public TextStyleBase, public ShapePaintContainer, public FileAssetReferencer { @@ -23,7 +24,7 @@ public: TextStyle(); void buildDependencies() override; - const rcp<Font> font() const { return m_font; } + const rcp<Font> font() const; void assets(const std::vector<FileAsset*>& assets) override; StatusCode import(ImportStack& importStack) override; @@ -32,14 +33,17 @@ void draw(Renderer* renderer); Core* clone() const override; void addVariation(TextStyleAxis* axis); + void updateVariableFont(); + StatusCode onAddedClean(CoreContext* context) override; void onDirty(ComponentDirt dirt) override; - void update(ComponentDirt value) override; + // void update(ComponentDirt value) override; protected: void fontSizeChanged() override; private: - rcp<Font> m_font; + std::unique_ptr<TextVariationHelper> m_variationHelper; + rcp<Font> m_variableFont; FontAsset* m_fontAsset = nullptr; std::unique_ptr<RenderPath> m_path; bool m_hasContents = false;
diff --git a/src/shapes/shape.cpp b/src/shapes/shape.cpp index cdcc59b..c7270fa 100644 --- a/src/shapes/shape.cpp +++ b/src/shapes/shape.cpp
@@ -24,10 +24,7 @@ if (hasDirt(value, ComponentDirt::RenderOpacity)) { - for (auto shapePaint : m_ShapePaints) - { - shapePaint->renderOpacity(renderOpacity()); - } + propagateOpacity(renderOpacity()); } }
diff --git a/src/shapes/shape_paint_container.cpp b/src/shapes/shape_paint_container.cpp index 458038c..283568a 100644 --- a/src/shapes/shape_paint_container.cpp +++ b/src/shapes/shape_paint_container.cpp
@@ -88,3 +88,11 @@ return std::unique_ptr<CommandPath>(factory->makeEmptyRenderPath()); } } + +void ShapePaintContainer::propagateOpacity(float opacity) +{ + for (auto shapePaint : m_ShapePaints) + { + shapePaint->renderOpacity(opacity); + } +} \ No newline at end of file
diff --git a/src/text/text.cpp b/src/text/text.cpp index af87a78..98406e0 100644 --- a/src/text/text.cpp +++ b/src/text/text.cpp
@@ -117,6 +117,7 @@ // This was the first path added to the style, so let's mark // it in our draw list. m_renderStyles.push_back(style); + style->propagateOpacity(renderOpacity()); } } lineIndex++; @@ -249,6 +250,15 @@ // with shaping. buildRenderStyles(); } + else if (hasDirt(value, ComponentDirt::RenderOpacity)) + { + // Note that buildRenderStyles does this too, which is why we can get + // away doing this in the else. + for (TextStyle* style : m_renderStyles) + { + style->propagateOpacity(renderOpacity()); + } + } } Core* Text::hitTest(HitInfo*, const Mat2D&)
diff --git a/src/text/text_style.cpp b/src/text/text_style.cpp index d3af95a..6ea4d37 100644 --- a/src/text/text_style.cpp +++ b/src/text/text_style.cpp
@@ -10,6 +10,27 @@ using namespace rive; +namespace rive +{ +class TextVariationHelper : public Component +{ +public: + TextVariationHelper(TextStyle* style) : m_textStyle(style) {} + TextStyle* style() const { return m_textStyle; } + void buildDependencies() override + { + auto text = m_textStyle->parent(); + text->artboard()->addDependent(this); + addDependent(text); + } + + void update(ComponentDirt value) override { m_textStyle->updateVariableFont(); } + +private: + TextStyle* m_textStyle; +}; +} // namespace rive + // satisfy unique_ptr TextStyle::TextStyle() {} @@ -20,34 +41,78 @@ if ((dirt & ComponentDirt::TextShape) == ComponentDirt::TextShape) { parent()->as<Text>()->markShapeDirty(); + if (m_variationHelper != nullptr) + { + m_variationHelper->addDirt(ComponentDirt::TextShape); + } } } -void TextStyle::update(ComponentDirt value) +StatusCode TextStyle::onAddedClean(CoreContext* context) { - if ((value & ComponentDirt::TextShape) == ComponentDirt::TextShape) + auto code = Super::onAddedClean(context); + if (code != StatusCode::Ok) { - rcp<Font> baseFont = m_fontAsset == nullptr ? nullptr : m_fontAsset->font(); - if (m_variations.empty()) + return code; + } + // This ensures context propagates to variation helper too. + if (!m_variations.empty()) + { + m_variationHelper = rivestd::make_unique<TextVariationHelper>(this); + } + if (m_variationHelper != nullptr) + { + if ((code = m_variationHelper->onAddedDirty(context)) != StatusCode::Ok) { - m_font = baseFont; + return code; } - else + if ((code = m_variationHelper->onAddedClean(context)) != StatusCode::Ok) { - m_coords.clear(); - for (TextStyleAxis* axis : m_variations) - { - m_coords.push_back({axis->tag(), axis->axisValue()}); - } - m_font = baseFont->makeAtCoords(m_coords); + return code; } } + return StatusCode::Ok; +} + +const rcp<Font> TextStyle::font() const +{ + if (m_variableFont != nullptr) + { + return m_variableFont; + } + return m_fontAsset == nullptr ? nullptr : m_fontAsset->font(); +} + +void TextStyle::updateVariableFont() +{ + rcp<Font> baseFont = m_fontAsset == nullptr ? nullptr : m_fontAsset->font(); + if (baseFont == nullptr) + { + // Not ready yet. + return; + } + if (!m_variations.empty()) + { + m_coords.clear(); + for (TextStyleAxis* axis : m_variations) + { + m_coords.push_back({axis->tag(), axis->axisValue()}); + } + m_variableFont = baseFont->makeAtCoords(m_coords); + } + else + { + m_variableFont = nullptr; + } } void TextStyle::buildDependencies() { - addDependent(parent()); - artboard()->addDependent(this); + if (m_variationHelper != nullptr) + { + m_variationHelper->buildDependencies(); + } + parent()->addDependent(this); Super::buildDependencies(); auto factory = getArtboard()->factory(); m_path = factory->makeEmptyRenderPath();