Merge 609c78f175
into 3eefa464ee
This commit is contained in:
commit
949f41e820
5 changed files with 98 additions and 1 deletions
|
@ -10,6 +10,7 @@
|
|||
#include <LibWeb/Bindings/ImageDataPrototype.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/HTML/ImageData.h>
|
||||
#include <LibWeb/HTML/StructuredSerialize.h>
|
||||
#include <LibWeb/WebIDL/Buffers.h>
|
||||
#include <LibWeb/WebIDL/DOMException.h>
|
||||
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||
|
@ -133,4 +134,50 @@ const JS::Uint8ClampedArray* ImageData::data() const
|
|||
return m_data;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/canvas.html#pixel-manipulation:serialization-steps
|
||||
WebIDL::ExceptionOr<void> ImageData::serialization_steps(HTML::SerializationRecord& serialized, bool for_storage, HTML::SerializationMemory& memory)
|
||||
{
|
||||
auto& vm = this->vm();
|
||||
|
||||
// FIXME: These have to be performed out of order, since these primitive types will get the wrong value when deserializing
|
||||
// if they're placed after the Uint8ClampedArray.
|
||||
// 2. Set serialized.[[Width]] to the value of value's width attribute.
|
||||
HTML::serialize_primitive_type(serialized, width());
|
||||
|
||||
// 3. Set serialized.[[Height]] to the value of value's height attribute.
|
||||
HTML::serialize_primitive_type(serialized, height());
|
||||
|
||||
// 1. Set serialized.[[Data]] to the sub-serialization of the value of value's data attribute.
|
||||
serialized.extend(TRY(HTML::structured_serialize_internal(vm, m_data, for_storage, memory)));
|
||||
|
||||
// FIXME: 4. Set serialized.[[ColorSpace]] to the value of value's colorSpace attribute.
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/canvas.html#pixel-manipulation:deserialization-steps
|
||||
WebIDL::ExceptionOr<void> ImageData::deserialization_steps(ReadonlySpan<u32> const& serialized, size_t& position, HTML::DeserializationMemory& memory)
|
||||
{
|
||||
auto& vm = this->vm();
|
||||
auto& realm = this->realm();
|
||||
|
||||
// FIXME: These have to be performed out of order, since these primitive types will get the wrong value if they're
|
||||
// placed after the Uint8ClampedArray.
|
||||
// 2. Initialize value's width attribute to serialized.[[Width]].
|
||||
// 3. Initialize value's height attribute to serialized.[[Height]].
|
||||
auto width = HTML::deserialize_primitive_type<unsigned>(serialized, position);
|
||||
auto height = HTML::deserialize_primitive_type<unsigned>(serialized, position);
|
||||
|
||||
// 1. Initialize value's data attribute to the sub-deserialization of serialized.[[Data]].
|
||||
auto deserialized_record = TRY(HTML::structured_deserialize_internal(vm, serialized, realm, memory, position));
|
||||
if (deserialized_record.value.has_value() && is<JS::Uint8ClampedArray>(deserialized_record.value.value().as_object()))
|
||||
m_data = dynamic_cast<JS::Uint8ClampedArray&>(deserialized_record.value.release_value().as_object());
|
||||
|
||||
m_bitmap = TRY_OR_THROW_OOM(vm, Gfx::Bitmap::create_wrapper(Gfx::BitmapFormat::RGBA8888, Gfx::AlphaType::Unpremultiplied, Gfx::IntSize(width, height), width * sizeof(u32), m_data->data().data()));
|
||||
|
||||
// FIXME: 4. Initialize value's colorSpace attribute to serialized.[[ColorSpace]].
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <LibGfx/Forward.h>
|
||||
#include <LibWeb/Bindings/ImageDataPrototype.h>
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/Bindings/Serializable.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
|
@ -17,7 +18,9 @@ struct ImageDataSettings {
|
|||
Bindings::PredefinedColorSpace color_space;
|
||||
};
|
||||
|
||||
class ImageData final : public Bindings::PlatformObject {
|
||||
class ImageData final
|
||||
: public Bindings::PlatformObject
|
||||
, public Bindings::Serializable {
|
||||
WEB_PLATFORM_OBJECT(ImageData, Bindings::PlatformObject);
|
||||
GC_DECLARE_ALLOCATOR(ImageData);
|
||||
|
||||
|
@ -39,6 +42,10 @@ public:
|
|||
JS::Uint8ClampedArray* data();
|
||||
const JS::Uint8ClampedArray* data() const;
|
||||
|
||||
virtual StringView interface_name() const override { return "ImageData"sv; }
|
||||
virtual WebIDL::ExceptionOr<void> serialization_steps(HTML::SerializationRecord& serialized, bool for_storage, HTML::SerializationMemory&) override;
|
||||
virtual WebIDL::ExceptionOr<void> deserialization_steps(ReadonlySpan<u32> const& serialized, size_t& position, HTML::DeserializationMemory&) override;
|
||||
|
||||
private:
|
||||
ImageData(JS::Realm&, NonnullRefPtr<Gfx::Bitmap>, GC::Ref<JS::Uint8ClampedArray>);
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include <LibWeb/Geometry/DOMQuad.h>
|
||||
#include <LibWeb/Geometry/DOMRect.h>
|
||||
#include <LibWeb/Geometry/DOMRectReadOnly.h>
|
||||
#include <LibWeb/HTML/ImageData.h>
|
||||
#include <LibWeb/HTML/MessagePort.h>
|
||||
#include <LibWeb/HTML/StructuredSerialize.h>
|
||||
#include <LibWeb/WebIDL/DOMException.h>
|
||||
|
@ -1069,6 +1070,8 @@ private:
|
|||
return Crypto::CryptoKey::create(realm);
|
||||
if (interface_name == "DOMQuad"sv)
|
||||
return Geometry::DOMQuad::create(realm);
|
||||
if (interface_name == "ImageData"sv) // FIXME: Unfortunately we have to create this with a dummy array and bitmap, as they're non-nullable.
|
||||
return MUST(HTML::ImageData::create(realm, 1, 1));
|
||||
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
=== before clone start ===
|
||||
width: 123
|
||||
height: 321
|
||||
data byteLength: 157932
|
||||
data filled with 0x41? true
|
||||
=== before clone end ===
|
||||
=== after clone start ===
|
||||
width: 123
|
||||
height: 321
|
||||
data byteLength: 157932
|
||||
data filled with 0x41? true
|
||||
not the same data array? true
|
||||
=== after clone end ===
|
27
Tests/LibWeb/Text/input/HTML/ImageData-is-serializable.html
Normal file
27
Tests/LibWeb/Text/input/HTML/ImageData-is-serializable.html
Normal file
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../include.js"></script>
|
||||
<script>
|
||||
test(() => {
|
||||
const arr = new Uint8ClampedArray(4 * 123 * 321);
|
||||
arr.fill(0x41);
|
||||
|
||||
const imageData = new ImageData(arr, 123, 321);
|
||||
|
||||
println("=== before clone start ===");
|
||||
println(`width: ${imageData.width}`);
|
||||
println(`height: ${imageData.height}`);
|
||||
println(`data byteLength: ${imageData.data.byteLength}`);
|
||||
println(`data filled with 0x41? ${imageData.data.every((val) => val === 0x41)}`);
|
||||
println("=== before clone end ===");
|
||||
|
||||
const clonedImageData = structuredClone(imageData);
|
||||
|
||||
println("=== after clone start ===");
|
||||
println(`width: ${clonedImageData.width}`);
|
||||
println(`height: ${clonedImageData.height}`);
|
||||
println(`data byteLength: ${clonedImageData.data.byteLength}`);
|
||||
println(`data filled with 0x41? ${clonedImageData.data.every((val) => val === 0x41)}`);
|
||||
println(`not the same data array? ${imageData.data !== clonedImageData.data}`);
|
||||
println("=== after clone end ===");
|
||||
});
|
||||
</script>
|
Loading…
Add table
Reference in a new issue