[librsvg] librsvg_crate/tests/render_to_viewport.rs - New test for the render_to_viewport() API



commit 96e1f22d1e4faf74633520f2630e344b17c7cf88
Author: Federico Mena Quintero <federico gnome org>
Date:   Thu Mar 7 09:30:36 2019 -0600

    librsvg_crate/tests/render_to_viewport.rs - New test for the render_to_viewport() API
    
    It turns out that the render_to_viewport() API lets us simulate the
    way in which io-svg.c calls librsvg: the latter uses the
    size_callback, which translates to creating a DrawingCtx with a
    viewport size that is different from the SVG's intrinsic size.
    
    This also changes NodeSvg::draw() so it will use the initial
    viewport (as computed by DrawingCtx), instead of a nested SVG's
    viewport.
    
    This is part of https://gitlab.gnome.org/GNOME/librsvg/issues/433

 librsvg_crate/tests/compare_surfaces.rs            |  10 +--
 .../tests/fixtures/rect-48x48-rendered-128x128.png | Bin 0 -> 373 bytes
 librsvg_crate/tests/render_to_viewport.rs          |  82 +++++++++++++++++++++
 rsvg_internals/src/structure.rs                    |  27 ++++++-
 4 files changed, 110 insertions(+), 9 deletions(-)
---
diff --git a/librsvg_crate/tests/compare_surfaces.rs b/librsvg_crate/tests/compare_surfaces.rs
index 229f494c..f592a071 100644
--- a/librsvg_crate/tests/compare_surfaces.rs
+++ b/librsvg_crate/tests/compare_surfaces.rs
@@ -3,8 +3,8 @@ extern crate rsvg_internals;
 
 use cairo::ImageSurface;
 
-use rsvg_internals::{IRect, RenderingError};
-use rsvg_internals::surface_utils::{
+use self::rsvg_internals::{IRect, RenderingError};
+use self::rsvg_internals::surface_utils::{
     iterators::Pixels,
     shared_surface::{SharedImageSurface, SurfaceType},
     ImageSurfaceDataExt,
@@ -17,9 +17,9 @@ pub enum BufferDiff {
 }
 
 pub struct Diff {
-    num_pixels_changed: usize,
-    max_diff: u8,
-    surface: SharedImageSurface,
+    pub num_pixels_changed: usize,
+    pub max_diff: u8,
+    pub surface: SharedImageSurface,
 }
 
 #[inline]
diff --git a/librsvg_crate/tests/fixtures/rect-48x48-rendered-128x128.png 
b/librsvg_crate/tests/fixtures/rect-48x48-rendered-128x128.png
new file mode 100644
index 00000000..e4ec9f7a
Binary files /dev/null and b/librsvg_crate/tests/fixtures/rect-48x48-rendered-128x128.png differ
diff --git a/librsvg_crate/tests/render_to_viewport.rs b/librsvg_crate/tests/render_to_viewport.rs
new file mode 100644
index 00000000..dd2d2c9c
--- /dev/null
+++ b/librsvg_crate/tests/render_to_viewport.rs
@@ -0,0 +1,82 @@
+extern crate cairo;
+extern crate gio;
+extern crate glib;
+extern crate librsvg;
+extern crate rsvg_internals;
+
+use gio::MemoryInputStreamExt;
+use glib::Cast;
+
+use librsvg::{
+    CairoRenderer,
+    Loader,
+    SvgHandle,
+};
+
+use std::fs::File;
+use std::io::BufReader;
+use std::path::Path;
+
+use self::rsvg_internals::surface_utils::shared_surface::{SharedImageSurface, SurfaceType};
+
+mod compare_surfaces;
+
+use compare_surfaces::{compare_surfaces, BufferDiff};
+
+fn load_svg(input: &'static [u8]) -> SvgHandle {
+    let stream = gio::MemoryInputStream::new();
+    stream.add_bytes(&glib::Bytes::from_static(input));
+
+    Loader::new()
+        .read_stream(&stream.upcast(), None, None)
+        .unwrap()
+}
+
+#[test]
+fn render_to_viewport_with_different_size() {
+    let svg = load_svg(
+        br#"<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"; width="48" height="48">
+  <rect x="8" y="8" width="32" height="32" fill="blue"/>
+</svg>
+"#,
+    );
+
+    let renderer = CairoRenderer::new(&svg);
+
+    let output = cairo::ImageSurface::create(cairo::Format::ARgb32, 128, 128).unwrap();
+
+    {
+        let cr = cairo::Context::new(&output);
+        renderer
+            .render_element_to_viewport(
+                &cr,
+                None,
+                &cairo::Rectangle {
+                    x: 0.0,
+                    y: 0.0,
+                    width: 128.0,
+                    height: 128.0,
+                },
+            )
+            .unwrap();
+    }
+
+    let output_surf = SharedImageSurface::new(output, SurfaceType::SRgb).unwrap();
+
+    let fixture_path = Path::new("tests/fixtures/rect-48x48-rendered-128x128.png");
+    let mut fixture_file = BufReader::new(File::open(fixture_path).unwrap());
+
+    let expected = cairo::ImageSurface::create_from_png(&mut fixture_file).unwrap();
+    let expected_surf = SharedImageSurface::new(expected, SurfaceType::SRgb).unwrap();
+
+    let diff = compare_surfaces(&output_surf, &expected_surf).unwrap();
+
+    match diff {
+        BufferDiff::DifferentSizes => unreachable!("surfaces should be of the same size"),
+
+        BufferDiff::Diff(diff) => {
+            assert_eq!(diff.num_pixels_changed, 0);
+        }
+    }
+}
diff --git a/rsvg_internals/src/structure.rs b/rsvg_internals/src/structure.rs
index 33e9feb1..b53b418c 100644
--- a/rsvg_internals/src/structure.rs
+++ b/rsvg_internals/src/structure.rs
@@ -278,11 +278,30 @@ impl NodeTrait for NodeSvg {
             None
         };
 
-        let (viewport, vbox) = {
-            let viewport = self.get_viewport(values, &params);
-            let vbox = self.vbox.get();
+        let svg_viewport = self.get_viewport(values, &params);
 
-            (viewport, vbox)
+        let viewport = if has_parent {
+            svg_viewport
+        } else {
+            cairo::Rectangle {
+                x: 0.0,
+                y: 0.0,
+                width: params.view_box_width,
+                height: params.view_box_height,
+            }
+        };
+
+        let vbox = if has_parent {
+            self.vbox.get()
+        } else {
+            self.vbox.get().or_else(|| {
+                Some(ViewBox {
+                    x: 0.0,
+                    y: 0.0,
+                    width: svg_viewport.width,
+                    height: svg_viewport.height,
+                })
+            })
         };
 
         draw_ctx.with_discrete_layer(node, values, clipping, &mut |dc| {


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