1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.javascript.host.svg;
16
17 import org.htmlunit.corejs.javascript.VarScope;
18 import org.htmlunit.javascript.HtmlUnitScriptable;
19 import org.htmlunit.javascript.JavaScriptEngine;
20 import org.htmlunit.javascript.configuration.JsxClass;
21 import org.htmlunit.javascript.configuration.JsxConstructor;
22 import org.htmlunit.javascript.configuration.JsxFunction;
23 import org.htmlunit.javascript.configuration.JsxGetter;
24 import org.htmlunit.javascript.configuration.JsxSetter;
25 import org.htmlunit.javascript.host.dom.DOMException;
26
27
28
29
30
31
32
33
34
35 @JsxClass
36 public class SVGMatrix extends HtmlUnitScriptable {
37
38 private double shearX_;
39 private double shearY_;
40 private double scaleX_;
41 private double scaleY_;
42 private double translateX_;
43 private double translateY_;
44
45
46
47
48 public SVGMatrix() {
49 super();
50
51 shearX_ = 0.0;
52 shearY_ = 0.0;
53 scaleX_ = 1.0;
54 scaleY_ = 1.0;
55 translateX_ = 0.0;
56 translateY_ = 0.0;
57 }
58
59
60
61
62 @JsxConstructor
63 public void jsConstructor() {
64
65 }
66
67
68
69
70
71
72 public SVGMatrix(final VarScope scope) {
73 this();
74 setParentScope(scope);
75 setPrototype(getPrototype(getClass()));
76 }
77
78
79
80
81
82
83 @JsxGetter
84 public double getA() {
85 return scaleX_;
86 }
87
88
89
90
91
92
93 @JsxGetter
94 public double getB() {
95 return shearY_;
96 }
97
98
99
100
101
102
103 @JsxGetter
104 public double getC() {
105 return shearX_;
106 }
107
108
109
110
111
112
113 @JsxGetter
114 public double getD() {
115 return scaleY_;
116 }
117
118
119
120
121
122
123 @JsxGetter
124 public double getE() {
125 return translateX_;
126 }
127
128
129
130
131
132
133 @JsxGetter
134 public double getF() {
135 return translateY_;
136 }
137
138
139
140
141
142
143 @JsxSetter
144 public void setA(final double newValue) {
145 scaleX_ = newValue;
146 }
147
148
149
150
151
152
153 @JsxSetter
154 public void setB(final double newValue) {
155 shearY_ = newValue;
156 }
157
158
159
160
161
162
163 @JsxSetter
164 public void setC(final double newValue) {
165 shearX_ = newValue;
166 }
167
168
169
170
171
172
173 @JsxSetter
174 public void setD(final double newValue) {
175 scaleY_ = newValue;
176 }
177
178
179
180
181
182
183 @JsxSetter
184 public void setE(final double newValue) {
185 translateX_ = newValue;
186 }
187
188
189
190
191
192
193 @JsxSetter
194 public void setF(final double newValue) {
195 translateY_ = newValue;
196 }
197
198
199
200
201
202
203 @JsxFunction
204 public SVGMatrix flipX() {
205 final SVGMatrix result = new SVGMatrix(getParentScope());
206 result.shearX_ = shearX_;
207 result.shearY_ = -shearY_;
208 result.scaleX_ = -scaleX_;
209 result.scaleY_ = scaleY_;
210 result.translateX_ = translateX_;
211 result.translateY_ = translateY_;
212
213 return result;
214 }
215
216
217
218
219
220
221 @JsxFunction
222 public SVGMatrix flipY() {
223 final SVGMatrix result = new SVGMatrix(getParentScope());
224 result.shearX_ = -shearX_;
225 result.shearY_ = shearY_;
226 result.scaleX_ = scaleX_;
227 result.scaleY_ = -scaleY_;
228 result.translateX_ = translateX_;
229 result.translateY_ = translateY_;
230
231 return result;
232 }
233
234
235
236
237
238
239 @JsxFunction
240 public SVGMatrix inverse() {
241 final double determinant = scaleX_ * scaleY_ - shearX_ * shearY_;
242
243 if (Math.abs(determinant) < 1E-10) {
244 throw JavaScriptEngine.asJavaScriptException(
245 getWindow(),
246 "Failed to execute 'inverse' on 'SVGMatrix': The matrix is not invertible.",
247 DOMException.INVALID_STATE_ERR);
248 }
249
250 final SVGMatrix result = new SVGMatrix(getParentScope());
251 result.shearX_ = -shearX_ / determinant;
252 result.shearY_ = -shearY_ / determinant;
253 result.scaleX_ = scaleY_ / determinant;
254 result.scaleY_ = scaleX_ / determinant;
255 result.translateX_ = (shearX_ * translateY_ - scaleY_ * translateX_) / determinant;
256 result.translateY_ = (shearY_ * translateX_ - scaleX_ * translateY_) / determinant;
257
258 return result;
259 }
260
261
262
263
264
265
266
267 @JsxFunction
268 public SVGMatrix multiply(final SVGMatrix by) {
269 final SVGMatrix result = new SVGMatrix(getParentScope());
270
271 result.shearX_ = by.shearX_ * scaleX_ + by.scaleY_ * shearX_;
272 result.shearY_ = by.scaleX_ * shearY_ + by.shearY_ * scaleY_;
273 result.scaleX_ = by.scaleX_ * scaleX_ + by.shearY_ * shearX_;
274 result.scaleY_ = by.shearX_ * shearY_ + by.scaleY_ * scaleY_;
275 result.translateX_ = by.translateX_ * scaleX_ + by.translateY_ * shearX_ + translateX_;
276 result.translateY_ = by.translateX_ * shearY_ + by.translateY_ * scaleY_ + translateY_;
277
278 return result;
279 }
280
281
282
283
284
285
286
287 @JsxFunction
288 public SVGMatrix rotate(final double angle) {
289 final double theta = Math.toRadians(angle);
290 final double sin = Math.sin(theta);
291 final double cos = Math.cos(theta);
292
293 final SVGMatrix result = new SVGMatrix(getParentScope());
294
295 result.shearX_ = -sin * scaleX_ + cos * shearX_;
296 result.shearY_ = cos * shearY_ + sin * scaleY_;
297 result.scaleX_ = cos * scaleX_ + sin * shearX_;
298 result.scaleY_ = -sin * shearY_ + cos * scaleY_;
299 result.translateX_ = translateX_;
300 result.translateY_ = translateY_;
301
302 return result;
303 }
304
305
306
307
308
309
310
311
312
313 @JsxFunction
314 public SVGMatrix rotateFromVector(final double x, final double y) {
315 if (x == 0 || y == 0) {
316 throw JavaScriptEngine.asJavaScriptException(
317 getWindow(),
318 "Failed to execute 'rotateFromVector' on 'SVGMatrix': Arguments cannot be zero.",
319 DOMException.INVALID_ACCESS_ERR);
320 }
321
322 final double theta = Math.atan2(y, x);
323 final double sin = Math.sin(theta);
324 final double cos = Math.cos(theta);
325
326 final SVGMatrix result = new SVGMatrix(getParentScope());
327
328 result.shearX_ = -sin * scaleX_ + cos * shearX_;
329 result.shearY_ = cos * shearY_ + sin * scaleY_;
330 result.scaleX_ = cos * scaleX_ + sin * shearX_;
331 result.scaleY_ = -sin * shearY_ + cos * scaleY_;
332 result.translateX_ = translateX_;
333 result.translateY_ = translateY_;
334
335 return result;
336 }
337
338
339
340
341
342
343
344 @JsxFunction
345 public SVGMatrix scale(final double factor) {
346 return scaleNonUniform(factor, factor);
347 }
348
349
350
351
352
353
354
355
356
357 @JsxFunction
358 public SVGMatrix scaleNonUniform(final double factorX, final double factorY) {
359 final SVGMatrix result = new SVGMatrix(getParentScope());
360
361 result.shearX_ = factorY * shearX_;
362 result.shearY_ = factorX * shearY_;
363 result.scaleX_ = factorX * scaleX_;
364 result.scaleY_ = factorY * scaleY_;
365 result.translateX_ = translateX_;
366 result.translateY_ = translateY_;
367
368 return result;
369 }
370
371
372
373
374
375
376
377
378 @JsxFunction
379 public SVGMatrix skewX(final double angle) {
380 final double shear = Math.tan(Math.toRadians(angle));
381
382 final SVGMatrix result = new SVGMatrix(getParentScope());
383
384 result.shearX_ = shear * scaleX_ + shearX_;
385 result.shearY_ = shearY_;
386 result.scaleX_ = scaleX_;
387 result.scaleY_ = shear * shearY_ + scaleY_;
388 result.translateX_ = translateX_;
389 result.translateY_ = translateY_;
390
391 return result;
392 }
393
394
395
396
397
398
399
400
401 @JsxFunction
402 public SVGMatrix skewY(final double angle) {
403 final double shear = Math.tan(Math.toRadians(angle));
404
405 final SVGMatrix result = new SVGMatrix(getParentScope());
406
407 result.shearX_ = shearX_;
408 result.shearY_ = shearY_ + shear * scaleY_;
409 result.scaleX_ = scaleX_ + shear * shearX_;
410 result.scaleY_ = scaleY_;
411 result.translateX_ = translateX_;
412 result.translateY_ = translateY_;
413
414 return result;
415 }
416
417
418
419
420
421
422
423
424 @JsxFunction
425 public SVGMatrix translate(final double x, final double y) {
426 final SVGMatrix result = new SVGMatrix(getParentScope());
427
428 result.shearX_ = shearX_;
429 result.shearY_ = shearY_;
430 result.scaleX_ = scaleX_;
431 result.scaleY_ = scaleY_;
432 result.translateX_ = x * scaleX_ + y * shearX_ + translateX_;
433 result.translateY_ = x * shearY_ + y * scaleY_ + translateY_;
434
435 return result;
436 }
437 }