diff --git a/Cargo.lock b/Cargo.lock index 28307f76e68..db4a0ac26fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -478,6 +478,12 @@ version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bincode" version = "1.3.3" @@ -1582,6 +1588,28 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "fontconfig-parser" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a595cb550439a117696039dfc69830492058211b771a2a165379f2a1a53d84d" +dependencies = [ + "roxmltree 0.19.0", +] + +[[package]] +name = "fontdb" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e32eac81c1135c1df01d4e6d4233c47ba11f6a6d07f33e0bba09d18797077770" +dependencies = [ + "fontconfig-parser", + "log", + "slotmap", + "tinyvec", + "ttf-parser 0.21.1", +] + [[package]] name = "foreign-types" version = "0.5.0" @@ -2224,11 +2252,12 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" [[package]] name = "kurbo" -version = "0.9.5" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd85a5776cd9500c2e2059c8c76c3b01528566b7fcbaf8098b55a33fc298849b" +checksum = "6e5aa9f0f96a938266bdb12928a67169e8d22c6a786fda8ed984b85e6ba93c3c" dependencies = [ "arrayvec", + "smallvec", ] [[package]] @@ -2694,7 +2723,7 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "706de7e2214113d63a8238d1910463cfce781129a6f263d13fdb09ff64355ba4" dependencies = [ - "ttf-parser", + "ttf-parser 0.19.1", ] [[package]] @@ -2791,7 +2820,7 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9d34169e64b3c7a80c8621a48adaf44e0cf62c78a9b25dd9dd35f1881a17cf9" dependencies = [ - "base64", + "base64 0.21.4", "indexmap", "line-wrap", "quick-xml 0.31.0", @@ -3029,12 +3058,6 @@ dependencies = [ "crossbeam-utils", ] -[[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.2.16" @@ -3101,9 +3124,9 @@ checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" [[package]] name = "resvg" -version = "0.37.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadccb3d99a9efb8e5e00c16fbb732cbe400db2ec7fc004697ee7d97d86cf1f4" +checksum = "944d052815156ac8fa77eaac055220e95ba0b01fa8887108ca710c03805d9051" dependencies = [ "log", "pico-args", @@ -3166,7 +3189,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" dependencies = [ - "base64", + "base64 0.21.4", "bitflags 2.5.0", "serde", "serde_derive", @@ -3178,6 +3201,12 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3cd14fd5e3b777a7422cca79358c57a8f6e3a703d9ac187448d0daf220c2407f" +[[package]] +name = "roxmltree" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -3239,6 +3268,22 @@ dependencies = [ "untrusted", ] +[[package]] +name = "rustybuzz" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfb9cf8877777222e4a3bc7eb247e398b56baba500c38c1c46842431adc8b55c" +dependencies = [ + "bitflags 2.5.0", + "bytemuck", + "smallvec", + "ttf-parser 0.21.1", + "unicode-bidi-mirroring", + "unicode-ccc", + "unicode-properties", + "unicode-script", +] + [[package]] name = "ryu" version = "1.0.15" @@ -3405,9 +3450,9 @@ dependencies = [ [[package]] name = "siphasher" -version = "0.3.11" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" [[package]] name = "slab" @@ -3520,9 +3565,9 @@ dependencies = [ [[package]] name = "svgtypes" -version = "0.13.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e44e288cd960318917cbd540340968b90becc8bc81f171345d706e7a89d9d70" +checksum = "fae3064df9b89391c9a76a0425a69d124aee9c5c28455204709e72c39868a43c" dependencies = [ "kurbo", "siphasher", @@ -3696,9 +3741,9 @@ dependencies = [ [[package]] name = "tiny-skia" -version = "0.11.3" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6a067b809476893fce6a254cf285850ff69c847e6cfbade6a20b655b6c7e80d" +checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab" dependencies = [ "arrayref", "arrayvec", @@ -3711,9 +3756,9 @@ dependencies = [ [[package]] name = "tiny-skia-path" -version = "0.11.3" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de35e8a90052baaaf61f171680ac2f8e925a1e43ea9d2e3a00514772250e541" +checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" dependencies = [ "arrayref", "bytemuck", @@ -3817,6 +3862,12 @@ version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a464a4b34948a5f67fddd2b823c62d9d92e44be75058b99939eae6c5b6960b33" +[[package]] +name = "ttf-parser" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8" + [[package]] name = "type-map" version = "0.5.0" @@ -3857,6 +3908,18 @@ version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +[[package]] +name = "unicode-bidi-mirroring" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23cb788ffebc92c5948d0e997106233eeb1d8b9512f93f41651f52b6c5f5af86" + +[[package]] +name = "unicode-ccc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df77b101bcc4ea3d78dafc5ad7e4f58ceffe0b2b16bf446aeb50b6cb4157656" + [[package]] name = "unicode-ident" version = "1.0.12" @@ -3872,12 +3935,30 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-properties" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" + +[[package]] +name = "unicode-script" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8d71f5726e5f285a935e9fe8edfd53f0491eb6e9a5774097fdabee7cd8c9cd" + [[package]] name = "unicode-segmentation" version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +[[package]] +name = "unicode-vo" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d386ff53b415b7fe27b50bb44679e2cc4660272694b7b6f3326d8480823a94" + [[package]] name = "unicode-width" version = "0.1.11" @@ -3908,7 +3989,7 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5ccd538d4a604753ebc2f17cd9946e89b77bf87f6a8e2309667c6f2e87855e3" dependencies = [ - "base64", + "base64 0.21.4", "flate2", "log", "once_cell", @@ -3939,46 +4020,29 @@ dependencies = [ [[package]] name = "usvg" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b0a51b72ab80ca511d126b77feeeb4fb1e972764653e61feac30adc161a756" -dependencies = [ - "base64", - "log", - "pico-args", - "usvg-parser", - "usvg-tree", - "xmlwriter", -] - -[[package]] -name = "usvg-parser" -version = "0.37.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bd4e3c291f45d152929a31f0f6c819245e2921bfd01e7bd91201a9af39a2bdc" +checksum = "b84ea542ae85c715f07b082438a4231c3760539d902e11d093847a0b22963032" dependencies = [ + "base64 0.22.1", "data-url", "flate2", + "fontdb", "imagesize", "kurbo", "log", - "roxmltree", + "pico-args", + "roxmltree 0.20.0", + "rustybuzz", "simplecss", "siphasher", - "svgtypes", - "usvg-tree", -] - -[[package]] -name = "usvg-tree" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee3d202ebdb97a6215604b8f5b4d6ef9024efd623cf2e373a6416ba976ec7d3" -dependencies = [ - "rctree", "strict-num", "svgtypes", "tiny-skia-path", + "unicode-bidi", + "unicode-script", + "unicode-vo", + "xmlwriter", ] [[package]] diff --git a/crates/egui_extras/Cargo.toml b/crates/egui_extras/Cargo.toml index b5d8efffac7..ba8c13a6e75 100644 --- a/crates/egui_extras/Cargo.toml +++ b/crates/egui_extras/Cargo.toml @@ -57,6 +57,9 @@ puffin = ["dep:puffin", "egui/puffin"] ## Support loading svg images. svg = ["resvg"] +## Support rendering text in svg images. +svg_text = ["svg", "resvg/text", "resvg/system-fonts"] + ## Enable better syntax highlighting using [`syntect`](https://docs.rs/syntect). syntect = ["dep:syntect"] @@ -94,7 +97,7 @@ syntect = { version = "5", optional = true, default-features = false, features = ] } # svg feature -resvg = { version = "0.37", optional = true, default-features = false } +resvg = { version = "0.42", optional = true, default-features = false } # http feature ehttp = { version = "0.5", optional = true, default-features = false } diff --git a/crates/egui_extras/src/image.rs b/crates/egui_extras/src/image.rs index f6301aec823..fcc22e11522 100644 --- a/crates/egui_extras/src/image.rs +++ b/crates/egui_extras/src/image.rs @@ -235,45 +235,50 @@ pub fn load_svg_bytes_with_size( size_hint: Option, ) -> Result { use resvg::tiny_skia::{IntSize, Pixmap}; - use resvg::usvg::{Options, Tree, TreeParsing}; + use resvg::usvg::{Options, Transform, Tree}; crate::profile_function!(); - let opt = Options::default(); - let mut rtree = Tree::from_data(svg_bytes, &opt).map_err(|err| err.to_string())?; - - let mut size = rtree.size.to_int_size(); - match size_hint { - None => (), - Some(SizeHint::Size(w, h)) => { - size = size.scale_to( - IntSize::from_wh(w, h).ok_or_else(|| format!("Failed to scale SVG to {w}x{h}"))?, - ); - } - Some(SizeHint::Height(h)) => { - size = size - .scale_to_height(h) - .ok_or_else(|| format!("Failed to scale SVG to height {h}"))?; - } - Some(SizeHint::Width(w)) => { - size = size - .scale_to_width(w) - .ok_or_else(|| format!("Failed to scale SVG to width {w}"))?; - } + // opt is mutated when `svg_text` feature flag is enabled + #[allow(unused_mut)] + let mut opt = Options::default(); + + #[cfg(feature = "svg_text")] + opt.fontdb_mut().load_system_fonts(); + + let rtree = Tree::from_data(svg_bytes, &opt).map_err(|err| err.to_string())?; + + let size = rtree.size().to_int_size(); + let scaled_size = match size_hint { + None => size, + Some(SizeHint::Size(w, h)) => size.scale_to( + IntSize::from_wh(w, h).ok_or_else(|| format!("Failed to scale SVG to {w}x{h}"))?, + ), + Some(SizeHint::Height(h)) => size + .scale_to_height(h) + .ok_or_else(|| format!("Failed to scale SVG to height {h}"))?, + Some(SizeHint::Width(w)) => size + .scale_to_width(w) + .ok_or_else(|| format!("Failed to scale SVG to width {w}"))?, Some(SizeHint::Scale(z)) => { let z_inner = z.into_inner(); - size = size - .scale_by(z_inner) - .ok_or_else(|| format!("Failed to scale SVG by {z_inner}"))?; + size.scale_by(z_inner) + .ok_or_else(|| format!("Failed to scale SVG by {z_inner}"))? } }; - let (w, h) = (size.width(), size.height()); + let (w, h) = (scaled_size.width(), scaled_size.height()); let mut pixmap = Pixmap::new(w, h).ok_or_else(|| format!("Failed to create SVG Pixmap of size {w}x{h}"))?; - rtree.size = size.to_size(); - resvg::Tree::from_usvg(&rtree).render(Default::default(), &mut pixmap.as_mut()); + resvg::render( + &rtree, + Transform::from_scale( + w as f32 / size.width() as f32, + h as f32 / size.height() as f32, + ), + &mut pixmap.as_mut(), + ); let image = egui::ColorImage::from_rgba_unmultiplied([w as _, h as _], pixmap.data());