use crate::geometry::Rect;
use lopdf::{Document, Object, ObjectId};
pub struct PageBoxes {
pub media_box: Rect,
pub trim_box: Option<Rect>,
pub bleed_box: Option<Rect>,
pub crop_box: Option<Rect>,
}
impl PageBoxes {
pub fn read(doc: &Document, page_id: ObjectId) -> crate::Result<Self> {
let page_dict = doc.get_dictionary(page_id)?;
let media_box = arr_to_rect(page_dict.get(b"MediaBox")?.as_array()?);
let trim_box = page_dict
.get(b"TrimBox")
.and_then(|obj| obj.as_array())
.map(|a| arr_to_rect(a))
.ok();
let bleed_box = page_dict
.get(b"BleedBox")
.and_then(|obj| obj.as_array())
.map(|a| arr_to_rect(a))
.ok();
let crop_box = page_dict
.get(b"CropBox")
.and_then(|obj| obj.as_array())
.map(|a| arr_to_rect(a))
.ok();
Ok(PageBoxes {
media_box,
trim_box,
bleed_box,
crop_box,
})
}
pub fn trim_or_media(&self) -> &Rect {
self.trim_box.as_ref().unwrap_or(&self.media_box)
}
pub fn bleed_rect(&self, pts: f64) -> Rect {
self.trim_or_media().expand(pts)
}
}
fn arr_to_rect(arr: &[Object]) -> Rect {
Rect::from_corners(
object_to_f64(&arr[0]),
object_to_f64(&arr[1]),
object_to_f64(&arr[2]),
object_to_f64(&arr[3]),
)
}
pub(crate) fn object_to_f64(obj: &lopdf::Object) -> f64 {
match obj {
lopdf::Object::Integer(i) => *i as f64,
lopdf::Object::Real(r) => *r as f64,
_ => panic!("expected numeric object, got {:?}", obj),
}
}