Skip to content

Add OpenType font variations#24088

Open
chronicl wants to merge 3 commits intobevyengine:mainfrom
chronicl:font_variations
Open

Add OpenType font variations#24088
chronicl wants to merge 3 commits intobevyengine:mainfrom
chronicl:font_variations

Conversation

@chronicl
Copy link
Copy Markdown
Contributor

@chronicl chronicl commented May 2, 2026

Objective

Bevy currently supports OpenType FontFeatures, but it doesn't support FontVariations, although parley has support for them.

Font features are mainly on/off values to vary the font (u32), while font variations are a continuous range of values that can be set to vary the font (f32).

I personally need it for setting FILL on the material design icon font.

Solution

I implemented FontVariations as a separate struct from FontFeatures for now and copied it's api.

However, since both are so similar it's worth considering to merge them into something like a FontVariables with a builder that has set_feature and set_variation methods.

Testing

Added a new example demonstrating how to set the font weight using FontVariations instead of FontWeight.

(Setting font weight using FontFeatures does not work, although the documentation suggests it should. I'm not sure if this depends on the variable font used or whether this is an error in the documentation.)

Showcase

Screenshot 2026-05-02 225528

@JMS55 JMS55 requested a review from ickshonpe May 3, 2026 00:23
@kfc35 kfc35 added A-Text Rendering and layout for characters S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels May 3, 2026
@alice-i-cecile alice-i-cecile requested a review from nicoburns May 3, 2026 21:25
@alice-i-cecile alice-i-cecile added C-Feature A new feature, making something new possible X-Uncontroversial This work is generally agreed upon labels May 3, 2026
font: font.clone(),
font_size: FontSize::Px(32.0),
font_variations: FontVariations::builder()
.set(FontVariationTag::WEIGHT, weight as f32)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels like a code smell that we should just be unifying the APIs here somehow.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can totally do that.

The question is what would we call the unified struct and builder. I was thinking

struct FontVariables {
    features: Vec<...>,
    variations: Vec<...>
}

and a corresponding builder.

However, this is less discoverable than FontVariations and FontFeatures, which match the OpenType names.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not so sure about unifying the APIs. I agree it would be more user friendly, but parley maintains separate lists and it might complicate font inheritance and change detection. So personally I think it would be better to leave it like this for now.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be okay though, I'm not certain.

@alice-i-cecile alice-i-cecile added this pull request to the merge queue May 3, 2026
@alice-i-cecile alice-i-cecile removed this pull request from the merge queue due to a manual request May 3, 2026

impl FontVariationTag {
/// Defines the stroke thickness.
pub const WEIGHT: FontVariationTag = FontVariationTag::new(b"wght");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels a bit empty just to have the wght tag, it would be nice to have a few more here.
And the doc comment for weight could mention the values will be clamped to some subrange inside 1..1000.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise, no complaints.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@cart cart closed this May 5, 2026
@cart cart reopened this May 5, 2026
@ickshonpe ickshonpe added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels May 8, 2026
@ickshonpe
Copy link
Copy Markdown
Contributor

@alice-i-cecile seems like this got forgotten after the merge problems a few days ago

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Text Rendering and layout for characters C-Feature A new feature, making something new possible S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it X-Uncontroversial This work is generally agreed upon

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants