Merge pull request #6136 from dotCooCoo/feat/ai-editing-data-symbols

.ai save: the editing copy keeps symbols and their instances
This commit is contained in:
BFlat
2026-11-09 01:58:07 +08:00
committed by GitHub
+34
View File
@@ -833,6 +833,40 @@ fn nested_symbol_instances_stop_at_the_symbol_art_limit() {
assert_eq!(layers.matches("\r\nf\r\n").count(), 3198, "the squares of the leaves written");
}
/// On a canvas of the usual size, nested symbols whose instances multiply, written as their art in
/// art cut to a clipping object, stop at [`vectorcraft_doc::MAX_SYMBOL_NODES`] objects of symbol art
/// in all, with a warning.
#[test]
fn clipped_nested_symbol_instances_stop_at_the_symbol_art_limit() {
let mut doc = Document::new(200.0, 100.0);
let layer = doc.layers[0].id;
// Empty paths: counted, but written as nothing, so the test stays small; and one filled square.
let empty = Arc::new(Node::path(doc.alloc_id(), PathData::new(vec![]), Appearance::default()));
let mut members = vec![empty; 4999];
let square_art = shapes::rectangle(Rect::new(0.0, 0.0, 1.0, 1.0));
members.push(Arc::new(Node::path(doc.alloc_id(), square_art, Appearance::basic(solid(Color::gray(0.5)), Paint::None, 0.0))));
let leaves = Node::group(doc.alloc_id(), members);
doc.symbols.push(Symbol { dynamic: false, name: "Leaf".into(), art: Arc::new(leaves) });
let leaf = Arc::new(Node::new(doc.alloc_id(), NodeKind::SymbolInstance { symbol: "Leaf".into(), xf: Affine::IDENTITY }));
let trees = Node::group(doc.alloc_id(), vec![leaf; 5000]);
doc.symbols.push(Symbol { dynamic: false, name: "Tree".into(), art: Arc::new(trees) });
let tree = Node::new(doc.alloc_id(), NodeKind::SymbolInstance { symbol: "Tree".into(), xf: Affine::IDENTITY });
// A group as the clipping object cuts the art instead of clipping it with a path, so the
// instances in it are written as their art. Its square is unpainted, so the only filled squares
// are the leaves'.
let outline = Node::path(doc.alloc_id(), shapes::rectangle(Rect::new(0.0, 0.0, 50.0, 50.0)), Appearance::default());
let clip = group(&mut doc, vec![outline], false);
let clipped = group(&mut doc, vec![clip, tree], true);
doc.insert(Some(layer), usize::MAX, clipped).unwrap();
let out = export_ai_editing(&doc, &opts()).unwrap();
assert!(out.warnings.iter().any(|w| w == writer::SYMBOL_LIMIT), "{:?}", out.warnings);
assert!(out.warnings.iter().any(|w| w == writer::SYMBOL_ART), "{:?}", out.warnings);
// 5,001 objects for the tree and each leaf: 3,198 leaves fit in 16,000,000.
let text = String::from_utf8(out.program).unwrap();
let layers = text.split_once("%%EndSetup").unwrap().1;
assert_eq!(layers.matches("\r\nf\r\n").count(), 3198, "the squares of the leaves written");
}
#[test]
fn a_stained_symbol_instance_is_written_in_its_stained_colors() {
let mut doc = Document::new(200.0, 100.0);