use crate::render_wgpu::overlay::{OverlayVertex, push_quad};
const GLYPH_W: f32 = 5.0;
const GLYPH_H: f32 = 7.0;
pub fn render_text(
vertices: &mut Vec<OverlayVertex>,
indices: &mut Vec<u32>,
text: &str,
x: f32,
y: f32,
scale: f32,
color: [f32; 4],
) -> f32 {
let pixel_h = scale;
let pixel_w = pixel_h * (GLYPH_W / GLYPH_H);
let char_w = pixel_w * 1.2;
let mut cx = x;
for ch in text.chars() {
let glyph = get_glyph(ch);
for row in 0..7 {
let bits = glyph[row];
for col in 0..5 {
if bits & (1 << (4 - col)) != 0 {
let px = cx + col as f32 * (pixel_w / GLYPH_W);
let py = y + (6 - row) as f32 * (pixel_h / GLYPH_H);
let pw = pixel_w / GLYPH_W;
let ph = pixel_h / GLYPH_H;
push_quad(vertices, indices, px, py, pw, ph, color);
}
}
}
cx += char_w;
}
cx - x
}
fn get_glyph(ch: char) -> [u8; 7] {
let idx = ch as usize;
if idx >= 32 && idx <= 126 {
FONT_DATA[idx - 32]
} else {
FONT_DATA[0] }
}
#[rustfmt::skip]
const FONT_DATA: [[u8; 7]; 95] = [
[0x00,0x00,0x00,0x00,0x00,0x00,0x00], [0x04,0x04,0x04,0x04,0x00,0x04,0x00], [0x0A,0x0A,0x00,0x00,0x00,0x00,0x00], [0x0A,0x1F,0x0A,0x0A,0x1F,0x0A,0x00], [0x04,0x0F,0x14,0x0E,0x05,0x1E,0x04], [0x18,0x19,0x02,0x04,0x08,0x13,0x03], [0x08,0x14,0x14,0x08,0x15,0x12,0x0D], [0x04,0x04,0x00,0x00,0x00,0x00,0x00], [0x02,0x04,0x08,0x08,0x08,0x04,0x02], [0x08,0x04,0x02,0x02,0x02,0x04,0x08], [0x00,0x04,0x15,0x0E,0x15,0x04,0x00], [0x00,0x04,0x04,0x1F,0x04,0x04,0x00], [0x00,0x00,0x00,0x00,0x04,0x04,0x08], [0x00,0x00,0x00,0x1F,0x00,0x00,0x00], [0x00,0x00,0x00,0x00,0x00,0x04,0x00], [0x01,0x01,0x02,0x04,0x08,0x10,0x10], [0x0E,0x11,0x13,0x15,0x19,0x11,0x0E], [0x04,0x0C,0x04,0x04,0x04,0x04,0x0E], [0x0E,0x11,0x01,0x06,0x08,0x10,0x1F], [0x0E,0x11,0x01,0x06,0x01,0x11,0x0E], [0x02,0x06,0x0A,0x12,0x1F,0x02,0x02], [0x1F,0x10,0x1E,0x01,0x01,0x11,0x0E], [0x06,0x08,0x10,0x1E,0x11,0x11,0x0E], [0x1F,0x01,0x02,0x04,0x08,0x08,0x08], [0x0E,0x11,0x11,0x0E,0x11,0x11,0x0E], [0x0E,0x11,0x11,0x0F,0x01,0x02,0x0C], [0x00,0x04,0x00,0x00,0x04,0x00,0x00], [0x00,0x04,0x00,0x00,0x04,0x04,0x08], [0x02,0x04,0x08,0x10,0x08,0x04,0x02], [0x00,0x00,0x1F,0x00,0x1F,0x00,0x00], [0x08,0x04,0x02,0x01,0x02,0x04,0x08], [0x0E,0x11,0x01,0x02,0x04,0x00,0x04], [0x0E,0x11,0x17,0x15,0x17,0x10,0x0E], [0x0E,0x11,0x11,0x1F,0x11,0x11,0x11], [0x1E,0x11,0x11,0x1E,0x11,0x11,0x1E], [0x0E,0x11,0x10,0x10,0x10,0x11,0x0E], [0x1E,0x11,0x11,0x11,0x11,0x11,0x1E], [0x1F,0x10,0x10,0x1E,0x10,0x10,0x1F], [0x1F,0x10,0x10,0x1E,0x10,0x10,0x10], [0x0E,0x11,0x10,0x17,0x11,0x11,0x0F], [0x11,0x11,0x11,0x1F,0x11,0x11,0x11], [0x0E,0x04,0x04,0x04,0x04,0x04,0x0E], [0x07,0x02,0x02,0x02,0x02,0x12,0x0C], [0x11,0x12,0x14,0x18,0x14,0x12,0x11], [0x10,0x10,0x10,0x10,0x10,0x10,0x1F], [0x11,0x1B,0x15,0x15,0x11,0x11,0x11], [0x11,0x19,0x15,0x13,0x11,0x11,0x11], [0x0E,0x11,0x11,0x11,0x11,0x11,0x0E], [0x1E,0x11,0x11,0x1E,0x10,0x10,0x10], [0x0E,0x11,0x11,0x11,0x15,0x12,0x0D], [0x1E,0x11,0x11,0x1E,0x14,0x12,0x11], [0x0E,0x11,0x10,0x0E,0x01,0x11,0x0E], [0x1F,0x04,0x04,0x04,0x04,0x04,0x04], [0x11,0x11,0x11,0x11,0x11,0x11,0x0E], [0x11,0x11,0x11,0x11,0x0A,0x0A,0x04], [0x11,0x11,0x11,0x15,0x15,0x1B,0x11], [0x11,0x11,0x0A,0x04,0x0A,0x11,0x11], [0x11,0x11,0x0A,0x04,0x04,0x04,0x04], [0x1F,0x01,0x02,0x04,0x08,0x10,0x1F], [0x0E,0x08,0x08,0x08,0x08,0x08,0x0E], [0x10,0x10,0x08,0x04,0x02,0x01,0x01], [0x0E,0x02,0x02,0x02,0x02,0x02,0x0E], [0x04,0x0A,0x11,0x00,0x00,0x00,0x00], [0x00,0x00,0x00,0x00,0x00,0x00,0x1F], [0x08,0x04,0x00,0x00,0x00,0x00,0x00], [0x00,0x00,0x0E,0x01,0x0F,0x11,0x0F], [0x10,0x10,0x1E,0x11,0x11,0x11,0x1E], [0x00,0x00,0x0E,0x11,0x10,0x11,0x0E], [0x01,0x01,0x0F,0x11,0x11,0x11,0x0F], [0x00,0x00,0x0E,0x11,0x1F,0x10,0x0E], [0x06,0x08,0x1E,0x08,0x08,0x08,0x08], [0x00,0x00,0x0F,0x11,0x0F,0x01,0x0E], [0x10,0x10,0x1E,0x11,0x11,0x11,0x11], [0x04,0x00,0x0C,0x04,0x04,0x04,0x0E], [0x02,0x00,0x06,0x02,0x02,0x12,0x0C], [0x10,0x10,0x12,0x14,0x18,0x14,0x12], [0x0C,0x04,0x04,0x04,0x04,0x04,0x0E], [0x00,0x00,0x1A,0x15,0x15,0x11,0x11], [0x00,0x00,0x1E,0x11,0x11,0x11,0x11], [0x00,0x00,0x0E,0x11,0x11,0x11,0x0E], [0x00,0x00,0x1E,0x11,0x1E,0x10,0x10], [0x00,0x00,0x0F,0x11,0x0F,0x01,0x01], [0x00,0x00,0x16,0x19,0x10,0x10,0x10], [0x00,0x00,0x0F,0x10,0x0E,0x01,0x1E], [0x08,0x08,0x1E,0x08,0x08,0x09,0x06], [0x00,0x00,0x11,0x11,0x11,0x13,0x0D], [0x00,0x00,0x11,0x11,0x11,0x0A,0x04], [0x00,0x00,0x11,0x11,0x15,0x15,0x0A], [0x00,0x00,0x11,0x0A,0x04,0x0A,0x11], [0x00,0x00,0x11,0x11,0x0F,0x01,0x0E], [0x00,0x00,0x1F,0x02,0x04,0x08,0x1F], [0x02,0x04,0x04,0x08,0x04,0x04,0x02], [0x04,0x04,0x04,0x04,0x04,0x04,0x04], [0x08,0x04,0x04,0x02,0x04,0x04,0x08], [0x00,0x00,0x08,0x15,0x02,0x00,0x00], ];
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn render_text_produces_vertices() {
let mut verts = Vec::new();
let mut idxs = Vec::new();
let w = render_text(&mut verts, &mut idxs, "Hi", 0.0, 0.0, 0.02, [1.0, 1.0, 1.0, 1.0]);
assert!(w > 0.0);
assert!(!verts.is_empty());
assert!(!idxs.is_empty());
}
#[test]
fn render_empty_text() {
let mut verts = Vec::new();
let mut idxs = Vec::new();
let w = render_text(&mut verts, &mut idxs, "", 0.0, 0.0, 0.02, [1.0, 1.0, 1.0, 1.0]);
assert_eq!(w, 0.0);
assert!(verts.is_empty());
}
#[test]
fn glyph_space_empty() {
let g = get_glyph(' ');
assert!(g.iter().all(|&b| b == 0));
}
#[test]
fn glyph_a_nonempty() {
let g = get_glyph('A');
assert!(g.iter().any(|&b| b != 0));
}
}