fix(runtime): Font weight layout measure fix (#10766) 0ae985862d

With certain fonts, the expected font features/variations aren't available until a frame after the text is measured, so for example, we measure glyphs using its default weight rather than the weight set in the style, which causes the rendered text not to fit within the measured area, thus incorrectly wrap to the next line. This fix updates variable fonts whenever TextStyle::font() is called IF the variable font hasn't previously been cached.

Specifically this issue was reproducible when using Solos to toggle between components which had text wrapped in layouts.

Co-authored-by: Philip Chung <philterdesign@gmail.com>
This commit is contained in:
philter
2025-10-14 17:32:00 +00:00
parent a839f067b0
commit 6c47e0e4a0
4 changed files with 19 additions and 6 deletions

View File

@@ -1 +1 @@
01c1b43af9ac51debb54e99a326405460b873fda
0ae985862d83742ed0883cb0228b6e06dbea1286

View File

@@ -34,7 +34,7 @@ public:
Core* clone() const override;
void addVariation(TextStyleAxis* axis);
void addFeature(TextStyleFeature* feature);
void updateVariableFont();
void updateVariableFont() const;
StatusCode onAddedClean(CoreContext* context) override;
void onDirty(ComponentDirt dirt) override;
bool validate(CoreContext* context) override;
@@ -47,12 +47,12 @@ protected:
private:
std::unique_ptr<TextVariationHelper> m_variationHelper;
rcp<Font> m_variableFont;
mutable rcp<Font> m_variableFont;
std::vector<Font::Coord> m_coords;
mutable std::vector<Font::Coord> m_coords;
std::vector<TextStyleAxis*> m_variations;
std::vector<TextStyleFeature*> m_styleFeatures;
std::vector<Font::Feature> m_features;
mutable std::vector<Font::Feature> m_features;
TextInterface* m_text = nullptr;
};
} // namespace rive

View File

@@ -78,11 +78,24 @@ const rcp<Font> TextStyle::font() const
return m_variableFont;
}
// Lazily build the variable font if variations/features are present but
// the variable font hasn't been created yet. This ensures the very first
// shape/measure uses the intended axes (e.g. wght) rather than the font's
// default axis values.
if ((!m_variations.empty() || !m_styleFeatures.empty()))
{
updateVariableFont();
if (m_variableFont != nullptr)
{
return m_variableFont;
}
}
auto asset = fontAsset();
return asset == nullptr ? nullptr : asset->font();
}
void TextStyle::updateVariableFont()
void TextStyle::updateVariableFont() const
{
auto asset = fontAsset();
rcp<Font> baseFont = asset == nullptr ? nullptr : asset->font();