diff options
Diffstat (limited to 'rsvg/tests/src/api.rs')
-rw-r--r-- | rsvg/tests/src/api.rs | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/rsvg/tests/src/api.rs b/rsvg/tests/src/api.rs new file mode 100644 index 00000000..7846b2cb --- /dev/null +++ b/rsvg/tests/src/api.rs @@ -0,0 +1,216 @@ +use cairo; +use rsvg::surface_utils::shared_surface::{SharedImageSurface, SurfaceType}; +use rsvg::{CairoRenderer, RenderingError}; + +use crate::reference_utils::{Compare, Evaluate, Reference}; +use crate::utils::load_svg; + +#[test] +fn has_element_with_id_works() { + let svg = load_svg( + br#"<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50"> + <rect id="foo" x="10" y="10" width="30" height="30"/> +</svg> +"#, + ) + .unwrap(); + + assert!(svg.has_element_with_id("#foo").unwrap()); + assert!(!svg.has_element_with_id("#bar").unwrap()); + + assert!(matches!( + svg.has_element_with_id(""), + Err(RenderingError::InvalidId(_)) + )); + + assert!(matches!( + svg.has_element_with_id("not a fragment"), + Err(RenderingError::InvalidId(_)) + )); + + assert!(matches!( + svg.has_element_with_id("notfragment#fragment"), + Err(RenderingError::InvalidId(_)) + )); +} + +#[test] +fn render_layer() { + let svg = load_svg( + br##"<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"> + <rect id="foo" x="10" y="10" width="30" height="30" fill="#00ff00"/> + <rect id="bar" x="20" y="20" width="30" height="30" fill="#0000ff"/> +</svg> +"##, + ) + .unwrap(); + + let renderer = CairoRenderer::new(&svg); + + let output = cairo::ImageSurface::create(cairo::Format::ARgb32, 300, 300).unwrap(); + + let res = { + let cr = cairo::Context::new(&output).expect("Failed to create cairo context"); + let viewport = cairo::Rectangle::new(100.0, 100.0, 100.0, 100.0); + + renderer.render_layer(&cr, Some("#bar"), &viewport) + }; + + let output_surf = res + .and_then(|_| Ok(SharedImageSurface::wrap(output, SurfaceType::SRgb).unwrap())) + .unwrap(); + + let reference_surf = cairo::ImageSurface::create(cairo::Format::ARgb32, 300, 300).unwrap(); + + { + let cr = cairo::Context::new(&reference_surf).expect("Failed to create a cairo context"); + + cr.translate(100.0, 100.0); + + cr.rectangle(20.0, 20.0, 30.0, 30.0); + cr.set_source_rgba(0.0, 0.0, 1.0, 1.0); + cr.fill().unwrap(); + } + + Reference::from_surface(reference_surf) + .compare(&output_surf) + .evaluate(&output_surf, "render_layer"); +} + +#[test] +fn untransformed_element() { + // This has a rectangle inside a transformed group. The rectangle + // inherits its stroke-width from the group. + // + // The idea is that we'll be able to extract the geometry of the rectangle + // as if it were not transformed by its ancestors, but still retain the + // cascade from the ancestors. + let svg = load_svg( + br##"<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"> + <g transform="rotate(45)" stroke-width="10" stroke="#000000"> + <rect id="foo" x="10" y="20" width="30" height="40" fill="#0000ff"/> + </g> +</svg> +"##, + ) + .unwrap(); + + let renderer = CairoRenderer::new(&svg); + + /* Measuring */ + + let (ink_r, logical_r) = renderer.geometry_for_element(Some("#foo")).unwrap(); + + assert_eq!(ink_r, cairo::Rectangle::new(0.0, 0.0, 40.0, 50.0)); + + assert_eq!(logical_r, cairo::Rectangle::new(5.0, 5.0, 30.0, 40.0)); + + /* Rendering */ + + let output = cairo::ImageSurface::create(cairo::Format::ARgb32, 300, 300).unwrap(); + + let res = { + let cr = cairo::Context::new(&output).expect("Failed to create cairo context"); + let viewport = cairo::Rectangle::new(100.0, 100.0, 100.0, 100.0); + + renderer.render_element(&cr, Some("#foo"), &viewport) + }; + + let output_surf = res + .and_then(|_| Ok(SharedImageSurface::wrap(output, SurfaceType::SRgb).unwrap())) + .unwrap(); + + let reference_surf = cairo::ImageSurface::create(cairo::Format::ARgb32, 300, 300).unwrap(); + + { + let cr = cairo::Context::new(&reference_surf).expect("Failed to create a cairo context"); + + cr.translate(100.0, 100.0); + + cr.rectangle(10.0, 10.0, 60.0, 80.0); + cr.set_source_rgba(0.0, 0.0, 1.0, 1.0); + cr.fill_preserve().unwrap(); + + cr.set_line_width(20.0); + cr.set_source_rgba(0.0, 0.0, 0.0, 1.0); + cr.stroke().unwrap(); + } + + Reference::from_surface(reference_surf) + .compare(&output_surf) + .evaluate(&output_surf, "untransformed_element"); +} + +#[test] +fn set_stylesheet() { + // This has a rectangle which we style from a user-supplied stylesheet. + let mut svg = load_svg( + br##"<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"> + <rect id="foo" x="10" y="20" width="30" height="40" fill="black"/> +</svg> +"##, + ) + .unwrap(); + + svg.set_stylesheet("rect { fill: #00ff00; }") + .expect("should be a valid stylesheet"); + + let renderer = CairoRenderer::new(&svg); + + let output = cairo::ImageSurface::create(cairo::Format::ARgb32, 100, 100).unwrap(); + + let res = { + let cr = cairo::Context::new(&output).expect("Failed to create cairo context"); + let viewport = cairo::Rectangle::new(0.0, 0.0, 100.0, 100.0); + + renderer.render_document(&cr, &viewport) + }; + + let output_surf = res + .and_then(|_| Ok(SharedImageSurface::wrap(output, SurfaceType::SRgb).unwrap())) + .unwrap(); + + let reference_surf = cairo::ImageSurface::create(cairo::Format::ARgb32, 100, 100).unwrap(); + + { + let cr = cairo::Context::new(&reference_surf).expect("Failed to create a cairo context"); + + cr.rectangle(10.0, 20.0, 30.0, 40.0); + cr.set_source_rgba(0.0, 1.0, 0.0, 1.0); + cr.fill().unwrap(); + } + + Reference::from_surface(reference_surf) + .compare(&output_surf) + .evaluate(&output_surf, "set_stylesheet"); +} + +// https://gitlab.gnome.org/GNOME/librsvg/-/issues/799 +#[test] +fn text_doesnt_leave_points_in_current_path() { + let svg = load_svg( + br##"<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"> + <text>Hello world!</text> +</svg> +"##, + ) + .unwrap(); + + let renderer = CairoRenderer::new(&svg); + + let output = cairo::ImageSurface::create(cairo::Format::ARgb32, 100, 100).unwrap(); + let cr = cairo::Context::new(&output).unwrap(); + + assert!(!cr.has_current_point().unwrap()); + + let viewport = cairo::Rectangle::new(0.0, 0.0, 100.0, 100.0); + + renderer.render_document(&cr, &viewport).unwrap(); + + assert!(!cr.has_current_point().unwrap()); +} |