pdfrum_anyrender/
write.rs1use crate::area::{GlyphArea, GlyphTally};
4use crate::prepare::Prepared;
5use crate::replay::Replay;
6use crate::sources::Sources;
7use anyrender::Scene;
8use pdfrum_common::Limits;
9use pdfrum_edit::{EditDoc, Error, Fill, SaveOptions, blank_document, save};
10use peniko::kurbo::{Affine, Rect, Size};
11
12#[derive(Debug, Clone)]
14pub struct Page {
15 pub size: Size,
17 pub scene: Scene,
19 pub placement: Affine,
22 pub clip: Rect,
24 pub area: GlyphArea,
26}
27
28#[derive(Debug, Clone, PartialEq)]
30pub struct Written {
31 pub bytes: Vec<u8>,
33 pub glyphs: GlyphTally,
35}
36
37pub fn write(pages: &[Page], sources: &Sources) -> Result<Written, Error> {
44 let sizes: Vec<Size> = pages.iter().map(|page| page.size).collect();
45 let base = blank_document(&sizes)?;
46 let mut edit = EditDoc::new(&base);
47 let prepared = Prepared::new(&mut edit, pages, &sources.images)?;
48 let mut glyphs = GlyphTally::default();
49 edit.draw_pages(&Limits::default(), |canvas| {
50 let Some(page) = canvas
51 .page()
52 .and_then(|index| pages.get(usize::try_from(u32::from(index)).ok()?))
53 else {
54 return;
55 };
56 canvas.saved(|canvas| {
57 canvas.transform(page.placement);
58 canvas.clip(page.clip, Fill::NonZero);
59 let mut replay = Replay::new(&prepared, sources, page.area);
60 replay.run(canvas, &mut page.scene.commands.iter());
61 glyphs = glyphs + replay.tally;
62 });
63 })?;
64 let mut bytes = Vec::new();
65 save(&edit, &SaveOptions::default(), &mut bytes)?;
66 Ok(Written { bytes, glyphs })
67}