[librsvg/rustify-rsvg-convert: 7/14] rsvg-convert: Add check for cairo image surface size limit




commit 0e9002fdaf15077a5e90ab0aca2385341fff44e2
Author: Sven Neumann <sven svenfoo org>
Date:   Wed Nov 4 22:56:46 2020 +0100

    rsvg-convert: Add check for cairo image surface size limit

 src/bin/rsvg-convert/main.rs    | 17 +++++++++++++----
 src/bin/rsvg-convert/surface.rs | 10 ++++++++--
 2 files changed, 21 insertions(+), 6 deletions(-)
---
diff --git a/src/bin/rsvg-convert/main.rs b/src/bin/rsvg-convert/main.rs
index 5ca17134..4ac0c439 100644
--- a/src/bin/rsvg-convert/main.rs
+++ b/src/bin/rsvg-convert/main.rs
@@ -22,6 +22,14 @@ macro_rules! exit {
     })
 }
 
+fn size_limit_exceeded() -> ! {
+    exit!(
+        "The resulting image would be larger than 32767 pixels on either dimension.\n\
+           Librsvg currently cannot render to images bigger than that.\n\
+           Please specify a smaller size."
+    );
+}
+
 fn load_stylesheet(args: &Args) -> std::io::Result<Option<String>> {
     match args.stylesheet {
         Some(ref filename) => std::fs::read_to_string(filename).map(Some),
@@ -58,10 +66,11 @@ fn main() {
                     let output = Stream::new(args.output())
                         .unwrap_or_else(|e| exit!("Error opening output: {}", e));
 
-                    Some(
-                        Surface::new(args.format, width, height, output)
-                            .unwrap_or_else(|e| exit!("Error creating output surface: {}", e)),
-                    )
+                    match Surface::new(args.format, width, height, output) {
+                        Ok(surface) => Some(surface),
+                        Err(cairo::Status::InvalidSize) => size_limit_exceeded(),
+                        Err(e) => exit!("Error creating output surface: {}", e),
+                    }
                 }
                 None => None,
             };
diff --git a/src/bin/rsvg-convert/surface.rs b/src/bin/rsvg-convert/surface.rs
index b99f11d2..b94c203a 100644
--- a/src/bin/rsvg-convert/surface.rs
+++ b/src/bin/rsvg-convert/surface.rs
@@ -6,6 +6,11 @@ use librsvg::{CairoRenderer, RenderingError};
 use crate::cli::Format;
 use crate::output::Stream;
 
+// TODO
+fn checked_i32(x: f64) -> Result<i32, cairo::Status> {
+    cast::i32(x).map_err(|_| cairo::Status::InvalidSize)
+}
+
 pub enum Surface {
     Png(cairo::ImageSurface, Stream),
     Pdf(cairo::PdfSurface, (f64, f64)),
@@ -43,8 +48,9 @@ impl Surface {
     }
 
     fn new_for_png(width: f64, height: f64, stream: Stream) -> Result<Self, cairo::Status> {
-        let surface =
-            cairo::ImageSurface::create(cairo::Format::ARgb32, width as i32, height as i32)?;
+        let w = checked_i32(width.round())?;
+        let h = checked_i32(height.round())?;
+        let surface = cairo::ImageSurface::create(cairo::Format::ARgb32, w, h)?;
         Ok(Self::Png(surface, stream))
     }
 


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