Просмотр исходного кода

LibWeb: Fix DOMMatrix fromMatrix to use complete DOMMatrixInit struct

DOMMatrix fromMatrix was using create_from_dom_matrix_2d_init to make
a DOMMatrix for it's init struct this is wrong because only the 2D
params of the DOMMatrix are put into the new matrix. I have added
a non 2D version of that function that takes the full DOMMatrixInit
so now fromMatrix works correctly again. I also have added some
text tests to test if it works correctly.

I split the dommatrix.html text tests into multiple files because that
file was becoming to big so now every sub function is a seperate file.
Bastiaan van der Plaat 1 год назад
Родитель
Сommit
67f6a9ee12

+ 4 - 0
Tests/LibWeb/Text/expected/geometry/dommatrix-create.txt

@@ -0,0 +1,4 @@
+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":10,"b":20,"c":50,"d":60,"e":130,"f":140,"m11":10,"m12":20,"m13":30,"m14":40,"m21":50,"m22":60,"m23":70,"m24":80,"m31":90,"m32":100,"m33":110,"m34":120,"m41":130,"m42":140,"m43":150,"m44":160,"is2D":false,"isIdentity":false}
+4. {"a":10,"b":20,"c":50,"d":60,"e":130,"f":140,"m11":10,"m12":20,"m13":30,"m14":40,"m21":50,"m22":60,"m23":70,"m24":80,"m31":90,"m32":100,"m33":110,"m34":120,"m41":130,"m42":140,"m43":150,"m44":160,"is2D":false,"isIdentity":false}

+ 4 - 0
Tests/LibWeb/Text/expected/geometry/dommatrix-flip.txt

@@ -0,0 +1,4 @@
+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":50,"d":60,"e":130,"f":140,"m11":-10,"m12":-20,"m13":-30,"m14":-40,"m21":50,"m22":60,"m23":70,"m24":80,"m31":90,"m32":100,"m33":110,"m34":120,"m41":130,"m42":140,"m43":150,"m44":160,"is2D":false,"isIdentity":false}
+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. {"a":10,"b":20,"c":-50,"d":-60,"e":130,"f":140,"m11":10,"m12":20,"m13":30,"m14":40,"m21":-50,"m22":-60,"m23":-70,"m24":-80,"m31":90,"m32":100,"m33":110,"m34":120,"m41":130,"m42":140,"m43":150,"m44":160,"is2D":false,"isIdentity":false}

+ 8 - 0
Tests/LibWeb/Text/expected/geometry/dommatrix-skew.txt

