Gradient: Perceptual PDF help says an RGB destination keeps RGB stops in RGB

The `method` text of `paint.editGradient` and two passages of
docs/mcp.md said a CMYK document writes RGB and Lab gradient stops in
CMYK. An export that converts colors to an RGB destination profile
converts them to that profile first, so in a CMYK document they stay
RGB and a Perceptual spot gradient with such stops is written as an
image with the spot warning. The texts now say so, and the test of RGB
stops in a CMYK document also checks the RGB destination case.
This commit is contained in:
dotCooCoo
2026-11-05 03:55:52 +07:00
committed by bflatastic
parent b742c77596
commit 0f99ca1895
3 changed files with 16 additions and 5 deletions
+1 -1
View File
@@ -23,7 +23,7 @@ pub fn specs() -> Vec<CommandSpec> {
"Gradient",
["Window", "Gradient"],
None,
"{stroke?: bool (default: the targeted item's kind, else the active proxy), kind?: linear|radial|freeform (freeform places points on each object, coloured along the stops), mode?: points|lines (freeform: how the Gradient tool adds points), method?: classic|perceptual (how the colours between the stops mix: in display RGB, or perceptually (OKLab) so the steps look even; SVG exports draw a Perceptual gradient as an image, and PDF exports do too unless it is linear or radial, has spot color stops, every other stop is paper white or written in CMYK or gray (a CMYK document, or an export that converts colors to a CMYK destination profile, writes RGB and Lab stops in CMYK), it is not a dithered fill and its curve does not have too many stops: then PDF writes tints of one spot ink as a Separation shading in that ink, and spot inks mixed with other spot, CMYK or gray inks as a DeviceN shading; freeform gradients mix their own way), stops?: [{offset 0..1, color? (needed without swatch; #rrggbbaa and #rgba are refused), opacity? 0..1 (or 0..100), midpoint? 0.13..0.87, swatch?: colour swatch name (a global or spot colour or tint swatch links the stop, so swatch edits recolour it and a spot stop prints on its plate; a process colour just gives its colour), tint?: 0..100 (% of the linked swatch; default 100, or a tint swatch's own)}] (at least 2; a freeform gradient's points are recoloured along them), keepModel?: bool (as paint.setFill; a stop color the gradient already has keeps its model), angle?: deg, aspect?: %, reverse?: bool, dither?: bool (fills only: a linear or radial gradient fill is drawn with fine noise that hides banding, and as pixels in SVG and PDF exports), item?: fill/stroke item index|null (omitted: the Appearance panel's active item when it is of the edited kind), ids?|id?, strokeMode?: within|along|across (strokes only: the gradient lies on the page and shows through the stroke, runs from the start of each subpath to its end, or runs from the stroke's left edge to its right all along it; with nothing selected, for the next object drawn; type characters' own strokes always paint within), target?: \"object\"|\"contents\"} edit the gradient in place (keeps its placement); solid/none paints become the default gradient",
"{stroke?: bool (default: the targeted item's kind, else the active proxy), kind?: linear|radial|freeform (freeform places points on each object, coloured along the stops), mode?: points|lines (freeform: how the Gradient tool adds points), method?: classic|perceptual (how the colours between the stops mix: in display RGB, or perceptually (OKLab) so the steps look even; SVG exports draw a Perceptual gradient as an image, and PDF exports do too unless it is linear or radial, has spot color stops, every other stop is paper white or written in CMYK or gray (an export that converts colors to a CMYK destination profile writes RGB and Lab stops in CMYK, and so does a CMYK document unless the export converts colors to an RGB destination profile), it is not a dithered fill and its curve does not have too many stops: then PDF writes tints of one spot ink as a Separation shading in that ink, and spot inks mixed with other spot, CMYK or gray inks as a DeviceN shading; freeform gradients mix their own way), stops?: [{offset 0..1, color? (needed without swatch; #rrggbbaa and #rgba are refused), opacity? 0..1 (or 0..100), midpoint? 0.13..0.87, swatch?: colour swatch name (a global or spot colour or tint swatch links the stop, so swatch edits recolour it and a spot stop prints on its plate; a process colour just gives its colour), tint?: 0..100 (% of the linked swatch; default 100, or a tint swatch's own)}] (at least 2; a freeform gradient's points are recoloured along them), keepModel?: bool (as paint.setFill; a stop color the gradient already has keeps its model), angle?: deg, aspect?: %, reverse?: bool, dither?: bool (fills only: a linear or radial gradient fill is drawn with fine noise that hides banding, and as pixels in SVG and PDF exports), item?: fill/stroke item index|null (omitted: the Appearance panel's active item when it is of the edited kind), ids?|id?, strokeMode?: within|along|across (strokes only: the gradient lies on the page and shows through the stroke, runs from the start of each subpath to its end, or runs from the stroke's left edge to its right all along it; with nothing selected, for the next object drawn; type characters' own strokes always paint within), target?: \"object\"|\"contents\"} edit the gradient in place (keeps its placement); solid/none paints become the default gradient",
has_doc,
edit_gradient
),
+11
View File
@@ -315,6 +315,17 @@ fn perceptual_spot_gradients_with_rgb_stops_in_a_cmyk_document_export_as_device_
assert!(pdf.contains("/ShadingType 2") && pdf.contains("/Ink]/DeviceCMYK"), "{what}: a DeviceN shading with Ink");
assert!(!r.warnings.iter().any(|w| w.contains("spot")), "{what}: {:?}", r.warnings);
}
// A conversion to an RGB destination keeps the RGB stop in RGB, in a CMYK document too: an
// image, with the spot warning.
let mut to_rgb = plain.clone();
to_rgb.settings.output = vectorcraft_pdf::OutputSettings {
conversion: vectorcraft_pdf::ColorConversion::Destination,
destination: vectorcraft_color::cms::SRGB.into(),
..Default::default()
};
let r = vectorcraft_pdf::export_with_report(&cmyk, &to_rgb).unwrap();
assert!(String::from_utf8_lossy(&r.bytes).contains("/Subtype/Image"), "RGB destination: an image");
assert!(r.warnings.iter().any(|w| w.contains("spot")), "RGB destination: {:?}", r.warnings);
}
#[test]
+4 -4
View File
@@ -926,8 +926,8 @@ Method (the Gradient panel's menu): `classic` (the default) mixes the colours be
Perceptual gradient as an image at the Document Raster Effects resolution (a dithered Perceptual fill with its noise).
PDF exports write it the same way, except for a linear or radial gradient with spot color stops whose other stops
are all paper white or written in CMYK or gray, that is not a dithered fill and whose curve does not have too many
stops. A CMYK document, or an export that converts colors to a CMYK destination profile, writes RGB and Lab stops in
CMYK. PDF writes tints of one spot ink as a Separation shading in that ink, and spot inks mixed with other spot, CMYK
stops. An export that converts colors to a CMYK destination profile writes RGB and Lab stops in CMYK, and so does a
CMYK document unless the export converts colors to an RGB destination profile. PDF writes tints of one spot ink as a Separation shading in that ink, and spot inks mixed with other spot, CMYK
or gray inks as a DeviceN shading.
`paint.setFill`/`paint.setStroke` take it in `gradient` too:
@@ -2788,8 +2788,8 @@ give it `swatch` (and `tint` %, default 100 or a tint swatch's own) instead of `
in gradient swatches. A spot stop separates on its plate. A linear or radial gradient whose stops are all tints of one spot ink (or
paper white, 0 %) exports to PDF as a Separation shading, and one that mixes spot inks with other spot, CMYK or gray
inks exports as a DeviceN shading. A gradient that mixes a spot ink with colors written in RGB or Lab is written in
process colors, with a warning; a CMYK document, or an export that converts colors to a CMYK destination profile,
writes RGB and Lab stops in CMYK. Freeform gradients and dithered fills export to PDF as images in process colors, and Method
process colors, with a warning; an export that converts colors to a CMYK destination profile writes RGB and Lab stops
in CMYK, and so does a CMYK document unless the export converts colors to an RGB destination profile. Freeform gradients and dithered fills export to PDF as images in process colors, and Method
above covers Perceptual gradients.
```json