@lightningjs/renderer 3.0.0-beta1 → 3.0.0-beta10

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 (611) hide show
  1. package/COPYING +1 -0
  2. package/LICENSE +202 -202
  3. package/NOTICE +3 -3
  4. package/README.md +133 -147
  5. package/dist/exports/canvas.d.ts +1 -1
  6. package/dist/exports/canvas.js +1 -1
  7. package/dist/exports/canvas.js.map +1 -1
  8. package/dist/exports/index.d.ts +1 -5
  9. package/dist/exports/index.js +1 -5
  10. package/dist/exports/index.js.map +1 -1
  11. package/dist/exports/utils.d.ts +2 -1
  12. package/dist/exports/utils.js +2 -1
  13. package/dist/exports/utils.js.map +1 -1
  14. package/dist/exports/webgl.d.ts +2 -1
  15. package/dist/exports/webgl.js +2 -1
  16. package/dist/exports/webgl.js.map +1 -1
  17. package/dist/src/core/CoreNode.d.ts +45 -69
  18. package/dist/src/core/CoreNode.js +323 -305
  19. package/dist/src/core/CoreNode.js.map +1 -1
  20. package/dist/src/core/CoreShaderManager.d.ts +3 -5
  21. package/dist/src/core/CoreShaderManager.js.map +1 -1
  22. package/dist/src/core/CoreTextNode.d.ts +58 -87
  23. package/dist/src/core/CoreTextNode.js +243 -237
  24. package/dist/src/core/CoreTextNode.js.map +1 -1
  25. package/dist/src/core/CoreTextureManager.d.ts +9 -11
  26. package/dist/src/core/CoreTextureManager.js +80 -91
  27. package/dist/src/core/CoreTextureManager.js.map +1 -1
  28. package/dist/src/core/Stage.d.ts +75 -31
  29. package/dist/src/core/Stage.js +270 -136
  30. package/dist/src/core/Stage.js.map +1 -1
  31. package/dist/src/core/TextureMemoryManager.d.ts +10 -1
  32. package/dist/src/core/TextureMemoryManager.js +112 -78
  33. package/dist/src/core/TextureMemoryManager.js.map +1 -1
  34. package/dist/src/core/animations/CoreAnimation.js +5 -0
  35. package/dist/src/core/animations/CoreAnimation.js.map +1 -1
  36. package/dist/src/core/animations/CoreAnimationController.d.ts +1 -0
  37. package/dist/src/core/animations/CoreAnimationController.js +11 -4
  38. package/dist/src/core/animations/CoreAnimationController.js.map +1 -1
  39. package/dist/src/core/lib/ImageWorker.js +3 -2
  40. package/dist/src/core/lib/ImageWorker.js.map +1 -1
  41. package/dist/src/core/lib/RenderCoords.d.ts +9 -10
  42. package/dist/src/core/lib/RenderCoords.js +43 -55
  43. package/dist/src/core/lib/RenderCoords.js.map +1 -1
  44. package/dist/src/core/lib/WebGlContextWrapper.d.ts +51 -2
  45. package/dist/src/core/lib/WebGlContextWrapper.js +92 -22
  46. package/dist/src/core/lib/WebGlContextWrapper.js.map +1 -1
  47. package/dist/src/core/lib/colorCache.d.ts +1 -0
  48. package/dist/src/core/lib/colorCache.js +19 -0
  49. package/dist/src/core/lib/colorCache.js.map +1 -0
  50. package/dist/src/core/lib/colorParser.d.ts +21 -0
  51. package/dist/src/core/lib/colorParser.js +72 -0
  52. package/dist/src/core/lib/colorParser.js.map +1 -0
  53. package/dist/src/core/lib/utils.d.ts +3 -0
  54. package/dist/src/core/lib/utils.js +42 -0
  55. package/dist/src/core/lib/utils.js.map +1 -1
  56. package/dist/src/core/lib/validateImageBitmap.d.ts +2 -1
  57. package/dist/src/core/lib/validateImageBitmap.js +4 -4
  58. package/dist/src/core/lib/validateImageBitmap.js.map +1 -1
  59. package/dist/src/core/platforms/Platform.d.ts +37 -0
  60. package/dist/src/{main-api/IRenderDriver.js → core/platforms/Platform.js} +4 -2
  61. package/dist/src/core/platforms/Platform.js.map +1 -0
  62. package/dist/src/core/platforms/web/WebPlatform.d.ts +9 -0
  63. package/dist/src/core/platforms/web/WebPlatform.js +84 -0
  64. package/dist/src/core/platforms/web/WebPlatform.js.map +1 -0
  65. package/dist/src/core/renderers/CoreContextTexture.d.ts +1 -1
  66. package/dist/src/core/renderers/CoreRenderer.d.ts +5 -2
  67. package/dist/src/core/renderers/CoreRenderer.js.map +1 -1
  68. package/dist/src/core/renderers/CoreShaderNode.d.ts +3 -3
  69. package/dist/src/core/renderers/CoreShaderNode.js +8 -2
  70. package/dist/src/core/renderers/CoreShaderNode.js.map +1 -1
  71. package/dist/src/core/renderers/canvas/CanvasRenderer.d.ts +1 -2
  72. package/dist/src/core/renderers/canvas/CanvasRenderer.js +10 -21
  73. package/dist/src/core/renderers/canvas/CanvasRenderer.js.map +1 -1
  74. package/dist/src/core/renderers/canvas/CanvasShaderNode.js +3 -5
  75. package/dist/src/core/renderers/canvas/CanvasShaderNode.js.map +1 -1
  76. package/dist/src/core/renderers/canvas/CanvasTexture.d.ts +2 -2
  77. package/dist/src/core/renderers/canvas/CanvasTexture.js +11 -9
  78. package/dist/src/core/renderers/canvas/CanvasTexture.js.map +1 -1
  79. package/dist/src/core/renderers/webgl/WebGlCtxRenderTexture.js +3 -0
  80. package/dist/src/core/renderers/webgl/WebGlCtxRenderTexture.js.map +1 -1
  81. package/dist/src/core/renderers/webgl/WebGlCtxTexture.d.ts +5 -6
  82. package/dist/src/core/renderers/webgl/WebGlCtxTexture.js +30 -21
  83. package/dist/src/core/renderers/webgl/WebGlCtxTexture.js.map +1 -1
  84. package/dist/src/core/renderers/webgl/WebGlRenderOp.d.ts +10 -2
  85. package/dist/src/core/renderers/webgl/WebGlRenderOp.js +37 -19
  86. package/dist/src/core/renderers/webgl/WebGlRenderOp.js.map +1 -1
  87. package/dist/src/core/renderers/webgl/WebGlRenderer.d.ts +5 -3
  88. package/dist/src/core/renderers/webgl/WebGlRenderer.js +144 -117
  89. package/dist/src/core/renderers/webgl/WebGlRenderer.js.map +1 -1
  90. package/dist/src/core/renderers/webgl/WebGlShaderNode.d.ts +2 -1
  91. package/dist/src/core/renderers/webgl/WebGlShaderNode.js +1 -4
  92. package/dist/src/core/renderers/webgl/WebGlShaderNode.js.map +1 -1
  93. package/dist/src/core/renderers/webgl/WebGlShaderProgram.d.ts +5 -3
  94. package/dist/src/core/renderers/webgl/WebGlShaderProgram.js +55 -31
  95. package/dist/src/core/renderers/webgl/WebGlShaderProgram.js.map +1 -1
  96. package/dist/src/core/renderers/webgl/internal/ShaderUtils.js +35 -35
  97. package/dist/src/core/shaders/canvas/Border.js +1 -1
  98. package/dist/src/core/shaders/canvas/Border.js.map +1 -1
  99. package/dist/src/core/shaders/canvas/LinearGradient.js +5 -3
  100. package/dist/src/core/shaders/canvas/LinearGradient.js.map +1 -1
  101. package/dist/src/core/shaders/canvas/RadialGradient.js +13 -11
  102. package/dist/src/core/shaders/canvas/RadialGradient.js.map +1 -1
  103. package/dist/src/core/shaders/canvas/RoundedWithBorder.js +14 -6
  104. package/dist/src/core/shaders/canvas/RoundedWithBorder.js.map +1 -1
  105. package/dist/src/core/shaders/canvas/RoundedWithBorderAndShadow.js +10 -8
  106. package/dist/src/core/shaders/canvas/RoundedWithBorderAndShadow.js.map +1 -1
  107. package/dist/src/core/shaders/canvas/RoundedWithShadow.js +7 -5
  108. package/dist/src/core/shaders/canvas/RoundedWithShadow.js.map +1 -1
  109. package/dist/src/core/shaders/templates/BorderTemplate.d.ts +1 -1
  110. package/dist/src/core/shaders/templates/BorderTemplate.js +1 -1
  111. package/dist/src/core/shaders/templates/BorderTemplate.js.map +1 -1
  112. package/dist/src/core/shaders/templates/HolePunchTemplate.js +1 -1
  113. package/dist/src/core/shaders/templates/HolePunchTemplate.js.map +1 -1
  114. package/dist/src/core/shaders/templates/RoundedTemplate.js +1 -1
  115. package/dist/src/core/shaders/templates/RoundedTemplate.js.map +1 -1
  116. package/dist/src/core/shaders/templates/RoundedWithBorderAndShadowTemplate.d.ts +1 -1
  117. package/dist/src/core/shaders/templates/RoundedWithBorderTemplate.d.ts +1 -1
  118. package/dist/src/core/shaders/templates/RoundedWithShadowTemplate.d.ts +1 -1
  119. package/dist/src/core/shaders/templates/ShadowTemplate.d.ts +1 -1
  120. package/dist/src/core/shaders/{templates/shaderUtils.d.ts → utils.d.ts} +1 -1
  121. package/dist/src/core/shaders/{templates/shaderUtils.js → utils.js} +2 -2
  122. package/dist/src/core/shaders/utils.js.map +1 -0
  123. package/dist/src/core/shaders/webgl/Border.js +86 -63
  124. package/dist/src/core/shaders/webgl/Border.js.map +1 -1
  125. package/dist/src/core/shaders/webgl/Default.js +47 -47
  126. package/dist/src/core/shaders/webgl/DefaultBatched.js +61 -61
  127. package/dist/src/core/shaders/webgl/HolePunch.js +36 -35
  128. package/dist/src/core/shaders/webgl/HolePunch.js.map +1 -1
  129. package/dist/src/core/shaders/webgl/LinearGradient.js +41 -40
  130. package/dist/src/core/shaders/webgl/LinearGradient.js.map +1 -1
  131. package/dist/src/core/shaders/webgl/RadialGradient.js +39 -38
  132. package/dist/src/core/shaders/webgl/RadialGradient.js.map +1 -1
  133. package/dist/src/core/shaders/webgl/Rounded.js +71 -71
  134. package/dist/src/core/shaders/webgl/RoundedWithBorder.js +115 -72
  135. package/dist/src/core/shaders/webgl/RoundedWithBorder.js.map +1 -1
  136. package/dist/src/core/shaders/webgl/RoundedWithBorderAndShadow.js +138 -88
  137. package/dist/src/core/shaders/webgl/RoundedWithBorderAndShadow.js.map +1 -1
  138. package/dist/src/core/shaders/webgl/RoundedWithShadow.js +54 -54
  139. package/dist/src/core/shaders/webgl/SdfShader.js +63 -63
  140. package/dist/src/core/shaders/webgl/SdfShader.js.map +1 -1
  141. package/dist/src/core/shaders/webgl/Shadow.js +83 -83
  142. package/dist/src/core/text-rendering/CanvasFontHandler.d.ts +25 -0
  143. package/dist/src/core/text-rendering/CanvasFontHandler.js +130 -0
  144. package/dist/src/core/text-rendering/CanvasFontHandler.js.map +1 -0
  145. package/dist/src/core/text-rendering/CanvasTextRenderer.d.ts +22 -0
  146. package/dist/src/core/text-rendering/CanvasTextRenderer.js +366 -0
  147. package/dist/src/core/text-rendering/CanvasTextRenderer.js.map +1 -0
  148. package/dist/src/core/text-rendering/SdfFontHandler.d.ts +137 -0
  149. package/dist/src/core/text-rendering/SdfFontHandler.js +336 -0
  150. package/dist/src/core/text-rendering/SdfFontHandler.js.map +1 -0
  151. package/dist/src/core/text-rendering/SdfTextRenderer.d.ts +17 -0
  152. package/dist/src/core/text-rendering/SdfTextRenderer.js +355 -0
  153. package/dist/src/core/text-rendering/SdfTextRenderer.js.map +1 -0
  154. package/dist/src/core/text-rendering/TextRenderer.d.ts +349 -0
  155. package/dist/src/{main-api/ICoreDriver.js → core/text-rendering/TextRenderer.js} +1 -1
  156. package/dist/src/core/text-rendering/TextRenderer.js.map +1 -0
  157. package/dist/src/core/text-rendering/Utils.d.ts +71 -0
  158. package/dist/src/core/text-rendering/Utils.js +212 -0
  159. package/dist/src/core/text-rendering/Utils.js.map +1 -0
  160. package/dist/src/core/text-rendering/canvas/Settings.d.ts +64 -0
  161. package/dist/src/core/{renderers/CoreShader.js → text-rendering/canvas/Settings.js} +3 -11
  162. package/dist/src/core/text-rendering/canvas/Settings.js.map +1 -0
  163. package/dist/src/core/text-rendering/canvas/Utils.d.ts +20 -0
  164. package/dist/src/core/text-rendering/canvas/Utils.js +144 -0
  165. package/dist/src/core/text-rendering/canvas/Utils.js.map +1 -0
  166. package/dist/src/core/text-rendering/canvas/calculateRenderInfo.d.ts +60 -0
  167. package/dist/src/core/text-rendering/canvas/calculateRenderInfo.js +183 -0
  168. package/dist/src/core/text-rendering/canvas/calculateRenderInfo.js.map +1 -0
  169. package/dist/src/core/text-rendering/canvas/draw.d.ts +5 -0
  170. package/dist/src/core/text-rendering/canvas/draw.js +132 -0
  171. package/dist/src/core/text-rendering/canvas/draw.js.map +1 -0
  172. package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.js +5 -0
  173. package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.js.map +1 -1
  174. package/dist/src/core/text-rendering/renderers/LightningTextTextureRenderer.d.ts +1 -1
  175. package/dist/src/core/text-rendering/renderers/LightningTextTextureRenderer.js +50 -2
  176. package/dist/src/core/text-rendering/renderers/LightningTextTextureRenderer.js.map +1 -1
  177. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js +9 -54
  178. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js.map +1 -1
  179. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.d.ts +1 -1
  180. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.js +66 -8
  181. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.js.map +1 -1
  182. package/dist/src/core/text-rendering/renderers/TextRenderer.d.ts +13 -0
  183. package/dist/src/core/text-rendering/renderers/TextRenderer.js +3 -0
  184. package/dist/src/core/text-rendering/renderers/TextRenderer.js.map +1 -1
  185. package/dist/src/core/text-rendering/sdf/Utils.d.ts +26 -0
  186. package/dist/src/core/text-rendering/sdf/Utils.js +304 -0
  187. package/dist/src/core/text-rendering/sdf/Utils.js.map +1 -0
  188. package/dist/src/core/text-rendering/sdf/index.d.ts +1 -0
  189. package/dist/src/{main-api/texture-usage-trackers/TextureUsageTracker.js → core/text-rendering/sdf/index.js} +3 -11
  190. package/dist/src/core/text-rendering/sdf/index.js.map +1 -0
  191. package/dist/src/core/textures/ImageTexture.d.ts +4 -3
  192. package/dist/src/core/textures/ImageTexture.js +36 -9
  193. package/dist/src/core/textures/ImageTexture.js.map +1 -1
  194. package/dist/src/core/textures/Texture.d.ts +21 -2
  195. package/dist/src/core/textures/Texture.js +37 -6
  196. package/dist/src/core/textures/Texture.js.map +1 -1
  197. package/dist/src/core/utils.d.ts +1 -1
  198. package/dist/src/main-api/INode.d.ts +2 -2
  199. package/dist/src/main-api/Inspector.d.ts +6 -1
  200. package/dist/src/main-api/Inspector.js +43 -7
  201. package/dist/src/main-api/Inspector.js.map +1 -1
  202. package/dist/src/main-api/Renderer.d.ts +122 -46
  203. package/dist/src/main-api/Renderer.js +174 -37
  204. package/dist/src/main-api/Renderer.js.map +1 -1
  205. package/dist/src/utils.d.ts +1 -6
  206. package/dist/src/utils.js +2 -9
  207. package/dist/src/utils.js.map +1 -1
  208. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  209. package/exports/canvas-shaders.ts +28 -28
  210. package/exports/canvas.ts +45 -45
  211. package/exports/index.ts +82 -89
  212. package/exports/inspector.ts +24 -24
  213. package/exports/utils.ts +50 -44
  214. package/exports/webgl-shaders.ts +28 -28
  215. package/exports/webgl.ts +52 -50
  216. package/package.json +2 -4
  217. package/src/common/CommonTypes.ts +146 -146
  218. package/src/common/EventEmitter.ts +77 -77
  219. package/src/common/IAnimationController.ts +92 -92
  220. package/src/common/IEventEmitter.ts +28 -28
  221. package/src/core/CoreNode.test.ts +202 -203
  222. package/src/core/CoreNode.ts +2491 -2476
  223. package/src/core/CoreShaderManager.ts +188 -193
  224. package/src/core/CoreTextNode.ts +443 -448
  225. package/src/core/CoreTextureManager.ts +565 -597
  226. package/src/core/Stage.ts +906 -740
  227. package/src/core/TextureMemoryManager.ts +445 -395
  228. package/src/core/animations/AnimationManager.ts +38 -38
  229. package/src/core/animations/CoreAnimation.ts +291 -284
  230. package/src/core/animations/CoreAnimationController.ts +166 -157
  231. package/src/core/lib/ContextSpy.ts +41 -41
  232. package/src/core/lib/ImageWorker.ts +286 -279
  233. package/src/core/lib/Matrix3d.ts +244 -244
  234. package/src/core/lib/RenderCoords.ts +71 -86
  235. package/src/core/lib/WebGlContextWrapper.ts +1381 -1324
  236. package/src/core/lib/colorCache.ts +20 -0
  237. package/src/core/{renderers/canvas/internal/ColorUtils.ts → lib/colorParser.ts} +85 -85
  238. package/src/core/lib/textureCompression.ts +152 -152
  239. package/src/core/lib/textureSvg.ts +78 -78
  240. package/src/core/lib/utils.ts +412 -361
  241. package/src/core/lib/validateImageBitmap.ts +87 -76
  242. package/src/core/platforms/Platform.ts +77 -0
  243. package/src/core/platforms/web/WebPlatform.ts +121 -0
  244. package/src/core/renderers/CoreContextTexture.ts +43 -43
  245. package/src/core/renderers/CoreRenderOp.ts +22 -22
  246. package/src/core/renderers/CoreRenderer.ts +110 -107
  247. package/src/core/renderers/CoreShaderNode.ts +175 -171
  248. package/src/core/renderers/CoreShaderProgram.ts +23 -23
  249. package/src/core/renderers/canvas/CanvasRenderer.ts +283 -299
  250. package/src/core/renderers/canvas/CanvasShaderNode.ts +96 -99
  251. package/src/core/renderers/canvas/CanvasTexture.ts +156 -153
  252. package/src/core/renderers/webgl/WebGlCtxRenderTexture.ts +91 -86
  253. package/src/core/renderers/webgl/WebGlCtxSubTexture.ts +50 -50
  254. package/src/core/renderers/webgl/WebGlCtxTexture.ts +310 -301
  255. package/src/core/renderers/webgl/WebGlRenderOp.ts +167 -145
  256. package/src/core/renderers/webgl/WebGlRenderer.ts +747 -715
  257. package/src/core/renderers/webgl/WebGlShaderNode.ts +435 -433
  258. package/src/core/renderers/webgl/WebGlShaderProgram.ts +341 -310
  259. package/src/core/renderers/webgl/internal/BufferCollection.ts +54 -54
  260. package/src/core/renderers/webgl/internal/RendererUtils.ts +155 -155
  261. package/src/core/renderers/webgl/internal/ShaderUtils.ts +281 -281
  262. package/src/core/renderers/webgl/internal/WebGlUtils.ts +35 -35
  263. package/src/core/shaders/canvas/Border.ts +75 -78
  264. package/src/core/shaders/canvas/HolePunch.ts +62 -62
  265. package/src/core/shaders/canvas/LinearGradient.ts +71 -69
  266. package/src/core/shaders/canvas/RadialGradient.ts +99 -113
  267. package/src/core/shaders/canvas/Rounded.ts +55 -55
  268. package/src/core/shaders/canvas/RoundedWithBorder.ts +74 -68
  269. package/src/core/shaders/canvas/RoundedWithBorderAndShadow.ts +90 -88
  270. package/src/core/shaders/canvas/RoundedWithShadow.ts +70 -69
  271. package/src/core/shaders/canvas/Shadow.ts +52 -52
  272. package/src/core/shaders/canvas/utils/render.ts +151 -151
  273. package/src/core/shaders/templates/BorderTemplate.ts +115 -115
  274. package/src/core/shaders/templates/HolePunchTemplate.ts +82 -82
  275. package/src/core/shaders/templates/LinearGradientTemplate.ts +71 -71
  276. package/src/core/shaders/templates/RadialGradientTemplate.ts +81 -81
  277. package/src/core/shaders/templates/RoundedTemplate.ts +98 -98
  278. package/src/core/shaders/templates/RoundedWithBorderAndShadowTemplate.ts +38 -38
  279. package/src/core/shaders/templates/RoundedWithBorderTemplate.ts +35 -35
  280. package/src/core/shaders/templates/RoundedWithShadowTemplate.ts +35 -35
  281. package/src/core/shaders/templates/ShadowTemplate.ts +106 -106
  282. package/src/core/shaders/{templates/shaderUtils.ts → utils.ts} +46 -47
  283. package/src/core/shaders/webgl/Border.ts +116 -96
  284. package/src/core/shaders/webgl/Default.ts +89 -89
  285. package/src/core/shaders/webgl/DefaultBatched.ts +129 -129
  286. package/src/core/shaders/webgl/HolePunch.ts +75 -78
  287. package/src/core/shaders/webgl/LinearGradient.ts +82 -81
  288. package/src/core/shaders/webgl/RadialGradient.ts +85 -84
  289. package/src/core/shaders/webgl/Rounded.ts +117 -117
  290. package/src/core/shaders/webgl/RoundedWithBorder.ts +155 -114
  291. package/src/core/shaders/webgl/RoundedWithBorderAndShadow.ts +175 -133
  292. package/src/core/shaders/webgl/RoundedWithShadow.ts +98 -98
  293. package/src/core/shaders/webgl/SdfShader.ts +134 -137
  294. package/src/core/shaders/webgl/Shadow.ts +115 -115
  295. package/src/core/text-rendering/CanvasFontHandler.ts +176 -0
  296. package/src/core/text-rendering/CanvasTextRenderer.ts +622 -0
  297. package/src/core/text-rendering/SdfFontHandler.ts +517 -0
  298. package/src/core/text-rendering/SdfTextRenderer.ts +466 -0
  299. package/src/core/text-rendering/TextRenderer.ts +404 -0
  300. package/src/core/text-rendering/{TextTextureRendererUtils.ts → Utils.ts} +257 -263
  301. package/src/core/text-rendering/canvas/Settings.ts +99 -0
  302. package/src/core/text-rendering/canvas/Utils.test.ts +206 -0
  303. package/src/core/text-rendering/canvas/Utils.ts +178 -0
  304. package/src/core/text-rendering/canvas/calculateRenderInfo.ts +299 -0
  305. package/src/core/text-rendering/canvas/draw.ts +165 -0
  306. package/src/core/text-rendering/sdf/Utils.test.ts +402 -0
  307. package/src/core/text-rendering/sdf/Utils.ts +436 -0
  308. package/src/core/text-rendering/sdf/index.ts +20 -0
  309. package/src/core/textures/ColorTexture.ts +102 -102
  310. package/src/core/textures/ImageTexture.ts +418 -376
  311. package/src/core/textures/NoiseTexture.ts +104 -104
  312. package/src/core/textures/RenderTexture.ts +85 -85
  313. package/src/core/textures/SubTexture.ts +205 -205
  314. package/src/core/textures/Texture.ts +381 -337
  315. package/src/core/utils.ts +227 -227
  316. package/src/env.d.ts +7 -7
  317. package/src/main-api/INode.ts +100 -99
  318. package/src/main-api/Inspector.ts +567 -522
  319. package/src/main-api/Renderer.ts +873 -649
  320. package/src/main-api/utils.ts +45 -45
  321. package/src/utils.ts +267 -267
  322. package/dist/exports/core-api.d.ts +0 -74
  323. package/dist/exports/core-api.js +0 -96
  324. package/dist/exports/core-api.js.map +0 -1
  325. package/dist/exports/main-api.d.ts +0 -30
  326. package/dist/exports/main-api.js +0 -45
  327. package/dist/exports/main-api.js.map +0 -1
  328. package/dist/src/core/CoreExtension.d.ts +0 -12
  329. package/dist/src/core/CoreExtension.js +0 -29
  330. package/dist/src/core/CoreExtension.js.map +0 -1
  331. package/dist/src/core/CoreStuff.d.ts +0 -1
  332. package/dist/src/core/CoreStuff.js +0 -138
  333. package/dist/src/core/CoreStuff.js.map +0 -1
  334. package/dist/src/core/CoreTexturizer.d.ts +0 -14
  335. package/dist/src/core/CoreTexturizer.js +0 -47
  336. package/dist/src/core/CoreTexturizer.js.map +0 -1
  337. package/dist/src/core/LngNode.d.ts +0 -736
  338. package/dist/src/core/LngNode.js +0 -1174
  339. package/dist/src/core/LngNode.js.map +0 -1
  340. package/dist/src/core/Matrix2DContext.d.ts +0 -15
  341. package/dist/src/core/Matrix2DContext.js +0 -45
  342. package/dist/src/core/Matrix2DContext.js.map +0 -1
  343. package/dist/src/core/ShaderNode.d.ts +0 -10
  344. package/dist/src/core/ShaderNode.js +0 -30
  345. package/dist/src/core/ShaderNode.js.map +0 -1
  346. package/dist/src/core/TextNode.d.ts +0 -103
  347. package/dist/src/core/TextNode.js +0 -331
  348. package/dist/src/core/TextNode.js.map +0 -1
  349. package/dist/src/core/lib/Coords.d.ts +0 -14
  350. package/dist/src/core/lib/Coords.js +0 -55
  351. package/dist/src/core/lib/Coords.js.map +0 -1
  352. package/dist/src/core/lib/glm/common.d.ts +0 -162
  353. package/dist/src/core/lib/glm/common.js +0 -81
  354. package/dist/src/core/lib/glm/common.js.map +0 -1
  355. package/dist/src/core/lib/glm/index.d.ts +0 -11
  356. package/dist/src/core/lib/glm/index.js +0 -30
  357. package/dist/src/core/lib/glm/index.js.map +0 -1
  358. package/dist/src/core/lib/glm/mat2.d.ts +0 -219
  359. package/dist/src/core/lib/glm/mat2.js +0 -396
  360. package/dist/src/core/lib/glm/mat2.js.map +0 -1
  361. package/dist/src/core/lib/glm/mat2d.d.ts +0 -237
  362. package/dist/src/core/lib/glm/mat2d.js +0 -442
  363. package/dist/src/core/lib/glm/mat2d.js.map +0 -1
  364. package/dist/src/core/lib/glm/mat3.d.ts +0 -283
  365. package/dist/src/core/lib/glm/mat3.js +0 -680
  366. package/dist/src/core/lib/glm/mat3.js.map +0 -1
  367. package/dist/src/core/lib/glm/mat4.d.ts +0 -550
  368. package/dist/src/core/lib/glm/mat4.js +0 -1802
  369. package/dist/src/core/lib/glm/mat4.js.map +0 -1
  370. package/dist/src/core/lib/glm/quat.d.ts +0 -363
  371. package/dist/src/core/lib/glm/quat.js +0 -693
  372. package/dist/src/core/lib/glm/quat.js.map +0 -1
  373. package/dist/src/core/lib/glm/quat2.d.ts +0 -356
  374. package/dist/src/core/lib/glm/quat2.js +0 -754
  375. package/dist/src/core/lib/glm/quat2.js.map +0 -1
  376. package/dist/src/core/lib/glm/vec2.d.ts +0 -365
  377. package/dist/src/core/lib/glm/vec2.js +0 -569
  378. package/dist/src/core/lib/glm/vec2.js.map +0 -1
  379. package/dist/src/core/lib/glm/vec3.d.ts +0 -406
  380. package/dist/src/core/lib/glm/vec3.js +0 -720
  381. package/dist/src/core/lib/glm/vec3.js.map +0 -1
  382. package/dist/src/core/lib/glm/vec4.d.ts +0 -330
  383. package/dist/src/core/lib/glm/vec4.js +0 -608
  384. package/dist/src/core/lib/glm/vec4.js.map +0 -1
  385. package/dist/src/core/platform.d.ts +0 -10
  386. package/dist/src/core/platform.js +0 -56
  387. package/dist/src/core/platform.js.map +0 -1
  388. package/dist/src/core/renderers/CoreShader.d.ts +0 -9
  389. package/dist/src/core/renderers/CoreShader.js.map +0 -1
  390. package/dist/src/core/renderers/CoreShaderManager.d.ts +0 -19
  391. package/dist/src/core/renderers/CoreShaderManager.js +0 -33
  392. package/dist/src/core/renderers/CoreShaderManager.js.map +0 -1
  393. package/dist/src/core/renderers/canvas/CanvasCoreRenderer.d.ts +0 -33
  394. package/dist/src/core/renderers/canvas/CanvasCoreRenderer.js +0 -250
  395. package/dist/src/core/renderers/canvas/CanvasCoreRenderer.js.map +0 -1
  396. package/dist/src/core/renderers/canvas/CanvasCoreTexture.d.ts +0 -16
  397. package/dist/src/core/renderers/canvas/CanvasCoreTexture.js +0 -123
  398. package/dist/src/core/renderers/canvas/CanvasCoreTexture.js.map +0 -1
  399. package/dist/src/core/renderers/canvas/shaders/UnsupportedShader.d.ts +0 -10
  400. package/dist/src/core/renderers/canvas/shaders/UnsupportedShader.js +0 -43
  401. package/dist/src/core/renderers/canvas/shaders/UnsupportedShader.js.map +0 -1
  402. package/dist/src/core/renderers/webgl/WebGlCoreCtxRenderTexture.d.ts +0 -12
  403. package/dist/src/core/renderers/webgl/WebGlCoreCtxRenderTexture.js +0 -55
  404. package/dist/src/core/renderers/webgl/WebGlCoreCtxRenderTexture.js.map +0 -1
  405. package/dist/src/core/renderers/webgl/WebGlCoreCtxSubTexture.d.ts +0 -9
  406. package/dist/src/core/renderers/webgl/WebGlCoreCtxSubTexture.js +0 -38
  407. package/dist/src/core/renderers/webgl/WebGlCoreCtxSubTexture.js.map +0 -1
  408. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.d.ts +0 -57
  409. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js +0 -227
  410. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js.map +0 -1
  411. package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.d.ts +0 -34
  412. package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.js +0 -114
  413. package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.js.map +0 -1
  414. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.d.ts +0 -133
  415. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js +0 -613
  416. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js.map +0 -1
  417. package/dist/src/core/renderers/webgl/WebGlCoreShader.d.ts +0 -83
  418. package/dist/src/core/renderers/webgl/WebGlCoreShader.js +0 -231
  419. package/dist/src/core/renderers/webgl/WebGlCoreShader.js.map +0 -1
  420. package/dist/src/core/renderers/webgl/WebGlCoreShaderManager.d.ts +0 -27
  421. package/dist/src/core/renderers/webgl/WebGlCoreShaderManager.js +0 -82
  422. package/dist/src/core/renderers/webgl/WebGlCoreShaderManager.js.map +0 -1
  423. package/dist/src/core/renderers/webgl/WebGlCoreShaderProgram.d.ts +0 -11
  424. package/dist/src/core/renderers/webgl/WebGlCoreShaderProgram.js +0 -34
  425. package/dist/src/core/renderers/webgl/WebGlCoreShaderProgram.js.map +0 -1
  426. package/dist/src/core/renderers/webgl/shaders/DefaultShader.d.ts +0 -9
  427. package/dist/src/core/renderers/webgl/shaders/DefaultShader.js +0 -87
  428. package/dist/src/core/renderers/webgl/shaders/DefaultShader.js.map +0 -1
  429. package/dist/src/core/renderers/webgl/shaders/DefaultShaderBatched.d.ts +0 -10
  430. package/dist/src/core/renderers/webgl/shaders/DefaultShaderBatched.js +0 -119
  431. package/dist/src/core/renderers/webgl/shaders/DefaultShaderBatched.js.map +0 -1
  432. package/dist/src/core/renderers/webgl/shaders/DynamicShader.d.ts +0 -29
  433. package/dist/src/core/renderers/webgl/shaders/DynamicShader.js +0 -413
  434. package/dist/src/core/renderers/webgl/shaders/DynamicShader.js.map +0 -1
  435. package/dist/src/core/renderers/webgl/shaders/RoundedRectangle.d.ts +0 -28
  436. package/dist/src/core/renderers/webgl/shaders/RoundedRectangle.js +0 -131
  437. package/dist/src/core/renderers/webgl/shaders/RoundedRectangle.js.map +0 -1
  438. package/dist/src/core/renderers/webgl/shaders/SdfShader.d.ts +0 -47
  439. package/dist/src/core/renderers/webgl/shaders/SdfShader.js +0 -160
  440. package/dist/src/core/renderers/webgl/shaders/SdfShader.js.map +0 -1
  441. package/dist/src/core/renderers/webgl/shaders/effects/BorderBottomEffect.d.ts +0 -31
  442. package/dist/src/core/renderers/webgl/shaders/effects/BorderBottomEffect.js +0 -71
  443. package/dist/src/core/renderers/webgl/shaders/effects/BorderBottomEffect.js.map +0 -1
  444. package/dist/src/core/renderers/webgl/shaders/effects/BorderEffect.d.ts +0 -30
  445. package/dist/src/core/renderers/webgl/shaders/effects/BorderEffect.js +0 -58
  446. package/dist/src/core/renderers/webgl/shaders/effects/BorderEffect.js.map +0 -1
  447. package/dist/src/core/renderers/webgl/shaders/effects/BorderLeftEffect.d.ts +0 -31
  448. package/dist/src/core/renderers/webgl/shaders/effects/BorderLeftEffect.js +0 -71
  449. package/dist/src/core/renderers/webgl/shaders/effects/BorderLeftEffect.js.map +0 -1
  450. package/dist/src/core/renderers/webgl/shaders/effects/BorderRightEffect.d.ts +0 -31
  451. package/dist/src/core/renderers/webgl/shaders/effects/BorderRightEffect.js +0 -71
  452. package/dist/src/core/renderers/webgl/shaders/effects/BorderRightEffect.js.map +0 -1
  453. package/dist/src/core/renderers/webgl/shaders/effects/BorderTopEffect.d.ts +0 -31
  454. package/dist/src/core/renderers/webgl/shaders/effects/BorderTopEffect.js +0 -71
  455. package/dist/src/core/renderers/webgl/shaders/effects/BorderTopEffect.js.map +0 -1
  456. package/dist/src/core/renderers/webgl/shaders/effects/EffectUtils.d.ts +0 -9
  457. package/dist/src/core/renderers/webgl/shaders/effects/EffectUtils.js +0 -136
  458. package/dist/src/core/renderers/webgl/shaders/effects/EffectUtils.js.map +0 -1
  459. package/dist/src/core/renderers/webgl/shaders/effects/FadeOutEffect.d.ts +0 -36
  460. package/dist/src/core/renderers/webgl/shaders/effects/FadeOutEffect.js +0 -85
  461. package/dist/src/core/renderers/webgl/shaders/effects/FadeOutEffect.js.map +0 -1
  462. package/dist/src/core/renderers/webgl/shaders/effects/GlitchEffect.d.ts +0 -45
  463. package/dist/src/core/renderers/webgl/shaders/effects/GlitchEffect.js +0 -104
  464. package/dist/src/core/renderers/webgl/shaders/effects/GlitchEffect.js.map +0 -1
  465. package/dist/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.d.ts +0 -22
  466. package/dist/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.js +0 -45
  467. package/dist/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.js.map +0 -1
  468. package/dist/src/core/renderers/webgl/shaders/effects/HolePunchEffect.d.ts +0 -58
  469. package/dist/src/core/renderers/webgl/shaders/effects/HolePunchEffect.js +0 -80
  470. package/dist/src/core/renderers/webgl/shaders/effects/HolePunchEffect.js.map +0 -1
  471. package/dist/src/core/renderers/webgl/shaders/effects/LinearGradientEffect.d.ts +0 -35
  472. package/dist/src/core/renderers/webgl/shaders/effects/LinearGradientEffect.js +0 -129
  473. package/dist/src/core/renderers/webgl/shaders/effects/LinearGradientEffect.js.map +0 -1
  474. package/dist/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.d.ts +0 -39
  475. package/dist/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.js +0 -116
  476. package/dist/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.js.map +0 -1
  477. package/dist/src/core/renderers/webgl/shaders/effects/RadialProgressEffect.d.ts +0 -61
  478. package/dist/src/core/renderers/webgl/shaders/effects/RadialProgressEffect.js +0 -127
  479. package/dist/src/core/renderers/webgl/shaders/effects/RadialProgressEffect.js.map +0 -1
  480. package/dist/src/core/renderers/webgl/shaders/effects/RadiusEffect.d.ts +0 -40
  481. package/dist/src/core/renderers/webgl/shaders/effects/RadiusEffect.js +0 -71
  482. package/dist/src/core/renderers/webgl/shaders/effects/RadiusEffect.js.map +0 -1
  483. package/dist/src/core/renderers/webgl/shaders/effects/ShaderEffect.d.ts +0 -115
  484. package/dist/src/core/renderers/webgl/shaders/effects/ShaderEffect.js +0 -61
  485. package/dist/src/core/renderers/webgl/shaders/effects/ShaderEffect.js.map +0 -1
  486. package/dist/src/core/scene/Scene.d.ts +0 -59
  487. package/dist/src/core/scene/Scene.js +0 -106
  488. package/dist/src/core/scene/Scene.js.map +0 -1
  489. package/dist/src/core/shaders/templates/shaderUtils.js.map +0 -1
  490. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.d.ts +0 -20
  491. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.js +0 -55
  492. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.js.map +0 -1
  493. package/dist/src/main-api/DynamicShaderController.d.ts +0 -29
  494. package/dist/src/main-api/DynamicShaderController.js +0 -58
  495. package/dist/src/main-api/DynamicShaderController.js.map +0 -1
  496. package/dist/src/main-api/ICoreDriver.d.ts +0 -27
  497. package/dist/src/main-api/ICoreDriver.js.map +0 -1
  498. package/dist/src/main-api/IRenderDriver.d.ts +0 -20
  499. package/dist/src/main-api/IRenderDriver.js.map +0 -1
  500. package/dist/src/main-api/IShaderController.d.ts +0 -14
  501. package/dist/src/main-api/IShaderController.js +0 -30
  502. package/dist/src/main-api/IShaderController.js.map +0 -1
  503. package/dist/src/main-api/IShaderNode.d.ts +0 -17
  504. package/dist/src/main-api/IShaderNode.js +0 -19
  505. package/dist/src/main-api/IShaderNode.js.map +0 -1
  506. package/dist/src/main-api/RendererMain.d.ts +0 -375
  507. package/dist/src/main-api/RendererMain.js +0 -365
  508. package/dist/src/main-api/RendererMain.js.map +0 -1
  509. package/dist/src/main-api/ShaderController.d.ts +0 -31
  510. package/dist/src/main-api/ShaderController.js +0 -37
  511. package/dist/src/main-api/ShaderController.js.map +0 -1
  512. package/dist/src/main-api/texture-usage-trackers/FinalizationRegistryTextureUsageTracker.d.ts +0 -9
  513. package/dist/src/main-api/texture-usage-trackers/FinalizationRegistryTextureUsageTracker.js +0 -38
  514. package/dist/src/main-api/texture-usage-trackers/FinalizationRegistryTextureUsageTracker.js.map +0 -1
  515. package/dist/src/main-api/texture-usage-trackers/ManualCountTextureUsageTracker.d.ts +0 -56
  516. package/dist/src/main-api/texture-usage-trackers/ManualCountTextureUsageTracker.js +0 -101
  517. package/dist/src/main-api/texture-usage-trackers/ManualCountTextureUsageTracker.js.map +0 -1
  518. package/dist/src/main-api/texture-usage-trackers/TextureUsageTracker.d.ts +0 -32
  519. package/dist/src/main-api/texture-usage-trackers/TextureUsageTracker.js.map +0 -1
  520. package/dist/src/render-drivers/main/MainCoreDriver.d.ts +0 -24
  521. package/dist/src/render-drivers/main/MainCoreDriver.js +0 -118
  522. package/dist/src/render-drivers/main/MainCoreDriver.js.map +0 -1
  523. package/dist/src/render-drivers/main/MainOnlyNode.d.ts +0 -99
  524. package/dist/src/render-drivers/main/MainOnlyNode.js +0 -396
  525. package/dist/src/render-drivers/main/MainOnlyNode.js.map +0 -1
  526. package/dist/src/render-drivers/main/MainOnlyShaderController.d.ts +0 -6
  527. package/dist/src/render-drivers/main/MainOnlyShaderController.js +0 -15
  528. package/dist/src/render-drivers/main/MainOnlyShaderController.js.map +0 -1
  529. package/dist/src/render-drivers/main/MainOnlyShaderNode.d.ts +0 -7
  530. package/dist/src/render-drivers/main/MainOnlyShaderNode.js +0 -34
  531. package/dist/src/render-drivers/main/MainOnlyShaderNode.js.map +0 -1
  532. package/dist/src/render-drivers/main/MainOnlyTextNode.d.ts +0 -47
  533. package/dist/src/render-drivers/main/MainOnlyTextNode.js +0 -205
  534. package/dist/src/render-drivers/main/MainOnlyTextNode.js.map +0 -1
  535. package/dist/src/render-drivers/main/MainRenderDriver.d.ts +0 -17
  536. package/dist/src/render-drivers/main/MainRenderDriver.js +0 -88
  537. package/dist/src/render-drivers/main/MainRenderDriver.js.map +0 -1
  538. package/dist/src/render-drivers/threadx/NodeStruct.d.ts +0 -90
  539. package/dist/src/render-drivers/threadx/NodeStruct.js +0 -281
  540. package/dist/src/render-drivers/threadx/NodeStruct.js.map +0 -1
  541. package/dist/src/render-drivers/threadx/SharedNode.d.ts +0 -39
  542. package/dist/src/render-drivers/threadx/SharedNode.js +0 -60
  543. package/dist/src/render-drivers/threadx/SharedNode.js.map +0 -1
  544. package/dist/src/render-drivers/threadx/TextNodeStruct.d.ts +0 -44
  545. package/dist/src/render-drivers/threadx/TextNodeStruct.js +0 -201
  546. package/dist/src/render-drivers/threadx/TextNodeStruct.js.map +0 -1
  547. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.d.ts +0 -28
  548. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js +0 -234
  549. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js.map +0 -1
  550. package/dist/src/render-drivers/threadx/ThreadXMainAnimationController.d.ts +0 -20
  551. package/dist/src/render-drivers/threadx/ThreadXMainAnimationController.js +0 -84
  552. package/dist/src/render-drivers/threadx/ThreadXMainAnimationController.js.map +0 -1
  553. package/dist/src/render-drivers/threadx/ThreadXMainNode.d.ts +0 -44
  554. package/dist/src/render-drivers/threadx/ThreadXMainNode.js +0 -154
  555. package/dist/src/render-drivers/threadx/ThreadXMainNode.js.map +0 -1
  556. package/dist/src/render-drivers/threadx/ThreadXMainShaderController.d.ts +0 -6
  557. package/dist/src/render-drivers/threadx/ThreadXMainShaderController.js +0 -16
  558. package/dist/src/render-drivers/threadx/ThreadXMainShaderController.js.map +0 -1
  559. package/dist/src/render-drivers/threadx/ThreadXMainShaderNode.d.ts +0 -7
  560. package/dist/src/render-drivers/threadx/ThreadXMainShaderNode.js +0 -15
  561. package/dist/src/render-drivers/threadx/ThreadXMainShaderNode.js.map +0 -1
  562. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.d.ts +0 -28
  563. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.js +0 -55
  564. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.js.map +0 -1
  565. package/dist/src/render-drivers/threadx/ThreadXRenderDriver.d.ts +0 -21
  566. package/dist/src/render-drivers/threadx/ThreadXRenderDriver.js +0 -198
  567. package/dist/src/render-drivers/threadx/ThreadXRenderDriver.js.map +0 -1
  568. package/dist/src/render-drivers/threadx/ThreadXRendererMessage.d.ts +0 -70
  569. package/dist/src/render-drivers/threadx/ThreadXRendererMessage.js +0 -32
  570. package/dist/src/render-drivers/threadx/ThreadXRendererMessage.js.map +0 -1
  571. package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.d.ts +0 -19
  572. package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js +0 -177
  573. package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js.map +0 -1
  574. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.d.ts +0 -27
  575. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js +0 -108
  576. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js.map +0 -1
  577. package/dist/src/render-drivers/threadx/worker/renderer.d.ts +0 -1
  578. package/dist/src/render-drivers/threadx/worker/renderer.js +0 -145
  579. package/dist/src/render-drivers/threadx/worker/renderer.js.map +0 -1
  580. package/dist/src/render-drivers/utils.d.ts +0 -12
  581. package/dist/src/render-drivers/utils.js +0 -69
  582. package/dist/src/render-drivers/utils.js.map +0 -1
  583. package/scripts/please-use-pnpm.js +0 -13
  584. package/src/core/platform.ts +0 -64
  585. package/src/core/renderers/canvas/internal/C2DShaderUtils.ts +0 -220
  586. package/src/core/text-rendering/TextRenderingUtils.ts +0 -36
  587. package/src/core/text-rendering/TrFontManager.ts +0 -183
  588. package/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.ts +0 -176
  589. package/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/FontShaper.ts +0 -139
  590. package/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.test.ts +0 -173
  591. package/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.ts +0 -171
  592. package/src/core/text-rendering/font-face-types/TrFontFace.ts +0 -187
  593. package/src/core/text-rendering/font-face-types/WebTrFontFace.ts +0 -94
  594. package/src/core/text-rendering/font-face-types/utils.ts +0 -39
  595. package/src/core/text-rendering/renderers/CanvasTextRenderer.ts +0 -509
  596. package/src/core/text-rendering/renderers/LightningTextTextureRenderer.ts +0 -815
  597. package/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.ts +0 -841
  598. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/PeekableGenerator.test.ts +0 -48
  599. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/PeekableGenerator.ts +0 -66
  600. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/SpecialCodepoints.ts +0 -52
  601. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/constants.ts +0 -32
  602. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.ts +0 -117
  603. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/getUnicodeCodepoints.test.ts +0 -133
  604. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/getUnicodeCodepoints.ts +0 -38
  605. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.ts +0 -408
  606. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/measureText.test.ts +0 -49
  607. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/measureText.ts +0 -52
  608. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.test.ts +0 -205
  609. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.ts +0 -93
  610. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.ts +0 -40
  611. package/src/core/text-rendering/renderers/TextRenderer.ts +0 -550
