mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
Merge pull request #2444 from marcoarnulfo/fix/ai-compound-holes
AI import: a compound path whose subpaths' group is marked like a look keeps its holes
This commit is contained in:
@@ -870,7 +870,9 @@ impl<'a> Reader<'a> {
|
||||
let mut painted = None;
|
||||
let node = match kind {
|
||||
// A compound path holding a group (its drawn look) is that look: its paths paint apart.
|
||||
Kind::Compound if kids.iter().any(|k| self.looks.contains(&k.id)) => {
|
||||
// Some files mark every group so, the plain one holding the subpaths too (#980): one
|
||||
// paint for all its paths keeps it one compound path, its holes cut.
|
||||
Kind::Compound if kids.iter().any(|k| self.looks.contains(&k.id) && paints_apart(k)) => {
|
||||
let (children, clip) = self.clip_first(kids, &clips);
|
||||
self.new_node(NodeKind::Group { children, clip }, &gs)
|
||||
}
|
||||
@@ -2203,6 +2205,19 @@ fn ungrouped(kids: Vec<Node>) -> Vec<Node> {
|
||||
out
|
||||
}
|
||||
|
||||
/// Whether `look`'s paths don't all paint the same.
|
||||
fn paints_apart(look: &Node) -> bool {
|
||||
fn leaves<'a>(n: &'a Node, out: &mut Vec<&'a Node>) {
|
||||
match &n.kind {
|
||||
NodeKind::Group { children, .. } => children.iter().for_each(|c| leaves(c, out)),
|
||||
_ => out.push(n),
|
||||
}
|
||||
}
|
||||
let mut paths = vec![];
|
||||
leaves(look, &mut paths);
|
||||
paths.windows(2).any(|w| matches!(w, [a, b] if a.appearance != b.appearance))
|
||||
}
|
||||
|
||||
fn path_rule(n: &Node) -> FillRule {
|
||||
match &n.kind {
|
||||
NodeKind::Path { rule, .. } | NodeKind::Compound { rule, .. } => *rule,
|
||||
|
||||
@@ -446,6 +446,21 @@ fn a_compound_path_holding_its_drawn_look_paints_its_paths_apart() {
|
||||
assert_eq!(fills, [Some(Color::rgb(1.0, 0.0, 0.0)), Some(Color::rgb(0.0, 0.0, 1.0))], "{a:#?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_compound_path_of_a_plain_group_stays_one_compound_path() {
|
||||
// GUARDS: #980. Files write `9 () XW` after every group, the one a compound path keeps its
|
||||
// subpaths in too: read as a drawn look, the compound became a group of filled paths, its
|
||||
// holes filled in. Here a ring (outer path, inner one reversed, one paint) and a path beside it.
|
||||
let ring = format!("{RED}1 D\n{}f\n0 D\n{}f\n", rect_path(0.0, 0.0, 20.0, 20.0), "5 5 m\n15 5 L\n15 15 L\n5 15 L\n5 5 L\n");
|
||||
let art_ = format!("0 Ae\nu\n0 Ae\n*u\n0 Ae\nu\n{ring}U\n9 () XW\n*U\n{}f\nU\n9 () XW\n", rect_path(8.0, 8.0, 12.0, 12.0));
|
||||
let a = art(&read_ok(&layer(&art_)).doc);
|
||||
let NodeKind::Group { children, .. } = &a[0].kind else { panic!("{a:#?}") };
|
||||
let NodeKind::Compound { children: subpaths, .. } = &children[0].kind else { panic!("a compound path: {:#?}", children[0]) };
|
||||
assert_eq!(subpaths.len(), 2, "{subpaths:#?}");
|
||||
assert!(subpaths.iter().all(|p| matches!(p.kind, NodeKind::Path { .. })));
|
||||
assert_eq!(fill(&children[0]).color(), Some(Color::rgb(1.0, 0.0, 0.0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gradients_through_a_skewed_matrix() {
|
||||
// GUARDS: a sheared `Xm` leaves the matrix's columns oblique. A linear ramp runs along the
|
||||
|
||||
Reference in New Issue
Block a user