LibWeb: Add DOMMatrix fromFloat32Array and fromFloat64Array

This commit is contained in:
Bastiaan van der Plaat 2023-09-25 22:11:30 +02:00 committed by Andrew Kaster
parent 2e122b16e4
commit 3c27843cfe
9 changed files with 146 additions and 13 deletions

View file

@ -662,7 +662,7 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter
auto @cpp_name@ = JS::make_handle(TRY(@js_name@@js_suffix@.to_object(vm)));
)~~~");
}
} else if (parameter.type->name() == "BufferSource") {
} else if (parameter.type->name() == "BufferSource" || parameter.type->name() == "Float32Array" || parameter.type->name() == "Float64Array") {
if (optional) {
scoped_generator.append(R"~~~(
Optional<JS::Handle<JS::Object>> @cpp_name@;

View file

@ -1,4 +1,10 @@
1. {"a":10,"b":20,"c":30,"d":40,"e":50,"f":60,"m11":10,"m12":20,"m13":0,"m14":0,"m21":30,"m22":40,"m23":0,"m24":0,"m31":0,"m32":0,"m33":1,"m34":0,"m41":50,"m42":60,"m43":0,"m44":1,"is2D":true,"isIdentity":false}
2. {"a":10,"b":20,"c":30,"d":40,"e":50,"f":60,"m11":10,"m12":20,"m13":0,"m14":0,"m21":30,"m22":40,"m23":0,"m24":0,"m31":0,"m32":0,"m33":1,"m34":0,"m41":50,"m42":60,"m43":0,"m44":1,"is2D":true,"isIdentity":false}
3. {"a":10,"b":20,"c":50,"d":60,"e":130,"f":140,"m11":10,"m12":20,"m13":30,"m14":40,"m21":50,"m22":60,"m23":70,"m24":80,"m31":90,"m32":100,"m33":110,"m34":120,"m41":130,"m42":140,"m43":150,"m44":160,"is2D":false,"isIdentity":false}
2. {"a":10,"b":20,"c":50,"d":60,"e":130,"f":140,"m11":10,"m12":20,"m13":30,"m14":40,"m21":50,"m22":60,"m23":70,"m24":80,"m31":90,"m32":100,"m33":110,"m34":120,"m41":130,"m42":140,"m43":150,"m44":160,"is2D":false,"isIdentity":false}
3. {"a":10,"b":20,"c":30,"d":40,"e":50,"f":60,"m11":10,"m12":20,"m13":0,"m14":0,"m21":30,"m22":40,"m23":0,"m24":0,"m31":0,"m32":0,"m33":1,"m34":0,"m41":50,"m42":60,"m43":0,"m44":1,"is2D":true,"isIdentity":false}
4. {"a":10,"b":20,"c":50,"d":60,"e":130,"f":140,"m11":10,"m12":20,"m13":30,"m14":40,"m21":50,"m22":60,"m23":70,"m24":80,"m31":90,"m32":100,"m33":110,"m34":120,"m41":130,"m42":140,"m43":150,"m44":160,"is2D":false,"isIdentity":false}
5. {"a":10,"b":20,"c":30,"d":40,"e":50,"f":60,"m11":10,"m12":20,"m13":0,"m14":0,"m21":30,"m22":40,"m23":0,"m24":0,"m31":0,"m32":0,"m33":1,"m34":0,"m41":50,"m42":60,"m43":0,"m44":1,"is2D":true,"isIdentity":false}
6. {"a":10,"b":20,"c":50,"d":60,"e":130,"f":140,"m11":10,"m12":20,"m13":30,"m14":40,"m21":50,"m22":60,"m23":70,"m24":80,"m31":90,"m32":100,"m33":110,"m34":120,"m41":130,"m42":140,"m43":150,"m44":160,"is2D":false,"isIdentity":false}
7. {"a":10,"b":20,"c":30,"d":40,"e":50,"f":60,"m11":10,"m12":20,"m13":0,"m14":0,"m21":30,"m22":40,"m23":0,"m24":0,"m31":0,"m32":0,"m33":1,"m34":0,"m41":50,"m42":60,"m43":0,"m44":1,"is2D":true,"isIdentity":false}
8. {"a":10,"b":20,"c":50,"d":60,"e":130,"f":140,"m11":10,"m12":20,"m13":30,"m14":40,"m21":50,"m22":60,"m23":70,"m24":80,"m31":90,"m32":100,"m33":110,"m34":120,"m41":130,"m42":140,"m43":150,"m44":160,"is2D":false,"isIdentity":false}
9. Exception: TypeError
10. Exception: TypeError

View file

@ -3,19 +3,42 @@
test(() => {
let testCounter = 1;
function testPart(part) {
println(`${testCounter++}. ${JSON.stringify(part())}`);
try {
println(`${testCounter}. ${JSON.stringify(part())}`);
} catch (e) {
println(`${testCounter}. Exception: ${e.name}`);
}
testCounter++;
}
// 1. Creating a DOMMatrix
testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]));
// 2. Creating a DOMMatrix with fromMatrix
testPart(() => DOMMatrix.fromMatrix({ a: 10, b: 20, c: 30, d: 40, e: 50, f: 60 }));
// 3. Creating a DOMMatrix
// 2. Creating a DOMMatrix
testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]));
// 3. Creating a DOMMatrix with fromMatrix
testPart(() => DOMMatrix.fromMatrix({ a: 10, b: 20, c: 30, d: 40, e: 50, f: 60 }));
// 4. Creating a DOMMatrix with fromMatrix
testPart(() => DOMMatrix.fromMatrix({ m11: 10, m12: 20, m13: 30, m14: 40, m21: 50, m22: 60, m23: 70, m24: 80, m31: 90, m32: 100, m33: 110, m34: 120, m41: 130, m42: 140, m43: 150, m44: 160 }));
// 5. Creating a DOMMatrix with fromFloat32Array
testPart(() => DOMMatrix.fromFloat32Array(new Float32Array([10, 20, 30, 40, 50, 60])));
// 6. Creating a DOMMatrix with fromFloat32Array
testPart(() => DOMMatrix.fromFloat32Array(new Float32Array([10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160])));
// 7. Creating a DOMMatrix with fromFloat64Array
testPart(() => DOMMatrix.fromFloat64Array(new Float64Array([10, 20, 30, 40, 50, 60])));
// 8. Creating a DOMMatrix with fromFloat64Array
testPart(() => DOMMatrix.fromFloat64Array(new Float64Array([10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160])));
// 9. Creating a DOMMatrix with fromFloat32Array wrong amount
testPart(() => DOMMatrix.fromFloat32Array(new Float32Array([10, 20, 30, 40])));
// 10. Creating a DOMMatrix with fromFloat64Array wrong amount
testPart(() => DOMMatrix.fromFloat64Array(new Float64Array([10, 20, 30, 40])));
});
</script>

