diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index fed5b897307..f1049abdcbc 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -268,7 +268,6 @@ set(SOURCES CSS/StyleValues/ImageStyleValue.cpp CSS/StyleValues/IntegerStyleValue.cpp CSS/StyleValues/KeywordStyleValue.cpp - CSS/StyleValues/LCHLikeColorStyleValue.cpp CSS/StyleValues/LengthStyleValue.cpp CSS/StyleValues/LightDarkStyleValue.cpp CSS/StyleValues/LinearGradientStyleValue.cpp diff --git a/Libraries/LibWeb/CSS/ColorInterpolation.cpp b/Libraries/LibWeb/CSS/ColorInterpolation.cpp index 22874aa0517..cd0c57384ba 100644 --- a/Libraries/LibWeb/CSS/ColorInterpolation.cpp +++ b/Libraries/LibWeb/CSS/ColorInterpolation.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include namespace Web::CSS { @@ -138,12 +137,12 @@ static MissingComponents extract_missing_components(StyleValue const& style_valu return { is_component_none(oklab.channel(0)), is_component_none(oklab.channel(1)), is_component_none(oklab.channel(2)), is_component_none(oklab.alpha()) }; } case ColorStyleValue::ColorType::LCH: { - auto const& lch = as(color); - return { is_component_none(lch.l()), is_component_none(lch.c()), is_component_none(lch.h()), is_component_none(lch.alpha()) }; + auto const& lch = as(color); + return { is_component_none(lch.channel(0)), is_component_none(lch.channel(1)), is_component_none(lch.channel(2)), is_component_none(lch.alpha()) }; } case ColorStyleValue::ColorType::OKLCH: { - auto const& oklch = as(color); - return { is_component_none(oklch.l()), is_component_none(oklch.c()), is_component_none(oklch.h()), is_component_none(oklch.alpha()) }; + auto const& oklch = as(color); + return { is_component_none(oklch.channel(0)), is_component_none(oklch.channel(1)), is_component_none(oklch.channel(2)), is_component_none(oklch.alpha()) }; } case ColorStyleValue::ColorType::RGB: { auto const& rgb = as(color); @@ -363,13 +362,13 @@ static ValueComparingNonnullRefPtr style_value_from_polar_colo alpha); } case PolarColorSpace::Lch: - return LCHLikeColorStyleValue::create( + return ColorFunctionStyleValue::create(ColorStyleValue::ColorType::LCH, number_or_none(components[0], missing.component(0)), number_or_none(components[1], missing.component(1)), number_or_none(components[2], missing.component(2)), alpha); case PolarColorSpace::Oklch: - return LCHLikeColorStyleValue::create( + return ColorFunctionStyleValue::create(ColorStyleValue::ColorType::OKLCH, number_or_none(components[0], missing.component(0)), number_or_none(components[1], missing.component(1)), number_or_none(components[2], missing.component(2)), @@ -437,20 +436,20 @@ static Optional style_value_to_color_components(StyleValue return Gfx::ColorComponents { static_cast(l.value()), static_cast(a_comp.value()), static_cast(b_comp.value()), a.value() }; } case ColorStyleValue::ColorType::LCH: { - auto const& lch = as(color); - auto l = ColorStyleValue::resolve_with_reference_value(lch.l(), 100.0f, context); - auto c = ColorStyleValue::resolve_with_reference_value(lch.c(), 150.0f, context); - auto h = ColorStyleValue::resolve_hue(lch.h(), context); + auto const& lch = as(color); + auto l = ColorStyleValue::resolve_with_reference_value(lch.channel(0), 100.0f, context); + auto c = ColorStyleValue::resolve_with_reference_value(lch.channel(1), 150.0f, context); + auto h = ColorStyleValue::resolve_hue(lch.channel(2), context); auto a = resolve_alpha(lch.alpha()); if (!l.has_value() || !c.has_value() || !h.has_value() || !a.has_value()) return {}; return Gfx::ColorComponents { static_cast(l.value()), static_cast(c.value()), static_cast(h.value()), a.value() }; } case ColorStyleValue::ColorType::OKLCH: { - auto const& oklch = as(color); - auto l = ColorStyleValue::resolve_with_reference_value(oklch.l(), 1.0f, context); - auto c = ColorStyleValue::resolve_with_reference_value(oklch.c(), 0.4f, context); - auto h = ColorStyleValue::resolve_hue(oklch.h(), context); + auto const& oklch = as(color); + auto l = ColorStyleValue::resolve_with_reference_value(oklch.channel(0), 1.0f, context); + auto c = ColorStyleValue::resolve_with_reference_value(oklch.channel(1), 0.4f, context); + auto h = ColorStyleValue::resolve_hue(oklch.channel(2), context); auto a = resolve_alpha(oklch.alpha()); if (!l.has_value() || !c.has_value() || !h.has_value() || !a.has_value()) return {}; diff --git a/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp b/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp index 84b7a404634..72b8227a047 100644 --- a/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp +++ b/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp @@ -56,7 +56,6 @@ #include #include #include -#include #include #include #include @@ -1893,7 +1892,7 @@ RefPtr Parser::parse_lch_color_value(TokenStream(color_values[0].release_nonnull(), + return ColorFunctionStyleValue::create(ColorStyleValue::ColorType::LCH, color_values[0].release_nonnull(), color_values[1].release_nonnull(), color_values[2].release_nonnull(), color_values[3].release_nonnull()); @@ -1913,7 +1912,7 @@ RefPtr Parser::parse_oklch_color_value(TokenStream(color_values[0].release_nonnull(), + return ColorFunctionStyleValue::create(ColorStyleValue::ColorType::OKLCH, color_values[0].release_nonnull(), color_values[1].release_nonnull(), color_values[2].release_nonnull(), color_values[3].release_nonnull()); diff --git a/Libraries/LibWeb/CSS/StyleValues/LCHLikeColorStyleValue.cpp b/Libraries/LibWeb/CSS/StyleValues/LCHLikeColorStyleValue.cpp deleted file mode 100644 index 360f11e7a91..00000000000 --- a/Libraries/LibWeb/CSS/StyleValues/LCHLikeColorStyleValue.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2024-2026, Sam Atkins - * Copyright (c) 2025, Tim Ledbetter - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include "LCHLikeColorStyleValue.h" -#include -#include -#include -#include -#include -#include -#include - -namespace Web::CSS { - -bool LCHLikeColorStyleValue::equals(StyleValue const& other) const -{ - if (type() != other.type()) - return false; - auto const& other_color = other.as_color(); - if (color_type() != other_color.color_type()) - return false; - auto const& other_oklch_like = as(other_color); - return m_properties == other_oklch_like.m_properties; -} - -Optional LCHColorStyleValue::to_color(ColorResolutionContext color_resolution_context) const -{ - auto raw_l_val = resolve_with_reference_value(m_properties.l, 100, color_resolution_context.calculation_resolution_context); - auto c_val = resolve_with_reference_value(m_properties.c, 150, color_resolution_context.calculation_resolution_context); - auto raw_h_val = resolve_hue(m_properties.h, color_resolution_context.calculation_resolution_context); - auto alpha_val = resolve_alpha(m_properties.alpha, color_resolution_context.calculation_resolution_context); - - if (!raw_l_val.has_value() || !c_val.has_value() || !raw_h_val.has_value() || !alpha_val.has_value()) - return {}; - - auto l_val = clamp(raw_l_val.value(), 0, 100); - auto h_val = AK::to_radians(raw_h_val.value()); - - return Color::from_lab(l_val, c_val.value() * cos(h_val), c_val.value() * sin(h_val), alpha_val.value()); -} - -ValueComparingNonnullRefPtr LCHColorStyleValue::absolutized(ComputationContext const& context) const -{ - auto l = m_properties.l->absolutized(context); - auto c = m_properties.c->absolutized(context); - auto h = m_properties.h->absolutized(context); - auto alpha = m_properties.alpha->absolutized(context); - if (l == m_properties.l && c == m_properties.c && h == m_properties.h && alpha == m_properties.alpha) - return *this; - return LCHLikeColorStyleValue::create(move(l), move(c), move(h), move(alpha)); -} - -// https://www.w3.org/TR/css-color-4/#serializing-lab-lch -void LCHColorStyleValue::serialize(StringBuilder& builder, SerializationMode mode) const -{ - builder.append("lch("sv); - serialize_color_component(builder, mode, m_properties.l, 100, 0, 100); - builder.append(' '); - serialize_color_component(builder, mode, m_properties.c, 150, 0); - builder.append(' '); - serialize_hue_component(builder, mode, m_properties.h); - if ((!m_properties.alpha->is_number() || m_properties.alpha->as_number().number() < 1) - && (!m_properties.alpha->is_percentage() || m_properties.alpha->as_percentage().percentage().as_fraction() < 1)) { - builder.append(" / "sv); - serialize_alpha_component(builder, mode, m_properties.alpha); - } - - builder.append(')'); -} - -Optional OKLCHColorStyleValue::to_color(ColorResolutionContext color_resolution_context) const -{ - auto raw_l_val = resolve_with_reference_value(m_properties.l, 1.0, color_resolution_context.calculation_resolution_context); - auto raw_c_val = resolve_with_reference_value(m_properties.c, 0.4, color_resolution_context.calculation_resolution_context); - auto raw_h_val = resolve_hue(m_properties.h, color_resolution_context.calculation_resolution_context); - auto alpha_val = resolve_alpha(m_properties.alpha, color_resolution_context.calculation_resolution_context); - - if (!raw_l_val.has_value() || !raw_c_val.has_value() || !raw_h_val.has_value() || !alpha_val.has_value()) - return {}; - - auto l_val = clamp(raw_l_val.value(), 0, 1); - auto c_val = max(raw_c_val.value(), 0); - auto h_val = AK::to_radians(raw_h_val.value()); - - return Color::from_oklab(l_val, c_val * cos(h_val), c_val * sin(h_val), alpha_val.value()); -} - -ValueComparingNonnullRefPtr OKLCHColorStyleValue::absolutized(ComputationContext const& context) const -{ - auto l = m_properties.l->absolutized(context); - auto c = m_properties.c->absolutized(context); - auto h = m_properties.h->absolutized(context); - auto alpha = m_properties.alpha->absolutized(context); - if (l == m_properties.l && c == m_properties.c && h == m_properties.h && alpha == m_properties.alpha) - return *this; - return LCHLikeColorStyleValue::create(l, c, h, alpha); -} - -// https://www.w3.org/TR/css-color-4/#serializing-oklab-oklch -void OKLCHColorStyleValue::serialize(StringBuilder& builder, SerializationMode mode) const -{ - builder.append("oklch("sv); - serialize_color_component(builder, mode, m_properties.l, 1.0f, 0, 1); - builder.append(' '); - serialize_color_component(builder, mode, m_properties.c, 0.4f, 0); - builder.append(' '); - serialize_hue_component(builder, mode, m_properties.h); - if ((!m_properties.alpha->is_number() || m_properties.alpha->as_number().number() < 1) - && (!m_properties.alpha->is_percentage() || m_properties.alpha->as_percentage().percentage().as_fraction() < 1)) { - builder.append(" / "sv); - serialize_alpha_component(builder, mode, m_properties.alpha); - } - - builder.append(')'); -} - -} diff --git a/Libraries/LibWeb/CSS/StyleValues/LCHLikeColorStyleValue.h b/Libraries/LibWeb/CSS/StyleValues/LCHLikeColorStyleValue.h deleted file mode 100644 index 8708f3bd1d3..00000000000 --- a/Libraries/LibWeb/CSS/StyleValues/LCHLikeColorStyleValue.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2024-2026, Sam Atkins - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include -#include -#include - -namespace Web::CSS { - -class LCHLikeColorStyleValue : public ColorStyleValue { -public: - template T> - static ValueComparingNonnullRefPtr create(ValueComparingNonnullRefPtr l, ValueComparingNonnullRefPtr c, ValueComparingNonnullRefPtr h, ValueComparingRefPtr alpha = {}) - { - // alpha defaults to 1 - if (!alpha) - alpha = NumberStyleValue::create(1); - - return adopt_ref(*new (nothrow) T({}, move(l), move(c), move(h), alpha.release_nonnull())); - } - virtual ~LCHLikeColorStyleValue() override = default; - - StyleValue const& l() const { return *m_properties.l; } - StyleValue const& c() const { return *m_properties.c; } - StyleValue const& h() const { return *m_properties.h; } - StyleValue const& alpha() const { return *m_properties.alpha; } - - virtual bool equals(StyleValue const& other) const override; - - virtual bool is_computationally_independent() const override - { - return m_properties.l->is_computationally_independent() - && m_properties.c->is_computationally_independent() - && m_properties.h->is_computationally_independent() - && m_properties.alpha->is_computationally_independent(); - } - -protected: - LCHLikeColorStyleValue(ColorType color_type, ValueComparingNonnullRefPtr l, ValueComparingNonnullRefPtr c, ValueComparingNonnullRefPtr h, ValueComparingNonnullRefPtr alpha) - : ColorStyleValue(color_type, ColorSyntax::Modern) - , m_properties { .l = move(l), .c = move(c), .h = move(h), .alpha = move(alpha) } - { - } - - struct Properties { - ValueComparingNonnullRefPtr l; - ValueComparingNonnullRefPtr c; - ValueComparingNonnullRefPtr h; - ValueComparingNonnullRefPtr alpha; - bool operator==(Properties const&) const = default; - } m_properties; -}; - -class LCHColorStyleValue final : public LCHLikeColorStyleValue { -public: - LCHColorStyleValue(Badge, ValueComparingNonnullRefPtr l, ValueComparingNonnullRefPtr c, ValueComparingNonnullRefPtr h, ValueComparingNonnullRefPtr alpha) - : LCHLikeColorStyleValue(ColorType::LCH, move(l), move(c), move(h), move(alpha)) - { - } - virtual ~LCHColorStyleValue() override = default; - - virtual Optional to_color(ColorResolutionContext) const override; - virtual ValueComparingNonnullRefPtr absolutized(ComputationContext const&) const override; - - virtual void serialize(StringBuilder&, SerializationMode) const override; -}; - -class OKLCHColorStyleValue final : public LCHLikeColorStyleValue { -public: - OKLCHColorStyleValue(Badge, ValueComparingNonnullRefPtr l, ValueComparingNonnullRefPtr c, ValueComparingNonnullRefPtr h, ValueComparingNonnullRefPtr alpha) - : LCHLikeColorStyleValue(ColorType::OKLCH, move(l), move(c), move(h), move(alpha)) - { - } - virtual ~OKLCHColorStyleValue() override = default; - - virtual Optional to_color(ColorResolutionContext) const override; - virtual ValueComparingNonnullRefPtr absolutized(ComputationContext const&) const override; - - virtual void serialize(StringBuilder&, SerializationMode) const override; -}; - -} diff --git a/Libraries/LibWeb/Forward.h b/Libraries/LibWeb/Forward.h index 86bed9c759d..95eb5eea386 100644 --- a/Libraries/LibWeb/Forward.h +++ b/Libraries/LibWeb/Forward.h @@ -362,7 +362,6 @@ class MediaQueryListEvent; class Number; class NumberStyleValue; class NumericType; -class OKLCHColorStyleValue; class OpenTypeTaggedStyleValue; class ParsedFontFace; class PendingSubstitutionStyleValue;