AI import: a clipping path alone in a group clips the clipping group around it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
EricKuck
2026-10-16 03:36:19 +07:00
committed by bflatastic
co-authored by Claude Opus 5.5
parent d5a672fda2
commit fb6fc437c3
2 changed files with 27 additions and 0 deletions
+15
View File
@@ -832,6 +832,21 @@ impl<'a> Reader<'a> {
_ => self.close(what, |k| matches!(k, Kind::Clip))?,
};
let Frame { kind, children: kids, gs, clips, hidden: opened_hidden, .. } = f;
// A group holding only clipping paths (`q … u <path> W n U … Q`) doesn't clip on its own: `u`/`U` don't save
// the graphics state as `q`/`Q` do, so its paths clip the clipping group around it, as the file's PDF part draws it.
if matches!(kind, Kind::Group)
&& !clips.is_empty()
&& clips.len() == kids.len()
&& matches!(self.frames.last(), Some(Frame { kind: Kind::Clip, .. }))
{
for kid in kids {
if let Some(parent) = self.frames.last_mut() {
parent.clips.push(parent.children.len());
}
self.add(kid, opened_hidden || hidden)?;
}
return Ok(());
}
// A compound path of clipping paths clips its clipping group.
let clipping = matches!(kind, Kind::Compound) && !clips.is_empty();
self.group_ended = !matches!(kind, Kind::Compound);
+12
View File
@@ -270,6 +270,18 @@ fn compound_paths_and_clipping() {
assert!(*clip && matches!(children[0].kind, NodeKind::Path { clipping: true, .. }));
}
/// A clipping group's clipping path can sit alone in a group of its own, after the art it clips (`q … u <path> W n U
/// … Q`): it still clips the clipping group.
#[test]
fn a_clipping_path_alone_in_a_group_clips_its_clipping_group() {
let body = format!("0 Ae\nq\n{RED}{}f\n0 Ae\nu\n{}h\nW\nn\nU\nQ\n", rect_path(0.0, 0.0, 30.0, 30.0), rect_path(5.0, 5.0, 25.0, 25.0));
let doc = read_ok(&layer(&body)).doc;
let NodeKind::Group { children, clip: true } = &art(&doc)[0].kind else { panic!("{:?}", art(&doc)[0].kind) };
assert_eq!(children.len(), 2, "{children:?}");
assert!(matches!(children[0].kind, NodeKind::Path { clipping: true, .. }));
assert_eq!(fill(&children[1]).color(), Some(Color::rgb(1.0, 0.0, 0.0)));
}
/// #1410: a compound path shows its last path's paint, and paths grouped in it stay its paths.
#[test]
fn compound_path_takes_its_last_paths_paint() {