mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-01 05:37:23 -06:00
M3.85: spot colours defined in Lab, with Spot Colors options for Lab values or CMYK equivalents
Colours gain a CIE Lab model (`Color::Lab {l,a,b}`, serde tag `lab`), handled through the
CMS (display, separation, conversions, gamut), tints (toward paper white), keep_model, harmonies,
recolouring, blends, Info and the Color panel. Swatch Options gets a Lab mode
(`swatch.edit {mode: "lab"}` / `{color: {l,a,b}}`), and colour params accept `{l,a,b}`.
Swatches panel → Spot Colors… (`ui.spotColors`, dialog `spotColors`) runs `swatch.spotOptions
{useLab}` (Document.spot_use_lab, default on): Lab spot colours show and separate from their Lab
values, or art linked to them takes their working-CMYK equivalents, as one undo step. PDF export
writes Lab spot inks as Separation spaces with a Lab alternate (tint function from paper white),
or a DeviceCMYK one with CMYK equivalents.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
c1df6f0621
commit
ea61d34a93
@@ -34,6 +34,7 @@ fn hash_color(c: &Color, h: &mut impl Hasher) {
|
||||
Color::Rgb { r, g, b } => (0u8, r.to_bits(), g.to_bits(), b.to_bits()).hash(h),
|
||||
Color::Cmyk { c, m, y, k } => (1u8, c.to_bits(), m.to_bits(), y.to_bits(), k.to_bits()).hash(h),
|
||||
Color::Gray { k } => (2u8, k.to_bits()).hash(h),
|
||||
Color::Lab { l, a, b } => (3u8, l.to_bits(), a.to_bits(), b.to_bits()).hash(h),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -75,17 +75,16 @@ pub fn plates(doc: &Document) -> Vec<Plate> {
|
||||
if let (true, Paint::Solid { color, .. }) = (sw.spot, &sw.paint)
|
||||
&& !v.iter().any(|p| p.name == sw.name)
|
||||
{
|
||||
v.push(Plate { name: sw.name.clone(), spot: true, rgb: c.display_rgb(color) });
|
||||
v.push(Plate { name: sw.name.clone(), spot: true, rgb: c.display_rgb(&doc.linked_color(*color, true)) });
|
||||
}
|
||||
}
|
||||
v
|
||||
}
|
||||
|
||||
fn spot_swatch<'a>(doc: &'a Document, name: &str) -> Option<&'a Color> {
|
||||
doc.swatch(name).filter(|s| s.spot).and_then(|s| match &s.paint {
|
||||
Paint::Solid { color, .. } => Some(color),
|
||||
_ => None,
|
||||
})
|
||||
/// The ink colour of spot swatch `name` as it shows ([`Document::linked_color`]).
|
||||
fn spot_color(doc: &Document, name: &str) -> Option<Color> {
|
||||
let s = doc.swatch(name).filter(|s| s.spot)?;
|
||||
s.paint.color().map(|c| doc.linked_color(c, true))
|
||||
}
|
||||
|
||||
/// A colour's swatch link and tint (`(swatch name, tint 0..1)`), as the colour visitors pass it.
|
||||
@@ -98,7 +97,7 @@ pub fn inks(doc: &Document, c: &Cms, color: &Color, link: Link, intent: Intent)
|
||||
return Inks { cmyk: [tint.clamp(0.0, 1.0); 4], spot: None, registration: true };
|
||||
}
|
||||
if let Some((name, tint)) = link
|
||||
&& spot_swatch(doc, name).is_some()
|
||||
&& doc.swatch(name).is_some_and(|s| s.spot && s.paint.color().is_some())
|
||||
{
|
||||
return Inks { cmyk: [0.0; 4], spot: Some((name.to_string(), tint.clamp(0.0, 1.0))), registration: false };
|
||||
}
|
||||
@@ -201,9 +200,9 @@ fn plate_color(doc: &Document, c: &Cms, proof: &ProofSetup, visible: &[String],
|
||||
for name in visible.iter().filter(|v| !PROCESS_PLATES.contains(&v.as_str())) {
|
||||
let t = ink.spot_tint(name);
|
||||
if t > 0.0
|
||||
&& let Some(sc) = spot_swatch(doc, name)
|
||||
&& let Some(sc) = spot_color(doc, name)
|
||||
{
|
||||
let s = c.display_rgb(sc);
|
||||
let s = c.display_rgb(&sc);
|
||||
for i in 0..3 {
|
||||
rgb[i] *= 1.0 - t * (1.0 - s[i]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user