diff --git a/Tests/LibWeb/Screenshot/clip-path-basic-shapes.html b/Tests/LibWeb/Screenshot/clip-path-basic-shapes.html
index 3aa88ff9475..b11829f6283 100644
--- a/Tests/LibWeb/Screenshot/clip-path-basic-shapes.html
+++ b/Tests/LibWeb/Screenshot/clip-path-basic-shapes.html
@@ -121,6 +121,9 @@
+
diff --git a/Tests/LibWeb/Screenshot/images/clip-path-basic-shapes-ref.png b/Tests/LibWeb/Screenshot/images/clip-path-basic-shapes-ref.png
index e8ec2cb0f86..8866642eedf 100644
Binary files a/Tests/LibWeb/Screenshot/images/clip-path-basic-shapes-ref.png and b/Tests/LibWeb/Screenshot/images/clip-path-basic-shapes-ref.png differ
diff --git a/Tests/LibWeb/Text/expected/css/calc-coverage.txt b/Tests/LibWeb/Text/expected/css/calc-coverage.txt
index 7917a439704..fc2f6a083a2 100644
--- a/Tests/LibWeb/Text/expected/css/calc-coverage.txt
+++ b/Tests/LibWeb/Text/expected/css/calc-coverage.txt
@@ -34,10 +34,10 @@ border-top-width: 'calc(2px)' -> 'calc(2px)'
border-top-width: 'calc(2px * var(--n))' -> 'calc(2px * 2)'
bottom: 'calc(2px)' -> 'calc(2px)'
bottom: 'calc(2px * var(--n))' -> 'calc(2px * 2)'
-clip-path: 'polygon(calc(0px) calc(2px), calc(2px) calc(0px), calc(2px) calc(2px))' -> 'polygon(calc(0px) calc(2px),calc(2px) calc(0px),calc(2px) calc(2px))'
-clip-path: 'polygon(calc(0px * var(--n)) calc(2px * var(--n)), calc(2px * var(--n)) calc(0px * var(--n)), calc(2px * var(--n)) calc(2px * var(--n)))' -> 'polygon(calc(0px * 2) calc(2px * 2),calc(2px * 2) calc(0px * 2),calc(2px * 2) calc(2px * 2))'
-clip-path: 'polygon(calc(0%) calc(2%), calc(2%) calc(0%), calc(2%) calc(2%))' -> 'polygon(calc(0%) calc(2%),calc(2%) calc(0%),calc(2%) calc(2%))'
-clip-path: 'polygon(calc(0% * var(--n)) calc(2% * var(--n)), calc(2% * var(--n)) calc(0% * var(--n)), calc(2% * var(--n)) calc(2% * var(--n)))' -> 'polygon(calc(0% * 2) calc(2% * 2),calc(2% * 2) calc(0% * 2),calc(2% * 2) calc(2% * 2))'
+clip-path: 'polygon(calc(0px) calc(2px), calc(2px) calc(0px), calc(2px) calc(2px))' -> 'polygon(nonzero, calc(0px) calc(2px), calc(2px) calc(0px), calc(2px) calc(2px))'
+clip-path: 'polygon(calc(0px * var(--n)) calc(2px * var(--n)), calc(2px * var(--n)) calc(0px * var(--n)), calc(2px * var(--n)) calc(2px * var(--n)))' -> 'polygon(nonzero, calc(0px * 2) calc(2px * 2), calc(2px * 2) calc(0px * 2), calc(2px * 2) calc(2px * 2))'
+clip-path: 'polygon(calc(0%) calc(2%), calc(2%) calc(0%), calc(2%) calc(2%))' -> 'polygon(nonzero, calc(0%) calc(2%), calc(2%) calc(0%), calc(2%) calc(2%))'
+clip-path: 'polygon(calc(0% * var(--n)) calc(2% * var(--n)), calc(2% * var(--n)) calc(0% * var(--n)), calc(2% * var(--n)) calc(2% * var(--n)))' -> 'polygon(nonzero, calc(0% * 2) calc(2% * 2), calc(2% * 2) calc(0% * 2), calc(2% * 2) calc(2% * 2))'
column-count: 'calc(2)' -> 'calc(2)'
column-count: 'calc(2 * var(--n))' -> '4'
column-gap: 'calc(2px)' -> 'calc(2px)'
diff --git a/Userland/Libraries/LibGfx/Path.h b/Userland/Libraries/LibGfx/Path.h
index c9fe6ee027b..4a1f21e5b66 100644
--- a/Userland/Libraries/LibGfx/Path.h
+++ b/Userland/Libraries/LibGfx/Path.h
@@ -39,6 +39,7 @@ public:
[[nodiscard]] virtual bool is_empty() const = 0;
virtual Gfx::FloatPoint last_point() const = 0;
virtual Gfx::FloatRect bounding_box() const = 0;
+ virtual void set_fill_type(Gfx::WindingRule winding_rule) = 0;
virtual bool contains(FloatPoint point, Gfx::WindingRule) const = 0;
virtual NonnullOwnPtr clone() const = 0;
@@ -86,6 +87,7 @@ public:
Gfx::FloatPoint last_point() const { return impl().last_point(); }
Gfx::FloatRect bounding_box() const { return impl().bounding_box(); }
bool contains(FloatPoint point, Gfx::WindingRule winding_rule) const { return impl().contains(point, winding_rule); }
+ void set_fill_type(Gfx::WindingRule winding_rule) { impl().set_fill_type(winding_rule); }
Gfx::Path clone() const { return Gfx::Path { impl().clone() }; }
Gfx::Path copy_transformed(Gfx::AffineTransform const& transform) const { return Gfx::Path { impl().copy_transformed(transform) }; }
diff --git a/Userland/Libraries/LibGfx/PathSkia.cpp b/Userland/Libraries/LibGfx/PathSkia.cpp
index 94db9cdce1b..9d17952202c 100644
--- a/Userland/Libraries/LibGfx/PathSkia.cpp
+++ b/Userland/Libraries/LibGfx/PathSkia.cpp
@@ -29,6 +29,12 @@ PathImplSkia::PathImplSkia()
{
}
+PathImplSkia::PathImplSkia(PathImplSkia const& other)
+ : m_last_move_to(other.m_last_move_to)
+ , m_path(adopt_own(*new SkPath(other.sk_path())))
+{
+}
+
PathImplSkia::~PathImplSkia() = default;
void PathImplSkia::clear()
@@ -217,21 +223,24 @@ bool PathImplSkia::contains(FloatPoint point, Gfx::WindingRule winding_rule) con
return temp_path.contains(point.x(), point.y());
}
+void PathImplSkia::set_fill_type(Gfx::WindingRule winding_rule)
+{
+ m_path->setFillType(to_skia_path_fill_type(winding_rule));
+}
+
NonnullOwnPtr PathImplSkia::clone() const
{
- auto new_path = PathImplSkia::create();
- new_path->sk_path().addPath(*m_path);
- return new_path;
+ return adopt_own(*new PathImplSkia(*this));
}
NonnullOwnPtr PathImplSkia::copy_transformed(Gfx::AffineTransform const& transform) const
{
- auto new_path = PathImplSkia::create();
+ auto new_path = adopt_own(*new PathImplSkia(*this));
auto matrix = SkMatrix::MakeAll(
transform.a(), transform.c(), transform.e(),
transform.b(), transform.d(), transform.f(),
0, 0, 1);
- new_path->sk_path().addPath(*m_path, matrix);
+ new_path->sk_path().transform(matrix);
return new_path;
}
diff --git a/Userland/Libraries/LibGfx/PathSkia.h b/Userland/Libraries/LibGfx/PathSkia.h
index 6039281eab2..e968948e474 100644
--- a/Userland/Libraries/LibGfx/PathSkia.h
+++ b/Userland/Libraries/LibGfx/PathSkia.h
@@ -36,6 +36,7 @@ public:
virtual Gfx::FloatPoint last_point() const override;
virtual Gfx::FloatRect bounding_box() const override;
virtual bool contains(FloatPoint point, Gfx::WindingRule) const override;
+ virtual void set_fill_type(Gfx::WindingRule winding_rule) override;
virtual NonnullOwnPtr clone() const override;
virtual NonnullOwnPtr copy_transformed(Gfx::AffineTransform const&) const override;
@@ -46,6 +47,7 @@ public:
private:
PathImplSkia();
+ PathImplSkia(PathImplSkia const& other);
Gfx::FloatPoint m_last_move_to;
NonnullOwnPtr m_path;
diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
index 072497de9b0..b389d07e384 100644
--- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
+++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
@@ -1457,15 +1457,15 @@ RefPtr Parser::parse_basic_shape_value(TokenStream fill_rule;
+ Optional fill_rule;
auto first_argument = arguments[0];
TokenStream first_argument_tokens { first_argument };
first_argument_tokens.discard_whitespace();
if (first_argument_tokens.next_token().is_ident("nonzero"sv)) {
- fill_rule = FillRule::Nonzero;
+ fill_rule = Gfx::WindingRule::Nonzero;
} else if (first_argument_tokens.next_token().is_ident("evenodd"sv)) {
- fill_rule = FillRule::Evenodd;
+ fill_rule = Gfx::WindingRule::EvenOdd;
}
if (fill_rule.has_value()) {
@@ -1475,7 +1475,7 @@ RefPtr Parser::parse_basic_shape_value(TokenStream
+#include
#include
#include
#include
@@ -84,8 +85,7 @@ struct Polygon {
bool operator==(Polygon const&) const = default;
- // FIXME: Actually use the fill rule
- FillRule fill_rule;
+ Gfx::WindingRule fill_rule;
Vector points;
};