Title: [288427] trunk
Revision
288427
Author
wei...@apple.com
Date
2022-01-23 16:57:12 -0800 (Sun, 23 Jan 2022)

Log Message

Support interpolating colors with missing/none components via color-mix()
https://bugs.webkit.org/show_bug.cgi?id=235496

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

Update color-mix() tests to include test cases that use 'none' components.

* web-platform-tests/css/css-color/parsing/color-mix-computed-expected.txt:
* web-platform-tests/css/css-color/parsing/color-mix-computed.html:
* web-platform-tests/css/css-color/parsing/color-mix-valid-expected.txt:
* web-platform-tests/css/css-color/parsing/color-mix-valid.html:

Source/WebCore:

Adds support for interpolating colors that have a missing/none component. Currently,
the only way for a color to have a missing/none component is for it to be specified
explicitly by the user (e.g. hsl(none 20% 40%)), but the interpolation implementation
is agnostic to how the color was created so will work once there is automatic creation
of missing/none components on conversion for powerless components.

This change only enables the new interpolation behavior for color-mix(), by replacing
a call of colorType.resolved() with colorType.unresolved(), support for other interpolation
use cases will follow.

* css/parser/CSSPropertyParserHelpers.cpp:
(WebCore::CSSPropertyParserHelpers::mixColorComponentsUsingColorInterpolationMethod):
Replace resolved() with unrersolved() to allow NaN values through to interpolation.

* platform/graphics/ColorInterpolation.cpp:
(WebCore::fixupHueComponentsPriorToInterpolation):
(WebCore::interpolateColors):
Move non-templated version of interpolateColors to the implementation file as it generates
a lot of code and there is little reason to believe it would be useful to inline it.

* platform/graphics/ColorInterpolation.h:
(WebCore::interpolateComponent):
(WebCore::interpolateComponentAccountingForNaN):
(WebCore::interpolateHue):
(WebCore::interpolateAlphaPremulitplied):
(WebCore::interpolateComponentUsingPremultipliedAlpha):
(WebCore::interpolateAlphaUnpremulitplied):
(WebCore::interpolateComponentUsingUnpremultipliedAlpha):
(WebCore::interpolateColorComponents):
(WebCore::preInterpolationNormalizationForComponent): Deleted.
(WebCore::preInterpolationNormalization): Deleted.
(WebCore::postInterpolationNormalizationForComponent): Deleted.
(WebCore::postInterpolationNormalization): Deleted.
(WebCore::interpolateColors): Deleted.
Replace existing interpolation implementation which separated each component into pre/interpolate/post
steps, with one that does all three steps at once and now also supports missing components. Removing
the steps made the overall algorithm is easier to understand a couples premulitplication and unpremultiplication
much closer together.

* platform/graphics/ColorTypes.h:
(WebCore::constexprIsNaN):
Update comment to include missing word.

Modified Paths

Diff

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (288426 => 288427)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2022-01-24 00:55:31 UTC (rev 288426)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2022-01-24 00:57:12 UTC (rev 288427)
@@ -1,3 +1,17 @@
+2022-01-23  Sam Weinig  <wei...@apple.com>
+
+        Support interpolating colors with missing/none components via color-mix()
+        https://bugs.webkit.org/show_bug.cgi?id=235496
+
+        Reviewed by Darin Adler.
+
+        Update color-mix() tests to include test cases that use 'none' components.
+
+        * web-platform-tests/css/css-color/parsing/color-mix-computed-expected.txt:
+        * web-platform-tests/css/css-color/parsing/color-mix-computed.html:
+        * web-platform-tests/css/css-color/parsing/color-mix-valid-expected.txt:
+        * web-platform-tests/css/css-color/parsing/color-mix-valid.html:
+
 2022-01-23  Ziran Sun  <z...@igalia.com>
 
         [forms] Prevent contenteditable anchors from being stuck

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/color-mix-computed-expected.txt (288426 => 288427)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/color-mix-computed-expected.txt	2022-01-24 00:55:31 UTC (rev 288426)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/color-mix-computed-expected.txt	2022-01-24 00:57:12 UTC (rev 288427)
@@ -53,6 +53,15 @@
 PASS Property color value 'color-mix(in hsl specified hue, hsl(330deg 50% 50%), hsl(50deg 50% 50%))'
 PASS Property color value 'color-mix(in hsl specified hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%))'
 PASS Property color value 'color-mix(in hsl specified hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%))'
+PASS Property color value 'color-mix(in hsl, hsl(none none none), hsl(none none none))'
+PASS Property color value 'color-mix(in hsl, hsl(none none none), hsl(30deg 40% 80%))'
+PASS Property color value 'color-mix(in hsl, hsl(120deg 20% 40%), hsl(none none none))'
+PASS Property color value 'color-mix(in hsl, hsl(120deg 20% none), hsl(30deg 40% 60%))'
+PASS Property color value 'color-mix(in hsl, hsl(120deg 20% 40%), hsl(30deg 20% none))'
+PASS Property color value 'color-mix(in hsl, hsl(none 20% 40%), hsl(30deg none 80%))'
+PASS Property color value 'color-mix(in hsl, hsl(120deg 40% 40% / none), hsl(0deg 40% 40%))'
+PASS Property color value 'color-mix(in hsl, hsl(120deg 40% 40% / none), hsl(0deg 40% 40% / 0.5))'
+PASS Property color value 'color-mix(in hsl, hsl(120deg 40% 40% / none), hsl(0deg 40% 40% / none))'
 PASS Property color value 'color-mix(in hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%))'
 PASS Property color value 'color-mix(in hwb, hwb(120deg 10% 20%) 25%, hwb(30deg 30% 40%))'
 PASS Property color value 'color-mix(in hwb, 25% hwb(120deg 10% 20%), hwb(30deg 30% 40%))'
@@ -107,6 +116,15 @@
 PASS Property color value 'color-mix(in hwb specified hue, hwb(330deg 30% 40%), hwb(50deg 30% 40%))'
 PASS Property color value 'color-mix(in hwb specified hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%))'
 PASS Property color value 'color-mix(in hwb specified hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%))'
+PASS Property color value 'color-mix(in hwb, hwb(none none none), hwb(none none none))'
+PASS Property color value 'color-mix(in hwb, hwb(none none none), hwb(30deg 30% 40%))'
+PASS Property color value 'color-mix(in hwb, hwb(120deg 10% 20%), hwb(none none none))'
+PASS Property color value 'color-mix(in hwb, hwb(120deg 10% none), hwb(30deg 30% 40%))'
+PASS Property color value 'color-mix(in hwb, hwb(120deg 10% 20%), hwb(30deg 30% none))'
+PASS Property color value 'color-mix(in hwb, hwb(none 10% 20%), hwb(30deg none 40%))'
+PASS Property color value 'color-mix(in hwb, hwb(120deg 10% 20% / none), hwb(30deg 30% 40%))'
+PASS Property color value 'color-mix(in hwb, hwb(120deg 10% 20% / none), hwb(30deg 30% 40% / 0.5))'
+PASS Property color value 'color-mix(in hwb, hwb(120deg 10% 20% / none), hwb(30deg 30% 40% / none))'
 PASS Property color value 'color-mix(in lch, lch(10% 20 30deg), lch(50% 60 70deg))'
 PASS Property color value 'color-mix(in lch, lch(10% 20 30deg) 25%, lch(50% 60 70deg))'
 PASS Property color value 'color-mix(in lch, 25% lch(10% 20 30deg), lch(50% 60 70deg))'
@@ -161,6 +179,15 @@
 PASS Property color value 'color-mix(in lch specified hue, lch(100% 0 330deg), lch(100% 0 50deg))'
 PASS Property color value 'color-mix(in lch specified hue, lch(100% 0 20deg), lch(100% 0 320deg))'
 PASS Property color value 'color-mix(in lch specified hue, lch(100% 0 320deg), lch(100% 0 20deg))'
+PASS Property color value 'color-mix(in lch, lch(none none none), lch(none none none))'
+PASS Property color value 'color-mix(in lch, lch(none none none), lch(50% 60 70deg))'
+PASS Property color value 'color-mix(in lch, lch(10% 20 30deg), lch(none none none))'
+PASS Property color value 'color-mix(in lch, lch(10% 20 none), lch(50% 60 70deg))'
+PASS Property color value 'color-mix(in lch, lch(10% 20 30deg), lch(50% 60 none))'
+PASS Property color value 'color-mix(in lch, lch(none 20 30deg), lch(50% none 70deg))'
+PASS Property color value 'color-mix(in lch, lch(10% 20 30deg / none), lch(50% 60 70deg))'
+PASS Property color value 'color-mix(in lch, lch(10% 20 30deg / none), lch(50% 60 70deg / 0.5))'
+PASS Property color value 'color-mix(in lch, lch(10% 20 30deg / none), lch(50% 60 70deg / none))'
 PASS Property color value 'color-mix(in oklch, oklch(10% 20 30deg), oklch(50% 60 70deg))'
 PASS Property color value 'color-mix(in oklch, oklch(10% 20 30deg) 25%, oklch(50% 60 70deg))'
 PASS Property color value 'color-mix(in oklch, 25% oklch(10% 20 30deg), oklch(50% 60 70deg))'
@@ -215,6 +242,15 @@
 PASS Property color value 'color-mix(in oklch specified hue, oklch(100% 0 330deg), oklch(100% 0 50deg))'
 PASS Property color value 'color-mix(in oklch specified hue, oklch(100% 0 20deg), oklch(100% 0 320deg))'
 PASS Property color value 'color-mix(in oklch specified hue, oklch(100% 0 320deg), oklch(100% 0 20deg))'
+PASS Property color value 'color-mix(in oklch, oklch(none none none), oklch(none none none))'
+PASS Property color value 'color-mix(in oklch, oklch(none none none), oklch(50% 60 70deg))'
+PASS Property color value 'color-mix(in oklch, oklch(10% 20 30deg), oklch(none none none))'
+PASS Property color value 'color-mix(in oklch, oklch(10% 20 none), oklch(50% 60 70deg))'
+PASS Property color value 'color-mix(in oklch, oklch(10% 20 30deg), oklch(50% 60 none))'
+PASS Property color value 'color-mix(in oklch, oklch(none 20 30deg), oklch(50% none 70deg))'
+PASS Property color value 'color-mix(in oklch, oklch(10% 20 30deg / none), oklch(50% 60 70deg))'
+PASS Property color value 'color-mix(in oklch, oklch(10% 20 30deg / none), oklch(50% 60 70deg / 0.5))'
+PASS Property color value 'color-mix(in oklch, oklch(10% 20 30deg / none), oklch(50% 60 70deg / none))'
 PASS Property color value 'color-mix(in lab, lab(10% 20 30), lab(50% 60 70))'
 PASS Property color value 'color-mix(in lab, lab(10% 20 30) 25%, lab(50% 60 70))'
 PASS Property color value 'color-mix(in lab, 25% lab(10% 20 30), lab(50% 60 70))'
