1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 18:07:35 +00:00

LibWeb: Add DOMPoint matrixTransform and DOMMatrix transformPoint

This commit is contained in:
Bastiaan van der Plaat 2023-08-15 13:16:45 +02:00 committed by Jelle Raaijmakers
parent 38bc8836d6
commit b4ae719664
9 changed files with 106 additions and 2 deletions

View file

@ -0,0 +1,6 @@
1. {"x":10,"y":20,"z":0,"w":1}
2. {"x":1,"y":2,"z":3,"w":4}
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. {"x":750,"y":1060,"z":0,"w":1}
5. {"x":750,"y":1060,"z":0,"w":1}
6. {"x":750,"y":1060,"z":0,"w":1}

View file

@ -0,0 +1,37 @@
<script src="../include.js"></script>
<script>
test(() => {
let testCounter = 1;
function testPart(part) {
println(`${testCounter++}. ${JSON.stringify(part())}`);
}
// 1. Creating a DOMPoint
testPart(() => new DOMPoint(10, 20));
// 2. Creating DOMPoint with fromPoint
testPart(() => DOMPoint.fromPoint({ x: 1, y: 2, z: 3, w: 4 }));
// 3. Creating a DOMMatrix
testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]));
// 4. Transforming a DOMPoint using a DOMMatrix
testPart(function () {
const matrix = new DOMMatrix([10, 20, 30, 40, 50, 60]);
const point = new DOMPoint(10, 20);
return point.matrixTransform(matrix);
});
// 5. Transforming a point using a DOMMatrix
testPart(function () {
const matrix = new DOMMatrix([10, 20, 30, 40, 50, 60]);
return matrix.transformPoint(new DOMPoint(10, 20));
});
// 6. Transforming a point using a DOMMatrix
testPart(function () {
const matrix = new DOMMatrix([10, 20, 30, 40, 50, 60]);
return matrix.transformPoint({x: 10, y: 20});
});
});
</script>

View file

