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 | |
| 11 | use oxedyne_fe2o3_austenite::emit::pearl::PearlDoc; |
| 12 | |
| 13 | use oxedyne_fe2o3_core::prelude::*; |
| 14 | |
| 15 | fn 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 | } |