mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 17:56:50 -06:00
90 lines
4.0 KiB
Rust
90 lines
4.0 KiB
Rust
//! Fill and stroke given to a path of a compound path paint the compound path (#3692): the
|
|
//! compound holds the paint, so a member's own appearance is never drawn.
|
|
|
|
use serde_json::{Value, json};
|
|
use vectorcraft_color::Paint;
|
|
|
|
use super::*;
|
|
|
|
fn run(s: &mut Session, id: &str, p: Value) -> Value {
|
|
s.execute(id, &p).unwrap()
|
|
}
|
|
|
|
fn rect(s: &mut Session, x: f64) -> NodeId {
|
|
NodeId(run(s, "shape.rectangle", json!({"x": x, "y": 0, "width": 40, "height": 40}))["id"].as_u64().unwrap())
|
|
}
|
|
|
|
/// A compound path of two black rectangles and a loose black rectangle → (compound, members, loose).
|
|
fn compound() -> (Session, NodeId, Vec<NodeId>, NodeId) {
|
|
let mut s = Session::new();
|
|
run(&mut s, "file.new", json!({"width": 200, "height": 100}));
|
|
let (a, b) = (rect(&mut s, 0.0), rect(&mut s, 10.0));
|
|
run(&mut s, "select.set", json!({"ids": [a.0, b.0]}));
|
|
run(&mut s, "object.compoundPath.make", json!({}));
|
|
let compound = s.doc().unwrap().selection.objects[0];
|
|
let loose = rect(&mut s, 100.0);
|
|
run(&mut s, "paint.setFill", json!({"color": "#000000", "ids": [compound.0, loose.0]}));
|
|
run(&mut s, "paint.setStroke", json!({"color": "#000000", "ids": [compound.0, loose.0]}));
|
|
let doc = &s.doc().unwrap().doc;
|
|
let members: Vec<NodeId> = doc.node(compound).unwrap().children().into_iter().flatten().map(|m| m.id).collect();
|
|
assert_eq!(members.len(), 2);
|
|
(s, compound, members, loose)
|
|
}
|
|
|
|
/// The hex of `id`'s own top fill (`fill`) or stroke, `None` when it has none or it isn't solid.
|
|
fn paint(s: &Session, id: NodeId, fill: bool) -> Option<String> {
|
|
match s.doc().unwrap().doc.node(id).unwrap().appearance.paint_at(None, fill)? {
|
|
Paint::Solid { color, .. } => Some(color.to_hex()),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
fn solid(hex: &str) -> Option<String> {
|
|
Some(hex.to_string())
|
|
}
|
|
|
|
#[test]
|
|
fn a_fill_given_to_a_member_id_paints_its_compound() {
|
|
let (mut s, compound, members, loose) = compound();
|
|
let member_paint = paint(&s, members[0], true);
|
|
run(&mut s, "paint.setFill", json!({"color": "#ff00ff", "ids": [members[0].0, members[1].0, loose.0]}));
|
|
assert_eq!(paint(&s, compound, true), solid("#ff00ff"), "the compound path takes the fill");
|
|
assert_eq!(paint(&s, loose, true), solid("#ff00ff"));
|
|
assert_eq!(paint(&s, members[0], true), member_paint, "the member's own appearance is left alone");
|
|
assert_eq!(paint(&s, compound, false), solid("#000000"), "the stroke stays");
|
|
run(&mut s, "edit.undo", json!({}));
|
|
assert_eq!(paint(&s, compound, true), solid("#000000"), "one undo step");
|
|
}
|
|
|
|
#[test]
|
|
fn a_stroke_given_to_a_selected_member_paints_its_compound() {
|
|
let (mut s, compound, members, _) = compound();
|
|
run(&mut s, "select.set", json!({"ids": [members[1].0]}));
|
|
run(&mut s, "paint.setStroke", json!({"color": "#00ff00"}));
|
|
assert_eq!(paint(&s, compound, false), solid("#00ff00"));
|
|
run(&mut s, "paint.setFill", json!({"color": "#0000ff"}));
|
|
assert_eq!(paint(&s, compound, true), solid("#0000ff"));
|
|
}
|
|
|
|
#[test]
|
|
fn the_members_of_one_compound_are_one_target() {
|
|
let (mut s, compound, members, _) = compound();
|
|
run(&mut s, "paint.setFill", json!({"color": "#ff0000", "ids": [compound.0]}));
|
|
// Swapped once per id, the two members would swap the compound path back.
|
|
run(&mut s, "paint.swap", json!({"ids": [members[0].0, members[1].0]}));
|
|
assert_eq!(paint(&s, compound, true), solid("#000000"), "swapped once, not once per member");
|
|
assert_eq!(paint(&s, compound, false), solid("#ff0000"));
|
|
}
|
|
|
|
#[test]
|
|
fn a_group_with_a_compound_still_paints_the_compound_once() {
|
|
let (mut s, compound, _, loose) = compound();
|
|
run(&mut s, "select.set", json!({"ids": [compound.0, loose.0]}));
|
|
let group = NodeId(run(&mut s, "object.group", json!({}))["id"].as_u64().unwrap());
|
|
run(&mut s, "paint.setFill", json!({"color": "#ff0000", "ids": [group.0]}));
|
|
run(&mut s, "paint.swap", json!({"ids": [group.0]}));
|
|
assert_eq!(paint(&s, compound, true), solid("#000000"));
|
|
assert_eq!(paint(&s, compound, false), solid("#ff0000"));
|
|
assert_eq!(paint(&s, loose, false), solid("#ff0000"));
|
|
}
|