From 284b5b45b693f9bd738c5c8386ccfeb97d510146 Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Sat, 31 Oct 2026 19:06:15 -0700 Subject: [PATCH] Swatch libraries: only a built-in pattern library's own swatches draw its pattern tiles --- crates/engine/src/cmd/patternlib.rs | 12 ++++++++---- crates/engine/src/tests/swatchlib.rs | 11 +++++++---- crates/ui-egui/src/panels/swatches/libraries.rs | 8 +++----- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/crates/engine/src/cmd/patternlib.rs b/crates/engine/src/cmd/patternlib.rs index 09afda500..b3e83ff22 100644 --- a/crates/engine/src/cmd/patternlib.rs +++ b/crates/engine/src/cmd/patternlib.rs @@ -71,10 +71,14 @@ pub fn library(id: &str) -> Option<(LibraryInfo, Arc)> { Some((infos().nth(i)?, MADE.get(i)?.clone())) } -/// The built-in library document that holds pattern `name` (a library panel draws its pattern -/// swatches from it). Pattern names are unique across the built-in libraries. -pub fn pattern_source(name: &str) -> Option> { - PATTERN_LIBRARIES.iter().filter_map(|b| library_doc(b.id)).find(|d| d.pattern(name).is_some()) +/// The built-in library document that holds the pattern of swatch `w`, when `w` is one of a +/// built-in pattern library's own swatches (a library panel draws them from it). A swatch of +/// another library is not, even under the same name. +pub fn swatch_source(w: &Swatch) -> Option> { + let Paint::Pattern { pattern, .. } = &w.paint else { return None }; + let own = |lib: &SwatchLibrary| lib.swatches.iter().any(|s| std::ptr::eq(s, w)); + let b = PATTERN_LIBRARIES.iter().find(|b| library(b.id).is_some_and(|(_, lib)| own(&lib)))?; + library_doc(b.id).filter(|d| d.pattern(pattern).is_some()) } /// Add pattern `name` of library `lib` to `d` with the resources its art uses, as pasting art diff --git a/crates/engine/src/tests/swatchlib.rs b/crates/engine/src/tests/swatchlib.rs index 6c73cc6cc..576b8f17a 100644 --- a/crates/engine/src/tests/swatchlib.rs +++ b/crates/engine/src/tests/swatchlib.rs @@ -719,10 +719,10 @@ fn pattern_libraries_bring_their_patterns_and_add_each_once() { } /// The built-in pattern libraries: unique, tiling patterns with art, whose names no two libraries -/// share. +/// share. Each library's own swatches draw from it; a swatch of the same name elsewhere does not. #[test] fn built_in_pattern_libraries_hold_tiling_patterns_with_unique_names() { - use crate::cmd::patternlib::{PATTERN_LIBRARIES, library_doc, pattern_source}; + use crate::cmd::patternlib::{PATTERN_LIBRARIES, library, library_doc, swatch_source}; let mut names = std::collections::HashSet::new(); for b in PATTERN_LIBRARIES { let d = library_doc(b.id).unwrap(); @@ -731,10 +731,13 @@ fn built_in_pattern_libraries_hold_tiling_patterns_with_unique_names() { assert!(names.insert(p.name.clone()), "{} is in two libraries", p.name); assert!(!p.art.is_empty() && p.width() > 0.0 && p.height() > 0.0, "{}", p.name); assert!(vectorcraft_render::render_pattern_swatch(&d, &p.name, 16).is_some(), "{}", p.name); - assert!(std::sync::Arc::ptr_eq(&pattern_source(&p.name).unwrap(), &d)); + } + let (_, lib) = library(b.id).unwrap(); + for w in &lib.swatches { + assert!(std::sync::Arc::ptr_eq(&swatch_source(w).unwrap(), &d), "{}", w.name); + assert!(swatch_source(&w.clone()).is_none(), "a copy of {} is another library's swatch", w.name); } } - assert!(pattern_source("No Such Pattern").is_none()); } /// #3602: a library titled with a Windows device name is saved under a name that is not one. diff --git a/crates/ui-egui/src/panels/swatches/libraries.rs b/crates/ui-egui/src/panels/swatches/libraries.rs index 349322939..772bc8e28 100644 --- a/crates/ui-egui/src/panels/swatches/libraries.rs +++ b/crates/ui-egui/src/panels/swatches/libraries.rs @@ -2,8 +2,8 @@ use super::actions::deletable; use super::dnd::selection; use super::tiles::{describe, global_mark, list_icons, pattern_thumb_in}; use super::{ - Arc, BuiltinLibrary, GRADIENT_LIBRARIES, Item, LibraryKind, LibraryRef, PATTERN_LIBRARIES, Paint, Rect, Row, SWATCH_LIBRARIES, Swatch, - SwatchLibrary, Ui, Value, VectorcraftApp, json, library_panel, menu_item, patternlib, swatch_tile, swatchlib, + Arc, BuiltinLibrary, GRADIENT_LIBRARIES, Item, LibraryKind, LibraryRef, PATTERN_LIBRARIES, Rect, Row, SWATCH_LIBRARIES, Swatch, SwatchLibrary, + Ui, Value, VectorcraftApp, json, library_panel, menu_item, patternlib, swatch_tile, swatchlib, }; fn library_refs(libs: Vec) -> Vec { @@ -100,9 +100,7 @@ impl LibraryKind for SwatchLibraries { fn draw(_: &VectorcraftApp, ui: &Ui, r: Rect, w: &Swatch, selected: bool, hovered: bool) { swatch_tile(ui, r, &w.paint, selected, hovered); // A built-in pattern library's pattern, drawn from the library. - if let Paint::Pattern { pattern, .. } = &w.paint - && let Some(src) = patternlib::pattern_source(pattern) - { + if let Some(src) = patternlib::swatch_source(w) { pattern_thumb_in(&src, ui, r.shrink(1.0), &w.paint); } if w.global {