aboutsummaryrefslogblamecommitdiffstats
path: root/src/font.rs
blob: 0baa862f41497959762c1c0d6949791aab323155 (plain) (tree)
1
2
3
4
5
6
7
8
9
10

                        
                                                                                                                                                       
 
                                
                                                                             
                 


                                                                                 


                          


                                                                                                       
                     


                                                              
                                               

                                                           
                         


                                        

     
 



































                                                                         
use std::sync::LazyLock;

use sdl2::{pixels::{Color, PixelFormatEnum}, rect::Rect, render::{Texture, TextureCreator, TextureValueError}, surface::Surface, video::WindowContext};

pub struct RenderableCharacter {
  /** The width of the character, indicating where to break into a newline */
  pub width: u16,
  /** The height of the character, derived from data's length divided by width */
  pub height: u16,
  /** The raw alpha layer of the character */
  pub data: &'static [u8],
}
/**
 A trait describing a generated font.
 We use traits implemented by each font because it's somehow optimized better in preliminary testing(?)
*/
pub trait BakedFont {
  fn has_char(&self, character: char) -> bool;
  fn get_char_bytes(&self, character: char) -> &'static [u8];
  fn get_char(&self, character: char) -> RenderableCharacter {
    let bytes = self.get_char_bytes(character);
    let width = (bytes[0] as u16) | (bytes[1] as u16 >> 8);
    let data = &bytes[2..];
    RenderableCharacter {
      width,
      height: data.len() as u16 / width,
      data,
    }
  }
}
impl RenderableCharacter {
  /** Alpha value of colour is currently ignored! */
  pub fn to_surface(&self, colour: Color) -> Surface<'static> {
    let mut surface = Surface::new(
      self.width.into(),
      self.height.into(),
      PixelFormatEnum::RGBA32,
    )
    .unwrap();
    surface.with_lock_mut(|buffer: &mut [u8]| {
      let mut idx: usize = 0;
      print!("{} ({}x{})", self.data.len() * 4, self.width, self.height);
      for pixel in self.data {
        let index = idx * 4;
        buffer[index] = colour.r; // Red
        buffer[index + 1] = colour.g; // Green
        buffer[index + 2] = colour.b; // Blue
        buffer[index + 3] = *pixel; // Alpha
        idx += 1;
      }
    });
    surface
  }
  /** Colour Alpha Channel is ignored */
  pub fn to_texture<'a>(
    &self,
    texture_creator: &'a TextureCreator<WindowContext>,
    colour: Color,
  ) -> Result<Texture<'a>, TextureValueError> {
    let surface = self.to_surface(colour);
    surface.as_texture(texture_creator)
  }
  pub fn to_rect(&self, x: i32, y: i32) -> Rect {
    Rect::new(x, y, self.width.into(), self.height.into())
  }
}