@@ -233,6 +269,15 @@
 PASS Property color value 'color-mix(in lab, lab(10% 20 30 / .4) 30%, lab(50% 60 70 / .8) 90%)'
 PASS Property color value 'color-mix(in lab, lab(10% 20 30 / .4) 12.5%, lab(50% 60 70 / .8) 37.5%)'
 PASS Property color value 'color-mix(in lab, lab(10% 20 30 / .4) 0%, lab(50% 60 70 / .8))'
+PASS Property color value 'color-mix(in lab, lab(none none none), lab(none none none))'
+PASS Property color value 'color-mix(in lab, lab(none none none), lab(50% 60 70))'
+PASS Property color value 'color-mix(in lab, lab(10% 20 30), lab(none none none))'
+PASS Property color value 'color-mix(in lab, lab(10% 20 none), lab(50% 60 70))'
+PASS Property color value 'color-mix(in lab, lab(10% 20 30), lab(50% 60 none))'
+PASS Property color value 'color-mix(in lab, lab(none 20 30), lab(50% none 70))'
+PASS Property color value 'color-mix(in lab, lab(10% 20 30 / none), lab(50% 60 70))'
+PASS Property color value 'color-mix(in lab, lab(10% 20 30 / none), lab(50% 60 70 / 0.5))'
+PASS Property color value 'color-mix(in lab, lab(10% 20 30 / none), lab(50% 60 70 / none))'
 PASS Property color value 'color-mix(in oklab, oklab(10% 20 30), oklab(50% 60 70))'
 PASS Property color value 'color-mix(in oklab, oklab(10% 20 30) 25%, oklab(50% 60 70))'
 PASS Property color value 'color-mix(in oklab, 25% oklab(10% 20 30), oklab(50% 60 70))'
@@ -251,6 +296,15 @@
 PASS Property color value 'color-mix(in oklab, oklab(10% 20 30 / .4) 30%, oklab(50% 60 70 / .8) 90%)'
 PASS Property color value 'color-mix(in oklab, oklab(10% 20 30 / .4) 12.5%, oklab(50% 60 70 / .8) 37.5%)'
 PASS Property color value 'color-mix(in oklab, oklab(10% 20 30 / .4) 0%, oklab(50% 60 70 / .8))'
+PASS Property color value 'color-mix(in oklab, oklab(none none none), oklab(none none none))'
+PASS Property color value 'color-mix(in oklab, oklab(none none none), oklab(50% 60 70))'
+PASS Property color value 'color-mix(in oklab, oklab(10% 20 30), oklab(none none none))'
+PASS Property color value 'color-mix(in oklab, oklab(10% 20 none), oklab(50% 60 70))'
+PASS Property color value 'color-mix(in oklab, oklab(10% 20 30), oklab(50% 60 none))'
+PASS Property color value 'color-mix(in oklab, oklab(none 20 30), oklab(50% none 70))'
+PASS Property color value 'color-mix(in oklab, oklab(10% 20 30 / none), oklab(50% 60 70))'
+PASS Property color value 'color-mix(in oklab, oklab(10% 20 30 / none), oklab(50% 60 70 / 0.5))'
+PASS Property color value 'color-mix(in oklab, oklab(10% 20 30 / none), oklab(50% 60 70 / none))'
 PASS Property color value 'color-mix(in srgb, color(srgb .1 .2 .3), color(srgb .5 .6 .7))'
 PASS Property color value 'color-mix(in srgb, color(srgb .1 .2 .3) 25%, color(srgb .5 .6 .7))'
 PASS Property color value 'color-mix(in srgb, 25% color(srgb .1 .2 .3), color(srgb .5 .6 .7))'
@@ -272,6 +326,15 @@
 PASS Property color value 'color-mix(in srgb, color(srgb 2 3 4 / 5), color(srgb 4 6 8 / 10))'
 PASS Property color value 'color-mix(in srgb, color(srgb -2 -3 -4), color(srgb -4 -6 -8))'
 PASS Property color value 'color-mix(in srgb, color(srgb -2 -3 -4 / -5), color(srgb -4 -6 -8 / -10))'
+PASS Property color value 'color-mix(in srgb, color(srgb none none none), color(srgb none none none))'
+PASS Property color value 'color-mix(in srgb, color(srgb none none none), color(srgb .5 .6 .7))'
+PASS Property color value 'color-mix(in srgb, color(srgb .1 .2 .3), color(srgb none none none))'
+PASS Property color value 'color-mix(in srgb, color(srgb .1 .2 none), color(srgb .5 .6 .7))'
+PASS Property color value 'color-mix(in srgb, color(srgb .1 .2 .3), color(srgb .5 .6 none))'
+PASS Property color value 'color-mix(in srgb, color(srgb none .2 .3), color(srgb .5 none .7))'
+PASS Property color value 'color-mix(in srgb, color(srgb .1 .2 .3 / none), color(srgb .5 .6 .7))'
+PASS Property color value 'color-mix(in srgb, color(srgb .1 .2 .3 / none), color(srgb .5 .6 .7 / 0.5))'
+PASS Property color value 'color-mix(in srgb, color(srgb .1 .2 .3 / none), color(srgb .5 .6 .7 / none))'
 PASS Property color value 'color-mix(in srgb-linear, color(srgb-linear .1 .2 .3), color(srgb-linear .5 .6 .7))'
 PASS Property color value 'color-mix(in srgb-linear, color(srgb-linear .1 .2 .3) 25%, color(srgb-linear .5 .6 .7))'
 PASS Property color value 'color-mix(in srgb-linear, 25% color(srgb-linear .1 .2 .3), color(srgb-linear .5 .6 .7))'
@@ -293,6 +356,15 @@
 PASS Property color value 'color-mix(in srgb-linear, color(srgb-linear 2 3 4 / 5), color(srgb-linear 4 6 8 / 10))'
 PASS Property color value 'color-mix(in srgb-linear, color(srgb-linear -2 -3 -4), color(srgb-linear -4 -6 -8))'
 PASS Property color value 'color-mix(in srgb-linear, color(srgb-linear -2 -3 -4 / -5), color(srgb-linear -4 -6 -8 / -10))'
+PASS Property color value 'color-mix(in srgb-linear, color(srgb-linear none none none), color(srgb-linear none none none))'
+PASS Property color value 'color-mix(in srgb-linear, color(srgb-linear none none none), color(srgb-linear .5 .6 .7))'
+PASS Property color value 'color-mix(in srgb-linear, color(srgb-linear .1 .2 .3), color(srgb-linear none none none))'
+PASS Property color value 'color-mix(in srgb-linear, color(srgb-linear .1 .2 none), color(srgb-linear .5 .6 .7))'
+PASS Property color value 'color-mix(in srgb-linear, color(srgb-linear .1 .2 .3), color(srgb-linear .5 .6 none))'
+PASS Property color value 'color-mix(in srgb-linear, color(srgb-linear none .2 .3), color(srgb-linear .5 none .7))'
+PASS Property color value 'color-mix(in srgb-linear, color(srgb-linear .1 .2 .3 / none), color(srgb-linear .5 .6 .7))'
+PASS Property color value 'color-mix(in srgb-linear, color(srgb-linear .1 .2 .3 / none), color(srgb-linear .5 .6 .7 / 0.5))'
+PASS Property color value 'color-mix(in srgb-linear, color(srgb-linear .1 .2 .3 / none), color(srgb-linear .5 .6 .7 / none))'
 PASS Property color value 'color-mix(in xyz, color(xyz .1 .2 .3), color(xyz .5 .6 .7))'
 PASS Property color value 'color-mix(in xyz, color(xyz .1 .2 .3) 25%, color(xyz .5 .6 .7))'
 PASS Property color value 'color-mix(in xyz, 25% color(xyz .1 .2 .3), color(xyz .5 .6 .7))'
@@ -314,6 +386,15 @@
 PASS Property color value 'color-mix(in xyz, color(xyz 2 3 4 / 5), color(xyz 4 6 8 / 10))'
 PASS Property color value 'color-mix(in xyz, color(xyz -2 -3 -4), color(xyz -4 -6 -8))'
 PASS Property color value 'color-mix(in xyz, color(xyz -2 -3 -4 / -5), color(xyz -4 -6 -8 / -10))'
+PASS Property color value 'color-mix(in xyz, color(xyz none none none), color(xyz none none none))'
+PASS Property color value 'color-mix(in xyz, color(xyz none none none), color(xyz .5 .6 .7))'
+PASS Property color value 'color-mix(in xyz, color(xyz .1 .2 .3), color(xyz none none none))'
+PASS Property color value 'color-mix(in xyz, color(xyz .1 .2 none), color(xyz .5 .6 .7))'
+PASS Property color value 'color-mix(in xyz, color(xyz .1 .2 .3), color(xyz .5 .6 none))'
+PASS Property color value 'color-mix(in xyz, color(xyz none .2 .3), color(xyz .5 none .7))'
+PASS Property color value 'color-mix(in xyz, color(xyz .1 .2 .3 / none), color(xyz .5 .6 .7))'
+PASS Property color value 'color-mix(in xyz, color(xyz .1 .2 .3 / none), color(xyz .5 .6 .7 / 0.5))'
+PASS Property color value 'color-mix(in xyz, color(xyz .1 .2 .3 / none), color(xyz .5 .6 .7 / none))'
 PASS Property color value 'color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3), color(xyz-d50 .5 .6 .7))'
 PASS Property color value 'color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3) 25%, color(xyz-d50 .5 .6 .7))'
 PASS Property color value 'color-mix(in xyz-d50, 25% color(xyz-d50 .1 .2 .3), color(xyz-d50 .5 .6 .7))'
@@ -335,6 +416,15 @@
 PASS Property color value 'color-mix(in xyz-d50, color(xyz-d50 2 3 4 / 5), color(xyz-d50 4 6 8 / 10))'
 PASS Property color value 'color-mix(in xyz-d50, color(xyz-d50 -2 -3 -4), color(xyz-d50 -4 -6 -8))'
 PASS Property color value 'color-mix(in xyz-d50, color(xyz-d50 -2 -3 -4 / -5), color(xyz-d50 -4 -6 -8 / -10))'
+PASS Property color value 'color-mix(in xyz-d50, color(xyz-d50 none none none), color(xyz-d50 none none none))'
+PASS Property color value 'color-mix(in xyz-d50, color(xyz-d50 none none none), color(xyz-d50 .5 .6 .7))'
+PASS Property color value 'color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3), color(xyz-d50 none none none))'
+PASS Property color value 'color-mix(in xyz-d50, color(xyz-d50 .1 .2 none), color(xyz-d50 .5 .6 .7))'
+PASS Property color value 'color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3), color(xyz-d50 .5 .6 none))'
+PASS Property color value 'color-mix(in xyz-d50, color(xyz-d50 none .2 .3), color(xyz-d50 .5 none .7))'
+PASS Property color value 'color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3 / none), color(xyz-d50 .5 .6 .7))'
+PASS Property color value 'color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3 / none), color(xyz-d50 .5 .6 .7 / 0.5))'
+PASS Property color value 'color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3 / none), color(xyz-d50 .5 .6 .7 / none))'
 PASS Property color value 'color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3), color(xyz-d65 .5 .6 .7))'
 PASS Property color value 'color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3) 25%, color(xyz-d65 .5 .6 .7))'
 PASS Property color value 'color-mix(in xyz-d65, 25% color(xyz-d65 .1 .2 .3), color(xyz-d65 .5 .6 .7))'
