Merge pull request #2050 from EricKuck/fix/ai-blurred-art-drawn-look

AI import: a drawn look that is an image stands for its object, as one of paths does
This commit is contained in:
BFlat
2026-10-16 03:59:15 +07:00
committed by GitHub
2 changed files with 19 additions and 2 deletions
+4 -2
View File
@@ -22,7 +22,8 @@
//! (y down, its centre the template box's), where they start at the point of art space's origin,
//! the first row the top one. Each is a linked image showing the preview until its file is found.
//! - Art with an appearance the format can't write as plain art (several fills or strokes,
//! effects, brushes) comes first as that look, drawn (a group), then the object itself on `%_`
//! effects, brushes) comes first as that look, drawn (a group, or an image where an effect
//! rasterizes it), then the object itself on `%_`
//! lines and `1 (style) XW`: the drawn look is kept, named after the object.
//! - Patterns: `%AI3_BeginPattern: (name)`, `(name) llx lly urx ury` (the tile, in the pattern's
//! space, y up), the tile's art (on `%_` lines in newer files), `E`, `%AI3_EndPattern`; each is
@@ -1549,9 +1550,10 @@ impl<'a> Reader<'a> {
let (Some(object), Some(look)) = (n.checked_sub(1).and_then(|i| f.children.get(i)), n.checked_sub(2).and_then(|i| f.children.get(i))) else {
return;
};
// The look is a group of paths, or one image where an effect (a blur, a shadow) rasterizes it.
if !self.hidden_ids.contains(&object.id)
|| self.hidden_ids.contains(&look.id) != hidden
|| !matches!(look.kind, NodeKind::Group { clip: false, .. })
|| !matches!(look.kind, NodeKind::Group { clip: false, .. } | NodeKind::Image(_))
{
return;
}
+15
View File
@@ -539,6 +539,21 @@ fn image(matrix: &str, (w, h): (u32, u32), (space, kind, alpha): (&str, u32, u32
out
}
/// An effect that rasterizes (a blur) leaves its drawn look as one image, then the object itself on
/// `%_` lines: the image stands for the object, as for a drawn look that's a group.
#[test]
fn a_drawn_look_that_is_an_image_stands_for_its_object() {
let mut data = image("[ 10 0 0 10 50 90 ]", (1, 1), ("DeviceRGB", 3, 0), &[255, 0, 0], 3);
let object = format!("%_0 Ae\r\n%_u\r\n%_{}f\r\n%_U\r\n1 (Blurred) XW\r\n", rect_path(0.0, 0.0, 10.0, 10.0).replace('\n', "\r\n%_"));
let at = data.windows(6).position(|w| w == b"N\r\nLB\r").unwrap() + 3;
data.splice(at..at, object.into_bytes());
let r = read(&data).unwrap();
let a = art(&r.doc);
assert_eq!(a.len(), 1, "{a:#?}");
assert!(matches!(a[0].kind, NodeKind::Image(_)), "{:?}", a[0].kind);
assert!(r.warnings.iter().any(|w| w.contains("drawn look (1)")), "{:?}", r.warnings);
}
fn pixels(doc: &Document) -> (image::RgbaImage, kurbo::Affine) {
let a = art(doc);
let NodeKind::Image(im) = &a[0].kind else { panic!("{:?}", a[0].kind) };