@lightningjs/renderer 0.6.1 → 0.7.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 (201) hide show
  1. package/dist/src/common/CommonTypes.d.ts +8 -0
  2. package/dist/src/core/CoreNode.d.ts +4 -7
  3. package/dist/src/core/CoreNode.js +73 -40
  4. package/dist/src/core/CoreNode.js.map +1 -1
  5. package/dist/src/core/CoreTextNode.d.ts +12 -2
  6. package/dist/src/core/CoreTextNode.js +46 -1
  7. package/dist/src/core/CoreTextNode.js.map +1 -1
  8. package/dist/src/core/CoreTextureManager.d.ts +3 -1
  9. package/dist/src/core/CoreTextureManager.js +4 -1
  10. package/dist/src/core/CoreTextureManager.js.map +1 -1
  11. package/dist/src/core/Stage.d.ts +6 -0
  12. package/dist/src/core/Stage.js +13 -4
  13. package/dist/src/core/Stage.js.map +1 -1
  14. package/dist/src/core/animations/CoreAnimation.d.ts +1 -0
  15. package/dist/src/core/animations/CoreAnimation.js +7 -0
  16. package/dist/src/core/animations/CoreAnimation.js.map +1 -1
  17. package/dist/src/core/lib/ImageWorker.d.ts +16 -0
  18. package/dist/src/core/lib/ImageWorker.js +111 -0
  19. package/dist/src/core/lib/ImageWorker.js.map +1 -0
  20. package/dist/src/core/lib/WebGlContextWrapper.d.ts +4 -0
  21. package/dist/src/core/lib/WebGlContextWrapper.js +7 -2
  22. package/dist/src/core/lib/WebGlContextWrapper.js.map +1 -1
  23. package/dist/src/core/lib/utils.d.ts +9 -0
  24. package/dist/src/core/lib/utils.js +48 -1
  25. package/dist/src/core/lib/utils.js.map +1 -1
  26. package/dist/src/core/renderers/CoreRenderer.d.ts +2 -2
  27. package/dist/src/core/renderers/webgl/WebGlCoreCtxSubTexture.d.ts +2 -1
  28. package/dist/src/core/renderers/webgl/WebGlCoreCtxSubTexture.js +2 -2
  29. package/dist/src/core/renderers/webgl/WebGlCoreCtxSubTexture.js.map +1 -1
  30. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.d.ts +3 -2
  31. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js +23 -21
  32. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js.map +1 -1
  33. package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.d.ts +5 -4
  34. package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.js +10 -14
  35. package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.js.map +1 -1
  36. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.d.ts +4 -1
  37. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js +30 -24
  38. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js.map +1 -1
  39. package/dist/src/core/renderers/webgl/WebGlCoreShader.d.ts +2 -1
  40. package/dist/src/core/renderers/webgl/WebGlCoreShader.js +24 -24
  41. package/dist/src/core/renderers/webgl/WebGlCoreShader.js.map +1 -1
  42. package/dist/src/core/renderers/webgl/internal/RendererUtils.d.ts +8 -5
  43. package/dist/src/core/renderers/webgl/internal/RendererUtils.js +11 -13
  44. package/dist/src/core/renderers/webgl/internal/RendererUtils.js.map +1 -1
  45. package/dist/src/core/renderers/webgl/internal/ShaderUtils.d.ts +3 -2
  46. package/dist/src/core/renderers/webgl/internal/ShaderUtils.js +15 -15
  47. package/dist/src/core/renderers/webgl/internal/ShaderUtils.js.map +1 -1
  48. package/dist/src/core/renderers/webgl/shaders/DefaultShader.js +3 -6
  49. package/dist/src/core/renderers/webgl/shaders/DefaultShader.js.map +1 -1
  50. package/dist/src/core/renderers/webgl/shaders/DefaultShaderBatched.js +3 -3
  51. package/dist/src/core/renderers/webgl/shaders/DefaultShaderBatched.js.map +1 -1
  52. package/dist/src/core/renderers/webgl/shaders/DynamicShader.d.ts +1 -0
  53. package/dist/src/core/renderers/webgl/shaders/DynamicShader.js +32 -12
  54. package/dist/src/core/renderers/webgl/shaders/DynamicShader.js.map +1 -1
  55. package/dist/src/core/renderers/webgl/shaders/RoundedRectangle.js +3 -3
  56. package/dist/src/core/renderers/webgl/shaders/RoundedRectangle.js.map +1 -1
  57. package/dist/src/core/renderers/webgl/shaders/SdfShader.js +3 -3
  58. package/dist/src/core/renderers/webgl/shaders/SdfShader.js.map +1 -1
  59. package/dist/src/core/renderers/webgl/shaders/effects/BorderEffect.js +1 -1
  60. package/dist/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.d.ts +14 -1
  61. package/dist/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.js +15 -5
  62. package/dist/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.js.map +1 -1
  63. package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.js +3 -3
  64. package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.js.map +1 -1
  65. package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.d.ts +2 -1
  66. package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.js +4 -2
  67. package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.js.map +1 -1
  68. package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.d.ts +2 -2
  69. package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.js +25 -0
  70. package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.js.map +1 -1
  71. package/dist/src/core/text-rendering/renderers/LightningTextTextureRenderer.d.ts +1 -1
  72. package/dist/src/core/text-rendering/renderers/LightningTextTextureRenderer.js +6 -6
  73. package/dist/src/core/text-rendering/renderers/LightningTextTextureRenderer.js.map +1 -1
  74. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.d.ts +8 -11
  75. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js +140 -81
  76. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js.map +1 -1
  77. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/findNearestMultiple.d.ts +8 -0
  78. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/findNearestMultiple.js +29 -0
  79. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/findNearestMultiple.js.map +1 -0
  80. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.d.ts +4 -3
  81. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.js +15 -11
  82. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.js.map +1 -1
  83. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.d.ts +3 -2
  84. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.js +30 -26
  85. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.js.map +1 -1
  86. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/SdfBufferHelper.d.ts +19 -0
  87. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/SdfBufferHelper.js +84 -0
  88. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/SdfBufferHelper.js.map +1 -0
  89. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutLine.d.ts +8 -0
  90. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutLine.js +40 -0
  91. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutLine.js.map +1 -0
  92. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutText2.d.ts +2 -0
  93. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutText2.js +41 -0
  94. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutText2.js.map +1 -0
  95. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/utils.d.ts +1 -0
  96. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/utils.js +4 -0
  97. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/utils.js.map +1 -0
  98. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2.d.ts +1 -0
  99. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2.js +2 -0
  100. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2.js.map +1 -0
  101. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/roundUpToMultiple.d.ts +9 -0
  102. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/roundUpToMultiple.js +32 -0
  103. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/roundUpToMultiple.js.map +1 -0
  104. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.d.ts +26 -0
  105. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.js +70 -0
  106. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.js.map +1 -0
  107. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.d.ts +16 -0
  108. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.js +39 -0
  109. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.js.map +1 -0
  110. package/dist/src/core/text-rendering/renderers/TextRenderer.d.ts +52 -2
  111. package/dist/src/core/text-rendering/renderers/TextRenderer.js +19 -0
  112. package/dist/src/core/text-rendering/renderers/TextRenderer.js.map +1 -1
  113. package/dist/src/core/textures/ImageTexture.js +14 -9
  114. package/dist/src/core/textures/ImageTexture.js.map +1 -1
  115. package/dist/src/core/utils.d.ts +1 -6
  116. package/dist/src/core/utils.js +3 -2
  117. package/dist/src/core/utils.js.map +1 -1
  118. package/dist/src/main-api/ICoreDriver.d.ts +2 -1
  119. package/dist/src/main-api/RendererMain.d.ts +25 -0
  120. package/dist/src/main-api/RendererMain.js +14 -5
  121. package/dist/src/main-api/RendererMain.js.map +1 -1
  122. package/dist/src/render-drivers/main/MainCoreDriver.d.ts +2 -1
  123. package/dist/src/render-drivers/main/MainCoreDriver.js +6 -4
  124. package/dist/src/render-drivers/main/MainCoreDriver.js.map +1 -1
  125. package/dist/src/render-drivers/main/MainOnlyTextNode.d.ts +10 -0
  126. package/dist/src/render-drivers/main/MainOnlyTextNode.js +45 -0
  127. package/dist/src/render-drivers/main/MainOnlyTextNode.js.map +1 -1
  128. package/dist/src/render-drivers/threadx/TextNodeStruct.d.ts +10 -0
  129. package/dist/src/render-drivers/threadx/TextNodeStruct.js +45 -0
  130. package/dist/src/render-drivers/threadx/TextNodeStruct.js.map +1 -1
  131. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.d.ts +2 -1
  132. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js +8 -1
  133. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js.map +1 -1
  134. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.d.ts +5 -0
  135. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.js +5 -0
  136. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.js.map +1 -1
  137. package/dist/src/render-drivers/threadx/ThreadXRendererMessage.d.ts +4 -1
  138. package/dist/src/render-drivers/threadx/ThreadXRendererMessage.js.map +1 -1
  139. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.d.ts +5 -0
  140. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js +10 -0
  141. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js.map +1 -1
  142. package/dist/src/render-drivers/threadx/worker/renderer.js +5 -3
  143. package/dist/src/render-drivers/threadx/worker/renderer.js.map +1 -1
  144. package/dist/src/utils.d.ts +2 -1
  145. package/dist/src/utils.js +22 -3
  146. package/dist/src/utils.js.map +1 -1
  147. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  148. package/package.json +3 -2
  149. package/src/common/CommonTypes.ts +9 -0
  150. package/src/core/CoreNode.ts +96 -62
  151. package/src/core/CoreTextNode.ts +58 -2
  152. package/src/core/CoreTextureManager.ts +4 -2
  153. package/src/core/Stage.ts +33 -4
  154. package/src/core/animations/CoreAnimation.ts +8 -0
  155. package/src/core/lib/ContextSpy.ts +41 -0
  156. package/src/core/lib/ImageWorker.ts +124 -0
  157. package/src/core/lib/WebGlContextWrapper.ts +965 -0
  158. package/src/core/lib/utils.ts +68 -1
  159. package/src/core/renderers/CoreRenderer.ts +2 -2
  160. package/src/core/renderers/webgl/WebGlCoreCtxSubTexture.ts +3 -2
  161. package/src/core/renderers/webgl/WebGlCoreCtxTexture.ts +29 -28
  162. package/src/core/renderers/webgl/WebGlCoreRenderOp.ts +13 -17
  163. package/src/core/renderers/webgl/WebGlCoreRenderer.ts +33 -25
  164. package/src/core/renderers/webgl/WebGlCoreShader.ts +34 -25
  165. package/src/core/renderers/webgl/internal/RendererUtils.ts +13 -16
  166. package/src/core/renderers/webgl/internal/ShaderUtils.ts +16 -15
  167. package/src/core/renderers/webgl/shaders/DefaultShader.ts +3 -7
  168. package/src/core/renderers/webgl/shaders/DefaultShaderBatched.ts +3 -3
  169. package/src/core/renderers/webgl/shaders/DynamicShader.ts +42 -14
  170. package/src/core/renderers/webgl/shaders/RoundedRectangle.ts +3 -3
  171. package/src/core/renderers/webgl/shaders/SdfShader.ts +3 -3
  172. package/src/core/renderers/webgl/shaders/effects/BorderEffect.ts +1 -1
  173. package/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.ts +35 -5
  174. package/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.ts +3 -3
  175. package/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.test.ts +9 -3
  176. package/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.ts +4 -2
  177. package/src/core/text-rendering/renderers/CanvasTextRenderer.ts +27 -1
  178. package/src/core/text-rendering/renderers/LightningTextTextureRenderer.ts +7 -7
  179. package/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.ts +193 -103
  180. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.ts +26 -18
  181. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.ts +40 -28
  182. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/measureText.test.ts +6 -1
  183. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.test.ts +205 -0
  184. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/{makeRenderWindow.ts → setRenderWindow.ts} +50 -21
  185. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.ts +40 -0
  186. package/src/core/text-rendering/renderers/TextRenderer.ts +75 -2
  187. package/src/core/textures/ImageTexture.ts +17 -9
  188. package/src/core/utils.ts +87 -85
  189. package/src/env.d.ts +7 -0
  190. package/src/main-api/ICoreDriver.ts +2 -1
  191. package/src/main-api/RendererMain.ts +43 -5
  192. package/src/render-drivers/main/MainCoreDriver.ts +8 -5
  193. package/src/render-drivers/main/MainOnlyTextNode.ts +55 -1
  194. package/src/render-drivers/threadx/TextNodeStruct.ts +45 -0
  195. package/src/render-drivers/threadx/ThreadXCoreDriver.ts +10 -2
  196. package/src/render-drivers/threadx/ThreadXMainTextNode.ts +10 -0
  197. package/src/render-drivers/threadx/ThreadXRendererMessage.ts +5 -1
  198. package/src/render-drivers/threadx/worker/ThreadXRendererTextNode.ts +15 -0
  199. package/src/render-drivers/threadx/worker/renderer.ts +6 -4
  200. package/src/utils.ts +25 -4
  201. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.test.ts +0 -136
