1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
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<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(())
}
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();
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;
}
}
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;
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);
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})
}
}
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<dyn std::error::Error>> {
exec(
"assets/fonts/Galmuri11.ttf",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz2053:"
.chars()
.collect(),
"Galmuri",
)?;
exec(
"assets/fonts/CherryBombOne.ttf",
"UwUSpace".chars().collect(),
"CherryBombOne",
)?;
Ok(())
}
|