diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index aa4d871b7b..020278212d 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -186,6 +186,21 @@ OKLabToSRGBColor(float aL, float aA, float aB, float aAlpha) { // Per CSS Color, the lightness component for Oklab/Oklch is clamped. float lightness = mozilla::clamped(aL, 0.0f, 1.0f); + uint8_t alpha = + nsStyleUtil::FloatToColorComponent(mozilla::clamped(aAlpha, 0.0f, 1.0f)); + + // Treat values extremely close to the endpoints as the endpoints to avoid + // tiny floating-point representation differences for percentage inputs. + static constexpr float kLightnessEndpointEpsilon = 0.000002f; + + // If lightness is at either endpoint, the color is black/white regardless + // of chroma and hue (or a/b). + if (lightness <= kLightnessEndpointEpsilon) { + return NS_RGBA(0, 0, 0, alpha); + } + if (lightness >= 1.0f - kLightnessEndpointEpsilon) { + return NS_RGBA(255, 255, 255, alpha); + } float lRoot = lightness + 0.3963377774f * aA + 0.2158037573f * aB; float mRoot = lightness - 0.1055613458f * aA - 0.0638541728f * aB; @@ -207,7 +222,7 @@ OKLabToSRGBColor(float aL, float aA, float aB, float aAlpha) NSToIntRound(r * 255.0f), NSToIntRound(g * 255.0f), NSToIntRound(b * 255.0f), - nsStyleUtil::FloatToColorComponent(mozilla::clamped(aAlpha, 0.0f, 1.0f))); + alpha); } static_assert(css::eAuthorSheetFeatures == 0 && diff --git a/layout/style/test/test_computed_style.html b/layout/style/test/test_computed_style.html index da4a0ba80a..1fd98f23f4 100644 --- a/layout/style/test/test_computed_style.html +++ b/layout/style/test/test_computed_style.html @@ -401,10 +401,14 @@ var noframe_container = document.getElementById("content"); ["hsl(0 0% 0% / 0.5)", "rgba(0, 0, 0, 0.5)"], ["oklab(0 0 0 / 1)", "rgb(0, 0, 0)"], ["oklab(0 0 0 / 0.5)", "rgba(0, 0, 0, 0.5)"], - ["oklab(150% 0.5 0.2 / 1)", "rgb(255, 0, 0)"], + ["oklab(150% 0.5 0.2 / 1)", "rgb(255, 255, 255)"], ["oklch(0 0 0 / 1)", "rgb(0, 0, 0)"], ["oklch(0 0 0 / 0.5)", "rgba(0, 0, 0, 0.5)"], - ["oklch(150% 0.5 50 / 1)", "rgb(255, 0, 0)"], + ["oklch(0.0001% 0.2 45 / 1)", "rgb(0, 0, 0)"], + ["oklch(99.9999% 0.2 45 / 1)", "rgb(255, 255, 255)"], + ["oklch(0% 1.1 60 / 1)", "rgb(0, 0, 0)"], + ["oklch(100% 110 60 / 1)", "rgb(255, 255, 255)"], + ["oklch(150% 0.5 50 / 1)", "rgb(255, 255, 255)"], ]; var p = document.createElement("p");