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
use rusttype; pub type Font = rusttype::Font<'static>; pub struct Text { pub bytes: Vec<u8>, pub size: (u32, u32), } impl Text { pub fn new(text: &str, font: &Font, height: f32) -> Self { let scale = rusttype::Scale::uniform(height); let offset = rusttype::point(0.0, font.v_metrics(scale).ascent); let glyphs: Vec<_> = font.layout(text, scale, offset).collect(); let width = glyphs.last().unwrap().pixel_bounding_box().unwrap().max.x; let height = height.ceil(); let size = (width as u32, height as u32); let bytes = Text::render(&glyphs, size); Self { bytes, size } } fn render(glyphs: &[rusttype::PositionedGlyph], size: (u32, u32)) -> Vec<u8> { let width = size.0 as usize; let height = size.1 as usize; let mut bytes = vec![0_u8; 4 * width * height]; let mapping_scale = 255.0; for glyph in glyphs.iter() { if let Some(bbox) = glyph.pixel_bounding_box() { glyph.draw(|x, y, alpha| { let alpha = (alpha * mapping_scale + 0.5) as u8; let x = x as i32 + bbox.min.x; let y = y as i32 + bbox.min.y; if alpha > 0 && x >= 0 && x < width as i32 && y >= 0 && y < height as i32 { let i = (x as usize + y as usize * width) * 4; bytes[i] = 255; bytes[i + 1] = 255; bytes[i + 2] = 255; bytes[i + 3] = alpha; } }); } } bytes } }