@@ -356,4 +446,13 @@
 PASS Property color value 'color-mix(in xyz-d65, color(xyz-d65 2 3 4 / 5), color(xyz-d65 4 6 8 / 10))'
 PASS Property color value 'color-mix(in xyz-d65, color(xyz-d65 -2 -3 -4), color(xyz-d65 -4 -6 -8))'
 PASS Property color value 'color-mix(in xyz-d65, color(xyz-d65 -2 -3 -4 / -5), color(xyz-d65 -4 -6 -8 / -10))'
+PASS Property color value 'color-mix(in xyz-d65, color(xyz-d65 none none none), color(xyz-d65 none none none))'
+PASS Property color value 'color-mix(in xyz-d65, color(xyz-d65 none none none), color(xyz-d65 .5 .6 .7))'
+PASS Property color value 'color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3), color(xyz-d65 none none none))'
+PASS Property color value 'color-mix(in xyz-d65, color(xyz-d65 .1 .2 none), color(xyz-d65 .5 .6 .7))'
+PASS Property color value 'color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3), color(xyz-d65 .5 .6 none))'
+PASS Property color value 'color-mix(in xyz-d65, color(xyz-d65 none .2 .3), color(xyz-d65 .5 none .7))'
+PASS Property color value 'color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3 / none), color(xyz-d65 .5 .6 .7))'
+PASS Property color value 'color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3 / none), color(xyz-d65 .5 .6 .7 / 0.5))'
+PASS Property color value 'color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3 / none), color(xyz-d65 .5 .6 .7 / none))'
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/color-mix-computed.html (288426 => 288427)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/color-mix-computed.html	2022-01-24 00:55:31 UTC (rev 288426)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/color-mix-computed.html	2022-01-24 00:57:12 UTC (rev 288427)
@@ -86,6 +86,18 @@
     test_computed_value(`color`, `color-mix(in hsl specified hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%))`, canonicalize(`hsl(170deg 50% 50%)`));
     test_computed_value(`color`, `color-mix(in hsl specified hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%))`, canonicalize(`hsl(170deg 50% 50%)`));
 
+    test_computed_value(`color`, `color-mix(in hsl, hsl(none none none), hsl(none none none))`, canonicalize(`hsl(none none none)`));
+    test_computed_value(`color`, `color-mix(in hsl, hsl(none none none), hsl(30deg 40% 80%))`, canonicalize(`hsl(30deg 40% 80%)`));
+    test_computed_value(`color`, `color-mix(in hsl, hsl(120deg 20% 40%), hsl(none none none))`, canonicalize(`hsl(120deg 20% 40%)`));
+    test_computed_value(`color`, `color-mix(in hsl, hsl(120deg 20% none), hsl(30deg 40% 60%))`, canonicalize(`hsl(75deg 30% 60%)`));
+    test_computed_value(`color`, `color-mix(in hsl, hsl(120deg 20% 40%), hsl(30deg 20% none))`, canonicalize(`hsl(75deg 20% 40%)`));
+    test_computed_value(`color`, `color-mix(in hsl, hsl(none 20% 40%), hsl(30deg none 80%))`, canonicalize(`hsl(30deg 20% 60%)`));
+
+    test_computed_value(`color`, `color-mix(in hsl, hsl(120deg 40% 40% / none), hsl(0deg 40% 40%))`, canonicalize(`hsl(60deg 40% 40%)`));
+    test_computed_value(`color`, `color-mix(in hsl, hsl(120deg 40% 40% / none), hsl(0deg 40% 40% / 0.5))`, canonicalize(`hsl(60deg 40% 40% / 0.5)`));
+    test_computed_value(`color`, `color-mix(in hsl, hsl(120deg 40% 40% / none), hsl(0deg 40% 40% / none))`, canonicalize(`hsl(60deg 40% 40% / none)`));
+
+
     test_computed_value(`color`, `color-mix(in hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%))`, `rgb(147, 179, 52)`);
     test_computed_value(`color`, `color-mix(in hwb, hwb(120deg 10% 20%) 25%, hwb(30deg 30% 40%))`, `rgb(166, 153, 64)`);
     test_computed_value(`color`, `color-mix(in hwb, 25% hwb(120deg 10% 20%), hwb(30deg 30% 40%))`, `rgb(166, 153, 64)`);
@@ -148,6 +160,16 @@
     test_computed_value(`color`, `color-mix(in hwb specified hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%))`, canonicalize(`hwb(170deg 30% 40%)`));
     test_computed_value(`color`, `color-mix(in hwb specified hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%))`, canonicalize(`hwb(170deg 30% 40%)`));
 
+    test_computed_value(`color`, `color-mix(in hwb, hwb(none none none), hwb(none none none))`, canonicalize(`hwb(none none none)`));
+    test_computed_value(`color`, `color-mix(in hwb, hwb(none none none), hwb(30deg 30% 40%))`, canonicalize(`hwb(30deg 30% 40%)`));
+    test_computed_value(`color`, `color-mix(in hwb, hwb(120deg 10% 20%), hwb(none none none))`, canonicalize(`hwb(120deg 10% 20%)`));
+    test_computed_value(`color`, `color-mix(in hwb, hwb(120deg 10% none), hwb(30deg 30% 40%))`, canonicalize(`hwb(75deg 20% 40%)`));
+    test_computed_value(`color`, `color-mix(in hwb, hwb(120deg 10% 20%), hwb(30deg 30% none))`, canonicalize(`hwb(75deg 20% 20%)`));
+    test_computed_value(`color`, `color-mix(in hwb, hwb(none 10% 20%), hwb(30deg none 40%))`, canonicalize(`hwb(30deg 10% 30%)`));
+    test_computed_value(`color`, `color-mix(in hwb, hwb(120deg 10% 20% / none), hwb(30deg 30% 40%))`, canonicalize(`hwb(75deg 20% 30%)`));
+    test_computed_value(`color`, `color-mix(in hwb, hwb(120deg 10% 20% / none), hwb(30deg 30% 40% / 0.5))`, canonicalize(`hwb(75deg 20% 30% / 0.5)`));
+    test_computed_value(`color`, `color-mix(in hwb, hwb(120deg 10% 20% / none), hwb(30deg 30% 40% / none))`, canonicalize(`hwb(75deg 20% 30% / none)`));
+
     for (const colorSpace of [ "lch", "oklch" ]) {
         test_computed_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30deg), ${colorSpace}(50% 60 70deg))`, `${colorSpace}(30% 40 50)`);
         test_computed_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30deg) 25%, ${colorSpace}(50% 60 70deg))`, `${colorSpace}(40% 50 60)`);
@@ -210,6 +232,16 @@
         test_computed_value(`color`, `color-mix(in ${colorSpace} specified hue, ${colorSpace}(100% 0 330deg), ${colorSpace}(100% 0 50deg))`, `${colorSpace}(100% 0 190)`);
         test_computed_value(`color`, `color-mix(in ${colorSpace} specified hue, ${colorSpace}(100% 0 20deg), ${colorSpace}(100% 0 320deg))`, `${colorSpace}(100% 0 170)`);
         test_computed_value(`color`, `color-mix(in ${colorSpace} specified hue, ${colorSpace}(100% 0 320deg), ${colorSpace}(100% 0 20deg))`, `${colorSpace}(100% 0 170)`);
+
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(none none none), ${colorSpace}(none none none))`, `${colorSpace}(none none none)`);
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(none none none), ${colorSpace}(50% 60 70deg))`, `${colorSpace}(50% 60 70)`);
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30deg), ${colorSpace}(none none none))`, `${colorSpace}(10% 20 30)`);
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 none), ${colorSpace}(50% 60 70deg))`, `${colorSpace}(30% 40 70)`);
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30deg), ${colorSpace}(50% 60 none))`, `${colorSpace}(30% 40 30)`);
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(none 20 30deg), ${colorSpace}(50% none 70deg))`, `${colorSpace}(50% 20 50)`);
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30deg / none), ${colorSpace}(50% 60 70deg))`, `${colorSpace}(30% 40 50)`);
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30deg / none), ${colorSpace}(50% 60 70deg / 0.5))`, `${colorSpace}(30% 40 50 / 0.5)`);
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30deg / none), ${colorSpace}(50% 60 70deg / none))`, `${colorSpace}(30% 40 50 / none)`);
     }
 
     for (const colorSpace of [ "lab", "oklab" ]) {
@@ -232,6 +264,16 @@
         test_computed_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30 / .4) 30%, ${colorSpace}(50% 60 70 / .8) 90%)`, `${colorSpace}(44.285713% 54.285717 64.28571 / 0.7)`); // Scale down > 100% sum.
         test_computed_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30 / .4) 12.5%, ${colorSpace}(50% 60 70 / .8) 37.5%)`, `${colorSpace}(44.285713% 54.285717 64.28571 / 0.35)`); // Scale up < 100% sum, causes alpha multiplication.
         test_computed_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30 / .4) 0%, ${colorSpace}(50% 60 70 / .8))`, `${colorSpace}(50% 60 70 / 0.8)`);
