use crate::area::{GlyphArea, GlyphTally};
use crate::prepare::Prepared;
use crate::replay::Replay;
use crate::sources::Sources;
use anyrender::Scene;
use pdfrum_common::Limits;
use pdfrum_edit::{EditDoc, Error, Fill, SaveOptions, blank_document, save};
use peniko::kurbo::{Affine, Rect, Size};
#[derive(Debug, Clone)]
pub struct Page {
pub size: Size,
pub scene: Scene,
pub placement: Affine,
pub clip: Rect,
pub area: GlyphArea,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Written {
pub bytes: Vec<u8>,
pub glyphs: GlyphTally,
}
pub fn write(pages: &[Page], sources: &Sources) -> Result<Written, Error> {
let sizes: Vec<Size> = pages.iter().map(|page| page.size).collect();
let base = blank_document(&sizes)?;
let mut edit = EditDoc::new(&base);
let prepared = Prepared::new(&mut edit, pages, &sources.images)?;
let mut glyphs = GlyphTally::default();
edit.draw_pages(&Limits::default(), |canvas| {
let Some(page) = canvas
.page()
.and_then(|index| pages.get(usize::try_from(u32::from(index)).ok()?))
else {
return;
};
canvas.saved(|canvas| {
canvas.transform(page.placement);
canvas.clip(page.clip, Fill::NonZero);
let mut replay = Replay::new(&prepared, sources, page.area);
replay.run(canvas, &mut page.scene.commands.iter());
glyphs = glyphs + replay.tally;
});
})?;
let mut bytes = Vec::new();
save(&edit, &SaveOptions::default(), &mut bytes)?;
Ok(Written { bytes, glyphs })
}