Serenity Operating System
at master 495 lines 22 kB view raw
1/* 2 * Copyright (c) 2023, Luke Wilde <lukew@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <LibWeb/Bindings/Intrinsics.h> 8#include <LibWeb/Geometry/DOMMatrix.h> 9#include <LibWeb/Geometry/DOMMatrixReadOnly.h> 10#include <LibWeb/WebIDL/ExceptionOr.h> 11 12namespace Web::Geometry { 13 14WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrixReadOnly>> DOMMatrixReadOnly::construct_impl(JS::Realm& realm, Optional<Variant<String, Vector<double>>> const& init) 15{ 16 auto& vm = realm.vm(); 17 18 // https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-dommatrixreadonly 19 if (init.has_value()) { 20 // -> Otherwise 21 // Throw a TypeError exception. 22 // The only condition where this can be met is with a sequence type which doesn't have exactly 6 or 16 elements. 23 if (auto* double_sequence = init.value().get_pointer<Vector<double>>(); double_sequence && (double_sequence->size() != 6 && double_sequence->size() != 16)) 24 return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, TRY_OR_THROW_OOM(vm, String::formatted("Sequence must contain exactly 6 or 16 elements, got {} element(s)", double_sequence->size())) }; 25 } 26 27 return realm.heap().allocate<DOMMatrixReadOnly>(realm, realm, init).release_allocated_value_but_fixme_should_propagate_errors(); 28} 29 30// https://drafts.fxtf.org/geometry/#create-a-dommatrixreadonly-from-the-2d-dictionary 31WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrixReadOnly>> DOMMatrixReadOnly::create_from_dom_matrix_2d_init(JS::Realm& realm, DOMMatrix2DInit& init) 32{ 33 // 1. Validate and fixup (2D) other. 34 TRY(validate_and_fixup_dom_matrix_2d_init(init)); 35 36 // These should all have values after calling `validate_and_fixup_dom_matrix_2d_init` 37 VERIFY(init.m11.has_value()); 38 VERIFY(init.m12.has_value()); 39 VERIFY(init.m21.has_value()); 40 VERIFY(init.m22.has_value()); 41 VERIFY(init.m41.has_value()); 42 VERIFY(init.m42.has_value()); 43 44 // 2. Return the result of invoking create a 2d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with a sequence of numbers, 45 // the values being the 6 elements m11, m12, m21, m22, m41 and m42 of other in the given order. 46 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()).release_allocated_value_but_fixme_should_propagate_errors(); 47} 48 49DOMMatrixReadOnly::DOMMatrixReadOnly(JS::Realm& realm, double m11, double m12, double m21, double m22, double m41, double m42) 50 : Bindings::PlatformObject(realm) 51{ 52 initialize_from_create_2d_matrix(m11, m12, m21, m22, m41, m42); 53} 54 55DOMMatrixReadOnly::DOMMatrixReadOnly(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) 56 : Bindings::PlatformObject(realm) 57{ 58 initialize_from_create_3d_matrix(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44); 59} 60 61DOMMatrixReadOnly::DOMMatrixReadOnly(JS::Realm& realm, Optional<Variant<String, Vector<double>>> const& init) 62 : Bindings::PlatformObject(realm) 63{ 64 // https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-dommatrixreadonly 65 // -> If init is omitted 66 if (!init.has_value()) { 67 // Return the result of invoking create a 2d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with the sequence [1, 0, 0, 1, 0, 0]. 68 initialize_from_create_2d_matrix(1, 0, 0, 1, 0, 0); 69 return; 70 } 71 auto const& init_value = init.value(); 72 73 // -> If init is a DOMString 74 if (init_value.has<String>()) { 75 dbgln("FIXME: Implement initializing DOMMatrix(ReadOnly) from DOMString: '{}'", init_value.get<String>()); 76 // NOTE: This will result in an identity matrix for now. 77 return; 78 } 79 80 auto const& double_sequence = init_value.get<Vector<double>>(); 81 82 // -> If init is a sequence with 6 elements 83 if (double_sequence.size() == 6) { 84 // Return the result of invoking create a 2d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with the sequence init. 85 initialize_from_create_2d_matrix(double_sequence[0], double_sequence[1], double_sequence[2], double_sequence[3], double_sequence[4], double_sequence[5]); 86 return; 87 } 88 89 // -> If init is a sequence with 16 elements 90 // NOTE: The "otherwise" case should be handled in construct_impl, leaving the only other possible condition here to be 16 elements. 91 VERIFY(double_sequence.size() == 16); 92 93 // Return the result of invoking create a 3d matrix of type DOMMatrixReadOnly or DOMMatrix as appropriate, with the sequence init. 94 initialize_from_create_3d_matrix( 95 double_sequence[0], double_sequence[1], double_sequence[2], double_sequence[3], 96 double_sequence[4], double_sequence[5], double_sequence[6], double_sequence[7], 97 double_sequence[8], double_sequence[9], double_sequence[10], double_sequence[11], 98 double_sequence[12], double_sequence[13], double_sequence[14], double_sequence[15]); 99} 100 101DOMMatrixReadOnly::DOMMatrixReadOnly(JS::Realm& realm, DOMMatrixReadOnly const& other) 102 : Bindings::PlatformObject(realm) 103 , m_matrix(other.m_matrix) 104 , m_is_2d(other.m_is_2d) 105{ 106} 107 108DOMMatrixReadOnly::~DOMMatrixReadOnly() = default; 109 110JS::ThrowCompletionOr<void> DOMMatrixReadOnly::initialize(JS::Realm& realm) 111{ 112 MUST_OR_THROW_OOM(Base::initialize(realm)); 113 set_prototype(&Bindings::ensure_web_prototype<Bindings::DOMMatrixReadOnlyPrototype>(realm, "DOMMatrixReadOnly")); 114 115 return {}; 116} 117 118// https://drafts.fxtf.org/geometry/#create-a-2d-matrix 119void DOMMatrixReadOnly::initialize_from_create_2d_matrix(double m11, double m12, double m21, double m22, double m41, double m42) 120{ 121 // 1. Let matrix be a new instance of type. 122 // 2. Set m11 element, m12 element, m21 element, m22 element, m41 element and m42 element to the values of init in order starting with the first value. 123 auto* elements = m_matrix.elements(); 124 elements[0][0] = m11; 125 elements[0][1] = m12; 126 elements[1][0] = m21; 127 elements[1][1] = m22; 128 elements[3][0] = m41; 129 elements[3][1] = m42; 130 131 // 3. Set m13 element, m14 element, m23 element, m24 element, m31 element, m32 element, m34 element, and m43 element to 0. 132 elements[0][2] = 0.0; 133 elements[0][3] = 0.0; 134 elements[1][2] = 0.0; 135 elements[1][3] = 0.0; 136 elements[2][0] = 0.0; 137 elements[2][1] = 0.0; 138 elements[2][3] = 0.0; 139 elements[3][2] = 0.0; 140 141 // 4. Set m33 element and m44 element to 1. 142 elements[2][2] = 1.0; 143 elements[3][3] = 1.0; 144 145 // 5. Set is 2D to true. 146 m_is_2d = true; 147 148 // 6. Return matrix 149} 150 151// https://drafts.fxtf.org/geometry/#create-a-3d-matrix 152void DOMMatrixReadOnly::initialize_from_create_3d_matrix(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) 153{ 154 // 1. Let matrix be a new instance of type. 155 // 2. Set m11 element to m44 element to the values of init in column-major order. 156 auto* elements = m_matrix.elements(); 157 elements[0][0] = m11; 158 elements[0][1] = m12; 159 elements[0][2] = m13; 160 elements[0][3] = m14; 161 elements[1][0] = m21; 162 elements[1][1] = m22; 163 elements[1][2] = m23; 164 elements[1][3] = m24; 165 elements[2][0] = m31; 166 elements[2][1] = m32; 167 elements[2][2] = m33; 168 elements[2][3] = m34; 169 elements[3][0] = m41; 170 elements[3][1] = m42; 171 elements[3][2] = m43; 172 elements[3][3] = m44; 173 174 // 3. Set is 2D to false. 175 m_is_2d = false; 176 177 // 4. Return matrix 178} 179 180// https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-isidentity 181bool DOMMatrixReadOnly::is_identity() const 182{ 183 // The isIdentity attribute must return true if 184 // m12 element, m13 element, m14 element, 185 // m21 element, m23 element, m24 element, 186 // m31 element, m32 element, m34 element 187 // m41 element, m42 element, m43 element 188 // are 0 or -0 and 189 // m11 element, m22 element, m33 element, m44 element are 1. 190 // Otherwise it must return false. 191 if (m12() != 0.0 && m12() != -0.0) 192 return false; 193 194 if (m13() != 0.0 && m13() != -0.0) 195 return false; 196 197 if (m14() != 0.0 && m14() != -0.0) 198 return false; 199 200 if (m21() != 0.0 && m21() != -0.0) 201 return false; 202 203 if (m23() != 0.0 && m24() != -0.0) 204 return false; 205 206 if (m31() != 0.0 && m32() != -0.0) 207 return false; 208 209 if (m34() != 0.0 && m34() != -0.0) 210 return false; 211 212 if (m41() != 0.0 && m42() != -0.0) 213 return false; 214 215 if (m43() != 0.0 && m43() != -0.0) 216 return false; 217 218 if (m11() != 1.0) 219 return false; 220 221 if (m22() != 1.0) 222 return false; 223 224 if (m33() != 1.0) 225 return false; 226 227 if (m44() != 1.0) 228 return false; 229 230 return true; 231} 232 233// https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-inverse 234JS::NonnullGCPtr<DOMMatrix> DOMMatrixReadOnly::inverse() const 235{ 236 // 1. Let result be the resulting matrix initialized to the values of the current matrix. 237 auto result = DOMMatrix::create_from_dom_matrix_read_only(realm(), *this); 238 239 // 2. Perform a invertSelf() transformation on result. 240 // 3. Return result. 241 // The current matrix is not modified. 242 return result->invert_self(); 243} 244 245// https://drafts.fxtf.org/geometry/#dommatrixreadonly-stringification-behavior 246WebIDL::ExceptionOr<String> DOMMatrixReadOnly::to_string() const 247{ 248 auto& vm = this->vm(); 249 250 // 1. If one or more of m11 element through m44 element are a non-finite value, then throw an "InvalidStateError" DOMException. 251 // Spec Note: The CSS syntax cannot represent NaN or Infinity values. 252 if (!isfinite(m11()) || !isfinite(m12()) || !isfinite(m13()) || !isfinite(m14()) 253 || !isfinite(m21()) || !isfinite(m22()) || !isfinite(m23()) || !isfinite(m24()) 254 || !isfinite(m31()) || !isfinite(m32()) || !isfinite(m33()) || !isfinite(m34()) 255 || !isfinite(m41()) || !isfinite(m42()) || !isfinite(m43()) || !isfinite(m44())) { 256 return WebIDL::InvalidStateError::create(realm(), "Cannot stringify non-finite matrix values"); 257 } 258 259 // 2. Let string be the empty string. 260 StringBuilder builder; 261 262 // 3. If is 2D is true, then: 263 if (m_is_2d) { 264 // 1. Append "matrix(" to string. 265 TRY_OR_THROW_OOM(vm, builder.try_append("matrix("sv)); 266 267 // 2. Append ! ToString(m11 element) to string. 268 TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::Value(m11()).to_string_without_side_effects()))); 269 270 // 3. Append ", " to string. 271 TRY_OR_THROW_OOM(vm, builder.try_append(", "sv)); 272 273 // 4. Append ! ToString(m12 element) to string. 274 TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::Value(m12()).to_string_without_side_effects()))); 275 276 // 5. Append ", " to string. 277 TRY_OR_THROW_OOM(vm, builder.try_append(", "sv)); 278 279 // 6. Append ! ToString(m21 element) to string. 280 TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::Value(m21()).to_string_without_side_effects()))); 281 282 // 7. Append ", " to string. 283 TRY_OR_THROW_OOM(vm, builder.try_append(", "sv)); 284 285 // 8. Append ! ToString(m22 element) to string. 286 TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::Value(m22()).to_string_without_side_effects()))); 287 288 // 9. Append ", " to string. 289 TRY_OR_THROW_OOM(vm, builder.try_append(", "sv)); 290 291 // 10. Append ! ToString(m41 element) to string. 292 TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::Value(m41()).to_string_without_side_effects()))); 293 294 // 11. Append ", " to string. 295 TRY_OR_THROW_OOM(vm, builder.try_append(", "sv)); 296 297 // 12. Append ! ToString(m42 element) to string. 298 TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::Value(m42()).to_string_without_side_effects()))); 299 300 // 13. Append ")" to string. 301 TRY_OR_THROW_OOM(vm, builder.try_append(")"sv)); 302 } else { 303 // 1. Append "matrix3d(" to string. 304 TRY_OR_THROW_OOM(vm, builder.try_append("matrix3d("sv)); 305 306 // 2. Append ! ToString(m11 element) to string. 307 TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m11())))); 308 309 // 3. Append ", " to string. 310 TRY_OR_THROW_OOM(vm, builder.try_append(", "sv)); 311 312 // 4. Append ! ToString(m12 element) to string. 313 TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m12())))); 314 315 // 5. Append ", " to string. 316 TRY_OR_THROW_OOM(vm, builder.try_append(", "sv)); 317 318 // 6. Append ! ToString(m13 element) to string. 319 TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m13())))); 320 321 // 7. Append ", " to string. 322 TRY_OR_THROW_OOM(vm, builder.try_append(", "sv)); 323 324 // 8. Append ! ToString(m14 element) to string. 325 TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m14())))); 326 327 // 9. Append ", " to string. 328 TRY_OR_THROW_OOM(vm, builder.try_append(", "sv)); 329 330 // 10. Append ! ToString(m21 element) to string. 331 TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m21())))); 332 333 // 11. Append ", " to string. 334 TRY_OR_THROW_OOM(vm, builder.try_append(", "sv)); 335 336 // 12. Append ! ToString(m22 element) to string. 337 TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m22())))); 338 339 // 13. Append ", " to string. 340 TRY_OR_THROW_OOM(vm, builder.try_append(", "sv)); 341 342 // 14. Append ! ToString(m23 element) to string. 343 TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m23())))); 344 345 // 15. Append ", " to string. 346 TRY_OR_THROW_OOM(vm, builder.try_append(", "sv)); 347 348 // 16. Append ! ToString(m24 element) to string. 349 TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m24())))); 350 351 // 17. Append ", " to string. 352 TRY_OR_THROW_OOM(vm, builder.try_append(", "sv)); 353 354 // NOTE: The spec doesn't include the steps to append m31 to m34, but they are required as matrix3d requires 16 elements. 355 TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m31())))); 356 TRY_OR_THROW_OOM(vm, builder.try_append(", "sv)); 357 TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m32())))); 358 TRY_OR_THROW_OOM(vm, builder.try_append(", "sv)); 359 TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m33())))); 360 TRY_OR_THROW_OOM(vm, builder.try_append(", "sv)); 361 TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m34())))); 362 TRY_OR_THROW_OOM(vm, builder.try_append(", "sv)); 363 364 // 18. Append ! ToString(m41 element) to string. 365 TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m41())))); 366 367 // 19. Append ", " to string. 368 TRY_OR_THROW_OOM(vm, builder.try_append(", "sv)); 369 370 // 20. Append ! ToString(m42 element) to string. 371 TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m42())))); 372 373 // 21. Append ", " to string. 374 TRY_OR_THROW_OOM(vm, builder.try_append(", "sv)); 375 376 // 22. Append ! ToString(m43 element) to string. 377 TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m43())))); 378 379 // 23. Append ", " to string. 380 TRY_OR_THROW_OOM(vm, builder.try_append(", "sv)); 381 382 // 24. Append ! ToString(m44 element) to string. 383 TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m44())))); 384 385 // 25. Append ")" to string. 386 TRY_OR_THROW_OOM(vm, builder.try_append(")"sv)); 387 } 388 389 // 5. Return string. 390 return TRY_OR_THROW_OOM(vm, builder.to_string()); 391} 392 393// https://drafts.fxtf.org/geometry/#matrix-validate-and-fixup-2d 394WebIDL::ExceptionOr<void> validate_and_fixup_dom_matrix_2d_init(DOMMatrix2DInit& init) 395{ 396 // 1. If at least one of the following conditions are true for dict, then throw a TypeError exception and abort these steps. 397 // - a and m11 are both present and SameValueZero(a, m11) is false. 398 if (init.a.has_value() && init.m11.has_value() && !JS::same_value_zero(JS::Value(init.a.value()), JS::Value(init.m11.value()))) 399 return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "DOMMatrix2DInit.a and DOMMatrix2DInit.m11 must have the same value if they are both present"sv }; 400 401 // - b and m12 are both present and SameValueZero(b, m12) is false. 402 if (init.b.has_value() && init.m12.has_value() && !JS::same_value_zero(JS::Value(init.b.value()), JS::Value(init.m12.value()))) 403 return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "DOMMatrix2DInit.b and DOMMatrix2DInit.m12 must have the same value if they are both present"sv }; 404 405 // - c and m21 are both present and SameValueZero(c, m21) is false. 406 if (init.c.has_value() && init.m21.has_value() && !JS::same_value_zero(JS::Value(init.c.value()), JS::Value(init.m21.value()))) 407 return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "DOMMatrix2DInit.c and DOMMatrix2DInit.m21 must have the same value if they are both present"sv }; 408 409 // - d and m22 are both present and SameValueZero(d, m22) is false. 410 if (init.d.has_value() && init.m22.has_value() && !JS::same_value_zero(JS::Value(init.d.value()), JS::Value(init.m22.value()))) 411 return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "DOMMatrix2DInit.d and DOMMatrix2DInit.m22 must have the same value if they are both present"sv }; 412 413 // - e and m41 are both present and SameValueZero(e, m41) is false. 414 if (init.e.has_value() && init.m41.has_value() && !JS::same_value_zero(JS::Value(init.e.value()), JS::Value(init.m41.value()))) 415 return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "DOMMatrix2DInit.e and DOMMatrix2DInit.m41 must have the same value if they are both present"sv }; 416 417 // - f and m42 are both present and SameValueZero(f, m42) is false. 418 if (init.f.has_value() && init.m42.has_value() && !JS::same_value_zero(JS::Value(init.f.value()), JS::Value(init.m42.value()))) 419 return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "DOMMatrix2DInit.f and DOMMatrix2DInit.m42 must have the same value if they are both present"sv }; 420 421 // 2. If m11 is not present then set it to the value of member a, or value 1 if a is also not present. 422 if (!init.m11.has_value()) 423 init.m11 = init.a.value_or(1.0); 424 425 // 3. If m12 is not present then set it to the value of member b, or value 0 if b is also not present. 426 if (!init.m12.has_value()) 427 init.m12 = init.b.value_or(0.0); 428 429 // 4. If m21 is not present then set it to the value of member c, or value 0 if c is also not present. 430 if (!init.m21.has_value()) 431 init.m21 = init.c.value_or(0.0); 432 433 // 5. If m22 is not present then set it to the value of member d, or value 1 if d is also not present. 434 if (!init.m22.has_value()) 435 init.m22 = init.d.value_or(1.0); 436 437 // 6. If m41 is not present then set it to the value of member e, or value 0 if e is also not present. 438 if (!init.m41.has_value()) 439 init.m41 = init.e.value_or(0.0); 440 441 // 7. If m42 is not present then set it to the value of member f, or value 0 if f is also not present. 442 if (!init.m42.has_value()) 443 init.m42 = init.f.value_or(0.0); 444 445 return {}; 446} 447 448// https://drafts.fxtf.org/geometry/#matrix-validate-and-fixup 449WebIDL::ExceptionOr<void> validate_and_fixup_dom_matrix_init(DOMMatrixInit& init) 450{ 451 // 1. Validate and fixup (2D) dict. 452 TRY(validate_and_fixup_dom_matrix_2d_init(init)); 453 454 // 2. If is2D is true and: at least one of m13, m14, m23, m24, m31, m32, m34, m43 are present with a value other than 0 or -0, 455 // or at least one of m33, m44 are present with a value other than 1, then throw a TypeError exception and abort these steps. 456 if (init.is2d.has_value() && init.is2d.value()) { 457 if ((init.m13 != 0.0 && init.m13 != -0.0) 458 || (init.m14 != 0.0 && init.m14 != -0.0) 459 || (init.m23 != 0.0 && init.m23 != -0.0) 460 || (init.m24 != 0.0 && init.m24 != -0.0) 461 || (init.m31 != 0.0 && init.m31 != -0.0) 462 || (init.m32 != 0.0 && init.m32 != -0.0) 463 || (init.m34 != 0.0 && init.m34 != -0.0) 464 || (init.m43 != 0.0 && init.m43 != -0.0) 465 || init.m33 != 1.0 466 || init.m44 != 1.0) { 467 return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "DOMMatrixInit.is2D is true, but the given matrix is not a 2D matrix"sv }; 468 } 469 } 470 471 // If is2D is not present and at least one of m13, m14, m23, m24, m31, m32, m34, m43 are present with a value other than 0 or -0, 472 // or at least one of m33, m44 are present with a value other than 1, set is2D to false. 473 if (!init.is2d.has_value()) { 474 if ((init.m13 != 0.0 && init.m13 != -0.0) 475 || (init.m14 != 0.0 && init.m14 != -0.0) 476 || (init.m23 != 0.0 && init.m23 != -0.0) 477 || (init.m24 != 0.0 && init.m24 != -0.0) 478 || (init.m31 != 0.0 && init.m31 != -0.0) 479 || (init.m32 != 0.0 && init.m32 != -0.0) 480 || (init.m34 != 0.0 && init.m34 != -0.0) 481 || (init.m43 != 0.0 && init.m43 != -0.0) 482 || init.m33 != 1.0 483 || init.m44 != 1.0) { 484 init.is2d = false; 485 } 486 } 487 488 // 4. If is2D is still not present, set it to true. 489 if (!init.is2d.has_value()) 490 init.is2d = true; 491 492 return {}; 493} 494 495}