+
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(none none none), ${colorSpace}(none none none))`, `${colorSpace}(none none none)`);
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(none none none), ${colorSpace}(50% 60 70))`, `${colorSpace}(50% 60 70)`);
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30), ${colorSpace}(none none none))`, `${colorSpace}(10% 20 30)`);
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 none), ${colorSpace}(50% 60 70))`, `${colorSpace}(30% 40 70)`);
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30), ${colorSpace}(50% 60 none))`, `${colorSpace}(30% 40 30)`);
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(none 20 30), ${colorSpace}(50% none 70))`, `${colorSpace}(50% 20 50)`);
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30 / none), ${colorSpace}(50% 60 70))`, `${colorSpace}(30% 40 50)`);
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30 / none), ${colorSpace}(50% 60 70 / 0.5))`, `${colorSpace}(30% 40 50 / 0.5)`);
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30 / none), ${colorSpace}(50% 60 70 / none))`, `${colorSpace}(30% 40 50 / none)`);
     }
 
     for (const colorSpace of [ "srgb", "srgb-linear", "xyz", "xyz-d50", "xyz-d65" ]) {
@@ -260,6 +302,16 @@
         test_computed_value(`color`, `color-mix(in ${colorSpace}, color(${colorSpace} 2 3 4 / 5), color(${colorSpace} 4 6 8 / 10))`, `color(${resultColorSpace} 3 4.5 6)`);
         test_computed_value(`color`, `color-mix(in ${colorSpace}, color(${colorSpace} -2 -3 -4), color(${colorSpace} -4 -6 -8))`, `color(${resultColorSpace} -3 -4.5 -6)`);
         test_computed_value(`color`, `color-mix(in ${colorSpace}, color(${colorSpace} -2 -3 -4 / -5), color(${colorSpace} -4 -6 -8 / -10))`, `color(${resultColorSpace} 0 0 0 / 0)`);
+
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, color(${colorSpace} none none none), color(${colorSpace} none none none))`, `color(${resultColorSpace} none none none)`);
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, color(${colorSpace} none none none), color(${colorSpace} .5 .6 .7))`, `color(${resultColorSpace} 0.5 0.6 0.7)`);
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, color(${colorSpace} .1 .2 .3), color(${colorSpace} none none none))`, `color(${resultColorSpace} 0.1 0.2 0.3)`);
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, color(${colorSpace} .1 .2 none), color(${colorSpace} .5 .6 .7))`, `color(${resultColorSpace} 0.3 0.4 0.7)`);
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, color(${colorSpace} .1 .2 .3), color(${colorSpace} .5 .6 none))`, `color(${resultColorSpace} 0.3 0.4 0.3)`);
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, color(${colorSpace} none .2 .3), color(${colorSpace} .5 none .7))`, `color(${resultColorSpace} 0.5 0.2 0.5)`);
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, color(${colorSpace} .1 .2 .3 / none), color(${colorSpace} .5 .6 .7))`, `color(${resultColorSpace} 0.3 0.4 0.5)`);
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, color(${colorSpace} .1 .2 .3 / none), color(${colorSpace} .5 .6 .7 / 0.5))`, `color(${resultColorSpace} 0.3 0.4 0.5 / 0.5)`);
+        test_computed_value(`color`, `color-mix(in ${colorSpace}, color(${colorSpace} .1 .2 .3 / none), color(${colorSpace} .5 .6 .7 / none))`, `color(${resultColorSpace} 0.3 0.4 0.5 / none)`);
     }
 </script>
 </body>

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/color-mix-valid-expected.txt (288426 => 288427)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/color-mix-valid-expected.txt	2022-01-24 00:55:31 UTC (rev 288426)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/color-mix-valid-expected.txt	2022-01-24 00:57:12 UTC (rev 288427)
@@ -53,6 +53,15 @@
 PASS e.style['color'] = "color-mix(in hsl specified hue, hsl(330deg 50% 50%), hsl(50deg 50% 50%))" should set the property value
 PASS e.style['color'] = "color-mix(in hsl specified hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%))" should set the property value
 PASS e.style['color'] = "color-mix(in hsl specified hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%))" should set the property value
+PASS e.style['color'] = "color-mix(in hsl, hsl(none none none), hsl(none none none))" should set the property value
+PASS e.style['color'] = "color-mix(in hsl, hsl(none none none), hsl(30deg 40% 80%))" should set the property value
+PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 20% 40%), hsl(none none none))" should set the property value
+PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 20% none), hsl(30deg 40% 60%))" should set the property value
+PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 20% 40%), hsl(30deg 20% none))" should set the property value
+PASS e.style['color'] = "color-mix(in hsl, hsl(none 20% 40%), hsl(30deg none 80%))" should set the property value
+PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 40% 40% / none), hsl(0deg 40% 40%))" should set the property value
+PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 40% 40% / none), hsl(0deg 40% 40% / 0.5))" should set the property value
+PASS e.style['color'] = "color-mix(in hsl, hsl(120deg 40% 40% / none), hsl(0deg 40% 40% / none))" should set the property value
 PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%))" should set the property value
 PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20%) 25%, hwb(30deg 30% 40%))" should set the property value
 PASS e.style['color'] = "color-mix(in hwb, 25% hwb(120deg 10% 20%), hwb(30deg 30% 40%))" should set the property value
@@ -107,6 +116,15 @@
 PASS e.style['color'] = "color-mix(in hwb specified hue, hwb(330deg 30% 40%), hwb(50deg 30% 40%))" should set the property value
 PASS e.style['color'] = "color-mix(in hwb specified hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%))" should set the property value
 PASS e.style['color'] = "color-mix(in hwb specified hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%))" should set the property value
+PASS e.style['color'] = "color-mix(in hwb, hwb(none none none), hwb(none none none))" should set the property value
+PASS e.style['color'] = "color-mix(in hwb, hwb(none none none), hwb(30deg 30% 40%))" should set the property value
+PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20%), hwb(none none none))" should set the property value
+PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% none), hwb(30deg 30% 40%))" should set the property value
+PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20%), hwb(30deg 30% none))" should set the property value
+PASS e.style['color'] = "color-mix(in hwb, hwb(none 10% 20%), hwb(30deg none 40%))" should set the property value
+PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20% / none), hwb(30deg 30% 40%))" should set the property value
+PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20% / none), hwb(30deg 30% 40% / 0.5))" should set the property value
+PASS e.style['color'] = "color-mix(in hwb, hwb(120deg 10% 20% / none), hwb(30deg 30% 40% / none))" should set the property value
 PASS e.style['color'] = "color-mix(in lch, lch(10% 20 30deg), lch(50% 60 70deg))" should set the property value
 PASS e.style['color'] = "color-mix(in lch, lch(10% 20 30deg) 25%, lch(50% 60 70deg))" should set the property value
 PASS e.style['color'] = "color-mix(in lch, 25% lch(10% 20 30deg), lch(50% 60 70deg))" should set the property value
@@ -161,6 +179,15 @@
 PASS e.style['color'] = "color-mix(in lch specified hue, lch(100% 0 330deg), lch(100% 0 50deg))" should set the property value
 PASS e.style['color'] = "color-mix(in lch specified hue, lch(100% 0 20deg), lch(100% 0 320deg))" should set the property value
 PASS e.style['color'] = "color-mix(in lch specified hue, lch(100% 0 320deg), lch(100% 0 20deg))" should set the property value
+PASS e.style['color'] = "color-mix(in lch, lch(none none none), lch(none none none))" should set the property value
+PASS e.style['color'] = "color-mix(in lch, lch(none none none), lch(50% 60 70deg))" should set the property value
+PASS e.style['color'] = "color-mix(in lch, lch(10% 20 30deg), lch(none none none))" should set the property value
+PASS e.style['color'] = "color-mix(in lch, lch(10% 20 none), lch(50% 60 70deg))" should set the property value
+PASS e.style['color'] = "color-mix(in lch, lch(10% 20 30deg), lch(50% 60 none))" should set the property value
+PASS e.style['color'] = "color-mix(in lch, lch(none 20 30deg), lch(50% none 70deg))" should set the property value
+PASS e.style['color'] = "color-mix(in lch, lch(10% 20 30deg / none), lch(50% 60 70deg))" should set the property value
+PASS e.style['color'] = "color-mix(in lch, lch(10% 20 30deg / none), lch(50% 60 70deg / 0.5))" should set the property value
+PASS e.style['color'] = "color-mix(in lch, lch(10% 20 30deg / none), lch(50% 60 70deg / none))" should set the property value
 PASS e.style['color'] = "color-mix(in oklch, oklch(10% 20 30deg), oklch(50% 60 70deg))" should set the property value
 PASS e.style['color'] = "color-mix(in oklch, oklch(10% 20 30deg) 25%, oklch(50% 60 70deg))" should set the property value
 PASS e.style['color'] = "color-mix(in oklch, 25% oklch(10% 20 30deg), oklch(50% 60 70deg))" should set the property value
@@ -215,6 +242,15 @@
 PASS e.style['color'] = "color-mix(in oklch specified hue, oklch(100% 0 330deg), oklch(100% 0 50deg))" should set the property value
 PASS e.style['color'] = "color-mix(in oklch specified hue, oklch(100% 0 20deg), oklch(100% 0 320deg))" should set the property value
 PASS e.style['color'] = "color-mix(in oklch specified hue, oklch(100% 0 320deg), oklch(100% 0 20deg))" should set the property value
+PASS e.style['color'] = "color-mix(in oklch, oklch(none none none), oklch(none none none))" should set the property value
+PASS e.style['color'] = "color-mix(in oklch, oklch(none none none), oklch(50% 60 70deg))" should set the property value
+PASS e.style['color'] = "color-mix(in oklch, oklch(10% 20 30deg), oklch(none none none))" should set the property value
+PASS e.style['color'] = "color-mix(in oklch, oklch(10% 20 none), oklch(50% 60 70deg))" should set the property value
+PASS e.style['color'] = "color-mix(in oklch, oklch(10% 20 30deg), oklch(50% 60 none))" should set the property value
+PASS e.style['color'] = "color-mix(in oklch, oklch(none 20 30deg), oklch(50% none 70deg))" should set the property value
+PASS e.style['color'] = "color-mix(in oklch, oklch(10% 20 30deg / none), oklch(50% 60 70deg))" should set the property value
+PASS e.style['color'] = "color-mix(in oklch, oklch(10% 20 30deg / none), oklch(50% 60 70deg / 0.5))" should set the property value
+PASS e.style['color'] = "color-mix(in oklch, oklch(10% 20 30deg / none), oklch(50% 60 70deg / none))" should set the property value
 PASS e.style['color'] = "color-mix(in lab, lab(10% 20 30), lab(50% 60 70))" should set the property value
 PASS e.style['color'] = "color-mix(in lab, lab(10% 20 30) 25%, lab(50% 60 70))" should set the property value
 PASS e.style['color'] = "color-mix(in lab, 25% lab(10% 20 30), lab(50% 60 70))" should set the property value
@@ -233,6 +269,15 @@
 PASS e.style['color'] = "color-mix(in lab, lab(10% 20 30 / .4) 30%, lab(50% 60 70 / .8) 90%)" should set the property value
 PASS e.style['color'] = "color-mix(in lab, lab(10% 20 30 / .4) 12.5%, lab(50% 60 70 / .8) 37.5%)" should set the property value
 PASS e.style['color'] = "color-mix(in lab, lab(10% 20 30 / .4) 0%, lab(50% 60 70 / .8))" should set the property value
+PASS e.style['color'] = "color-mix(in lab, lab(none none none), lab(none none none))" should set the property value
+PASS e.style['color'] = "color-mix(in lab, lab(none none none), lab(50% 60 70))" should set the property value
+PASS e.style['color'] = "color-mix(in lab, lab(10% 20 30), lab(none none none))" should set the property value
+PASS e.style['color'] = "color-mix(in lab, lab(10% 20 none), lab(50% 60 70))" should set the property value
+PASS e.style['color'] = "color-mix(in lab, lab(10% 20 30), lab(50% 60 none))" should set the property value
+PASS e.style['color'] = "color-mix(in lab, lab(none 20 30), lab(50% none 70))" should set the property value
+PASS e.style['color'] = "color-mix(in lab, lab(10% 20 30 / none), lab(50% 60 70))" should set the property value
+PASS e.style['color'] = "color-mix(in lab, lab(10% 20 30 / none), lab(50% 60 70 / 0.5))" should set the property value
+PASS e.style['color'] = "color-mix(in lab, lab(10% 20 30 / none), lab(50% 60 70 / none))" should set the property value
 PASS e.style['color'] = "color-mix(in oklab, oklab(10% 20 30), oklab(50% 60 70))" should set the property value
 PASS e.style['color'] = "color-mix(in oklab, oklab(10% 20 30) 25%, oklab(50% 60 70))" should set the property value
 PASS e.style['color'] = "color-mix(in oklab, 25% oklab(10% 20 30), oklab(50% 60 70))" should set the property value
@@ -251,6 +296,15 @@
 PASS e.style['color'] = "color-mix(in oklab, oklab(10% 20 30 / .4) 30%, oklab(50% 60 70 / .8) 90%)" should set the property value
 PASS e.style['color'] = "color-mix(in oklab, oklab(10% 20 30 / .4) 12.5%, oklab(50% 60 70 / .8) 37.5%)" should set the property value
 PASS e.style['color'] = "color-mix(in oklab, oklab(10% 20 30 / .4) 0%, oklab(50% 60 70 / .8))" should set the property value
+PASS e.style['color'] = "color-mix(in oklab, oklab(none none none), oklab(none none none))" should set the property value
+PASS e.style['color'] = "color-mix(in oklab, oklab(none none none), oklab(50% 60 70))" should set the property value
+PASS e.style['color'] = "color-mix(in oklab, oklab(10% 20 30), oklab(none none none))" should set the property value
+PASS e.style['color'] = "color-mix(in oklab, oklab(10% 20 none), oklab(50% 60 70))" should set the property value
+PASS e.style['color'] = "color-mix(in oklab, oklab(10% 20 30), oklab(50% 60 none))" should set the property value
+PASS e.style['color'] = "color-mix(in oklab, oklab(none 20 30), oklab(50% none 70))" should set the property value
+PASS e.style['color'] = "color-mix(in oklab, oklab(10% 20 30 / none), oklab(50% 60 70))" should set the property value
+PASS e.style['color'] = "color-mix(in oklab, oklab(10% 20 30 / none), oklab(50% 60 70 / 0.5))" should set the property value
+PASS e.style['color'] = "color-mix(in oklab, oklab(10% 20 30 / none), oklab(50% 60 70 / none))" should set the property value
 PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3), color(srgb .5 .6 .7))" should set the property value
 PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3) 25%, color(srgb .5 .6 .7))" should set the property value
 PASS e.style['color'] = "color-mix(in srgb, 25% color(srgb .1 .2 .3), color(srgb .5 .6 .7))" should set the property value
@@ -272,6 +326,15 @@
 PASS e.style['color'] = "color-mix(in srgb, color(srgb 2 3 4 / 5), color(srgb 4 6 8 / 10))" should set the property value
 PASS e.style['color'] = "color-mix(in srgb, color(srgb -2 -3 -4), color(srgb -4 -6 -8))" should set the property value
 PASS e.style['color'] = "color-mix(in srgb, color(srgb -2 -3 -4 / -5), color(srgb -4 -6 -8 / -10))" should set the property value
+PASS e.style['color'] = "color-mix(in srgb, color(srgb none none none), color(srgb none none none))" should set the property value
+PASS e.style['color'] = "color-mix(in srgb, color(srgb none none none), color(srgb .5 .6 .7))" should set the property value
+PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3), color(srgb none none none))" should set the property value
+PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 none), color(srgb .5 .6 .7))" should set the property value
+PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3), color(srgb .5 .6 none))" should set the property value
+PASS e.style['color'] = "color-mix(in srgb, color(srgb none .2 .3), color(srgb .5 none .7))" should set the property value
+PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3 / none), color(srgb .5 .6 .7))" should set the property value
+PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3 / none), color(srgb .5 .6 .7 / 0.5))" should set the property value
+PASS e.style['color'] = "color-mix(in srgb, color(srgb .1 .2 .3 / none), color(srgb .5 .6 .7 / none))" should set the property value
 PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3), color(srgb-linear .5 .6 .7))" should set the property value
 PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3) 25%, color(srgb-linear .5 .6 .7))" should set the property value
 PASS e.style['color'] = "color-mix(in srgb-linear, 25% color(srgb-linear .1 .2 .3), color(srgb-linear .5 .6 .7))" should set the property value
@@ -293,6 +356,15 @@
 PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear 2 3 4 / 5), color(srgb-linear 4 6 8 / 10))" should set the property value
 PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear -2 -3 -4), color(srgb-linear -4 -6 -8))" should set the property value
 PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear -2 -3 -4 / -5), color(srgb-linear -4 -6 -8 / -10))" should set the property value
+PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear none none none), color(srgb-linear none none none))" should set the property value
+PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear none none none), color(srgb-linear .5 .6 .7))" should set the property value
+PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3), color(srgb-linear none none none))" should set the property value
+PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 none), color(srgb-linear .5 .6 .7))" should set the property value
+PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3), color(srgb-linear .5 .6 none))" should set the property value
+PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear none .2 .3), color(srgb-linear .5 none .7))" should set the property value
+PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3 / none), color(srgb-linear .5 .6 .7))" should set the property value
+PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3 / none), color(srgb-linear .5 .6 .7 / 0.5))" should set the property value
+PASS e.style['color'] = "color-mix(in srgb-linear, color(srgb-linear .1 .2 .3 / none), color(srgb-linear .5 .6 .7 / none))" should set the property value
 PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3), color(xyz .5 .6 .7))" should set the property value
 PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3) 25%, color(xyz .5 .6 .7))" should set the property value
 PASS e.style['color'] = "color-mix(in xyz, 25% color(xyz .1 .2 .3), color(xyz .5 .6 .7))" should set the property value
@@ -314,6 +386,15 @@
 PASS e.style['color'] = "color-mix(in xyz, color(xyz 2 3 4 / 5), color(xyz 4 6 8 / 10))" should set the property value
 PASS e.style['color'] = "color-mix(in xyz, color(xyz -2 -3 -4), color(xyz -4 -6 -8))" should set the property value
 PASS e.style['color'] = "color-mix(in xyz, color(xyz -2 -3 -4 / -5), color(xyz -4 -6 -8 / -10))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz, color(xyz none none none), color(xyz none none none))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz, color(xyz none none none), color(xyz .5 .6 .7))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3), color(xyz none none none))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 none), color(xyz .5 .6 .7))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3), color(xyz .5 .6 none))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz, color(xyz none .2 .3), color(xyz .5 none .7))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3 / none), color(xyz .5 .6 .7))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3 / none), color(xyz .5 .6 .7 / 0.5))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz, color(xyz .1 .2 .3 / none), color(xyz .5 .6 .7 / none))" should set the property value
 PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3), color(xyz-d50 .5 .6 .7))" should set the property value
 PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3) 25%, color(xyz-d50 .5 .6 .7))" should set the property value
 PASS e.style['color'] = "color-mix(in xyz-d50, 25% color(xyz-d50 .1 .2 .3), color(xyz-d50 .5 .6 .7))" should set the property value
@@ -335,6 +416,15 @@
 PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 2 3 4 / 5), color(xyz-d50 4 6 8 / 10))" should set the property value
 PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 -2 -3 -4), color(xyz-d50 -4 -6 -8))" should set the property value
 PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 -2 -3 -4 / -5), color(xyz-d50 -4 -6 -8 / -10))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 none none none), color(xyz-d50 none none none))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 none none none), color(xyz-d50 .5 .6 .7))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3), color(xyz-d50 none none none))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 none), color(xyz-d50 .5 .6 .7))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3), color(xyz-d50 .5 .6 none))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 none .2 .3), color(xyz-d50 .5 none .7))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3 / none), color(xyz-d50 .5 .6 .7))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3 / none), color(xyz-d50 .5 .6 .7 / 0.5))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz-d50, color(xyz-d50 .1 .2 .3 / none), color(xyz-d50 .5 .6 .7 / none))" should set the property value
 PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3), color(xyz-d65 .5 .6 .7))" should set the property value
 PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3) 25%, color(xyz-d65 .5 .6 .7))" should set the property value
 PASS e.style['color'] = "color-mix(in xyz-d65, 25% color(xyz-d65 .1 .2 .3), color(xyz-d65 .5 .6 .7))" should set the property value
@@ -356,4 +446,13 @@
 PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 2 3 4 / 5), color(xyz-d65 4 6 8 / 10))" should set the property value
 PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 -2 -3 -4), color(xyz-d65 -4 -6 -8))" should set the property value
 PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 -2 -3 -4 / -5), color(xyz-d65 -4 -6 -8 / -10))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 none none none), color(xyz-d65 none none none))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 none none none), color(xyz-d65 .5 .6 .7))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3), color(xyz-d65 none none none))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 none), color(xyz-d65 .5 .6 .7))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3), color(xyz-d65 .5 .6 none))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 none .2 .3), color(xyz-d65 .5 none .7))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3 / none), color(xyz-d65 .5 .6 .7))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3 / none), color(xyz-d65 .5 .6 .7 / 0.5))" should set the property value
+PASS e.style['color'] = "color-mix(in xyz-d65, color(xyz-d65 .1 .2 .3 / none), color(xyz-d65 .5 .6 .7 / none))" should set the property value
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/color-mix-valid.html (288426 => 288427)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/color-mix-valid.html	2022-01-24 00:55:31 UTC (rev 288426)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/parsing/color-mix-valid.html	2022-01-24 00:57:12 UTC (rev 288427)
@@ -86,6 +86,18 @@
     test_valid_value(`color`, `color-mix(in hsl specified hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%))`, canonicalize(`hsl(170deg 50% 50%)`));
     test_valid_value(`color`, `color-mix(in hsl specified hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%))`, canonicalize(`hsl(170deg 50% 50%)`));
 
+    test_valid_value(`color`, `color-mix(in hsl, hsl(none none none), hsl(none none none))`, canonicalize(`hsl(none none none)`));
+    test_valid_value(`color`, `color-mix(in hsl, hsl(none none none), hsl(30deg 40% 80%))`, canonicalize(`hsl(30deg 40% 80%)`));
+    test_valid_value(`color`, `color-mix(in hsl, hsl(120deg 20% 40%), hsl(none none none))`, canonicalize(`hsl(120deg 20% 40%)`));
+    test_valid_value(`color`, `color-mix(in hsl, hsl(120deg 20% none), hsl(30deg 40% 60%))`, canonicalize(`hsl(75deg 30% 60%)`));
+    test_valid_value(`color`, `color-mix(in hsl, hsl(120deg 20% 40%), hsl(30deg 20% none))`, canonicalize(`hsl(75deg 20% 40%)`));
+    test_valid_value(`color`, `color-mix(in hsl, hsl(none 20% 40%), hsl(30deg none 80%))`, canonicalize(`hsl(30deg 20% 60%)`));
+
+    test_valid_value(`color`, `color-mix(in hsl, hsl(120deg 40% 40% / none), hsl(0deg 40% 40%))`, canonicalize(`hsl(60deg 40% 40%)`));
+    test_valid_value(`color`, `color-mix(in hsl, hsl(120deg 40% 40% / none), hsl(0deg 40% 40% / 0.5))`, canonicalize(`hsl(60deg 40% 40% / 0.5)`));
+    test_valid_value(`color`, `color-mix(in hsl, hsl(120deg 40% 40% / none), hsl(0deg 40% 40% / none))`, canonicalize(`hsl(60deg 40% 40% / none)`));
+
+
     test_valid_value(`color`, `color-mix(in hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%))`, `rgb(147, 179, 52)`);
     test_valid_value(`color`, `color-mix(in hwb, hwb(120deg 10% 20%) 25%, hwb(30deg 30% 40%))`, `rgb(166, 153, 64)`);
     test_valid_value(`color`, `color-mix(in hwb, 25% hwb(120deg 10% 20%), hwb(30deg 30% 40%))`, `rgb(166, 153, 64)`);
@@ -148,6 +160,16 @@
     test_valid_value(`color`, `color-mix(in hwb specified hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%))`, canonicalize(`hwb(170deg 30% 40%)`));
     test_valid_value(`color`, `color-mix(in hwb specified hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%))`, canonicalize(`hwb(170deg 30% 40%)`));
 
+    test_valid_value(`color`, `color-mix(in hwb, hwb(none none none), hwb(none none none))`, canonicalize(`hwb(none none none)`));
+    test_valid_value(`color`, `color-mix(in hwb, hwb(none none none), hwb(30deg 30% 40%))`, canonicalize(`hwb(30deg 30% 40%)`));
+    test_valid_value(`color`, `color-mix(in hwb, hwb(120deg 10% 20%), hwb(none none none))`, canonicalize(`hwb(120deg 10% 20%)`));
+    test_valid_value(`color`, `color-mix(in hwb, hwb(120deg 10% none), hwb(30deg 30% 40%))`, canonicalize(`hwb(75deg 20% 40%)`));
+    test_valid_value(`color`, `color-mix(in hwb, hwb(120deg 10% 20%), hwb(30deg 30% none))`, canonicalize(`hwb(75deg 20% 20%)`));
+    test_valid_value(`color`, `color-mix(in hwb, hwb(none 10% 20%), hwb(30deg none 40%))`, canonicalize(`hwb(30deg 10% 30%)`));
+    test_valid_value(`color`, `color-mix(in hwb, hwb(120deg 10% 20% / none), hwb(30deg 30% 40%))`, canonicalize(`hwb(75deg 20% 30%)`));
+    test_valid_value(`color`, `color-mix(in hwb, hwb(120deg 10% 20% / none), hwb(30deg 30% 40% / 0.5))`, canonicalize(`hwb(75deg 20% 30% / 0.5)`));
+    test_valid_value(`color`, `color-mix(in hwb, hwb(120deg 10% 20% / none), hwb(30deg 30% 40% / none))`, canonicalize(`hwb(75deg 20% 30% / none)`));
+
     for (const colorSpace of [ "lch", "oklch" ]) {
         test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30deg), ${colorSpace}(50% 60 70deg))`, `${colorSpace}(30% 40 50)`);
         test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30deg) 25%, ${colorSpace}(50% 60 70deg))`, `${colorSpace}(40% 50 60)`);
@@ -210,6 +232,16 @@
         test_valid_value(`color`, `color-mix(in ${colorSpace} specified hue, ${colorSpace}(100% 0 330deg), ${colorSpace}(100% 0 50deg))`, `${colorSpace}(100% 0 190)`);
         test_valid_value(`color`, `color-mix(in ${colorSpace} specified hue, ${colorSpace}(100% 0 20deg), ${colorSpace}(100% 0 320deg))`, `${colorSpace}(100% 0 170)`);
         test_valid_value(`color`, `color-mix(in ${colorSpace} specified hue, ${colorSpace}(100% 0 320deg), ${colorSpace}(100% 0 20deg))`, `${colorSpace}(100% 0 170)`);
+
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(none none none), ${colorSpace}(none none none))`, `${colorSpace}(none none none)`);
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(none none none), ${colorSpace}(50% 60 70deg))`, `${colorSpace}(50% 60 70)`);
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30deg), ${colorSpace}(none none none))`, `${colorSpace}(10% 20 30)`);
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 none), ${colorSpace}(50% 60 70deg))`, `${colorSpace}(30% 40 70)`);
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30deg), ${colorSpace}(50% 60 none))`, `${colorSpace}(30% 40 30)`);
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(none 20 30deg), ${colorSpace}(50% none 70deg))`, `${colorSpace}(50% 20 50)`);
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30deg / none), ${colorSpace}(50% 60 70deg))`, `${colorSpace}(30% 40 50)`);
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30deg / none), ${colorSpace}(50% 60 70deg / 0.5))`, `${colorSpace}(30% 40 50 / 0.5)`);
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30deg / none), ${colorSpace}(50% 60 70deg / none))`, `${colorSpace}(30% 40 50 / none)`);
     }
 
     for (const colorSpace of [ "lab", "oklab" ]) {
@@ -232,6 +264,16 @@
         test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30 / .4) 30%, ${colorSpace}(50% 60 70 / .8) 90%)`, `${colorSpace}(44.285713% 54.285717 64.28571 / 0.7)`); // Scale down > 100% sum.
         test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30 / .4) 12.5%, ${colorSpace}(50% 60 70 / .8) 37.5%)`, `${colorSpace}(44.285713% 54.285717 64.28571 / 0.35)`); // Scale up < 100% sum, causes alpha multiplication.
         test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30 / .4) 0%, ${colorSpace}(50% 60 70 / .8))`, `${colorSpace}(50% 60 70 / 0.8)`);
+
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(none none none), ${colorSpace}(none none none))`, `${colorSpace}(none none none)`);
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(none none none), ${colorSpace}(50% 60 70))`, `${colorSpace}(50% 60 70)`);
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30), ${colorSpace}(none none none))`, `${colorSpace}(10% 20 30)`);
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 none), ${colorSpace}(50% 60 70))`, `${colorSpace}(30% 40 70)`);
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30), ${colorSpace}(50% 60 none))`, `${colorSpace}(30% 40 30)`);
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(none 20 30), ${colorSpace}(50% none 70))`, `${colorSpace}(50% 20 50)`);
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30 / none), ${colorSpace}(50% 60 70))`, `${colorSpace}(30% 40 50)`);
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30 / none), ${colorSpace}(50% 60 70 / 0.5))`, `${colorSpace}(30% 40 50 / 0.5)`);
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, ${colorSpace}(10% 20 30 / none), ${colorSpace}(50% 60 70 / none))`, `${colorSpace}(30% 40 50 / none)`);
     }
 
     for (const colorSpace of [ "srgb", "srgb-linear", "xyz", "xyz-d50", "xyz-d65" ]) {
@@ -260,6 +302,16 @@
         test_valid_value(`color`, `color-mix(in ${colorSpace}, color(${colorSpace} 2 3 4 / 5), color(${colorSpace} 4 6 8 / 10))`, `color(${resultColorSpace} 3 4.5 6)`);
         test_valid_value(`color`, `color-mix(in ${colorSpace}, color(${colorSpace} -2 -3 -4), color(${colorSpace} -4 -6 -8))`, `color(${resultColorSpace} -3 -4.5 -6)`);
         test_valid_value(`color`, `color-mix(in ${colorSpace}, color(${colorSpace} -2 -3 -4 / -5), color(${colorSpace} -4 -6 -8 / -10))`, `color(${resultColorSpace} 0 0 0 / 0)`);
+
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, color(${colorSpace} none none none), color(${colorSpace} none none none))`, `color(${resultColorSpace} none none none)`);
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, color(${colorSpace} none none none), color(${colorSpace} .5 .6 .7))`, `color(${resultColorSpace} 0.5 0.6 0.7)`);
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, color(${colorSpace} .1 .2 .3), color(${colorSpace} none none none))`, `color(${resultColorSpace} 0.1 0.2 0.3)`);
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, color(${colorSpace} .1 .2 none), color(${colorSpace} .5 .6 .7))`, `color(${resultColorSpace} 0.3 0.4 0.7)`);
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, color(${colorSpace} .1 .2 .3), color(${colorSpace} .5 .6 none))`, `color(${resultColorSpace} 0.3 0.4 0.3)`);
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, color(${colorSpace} none .2 .3), color(${colorSpace} .5 none .7))`, `color(${resultColorSpace} 0.5 0.2 0.5)`);
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, color(${colorSpace} .1 .2 .3 / none), color(${colorSpace} .5 .6 .7))`, `color(${resultColorSpace} 0.3 0.4 0.5)`);
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, color(${colorSpace} .1 .2 .3 / none), color(${colorSpace} .5 .6 .7 / 0.5))`, `color(${resultColorSpace} 0.3 0.4 0.5 / 0.5)`);
+        test_valid_value(`color`, `color-mix(in ${colorSpace}, color(${colorSpace} .1 .2 .3 / none), color(${colorSpace} .5 .6 .7 / none))`, `color(${resultColorSpace} 0.3 0.4 0.5 / none)`);
     }
 </script>
 </body>

