engine/oklab library

OKLab / OKLCH ↔ linear sRGB ↔ 8-bit ARGB, and gamut mapping (research theme-engine.md §2–3, Recommendations 1–2).

Matrices are the CSS Color 4 compositions (white maps to exactly L = 1, C ≈ 0). They are frozen under engineVersion 1: changing any constant changes generated themes.

Colours in the engine are plain int ARGB (0xAARRGGBB).

Constants

achromaticChroma → const double
Chroma at or below which hue is powerless (CSS Color 4).
chromaSearchMax → const double
Upper bound of the chroma bisection (sRGB max chroma is ≈ 0.3225).

Functions

argbToLin(int argb) → LinRgb
Decodes the RGB channels of argb to linear light (alpha ignored).
argbToOklab(int argb) → LinRgb
ARGB → OKLab.
argbToOklch(int argb) → Lch
ARGB → OKLCH.
compositeOver(int fg, int bg) → int
Source-over composite of fg (any alpha) on opaque bg, per channel in encoded sRGB (what Flutter's Color.alphaBlend does). Returns opaque.
deltaEOK(Lab x, Lab y) → double
Euclidean distance in OKLab (ΔEOK; 0.02 ≈ one JND).
deltaEOKArgb(int a, int b) → double
ΔEOK between two ARGB colours.
inGamut(LinRgb c, [double eps = 1e-9]) → bool
Whether c lies in the sRGB gamut, with tolerance eps.
lerpArgbOklab(int a, int b, double t) → int
Interpolates two ARGB colours in OKLab (t = 0 → a, 1 → b); alpha is interpolated linearly. For theme cross-fades (research §5.4).
linToArgb(LinRgb c) → int
Quantises linear sRGB to opaque 8-bit ARGB.
linToOklab(LinRgb c) → Lab
Linear sRGB → OKLab (sign-matched cube root).
mapOklch(double l, double c, double hDeg) → LinRgb
Gamut-maps OKLCH to linear sRGB by constant-L, constant-h chroma reduction (exact boundary via maxChroma), then clamps float noise. White for L ≥ 1, black for L ≤ 0. Luminance is non-decreasing in L along this map, which the contrast solver relies on.
maxChroma(double l, double hDeg) → double
Largest in-gamut chroma at lightness l and hue hDeg: 24 bisection steps on 0, 0.4 (error < 3e-8). 0 at L ≤ 0 or L ≥ 1.
oklabToLin(Lab c) → Lab
OKLab → linear sRGB (may be out of gamut).
oklabToOklch(Lab lab) → Lch
OKLab → OKLCH. Hue is 0 for achromatic colours.
oklchTenthsToArgb(double l, double c, int hueTenths) → int
OKLCH with hue in integer tenths of a degree → ARGB.
oklchToArgb(double l, double c, double hDeg) → int
OKLCH → gamut-mapped, quantised opaque ARGB.
oklchToOklab(double l, double c, double hDeg) → LinRgb
OKLCH (hue in degrees) → OKLab.
withAlpha(int argb, int alpha) → int
Replaces the alpha channel of argb with alpha (0–255).

Typedefs

Lab = (double, double, double)
OKLab triple.
Lch = ({double c, double h, double l})
OKLCH: lightness 0, 1, chroma ≥ 0, hue in degrees [0, 360).
LinRgb = (double, double, double)
Linear-light sRGB triple (components nominally in 0, 1).