@swf2es/player-hosts 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/thread/format/bitmap.js +13 -14
- package/dist/thread/format/index.js +1 -1
- package/dist/thread/format/swf.js +11 -1
- package/dist/thread/player/avm1/globals/BitmapData.js +2 -1
- package/dist/thread/player/bitmap/composite.js +767 -0
- package/dist/thread/player/bitmap/draw.js +3 -3
- package/dist/thread/player/bitmap/filters.js +32 -32
- package/dist/thread/player/bitmap/ops.js +2 -766
- package/dist/thread/player/bitmap/pixel-bender.js +4 -1
- package/dist/thread/player/display/bounds.js +105 -0
- package/dist/thread/player/display/displayobject.js +1 -1
- package/dist/thread/player/display/drawing.js +25 -10
- package/dist/thread/player/display/instantiate.js +28 -29
- package/dist/thread/player/display/shapes.js +72 -54
- package/dist/thread/player/display/textobjects.js +34 -1
- package/dist/thread/player/player.js +4 -3
- package/dist/thread/player/playerglobal/flash/desktop/NativeApplication.js +1 -1
- package/dist/thread/player/playerglobal/flash/display/BitmapData.js +3 -2
- package/dist/thread/player/playerglobal/flash/display/DisplayObject.js +2 -2
- package/dist/thread/player/playerglobal/flash/display/SimpleButton.js +12 -11
- package/dist/thread/player/playerglobal/flash/display/Stage.js +2 -8
- package/dist/thread/player/playerglobal/flash/display/shaders.js +1 -1
- package/dist/thread/player/playerglobal/flash/filesystem/paths.js +1 -1
- package/dist/thread/player/playerglobal/flash/filesystem/writes.js +1 -1
- package/dist/thread/player/playerglobal/flash/globalization/locale.js +1 -1
- package/dist/thread/player/scripting/events.js +2 -2
- package/dist/thread/player/scripting/lifecycle.js +39 -19
- package/dist/thread/player/scripting/symbols.js +24 -30
- package/dist/thread/player/scripting.js +5 -9
- package/dist/thread/runtime/avm1/errors.js +1 -1
- package/dist/thread/runtime/avm1/numbers.js +7 -8
- package/dist/thread/runtime/avm2/amf.js +2 -1
- package/dist/thread/runtime/avm2/names.js +0 -4
- package/dist/thread/runtime/avm2/natives/bytearray.js +6 -166
- package/dist/thread/runtime/avm2/natives/regexp.js +68 -64
- package/dist/thread/runtime/avm2/natives/shell-workers.js +1 -1
- package/dist/thread/runtime/avm2/natives/shell.js +2 -1
- package/dist/thread/runtime/avm2/natives/xml/parser.js +2 -2
- package/dist/thread/runtime/avm2/numbers.js +1 -1
- package/dist/thread/runtime/avm2/runtime.js +10 -8
- package/dist/thread/runtime/avm2/traits.js +1 -1
- package/dist/thread/runtime/avm2/utf8.js +167 -0
- package/package.json +2 -2
|
@@ -767,7 +767,10 @@ export class PixelBender {
|
|
|
767
767
|
}
|
|
768
768
|
}
|
|
769
769
|
}
|
|
770
|
-
/**
|
|
770
|
+
/**
|
|
771
|
+
* A float as a bitmap's byte: clamped, NaN as 0, then rounded to the nearest, a half to the even.
|
|
772
|
+
* @public tests/player/pixel-bender.ts imports it into Chrome by name.
|
|
773
|
+
*/
|
|
771
774
|
export function outputByte(v) {
|
|
772
775
|
const c = v > 0 ? (v < 1 ? v : 1) : 0;
|
|
773
776
|
return nearest(Math.fround(c * 255));
|
|
@@ -25,6 +25,7 @@ export function ownBounds(d, lines) {
|
|
|
25
25
|
: null;
|
|
26
26
|
}
|
|
27
27
|
if (d instanceof TextObject) {
|
|
28
|
+
d.settle();
|
|
28
29
|
return { xMin: d.left, yMin: d.top, xMax: d.left + d.width, yMax: d.top + d.height };
|
|
29
30
|
}
|
|
30
31
|
if (d instanceof VideoObject) {
|
|
@@ -95,12 +96,116 @@ export function placedRect(d, r, drawn = false) {
|
|
|
95
96
|
const box = transformRect(r, own);
|
|
96
97
|
return back ? boxThrough(box, back) : box;
|
|
97
98
|
}
|
|
99
|
+
// Scratch matrices for boundsIn's flat case: getRect and getBounds are asked of every moved
|
|
100
|
+
// sprite, every frame, by some movies, and these leave nothing behind for the collector.
|
|
101
|
+
const scratchUp = { a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0 };
|
|
102
|
+
const scratchDown = { a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0 };
|
|
103
|
+
const scratchBoth = { a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0 };
|
|
104
|
+
/** `m` set to `p`'s six numbers. */
|
|
105
|
+
function copyInto(m, p) {
|
|
106
|
+
m.a = p.a;
|
|
107
|
+
m.b = p.b;
|
|
108
|
+
m.c = p.c;
|
|
109
|
+
m.d = p.d;
|
|
110
|
+
m.tx = p.tx;
|
|
111
|
+
m.ty = p.ty;
|
|
112
|
+
}
|
|
113
|
+
/** `m` then `p` into `out`, as concat multiplies two flat matrices; `out` may be `m`. */
|
|
114
|
+
function concatInto(out, m, p) {
|
|
115
|
+
const a = m.a * p.a + m.b * p.c;
|
|
116
|
+
const b = m.a * p.b + m.b * p.d;
|
|
117
|
+
const c = m.c * p.a + m.d * p.c;
|
|
118
|
+
const d = m.c * p.b + m.d * p.d;
|
|
119
|
+
const tx = m.tx * p.a + m.ty * p.c + p.tx;
|
|
120
|
+
const ty = m.tx * p.b + m.ty * p.d + p.ty;
|
|
121
|
+
out.a = a;
|
|
122
|
+
out.b = b;
|
|
123
|
+
out.c = c;
|
|
124
|
+
out.d = d;
|
|
125
|
+
out.tx = tx;
|
|
126
|
+
out.ty = ty;
|
|
127
|
+
}
|
|
128
|
+
// `placed` of one with a scrollRect, shifted as geometry's shifted shifts it, without a new matrix.
|
|
129
|
+
const scratchPlaced = { a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0 };
|
|
130
|
+
/** `d.placed` if flat, into scratchPlaced where a scroll shifts it; null for a projective one. */
|
|
131
|
+
function flatPlaced(d) {
|
|
132
|
+
if (d.space) {
|
|
133
|
+
const m = d.placed;
|
|
134
|
+
return isProjective(m) ? null : m;
|
|
135
|
+
}
|
|
136
|
+
const m = d.matrix;
|
|
137
|
+
if (isProjective(m)) {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
const r = d.scroll;
|
|
141
|
+
if (!r) {
|
|
142
|
+
return m;
|
|
143
|
+
}
|
|
144
|
+
copyInto(scratchPlaced, m);
|
|
145
|
+
scratchPlaced.tx = m.tx - m.a * r.xMin - m.c * r.yMin;
|
|
146
|
+
scratchPlaced.ty = m.ty - m.b * r.xMin - m.d * r.yMin;
|
|
147
|
+
return scratchPlaced;
|
|
148
|
+
}
|
|
149
|
+
/** toStage into `out`, if every matrix on the way is flat; false, `out` spoilt, otherwise. */
|
|
150
|
+
function flatToStage(d, stage, out) {
|
|
151
|
+
const own = flatPlaced(d);
|
|
152
|
+
if (!own) {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
copyInto(out, own);
|
|
156
|
+
for (let p = d.parent; p && p !== stage; p = p.parent) {
|
|
157
|
+
const m = flatPlaced(p);
|
|
158
|
+
if (!m) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
concatInto(out, out, m);
|
|
162
|
+
}
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
/** `m` inverted in place, as invert does; left as it is, as invert's null is, when flat. */
|
|
166
|
+
function invertFlat(m) {
|
|
167
|
+
const det = m.a * m.d - m.b * m.c;
|
|
168
|
+
if (det === 0) {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
const a = m.d / det;
|
|
172
|
+
const b = -m.b / det;
|
|
173
|
+
const c = -m.c / det;
|
|
174
|
+
const d = m.a / det;
|
|
175
|
+
const tx = (m.c * m.ty - m.d * m.tx) / det;
|
|
176
|
+
const ty = (m.b * m.tx - m.a * m.ty) / det;
|
|
177
|
+
m.a = a;
|
|
178
|
+
m.b = b;
|
|
179
|
+
m.c = c;
|
|
180
|
+
m.d = d;
|
|
181
|
+
m.tx = tx;
|
|
182
|
+
m.ty = ty;
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
98
185
|
/** `d`'s bounds in `target`'s space (its own for null), through the stage. */
|
|
99
186
|
export function boundsIn(d, target, stage, lines) {
|
|
100
187
|
const own = bounds(d, lines) ?? { xMin: 0, yMin: 0, xMax: 0, yMax: 0 };
|
|
101
188
|
if (!target || target === d) {
|
|
102
189
|
return own;
|
|
103
190
|
}
|
|
191
|
+
// Flat all the way, the common case, the same arithmetic as below's in scratch matrices.
|
|
192
|
+
if (flatToStage(d, stage, scratchUp)) {
|
|
193
|
+
if (target === stage) {
|
|
194
|
+
copyInto(scratchDown, IDENTITY);
|
|
195
|
+
}
|
|
196
|
+
else if (!flatToStage(target, stage, scratchDown)) {
|
|
197
|
+
return boundsInThrough(d, target, stage, own);
|
|
198
|
+
}
|
|
199
|
+
else if (!invertFlat(scratchDown)) {
|
|
200
|
+
copyInto(scratchDown, IDENTITY);
|
|
201
|
+
}
|
|
202
|
+
concatInto(scratchBoth, scratchUp, scratchDown);
|
|
203
|
+
return transformRect(own, scratchBoth);
|
|
204
|
+
}
|
|
205
|
+
return boundsInThrough(d, target, stage, own);
|
|
206
|
+
}
|
|
207
|
+
/** boundsIn where a plane is on the way: up or down through a projective matrix. */
|
|
208
|
+
function boundsInThrough(d, target, stage, own) {
|
|
104
209
|
const up = toStage(d, stage);
|
|
105
210
|
const down = target === stage ? IDENTITY : (invert(toStage(target, stage)) ?? IDENTITY);
|
|
106
211
|
if (!isProjective(up)) {
|
|
@@ -12,7 +12,7 @@ export const TRANSFORM = 1;
|
|
|
12
12
|
export const CHILDREN = 2;
|
|
13
13
|
export const CONTENT = 4;
|
|
14
14
|
/** A Bitmap's pixels changed in place: the texture uploads again, nothing is rebuilt. */
|
|
15
|
-
|
|
15
|
+
const PIXELS = 8;
|
|
16
16
|
/**
|
|
17
17
|
* A count that moves whenever something changes that a round of frame
|
|
18
18
|
* scripts (Scripting.runFrameScripts) reads to find a script to run: a
|
|
@@ -20,6 +20,13 @@ function fillsOnly(layer) {
|
|
|
20
20
|
const LINE_POINTS = [0, 0];
|
|
21
21
|
const CURVE_POINTS = [0, 0, 0, 0];
|
|
22
22
|
const CUBIC_POINTS = [0, 0, 0, 0, 0, 0];
|
|
23
|
+
// Each quarter's start and end directions, (sx, sy) and (ex, ey), for arc.
|
|
24
|
+
const QUARTERS = [
|
|
25
|
+
[1, 0, 0, 1],
|
|
26
|
+
[0, 1, -1, 0],
|
|
27
|
+
[-1, 0, 0, -1],
|
|
28
|
+
[0, -1, 1, 0],
|
|
29
|
+
];
|
|
23
30
|
/** `kind` and `points` onto the last of `paths`. */
|
|
24
31
|
function append(paths, kind, points) {
|
|
25
32
|
const path = paths[paths.length - 1];
|
|
@@ -40,8 +47,13 @@ export class Drawing {
|
|
|
40
47
|
/** Where the open fill's entries begin in its layer, which fills before it may share. */
|
|
41
48
|
fillStart = 0;
|
|
42
49
|
stroke = null;
|
|
43
|
-
/**
|
|
50
|
+
/**
|
|
51
|
+
* The stroke whose last closing line closes the open contour, or the one
|
|
52
|
+
* endFill closed, while a line drawn on may take it away.
|
|
53
|
+
*/
|
|
44
54
|
closing = null;
|
|
55
|
+
/** The closing line last taken away, for the next: a filled, lined pen makes one a segment. */
|
|
56
|
+
spareClose = null;
|
|
45
57
|
/**
|
|
46
58
|
* A point of the open contour off its start, for whether it leaves the
|
|
47
59
|
* line through them: its offset from the start, while `heading`.
|
|
@@ -205,12 +217,11 @@ export class Drawing {
|
|
|
205
217
|
if (rx === 0 && ry === 0) {
|
|
206
218
|
return;
|
|
207
219
|
}
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
][quarter];
|
|
220
|
+
const turn = QUARTERS[quarter];
|
|
221
|
+
const sx = turn[0];
|
|
222
|
+
const sy = turn[1];
|
|
223
|
+
const ex = turn[2];
|
|
224
|
+
const ey = turn[3];
|
|
214
225
|
this.curveTo(cx + (sx + ex * TAN_22_5) * rx, cy + (sy + ey * TAN_22_5) * ry, cx + (sx + ex) * COS_45 * rx, cy + (sy + ey) * COS_45 * ry);
|
|
215
226
|
this.curveTo(cx + (ex + sx * TAN_22_5) * rx, cy + (ey + sy * TAN_22_5) * ry, cx + ex * rx, cy + ey * ry);
|
|
216
227
|
}
|
|
@@ -591,7 +602,7 @@ export class Drawing {
|
|
|
591
602
|
unclose() {
|
|
592
603
|
if (this.closing) {
|
|
593
604
|
this.version++;
|
|
594
|
-
this.closing.
|
|
605
|
+
this.spareClose = this.closing.closes?.pop() ?? null;
|
|
595
606
|
this.closing = null;
|
|
596
607
|
}
|
|
597
608
|
}
|
|
@@ -603,10 +614,14 @@ export class Drawing {
|
|
|
603
614
|
return;
|
|
604
615
|
}
|
|
605
616
|
if (contour[1] !== this.x || contour[2] !== this.y) {
|
|
606
|
-
const close = { at:
|
|
617
|
+
const close = this.spareClose ?? { at: 0, x: 0, y: 0 };
|
|
618
|
+
this.spareClose = null;
|
|
619
|
+
close.at = stroke.paths.length - 1;
|
|
620
|
+
close.x = contour[1];
|
|
621
|
+
close.y = contour[2];
|
|
607
622
|
stroke.closes = stroke.closes ?? [];
|
|
608
623
|
stroke.closes.push(close);
|
|
609
|
-
this.closing =
|
|
624
|
+
this.closing = stroke;
|
|
610
625
|
this.version++;
|
|
611
626
|
}
|
|
612
627
|
}
|
|
@@ -10,35 +10,34 @@ import { INVALID_PIXELS } from "./timeline.js";
|
|
|
10
10
|
/** A display object for a character, before its first frame: a shape, or a clip. */
|
|
11
11
|
/** `hasImage` is PlaceObject3's flag where a timeline places it, which a bitmap's construction reads. */
|
|
12
12
|
export function displayFor(character, library, hasImage = false) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
return button;
|
|
13
|
+
switch (character.type) {
|
|
14
|
+
case "shape":
|
|
15
|
+
return new ShapeObject(character);
|
|
16
|
+
case "morph":
|
|
17
|
+
return ShapeObject.ofMorph(character);
|
|
18
|
+
case "bitmap": {
|
|
19
|
+
// With scripts, its Bitmap's constructor gives it its data; without, a copy of the pixels.
|
|
20
|
+
const bitmap = new BitmapObject(library.construct ? null : BitmapStore.of(character.pixels ?? INVALID_PIXELS));
|
|
21
|
+
bitmap.character = character;
|
|
22
|
+
bitmap.hasImage = hasImage;
|
|
23
|
+
return bitmap;
|
|
24
|
+
}
|
|
25
|
+
case "static":
|
|
26
|
+
return new StaticTextObject(character, library.characters);
|
|
27
|
+
case "text": {
|
|
28
|
+
const text = new TextObject(character);
|
|
29
|
+
text.fonts = library.fonts;
|
|
30
|
+
return text;
|
|
31
|
+
}
|
|
32
|
+
// Its states are made where it is constructed (Scripting.construct).
|
|
33
|
+
case "button": {
|
|
34
|
+
const button = new ButtonObject();
|
|
35
|
+
button.character = character;
|
|
36
|
+
button.library = library;
|
|
37
|
+
button.trackAsMenu = character.trackAsMenu;
|
|
38
|
+
button.scale9Grid = character.grid;
|
|
39
|
+
return button;
|
|
40
|
+
}
|
|
42
41
|
}
|
|
43
42
|
const clip = new MovieClip(character.timeline, library);
|
|
44
43
|
clip.character = character;
|
|
@@ -58,21 +58,60 @@ export function inside(points, px, py) {
|
|
|
58
58
|
}
|
|
59
59
|
return hit;
|
|
60
60
|
}
|
|
61
|
+
// The running box of extent: one for every call, as bounds are asked of every drawn shape.
|
|
62
|
+
const box = new Float64Array(4);
|
|
63
|
+
function take(x, y) {
|
|
64
|
+
box[0] = Math.min(box[0], x);
|
|
65
|
+
box[1] = Math.min(box[1], y);
|
|
66
|
+
box[2] = Math.max(box[2], x);
|
|
67
|
+
box[3] = Math.max(box[3], y);
|
|
68
|
+
}
|
|
69
|
+
/** The quadratic curve from (x, y) through (cx, cy) to (ax, ay), at `t`, into the box. */
|
|
70
|
+
function takeCurveAt(t, x, y, cx, cy, ax, ay) {
|
|
71
|
+
const u = 1 - t;
|
|
72
|
+
take(u * u * x + 2 * u * t * cx + t * t * ax, u * u * y + 2 * u * t * cy + t * t * ay);
|
|
73
|
+
}
|
|
74
|
+
/** The cubic curve from (x, y) by (c1x, c1y) and (c2x, c2y) to (ax, ay), at `t`, into the box. */
|
|
75
|
+
function takeCubicAt(t, x, y, c1x, c1y, c2x, c2y, ax, ay) {
|
|
76
|
+
if (!(t > 0 && t < 1)) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const u = 1 - t;
|
|
80
|
+
take(u * u * u * x + 3 * u * u * t * c1x + 3 * u * t * t * c2x + t * t * t * ax, u * u * u * y + 3 * u * u * t * c1y + 3 * u * t * t * c2y + t * t * t * ay);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Where the cubic's derivative on one axis, from p0 by c1 and c2 to p3, is
|
|
84
|
+
* zero within it: the roots of a t² + b t + c, each into the box.
|
|
85
|
+
*/
|
|
86
|
+
function takeCubicTurns(p0, c1, c2, p3, x, y, c1x, c1y, c2x, c2y, ax, ay) {
|
|
87
|
+
const a = -p0 + 3 * c1 - 3 * c2 + p3;
|
|
88
|
+
const b = 2 * (p0 - 2 * c1 + c2);
|
|
89
|
+
const c = c1 - p0;
|
|
90
|
+
if (a === 0) {
|
|
91
|
+
if (b !== 0) {
|
|
92
|
+
takeCubicAt(-c / b, x, y, c1x, c1y, c2x, c2y, ax, ay);
|
|
93
|
+
}
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const d = b * b - 4 * a * c;
|
|
97
|
+
if (d < 0) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const s = Math.sqrt(d);
|
|
101
|
+
takeCubicAt((-b + s) / (2 * a), x, y, c1x, c1y, c2x, c2y, ax, ay);
|
|
102
|
+
takeCubicAt((-b - s) / (2 * a), x, y, c1x, c1y, c2x, c2y, ax, ay);
|
|
103
|
+
}
|
|
61
104
|
/**
|
|
62
105
|
* The path's extent, each curve at its true extremes, as [xMin, yMin,
|
|
63
|
-
* xMax, yMax]; null for a path with no points.
|
|
106
|
+
* xMax, yMax]; null for a path with no points. It allocates only its
|
|
107
|
+
* answer: the bounds of every shape drawn, a pen's redrawn each frame
|
|
108
|
+
* among them, are asked again and again.
|
|
64
109
|
*/
|
|
65
110
|
export function extent(path) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const take = (x, y) => {
|
|
71
|
-
xMin = Math.min(xMin, x);
|
|
72
|
-
yMin = Math.min(yMin, y);
|
|
73
|
-
xMax = Math.max(xMax, x);
|
|
74
|
-
yMax = Math.max(yMax, y);
|
|
75
|
-
};
|
|
111
|
+
box[0] = Number.POSITIVE_INFINITY;
|
|
112
|
+
box[1] = Number.POSITIVE_INFINITY;
|
|
113
|
+
box[2] = Number.NEGATIVE_INFINITY;
|
|
114
|
+
box[3] = Number.NEGATIVE_INFINITY;
|
|
76
115
|
let x = 0;
|
|
77
116
|
let y = 0;
|
|
78
117
|
for (let i = 0; i < path.length;) {
|
|
@@ -86,49 +125,36 @@ export function extent(path) {
|
|
|
86
125
|
}
|
|
87
126
|
take(x, y);
|
|
88
127
|
if (command === CURVE) {
|
|
89
|
-
const
|
|
128
|
+
const cx = path[i + 1];
|
|
129
|
+
const cy = path[i + 2];
|
|
130
|
+
const ax = path[i + 3];
|
|
131
|
+
const ay = path[i + 4];
|
|
90
132
|
take(ax, ay);
|
|
91
133
|
// Where the derivative is zero on either axis, if within the curve.
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const t = denominator === 0 ? -1 : (p0 - c) / denominator;
|
|
102
|
-
if (t > 0 && t < 1) {
|
|
103
|
-
at(t);
|
|
104
|
-
}
|
|
134
|
+
const dx = x - 2 * cx + ax;
|
|
135
|
+
const tx = dx === 0 ? -1 : (x - cx) / dx;
|
|
136
|
+
if (tx > 0 && tx < 1) {
|
|
137
|
+
takeCurveAt(tx, x, y, cx, cy, ax, ay);
|
|
138
|
+
}
|
|
139
|
+
const dy = y - 2 * cy + ay;
|
|
140
|
+
const ty = dy === 0 ? -1 : (y - cy) / dy;
|
|
141
|
+
if (ty > 0 && ty < 1) {
|
|
142
|
+
takeCurveAt(ty, x, y, cx, cy, ax, ay);
|
|
105
143
|
}
|
|
106
144
|
x = ax;
|
|
107
145
|
y = ay;
|
|
108
146
|
i += 5;
|
|
109
147
|
}
|
|
110
148
|
else if (command === CUBIC) {
|
|
111
|
-
const
|
|
149
|
+
const c1x = path[i + 1];
|
|
150
|
+
const c1y = path[i + 2];
|
|
151
|
+
const c2x = path[i + 3];
|
|
152
|
+
const c2y = path[i + 4];
|
|
153
|
+
const ax = path[i + 5];
|
|
154
|
+
const ay = path[i + 6];
|
|
112
155
|
take(ax, ay);
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
take(u * u * u * x + 3 * u * u * t * c1x + 3 * u * t * t * c2x + t * t * t * ax, u * u * u * y + 3 * u * u * t * c1y + 3 * u * t * t * c2y + t * t * t * ay);
|
|
116
|
-
};
|
|
117
|
-
for (const [p0, c1, c2, p3] of [
|
|
118
|
-
[x, c1x, c2x, ax],
|
|
119
|
-
[y, c1y, c2y, ay],
|
|
120
|
-
]) {
|
|
121
|
-
// The derivative's roots: a t² + b t + c = 0.
|
|
122
|
-
const a = -p0 + 3 * c1 - 3 * c2 + p3;
|
|
123
|
-
const b = 2 * (p0 - 2 * c1 + c2);
|
|
124
|
-
const c = c1 - p0;
|
|
125
|
-
const roots = a === 0 ? (b === 0 ? [] : [-c / b]) : quadraticRoots(a, b, c);
|
|
126
|
-
for (const t of roots) {
|
|
127
|
-
if (t > 0 && t < 1) {
|
|
128
|
-
at(t);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
156
|
+
takeCubicTurns(x, c1x, c2x, ax, x, y, c1x, c1y, c2x, c2y, ax, ay);
|
|
157
|
+
takeCubicTurns(y, c1y, c2y, ay, x, y, c1x, c1y, c2x, c2y, ax, ay);
|
|
132
158
|
x = ax;
|
|
133
159
|
y = ay;
|
|
134
160
|
i += 7;
|
|
@@ -140,15 +166,7 @@ export function extent(path) {
|
|
|
140
166
|
i += 3;
|
|
141
167
|
}
|
|
142
168
|
}
|
|
143
|
-
return
|
|
144
|
-
}
|
|
145
|
-
function quadraticRoots(a, b, c) {
|
|
146
|
-
const d = b * b - 4 * a * c;
|
|
147
|
-
if (d < 0) {
|
|
148
|
-
return [];
|
|
149
|
-
}
|
|
150
|
-
const s = Math.sqrt(d);
|
|
151
|
-
return [(-b + s) / (2 * a), (-b - s) / (2 * a)];
|
|
169
|
+
return box[0] <= box[2] ? [box[0], box[1], box[2], box[3]] : null;
|
|
152
170
|
}
|
|
153
171
|
/** Layers as they draw mirrored, as of a version: the renderer and the hit tests ask on each redraw. */
|
|
154
172
|
const mirroredLayers = new WeakMap();
|
|
@@ -30,6 +30,15 @@ export class StaticTextObject extends DisplayObject {
|
|
|
30
30
|
return this.laidGlyphs;
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
+
/** The fields whose fit a set size left pending, for the frame to settle before it is drawn. */
|
|
34
|
+
const pendingFits = new Set();
|
|
35
|
+
/** Every pending fit applied, as Flash applies them before it draws. */
|
|
36
|
+
export function settleFits() {
|
|
37
|
+
for (const field of pendingFits) {
|
|
38
|
+
field.settle();
|
|
39
|
+
}
|
|
40
|
+
pendingFits.clear();
|
|
41
|
+
}
|
|
33
42
|
/**
|
|
34
43
|
* A TextField: placed by DefineEditText, or made by a script. Its text and
|
|
35
44
|
* formats are a TextModel; a timeline's starts with its tag's text, read
|
|
@@ -55,6 +64,12 @@ export class TextObject extends DisplayObject {
|
|
|
55
64
|
type = "dynamic";
|
|
56
65
|
embedFonts = false;
|
|
57
66
|
autoSize = "none";
|
|
67
|
+
/**
|
|
68
|
+
* A script set the size of a field that fits itself: as in Flash, the fit
|
|
69
|
+
* waits for its size to be asked, its transform to change or the frame to
|
|
70
|
+
* be drawn, and a wordWrap set meanwhile wraps at the size set (adl).
|
|
71
|
+
*/
|
|
72
|
+
fitPending = false;
|
|
58
73
|
selectable = true;
|
|
59
74
|
maxChars = 0;
|
|
60
75
|
displayAsPassword = false;
|
|
@@ -165,7 +180,7 @@ export class TextObject extends DisplayObject {
|
|
|
165
180
|
* centre or right edge where it was.
|
|
166
181
|
*/
|
|
167
182
|
fit() {
|
|
168
|
-
if (this.autoSize === "none") {
|
|
183
|
+
if (this.autoSize === "none" || this.fitPending) {
|
|
169
184
|
return;
|
|
170
185
|
}
|
|
171
186
|
const layout = this.layout;
|
|
@@ -186,6 +201,24 @@ export class TextObject extends DisplayObject {
|
|
|
186
201
|
this.height = height;
|
|
187
202
|
this.invalidate(CONTENT);
|
|
188
203
|
}
|
|
204
|
+
/** A script set its size: under autoSize, the fit waits (fitPending). */
|
|
205
|
+
sizeSet() {
|
|
206
|
+
if (this.autoSize !== "none") {
|
|
207
|
+
this.fitPending = true;
|
|
208
|
+
pendingFits.add(this);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/** The fit a set size left pending, applied: its size asked, its transform changed, the frame drawn. */
|
|
212
|
+
settle() {
|
|
213
|
+
if (this.fitPending) {
|
|
214
|
+
this.fitPending = false;
|
|
215
|
+
this.fit();
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
touch() {
|
|
219
|
+
super.touch();
|
|
220
|
+
this.settle();
|
|
221
|
+
}
|
|
189
222
|
/** The text, \r between its lines. */
|
|
190
223
|
get text() {
|
|
191
224
|
return this.model.text;
|
|
@@ -10,6 +10,7 @@ import { decodeImages, decodeInBrowser } from "./bitmap/images.js";
|
|
|
10
10
|
import { drawKernelFrame, drawKernelLetGo, drawKernelUsed } from "./bitmap/kernel.js";
|
|
11
11
|
import { BUTTON, CLIP, Container, MovieClip, OTHER, unloads, walkList, } from "./display/display.js";
|
|
12
12
|
import { setStageSize } from "./display/perspective.js";
|
|
13
|
+
import { settleFits } from "./display/textobjects.js";
|
|
13
14
|
import { readLibrary } from "./display/timeline.js";
|
|
14
15
|
import { customContextMenu } from "./input/context-menu.js";
|
|
15
16
|
import { KeyboardInput } from "./input/keyboard.js";
|
|
@@ -607,9 +608,7 @@ export class Player {
|
|
|
607
608
|
}
|
|
608
609
|
};
|
|
609
610
|
collect(this.stage);
|
|
610
|
-
|
|
611
|
-
collect(orphan);
|
|
612
|
-
}
|
|
611
|
+
this.scripting?.lifecycle.eachOrphanRoot(collect);
|
|
613
612
|
// Let go of once advanced, so that the kept list holds none past the tick.
|
|
614
613
|
try {
|
|
615
614
|
for (let i = 0; i < count; i++) {
|
|
@@ -624,5 +623,7 @@ export class Player {
|
|
|
624
623
|
this.scripting.frame(this.stage, true, render);
|
|
625
624
|
this.frameRate = this.scripting.frameRate;
|
|
626
625
|
}
|
|
626
|
+
// The fits a set size left pending happen before the frame is drawn, as in Flash.
|
|
627
|
+
settleFits();
|
|
627
628
|
}
|
|
628
629
|
}
|
|
@@ -13,7 +13,7 @@ import { nativeWindowOf } from "../display/NativeWindow.js";
|
|
|
13
13
|
import { addListener, removeListener } from "../events/EventDispatcher.js";
|
|
14
14
|
import { fileAt } from "../filesystem/File.js";
|
|
15
15
|
/** NativeApplication.runtimeVersion, and its patch level: the AIR these natives follow. */
|
|
16
|
-
|
|
16
|
+
const AIR_RUNTIME_VERSION = "51.3.1.2";
|
|
17
17
|
const AIR_PATCH_LEVEL = 2;
|
|
18
18
|
const INVOKE = "invoke";
|
|
19
19
|
export function nativeApplicationNatives(s) {
|
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
// ArgumentError 2015 for a size it refuses and for a store disposed.
|
|
4
4
|
import { avm2 } from "../../../../runtime/index.js";
|
|
5
5
|
import { BitmapStore, pixelRect, spanRect } from "../../../bitmap/bitmap.js";
|
|
6
|
+
import { drawBitmap } from "../../../bitmap/composite.js";
|
|
6
7
|
import { drawDisplayObject } from "../../../bitmap/draw.js";
|
|
7
8
|
import { applyFilter, filterRefusal, filtersDrawn, GLOWS, generatedRect, } from "../../../bitmap/filters.js";
|
|
8
|
-
import { alphaAt, colorBounds, colorTransform, comparePixels, copyChannel,
|
|
9
|
+
import { alphaAt, colorBounds, colorTransform, comparePixels, copyChannel, floodFill, histogram, isThresholdOperation, merge, noise, paletteMap, perlinNoise, pixelDissolve, scroll, threshold, } from "../../../bitmap/ops.js";
|
|
9
10
|
import { shaderFilter } from "../../../bitmap/pixel-bender.js";
|
|
10
11
|
import { encodePng } from "../../../bitmap/png.js";
|
|
11
12
|
import { INVALID_PIXELS } from "../../../display/timeline.js";
|
|
@@ -74,7 +75,7 @@ function sourceOf(s, v) {
|
|
|
74
75
|
}
|
|
75
76
|
/**
|
|
76
77
|
* draw: a BitmapData, or a Bitmap as its data, its own transform ignored,
|
|
77
|
-
* composited on the CPU (bitmap/
|
|
78
|
+
* composited on the CPU (bitmap/composite.ts); any other display
|
|
78
79
|
* object rendered by the Scripting's drawer at `samples` a side, over its
|
|
79
80
|
* own bounds alone, then composited the same way. A null source is
|
|
80
81
|
* ArgumentError 2005, as Flash words it.
|
|
@@ -340,7 +340,7 @@ export function displayObjectNatives(s) {
|
|
|
340
340
|
if (d instanceof TextObject) {
|
|
341
341
|
d.width = value / (Math.abs(d.scaleX) || 1);
|
|
342
342
|
d.invalidate(CONTENT);
|
|
343
|
-
d.
|
|
343
|
+
d.sizeSet();
|
|
344
344
|
return;
|
|
345
345
|
}
|
|
346
346
|
const r = bounds(d, true);
|
|
@@ -375,7 +375,7 @@ export function displayObjectNatives(s) {
|
|
|
375
375
|
if (d instanceof TextObject) {
|
|
376
376
|
d.height = value / (Math.abs(d.scaleY) || 1);
|
|
377
377
|
d.invalidate(CONTENT);
|
|
378
|
-
d.
|
|
378
|
+
d.sizeSet();
|
|
379
379
|
return;
|
|
380
380
|
}
|
|
381
381
|
const r = bounds(d, true);
|
|
@@ -24,17 +24,18 @@ export function simpleButtonNatives(s) {
|
|
|
24
24
|
if (d?.parent && d.parent !== b && !d.encloses(b)) {
|
|
25
25
|
d.parent.removeChild(d);
|
|
26
26
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
27
|
+
switch (state) {
|
|
28
|
+
case "up":
|
|
29
|
+
b.upState = d;
|
|
30
|
+
break;
|
|
31
|
+
case "over":
|
|
32
|
+
b.overState = d;
|
|
33
|
+
break;
|
|
34
|
+
case "down":
|
|
35
|
+
b.downState = d;
|
|
36
|
+
break;
|
|
37
|
+
default:
|
|
38
|
+
b.hitTestState = d;
|
|
38
39
|
}
|
|
39
40
|
b.show();
|
|
40
41
|
// adl reports #2150 as an error nothing caught, from the setter of the state the button
|
|
@@ -41,12 +41,9 @@ export function stageNatives(s) {
|
|
|
41
41
|
s.invalidated = true;
|
|
42
42
|
}
|
|
43
43
|
get scaleMode() {
|
|
44
|
-
return s.
|
|
44
|
+
return s.stageScaleMode;
|
|
45
45
|
}
|
|
46
46
|
set scaleMode(v) {
|
|
47
|
-
if (!s.liveStageLayout) {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
47
|
if (v == null) {
|
|
51
48
|
throw s.rt.error("TypeError", 2007, "scaleMode");
|
|
52
49
|
}
|
|
@@ -67,12 +64,9 @@ export function stageNatives(s) {
|
|
|
67
64
|
}
|
|
68
65
|
}
|
|
69
66
|
get align() {
|
|
70
|
-
return s.
|
|
67
|
+
return s.stageAlign;
|
|
71
68
|
}
|
|
72
69
|
set align(v) {
|
|
73
|
-
if (!s.liveStageLayout) {
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
70
|
if (v == null) {
|
|
77
71
|
throw s.rt.error("TypeError", 2007, "align");
|
|
78
72
|
}
|
|
@@ -29,7 +29,7 @@ export function kernelOfShader(shader) {
|
|
|
29
29
|
* number, or ArgumentError 2004, as many as its type holds, 0 past the
|
|
30
30
|
* Array's end.
|
|
31
31
|
*/
|
|
32
|
-
|
|
32
|
+
function parameterValues(s, data, p) {
|
|
33
33
|
const classes = shaderClasses(s);
|
|
34
34
|
const size = PBJ_TYPE_SIZES[p.type] ?? 0;
|
|
35
35
|
const float = pbjFloatType(p.type);
|
|
@@ -151,6 +151,6 @@ export class NativePaths {
|
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
153
|
/** A path segment in a URL: UTF-8, percent-encoded as adl writes them ("#?%" and spaces among them). */
|
|
154
|
-
|
|
154
|
+
function encodeSegment(segment) {
|
|
155
155
|
return encodeURIComponent(segment);
|
|
156
156
|
}
|