From d13875044864c4f33c667fd805f3ba342b2141fe Mon Sep 17 00:00:00 2001 From: Sophie Herold Date: Thu, 21 Dec 2023 23:40:17 +0100 Subject: [PATCH 1/2] print: Adjust 100% to SVG physical dimensions Some SVGs store there size in cm or inch. With this change, the 100% in the print dialog is calculated according to that physical size. Closes #141 --- src/decoder/formats/mod.rs | 2 +- src/decoder/formats/svg.rs | 5 ++- src/widgets/print.rs | 56 +++++++++++++++++++++++----------- src/widgets/print_preview.rs | 2 +- src/widgets/properties_view.rs | 2 +- 5 files changed, 45 insertions(+), 22 deletions(-) diff --git a/src/decoder/formats/mod.rs b/src/decoder/formats/mod.rs index 4ab5b328..3541848f 100644 --- a/src/decoder/formats/mod.rs +++ b/src/decoder/formats/mod.rs @@ -25,7 +25,7 @@ use super::{DecoderUpdate, UpdateSender}; #[derive(Clone, Debug, Default)] pub enum ImageDimensionDetails { - Svg(String), + Svg(String, Option<(f64, f64)>), #[default] None, } diff --git a/src/decoder/formats/svg.rs b/src/decoder/formats/svg.rs index 373d43fd..d7d47ee1 100644 --- a/src/decoder/formats/svg.rs +++ b/src/decoder/formats/svg.rs @@ -83,7 +83,10 @@ impl Svg { let image = image_request.request().await?; let dimensions = if let Some(string) = image.info().dimensions_text.as_ref() { - ImageDimensionDetails::Svg(string.to_string()) + ImageDimensionDetails::Svg( + string.to_string(), + image.info().dimensions_inch.clone().into(), + ) } else { ImageDimensionDetails::None }; diff --git a/src/widgets/print.rs b/src/widgets/print.rs index 7eccae67..47e164a1 100644 --- a/src/widgets/print.rs +++ b/src/widgets/print.rs @@ -27,7 +27,7 @@ use glib::Properties; use gtk::CompositeTemplate; use once_cell::sync::OnceCell; -use crate::decoder; +use crate::decoder::{self, ImageDimensionDetails}; use crate::deps::*; use crate::util::gettext::*; use crate::widgets::{LpImage, LpPrintPreview}; @@ -167,12 +167,12 @@ impl std::fmt::Display for Unit { } impl Unit { - fn factor(&self, dpi: f64, total_size: i32) -> f64 { + fn factor(&self, dpi: f64, total_size: f64) -> f64 { match self { Self::Centimeter => 2.54 / dpi, Self::Inch => 1. / dpi, Self::Pixel => 1., - Self::Percent => 100. / total_size as f64, + Self::Percent => 100. / total_size, } } @@ -392,7 +392,7 @@ mod imp { let size_unit = obj.size_unit(); imp.width.set_value( size_unit - .round(obj.image().image_size().0 as f64 * obj.width_unit_factor()), + .round(obj.original_size().0 as f64 * obj.width_unit_factor()), ); // Default to inch for USA and Liberia @@ -500,6 +500,19 @@ impl LpPrint { obj } + pub fn original_size(&self) -> (f64, f64) { + let image = self.image(); + if let ImageDimensionDetails::Svg(_, Some((w, h))) = image.dimension_details() { + let dpi = self.dpi(); + + ((w * dpi).round(), (h * dpi).round()) + } else { + let (w, h) = self.image().image_size(); + + (w as f64, h as f64) + } + } + /// Starts print preparation process by showing the print dialog pub fn run(&self) -> Result<(), glib::Error> { self.print_operation() @@ -566,10 +579,10 @@ impl LpPrint { // Disable 'fill space' when manually changing size imp.fill_space.set_active(false); - let (orig_width, orig_height) = self.image().image_size(); + let (orig_width, orig_height) = self.original_size(); let width = self .size_unit() - .round(imp.height.value() * orig_width as f64 / orig_height as f64); + .round(imp.height.value() * orig_width / orig_height); imp.width.set_value(width); self.draw_preview(); @@ -595,13 +608,20 @@ impl LpPrint { /// Returns user selected image height in pixels pub fn user_height(&self) -> f64 { - let (_, orig_height) = self.image().image_size(); + let (_, orig_height) = self.original_size(); - f64::max(1., orig_height as f64 * self.user_scale()) + f64::max(1., orig_height * self.user_scale()) } /// Returns scaling of the original image based on selected image size pub fn user_scale(&self) -> f64 { + let (orig_width, _) = self.original_size(); + + self.user_width() / orig_width + } + + /// Returns scaling of the original image based on selected image size + pub fn user_scale_original(&self) -> f64 { let (orig_width, _) = self.image().image_size(); self.user_width() / orig_width as f64 @@ -707,17 +727,17 @@ impl LpPrint { let width1 = self.paper_width() - 2. * self.user_margin_horizontal(); let height = self.paper_height() - 2. * self.user_margin_vertical(); - let (orig_width, orig_height) = self.image().image_size(); - let width2 = height * orig_width as f64 / orig_height as f64; + let (orig_width, orig_height) = self.original_size(); + let width2 = height * orig_width / orig_height; f64::min(width1, width2) } /// Returns height that makes the image fill the page fn fill_space_height(&self) -> f64 { - let (orig_width, orig_height) = self.image().image_size(); + let (orig_width, orig_height) = self.original_size(); - self.fill_space_width() * orig_height as f64 / orig_width as f64 + self.fill_space_width() * orig_height / orig_width } /// Updates width according to margins if fill space is activated @@ -746,7 +766,7 @@ impl LpPrint { let imp = self.imp(); let _ui_updates_disabled = self.disable_ui_updates(); - let (orig_width, orig_height) = self.image().image_size(); + let (orig_width, orig_height) = self.original_size(); let unit = self.size_unit(); let width_factor = unit.factor(self.dpi(), orig_width); @@ -775,7 +795,7 @@ impl LpPrint { let _ui_updates_disabled = self.disable_ui_updates(); let unit = self.margin_unit(); - let unit_factor = unit.factor(self.dpi(), 1); + let unit_factor = unit.factor(self.dpi(), 1.); let update_factor = unit_factor / self.margin_unit_factor(); let margin_horizontal = imp.margin_horizontal.value() * update_factor; @@ -849,9 +869,9 @@ impl LpPrint { let cairo_dpi = print_context.dpi_x(); - let (orig_width, orig_height) = image.image_size(); + let (orig_width, orig_height) = self.original_size(); - let texture_scale = self.user_width() / orig_width as f64; + let texture_scale = self.user_width() / orig_width; let cairo_scale = cairo_dpi / self.dpi(); let texture = if image.metadata().format().map_or(false, |x| x.is_svg()) { @@ -859,8 +879,8 @@ impl LpPrint { // TODO: This should be async decoder::formats::Svg::render_print( &image.file().unwrap(), - (orig_width as f64 * texture_scale) as i32, - (orig_height as f64 * texture_scale) as i32, + (orig_width * texture_scale) as i32, + (orig_height * texture_scale) as i32, ) .unwrap() } else { diff --git a/src/widgets/print_preview.rs b/src/widgets/print_preview.rs index 34d96d38..a269ebcd 100644 --- a/src/widgets/print_preview.rs +++ b/src/widgets/print_preview.rs @@ -53,7 +53,7 @@ mod imp_page { fn snapshot(&self, snapshot: >k::Snapshot) { snapshot.save(); - let scale = self.print().user_scale() * self.display_scale(); + let scale = self.print().user_scale_original() * self.display_scale(); let margin_left = self.print().effective_margin_left() * self.display_scale(); let margin_top = self.print().effective_margin_top() * self.display_scale(); diff --git a/src/widgets/properties_view.rs b/src/widgets/properties_view.rs index 60c0fe96..ff3ced2e 100644 --- a/src/widgets/properties_view.rs +++ b/src/widgets/properties_view.rs @@ -227,7 +227,7 @@ mod imp { if let Some(image) = obj.image() { match image.dimension_details() { - ImageDimensionDetails::Svg(string) => Some(string), + ImageDimensionDetails::Svg(string, _) => Some(string), _ => { let (width, height) = image.image_size(); if width > 0 && height > 0 { -- GitLab From 2864eb7cc3364cc0cce201e8f5f138a806559029 Mon Sep 17 00:00:00 2001 From: Sophie Herold Date: Fri, 22 Dec 2023 21:42:37 +0100 Subject: [PATCH 2/2] print: Only show one size input for percent --- src/widgets/print.rs | 11 +++++++++++ src/widgets/print.ui | 3 +-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/widgets/print.rs b/src/widgets/print.rs index 47e164a1..db5ee028 100644 --- a/src/widgets/print.rs +++ b/src/widgets/print.rs @@ -764,6 +764,16 @@ impl LpPrint { fn on_size_unit_changed(&self) { let imp = self.imp(); + + // Only show one size input for percentage + if matches!(self.size_unit(), Unit::Percent) { + imp.width.set_title(&gettext("_Scale")); + imp.height.set_visible(false); + } else { + imp.width.set_title(&gettext("_Width")); + imp.height.set_visible(true); + } + let _ui_updates_disabled = self.disable_ui_updates(); let (orig_width, orig_height) = self.original_size(); @@ -792,6 +802,7 @@ impl LpPrint { fn on_margin_unit_changed(&self) { let imp = self.imp(); + let _ui_updates_disabled = self.disable_ui_updates(); let unit = self.margin_unit(); diff --git a/src/widgets/print.ui b/src/widgets/print.ui index 886e349b..fb8d6b8b 100644 --- a/src/widgets/print.ui +++ b/src/widgets/print.ui @@ -166,7 +166,6 @@ - _Width true @@ -196,4 +195,4 @@ - + \ No newline at end of file -- GitLab