Line data Source code
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/. */
6 :
7 : #include "mozilla/dom/SVGMatrix.h"
8 : #include "nsError.h"
9 : #include <math.h>
10 : #include "mozilla/dom/SVGMatrixBinding.h"
11 : #include "mozilla/FloatingPoint.h"
12 :
13 : const double radPerDegree = 2.0 * M_PI / 360.0;
14 :
15 : namespace mozilla {
16 : namespace dom {
17 :
18 0 : NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(SVGMatrix, mTransform)
19 :
20 0 : NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(SVGMatrix, AddRef)
21 0 : NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(SVGMatrix, Release)
22 :
23 : SVGTransform*
24 0 : SVGMatrix::GetParentObject() const
25 : {
26 0 : return mTransform;
27 : }
28 :
29 : JSObject*
30 0 : SVGMatrix::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
31 : {
32 0 : return SVGMatrixBinding::Wrap(aCx, this, aGivenProto);
33 : }
34 :
35 : void
36 0 : SVGMatrix::SetA(float aA, ErrorResult& rv)
37 : {
38 0 : if (IsAnimVal()) {
39 0 : rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
40 0 : return;
41 : }
42 :
43 0 : gfxMatrix mx = GetMatrix();
44 0 : mx._11 = aA;
45 0 : SetMatrix(mx);
46 : }
47 :
48 : void
49 0 : SVGMatrix::SetB(float aB, ErrorResult& rv)
50 : {
51 0 : if (IsAnimVal()) {
52 0 : rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
53 0 : return;
54 : }
55 :
56 0 : gfxMatrix mx = GetMatrix();
57 0 : mx._12 = aB;
58 0 : SetMatrix(mx);
59 : }
60 :
61 : void
62 0 : SVGMatrix::SetC(float aC, ErrorResult& rv)
63 : {
64 0 : if (IsAnimVal()) {
65 0 : rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
66 0 : return;
67 : }
68 :
69 0 : gfxMatrix mx = GetMatrix();
70 0 : mx._21 = aC;
71 0 : SetMatrix(mx);
72 : }
73 :
74 : void
75 0 : SVGMatrix::SetD(float aD, ErrorResult& rv)
76 : {
77 0 : if (IsAnimVal()) {
78 0 : rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
79 0 : return;
80 : }
81 :
82 0 : gfxMatrix mx = GetMatrix();
83 0 : mx._22 = aD;
84 0 : SetMatrix(mx);
85 : }
86 :
87 : void
88 0 : SVGMatrix::SetE(float aE, ErrorResult& rv)
89 : {
90 0 : if (IsAnimVal()) {
91 0 : rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
92 0 : return;
93 : }
94 :
95 0 : gfxMatrix mx = GetMatrix();
96 0 : mx._31 = aE;
97 0 : SetMatrix(mx);
98 : }
99 :
100 : void
101 0 : SVGMatrix::SetF(float aF, ErrorResult& rv)
102 : {
103 0 : if (IsAnimVal()) {
104 0 : rv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
105 0 : return;
106 : }
107 :
108 0 : gfxMatrix mx = GetMatrix();
109 0 : mx._32 = aF;
110 0 : SetMatrix(mx);
111 : }
112 :
113 : already_AddRefed<SVGMatrix>
114 0 : SVGMatrix::Multiply(SVGMatrix& aMatrix)
115 : {
116 0 : RefPtr<SVGMatrix> matrix = new SVGMatrix(aMatrix.GetMatrix() * GetMatrix());
117 0 : return matrix.forget();
118 : }
119 :
120 : already_AddRefed<SVGMatrix>
121 0 : SVGMatrix::Inverse(ErrorResult& rv)
122 : {
123 0 : gfxMatrix mat = GetMatrix();
124 0 : if (!mat.Invert()) {
125 0 : rv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
126 0 : return nullptr;
127 : }
128 0 : RefPtr<SVGMatrix> matrix = new SVGMatrix(mat);
129 0 : return matrix.forget();
130 : }
131 :
132 : already_AddRefed<SVGMatrix>
133 0 : SVGMatrix::Translate(float x, float y)
134 : {
135 : RefPtr<SVGMatrix> matrix =
136 0 : new SVGMatrix(gfxMatrix(GetMatrix()).PreTranslate(gfxPoint(x, y)));
137 0 : return matrix.forget();
138 : }
139 :
140 : already_AddRefed<SVGMatrix>
141 0 : SVGMatrix::Scale(float scaleFactor)
142 : {
143 0 : return ScaleNonUniform(scaleFactor, scaleFactor);
144 : }
145 :
146 : already_AddRefed<SVGMatrix>
147 0 : SVGMatrix::ScaleNonUniform(float scaleFactorX,
148 : float scaleFactorY)
149 : {
150 : RefPtr<SVGMatrix> matrix =
151 0 : new SVGMatrix(gfxMatrix(GetMatrix()).PreScale(scaleFactorX, scaleFactorY));
152 0 : return matrix.forget();
153 : }
154 :
155 : already_AddRefed<SVGMatrix>
156 0 : SVGMatrix::Rotate(float angle)
157 : {
158 : RefPtr<SVGMatrix> matrix =
159 0 : new SVGMatrix(gfxMatrix(GetMatrix()).PreRotate(angle*radPerDegree));
160 0 : return matrix.forget();
161 : }
162 :
163 : already_AddRefed<SVGMatrix>
164 0 : SVGMatrix::RotateFromVector(float x, float y, ErrorResult& rv)
165 : {
166 0 : if (x == 0.0 || y == 0.0) {
167 0 : rv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
168 0 : return nullptr;
169 : }
170 :
171 : RefPtr<SVGMatrix> matrix =
172 0 : new SVGMatrix(gfxMatrix(GetMatrix()).PreRotate(atan2(y, x)));
173 0 : return matrix.forget();
174 : }
175 :
176 : already_AddRefed<SVGMatrix>
177 0 : SVGMatrix::FlipX()
178 : {
179 0 : const gfxMatrix& mx = GetMatrix();
180 : RefPtr<SVGMatrix> matrix =
181 0 : new SVGMatrix(gfxMatrix(-mx._11, -mx._12, mx._21, mx._22, mx._31, mx._32));
182 0 : return matrix.forget();
183 : }
184 :
185 : already_AddRefed<SVGMatrix>
186 0 : SVGMatrix::FlipY()
187 : {
188 0 : const gfxMatrix& mx = GetMatrix();
189 : RefPtr<SVGMatrix> matrix =
190 0 : new SVGMatrix(gfxMatrix(mx._11, mx._12, -mx._21, -mx._22, mx._31, mx._32));
191 0 : return matrix.forget();
192 : }
193 :
194 : already_AddRefed<SVGMatrix>
195 0 : SVGMatrix::SkewX(float angle, ErrorResult& rv)
196 : {
197 0 : double ta = tan( angle*radPerDegree );
198 0 : if (!IsFinite(ta)) {
199 0 : rv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
200 0 : return nullptr;
201 : }
202 :
203 0 : const gfxMatrix& mx = GetMatrix();
204 0 : gfxMatrix skewMx(mx._11, mx._12,
205 0 : (float) (mx._21 + mx._11*ta), (float) (mx._22 + mx._12*ta),
206 0 : mx._31, mx._32);
207 0 : RefPtr<SVGMatrix> matrix = new SVGMatrix(skewMx);
208 0 : return matrix.forget();
209 : }
210 :
211 : already_AddRefed<SVGMatrix>
212 0 : SVGMatrix::SkewY(float angle, ErrorResult& rv)
213 : {
214 0 : double ta = tan( angle*radPerDegree );
215 0 : if (!IsFinite(ta)) {
216 0 : rv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
217 0 : return nullptr;
218 : }
219 :
220 0 : const gfxMatrix& mx = GetMatrix();
221 0 : gfxMatrix skewMx((float) (mx._11 + mx._21*ta), (float) (mx._12 + mx._22*ta),
222 0 : mx._21, mx._22,
223 0 : mx._31, mx._32);
224 :
225 0 : RefPtr<SVGMatrix> matrix = new SVGMatrix(skewMx);
226 0 : return matrix.forget();
227 : }
228 :
229 : } // namespace dom
230 : } // namespace mozilla
|