From 8df18a77c03a083e2e518d496dfa649b70d47f64 Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Sun, 31 Jan 2021 22:18:52 +0100 Subject: [PATCH] favicons: properly detect icon sizes --- Cargo.lock | 34 ++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/models/favicon.rs | 30 +++++++++++++++++++----------- 3 files changed, 54 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f67ae5d..6506a14 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -284,6 +284,7 @@ dependencies = [ "serde", "serde_json", "surf", + "svg_metadata", "unicase", "url", "zbar-rust", @@ -731,6 +732,12 @@ dependencies = [ "libloading", ] +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + [[package]] name = "downcast-rs" version = "1.2.0" @@ -2448,6 +2455,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "roxmltree" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf7d7b1ea646d380d0e8153158063a6da7efe30ddbf3184042848e3f8a6f671" +dependencies = [ + "xmlparser", +] + [[package]] name = "rust-argon2" version = "0.8.3" @@ -2785,6 +2801,18 @@ dependencies = [ "web-sys", ] +[[package]] +name = "svg_metadata" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d39f36262efe61096a17aa42140b0e44b9189806c3fa71ab3cff123429938eb0" +dependencies = [ + "doc-comment", + "lazy_static", + "regex", + "roxmltree", +] + [[package]] name = "syn" version = "1.0.60" @@ -3283,6 +3311,12 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b07db065a5cf61a7e4ba64f29e67db906fb1787316516c4e6e5ff0fea1efcd8a" +[[package]] +name = "xmlparser" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "114ba2b24d2167ef6d67d7d04c8cc86522b87f490025f39f0303b7db5bf5e3d8" + [[package]] name = "zbar-rust" version = "0.0.14" diff --git a/Cargo.toml b/Cargo.toml index 1c975ef..9f0ccd3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,3 +35,4 @@ surf = "2.1" unicase = "2.6" url = "2.2" zbar-rust = "0.0" +svg_metadata = "0.4" diff --git a/src/models/favicon.rs b/src/models/favicon.rs index ee73925..a2f5022 100644 --- a/src/models/favicon.rs +++ b/src/models/favicon.rs @@ -76,21 +76,29 @@ impl Favicon { let ext = std::path::Path::new(url.path()) .extension() .map(|e| e.to_str().unwrap())?; - // Assumes the svg is the best size we can find + if ext == "svg" { - return Some((1024, 1024)); + let body = response.body_string().await.ok()?; + + self.svg_dimensions(body) + } else { + let bytes = response.body_bytes().await.ok()?; + + let mut image = ImageReader::new(Cursor::new(bytes)); + + let format = image::ImageFormat::from_extension(ext)?; + image.set_format(format); + image.into_dimensions().ok() } + } - let format = match ext { - "png" => image::ImageFormat::Png, - "ico" => image::ImageFormat::Ico, - _ => unreachable!(), - }; + // TODO: replace with librsvg maybe? + fn svg_dimensions(&self, svg: String) -> Option<(u32, u32)> { + let metadata = svg_metadata::Metadata::parse(svg).ok()?; - let bytes = response.body_bytes().await.ok()?; - let mut image = ImageReader::new(Cursor::new(bytes)); - image.set_format(format); - image.into_dimensions().ok() + let width = metadata.width()? as u32; + let height = metadata.height()? as u32; + Some((width, height)) } } #[derive(Debug)]