package/src/core/utils.ts CHANGED
@@ -23,6 +23,8 @@
23
23
  * @module
24
24
  */
25
25
 
26
+ import memo from 'memize';
27
+
26
28
  export const EPSILON = 0.000001;
27
29
  export let ARRAY_TYPE =
28
30
  typeof Float32Array !== 'undefined' ? Float32Array : Array;
@@ -119,97 +121,97 @@ const getTimingBezier = (
119
121
  };
120
122
  };
121
123
 
122
- export const getTimingFunction = (
123
- str: string,
124
- ): ((time: number) => number | undefined) => {
125
- switch (str) {
126
- case 'linear':
127
- return function (time: number) {
128
- return time;
129
- };
130
- case 'ease':
131
- return getTimingBezier(0.25, 0.1, 0.25, 1.0);
132
-
133
- case 'ease-in':
134
- return getTimingBezier(0.42, 0, 1.0, 1.0);
135
- case 'ease-out':
136
- return getTimingBezier(0, 0, 0.58, 1.0);
137
- case 'ease-in-out':
138
- return getTimingBezier(0.42, 0, 0.58, 1.0);
139
-
140
- case 'ease-in-sine':
141
- return getTimingBezier(0.12, 0, 0.39, 0);
142
- case 'ease-out-sine':
143
- return getTimingBezier(0.12, 0, 0.39, 0);
144
- case 'ease-in-out-sine':
145
- return getTimingBezier(0.37, 0, 0.63, 1);
146
-
147
- case 'ease-in-cubic':
148
- return getTimingBezier(0.32, 0, 0.67, 0);
149
- case 'ease-out-cubic':
150
- return getTimingBezier(0.33, 1, 0.68, 1);
151
- case 'ease-in-out-cubic':
152
- return getTimingBezier(0.65, 0, 0.35, 1);
153
-
154
- case 'ease-in-circ':
155
- return getTimingBezier(0.55, 0, 1, 0.45);
156
- case 'ease-out-circ':
157
- return getTimingBezier(0, 0.55, 0.45, 1);
158
- case 'ease-in-out-circ':
159
- return getTimingBezier(0.85, 0, 0.15, 1);
160
-
161
- case 'ease-in-back':
162
- return getTimingBezier(0.36, 0, 0.66, -0.56);
163
- case 'ease-out-back':
164
- return getTimingBezier(0.34, 1.56, 0.64, 1);
165
- case 'ease-in-out-back':
166
- return getTimingBezier(0.68, -0.6, 0.32, 1.6);
167
-
168
- case 'step-start':
169
- return function () {
170
- return 1;
171
- };
172
- case 'step-end':
173
- return function (time: number) {
174
- return time === 1 ? 1 : 0;
175
- };
176
- default:
177
- // eslint-disable-next-line no-case-declarations
178
- const s = 'cubic-bezier(';
179
- if (str && str.indexOf(s) === 0) {
180
- const parts = str
181
- .substr(s.length, str.length - s.length - 1)
182
- .split(',');
183
- if (parts.length !== 4) {
124
+ export const getTimingFunction = memo(
125
+ (str: string): ((time: number) => number | undefined) => {
126
+ switch (str) {
127
+ case 'linear':
128
+ return function (time: number) {
129
+ return time;
130
+ };
131
+ case 'ease':
132
+ return getTimingBezier(0.25, 0.1, 0.25, 1.0);
133
+
134
+ case 'ease-in':
135
+ return getTimingBezier(0.42, 0, 1.0, 1.0);
136
+ case 'ease-out':
137
+ return getTimingBezier(0, 0, 0.58, 1.0);
138
+ case 'ease-in-out':
139
+ return getTimingBezier(0.42, 0, 0.58, 1.0);
140
+
141
+ case 'ease-in-sine':
142
+ return getTimingBezier(0.12, 0, 0.39, 0);
143
+ case 'ease-out-sine':
144
+ return getTimingBezier(0.12, 0, 0.39, 0);
145
+ case 'ease-in-out-sine':
146
+ return getTimingBezier(0.37, 0, 0.63, 1);
147
+
148
+ case 'ease-in-cubic':
149
+ return getTimingBezier(0.32, 0, 0.67, 0);
150
+ case 'ease-out-cubic':
151
+ return getTimingBezier(0.33, 1, 0.68, 1);
152
+ case 'ease-in-out-cubic':
153
+ return getTimingBezier(0.65, 0, 0.35, 1);
154
+
155
+ case 'ease-in-circ':
156
+ return getTimingBezier(0.55, 0, 1, 0.45);
157
+ case 'ease-out-circ':
158
+ return getTimingBezier(0, 0.55, 0.45, 1);
159
+ case 'ease-in-out-circ':
160
+ return getTimingBezier(0.85, 0, 0.15, 1);
161
+
162
+ case 'ease-in-back':
163
+ return getTimingBezier(0.36, 0, 0.66, -0.56);
164
+ case 'ease-out-back':
165
+ return getTimingBezier(0.34, 1.56, 0.64, 1);
166
+ case 'ease-in-out-back':
167
+ return getTimingBezier(0.68, -0.6, 0.32, 1.6);
168
+
169
+ case 'step-start':
170
+ return function () {
171
+ return 1;
172
+ };
173
+ case 'step-end':
174
+ return function (time: number) {
175
+ return time === 1 ? 1 : 0;
176
+ };
177
+ default:
178
+ // eslint-disable-next-line no-case-declarations
179
+ const s = 'cubic-bezier(';
180
+ if (str && str.indexOf(s) === 0) {
181
+ const parts = str
182
+ .substr(s.length, str.length - s.length - 1)
183
+ .split(',');
184
+ if (parts.length !== 4) {
185
+ console.warn('Unknown timing function: ' + str);
186
+ // Fallback: use linear.
187
+ return function (time) {
188
+ return time;
189
+ };
190
+ }
191
+ const a = parseFloat(parts[0] || '0.42');
192
+ const b = parseFloat(parts[1] || '0');
193
+ const c = parseFloat(parts[2] || '1');
194
+ const d = parseFloat(parts[3] || '1');
195
+
196
+ if (isNaN(a) || isNaN(b) || isNaN(c) || isNaN(d)) {
197
+ console.warn(' Unknown timing function: ' + str);
198
+ // Fallback: use linear.
199
+ return function (time) {
200
+ return time;
201
+ };
202
+ }
203
+
204
+ return getTimingBezier(a, b, c, d);
205
+ } else {
184
206
  console.warn('Unknown timing function: ' + str);
185
207
  // Fallback: use linear.
186
208
  return function (time) {
187
209
  return time;
188
210
  };
189
211
  }
190
- const a = parseFloat(parts[0] || '0.42');
191
- const b = parseFloat(parts[1] || '0');
192
- const c = parseFloat(parts[2] || '1');
193
- const d = parseFloat(parts[3] || '1');
194
-
195
- if (isNaN(a) || isNaN(b) || isNaN(c) || isNaN(d)) {
196
- console.warn(' Unknown timing function: ' + str);
197
- // Fallback: use linear.
198
- return function (time) {
199
- return time;
200
- };
201
- }
202
-
203
- return getTimingBezier(a, b, c, d);
204
- } else {
205
- console.warn('Unknown timing function: ' + str);
206
- // Fallback: use linear.
207
- return function (time) {
208
- return time;
209
- };
210
- }
211
- }
212
- };
212
+ }
213
+ },
214
+ );
213
215
 
214
216
  if (!Math.hypot)
215
217
  Math.hypot = (...args: number[]) => {
package/src/env.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ interface ImportMetaEnv {
2
+ readonly PROD: boolean;
3
+ }
4
+
5
+ interface ImportMeta {
6
+ readonly env: ImportMetaEnv;
7
+ }
@@ -17,6 +17,7 @@
17
17
  * limitations under the License.
18
18
  */
19
19
 
20
+ import type { FpsUpdatePayload } from '../common/CommonTypes.js';
20
21
  import type {
21
22
  INode,
22
23
  INodeWritableProps,
@@ -56,5 +57,5 @@ export interface ICoreDriver {
56
57
 
57
58
  onBeforeDestroyNode(node: INode): void;
58
59
 
59
- onFpsUpdate(fps: number): void;
60
+ onFpsUpdate(fpsData: FpsUpdatePayload): void;
60
61
  }
@@ -211,6 +211,33 @@ export interface RendererMainSettings {
211
211
  * @defaultValue `0` (disabled)
212
212
  */
213
213
  fpsUpdateInterval?: number;
214
+
215
+ /**
216
+ * Include context call (i.e. WebGL) information in FPS updates
217
+ *
218
+ * @remarks
219
+ * When enabled the number of calls to each context method over the
220
+ * `fpsUpdateInterval` will be included in the FPS update payload's
221
+ * `contextSpyData` property.
222
+ *
223
+ * Enabling the context spy has a serious impact on performance so only use it
224
+ * when you need to extract context call information.
225
+ *
226
+ * @defaultValue `false` (disabled)
227
+ */
228
+ enableContextSpy?: boolean;
229
+
230
+ /**
231
+ * Number or Image Workers to use
232
+ *
233
+ * @remarks
234
+ * On devices with multiple cores, this can be used to improve image loading
235
+ * as well as reduce the impact of image loading on the main thread.
236
+ * Set to 0 to disable image workers.
237
+ *
238
+ * @defaultValue `2`
239
+ */
240
+ numImageWorkers?: number;
214
241
  }
215
242
 
216
243
  /**
@@ -278,6 +305,9 @@ export class RendererMain extends EventEmitter {
278
305
  settings.experimental_FinalizationRegistryTextureUsageTracker ?? false,
279
306
  textureCleanupOptions: settings.textureCleanupOptions || {},
280
307
  fpsUpdateInterval: settings.fpsUpdateInterval || 0,
308
+ numImageWorkers:
309
+ settings.numImageWorkers !== undefined ? settings.numImageWorkers : 2,
310
+ enableContextSpy: settings.enableContextSpy ?? false,
281
311
  };
282
312
  this.settings = resolvedSettings;
283
313
 
@@ -335,8 +365,8 @@ export class RendererMain extends EventEmitter {
335
365
  this.nodes.delete(node.id);
336
366
  };
337
367
 
338
- driver.onFpsUpdate = (fps) => {
339
- this.emit('fpsUpdate', fps);
368
+ driver.onFpsUpdate = (fpsData) => {
369
+ this.emit('fpsUpdate', fpsData);
340
370
  };
341
371
 
342
372
  targetEl.appendChild(canvas);
@@ -389,11 +419,12 @@ export class RendererMain extends EventEmitter {
389
419
  * @returns
390
420
  */
391
421
  createTextNode(props: Partial<ITextNodeWritableProps>): ITextNode {
392
- return this.driver.createTextNode({
422
+ const fontSize = props.fontSize ?? 16;
423
+ const data = {
393
424
  ...this.resolveNodeDefaults(props),
394
425
  text: props.text ?? '',
395
426
  textRendererOverride: props.textRendererOverride ?? null,
396
- fontSize: props.fontSize ?? 16,
427
+ fontSize,
397
428
  fontFamily: props.fontFamily ?? 'sans-serif',
398
429
  fontStyle: props.fontStyle ?? 'normal',
399
430
  fontWeight: props.fontWeight ?? 'normal',
@@ -404,8 +435,15 @@ export class RendererMain extends EventEmitter {
404
435
  scrollY: props.scrollY ?? 0,
405
436
  offsetY: props.offsetY ?? 0,
406
437
  letterSpacing: props.letterSpacing ?? 0,
438
+ lineHeight: props.lineHeight ?? fontSize,
439
+ maxLines: props.maxLines ?? 0,
440
+ textBaseline: props.textBaseline ?? 'alphabetic',
441
+ verticalAlign: props.verticalAlign ?? 'top',
442
+ overflowSuffix: props.overflowSuffix ?? '...',
407
443
  debug: props.debug ?? {},
408
- });
444
+ };
445
+
446
+ return this.driver.createTextNode(data);
409
447
  }
410
448
 
411
449
  /**
@@ -25,13 +25,14 @@ import type {
25
25
  ITextNodeWritableProps,
26
26
  } from '../../main-api/INode.js';
27
27
  import { MainOnlyNode, getNewId } from './MainOnlyNode.js';
28
- import { Stage } from '../../core/Stage.js';
28
+ import { Stage, type StageFpsUpdateHandler } from '../../core/Stage.js';
29
29
  import type {
30
30
  RendererMain,
31
31
  RendererMainSettings,
32
32
  } from '../../main-api/RendererMain.js';
33
33
  import { MainOnlyTextNode } from './MainOnlyTextNode.js';
34
34
  import { loadCoreExtension } from '../utils.js';
35
+ import type { FpsUpdatePayload } from '../../common/CommonTypes.js';
35
36
 
36
37
  export class MainCoreDriver implements ICoreDriver {
37
38
  private root: MainOnlyNode | null = null;
@@ -52,6 +53,8 @@ export class MainCoreDriver implements ICoreDriver {
52
53
  clearColor: rendererSettings.clearColor,
53
54
  canvas,
54
55
  fpsUpdateInterval: rendererSettings.fpsUpdateInterval,
56
+ enableContextSpy: rendererSettings.enableContextSpy,
57
+ numImageWorkers: rendererSettings.numImageWorkers,
55
58
  debug: {
56
59
  monitorTextureCache: false,
57
60
  },
@@ -74,9 +77,9 @@ export class MainCoreDriver implements ICoreDriver {
74
77
  }
75
78
 
76
79
  // Forward fpsUpdate events from the stage to RendererMain
77
- this.stage.on('fpsUpdate', (stage: Stage, fps: number) => {
78
- this.onFpsUpdate(fps);
79
- });
80
+ this.stage.on('fpsUpdate', ((stage, fpsData) => {
81
+ this.onFpsUpdate(fpsData);
82
+ }) satisfies StageFpsUpdateHandler);
80
83
  }
81
84
 
82
85
  createNode(props: INodeWritableProps): INode {
@@ -123,7 +126,7 @@ export class MainCoreDriver implements ICoreDriver {
123
126
  throw new Error('Method not implemented.');
124
127
  }
125
128
 
126
- onFpsUpdate(fps: number) {
129
+ onFpsUpdate(fpsData: FpsUpdatePayload) {
127
130
  throw new Error('Method not implemented.');
128
131
  }
129
132
  //#endregion
@@ -81,8 +81,12 @@ export class MainOnlyTextNode extends MainOnlyNode implements ITextNode {
81
81
  scrollY: props.scrollY,
82
82
  offsetY: props.offsetY,
83
83
  textRendererOverride: props.textRendererOverride,
84
+ lineHeight: props.lineHeight,
85
+ maxLines: props.maxLines,
86
+ textBaseline: props.textBaseline,
87
+ verticalAlign: props.verticalAlign,
88
+ overflowSuffix: props.overflowSuffix,
84
89
  debug: props.debug,
85
-
86
90
  // These properties will get set appropriately in the base MainOnlyNode class
87
91
  parent: null,
88
92
  texture: null,
@@ -197,6 +201,56 @@ export class MainOnlyTextNode extends MainOnlyNode implements ITextNode {
197
201
  this.coreNode.letterSpacing = value;
198
202
  }
199
203
 
204
+ get lineHeight(): ITextNode['lineHeight'] {
205
+ return this.coreNode.lineHeight;
206
+ }
207
+
208
+ set lineHeight(value: ITextNode['lineHeight']) {
209
+ if (value) {
210
+ this.coreNode.lineHeight = value;
211
+ }
212
+ }
213
+
214
+ get maxLines(): ITextNode['maxLines'] {
215
+ return this.coreNode.maxLines;
216
+ }
217
+
218
+ set maxLines(value: ITextNode['maxLines']) {
219
+ if (value) {
220
+ this.coreNode.maxLines = value;
221
+ }
222
+ }
223
+
224
+ get textBaseline(): ITextNode['textBaseline'] {
225
+ return this.coreNode.textBaseline;
226
+ }
227
+
228
+ set textBaseline(value: ITextNode['textBaseline']) {
229
+ if (value) {
230
+ this.coreNode.textBaseline = value;
231
+ }
232
+ }
233
+
234
+ get verticalAlign(): ITextNode['verticalAlign'] {
235
+ return this.coreNode.verticalAlign;
236
+ }
237
+
238
+ set verticalAlign(value: ITextNode['verticalAlign']) {
239
+ if (value) {
240
+ this.coreNode.verticalAlign = value;
241
+ }
242
+ }
243
+
244
+ get overflowSuffix(): ITextNode['overflowSuffix'] {
245
+ return this.coreNode.overflowSuffix;
246
+ }
247
+
248
+ set overflowSuffix(value: ITextNode['overflowSuffix']) {
249
+ if (value) {
250
+ this.coreNode.overflowSuffix = value;
251
+ }
252
+ }
253
+
200
254
  get debug(): ITextNode['debug'] {
201
255
  return this.coreNode.debug;
202
256
  }
@@ -163,4 +163,49 @@ export class TextNodeStruct
163
163
  set letterSpacing(value: TextNodeStructWritableProps['letterSpacing']) {
164
164
  // Decorator will handle this
165
165
  }
166
+
167
+ @structProp('number')
168
+ get lineHeight(): TextNodeStructWritableProps['lineHeight'] {
169
+ return 0;
170
+ }
171
+
172
+ set lineHeight(value: TextNodeStructWritableProps['lineHeight']) {
173
+ // Decorator will handle this
174
+ }
175
+
176
+ @structProp('number')
177
+ get maxLines(): TextNodeStructWritableProps['maxLines'] {
178
+ return 0;
179
+ }
180
+
181
+ set maxLines(value: TextNodeStructWritableProps['maxLines']) {
182
+ // Decorator will handle this
183
+ }
184
+
185
+ @structProp('string')
186
+ get textBaseline(): TextNodeStructWritableProps['textBaseline'] {
187
+ return 'alphabetic';
188
+ }
189
+
190
+ set textBaseline(value: TextNodeStructWritableProps['textBaseline']) {
191
+ // Decorator will handle this
192
+ }
193
+
194
+ @structProp('string')
195
+ get verticalAlign(): TextNodeStructWritableProps['verticalAlign'] {
196
+ return 'middle';
197
+ }
198
+
199
+ set verticalAlign(value: TextNodeStructWritableProps['verticalAlign']) {
200
+ // Decorator will handle this
201
+ }
202
+
203
+ @structProp('string')
204
+ get overflowSuffix(): TextNodeStructWritableProps['overflowSuffix'] {
205
+ return '...';
206
+ }
207
+
208
+ set overflowSuffix(value: TextNodeStructWritableProps['overflowSuffix']) {
209
+ // Decorator will handle this
210
+ }
166
211
  }
@@ -42,6 +42,7 @@ import {
42
42
  type TextNodeStructWritableProps,
43
43
  } from './TextNodeStruct.js';
44
44
  import { ThreadXMainTextNode } from './ThreadXMainTextNode.js';
45
+ import type { FpsUpdatePayload } from '../../common/CommonTypes.js';
45
46
 
46
47
  export interface ThreadXRendererSettings {
47
48
  coreWorkerUrl: string;
@@ -79,7 +80,7 @@ export class ThreadXCoreDriver implements ICoreDriver {
79
80
  onMessage: async (message) => {
80
81
  // Forward fpsUpdate events from the renderer worker's Stage to RendererMain
81
82
  if (isThreadXRendererMessage('fpsUpdate', message)) {
82
- this.onFpsUpdate(message.fps);
83
+ this.onFpsUpdate(message.fpsData);
83
84
  }
84
85
  },
85
86
  });
@@ -108,6 +109,8 @@ export class ThreadXCoreDriver implements ICoreDriver {
108
109
  clearColor: rendererSettings.clearColor,
109
110
  coreExtensionModule: rendererSettings.coreExtensionModule,
110
111
  fpsUpdateInterval: rendererSettings.fpsUpdateInterval,
112
+ enableContextSpy: rendererSettings.enableContextSpy,
113
+ numImageWorkers: rendererSettings.numImageWorkers,
111
114
  } satisfies ThreadXRendererInitMessage,
112
115
  [offscreenCanvas],
113
116
  )) as number;
@@ -215,8 +218,13 @@ export class ThreadXCoreDriver implements ICoreDriver {
215
218
  fontWeight: props.fontWeight,
216
219
  fontStretch: props.fontStretch,
217
220
  fontStyle: props.fontStyle,
221
+ lineHeight: props.lineHeight,
222
+ maxLines: props.maxLines,
223
+ textBaseline: props.textBaseline,
224
+ verticalAlign: props.verticalAlign,
218
225
  contain: props.contain,
219
226
  letterSpacing: props.letterSpacing,
227
+ overflowSuffix: props.overflowSuffix,
220
228
  offsetY: props.offsetY,
221
229
  textAlign: props.textAlign,
222
230
  scrollable: props.scrollable,
@@ -258,7 +266,7 @@ export class ThreadXCoreDriver implements ICoreDriver {
258
266
  throw new Error('Method not implemented.');
259
267
  }
260
268
 
261
- onFpsUpdate(fps: number): void {
269
+ onFpsUpdate(fps: FpsUpdatePayload): void {
262
270
  throw new Error('Method not implemented.');
263
271
  }
264
272
  //#endregion
@@ -38,12 +38,17 @@ export class ThreadXMainTextNode extends ThreadXMainNode implements ITextNode {
38
38
  fontStretch: sharedNodeStruct.fontStretch,
39
39
  fontStyle: sharedNodeStruct.fontStyle,
40
40
  fontWeight: sharedNodeStruct.fontWeight,
41
+ lineHeight: sharedNodeStruct.lineHeight,
42
+ maxLines: sharedNodeStruct.maxLines,
43
+ textBaseline: sharedNodeStruct.textBaseline,
44
+ verticalAlign: sharedNodeStruct.verticalAlign,
41
45
  contain: sharedNodeStruct.contain,
42
46
  letterSpacing: sharedNodeStruct.letterSpacing,
43
47
  offsetY: sharedNodeStruct.offsetY,
44
48
  scrollable: sharedNodeStruct.scrollable,
45
49
  scrollY: sharedNodeStruct.scrollY,
46
50
  textAlign: sharedNodeStruct.textAlign,
51
+ overflowSuffix: sharedNodeStruct.overflowSuffix,
47
52
  } satisfies Omit<TextNodeStructWritableProps, keyof NodeStructWritableProps>);
48
53
  }
49
54
 
@@ -54,12 +59,17 @@ export class ThreadXMainTextNode extends ThreadXMainNode implements ITextNode {
54
59
  declare fontStretch: ITextNode['fontStretch'];
55
60
  declare fontStyle: ITextNode['fontStyle'];
56
61
  declare fontWeight: ITextNode['fontWeight'];
62
+ declare lineHeight: ITextNode['lineHeight'];
63
+ declare maxLines: ITextNode['maxLines'];
64
+ declare textBaseline: ITextNode['textBaseline'];
65
+ declare verticalAlign: ITextNode['verticalAlign'];
57
66
  declare textAlign: ITextNode['textAlign'];
58
67
  declare contain: ITextNode['contain'];
59
68
  declare scrollable: ITextNode['scrollable'];
60
69
  declare scrollY: ITextNode['scrollY'];
61
70
  declare offsetY: ITextNode['offsetY'];
62
71
  declare letterSpacing: ITextNode['letterSpacing'];
72
+ declare overflowSuffix: ITextNode['overflowSuffix'];
63
73
 
64
74
  get debug(): ITextNode['debug'] {
65
75
  return this._debug;
@@ -17,6 +17,8 @@
17
17
  * limitations under the License.
18
18
  */
19
19
 
20
+ import type { FpsUpdatePayload } from '../../common/CommonTypes.js';
21
+
20
22
  /**
21
23
  * @module
22
24
  * @description
@@ -43,6 +45,8 @@ export interface ThreadXRendererInitMessage extends ThreadXRendererMessage {
43
45
  devicePhysicalPixelRatio: number;
44
46
  clearColor: number;
45
47
  fpsUpdateInterval: number;
48
+ enableContextSpy: boolean;
49
+ numImageWorkers: number;
46
50
  coreExtensionModule: string | null;
47
51
  }
48
52
 
@@ -62,7 +66,7 @@ export interface ThreadXRendererReleaseTextureMessage
62
66
  export interface ThreadXRendererFpsUpdateMessage
63
67
  extends ThreadXRendererMessage {
64
68
  type: 'fpsUpdate';
65
- fps: number;
69
+ fpsData: FpsUpdatePayload;
66
70
  }
67
71
 
68
72
  /**
@@ -85,6 +85,11 @@ export class ThreadXRendererTextNode extends ThreadXRendererNode {
85
85
  fontWeight: sharedNodeStruct.fontWeight,
86
86
  fontStretch: sharedNodeStruct.fontStretch,
87
87
  fontStyle: sharedNodeStruct.fontStyle,
88
+ lineHeight: sharedNodeStruct.lineHeight,
89
+ maxLines: sharedNodeStruct.maxLines,
90
+ textBaseline: sharedNodeStruct.textBaseline,
91
+ verticalAlign: sharedNodeStruct.verticalAlign,
92
+ overflowSuffix: sharedNodeStruct.overflowSuffix,
88
93
  contain: sharedNodeStruct.contain,
89
94
  letterSpacing: sharedNodeStruct.letterSpacing,
90
95
  offsetY: sharedNodeStruct.offsetY,
@@ -101,6 +106,11 @@ export class ThreadXRendererTextNode extends ThreadXRendererNode {
101
106
  fontWeight: sharedNodeStruct.fontWeight,
102
107
  fontStretch: sharedNodeStruct.fontStretch,
103
108
  fontStyle: sharedNodeStruct.fontStyle,
109
+ lineHeight: sharedNodeStruct.lineHeight,
110
+ maxLines: sharedNodeStruct.maxLines,
111
+ textBaseline: sharedNodeStruct.textBaseline,
112
+ verticalAlign: sharedNodeStruct.verticalAlign,
113
+ overflowSuffix: sharedNodeStruct.overflowSuffix,
104
114
  contain: sharedNodeStruct.contain,
105
115
  letterSpacing: sharedNodeStruct.letterSpacing,
106
116
  offsetY: sharedNodeStruct.offsetY,
@@ -125,6 +135,11 @@ export class ThreadXRendererTextNode extends ThreadXRendererNode {
125
135
  declare fontWeight: TextNodeStructWritableProps['fontWeight'];
126
136
  declare fontStretch: TextNodeStructWritableProps['fontStretch'];
127
137
  declare fontStyle: TextNodeStructWritableProps['fontStyle'];
138
+ declare lineHeight: TextNodeStructWritableProps['lineHeight'];
139
+ declare maxLines: TextNodeStructWritableProps['maxLines'];
140
+ declare textBaseline: TextNodeStructWritableProps['textBaseline'];
141
+ declare verticalAlign: TextNodeStructWritableProps['verticalAlign'];
142
+ declare overflowSuffix: TextNodeStructWritableProps['overflowSuffix'];
128
143
  declare contain: TextNodeStructWritableProps['contain'];
129
144
  declare letterSpacing: TextNodeStructWritableProps['letterSpacing'];
130
145
  declare offsetY: TextNodeStructWritableProps['offsetY'];
@@ -20,7 +20,7 @@
20
20
  import { ThreadX, BufferStruct } from '@lightningjs/threadx';
21
21
  import { NodeStruct, type NodeStructWritableProps } from '../NodeStruct.js';
22
22
  import { ThreadXRendererNode } from './ThreadXRendererNode.js';
23
- import { Stage } from '../../../core/Stage.js';
23
+ import { Stage, type StageFpsUpdateHandler } from '../../../core/Stage.js';
24
24
  import { assertTruthy } from '../../../utils.js';
25
25
  import {
26
26
  isThreadXRendererMessage,
@@ -71,6 +71,8 @@ const threadx = ThreadX.init({
71
71
  clearColor: message.clearColor,
72
72
  canvas,
73
73
  fpsUpdateInterval: message.fpsUpdateInterval,
74
+ enableContextSpy: message.enableContextSpy,
75
+ numImageWorkers: message.numImageWorkers,
74
76
  debug: {
75
77
  monitorTextureCache: false,
76
78
  },
@@ -120,12 +122,12 @@ const threadx = ThreadX.init({
120
122
  }
121
123
 
122
124
  // Forward FPS updates to the main worker.
123
- stage.on('fpsUpdate', (stage: Stage, fps: number) => {
125
+ stage.on('fpsUpdate', ((stage, fpsData) => {
124
126
  threadx.sendMessage('parent', {
125
127
  type: 'fpsUpdate',
126
- fps,
128
+ fpsData: fpsData,
127
129
  } satisfies ThreadXRendererFpsUpdateMessage);
128
- });
130
+ }) satisfies StageFpsUpdateHandler);
129
131
 
130
132
  // Return its ID so the main worker can retrieve it from the shared object
131
133
  // store.