summaryrefslogtreecommitdiff
path: root/rsvg/tests/primitive_geometries.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rsvg/tests/primitive_geometries.rs')
-rw-r--r--rsvg/tests/primitive_geometries.rs167
1 files changed, 167 insertions, 0 deletions
diff --git a/rsvg/tests/primitive_geometries.rs b/rsvg/tests/primitive_geometries.rs
new file mode 100644
index 00000000..479d6445
--- /dev/null
+++ b/rsvg/tests/primitive_geometries.rs
@@ -0,0 +1,167 @@
+//! Tests for geometries of SVG primitives
+//!
+//! These use the *.svg and *.svg.geom files in the tests/fixtures/primitive_geometries directory.
+//!
+//! Each .svg.geom is a JSON file formatted like this:
+//!
+//! ```json
+//! {
+//! "#element_id": {
+//! "ink_rect": {
+//! "x": 5.0,
+//! "y": 15.0,
+//! "width": 40.0,
+//! "height": 50.0
+//! },
+//! "logical_rect": {
+//! "x": 10.0,
+//! "y": 20.0,
+//! "width": 30.0,
+//! "height": 40.0
+//! }
+//! }
+//! }
+//! ```
+//!
+//! Any number of element_ids may appear in the file. For each of those, the `test()` function will
+//! call `CairoRenderer::get_layer_geometry()` and compare its result against the provided rectangles.
+
+use anyhow::{Context, Result};
+use cairo;
+use rsvg::{CairoRenderer, LengthUnit, Loader, Rect};
+use serde::Deserialize;
+use std::collections::BTreeMap;
+use std::fs;
+
+// Copy of cairo::Rectangle
+//
+// Somehow I can't make serde's "remote" work here, in combination with the BTreeMap below...
+#[derive(Copy, Clone, Deserialize, Debug, PartialEq)]
+struct Rectangle {
+ x: f64,
+ y: f64,
+ width: f64,
+ height: f64,
+}
+
+impl From<Rectangle> for Rect {
+ fn from(r: Rectangle) -> Rect {
+ Rect {
+ x0: r.x,
+ y0: r.y,
+ x1: r.x + r.width,
+ y1: r.y + r.height,
+ }
+ }
+}
+
+#[derive(Copy, Clone, Deserialize, Debug, PartialEq)]
+struct ElementGeometry {
+ ink_rect: Option<Rectangle>,
+ logical_rect: Option<Rectangle>,
+}
+
+#[derive(Deserialize)]
+struct Geometries(BTreeMap<String, ElementGeometry>);
+
+fn read_geometries(path: &str) -> Result<Geometries> {
+ let contents = fs::read_to_string(path).context(format!("could not read {:?}", path))?;
+ Ok(serde_json::from_str(&contents).context(format!("could not parse JSON from {:?}", path))?)
+}
+
+// We create a struct with the id and geometry so that
+// assert_eq!() in the tests will print out the element name for failures.
+//
+// Here we use rsvg::Rect as that one has an approx_eq() method.
+#[derive(Debug, PartialEq)]
+struct Element {
+ id: String,
+ ink_rect: Option<Rect>,
+ logical_rect: Option<Rect>,
+}
+
+impl Element {
+ fn from_element_geometry(id: &str, geom: &ElementGeometry) -> Element {
+ Element {
+ id: String::from(id),
+ ink_rect: geom.ink_rect.map(Into::into),
+ logical_rect: geom.logical_rect.map(Into::into),
+ }
+ }
+
+ fn from_rectangles(
+ id: &str,
+ ink_rect: cairo::Rectangle,
+ logical_rect: cairo::Rectangle,
+ ) -> Element {
+ Element {
+ id: String::from(id),
+ ink_rect: Some(ink_rect.into()),
+ logical_rect: Some(logical_rect.into()),
+ }
+ }
+}
+
+fn test(svg_filename: &str, geometries_filename: &str) {
+ let geometries = read_geometries(geometries_filename).expect("reading geometries JSON");
+
+ let handle = Loader::new()
+ .read_path(svg_filename)
+ .expect("reading geometries SVG");
+ let renderer = CairoRenderer::new(&handle);
+ let dimensions = renderer.intrinsic_dimensions();
+ let (svg_width, svg_height) = renderer
+ .intrinsic_size_in_pixels()
+ .expect("intrinsic size in pixels");
+
+ assert!(matches!(dimensions.width.unit, LengthUnit::Px));
+ assert!(matches!(dimensions.height.unit, LengthUnit::Px));
+ assert_eq!(dimensions.width.length, svg_width);
+ assert_eq!(dimensions.height.length, svg_height);
+
+ for (id, expected) in geometries.0.iter() {
+ let expected = Element::from_element_geometry(id, expected);
+
+ let viewport = cairo::Rectangle::new(0.0, 0.0, svg_width, svg_height);
+
+ let (ink_rect, logical_rect) = renderer
+ .geometry_for_layer(Some(id), &viewport)
+ .expect(&format!("getting geometry for {}", id));
+
+ let computed = Element::from_rectangles(id, ink_rect, logical_rect);
+
+ assert_eq!(expected, computed);
+ }
+}
+
+#[test]
+fn rect() {
+ test(
+ "tests/fixtures/primitive_geometries/rect.svg",
+ "tests/fixtures/primitive_geometries/rect.svg.geom",
+ );
+}
+
+#[test]
+fn rect_stroke() {
+ test(
+ "tests/fixtures/primitive_geometries/rect_stroke.svg",
+ "tests/fixtures/primitive_geometries/rect_stroke.svg.geom",
+ );
+}
+
+#[test]
+fn rect_stroke_unfilled() {
+ test(
+ "tests/fixtures/primitive_geometries/rect_stroke_unfilled.svg",
+ "tests/fixtures/primitive_geometries/rect_stroke_unfilled.svg.geom",
+ );
+}
+
+#[test]
+fn rect_isolate() {
+ test(
+ "tests/fixtures/primitive_geometries/rect_isolate.svg",
+ "tests/fixtures/primitive_geometries/rect_isolate.svg.geom",
+ );
+}