diff --git a/Tests/LibWeb/Text/expected/geometry/dommatrix-scale.txt b/Tests/LibWeb/Text/expected/geometry/dommatrix-scale.txt new file mode 100644 index 0000000000..00bfd764b3 --- /dev/null +++ b/Tests/LibWeb/Text/expected/geometry/dommatrix-scale.txt @@ -0,0 +1,6 @@ +1. {"a":10,"b":20,"c":60,"d":80,"e":50,"f":60,"m11":10,"m12":20,"m13":0,"m14":0,"m21":60,"m22":80,"m23":0,"m24":0,"m31":0,"m32":0,"m33":3,"m34":0,"m41":50,"m42":60,"m43":0,"m44":1,"is2D":false,"isIdentity":false} +2. {"a":10,"b":20,"c":60,"d":80,"e":50,"f":60,"m11":10,"m12":20,"m13":0,"m14":0,"m21":60,"m22":80,"m23":0,"m24":0,"m31":0,"m32":0,"m33":3,"m34":0,"m41":50,"m42":60,"m43":0,"m44":1,"is2D":false,"isIdentity":false} +3. {"a":10,"b":20,"c":100,"d":120,"e":130,"f":140,"m11":10,"m12":20,"m13":30,"m14":40,"m21":100,"m22":120,"m23":140,"m24":160,"m31":270,"m32":300,"m33":330,"m34":360,"m41":130,"m42":140,"m43":150,"m44":160,"is2D":false,"isIdentity":false} +4. {"a":50,"b":100,"c":150,"d":200,"e":-470,"f":-740,"m11":50,"m12":100,"m13":0,"m14":0,"m21":150,"m22":200,"m23":0,"m24":0,"m31":0,"m32":0,"m33":5,"m34":0,"m41":-470,"m42":-740,"m43":-8,"m44":1,"is2D":false,"isIdentity":false} +5. {"a":50,"b":100,"c":150,"d":200,"e":-470,"f":-740,"m11":50,"m12":100,"m13":0,"m14":0,"m21":150,"m22":200,"m23":0,"m24":0,"m31":0,"m32":0,"m33":5,"m34":0,"m41":-470,"m42":-740,"m43":-8,"m44":1,"is2D":false,"isIdentity":false} +6. {"a":50,"b":100,"c":250,"d":300,"e":-1350,"f":-1700,"m11":50,"m12":100,"m13":150,"m14":200,"m21":250,"m22":300,"m23":350,"m24":400,"m31":450,"m32":500,"m33":550,"m34":600,"m41":-1350,"m42":-1700,"m43":-2050,"m44":-2400,"is2D":false,"isIdentity":false} diff --git a/Tests/LibWeb/Text/input/geometry/dommatrix-scale.html b/Tests/LibWeb/Text/input/geometry/dommatrix-scale.html new file mode 100644 index 0000000000..353aba05a7 --- /dev/null +++ b/Tests/LibWeb/Text/input/geometry/dommatrix-scale.html @@ -0,0 +1,27 @@ + + diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.cpp b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.cpp index ccad4fe208..5d3a3f219b 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.cpp +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.cpp @@ -326,6 +326,51 @@ JS::NonnullGCPtr DOMMatrix::translate_self(Optional tx, Optio return *this; } +// https://drafts.fxtf.org/geometry/#dom-dommatrix-scaleself +JS::NonnullGCPtr DOMMatrix::scale_self(Optional scale_x, Optional scale_y, Optional scale_z, Optional origin_x, Optional origin_y, Optional origin_z) +{ + // 1. Perform a translateSelf() transformation on the current matrix with the arguments originX, originY, originZ. + translate_self(origin_x, origin_y, origin_z); + + // 2. If scaleY is missing, set scaleY to the value of scaleX. + if (!scale_y.has_value()) + scale_y = scale_x.value_or(1); + + // 3. Post-multiply a non-uniform scale transformation on the current matrix. The 3D scale matrix is described in CSS Transforms with sx = scaleX, sy = scaleY and sz = scaleZ. [CSS3-TRANSFORMS] + m_matrix = m_matrix * Gfx::scale_matrix(Vector3 { scale_x.value_or(1), scale_y.value(), scale_z.value_or(1) }); + + // 4. Negate originX, originY and originZ. + // 5. Perform a translateSelf() transformation on the current matrix with the arguments originX, originY, originZ. + translate_self(-origin_x.value_or(0), -origin_y.value_or(0), -origin_z.value_or(0)); + + // 6. If scaleZ is not 1, set is 2D of the current matrix to false. + if (scale_z != 1) + m_is_2d = false; + + // 7. Return the current matrix. + return *this; +} + +// https://drafts.fxtf.org/geometry/#dom-dommatrix-scale3dself +JS::NonnullGCPtr DOMMatrix::scale3d_self(Optional scale, Optional origin_x, Optional origin_y, Optional origin_z) +{ + // 1. Apply a translateSelf() transformation to the current matrix with the arguments originX, originY, originZ. + translate_self(origin_x, origin_y, origin_z); + + // 2. Post-multiply a uniform 3D scale transformation (m11 = m22 = m33 = scale) on the current matrix. The 3D scale matrix is described in CSS Transforms with sx = sy = sz = scale. [CSS3-TRANSFORMS] + m_matrix = m_matrix * Gfx::scale_matrix(Vector3 { scale.value_or(1), scale.value_or(1), scale.value_or(1) }); + + // 3. Apply a translateSelf() transformation to the current matrix with the arguments -originX, -originY, -originZ. + translate_self(-origin_x.value_or(0), -origin_y.value_or(0), -origin_z.value_or(0)); + + // 4. If scale is not 1, set is 2D of the current matrix to false. + if (scale != 1) + m_is_2d = false; + + // 5. Return the current matrix. + return *this; +} + // https://drafts.fxtf.org/geometry/#dom-dommatrix-skewxself JS::NonnullGCPtr DOMMatrix::skew_x_self(double sx) { diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.h b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.h index 7d99a50305..6f9501b939 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.h +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.h @@ -52,6 +52,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 scale_self(Optional scale_x, Optional scale_y, Optional scale_z, Optional origin_x, Optional origin_y, Optional origin_z); + JS::NonnullGCPtr scale3d_self(Optional scale, Optional origin_x, Optional origin_y, Optional origin_z); JS::NonnullGCPtr skew_x_self(double sx = 0); JS::NonnullGCPtr skew_y_self(double sy = 0); JS::NonnullGCPtr invert_self(); diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.idl b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.idl index 9f4cfd9651..20f66bea45 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrix.idl +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrix.idl @@ -39,8 +39,8 @@ interface DOMMatrix : DOMMatrixReadOnly { DOMMatrix multiplySelf(optional DOMMatrixInit other = {}); DOMMatrix preMultiplySelf(optional DOMMatrixInit other = {}); 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); + 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); + 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); // 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); diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.cpp b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.cpp index 4f59e314a0..a832cdf998 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.cpp +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.cpp @@ -270,6 +270,43 @@ JS::NonnullGCPtr DOMMatrixReadOnly::translate(Optional const& return result->translate_self(tx, ty, tz); } +// https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-scale +JS::NonnullGCPtr DOMMatrixReadOnly::scale(Optional scale_x, Optional scale_y, Optional scale_z, Optional origin_x, Optional origin_y, Optional origin_z) +{ + // 1. If scaleY is missing, set scaleY to the value of scaleX. + if (!scale_y.has_value()) + scale_y = scale_x; + + // 2. 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); + + // 3. Perform a scaleSelf() transformation on result with the arguments scaleX, scaleY, scaleZ, originX, originY, originZ. + // 4. Return result. + return result->scale_self(scale_x, scale_y, scale_z, origin_x, origin_y, origin_z); +} + +// https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-scalenonuniform +JS::NonnullGCPtr DOMMatrixReadOnly::scale_non_uniform(Optional scale_x, Optional scale_y) +{ + // 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 scaleSelf() transformation on result with the arguments scaleX, scaleY, 1, 0, 0, 0. + // 3. Return result. + return result->scale_self(scale_x, scale_y, 1, 0, 0, 0); +} + +// https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-scale3d +JS::NonnullGCPtr DOMMatrixReadOnly::scale3d(Optional scale, Optional origin_x, Optional origin_y, Optional origin_z) +{ + // 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 scale3dSelf() transformation on result with the arguments scale, originX, originY, originZ. + // 3. Return result. + return result->scale3d_self(scale, origin_x, origin_y, origin_z); +} + // https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-skewx JS::NonnullGCPtr DOMMatrixReadOnly::skew_x(double sx) const { diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.h b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.h index 9bd17793ea..1cb3017bec 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.h +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.h @@ -86,6 +86,9 @@ public: bool is_identity() const; JS::NonnullGCPtr translate(Optional const& tx, Optional const& ty, Optional const& tz) const; + JS::NonnullGCPtr scale(Optional scale_x, Optional scale_y, Optional scale_z, Optional origin_x, Optional origin_y, Optional origin_z); + JS::NonnullGCPtr scale_non_uniform(Optional scale_x, Optional scale_y); + JS::NonnullGCPtr scale3d(Optional scale, Optional origin_x, Optional origin_y, Optional origin_z); JS::NonnullGCPtr skew_x(double sx = 0) const; JS::NonnullGCPtr skew_y(double sy = 0) const; WebIDL::ExceptionOr> multiply(DOMMatrixInit other = {}); diff --git a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.idl b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.idl index 6a5651bbb1..772a8596b0 100644 --- a/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.idl +++ b/Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.idl @@ -40,9 +40,9 @@ interface DOMMatrixReadOnly { // Immutable transform methods [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); + [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); + [NewObject] DOMMatrix scaleNonUniform(optional unrestricted double scaleX = 1, optional unrestricted double scaleY = 1); + [NewObject] DOMMatrix scale3d(optional unrestricted double scale = 1, optional unrestricted double originX = 0, optional unrestricted double originY = 0, optional unrestricted double originZ = 0); // 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);