use std::path::PathBuf; use std::time::Instant; use siphon::geom::BBox; use siphon::render::render as render_board; use siphon::{render_to_svg, LibraryResolver, RenderOptions, SvgSink}; fn main() { let path: PathBuf = std::env::args().nth(1) .expect("usage: render_board [out.svg]") .into(); let out: PathBuf = std::env::args().nth(2) .map(Into::into) .unwrap_or_else(|| { let stem = path.file_stem().unwrap_or_default().to_string_lossy().to_string(); PathBuf::from(format!("/tmp/siphon_{stem}.svg")) }); let source = std::fs::read_to_string(&path).expect("read board"); let project_dir = path.parent().unwrap_or_else(|| std::path::Path::new(".")); let _ = LibraryResolver::from_global().and_then(|r| r.with_project(project_dir)); let t0 = Instant::now(); let svg = render_to_svg(&source, &RenderOptions::default()).expect("render"); let dt = t0.elapsed(); let board = siphon::parse::board::parse(&source).expect("parse"); let stats = count_items(&board); println!( "render {:?} → {} bytes in {:?}\n items: {} tracks, {} arcs, {} vias, {} gr_*, {} footprints, {} zones ({} fills), {} dims, {} texts", path.file_name().unwrap(), svg.len(), dt, stats.tracks, stats.arcs, stats.vias, stats.gr, stats.footprints, stats.zones, stats.zone_fills, stats.dims, stats.texts, ); std::fs::write(&out, svg).expect("write"); println!("wrote {}", out.display()); let mut sink = SvgSink::new(BBox::empty()); let bb = render_board(&board, &mut sink, &RenderOptions::default()); sink.bounds = bb; } #[derive(Default)] struct Stats { tracks: usize, arcs: usize, vias: usize, gr: usize, footprints: usize, zones: usize, zone_fills: usize, dims: usize, texts: usize, } fn count_items(board: &siphon::Board) -> Stats { use siphon::Item; let mut s = Stats::default(); for item in &board.items { match item { Item::Segment(_) => s.tracks += 1, Item::Arc(_) => s.arcs += 1, Item::Via(_) => s.vias += 1, Item::GrLine(_) | Item::GrArc(_) | Item::GrRect(_) | Item::GrCircle(_) | Item::GrPoly(_) => s.gr += 1, Item::GrText(_) => s.texts += 1, Item::Footprint(f) => { s.footprints += 1; s.texts += f.texts.len(); } Item::Zone(z) => { s.zones += 1; s.zone_fills += z.filled_polygons.len(); } Item::Dimension(_) => s.dims += 1, } } s }