@@ -0,0 +1,8 @@
+1. {"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}
+2. {"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}
+3. {"a":10,"b":20,"c":53.63970234266203,"d":67.27940468532405,"e":130,"f":140,"m11":10,"m12":20,"m13":30,"m14":40,"m21":53.63970234266203,"m22":67.27940468532405,"m23":80.91910702798607,"m24":94.55880937064809,"m31":90,"m32":100,"m33":110,"m34":120,"m41":130,"m42":140,"m43":150,"m44":160,"is2D":false,"isIdentity":false}
+4. {"a":10,"b":20,"c":53.63970234266203,"d":67.27940468532405,"e":130,"f":140,"m11":10,"m12":20,"m13":30,"m14":40,"m21":53.63970234266203,"m22":67.27940468532405,"m23":80.91910702798607,"m24":94.55880937064809,"m31":90,"m32":100,"m33":110,"m34":120,"m41":130,"m42":140,"m43":150,"m44":160,"is2D":false,"isIdentity":false}
+5. {"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}
+6. {"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}
+7. {"a":28.19851171331012,"b":41.838214055972145,"c":50,"d":60,"e":130,"f":140,"m11":28.19851171331012,"m12":41.838214055972145,"m13":55.477916398634164,"m14":69.11761874129618,"m21":50,"m22":60,"m23":70,"m24":80,"m31":90,"m32":100,"m33":110,"m34":120,"m41":130,"m42":140,"m43":150,"m44":160,"is2D":false,"isIdentity":false}
+8. {"a":28.19851171331012,"b":41.838214055972145,"c":50,"d":60,"e":130,"f":140,"m11":28.19851171331012,"m12":41.838214055972145,"m13":55.477916398634164,"m14":69.11761874129618,"m21":50,"m22":60,"m23":70,"m24":80,"m31":90,"m32":100,"m33":110,"m34":120,"m41":130,"m42":140,"m43":150,"m44":160,"is2D":false,"isIdentity":false}

+ 6 - 0
Tests/LibWeb/Text/expected/geometry/dommatrix-translate.txt

@@ -0,0 +1,6 @@
+1. {"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}
+2. {"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}
+3. {"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}
+4. {"a":10,"b":20,"c":50,"d":60,"e":3130,"f":4140,"m11":10,"m12":20,"m13":30,"m14":40,"m21":50,"m22":60,"m23":70,"m24":80,"m31":90,"m32":100,"m33":110,"m34":120,"m41":3130,"m42":4140,"m43":5150,"m44":6160,"is2D":false,"isIdentity":false}
+5. {"a":10,"b":20,"c":50,"d":60,"e":3130,"f":4140,"m11":10,"m12":20,"m13":30,"m14":40,"m21":50,"m22":60,"m23":70,"m24":80,"m31":90,"m32":100,"m33":110,"m34":120,"m41":3130,"m42":4140,"m43":5150,"m44":6160,"is2D":false,"isIdentity":false}
+6. {"a":2010,"b":2020,"c":4050,"d":4060,"e":8130,"f":8140,"m11":2010,"m12":2020,"m13":30,"m14":40,"m21":4050,"m22":4060,"m23":70,"m24":80,"m31":6090,"m32":6100,"m33":110,"m34":120,"m41":8130,"m42":8140,"m43":150,"m44":160,"is2D":false,"isIdentity":false}

+ 0 - 14
Tests/LibWeb/Text/expected/geometry/dommatrix.txt

@@ -1,14 +0,0 @@
-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}
-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}
-13. {"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}
-14. {"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}

+ 21 - 0
Tests/LibWeb/Text/input/geometry/dommatrix-create.html

@@ -0,0 +1,21 @@
+<script src="../include.js"></script>
+<script>
+    test(() => {
+        let testCounter = 1;
+        function testPart(part) {
+            println(`${testCounter++}. ${JSON.stringify(part())}`);
+        }
+
+        // 1. Creating a DOMMatrix
+        testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]));
+
+        // 2. Creating a DOMMatrix with fromMatrix
+        testPart(() => DOMMatrix.fromMatrix({ a: 10, b: 20, c: 30, d: 40, e: 50, f: 60 }));
+
+        // 3. Creating a DOMMatrix
+        testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]));
+
+        // 4. Creating a DOMMatrix with fromMatrix
+        testPart(() => DOMMatrix.fromMatrix({ m11: 10, m12: 20, m13: 30, m14: 40, m21: 50, m22: 60, m23: 70, m24: 80, m31: 90, m32: 100, m33: 110, m34: 120, m41: 130, m42: 140, m43: 150, m44: 160 }));
+    });
+</script>

+ 21 - 0
Tests/LibWeb/Text/input/geometry/dommatrix-flip.html

@@ -0,0 +1,21 @@
+<script src="../include.js"></script>
+<script>
+    test(() => {
+        let testCounter = 1;
+        function testPart(part) {
+            println(`${testCounter++}. ${JSON.stringify(part())}`);
+        }
+
+        // 1. Flip X DOMMatrix
+        testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).flipX());
+
+        // 2. Flip X DOMMatrix
+        testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]).flipX());
+
+        // 2. Flip Y DOMMatrix
+        testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).flipY());
+
+        // 3. Flip Y DOMMatrix
+        testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]).flipY());
+    });
+</script>

