mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-29 12:17:14 -06:00
Part of #3235: PDF import keeps the spot swatch of a DeviceN color that mixes inks
A DeviceN color with a spot ink at a tint above 0 together with a process plate or a second ink imports as RGB. The importer returned before marking those inks as used, and only used inks become spot swatches, so the spot ink was missing from the document and from every later export. Shading stops take the same path, so a DeviceN gradient lost its ink the same way. The art still imports as RGB with the existing warning; each ink it paints with now becomes a spot swatch with its 100% color.
This commit is contained in:
@@ -301,6 +301,16 @@ impl<'p> Colors<'p> {
|
||||
let process = cmyk.iter().any(|v| *v > 0.0);
|
||||
let (c, t) = match (ink, first_ink) {
|
||||
(Some(_), _) if several || process => {
|
||||
// The color can't link to one swatch, but each ink it paints with is still a
|
||||
// spot swatch.
|
||||
for (c, t) in colorants.iter().zip(comps) {
|
||||
if let Colorant::Ink(k) = *c
|
||||
&& round3(t.clamp(0.0, 1.0)) > 0.0
|
||||
&& let Some(ink) = self.inks.get_mut(k)
|
||||
{
|
||||
ink.used = true;
|
||||
}
|
||||
}
|
||||
self.mixed = true;
|
||||
return None;
|
||||
}
|
||||
|
||||
@@ -164,6 +164,29 @@ fn device_n_inks_become_spot_swatches_and_process_plates_cmyk() {
|
||||
assert_eq!(d.swatches.iter().filter(|s| s.spot).count(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_spot_ink_mixed_with_a_process_plate_keeps_its_swatch() {
|
||||
// Gold and Cyan → CMYK (cyan, 0, gold, 0): a fill, then an axial shading of Gold 0 to 1 over
|
||||
// Cyan at 0.3.
|
||||
let space = format!("[/DeviceN [/Gold /Cyan] /DeviceCMYK {} 0 R]", first_extra(1));
|
||||
let func = "<< /FunctionType 4 /Domain [0 1 0 1] /Range [0 1 0 1 0 1 0 1] /Length 17 >>\nstream\n{ exch 0 exch 0 }\nendstream";
|
||||
let shading = format!(
|
||||
"<< /ShadingType 2 /ColorSpace {space} /Coords [0 0 50 0] /Function << /FunctionType 2 /Domain [0 1] /C0 [0 0.3] /C1 [1 0.3] /N 1 >> /Extend [true true] >>"
|
||||
);
|
||||
let fill = page_with(&format!("/CS0 {space}"), &[("CS0", "0.5 0.3")]);
|
||||
let sh = PdfPage { resources: format!("/Shading << /Sh0 {shading} >>"), ..PdfPage::new(100.0, 50.0, "q 0 0 50 50 re W n /Sh0 sh Q") };
|
||||
for (what, page) in [("fill", fill), ("shading", sh)] {
|
||||
let r = import_with_report(&pdf_with(&[page], &[func], None), &ImportOptions::default()).unwrap();
|
||||
let d = &r.document;
|
||||
assert!(r.warnings.iter().any(|w| w.contains("several inks")), "{what}: {:?}", r.warnings);
|
||||
assert!(links(d).iter().all(Option::is_none), "{what}: the art stays RGB");
|
||||
let gold = d.swatch("Gold").unwrap_or_else(|| panic!("{what}: no Gold swatch"));
|
||||
assert!(gold.spot && gold.global, "{what}: Gold is a spot swatch");
|
||||
assert!(near(gold.paint.color().unwrap(), Color::cmyk(0.0, 0.0, 1.0, 0.0)), "{what}: {gold:?}");
|
||||
assert_eq!(d.swatches.iter().filter(|s| s.spot).count(), 1, "{what}: Cyan is a process plate");
|
||||
}
|
||||
}
|
||||
|
||||
/// The spaces `/CS1` and `/CS2` of two inks (`[/{kind} {a} …]`, `[/{kind} {b} …]`) with the same
|
||||
/// alternate and tint transform, blue at 100 %: they look the same to the interpreter.
|
||||
fn blues(kind: &str, a: &str, b: &str) -> String {
|
||||
|
||||
Reference in New Issue
Block a user