vectorcraft/crates/render/src/tests_tileedge.rs

70 lines
3.3 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! Pattern editing mode: the tile edge in the Tile Edge Color, and Show Swatch Bounds.
use super::*;
use vectorcraft_color::{Color, Paint};
use vectorcraft_doc::pattern::{PatternDef, PatternEdit, TileType};
use vectorcraft_doc::{Appearance, Node};
use vectorcraft_geom::shapes;
/// A document editing a 20×20 pattern tile of type `tt` (a red 10×10 square in its corner, no
/// preview copies), its tile edge and swatch bounds shown as asked.
fn editing(tt: TileType, edge: bool, bounds: bool) -> Document {
let mut d = Document::new(200.0, 200.0);
let id = d.alloc_id();
let red = Node::path(
id,
shapes::rectangle(Rect::new(0.0, 0.0, 10.0, 10.0)),
Appearance::basic(Paint::solid(Color::rgb(1.0, 0.0, 0.0)), Paint::None, 0.0),
);
let mut def = PatternDef::new("Checks", vec![Arc::new(red.clone())]);
def.tile = Rect::new(0.0, 0.0, 20.0, 20.0);
(def.tile_type, def.copies, def.show_tile_edge, def.show_swatch_bounds) = (tt, 1, edge, bounds);
d.patterns.push(def);
let layer = d.add_layer(Some("Pattern Editing Mode"));
d.insert(Some(layer), 0, red).unwrap();
d.pattern_edit = Some(PatternEdit { pattern: "Checks".into(), layer, original: None });
d
}
/// `d` at 1:1 with the tile's corner at the centre of pixel (50, 50), on white.
fn render(d: &Document, tile_edge: Option<[u8; 3]>) -> Rendered {
let opts = RenderOptions { background: Some([255; 4]), tile_edge: tile_edge.unwrap_or(RenderOptions::default().tile_edge), ..Default::default() };
Renderer::new().render(d, 120, 120, Affine::translate((50.5, 50.5)), &opts)
}
fn is_white(p: [u8; 4]) -> bool {
p[0] > 245 && p[1] > 245 && p[2] > 245
}
#[test]
fn the_tile_edge_takes_the_tile_edge_color() {
let green = render(&editing(TileType::Grid, true, false), Some([0, 200, 0]));
// The left edge below the red square, and the bottom edge.
for (x, y) in [(50, 65), (60, 70), (70, 55)] {
let p = green.pixel(x, y);
assert!(p[1] > 150 && p[0] < 100 && p[2] < 100, "({x},{y}) {p:?}");
}
assert!(is_white(green.pixel(65, 65)), "inside the tile");
// The default is the first layer colour (light blue).
let [r, g, b] = RenderOptions::default().tile_edge;
let p = render(&editing(TileType::Grid, true, false), None).pixel(50, 65);
assert!(p[0].abs_diff(r) < 30 && p[1].abs_diff(g) < 30 && p[2].abs_diff(b) < 30, "{p:?}");
// Hidden: nothing there.
assert!(is_white(render(&editing(TileType::Grid, false, false), Some([0, 200, 0])).pixel(50, 65)));
}
#[test]
fn swatch_bounds_outline_the_period_dashed() {
// Brick by row repeats every two rows: the swatch is 20×40 from the tile's corner.
let tt = TileType::BrickByRow { offset: 0.5 };
let on = render(&editing(tt, false, true), Some([0, 200, 0]));
let green = |p: [u8; 4]| p[1] > 150 && p[0] < 100 && p[2] < 100;
let bottom: Vec<bool> = (51..70).map(|x| green(on.pixel(x, 90))).collect();
assert!(bottom.iter().any(|g| *g) && bottom.iter().any(|g| !*g), "dashed: {bottom:?}");
assert!((51..90).any(|y| green(on.pixel(70, y))), "right side");
assert!(!(51..70).any(|x| green(on.pixel(x, 70))), "the tile edge itself stays hidden");
// Off: no outline.
let off = render(&editing(tt, false, false), Some([0, 200, 0]));
assert!((51..70).all(|x| is_white(off.pixel(x, 90))));
}