mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
Fix #3233: dimensions are redrawn in the colour mode after Document Color Mode and on open
Follow-up to #3702 (CodeRabbit): dimensions are only redrawn when their recipe changes. Document Color Mode converted their art through the colour profile, so black became a four-ink C67 M67 Y67 K100 again, and CMYK files saved before #3702 kept RGB dimension art. dimension::refresh now also redraws when the document's colour mode changes. dimension::conform, run when a document is opened or reverted (Session::add_document, replace_document), redraws a dimension whose art has colours in the wrong model; one that can't be redrawn keeps its art. dimension_colours_follow_the_document_colour_model covers RGB to CMYK and back, and a CMYK document with RGB dimension art being opened. Without the change it finds C0.67 M0.67 Y0.67 K1 after Document Color Mode.
This commit is contained in:
committed by
bflatastic
parent
d288319e26
commit
3d24c663d2
@@ -227,13 +227,45 @@ pub(crate) fn refresh(before: &Document, doc: &mut Document) -> Result<()> {
|
||||
next.moved = None;
|
||||
}
|
||||
}
|
||||
if next != old || before.node(id).and_then(|n| n.extras().dimension.as_deref()).is_some_and(|d| d != &next) {
|
||||
// A new document colour mode (Document Color Mode) redraws every dimension in it.
|
||||
if next != old
|
||||
|| before.color_mode != doc.color_mode
|
||||
|| before.node(id).and_then(|n| n.extras().dimension.as_deref()).is_some_and(|d| d != &next)
|
||||
{
|
||||
replace(doc, id, next)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Redraw the dimensions of an opened document whose art isn't in its colour mode: files saved
|
||||
/// before dimensions followed the colour mode have RGB dimensions in CMYK documents. A dimension
|
||||
/// that can't be redrawn keeps the art it has.
|
||||
pub(crate) fn conform(doc: &mut Document) {
|
||||
if !doc.dimensions {
|
||||
return;
|
||||
}
|
||||
let mode = doc.color_mode;
|
||||
let off_mode = |c: &Color| match mode {
|
||||
ColorMode::Rgb => matches!(c, Color::Cmyk { .. }),
|
||||
ColorMode::Cmyk => matches!(c, Color::Rgb { .. }),
|
||||
};
|
||||
let mut stale = Vec::new();
|
||||
doc.walk(|n| {
|
||||
if let Some(d) = &n.extras().dimension {
|
||||
let mut off = false;
|
||||
n.walk(&mut |c| off |= [c.appearance.fill_paint(), c.appearance.stroke_paint()].iter().filter_map(|p| p.color()).any(|c| off_mode(&c)));
|
||||
if off {
|
||||
stale.push((n.id, (**d).clone()));
|
||||
}
|
||||
}
|
||||
});
|
||||
for (id, d) in stale {
|
||||
// An error leaves this dimension as it was; the others are still redrawn.
|
||||
let _ = replace(doc, id, d);
|
||||
}
|
||||
}
|
||||
|
||||
/// Option colour `c` as a paint in the document's colour model: in a CMYK document black is K
|
||||
/// only (a rich four-ink black would print a black dimension in every plate) and other colours
|
||||
/// convert through the active colour settings.
|
||||
|
||||
@@ -1587,6 +1587,7 @@ impl Session {
|
||||
Self::refresh_text_bounds(&mut doc);
|
||||
// Guides from files saved before guides had layers go on a layer.
|
||||
doc.adopt_guides();
|
||||
cmd::dimension::conform(&mut doc);
|
||||
self.reset_tool_for_doc_switch();
|
||||
let mut st = DocState::new(doc, path);
|
||||
st.history.limit = self.prefs.history_states as usize;
|
||||
@@ -1604,6 +1605,7 @@ impl Session {
|
||||
doc.limit_depth();
|
||||
Self::refresh_text_bounds(&mut doc);
|
||||
doc.adopt_guides();
|
||||
cmd::dimension::conform(&mut doc);
|
||||
if self.active == Some(index) {
|
||||
// Pending tool work (typing, a drag) belongs to the content being thrown away.
|
||||
self.reset_tool_for_doc_switch();
|
||||
|
||||
@@ -505,4 +505,19 @@ fn dimension_colours_follow_the_document_colour_model() {
|
||||
let line = edge(&mut s);
|
||||
let id = dim(&mut s, line);
|
||||
assert!(colours(&s, id).iter().all(|c| *c == vectorcraft_color::Color::rgb8(0, 0, 0)));
|
||||
// Document Color Mode redraws dimensions in the new mode: K-only black in CMYK, RGB black back
|
||||
// in RGB (not a profile conversion of the old art).
|
||||
let k = vectorcraft_color::Color::cmyk(0.0, 0.0, 0.0, 1.0);
|
||||
run(&mut s, "file.documentColorMode", json!({"mode":"cmyk"}));
|
||||
let after = colours(&s, id);
|
||||
assert!(!after.is_empty() && after.iter().all(|c| *c == k), "{after:?}");
|
||||
run(&mut s, "file.documentColorMode", json!({"mode":"rgb"}));
|
||||
assert!(colours(&s, id).iter().all(|c| *c == vectorcraft_color::Color::rgb8(0, 0, 0)), "{:?}", colours(&s, id));
|
||||
// A CMYK file saved with RGB dimension art (before dimensions followed the colour mode) opens
|
||||
// with its dimensions redrawn in CMYK.
|
||||
let mut old = (*s.doc().unwrap().doc).clone();
|
||||
old.color_mode = vectorcraft_doc::ColorMode::Cmyk;
|
||||
s.add_document(old, None);
|
||||
let opened = colours(&s, id);
|
||||
assert!(!opened.is_empty() && opened.iter().all(|c| *c == k), "{opened:?}");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user