LibWeb/CSS: Support the xyz-d65 colorspace in the color() function

This also adds support for `xyz` as it defaults to `xyz-d65`. We now
pass the following WPT tests:
 - css/css-color/xyz-001.html
 - css/css-color/xyz-002.html
 - css/css-color/xyz-004.html
 - css/css-color/xyz-d65-001.html
 - css/css-color/xyz-d65-002.html
 - css/css-color/xyz-d65-004.html
This commit is contained in:
Lucas CHOLLET 2024-10-27 14:02:10 -04:00 committed by Andreas Kling
parent ff6102430e
commit 10dc7ff042
Notes: github-actions[bot] 2024-11-09 14:16:30 +00:00
8 changed files with 70 additions and 3 deletions

View file

@ -0,0 +1,10 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Green square reference</title>
<style>
.test { background-color: #008000; width: 12em; height: 12em;}
</style>
<body>
<p>Test passes if you see a green square, and no red.</p>
<div class="test"></div>
</body>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Color 4: xyz</title>
<link rel="author" title="Sam Weinig" href="mailto:weinig@apple.com">
<link rel="help" href="https://drafts.csswg.org/css-color-4/#valdef-color-xyz">
<link rel="match" href="../../../../expected/wpt-import/css/css-color/greensquare-ref.html">
<meta name="assert" content="xyz with no alpha">
<style>
.test { background-color: red; width: 12em; height: 12em; }
.test { background-color: color(xyz 0.07719 0.15438 0.02573); } /* green (sRGB #008000) converted to xyz */
</style>
<body>
<p>Test passes if you see a green square, and no red.</p>
<div class="test"></div>
</body>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Color 4: xyz</title>
<link rel="author" title="Sam Weinig" href="mailto:weinig@apple.com">
<link rel="help" href="https://drafts.csswg.org/css-color-4/#valdef-color-xyz">
<link rel="match" href="../../../../expected/wpt-import/css/css-color/greensquare-ref.html">
<meta name="assert" content="xyz-d65 with no alpha">
<style>
.test { background-color: red; width: 12em; height: 12em; }
.test { background-color: color(xyz-d65 0.07719 0.15438 0.02573); } /* green (sRGB #008000) converted to xyz-d65 */
</style>
<body>
<p>Test passes if you see a green square, and no red.</p>
<div class="test"></div>
</body>

View file

@ -423,6 +423,16 @@ Color Color::from_xyz50(float x, float y, float z, float alpha)
return from_linear_srgb(red, green, blue, alpha);
}
Color Color::from_xyz65(float x, float y, float z, float alpha)
{
// https://en.wikipedia.org/wiki/SRGB#From_CIE_XYZ_to_sRGB
float red = 3.2406 * x - 1.5372 * y - 0.4986 * z;
float green = -0.9689 * x + 1.8758 * y + 0.0415 * z;
float blue = 0.0557 * x - 0.2040 * y + 1.0570 * z;
return from_linear_srgb(red, green, blue, alpha);
}
Color Color::from_lab(float L, float a, float b, float alpha)
{
// Third edition of "Colorimetry" by the CIE

View file

@ -184,6 +184,7 @@ public:
static Color from_lab(float L, float a, float b, float alpha = 1.0f);
static Color from_xyz50(float x, float y, float z, float alpha = 1.0f);
static Color from_xyz65(float x, float y, float z, float alpha = 1.0f);
static Color from_linear_srgb(float x, float y, float z, float alpha = 1.0f);
// https://bottosson.github.io/posts/oklab/

View file

@ -11,6 +11,19 @@
namespace Web::CSS {
namespace {
CSSColorValue::ColorType color_type_from_string_view(StringView color_space)
{
if (color_space == "xyz-d50"sv)
return CSSColorValue::ColorType::XYZD50;
if (color_space == "xyz"sv || color_space == "xyz-d65")
return CSSColorValue::ColorType::XYZD65;
VERIFY_NOT_REACHED();
}
}
ValueComparingNonnullRefPtr<CSSColor> CSSColor::create(StringView color_space, ValueComparingNonnullRefPtr<CSSStyleValue> c1, ValueComparingNonnullRefPtr<CSSStyleValue> c2, ValueComparingNonnullRefPtr<CSSStyleValue> c3, ValueComparingRefPtr<CSSStyleValue> alpha)
{
VERIFY(any_of(s_supported_color_space, [=](auto supported) { return color_space == supported; }));
@ -18,8 +31,7 @@ ValueComparingNonnullRefPtr<CSSColor> CSSColor::create(StringView color_space, V
if (!alpha)
alpha = NumberStyleValue::create(1);
if (color_space == "xyz-d50")
return adopt_ref(*new (nothrow) CSSColor(ColorType::XYZD50, move(c1), move(c2), move(c3), alpha.release_nonnull()));
return adopt_ref(*new (nothrow) CSSColor(color_type_from_string_view(color_space), move(c1), move(c2), move(c3), alpha.release_nonnull()));
VERIFY_NOT_REACHED();
}
@ -52,6 +64,9 @@ Color CSSColor::to_color(Optional<Layout::NodeWithStyle const&>) const
if (color_type() == ColorType::XYZD50)
return Color::from_xyz50(c1, c2, c3, alpha_val);
if (color_type() == ColorType::XYZD65)
return Color::from_xyz65(c1, c2, c3, alpha_val);
VERIFY_NOT_REACHED();
}

View file

@ -21,7 +21,7 @@ public:
virtual Color to_color(Optional<Layout::NodeWithStyle const&>) const override;
virtual String to_string() const override;
static constexpr Array s_supported_color_space = { "xyz-d50"sv };
static constexpr Array s_supported_color_space = { "xyz"sv, "xyz-d50"sv, "xyz-d65"sv };
private:
CSSColor(ColorType color_type, ValueComparingNonnullRefPtr<CSSStyleValue> c1, ValueComparingNonnullRefPtr<CSSStyleValue> c2, ValueComparingNonnullRefPtr<CSSStyleValue> c3, ValueComparingNonnullRefPtr<CSSStyleValue> alpha)

View file

@ -31,6 +31,7 @@ public:
OKLab,
OKLCH,
XYZD50,
XYZD65,
};
ColorType color_type() const { return m_color_type; }