Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_austenite/src/bin/pearl_render.rs

2.2 KiB, 3 runs

created by r1870400018:38443, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1//! `pearl_render` -- render a `.prl` back to SVG.
2//!
3//! Reads a Pearl document written by `austenite --pearl` and, for every page in its index, reconstructs
4//! the very SVG the engine's SVG arm would have written -- from the stored glyph outlines, geometry and
5//! paint alone, without the engine. This is the round-trip the Pearl v0 spike exists to prove: a `.prl`
6//! is enough to render the document.
7//!
8//! Usage: `pearl_render <DOCUMENT.prl> [OUTPUT_DIR]` (default output the `.prl`'s own directory), writing
9//! `pearl-page-001.svg`, `pearl-page-002.svg`, and so on.
10
11use oxedyne_fe2o3_austenite::emit::pearl::PearlDoc;
12
13use oxedyne_fe2o3_core::prelude::*;
14
15fn main() -> Outcome<()> {
16 let args: Vec<String> = std::env::args().skip(1).collect();
17 let source = match args.first() {
18 Some(s) => s.clone(),
19 None => return Err(err!(
20 "Usage: pearl_render <DOCUMENT.prl> [OUTPUT_DIR]"; Input, Invalid, Missing)),
21 };
22 // Default the output beside the source, so a bare `pearl_render out/document.prl` drops its pages next
23 // to the file it read.
24 let out_dir = match args.get(1) {
25 Some(s) => s.clone(),
26 None => std::path::Path::new(&source)
27 .parent()
28 .map(|p| p.to_string_lossy().into_owned())
29 .filter(|s| !s.is_empty())
30 .unwrap_or_else(|| ".".to_string()),
31 };
32
33 let doc = res!(PearlDoc::read_file(&source));
34 let pages = res!(doc.page_count());
35 res!(std::fs::create_dir_all(&out_dir));
36 for i in 0..pages {
37 let svg = res!(doc.render_page(i));
38 let path = fmt!("{}/pearl-page-{:03}.svg", out_dir, i + 1);
39 res!(std::fs::write(&path, &svg));
40 }
41 println!("pearl_render: {} -> {} page(s); written to {}/", source, pages, out_dir);
42
43 // Read the annotations back through the format's own decoder, so a `.prl` authored elsewhere -- the
44 // browser reader included -- is proven readable here, rectangles and all.
45 let anns = res!(doc.annotations());
46 println!("pearl_render: {} annotation(s)", anns.len());
47 for a in &anns {
48 let rect = match a.rect {
49 Some((x, y, w, h)) => fmt!("[{} {} {} {}]", x.raw(), y.raw(), w.raw(), h.raw()),
50 None => "(whole block)".to_string(),
51 };
52 println!(" {} @ {} rect {} by {} -- {:?}",
53 a.kind.as_str(), &a.anchor[..8.min(a.anchor.len())], rect, a.author, a.payload);
54 }
55 Ok(())
56}