aboutsummaryrefslogtreecommitdiffstats
path: root/build.rs
diff options
context:
space:
mode:
authorLibravatarLarge Libravatar memdmp <memdmpmemewarenet>2025-01-11 23:23:43 +0100
committerLibravatarLarge Libravatar memdmp <memdmpmemewarenet>2025-01-11 23:23:43 +0100
commitf5152a1e36f7e765f5894370fead0d5602894f8b (patch)
tree6ffca13cc4f0e4246e77bb77f66fbb066fd239c5 /build.rs
parent9367f608f9ba67b0031a7f08b58cc6cc843b8c79 (diff)
downloadcosin25-invite-mountainbytes-f5152a1e36f7e765f5894370fead0d5602894f8b.tar.gz
cosin25-invite-mountainbytes-f5152a1e36f7e765f5894370fead0d5602894f8b.tar.bz2
cosin25-invite-mountainbytes-f5152a1e36f7e765f5894370fead0d5602894f8b.tar.lz
cosin25-invite-mountainbytes-f5152a1e36f7e765f5894370fead0d5602894f8b.zip

feat: code generation :3

Diffstat (limited to 'build.rs')
-rw-r--r--build.rs213
1 files changed, 127 insertions, 86 deletions
diff --git a/build.rs b/build.rs
index a6a53d2..3a4b452 100644
--- a/build.rs
+++ b/build.rs
@@ -1,112 +1,153 @@
-use image::{GrayImage, Luma};
-use rusttype::{point, Font, Point, Scale};
-use std::env;
+use rusttype::{Font, Point, Scale};
use std::fs::{self, File};
use std::io::{self, Write};
-use std::path::Path;
-fn exec(font_path: &str, characters: Vec<char>, 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(())
+#[derive(Clone)]
+struct FontMetadata {
+ pub charset: &'static str,
+ pub name: &'static str,
+ pub font: Font<'static>,
}
+impl FontMetadata {
+ pub fn render_character(&self, scale: Scale, character: char) -> Vec<u8> {
+ let glyph = self.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;
-fn render_character(font: &Font, scale: Scale, character: char) -> Vec<u8> {
- 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<u8> = Vec::new();
- let mut image: Vec<u8> = Vec::new();
-
- fn define_item(a: &mut Vec<u8>, i: usize, v: u8) {
- if a.len() <= i {
- while a.len() < i {
- a.push(0x00);
+ fn define_item(a: &mut Vec<u8>, i: usize, v: u8) {
+ if a.len() <= i {
+ while a.len() < i {
+ a.push(0x00);
+ }
+ a.push(v)
+ } else {
+ a[i] = v;
}
- a.push(v)
- } else {
- a[i] = v;
}
- }
- define_item(&mut image, 2 + ((width as usize) * (height as usize)), 0x00);
+ 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!");
- }
+ 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;
- if gx < width {
- define_item(&mut image, (2 + (gy * width) + gx) as usize, bit);
- }
- });
- image
-}
-fn img_to_hex(image: Vec<u8>) -> Vec<u8> {
- let mut image2: Vec<u8> = Vec::new();
- let width = (image[0] as u16) | (image[1] as u16 >> 8);
+ glyph
+ .positioned(Point { x: 0.0, y: 0.0 })
+ .draw(|gx: u32, gy: u32, v| {
+ let bit = (v * 255.0) as u8;
+ if gx < width {
+ define_item(&mut image, (2 + (gy * width) + gx) as usize, bit);
+ }
+ });
+ image
+ }
+ pub fn img_to_hex(image: Vec<u8>) -> Vec<u8> {
+ let mut image2: Vec<u8> = Vec::new();
+ let width = (image[0] as u16) | (image[1] as u16 >> 8);
- let mut i: i32 = -3;
- for bit in image {
- i += 1;
- if i >= 0 {
- if i as u16 == width {
- i = 0;
- image2.push('\n' as u8);
+ let mut i: i32 = -3;
+ for bit in image {
+ i += 1;
+ if i >= 0 {
+ if i as u16 == width {
+ 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(if bit < 80 {' ' as u8} else if bit < 150 {'-' as u8} else {'#' 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
+ }
+ fn unique_chars(&self) -> Vec<char> {
+ let mut v: Vec<char> = Vec::new();
+ for char in self.charset.chars() {
+ if !v.contains(&char) {
+ v.push(char);
}
- // image2.push(if bit < 80 {' ' as u8} else if bit < 150 {'-' as u8} else {'#' as u8})
}
+ v
}
- 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
- );
+fn exec(font: FontMetadata) -> io::Result<()> {
+ let scale = Scale::uniform(32.0); // Set the font size
+
+ for c in font.unique_chars() {
+ let image = font.render_character(scale, c);
+ save_bits_to_file(&font, c as u8, &image)?;
+ }
+
+ Ok(())
+}
+
+fn save_bits_to_file(font: &FontMetadata, char: u8, bits: &[u8]) -> io::Result<()> {
+ fs::create_dir_all(format!("assets/computed-fonts/{}/", font.name))?;
+ let filename = format!("assets/computed-fonts/{}/{}.bin", font.name, char);
let mut file = File::create(&filename)?;
file.write_all(bits)?;
- let filename = format!(
- "assets/computed-fonts/{}/{}.txt",
- font_name, character as u8
- );
+ let filename = format!("assets/computed-fonts/{}/{}.txt", font.name, char);
let mut file = File::create(&filename)?;
- file.write_all(&img_to_hex(bits.to_vec()))?;
+ file.write_all(&FontMetadata::img_to_hex(bits.to_vec()))?;
Ok(())
}
+fn generate_struct(font: &FontMetadata) -> io::Result<String> {
+ let name = font.name;
+ let mut contents = format!(
+ "pub struct {name} {{}}
+impl {name} {{}}
+impl BakedFont for {name} {{
+ fn get_char(c: char) -> &'static [u8] {{
+ match c as u8 {{
+"
+ );
+ for char in font.unique_chars() {
+ contents = format!(
+ "{contents} {} => include_bytes!(\"../../assets/computed-fonts/{}/{}.bin\"),
+",
+ char as u8, font.name, char as u8
+ );
+ }
+ contents = format!(
+ "{contents} _ => panic!(\"Glyph {{}} not included in precomputed fonts\", c)
+ }}
+ }}
+}}
+"
+ );
+ Ok(contents)
+}
fn main() -> Result<(), Box<dyn std::error::Error>> {
- exec(
- "assets/fonts/Galmuri11.ttf",
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz2053:"
- .chars()
- .collect(),
- "Galmuri",
- )?;
- exec(
- "assets/fonts/CherryBombOne.ttf",
- "UwUSpace".chars().collect(),
- "CherryBombOne",
- )?;
+ fs::create_dir_all("src/generated")?;
+ let mut modrs = format!("// Copyright is a sham this is a @generated file.
+use crate::font::BakedFont;
+");
+ let fonts = [
+ FontMetadata {
+ name: "Galmuri",
+ font: { Font::try_from_vec(fs::read("assets/fonts/Galmuri11.ttf")?).unwrap() },
+ charset: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz2053:",
+ },
+ FontMetadata {
+ name: "CherryBombOne",
+ font: { Font::try_from_vec(fs::read("assets/fonts/CherryBombOne.ttf")?).unwrap() },
+ charset: "UwUSpace",
+ },
+ ];
+ for font in fonts {
+ modrs=format!("{modrs}{}
+",generate_struct(&font)?);
+ exec(font)?;
+ }
+ File::create(&"src/generated/fonts.rs")?.write_all(modrs.as_bytes())?;
Ok(())
}