summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Userland/Libraries/LibWeb/CMakeLists.txt1
-rw-r--r--Userland/Libraries/LibWeb/CSS/BackdropFilter.h1
-rw-r--r--Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp1
-rw-r--r--Userland/Libraries/LibWeb/CSS/StyleComputer.cpp1
-rw-r--r--Userland/Libraries/LibWeb/CSS/StyleValue.cpp112
-rw-r--r--Userland/Libraries/LibWeb/CSS/StyleValue.h80
-rw-r--r--Userland/Libraries/LibWeb/CSS/StyleValues/FilterValueListStyleValue.cpp127
-rw-r--r--Userland/Libraries/LibWeb/CSS/StyleValues/FilterValueListStyleValue.h100
8 files changed, 232 insertions, 191 deletions
diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt
index 1d35524eb9..450c8b59ac 100644
--- a/Userland/Libraries/LibWeb/CMakeLists.txt
+++ b/Userland/Libraries/LibWeb/CMakeLists.txt
@@ -73,6 +73,7 @@ set(SOURCES
CSS/StyleValues/BorderStyleValue.cpp
CSS/StyleValues/ColorStyleValue.cpp
CSS/StyleValues/ContentStyleValue.cpp
+ CSS/StyleValues/FilterValueListStyleValue.cpp
CSS/Supports.cpp
CSS/SyntaxHighlighter/SyntaxHighlighter.cpp
CSS/Time.cpp
diff --git a/Userland/Libraries/LibWeb/CSS/BackdropFilter.h b/Userland/Libraries/LibWeb/CSS/BackdropFilter.h
index bdceb36ee1..5dd1e5be8d 100644
--- a/Userland/Libraries/LibWeb/CSS/BackdropFilter.h
+++ b/Userland/Libraries/LibWeb/CSS/BackdropFilter.h
@@ -8,6 +8,7 @@
#include <AK/Variant.h>
#include <LibWeb/CSS/StyleValue.h>
+#include <LibWeb/CSS/StyleValues/FilterValueListStyleValue.h>
namespace Web::CSS {
diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
index 84b48ed75b..1a2883164a 100644
--- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
+++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
@@ -38,6 +38,7 @@
#include <LibWeb/CSS/StyleValues/BorderStyleValue.h>
#include <LibWeb/CSS/StyleValues/ColorStyleValue.h>
#include <LibWeb/CSS/StyleValues/ContentStyleValue.h>
+#include <LibWeb/CSS/StyleValues/FilterValueListStyleValue.h>
#include <LibWeb/DOM/Document.h>
#include <LibWeb/Dump.h>
#include <LibWeb/Infra/Strings.h>
diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp
index c04837ee15..61d8a4b754 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp
+++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp
@@ -30,6 +30,7 @@
#include <LibWeb/CSS/StyleValues/BorderRadiusStyleValue.h>
#include <LibWeb/CSS/StyleValues/BorderStyleValue.h>
#include <LibWeb/CSS/StyleValues/ColorStyleValue.h>
+#include <LibWeb/CSS/StyleValues/FilterValueListStyleValue.h>
#include <LibWeb/DOM/Document.h>
#include <LibWeb/DOM/Element.h>
#include <LibWeb/FontCache.h>
diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp
index 0e9bca9cb5..f13b0db3a2 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp
+++ b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp
@@ -20,6 +20,7 @@
#include <LibWeb/CSS/StyleValues/BorderStyleValue.h>
#include <LibWeb/CSS/StyleValues/ColorStyleValue.h>
#include <LibWeb/CSS/StyleValues/ContentStyleValue.h>
+#include <LibWeb/CSS/StyleValues/FilterValueListStyleValue.h>
#include <LibWeb/DOM/Document.h>
#include <LibWeb/HTML/BrowsingContext.h>
#include <LibWeb/Loader/LoadRequest.h>
@@ -1022,117 +1023,6 @@ CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalcNumberSumPartW
return value->resolve(layout_node, percentage_basis);
}
-float Filter::Blur::resolved_radius(Layout::Node const& node) const
-{
- // Default value when omitted is 0px.
- auto sigma = 0;
- if (radius.has_value())
- sigma = radius->resolved(node).to_px(node).value();
- // Note: The radius/sigma of the blur needs to be doubled for LibGfx's blur functions.
- return sigma * 2;
-}
-
-Filter::DropShadow::Resolved Filter::DropShadow::resolved(Layout::Node const& node) const
-{
- // The default value for omitted values is missing length values set to 0
- // and the missing used color is taken from the color property.
- return Resolved {
- offset_x.resolved(node).to_px(node).value(),
- offset_y.resolved(node).to_px(node).value(),
- radius.has_value() ? radius->resolved(node).to_px(node).value() : 0.0f,
- color.has_value() ? *color : node.computed_values().color()
- };
-}
-
-float Filter::HueRotate::angle_degrees() const
-{
- // Default value when omitted is 0deg.
- if (!angle.has_value())
- return 0.0f;
- return angle->visit([&](Angle const& angle) { return angle.to_degrees(); }, [&](auto) { return 0.0f; });
-}
-
-float Filter::Color::resolved_amount() const
-{
- if (amount.has_value()) {
- if (amount->is_percentage())
- return amount->percentage().as_fraction();
- return amount->number().value();
- }
- // All color filters (brightness, sepia, etc) have a default amount of 1.
- return 1.0f;
-}
-
-ErrorOr<String> FilterValueListStyleValue::to_string() const
-{
- StringBuilder builder {};
- bool first = true;
- for (auto& filter_function : filter_value_list()) {
- if (!first)
- TRY(builder.try_append(' '));
- TRY(filter_function.visit(
- [&](Filter::Blur const& blur) -> ErrorOr<void> {
- TRY(builder.try_append("blur("sv));
- if (blur.radius.has_value())
- TRY(builder.try_append(TRY(blur.radius->to_string())));
- return {};
- },
- [&](Filter::DropShadow const& drop_shadow) -> ErrorOr<void> {
- TRY(builder.try_appendff("drop-shadow({} {}"sv,
- drop_shadow.offset_x, drop_shadow.offset_y));
- if (drop_shadow.radius.has_value())
- TRY(builder.try_appendff(" {}", TRY(drop_shadow.radius->to_string())));
- if (drop_shadow.color.has_value()) {
- TRY(builder.try_append(' '));
- TRY(serialize_a_srgb_value(builder, *drop_shadow.color));
- }
- return {};
- },
- [&](Filter::HueRotate const& hue_rotate) -> ErrorOr<void> {
- TRY(builder.try_append("hue-rotate("sv));
- if (hue_rotate.angle.has_value()) {
- TRY(hue_rotate.angle->visit(
- [&](Angle const& angle) -> ErrorOr<void> {
- return builder.try_append(TRY(angle.to_string()));
- },
- [&](auto&) -> ErrorOr<void> {
- return builder.try_append('0');
- }));
- }
- return {};
- },
- [&](Filter::Color const& color) -> ErrorOr<void> {
- TRY(builder.try_appendff("{}(",
- [&] {
- switch (color.operation) {
- case Filter::Color::Operation::Brightness:
- return "brightness"sv;
- case Filter::Color::Operation::Contrast:
- return "contrast"sv;
- case Filter::Color::Operation::Grayscale:
- return "grayscale"sv;
- case Filter::Color::Operation::Invert:
- return "invert"sv;
- case Filter::Color::Operation::Opacity:
- return "opacity"sv;
- case Filter::Color::Operation::Saturate:
- return "saturate"sv;
- case Filter::Color::Operation::Sepia:
- return "sepia"sv;
- default:
- VERIFY_NOT_REACHED();
- }
- }()));
- if (color.amount.has_value())
- TRY(builder.try_append(TRY(color.amount->to_string())));
- return {};
- }));
- TRY(builder.try_append(')'));
- first = false;
- }
- return builder.to_string();
-}
-
ErrorOr<String> FlexStyleValue::to_string() const
{
return String::formatted("{} {} {}", TRY(m_properties.grow->to_string()), TRY(m_properties.shrink->to_string()), TRY(m_properties.basis->to_string()));
diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValue.h
index 0719cc91a5..1a40817745 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleValue.h
+++ b/Userland/Libraries/LibWeb/CSS/StyleValue.h
@@ -145,58 +145,6 @@ struct EdgeRect {
bool operator==(EdgeRect const&) const = default;
};
-namespace Filter {
-
-struct Blur {
- Optional<Length> radius {};
- float resolved_radius(Layout::Node const&) const;
- bool operator==(Blur const&) const = default;
-};
-
-struct DropShadow {
- Length offset_x;
- Length offset_y;
- Optional<Length> radius {};
- Optional<Color> color {};
- struct Resolved {
- float offset_x;
- float offset_y;
- float radius;
- Color color;
- };
- Resolved resolved(Layout::Node const&) const;
- bool operator==(DropShadow const&) const = default;
-};
-
-struct HueRotate {
- struct Zero {
- bool operator==(Zero const&) const = default;
- };
- using AngleOrZero = Variant<Angle, Zero>;
- Optional<AngleOrZero> angle {};
- float angle_degrees() const;
- bool operator==(HueRotate const&) const = default;
-};
-
-struct Color {
- enum class Operation {
- Brightness,
- Contrast,
- Grayscale,
- Invert,
- Opacity,
- Saturate,
- Sepia
- } operation;
- Optional<NumberPercentage> amount {};
- float resolved_amount() const;
- bool operator==(Color const&) const = default;
-};
-
-};
-
-using FilterFunction = Variant<Filter::Blur, Filter::DropShadow, Filter::HueRotate, Filter::Color>;
-
// FIXME: Find a better place for this helper.
inline Gfx::Painter::ScalingMode to_gfx_scaling_mode(CSS::ImageRendering css_value)
{
@@ -713,34 +661,6 @@ private:
NonnullOwnPtr<CalcSum> m_expression;
};
-class FilterValueListStyleValue final : public StyleValueWithDefaultOperators<FilterValueListStyleValue> {
-public:
- static ValueComparingNonnullRefPtr<FilterValueListStyleValue> create(
- Vector<FilterFunction> filter_value_list)
- {
- VERIFY(filter_value_list.size() >= 1);
- return adopt_ref(*new FilterValueListStyleValue(move(filter_value_list)));
- }
-
- Vector<FilterFunction> const& filter_value_list() const { return m_filter_value_list; }
-
- virtual ErrorOr<String> to_string() const override;
-
- virtual ~FilterValueListStyleValue() override = default;
-
- bool properties_equal(FilterValueListStyleValue const& other) const { return m_filter_value_list == other.m_filter_value_list; };
-
-private:
- FilterValueListStyleValue(Vector<FilterFunction> filter_value_list)
- : StyleValueWithDefaultOperators(Type::FilterValueList)
- , m_filter_value_list(move(filter_value_list))
- {
- }
-
- // FIXME: No support for SVG filters yet
- Vector<FilterFunction> m_filter_value_list;
-};
-
class FlexStyleValue final : public StyleValueWithDefaultOperators<FlexStyleValue> {
public:
static ValueComparingNonnullRefPtr<FlexStyleValue> create(
diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/FilterValueListStyleValue.cpp b/Userland/Libraries/LibWeb/CSS/StyleValues/FilterValueListStyleValue.cpp
new file mode 100644
index 0000000000..a106fd1001
--- /dev/null
+++ b/Userland/Libraries/LibWeb/CSS/StyleValues/FilterValueListStyleValue.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org>
+ * Copyright (c) 2021-2023, Sam Atkins <atkinssj@serenityos.org>
+ * Copyright (c) 2022-2023, MacDue <macdue@dueutil.tech>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include "FilterValueListStyleValue.h"
+#include <LibWeb/CSS/Serialize.h>
+#include <LibWeb/Layout/Node.h>
+
+namespace Web::CSS {
+
+float Filter::Blur::resolved_radius(Layout::Node const& node) const
+{
+ // Default value when omitted is 0px.
+ auto sigma = 0;
+ if (radius.has_value())
+ sigma = radius->resolved(node).to_px(node).value();
+ // Note: The radius/sigma of the blur needs to be doubled for LibGfx's blur functions.
+ return sigma * 2;
+}
+
+Filter::DropShadow::Resolved Filter::DropShadow::resolved(Layout::Node const& node) const
+{
+ // The default value for omitted values is missing length values set to 0
+ // and the missing used color is taken from the color property.
+ return Resolved {
+ offset_x.resolved(node).to_px(node).value(),
+ offset_y.resolved(node).to_px(node).value(),
+ radius.has_value() ? radius->resolved(node).to_px(node).value() : 0.0f,
+ color.has_value() ? *color : node.computed_values().color()
+ };
+}
+
+float Filter::HueRotate::angle_degrees() const
+{
+ // Default value when omitted is 0deg.
+ if (!angle.has_value())
+ return 0.0f;
+ return angle->visit([&](Angle const& a) { return a.to_degrees(); }, [&](auto) { return 0.0f; });
+}
+
+float Filter::Color::resolved_amount() const
+{
+ if (amount.has_value()) {
+ if (amount->is_percentage())
+ return amount->percentage().as_fraction();
+ return amount->number().value();
+ }
+ // All color filters (brightness, sepia, etc) have a default amount of 1.
+ return 1.0f;
+}
+
+ErrorOr<String> FilterValueListStyleValue::to_string() const
+{
+ StringBuilder builder {};
+ bool first = true;
+ for (auto& filter_function : filter_value_list()) {
+ if (!first)
+ TRY(builder.try_append(' '));
+ TRY(filter_function.visit(
+ [&](Filter::Blur const& blur) -> ErrorOr<void> {
+ TRY(builder.try_append("blur("sv));
+ if (blur.radius.has_value())
+ TRY(builder.try_append(TRY(blur.radius->to_string())));
+ return {};
+ },
+ [&](Filter::DropShadow const& drop_shadow) -> ErrorOr<void> {
+ TRY(builder.try_appendff("drop-shadow({} {}"sv,
+ drop_shadow.offset_x, drop_shadow.offset_y));
+ if (drop_shadow.radius.has_value())
+ TRY(builder.try_appendff(" {}", TRY(drop_shadow.radius->to_string())));
+ if (drop_shadow.color.has_value()) {
+ TRY(builder.try_append(' '));
+ TRY(serialize_a_srgb_value(builder, *drop_shadow.color));
+ }
+ return {};
+ },
+ [&](Filter::HueRotate const& hue_rotate) -> ErrorOr<void> {
+ TRY(builder.try_append("hue-rotate("sv));
+ if (hue_rotate.angle.has_value()) {
+ TRY(hue_rotate.angle->visit(
+ [&](Angle const& angle) -> ErrorOr<void> {
+ return builder.try_append(TRY(angle.to_string()));
+ },
+ [&](auto&) -> ErrorOr<void> {
+ return builder.try_append('0');
+ }));
+ }
+ return {};
+ },
+ [&](Filter::Color const& color) -> ErrorOr<void> {
+ TRY(builder.try_appendff("{}(",
+ [&] {
+ switch (color.operation) {
+ case Filter::Color::Operation::Brightness:
+ return "brightness"sv;
+ case Filter::Color::Operation::Contrast:
+ return "contrast"sv;
+ case Filter::Color::Operation::Grayscale:
+ return "grayscale"sv;
+ case Filter::Color::Operation::Invert:
+ return "invert"sv;
+ case Filter::Color::Operation::Opacity:
+ return "opacity"sv;
+ case Filter::Color::Operation::Saturate:
+ return "saturate"sv;
+ case Filter::Color::Operation::Sepia:
+ return "sepia"sv;
+ default:
+ VERIFY_NOT_REACHED();
+ }
+ }()));
+ if (color.amount.has_value())
+ TRY(builder.try_append(TRY(color.amount->to_string())));
+ return {};
+ }));
+ TRY(builder.try_append(')'));
+ first = false;
+ }
+ return builder.to_string();
+}
+
+}
diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/FilterValueListStyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValues/FilterValueListStyleValue.h
new file mode 100644
index 0000000000..2275d04dcc
--- /dev/null
+++ b/Userland/Libraries/LibWeb/CSS/StyleValues/FilterValueListStyleValue.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org>
+ * Copyright (c) 2021-2023, Sam Atkins <atkinssj@serenityos.org>
+ * Copyright (c) 2022-2023, MacDue <macdue@dueutil.tech>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <LibWeb/CSS/Angle.h>
+#include <LibWeb/CSS/Length.h>
+#include <LibWeb/CSS/Number.h>
+#include <LibWeb/CSS/Percentage.h>
+#include <LibWeb/CSS/StyleValue.h>
+
+namespace Web::CSS {
+
+namespace Filter {
+
+struct Blur {
+ Optional<Length> radius {};
+ float resolved_radius(Layout::Node const&) const;
+ bool operator==(Blur const&) const = default;
+};
+
+struct DropShadow {
+ Length offset_x;
+ Length offset_y;
+ Optional<Length> radius {};
+ Optional<Color> color {};
+ struct Resolved {
+ float offset_x;
+ float offset_y;
+ float radius;
+ Color color;
+ };
+ Resolved resolved(Layout::Node const&) const;
+ bool operator==(DropShadow const&) const = default;
+};
+
+struct HueRotate {
+ struct Zero {
+ bool operator==(Zero const&) const = default;
+ };
+ using AngleOrZero = Variant<Angle, Zero>;
+ Optional<AngleOrZero> angle {};
+ float angle_degrees() const;
+ bool operator==(HueRotate const&) const = default;
+};
+
+struct Color {
+ enum class Operation {
+ Brightness,
+ Contrast,
+ Grayscale,
+ Invert,
+ Opacity,
+ Saturate,
+ Sepia
+ } operation;
+ Optional<NumberPercentage> amount {};
+ float resolved_amount() const;
+ bool operator==(Color const&) const = default;
+};
+
+};
+
+using FilterFunction = Variant<Filter::Blur, Filter::DropShadow, Filter::HueRotate, Filter::Color>;
+
+class FilterValueListStyleValue final : public StyleValueWithDefaultOperators<FilterValueListStyleValue> {
+public:
+ static ValueComparingNonnullRefPtr<FilterValueListStyleValue> create(
+ Vector<FilterFunction> filter_value_list)
+ {
+ VERIFY(filter_value_list.size() >= 1);
+ return adopt_ref(*new FilterValueListStyleValue(move(filter_value_list)));
+ }
+
+ Vector<FilterFunction> const& filter_value_list() const { return m_filter_value_list; }
+
+ virtual ErrorOr<String> to_string() const override;
+
+ virtual ~FilterValueListStyleValue() override = default;
+
+ bool properties_equal(FilterValueListStyleValue const& other) const { return m_filter_value_list == other.m_filter_value_list; };
+
+private:
+ FilterValueListStyleValue(Vector<FilterFunction> filter_value_list)
+ : StyleValueWithDefaultOperators(Type::FilterValueList)
+ , m_filter_value_list(move(filter_value_list))
+ {
+ }
+
+ // FIXME: No support for SVG filters yet
+ Vector<FilterFunction> m_filter_value_list;
+};
+
+}