diff --git a/crates/svg/src/import/prepass.rs b/crates/svg/src/import/prepass.rs index 245392fda..5a393e79a 100644 --- a/crates/svg/src/import/prepass.rs +++ b/crates/svg/src/import/prepass.rs @@ -149,7 +149,7 @@ fn named_made_up_ids(xml: &roxmltree::Document) -> HashSet { /// * so do objects with attributes in other applications' namespaces ([`foreign`]); /// * so do `` and `` elements, recorded: usvg makes their arcs into a varying /// number of curves, and they come back as the ellipse VectorCraft draws (not in a file whose -/// style sheet has an `[id` selector); +/// style sheet has an attribute selector); /// * linked files are read ([`files`]); /// * percentage lengths in a `` with a `viewBox` become numbers ([`symbol_units`]); /// * what style sheet rules with a `:not()` set goes in `style` attributes ([`not_rules`]). @@ -164,8 +164,9 @@ pub(super) fn prepass<'s>(svg: &'s str, markers: &str, xml: &roxmltree::Document let not = markers.contains(":not("); let events = SVG_EVENTS.iter().any(|e| markers.contains(e)); let foreign_attrs = markers.contains("xmlns:") && has_foreign_attributes(xml); - // An id would change what a style sheet's `[id]` selector matches: such files keep usvg's curves. - let ellipses = !markers.contains("[id") && [" (Document, Vec) { import_with_report(&svg(body)).unwrap() } +#[test] +fn decoded_id_selectors_do_not_recolor_bare_ellipses() { + for selector in ["circle[id]", "ellipse[id]", "circle[id]", "ellipse[id]", "circle[ id ]", r"ellipse[\69 d]"] { + let source = svg(&format!( + "" + )); + let doc = import(&source).unwrap(); + let actual = render_artboard(&doc); + let expected = resvg_render(&source, 200, 120); + assert_eq!((actual.width, actual.height), (expected.width, expected.height)); + for (x, y) in [(40, 50), (100, 50), (40, 100), (100, 100)] { + let at = 4 * (y * actual.width + x) as usize; + assert_eq!(&actual.rgba[at..at + 4], &expected.rgba[at..at + 4], "{selector}: ({x}, {y})"); + } + } +} + /// All non-layer nodes in paint order. fn art(d: &Document) -> Vec<&Node> { let mut v = Vec::new();