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 #ifndef MOZILLA_DOM_DOMMATRIX_H_
8 #define MOZILLA_DOM_DOMMATRIX_H_
12 #include "js/RootingAPI.h"
13 #include "mozilla/AlreadyAddRefed.h"
14 #include "mozilla/Assertions.h"
15 #include "mozilla/UniquePtr.h"
16 #include "mozilla/dom/TypedArray.h"
17 #include "mozilla/gfx/Matrix.h"
19 #include "nsCycleCollectionParticipant.h"
20 #include "nsISupports.h"
21 #include "nsStringFwd.h"
22 #include "nsWrapperCache.h"
25 class nsIGlobalObject
;
27 struct JSStructuredCloneReader
;
28 struct JSStructuredCloneWriter
;
40 class UTF8StringOrUnrestrictedDoubleSequenceOrDOMMatrixReadOnly
;
43 struct DOMMatrix2DInit
;
45 class DOMMatrixReadOnly
: public nsWrapperCache
{
47 explicit DOMMatrixReadOnly(nsISupports
* aParent
)
48 : mParent(aParent
), mMatrix2D(new gfx::MatrixDouble()) {}
50 DOMMatrixReadOnly(nsISupports
* aParent
, const DOMMatrixReadOnly
& other
)
52 if (other
.mMatrix2D
) {
53 mMatrix2D
= MakeUnique
<gfx::MatrixDouble
>(*other
.mMatrix2D
);
55 mMatrix3D
= MakeUnique
<gfx::Matrix4x4Double
>(*other
.mMatrix3D
);
59 DOMMatrixReadOnly(nsISupports
* aParent
, const gfx::Matrix4x4
& aMatrix
)
61 mMatrix3D
= MakeUnique
<gfx::Matrix4x4Double
>(aMatrix
);
64 DOMMatrixReadOnly(nsISupports
* aParent
, const gfx::Matrix
& aMatrix
)
66 mMatrix2D
= MakeUnique
<gfx::MatrixDouble
>(aMatrix
);
69 NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMMatrixReadOnly
)
70 NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(DOMMatrixReadOnly
)
72 nsISupports
* GetParentObject() const { return mParent
; }
73 virtual JSObject
* WrapObject(JSContext
* cx
,
74 JS::Handle
<JSObject
*> aGivenProto
) override
;
76 static already_AddRefed
<DOMMatrixReadOnly
> FromMatrix(
77 nsISupports
* aParent
, const DOMMatrix2DInit
& aMatrixInit
,
80 static already_AddRefed
<DOMMatrixReadOnly
> FromMatrix(
81 nsISupports
* aParent
, const DOMMatrixInit
& aMatrixInit
, ErrorResult
& aRv
);
83 static already_AddRefed
<DOMMatrixReadOnly
> FromMatrix(
84 const GlobalObject
& aGlobal
, const DOMMatrixInit
& aMatrixInit
,
87 static already_AddRefed
<DOMMatrixReadOnly
> FromFloat32Array(
88 const GlobalObject
& aGlobal
, const Float32Array
& aArray32
,
91 static already_AddRefed
<DOMMatrixReadOnly
> FromFloat64Array(
92 const GlobalObject
& aGlobal
, const Float64Array
& aArray64
,
95 static already_AddRefed
<DOMMatrixReadOnly
> Constructor(
96 const GlobalObject
& aGlobal
,
97 const Optional
<UTF8StringOrUnrestrictedDoubleSequenceOrDOMMatrixReadOnly
>&
101 static already_AddRefed
<DOMMatrixReadOnly
> ReadStructuredClone(
102 JSContext
* aCx
, nsIGlobalObject
* aGlobal
,
103 JSStructuredCloneReader
* aReader
);
106 #define GetMatrixMember(entry2D, entry3D, default) \
109 return mMatrix3D->entry3D; \
111 return mMatrix2D->entry2D; \
114 #define Get3DMatrixMember(entry3D, default) \
117 return mMatrix3D->entry3D; \
122 double A() const GetMatrixMember(_11
, _11
, 1.0)
123 double B() const GetMatrixMember(_12
, _12
, 0)
124 double C() const GetMatrixMember(_21
, _21
, 0)
125 double D() const GetMatrixMember(_22
, _22
, 1.0)
126 double E() const GetMatrixMember(_31
, _41
, 0)
127 double F() const GetMatrixMember(_32
, _42
, 0)
129 double M11() const GetMatrixMember(_11
, _11
, 1.0)
130 double M12() const GetMatrixMember(_12
, _12
, 0)
131 double M13() const Get3DMatrixMember(_13
, 0)
132 double M14() const Get3DMatrixMember(_14
, 0)
133 double M21() const GetMatrixMember(_21
, _21
, 0)
134 double M22() const GetMatrixMember(_22
, _22
, 1.0)
135 double M23() const Get3DMatrixMember(_23
, 0)
136 double M24() const Get3DMatrixMember(_24
, 0)
137 double M31() const Get3DMatrixMember(_31
, 0)
138 double M32() const Get3DMatrixMember(_32
, 0)
139 double M33() const Get3DMatrixMember(_33
, 1.0)
140 double M34() const Get3DMatrixMember(_34
, 0)
141 double M41() const GetMatrixMember(_31
, _41
, 0)
142 double M42() const GetMatrixMember(_32
, _42
, 0)
143 double M43() const Get3DMatrixMember(_43
, 0)
144 double M44() const Get3DMatrixMember(_44
, 1.0)
146 #undef GetMatrixMember
147 #undef Get3DMatrixMember
149 // Defined here so we can construct DOMMatrixReadOnly objects.
150 #define Set2DMatrixMember(entry2D, entry3D) \
153 mMatrix3D->entry3D = v; \
155 mMatrix2D->entry2D = v; \
159 #define Set3DMatrixMember(entry3D, default) \
161 if (mMatrix3D || (v != default)) { \
163 mMatrix3D->entry3D = v; \
167 void SetA(double v
) Set2DMatrixMember(_11
, _11
)
168 void SetB(double v
) Set2DMatrixMember(_12
, _12
)
169 void SetC(double v
) Set2DMatrixMember(_21
, _21
)
170 void SetD(double v
) Set2DMatrixMember(_22
, _22
)
171 void SetE(double v
) Set2DMatrixMember(_31
, _41
)
172 void SetF(double v
) Set2DMatrixMember(_32
, _42
)
174 void SetM11(double v
) Set2DMatrixMember(_11
, _11
)
175 void SetM12(double v
) Set2DMatrixMember(_12
, _12
)
176 void SetM13(double v
) Set3DMatrixMember(_13
, 0)
177 void SetM14(double v
) Set3DMatrixMember(_14
, 0)
178 void SetM21(double v
) Set2DMatrixMember(_21
, _21
)
179 void SetM22(double v
) Set2DMatrixMember(_22
, _22
)
180 void SetM23(double v
) Set3DMatrixMember(_23
, 0)
181 void SetM24(double v
) Set3DMatrixMember(_24
, 0)
182 void SetM31(double v
) Set3DMatrixMember(_31
, 0)
183 void SetM32(double v
) Set3DMatrixMember(_32
, 0)
184 void SetM33(double v
) Set3DMatrixMember(_33
, 1.0)
185 void SetM34(double v
) Set3DMatrixMember(_34
, 0)
186 void SetM41(double v
) Set2DMatrixMember(_31
, _41
)
187 void SetM42(double v
) Set2DMatrixMember(_32
, _42
)
188 void SetM43(double v
) Set3DMatrixMember(_43
, 0)
189 void SetM44(double v
) Set3DMatrixMember(_44
, 1.0)
190 ; // semi-colon here to get clang-format to align properly from here on
192 #undef Set2DMatrixMember
193 #undef Set3DMatrixMember
196 already_AddRefed
<DOMMatrix
> Translate(double aTx
, double aTy
,
197 double aTz
= 0) const;
198 already_AddRefed
<DOMMatrix
> Scale(double aScaleX
,
199 const Optional
<double>& aScaleY
,
200 double aScaleZ
, double aOriginX
,
201 double aOriginY
, double aOriginZ
) const;
202 already_AddRefed
<DOMMatrix
> Scale3d(double aScale
, double aOriginX
= 0,
204 double aOriginZ
= 0) const;
205 already_AddRefed
<DOMMatrix
> ScaleNonUniform(double aScaleX
,
206 double aScaleY
) const;
207 already_AddRefed
<DOMMatrix
> Rotate(double aRotX
,
208 const Optional
<double>& aRotY
,
209 const Optional
<double>& aRotZ
) const;
210 already_AddRefed
<DOMMatrix
> RotateFromVector(double aX
, double aY
) const;
211 already_AddRefed
<DOMMatrix
> RotateAxisAngle(double aX
, double aY
, double aZ
,
212 double aAngle
) const;
213 already_AddRefed
<DOMMatrix
> SkewX(double aSx
) const;
214 already_AddRefed
<DOMMatrix
> SkewY(double aSy
) const;
215 already_AddRefed
<DOMMatrix
> Multiply(const DOMMatrixInit
& aOther
,
216 ErrorResult
& aRv
) const;
217 already_AddRefed
<DOMMatrix
> FlipX() const;
218 already_AddRefed
<DOMMatrix
> FlipY() const;
219 already_AddRefed
<DOMMatrix
> Inverse() const;
222 bool IsIdentity() const;
223 already_AddRefed
<DOMPoint
> TransformPoint(const DOMPointInit
& aPoint
) const;
224 void ToFloat32Array(JSContext
* aCx
, JS::MutableHandle
<JSObject
*> aResult
,
225 ErrorResult
& aRv
) const;
226 void ToFloat64Array(JSContext
* aCx
, JS::MutableHandle
<JSObject
*> aResult
,
227 ErrorResult
& aRv
) const;
228 void Stringify(nsAString
& aResult
, ErrorResult
& aRv
);
230 bool WriteStructuredClone(JSContext
* aCx
,
231 JSStructuredCloneWriter
* aWriter
) const;
232 const gfx::MatrixDouble
* GetInternal2D() const {
234 return mMatrix2D
.get();
240 nsCOMPtr
<nsISupports
> mParent
;
241 UniquePtr
<gfx::MatrixDouble
> mMatrix2D
;
242 UniquePtr
<gfx::Matrix4x4Double
> mMatrix3D
;
244 virtual ~DOMMatrixReadOnly() = default;
247 * Sets data from a fully validated and fixed-up matrix init,
248 * where all of its members are properly defined.
249 * The init dictionary's dimension must match the matrix one.
251 void SetDataFromMatrix2DInit(const DOMMatrix2DInit
& aMatrixInit
);
252 void SetDataFromMatrixInit(const DOMMatrixInit
& aMatrixInit
);
254 DOMMatrixReadOnly
* SetMatrixValue(const nsACString
&, ErrorResult
&);
255 void Ensure3DMatrix();
257 DOMMatrixReadOnly(nsISupports
* aParent
, bool is2D
)
258 : DOMMatrixReadOnly(do_AddRef(aParent
), is2D
) {}
259 DOMMatrixReadOnly(already_AddRefed
<nsISupports
>&& aParent
, bool is2D
)
260 : mParent(std::move(aParent
)) {
262 mMatrix2D
= MakeUnique
<gfx::MatrixDouble
>();
264 mMatrix3D
= MakeUnique
<gfx::Matrix4x4Double
>();
268 static bool ReadStructuredCloneElements(JSStructuredCloneReader
* aReader
,
269 DOMMatrixReadOnly
* matrix
);
272 DOMMatrixReadOnly() = delete;
273 DOMMatrixReadOnly(const DOMMatrixReadOnly
&) = delete;
274 DOMMatrixReadOnly
& operator=(const DOMMatrixReadOnly
&) = delete;
277 class DOMMatrix
: public DOMMatrixReadOnly
{
279 explicit DOMMatrix(nsISupports
* aParent
) : DOMMatrixReadOnly(aParent
) {}
281 DOMMatrix(nsISupports
* aParent
, const DOMMatrixReadOnly
& other
)
282 : DOMMatrixReadOnly(aParent
, other
) {}
284 DOMMatrix(nsISupports
* aParent
, const gfx::Matrix4x4
& aMatrix
)
285 : DOMMatrixReadOnly(aParent
, aMatrix
) {}
287 DOMMatrix(nsISupports
* aParent
, const gfx::Matrix
& aMatrix
)
288 : DOMMatrixReadOnly(aParent
, aMatrix
) {}
290 static already_AddRefed
<DOMMatrix
> FromMatrix(
291 nsISupports
* aParent
, const DOMMatrixInit
& aMatrixInit
, ErrorResult
& aRv
);
293 static already_AddRefed
<DOMMatrix
> FromMatrix(
294 const GlobalObject
& aGlobal
, const DOMMatrixInit
& aMatrixInit
,
297 static already_AddRefed
<DOMMatrix
> FromFloat32Array(
298 const GlobalObject
& aGlobal
, const Float32Array
& aArray32
,
301 static already_AddRefed
<DOMMatrix
> FromFloat64Array(
302 const GlobalObject
& aGlobal
, const Float64Array
& aArray64
,
305 static already_AddRefed
<DOMMatrix
> Constructor(
306 const GlobalObject
& aGlobal
,
307 const Optional
<UTF8StringOrUnrestrictedDoubleSequenceOrDOMMatrixReadOnly
>&
311 static already_AddRefed
<DOMMatrix
> ReadStructuredClone(
312 JSContext
* aCx
, nsIGlobalObject
* aGlobal
,
313 JSStructuredCloneReader
* aReader
);
315 virtual JSObject
* WrapObject(JSContext
* aCx
,
316 JS::Handle
<JSObject
*> aGivenProto
) override
;
318 DOMMatrix
* MultiplySelf(const DOMMatrixInit
& aOther
, ErrorResult
& aRv
);
319 DOMMatrix
* PreMultiplySelf(const DOMMatrixInit
& aOther
, ErrorResult
& aRv
);
320 DOMMatrix
* TranslateSelf(double aTx
, double aTy
, double aTz
= 0);
321 DOMMatrix
* ScaleSelf(double aScaleX
, const Optional
<double>& aScaleY
,
322 double aScaleZ
, double aOriginX
, double aOriginY
,
324 DOMMatrix
* Scale3dSelf(double aScale
, double aOriginX
= 0,
325 double aOriginY
= 0, double aOriginZ
= 0);
326 DOMMatrix
* RotateSelf(double aRotX
, const Optional
<double>& aRotY
,
327 const Optional
<double>& aRotZ
);
328 DOMMatrix
* RotateFromVectorSelf(double aX
, double aY
);
329 DOMMatrix
* RotateAxisAngleSelf(double aX
, double aY
, double aZ
,
331 DOMMatrix
* SkewXSelf(double aSx
);
332 DOMMatrix
* SkewYSelf(double aSy
);
333 DOMMatrix
* InvertSelf();
334 DOMMatrix
* SetMatrixValue(const nsACString
&, ErrorResult
&);
336 virtual ~DOMMatrix() = default;
339 DOMMatrix(nsISupports
* aParent
, bool is2D
)
340 : DOMMatrixReadOnly(aParent
, is2D
) {}
341 DOMMatrix(already_AddRefed
<nsISupports
>&& aParent
, bool is2D
)
342 : DOMMatrixReadOnly(std::move(aParent
), is2D
) {}
346 } // namespace mozilla
348 #endif /*MOZILLA_DOM_DOMMATRIX_H_*/