diff --git a/Tests/LibWeb/Text/expected/geometry/dompoint.txt b/Tests/LibWeb/Text/expected/geometry/dompoint.txt new file mode 100644 index 0000000000..8b6543873d --- /dev/null +++ b/Tests/LibWeb/Text/expected/geometry/dompoint.txt @@ -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} diff --git a/Tests/LibWeb/Text/input/geometry/dompoint.html b/Tests/LibWeb/Text/input/geometry/dompoint.html new file mode 100644 index 0000000000..38ec20ba17 --- /dev/null +++ b/Tests/LibWeb/Text/input/geometry/dompoint.html @@ -0,0 +1,37 @@ + + diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index ed86d8ad58..74b34e66d3 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -299,8 +299,11 @@ class File; namespace Web::Geometry { class DOMMatrix; +struct DOMMatrix2DInit; +struct DOMMatrixInit; class DOMMatrixReadOnly; class DOMPoint; +struct DOMPointInit; class DOMPointReadOnly; class DOMQuad; class DOMRect; diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.cpp b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.cpp index b96dc1edb9..867de28b08 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.cpp +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include namespace Web::Geometry { @@ -240,6 +241,39 @@ JS::NonnullGCPtr DOMMatrixReadOnly::inverse() const return result->invert_self(); } +// https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-transformpoint +JS::NonnullGCPtr 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 DOMMatrixReadOnly::transform_point(DOMPointReadOnly const& point) const +{ + // 1. Let x be point’s x coordinate. + // 2. Let y be point’s y coordinate. + // 3. Let z be point’s z coordinate. + // 4. Let w be point’s w perspective. + // 5. Let pointVector be a new column vector with the elements being x, y, z, and w, respectively. + Vector4 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 transformedPoint’s x coordinate to pointVector’s first element. + // 9. Set transformedPoint’s y coordinate to pointVector’s second element. + // 10. Set transformedPoint’s z coordinate to pointVector’s third element. + // 11. Set transformedPoint’s w perspective to pointVector’s 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 WebIDL::ExceptionOr DOMMatrixReadOnly::to_string() const { diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.h b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.h index e01543a611..64cd25d4bf 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.h +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.h @@ -83,6 +83,10 @@ public: JS::NonnullGCPtr inverse() const; + JS::NonnullGCPtr transform_point(DOMPointInit const&) const; + + JS::NonnullGCPtr transform_point(DOMPointReadOnly const&) const; + WebIDL::ExceptionOr to_string() const; protected: diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.idl b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.idl index 3e2b43e72f..e55a48fc5f 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.idl +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.idl @@ -1,4 +1,5 @@ #import +#import // https://drafts.fxtf.org/geometry/#dommatrixreadonly [Exposed=(Window,Worker), Serializable, UseNewAKString] @@ -52,7 +53,7 @@ interface DOMMatrixReadOnly { // FIXME: [NewObject] DOMMatrix flipY(); [NewObject] DOMMatrix inverse(); - // FIXME: [NewObject] DOMPoint transformPoint(optional DOMPointInit point = {}); + [NewObject] DOMPoint transformPoint(optional DOMPointInit point = {}); // FIXME: [NewObject] Float32Array toFloat32Array(); // FIXME: [NewObject] Float64Array toFloat64Array(); diff --git a/Userland/Libraries/LibWeb/Geometry/DOMPointReadOnly.cpp b/Userland/Libraries/LibWeb/Geometry/DOMPointReadOnly.cpp index 7a1fc94644..7f9f77fc64 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMPointReadOnly.cpp +++ b/Userland/Libraries/LibWeb/Geometry/DOMPointReadOnly.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include @@ -34,6 +35,19 @@ JS::NonnullGCPtr DOMPointReadOnly::from_point(JS::VM& vm, DOMP DOMPointReadOnly::~DOMPointReadOnly() = default; +// https://drafts.fxtf.org/geometry/#dom-dompointreadonly-matrixtransform +WebIDL::ExceptionOr> 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) { Base::initialize(realm); diff --git a/Userland/Libraries/LibWeb/Geometry/DOMPointReadOnly.h b/Userland/Libraries/LibWeb/Geometry/DOMPointReadOnly.h index be5819b57f..c4f17e50d8 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMPointReadOnly.h +++ b/Userland/Libraries/LibWeb/Geometry/DOMPointReadOnly.h @@ -36,6 +36,8 @@ public: double z() const { return m_z; } double w() const { return m_w; } + WebIDL::ExceptionOr> matrix_transform(DOMMatrixInit&) const; + protected: DOMPointReadOnly(JS::Realm&, double x, double y, double z, double w); diff --git a/Userland/Libraries/LibWeb/Geometry/DOMPointReadOnly.idl b/Userland/Libraries/LibWeb/Geometry/DOMPointReadOnly.idl index 4e3e5475e6..8b61b67561 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMPointReadOnly.idl +++ b/Userland/Libraries/LibWeb/Geometry/DOMPointReadOnly.idl @@ -1,3 +1,6 @@ +#import +#import + // https://drafts.fxtf.org/geometry/#dompointreadonly [Exposed=(Window,Worker), Serializable] interface DOMPointReadOnly { @@ -12,7 +15,7 @@ interface DOMPointReadOnly { readonly attribute unrestricted double z; readonly attribute unrestricted double w; - // FIXME: DOMPoint matrixTransform(optional DOMMatrixInit matrix = {}); + [NewObject] DOMPoint matrixTransform(optional DOMMatrixInit matrix = {}); [Default] object toJSON(); };