Skip to content

Commit

Permalink
out of gamut hwb (#1452)
Browse files Browse the repository at this point in the history
  • Loading branch information
romainmenke authored Aug 10, 2024
1 parent 66f7bec commit 31769ce
Show file tree
Hide file tree
Showing 13 changed files with 318 additions and 328 deletions.
60 changes: 3 additions & 57 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions packages/color-helpers/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changes to Color Helpers

### Unreleased (patch)

- fix `XYZ_D50_to_HWB` to not do corrections for out of gamut colors.

### 5.0.0

_August 3, 2024_
Expand Down
230 changes: 115 additions & 115 deletions packages/color-helpers/dist/index.cjs

Large diffs are not rendered by default.

222 changes: 111 additions & 111 deletions packages/color-helpers/dist/index.mjs

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions packages/color-helpers/scripts/check-changes.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const WATCHED_FILES = [
'https://raw.githubusercontent.com/w3c/csswg-drafts/main/css-color-4/hslToRgb.js',
'https://raw.githubusercontent.com/w3c/csswg-drafts/main/css-color-4/better-rgbToHsl.js',
'https://raw.githubusercontent.com/w3c/csswg-drafts/main/css-color-4/hwbToRgb.js',
'https://raw.githubusercontent.com/w3c/csswg-drafts/main/css-color-4/rgbToHwb.js',
];

const newHashes = await Promise.all(WATCHED_FILES.map(async urlPath => {
Expand Down
5 changes: 3 additions & 2 deletions packages/color-helpers/scripts/hashes.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"cd99f5e1c28fc9df18684e351049e7a6",
"094c9859b0960c4e394947cc4832b54f",
"c9e2f2a3b2cba543a01cb8aa5d77c04a",
"1d05413ce5d8b0669b6048f87338b106",
"7aba804ac76ce5d733956b4251194344",
"d575d036af8c4a813217192a15982021",
"f912dea8d7d9813556f3ece0730f5392"
"f912dea8d7d9813556f3ece0730f5392",
"45dd3fb5a146c0865a4ed06d4d230eb0"
]
28 changes: 28 additions & 0 deletions packages/color-helpers/src/conversions/srgb-to-hue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { Color } from "../types/color";

export function sRGB_to_Hue(x: Color): number {
const red = x[0];
const green = x[1];
const blue = x[2];

const max = Math.max(red, green, blue);
const min = Math.min(red, green, blue);
let hue = NaN;
const d = max - min;

if (d !== 0) {
switch (max) {
case red: hue = (green - blue) / d + (green < blue ? 6 : 0); break;
case green: hue = (blue - red) / d + 2; break;
case blue: hue = (red - green) / d + 4;
}

hue *= 60;
}

if (hue >= 360) {
hue -= 360;
}

return hue;
}
70 changes: 35 additions & 35 deletions packages/color-helpers/src/conversions/xyz/index.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,38 @@
import type { Color } from '../../types/color';
import { D65_to_D50 } from '../../conversions/d65-to-d50';
import { HSL_to_sRGB } from '../../conversions/hsl-to-srgb';
import { HWB_to_sRGB } from '../../conversions/hwb-to-srgb';
import { LCH_to_Lab } from '../../conversions/lch-to-lab';
import { Lab_to_XYZ } from '../../conversions/lab-to-xyz';
import { OKLCH_to_OKLab } from '../../conversions/oklch-to-oklab';
import { OKLab_to_XYZ } from '../../conversions/oklab-to-xyz';
import { lin_2020 } from '../../conversions/lin-2020';
import { lin_2020_to_XYZ } from '../../conversions/lin-2020-to-xyz';
import { lin_P3 } from '../../conversions/lin-p3';
import { lin_P3_to_XYZ } from '../../conversions/lin-p3-to-xyz';
import { lin_ProPhoto } from '../../conversions/lin-pro-photo';
import { lin_ProPhoto_to_XYZ } from '../../conversions/lin-pro-photo-to-xyz';
import { lin_a98rgb } from '../../conversions/lin-a98rgb';
import { lin_a98rgb_to_XYZ } from '../../conversions/lin-a98rgb-to-xyz';
import { lin_sRGB } from '../../conversions/lin-srgb';
import { lin_sRGB_to_XYZ } from '../../conversions/lin-srgb-to-xyz';
import { D50_to_D65 } from '../../conversions/d50-to-d65';
import { XYZ_to_lin_sRGB } from '../../conversions/xyz-to-lin-srgb';
import { gam_sRGB } from '../../conversions/gam-srgb';
import { sRGB_to_HSL } from '../../conversions/srgb-to-hsl';
import { XYZ_to_lin_P3 } from '../../conversions/xyz-to-lin-p3';
import { gam_P3 } from '../../conversions/gam-p3';
import { XYZ_to_Lab } from '../../conversions/xyz-to-lab';
import { XYZ_to_OKLab } from '../../conversions/xyz-to-oklab';
import { Lab_to_LCH } from '../../conversions/lab-to-lch';
import { OKLab_to_OKLCH } from '../../conversions/oklab-to-oklch';
import { XYZ_to_lin_a98rgb } from '../../conversions/xyz-to-lin-a98rgb';
import { gam_a98rgb } from '../../conversions/gam-a98rgb';
import { XYZ_to_lin_2020 } from '../../conversions/xyz-to-lin-2020';
import { gam_2020 } from '../../conversions/gam-2020';
import { XYZ_to_lin_ProPhoto } from '../../conversions/xyz-to-lin-pro-photo';
import { gam_ProPhoto } from '../../conversions/gam-pro-photo';
import { D50_to_D65 } from '../d50-to-d65';
import { D65_to_D50 } from '../d65-to-d50';
import { HSL_to_sRGB } from '../hsl-to-srgb';
import { HWB_to_sRGB } from '../hwb-to-srgb';
import { LCH_to_Lab } from '../lch-to-lab';
import { Lab_to_LCH } from '../lab-to-lch';
import { Lab_to_XYZ } from '../lab-to-xyz';
import { OKLCH_to_OKLab } from '../oklch-to-oklab';
import { OKLab_to_OKLCH } from '../oklab-to-oklch';
import { OKLab_to_XYZ } from '../oklab-to-xyz';
import { XYZ_to_Lab } from '../xyz-to-lab';
import { XYZ_to_OKLab } from '../xyz-to-oklab';
import { XYZ_to_lin_2020 } from '../xyz-to-lin-2020';
import { XYZ_to_lin_P3 } from '../xyz-to-lin-p3';
import { XYZ_to_lin_ProPhoto } from '../xyz-to-lin-pro-photo';
import { XYZ_to_lin_a98rgb } from '../xyz-to-lin-a98rgb';
import { XYZ_to_lin_sRGB } from '../xyz-to-lin-srgb';
import { gam_2020 } from '../gam-2020';
import { gam_P3 } from '../gam-p3';
import { gam_ProPhoto } from '../gam-pro-photo';
import { gam_a98rgb } from '../gam-a98rgb';
import { gam_sRGB } from '../gam-srgb';
import { lin_2020 } from '../lin-2020';
import { lin_2020_to_XYZ } from '../lin-2020-to-xyz';
import { lin_P3 } from '../lin-p3';
import { lin_P3_to_XYZ } from '../lin-p3-to-xyz';
import { lin_ProPhoto } from '../lin-pro-photo';
import { lin_ProPhoto_to_XYZ } from '../lin-pro-photo-to-xyz';
import { lin_a98rgb } from '../lin-a98rgb';
import { lin_a98rgb_to_XYZ } from '../lin-a98rgb-to-xyz';
import { lin_sRGB } from '../lin-srgb';
import { lin_sRGB_to_XYZ } from '../lin-srgb-to-xyz';
import { sRGB_to_HSL } from '../srgb-to-hsl';
import { sRGB_to_Hue } from '../srgb-to-hue';

/**
* @param {Color} color [r, g, b]
Expand Down Expand Up @@ -132,11 +133,10 @@ export function XYZ_D50_to_HWB(x: Color): Color {
y = D50_to_D65(y);
y = XYZ_to_lin_sRGB(y);
const srgb = gam_sRGB(y);
y = sRGB_to_HSL(srgb);

const white = Math.min(srgb[0], srgb[1], srgb[2]);
const black = 1 - Math.max(srgb[0], srgb[1], srgb[2]);
return ([y[0], white * 100, black * 100]);
return [sRGB_to_Hue(srgb), white * 100, black * 100];
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/css-color-parser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"dist"
],
"dependencies": {
"@csstools/color-helpers": "^4.2.1",
"@csstools/color-helpers": "^5.0.0",
"@csstools/css-calc": "^2.0.0"
},
"peerDependencies": {
Expand Down
12 changes: 11 additions & 1 deletion packages/css-color-parser/test/basic/hwb.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { color } from '@csstools/css-color-parser';
import assert from 'node:assert';
import { parse } from '../util/parse.mjs';
import { serialize_sRGB_data } from '../util/serialize.mjs';
import { serialize_P3_data, serialize_sRGB_data } from '../util/serialize.mjs';

assert.deepStrictEqual(
serialize_sRGB_data(color(parse('hwb(90deg 25% 25%)'))),
Expand All @@ -12,3 +12,13 @@ assert.deepStrictEqual(
serialize_sRGB_data(color(parse('hwb(90deg 25 25)'))),
'rgb(128, 191, 64)',
);

assert.deepStrictEqual(
serialize_P3_data(color(parse('hwb(from color(srgb 1.59343 0.58802 1.40564) h w b / alpha)')), false),
'color(display-p3 1.47868 0.65877 1.37065)',
);

assert.deepStrictEqual(
serialize_P3_data(color(parse('hwb(from lab(100 104.3 -50.9) h w b)')), false),
'color(display-p3 1.47874 0.65856 1.37055)',
);
8 changes: 4 additions & 4 deletions packages/css-color-parser/test/util/serialize.mjs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { serializeRGB, serializeP3, serializeOKLCH, serializeHSL } from '@csstools/css-color-parser';

export function serialize_sRGB_data(x) {
export function serialize_sRGB_data(x, gamutMapping = true) {
if (!x) {
return '';
}

return serializeRGB(x).toString();
return serializeRGB(x, gamutMapping).toString();
}

export function serialize_HSL_data(x) {
Expand All @@ -16,12 +16,12 @@ export function serialize_HSL_data(x) {
return serializeHSL(x).toString();
}

export function serialize_P3_data(x) {
export function serialize_P3_data(x, gamutMapping = true) {
if (!x) {
return '';
}

return serializeP3(x).toString();
return serializeP3(x, gamutMapping).toString();
}

export function serialize_OKLCH_data(x) {
Expand Down
2 changes: 1 addition & 1 deletion plugins/postcss-contrast-color-function/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"dist"
],
"dependencies": {
"@csstools/color-helpers": "^4.2.1",
"@csstools/color-helpers": "^5.0.0",
"@csstools/css-color-parser": "^3.0.0",
"@csstools/css-parser-algorithms": "^3.0.0",
"@csstools/css-tokenizer": "^3.0.0",
Expand Down
2 changes: 1 addition & 1 deletion plugins/postcss-text-decoration-shorthand/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"dist"
],
"dependencies": {
"@csstools/color-helpers": "^4.2.1",
"@csstools/color-helpers": "^5.0.0",
"postcss-value-parser": "^4.2.0"
},
"peerDependencies": {
Expand Down

0 comments on commit 31769ce

Please sign in to comment.