use std::collections::HashMap;
use crate::{
assert_empty, error::PdfResult, font::Font, objects::Dictionary, pdf_enum,
shading::ShadingObject, xobject::XObject, Resolve,
};
use self::{graphics_state_parameters::GraphicsStateParameters, pattern::Pattern};
pub mod graphics_state_parameters;
pub mod pattern;
#[derive(Debug)]
pub struct Resources {
ext_g_state: Option<HashMap<String, GraphicsStateParameters>>,
color_space: Option<Dictionary>,
pattern: Option<HashMap<String, Pattern>>,
shading: Option<HashMap<String, ShadingObject>>,
xobject: Option<HashMap<String, XObject>>,
font: Option<HashMap<String, Font>>,
proc_set: Option<Vec<ProcedureSet>>,
properties: Option<Dictionary>,
}
impl Resources {
pub(crate) fn from_dict(mut dict: Dictionary, resolver: &mut dyn Resolve) -> PdfResult<Self> {
let ext_g_state = dict
.get_dict("ExtGState", resolver)?
.map(|dict| {
dict.entries()
.map(|(key, value)| {
let dict = resolver.assert_dict(value)?;
let graphics = GraphicsStateParameters::from_dict(dict, resolver)?;
Ok((key, graphics))
})
.collect::<PdfResult<HashMap<String, GraphicsStateParameters>>>()
})
.transpose()?;
let color_space = dict.get_dict("ColorSpace", resolver)?;
let pattern = dict
.get_dict("Pattern", resolver)?
.map(|dict| {
dict.entries()
.map(|(key, obj)| Ok((key, Pattern::from_object(obj, resolver)?)))
.collect::<PdfResult<HashMap<String, Pattern>>>()
})
.transpose()?;
let shading = dict
.get_dict("Shading", resolver)?
.map(|dict| {
dict.entries()
.map(|(key, obj)| Ok((key, ShadingObject::from_obj(obj, resolver)?)))
.collect::<PdfResult<HashMap<String, ShadingObject>>>()
})
.transpose()?;
let xobject = dict
.get_dict("XObject", resolver)?
.map(|dict| {
dict.entries()
.map(|(key, obj)| {
Ok((
key,
XObject::from_stream(resolver.assert_stream(obj)?, resolver)?,
))
})
.collect::<PdfResult<HashMap<String, XObject>>>()
})
.transpose()?;
let font = dict
.get_dict("Font", resolver)?
.map(|dict| {
dict.entries()
.map(|(key, obj)| {
Ok((key, Font::from_dict(resolver.assert_dict(obj)?, resolver)?))
})
.collect::<PdfResult<HashMap<String, Font>>>()
})
.transpose()?;
let proc_set = dict
.get_arr("ProcSet", resolver)?
.or(dict.get_arr("ProcSets", resolver)?)
.map(|proc| {
proc.into_iter()
.map(|proc| ProcedureSet::from_str(&resolver.assert_name(proc)?))
.collect::<PdfResult<Vec<ProcedureSet>>>()
})
.transpose()?;
let properties = dict.get_dict("Properties", resolver)?;
assert_empty(dict);
Ok(Resources {
ext_g_state,
color_space,
pattern,
shading,
xobject,
font,
proc_set,
properties,
})
}
}
pdf_enum!(
#[derive(Debug)]
pub enum ProcedureSet {
Pdf = "PDF",
Text = "Text",
ImageB = "ImageB",
ImageC = "ImageC",
ImageI = "ImageI",
}
);