use crate::page::PageObject;
use crate::{IndexOutOfRange, Page};
use kurbo::Affine;
use pdfrum_common::PageIndex;
#[derive(Debug, Clone)]
pub struct PageEdit {
pub(crate) index: PageIndex,
pub(crate) page: Page,
}
impl PageEdit {
#[must_use]
pub fn new(index: PageIndex, page: Page) -> Self {
Self { index, page }
}
#[must_use]
pub fn len(&self) -> usize {
self.page.objects().len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.page.objects().is_empty()
}
#[must_use]
pub fn index(&self) -> PageIndex {
self.index
}
#[must_use]
pub fn objects(&self) -> &[PageObject] {
self.page.objects()
}
pub fn object_mut(&mut self, index: usize) -> Option<&mut PageObject> {
self.page.object_mut(index)
}
pub fn push(&mut self, object: PageObject) {
self.page.push_object(object);
}
pub fn insert(&mut self, index: usize, object: PageObject) -> Result<(), IndexOutOfRange> {
self.page.insert_object(index, object)
}
pub fn remove(&mut self, index: usize) -> Option<PageObject> {
self.page.remove_object(index)
}
pub fn show(&mut self, index: usize) -> Result<(), IndexOutOfRange> {
self.set_active(index, true)
}
pub fn hide(&mut self, index: usize) -> Result<(), IndexOutOfRange> {
self.set_active(index, false)
}
fn set_active(&mut self, index: usize, active: bool) -> Result<(), IndexOutOfRange> {
let len = self.page.objects.len();
let Some(object) = self.page.objects.get_mut(index) else {
return Err(IndexOutOfRange { index, len });
};
object.set_active(active);
Ok(())
}
#[must_use]
pub fn is_visible(&self, index: usize) -> Option<bool> {
self.page.objects().get(index).map(PageObject::is_active)
}
pub fn transform(&mut self, index: usize, transform: Affine) -> Result<(), IndexOutOfRange> {
let len = self.page.objects.len();
let Some(object) = self.page.object_mut(index) else {
return Err(IndexOutOfRange { index, len });
};
transform_object(object, transform);
Ok(())
}
#[must_use]
pub fn is_modified(&self) -> bool {
self.page.is_dirty()
}
#[must_use]
pub fn graph(&self) -> &Page {
&self.page
}
pub fn graph_mut(&mut self) -> &mut Page {
&mut self.page
}
}
pub fn transform_object(object: &mut PageObject, transform: Affine) {
match object {
PageObject::Path(p) => p.object.matrix = transform * p.object.matrix,
PageObject::Text(t) => {
t.object.matrix = transform * t.object.matrix;
t.object.position = transform * t.object.position;
}
PageObject::Image(i) => i.object.matrix = transform * i.object.matrix,
PageObject::Shading(s) => s.object.matrix = transform * s.object.matrix,
PageObject::Form(f) => f.object.matrix = transform * f.object.matrix,
}
}
impl PageEdit {
#[must_use]
pub fn font_of(&self, index: usize) -> Option<pdfrum_object::ObjRef> {
match self.page.objects().get(index)? {
PageObject::Text(text) => text.object.font_source,
_ => None,
}
}
#[must_use]
pub fn image_of(&self, index: usize) -> Option<pdfrum_object::ObjRef> {
match self.page.objects().get(index)? {
PageObject::Image(image) => image.object.source,
_ => None,
}
}
}