Modified: trunk/Source/WebCore/ChangeLog (288426 => 288427)


--- trunk/Source/WebCore/ChangeLog	2022-01-24 00:55:31 UTC (rev 288426)
+++ trunk/Source/WebCore/ChangeLog	2022-01-24 00:57:12 UTC (rev 288427)
@@ -1,3 +1,53 @@
+2022-01-23  Sam Weinig  <wei...@apple.com>
+
+        Support interpolating colors with missing/none components via color-mix()
+        https://bugs.webkit.org/show_bug.cgi?id=235496
+
+        Reviewed by Darin Adler.
+
+        Adds support for interpolating colors that have a missing/none component. Currently,
+        the only way for a color to have a missing/none component is for it to be specified
+        explicitly by the user (e.g. hsl(none 20% 40%)), but the interpolation implementation
+        is agnostic to how the color was created so will work once there is automatic creation
+        of missing/none components on conversion for powerless components.
+
+        This change only enables the new interpolation behavior for color-mix(), by replacing
+        a call of colorType.resolved() with colorType.unresolved(), support for other interpolation
+        use cases will follow. 
+
+        * css/parser/CSSPropertyParserHelpers.cpp:
+        (WebCore::CSSPropertyParserHelpers::mixColorComponentsUsingColorInterpolationMethod):
+        Replace resolved() with unrersolved() to allow NaN values through to interpolation.
+
+        * platform/graphics/ColorInterpolation.cpp:
+        (WebCore::fixupHueComponentsPriorToInterpolation):
+        (WebCore::interpolateColors):
+        Move non-templated version of interpolateColors to the implementation file as it generates
+        a lot of code and there is little reason to believe it would be useful to inline it.
+
+        * platform/graphics/ColorInterpolation.h:
+        (WebCore::interpolateComponent):
+        (WebCore::interpolateComponentAccountingForNaN):
+        (WebCore::interpolateHue):
+        (WebCore::interpolateAlphaPremulitplied):
+        (WebCore::interpolateComponentUsingPremultipliedAlpha):
+        (WebCore::interpolateAlphaUnpremulitplied):
+        (WebCore::interpolateComponentUsingUnpremultipliedAlpha):
+        (WebCore::interpolateColorComponents):
+        (WebCore::preInterpolationNormalizationForComponent): Deleted.
+        (WebCore::preInterpolationNormalization): Deleted.
+        (WebCore::postInterpolationNormalizationForComponent): Deleted.
+        (WebCore::postInterpolationNormalization): Deleted.
+        (WebCore::interpolateColors): Deleted.
+        Replace existing interpolation implementation which separated each component into pre/interpolate/post
+        steps, with one that does all three steps at once and now also supports missing components. Removing
+        the steps made the overall algorithm is easier to understand a couples premulitplication and unpremultiplication
+        much closer together.
+
+        * platform/graphics/ColorTypes.h:
+        (WebCore::constexprIsNaN):
+        Update comment to include missing word.
+
 2022-01-23  Darin Adler  <da...@apple.com>
 
         Improve FourCC to use more inlining, fix incorrect mix of WEBCORE_EXPORT on entire class with inline functions

