[librsvg: 22/35] rsvg-convert: New --page-width and --page-height options




commit 8e437d06ccd87fb2aae877fe0d9b319863a49cc9
Author: Federico Mena Quintero <federico gnome org>
Date:   Tue Jun 15 20:03:00 2021 -0500

    rsvg-convert: New --page-width and --page-height options
    
    These will be used to set the surface size, decoupling it from the
    rendered size of the SVG document.
    
    I had to raise the epsilon for comparing Dimension values... they are
    now "equal" if they match within a millionth of a point.  Pretty
    accurate, eh?
    
    Part-of: <https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/547>

 src/bin/rsvg-convert.rs           | 52 +++++++++++++++++++++++++++++++++++++--
 tests/src/cmdline/rsvg_convert.rs | 12 +++++++++
 tests/src/predicates/pdf.rs       | 13 ++++++++--
 3 files changed, 73 insertions(+), 4 deletions(-)
---
diff --git a/src/bin/rsvg-convert.rs b/src/bin/rsvg-convert.rs
index ec9dd82f..e8c6acec 100644
--- a/src/bin/rsvg-convert.rs
+++ b/src/bin/rsvg-convert.rs
@@ -443,6 +443,7 @@ struct Converter {
     pub zoom: Scale,
     pub width: Option<ULength<Horizontal>>,
     pub height: Option<ULength<Vertical>>,
+    pub page_size: Option<(ULength<Horizontal>, ULength<Vertical>)>,
     pub format: Format,
     pub export_id: Option<String>,
     pub keep_aspect_ratio: bool,
@@ -502,13 +503,17 @@ impl Converter {
             let params = NormalizeParams::from_dpi(Dpi::new(self.dpi.0, self.dpi.1));
 
             // Convert natural size and requested size to pixels or points, depending on the target format,
-            let (natural_size, requested_width, requested_height) = match self.format {
+            let (natural_size, requested_width, requested_height, page_size) = match self.format {
                 Format::Png => {
                     // PNG surface requires units in pixels
                     (
                         natural_size,
                         self.width.map(|l| l.to_user(&params)),
                         self.height.map(|l| l.to_user(&params)),
+                        self.page_size.map(|(w, h)| Size {
+                            w: w.to_user(&params),
+                            h: h.to_user(&params),
+                        }),
                     )
                 }
 
@@ -523,6 +528,10 @@ impl Converter {
                         },
                         self.width.map(|l| l.to_points(&params)),
                         self.height.map(|l| l.to_points(&params)),
+                        self.page_size.map(|(w, h)| Size {
+                            w: w.to_points(&params),
+                            h: h.to_points(&params),
+                        }),
                     )
                 }
 
@@ -532,6 +541,10 @@ impl Converter {
                         natural_size,
                         self.width.map(|l| l.to_user(&params)),
                         self.height.map(|l| l.to_user(&params)),
+                        self.page_size.map(|(w, h)| Size {
+                            w: w.to_user(&params),
+                            h: h.to_user(&params),
+                        }),
                     )
                 }
             };
@@ -555,7 +568,8 @@ impl Converter {
             let final_size = self.final_size(&strategy, &natural_size, input)?;
 
             // Create the surface once on the first input
-            let s = surface.get_or_try_init(|| self.create_surface(final_size))?;
+            let page_size = page_size.unwrap_or(final_size);
+            let s = surface.get_or_try_init(|| self.create_surface(page_size))?;
 
             s.render(
                 &renderer,
@@ -708,6 +722,20 @@ fn parse_args() -> Result<Converter, Error> {
                 .value_name("length")
                 .help("Height [defaults to the height of the SVG]"),
         )
+        .arg(
+            clap::Arg::with_name("page_width")
+                .long("page-width")
+                .takes_value(true)
+                .value_name("length")
+                .help("Width of output media [defaults to the width of the SVG]"),
+        )
+        .arg(
+            clap::Arg::with_name("page_height")
+                .long("page-height")
+                .takes_value(true)
+                .value_name("length")
+                .help("Height of output media [defaults to the height of the SVG]"),
+        )
         .arg(
             clap::Arg::with_name("format")
                 .short("f")
@@ -828,6 +856,25 @@ fn parse_args() -> Result<Converter, Error> {
         .map(parse_length)
         .transpose()?;
 
+    let page_width = value_t!(matches, "page_width", String)
+        .or_none()?
+        .map(parse_length)
+        .transpose()?;
+    let page_height = value_t!(matches, "page_height", String)
+        .or_none()?
+        .map(parse_length)
+        .transpose()?;
+
+    let page_size = match (page_width, page_height) {
+        (None, None) => None,
+        (Some(_), None) | (None, Some(_)) => {
+            return Err(error!(
+                "Please specify both the --page-width and --page-height options together."
+            ));
+        }
+        (Some(w), Some(h)) => Some((w, h)),
+    };
+
     let zoom = value_t!(matches, "zoom", f64).or_none()?;
     let zoom_x = value_t!(matches, "zoom_x", f64).or_none()?;
     let zoom_y = value_t!(matches, "zoom_y", f64).or_none()?;
@@ -858,6 +905,7 @@ fn parse_args() -> Result<Converter, Error> {
         },
         width,
         height,
+        page_size,
         format,
         export_id: value_t!(matches, "export_id", String)
             .or_none()?
diff --git a/tests/src/cmdline/rsvg_convert.rs b/tests/src/cmdline/rsvg_convert.rs
index 41b33acd..4f983be2 100644
--- a/tests/src/cmdline/rsvg_convert.rs
+++ b/tests/src/cmdline/rsvg_convert.rs
@@ -564,6 +564,18 @@ fn pdf_size_width_height_proportional() {
         .stdout(file::is_pdf().with_page_size(144.0, 144.0));
 }
 
+#[cfg(system_deps_have_cairo_pdf)]
+#[test]
+fn pdf_page_size() {
+    RsvgConvert::new_with_input("tests/fixtures/cmdline/dimensions-in.svg")
+        .arg("--format=pdf")
+        .arg("--page-width=210mm")
+        .arg("--page-height=297mm")
+        .assert()
+        .success()
+        .stdout(file::is_pdf().with_page_size(210.0 / 25.4 * 72.0, 297.0 / 25.4 * 72.0));
+}
+
 #[test]
 fn does_not_clip_partial_coverage_pixels() {
     RsvgConvert::new_with_input("tests/fixtures/cmdline/677-partial-pixel.svg")
diff --git a/tests/src/predicates/pdf.rs b/tests/src/predicates/pdf.rs
index d6fa86b1..5c51514b 100644
--- a/tests/src/predicates/pdf.rs
+++ b/tests/src/predicates/pdf.rs
@@ -114,8 +114,17 @@ impl fmt::Display for Dimensions {
 
 impl cmp::PartialEq for Dimensions {
     fn eq(&self, other: &Self) -> bool {
-        approx_eq!(f64, self.width_in_pt(), other.width_in_pt())
-            && approx_eq!(f64, self.height_in_pt(), other.height_in_pt())
+        approx_eq!(
+            f64,
+            self.width_in_pt(),
+            other.width_in_pt(),
+            epsilon = 0.000_001
+        ) && approx_eq!(
+            f64,
+            self.height_in_pt(),
+            other.height_in_pt(),
+            epsilon = 0.000_001
+        )
     }
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]