Files
bevy/examples/ui/text/font_variations.rs
Lennard d2481ccf60 Add OpenType font variations (#24088)
# 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

<img width="946" height="541" alt="Screenshot 2026-05-02 225528"
src="https://github.com/user-attachments/assets/9067191b-8517-4fec-9283-45e57180658a"
/>

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2026-05-08 13:29:06 +00:00

62 lines
2.0 KiB
Rust

//! This example demonstrates how to use font variations to control variable font axes.
use bevy::prelude::*;
use bevy::text::{FontVariationTag, FontVariations};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.run();
}
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
let font: FontSource = asset_server.load("fonts/MonaSans-VariableFont.ttf").into();
commands.spawn(Camera2d);
commands.spawn((
Node {
flex_direction: FlexDirection::Column,
align_self: AlignSelf::Center,
justify_self: JustifySelf::Center,
align_items: AlignItems::Center,
..default()
},
children![
(
Text::new("Font Variations (wght axis)"),
TextFont {
font: font.clone(),
font_size: FontSize::Px(32.0),
..default()
},
Underline,
),
(
Node {
flex_direction: FlexDirection::Column,
padding: px(8.).all(),
row_gap: px(8.),
..default()
},
Children::spawn(SpawnIter(
[100, 200, 300, 400, 500, 600, 700, 800, 900]
.into_iter()
.map(move |weight| (
Text(format!("wght {weight}")),
TextFont {
font: font.clone(),
font_size: FontSize::Px(32.0),
font_variations: FontVariations::builder()
.set(FontVariationTag::WEIGHT, weight as f32)
.build(),
..default()
},
))
)),
),
],
));
}