@swf2es/player 0.1.0 → 0.1.1

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.
Files changed (277) hide show
  1. package/package.json +7 -7
  2. package/dist/audio.d.ts +0 -22
  3. package/dist/audio.d.ts.map +0 -1
  4. package/dist/audio.js +0 -106
  5. package/dist/audio.js.map +0 -1
  6. package/dist/bitmap-filters.d.ts +0 -29
  7. package/dist/bitmap-filters.d.ts.map +0 -1
  8. package/dist/bitmap-filters.js +0 -906
  9. package/dist/bitmap-filters.js.map +0 -1
  10. package/dist/bitmap-ops.d.ts +0 -113
  11. package/dist/bitmap-ops.d.ts.map +0 -1
  12. package/dist/bitmap-ops.js +0 -725
  13. package/dist/bitmap-ops.js.map +0 -1
  14. package/dist/bitmap.d.ts +0 -98
  15. package/dist/bitmap.d.ts.map +0 -1
  16. package/dist/bitmap.js +0 -314
  17. package/dist/bitmap.js.map +0 -1
  18. package/dist/bounds.d.ts +0 -26
  19. package/dist/bounds.d.ts.map +0 -1
  20. package/dist/bounds.js +0 -300
  21. package/dist/bounds.js.map +0 -1
  22. package/dist/color.d.ts +0 -7
  23. package/dist/color.d.ts.map +0 -1
  24. package/dist/color.js +0 -42
  25. package/dist/color.js.map +0 -1
  26. package/dist/display.d.ts +0 -425
  27. package/dist/display.d.ts.map +0 -1
  28. package/dist/display.js +0 -1274
  29. package/dist/display.js.map +0 -1
  30. package/dist/drawing.d.ts +0 -52
  31. package/dist/drawing.d.ts.map +0 -1
  32. package/dist/drawing.js +0 -204
  33. package/dist/drawing.js.map +0 -1
  34. package/dist/filters.d.ts +0 -54
  35. package/dist/filters.d.ts.map +0 -1
  36. package/dist/filters.js +0 -155
  37. package/dist/filters.js.map +0 -1
  38. package/dist/fonts.d.ts +0 -23
  39. package/dist/fonts.d.ts.map +0 -1
  40. package/dist/fonts.js +0 -91
  41. package/dist/fonts.js.map +0 -1
  42. package/dist/geometry.d.ts +0 -21
  43. package/dist/geometry.d.ts.map +0 -1
  44. package/dist/geometry.js +0 -76
  45. package/dist/geometry.js.map +0 -1
  46. package/dist/gradients.d.ts +0 -29
  47. package/dist/gradients.d.ts.map +0 -1
  48. package/dist/gradients.js +0 -116
  49. package/dist/gradients.js.map +0 -1
  50. package/dist/images.d.ts +0 -22
  51. package/dist/images.d.ts.map +0 -1
  52. package/dist/images.js +0 -147
  53. package/dist/images.js.map +0 -1
  54. package/dist/input.d.ts +0 -79
  55. package/dist/input.d.ts.map +0 -1
  56. package/dist/input.js +0 -366
  57. package/dist/input.js.map +0 -1
  58. package/dist/keyboard.d.ts +0 -97
  59. package/dist/keyboard.d.ts.map +0 -1
  60. package/dist/keyboard.js +0 -583
  61. package/dist/keyboard.js.map +0 -1
  62. package/dist/morph.d.ts +0 -17
  63. package/dist/morph.d.ts.map +0 -1
  64. package/dist/morph.js +0 -218
  65. package/dist/morph.js.map +0 -1
  66. package/dist/pixi-blend.d.ts +0 -7
  67. package/dist/pixi-blend.d.ts.map +0 -1
  68. package/dist/pixi-blend.js +0 -253
  69. package/dist/pixi-blend.js.map +0 -1
  70. package/dist/pixi-color.d.ts +0 -54
  71. package/dist/pixi-color.d.ts.map +0 -1
  72. package/dist/pixi-color.js +0 -336
  73. package/dist/pixi-color.js.map +0 -1
  74. package/dist/pixi-filters.d.ts +0 -40
  75. package/dist/pixi-filters.d.ts.map +0 -1
  76. package/dist/pixi-filters.js +0 -953
  77. package/dist/pixi-filters.js.map +0 -1
  78. package/dist/pixi-resolve.d.ts +0 -4
  79. package/dist/pixi-resolve.d.ts.map +0 -1
  80. package/dist/pixi-resolve.js +0 -76
  81. package/dist/pixi-resolve.js.map +0 -1
  82. package/dist/pixi.d.ts +0 -219
  83. package/dist/pixi.d.ts.map +0 -1
  84. package/dist/pixi.js +0 -2169
  85. package/dist/pixi.js.map +0 -1
  86. package/dist/playerglobal/flash/filters/filters.d.ts +0 -26
  87. package/dist/playerglobal/flash/filters/filters.d.ts.map +0 -1
  88. package/dist/playerglobal/flash/filters/filters.js +0 -287
  89. package/dist/playerglobal/flash/filters/filters.js.map +0 -1
  90. package/dist/playerglobal/flash/system/FSCommand.d.ts +0 -4
  91. package/dist/playerglobal/flash/system/FSCommand.d.ts.map +0 -1
  92. package/dist/playerglobal/flash/system/FSCommand.js +0 -18
  93. package/dist/playerglobal/flash/system/FSCommand.js.map +0 -1
  94. package/dist/playerglobal/natives.d.ts +0 -10
  95. package/dist/playerglobal/natives.d.ts.map +0 -1
  96. package/dist/playerglobal/natives.js +0 -53
  97. package/dist/playerglobal/natives.js.map +0 -1
  98. package/dist/png.d.ts +0 -4
  99. package/dist/png.d.ts.map +0 -1
  100. package/dist/png.js +0 -140
  101. package/dist/png.js.map +0 -1
  102. package/dist/render/art.d.ts +0 -148
  103. package/dist/render/art.d.ts.map +0 -1
  104. package/dist/render/art.js +0 -575
  105. package/dist/render/art.js.map +0 -1
  106. package/dist/render/batchers.d.ts +0 -23
  107. package/dist/render/batchers.d.ts.map +0 -1
  108. package/dist/render/batchers.js +0 -52
  109. package/dist/render/batchers.js.map +0 -1
  110. package/dist/render/bitmaps.d.ts +0 -117
  111. package/dist/render/bitmaps.d.ts.map +0 -1
  112. package/dist/render/bitmaps.js +0 -422
  113. package/dist/render/bitmaps.js.map +0 -1
  114. package/dist/render/blend.d.ts +0 -37
  115. package/dist/render/blend.d.ts.map +0 -1
  116. package/dist/render/blend.js +0 -195
  117. package/dist/render/blend.js.map +0 -1
  118. package/dist/render/color.d.ts +0 -111
  119. package/dist/render/color.d.ts.map +0 -1
  120. package/dist/render/color.js +0 -533
  121. package/dist/render/color.js.map +0 -1
  122. package/dist/render/compositing.d.ts +0 -77
  123. package/dist/render/compositing.d.ts.map +0 -1
  124. package/dist/render/compositing.js +0 -188
  125. package/dist/render/compositing.js.map +0 -1
  126. package/dist/render/filters.d.ts +0 -98
  127. package/dist/render/filters.d.ts.map +0 -1
  128. package/dist/render/filters.js +0 -1326
  129. package/dist/render/filters.js.map +0 -1
  130. package/dist/render/hooks.d.ts +0 -4
  131. package/dist/render/hooks.d.ts.map +0 -1
  132. package/dist/render/hooks.js +0 -48
  133. package/dist/render/hooks.js.map +0 -1
  134. package/dist/render/node.d.ts +0 -139
  135. package/dist/render/node.d.ts.map +0 -1
  136. package/dist/render/node.js +0 -59
  137. package/dist/render/node.js.map +0 -1
  138. package/dist/render/patches.d.ts +0 -54
  139. package/dist/render/patches.d.ts.map +0 -1
  140. package/dist/render/patches.js +0 -154
  141. package/dist/render/patches.js.map +0 -1
  142. package/dist/render/planes.d.ts +0 -74
  143. package/dist/render/planes.d.ts.map +0 -1
  144. package/dist/render/planes.js +0 -267
  145. package/dist/render/planes.js.map +0 -1
  146. package/dist/render/pointer.d.ts +0 -5
  147. package/dist/render/pointer.d.ts.map +0 -1
  148. package/dist/render/pointer.js +0 -279
  149. package/dist/render/pointer.js.map +0 -1
  150. package/dist/render/pools.d.ts +0 -122
  151. package/dist/render/pools.d.ts.map +0 -1
  152. package/dist/render/pools.js +0 -238
  153. package/dist/render/pools.js.map +0 -1
  154. package/dist/render/resolve.d.ts +0 -4
  155. package/dist/render/resolve.d.ts.map +0 -1
  156. package/dist/render/resolve.js +0 -76
  157. package/dist/render/resolve.js.map +0 -1
  158. package/dist/render/saffron.d.ts +0 -135
  159. package/dist/render/saffron.d.ts.map +0 -1
  160. package/dist/render/saffron.js +0 -725
  161. package/dist/render/saffron.js.map +0 -1
  162. package/dist/render/settle.d.ts +0 -60
  163. package/dist/render/settle.d.ts.map +0 -1
  164. package/dist/render/settle.js +0 -128
  165. package/dist/render/settle.js.map +0 -1
  166. package/dist/render/shared.d.ts +0 -25
  167. package/dist/render/shared.d.ts.map +0 -1
  168. package/dist/render/shared.js +0 -33
  169. package/dist/render/shared.js.map +0 -1
  170. package/dist/render/snapshot.d.ts +0 -21
  171. package/dist/render/snapshot.d.ts.map +0 -1
  172. package/dist/render/snapshot.js +0 -91
  173. package/dist/render/snapshot.js.map +0 -1
  174. package/dist/render/spares.d.ts +0 -56
  175. package/dist/render/spares.d.ts.map +0 -1
  176. package/dist/render/spares.js +0 -160
  177. package/dist/render/spares.js.map +0 -1
  178. package/dist/render/strokes.d.ts +0 -107
  179. package/dist/render/strokes.d.ts.map +0 -1
  180. package/dist/render/strokes.js +0 -448
  181. package/dist/render/strokes.js.map +0 -1
  182. package/dist/render/table.d.ts +0 -213
  183. package/dist/render/table.d.ts.map +0 -1
  184. package/dist/render/table.js +0 -795
  185. package/dist/render/table.js.map +0 -1
  186. package/dist/render/tessellate.d.ts +0 -89
  187. package/dist/render/tessellate.d.ts.map +0 -1
  188. package/dist/render/tessellate.js +0 -386
  189. package/dist/render/tessellate.js.map +0 -1
  190. package/dist/render/text.d.ts +0 -40
  191. package/dist/render/text.d.ts.map +0 -1
  192. package/dist/render/text.js +0 -309
  193. package/dist/render/text.js.map +0 -1
  194. package/dist/render/three.d.ts +0 -83
  195. package/dist/render/three.d.ts.map +0 -1
  196. package/dist/render/three.js +0 -511
  197. package/dist/render/three.js.map +0 -1
  198. package/dist/render/triangles.d.ts +0 -28
  199. package/dist/render/triangles.d.ts.map +0 -1
  200. package/dist/render/triangles.js +0 -189
  201. package/dist/render/triangles.js.map +0 -1
  202. package/dist/render/view.d.ts +0 -238
  203. package/dist/render/view.d.ts.map +0 -1
  204. package/dist/render/view.js +0 -1173
  205. package/dist/render/view.js.map +0 -1
  206. package/dist/render/worker/bitmaps.d.ts +0 -43
  207. package/dist/render/worker/bitmaps.d.ts.map +0 -1
  208. package/dist/render/worker/bitmaps.js +0 -151
  209. package/dist/render/worker/bitmaps.js.map +0 -1
  210. package/dist/render/worker/drawing.d.ts +0 -21
  211. package/dist/render/worker/drawing.d.ts.map +0 -1
  212. package/dist/render/worker/drawing.js +0 -356
  213. package/dist/render/worker/drawing.js.map +0 -1
  214. package/dist/render/worker/filters.d.ts +0 -7
  215. package/dist/render/worker/filters.d.ts.map +0 -1
  216. package/dist/render/worker/filters.js +0 -125
  217. package/dist/render/worker/filters.js.map +0 -1
  218. package/dist/render/worker/frames.d.ts +0 -32
  219. package/dist/render/worker/frames.d.ts.map +0 -1
  220. package/dist/render/worker/frames.js +0 -124
  221. package/dist/render/worker/frames.js.map +0 -1
  222. package/dist/render/worker/host.d.ts +0 -60
  223. package/dist/render/worker/host.d.ts.map +0 -1
  224. package/dist/render/worker/host.js +0 -297
  225. package/dist/render/worker/host.js.map +0 -1
  226. package/dist/render/worker/libraries.d.ts +0 -36
  227. package/dist/render/worker/libraries.d.ts.map +0 -1
  228. package/dist/render/worker/libraries.js +0 -153
  229. package/dist/render/worker/libraries.js.map +0 -1
  230. package/dist/render/worker/presentation.d.ts +0 -18
  231. package/dist/render/worker/presentation.d.ts.map +0 -1
  232. package/dist/render/worker/presentation.js +0 -47
  233. package/dist/render/worker/presentation.js.map +0 -1
  234. package/dist/render/worker/renderer.d.ts +0 -4
  235. package/dist/render/worker/renderer.d.ts.map +0 -1
  236. package/dist/render/worker/renderer.js +0 -21
  237. package/dist/render/worker/renderer.js.map +0 -1
  238. package/dist/render/worker/scene.d.ts +0 -32
  239. package/dist/render/worker/scene.d.ts.map +0 -1
  240. package/dist/render/worker/scene.js +0 -611
  241. package/dist/render/worker/scene.js.map +0 -1
  242. package/dist/render/worker/text.d.ts +0 -47
  243. package/dist/render/worker/text.d.ts.map +0 -1
  244. package/dist/render/worker/text.js +0 -261
  245. package/dist/render/worker/text.js.map +0 -1
  246. package/dist/render/worker/thread.d.ts +0 -23
  247. package/dist/render/worker/thread.d.ts.map +0 -1
  248. package/dist/render/worker/thread.js +0 -107
  249. package/dist/render/worker/thread.js.map +0 -1
  250. package/dist/render/worker/values.d.ts +0 -18
  251. package/dist/render/worker/values.d.ts.map +0 -1
  252. package/dist/render/worker/values.js +0 -64
  253. package/dist/render/worker/values.js.map +0 -1
  254. package/dist/sha256.d.ts +0 -5
  255. package/dist/sha256.d.ts.map +0 -1
  256. package/dist/sha256.js +0 -96
  257. package/dist/sha256.js.map +0 -1
  258. package/dist/shapes.d.ts +0 -71
  259. package/dist/shapes.d.ts.map +0 -1
  260. package/dist/shapes.js +0 -340
  261. package/dist/shapes.js.map +0 -1
  262. package/dist/static-text.d.ts +0 -33
  263. package/dist/static-text.d.ts.map +0 -1
  264. package/dist/static-text.js +0 -105
  265. package/dist/static-text.js.map +0 -1
  266. package/dist/text-layout.d.ts +0 -66
  267. package/dist/text-layout.d.ts.map +0 -1
  268. package/dist/text-layout.js +0 -315
  269. package/dist/text-layout.js.map +0 -1
  270. package/dist/text.d.ts +0 -67
  271. package/dist/text.d.ts.map +0 -1
  272. package/dist/text.js +0 -383
  273. package/dist/text.js.map +0 -1
  274. package/dist/timeline.d.ts +0 -150
  275. package/dist/timeline.d.ts.map +0 -1
  276. package/dist/timeline.js +0 -266
  277. package/dist/timeline.js.map +0 -1