+ 33 - 0
Tests/LibWeb/Text/input/geometry/dommatrix-skew.html

@@ -0,0 +1,33 @@
+<script src="../include.js"></script>
+<script>
+    test(() => {
+        let testCounter = 1;
+        function testPart(part) {
+            println(`${testCounter++}. ${JSON.stringify(part())}`);
+        }
+
+        // 1. Skew X DOMMatrix
+        testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).skewXSelf(10));
+
+        // 2. Skew X DOMMatrix with multiply
+        testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).multiply(new DOMMatrix().skewX(10)));
+
+        // 3. Skew X DOMMatrix
+        testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]).skewXSelf(20));
+
+        // 4. Skew X DOMMatrix with multiply
+        testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]).multiply(new DOMMatrix().skewX(20)));
+
+        // 5. Skew Y DOMMatrix
+        testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).skewYSelf(10));
+
+        // 6. Skew Y DOMMatrix with multiply
+        testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).multiply(new DOMMatrix().skewY(10)));
+
+        // 7. Skew Y DOMMatrix
+        testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]).skewYSelf(20));
+
+        // 8. Skew Y DOMMatrix with multiply
+        testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]).multiply(new DOMMatrix().skewY(20)));
+    });
+</script>

+ 27 - 0
Tests/LibWeb/Text/input/geometry/dommatrix-translate.html

@@ -0,0 +1,27 @@
+<script src="../include.js"></script>
+<script>
+    test(() => {
+        let testCounter = 1;
+        function testPart(part) {
+            println(`${testCounter++}. ${JSON.stringify(part())}`);
+        }
+
+        // 1. Translate DOMMatrix
+        testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).translateSelf(25, 25));
+
+        // 2. Translate DOMMatrix with multiply
+        testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).multiply(new DOMMatrix().translate(25, 25)));
+
+        // 3. Translate DOMMatrix with preMultiplySelf
+        testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).preMultiplySelf(new DOMMatrix().translate(25, 25)));
+
+        // 4. Translate DOMMatrix
+        testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]).translateSelf(50, 50));
+
+        // 5. Translate DOMMatrix with multiply
+        testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]).multiply(new DOMMatrix().translate(50, 50)));
+
+        // 6. Translate DOMMatrix with preMultiplySelf
+        testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]).preMultiplySelf(new DOMMatrix().translate(50, 50)));
+    });
+</script>

+ 0 - 51
Tests/LibWeb/Text/input/geometry/dommatrix.html

@@ -1,51 +0,0 @@
-<script src="../include.js"></script>
-<script>
-    test(() => {
-        let testCounter = 1;
-        function testPart(part) {
-            println(`${testCounter++}. ${JSON.stringify(part())}`);
-        }
-
-        // 1. Creating a DOMMatrix
-        testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]));
-
-        // 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])));
-
-        // 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)));
-
-        // 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)));
-
-        // 13. Flip X DOMMatrix
-        testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).flipX());
-
-        // 14. Flip Y DOMMatrix
-        testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).flipY());
-    });
-</script>

+ 27 - 3
Userland/Libraries/LibWeb/Geometry/DOMMatrix.cpp

@@ -46,6 +46,25 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> DOMMatrix::create_from_dom_matr
     return realm.heap().allocate<DOMMatrix>(realm, realm, init.m11.value(), init.m12.value(), init.m21.value(), init.m22.value(), init.m41.value(), init.m42.value());
 }
 
