const FONT_DATA: &'static [u8] = include_bytes!("../font6x8_1bpp.raw");
pub(crate) fn character_pixel(c: char, x: u32, y: u32) -> bool {
let char_per_row = 240 / 6;
let char_offset = char_offset(c);
let row = char_offset / char_per_row;
let char_x = (char_offset - (row * char_per_row)) * 6;
let char_y = row * 8;
let bitmap_bit_index = char_x + x + ((char_y + y) * 240);
let bitmap_byte = bitmap_bit_index / 8;
let bitmap_bit = 7 - (bitmap_bit_index % 8);
FONT_DATA[bitmap_byte as usize] & (1 << bitmap_bit) != 0
}
fn char_offset(c: char) -> u32 {
let fallback = '?' as u32 - ' ' as u32;
if c < ' ' {
return fallback;
}
if c <= '~' {
return c as u32 - ' ' as u32;
}
if c < '¡' || c > 'ÿ' {
return fallback;
}
c as u32 - ' ' as u32 - 34
}
fn blit_text(text: &str) -> Vec<u8> {
let mut data: Vec<u8> = Vec::with_capacity(text.len() * 2 * 6 * 8);
for y in 0..8 {
for x in 0..6 * text.len() {
let is_set = character_pixel(text.as_bytes()[x / 6] as char, (x % 6) as u32, y);
data.push(if is_set { 0u8 } else { 255u8 }); data.push(if is_set { 255u8 } else { 0u8 }); }
}
data
}
pub fn blit_text_span(x: f64, y: f64, text: &str) -> usvg::Image {
let data: Vec<u8> = blit_text(text);
let mut out: Vec<u8> = Vec::with_capacity(512);
let mut encoder = png::Encoder::new(&mut out, (text.len() * 6) as u32, 8);
encoder.set_color(png::ColorType::GrayscaleAlpha);
encoder.set_depth(png::BitDepth::Eight);
let mut writer = encoder.write_header().unwrap();
writer.write_image_data(&data).unwrap();
drop(writer);
usvg::Image {
id: "".to_string(),
transform: usvg::Transform::new_translate(x, y),
view_box: usvg::ViewBox {
rect: usvg::Rect::new(0., 0., text.len() as f64, 1.0).unwrap(),
aspect: usvg::AspectRatio::default(),
},
visibility: usvg::Visibility::Visible,
rendering_mode: usvg::ImageRendering::OptimizeSpeed,
kind: usvg::ImageKind::PNG(out),
}
}