mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-06 07:48:38 +09:00
Issue #2982 - Initial oklch test implementation
This commit is contained in:
parent
78035ce7a9
commit
45e476f332
3 changed files with 5743 additions and 1994 deletions
|
|
@ -166,6 +166,44 @@ struct ReducePercentageCalcOps : ReduceNumberCalcOps
|
|||
}
|
||||
};
|
||||
|
||||
static constexpr float kOKLabPercentScaleAB = 0.4f;
|
||||
static constexpr double kRadiansPerDegree = 0.01745329251994329576923690768489;
|
||||
|
||||
static inline float
|
||||
LinearSRGBToEncoded(float aValue)
|
||||
{
|
||||
if (aValue <= 0.0031308f) {
|
||||
return 12.92f * aValue;
|
||||
}
|
||||
return 1.055f * std::pow(aValue, 1.0f / 2.4f) - 0.055f;
|
||||
}
|
||||
|
||||
static nscolor
|
||||
OKLabToSRGBColor(float aL, float aA, float aB, float aAlpha)
|
||||
{
|
||||
float lRoot = aL + 0.3963377774f * aA + 0.2158037573f * aB;
|
||||
float mRoot = aL - 0.1055613458f * aA - 0.0638541728f * aB;
|
||||
float sRoot = aL - 0.0894841775f * aA - 1.2914855480f * aB;
|
||||
|
||||
float l = lRoot * lRoot * lRoot;
|
||||
float m = mRoot * mRoot * mRoot;
|
||||
float s = sRoot * sRoot * sRoot;
|
||||
|
||||
float linearR = 4.0767416621f * l - 3.3077115913f * m + 0.2309699292f * s;
|
||||
float linearG = -1.2684380046f * l + 2.6097574011f * m - 0.3413193965f * s;
|
||||
float linearB = -0.0041960863f * l - 0.7034186147f * m + 1.7076147010f * s;
|
||||
|
||||
float r = mozilla::clamped(LinearSRGBToEncoded(linearR), 0.0f, 1.0f);
|
||||
float g = mozilla::clamped(LinearSRGBToEncoded(linearG), 0.0f, 1.0f);
|
||||
float b = mozilla::clamped(LinearSRGBToEncoded(linearB), 0.0f, 1.0f);
|
||||
|
||||
return NS_RGBA(
|
||||
NSToIntRound(r * 255.0f),
|
||||
NSToIntRound(g * 255.0f),
|
||||
NSToIntRound(b * 255.0f),
|
||||
nsStyleUtil::FloatToColorComponent(mozilla::clamped(aAlpha, 0.0f, 1.0f)));
|
||||
}
|
||||
|
||||
static_assert(css::eAuthorSheetFeatures == 0 &&
|
||||
css::eUserSheetFeatures == 1 &&
|
||||
css::eAgentSheetFeatures == 2,
|
||||
|
|
@ -1233,6 +1271,10 @@ protected:
|
|||
ComponentType& aA);
|
||||
bool ParseHSLColor(float& aHue, float& aSaturation, float& aLightness,
|
||||
float& aOpacity);
|
||||
bool ParseOKLabColor(nscolor& aColor);
|
||||
bool ParseOKLCHColor(nscolor& aColor);
|
||||
bool ParseOKLabComponent(float& aComponent, float aPercentScale,
|
||||
Maybe<char> aSeparator);
|
||||
|
||||
// The ParseColorOpacityAndCloseParen methods below attempt to parse an
|
||||
// optional [ separator <alpha-value> ] expression, followed by a
|
||||
|
|
@ -7608,6 +7650,22 @@ CSSParserImpl::ParseColor(nsCSSValue& aValue)
|
|||
SkipUntil(')');
|
||||
return CSSParseResult::Error;
|
||||
}
|
||||
else if (mToken.mIdent.LowerCaseEqualsLiteral("oklab")) {
|
||||
if (ParseOKLabColor(rgba)) {
|
||||
aValue.SetColorValue(rgba);
|
||||
return CSSParseResult::Ok;
|
||||
}
|
||||
SkipUntil(')');
|
||||
return CSSParseResult::Error;
|
||||
}
|
||||
else if (mToken.mIdent.LowerCaseEqualsLiteral("oklch")) {
|
||||
if (ParseOKLCHColor(rgba)) {
|
||||
aValue.SetColorValue(rgba);
|
||||
return CSSParseResult::Ok;
|
||||
}
|
||||
SkipUntil(')');
|
||||
return CSSParseResult::Error;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
@ -7808,6 +7866,84 @@ CSSParserImpl::ParseHSLColor(float& aHue, float& aSaturation, float& aLightness,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseOKLabComponent(float& aComponent, float aPercentScale,
|
||||
Maybe<char> aSeparator)
|
||||
{
|
||||
if (!GetToken(true)) {
|
||||
REPORT_UNEXPECTED_EOF(PEColorComponentEOF);
|
||||
return false;
|
||||
}
|
||||
|
||||
float value;
|
||||
if (mToken.mType == eCSSToken_Number) {
|
||||
value = mToken.mNumber;
|
||||
} else if (mToken.mType == eCSSToken_Percentage) {
|
||||
value = mToken.mNumber * aPercentScale;
|
||||
} else {
|
||||
REPORT_UNEXPECTED_TOKEN(PEExpectedNumberOrPercent);
|
||||
UngetToken();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aSeparator && !ExpectSymbol(*aSeparator, true)) {
|
||||
REPORT_UNEXPECTED_TOKEN_CHAR(PEColorComponentBadTerm, *aSeparator);
|
||||
return false;
|
||||
}
|
||||
|
||||
aComponent = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseOKLabColor(nscolor& aColor)
|
||||
{
|
||||
const char commaSeparator = ',';
|
||||
float l, a, b, alpha;
|
||||
|
||||
if (!ParseOKLabComponent(l, 1.0f, Nothing())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hasComma = ExpectSymbol(commaSeparator, true);
|
||||
const char separatorBeforeAlpha = hasComma ? commaSeparator : '/';
|
||||
if (!ParseOKLabComponent(a, kOKLabPercentScaleAB,
|
||||
hasComma ? Some(commaSeparator) : Nothing()) ||
|
||||
!ParseOKLabComponent(b, kOKLabPercentScaleAB, Nothing()) ||
|
||||
!ParseColorOpacityAndCloseParen(alpha, separatorBeforeAlpha)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aColor = OKLabToSRGBColor(l, a, b, alpha);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseOKLCHColor(nscolor& aColor)
|
||||
{
|
||||
const char commaSeparator = ',';
|
||||
float l, chroma, hue, alpha;
|
||||
|
||||
if (!ParseOKLabComponent(l, 1.0f, Nothing())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hasComma = ExpectSymbol(commaSeparator, true);
|
||||
const char separatorBeforeAlpha = hasComma ? commaSeparator : '/';
|
||||
if (!ParseOKLabComponent(chroma, kOKLabPercentScaleAB,
|
||||
hasComma ? Some(commaSeparator) : Nothing()) ||
|
||||
!ParseHue(hue) ||
|
||||
!ParseColorOpacityAndCloseParen(alpha, separatorBeforeAlpha)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
double hueRadians = hue * kRadiansPerDegree;
|
||||
float a = chroma * std::cos(hueRadians);
|
||||
float b = chroma * std::sin(hueRadians);
|
||||
aColor = OKLabToSRGBColor(l, a, b, alpha);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseColorOpacityAndCloseParen(uint8_t& aOpacity,
|
||||
|
|
@ -8756,6 +8892,8 @@ CSSParserImpl::ParseVariant(nsCSSValue& aValue,
|
|||
tk->mIdent.LowerCaseEqualsLiteral("hsl") ||
|
||||
tk->mIdent.LowerCaseEqualsLiteral("rgba") ||
|
||||
tk->mIdent.LowerCaseEqualsLiteral("hsla") ||
|
||||
tk->mIdent.LowerCaseEqualsLiteral("oklab") ||
|
||||
tk->mIdent.LowerCaseEqualsLiteral("oklch") ||
|
||||
tk->mIdent.LowerCaseEqualsLiteral("color-mix"))))
|
||||
{
|
||||
// Put token back so that parse color can get it
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue