Changeset 274947 in webkit
- Timestamp:
- Mar 24, 2021 10:34:50 AM (16 months ago)
- Location:
- trunk
- Files:
-
- 9 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/fast/css/parsing-color-mix-expected.txt (modified) (1 diff)
-
LayoutTests/fast/css/parsing-color-mix.html (modified) (5 diffs)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/css/CSSValueKeywords.in (modified) (1 diff)
-
Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp (modified) (2 diffs)
-
Source/WebCore/platform/graphics/ColorModels.h (modified) (9 diffs)
-
Source/WebCore/platform/graphics/ColorTypes.h (modified) (2 diffs)
-
Source/WebCore/platform/graphics/ColorUtilities.h (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r274936 r274947 1 2021-03-24 Sam Weinig <weinig@apple.com> 2 3 Update CSS Color 5 color-mix() implementation to match the latest draft spec 4 https://bugs.webkit.org/show_bug.cgi?id=223665 5 6 Reviewed by Simon Fraser. 7 8 * fast/css/parsing-color-mix-expected.txt: 9 * fast/css/parsing-color-mix.html: 10 Update test and results for vastly simplified color-mix(). 11 1 12 2021-03-24 Chris Lord <clord@igalia.com> 2 13 -
trunk/LayoutTests/fast/css/parsing-color-mix-expected.txt
r273244 r274947 5 5 6 6 color-mix(hsl, ...) 7 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%), hsl(30deg 30% 40%))") is "rgb(84, 92, 61)" 8 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) 25%, hsl(30deg 30% 40%))") is "rgb(112, 106, 67)" 9 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%), hsl(30deg 30% 40%) 25%)") is "rgb(61, 73, 54)" 10 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) 25%, hsl(30deg 30% 40%) 75%)") is "rgb(112, 106, 67)" 11 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) 50%, hsl(30deg 30% 40%) 150%)") is "rgb(112, 106, 67)" 12 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) 12.5%, hsl(30deg 30% 40%) 37.5%)") is "rgb(112, 106, 67)" 13 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) 0%, hsl(30deg 30% 40%))") is "rgb(133, 102, 71)" 14 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) hue 50%, hsl(30deg 30% 40%))") is "rgb(53, 56, 46)" 15 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%), hsl(30deg 30% 40%) hue 50%)") is "rgb(53, 56, 46)" 16 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) hue 50%, hsl(30deg 30% 40%) hue 50%)") is "rgb(53, 56, 46)" 17 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) hue 100%, hsl(30deg 30% 40%))") is "rgb(46, 56, 46)" 18 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) hue 50%, hsl(30deg 30% 40%))") is "rgb(53, 56, 46)" 19 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) hue 50% saturation 100%, hsl(30deg 30% 40%))") is "rgb(53, 56, 46)" 20 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) hue 50% saturation 100% lightness 100%, hsl(30deg 30% 40%))") is "rgb(53, 56, 46)" 21 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) hue 50% saturation 100% lightness 100% alpha 100%, hsl(30deg 30% 40%))") is "rgb(53, 56, 46)" 22 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) hue 50%, hsl(30deg 30% 40%) saturation 0%)") is "rgb(53, 56, 46)" 23 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) hue 50%, hsl(30deg 30% 40%) saturation 0% lightness 0%)") is "rgb(53, 56, 46)" 24 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) hue 50%, hsl(30deg 30% 40%) saturation 0% lightness 0% alpha 0%)") is "rgb(53, 56, 46)" 25 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) hue 50% saturation 75%, hsl(30deg 30% 40%))") is "rgb(55, 59, 43)" 26 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) hue 50% saturation 75% lightness 15%, hsl(30deg 30% 40%))") is "rgb(101, 108, 80)" 27 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) hue 50% saturation 75% lightness 15% alpha 10%, hsl(30deg 30% 40%))") is "rgb(101, 108, 80)" 28 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) hue 60%, hsl(30deg 30% 40%))") is "rgb(52, 56, 46)" 29 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%), hsl(30deg 30% 40%) hue 40%)") is "rgb(52, 56, 46)" 30 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) hue 60%, hsl(30deg 30% 40%) hue 40%)") is "rgb(52, 56, 46)" 31 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) hue 60% hue 40%, hsl(30deg 30% 40%))") is "rgb(55, 56, 46)" 32 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) hue 40%, hsl(30deg 30% 40%))") is "rgb(55, 56, 46)" 33 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) hue, hsl(30deg 30% 40%))") is "rgb(56, 51, 46)" 34 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) hue 0%, hsl(30deg 30% 40%))") is "rgb(56, 51, 46)" 35 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) -10%, hsl(30deg 30% 40%))") is "rgb(133, 102, 71)" 36 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) 0%, hsl(30deg 30% 40%))") is "rgb(133, 102, 71)" 37 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) hue -10%, hsl(30deg 30% 40%))") is "rgb(56, 51, 46)" 38 PASS computedStyle("background-color", "color-mix(hsl, hsl(120deg 10% 20%) hue 0%, hsl(30deg 30% 40%))") is "rgb(56, 51, 46)" 7 PASS computedStyle("background-color", "color-mix(in hsl, hsl(120deg 10% 20%), hsl(30deg 30% 40%))") is "rgb(84, 92, 61)" 8 PASS computedStyle("background-color", "color-mix(in hsl, hsl(120deg 10% 20%) 25%, hsl(30deg 30% 40%))") is "rgb(112, 106, 67)" 9 PASS computedStyle("background-color", "color-mix(in hsl, 25% hsl(120deg 10% 20%), hsl(30deg 30% 40%))") is "rgb(112, 106, 67)" 10 PASS computedStyle("background-color", "color-mix(in hsl, hsl(120deg 10% 20%), 25% hsl(30deg 30% 40%))") is "rgb(61, 73, 54)" 11 PASS computedStyle("background-color", "color-mix(in hsl, hsl(120deg 10% 20%), hsl(30deg 30% 40%) 25%)") is "rgb(61, 73, 54)" 12 PASS computedStyle("background-color", "color-mix(in hsl, hsl(120deg 10% 20%) 25%, hsl(30deg 30% 40%) 75%)") is "rgb(112, 106, 67)" 13 PASS computedStyle("background-color", "color-mix(in hsl, hsl(120deg 10% 20%) 50%, hsl(30deg 30% 40%) 150%)") is "rgb(112, 106, 67)" 14 PASS computedStyle("background-color", "color-mix(in hsl, hsl(120deg 10% 20%) 12.5%, hsl(30deg 30% 40%) 37.5%)") is "rgb(112, 106, 67)" 15 PASS computedStyle("background-color", "color-mix(in hsl, hsl(120deg 10% 20%) 0%, hsl(30deg 30% 40%))") is "rgb(133, 102, 71)" 16 PASS computedStyle("background-color", "color-mix(in hsl, hsl(120deg 10% 20%) -10%, hsl(30deg 30% 40%))") is "rgb(142, 97, 72)" 39 17 40 18 color-mix(hwb, ...) 41 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%))") is "rgb(147, 179, 52)" 42 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) 25%, hwb(30deg 30% 40%))") is "rgb(166, 153, 64)" 43 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%) 25%)") is "rgb(96, 191, 39)" 44 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) 25%, hwb(30deg 30% 40%) 75%)") is "rgb(166, 153, 64)" 45 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) 50%, hwb(30deg 30% 40%) 150%)") is "rgb(166, 153, 64)" 46 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) 12.5%, hwb(30deg 30% 40%) 37.5%)") is "rgb(166, 153, 64)" 47 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) 0%, hwb(30deg 30% 40%))") is "rgb(153, 115, 77)" 48 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) hue 50%, hwb(30deg 30% 40%))") is "rgb(160, 204, 26)" 49 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%) hue 50%)") is "rgb(160, 204, 26)" 50 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) hue 50%, hwb(30deg 30% 40%) hue 50%)") is "rgb(160, 204, 26)" 51 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) hue 100%, hwb(30deg 30% 40%))") is "rgb(26, 204, 26)" 52 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) hue 50%, hwb(30deg 30% 40%))") is "rgb(160, 204, 26)" 53 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) hue 50% whiteness 100%, hwb(30deg 30% 40%))") is "rgb(160, 204, 26)" 54 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) hue 50% whiteness 100% blackness 100%, hwb(30deg 30% 40%))") is "rgb(160, 204, 26)" 55 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) hue 50% whiteness 100% blackness 100% alpha 100%, hwb(30deg 30% 40%))") is "rgb(160, 204, 26)" 56 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) hue 50%, hwb(30deg 30% 40%) whiteness 0%)") is "rgb(160, 204, 26)" 57 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) hue 50%, hwb(30deg 30% 40%) whiteness 0% blackness 0%)") is "rgb(160, 204, 26)" 58 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) hue 50%, hwb(30deg 30% 40%) whiteness 0% blackness 0% alpha 0%)") is "rgb(160, 204, 26)" 59 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) hue 50% whiteness 75%, hwb(30deg 30% 40%))") is "rgb(163, 204, 39)" 60 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) hue 50% whiteness 75% blackness 15%, hwb(30deg 30% 40%))") is "rgb(130, 161, 39)" 61 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) hue 50% whiteness 75% blackness 15% alpha 10%, hwb(30deg 30% 40%))") is "rgb(130, 161, 39)" 62 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) hue 60%, hwb(30deg 30% 40%))") is "rgb(133, 204, 26)" 63 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%) hue 40%)") is "rgb(133, 204, 26)" 64 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) hue 60%, hwb(30deg 30% 40%) hue 40%)") is "rgb(133, 204, 26)" 65 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 75% 25%) whiteness 100%, hwb(120deg 25% 75%) blackness 100%)") is "rgb(128, 128, 128)" 66 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) hue 60% hue 40%, hwb(30deg 30% 40%))") is "rgb(186, 204, 26)" 67 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) hue 40%, hwb(30deg 30% 40%))") is "rgb(186, 204, 26)" 68 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) hue, hwb(30deg 30% 40%))") is "rgb(204, 115, 26)" 69 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) hue 0%, hwb(30deg 30% 40%))") is "rgb(204, 115, 26)" 70 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) -10%, hwb(30deg 30% 40%))") is "rgb(153, 115, 77)" 71 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) 0%, hwb(30deg 30% 40%))") is "rgb(153, 115, 77)" 72 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) hue -10%, hwb(30deg 30% 40%))") is "rgb(204, 115, 26)" 73 PASS computedStyle("background-color", "color-mix(hwb, hwb(120deg 10% 20%) hue 0%, hwb(30deg 30% 40%))") is "rgb(204, 115, 26)" 19 PASS computedStyle("background-color", "color-mix(in hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%))") is "rgb(147, 179, 52)" 20 PASS computedStyle("background-color", "color-mix(in hwb, hwb(120deg 10% 20%) 25%, hwb(30deg 30% 40%))") is "rgb(166, 153, 64)" 21 PASS computedStyle("background-color", "color-mix(in hwb, 25% hwb(120deg 10% 20%), hwb(30deg 30% 40%))") is "rgb(166, 153, 64)" 22 PASS computedStyle("background-color", "color-mix(in hwb, hwb(120deg 10% 20%), 25% hwb(30deg 30% 40%))") is "rgb(96, 191, 39)" 23 PASS computedStyle("background-color", "color-mix(in hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%) 25%)") is "rgb(96, 191, 39)" 24 PASS computedStyle("background-color", "color-mix(in hwb, hwb(120deg 10% 20%) 25%, hwb(30deg 30% 40%) 75%)") is "rgb(166, 153, 64)" 25 PASS computedStyle("background-color", "color-mix(in hwb, hwb(120deg 10% 20%) 50%, hwb(30deg 30% 40%) 150%)") is "rgb(166, 153, 64)" 26 PASS computedStyle("background-color", "color-mix(in hwb, hwb(120deg 10% 20%) 12.5%, hwb(30deg 30% 40%) 37.5%)") is "rgb(166, 153, 64)" 27 PASS computedStyle("background-color", "color-mix(in hwb, hwb(120deg 10% 20%) 0%, hwb(30deg 30% 40%))") is "rgb(153, 115, 77)" 28 PASS computedStyle("background-color", "color-mix(in hwb, hwb(120deg 10% 20%) -10%, hwb(30deg 30% 40%))") is "rgb(148, 105, 82)" 74 29 75 30 color-mix(lch, ...) 76 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4), lch(50% 60 70deg / .8))") is "lch(30% 40 50 / 0.6)" 77 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) 25%, lch(50% 60 70deg / .8))") is "lch(40% 50 60 / 0.7)" 78 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4), lch(50% 60 70deg / .8) 25%)") is "lch(20% 30 40 / 0.5)" 79 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) 25%, lch(50% 60 70deg / .8) 75%)") is "lch(40% 50 60 / 0.7)" 80 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) 50%, lch(50% 60 70deg / .8) 150%)") is "lch(40% 50 60 / 0.7)" 81 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) 12.5%, lch(50% 60 70deg / .8) 37.5%)") is "lch(40% 50 60 / 0.7)" 82 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) 0%, lch(50% 60 70deg / .8))") is "lch(50% 60 70 / 0.8)" 83 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) lightness 50%, lch(50% 60 70deg / .8))") is "lch(30% 20 30 / 0.4)" 84 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4), lch(50% 60 70deg / .8) lightness 50%)") is "lch(30% 20 30 / 0.4)" 85 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) lightness 50%, lch(50% 60 70deg / .8) lightness 50%)") is "lch(30% 20 30 / 0.4)" 86 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) lightness 100%, lch(50% 60 70deg / .8))") is "lch(10% 20 30 / 0.4)" 87 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) lightness 50%, lch(50% 60 70deg / .8))") is "lch(30% 20 30 / 0.4)" 88 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) lightness 50% chroma 100%, lch(50% 60 70deg / .8))") is "lch(30% 20 30 / 0.4)" 89 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) lightness 50% chroma 100% hue 100%, lch(50% 60 70deg / .8))") is "lch(30% 20 30 / 0.4)" 90 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) lightness 50% chroma 100% hue 100% alpha 100%, lch(50% 60 70deg / .8))") is "lch(30% 20 30 / 0.4)" 91 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) lightness 50%, lch(50% 60 70deg / .8) chroma 0%)") is "lch(30% 20 30 / 0.4)" 92 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) lightness 50%, lch(50% 60 70deg / .8) chroma 0% hue 0%)") is "lch(30% 20 30 / 0.4)" 93 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) lightness 50%, lch(50% 60 70deg / .8) chroma 0% hue 0% alpha 0%)") is "lch(30% 20 30 / 0.4)" 94 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) lightness 50% chroma 75%, lch(50% 60 70deg / .8))") is "lch(30% 30 30 / 0.4)" 95 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) lightness 50% chroma 75% hue 15%, lch(50% 60 70deg / .8))") is "lch(30% 30 64 / 0.4)" 96 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) lightness 50% chroma 75% hue 15% alpha 10%, lch(50% 60 70deg / .8))") is "lch(30% 30 64 / 0.76)" 97 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) lightness 60%, lch(50% 60 70deg / .8))") is "lch(26% 20 30 / 0.4)" 98 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4), lch(50% 60 70deg / .8) lightness 40%)") is "lch(26% 20 30 / 0.4)" 99 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) lightness 60%, lch(50% 60 70deg / .8) lightness 40%)") is "lch(26% 20 30 / 0.4)" 100 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) lightness 60% lightness 40%, lch(50% 60 70deg / .8))") is "lch(34% 20 30 / 0.4)" 101 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) lightness 40%, lch(50% 60 70deg / .8))") is "lch(34% 20 30 / 0.4)" 102 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) lightness, lch(50% 60 70deg / .8))") is "lch(50% 20 30 / 0.4)" 103 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) lightness 0%, lch(50% 60 70deg / .8))") is "lch(50% 20 30 / 0.4)" 104 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) -10%, lch(50% 60 70deg / .8))") is "lch(50% 60 70 / 0.8)" 105 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) 0%, lch(50% 60 70deg / .8))") is "lch(50% 60 70 / 0.8)" 106 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) lightness -10%, lch(50% 60 70deg / .8))") is "lch(50% 20 30 / 0.4)" 107 PASS computedStyle("background-color", "color-mix(lch, lch(10% 20 30deg / .4) lightness 0%, lch(50% 60 70deg / .8))") is "lch(50% 20 30 / 0.4)" 31 PASS computedStyle("background-color", "color-mix(in lch, lch(10% 20 30deg / .4), lch(50% 60 70deg / .8))") is "lch(30% 40 50 / 0.6)" 32 PASS computedStyle("background-color", "color-mix(in lch, lch(10% 20 30deg / .4) 25%, lch(50% 60 70deg / .8))") is "lch(40% 50 60 / 0.7)" 33 PASS computedStyle("background-color", "color-mix(in lch, 25% lch(10% 20 30deg / .4), lch(50% 60 70deg / .8))") is "lch(40% 50 60 / 0.7)" 34 PASS computedStyle("background-color", "color-mix(in lch, lch(10% 20 30deg / .4), 25% lch(50% 60 70deg / .8))") is "lch(20% 30 40 / 0.5)" 35 PASS computedStyle("background-color", "color-mix(in lch, lch(10% 20 30deg / .4), lch(50% 60 70deg / .8) 25%)") is "lch(20% 30 40 / 0.5)" 36 PASS computedStyle("background-color", "color-mix(in lch, lch(10% 20 30deg / .4) 25%, lch(50% 60 70deg / .8) 75%)") is "lch(40% 50 60 / 0.7)" 37 PASS computedStyle("background-color", "color-mix(in lch, lch(10% 20 30deg / .4) 50%, lch(50% 60 70deg / .8) 150%)") is "lch(40% 50 60 / 0.7)" 38 PASS computedStyle("background-color", "color-mix(in lch, lch(10% 20 30deg / .4) 12.5%, lch(50% 60 70deg / .8) 37.5%)") is "lch(40% 50 60 / 0.7)" 39 PASS computedStyle("background-color", "color-mix(in lch, lch(10% 20 30deg / .4) 0%, lch(50% 60 70deg / .8))") is "lch(50% 60 70 / 0.8)" 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)" 108 41 109 42 color-mix(lab, ...) 110 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4), lab(50% 60 70 / .8))") is "lab(30% 40 50 / 0.6)" 111 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4) 25%, lab(50% 60 70 / .8))") is "lab(40% 50 60 / 0.7)" 112 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4), lab(50% 60 70 / .8) 25%)") is "lab(20% 30 40 / 0.5)" 113 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4) 25%, lab(50% 60 70 / .8) 75%)") is "lab(40% 50 60 / 0.7)" 114 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4) 50%, lab(50% 60 70 / .8) 150%)") is "lab(40% 50 60 / 0.7)" 115 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4) 12.5%, lab(50% 60 70 / .8) 37.5%)") is "lab(40% 50 60 / 0.7)" 116 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4) 0%, lab(50% 60 70 / .8))") is "lab(50% 60 70 / 0.8)" 117 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4) lightness 50%, lab(50% 60 70 / .8))") is "lab(30% 20 30 / 0.4)" 118 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4), lab(50% 60 70 / .8) lightness 50%)") is "lab(30% 20 30 / 0.4)" 119 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4) lightness 50%, lab(50% 60 70 / .8) lightness 50%)") is "lab(30% 20 30 / 0.4)" 120 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4) lightness 100%, lab(50% 60 70 / .8))") is "lab(10% 20 30 / 0.4)" 121 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4) lightness 50%, lab(50% 60 70 / .8))") is "lab(30% 20 30 / 0.4)" 122 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4) lightness 50% a 100%, lab(50% 60 70 / .8))") is "lab(30% 20 30 / 0.4)" 123 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4) lightness 50% a 100% b 100%, lab(50% 60 70 / .8))") is "lab(30% 20 30 / 0.4)" 124 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4) lightness 50% a 100% b 100% alpha 100%, lab(50% 60 70 / .8))") is "lab(30% 20 30 / 0.4)" 125 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4) lightness 50%, lab(50% 60 70 / .8) a 0%)") is "lab(30% 20 30 / 0.4)" 126 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4) lightness 50%, lab(50% 60 70 / .8) a 0% b 0%)") is "lab(30% 20 30 / 0.4)" 127 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4) lightness 50%, lab(50% 60 70 / .8) a 0% b 0% alpha 0%)") is "lab(30% 20 30 / 0.4)" 128 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4) lightness 50% a 75%, lab(50% 60 70 / .8))") is "lab(30% 30 30 / 0.4)" 129 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4) lightness 50% a 75% b 15%, lab(50% 60 70 / .8))") is "lab(30% 30 64 / 0.4)" 130 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4) lightness 50% a 75% b 15% alpha 10%, lab(50% 60 70 / .8))") is "lab(30% 30 64 / 0.76)" 131 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4) lightness 60%, lab(50% 60 70 / .8))") is "lab(26% 20 30 / 0.4)" 132 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4), lab(50% 60 70 / .8) lightness 40%)") is "lab(26% 20 30 / 0.4)" 133 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4) lightness 60%, lab(50% 60 70 / .8) lightness 40%)") is "lab(26% 20 30 / 0.4)" 134 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4) lightness 60% lightness 40%, lab(50% 60 70 / .8))") is "lab(34% 20 30 / 0.4)" 135 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4) lightness, lab(50% 60 70 / .8))") is "lab(50% 20 30 / 0.4)" 136 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4) lightness 0%, lab(50% 60 70 / .8))") is "lab(50% 20 30 / 0.4)" 137 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4) -10%, lab(50% 60 70 / .8))") is "lab(50% 60 70 / 0.8)" 138 PASS computedStyle("background-color", "color-mix(lab, lab(10% 20 30 / .4) lightness -10%, lab(50% 60 70 / .8))") is "lab(50% 20 30 / 0.4)" 43 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)" 44 PASS computedStyle("background-color", "color-mix(in lab, lab(10% 20 30 / .4) 25%, lab(50% 60 70 / .8))") is "lab(40% 50 60 / 0.7)" 45 PASS computedStyle("background-color", "color-mix(in lab, 25% lab(10% 20 30 / .4), lab(50% 60 70 / .8))") is "lab(40% 50 60 / 0.7)" 46 PASS computedStyle("background-color", "color-mix(in lab, lab(10% 20 30 / .4), 25% lab(50% 60 70 / .8))") is "lab(20% 30 40 / 0.5)" 47 PASS computedStyle("background-color", "color-mix(in lab, lab(10% 20 30 / .4), lab(50% 60 70 / .8) 25%)") is "lab(20% 30 40 / 0.5)" 48 PASS computedStyle("background-color", "color-mix(in lab, lab(10% 20 30 / .4) 25%, lab(50% 60 70 / .8) 75%)") is "lab(40% 50 60 / 0.7)" 49 PASS computedStyle("background-color", "color-mix(in lab, lab(10% 20 30 / .4) 50%, lab(50% 60 70 / .8) 150%)") is "lab(40% 50 60 / 0.7)" 50 PASS computedStyle("background-color", "color-mix(in lab, lab(10% 20 30 / .4) 12.5%, lab(50% 60 70 / .8) 37.5%)") is "lab(40% 50 60 / 0.7)" 51 PASS computedStyle("background-color", "color-mix(in lab, lab(10% 20 30 / .4) 0%, lab(50% 60 70 / .8))") is "lab(50% 60 70 / 0.8)" 52 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)" 139 53 140 54 color-mix(srgb, ...) 141 PASS computedStyle("background-color", "color-mix(srgb, color(srgb .1 .2 .3 / .4), color(srgb .5 .6 .7 / .8))") is "color(srgb 0.3 0.4 0.5 / 0.6)" 142 PASS computedStyle("background-color", "color-mix(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)" 143 PASS computedStyle("background-color", "color-mix(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)" 144 PASS computedStyle("background-color", "color-mix(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)" 145 PASS computedStyle("background-color", "color-mix(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)" 146 PASS computedStyle("background-color", "color-mix(srgb, color(srgb .1 .2 .3 / .4) 12.5%, color(srgb .5 .6 .7 / .8) 37.5%)") is "color(srgb 0.4 0.5 0.6 / 0.7)" 147 PASS computedStyle("background-color", "color-mix(srgb, color(srgb .1 .2 .3 / .4) 0%, color(srgb .5 .6 .7 / .8))") is "color(srgb 0.5 0.6 0.7 / 0.8)" 148 PASS computedStyle("background-color", "color-mix(srgb, color(srgb .1 .2 .3 / .4) red 50%, color(srgb .5 .6 .7 / .8))") is "color(srgb 0.3 0.2 0.3 / 0.4)" 149 PASS computedStyle("background-color", "color-mix(srgb, color(srgb .1 .2 .3 / .4), color(srgb .5 .6 .7 / .8) red 50%)") is "color(srgb 0.3 0.2 0.3 / 0.4)" 150 PASS computedStyle("background-color", "color-mix(srgb, color(srgb .1 .2 .3 / .4) red 50%, color(srgb .5 .6 .7 / .8) red 50%)") is "color(srgb 0.3 0.2 0.3 / 0.4)" 151 PASS computedStyle("background-color", "color-mix(srgb, color(srgb .1 .2 .3 / .4) red 100%, color(srgb .5 .6 .7 / .8))") is "color(srgb 0.1 0.2 0.3 / 0.4)" 152 PASS computedStyle("background-color", "color-mix(srgb, color(srgb .1 .2 .3 / .4) red 50%, color(srgb .5 .6 .7 / .8))") is "color(srgb 0.3 0.2 0.3 / 0.4)" 153 PASS computedStyle("background-color", "color-mix(srgb, color(srgb .1 .2 .3 / .4) red 50% green 100%, color(srgb .5 .6 .7 / .8))") is "color(srgb 0.3 0.2 0.3 / 0.4)" 154 PASS computedStyle("background-color", "color-mix(srgb, color(srgb .1 .2 .3 / .4) red 50% green 100% blue 100%, color(srgb .5 .6 .7 / .8))") is "color(srgb 0.3 0.2 0.3 / 0.4)" 155 PASS computedStyle("background-color", "color-mix(srgb, color(srgb .1 .2 .3 / .4) red 50% green 100% blue 100% alpha 100%, color(srgb .5 .6 .7 / .8))") is "color(srgb 0.3 0.2 0.3 / 0.4)" 156 PASS computedStyle("background-color", "color-mix(srgb, color(srgb .1 .2 .3 / .4) red 50%, color(srgb .5 .6 .7 / .8) green 0%)") is "color(srgb 0.3 0.2 0.3 / 0.4)" 157 PASS computedStyle("background-color", "color-mix(srgb, color(srgb .1 .2 .3 / .4) red 50%, color(srgb .5 .6 .7 / .8) green 0% blue 0%)") is "color(srgb 0.3 0.2 0.3 / 0.4)" 158 PASS computedStyle("background-color", "color-mix(srgb, color(srgb .1 .2 .3 / .4) red 50%, color(srgb .5 .6 .7 / .8) green 0% blue 0% alpha 0%)") is "color(srgb 0.3 0.2 0.3 / 0.4)" 159 PASS computedStyle("background-color", "color-mix(srgb, color(srgb .1 .2 .3 / .4) red 50% green 75%, color(srgb .5 .6 .7 / .8))") is "color(srgb 0.3 0.3 0.3 / 0.4)" 160 PASS computedStyle("background-color", "color-mix(srgb, color(srgb .1 .2 .3 / .4) red 50% green 75% blue 15%, color(srgb .5 .6 .7 / .8))") is "color(srgb 0.3 0.3 0.64 / 0.4)" 161 PASS computedStyle("background-color", "color-mix(srgb, color(srgb .1 .2 .3 / .4) red 50% green 75% blue 15% alpha 10%, color(srgb .5 .6 .7 / .8))") is "color(srgb 0.3 0.3 0.64 / 0.76)" 162 PASS computedStyle("background-color", "color-mix(srgb, color(srgb .1 .2 .3 / .4) red 60%, color(srgb .5 .6 .7 / .8))") is "color(srgb 0.26 0.2 0.3 / 0.4)" 163 PASS computedStyle("background-color", "color-mix(srgb, color(srgb .1 .2 .3 / .4), color(srgb .5 .6 .7 / .8) red 40%)") is "color(srgb 0.26 0.2 0.3 / 0.4)" 164 PASS computedStyle("background-color", "color-mix(srgb, color(srgb .1 .2 .3 / .4) red 60%, color(srgb .5 .6 .7 / .8) red 40%)") is "color(srgb 0.26 0.2 0.3 / 0.4)" 165 PASS computedStyle("background-color", "color-mix(srgb, color(srgb .1 .2 .3 / .4) red 60% red 40%, color(srgb .5 .6 .7 / .8))") is "color(srgb 0.34 0.2 0.3 / 0.4)" 166 PASS computedStyle("background-color", "color-mix(srgb, color(srgb .1 .2 .3 / .4) red, color(srgb .5 .6 .7 / .8))") is "color(srgb 0.5 0.2 0.3 / 0.4)" 167 PASS computedStyle("background-color", "color-mix(srgb, color(srgb .1 .2 .3 / .4) red 0%, color(srgb .5 .6 .7 / .8))") is "color(srgb 0.5 0.2 0.3 / 0.4)" 168 PASS computedStyle("background-color", "color-mix(srgb, color(srgb .1 .2 .3 / .4) -10%, color(srgb .5 .6 .7 / .8))") is "color(srgb 0.5 0.6 0.7 / 0.8)" 169 PASS computedStyle("background-color", "color-mix(srgb, color(srgb .1 .2 .3 / .4) red -10%, color(srgb .5 .6 .7 / .8))") is "color(srgb 0.5 0.2 0.3 / 0.4)" 55 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 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 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)" 58 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 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 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)" 62 PASS computedStyle("background-color", "color-mix(in srgb, color(srgb .1 .2 .3 / .4) 12.5%, color(srgb .5 .6 .7 / .8) 37.5%)") is "color(srgb 0.4 0.5 0.6 / 0.7)" 63 PASS computedStyle("background-color", "color-mix(in srgb, color(srgb .1 .2 .3 / .4) 0%, color(srgb .5 .6 .7 / .8))") is "color(srgb 0.5 0.6 0.7 / 0.8)" 64 PASS computedStyle("background-color", "color-mix(in srgb, color(srgb .1 .2 .3 / .4) -10%, color(srgb .5 .6 .7 / .8))") is "color(srgb 0.54 0.64000005 0.74 / 0.84000003)" 170 65 171 66 color-mix(xyz, ...) 172 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4), color(xyz .5 .6 .7 / .8))") is "color(xyz 0.3 0.4 0.5 / 0.6)" 173 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4) 25%, color(xyz .5 .6 .7 / .8))") is "color(xyz 0.4 0.5 0.6 / 0.7)" 174 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4), color(xyz .5 .6 .7 / .8) 25%)") is "color(xyz 0.2 0.3 0.4 / 0.5)" 175 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4) 25%, color(xyz .5 .6 .7 / .8) 75%)") is "color(xyz 0.4 0.5 0.6 / 0.7)" 176 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4) 50%, color(xyz .5 .6 .7 / .8) 150%)") is "color(xyz 0.4 0.5 0.6 / 0.7)" 177 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4) 12.5%, color(xyz .5 .6 .7 / .8) 37.5%)") is "color(xyz 0.4 0.5 0.6 / 0.7)" 178 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4) 0%, color(xyz .5 .6 .7 / .8))") is "color(xyz 0.5 0.6 0.7 / 0.8)" 179 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4) x 50%, color(xyz .5 .6 .7 / .8))") is "color(xyz 0.3 0.2 0.3 / 0.4)" 180 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4), color(xyz .5 .6 .7 / .8) x 50%)") is "color(xyz 0.3 0.2 0.3 / 0.4)" 181 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4) x 50%, color(xyz .5 .6 .7 / .8) x 50%)") is "color(xyz 0.3 0.2 0.3 / 0.4)" 182 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4) x 100%, color(xyz .5 .6 .7 / .8))") is "color(xyz 0.1 0.2 0.3 / 0.4)" 183 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4) x 50%, color(xyz .5 .6 .7 / .8))") is "color(xyz 0.3 0.2 0.3 / 0.4)" 184 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4) x 50% y 100%, color(xyz .5 .6 .7 / .8))") is "color(xyz 0.3 0.2 0.3 / 0.4)" 185 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4) x 50% y 100% z 100%, color(xyz .5 .6 .7 / .8))") is "color(xyz 0.3 0.2 0.3 / 0.4)" 186 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4) x 50% y 100% z 100% alpha 100%, color(xyz .5 .6 .7 / .8))") is "color(xyz 0.3 0.2 0.3 / 0.4)" 187 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4) x 50%, color(xyz .5 .6 .7 / .8) y 0%)") is "color(xyz 0.3 0.2 0.3 / 0.4)" 188 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4) x 50%, color(xyz .5 .6 .7 / .8) y 0% z 0%)") is "color(xyz 0.3 0.2 0.3 / 0.4)" 189 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4) x 50%, color(xyz .5 .6 .7 / .8) y 0% z 0% alpha 0%)") is "color(xyz 0.3 0.2 0.3 / 0.4)" 190 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4) x 50% y 75%, color(xyz .5 .6 .7 / .8))") is "color(xyz 0.3 0.3 0.3 / 0.4)" 191 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4) x 50% y 75% z 15%, color(xyz .5 .6 .7 / .8))") is "color(xyz 0.3 0.3 0.64 / 0.4)" 192 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4) x 50% y 75% z 15% alpha 10%, color(xyz .5 .6 .7 / .8))") is "color(xyz 0.3 0.3 0.64 / 0.76)" 193 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4) x 60%, color(xyz .5 .6 .7 / .8))") is "color(xyz 0.26 0.2 0.3 / 0.4)" 194 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4), color(xyz .5 .6 .7 / .8) x 40%)") is "color(xyz 0.26 0.2 0.3 / 0.4)" 195 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4) x 60%, color(xyz .5 .6 .7 / .8) x 40%)") is "color(xyz 0.26 0.2 0.3 / 0.4)" 196 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4) x 60% x 40%, color(xyz .5 .6 .7 / .8))") is "color(xyz 0.34 0.2 0.3 / 0.4)" 197 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4) x, color(xyz .5 .6 .7 / .8))") is "color(xyz 0.5 0.2 0.3 / 0.4)" 198 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4) x 0%, color(xyz .5 .6 .7 / .8))") is "color(xyz 0.5 0.2 0.3 / 0.4)" 199 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4) -10%, color(xyz .5 .6 .7 / .8))") is "color(xyz 0.5 0.6 0.7 / 0.8)" 200 PASS computedStyle("background-color", "color-mix(xyz, color(xyz .1 .2 .3 / .4) x -10%, color(xyz .5 .6 .7 / .8))") is "color(xyz 0.5 0.2 0.3 / 0.4)" 67 PASS computedStyle("background-color", "color-mix(in xyz, color(xyz .1 .2 .3 / .4), color(xyz .5 .6 .7 / .8))") is "color(xyz 0.3 0.4 0.5 / 0.6)" 68 PASS computedStyle("background-color", "color-mix(in xyz, color(xyz .1 .2 .3 / .4) 25%, color(xyz .5 .6 .7 / .8))") is "color(xyz 0.4 0.5 0.6 / 0.7)" 69 PASS computedStyle("background-color", "color-mix(in xyz, 25% color(xyz .1 .2 .3 / .4), color(xyz .5 .6 .7 / .8))") is "color(xyz 0.4 0.5 0.6 / 0.7)" 70 PASS computedStyle("background-color", "color-mix(in xyz, color(xyz .1 .2 .3 / .4), color(xyz .5 .6 .7 / .8) 25%)") is "color(xyz 0.2 0.3 0.4 / 0.5)" 71 PASS computedStyle("background-color", "color-mix(in xyz, color(xyz .1 .2 .3 / .4), 25% color(xyz .5 .6 .7 / .8))") is "color(xyz 0.2 0.3 0.4 / 0.5)" 72 PASS computedStyle("background-color", "color-mix(in xyz, color(xyz .1 .2 .3 / .4) 25%, color(xyz .5 .6 .7 / .8) 75%)") is "color(xyz 0.4 0.5 0.6 / 0.7)" 73 PASS computedStyle("background-color", "color-mix(in xyz, color(xyz .1 .2 .3 / .4) 50%, color(xyz .5 .6 .7 / .8) 150%)") is "color(xyz 0.4 0.5 0.6 / 0.7)" 74 PASS computedStyle("background-color", "color-mix(in xyz, color(xyz .1 .2 .3 / .4) 12.5%, color(xyz .5 .6 .7 / .8) 37.5%)") is "color(xyz 0.4 0.5 0.6 / 0.7)" 75 PASS computedStyle("background-color", "color-mix(in xyz, color(xyz .1 .2 .3 / .4) 0%, color(xyz .5 .6 .7 / .8))") is "color(xyz 0.5 0.6 0.7 / 0.8)" 76 PASS computedStyle("background-color", "color-mix(in xyz, color(xyz .1 .2 .3 / .4) -10%, color(xyz .5 .6 .7 / .8))") is "color(xyz 0.54 0.64000005 0.74 / 0.84000003)" 201 77 PASS successfullyParsed is true 202 78 -
trunk/LayoutTests/fast/css/parsing-color-mix.html
r273244 r274947 29 29 debug('color-mix(hsl, ...)'); 30 30 31 // Special case no adjusters or percentage is split 50-50. 32 testComputed(`color-mix(hsl, hsl(120deg 10% 20%), hsl(30deg 30% 40%))`, `rgb(84, 92, 61)`); // hsl(75deg 20% 30%) 31 testComputed(`color-mix(in hsl, hsl(120deg 10% 20%), hsl(30deg 30% 40%))`, `rgb(84, 92, 61)`); // hsl(75deg 20% 30%) 32 testComputed(`color-mix(in hsl, hsl(120deg 10% 20%) 25%, hsl(30deg 30% 40%))`, `rgb(112, 106, 67)`); 33 testComputed(`color-mix(in hsl, 25% hsl(120deg 10% 20%), hsl(30deg 30% 40%))`, `rgb(112, 106, 67)`); 34 testComputed(`color-mix(in hsl, hsl(120deg 10% 20%), 25% hsl(30deg 30% 40%))`, `rgb(61, 73, 54)`); 35 testComputed(`color-mix(in hsl, hsl(120deg 10% 20%), hsl(30deg 30% 40%) 25%)`, `rgb(61, 73, 54)`); 36 testComputed(`color-mix(in hsl, hsl(120deg 10% 20%) 25%, hsl(30deg 30% 40%) 75%)`, `rgb(112, 106, 67)`); 37 testComputed(`color-mix(in hsl, hsl(120deg 10% 20%) 50%, hsl(30deg 30% 40%) 150%)`, `rgb(112, 106, 67)`); // Scale down > 100% sum. 38 testComputed(`color-mix(in hsl, hsl(120deg 10% 20%) 12.5%, hsl(30deg 30% 40%) 37.5%)`, `rgb(112, 106, 67)`); // Scale up < 100% sum. 39 testComputed(`color-mix(in hsl, hsl(120deg 10% 20%) 0%, hsl(30deg 30% 40%))`, `rgb(133, 102, 71)`); 33 40 34 // Test precentage without adjusters. 35 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) 25%, hsl(30deg 30% 40%))`, `rgb(112, 106, 67)`); 36 testComputed(`color-mix(hsl, hsl(120deg 10% 20%), hsl(30deg 30% 40%) 25%)`, `rgb(61, 73, 54)`); 37 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) 25%, hsl(30deg 30% 40%) 75%)`, `rgb(112, 106, 67)`); 38 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) 50%, hsl(30deg 30% 40%) 150%)`, `rgb(112, 106, 67)`); // Scale down > 100% sum. 39 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) 12.5%, hsl(30deg 30% 40%) 37.5%)`, `rgb(112, 106, 67)`); // Scale up < 100% sum. 40 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) 0%, hsl(30deg 30% 40%))`, `rgb(133, 102, 71)`); 41 42 // Test per-channel adjusters. 43 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) hue 50%, hsl(30deg 30% 40%))`, `rgb(53, 56, 46)`); 44 testComputed(`color-mix(hsl, hsl(120deg 10% 20%), hsl(30deg 30% 40%) hue 50%)`, `rgb(53, 56, 46)`); 45 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) hue 50%, hsl(30deg 30% 40%) hue 50%)`, `rgb(53, 56, 46)`); 46 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) hue 100%, hsl(30deg 30% 40%))`, `rgb(46, 56, 46)`); 47 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) hue 50%, hsl(30deg 30% 40%))`, `rgb(53, 56, 46)`); 48 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) hue 50% saturation 100%, hsl(30deg 30% 40%))`, `rgb(53, 56, 46)`); 49 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) hue 50% saturation 100% lightness 100%, hsl(30deg 30% 40%))`, `rgb(53, 56, 46)`); 50 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) hue 50% saturation 100% lightness 100% alpha 100%, hsl(30deg 30% 40%))`, `rgb(53, 56, 46)`); 51 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) hue 50%, hsl(30deg 30% 40%) saturation 0%)`, `rgb(53, 56, 46)`); 52 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) hue 50%, hsl(30deg 30% 40%) saturation 0% lightness 0%)`, `rgb(53, 56, 46)`); 53 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) hue 50%, hsl(30deg 30% 40%) saturation 0% lightness 0% alpha 0%)`, `rgb(53, 56, 46)`); 54 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) hue 50% saturation 75%, hsl(30deg 30% 40%))`, `rgb(55, 59, 43)`); 55 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) hue 50% saturation 75% lightness 15%, hsl(30deg 30% 40%))`, `rgb(101, 108, 80)`); 56 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) hue 50% saturation 75% lightness 15% alpha 10%, hsl(30deg 30% 40%))`, `rgb(101, 108, 80)`); 57 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) hue 60%, hsl(30deg 30% 40%))`, `rgb(52, 56, 46)`); 58 testComputed(`color-mix(hsl, hsl(120deg 10% 20%), hsl(30deg 30% 40%) hue 40%)`, `rgb(52, 56, 46)`); 59 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) hue 60%, hsl(30deg 30% 40%) hue 40%)`, `rgb(52, 56, 46)`); 60 61 // FIXME: Test hue mixes with modifiers. 62 63 // Open questions. 64 65 // What should happen if you provide the same adjuster more than once? Currently, we do last one wins. 66 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) hue 60% hue 40%, hsl(30deg 30% 40%))`, `rgb(55, 56, 46)`); 67 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) hue 40%, hsl(30deg 30% 40%))`, `rgb(55, 56, 46)`); 68 69 // What should happen if you provide an adjuster without a paihue percent? Currently, we treat that like having 0% for that adjuster. 70 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) hue, hsl(30deg 30% 40%))`, `rgb(56, 51, 46)`); 71 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) hue 0%, hsl(30deg 30% 40%))`, `rgb(56, 51, 46)`); 72 73 // What should happen if you provide an adjuster without a negative percent? Currently, we treat that like having 0% for that adjuster. 74 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) -10%, hsl(30deg 30% 40%))`, `rgb(133, 102, 71)`); 75 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) 0%, hsl(30deg 30% 40%))`, `rgb(133, 102, 71)`); 76 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) hue -10%, hsl(30deg 30% 40%))`, `rgb(56, 51, 46)`); 77 testComputed(`color-mix(hsl, hsl(120deg 10% 20%) hue 0%, hsl(30deg 30% 40%))`, `rgb(56, 51, 46)`); 41 // What should happen if you provide a negative percent? https://github.com/w3c/csswg-drafts/issues/6047 42 testComputed(`color-mix(in hsl, hsl(120deg 10% 20%) -10%, hsl(30deg 30% 40%))`, `rgb(142, 97, 72)`); 78 43 79 44 … … 81 46 debug('color-mix(hwb, ...)'); 82 47 83 // Special case no adjusters or percentage is split 50-50. 84 testComputed(`color-mix(hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%))`, `rgb(147, 179, 52)`); // hwb(75deg 20% 30%) 48 testComputed(`color-mix(in hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%))`, `rgb(147, 179, 52)`); // hwb(75deg 20% 30%) 49 testComputed(`color-mix(in hwb, hwb(120deg 10% 20%) 25%, hwb(30deg 30% 40%))`, `rgb(166, 153, 64)`); 50 testComputed(`color-mix(in hwb, 25% hwb(120deg 10% 20%), hwb(30deg 30% 40%))`, `rgb(166, 153, 64)`); 51 testComputed(`color-mix(in hwb, hwb(120deg 10% 20%), 25% hwb(30deg 30% 40%))`, `rgb(96, 191, 39)`); 52 testComputed(`color-mix(in hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%) 25%)`, `rgb(96, 191, 39)`); 53 testComputed(`color-mix(in hwb, hwb(120deg 10% 20%) 25%, hwb(30deg 30% 40%) 75%)`, `rgb(166, 153, 64)`); 54 testComputed(`color-mix(in hwb, hwb(120deg 10% 20%) 50%, hwb(30deg 30% 40%) 150%)`, `rgb(166, 153, 64)`); // Scale down > 100% sum. 55 testComputed(`color-mix(in hwb, hwb(120deg 10% 20%) 12.5%, hwb(30deg 30% 40%) 37.5%)`, `rgb(166, 153, 64)`); // Scale up < 100% sum. 56 testComputed(`color-mix(in hwb, hwb(120deg 10% 20%) 0%, hwb(30deg 30% 40%))`, `rgb(153, 115, 77)`); 85 57 86 // Test precentage without adjusters. 87 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) 25%, hwb(30deg 30% 40%))`, `rgb(166, 153, 64)`); 88 testComputed(`color-mix(hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%) 25%)`, `rgb(96, 191, 39)`); 89 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) 25%, hwb(30deg 30% 40%) 75%)`, `rgb(166, 153, 64)`); 90 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) 50%, hwb(30deg 30% 40%) 150%)`, `rgb(166, 153, 64)`); // Scale down > 100% sum. 91 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) 12.5%, hwb(30deg 30% 40%) 37.5%)`, `rgb(166, 153, 64)`); // Scale up < 100% sum. 92 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) 0%, hwb(30deg 30% 40%))`, `rgb(153, 115, 77)`); 93 94 // Test per-channel adjusters. 95 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) hue 50%, hwb(30deg 30% 40%))`, `rgb(160, 204, 26)`); 96 testComputed(`color-mix(hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%) hue 50%)`, `rgb(160, 204, 26)`); 97 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) hue 50%, hwb(30deg 30% 40%) hue 50%)`, `rgb(160, 204, 26)`); 98 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) hue 100%, hwb(30deg 30% 40%))`, `rgb(26, 204, 26)`); 99 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) hue 50%, hwb(30deg 30% 40%))`, `rgb(160, 204, 26)`); 100 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) hue 50% whiteness 100%, hwb(30deg 30% 40%))`, `rgb(160, 204, 26)`); 101 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) hue 50% whiteness 100% blackness 100%, hwb(30deg 30% 40%))`, `rgb(160, 204, 26)`); 102 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) hue 50% whiteness 100% blackness 100% alpha 100%, hwb(30deg 30% 40%))`, `rgb(160, 204, 26)`); 103 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) hue 50%, hwb(30deg 30% 40%) whiteness 0%)`, `rgb(160, 204, 26)`); 104 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) hue 50%, hwb(30deg 30% 40%) whiteness 0% blackness 0%)`, `rgb(160, 204, 26)`); 105 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) hue 50%, hwb(30deg 30% 40%) whiteness 0% blackness 0% alpha 0%)`, `rgb(160, 204, 26)`); 106 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) hue 50% whiteness 75%, hwb(30deg 30% 40%))`, `rgb(163, 204, 39)`); 107 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) hue 50% whiteness 75% blackness 15%, hwb(30deg 30% 40%))`, `rgb(130, 161, 39)`); 108 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) hue 50% whiteness 75% blackness 15% alpha 10%, hwb(30deg 30% 40%))`, `rgb(130, 161, 39)`); 109 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) hue 60%, hwb(30deg 30% 40%))`, `rgb(133, 204, 26)`); 110 testComputed(`color-mix(hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%) hue 40%)`, `rgb(133, 204, 26)`); 111 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) hue 60%, hwb(30deg 30% 40%) hue 40%)`, `rgb(133, 204, 26)`); 112 113 // Test mix that creates whiteness + blackness > 100%. 114 testComputed(`color-mix(hwb, hwb(120deg 75% 25%) whiteness 100%, hwb(120deg 25% 75%) blackness 100%)`, `rgb(128, 128, 128)`); 115 116 // FIXME: Test hue mixes with modifiers. 117 118 119 // Open questions. 120 121 // What should happen if you provide the same adjuster more than once? Currently, we do last one wins. 122 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) hue 60% hue 40%, hwb(30deg 30% 40%))`, `rgb(186, 204, 26)`); 123 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) hue 40%, hwb(30deg 30% 40%))`, `rgb(186, 204, 26)`); 124 125 // What should happen if you provide an adjuster without a paihue percent? Currently, we treat that like having 0% for that adjuster. 126 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) hue, hwb(30deg 30% 40%))`, `rgb(204, 115, 26)`); 127 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) hue 0%, hwb(30deg 30% 40%))`, `rgb(204, 115, 26)`); 128 129 // What should happen if you provide an adjuster without a negative percent? Currently, we treat that like having 0% for that adjuster. 130 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) -10%, hwb(30deg 30% 40%))`, `rgb(153, 115, 77)`); 131 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) 0%, hwb(30deg 30% 40%))`, `rgb(153, 115, 77)`); 132 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) hue -10%, hwb(30deg 30% 40%))`, `rgb(204, 115, 26)`); 133 testComputed(`color-mix(hwb, hwb(120deg 10% 20%) hue 0%, hwb(30deg 30% 40%))`, `rgb(204, 115, 26)`); 58 // What should happen if you provide a negative percent? https://github.com/w3c/csswg-drafts/issues/6047 59 testComputed(`color-mix(in hwb, hwb(120deg 10% 20%) -10%, hwb(30deg 30% 40%))`, `rgb(148, 105, 82)`); 134 60 135 61 … … 137 63 debug('color-mix(lch, ...)'); 138 64 139 // Special case no adjusters or percentage is split 50-50. 140 testComputed(`color-mix(lch, lch(10% 20 30deg / .4), lch(50% 60 70deg / .8))`, `lch(30% 40 50 / 0.6)`); 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)`); 141 74 142 // Test precentage without adjusters. 143 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) 25%, lch(50% 60 70deg / .8))`, `lch(40% 50 60 / 0.7)`); 144 testComputed(`color-mix(lch, lch(10% 20 30deg / .4), lch(50% 60 70deg / .8) 25%)`, `lch(20% 30 40 / 0.5)`); 145 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) 25%, lch(50% 60 70deg / .8) 75%)`, `lch(40% 50 60 / 0.7)`); 146 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) 50%, lch(50% 60 70deg / .8) 150%)`, `lch(40% 50 60 / 0.7)`); // Scale down > 100% sum. 147 testComputed(`color-mix(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. 148 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) 0%, lch(50% 60 70deg / .8))`, `lch(50% 60 70 / 0.8)`); 149 150 // Test per-channel adjusters. 151 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) lightness 50%, lch(50% 60 70deg / .8))`, `lch(30% 20 30 / 0.4)`); 152 testComputed(`color-mix(lch, lch(10% 20 30deg / .4), lch(50% 60 70deg / .8) lightness 50%)`, `lch(30% 20 30 / 0.4)`); 153 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) lightness 50%, lch(50% 60 70deg / .8) lightness 50%)`, `lch(30% 20 30 / 0.4)`); 154 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) lightness 100%, lch(50% 60 70deg / .8))`, `lch(10% 20 30 / 0.4)`); 155 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) lightness 50%, lch(50% 60 70deg / .8))`, `lch(30% 20 30 / 0.4)`); 156 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) lightness 50% chroma 100%, lch(50% 60 70deg / .8))`, `lch(30% 20 30 / 0.4)`); 157 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) lightness 50% chroma 100% hue 100%, lch(50% 60 70deg / .8))`, `lch(30% 20 30 / 0.4)`); 158 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) lightness 50% chroma 100% hue 100% alpha 100%, lch(50% 60 70deg / .8))`, `lch(30% 20 30 / 0.4)`); 159 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) lightness 50%, lch(50% 60 70deg / .8) chroma 0%)`, `lch(30% 20 30 / 0.4)`); 160 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) lightness 50%, lch(50% 60 70deg / .8) chroma 0% hue 0%)`, `lch(30% 20 30 / 0.4)`); 161 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) lightness 50%, lch(50% 60 70deg / .8) chroma 0% hue 0% alpha 0%)`, `lch(30% 20 30 / 0.4)`); 162 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) lightness 50% chroma 75%, lch(50% 60 70deg / .8))`, `lch(30% 30 30 / 0.4)`); 163 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) lightness 50% chroma 75% hue 15%, lch(50% 60 70deg / .8))`, `lch(30% 30 64 / 0.4)`); 164 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) lightness 50% chroma 75% hue 15% alpha 10%, lch(50% 60 70deg / .8))`, `lch(30% 30 64 / 0.76)`); 165 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) lightness 60%, lch(50% 60 70deg / .8))`, `lch(26% 20 30 / 0.4)`); 166 testComputed(`color-mix(lch, lch(10% 20 30deg / .4), lch(50% 60 70deg / .8) lightness 40%)`, `lch(26% 20 30 / 0.4)`); 167 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) lightness 60%, lch(50% 60 70deg / .8) lightness 40%)`, `lch(26% 20 30 / 0.4)`); 168 169 // FIXME: Test hue mixes with modifiers. 170 171 // Open questions. 172 173 // What should happen if you provide the same adjuster more than once? Currently, we do last one wins. 174 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) lightness 60% lightness 40%, lch(50% 60 70deg / .8))`, `lch(34% 20 30 / 0.4)`); 175 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) lightness 40%, lch(50% 60 70deg / .8))`, `lch(34% 20 30 / 0.4)`); 176 177 // What should happen if you provide an adjuster without a pailightness percent? Currently, we treat that like having 0% for that adjuster. 178 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) lightness, lch(50% 60 70deg / .8))`, `lch(50% 20 30 / 0.4)`); 179 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) lightness 0%, lch(50% 60 70deg / .8))`, `lch(50% 20 30 / 0.4)`); 180 181 // What should happen if you provide an adjuster without a negative percent? Currently, we treat that like having 0% for that adjuster. 182 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) -10%, lch(50% 60 70deg / .8))`, `lch(50% 60 70 / 0.8)`); 183 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) 0%, lch(50% 60 70deg / .8))`, `lch(50% 60 70 / 0.8)`); 184 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) lightness -10%, lch(50% 60 70deg / .8))`, `lch(50% 20 30 / 0.4)`); 185 testComputed(`color-mix(lch, lch(10% 20 30deg / .4) lightness 0%, lch(50% 60 70deg / .8))`, `lch(50% 20 30 / 0.4)`); 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)`); 186 77 187 78 … … 189 80 debug('color-mix(lab, ...)'); 190 81 191 // Special case no adjusters or percentage is split 50-50. 192 testComputed(`color-mix(lab, lab(10% 20 30 / .4), lab(50% 60 70 / .8))`, `lab(30% 40 50 / 0.6)`); 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)`); 193 91 194 // Test precentage without adjusters. 195 testComputed(`color-mix(lab, lab(10% 20 30 / .4) 25%, lab(50% 60 70 / .8))`, `lab(40% 50 60 / 0.7)`); 196 testComputed(`color-mix(lab, lab(10% 20 30 / .4), lab(50% 60 70 / .8) 25%)`, `lab(20% 30 40 / 0.5)`); 197 testComputed(`color-mix(lab, lab(10% 20 30 / .4) 25%, lab(50% 60 70 / .8) 75%)`, `lab(40% 50 60 / 0.7)`); 198 testComputed(`color-mix(lab, lab(10% 20 30 / .4) 50%, lab(50% 60 70 / .8) 150%)`, `lab(40% 50 60 / 0.7)`); // Scale down > 100% sum. 199 testComputed(`color-mix(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. 200 testComputed(`color-mix(lab, lab(10% 20 30 / .4) 0%, lab(50% 60 70 / .8))`, `lab(50% 60 70 / 0.8)`); 201 202 // Test per-channel adjusters. 203 testComputed(`color-mix(lab, lab(10% 20 30 / .4) lightness 50%, lab(50% 60 70 / .8))`, `lab(30% 20 30 / 0.4)`); 204 testComputed(`color-mix(lab, lab(10% 20 30 / .4), lab(50% 60 70 / .8) lightness 50%)`, `lab(30% 20 30 / 0.4)`); 205 testComputed(`color-mix(lab, lab(10% 20 30 / .4) lightness 50%, lab(50% 60 70 / .8) lightness 50%)`, `lab(30% 20 30 / 0.4)`); 206 testComputed(`color-mix(lab, lab(10% 20 30 / .4) lightness 100%, lab(50% 60 70 / .8))`, `lab(10% 20 30 / 0.4)`); 207 testComputed(`color-mix(lab, lab(10% 20 30 / .4) lightness 50%, lab(50% 60 70 / .8))`, `lab(30% 20 30 / 0.4)`); 208 testComputed(`color-mix(lab, lab(10% 20 30 / .4) lightness 50% a 100%, lab(50% 60 70 / .8))`, `lab(30% 20 30 / 0.4)`); 209 testComputed(`color-mix(lab, lab(10% 20 30 / .4) lightness 50% a 100% b 100%, lab(50% 60 70 / .8))`, `lab(30% 20 30 / 0.4)`); 210 testComputed(`color-mix(lab, lab(10% 20 30 / .4) lightness 50% a 100% b 100% alpha 100%, lab(50% 60 70 / .8))`, `lab(30% 20 30 / 0.4)`); 211 testComputed(`color-mix(lab, lab(10% 20 30 / .4) lightness 50%, lab(50% 60 70 / .8) a 0%)`, `lab(30% 20 30 / 0.4)`); 212 testComputed(`color-mix(lab, lab(10% 20 30 / .4) lightness 50%, lab(50% 60 70 / .8) a 0% b 0%)`, `lab(30% 20 30 / 0.4)`); 213 testComputed(`color-mix(lab, lab(10% 20 30 / .4) lightness 50%, lab(50% 60 70 / .8) a 0% b 0% alpha 0%)`, `lab(30% 20 30 / 0.4)`); 214 testComputed(`color-mix(lab, lab(10% 20 30 / .4) lightness 50% a 75%, lab(50% 60 70 / .8))`, `lab(30% 30 30 / 0.4)`); 215 testComputed(`color-mix(lab, lab(10% 20 30 / .4) lightness 50% a 75% b 15%, lab(50% 60 70 / .8))`, `lab(30% 30 64 / 0.4)`); 216 testComputed(`color-mix(lab, lab(10% 20 30 / .4) lightness 50% a 75% b 15% alpha 10%, lab(50% 60 70 / .8))`, `lab(30% 30 64 / 0.76)`); 217 testComputed(`color-mix(lab, lab(10% 20 30 / .4) lightness 60%, lab(50% 60 70 / .8))`, `lab(26% 20 30 / 0.4)`); 218 testComputed(`color-mix(lab, lab(10% 20 30 / .4), lab(50% 60 70 / .8) lightness 40%)`, `lab(26% 20 30 / 0.4)`); 219 testComputed(`color-mix(lab, lab(10% 20 30 / .4) lightness 60%, lab(50% 60 70 / .8) lightness 40%)`, `lab(26% 20 30 / 0.4)`); 220 221 // Open questions. 222 223 // What should happen if you provide the same adjuster more than once? Currently, we do last one wins. 224 testComputed(`color-mix(lab, lab(10% 20 30 / .4) lightness 60% lightness 40%, lab(50% 60 70 / .8))`, `lab(34% 20 30 / 0.4)`); 225 226 // What should happen if you provide an adjuster without a pailightness percent? Currently, we treat that like having 0% for that adjuster. 227 testComputed(`color-mix(lab, lab(10% 20 30 / .4) lightness, lab(50% 60 70 / .8))`, `lab(50% 20 30 / 0.4)`); 228 testComputed(`color-mix(lab, lab(10% 20 30 / .4) lightness 0%, lab(50% 60 70 / .8))`, `lab(50% 20 30 / 0.4)`); 229 230 // What should happen if you provide an adjuster without a negative percent? Currently, we treat that like having 0% for that adjuster. 231 testComputed(`color-mix(lab, lab(10% 20 30 / .4) -10%, lab(50% 60 70 / .8))`, `lab(50% 60 70 / 0.8)`); 232 testComputed(`color-mix(lab, lab(10% 20 30 / .4) lightness -10%, lab(50% 60 70 / .8))`, `lab(50% 20 30 / 0.4)`); 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)`); 233 94 234 95 debug(''); 235 96 debug('color-mix(srgb, ...)'); 236 97 237 // Special case no adjusters or percentage is split 50-50. 238 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4), color(srgb .5 .6 .7 / .8))`, `color(srgb 0.3 0.4 0.5 / 0.6)`); 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)`); 239 107 240 // Test precentage without adjusters. 241 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4) 25%, color(srgb .5 .6 .7 / .8))`, `color(srgb 0.4 0.5 0.6 / 0.7)`); 242 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4), color(srgb .5 .6 .7 / .8) 25%)`, `color(srgb 0.2 0.3 0.4 / 0.5)`); 243 testComputed(`color-mix(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)`); 244 testComputed(`color-mix(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. 245 testComputed(`color-mix(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. 246 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4) 0%, color(srgb .5 .6 .7 / .8))`, `color(srgb 0.5 0.6 0.7 / 0.8)`); 247 248 // Test per-channel adjusters. 249 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4) red 50%, color(srgb .5 .6 .7 / .8))`, `color(srgb 0.3 0.2 0.3 / 0.4)`); 250 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4), color(srgb .5 .6 .7 / .8) red 50%)`, `color(srgb 0.3 0.2 0.3 / 0.4)`); 251 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4) red 50%, color(srgb .5 .6 .7 / .8) red 50%)`, `color(srgb 0.3 0.2 0.3 / 0.4)`); 252 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4) red 100%, color(srgb .5 .6 .7 / .8))`, `color(srgb 0.1 0.2 0.3 / 0.4)`); 253 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4) red 50%, color(srgb .5 .6 .7 / .8))`, `color(srgb 0.3 0.2 0.3 / 0.4)`); 254 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4) red 50% green 100%, color(srgb .5 .6 .7 / .8))`, `color(srgb 0.3 0.2 0.3 / 0.4)`); 255 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4) red 50% green 100% blue 100%, color(srgb .5 .6 .7 / .8))`, `color(srgb 0.3 0.2 0.3 / 0.4)`); 256 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4) red 50% green 100% blue 100% alpha 100%, color(srgb .5 .6 .7 / .8))`, `color(srgb 0.3 0.2 0.3 / 0.4)`); 257 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4) red 50%, color(srgb .5 .6 .7 / .8) green 0%)`, `color(srgb 0.3 0.2 0.3 / 0.4)`); 258 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4) red 50%, color(srgb .5 .6 .7 / .8) green 0% blue 0%)`, `color(srgb 0.3 0.2 0.3 / 0.4)`); 259 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4) red 50%, color(srgb .5 .6 .7 / .8) green 0% blue 0% alpha 0%)`, `color(srgb 0.3 0.2 0.3 / 0.4)`); 260 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4) red 50% green 75%, color(srgb .5 .6 .7 / .8))`, `color(srgb 0.3 0.3 0.3 / 0.4)`); 261 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4) red 50% green 75% blue 15%, color(srgb .5 .6 .7 / .8))`, `color(srgb 0.3 0.3 0.64 / 0.4)`); 262 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4) red 50% green 75% blue 15% alpha 10%, color(srgb .5 .6 .7 / .8))`, `color(srgb 0.3 0.3 0.64 / 0.76)`); 263 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4) red 60%, color(srgb .5 .6 .7 / .8))`, `color(srgb 0.26 0.2 0.3 / 0.4)`); 264 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4), color(srgb .5 .6 .7 / .8) red 40%)`, `color(srgb 0.26 0.2 0.3 / 0.4)`); 265 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4) red 60%, color(srgb .5 .6 .7 / .8) red 40%)`, `color(srgb 0.26 0.2 0.3 / 0.4)`); 266 267 // Open questions. 268 269 // What should happen if you provide the same adjuster more than once? Currently, we do last one wins. 270 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4) red 60% red 40%, color(srgb .5 .6 .7 / .8))`, `color(srgb 0.34 0.2 0.3 / 0.4)`); 271 272 // What should happen if you provide an adjuster without a paired percent? Currently, we treat that like having 0% for that adjuster. 273 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4) red, color(srgb .5 .6 .7 / .8))`, `color(srgb 0.5 0.2 0.3 / 0.4)`); 274 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4) red 0%, color(srgb .5 .6 .7 / .8))`, `color(srgb 0.5 0.2 0.3 / 0.4)`); 275 276 // What should happen if you provide an adjuster without a negative percent? Currently, we treat that like having 0% for that adjuster. 277 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4) -10%, color(srgb .5 .6 .7 / .8))`, `color(srgb 0.5 0.6 0.7 / 0.8)`); 278 testComputed(`color-mix(srgb, color(srgb .1 .2 .3 / .4) red -10%, color(srgb .5 .6 .7 / .8))`, `color(srgb 0.5 0.2 0.3 / 0.4)`); 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)`); 279 110 280 111 … … 282 113 debug('color-mix(xyz, ...)'); 283 114 284 // Special case no adjusters or percentage is split 50-50. 285 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4), color(xyz .5 .6 .7 / .8))`, `color(xyz 0.3 0.4 0.5 / 0.6)`); 115 testComputed(`color-mix(in xyz, color(xyz .1 .2 .3 / .4), color(xyz .5 .6 .7 / .8))`, `color(xyz 0.3 0.4 0.5 / 0.6)`); 116 testComputed(`color-mix(in xyz, color(xyz .1 .2 .3 / .4) 25%, color(xyz .5 .6 .7 / .8))`, `color(xyz 0.4 0.5 0.6 / 0.7)`); 117 testComputed(`color-mix(in xyz, 25% color(xyz .1 .2 .3 / .4), color(xyz .5 .6 .7 / .8))`, `color(xyz 0.4 0.5 0.6 / 0.7)`); 118 testComputed(`color-mix(in xyz, color(xyz .1 .2 .3 / .4), color(xyz .5 .6 .7 / .8) 25%)`, `color(xyz 0.2 0.3 0.4 / 0.5)`); 119 testComputed(`color-mix(in xyz, color(xyz .1 .2 .3 / .4), 25% color(xyz .5 .6 .7 / .8))`, `color(xyz 0.2 0.3 0.4 / 0.5)`); 120 testComputed(`color-mix(in xyz, color(xyz .1 .2 .3 / .4) 25%, color(xyz .5 .6 .7 / .8) 75%)`, `color(xyz 0.4 0.5 0.6 / 0.7)`); 121 testComputed(`color-mix(in xyz, color(xyz .1 .2 .3 / .4) 50%, color(xyz .5 .6 .7 / .8) 150%)`, `color(xyz 0.4 0.5 0.6 / 0.7)`); // Scale down > 100% sum. 122 testComputed(`color-mix(in xyz, color(xyz .1 .2 .3 / .4) 12.5%, color(xyz .5 .6 .7 / .8) 37.5%)`, `color(xyz 0.4 0.5 0.6 / 0.7)`); // Scale up < 100% sum. 123 testComputed(`color-mix(in xyz, color(xyz .1 .2 .3 / .4) 0%, color(xyz .5 .6 .7 / .8))`, `color(xyz 0.5 0.6 0.7 / 0.8)`); 286 124 287 // Test precentage without adjusters. 288 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4) 25%, color(xyz .5 .6 .7 / .8))`, `color(xyz 0.4 0.5 0.6 / 0.7)`); 289 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4), color(xyz .5 .6 .7 / .8) 25%)`, `color(xyz 0.2 0.3 0.4 / 0.5)`); 290 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4) 25%, color(xyz .5 .6 .7 / .8) 75%)`, `color(xyz 0.4 0.5 0.6 / 0.7)`); 291 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4) 50%, color(xyz .5 .6 .7 / .8) 150%)`, `color(xyz 0.4 0.5 0.6 / 0.7)`); // Scale down > 100% sum. 292 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4) 12.5%, color(xyz .5 .6 .7 / .8) 37.5%)`, `color(xyz 0.4 0.5 0.6 / 0.7)`); // Scale up < 100% sum. 293 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4) 0%, color(xyz .5 .6 .7 / .8))`, `color(xyz 0.5 0.6 0.7 / 0.8)`); 294 295 // Test per-channel adjusters. 296 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4) x 50%, color(xyz .5 .6 .7 / .8))`, `color(xyz 0.3 0.2 0.3 / 0.4)`); 297 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4), color(xyz .5 .6 .7 / .8) x 50%)`, `color(xyz 0.3 0.2 0.3 / 0.4)`); 298 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4) x 50%, color(xyz .5 .6 .7 / .8) x 50%)`, `color(xyz 0.3 0.2 0.3 / 0.4)`); 299 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4) x 100%, color(xyz .5 .6 .7 / .8))`, `color(xyz 0.1 0.2 0.3 / 0.4)`); 300 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4) x 50%, color(xyz .5 .6 .7 / .8))`, `color(xyz 0.3 0.2 0.3 / 0.4)`); 301 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4) x 50% y 100%, color(xyz .5 .6 .7 / .8))`, `color(xyz 0.3 0.2 0.3 / 0.4)`); 302 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4) x 50% y 100% z 100%, color(xyz .5 .6 .7 / .8))`, `color(xyz 0.3 0.2 0.3 / 0.4)`); 303 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4) x 50% y 100% z 100% alpha 100%, color(xyz .5 .6 .7 / .8))`, `color(xyz 0.3 0.2 0.3 / 0.4)`); 304 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4) x 50%, color(xyz .5 .6 .7 / .8) y 0%)`, `color(xyz 0.3 0.2 0.3 / 0.4)`); 305 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4) x 50%, color(xyz .5 .6 .7 / .8) y 0% z 0%)`, `color(xyz 0.3 0.2 0.3 / 0.4)`); 306 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4) x 50%, color(xyz .5 .6 .7 / .8) y 0% z 0% alpha 0%)`, `color(xyz 0.3 0.2 0.3 / 0.4)`); 307 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4) x 50% y 75%, color(xyz .5 .6 .7 / .8))`, `color(xyz 0.3 0.3 0.3 / 0.4)`); 308 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4) x 50% y 75% z 15%, color(xyz .5 .6 .7 / .8))`, `color(xyz 0.3 0.3 0.64 / 0.4)`); 309 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4) x 50% y 75% z 15% alpha 10%, color(xyz .5 .6 .7 / .8))`, `color(xyz 0.3 0.3 0.64 / 0.76)`); 310 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4) x 60%, color(xyz .5 .6 .7 / .8))`, `color(xyz 0.26 0.2 0.3 / 0.4)`); 311 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4), color(xyz .5 .6 .7 / .8) x 40%)`, `color(xyz 0.26 0.2 0.3 / 0.4)`); 312 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4) x 60%, color(xyz .5 .6 .7 / .8) x 40%)`, `color(xyz 0.26 0.2 0.3 / 0.4)`); 313 314 // Open questions. 315 316 // What should happen if you provide the same adjuster more than once? Currently, we do last one wins. 317 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4) x 60% x 40%, color(xyz .5 .6 .7 / .8))`, `color(xyz 0.34 0.2 0.3 / 0.4)`); 318 319 // What should happen if you provide an adjuster without a paix percent? Currently, we treat that like having 0% for that adjuster. 320 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4) x, color(xyz .5 .6 .7 / .8))`, `color(xyz 0.5 0.2 0.3 / 0.4)`); 321 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4) x 0%, color(xyz .5 .6 .7 / .8))`, `color(xyz 0.5 0.2 0.3 / 0.4)`); 322 323 // What should happen if you provide an adjuster without a negative percent? Currently, we treat that like having 0% for that adjuster. 324 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4) -10%, color(xyz .5 .6 .7 / .8))`, `color(xyz 0.5 0.6 0.7 / 0.8)`); 325 testComputed(`color-mix(xyz, color(xyz .1 .2 .3 / .4) x -10%, color(xyz .5 .6 .7 / .8))`, `color(xyz 0.5 0.2 0.3 / 0.4)`); 125 // What should happen if you provide a negative percent? https://github.com/w3c/csswg-drafts/issues/6047 126 testComputed(`color-mix(in xyz, color(xyz .1 .2 .3 / .4) -10%, color(xyz .5 .6 .7 / .8))`, `color(xyz 0.54 0.64000005 0.74 / 0.84000003)`); 326 127 </script> 327 128 -
trunk/Source/WebCore/ChangeLog
r274943 r274947 1 2021-03-24 Sam Weinig <weinig@apple.com> 2 3 Update CSS Color 5 color-mix() implementation to match the latest draft spec 4 https://bugs.webkit.org/show_bug.cgi?id=223665 5 6 Reviewed by Simon Fraser. 7 8 Update to the latest draft spec, which dramatically reduces the complexity of color-mix() 9 by remove per-component adjusters. 10 11 * css/CSSValueKeywords.in: 12 * css/parser/CSSPropertyParserHelpers.cpp: 13 (WebCore::CSSPropertyParserHelpers::normalizeWhitenessBlackness): 14 (WebCore::CSSPropertyParserHelpers::consumeColorMixColorSpaceAndComma): 15 (WebCore::CSSPropertyParserHelpers::consumeColorMixComponent): 16 (WebCore::CSSPropertyParserHelpers::normalizedMixPercentages): 17 (WebCore::CSSPropertyParserHelpers::makeColorTypeByNormalizingComponentsAfterMix): 18 (WebCore::CSSPropertyParserHelpers::makeColorTypeByNormalizingComponentsAfterMix<HWBA<float>>): 19 (WebCore::CSSPropertyParserHelpers::makeColorTypeByNormalizingComponentsAfterMix<HSLA<float>>): 20 (WebCore::CSSPropertyParserHelpers::fixupHueComponentsPriorToMix): 21 (WebCore::CSSPropertyParserHelpers::mixColorComponentsInColorSpace): 22 (WebCore::CSSPropertyParserHelpers::mixColorComponents): 23 (WebCore::CSSPropertyParserHelpers::parseColorMixFunctionParameters): 24 (WebCore::CSSPropertyParserHelpers::HueColorAdjuster::fixupAnglesForInterpolation): Deleted. 25 (WebCore::CSSPropertyParserHelpers::HueColorAdjuster::HueColorAdjuster): Deleted. 26 (WebCore::CSSPropertyParserHelpers::ColorAdjuster::ColorAdjuster): Deleted. 27 (WebCore::CSSPropertyParserHelpers::consumeAdjuster): Deleted. 28 (WebCore::CSSPropertyParserHelpers::consumeAndUpdateAdjusterAtIndex): Deleted. 29 (WebCore::CSSPropertyParserHelpers::consumeAndUpdateAdjuster): Deleted. 30 (WebCore::CSSPropertyParserHelpers::consumeAdjusters): Deleted. 31 (WebCore::CSSPropertyParserHelpers::consumeMixComponents): Deleted. 32 (WebCore::CSSPropertyParserHelpers::normalizeAdjusterValues): Deleted. 33 (WebCore::CSSPropertyParserHelpers::remainingAdjustment): Deleted. 34 (WebCore::CSSPropertyParserHelpers::mixComponent): Deleted. 35 (WebCore::CSSPropertyParserHelpers::mixComponentAtIndex): Deleted. 36 (WebCore::CSSPropertyParserHelpers::mix): Deleted. 37 (WebCore::CSSPropertyParserHelpers::parseColorMixFunctionParametersUsingAdjusters): Deleted. 38 Update to the new syntax and remove component adjusters. They may come back for color-adjust() 39 in the future. 40 41 * platform/graphics/ColorModels.h: 42 * platform/graphics/ColorTypes.h: 43 (WebCore::clampedComponent): 44 (WebCore::assertInRange): 45 * platform/graphics/ColorUtilities.h: 46 (WebCore::invertedColorWithOverriddenAlpha): 47 Add support in the color models for annotating more about each component, now including 48 the type (angle, number or percentage). This allows algorithms generic algorithms to 49 operate on abstract color type components without specializing for each color type. 50 1 51 2021-03-24 Zan Dobersek <zdobersek@igalia.com> 2 52 -
trunk/Source/WebCore/css/CSSValueKeywords.in
r274793 r274947 1444 1444 // color-mix() 1445 1445 color-mix 1446 shorter 1447 longer 1448 increasing 1449 decreasing 1450 specified 1451 lightness 1452 chroma 1453 whiteness 1454 blackness 1446 in 1455 1447 1456 1448 // prefers-default-appearance -
trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp
r274053 r274947 1105 1105 } 1106 1106 1107 template<typename ComponentType> 1107 1108 struct WhitenessBlackness { 1108 double whiteness;1109 double blackness;1109 ComponentType whiteness; 1110 ComponentType blackness; 1110 1111 }; 1111 static WhitenessBlackness normalizeWhitenessBlackness(double whiteness, double blackness) 1112 1113 template<typename ComponentType> static auto normalizeWhitenessBlackness(ComponentType whiteness, ComponentType blackness) -> WhitenessBlackness<ComponentType> 1112 1114 { 1113 1115 // Values outside of these ranges are not invalid, but are clamped to the 1114 1116 // ranges defined here at computed-value time. 1115 WhitenessBlackness result {1116 clampTo (whiteness, 0.0, 100.0),1117 clampTo (blackness, 0.0, 100.0)1117 WhitenessBlackness<ComponentType> result { 1118 clampTo<ComponentType>(whiteness, 0.0, 100.0), 1119 clampTo<ComponentType>(blackness, 0.0, 100.0) 1118 1120 }; 1119 1121 … … 1552 1554 } 1553 1555 1554 struct HueColorAdjuster { 1555 enum class Type { 1556 Shorter, 1557 Longer, 1558 Increasing, 1559 Decreasing, 1560 Specified 1556 enum class ColorMixColorSpace { 1557 Srgb, 1558 Hsl, 1559 Hwb, 1560 Xyz, 1561 Lab, 1562 Lch 1563 }; 1564 1565 static Optional<ColorMixColorSpace> consumeColorMixColorSpaceAndComma(CSSParserTokenRange& args) 1566 { 1567 auto consumeIdentAndComma = [](CSSParserTokenRange& args, ColorMixColorSpace colorSpace) -> Optional<ColorMixColorSpace> { 1568 consumeIdentRaw(args); 1569 if (!consumeCommaIncludingWhitespace(args)) 1570 return WTF::nullopt; 1571 return colorSpace; 1561 1572 }; 1562 1573 1563 static std::pair<double, double> fixupAnglesForInterpolation(double theta1, double theta2, Type type) 1564 { 1565 ASSERT(theta1 >= 0.0); 1566 ASSERT(theta1 <= 360.0); 1567 ASSERT(theta2 >= 0.0); 1568 ASSERT(theta2 <= 360.0); 1569 1570 switch (type) { 1571 case Type::Shorter: { 1572 auto difference = theta2 - theta1; 1573 if (difference > 180.0) 1574 return { theta1 + 360.0, theta2 }; 1575 if (difference < -180.0) 1576 return { theta1, theta2 + 360.0 }; 1577 return { theta1, theta2 }; 1578 } 1579 case Type::Longer: { 1580 auto difference = theta2 - theta1; 1581 if (difference >= 0.0 && difference < 180.0) 1582 return { theta1 + 360.0, theta2 }; 1583 if (difference >= -180.0 && difference < 0) 1584 return { theta1, theta2 + 360.0 }; 1585 return { theta1, theta2 }; 1586 } 1587 case Type::Increasing: { 1588 if (theta2 < theta1) 1589 return { theta1, theta2 + 360.0 }; 1590 return { theta1, theta2 }; 1591 } 1592 case Type::Decreasing: { 1593 if (theta1 < theta2) 1594 return { theta1 + 360.0, theta2 }; 1595 return { theta1, theta2 }; 1596 } 1597 case Type::Specified: 1598 return { theta1, theta2 }; 1599 } 1600 1601 RELEASE_ASSERT_NOT_REACHED(); 1602 } 1603 1604 HueColorAdjuster(double value = 0.0, Type type = Type::Shorter) 1605 : type { type } 1606 , value { value } 1607 { 1608 } 1609 1610 Type type; 1611 double value; 1574 switch (args.peek().id()) { 1575 case CSSValueHsl: 1576 return consumeIdentAndComma(args, ColorMixColorSpace::Hsl); 1577 case CSSValueHwb: 1578 return consumeIdentAndComma(args, ColorMixColorSpace::Hwb); 1579 case CSSValueLch: 1580 return consumeIdentAndComma(args, ColorMixColorSpace::Lch); 1581 case CSSValueLab: 1582 return consumeIdentAndComma(args, ColorMixColorSpace::Lab); 1583 case CSSValueXyz: 1584 return consumeIdentAndComma(args, ColorMixColorSpace::Xyz); 1585 case CSSValueSRGB: 1586 return consumeIdentAndComma(args, ColorMixColorSpace::Srgb); 1587 default: 1588 return WTF::nullopt; 1589 } 1590 } 1591 1592 struct ColorMixComponent { 1593 Color color; 1594 Optional<double> percentage; 1612 1595 }; 1613 1596 1614 template<typename C, CSSValueID ID0, typename Channel0, CSSValueID ID1, typename Channel1, CSSValueID ID2, typename Channel2, CSSValueID ID3, typename Channel3> 1615 struct ColorAdjuster { 1616 using ColorType = C; 1617 static constexpr auto channelCSSValueIDs = std::make_tuple(ID0, ID1, ID2, ID3); 1618 1619 ColorAdjuster() = default; 1620 explicit ColorAdjuster(double percentage) 1621 : channels { percentage, percentage, percentage, percentage } 1622 { 1623 } 1624 1625 std::tuple<Optional<Channel0>, Optional<Channel1>, Optional<Channel2>, Optional<Channel3>> channels; 1597 static Optional<ColorMixComponent> consumeColorMixComponent(CSSParserTokenRange& args, const CSSParserContext& context) 1598 { 1599 ColorMixComponent result; 1600 1601 if (auto percentage = consumePercentRaw(args)) 1602 result.percentage = percentage; 1603 1604 result.color = consumeOriginColor(args, context); 1605 if (!result.color.isValid()) 1606 return WTF::nullopt; 1607 1608 if (!result.percentage) { 1609 if (auto percentage = consumePercentRaw(args)) 1610 result.percentage = percentage; 1611 } 1612 1613 return result; 1614 } 1615 1616 struct ColorMixPercentages { 1617 double p1; 1618 double p2; 1626 1619 }; 1627 1620 1628 using HSLColorAdjuster = ColorAdjuster<HSLA<float>, CSSValueHue, HueColorAdjuster, CSSValueSaturation, double, CSSValueLightness, double, CSSValueAlpha, double>; 1629 using HWBColorAdjuster = ColorAdjuster<HWBA<float>, CSSValueHue, HueColorAdjuster, CSSValueWhiteness, double, CSSValueBlackness, double, CSSValueAlpha, double>; 1630 using LCHColorAdjuster = ColorAdjuster<LCHA<float>, CSSValueLightness, double, CSSValueChroma, HueColorAdjuster, CSSValueHue, double, CSSValueAlpha, double>; 1631 using LabColorAdjuster = ColorAdjuster<Lab<float>, CSSValueLightness, double, CSSValueA, double, CSSValueB, double, CSSValueAlpha, double>; 1632 using SRGBColorAdjuster = ColorAdjuster<SRGBA<float>, CSSValueRed, double, CSSValueGreen, double, CSSValueBlue, double, CSSValueAlpha, double>; 1633 using XYZColorAdjuster = ColorAdjuster<XYZA<float, WhitePoint::D50>, CSSValueX, double, CSSValueY, double, CSSValueZ, double, CSSValueAlpha, double>; 1634 1635 template<typename Adjuster> struct ColorMixComponent { 1636 Color color; 1637 Adjuster adjuster; 1638 }; 1639 1640 template<CSSValueID Ident, typename T> struct AdjusterConsumer; 1641 1642 template<CSSValueID Ident> struct AdjusterConsumer<Ident, HueColorAdjuster> { 1643 static Optional<HueColorAdjuster> consume(CSSParserTokenRange& args) 1644 { 1645 if (!consumeIdentRaw<Ident>(args)) 1646 return WTF::nullopt; 1647 1648 HueColorAdjuster result; 1649 if (auto hueAdjustmentType = consumeHueAdjustmentType(args)) 1650 result.type = *hueAdjustmentType; 1651 1652 // FIXME: Is clamping to 0 for negative percentages the right thing to do? 1653 if (auto percentage = consumePercentRaw(args)) 1654 result.value = std::max(0.0, *percentage); 1655 1656 // FIXME: Should an adjuster without a percetange be allowed? 1657 // e.g color-mix(hsl, teal hue, red); 1658 1659 return result; 1660 } 1661 1662 static Optional<HueColorAdjuster::Type> consumeHueAdjustmentType(CSSParserTokenRange& args) 1663 { 1664 switch (args.peek().id()) { 1665 case CSSValueShorter: 1666 consumeIdentRaw(args); 1667 return HueColorAdjuster::Type::Shorter; 1668 case CSSValueLonger: 1669 consumeIdentRaw(args); 1670 return HueColorAdjuster::Type::Longer; 1671 case CSSValueIncreasing: 1672 consumeIdentRaw(args); 1673 return HueColorAdjuster::Type::Increasing; 1674 case CSSValueDecreasing: 1675 consumeIdentRaw(args); 1676 return HueColorAdjuster::Type::Decreasing; 1677 case CSSValueSpecified: 1678 consumeIdentRaw(args); 1679 return HueColorAdjuster::Type::Specified; 1680 default: 1681 return WTF::nullopt; 1682 } 1683 } 1684 }; 1685 1686 template<CSSValueID Ident> struct AdjusterConsumer<Ident, double> { 1687 static Optional<double> consume(CSSParserTokenRange& args) 1688 { 1689 if (!consumeIdentRaw<Ident>(args)) 1690 return WTF::nullopt; 1691 1692 // FIXME: Is clamping to 0 for negative percentages the right thing to do? 1693 if (auto percentage = consumePercentRaw(args)) 1694 return std::max(0.0, *percentage); 1695 1696 // FIXME: Should an adjuster without a percetange be allowed? 1697 // e.g color-mix(hsl, teal saturation, red); 1698 1699 return 0; 1700 } 1701 }; 1702 1703 template<CSSValueID Ident, typename T> inline decltype(auto) consumeAdjuster(CSSParserTokenRange& args) 1704 { 1705 return AdjusterConsumer<Ident, T>::consume(args); 1706 } 1707 1708 template<std::size_t I, typename Adjuster> static bool consumeAndUpdateAdjusterAtIndex(CSSParserTokenRange& args, Adjuster& adjuster) 1709 { 1710 using AdjusterType = std::decay_t<decltype(std::get<I>(adjuster.channels).value())>; 1711 static constexpr CSSValueID Ident = std::get<I>(Adjuster::channelCSSValueIDs); 1712 1713 if (auto adjustment = consumeAdjuster<Ident, AdjusterType>(args)) { 1714 std::get<I>(adjuster.channels) = *adjustment; 1715 return true; 1716 } 1717 return false; 1718 } 1719 1720 template<typename Adjuster> static bool consumeAndUpdateAdjuster(CSSParserTokenRange& args, Adjuster& adjuster) 1721 { 1722 if (consumeAndUpdateAdjusterAtIndex<0>(args, adjuster)) 1723 return true; 1724 if (consumeAndUpdateAdjusterAtIndex<1>(args, adjuster)) 1725 return true; 1726 if (consumeAndUpdateAdjusterAtIndex<2>(args, adjuster)) 1727 return true; 1728 if (consumeAndUpdateAdjusterAtIndex<3>(args, adjuster)) 1729 return true; 1730 return false; 1731 } 1732 1733 template<typename Adjuster> static Adjuster consumeAdjusters(CSSParserTokenRange& args) 1734 { 1735 Adjuster adjuster; 1736 while (consumeAndUpdateAdjuster(args, adjuster)) { 1737 // Keep consuming until there are no more adjusters. 1738 } 1621 static ColorMixPercentages normalizedMixPercentages(const ColorMixComponent& mixComponents1, const ColorMixComponent& mixComponents2) 1622 { 1623 // The percentages are normalized as follows: 1624 1625 // 1. Let p1 be the first percentage and p2 the second one. 1626 1627 // 2. If both percentages are omitted, they each default to 50% (an equal mix of the two colors). 1628 if (!mixComponents1.percentage && !mixComponents2.percentage) 1629 return { 50.0, 50.0 }; 1739 1630 1740 return adjuster; 1741 } 1742 1743 template<typename Adjuster> static Optional<ColorMixComponent<Adjuster>> consumeMixComponents(CSSParserTokenRange& args, const CSSParserContext& context) 1744 { 1745 auto originColor = consumeOriginColor(args, context); 1746 if (!originColor.isValid()) 1747 return WTF::nullopt; 1748 1749 // FIXME: Is clamping to 0 for negative percentages the right thing to do? 1750 if (auto percentage = consumePercentRaw(args)) 1751 return { { WTFMove(originColor), Adjuster { std::max(0.0, *percentage) } } }; 1752 1753 return { { WTFMove(originColor), consumeAdjusters<Adjuster>(args) } }; 1754 } 1755 1756 static std::pair<HueColorAdjuster, HueColorAdjuster> normalizeAdjusterValues(HueColorAdjuster adjuster1, HueColorAdjuster adjuster2) 1757 { 1758 if (auto sum = adjuster1.value + adjuster2.value; sum != 100.0) { 1759 adjuster1.value *= 100.0 / sum; 1760 adjuster2.value *= 100.0 / sum; 1761 } 1762 1763 return { adjuster1, adjuster2 }; 1764 } 1765 1766 static std::pair<double, double> normalizeAdjusterValues(double adjuster1, double adjuster2) 1767 { 1768 if (auto sum = adjuster1 + adjuster2; sum != 100.0) { 1769 adjuster1 *= 100.0 / sum; 1770 adjuster2 *= 100.0 / sum; 1771 } 1772 1773 return { adjuster1, adjuster2 }; 1774 } 1775 1776 static HueColorAdjuster remainingAdjustment(HueColorAdjuster adjuster) 1777 { 1778 return { 100.0 - adjuster.value, adjuster.type }; 1779 } 1780 1781 static double remainingAdjustment(double adjuster) 1782 { 1783 return 100.0 - adjuster; 1784 } 1785 1786 template<typename AdjusterType> static auto normalizeAdjusterValues(Optional<AdjusterType> adjuster1, Optional<AdjusterType> adjuster2) -> std::pair<AdjusterType, AdjusterType> 1787 { 1788 if (adjuster1 && adjuster2) 1789 return normalizeAdjusterValues(*adjuster1, *adjuster2); 1790 if (!adjuster1 && adjuster2) 1791 return { remainingAdjustment(*adjuster2), *adjuster2 }; 1792 if (adjuster1 && !adjuster2) 1793 return { *adjuster1, remainingAdjustment(*adjuster1) }; 1794 // When neigher mix component provides an adjuster, the result is the non-modified 1795 // channel from from the first color. 1796 ASSERT(!adjuster1 && !adjuster2); 1797 return { 100.0, 0.0 }; 1798 } 1799 1800 static double mixComponent(float component1, HueColorAdjuster adjustment1, float component2, HueColorAdjuster adjustment2) 1801 { 1802 // FIXME: The spec does not indicate what to do if two different hue types are specified. We always use the first one for now, 1803 // though we probably should take into account whether it was actually specified or is the default value. That normalization 1804 // should happen in normalizeAdjusterValues(). 1805 1806 auto [fixedUpComponent1, fixedUpComponent2] = HueColorAdjuster::fixupAnglesForInterpolation(component1, component2, adjustment1.type); 1807 auto result = (fixedUpComponent1 * (adjustment1.value / 100.0)) + (fixedUpComponent2 * (adjustment2.value / 100.0)); 1808 // FIXME: Check if this full normalization is needed. 1809 return normalizeHue(result); 1810 } 1811 1812 static double mixComponent(float component1, double adjustment1, float component2, double adjustment2) 1813 { 1814 return (component1 * (adjustment1 / 100.0)) + (component2 * (adjustment2 / 100.0)); 1815 } 1816 1817 template<std::size_t I, typename Adjuster> static double mixComponentAtIndex(const ColorComponents<float>& color1, const Adjuster& adjuster1, const ColorComponents<float>& color2, const Adjuster& adjuster2) 1818 { 1819 auto [normalizedAdjuster1Value, normalizedAdjuster2Value] = normalizeAdjusterValues(std::get<I>(adjuster1.channels), std::get<I>(adjuster2.channels)); 1820 return mixComponent(color1[I], normalizedAdjuster1Value, color2[I], normalizedAdjuster2Value); 1821 } 1822 1823 template<typename ColorType> inline ColorType makeColorTypeByNormalizingComponentsAfterMix(double channel0, double channel1, double channel2, double channel3) 1824 { 1825 return { static_cast<float>(channel0), static_cast<float>(channel1), static_cast<float>(channel2), static_cast<float>(channel3) }; 1826 } 1827 1828 template<> inline HWBA<float> makeColorTypeByNormalizingComponentsAfterMix<HWBA<float>>(double hue, double whiteness, double blackness, double alpha) 1829 { 1631 ColorMixPercentages result; 1632 1633 if (!mixComponents2.percentage) { 1634 // 3. Otherwise, if p2 is omitted, it becomes 100% - p1 1635 result.p1 = *mixComponents1.percentage; 1636 result.p2 = 100.0 - result.p1; 1637 } else if (!mixComponents1.percentage) { 1638 // 4. Otherwise, if p1 is omitted, it becomes 100% - p2 1639 result.p2 = *mixComponents2.percentage; 1640 result.p1 = 100.0 - result.p2; 1641 } else { 1642 result.p1 = *mixComponents1.percentage; 1643 result.p2 = *mixComponents2.percentage; 1644 } 1645 1646 auto sum = result.p1 + result.p2; 1647 1648 // 5. If the percentages sum to zero do something, tbd. (FIXME: We just use 50 / 50 for this case for now). 1649 if (sum == 0) 1650 return { 50.0, 50.0 }; 1651 1652 if (sum != 100.0) { 1653 // 6. Otherwise, if both are provided but do not add up to 100%, they are scaled accordingly so that they 1654 // add up to 100%. This means that p1 becomes p1 / (p1 + p2) and p2 becomes p2 / (p1 + p2). 1655 result.p1 *= 100.0 / sum; 1656 result.p2 *= 100.0 / sum; 1657 } 1658 1659 return result; 1660 } 1661 1662 // Normalization is special cased for HWBA, which needs to normalize the whiteness and blackness components and convert to sRGB 1663 // and HSLA, which just needs to be converted to sRGB. All other color types can go through this non-specialized case. 1664 1665 template<typename ColorType> inline Color makeColorTypeByNormalizingComponentsAfterMix(const ColorComponents<float>& colorComponents) 1666 { 1667 return makeFromComponents<ColorType>(colorComponents); 1668 } 1669 1670 template<> inline Color makeColorTypeByNormalizingComponentsAfterMix<HWBA<float>>(const ColorComponents<float>& colorComponents) 1671 { 1672 auto [hue, whiteness, blackness, alpha] = colorComponents; 1830 1673 auto [normalizedWhitness, normalizedBlackness] = normalizeWhitenessBlackness(whiteness, blackness); 1831 return { static_cast<float>(hue), static_cast<float>(normalizedWhitness), static_cast<float>(normalizedBlackness), static_cast<float>(alpha) }; 1832 } 1833 1834 template<typename Adjuster> static typename Adjuster::ColorType mix(const ColorMixComponent<Adjuster>& mixComponents1, const ColorMixComponent<Adjuster>& mixComponents2) 1835 { 1836 using ColorType = typename Adjuster::ColorType; 1837 1838 auto color1 = asColorComponents(mixComponents1.color.template toColorTypeLossy<ColorType>()); 1839 auto color2 = asColorComponents(mixComponents2.color.template toColorTypeLossy<ColorType>()); 1840 1841 auto adjuster1 = mixComponents1.adjuster; 1842 auto adjuster2 = mixComponents2.adjuster; 1843 1844 if (!std::get<0>(adjuster1.channels) && !std::get<1>(adjuster1.channels) && !std::get<2>(adjuster1.channels) && !std::get<3>(adjuster1.channels) && !std::get<0>(adjuster2.channels) && !std::get<1>(adjuster2.channels) && !std::get<2>(adjuster2.channels) && !std::get<3>(adjuster2.channels)) { 1845 // No adjusters being specified at all is special cased to mean mix 50-50. 1846 adjuster1 = Adjuster { 50.0 }; 1847 adjuster2 = Adjuster { 50.0 }; 1848 } 1849 1850 auto channel0 = mixComponentAtIndex<0>(color1, adjuster1, color2, adjuster2); 1851 auto channel1 = mixComponentAtIndex<1>(color1, adjuster1, color2, adjuster2); 1852 auto channel2 = mixComponentAtIndex<2>(color1, adjuster1, color2, adjuster2); 1853 auto channel3 = mixComponentAtIndex<3>(color1, adjuster1, color2, adjuster2); 1854 1855 return makeColorTypeByNormalizingComponentsAfterMix<ColorType>(channel0, channel1, channel2, channel3); 1856 } 1857 1858 template<typename Adjuster> static Optional<typename Adjuster::ColorType> parseColorMixFunctionParametersUsingAdjusters(CSSParserTokenRange& args, const CSSParserContext& context) 1859 { 1860 auto mixComponents1 = consumeMixComponents<Adjuster>(args, context); 1861 if (!mixComponents1) 1862 return WTF::nullopt; 1863 1864 // FIXME: This comma is not in the grammar, but is in all the examples. 1674 1675 return convertColor<SRGBA<uint8_t>>(HWBA<float> { hue, normalizedWhitness, normalizedBlackness, alpha }); 1676 } 1677 1678 template<> inline Color makeColorTypeByNormalizingComponentsAfterMix<HSLA<float>>(const ColorComponents<float>& colorComponents) 1679 { 1680 return convertColor<SRGBA<uint8_t>>(makeFromComponents<HSLA<float>>(colorComponents)); 1681 } 1682 1683 template<size_t I, typename ComponentType> static void fixupHueComponentsPriorToMix(ColorComponents<ComponentType>& colorComponents1, ColorComponents<ComponentType>& colorComponents2) 1684 { 1685 auto normalizeAnglesUsingShorterAlgorithm = [] (auto theta1, auto theta2) -> std::pair<ComponentType, ComponentType> { 1686 // https://drafts.csswg.org/css-color-4/#hue-shorter 1687 auto difference = theta2 - theta1; 1688 if (difference > 180.0) 1689 return { theta1 + 360.0, theta2 }; 1690 if (difference < -180.0) 1691 return { theta1, theta2 + 360.0 }; 1692 return { theta1, theta2 }; 1693 }; 1694 1695 // As no other interpolation type was specified, all angles should be normalized to use the "shorter" algorithm. 1696 auto [theta1, theta2] = normalizeAnglesUsingShorterAlgorithm(colorComponents1[I], colorComponents2[I]); 1697 colorComponents1[I] = theta1; 1698 colorComponents2[I] = theta2; 1699 } 1700 1701 template<typename ColorType> static Color mixColorComponentsInColorSpace(ColorMixPercentages mixPercentages, const Color& color1, const Color& color2) 1702 { 1703 auto colorComponents1 = asColorComponents(color1.template toColorTypeLossy<ColorType>()); 1704 auto colorComponents2 = asColorComponents(color2.template toColorTypeLossy<ColorType>()); 1705 1706 // Perform fixups on any hue/angle components. 1707 constexpr auto componentInfo = ColorType::Model::componentInfo; 1708 if constexpr (componentInfo[0].type == ColorComponentType::Angle) 1709 fixupHueComponentsPriorToMix<0>(colorComponents1, colorComponents2); 1710 if constexpr (componentInfo[1].type == ColorComponentType::Angle) 1711 fixupHueComponentsPriorToMix<1>(colorComponents1, colorComponents2); 1712 if constexpr (componentInfo[2].type == ColorComponentType::Angle) 1713 fixupHueComponentsPriorToMix<2>(colorComponents1, colorComponents2); 1714 1715 auto colorComponentsMixed = mapColorComponents([&] (auto componentFromColor1, auto componentFromColor2) -> float { 1716 return (componentFromColor1 * mixPercentages.p1 / 100.0) + (componentFromColor2 * mixPercentages.p2 / 100.0); 1717 }, colorComponents1, colorComponents2); 1718 1719 return makeColorTypeByNormalizingComponentsAfterMix<ColorType>(colorComponentsMixed); 1720 } 1721 1722 static Color mixColorComponents(ColorMixColorSpace colorSpace, const ColorMixComponent& mixComponents1, const ColorMixComponent& mixComponents2) 1723 { 1724 auto mixPercentages = normalizedMixPercentages(mixComponents1, mixComponents2); 1725 1726 switch (colorSpace) { 1727 case ColorMixColorSpace::Hsl: 1728 return mixColorComponentsInColorSpace<HSLA<float>>(mixPercentages, mixComponents1.color, mixComponents2.color); 1729 case ColorMixColorSpace::Hwb: 1730 return mixColorComponentsInColorSpace<HWBA<float>>(mixPercentages, mixComponents1.color, mixComponents2.color); 1731 case ColorMixColorSpace::Lch: 1732 return mixColorComponentsInColorSpace<LCHA<float>>(mixPercentages, mixComponents1.color, mixComponents2.color); 1733 case ColorMixColorSpace::Lab: 1734 return mixColorComponentsInColorSpace<Lab<float>>(mixPercentages, mixComponents1.color, mixComponents2.color); 1735 case ColorMixColorSpace::Xyz: 1736 return mixColorComponentsInColorSpace<XYZA<float, WhitePoint::D50>>(mixPercentages, mixComponents1.color, mixComponents2.color); 1737 case ColorMixColorSpace::Srgb: 1738 return mixColorComponentsInColorSpace<SRGBA<float>>(mixPercentages, mixComponents1.color, mixComponents2.color); 1739 } 1740 } 1741 1742 static Color parseColorMixFunctionParameters(CSSParserTokenRange& range, const CSSParserContext& context) 1743 { 1744 ASSERT(range.peek().functionId() == CSSValueColorMix); 1745 1746 if (!context.colorMixEnabled) 1747 return { }; 1748 1749 auto args = consumeFunction(range); 1750 1751 if (!consumeIdentRaw<CSSValueIn>(args)) 1752 return { }; 1753 1754 auto colorSpace = consumeColorMixColorSpaceAndComma(args); 1755 if (!colorSpace) 1756 return { }; 1757 1758 auto mixComponent1 = consumeColorMixComponent(args, context); 1759 if (!mixComponent1) 1760 return { }; 1761 1865 1762 if (!consumeCommaIncludingWhitespace(args)) 1866 return WTF::nullopt; 1867 1868 auto mixComponents2 = consumeMixComponents<Adjuster>(args, context); 1869 if (!mixComponents2) 1870 return WTF::nullopt; 1871 1872 return mix(*mixComponents1, *mixComponents2); 1873 } 1874 1875 static Color parseColorMixFunctionParameters(CSSParserTokenRange& range, const CSSParserContext& context) 1876 { 1877 ASSERT(range.peek().functionId() == CSSValueColorMix); 1878 1879 if (!context.colorMixEnabled) 1880 return { }; 1881 1882 auto args = consumeFunction(range); 1883 1884 auto consumeIdentAndComma = [](CSSParserTokenRange& args) { 1885 consumeIdentRaw(args); 1886 // FIXME: This comma is not in the grammar, but is in all the examples. 1887 return consumeCommaIncludingWhitespace(args); 1888 }; 1889 1890 switch (args.peek().id()) { 1891 case CSSValueHsl: { 1892 if (!consumeIdentAndComma(args)) 1893 return { }; 1894 auto hsl = parseColorMixFunctionParametersUsingAdjusters<HSLColorAdjuster>(args, context); 1895 if (!hsl) 1896 return { }; 1897 return convertColor<SRGBA<uint8_t>>(*hsl); 1898 } 1899 case CSSValueHwb: { 1900 if (!consumeIdentAndComma(args)) 1901 return { }; 1902 auto hwb = parseColorMixFunctionParametersUsingAdjusters<HWBColorAdjuster>(args, context); 1903 if (!hwb) 1904 return { }; 1905 return convertColor<SRGBA<uint8_t>>(*hwb); 1906 } 1907 case CSSValueLch: 1908 if (!consumeIdentAndComma(args)) 1909 return { }; 1910 return parseColorMixFunctionParametersUsingAdjusters<LCHColorAdjuster>(args, context); 1911 case CSSValueLab: 1912 if (!consumeIdentAndComma(args)) 1913 return { }; 1914 return parseColorMixFunctionParametersUsingAdjusters<LabColorAdjuster>(args, context); 1915 case CSSValueXyz: 1916 if (!consumeIdentAndComma(args)) 1917 return { }; 1918 return parseColorMixFunctionParametersUsingAdjusters<XYZColorAdjuster>(args, context); 1919 case CSSValueSRGB: 1920 if (!consumeIdentAndComma(args)) 1921 return { }; 1922 return parseColorMixFunctionParametersUsingAdjusters<SRGBColorAdjuster>(args, context); 1923 default: 1924 // Default to using LCH if no color space is provided as per the spec. 1925 // FIXME: This behavior is unnecessarily confusing, we should remove the default from the spec. 1926 return parseColorMixFunctionParametersUsingAdjusters<LCHColorAdjuster>(args, context); 1927 } 1763 return { }; 1764 1765 auto mixComponent2 = consumeColorMixComponent(args, context); 1766 if (!mixComponent2) 1767 return { }; 1768 1769 if (!args.atEnd()) 1770 return { }; 1771 1772 return mixColorComponents(*colorSpace, *mixComponent1, *mixComponent2); 1928 1773 } 1929 1774 -
trunk/Source/WebCore/platform/graphics/ColorModels.h
r272870 r274947 32 32 33 33 template<typename> struct AlphaTraits; 34 template<typename> struct ColorComponent Range;34 template<typename> struct ColorComponentInfo; 35 35 template<typename> struct ExtendedRGBModel; 36 36 template<typename> struct HSLModel; … … 52 52 }; 53 53 54 template<typename T> struct ColorComponentRange { 54 enum class ColorComponentType { 55 Angle, 56 Number, 57 Percentage 58 }; 59 60 template<typename T> struct ColorComponentInfo { 55 61 T min; 56 62 T max; 63 ColorComponentType type; 57 64 }; 58 65 59 66 template<> struct ExtendedRGBModel<float> { 60 static constexpr std::array<ColorComponent Range<float>, 3> ranges{ {61 { -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity() },62 { -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity() },63 { -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity() }67 static constexpr std::array<ColorComponentInfo<float>, 3> componentInfo { { 68 { -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity(), ColorComponentType::Number }, 69 { -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity(), ColorComponentType::Number }, 70 { -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity(), ColorComponentType::Number } 64 71 } }; 65 72 static constexpr bool isInvertible = false; … … 67 74 68 75 template<> struct HSLModel<float> { 69 static constexpr std::array<ColorComponent Range<float>, 3> ranges{ {70 { 0, 360 },71 { 0, 100 },72 { 0, 100 }76 static constexpr std::array<ColorComponentInfo<float>, 3> componentInfo { { 77 { 0, 360, ColorComponentType::Angle }, 78 { 0, 100, ColorComponentType::Percentage }, 79 { 0, 100, ColorComponentType::Percentage } 73 80 } }; 74 81 static constexpr bool isInvertible = false; … … 76 83 77 84 template<> struct HWBModel<float> { 78 static constexpr std::array<ColorComponent Range<float>, 3> ranges{ {79 { 0, 360 },80 { 0, 100 },81 { 0, 100 }85 static constexpr std::array<ColorComponentInfo<float>, 3> componentInfo { { 86 { 0, 360, ColorComponentType::Angle }, 87 { 0, 100, ColorComponentType::Percentage }, 88 { 0, 100, ColorComponentType::Percentage } 82 89 } }; 83 90 static constexpr bool isInvertible = false; … … 85 92 86 93 template<> struct LabModel<float> { 87 static constexpr std::array<ColorComponent Range<float>, 3> ranges{ {88 { 0, std::numeric_limits<float>::infinity() },89 { -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity() },90 { -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity() }94 static constexpr std::array<ColorComponentInfo<float>, 3> componentInfo { { 95 { 0, std::numeric_limits<float>::infinity(), ColorComponentType::Number }, 96 { -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity(), ColorComponentType::Number }, 97 { -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity(), ColorComponentType::Number } 91 98 } }; 92 99 static constexpr bool isInvertible = false; … … 94 101 95 102 template<> struct LCHModel<float> { 96 static constexpr std::array<ColorComponent Range<float>, 3> ranges{ {97 { 0, std::numeric_limits<float>::infinity() },98 { 0, std::numeric_limits<float>::infinity() },99 { 0, 360 }103 static constexpr std::array<ColorComponentInfo<float>, 3> componentInfo { { 104 { 0, std::numeric_limits<float>::infinity(), ColorComponentType::Number }, 105 { 0, std::numeric_limits<float>::infinity(), ColorComponentType::Number }, 106 { 0, 360, ColorComponentType::Angle } 100 107 } }; 101 108 static constexpr bool isInvertible = false; … … 103 110 104 111 template<> struct RGBModel<float> { 105 static constexpr std::array<ColorComponent Range<float>, 3> ranges{ {106 { 0, 1 },107 { 0, 1 },108 { 0, 1 }112 static constexpr std::array<ColorComponentInfo<float>, 3> componentInfo { { 113 { 0, 1, ColorComponentType::Number }, 114 { 0, 1, ColorComponentType::Number }, 115 { 0, 1, ColorComponentType::Number } 109 116 } }; 110 117 static constexpr bool isInvertible = true; … … 112 119 113 120 template<> struct RGBModel<uint8_t> { 114 static constexpr std::array<ColorComponent Range<uint8_t>, 3> ranges{ {115 { 0, 255 },116 { 0, 255 },117 { 0, 255 }121 static constexpr std::array<ColorComponentInfo<uint8_t>, 3> componentInfo { { 122 { 0, 255, ColorComponentType::Number }, 123 { 0, 255, ColorComponentType::Number }, 124 { 0, 255, ColorComponentType::Number } 118 125 } }; 119 126 static constexpr bool isInvertible = true; … … 121 128 122 129 template<> struct XYZModel<float> { 123 static constexpr std::array<ColorComponent Range<float>, 3> ranges{ {124 { -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity() },125 { -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity() },126 { -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity() }130 static constexpr std::array<ColorComponentInfo<float>, 3> componentInfo { { 131 { -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity(), ColorComponentType::Number }, 132 { -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity(), ColorComponentType::Number }, 133 { -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity(), ColorComponentType::Number } 127 134 } }; 128 135 static constexpr bool isInvertible = false; -
trunk/Source/WebCore/platform/graphics/ColorTypes.h
r272837 r274947 56 56 static_assert(std::is_integral_v<T>); 57 57 58 constexpr auto range = ColorType::Model::ranges[Index];59 return std::clamp<T>(c, range.min, range.max);58 constexpr auto componentInfo = ColorType::Model::componentInfo[Index]; 59 return std::clamp<T>(c, componentInfo.min, componentInfo.max); 60 60 } 61 61 62 62 template<typename ColorType, unsigned Index> constexpr float clampedComponent(float c) 63 63 { 64 constexpr auto range = ColorType::Model::ranges[Index];65 66 if constexpr ( range.min == -std::numeric_limits<float>::infinity() && range.max == std::numeric_limits<float>::infinity())64 constexpr auto componentInfo = ColorType::Model::componentInfo[Index]; 65 66 if constexpr (componentInfo.min == -std::numeric_limits<float>::infinity() && componentInfo.max == std::numeric_limits<float>::infinity()) 67 67 return c; 68 68 69 if constexpr ( range.min == -std::numeric_limits<float>::infinity())70 return std::min(c, range.max);71 72 if constexpr ( range.max == std::numeric_limits<float>::infinity())73 return std::max(c, range.min);74 75 return std::clamp(c, range.min, range.max);69 if constexpr (componentInfo.min == -std::numeric_limits<float>::infinity()) 70 return std::min(c, componentInfo.max); 71 72 if constexpr (componentInfo.max == std::numeric_limits<float>::infinity()) 73 return std::max(c, componentInfo.min); 74 75 return std::clamp(c, componentInfo.min, componentInfo.max); 76 76 } 77 77 … … 128 128 auto components = asColorComponents(color); 129 129 for (unsigned i = 0; i < 3; ++i) { 130 ASSERT_WITH_MESSAGE(components[i] >= T::Model:: ranges[i].min, "Component at index %d is %f and is less than the allowed minimum %f", i, components[i], T::Model::ranges[i].min);131 ASSERT_WITH_MESSAGE(components[i] <= T::Model:: ranges[i].max, "Component at index %d is %f and is greater than the allowed maximum %f", i, components[i], T::Model::ranges[i].max);130 ASSERT_WITH_MESSAGE(components[i] >= T::Model::componentInfo[i].min, "Component at index %d is %f and is less than the allowed minimum %f", i, components[i], T::Model::componentInfo[i].min); 131 ASSERT_WITH_MESSAGE(components[i] <= T::Model::componentInfo[i].max, "Component at index %d is %f and is greater than the allowed maximum %f", i, components[i], T::Model::componentInfo[i].max); 132 132 } 133 133 ASSERT_WITH_MESSAGE(color.alpha >= AlphaTraits<typename T::ComponentType>::transparent, "Alpha is %f and is less than the allowed minimum (transparent) %f", color.alpha, AlphaTraits<typename T::ComponentType>::transparent); -
trunk/Source/WebCore/platform/graphics/ColorUtilities.h
r273683 r274947 126 126 127 127 for (unsigned i = 0; i < 3; ++i) 128 copy[i] = ColorType::Model:: ranges[i].max - components[i];128 copy[i] = ColorType::Model::componentInfo[i].max - components[i]; 129 129 copy[3] = convertByteAlphaTo<typename ColorType::ComponentType>(overrideAlpha); 130 130 … … 140 140 141 141 for (unsigned i = 0; i < 3; ++i) 142 copy[i] = ColorType::Model:: ranges[i].max - components[i];142 copy[i] = ColorType::Model::componentInfo[i].max - components[i]; 143 143 copy[3] = convertFloatAlphaTo<typename ColorType::ComponentType>(overrideAlpha); 144 144 … … 165 165 { 166 166 auto [c1, c2, c3, alpha] = color; 167 constexpr auto ranges = ColorType::Model::ranges;168 return c1 == ranges[0].min && c2 == ranges[1].min && c3 == ranges[2].min && alpha == AlphaTraits<typename ColorType::ComponentType>::opaque;167 constexpr auto componentInfo = ColorType::Model::componentInfo; 168 return c1 == componentInfo[0].min && c2 == componentInfo[1].min && c3 == componentInfo[2].min && alpha == AlphaTraits<typename ColorType::ComponentType>::opaque; 169 169 } 170 170 … … 188 188 { 189 189 auto [c1, c2, c3, alpha] = color; 190 constexpr auto ranges = ColorType::Model::ranges;191 return c1 == ranges[0].max && c2 == ranges[1].max && c3 == ranges[2].max && alpha == AlphaTraits<typename ColorType::ComponentType>::opaque;190 constexpr auto componentInfo = ColorType::Model::componentInfo; 191 return c1 == componentInfo[0].max && c2 == componentInfo[1].max && c3 == componentInfo[2].max && alpha == AlphaTraits<typename ColorType::ComponentType>::opaque; 192 192 } 193 193
Note: See TracChangeset
for help on using the changeset viewer.