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
This commit is contained in:
parent
04dfed4678
commit
d138750448
5 changed files with 45 additions and 22 deletions
|
|
@ -25,7 +25,7 @@ use super::{DecoderUpdate, UpdateSender};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub enum ImageDimensionDetails {
|
pub enum ImageDimensionDetails {
|
||||||
Svg(String),
|
Svg(String, Option<(f64, f64)>),
|
||||||
#[default]
|
#[default]
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,10 @@ impl Svg {
|
||||||
let image = image_request.request().await?;
|
let image = image_request.request().await?;
|
||||||
|
|
||||||
let dimensions = if let Some(string) = image.info().dimensions_text.as_ref() {
|
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 {
|
} else {
|
||||||
ImageDimensionDetails::None
|
ImageDimensionDetails::None
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ use glib::Properties;
|
||||||
use gtk::CompositeTemplate;
|
use gtk::CompositeTemplate;
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
|
|
||||||
use crate::decoder;
|
use crate::decoder::{self, ImageDimensionDetails};
|
||||||
use crate::deps::*;
|
use crate::deps::*;
|
||||||
use crate::util::gettext::*;
|
use crate::util::gettext::*;
|
||||||
use crate::widgets::{LpImage, LpPrintPreview};
|
use crate::widgets::{LpImage, LpPrintPreview};
|
||||||
|
|
@ -167,12 +167,12 @@ impl std::fmt::Display for Unit {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Unit {
|
impl Unit {
|
||||||
fn factor(&self, dpi: f64, total_size: i32) -> f64 {
|
fn factor(&self, dpi: f64, total_size: f64) -> f64 {
|
||||||
match self {
|
match self {
|
||||||
Self::Centimeter => 2.54 / dpi,
|
Self::Centimeter => 2.54 / dpi,
|
||||||
Self::Inch => 1. / dpi,
|
Self::Inch => 1. / dpi,
|
||||||
Self::Pixel => 1.,
|
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();
|
let size_unit = obj.size_unit();
|
||||||
imp.width.set_value(
|
imp.width.set_value(
|
||||||
size_unit
|
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
|
// Default to inch for USA and Liberia
|
||||||
|
|
@ -500,6 +500,19 @@ impl LpPrint {
|
||||||
obj
|
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
|
/// Starts print preparation process by showing the print dialog
|
||||||
pub fn run(&self) -> Result<(), glib::Error> {
|
pub fn run(&self) -> Result<(), glib::Error> {
|
||||||
self.print_operation()
|
self.print_operation()
|
||||||
|
|
@ -566,10 +579,10 @@ impl LpPrint {
|
||||||
// Disable 'fill space' when manually changing size
|
// Disable 'fill space' when manually changing size
|
||||||
imp.fill_space.set_active(false);
|
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
|
let width = self
|
||||||
.size_unit()
|
.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);
|
imp.width.set_value(width);
|
||||||
|
|
||||||
self.draw_preview();
|
self.draw_preview();
|
||||||
|
|
@ -595,13 +608,20 @@ impl LpPrint {
|
||||||
|
|
||||||
/// Returns user selected image height in pixels
|
/// Returns user selected image height in pixels
|
||||||
pub fn user_height(&self) -> f64 {
|
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
|
/// Returns scaling of the original image based on selected image size
|
||||||
pub fn user_scale(&self) -> f64 {
|
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();
|
let (orig_width, _) = self.image().image_size();
|
||||||
|
|
||||||
self.user_width() / orig_width as f64
|
self.user_width() / orig_width as f64
|
||||||
|
|
@ -707,17 +727,17 @@ impl LpPrint {
|
||||||
let width1 = self.paper_width() - 2. * self.user_margin_horizontal();
|
let width1 = self.paper_width() - 2. * self.user_margin_horizontal();
|
||||||
|
|
||||||
let height = self.paper_height() - 2. * self.user_margin_vertical();
|
let height = self.paper_height() - 2. * self.user_margin_vertical();
|
||||||
let (orig_width, orig_height) = self.image().image_size();
|
let (orig_width, orig_height) = self.original_size();
|
||||||
let width2 = height * orig_width as f64 / orig_height as f64;
|
let width2 = height * orig_width / orig_height;
|
||||||
|
|
||||||
f64::min(width1, width2)
|
f64::min(width1, width2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns height that makes the image fill the page
|
/// Returns height that makes the image fill the page
|
||||||
fn fill_space_height(&self) -> f64 {
|
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
|
/// Updates width according to margins if fill space is activated
|
||||||
|
|
@ -746,7 +766,7 @@ impl LpPrint {
|
||||||
let imp = self.imp();
|
let imp = self.imp();
|
||||||
let _ui_updates_disabled = self.disable_ui_updates();
|
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 unit = self.size_unit();
|
||||||
let width_factor = unit.factor(self.dpi(), orig_width);
|
let width_factor = unit.factor(self.dpi(), orig_width);
|
||||||
|
|
@ -775,7 +795,7 @@ impl LpPrint {
|
||||||
let _ui_updates_disabled = self.disable_ui_updates();
|
let _ui_updates_disabled = self.disable_ui_updates();
|
||||||
|
|
||||||
let unit = self.margin_unit();
|
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 update_factor = unit_factor / self.margin_unit_factor();
|
||||||
let margin_horizontal = imp.margin_horizontal.value() * update_factor;
|
let margin_horizontal = imp.margin_horizontal.value() * update_factor;
|
||||||
|
|
@ -849,9 +869,9 @@ impl LpPrint {
|
||||||
|
|
||||||
let cairo_dpi = print_context.dpi_x();
|
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 cairo_scale = cairo_dpi / self.dpi();
|
||||||
|
|
||||||
let texture = if image.metadata().format().map_or(false, |x| x.is_svg()) {
|
let texture = if image.metadata().format().map_or(false, |x| x.is_svg()) {
|
||||||
|
|
@ -859,8 +879,8 @@ impl LpPrint {
|
||||||
// TODO: This should be async
|
// TODO: This should be async
|
||||||
decoder::formats::Svg::render_print(
|
decoder::formats::Svg::render_print(
|
||||||
&image.file().unwrap(),
|
&image.file().unwrap(),
|
||||||
(orig_width as f64 * texture_scale) as i32,
|
(orig_width * texture_scale) as i32,
|
||||||
(orig_height as f64 * texture_scale) as i32,
|
(orig_height * texture_scale) as i32,
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ mod imp_page {
|
||||||
fn snapshot(&self, snapshot: >k::Snapshot) {
|
fn snapshot(&self, snapshot: >k::Snapshot) {
|
||||||
snapshot.save();
|
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_left = self.print().effective_margin_left() * self.display_scale();
|
||||||
let margin_top = self.print().effective_margin_top() * self.display_scale();
|
let margin_top = self.print().effective_margin_top() * self.display_scale();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,7 @@ mod imp {
|
||||||
|
|
||||||
if let Some(image) = obj.image() {
|
if let Some(image) = obj.image() {
|
||||||
match image.dimension_details() {
|
match image.dimension_details() {
|
||||||
ImageDimensionDetails::Svg(string) => Some(string),
|
ImageDimensionDetails::Svg(string, _) => Some(string),
|
||||||
_ => {
|
_ => {
|
||||||
let (width, height) = image.image_size();
|
let (width, height) = image.image_size();
|
||||||
if width > 0 && height > 0 {
|
if width > 0 && height > 0 {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue