@lightningjs/renderer 3.0.0-beta6 → 3.0.0-beta7

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 (349) hide show
  1. package/COPYING +1 -0
  2. package/LICENSE +202 -202
  3. package/NOTICE +3 -3
  4. package/README.md +147 -147
  5. package/dist/src/core/CoreNode.d.ts +9 -0
  6. package/dist/src/core/CoreNode.js +17 -0
  7. package/dist/src/core/CoreNode.js.map +1 -1
  8. package/dist/src/core/CoreTextureManager.js +6 -0
  9. package/dist/src/core/CoreTextureManager.js.map +1 -1
  10. package/dist/src/core/Stage.d.ts +16 -0
  11. package/dist/src/core/Stage.js +39 -0
  12. package/dist/src/core/Stage.js.map +1 -1
  13. package/dist/src/core/lib/ImageWorker.js +1 -1
  14. package/dist/src/core/lib/ImageWorker.js.map +1 -1
  15. package/dist/src/core/lib/utils.d.ts +1 -0
  16. package/dist/src/core/lib/utils.js +3 -0
  17. package/dist/src/core/lib/utils.js.map +1 -1
  18. package/dist/src/core/renderers/webgl/WebGlRenderer.d.ts +1 -2
  19. package/dist/src/core/renderers/webgl/WebGlRenderer.js +1 -3
  20. package/dist/src/core/renderers/webgl/WebGlRenderer.js.map +1 -1
  21. package/dist/src/core/renderers/webgl/internal/ShaderUtils.js +35 -35
  22. package/dist/src/core/renderers/webgl/shaders/DefaultShader.js +45 -45
  23. package/dist/src/core/renderers/webgl/shaders/DefaultShaderBatched.js +61 -61
  24. package/dist/src/core/renderers/webgl/shaders/DynamicShader.js +93 -93
  25. package/dist/src/core/renderers/webgl/shaders/RoundedRectangle.js +63 -63
  26. package/dist/src/core/renderers/webgl/shaders/SdfShader.js +62 -62
  27. package/dist/src/core/renderers/webgl/shaders/effects/BorderBottomEffect.js +15 -15
  28. package/dist/src/core/renderers/webgl/shaders/effects/BorderEffect.js +6 -6
  29. package/dist/src/core/renderers/webgl/shaders/effects/BorderLeftEffect.js +15 -15
  30. package/dist/src/core/renderers/webgl/shaders/effects/BorderRightEffect.js +15 -15
  31. package/dist/src/core/renderers/webgl/shaders/effects/BorderTopEffect.js +15 -15
  32. package/dist/src/core/renderers/webgl/shaders/effects/FadeOutEffect.js +42 -42
  33. package/dist/src/core/renderers/webgl/shaders/effects/GlitchEffect.js +44 -44
  34. package/dist/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.js +3 -3
  35. package/dist/src/core/renderers/webgl/shaders/effects/HolePunchEffect.js +22 -22
  36. package/dist/src/core/renderers/webgl/shaders/effects/LinearGradientEffect.js +28 -28
  37. package/dist/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.js +10 -10
  38. package/dist/src/core/renderers/webgl/shaders/effects/RadialProgressEffect.js +37 -37
  39. package/dist/src/core/renderers/webgl/shaders/effects/RadiusEffect.js +19 -19
  40. package/dist/src/core/shaders/webgl/Border.js +82 -82
  41. package/dist/src/core/shaders/webgl/Default.js +47 -47
  42. package/dist/src/core/shaders/webgl/DefaultBatched.js +61 -61
  43. package/dist/src/core/shaders/webgl/HolePunch.js +32 -32
  44. package/dist/src/core/shaders/webgl/LinearGradient.js +36 -36
  45. package/dist/src/core/shaders/webgl/RadialGradient.js +33 -33
  46. package/dist/src/core/shaders/webgl/Rounded.js +71 -71
  47. package/dist/src/core/shaders/webgl/RoundedWithBorder.js +100 -100
  48. package/dist/src/core/shaders/webgl/RoundedWithBorderAndShadow.js +118 -118
  49. package/dist/src/core/shaders/webgl/RoundedWithShadow.js +54 -54
  50. package/dist/src/core/shaders/webgl/SdfShader.js +62 -62
  51. package/dist/src/core/shaders/webgl/Shadow.js +83 -83
  52. package/dist/src/core/temp.js +77 -0
  53. package/dist/src/core/temp.js.map +1 -0
  54. package/dist/src/core/textures/ImageTexture.js +5 -0
  55. package/dist/src/core/textures/ImageTexture.js.map +1 -1
  56. package/dist/src/main-api/Renderer.js +1 -1
  57. package/dist/src/main-api/Renderer.js.map +1 -1
  58. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  59. package/exports/canvas-shaders.ts +28 -28
  60. package/exports/canvas.ts +45 -45
  61. package/exports/index.ts +90 -90
  62. package/exports/inspector.ts +24 -24
  63. package/exports/utils.ts +44 -44
  64. package/exports/webgl-shaders.ts +28 -28
  65. package/exports/webgl.ts +50 -50
  66. package/package.json +1 -2
  67. package/src/common/CommonTypes.ts +146 -146
  68. package/src/common/EventEmitter.ts +77 -77
  69. package/src/common/IAnimationController.ts +92 -92
  70. package/src/common/IEventEmitter.ts +28 -28
  71. package/src/core/CoreNode.test.ts +202 -202
  72. package/src/core/CoreNode.ts +2495 -2469
  73. package/src/core/CoreShaderManager.ts +188 -188
  74. package/src/core/CoreTextNode.ts +448 -448
  75. package/src/core/CoreTextureManager.ts +607 -600
  76. package/src/core/Stage.ts +797 -751
  77. package/src/core/TextureMemoryManager.ts +394 -394
  78. package/src/core/animations/AnimationManager.ts +38 -38
  79. package/src/core/animations/CoreAnimation.ts +284 -284
  80. package/src/core/animations/CoreAnimationController.ts +157 -157
  81. package/src/core/lib/ContextSpy.ts +41 -41
  82. package/src/core/lib/ImageWorker.ts +286 -280
  83. package/src/core/lib/Matrix3d.ts +244 -244
  84. package/src/core/lib/RenderCoords.ts +71 -71
  85. package/src/core/lib/WebGlContextWrapper.ts +1374 -1374
  86. package/src/core/lib/textureCompression.ts +152 -152
  87. package/src/core/lib/textureSvg.ts +78 -78
  88. package/src/core/lib/utils.ts +390 -386
  89. package/src/core/lib/validateImageBitmap.ts +87 -87
  90. package/src/core/platforms/Platform.ts +77 -77
  91. package/src/core/platforms/web/WebPlatform.ts +84 -84
  92. package/src/core/renderers/CoreContextTexture.ts +43 -43
  93. package/src/core/renderers/CoreRenderOp.ts +22 -22
  94. package/src/core/renderers/CoreRenderer.ts +109 -109
  95. package/src/core/renderers/CoreShaderNode.ts +165 -165
  96. package/src/core/renderers/CoreShaderProgram.ts +23 -23
  97. package/src/core/renderers/canvas/CanvasRenderer.ts +298 -298
  98. package/src/core/renderers/canvas/CanvasShaderNode.ts +99 -99
  99. package/src/core/renderers/canvas/CanvasTexture.ts +156 -156
  100. package/src/core/renderers/canvas/internal/C2DShaderUtils.ts +220 -220
  101. package/src/core/renderers/canvas/internal/ColorUtils.ts +85 -85
  102. package/src/core/renderers/webgl/WebGlCtxRenderTexture.ts +86 -86
  103. package/src/core/renderers/webgl/WebGlCtxSubTexture.ts +50 -50
  104. package/src/core/renderers/webgl/WebGlCtxTexture.ts +301 -301
  105. package/src/core/renderers/webgl/WebGlRenderOp.ts +161 -161
  106. package/src/core/renderers/webgl/WebGlRenderer.ts +748 -750
  107. package/src/core/renderers/webgl/WebGlShaderNode.ts +437 -437
  108. package/src/core/renderers/webgl/WebGlShaderProgram.ts +318 -318
  109. package/src/core/renderers/webgl/internal/BufferCollection.ts +54 -54
  110. package/src/core/renderers/webgl/internal/RendererUtils.ts +155 -155
  111. package/src/core/renderers/webgl/internal/ShaderUtils.ts +281 -281
  112. package/src/core/renderers/webgl/internal/WebGlUtils.ts +35 -35
  113. package/src/core/shaders/canvas/Border.ts +78 -78
  114. package/src/core/shaders/canvas/HolePunch.ts +62 -62
  115. package/src/core/shaders/canvas/LinearGradient.ts +69 -69
  116. package/src/core/shaders/canvas/RadialGradient.ts +113 -113
  117. package/src/core/shaders/canvas/Rounded.ts +55 -55
  118. package/src/core/shaders/canvas/RoundedWithBorder.ts +72 -72
  119. package/src/core/shaders/canvas/RoundedWithBorderAndShadow.ts +88 -88
  120. package/src/core/shaders/canvas/RoundedWithShadow.ts +69 -69
  121. package/src/core/shaders/canvas/Shadow.ts +52 -52
  122. package/src/core/shaders/canvas/utils/render.ts +151 -151
  123. package/src/core/shaders/templates/BorderTemplate.ts +115 -115
  124. package/src/core/shaders/templates/HolePunchTemplate.ts +82 -82
  125. package/src/core/shaders/templates/LinearGradientTemplate.ts +71 -71
  126. package/src/core/shaders/templates/RadialGradientTemplate.ts +81 -81
  127. package/src/core/shaders/templates/RoundedTemplate.ts +98 -98
  128. package/src/core/shaders/templates/RoundedWithBorderAndShadowTemplate.ts +38 -38
  129. package/src/core/shaders/templates/RoundedWithBorderTemplate.ts +35 -35
  130. package/src/core/shaders/templates/RoundedWithShadowTemplate.ts +35 -35
  131. package/src/core/shaders/templates/ShadowTemplate.ts +106 -106
  132. package/src/core/shaders/templates/shaderUtils.ts +47 -47
  133. package/src/core/shaders/webgl/Border.ts +116 -116
  134. package/src/core/shaders/webgl/Default.ts +89 -89
  135. package/src/core/shaders/webgl/DefaultBatched.ts +129 -129
  136. package/src/core/shaders/webgl/HolePunch.ts +78 -78
  137. package/src/core/shaders/webgl/LinearGradient.ts +81 -81
  138. package/src/core/shaders/webgl/RadialGradient.ts +84 -84
  139. package/src/core/shaders/webgl/Rounded.ts +117 -117
  140. package/src/core/shaders/webgl/RoundedWithBorder.ts +144 -144
  141. package/src/core/shaders/webgl/RoundedWithBorderAndShadow.ts +166 -166
  142. package/src/core/shaders/webgl/RoundedWithShadow.ts +98 -98
  143. package/src/core/shaders/webgl/SdfShader.ts +134 -134
  144. package/src/core/shaders/webgl/Shadow.ts +115 -115
  145. package/src/core/text-rendering/TextRenderingUtils.ts +36 -36
  146. package/src/core/text-rendering/TextTextureRendererUtils.ts +263 -263
  147. package/src/core/text-rendering/TrFontManager.ts +183 -183
  148. package/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.ts +176 -176
  149. package/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/FontShaper.ts +139 -139
  150. package/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.test.ts +173 -173
  151. package/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.ts +171 -171
  152. package/src/core/text-rendering/font-face-types/TrFontFace.ts +187 -187
  153. package/src/core/text-rendering/font-face-types/WebTrFontFace.ts +94 -94
  154. package/src/core/text-rendering/font-face-types/utils.ts +39 -39
  155. package/src/core/text-rendering/renderers/CanvasTextRenderer.ts +514 -514
  156. package/src/core/text-rendering/renderers/LightningTextTextureRenderer.ts +863 -863
  157. package/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.ts +849 -849
  158. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/PeekableGenerator.test.ts +48 -48
  159. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/PeekableGenerator.ts +66 -66
  160. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/SpecialCodepoints.ts +52 -52
  161. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/constants.ts +32 -32
  162. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.ts +117 -117
  163. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/getUnicodeCodepoints.test.ts +133 -133
  164. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/getUnicodeCodepoints.ts +38 -38
  165. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.ts +497 -497
  166. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/measureText.test.ts +49 -49
  167. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/measureText.ts +52 -52
  168. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.test.ts +205 -205
  169. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.ts +93 -93
  170. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.ts +40 -40
  171. package/src/core/text-rendering/renderers/TextRenderer.ts +567 -567
  172. package/src/core/textures/ColorTexture.ts +102 -102
  173. package/src/core/textures/ImageTexture.ts +417 -410
  174. package/src/core/textures/NoiseTexture.ts +104 -104
  175. package/src/core/textures/RenderTexture.ts +85 -85
  176. package/src/core/textures/SubTexture.ts +205 -205
  177. package/src/core/textures/Texture.ts +358 -358
  178. package/src/core/utils.ts +227 -227
  179. package/src/env.d.ts +7 -7
  180. package/src/main-api/INode.ts +100 -100
  181. package/src/main-api/Inspector.ts +522 -522
  182. package/src/main-api/Renderer.ts +673 -673
  183. package/src/main-api/utils.ts +45 -45
  184. package/src/utils.ts +267 -267
  185. package/dist/exports/core-api.d.ts +0 -74
  186. package/dist/exports/core-api.js +0 -96
  187. package/dist/exports/core-api.js.map +0 -1
  188. package/dist/exports/main-api.d.ts +0 -30
  189. package/dist/exports/main-api.js +0 -45
  190. package/dist/exports/main-api.js.map +0 -1
  191. package/dist/src/core/CoreExtension.d.ts +0 -12
  192. package/dist/src/core/CoreExtension.js +0 -29
  193. package/dist/src/core/CoreExtension.js.map +0 -1
  194. package/dist/src/core/CoreStuff.js +0 -138
  195. package/dist/src/core/CoreStuff.js.map +0 -1
  196. package/dist/src/core/CoreTexturizer.d.ts +0 -14
  197. package/dist/src/core/CoreTexturizer.js +0 -47
  198. package/dist/src/core/CoreTexturizer.js.map +0 -1
  199. package/dist/src/core/LngNode.d.ts +0 -736
  200. package/dist/src/core/LngNode.js +0 -1174
  201. package/dist/src/core/LngNode.js.map +0 -1
  202. package/dist/src/core/Matrix2DContext.d.ts +0 -15
  203. package/dist/src/core/Matrix2DContext.js +0 -45
  204. package/dist/src/core/Matrix2DContext.js.map +0 -1
  205. package/dist/src/core/ShaderNode.d.ts +0 -10
  206. package/dist/src/core/ShaderNode.js +0 -30
  207. package/dist/src/core/ShaderNode.js.map +0 -1
  208. package/dist/src/core/TextNode.d.ts +0 -103
  209. package/dist/src/core/TextNode.js +0 -331
  210. package/dist/src/core/TextNode.js.map +0 -1
  211. package/dist/src/core/lib/Coords.d.ts +0 -14
  212. package/dist/src/core/lib/Coords.js +0 -55
  213. package/dist/src/core/lib/Coords.js.map +0 -1
  214. package/dist/src/core/lib/glm/common.d.ts +0 -162
  215. package/dist/src/core/lib/glm/common.js +0 -81
  216. package/dist/src/core/lib/glm/common.js.map +0 -1
  217. package/dist/src/core/lib/glm/index.d.ts +0 -11
  218. package/dist/src/core/lib/glm/index.js +0 -30
  219. package/dist/src/core/lib/glm/index.js.map +0 -1
  220. package/dist/src/core/lib/glm/mat2.d.ts +0 -219
  221. package/dist/src/core/lib/glm/mat2.js +0 -396
  222. package/dist/src/core/lib/glm/mat2.js.map +0 -1
  223. package/dist/src/core/lib/glm/mat2d.d.ts +0 -237
  224. package/dist/src/core/lib/glm/mat2d.js +0 -442
  225. package/dist/src/core/lib/glm/mat2d.js.map +0 -1
  226. package/dist/src/core/lib/glm/mat3.d.ts +0 -283
  227. package/dist/src/core/lib/glm/mat3.js +0 -680
  228. package/dist/src/core/lib/glm/mat3.js.map +0 -1
  229. package/dist/src/core/lib/glm/mat4.d.ts +0 -550
  230. package/dist/src/core/lib/glm/mat4.js +0 -1802
  231. package/dist/src/core/lib/glm/mat4.js.map +0 -1
  232. package/dist/src/core/lib/glm/quat.d.ts +0 -363
  233. package/dist/src/core/lib/glm/quat.js +0 -693
  234. package/dist/src/core/lib/glm/quat.js.map +0 -1
  235. package/dist/src/core/lib/glm/quat2.d.ts +0 -356
  236. package/dist/src/core/lib/glm/quat2.js +0 -754
  237. package/dist/src/core/lib/glm/quat2.js.map +0 -1
  238. package/dist/src/core/lib/glm/vec2.d.ts +0 -365
  239. package/dist/src/core/lib/glm/vec2.js +0 -569
  240. package/dist/src/core/lib/glm/vec2.js.map +0 -1
  241. package/dist/src/core/lib/glm/vec3.d.ts +0 -406
  242. package/dist/src/core/lib/glm/vec3.js +0 -720
  243. package/dist/src/core/lib/glm/vec3.js.map +0 -1
  244. package/dist/src/core/lib/glm/vec4.d.ts +0 -330
  245. package/dist/src/core/lib/glm/vec4.js +0 -608
  246. package/dist/src/core/lib/glm/vec4.js.map +0 -1
  247. package/dist/src/core/renderers/CoreShaderManager.d.ts +0 -19
  248. package/dist/src/core/renderers/CoreShaderManager.js +0 -33
  249. package/dist/src/core/renderers/CoreShaderManager.js.map +0 -1
  250. package/dist/src/core/renderers/webgl/WebGlCoreShaderManager.d.ts +0 -27
  251. package/dist/src/core/renderers/webgl/WebGlCoreShaderManager.js +0 -82
  252. package/dist/src/core/renderers/webgl/WebGlCoreShaderManager.js.map +0 -1
  253. package/dist/src/core/renderers/webgl/WebGlCoreShaderProgram.d.ts +0 -11
  254. package/dist/src/core/renderers/webgl/WebGlCoreShaderProgram.js +0 -34
  255. package/dist/src/core/renderers/webgl/WebGlCoreShaderProgram.js.map +0 -1
  256. package/dist/src/core/scene/Scene.d.ts +0 -59
  257. package/dist/src/core/scene/Scene.js +0 -106
  258. package/dist/src/core/scene/Scene.js.map +0 -1
  259. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.d.ts +0 -20
  260. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.js +0 -55
  261. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.js.map +0 -1
  262. package/dist/src/main-api/ICoreDriver.d.ts +0 -27
  263. package/dist/src/main-api/ICoreDriver.js +0 -20
  264. package/dist/src/main-api/ICoreDriver.js.map +0 -1
  265. package/dist/src/main-api/IRenderDriver.d.ts +0 -20
  266. package/dist/src/main-api/IRenderDriver.js +0 -20
  267. package/dist/src/main-api/IRenderDriver.js.map +0 -1
  268. package/dist/src/main-api/IShaderController.d.ts +0 -14
  269. package/dist/src/main-api/IShaderController.js +0 -30
  270. package/dist/src/main-api/IShaderController.js.map +0 -1
  271. package/dist/src/main-api/IShaderNode.d.ts +0 -17
  272. package/dist/src/main-api/IShaderNode.js +0 -19
  273. package/dist/src/main-api/IShaderNode.js.map +0 -1
  274. package/dist/src/main-api/RendererMain.d.ts +0 -375
  275. package/dist/src/main-api/RendererMain.js +0 -365
  276. package/dist/src/main-api/RendererMain.js.map +0 -1
  277. package/dist/src/main-api/texture-usage-trackers/FinalizationRegistryTextureUsageTracker.d.ts +0 -9
  278. package/dist/src/main-api/texture-usage-trackers/FinalizationRegistryTextureUsageTracker.js +0 -38
  279. package/dist/src/main-api/texture-usage-trackers/FinalizationRegistryTextureUsageTracker.js.map +0 -1
  280. package/dist/src/main-api/texture-usage-trackers/ManualCountTextureUsageTracker.d.ts +0 -56
  281. package/dist/src/main-api/texture-usage-trackers/ManualCountTextureUsageTracker.js +0 -101
  282. package/dist/src/main-api/texture-usage-trackers/ManualCountTextureUsageTracker.js.map +0 -1
  283. package/dist/src/main-api/texture-usage-trackers/TextureUsageTracker.d.ts +0 -32
  284. package/dist/src/main-api/texture-usage-trackers/TextureUsageTracker.js +0 -28
  285. package/dist/src/main-api/texture-usage-trackers/TextureUsageTracker.js.map +0 -1
  286. package/dist/src/render-drivers/main/MainCoreDriver.d.ts +0 -24
  287. package/dist/src/render-drivers/main/MainCoreDriver.js +0 -118
  288. package/dist/src/render-drivers/main/MainCoreDriver.js.map +0 -1
  289. package/dist/src/render-drivers/main/MainOnlyNode.d.ts +0 -99
  290. package/dist/src/render-drivers/main/MainOnlyNode.js +0 -396
  291. package/dist/src/render-drivers/main/MainOnlyNode.js.map +0 -1
  292. package/dist/src/render-drivers/main/MainOnlyShaderController.d.ts +0 -6
  293. package/dist/src/render-drivers/main/MainOnlyShaderController.js +0 -15
  294. package/dist/src/render-drivers/main/MainOnlyShaderController.js.map +0 -1
  295. package/dist/src/render-drivers/main/MainOnlyShaderNode.d.ts +0 -7
  296. package/dist/src/render-drivers/main/MainOnlyShaderNode.js +0 -34
  297. package/dist/src/render-drivers/main/MainOnlyShaderNode.js.map +0 -1
  298. package/dist/src/render-drivers/main/MainOnlyTextNode.d.ts +0 -47
  299. package/dist/src/render-drivers/main/MainOnlyTextNode.js +0 -205
  300. package/dist/src/render-drivers/main/MainOnlyTextNode.js.map +0 -1
  301. package/dist/src/render-drivers/main/MainRenderDriver.d.ts +0 -17
  302. package/dist/src/render-drivers/main/MainRenderDriver.js +0 -88
  303. package/dist/src/render-drivers/main/MainRenderDriver.js.map +0 -1
  304. package/dist/src/render-drivers/threadx/NodeStruct.d.ts +0 -90
  305. package/dist/src/render-drivers/threadx/NodeStruct.js +0 -281
  306. package/dist/src/render-drivers/threadx/NodeStruct.js.map +0 -1
  307. package/dist/src/render-drivers/threadx/SharedNode.d.ts +0 -39
  308. package/dist/src/render-drivers/threadx/SharedNode.js +0 -60
  309. package/dist/src/render-drivers/threadx/SharedNode.js.map +0 -1
  310. package/dist/src/render-drivers/threadx/TextNodeStruct.d.ts +0 -44
  311. package/dist/src/render-drivers/threadx/TextNodeStruct.js +0 -201
  312. package/dist/src/render-drivers/threadx/TextNodeStruct.js.map +0 -1
  313. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.d.ts +0 -28
  314. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js +0 -234
  315. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js.map +0 -1
  316. package/dist/src/render-drivers/threadx/ThreadXMainAnimationController.d.ts +0 -20
  317. package/dist/src/render-drivers/threadx/ThreadXMainAnimationController.js +0 -84
  318. package/dist/src/render-drivers/threadx/ThreadXMainAnimationController.js.map +0 -1
  319. package/dist/src/render-drivers/threadx/ThreadXMainNode.d.ts +0 -44
  320. package/dist/src/render-drivers/threadx/ThreadXMainNode.js +0 -154
  321. package/dist/src/render-drivers/threadx/ThreadXMainNode.js.map +0 -1
  322. package/dist/src/render-drivers/threadx/ThreadXMainShaderController.d.ts +0 -6
  323. package/dist/src/render-drivers/threadx/ThreadXMainShaderController.js +0 -16
  324. package/dist/src/render-drivers/threadx/ThreadXMainShaderController.js.map +0 -1
  325. package/dist/src/render-drivers/threadx/ThreadXMainShaderNode.d.ts +0 -7
  326. package/dist/src/render-drivers/threadx/ThreadXMainShaderNode.js +0 -15
  327. package/dist/src/render-drivers/threadx/ThreadXMainShaderNode.js.map +0 -1
  328. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.d.ts +0 -28
  329. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.js +0 -55
  330. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.js.map +0 -1
  331. package/dist/src/render-drivers/threadx/ThreadXRenderDriver.d.ts +0 -21
  332. package/dist/src/render-drivers/threadx/ThreadXRenderDriver.js +0 -198
  333. package/dist/src/render-drivers/threadx/ThreadXRenderDriver.js.map +0 -1
  334. package/dist/src/render-drivers/threadx/ThreadXRendererMessage.d.ts +0 -70
  335. package/dist/src/render-drivers/threadx/ThreadXRendererMessage.js +0 -32
  336. package/dist/src/render-drivers/threadx/ThreadXRendererMessage.js.map +0 -1
  337. package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.d.ts +0 -19
  338. package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js +0 -177
  339. package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js.map +0 -1
  340. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.d.ts +0 -27
  341. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js +0 -108
  342. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js.map +0 -1
  343. package/dist/src/render-drivers/threadx/worker/renderer.d.ts +0 -1
  344. package/dist/src/render-drivers/threadx/worker/renderer.js +0 -145
  345. package/dist/src/render-drivers/threadx/worker/renderer.js.map +0 -1
  346. package/dist/src/render-drivers/utils.d.ts +0 -12
  347. package/dist/src/render-drivers/utils.js +0 -69
  348. package/dist/src/render-drivers/utils.js.map +0 -1
  349. /package/dist/src/core/{CoreStuff.d.ts → temp.d.ts} +0 -0
