From 9de93b4f64fc7fa16a725bd6910548d609bdb3ae Mon Sep 17 00:00:00 2001 From: Jeremy James Date: Fri, 27 Dec 2024 15:04:19 +0000 Subject: [PATCH] Support floating point viewbox in resvg binary Avoid rounding sizes for images until creating the pixmap, and always use the ceil for that to avoid truncating images. This requires a corresponding change to tiny-skia to add scale_by/scale_to_width/scale_to_height functions to tiny_skia_path::Size to match the implementations in IntSize. --- crates/resvg/src/main.rs | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/crates/resvg/src/main.rs b/crates/resvg/src/main.rs index c4d15283..0b246e23 100644 --- a/crates/resvg/src/main.rs +++ b/crates/resvg/src/main.rs @@ -389,30 +389,29 @@ enum FitTo { /// Keep original size. Original, /// Scale to width. - Width(u32), + Width(f32), /// Scale to height. - Height(u32), + Height(f32), /// Scale to size. - Size(u32, u32), + Size(f32, f32), /// Zoom by factor. Zoom(f32), } impl FitTo { - fn fit_to_size(&self, size: tiny_skia::IntSize) -> Option { + fn fit_to_size(&self, size: tiny_skia::Size) -> Option { match *self { FitTo::Original => Some(size), FitTo::Width(w) => size.scale_to_width(w), FitTo::Height(h) => size.scale_to_height(h), - FitTo::Size(w, h) => tiny_skia::IntSize::from_wh(w, h).map(|s| size.scale_to(s)), + FitTo::Size(w, h) => tiny_skia::Size::from_wh(w, h).map(|s| size.scale_to(s)), FitTo::Zoom(z) => size.scale_by(z), } } - fn fit_to_transform(&self, size: tiny_skia::IntSize) -> tiny_skia::Transform { - let size1 = size.to_size(); - let size2 = match self.fit_to_size(size) { - Some(v) => v.to_size(), + fn fit_to_transform(&self, size1: tiny_skia::Size) -> tiny_skia::Transform { + let size2 = match self.fit_to_size(size1) { + Some(v) => v, None => return tiny_skia::Transform::default(), }; tiny_skia::Transform::from_scale( @@ -526,13 +525,13 @@ fn parse_args() -> Result { let mut default_size = usvg::Size::from_wh(100.0, 100.0).unwrap(); if let (Some(w), Some(h)) = (args.width, args.height) { default_size = usvg::Size::from_wh(w as f32, h as f32).unwrap(); - fit_to = FitTo::Size(w, h); + fit_to = FitTo::Size(w as f32, h as f32); } else if let Some(w) = args.width { default_size = usvg::Size::from_wh(w as f32, 100.0).unwrap(); - fit_to = FitTo::Width(w); + fit_to = FitTo::Width(w as f32); } else if let Some(h) = args.height { default_size = usvg::Size::from_wh(100.0, h as f32).unwrap(); - fit_to = FitTo::Height(h); + fit_to = FitTo::Height(h as f32); } else if let Some(z) = args.zoom { fit_to = FitTo::Zoom(z); } @@ -681,11 +680,11 @@ fn render_svg(args: &Args, tree: &usvg::Tree) -> Result Result Result Result