1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/dom/DOMQuad.h"
10 #include "mozilla/FloatingPoint.h"
11 #include "mozilla/MacroForEach.h"
12 #include "mozilla/dom/BindingDeclarations.h"
13 #include "mozilla/dom/DOMPoint.h"
14 #include "mozilla/dom/DOMQuadBinding.h"
15 #include "mozilla/dom/DOMRect.h"
16 #include "mozilla/dom/DOMRectBinding.h"
17 #include "mozilla/gfx/BasePoint.h"
18 #include "mozilla/gfx/MatrixFwd.h"
19 #include "nsIGlobalObject.h"
21 using namespace mozilla
;
22 using namespace mozilla::dom
;
23 using namespace mozilla::gfx
;
25 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMQuad
, mParent
, mPoints
[0], mPoints
[1],
26 mPoints
[2], mPoints
[3])
28 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMQuad
, AddRef
)
29 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMQuad
, Release
)
31 DOMQuad::DOMQuad(nsISupports
* aParent
, CSSPoint aPoints
[4]) : mParent(aParent
) {
32 for (uint32_t i
= 0; i
< 4; ++i
) {
33 mPoints
[i
] = new DOMPoint(aParent
, aPoints
[i
].x
, aPoints
[i
].y
);
37 DOMQuad::DOMQuad(nsISupports
* aParent
) : mParent(aParent
) {}
39 DOMQuad::~DOMQuad() = default;
41 JSObject
* DOMQuad::WrapObject(JSContext
* aCx
,
42 JS::Handle
<JSObject
*> aGivenProto
) {
43 return DOMQuad_Binding::Wrap(aCx
, this, aGivenProto
);
46 already_AddRefed
<DOMQuad
> DOMQuad::FromRect(const GlobalObject
& aGlobal
,
47 const DOMRectInit
& aInit
) {
48 nsISupports
* parent
= aGlobal
.GetAsSupports();
49 RefPtr
<DOMQuad
> obj
= new DOMQuad(parent
);
50 obj
->mPoints
[0] = new DOMPoint(parent
, aInit
.mX
, aInit
.mY
, 0, 1);
52 new DOMPoint(parent
, aInit
.mX
+ aInit
.mWidth
, aInit
.mY
, 0, 1);
53 obj
->mPoints
[2] = new DOMPoint(parent
, aInit
.mX
+ aInit
.mWidth
,
54 aInit
.mY
+ aInit
.mHeight
, 0, 1);
56 new DOMPoint(parent
, aInit
.mX
, aInit
.mY
+ aInit
.mHeight
, 0, 1);
60 already_AddRefed
<DOMQuad
> DOMQuad::FromQuad(const GlobalObject
& aGlobal
,
61 const DOMQuadInit
& aInit
) {
62 RefPtr
<DOMQuad
> obj
= new DOMQuad(aGlobal
.GetAsSupports());
63 obj
->mPoints
[0] = DOMPoint::FromPoint(aGlobal
, aInit
.mP1
);
64 obj
->mPoints
[1] = DOMPoint::FromPoint(aGlobal
, aInit
.mP2
);
65 obj
->mPoints
[2] = DOMPoint::FromPoint(aGlobal
, aInit
.mP3
);
66 obj
->mPoints
[3] = DOMPoint::FromPoint(aGlobal
, aInit
.mP4
);
70 already_AddRefed
<DOMQuad
> DOMQuad::Constructor(const GlobalObject
& aGlobal
,
71 const DOMPointInit
& aP1
,
72 const DOMPointInit
& aP2
,
73 const DOMPointInit
& aP3
,
74 const DOMPointInit
& aP4
) {
75 RefPtr
<DOMQuad
> obj
= new DOMQuad(aGlobal
.GetAsSupports());
76 obj
->mPoints
[0] = DOMPoint::FromPoint(aGlobal
, aP1
);
77 obj
->mPoints
[1] = DOMPoint::FromPoint(aGlobal
, aP2
);
78 obj
->mPoints
[2] = DOMPoint::FromPoint(aGlobal
, aP3
);
79 obj
->mPoints
[3] = DOMPoint::FromPoint(aGlobal
, aP4
);
83 already_AddRefed
<DOMQuad
> DOMQuad::Constructor(const GlobalObject
& aGlobal
,
84 const DOMRectReadOnly
& aRect
) {
86 Float x
= aRect
.X(), y
= aRect
.Y(), w
= aRect
.Width(), h
= aRect
.Height();
87 points
[0] = CSSPoint(x
, y
);
88 points
[1] = CSSPoint(x
+ w
, y
);
89 points
[2] = CSSPoint(x
+ w
, y
+ h
);
90 points
[3] = CSSPoint(x
, y
+ h
);
91 RefPtr
<DOMQuad
> obj
= new DOMQuad(aGlobal
.GetAsSupports(), points
);
95 void DOMQuad::GetHorizontalMinMax(double* aX1
, double* aX2
) const {
97 x1
= x2
= Point(0)->X();
98 for (uint32_t i
= 1; i
< 4; ++i
) {
99 double x
= Point(i
)->X();
100 x1
= NaNSafeMin(x1
, x
);
101 x2
= NaNSafeMax(x2
, x
);
107 void DOMQuad::GetVerticalMinMax(double* aY1
, double* aY2
) const {
109 y1
= y2
= Point(0)->Y();
110 for (uint32_t i
= 1; i
< 4; ++i
) {
111 double y
= Point(i
)->Y();
112 y1
= NaNSafeMin(y1
, y
);
113 y2
= NaNSafeMax(y2
, y
);
119 already_AddRefed
<DOMRectReadOnly
> DOMQuad::GetBounds() const {
123 GetHorizontalMinMax(&x1
, &x2
);
124 GetVerticalMinMax(&y1
, &y2
);
126 RefPtr
<DOMRectReadOnly
> rval
=
127 new DOMRectReadOnly(GetParentObject(), x1
, y1
, x2
- x1
, y2
- y1
);
128 return rval
.forget();
131 // https://drafts.fxtf.org/geometry/#structured-serialization
132 bool DOMQuad::WriteStructuredClone(JSContext
* aCx
,
133 JSStructuredCloneWriter
* aWriter
) const {
134 for (const auto& point
: mPoints
) {
135 if (!point
->WriteStructuredClone(aCx
, aWriter
)) {
143 already_AddRefed
<DOMQuad
> DOMQuad::ReadStructuredClone(
144 JSContext
* aCx
, nsIGlobalObject
* aGlobal
,
145 JSStructuredCloneReader
* aReader
) {
146 RefPtr
<DOMQuad
> quad
= new DOMQuad(aGlobal
);
147 for (auto& point
: quad
->mPoints
) {
148 point
= DOMPoint::ReadStructuredClone(aCx
, aGlobal
, aReader
);
153 return quad
.forget();