use std::fmt::Debug;
use compact_str::CompactString;
use crate::{CellSize, Deserializer, Glyph, Serializable, SerializationError};
#[derive(Clone, PartialEq)]
pub struct FontAtlasData {
pub(crate) font_name: CompactString,
pub(crate) font_size: f32,
pub(crate) max_halfwidth_base_glyph_id: u16,
pub(crate) texture_dimensions: (i32, i32, i32),
pub(crate) cell_size: CellSize,
pub(crate) underline: LineDecoration,
pub(crate) strikethrough: LineDecoration,
pub(crate) glyphs: Vec<Glyph>,
pub(crate) texture_data: Vec<u8>,
}
impl Debug for FontAtlasData {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("FontAtlasData")
.field("font_name", &self.font_name)
.field("font_size", &self.font_size)
.field("texture_dimensions", &self.texture_dimensions)
.field("cell_size", &self.cell_size)
.field("glyphs_count", &self.glyphs.len())
.field("texture_data_kb", &(self.texture_data.len() / 1024))
.finish()
}
}
impl FontAtlasData {
pub const PADDING: i32 = 1;
pub const CELLS_PER_SLICE: i32 = 32;
#[allow(clippy::too_many_arguments)]
#[must_use]
pub fn new(
font_name: CompactString,
font_size: f32,
max_halfwidth_base_glyph_id: u16,
texture_dimensions: (i32, i32, i32),
cell_size: CellSize,
underline: LineDecoration,
strikethrough: LineDecoration,
glyphs: Vec<Glyph>,
texture_data: Vec<u8>,
) -> Self {
Self {
font_name,
font_size,
max_halfwidth_base_glyph_id,
texture_dimensions,
cell_size,
underline,
strikethrough,
glyphs,
texture_data,
}
}
#[inline]
#[must_use]
pub fn font_name(&self) -> &str {
&self.font_name
}
#[inline]
#[must_use]
pub fn font_size(&self) -> f32 {
self.font_size
}
#[inline]
#[must_use]
pub fn max_halfwidth_base_glyph_id(&self) -> u16 {
self.max_halfwidth_base_glyph_id
}
#[inline]
#[must_use]
pub fn texture_dimensions(&self) -> (i32, i32, i32) {
self.texture_dimensions
}
#[inline]
#[must_use]
pub fn underline(&self) -> LineDecoration {
self.underline
}
#[inline]
#[must_use]
pub fn strikethrough(&self) -> LineDecoration {
self.strikethrough
}
#[inline]
#[must_use]
pub fn glyphs(&self) -> &[Glyph] {
&self.glyphs
}
#[inline]
#[must_use]
pub fn texture_data(&self) -> &[u8] {
&self.texture_data
}
#[must_use]
pub fn into_glyphs(self) -> Vec<Glyph> {
self.glyphs
}
pub fn from_binary(serialized: &[u8]) -> Result<Self, SerializationError> {
let mut deserializer = Deserializer::new(serialized);
FontAtlasData::deserialize(&mut deserializer)
}
pub fn to_binary(&self) -> Result<Vec<u8>, SerializationError> {
self.serialize()
}
#[must_use]
pub fn terminal_size(&self, viewport_width: i32, viewport_height: i32) -> (i32, i32) {
(
viewport_width / self.cell_size.width,
viewport_height / self.cell_size.height,
)
}
#[must_use]
pub fn cell_size(&self) -> CellSize {
self.cell_size
}
}
impl Default for FontAtlasData {
fn default() -> Self {
Self::from_binary(include_bytes!("../atlas/bitmap_font.atlas")).unwrap()
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct LineDecoration {
pub(crate) position: f32,
pub(crate) thickness: f32,
}
impl LineDecoration {
#[must_use]
pub fn new(position: f32, thickness: f32) -> Self {
Self {
position: position.clamp(0.0, 1.0),
thickness: thickness.clamp(0.0, 1.0),
}
}
#[inline]
#[must_use]
pub fn position(&self) -> f32 {
self.position
}
#[inline]
#[must_use]
pub fn thickness(&self) -> f32 {
self.thickness
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DebugSpacePattern {
OnePixel,
TwoByTwo,
}