package/src/core/Stage.ts CHANGED
@@ -1,740 +1,906 @@
1
- /*
2
- * If not stated otherwise in this file or this component's LICENSE file the
3
- * following copyright and licenses apply:
4
- *
5
- * Copyright 2023 Comcast Cable Communications Management, LLC.
6
- *
7
- * Licensed under the Apache License, Version 2.0 (the License);
8
- * you may not use this file except in compliance with the License.
9
- * You may obtain a copy of the License at
10
- *
11
- * http://www.apache.org/licenses/LICENSE-2.0
12
- *
13
- * Unless required by applicable law or agreed to in writing, software
14
- * distributed under the License is distributed on an "AS IS" BASIS,
15
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- * See the License for the specific language governing permissions and
17
- * limitations under the License.
18
- */
19
- import { startLoop, getTimeStamp } from './platform.js';
20
- import { assertTruthy, setPremultiplyMode } from '../utils.js';
21
- import { AnimationManager } from './animations/AnimationManager.js';
22
- import {
23
- UpdateType,
24
- CoreNode,
25
- CoreNodeRenderState,
26
- type CoreNodeProps,
27
- } from './CoreNode.js';
28
- import { CoreTextureManager } from './CoreTextureManager.js';
29
- import { TrFontManager } from './text-rendering/TrFontManager.js';
30
- import { CoreShaderManager } from './CoreShaderManager.js';
31
- import {
32
- TextRenderer,
33
- type TextRendererMap,
34
- type TrProps,
35
- } from './text-rendering/renderers/TextRenderer.js';
36
-
37
- import { EventEmitter } from '../common/EventEmitter.js';
38
- import { ContextSpy } from './lib/ContextSpy.js';
39
- import type {
40
- FpsUpdatePayload,
41
- FrameTickPayload,
42
- QuadsUpdatePayload,
43
- } from '../common/CommonTypes.js';
44
- import {
45
- TextureMemoryManager,
46
- type TextureMemoryManagerSettings,
47
- } from './TextureMemoryManager.js';
48
- import { CoreRenderer } from './renderers/CoreRenderer.js';
49
- import type { WebGlRenderer } from './renderers/webgl/WebGlRenderer.js';
50
- import type { CanvasRenderer } from './renderers/canvas/CanvasRenderer.js';
51
- import { CoreTextNode, type CoreTextNodeProps } from './CoreTextNode.js';
52
- import { santizeCustomDataMap } from '../main-api/utils.js';
53
- import type { SdfTextRenderer } from './text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js';
54
- import type { CanvasTextRenderer } from './text-rendering/renderers/CanvasTextRenderer.js';
55
- import type { CoreShaderNode } from './renderers/CoreShaderNode.js';
56
- import { createBound, createPreloadBounds, type Bound } from './lib/utils.js';
57
- import type { Texture } from './textures/Texture.js';
58
- import { ColorTexture } from './textures/ColorTexture.js';
59
-
60
- export interface StageOptions {
61
- appWidth: number;
62
- appHeight: number;
63
- textureMemory: TextureMemoryManagerSettings;
64
- boundsMargin: number | [number, number, number, number];
65
- deviceLogicalPixelRatio: number;
66
- devicePhysicalPixelRatio: number;
67
- canvas: HTMLCanvasElement | OffscreenCanvas;
68
- clearColor: number;
69
- fpsUpdateInterval: number;
70
- enableContextSpy: boolean;
71
- forceWebGL2: boolean;
72
- numImageWorkers: number;
73
- renderEngine: typeof WebGlRenderer | typeof CanvasRenderer;
74
- eventBus: EventEmitter;
75
- quadBufferSize: number;
76
- fontEngines: (typeof CanvasTextRenderer | typeof SdfTextRenderer)[];
77
- inspector: boolean;
78
- strictBounds: boolean;
79
- textureProcessingTimeLimit: number;
80
- createImageBitmapSupport: 'auto' | 'basic' | 'options' | 'full';
81
- }
82
-
83
- export type StageFpsUpdateHandler = (
84
- stage: Stage,
85
- fpsData: FpsUpdatePayload,
86
- ) => void;
87
-
88
- export type StageFrameTickHandler = (
89
- stage: Stage,
90
- frameTickData: FrameTickPayload,
91
- ) => void;
92
-
93
- const autoStart = true;
94
-
95
- export class Stage {
96
- /// Module Instances
97
- public readonly animationManager: AnimationManager;
98
- public readonly txManager: CoreTextureManager;
99
- public readonly txMemManager: TextureMemoryManager;
100
- public readonly fontManager: TrFontManager;
101
- public readonly textRenderers: Partial<TextRendererMap>;
102
- public readonly shManager: CoreShaderManager;
103
- public readonly renderer: CoreRenderer;
104
- public readonly root: CoreNode;
105
- public boundsMargin: [number, number, number, number];
106
- public readonly defShaderNode: CoreShaderNode | null = null;
107
- public readonly strictBound: Bound;
108
- public readonly preloadBound: Bound;
109
- public readonly strictBounds: boolean;
110
- public readonly defaultTexture: Texture | null = null;
111
- public readonly pixelRatio: number;
112
- public readonly bufferMemory: number = 2e6;
113
- /**
114
- * Renderer Event Bus for the Stage to emit events onto
115
- *
116
- * @remarks
117
- * In reality this is just the RendererMain instance, which is an EventEmitter.
118
- * this allows us to directly emit events from the Stage to RendererMain
119
- * without having to set up forwarding handlers.
120
- */
121
- public readonly eventBus: EventEmitter;
122
-
123
- /// State
124
- deltaTime = 0;
125
- lastFrameTime = 0;
126
- currentFrameTime = 0;
127
- private clrColor = 0x00000000;
128
- private fpsNumFrames = 0;
129
- private fpsElapsedTime = 0;
130
- private numQuadsRendered = 0;
131
- private renderRequested = false;
132
- private frameEventQueue: [name: string, payload: unknown][] = [];
133
- private fontResolveMap: Record<string, CanvasTextRenderer | SdfTextRenderer> =
134
- {};
135
-
136
- /// Debug data
137
- contextSpy: ContextSpy | null = null;
138
-
139
- /**
140
- * Stage constructor
141
- */
142
- constructor(readonly options: StageOptions) {
143
- const {
144
- canvas,
145
- clearColor,
146
- appWidth,
147
- appHeight,
148
- boundsMargin,
149
- enableContextSpy,
150
- forceWebGL2,
151
- numImageWorkers,
152
- textureMemory,
153
- renderEngine,
154
- fontEngines,
155
- createImageBitmapSupport,
156
- } = options;
157
-
158
- this.eventBus = options.eventBus;
159
- this.txManager = new CoreTextureManager(this, {
160
- numImageWorkers,
161
- createImageBitmapSupport,
162
- });
163
-
164
- // Wait for the Texture Manager to initialize
165
- // once it does, request a render
166
- this.txManager.on('initialized', () => {
167
- this.requestRender();
168
- });
169
-
170
- this.txMemManager = new TextureMemoryManager(this, textureMemory);
171
-
172
- this.animationManager = new AnimationManager();
173
- this.contextSpy = enableContextSpy ? new ContextSpy() : null;
174
- this.strictBounds = options.strictBounds;
175
-
176
- let bm = [0, 0, 0, 0] as [number, number, number, number];
177
- if (boundsMargin) {
178
- bm = Array.isArray(boundsMargin)
179
- ? boundsMargin
180
- : [boundsMargin, boundsMargin, boundsMargin, boundsMargin];
181
- }
182
- this.boundsMargin = bm;
183
-
184
- // precalculate our viewport bounds
185
- this.strictBound = createBound(0, 0, appWidth, appHeight);
186
- this.preloadBound = createPreloadBounds(this.strictBound, bm);
187
-
188
- this.clrColor = clearColor;
189
-
190
- this.pixelRatio =
191
- options.devicePhysicalPixelRatio * options.deviceLogicalPixelRatio;
192
-
193
- this.renderer = new renderEngine({
194
- stage: this,
195
- canvas,
196
- contextSpy: this.contextSpy,
197
- forceWebGL2,
198
- });
199
-
200
- this.shManager = new CoreShaderManager(this);
201
-
202
- this.defShaderNode = this.renderer.getDefaultShaderNode();
203
-
204
- const renderMode = this.renderer.mode || 'webgl';
205
-
206
- this.createDefaultTexture();
207
- setPremultiplyMode(renderMode);
208
-
209
- // Must do this after renderer is created
210
- this.txManager.renderer = this.renderer;
211
-
212
- // Create text renderers
213
- this.textRenderers = {};
214
- fontEngines.forEach((fontEngineConstructor) => {
215
- const fontEngineInstance = new fontEngineConstructor(this);
216
- const className = fontEngineInstance.type;
217
-
218
- if (className === 'sdf' && renderMode === 'canvas') {
219
- console.warn(
220
- 'SdfTextRenderer is not compatible with Canvas renderer. Skipping...',
221
- );
222
- return;
223
- }
224
-
225
- if (fontEngineInstance instanceof TextRenderer) {
226
- if (className === 'canvas') {
227
- this.textRenderers['canvas'] =
228
- fontEngineInstance as CanvasTextRenderer;
229
- } else if (className === 'sdf') {
230
- this.textRenderers['sdf'] = fontEngineInstance as SdfTextRenderer;
231
- }
232
- }
233
- });
234
-
235
- if (Object.keys(this.textRenderers).length === 0) {
236
- console.warn('No text renderers available. Your text will not render.');
237
- }
238
-
239
- this.fontManager = new TrFontManager(this.textRenderers);
240
-
241
- // create root node
242
- const rootNode = new CoreNode(this, {
243
- x: 0,
244
- y: 0,
245
- width: appWidth,
246
- height: appHeight,
247
- alpha: 1,
248
- autosize: false,
249
- boundsMargin: null,
250
- clipping: false,
251
- color: 0x00000000,
252
- colorTop: 0x00000000,
253
- colorBottom: 0x00000000,
254
- colorLeft: 0x00000000,
255
- colorRight: 0x00000000,
256
- colorTl: 0x00000000,
257
- colorTr: 0x00000000,
258
- colorBl: 0x00000000,
259
- colorBr: 0x00000000,
260
- zIndex: 0,
261
- zIndexLocked: 0,
262
- scaleX: 1,
263
- scaleY: 1,
264
- mountX: 0,
265
- mountY: 0,
266
- mount: 0,
267
- pivot: 0.5,
268
- pivotX: 0.5,
269
- pivotY: 0.5,
270
- rotation: 0,
271
- parent: null,
272
- texture: null,
273
- textureOptions: {},
274
- shader: this.defShaderNode,
275
- rtt: false,
276
- src: null,
277
- scale: 1,
278
- preventCleanup: false,
279
- strictBounds: this.strictBounds,
280
- });
281
-
282
- this.root = rootNode;
283
-
284
- // execute platform start loop
285
- if (autoStart) {
286
- startLoop(this);
287
- }
288
- }
289
-
290
- setClearColor(color: number) {
291
- this.clearColor = color;
292
- this.renderer.updateClearColor(color);
293
- this.renderRequested = true;
294
- }
295
-
296
- updateFrameTime() {
297
- const newFrameTime = getTimeStamp();
298
- this.lastFrameTime = this.currentFrameTime;
299
- this.currentFrameTime = newFrameTime;
300
- this.deltaTime = !this.lastFrameTime
301
- ? 100 / 6
302
- : newFrameTime - this.lastFrameTime;
303
- this.txManager.frameTime = newFrameTime;
304
- this.txMemManager.frameTime = newFrameTime;
305
-
306
- // This event is emitted at the beginning of the frame (before any updates
307
- // or rendering), so no need to to use `stage.queueFrameEvent` here.
308
- this.eventBus.emit('frameTick', {
309
- time: this.currentFrameTime,
310
- delta: this.deltaTime,
311
- });
312
- }
313
-
314
- /**
315
- * Create default PixelTexture
316
- */
317
- createDefaultTexture() {
318
- console.log('Creating default texture');
319
- (this.defaultTexture as ColorTexture) = this.txManager.createTexture(
320
- 'ColorTexture',
321
- {
322
- color: 0xffffffff,
323
- },
324
- );
325
-
326
- assertTruthy(this.defaultTexture instanceof ColorTexture);
327
- this.txManager.loadTexture(this.defaultTexture, true);
328
-
329
- // Mark the default texture as ALWAYS renderable
330
- // This prevents it from ever being cleaned up.
331
- // Fixes https://github.com/lightning-js/renderer/issues/262
332
- this.defaultTexture.setRenderableOwner(this, true);
333
-
334
- // When the default texture is loaded, request a render in case the
335
- // RAF is paused. Fixes: https://github.com/lightning-js/renderer/issues/123
336
- this.defaultTexture.once('loaded', () => {
337
- this.requestRender();
338
- });
339
- }
340
-
341
- /**
342
- * Update animations
343
- */
344
- updateAnimations() {
345
- const { animationManager } = this;
346
- if (!this.root) {
347
- return;
348
- }
349
- // step animation
350
- animationManager.update(this.deltaTime);
351
- }
352
-
353
- /**
354
- * Check if the scene has updates
355
- */
356
- hasSceneUpdates() {
357
- return (
358
- !!this.root.updateType ||
359
- this.renderRequested ||
360
- this.txManager.hasUpdates()
361
- );
362
- }
363
-
364
- /**
365
- * Start a new frame draw
366
- */
367
- drawFrame() {
368
- const { renderer, renderRequested } = this;
369
- assertTruthy(renderer);
370
-
371
- // Update tree if needed
372
- if (this.root.updateType !== 0) {
373
- this.root.update(this.deltaTime, this.root.clippingRect);
374
- }
375
-
376
- // Process some textures
377
- this.txManager.processSome(this.options.textureProcessingTimeLimit);
378
-
379
- // Reset render operations and clear the canvas
380
- renderer.reset();
381
-
382
- // Check if we need to cleanup textures
383
- if (this.txMemManager.criticalCleanupRequested === true) {
384
- this.txMemManager.cleanup(false);
385
-
386
- if (this.txMemManager.criticalCleanupRequested === true) {
387
- // If we still need to cleanup, request another but aggressive cleanup
388
- this.txMemManager.cleanup(true);
389
- }
390
- }
391
-
392
- // If we have RTT nodes draw them first
393
- // So we can use them as textures in the main scene
394
- if (renderer.rttNodes.length > 0) {
395
- renderer.renderRTTNodes();
396
- }
397
-
398
- // Fill quads buffer
399
- this.addQuads(this.root);
400
-
401
- // Perform render pass
402
- renderer?.render();
403
-
404
- this.calculateFps();
405
- this.calculateQuads();
406
-
407
- // Reset renderRequested flag if it was set
408
- if (renderRequested) {
409
- this.renderRequested = false;
410
- }
411
- }
412
-
413
- /**
414
- * Queue an event to be emitted after the current/next frame is rendered
415
- *
416
- * @remarks
417
- * When we are operating in the context of the render loop, we may want to
418
- * emit events that are related to the current frame. However, we generally do
419
- * NOT want to emit events directly in the middle of the render loop, since
420
- * this could enable event handlers to modify the scene graph and cause
421
- * unexpected behavior. Instead, we queue up events to be emitted and then
422
- * flush the queue after the frame has been rendered.
423
- *
424
- * @param name
425
- * @param data
426
- */
427
- queueFrameEvent(name: string, data: unknown) {
428
- this.frameEventQueue.push([name, data]);
429
- }
430
-
431
- /**
432
- * Emit all queued frame events
433
- *
434
- * @remarks
435
- * This method should be called after the frame has been rendered to emit
436
- * all events that were queued during the frame.
437
- *
438
- * See {@link queueFrameEvent} for more information.
439
- */
440
- flushFrameEvents() {
441
- for (const [name, data] of this.frameEventQueue) {
442
- this.eventBus.emit(name, data);
443
- }
444
- this.frameEventQueue = [];
445
- }
446
-
447
- calculateFps() {
448
- // If there's an FPS update interval, emit the FPS update event
449
- // when the specified interval has elapsed.
450
- const { fpsUpdateInterval } = this.options;
451
- if (fpsUpdateInterval) {
452
- this.fpsNumFrames++;
453
- this.fpsElapsedTime += this.deltaTime;
454
- if (this.fpsElapsedTime >= fpsUpdateInterval) {
455
- const fps = Math.round(
456
- (this.fpsNumFrames * 1000) / this.fpsElapsedTime,
457
- );
458
- this.fpsNumFrames = 0;
459
- this.fpsElapsedTime = 0;
460
- this.queueFrameEvent('fpsUpdate', {
461
- fps,
462
- contextSpyData: this.contextSpy?.getData() ?? null,
463
- } satisfies FpsUpdatePayload);
464
- this.contextSpy?.reset();
465
- }
466
- }
467
- }
468
-
469
- calculateQuads() {
470
- const quads = this.renderer.getQuadCount();
471
- if (quads && quads !== this.numQuadsRendered) {
472
- this.numQuadsRendered = quads;
473
- this.queueFrameEvent('quadsUpdate', {
474
- quads,
475
- } satisfies QuadsUpdatePayload);
476
- }
477
- }
478
-
479
- addQuads(node: CoreNode) {
480
- assertTruthy(this.renderer);
481
-
482
- // If the node is renderable and has a loaded texture, render it
483
- if (node.isRenderable === true) {
484
- node.renderQuads(this.renderer);
485
- }
486
-
487
- for (let i = 0; i < node.children.length; i++) {
488
- const child = node.children[i];
489
-
490
- if (child === undefined) {
491
- continue;
492
- }
493
-
494
- if (
495
- child.worldAlpha === 0 ||
496
- (child.strictBounds === true &&
497
- child.renderState === CoreNodeRenderState.OutOfBounds)
498
- ) {
499
- continue;
500
- }
501
-
502
- this.addQuads(child);
503
- }
504
- }
505
-
506
- /**
507
- * Request a render pass without forcing an update
508
- */
509
- requestRender() {
510
- this.renderRequested = true;
511
- }
512
-
513
- /**
514
- * Given a font name, and possible renderer override, return the best compatible text renderer.
515
- *
516
- * @remarks
517
- * Will try to return a canvas renderer if no other suitable renderer can be resolved.
518
- *
519
- * @param fontFamily
520
- * @param textRendererOverride
521
- * @returns
522
- */
523
- resolveTextRenderer(
524
- trProps: TrProps,
525
- textRendererOverride: keyof TextRendererMap | null = null,
526
- ): TextRenderer | null {
527
- const fontCacheString = `${trProps.fontFamily}${trProps.fontStyle}${
528
- trProps.fontWeight
529
- }${trProps.fontStretch}${textRendererOverride ? textRendererOverride : ''}`;
530
-
531
- // check our resolve cache first
532
- if (this.fontResolveMap[fontCacheString] !== undefined) {
533
- return this.fontResolveMap[fontCacheString] as unknown as TextRenderer;
534
- }
535
-
536
- // Resolve the text renderer
537
- let rendererId = textRendererOverride;
538
- let overrideFallback = false;
539
-
540
- // Check if the override is valid (if one is provided)
541
- if (rendererId) {
542
- const possibleRenderer = this.textRenderers[rendererId];
543
- if (!possibleRenderer) {
544
- console.warn(`Text renderer override '${rendererId}' not found.`);
545
- rendererId = null;
546
- overrideFallback = true;
547
- } else if (!possibleRenderer.canRenderFont(trProps)) {
548
- console.warn(
549
- `Cannot use override text renderer '${rendererId}' for font`,
550
- trProps,
551
- );
552
- rendererId = null;
553
- overrideFallback = true;
554
- }
555
- }
556
-
557
- if (!rendererId) {
558
- // Iterate through the text renderers and find the first one that can render the font
559
- for (const [trId, tr] of Object.entries(this.textRenderers)) {
560
- if (tr.canRenderFont(trProps)) {
561
- rendererId = trId as keyof TextRendererMap;
562
- break;
563
- }
564
- }
565
- if (!rendererId && this.textRenderers.canvas !== undefined) {
566
- // If no renderer can be found, use the canvas renderer
567
- rendererId = 'canvas';
568
- }
569
- }
570
-
571
- if (overrideFallback) {
572
- console.warn(`Falling back to text renderer ${String(rendererId)}`);
573
- }
574
-
575
- if (!rendererId) {
576
- // silently fail if no renderer can be found, the error is already created
577
- // at the constructor level
578
- return null;
579
- }
580
-
581
- // By now we are guaranteed to have a valid rendererId (at least Canvas);
582
- const resolvedTextRenderer = this.textRenderers[rendererId];
583
- assertTruthy(resolvedTextRenderer, 'resolvedTextRenderer undefined');
584
-
585
- // cache the resolved renderer for future use with these trProps
586
- this.fontResolveMap[fontCacheString] = resolvedTextRenderer;
587
-
588
- // Need to explicitly cast to TextRenderer because TS doesn't like
589
- // the covariant state argument in the setter method map
590
- return resolvedTextRenderer as unknown as TextRenderer;
591
- }
592
-
593
- createNode(props: Partial<CoreNodeProps>) {
594
- const resolvedProps = this.resolveNodeDefaults(props);
595
- return new CoreNode(this, resolvedProps);
596
- }
597
-
598
- createTextNode(props: Partial<CoreTextNodeProps>) {
599
- const fontSize = props.fontSize ?? 16;
600
- const resolvedProps = {
601
- ...this.resolveNodeDefaults(props),
602
- text: props.text ?? '',
603
- textRendererOverride: props.textRendererOverride ?? null,
604
- fontSize,
605
- fontFamily: props.fontFamily ?? 'sans-serif',
606
- fontStyle: props.fontStyle ?? 'normal',
607
- fontWeight: props.fontWeight ?? 'normal',
608
- fontStretch: props.fontStretch ?? 'normal',
609
- textAlign: props.textAlign ?? 'left',
610
- contain: props.contain ?? 'none',
611
- scrollable: props.scrollable ?? false,
612
- scrollY: props.scrollY ?? 0,
613
- offsetY: props.offsetY ?? 0,
614
- letterSpacing: props.letterSpacing ?? 0,
615
- lineHeight: props.lineHeight, // `undefined` is a valid value
616
- maxLines: props.maxLines ?? 0,
617
- textBaseline: props.textBaseline ?? 'alphabetic',
618
- verticalAlign: props.verticalAlign ?? 'middle',
619
- overflowSuffix: props.overflowSuffix ?? '...',
620
- debug: props.debug ?? {},
621
- shaderProps: null,
622
- };
623
-
624
- const resolvedTextRenderer = this.resolveTextRenderer(
625
- resolvedProps,
626
- props.textRendererOverride,
627
- );
628
-
629
- if (!resolvedTextRenderer) {
630
- throw new Error(
631
- `No compatible text renderer found for ${resolvedProps.fontFamily}`,
632
- );
633
- }
634
-
635
- return new CoreTextNode(this, resolvedProps, resolvedTextRenderer);
636
- }
637
-
638
- setBoundsMargin(value: number | [number, number, number, number]) {
639
- this.boundsMargin = Array.isArray(value)
640
- ? value
641
- : [value, value, value, value];
642
-
643
- this.root.setUpdateType(UpdateType.RenderBounds);
644
- }
645
-
646
- /**
647
- * Resolves the default property values for a Node
648
- *
649
- * @remarks
650
- * This method is used internally by the RendererMain to resolve the default
651
- * property values for a Node. It is exposed publicly so that it can be used
652
- * by Core Driver implementations.
653
- *
654
- * @param props
655
- * @returns
656
- */
657
- protected resolveNodeDefaults(props: Partial<CoreNodeProps>): CoreNodeProps {
658
- const color = props.color ?? 0xffffffff;
659
- const colorTl = props.colorTl ?? props.colorTop ?? props.colorLeft ?? color;
660
- const colorTr =
661
- props.colorTr ?? props.colorTop ?? props.colorRight ?? color;
662
- const colorBl =
663
- props.colorBl ?? props.colorBottom ?? props.colorLeft ?? color;
664
- const colorBr =
665
- props.colorBr ?? props.colorBottom ?? props.colorRight ?? color;
666
-
667
- let data = {};
668
- if (this.options.inspector === true) {
669
- data = santizeCustomDataMap(props.data ?? {});
670
- }
671
-
672
- return {
673
- x: props.x ?? 0,
674
- y: props.y ?? 0,
675
- width: props.width ?? 0,
676
- height: props.height ?? 0,
677
- alpha: props.alpha ?? 1,
678
- autosize: props.autosize ?? false,
679
- boundsMargin: props.boundsMargin ?? null,
680
- clipping: props.clipping ?? false,
681
- color,
682
- colorTop: props.colorTop ?? color,
683
- colorBottom: props.colorBottom ?? color,
684
- colorLeft: props.colorLeft ?? color,
685
- colorRight: props.colorRight ?? color,
686
- colorBl,
687
- colorBr,
688
- colorTl,
689
- colorTr,
690
- zIndex: props.zIndex ?? 0,
691
- zIndexLocked: props.zIndexLocked ?? 0,
692
- parent: props.parent ?? null,
693
- texture: props.texture ?? null,
694
- textureOptions: props.textureOptions ?? {},
695
- shader: props.shader ?? this.defShaderNode,
696
- // Since setting the `src` will trigger a texture load, we need to set it after
697
- // we set the texture. Otherwise, problems happen.
698
- src: props.src ?? null,
699
- srcHeight: props.srcHeight,
700
- srcWidth: props.srcWidth,
701
- srcX: props.srcX,
702
- srcY: props.srcY,
703
- scale: props.scale ?? null,
704
- scaleX: props.scaleX ?? props.scale ?? 1,
705
- scaleY: props.scaleY ?? props.scale ?? 1,
706
- mount: props.mount ?? 0,
707
- mountX: props.mountX ?? props.mount ?? 0,
708
- mountY: props.mountY ?? props.mount ?? 0,
709
- pivot: props.pivot ?? 0.5,
710
- pivotX: props.pivotX ?? props.pivot ?? 0.5,
711
- pivotY: props.pivotY ?? props.pivot ?? 0.5,
712
- rotation: props.rotation ?? 0,
713
- rtt: props.rtt ?? false,
714
- data: data,
715
- preventCleanup: props.preventCleanup ?? false,
716
- imageType: props.imageType,
717
- strictBounds: props.strictBounds ?? this.strictBounds,
718
- };
719
- }
720
-
721
- /**
722
- * Cleanup Orphaned Textures
723
- *
724
- * @remarks
725
- * This method is used to cleanup orphaned textures that are no longer in use.
726
- */
727
- cleanup(aggressive: boolean) {
728
- this.txMemManager.cleanup(aggressive);
729
- }
730
-
731
- set clearColor(value: number) {
732
- this.renderer.updateClearColor(value);
733
- this.renderRequested = true;
734
- this.clrColor = value;
735
- }
736
-
737
- get clearColor() {
738
- return this.clrColor;
739
- }
740
- }
1
+ /*
2
+ * If not stated otherwise in this file or this component's LICENSE file the
3
+ * following copyright and licenses apply:
4
+ *
5
+ * Copyright 2023 Comcast Cable Communications Management, LLC.
6
+ *
7
+ * Licensed under the Apache License, Version 2.0 (the License);
8
+ * you may not use this file except in compliance with the License.
9
+ * You may obtain a copy of the License at
10
+ *
11
+ * http://www.apache.org/licenses/LICENSE-2.0
12
+ *
13
+ * Unless required by applicable law or agreed to in writing, software
14
+ * distributed under the License is distributed on an "AS IS" BASIS,
15
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ */
19
+
20
+ import { assertTruthy, setPremultiplyMode } from '../utils.js';
21
+ import { AnimationManager } from './animations/AnimationManager.js';
22
+ import {
23
+ UpdateType,
24
+ CoreNode,
25
+ CoreNodeRenderState,
26
+ type CoreNodeProps,
27
+ } from './CoreNode.js';
28
+ import { CoreTextureManager } from './CoreTextureManager.js';
29
+ import { CoreShaderManager } from './CoreShaderManager.js';
30
+ import {
31
+ type FontHandler,
32
+ type FontLoadOptions,
33
+ type TextRenderer,
34
+ type TextRenderers,
35
+ type TrProps,
36
+ } from './text-rendering/TextRenderer.js';
37
+
38
+ import { EventEmitter } from '../common/EventEmitter.js';
39
+ import { ContextSpy } from './lib/ContextSpy.js';
40
+ import type {
41
+ FpsUpdatePayload,
42
+ FrameTickPayload,
43
+ QuadsUpdatePayload,
44
+ } from '../common/CommonTypes.js';
45
+ import {
46
+ TextureMemoryManager,
47
+ type TextureMemoryManagerSettings,
48
+ } from './TextureMemoryManager.js';
49
+ import { CoreRenderer } from './renderers/CoreRenderer.js';
50
+ import { CoreTextNode, type CoreTextNodeProps } from './CoreTextNode.js';
51
+ import { santizeCustomDataMap } from '../main-api/utils.js';
52
+ import { pointInBound } from './lib/utils.js';
53
+ import type { CoreShaderNode } from './renderers/CoreShaderNode.js';
54
+ import { createBound, createPreloadBounds, type Bound } from './lib/utils.js';
55
+ import type { Texture } from './textures/Texture.js';
56
+ import { ColorTexture } from './textures/ColorTexture.js';
57
+ import type { Platform } from './platforms/Platform.js';
58
+ import type { WebPlatform } from './platforms/web/WebPlatform.js';
59
+ import type { RendererMainSettings } from '../main-api/Renderer.js';
60
+
61
+ export type StageOptions = Omit<
62
+ RendererMainSettings,
63
+ 'inspector' | 'platform'
64
+ > & {
65
+ textureMemory: TextureMemoryManagerSettings;
66
+ canvas: HTMLCanvasElement | OffscreenCanvas;
67
+ fpsUpdateInterval: number;
68
+ eventBus: EventEmitter;
69
+ platform: Platform | WebPlatform;
70
+ inspector: boolean;
71
+ };
72
+
73
+ export type StageFpsUpdateHandler = (
74
+ stage: Stage,
75
+ fpsData: FpsUpdatePayload,
76
+ ) => void;
77
+
78
+ export type StageFrameTickHandler = (
79
+ stage: Stage,
80
+ frameTickData: FrameTickPayload,
81
+ ) => void;
82
+
83
+ export interface Point {
84
+ x: number;
85
+ y: number;
86
+ }
87
+
88
+ const autoStart = true;
89
+
90
+ export class Stage {
91
+ /// Module Instances
92
+ public readonly animationManager: AnimationManager;
93
+ public readonly txManager: CoreTextureManager;
94
+ public readonly txMemManager: TextureMemoryManager;
95
+ public readonly textRenderers: Record<string, TextRenderer> = {};
96
+ public readonly fontHandlers: Record<string, FontHandler> = {};
97
+ public readonly shManager: CoreShaderManager;
98
+ public readonly renderer: CoreRenderer;
99
+ public readonly root: CoreNode;
100
+ public readonly interactiveNodes: Set<CoreNode> = new Set();
101
+ public boundsMargin: [number, number, number, number];
102
+ public readonly defShaderNode: CoreShaderNode | null = null;
103
+ public strictBound: Bound;
104
+ public preloadBound: Bound;
105
+ public readonly strictBounds: boolean;
106
+ public readonly defaultTexture: Texture | null = null;
107
+ public pixelRatio: number;
108
+ public readonly bufferMemory: number = 2e6;
109
+ public readonly platform: Platform | WebPlatform;
110
+ public readonly calculateTextureCoord: boolean;
111
+
112
+ /**
113
+ * Target frame time in milliseconds (calculated from targetFPS)
114
+ *
115
+ * @remarks
116
+ * This is pre-calculated to avoid recalculating on every frame.
117
+ * - 0 means no throttling (use display refresh rate)
118
+ * - >0 means throttle to this frame time (1000 / targetFPS)
119
+ */
120
+ public targetFrameTime: number = 0;
121
+
122
+ /**
123
+ * Renderer Event Bus for the Stage to emit events onto
124
+ *
125
+ * @remarks
126
+ * In reality this is just the RendererMain instance, which is an EventEmitter.
127
+ * this allows us to directly emit events from the Stage to RendererMain
128
+ * without having to set up forwarding handlers.
129
+ */
130
+ public readonly eventBus: EventEmitter;
131
+
132
+ /// State
133
+ deltaTime = 0;
134
+ lastFrameTime = 0;
135
+ currentFrameTime = 0;
136
+ private clrColor = 0x00000000;
137
+ private fpsNumFrames = 0;
138
+ private fpsElapsedTime = 0;
139
+ private numQuadsRendered = 0;
140
+ private renderRequested = false;
141
+ private frameEventQueue: [name: string, payload: unknown][] = [];
142
+
143
+ // Font resolve optimisation flags
144
+ private hasOnlyOneFontEngine: boolean;
145
+ private hasOnlyCanvasFontEngine: boolean;
146
+ private hasCanvasEngine: boolean;
147
+ private singleFontEngine: TextRenderer | null = null;
148
+ private singleFontHandler: FontHandler | null = null;
149
+
150
+ // Debug data
151
+ contextSpy: ContextSpy | null = null;
152
+
153
+ /**
154
+ * Stage constructor
155
+ */
156
+ constructor(public options: StageOptions) {
157
+ const {
158
+ canvas,
159
+ clearColor,
160
+ appWidth,
161
+ appHeight,
162
+ boundsMargin,
163
+ enableContextSpy,
164
+ forceWebGL2,
165
+ numImageWorkers,
166
+ textureMemory,
167
+ renderEngine,
168
+ fontEngines,
169
+ createImageBitmapSupport,
170
+ platform,
171
+ } = options;
172
+
173
+ assertTruthy(
174
+ platform !== null,
175
+ 'A CorePlatform is not provided in the options',
176
+ );
177
+
178
+ this.platform = platform;
179
+
180
+ this.eventBus = options.eventBus;
181
+
182
+ // Calculate target frame time from targetFPS option
183
+ this.targetFrameTime = options.targetFPS > 0 ? 1000 / options.targetFPS : 0;
184
+
185
+ this.txManager = new CoreTextureManager(this, {
186
+ numImageWorkers,
187
+ createImageBitmapSupport,
188
+ });
189
+
190
+ // Wait for the Texture Manager to initialize
191
+ // once it does, request a render
192
+ this.txManager.on('initialized', () => {
193
+ this.requestRender();
194
+ });
195
+
196
+ this.txMemManager = new TextureMemoryManager(this, textureMemory);
197
+
198
+ this.animationManager = new AnimationManager();
199
+ this.contextSpy = enableContextSpy ? new ContextSpy() : null;
200
+ this.strictBounds = options.strictBounds;
201
+
202
+ let bm = [0, 0, 0, 0] as [number, number, number, number];
203
+ if (boundsMargin) {
204
+ bm = Array.isArray(boundsMargin)
205
+ ? boundsMargin
206
+ : [boundsMargin, boundsMargin, boundsMargin, boundsMargin];
207
+ }
208
+ this.boundsMargin = bm;
209
+
210
+ // precalculate our viewport bounds
211
+ this.strictBound = createBound(0, 0, appWidth, appHeight);
212
+ this.preloadBound = createPreloadBounds(this.strictBound, bm);
213
+
214
+ this.clrColor = clearColor;
215
+
216
+ this.pixelRatio =
217
+ options.devicePhysicalPixelRatio * options.deviceLogicalPixelRatio;
218
+
219
+ this.renderer = new renderEngine({
220
+ stage: this,
221
+ canvas,
222
+ contextSpy: this.contextSpy,
223
+ forceWebGL2,
224
+ });
225
+
226
+ this.shManager = new CoreShaderManager(this);
227
+
228
+ this.defShaderNode = this.renderer.getDefaultShaderNode();
229
+ this.calculateTextureCoord = this.renderer.getTextureCoords !== undefined;
230
+
231
+ const renderMode = this.renderer.mode || 'webgl';
232
+
233
+ this.createDefaultTexture();
234
+ setPremultiplyMode(renderMode);
235
+
236
+ // Must do this after renderer is created
237
+ this.txManager.renderer = this.renderer;
238
+
239
+ // Create text renderers
240
+ this.hasOnlyOneFontEngine = fontEngines.length === 1;
241
+ this.hasOnlyCanvasFontEngine =
242
+ fontEngines.length === 1 && fontEngines[0]!.type === 'canvas';
243
+ this.hasCanvasEngine = false;
244
+ this.singleFontEngine = this.hasOnlyOneFontEngine
245
+ ? (fontEngines[0] as TextRenderer)
246
+ : null;
247
+ this.singleFontHandler = this.hasOnlyOneFontEngine
248
+ ? (fontEngines[0]?.font as FontHandler)
249
+ : null;
250
+
251
+ if (this.singleFontEngine === null) {
252
+ // Multiple font engines case
253
+ // Filter out incompatible engines first
254
+ const compatibleEngines = fontEngines.filter(
255
+ (fontEngine: TextRenderer) => {
256
+ const type = fontEngine.type;
257
+
258
+ if (type === 'sdf' && renderMode === 'canvas') {
259
+ console.warn(
260
+ 'MsdfTextRenderer is not compatible with Canvas renderer. Skipping...',
261
+ );
262
+ return false;
263
+ }
264
+
265
+ if (type === 'canvas') {
266
+ this.hasCanvasEngine = true;
267
+ }
268
+
269
+ return true;
270
+ },
271
+ );
272
+
273
+ // Sort engines: SDF first, Canvas last, others in between
274
+ const sortedEngines = compatibleEngines.sort(
275
+ (a: TextRenderer, b: TextRenderer) => {
276
+ if (a.type === 'sdf') return -1;
277
+ if (b.type === 'sdf') return 1;
278
+ if (a.type === 'canvas') return 1;
279
+ if (b.type === 'canvas') return -1;
280
+ return 0;
281
+ },
282
+ );
283
+
284
+ // Initialize engines in sorted order
285
+ sortedEngines.forEach((fontEngine: TextRenderer) => {
286
+ const type = fontEngine.type;
287
+
288
+ // Add to map for type-based access
289
+ this.textRenderers[type] = fontEngine;
290
+ this.textRenderers[type].init(this);
291
+
292
+ this.fontHandlers[type] = fontEngine.font;
293
+ });
294
+ } else {
295
+ // Single font engine case - initialize it directly
296
+ const fontEngine = this.singleFontEngine;
297
+ const type = fontEngine.type;
298
+
299
+ // Check compatibility
300
+ if (type === 'sdf' && renderMode === 'canvas') {
301
+ console.warn(
302
+ 'MsdfTextRenderer is not compatible with Canvas renderer. Skipping...',
303
+ );
304
+ } else {
305
+ if (type === 'canvas') {
306
+ this.hasCanvasEngine = true;
307
+ }
308
+
309
+ // Add to map for type-based access
310
+ this.textRenderers[type] = fontEngine;
311
+ this.fontHandlers[type] = fontEngine.font;
312
+ this.textRenderers[type].init(this);
313
+ }
314
+ }
315
+
316
+ if (Object.keys(this.textRenderers).length === 0) {
317
+ console.warn('No text renderers available. Your text will not render.');
318
+ }
319
+
320
+ // create root node
321
+ const rootNode = new CoreNode(this, {
322
+ x: 0,
323
+ y: 0,
324
+ width: appWidth,
325
+ height: appHeight,
326
+ alpha: 1,
327
+ autosize: false,
328
+ boundsMargin: null,
329
+ clipping: false,
330
+ color: 0x00000000,
331
+ colorTop: 0x00000000,
332
+ colorBottom: 0x00000000,
333
+ colorLeft: 0x00000000,
334
+ colorRight: 0x00000000,
335
+ colorTl: 0x00000000,
336
+ colorTr: 0x00000000,
337
+ colorBl: 0x00000000,
338
+ colorBr: 0x00000000,
339
+ zIndex: 0,
340
+ zIndexLocked: 0,
341
+ scaleX: 1,
342
+ scaleY: 1,
343
+ mountX: 0,
344
+ mountY: 0,
345
+ mount: 0,
346
+ pivot: 0.5,
347
+ pivotX: 0.5,
348
+ pivotY: 0.5,
349
+ rotation: 0,
350
+ parent: null,
351
+ texture: null,
352
+ textureOptions: {},
353
+ shader: this.defShaderNode,
354
+ rtt: false,
355
+ src: null,
356
+ scale: 1,
357
+ strictBounds: this.strictBounds,
358
+ });
359
+
360
+ this.root = rootNode;
361
+
362
+ // execute platform start loop
363
+ if (autoStart === true) {
364
+ this.platform.startLoop(this);
365
+ }
366
+ }
367
+
368
+ setClearColor(color: number) {
369
+ this.clearColor = color;
370
+ this.renderer.updateClearColor(color);
371
+ this.renderRequested = true;
372
+ }
373
+
374
+ /**
375
+ * Update the target frame time based on the current targetFPS setting
376
+ *
377
+ * @remarks
378
+ * This should be called whenever the targetFPS option is changed
379
+ * to ensure targetFrameTime stays in sync.
380
+ * targetFPS of 0 means no throttling (targetFrameTime = 0)
381
+ * targetFPS > 0 means throttle to 1000/targetFPS milliseconds
382
+ */
383
+ updateTargetFrameTime() {
384
+ this.targetFrameTime =
385
+ this.options.targetFPS > 0 ? 1000 / this.options.targetFPS : 0;
386
+ }
387
+
388
+ updateFrameTime() {
389
+ const newFrameTime = this.platform!.getTimeStamp();
390
+ this.lastFrameTime = this.currentFrameTime;
391
+ this.currentFrameTime = newFrameTime;
392
+ this.deltaTime = !this.lastFrameTime
393
+ ? 100 / 6
394
+ : newFrameTime - this.lastFrameTime;
395
+ this.txManager.frameTime = newFrameTime;
396
+ this.txMemManager.frameTime = newFrameTime;
397
+
398
+ // This event is emitted at the beginning of the frame (before any updates
399
+ // or rendering), so no need to to use `stage.queueFrameEvent` here.
400
+ this.eventBus.emit('frameTick', {
401
+ time: this.currentFrameTime,
402
+ delta: this.deltaTime,
403
+ });
404
+ }
405
+
406
+ /**
407
+ * Create default PixelTexture
408
+ */
409
+ createDefaultTexture() {
410
+ (this.defaultTexture as ColorTexture) = this.txManager.createTexture(
411
+ 'ColorTexture',
412
+ {
413
+ color: 0xffffffff,
414
+ },
415
+ );
416
+
417
+ assertTruthy(this.defaultTexture instanceof ColorTexture);
418
+ this.txManager.loadTexture(this.defaultTexture, true);
419
+
420
+ // Mark the default texture as ALWAYS renderable
421
+ // This prevents it from ever being cleaned up.
422
+ // Fixes https://github.com/lightning-js/renderer/issues/262
423
+ this.defaultTexture.setRenderableOwner(this, true);
424
+
425
+ // When the default texture is loaded, request a render in case the
426
+ // RAF is paused. Fixes: https://github.com/lightning-js/renderer/issues/123
427
+ this.defaultTexture.once('loaded', () => {
428
+ this.requestRender();
429
+ });
430
+ }
431
+
432
+ /**
433
+ * Update animations
434
+ */
435
+ updateAnimations() {
436
+ const { animationManager } = this;
437
+ if (!this.root) {
438
+ return;
439
+ }
440
+ // step animation
441
+ animationManager.update(this.deltaTime);
442
+ }
443
+
444
+ /**
445
+ * Check if the scene has updates
446
+ */
447
+ hasSceneUpdates() {
448
+ return (
449
+ !!this.root.updateType ||
450
+ this.renderRequested ||
451
+ this.txManager.hasUpdates()
452
+ );
453
+ }
454
+
455
+ /**
456
+ * Start a new frame draw
457
+ */
458
+ drawFrame() {
459
+ const { renderer, renderRequested, root } = this;
460
+ const txMemManager = this.txMemManager;
461
+
462
+ // Update tree if needed
463
+ if (root.updateType !== 0) {
464
+ root.update(this.deltaTime, root.clippingRect);
465
+ }
466
+
467
+ // Process some textures asynchronously but don't block the frame
468
+ // Use a background task to prevent frame drops
469
+ this.txManager
470
+ .processSome(this.options.textureProcessingTimeLimit)
471
+ .catch((err) => {
472
+ console.error('Error processing textures:', err);
473
+ });
474
+
475
+ // Reset render operations and clear the canvas
476
+ renderer.reset();
477
+
478
+ // Check if we need to cleanup textures
479
+ if (txMemManager.criticalCleanupRequested === true) {
480
+ txMemManager.cleanup(false);
481
+
482
+ if (txMemManager.criticalCleanupRequested === true) {
483
+ // If we still need to cleanup, request another but aggressive cleanup
484
+ txMemManager.cleanup(true);
485
+ }
486
+ }
487
+
488
+ // If we have RTT nodes draw them first
489
+ // So we can use them as textures in the main scene
490
+ if (renderer.rttNodes.length > 0) {
491
+ renderer.renderRTTNodes();
492
+ }
493
+
494
+ // Fill quads buffer
495
+ this.addQuads(this.root);
496
+
497
+ // Perform render pass
498
+ renderer.render();
499
+
500
+ this.calculateFps();
501
+ this.calculateQuads();
502
+
503
+ // Reset renderRequested flag if it was set
504
+ if (renderRequested === true) {
505
+ this.renderRequested = false;
506
+ }
507
+ }
508
+
509
+ /**
510
+ * Queue an event to be emitted after the current/next frame is rendered
511
+ *
512
+ * @remarks
513
+ * When we are operating in the context of the render loop, we may want to
514
+ * emit events that are related to the current frame. However, we generally do
515
+ * NOT want to emit events directly in the middle of the render loop, since
516
+ * this could enable event handlers to modify the scene graph and cause
517
+ * unexpected behavior. Instead, we queue up events to be emitted and then
518
+ * flush the queue after the frame has been rendered.
519
+ *
520
+ * @param name
521
+ * @param data
522
+ */
523
+ queueFrameEvent(name: string, data: unknown) {
524
+ this.frameEventQueue.push([name, data]);
525
+ }
526
+
527
+ /**
528
+ * Emit all queued frame events
529
+ *
530
+ * @remarks
531
+ * This method should be called after the frame has been rendered to emit
532
+ * all events that were queued during the frame.
533
+ *
534
+ * See {@link queueFrameEvent} for more information.
535
+ */
536
+ flushFrameEvents() {
537
+ for (const [name, data] of this.frameEventQueue) {
538
+ this.eventBus.emit(name, data);
539
+ }
540
+ this.frameEventQueue = [];
541
+ }
542
+
543
+ calculateFps() {
544
+ // If there's an FPS update interval, emit the FPS update event
545
+ // when the specified interval has elapsed.
546
+ const { fpsUpdateInterval } = this.options;
547
+ if (fpsUpdateInterval) {
548
+ this.fpsNumFrames++;
549
+ this.fpsElapsedTime += this.deltaTime;
550
+ if (this.fpsElapsedTime >= fpsUpdateInterval) {
551
+ const fps = Math.round(
552
+ (this.fpsNumFrames * 1000) / this.fpsElapsedTime,
553
+ );
554
+ this.fpsNumFrames = 0;
555
+ this.fpsElapsedTime = 0;
556
+ this.queueFrameEvent('fpsUpdate', {
557
+ fps,
558
+ contextSpyData: this.contextSpy?.getData() ?? null,
559
+ } satisfies FpsUpdatePayload);
560
+ this.contextSpy?.reset();
561
+ }
562
+ }
563
+ }
564
+
565
+ calculateQuads() {
566
+ const quads = this.renderer.getQuadCount();
567
+ if (quads && quads !== this.numQuadsRendered) {
568
+ this.numQuadsRendered = quads;
569
+ this.queueFrameEvent('quadsUpdate', {
570
+ quads,
571
+ } satisfies QuadsUpdatePayload);
572
+ }
573
+ }
574
+
575
+ addQuads(node: CoreNode) {
576
+ assertTruthy(this.renderer);
577
+
578
+ // If the node is renderable and has a loaded texture, render it
579
+ if (node.isRenderable === true) {
580
+ node.renderQuads(this.renderer);
581
+ }
582
+
583
+ for (let i = 0; i < node.children.length; i++) {
584
+ const child = node.children[i];
585
+
586
+ if (child === undefined) {
587
+ continue;
588
+ }
589
+
590
+ if (
591
+ child.worldAlpha === 0 ||
592
+ (child.strictBounds === true &&
593
+ child.renderState === CoreNodeRenderState.OutOfBounds)
594
+ ) {
595
+ continue;
596
+ }
597
+
598
+ this.addQuads(child);
599
+ }
600
+ }
601
+
602
+ /**
603
+ * Request a render pass without forcing an update
604
+ */
605
+ requestRender() {
606
+ this.renderRequested = true;
607
+ }
608
+
609
+ /**
610
+ * Given a font name, and possible renderer override, return the best compatible text renderer.
611
+ *
612
+ * @remarks
613
+ * Will try to return a canvas renderer if no other suitable renderer can be resolved.
614
+ *
615
+ * @param fontFamily
616
+ * @param textRendererOverride
617
+ * @returns
618
+ */
619
+ resolveTextRenderer(
620
+ trProps: TrProps,
621
+ textRendererOverride: keyof TextRenderers | null = null,
622
+ ): TextRenderer | null {
623
+ // If we have an overide, return it
624
+ if (textRendererOverride !== null) {
625
+ const overrideKey = String(textRendererOverride);
626
+ if (this.textRenderers[overrideKey] === undefined) {
627
+ console.warn(`Text renderer override '${overrideKey}' not found.`);
628
+ return null;
629
+ }
630
+
631
+ return this.textRenderers[overrideKey];
632
+ }
633
+
634
+ // If we have only one font engine early return it
635
+ if (this.singleFontEngine !== null) {
636
+ // If we have only one font engine and its the canvas engine, we can just return it
637
+ if (this.hasOnlyCanvasFontEngine === true) {
638
+ return this.singleFontEngine;
639
+ }
640
+
641
+ // If we have only one font engine and it can render the font, return it
642
+ if (this.singleFontHandler?.canRenderFont(trProps) === true) {
643
+ return this.singleFontEngine;
644
+ }
645
+
646
+ // If we have only one font engine and it cannot render the font, return null
647
+ console.warn(`Text renderer cannot render font`, trProps);
648
+
649
+ return null;
650
+ }
651
+
652
+ // Multi font handling - If we have multiple font engines, we need to resolve the best one
653
+
654
+ // First check SDF
655
+ if (this.fontHandlers['sdf']?.canRenderFont(trProps) === true) {
656
+ return this.textRenderers.sdf || null;
657
+ }
658
+
659
+ // If we have a canvas engine, we can return it (it can render all fonts)
660
+ if (this.hasCanvasEngine === true) {
661
+ return this.textRenderers.canvas || null;
662
+ }
663
+
664
+ // If we have no font engines, return null
665
+ console.warn('No text renderers available. Your text will not render.');
666
+ return null;
667
+ }
668
+
669
+ createNode(props: Partial<CoreNodeProps>) {
670
+ const resolvedProps = this.resolveNodeDefaults(props);
671
+ return new CoreNode(this, resolvedProps);
672
+ }
673
+
674
+ createTextNode(props: Partial<CoreTextNodeProps>) {
675
+ const fontSize = props.fontSize || 16;
676
+ const resolvedProps = Object.assign(this.resolveNodeDefaults(props), {
677
+ text: props.text || '',
678
+ textRendererOverride: props.textRendererOverride || null,
679
+ fontSize,
680
+ fontFamily: props.fontFamily || 'sans-serif',
681
+ fontStyle: props.fontStyle || 'normal',
682
+ textAlign: props.textAlign || 'left',
683
+ offsetY: props.offsetY || 0,
684
+ letterSpacing: props.letterSpacing || 0,
685
+ lineHeight: props.lineHeight || 0,
686
+ maxLines: props.maxLines || 0,
687
+ textBaseline: props.textBaseline || 'alphabetic',
688
+ verticalAlign: props.verticalAlign || 'middle',
689
+ overflowSuffix: props.overflowSuffix || '...',
690
+ wordBreak: props.wordBreak || 'normal',
691
+ maxWidth: props.maxWidth || 0,
692
+ maxHeight: props.maxHeight || 0,
693
+ forceLoad: props.forceLoad || false,
694
+ });
695
+
696
+ const resolvedTextRenderer = this.resolveTextRenderer(
697
+ resolvedProps,
698
+ resolvedProps.textRendererOverride as keyof TextRenderers | null,
699
+ );
700
+
701
+ if (!resolvedTextRenderer) {
702
+ throw new Error(
703
+ `No compatible text renderer found for ${resolvedProps.fontFamily}`,
704
+ );
705
+ }
706
+
707
+ return new CoreTextNode(this, resolvedProps, resolvedTextRenderer);
708
+ }
709
+
710
+ setBoundsMargin(value: number | [number, number, number, number]) {
711
+ this.boundsMargin = Array.isArray(value)
712
+ ? value
713
+ : [value, value, value, value];
714
+
715
+ this.root.setUpdateType(UpdateType.RenderBounds);
716
+ }
717
+
718
+ /**
719
+ * Update the viewport bounds
720
+ */
721
+ updateViewportBounds() {
722
+ const { appWidth, appHeight } = this.options;
723
+ this.strictBound = createBound(0, 0, appWidth, appHeight);
724
+ this.preloadBound = createPreloadBounds(
725
+ this.strictBound,
726
+ this.boundsMargin,
727
+ );
728
+ this.root.setUpdateType(UpdateType.RenderBounds | UpdateType.Children);
729
+ this.root.childUpdateType |= UpdateType.RenderBounds;
730
+ }
731
+
732
+ /** Find all nodes at a given point
733
+ * @param data
734
+ */
735
+ findNodesAtPoint(data: Point): CoreNode[] {
736
+ const x = data.x / this.options.deviceLogicalPixelRatio;
737
+ const y = data.y / this.options.deviceLogicalPixelRatio;
738
+ const nodes: CoreNode[] = [];
739
+ for (const node of this.interactiveNodes) {
740
+ if (node.isRenderable === false) {
741
+ continue;
742
+ }
743
+ if (pointInBound(x, y, node.renderBound!) === true) {
744
+ nodes.push(node);
745
+ }
746
+ }
747
+ return nodes;
748
+ }
749
+
750
+ /**
751
+ * Find the top node at a given point
752
+ * @param data
753
+ * @returns
754
+ */
755
+ getNodeFromPosition(data: Point): CoreNode | null {
756
+ const nodes: CoreNode[] = this.findNodesAtPoint(data);
757
+ if (nodes.length === 0) {
758
+ return null;
759
+ }
760
+ let topNode = nodes[0] as CoreNode;
761
+ for (let i = 0; i < nodes.length; i++) {
762
+ if (nodes[i]!.zIndex > topNode.zIndex) {
763
+ topNode = nodes[i]!;
764
+ }
765
+ }
766
+ return topNode || null;
767
+ }
768
+
769
+ /**
770
+ * Resolves the default property values for a Node
771
+ *
772
+ * @remarks
773
+ * This method is used internally by the RendererMain to resolve the default
774
+ * property values for a Node. It is exposed publicly so that it can be used
775
+ * by Core Driver implementations.
776
+ *
777
+ * @param props
778
+ * @returns
779
+ */
780
+ protected resolveNodeDefaults(props: Partial<CoreNodeProps>): CoreNodeProps {
781
+ const {
782
+ colorTop: top,
783
+ colorBottom: bottom,
784
+ colorLeft: left,
785
+ colorRight: right,
786
+ } = props;
787
+
788
+ const color = props.color ?? 0xffffffff;
789
+ const colorTop = top ?? color;
790
+ const colorBottom = bottom ?? color;
791
+ const colorLeft = left ?? color;
792
+ const colorRight = right ?? color;
793
+
794
+ const colorTl = props.colorTl ?? top ?? left ?? color;
795
+ const colorTr = props.colorTr ?? top ?? right ?? color;
796
+ const colorBl = props.colorBl ?? bottom ?? left ?? color;
797
+ const colorBr = props.colorBr ?? bottom ?? right ?? color;
798
+
799
+ const scale = props.scale ?? null;
800
+ const mount = props.mount ?? 0;
801
+ const pivot = props.pivot ?? 0.5;
802
+
803
+ const data = this.options.inspector
804
+ ? santizeCustomDataMap(props.data ?? {})
805
+ : {};
806
+
807
+ return {
808
+ x: props.x ?? 0,
809
+ y: props.y ?? 0,
810
+ width: props.width ?? 0,
811
+ height: props.height ?? 0,
812
+ alpha: props.alpha ?? 1,
813
+ autosize: props.autosize ?? false,
814
+ boundsMargin: props.boundsMargin ?? null,
815
+ clipping: props.clipping ?? false,
816
+ color,
817
+ colorTop,
818
+ colorBottom,
819
+ colorLeft,
820
+ colorRight,
821
+ colorTl,
822
+ colorTr,
823
+ colorBl,
824
+ colorBr,
825
+ zIndex: props.zIndex ?? 0,
826
+ zIndexLocked: props.zIndexLocked ?? 0,
827
+ parent: props.parent ?? null,
828
+ texture: props.texture ?? null,
829
+ textureOptions: props.textureOptions ?? {},
830
+ shader: props.shader ?? this.defShaderNode,
831
+ src: props.src ?? null,
832
+ srcHeight: props.srcHeight,
833
+ srcWidth: props.srcWidth,
834
+ srcX: props.srcX,
835
+ srcY: props.srcY,
836
+ scale,
837
+ scaleX: props.scaleX ?? scale ?? 1,
838
+ scaleY: props.scaleY ?? scale ?? 1,
839
+ mount,
840
+ mountX: props.mountX ?? mount,
841
+ mountY: props.mountY ?? mount,
842
+ pivot,
843
+ pivotX: props.pivotX ?? pivot,
844
+ pivotY: props.pivotY ?? pivot,
845
+ rotation: props.rotation ?? 0,
846
+ rtt: props.rtt ?? false,
847
+ data,
848
+ imageType: props.imageType,
849
+ interactive: props.interactive ?? false,
850
+ strictBounds: props.strictBounds ?? this.strictBounds,
851
+ };
852
+ }
853
+
854
+ /**
855
+ * Cleanup Orphaned Textures
856
+ *
857
+ * @remarks
858
+ * This method is used to cleanup orphaned textures that are no longer in use.
859
+ */
860
+ cleanup(aggressive: boolean) {
861
+ this.txMemManager.cleanup(aggressive);
862
+ }
863
+
864
+ set clearColor(value: number) {
865
+ this.renderer.updateClearColor(value);
866
+ this.renderRequested = true;
867
+ this.clrColor = value;
868
+ }
869
+
870
+ get clearColor() {
871
+ return this.clrColor;
872
+ }
873
+
874
+ /**
875
+ * Load a font using a specific text renderer type
876
+ *
877
+ * @remarks
878
+ * This method allows consumers to explicitly load fonts for a specific
879
+ * text renderer type (e.g., 'canvas', 'sdf'). Consumers must specify
880
+ * the renderer type to ensure fonts are loaded with the correct pipeline.
881
+ *
882
+ * For Canvas fonts, provide fontUrl (e.g., .ttf, .woff, .woff2)
883
+ * For SDF fonts, provide atlasUrl (image) and atlasDataUrl (JSON glyph data)
884
+ *
885
+ * @param rendererType - The type of text renderer ('canvas', 'sdf', etc.)
886
+ * @param options - Font loading options specific to the renderer type
887
+ * @returns Promise that resolves when the font is loaded
888
+ */
889
+ async loadFont(
890
+ rendererType: TextRenderers,
891
+ options: FontLoadOptions,
892
+ ): Promise<void> {
893
+ const rendererTypeKey = String(rendererType);
894
+ const fontHandler = this.fontHandlers[rendererTypeKey];
895
+
896
+ if (!fontHandler) {
897
+ throw new Error(
898
+ `Font handler for renderer type '${rendererTypeKey}' not found. Available types: ${Object.keys(
899
+ this.fontHandlers,
900
+ ).join(', ')}`,
901
+ );
902
+ }
903
+
904
+ return fontHandler.loadFont(this, options);
905
+ }
906
+ }