mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-14 19:26:56 -04:00
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 <[email protected]>
This commit is contained in:
1 parent
e1beafb359
commit
650c5a00a6
2 files changed
+20
-3
No files matched your search
@@ -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()?;
|
||||
|
||||
@@ -303,3 +303,16 @@ fn edit_group_refuses_to_change_built_in_swatches() {
|
||||
let ok = run(&mut s, "swatch.editGroup", json!({"group": "Marks", "colors": [key, "#0000ff"]}));
|
||||
assert_eq!(ok["swatches"][0], vectorcraft_color::swatch::REGISTRATION, "kept as it is");
|
||||
}
|
||||
|
||||
/// A `{c, m, y, k}` object takes one scale for the whole colour: percent as soon as any component is
|
||||
/// above 1, else fractions. Reading each component on its own turned K 0.79 % into 79 %.
|
||||
#[test]
|
||||
fn cmyk_object_reads_one_scale_for_every_component() {
|
||||
let k = |v: Value| color_value(&v).unwrap().to_cmyk();
|
||||
let close = |a: [f32; 4], b: [f32; 4]| a.iter().zip(b).all(|(x, y)| (x - y).abs() < 1e-5);
|
||||
assert!(close(k(json!({"c": 18.16, "m": 13.39, "y": 13.9, "k": 0.79})), [0.1816, 0.1339, 0.139, 0.0079]));
|
||||
assert!(close(k(json!({"c": 100, "m": 0.5, "y": 0, "k": 1})), [1.0, 0.005, 0.0, 0.01]));
|
||||
// All components 0..1: fractions, as before.
|
||||
assert!(close(k(json!({"c": 0.1, "m": 0.5, "y": 0.9, "k": 0.2})), [0.1, 0.5, 0.9, 0.2]));
|
||||
assert!(close(k(json!({"c": 0, "m": 1, "y": 1, "k": 0})), [0.0, 1.0, 1.0, 0.0]));
|
||||
}
|
||||
Reference in new issue
Block a user