#![deny(missing_copy_implementations, missing_debug_implementations, missing_docs)]
#![no_std]
pub mod dict;
pub mod error;
pub mod glyphs;
pub mod index;
use tarrasque::{Extract, ExtractError, ExtractResult, Stream, extract};
use crate::dict::{Top};
use crate::error::{OFFSET_SIZE};
use crate::glyphs::{Glyphs};
use crate::index::{Index, Strings};
pub use crate::error::{CffError};
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct OffsetSize(pub u8);
impl<'s> Extract<'s, ()> for OffsetSize {
#[inline]
fn extract(stream: &mut Stream<'s>, _: ()) -> ExtractResult<'s, Self> {
let size: u8 = stream.extract(())?;
if size >= 1 && size <= 4 {
Ok(OffsetSize(size))
} else {
Err(ExtractError::Code(OFFSET_SIZE))
}
}
}
extract! {
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Header[4] {
pub major_version: u8 = [],
pub minor_version: u8 = [],
pub header_size: u8 = [],
pub offset_size: OffsetSize = [],
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Cff<'s> {
pub bytes: &'s [u8],
pub header: Header,
pub names: Index<'s, &'s str>,
pub tops: Index<'s, Top<'s>>,
pub strings: Strings<'s>,
pub subroutines: Index<'s, &'s [u8]>,
}
impl<'s> Cff<'s> {
#[inline]
pub fn parse(bytes: &'s [u8]) -> Result<Self, CffError<'s>> {
let mut stream = Stream(bytes);
let header: Header = stream.extract(())?;
let names: Index<&str> = stream.extract(())?;
let tops: Index<Top> = stream.extract(())?;
let strings: Strings = stream.extract(())?;
let subroutines: Index<&[u8]> = stream.extract(())?;
Ok(Cff { bytes, header, names, tops, strings, subroutines })
}
#[inline]
pub fn parse_glyphs(
&self, index: usize
) -> Option<Result<Glyphs<'s>, CffError<'s>>> {
self.tops.parse_object(index).map(|t| {
Glyphs::parse(&self.bytes, t?, self.subroutines)
})
}
}