Changeset 289396 in webkit
- Timestamp:
- Feb 8, 2022 10:57:30 AM (5 months ago)
- Location:
- trunk
- Files:
-
- 17 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/imported/w3c/ChangeLog (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/color-mix-computed-expected.txt (modified) (2 diffs)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/color-mix-computed.html (modified) (2 diffs)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/color-mix-valid-expected.txt (modified) (2 diffs)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/color-mix-valid.html (modified) (2 diffs)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/relative-color-computed-expected.txt (modified) (3 diffs)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/relative-color-computed.html (modified) (4 diffs)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/relative-color-valid-expected.txt (modified) (3 diffs)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/relative-color-valid.html (modified) (4 diffs)
-
LayoutTests/platform/gtk/TestExpectations (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/platform/graphics/ColorConversion.cpp (modified) (3 diffs)
-
Source/WebCore/platform/graphics/ColorConversion.h (modified) (10 diffs)
-
Source/WebCore/platform/graphics/ColorTypes.h (modified) (2 diffs)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/TestWebKitAPI/Tests/WebCore/ColorTests.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r289381 r289396 1 2022-02-08 Sam Weinig <weinig@apple.com> 2 3 Conversion to a color space with a smaller gamut should perform gamut mapping 4 https://bugs.webkit.org/show_bug.cgi?id=236200 5 6 Reviewed by Darin Adler. 7 8 * platform/gtk/TestExpectations: 9 Add more tests that are only failing on the GTK bots due to a small floating point issues that needs further investigation. 10 1 11 2022-02-08 Youenn Fablet <youenn@apple.com> 2 12 -
trunk/LayoutTests/imported/w3c/ChangeLog
r289247 r289396 1 2022-02-08 Sam Weinig <weinig@apple.com> 2 3 Conversion to a color space with a smaller gamut should perform gamut mapping 4 https://bugs.webkit.org/show_bug.cgi?id=236200 5 6 Reviewed by Darin Adler. 7 8 Update tests to include more examples that force gamut mapping and update the results 9 of a few existing ones to account for the new algorithm. 10 11 * web-platform-tests/css/css-color/parsing/color-mix-computed-expected.txt: 12 * web-platform-tests/css/css-color/parsing/color-mix-computed.html: 13 * web-platform-tests/css/css-color/parsing/color-mix-valid-expected.txt: 14 * web-platform-tests/css/css-color/parsing/color-mix-valid.html: 15 * web-platform-tests/css/css-color/parsing/relative-color-computed-expected.txt: 16 * web-platform-tests/css/css-color/parsing/relative-color-computed.html: 17 * web-platform-tests/css/css-color/parsing/relative-color-valid-expected.txt: 18 * web-platform-tests/css/css-color/parsing/relative-color-valid.html: 19 1 20 2022-02-07 Chris Dumez <cdumez@apple.com> 2 21 -
trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/color-mix-computed-expected.txt
r288427 r289396 63 63 PASS Property color value 'color-mix(in hsl, hsl(120deg 40% 40% / none), hsl(0deg 40% 40% / 0.5))' 64 64 PASS Property color value 'color-mix(in hsl, hsl(120deg 40% 40% / none), hsl(0deg 40% 40% / none))' 65 PASS Property color value 'color-mix(in hsl, color(display-p3 0 1 0) 100%, rgb(0, 0, 0) 0%)' 66 PASS Property color value 'color-mix(in hsl, lab(100% 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)' 67 PASS Property color value 'color-mix(in hsl, lab(0% 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)' 68 PASS Property color value 'color-mix(in hsl, lch(100% 116 334) 100%, rgb(0, 0, 0) 0%)' 69 PASS Property color value 'color-mix(in hsl, lch(0% 116 334) 100%, rgb(0, 0, 0) 0%)' 70 PASS Property color value 'color-mix(in hsl, oklab(100% 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)' 71 PASS Property color value 'color-mix(in hsl, oklab(0% 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)' 72 PASS Property color value 'color-mix(in hsl, oklch(100% 0.399 336.3) 100%, rgb(0, 0, 0) 0%)' 73 PASS Property color value 'color-mix(in hsl, oklch(0% 0.399 336.3) 100%, rgb(0, 0, 0) 0%)' 65 74 PASS Property color value 'color-mix(in hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%))' 66 75 PASS Property color value 'color-mix(in hwb, hwb(120deg 10% 20%) 25%, hwb(30deg 30% 40%))' … … 126 135 PASS Property color value 'color-mix(in hwb, hwb(120deg 10% 20% / none), hwb(30deg 30% 40% / 0.5))' 127 136 PASS Property color value 'color-mix(in hwb, hwb(120deg 10% 20% / none), hwb(30deg 30% 40% / none))' 137 PASS Property color value 'color-mix(in hwb, color(display-p3 0 1 0) 100%, rgb(0, 0, 0) 0%)' 138 PASS Property color value 'color-mix(in hwb, lab(100% 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)' 139 PASS Property color value 'color-mix(in hwb, lab(0% 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)' 140 PASS Property color value 'color-mix(in hwb, lch(100% 116 334) 100%, rgb(0, 0, 0) 0%)' 141 PASS Property color value 'color-mix(in hwb, lch(0% 116 334) 100%, rgb(0, 0, 0) 0%)' 142 PASS Property color value 'color-mix(in hwb, oklab(100% 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)' 143 PASS Property color value 'color-mix(in hwb, oklab(0% 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)' 144 PASS Property color value 'color-mix(in hwb, oklch(100% 0.399 336.3) 100%, rgb(0, 0, 0) 0%)' 145 PASS Property color value 'color-mix(in hwb, oklch(0% 0.399 336.3) 100%, rgb(0, 0, 0) 0%)' 128 146 PASS Property color value 'color-mix(in lch, lch(10% 20 30deg), lch(50% 60 70deg))' 129 147 PASS Property color value 'color-mix(in lch, lch(10% 20 30deg) 25%, lch(50% 60 70deg))' -
trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/color-mix-computed.html
r288427 r289396 98 98 test_computed_value(`color`, `color-mix(in hsl, hsl(120deg 40% 40% / none), hsl(0deg 40% 40% / none))`, canonicalize(`hsl(60deg 40% 40% / none)`)); 99 99 100 test_computed_value(`color`, `color-mix(in hsl, color(display-p3 0 1 0) 100%, rgb(0, 0, 0) 0%)`, `rgb(0, 249, 66)`); // Naive clip based mapping would give rgb(0, 255, 0). 101 test_computed_value(`color`, `color-mix(in hsl, lab(100% 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). 102 test_computed_value(`color`, `color-mix(in hsl, lab(0% 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, 103 test_computed_value(`color`, `color-mix(in hsl, lch(100% 116 334) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). 104 test_computed_value(`color`, `color-mix(in hsl, lch(0% 116 334) 100%, rgb(0, 0, 0) 0%)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, 105 test_computed_value(`color`, `color-mix(in hsl, oklab(100% 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). 106 test_computed_value(`color`, `color-mix(in hsl, oklab(0% 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(19, 0, 24). 107 test_computed_value(`color`, `color-mix(in hsl, oklch(100% 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). 108 test_computed_value(`color`, `color-mix(in hsl, oklch(0% 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(20, 0, 24). 109 100 110 101 111 test_computed_value(`color`, `color-mix(in hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%))`, `rgb(147, 179, 52)`); … … 170 180 test_computed_value(`color`, `color-mix(in hwb, hwb(120deg 10% 20% / none), hwb(30deg 30% 40% / 0.5))`, canonicalize(`hwb(75deg 20% 30% / 0.5)`)); 171 181 test_computed_value(`color`, `color-mix(in hwb, hwb(120deg 10% 20% / none), hwb(30deg 30% 40% / none))`, canonicalize(`hwb(75deg 20% 30% / none)`)); 182 183 test_computed_value(`color`, `color-mix(in hwb, color(display-p3 0 1 0) 100%, rgb(0, 0, 0) 0%)`, `rgb(0, 249, 66)`); // Naive clip based mapping would give rgb(0, 255, 0). 184 test_computed_value(`color`, `color-mix(in hwb, lab(100% 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). 185 test_computed_value(`color`, `color-mix(in hwb, lab(0% 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, 186 test_computed_value(`color`, `color-mix(in hwb, lch(100% 116 334) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). 187 test_computed_value(`color`, `color-mix(in hwb, lch(0% 116 334) 100%, rgb(0, 0, 0) 0%)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, 188 test_computed_value(`color`, `color-mix(in hwb, oklab(100% 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). 189 test_computed_value(`color`, `color-mix(in hwb, oklab(0% 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(19, 0, 24). 190 test_computed_value(`color`, `color-mix(in hwb, oklch(100% 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). 191 test_computed_value(`color`, `color-mix(in hwb, oklch(0% 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(20, 0, 24). 172 192 173 193 for (const colorSpace of [ "lch", "oklch" ]) { -
trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/color-mix-valid-expected.txt
r288427 r289396 63 63 PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 40% 40% / none), hsl(0deg 40% 40% / 0.5))" should set the property value 64 64 PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 40% 40% / none), hsl(0deg 40% 40% / none))" should set the property value 65 PASS e.style['color'] = "color-mix(in hsl, color(display-p3 0 1 0) 100%, rgb(0, 0, 0) 0%)" should set the property value 66 PASS e.style['color'] = "color-mix(in hsl, lab(100% 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)" should set the property value 67 PASS e.style['color'] = "color-mix(in hsl, lab(0% 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)" should set the property value 68 PASS e.style['color'] = "color-mix(in hsl, lch(100% 116 334) 100%, rgb(0, 0, 0) 0%)" should set the property value 69 PASS e.style['color'] = "color-mix(in hsl, lch(0% 116 334) 100%, rgb(0, 0, 0) 0%)" should set the property value 70 PASS e.style['color'] = "color-mix(in hsl, oklab(100% 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)" should set the property value 71 PASS e.style['color'] = "color-mix(in hsl, oklab(0% 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)" should set the property value 72 PASS e.style['color'] = "color-mix(in hsl, oklch(100% 0.399 336.3) 100%, rgb(0, 0, 0) 0%)" should set the property value 73 PASS e.style['color'] = "color-mix(in hsl, oklch(0% 0.399 336.3) 100%, rgb(0, 0, 0) 0%)" should set the property value 65 74 PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%))" should set the property value 66 75 PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20%) 25%, hwb(30deg 30% 40%))" should set the property value … … 126 135 PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20% / none), hwb(30deg 30% 40% / 0.5))" should set the property value 127 136 PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20% / none), hwb(30deg 30% 40% / none))" should set the property value 137 PASS e.style['color'] = "color-mix(in hwb, color(display-p3 0 1 0) 100%, rgb(0, 0, 0) 0%)" should set the property value 138 PASS e.style['color'] = "color-mix(in hwb, lab(100% 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)" should set the property value 139 PASS e.style['color'] = "color-mix(in hwb, lab(0% 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)" should set the property value 140 PASS e.style['color'] = "color-mix(in hwb, lch(100% 116 334) 100%, rgb(0, 0, 0) 0%)" should set the property value 141 PASS e.style['color'] = "color-mix(in hwb, lch(0% 116 334) 100%, rgb(0, 0, 0) 0%)" should set the property value 142 PASS e.style['color'] = "color-mix(in hwb, oklab(100% 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)" should set the property value 143 PASS e.style['color'] = "color-mix(in hwb, oklab(0% 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)" should set the property value 144 PASS e.style['color'] = "color-mix(in hwb, oklch(100% 0.399 336.3) 100%, rgb(0, 0, 0) 0%)" should set the property value 145 PASS e.style['color'] = "color-mix(in hwb, oklch(0% 0.399 336.3) 100%, rgb(0, 0, 0) 0%)" should set the property value 128 146 PASS e.style['color'] = "color-mix(in lch, lch(10% 20 30deg), lch(50% 60 70deg))" should set the property value 129 147 PASS e.style['color'] = "color-mix(in lch, lch(10% 20 30deg) 25%, lch(50% 60 70deg))" should set the property value -
trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/color-mix-valid.html
r288427 r289396 98 98 test_valid_value(`color`, `color-mix(in hsl, hsl(120deg 40% 40% / none), hsl(0deg 40% 40% / none))`, canonicalize(`hsl(60deg 40% 40% / none)`)); 99 99 100 test_valid_value(`color`, `color-mix(in hsl, color(display-p3 0 1 0) 100%, rgb(0, 0, 0) 0%)`, `rgb(0, 249, 66)`); // Naive clip based mapping would give rgb(0, 255, 0). 101 test_valid_value(`color`, `color-mix(in hsl, lab(100% 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). 102 test_valid_value(`color`, `color-mix(in hsl, lab(0% 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, 103 test_valid_value(`color`, `color-mix(in hsl, lch(100% 116 334) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). 104 test_valid_value(`color`, `color-mix(in hsl, lch(0% 116 334) 100%, rgb(0, 0, 0) 0%)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, 105 test_valid_value(`color`, `color-mix(in hsl, oklab(100% 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). 106 test_valid_value(`color`, `color-mix(in hsl, oklab(0% 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(19, 0, 24). 107 test_valid_value(`color`, `color-mix(in hsl, oklch(100% 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). 108 test_valid_value(`color`, `color-mix(in hsl, oklch(0% 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(20, 0, 24). 109 100 110 101 111 test_valid_value(`color`, `color-mix(in hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%))`, `rgb(147, 179, 52)`); … … 170 180 test_valid_value(`color`, `color-mix(in hwb, hwb(120deg 10% 20% / none), hwb(30deg 30% 40% / 0.5))`, canonicalize(`hwb(75deg 20% 30% / 0.5)`)); 171 181 test_valid_value(`color`, `color-mix(in hwb, hwb(120deg 10% 20% / none), hwb(30deg 30% 40% / none))`, canonicalize(`hwb(75deg 20% 30% / none)`)); 182 183 test_valid_value(`color`, `color-mix(in hwb, color(display-p3 0 1 0) 100%, rgb(0, 0, 0) 0%)`, `rgb(0, 249, 66)`); // Naive clip based mapping would give rgb(0, 255, 0). 184 test_valid_value(`color`, `color-mix(in hwb, lab(100% 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). 185 test_valid_value(`color`, `color-mix(in hwb, lab(0% 104.3 -50.9) 100%, rgb(0, 0, 0) 0%)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, 186 test_valid_value(`color`, `color-mix(in hwb, lch(100% 116 334) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). 187 test_valid_value(`color`, `color-mix(in hwb, lch(0% 116 334) 100%, rgb(0, 0, 0) 0%)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, 188 test_valid_value(`color`, `color-mix(in hwb, oklab(100% 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). 189 test_valid_value(`color`, `color-mix(in hwb, oklab(0% 0.365 -0.16) 100%, rgb(0, 0, 0) 0%)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(19, 0, 24). 190 test_valid_value(`color`, `color-mix(in hwb, oklch(100% 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). 191 test_valid_value(`color`, `color-mix(in hwb, oklch(0% 0.399 336.3) 100%, rgb(0, 0, 0) 0%)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(20, 0, 24). 172 192 173 193 for (const colorSpace of [ "lch", "oklch" ]) { -
trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/relative-color-computed-expected.txt
r288143 r289396 6 6 PASS Property color value 'rgb(from rgb(from rebeccapurple r g b) r g b)' 7 7 PASS Property color value 'rgb(from color(display-p3 0 1 0) r g b / alpha)' 8 PASS Property color value 'rgb(from lab(100% 104.3 -50.9) r g b)' 9 PASS Property color value 'rgb(from lab(0% 104.3 -50.9) r g b)' 10 PASS Property color value 'rgb(from lch(100% 116 334) r g b)' 11 PASS Property color value 'rgb(from lch(0% 116 334) r g b)' 12 PASS Property color value 'rgb(from oklab(100% 0.365 -0.16) r g b)' 13 PASS Property color value 'rgb(from oklab(0% 0.365 -0.16) r g b)' 14 PASS Property color value 'rgb(from oklch(100% 0.399 336.3) r g b)' 15 PASS Property color value 'rgb(from oklch(0% 0.399 336.3) r g b)' 8 16 PASS Property color value 'rgb(from rebeccapurple 0 0 0)' 9 17 PASS Property color value 'rgb(from rebeccapurple 0 0 0 / 0)' … … 75 83 PASS Property color value 'hsl(from hsl(from rebeccapurple h s l) h s l)' 76 84 PASS Property color value 'hsl(from color(display-p3 0 1 0) h s l / alpha)' 85 PASS Property color value 'hsl(from lab(100% 104.3 -50.9) h s l)' 86 PASS Property color value 'hsl(from lab(0% 104.3 -50.9) h s l)' 87 PASS Property color value 'hsl(from lch(100% 116 334) h s l)' 88 PASS Property color value 'hsl(from lch(0% 116 334) h s l)' 89 PASS Property color value 'hsl(from oklab(100% 0.365 -0.16) h s l)' 90 PASS Property color value 'hsl(from oklab(0% 0.365 -0.16) h s l)' 91 PASS Property color value 'hsl(from oklch(100% 0.399 336.3) h s l)' 92 PASS Property color value 'hsl(from oklch(0% 0.399 336.3) h s l)' 77 93 PASS Property color value 'hsl(from rebeccapurple 0 0% 0%)' 78 94 PASS Property color value 'hsl(from rebeccapurple 0deg 0% 0%)' … … 129 145 PASS Property color value 'hwb(from hwb(from rebeccapurple h w b) h w b)' 130 146 PASS Property color value 'hwb(from color(display-p3 0 1 0) h w b / alpha)' 147 PASS Property color value 'hwb(from lab(100% 104.3 -50.9) h w b)' 148 PASS Property color value 'hwb(from lab(0% 104.3 -50.9) h w b)' 149 PASS Property color value 'hwb(from lch(100% 116 334) h w b)' 150 PASS Property color value 'hwb(from lch(0% 116 334) h w b)' 151 PASS Property color value 'hwb(from oklab(100% 0.365 -0.16) h w b)' 152 PASS Property color value 'hwb(from oklab(0% 0.365 -0.16) h w b)' 153 PASS Property color value 'hwb(from oklch(100% 0.399 336.3) h w b)' 154 PASS Property color value 'hwb(from oklch(0% 0.399 336.3) h w b)' 131 155 PASS Property color value 'hwb(from rebeccapurple 0 0% 0%)' 132 156 PASS Property color value 'hwb(from rebeccapurple 0deg 0% 0%)' -
trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/relative-color-computed.html
r289194 r289396 34 34 test_computed_value(`color`, `rgb(from rgb(from rebeccapurple r g b) r g b)`, `rgb(102, 51, 153)`); 35 35 36 // Testing non-sRGB origin colors to see gamut clipping. 37 test_computed_value(`color`, `rgb(from color(display-p3 0 1 0) r g b / alpha)`, `rgb(0, 255, 0)`); 36 // Testing non-sRGB origin colors to see gamut mapping. 37 test_computed_value(`color`, `rgb(from color(display-p3 0 1 0) r g b / alpha)`, `rgb(0, 249, 66)`); // Naive clip based mapping would give rgb(0, 255, 0). 38 test_computed_value(`color`, `rgb(from lab(100% 104.3 -50.9) r g b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). 39 test_computed_value(`color`, `rgb(from lab(0% 104.3 -50.9) r g b)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, 40 test_computed_value(`color`, `rgb(from lch(100% 116 334) r g b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). 41 test_computed_value(`color`, `rgb(from lch(0% 116 334) r g b)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, 42 test_computed_value(`color`, `rgb(from oklab(100% 0.365 -0.16) r g b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). 43 test_computed_value(`color`, `rgb(from oklab(0% 0.365 -0.16) r g b)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(19, 0, 24). 44 test_computed_value(`color`, `rgb(from oklch(100% 0.399 336.3) r g b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). 45 test_computed_value(`color`, `rgb(from oklch(0% 0.399 336.3) r g b)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(20, 0, 24). 38 46 39 47 // Testing replacement with 0. … … 132 140 test_computed_value(`color`, `hsl(from hsl(from rebeccapurple h s l) h s l)`, `rgb(102, 51, 153)`); 133 141 134 // Testing non-sRGB origin colors to see gamut clipping. 135 test_computed_value(`color`, `hsl(from color(display-p3 0 1 0) h s l / alpha)`, `rgb(0, 255, 0)`); 142 // Testing non-sRGB origin colors to see gamut mapping. 143 test_computed_value(`color`, `hsl(from color(display-p3 0 1 0) h s l / alpha)`, `rgb(0, 249, 66)`); // Naive clip based mapping would give rgb(0, 255, 0). 144 test_computed_value(`color`, `hsl(from lab(100% 104.3 -50.9) h s l)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). 145 test_computed_value(`color`, `hsl(from lab(0% 104.3 -50.9) h s l)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, 146 test_computed_value(`color`, `hsl(from lch(100% 116 334) h s l)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). 147 test_computed_value(`color`, `hsl(from lch(0% 116 334) h s l)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, 148 test_computed_value(`color`, `hsl(from oklab(100% 0.365 -0.16) h s l)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). 149 test_computed_value(`color`, `hsl(from oklab(0% 0.365 -0.16) h s l)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(19, 0, 24). 150 test_computed_value(`color`, `hsl(from oklch(100% 0.399 336.3) h s l)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). 151 test_computed_value(`color`, `hsl(from oklch(0% 0.399 336.3) h s l)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(20, 0, 24). 136 152 137 153 // Testing replacement with 0. … … 205 221 test_computed_value(`color`, `hwb(from hwb(from rebeccapurple h w b) h w b)`, `rgb(102, 51, 153)`); 206 222 207 // Testing non-sRGB origin colors to see gamut clipping. 208 test_computed_value(`color`, `hwb(from color(display-p3 0 1 0) h w b / alpha)`, `rgb(0, 255, 0)`); 223 // Testing non-sRGB origin colors to see gamut mapping. 224 test_computed_value(`color`, `hwb(from color(display-p3 0 1 0) h w b / alpha)`, `rgb(0, 249, 66)`); // Naive clip based mapping would give rgb(0, 255, 0). 225 test_computed_value(`color`, `hwb(from lab(100% 104.3 -50.9) h w b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). 226 test_computed_value(`color`, `hwb(from lab(0% 104.3 -50.9) h w b)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, 227 test_computed_value(`color`, `hwb(from lch(100% 116 334) h w b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). 228 test_computed_value(`color`, `hwb(from lch(0% 116 334) h w b)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, 229 test_computed_value(`color`, `hwb(from oklab(100% 0.365 -0.16) h w b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). 230 test_computed_value(`color`, `hwb(from oklab(0% 0.365 -0.16) h w b)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(19, 0, 24). 231 test_computed_value(`color`, `hwb(from oklch(100% 0.399 336.3) h w b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). 232 test_computed_value(`color`, `hwb(from oklch(0% 0.399 336.3) h w b)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(20, 0, 24). 209 233 210 234 // Testing replacement with 0. … … 343 367 test_computed_value(`color`, `${colorSpace}(from ${colorSpace}(from ${colorSpace}(70% 45 30) l c h) l c h)`, `${colorSpace}(70% 45 30)`); 344 368 345 // Testing non-sRGB origin colors to see gamut clipping.369 // Testing non-sRGB origin colors (no gamut mapping will happen since the destination is not a bounded RGB color space). 346 370 test_computed_value(`color`, `${colorSpace}(from color(display-p3 0 0 0) l c h / alpha)`, `${colorSpace}(0% 0 0)`); 347 371 test_computed_value(`color`, `${colorSpace}(from ${rectangularForm}(70% 45 30) l c h / alpha)`, `${colorSpace}(70% 54.08327 33.690067)`); -
trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/relative-color-valid-expected.txt
r288143 r289396 6 6 PASS e.style['color'] = "rgb(from rgb(from rebeccapurple r g b) r g b)" should set the property value 7 7 PASS e.style['color'] = "rgb(from color(display-p3 0 1 0) r g b / alpha)" should set the property value 8 PASS e.style['color'] = "rgb(from lab(100% 104.3 -50.9) r g b)" should set the property value 9 PASS e.style['color'] = "rgb(from lab(0% 104.3 -50.9) r g b)" should set the property value 10 PASS e.style['color'] = "rgb(from lch(100% 116 334) r g b)" should set the property value 11 PASS e.style['color'] = "rgb(from lch(0% 116 334) r g b)" should set the property value 12 PASS e.style['color'] = "rgb(from oklab(100% 0.365 -0.16) r g b)" should set the property value 13 PASS e.style['color'] = "rgb(from oklab(0% 0.365 -0.16) r g b)" should set the property value 14 PASS e.style['color'] = "rgb(from oklch(100% 0.399 336.3) r g b)" should set the property value 15 PASS e.style['color'] = "rgb(from oklch(0% 0.399 336.3) r g b)" should set the property value 8 16 PASS e.style['color'] = "rgb(from rebeccapurple 0 0 0)" should set the property value 9 17 PASS e.style['color'] = "rgb(from rebeccapurple 0 0 0 / 0)" should set the property value … … 75 83 PASS e.style['color'] = "hsl(from hsl(from rebeccapurple h s l) h s l)" should set the property value 76 84 PASS e.style['color'] = "hsl(from color(display-p3 0 1 0) h s l / alpha)" should set the property value 85 PASS e.style['color'] = "hsl(from lab(100% 104.3 -50.9) h s l)" should set the property value 86 PASS e.style['color'] = "hsl(from lab(0% 104.3 -50.9) h s l)" should set the property value 87 PASS e.style['color'] = "hsl(from lch(100% 116 334) h s l)" should set the property value 88 PASS e.style['color'] = "hsl(from lch(0% 116 334) h s l)" should set the property value 89 PASS e.style['color'] = "hsl(from oklab(100% 0.365 -0.16) h s l)" should set the property value 90 PASS e.style['color'] = "hsl(from oklab(0% 0.365 -0.16) h s l)" should set the property value 91 PASS e.style['color'] = "hsl(from oklch(100% 0.399 336.3) h s l)" should set the property value 92 PASS e.style['color'] = "hsl(from oklch(0% 0.399 336.3) h s l)" should set the property value 77 93 PASS e.style['color'] = "hsl(from rebeccapurple 0 0% 0%)" should set the property value 78 94 PASS e.style['color'] = "hsl(from rebeccapurple 0deg 0% 0%)" should set the property value … … 129 145 PASS e.style['color'] = "hwb(from hwb(from rebeccapurple h w b) h w b)" should set the property value 130 146 PASS e.style['color'] = "hwb(from color(display-p3 0 1 0) h w b / alpha)" should set the property value 147 PASS e.style['color'] = "hwb(from lab(100% 104.3 -50.9) h w b)" should set the property value 148 PASS e.style['color'] = "hwb(from lab(0% 104.3 -50.9) h w b)" should set the property value 149 PASS e.style['color'] = "hwb(from lch(100% 116 334) h w b)" should set the property value 150 PASS e.style['color'] = "hwb(from lch(0% 116 334) h w b)" should set the property value 151 PASS e.style['color'] = "hwb(from oklab(100% 0.365 -0.16) h w b)" should set the property value 152 PASS e.style['color'] = "hwb(from oklab(0% 0.365 -0.16) h w b)" should set the property value 153 PASS e.style['color'] = "hwb(from oklch(100% 0.399 336.3) h w b)" should set the property value 154 PASS e.style['color'] = "hwb(from oklch(0% 0.399 336.3) h w b)" should set the property value 131 155 PASS e.style['color'] = "hwb(from rebeccapurple 0 0% 0%)" should set the property value 132 156 PASS e.style['color'] = "hwb(from rebeccapurple 0deg 0% 0%)" should set the property value -
trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/relative-color-valid.html
r289194 r289396 33 33 test_valid_value(`color`, `rgb(from rgb(from rebeccapurple r g b) r g b)`, `rgb(102, 51, 153)`); 34 34 35 // Testing non-sRGB origin colors to see gamut clipping. 36 test_valid_value(`color`, `rgb(from color(display-p3 0 1 0) r g b / alpha)`, `rgb(0, 255, 0)`); 35 // Testing non-sRGB origin colors to see gamut mapping. 36 test_valid_value(`color`, `rgb(from color(display-p3 0 1 0) r g b / alpha)`, `rgb(0, 249, 66)`); // Naive clip based mapping would give rgb(0, 255, 0). 37 test_valid_value(`color`, `rgb(from lab(100% 104.3 -50.9) r g b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). 38 test_valid_value(`color`, `rgb(from lab(0% 104.3 -50.9) r g b)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, 39 test_valid_value(`color`, `rgb(from lch(100% 116 334) r g b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). 40 test_valid_value(`color`, `rgb(from lch(0% 116 334) r g b)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, 41 test_valid_value(`color`, `rgb(from oklab(100% 0.365 -0.16) r g b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). 42 test_valid_value(`color`, `rgb(from oklab(0% 0.365 -0.16) r g b)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(19, 0, 24). 43 test_valid_value(`color`, `rgb(from oklch(100% 0.399 336.3) r g b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). 44 test_valid_value(`color`, `rgb(from oklch(0% 0.399 336.3) r g b)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(20, 0, 24). 37 45 38 46 // Testing replacement with 0. … … 131 139 test_valid_value(`color`, `hsl(from hsl(from rebeccapurple h s l) h s l)`, `rgb(102, 51, 153)`); 132 140 133 // Testing non-sRGB origin colors to see gamut clipping. 134 test_valid_value(`color`, `hsl(from color(display-p3 0 1 0) h s l / alpha)`, `rgb(0, 255, 0)`); 141 // Testing non-sRGB origin colors to see gamut mapping. 142 test_valid_value(`color`, `hsl(from color(display-p3 0 1 0) h s l / alpha)`, `rgb(0, 249, 66)`); // Naive clip based mapping would give rgb(0, 255, 0). 143 test_valid_value(`color`, `hsl(from lab(100% 104.3 -50.9) h s l)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). 144 test_valid_value(`color`, `hsl(from lab(0% 104.3 -50.9) h s l)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, 145 test_valid_value(`color`, `hsl(from lch(100% 116 334) h s l)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). 146 test_valid_value(`color`, `hsl(from lch(0% 116 334) h s l)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, 147 test_valid_value(`color`, `hsl(from oklab(100% 0.365 -0.16) h s l)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). 148 test_valid_value(`color`, `hsl(from oklab(0% 0.365 -0.16) h s l)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(19, 0, 24). 149 test_valid_value(`color`, `hsl(from oklch(100% 0.399 336.3) h s l)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). 150 test_valid_value(`color`, `hsl(from oklch(0% 0.399 336.3) h s l)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(20, 0, 24). 135 151 136 152 // Testing replacement with 0. … … 204 220 test_valid_value(`color`, `hwb(from hwb(from rebeccapurple h w b) h w b)`, `rgb(102, 51, 153)`); 205 221 206 // Testing non-sRGB origin colors to see gamut clipping. 207 test_valid_value(`color`, `hwb(from color(display-p3 0 1 0) h w b / alpha)`, `rgb(0, 255, 0)`); 222 // Testing non-sRGB origin colors to see gamut mapping. 223 test_valid_value(`color`, `hwb(from color(display-p3 0 1 0) h w b / alpha)`, `rgb(0, 249, 66)`); // Naive clip based mapping would give rgb(0, 255, 0). 224 test_valid_value(`color`, `hwb(from lab(100% 104.3 -50.9) h w b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). 225 test_valid_value(`color`, `hwb(from lab(0% 104.3 -50.9) h w b)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, 226 test_valid_value(`color`, `hwb(from lch(100% 116 334) h w b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 150, 255). 227 test_valid_value(`color`, `hwb(from lch(0% 116 334) h w b)`, `rgb(42, 0, 34)`); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black, 228 test_valid_value(`color`, `hwb(from oklab(100% 0.365 -0.16) h w b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 92, 255). 229 test_valid_value(`color`, `hwb(from oklab(0% 0.365 -0.16) h w b)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(19, 0, 24). 230 test_valid_value(`color`, `hwb(from oklch(100% 0.399 336.3) h w b)`, `rgb(255, 255, 255)`); // Naive clip based mapping would give rgb(255, 91, 255). 231 test_valid_value(`color`, `hwb(from oklch(0% 0.399 336.3) h w b)`, `rgb(0, 0, 0)`); // Naive clip based mapping would give rgb(20, 0, 24). 208 232 209 233 // Testing replacement with 0. … … 342 366 test_valid_value(`color`, `${colorSpace}(from ${colorSpace}(from ${colorSpace}(70% 45 30) l c h) l c h)`, `${colorSpace}(70% 45 30)`); 343 367 344 // Testing non-sRGB origin colors to see gamut clipping.368 // Testing non-sRGB origin colors (no gamut mapping will happen since the destination is not a bounded RGB color space). 345 369 test_valid_value(`color`, `${colorSpace}(from color(display-p3 0 0 0) l c h / alpha)`, `${colorSpace}(0% 0 0)`); 346 370 test_valid_value(`color`, `${colorSpace}(from ${rectangularForm}(70% 45 30) l c h / alpha)`, `${colorSpace}(70% 54.08327 33.690067)`); -
trunk/LayoutTests/platform/gtk/TestExpectations
r289381 r289396 1839 1839 webkit.org/b/230277 imported/w3c/web-platform-tests/css/css-transforms/3dtransform-and-filter-no-perspective-001.html [ ImageOnlyFailure ] 1840 1840 1841 webkit.org/b/234726 imported/w3c/web-platform-tests/css/css-color/color-mix-non-srgb-001.html [ Failure ] 1841 1842 webkit.org/b/234726 imported/w3c/web-platform-tests/css/css-color/parsing/relative-color-computed.html [ Failure ] 1842 1843 webkit.org/b/234726 imported/w3c/web-platform-tests/css/css-color/parsing/relative-color-valid.html [ Failure ] 1844 webkit.org/b/234726 imported/w3c/web-platform-tests/css/css-color/parsing/color-mix-computed.html [ Failure ] 1845 webkit.org/b/234726 imported/w3c/web-platform-tests/css/css-color/parsing/color-mix-valid.html [ Failure ] 1843 1846 1844 1847 webkit.org/b/234782 imported/w3c/web-platform-tests/css/css-writing-modes/text-shadow-orientation-upright-001.html [ ImageOnlyFailure ] -
trunk/Source/WebCore/ChangeLog
r289383 r289396 1 2022-02-08 Sam Weinig <weinig@apple.com> 2 3 Conversion to a color space with a smaller gamut should perform gamut mapping 4 https://bugs.webkit.org/show_bug.cgi?id=236200 5 6 Reviewed by Darin Adler. 7 8 CSS Color now defines that gamut mapping should happen when converting to an RGB color space 9 with bounded gamut that is smaller than the origin color's color space. Specifically, it 10 specifies the use of a new "CSS gamut mapping algorithm" https://drafts.csswg.org/css-color/#css-gamut-mapping 11 which implements a relative colorimetric intent mapping with colors inside the destination 12 gamut unchanged. 13 14 The previous behavior we implemented was to clip out of gamut colors to the gamut (e.g. 15 color(srgb 1.4 -0.2 .5) would become color(srgb 1 0 .5)) which can lead to very odd results. 16 17 To keep things simple, the gamut mapping has been incorporated directly into the main color 18 conversion pipeline, replacing the call to makeFromComponentsClampingExceptAlpha in toBounded() 19 with one implements the new algorithm. To accomadate this, the pipeline was modified so that 20 the matrix conversions now only happen to/from extended-linear and XYZ color types, rather than 21 the old behavior which allowed shortcuting from bounded-linear, which was ok because the clip 22 would result in the same value. Since conversion from bounded-linear to extended-linear is free 23 (just a type change, no conversion), the only additional cost here is the gamut mapping. 24 25 The implementation of the CSS gamut mapping algorithm itself is a naive iterative bisection 26 implementation based on the psuedo-code from the spec. As an optimization in the future, we should 27 consider implementing an analytic solution, which will be more complicated, but likely faster. 28 29 Currently, the only place where the effect of this new gamut mapping behavior will be visible is 30 via functions that explicitly convert to a bounded color space, specifically the CSS color-mix() 31 function and relative color syntax. Ultimately, we should also be using this to map CSS colors 32 to the output color space of the screen / HTML canvas, but finding the right place to do that 33 is not a part of this initial change. 34 35 * platform/graphics/ColorConversion.cpp: 36 (WebCore::ColorConversion<Lab<float>, XYZA<float, WhitePoint::D50>>::convert): 37 (WebCore::ColorConversion<OKLab<float>, XYZA<float, WhitePoint::D65>>::convert): 38 Add call to makeFromComponentsClampingExceptAlpha at the end of conversion to Lab/OKLab 39 as the conversion functions can produce lightness values just ever so less than 0. 40 In practice, only the lightness value is bounded, so it is the only thing that actually 41 gets clamped thanks to the constexpr nature of clampedComponent(). 42 43 * platform/graphics/ColorConversion.h: 44 (WebCore::computeDeltaEOK): 45 Add implementation of the deltaEOK algorithm. 46 47 (WebCore::ClipGamutMapping::mapToBoundedGamut): 48 Add implementation of the degenerate gamut mapping algorithm. 49 50 (WebCore::CSSGamutMapping::mapToBoundedGamut): 51 Add implementation of the CSS gamut mapping algorithm. 52 53 (WebCore::ColorConversion::convert): 54 Add a new step to the main pipeline that explicitly handles bounds conversions to/from 55 extended-linear so that the matrix conversions can rely on always working in extended space. 56 57 (WebCore::ColorConversion::toBounded): 58 Replace call to clamp with call out to gamut mapping algorithm. 59 60 (WebCore::ColorConversion::handleMatrixConversion): 61 Replace makeFromComponentsClampingExceptAlpha with makeFromComponents now that all conversions 62 are in the extended space and clamping is no-op. 63 64 * platform/graphics/ColorTypes.h: 65 (WebCore::inGamut): 66 (WebCore::colorIfInGamut): 67 (WebCore::clipToGamut): 68 Add some helpers to check/convert/clip to the bounded gamut of RGB types. 69 1 70 2022-02-07 Yusuke Suzuki <ysuzuki@apple.com> 2 71 -
trunk/Source/WebCore/platform/graphics/ColorConversion.cpp
r287552 r289396 45 45 float chroma = std::hypot(a, b); 46 46 47 return { lightness, chroma, hue >= 0 ? hue : hue + 360, alpha };47 return { lightness, chroma, hue >= 0.0f ? hue : hue + 360.0f, alpha }; 48 48 } 49 49 … … 273 273 float b = 200.0f * (f1 - f2); 274 274 275 return { lightness, a, b, alpha };275 return makeFromComponentsClampingExceptAlpha<Lab<float>>(lightness, a, b, alpha); 276 276 } 277 277 … … 359 359 360 360 // 4. Transform lightness from unit lightness to percentage lightness. 361 return { lightness * 100.0f, a, b, alpha };361 return makeFromComponentsClampingExceptAlpha<OKLab<float>>(lightness * 100.0f, a, b, alpha); 362 362 } 363 363 -
trunk/Source/WebCore/platform/graphics/ColorConversion.h
r287552 r289396 1 1 /* 2 * Copyright (C) 2017-202 1Apple Inc. All rights reserved.2 * Copyright (C) 2017-2022 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 27 27 28 28 #include "ColorTypes.h" 29 #include <wtf/MathExtras.h> 29 30 30 31 namespace WebCore { … … 140 141 }; 141 142 143 // MARK: DeltaE color difference algorithms. 144 145 template<typename ColorType1, typename ColorType2> inline constexpr float computeDeltaEOK(ColorType1 color1, ColorType2 color2) 146 { 147 // https://drafts.csswg.org/css-color/#color-difference-OK 148 149 auto [L1, a1, b1, alpha1] = convertColor<OKLab<float>>(color1).resolved(); 150 auto [L2, a2, b2, alpha2] = convertColor<OKLab<float>>(color2).resolved(); 151 152 auto deltaL = (L1 / 100.0f) - (L2 / 100.0f); 153 auto deltaA = a1 - a2; 154 auto deltaB = b1 - b2; 155 156 return std::hypot(deltaL, deltaA, deltaB); 157 } 158 159 // MARK: Gamut mapping algorithms. 160 161 struct ClipGamutMapping { 162 template<typename ColorType> static auto mapToBoundedGamut(const ColorType& color) -> typename ColorType::BoundedCounterpart 163 { 164 return clipToGamut<typename ColorType::BoundedCounterpart>(color); 165 } 166 }; 167 168 struct CSSGamutMapping { 169 // This implements the CSS gamut mapping algorithm (https://drafts.csswg.org/css-color/#css-gamut-mapping) for RGB 170 // colors that are out of gamut for a particular RGB color space. It implements a relative colorimetric intent mapping 171 // for colors that are outside the destionation gamut and leaves colors inside the destination gamut unchanged. 172 173 // A simple optimization over the psuedocode in the specification has been made to avoid unnecessary work in the 174 // main bisection loop by checking the gamut using the extended linear color space of the RGB family regardless of 175 // of whether the final type is gamma encoded or not. This avoids unnecessary gamma encoding for non final loops. 176 177 // FIXME: This is a naive iterative solution that works for any bounded RGB color space. This can be optimized by 178 // using an analytical solution that computes the exact intersection. 179 180 static constexpr float JND = 0.02f; 181 182 template<typename ColorType> static auto mapToBoundedGamut(const ColorType& color) -> typename ColorType::BoundedCounterpart 183 { 184 using BoundedColorType = typename ColorType::BoundedCounterpart; 185 using ExtendedLinearColorType = ExtendedLinearEncoded<typename BoundedColorType::ComponentType, typename BoundedColorType::Descriptor>; 186 using BoundedLinearColorType = BoundedLinearEncoded<typename BoundedColorType::ComponentType, typename BoundedColorType::Descriptor>; 187 188 auto resolvedColor = color.resolved(); 189 190 if (auto result = colorIfInGamut<BoundedColorType>(resolvedColor)) 191 return *result; 192 193 auto colorInOKLCHColorSpace = convertColor<OKLCHA<float>>(resolvedColor).resolved(); 194 195 if (WTF::areEssentiallyEqual(colorInOKLCHColorSpace.lightness, 100.0f) || colorInOKLCHColorSpace.lightness > 100.0f) 196 return { 1.0, 1.0, 1.0, resolvedColor.alpha }; 197 else if (WTF::areEssentiallyEqual(colorInOKLCHColorSpace.lightness, 0.0f)) 198 return { 0.0f, 0.0f, 0.0f, resolvedColor.alpha }; 199 200 float min = 0.0f; 201 float max = colorInOKLCHColorSpace.chroma; 202 203 while (true) { 204 auto chroma = (min + max) / 2.0f; 205 206 auto current = colorInOKLCHColorSpace; 207 current.chroma = chroma; 208 209 auto currentInExtendedLinearColorSpace = convertColor<ExtendedLinearColorType>(current).resolved(); 210 211 if (inGamut<BoundedLinearColorType>(currentInExtendedLinearColorSpace)) { 212 min = chroma; 213 continue; 214 } 215 216 auto currentClippedToBoundedLinearColorSpace = clipToGamut<BoundedLinearColorType>(currentInExtendedLinearColorSpace); 217 218 auto deltaE = computeDeltaEOK(currentClippedToBoundedLinearColorSpace, current); 219 if (deltaE < JND) 220 return convertColor<BoundedColorType>(currentClippedToBoundedLinearColorSpace); 221 222 max = chroma; 223 } 224 } 225 }; 142 226 143 227 // Main conversion. … … 153 237 // │ │ │ │ │ │ │ │ │ │ 154 238 // │ ProPhotoRGB───────────────────┐ │ SRGB──────────────────────────┐ DisplayP3─────────────────────┐ A98RGB────────────────────────┐ Rec2020───────────────────────┐ │ 155 // │ │ │┌────────┐ ┌────────────────┐│ │ │┌────────┐ ┌────────────────┐│ │┌────────┐ ┌────────────────┐│ │┌────────┐ ┌────────────────┐│ │┌────────┐ ┌────────────────┐│ │ │ 156 // │ ││ Linear │ │ LinearExtended ││ │ ││ Linear │ │ LinearExtended ││ ││ Linear │ │ LinearExtended ││ ││ Linear │ │ LinearExtended ││ ││ Linear │ │ LinearExtended ││ │ 157 // │ │ │└────────┘ └────────────────┘│ │ │└────────┘ └────────────────┘│ │└────────┘ └────────────────┘│ │└────────┘ └────────────────┘│ │└────────┘ └────────────────┘│ │ │ 158 // │ ─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─ ─│─ ─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─ │ 239 // │ │ │ ┌────────────────┐│ │ │ ┌────────────────┐│ │ ┌────────────────┐│ │ ┌────────────────┐│ │ ┌────────────────┐│ │ │ 240 // │ │ ┌─────▶︎ LinearExtended ││ │ │ ┌─────▶︎ LinearExtended ││ │ ┌─────▶︎ LinearExtended ││ │ ┌─────▶︎ LinearExtended ││ │ ┌─────▶︎ LinearExtended ││ │ 241 // │ │ │ │ └────────▲───────┘│ │ │ │ └────────▲───────┘│ │ │ └────────▲───────┘│ │ │ └────────▲───────┘│ │ │ └────────▲───────┘│ │ │ 242 // │ ─│─ ─ ─│─ ─ ─ ─ ─ ─ ─ ┼ ─ ─ ─ ─│─ ─│─ ─│─ ─ ─│─ ─ ─ ─ ─ ─ ─ ┼ ─ ─ ─ ─│─│─ ─ ─│─ ─ ─ ─ ─ ─ ─ ┼ ─ ─ ─ ─│─│─ ─ ─│─ ─ ─ ─ ─ ─ ─ ┼ ─ ─ ─ ─│─│─ ─ ─│─ ─ ─ ─ ─ ─ ─ ┼ ─ ─ ─ ─│─ │ 243 // │ │┌────────┐ │ │ │ │┌────────┐ │ │ │┌────────┐ │ │ │┌────────┐ │ │ │┌────────┐ │ │ │ 244 // │ ││ Linear │ │ │ │ ││ Linear │ │ │ ││ Linear │ │ │ ││ Linear │ │ │ ││ Linear │ │ │ │ 245 // │ │└────▲───┘ │ │ │ │└────▲───┘ │ │ │└────▲───┘ │ │ │└────▲───┘ │ │ │└────▲───┘ │ │ │ 246 // │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 159 247 // ┌───────────┐ │┌────────┐ ┌────────────────┐│ │ │┌────────┐ ┌────────────────┐│ │┌────────┐ ┌────────────────┐│ │┌────────┐ ┌────────────────┐│ │┌────────┐ ┌────────────────┐│ ┌───────────┐ 160 // │ Lab │ ││ Gamma │ │ GammaExtended ││ │ ││ Gamma │ │ GammaExtended ││ ││ Gamma │ │ GammaExtended ││ ││ Gamma │ │ GammaExtended ││ ││ Gamma ││ GammaExtended ││ │ OKLab │248 // │ Lab │ ││ Gamma │─│ GammaExtended ││ │ ││ Gamma │─│ GammaExtended ││ ││ Gamma │─│ GammaExtended ││ ││ Gamma │─│ GammaExtended ││ ││ Gamma │─│ GammaExtended ││ │ OKLab │ 161 249 // └─────▲─────┘ │└────────┘ └────────────────┘│ │ │└────▲───┘ └────────────────┘│ │└────────┘ └────────────────┘│ │└────────┘ └────────────────┘│ │└────────┘ └────────────────┘│ └─────▲─────┘ 162 250 // │ └─────────────────────────────┘ │ └─────┼───────────────────────┘ └─────────────────────────────┘ └─────────────────────────────┘ └─────────────────────────────┘ │ … … 196 284 return convertColor<Output>(convertColor<typename Output::LinearCounterpart>(color)); 197 285 198 // 5. At this point, Input and Output are each either Linear-RGB types (of different familes) or XYZA 286 // 5. Handle any bounds conversions for the Input and Output. 287 else if constexpr (IsRGBBoundedType<Input>) 288 return convertColor<Output>(convertColor<typename Input::ExtendedCounterpart>(color)); 289 else if constexpr (IsRGBBoundedType<Output>) 290 return convertColor<Output>(convertColor<typename Output::ExtendedCounterpart>(color)); 291 292 // 6. At this point, Input and Output are each either ExtendedLinear-RGB types (of different familes) or XYZA 199 293 // and therefore all additional conversion can happen via matrix transformation. 200 294 else … … 244 338 template<typename ColorType> static inline constexpr auto toBounded(const ColorType& color) -> typename ColorType::BoundedCounterpart 245 339 { 246 return makeFromComponentsClampingExceptAlpha<typename ColorType::BoundedCounterpart>(asColorComponents(color.resolved()));340 return CSSGamutMapping::mapToBoundedGamut(color); 247 341 } 248 342 … … 252 346 253 347 // RGB Family────────────────────┐ 348 // │ ┌────────────────┐│ 349 // │ ┌─────▶︎ LinearExtended ││ 350 // │ │ └────────▲───────┘│ 351 // │ │ │ │ 352 // │┌────────┐ │ │ 353 // ││ Linear │ │ │ 354 // │└────▲───┘ │ │ 355 // │ │ │ │ 254 356 // │┌────────┐ ┌────────────────┐│ 255 // ││ Linear │ │ LinearExtended ││ 256 // │└────────┘ └────────────────┘│ 257 // │┌────────┐ ┌────────────────┐│ 258 // ││ Gamma │ │ GammaExtended ││ 357 // ││ Gamma │─│ GammaExtended ││ 259 358 // │└────────┘ └────────────────┘│ 260 359 // └─────────────────────────────┘ … … 286 385 static inline constexpr Output handleMatrixConversion(const Input& color) 287 386 { 288 static_assert( IsRGBLinearEncodedType<Input>|| IsXYZA<Input>);289 static_assert( IsRGBLinearEncodedType<Output>|| IsXYZA<Output>);387 static_assert((IsRGBLinearEncodedType<Input> && IsRGBExtendedType<Input>) || IsXYZA<Input>); 388 static_assert((IsRGBLinearEncodedType<Output> && IsRGBExtendedType<Output>) || IsXYZA<Output>); 290 389 291 390 // ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┼ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ … … 299 398 // │ │ │ │ │ │ │ │ 300 399 // ProPhotoRGB───────────────────┐ │ SRGB──────────────────────────┐ DisplayP3─────────────────────┐ A98RGB────────────────────────┐ Rec2020───────────────────────┐ 301 // │ │ ┌────────┐ ┌────────────────┐│ │ │┌────────┐ ┌────────────────┐│ │┌────────┐ ┌────────────────┐│ │┌────────┐ ┌────────────────┐│ │┌────────┐┌────────────────┐│ │302 // │ │ Linear │ │ LinearExtended ││ │ ││ Linear │ │ LinearExtended ││ ││ Linear │ │ LinearExtended ││ ││ Linear │ │ LinearExtended ││ ││ Linear │ │LinearExtended ││303 // │ │ └────────┘ └────────────────┘│ │ │└────────┘ └────────────────┘│ │└────────┘ └────────────────┘│ │└────────┘ └────────────────┘│ │└────────┘ └────────────────┘│ │304 // ─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─ ─│─ ─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ── ─ ─ ─│─305 306 // This handles conversions between linear color types that can be converted using pre-defined400 // │ │ ┌────────────────┐│ │ │ ┌────────────────┐│ │ ┌────────────────┐│ │ ┌────────────────┐│ │ ┌────────────────┐│ │ 401 // │ ┌─────▶︎ LinearExtended ││ │ │ ┌─────▶︎ LinearExtended ││ │ ┌─────▶︎ LinearExtended ││ │ ┌─────▶︎ LinearExtended ││ │ ┌─────▶︎ LinearExtended ││ 402 // │ │ │ └────────▲───────┘│ │ │ │ └────────▲───────┘│ │ │ └────────▲───────┘│ │ │ └────────▲───────┘│ │ │ └────────▲───────┘│ │ 403 // ─│─ ─ ─│─ ─ ─ ─ ─ ─ ─ ┼ ─ ─ ─ ─│─ ─│─ ─│─ ─ ─│─ ─ ─ ─ ─ ─ ─ ┼ ─ ─ ─ ─│─│─ ─ ─│─ ─ ─ ─ ─ ─ ─ ┼ ─ ─ ─ ─│─│─ ─ ─│─ ─ ─ ─ ─ ─ ─ ┼ ─ ─ ─ ─│─│─ ─ ─│─ ─ ─ ─ ─ ─ ─ ┼ ─ ─ ─ ─│─ 404 405 // This handles conversions between extended linear color types that can be converted using pre-defined 307 406 // 3x3 matrices. 308 407 … … 313 412 314 413 auto applyMatrices = [](const Input& color, auto... matrices) { 315 return makeFromComponents ClampingExceptAlpha<Output>(applyMatricesToColorComponents(asColorComponents(color.resolved()), matrices...));414 return makeFromComponents<Output>(applyMatricesToColorComponents(asColorComponents(color.resolved()), matrices...)); 316 415 }; 317 416 -
trunk/Source/WebCore/platform/graphics/ColorTypes.h
r289122 r289396 30 30 #include "ColorModels.h" 31 31 #include "ColorTransferFunctions.h" 32 #include <optional> 32 33 33 34 namespace WebCore { … … 312 313 template<typename ColorType1, typename ColorType2> inline constexpr bool IsSameRGBTypeFamily = IsSameRGBTypeFamilyValue<ColorType1, ColorType2, IsRGBType<ColorType1> && IsRGBType<ColorType2>>; 313 314 315 template<typename BoundedColorType> constexpr bool inGamut(typename BoundedColorType::ComponentType component) 316 { 317 static_assert(IsRGBBoundedType<BoundedColorType>); 318 319 return component >= 0.0f && component <= 1.0f; 320 } 321 322 template<typename BoundedColorType> constexpr bool inGamut(ColorComponents<typename BoundedColorType::ComponentType, 4> components) 323 { 324 static_assert(IsRGBBoundedType<BoundedColorType>); 325 326 return inGamut<BoundedColorType>(components[0]) && inGamut<BoundedColorType>(components[1]) && inGamut<BoundedColorType>(components[2]); 327 } 328 329 template<typename BoundedColorType, typename ColorType> constexpr bool inGamut(ColorType color) 330 { 331 static_assert(IsRGBBoundedType<BoundedColorType>); 332 static_assert(std::is_same_v<BoundedColorType, typename ColorType::BoundedCounterpart>); 333 334 return inGamut<BoundedColorType>(asColorComponents(color.resolved())); 335 } 336 337 template<typename BoundedColorType, typename ColorType> constexpr std::optional<BoundedColorType> colorIfInGamut(ColorType color) 338 { 339 static_assert(IsRGBBoundedType<BoundedColorType>); 340 static_assert(std::is_same_v<BoundedColorType, typename ColorType::BoundedCounterpart>); 341 342 auto components = asColorComponents(color.resolved()); 343 if (!inGamut<BoundedColorType>(components)) 344 return std::nullopt; 345 return makeFromComponents<BoundedColorType>(components); 346 } 347 348 template<typename BoundedColorType, typename ColorType> constexpr BoundedColorType clipToGamut(ColorType color) 349 { 350 static_assert(IsRGBBoundedType<BoundedColorType>); 351 static_assert(std::is_same_v<BoundedColorType, typename ColorType::BoundedCounterpart>); 352 353 return makeFromComponentsClampingExceptAlpha<BoundedColorType>(asColorComponents(color.resolved())); 354 } 355 314 356 struct SRGBADescriptor { 315 357 template<typename T, TransferFunctionMode Mode> using TransferFunction = SRGBTransferFunction<T, Mode>; -
trunk/Tools/ChangeLog
r289386 r289396 1 2022-02-08 Sam Weinig <weinig@apple.com> 2 3 Conversion to a color space with a smaller gamut should perform gamut mapping 4 https://bugs.webkit.org/show_bug.cgi?id=236200 5 6 Reviewed by Darin Adler. 7 8 * TestWebKitAPI/Tests/WebCore/ColorTests.cpp: 9 (TestWebKitAPI::TEST): 10 Update color conversion tests to account for gamut mapping and add a new test 11 that bypasses gamut mapping by converting to extended sRGB. 12 1 13 2022-02-01 Jonathan Bedard <jbedard@apple.com> 2 14 -
trunk/Tools/TestWebKitAPI/Tests/WebCore/ColorTests.cpp
r287552 r289396 373 373 auto sRGBAColor = p3Color.toColorTypeLossy<SRGBA<float>>().resolved(); 374 374 EXPECT_FLOAT_EQ(sRGBAColor.red, 1.0f); 375 EXPECT_FLOAT_EQ(sRGBAColor.green, 0.50120097f); 376 EXPECT_FLOAT_EQ(sRGBAColor.blue, 0.26161569f); 377 EXPECT_FLOAT_EQ(sRGBAColor.alpha, 0.75f); 378 } 379 380 TEST(Color, P3ConversionToExtendedSRGB) 381 { 382 Color p3Color { DisplayP3<float> { 1.0, 0.5, 0.25, 0.75 } }; 383 auto sRGBAColor = p3Color.toColorTypeLossy<ExtendedSRGBA<float>>().resolved(); 384 EXPECT_FLOAT_EQ(sRGBAColor.red, 1.0740442f); 375 385 EXPECT_FLOAT_EQ(sRGBAColor.green, 0.46253282f); 376 386 EXPECT_FLOAT_EQ(sRGBAColor.blue, 0.14912748f);
Note: See TracChangeset
for help on using the changeset viewer.