use rusttype::{ Font, Scale, point, PositionedGlyph };
pub struct FontRenderer {
font: Font<'static>,
}
impl FontRenderer {
pub fn new(font_data: Vec<u8>) -> Self {
let font_data = font_data.into_boxed_slice();
let font_data: &'static [u8] = Box::leak(font_data);
let font = Font::try_from_bytes(font_data).expect("Error constructing Font");
Self { font }
}
pub fn render_text(&self, text: &str, scale: f32) -> Vec<PositionedGlyph<'static>> {
let scale = Scale::uniform(scale * 0.75);
let v_metrics = self.font.v_metrics(scale);
let offset = point(0.0, v_metrics.ascent);
self.font.layout(text, scale, offset).collect()
}
pub fn calculate_text_size(&self, text: &str, scale: f32) -> (f32, f32) {
let scale = Scale::uniform(scale * 0.75);
let v_metrics = self.font.v_metrics(scale);
let glyphs: Vec<_> = self.font.layout(text, scale, point(0.0, v_metrics.ascent)).collect();
if glyphs.is_empty() {
return (0.0, 0.0);
}
let min_x = glyphs
.first()
.and_then(|g| g.pixel_bounding_box())
.map(|bb| bb.min.x as f32)
.unwrap_or(0.0);
let max_x = glyphs
.last()
.and_then(|g| g.pixel_bounding_box())
.map(|bb| bb.max.x as f32)
.unwrap_or(0.0);
let width = max_x - min_x;
let height = v_metrics.ascent - v_metrics.descent;
(width, height.abs())
}
}