+// https://drafts.fxtf.org/geometry/#create-a-dommatrix-from-the-dictionary
+WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> DOMMatrix::create_from_dom_matrix_init(JS::Realm& realm, DOMMatrixInit& init)
+{
+    // 1. Validate and fixup other.
+    TRY(validate_and_fixup_dom_matrix_init(init));
+
+    // 2. If the is2D dictionary member of other is true.
+    if (init.is2d.has_value() && init.is2d.value()) {
+        // Return the result of invoking create a 2d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with a sequence of numbers, the values being the 6 elements m11, m12, m21, m22, m41 and m42 of other in the given order.
+        return realm.heap().allocate<DOMMatrix>(realm, realm, init.m11.value(), init.m12.value(), init.m21.value(), init.m22.value(), init.m41.value(), init.m42.value());
+    }
+
+    // Otherwise, Return the result of invoking create a 3d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with a sequence of numbers, the values being the 16 elements m11, m12, m13, ..., m44 of other in the given order.
+    return realm.heap().allocate<DOMMatrix>(realm, realm, init.m11.value(), init.m12.value(), init.m13, init.m14,
+        init.m21.value(), init.m22.value(), init.m23, init.m24,
+        init.m31, init.m32, init.m33, init.m34,
+        init.m41.value(), init.m42.value(), init.m43, init.m44);
+}
+
 JS::NonnullGCPtr<DOMMatrix> DOMMatrix::create_from_dom_matrix_read_only(JS::Realm& realm, DOMMatrixReadOnly const& read_only_matrix)
 {
     return realm.heap().allocate<DOMMatrix>(realm, realm, read_only_matrix);
@@ -56,6 +75,11 @@ DOMMatrix::DOMMatrix(JS::Realm& realm, double m11, double m12, double m21, doubl
 {
 }
 
+DOMMatrix::DOMMatrix(JS::Realm& realm, double m11, double m12, double m13, double m14, double m21, double m22, double m23, double m24, double m31, double m32, double m33, double m34, double m41, double m42, double m43, double m44)
+    : DOMMatrixReadOnly(realm, m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44)
+{
+}
+
 DOMMatrix::DOMMatrix(JS::Realm& realm, Optional<Variant<String, Vector<double>>> const& init)
     : DOMMatrixReadOnly(realm, init)
 {
@@ -77,7 +101,7 @@ void DOMMatrix::initialize(JS::Realm& realm)
 // https://drafts.fxtf.org/geometry/#dom-dommatrix-frommatrix
 WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> DOMMatrix::from_matrix(JS::VM& vm, DOMMatrixInit other)
 {
-    return create_from_dom_matrix_2d_init(*vm.current_realm(), other);
+    return create_from_dom_matrix_init(*vm.current_realm(), other);
 }
 
 // https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-m11
@@ -258,7 +282,7 @@ void DOMMatrix::set_f(double value)
 WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> DOMMatrix::multiply_self(DOMMatrixInit other)
 {
     // 1. Let otherObject be the result of invoking create a DOMMatrix from the dictionary other.
-    auto other_object = TRY(DOMMatrix::create_from_dom_matrix_2d_init(realm(), other));
+    auto other_object = TRY(DOMMatrix::create_from_dom_matrix_init(realm(), other));
 
     // 2. The otherObject matrix gets post-multiplied to the current matrix.
     m_matrix = m_matrix * other_object->m_matrix;
@@ -275,7 +299,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> DOMMatrix::multiply_self(DOMMat
 WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> DOMMatrix::pre_multiply_self(DOMMatrixInit other)
 {
     // 1. Let otherObject be the result of invoking create a DOMMatrix from the dictionary other.
-    auto other_object = TRY(DOMMatrix::create_from_dom_matrix_2d_init(realm(), other));
+    auto other_object = TRY(DOMMatrix::create_from_dom_matrix_init(realm(), other));
 
     // 2. The otherObject matrix gets pre-multiplied to the current matrix.
     m_matrix = other_object->m_matrix * m_matrix;

+ 2 - 0
Userland/Libraries/LibWeb/Geometry/DOMMatrix.h

@@ -18,6 +18,7 @@ class DOMMatrix : public DOMMatrixReadOnly {
 public:
     static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> construct_impl(JS::Realm&, Optional<Variant<String, Vector<double>>> const& init);
     static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> create_from_dom_matrix_2d_init(JS::Realm&, DOMMatrix2DInit& init);
+    static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> create_from_dom_matrix_init(JS::Realm&, DOMMatrixInit& init);
     static JS::NonnullGCPtr<DOMMatrix> create_from_dom_matrix_read_only(JS::Realm&, DOMMatrixReadOnly const& read_only_matrix);
 
     virtual ~DOMMatrix() override;
@@ -57,6 +58,7 @@ public:
 
 private:
     DOMMatrix(JS::Realm&, double m11, double m12, double m21, double m22, double m41, double m42);
+    DOMMatrix(JS::Realm&, double m11, double m12, double m13, double m14, double m21, double m22, double m23, double m24, double m31, double m32, double m33, double m34, double m41, double m42, double m43, double m44);
     DOMMatrix(JS::Realm&, Optional<Variant<String, Vector<double>>> const& init);
     DOMMatrix(JS::Realm&, DOMMatrixReadOnly const& read_only_matrix);
 

+ 20 - 1
Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.cpp

@@ -48,6 +48,25 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrixReadOnly>> DOMMatrixReadOnly::crea
     return realm.heap().allocate<DOMMatrixReadOnly>(realm, realm, init.m11.value(), init.m12.value(), init.m21.value(), init.m22.value(), init.m41.value(), init.m42.value());
 }
 
+// https://drafts.fxtf.org/geometry/#create-a-dommatrixreadonly-from-the-dictionary
+WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrixReadOnly>> DOMMatrixReadOnly::create_from_dom_matrix_init(JS::Realm& realm, DOMMatrixInit& init)
+{
+    // 1. Validate and fixup other.
+    TRY(validate_and_fixup_dom_matrix_init(init));
+
+    // 2. If the is2D dictionary member of other is true.
+    if (init.is2d.has_value() && init.is2d.value()) {
+        // Return the result of invoking create a 2d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with a sequence of numbers, the values being the 6 elements m11, m12, m21, m22, m41 and m42 of other in the given order.
+        return realm.heap().allocate<DOMMatrix>(realm, realm, init.m11.value(), init.m12.value(), init.m21.value(), init.m22.value(), init.m41.value(), init.m42.value());
+    }
+
+    // Otherwise, Return the result of invoking create a 3d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with a sequence of numbers, the values being the 16 elements m11, m12, m13, ..., m44 of other in the given order.
+    return realm.heap().allocate<DOMMatrix>(realm, realm, init.m11.value(), init.m12.value(), init.m13, init.m14,
+        init.m21.value(), init.m22.value(), init.m23, init.m24,
+        init.m31, init.m32, init.m33, init.m34,
+        init.m41.value(), init.m42.value(), init.m43, init.m44);
+}
+
 DOMMatrixReadOnly::DOMMatrixReadOnly(JS::Realm& realm, double m11, double m12, double m21, double m22, double m41, double m42)
     : Bindings::PlatformObject(realm)
 {
@@ -184,7 +203,7 @@ void DOMMatrixReadOnly::initialize_from_create_3d_matrix(double m11, double m12,
 // https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-frommatrix
 WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrixReadOnly>> DOMMatrixReadOnly::from_matrix(JS::VM& vm, DOMMatrixInit& other)
 {
-    return create_from_dom_matrix_2d_init(*vm.current_realm(), other);
+    return create_from_dom_matrix_init(*vm.current_realm(), other);
 }
 
 // https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-isidentity

+ 1 - 0
Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.h

@@ -51,6 +51,7 @@ class DOMMatrixReadOnly : public Bindings::PlatformObject {
 public:
     static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrixReadOnly>> construct_impl(JS::Realm&, Optional<Variant<String, Vector<double>>> const& init);
     static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrixReadOnly>> create_from_dom_matrix_2d_init(JS::Realm&, DOMMatrix2DInit& init);
+    static WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrixReadOnly>> create_from_dom_matrix_init(JS::Realm&, DOMMatrixInit& init);
 
     virtual ~DOMMatrixReadOnly() override;