84 lines
2.8 KiB
Rust
84 lines
2.8 KiB
Rust
|
use std::{
|
||
|
env,
|
||
|
fs::File,
|
||
|
io::{stdin, stdout, IsTerminal, Read, Write},
|
||
|
ops::Neg,
|
||
|
os::unix::process::CommandExt,
|
||
|
path::Path,
|
||
|
process::{exit, Command},
|
||
|
};
|
||
|
|
||
|
// takes all charaters in bdf and returns a vec of each character row byte in order, normalized to
|
||
|
// width & height of the font (only works with 8 or fewer pixel wide fonts, should work for any height)
|
||
|
fn bdf_to_bitmap(mut bdf: File) -> [u8; 0x8000] {
|
||
|
let mut bdf_font_bytes = Vec::new();
|
||
|
bdf.read_to_end(&mut bdf_font_bytes).unwrap();
|
||
|
|
||
|
let bdf_font = bdf_parser::BdfFont::parse(&bdf_font_bytes).unwrap();
|
||
|
let mut bdf_vec = vec![];
|
||
|
for glyph in bdf_font.glyphs.iter() {
|
||
|
let glyph_offset_x = glyph.bounding_box.offset.x;
|
||
|
let glyph_offset_y = glyph.bounding_box.offset.y;
|
||
|
let glyph_height = glyph.bounding_box.size.y;
|
||
|
let font_height = bdf_font.metadata.bounding_box.size.y;
|
||
|
let font_offset_y = bdf_font.metadata.bounding_box.offset.y;
|
||
|
|
||
|
let top_space = font_height + font_offset_y - glyph_height - glyph_offset_y;
|
||
|
for _ in 0..top_space {
|
||
|
bdf_vec.push(0x00);
|
||
|
}
|
||
|
for bitmap in glyph.bitmap.iter() {
|
||
|
bdf_vec.push(bitmap >> glyph_offset_x);
|
||
|
}
|
||
|
|
||
|
let bottom_space = font_offset_y.neg() + glyph_offset_y;
|
||
|
for _ in 0..bottom_space {
|
||
|
bdf_vec.push(0x00);
|
||
|
}
|
||
|
}
|
||
|
let height = bdf_font.metadata.bounding_box.size.y as usize;
|
||
|
reorder_bitmap(&bdf_vec, height)
|
||
|
}
|
||
|
|
||
|
// takes an vec of ordered characters and translates them for use with the character rom
|
||
|
// TODO: make this work for any arbitrary char rom pin format using some kinda interface
|
||
|
fn reorder_bitmap(bitmap: &[u8], font_height: usize) -> [u8; 0x8000] {
|
||
|
let mut rom = [0; 0x8000]; // create vec the size of character rom
|
||
|
|
||
|
for row in 0..font_height {
|
||
|
for ascii_address in 0..u8::MAX {
|
||
|
// first 8 bits of address pick character
|
||
|
// next 5 bits pick row
|
||
|
// TODO: final 2 pick character set
|
||
|
let byte = bitmap[ascii_address as usize * font_height + row];
|
||
|
let rom_index: u16 = ((row as u16) << 8) + ascii_address as u16;
|
||
|
rom[rom_index as usize] = byte;
|
||
|
}
|
||
|
}
|
||
|
rom
|
||
|
}
|
||
|
|
||
|
fn rom_from_file<P>(path: P) -> [u8; 0x8000]
|
||
|
where
|
||
|
P: AsRef<Path>,
|
||
|
{
|
||
|
let file = File::open(path).unwrap();
|
||
|
bdf_to_bitmap(file)
|
||
|
}
|
||
|
|
||
|
fn main() {
|
||
|
let mut regen_font = Command::new("regen-font.sh");
|
||
|
let mut cleanup = Command::new("cleanup.sh");
|
||
|
|
||
|
regen_font.exec();
|
||
|
|
||
|
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||
|
let dest_path = Path::new(&out_dir).join("cozette.rom");
|
||
|
|
||
|
let cozette_rom_bytes = rom_from_file("build/cozette.bdf");
|
||
|
let mut cozette_rom = File::create(dest_path).unwrap();
|
||
|
cozette_rom.write_all(&cozette_rom_bytes).unwrap();
|
||
|
|
||
|
cleanup.exec();
|
||
|
}
|