diff --git a/tools/bdf-to-stm/.gitignore b/tools/bdf-to-stm/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..2f7896d1d1365eafb0da03d9fe456fac81408487 --- /dev/null +++ b/tools/bdf-to-stm/.gitignore @@ -0,0 +1 @@ +target/ diff --git a/tools/bdf-to-stm/Cargo.lock b/tools/bdf-to-stm/Cargo.lock new file mode 100644 index 0000000000000000000000000000000000000000..cf1054284a404e73b3aea01463c514d0f9790f04 --- /dev/null +++ b/tools/bdf-to-stm/Cargo.lock @@ -0,0 +1,50 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "bdf" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bit-set 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bdf-to-stm" +version = "0.1.0" +dependencies = [ + "bdf 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bit-set" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bit-vec 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bit-vec" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "either" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "itertools" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[metadata] +"checksum bdf 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a28b986e043da7dc2a39dc58940571c4da585cb2e222843c3e261fbe64435eb9" +"checksum bit-set 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "84527c7b0452f22545cc010e72d366a435561d2b28b978035550b3778c4d428d" +"checksum bit-vec 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a4523a10839ffae575fb08aa3423026c8cb4687eef43952afb956229d4f246f7" +"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" +"checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" diff --git a/tools/bdf-to-stm/Cargo.toml b/tools/bdf-to-stm/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..88dcb36f0cef95c26e3b84087f725d13d2a29f67 --- /dev/null +++ b/tools/bdf-to-stm/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "bdf-to-stm" +version = "0.1.0" +authors = ["meh"] +edition = "2018" + +[dependencies] +bdf = "0.5.3" +itertools = "0.8.0" diff --git a/tools/bdf-to-stm/README.md b/tools/bdf-to-stm/README.md new file mode 100644 index 0000000000000000000000000000000000000000..6430921252072e43f162e006c0a0959f4e62e202 --- /dev/null +++ b/tools/bdf-to-stm/README.md @@ -0,0 +1,6 @@ +Usage +===== + +```shell-session +$ cargo run -- gohufont < gohufont-11.bdf +``` diff --git a/tools/bdf-to-stm/src/main.rs b/tools/bdf-to-stm/src/main.rs new file mode 100644 index 0000000000000000000000000000000000000000..59592b499ecc9224ab42ed8ea32e4f13550ec2e4 --- /dev/null +++ b/tools/bdf-to-stm/src/main.rs @@ -0,0 +1,85 @@ +use bdf; +use itertools::Itertools; +use std::{env, error::Error, io, iter}; + +const CHARSET: &[char] = &[ + ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', + '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', + 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', + 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', +]; + +fn main() -> Result<(), Box<dyn Error>> { + let name = env::args().nth(1).expect("no font name provided"); + let font = bdf::read(io::stdin())?; + + println!("#include \"fonts.h\""); + println!("const uint8_t {name}_Table[] =", name = name); + println!("{{"); + + for (&ch, glyph) in CHARSET + .iter() + .map(|ch| (ch, font.glyphs().get(ch).unwrap())) + { + println!(); + println!( + "\t// @{codepoint} {ch:?} ({width} pixels wide)", + codepoint = ch as usize, + ch = ch, + width = glyph.width() + ); + + for y in 0..glyph.height() { + print!("\t"); + + let mut draw = String::new(); + + for bits in &iter::repeat(false) + .take(glyph.bounds().x as usize) + .chain((0..glyph.width()).map(|x| glyph.map().get(x, y))) + .chunks(8) + { + let mut bits = bits.collect::<Vec<_>>(); + if bits.len() < 8 { + for _ in 0..8 - bits.len() { + bits.push(false); + } + } + + let byte = bits + .into_iter() + .rev() + .enumerate() + .fold(0, |acc, (i, b)| acc | ((b as u8) << i)); + + draw.push_str(&format!("{1:00$b}", glyph.width() as usize, byte)); + + print!("0x{:02X}, ", byte); + } + + println!("//{}", draw.replace("1", "#").replace("0", " ")); + } + + // Print the right amount of empty lines. + for _ in 0..font.bounds().y.abs() + glyph.bounds().y { + for _ in 0..(glyph.width() + glyph.bounds().x as u32) / 8 { + print!("0x{:02X}, ", 0); + } + + println!(); + } + } + + println!("}};"); + println!(); + + println!( + "sFONT {name} = {{ {name}_Table, {width}, {height} }};", + name = name, + width = font.bounds().width, + height = font.bounds().height + ); + + Ok(()) +}