Changeset 286191 in webkit
- Timestamp:
- Nov 27, 2021, 12:54:28 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 32 added
- 22 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/fast/css/parsing-color-mix-expected.txt (modified) (2 diffs)
-
LayoutTests/fast/css/parsing-color-mix.html (modified) (1 diff)
-
LayoutTests/fast/css/parsing-lab-colors-expected.txt (modified) (3 diffs)
-
LayoutTests/fast/css/parsing-lab-colors.html (modified) (2 diffs)
-
LayoutTests/fast/css/parsing-relative-color-syntax-expected.txt (modified) (6 diffs)
-
LayoutTests/fast/css/parsing-relative-color-syntax.html (modified) (1 diff)
-
LayoutTests/imported/w3c/ChangeLog (modified) (1 diff)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklab-001-expected.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklab-001.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklab-002-expected.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklab-002.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklab-003-expected.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklab-003.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklab-004-expected.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklab-004.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklab-005-expected.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklab-005.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklab-006-expected.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklab-006.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklab-007-expected.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklab-007.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklab-008-expected.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklab-008.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklch-001-expected.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklch-001.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklch-002-expected.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklch-002.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklch-003-expected.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklch-003.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklch-004-expected.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklch-004.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklch-005-expected.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklch-005.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklch-006-expected.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklch-006.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklch-007-expected.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklch-007.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklch-008-expected.html (added)
-
LayoutTests/imported/w3c/web-platform-tests/css/css-color/oklch-008.html (added)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/css/CSSValueKeywords.in (modified) (2 diffs)
-
Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp (modified) (15 diffs)
-
Source/WebCore/platform/graphics/ColorComponents.h (modified) (1 diff)
-
Source/WebCore/platform/graphics/ColorConversion.cpp (modified) (3 diffs)
-
Source/WebCore/platform/graphics/ColorConversion.h (modified) (2 diffs)
-
Source/WebCore/platform/graphics/ColorMatrix.h (modified) (2 diffs)
-
Source/WebCore/platform/graphics/ColorModels.h (modified) (7 diffs)
-
Source/WebCore/platform/graphics/ColorSerialization.cpp (modified) (6 diffs)
-
Source/WebCore/platform/graphics/ColorSpace.cpp (modified) (2 diffs)
-
Source/WebCore/platform/graphics/ColorSpace.h (modified) (4 diffs)
-
Source/WebCore/platform/graphics/ColorTypes.h (modified) (13 diffs)
-
Source/WebCore/platform/graphics/ColorUtilities.h (modified) (3 diffs)
-
Source/WebCore/platform/graphics/cg/ColorSpaceCG.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r286181 r286191 1 2021-11-27 Sam Weinig <[email protected]> 2 3 [CSS Color 4] Add support for oklab() and oklch() colors 4 https://bugs.webkit.org/show_bug.cgi?id=233507 5 6 Reviewed by Cameron McCormack. 7 8 Update existing tests for lab() and lch() to also test oklab() and oklch(). 9 As they have the same parsing rules, this is mostly done by templatizing 10 the tests and running them in a loop. 11 12 * fast/css/parsing-color-mix-expected.txt: 13 * fast/css/parsing-color-mix.html: 14 * fast/css/parsing-lab-colors-expected.txt: 15 * fast/css/parsing-lab-colors.html: 16 * fast/css/parsing-relative-color-syntax-expected.txt: 17 * fast/css/parsing-relative-color-syntax.html: 18 1 19 2021-11-26 Tim Nguyen <[email protected]> 2 20 -
trunk/LayoutTests/fast/css/parsing-color-mix-expected.txt
r286168 r286191 40 40 PASS computedStyle("background-color", "color-mix(in lch, lch(10% 20 30deg / .4) -10%, lch(50% 60 70deg / .8))") is "lch(54% 64 74 / 0.84000003)" 41 41 42 color-mix(in oklch, ...) 43 PASS computedStyle("background-color", "color-mix(in oklch, oklch(10% 20 30deg / .4), oklch(50% 60 70deg / .8))") is "oklch(30% 40 50 / 0.6)" 44 PASS computedStyle("background-color", "color-mix(in oklch, oklch(10% 20 30deg / .4) 25%, oklch(50% 60 70deg / .8))") is "oklch(40% 50 60 / 0.7)" 45 PASS computedStyle("background-color", "color-mix(in oklch, 25% oklch(10% 20 30deg / .4), oklch(50% 60 70deg / .8))") is "oklch(40% 50 60 / 0.7)" 46 PASS computedStyle("background-color", "color-mix(in oklch, oklch(10% 20 30deg / .4), 25% oklch(50% 60 70deg / .8))") is "oklch(20% 30 40 / 0.5)" 47 PASS computedStyle("background-color", "color-mix(in oklch, oklch(10% 20 30deg / .4), oklch(50% 60 70deg / .8) 25%)") is "oklch(20% 30 40 / 0.5)" 48 PASS computedStyle("background-color", "color-mix(in oklch, oklch(10% 20 30deg / .4) 25%, oklch(50% 60 70deg / .8) 75%)") is "oklch(40% 50 60 / 0.7)" 49 PASS computedStyle("background-color", "color-mix(in oklch, oklch(10% 20 30deg / .4) 50%, oklch(50% 60 70deg / .8) 150%)") is "oklch(40% 50 60 / 0.7)" 50 PASS computedStyle("background-color", "color-mix(in oklch, oklch(10% 20 30deg / .4) 12.5%, oklch(50% 60 70deg / .8) 37.5%)") is "oklch(40% 50 60 / 0.7)" 51 PASS computedStyle("background-color", "color-mix(in oklch, oklch(10% 20 30deg / .4) 0%, oklch(50% 60 70deg / .8))") is "oklch(50% 60 70 / 0.8)" 52 PASS computedStyle("background-color", "color-mix(in oklch, oklch(10% 20 30deg / .4) -10%, oklch(50% 60 70deg / .8))") is "oklch(54% 64 74 / 0.84000003)" 53 42 54 color-mix(in lab, ...) 43 55 PASS computedStyle("background-color", "color-mix(in lab, lab(10% 20 30 / .4), lab(50% 60 70 / .8))") is "lab(30% 40 50 / 0.6)" … … 52 64 PASS computedStyle("background-color", "color-mix(in lab, lab(10% 20 30 / .4) -10%, lab(50% 60 70 / .8))") is "lab(54% 64 74 / 0.84000003)" 53 65 66 color-mix(in oklab, ...) 67 PASS computedStyle("background-color", "color-mix(in oklab, oklab(10% 20 30 / .4), oklab(50% 60 70 / .8))") is "oklab(30% 40 50 / 0.6)" 68 PASS computedStyle("background-color", "color-mix(in oklab, oklab(10% 20 30 / .4) 25%, oklab(50% 60 70 / .8))") is "oklab(40% 50 60 / 0.7)" 69 PASS computedStyle("background-color", "color-mix(in oklab, 25% oklab(10% 20 30 / .4), oklab(50% 60 70 / .8))") is "oklab(40% 50 60 / 0.7)" 70 PASS computedStyle("background-color", "color-mix(in oklab, oklab(10% 20 30 / .4), 25% oklab(50% 60 70 / .8))") is "oklab(20% 30 40 / 0.5)" 71 PASS computedStyle("background-color", "color-mix(in oklab, oklab(10% 20 30 / .4), oklab(50% 60 70 / .8) 25%)") is "oklab(20% 30 40 / 0.5)" 72 PASS computedStyle("background-color", "color-mix(in oklab, oklab(10% 20 30 / .4) 25%, oklab(50% 60 70 / .8) 75%)") is "oklab(40% 50 60 / 0.7)" 73 PASS computedStyle("background-color", "color-mix(in oklab, oklab(10% 20 30 / .4) 50%, oklab(50% 60 70 / .8) 150%)") is "oklab(40% 50 60 / 0.7)" 74 PASS computedStyle("background-color", "color-mix(in oklab, oklab(10% 20 30 / .4) 12.5%, oklab(50% 60 70 / .8) 37.5%)") is "oklab(40% 50 60 / 0.7)" 75 PASS computedStyle("background-color", "color-mix(in oklab, oklab(10% 20 30 / .4) 0%, oklab(50% 60 70 / .8))") is "oklab(50% 60 70 / 0.8)" 76 PASS computedStyle("background-color", "color-mix(in oklab, oklab(10% 20 30 / .4) -10%, oklab(50% 60 70 / .8))") is "oklab(54% 64 74 / 0.84000003)" 77 54 78 color-mix(in srgb, ...) 55 79 PASS computedStyle("background-color", "color-mix(in srgb, color(srgb .1 .2 .3 / .4), color(srgb .5 .6 .7 / .8))") is "color(srgb 0.3 0.4 0.5 / 0.6)" 56 80 PASS computedStyle("background-color", "color-mix(in srgb, color(srgb .1 .2 .3 / .4) 25%, color(srgb .5 .6 .7 / .8))") is "color(srgb 0.4 0.5 0.6 / 0.7)" 57 81 PASS computedStyle("background-color", "color-mix(in srgb, 25% color(srgb .1 .2 .3 / .4), color(srgb .5 .6 .7 / .8))") is "color(srgb 0.4 0.5 0.6 / 0.7)" 82 PASS computedStyle("background-color", "color-mix(in srgb, color(srgb .1 .2 .3 / .4), color(srgb .5 .6 .7 / .8) 25%)") is "color(srgb 0.2 0.3 0.4 / 0.5)" 58 83 PASS computedStyle("background-color", "color-mix(in srgb, color(srgb .1 .2 .3 / .4), 25% color(srgb .5 .6 .7 / .8))") is "color(srgb 0.2 0.3 0.4 / 0.5)" 59 PASS computedStyle("background-color", "color-mix(in srgb, color(srgb .1 .2 .3 / .4), color(srgb .5 .6 .7 / .8) 25%)") is "color(srgb 0.2 0.3 0.4 / 0.5)"60 84 PASS computedStyle("background-color", "color-mix(in srgb, color(srgb .1 .2 .3 / .4) 25%, color(srgb .5 .6 .7 / .8) 75%)") is "color(srgb 0.4 0.5 0.6 / 0.7)" 61 85 PASS computedStyle("background-color", "color-mix(in srgb, color(srgb .1 .2 .3 / .4) 50%, color(srgb .5 .6 .7 / .8) 150%)") is "color(srgb 0.4 0.5 0.6 / 0.7)" -
trunk/LayoutTests/fast/css/parsing-color-mix.html
r286168 r286191 59 59 testComputed(`color-mix(in hwb, hwb(120deg 10% 20%) -10%, hwb(30deg 30% 40%))`, `rgb(148, 105, 82)`); 60 60 61 for (const colorSpace of [ "lch", "oklch" ]) { 62 debug(''); 63 debug(`color-mix(in ${colorSpace}, ...)`); 61 64 62 debug(''); 63 debug('color-mix(in lch, ...)'); 65 testComputed(`color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30deg / .4), ${colorSpace}(50% 60 70deg / .8))`, `${colorSpace}(30% 40 50 / 0.6)`); 66 testComputed(`color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30deg / .4) 25%, ${colorSpace}(50% 60 70deg / .8))`, `${colorSpace}(40% 50 60 / 0.7)`); 67 testComputed(`color-mix(in ${colorSpace}, 25% ${colorSpace}(10% 20 30deg / .4), ${colorSpace}(50% 60 70deg / .8))`, `${colorSpace}(40% 50 60 / 0.7)`); 68 testComputed(`color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30deg / .4), 25% ${colorSpace}(50% 60 70deg / .8))`, `${colorSpace}(20% 30 40 / 0.5)`); 69 testComputed(`color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30deg / .4), ${colorSpace}(50% 60 70deg / .8) 25%)`, `${colorSpace}(20% 30 40 / 0.5)`); 70 testComputed(`color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30deg / .4) 25%, ${colorSpace}(50% 60 70deg / .8) 75%)`, `${colorSpace}(40% 50 60 / 0.7)`); 71 testComputed(`color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30deg / .4) 50%, ${colorSpace}(50% 60 70deg / .8) 150%)`, `${colorSpace}(40% 50 60 / 0.7)`); // Scale down > 100% sum. 72 testComputed(`color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30deg / .4) 12.5%, ${colorSpace}(50% 60 70deg / .8) 37.5%)`, `${colorSpace}(40% 50 60 / 0.7)`); // Scale up < 100% sum. 73 testComputed(`color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30deg / .4) 0%, ${colorSpace}(50% 60 70deg / .8))`, `${colorSpace}(50% 60 70 / 0.8)`); 64 74 65 testComputed(`color-mix(in lch, lch(10% 20 30deg / .4), lch(50% 60 70deg / .8))`, `lch(30% 40 50 / 0.6)`); 66 testComputed(`color-mix(in lch, lch(10% 20 30deg / .4) 25%, lch(50% 60 70deg / .8))`, `lch(40% 50 60 / 0.7)`); 67 testComputed(`color-mix(in lch, 25% lch(10% 20 30deg / .4), lch(50% 60 70deg / .8))`, `lch(40% 50 60 / 0.7)`); 68 testComputed(`color-mix(in lch, lch(10% 20 30deg / .4), 25% lch(50% 60 70deg / .8))`, `lch(20% 30 40 / 0.5)`); 69 testComputed(`color-mix(in lch, lch(10% 20 30deg / .4), lch(50% 60 70deg / .8) 25%)`, `lch(20% 30 40 / 0.5)`); 70 testComputed(`color-mix(in lch, lch(10% 20 30deg / .4) 25%, lch(50% 60 70deg / .8) 75%)`, `lch(40% 50 60 / 0.7)`); 71 testComputed(`color-mix(in lch, lch(10% 20 30deg / .4) 50%, lch(50% 60 70deg / .8) 150%)`, `lch(40% 50 60 / 0.7)`); // Scale down > 100% sum. 72 testComputed(`color-mix(in lch, lch(10% 20 30deg / .4) 12.5%, lch(50% 60 70deg / .8) 37.5%)`, `lch(40% 50 60 / 0.7)`); // Scale up < 100% sum. 73 testComputed(`color-mix(in lch, lch(10% 20 30deg / .4) 0%, lch(50% 60 70deg / .8))`, `lch(50% 60 70 / 0.8)`); 75 // What should happen if you provide a negative percent? https://github.com/w3c/csswg-drafts/issues/6047 76 testComputed(`color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30deg / .4) -10%, ${colorSpace}(50% 60 70deg / .8))`, `${colorSpace}(54% 64 74 / 0.84000003)`); 77 } 74 78 75 // What should happen if you provide a negative percent? https://github.com/w3c/csswg-drafts/issues/6047 76 testComputed(`color-mix(in lch, lch(10% 20 30deg / .4) -10%, lch(50% 60 70deg / .8))`, `lch(54% 64 74 / 0.84000003)`); 79 for (const colorSpace of [ "lab", "oklab" ]) { 80 debug(''); 81 debug(`color-mix(in ${colorSpace}, ...)`); 77 82 83 testComputed(`color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30 / .4), ${colorSpace}(50% 60 70 / .8))`, `${colorSpace}(30% 40 50 / 0.6)`); 84 testComputed(`color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30 / .4) 25%, ${colorSpace}(50% 60 70 / .8))`, `${colorSpace}(40% 50 60 / 0.7)`); 85 testComputed(`color-mix(in ${colorSpace}, 25% ${colorSpace}(10% 20 30 / .4), ${colorSpace}(50% 60 70 / .8))`, `${colorSpace}(40% 50 60 / 0.7)`); 86 testComputed(`color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30 / .4), 25% ${colorSpace}(50% 60 70 / .8))`, `${colorSpace}(20% 30 40 / 0.5)`); 87 testComputed(`color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30 / .4), ${colorSpace}(50% 60 70 / .8) 25%)`, `${colorSpace}(20% 30 40 / 0.5)`); 88 testComputed(`color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30 / .4) 25%, ${colorSpace}(50% 60 70 / .8) 75%)`, `${colorSpace}(40% 50 60 / 0.7)`); 89 testComputed(`color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30 / .4) 50%, ${colorSpace}(50% 60 70 / .8) 150%)`, `${colorSpace}(40% 50 60 / 0.7)`); // Scale down > 100% sum. 90 testComputed(`color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30 / .4) 12.5%, ${colorSpace}(50% 60 70 / .8) 37.5%)`, `${colorSpace}(40% 50 60 / 0.7)`); // Scale up < 100% sum. 91 testComputed(`color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30 / .4) 0%, ${colorSpace}(50% 60 70 / .8))`, `${colorSpace}(50% 60 70 / 0.8)`); 78 92 79 debug(''); 80 debug('color-mix(in lab, ...)'); 81 82 testComputed(`color-mix(in lab, lab(10% 20 30 / .4), lab(50% 60 70 / .8))`, `lab(30% 40 50 / 0.6)`); 83 testComputed(`color-mix(in lab, lab(10% 20 30 / .4) 25%, lab(50% 60 70 / .8))`, `lab(40% 50 60 / 0.7)`); 84 testComputed(`color-mix(in lab, 25% lab(10% 20 30 / .4), lab(50% 60 70 / .8))`, `lab(40% 50 60 / 0.7)`); 85 testComputed(`color-mix(in lab, lab(10% 20 30 / .4), 25% lab(50% 60 70 / .8))`, `lab(20% 30 40 / 0.5)`); 86 testComputed(`color-mix(in lab, lab(10% 20 30 / .4), lab(50% 60 70 / .8) 25%)`, `lab(20% 30 40 / 0.5)`); 87 testComputed(`color-mix(in lab, lab(10% 20 30 / .4) 25%, lab(50% 60 70 / .8) 75%)`, `lab(40% 50 60 / 0.7)`); 88 testComputed(`color-mix(in lab, lab(10% 20 30 / .4) 50%, lab(50% 60 70 / .8) 150%)`, `lab(40% 50 60 / 0.7)`); // Scale down > 100% sum. 89 testComputed(`color-mix(in lab, lab(10% 20 30 / .4) 12.5%, lab(50% 60 70 / .8) 37.5%)`, `lab(40% 50 60 / 0.7)`); // Scale up < 100% sum. 90 testComputed(`color-mix(in lab, lab(10% 20 30 / .4) 0%, lab(50% 60 70 / .8))`, `lab(50% 60 70 / 0.8)`); 91 92 // What should happen if you provide a negative percent? https://github.com/w3c/csswg-drafts/issues/6047 93 testComputed(`color-mix(in lab, lab(10% 20 30 / .4) -10%, lab(50% 60 70 / .8))`, `lab(54% 64 74 / 0.84000003)`); 93 // What should happen if you provide a negative percent? https://github.com/w3c/csswg-drafts/issues/6047 94 testComputed(`color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30 / .4) -10%, ${colorSpace}(50% 60 70 / .8))`, `${colorSpace}(54% 64 74 / 0.84000003)`); 95 } 94 96 95 debug(''); 96 debug('color-mix(in srgb, ...)'); 97 98 testComputed(`color-mix(in srgb, color(srgb .1 .2 .3 / .4), color(srgb .5 .6 .7 / .8))`, `color(srgb 0.3 0.4 0.5 / 0.6)`); 99 testComputed(`color-mix(in srgb, color(srgb .1 .2 .3 / .4) 25%, color(srgb .5 .6 .7 / .8))`, `color(srgb 0.4 0.5 0.6 / 0.7)`); 100 testComputed(`color-mix(in srgb, 25% color(srgb .1 .2 .3 / .4), color(srgb .5 .6 .7 / .8))`, `color(srgb 0.4 0.5 0.6 / 0.7)`); 101 testComputed(`color-mix(in srgb, color(srgb .1 .2 .3 / .4), 25% color(srgb .5 .6 .7 / .8))`, `color(srgb 0.2 0.3 0.4 / 0.5)`); 102 testComputed(`color-mix(in srgb, color(srgb .1 .2 .3 / .4), color(srgb .5 .6 .7 / .8) 25%)`, `color(srgb 0.2 0.3 0.4 / 0.5)`); 103 testComputed(`color-mix(in srgb, color(srgb .1 .2 .3 / .4) 25%, color(srgb .5 .6 .7 / .8) 75%)`, `color(srgb 0.4 0.5 0.6 / 0.7)`); 104 testComputed(`color-mix(in srgb, color(srgb .1 .2 .3 / .4) 50%, color(srgb .5 .6 .7 / .8) 150%)`, `color(srgb 0.4 0.5 0.6 / 0.7)`); // Scale down > 100% sum. 105 testComputed(`color-mix(in srgb, color(srgb .1 .2 .3 / .4) 12.5%, color(srgb .5 .6 .7 / .8) 37.5%)`, `color(srgb 0.4 0.5 0.6 / 0.7)`); // Scale up < 100% sum. 106 testComputed(`color-mix(in srgb, color(srgb .1 .2 .3 / .4) 0%, color(srgb .5 .6 .7 / .8))`, `color(srgb 0.5 0.6 0.7 / 0.8)`); 107 108 // What should happen if you provide a negative percent? https://github.com/w3c/csswg-drafts/issues/6047 109 testComputed(`color-mix(in srgb, color(srgb .1 .2 .3 / .4) -10%, color(srgb .5 .6 .7 / .8))`, `color(srgb 0.54 0.64000005 0.74 / 0.84000003)`); 110 111 for (const colorSpace of [ "xyz", "xyz-d50", "xyz-d65" ]) { 97 for (const colorSpace of [ "srgb", "xyz", "xyz-d50", "xyz-d65" ]) { 112 98 debug(''); 113 99 debug(`color-mix(in ${colorSpace}, ...)`); -
trunk/LayoutTests/fast/css/parsing-lab-colors-expected.txt
r278268 r286191 1 Test the parsing of lab(...) andlch(...) colors.1 Test the parsing of lab(...), lch(...), oklab(...) and oklch(...) colors. 2 2 3 3 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". 4 4 5 5 6 lab() 6 7 lab(...) 7 8 PASS computedStyle("background-color", "lab(0% 0 0)") is "lab(0% 0 0)" 8 9 PASS computedStyle("background-color", "lab(0% 0 0 / 1)") is "lab(0% 0 0)" … … 20 21 PASS computedStyle("background-color", "lab(50% 0 -20)") is "lab(50% 0 -20)" 21 22 22 lch() 23 Test invalid values 24 PASS computedStyle("background-color", "lab(0 0 0)") is "rgba(0, 0, 0, 0)" 25 PASS computedStyle("background-color", "lab(0% 0% 0)") is "rgba(0, 0, 0, 0)" 26 PASS computedStyle("background-color", "lab(0% 0 0 1)") is "rgba(0, 0, 0, 0)" 27 PASS computedStyle("background-color", "lab(0% 0 0 10%)") is "rgba(0, 0, 0, 0)" 28 PASS computedStyle("background-color", "lab(0% 0 0deg)") is "rgba(0, 0, 0, 0)" 29 PASS computedStyle("background-color", "lab(0% 0% 0deg)") is "rgba(0, 0, 0, 0)" 30 PASS computedStyle("background-color", "lab(40% 0 0deg)") is "rgba(0, 0, 0, 0)" 31 PASS computedStyle("background-color", "color(lab 20% 0 10 / 50%)") is "rgba(0, 0, 0, 0)" 32 33 oklab(...) 34 PASS computedStyle("background-color", "oklab(0% 0 0)") is "oklab(0% 0 0)" 35 PASS computedStyle("background-color", "oklab(0% 0 0 / 1)") is "oklab(0% 0 0)" 36 PASS computedStyle("background-color", "oklab(0% 0 0 / 0.5)") is "oklab(0% 0 0 / 0.5)" 37 PASS computedStyle("background-color", "oklab(20% 0 10/0.5)") is "oklab(20% 0 10 / 0.5)" 38 PASS computedStyle("background-color", "oklab(20% 0 10/50%)") is "oklab(20% 0 10 / 0.5)" 39 PASS computedStyle("background-color", "oklab(400% 0 10/50%)") is "oklab(400% 0 10 / 0.5)" 40 PASS computedStyle("background-color", "oklab(50% -160 160)") is "oklab(50% -160 160)" 41 PASS computedStyle("background-color", "oklab(50% -200 200)") is "oklab(50% -200 200)" 42 PASS computedStyle("background-color", "oklab(0% 0 0 / -10%)") is "oklab(0% 0 0 / 0)" 43 PASS computedStyle("background-color", "oklab(0% 0 0 / 110%)") is "oklab(0% 0 0)" 44 PASS computedStyle("background-color", "oklab(0% 0 0 / 300%)") is "oklab(0% 0 0)" 45 PASS computedStyle("background-color", "oklab(-40% 0 0)") is "oklab(0% 0 0)" 46 PASS computedStyle("background-color", "oklab(50% -20 0)") is "oklab(50% -20 0)" 47 PASS computedStyle("background-color", "oklab(50% 0 -20)") is "oklab(50% 0 -20)" 48 49 Test invalid values 50 PASS computedStyle("background-color", "oklab(0 0 0)") is "rgba(0, 0, 0, 0)" 51 PASS computedStyle("background-color", "oklab(0% 0% 0)") is "rgba(0, 0, 0, 0)" 52 PASS computedStyle("background-color", "oklab(0% 0 0 1)") is "rgba(0, 0, 0, 0)" 53 PASS computedStyle("background-color", "oklab(0% 0 0 10%)") is "rgba(0, 0, 0, 0)" 54 PASS computedStyle("background-color", "oklab(0% 0 0deg)") is "rgba(0, 0, 0, 0)" 55 PASS computedStyle("background-color", "oklab(0% 0% 0deg)") is "rgba(0, 0, 0, 0)" 56 PASS computedStyle("background-color", "oklab(40% 0 0deg)") is "rgba(0, 0, 0, 0)" 57 PASS computedStyle("background-color", "color(oklab 20% 0 10 / 50%)") is "rgba(0, 0, 0, 0)" 58 59 lch(...) 23 60 PASS computedStyle("background-color", "lch(0% 0 0deg)") is "lch(0% 0 0)" 24 61 PASS computedStyle("background-color", "lch(0% 0 0deg / 1)") is "lch(0% 0 0)" … … 41 78 42 79 Test invalid values 43 PASS computedStyle("background-color", "lab(0 0 0)") is "rgba(0, 0, 0, 0)"44 PASS computedStyle("background-color", "lab(0% 0% 0)") is "rgba(0, 0, 0, 0)"45 PASS computedStyle("background-color", "lab(0% 0 0 1)") is "rgba(0, 0, 0, 0)"46 PASS computedStyle("background-color", "lab(0% 0 0 10%)") is "rgba(0, 0, 0, 0)"47 PASS computedStyle("background-color", "lab(0% 0 0deg)") is "rgba(0, 0, 0, 0)"48 PASS computedStyle("background-color", "lab(0% 0% 0deg)") is "rgba(0, 0, 0, 0)"49 PASS computedStyle("background-color", "lab(40% 0 0deg)") is "rgba(0, 0, 0, 0)"50 80 PASS computedStyle("background-color", "lch(0 0 0 / 0.5)") is "rgba(0, 0, 0, 0)" 51 81 PASS computedStyle("background-color", "lch(20% 10 10deg 10)") is "rgba(0, 0, 0, 0)" 52 82 PASS computedStyle("background-color", "lch(20% 10 10deg 10 / 0.5)") is "rgba(0, 0, 0, 0)" 53 PASS computedStyle("background-color", "color(lab 20% 0 10 / 50%)") is "rgba(0, 0, 0, 0)" 83 PASS computedStyle("background-color", "color(lch 20% 0 10 / 50%)") is "rgba(0, 0, 0, 0)" 84 85 oklch(...) 86 PASS computedStyle("background-color", "oklch(0% 0 0deg)") is "oklch(0% 0 0)" 87 PASS computedStyle("background-color", "oklch(0% 0 0deg / 1)") is "oklch(0% 0 0)" 88 PASS computedStyle("background-color", "oklch(0% 0 0deg / 0.5)") is "oklch(0% 0 0 / 0.5)" 89 PASS computedStyle("background-color", "oklch(100% 230 0deg / 0.5)") is "oklch(100% 230 0 / 0.5)" 90 PASS computedStyle("background-color", "oklch(20% 50 20deg/0.5)") is "oklch(20% 50 20 / 0.5)" 91 PASS computedStyle("background-color", "oklch(20% 50 20deg/50%)") is "oklch(20% 50 20 / 0.5)" 92 PASS computedStyle("background-color", "oklch(10% 20 20deg / -10%)") is "oklch(10% 20 20 / 0)" 93 PASS computedStyle("background-color", "oklch(10% 20 20deg / 110%)") is "oklch(10% 20 20)" 94 PASS computedStyle("background-color", "oklch(10% 20 1.28rad)") is "oklch(10% 20 73.3386)" 95 PASS computedStyle("background-color", "oklch(10% 20 380deg)") is "oklch(10% 20 20)" 96 PASS computedStyle("background-color", "oklch(10% 20 -340deg)") is "oklch(10% 20 20)" 97 PASS computedStyle("background-color", "oklch(10% 20 740deg)") is "oklch(10% 20 20)" 98 PASS computedStyle("background-color", "oklch(10% 20 -700deg)") is "oklch(10% 20 20)" 99 PASS computedStyle("background-color", "oklch(-40% 0 0)") is "oklch(0% 0 0)" 100 PASS computedStyle("background-color", "oklch(20% -20 0)") is "oklch(20% 0 0)" 101 PASS computedStyle("background-color", "oklch(0% 0 0 / 0.5)") is "oklch(0% 0 0 / 0.5)" 102 PASS computedStyle("background-color", "oklch(10% 20 20 / 110%)") is "oklch(10% 20 20)" 103 PASS computedStyle("background-color", "oklch(10% 20 -700)") is "oklch(10% 20 20)" 104 105 Test invalid values 106 PASS computedStyle("background-color", "oklch(0 0 0 / 0.5)") is "rgba(0, 0, 0, 0)" 107 PASS computedStyle("background-color", "oklch(20% 10 10deg 10)") is "rgba(0, 0, 0, 0)" 108 PASS computedStyle("background-color", "oklch(20% 10 10deg 10 / 0.5)") is "rgba(0, 0, 0, 0)" 109 PASS computedStyle("background-color", "color(oklch 20% 0 10 / 50%)") is "rgba(0, 0, 0, 0)" 54 110 PASS successfullyParsed is true 55 111 -
trunk/LayoutTests/fast/css/parsing-lab-colors.html
r278268 r286191 4 4 <body> 5 5 <script> 6 description("Test the parsing of lab(...) andlch(...) colors.");6 description("Test the parsing of lab(...), lch(...), oklab(...) and oklch(...) colors."); 7 7 8 8 function computedStyle(property, value) … … 35 35 } 36 36 37 debug('lab()'); 38 testComputed("background-color", "lab(0% 0 0)", "lab(0% 0 0)"); 39 testComputed("background-color", "lab(0% 0 0 / 1)", "lab(0% 0 0)"); 40 testComputed("background-color", "lab(0% 0 0 / 0.5)", "lab(0% 0 0 / 0.5)"); 41 testComputed("background-color", "lab(20% 0 10/0.5)", "lab(20% 0 10 / 0.5)"); 42 testComputed("background-color", "lab(20% 0 10/50%)", "lab(20% 0 10 / 0.5)"); 43 testComputed("background-color", "lab(400% 0 10/50%)", "lab(400% 0 10 / 0.5)"); 44 testComputed("background-color", "lab(50% -160 160)", "lab(50% -160 160)"); 45 testComputed("background-color", "lab(50% -200 200)", "lab(50% -200 200)"); 46 testComputed("background-color", "lab(0% 0 0 / -10%)", "lab(0% 0 0 / 0)"); 47 testComputed("background-color", "lab(0% 0 0 / 110%)", "lab(0% 0 0)"); 48 testComputed("background-color", "lab(0% 0 0 / 300%)", "lab(0% 0 0)"); 49 testComputed("background-color", "lab(-40% 0 0)", "lab(0% 0 0)"); 50 testComputed("background-color", "lab(50% -20 0)", "lab(50% -20 0)"); 51 testComputed("background-color", "lab(50% 0 -20)", "lab(50% 0 -20)"); 37 for (const colorSpace of [ "lab", "oklab" ]) { 38 debug(''); 39 debug(`${colorSpace}(...)`); 40 testComputed(`background-color`, `${colorSpace}(0% 0 0)`, `${colorSpace}(0% 0 0)`); 41 testComputed(`background-color`, `${colorSpace}(0% 0 0 / 1)`, `${colorSpace}(0% 0 0)`); 42 testComputed(`background-color`, `${colorSpace}(0% 0 0 / 0.5)`, `${colorSpace}(0% 0 0 / 0.5)`); 43 testComputed(`background-color`, `${colorSpace}(20% 0 10/0.5)`, `${colorSpace}(20% 0 10 / 0.5)`); 44 testComputed(`background-color`, `${colorSpace}(20% 0 10/50%)`, `${colorSpace}(20% 0 10 / 0.5)`); 45 testComputed(`background-color`, `${colorSpace}(400% 0 10/50%)`, `${colorSpace}(400% 0 10 / 0.5)`); 46 testComputed(`background-color`, `${colorSpace}(50% -160 160)`, `${colorSpace}(50% -160 160)`); 47 testComputed(`background-color`, `${colorSpace}(50% -200 200)`, `${colorSpace}(50% -200 200)`); 48 testComputed(`background-color`, `${colorSpace}(0% 0 0 / -10%)`, `${colorSpace}(0% 0 0 / 0)`); 49 testComputed(`background-color`, `${colorSpace}(0% 0 0 / 110%)`, `${colorSpace}(0% 0 0)`); 50 testComputed(`background-color`, `${colorSpace}(0% 0 0 / 300%)`, `${colorSpace}(0% 0 0)`); 51 testComputed(`background-color`, `${colorSpace}(-40% 0 0)`, `${colorSpace}(0% 0 0)`); 52 testComputed(`background-color`, `${colorSpace}(50% -20 0)`, `${colorSpace}(50% -20 0)`); 53 testComputed(`background-color`, `${colorSpace}(50% 0 -20)`, `${colorSpace}(50% 0 -20)`); 52 54 53 debug(''); 54 debug('lch()'); 55 testComputed("background-color", "lch(0% 0 0deg)", "lch(0% 0 0)"); 56 testComputed("background-color", "lch(0% 0 0deg / 1)", "lch(0% 0 0)"); 57 testComputed("background-color", "lch(0% 0 0deg / 0.5)", "lch(0% 0 0 / 0.5)"); 58 testComputed("background-color", "lch(100% 230 0deg / 0.5)", "lch(100% 230 0 / 0.5)"); 59 testComputed("background-color", "lch(20% 50 20deg/0.5)", "lch(20% 50 20 / 0.5)"); 60 testComputed("background-color", "lch(20% 50 20deg/50%)", "lch(20% 50 20 / 0.5)"); 61 testComputed("background-color", "lch(10% 20 20deg / -10%)", "lch(10% 20 20 / 0)"); 62 testComputed("background-color", "lch(10% 20 20deg / 110%)", "lch(10% 20 20)"); 63 testComputed("background-color", "lch(10% 20 1.28rad)", "lch(10% 20 73.3386)"); 64 testComputed("background-color", "lch(10% 20 380deg)", "lch(10% 20 20)"); 65 testComputed("background-color", "lch(10% 20 -340deg)", "lch(10% 20 20)"); 66 testComputed("background-color", "lch(10% 20 740deg)", "lch(10% 20 20)"); 67 testComputed("background-color", "lch(10% 20 -700deg)", "lch(10% 20 20)"); 68 testComputed("background-color", "lch(-40% 0 0)", "lch(0% 0 0)"); 69 testComputed("background-color", "lch(20% -20 0)", "lch(20% 0 0)"); 70 // hue (the third argument) can be either an angle or number, with number interpreted as degrees. 71 testComputed("background-color", "lch(0% 0 0 / 0.5)", "lch(0% 0 0 / 0.5)"); 72 testComputed("background-color", "lch(10% 20 20 / 110%)", "lch(10% 20 20)"); 73 testComputed("background-color", "lch(10% 20 -700)", "lch(10% 20 20)"); 55 debug(''); 56 debug('Test invalid values'); 57 testComputed(`background-color`, `${colorSpace}(0 0 0)`, `rgba(0, 0, 0, 0)`); 58 testComputed(`background-color`, `${colorSpace}(0% 0% 0)`, `rgba(0, 0, 0, 0)`); 59 testComputed(`background-color`, `${colorSpace}(0% 0 0 1)`, `rgba(0, 0, 0, 0)`); 60 testComputed(`background-color`, `${colorSpace}(0% 0 0 10%)`, `rgba(0, 0, 0, 0)`); 61 testComputed(`background-color`, `${colorSpace}(0% 0 0deg)`, `rgba(0, 0, 0, 0)`); 62 testComputed(`background-color`, `${colorSpace}(0% 0% 0deg)`, `rgba(0, 0, 0, 0)`); 63 testComputed(`background-color`, `${colorSpace}(40% 0 0deg)`, `rgba(0, 0, 0, 0)`); 64 testComputed(`background-color`, `color(${colorSpace} 20% 0 10 / 50%)`, `rgba(0, 0, 0, 0)`); 65 } 74 66 75 debug(''); 76 debug('Test invalid values'); 77 testComputed("background-color", "lab(0 0 0)", "rgba(0, 0, 0, 0)"); 78 testComputed("background-color", "lab(0% 0% 0)", "rgba(0, 0, 0, 0)"); 79 testComputed("background-color", "lab(0% 0 0 1)", "rgba(0, 0, 0, 0)"); 80 testComputed("background-color", "lab(0% 0 0 10%)", "rgba(0, 0, 0, 0)"); 81 testComputed("background-color", "lab(0% 0 0deg)", "rgba(0, 0, 0, 0)"); 82 testComputed("background-color", "lab(0% 0% 0deg)", "rgba(0, 0, 0, 0)"); 83 testComputed("background-color", "lab(40% 0 0deg)", "rgba(0, 0, 0, 0)"); 67 for (const colorSpace of [ "lch", "oklch" ]) { 68 debug(''); 69 debug(`${colorSpace}(...)`); 70 testComputed(`background-color`, `${colorSpace}(0% 0 0deg)`, `${colorSpace}(0% 0 0)`); 71 testComputed(`background-color`, `${colorSpace}(0% 0 0deg / 1)`, `${colorSpace}(0% 0 0)`); 72 testComputed(`background-color`, `${colorSpace}(0% 0 0deg / 0.5)`, `${colorSpace}(0% 0 0 / 0.5)`); 73 testComputed(`background-color`, `${colorSpace}(100% 230 0deg / 0.5)`, `${colorSpace}(100% 230 0 / 0.5)`); 74 testComputed(`background-color`, `${colorSpace}(20% 50 20deg/0.5)`, `${colorSpace}(20% 50 20 / 0.5)`); 75 testComputed(`background-color`, `${colorSpace}(20% 50 20deg/50%)`, `${colorSpace}(20% 50 20 / 0.5)`); 76 testComputed(`background-color`, `${colorSpace}(10% 20 20deg / -10%)`, `${colorSpace}(10% 20 20 / 0)`); 77 testComputed(`background-color`, `${colorSpace}(10% 20 20deg / 110%)`, `${colorSpace}(10% 20 20)`); 78 testComputed(`background-color`, `${colorSpace}(10% 20 1.28rad)`, `${colorSpace}(10% 20 73.3386)`); 79 testComputed(`background-color`, `${colorSpace}(10% 20 380deg)`, `${colorSpace}(10% 20 20)`); 80 testComputed(`background-color`, `${colorSpace}(10% 20 -340deg)`, `${colorSpace}(10% 20 20)`); 81 testComputed(`background-color`, `${colorSpace}(10% 20 740deg)`, `${colorSpace}(10% 20 20)`); 82 testComputed(`background-color`, `${colorSpace}(10% 20 -700deg)`, `${colorSpace}(10% 20 20)`); 83 testComputed(`background-color`, `${colorSpace}(-40% 0 0)`, `${colorSpace}(0% 0 0)`); 84 testComputed(`background-color`, `${colorSpace}(20% -20 0)`, `${colorSpace}(20% 0 0)`); 85 // hue (the third argument) can be either an angle or number, with number interpreted as degrees. 86 testComputed(`background-color`, `${colorSpace}(0% 0 0 / 0.5)`, `${colorSpace}(0% 0 0 / 0.5)`); 87 testComputed(`background-color`, `${colorSpace}(10% 20 20 / 110%)`, `${colorSpace}(10% 20 20)`); 88 testComputed(`background-color`, `${colorSpace}(10% 20 -700)`, `${colorSpace}(10% 20 20)`); 84 89 85 testComputed("background-color", "lch(0 0 0 / 0.5)", "rgba(0, 0, 0, 0)"); 86 testComputed("background-color", "lch(20% 10 10deg 10)", "rgba(0, 0, 0, 0)"); 87 testComputed("background-color", "lch(20% 10 10deg 10 / 0.5)", "rgba(0, 0, 0, 0)"); 90 debug(''); 91 debug('Test invalid values'); 88 92 89 testComputed("background-color", "color(lab 20% 0 10 / 50%)", "rgba(0, 0, 0, 0)"); 93 testComputed(`background-color`, `${colorSpace}(0 0 0 / 0.5)`, `rgba(0, 0, 0, 0)`); 94 testComputed(`background-color`, `${colorSpace}(20% 10 10deg 10)`, `rgba(0, 0, 0, 0)`); 95 testComputed(`background-color`, `${colorSpace}(20% 10 10deg 10 / 0.5)`, `rgba(0, 0, 0, 0)`); 96 testComputed(`background-color`, `color(${colorSpace} 20% 0 10 / 50%)`, `rgba(0, 0, 0, 0)`); 97 } 90 98 91 99 </script> -
trunk/LayoutTests/fast/css/parsing-relative-color-syntax-expected.txt
r286168 r286191 230 230 PASS computedStyle("background-color", "lab(from lab(25% 20 50) h g b)") is "rgba(0, 0, 0, 0)" 231 231 232 oklab(from ...) 233 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50) l a b)") is "oklab(25% 20 50)" 234 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50) l a b / alpha)") is "oklab(25% 20 50)" 235 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50 / 40%) l a b / alpha)") is "oklab(25% 20 50 / 0.4)" 236 PASS computedStyle("background-color", "oklab(from oklab(from oklab(25% 20 50) l a b) l a b)") is "oklab(25% 20 50)" 237 PASS computedStyle("background-color", "oklab(from color(display-p3 0 0 0) l a b / alpha)") is "oklab(0% 0 0)" 238 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50) 0% 0 0)") is "oklab(0% 0 0)" 239 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50) 0% 0 0 / 0)") is "oklab(0% 0 0 / 0)" 240 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50) 0% a b / alpha)") is "oklab(0% 20 50)" 241 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50) l 0 b / alpha)") is "oklab(25% 0 50)" 242 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50) l a 0 / alpha)") is "oklab(25% 20 0)" 243 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50) l a b / 0)") is "oklab(25% 20 50 / 0)" 244 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50 / 40%) 0% a b / alpha)") is "oklab(0% 20 50 / 0.4)" 245 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50 / 40%) l 0 b / alpha)") is "oklab(25% 0 50 / 0.4)" 246 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50 / 40%) l a 0 / alpha)") is "oklab(25% 20 0 / 0.4)" 247 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50 / 40%) l a b / 0)") is "oklab(25% 20 50 / 0)" 248 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50) 35% a b / alpha)") is "oklab(35% 20 50)" 249 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50) l 35 b / alpha)") is "oklab(25% 35 50)" 250 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50) l a 35 / alpha)") is "oklab(25% 20 35)" 251 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50) l a b / .35)") is "oklab(25% 20 50 / 0.35)" 252 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50 / 40%) 35% a b / alpha)") is "oklab(35% 20 50 / 0.4)" 253 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50 / 40%) l 35 b / alpha)") is "oklab(25% 35 50 / 0.4)" 254 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50 / 40%) l a 35 / alpha)") is "oklab(25% 20 35 / 0.4)" 255 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50 / 40%) l a b / .35)") is "oklab(25% 20 50 / 0.35)" 256 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50) l b a)") is "oklab(25% 50 20)" 257 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50) l a a / a)") is "oklab(25% 20 20)" 258 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50 / 40%) l b a)") is "oklab(25% 50 20)" 259 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50 / 40%) l a a / a)") is "oklab(25% 20 20)" 260 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50) l alpha a / b)") is "rgba(0, 0, 0, 0)" 261 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50) l alpha alpha / alpha)") is "rgba(0, 0, 0, 0)" 262 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50 / 40%) l alpha a / b)") is "rgba(0, 0, 0, 0)" 263 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50 / 40%) l alpha alpha / alpha)") is "rgba(0, 0, 0, 0)" 264 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50) calc(l) calc(a) calc(b))") is "oklab(25% 20 50)" 265 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50 / 40%) calc(l) calc(a) calc(b) / calc(alpha))") is "oklab(25% 20 50 / 0.4)" 266 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50) l 10% 10)") is "rgba(0, 0, 0, 0)" 267 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50) l 10 10%)") is "rgba(0, 0, 0, 0)" 268 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50) 10 a b)") is "rgba(0, 0, 0, 0)" 269 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50 / 40%) l 10% 10)") is "rgba(0, 0, 0, 0)" 270 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50 / 40%) l 10 10%)") is "rgba(0, 0, 0, 0)" 271 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50 / 40%) 10 a b)") is "rgba(0, 0, 0, 0)" 272 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50) lightness a b)") is "rgba(0, 0, 0, 0)" 273 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50) x a b)") is "rgba(0, 0, 0, 0)" 274 PASS computedStyle("background-color", "oklab(from oklab(25% 20 50) h g b)") is "rgba(0, 0, 0, 0)" 275 232 276 lch(from ...) 233 277 PASS computedStyle("background-color", "lch(from lch(70% 45 30) l c h)") is "lch(70% 45 30)" … … 287 331 PASS computedStyle("background-color", "lch(from lch(70% 45 30) l g b)") is "rgba(0, 0, 0, 0)" 288 332 289 color(from ... ${color} ...) 333 oklch(from ...) 334 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) l c h)") is "oklch(70% 45 30)" 335 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) l c h / alpha)") is "oklch(70% 45 30)" 336 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30 / 40%) l c h/ alpha)") is "oklch(70% 45 30 / 0.4)" 337 PASS computedStyle("background-color", "oklch(from oklch(from oklch(70% 45 30) l c h) l c h)") is "oklch(70% 45 30)" 338 PASS computedStyle("background-color", "oklch(from color(display-p3 0 0 0) l c h / alpha)") is "oklch(0% 0 0)" 339 PASS computedStyle("background-color", "oklch(from oklab(70% 45 30) l c h / alpha)") is "oklch(70% 54.08327 33.690067)" 340 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) 0% 0 0)") is "oklch(0% 0 0)" 341 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) 0% 0 0deg)") is "oklch(0% 0 0)" 342 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) 0% 0 0 / 0)") is "oklch(0% 0 0 / 0)" 343 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) 0% 0 0deg / 0)") is "oklch(0% 0 0 / 0)" 344 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) 0% c h / alpha)") is "oklch(0% 45 30)" 345 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) l 0 h / alpha)") is "oklch(70% 0 30)" 346 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) l c 0 / alpha)") is "oklch(70% 45 0)" 347 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) l c 0deg / alpha)") is "oklch(70% 45 0)" 348 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) l c h / 0)") is "oklch(70% 45 30 / 0)" 349 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30 / 40%) 0% c h / alpha)") is "oklch(0% 45 30 / 0.4)" 350 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30 / 40%) l 0 h / alpha)") is "oklch(70% 0 30 / 0.4)" 351 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30 / 40%) l c 0 / alpha)") is "oklch(70% 45 0 / 0.4)" 352 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30 / 40%) l c 0deg / alpha)") is "oklch(70% 45 0 / 0.4)" 353 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30 / 40%) l c h / 0)") is "oklch(70% 45 30 / 0)" 354 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) 25% c h / alpha)") is "oklch(25% 45 30)" 355 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) l 25 h / alpha)") is "oklch(70% 25 30)" 356 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) l c 25 / alpha)") is "oklch(70% 45 25)" 357 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) l c 25deg / alpha)") is "oklch(70% 45 25)" 358 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) l c h / .25)") is "oklch(70% 45 30 / 0.25)" 359 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30 / 40%) 25% c h / alpha)") is "oklch(25% 45 30 / 0.4)" 360 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30 / 40%) l 25 h / alpha)") is "oklch(70% 25 30 / 0.4)" 361 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30 / 40%) l c 25 / alpha)") is "oklch(70% 45 25 / 0.4)" 362 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30 / 40%) l c 25deg / alpha)") is "oklch(70% 45 25 / 0.4)" 363 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30 / 40%) l c h / .25)") is "oklch(70% 45 30 / 0.25)" 364 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) alpha c h / l)") is "oklch(100% 45 30 / 0.7)" 365 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) l c c / alpha)") is "oklch(70% 45 45)" 366 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) alpha c h / alpha)") is "oklch(100% 45 30)" 367 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) alpha c c / alpha)") is "oklch(100% 45 45)" 368 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30 / 40%) alpha c h / l)") is "oklch(40% 45 30 / 0.7)" 369 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30 / 40%) l c c / alpha)") is "oklch(70% 45 45 / 0.4)" 370 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30 / 40%) alpha c h / alpha)") is "oklch(40% 45 30 / 0.4)" 371 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30 / 40%) alpha c c / alpha)") is "oklch(40% 45 45 / 0.4)" 372 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) h l c / alpha)") is "rgba(0, 0, 0, 0)" 373 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) c c c / c)") is "rgba(0, 0, 0, 0)" 374 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) alpha alpha alpha / alpha)") is "rgba(0, 0, 0, 0)" 375 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30 / 40%) h l c / alpha)") is "rgba(0, 0, 0, 0)" 376 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30 / 40%) c c c / c)") is "rgba(0, 0, 0, 0)" 377 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30 / 40%) alpha alpha alpha / alpha)") is "rgba(0, 0, 0, 0)" 378 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) calc(l) calc(c) calc(h))") is "oklch(70% 45 30)" 379 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))") is "oklch(70% 45 30 / 0.4)" 380 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) l 10% h)") is "rgba(0, 0, 0, 0)" 381 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) l c 10%)") is "rgba(0, 0, 0, 0)" 382 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) 10 c h)") is "rgba(0, 0, 0, 0)" 383 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30 / 40%) l 10% h)") is "rgba(0, 0, 0, 0)" 384 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30 / 40%) l c 10%)") is "rgba(0, 0, 0, 0)" 385 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30 / 40%) 10 c h)") is "rgba(0, 0, 0, 0)" 386 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) lightness c h)") is "rgba(0, 0, 0, 0)" 387 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) x c h)") is "rgba(0, 0, 0, 0)" 388 PASS computedStyle("background-color", "oklch(from oklch(70% 45 30) l g b)") is "rgba(0, 0, 0, 0)" 389 390 color(from ... srgb ...) 290 391 PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb r g b)") is "color(srgb 0.7 0.5 0.3)" 291 392 PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb r g b / alpha)") is "color(srgb 0.7 0.5 0.3)" … … 339 440 PASS computedStyle("background-color", "color(from color(srgb 0.7 0.5 0.3) srgb l g b)") is "rgba(0, 0, 0, 0)" 340 441 341 color(from ... ${color}...)442 color(from ... srgb-linear ...) 342 443 PASS computedStyle("background-color", "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b)") is "color(srgb-linear 0.7 0.5 0.3)" 343 444 PASS computedStyle("background-color", "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear r g b / alpha)") is "color(srgb-linear 0.7 0.5 0.3)" … … 391 492 PASS computedStyle("background-color", "color(from color(srgb-linear 0.7 0.5 0.3) srgb-linear l g b)") is "rgba(0, 0, 0, 0)" 392 493 393 color(from ... ${color}...)494 color(from ... a98-rgb ...) 394 495 PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b)") is "color(a98-rgb 0.7 0.5 0.3)" 395 496 PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / alpha)") is "color(a98-rgb 0.7 0.5 0.3)" … … 443 544 PASS computedStyle("background-color", "color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb l g b)") is "rgba(0, 0, 0, 0)" 444 545 445 color(from ... ${color}...)546 color(from ... rec2020 ...) 446 547 PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b)") is "color(rec2020 0.7 0.5 0.3)" 447 548 PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 r g b / alpha)") is "color(rec2020 0.7 0.5 0.3)" … … 495 596 PASS computedStyle("background-color", "color(from color(rec2020 0.7 0.5 0.3) rec2020 l g b)") is "rgba(0, 0, 0, 0)" 496 597 497 color(from ... ${color}...)598 color(from ... prophoto-rgb ...) 498 599 PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b)") is "color(prophoto-rgb 0.7 0.5 0.3)" 499 600 PASS computedStyle("background-color", "color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b / alpha)") is "color(prophoto-rgb 0.7 0.5 0.3)" -
trunk/LayoutTests/fast/css/parsing-relative-color-syntax.html
r286168 r286191 298 298 testComputed(`hwb(from rebeccapurple h g b)`, `rgba(0, 0, 0, 0)`); 299 299 300 301 debug(''); 302 debug('lab(from ...)'); 303 304 // Testing no modifications. 305 testComputed(`lab(from lab(25% 20 50) l a b)`, `lab(25% 20 50)`); 306 testComputed(`lab(from lab(25% 20 50) l a b / alpha)`, `lab(25% 20 50)`); 307 testComputed(`lab(from lab(25% 20 50 / 40%) l a b / alpha)`, `lab(25% 20 50 / 0.4)`); 308 309 // Test nesting relative colors. 310 testComputed(`lab(from lab(from lab(25% 20 50) l a b) l a b)`, `lab(25% 20 50)`); 311 312 // Testing non-lab origin to see conversion. 313 testComputed(`lab(from color(display-p3 0 0 0) l a b / alpha)`, `lab(0% 0 0)`); 314 315 // Testing replacement with 0. 316 testComputed(`lab(from lab(25% 20 50) 0% 0 0)`, `lab(0% 0 0)`); 317 testComputed(`lab(from lab(25% 20 50) 0% 0 0 / 0)`, `lab(0% 0 0 / 0)`); 318 testComputed(`lab(from lab(25% 20 50) 0% a b / alpha)`, `lab(0% 20 50)`); 319 testComputed(`lab(from lab(25% 20 50) l 0 b / alpha)`, `lab(25% 0 50)`); 320 testComputed(`lab(from lab(25% 20 50) l a 0 / alpha)`, `lab(25% 20 0)`); 321 testComputed(`lab(from lab(25% 20 50) l a b / 0)`, `lab(25% 20 50 / 0)`); 322 testComputed(`lab(from lab(25% 20 50 / 40%) 0% a b / alpha)`, `lab(0% 20 50 / 0.4)`); 323 testComputed(`lab(from lab(25% 20 50 / 40%) l 0 b / alpha)`, `lab(25% 0 50 / 0.4)`); 324 testComputed(`lab(from lab(25% 20 50 / 40%) l a 0 / alpha)`, `lab(25% 20 0 / 0.4)`); 325 testComputed(`lab(from lab(25% 20 50 / 40%) l a b / 0)`, `lab(25% 20 50 / 0)`); 326 327 // Testing replacement with a constant. 328 testComputed(`lab(from lab(25% 20 50) 35% a b / alpha)`, `lab(35% 20 50)`); 329 testComputed(`lab(from lab(25% 20 50) l 35 b / alpha)`, `lab(25% 35 50)`); 330 testComputed(`lab(from lab(25% 20 50) l a 35 / alpha)`, `lab(25% 20 35)`); 331 testComputed(`lab(from lab(25% 20 50) l a b / .35)`, `lab(25% 20 50 / 0.35)`); 332 testComputed(`lab(from lab(25% 20 50 / 40%) 35% a b / alpha)`, `lab(35% 20 50 / 0.4)`); 333 testComputed(`lab(from lab(25% 20 50 / 40%) l 35 b / alpha)`, `lab(25% 35 50 / 0.4)`); 334 testComputed(`lab(from lab(25% 20 50 / 40%) l a 35 / alpha)`, `lab(25% 20 35 / 0.4)`); 335 testComputed(`lab(from lab(25% 20 50 / 40%) l a b / .35)`, `lab(25% 20 50 / 0.35)`); 336 337 // Testing valid permutation (types match). 338 testComputed(`lab(from lab(25% 20 50) l b a)`, `lab(25% 50 20)`); 339 testComputed(`lab(from lab(25% 20 50) l a a / a)`, `lab(25% 20 20)`); 340 testComputed(`lab(from lab(25% 20 50 / 40%) l b a)`, `lab(25% 50 20)`); 341 testComputed(`lab(from lab(25% 20 50 / 40%) l a a / a)`, `lab(25% 20 20)`); 342 343 // Testing invalid permutation (types don't match). 344 testComputed(`lab(from lab(25% 20 50) l alpha a / b)`, `rgba(0, 0, 0, 0)`); 345 testComputed(`lab(from lab(25% 20 50) l alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`); 346 testComputed(`lab(from lab(25% 20 50 / 40%) l alpha a / b)`, `rgba(0, 0, 0, 0)`); 347 testComputed(`lab(from lab(25% 20 50 / 40%) l alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`); 348 349 // Testing with calc(). 350 testComputed(`lab(from lab(25% 20 50) calc(l) calc(a) calc(b))`, `lab(25% 20 50)`); 351 testComputed(`lab(from lab(25% 20 50 / 40%) calc(l) calc(a) calc(b) / calc(alpha))`, `lab(25% 20 50 / 0.4)`); 352 353 // Testing invalid values. 354 testComputed(`lab(from lab(25% 20 50) l 10% 10)`, `rgba(0, 0, 0, 0)`); 355 testComputed(`lab(from lab(25% 20 50) l 10 10%)`, `rgba(0, 0, 0, 0)`); 356 testComputed(`lab(from lab(25% 20 50) 10 a b)`, `rgba(0, 0, 0, 0)`); 357 testComputed(`lab(from lab(25% 20 50 / 40%) l 10% 10)`, `rgba(0, 0, 0, 0)`); 358 testComputed(`lab(from lab(25% 20 50 / 40%) l 10 10%)`, `rgba(0, 0, 0, 0)`); 359 testComputed(`lab(from lab(25% 20 50 / 40%) 10 a b)`, `rgba(0, 0, 0, 0)`); 360 361 // Testing invalid component names 362 testComputed(`lab(from lab(25% 20 50) lightness a b)`, `rgba(0, 0, 0, 0)`); 363 testComputed(`lab(from lab(25% 20 50) x a b)`, `rgba(0, 0, 0, 0)`); 364 testComputed(`lab(from lab(25% 20 50) h g b)`, `rgba(0, 0, 0, 0)`); 365 366 367 debug(''); 368 debug('lch(from ...)'); 369 370 // Testing no modifications. 371 testComputed(`lch(from lch(70% 45 30) l c h)`, `lch(70% 45 30)`); 372 testComputed(`lch(from lch(70% 45 30) l c h / alpha)`, `lch(70% 45 30)`); 373 testComputed(`lch(from lch(70% 45 30 / 40%) l c h/ alpha)`, `lch(70% 45 30 / 0.4)`); 374 375 // Test nesting relative colors. 376 testComputed(`lch(from lch(from lch(70% 45 30) l c h) l c h)`, `lch(70% 45 30)`); 377 378 // Testing non-sRGB origin colors to see gamut clipping. 379 testComputed(`lch(from color(display-p3 0 0 0) l c h / alpha)`, `lch(0% 0 0)`); 380 testComputed(`lch(from lab(70% 45 30) l c h / alpha)`, `lch(70% 54.08327 33.690067)`); 381 382 // Testing replacement with 0. 383 testComputed(`lch(from lch(70% 45 30) 0% 0 0)`, `lch(0% 0 0)`); 384 testComputed(`lch(from lch(70% 45 30) 0% 0 0deg)`, `lch(0% 0 0)`); 385 testComputed(`lch(from lch(70% 45 30) 0% 0 0 / 0)`, `lch(0% 0 0 / 0)`); 386 testComputed(`lch(from lch(70% 45 30) 0% 0 0deg / 0)`, `lch(0% 0 0 / 0)`); 387 testComputed(`lch(from lch(70% 45 30) 0% c h / alpha)`, `lch(0% 45 30)`); 388 testComputed(`lch(from lch(70% 45 30) l 0 h / alpha)`, `lch(70% 0 30)`); 389 testComputed(`lch(from lch(70% 45 30) l c 0 / alpha)`, `lch(70% 45 0)`); 390 testComputed(`lch(from lch(70% 45 30) l c 0deg / alpha)`, `lch(70% 45 0)`); 391 testComputed(`lch(from lch(70% 45 30) l c h / 0)`, `lch(70% 45 30 / 0)`); 392 testComputed(`lch(from lch(70% 45 30 / 40%) 0% c h / alpha)`, `lch(0% 45 30 / 0.4)`); 393 testComputed(`lch(from lch(70% 45 30 / 40%) l 0 h / alpha)`, `lch(70% 0 30 / 0.4)`); 394 testComputed(`lch(from lch(70% 45 30 / 40%) l c 0 / alpha)`, `lch(70% 45 0 / 0.4)`); 395 testComputed(`lch(from lch(70% 45 30 / 40%) l c 0deg / alpha)`, `lch(70% 45 0 / 0.4)`); 396 testComputed(`lch(from lch(70% 45 30 / 40%) l c h / 0)`, `lch(70% 45 30 / 0)`); 397 398 // Testing replacement with a constant. 399 testComputed(`lch(from lch(70% 45 30) 25% c h / alpha)`, `lch(25% 45 30)`); 400 testComputed(`lch(from lch(70% 45 30) l 25 h / alpha)`, `lch(70% 25 30)`); 401 testComputed(`lch(from lch(70% 45 30) l c 25 / alpha)`, `lch(70% 45 25)`); 402 testComputed(`lch(from lch(70% 45 30) l c 25deg / alpha)`, `lch(70% 45 25)`); 403 testComputed(`lch(from lch(70% 45 30) l c h / .25)`, `lch(70% 45 30 / 0.25)`); 404 testComputed(`lch(from lch(70% 45 30 / 40%) 25% c h / alpha)`, `lch(25% 45 30 / 0.4)`); 405 testComputed(`lch(from lch(70% 45 30 / 40%) l 25 h / alpha)`, `lch(70% 25 30 / 0.4)`); 406 testComputed(`lch(from lch(70% 45 30 / 40%) l c 25 / alpha)`, `lch(70% 45 25 / 0.4)`); 407 testComputed(`lch(from lch(70% 45 30 / 40%) l c 25deg / alpha)`, `lch(70% 45 25 / 0.4)`); 408 testComputed(`lch(from lch(70% 45 30 / 40%) l c h / .25)`, `lch(70% 45 30 / 0.25)`); 409 410 // Testing valid permutation (types match). 411 // NOTE: 'c' is a vaild hue, as hue is <angle>|<number>. 412 testComputed(`lch(from lch(70% 45 30) alpha c h / l)`, `lch(100% 45 30 / 0.7)`); 413 testComputed(`lch(from lch(70% 45 30) l c c / alpha)`, `lch(70% 45 45)`); 414 testComputed(`lch(from lch(70% 45 30) alpha c h / alpha)`, `lch(100% 45 30)`); 415 testComputed(`lch(from lch(70% 45 30) alpha c c / alpha)`, `lch(100% 45 45)`); 416 testComputed(`lch(from lch(70% 45 30 / 40%) alpha c h / l)`, `lch(40% 45 30 / 0.7)`); 417 testComputed(`lch(from lch(70% 45 30 / 40%) l c c / alpha)`, `lch(70% 45 45 / 0.4)`); 418 testComputed(`lch(from lch(70% 45 30 / 40%) alpha c h / alpha)`, `lch(40% 45 30 / 0.4)`); 419 testComputed(`lch(from lch(70% 45 30 / 40%) alpha c c / alpha)`, `lch(40% 45 45 / 0.4)`); 420 421 // Testing invalid permutation (types don't match). 422 testComputed(`lch(from lch(70% 45 30) h l c / alpha)`, `rgba(0, 0, 0, 0)`); 423 testComputed(`lch(from lch(70% 45 30) c c c / c)`, `rgba(0, 0, 0, 0)`); 424 testComputed(`lch(from lch(70% 45 30) alpha alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`); 425 testComputed(`lch(from lch(70% 45 30 / 40%) h l c / alpha)`, `rgba(0, 0, 0, 0)`); 426 testComputed(`lch(from lch(70% 45 30 / 40%) c c c / c)`, `rgba(0, 0, 0, 0)`); 427 testComputed(`lch(from lch(70% 45 30 / 40%) alpha alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`); 428 429 // Testing with calc(). 430 testComputed(`lch(from lch(70% 45 30) calc(l) calc(c) calc(h))`, `lch(70% 45 30)`); 431 testComputed(`lch(from lch(70% 45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))`, `lch(70% 45 30 / 0.4)`); 432 433 // Testing invalid values. 434 testComputed(`lch(from lch(70% 45 30) l 10% h)`, `rgba(0, 0, 0, 0)`); 435 testComputed(`lch(from lch(70% 45 30) l c 10%)`, `rgba(0, 0, 0, 0)`); 436 testComputed(`lch(from lch(70% 45 30) 10 c h)`, `rgba(0, 0, 0, 0)`); 437 testComputed(`lch(from lch(70% 45 30 / 40%) l 10% h)`, `rgba(0, 0, 0, 0)`); 438 testComputed(`lch(from lch(70% 45 30 / 40%) l c 10%)`, `rgba(0, 0, 0, 0)`); 439 testComputed(`lch(from lch(70% 45 30 / 40%) 10 c h)`, `rgba(0, 0, 0, 0)`); 440 441 // Testing invalid component names 442 testComputed(`lch(from lch(70% 45 30) lightness c h)`, `rgba(0, 0, 0, 0)`); 443 testComputed(`lch(from lch(70% 45 30) x c h)`, `rgba(0, 0, 0, 0)`); 444 testComputed(`lch(from lch(70% 45 30) l g b)`, `rgba(0, 0, 0, 0)`); 445 446 447 for (const color of [ "srgb", "srgb-linear", "a98-rgb", "rec2020", "prophoto-rgb" ]) { 300 for (const colorSpace of [ "lab", "oklab" ]) { 448 301 debug(''); 449 debug( 'color(from ... ${color} ...)');302 debug(`${colorSpace}(from ...)`); 450 303 451 304 // Testing no modifications. 452 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r g b)`, `color(${color} 0.7 0.5 0.3)`); 453 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r g b / alpha)`, `color(${color} 0.7 0.5 0.3)`); 454 testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} r g b)`, `color(${color} 0.7 0.5 0.3)`); 455 testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} r g b / alpha)`, `color(${color} 0.7 0.5 0.3 / 0.4)`); 305 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50) l a b)`, `${colorSpace}(25% 20 50)`); 306 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50) l a b / alpha)`, `${colorSpace}(25% 20 50)`); 307 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50 / 40%) l a b / alpha)`, `${colorSpace}(25% 20 50 / 0.4)`); 456 308 457 309 // Test nesting relative colors. 458 testComputed(`color(from color(from color(${color} 0.7 0.5 0.3) ${color} r g b) ${color} r g b)`, `color(${color} 0.7 0.5 0.3)`); 310 testComputed(`${colorSpace}(from ${colorSpace}(from ${colorSpace}(25% 20 50) l a b) l a b)`, `${colorSpace}(25% 20 50)`); 311 312 // Testing non-${colorSpace} origin to see conversion. 313 testComputed(`${colorSpace}(from color(display-p3 0 0 0) l a b / alpha)`, `${colorSpace}(0% 0 0)`); 459 314 460 315 // Testing replacement with 0. 461 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} 0 0 0)`, `color(${color} 0 0 0)`); 462 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} 0 0 0)`, `color(${color} 0 0 0)`); 463 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} 0 0 0 / 0)`, `color(${color} 0 0 0 / 0)`); 464 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} 0 0 0 / 0)`, `color(${color} 0 0 0 / 0)`); 465 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} 0 g b / alpha)`, `color(${color} 0 0.5 0.3)`); 466 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r 0 b / alpha)`, `color(${color} 0.7 0 0.3)`); 467 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r g 0 / alpha)`, `color(${color} 0.7 0.5 0)`); 468 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r g b / 0)`, `color(${color} 0.7 0.5 0.3 / 0)`); 469 testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} 0 g b / alpha)`, `color(${color} 0 0.5 0.3 / 0.4)`); 470 testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} r 0 b / alpha)`, `color(${color} 0.7 0 0.3 / 0.4)`); 471 testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} r g 0 / alpha)`, `color(${color} 0.7 0.5 0 / 0.4)`); 472 testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} r g b / 0)`, `color(${color} 0.7 0.5 0.3 / 0)`); 316 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50) 0% 0 0)`, `${colorSpace}(0% 0 0)`); 317 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50) 0% 0 0 / 0)`, `${colorSpace}(0% 0 0 / 0)`); 318 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50) 0% a b / alpha)`, `${colorSpace}(0% 20 50)`); 319 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50) l 0 b / alpha)`, `${colorSpace}(25% 0 50)`); 320 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50) l a 0 / alpha)`, `${colorSpace}(25% 20 0)`); 321 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50) l a b / 0)`, `${colorSpace}(25% 20 50 / 0)`); 322 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50 / 40%) 0% a b / alpha)`, `${colorSpace}(0% 20 50 / 0.4)`); 323 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50 / 40%) l 0 b / alpha)`, `${colorSpace}(25% 0 50 / 0.4)`); 324 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50 / 40%) l a 0 / alpha)`, `${colorSpace}(25% 20 0 / 0.4)`); 325 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50 / 40%) l a b / 0)`, `${colorSpace}(25% 20 50 / 0)`); 473 326 474 327 // Testing replacement with a constant. 475 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} 0.2 g b / alpha)`, `color(${color} 0.2 0.5 0.3)`); 476 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} 20% g b / alpha)`, `color(${color} 0.2 0.5 0.3)`); 477 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r 0.2 b / alpha)`, `color(${color} 0.7 0.2 0.3)`); 478 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r 20% b / alpha)`, `color(${color} 0.7 0.2 0.3)`); 479 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r g 0.2 / alpha)`, `color(${color} 0.7 0.5 0.2)`); 480 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r g 20% / alpha)`, `color(${color} 0.7 0.5 0.2)`); 481 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r g b / 0.2)`, `color(${color} 0.7 0.5 0.3 / 0.2)`); 482 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r g b / 20%)`, `color(${color} 0.7 0.5 0.3 / 0.2)`); 483 testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} 0.2 g b / alpha)`, `color(${color} 0.2 0.5 0.3 / 0.4)`); 484 testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} 20% g b / alpha)`, `color(${color} 0.2 0.5 0.3 / 0.4)`); 485 testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} r 0.2 b / alpha)`, `color(${color} 0.7 0.2 0.3 / 0.4)`); 486 testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} r 20% b / alpha)`, `color(${color} 0.7 0.2 0.3 / 0.4)`); 487 testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} r g 0.2 / alpha)`, `color(${color} 0.7 0.5 0.2 / 0.4)`); 488 testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} r g 20% / alpha)`, `color(${color} 0.7 0.5 0.2 / 0.4)`); 489 testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} r g b / 0.2)`, `color(${color} 0.7 0.5 0.3 / 0.2)`); 490 testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} r g b / 20%)`, `color(${color} 0.7 0.5 0.3 / 0.2)`); 328 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50) 35% a b / alpha)`, `${colorSpace}(35% 20 50)`); 329 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50) l 35 b / alpha)`, `${colorSpace}(25% 35 50)`); 330 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50) l a 35 / alpha)`, `${colorSpace}(25% 20 35)`); 331 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50) l a b / .35)`, `${colorSpace}(25% 20 50 / 0.35)`); 332 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50 / 40%) 35% a b / alpha)`, `${colorSpace}(35% 20 50 / 0.4)`); 333 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50 / 40%) l 35 b / alpha)`, `${colorSpace}(25% 35 50 / 0.4)`); 334 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50 / 40%) l a 35 / alpha)`, `${colorSpace}(25% 20 35 / 0.4)`); 335 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50 / 40%) l a b / .35)`, `${colorSpace}(25% 20 50 / 0.35)`); 491 336 492 337 // Testing valid permutation (types match). 493 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} g b r)`, `color(${color} 0.5 0.3 0.7)`); 494 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} b alpha r / g)`, `color(${color} 0.3 1 0.7 / 0.5)`); 495 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r r r / r)`, `color(${color} 0.7 0.7 0.7 / 0.7)`); 496 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} alpha alpha alpha / alpha)`, `color(${color} 1 1 1)`); 497 testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} g b r)`, `color(${color} 0.5 0.3 0.7)`); 498 testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} b alpha r / g)`, `color(${color} 0.3 0.4 0.7 / 0.5)`); 499 testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} r r r / r)`, `color(${color} 0.7 0.7 0.7 / 0.7)`); 500 testComputed(`color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} alpha alpha alpha / alpha)`, `color(${color} 0.4 0.4 0.4 / 0.4)`); 338 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50) l b a)`, `${colorSpace}(25% 50 20)`); 339 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50) l a a / a)`, `${colorSpace}(25% 20 20)`); 340 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50 / 40%) l b a)`, `${colorSpace}(25% 50 20)`); 341 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50 / 40%) l a a / a)`, `${colorSpace}(25% 20 20)`); 342 343 // Testing invalid permutation (types don't match). 344 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50) l alpha a / b)`, `rgba(0, 0, 0, 0)`); 345 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50) l alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`); 346 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50 / 40%) l alpha a / b)`, `rgba(0, 0, 0, 0)`); 347 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50 / 40%) l alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`); 501 348 502 349 // Testing with calc(). 503 testComputed(` color(from color(${color} 0.7 0.5 0.3) ${color} calc(r) calc(g) calc(b))`, `color(${color} 0.7 0.5 0.3)`);504 testComputed(` color(from color(${color} 0.7 0.5 0.3 / 40%) ${color} calc(r) calc(g) calc(b) / calc(alpha))`, `color(${color} 0.7 0.5 0.3/ 0.4)`);350 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50) calc(l) calc(a) calc(b))`, `${colorSpace}(25% 20 50)`); 351 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50 / 40%) calc(l) calc(a) calc(b) / calc(alpha))`, `${colorSpace}(25% 20 50 / 0.4)`); 505 352 506 353 // Testing invalid values. 507 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} 10deg g b)`, `rgba(0, 0, 0, 0)`); 508 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r 10deg b)`, `rgba(0, 0, 0, 0)`); 509 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r g 10deg)`, `rgba(0, 0, 0, 0)`); 510 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} r g b / 10deg)`, `rgba(0, 0, 0, 0)`); 354 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50) l 10% 10)`, `rgba(0, 0, 0, 0)`); 355 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50) l 10 10%)`, `rgba(0, 0, 0, 0)`); 356 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50) 10 a b)`, `rgba(0, 0, 0, 0)`); 357 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50 / 40%) l 10% 10)`, `rgba(0, 0, 0, 0)`); 358 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50 / 40%) l 10 10%)`, `rgba(0, 0, 0, 0)`); 359 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50 / 40%) 10 a b)`, `rgba(0, 0, 0, 0)`); 511 360 512 361 // Testing invalid component names 513 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} red g b)`, `rgba(0, 0, 0, 0)`); 514 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} x g b)`, `rgba(0, 0, 0, 0)`); 515 testComputed(`color(from color(${color} 0.7 0.5 0.3) ${color} l g b)`, `rgba(0, 0, 0, 0)`); 516 } 517 518 for (const color of [ "xyz", "xyz-d50", "xyz-d65" ]) { 362 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50) lightness a b)`, `rgba(0, 0, 0, 0)`); 363 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50) x a b)`, `rgba(0, 0, 0, 0)`); 364 testComputed(`${colorSpace}(from ${colorSpace}(25% 20 50) h g b)`, `rgba(0, 0, 0, 0)`); 365 } 366 367 for (const colorSpace of [ "lch", "oklch" ]) { 368 debug(''); 369 debug(`${colorSpace}(from ...)`); 370 371 const rectangularForm = colorSpace == "lch" ? "lab" : "oklab"; 372 373 // Testing no modifications. 374 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) l c h)`, `${colorSpace}(70% 45 30)`); 375 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) l c h / alpha)`, `${colorSpace}(70% 45 30)`); 376 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30 / 40%) l c h/ alpha)`, `${colorSpace}(70% 45 30 / 0.4)`); 377 378 // Test nesting relative colors. 379 testComputed(`${colorSpace}(from ${colorSpace}(from ${colorSpace}(70% 45 30) l c h) l c h)`, `${colorSpace}(70% 45 30)`); 380 381 // Testing non-sRGB origin colors to see gamut clipping. 382 testComputed(`${colorSpace}(from color(display-p3 0 0 0) l c h / alpha)`, `${colorSpace}(0% 0 0)`); 383 testComputed(`${colorSpace}(from ${rectangularForm}(70% 45 30) l c h / alpha)`, `${colorSpace}(70% 54.08327 33.690067)`); 384 385 // Testing replacement with 0. 386 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) 0% 0 0)`, `${colorSpace}(0% 0 0)`); 387 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) 0% 0 0deg)`, `${colorSpace}(0% 0 0)`); 388 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) 0% 0 0 / 0)`, `${colorSpace}(0% 0 0 / 0)`); 389 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) 0% 0 0deg / 0)`, `${colorSpace}(0% 0 0 / 0)`); 390 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) 0% c h / alpha)`, `${colorSpace}(0% 45 30)`); 391 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) l 0 h / alpha)`, `${colorSpace}(70% 0 30)`); 392 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) l c 0 / alpha)`, `${colorSpace}(70% 45 0)`); 393 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) l c 0deg / alpha)`, `${colorSpace}(70% 45 0)`); 394 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) l c h / 0)`, `${colorSpace}(70% 45 30 / 0)`); 395 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30 / 40%) 0% c h / alpha)`, `${colorSpace}(0% 45 30 / 0.4)`); 396 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30 / 40%) l 0 h / alpha)`, `${colorSpace}(70% 0 30 / 0.4)`); 397 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30 / 40%) l c 0 / alpha)`, `${colorSpace}(70% 45 0 / 0.4)`); 398 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30 / 40%) l c 0deg / alpha)`, `${colorSpace}(70% 45 0 / 0.4)`); 399 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30 / 40%) l c h / 0)`, `${colorSpace}(70% 45 30 / 0)`); 400 401 // Testing replacement with a constant. 402 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) 25% c h / alpha)`, `${colorSpace}(25% 45 30)`); 403 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) l 25 h / alpha)`, `${colorSpace}(70% 25 30)`); 404 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) l c 25 / alpha)`, `${colorSpace}(70% 45 25)`); 405 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) l c 25deg / alpha)`, `${colorSpace}(70% 45 25)`); 406 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) l c h / .25)`, `${colorSpace}(70% 45 30 / 0.25)`); 407 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30 / 40%) 25% c h / alpha)`, `${colorSpace}(25% 45 30 / 0.4)`); 408 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30 / 40%) l 25 h / alpha)`, `${colorSpace}(70% 25 30 / 0.4)`); 409 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30 / 40%) l c 25 / alpha)`, `${colorSpace}(70% 45 25 / 0.4)`); 410 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30 / 40%) l c 25deg / alpha)`, `${colorSpace}(70% 45 25 / 0.4)`); 411 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30 / 40%) l c h / .25)`, `${colorSpace}(70% 45 30 / 0.25)`); 412 413 // Testing valid permutation (types match). 414 // NOTE: 'c' is a vaild hue, as hue is <angle>|<number>. 415 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) alpha c h / l)`, `${colorSpace}(100% 45 30 / 0.7)`); 416 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) l c c / alpha)`, `${colorSpace}(70% 45 45)`); 417 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) alpha c h / alpha)`, `${colorSpace}(100% 45 30)`); 418 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) alpha c c / alpha)`, `${colorSpace}(100% 45 45)`); 419 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30 / 40%) alpha c h / l)`, `${colorSpace}(40% 45 30 / 0.7)`); 420 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30 / 40%) l c c / alpha)`, `${colorSpace}(70% 45 45 / 0.4)`); 421 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30 / 40%) alpha c h / alpha)`, `${colorSpace}(40% 45 30 / 0.4)`); 422 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30 / 40%) alpha c c / alpha)`, `${colorSpace}(40% 45 45 / 0.4)`); 423 424 // Testing invalid permutation (types don't match). 425 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) h l c / alpha)`, `rgba(0, 0, 0, 0)`); 426 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) c c c / c)`, `rgba(0, 0, 0, 0)`); 427 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) alpha alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`); 428 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30 / 40%) h l c / alpha)`, `rgba(0, 0, 0, 0)`); 429 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30 / 40%) c c c / c)`, `rgba(0, 0, 0, 0)`); 430 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30 / 40%) alpha alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`); 431 432 // Testing with calc(). 433 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) calc(l) calc(c) calc(h))`, `${colorSpace}(70% 45 30)`); 434 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))`, `${colorSpace}(70% 45 30 / 0.4)`); 435 436 // Testing invalid values. 437 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) l 10% h)`, `rgba(0, 0, 0, 0)`); 438 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) l c 10%)`, `rgba(0, 0, 0, 0)`); 439 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) 10 c h)`, `rgba(0, 0, 0, 0)`); 440 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30 / 40%) l 10% h)`, `rgba(0, 0, 0, 0)`); 441 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30 / 40%) l c 10%)`, `rgba(0, 0, 0, 0)`); 442 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30 / 40%) 10 c h)`, `rgba(0, 0, 0, 0)`); 443 444 // Testing invalid component names 445 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) lightness c h)`, `rgba(0, 0, 0, 0)`); 446 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) x c h)`, `rgba(0, 0, 0, 0)`); 447 testComputed(`${colorSpace}(from ${colorSpace}(70% 45 30) l g b)`, `rgba(0, 0, 0, 0)`); 448 } 449 450 for (const colorSpace of [ "srgb", "srgb-linear", "a98-rgb", "rec2020", "prophoto-rgb" ]) { 451 debug(''); 452 debug(`color(from ... ${colorSpace} ...)`); 453 454 // Testing no modifications. 455 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} r g b)`, `color(${colorSpace} 0.7 0.5 0.3)`); 456 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} r g b / alpha)`, `color(${colorSpace} 0.7 0.5 0.3)`); 457 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3 / 40%) ${colorSpace} r g b)`, `color(${colorSpace} 0.7 0.5 0.3)`); 458 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3 / 40%) ${colorSpace} r g b / alpha)`, `color(${colorSpace} 0.7 0.5 0.3 / 0.4)`); 459 460 // Test nesting relative colors. 461 testComputed(`color(from color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} r g b) ${colorSpace} r g b)`, `color(${colorSpace} 0.7 0.5 0.3)`); 462 463 // Testing replacement with 0. 464 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} 0 0 0)`, `color(${colorSpace} 0 0 0)`); 465 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} 0 0 0)`, `color(${colorSpace} 0 0 0)`); 466 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} 0 0 0 / 0)`, `color(${colorSpace} 0 0 0 / 0)`); 467 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} 0 0 0 / 0)`, `color(${colorSpace} 0 0 0 / 0)`); 468 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} 0 g b / alpha)`, `color(${colorSpace} 0 0.5 0.3)`); 469 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} r 0 b / alpha)`, `color(${colorSpace} 0.7 0 0.3)`); 470 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} r g 0 / alpha)`, `color(${colorSpace} 0.7 0.5 0)`); 471 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} r g b / 0)`, `color(${colorSpace} 0.7 0.5 0.3 / 0)`); 472 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3 / 40%) ${colorSpace} 0 g b / alpha)`, `color(${colorSpace} 0 0.5 0.3 / 0.4)`); 473 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3 / 40%) ${colorSpace} r 0 b / alpha)`, `color(${colorSpace} 0.7 0 0.3 / 0.4)`); 474 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3 / 40%) ${colorSpace} r g 0 / alpha)`, `color(${colorSpace} 0.7 0.5 0 / 0.4)`); 475 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3 / 40%) ${colorSpace} r g b / 0)`, `color(${colorSpace} 0.7 0.5 0.3 / 0)`); 476 477 // Testing replacement with a constant. 478 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} 0.2 g b / alpha)`, `color(${colorSpace} 0.2 0.5 0.3)`); 479 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} 20% g b / alpha)`, `color(${colorSpace} 0.2 0.5 0.3)`); 480 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} r 0.2 b / alpha)`, `color(${colorSpace} 0.7 0.2 0.3)`); 481 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} r 20% b / alpha)`, `color(${colorSpace} 0.7 0.2 0.3)`); 482 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} r g 0.2 / alpha)`, `color(${colorSpace} 0.7 0.5 0.2)`); 483 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} r g 20% / alpha)`, `color(${colorSpace} 0.7 0.5 0.2)`); 484 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} r g b / 0.2)`, `color(${colorSpace} 0.7 0.5 0.3 / 0.2)`); 485 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} r g b / 20%)`, `color(${colorSpace} 0.7 0.5 0.3 / 0.2)`); 486 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3 / 40%) ${colorSpace} 0.2 g b / alpha)`, `color(${colorSpace} 0.2 0.5 0.3 / 0.4)`); 487 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3 / 40%) ${colorSpace} 20% g b / alpha)`, `color(${colorSpace} 0.2 0.5 0.3 / 0.4)`); 488 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3 / 40%) ${colorSpace} r 0.2 b / alpha)`, `color(${colorSpace} 0.7 0.2 0.3 / 0.4)`); 489 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3 / 40%) ${colorSpace} r 20% b / alpha)`, `color(${colorSpace} 0.7 0.2 0.3 / 0.4)`); 490 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3 / 40%) ${colorSpace} r g 0.2 / alpha)`, `color(${colorSpace} 0.7 0.5 0.2 / 0.4)`); 491 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3 / 40%) ${colorSpace} r g 20% / alpha)`, `color(${colorSpace} 0.7 0.5 0.2 / 0.4)`); 492 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3 / 40%) ${colorSpace} r g b / 0.2)`, `color(${colorSpace} 0.7 0.5 0.3 / 0.2)`); 493 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3 / 40%) ${colorSpace} r g b / 20%)`, `color(${colorSpace} 0.7 0.5 0.3 / 0.2)`); 494 495 // Testing valid permutation (types match). 496 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} g b r)`, `color(${colorSpace} 0.5 0.3 0.7)`); 497 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} b alpha r / g)`, `color(${colorSpace} 0.3 1 0.7 / 0.5)`); 498 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} r r r / r)`, `color(${colorSpace} 0.7 0.7 0.7 / 0.7)`); 499 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} alpha alpha alpha / alpha)`, `color(${colorSpace} 1 1 1)`); 500 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3 / 40%) ${colorSpace} g b r)`, `color(${colorSpace} 0.5 0.3 0.7)`); 501 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3 / 40%) ${colorSpace} b alpha r / g)`, `color(${colorSpace} 0.3 0.4 0.7 / 0.5)`); 502 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3 / 40%) ${colorSpace} r r r / r)`, `color(${colorSpace} 0.7 0.7 0.7 / 0.7)`); 503 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3 / 40%) ${colorSpace} alpha alpha alpha / alpha)`, `color(${colorSpace} 0.4 0.4 0.4 / 0.4)`); 504 505 // Testing with calc(). 506 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} calc(r) calc(g) calc(b))`, `color(${colorSpace} 0.7 0.5 0.3)`); 507 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3 / 40%) ${colorSpace} calc(r) calc(g) calc(b) / calc(alpha))`, `color(${colorSpace} 0.7 0.5 0.3 / 0.4)`); 508 509 // Testing invalid values. 510 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} 10deg g b)`, `rgba(0, 0, 0, 0)`); 511 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} r 10deg b)`, `rgba(0, 0, 0, 0)`); 512 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} r g 10deg)`, `rgba(0, 0, 0, 0)`); 513 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} r g b / 10deg)`, `rgba(0, 0, 0, 0)`); 514 515 // Testing invalid component names 516 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} red g b)`, `rgba(0, 0, 0, 0)`); 517 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} x g b)`, `rgba(0, 0, 0, 0)`); 518 testComputed(`color(from color(${colorSpace} 0.7 0.5 0.3) ${colorSpace} l g b)`, `rgba(0, 0, 0, 0)`); 519 } 520 521 for (const colorSpace of [ "xyz", "xyz-d50", "xyz-d65" ]) { 519 522 debug(''); 520 debug(`color(from ... ${color} ...)`);521 522 const resultColorSpace = color == "xyz" ? "xyz-d65" : color;523 debug(`color(from ... ${colorSpace} ...)`); 524 525 const resultColorSpace = colorSpace == "xyz" ? "xyz-d65" : colorSpace; 523 526 524 527 // Testing no modifications. 525 testComputed(`color(from color(${color } 7 -20.5 100) ${color} x y z)`, `color(${resultColorSpace} 7 -20.5 100)`);526 testComputed(`color(from color(${color } 7 -20.5 100) ${color} x y z / alpha)`, `color(${resultColorSpace} 7 -20.5 100)`);527 testComputed(`color(from color(${color } 7 -20.5 100 / 40%) ${color} x y z)`, `color(${resultColorSpace} 7 -20.5 100)`);528 testComputed(`color(from color(${color } 7 -20.5 100 / 40%) ${color} x y z / alpha)`, `color(${resultColorSpace} 7 -20.5 100 / 0.4)`);528 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} x y z)`, `color(${resultColorSpace} 7 -20.5 100)`); 529 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} x y z / alpha)`, `color(${resultColorSpace} 7 -20.5 100)`); 530 testComputed(`color(from color(${colorSpace} 7 -20.5 100 / 40%) ${colorSpace} x y z)`, `color(${resultColorSpace} 7 -20.5 100)`); 531 testComputed(`color(from color(${colorSpace} 7 -20.5 100 / 40%) ${colorSpace} x y z / alpha)`, `color(${resultColorSpace} 7 -20.5 100 / 0.4)`); 529 532 530 533 // Test nesting relative colors. 531 testComputed(`color(from color(from color(${color } 7 -20.5 100) ${color} x y z) ${color} x y z)`, `color(${resultColorSpace} 7 -20.5 100)`);534 testComputed(`color(from color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} x y z) ${colorSpace} x y z)`, `color(${resultColorSpace} 7 -20.5 100)`); 532 535 533 536 // Testing replacement with 0. 534 testComputed(`color(from color(${color } 7 -20.5 100) ${color} 0 0 0)`, `color(${resultColorSpace} 0 0 0)`);535 testComputed(`color(from color(${color } 7 -20.5 100) ${color} 0 0 0)`, `color(${resultColorSpace} 0 0 0)`);536 testComputed(`color(from color(${color } 7 -20.5 100) ${color} 0 0 0 / 0)`, `color(${resultColorSpace} 0 0 0 / 0)`);537 testComputed(`color(from color(${color } 7 -20.5 100) ${color} 0 0 0 / 0)`, `color(${resultColorSpace} 0 0 0 / 0)`);538 testComputed(`color(from color(${color } 7 -20.5 100) ${color} 0 y z / alpha)`, `color(${resultColorSpace} 0 -20.5 100)`);539 testComputed(`color(from color(${color } 7 -20.5 100) ${color} x 0 z / alpha)`, `color(${resultColorSpace} 7 0 100)`);540 testComputed(`color(from color(${color } 7 -20.5 100) ${color} x y 0 / alpha)`, `color(${resultColorSpace} 7 -20.5 0)`);541 testComputed(`color(from color(${color } 7 -20.5 100) ${color} x y z / 0)`, `color(${resultColorSpace} 7 -20.5 100 / 0)`);542 testComputed(`color(from color(${color } 7 -20.5 100 / 40%) ${color} 0 y z / alpha)`, `color(${resultColorSpace} 0 -20.5 100 / 0.4)`);543 testComputed(`color(from color(${color } 7 -20.5 100 / 40%) ${color} x 0 z / alpha)`, `color(${resultColorSpace} 7 0 100 / 0.4)`);544 testComputed(`color(from color(${color } 7 -20.5 100 / 40%) ${color} x y 0 / alpha)`, `color(${resultColorSpace} 7 -20.5 0 / 0.4)`);545 testComputed(`color(from color(${color } 7 -20.5 100 / 40%) ${color} x y z / 0)`, `color(${resultColorSpace} 7 -20.5 100 / 0)`);537 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} 0 0 0)`, `color(${resultColorSpace} 0 0 0)`); 538 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} 0 0 0)`, `color(${resultColorSpace} 0 0 0)`); 539 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} 0 0 0 / 0)`, `color(${resultColorSpace} 0 0 0 / 0)`); 540 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} 0 0 0 / 0)`, `color(${resultColorSpace} 0 0 0 / 0)`); 541 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} 0 y z / alpha)`, `color(${resultColorSpace} 0 -20.5 100)`); 542 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} x 0 z / alpha)`, `color(${resultColorSpace} 7 0 100)`); 543 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} x y 0 / alpha)`, `color(${resultColorSpace} 7 -20.5 0)`); 544 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} x y z / 0)`, `color(${resultColorSpace} 7 -20.5 100 / 0)`); 545 testComputed(`color(from color(${colorSpace} 7 -20.5 100 / 40%) ${colorSpace} 0 y z / alpha)`, `color(${resultColorSpace} 0 -20.5 100 / 0.4)`); 546 testComputed(`color(from color(${colorSpace} 7 -20.5 100 / 40%) ${colorSpace} x 0 z / alpha)`, `color(${resultColorSpace} 7 0 100 / 0.4)`); 547 testComputed(`color(from color(${colorSpace} 7 -20.5 100 / 40%) ${colorSpace} x y 0 / alpha)`, `color(${resultColorSpace} 7 -20.5 0 / 0.4)`); 548 testComputed(`color(from color(${colorSpace} 7 -20.5 100 / 40%) ${colorSpace} x y z / 0)`, `color(${resultColorSpace} 7 -20.5 100 / 0)`); 546 549 547 550 // Testing replacement with a constant. 548 testComputed(`color(from color(${color } 7 -20.5 100) ${color} 0.2 y z / alpha)`, `color(${resultColorSpace} 0.2 -20.5 100)`);549 testComputed(`color(from color(${color } 7 -20.5 100) ${color} x 0.2 z / alpha)`, `color(${resultColorSpace} 7 0.2 100)`);550 testComputed(`color(from color(${color } 7 -20.5 100) ${color} x y 0.2 / alpha)`, `color(${resultColorSpace} 7 -20.5 0.2)`);551 testComputed(`color(from color(${color } 7 -20.5 100) ${color} x y z / 0.2)`, `color(${resultColorSpace} 7 -20.5 100 / 0.2)`);552 testComputed(`color(from color(${color } 7 -20.5 100) ${color} x y z / 20%)`, `color(${resultColorSpace} 7 -20.5 100 / 0.2)`);553 testComputed(`color(from color(${color } 7 -20.5 100 / 40%) ${color} 0.2 y z / alpha)`, `color(${resultColorSpace} 0.2 -20.5 100 / 0.4)`);554 testComputed(`color(from color(${color } 7 -20.5 100 / 40%) ${color} x 0.2 z / alpha)`, `color(${resultColorSpace} 7 0.2 100 / 0.4)`);555 testComputed(`color(from color(${color } 7 -20.5 100 / 40%) ${color} x y 0.2 / alpha)`, `color(${resultColorSpace} 7 -20.5 0.2 / 0.4)`);556 testComputed(`color(from color(${color } 7 -20.5 100 / 40%) ${color} x y z / 0.2)`, `color(${resultColorSpace} 7 -20.5 100 / 0.2)`);551 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} 0.2 y z / alpha)`, `color(${resultColorSpace} 0.2 -20.5 100)`); 552 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} x 0.2 z / alpha)`, `color(${resultColorSpace} 7 0.2 100)`); 553 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} x y 0.2 / alpha)`, `color(${resultColorSpace} 7 -20.5 0.2)`); 554 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} x y z / 0.2)`, `color(${resultColorSpace} 7 -20.5 100 / 0.2)`); 555 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} x y z / 20%)`, `color(${resultColorSpace} 7 -20.5 100 / 0.2)`); 556 testComputed(`color(from color(${colorSpace} 7 -20.5 100 / 40%) ${colorSpace} 0.2 y z / alpha)`, `color(${resultColorSpace} 0.2 -20.5 100 / 0.4)`); 557 testComputed(`color(from color(${colorSpace} 7 -20.5 100 / 40%) ${colorSpace} x 0.2 z / alpha)`, `color(${resultColorSpace} 7 0.2 100 / 0.4)`); 558 testComputed(`color(from color(${colorSpace} 7 -20.5 100 / 40%) ${colorSpace} x y 0.2 / alpha)`, `color(${resultColorSpace} 7 -20.5 0.2 / 0.4)`); 559 testComputed(`color(from color(${colorSpace} 7 -20.5 100 / 40%) ${colorSpace} x y z / 0.2)`, `color(${resultColorSpace} 7 -20.5 100 / 0.2)`); 557 560 558 561 // Testing valid permutation (types match). 559 testComputed(`color(from color(${color } 7 -20.5 100) ${color} y z x)`, `color(${resultColorSpace} -20.5 100 7)`);560 testComputed(`color(from color(${color } 7 -20.5 100) ${color} x x x / x)`, `color(${resultColorSpace} 7 7 7)`);561 testComputed(`color(from color(${color } 7 -20.5 100 / 40%) ${color} y z x)`, `color(${resultColorSpace} -20.5 100 7)`);562 testComputed(`color(from color(${color } 7 -20.5 100 / 40%) ${color} x x x / x)`, `color(${resultColorSpace} 7 7 7)`);562 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} y z x)`, `color(${resultColorSpace} -20.5 100 7)`); 563 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} x x x / x)`, `color(${resultColorSpace} 7 7 7)`); 564 testComputed(`color(from color(${colorSpace} 7 -20.5 100 / 40%) ${colorSpace} y z x)`, `color(${resultColorSpace} -20.5 100 7)`); 565 testComputed(`color(from color(${colorSpace} 7 -20.5 100 / 40%) ${colorSpace} x x x / x)`, `color(${resultColorSpace} 7 7 7)`); 563 566 564 567 // Testing invalid permutation (types don't match). 565 testComputed(`color(from color(${color } 7 -20.5 100) ${color} z alpha x / y)`, `rgba(0, 0, 0, 0)`);566 testComputed(`color(from color(${color } 7 -20.5 100) ${color} alpha alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`);567 testComputed(`color(from color(${color } 7 -20.5 100 / 40%) ${color} z alpha x / y)`, `rgba(0, 0, 0, 0)`);568 testComputed(`color(from color(${color } 7 -20.5 100 / 40%) ${color} alpha alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`);568 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} z alpha x / y)`, `rgba(0, 0, 0, 0)`); 569 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} alpha alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`); 570 testComputed(`color(from color(${colorSpace} 7 -20.5 100 / 40%) ${colorSpace} z alpha x / y)`, `rgba(0, 0, 0, 0)`); 571 testComputed(`color(from color(${colorSpace} 7 -20.5 100 / 40%) ${colorSpace} alpha alpha alpha / alpha)`, `rgba(0, 0, 0, 0)`); 569 572 570 573 // Testing with calc(). 571 testComputed(`color(from color(${color } 7 -20.5 100) ${color} calc(x) calc(y) calc(z))`, `color(${resultColorSpace} 7 -20.5 100)`);572 testComputed(`color(from color(${color } 7 -20.5 100 / 40%) ${color} calc(x) calc(y) calc(z) / calc(alpha))`, `color(${resultColorSpace} 7 -20.5 100 / 0.4)`);574 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} calc(x) calc(y) calc(z))`, `color(${resultColorSpace} 7 -20.5 100)`); 575 testComputed(`color(from color(${colorSpace} 7 -20.5 100 / 40%) ${colorSpace} calc(x) calc(y) calc(z) / calc(alpha))`, `color(${resultColorSpace} 7 -20.5 100 / 0.4)`); 573 576 574 577 // Testing invalid values. 575 testComputed(`color(from color(${color } 7 -20.5 100) ${color} 10deg y z)`, `rgba(0, 0, 0, 0)`);576 testComputed(`color(from color(${color } 7 -20.5 100) ${color} x 10deg z)`, `rgba(0, 0, 0, 0)`);577 testComputed(`color(from color(${color } 7 -20.5 100) ${color} x y 10deg)`, `rgba(0, 0, 0, 0)`);578 testComputed(`color(from color(${color } 7 -20.5 100) ${color} x y z / 10deg)`, `rgba(0, 0, 0, 0)`);578 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} 10deg y z)`, `rgba(0, 0, 0, 0)`); 579 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} x 10deg z)`, `rgba(0, 0, 0, 0)`); 580 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} x y 10deg)`, `rgba(0, 0, 0, 0)`); 581 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} x y z / 10deg)`, `rgba(0, 0, 0, 0)`); 579 582 580 583 // Testing invalid component names 581 testComputed(`color(from color(${color } 7 -20.5 100) ${color} red y)`, `rgba(0, 0, 0, 0)`);582 testComputed(`color(from color(${color } 7 -20.5 100) ${color} r y z)`, `rgba(0, 0, 0, 0)`);583 testComputed(`color(from color(${color } 7 -20.5 100) ${color} l y z)`, `rgba(0, 0, 0, 0)`);584 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} red y)`, `rgba(0, 0, 0, 0)`); 585 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} r y z)`, `rgba(0, 0, 0, 0)`); 586 testComputed(`color(from color(${colorSpace} 7 -20.5 100) ${colorSpace} l y z)`, `rgba(0, 0, 0, 0)`); 584 587 } 585 588 -
trunk/LayoutTests/imported/w3c/ChangeLog
r286174 r286191 1 2021-11-27 Sam Weinig <[email protected]> 2 3 [CSS Color 4] Add support for oklab() and oklch() colors 4 https://bugs.webkit.org/show_bug.cgi?id=233507 5 6 Reviewed by Cameron McCormack. 7 8 Add new tests for oklab() and oklch() based on the existing lab() 9 and lch() tests. 10 11 * web-platform-tests/css/css-color/oklab-001-expected.html: Added. 12 * web-platform-tests/css/css-color/oklab-001.html: Added. 13 * web-platform-tests/css/css-color/oklab-002-expected.html: Added. 14 * web-platform-tests/css/css-color/oklab-002.html: Added. 15 * web-platform-tests/css/css-color/oklab-003-expected.html: Added. 16 * web-platform-tests/css/css-color/oklab-003.html: Added. 17 * web-platform-tests/css/css-color/oklab-004-expected.html: Added. 18 * web-platform-tests/css/css-color/oklab-004.html: Added. 19 * web-platform-tests/css/css-color/oklab-005-expected.html: Added. 20 * web-platform-tests/css/css-color/oklab-005.html: Added. 21 * web-platform-tests/css/css-color/oklab-006-expected.html: Added. 22 * web-platform-tests/css/css-color/oklab-006.html: Added. 23 * web-platform-tests/css/css-color/oklab-007-expected.html: Added. 24 * web-platform-tests/css/css-color/oklab-007.html: Added. 25 * web-platform-tests/css/css-color/oklab-008-expected.html: Added. 26 * web-platform-tests/css/css-color/oklab-008.html: Added. 27 * web-platform-tests/css/css-color/oklch-001-expected.html: Added. 28 * web-platform-tests/css/css-color/oklch-001.html: Added. 29 * web-platform-tests/css/css-color/oklch-002-expected.html: Added. 30 * web-platform-tests/css/css-color/oklch-002.html: Added. 31 * web-platform-tests/css/css-color/oklch-003-expected.html: Added. 32 * web-platform-tests/css/css-color/oklch-003.html: Added. 33 * web-platform-tests/css/css-color/oklch-004-expected.html: Added. 34 * web-platform-tests/css/css-color/oklch-004.html: Added. 35 * web-platform-tests/css/css-color/oklch-005-expected.html: Added. 36 * web-platform-tests/css/css-color/oklch-005.html: Added. 37 * web-platform-tests/css/css-color/oklch-006-expected.html: Added. 38 * web-platform-tests/css/css-color/oklch-006.html: Added. 39 * web-platform-tests/css/css-color/oklch-007-expected.html: Added. 40 * web-platform-tests/css/css-color/oklch-007.html: Added. 41 * web-platform-tests/css/css-color/oklch-008-expected.html: Added. 42 * web-platform-tests/css/css-color/oklch-008.html: Added. 43 1 44 2021-11-26 Tim Nguyen <[email protected]> 2 45 -
trunk/Source/WebCore/ChangeLog
r286190 r286191 1 2021-11-27 Sam Weinig <[email protected]> 2 3 [CSS Color 4] Add support for oklab() and oklch() colors 4 https://bugs.webkit.org/show_bug.cgi?id=233507 5 6 Reviewed by Cameron McCormack. 7 8 Tests: imported/w3c/web-platform-tests/css/css-color/oklab-001.html 9 imported/w3c/web-platform-tests/css/css-color/oklab-002.html 10 imported/w3c/web-platform-tests/css/css-color/oklab-003.html 11 imported/w3c/web-platform-tests/css/css-color/oklab-004.html 12 imported/w3c/web-platform-tests/css/css-color/oklab-005.html 13 imported/w3c/web-platform-tests/css/css-color/oklab-006.html 14 imported/w3c/web-platform-tests/css/css-color/oklab-007.html 15 imported/w3c/web-platform-tests/css/css-color/oklab-008.html 16 imported/w3c/web-platform-tests/css/css-color/oklch-001.html 17 imported/w3c/web-platform-tests/css/css-color/oklch-002.html 18 imported/w3c/web-platform-tests/css/css-color/oklch-003.html 19 imported/w3c/web-platform-tests/css/css-color/oklch-004.html 20 imported/w3c/web-platform-tests/css/css-color/oklch-005.html 21 imported/w3c/web-platform-tests/css/css-color/oklch-006.html 22 imported/w3c/web-platform-tests/css/css-color/oklch-007.html 23 imported/w3c/web-platform-tests/css/css-color/oklch-008.html 24 25 Adds support for oklab() and oklch() CSS colors and as interpolation 26 parameters for color-mix(). 27 28 OKLab (and its polar form OKLCH) is a relatively new Lab-like colorspace that aims 29 to be an improved (improved hue linearity, hue uniformity, and chroma uniformity) 30 Lab. It was create by Björn Ottosson and is documented at https://bottosson.github.io/posts/oklab/. 31 32 * css/CSSValueKeywords.in: 33 Add 'oklab' and 'oklch' to the keyword list so they can be used as function 34 identifiers. Remove old mention of 'lab' in the color() function section, 35 since 'lab' is no longer a valid colorspace to use in the color() function 36 (rather, only lab() is supported). 37 38 * css/parser/CSSPropertyParserHelpers.cpp: 39 (WebCore::CSSPropertyParserHelpers::parseLabParameters): 40 (WebCore::CSSPropertyParserHelpers::parseRelativeLabParameters): 41 (WebCore::CSSPropertyParserHelpers::parseNonRelativeLabParameters): 42 (WebCore::CSSPropertyParserHelpers::parseLCHParameters): 43 (WebCore::CSSPropertyParserHelpers::parseRelativeLCHParameters): 44 (WebCore::CSSPropertyParserHelpers::parseNonRelativeLCHParameters): 45 (WebCore::CSSPropertyParserHelpers::parseColorFunction): 46 Generalize lab and lch function parsing to also support the oklab and 47 oklch variants (they have the same parsing rules). 48 49 (WebCore::CSSPropertyParserHelpers::consumeColorMixColorSpaceAndComma): 50 (WebCore::CSSPropertyParserHelpers::mixColorComponents): 51 Add support for using oklab and oklch as the interpolation space of a color-mix(). 52 This was already generalized so all it meant doing was adding mappings of the 53 new identifiers to enums and mixColorComponentsInColorSpace calls. 54 55 * platform/graphics/ColorComponents.h: 56 (WebCore::ColorComponents::subset const): 57 Fix compile error (no one had used subset yet it seems). 'std::remove_const_t<decltype(T::Size)>' 58 was likely copied from mapColorComponents() where it is templatized and needs to deduce the loop 59 variable, but that is not needed here. 60 61 * platform/graphics/ColorConversion.cpp: 62 (WebCore::convertToPolarForm): 63 (WebCore::convertToRectangularForm): 64 Move conversion to/from polar/rectangular forms from the LCHA conversion 65 code here, so that it can be reused for OKLCHA. 66 67 (WebCore::OKLab<float>>::convert): 68 Add support for converting OKLab to/from XYZ D65. Matrix values come from https://bottosson.github.io/posts/oklab/ 69 with updates from https://github.com/w3c/csswg-drafts/issues/6642#issuecomment-943521484 70 71 (WebCore::OKLCHA<float>>::convert): 72 Add support for converting OKLCHA. This is identical to the LCHA code above. 73 74 (WebCore::converColorComponents): 75 Add cases for new colorspaces. 76 77 * platform/graphics/ColorConversion.h: 78 Add converters for new colorspaces. Update diagram with them as well. 79 80 * platform/graphics/ColorMatrix.h: 81 (WebCore::ColorMatrix::transformedColorComponents const): 82 Generalize transformedColorComponents to work with any size ColorComponents object. This allows 83 the OKLab conversion code to be a bit simpler as it can operate on just the non-alpha components 84 in a more systematic way. 85 86 * platform/graphics/ColorModels.h: 87 Add new predicate template variables to help when needing to check what model a particular 88 color type uses. 89 90 * platform/graphics/ColorSerialization.cpp: 91 (WebCore::serialization): 92 (WebCore::serializationForCSS): 93 (WebCore::serializationForHTML): 94 (WebCore::serializationForRenderTreeAsText): 95 Add serialization support for new colorspaces. Also removes unused support for serializing lab 96 colors using the color(lab ...) syntax which has not been supported for some time. 97 98 * platform/graphics/ColorSpace.cpp: 99 * platform/graphics/ColorSpace.h: 100 * platform/graphics/cg/ColorSpaceCG.h: 101 Add OKLab and OKLCH to the list of enumerated colorspaces and add mappings to their 102 newly defined types OKLab<T> and OKLCHA<T>. 103 104 * platform/graphics/ColorTypes.h: 105 (WebCore::OKLab::OKLab): 106 (WebCore::OKLCHA::OKLCHA): 107 Add new types OKLab<T> and OKLCHA<T> (it looks like at some point an earlier version of this 108 must have partially landed as there were existing forward declarations). Like Lab<T> and LCHA<T>, 109 these new types use the LabModel<T> and LCHModel<T> models, but unlike them they use a whitepoint 110 of D65. 111 112 * platform/graphics/ColorUtilities.h: 113 Generalize isBlack and isWhite to have a variant that works with Lab, LCH, OKLab and OKLCH (as they 114 all are identical) using SFINAE, use the new model predicates to make this more clear. 115 1 116 2021-11-27 Alan Bujtas <[email protected]> 2 117 -
trunk/Source/WebCore/css/CSSValueKeywords.in
r286168 r286191 1285 1285 lab 1286 1286 lch 1287 oklab 1288 oklch 1287 1289 //color 1288 1290 … … 1466 1468 a98-rgb 1467 1469 display-p3 1468 // lab1469 1470 prophoto-rgb 1470 1471 // rec2020 -
trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp
r286168 r286191 1833 1833 } 1834 1834 1835 template<typename Co nsumerForLightness, typename ConsumerForAB, typename ConsumerForAlpha>1835 template<typename ColorType, typename ConsumerForLightness, typename ConsumerForAB, typename ConsumerForAlpha> 1836 1836 static Color parseLabParameters(CSSParserTokenRange& args, ConsumerForLightness&& lightnessConsumer, ConsumerForAB&& abConsumer, ConsumerForAlpha&& alphaConsumer) 1837 1837 { … … 1857 1857 auto normalizedLightness = std::max(0.0, *lightness); 1858 1858 1859 return Lab<float> { static_cast<float>(normalizedLightness), static_cast<float>(*aValue), static_cast<float>(*bValue), static_cast<float>(*alpha) }; 1860 } 1861 1859 return ColorType { static_cast<float>(normalizedLightness), static_cast<float>(*aValue), static_cast<float>(*bValue), static_cast<float>(*alpha) }; 1860 } 1861 1862 template<typename ColorType> 1862 1863 static Color parseRelativeLabParameters(CSSParserTokenRange& args, const CSSParserContext& context) 1863 1864 { … … 1869 1870 return { }; 1870 1871 1871 auto originColorAsLab = originColor.toColorTypeLossy< Lab<float>>();1872 auto originColorAsLab = originColor.toColorTypeLossy<ColorType>(); 1872 1873 1873 1874 CSSCalcSymbolTable symbolTable { … … 1882 1883 auto alphaConsumer = [&symbolTable](auto& args) { return consumeOptionalAlphaAllowingSymbolTableIdent(args, symbolTable); }; 1883 1884 1884 return parseLabParameters(args, WTFMove(lightnessConsumer), WTFMove(abConsumer), WTFMove(alphaConsumer)); 1885 } 1886 1885 return parseLabParameters<ColorType>(args, WTFMove(lightnessConsumer), WTFMove(abConsumer), WTFMove(alphaConsumer)); 1886 } 1887 1888 template<typename ColorType> 1887 1889 static Color parseNonRelativeLabParameters(CSSParserTokenRange& args) 1888 1890 { … … 1891 1893 auto alphaConsumer = [](auto& args) { return consumeOptionalAlpha(args); }; 1892 1894 1893 return parseLabParameters(args, WTFMove(lightnessConsumer), WTFMove(abConsumer), WTFMove(alphaConsumer)); 1894 } 1895 1895 return parseLabParameters<ColorType>(args, WTFMove(lightnessConsumer), WTFMove(abConsumer), WTFMove(alphaConsumer)); 1896 } 1897 1898 template<typename ColorType> 1896 1899 static Color parseLabParameters(CSSParserTokenRange& range, const CSSParserContext& context) 1897 1900 { 1898 ASSERT(range.peek().functionId() == CSSValueLab );1901 ASSERT(range.peek().functionId() == CSSValueLab || range.peek().functionId() == CSSValueOklab); 1899 1902 1900 1903 if (!context.cssColor4) … … 1904 1907 1905 1908 if (context.relativeColorSyntaxEnabled && args.peek().id() == CSSValueFrom) 1906 return parseRelativeLabParameters (args, context);1907 return parseNonRelativeLabParameters (args);1908 } 1909 1910 template<typename Co nsumerForLightness, typename ConsumerForChroma, typename ConsumerForHue, typename ConsumerForAlpha>1909 return parseRelativeLabParameters<ColorType>(args, context); 1910 return parseNonRelativeLabParameters<ColorType>(args); 1911 } 1912 1913 template<typename ColorType, typename ConsumerForLightness, typename ConsumerForChroma, typename ConsumerForHue, typename ConsumerForAlpha> 1911 1914 static Color parseLCHParameters(CSSParserTokenRange& args, ConsumerForLightness&& lightnessConsumer, ConsumerForChroma&& chromaConsumer, ConsumerForHue&& hueConsumer, ConsumerForAlpha&& alphaConsumer) 1912 1915 { … … 1934 1937 auto normalizedHue = normalizeHue(*hue); 1935 1938 1936 return LCHA<float> { static_cast<float>(normalizedLightness), static_cast<float>(normalizedChroma), static_cast<float>(normalizedHue), static_cast<float>(*alpha) }; 1937 } 1938 1939 return ColorType { static_cast<float>(normalizedLightness), static_cast<float>(normalizedChroma), static_cast<float>(normalizedHue), static_cast<float>(*alpha) }; 1940 } 1941 1942 template<typename ColorType> 1939 1943 static Color parseRelativeLCHParameters(CSSParserTokenRange& args, const CSSParserContext& context) 1940 1944 { … … 1946 1950 return { }; 1947 1951 1948 auto originColorAsLCH = originColor.toColorTypeLossy< LCHA<float>>();1952 auto originColorAsLCH = originColor.toColorTypeLossy<ColorType>(); 1949 1953 1950 1954 CSSCalcSymbolTable symbolTable { … … 1960 1964 auto alphaConsumer = [&symbolTable](auto& args) { return consumeOptionalAlphaAllowingSymbolTableIdent(args, symbolTable); }; 1961 1965 1962 return parseLCHParameters(args, WTFMove(lightnessConsumer), WTFMove(chromaConsumer), WTFMove(hueConsumer), WTFMove(alphaConsumer)); 1963 } 1964 1966 return parseLCHParameters<ColorType>(args, WTFMove(lightnessConsumer), WTFMove(chromaConsumer), WTFMove(hueConsumer), WTFMove(alphaConsumer)); 1967 } 1968 1969 template<typename ColorType> 1965 1970 static Color parseNonRelativeLCHParameters(CSSParserTokenRange& args, const CSSParserContext& context) 1966 1971 { … … 1970 1975 auto alphaConsumer = [](auto& args) { return consumeOptionalAlpha(args); }; 1971 1976 1972 return parseLCHParameters(args, WTFMove(lightnessConsumer), WTFMove(chromaConsumer), WTFMove(hueConsumer), WTFMove(alphaConsumer)); 1973 } 1974 1977 return parseLCHParameters<ColorType>(args, WTFMove(lightnessConsumer), WTFMove(chromaConsumer), WTFMove(hueConsumer), WTFMove(alphaConsumer)); 1978 } 1979 1980 template<typename ColorType> 1975 1981 static Color parseLCHParameters(CSSParserTokenRange& range, const CSSParserContext& context) 1976 1982 { 1977 ASSERT(range.peek().functionId() == CSSValueLch );1983 ASSERT(range.peek().functionId() == CSSValueLch || range.peek().functionId() == CSSValueOklch); 1978 1984 1979 1985 if (!context.cssColor4) … … 1983 1989 1984 1990 if (context.relativeColorSyntaxEnabled && args.peek().id() == CSSValueFrom) 1985 return parseRelativeLCHParameters (args, context);1986 return parseNonRelativeLCHParameters (args, context);1991 return parseRelativeLCHParameters<ColorType>(args, context); 1992 return parseNonRelativeLCHParameters<ColorType>(args, context); 1987 1993 } 1988 1994 … … 2290 2296 Lab, 2291 2297 Lch, 2298 Oklab, 2299 Oklch, 2292 2300 Srgb, 2293 2301 XyzD50, … … 2313 2321 case CSSValueLch: 2314 2322 return consumeIdentAndComma(args, ColorMixColorSpace::Lch); 2323 case CSSValueOklab: 2324 return consumeIdentAndComma(args, ColorMixColorSpace::Oklab); 2325 case CSSValueOklch: 2326 return consumeIdentAndComma(args, ColorMixColorSpace::Oklch); 2315 2327 case CSSValueSRGB: 2316 2328 return consumeIdentAndComma(args, ColorMixColorSpace::Srgb); … … 2468 2480 case ColorMixColorSpace::Lch: 2469 2481 return mixColorComponentsInColorSpace<LCHA<float>>(mixPercentages, mixComponents1.color, mixComponents2.color); 2482 case ColorMixColorSpace::Oklab: 2483 return mixColorComponentsInColorSpace<OKLab<float>>(mixPercentages, mixComponents1.color, mixComponents2.color); 2484 case ColorMixColorSpace::Oklch: 2485 return mixColorComponentsInColorSpace<OKLCHA<float>>(mixPercentages, mixComponents1.color, mixComponents2.color); 2470 2486 case ColorMixColorSpace::Srgb: 2471 2487 return mixColorComponentsInColorSpace<SRGBA<float>>(mixPercentages, mixComponents1.color, mixComponents2.color); … … 2575 2591 break; 2576 2592 case CSSValueLab: 2577 color = parseLabParameters (colorRange, context);2593 color = parseLabParameters<Lab<float>>(colorRange, context); 2578 2594 break; 2579 2595 case CSSValueLch: 2580 color = parseLCHParameters(colorRange, context); 2596 color = parseLCHParameters<LCHA<float>>(colorRange, context); 2597 break; 2598 case CSSValueOklab: 2599 color = parseLabParameters<OKLab<float>>(colorRange, context); 2600 break; 2601 case CSSValueOklch: 2602 color = parseLCHParameters<OKLCHA<float>>(colorRange, context); 2581 2603 break; 2582 2604 case CSSValueColor: -
trunk/Source/WebCore/platform/graphics/ColorComponents.h
r279240 r286191 136 136 { 137 137 ColorComponents<T, End - Start> result; 138 for (s td::remove_const_t<decltype(T::Size)>i = Start; i < End; ++i)138 for (size_t i = Start; i < End; ++i) 139 139 result[i - Start] = components[i]; 140 140 return result; -
trunk/Source/WebCore/platform/graphics/ColorConversion.cpp
r286187 r286191 34 34 namespace WebCore { 35 35 36 // MARK: Lab-Like to LCH-Like conversion utilities. 37 38 template<typename LCHLike, typename LabLike> 39 LCHLike convertToPolarForm(const LabLike& color) 40 { 41 // https://drafts.csswg.org/css-color/#lab-to-lch 42 float hue = rad2deg(atan2(color.b, color.a)); 43 44 return { 45 color.lightness, 46 std::hypot(color.a, color.b), 47 hue >= 0 ? hue : hue + 360, 48 color.alpha 49 }; 50 } 51 52 template<typename LabLike, typename LCHLike> 53 LabLike convertToRectangularForm(const LCHLike& color) 54 { 55 // https://drafts.csswg.org/css-color/#lch-to-lab 56 float hueAngleRadians = deg2rad(color.hue); 57 58 return { 59 color.lightness, 60 color.chroma * std::cos(hueAngleRadians), 61 color.chroma * std::sin(hueAngleRadians), 62 color.alpha 63 }; 64 } 65 36 66 // MARK: HSL conversions. 37 67 … … 245 275 } 246 276 247 248 277 // MARK: LCH conversions. 249 278 250 279 LCHA<float> ColorConversion<LCHA<float>, Lab<float>>::convert(const Lab<float>& color) 251 280 { 252 // https://www.w3.org/TR/css-color-4/#lab-to-lch 253 float hue = rad2deg(atan2(color.b, color.a)); 254 255 return { 256 color.lightness, 257 std::hypot(color.a, color.b), 258 hue >= 0 ? hue : hue + 360, 259 color.alpha 260 }; 281 return convertToPolarForm<LCHA<float>>(color); 261 282 } 262 283 263 284 Lab<float> ColorConversion<Lab<float>, LCHA<float>>::convert(const LCHA<float>& color) 264 285 { 265 // https://www.w3.org/TR/css-color-4/#lch-to-lab 266 float hueAngleRadians = deg2rad(color.hue); 267 268 return { 269 color.lightness, 270 color.chroma * std::cos(hueAngleRadians), 271 color.chroma * std::sin(hueAngleRadians), 272 color.alpha 273 }; 286 return convertToRectangularForm<Lab<float>>(color); 287 } 288 289 // MARK: OKLab conversions. 290 291 XYZA<float, WhitePoint::D65> ColorConversion<XYZA<float, WhitePoint::D65>, OKLab<float>>::convert(const OKLab<float>& color) 292 { 293 // FIXME: This could be optimized for when we are not explicitly converting to XYZ-D65 by pre-multiplying the 'LMSToXYZD65' 294 // matrix with any subsequent matrices in the conversion. This would mean teaching the main conversion about this matrix 295 // and adding new logic for this transform. 296 297 // https://bottosson.github.io/posts/oklab/ with XYZ <-> LMS matrices recalculated for consistent reference white in https://github.com/w3c/csswg-drafts/issues/6642#issuecomment-943521484 298 299 static constexpr ColorMatrix<3, 3> LinearLMSToXYZD65 { 300 1.2268798733741557f, -0.5578149965554813f, 0.28139105017721583f, 301 -0.04057576262431372f, 1.1122868293970594f, -0.07171106666151701f, 302 -0.07637294974672142f, -0.4214933239627914f, 1.5869240244272418f 303 }; 304 305 static constexpr ColorMatrix<3, 3> OKLabToNonLinearLMS { 306 0.99999999845051981432f, 0.39633779217376785678f, 0.21580375806075880339f, 307 1.0000000088817607767f, -0.1055613423236563494f, -0.063854174771705903402f, 308 1.0000000546724109177f, -0.089484182094965759684f, -1.2914855378640917399f 309 }; 310 311 // 1. Transform from precentage lightness to unit lightness. 312 auto components = asColorComponents(color).subset<0, 3>(); 313 components[0] = components[0] / 100.0f; 314 315 // 2. Transform from Lab-coordinates into non-linear LMS "approximate cone responses". 316 auto nonLinearLMS = OKLabToNonLinearLMS.transformedColorComponents(components); 317 318 // 3. Apply linearity. 319 auto linearLMS = nonLinearLMS.map([] (float v) { return v * v * v; }); 320 321 // 4. Convert to XYZ. 322 auto [x, y, z] = LinearLMSToXYZD65.transformedColorComponents(linearLMS); 323 324 return { x, y, z, color.alpha }; 325 } 326 327 OKLab<float> ColorConversion<OKLab<float>, XYZA<float, WhitePoint::D65>>::convert(const XYZA<float, WhitePoint::D65>& color) 328 { 329 // FIXME: This could be optimized for when we are not explicitly converting from XYZ-D65 by pre-multiplying the 'XYZD65ToLMS' 330 // matrix with any previous matrices in the conversion. This would mean teaching the main conversion about this matrix 331 // and adding new logic for this transform. 332 333 // https://bottosson.github.io/posts/oklab/ with XYZ <-> LMS matrices recalculated for consistent reference white in https://github.com/w3c/csswg-drafts/issues/6642#issuecomment-943521484 334 335 static constexpr ColorMatrix<3, 3> XYZD65ToLinearLMS { 336 0.8190224432164319f, 0.3619062562801221f, -0.12887378261216414f, 337 0.0329836671980271f, 0.9292868468965546f, 0.03614466816999844f, 338 0.048177199566046255f, 0.26423952494422764f, 0.6335478258136937f 339 }; 340 341 static constexpr ColorMatrix<3, 3> NonLinearLMSToOKLab { 342 0.2104542553f, 0.7936177850f, -0.0040720468f, 343 1.9779984951f, -2.4285922050f, 0.4505937099f, 344 0.0259040371f, 0.7827717662f, -0.8086757660f 345 }; 346 347 // 1. Convert XYZ into LMS "approximate cone responses". 348 auto linearLMS = XYZD65ToLinearLMS.transformedColorComponents(asColorComponents(color).subset<0, 3>()); 349 350 // 2. Apply non-linearity. 351 auto nonLinearLMS = linearLMS.map([] (float v) { return std::cbrt(v); }); 352 353 // 3. Transform into Lab-coordinates. 354 auto [lightness, a, b] = NonLinearLMSToOKLab.transformedColorComponents(nonLinearLMS); 355 356 // 4. Transform lightness from unit lightness to percentage lightness. 357 return { lightness * 100.0f, a, b, color.alpha }; 358 } 359 360 // MARK: OKLCH conversions. 361 362 OKLCHA<float> ColorConversion<OKLCHA<float>, OKLab<float>>::convert(const OKLab<float>& color) 363 { 364 return convertToPolarForm<OKLCHA<float>>(color); 365 } 366 367 OKLab<float> ColorConversion<OKLab<float>, OKLCHA<float>>::convert(const OKLCHA<float>& color) 368 { 369 return convertToRectangularForm<OKLab<float>>(color); 274 370 } 275 371 … … 290 386 case ColorSpace::LinearSRGB: 291 387 return asColorComponents(convertColor<LinearSRGBA<float>>(inputColor)); 388 case ColorSpace::OKLCH: 389 return asColorComponents(convertColor<OKLCHA<float>>(inputColor)); 390 case ColorSpace::OKLab: 391 return asColorComponents(convertColor<OKLab<float>>(inputColor)); 292 392 case ColorSpace::ProPhotoRGB: 293 393 return asColorComponents(convertColor<ProPhotoRGB<float>>(inputColor)); -
trunk/Source/WebCore/platform/graphics/ColorConversion.h
r286187 r286191 115 115 }; 116 116 117 // MARK: OKLCHA 118 template<> struct ColorConversion<OKLab<float>, OKLCHA<float>> { 119 WEBCORE_EXPORT static OKLab<float> convert(const OKLCHA<float>&); 120 }; 121 template<> struct ColorConversion<OKLCHA<float>, OKLab<float>> { 122 WEBCORE_EXPORT static OKLCHA<float> convert(const OKLab<float>&); 123 }; 124 125 // MARK: OKLab 126 template<> struct ColorConversion<XYZA<float, WhitePoint::D65>, OKLab<float>> { 127 WEBCORE_EXPORT static XYZA<float, WhitePoint::D65> convert(const OKLab<float>&); 128 }; 129 template<> struct ColorConversion<OKLab<float>, XYZA<float, WhitePoint::D65>> { 130 WEBCORE_EXPORT static OKLab<float> convert(const XYZA<float, WhitePoint::D65>&); 131 }; 132 117 133 // Identity conversion. 118 134 … … 132 148 // └─────▲─────┘│└─────▲─────┘ 133 149 // │ │ │ │ │ 134 // ┌─────────────────────────┬───────────┘ │ └───────────┬───────────────────────────────┬───────────────────────────────┬─────────────────────────────── ┐135 // │ │ │ │ │ │ │ │ │ 136 // │ │ │ │ │ │ │ 137 // │ │ │ │ │ │ │ │ │ 138 // │ ProPhotoRGB───────────────────┐ │ SRGB──────────────────────────┐ DisplayP3─────────────────────┐ A98RGB────────────────────────┐ Rec2020───────────────────────┐ 139 // │ │ │┌────────┐ ┌────────────────┐│ │ │┌────────┐ ┌────────────────┐│ │┌────────┐ ┌────────────────┐│ │┌────────┐ ┌────────────────┐│ │┌────────┐ ┌────────────────┐│ │ 140 // │ ││ Linear │ │ LinearExtended ││ │ ││ Linear │ │ LinearExtended ││ ││ Linear │ │ LinearExtended ││ ││ Linear │ │ LinearExtended ││ ││ Linear │ │ LinearExtended ││ 141 // │ │ │└────────┘ └────────────────┘│ │ │└────────┘ └────────────────┘│ │└────────┘ └────────────────┘│ │└────────┘ └────────────────┘│ │└────────┘ └────────────────┘│ │ 142 // │ ─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─ ─│─ ─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─ 143 // ┌───────────┐ │┌────────┐ ┌────────────────┐│ │ │┌────────┐ ┌────────────────┐│ │┌────────┐ ┌────────────────┐│ │┌────────┐ ┌────────────────┐│ │┌────────┐ ┌────────────────┐│ 144 // │ Lab │ ││ Gamma │ │ GammaExtended ││ │ ││ Gamma │ │ GammaExtended ││ ││ Gamma │ │ GammaExtended ││ ││ Gamma │ │ GammaExtended ││ ││ Gamma │ │ GammaExtended ││ 145 // └─────▲─────┘ │└────────┘ └────────────────┘│ │ │└────▲───┘ └────────────────┘│ │└────────┘ └────────────────┘│ │└────────┘ └────────────────┘│ │└────────┘ └────────────────┘│ 146 // │ └─────────────────────────────┘ │ └─────┼───────────────────────┘ └─────────────────────────────┘ └─────────────────────────────┘ └─────────────────────────────┘ 147 // │ │ ┌──┴──────────┐ 148 // │ │ │ │ 149 // ┌───────────┐ │┌───────────┐ ┌───────────┐ 150 // │ LCH │ ││ HSL │ │ HWB │ 151 // └───────────┘ │└───────────┘ └───────────┘ 150 // ┌─────────────────────────┬───────────┘ │ └───────────┬───────────────────────────────┬───────────────────────────────┬───────────────────────────────┬─────────────────────────┐ 151 // │ │ │ │ │ │ │ │ │ │ 152 // │ │ │ │ │ │ │ │ 153 // │ │ │ │ │ │ │ │ │ │ 154 // │ ProPhotoRGB───────────────────┐ │ SRGB──────────────────────────┐ DisplayP3─────────────────────┐ A98RGB────────────────────────┐ Rec2020───────────────────────┐ │ 155 // │ │ │┌────────┐ ┌────────────────┐│ │ │┌────────┐ ┌────────────────┐│ │┌────────┐ ┌────────────────┐│ │┌────────┐ ┌────────────────┐│ │┌────────┐ ┌────────────────┐│ │ │ 156 // │ ││ Linear │ │ LinearExtended ││ │ ││ Linear │ │ LinearExtended ││ ││ Linear │ │ LinearExtended ││ ││ Linear │ │ LinearExtended ││ ││ Linear │ │ LinearExtended ││ │ 157 // │ │ │└────────┘ └────────────────┘│ │ │└────────┘ └────────────────┘│ │└────────┘ └────────────────┘│ │└────────┘ └────────────────┘│ │└────────┘ └────────────────┘│ │ │ 158 // │ ─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─ ─│─ ─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─ │ 159 // ┌───────────┐ │┌────────┐ ┌────────────────┐│ │ │┌────────┐ ┌────────────────┐│ │┌────────┐ ┌────────────────┐│ │┌────────┐ ┌────────────────┐│ │┌────────┐ ┌────────────────┐│ ┌───────────┐ 160 // │ Lab │ ││ Gamma │ │ GammaExtended ││ │ ││ Gamma │ │ GammaExtended ││ ││ Gamma │ │ GammaExtended ││ ││ Gamma │ │ GammaExtended ││ ││ Gamma │ │ GammaExtended ││ │ OKLab │ 161 // └─────▲─────┘ │└────────┘ └────────────────┘│ │ │└────▲───┘ └────────────────┘│ │└────────┘ └────────────────┘│ │└────────┘ └────────────────┘│ │└────────┘ └────────────────┘│ └─────▲─────┘ 162 // │ └─────────────────────────────┘ │ └─────┼───────────────────────┘ └─────────────────────────────┘ └─────────────────────────────┘ └─────────────────────────────┘ │ 163 // │ │ ┌──┴──────────┐ │ 164 // │ │ │ │ │ 165 // ┌───────────┐ │┌───────────┐ ┌───────────┐ ┌───────────┐ 166 // │ LCH │ ││ HSL │ │ HWB │ │ OKLCH │ 167 // └───────────┘ │└───────────┘ └───────────┘ └───────────┘ 152 168 153 169 template<typename Output, typename Input, typename> struct ColorConversion { -
trunk/Source/WebCore/platform/graphics/ColorMatrix.h
r275206 r286191 43 43 } 44 44 45 constexpr ColorComponents<float, 4> transformedColorComponents(const ColorComponents<float, 4>&) const; 45 template<size_t NumberOfComponents> 46 constexpr ColorComponents<float, NumberOfComponents> transformedColorComponents(const ColorComponents<float, NumberOfComponents>&) const; 46 47 47 48 constexpr float at(size_t row, size_t column) const … … 121 122 122 123 template<size_t ColumnCount, size_t RowCount> 123 constexpr ColorComponents<float, 4> ColorMatrix<ColumnCount, RowCount>::transformedColorComponents(const ColorComponents<float, 4>& inputVector) const 124 template<size_t NumberOfComponents> 125 constexpr auto ColorMatrix<ColumnCount, RowCount>::transformedColorComponents(const ColorComponents<float, NumberOfComponents>& inputVector) const -> ColorComponents<float, NumberOfComponents> 124 126 { 125 static_assert(ColorComponents<float, 4>::Size >= RowCount);127 static_assert(ColorComponents<float, NumberOfComponents>::Size >= RowCount); 126 128 127 ColorComponents<float, 4> result;129 ColorComponents<float, NumberOfComponents> result; 128 130 for (size_t row = 0; row < RowCount; ++row) { 129 if constexpr (ColumnCount <= ColorComponents<float, 4>::Size) {131 if constexpr (ColumnCount <= ColorComponents<float, NumberOfComponents>::Size) { 130 132 for (size_t column = 0; column < ColumnCount; ++column) 131 133 result[row] += at(row, column) * inputVector[column]; 132 } else if constexpr (ColumnCount > ColorComponents<float, 4>::Size) {133 for (size_t column = 0; column < ColorComponents<float, 4>::Size; ++column)134 } else if constexpr (ColumnCount > ColorComponents<float, NumberOfComponents>::Size) { 135 for (size_t column = 0; column < ColorComponents<float, NumberOfComponents>::Size; ++column) 134 136 result[row] += at(row, column) * inputVector[column]; 135 for (size_t additionalColumn = ColorComponents<float, 4>::Size; additionalColumn < ColumnCount; ++additionalColumn)137 for (size_t additionalColumn = ColorComponents<float, NumberOfComponents>::Size; additionalColumn < ColumnCount; ++additionalColumn) 136 138 result[row] += at(row, additionalColumn); 137 139 } 138 140 } 139 if constexpr (ColorComponents<float, 4>::Size > RowCount) {140 for (size_t additionalRow = RowCount; additionalRow < ColorComponents<float, 4>::Size; ++additionalRow)141 if constexpr (ColorComponents<float, NumberOfComponents>::Size > RowCount) { 142 for (size_t additionalRow = RowCount; additionalRow < ColorComponents<float, NumberOfComponents>::Size; ++additionalRow) 141 143 result[additionalRow] = inputVector[additionalRow]; 142 144 } -
trunk/Source/WebCore/platform/graphics/ColorModels.h
r274947 r286191 73 73 }; 74 74 75 template<typename ColorType> inline constexpr bool UsesExtendedRGBModel = std::is_same_v<typename ColorType::Model, ExtendedRGBModel<typename ColorType::ComponentType>>; 76 75 77 template<> struct HSLModel<float> { 76 78 static constexpr std::array<ColorComponentInfo<float>, 3> componentInfo { { … … 81 83 static constexpr bool isInvertible = false; 82 84 }; 85 86 template<typename ColorType> inline constexpr bool UsesHSLModel = std::is_same_v<typename ColorType::Model, HSLModel<typename ColorType::ComponentType>>; 83 87 84 88 template<> struct HWBModel<float> { … … 91 95 }; 92 96 97 template<typename ColorType> inline constexpr bool UsesHWBModel = std::is_same_v<typename ColorType::Model, HWBModel<typename ColorType::ComponentType>>; 98 93 99 template<> struct LabModel<float> { 94 100 static constexpr std::array<ColorComponentInfo<float>, 3> componentInfo { { … … 100 106 }; 101 107 108 template<typename ColorType> inline constexpr bool UsesLabModel = std::is_same_v<typename ColorType::Model, LabModel<typename ColorType::ComponentType>>; 109 102 110 template<> struct LCHModel<float> { 103 111 static constexpr std::array<ColorComponentInfo<float>, 3> componentInfo { { … … 108 116 static constexpr bool isInvertible = false; 109 117 }; 118 119 template<typename ColorType> inline constexpr bool UsesLCHModel = std::is_same_v<typename ColorType::Model, LCHModel<typename ColorType::ComponentType>>; 110 120 111 121 template<> struct RGBModel<float> { … … 127 137 }; 128 138 139 template<typename ColorType> inline constexpr bool UsesRGBModel = std::is_same_v<typename ColorType::Model, RGBModel<typename ColorType::ComponentType>>; 140 129 141 template<> struct XYZModel<float> { 130 142 static constexpr std::array<ColorComponentInfo<float>, 3> componentInfo { { … … 136 148 }; 137 149 150 template<typename ColorType> inline constexpr bool UsesXYZModel = std::is_same_v<typename ColorType::Model, XYZModel<typename ColorType::ComponentType>>; 151 138 152 } -
trunk/Source/WebCore/platform/graphics/ColorSerialization.cpp
r286168 r286191 56 56 static String serializationForRenderTreeAsText(const LinearSRGBA<float>&, bool useColorFunctionSerialization); 57 57 58 static String serializationForCSS(const OKLCHA<float>&, bool useColorFunctionSerialization); 59 static String serializationForHTML(const OKLCHA<float>&, bool useColorFunctionSerialization); 60 static String serializationForRenderTreeAsText(const OKLCHA<float>&, bool useColorFunctionSerialization); 61 62 static String serializationForCSS(const OKLab<float>&, bool useColorFunctionSerialization); 63 static String serializationForHTML(const OKLab<float>&, bool useColorFunctionSerialization); 64 static String serializationForRenderTreeAsText(const OKLab<float>&, bool useColorFunctionSerialization); 65 58 66 static String serializationForCSS(const ProPhotoRGB<float>&, bool useColorFunctionSerialization); 59 67 static String serializationForHTML(const ProPhotoRGB<float>&, bool useColorFunctionSerialization); … … 115 123 case ColorSpace::LinearSRGB: 116 124 return "srgb-linear"_s; 125 case ColorSpace::OKLCH: 126 return "oklch"_s; 127 case ColorSpace::OKLab: 128 return "oklab"_s; 117 129 case ColorSpace::ProPhotoRGB: 118 130 return "prophoto-rgb"_s; … … 141 153 } 142 154 143 static String serializationUsingColorFunction(const Lab<float>& color)144 {145 auto [c1, c2, c3, alpha] = color;146 if (WTF::areEssentiallyEqual(alpha, 1.0f))147 return makeString("color(", serialization(ColorSpaceFor<Lab<float>>), ' ', c1, "% ", c2, ' ', c3, ')');148 return makeString("color(", serialization(ColorSpaceFor<Lab<float>>), ' ', c1, "% ", c2, ' ', c3, " / ", alpha, ')');149 }150 151 155 static String serializationUsingColorFunction(const SRGBA<uint8_t>& color) 152 156 { … … 190 194 // MARK: LCHA<float> overloads 191 195 192 String serializationForCSS(const LCHA<float>& color, bool useColorFunctionSerialization)196 String serializationForCSS(const LCHA<float>& color, bool) 193 197 { 194 198 // https://www.w3.org/TR/css-color-4/#serializing-lab-lch 195 if (useColorFunctionSerialization)196 return serializationUsingColorFunction(color);197 198 199 auto [c1, c2, c3, alpha] = color; 199 200 if (WTF::areEssentiallyEqual(alpha, 1.0f)) … … 214 215 // MARK: Lab<float> overloads 215 216 216 String serializationForCSS(const Lab<float>& color, bool useColorFunctionSerialization)217 String serializationForCSS(const Lab<float>& color, bool) 217 218 { 218 219 // https://www.w3.org/TR/css-color-4/#serializing-lab-lch 219 if (useColorFunctionSerialization)220 return serializationUsingColorFunction(color);221 222 220 auto [c1, c2, c3, alpha] = color; 223 221 if (WTF::areEssentiallyEqual(alpha, 1.0f)) … … 251 249 { 252 250 return serializationUsingColorFunction(color); 251 } 252 253 // MARK: OKLCHA<float> overloads 254 255 String serializationForCSS(const OKLCHA<float>& color, bool) 256 { 257 auto [c1, c2, c3, alpha] = color; 258 if (WTF::areEssentiallyEqual(alpha, 1.0f)) 259 return makeString("oklch(", c1, "% ", c2, ' ', c3, ')'); 260 return makeString("oklch(", c1, "% ", c2, ' ', c3, " / ", alpha, ')'); 261 } 262 263 String serializationForHTML(const OKLCHA<float>& color, bool useColorFunctionSerialization) 264 { 265 return serializationForCSS(color, useColorFunctionSerialization); 266 } 267 268 String serializationForRenderTreeAsText(const OKLCHA<float>& color, bool useColorFunctionSerialization) 269 { 270 return serializationForCSS(color, useColorFunctionSerialization); 271 } 272 273 // MARK: OKLab<float> overloads 274 275 String serializationForCSS(const OKLab<float>& color, bool) 276 { 277 auto [c1, c2, c3, alpha] = color; 278 if (WTF::areEssentiallyEqual(alpha, 1.0f)) 279 return makeString("oklab(", c1, "% ", c2, ' ', c3, ')'); 280 return makeString("oklab(", c1, "% ", c2, ' ', c3, " / ", alpha, ')'); 281 } 282 283 String serializationForHTML(const OKLab<float>& color, bool useColorFunctionSerialization) 284 { 285 return serializationForCSS(color, useColorFunctionSerialization); 286 } 287 288 String serializationForRenderTreeAsText(const OKLab<float>& color, bool useColorFunctionSerialization) 289 { 290 return serializationForCSS(color, useColorFunctionSerialization); 253 291 } 254 292 -
trunk/Source/WebCore/platform/graphics/ColorSpace.cpp
r286168 r286191 35 35 switch (colorSpace) { 36 36 case ColorSpace::A98RGB: 37 ts << " a98-rgb";37 ts << "A98-RGB"; 38 38 break; 39 39 case ColorSpace::DisplayP3: … … 44 44 break; 45 45 case ColorSpace::Lab: 46 ts << "L *a*b";46 ts << "Lab"; 47 47 break; 48 48 case ColorSpace::LinearSRGB: 49 49 ts << "LinearSRGB"; 50 break; 51 case ColorSpace::OKLCH: 52 ts << "OKLCH"; 53 break; 54 case ColorSpace::OKLab: 55 ts << "OKLab"; 50 56 break; 51 57 case ColorSpace::ProPhotoRGB: -
trunk/Source/WebCore/platform/graphics/ColorSpace.h
r286168 r286191 39 39 Lab, 40 40 LinearSRGB, 41 OKLCH, 42 OKLab, 41 43 ProPhotoRGB, 42 44 Rec2020, … … 55 57 template<typename T> struct ColorSpaceMapping<Lab<T>> { static constexpr auto colorSpace { ColorSpace::Lab }; }; 56 58 template<typename T> struct ColorSpaceMapping<LinearSRGBA<T>> { static constexpr auto colorSpace { ColorSpace::LinearSRGB }; }; 59 template<typename T> struct ColorSpaceMapping<OKLab<T>> { static constexpr auto colorSpace { ColorSpace::OKLab }; }; 60 template<typename T> struct ColorSpaceMapping<OKLCHA<T>> { static constexpr auto colorSpace { ColorSpace::OKLCH }; }; 57 61 template<typename T> struct ColorSpaceMapping<ProPhotoRGB<T>> { static constexpr auto colorSpace { ColorSpace::ProPhotoRGB }; }; 58 62 template<typename T> struct ColorSpaceMapping<Rec2020<T>> { static constexpr auto colorSpace { ColorSpace::Rec2020 }; }; … … 77 81 case ColorSpace::LinearSRGB: 78 82 return std::invoke(std::forward<Functor>(functor), makeFromComponents<LinearSRGBA<T>>(components)); 83 case ColorSpace::OKLCH: 84 return std::invoke(std::forward<Functor>(functor), makeFromComponents<OKLCHA<T>>(components)); 85 case ColorSpace::OKLab: 86 return std::invoke(std::forward<Functor>(functor), makeFromComponents<OKLab<T>>(components)); 79 87 case ColorSpace::ProPhotoRGB: 80 88 return std::invoke(std::forward<Functor>(functor), makeFromComponents<ProPhotoRGB<T>>(components)); … … 106 114 WebCore::ColorSpace::Lab, 107 115 WebCore::ColorSpace::LinearSRGB, 116 WebCore::ColorSpace::OKLCH, 117 WebCore::ColorSpace::OKLab, 108 118 WebCore::ColorSpace::ProPhotoRGB, 109 119 WebCore::ColorSpace::Rec2020, -
trunk/Source/WebCore/platform/graphics/ColorTypes.h
r278070 r286191 43 43 template<typename> struct LCHA; 44 44 template<typename> struct Lab; 45 template<typename> struct O klab;46 template<typename> struct O klch;45 template<typename> struct OKLCHA; 46 template<typename> struct OKLab; 47 47 template<typename, WhitePoint> struct XYZA; 48 48 … … 196 196 using TransferFunction = TF; 197 197 using Descriptor = D; 198 static constexpr WhitePointwhitePoint = D::whitePoint;198 static constexpr auto whitePoint = D::whitePoint; 199 199 200 200 constexpr RGBAType(T red, T green, T blue, T alpha = AlphaTraits<T>::opaque) … … 300 300 struct SRGBADescriptor { 301 301 template<typename T, TransferFunctionMode Mode> using TransferFunction = SRGBTransferFunction<T, Mode>; 302 static constexpr WhitePointwhitePoint = WhitePoint::D65;302 static constexpr auto whitePoint = WhitePoint::D65; 303 303 304 304 // https://drafts.csswg.org/css-color/#color-conversion-code … … 323 323 struct A98RGBDescriptor { 324 324 template<typename T, TransferFunctionMode Mode> using TransferFunction = A98RGBTransferFunction<T, Mode>; 325 static constexpr WhitePointwhitePoint = WhitePoint::D65;325 static constexpr auto whitePoint = WhitePoint::D65; 326 326 327 327 // https://drafts.csswg.org/css-color/#color-conversion-code … … 344 344 struct DisplayP3Descriptor { 345 345 template<typename T, TransferFunctionMode Mode> using TransferFunction = SRGBTransferFunction<T, Mode>; 346 static constexpr WhitePointwhitePoint = WhitePoint::D65;346 static constexpr auto whitePoint = WhitePoint::D65; 347 347 348 348 // https://drafts.csswg.org/css-color/#color-conversion-code … … 365 365 struct ProPhotoRGBDescriptor { 366 366 template<typename T, TransferFunctionMode Mode> using TransferFunction = ProPhotoRGBTransferFunction<T, Mode>; 367 static constexpr WhitePointwhitePoint = WhitePoint::D50;367 static constexpr auto whitePoint = WhitePoint::D50; 368 368 369 369 // https://drafts.csswg.org/css-color/#color-conversion-code … … 386 386 struct Rec2020Descriptor { 387 387 template<typename T, TransferFunctionMode Mode> using TransferFunction = Rec2020TransferFunction<T, Mode>; 388 static constexpr WhitePointwhitePoint = WhitePoint::D65;388 static constexpr auto whitePoint = WhitePoint::D65; 389 389 390 390 // https://drafts.csswg.org/css-color/#color-conversion-code … … 410 410 using ComponentType = T; 411 411 using Model = LabModel<T>; 412 static constexpr WhitePointwhitePoint = WhitePoint::D50;413 using Reference = XYZA<T, whitePoint>;412 static constexpr auto whitePoint = WhitePoint::D50; 413 using Reference = XYZA<T, whitePoint>; 414 414 415 415 constexpr Lab(T lightness, T a, T b, T alpha = AlphaTraits<T>::opaque) … … 445 445 using ComponentType = T; 446 446 using Model = LCHModel<T>; 447 static constexpr WhitePointwhitePoint = WhitePoint::D50;447 static constexpr auto whitePoint = WhitePoint::D50; 448 448 using Reference = Lab<T>; 449 449 … … 475 475 template<typename ColorType> inline constexpr bool IsLCHA = std::is_same_v<LCHA<typename ColorType::ComponentType>, ColorType>; 476 476 477 // MARK: - OKLab Color Type. 478 479 template<typename T> struct OKLab : ColorWithAlphaHelper<OKLab<T>> { 480 using ComponentType = T; 481 using Model = LabModel<T>; 482 static constexpr auto whitePoint = WhitePoint::D65; 483 using Reference = XYZA<T, whitePoint>; 484 485 constexpr OKLab(T lightness, T a, T b, T alpha = AlphaTraits<T>::opaque) 486 : lightness { lightness } 487 , a { a } 488 , b { b } 489 , alpha { alpha } 490 { 491 assertInRange(*this); 492 } 493 494 constexpr OKLab() 495 : OKLab { 0, 0, 0, 0 } 496 { 497 } 498 499 T lightness; 500 T a; 501 T b; 502 T alpha; 503 }; 504 505 template<typename T> constexpr ColorComponents<T, 4> asColorComponents(const OKLab<T>& c) 506 { 507 return { c.lightness, c.a, c.b, c.alpha }; 508 } 509 510 template<typename ColorType> inline constexpr bool IsOKLab = std::is_same_v<OKLab<typename ColorType::ComponentType>, ColorType>; 511 512 // MARK: - OKLCHA Color Type. 513 514 template<typename T> struct OKLCHA : ColorWithAlphaHelper<OKLCHA<T>> { 515 using ComponentType = T; 516 using Model = LCHModel<T>; 517 static constexpr auto whitePoint = WhitePoint::D65; 518 using Reference = OKLab<T>; 519 520 constexpr OKLCHA(T lightness, T chroma, T hue, T alpha = AlphaTraits<T>::opaque) 521 : lightness { lightness } 522 , chroma { chroma } 523 , hue { hue } 524 , alpha { alpha } 525 { 526 assertInRange(*this); 527 } 528 529 constexpr OKLCHA() 530 : OKLCHA { 0, 0, 0, 0 } 531 { 532 } 533 534 T lightness; 535 T chroma; 536 T hue; 537 T alpha; 538 }; 539 540 template<typename T> constexpr ColorComponents<T, 4> asColorComponents(const OKLCHA<T>& c) 541 { 542 return { c.lightness, c.chroma, c.hue, c.alpha }; 543 } 544 545 template<typename ColorType> inline constexpr bool IsOKLCHA = std::is_same_v<OKLCHA<typename ColorType::ComponentType>, ColorType>; 546 477 547 478 548 // MARK: - HSLA Color Type. … … 481 551 using ComponentType = T; 482 552 using Model = HSLModel<T>; 483 static constexpr WhitePointwhitePoint = WhitePoint::D65;553 static constexpr auto whitePoint = WhitePoint::D65; 484 554 using Reference = SRGBA<T>; 485 555 … … 516 586 using ComponentType = T; 517 587 using Model = HWBModel<T>; 518 static constexpr WhitePointwhitePoint = WhitePoint::D65;588 static constexpr auto whitePoint = WhitePoint::D65; 519 589 using Reference = SRGBA<T>; 520 590 … … 552 622 using Model = XYZModel<T>; 553 623 using ReferenceXYZ = XYZA<T, W>; 554 static constexpr WhitePointwhitePoint = W;624 static constexpr auto whitePoint = W; 555 625 556 626 constexpr XYZA(T x, T y, T z, T alpha = AlphaTraits<T>::opaque) -
trunk/Source/WebCore/platform/graphics/ColorUtilities.h
r274947 r286191 55 55 template<typename ColorType> ColorType invertedColorWithOverriddenAlpha(const ColorType&, float overrideAlpha); 56 56 57 template<typename ColorType, typename std::enable_if_t<std::is_same_v<typename ColorType::Model, RGBModel<typename ColorType::ComponentType>>>* = nullptr> constexpr bool isBlack(const ColorType&); 57 template<typename ColorType, typename std::enable_if_t<UsesLabModel<ColorType> || UsesLCHModel<ColorType>>* = nullptr> constexpr bool isBlack(const ColorType&); 58 template<typename ColorType, typename std::enable_if_t<UsesRGBModel<ColorType>>* = nullptr> constexpr bool isBlack(const ColorType&); 58 59 template<WhitePoint W> constexpr bool isBlack(const XYZA<float, W>&); 59 constexpr bool isBlack(const LCHA<float>&);60 constexpr bool isBlack(const Lab<float>&);61 60 62 template<typename ColorType, typename std::enable_if_t<std::is_same_v<typename ColorType::Model, RGBModel<typename ColorType::ComponentType>>>* = nullptr> constexpr bool isWhite(const ColorType&); 61 template<typename ColorType, typename std::enable_if_t<UsesLabModel<ColorType> || UsesLCHModel<ColorType>>* = nullptr> constexpr bool isWhite(const ColorType&); 62 template<typename ColorType, typename std::enable_if_t<UsesRGBModel<ColorType>>* = nullptr> constexpr bool isWhite(const ColorType&); 63 63 template<WhitePoint W> constexpr bool isWhite(const XYZA<float, W>&); 64 constexpr bool isWhite(const LCHA<float>&);65 constexpr bool isWhite(const Lab<float>&);66 64 67 65 constexpr uint16_t fastMultiplyBy255(uint16_t); … … 151 149 } 152 150 153 constexpr bool isBlack(const LCHA<float>& color) 151 template<typename ColorType, typename std::enable_if_t<UsesLabModel<ColorType> || UsesLCHModel<ColorType>>*> 152 constexpr bool isBlack(const ColorType& color) 154 153 { 155 154 return color.lightness == 0 && color.alpha == AlphaTraits<float>::opaque; 156 155 } 157 156 158 constexpr bool isBlack(const Lab<float>& color) 159 { 160 return color.lightness == 0 && color.alpha == AlphaTraits<float>::opaque; 161 } 162 163 template<typename ColorType, typename std::enable_if_t<std::is_same_v<typename ColorType::Model, RGBModel<typename ColorType::ComponentType>>>*> 157 template<typename ColorType, typename std::enable_if_t<UsesRGBModel<ColorType>>*> 164 158 constexpr bool isBlack(const ColorType& color) 165 159 { … … 174 168 } 175 169 176 constexpr bool isWhite(const LCHA<float>& color) 170 template<typename ColorType, typename std::enable_if_t<UsesLabModel<ColorType> || UsesLCHModel<ColorType>>*> 171 constexpr bool isWhite(const ColorType& color) 177 172 { 178 173 return color.lightness == 100 && color.alpha == AlphaTraits<float>::opaque; 179 174 } 180 175 181 constexpr bool isWhite(const Lab<float>& color) 182 { 183 return color.lightness == 100 && color.alpha == AlphaTraits<float>::opaque; 184 } 185 186 template<typename ColorType, typename std::enable_if_t<std::is_same_v<typename ColorType::Model, RGBModel<typename ColorType::ComponentType>>>*> 176 template<typename ColorType, typename std::enable_if_t<UsesRGBModel<ColorType>>*> 187 177 constexpr bool isWhite(const ColorType& color) 188 178 { -
trunk/Source/WebCore/platform/graphics/cg/ColorSpaceCG.h
r286168 r286191 86 86 return nullptr; 87 87 #endif 88 case ColorSpace::LCH:89 return nullptr;90 88 case ColorSpace::Lab: 91 89 #if HAVE(CORE_GRAPHICS_LAB_COLOR_SPACE) … … 120 118 return nullptr; 121 119 #endif 120 121 // FIXME: Add support for these once CoreGraphics supports it. 122 case ColorSpace::LCH: 123 case ColorSpace::OKLCH: 124 case ColorSpace::OKLab: 122 125 case ColorSpace::XYZ_D65: 123 // FIXME: Add support for this once we have figured out how to create the CoreGraphics representation.124 126 return nullptr; 125 127
Note:
See TracChangeset
for help on using the changeset viewer.