Modified: trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp (288426 => 288427)


--- trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp	2022-01-24 00:55:31 UTC (rev 288426)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp	2022-01-24 00:57:12 UTC (rev 288427)
@@ -2837,11 +2837,11 @@
     auto convertedColor2 = color2.template toColorTypeLossy<ColorType>();
 
     // 2. Colors are then interpolated in the specified color space, as described in CSS Color 4 § 13 Interpolation. [...]
-    auto mixedColor = interpolateColorComponents<AlphaPremultiplication::Premultiplied>(interpolationMethod, convertedColor1, mixPercentages.p1 / 100.0, convertedColor2, mixPercentages.p2 / 100.0).resolved();
+    auto mixedColor = interpolateColorComponents<AlphaPremultiplication::Premultiplied>(interpolationMethod, convertedColor1, mixPercentages.p1 / 100.0, convertedColor2, mixPercentages.p2 / 100.0).unresolved();
 
     // 3. If an alpha multiplier was produced during percentage normalization, the alpha component of the interpolated result
     //    is multiplied by the alpha multiplier.
-    if (mixPercentages.alphaMultiplier)
+    if (mixPercentages.alphaMultiplier && !std::isnan(mixedColor.alpha))
         mixedColor.alpha *= (*mixPercentages.alphaMultiplier / 100.0);
 
     return makeCanonicalColor(mixedColor);

