Issue #2982 - Follow-up: allow color-mix to work with oklab and oklch

Tag #2489 and #3003
This commit is contained in:
Basilisk-Dev 2026-05-08 14:29:43 -04:00 • committed by EAZYBLACK
commit 7e0818c9ec
7 changed files with 460 additions and 59 deletions

View file

@ -1238,8 +1238,9 @@ protected:
bool ParseHSLColor(float& aHue, float& aSaturation, float& aLightness,
float& aOpacity);
bool ParseLCHColor(nscolor& aColor);
bool ParseOKLabColor(nscolor& aColor);
bool ParseOKLCHColor(nscolor& aColor);
bool ParseOKLabColor(float& aL, float& aA, float& aB, float& aAlpha);
bool ParseOKLCHColor(float& aL, float& aChroma, float& aHue,
float& aAlpha);
bool ParseOKLabComponent(float& aComponent, float aPercentScale,
Maybe<char> aSeparator);
@ -7474,7 +7475,7 @@ CSSParserImpl::ParseColor(nsCSSValue& aValue)
return CSSParseResult::Error;
}
// Check for supported color spaces: srgb or hsl
// Check for supported color spaces.
if (!GetToken(true) || mToken.mType != eCSSToken_Ident) {
SkipUntil(')');
return CSSParseResult::Error;
@ -7485,6 +7486,10 @@ CSSParserImpl::ParseColor(nsCSSValue& aValue)
colorSpace = mozilla::css::ColorMixColorSpace::sRGB;
} else if (mToken.mIdent.LowerCaseEqualsLiteral("hsl")) {
colorSpace = mozilla::css::ColorMixColorSpace::HSL;
} else if (mToken.mIdent.LowerCaseEqualsLiteral("oklab")) {
colorSpace = mozilla::css::ColorMixColorSpace::Oklab;
} else if (mToken.mIdent.LowerCaseEqualsLiteral("oklch")) {
colorSpace = mozilla::css::ColorMixColorSpace::Oklch;
} else {
SkipUntil(')');
return CSSParseResult::Error;
@ -7633,16 +7638,19 @@ CSSParserImpl::ParseColor(nsCSSValue& aValue)
return CSSParseResult::Error;
}
else if (mToken.mIdent.LowerCaseEqualsLiteral("oklab")) {
if (ParseOKLabColor(rgba)) {
aValue.SetColorValue(rgba);
float l, a, b, alpha;
if (ParseOKLabColor(l, a, b, alpha)) {
aValue.SetFloatColorValue(l, a, b, alpha, eCSSUnit_OklabColor);
return CSSParseResult::Ok;
}
SkipUntil(')');
return CSSParseResult::Error;
}
else if (mToken.mIdent.LowerCaseEqualsLiteral("oklch")) {
if (ParseOKLCHColor(rgba)) {
aValue.SetColorValue(rgba);
float l, chroma, hue, alpha;
if (ParseOKLCHColor(l, chroma, hue, alpha)) {
aValue.SetFloatColorValue(l, chroma, hue, alpha,
eCSSUnit_OklchColor);
return CSSParseResult::Ok;
}
SkipUntil(')');
@ -7894,7 +7902,8 @@ CSSParserImpl::ParseLCHColor(nscolor& aColor)
}
bool
CSSParserImpl::ParseOKLabColor(nscolor& aColor)
CSSParserImpl::ParseOKLabColor(float& aL, float& aA, float& aB,
float& aAlpha)
{
const char commaSeparator = ',';
float l, a, b, alpha;
@ -7912,12 +7921,16 @@ CSSParserImpl::ParseOKLabColor(nscolor& aColor)
return false;
}
aColor = OklabToSRGBColor(l, a, b, alpha);
aL = mozilla::clamped(l, 0.0f, 1.0f);
aA = a;
aB = b;
aAlpha = alpha;
return true;
}
bool
CSSParserImpl::ParseOKLCHColor(nscolor& aColor)
CSSParserImpl::ParseOKLCHColor(float& aL, float& aChroma, float& aHue,
float& aAlpha)
{
const char commaSeparator = ',';
float l, chroma, hue, alpha;
@ -7935,7 +7948,10 @@ CSSParserImpl::ParseOKLCHColor(nscolor& aColor)
return false;
}
aColor = OklchToSRGBColor(l, chroma, hue, alpha);
aL = mozilla::clamped(l, 0.0f, 1.0f);
aChroma = std::max(chroma, 0.0f);
aHue = NormalizeHue(hue);
aAlpha = alpha;
return true;
}