@@ -1,725 +0,0 @@
1
- import { Buffer, BufferImageSource, BufferUsage, Geometry, GlProgram, Mesh, RendererType, Shader, UniformGroup, } from "pixi.js";
2
- import { CURVE, LINE, MOVE, shapeLayers } from "../display/shapes.js";
3
- /** Most table entries a text's uniforms hold. */
4
- const ENTRIES = 48;
5
- /**
6
- * Chords a curve is cut into stray from it by this fraction of the em at
7
- * most: a 2048th, a hundredth of a pixel at 20 pixels, and few chords.
8
- */
9
- const TOLERANCE = 2048;
10
- // uView.x: Flash's pixels to a unit of the world, on whose grid they lie, whatever the target.
11
- // uMode: gridFitType (0 none, 1 pixel, 2 subpixel), thickness, sharpness, and whether a Flash
12
- // colour transform (uMul, uAdd) replaces Pixi's colour. uWorldOffset (the Pixi fork's): what a
13
- // filter's input took off the world's translation. uTable: the tables' entries, size, inside,
14
- // outside. A glyph's aOrigin is its pen and its light and dark tables, each its first entry plus
15
- // 64 times its entries; aGlyph a corner of its outline's bounds and the way out from it; aRun its
16
- // segments, first and count, the pixels of a unit of its outline, and its size.
17
- const vertex = `#version 300 es
18
- in vec2 aPosition;
19
- in vec4 aOrigin;
20
- in vec4 aGlyph;
21
- in vec4 aRun;
22
- in vec4 aColor;
23
- out vec2 vPixel;
24
- flat out vec2 vPen;
25
- flat out vec4 vToGlyph;
26
- flat out vec4 vToPixel;
27
- flat out vec4 vCut;
28
- flat out vec4 vShown;
29
- uniform mat3 uProjectionMatrix;
30
- uniform mat3 uWorldTransformMatrix;
31
- uniform vec4 uWorldColorAlpha;
32
- uniform mat3 uTransformMatrix;
33
- uniform vec4 uColor;
34
- uniform vec2 uWorldOffset;
35
- uniform vec4 uView;
36
- uniform vec4 uMode;
37
- uniform vec4 uMul;
38
- uniform vec4 uAdd;
39
- uniform vec4 uTable[${ENTRIES}];
40
-
41
- // The cutoffs at ppem by the table of entries start to start + count, as text/csm.ts' cutoffs.
42
- vec2 cutoffs(int start, int count, float ppem) {
43
- vec4 first = uTable[start];
44
- vec4 last = uTable[start + count - 1];
45
- vec2 c = first.yz;
46
- if (ppem >= last.x) {
47
- c = last.yz;
48
- } else if (ppem > first.x) {
49
- for (int i = 1; i < ${ENTRIES}; i++) {
50
- if (i >= count) {
51
- break;
52
- }
53
-
54
- vec4 b = uTable[start + i];
55
- if (ppem <= b.x) {
56
- vec4 a = uTable[start + i - 1];
57
- c = mix(a.yz, b.yz, (ppem - a.x) / (b.x - a.x));
58
- break;
59
- }
60
- }
61
- }
62
-
63
- float unit = 0.0001 * ppem;
64
- float t = clamp(uMode.y, -200.0, 200.0);
65
- float s = clamp(uMode.z, -400.0, 400.0);
66
- c -= unit * vec2(t + s * 0.5, t - s * 0.5);
67
- if (c.x < c.y) {
68
- c = vec2((c.x + c.y) * 0.5);
69
- }
70
-
71
- return c;
72
- }
73
-
74
- void main(void) {
75
- // The local space to Flash's pixels, in the world's space: their grid is the stage's (or a
76
- // BitmapData's) wherever the target lies on it, as a filter's does.
77
- float unit = uView.x;
78
- mat3 m = mat3(unit, 0.0, 0.0, 0.0, unit, 0.0, uWorldOffset * unit, 1.0)
79
- * uWorldTransformMatrix * uTransformMatrix;
80
- mat2 linear = mat2(m[0].xy, m[1].xy);
81
- vec2 origin = m[2].xy;
82
- vec2 pen = (m * vec3(aOrigin.xy, 1.0)).xy + roundEven(origin) - origin;
83
- float across = max(abs(linear[0][1]), abs(linear[1][0]));
84
- if (across > max(abs(linear[0][0]), abs(linear[1][1])) / 65536.0) {
85
- // Turned or skewed: no grid.
86
- } else if (uMode.x == 1.0) {
87
- pen = vec2(roundEven(pen.x * 8.0) / 8.0 + 0.5, roundEven(pen.y));
88
- } else if (uMode.x == 2.0) {
89
- pen = vec2(roundEven(pen.x * 4.0) / 4.0 + 0.5, roundEven(pen.y));
90
- } else {
91
- pen = roundEven(pen * 4.0) / 4.0 + vec2(0.5, 0.0);
92
- }
93
-
94
- float ppem = aRun.w * sqrt(abs(determinant(linear)));
95
- // The colour as drawn, straight: light or dark by it, as adl chooses.
96
- vec4 tint = uColor * uWorldColorAlpha;
97
- vec4 shown = uMode.w < 0.5
98
- ? vec4(aColor.rgb * (tint.a > 0.0 ? tint.rgb / tint.a : vec3(0.0)), aColor.a * tint.a)
99
- : clamp(aColor * uMul + uAdd, 0.0, 1.0);
100
- bool light = dot(floor(shown.rgb * 255.0 + 0.5), vec3(30.0, 59.0, 11.0)) > 20000.0;
101
- int table = int(light ? aOrigin.z : aOrigin.w);
102
- vec2 cut = cutoffs(table & 63, table >> 6, ppem);
103
- mat2 toPixel = linear * aRun.z;
104
- float margin = max(abs(cut.x), abs(cut.y)) + 1.0;
105
- float det = determinant(toPixel);
106
- mat2 inverse = det != 0.0
107
- ? mat2(toPixel[1][1], -toPixel[0][1], -toPixel[1][0], toPixel[0][0]) / det
108
- : mat2(0.0);
109
- // Expand in glyph space so the margin stays outside under reflections and rotations.
110
- // Each inverse row gives the glyph units needed for a pixel perpendicular to that edge.
111
- vec2 reach = vec2(length(vec2(inverse[0][0], inverse[1][0])),
112
- length(vec2(inverse[0][1], inverse[1][1]))) * margin;
113
- vec2 p = pen + toPixel * (aGlyph.xy + aGlyph.zw * reach);
114
- vPixel = p;
115
- vPen = pen;
116
- vToGlyph = vec4(inverse[0], inverse[1]);
117
- vToPixel = vec4(toPixel[0], toPixel[1]);
118
- vCut = vec4(cut, aRun.xy);
119
- vShown = shown;
120
- gl_Position = vec4((uProjectionMatrix * vec3(p / unit - uWorldOffset, 1.0)).xy, 0.0, 1.0);
121
- }
122
- `;
123
- const fragment = `#version 300 es
124
- precision highp float;
125
- precision highp int;
126
- in vec2 vPixel;
127
- flat in vec2 vPen;
128
- flat in vec4 vToGlyph;
129
- flat in vec4 vToPixel;
130
- flat in vec4 vCut;
131
- flat in vec4 vShown;
132
- out vec4 finalColor;
133
- uniform highp sampler2D uSegments;
134
-
135
- void main(void) {
136
- vec2 centre = floor(vPixel) + 0.5;
137
- mat2 toGlyph = mat2(vToGlyph.xy, vToGlyph.zw);
138
- mat2 toPixel = mat2(vToPixel.xy, vToPixel.zw);
139
- vec2 g = toGlyph * (centre - vPen);
140
- int start = int(vCut.z);
141
- int count = int(vCut.w);
142
- float nearest = 3.4e38;
143
- vec2 along = vec2(1.0, 0.0);
144
- bool inside = false;
145
- for (int i = 0; i < count; i++) {
146
- int k = start + i;
147
- vec4 s = texelFetch(uSegments, ivec2(k & 1023, k >> 10), 0);
148
- vec2 a = s.xy;
149
- vec2 e = s.zw - a;
150
- vec2 w = g - a;
151
- float t = clamp(dot(w, e) / max(dot(e, e), 1e-20), 0.0, 1.0);
152
- vec2 off = w - e * t;
153
- float d = dot(off, off);
154
- if (d < nearest) {
155
- nearest = d;
156
- along = e;
157
- }
158
-
159
- if ((a.y > g.y) != (s.w > g.y) && a.x + (g.y - a.y) * e.x / e.y > g.x) {
160
- inside = !inside;
161
- }
162
- }
163
-
164
- // In Flash's pixels, across the nearest edge as the transform stretches it.
165
- float stretch = length(toPixel * along);
166
- float d = stretch > 0.0
167
- ? sqrt(nearest) * abs(determinant(toPixel)) * length(along) / stretch
168
- : 0.0;
169
- d = inside ? d : -d;
170
- float coverage = vCut.x > vCut.y
171
- ? clamp((d - vCut.y) / (vCut.x - vCut.y), 0.0, 1.0)
172
- : step(vCut.x, d);
173
- // Nothing outside: as a mask, which writes the stencil wherever it draws, a glyph is its shape.
174
- if (coverage <= 0.0) {
175
- discard;
176
- }
177
-
178
- finalColor = vec4(vShown.rgb * vShown.a, vShown.a) * coverage;
179
- }
180
- `;
181
- let program = null;
182
- /** Segments to a row of the texture. */
183
- const ROW = 1024;
184
- /** The most segments kept: 16 bytes each, 16 MB. Past it the store starts again. */
185
- export const MOST = ROW * 1024;
186
- /**
187
- * The most segments a glyph may have: every pixel of its quad goes through
188
- * them all, so a glyph past this is drawn as normal text is.
189
- */
190
- export const GLYPH_MOST = 2048;
191
- /**
192
- * The most a field may ask of the shader, its glyphs' segments times the
193
- * pixels of their quads: past it, the field is drawn as normal text, so
194
- * that no SWF has the GPU go through millions of segments a pixel.
195
- */
196
- export const FIELD_BUDGET = 2 ** 25;
197
- /**
198
- * The glyphs' outlines as segments, x0 y0 x1 y1 a texel, in the font's
199
- * units over 20 (as shapeLayers reads them), each glyph's a run of its
200
- * own: added as a glyph is first drawn, kept until the store is full, when
201
- * it starts again and the texts drawn from it are drawn again, or until the
202
- * last view that draws them goes.
203
- */
204
- let data = new Float32Array(ROW * 4 * 16);
205
- let used = 0;
206
- let source = null;
207
- /** Bumped as the store starts again, grows or goes: each renderer then uploads it whole. */
208
- let epoch = 0;
209
- /** Each renderer's upload of the store: of which epoch, and how many segments of it. */
210
- const uploads = new WeakMap();
211
- /** What a glyph of more segments than GLYPH_MOST is known by, so that it is not cut again. */
212
- const TOO_MANY = { start: 0, count: 0, xMin: 0, yMin: 0, xMax: 0, yMax: 0 };
213
- /** Each glyph's outline in the store as it now is; null for an empty one. */
214
- let outlines = new WeakMap();
215
- /** The texts drawn from the store, each with what draws it again. */
216
- const live = new Map();
217
- /** The segments' texture, made on first use; its contents go up as renderers draw (uploadSegments). */
218
- function segments() {
219
- source ??= new BufferImageSource({
220
- resource: data,
221
- width: ROW,
222
- height: data.length / 4 / ROW,
223
- format: "rgba32float",
224
- scaleMode: "nearest",
225
- alphaMode: "no-premultiply-alpha",
226
- autoGenerateMipmaps: false,
227
- });
228
- return source;
229
- }
230
- /**
231
- * Upload what `renderer` has not of the store: the rows added since it last
232
- * did, or the whole after the store started again or grew. A view calls it
233
- * after it syncs, before it draws.
234
- */
235
- export function uploadSegments(renderer) {
236
- if (!source || renderer.type !== RendererType.WEBGL) {
237
- return;
238
- }
239
- let upload = uploads.get(renderer);
240
- if (!upload) {
241
- // Its first bind uploads the texture whole.
242
- upload = { epoch, segments: used };
243
- uploads.set(renderer, upload);
244
- return;
245
- }
246
- const from = upload.epoch === epoch ? upload.segments : 0;
247
- if (from >= used) {
248
- return;
249
- }
250
- const gl = renderer.gl;
251
- const first = Math.floor(from / ROW);
252
- const rows = Math.ceil(used / ROW) - first;
253
- renderer.texture.bindForUpload(source);
254
- gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, first, ROW, rows, gl.RGBA, gl.FLOAT, data, first * ROW * 4);
255
- upload.epoch = epoch;
256
- upload.segments = used;
257
- }
258
- /**
259
- * Start the store again: every outline is cut again on its next draw, and
260
- * every text drawn from the store hidden till it is drawn again.
261
- */
262
- export function resetSegments() {
263
- used = 0;
264
- epoch++;
265
- outlines = new WeakMap();
266
- for (const [text, again] of live) {
267
- text.visible = false;
268
- again();
269
- }
270
- live.clear();
271
- }
272
- /** How many segments the store holds, for tests. */
273
- export function segmentsUsed() {
274
- return used;
275
- }
276
- /** Room for `count` more segments, the store grown to hold them: false past MOST. */
277
- function room(count) {
278
- if (used + count > MOST) {
279
- return false;
280
- }
281
- if ((used + count) * 4 > data.length) {
282
- let length = data.length;
283
- while ((used + count) * 4 > length) {
284
- length *= 2;
285
- }
286
- const grown = new Float32Array(length);
287
- grown.set(data.subarray(0, used * 4));
288
- data = grown;
289
- if (source) {
290
- source.resource = data;
291
- source.resize(ROW, length / 4 / ROW, 1);
292
- }
293
- epoch++;
294
- }
295
- return true;
296
- }
297
- /**
298
- * A glyph's outline cut into segments, its curves into chords that stray
299
- * from them by `tolerance` at most, as x0 y0 x1 y1 each.
300
- */
301
- export function chordsOf(glyph, tolerance) {
302
- const shape = {
303
- id: 0,
304
- bounds: { xMin: 0, xMax: 0, yMin: 0, yMax: 0 },
305
- edgeBounds: null,
306
- fills: [{ type: "solid", color: 0xffffffff }],
307
- lines: [],
308
- records: glyph.records,
309
- truncated: false,
310
- };
311
- const layers = shapeLayers(shape);
312
- const points = [];
313
- const contours = layers.length > 0 ? layers[0].fills.flatMap((f) => f.contours) : [];
314
- for (const path of contours) {
315
- let x = 0;
316
- let y = 0;
317
- let startX = 0;
318
- let startY = 0;
319
- for (let i = 0; i < path.length;) {
320
- switch (path[i]) {
321
- case MOVE:
322
- if (x !== startX || y !== startY) {
323
- points.push(x, y, startX, startY);
324
- }
325
- x = startX = path[i + 1];
326
- y = startY = path[i + 2];
327
- i += 3;
328
- break;
329
- case LINE:
330
- points.push(x, y, path[i + 1], path[i + 2]);
331
- x = path[i + 1];
332
- y = path[i + 2];
333
- i += 3;
334
- break;
335
- case CURVE: {
336
- const cx = path[i + 1];
337
- const cy = path[i + 2];
338
- const ax = path[i + 3];
339
- const ay = path[i + 4];
340
- // A quadratic strays from its chords of a nth of it by |p0 - 2c + p1| / 4n² at most.
341
- const bend = Math.hypot(x - 2 * cx + ax, y - 2 * cy + ay);
342
- const n = Math.max(1, Math.min(64, Math.ceil(Math.sqrt(bend / (4 * tolerance)))));
343
- let px = x;
344
- let py = y;
345
- for (let k = 1; k <= n; k++) {
346
- const t = k / n;
347
- const u = 1 - t;
348
- const qx = u * u * x + 2 * u * t * cx + t * t * ax;
349
- const qy = u * u * y + 2 * u * t * cy + t * t * ay;
350
- points.push(px, py, qx, qy);
351
- px = qx;
352
- py = qy;
353
- }
354
- x = ax;
355
- y = ay;
356
- i += 5;
357
- break;
358
- }
359
- default:
360
- // A cubic, which no glyph has.
361
- i += 7;
362
- }
363
- }
364
- if (x !== startX || y !== startY) {
365
- points.push(x, y, startX, startY);
366
- }
367
- }
368
- return points;
369
- }
370
- /**
371
- * A glyph's outline in the store, cut on its first draw: null for an empty
372
- * glyph, undefined for one of more segments than GLYPH_MOST or past the
373
- * store's room.
374
- */
375
- function outlineOf(glyph, tolerance) {
376
- const known = outlines.get(glyph);
377
- if (known !== undefined) {
378
- return known === TOO_MANY ? undefined : known;
379
- }
380
- const points = chordsOf(glyph, tolerance);
381
- const count = points.length / 4;
382
- if (count === 0) {
383
- outlines.set(glyph, null);
384
- return null;
385
- }
386
- if (count > GLYPH_MOST) {
387
- outlines.set(glyph, TOO_MANY);
388
- return undefined;
389
- }
390
- if (!room(count)) {
391
- return undefined;
392
- }
393
- const outline = {
394
- start: used,
395
- count,
396
- xMin: Number.POSITIVE_INFINITY,
397
- yMin: Number.POSITIVE_INFINITY,
398
- xMax: Number.NEGATIVE_INFINITY,
399
- yMax: Number.NEGATIVE_INFINITY,
400
- };
401
- for (let i = 0; i < points.length; i += 2) {
402
- outline.xMin = Math.min(outline.xMin, points[i]);
403
- outline.xMax = Math.max(outline.xMax, points[i]);
404
- outline.yMin = Math.min(outline.yMin, points[i + 1]);
405
- outline.yMax = Math.max(outline.yMax, points[i + 1]);
406
- }
407
- data.set(points, used * 4);
408
- used += count;
409
- outlines.set(glyph, outline);
410
- return outline;
411
- }
412
- /** The views that draw on the stage, by which the store is kept: it goes with the last. */
413
- let views = 0;
414
- const viewsGone = new FinalizationRegistry(() => {
415
- views--;
416
- if (views === 0) {
417
- resetSegments();
418
- source?.destroy();
419
- source = null;
420
- data = new Float32Array(ROW * 4 * 16);
421
- }
422
- });
423
- /**
424
- * What every advanced text a view draws shares: Flash's pixels to a unit
425
- * of its world, and whether its renderer draws them at all (WebGL 2, as
426
- * the shader is GLSL ES 3.0; elsewhere text is drawn as normal text).
427
- */
428
- export class SaffronView {
429
- uniforms = new UniformGroup({
430
- uView: { value: new Float32Array([1, 0, 0, 0]), type: "vec4<f32>" },
431
- });
432
- enabled;
433
- constructor(renderer, keeps) {
434
- this.enabled =
435
- renderer.type === RendererType.WEBGL &&
436
- renderer.context?.webGLVersion === 2;
437
- if (keeps) {
438
- views++;
439
- viewsGone.register(this, null);
440
- }
441
- }
442
- get unit() {
443
- return this.uniforms.uniforms.uView[0];
444
- }
445
- set unit(unit) {
446
- const view = this.uniforms.uniforms.uView;
447
- if (view[0] !== unit) {
448
- view[0] = unit;
449
- this.uniforms.update();
450
- }
451
- }
452
- }
453
- /** The corners of a glyph's quad, as signs: the margin goes out from it so. */
454
- const CORNERS = [-1, -1, 1, -1, 1, 1, -1, 1];
455
- /** Floats a vertex: aPosition 2, then aOrigin, aGlyph, aRun and aColor 4 each. */
456
- const STRIDE = 18;
457
- /** The vertices a builder writes, reused by the next: builders build one at a time. */
458
- let scratch = new Float32Array(STRIDE * 4 * 64);
459
- /** Indices of quads in order, two triangles each: views of one array, which only grows. */
460
- let quads = new Uint32Array(0);
461
- function quadIndices(count) {
462
- if (quads.length < count * 6) {
463
- const n = Math.max(count, quads.length / 3);
464
- quads = new Uint32Array(n * 6);
465
- for (let i = 0; i < n; i++) {
466
- const v = i * 4;
467
- const at = i * 6;
468
- quads[at] = v;
469
- quads[at + 1] = v + 1;
470
- quads[at + 2] = v + 2;
471
- quads[at + 3] = v;
472
- quads[at + 4] = v + 2;
473
- quads[at + 5] = v + 3;
474
- }
475
- }
476
- return quads.subarray(0, count * 6);
477
- }
478
- /** The finite value of `v`, 0 for NaN or an infinity, as a field's settings reach the shader. */
479
- const finite = (v) => (Number.isFinite(v) ? v : 0);
480
- /** The table's furthest cutoff from the outline, in pixels. */
481
- function reachOf(table) {
482
- let reach = 0;
483
- for (let i = 0; i < table.length; i += 3) {
484
- reach = Math.max(reach, Math.abs(table[i + 1]), Math.abs(table[i + 2]));
485
- }
486
- return reach;
487
- }
488
- /**
489
- * The glyphs of a text drawn with advanced anti-aliasing: each glyph first
490
- * reserved (reserve), which cuts its outline and counts what it asks of
491
- * the shader, then, if all fit, added (add) and made into one mesh
492
- * (done). One builds at a time: they share the vertices they write.
493
- */
494
- export class SaffronBuilder {
495
- view;
496
- grid;
497
- scale;
498
- again;
499
- glyphs = 0;
500
- tables = [];
501
- starts = [];
502
- entries = 0;
503
- cost = 0;
504
- thickness;
505
- sharpness;
506
- /** The epoch the reserved glyphs' outlines are of. */
507
- reserved = epoch;
508
- constructor(view,
509
- /** 0 none, 1 pixel, 2 subpixel. */
510
- grid, thickness, sharpness,
511
- /** Flash's pixels to a pixel of the text, as it is placed now, for the quads' reach and cost. */
512
- scale,
513
- /** Draws the text again, when the store it is drawn from starts again. */
514
- again) {
515
- this.view = view;
516
- this.grid = grid;
517
- this.scale = scale;
518
- this.again = again;
519
- this.thickness = finite(thickness);
520
- this.sharpness = finite(sharpness);
521
- }
522
- /** Flash's pixels the shader may reach past the outline, at `size` pixels to the em, by `tables`. */
523
- reach(size, tables) {
524
- const ppem = size * this.scale;
525
- const moved = 0.0001 * ppem * (Math.abs(this.thickness) + Math.abs(this.sharpness) / 2);
526
- // And a pixel round, and two for the pen's snapping.
527
- return Math.max(reachOf(tables[0]), reachOf(tables[1])) + moved + 3;
528
- }
529
- /**
530
- * Cut a glyph of a font of `em` units and count it at `size` pixels to the
531
- * em: false where the text cannot be drawn so, a glyph past GLYPH_MOST
532
- * or the field past FIELD_BUDGET, for the whole text to be drawn as
533
- * normal text. The store may start again here: reserving every glyph
534
- * then goes again (reserveAll).
535
- */
536
- reserve(glyph, em, size, tables) {
537
- const units = em / 20;
538
- let outline = outlineOf(glyph, units / TOLERANCE);
539
- if (outline === undefined && outlines.get(glyph) !== TOO_MANY) {
540
- resetSegments();
541
- outline = outlineOf(glyph, units / TOLERANCE);
542
- }
543
- if (outline === undefined) {
544
- return false;
545
- }
546
- if (outline === null) {
547
- return true;
548
- }
549
- const s = (size / units) * this.scale;
550
- const margin = 2 * this.reach(size, tables);
551
- const area = ((outline.xMax - outline.xMin) * s + margin) * ((outline.yMax - outline.yMin) * s + margin);
552
- this.cost += outline.count * area;
553
- return this.cost <= FIELD_BUDGET;
554
- }
555
- /**
556
- * Whether every glyph reserved since restart is still in the store as it
557
- * was: false where the store started again while they were reserved.
558
- */
559
- intact() {
560
- return this.reserved === epoch;
561
- }
562
- /** Reserve afresh, the store's epoch now. */
563
- restart() {
564
- this.cost = 0;
565
- this.reserved = epoch;
566
- }
567
- /**
568
- * Add a reserved glyph, its pen at (x, y) in the text's pixels, `size`
569
- * pixels to the em, in 0xRRGGBB and `alpha`, by the light or the dark of
570
- * `tables` as its colour is drawn: false where the tables' room is full,
571
- * which leaves the text to be drawn as normal text.
572
- */
573
- add(glyph, em, x, y, size, color, alpha, tables) {
574
- const units = em / 20;
575
- const outline = outlineOf(glyph, units / TOLERANCE);
576
- if (outline === null) {
577
- return true;
578
- }
579
- if (outline === undefined) {
580
- return false;
581
- }
582
- const light = this.code(tables[0]);
583
- const dark = this.code(tables[1]);
584
- if (light < 0 || dark < 0) {
585
- return false;
586
- }
587
- if ((this.glyphs + 1) * 4 * STRIDE > scratch.length) {
588
- const grown = new Float32Array(scratch.length * 2);
589
- grown.set(scratch.subarray(0, this.glyphs * 4 * STRIDE));
590
- scratch = grown;
591
- }
592
- const scale = size / units;
593
- // Where the quad reaches in the text's pixels, for Pixi's bounds (filters, culling): the
594
- // shader moves it out by the cutoffs from where the pen snaps.
595
- const out = this.reach(size, tables) / Math.max(this.scale, 1 / 64);
596
- const r = ((color >> 16) & 0xff) / 255;
597
- const g = ((color >> 8) & 0xff) / 255;
598
- const b = (color & 0xff) / 255;
599
- let at = this.glyphs * 4 * STRIDE;
600
- for (let k = 0; k < 8; k += 2) {
601
- const sx = CORNERS[k];
602
- const sy = CORNERS[k + 1];
603
- const gx = sx < 0 ? outline.xMin : outline.xMax;
604
- const gy = sy < 0 ? outline.yMin : outline.yMax;
605
- scratch[at] = x + gx * scale + sx * out;
606
- scratch[at + 1] = y + gy * scale + sy * out;
607
- scratch[at + 2] = x;
608
- scratch[at + 3] = y;
609
- scratch[at + 4] = light;
610
- scratch[at + 5] = dark;
611
- scratch[at + 6] = gx;
612
- scratch[at + 7] = gy;
613
- scratch[at + 8] = sx;
614
- scratch[at + 9] = sy;
615
- scratch[at + 10] = outline.start;
616
- scratch[at + 11] = outline.count;
617
- scratch[at + 12] = scale;
618
- scratch[at + 13] = size;
619
- scratch[at + 14] = r;
620
- scratch[at + 15] = g;
621
- scratch[at + 16] = b;
622
- scratch[at + 17] = alpha;
623
- at += STRIDE;
624
- }
625
- this.glyphs++;
626
- return true;
627
- }
628
- /** A table's place in the uniforms, its first entry plus 64 times its entries, added where new; -1 past their room. */
629
- code(table) {
630
- let t = this.tables.indexOf(table);
631
- if (t < 0) {
632
- if (this.entries + table.length / 3 > ENTRIES) {
633
- return -1;
634
- }
635
- t = this.tables.length;
636
- this.tables.push(table);
637
- this.starts.push(this.entries);
638
- this.entries += table.length / 3;
639
- }
640
- return this.starts[t] + (table.length / 3) * 64;
641
- }
642
- /** The mesh of the glyphs added, null for none. */
643
- done() {
644
- if (this.glyphs === 0) {
645
- return null;
646
- }
647
- const buffer = new Buffer({
648
- data: scratch.slice(0, this.glyphs * 4 * STRIDE),
649
- usage: BufferUsage.VERTEX | BufferUsage.COPY_DST,
650
- });
651
- const bytes = STRIDE * 4;
652
- const geometry = new Geometry({
653
- attributes: {
654
- aPosition: { buffer, format: "float32x2", stride: bytes, offset: 0 },
655
- aOrigin: { buffer, format: "float32x4", stride: bytes, offset: 8 },
656
- aGlyph: { buffer, format: "float32x4", stride: bytes, offset: 24 },
657
- aRun: { buffer, format: "float32x4", stride: bytes, offset: 40 },
658
- aColor: { buffer, format: "float32x4", stride: bytes, offset: 56 },
659
- },
660
- indexBuffer: quadIndices(this.glyphs),
661
- });
662
- const table = new Float32Array(ENTRIES * 4);
663
- for (let t = 0; t < this.tables.length; t++) {
664
- const entries = this.tables[t];
665
- for (let i = 0; i < entries.length; i += 3) {
666
- const at = (this.starts[t] + i / 3) * 4;
667
- table[at] = entries[i];
668
- table[at + 1] = entries[i + 1];
669
- table[at + 2] = entries[i + 2];
670
- }
671
- }
672
- const text = new SaffronText(geometry, this.view, new Float32Array([this.grid, this.thickness, this.sharpness, 0]), table);
673
- live.set(text, this.again);
674
- return text;
675
- }
676
- }
677
- /**
678
- * A text's glyphs drawn with advanced anti-aliasing: a mesh of their
679
- * quads under its own shader, one draw. It destroys its geometry and its
680
- * shader with itself, and leaves the segments' texture, which every one
681
- * shares.
682
- */
683
- export class SaffronText extends Mesh {
684
- uniforms;
685
- flash = null;
686
- constructor(geometry, view, mode, table) {
687
- program ??= new GlProgram({ vertex, fragment, name: "flash-saffron" });
688
- const uniforms = new UniformGroup({
689
- uMode: { value: mode, type: "vec4<f32>" },
690
- uMul: { value: new Float32Array([1, 1, 1, 1]), type: "vec4<f32>" },
691
- uAdd: { value: new Float32Array(4), type: "vec4<f32>" },
692
- uTable: { value: table, type: "vec4<f32>", size: ENTRIES },
693
- });
694
- const shader = new Shader({
695
- glProgram: program,
696
- resources: { uSegments: segments(), saffronView: view.uniforms, saffronText: uniforms },
697
- });
698
- super({ geometry, shader });
699
- this.uniforms = uniforms;
700
- }
701
- /** The Flash colour transform it draws under, in place of Pixi's colour (render/color.ts). */
702
- get flashColor() {
703
- return this.flash;
704
- }
705
- set flashColor(ct) {
706
- this.flash = ct;
707
- const { uMode, uMul, uAdd } = this.uniforms.uniforms;
708
- uMode[3] = ct ? 1 : 0;
709
- if (ct) {
710
- uMul.set([ct.rMul, ct.gMul, ct.bMul, ct.aMul]);
711
- uAdd.set([ct.rAdd / 255, ct.gAdd / 255, ct.bAdd / 255, ct.aAdd / 255]);
712
- }
713
- this.uniforms.update();
714
- }
715
- destroy() {
716
- const geometry = this.geometry;
717
- const shader = this.shader;
718
- live.delete(this);
719
- super.destroy();
720
- // Its buffers too: the renderer holds a buffer, and its data, till the buffer goes.
721
- geometry.destroy(true);
722
- shader.destroy();
723
- }
724
- }
725
- //# sourceMappingURL=saffron.js.map