[librsvg: 10/35] For tests, handle PDF dimensions in floats




commit c930b29df28ed7bdc35d82d557a2073023a2df47
Author: Federico Mena Quintero <federico gnome org>
Date:   Fri Jun 11 16:30:02 2021 -0500

    For tests, handle PDF dimensions in floats
    
    This copies some of lopdf's commit 63f29475e444e8ad60287d2c166b89f572272f94.
    
    We bring in an Object.as_float() method, done here as an extension
    trait, to convert integer objects to floats automatically.  Otherwise,
    it seems that lopdf sees a MediaBox like
    
       /MediaBox [ 0 0 200 100 ]
    
    and thinks it should generate Object::Integer - which is not
    unreasonable, but inconvenient for us.
    
    Part-of: <https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/547>

 tests/src/cmdline/rsvg_convert.rs |  2 +-
 tests/src/predicates/pdf.rs       | 37 ++++++++++++++++++++++++++++---------
 2 files changed, 29 insertions(+), 10 deletions(-)
---
diff --git a/tests/src/cmdline/rsvg_convert.rs b/tests/src/cmdline/rsvg_convert.rs
index 417d8666..04f46265 100644
--- a/tests/src/cmdline/rsvg_convert.rs
+++ b/tests/src/cmdline/rsvg_convert.rs
@@ -538,7 +538,7 @@ fn pdf_page_size() {
         .success()
         // TODO: the PDF size and resolution is actually a bug in rsvg-convert,
         // see https://gitlab.gnome.org/GNOME/librsvg/issues/514
-        .stdout(file::is_pdf().with_page_size(200, 100));
+        .stdout(file::is_pdf().with_page_size(200.0, 100.0));
 }
 
 #[test]
diff --git a/tests/src/predicates/pdf.rs b/tests/src/predicates/pdf.rs
index d90c9e62..f19d845f 100644
--- a/tests/src/predicates/pdf.rs
+++ b/tests/src/predicates/pdf.rs
@@ -19,7 +19,7 @@ impl PdfPredicate {
         }
     }
 
-    pub fn with_page_size(self: Self, width: i64, height: i64) -> DetailPredicate<Self> {
+    pub fn with_page_size(self: Self, width: f64, height: f64) -> DetailPredicate<Self> {
         DetailPredicate::<Self> {
             p: self,
             d: Detail::PageSize(Dimensions {
@@ -78,8 +78,8 @@ enum Detail {
 /// Note that `w` and `h` given in `UserUnit`, which is by default 1.0 = 1/72 inch.
 #[derive(Debug)]
 struct Dimensions {
-    w: i64,
-    h: i64,
+    w: f64,
+    h: f64,
     unit: f64, // UserUnit, in points (1/72 of an inch)
 }
 
@@ -87,18 +87,18 @@ impl Dimensions {
     pub fn from_media_box(obj: &lopdf::Object, unit: Option<f64>) -> lopdf::Result<Dimensions> {
         let a = obj.as_array()?;
         Ok(Dimensions {
-            w: a[2].as_i64()?,
-            h: a[3].as_i64()?,
+            w: a[2].as_float()?,
+            h: a[3].as_float()?,
             unit: unit.unwrap_or(1.0),
         })
     }
 
     pub fn width_in_mm(self: &Self) -> f64 {
-        self.w as f64 * self.unit * 72.0 / 254.0
+        self.w * self.unit * 72.0 / 254.0
     }
 
     pub fn height_in_mm(self: &Self) -> f64 {
-        self.h as f64 * self.unit * 72.0 / 254.0
+        self.h * self.unit * 72.0 / 254.0
     }
 }
 
@@ -164,16 +164,35 @@ impl DetailPredicate<PdfPredicate> {
     }
 }
 
+// Extensions to lopdf::Object; can be removed after lopdf 0.26
+trait ObjExt {
+    /// Get the object value as a float.
+    /// Unlike as_f64() this will also cast an Integer to a Real.
+    fn as_float(&self) -> lopdf::Result<f64>;
+}
+
+impl ObjExt for lopdf::Object {
+    fn as_float(&self) -> lopdf::Result<f64> {
+        match *self {
+            lopdf::Object::Integer(ref value) => Ok(*value as f64),
+            lopdf::Object::Real(ref value) => Ok(*value),
+            _ => Err(lopdf::Error::Type),
+        }
+    }
+}
+
 impl Details for lopdf::Document {
     fn get_page_count(self: &Self) -> usize {
         self.get_pages().len()
     }
 
     fn get_page_size(self: &Self) -> Option<Dimensions> {
-        let to_f64 = |obj: &lopdf::Object| obj.as_f64();
         match self.get_from_first_page(b"MediaBox") {
             Ok(obj) => {
-                let unit = self.get_from_first_page(b"UserUnit").and_then(to_f64).ok();
+                let unit = self
+                    .get_from_first_page(b"UserUnit")
+                    .and_then(ObjExt::as_float)
+                    .ok();
                 Dimensions::from_media_box(obj, unit).ok()
             }
             Err(_) => None,


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