mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-28 11:49:44 +00:00
LibWeb: Add OffscreenCanvas to IDL types
Add OffscreenCanvas to TexImageSource and CanvasImageSource. Implement all the necessary features to make it work in all cases where these types are used.
This commit is contained in:
parent
2ad3ce5d37
commit
f1a096d6e4
Notes:
github-actions[bot]
2025-06-30 15:47:37 +00:00
Author: https://github.com/Totto16
Commit: f1a096d6e4
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3788
Reviewed-by: https://github.com/ADKaster ✅
Reviewed-by: https://github.com/tcl3
8 changed files with 35 additions and 9 deletions
|
@ -42,6 +42,12 @@ static void default_source_size(CanvasImageSource const& image, float& source_wi
|
||||||
source_height = source->video_height();
|
source_height = source->video_height();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
[&source_width, &source_height](GC::Root<OffscreenCanvas> const& source) {
|
||||||
|
auto const bitmap = source->bitmap();
|
||||||
|
|
||||||
|
source_width = bitmap->width();
|
||||||
|
source_height = bitmap->height();
|
||||||
|
},
|
||||||
[&source_width, &source_height](GC::Root<HTMLCanvasElement> const& source) {
|
[&source_width, &source_height](GC::Root<HTMLCanvasElement> const& source) {
|
||||||
if (source->surface()) {
|
if (source->surface()) {
|
||||||
source_width = source->surface()->size().width();
|
source_width = source->surface()->size().width();
|
||||||
|
|
|
@ -10,13 +10,14 @@
|
||||||
#include <LibWeb/HTML/HTMLCanvasElement.h>
|
#include <LibWeb/HTML/HTMLCanvasElement.h>
|
||||||
#include <LibWeb/HTML/HTMLImageElement.h>
|
#include <LibWeb/HTML/HTMLImageElement.h>
|
||||||
#include <LibWeb/HTML/HTMLVideoElement.h>
|
#include <LibWeb/HTML/HTMLVideoElement.h>
|
||||||
|
#include <LibWeb/HTML/OffscreenCanvas.h>
|
||||||
#include <LibWeb/WebIDL/ExceptionOr.h>
|
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||||
|
|
||||||
namespace Web::HTML {
|
namespace Web::HTML {
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/canvas.html#canvasimagesource
|
// 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.
|
// NOTE: This is the Variant created by the IDL wrapper generator, and needs to be updated accordingly.
|
||||||
using CanvasImageSource = Variant<GC::Root<HTMLImageElement>, GC::Root<SVG::SVGImageElement>, GC::Root<HTMLCanvasElement>, GC::Root<ImageBitmap>, GC::Root<HTMLVideoElement>>;
|
using CanvasImageSource = Variant<GC::Root<HTMLImageElement>, GC::Root<SVG::SVGImageElement>, GC::Root<HTMLCanvasElement>, GC::Root<ImageBitmap>, GC::Root<OffscreenCanvas>, GC::Root<HTMLVideoElement>>;
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/canvas.html#canvasdrawimage
|
// https://html.spec.whatwg.org/multipage/canvas.html#canvasdrawimage
|
||||||
class CanvasDrawImage {
|
class CanvasDrawImage {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#import <HTML/HTMLCanvasElement.idl>
|
#import <HTML/HTMLCanvasElement.idl>
|
||||||
#import <HTML/HTMLImageElement.idl>
|
#import <HTML/HTMLImageElement.idl>
|
||||||
#import <HTML/HTMLVideoElement.idl>
|
#import <HTML/HTMLVideoElement.idl>
|
||||||
|
#import <HTML/Canvas/OffscreenCanvasBase.idl>
|
||||||
#import <HTML/ImageBitmap.idl>
|
#import <HTML/ImageBitmap.idl>
|
||||||
#import <SVG/SVGImageElement.idl>
|
#import <SVG/SVGImageElement.idl>
|
||||||
|
|
||||||
|
@ -9,8 +10,8 @@ typedef (HTMLImageElement or
|
||||||
// FIXME: We should use HTMLOrSVGImageElement instead of HTMLImageElement
|
// FIXME: We should use HTMLOrSVGImageElement instead of HTMLImageElement
|
||||||
HTMLVideoElement or
|
HTMLVideoElement or
|
||||||
HTMLCanvasElement or
|
HTMLCanvasElement or
|
||||||
ImageBitmap
|
ImageBitmap or
|
||||||
// FIXME: OffscreenCanvas
|
OffscreenCanvas
|
||||||
// FIXME: VideoFrame
|
// FIXME: VideoFrame
|
||||||
) CanvasImageSource;
|
) CanvasImageSource;
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ namespace Web::HTML {
|
||||||
|
|
||||||
GC_DEFINE_ALLOCATOR(CanvasPattern);
|
GC_DEFINE_ALLOCATOR(CanvasPattern);
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/canvas.html#dom-canvaspattern-settransform
|
||||||
void CanvasPatternPaintStyle::paint(Gfx::IntRect physical_bounding_box, PaintFunction paint) const
|
void CanvasPatternPaintStyle::paint(Gfx::IntRect physical_bounding_box, PaintFunction paint) const
|
||||||
{
|
{
|
||||||
// 1. Create an infinite transparent black bitmap.
|
// 1. Create an infinite transparent black bitmap.
|
||||||
|
@ -50,6 +51,7 @@ void CanvasPatternPaintStyle::paint(Gfx::IntRect physical_bounding_box, PaintFun
|
||||||
auto bitmap = m_image.visit(
|
auto bitmap = m_image.visit(
|
||||||
[](GC::Root<HTMLImageElement> const& source) -> RefPtr<Gfx::ImmutableBitmap> { return source->immutable_bitmap(); },
|
[](GC::Root<HTMLImageElement> const& source) -> RefPtr<Gfx::ImmutableBitmap> { return source->immutable_bitmap(); },
|
||||||
[](GC::Root<SVG::SVGImageElement> const& source) -> RefPtr<Gfx::ImmutableBitmap> { return source->current_image_bitmap(); },
|
[](GC::Root<SVG::SVGImageElement> const& source) -> RefPtr<Gfx::ImmutableBitmap> { return source->current_image_bitmap(); },
|
||||||
|
[](GC::Root<OffscreenCanvas> const& source) -> RefPtr<Gfx::ImmutableBitmap> { return Gfx::ImmutableBitmap::create(*source->bitmap()); },
|
||||||
[](GC::Root<HTMLCanvasElement> const& source) -> RefPtr<Gfx::ImmutableBitmap> { return Gfx::ImmutableBitmap::create_snapshot_from_painting_surface(*source->surface()); },
|
[](GC::Root<HTMLCanvasElement> const& source) -> RefPtr<Gfx::ImmutableBitmap> { return Gfx::ImmutableBitmap::create_snapshot_from_painting_surface(*source->surface()); },
|
||||||
[](GC::Root<HTMLVideoElement> const& source) -> RefPtr<Gfx::ImmutableBitmap> { return Gfx::ImmutableBitmap::create(*source->bitmap()); },
|
[](GC::Root<HTMLVideoElement> const& source) -> RefPtr<Gfx::ImmutableBitmap> { return Gfx::ImmutableBitmap::create(*source->bitmap()); },
|
||||||
[](GC::Root<ImageBitmap> const& source) -> RefPtr<Gfx::ImmutableBitmap> { return Gfx::ImmutableBitmap::create(*source->bitmap()); });
|
[](GC::Root<ImageBitmap> const& source) -> RefPtr<Gfx::ImmutableBitmap> { return Gfx::ImmutableBitmap::create(*source->bitmap()); });
|
||||||
|
|
|
@ -135,6 +135,7 @@ WebIDL::ExceptionOr<void> CanvasRenderingContext2D::draw_image_internal(CanvasIm
|
||||||
[](GC::Root<SVG::SVGImageElement> const& source) -> RefPtr<Gfx::ImmutableBitmap> {
|
[](GC::Root<SVG::SVGImageElement> const& source) -> RefPtr<Gfx::ImmutableBitmap> {
|
||||||
return source->current_image_bitmap();
|
return source->current_image_bitmap();
|
||||||
},
|
},
|
||||||
|
[](GC::Root<OffscreenCanvas> const& source) -> RefPtr<Gfx::ImmutableBitmap> { return Gfx::ImmutableBitmap::create(*source->bitmap()); },
|
||||||
[](GC::Root<HTMLCanvasElement> const& source) -> RefPtr<Gfx::ImmutableBitmap> {
|
[](GC::Root<HTMLCanvasElement> const& source) -> RefPtr<Gfx::ImmutableBitmap> {
|
||||||
auto surface = source->surface();
|
auto surface = source->surface();
|
||||||
if (!surface)
|
if (!surface)
|
||||||
|
@ -737,8 +738,14 @@ WebIDL::ExceptionOr<CanvasImageSourceUsability> check_usability_of_image(CanvasI
|
||||||
return Optional<CanvasImageSourceUsability> {};
|
return Optional<CanvasImageSourceUsability> {};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// OffscreenCanvas
|
||||||
|
[](GC::Root<OffscreenCanvas> const& offscreen_canvas) -> WebIDL::ExceptionOr<Optional<CanvasImageSourceUsability>> {
|
||||||
|
// If image has either a horizontal dimension or a vertical dimension equal to zero, then throw an "InvalidStateError" DOMException.
|
||||||
|
if (offscreen_canvas->width() == 0 || offscreen_canvas->height() == 0)
|
||||||
|
return WebIDL::InvalidStateError::create(offscreen_canvas->realm(), "OffscreenCanvas width or height is zero"_string);
|
||||||
|
return Optional<CanvasImageSourceUsability> {};
|
||||||
|
},
|
||||||
// HTMLCanvasElement
|
// HTMLCanvasElement
|
||||||
// FIXME: OffscreenCanvas
|
|
||||||
[](GC::Root<HTMLCanvasElement> const& canvas_element) -> WebIDL::ExceptionOr<Optional<CanvasImageSourceUsability>> {
|
[](GC::Root<HTMLCanvasElement> const& canvas_element) -> WebIDL::ExceptionOr<Optional<CanvasImageSourceUsability>> {
|
||||||
// If image has either a horizontal dimension or a vertical dimension equal to zero, then throw an "InvalidStateError" DOMException.
|
// If image has either a horizontal dimension or a vertical dimension equal to zero, then throw an "InvalidStateError" DOMException.
|
||||||
if (canvas_element->width() == 0 || canvas_element->height() == 0)
|
if (canvas_element->width() == 0 || canvas_element->height() == 0)
|
||||||
|
@ -778,8 +785,8 @@ bool image_is_not_origin_clean(CanvasImageSource const& image)
|
||||||
// FIXME: image's media data is CORS-cross-origin.
|
// FIXME: image's media data is CORS-cross-origin.
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
// HTMLCanvasElement
|
// HTMLCanvasElement, ImageBitmap or OffscreenCanvas
|
||||||
[](OneOf<GC::Root<HTMLCanvasElement>, GC::Root<ImageBitmap>> auto const&) {
|
[](OneOf<GC::Root<HTMLCanvasElement>, GC::Root<ImageBitmap>, GC::Root<OffscreenCanvas>> auto const&) {
|
||||||
// FIXME: image's bitmap's origin-clean flag is false.
|
// FIXME: image's bitmap's origin-clean flag is false.
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,8 +6,14 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <LibWeb/Forward.h>
|
||||||
|
#include <LibWeb/WebIDL/Types.h>
|
||||||
|
|
||||||
namespace Web::WebGL {
|
namespace Web::WebGL {
|
||||||
|
|
||||||
|
// NOTE: This is the Variant created by the IDL wrapper generator, and needs to be updated accordingly.
|
||||||
|
using TexImageSource = Variant<GC::Root<HTML::ImageBitmap>, GC::Root<HTML::ImageData>, GC::Root<HTML::HTMLImageElement>, GC::Root<HTML::HTMLCanvasElement>, GC::Root<HTML::OffscreenCanvas>, GC::Root<HTML::HTMLVideoElement>>;
|
||||||
|
|
||||||
// FIXME: This object should inherit from Bindings::PlatformObject and implement the WebGLRenderingContextBase IDL interface.
|
// FIXME: This object should inherit from Bindings::PlatformObject and implement the WebGLRenderingContextBase IDL interface.
|
||||||
// We should make WebGL code generator to produce implementation for this interface.
|
// We should make WebGL code generator to produce implementation for this interface.
|
||||||
class WebGLRenderingContextBase {
|
class WebGLRenderingContextBase {
|
||||||
|
|
|
@ -4,8 +4,8 @@ typedef (ImageBitmap or
|
||||||
ImageData or
|
ImageData or
|
||||||
HTMLImageElement or
|
HTMLImageElement or
|
||||||
HTMLCanvasElement or
|
HTMLCanvasElement or
|
||||||
HTMLVideoElement
|
HTMLVideoElement or
|
||||||
// FIXME: OffscreenCanvas or
|
OffscreenCanvas
|
||||||
// FIXME: VideoFrame
|
// FIXME: VideoFrame
|
||||||
) TexImageSource;
|
) TexImageSource;
|
||||||
|
|
||||||
|
|
|
@ -730,7 +730,7 @@ struct ConvertedTexture {
|
||||||
int height { 0 };
|
int height { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
static Optional<ConvertedTexture> read_and_pixel_convert_texture_image_source(Variant<GC::Root<ImageBitmap>, GC::Root<ImageData>, GC::Root<HTMLImageElement>, GC::Root<HTMLCanvasElement>, GC::Root<HTMLVideoElement>> const& source, WebIDL::UnsignedLong format, WebIDL::UnsignedLong type, Optional<int> destination_width = OptionalNone {}, Optional<int> destination_height = OptionalNone {})
|
static Optional<ConvertedTexture> read_and_pixel_convert_texture_image_source(TexImageSource const& source, WebIDL::UnsignedLong format, WebIDL::UnsignedLong type, Optional<int> destination_width = OptionalNone {}, Optional<int> destination_height = OptionalNone {})
|
||||||
{
|
{
|
||||||
// FIXME: If this function is called with an ImageData whose data attribute has been neutered,
|
// FIXME: If this function is called with an ImageData whose data attribute has been neutered,
|
||||||
// an INVALID_VALUE error is generated.
|
// an INVALID_VALUE error is generated.
|
||||||
|
@ -753,6 +753,9 @@ static Optional<ConvertedTexture> read_and_pixel_convert_texture_image_source(Va
|
||||||
surface->read_into_bitmap(*bitmap);
|
surface->read_into_bitmap(*bitmap);
|
||||||
return Gfx::ImmutableBitmap::create(*bitmap);
|
return Gfx::ImmutableBitmap::create(*bitmap);
|
||||||
},
|
},
|
||||||
|
[](GC::Root<OffscreenCanvas> const& source) -> RefPtr<Gfx::ImmutableBitmap> {
|
||||||
|
return Gfx::ImmutableBitmap::create(*source->bitmap());
|
||||||
|
},
|
||||||
[](GC::Root<HTMLVideoElement> const& source) -> RefPtr<Gfx::ImmutableBitmap> {
|
[](GC::Root<HTMLVideoElement> const& source) -> RefPtr<Gfx::ImmutableBitmap> {
|
||||||
return Gfx::ImmutableBitmap::create(*source->bitmap());
|
return Gfx::ImmutableBitmap::create(*source->bitmap());
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue