DOMQuad.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /*
  2. * Copyright (c) 2023, Bastiaan van der Plaat <bastiaan.v.d.plaat@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibWeb/Bindings/Intrinsics.h>
  7. #include <LibWeb/Geometry/DOMQuad.h>
  8. namespace Web::Geometry {
  9. JS_DEFINE_ALLOCATOR(DOMQuad);
  10. JS::NonnullGCPtr<DOMQuad> DOMQuad::construct_impl(JS::Realm& realm, DOMPointInit const& p1, DOMPointInit const& p2, DOMPointInit const& p3, DOMPointInit const& p4)
  11. {
  12. return realm.heap().allocate<DOMQuad>(realm, realm, p1, p2, p3, p4);
  13. }
  14. DOMQuad::DOMQuad(JS::Realm& realm, DOMPointInit const& p1, DOMPointInit const& p2, DOMPointInit const& p3, DOMPointInit const& p4)
  15. : PlatformObject(realm)
  16. , m_p1(DOMPoint::from_point(realm.vm(), p1))
  17. , m_p2(DOMPoint::from_point(realm.vm(), p2))
  18. , m_p3(DOMPoint::from_point(realm.vm(), p3))
  19. , m_p4(DOMPoint::from_point(realm.vm(), p4))
  20. {
  21. }
  22. DOMQuad::~DOMQuad() = default;
  23. // https://drafts.fxtf.org/geometry/#dom-domquad-fromrect
  24. JS::NonnullGCPtr<DOMQuad> DOMQuad::from_rect(JS::VM& vm, DOMRectInit const& other)
  25. {
  26. // The fromRect(other) static method on DOMQuad must create a DOMQuad from the DOMRectInit dictionary other.
  27. return construct_impl(*vm.current_realm(), { other.x, other.y },
  28. { other.x + other.width, other.y },
  29. { other.x + other.width, other.y + other.height },
  30. { other.x, other.y + other.height });
  31. }
  32. // https://drafts.fxtf.org/geometry/#dom-domquad-fromquad
  33. JS::NonnullGCPtr<DOMQuad> DOMQuad::from_quad(JS::VM& vm, DOMQuadInit const& other)
  34. {
  35. // The fromQuad(other) static method on DOMQuad must create a DOMQuad from the DOMQuadInit dictionary other.
  36. return construct_impl(*vm.current_realm(), other.p1, other.p2, other.p3, other.p4);
  37. }
  38. // https://drafts.fxtf.org/geometry/#dom-domquad-getbounds
  39. JS::NonnullGCPtr<DOMRect> DOMQuad::get_bounds() const
  40. {
  41. auto nan_safe_minimum = [](double a, double b, double c, double d) -> double {
  42. if (isnan(a) || isnan(b) || isnan(c) || isnan(d))
  43. return NAN;
  44. return min(a, min(b, min(c, d)));
  45. };
  46. auto nan_safe_maximum = [](double a, double b, double c, double d) -> double {
  47. if (isnan(a) || isnan(b) || isnan(c) || isnan(d))
  48. return NAN;
  49. return max(a, max(b, max(c, d)));
  50. };
  51. // 1. Let bounds be a DOMRect object.
  52. auto bounds = DOMRect::create(realm(), {});
  53. // 2. Let left be the NaN-safe minimum of point 1’s x coordinate, point 2’s x coordinate, point 3’s x coordinate and point 4’s x coordinate.
  54. auto left = nan_safe_minimum(m_p1->x(), m_p2->x(), m_p3->x(), m_p4->x());
  55. // 3. Let top be the NaN-safe minimum of point 1’s y coordinate, point 2’s y coordinate, point 3’s y coordinate and point 4’s y coordinate.
  56. auto top = nan_safe_minimum(m_p1->y(), m_p2->y(), m_p3->y(), m_p4->y());
  57. // 4. Let right be the NaN-safe maximum of point 1’s x coordinate, point 2’s x coordinate, point 3’s x coordinate and point 4’s x coordinate.
  58. auto right = nan_safe_maximum(m_p1->x(), m_p2->x(), m_p3->x(), m_p4->x());
  59. // 5. Let bottom be the NaN-safe maximum of point 1’s y coordinate, point 2’s y coordinate, point 3’s y coordinate and point 4’s y coordinate.
  60. auto bottom = nan_safe_maximum(m_p1->y(), m_p2->y(), m_p3->y(), m_p4->y());
  61. // 6. Set x coordinate of bounds to left, y coordinate of bounds to top, width dimension of bounds to right - left and height dimension of bounds to bottom - top.
  62. bounds->set_x(left);
  63. bounds->set_y(top);
  64. bounds->set_width(right - left);
  65. bounds->set_height(bottom - top);
  66. // 7. Return bounds.
  67. return bounds;
  68. }
  69. void DOMQuad::initialize(JS::Realm& realm)
  70. {
  71. Base::initialize(realm);
  72. WEB_SET_PROTOTYPE_FOR_INTERFACE(DOMQuad);
  73. }
  74. void DOMQuad::visit_edges(Cell::Visitor& visitor)
  75. {
  76. Base::visit_edges(visitor);
  77. visitor.visit(m_p1);
  78. visitor.visit(m_p2);
  79. visitor.visit(m_p3);
  80. visitor.visit(m_p4);
  81. }
  82. }