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
This commit is contained in:
Sophie Herold 2024-07-29 03:32:13 +02:00
parent 9feef50c01
commit c3547f82fc
4 changed files with 43 additions and 24 deletions

View file

@ -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.

View file

@ -116,21 +116,25 @@ impl UpdateSender {
let result: Result<(), glycin::ErrorCtx> = f.await; let result: Result<(), glycin::ErrorCtx> = f.await;
if let Err(err) = result { if let Err(err) = result {
update_sender.send_error(err);
}
})
}
pub fn send_error(&self, err: glycin::ErrorCtx) {
if err.unsupported_format().is_some() { if err.unsupported_format().is_some() {
update_sender.send(DecoderUpdate::SpecificError( self.send(DecoderUpdate::SpecificError(
DecoderError::UnsupportedFormat, DecoderError::UnsupportedFormat,
)); ));
} }
if err.is_out_of_memory() { if err.is_out_of_memory() {
update_sender.send(DecoderUpdate::SpecificError(DecoderError::OutOfMemory)); self.send(DecoderUpdate::SpecificError(DecoderError::OutOfMemory));
} else if matches!(err.error(), glycin::Error::NoLoadersConfigured(_)) { } else if matches!(err.error(), glycin::Error::NoLoadersConfigured(_)) {
update_sender.send(DecoderUpdate::SpecificError( self.send(DecoderUpdate::SpecificError(
DecoderError::NoLoadersConfigured, DecoderError::NoLoadersConfigured,
)); ));
} }
update_sender.send(DecoderUpdate::GenericError(err.into())); self.send(DecoderUpdate::GenericError(err.into()));
}
})
} }
} }

View file

@ -71,6 +71,7 @@ impl Svg {
updater.clone().spawn_error_handled(async move { updater.clone().spawn_error_handled(async move {
log::trace!("Setting up SVG loader"); log::trace!("Setting up SVG loader");
let mut loader = glycin::Loader::new(file); let mut loader = glycin::Loader::new(file);
loader.sandbox_selector(glycin::SandboxSelector::FlatpakSpawn);
loader.cancellable(cancellable.clone()); loader.cancellable(cancellable.clone());
@ -135,8 +136,8 @@ impl Svg {
area.height() as u32, area.height() as u32,
); );
let frame = image.specific_frame(frame_request).await?; match image.specific_frame(frame_request).await {
Ok(frame) => {
let position = ( let position = (
tile_instructions.area.x() as u32, tile_instructions.area.x() as u32,
tile_instructions.area.y() as u32, tile_instructions.area.y() as u32,
@ -144,6 +145,11 @@ impl Svg {
tiles.push_tile(tiling, position, frame.texture()); tiles.push_tile(tiling, position, frame.texture());
} }
Err(err) => {
updater.send_error(err);
}
}
}
} }
} }
} }

View file

@ -112,9 +112,6 @@ impl imp::LpImage {
)); ));
} }
} }
DecoderUpdate::GenericError(err) => {
self.set_error(Some(err));
}
DecoderUpdate::Animated => { DecoderUpdate::Animated => {
if self.still.get() { if self.still.get() {
// Just load the first frame // Just load the first frame
@ -131,9 +128,20 @@ impl imp::LpImage {
} }
} }
DecoderUpdate::SpecificError(err) => { DecoderUpdate::SpecificError(err) => {
if self.obj().is_loaded() {
log::warn!("Error occured while loading additional data: {err:?}");
} else {
self.set_specific_error(err); 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));
}
}
}
} }
/// Roughly called for every frame if image is visible /// Roughly called for every frame if image is visible