diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 846c0d7ce71..8b83b8b15da 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -3385,6 +3385,26 @@ Optional, 4>> Parser::parse_lch_like_color_value(Tok return Array { move(l), move(c), move(h), move(alpha) }; } +// https://www.w3.org/TR/css-color-4/#funcdef-lch +RefPtr Parser::parse_lch_color_value(TokenStream& outer_tokens) +{ + // lch() = lch( [ | | none] + // [ | | none] + // [ | none] + // [ / [ | none] ]? ) + + auto maybe_color_values = parse_lch_like_color_value(outer_tokens, "lch"sv); + if (!maybe_color_values.has_value()) + return {}; + + auto& color_values = *maybe_color_values; + + return CSSLCHLike::create(color_values[0].release_nonnull(), + color_values[1].release_nonnull(), + color_values[2].release_nonnull(), + color_values[3].release_nonnull()); +} + // https://www.w3.org/TR/css-color-4/#funcdef-oklch RefPtr Parser::parse_oklch_color_value(TokenStream& outer_tokens) { @@ -3490,6 +3510,8 @@ RefPtr Parser::parse_color_value(TokenStream& tok return hwb; if (auto lab = parse_lab_color_value(tokens)) return lab; + if (auto lch = parse_lch_color_value(tokens)) + return lch; if (auto oklab = parse_oklab_color_value(tokens)) return oklab; if (auto oklch = parse_oklch_color_value(tokens)) diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h index 5a9c4f483a2..d0865d55d88 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h @@ -254,6 +254,7 @@ private: RefPtr parse_lab_color_value(TokenStream&); RefPtr parse_oklab_color_value(TokenStream&); Optional, 4>> parse_lch_like_color_value(TokenStream&, StringView); + RefPtr parse_lch_color_value(TokenStream&); RefPtr parse_oklch_color_value(TokenStream&); RefPtr parse_color_function(TokenStream&); RefPtr parse_color_value(TokenStream&); diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/CSSColorValue.h b/Userland/Libraries/LibWeb/CSS/StyleValues/CSSColorValue.h index 5398fe87a76..9b3f16fe30e 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValues/CSSColorValue.h +++ b/Userland/Libraries/LibWeb/CSS/StyleValues/CSSColorValue.h @@ -27,6 +27,7 @@ public: HSL, HWB, Lab, + LCH, OKLab, OKLCH, XYZD50, diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/CSSLCHLike.cpp b/Userland/Libraries/LibWeb/CSS/StyleValues/CSSLCHLike.cpp index 9d1f81c7987..c8f7ae30ef2 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValues/CSSLCHLike.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleValues/CSSLCHLike.cpp @@ -25,6 +25,23 @@ bool CSSLCHLike::equals(CSSStyleValue const& other) const return m_properties == other_oklch_like.m_properties; } +Color CSSLCH::to_color(Optional) const +{ + auto const l_val = clamp(resolve_with_reference_value(m_properties.l, 100).value_or(0), 0, 100); + auto const c_val = resolve_with_reference_value(m_properties.c, 150).value_or(0); + auto const h_val = AK::to_radians(resolve_hue(m_properties.h).value_or(0)); + auto const alpha_val = resolve_alpha(m_properties.alpha).value_or(1); + + return Color::from_lab(l_val, c_val * cos(h_val), c_val * sin(h_val), alpha_val); +} + +// https://www.w3.org/TR/css-color-4/#serializing-lab-lch +String CSSLCH::to_string() const +{ + // FIXME: Do this properly, taking unresolved calculated values into account. + return serialize_a_srgb_value(to_color({})); +} + Color CSSOKLCH::to_color(Optional) const { auto const l_val = clamp(resolve_with_reference_value(m_properties.l, 1.0).value_or(0), 0, 1); diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/CSSLCHLike.h b/Userland/Libraries/LibWeb/CSS/StyleValues/CSSLCHLike.h index 7410ec60b04..6e52645486e 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValues/CSSLCHLike.h +++ b/Userland/Libraries/LibWeb/CSS/StyleValues/CSSLCHLike.h @@ -14,7 +14,7 @@ namespace Web::CSS { class CSSLCHLike : public CSSColorValue { public: template T> - static ValueComparingNonnullRefPtr create(ValueComparingNonnullRefPtr l, ValueComparingNonnullRefPtr c, ValueComparingNonnullRefPtr h, ValueComparingRefPtr alpha = {}) + static ValueComparingNonnullRefPtr create(ValueComparingNonnullRefPtr l, ValueComparingNonnullRefPtr c, ValueComparingNonnullRefPtr h, ValueComparingRefPtr alpha = {}) { // alpha defaults to 1 if (!alpha) @@ -47,6 +47,20 @@ protected: } m_properties; }; +// https://drafts.css-houdini.org/css-typed-om-1/#csslch +class CSSLCH final : public CSSLCHLike { +public: + CSSLCH(Badge, ValueComparingNonnullRefPtr l, ValueComparingNonnullRefPtr c, ValueComparingNonnullRefPtr h, ValueComparingNonnullRefPtr alpha) + : CSSLCHLike(ColorType::LCH, move(l), move(c), move(h), move(alpha)) + { + } + virtual ~CSSLCH() override = default; + + virtual Color to_color(Optional) const override; + + virtual String to_string() const override; +}; + // https://drafts.css-houdini.org/css-typed-om-1/#cssoklch class CSSOKLCH final : public CSSLCHLike { public: