Skip to content

Commit

Permalink
Merge pull request #120 from facelessuser/feature/lch-chroma
Browse files Browse the repository at this point in the history
Use lch-chroma as the default again
  • Loading branch information
facelessuser authored Feb 19, 2022
2 parents ccdd424 + 8fdf735 commit 214c6e0
Show file tree
Hide file tree
Showing 18 changed files with 27 additions and 26 deletions.
2 changes: 1 addition & 1 deletion coloraide/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
DEF_MIX = 0.5
DEF_HUE_ADJ = "shorter"
DEF_INTERPOLATE = "oklab"
DEF_FIT = "oklch-chroma"
DEF_FIT = "lch-chroma"
DEF_DELTA_E = "76"

ERR_MAP_MSG = """
Expand Down
2 changes: 2 additions & 0 deletions docs/src/markdown/about/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## 0.10.0

- **NEW**: Switch back to using CIELCH for gamut mapping (`lch-chroma`). There are still some edge cases that make
`oklch-chroma` less desirable.
- **FIX**: Fix an issue where when attempting to generate steps some ∆E distance apart, the maximum step range was not
respected and could result in large hangs.

Expand Down
17 changes: 8 additions & 9 deletions docs/src/markdown/gamut.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,15 +131,14 @@ There are various different ways to gamut map a color into a smaller gamut. Curr
Method | Description
-------------- | -----------
`clip` | Simple, naive clipping.
`oklch-chroma` | Compress chroma in the Oklch color space to bring a color in gamut. This is the default method used.
`lch-chroma` | This is like `oklch-chroma` but is done with CIELCH. This is what ColorAide originally used before `oklch-chroma`. Hue preservation is not as good. This method may be removed at some future point as it does not hold the hue as well as Oklch.
`lch-chroma` | Uses chroma reduction in the CIELCH color space to bring a color into gamut. This is the default method used.
`oklch-chroma` | Like `lch-chroma`, but uses the Oklch color space instead. Currently experimental.

!!! note "CSS Level 4 Gamut Mapping"
We do currently use the algorithm as defined in the [CSS Level 4 specification](https://drafts.csswg.org/css-color/#binsearch).
This is because the current algorithm, as defined, has some issues that create gradients that are not smooth.
We currently feel the algorithm we are using does a better job as it creates smooth gradients without odd
discontinuities. If/when the CSS Level 4 specification is updated to address such concerns, we may align more
closely.
We do not currently use the algorithm as defined in the [CSS Level 4 specification](https://drafts.csswg.org/css-color/#binsearch).
This is because the current algorithm, as defined, has some issues that create gradients that are not smooth and
can create unexpected colors in some situations. If/when the CSS Level 4 specification is updated to address such
concerns, we may align more closely.

In this example, we will take the color `#!color lch(100% 50 75)`. CIELCH's gamut is technically unbounded, but when we
convert the color to sRGB, we find that the color is out of gamut. So, using the `fit` method, we can actually transform
Expand Down Expand Up @@ -178,14 +177,14 @@ Color("lch(100% 50 75)").fit("srgb", method='clip')

If we wanted to change the default "fitting" to `clip`, we can also just use a
[class override](./color.md#override-default-settings). Doing this will cause the class to default to `clip` any time a
color needs to be mapped. Though, you can still use chroma compression by specifying `oklch-chroma` for the `method`.
color needs to be mapped. Though, you can still use chroma compression by specifying `lch-chroma` for the `method`.

```playground
class Custom(Color):
FIT = 'clip'
Custom("lch(100% 50 75)").convert('srgb').fit()
Custom("lch(100% 50 75)").convert('srgb').fit(method='oklch-chroma')
Custom("lch(100% 50 75)").convert('srgb').fit(method='lch-chroma')
```

It is important to note that when using fit, there is no tolerance, so even if `in_gamut` allowed enough tolerance to
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ extra_css:
- assets/coloraide-extras/extra-ccd229caf0.css
extra_javascript:
- https://cdn.jsdelivr.net/pyodide/v0.19.0/full/pyodide.js
- assets/coloraide-extras/extra-notebook-8732391e.js
- assets/coloraide-extras/extra-notebook-678306ab.js

extra:
social:
Expand Down
2 changes: 1 addition & 1 deletion tests/test_a98_rgb.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def test_fit(self):

self.assertEqual(
Color('color(a98-rgb 2 -1 0)').to_string(),
'color(a98-rgb 1 1 1)'
'color(a98-rgb 1 0.84447 0.82443)'
)

self.assertEqual(
Expand Down
2 changes: 1 addition & 1 deletion tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -1502,7 +1502,7 @@ class Color2(Color):

self.assertEqual(
Color('color(srgb 2 -1 0)').fit().to_string(),
'rgb(255 153.85 169.85)'
'rgb(255 117.89 100.38)'
)

self.assertEqual(
Expand Down
2 changes: 1 addition & 1 deletion tests/test_display_p3.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def test_fit(self):

self.assertEqual(
Color('color(display-p3 2 -1 0)').to_string(),
'color(display-p3 1 0.74486 0.77344)'
'color(display-p3 1 0.60349 0.48071)'
)

self.assertEqual(
Expand Down
2 changes: 1 addition & 1 deletion tests/test_hsl.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ def test_fit(self):

self.assertEqual(
Color('color(--hsl 20 150% 75%)').to_string(),
'hsl(19.317 100% 77.159%)'
'hsl(19.891 100% 76.496%)'
)

self.assertEqual(
Expand Down
2 changes: 1 addition & 1 deletion tests/test_hsv.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def test_fit(self):

self.assertEqual(
Color('color(--hsv 20 1.5 0.75)').to_string(),
'color(--hsv 51.799 1 0.45576)'
'color(--hsv 40.492 1 0.50528)'
)

self.assertEqual(
Expand Down
2 changes: 1 addition & 1 deletion tests/test_hwb.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def test_fit(self):

self.assertEqual(
Color('color(--hwb 20 0% -55%)').to_string(),
'hwb(14.271 82.804% 0%)'
'hwb(17.844 77.324% 0%)'
)

self.assertEqual(
Expand Down
2 changes: 1 addition & 1 deletion tests/test_okhsl.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def test_fit(self):

self.assertEqual(
Color('color(--okhsl 50 40% 110%)').to_string(),
'color(--okhsl 0 0 1)'
'color(--okhsl 90 0 1)'
)

self.assertEqual(
Expand Down
2 changes: 1 addition & 1 deletion tests/test_okhsv.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def test_fit(self):

self.assertEqual(
Color('color(--okhsv 20 150% 75%)').to_string(),
'color(--okhsv 20 1 0.60559)'
'color(--okhsv 23.815 1 0.57453)'
)

self.assertEqual(
Expand Down
2 changes: 1 addition & 1 deletion tests/test_prophoto_rgb.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def test_fit(self):

self.assertEqual(
Color('color(prophoto-rgb 2 -1 0)').to_string(),
'color(prophoto-rgb 1 0.38166 0.5562)'
'color(prophoto-rgb 1 0 0.25853)'
)

self.assertEqual(
Expand Down
2 changes: 1 addition & 1 deletion tests/test_rec2020.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def test_fit(self):

self.assertEqual(
Color('color(rec2020 2 -1 0)').to_string(),
'color(rec2020 1 0.72306 0.76062)'
'color(rec2020 1 0.51313 0.38209)'
)

self.assertEqual(
Expand Down
2 changes: 1 addition & 1 deletion tests/test_srgb.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ def test_fit(self):

self.assertEqual(
Color('color(srgb 2 -1 0)').to_string(),
'rgb(255 153.85 169.85)'
'rgb(255 117.89 100.38)'
)

self.assertEqual(
Expand Down
2 changes: 1 addition & 1 deletion tests/test_srgb_linear.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def test_fit(self):

self.assertEqual(
Color('color(srgb-linear 2 0 0)').to_string(),
'color(srgb-linear 1 0.29816 0.22913)'
'color(srgb-linear 1 0.26331 0.14651)'
)

self.assertEqual(
Expand Down

0 comments on commit 214c6e0

Please sign in to comment.