From a027513447afa62d483e54154f566a9ffc47ce67 Mon Sep 17 00:00:00 2001 From: Sophie Herold Date: Fri, 4 Aug 2023 13:20:41 +0200 Subject: [PATCH] decoder: Use glycin for decoding SVGs as well Part-of: --- Cargo.lock | 754 +------------------ Cargo.toml | 6 +- build-aux/flatpak/org.gnome.Loupe.Devel.json | 2 +- src/decoder/formats/glycin_proxy.rs | 124 ++- src/decoder/formats/mod.rs | 2 +- src/decoder/formats/svg.rs | 181 ++--- src/decoder/mod.rs | 17 +- src/widgets/print.rs | 6 +- src/widgets/properties_view.rs | 26 +- 9 files changed, 140 insertions(+), 978 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 54dba63..c0eb1d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,15 +35,6 @@ dependencies = [ "backtrace", ] -[[package]] -name = "approx" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" -dependencies = [ - "num-traits", -] - [[package]] name = "arc-swap" version = "1.6.0" @@ -64,7 +55,7 @@ dependencies = [ "gdk4-x11", "gtk4", "once_cell", - "rand 0.8.5", + "rand", "serde", "serde_repr", "url", @@ -347,12 +338,6 @@ dependencies = [ "system-deps", ] -[[package]] -name = "cast" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" - [[package]] name = "cc" version = "1.0.79" @@ -387,12 +372,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - [[package]] name = "cpufeatures" version = "0.2.9" @@ -411,40 +390,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crossbeam-channel" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset 0.9.0", - "scopeguard", -] - [[package]] name = "crossbeam-utils" version = "0.8.16" @@ -464,39 +409,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "cssparser" -version = "0.29.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93d03419cb5950ccfd3daf3ff1c7a36ace64609a1a8746d493df1ca0afde0fa" -dependencies = [ - "cssparser-macros", - "dtoa-short", - "itoa", - "matches", - "phf 0.10.1", - "proc-macro2", - "quote", - "smallvec", - "syn 1.0.109", -] - -[[package]] -name = "cssparser-macros" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" -dependencies = [ - "quote", - "syn 2.0.23", -] - -[[package]] -name = "data-url" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d7439c3735f405729d52c3fbbe4de140eaf938a1fe47d227c27f8254d4302a5" - [[package]] name = "derivative" version = "2.2.0" @@ -508,19 +420,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "derive_more" -version = "0.99.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn 1.0.109", -] - [[package]] name = "digest" version = "0.10.7" @@ -531,42 +430,12 @@ dependencies = [ "crypto-common", ] -[[package]] -name = "dtoa" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "519b83cd10f5f6e969625a409f735182bea5558cd8b64c655806ceaae36f1999" - -[[package]] -name = "dtoa-short" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbaceec3c6e4211c79e7b1800fb9680527106beb2f9c51904a3210c03a448c74" -dependencies = [ - "dtoa", -] - [[package]] name = "dunce" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" -[[package]] -name = "either" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" - -[[package]] -name = "encoding_rs" -version = "0.8.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" -dependencies = [ - "cfg-if", -] - [[package]] name = "enumflags2" version = "0.7.7" @@ -663,15 +532,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "float-cmp" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" -dependencies = [ - "num-traits", -] - [[package]] name = "foreign-types" version = "0.5.0" @@ -708,16 +568,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "futf" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" -dependencies = [ - "mac", - "new_debug_unreachable", -] - [[package]] name = "futures" version = "0.3.28" @@ -822,15 +672,6 @@ dependencies = [ "slab", ] -[[package]] -name = "fxhash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -dependencies = [ - "byteorder", -] - [[package]] name = "gdk-pixbuf" version = "0.18.0" @@ -948,17 +789,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - [[package]] name = "getrandom" version = "0.2.10" @@ -967,7 +797,7 @@ checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", ] [[package]] @@ -1457,15 +1287,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "1.0.8" @@ -1508,12 +1329,6 @@ dependencies = [ "log", ] -[[package]] -name = "language-tags" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" - [[package]] name = "lazy_static" version = "1.4.0" @@ -1627,16 +1442,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "lock_api" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" -dependencies = [ - "autocfg", - "scopeguard", -] - [[package]] name = "log" version = "0.4.19" @@ -1654,6 +1459,7 @@ dependencies = [ "arc-swap", "ashpd", "async-channel", + "async-std", "env_logger", "futures", "gettext-rs", @@ -1668,16 +1474,9 @@ dependencies = [ "libgweather", "log", "once_cell", - "rsvg", "url", ] -[[package]] -name = "mac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" - [[package]] name = "malloc_buf" version = "0.0.6" @@ -1687,36 +1486,6 @@ dependencies = [ "libc", ] -[[package]] -name = "markup5ever" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016" -dependencies = [ - "log", - "phf 0.10.1", - "phf_codegen 0.10.0", - "string_cache", - "string_cache_codegen", - "tendril", -] - -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - -[[package]] -name = "matrixmultiply" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090126dc04f95dc0d1c1c91f61bdd474b3930ca064c1edc8a849da2c6cbe1e77" -dependencies = [ - "autocfg", - "rawpointer", -] - [[package]] name = "memchr" version = "2.5.0" @@ -1774,39 +1543,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16cf681a23b4d0a43fc35024c176437f9dcd818db34e0f42ab456a0ee5ad497b" -[[package]] -name = "nalgebra" -version = "0.32.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d68d47bba83f9e2006d117a9a33af1524e655516b8919caac694427a6fb1e511" -dependencies = [ - "approx", - "matrixmultiply", - "nalgebra-macros", - "num-complex", - "num-rational", - "num-traits", - "simba", - "typenum", -] - -[[package]] -name = "nalgebra-macros" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d232c68884c0c99810a5a4d333ef7e47689cfd0edc85efc9e54e1e6bf5212766" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "new_debug_unreachable" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" - [[package]] name = "nix" version = "0.26.2" @@ -1821,61 +1557,6 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "nodrop" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" - -[[package]] -name = "num-complex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e0d21255c828d6f128a1e41534206671e8c3ea0c62f32291e808dc82cff17d" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "objc" version = "0.2.7" @@ -1955,165 +1636,18 @@ dependencies = [ "system-deps", ] -[[package]] -name = "pangocairo" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57036589a9cfcacf83f9e606d15813fc6bf03f0e9e69aa2b5e3bb85af86b38a5" -dependencies = [ - "cairo-rs", - "glib 0.18.1", - "libc", - "pango", - "pangocairo-sys", -] - -[[package]] -name = "pangocairo-sys" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc3c8ff676a37e7a72ec1d5fc029f91c407278083d2752784ff9f5188c108833" -dependencies = [ - "cairo-sys-rs", - "glib-sys 0.18.1", - "libc", - "pango-sys", - "system-deps", -] - [[package]] name = "parking" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" -[[package]] -name = "parking_lot" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets", -] - -[[package]] -name = "paste" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b27ab7be369122c218afc2079489cdcb4b517c0a3fc386ff11e1fedfcc2b35" - [[package]] name = "percent-encoding" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" -[[package]] -name = "phf" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" -dependencies = [ - "phf_shared 0.8.0", -] - -[[package]] -name = "phf" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" -dependencies = [ - "phf_macros", - "phf_shared 0.10.0", - "proc-macro-hack", -] - -[[package]] -name = "phf_codegen" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" -dependencies = [ - "phf_generator 0.8.0", - "phf_shared 0.8.0", -] - -[[package]] -name = "phf_codegen" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" -dependencies = [ - "phf_generator 0.10.0", - "phf_shared 0.10.0", -] - -[[package]] -name = "phf_generator" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" -dependencies = [ - "phf_shared 0.8.0", - "rand 0.7.3", -] - -[[package]] -name = "phf_generator" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" -dependencies = [ - "phf_shared 0.10.0", - "rand 0.8.5", -] - -[[package]] -name = "phf_macros" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" -dependencies = [ - "phf_generator 0.10.0", - "phf_shared 0.10.0", - "proc-macro-hack", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "phf_shared" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" -dependencies = [ - "siphasher", -] - -[[package]] -name = "phf_shared" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" -dependencies = [ - "siphasher", -] - [[package]] name = "pin-project-lite" version = "0.2.10" @@ -2154,12 +1688,6 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" -[[package]] -name = "precomputed-hash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" - [[package]] name = "proc-macro-crate" version = "1.3.1" @@ -2194,12 +1722,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "proc-macro-hack" -version = "0.5.20+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" - [[package]] name = "proc-macro2" version = "1.0.63" @@ -2237,20 +1759,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", - "rand_pcg", -] - [[package]] name = "rand" version = "0.8.5" @@ -2258,18 +1766,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", + "rand_chacha", + "rand_core", ] [[package]] @@ -2279,16 +1777,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", + "rand_core", ] [[package]] @@ -2297,61 +1786,9 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.10", + "getrandom", ] -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rand_pcg" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rawpointer" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" - -[[package]] -name = "rayon" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - -[[package]] -name = "rctree" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b42e27ef78c35d3998403c1d26f3efd9e135d3e5121b0a4845cc5cc27547f4f" - [[package]] name = "redox_syscall" version = "0.3.5" @@ -2399,43 +1836,6 @@ dependencies = [ "bytemuck", ] -[[package]] -name = "rsvg" -version = "2.56.91" -source = "git+https://gitlab.gnome.org/GNOME/librsvg.git?rev=81b58cc1368ab10f6de3439c8b1276c40b8d4286#81b58cc1368ab10f6de3439c8b1276c40b8d4286" -dependencies = [ - "byteorder", - "cairo-rs", - "cast", - "cssparser", - "data-url", - "encoding_rs", - "float-cmp", - "gdk-pixbuf", - "gio 0.18.1", - "glib 0.18.1", - "itertools", - "language-tags", - "libc", - "locale_config", - "markup5ever", - "nalgebra", - "num-traits", - "once_cell", - "pango", - "pangocairo", - "rayon", - "rctree", - "regex", - "rgb", - "selectors", - "string_cache", - "system-deps", - "tinyvec", - "url", - "xml5ever", -] - [[package]] name = "rustc-demangle" version = "0.1.23" @@ -2490,15 +1890,6 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98a01dab6acf992653be49205bdd549f32f17cb2803e8eacf1560bf97259aae8" -[[package]] -name = "safe_arch" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62a7484307bd40f8f7ccbacccac730108f2cae119a3b11c74485b48aa9ea650f" -dependencies = [ - "bytemuck", -] - [[package]] name = "same-file" version = "1.0.6" @@ -2508,30 +1899,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "selectors" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c37578180969d00692904465fb7f6b3d50b9a2b952b87c23d0e2e5cb5013416" -dependencies = [ - "bitflags 1.3.2", - "cssparser", - "derive_more", - "fxhash", - "log", - "phf 0.8.0", - "phf_codegen 0.8.0", - "precomputed-hash", - "servo_arc", - "smallvec", -] - [[package]] name = "semver" version = "1.0.17" @@ -2589,16 +1956,6 @@ dependencies = [ "serde", ] -[[package]] -name = "servo_arc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52aa42f8fdf0fed91e5ce7f23d8138441002fa31dca008acf47e6fd4721f741" -dependencies = [ - "nodrop", - "stable_deref_trait", -] - [[package]] name = "sha1" version = "0.10.5" @@ -2629,25 +1986,6 @@ dependencies = [ "libc", ] -[[package]] -name = "simba" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "061507c94fc6ab4ba1c9a0305018408e312e17c041eb63bef8aa726fa33aceae" -dependencies = [ - "approx", - "num-complex", - "num-traits", - "paste", - "wide", -] - -[[package]] -name = "siphasher" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" - [[package]] name = "slab" version = "0.4.8" @@ -2673,44 +2011,12 @@ dependencies = [ "winapi", ] -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - [[package]] name = "static_assertions" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "string_cache" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" -dependencies = [ - "new_debug_unreachable", - "once_cell", - "parking_lot", - "phf_shared 0.10.0", - "precomputed-hash", - "serde", -] - -[[package]] -name = "string_cache_codegen" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" -dependencies = [ - "phf_generator 0.10.0", - "phf_shared 0.10.0", - "proc-macro2", - "quote", -] - [[package]] name = "syn" version = "1.0.109" @@ -2772,17 +2078,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "tendril" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" -dependencies = [ - "futf", - "mac", - "utf-8", -] - [[package]] name = "termcolor" version = "1.2.0" @@ -2942,12 +2237,6 @@ dependencies = [ "serde", ] -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - [[package]] name = "value-bag" version = "1.4.1" @@ -2982,12 +2271,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -3070,16 +2353,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "wide" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40018623e2dba2602a9790faba8d33f2ebdebf4b86561b83928db735f8784728" -dependencies = [ - "bytemuck", - "safe_arch", -] - [[package]] name = "winapi" version = "0.3.9" @@ -3196,17 +2469,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "xml5ever" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4034e1d05af98b51ad7214527730626f019682d797ba38b51689212118d8e650" -dependencies = [ - "log", - "mac", - "markup5ever", -] - [[package]] name = "zbus" version = "3.14.1" @@ -3234,7 +2496,7 @@ dependencies = [ "nix", "once_cell", "ordered-stream", - "rand 0.8.5", + "rand", "serde", "serde_repr", "sha1", diff --git a/Cargo.toml b/Cargo.toml index 3888dcf..fdba22c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,8 +16,10 @@ disable-glycin-sandbox = [] anyhow = { version = "1.0.66", features = ["backtrace"] } arc-swap = "1.6.0" async-channel = "1.8.0" +async-std = "1.12.0" env_logger = "0.10.0" futures = "0.3.25" +glycin = "0.1.0-beta.1" gvdb-macros = "0.1.6" indexmap = "2.0.0" kamadak-exif = "0.5.5" @@ -26,10 +28,6 @@ log = "0.4.17" once_cell = "1.16.0" url = "2.3.1" -# decoders -rsvg = { git = "https://gitlab.gnome.org/GNOME/librsvg.git", rev = "81b58cc1368ab10f6de3439c8b1276c40b8d4286" } -glycin = "0.1.0-beta.0" - [dependencies.ashpd] version = "0.5.0" features = ["gtk4"] diff --git a/build-aux/flatpak/org.gnome.Loupe.Devel.json b/build-aux/flatpak/org.gnome.Loupe.Devel.json index d863a8e..c061e93 100644 --- a/build-aux/flatpak/org.gnome.Loupe.Devel.json +++ b/build-aux/flatpak/org.gnome.Loupe.Devel.json @@ -156,7 +156,7 @@ { "type" : "git", "url" : "https://gitlab.gnome.org/sophie-h/glycin.git", - "commit" : "897032e50f38370881fb2eb07c3425084c188eff" + "tag" : "0.1.beta" } ] }, diff --git a/src/decoder/formats/glycin_proxy.rs b/src/decoder/formats/glycin_proxy.rs index e11be4a..49103fb 100644 --- a/src/decoder/formats/glycin_proxy.rs +++ b/src/decoder/formats/glycin_proxy.rs @@ -51,96 +51,84 @@ impl Glycin { let (next_frame_send, next_frame_recv) = async_channel::bounded(2); - glib::MainContext::default().spawn(async move { - let update_sender = updater.clone(); + updater.clone().spawn_error_handled(async move { + let mut image_request = glycin::ImageRequest::new(file); - let result: Result<(), glycin::Error> = async move { - let mut image_request = glycin::ImageRequest::new(file); + #[cfg(feature = "disable-glycin-sandbox")] + image_request.sandbox_mechanism(Some(glycin::SandboxMechanism::NotSandboxed)); - #[cfg(feature = "disable-glycin-sandbox")] - image_request.sandbox_mechanism(Some(glycin::SandboxMechanism::NotSandboxed)); + image_request.cancellable(cancellable_); - image_request.cancellable(cancellable_); + let image = image_request.request().await?; - let image = image_request.request().await?; - - if let Some(exif_raw) = image.info().exif.clone().into() { - updater.send(DecoderUpdate::Metadata(ImageMetadata::from_exif_bytes( - exif_raw, - ))); - } - - let dimensions = (image.info().width, image.info().height); - tiles.set_original_dimensions(dimensions); - - updater.send(DecoderUpdate::Format(ImageFormat::new( - image.mime_type(), - image.format_name(), + if let Some(exif_raw) = image.info().exif.clone().into() { + updater.send(DecoderUpdate::Metadata(ImageMetadata::from_exif_bytes( + exif_raw, ))); + } - let frame = image.next_frame().await?; + let dimensions = (image.info().width, image.info().height); + tiles.set_original_dimensions(dimensions); - if let Some(delay) = frame.delay { - updater.send(DecoderUpdate::Animated); + updater.send(DecoderUpdate::Format(ImageFormat::new( + image.mime_type(), + image.format_name(), + ))); - let position = (0, 0); + let frame = image.next_frame().await?; - let tile = tiling::Tile { - position, - zoom_level: tiling::zoom_to_level(1.), - bleed: 0, - texture: frame.texture, - }; + if let Some(delay) = frame.delay { + updater.send(DecoderUpdate::Animated); - tiles.push_frame(tile, dimensions, delay); - updater.send(DecoderUpdate::Redraw); + let position = (0, 0); - loop { - if next_frame_recv.recv().await.is_ok() { - loop { - let frame = image.next_frame().await?; + let tile = tiling::Tile { + position, + zoom_level: tiling::zoom_to_level(1.), + bleed: 0, + texture: frame.texture, + }; - let position = (0, 0); + tiles.push_frame(tile, dimensions, delay); + updater.send(DecoderUpdate::Redraw); - let tile = tiling::Tile { - position, - zoom_level: tiling::zoom_to_level(1.), - bleed: 0, - texture: frame.texture, - }; + loop { + if next_frame_recv.recv().await.is_ok() { + loop { + let frame = image.next_frame().await?; - tiles.push_frame(tile, dimensions, delay); + let position = (0, 0); - if tiles.n_frames() >= FRAME_BUFFER { - break; - } + let tile = tiling::Tile { + position, + zoom_level: tiling::zoom_to_level(1.), + bleed: 0, + texture: frame.texture, + }; + + tiles.push_frame(tile, dimensions, delay); + + if tiles.n_frames() >= FRAME_BUFFER { + break; } - } else { - log::debug!("Animation handler gone"); - return Ok(()); } + } else { + log::debug!("Animation handler gone"); + return Ok(()); } - } else { - let tile = tiling::Tile { - position: (0, 0), - zoom_level: tiling::zoom_to_level(1.), - bleed: 0, - texture: frame.texture, - }; - - tiles.push(tile); } + } else { + let tile = tiling::Tile { + position: (0, 0), + zoom_level: tiling::zoom_to_level(1.), + bleed: 0, + texture: frame.texture, + }; - Ok(()) + tiles.push(tile); } - .await; - if let Err(err) = result { - if err.unsupported_format().is_some() { - update_sender.send(DecoderUpdate::UnsupportedFormat); - } - update_sender.send(DecoderUpdate::Error(err.into())); - } + Ok(()) }); Self { diff --git a/src/decoder/formats/mod.rs b/src/decoder/formats/mod.rs index 19ebfed..c6779ff 100644 --- a/src/decoder/formats/mod.rs +++ b/src/decoder/formats/mod.rs @@ -54,7 +54,7 @@ impl std::fmt::Display for ImageFormat { #[derive(Clone, Debug, Default)] pub enum ImageDimensionDetails { - Svg((rsvg::Length, rsvg::Length)), + Svg(String), #[default] None, } diff --git a/src/decoder/formats/svg.rs b/src/decoder/formats/svg.rs index 76e51c1..a8a817f 100644 --- a/src/decoder/formats/svg.rs +++ b/src/decoder/formats/svg.rs @@ -23,6 +23,7 @@ use crate::deps::*; use anyhow::Context; use arc_swap::ArcSwap; +use async_channel as mpsc; use gtk::prelude::*; use std::sync::Arc; @@ -33,7 +34,7 @@ pub const RSVG_MAX_SIZE: u32 = 32_767; #[derive(Debug)] pub struct Svg { - thread_handle: std::thread::JoinHandle<()>, + wakeup: mpsc::Sender<()>, current_request: Arc>, cancellable: gio::Cancellable, } @@ -54,7 +55,7 @@ impl Request { impl Drop for Svg { fn drop(&mut self) { self.cancellable.cancel(); - self.thread_handle.thread().unpark(); + let _ = self.wakeup.try_send(()); } } @@ -68,22 +69,37 @@ impl Svg { let request_store = current_request.clone(); let cancellable = gio::Cancellable::new(); let cancellable_ = cancellable.clone(); + let (wakeup, wakeup_resv) = mpsc::unbounded(); - let thread_handle = updater.spawn_error_handled(move || { - let handle = rsvg::Loader::new().read_file(&file, Some(&cancellable))?; - let renderer = rsvg::CairoRenderer::new(&handle); + updater.clone().spawn_error_handled(async move { + let mut image_request = glycin::ImageRequest::new(file); - let (original_width, original_height) = svg_dimensions(&renderer); + #[cfg(feature = "disable-glycin-sandbox")] + image_request.sandbox_mechanism(Some(glycin::SandboxMechanism::NotSandboxed)); + + image_request.cancellable(cancellable.clone()); + + let image = image_request.request().await?; + + let dimensions = if let Some(string) = image.info().dimensions_text.as_ref() { + ImageDimensionDetails::Svg(string.to_string()) + } else { + ImageDimensionDetails::None + }; - let intrisic_dimensions = renderer.intrinsic_dimensions(); tiles.set_original_dimensions_full( - (original_width, original_height), - ImageDimensionDetails::Svg((intrisic_dimensions.width, intrisic_dimensions.height)), + (image.info().width, image.info().height), + dimensions, ); + updater.send(DecoderUpdate::Format(ImageFormat::new( + image.mime_type(), + image.format_name(), + ))); + loop { let tile_request = { - let mut request = request_store.write().ok().context("RwLock is poisoned")?; + let mut request = request_store.write().unwrap(); let value = request.clone(); *request = Request::None; value @@ -96,7 +112,10 @@ impl Svg { match tile_request { Request::None => { - std::thread::park(); + let result = wakeup_resv.recv().await; + if result.is_err() { + return Ok(()); + } } Request::Tile(tile_request) => { @@ -106,12 +125,7 @@ impl Svg { let relevant_tiles = tiling.relevant_tiles(&tile_request.area); for tile_instructions in relevant_tiles { - if request_store - .read() - .ok() - .context("RwLock is poisoned")? - .is_waiting() - { + if request_store.read().ok().unwrap().is_waiting() { break; } @@ -122,44 +136,27 @@ impl Svg { continue; } - let area = tile_instructions.area_with_bleed(); - let surface = cairo::ImageSurface::create( - cairo::Format::ARgb32, - area.width() as i32, - area.height() as i32, - )?; - - let context = cairo::Context::new(&surface)?; let (total_width, total_height) = tile_instructions.tiling.scaled_dimensions(); + let area = tile_instructions.area_with_bleed(); - // librsvg does not currently support larger images - if total_height > RSVG_MAX_SIZE || total_width > RSVG_MAX_SIZE { - continue; - } + let frame_request = glycin::FrameRequest::new() + .scale(total_width, total_height) + .clip( + area.x() as u32, + area.y() as u32, + area.width() as u32, + area.height() as u32, + ); - renderer - .render_document( - &context, - &cairo::Rectangle::new( - -area.x() as f64, - -area.y() as f64, - total_width as f64, - total_height as f64, - ), - ) - .context("Failed to render image")?; - drop(context); - - let decoded_image = Decoded { surface }; + let frame = image.specific_frame(frame_request).await?; let position = ( tile_instructions.area.x() as u32, tile_instructions.area.y() as u32, ); - let texture = decoded_image.into_texture()?; - tiles.push_tile(tiling, position, texture); + tiles.push_tile(tiling, position, frame.texture); } } } @@ -169,7 +166,7 @@ impl Svg { }); Self { - thread_handle, + wakeup, current_request, cancellable: cancellable_, } @@ -182,90 +179,22 @@ impl Svg { .ok() .context("RwLock is poisoned")?; *current_request = Request::Tile(request); - self.thread_handle.thread().unpark(); + self.wakeup.try_send(())?; Ok(()) } - pub fn render_print( - file: &gio::File, - width: i32, - height: i32, - ) -> anyhow::Result { - let handle = rsvg::Loader::new().read_file(file, gio::Cancellable::NONE)?; - let renderer = rsvg::CairoRenderer::new(&handle); - let surface = cairo::ImageSurface::create(cairo::Format::ARgb32, width, height)?; - let context = cairo::Context::new(&surface)?; - renderer - .render_document( - &context, - &cairo::Rectangle::new(0., 0., width as f64, height as f64), - ) - .context("Failed to render image")?; - drop(context); + pub fn render_print(file: &gio::File, width: i32, height: i32) -> anyhow::Result { + #[allow(unused_mut)] + let mut image_request = glycin::ImageRequest::new(file.clone()); - Ok(surface) - } -} - -pub fn svg_dimensions(renderer: &rsvg::CairoRenderer) -> (u32, u32) { - if let Some((width, height)) = renderer.intrinsic_size_in_pixels() { - (width.ceil() as u32, height.ceil() as u32) - } else { - match renderer.intrinsic_dimensions() { - rsvg::IntrinsicDimensions { - width: - rsvg::Length { - length: width, - unit: rsvg::LengthUnit::Percent, - }, - height: - rsvg::Length { - length: height, - unit: rsvg::LengthUnit::Percent, - }, - vbox: Some(vbox), - } => ( - (width * vbox.width()).ceil() as u32, - (height * vbox.height()).ceil() as u32, - ), - dimensions => { - log::warn!("Failed to parse SVG dimensions: {dimensions:?}"); - (300, 300) - } - } - } -} - -struct Decoded { - surface: cairo::ImageSurface, -} - -impl Decoded { - pub fn into_texture(self) -> anyhow::Result { - let memory_format = { - #[cfg(target_endian = "little")] - { - gdk::MemoryFormat::B8g8r8a8 - } - - #[cfg(target_endian = "big")] - { - gdk::MemoryFormat::A8r8g8b8 - } - }; - - let width = self.surface.width(); - let height = self.surface.height(); - let stride = self.surface.stride() as usize; - - let bytes = glib::Bytes::from_owned( - self.surface - .take_data() - .context("Cairo surface already taken")? - .to_vec(), - ); - - Ok(gdk::MemoryTexture::new(width, height, memory_format, &bytes, stride).upcast()) + #[cfg(feature = "disable-glycin-sandbox")] + image_request.sandbox_mechanism(Some(glycin::SandboxMechanism::NotSandboxed)); + + let image = async_std::task::block_on(image_request.request())?; + let frame_request = glycin::FrameRequest::new().scale(width as u32, height as u32); + let frame = async_std::task::block_on(image.specific_frame(frame_request))?; + + Ok(frame.texture) } } diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 4899319..da5e671 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -80,14 +80,21 @@ impl UpdateSender { } /// Send occuring errors to renderer - pub fn spawn_error_handled(&self, f: F) -> std::thread::JoinHandle<()> + pub fn spawn_error_handled(&self, f: F) -> glib::JoinHandle<()> where - F: FnOnce() -> Result<(), anyhow::Error> + Send + 'static, + F: std::future::Future> + Send + 'static, { let update_sender = self.clone(); - std::thread::spawn(move || { - if let Err(err) = f() { - update_sender.send(DecoderUpdate::Error(err)); + glib::MainContext::default().spawn(async move { + let update_sender = update_sender.clone(); + + let result: Result<(), glycin::Error> = f.await; + + if let Err(err) = result { + if err.unsupported_format().is_some() { + update_sender.send(DecoderUpdate::UnsupportedFormat); + } + update_sender.send(DecoderUpdate::Error(err.into())); } }) } diff --git a/src/widgets/print.rs b/src/widgets/print.rs index 01bc7dd..2ad0efb 100644 --- a/src/widgets/print.rs +++ b/src/widgets/print.rs @@ -847,7 +847,7 @@ impl LpPrint { let texture_scale = self.user_width() / orig_width as f64; let cairo_scale = cairo_dpi / self.dpi(); - let cairo_surface = if image.format().map_or(false, |x| x.is_svg()) { + let texture = if image.format().map_or(false, |x| x.is_svg()) { // Render SVG to exact needed sizes // TODO: This should be async decoder::formats::Svg::render_print( @@ -857,8 +857,10 @@ impl LpPrint { ) .unwrap() } else { - let texture = image.print_data(texture_scale).unwrap(); + image.print_data(texture_scale).unwrap() + }; + let cairo_surface = { let mut downloader = gdk::TextureDownloader::new(&texture); downloader.set_format(gdk::MemoryFormat::B8g8r8a8Premultiplied); diff --git a/src/widgets/properties_view.rs b/src/widgets/properties_view.rs index 2e0d03b..a13277e 100644 --- a/src/widgets/properties_view.rs +++ b/src/widgets/properties_view.rs @@ -306,31 +306,7 @@ impl LpPropertiesView { fn image_size(&self, _image_size: Option) -> String { if let Some(image) = self.image() { match image.dimension_details() { - ImageDimensionDetails::Svg((width, height)) - if width.unit != rsvg::LengthUnit::Px - && height.unit != rsvg::LengthUnit::Px => - { - // Percent is not stored as percentile - let width_factor = if width.unit == rsvg::LengthUnit::Percent { - 100. - } else { - 1. - }; - let height_factor = if height.unit == rsvg::LengthUnit::Percent { - 100. - } else { - 1. - }; - - // Only show two digits - let width_n = (width.length * width_factor * 100.).round() / 100.; - let height_n = (height.length * height_factor * 100.).round() / 100.; - - let width_unit = width.unit; - let height_unit = height.unit; - - format!("{width_n}\u{202F}{width_unit} \u{D7} {height_n}\u{202F}{height_unit}") - } + ImageDimensionDetails::Svg(string) => string, _ => { let (width, height) = image.image_size(); if width > 0 && height > 0 {