1use std::fmt::Debug;
2
3use compact_str::CompactString;
4
5use crate::{Deserializer, FontAtlasDeserializationError, Glyph, Serializable};
6
7#[derive(PartialEq)]
13pub struct FontAtlasData {
14 pub font_name: CompactString,
16 pub font_size: f32,
18 pub texture_dimensions: (i32, i32, i32),
20 pub cell_size: (i32, i32),
22 pub underline: LineDecoration,
24 pub strikethrough: LineDecoration,
26 pub glyphs: Vec<Glyph>,
28 pub texture_data: Vec<u8>,
30}
31
32impl Debug for FontAtlasData {
33 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 f.debug_struct("FontAtlasData")
35 .field("font_name", &self.font_name)
36 .field("font_size", &self.font_size)
37 .field("texture_dimensions", &self.texture_dimensions)
38 .field("cell_size", &self.cell_size)
39 .field("glyphs_count", &self.glyphs.len())
40 .field("texture_data_kb", &(self.texture_data.len() * 4 / 1024))
41 .finish()
42 }
43}
44
45impl FontAtlasData {
46 pub const PADDING: i32 = 1;
47 pub const CELLS_PER_SLICE: i32 = 32;
48
49 pub fn from_binary(serialized: &[u8]) -> Result<Self, FontAtlasDeserializationError> {
50 let mut deserializer = Deserializer::new(serialized);
51 FontAtlasData::deserialize(&mut deserializer).map_err(|e| FontAtlasDeserializationError {
52 message: format!("Failed to deserialize font atlas: {}", e.message),
53 })
54 }
55
56 pub fn to_binary(&self) -> Vec<u8> {
57 self.serialize()
58 }
59
60 pub fn terminal_size(&self, viewport_width: i32, viewport_height: i32) -> (i32, i32) {
61 (
62 viewport_width / self.cell_size.0,
63 viewport_height / self.cell_size.1,
64 )
65 }
66
67 pub fn cell_size(&self) -> (i32, i32) {
68 self.cell_size
69 }
70}
71
72impl Default for FontAtlasData {
73 fn default() -> Self {
74 Self::from_binary(include_bytes!("../atlas/bitmap_font.atlas")).unwrap()
75 }
76}
77
78#[derive(Copy, Clone, Debug, PartialEq)]
79pub struct LineDecoration {
80 pub position: f32,
82 pub thickness: f32,
84}
85
86impl LineDecoration {
87 pub fn new(position: f32, thickness: f32) -> Self {
88 Self {
89 position: position.clamp(0.0, 1.0),
90 thickness: thickness.clamp(0.0, 1.0),
91 }
92 }
93}