@@ -1,514 +1,514 @@
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 { EventEmitter } from '../../../common/EventEmitter.js';
21
- import { assertTruthy } from '../../../utils.js';
22
- import type { CoreNode } from '../../CoreNode.js';
23
- import type { CoreTextNode } from '../../CoreTextNode.js';
24
- import type { Stage } from '../../Stage.js';
25
- import {
26
- getNormalizedRgbaComponents,
27
- getNormalizedAlphaComponent,
28
- } from '../../lib/utils.js';
29
- import { type FontFamilyMap } from '../TrFontManager.js';
30
- import type { TrFontFace } from '../font-face-types/TrFontFace.js';
31
- import { WebTrFontFace } from '../font-face-types/WebTrFontFace.js';
32
- import {
33
- LightningTextTextureRenderer,
34
- type RenderInfo,
35
- } from './LightningTextTextureRenderer.js';
36
- import {
37
- TextRenderer,
38
- type TextRendererState,
39
- type TrFontProps,
40
- type TrPropSetters,
41
- type TrProps,
42
- } from './TextRenderer.js';
43
-
44
- const resolvedGlobal = typeof self === 'undefined' ? globalThis : self;
45
-
46
- /**
47
- * Global font set regardless of if run in the main thread or a web worker
48
- */
49
- const globalFontSet: FontFaceSet = (resolvedGlobal.document?.fonts ||
50
- (resolvedGlobal as any).fonts) as FontFaceSet;
51
-
52
- declare module './TextRenderer.js' {
53
- interface TextRendererMap {
54
- canvas: CanvasTextRenderer;
55
- }
56
- }
57
-
58
- function getFontCssString(props: TrProps): string {
59
- const { fontFamily, fontStyle, fontWeight, fontStretch, fontSize } = props;
60
- return [fontStyle, fontWeight, fontStretch, `${fontSize}px`, fontFamily].join(
61
- ' ',
62
- );
63
- }
64
-
65
- export interface CanvasTextRendererState extends TextRendererState {
66
- node: CoreTextNode;
67
- props: TrProps;
68
- fontInfo:
69
- | {
70
- fontFace: WebTrFontFace;
71
- cssString: string;
72
- loaded: boolean;
73
- }
74
- | undefined;
75
- textureNode: CoreNode | undefined;
76
- lightning2TextRenderer: LightningTextTextureRenderer;
77
- renderInfo: RenderInfo | undefined;
78
- }
79
-
80
- export class CanvasTextRenderer extends TextRenderer<CanvasTextRendererState> {
81
- protected canvas: OffscreenCanvas | HTMLCanvasElement;
82
- protected context:
83
- | OffscreenCanvasRenderingContext2D
84
- | CanvasRenderingContext2D;
85
- /**
86
- * Font family map used to store web font faces that were added to the
87
- * canvas text renderer.
88
- */
89
- private fontFamilies: FontFamilyMap = {};
90
- private fontFamilyArray: FontFamilyMap[] = [this.fontFamilies];
91
-
92
- public type: 'canvas' | 'sdf' = 'canvas';
93
-
94
- constructor(stage: Stage) {
95
- super(stage);
96
- if (typeof OffscreenCanvas !== 'undefined') {
97
- this.canvas = new OffscreenCanvas(0, 0);
98
- } else {
99
- this.canvas = document.createElement('canvas');
100
- }
101
-
102
- let context = this.canvas.getContext('2d', {
103
- willReadFrequently: true,
104
- }) as OffscreenCanvasRenderingContext2D | CanvasRenderingContext2D | null;
105
- if (!context) {
106
- // A browser may appear to support OffscreenCanvas but not actually support the Canvas '2d' context
107
- // Here we try getting the context again after falling back to an HTMLCanvasElement.
108
- // See: https://github.com/lightning-js/renderer/issues/26#issuecomment-1750438486
109
- this.canvas = document.createElement('canvas');
110
- context = this.canvas.getContext('2d', {
111
- willReadFrequently: true,
112
- });
113
- }
114
- assertTruthy(context);
115
- this.context = context;
116
-
117
- // Install the default 'san-serif' font face
118
- this.addFontFace(
119
- new WebTrFontFace({
120
- fontFamily: 'sans-serif',
121
- descriptors: {},
122
- fontUrl: '',
123
- }),
124
- );
125
- }
126
-
127
- //#region Overrides
128
- override getPropertySetters(): Partial<
129
- TrPropSetters<CanvasTextRendererState>
130
- > {
131
- return {
132
- fontFamily: (state, value) => {
133
- state.props.fontFamily = value;
134
- state.fontInfo = undefined;
135
- this.invalidateLayoutCache(state);
136
- },
137
- fontWeight: (state, value) => {
138
- state.props.fontWeight = value;
139
- state.fontInfo = undefined;
140
- this.invalidateLayoutCache(state);
141
- },
142
- fontStyle: (state, value) => {
143
- state.props.fontStyle = value;
144
- state.fontInfo = undefined;
145
- this.invalidateLayoutCache(state);
146
- },
147
- fontStretch: (state, value) => {
148
- state.props.fontStretch = value;
149
- state.fontInfo = undefined;
150
- this.invalidateLayoutCache(state);
151
- },
152
- fontSize: (state, value) => {
153
- state.props.fontSize = value;
154
- state.fontInfo = undefined;
155
- this.invalidateLayoutCache(state);
156
- },
157
- text: (state, value) => {
158
- state.props.text = value;
159
- this.invalidateLayoutCache(state);
160
- },
161
- textAlign: (state, value) => {
162
- state.props.textAlign = value;
163
- this.invalidateLayoutCache(state);
164
- },
165
- color: (state, value) => {
166
- state.props.color = value;
167
- this.invalidateLayoutCache(state);
168
- },
169
- x: (state, value) => {
170
- state.props.x = value;
171
- },
172
- y: (state, value) => {
173
- state.props.y = value;
174
- },
175
- contain: (state, value) => {
176
- state.props.contain = value;
177
- this.invalidateLayoutCache(state);
178
- },
179
- width: (state, value) => {
180
- state.props.width = value;
181
- // Only invalidate layout cache if we're containing in the horizontal direction
182
- if (state.props.contain !== 'none') {
183
- this.invalidateLayoutCache(state);
184
- }
185
- },
186
- height: (state, value) => {
187
- state.props.height = value;
188
- // Only invalidate layout cache if we're containing in the vertical direction
189
- if (state.props.contain === 'both') {
190
- this.invalidateLayoutCache(state);
191
- }
192
- },
193
- offsetY: (state, value) => {
194
- state.props.offsetY = value;
195
- this.invalidateLayoutCache(state);
196
- },
197
- scrollY: (state, value) => {
198
- state.props.scrollY = value;
199
- },
200
- letterSpacing: (state, value) => {
201
- state.props.letterSpacing = value;
202
- this.invalidateLayoutCache(state);
203
- },
204
- lineHeight: (state, value) => {
205
- state.props.lineHeight = value;
206
- this.invalidateLayoutCache(state);
207
- },
208
- maxLines: (state, value) => {
209
- state.props.maxLines = value;
210
- this.invalidateLayoutCache(state);
211
- },
212
- textBaseline: (state, value) => {
213
- state.props.textBaseline = value;
214
- this.invalidateLayoutCache(state);
215
- },
216
- verticalAlign: (state, value) => {
217
- state.props.verticalAlign = value;
218
- this.invalidateLayoutCache(state);
219
- },
220
- wordBreak: (state, value) => {
221
- state.props.wordBreak = value;
222
- this.invalidateLayoutCache(state);
223
- },
224
- overflowSuffix: (state, value) => {
225
- state.props.overflowSuffix = value;
226
- this.invalidateLayoutCache(state);
227
- },
228
- };
229
- }
230
-
231
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
232
- override canRenderFont(props: TrFontProps): boolean {
233
- // The canvas renderer can render any font because it automatically
234
- // falls back to system fonts. The CanvasTextRenderer should be
235
- // checked last if other renderers are preferred.
236
- return true;
237
- }
238
-
239
- override isFontFaceSupported(fontFace: TrFontFace): boolean {
240
- return fontFace instanceof WebTrFontFace;
241
- }
242
-
243
- override addFontFace(fontFace: TrFontFace): void {
244
- // Make sure the font face is an Canvas font face (it should have already passed
245
- // the `isFontFaceSupported` check)
246
- assertTruthy(fontFace instanceof WebTrFontFace);
247
-
248
- const fontFamily = fontFace.fontFamily;
249
-
250
- // Add the font face to the document
251
- // Except for the 'sans-serif' font family, which the Renderer provides
252
- // as a special default fallback.
253
- if (fontFamily !== 'sans-serif') {
254
- // @ts-expect-error `add()` method should be available from a FontFaceSet
255
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
256
- globalFontSet.add(fontFace.fontFace);
257
- }
258
-
259
- let faceSet = this.fontFamilies[fontFamily];
260
- if (!faceSet) {
261
- faceSet = new Set();
262
- this.fontFamilies[fontFamily] = faceSet;
263
- }
264
- faceSet.add(fontFace);
265
- }
266
-
267
- override createState(
268
- props: TrProps,
269
- node: CoreTextNode,
270
- ): CanvasTextRendererState {
271
- return {
272
- node,
273
- props,
274
- status: 'initialState',
275
- updateScheduled: false,
276
- emitter: new EventEmitter(),
277
- textureNode: undefined,
278
- lightning2TextRenderer: new LightningTextTextureRenderer(
279
- this.canvas,
280
- this.context,
281
- ),
282
- renderInfo: undefined,
283
- forceFullLayoutCalc: false,
284
- textW: 0,
285
- textH: 0,
286
- fontInfo: undefined,
287
- isRenderable: false,
288
- debugData: {
289
- updateCount: 0,
290
- layoutCount: 0,
291
- drawCount: 0,
292
- lastLayoutNumCharacters: 0,
293
- layoutSum: 0,
294
- drawSum: 0,
295
- bufferSize: 0,
296
- },
297
- };
298
- }
299
-
300
- override updateState(state: CanvasTextRendererState): void {
301
- // On the first update call we need to set the status to loading
302
- if (state.status === 'initialState') {
303
- this.setStatus(state, 'loading');
304
- // check if we're on screen
305
- // if (this.isValidOnScreen(state) === true) {
306
- // this.setStatus(state, 'loading');
307
- // }
308
- }
309
-
310
- if (state.status === 'loaded') {
311
- // If we're loaded, we don't need to do anything
312
- return;
313
- }
314
-
315
- // If fontInfo is invalid, we need to establish it
316
- if (!state.fontInfo) {
317
- return this.loadFont(state);
318
- }
319
-
320
- // If we're waiting for a font face to load, don't render anything
321
- if (!state.fontInfo.loaded) {
322
- return;
323
- }
324
-
325
- if (!state.renderInfo) {
326
- state.renderInfo = this.calculateRenderInfo(state);
327
- state.textH = state.renderInfo.lineHeight * state.renderInfo.lines.length;
328
- state.textW = state.renderInfo.width;
329
- this.renderSingleCanvasPage(state);
330
- }
331
-
332
- // handle scrollable text !!!
333
- // if (state.isScrollable === true) {
334
- // return this.renderScrollableCanvasPages(state);
335
- // }
336
-
337
- // handle single page text
338
- }
339
-
340
- renderSingleCanvasPage(state: CanvasTextRendererState): void {
341
- assertTruthy(state.renderInfo);
342
- const node = state.node;
343
-
344
- const texture = this.stage.txManager.createTexture('ImageTexture', {
345
- premultiplyAlpha: true,
346
- src: function (
347
- this: CanvasTextRenderer,
348
- lightning2TextRenderer: LightningTextTextureRenderer,
349
- renderInfo: RenderInfo,
350
- ) {
351
- // load the canvas texture
352
- assertTruthy(renderInfo);
353
- lightning2TextRenderer.draw(renderInfo, {
354
- lines: renderInfo.lines,
355
- lineWidths: renderInfo.lineWidths,
356
- });
357
- if (this.canvas.width === 0 || this.canvas.height === 0) {
358
- return null;
359
- }
360
- return this.context.getImageData(
361
- 0,
362
- 0,
363
- this.canvas.width,
364
- this.canvas.height,
365
- );
366
- }.bind(this, state.lightning2TextRenderer, state.renderInfo),
367
- });
368
-
369
- if (state.textureNode) {
370
- // Use the existing texture node
371
- state.textureNode.texture = texture;
372
- // Update the alpha
373
- state.textureNode.alpha = getNormalizedAlphaComponent(state.props.color);
374
- } else {
375
- // Create a new texture node
376
- const textureNode = this.stage.createNode({
377
- parent: node,
378
- texture,
379
- autosize: true,
380
- // The alpha channel of the color is ignored when rasterizing the text
381
- // texture so we need to pass it directly to the texture node.
382
- alpha: getNormalizedAlphaComponent(state.props.color),
383
- });
384
- state.textureNode = textureNode;
385
- }
386
-
387
- this.setStatus(state, 'loaded');
388
- }
389
-
390
- loadFont = (state: CanvasTextRendererState): void => {
391
- const cssString = getFontCssString(state.props);
392
-
393
- const trFontFace = this.stage.fontManager.resolveFontFace(
394
- this.fontFamilyArray,
395
- state.props,
396
- 'canvas',
397
- ) as WebTrFontFace | undefined;
398
- assertTruthy(trFontFace, `Could not resolve font face for ${cssString}`);
399
- state.fontInfo = {
400
- fontFace: trFontFace,
401
- cssString: cssString,
402
- // TODO: For efficiency we would use this here but it's not reliable on WPE -> document.fonts.check(cssString),
403
- loaded: false,
404
- };
405
- // If font is not loaded, set up a handler to update the font info when the font loads
406
- if (!state.fontInfo.loaded) {
407
- globalFontSet
408
- .load(cssString)
409
- .then(this.onFontLoaded.bind(this, state, cssString))
410
- .catch(this.onFontLoadError.bind(this, state, cssString));
411
- return;
412
- }
413
- };
414
-
415
- calculateRenderInfo(state: CanvasTextRendererState): RenderInfo {
416
- state.lightning2TextRenderer.settings = {
417
- text: state.props.text,
418
- textAlign: state.props.textAlign,
419
- fontFamily: state.props.fontFamily,
420
- trFontFace: state.fontInfo?.fontFace,
421
- fontSize: state.props.fontSize,
422
- fontStyle: [
423
- state.props.fontStretch,
424
- state.props.fontStyle,
425
- state.props.fontWeight,
426
- ].join(' '),
427
- textColor: getNormalizedRgbaComponents(state.props.color),
428
- offsetY: state.props.offsetY,
429
- wordWrap: state.props.contain !== 'none',
430
- wordWrapWidth:
431
- state.props.contain === 'none' ? undefined : state.props.width,
432
- letterSpacing: state.props.letterSpacing,
433
- lineHeight: state.props.lineHeight ?? null,
434
- maxLines: state.props.maxLines,
435
- maxHeight:
436
- state.props.contain === 'both'
437
- ? state.props.height - state.props.offsetY
438
- : null,
439
- textBaseline: state.props.textBaseline,
440
- verticalAlign: state.props.verticalAlign,
441
- overflowSuffix: state.props.overflowSuffix,
442
- wordBreak: state.props.wordBreak,
443
- w: state.props.contain !== 'none' ? state.props.width : undefined,
444
- };
445
- state.renderInfo = state.lightning2TextRenderer.calculateRenderInfo();
446
- return state.renderInfo;
447
- }
448
-
449
- override renderQuads(): void {
450
- // Do nothing. The renderer will render the child node(s) that were created
451
- // in the state update.
452
- return;
453
- }
454
-
455
- override destroyState(state: CanvasTextRendererState): void {
456
- if (state.status === 'destroyed') {
457
- return;
458
- }
459
- super.destroyState(state);
460
-
461
- if (state.textureNode) {
462
- state.textureNode.destroy();
463
- delete state.textureNode;
464
- }
465
- delete state.renderInfo;
466
- }
467
- //#endregion Overrides
468
-
469
- /**
470
- * Invalidate the layout cache stored in the state. This will cause the text
471
- * to be re-rendered on the next update.
472
- *
473
- * @remarks
474
- * This also invalidates the visible window cache.
475
- *
476
- * @param state
477
- */
478
- private invalidateLayoutCache(state: CanvasTextRendererState): void {
479
- state.renderInfo = undefined;
480
- this.setStatus(state, 'loading');
481
- this.scheduleUpdateState(state);
482
- }
483
-
484
- private onFontLoaded(
485
- state: CanvasTextRendererState,
486
- cssString: string,
487
- ): void {
488
- if (cssString !== state.fontInfo?.cssString || !state.fontInfo) {
489
- return;
490
- }
491
- state.fontInfo.loaded = true;
492
- this.scheduleUpdateState(state);
493
- }
494
-
495
- private onFontLoadError(
496
- state: CanvasTextRendererState,
497
- cssString: string,
498
- error: Error,
499
- ): void {
500
- if (cssString !== state.fontInfo?.cssString || !state.fontInfo) {
501
- return;
502
- }
503
-
504
- // Font didn't actually load, but we'll log the error and mark it as loaded
505
- // because the browser can still render with a fallback font.
506
- state.fontInfo.loaded = true;
507
-
508
- console.error(
509
- `CanvasTextRenderer: Error loading font '${state.fontInfo.cssString}'`,
510
- error,
511
- );
512
- this.scheduleUpdateState(state);
513
- }
514
- }
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 { EventEmitter } from '../../../common/EventEmitter.js';
21
+ import { assertTruthy } from '../../../utils.js';
22
+ import type { CoreNode } from '../../CoreNode.js';
23
+ import type { CoreTextNode } from '../../CoreTextNode.js';
24
+ import type { Stage } from '../../Stage.js';
25
+ import {
26
+ getNormalizedRgbaComponents,
27
+ getNormalizedAlphaComponent,
28
+ } from '../../lib/utils.js';
29
+ import { type FontFamilyMap } from '../TrFontManager.js';
30
+ import type { TrFontFace } from '../font-face-types/TrFontFace.js';
31
+ import { WebTrFontFace } from '../font-face-types/WebTrFontFace.js';
32
+ import {
33
+ LightningTextTextureRenderer,
34
+ type RenderInfo,
35
+ } from './LightningTextTextureRenderer.js';
36
+ import {
37
+ TextRenderer,
38
+ type TextRendererState,
39
+ type TrFontProps,
40
+ type TrPropSetters,
41
+ type TrProps,
42
+ } from './TextRenderer.js';
43
+
44
+ const resolvedGlobal = typeof self === 'undefined' ? globalThis : self;
45
+
46
+ /**
47
+ * Global font set regardless of if run in the main thread or a web worker
48
+ */
49
+ const globalFontSet: FontFaceSet = (resolvedGlobal.document?.fonts ||
50
+ (resolvedGlobal as any).fonts) as FontFaceSet;
51
+
52
+ declare module './TextRenderer.js' {
53
+ interface TextRendererMap {
54
+ canvas: CanvasTextRenderer;
55
+ }
56
+ }
57
+
58
+ function getFontCssString(props: TrProps): string {
59
+ const { fontFamily, fontStyle, fontWeight, fontStretch, fontSize } = props;
60
+ return [fontStyle, fontWeight, fontStretch, `${fontSize}px`, fontFamily].join(
61
+ ' ',
62
+ );
63
+ }
64
+
65
+ export interface CanvasTextRendererState extends TextRendererState {
66
+ node: CoreTextNode;
67
+ props: TrProps;
68
+ fontInfo:
69
+ | {
70
+ fontFace: WebTrFontFace;
71
+ cssString: string;
72
+ loaded: boolean;
73
+ }
74
+ | undefined;
75
+ textureNode: CoreNode | undefined;
76
+ lightning2TextRenderer: LightningTextTextureRenderer;
77
+ renderInfo: RenderInfo | undefined;
78
+ }
79
+
80
+ export class CanvasTextRenderer extends TextRenderer<CanvasTextRendererState> {
81
+ protected canvas: OffscreenCanvas | HTMLCanvasElement;
82
+ protected context:
83
+ | OffscreenCanvasRenderingContext2D
84
+ | CanvasRenderingContext2D;
85
+ /**
86
+ * Font family map used to store web font faces that were added to the
87
+ * canvas text renderer.
88
+ */
89
+ private fontFamilies: FontFamilyMap = {};
90
+ private fontFamilyArray: FontFamilyMap[] = [this.fontFamilies];
91
+
92
+ public type: 'canvas' | 'sdf' = 'canvas';
93
+
94
+ constructor(stage: Stage) {
95
+ super(stage);
96
+ if (typeof OffscreenCanvas !== 'undefined') {
97
+ this.canvas = new OffscreenCanvas(0, 0);
98
+ } else {
99
+ this.canvas = document.createElement('canvas');
100
+ }
101
+
102
+ let context = this.canvas.getContext('2d', {
103
+ willReadFrequently: true,
104
+ }) as OffscreenCanvasRenderingContext2D | CanvasRenderingContext2D | null;
105
+ if (!context) {
106
+ // A browser may appear to support OffscreenCanvas but not actually support the Canvas '2d' context
107
+ // Here we try getting the context again after falling back to an HTMLCanvasElement.
108
+ // See: https://github.com/lightning-js/renderer/issues/26#issuecomment-1750438486
109
+ this.canvas = document.createElement('canvas');
110
+ context = this.canvas.getContext('2d', {
111
+ willReadFrequently: true,
112
+ });
113
+ }
114
+ assertTruthy(context);
115
+ this.context = context;
116
+
117
+ // Install the default 'san-serif' font face
118
+ this.addFontFace(
119
+ new WebTrFontFace({
120
+ fontFamily: 'sans-serif',
121
+ descriptors: {},
122
+ fontUrl: '',
123
+ }),
124
+ );
125
+ }
126
+
127
+ //#region Overrides
128
+ override getPropertySetters(): Partial<
129
+ TrPropSetters<CanvasTextRendererState>
130
+ > {
131
+ return {
132
+ fontFamily: (state, value) => {
133
+ state.props.fontFamily = value;
134
+ state.fontInfo = undefined;
135
+ this.invalidateLayoutCache(state);
136
+ },
137
+ fontWeight: (state, value) => {
138
+ state.props.fontWeight = value;
139
+ state.fontInfo = undefined;
140
+ this.invalidateLayoutCache(state);
141
+ },
142
+ fontStyle: (state, value) => {
143
+ state.props.fontStyle = value;
144
+ state.fontInfo = undefined;
145
+ this.invalidateLayoutCache(state);
146
+ },
147
+ fontStretch: (state, value) => {
148
+ state.props.fontStretch = value;
149
+ state.fontInfo = undefined;
150
+ this.invalidateLayoutCache(state);
151
+ },
152
+ fontSize: (state, value) => {
153
+ state.props.fontSize = value;
154
+ state.fontInfo = undefined;
155
+ this.invalidateLayoutCache(state);
156
+ },
157
+ text: (state, value) => {
158
+ state.props.text = value;
159
+ this.invalidateLayoutCache(state);
160
+ },
161
+ textAlign: (state, value) => {
162
+ state.props.textAlign = value;
163
+ this.invalidateLayoutCache(state);
164
+ },
165
+ color: (state, value) => {
166
+ state.props.color = value;
167
+ this.invalidateLayoutCache(state);
168
+ },
169
+ x: (state, value) => {
170
+ state.props.x = value;
171
+ },
172
+ y: (state, value) => {
173
+ state.props.y = value;
174
+ },
175
+ contain: (state, value) => {
176
+ state.props.contain = value;
177
+ this.invalidateLayoutCache(state);
178
+ },
179
+ width: (state, value) => {
180
+ state.props.width = value;
181
+ // Only invalidate layout cache if we're containing in the horizontal direction
182
+ if (state.props.contain !== 'none') {
183
+ this.invalidateLayoutCache(state);
184
+ }
185
+ },
186
+ height: (state, value) => {
187
+ state.props.height = value;
188
+ // Only invalidate layout cache if we're containing in the vertical direction
189
+ if (state.props.contain === 'both') {
190
+ this.invalidateLayoutCache(state);
191
+ }
192
+ },
193
+ offsetY: (state, value) => {
194
+ state.props.offsetY = value;
195
+ this.invalidateLayoutCache(state);
196
+ },
197
+ scrollY: (state, value) => {
198
+ state.props.scrollY = value;
199
+ },
200
+ letterSpacing: (state, value) => {
201
+ state.props.letterSpacing = value;
202
+ this.invalidateLayoutCache(state);
203
+ },
204
+ lineHeight: (state, value) => {
205
+ state.props.lineHeight = value;
206
+ this.invalidateLayoutCache(state);
207
+ },
208
+ maxLines: (state, value) => {
209
+ state.props.maxLines = value;
210
+ this.invalidateLayoutCache(state);
211
+ },
212
+ textBaseline: (state, value) => {
213
+ state.props.textBaseline = value;
214
+ this.invalidateLayoutCache(state);
215
+ },
216
+ verticalAlign: (state, value) => {
217
+ state.props.verticalAlign = value;
218
+ this.invalidateLayoutCache(state);
219
+ },
220
+ wordBreak: (state, value) => {
221
+ state.props.wordBreak = value;
222
+ this.invalidateLayoutCache(state);
223
+ },
224
+ overflowSuffix: (state, value) => {
225
+ state.props.overflowSuffix = value;
226
+ this.invalidateLayoutCache(state);
227
+ },
228
+ };
229
+ }
230
+
231
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
232
+ override canRenderFont(props: TrFontProps): boolean {
233
+ // The canvas renderer can render any font because it automatically
234
+ // falls back to system fonts. The CanvasTextRenderer should be
235
+ // checked last if other renderers are preferred.
236
+ return true;
237
+ }
238
+
239
+ override isFontFaceSupported(fontFace: TrFontFace): boolean {
240
+ return fontFace instanceof WebTrFontFace;
241
+ }
242
+
243
+ override addFontFace(fontFace: TrFontFace): void {
244
+ // Make sure the font face is an Canvas font face (it should have already passed
245
+ // the `isFontFaceSupported` check)
246
+ assertTruthy(fontFace instanceof WebTrFontFace);
247
+
248
+ const fontFamily = fontFace.fontFamily;
249
+
250
+ // Add the font face to the document
251
+ // Except for the 'sans-serif' font family, which the Renderer provides
252
+ // as a special default fallback.
253
+ if (fontFamily !== 'sans-serif') {
254
+ // @ts-expect-error `add()` method should be available from a FontFaceSet
255
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
256
+ globalFontSet.add(fontFace.fontFace);
257
+ }
258
+
259
+ let faceSet = this.fontFamilies[fontFamily];
260
+ if (!faceSet) {
261
+ faceSet = new Set();
262
+ this.fontFamilies[fontFamily] = faceSet;
263
+ }
264
+ faceSet.add(fontFace);
265
+ }
266
+
267
+ override createState(
268
+ props: TrProps,
269
+ node: CoreTextNode,
270
+ ): CanvasTextRendererState {
271
+ return {
272
+ node,
273
+ props,
274
+ status: 'initialState',
275
+ updateScheduled: false,
276
+ emitter: new EventEmitter(),
277
+ textureNode: undefined,
278
+ lightning2TextRenderer: new LightningTextTextureRenderer(
279
+ this.canvas,
280
+ this.context,
281
+ ),
282
+ renderInfo: undefined,
283
+ forceFullLayoutCalc: false,
284
+ textW: 0,
285
+ textH: 0,
286
+ fontInfo: undefined,
287
+ isRenderable: false,
288
+ debugData: {
289
+ updateCount: 0,
290
+ layoutCount: 0,
291
+ drawCount: 0,
292
+ lastLayoutNumCharacters: 0,
293
+ layoutSum: 0,
294
+ drawSum: 0,
295
+ bufferSize: 0,
296
+ },
297
+ };
298
+ }
299
+
300
+ override updateState(state: CanvasTextRendererState): void {
301
+ // On the first update call we need to set the status to loading
302
+ if (state.status === 'initialState') {
303
+ this.setStatus(state, 'loading');
304
+ // check if we're on screen
305
+ // if (this.isValidOnScreen(state) === true) {
306
+ // this.setStatus(state, 'loading');
307
+ // }
308
+ }
309
+
310
+ if (state.status === 'loaded') {
311
+ // If we're loaded, we don't need to do anything
312
+ return;
313
+ }
314
+
315
+ // If fontInfo is invalid, we need to establish it
316
+ if (!state.fontInfo) {
317
+ return this.loadFont(state);
318
+ }
319
+
320
+ // If we're waiting for a font face to load, don't render anything
321
+ if (!state.fontInfo.loaded) {
322
+ return;
323
+ }
324
+
325
+ if (!state.renderInfo) {
326
+ state.renderInfo = this.calculateRenderInfo(state);
327
+ state.textH = state.renderInfo.lineHeight * state.renderInfo.lines.length;
328
+ state.textW = state.renderInfo.width;
329
+ this.renderSingleCanvasPage(state);
330
+ }
331
+
332
+ // handle scrollable text !!!
333
+ // if (state.isScrollable === true) {
334
+ // return this.renderScrollableCanvasPages(state);
335
+ // }
336
+
337
+ // handle single page text
338
+ }
339
+
340
+ renderSingleCanvasPage(state: CanvasTextRendererState): void {
341
+ assertTruthy(state.renderInfo);
342
+ const node = state.node;
343
+
344
+ const texture = this.stage.txManager.createTexture('ImageTexture', {
345
+ premultiplyAlpha: true,
346
+ src: function (
347
+ this: CanvasTextRenderer,
348
+ lightning2TextRenderer: LightningTextTextureRenderer,
349
+ renderInfo: RenderInfo,
350
+ ) {
351
+ // load the canvas texture
352
+ assertTruthy(renderInfo);
353
+ lightning2TextRenderer.draw(renderInfo, {
354
+ lines: renderInfo.lines,
355
+ lineWidths: renderInfo.lineWidths,
356
+ });
357
+ if (this.canvas.width === 0 || this.canvas.height === 0) {
358
+ return null;
359
+ }
360
+ return this.context.getImageData(
361
+ 0,
362
+ 0,
363
+ this.canvas.width,
364
+ this.canvas.height,
365
+ );
366
+ }.bind(this, state.lightning2TextRenderer, state.renderInfo),
367
+ });
368
+
369
+ if (state.textureNode) {
370
+ // Use the existing texture node
371
+ state.textureNode.texture = texture;
372
+ // Update the alpha
373
+ state.textureNode.alpha = getNormalizedAlphaComponent(state.props.color);
374
+ } else {
375
+ // Create a new texture node
376
+ const textureNode = this.stage.createNode({
377
+ parent: node,
378
+ texture,
379
+ autosize: true,
380
+ // The alpha channel of the color is ignored when rasterizing the text
381
+ // texture so we need to pass it directly to the texture node.
382
+ alpha: getNormalizedAlphaComponent(state.props.color),
383
+ });
384
+ state.textureNode = textureNode;
385
+ }
386
+
387
+ this.setStatus(state, 'loaded');
388
+ }
389
+
390
+ loadFont = (state: CanvasTextRendererState): void => {
391
+ const cssString = getFontCssString(state.props);
392
+
393
+ const trFontFace = this.stage.fontManager.resolveFontFace(
394
+ this.fontFamilyArray,
395
+ state.props,
396
+ 'canvas',
397
+ ) as WebTrFontFace | undefined;
398
+ assertTruthy(trFontFace, `Could not resolve font face for ${cssString}`);
399
+ state.fontInfo = {
400
+ fontFace: trFontFace,
401
+ cssString: cssString,
402
+ // TODO: For efficiency we would use this here but it's not reliable on WPE -> document.fonts.check(cssString),
403
+ loaded: false,
404
+ };
405
+ // If font is not loaded, set up a handler to update the font info when the font loads
406
+ if (!state.fontInfo.loaded) {
407
+ globalFontSet
408
+ .load(cssString)
409
+ .then(this.onFontLoaded.bind(this, state, cssString))
410
+ .catch(this.onFontLoadError.bind(this, state, cssString));
411
+ return;
412
+ }
413
+ };
414
+
415
+ calculateRenderInfo(state: CanvasTextRendererState): RenderInfo {
416
+ state.lightning2TextRenderer.settings = {
417
+ text: state.props.text,
418
+ textAlign: state.props.textAlign,
419
+ fontFamily: state.props.fontFamily,
420
+ trFontFace: state.fontInfo?.fontFace,
421
+ fontSize: state.props.fontSize,
422
+ fontStyle: [
423
+ state.props.fontStretch,
424
+ state.props.fontStyle,
425
+ state.props.fontWeight,
426
+ ].join(' '),
427
+ textColor: getNormalizedRgbaComponents(state.props.color),
428
+ offsetY: state.props.offsetY,
429
+ wordWrap: state.props.contain !== 'none',
430
+ wordWrapWidth:
431
+ state.props.contain === 'none' ? undefined : state.props.width,
432
+ letterSpacing: state.props.letterSpacing,
433
+ lineHeight: state.props.lineHeight ?? null,
434
+ maxLines: state.props.maxLines,
435
+ maxHeight:
436
+ state.props.contain === 'both'
437
+ ? state.props.height - state.props.offsetY
438
+ : null,
439
+ textBaseline: state.props.textBaseline,
440
+ verticalAlign: state.props.verticalAlign,
441
+ overflowSuffix: state.props.overflowSuffix,
442
+ wordBreak: state.props.wordBreak,
443
+ w: state.props.contain !== 'none' ? state.props.width : undefined,
444
+ };
445
+ state.renderInfo = state.lightning2TextRenderer.calculateRenderInfo();
446
+ return state.renderInfo;
447
+ }
448
+
449
+ override renderQuads(): void {
450
+ // Do nothing. The renderer will render the child node(s) that were created
451
+ // in the state update.
452
+ return;
453
+ }
454
+
455
+ override destroyState(state: CanvasTextRendererState): void {
456
+ if (state.status === 'destroyed') {
457
+ return;
458
+ }
459
+ super.destroyState(state);
460
+
461
+ if (state.textureNode) {
462
+ state.textureNode.destroy();
463
+ delete state.textureNode;
464
+ }
465
+ delete state.renderInfo;
466
+ }
467
+ //#endregion Overrides
468
+
469
+ /**
470
+ * Invalidate the layout cache stored in the state. This will cause the text
471
+ * to be re-rendered on the next update.
472
+ *
473
+ * @remarks
474
+ * This also invalidates the visible window cache.
475
+ *
476
+ * @param state
477
+ */
478
+ private invalidateLayoutCache(state: CanvasTextRendererState): void {
479
+ state.renderInfo = undefined;
480
+ this.setStatus(state, 'loading');
481
+ this.scheduleUpdateState(state);
482
+ }
483
+
484
+ private onFontLoaded(
485
+ state: CanvasTextRendererState,
486
+ cssString: string,
487
+ ): void {
488
+ if (cssString !== state.fontInfo?.cssString || !state.fontInfo) {
489
+ return;
490
+ }
491
+ state.fontInfo.loaded = true;
492
+ this.scheduleUpdateState(state);
493
+ }
494
+
495
+ private onFontLoadError(
496
+ state: CanvasTextRendererState,
497
+ cssString: string,
498
+ error: Error,
499
+ ): void {
500
+ if (cssString !== state.fontInfo?.cssString || !state.fontInfo) {
501
+ return;
502
+ }
503
+
504
+ // Font didn't actually load, but we'll log the error and mark it as loaded
505
+ // because the browser can still render with a fallback font.
506
+ state.fontInfo.loaded = true;
507
+
508
+ console.error(
509
+ `CanvasTextRenderer: Error loading font '${state.fontInfo.cssString}'`,
510
+ error,
511
+ );
512
+ this.scheduleUpdateState(state);
513
+ }
514
+ }