From f8645923617de3a5f2482ecbc0cfc0b3fbf535e5 Mon Sep 17 00:00:00 2001 From: gered Date: Sat, 11 Nov 2023 19:04:08 -0500 Subject: [PATCH] add methods to bitmask font/char structs to allow creation of new fonts --- ggdt/src/graphics/font.rs | 51 +++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/ggdt/src/graphics/font.rs b/ggdt/src/graphics/font.rs index 54db97d..f65d64d 100644 --- a/ggdt/src/graphics/font.rs +++ b/ggdt/src/graphics/font.rs @@ -21,6 +21,15 @@ pub enum FontError { #[error("Font I/O error")] IOError(#[from] std::io::Error), + + #[error("Invalid character dimensions")] + InvalidCharacterDimensions, + + #[error("Invalid number of characters")] + InvalidNumberOfCharacters, + + #[error("Invalid line height")] + InvalidLineHeight, } #[derive(Debug, Copy, Clone, Eq, PartialEq)] @@ -53,6 +62,16 @@ pub struct BitmaskCharacter { bounds: Rect, } +impl BitmaskCharacter { + pub fn new(bytes: [u8; CHAR_HEIGHT], width: usize) -> Result { + if width < 1 || width > CHAR_FIXED_WIDTH { + return Err(FontError::InvalidCharacterDimensions); + } + + Ok(BitmaskCharacter { bytes, bounds: Rect::new(0, 0, width as u32, CHAR_HEIGHT as u32) }) + } +} + impl Character for BitmaskCharacter { #[inline] fn bounds(&self) -> &Rect { @@ -116,6 +135,27 @@ impl BitmaskFont { BitmaskFont::load_from_bytes(&mut Cursor::new(VGA_FONT_BYTES)) } + pub fn new(characters: &[BitmaskCharacter], line_height: usize) -> Result { + if characters.len() != NUM_CHARS { + return Err(FontError::InvalidNumberOfCharacters); + } + if line_height < 1 || line_height > CHAR_HEIGHT { + return Err(FontError::InvalidLineHeight); + } + + let mut font = BitmaskFont { + characters: Box::from(characters), + line_height: line_height as u8, + space_width: characters[' ' as usize].bounds.width as u8, + }; + + for i in 0..NUM_CHARS { + font.characters[i].bounds.height = line_height as u32; + } + + Ok(font) + } + pub fn load_from_file(path: &Path) -> Result { let f = File::open(path)?; let mut reader = BufReader::new(f); @@ -145,17 +185,8 @@ impl BitmaskFont { // read global font height (used for rendering) let line_height = reader.read_u8()?; - for i in 0..NUM_CHARS { - characters[i].bounds.height = line_height as u32; - } - let space_width = characters[' ' as usize].bounds.width as u8; - - Ok(BitmaskFont { - characters: characters.into_boxed_slice(), // - line_height, - space_width, - }) + Self::new(&characters, line_height as usize) } pub fn to_file(&self, path: &Path) -> Result<(), FontError> {