diff --git a/Libraries/LibWeb/HTML/CanvasPattern.cpp b/Libraries/LibWeb/HTML/CanvasPattern.cpp
index ea2e9967110a..e467d735033f 100644
--- a/Libraries/LibWeb/HTML/CanvasPattern.cpp
+++ b/Libraries/LibWeb/HTML/CanvasPattern.cpp
@@ -46,8 +46,17 @@ void CanvasPatternPaintStyle::paint(Gfx::IntRect physical_bounding_box, PaintFun
// 6. The resulting bitmap is what is to be rendered, with the same origin and same scale.
- auto const bitmap_width = m_immutable_bitmap->width();
- auto const bitmap_height = m_immutable_bitmap->height();
+ // FIXME: This doesn't handle a 'none' canvas context mode.
+ auto bitmap = m_image.visit(
+ [](GC::Root const& source) -> RefPtr { return source->immutable_bitmap(); },
+ [](GC::Root const& source) -> RefPtr { return source->current_image_bitmap(); },
+ [](GC::Root const& source) -> RefPtr { return Gfx::ImmutableBitmap::create_snapshot_from_painting_surface(*source->surface()); },
+ [](GC::Root const& source) -> RefPtr { return Gfx::ImmutableBitmap::create(*source->bitmap()); },
+ [](GC::Root const& source) -> RefPtr { return Gfx::ImmutableBitmap::create(*source->bitmap()); });
+ VERIFY(bitmap);
+
+ auto const bitmap_width = bitmap->width();
+ auto const bitmap_height = bitmap->height();
paint([=, this](auto point) {
point.translate_by(physical_bounding_box.location());
@@ -78,8 +87,8 @@ void CanvasPatternPaintStyle::paint(Gfx::IntRect physical_bounding_box, PaintFun
VERIFY_NOT_REACHED();
}
}();
- if (m_immutable_bitmap->rect().contains(point))
- return m_immutable_bitmap->get_pixel(point.x(), point.y());
+ if (bitmap->rect().contains(point))
+ return bitmap->get_pixel(point.x(), point.y());
return Gfx::Color();
});
}
@@ -127,16 +136,8 @@ WebIDL::ExceptionOr> CanvasPattern::create(JS::Realm& rea
if (!repetition_value.has_value())
return WebIDL::SyntaxError::create(realm, "Repetition value is not valid"_string);
- // Note: Bitmap won't be null here, as if it were it would have "bad" usability.
- auto bitmap = image.visit(
- [](GC::Root const& source) -> RefPtr { return source->immutable_bitmap(); },
- [](GC::Root const& source) -> RefPtr { return source->current_image_bitmap(); },
- [](GC::Root const& source) -> RefPtr { return Gfx::ImmutableBitmap::create_snapshot_from_painting_surface(*source->surface()); },
- [](GC::Root const& source) -> RefPtr { return Gfx::ImmutableBitmap::create(*source->bitmap()); },
- [](GC::Root const& source) -> RefPtr { return Gfx::ImmutableBitmap::create(*source->bitmap()); });
-
// 6. Let pattern be a new CanvasPattern object with the image image and the repetition behavior given by repetition.
- auto pattern = TRY_OR_THROW_OOM(realm.vm(), CanvasPatternPaintStyle::create(*bitmap, *repetition_value));
+ auto pattern = TRY_OR_THROW_OOM(realm.vm(), CanvasPatternPaintStyle::create(image, *repetition_value));
// FIXME: 7. If image is not origin-clean, then mark pattern as not origin-clean.
diff --git a/Libraries/LibWeb/HTML/CanvasPattern.h b/Libraries/LibWeb/HTML/CanvasPattern.h
index bdba5dbf1aa6..4abf33b38716 100644
--- a/Libraries/LibWeb/HTML/CanvasPattern.h
+++ b/Libraries/LibWeb/HTML/CanvasPattern.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2023, MacDue
+ * Copyright (c) 2025, Shannon Booth
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@@ -21,21 +22,21 @@ class CanvasPatternPaintStyle final : public Gfx::PaintStyle {
NoRepeat
};
- static ErrorOr> create(Gfx::ImmutableBitmap const& bitmap, Repetition repetition)
+ static ErrorOr> create(CanvasImageSource image, Repetition repetition)
{
- return adopt_nonnull_ref_or_enomem(new (nothrow) CanvasPatternPaintStyle(bitmap, repetition));
+ return adopt_nonnull_ref_or_enomem(new (nothrow) CanvasPatternPaintStyle(move(image), repetition));
}
virtual void paint(Gfx::IntRect physical_bounding_box, PaintFunction paint) const override;
private:
- CanvasPatternPaintStyle(Gfx::ImmutableBitmap const& immutable_bitmap, Repetition repetition)
- : m_immutable_bitmap(immutable_bitmap)
+ CanvasPatternPaintStyle(CanvasImageSource image, Repetition repetition)
+ : m_image(move(image))
, m_repetition(repetition)
{
}
- NonnullRefPtr m_immutable_bitmap;
+ CanvasImageSource m_image;
Repetition m_repetition { Repetition::Repeat };
};
diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.nocontext.txt b/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.nocontext.txt
new file mode 100644
index 000000000000..e3b013323d26
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.nocontext.txt
@@ -0,0 +1,6 @@
+Harness status: OK
+
+Found 1 tests
+
+1 Fail
+Fail Canvas test: 2d.pattern.basic.nocontext
\ No newline at end of file
diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.null.txt b/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.null.txt
new file mode 100644
index 000000000000..20cf74aac354
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.null.txt
@@ -0,0 +1,6 @@
+Harness status: OK
+
+Found 1 tests
+
+1 Pass
+Pass Canvas test: 2d.pattern.repeat.null
\ No newline at end of file
diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.identity.txt b/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.identity.txt
new file mode 100644
index 000000000000..c81b34acf6cc
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.identity.txt
@@ -0,0 +1,6 @@
+Harness status: OK
+
+Found 1 tests
+
+1 Fail
+Fail Canvas test: 2d.pattern.transform.identity
\ No newline at end of file
diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.infinity.txt b/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.infinity.txt
new file mode 100644
index 000000000000..2e0b91016af6
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.infinity.txt
@@ -0,0 +1,6 @@
+Harness status: OK
+
+Found 1 tests
+
+1 Fail
+Fail Canvas test: 2d.pattern.transform.infinity
\ No newline at end of file
diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.invalid.txt b/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.invalid.txt
new file mode 100644
index 000000000000..7ba2c8dc74b4
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.invalid.txt
@@ -0,0 +1,6 @@
+Harness status: OK
+
+Found 1 tests
+
+1 Pass
+Pass Canvas test: 2d.pattern.transform.invalid
\ No newline at end of file
diff --git a/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.nocontext.html b/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.nocontext.html
new file mode 100644
index 000000000000..634fd95a4773
--- /dev/null
+++ b/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.basic.nocontext.html
@@ -0,0 +1,41 @@
+
+
+
+Canvas test: 2d.pattern.basic.nocontext
+
+
+
+
+
+
+2d.pattern.basic.nocontext
+
+
+
+Actual output:
+
+Expected output:
+
+
+
diff --git a/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.null.html b/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.null.html
new file mode 100644
index 000000000000..b7389c976811
--- /dev/null
+++ b/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.repeat.null.html
@@ -0,0 +1,27 @@
+
+
+
+Canvas test: 2d.pattern.repeat.null
+
+
+
+
+
+
+2d.pattern.repeat.null
+
+
+
+Actual output:
+
+
+
+
+
diff --git a/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.identity.html b/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.identity.html
new file mode 100644
index 000000000000..f1410a4b5ab6
--- /dev/null
+++ b/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.identity.html
@@ -0,0 +1,42 @@
+
+
+
+Canvas test: 2d.pattern.transform.identity
+
+
+
+
+
+
+2d.pattern.transform.identity
+
+
+
+Actual output:
+
+Expected output:
+
+
+
diff --git a/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.infinity.html b/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.infinity.html
new file mode 100644
index 000000000000..4d703c36243b
--- /dev/null
+++ b/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.infinity.html
@@ -0,0 +1,42 @@
+
+
+
+Canvas test: 2d.pattern.transform.infinity
+
+
+
+
+
+
+2d.pattern.transform.infinity
+
+
+
+Actual output:
+
+Expected output:
+
+
+
diff --git a/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.invalid.html b/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.invalid.html
new file mode 100644
index 000000000000..29d9f1f6265a
--- /dev/null
+++ b/Tests/LibWeb/Text/input/wpt-import/html/canvas/element/fill-and-stroke-styles/2d.pattern.transform.invalid.html
@@ -0,0 +1,31 @@
+
+
+
+Canvas test: 2d.pattern.transform.invalid
+
+
+
+
+
+
+2d.pattern.transform.invalid
+
+
+
+Actual output:
+
+
+
+
+