mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-24 16:17:29 +09:00
Issue #2489: Allow color-mix() to differentiate color spaces
This commit is contained in:
parent
cb2547efa3
commit
01b0b8251d
2 changed files with 79 additions and 27 deletions
|
|
@ -7457,7 +7457,18 @@ CSSParserImpl::ParseColor(nsCSSValue& aValue)
|
||||||
return CSSParseResult::Error;
|
return CSSParseResult::Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GetToken(true) || mToken.mType != eCSSToken_Ident || !mToken.mIdent.LowerCaseEqualsLiteral("srgb")) {
|
// Check for supported color spaces: srgb or hsl
|
||||||
|
if (!GetToken(true) || mToken.mType != eCSSToken_Ident) {
|
||||||
|
SkipUntil(')');
|
||||||
|
return CSSParseResult::Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
mozilla::css::ColorMixColorSpace colorSpace;
|
||||||
|
if (mToken.mIdent.LowerCaseEqualsLiteral("srgb")) {
|
||||||
|
colorSpace = mozilla::css::ColorMixColorSpace::sRGB;
|
||||||
|
} else if (mToken.mIdent.LowerCaseEqualsLiteral("hsl")) {
|
||||||
|
colorSpace = mozilla::css::ColorMixColorSpace::HSL;
|
||||||
|
} else {
|
||||||
SkipUntil(')');
|
SkipUntil(')');
|
||||||
return CSSParseResult::Error;
|
return CSSParseResult::Error;
|
||||||
}
|
}
|
||||||
|
|
@ -7528,7 +7539,7 @@ CSSParserImpl::ParseColor(nsCSSValue& aValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<mozilla::css::ColorMixValue> colorMix = new mozilla::css::ColorMixValue(
|
RefPtr<mozilla::css::ColorMixValue> colorMix = new mozilla::css::ColorMixValue(
|
||||||
mozilla::css::ColorMixColorSpace::sRGB, color1, color2, w1, w2);
|
colorSpace, color1, color2, w1, w2);
|
||||||
aValue.SetColorMixValue(colorMix.forget());
|
aValue.SetColorMixValue(colorMix.forget());
|
||||||
return CSSParseResult::Ok;
|
return CSSParseResult::Ok;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1153,17 +1153,6 @@ static bool SetColor(const nsCSSValue& aValue, const nscolor aParentColor,
|
||||||
aResult = NS_RGBA(0, 0, 0, 0);
|
aResult = NS_RGBA(0, 0, 0, 0);
|
||||||
result = true;
|
result = true;
|
||||||
} else {
|
} else {
|
||||||
// extracts RGBA components from both colors
|
|
||||||
float r1 = NS_GET_R(color1);
|
|
||||||
float g1 = NS_GET_G(color1);
|
|
||||||
float b1 = NS_GET_B(color1);
|
|
||||||
float a1 = NS_GET_A(color1);
|
|
||||||
|
|
||||||
float r2 = NS_GET_R(color2);
|
|
||||||
float g2 = NS_GET_G(color2);
|
|
||||||
float b2 = NS_GET_B(color2);
|
|
||||||
float a2 = NS_GET_A(color2);
|
|
||||||
|
|
||||||
// normalize weights
|
// normalize weights
|
||||||
float sum = w1 + w2;
|
float sum = w1 + w2;
|
||||||
if (sum <= 0.0f) {
|
if (sum <= 0.0f) {
|
||||||
|
|
@ -1175,20 +1164,72 @@ static bool SetColor(const nsCSSValue& aValue, const nscolor aParentColor,
|
||||||
float norm1 = w1 / sum;
|
float norm1 = w1 / sum;
|
||||||
float norm2 = w2 / sum;
|
float norm2 = w2 / sum;
|
||||||
|
|
||||||
// perform linear interpolation
|
if (colorMix->mColorSpace == mozilla::css::ColorMixColorSpace::HSL) {
|
||||||
float r = r1 * norm1 + r2 * norm2;
|
// HSL color space mixing
|
||||||
float g = g1 * norm1 + g2 * norm2;
|
float h1, s1, l1, h2, s2, l2;
|
||||||
float b = b1 * norm1 + b2 * norm2;
|
|
||||||
float a = a1 * norm1 + a2 * norm2;
|
|
||||||
|
|
||||||
// convert to integers with rounding
|
// Convert RGB colors to HSL
|
||||||
uint8_t rInt = (uint8_t)mozilla::clamped(r + 0.5f, 0.0f, 255.0f);
|
NS_RGB2HSL(NS_GET_R(color1), NS_GET_G(color1), NS_GET_B(color1), &h1, &s1, &l1);
|
||||||
uint8_t gInt = (uint8_t)mozilla::clamped(g + 0.5f, 0.0f, 255.0f);
|
NS_RGB2HSL(NS_GET_R(color2), NS_GET_G(color2), NS_GET_B(color2), &h2, &s2, &l2);
|
||||||
uint8_t bInt = (uint8_t)mozilla::clamped(b + 0.5f, 0.0f, 255.0f);
|
|
||||||
uint8_t aInt = (uint8_t)mozilla::clamped(a + 0.5f, 0.0f, 255.0f);
|
|
||||||
|
|
||||||
aResult = NS_RGBA(rInt, gInt, bInt, aInt);
|
// Handle hue interpolation (circular)
|
||||||
result = true;
|
float h;
|
||||||
|
if (s1 == 0.0f || s2 == 0.0f) {
|
||||||
|
// If either color is achromatic, use the hue from the chromatic color
|
||||||
|
h = (s1 == 0.0f) ? h2 : h1;
|
||||||
|
} else {
|
||||||
|
float hue_diff = h2 - h1;
|
||||||
|
if (hue_diff > 0.5f) {
|
||||||
|
h1 += 1.0f;
|
||||||
|
} else if (hue_diff < -0.5f) {
|
||||||
|
h2 += 1.0f;
|
||||||
|
}
|
||||||
|
h = h1 * norm1 + h2 * norm2;
|
||||||
|
if (h >= 1.0f) h -= 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interpolate saturation and lightness linearly
|
||||||
|
float s = s1 * norm1 + s2 * norm2;
|
||||||
|
float l = l1 * norm1 + l2 * norm2;
|
||||||
|
|
||||||
|
// Interpolate alpha in RGB space
|
||||||
|
float a1 = NS_GET_A(color1);
|
||||||
|
float a2 = NS_GET_A(color2);
|
||||||
|
float a = a1 * norm1 + a2 * norm2;
|
||||||
|
|
||||||
|
// Convert back to RGB
|
||||||
|
nscolor hslResult = NS_HSL2RGB(h, s, l);
|
||||||
|
uint8_t aInt = (uint8_t)mozilla::clamped(a + 0.5f, 0.0f, 255.0f);
|
||||||
|
|
||||||
|
aResult = NS_RGBA(NS_GET_R(hslResult), NS_GET_G(hslResult), NS_GET_B(hslResult), aInt);
|
||||||
|
result = true;
|
||||||
|
} else {
|
||||||
|
// sRGB color space mixing (existing logic)
|
||||||
|
float r1 = NS_GET_R(color1);
|
||||||
|
float g1 = NS_GET_G(color1);
|
||||||
|
float b1 = NS_GET_B(color1);
|
||||||
|
float a1 = NS_GET_A(color1);
|
||||||
|
|
||||||
|
float r2 = NS_GET_R(color2);
|
||||||
|
float g2 = NS_GET_G(color2);
|
||||||
|
float b2 = NS_GET_B(color2);
|
||||||
|
float a2 = NS_GET_A(color2);
|
||||||
|
|
||||||
|
// perform linear interpolation
|
||||||
|
float r = r1 * norm1 + r2 * norm2;
|
||||||
|
float g = g1 * norm1 + g2 * norm2;
|
||||||
|
float b = b1 * norm1 + b2 * norm2;
|
||||||
|
float a = a1 * norm1 + a2 * norm2;
|
||||||
|
|
||||||
|
// convert to integers with rounding
|
||||||
|
uint8_t rInt = (uint8_t)mozilla::clamped(r + 0.5f, 0.0f, 255.0f);
|
||||||
|
uint8_t gInt = (uint8_t)mozilla::clamped(g + 0.5f, 0.0f, 255.0f);
|
||||||
|
uint8_t bInt = (uint8_t)mozilla::clamped(b + 0.5f, 0.0f, 255.0f);
|
||||||
|
uint8_t aInt = (uint8_t)mozilla::clamped(a + 0.5f, 0.0f, 255.0f);
|
||||||
|
|
||||||
|
aResult = NS_RGBA(rInt, gInt, bInt, aInt);
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue