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/SVGMatrix.h"
10 #include "mozilla/dom/SVGMatrixBinding.h"
11 #include "mozilla/FloatingPoint.h"
13 const double radPerDegree
= 2.0 * M_PI
/ 360.0;
15 namespace mozilla::dom
{
17 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(SVGMatrix
, mTransform
)
19 DOMSVGTransform
* SVGMatrix::GetParentObject() const { return mTransform
; }
21 JSObject
* SVGMatrix::WrapObject(JSContext
* aCx
,
22 JS::Handle
<JSObject
*> aGivenProto
) {
23 return SVGMatrix_Binding::Wrap(aCx
, this, aGivenProto
);
26 void SVGMatrix::SetA(float aA
, ErrorResult
& rv
) {
28 rv
.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR
);
32 gfxMatrix mx
= GetMatrix();
37 void SVGMatrix::SetB(float aB
, ErrorResult
& rv
) {
39 rv
.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR
);
43 gfxMatrix mx
= GetMatrix();
48 void SVGMatrix::SetC(float aC
, ErrorResult
& rv
) {
50 rv
.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR
);
54 gfxMatrix mx
= GetMatrix();
59 void SVGMatrix::SetD(float aD
, ErrorResult
& rv
) {
61 rv
.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR
);
65 gfxMatrix mx
= GetMatrix();
70 void SVGMatrix::SetE(float aE
, ErrorResult
& rv
) {
72 rv
.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR
);
76 gfxMatrix mx
= GetMatrix();
81 void SVGMatrix::SetF(float aF
, ErrorResult
& rv
) {
83 rv
.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR
);
87 gfxMatrix mx
= GetMatrix();
92 already_AddRefed
<SVGMatrix
> SVGMatrix::Multiply(SVGMatrix
& aMatrix
) {
93 return do_AddRef(new SVGMatrix(aMatrix
.GetMatrix() * GetMatrix()));
96 already_AddRefed
<SVGMatrix
> SVGMatrix::Inverse(ErrorResult
& rv
) {
97 gfxMatrix mat
= GetMatrix();
99 rv
.Throw(NS_ERROR_DOM_INVALID_STATE_ERR
);
102 return do_AddRef(new SVGMatrix(mat
));
105 already_AddRefed
<SVGMatrix
> SVGMatrix::Translate(float x
, float y
) {
107 new SVGMatrix(gfxMatrix(GetMatrix()).PreTranslate(gfxPoint(x
, y
))));
110 already_AddRefed
<SVGMatrix
> SVGMatrix::Scale(float scaleFactor
) {
111 return ScaleNonUniform(scaleFactor
, scaleFactor
);
114 already_AddRefed
<SVGMatrix
> SVGMatrix::ScaleNonUniform(float scaleFactorX
,
115 float scaleFactorY
) {
116 return do_AddRef(new SVGMatrix(
117 gfxMatrix(GetMatrix()).PreScale(scaleFactorX
, scaleFactorY
)));
120 already_AddRefed
<SVGMatrix
> SVGMatrix::Rotate(float angle
) {
122 new SVGMatrix(gfxMatrix(GetMatrix()).PreRotate(angle
* radPerDegree
)));
125 already_AddRefed
<SVGMatrix
> SVGMatrix::RotateFromVector(float x
, float y
,
127 if (x
== 0.0 || y
== 0.0) {
128 rv
.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR
);
133 new SVGMatrix(gfxMatrix(GetMatrix()).PreRotate(atan2(y
, x
))));
136 already_AddRefed
<SVGMatrix
> SVGMatrix::FlipX() {
137 const gfxMatrix
& mx
= GetMatrix();
138 return do_AddRef(new SVGMatrix(
139 gfxMatrix(-mx
._11
, -mx
._12
, mx
._21
, mx
._22
, mx
._31
, mx
._32
)));
142 already_AddRefed
<SVGMatrix
> SVGMatrix::FlipY() {
143 const gfxMatrix
& mx
= GetMatrix();
144 return do_AddRef(new SVGMatrix(
145 gfxMatrix(mx
._11
, mx
._12
, -mx
._21
, -mx
._22
, mx
._31
, mx
._32
)));
148 already_AddRefed
<SVGMatrix
> SVGMatrix::SkewX(float angle
, ErrorResult
& rv
) {
149 double ta
= tan(angle
* radPerDegree
);
150 if (!std::isfinite(ta
)) {
151 rv
.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR
);
155 const gfxMatrix
& mx
= GetMatrix();
156 gfxMatrix
skewMx(mx
._11
, mx
._12
, mx
._21
+ mx
._11
* ta
, mx
._22
+ mx
._12
* ta
,
158 return do_AddRef(new SVGMatrix(skewMx
));
161 already_AddRefed
<SVGMatrix
> SVGMatrix::SkewY(float angle
, ErrorResult
& rv
) {
162 double ta
= tan(angle
* radPerDegree
);
163 if (!std::isfinite(ta
)) {
164 rv
.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR
);
168 const gfxMatrix
& mx
= GetMatrix();
169 gfxMatrix
skewMx(mx
._11
+ mx
._21
* ta
, mx
._12
+ mx
._22
* ta
, mx
._21
, mx
._22
,
172 return do_AddRef(new SVGMatrix(skewMx
));
175 } // namespace mozilla::dom