@swf2es/player-hosts 0.1.7 → 0.1.10

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.
@@ -65,9 +65,10 @@ export class TextObject extends DisplayObject {
65
65
  embedFonts = false;
66
66
  autoSize = "none";
67
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).
68
+ * A script set the size or the autoSize of a field that fits itself: as
69
+ * in Flash, the fit waits for its size to be asked, its transform to
70
+ * change or the frame to be drawn, and a wordWrap set meanwhile wraps at
71
+ * the size the field has (adl).
71
72
  */
72
73
  fitPending = false;
73
74
  selectable = true;
@@ -201,24 +202,24 @@ export class TextObject extends DisplayObject {
201
202
  this.height = height;
202
203
  this.invalidate(CONTENT);
203
204
  }
204
- /** A script set its size: under autoSize, the fit waits (fitPending). */
205
- sizeSet() {
206
- if (this.autoSize !== "none") {
205
+ /** A script set its size or its autoSize: under autoSize, the fit waits (fitPending). */
206
+ deferFit() {
207
+ if (this.autoSize !== "none" && !this.fitPending) {
207
208
  this.fitPending = true;
208
209
  pendingFits.add(this);
209
210
  }
210
211
  }
211
- /** The fit a set size left pending, applied: its size asked, its transform changed, the frame drawn. */
212
+ /**
213
+ * The fit left pending, applied: as its position, size or bounds are
214
+ * asked, its transform is set, or the frame is drawn; not as its scale,
215
+ * its rotation or its text metrics are asked, or its alpha set (adl).
216
+ */
212
217
  settle() {
213
218
  if (this.fitPending) {
214
219
  this.fitPending = false;
215
220
  this.fit();
216
221
  }
217
222
  }
218
- touch() {
219
- super.touch();
220
- this.settle();
221
- }
222
223
  /** The text, \r between its lines. */
223
224
  get text() {
224
225
  return this.model.text;
@@ -144,6 +144,10 @@ function spriteOnly(traits) {
144
144
  }
145
145
  /** Move a display object, by a copy of its matrix, and have it drawn again. */
146
146
  function transform(d, change) {
147
+ // A field's pending fit first, so that what is set is where it stays.
148
+ if (d instanceof TextObject) {
149
+ d.settle();
150
+ }
147
151
  const m = { ...d.matrix };
148
152
  change(m);
149
153
  d.matrix = m;
@@ -191,6 +195,10 @@ export function displayObjectNatives(s) {
191
195
  }
192
196
  }
193
197
  get x() {
198
+ // A field's pending fit moves a centred or right-aligned one (adl).
199
+ if (this.$display instanceof TextObject) {
200
+ this.$display.settle();
201
+ }
194
202
  return withOffset(this.$display.matrix.tx, fieldOffset(this.$display)[0]);
195
203
  }
196
204
  // A NaN position is 0, as Flash has it (the corpus's `displayobject_invalid_floats`), and
@@ -207,6 +215,9 @@ export function displayObjectNatives(s) {
207
215
  });
208
216
  }
209
217
  get y() {
218
+ if (this.$display instanceof TextObject) {
219
+ this.$display.settle();
220
+ }
210
221
  return withOffset(this.$display.matrix.ty, fieldOffset(this.$display)[1]);
211
222
  }
212
223
  set y(v) {
@@ -340,7 +351,7 @@ export function displayObjectNatives(s) {
340
351
  if (d instanceof TextObject) {
341
352
  d.width = value / (Math.abs(d.scaleX) || 1);
342
353
  d.invalidate(CONTENT);
343
- d.sizeSet();
354
+ d.deferFit();
344
355
  return;
345
356
  }
346
357
  const r = bounds(d, true);
@@ -375,7 +386,7 @@ export function displayObjectNatives(s) {
375
386
  if (d instanceof TextObject) {
376
387
  d.height = value / (Math.abs(d.scaleY) || 1);
377
388
  d.invalidate(CONTENT);
378
- d.sizeSet();
389
+ d.deferFit();
379
390
  return;
380
391
  }
381
392
  const r = bounds(d, true);
@@ -9,8 +9,11 @@ function style(font) {
9
9
  }
10
10
  return font.italic ? "italic" : "regular";
11
11
  }
12
- /** The fonts enumerateFonts lists: the running code's SWF's, with layout or no glyphs, and those registered. */
13
- export function embeddedFonts(s) {
12
+ /**
13
+ * The fonts enumerateFonts lists: the running code's SWF's, with layout or
14
+ * no glyphs, and, unless `registered` is false, those registered.
15
+ */
16
+ export function embeddedFonts(s, registered = true) {
14
17
  const fonts = [];
15
18
  const library = s.code.codeLibrary();
16
19
  if (library) {
@@ -21,7 +24,9 @@ export function embeddedFonts(s) {
21
24
  }
22
25
  }
23
26
  }
24
- fonts.push(...s.symbols.registeredFonts.values());
27
+ if (registered) {
28
+ fonts.push(...s.symbols.registeredFonts.values());
29
+ }
25
30
  return fonts;
26
31
  }
27
32
  export function fontNatives(s) {
@@ -57,15 +62,28 @@ export function fontNatives(s) {
57
62
  }
58
63
  return true;
59
64
  }
65
+ /**
66
+ * The fonts as Font objects, by name: a registered font an instance of
67
+ * the class it was registered by, as Flash makes it, so that its class
68
+ * name finds that class again; the SWF's own a plain Font, as Flash
69
+ * makes those though a class is bound to them.
70
+ */
60
71
  static enumerateFonts(_enumerateDeviceFonts) {
61
- const cls = s.rt.classNamed("flash.text::Font");
62
- const fonts = embeddedFonts(s);
72
+ const plain = s.rt.classNamed("flash.text::Font");
73
+ const fonts = [];
74
+ for (const font of embeddedFonts(s, false)) {
75
+ fonts.push({ font, cls: plain });
76
+ }
77
+ for (const [cls, font] of s.symbols.registeredFonts) {
78
+ fonts.push({ font, cls });
79
+ }
80
+ // Stable: a SWF's own font before one registered of the same name, as adl lists them.
63
81
  fonts.sort((a, b) => {
64
- const first = a.name.toLowerCase();
65
- const second = b.name.toLowerCase();
82
+ const first = a.font.name.toLowerCase();
83
+ const second = b.font.name.toLowerCase();
66
84
  return first < second ? -1 : first > second ? 1 : 0;
67
85
  });
68
- return s.rt.array(fonts.map((font) => {
86
+ return s.rt.array(fonts.map(({ font, cls }) => {
69
87
  const object = s.rt.construct(cls);
70
88
  object.$font = font;
71
89
  return object;
@@ -342,7 +342,8 @@ export function textFieldNatives(s) {
342
342
  }
343
343
  set autoSize(v) {
344
344
  this.$display.autoSize = choice(v, ["none", "left", "right", "center"], "autoSize");
345
- this.$display.fit();
345
+ // Its fit waits for its size to be asked, or the frame, as one a set width leaves (adl).
346
+ this.$display.deferFit();
346
347
  }
347
348
  get antiAliasType() {
348
349
  return this.$display.antiAliasType;
@@ -39,14 +39,18 @@ export class XMLTag {
39
39
  this.attributes = [];
40
40
  }
41
41
  }
42
- /** The entities XMLParser knows: the XML ones, and nbsp. */
42
+ /**
43
+ * The entities XMLParser knows: the XML ones, and nbsp, which avmplus
44
+ * makes U+FFA0 rather than U+00A0, as avmshell and Flash Player give it: its
45
+ * table's 0xA0 is a signed char, widened to -96.
46
+ */
43
47
  const ENTITIES = {
44
48
  amp: "&",
45
49
  quot: '"',
46
50
  apos: "'",
47
51
  lt: "<",
48
52
  gt: ">",
49
- nbsp: "\u00a0",
53
+ nbsp: "\uffa0",
50
54
  };
51
55
  export class XMLParser {
52
56
  pos = 0;
@@ -244,19 +248,20 @@ export class XMLParser {
244
248
  return OK;
245
249
  }
246
250
  /**
247
- * As XMLParser::unescape: [start, last) with its entity and character
251
+ * As XMLParser::unescape: [from, to) with its entity and character
248
252
  * references decoded: &#dd; and &#xhh; up to 0xFFFF, and ENTITIES. An &
249
253
  * without a ; ends the decoding; one that is not a known reference is
250
- * kept as it is.
254
+ * kept as it is. Searched within the value alone: a search of the text
255
+ * past it, for an & or a ; it would not use, made a document of many
256
+ * values without them take a scan of the rest of it for each.
251
257
  */
252
- unescape(start, last) {
253
- const str = this.text;
254
- if (start === last) {
255
- return "";
256
- }
257
- let bgn = str.indexOf("&", start);
258
- if (bgn < 0 || bgn >= last) {
259
- return str.slice(start, last);
258
+ unescape(from, to) {
259
+ const str = this.text.slice(from, to);
260
+ const start = 0;
261
+ const last = str.length;
262
+ let bgn = str.indexOf("&");
263
+ if (bgn < 0) {
264
+ return str;
260
265
  }
261
266
  let dest = "";
262
267
  let end = start;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swf2es/player-hosts",
3
- "version": "0.1.7",
3
+ "version": "0.1.10",
4
4
  "description": "Optional Node and WebSocket transports, worker threads, an IndexedDB module cache and precompiled modules for the swf2es player",
5
5
  "keywords": [
6
6
  "swf",
@@ -60,6 +60,6 @@
60
60
  "LICENSE.third-party"
61
61
  ],
62
62
  "dependencies": {
63
- "@swf2es/player": "0.1.7"
63
+ "@swf2es/player": "0.1.10"
64
64
  }
65
65
  }