Modified: trunk/Source/WebCore/platform/graphics/ColorInterpolation.cpp (288426 => 288427)


--- trunk/Source/WebCore/platform/graphics/ColorInterpolation.cpp	2022-01-24 00:55:31 UTC (rev 288426)
+++ trunk/Source/WebCore/platform/graphics/ColorInterpolation.cpp	2022-01-24 00:57:12 UTC (rev 288427)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 Apple Inc. All rights reserved.
+ * Copyright (C) 2021-2022 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,6 +26,8 @@
 #include "config.h"
 #include "ColorInterpolation.h"
 
+#include "Color.h"
+
 namespace WebCore {
 
 std::pair<float, float> fixupHueComponentsPriorToInterpolation(HueInterpolationMethod method, float component1, float component2)
@@ -84,4 +86,20 @@
     RELEASE_ASSERT_NOT_REACHED();
 }
 
+Color interpolateColors(ColorInterpolationMethod colorInterpolationMethod, Color color1, double color1Multiplier, Color color2, double color2Multiplier)
+{
+    return WTF::switchOn(colorInterpolationMethod.colorSpace,
+        [&] (auto& colorSpace) {
+            using ColorType = typename std::remove_reference_t<decltype(colorSpace)>::ColorType;
+            switch (colorInterpolationMethod.alphaPremultiplication) {
+            case AlphaPremultiplication::Premultiplied:
+                return makeCanonicalColor(interpolateColorComponents<AlphaPremultiplication::Premultiplied>(colorSpace, color1.toColorTypeLossy<ColorType>(), color1Multiplier, color2.toColorTypeLossy<ColorType>(), color2Multiplier));
+            case AlphaPremultiplication::Unpremultiplied:
+                return makeCanonicalColor(interpolateColorComponents<AlphaPremultiplication::Unpremultiplied>(colorSpace, color1.toColorTypeLossy<ColorType>(), color1Multiplier, color2.toColorTypeLossy<ColorType>(), color2Multiplier));
+            }
+            RELEASE_ASSERT_NOT_REACHED();
+        }
+    );
 }
+
+}

Modified: trunk/Source/WebCore/platform/graphics/ColorInterpolation.h (288426 => 288427)


--- trunk/Source/WebCore/platform/graphics/ColorInterpolation.h	2022-01-24 00:55:31 UTC (rev 288426)
+++ trunk/Source/WebCore/platform/graphics/ColorInterpolation.h	2022-01-24 00:57:12 UTC (rev 288427)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 Apple Inc. All rights reserved.
+ * Copyright (C) 2021-2022 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,7 +26,6 @@
 #pragma once
 
 #include "AlphaPremultiplication.h"
-#include "Color.h"
 #include "ColorInterpolationMethod.h"
 #include "ColorNormalization.h"
 #include "ColorTypes.h"
@@ -33,102 +32,140 @@
 
 namespace WebCore {
 
-// MARK: - Pre-interpolation normalization/fixup
+class Color;
 
-std::pair<float, float> fixupHueComponentsPriorToInterpolation(HueInterpolationMethod, float, float);
+template<AlphaPremultiplication, typename InterpolationMethodColorSpace>
+typename InterpolationMethodColorSpace::ColorType interpolateColorComponents(InterpolationMethodColorSpace, typename InterpolationMethodColorSpace::ColorType color1, double color1Multiplier, typename InterpolationMethodColorSpace::ColorType color2, double color2Multiplier);
 
-template<size_t I, AlphaPremultiplication alphaPremultiplication, typename InterpolationMethodColorSpace>
-std::pair<float, float> preInterpolationNormalizationForComponent(InterpolationMethodColorSpace interpolationMethodColorSpace, ColorComponents<float, 4> colorComponents1, ColorComponents<float, 4> colorComponents2)
+Color interpolateColors(ColorInterpolationMethod, Color color1, double color1Multiplier, Color color2, double color2Multiplier);
+
+
+// MARK: - Pre-interpolation normalization/fixup.
+
+std::pair<float, float> fixupHueComponentsPriorToInterpolation(HueInterpolationMethod, float component1, float component2);
+
+// MARK: - Premultiplication-agnostic interpolation helpers.
+
+inline float interpolateComponetWithoutAccountingForNaN(float componentFromColor1, double color1Multiplier, float componentFromColor2, double color2Multiplier)
 {
-    using ColorType = typename InterpolationMethodColorSpace::ColorType;
-    constexpr auto componentInfo = ColorType::Model::componentInfo;
+    return (componentFromColor1 * color1Multiplier) + (componentFromColor2 * color2Multiplier);
+}
 
-    if constexpr (componentInfo[I].type == ColorComponentType::Angle)
-        return fixupHueComponentsPriorToInterpolation(interpolationMethodColorSpace.hueInterpolationMethod, colorComponents1[I], colorComponents2[I]);
-    else {
-        if constexpr (alphaPremultiplication == AlphaPremultiplication::Premultiplied)
-            return { colorComponents1[I] * colorComponents1[3], colorComponents2[I] * colorComponents2[3] };
-        else
-            return { colorComponents1[I], colorComponents2[I] };
-    }
+inline float interpolateComponentAccountingForNaN(float componentFromColor1, double color1Multiplier, float componentFromColor2, double color2Multiplier)
+{
+    if (std::isnan(componentFromColor1))
+        return componentFromColor2;
+    if (std::isnan(componentFromColor2))
+        return componentFromColor1;
+
+    return interpolateComponetWithoutAccountingForNaN(componentFromColor1, color1Multiplier, componentFromColor2, color2Multiplier);
 }
 
-template<AlphaPremultiplication alphaPremultiplication, typename InterpolationMethodColorSpace>
-std::pair<ColorComponents<float, 4>, ColorComponents<float, 4>> preInterpolationNormalization(InterpolationMethodColorSpace interpolationMethodColorSpace, ColorComponents<float, 4> colorComponents1, ColorComponents<float, 4> colorComponents2)
+template<typename InterpolationMethodColorSpace>
+float interpolateHue(InterpolationMethodColorSpace interpolationMethodColorSpace, float componentFromColor1, double color1Multiplier, float componentFromColor2, double color2Multiplier)
 {
-    auto [colorA0, colorB0] = preInterpolationNormalizationForComponent<0, alphaPremultiplication>(interpolationMethodColorSpace, colorComponents1, colorComponents2);
-    auto [colorA1, colorB1] = preInterpolationNormalizationForComponent<1, alphaPremultiplication>(interpolationMethodColorSpace, colorComponents1, colorComponents2);
-    auto [colorA2, colorB2] = preInterpolationNormalizationForComponent<2, alphaPremultiplication>(interpolationMethodColorSpace, colorComponents1, colorComponents2);
+    if (std::isnan(componentFromColor1))
+        return componentFromColor2;
+    if (std::isnan(componentFromColor2))
+        return componentFromColor1;
 
-    return {
-        { colorA0, colorA1, colorA2, colorComponents1[3] },
-        { colorB0, colorB1, colorB2, colorComponents2[3] }
-    };
+    auto [fixedupComponent1, fixedupComponent2] = fixupHueComponentsPriorToInterpolation(interpolationMethodColorSpace.hueInterpolationMethod, componentFromColor1, componentFromColor2);
+    return interpolateComponetWithoutAccountingForNaN(fixedupComponent1, color1Multiplier, fixedupComponent2, color2Multiplier);
 }
 
+// MARK: - Premultiplied interpolation.
 
-// MARK: - Post-interpolation normalization/fixup
+struct PremultipliedAlphaState {
+    float alphaForPremultiplicationOfColor1;
+    float alphaForPremultiplicationOfColor2;
+    float alphaForUnpremultiplication;
+    float resultAlpha;
+};
+inline PremultipliedAlphaState interpolateAlphaPremulitplied(float alphaForColor1, double color1Multiplier, float alphaForColor2, double color2Multiplier)
+{
+    // If both alpha channels are none/missing, no premultiplication is performed and the resulting color will have a none/missing alpha channel.
+    // If only one alpha channels is none/missing, the other alpha channel is used premultiplication of both colors and is the resulting color's alpha channel.
+    // If neither alpha channel is none/missing, each alpha channel is used for the premultiplication of its associated color and the interpolated result of the two alpha channels is the resulting color's alpha channel.
 
-template<size_t I, AlphaPremultiplication alphaPremultiplication, typename InterpolationMethodColorSpace>
-float postInterpolationNormalizationForComponent(InterpolationMethodColorSpace, ColorComponents<float, 4> colorComponents)
+    if (std::isnan(alphaForColor1)) {
+        if (std::isnan(alphaForColor2))
+            return { 1.0f, 1.0f, 1.0f, std::numeric_limits<float>::quiet_NaN() };
+        return { alphaForColor2, alphaForColor2, alphaForColor2, alphaForColor2 };
+    }
+    if (std::isnan(alphaForColor2))
+        return { alphaForColor1, alphaForColor1, alphaForColor1, alphaForColor1 };
+
+    auto interpolatedAlpha = interpolateComponetWithoutAccountingForNaN(alphaForColor1, color1Multiplier, alphaForColor2, color2Multiplier);
+    return { alphaForColor1, alphaForColor2, interpolatedAlpha, interpolatedAlpha };
+}
+
+template<size_t I, typename InterpolationMethodColorSpace>
+float interpolateComponentUsingPremultipliedAlpha(InterpolationMethodColorSpace interpolationMethodColorSpace, ColorComponents<float, 4> colorComponents1, double color1Multiplier, ColorComponents<float, 4> colorComponents2, double color2Multiplier, PremultipliedAlphaState interpolatedAlpha)
 {
     using ColorType = typename InterpolationMethodColorSpace::ColorType;
     constexpr auto componentInfo = ColorType::Model::componentInfo;
 
-    if constexpr (componentInfo[I].type != ColorComponentType::Angle && alphaPremultiplication == AlphaPremultiplication::Premultiplied) {
-        if (colorComponents[3] == 0.0f)
-            return 0;
-        return colorComponents[I] / colorComponents[3];
-    } else
-        return colorComponents[I];
+    if constexpr (componentInfo[I].type == ColorComponentType::Angle)
+        return interpolateHue(interpolationMethodColorSpace, colorComponents1[I], color1Multiplier, colorComponents2[I], color2Multiplier);
+    else {
+        if (std::isnan(colorComponents1[I]))
+            return colorComponents2[I];
+        if (std::isnan(colorComponents2[I]))
+            return colorComponents1[I];
+
+        auto premultipliedComponent1 = colorComponents1[I] * interpolatedAlpha.alphaForPremultiplicationOfColor1;
+        auto premultipliedComponent2 = colorComponents2[I] * interpolatedAlpha.alphaForPremultiplicationOfColor2;
+
+        auto premultipliedResult = interpolateComponetWithoutAccountingForNaN(premultipliedComponent1, color1Multiplier, premultipliedComponent2, color2Multiplier);
+
+        if (interpolatedAlpha.alphaForUnpremultiplication == 0.0f)
+            return premultipliedResult;
+        return premultipliedResult / interpolatedAlpha.alphaForUnpremultiplication;
+    }
 }
 
-template<AlphaPremultiplication alphaPremultiplication, typename InterpolationMethodColorSpace>
-ColorComponents<float, 4> postInterpolationNormalization(InterpolationMethodColorSpace interpolationMethodColorSpace, ColorComponents<float, 4> colorComponents)
+// MARK: - Unpremultiplied interpolation.
+
+inline float interpolateAlphaUnpremulitplied(float alphaForColor1, double color1Multiplier, float alphaForColor2, double color2Multiplier)
 {
-    return {
-        postInterpolationNormalizationForComponent<0, alphaPremultiplication>(interpolationMethodColorSpace, colorComponents),
-        postInterpolationNormalizationForComponent<1, alphaPremultiplication>(interpolationMethodColorSpace, colorComponents),
-        postInterpolationNormalizationForComponent<2, alphaPremultiplication>(interpolationMethodColorSpace, colorComponents),
-        colorComponents[3]
-    };
- }
+    return interpolateComponentAccountingForNaN(alphaForColor1, color1Multiplier, alphaForColor2, color2Multiplier);
+}
 
