mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-11 18:54:55 +00:00
Symbols: an instance that only moves holds art its 9-slice guides move
A symbol whose natural size is not 20 x 20 is drawn through its 9-slice guides by an instance that only moves, so art the guides move can draw outside the art box moved by the instance. The visual box took that moved art box alone, and the renderer culled the instance when only the moved art was in view. The visual box now measures such an instance as it does a scaled one.
This commit is contained in:
@@ -373,7 +373,10 @@ impl Node {
|
||||
NodeKind::SymbolInstance { symbol, xf } => {
|
||||
let b = match symbols.and_then(|s| Some((s, s.art(symbol)?))) {
|
||||
Some((s, art)) if !s.art_strokes() => xf.transform_rect_bbox(art.geometric),
|
||||
Some((_, art)) if moves_only(*xf) => xf.transform_rect_bbox(art.visual),
|
||||
// A symbol drawn at other than its natural size goes through its 9-slice guides.
|
||||
Some((s, art)) if moves_only(*xf) && s.document().symbol_slice_map_of(symbol, art.geometric, *xf).is_none() => {
|
||||
xf.transform_rect_bbox(art.visual)
|
||||
}
|
||||
Some((s, art)) => {
|
||||
let placed = xf.transform_rect_bbox(art.geometric);
|
||||
match s.placed_visual(symbol, *xf).or_else(|| s.sliced_visual(symbol, *xf)) {
|
||||
|
||||
@@ -425,6 +425,29 @@ fn an_instance_is_culled_by_the_art_nested_9_slice_guides_move() {
|
||||
assert_eq!(img.pixel(95, 50), [255, 0, 0, 255]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_instance_that_only_moves_is_culled_by_the_art_its_9_slice_guides_move() {
|
||||
// A symbol made in the app: art in the 20 × 20 square, a natural size of 2 × 2, and guides a
|
||||
// quarter in. An instance that only moves draws it at 20 × 20, ten times its natural size. The
|
||||
// bar from x −9.9 to 0.1 crosses the left guide and is placed by the middle column's map,
|
||||
// x → 1.9x: moved 115 pt right, it draws from x 96.19 to 115.19 while its art box starts at
|
||||
// x 105, out of view.
|
||||
let mut d = Document::new(100.0, 100.0);
|
||||
let bar = rect_node(&mut d, Rect::new(-9.9, -1.0, 0.1, 1.0), Paint::solid(Color::rgb(1.0, 0.0, 0.0)), Paint::None, 0.0);
|
||||
d.symbols.push(vectorcraft_doc::Symbol { dynamic: false, name: "Bar".into(), art: Arc::new(bar) });
|
||||
let frame = rect_node(&mut d, Rect::new(-10.0, -10.0, 10.0, 10.0), Paint::None, Paint::None, 0.0);
|
||||
let inner = Node::new(d.alloc_id(), NodeKind::SymbolInstance { symbol: "Bar".into(), xf: Affine::IDENTITY });
|
||||
let art = Node::group(d.alloc_id(), vec![Arc::new(frame), Arc::new(inner)]);
|
||||
d.symbols.push(vectorcraft_doc::Symbol { dynamic: false, name: "Panel".into(), art: Arc::new(art) });
|
||||
d.unknown.insert(vectorcraft_doc::SYMBOL_SIZES.into(), serde_json::json!({ "Panel": [2.0, 2.0] }));
|
||||
d.set_symbol_nine_slice("Panel", Some(vectorcraft_doc::SymbolNineSlice::default()));
|
||||
let (id, l) = (d.alloc_id(), d.layers[0].id);
|
||||
let xf = Affine::translate((115.0, 50.0));
|
||||
d.insert(Some(l), 0, Node::new(id, NodeKind::SymbolInstance { symbol: "Panel".into(), xf })).unwrap();
|
||||
let img = Renderer::new().render(&d, 100, 100, Affine::IDENTITY, &RenderOptions::default());
|
||||
assert_eq!(img.pixel(98, 50), [255, 0, 0, 255]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_instance_with_a_geometry_effect_is_culled_by_its_reshaped_art() {
|
||||
// The art, (0, 0) to (20, 20), drawn from (-100, 10) is out of view, and the Transform effect
|
||||
|
||||
Reference in New Issue
Block a user