[librsvg: 16/53] Reference tests: check that all test images have "obvious" intrinsic dimensions
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 16/53] Reference tests: check that all test images have "obvious" intrinsic dimensions
- Date: Fri, 23 Oct 2020 02:19:06 +0000 (UTC)
commit f2d9924adacb5cd7b3ebaa764777a16a6ef91e8a
Author: Federico Mena Quintero <federico gnome org>
Date: Wed Oct 14 13:34:01 2020 -0500
Reference tests: check that all test images have "obvious" intrinsic dimensions
I.e. that they don't need to figure out the document size from the
font size (em/ex units in the width/height attributes of <svg>), or
have non-100% percentage units.
Cargo.lock | 1 +
librsvg/c_api.rs | 2 +
tests/Cargo.toml | 1 +
tests/src/main.rs | 3 ++
tests/src/reference.rs | 142 +++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 149 insertions(+)
---
diff --git a/Cargo.lock b/Cargo.lock
index 001703e2..03227de2 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -781,6 +781,7 @@ version = "0.1.0"
dependencies = [
"assert_cmd",
"cairo-rs",
+ "cast",
"chrono",
"float-cmp",
"librsvg",
diff --git a/librsvg/c_api.rs b/librsvg/c_api.rs
index 116877d7..25555236 100644
--- a/librsvg/c_api.rs
+++ b/librsvg/c_api.rs
@@ -466,6 +466,7 @@ impl ObjectImpl for CHandle {
}
}
+// Keep in sync with tests/src/reference.rs
pub fn checked_i32(x: f64) -> Result<i32, cairo::Status> {
cast::i32(x).map_err(|_| cairo::Status::InvalidSize)
}
@@ -815,6 +816,7 @@ impl CHandle {
let res = handle
.get_geometry_sub(id, inner.dpi.into(), inner.is_testing)
.and_then(|(ink_r, _)| {
+ // Keep these in sync with tests/src/reference.rs
let width = checked_i32(ink_r.width().round())?;
let height = checked_i32(ink_r.height().round())?;
diff --git a/tests/Cargo.toml b/tests/Cargo.toml
index ac6a537d..932b4ab6 100644
--- a/tests/Cargo.toml
+++ b/tests/Cargo.toml
@@ -8,6 +8,7 @@ edition = "2018"
[dev-dependencies]
assert_cmd = "1.0.1"
cairo-rs = { version = "0.8.0", features = ["png"] }
+cast = "0.2.3"
chrono = "0.4.0"
float-cmp = "0.8.0"
librsvg = { path = "../librsvg_crate" }
diff --git a/tests/src/main.rs b/tests/src/main.rs
index 8bd5ba4a..a8a3a6df 100644
--- a/tests/src/main.rs
+++ b/tests/src/main.rs
@@ -14,6 +14,9 @@ mod loading_crash;
#[cfg(test)]
mod predicates;
+#[cfg(test)]
+mod reference;
+
#[cfg(test)]
mod render_crash;
diff --git a/tests/src/reference.rs b/tests/src/reference.rs
new file mode 100644
index 00000000..c7cb7e7d
--- /dev/null
+++ b/tests/src/reference.rs
@@ -0,0 +1,142 @@
+//! Tests with reference images.
+//!
+//! This is the bulk of librsvg's black-box tests. In principle, each test takes an SVG file, renders
+//! it to a raster image, and compares that image to a reference image stored on disk. If the images
+//! are "too different", the test fails. We allow for minor differences in rendering to account for
+//! antialiasing artifacts, floating-point variations, and such.
+//!
+
+#![cfg(test)]
+use test_generator::test_resources;
+
+use librsvg::{CairoRenderer, IntrinsicDimensions, Length, LengthUnit, Loader};
+
+use crate::utils::fixture_path;
+
+// The original reference images from the SVG1.1 test suite are at 72 DPI.
+const TEST_SUITE_DPI: f64 = 72.0;
+
+fn reference_test(name: &str) {
+ let path = fixture_path(name);
+
+ let handle = Loader::new()
+ .read_path(path)
+ .unwrap_or_else(|e| panic!("could not load: {}", e));
+
+ let renderer = CairoRenderer::new(&handle).with_dpi(TEST_SUITE_DPI, TEST_SUITE_DPI);
+
+ let (width, height) = image_size(renderer.intrinsic_dimensions(), TEST_SUITE_DPI);
+}
+
+/// Computes the (width, height) pixel size at which an SVG should be rendered, based on its intrinsic
dimensions.
+///
+/// # Panics:
+///
+/// Will panic if none of the following conditions are met:
+///
+/// * Width and height both exist
+/// * Width and height do not exist, but viewBox exists.
+fn image_size(dim: IntrinsicDimensions, dpi: f64) -> (i32, i32) {
+ let IntrinsicDimensions {
+ width,
+ height,
+ vbox,
+ } = dim;
+
+ use LengthUnit::*;
+
+ if let (Some(width), Some(height)) = (width, height) {
+ if !(has_supported_unit(&width) && has_supported_unit(&height)) {
+ panic!("SVG has unsupported unit type in width or height");
+ }
+ }
+
+ #[rustfmt::skip]
+ let (width, height) = match (width, height, vbox) {
+ (Some(Length { length: w, unit: Percent }),
+ Some(Length { length: h, unit: Percent }), vbox) if w == 1.0 && h == 1.0 => {
+ if let Some(vbox) = vbox {
+ (vbox.width, vbox.height)
+ } else {
+ panic!("SVG with percentage width/height must have a viewBox");
+ }
+ }
+
+ (Some(Length { length: _, unit: Percent }),
+ Some(Length { length: _, unit: Percent }), _) => {
+ panic!("Test suite only supports percentage width/height at 100%");
+ }
+
+ (Some(w), Some(h), _) => {
+ (normalize(&w, dpi), normalize(&h, dpi))
+ }
+
+ (None, None, Some(vbox)) => (vbox.width, vbox.height),
+
+ (_, _, _) => panic!("Test suite does not support the dimensions of this file"),
+ };
+
+ // Keep in sync with c_api.rs
+ let width = checked_i32(width.round());
+ let height = checked_i32(height.round());
+
+ (width, height)
+}
+
+// Keep in sync with c_api.rs
+fn checked_i32(x: f64) -> i32 {
+ cast::i32(x).expect("overflow when converting f64 to i32")
+}
+
+fn has_supported_unit(l: &Length) -> bool {
+ use LengthUnit::*;
+
+ match l.unit {
+ Percent | Px | In | Cm | Mm | Pt | Pc => true,
+ _ => false,
+ }
+}
+
+const POINTS_PER_INCH: f64 = 72.0;
+const CM_PER_INCH: f64 = 2.54;
+const MM_PER_INCH: f64 = 25.4;
+const PICA_PER_INCH: f64 = 6.0;
+
+fn normalize(l: &Length, dpi: f64) -> f64 {
+ use LengthUnit::*;
+
+ match l.unit {
+ Px => l.length,
+ In => l.length * dpi,
+ Cm => l.length * dpi / CM_PER_INCH,
+ Mm => l.length * dpi / MM_PER_INCH,
+ Pt => l.length * dpi / POINTS_PER_INCH,
+ Pc => l.length * dpi / PICA_PER_INCH,
+ _ => panic!("unsupported length unit"),
+ }
+}
+
+#[test_resources("tests/fixtures/reftests/*.svg")]
+fn reftests(name: &str) {
+ reference_test(name);
+}
+
+#[test_resources("tests/fixtures/reftests/adwaita/*.svg")]
+fn adwaita(name: &str) {
+ reference_test(name);
+}
+
+#[test_resources("tests/fixtures/reftests/bugs/*.svg")]
+fn bugs(name: &str) {
+ reference_test(name);
+}
+
+#[test_resources("tests/fixtures/reftests/svg1.1/*.svg")]
+fn svg_1_1(name: &str) {
+ reference_test(name);
+}
+
+#[test_resources("tests/fixtures/reftests/svg2/*.svg")]
+fn svg_2(name: &str) {
+ reference_test(name);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]