View file

@ -5,6 +5,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibJS/Runtime/TypedArray.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/Geometry/DOMMatrix.h>
#include <LibWeb/WebIDL/ExceptionOr.h>
@ -104,6 +105,56 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> DOMMatrix::from_matrix(JS::VM&
return create_from_dom_matrix_init(*vm.current_realm(), other);
}
// https://drafts.fxtf.org/geometry/#dom-dommatrix-fromfloat32array
WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> DOMMatrix::from_float32_array(JS::VM& vm, JS::Handle<JS::Object> const& array32)
{
if (!is<JS::Float32Array>(*array32))
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "Float32Array");
auto& realm = *vm.current_realm();
auto& float32_array = static_cast<JS::Float32Array&>(*array32);
ReadonlySpan<float> elements = float32_array.data();
// If array32 has 6 elements, return the result of invoking create a 2d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with a sequence of numbers taking the values from array32 in the provided order.
if (elements.size() == 6)
return realm.heap().allocate<DOMMatrix>(realm, realm, elements.at(0), elements.at(1), elements.at(2), elements.at(3), elements.at(4), elements.at(5));
// If array32 has 16 elements, return the result of invoking create a 3d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with a sequence of numbers taking the values from array32 in the provided order.
if (elements.size() == 16)
return realm.heap().allocate<DOMMatrix>(realm, realm, elements.at(0), elements.at(1), elements.at(2), elements.at(3),
elements.at(4), elements.at(5), elements.at(6), elements.at(7),
elements.at(8), elements.at(9), elements.at(10), elements.at(11),
elements.at(12), elements.at(13), elements.at(14), elements.at(15));
// Otherwise, throw a TypeError exception.
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Expected a Float32Array argument with 6 or 16 elements"_string };
}
// https://drafts.fxtf.org/geometry/#dom-dommatrix-fromfloat64array
WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> DOMMatrix::from_float64_array(JS::VM& vm, JS::Handle<JS::Object> const& array64)
{
if (!is<JS::Float64Array>(*array64))
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "Float64Array");
auto& realm = *vm.current_realm();
auto& float64_array = static_cast<JS::Float64Array&>(*array64);
ReadonlySpan<double> elements = float64_array.data();
// If array64 has 6 elements, return the result of invoking create a 2d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with a sequence of numbers taking the values from array64 in the provided order.
if (elements.size() == 6)
return realm.heap().allocate<DOMMatrix>(realm, realm, elements.at(0), elements.at(1), elements.at(2), elements.at(3), elements.at(4), elements.at(5));
// If array64 has 16 elements, return the result of invoking create a 3d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with a sequence of numbers taking the values from array64 in the provided order.
if (elements.size() == 16)
return realm.heap().allocate<DOMMatrix>(realm, realm, elements.at(0), elements.at(1), elements.at(2), elements.at(3),
elements.at(4), elements.at(5), elements.at(6), elements.at(7),
elements.at(8), elements.at(9), elements.at(10), elements.at(11),
elements.at(12), elements.at(13), elements.at(14), elements.at(15));
// Otherwise, throw a TypeError exception.
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Expected a Float64Array argument with 6 or 16 elements"_string };
}
// https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-m11
void DOMMatrix::set_m11(double value)
{

View file

@ -24,6 +24,8 @@ public:
virtual ~DOMMatrix() override;
static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> from_matrix(JS::VM&, DOMMatrixInit other = {});
static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> from_float32_array(JS::VM&, JS::Handle<JS::Object> const& array32);
static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> from_float64_array(JS::VM&, JS::Handle<JS::Object> const& array64);
void set_m11(double value);
void set_m12(double value);

View file

@ -7,8 +7,8 @@ interface DOMMatrix : DOMMatrixReadOnly {
constructor(optional (DOMString or sequence<unrestricted double>) init);
[NewObject] static DOMMatrix fromMatrix(optional DOMMatrixInit other = {});
// FIXME: [NewObject] static DOMMatrix fromFloat32Array(Float32Array array32);
// FIXME: [NewObject] static DOMMatrix fromFloat64Array(Float64Array array64);
[NewObject] static DOMMatrix fromFloat32Array(Float32Array array32);
[NewObject] static DOMMatrix fromFloat64Array(Float64Array array64);
// These attributes are simple aliases for certain elements of the 4x4 matrix
inherit attribute unrestricted double a;

View file

@ -5,7 +5,6 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibJS/Runtime/ArrayBuffer.h>
#include <LibJS/Runtime/TypedArray.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/Geometry/DOMMatrix.h>
@ -208,6 +207,56 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrixReadOnly>> DOMMatrixReadOnly::from
return create_from_dom_matrix_init(*vm.current_realm(), other);
}
// https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-fromfloat32array
WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrixReadOnly>> DOMMatrixReadOnly::from_float32_array(JS::VM& vm, JS::Handle<JS::Object> const& array32)
{
if (!is<JS::Float32Array>(*array32))
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "Float32Array");
auto& realm = *vm.current_realm();
auto& float32_array = static_cast<JS::Float32Array&>(*array32);
ReadonlySpan<float> elements = float32_array.data();
// If array32 has 6 elements, return the result of invoking create a 2d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with a sequence of numbers taking the values from array32 in the provided order.
if (elements.size() == 6)
return realm.heap().allocate<DOMMatrix>(realm, realm, elements.at(0), elements.at(1), elements.at(2), elements.at(3), elements.at(4), elements.at(5));
// If array32 has 16 elements, return the result of invoking create a 3d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with a sequence of numbers taking the values from array32 in the provided order.
if (elements.size() == 16)
return realm.heap().allocate<DOMMatrix>(realm, realm, elements.at(0), elements.at(1), elements.at(2), elements.at(3),
elements.at(4), elements.at(5), elements.at(6), elements.at(7),
elements.at(8), elements.at(9), elements.at(10), elements.at(11),
elements.at(12), elements.at(13), elements.at(14), elements.at(15));
// Otherwise, throw a TypeError exception.
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Expected a Float32Array argument with 6 or 16 elements"_string };
}
// https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-fromfloat64array
WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrixReadOnly>> DOMMatrixReadOnly::from_float64_array(JS::VM& vm, JS::Handle<JS::Object> const& array64)
{
if (!is<JS::Float64Array>(*array64))
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "Float64Array");
auto& realm = *vm.current_realm();
auto& float64_array = static_cast<JS::Float64Array&>(*array64);
ReadonlySpan<double> elements = float64_array.data();
// If array64 has 6 elements, return the result of invoking create a 2d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with a sequence of numbers taking the values from array64 in the provided order.
if (elements.size() == 6)
return realm.heap().allocate<DOMMatrix>(realm, realm, elements.at(0), elements.at(1), elements.at(2), elements.at(3), elements.at(4), elements.at(5));
// If array64 has 16 elements, return the result of invoking create a 3d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with a sequence of numbers taking the values from array64 in the provided order.
if (elements.size() == 16)
return realm.heap().allocate<DOMMatrix>(realm, realm, elements.at(0), elements.at(1), elements.at(2), elements.at(3),
elements.at(4), elements.at(5), elements.at(6), elements.at(7),
elements.at(8), elements.at(9), elements.at(10), elements.at(11),
elements.at(12), elements.at(13), elements.at(14), elements.at(15));
// Otherwise, throw a TypeError exception.
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Expected a Float64Array argument with 6 or 16 elements"_string };
}
// https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-isidentity
bool DOMMatrixReadOnly::is_identity() const
{

View file

@ -56,6 +56,8 @@ public:
virtual ~DOMMatrixReadOnly() override;
static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrixReadOnly>> from_matrix(JS::VM&, DOMMatrixInit& other);
static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrixReadOnly>> from_float32_array(JS::VM&, JS::Handle<JS::Object> const& array32);
static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrixReadOnly>> from_float64_array(JS::VM&, JS::Handle<JS::Object> const& array64);
// https://drafts.fxtf.org/geometry/#dommatrix-attributes
double m11() const { return m_matrix.elements()[0][0]; }

View file

@ -7,8 +7,8 @@ interface DOMMatrixReadOnly {
constructor(optional (DOMString or sequence<unrestricted double>) init);
[NewObject] static DOMMatrixReadOnly fromMatrix(optional DOMMatrixInit other = {});
// FIXME: [NewObject] static DOMMatrixReadOnly fromFloat32Array(Float32Array array32);
// FIXME: [NewObject] static DOMMatrixReadOnly fromFloat64Array(Float64Array array64);
[NewObject] static DOMMatrixReadOnly fromFloat32Array(Float32Array array32);
[NewObject] static DOMMatrixReadOnly fromFloat64Array(Float64Array array64);
// These attributes are simple aliases for certain elements of the 4x4 matrix
readonly attribute unrestricted double a;