 ffecb05a0a
			
		
	
	
		ffecb05a0a
		
	
	
	
	
		
			
			This makes the [New Bevy Renderer](#2535) the default (and only) renderer. The new renderer isn't _quite_ ready for the final release yet, but I want as many people as possible to start testing it so we can identify bugs and address feedback prior to release. The examples are all ported over and operational with a few exceptions: * I removed a good portion of the examples in the `shader` folder. We still have some work to do in order to make these examples possible / ergonomic / worthwhile: #3120 and "high level shader material plugins" are the big ones. This is a temporary measure. * Temporarily removed the multiple_windows example: doing this properly in the new renderer will require the upcoming "render targets" changes. Same goes for the render_to_texture example. * Removed z_sort_debug: entity visibility sort info is no longer available in app logic. we could do this on the "render app" side, but i dont consider it a priority.
		
			
				
	
	
		
			131 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			131 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| use std::hash::Hash;
 | |
| 
 | |
| use ab_glyph::{PxScale, ScaleFont};
 | |
| use bevy_asset::{Assets, Handle, HandleId};
 | |
| use bevy_math::Size;
 | |
| use bevy_render::texture::Image;
 | |
| use bevy_sprite::TextureAtlas;
 | |
| use bevy_utils::HashMap;
 | |
| 
 | |
| use glyph_brush_layout::{FontId, SectionText};
 | |
| 
 | |
| use crate::{
 | |
|     error::TextError, glyph_brush::GlyphBrush, scale_value, Font, FontAtlasSet, PositionedGlyph,
 | |
|     TextAlignment, TextSection,
 | |
| };
 | |
| 
 | |
| pub struct TextPipeline<ID> {
 | |
|     brush: GlyphBrush,
 | |
|     glyph_map: HashMap<ID, TextLayoutInfo>,
 | |
|     map_font_id: HashMap<HandleId, FontId>,
 | |
| }
 | |
| 
 | |
| impl<ID> Default for TextPipeline<ID> {
 | |
|     fn default() -> Self {
 | |
|         TextPipeline {
 | |
|             brush: GlyphBrush::default(),
 | |
|             glyph_map: Default::default(),
 | |
|             map_font_id: Default::default(),
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| pub struct TextLayoutInfo {
 | |
|     pub glyphs: Vec<PositionedGlyph>,
 | |
|     pub size: Size,
 | |
| }
 | |
| 
 | |
| impl<ID: Hash + Eq> TextPipeline<ID> {
 | |
|     pub fn get_or_insert_font_id(&mut self, handle: &Handle<Font>, font: &Font) -> FontId {
 | |
|         let brush = &mut self.brush;
 | |
|         *self
 | |
|             .map_font_id
 | |
|             .entry(handle.id)
 | |
|             .or_insert_with(|| brush.add_font(handle.clone(), font.font.clone()))
 | |
|     }
 | |
| 
 | |
|     pub fn get_glyphs(&self, id: &ID) -> Option<&TextLayoutInfo> {
 | |
|         self.glyph_map.get(id)
 | |
|     }
 | |
| 
 | |
|     #[allow(clippy::too_many_arguments)]
 | |
|     pub fn queue_text(
 | |
|         &mut self,
 | |
|         id: ID,
 | |
|         fonts: &Assets<Font>,
 | |
|         sections: &[TextSection],
 | |
|         scale_factor: f64,
 | |
|         text_alignment: TextAlignment,
 | |
|         bounds: Size,
 | |
|         font_atlas_set_storage: &mut Assets<FontAtlasSet>,
 | |
|         texture_atlases: &mut Assets<TextureAtlas>,
 | |
|         textures: &mut Assets<Image>,
 | |
|     ) -> Result<(), TextError> {
 | |
|         let mut scaled_fonts = Vec::new();
 | |
|         let sections = sections
 | |
|             .iter()
 | |
|             .map(|section| {
 | |
|                 let font = fonts
 | |
|                     .get(section.style.font.id)
 | |
|                     .ok_or(TextError::NoSuchFont)?;
 | |
|                 let font_id = self.get_or_insert_font_id(§ion.style.font, font);
 | |
|                 let font_size = scale_value(section.style.font_size, scale_factor);
 | |
| 
 | |
|                 scaled_fonts.push(ab_glyph::Font::as_scaled(&font.font, font_size));
 | |
| 
 | |
|                 let section = SectionText {
 | |
|                     font_id,
 | |
|                     scale: PxScale::from(font_size),
 | |
|                     text: §ion.value,
 | |
|                 };
 | |
| 
 | |
|                 Ok(section)
 | |
|             })
 | |
|             .collect::<Result<Vec<_>, _>>()?;
 | |
| 
 | |
|         let section_glyphs = self
 | |
|             .brush
 | |
|             .compute_glyphs(§ions, bounds, text_alignment)?;
 | |
| 
 | |
|         if section_glyphs.is_empty() {
 | |
|             self.glyph_map.insert(
 | |
|                 id,
 | |
|                 TextLayoutInfo {
 | |
|                     glyphs: Vec::new(),
 | |
|                     size: Size::new(0., 0.),
 | |
|                 },
 | |
|             );
 | |
|             return Ok(());
 | |
|         }
 | |
| 
 | |
|         let mut min_x: f32 = std::f32::MAX;
 | |
|         let mut min_y: f32 = std::f32::MAX;
 | |
|         let mut max_x: f32 = std::f32::MIN;
 | |
|         let mut max_y: f32 = std::f32::MIN;
 | |
| 
 | |
|         for sg in section_glyphs.iter() {
 | |
|             let scaled_font = scaled_fonts[sg.section_index];
 | |
|             let glyph = &sg.glyph;
 | |
|             min_x = min_x.min(glyph.position.x);
 | |
|             min_y = min_y.min(glyph.position.y - scaled_font.ascent());
 | |
|             max_x = max_x.max(glyph.position.x + scaled_font.h_advance(glyph.id));
 | |
|             max_y = max_y.max(glyph.position.y - scaled_font.descent());
 | |
|         }
 | |
| 
 | |
|         let size = Size::new(max_x - min_x, max_y - min_y);
 | |
| 
 | |
|         let glyphs = self.brush.process_glyphs(
 | |
|             section_glyphs,
 | |
|             §ions,
 | |
|             font_atlas_set_storage,
 | |
|             fonts,
 | |
|             texture_atlases,
 | |
|             textures,
 | |
|         )?;
 | |
| 
 | |
|         self.glyph_map.insert(id, TextLayoutInfo { glyphs, size });
 | |
| 
 | |
|         Ok(())
 | |
|     }
 | |
| }
 |