diff --git a/Tests/LibWeb/Text/expected/geometry/dommatrix.txt b/Tests/LibWeb/Text/expected/geometry/dommatrix.txt index 9ee284863e..26a66f5c36 100644 --- a/Tests/LibWeb/Text/expected/geometry/dommatrix.txt +++ b/Tests/LibWeb/Text/expected/geometry/dommatrix.txt @@ -1,3 +1,8 @@ 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} +4. {"a":1,"b":0,"c":0,"d":1,"e":25,"f":25,"m11":1,"m12":0,"m13":0,"m14":0,"m21":0,"m22":1,"m23":0,"m24":0,"m31":0,"m32":0,"m33":1,"m34":0,"m41":25,"m42":25,"m43":0,"m44":1,"is2D":true,"isIdentity":false} +5. {"a":10,"b":20,"c":30,"d":40,"e":1050,"f":1560,"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":1050,"m42":1560,"m43":0,"m44":1,"is2D":true,"isIdentity":false} +6. {"a":10,"b":20,"c":30,"d":40,"e":1050,"f":1560,"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":1050,"m42":1560,"m43":0,"m44":1,"is2D":true,"isIdentity":false} +7. {"a":10,"b":20,"c":30,"d":40,"e":1050,"f":1560,"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":1050,"m42":1560,"m43":0,"m44":1,"is2D":true,"isIdentity":false} +8. {"a":10,"b":20,"c":30,"d":40,"e":75,"f":85,"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":75,"m42":85,"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 a6d1a88517..df0526efec 100644 --- a/Tests/LibWeb/Text/input/geometry/dommatrix.html +++ b/Tests/LibWeb/Text/input/geometry/dommatrix.html @@ -14,5 +14,20 @@ // 3. Multiply DOMMatrix by DOMMatrix testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).multiply(new DOMMatrix([10, 20, 30, 40, 50, 60]))); + + // 4. Create translation DOMMatrix + testPart(() => new DOMMatrix().translate(25, 25)); + + // 5. Translate DOMMatrix + testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).translateSelf(25, 25)); + + // 6. Translate DOMMatrix with multiply + testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).multiply(new DOMMatrix().translate(25, 25))); + + // 7. Translate DOMMatrix with multiplySelf + testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).multiplySelf(new DOMMatrix().translate(25, 25))); + + // 8. Translate DOMMatrix with preMultiplySelf + testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).preMultiplySelf(new DOMMatrix().translate(25, 25))); }); diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.cpp b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.cpp index 5c831947b6..cc1ba90429 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.cpp +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.cpp @@ -293,6 +293,20 @@ WebIDL::ExceptionOr> DOMMatrix::pre_multiply_self(DO return JS::NonnullGCPtr(*this); } +// https://drafts.fxtf.org/geometry/#dom-dommatrix-translateself +JS::NonnullGCPtr DOMMatrix::translate_self(Optional tx, Optional ty, Optional tz) +{ + // 1. Post-multiply a translation transformation on the current matrix. The 3D translation matrix is described in CSS Transforms. + m_matrix = m_matrix * Gfx::translation_matrix(Vector3 { tx.value_or(0), ty.value_or(0), tz.value_or(0) }); + + // 2. If tz is specified and not 0 or -0, set is 2D of the current matrix to false. + if (tz.has_value() && (tz != 0 || tz != -0)) + m_is_2d = false; + + // 3. Return the current matrix. + return *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 fb54af3643..22dcde9006 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.h +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.h @@ -49,6 +49,7 @@ public: WebIDL::ExceptionOr> multiply_self(DOMMatrixInit other = {}); WebIDL::ExceptionOr> pre_multiply_self(DOMMatrixInit other = {}); + JS::NonnullGCPtr translate_self(Optional tx, Optional ty, Optional tz); JS::NonnullGCPtr invert_self(); private: diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.idl b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.idl index 77192be709..535da9f0ee 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.idl +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.idl @@ -38,7 +38,7 @@ interface DOMMatrix : DOMMatrixReadOnly { // Mutable transform methods 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); + 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); // FIXME: DOMMatrix rotateSelf(optional unrestricted double rotX = 0, optional unrestricted double rotY, optional unrestricted double rotZ); diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.cpp b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.cpp index 880ca19680..8a6504f71d 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-translate +JS::NonnullGCPtr DOMMatrixReadOnly::translate(Optional const& tx, Optional const& ty, Optional const& tz) const +{ + // 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 translateSelf() transformation on result with the arguments tx, ty, tz. + // 3. Return result. + return result->translate_self(tx, ty, tz); +} + // https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-multiply WebIDL::ExceptionOr> DOMMatrixReadOnly::multiply(DOMMatrixInit other) { diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.h b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.h index a7e1408ccb..409374ca3f 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.h +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.h @@ -83,6 +83,7 @@ public: bool is2d() const { return m_is_2d; } bool is_identity() const; + JS::NonnullGCPtr translate(Optional const& tx, Optional const& ty, Optional const& tz) const; WebIDL::ExceptionOr> multiply(DOMMatrixInit other = {}); JS::NonnullGCPtr inverse() const; diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.idl b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.idl index c76c1b9e4e..ed60bf7a97 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.idl +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.idl @@ -39,7 +39,7 @@ interface DOMMatrixReadOnly { readonly attribute boolean isIdentity; // Immutable transform methods - // FIXME: [NewObject] DOMMatrix translate(optional unrestricted double tx = 0, optional unrestricted double ty = 0, optional unrestricted double tz = 0); + [NewObject] DOMMatrix translate(optional unrestricted double tx = 0, optional unrestricted double ty = 0, optional unrestricted double tz = 0); // FIXME: [NewObject] DOMMatrix scale(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: [NewObject] DOMMatrix scaleNonUniform(optional unrestricted double scaleX = 1, optional unrestricted double scaleY = 1); // FIXME: [NewObject] DOMMatrix scale3d(optional unrestricted double scale = 1, optional unrestricted double originX = 0, optional unrestricted double originY = 0, optional unrestricted double originZ = 0);