refactor: move svg integration into crate

This commit is contained in:
electria 2026-08-14 11:27:07 -07:00
commit 85a80346e3
Signed by: electria
SSH key fingerprint: SHA256:8LlB3ucPbBHqozqkhsNbaV5oG3SlzzqUj8FZDL6IPQs
4 changed files with 14 additions and 74 deletions

23
Cargo.lock generated
View file

@ -1990,7 +1990,7 @@ dependencies = [
"iced", "iced",
"image", "image",
"jxl-oxide", "jxl-oxide",
"kra-image-integration", "misc-image-integration",
"resvg", "resvg",
"rfd", "rfd",
"size", "size",
@ -2327,16 +2327,6 @@ version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
[[package]]
name = "kra-image-integration"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ab1db0e6caced9f4b26057c10ea190c447a8be4fcac03afd7213e35168ad700"
dependencies = [
"image",
"zip",
]
[[package]] [[package]]
name = "kurbo" name = "kurbo"
version = "0.10.4" version = "0.10.4"
@ -2555,6 +2545,17 @@ dependencies = [
"simd-adler32", "simd-adler32",
] ]
[[package]]
name = "misc-image-integration"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8021bf53776c68684f91b0eea6317b518d6b113db09fc929f51f1c01a760ca8f"
dependencies = [
"image",
"resvg",
"zip",
]
[[package]] [[package]]
name = "moxcms" name = "moxcms"
version = "0.8.1" version = "0.8.1"

View file

@ -6,7 +6,7 @@ license = "AGPL-3.0-or-later"
[dependencies] [dependencies]
dirs = "6.0.0" dirs = "6.0.0"
kra-image-integration = "0.1.0" misc-image-integration = "0.1.0"
resvg = "0.48.1" resvg = "0.48.1"
rfd = "0.17.2" rfd = "0.17.2"
size = "0.5.0" size = "0.5.0"

View file

@ -15,7 +15,6 @@ use iced::{
use image::{EncodableLayout, RgbaImage, imageops}; use image::{EncodableLayout, RgbaImage, imageops};
use size::Size; use size::Size;
mod svg;
mod utils; mod utils;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -302,8 +301,7 @@ impl State {
fn main() -> Result<(), iced::Error> { fn main() -> Result<(), iced::Error> {
jxl_oxide::integration::register_image_decoding_hook(); jxl_oxide::integration::register_image_decoding_hook();
kra_image_integration::register(); misc_image_integration::register();
svg::register();
iced::application(State::new, State::update, State::view) iced::application(State::new, State::update, State::view)
.subscription(State::subscription) .subscription(State::subscription)

View file

@ -1,59 +0,0 @@
use std::io::Read;
use image::{
ImageDecoder, ImageError, ImageResult,
error::DecodingError,
hooks::{self, GenericReader},
};
use resvg::usvg::{Options, Transform, Tree};
pub fn register() -> bool {
hooks::register_decoding_hook("svg".into(), Box::new(hook))
&& hooks::register_decoding_hook("svgz".into(), Box::new(hook))
}
fn hook<'a>(mut reader: GenericReader<'a>) -> ImageResult<Box<dyn ImageDecoder + 'a>> {
let mut buf = Vec::new();
reader.read_to_end(&mut buf)?;
let tree = Tree::from_data(&buf, &Options::default()).map_err(to_image_error)?;
Ok(Box::new(SvgDecoder::new(tree)))
}
struct SvgDecoder {
tree: Tree,
}
impl SvgDecoder {
fn new(tree: Tree) -> Self {
Self { tree }
}
}
impl ImageDecoder for SvgDecoder {
fn color_type(&self) -> image::ColorType {
image::ColorType::Rgba8
}
fn dimensions(&self) -> (u32, u32) {
self.tree.size().to_int_size().dimensions()
}
fn read_image(self, buf: &mut [u8]) -> ImageResult<()>
where
Self: Sized,
{
let (width, height) = self.dimensions();
let mut pixmap = resvg::tiny_skia::PixmapMut::from_bytes(buf, width, height).unwrap();
resvg::render(&self.tree, Transform::default(), &mut pixmap);
Ok(())
}
fn read_image_boxed(self: Box<Self>, buf: &mut [u8]) -> ImageResult<()> {
(*self).read_image(buf)
}
}
fn to_image_error(
e: impl Into<Box<dyn std::error::Error + std::marker::Send + Sync + 'static>>,
) -> ImageError {
ImageError::Decoding(DecodingError::new(
image::error::ImageFormatHint::Name("SVG".into()),
e,
))
}