2
// Copyright (C) 2008 Free Software Foundation, Inc.
4
// This program is free software; you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation; either version 2 of the License, or
7
// (at your option) any later version.
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
// GNU General Public License for more details.
14
// You should have received a copy of the GNU General Public License
16
// along with this program; if not, write to the Free Software
17
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
// Test case for TextFormat ActionScript class
20
// compile this test case with Ming makeswf, and then
21
// execute it like this gnash -1 -r 0 -v out.swf
23
rcsid="$Id: Matrix.as,v 1.11 2008/06/19 11:49:17 bwy Exp $";
26
// There are lots of floating point calculations here. Comparing them
27
// as a string means they are checked to the 15th significant digit, which
28
// isn't always unreasonable. I've handled the ones that failed for me with
29
// an epsilon; others may fail for other people - so please edit as necessary
30
// - but it's good to be as accurate as possible.
32
// A ming bug up to version 0.4 beta 5 makes very large numbers fail.
35
ASSetPropFlags (_global, "flash", 0, 5248);
37
#if OUTPUT_VERSION < 6
39
check_equals(typeof(flash), 'undefined');
45
Matrix = flash.geom.Matrix;
46
check_equals(typeof(Matrix), 'function');
47
check_equals(typeof(Matrix.prototype), 'object');
48
check(Matrix.prototype.hasOwnProperty('identity'));
49
check(Matrix.prototype.hasOwnProperty('rotate'));
50
check(Matrix.prototype.hasOwnProperty('concat'));
51
check(Matrix.prototype.hasOwnProperty('translate'));
52
check(Matrix.prototype.hasOwnProperty('scale'));
53
check(Matrix.prototype.hasOwnProperty('transformPoint'));
54
check(Matrix.prototype.hasOwnProperty('deltaTransformPoint'));
55
check(Matrix.prototype.hasOwnProperty('createBox'));
56
check(Matrix.prototype.hasOwnProperty('clone'));
57
check(Matrix.prototype.hasOwnProperty('createGradientBox'));
58
check(Matrix.prototype.hasOwnProperty('invert'));
59
check(Matrix.prototype.hasOwnProperty('toString'));
60
check(!Matrix.prototype.hasOwnProperty('a'));
61
check(!Matrix.prototype.hasOwnProperty('b'));
62
check(!Matrix.prototype.hasOwnProperty('c'));
63
check(!Matrix.prototype.hasOwnProperty('d'));
64
check(!Matrix.prototype.hasOwnProperty('tx'));
65
check(!Matrix.prototype.hasOwnProperty('ty'));
67
//-------------------------------------------------------------
69
//-------------------------------------------------------------
72
check_equals(typeof(m), 'object');
73
check(m instanceof Matrix);
74
check(m.hasOwnProperty('a'));
75
check(m.hasOwnProperty('b'));
76
check(m.hasOwnProperty('c'));
77
check(m.hasOwnProperty('d'));
78
check(m.hasOwnProperty("tx"));
79
check(m.hasOwnProperty("ty"));
85
check_equals(m.tx, 0);
86
check_equals(m.ty, 0);
88
check_equals (m.toString(), "(a=1, b=0, c=0, d=1, tx=0, ty=0)");
91
check_equals(m.b, "5.4");
94
check_equals(m.c, "4.548759874");
97
// PP: (a=4.10203808667724, b=-3.65147689783865, c=-1.49969051027619, d=-4.40932475155777, tx=0, ty=0)
98
// Some of these may be accurate enough:
99
check_equals(m.toString(), "(a=4.10203808667724, b=-3.65147689783865, c=-1.49969051027619, d=-4.40932475155777, tx=0, ty=0)");
100
check (m.a < 4.1020381 && m.a > 4.1020379);
101
check (m.b < -3.6514768 && m.b > -3.6514769);
102
check (m.c < -1.49969051 && m.c > -1.49969052);
103
check (m.d < -4.40932475 && m.d > -4.40932476);
107
// A non-matrix with a matrix's rotate method (fails?).
108
fakematrix = {a:1, b:1, c: 1, d: 1, tx:5, ty: 5};
109
fakematrix.rotate = Matrix.prototype.rotate;
110
fakematrix.rotate(2);
111
check_equals(fakematrix.a.toString(), 1);
112
check_equals(fakematrix.b.toString(), 1);
113
check_equals(fakematrix.c.toString(), 1);
114
check_equals(fakematrix.d.toString(), 1);
115
check_equals(fakematrix.tx.toString(), 5);
116
check_equals(fakematrix.ty.toString(), 5);
118
m.scale(-343, 0.33874983);
119
check_equals (m.toString(), "(a=-1406.99906373029, b=-1.23693717839177, c=514.393845024734, d=-1.49365801000499, tx=0, ty=0)");
121
m.translate(333,-283747.22);
122
check_equals (m.toString(), "(a=-1406.99906373029, b=-1.23693717839177, c=514.393845024734, d=-1.49365801000499, tx=333, ty=-283747.22)");
124
// A non-matrix with a matrix's translate method (works).
125
fakematrix = {a:1, b:1, c: 1, d: 1, tx:5, ty: 5};
126
fakematrix.translate = Matrix.prototype.translate;
127
fakematrix.translate(200,400);
128
check_equals(fakematrix.tx.toString(), 205);
129
check_equals(fakematrix.ty.toString(), 405);
131
m.scale(4798747e+98, 0.33874983);
132
// PP: (a=-6.75183253607854e+107, b=-0.419012258900892, c=2.46844592063091e+107, d=-0.505976396967328, tx=1.597982751e+107, ty=-96119.3225379726)
133
// I get one discrepancy in 'a' here.
134
#if MING_VERSION_CODE > 00040005
135
check(m.a < -6.7518325360784e+107 && m.a > -6.7518325360786e+107)
136
check_equals(m.c.toString(), "2.46844592063091e+107");
137
check_equals(m.tx.toString(), "1.597982751e+107");
139
check_equals(m.b.toString(), "-0.419012258900892");
140
check_equals(m.d.toString(), "-0.505976396967328");
141
check_equals(m.ty.toString(), "-96119.3225379726");
143
m.rotate(-1.2873874);
144
// PP: (a=-1.888016310255e+107, b=6.48248694618508e+107, c=6.9025203664787e+106, d=-2.36997413255563e+107, tx=4.46844242844096e+106, ty=-1.53423567131344e+107)
145
// tx is slightly different for me.
146
#if MING_VERSION_CODE > 00040005
147
check_equals(m.a.toString(), "-1.888016310255e+107");
148
check_equals(m.b.toString(), "6.48248694618508e+107");
149
check_equals(m.c.toString(), "6.9025203664787e+106");
150
check_equals(m.d.toString(), "-2.36997413255563e+107");
151
check(m.tx < 4.46844242844097e+106 && m.tx > 4.46844242844095e+106)
152
check_equals(m.ty.toString(), "-1.53423567131344e+107");
156
#if OUTPUT_VERSION > 6
157
check_equals(m1.toString(), "(a=8, b=undefined, c=undefined, d=undefined, tx=undefined, ty=undefined)");
159
xcheck_equals(m1.toString(), "(a=8, b=, c=, d=, tx=, ty=)");
162
m1 = new Matrix(1, 2, 3, 4, 5, 6);
163
check_equals(m1.toString(), "(a=1, b=2, c=3, d=4, tx=5, ty=6)");
166
check_equals(m1.toString(), "(a=32, b=-6.8, c=96, d=-13.6, tx=160, ty=-20.4)");
167
// Do not change m1; it's used later to test concat!
172
// PP: "(a=-1, b=1.22460635382238e-16, c=-1.22460635382238e-16, d=-1, tx=0, ty=0) ");
173
check_equals (m2.a, -1);
174
check (m2.b < 0.00000000001 && m2.b > -0.000000000001);
175
check (m2.c < 0.00000000001 && m2.c > -0.000000000001);
183
//PP: (a=0.267498828624587, b=0.963558185417193, c=-0.963558185417193, d=0.267498828624587, tx=0, ty=0)
184
check (m2.b < 0.96355819 && m2.b > 0.96355818);
185
check (m2.c < -0.96355818 && m2.c > -0.96355819);
186
check (m2.d < 0.26749883 && m2.d > 0.26749881);
189
// Do not change m2 after this; it's used later to test concat!
192
/// Test deltaTransform of Point
194
Point = flash.geom.Point;
195
p = new Point(34, -23);
196
newP = m2.deltaTransformPoint(p);
197
check_equals(typeof(newP), "object");
198
check_equals(newP.toString(), "(x=31.2567984378314, y=26.6085052458191)");
200
fakepoint = {x: 34, y: -23};
201
newP2 = m2.deltaTransformPoint(fakepoint);
202
check_equals(typeof(newP2), "object");
203
check(newP2 instanceof Point);
204
check_equals(newP.toString(), newP2.toString());
210
m3 = new Matrix(2, 0, 0, 2, 100, 100);
212
check_equals(m3.toString(), "(a=6, b=0, c=0, d=8, tx=300, ty=400)");
213
// Do not change m3; it is used to test invert!
215
// A non-matrix with a matrix's invert method (fails?).
216
fakematrix = {a:3, b:2, c: 5, d: 3, tx:5, ty: 5};
217
fakematrix.scale = Matrix.prototype.scale;
218
fakematrix.scale(4, 5);
219
check_equals(fakematrix.a.toString(), "3");
220
check_equals(fakematrix.b.toString(), "2");
221
check_equals(fakematrix.c.toString(), "5");
222
check_equals(fakematrix.d.toString(), "3");
223
check_equals(fakematrix.tx.toString(), "5");
224
check_equals(fakematrix.ty.toString(), "5");
225
fakematrix.toString = Matrix.prototype.toString;
226
check_equals(fakematrix.toString(), "(a=3, b=2, c=5, d=3, tx=5, ty=5)");
230
check_equals(m4.toString(), "(a=6, b=0, c=0, d=8, tx=300, ty=400)");
231
// Do not change m4; it's used later to test concat!
233
// A non-matrix with a matrix's invert method (works).
234
fakematrix = {a:3, b:2, c: 5, d: 3, tx:5, ty: 5};
235
fakematrix.clone = Matrix.prototype.clone;
236
r = fakematrix.clone();
237
check_equals(r.toString(), "(a=3, b=2, c=5, d=3, tx=5, ty=5)");
238
check(r instanceof Matrix);
243
check_equals(m3.toString(), "(a=0.166666666666667, b=0, c=0, d=0.125, tx=-50, ty=-50)");
246
m6 = new Matrix(4, 5, 44, 55, 2, 4);
247
check_equals(m6.toString(), "(a=4, b=5, c=44, d=55, tx=2, ty=4)");
249
check_equals(m6.toString(), "(a=1, b=0, c=0, d=1, tx=0, ty=0)");
251
// A non-matrix with a matrix's invert method (half works).
252
fakematrix = {a:3, b:2, c: 5, d: 3, tx:5, ty: 5};
253
fakematrix.invert = Matrix.prototype.invert;
255
xcheck_equals(fakematrix.tx.toString(), "NaN");
256
check_equals(fakematrix.a.toString(), -3);
259
m6 = new Matrix(4, 5, 0, 5, 2, 3);
260
check_equals(m6.toString(), "(a=4, b=5, c=0, d=5, tx=2, ty=3)");
262
check_equals(m6.toString(), "(a=0.25, b=-0.25, c=0, d=0.2, tx=-0.5, ty=-0.1)");
264
check_equals(m6.toString(), "(a=0.0995392558215424, b=-0.339252025123644, c=0.0958851077208406, d=0.175516512378075, tx=-0.486733834805607, ty=0.151954513113064)");
266
check_equals(m6.toString(), "(a=3.51033024756149, b=6.78504050247288, c=-1.91770215441681, d=1.99078511643085, tx=2, ty=3)");
269
// Matrix.transformPoint (and deltaTransformPoint again)
270
p = new Point(23, 95);
271
p2 = m6.transformPoint(p);
272
check_equals(p2.toString(), "(x=-99.4441089756828, y=348.180517617807)");
273
p3 = m6.deltaTransformPoint(p);
274
check_equals(p3.toString(), "(x=-101.444108975683, y=345.180517617807)");
275
p2 = m6.transformPoint(p2);
276
check_equals(p2.toString(), "(x=-1014.78819244077, y=21.420285172384)");
278
// Transforming points with a fake matrix.
279
fakematrix = {a:3, b:2, c: 5, d: 3, tx:5, ty: 5};
280
fakematrix.deltaTransformPoint = Matrix.prototype.deltaTransformPoint;
281
f = fakematrix.deltaTransformPoint(p2);
282
check (f instanceof Point);
283
check_equals (f.toString(), "(x=-2937.26315146039, y=-1965.31552936439)");
285
fakematrix.transformPoint = Matrix.prototype.transformPoint;
286
f = fakematrix.transformPoint(p2);
287
check (f instanceof Point);
288
check_equals (f.toString(), "(x=-2932.26315146039, y=-1960.31552936439)");
291
// Rotation applies to translation
292
m3 = new Matrix(1, 0, 0, 1, 2, 2);
293
m3.rotate (Math.PI / 2);
294
// PP: "(a=6.12303176911189e-17, b=1, c=-1, d=6.12303176911189e-17, tx=-2, ty=2)"
295
check_equals(m3.b.toString(), "1");
296
check_equals(m3.c.toString(), "-1");
297
check_equals(m3.tx.toString(), "-2");
298
check_equals(m3.ty.toString(), "2");
301
/// identity() returns void.
302
check_equals(m5, undefined);
303
check_equals(m3.a.toString(), "1");
304
check_equals(m3.b.toString(), "0");
305
check_equals(m3.c.toString(), "0");
306
check_equals(m3.d.toString(), "1");
307
check_equals(m3.tx.toString(), "0");
308
check_equals(m3.ty.toString(), "0");
311
check_equals(t.a, undefined)
312
t.identity = Matrix.prototype.identity;
314
check_equals(t.a.toString(), "1");
315
check_equals(t.b.toString(), "0");
316
check_equals(t.c.toString(), "0");
317
check_equals(t.d.toString(), "1");
318
check_equals(t.tx.toString(), "0");
319
check_equals(t.ty.toString(), "0");
321
// m4 is still interesting
323
check_equals(m4.toString(), "(a=192, b=-40.8, c=768, d=-108.8, tx=48160, ty=-7500.4)");
326
check_equals(m4.toString(), "(a=90.6729490609422, b=174.089219392218, c=310.274230957074, d=710.908813846049, tx=20109.8154004632, ty=44398.6139954762)");
328
// A non-matrix with a matrix's concat method (works).
329
fakematrix = {a:1, b:1, c: 1, d: 1, tx:5, ty: 5};
330
fakematrix.concat = Matrix.prototype.concat;
331
fakematrix.concat(new Matrix(4, 4, 4, 4, 4, 4));
332
check_equals(fakematrix.tx.toString(), 44);
333
check_equals(fakematrix.a.toString(), 8);
335
m7 = new Matrix ("A string", undefined, new Object, true, NaN, new Point);
336
#if OUTPUT_VERSION > 6
337
check_equals("" + m7, "(a=A string, b=undefined, c=[object Object], d=true, tx=NaN, ty=(x=0, y=0))");
339
xcheck_equals("" + m7, "(a=A string, b=, c=[object Object], d=true, tx=NaN, ty=(x=0, y=0))");
343
check_equals(m7.toString(), "(a=NaN, b=NaN, c=NaN, d=NaN, tx=NaN, ty=NaN)");
345
m8 = new Matrix(5, 4, 5, 3, 2, 1);
346
check_equals(m8.toString(), "(a=5, b=4, c=5, d=3, tx=2, ty=1)");
347
m8.createBox(4, 3, 4, 2, 3);
348
check_equals(m8.toString(), "(a=-2.61457448345445, b=-2.27040748592378, c=3.02720998123171, d=-1.96093086259084, tx=2, ty=3)");
349
m8.createBox(45, 444, -1.3874987, -47, -2999398);
350
check_equals(m8.toString(), "(a=8.2022824555003, b=-436.562099487155, c=44.2461587318062, d=80.9291868942697, tx=-47, ty=-2999398)");
351
m8.createBox(4, 3, new Object(), "a string");
352
check_equals(m8.toString(), "(a=NaN, b=NaN, c=NaN, d=NaN, tx=a string, ty=0)");
353
m8.createBox("a", "b");
354
#if OUTPUT_VERSION > 6
355
check_equals(m8.toString(), "(a=NaN, b=NaN, c=NaN, d=NaN, tx=0, ty=0)");
357
xcheck_equals(m8.toString(), "(a=NaN, b=0, c=0, d=NaN, tx=0, ty=0)");
360
// A non-matrix with a matrix's createBox method (half works).
362
fakematrix = new Object();
363
fakematrix.createBox = Matrix.prototype.createBox;
364
fakematrix.createBox(4, 3, 4, 2, 3);
365
xcheck_equals(fakematrix.a.toString(), undefined);
366
xcheck_equals(fakematrix.b.toString(), undefined);
367
xcheck_equals(fakematrix.c.toString(), undefined);
368
xcheck_equals(fakematrix.d.toString(), undefined);
369
check_equals(fakematrix.tx.toString(), "2");
370
check_equals(fakematrix.ty.toString(), "3");
373
m8.createGradientBox(20, 30, 2 * Math.PI, 10, 25);
375
// The very small numbers aren't very 'accurate', of course.
376
check_equals(m8.a.toString(), "0.01220703125");
377
check_equals(m8.d.toString(), "0.018310546875");
378
check_equals(m8.tx.toString(), "20");
379
check_equals(m8.ty.toString(), "40");
380
check(Math.abs(m8.b) < 0.0000000000001);
381
check(Math.abs(m8.c) < 0.0000000000001);
383
m8.createGradientBox(40, 49, 0, "string", undefined);
384
// Half of the width is added to the translation - they take that quite literally...
385
#if OUTPUT_VERSION > 6
386
check_equals(m8.toString(), "(a=0.0244140625, b=0, c=0, d=0.0299072265625, tx=string20, ty=NaN)");
388
check_equals(m8.toString(), "(a=0.0244140625, b=0, c=0, d=0.0299072265625, tx=string20, ty=24.5)");
390
m8.createGradientBox(5, 6, 0, 1, 1);
391
check_equals(m8.toString(), "(a=0.0030517578125, b=0, c=0, d=0.003662109375, tx=3.5, ty=4)");
392
m8.createGradientBox(5, 6, 2, 1, 1);
393
check_equals(m8.toString(), "(a=-0.0012699793595799, b=0.00332994663144171, c=-0.00277495552620142, d=-0.00152397523149588, tx=3.5, ty=4)");
395
// A non-matrix with a matrix's createGradientBox method (fails).
397
fakematrix = new Object();
398
fakematrix.createGradientBox = Matrix.prototype.createGradientBox;
399
fakematrix.createGradientBox(20, 30, 2 * Math.PI, 10, 25);
400
check_equals(fakematrix.a.toString(), undefined);
401
check_equals(fakematrix.b.toString(), undefined);
402
check_equals(fakematrix.c.toString(), undefined);
403
check_equals(fakematrix.d.toString(), undefined);
404
check_equals(fakematrix.tx.toString(), undefined);
405
check_equals(fakematrix.ty.toString(), undefined);
408
//-------------------------------------------------------------
410
//-------------------------------------------------------------
411
#if MING_VERSION_CODE > 00040005
417
#endif // OUTPUT_VERSION >= 8