Files
bevy/examples/ui/text/font_atlas_debug.rs
Gonçalo Rica Pais da Silva f255b8e57a Upgrade glam, hexasphere, rand & uuid to latest versions (#22928)
# Objective

- `glam`, `hexasphere` & `rand` have released their latest versions,
update Bevy to support them.

## Solution

- The above have been updated to their compatible versions. `rand_distr`
updated as well to match `rand` v0.10 support.
- `rand_chacha` is soft deprecated and no longer used by `rand`, so its
usage has been changed to `chacha20` to match `rand` dep tree.
- `uuid` is in the process of updating to `getrandom` v0.4, which `rand`
v0.10 supports. This PR remains in draft until a new `uuid` release hits
crates.io.
- `RngCore` is now `Rng`, and `Rng` is now `RngExt`, so this required
updating across many files.
- `choose_multiple` method is deprecated, changed to `sample`.

## Testing

- Chase all compiler errors, since this should not regress any already
existing behaviour.
- This must pass CI without regressions.

## Additional Notes

`getrandom` v0.4 doesn't add anything new for Web WASM support, so the
same `wasm_js` feature is used.
2026-02-19 22:17:25 +00:00

112 lines
3.2 KiB
Rust

//! This example illustrates how `FontAtlas`'s are populated.
//! Bevy uses `FontAtlas`'s under the hood to optimize text rendering.
use bevy::{color::palettes::basic::YELLOW, prelude::*, text::FontAtlasSet};
use chacha20::ChaCha8Rng;
use rand::{RngExt, SeedableRng};
fn main() {
App::new()
.init_resource::<State>()
.insert_resource(ClearColor(Color::BLACK))
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, (text_update_system, atlas_render_system))
.run();
}
#[derive(Resource)]
struct State {
atlas_count: u32,
handle: Handle<Font>,
timer: Timer,
}
impl Default for State {
fn default() -> Self {
Self {
atlas_count: 0,
handle: Handle::default(),
timer: Timer::from_seconds(0.05, TimerMode::Repeating),
}
}
}
#[derive(Resource, Deref, DerefMut)]
struct SeededRng(ChaCha8Rng);
fn atlas_render_system(
mut commands: Commands,
mut state: ResMut<State>,
font_atlas_set: Res<FontAtlasSet>,
images: Res<Assets<Image>>,
) {
if let Some(font_atlases) = font_atlas_set.values().next() {
let x_offset = state.atlas_count as f32;
if state.atlas_count == font_atlases.len() as u32 {
return;
}
let font_atlas = &font_atlases[state.atlas_count as usize];
let image = images.get(&font_atlas.texture).unwrap();
state.atlas_count += 1;
commands.spawn((
ImageNode::new(font_atlas.texture.clone()),
Node {
position_type: PositionType::Absolute,
top: Val::ZERO,
left: px(image.width() as f32 * x_offset),
..default()
},
));
}
}
fn text_update_system(
mut state: ResMut<State>,
time: Res<Time>,
mut query: Query<&mut Text>,
mut seeded_rng: ResMut<SeededRng>,
) {
if !state.timer.tick(time.delta()).just_finished() {
return;
}
for mut text in &mut query {
let c = seeded_rng.random::<u8>() as char;
let string = &mut **text;
if !string.contains(c) {
string.push(c);
}
}
}
fn setup(mut commands: Commands, asset_server: Res<AssetServer>, mut state: ResMut<State>) {
state.handle = asset_server.load("fonts/FiraSans-Bold.ttf");
let font = FontSource::from(state.handle.clone());
commands.spawn(Camera2d);
commands
.spawn((
Node {
position_type: PositionType::Absolute,
bottom: Val::ZERO,
..default()
},
BackgroundColor(Color::NONE),
))
.with_children(|parent| {
parent.spawn((
Text::new("a"),
TextFont {
font,
font_size: FontSize::Px(50.0),
..default()
},
TextColor(YELLOW.into()),
));
});
// We're seeding the PRNG here to make this example deterministic for testing purposes.
// This isn't strictly required in practical use unless you need your app to be deterministic.
commands.insert_resource(SeededRng(ChaCha8Rng::seed_from_u64(19878367467713)));
}