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();
};