honour the /Lab colour space /WhitePoint (#1203) (#1237)

* fix: recognize paragraph drafts as unsaved work (Issue #811)

* fix(color): honour the /Lab colour space /WhitePoint (#1203)

The old path fed every Lab value to the bundled ICC transform as if the
space's white point were D50, so a /Lab space with any other /WhitePoint
(e.g. D65 [0.9505 1 1.089]) rendered off by several levels per channel
and a D65 blue came out 45 levels too red.

Map L*a*b* to XYZ in the space's own white coordinates (ISO 32000-2
§8.6.5.4), Bradford-adapt it to D65 and convert to sRGB directly, as
Poppler does. Missing or degenerate white points fall back to a flat
white and hostile components are clamped without panicking.

Add a render regression that checks the five reported flat patches of
the D65 white-point fixture against their CIE sRGB values.

* Lab: map normalised Indexed palette components onto L*/Range; drop unused LAB.icc

An /Indexed palette over Lab passes its entries as byte/255 (manual_scale),
which the new Lab conversion read as raw L*a*b* and drew near black. Map
them onto L* 0..100 and the a*/b* /Range, with a regression test. Record the
patch as hayro-interpret (25) in vendor/README.md, and remove LAB.icc (no
longer referenced) with its ATTRIBUTION, NOTICE and assets README entries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Main gates: rustfmt tests/viewer.rs; a type alias for the refresh-steps array (clippy type_complexity)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Krzysztof Cieślik
2026-10-12 02:08:21 -04:00
committed by GitHub
co-authored by Claude Opus 5.5 Brandon Thomas
parent 13637b8440
commit bde9dc52fe
10 changed files with 179 additions and 67 deletions
+2 -1
View File
@@ -3925,7 +3925,8 @@ fn edits_let_go_of_the_previous_working_file() {
|| Edit::AddWatermark { pages: vec![0], settings: Watermark { text: "Draft".into(), ..Watermark::default() }, file: None, replace: false };
s.apply(id, Edit::RotatePages { pages: vec![1], degrees: 90 }).unwrap();
// A full refresh, a comment refresh, a content refresh, then undo and redo.
let steps: [(&str, Box<dyn Fn(&mut Session)>); 5] = [
type Step<'a> = Box<dyn Fn(&mut Session) + 'a>;
let steps: [(&str, Step<'_>); 5] = [
("rotate", Box::new(|s: &mut Session| s.apply(id, Edit::RotatePages { pages: vec![0], degrees: 90 }).unwrap())),
("comment", Box::new(move |s: &mut Session| s.apply(id, comment()).unwrap())),
("watermark", Box::new(move |s: &mut Session| s.apply(id, watermark()).unwrap())),