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 DOMQuad::DOMQuad(nsISupports
* aParent
, CSSPoint aPoints
[4]) : mParent(aParent
) {
29 for (uint32_t i
= 0; i
< 4; ++i
) {
30 mPoints
[i
] = new DOMPoint(aParent
, aPoints
[i
].x
, aPoints
[i
].y
);
34 DOMQuad::DOMQuad(nsISupports
* aParent
) : mParent(aParent
) {}
36 DOMQuad::~DOMQuad() = default;
38 JSObject
* DOMQuad::WrapObject(JSContext
* aCx
,
39 JS::Handle
<JSObject
*> aGivenProto
) {
40 return DOMQuad_Binding::Wrap(aCx
, this, aGivenProto
);
43 already_AddRefed
<DOMQuad
> DOMQuad::FromRect(const GlobalObject
& aGlobal
,
44 const DOMRectInit
& aInit
) {
45 nsISupports
* parent
= aGlobal
.GetAsSupports();
46 RefPtr
<DOMQuad
> obj
= new DOMQuad(parent
);
47 obj
->mPoints
[0] = new DOMPoint(parent
, aInit
.mX
, aInit
.mY
, 0, 1);
49 new DOMPoint(parent
, aInit
.mX
+ aInit
.mWidth
, aInit
.mY
, 0, 1);
50 obj
->mPoints
[2] = new DOMPoint(parent
, aInit
.mX
+ aInit
.mWidth
,
51 aInit
.mY
+ aInit
.mHeight
, 0, 1);
53 new DOMPoint(parent
, aInit
.mX
, aInit
.mY
+ aInit
.mHeight
, 0, 1);
57 already_AddRefed
<DOMQuad
> DOMQuad::FromQuad(const GlobalObject
& aGlobal
,
58 const DOMQuadInit
& aInit
) {
59 RefPtr
<DOMQuad
> obj
= new DOMQuad(aGlobal
.GetAsSupports());
60 obj
->mPoints
[0] = DOMPoint::FromPoint(aGlobal
, aInit
.mP1
);
61 obj
->mPoints
[1] = DOMPoint::FromPoint(aGlobal
, aInit
.mP2
);
62 obj
->mPoints
[2] = DOMPoint::FromPoint(aGlobal
, aInit
.mP3
);
63 obj
->mPoints
[3] = DOMPoint::FromPoint(aGlobal
, aInit
.mP4
);
67 already_AddRefed
<DOMQuad
> DOMQuad::Constructor(const GlobalObject
& aGlobal
,
68 const DOMPointInit
& aP1
,
69 const DOMPointInit
& aP2
,
70 const DOMPointInit
& aP3
,
71 const DOMPointInit
& aP4
) {
72 RefPtr
<DOMQuad
> obj
= new DOMQuad(aGlobal
.GetAsSupports());
73 obj
->mPoints
[0] = DOMPoint::FromPoint(aGlobal
, aP1
);
74 obj
->mPoints
[1] = DOMPoint::FromPoint(aGlobal
, aP2
);
75 obj
->mPoints
[2] = DOMPoint::FromPoint(aGlobal
, aP3
);
76 obj
->mPoints
[3] = DOMPoint::FromPoint(aGlobal
, aP4
);
80 already_AddRefed
<DOMQuad
> DOMQuad::Constructor(const GlobalObject
& aGlobal
,
81 const DOMRectReadOnly
& aRect
) {
83 Float x
= aRect
.X(), y
= aRect
.Y(), w
= aRect
.Width(), h
= aRect
.Height();
84 points
[0] = CSSPoint(x
, y
);
85 points
[1] = CSSPoint(x
+ w
, y
);
86 points
[2] = CSSPoint(x
+ w
, y
+ h
);
87 points
[3] = CSSPoint(x
, y
+ h
);
88 RefPtr
<DOMQuad
> obj
= new DOMQuad(aGlobal
.GetAsSupports(), points
);
92 void DOMQuad::GetHorizontalMinMax(double* aX1
, double* aX2
) const {
94 x1
= x2
= Point(0)->X();
95 for (uint32_t i
= 1; i
< 4; ++i
) {
96 double x
= Point(i
)->X();
97 x1
= NaNSafeMin(x1
, x
);
98 x2
= NaNSafeMax(x2
, x
);
104 void DOMQuad::GetVerticalMinMax(double* aY1
, double* aY2
) const {
106 y1
= y2
= Point(0)->Y();
107 for (uint32_t i
= 1; i
< 4; ++i
) {
108 double y
= Point(i
)->Y();
109 y1
= NaNSafeMin(y1
, y
);
110 y2
= NaNSafeMax(y2
, y
);
116 already_AddRefed
<DOMRectReadOnly
> DOMQuad::GetBounds() const {
120 GetHorizontalMinMax(&x1
, &x2
);
121 GetVerticalMinMax(&y1
, &y2
);
123 RefPtr
<DOMRectReadOnly
> rval
=
124 new DOMRectReadOnly(GetParentObject(), x1
, y1
, x2
- x1
, y2
- y1
);
125 return rval
.forget();
128 // https://drafts.fxtf.org/geometry/#structured-serialization
129 bool DOMQuad::WriteStructuredClone(JSContext
* aCx
,
130 JSStructuredCloneWriter
* aWriter
) const {
131 for (const auto& point
: mPoints
) {
132 if (!point
->WriteStructuredClone(aCx
, aWriter
)) {
140 already_AddRefed
<DOMQuad
> DOMQuad::ReadStructuredClone(
141 JSContext
* aCx
, nsIGlobalObject
* aGlobal
,
142 JSStructuredCloneReader
* aReader
) {
143 RefPtr
<DOMQuad
> quad
= new DOMQuad(aGlobal
);
144 for (auto& point
: quad
->mPoints
) {
145 point
= DOMPoint::ReadStructuredClone(aCx
, aGlobal
, aReader
);
150 return quad
.forget();