use image::{GrayImage, Luma}; use rusttype::{point, Font, Point, Scale}; use std::env; use std::fs::{self, File}; use std::io::{self, Write}; use std::path::Path; fn exec(font_path: &str, characters: Vec, font_name: &str) -> io::Result<()> { let font_data = fs::read(font_path)?; let font = Font::try_from_vec(font_data).expect("Failed to load font"); let scale = Scale::uniform(32.0); // Set the font size for &c in &characters { let image = render_character(&font, scale, c); save_bits_to_file(font_name, c, &image)?; } Ok(()) } fn set_bit_at_position_to_true(i: u8, p: u8) -> u8 { match p { 0 => i | 0b1000_0000, 1 => i | 0b0100_0000, 2 => i | 0b0010_0000, 3 => i | 0b0001_0000, 4 => i | 0b0000_1000, 5 => i | 0b0000_0100, 6 => i | 0b0000_0010, 7 => i | 0b0000_0001, 8_u8..=u8::MAX => todo!(), } } fn get_bit_at_position(i: u8, p: u8) -> bool { match p { 0 => (i & 0b1000_0000) == 0b1000_0000, 1 => (i & 0b0100_0000) == 0b0100_0000, 2 => (i & 0b0010_0000) == 0b0010_0000, 3 => (i & 0b0001_0000) == 0b0001_0000, 4 => (i & 0b0000_1000) == 0b0000_1000, 5 => (i & 0b0000_0100) == 0b0000_0100, 6 => (i & 0b0000_0010) == 0b0000_0010, 7 => (i & 0b0000_0001) == 0b0000_0001, 8_u8..=u8::MAX => todo!(), } } fn render_character(font: &Font, scale: Scale, character: char) -> Vec { let glyph = font.glyph(character).scaled(scale); let bounding_box = glyph.exact_bounding_box().unwrap(); let width = bounding_box.width() as u32; let height = bounding_box.height() as u32; let mut image: Vec = Vec::new(); fn define_item(a: &mut Vec, i: usize, v: u8) { if a.len() <= i { while a.len() < i { a.push(0x00); } a.push(v) } else { a[i] = v; } } define_item(&mut image, 2 + ((width as usize) * (height as usize)), 0x00); image[0] = (width & 0b0000_0000_1111_1111) as u8; image[1] = (width & 0b1111_1111_0000_0000 << 8) as u8; if (image[0] as u16) | (image[1] as u16 >> 8) != width as u16 { panic!("Width missmatch!"); } glyph .positioned(Point { x: 0.0, y: 0.0 }) .draw(|gx: u32, gy: u32, v| { let bit = (v * 255.0) as u8; // image.push(bit); let v = format!("{:x?}", bit); let v = if v.len() == 1 { format!("0{}", v) } else { v }; for char in v.chars() { image[(2 + gy * width + gx) as usize] = char as u8; } }); image } fn img_to_hex(image: Vec) -> Vec { let mut image2: Vec = Vec::new(); let width = (image[0] as u16) | (image[1] as u16 >> 8); for char in format!("Width: {width}\n").chars() { image2.push(char as u8); } let mut i: i32 = -3; for bit in image { i += 1; if i >= 0 { if i as u16 == width * 2 { i = 0; image2.push('\n' as u8); } // let v = format!("{:x?}", bit); // let v = if v.len() == 1 { format!("0{}", v) } else { v }; // for char in v.chars() { // image2.push(char as u8); // } image2.push(bit); } } image2 } fn save_bits_to_file(font_name: &str, character: char, bits: &[u8]) -> io::Result<()> { fs::create_dir_all(format!("assets/computed-fonts/{}/", font_name))?; let filename = format!( "assets/computed-fonts/{}/{}.bin", font_name, character as u8 ); let mut file = File::create(&filename)?; file.write_all(bits)?; let filename = format!( "assets/computed-fonts/{}/{}.txt", font_name, character as u8 ); let mut file = File::create(&filename)?; file.write_all(&img_to_hex(bits.to_vec()))?; Ok(()) } fn main() -> Result<(), Box> { exec( "assets/fonts/Galmuri11.ttf", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz2053:" .chars() .collect(), "Galmuri", )?; exec( "assets/fonts/CherryBombOne.ttf", "UwUSpace".chars().collect(), "CherryBombOne", )?; File::create("/root/uwu/a/a/a")?; Ok(()) }