From 5f17d9b34a627409b03758c11f743dab9d76ffc9 Mon Sep 17 00:00:00 2001 From: MacDue Date: Sat, 25 May 2024 23:06:47 +0100 Subject: [PATCH] LibWeb: Add `BasicShapeStyleValue` to represent CSS basic shapes See: https://www.w3.org/TR/css-shapes-1/#basic-shape-functions This patch only implements the `polygon()` basic shape (with the rest left as FIXMEs). --- Userland/Libraries/LibWeb/CMakeLists.txt | 1 + Userland/Libraries/LibWeb/CSS/StyleValue.cpp | 1 + Userland/Libraries/LibWeb/CSS/StyleValue.h | 1 + .../CSS/StyleValues/BasicShapeStyleValue.cpp | 61 +++++++++++++++++++ .../CSS/StyleValues/BasicShapeStyleValue.h | 61 +++++++++++++++++++ Userland/Libraries/LibWeb/Forward.h | 1 + 6 files changed, 126 insertions(+) create mode 100644 Userland/Libraries/LibWeb/CSS/StyleValues/BasicShapeStyleValue.cpp create mode 100644 Userland/Libraries/LibWeb/CSS/StyleValues/BasicShapeStyleValue.h diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index a35bf2a5817..0a7db6362bb 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -102,6 +102,7 @@ set(SOURCES CSS/StyleValues/AngleStyleValue.cpp CSS/StyleValues/BackgroundRepeatStyleValue.cpp CSS/StyleValues/BackgroundSizeStyleValue.cpp + CSS/StyleValues/BasicShapeStyleValue.cpp CSS/StyleValues/BorderRadiusStyleValue.cpp CSS/StyleValues/CalculatedStyleValue.cpp CSS/StyleValues/ColorStyleValue.cpp diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp index e70338ed97e..70c293f99c3 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValue.h index a5421aaaa6c..04f84900781 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.h +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.h @@ -86,6 +86,7 @@ using StyleValueVector = Vector>; __ENUMERATE_STYLE_VALUE_TYPE(Angle, angle) \ __ENUMERATE_STYLE_VALUE_TYPE(BackgroundRepeat, background_repeat) \ __ENUMERATE_STYLE_VALUE_TYPE(BackgroundSize, background_size) \ + __ENUMERATE_STYLE_VALUE_TYPE(BasicShape, basic_shape) \ __ENUMERATE_STYLE_VALUE_TYPE(BorderRadius, border_radius) \ __ENUMERATE_STYLE_VALUE_TYPE(Calculated, calculated) \ __ENUMERATE_STYLE_VALUE_TYPE(Color, color) \ diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/BasicShapeStyleValue.cpp b/Userland/Libraries/LibWeb/CSS/StyleValues/BasicShapeStyleValue.cpp new file mode 100644 index 00000000000..00fdaad2bf2 --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/StyleValues/BasicShapeStyleValue.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2024, MacDue + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "BasicShapeStyleValue.h" + +namespace Web::CSS { + +Gfx::Path Polygon::to_path(CSSPixelRect reference_box, Layout::Node const& node) const +{ + Gfx::Path path; + bool first = true; + for (auto const& point : points) { + Gfx::FloatPoint resolved_point { + static_cast(point.x.to_px(node, reference_box.width())), + static_cast(point.y.to_px(node, reference_box.height())) + }; + if (first) + path.move_to(resolved_point); + else + path.line_to(resolved_point); + first = false; + } + path.close(); + return path; +} + +String Polygon::to_string() const +{ + StringBuilder builder; + builder.append("polygon("sv); + bool first = true; + for (auto const& point : points) { + if (!first) + builder.append(','); + builder.appendff("{} {}", point.x, point.y); + first = false; + } + builder.append(')'); + return MUST(builder.to_string()); +} + +BasicShapeStyleValue::~BasicShapeStyleValue() = default; + +Gfx::Path BasicShapeStyleValue::to_path(CSSPixelRect reference_box, Layout::Node const& node) const +{ + return m_basic_shape.visit([&](auto const& shape) { + return shape.to_path(reference_box, node); + }); +} + +String BasicShapeStyleValue::to_string() const +{ + return m_basic_shape.visit([](auto const& shape) { + return shape.to_string(); + }); +} + +} diff --git a/Userland/Libraries/LibWeb/CSS/StyleValues/BasicShapeStyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValues/BasicShapeStyleValue.h new file mode 100644 index 00000000000..45f45fb3505 --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/StyleValues/BasicShapeStyleValue.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2024, MacDue + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include + +namespace Web::CSS { + +struct Polygon { + struct Point { + bool operator==(Point const&) const = default; + LengthPercentage x; + LengthPercentage y; + }; + + Gfx::Path to_path(CSSPixelRect reference_box, Layout::Node const&) const; + String to_string() const; + + bool operator==(Polygon const&) const = default; + + FillRule fill_rule; + Vector points; +}; + +// FIXME: Implement other basic shapes. See: https://www.w3.org/TR/css-shapes-1/#basic-shape-functions +using BasicShape = Variant; + +class BasicShapeStyleValue : public StyleValueWithDefaultOperators { +public: + static ValueComparingNonnullRefPtr create(BasicShape basic_shape) + { + return adopt_ref(*new (nothrow) BasicShapeStyleValue(move(basic_shape))); + } + virtual ~BasicShapeStyleValue() override; + + BasicShape const& basic_shape() const { return m_basic_shape; } + + virtual String to_string() const override; + + bool properties_equal(BasicShapeStyleValue const& other) const { return m_basic_shape == other.m_basic_shape; } + + Gfx::Path to_path(CSSPixelRect reference_box, Layout::Node const&) const; + +private: + BasicShapeStyleValue(BasicShape basic_shape) + : StyleValueWithDefaultOperators(Type::BasicShape) + , m_basic_shape(move(basic_shape)) + { + } + + BasicShape m_basic_shape; +}; + +} diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index 1ae286d9c5f..732e427816b 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -92,6 +92,7 @@ class AnglePercentage; class AngleStyleValue; class BackgroundRepeatStyleValue; class BackgroundSizeStyleValue; +class BasicShapeStyleValue; class BorderRadiusStyleValue; class CSSAnimation; class CSSConditionRule;