Browse Source

Update resvg dependency of egui_extras (#3719)

Update `resvg` from v0.28 to v0.37. 
Remove related, unnecessary entries from `deny.toml`.

⚠ In example `images` ferris is scaled differently, but I guess that now
it scales in expected way (takes all available space; before this PR it
takes up to space that, was available at first render- it does not
upscale).

This PR is minimal adaptation to new `resvg` api and small related
simplification, however it should be considered to update loaders
(currently if svg image initially was small and was scaled up it will be
blurred, see https://github.com/emilk/egui/issues/3501). As svg image
now scales over render size, problem will be more often seen now.

(currently `SvgLoader` theoretically should rerender for different sizes
(but I guess it will result in memory leak in that case), but refreshing
is stopped earlier in `DefaultTextureLoader`).

I have initial version of loaders update, that will fix issue with svg
scaling (and also enable e.g. reloading image if file has been changed),
I will submit these changes in separate PR once this one is merged.

Closes <https://github.com/emilk/egui/issues/3652>.
pull/3727/head
PingPongun 11 months ago
committed by GitHub
parent
commit
963be247f2
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 118
      Cargo.lock
  2. 2
      crates/egui/src/load.rs
  3. 2
      crates/egui_extras/Cargo.toml
  4. 58
      crates/egui_extras/src/image.rs
  5. 12
      crates/egui_extras/src/loaders/svg_loader.rs
  6. 4
      deny.toml

118
Cargo.lock

@ -474,12 +474,6 @@ dependencies = [
"rustc-demangle",
]
[[package]]
name = "base64"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]]
name = "base64"
version = "0.21.4"
@ -1061,9 +1055,9 @@ dependencies = [
[[package]]
name = "data-url"
version = "0.2.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d7439c3735f405729d52c3fbbe4de140eaf938a1fe47d227c27f8254d4302a5"
checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a"
[[package]]
name = "deranged"
@ -2091,9 +2085,9 @@ dependencies = [
[[package]]
name = "imagesize"
version = "0.10.1"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df19da1e92fbfec043ca97d622955381b1f3ee72a180ec999912df31b1ccd951"
checksum = "029d73f573d8e8d63e6d5020011d3255b28c3ba85d6cf870a07184ed23de9284"
[[package]]
name = "indexmap"
@ -2224,9 +2218,9 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
[[package]]
name = "kurbo"
version = "0.8.3"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a53776d271cfb873b17c618af0298445c88afc52837f3e948fa3fafd131f449"
checksum = "bd85a5776cd9500c2e2059c8c76c3b01528566b7fcbaf8098b55a33fc298849b"
dependencies = [
"arrayvec",
]
@ -2775,7 +2769,7 @@ version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5699cc8a63d1aa2b1ee8e12b9ad70ac790d65788cd36101fa37f87ea46c4cef"
dependencies = [
"base64 0.21.4",
"base64",
"indexmap",
"line-wrap",
"quick-xml 0.31.0",
@ -3070,15 +3064,15 @@ checksum = "216080ab382b992234dda86873c18d4c48358f5cfcb70fd693d7f6f2131b628b"
[[package]]
name = "resvg"
version = "0.28.0"
version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c115863f2d3621999cf187e318bc92b16402dfeff6a48c74df700d77381394c1"
checksum = "cadccb3d99a9efb8e5e00c16fbb732cbe400db2ec7fc004697ee7d97d86cf1f4"
dependencies = [
"log",
"pico-args",
"rgb",
"svgtypes",
"tiny-skia 0.8.4",
"tiny-skia",
"usvg",
]
@ -3137,7 +3131,7 @@ version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94"
dependencies = [
"base64 0.21.4",
"base64",
"bitflags 2.4.0",
"serde",
"serde_derive",
@ -3145,12 +3139,9 @@ dependencies = [
[[package]]
name = "roxmltree"
version = "0.15.1"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b9de9831a129b122e7e61f242db509fa9d0838008bf0b29bb0624669edfe48a"
dependencies = [
"xmlparser",
]
checksum = "3cd14fd5e3b777a7422cca79358c57a8f6e3a703d9ac187448d0daf220c2407f"
[[package]]
name = "rustc-demangle"
@ -3286,7 +3277,7 @@ dependencies = [
"log",
"memmap2",
"smithay-client-toolkit",
"tiny-skia 0.11.2",
"tiny-skia",
]
[[package]]
@ -3516,10 +3507,11 @@ dependencies = [
[[package]]
name = "svgtypes"
version = "0.8.2"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22975e8a2bac6a76bb54f898a6b18764633b00e780330f0b689f65afb3975564"
checksum = "6e44e288cd960318917cbd540340968b90becc8bc81f171345d706e7a89d9d70"
dependencies = [
"kurbo",
"siphasher",
]
@ -3674,48 +3666,24 @@ dependencies = [
[[package]]
name = "tiny-skia"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df8493a203431061e901613751931f047d1971337153f96d0e5e363d6dbf6a67"
dependencies = [
"arrayref",
"arrayvec",
"bytemuck",
"cfg-if",
"png",
"tiny-skia-path 0.8.4",
]
[[package]]
name = "tiny-skia"
version = "0.11.2"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b72a92a05db376db09fe6d50b7948d106011761c05a6a45e23e17ee9b556222"
checksum = "b6a067b809476893fce6a254cf285850ff69c847e6cfbade6a20b655b6c7e80d"
dependencies = [
"arrayref",
"arrayvec",
"bytemuck",
"cfg-if",
"log",
"tiny-skia-path 0.11.2",
]
[[package]]
name = "tiny-skia-path"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adbfb5d3f3dd57a0e11d12f4f13d4ebbbc1b5c15b7ab0a156d030b21da5f677c"
dependencies = [
"arrayref",
"bytemuck",
"strict-num",
"png",
"tiny-skia-path",
]
[[package]]
name = "tiny-skia-path"
version = "0.11.2"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ac3865b9708fc7e1961a65c3a4fa55e984272f33092d3c859929f887fceb647"
checksum = "5de35e8a90052baaaf61f171680ac2f8e925a1e43ea9d2e3a00514772250e541"
dependencies = [
"arrayref",
"bytemuck",
@ -3910,7 +3878,7 @@ version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5ccd538d4a604753ebc2f17cd9946e89b77bf87f6a8e2309667c6f2e87855e3"
dependencies = [
"base64 0.21.4",
"base64",
"flate2",
"log",
"once_cell",
@ -3941,22 +3909,46 @@ dependencies = [
[[package]]
name = "usvg"
version = "0.28.0"
version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b5b7c2b30845b3348c067ca3d09e20cc6e327c288f0ca4c48698712abf432e9"
checksum = "38b0a51b72ab80ca511d126b77feeeb4fb1e972764653e61feac30adc161a756"
dependencies = [
"base64",
"log",
"pico-args",
"usvg-parser",
"usvg-tree",
"xmlwriter",
]
[[package]]
name = "usvg-parser"
version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bd4e3c291f45d152929a31f0f6c819245e2921bfd01e7bd91201a9af39a2bdc"
dependencies = [
"base64 0.13.1",
"data-url",
"flate2",
"imagesize",
"kurbo",
"log",
"rctree",
"roxmltree",
"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",
]
[[package]]
@ -4693,10 +4685,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a"
[[package]]
name = "xmlparser"
version = "0.13.5"
name = "xmlwriter"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d25c75bf9ea12c4040a97f829154768bbbce366287e2dc044af160cd79a13fd"
checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9"
[[package]]
name = "yaml-rust"

2
crates/egui/src/load.rs

@ -127,8 +127,6 @@ pub type Result<T, E = LoadError> = std::result::Result<T, E>;
/// Used mostly for rendering SVG:s to a good size.
///
/// All variants will preserve the original aspect ratio.
///
/// Similar to `usvg::FitTo`.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum SizeHint {
/// Scale original size by some factor.

2
crates/egui_extras/Cargo.toml

@ -92,7 +92,7 @@ syntect = { version = "5", optional = true, default-features = false, features =
] }
# svg feature
resvg = { version = "0.28", optional = true, default-features = false }
resvg = { version = "0.37", optional = true, default-features = false }
# http feature
ehttp = { version = "0.3.1", optional = true, default-features = false }

58
crates/egui_extras/src/image.rs

@ -3,10 +3,7 @@
use egui::{mutex::Mutex, TextureOptions};
#[cfg(feature = "svg")]
use resvg::{tiny_skia, usvg};
#[cfg(feature = "svg")]
pub use usvg::FitTo;
use egui::SizeHint;
/// An image to be shown in egui.
///
@ -67,7 +64,7 @@ impl RetainedImage {
/// On invalid image
#[cfg(feature = "svg")]
pub fn from_svg_bytes(debug_name: impl Into<String>, svg_bytes: &[u8]) -> Result<Self, String> {
Self::from_svg_bytes_with_size(debug_name, svg_bytes, FitTo::Original)
Self::from_svg_bytes_with_size(debug_name, svg_bytes, None)
}
/// Pass in the str of an SVG that you've loaded.
@ -88,11 +85,11 @@ impl RetainedImage {
pub fn from_svg_bytes_with_size(
debug_name: impl Into<String>,
svg_bytes: &[u8],
size: FitTo,
size_hint: Option<SizeHint>,
) -> Result<Self, String> {
Ok(Self::from_color_image(
debug_name,
load_svg_bytes_with_size(svg_bytes, size)?,
load_svg_bytes_with_size(svg_bytes, size_hint)?,
))
}
@ -223,7 +220,7 @@ pub fn load_image_bytes(image_bytes: &[u8]) -> Result<egui::ColorImage, String>
/// On invalid image
#[cfg(feature = "svg")]
pub fn load_svg_bytes(svg_bytes: &[u8]) -> Result<egui::ColorImage, String> {
load_svg_bytes_with_size(svg_bytes, FitTo::Original)
load_svg_bytes_with_size(svg_bytes, None)
}
/// Load an SVG and rasterize it into an egui image with a scaling parameter.
@ -235,36 +232,31 @@ pub fn load_svg_bytes(svg_bytes: &[u8]) -> Result<egui::ColorImage, String> {
#[cfg(feature = "svg")]
pub fn load_svg_bytes_with_size(
svg_bytes: &[u8],
fit_to: FitTo,
size_hint: Option<SizeHint>,
) -> Result<egui::ColorImage, String> {
use resvg::tiny_skia::{IntSize, Pixmap};
use resvg::usvg::{Options, Tree, TreeParsing};
crate::profile_function!();
let opt = usvg::Options::default();
let rtree = usvg::Tree::from_data(svg_bytes, &opt).map_err(|err| err.to_string())?;
let pixmap_size = rtree.size.to_screen_size();
let [w, h] = match fit_to {
FitTo::Original => [pixmap_size.width(), pixmap_size.height()],
FitTo::Size(w, h) => [w, h],
FitTo::Height(h) => [
(pixmap_size.width() as f32 * (h as f32 / pixmap_size.height() as f32)) as u32,
h,
],
FitTo::Width(w) => [
w,
(pixmap_size.height() as f32 * (w as f32 / pixmap_size.width() as f32)) as u32,
],
FitTo::Zoom(z) => [
(pixmap_size.width() as f32 * z) as u32,
(pixmap_size.height() as f32 * z) as u32,
],
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).unwrap()),
Some(SizeHint::Height(h)) => size = size.scale_to_height(h).unwrap(),
Some(SizeHint::Width(w)) => size = size.scale_to_width(w).unwrap(),
Some(SizeHint::Scale(z)) => size = size.scale_by(z.into_inner()).unwrap(),
};
let (w, h) = (size.width(), size.height());
let mut pixmap = tiny_skia::Pixmap::new(w, h)
.ok_or_else(|| format!("Failed to create SVG Pixmap of size {w}x{h}"))?;
let mut pixmap =
Pixmap::new(w, h).ok_or_else(|| format!("Failed to create SVG Pixmap of size {w}x{h}"))?;
resvg::render(&rtree, fit_to, Default::default(), pixmap.as_mut())
.ok_or_else(|| "Failed to render SVG".to_owned())?;
rtree.size = size.to_size();
resvg::Tree::from_usvg(&rtree).render(Default::default(), &mut pixmap.as_mut());
let image = egui::ColorImage::from_rgba_unmultiplied([w as _, h as _], pixmap.data());

12
crates/egui_extras/src/loaders/svg_loader.rs

@ -7,8 +7,6 @@ use egui::{
ColorImage,
};
use resvg::usvg;
type Entry = Result<Arc<ColorImage>, String>;
#[derive(Default)]
@ -51,14 +49,8 @@ impl ImageLoader for SvgLoader {
match ctx.try_load_bytes(&uri) {
Ok(BytesPoll::Ready { bytes, .. }) => {
log::trace!("started loading {uri:?}");
let fit_to = match size_hint {
SizeHint::Scale(factor) => usvg::FitTo::Zoom(factor.into_inner()),
SizeHint::Width(w) => usvg::FitTo::Width(w),
SizeHint::Height(h) => usvg::FitTo::Height(h),
SizeHint::Size(w, h) => usvg::FitTo::Size(w, h),
};
let result =
crate::image::load_svg_bytes_with_size(&bytes, fit_to).map(Arc::new);
let result = crate::image::load_svg_bytes_with_size(&bytes, Some(size_hint))
.map(Arc::new);
log::trace!("finished loading {uri:?}");
cache.insert((uri, size_hint), result.clone());
match result {

4
deny.toml

@ -34,8 +34,6 @@ deny = [
]
skip = [
{ name = "arrayvec" }, # old version via tiny-skiaz
{ name = "base64" }, # small crate, old version from usvg
{ name = "bitflags" }, # old 1.0 version via glutin, png, spirv, …
{ name = "libloading" }, # wgpu-hal itself depends on 0.8 while some of its dependencies, like ash and d3d12, depend on 0.7
{ name = "memoffset" }, # tiny dependency
@ -43,7 +41,6 @@ skip = [
{ name = "redox_syscall" }, # old version via directories-next
{ name = "spin" }, # old version via ring through rusttls and other libraries, newer for wgpu.
{ name = "time" }, # old version pulled in by unmaintianed crate 'chrono'
{ name = "ttf-parser" }, # different versions pulled in by ab_glyph and usvg
{ name = "windows" }, # old version via accesskit_windows
]
skip-tree = [
@ -51,7 +48,6 @@ skip-tree = [
{ name = "foreign-types" }, # small crate. Old version via cocoa and core-graphics (winit).
{ name = "objc2" }, # old version via accesskit_macos
{ name = "rfd" }, # example dependency
{ name = "tiny-skia" }, # old version via old resvg in egui_extras - see https://github.com/emilk/egui/issues/3652
]

Loading…
Cancel
Save