From c3547f82fc5f85eecebfc49e2deb25780ae84df4 Mon Sep 17 00:00:00 2001 From: Sophie Herold Date: Mon, 29 Jul 2024 03:32:13 +0200 Subject: [PATCH] svg: Handle errors for additional tiles gracefully Some SVGs run into issues when zooming in due to memory limitations. These errors are now ignored and the existing tiles are used. Issue #358 --- .../fixed-svg-dont-fail-on-additional-tails | 1 + src/decoder.rs | 30 +++++++++++-------- src/decoder/formats/svg.rs | 20 ++++++++----- src/widgets/image/loading.rs | 16 +++++++--- 4 files changed, 43 insertions(+), 24 deletions(-) create mode 100644 news.d/47.beta/fixed-svg-dont-fail-on-additional-tails diff --git a/news.d/47.beta/fixed-svg-dont-fail-on-additional-tails b/news.d/47.beta/fixed-svg-dont-fail-on-additional-tails new file mode 100644 index 0000000..f2ac281 --- /dev/null +++ b/news.d/47.beta/fixed-svg-dont-fail-on-additional-tails @@ -0,0 +1 @@ +Don't show error-screen if SVG has been loaded and only the rendering for tiles for other zoom levels fails. Instead, show the already loaded tiles. diff --git a/src/decoder.rs b/src/decoder.rs index 05b52e0..11906cc 100644 --- a/src/decoder.rs +++ b/src/decoder.rs @@ -116,22 +116,26 @@ impl UpdateSender { let result: Result<(), glycin::ErrorCtx> = f.await; if let Err(err) = result { - if err.unsupported_format().is_some() { - update_sender.send(DecoderUpdate::SpecificError( - DecoderError::UnsupportedFormat, - )); - } - if err.is_out_of_memory() { - update_sender.send(DecoderUpdate::SpecificError(DecoderError::OutOfMemory)); - } else if matches!(err.error(), glycin::Error::NoLoadersConfigured(_)) { - update_sender.send(DecoderUpdate::SpecificError( - DecoderError::NoLoadersConfigured, - )); - } - update_sender.send(DecoderUpdate::GenericError(err.into())); + update_sender.send_error(err); } }) } + + pub fn send_error(&self, err: glycin::ErrorCtx) { + if err.unsupported_format().is_some() { + self.send(DecoderUpdate::SpecificError( + DecoderError::UnsupportedFormat, + )); + } + if err.is_out_of_memory() { + self.send(DecoderUpdate::SpecificError(DecoderError::OutOfMemory)); + } else if matches!(err.error(), glycin::Error::NoLoadersConfigured(_)) { + self.send(DecoderUpdate::SpecificError( + DecoderError::NoLoadersConfigured, + )); + } + self.send(DecoderUpdate::GenericError(err.into())); + } } #[derive(Debug)] diff --git a/src/decoder/formats/svg.rs b/src/decoder/formats/svg.rs index 53fde14..cdc3871 100644 --- a/src/decoder/formats/svg.rs +++ b/src/decoder/formats/svg.rs @@ -71,6 +71,7 @@ impl Svg { updater.clone().spawn_error_handled(async move { log::trace!("Setting up SVG loader"); let mut loader = glycin::Loader::new(file); + loader.sandbox_selector(glycin::SandboxSelector::FlatpakSpawn); loader.cancellable(cancellable.clone()); @@ -135,14 +136,19 @@ impl Svg { area.height() as u32, ); - let frame = image.specific_frame(frame_request).await?; + match image.specific_frame(frame_request).await { + Ok(frame) => { + let position = ( + tile_instructions.area.x() as u32, + tile_instructions.area.y() as u32, + ); - let position = ( - tile_instructions.area.x() as u32, - tile_instructions.area.y() as u32, - ); - - tiles.push_tile(tiling, position, frame.texture()); + tiles.push_tile(tiling, position, frame.texture()); + } + Err(err) => { + updater.send_error(err); + } + } } } } diff --git a/src/widgets/image/loading.rs b/src/widgets/image/loading.rs index ab69387..8b8fc4b 100644 --- a/src/widgets/image/loading.rs +++ b/src/widgets/image/loading.rs @@ -112,9 +112,6 @@ impl imp::LpImage { )); } } - DecoderUpdate::GenericError(err) => { - self.set_error(Some(err)); - } DecoderUpdate::Animated => { if self.still.get() { // Just load the first frame @@ -131,7 +128,18 @@ impl imp::LpImage { } } DecoderUpdate::SpecificError(err) => { - self.set_specific_error(err); + if self.obj().is_loaded() { + log::warn!("Error occured while loading additional data: {err:?}"); + } else { + self.set_specific_error(err); + } + } + DecoderUpdate::GenericError(err) => { + if self.obj().is_loaded() { + log::warn!("Error occured while loading additional data: {err:?}"); + } else { + self.set_error(Some(err)); + } } } }