Color params: one scale per CMYK colour, not per component

paint.setFill {"color": {"c": 18.16, "m": 13.39, "y": 13.9, "k": 0.79}} stored
K 79 %: recolor.colors listed the colour as "cmyk 18.16 13.39 13.9 79" and the
exported PDF printed it as a dark grey. color_value chose the scale for each
component on its own (above 1: percent, else a fraction), so a percentage of
1 or less beside larger ones became a fraction.

A {c, m, y, k} object now takes percent for every component as soon as one is
above 1, and fractions only when all four are within 0..1, as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
japbcoelho
2026-10-12 06:59:49 +07:00
committed by bflatastic
co-authored by Claude Opus 5.5
parent e1beafb359
commit 650c5a00a6
2 changed files with 20 additions and 3 deletions
+7 -3
View File
@@ -363,7 +363,7 @@ pub fn matrix_param(p: &Value, key: &str) -> Option<Affine> {
Some(Affine::new(c))
}
/// A colour from `"#rrggbb"`, a colour key (`"cmyk 0 100 100 0"`, `"lab 55 60 40"`), `[r,g,b]` (0..1),
/// `{"c":..,"m":..,"y":..,"k":..}`, `{"gray":..}` or `{"l":..,"a":..,"b":..}` (CIE Lab: L 0..100, a and b about
/// `{"c":..,"m":..,"y":..,"k":..}` (percent when any component is above 1, else 0..1), `{"gray":..}` or `{"l":..,"a":..,"b":..}` (CIE Lab: L 0..100, a and b about
/// −128..127).
pub fn color_value(v: &Value) -> Option<Color> {
match v {
@@ -372,8 +372,12 @@ pub fn color_value(v: &Value) -> Option<Color> {
Value::Array(a) if a.len() >= 3 => Some(Color::rgb(a[0].as_f64()? as f32, a[1].as_f64()? as f32, a[2].as_f64()? as f32)),
Value::Object(o) => {
if let (Some(c), Some(m), Some(y), Some(k)) = (o.get("c"), o.get("m"), o.get("y"), o.get("k")) {
let f = |v: &Value| v.as_f64().map(|x| if x > 1.0 { x / 100.0 } else { x } as f32);
return Some(Color::cmyk(f(c)?, f(m)?, f(y)?, f(k)?));
// One scale for the whole colour: percent when any component is above 1, else 0..1.
// Deciding per component read {c: 18, k: 0.79} as K 79 %.
let v = [c.as_f64()?, m.as_f64()?, y.as_f64()?, k.as_f64()?];
let scale = if v.iter().any(|x| *x > 1.0) { 100.0 } else { 1.0 };
let f = |x: f64| (x / scale) as f32;
return Some(Color::cmyk(f(v[0]), f(v[1]), f(v[2]), f(v[3])));
}
if let Some(g) = o.get("gray") {
let g = g.as_f64()?;