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 = 16;
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 (viewport_width / self.cell_size.0, viewport_height / self.cell_size.1)
62 }
63
64 pub fn cell_size(&self) -> (i32, i32) {
65 self.cell_size
66 }
67}
68
69impl Default for FontAtlasData {
70 fn default() -> Self {
71 Self::from_binary(include_bytes!("../atlas/bitmap_font.atlas")).unwrap()
72 }
73}
74
75#[derive(Copy, Clone, Debug, PartialEq)]
76pub struct LineDecoration {
77 pub(super) position: f32,
79 pub(super) thickness: f32,
81}
82
83impl LineDecoration {
84 pub fn new(position: f32, thickness: f32) -> Self {
85 Self {
86 position: position.clamp(0.0, 1.0),
87 thickness: thickness.clamp(0.0, 1.0),
88 }
89 }
90}