diff --git a/Tests/LibWeb/Text/expected/geometry/dommatrix.txt b/Tests/LibWeb/Text/expected/geometry/dommatrix.txt index 26a66f5c36..146a39da14 100644 --- a/Tests/LibWeb/Text/expected/geometry/dommatrix.txt +++ b/Tests/LibWeb/Text/expected/geometry/dommatrix.txt @@ -6,3 +6,7 @@ 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} +9. {"a":10,"b":20,"c":31.76326980708465,"d":43.5265396141693,"e":50,"f":60,"m11":10,"m12":20,"m13":0,"m14":0,"m21":31.76326980708465,"m22":43.5265396141693,"m23":0,"m24":0,"m31":0,"m32":0,"m33":1,"m34":0,"m41":50,"m42":60,"m43":0,"m44":1,"is2D":true,"isIdentity":false} +10. {"a":10,"b":20,"c":31.76326980708465,"d":43.5265396141693,"e":50,"f":60,"m11":10,"m12":20,"m13":0,"m14":0,"m21":31.76326980708465,"m22":43.5265396141693,"m23":0,"m24":0,"m31":0,"m32":0,"m33":1,"m34":0,"m41":50,"m42":60,"m43":0,"m44":1,"is2D":true,"isIdentity":false} +11. {"a":15.289809421253949,"b":27.0530792283386,"c":30,"d":40,"e":50,"f":60,"m11":15.289809421253949,"m12":27.0530792283386,"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} +12. {"a":15.289809421253949,"b":27.0530792283386,"c":30,"d":40,"e":50,"f":60,"m11":15.289809421253949,"m12":27.0530792283386,"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} diff --git a/Tests/LibWeb/Text/input/geometry/dommatrix.html b/Tests/LibWeb/Text/input/geometry/dommatrix.html index df0526efec..981bc2d262 100644 --- a/Tests/LibWeb/Text/input/geometry/dommatrix.html +++ b/Tests/LibWeb/Text/input/geometry/dommatrix.html @@ -29,5 +29,17 @@ // 8. Translate DOMMatrix with preMultiplySelf testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).preMultiplySelf(new DOMMatrix().translate(25, 25))); + + // 9. Skew X DOMMatrix + testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).skewXSelf(10)); + + // 10. Skew X DOMMatrix with multiply + testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).multiply(new DOMMatrix().skewX(10))); + + // 11. Skew Y DOMMatrix + testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).skewYSelf(10)); + + // 12. Skew Y DOMMatrix with multiply + testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).multiply(new DOMMatrix().skewY(10))); }); diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.cpp b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.cpp index cc1ba90429..e5a5d51bf1 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.cpp +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2023, Luke Wilde + * Copyright (c) 2023, Bastiaan van der Plaat * * SPDX-License-Identifier: BSD-2-Clause */ @@ -307,6 +308,38 @@ JS::NonnullGCPtr DOMMatrix::translate_self(Optional tx, Optio return *this; } +// https://drafts.fxtf.org/geometry/#dom-dommatrix-skewxself +JS::NonnullGCPtr DOMMatrix::skew_x_self(double sx) +{ + // 1. Post-multiply a skewX transformation on the current matrix by the specified angle sx in degrees. The 2D skewX matrix is described in CSS Transforms with alpha = sx in degrees. [CSS3-TRANSFORMS] + // clang-format off + Gfx::DoubleMatrix4x4 skew_matrix = { 1, tan(sx * M_PI / 180.0), 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 }; + // clang-format on + m_matrix = m_matrix * skew_matrix; + + // 3. Return the current matrix. + return *this; +} + +// https://drafts.fxtf.org/geometry/#dom-dommatrix-skewyself +JS::NonnullGCPtr DOMMatrix::skew_y_self(double sy) +{ + // 1. Post-multiply a skewX transformation on the current matrix by the specified angle sy in degrees. The 2D skewY matrix is described in CSS Transforms with beta = sy in degrees. [CSS3-TRANSFORMS] + // clang-format off + Gfx::DoubleMatrix4x4 skew_matrix = { 1, 0, 0, 0, + tan(sy * M_PI / 180.0), 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 }; + // clang-format on + m_matrix = m_matrix * skew_matrix; + + // 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 22dcde9006..6c840b7e3a 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.h +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2023, Luke Wilde + * Copyright (c) 2023, Bastiaan van der Plaat * * SPDX-License-Identifier: BSD-2-Clause */ @@ -50,6 +51,8 @@ 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 skew_x_self(double sx = 0); + JS::NonnullGCPtr skew_y_self(double sy = 0); JS::NonnullGCPtr invert_self(); private: diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.idl b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.idl index 535da9f0ee..9f4cfd9651 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.idl +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.idl @@ -44,8 +44,8 @@ interface DOMMatrix : DOMMatrixReadOnly { // FIXME: DOMMatrix rotateSelf(optional unrestricted double rotX = 0, optional unrestricted double rotY, optional unrestricted double rotZ); // FIXME: DOMMatrix rotateFromVectorSelf(optional unrestricted double x = 0, optional unrestricted double y = 0); // FIXME: DOMMatrix rotateAxisAngleSelf(optional unrestricted double x = 0, optional unrestricted double y = 0, optional unrestricted double z = 0, optional unrestricted double angle = 0); - // FIXME: DOMMatrix skewXSelf(optional unrestricted double sx = 0); - // FIXME: DOMMatrix skewYSelf(optional unrestricted double sy = 0); + DOMMatrix skewXSelf(optional unrestricted double sx = 0); + DOMMatrix skewYSelf(optional unrestricted double sy = 0); DOMMatrix invertSelf(); // FIXME: [Exposed=Window] DOMMatrix setMatrixValue(DOMString transformList); diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.cpp b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.cpp index 8a6504f71d..948f3229c3 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.cpp +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2023, Luke Wilde + * Copyright (c) 2023, Bastiaan van der Plaat * * SPDX-License-Identifier: BSD-2-Clause */ @@ -250,6 +251,28 @@ JS::NonnullGCPtr DOMMatrixReadOnly::translate(Optional const& return result->translate_self(tx, ty, tz); } +// https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-skewx +JS::NonnullGCPtr DOMMatrixReadOnly::skew_x(double sx) 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 skewXSelf() transformation on result with the argument sx. + // 3. Return result. + return result->skew_x_self(sx); +} + +// https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-skewy +JS::NonnullGCPtr DOMMatrixReadOnly::skew_y(double sy) 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 skewYSelf() transformation on result with the argument sy. + // 3. Return result. + return result->skew_y_self(sy); +} + // 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 409374ca3f..6b7d2e5769 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.h +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2023, Luke Wilde + * Copyright (c) 2023, Bastiaan van der Plaat * * SPDX-License-Identifier: BSD-2-Clause */ @@ -84,6 +85,8 @@ public: bool is_identity() const; JS::NonnullGCPtr translate(Optional const& tx, Optional const& ty, Optional const& tz) const; + JS::NonnullGCPtr skew_x(double sx = 0) const; + JS::NonnullGCPtr skew_y(double sy = 0) 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 ed60bf7a97..2b25fad8de 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.idl +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.idl @@ -46,8 +46,8 @@ interface DOMMatrixReadOnly { // FIXME: [NewObject] DOMMatrix rotate(optional unrestricted double rotX = 0, optional unrestricted double rotY, optional unrestricted double rotZ); // FIXME: [NewObject] DOMMatrix rotateFromVector(optional unrestricted double x = 0, optional unrestricted double y = 0); // 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); + [NewObject] DOMMatrix skewX(optional unrestricted double sx = 0); + [NewObject] DOMMatrix skewY(optional unrestricted double sy = 0); [NewObject] DOMMatrix multiply(optional DOMMatrixInit other = {}); // FIXME: [NewObject] DOMMatrix flipX(); // FIXME: [NewObject] DOMMatrix flipY();