[librsvg] render_element_to_viewport() - new primitive, doesn't quite work yet



commit e13e2221d659840ee6b134ce7c5ecddc41738e3e
Author: Federico Mena Quintero <federico gnome org>
Date:   Tue Feb 19 18:41:48 2019 -0600

    render_element_to_viewport() - new primitive, doesn't quite work yet
    
    This takes a viewport, and is supposed to compute the appropriate
    transform for it based on the SVG's viewBox/etc.
    
    It doesn't quite work yet; there is a new
    librsvg_crate/examples/proportional.rs to test this.

 librsvg_crate/examples/proportional.rs | 51 ++++++++++++++++++++++++++++++++++
 librsvg_crate/src/lib.rs               |  9 ++++++
 rsvg_internals/src/handle.rs           | 36 ++++++++++++++++++++++++
 3 files changed, 96 insertions(+)
---
diff --git a/librsvg_crate/examples/proportional.rs b/librsvg_crate/examples/proportional.rs
new file mode 100644
index 00000000..ee02f3ed
--- /dev/null
+++ b/librsvg_crate/examples/proportional.rs
@@ -0,0 +1,51 @@
+extern crate cairo;
+extern crate librsvg;
+
+use std::fs::File;
+use std::io::BufWriter;
+use std::process;
+
+fn main() {
+    let args = std::env::args_os();
+
+    if args.len() != 5 {
+        eprintln!("usage: render <input.svg> <width> <height> <output.png>");
+        process::exit(1);
+    }
+
+    let mut args = args.skip(1);
+
+    let input = args.next().unwrap();
+    let width_os = args.next().unwrap();
+    let height_os = args.next().unwrap();
+    let output = args.next().unwrap();
+
+    let width_s = width_os.to_str().unwrap();
+    let height_s = height_os.to_str().unwrap();
+
+    let width: i32 = width_s.parse().unwrap();
+    let height: i32 = height_s.parse().unwrap();
+
+    assert!(width > 0 && height > 0);
+
+    let handle = librsvg::LoadOptions::new().read_path(input).unwrap();
+
+    let renderer = handle.get_cairo_renderer();
+
+    let surface = cairo::ImageSurface::create(cairo::Format::ARgb32, width, height).unwrap();
+    let cr = cairo::Context::new(&surface);
+    renderer.render_element_to_viewport(
+        &cr,
+        None,
+        &cairo::Rectangle {
+            x: 0.0,
+            y: 0.0,
+            width: f64::from(width),
+            height: f64::from(height),
+        }
+    ).unwrap();
+
+    let mut file = BufWriter::new(File::create(output).unwrap());
+
+    surface.write_to_png(&mut file).unwrap();
+}
diff --git a/librsvg_crate/src/lib.rs b/librsvg_crate/src/lib.rs
index d49650fb..f5bb489e 100644
--- a/librsvg_crate/src/lib.rs
+++ b/librsvg_crate/src/lib.rs
@@ -426,4 +426,13 @@ impl<'a> CairoRenderer<'a> {
     ) -> Result<(), RenderingError> {
         self.handle.0.render_cairo_sub(cr, id)
     }
+
+    pub fn render_element_to_viewport(
+        &self,
+        cr: &cairo::Context,
+        id: Option<&str>,
+        viewport: &cairo::Rectangle,
+    ) -> Result<(), RenderingError> {
+        self.handle.0.render_element_to_viewport(cr, id, viewport)
+    }
 }
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index b84df410..d43acac1 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -545,6 +545,42 @@ impl Handle {
         res
     }
 
+    pub fn render_element_to_viewport(
+        &self,
+        cr: &cairo::Context,
+        id: Option<&str>,
+        viewport: &cairo::Rectangle,
+    ) -> Result<(), RenderingError> {
+        check_cairo_context(cr)?;
+
+        let node = if let Some(id) = id {
+            Some(self.lookup_node(id).map_err(RenderingError::InvalidId)?)
+        } else {
+            None
+        };
+
+        let root = self.get_root();
+
+        let svg_ref = self.svg.borrow();
+        let svg = svg_ref.as_ref().unwrap();
+
+        let dimensions = svg.get_intrinsic_dimensions();
+
+        let vbox = dimensions.vbox.unwrap_or_else(|| ViewBox {
+            x: viewport.x,
+            y: viewport.y,
+            width: viewport.width,
+            height: viewport.height,
+        });
+
+        cr.save();
+        let mut draw_ctx = self.create_drawing_ctx_for_node(cr, viewport, &vbox, node.as_ref());
+        let res = draw_ctx.draw_node_from_stack(&root.get_cascaded_values(), &root, false);
+        cr.restore();
+
+        res
+    }
+
     fn construct_new_from_gfile_sync(
         &mut self,
         file: &gio::File,


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