Skip to content

Commit

Permalink
LibWeb: Make HTMLVideoElement part of CanvasImageSource union
Browse files Browse the repository at this point in the history
(cherry picked from commit abe1172d7097ddae2aff2ddd839b96ed90ba7a13)
  • Loading branch information
Totto16 authored and nico committed Nov 17, 2024
1 parent abf9980 commit b388106
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 8 deletions.
2 changes: 2 additions & 0 deletions Tests/LibWeb/Text/expected/canvas/pattern-from-video.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
null
PASS (didn't throw!)
10 changes: 10 additions & 0 deletions Tests/LibWeb/Text/input/canvas/pattern-from-video.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<script src="../include.js"></script>
<script>
test(() => {
let canvas = document.createElement("canvas");
let ctx = canvas.getContext("2d");
let v = document.createElement("video");
println(ctx.createPattern(v, 'repeat'));
println("PASS (didn't throw!)");
});
</script>
9 changes: 9 additions & 0 deletions Userland/Libraries/LibWeb/HTML/Canvas/CanvasDrawImage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<HTML::HTMLVideoElement> 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();
Expand Down
3 changes: 2 additions & 1 deletion Userland/Libraries/LibWeb/HTML/Canvas/CanvasDrawImage.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@
#include <LibWeb/Forward.h>
#include <LibWeb/HTML/HTMLCanvasElement.h>
#include <LibWeb/HTML/HTMLImageElement.h>
#include <LibWeb/HTML/HTMLVideoElement.h>
#include <LibWeb/WebIDL/ExceptionOr.h>

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<HTMLImageElement>, JS::Handle<SVG::SVGImageElement>, JS::Handle<HTMLCanvasElement>, JS::Handle<ImageBitmap>>;
using CanvasImageSource = Variant<JS::Handle<HTMLImageElement>, JS::Handle<SVG::SVGImageElement>, JS::Handle<HTMLCanvasElement>, JS::Handle<ImageBitmap>, JS::Handle<HTMLVideoElement>>;

// https://html.spec.whatwg.org/multipage/canvas.html#canvasdrawimage
class CanvasDrawImage {
Expand Down
3 changes: 2 additions & 1 deletion Userland/Libraries/LibWeb/HTML/Canvas/CanvasDrawImage.idl
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
#import <HTML/HTMLCanvasElement.idl>
#import <HTML/HTMLImageElement.idl>
#import <HTML/HTMLVideoElement.idl>
#import <HTML/ImageBitmap.idl>
#import <SVG/SVGImageElement.idl>

typedef (HTMLImageElement or
SVGImageElement or
// FIXME: We should use HTMLOrSVGImageElement instead of HTMLImageElement
// FIXME: HTMLVideoElement or
HTMLVideoElement or
HTMLCanvasElement or
ImageBitmap
// FIXME: OffscreenCanvas
Expand Down
17 changes: 11 additions & 6 deletions Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -675,8 +675,13 @@ WebIDL::ExceptionOr<CanvasImageSourceUsability> check_usability_of_image(CanvasI
return Optional<CanvasImageSourceUsability> {};
},

// FIXME: HTMLVideoElement
// If image's readyState attribute is either HAVE_NOTHING or HAVE_METADATA, then return bad.
[](JS::Handle<HTML::HTMLVideoElement> const& video_element) -> WebIDL::ExceptionOr<Optional<CanvasImageSourceUsability>> {
// 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<CanvasImageSourceUsability> {};
},

// HTMLCanvasElement
// FIXME: OffscreenCanvas
Expand Down Expand Up @@ -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<HTML::HTMLVideoElement> const&) {
// FIXME: image's media data is CORS-cross-origin.
return false;
},
// HTMLCanvasElement
[](OneOf<JS::Handle<HTMLCanvasElement>, JS::Handle<ImageBitmap>> auto const&) {
// FIXME: image's bitmap's origin-clean flag is false.
Expand Down
6 changes: 6 additions & 0 deletions Userland/Libraries/LibWeb/HTML/HTMLVideoElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ class HTMLVideoElement final : public HTMLMediaElement {
VideoFrame const& current_frame() const { return m_current_frame; }
RefPtr<Gfx::Bitmap> const& poster_frame() const { return m_poster_frame; }

// FIXME: This is a hack for images used as CanvasImageSource. Do something more elegant.
RefPtr<Gfx::Bitmap> bitmap() const
{
return current_frame().frame;
}

private:
HTMLVideoElement(DOM::Document&, DOM::QualifiedName);

Expand Down

0 comments on commit b388106

Please sign in to comment.