mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 01:37:02 -06:00
Merge pull request #3918 from lehni/fix/svg-glyph-image-href
Type: an SVG glyph's image is an SVG image by its plain href first
This commit is contained in:
@@ -99,11 +99,10 @@ fn glyph(svg: &str, id: &str, color: &str) -> Option<Glyph> {
|
||||
// Edits: byte ranges to cut and what to put in their place, in order.
|
||||
let mut edits: Vec<(Range<usize>, String)> = vec![];
|
||||
// Cut with the left-out elements: images of SVG documents, as the table asks (a glyph draws no
|
||||
// documents inside it).
|
||||
// documents inside it). Their link is `href`, else `xlink:href`, as the importer reads it.
|
||||
let svg_image = |n: &roxmltree::Node| {
|
||||
n.tag_name().name() == "image"
|
||||
&& n.attributes()
|
||||
.any(|a| a.name() == "href" && a.value().trim_start().get(..14).is_some_and(|v| v.eq_ignore_ascii_case("data:image/svg")))
|
||||
let href = n.attribute("href").or_else(|| n.attribute(("http://www.w3.org/1999/xlink", "href")));
|
||||
n.tag_name().name() == "image" && href.and_then(|h| h.trim_start().get(..14)).is_some_and(|v| v.eq_ignore_ascii_case("data:image/svg"))
|
||||
};
|
||||
for n in root.descendants().filter(|n| n.is_element() && (LEFT_OUT.contains(&n.tag_name().name()) || svg_image(n))) {
|
||||
edits.push((n.range(), String::new()));
|
||||
|
||||
@@ -230,3 +230,30 @@ fn svg_images_are_left_out() {
|
||||
assert!(fills.contains(&Paint::solid(Color::rgb8(0, 0, 255))), "the glyph's own art");
|
||||
assert!(!fills.contains(&Paint::solid(Color::rgb8(255, 0, 0))), "not the images' documents: {fills:?}");
|
||||
}
|
||||
|
||||
/// Of `href` and `xlink:href`, the plain one counts, as the importer reads them (SVG 2): an image
|
||||
/// whose `href` is a PNG stays, whatever its `xlink:href`; one whose `href` is a document goes.
|
||||
#[test]
|
||||
fn an_images_plain_href_decides_whether_it_is_an_svg_image() {
|
||||
let png = vectorcraft_svg::base64_encode(&vectorcraft_text::test_fonts::solid_png(4, [0, 0, 255, 255]));
|
||||
let svg = vectorcraft_svg::base64_encode(
|
||||
br##"<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10"><rect width="10" height="10" fill="#f00"/></svg>"##,
|
||||
);
|
||||
let image = |href: &str, xlink: &str| {
|
||||
format!(
|
||||
r##"<image width="500" height="500" href="data:image/{href};base64,{}" xlink:href="data:image/{xlink};base64,{}"/>"##,
|
||||
if href == "png" { &png } else { &svg },
|
||||
if xlink == "png" { &png } else { &svg }
|
||||
)
|
||||
};
|
||||
let images = |inner: String| {
|
||||
let doc = format!(
|
||||
r##"<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g id="glyph1"><path d="M0 0h1v-1z"/>{inner}</g></svg>"##
|
||||
);
|
||||
let mut n = 0;
|
||||
art(&doc, 1).unwrap().walk(&mut |c| n += usize::from(matches!(c.kind, NodeKind::Image(_))));
|
||||
n
|
||||
};
|
||||
assert_eq!(images(image("png", "svg+xml")), 1, "the PNG stays");
|
||||
assert_eq!(images(image("svg+xml", "png")), 0, "the document goes");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user