@ -299,8 +299,11 @@ class File;
namespace Web::Geometry { namespace Web::Geometry {
class DOMMatrix; class DOMMatrix;
struct DOMMatrix2DInit;
struct DOMMatrixInit;
class DOMMatrixReadOnly; class DOMMatrixReadOnly;
class DOMPoint; class DOMPoint;
struct DOMPointInit;
class DOMPointReadOnly; class DOMPointReadOnly;
class DOMQuad; class DOMQuad;
class DOMRect; class DOMRect;

View file

@ -7,6 +7,7 @@
#include <LibWeb/Bindings/Intrinsics.h> #include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/Geometry/DOMMatrix.h> #include <LibWeb/Geometry/DOMMatrix.h>
#include <LibWeb/Geometry/DOMMatrixReadOnly.h> #include <LibWeb/Geometry/DOMMatrixReadOnly.h>
#include <LibWeb/Geometry/DOMPoint.h>
#include <LibWeb/WebIDL/ExceptionOr.h> #include <LibWeb/WebIDL/ExceptionOr.h>
namespace Web::Geometry { namespace Web::Geometry {
@ -240,6 +241,39 @@ JS::NonnullGCPtr<DOMMatrix> DOMMatrixReadOnly::inverse() const
return result->invert_self(); return result->invert_self();
} }
// https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-transformpoint
JS::NonnullGCPtr<DOMPoint> DOMMatrixReadOnly::transform_point(DOMPointInit const& point) const
{
// Let pointObject be the result of invoking create a DOMPoint from the dictionary point.
auto point_object = DOMPoint::from_point(realm().vm(), point);
// Return the result of invoking transform a point with a matrix, given pointObject and the current matrix. The passed argument does not get modified.
return transform_point(point_object);
}
// https://drafts.fxtf.org/geometry/#transform-a-point-with-a-matrix
JS::NonnullGCPtr<DOMPoint> DOMMatrixReadOnly::transform_point(DOMPointReadOnly const& point) const
{
// 1. Let x be points x coordinate.
// 2. Let y be points y coordinate.
// 3. Let z be points z coordinate.
// 4. Let w be points w perspective.
// 5. Let pointVector be a new column vector with the elements being x, y, z, and w, respectively.
Vector4<double> point_vector { point.x(), point.y(), point.z(), point.w() };
// 6. Set pointVector to pointVector pre-multiplied by matrix.
// This is really a post multiply because of the transposed m_matrix.
point_vector = m_matrix.transpose() * point_vector;
// 7. Let transformedPoint be a new DOMPoint object.
// 8. Set transformedPoints x coordinate to pointVectors first element.
// 9. Set transformedPoints y coordinate to pointVectors second element.
// 10. Set transformedPoints z coordinate to pointVectors third element.
// 11. Set transformedPoints w perspective to pointVectors fourth element.
// 12. Return transformedPoint.
return DOMPoint::construct_impl(realm(), point_vector.x(), point_vector.y(), point_vector.z(), point_vector.w());
}
// https://drafts.fxtf.org/geometry/#dommatrixreadonly-stringification-behavior // https://drafts.fxtf.org/geometry/#dommatrixreadonly-stringification-behavior
WebIDL::ExceptionOr<String> DOMMatrixReadOnly::to_string() const WebIDL::ExceptionOr<String> DOMMatrixReadOnly::to_string() const
{ {

View file

@ -83,6 +83,10 @@ public:
JS::NonnullGCPtr<DOMMatrix> inverse() const; JS::NonnullGCPtr<DOMMatrix> inverse() const;
JS::NonnullGCPtr<DOMPoint> transform_point(DOMPointInit const&) const;
JS::NonnullGCPtr<DOMPoint> transform_point(DOMPointReadOnly const&) const;
WebIDL::ExceptionOr<String> to_string() const; WebIDL::ExceptionOr<String> to_string() const;
protected: protected:

View file

@ -1,4 +1,5 @@
#import <Geometry/DOMMatrix.idl> #import <Geometry/DOMMatrix.idl>
#import <Geometry/DOMPoint.idl>
// https://drafts.fxtf.org/geometry/#dommatrixreadonly // https://drafts.fxtf.org/geometry/#dommatrixreadonly
[Exposed=(Window,Worker), Serializable, UseNewAKString] [Exposed=(Window,Worker), Serializable, UseNewAKString]
@ -52,7 +53,7 @@ interface DOMMatrixReadOnly {
// FIXME: [NewObject] DOMMatrix flipY(); // FIXME: [NewObject] DOMMatrix flipY();
[NewObject] DOMMatrix inverse(); [NewObject] DOMMatrix inverse();
// FIXME: [NewObject] DOMPoint transformPoint(optional DOMPointInit point = {}); [NewObject] DOMPoint transformPoint(optional DOMPointInit point = {});
// FIXME: [NewObject] Float32Array toFloat32Array(); // FIXME: [NewObject] Float32Array toFloat32Array();
// FIXME: [NewObject] Float64Array toFloat64Array(); // FIXME: [NewObject] Float64Array toFloat64Array();

View file

@ -6,6 +6,7 @@
*/ */
#include <LibWeb/Bindings/Intrinsics.h> #include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/Geometry/DOMMatrix.h>
#include <LibWeb/Geometry/DOMPointReadOnly.h> #include <LibWeb/Geometry/DOMPointReadOnly.h>
#include <LibWeb/WebIDL/ExceptionOr.h> #include <LibWeb/WebIDL/ExceptionOr.h>
@ -34,6 +35,19 @@ JS::NonnullGCPtr<DOMPointReadOnly> DOMPointReadOnly::from_point(JS::VM& vm, DOMP
DOMPointReadOnly::~DOMPointReadOnly() = default; DOMPointReadOnly::~DOMPointReadOnly() = default;
// https://drafts.fxtf.org/geometry/#dom-dompointreadonly-matrixtransform
WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMPoint>> DOMPointReadOnly::matrix_transform(DOMMatrixInit& matrix) const
{
// 1. Let matrixObject be the result of invoking create a DOMMatrix from the dictionary matrix.
auto maybe_matrix_object = DOMMatrix::create_from_dom_matrix_2d_init(realm(), matrix);
if (maybe_matrix_object.is_exception())
return maybe_matrix_object.exception();
auto matrix_object = maybe_matrix_object.release_value();
// 2. Return the result of invoking transform a point with a matrix, given the current point and matrixObject. The current point does not get modified.
return matrix_object->transform_point(*this);
}
void DOMPointReadOnly::initialize(JS::Realm& realm) void DOMPointReadOnly::initialize(JS::Realm& realm)
{ {
Base::initialize(realm); Base::initialize(realm);

View file

@ -36,6 +36,8 @@ public:
double z() const { return m_z; } double z() const { return m_z; }
double w() const { return m_w; } double w() const { return m_w; }
WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMPoint>> matrix_transform(DOMMatrixInit&) const;
protected: protected:
DOMPointReadOnly(JS::Realm&, double x, double y, double z, double w); DOMPointReadOnly(JS::Realm&, double x, double y, double z, double w);

View file

@ -1,3 +1,6 @@
#import <Geometry/DOMMatrixReadOnly.idl>
#import <Geometry/DOMPoint.idl>
// https://drafts.fxtf.org/geometry/#dompointreadonly // https://drafts.fxtf.org/geometry/#dompointreadonly
[Exposed=(Window,Worker), Serializable] [Exposed=(Window,Worker), Serializable]
interface DOMPointReadOnly { interface DOMPointReadOnly {
@ -12,7 +15,7 @@ interface DOMPointReadOnly {
readonly attribute unrestricted double z; readonly attribute unrestricted double z;
readonly attribute unrestricted double w; readonly attribute unrestricted double w;
// FIXME: DOMPoint matrixTransform(optional DOMMatrixInit matrix = {}); [NewObject] DOMPoint matrixTransform(optional DOMMatrixInit matrix = {});
[Default] object toJSON(); [Default] object toJSON();
}; };