+template<size_t I, typename InterpolationMethodColorSpace>
+float interpolateComponentUsingUnpremultipliedAlpha(InterpolationMethodColorSpace interpolationMethodColorSpace, ColorComponents<float, 4> colorComponents1, double color1Multiplier, ColorComponents<float, 4> colorComponents2, double color2Multiplier)
+{
+    using ColorType = typename InterpolationMethodColorSpace::ColorType;
+    constexpr auto componentInfo = ColorType::Model::componentInfo;
 
-// MARK: - Interpolation
+    if constexpr (componentInfo[I].type == ColorComponentType::Angle)
+        return interpolateHue(interpolationMethodColorSpace, colorComponents1[I], color1Multiplier, colorComponents2[I], color2Multiplier);
+    else
+        return interpolateComponentAccountingForNaN(colorComponents1[I], color1Multiplier, colorComponents2[I], color2Multiplier);
+}
 
+// MARK: - Interpolation.
+
 template<AlphaPremultiplication alphaPremultiplication, typename InterpolationMethodColorSpace>
 typename InterpolationMethodColorSpace::ColorType interpolateColorComponents(InterpolationMethodColorSpace interpolationMethodColorSpace, typename InterpolationMethodColorSpace::ColorType color1, double color1Multiplier, typename InterpolationMethodColorSpace::ColorType color2, double color2Multiplier)
 {
-    // 1. Apply pre-interpolation transforms (hue fixup for polar color spaces, alpha premultiplication if required).
-    auto [normalizedColorComponents1, normalizedColorComponents2] = preInterpolationNormalization<alphaPremultiplication>(interpolationMethodColorSpace, asColorComponents(color1.resolved()), asColorComponents(color2.resolved()));
+    auto colorComponents1 = asColorComponents(color1.unresolved());
+    auto colorComponents2 = asColorComponents(color2.unresolved());
 
-    // 2. Interpolate using the normalized components.
-    auto interpolatedColorComponents = mapColorComponents([&] (auto componentFromColor1, auto componentFromColor2) -> float {
-        return (componentFromColor1 * color1Multiplier) + (componentFromColor2 * color2Multiplier);
-    }, normalizedColorComponents1, normalizedColorComponents2);
+    if constexpr (alphaPremultiplication == AlphaPremultiplication::Premultiplied) {
+        auto interpolatedAlpha = interpolateAlphaPremulitplied(colorComponents1[3], color1Multiplier, colorComponents2[3], color2Multiplier);
+        auto interpolatedComponent1 = interpolateComponentUsingPremultipliedAlpha<0>(interpolationMethodColorSpace, colorComponents1, color1Multiplier, colorComponents2, color2Multiplier, interpolatedAlpha);
+        auto interpolatedComponent2 = interpolateComponentUsingPremultipliedAlpha<1>(interpolationMethodColorSpace, colorComponents1, color1Multiplier, colorComponents2, color2Multiplier, interpolatedAlpha);
+        auto interpolatedComponent3 = interpolateComponentUsingPremultipliedAlpha<2>(interpolationMethodColorSpace, colorComponents1, color1Multiplier, colorComponents2, color2Multiplier, interpolatedAlpha);
 
-    // 3. Apply post-interpolation trasforms (alpha un-premultiplication if required).
-    auto normalizedInterpolatedColorComponents = postInterpolationNormalization<alphaPremultiplication>(interpolationMethodColorSpace, interpolatedColorComponents);
+        return makeColorTypeByNormalizingComponents<typename InterpolationMethodColorSpace::ColorType>({ interpolatedComponent1, interpolatedComponent2, interpolatedComponent3, interpolatedAlpha.resultAlpha });
+    } else {
+        auto interpolatedAlpha = interpolateAlphaUnpremulitplied(colorComponents1[3], color1Multiplier, colorComponents2[3], color2Multiplier);
+        auto interpolatedComponent1 = interpolateComponentUsingUnpremultipliedAlpha<0>(interpolationMethodColorSpace, colorComponents1, color1Multiplier, colorComponents2, color2Multiplier);
+        auto interpolatedComponent2 = interpolateComponentUsingUnpremultipliedAlpha<1>(interpolationMethodColorSpace, colorComponents1, color1Multiplier, colorComponents2, color2Multiplier);
+        auto interpolatedComponent3 = interpolateComponentUsingUnpremultipliedAlpha<2>(interpolationMethodColorSpace, colorComponents1, color1Multiplier, colorComponents2, color2Multiplier);
 
-    // 4. Create color type from components, normalizing any components that may be out of range.
-    return makeColorTypeByNormalizingComponents<typename InterpolationMethodColorSpace::ColorType>(normalizedInterpolatedColorComponents);
+        return makeColorTypeByNormalizingComponents<typename InterpolationMethodColorSpace::ColorType>({ interpolatedComponent1, interpolatedComponent2, interpolatedComponent3, interpolatedAlpha });
+    }
 }
 
-inline Color interpolateColors(ColorInterpolationMethod colorInterpolationMethod, Color color1, double color1Multiplier, Color color2, double color2Multiplier)
-{
-    return WTF::switchOn(colorInterpolationMethod.colorSpace,
-        [&] (auto& colorSpace) {
-            using ColorType = typename std::remove_reference_t<decltype(colorSpace)>::ColorType;
-            switch (colorInterpolationMethod.alphaPremultiplication) {
-            case AlphaPremultiplication::Premultiplied:
-                return makeCanonicalColor(interpolateColorComponents<AlphaPremultiplication::Premultiplied>(colorSpace, color1.toColorTypeLossy<ColorType>(), color1Multiplier, color2.toColorTypeLossy<ColorType>(), color2Multiplier));
-            case AlphaPremultiplication::Unpremultiplied:
-                return makeCanonicalColor(interpolateColorComponents<AlphaPremultiplication::Unpremultiplied>(colorSpace, color1.toColorTypeLossy<ColorType>(), color1Multiplier, color2.toColorTypeLossy<ColorType>(), color2Multiplier));
-            }
-            RELEASE_ASSERT_NOT_REACHED();
-        }
-    );
 }
-
-}

Modified: trunk/Source/WebCore/platform/graphics/ColorTypes.h (288426 => 288427)


--- trunk/Source/WebCore/platform/graphics/ColorTypes.h	2022-01-24 00:55:31 UTC (rev 288426)
+++ trunk/Source/WebCore/platform/graphics/ColorTypes.h	2022-01-24 00:57:12 UTC (rev 288427)
@@ -135,7 +135,7 @@
 template<typename ComponentType>
 constexpr bool constexprIsNaN(ComponentType value)
 {
-    // FIXME: Replace std::isnan() once std::isnan() is constexpr.
+    // FIXME: Replace with std::isnan() once std::isnan() is constexpr.
     return value != value;
 }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to