79 lines
2.1 KiB
Rust
79 lines
2.1 KiB
Rust
use mammoth::debug;
|
|
use mammoth::zion::ZError;
|
|
use victoriafalls::file::File;
|
|
|
|
const MAGIC_HEADER: u32 = 0x864AB572;
|
|
|
|
#[repr(C)]
|
|
struct PsfHeader {
|
|
magic: u32, /* magic bytes to identify PSF */
|
|
version: u32, /* zero */
|
|
headersize: u32, /* offset of bitmaps in file, 32 */
|
|
flags: u32, /* 0 if there's no unicode table */
|
|
numglyph: u32, /* number of glyphs */
|
|
bytes_per_glyph: u32, /* size of each glyph */
|
|
height: u32, /* height in pixels */
|
|
width: u32, /* width in pixels */
|
|
}
|
|
|
|
pub struct Psf {
|
|
file: File,
|
|
header: &'static PsfHeader,
|
|
}
|
|
|
|
impl Psf {
|
|
pub fn new(path: &str) -> Result<Self, ZError> {
|
|
let file = File::open(&path)?;
|
|
|
|
let header = file.slice()[0..core::mem::size_of::<PsfHeader>()]
|
|
.as_ptr()
|
|
.cast();
|
|
let psf = Self {
|
|
file,
|
|
header: unsafe { &*header },
|
|
};
|
|
|
|
psf.validate()?;
|
|
|
|
Ok(psf)
|
|
}
|
|
|
|
fn validate(&self) -> Result<(), ZError> {
|
|
if self.header.magic != MAGIC_HEADER {
|
|
debug!("PSF: Magic value: {:x}", self.header.magic);
|
|
return Err(ZError::INVALID_ARGUMENT);
|
|
}
|
|
|
|
if self.header.version != 0 {
|
|
debug!("PSF non-zero version");
|
|
return Err(ZError::INVALID_ARGUMENT);
|
|
}
|
|
|
|
if self.header.height != 0x10 {
|
|
debug!("PSF height other than 16 not handled");
|
|
return Err(ZError::UNIMPLEMENTED);
|
|
}
|
|
|
|
if self.header.width != 0x8 {
|
|
debug!("PSF width other than 8 not handled");
|
|
return Err(ZError::UNIMPLEMENTED);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
pub fn glyph(&self, index: u32) -> &[u8] {
|
|
let offset: usize =
|
|
(self.header.headersize + (index * self.header.bytes_per_glyph)) as usize;
|
|
let len: usize = self.header.bytes_per_glyph as usize;
|
|
&self.file.slice()[offset..offset + len]
|
|
}
|
|
|
|
pub fn width(&self) -> u32 {
|
|
self.header.width
|
|
}
|
|
|
|
pub fn height(&self) -> u32 {
|
|
self.header.height
|
|
}
|
|
}
|