Add wide gamut color support with OKLCH and LAB formats

Implements modern wide gamut color formats with CSS Color Module Level 4
gamut mapping, addressing PR feedback with Go implementation, performance
benchmarks, and reorganized documentation.

Features:
- OKLCH (perceptually uniform color space)
- CIE LAB (device-independent color space)
- CSS Color 4 compliant gamut mapping algorithm
- Inline comment support in color config parsing

Addressing PR Feedback:

1. Go Implementation (tools/utils/style/):
   - Complete OKLCH and LAB parsing with gamut mapping
   - Matches Python implementation structure
   - Comprehensive test suite (all tests passing)
   - Performance benchmarks showing acceptable overhead

2. Performance Benchmarks:
   - OKLCH: ~4.6 µs/op
   - LAB: ~1.5 µs/op
   - 10 mixed colors: ~13 µs total
   - Typical config (50 colors): <0.5ms startup impact

3. Documentation Reorganization:
   - Moved detailed color docs to docs/wide-gamut-colors.rst
   - Configuration docs now link to separate documentation
   - Reduces size of main configuration documentation

Gamut Mapping:
- Binary search chroma reduction from CSS Color Module Level 4
- Preserves lightness and hue while reducing chroma for out-of-gamut colors
- Uses deltaE OK (JND threshold: 0.02) for perceptual difference
- Ensures graceful degradation on sRGB displays

Python Implementation:
- parse_oklch(): OKLCH color parsing with gamut mapping
- parse_lab(): CIE LAB parsing with gamut mapping via OKLCH conversion
- lab_to_oklch(): LAB to OKLCH conversion for consistent gamut mapping
- oklch_to_srgb_gamut_map(): CSS Color 4 gamut mapping algorithm
- srgb_to_oklab(): Reverse conversion for deltaE calculations
- deltaE_ok(): Perceptual color difference in OKLab space

Go Implementation:
- colorspaces.go: All color space conversions and gamut mapping
- wrapper.go: ParseColor() updated to support OKLCH and LAB
- Comprehensive test coverage with benchmarks
- Matches Python implementation behavior

Robustness:
- NaN and infinity validation in all color parsing functions
- Defense-in-depth with validation at parsing and gamut mapping levels
- Returns None/error for invalid input (consistent error handling)
- Validates before clamping operations to prevent NaN propagation

Files changed:
- Python: kitty/rgb.py, kitty_tests/datatypes.py (+250 lines)
- Go: tools/utils/style/colorspaces.go, wrapper.go (+350 lines, tests)
- Docs: docs/wide-gamut-colors.rst (moved from inline)
- Config: kitty/options/definition.py (simplified, links to docs)

References:
- CSS Color Module Level 4: https://www.w3.org/TR/css-color-4/
- OKLCH Color Space: https://bottosson.github.io/posts/oklab/

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Jökull Sólberg
2025-12-25 15:36:23 +00:00
parent 0fb54d32b1
commit 64abd87a9e
8 changed files with 1269 additions and 1 deletions

View File

@@ -0,0 +1,82 @@
Wide gamut color formats
=========================
kitty supports modern wide gamut color formats for precise color specification.
These formats can be used anywhere a color value is accepted in the configuration
(foreground, background, color0-color255, etc.).
OKLCH Colors
------------
OKLCH is a perceptually uniform color space, ideal for creating color themes.
The format is::
foreground oklch(0.9 0.05 140)
color1 oklch(0.7 0.25 25)
Parameters:
- **L** (Lightness): 0 to 1, where 0 is black and 1 is white
- **C** (Chroma): 0 to approximately 0.4, represents color saturation
- **H** (Hue): 0 to 360 degrees (0=red, 120=green, 240=blue)
Benefits:
- Perceptually uniform - equal changes produce equal perceived differences
- Adjusting lightness preserves hue (unlike HSL)
- Industry standard for modern color design
Example::
foreground oklch(0.9 0.05 140)
color1 oklch(0.65 0.25 29) # Vibrant red-orange
color2 oklch(0.65 0.25 142) # Vibrant green
color3 oklch(0.70 0.19 90) # Warm yellow
CIE LAB Colors
--------------
CIE LAB is a device-independent color space designed to approximate human vision.
The format is::
background lab(20 5 -10)
color4 lab(50 0 -50)
Parameters:
- **L**: Lightness, 0 to 100 (0 = black, 100 = white)
- **a**: Green (-) to red (+), typically -100 to +100
- **b**: Blue (-) to yellow (+), typically -100 to +100
Example::
background lab(10 0 0) # Very dark neutral gray
foreground lab(90 0 0) # Very light neutral gray
color1 lab(50 60 40) # Red
color4 lab(50 0 -50) # Blue
Gamut Mapping
-------------
When you specify colors in OKLCH or CIE LAB formats that are outside your display's
color gamut, kitty automatically converts them using the CSS Color Module Level 4
gamut mapping algorithm:
- Preserves the original lightness and hue as much as possible
- Reduces chroma (saturation) until the color fits within the displayable range
- Uses perceptual color difference (deltaE OK) to minimize visible changes
- Maximizes color saturation while staying in gamut
This ensures that wide gamut colors gracefully degrade on standard sRGB displays while
taking full advantage of wide gamut displays when available. The mapping happens
automatically - you don't need to do anything special.
For example, :code:`oklch(0.7 0.4 25)` might be too saturated for sRGB but will be
automatically adjusted to fit while preserving the perceived hue and lightness.
References
----------
- `CSS Color Module Level 4 <https://www.w3.org/TR/css-color-4/>`_
- `OKLCH Color Space <https://bottosson.github.io/posts/oklab/>`_