use crate::{
catalog::MetadataStream, error::PdfResult, objects::Dictionary, pdf_enum, stream::Stream,
Resolve,
};
#[derive(Debug)]
struct EmbeddedFontDictionary {
length_one: Option<u32>,
length_two: Option<u32>,
length_three: Option<u32>,
metadata: Option<MetadataStream>,
}
impl EmbeddedFontDictionary {
pub fn from_dict(dict: &mut Dictionary, resolver: &mut dyn Resolve) -> PdfResult<Self> {
let length_one = dict.get_unsigned_integer("Length1", resolver)?;
let length_two = dict.get_unsigned_integer("Length2", resolver)?;
let length_three = dict.get_unsigned_integer("Length3", resolver)?;
let metadata = dict
.get_stream("Metadata", resolver)?
.map(|stream| MetadataStream::from_stream(stream, resolver))
.transpose()?;
Ok(Self {
length_one,
length_two,
length_three,
metadata,
})
}
}
#[derive(Debug)]
pub struct Type1FontFile {
dict: EmbeddedFontDictionary,
stream: Stream,
}
impl Type1FontFile {
pub fn from_stream(mut stream: Stream, resolver: &mut dyn Resolve) -> PdfResult<Self> {
let dict = EmbeddedFontDictionary::from_dict(&mut stream.dict.other, resolver)?;
Ok(Self { dict, stream })
}
}
#[derive(Debug)]
pub struct TrueTypeFontFile {
dict: EmbeddedFontDictionary,
stream: Stream,
}
impl TrueTypeFontFile {
pub fn from_stream(mut stream: Stream, resolver: &mut dyn Resolve) -> PdfResult<Self> {
let dict = EmbeddedFontDictionary::from_dict(&mut stream.dict.other, resolver)?;
Ok(Self { dict, stream })
}
}
#[derive(Debug)]
pub enum Type3FontFile {
CompactType1(CompactType1FontFile),
CompactType0Cid(CompactType0CidFontFile),
OpenType(OpenTypeFontFile),
}
#[derive(Debug)]
pub struct CompactType1FontFile {
dict: EmbeddedFontDictionary,
stream: Stream,
}
#[derive(Debug)]
pub struct CompactType0CidFontFile {
dict: EmbeddedFontDictionary,
stream: Stream,
}
#[derive(Debug)]
pub struct OpenTypeFontFile {
dict: EmbeddedFontDictionary,
stream: Stream,
}
pdf_enum!(
enum Type3Subtype {
Type1C = "Type1C",
CIDFontType0C = "CIDFontType0C",
OpenType = "OpenType",
}
);
impl Type3FontFile {
pub fn from_stream(mut stream: Stream, resolver: &mut dyn Resolve) -> PdfResult<Self> {
let subtype = Type3Subtype::from_str(&stream.dict.other.expect_name("Subtype", resolver)?)?;
Ok(match subtype {
Type3Subtype::Type1C => {
Self::CompactType1(CompactType1FontFile::from_stream(stream, resolver)?)
}
Type3Subtype::CIDFontType0C => {
Self::CompactType0Cid(CompactType0CidFontFile::from_stream(stream, resolver)?)
}
Type3Subtype::OpenType => {
Self::OpenType(OpenTypeFontFile::from_stream(stream, resolver)?)
}
})
}
}
impl CompactType1FontFile {
pub fn from_stream(mut stream: Stream, resolver: &mut dyn Resolve) -> PdfResult<Self> {
let dict = EmbeddedFontDictionary::from_dict(&mut stream.dict.other, resolver)?;
Ok(Self { dict, stream })
}
}
impl CompactType0CidFontFile {
pub fn from_stream(mut stream: Stream, resolver: &mut dyn Resolve) -> PdfResult<Self> {
let dict = EmbeddedFontDictionary::from_dict(&mut stream.dict.other, resolver)?;
Ok(Self { dict, stream })
}
}
impl OpenTypeFontFile {
pub fn from_stream(mut stream: Stream, resolver: &mut dyn Resolve) -> PdfResult<Self> {
let dict = EmbeddedFontDictionary::from_dict(&mut stream.dict.other, resolver)?;
Ok(Self { dict, stream })
}
}