From: Ian Jackson Date: Sat, 22 May 2021 20:07:52 +0000 (+0100) Subject: bundles: Parse size of out of our generated usvgs, wip for base64 X-Git-Tag: otter-0.6.0~61 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=78812d1adafe3921a909dd8d96f0268e46619750;p=otter.git bundles: Parse size of out of our generated usvgs, wip for base64 This is not really useful atm, but it proves the principle. Signed-off-by: Ian Jackson --- diff --git a/Cargo.lock b/Cargo.lock index 9f3095be..e7178559 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2384,6 +2384,7 @@ dependencies = [ "url 2.2.2", "usvg", "vecdeque-stableix", + "xmlparser", "zip", ] diff --git a/Cargo.toml b/Cargo.toml index 3b253ad6..c9f6a929 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -82,6 +82,7 @@ unicase="2" unicode-width="0.1" url="2" vecdeque-stableix="1" +xmlparser = "0.13" zip="0.5" enum-map = { version="1" , features=["serde" ] } diff --git a/src/bundles.rs b/src/bundles.rs index 1cd16266..dd2bd8f0 100644 --- a/src/bundles.rs +++ b/src/bundles.rs @@ -752,6 +752,53 @@ fn image_usvg(zfname: &str, input: File, output: File, output.flush().context("flush output?").map_err(IE::from)?; } +#[throws(InternalError)] +fn usvg_size(f: &mut BufReader) -> [f64;2] { + let mut buf = [0; 1024]; + f.read(&mut buf).context("read start of usvg to get size")?; + + let s = str::from_utf8(&buf).unwrap_or_else( + |e| str::from_utf8(&buf[0.. e.valid_up_to()]).unwrap()); + + let mut stream = xmlparser::Tokenizer::from(s); + let mut token = || Ok::<_,AE>( + stream.next().ok_or_else(||anyhow!("eof or too far"))?? + ); + use xmlparser::Token as XT; + (|| Ok::<_,AE>( loop { + match token()? { + XT::ElementStart { local,.. } => { + ensure_eq!( local.as_str(), "svg" ); + break; + }, + _ => { }, + } + }))().context("looking for svg element")?; + + let mut size: [Option; 2] = default(); + (|| Ok::<_,AE>( loop { + match token()? { + XT::Attribute { local, value, .. } => { + size[match local.as_str() { + "width" => 0, + "height" => 1, + _ => continue, + }] = Some( + value.parse().context("parse width/height")? + ); + + if_chain!{ + if let Some(width) = size[0]; + if let Some(height) = size[1]; + then { break [width,height] } + } + }, + XT::ElementEnd {..} => throw!(anyhow!("not found")), + _ => { } + } + }))().context("looking for width/height attributes")? +} + #[throws(LE)] fn make_usvg(za: &mut IndexedZip, progress_count: &mut usize, mut for_progress: &mut dyn progress::Originator, @@ -798,6 +845,9 @@ fn make_usvg(za: &mut IndexedZip, progress_count: &mut usize, zf.name(), got.status, String::from_utf8_lossy(&got.stderr) ))); } + let t_f = File::open(&usvg_path).context("reopen").map_err(IE::from)?; + let size = usvg_size(&mut BufReader::new(t_f))?; + dbgc!(size); }, PF::Png => image_usvg(zf.name(),input,output, IF::Png, "image/png")?, }