Skip to content

Commit

Permalink
Update resvg dependency of egui_extras (#3719)
Browse files Browse the repository at this point in the history
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 #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 <#3652>.
  • Loading branch information
PingPongun authored Dec 20, 2023
1 parent add1695 commit 963be24
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 113 deletions.
118 changes: 55 additions & 63 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions crates/egui/src/load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion crates/egui_extras/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 25 additions & 33 deletions crates/egui_extras/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down Expand Up @@ -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.
Expand All @@ -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)?,
))
}

Expand Down Expand Up @@ -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.
Expand All @@ -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());

Expand Down
12 changes: 2 additions & 10 deletions crates/egui_extras/src/loaders/svg_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ use egui::{
ColorImage,
};

use resvg::usvg;

type Entry = Result<Arc<ColorImage>, String>;

#[derive(Default)]
Expand Down Expand Up @@ -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 {
Expand Down
Loading

0 comments on commit 963be24

Please sign in to comment.