diff --git a/crates/engine/src/cmd/buildcmds.rs b/crates/engine/src/cmd/buildcmds.rs index 8fb73898b..7ab4829eb 100644 --- a/crates/engine/src/cmd/buildcmds.rs +++ b/crates/engine/src/cmd/buildcmds.rs @@ -1256,8 +1256,7 @@ pub(crate) fn keep_warnings(params: &tr::TraceParams, res: &tr::TraceResult) -> return vec![format!("Nothing was traced: none of the colors the trace found matches keepColors ({}).", params.keep_colors.join(", "))]; } let mut out = vec![]; - // The trace's palette holds each color it traced, also one that produced no paths. - if res.paths.is_empty() && params.ignore_white && res.palette.is_empty() { + if res.paths.is_empty() && res.keep_ignored { out.push("Nothing was traced: Ignore Color leaves out every area of the colors keepColors lists.".to_string()); } else if res.paths.is_empty() { out.push("Nothing was traced: the colors that match keepColors produce no paths.".to_string()); @@ -1341,8 +1340,8 @@ mod trace_limit_tests { #[test] fn keep_warnings_name_matched_colors_that_produce_no_paths() { let params = tr::TraceParams { keep_colors: vec!["#ff0000".into()], ..tr::TraceParams::default() }; - // A listed color was traced, and produced no paths. - let traced = tr::TraceResult { palette: vec![[255, 0, 0]], ..tr::TraceResult::default() }; + // A listed color was traced, and produced no paths: the palette lists no color without paths. + let traced = tr::TraceResult::default(); let none = vec!["Nothing was traced: the colors that match keepColors produce no paths.".to_string()]; assert_eq!(keep_warnings(¶ms, &traced), none); // With Ignore Color, too: Ignore Color did not leave that color out. @@ -1350,7 +1349,7 @@ mod trace_limit_tests { assert_eq!(keep_warnings(&ignoring, &traced), none); // Ignore Color left out every color that matches: none was traced. assert_eq!( - keep_warnings(&ignoring, &tr::TraceResult::default()), + keep_warnings(&ignoring, &tr::TraceResult { keep_ignored: true, ..tr::TraceResult::default() }), vec!["Nothing was traced: Ignore Color leaves out every area of the colors keepColors lists.".to_string()] ); } diff --git a/crates/trace/src/lib.rs b/crates/trace/src/lib.rs index 657365051..6f5776d7c 100644 --- a/crates/trace/src/lib.rs +++ b/crates/trace/src/lib.rs @@ -493,6 +493,9 @@ pub struct TraceResult { /// Keep Colors: the colors listed in [`TraceParams::keep_colors`] (as written) that no color /// the trace found matches, so that nothing of them is traced. (Flat Logo mode: empty.) pub keep_unmatched: Vec, + /// Keep Colors: whether Ignore Color left out every color the trace found that a listed color + /// matches, so that none of them was traced. (Flat Logo mode: false.) + pub keep_ignored: bool, /// Flat Logo: the size in pixels the image was traced at when it was averaged down first; /// `None` when it was traced at its own size. pub worked_at: Option<(u32, u32)>, @@ -658,6 +661,8 @@ fn trace_paths(img: &Raster, params: &TraceParams, max_anchors: usize) -> Result .filter(|&(_, &k)| !order.iter().any(|&ci| is_kept(q.palette[ci], &[k]))) .map(|(name, _)| name.clone()) .collect(); + // Every layer is left out although a listed color matches one: Ignore Color left those out. + let keep_ignored = !listed.is_empty() && layers.is_empty() && order.iter().any(|&ci| is_kept(q.palette[ci], &listed)); let job = Layers { q: &q, rank: &rank, @@ -673,7 +678,7 @@ fn trace_paths(img: &Raster, params: &TraceParams, max_anchors: usize) -> Result anchors: AtomicUsize::new(0), max_anchors, }; - let mut out = TraceResult { keep_unmatched, ..TraceResult::default() }; + let mut out = TraceResult { keep_unmatched, keep_ignored, ..TraceResult::default() }; // A layer takes about ten bytes a pixel of its box while it is traced (its mask, the labels // of its components, the stack that fills them, its edges): as many layers at a time as fit // in half a gigabyte, so that a large image is not traced at the cost of gigabytes. diff --git a/crates/trace/src/tests.rs b/crates/trace/src/tests.rs index 602fe85b2..73b903486 100644 --- a/crates/trace/src/tests.rs +++ b/crates/trace/src/tests.rs @@ -1310,6 +1310,14 @@ fn keep_colors_names_the_colors_nothing_matches() { // A color Ignore Color leaves out still matches one the trace found. let ignoring = TraceParams { ignore_white: true, ignore_color: Some("#14285a".into()), ..params.clone() }; assert_eq!(unmatched(&["#14285a"], &ignoring), (Vec::new(), 0)); + // The result says that Ignore Color left out every color that matches, and only then. + let keep = |keep: &[&str], params: &TraceParams| { + trace(&img, &TraceParams { keep_colors: keep.iter().map(|k| k.to_string()).collect(), ..params.clone() }) + }; + assert!(keep(&["#14285a"], &ignoring).keep_ignored); + assert!(!keep(&["#14285a", "#f0c832"], &ignoring).keep_ignored); + assert!(!keep(&["#14285a"], ¶ms).keep_ignored); + assert!(!keep(&["#ff00ff"], &ignoring).keep_ignored); // With none listed, none is named. assert!(trace(&img, ¶ms).keep_unmatched.is_empty()); // Flat Logo mode does not use the list.