parent
							
								
									2b0ee24a5d
								
							
						
					
					
						commit
						d4ab2f4d47
					
				@ -39,15 +39,16 @@ impl FontAtlas {
 | 
			
		||||
        texture_atlases: &mut Assets<TextureAtlas>,
 | 
			
		||||
        character: char,
 | 
			
		||||
        texture: &Texture,
 | 
			
		||||
    ) {
 | 
			
		||||
    ) -> bool {
 | 
			
		||||
        let texture_atlas = texture_atlases.get_mut(&self.texture_atlas).unwrap();
 | 
			
		||||
        if let Some(index) =
 | 
			
		||||
            self.dynamic_texture_atlas_builder
 | 
			
		||||
                .add_texture(texture_atlas, textures, texture)
 | 
			
		||||
        {
 | 
			
		||||
            self.glyph_to_index.insert(character, index);
 | 
			
		||||
            true
 | 
			
		||||
        } else {
 | 
			
		||||
            panic!("ran out of space in font atlas");
 | 
			
		||||
            false
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@ type FontSizeKey = FloatOrd;
 | 
			
		||||
#[derive(Default)]
 | 
			
		||||
pub struct FontAtlasSet {
 | 
			
		||||
    font: Handle<Font>,
 | 
			
		||||
    font_atlases: HashMap<FontSizeKey, FontAtlas>,
 | 
			
		||||
    font_atlases: HashMap<FontSizeKey, Vec<FontAtlas>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
@ -30,7 +30,7 @@ impl FontAtlasSet {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn iter(&self) -> impl Iterator<Item = (&FontSizeKey, &FontAtlas)> {
 | 
			
		||||
    pub fn iter(&self) -> impl Iterator<Item = (&FontSizeKey, &Vec<FontAtlas>)> {
 | 
			
		||||
        self.font_atlases.iter()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -38,7 +38,9 @@ impl FontAtlasSet {
 | 
			
		||||
        self.font_atlases
 | 
			
		||||
            .get(&FloatOrd(font_size))
 | 
			
		||||
            .map_or(false, |font_atlas| {
 | 
			
		||||
                font_atlas.get_char_index(character).is_some()
 | 
			
		||||
                font_atlas
 | 
			
		||||
                    .iter()
 | 
			
		||||
                    .any(|atlas| atlas.get_char_index(character).is_some())
 | 
			
		||||
            })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -52,10 +54,16 @@ impl FontAtlasSet {
 | 
			
		||||
    ) -> f32 {
 | 
			
		||||
        let font = fonts.get(&self.font).unwrap();
 | 
			
		||||
        let scaled_font = ab_glyph::Font::as_scaled(&font.font, font_size);
 | 
			
		||||
        let font_atlas = self
 | 
			
		||||
        let font_atlases = self
 | 
			
		||||
            .font_atlases
 | 
			
		||||
            .entry(FloatOrd(font_size))
 | 
			
		||||
            .or_insert_with(|| FontAtlas::new(textures, texture_atlases, Vec2::new(512.0, 512.0)));
 | 
			
		||||
            .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;
 | 
			
		||||
@ -67,10 +75,30 @@ impl FontAtlasSet {
 | 
			
		||||
            if let Some(last_glyph) = last_glyph.take() {
 | 
			
		||||
                width += scaled_font.kern(last_glyph.id, glyph.id);
 | 
			
		||||
            }
 | 
			
		||||
            if font_atlas.get_char_index(character).is_none() {
 | 
			
		||||
            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);
 | 
			
		||||
                    font_atlas.add_char(textures, texture_atlases, character, &glyph_texture);
 | 
			
		||||
                    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);
 | 
			
		||||
@ -85,9 +113,14 @@ impl FontAtlasSet {
 | 
			
		||||
            .get(&FloatOrd(font_size))
 | 
			
		||||
            .and_then(|font_atlas| {
 | 
			
		||||
                font_atlas
 | 
			
		||||
                    .get_char_index(character)
 | 
			
		||||
                    .map(|char_index| GlyphAtlasInfo {
 | 
			
		||||
                        texture_atlas: font_atlas.texture_atlas,
 | 
			
		||||
                    .iter()
 | 
			
		||||
                    .find_map(|atlas| {
 | 
			
		||||
                        atlas
 | 
			
		||||
                            .get_char_index(character)
 | 
			
		||||
                            .map(|char_index| (char_index, atlas.texture_atlas))
 | 
			
		||||
                    })
 | 
			
		||||
                    .map(|(char_index, texture_atlas)| GlyphAtlasInfo {
 | 
			
		||||
                        texture_atlas,
 | 
			
		||||
                        char_index,
 | 
			
		||||
                    })
 | 
			
		||||
            })
 | 
			
		||||
 | 
			
		||||
@ -12,7 +12,7 @@ fn main() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct State {
 | 
			
		||||
    added: bool,
 | 
			
		||||
    atlas_count: u32,
 | 
			
		||||
    handle: Handle<Font>,
 | 
			
		||||
    timer: Timer,
 | 
			
		||||
}
 | 
			
		||||
@ -20,7 +20,7 @@ struct State {
 | 
			
		||||
impl Default for State {
 | 
			
		||||
    fn default() -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            added: false,
 | 
			
		||||
            atlas_count: 0,
 | 
			
		||||
            handle: Handle::default(),
 | 
			
		||||
            timer: Timer::from_seconds(0.05, true),
 | 
			
		||||
        }
 | 
			
		||||
@ -34,20 +34,23 @@ fn atlas_render_system(
 | 
			
		||||
    font_atlas_sets: Res<Assets<FontAtlasSet>>,
 | 
			
		||||
    texture_atlases: Res<Assets<TextureAtlas>>,
 | 
			
		||||
) {
 | 
			
		||||
    if state.added {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    if let Some(set) = font_atlas_sets.get(&state.handle.as_handle::<FontAtlasSet>()) {
 | 
			
		||||
        if let Some((_size, font_atlas)) = set.iter().next() {
 | 
			
		||||
            state.added = true;
 | 
			
		||||
            let texture_atlas = texture_atlases.get(&font_atlas.texture_atlas).unwrap();
 | 
			
		||||
            let x_offset = state.atlas_count as f32;
 | 
			
		||||
            if state.atlas_count == font_atlas.len() as u32 {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            let texture_atlas = texture_atlases
 | 
			
		||||
                .get(&font_atlas[state.atlas_count as usize].texture_atlas)
 | 
			
		||||
                .unwrap();
 | 
			
		||||
            state.atlas_count += 1;
 | 
			
		||||
            commands.spawn(ImageComponents {
 | 
			
		||||
                material: materials.add(texture_atlas.texture.into()),
 | 
			
		||||
                style: Style {
 | 
			
		||||
                    position_type: PositionType::Absolute,
 | 
			
		||||
                    position: Rect {
 | 
			
		||||
                        top: Val::Px(0.0),
 | 
			
		||||
                        left: Val::Px(0.0),
 | 
			
		||||
                        left: Val::Px(512.0 * x_offset),
 | 
			
		||||
                        ..Default::default()
 | 
			
		||||
                    },
 | 
			
		||||
                    ..Default::default()
 | 
			
		||||
@ -61,8 +64,9 @@ fn atlas_render_system(
 | 
			
		||||
fn text_update_system(mut state: ResMut<State>, time: Res<Time>, mut query: Query<&mut Text>) {
 | 
			
		||||
    for mut text in &mut query.iter() {
 | 
			
		||||
        state.timer.tick(time.delta_seconds);
 | 
			
		||||
        if state.timer.finished {
 | 
			
		||||
            text.value = format!("{}", rand::random::<u8>() as char);
 | 
			
		||||
        let c = rand::random::<u8>() as char;
 | 
			
		||||
        if !text.value.contains(c) && state.timer.finished {
 | 
			
		||||
            text.value = format!("{}{}", text.value, c);
 | 
			
		||||
            state.timer.reset();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user