60 lines
1.6 KiB
Rust
60 lines
1.6 KiB
Rust
use serde_json::Value;
|
|
|
|
const FONT_5X7_JSON: &str = include_str!("../../assets/fonts/5x7.json");
|
|
|
|
pub struct Font {
|
|
// pub name: String,
|
|
// pub font_json: String,
|
|
pub font_parsed: Value,
|
|
}
|
|
|
|
/// Return the embedded font JSON by string key
|
|
pub fn get_font_json(name: &str) -> Option<&'static str> {
|
|
match name {
|
|
"5x7" => Some(FONT_5X7_JSON),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
impl Font {
|
|
pub fn new(name: &str) -> Self {
|
|
let font_json = get_font_json(name)
|
|
.unwrap_or_else(|| panic!("Unknown font: {}", name))
|
|
.to_string();
|
|
|
|
let font_parsed: Value = serde_json::from_str(&font_json).unwrap();
|
|
|
|
return Self {
|
|
// name: name.to_string(),
|
|
// font_json,
|
|
font_parsed,
|
|
};
|
|
}
|
|
|
|
pub fn get_char_bitmap(&self, index: u64) -> Option<Vec<Vec<u8>>> {
|
|
let bytes = self
|
|
.font_parsed
|
|
.get("data")?
|
|
.as_array()?
|
|
.iter()
|
|
.find(|entry| entry.get("n").map_or(false, |n| n == index))
|
|
.and_then(|character| {
|
|
character.get("b")?.as_array().map(|arr| {
|
|
arr.iter()
|
|
.filter_map(|val| val.as_u64())
|
|
.map(|n| n as u8)
|
|
.collect::<Vec<u8>>()
|
|
})
|
|
})?;
|
|
|
|
let bits = bytes
|
|
.iter()
|
|
.flat_map(|&byte| (0..8).rev().map(move |i| (byte >> i) & 1))
|
|
.collect::<Vec<u8>>();
|
|
|
|
let char_matrix = bits.chunks(5).map(|chunk| chunk.to_vec()).collect();
|
|
|
|
Some(char_matrix)
|
|
}
|
|
}
|