use std::convert::TryInto;
use crate::{
catalog::assert_len,
error::{ParseError, PdfResult},
function::Function,
objects::{Dictionary, Object},
Resolve,
};
#[derive(Debug)]
pub struct AxialShading {
coords: Coords,
domain: [f32; 2],
function: Function,
extend: [bool; 2],
}
impl AxialShading {
pub fn from_dict(dict: &mut Dictionary, resolver: &mut dyn Resolve) -> PdfResult<Self> {
let coords = Coords::from_arr(dict.expect_arr("Coords", resolver)?, resolver)?;
let domain = dict
.get_arr("Domain", resolver)?
.map(|arr| -> Result<_, ParseError> {
assert_len(&arr, 2)?;
Ok(arr
.into_iter()
.map(|obj| resolver.assert_number(obj))
.collect::<PdfResult<Vec<f32>>>()?
.try_into()
.unwrap())
})
.transpose()?
.unwrap_or([0.0, 1.0]);
let function = dict.expect_function("Function", resolver)?;
let extend = dict
.get_arr("Extend", resolver)?
.map(|arr| -> Result<_, ParseError> {
assert_len(&arr, 2)?;
Ok(arr
.into_iter()
.map(|obj| resolver.assert_bool(obj))
.collect::<PdfResult<Vec<bool>>>()?
.try_into()
.unwrap())
})
.transpose()?
.unwrap_or([false, false]);
Ok(Self {
coords,
domain,
function,
extend,
})
}
}
#[derive(Debug)]
struct Coords {
x0: f32,
y0: f32,
x1: f32,
y1: f32,
}
impl Coords {
pub fn from_arr(mut arr: Vec<Object>, resolver: &mut dyn Resolve) -> PdfResult<Self> {
assert_len(&arr, 4)?;
let y1 = resolver.assert_number(arr.pop().unwrap())?;
let x1 = resolver.assert_number(arr.pop().unwrap())?;
let y0 = resolver.assert_number(arr.pop().unwrap())?;
let x0 = resolver.assert_number(arr.pop().unwrap())?;
Ok(Self { x0, y0, x1, y1 })
}
}