Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not assume font handle is present in assets. #490

Merged
merged 1 commit into from
Sep 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 47 additions & 46 deletions crates/bevy_text/src/font_atlas_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,57 +52,58 @@ impl FontAtlasSet {
font_size: f32,
text: &str,
) -> f32 {
let font = fonts.get(&self.font).unwrap();
let scaled_font = ab_glyph::Font::as_scaled(&font.font, font_size);
let font_atlases = self
.font_atlases
.entry(FloatOrd(font_size))
.or_insert_with(|| {
vec![FontAtlas::new(
textures,
texture_atlases,
Vec2::new(512.0, 512.0),
)]
});

let mut last_glyph: Option<Glyph> = None;
let mut width = 0.0;
for character in text.chars() {
if character.is_control() {
continue;
}
let glyph = scaled_font.scaled_glyph(character);
if let Some(last_glyph) = last_glyph.take() {
width += scaled_font.kern(last_glyph.id, glyph.id);
}
if !font_atlases
.iter()
.any(|atlas| atlas.get_char_index(character).is_some())
{
if let Some(outlined_glyph) = scaled_font.outline_glyph(glyph.clone()) {
let glyph_texture = Font::get_outlined_glyph_texture(outlined_glyph);
let add_char_to_font_atlas = |atlas: &mut FontAtlas| -> bool {
atlas.add_char(textures, texture_atlases, character, &glyph_texture)
};
if !font_atlases.iter_mut().any(add_char_to_font_atlas) {
font_atlases.push(FontAtlas::new(
textures,
texture_atlases,
Vec2::new(512.0, 512.0),
));
if !font_atlases.last_mut().unwrap().add_char(
textures,
texture_atlases,
character,
&glyph_texture,
) {
panic!("could not add character to newly created FontAtlas");
if let Some(font) = fonts.get(&self.font) {
Copy link
Contributor

Choose a reason for hiding this comment

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

As an alternative, you could make an early return here in case the font doesn't exist yet. This way the rest of the function isn't indented.

Copy link
Member

Choose a reason for hiding this comment

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

I think that would require this:

if fonts.get(&self.font).is_some() { return; }
let font = self.fonts.get(&self.font).unwrap();

Which is both a double hash, slightly less safe, and less idiomatic. I definitely love flattening out indentation, but im not sure thats the right call here.

Copy link
Contributor

Choose a reason for hiding this comment

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

A simple way is:

let font = if let Some(font) = fonts.get(&self.font) { font } else { return };

let scaled_font = ab_glyph::Font::as_scaled(&font.font, font_size);
let font_atlases = self
.font_atlases
.entry(FloatOrd(font_size))
.or_insert_with(|| {
vec![FontAtlas::new(
textures,
texture_atlases,
Vec2::new(512.0, 512.0),
)]
});

let mut last_glyph: Option<Glyph> = None;
for character in text.chars() {
if character.is_control() {
continue;
}
let glyph = scaled_font.scaled_glyph(character);
if let Some(last_glyph) = last_glyph.take() {
width += scaled_font.kern(last_glyph.id, glyph.id);
}
if !font_atlases
.iter()
.any(|atlas| atlas.get_char_index(character).is_some())
{
if let Some(outlined_glyph) = scaled_font.outline_glyph(glyph.clone()) {
let glyph_texture = Font::get_outlined_glyph_texture(outlined_glyph);
let add_char_to_font_atlas = |atlas: &mut FontAtlas| -> bool {
atlas.add_char(textures, texture_atlases, character, &glyph_texture)
};
if !font_atlases.iter_mut().any(add_char_to_font_atlas) {
font_atlases.push(FontAtlas::new(
textures,
texture_atlases,
Vec2::new(512.0, 512.0),
));
if !font_atlases.last_mut().unwrap().add_char(
textures,
texture_atlases,
character,
&glyph_texture,
) {
panic!("could not add character to newly created FontAtlas");
}
}
}
width += scaled_font.h_advance(glyph.id);
last_glyph = Some(glyph);
}
}
width += scaled_font.h_advance(glyph.id);
last_glyph = Some(glyph);
}

width
Expand Down
34 changes: 18 additions & 16 deletions crates/bevy_ui/src/widget/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,21 +61,23 @@ pub fn draw_text_system(
mut query: Query<(&mut Draw, &Text, &Node, &GlobalTransform)>,
) {
for (mut draw, text, node, global_transform) in &mut query.iter() {
let position = global_transform.translation() - (node.size / 2.0).extend(0.0);
let mut drawable_text = DrawableText {
font: fonts.get(&text.font).unwrap(),
font_atlas_set: font_atlas_sets
.get(&text.font.as_handle::<FontAtlasSet>())
.unwrap(),
texture_atlases: &texture_atlases,
render_resource_bindings: &mut render_resource_bindings,
asset_render_resource_bindings: &mut asset_render_resource_bindings,
position,
msaa: &msaa,
style: &text.style,
text: &text.value,
container_size: node.size,
};
drawable_text.draw(&mut draw, &mut draw_context).unwrap();
if let Some(font) = fonts.get(&text.font) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Similarly here, a continue would have the same effect without indenting the whole block

let position = global_transform.translation() - (node.size / 2.0).extend(0.0);
let mut drawable_text = DrawableText {
font,
font_atlas_set: font_atlas_sets
.get(&text.font.as_handle::<FontAtlasSet>())
.unwrap(),
texture_atlases: &texture_atlases,
render_resource_bindings: &mut render_resource_bindings,
asset_render_resource_bindings: &mut asset_render_resource_bindings,
position,
msaa: &msaa,
style: &text.style,
text: &text.value,
container_size: node.size,
};
drawable_text.draw(&mut draw, &mut draw_context).unwrap();
}
}
}