SVG import: an unsupported filter's warning names the filter and the object
A filter that can't become a live effect warned "filter on a group ignored", even on a plain <rect>: usvg wraps every filtered element in a group of its own, which the message named. The warning now names the filter and its primitives and the element (by id, or "an object"), and says it is drawn without it: "filter 'f' (feColorMatrix) on an object isn't supported; drawn without it". Fixes #1598
This commit is contained in:
parent
13bd24ba79
commit
546c81624a
|
|
@ -245,6 +245,44 @@ impl RootUnits {
|
|||
}
|
||||
}
|
||||
|
||||
/// `'id' (feA, feB)` for each filter: its id and the primitives it uses, for warnings.
|
||||
fn filter_names(filters: &[Arc<usvg::filter::Filter>]) -> String {
|
||||
use usvg::filter::Kind as K;
|
||||
let names: Vec<String> = filters
|
||||
.iter()
|
||||
.map(|f| {
|
||||
let mut kinds: Vec<&str> = Vec::new();
|
||||
for p in f.primitives() {
|
||||
let k = match p.kind() {
|
||||
K::Blend(_) => "feBlend",
|
||||
K::ColorMatrix(_) => "feColorMatrix",
|
||||
K::ComponentTransfer(_) => "feComponentTransfer",
|
||||
K::Composite(_) => "feComposite",
|
||||
K::ConvolveMatrix(_) => "feConvolveMatrix",
|
||||
K::DiffuseLighting(_) => "feDiffuseLighting",
|
||||
K::DisplacementMap(_) => "feDisplacementMap",
|
||||
K::DropShadow(_) => "feDropShadow",
|
||||
K::Flood(_) => "feFlood",
|
||||
K::GaussianBlur(_) => "feGaussianBlur",
|
||||
K::Image(_) => "feImage",
|
||||
K::Merge(_) => "feMerge",
|
||||
K::Morphology(_) => "feMorphology",
|
||||
K::Offset(_) => "feOffset",
|
||||
K::SpecularLighting(_) => "feSpecularLighting",
|
||||
K::Tile(_) => "feTile",
|
||||
K::Turbulence(_) => "feTurbulence",
|
||||
};
|
||||
if !kinds.contains(&k) {
|
||||
kinds.push(k);
|
||||
}
|
||||
}
|
||||
let id = if f.id().is_empty() || made_up(f.id()) { String::new() } else { format!("'{}' ", f.id()) };
|
||||
format!("{id}({})", kinds.join(", "))
|
||||
})
|
||||
.collect();
|
||||
names.join(", ")
|
||||
}
|
||||
|
||||
/// How many clip paths deep (`<clipPath clip-path>`) an object's clip is read.
|
||||
const MAX_CLIP_NEST: usize = 16;
|
||||
|
||||
|
|
@ -902,7 +940,19 @@ impl Importer {
|
|||
let effects = match g.filters() {
|
||||
[] => vec![],
|
||||
filters => fx::effects(filters, ts, &self.blends).unwrap_or_else(|| {
|
||||
self.warn(format!("filter on {label} ignored"));
|
||||
// usvg wraps a filtered element in a group of its own: name the element then.
|
||||
let on = match g.children() {
|
||||
[usvg::Node::Group(_)] | [] => label.clone(),
|
||||
[one] if made_up(g.id()) || g.id().is_empty() => {
|
||||
if one.id().is_empty() || made_up(one.id()) {
|
||||
"an object".to_string()
|
||||
} else {
|
||||
format!("'{}'", one.id())
|
||||
}
|
||||
}
|
||||
_ => label.clone(),
|
||||
};
|
||||
self.warn(format!("filter {} on {on} isn't supported; drawn without it", filter_names(filters)));
|
||||
vec![]
|
||||
}),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -216,3 +216,16 @@ fn percentages_in_a_symbol_are_of_its_view_box() {
|
|||
};
|
||||
assert_similar(&drawing("100%", "100%", "25%", "50%"), &drawing("100", "50", "25", "25"), 24.0, 0.001);
|
||||
}
|
||||
|
||||
/// #1598: an unsupported filter's warning names the filter, its primitives and the object, and
|
||||
/// says it is drawn without it (not "a group": usvg wraps the element in one).
|
||||
#[test]
|
||||
fn unsupported_filters_are_named_in_the_warning() {
|
||||
let body = r#"<filter id="f"><feColorMatrix type="saturate" values="0"/></filter><filter id="t"><feTurbulence baseFrequency="0.05"/></filter>
|
||||
<rect x="20" y="20" width="60" height="60" fill="red" filter="url(#f)"/>
|
||||
<rect id="r" x="100" y="20" width="60" height="60" fill="blue" filter="url(#t)"/>"#;
|
||||
let (d, w) = import_with_report(&svg(body)).unwrap();
|
||||
assert!(w.iter().any(|w| w == "filter 'f' (feColorMatrix) on an object isn't supported; drawn without it"), "{w:?}");
|
||||
assert!(w.iter().any(|w| w == "filter 't' (feTurbulence) on 'r' isn't supported; drawn without it"), "{w:?}");
|
||||
assert_eq!(art(&d).iter().filter(|n| n.path_data().is_some()).count(), 2, "both drawn");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue