use crate::{
catalog::assert_len,
data_structures::Matrix,
error::PdfResult,
function::Function,
objects::{Dictionary, Object},
Resolve,
};
#[derive(Debug)]
pub struct FunctionBasedShading {
domain: FunctionDomain,
matrix: Option<Matrix>,
function: Function,
}
impl FunctionBasedShading {
pub fn from_dict(dict: &mut Dictionary, resolver: &mut dyn Resolve) -> PdfResult<Self> {
let domain = dict
.get_arr("Domain", resolver)?
.map(|arr| FunctionDomain::from_arr(arr, resolver))
.transpose()?
.unwrap_or_default();
let matrix = dict.get_matrix("Matrix", resolver)?;
let function = dict.expect_function("Function", resolver)?;
Ok(Self {
domain,
matrix,
function,
})
}
}
#[derive(Debug)]
struct FunctionDomain {
x_min: f32,
x_max: f32,
y_min: f32,
y_max: f32,
}
impl FunctionDomain {
pub fn from_arr(mut arr: Vec<Object>, resolver: &mut dyn Resolve) -> PdfResult<Self> {
assert_len(&arr, 4)?;
let y_max = resolver.assert_number(arr.pop().unwrap())?;
let y_min = resolver.assert_number(arr.pop().unwrap())?;
let x_max = resolver.assert_number(arr.pop().unwrap())?;
let x_min = resolver.assert_number(arr.pop().unwrap())?;
Ok(Self {
x_min,
x_max,
y_min,
y_max,
})
}
}
impl Default for FunctionDomain {
fn default() -> Self {
Self {
x_min: 0.0,
x_max: 1.0,
y_min: 0.0,
y_max: 1.0,
}
}
}