1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
use crate::*; use riddle_font::ImgFont; use riddle_math::{Rect, SpacialNumericConversion, Vector2}; /// An efficient [`riddle_font::ImgFont`] renderer. /// /// Use [`crate::SpriteRenderArgs`] for access to all supported paramters when rendering /// sprites. /// /// # Example /// /// ```no_run /// # use riddle::{common::Color, image::*, platform::*, renderer::*, math::*, font::*, *}; /// # fn main() -> Result<(), RiddleError> { /// # let rdl = RiddleLib::new()?; /// # let window = WindowBuilder::new().build(rdl.context())?; /// let renderer = Renderer::new_from_window(&window)?; /// /// // Load a TTFont, generate an ImgFont, and then construct the SpriteFont with it /// let img_font: ImgFont = { /// let font_bytes = include_bytes!("../../example_assets/Roboto-Regular.ttf"); /// let ttfont = TTFont::load(&font_bytes[..])?; /// ImgFontGenerator::new("abcdefghijklmnopqrstuvwxyz ", 32).generate(&ttfont)? /// }; /// let sprite_font = SpriteFont::new(&renderer, img_font)?; /// /// // Render the sprite at the top left corner of the screen /// renderer.render(|render_ctx| { /// render_ctx.clear(Color::WHITE); /// sprite_font.render( /// render_ctx, /// &SpriteRenderArgs::new([0.0, 0.0]).with_color(Color::BLACK), /// "hello world", /// ) /// })?; /// # Ok(()) } /// ``` pub struct SpriteFont<R: CommonRenderer> { sprite: R::Sprite, font: ImgFont, } impl<R: CommonRenderer> SpriteFont<R> { /// Build a SpriteFont from the ImgFont given. The ImgFont's image will get loaded in to a /// texture, and its glyph information will be used for layout. pub fn new(renderer: &R, font: ImgFont) -> Result<Self> { let sprite = R::Sprite::new_from_image( renderer, font.image(), &SpriteInitArgs { min_filter: FilterMode::Linear, mag_filter: FilterMode::Linear, }, )?; Ok(Self { sprite, font }) } pub fn render<Ctx: RenderContext<R> + ?Sized>( &self, render_ctx: &mut Ctx, render_args: &SpriteRenderArgs, text: &str, ) -> std::result::Result<(), RendererError> { let mut parts: Vec<(Rect<f32>, Vector2<f32>)> = Vec::with_capacity(text.len()); self.font.layout(text, |_, rect, location| { parts.push((rect.clone().convert(), location.convert())); }); self.sprite .render_regions(render_ctx, render_args, &parts[..]) } }