diff --git a/Tests/LibWeb/Text/expected/canvas/pattern-from-video.txt b/Tests/LibWeb/Text/expected/canvas/pattern-from-video.txt new file mode 100644 index 00000000000000..9f21df3f30f5c7 --- /dev/null +++ b/Tests/LibWeb/Text/expected/canvas/pattern-from-video.txt @@ -0,0 +1,2 @@ +null +PASS (didn't throw!) diff --git a/Tests/LibWeb/Text/input/canvas/pattern-from-video.html b/Tests/LibWeb/Text/input/canvas/pattern-from-video.html new file mode 100644 index 00000000000000..68118f3144b97a --- /dev/null +++ b/Tests/LibWeb/Text/input/canvas/pattern-from-video.html @@ -0,0 +1,10 @@ + + diff --git a/Userland/Libraries/LibWeb/HTML/Canvas/CanvasDrawImage.cpp b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasDrawImage.cpp index 3c93d18c52ea17..7cb01326bca8a7 100644 --- a/Userland/Libraries/LibWeb/HTML/Canvas/CanvasDrawImage.cpp +++ b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasDrawImage.cpp @@ -23,6 +23,15 @@ static void default_source_size(CanvasImageSource const& image, float& source_wi source_height = source->height()->anim_val()->value(); } }, + [&source_width, &source_height](JS::Handle const& source) { + if (auto const bitmap = source->bitmap(); bitmap) { + source_width = bitmap->width(); + source_height = bitmap->height(); + } else { + source_width = source->video_width(); + source_height = source->video_height(); + } + }, [&source_width, &source_height](auto const& source) { if (source->bitmap()) { source_width = source->bitmap()->width(); diff --git a/Userland/Libraries/LibWeb/HTML/Canvas/CanvasDrawImage.h b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasDrawImage.h index cfe4aa0c315d01..d1b90186f92d2f 100644 --- a/Userland/Libraries/LibWeb/HTML/Canvas/CanvasDrawImage.h +++ b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasDrawImage.h @@ -9,13 +9,14 @@ #include #include #include +#include #include namespace Web::HTML { // https://html.spec.whatwg.org/multipage/canvas.html#canvasimagesource // NOTE: This is the Variant created by the IDL wrapper generator, and needs to be updated accordingly. -using CanvasImageSource = Variant, JS::Handle, JS::Handle, JS::Handle>; +using CanvasImageSource = Variant, JS::Handle, JS::Handle, JS::Handle, JS::Handle>; // https://html.spec.whatwg.org/multipage/canvas.html#canvasdrawimage class CanvasDrawImage { diff --git a/Userland/Libraries/LibWeb/HTML/Canvas/CanvasDrawImage.idl b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasDrawImage.idl index f3da18fef4f916..df5c3ac36fe87a 100644 --- a/Userland/Libraries/LibWeb/HTML/Canvas/CanvasDrawImage.idl +++ b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasDrawImage.idl @@ -1,12 +1,13 @@ #import #import +#import #import #import typedef (HTMLImageElement or SVGImageElement or // FIXME: We should use HTMLOrSVGImageElement instead of HTMLImageElement -// FIXME: HTMLVideoElement or + HTMLVideoElement or HTMLCanvasElement or ImageBitmap // FIXME: OffscreenCanvas diff --git a/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp b/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp index 6301144e3b8a44..66d7d5b7b85c33 100644 --- a/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp +++ b/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp @@ -675,8 +675,13 @@ WebIDL::ExceptionOr check_usability_of_image(CanvasI return Optional {}; }, - // FIXME: HTMLVideoElement - // If image's readyState attribute is either HAVE_NOTHING or HAVE_METADATA, then return bad. + [](JS::Handle const& video_element) -> WebIDL::ExceptionOr> { + // If image's readyState attribute is either HAVE_NOTHING or HAVE_METADATA, then return bad. + if (video_element->ready_state() == HTML::HTMLMediaElement::ReadyState::HaveNothing || video_element->ready_state() == HTML::HTMLMediaElement::ReadyState::HaveMetadata) { + return { CanvasImageSourceUsability::Bad }; + } + return Optional {}; + }, // HTMLCanvasElement // FIXME: OffscreenCanvas @@ -715,10 +720,10 @@ bool image_is_not_origin_clean(CanvasImageSource const& image) // FIXME: image's current request's image data is CORS-cross-origin. return false; }, - - // FIXME: HTMLVideoElement - // image's media data is CORS-cross-origin. - + [](JS::Handle const&) { + // FIXME: image's media data is CORS-cross-origin. + return false; + }, // HTMLCanvasElement [](OneOf, JS::Handle> auto const&) { // FIXME: image's bitmap's origin-clean flag is false. diff --git a/Userland/Libraries/LibWeb/HTML/HTMLVideoElement.h b/Userland/Libraries/LibWeb/HTML/HTMLVideoElement.h index f6d1ac9d42b4b4..a5b8582077d97c 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLVideoElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLVideoElement.h @@ -42,6 +42,12 @@ class HTMLVideoElement final : public HTMLMediaElement { VideoFrame const& current_frame() const { return m_current_frame; } RefPtr const& poster_frame() const { return m_poster_frame; } + // FIXME: This is a hack for images used as CanvasImageSource. Do something more elegant. + RefPtr bitmap() const + { + return current_frame().frame; + } + private: HTMLVideoElement(DOM::Document&, DOM::QualifiedName);