diff --git a/Tests/LibWeb/Text/expected/geometry/dommatrix.txt b/Tests/LibWeb/Text/expected/geometry/dommatrix.txt index 773fe501de..9ee284863e 100644 --- a/Tests/LibWeb/Text/expected/geometry/dommatrix.txt +++ b/Tests/LibWeb/Text/expected/geometry/dommatrix.txt @@ -1,2 +1,3 @@ 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":700,"b":1000,"c":1500,"d":2200,"e":2350,"f":3460,"m11":700,"m12":1000,"m13":0,"m14":0,"m21":1500,"m22":2200,"m23":0,"m24":0,"m31":0,"m32":0,"m33":1,"m34":0,"m41":2350,"m42":3460,"m43":0,"m44":1,"is2D":true,"isIdentity":false} diff --git a/Tests/LibWeb/Text/input/geometry/dommatrix.html b/Tests/LibWeb/Text/input/geometry/dommatrix.html index 920300bd74..a6d1a88517 100644 --- a/Tests/LibWeb/Text/input/geometry/dommatrix.html +++ b/Tests/LibWeb/Text/input/geometry/dommatrix.html @@ -11,5 +11,8 @@ // 2. Creating a DOMMatrix with fromMatrix testPart(() => DOMMatrix.fromMatrix({ a: 10, b: 20, c: 30, d: 40, e: 50, f: 60 })); + + // 3. Multiply DOMMatrix by DOMMatrix + testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).multiply(new DOMMatrix([10, 20, 30, 40, 50, 60]))); }); diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.cpp b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.cpp index e20b7e1fed..5c831947b6 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.cpp +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.cpp @@ -253,6 +253,46 @@ void DOMMatrix::set_f(double value) set_m42(value); } +// https://drafts.fxtf.org/geometry/#dom-dommatrix-multiplyself +WebIDL::ExceptionOr> DOMMatrix::multiply_self(DOMMatrixInit other) +{ + // 1. Let otherObject be the result of invoking create a DOMMatrix from the dictionary other. + auto maybe_other_object = DOMMatrix::create_from_dom_matrix_2d_init(realm(), other); + if (maybe_other_object.is_exception()) + return maybe_other_object.exception(); + auto other_object = maybe_other_object.release_value(); + + // 2. The otherObject matrix gets post-multiplied to the current matrix. + m_matrix = m_matrix * other_object->m_matrix; + + // 3. If is 2D of otherObject is false, set is 2D of the current matrix to false. + if (!other_object->m_is_2d) + m_is_2d = false; + + // 4. Return the current matrix. + return JS::NonnullGCPtr(*this); +} + +// https://drafts.fxtf.org/geometry/#dom-dommatrix-premultiplyself +WebIDL::ExceptionOr> DOMMatrix::pre_multiply_self(DOMMatrixInit other) +{ + // 1. Let otherObject be the result of invoking create a DOMMatrix from the dictionary other. + auto maybe_other_object = DOMMatrix::create_from_dom_matrix_2d_init(realm(), other); + if (maybe_other_object.is_exception()) + return maybe_other_object.exception(); + auto other_object = maybe_other_object.release_value(); + + // 2. The otherObject matrix gets pre-multiplied to the current matrix. + m_matrix = other_object->m_matrix * m_matrix; + + // 3. If is 2D of otherObject is false, set is 2D of the current matrix to false. + if (!other_object->m_is_2d) + m_is_2d = false; + + // 4. Return the current matrix. + return JS::NonnullGCPtr(*this); +} + // https://drafts.fxtf.org/geometry/#dom-dommatrix-invertself JS::NonnullGCPtr DOMMatrix::invert_self() { diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.h b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.h index 9fa47d9f90..fb54af3643 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.h +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.h @@ -47,6 +47,8 @@ public: void set_e(double value); void set_f(double value); + WebIDL::ExceptionOr> multiply_self(DOMMatrixInit other = {}); + WebIDL::ExceptionOr> pre_multiply_self(DOMMatrixInit other = {}); JS::NonnullGCPtr invert_self(); private: diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.idl b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.idl index 579d7b3d12..77192be709 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.idl +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.idl @@ -36,8 +36,8 @@ interface DOMMatrix : DOMMatrixReadOnly { inherit attribute unrestricted double m44; // Mutable transform methods - // FIXME: DOMMatrix multiplySelf(optional DOMMatrixInit other = {}); - // FIXME: DOMMatrix preMultiplySelf(optional DOMMatrixInit other = {}); + DOMMatrix multiplySelf(optional DOMMatrixInit other = {}); + DOMMatrix preMultiplySelf(optional DOMMatrixInit other = {}); // FIXME: DOMMatrix translateSelf(optional unrestricted double tx = 0, optional unrestricted double ty = 0, optional unrestricted double tz = 0); // FIXME: DOMMatrix scaleSelf(optional unrestricted double scaleX = 1, optional unrestricted double scaleY, optional unrestricted double scaleZ = 1, optional unrestricted double originX = 0, optional unrestricted double originY = 0, optional unrestricted double originZ = 0); // FIXME: DOMMatrix scale3dSelf(optional unrestricted double scale = 1, optional unrestricted double originX = 0, optional unrestricted double originY = 0, optional unrestricted double originZ = 0); diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.cpp b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.cpp index 96fd291f6b..880ca19680 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.cpp +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.cpp @@ -239,6 +239,17 @@ bool DOMMatrixReadOnly::is_identity() const return true; } +// https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-multiply +WebIDL::ExceptionOr> DOMMatrixReadOnly::multiply(DOMMatrixInit other) +{ + // 1. Let result be the resulting matrix initialized to the values of the current matrix. + auto result = DOMMatrix::create_from_dom_matrix_read_only(realm(), *this); + + // 2. Perform a multiplySelf() transformation on result with the argument other. + // 3. Return result. + return result->multiply_self(other); +} + // https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-inverse JS::NonnullGCPtr DOMMatrixReadOnly::inverse() const { diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.h b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.h index e045de0d49..a7e1408ccb 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.h +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.h @@ -83,10 +83,10 @@ public: bool is2d() const { return m_is_2d; } bool is_identity() const; + WebIDL::ExceptionOr> multiply(DOMMatrixInit other = {}); JS::NonnullGCPtr inverse() const; JS::NonnullGCPtr transform_point(DOMPointInit const&) const; - JS::NonnullGCPtr transform_point(DOMPointReadOnly const&) const; WebIDL::ExceptionOr to_string() const; diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.idl b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.idl index d757df0658..c76c1b9e4e 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.idl +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.idl @@ -48,7 +48,7 @@ interface DOMMatrixReadOnly { // FIXME: [NewObject] DOMMatrix rotateAxisAngle(optional unrestricted double x = 0, optional unrestricted double y = 0, optional unrestricted double z = 0, optional unrestricted double angle = 0); // FIXME: [NewObject] DOMMatrix skewX(optional unrestricted double sx = 0); // FIXME: [NewObject] DOMMatrix skewY(optional unrestricted double sy = 0); - // FIXME: [NewObject] DOMMatrix multiply(optional DOMMatrixInit other = {}); + [NewObject] DOMMatrix multiply(optional DOMMatrixInit other = {}); // FIXME: [NewObject] DOMMatrix flipX(); // FIXME: [NewObject] DOMMatrix flipY(); [NewObject] DOMMatrix inverse();