2024-01-01 22:41:56 +01:00
|
|
|
// Copyright (c) 2023-2024 Sophie Herold
|
2023-04-19 20:02:01 +02:00
|
|
|
//
|
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
// (at your option) any later version.
|
|
|
|
|
//
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
|
//
|
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
//
|
|
|
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
|
|
2023-05-23 01:49:40 +02:00
|
|
|
//! Decode using librsvg
|
2023-12-26 22:07:46 +01:00
|
|
|
|
2023-12-06 23:45:02 +01:00
|
|
|
use std::sync::Arc;
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
|
|
|
|
|
use anyhow::Context;
|
2023-08-04 13:20:41 +02:00
|
|
|
use async_channel as mpsc;
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
use gtk::prelude::*;
|
|
|
|
|
|
2023-12-06 23:45:02 +01:00
|
|
|
use super::*;
|
2023-12-26 22:07:46 +01:00
|
|
|
use crate::decoder::tiling::SharedFrameBuffer;
|
2023-12-06 23:45:02 +01:00
|
|
|
use crate::decoder::TileRequest;
|
|
|
|
|
use crate::deps::*;
|
2024-01-01 22:41:56 +01:00
|
|
|
use crate::metadata::Metadata;
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
|
2023-03-09 21:27:51 +01:00
|
|
|
/// Current librsvg limit on maximum dimensions. See
|
|
|
|
|
/// <https://gitlab.gnome.org/GNOME/librsvg/-/issues/938>
|
|
|
|
|
pub const RSVG_MAX_SIZE: u32 = 32_767;
|
|
|
|
|
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
#[derive(Debug)]
|
|
|
|
|
pub struct Svg {
|
2023-08-04 13:20:41 +02:00
|
|
|
wakeup: mpsc::Sender<()>,
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
current_request: Arc<std::sync::RwLock<Request>>,
|
2023-04-27 22:05:44 +02:00
|
|
|
cancellable: gio::Cancellable,
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Default, Debug, Clone)]
|
|
|
|
|
enum Request {
|
|
|
|
|
#[default]
|
|
|
|
|
None,
|
|
|
|
|
Tile(TileRequest),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Request {
|
|
|
|
|
fn is_waiting(&self) -> bool {
|
|
|
|
|
!matches!(self, Self::None)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Drop for Svg {
|
|
|
|
|
fn drop(&mut self) {
|
2023-04-27 22:05:44 +02:00
|
|
|
self.cancellable.cancel();
|
2023-08-04 13:20:41 +02:00
|
|
|
let _ = self.wakeup.try_send(());
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Svg {
|
2023-12-26 22:07:46 +01:00
|
|
|
pub fn new(file: gio::File, updater: UpdateSender, tiles: Arc<SharedFrameBuffer>) -> Self {
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
let current_request: Arc<std::sync::RwLock<Request>> = Default::default();
|
|
|
|
|
let request_store = current_request.clone();
|
2023-04-27 22:05:44 +02:00
|
|
|
let cancellable = gio::Cancellable::new();
|
|
|
|
|
let cancellable_ = cancellable.clone();
|
2023-08-04 13:20:41 +02:00
|
|
|
let (wakeup, wakeup_resv) = mpsc::unbounded();
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
|
2023-08-04 13:20:41 +02:00
|
|
|
updater.clone().spawn_error_handled(async move {
|
2024-02-29 14:21:26 +01:00
|
|
|
log::trace!("Setting up SVG loader");
|
2024-02-22 01:23:06 +01:00
|
|
|
let mut loader = glycin::Loader::new(file);
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
|
2023-08-04 13:20:41 +02:00
|
|
|
#[cfg(feature = "disable-glycin-sandbox")]
|
2024-02-22 01:23:06 +01:00
|
|
|
loader.sandbox_mechanism(Some(glycin::SandboxMechanism::NotSandboxed));
|
2023-08-04 13:20:41 +02:00
|
|
|
|
2024-02-22 01:23:06 +01:00
|
|
|
loader.cancellable(cancellable.clone());
|
2023-08-04 13:20:41 +02:00
|
|
|
|
2024-02-22 01:23:06 +01:00
|
|
|
let image = loader.load().await?;
|
2023-08-04 13:20:41 +02:00
|
|
|
|
2024-01-01 22:41:56 +01:00
|
|
|
let mut metadata: Metadata = Metadata::default();
|
|
|
|
|
metadata.set_image_info(image.info().details.clone());
|
|
|
|
|
metadata.set_mime_type(image.mime_type());
|
|
|
|
|
updater.send(DecoderUpdate::Metadata(Box::new(metadata)));
|
|
|
|
|
|
|
|
|
|
tiles.set_original_dimensions((image.info().width, image.info().height));
|
2023-08-04 13:20:41 +02:00
|
|
|
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
loop {
|
|
|
|
|
let tile_request = {
|
2023-08-04 13:20:41 +02:00
|
|
|
let mut request = request_store.write().unwrap();
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
let value = request.clone();
|
|
|
|
|
*request = Request::None;
|
|
|
|
|
value
|
|
|
|
|
};
|
|
|
|
|
|
2023-04-27 22:05:44 +02:00
|
|
|
if cancellable.is_cancelled() {
|
|
|
|
|
log::debug!("Terminating SVG decoder thread");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
match tile_request {
|
|
|
|
|
Request::None => {
|
2023-08-04 13:20:41 +02:00
|
|
|
let result = wakeup_resv.recv().await;
|
|
|
|
|
if result.is_err() {
|
|
|
|
|
return Ok(());
|
|
|
|
|
}
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
}
|
2023-04-27 22:05:44 +02:00
|
|
|
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
Request::Tile(tile_request) => {
|
2023-04-16 01:36:38 +02:00
|
|
|
let tiling = tiles
|
|
|
|
|
.get_layer_tiling_or_default(tile_request.zoom, tile_request.viewport);
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
|
2023-04-16 01:36:38 +02:00
|
|
|
let relevant_tiles = tiling.relevant_tiles(&tile_request.area);
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
|
|
|
|
|
for tile_instructions in relevant_tiles {
|
2023-08-04 13:20:41 +02:00
|
|
|
if request_store.read().ok().unwrap().is_waiting() {
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if tiles
|
|
|
|
|
.load()
|
|
|
|
|
.contains(tile_request.zoom, tile_instructions.coordinates)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let (total_width, total_height) =
|
|
|
|
|
tile_instructions.tiling.scaled_dimensions();
|
2023-08-04 13:20:41 +02:00
|
|
|
let area = tile_instructions.area_with_bleed();
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
|
2023-08-04 13:20:41 +02:00
|
|
|
let frame_request = glycin::FrameRequest::new()
|
|
|
|
|
.scale(total_width, total_height)
|
|
|
|
|
.clip(
|
|
|
|
|
area.x() as u32,
|
|
|
|
|
area.y() as u32,
|
|
|
|
|
area.width() as u32,
|
|
|
|
|
area.height() as u32,
|
|
|
|
|
);
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
|
2023-08-04 13:20:41 +02:00
|
|
|
let frame = image.specific_frame(frame_request).await?;
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
|
2023-04-16 01:36:38 +02:00
|
|
|
let position = (
|
|
|
|
|
tile_instructions.area.x() as u32,
|
|
|
|
|
tile_instructions.area.y() as u32,
|
|
|
|
|
);
|
|
|
|
|
|
2023-08-04 13:20:41 +02:00
|
|
|
tiles.push_tile(tiling, position, frame.texture);
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
Self {
|
2023-08-04 13:20:41 +02:00
|
|
|
wakeup,
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
current_request,
|
2023-04-27 22:05:44 +02:00
|
|
|
cancellable: cancellable_,
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-10 17:53:15 +02:00
|
|
|
pub fn request(&self, request: TileRequest) -> anyhow::Result<()> {
|
|
|
|
|
let mut current_request = self
|
|
|
|
|
.current_request
|
|
|
|
|
.write()
|
|
|
|
|
.ok()
|
|
|
|
|
.context("RwLock is poisoned")?;
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
*current_request = Request::Tile(request);
|
2023-08-04 13:20:41 +02:00
|
|
|
self.wakeup.try_send(())?;
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
2023-04-17 22:38:52 +02:00
|
|
|
|
2023-08-04 13:20:41 +02:00
|
|
|
pub fn render_print(file: &gio::File, width: i32, height: i32) -> anyhow::Result<gdk::Texture> {
|
|
|
|
|
#[allow(unused_mut)]
|
2024-02-22 01:23:06 +01:00
|
|
|
let mut loader = glycin::Loader::new(file.clone());
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
|
2023-08-04 13:20:41 +02:00
|
|
|
#[cfg(feature = "disable-glycin-sandbox")]
|
2024-02-22 01:23:06 +01:00
|
|
|
loader.sandbox_mechanism(Some(glycin::SandboxMechanism::NotSandboxed));
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
|
2024-02-22 01:23:06 +01:00
|
|
|
let image = futures_lite::future::block_on(loader.load())?;
|
2023-08-04 13:20:41 +02:00
|
|
|
let frame_request = glycin::FrameRequest::new().scale(width as u32, height as u32);
|
2023-12-25 21:52:00 +01:00
|
|
|
let frame = futures_lite::future::block_on(image.specific_frame(frame_request))?;
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
|
2023-08-04 13:20:41 +02:00
|
|
|
Ok(frame.texture)
|
decoder: Use image-rs, libheif-rs, librsvg
This adds proper support for a lot of image formats including SVGs.
It will be the basis for many features to come. The technical core
is an asynchronous renderer that can arrange textures in smaller tiles
which might be generated on demand.
Closes #34, #40, #41, #49
Basis for fixing the following issues #7, #27, #36, #43, #68, #71
2023-03-04 03:14:52 +01:00
|
|
|
}
|
|
|
|
|
}
|