@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,953 +0,0 @@
1
- // A display object's filters drawn as adl draws them (docs/architecture.md,
2
- // "Filters"): a blur is a box blurX by blurY wide, its ends' pixels
3
- // weighted by how much of them it covers, run `quality` times each way,
4
- // each run truncated to 8 bits; a glow and a shadow are the object's alpha
5
- // so blurred, times strength and alpha, in their colour, behind or inside
6
- // it; a colour matrix maps each pixel's straight colour, transparent ones
7
- // too; a bevel is the object's alpha so blurred, read on and back by its
8
- // offset, their difference in its highlight or shadow colour; a convolution
9
- // sums its taps' straight colour over the object's pixels and one more
10
- // right and down, as BitmapData.applyFilter does. WebGL
11
- // alone: each pass is a filter of its own.
12
- import { BufferImageSource, Filter, GlProgram, Texture as PixiTexture, TexturePool, TextureSource, } from "pixi.js";
13
- import { filterRect, gradientTable, integerKernel } from "./bitmap-filters.js";
14
- const VERTEX = `in vec2 aPosition;
15
- out vec2 vTextureCoord;
16
- uniform vec4 uInputSize;
17
- uniform vec4 uOutputFrame;
18
- uniform vec4 uOutputTexture;
19
- void main(void) {
20
- vec2 position = aPosition * uOutputFrame.zw + uOutputFrame.xy;
21
- position.x = position.x * (2.0 / uOutputTexture.x) - 1.0;
22
- position.y = position.y * (2.0 * uOutputTexture.z / uOutputTexture.y) - uOutputTexture.z;
23
- gl_Position = vec4(position, 0.0, 1.0);
24
- vTextureCoord = aPosition * (uOutputFrame.zw * uInputSize.zw);
25
- }`;
26
- /** Truncated to 8 bits, as adl's each pass is: a hair over, so that an exact value stays. */
27
- const TRUNCATE = "floor(c * 255.0 + 0.001) / 255.0";
28
- /**
29
- * One run of the box one way: `uWidth` texels wide, its end texels weighted
30
- * by their part; `uDirection` a texel's step in the input's pixels, which
31
- * uInputSize gives the coordinates in.
32
- */
33
- const BOX = `in vec2 vTextureCoord;
34
- out vec4 finalColor;
35
- uniform sampler2D uTexture;
36
- // As the vertex shader has it, which is highp: a program's uniforms agree.
37
- uniform highp vec4 uInputSize;
38
- uniform vec2 uDirection;
39
- uniform float uWidth;
40
- void main(void) {
41
- float half_ = uWidth * 0.5;
42
- int reach = int(ceil(half_));
43
- vec4 sum = vec4(0.0);
44
- // As far as 255 pixels at 4 texels a pixel, each way.
45
- for (int i = 0; i <= 2040; i++) {
46
- if (i > 2 * reach) { break; }
47
- float f = float(i - reach);
48
- float weight = max(0.0, min(f + 0.5, half_) - max(f - 0.5, -half_));
49
- sum += texture(uTexture, vTextureCoord + uDirection * uInputSize.zw * f) * weight;
50
- }
51
- vec4 c = sum / uWidth;
52
- finalColor = ${TRUNCATE};
53
- }`;
54
- class BoxPass extends Filter {
55
- constructor() {
56
- super({
57
- glProgram: GlProgram.from({ vertex: VERTEX, fragment: BOX, name: "flash-box-blur" }),
58
- resources: {
59
- boxUniforms: {
60
- uDirection: { value: new Float32Array([1, 0]), type: "vec2<f32>" },
61
- uWidth: { value: 1, type: "f32" },
62
- },
63
- },
64
- });
65
- }
66
- set(dx, dy, width) {
67
- const u = this.resources.boxUniforms.uniforms;
68
- u.uDirection[0] = dx;
69
- u.uDirection[1] = dy;
70
- u.uWidth = width;
71
- }
72
- }
73
- /** The box's runs over `input` into `output`, through a texture of the pool between them. */
74
- function blur(system, pass, input, output, blurX, blurY, quality, resolution, clear) {
75
- const runs = [];
76
- for (let i = 0; i < quality; i++) {
77
- if (blurX > 1) {
78
- runs.push([1 / resolution, 0, blurX * resolution]);
79
- }
80
- if (blurY > 1) {
81
- runs.push([0, 1 / resolution, blurY * resolution]);
82
- }
83
- }
84
- if (runs.length === 0) {
85
- pass.set(1, 0, 1);
86
- system.applyFilter(pass, input, output, clear);
87
- return;
88
- }
89
- const temps = [TexturePool.getSameSizeTexture(input), TexturePool.getSameSizeTexture(input)];
90
- let from = input;
91
- for (const [k, [dx, dy, width]] of runs.entries()) {
92
- pass.set(dx, dy, width);
93
- const last = k === runs.length - 1;
94
- const to = last ? output : temps[k % 2];
95
- system.applyFilter(pass, from, to, last ? clear : true);
96
- from = to;
97
- }
98
- for (const t of temps) {
99
- TexturePool.returnTexture(t);
100
- }
101
- }
102
- /** A filter run at the target's resolution, which the blur's width is in texels of. */
103
- class FlashFilter extends Filter {
104
- /** The texels to a pixel this run: the input's, made at the target's resolution. */
105
- texels(input) {
106
- return input.source.resolution;
107
- }
108
- }
109
- /** A private idle binding avoids scanning every other filter's listener on WHITE. */
110
- class BlurredFilter extends FlashFilter {
111
- unbound;
112
- constructor(options) {
113
- const unbound = new TextureSource();
114
- super({ ...options, resources: { ...options.resources, uBlurred: unbound } });
115
- this.unbound = unbound;
116
- }
117
- /** Release pooled textures before the pool can destroy them. */
118
- unbind() {
119
- this.resources.uBlurred = this.unbound;
120
- }
121
- destroy() {
122
- super.destroy();
123
- this.unbound.destroy();
124
- }
125
- }
126
- class BlurFilter extends FlashFilter {
127
- f;
128
- pass = new BoxPass();
129
- /** Its box's pass too, a filter of its own. */
130
- destroy() {
131
- this.pass.destroy();
132
- super.destroy();
133
- }
134
- constructor(f) {
135
- super({
136
- glProgram: GlProgram.from({ vertex: VERTEX, fragment: BOX, name: "flash-blur" }),
137
- resources: {},
138
- });
139
- this.f = f;
140
- this.padding = Math.ceil((f.quality * Math.max(f.blurX, f.blurY)) / 2);
141
- }
142
- apply(system, input, output, clear) {
143
- const f = this.f;
144
- blur(system, this.pass, input, output, f.blurX || 0, f.blurY || 0, f.quality, this.texels(input), clear);
145
- }
146
- }
147
- /**
148
- * A glow or a shadow: the input's blurred alpha (uBlurred), from `uOffset`
149
- * texels back for a shadow, times strength and alpha, in its colour; behind
150
- * the object, or inside it for an inner one; the object kept, or not.
151
- */
152
- const GLOW = `in vec2 vTextureCoord;
153
- out vec4 finalColor;
154
- uniform sampler2D uTexture;
155
- uniform sampler2D uBlurred;
156
- uniform highp vec4 uInputSize;
157
- uniform vec3 uColor;
158
- uniform float uAlpha;
159
- uniform float uStrength;
160
- uniform vec2 uOffset;
161
- uniform float uInner;
162
- uniform float uKnockout;
163
- uniform float uHide;
164
- void main(void) {
165
- vec4 src = texture(uTexture, vTextureCoord);
166
- float a = texture(uBlurred, vTextureCoord - uOffset * uInputSize.zw).a;
167
- vec4 c;
168
- if (uInner > 0.5) {
169
- float g = clamp((1.0 - a) * uStrength, 0.0, 1.0) * uAlpha * src.a;
170
- vec4 glow = vec4(uColor * g, g);
171
- c = uKnockout > 0.5 ? glow : glow + src * (1.0 - g);
172
- } else {
173
- float g = clamp(a * uStrength, 0.0, 1.0) * uAlpha;
174
- vec4 glow = vec4(uColor * g, g);
175
- c = uKnockout > 0.5 ? glow * (1.0 - src.a) : uHide > 0.5 ? glow : src + glow * (1.0 - src.a);
176
- }
177
- finalColor = ${TRUNCATE};
178
- }`;
179
- class GlowFilter extends BlurredFilter {
180
- f;
181
- pass = new BoxPass();
182
- /** Its box's pass too, a filter of its own. */
183
- destroy() {
184
- this.pass.destroy();
185
- super.destroy();
186
- }
187
- constructor(f) {
188
- const shadow = f.kind === "dropShadow";
189
- const radians = ((f.angle || 0) * Math.PI) / 180;
190
- const distance = shadow ? f.distance || 0 : 0;
191
- super({
192
- glProgram: GlProgram.from({ vertex: VERTEX, fragment: GLOW, name: "flash-glow" }),
193
- resources: {
194
- glowUniforms: {
195
- uColor: {
196
- value: new Float32Array([
197
- ((f.color >> 16) & 0xff) / 255,
198
- ((f.color >> 8) & 0xff) / 255,
199
- (f.color & 0xff) / 255,
200
- ]),
201
- type: "vec3<f32>",
202
- },
203
- uAlpha: { value: f.alpha, type: "f32" },
204
- uStrength: { value: f.strength, type: "f32" },
205
- uOffset: {
206
- value: new Float32Array([distance * Math.cos(radians), distance * Math.sin(radians)]),
207
- type: "vec2<f32>",
208
- },
209
- uInner: { value: f.inner ? 1 : 0, type: "f32" },
210
- uKnockout: { value: f.knockout ? 1 : 0, type: "f32" },
211
- uHide: { value: shadow && f.hideObject ? 1 : 0, type: "f32" },
212
- },
213
- },
214
- });
215
- this.f = f;
216
- this.padding = Math.ceil((f.quality * Math.max(f.blurX, f.blurY)) / 2 + Math.abs(distance));
217
- }
218
- apply(system, input, output, clear) {
219
- const f = this.f;
220
- const resolution = this.texels(input);
221
- const offset = this.resources.glowUniforms.uniforms.uOffset;
222
- const radians = ((f.angle || 0) * Math.PI) / 180;
223
- const distance = f.kind === "dropShadow" ? f.distance || 0 : 0;
224
- // In the input's pixels, as its coordinates are.
225
- offset[0] = distance * Math.cos(radians);
226
- offset[1] = distance * Math.sin(radians);
227
- const blurred = TexturePool.getSameSizeTexture(input);
228
- blur(system, this.pass, input, blurred, f.blurX || 0, f.blurY || 0, f.quality, resolution, true);
229
- this.resources.uBlurred = blurred.source;
230
- system.applyFilter(this, input, output, clear);
231
- this.unbind();
232
- TexturePool.returnTexture(blurred);
233
- }
234
- }
235
- /**
236
- * A bevel: the input's blurred alpha (uBlurred) from uOffset texels on and
237
- * back; their difference times strength, clamped, times the colour's alpha,
238
- * the highlight where on is more and the shadow where it is less. Inner
239
- * (uType 0) atop the object, outer (1) behind it, full (2) over it;
240
- * knocked out, alone, masked to where the object is (inner) or is not
241
- * (outer).
242
- */
243
- const BEVEL = `in vec2 vTextureCoord;
244
- out vec4 finalColor;
245
- uniform sampler2D uTexture;
246
- uniform sampler2D uBlurred;
247
- uniform highp vec4 uInputSize;
248
- uniform vec3 uHighlight;
249
- uniform vec3 uShadow;
250
- uniform float uHighlightAlpha;
251
- uniform float uShadowAlpha;
252
- uniform float uStrength;
253
- uniform vec2 uOffset;
254
- uniform float uType;
255
- uniform float uKnockout;
256
- void main(void) {
257
- // Keep source samples sharp; the bevel reads alpha at a stage pixel's centre.
258
- vec2 at = (floor(vTextureCoord * uInputSize.xy) + 0.5) * uInputSize.zw;
259
- vec4 src = texture(uTexture, vTextureCoord);
260
- vec2 step_ = uOffset * uInputSize.zw;
261
- // In 255ths, each read truncated, as adl's are.
262
- float on = floor(texture(uBlurred, at + step_).a * 255.0 + 0.001);
263
- float back = floor(texture(uBlurred, at - step_).a * 255.0 + 0.001);
264
- float d = on - back;
265
- bool lit = d > 0.0;
266
- float strong = min(255.0, floor(abs(d) * uStrength + 0.001));
267
- float la = floor(strong * (lit ? uHighlightAlpha : uShadowAlpha) + 0.5) / 255.0;
268
- float m = uType < 0.5 ? src.a : (uType < 1.5 && uKnockout > 0.5 ? 1.0 - src.a : 1.0);
269
- vec4 layer = vec4((lit ? uHighlight : uShadow) * la, la) * m;
270
- vec4 c;
271
- if (uKnockout > 0.5) {
272
- c = layer;
273
- } else if (uType > 0.5 && uType < 1.5) {
274
- c = src + layer * (1.0 - src.a);
275
- } else {
276
- c = layer + src * (1.0 - (uType < 0.5 ? la : layer.a));
277
- }
278
- finalColor = ${TRUNCATE};
279
- }`;
280
- class BevelFilter extends BlurredFilter {
281
- f;
282
- pass = new BoxPass();
283
- /** Its box's pass too, a filter of its own. */
284
- destroy() {
285
- this.pass.destroy();
286
- super.destroy();
287
- }
288
- constructor(f) {
289
- const rgb = (c) => new Float32Array([((c >> 16) & 0xff) / 255, ((c >> 8) & 0xff) / 255, (c & 0xff) / 255]);
290
- const radians = ((f.angle || 0) * Math.PI) / 180;
291
- const distance = f.distance || 0;
292
- super({
293
- glProgram: GlProgram.from({ vertex: VERTEX, fragment: BEVEL, name: "flash-bevel" }),
294
- resources: {
295
- bevelUniforms: {
296
- uHighlight: { value: rgb(f.highlightColor), type: "vec3<f32>" },
297
- uShadow: { value: rgb(f.shadowColor), type: "vec3<f32>" },
298
- uHighlightAlpha: { value: f.highlightAlpha, type: "f32" },
299
- uShadowAlpha: { value: f.shadowAlpha, type: "f32" },
300
- uStrength: { value: f.strength, type: "f32" },
301
- uOffset: {
302
- value: new Float32Array([distance * Math.cos(radians), distance * Math.sin(radians)]),
303
- type: "vec2<f32>",
304
- },
305
- uType: { value: f.type === "inner" ? 0 : f.type === "outer" ? 1 : 2, type: "f32" },
306
- uKnockout: { value: f.knockout ? 1 : 0, type: "f32" },
307
- },
308
- },
309
- });
310
- this.f = f;
311
- this.padding = Math.ceil((f.quality * Math.max(f.blurX, f.blurY)) / 2 + Math.abs(distance));
312
- }
313
- apply(system, input, output, clear) {
314
- const f = this.f;
315
- const blurred = TexturePool.getSameSizeTexture(input);
316
- blur(system, this.pass, input, blurred, f.blurX || 0, f.blurY || 0, f.quality, this.texels(input), true);
317
- this.resources.uBlurred = blurred.source;
318
- system.applyFilter(this, input, output, clear);
319
- this.unbind();
320
- TexturePool.returnTexture(blurred);
321
- }
322
- }
323
- /** Premultiplied ARGB as the RGBA bytes a texture holds, still premultiplied. */
324
- export function rgbaOf(pixels) {
325
- const out = new Uint8Array(pixels.length * 4);
326
- for (let i = 0; i < pixels.length; i++) {
327
- const p = pixels[i];
328
- const j = i * 4;
329
- out[j] = (p >>> 16) & 0xff;
330
- out[j + 1] = (p >>> 8) & 0xff;
331
- out[j + 2] = p & 0xff;
332
- out[j + 3] = p >>> 24;
333
- }
334
- return out;
335
- }
336
- /**
337
- * How a bevel or a gradient filter places its layer (premultiplied) on the
338
- * object's pixel, as bitmap-filters' placer does: masked to where the
339
- * object is (uType 0, inner) or, knocked out, is not (1, outer); inner
340
- * atop it, outer behind it, full (2) over it, knocked out alone.
341
- */
342
- const PLACE = `vec4 place(vec4 src, vec4 layer) {
343
- float m = uType < 0.5 ? src.a : (uType < 1.5 && uKnockout > 0.5 ? 1.0 - src.a : 1.0);
344
- vec4 masked = layer * m;
345
- if (uKnockout > 0.5) {
346
- return masked;
347
- }
348
- if (uType > 0.5 && uType < 1.5) {
349
- return src + masked * (1.0 - src.a);
350
- }
351
- return masked + src * (1.0 - (uType < 0.5 ? layer.a : masked.a));
352
- }`;
353
- /**
354
- * A gradient glow: the input's blurred alpha (uBlurred) from uOffset back,
355
- * as a shadow reads it, times strength, picking a texel of the gradient
356
- * (uGradient, 256 wide); a gradient bevel (uBevel 1): the difference of
357
- * that alpha on and back, the middle of the gradient where they agree.
358
- * Each pixel is evaluated once, at its centre, in 255ths truncated.
359
- */
360
- const GRADIENT = `in vec2 vTextureCoord;
361
- out vec4 finalColor;
362
- uniform sampler2D uTexture;
363
- uniform sampler2D uBlurred;
364
- uniform sampler2D uGradient;
365
- uniform highp vec4 uInputSize;
366
- uniform float uStrength;
367
- uniform vec2 uOffset;
368
- uniform float uType;
369
- uniform float uKnockout;
370
- uniform float uBevel;
371
- uniform vec4 uRegion;
372
- ${PLACE}
373
- float alphaAt(vec2 at) {
374
- return floor(texture(uBlurred, at).a * 255.0 + 0.001);
375
- }
376
- void main(void) {
377
- vec2 p = floor(vTextureCoord * uInputSize.xy) + 0.5;
378
- // Past the filter's rect it draws nothing, though its gradient may have colour at 0.
379
- if (any(lessThan(p, uRegion.xy)) || any(greaterThanEqual(p, uRegion.zw))) {
380
- finalColor = vec4(0.0);
381
- return;
382
- }
383
- vec2 at = p * uInputSize.zw;
384
- vec4 src = texture(uTexture, at);
385
- vec2 step_ = uOffset * uInputSize.zw;
386
- float index;
387
- if (uBevel > 0.5) {
388
- float d = clamp(floor((alphaAt(at + step_) - alphaAt(at - step_)) * uStrength), -255.0, 255.0);
389
- index = floor((d + 256.0) / 2.0);
390
- } else {
391
- index = min(255.0, floor(alphaAt(at - step_) * uStrength + 0.001));
392
- }
393
- vec4 layer = texture(uGradient, vec2((index + 0.5) / 256.0, 0.5));
394
- vec4 c = place(src, layer);
395
- finalColor = ${TRUNCATE};
396
- }`;
397
- class GradientFilter extends BlurredFilter {
398
- f;
399
- pass = new BoxPass();
400
- gradient;
401
- /** Its box's pass and its gradient too. */
402
- destroy() {
403
- this.pass.destroy();
404
- this.gradient.destroy(true);
405
- super.destroy();
406
- }
407
- constructor(f) {
408
- const radians = ((f.angle || 0) * Math.PI) / 180;
409
- const distance = f.distance || 0;
410
- const gradient = new PixiTexture({
411
- source: new BufferImageSource({
412
- resource: rgbaOf(gradientTable(f)),
413
- width: 256,
414
- height: 1,
415
- alphaMode: "premultiplied-alpha",
416
- scaleMode: "nearest",
417
- addressMode: "clamp-to-edge",
418
- }),
419
- });
420
- super({
421
- glProgram: GlProgram.from({
422
- vertex: VERTEX,
423
- fragment: GRADIENT,
424
- name: "flash-gradient-filter",
425
- }),
426
- resources: {
427
- gradientUniforms: {
428
- uStrength: { value: f.strength, type: "f32" },
429
- uOffset: {
430
- value: new Float32Array([distance * Math.cos(radians), distance * Math.sin(radians)]),
431
- type: "vec2<f32>",
432
- },
433
- uType: { value: f.type === "inner" ? 0 : f.type === "outer" ? 1 : 2, type: "f32" },
434
- uKnockout: { value: f.knockout ? 1 : 0, type: "f32" },
435
- uBevel: { value: f.kind === "gradientBevel" ? 1 : 0, type: "f32" },
436
- uRegion: { value: new Float32Array(4), type: "vec4<f32>" },
437
- },
438
- uGradient: gradient.source,
439
- },
440
- });
441
- this.f = f;
442
- this.gradient = gradient;
443
- // The rect's growth each way, as applyFilter's: left, top, right, bottom.
444
- const rect = filterRect({ x: 0, y: 0, width: 1, height: 1 }, f);
445
- this.grows = [-rect.x, -rect.y, rect.x + rect.width - 1, rect.y + rect.height - 1];
446
- this.padding = Math.max(...this.grows) + 1;
447
- }
448
- /** How far the filter's rect grows past the object, each way: left, top, right, bottom. */
449
- grows;
450
- /** How far in from the input's frame the object's pixels start: this and the later filters' padding. */
451
- inset = 0;
452
- apply(system, input, output, clear) {
453
- const f = this.f;
454
- const blurred = TexturePool.getSameSizeTexture(input);
455
- blur(system, this.pass, input, blurred, f.blurX || 0, f.blurY || 0, f.quality, this.texels(input), true);
456
- this.resources.uBlurred = blurred.source;
457
- // The object's pixels and one more right and down, as adl's bitmap of it, grown by the rect.
458
- const region = this.resources.gradientUniforms.uniforms.uRegion;
459
- const [left, top, right, bottom] = this.grows;
460
- region[0] = this.inset - left;
461
- region[1] = this.inset - top;
462
- region[2] = input.frame.width - this.inset + 1 + right;
463
- region[3] = input.frame.height - this.inset + 1 + bottom;
464
- system.applyFilter(this, input, output, clear);
465
- this.unbind();
466
- TexturePool.returnTexture(blurred);
467
- }
468
- }
469
- /**
470
- * A displacement map, in the input's pixels from its frame's corner: each
471
- * pixel of the object's (uBox) where the map lies (uMapAt, uMapSize) takes
472
- * the input at itself moved by the map's channel (uComponents picks one
473
- * for x, one for y) less 128, times scale, in 256ths toward 0, between
474
- * pixels with weights in 256ths; past the object's pixels as uMode says:
475
- * 0 wrap, 1 clamp, 2 its own place, 3 uColor, which also fills uGrow pixels
476
- * round the object, as adl's drawing of it does. Each pixel once, at its
477
- * centre.
478
- */
479
- const DISPLACE = `in vec2 vTextureCoord;
480
- out vec4 finalColor;
481
- uniform sampler2D uTexture;
482
- uniform sampler2D uMap;
483
- uniform highp vec4 uInputSize;
484
- uniform vec4 uBox;
485
- uniform vec4 uMapAt;
486
- uniform vec4 uComponentX;
487
- uniform vec4 uComponentY;
488
- uniform vec2 uScale;
489
- uniform float uMode;
490
- uniform vec4 uColor;
491
- uniform vec2 uGrow;
492
- vec4 read(vec2 at, vec2 own) {
493
- vec2 size = uBox.zw - uBox.xy;
494
- vec2 i = at - uBox.xy;
495
- if (any(lessThan(i, vec2(0.0))) || any(greaterThanEqual(i, size))) {
496
- if (uMode < 0.5) {
497
- i = mod(i, size);
498
- } else if (uMode < 2.5) {
499
- i = clamp(i, vec2(0.0), size - 1.0);
500
- } else {
501
- return uColor;
502
- }
503
- }
504
- return texture(uTexture, (uBox.xy + i + 0.5) * uInputSize.zw);
505
- }
506
- void main(void) {
507
- vec2 p = floor(vTextureCoord * uInputSize.xy);
508
- vec4 own = texture(uTexture, (p + 0.5) * uInputSize.zw);
509
- vec2 m = p - uMapAt.xy;
510
- if (any(lessThan(p, uBox.xy)) || any(greaterThanEqual(p, uBox.zw))) {
511
- bool near = all(greaterThanEqual(p, uBox.xy - uGrow)) && all(lessThan(p, uBox.zw + uGrow));
512
- finalColor = uMode > 2.5 && near ? uColor : vec4(0.0);
513
- return;
514
- }
515
- if (any(lessThan(m, vec2(0.0))) || any(greaterThanEqual(m, uMapAt.zw))) {
516
- finalColor = own;
517
- return;
518
- }
519
- vec4 map = texture(uMap, (m + 0.5) / uMapAt.zw);
520
- vec4 straight = map.a > 0.0 ? vec4(map.rgb / map.a, map.a) : vec4(0.0);
521
- vec2 c = floor(vec2(dot(straight, uComponentX), dot(straight, uComponentY)) * 255.0 + 0.5);
522
- // None picked: no move.
523
- c = vec2(uComponentX == vec4(0.0) ? 128.0 : c.x, uComponentY == vec4(0.0) ? 128.0 : c.y);
524
- // Toward 0, without trunc, which GLSL ES 1 has not.
525
- vec2 moved = (c - 128.0) * uScale;
526
- vec2 q = p * 256.0 + sign(moved) * floor(abs(moved));
527
- vec2 whole = floor(q / 256.0);
528
- vec2 f = q - whole * 256.0;
529
- if (uMode > 1.5 && uMode < 2.5) {
530
- vec2 i = whole - uBox.xy;
531
- vec2 size = uBox.zw - uBox.xy;
532
- whole = vec2(i.x < 0.0 || i.x >= size.x ? p.x : whole.x, i.y < 0.0 || i.y >= size.y ? p.y : whole.y);
533
- }
534
- float w00 = floor((256.0 - f.x) * (256.0 - f.y) / 256.0);
535
- float w10 = floor(f.x * (256.0 - f.y) / 256.0);
536
- float w01 = floor((256.0 - f.x) * f.y / 256.0);
537
- float w11 = floor(f.x * f.y / 256.0);
538
- vec4 v = read(whole, p) * w00 + read(whole + vec2(1.0, 0.0), p) * w10 +
539
- read(whole + vec2(0.0, 1.0), p) * w01 + read(whole + vec2(1.0, 1.0), p) * w11;
540
- vec4 c8 = floor(v * 255.0 / 256.0 + 0.001) / 255.0;
541
- finalColor = c8;
542
- }`;
543
- class DisplacementFilter extends FlashFilter {
544
- f;
545
- map;
546
- /** How far in from the input's frame the object's pixels start: this and the later filters' padding. */
547
- inset = 0;
548
- constructor(f, map) {
549
- const pick = (c) => new Float32Array([c === 1 ? 1 : 0, c === 2 ? 1 : 0, c === 4 ? 1 : 0, c === 8 ? 1 : 0]);
550
- // Colour mode draws half the scale round the object, as adl does.
551
- const grow = f.mode === "color"
552
- ? [Math.floor(Math.abs(f.scaleX) / 2) || 0, Math.floor(Math.abs(f.scaleY) / 2) || 0]
553
- : [0, 0];
554
- const a = Math.floor(f.alpha * 255) / 255;
555
- super({
556
- glProgram: GlProgram.from({ vertex: VERTEX, fragment: DISPLACE, name: "flash-displacement" }),
557
- resources: {
558
- displaceUniforms: {
559
- uBox: { value: new Float32Array(4), type: "vec4<f32>" },
560
- uMapAt: { value: new Float32Array(4), type: "vec4<f32>" },
561
- uComponentX: { value: pick(f.componentX), type: "vec4<f32>" },
562
- uComponentY: { value: pick(f.componentY), type: "vec4<f32>" },
563
- uScale: { value: new Float32Array([f.scaleX || 0, f.scaleY || 0]), type: "vec2<f32>" },
564
- uMode: {
565
- value: ["wrap", "clamp", "ignore", "color"].indexOf(f.mode),
566
- type: "f32",
567
- },
568
- uColor: {
569
- value: new Float32Array([
570
- (((f.color >> 16) & 0xff) / 255) * a,
571
- (((f.color >> 8) & 0xff) / 255) * a,
572
- ((f.color & 0xff) / 255) * a,
573
- a,
574
- ]),
575
- type: "vec4<f32>",
576
- },
577
- uGrow: { value: new Float32Array(grow), type: "vec2<f32>" },
578
- },
579
- uMap: PixiTexture.EMPTY.source,
580
- },
581
- });
582
- this.f = f;
583
- this.map = map;
584
- this.padding = Math.max(...grow) + 1;
585
- }
586
- apply(system, input, output, clear) {
587
- const map = this.map;
588
- const u = this.resources.displaceUniforms.uniforms;
589
- const box = u.uBox;
590
- // The object's pixels and one more right and down, as adl's bitmap of it.
591
- box[0] = this.inset;
592
- box[1] = this.inset;
593
- box[2] = input.frame.width - this.inset + 1;
594
- box[3] = input.frame.height - this.inset + 1;
595
- const at = u.uMapAt;
596
- at[0] = this.inset + this.f.mapPoint[0];
597
- at[1] = this.inset + this.f.mapPoint[1];
598
- at[2] = map.width;
599
- at[3] = map.height;
600
- this.resources.uMap = map.source;
601
- system.applyFilter(this, input, output, clear);
602
- }
603
- }
604
- /** A colour matrix of a pixel's straight colour, its offsets in 255ths, transparent pixels too. */
605
- const MATRIX = `in vec2 vTextureCoord;
606
- out vec4 finalColor;
607
- uniform sampler2D uTexture;
608
- uniform mat4 uMatrix;
609
- uniform vec4 uOffset;
610
- void main(void) {
611
- vec4 src = texture(uTexture, vTextureCoord);
612
- vec4 straight = src.a > 0.0 ? vec4(src.rgb / src.a, src.a) : vec4(0.0);
613
- vec4 s = clamp(uMatrix * straight + uOffset, 0.0, 1.0);
614
- vec4 c = vec4(s.rgb * s.a, s.a);
615
- finalColor = ${TRUNCATE};
616
- }`;
617
- class ColorMatrixFilter extends FlashFilter {
618
- constructor(f) {
619
- const m = f.matrix;
620
- // Column-major for GLSL: column j is input channel j's part of each output.
621
- const matrix = new Float32Array(16);
622
- for (let row = 0; row < 4; row++) {
623
- for (let col = 0; col < 4; col++) {
624
- matrix[col * 4 + row] = m[row * 5 + col] || 0;
625
- }
626
- }
627
- super({
628
- glProgram: GlProgram.from({ vertex: VERTEX, fragment: MATRIX, name: "flash-color-matrix" }),
629
- resources: {
630
- matrixUniforms: {
631
- uMatrix: { value: matrix, type: "mat4x4<f32>" },
632
- uOffset: {
633
- value: new Float32Array([0, 1, 2, 3].map((row) => (m[row * 5 + 4] || 0) / 255)),
634
- type: "vec4<f32>",
635
- },
636
- },
637
- },
638
- });
639
- }
640
- }
641
- /**
642
- * A convolution, in 255ths: the taps' straight colour over uBox, the
643
- * object's pixels as adl filters them, in the input's pixels from its
644
- * frame's corner; past it the nearest edge's or uEdge; summed, divided,
645
- * biased, clamped and premultiplied as bitmap-filters' convolve does, the
646
- * fixed-point way too (uReciprocal not 0) where every tap lies in the box.
647
- */
648
- const CONVOLUTION = `in vec2 vTextureCoord;
649
- out vec4 finalColor;
650
- uniform sampler2D uTexture;
651
- uniform highp vec4 uInputSize;
652
- uniform vec4 uMatrix[57];
653
- uniform vec2 uSize;
654
- uniform vec4 uBox;
655
- uniform vec4 uEdge;
656
- uniform float uDivisor;
657
- uniform float uReciprocal;
658
- uniform float uBias;
659
- uniform float uClamp;
660
- uniform float uPreserve;
661
- vec4 straight(vec2 p) {
662
- if (any(lessThan(p, uBox.xy)) || any(greaterThanEqual(p, uBox.zw))) {
663
- if (uClamp < 0.5) { return uEdge; }
664
- p = clamp(p, floor(uBox.xy) + 0.5, floor(uBox.zw) - 0.5);
665
- }
666
- vec4 c = texture(uTexture, p * uInputSize.zw);
667
- return c.a > 0.0 ? floor(vec4(c.rgb / c.a, c.a) * 255.0 + 0.5) : vec4(0.0);
668
- }
669
- void main(void) {
670
- // The pixel's centre, which all its texels read alike, as adl's one pixel.
671
- vec2 p = floor(vTextureCoord * uInputSize.xy) + 0.5;
672
- vec2 reach = floor(uSize * 0.5);
673
- if (any(lessThan(p, uBox.xy - reach)) || any(greaterThanEqual(p, uBox.zw + reach))) {
674
- finalColor = vec4(0.0);
675
- return;
676
- }
677
- bool fixed_ = uReciprocal != 0.0 && all(greaterThanEqual(p - 1.0, uBox.xy)) &&
678
- all(lessThan(p + 1.0, uBox.zw));
679
- int cols = int(uSize.x);
680
- int count = cols * int(uSize.y);
681
- vec4 sum = vec4(0.0);
682
- // One loop, its index alone indexing the weights, as GLSL ES 1 allows.
683
- for (int k = 0; k < 225; k++) {
684
- if (k >= count) { break; }
685
- float w = dot(uMatrix[k / 4], vec4(equal(vec4(float(k - k / 4 * 4)), vec4(0.0, 1.0, 2.0, 3.0))));
686
- if (w != 0.0) {
687
- int j = k / cols;
688
- vec2 at = vec2(float(k - j * cols), float(j)) - reach;
689
- sum += straight(fixed_ && k == 8 ? p : p + at) * w;
690
- }
691
- }
692
- sum = fixed_ ? floor(sum * uReciprocal) : sum / uDivisor;
693
- vec4 v = floor(clamp(sum + uBias, 0.0, 255.0) + 0.0001);
694
- float a = uPreserve > 0.5 ? straight(p).a : v.a;
695
- vec3 c = fixed_ ? floor(v.rgb * a / 255.0) : floor((v.rgb * a + 127.0) / 255.0);
696
- finalColor = vec4(c, a) / 255.0;
697
- }`;
698
- class ConvolutionFilter extends FlashFilter {
699
- /** How far in from the input's frame the object's pixels start: this and the later filters' padding. */
700
- inset = 0;
701
- constructor(f) {
702
- const matrix = new Float32Array(57 * 4);
703
- const count = f.matrixX * f.matrixY;
704
- for (let k = 0; k < count; k++) {
705
- matrix[k] = f.matrix[k] || 0;
706
- }
707
- const divisor = f.divisor || 1;
708
- const reciprocal = integerKernel(Array.from(matrix.subarray(0, count)), divisor);
709
- super({
710
- glProgram: GlProgram.from({
711
- vertex: VERTEX,
712
- fragment: CONVOLUTION,
713
- name: "flash-convolution",
714
- }),
715
- resources: {
716
- convolutionUniforms: {
717
- uMatrix: { value: matrix, type: "vec4<f32>", size: 57 },
718
- uSize: { value: new Float32Array([f.matrixX, f.matrixY]), type: "vec2<f32>" },
719
- uBox: { value: new Float32Array(4), type: "vec4<f32>" },
720
- uEdge: {
721
- value: new Float32Array([
722
- (f.color >> 16) & 0xff,
723
- (f.color >> 8) & 0xff,
724
- f.color & 0xff,
725
- Math.floor(f.alpha * 255),
726
- ]),
727
- type: "vec4<f32>",
728
- },
729
- uDivisor: { value: divisor, type: "f32" },
730
- uReciprocal: { value: reciprocal === null ? 0 : reciprocal / 65536, type: "f32" },
731
- uBias: { value: f.bias || 0, type: "f32" },
732
- uClamp: { value: f.clamp ? 1 : 0, type: "f32" },
733
- uPreserve: { value: f.preserveAlpha ? 1 : 0, type: "f32" },
734
- },
735
- },
736
- });
737
- // Its reach, and the pixel right and down adl's bitmap of the object has.
738
- this.padding = Math.max(f.matrixX >> 1, f.matrixY >> 1) + 1;
739
- }
740
- apply(system, input, output, clear) {
741
- const box = this.resources.convolutionUniforms.uniforms.uBox;
742
- box[0] = this.inset;
743
- box[1] = this.inset;
744
- box[2] = input.frame.width - this.inset + 1;
745
- box[3] = input.frame.height - this.inset + 1;
746
- system.applyFilter(this, input, output, clear);
747
- }
748
- }
749
- /**
750
- * A convolution with no taps as adl draws it, a copy moved up and left by
751
- * the half of the other size: one tap there, of 1, the edges transparent.
752
- */
753
- function emptyKernel(f) {
754
- const hx = f.matrixX >> 1;
755
- const hy = f.matrixY >> 1;
756
- const matrixX = 2 * hx + 1;
757
- const matrixY = 2 * hy + 1;
758
- const matrix = new Array(matrixX * matrixY).fill(0);
759
- matrix[matrix.length - 1] = 1;
760
- return {
761
- ...f,
762
- matrixX,
763
- matrixY,
764
- matrix,
765
- divisor: 1,
766
- bias: 0,
767
- clamp: false,
768
- color: 0,
769
- alpha: 0,
770
- preserveAlpha: false,
771
- };
772
- }
773
- /** The Pixi filters a display object's filter records draw as: those swf2es draws yet, in their order. */
774
- export function displayFilters(records, mapTexture = () => null) {
775
- const out = [];
776
- for (const f of records) {
777
- let filter = null;
778
- if (f.kind === "blur") {
779
- filter = new BlurFilter(f);
780
- }
781
- else if (f.kind === "glow" || f.kind === "dropShadow") {
782
- filter = new GlowFilter(f);
783
- }
784
- else if (f.kind === "colorMatrix") {
785
- filter = new ColorMatrixFilter(f);
786
- }
787
- else if (f.kind === "bevel") {
788
- filter = new BevelFilter(f);
789
- }
790
- else if (f.kind === "gradientGlow" || f.kind === "gradientBevel") {
791
- filter = new GradientFilter(f);
792
- }
793
- else if (f.kind === "displacementMap") {
794
- // Its map, a copy the object took when its filters were set, as a
795
- // texture now, never in a pass; with none it leaves the object be.
796
- const map = f.mapSnapshot ?? f.mapBitmap;
797
- const texture = map ? mapTexture(map) : null;
798
- filter = texture ? new DisplacementFilter(f, texture) : null;
799
- }
800
- else if (f.kind === "convolution") {
801
- filter = new ConvolutionFilter(f.matrixX * f.matrixY > 0 ? f : emptyKernel(f));
802
- }
803
- if (filter) {
804
- filter.resolution = "inherit";
805
- out.push(filter);
806
- }
807
- }
808
- let inset = 0;
809
- for (let i = out.length - 1; i >= 0; i--) {
810
- inset += out[i].padding;
811
- const filter = out[i];
812
- if (filter instanceof ConvolutionFilter ||
813
- filter instanceof GradientFilter ||
814
- filter instanceof DisplacementFilter) {
815
- filter.inset = inset;
816
- }
817
- }
818
- return out;
819
- }
820
- const COPY = `in vec2 vTextureCoord;
821
- out vec4 finalColor;
822
- uniform sampler2D uTexture;
823
- void main(void) {
824
- finalColor = texture(uTexture, vTextureCoord);
825
- }`;
826
- /** Whether `a` and `b` give the same output: a move may shift the corner a texel either way. */
827
- function sameInput(a, b) {
828
- return (a.width === b.width &&
829
- a.height === b.height &&
830
- a.resolution === b.resolution &&
831
- Math.abs(a.dx - b.dx) <= 1 &&
832
- Math.abs(a.dy - b.dy) <= 1 &&
833
- a.colorAlpha === b.colorAlpha);
834
- }
835
- /**
836
- * A display object's filters as one, their output kept and drawn again
837
- * while nothing they were run on changed, as Flash caches a filtered
838
- * object as a bitmap: the object, all below it, its transform but for a
839
- * move, the colour and alpha it is drawn in, and how much of it the
840
- * screen shows. The owner calls `changed()` for what Pixi cannot see.
841
- * One changing frame after frame is filtered straight to the target,
842
- * with no copy kept; so is one that `keeps` not, drawn once.
843
- */
844
- export class FilterChain extends Filter {
845
- filters;
846
- owner;
847
- keeps;
848
- /** The input last run on, and the output kept of it, if any. */
849
- ran = null;
850
- kept = null;
851
- stale = true;
852
- /** Runs in a row its object changed for. */
853
- changing = 0;
854
- constructor(filters, owner, keeps = true) {
855
- super({
856
- glProgram: GlProgram.from({ vertex: VERTEX, fragment: COPY, name: "flash-filter-copy" }),
857
- resources: {},
858
- });
859
- this.filters = filters;
860
- this.owner = owner;
861
- this.keeps = keeps;
862
- this.padding = filters.reduce((sum, f) => sum + f.padding, 0);
863
- this.resolution = "inherit";
864
- // The object is drawn into the chain's input as the target draws, with
865
- // its multisampling: Pixi's filters default to none, which left a
866
- // filtered object's edges stepped beside its unfiltered neighbours'.
867
- // Any filter of an object that says "off" turns it off for all of them.
868
- this.antialias = "inherit";
869
- }
870
- /** What it was run on changed: run it again. */
871
- changed() {
872
- this.stale = true;
873
- }
874
- /** The output kept let go of, as its object leaves the display list. */
875
- forget() {
876
- this.release();
877
- this.ran = null;
878
- }
879
- apply(system, input, output, clear) {
880
- if (!this.keeps) {
881
- this.run(system, input, output, clear);
882
- return;
883
- }
884
- const resolution = input.source.resolution;
885
- // The input's corner on the screen, which Pixi 8 keeps to itself.
886
- const bounds = system._activeFilterData.bounds;
887
- const m = this.owner.worldTransform;
888
- const now = {
889
- width: input.frame.width,
890
- height: input.frame.height,
891
- resolution,
892
- dx: (bounds.minX - m.tx) * resolution,
893
- dy: (bounds.minY - m.ty) * resolution,
894
- colorAlpha: this.owner.groupColorAlpha,
895
- };
896
- const same = this.ran !== null && sameInput(this.ran, now);
897
- if (same && !this.stale && this.kept) {
898
- this.changing = 0;
899
- system.applyFilter(this, this.kept, output, clear);
900
- return;
901
- }
902
- // Unchanged but not kept, as after being filtered straight: kept now.
903
- this.changing = this.stale || !same ? this.changing + 1 : 0;
904
- this.stale = false;
905
- this.ran = now;
906
- this.release();
907
- if (this.changing > 1) {
908
- this.run(system, input, output, clear);
909
- return;
910
- }
911
- const kept = TexturePool.getSameSizeTexture(input);
912
- this.run(system, input, kept, true);
913
- this.kept = kept;
914
- system.applyFilter(this, kept, output, clear);
915
- }
916
- /** The filters in turn, as Pixi runs a chain, through a texture of the pool between them. */
917
- run(system, input, output, clear) {
918
- const filters = this.filters;
919
- if (filters.length === 1) {
920
- filters[0].apply(system, input, output, clear);
921
- return;
922
- }
923
- const temps = [TexturePool.getSameSizeTexture(input)];
924
- if (filters.length > 2) {
925
- temps.push(TexturePool.getSameSizeTexture(input));
926
- }
927
- let from = input;
928
- for (let i = 0; i < filters.length - 1; i++) {
929
- const to = temps[i % temps.length];
930
- filters[i].apply(system, from, to, true);
931
- from = to;
932
- }
933
- filters[filters.length - 1].apply(system, from, output, clear);
934
- for (const t of temps) {
935
- TexturePool.returnTexture(t);
936
- }
937
- }
938
- release() {
939
- if (this.kept) {
940
- TexturePool.returnTexture(this.kept);
941
- this.kept = null;
942
- }
943
- }
944
- /** Its filters too, and the output it kept. */
945
- destroy() {
946
- this.release();
947
- for (const f of this.filters) {
948
- f.destroy();
949
- }
950
- super.destroy();
951
- }
952
- }
953
- //# sourceMappingURL=pixi-filters.js.map