Files
ickshonpe 48ec375a3a bevy_text parley migration (#22879)
# Objective

Migrate `bevy_text` from Cosmic Text to Parley.

Closes #21940. Fixes #21767, fixes #21768. Part of #21676.

## Solution

I came down with the flu yesterday when I was about halfway done. I
managed to work through it and drag this to a sort of finished state
anyway but there's probably some weird decisions because I haven't been
entirely coherent.

Most of the significant changes are to the pipeline module. There is
also a new `parley_context` module.
`FontAtlasKey` has a bunch of new fields, I can't remember why there's
both an `id` and a `index` now.

## Testing

Weird bug in `testbed_2d`:

<img width="893" height="168" alt="symbols"
src="https://github.com/user-attachments/assets/29288e16-9c3a-4aee-9ec5-638179b0bac0"
/>

Most other things seem to work the same as main, ymmv.

## Showcase

`testbed_2d`'s text scene on main with Cosmic Text:

<img width="1924" height="1127" alt="main-text2d-layout"
src="https://github.com/user-attachments/assets/55d0c7b7-7517-4a50-b76f-2a24e7cdc28f"
/>

`testbed_2d`'s text scene on this PR with Parley:

<img width="1924" height="1127" alt="testbed-2d-text"
src="https://github.com/user-attachments/assets/c87265fa-6e5f-4c03-aa5e-730f09f83ca3"
/>

`testbed_ui`'s text scene on main with Cosmic Text:

<img width="1924" height="1127" alt="testbed-ui-main"
src="https://github.com/user-attachments/assets/ce764891-3ca6-4c63-83af-8fe285a4a229"
/>

`testbed_ui`'s text scene on this PR with Parley:

<img width="1924" height="1127" alt="testbed_ui_parley"
src="https://github.com/user-attachments/assets/45bcbfe7-1ce4-44f7-bad7-7fa8f46c66ce"
/>

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2026-02-11 05:52:47 +00:00

253 lines
10 KiB
Rust

//! This example demonstrates how to use font weights, widths and styles.
use bevy::prelude::*;
use bevy::text::FontSource;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.run();
}
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
let family = FontSource::from(asset_server.load("fonts/MonaSans-VariableFont.ttf"));
commands.spawn(Camera2d);
commands.spawn((
Node {
flex_direction: FlexDirection::Column,
align_self: AlignSelf::Center,
justify_self: JustifySelf::Center,
align_items: AlignItems::Center,
padding: px(16.).all(),
row_gap: px(16.),
..default()
},
children![
(
Text::new("Font Weights, Widths & Styles"),
TextFont {
font: family.clone(),
font_size: FontSize::Px(32.0),
..default()
},
Underline,
),
(
// Two columns side-by-side
Node {
flex_direction: FlexDirection::Row,
column_gap: px(32.),
..default()
},
children![
(
// Left column: Weights
Node {
flex_direction: FlexDirection::Column,
padding: px(8.).all(),
row_gap: px(8.),
..default()
},
children![
(
Text::new("Weight 100 (Thin)"),
TextFont {
font: family.clone(),
weight: FontWeight::THIN,
..default()
},
),
(
Text::new("Weight 200 (Extra Light)"),
TextFont {
font: family.clone(),
weight: FontWeight::EXTRA_LIGHT,
..default()
},
),
(
Text::new("Weight 300 (Light)"),
TextFont {
font: family.clone(),
weight: FontWeight::LIGHT,
..default()
},
),
(
Text::new("Weight 400 (Normal)"),
TextFont {
font: family.clone(),
weight: FontWeight::NORMAL,
..default()
},
),
(
Text::new("Weight 500 (Medium)"),
TextFont {
font: family.clone(),
weight: FontWeight::MEDIUM,
..default()
},
),
(
Text::new("Weight 600 (Semibold)"),
TextFont {
font: family.clone(),
weight: FontWeight::SEMIBOLD,
..default()
},
),
(
Text::new("Weight 700 (Bold)"),
TextFont {
font: family.clone(),
weight: FontWeight::BOLD,
..default()
},
),
(
Text::new("Weight 800 (Extra Bold)"),
TextFont {
font: family.clone(),
weight: FontWeight::EXTRA_BOLD,
..default()
},
),
(
Text::new("Weight 900 (Black)"),
TextFont {
font: family.clone(),
weight: FontWeight::BLACK,
..default()
},
),
]
),
(
// Right column: Widths
Node {
flex_direction: FlexDirection::Column,
padding: px(8.).all(),
row_gap: px(8.),
..default()
},
children![
(
Text::new("FontWidth::ULTRA_CONDENSED"),
TextFont {
font: family.clone(),
width: FontWidth::ULTRA_CONDENSED,
..default()
},
),
(
Text::new("FontWidth::EXTRA_CONDENSED"),
TextFont {
font: family.clone(),
width: FontWidth::EXTRA_CONDENSED,
..default()
},
),
(
Text::new("FontWidth::CONDENSED"),
TextFont {
font: family.clone(),
width: FontWidth::CONDENSED,
..default()
},
),
(
Text::new("FontWidth::SEMI_CONDENSED"),
TextFont {
font: family.clone(),
width: FontWidth::SEMI_CONDENSED,
..default()
},
),
(
Text::new("FontWidth::NORMAL"),
TextFont {
font: family.clone(),
width: FontWidth::NORMAL,
..default()
},
),
(
Text::new("FontWidth::SEMI_EXPANDED"),
TextFont {
font: family.clone(),
width: FontWidth::SEMI_EXPANDED,
..default()
},
),
(
Text::new("FontWidth::EXPANDED"),
TextFont {
font: family.clone(),
width: FontWidth::EXPANDED,
..default()
},
),
(
Text::new("FontWidth::EXTRA_EXPANDED"),
TextFont {
font: family.clone(),
width: FontWidth::EXTRA_EXPANDED,
..default()
},
),
(
Text::new("FontWidth::ULTRA_EXPANDED"),
TextFont {
font: family.clone(),
width: FontWidth::ULTRA_EXPANDED,
..default()
},
),
],
),
(
// Right column: Style
Node {
flex_direction: FlexDirection::Column,
padding: px(8.).all(),
row_gap: px(8.),
..default()
},
children![
(
Text::new("FontStyle::Normal"),
TextFont {
font: family.clone(),
style: FontStyle::Normal,
..default()
},
),
(
Text::new("FontStyle::Oblique"),
TextFont {
font: family.clone(),
style: FontStyle::Oblique(None),
..default()
},
),
(
Text::new("FontStyle::Italic"),
TextFont {
font: family.clone(),
style: FontStyle::Italic,
..default()
},
),
]
),
]
),
],
));
}