@lightningjs/renderer 3.0.3 → 3.0.5

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 (240) hide show
  1. package/dist/src/common/EventEmitter.d.ts +7 -4
  2. package/dist/src/common/EventEmitter.js +1 -1
  3. package/dist/src/common/EventEmitter.js.map +1 -1
  4. package/dist/src/core/AutosizeManager.d.ts +29 -0
  5. package/dist/src/core/AutosizeManager.js +169 -0
  6. package/dist/src/core/AutosizeManager.js.map +1 -0
  7. package/dist/src/core/CoreNode.d.ts +2 -1
  8. package/dist/src/core/CoreNode.js +6 -3
  9. package/dist/src/core/CoreNode.js.map +1 -1
  10. package/dist/src/core/CoreTextNode.d.ts +18 -5
  11. package/dist/src/core/CoreTextNode.js +141 -59
  12. package/dist/src/core/CoreTextNode.js.map +1 -1
  13. package/dist/src/core/CoreTextNodeCanvas.d.ts +215 -0
  14. package/dist/src/core/CoreTextNodeCanvas.js +236 -0
  15. package/dist/src/core/CoreTextNodeCanvas.js.map +1 -0
  16. package/dist/src/core/Stage.js +10 -0
  17. package/dist/src/core/Stage.js.map +1 -1
  18. package/dist/src/core/TextureMemoryManager.js +4 -3
  19. package/dist/src/core/TextureMemoryManager.js.map +1 -1
  20. package/dist/src/core/animations/Animation.d.ts +21 -0
  21. package/dist/src/core/animations/Animation.js +194 -0
  22. package/dist/src/core/animations/Animation.js.map +1 -0
  23. package/dist/src/core/animations/AnimationManager.d.ts +1 -1
  24. package/dist/src/core/animations/AnimationManager.js +5 -5
  25. package/dist/src/core/animations/AnimationManager.js.map +1 -1
  26. package/dist/src/core/animations/CoreAnimation.d.ts +11 -2
  27. package/dist/src/core/animations/CoreAnimation.js +44 -38
  28. package/dist/src/core/animations/CoreAnimation.js.map +1 -1
  29. package/dist/src/core/animations/CoreAnimationController.d.ts +6 -0
  30. package/dist/src/core/animations/CoreAnimationController.js +16 -3
  31. package/dist/src/core/animations/CoreAnimationController.js.map +1 -1
  32. package/dist/src/core/animations/Playback.d.ts +64 -0
  33. package/dist/src/core/animations/Playback.js +169 -0
  34. package/dist/src/core/animations/Playback.js.map +1 -0
  35. package/dist/src/core/animations/Ticker.d.ts +71 -0
  36. package/dist/src/core/animations/Ticker.js +89 -0
  37. package/dist/src/core/animations/Ticker.js.map +1 -0
  38. package/dist/src/core/animations/Transition.d.ts +38 -0
  39. package/dist/src/core/animations/Transition.js +35 -0
  40. package/dist/src/core/animations/Transition.js.map +1 -0
  41. package/dist/src/core/animations/TransitionsController.d.ts +10 -0
  42. package/dist/src/core/animations/TransitionsController.js +39 -0
  43. package/dist/src/core/animations/TransitionsController.js.map +1 -0
  44. package/dist/src/core/animations/utils.d.ts +2 -0
  45. package/dist/src/core/animations/utils.js +136 -0
  46. package/dist/src/core/animations/utils.js.map +1 -0
  47. package/dist/src/core/lib/ImageWorker.d.ts +2 -2
  48. package/dist/src/core/lib/ImageWorker.js +11 -30
  49. package/dist/src/core/lib/ImageWorker.js.map +1 -1
  50. package/dist/src/core/lib/WebGlContextWrapper.d.ts +5 -16
  51. package/dist/src/core/lib/WebGlContextWrapper.js +1 -35
  52. package/dist/src/core/lib/WebGlContextWrapper.js.map +1 -1
  53. package/dist/src/core/lib/textureCompression.d.ts +2 -14
  54. package/dist/src/core/lib/textureCompression.js +67 -320
  55. package/dist/src/core/lib/textureCompression.js.map +1 -1
  56. package/dist/src/core/platform.js +9 -38
  57. package/dist/src/core/platform.js.map +1 -1
  58. package/dist/src/core/renderers/canvas/CanvasCoreRenderer.d.ts +0 -1
  59. package/dist/src/core/renderers/canvas/CanvasCoreRenderer.js +3 -11
  60. package/dist/src/core/renderers/canvas/CanvasCoreRenderer.js.map +1 -1
  61. package/dist/src/core/renderers/canvas/CanvasCoreTexture.d.ts +1 -2
  62. package/dist/src/core/renderers/canvas/CanvasCoreTexture.js +11 -16
  63. package/dist/src/core/renderers/canvas/CanvasCoreTexture.js.map +1 -1
  64. package/dist/src/core/renderers/canvas/CanvasRenderer.js +14 -1
  65. package/dist/src/core/renderers/canvas/CanvasRenderer.js.map +1 -1
  66. package/dist/src/core/renderers/canvas/CanvasTexture.d.ts +1 -1
  67. package/dist/src/core/renderers/canvas/CanvasTexture.js +16 -6
  68. package/dist/src/core/renderers/canvas/CanvasTexture.js.map +1 -1
  69. package/dist/src/core/renderers/canvas/internal/C2DShaderUtils.d.ts +0 -13
  70. package/dist/src/core/renderers/canvas/internal/C2DShaderUtils.js +192 -113
  71. package/dist/src/core/renderers/canvas/internal/C2DShaderUtils.js.map +1 -1
  72. package/dist/src/core/renderers/canvas/internal/ColorUtils.d.ts +2 -0
  73. package/dist/src/core/renderers/canvas/internal/ColorUtils.js +14 -0
  74. package/dist/src/core/renderers/canvas/internal/ColorUtils.js.map +1 -1
  75. package/dist/src/core/renderers/webgl/WebGlCoreCtxRenderTexture.d.ts +1 -2
  76. package/dist/src/core/renderers/webgl/WebGlCoreCtxRenderTexture.js +5 -12
  77. package/dist/src/core/renderers/webgl/WebGlCoreCtxRenderTexture.js.map +1 -1
  78. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.d.ts +6 -18
  79. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js +60 -102
  80. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js.map +1 -1
  81. package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.js +1 -1
  82. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.d.ts +1 -3
  83. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js +31 -74
  84. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js.map +1 -1
  85. package/dist/src/core/renderers/webgl/WebGlCoreShader.d.ts +7 -2
  86. package/dist/src/core/renderers/webgl/WebGlCoreShader.js +50 -21
  87. package/dist/src/core/renderers/webgl/WebGlCoreShader.js.map +1 -1
  88. package/dist/src/core/renderers/webgl/WebGlRenderOp.d.ts +2 -3
  89. package/dist/src/core/renderers/webgl/WebGlRenderOp.js +1 -3
  90. package/dist/src/core/renderers/webgl/WebGlRenderOp.js.map +1 -1
  91. package/dist/src/core/renderers/webgl/WebGlRenderer.d.ts +2 -2
  92. package/dist/src/core/renderers/webgl/WebGlRenderer.js.map +1 -1
  93. package/dist/src/core/renderers/webgl/WebGlShaderNode.d.ts +1 -0
  94. package/dist/src/core/renderers/webgl/WebGlShaderNode.js +23 -0
  95. package/dist/src/core/renderers/webgl/WebGlShaderNode.js.map +1 -1
  96. package/dist/src/core/renderers/webgl/WebGlShaderProgram.js +4 -5
  97. package/dist/src/core/renderers/webgl/WebGlShaderProgram.js.map +1 -1
  98. package/dist/src/core/renderers/webgl/internal/ShaderUtils.d.ts +1 -0
  99. package/dist/src/core/renderers/webgl/internal/ShaderUtils.js.map +1 -1
  100. package/dist/src/core/renderers/webgl/shaders/DefaultShader.js +6 -3
  101. package/dist/src/core/renderers/webgl/shaders/DefaultShader.js.map +1 -1
  102. package/dist/src/core/renderers/webgl/shaders/DefaultShaderBatched.js +11 -0
  103. package/dist/src/core/renderers/webgl/shaders/DefaultShaderBatched.js.map +1 -1
  104. package/dist/src/core/renderers/webgl/shaders/DynamicShader.js +10 -5
  105. package/dist/src/core/renderers/webgl/shaders/DynamicShader.js.map +1 -1
  106. package/dist/src/core/renderers/webgl/shaders/RoundedRectangle.js +10 -5
  107. package/dist/src/core/renderers/webgl/shaders/RoundedRectangle.js.map +1 -1
  108. package/dist/src/core/renderers/webgl/shaders/SdfShader.js +12 -0
  109. package/dist/src/core/renderers/webgl/shaders/SdfShader.js.map +1 -1
  110. package/dist/src/core/renderers/webgl/shaders/effects/BorderBottomEffect.js +1 -1
  111. package/dist/src/core/renderers/webgl/shaders/effects/BorderLeftEffect.js +1 -1
  112. package/dist/src/core/renderers/webgl/shaders/effects/BorderRightEffect.js +1 -1
  113. package/dist/src/core/renderers/webgl/shaders/effects/BorderTopEffect.js +1 -1
  114. package/dist/src/core/renderers/webgl/shaders/effects/EffectUtils.js +2 -2
  115. package/dist/src/core/renderers/webgl/shaders/effects/FadeOutEffect.js +5 -5
  116. package/dist/src/core/renderers/webgl/shaders/effects/HolePunchEffect.js +1 -1
  117. package/dist/src/core/renderers/webgl/shaders/effects/LinearGradientEffect.d.ts +1 -0
  118. package/dist/src/core/renderers/webgl/shaders/effects/LinearGradientEffect.js +30 -14
  119. package/dist/src/core/renderers/webgl/shaders/effects/LinearGradientEffect.js.map +1 -1
  120. package/dist/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.d.ts +0 -1
  121. package/dist/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.js +3 -13
  122. package/dist/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.js.map +1 -1
  123. package/dist/src/core/renderers/webgl/shaders/effects/RadialProgressEffect.js +1 -1
  124. package/dist/src/core/renderers/webgl/shaders/effects/RadiusEffect.js +5 -5
  125. package/dist/src/core/shaders/webgl/SdfShadowShader.d.ts +9 -0
  126. package/dist/src/core/shaders/webgl/SdfShadowShader.js +100 -0
  127. package/dist/src/core/shaders/webgl/SdfShadowShader.js.map +1 -0
  128. package/dist/src/core/text-rendering/CanvasFont.d.ts +1 -1
  129. package/dist/src/core/text-rendering/CanvasFont.js +7 -16
  130. package/dist/src/core/text-rendering/CanvasFont.js.map +1 -1
  131. package/dist/src/core/text-rendering/CanvasFontHandler.d.ts +1 -1
  132. package/dist/src/core/text-rendering/CanvasFontHandler.js +1 -1
  133. package/dist/src/core/text-rendering/CanvasFontHandler.js.map +1 -1
  134. package/dist/src/core/text-rendering/CanvasTextRenderer.d.ts +2 -3
  135. package/dist/src/core/text-rendering/CanvasTextRenderer.js +7 -5
  136. package/dist/src/core/text-rendering/CanvasTextRenderer.js.map +1 -1
  137. package/dist/src/core/text-rendering/CoreFont.d.ts +1 -1
  138. package/dist/src/core/text-rendering/CoreFont.js +1 -1
  139. package/dist/src/core/text-rendering/CoreFont.js.map +1 -1
  140. package/dist/src/core/text-rendering/FontManager.js +2 -1
  141. package/dist/src/core/text-rendering/FontManager.js.map +1 -1
  142. package/dist/src/core/text-rendering/SdfTextRenderer.d.ts +3 -5
  143. package/dist/src/core/text-rendering/SdfTextRenderer.js +19 -109
  144. package/dist/src/core/text-rendering/SdfTextRenderer.js.map +1 -1
  145. package/dist/src/core/text-rendering/TextLayoutEngine.js +43 -12
  146. package/dist/src/core/text-rendering/TextLayoutEngine.js.map +1 -1
  147. package/dist/src/core/text-rendering/TextRenderer.d.ts +16 -8
  148. package/dist/src/core/text-rendering/canvas/Settings.d.ts +64 -0
  149. package/dist/src/core/text-rendering/canvas/Settings.js +20 -0
  150. package/dist/src/core/text-rendering/canvas/Settings.js.map +1 -0
  151. package/dist/src/core/text-rendering/canvas/Utils.d.ts +20 -0
  152. package/dist/src/core/text-rendering/canvas/Utils.js +144 -0
  153. package/dist/src/core/text-rendering/canvas/Utils.js.map +1 -0
  154. package/dist/src/core/text-rendering/canvas/calculateRenderInfo.d.ts +60 -0
  155. package/dist/src/core/text-rendering/canvas/calculateRenderInfo.js +183 -0
  156. package/dist/src/core/text-rendering/canvas/calculateRenderInfo.js.map +1 -0
  157. package/dist/src/core/text-rendering/canvas/draw.d.ts +5 -0
  158. package/dist/src/core/text-rendering/canvas/draw.js +132 -0
  159. package/dist/src/core/text-rendering/canvas/draw.js.map +1 -0
  160. package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.js +2 -2
  161. package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.js.map +1 -1
  162. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.d.ts +3 -4
  163. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js +46 -98
  164. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js.map +1 -1
  165. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.d.ts +1 -1
  166. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.d.ts +2 -2
  167. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.js +66 -8
  168. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.js.map +1 -1
  169. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.d.ts +1 -1
  170. package/dist/src/core/text-rendering/renderers/TextRenderer.d.ts +1 -1
  171. package/dist/src/core/text-rendering/renderers/canvas/CanvasTextRenderer.d.ts +26 -0
  172. package/dist/src/core/text-rendering/renderers/canvas/CanvasTextRenderer.js +158 -0
  173. package/dist/src/core/text-rendering/renderers/canvas/CanvasTextRenderer.js.map +1 -0
  174. package/dist/src/core/text-rendering/renderers/canvas/internal/draw.d.ts +5 -0
  175. package/dist/src/core/text-rendering/renderers/canvas/internal/draw.js +127 -0
  176. package/dist/src/core/text-rendering/renderers/canvas/internal/draw.js.map +1 -0
  177. package/dist/src/core/text-rendering/renderers/canvas/internal/mergeDefaults.d.ts +2 -0
  178. package/dist/src/core/text-rendering/renderers/canvas/internal/mergeDefaults.js +50 -0
  179. package/dist/src/core/text-rendering/renderers/canvas/internal/mergeDefaults.js.map +1 -0
  180. package/dist/src/core/text-rendering/renderers/canvas/internal/renderInfo.d.ts +33 -0
  181. package/dist/src/core/text-rendering/renderers/canvas/internal/renderInfo.js +192 -0
  182. package/dist/src/core/text-rendering/renderers/canvas/internal/renderInfo.js.map +1 -0
  183. package/dist/src/core/text-rendering/renderers/canvas/internal/types.d.ts +66 -0
  184. package/dist/src/core/text-rendering/renderers/canvas/internal/types.js +2 -0
  185. package/dist/src/core/text-rendering/renderers/canvas/internal/types.js.map +1 -0
  186. package/dist/src/core/text-rendering/renderers/canvas/internal/utils.d.ts +91 -0
  187. package/dist/src/core/text-rendering/renderers/canvas/internal/utils.js +282 -0
  188. package/dist/src/core/text-rendering/renderers/canvas/internal/utils.js.map +1 -0
  189. package/dist/src/core/text-rendering/sdf/PeekableGenerator.d.ts +12 -0
  190. package/dist/src/core/text-rendering/sdf/PeekableGenerator.js +61 -0
  191. package/dist/src/core/text-rendering/sdf/PeekableGenerator.js.map +1 -0
  192. package/dist/src/core/text-rendering/sdf/SimpleFontShaper.d.ts +45 -0
  193. package/dist/src/core/text-rendering/sdf/SimpleFontShaper.js +69 -0
  194. package/dist/src/core/text-rendering/sdf/SimpleFontShaper.js.map +1 -0
  195. package/dist/src/core/text-rendering/sdf/Utils.d.ts +26 -0
  196. package/dist/src/core/text-rendering/sdf/Utils.js +301 -0
  197. package/dist/src/core/text-rendering/sdf/Utils.js.map +1 -0
  198. package/dist/src/core/text-rendering/sdf/index.d.ts +1 -0
  199. package/dist/src/core/text-rendering/sdf/index.js +20 -0
  200. package/dist/src/core/text-rendering/sdf/index.js.map +1 -0
  201. package/dist/src/core/textures/ImageTexture.js +11 -0
  202. package/dist/src/core/textures/ImageTexture.js.map +1 -1
  203. package/dist/src/core/textures/Texture.js +5 -0
  204. package/dist/src/core/textures/Texture.js.map +1 -1
  205. package/dist/src/main-api/Inspector.d.ts +1 -1
  206. package/dist/src/main-api/Inspector.js +25 -20
  207. package/dist/src/main-api/Inspector.js.map +1 -1
  208. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  209. package/dist/tsconfig.tsbuildinfo +1 -0
  210. package/package.json +1 -1
  211. package/src/common/EventEmitter.ts +6 -8
  212. package/src/core/CoreNode.test.ts +1 -1
  213. package/src/core/CoreNode.ts +8 -4
  214. package/src/core/CoreTextNode.test.ts +138 -25
  215. package/src/core/CoreTextNode.ts +174 -67
  216. package/src/core/Stage.ts +11 -0
  217. package/src/core/TextureMemoryManager.ts +4 -3
  218. package/src/core/animations/AnimationManager.ts +5 -5
  219. package/src/core/animations/CoreAnimation.ts +61 -45
  220. package/src/core/animations/CoreAnimationController.ts +16 -7
  221. package/src/core/renderers/canvas/CanvasRenderer.ts +19 -1
  222. package/src/core/renderers/canvas/CanvasTexture.ts +23 -8
  223. package/src/core/renderers/webgl/WebGlRenderer.ts +2 -3
  224. package/src/core/renderers/webgl/WebGlShaderNode.ts +24 -0
  225. package/src/core/renderers/webgl/WebGlShaderProgram.test.ts +274 -0
  226. package/src/core/renderers/webgl/WebGlShaderProgram.ts +10 -10
  227. package/src/core/renderers/webgl/internal/ShaderUtils.ts +1 -0
  228. package/src/core/text-rendering/CanvasFontHandler.ts +2 -2
  229. package/src/core/text-rendering/CanvasTextRenderer.ts +14 -7
  230. package/src/core/text-rendering/SdfTextRenderer.ts +28 -140
  231. package/src/core/text-rendering/TextLayoutEngine.ts +61 -28
  232. package/src/core/text-rendering/TextRenderer.ts +19 -12
  233. package/src/core/text-rendering/tests/TextLayoutEngine.test.ts +20 -0
  234. package/src/core/textures/ImageTexture.ts +18 -0
  235. package/src/core/textures/Texture.ts +6 -0
  236. package/src/main-api/Inspector.ts +25 -25
  237. package/dist/src/core/text-rendering/TextGenerator.d.ts +0 -10
  238. package/dist/src/core/text-rendering/TextGenerator.js +0 -36
  239. package/dist/src/core/text-rendering/TextGenerator.js.map +0 -1
  240. package/src/core/renderers/webgl/SdfRenderOp.ts +0 -106
@@ -227,7 +227,9 @@ export const wrapText = (
227
227
  : [[['', 0, false, 0, 0]], remainingLines, i < lines.length - 1];
228
228
 
229
229
  remainingLines--;
230
- wrappedLines.push(...wrappedLine);
230
+ for (let j = 0; j < wrappedLine.length; j++) {
231
+ wrappedLines.push(wrappedLine[j]!);
232
+ }
231
233
 
232
234
  if (hasMaxLines === true && remainingLines <= 0) {
233
235
  const lastLine = wrappedLines[wrappedLines.length - 1]!;
@@ -278,44 +280,75 @@ export const wrapLine = (
278
280
  let hasRemainingText = true;
279
281
 
280
282
  const wrapFn = getWrapStrategy(wordBreak);
281
- while (words.length > 0 && remainingLines > 0) {
282
- let word = words.shift()!;
283
- let wordWidth = measureText(word, fontFamily, letterSpacing);
283
+ let wordIdx = 0;
284
+ let spaceIdx = 0;
285
+ let pendingWord = '';
286
+
287
+ while (
288
+ (pendingWord.length > 0 || wordIdx < words.length) &&
289
+ remainingLines > 0
290
+ ) {
291
+ let word: string;
292
+ let wordWidth: number;
284
293
  let remainingWord = '';
285
294
 
295
+ if (pendingWord.length > 0) {
296
+ word = pendingWord;
297
+ pendingWord = '';
298
+ } else {
299
+ word = words[wordIdx++]!;
300
+ }
301
+ wordWidth = measureText(word, fontFamily, letterSpacing);
302
+
286
303
  //handle first word of new line separately to avoid empty line issues
287
304
  if (currentLineWidth === 0) {
288
305
  // Word doesn't fit on current line
289
306
  //if first word doesn't fit on empty line
290
307
  if (wordWidth > maxWidth) {
291
308
  remainingLines--;
309
+ const isLastLine = remainingLines === 0;
310
+ let lineTruncated = isLastLine;
292
311
  //truncate word to fit
293
- [word, remainingWord, wordWidth] =
294
- remainingLines === 0
295
- ? truncateWord(
296
- measureText,
297
- word,
298
- wordWidth,
299
- maxWidth,
300
- fontFamily,
301
- letterSpacing,
302
- overflowSuffix,
303
- overflowWidth,
304
- )
305
- : splitWord(
306
- measureText,
307
- word,
308
- wordWidth,
309
- maxWidth,
310
- fontFamily,
311
- letterSpacing,
312
- );
312
+ [word, remainingWord, wordWidth] = isLastLine
313
+ ? truncateWord(
314
+ measureText,
315
+ word,
316
+ wordWidth,
317
+ maxWidth,
318
+ fontFamily,
319
+ letterSpacing,
320
+ overflowSuffix,
321
+ overflowWidth,
322
+ )
323
+ : splitWord(
324
+ measureText,
325
+ word,
326
+ wordWidth,
327
+ maxWidth,
328
+ fontFamily,
329
+ letterSpacing,
330
+ );
313
331
 
314
332
  if (remainingWord.length > 0) {
315
- words.unshift(remainingWord);
333
+ if (word.length === 0) {
334
+ if (overflowSuffix.length > 0) {
335
+ word = overflowSuffix;
336
+ wordWidth = overflowWidth;
337
+ } else {
338
+ word = remainingWord.charAt(0);
339
+ if (word.length === 0) {
340
+ break;
341
+ }
342
+ wordWidth = measureText(word, fontFamily, letterSpacing);
343
+ }
344
+ remainingWord = '';
345
+ remainingLines = 0;
346
+ lineTruncated = true;
347
+ }
348
+ pendingWord = remainingWord;
316
349
  }
317
350
  // first word doesn't fit on an empty line
318
- wrappedLines.push([word, wordWidth, false, 0, 0]);
351
+ wrappedLines.push([word, wordWidth, lineTruncated, 0, 0]);
319
352
  } else if (wordWidth + spaceWidth >= maxWidth) {
320
353
  remainingLines--;
321
354
  // word with space doesn't fit, but word itself fits - put on new line
@@ -326,7 +359,7 @@ export const wrapLine = (
326
359
  }
327
360
  continue;
328
361
  }
329
- const space = spaces.shift() || '';
362
+ const space = spaces[spaceIdx++] || '';
330
363
  // For width calculation, treat ZWSP as having 0 width but regular space functionality
331
364
  const effectiveSpaceWidth = space === '\u200B' ? 0 : spaceWidth;
332
365
  const totalWidth = currentLineWidth + effectiveSpaceWidth + wordWidth;
@@ -367,7 +400,7 @@ export const wrapLine = (
367
400
  );
368
401
 
369
402
  if (remainingWord.length > 0) {
370
- words.unshift(remainingWord);
403
+ pendingWord = remainingWord;
371
404
  }
372
405
  }
373
406
 
@@ -17,8 +17,8 @@
17
17
  * limitations under the License.
18
18
  */
19
19
 
20
- import type { CoreTextNodeProps } from '../CoreTextNode.js';
21
- import type { CoreRenderer } from '../renderers/CoreRenderer.js';
20
+ import type { CoreTextNode, CoreTextNodeProps } from '../CoreTextNode.js';
21
+ import type { WebGlCtxTexture } from '../renderers/webgl/WebGlCtxTexture.js';
22
22
  import type { Stage } from '../Stage.js';
23
23
 
24
24
  // Text baseline and vertical align types
@@ -385,24 +385,31 @@ export interface TextRenderProps {
385
385
  glBufferRef: { current: WebGLBuffer | null };
386
386
  }
387
387
 
388
- export interface TextRenderInfo {
388
+ export interface RenderInfo {
389
389
  width: number;
390
390
  height: number;
391
- hasRemainingText?: boolean;
392
- remainingLines?: number;
393
- imageData?: ImageData | null; // Image data for Canvas Text Renderer
394
- layout?: TextLayout; // Layout data for SDF renderer caching
391
+ hasRemainingText: boolean;
392
+ remainingLines: number;
395
393
  }
396
394
 
395
+ export type SdfRenderInfo = RenderInfo & {
396
+ type: 'sdf';
397
+ layout: TextLayout;
398
+ atlasTexture: WebGlCtxTexture;
399
+ };
400
+
401
+ export type CanvasRenderInfo = RenderInfo & {
402
+ type: 'canvas';
403
+ imageData: ImageData;
404
+ };
405
+
406
+ export type TextRenderInfo = SdfRenderInfo | CanvasRenderInfo;
407
+
397
408
  export interface TextRenderer {
398
409
  type: 'canvas' | 'sdf';
399
410
  font: FontHandler;
400
411
  renderText: (props: CoreTextNodeProps) => TextRenderInfo;
401
- renderQuads: (
402
- renderer: CoreRenderer,
403
- layout: TextLayout,
404
- renderProps: TextRenderProps,
405
- ) => void;
412
+ renderQuads: (textNode: CoreTextNode) => void;
406
413
  init: (stage: Stage) => void;
407
414
  clearCache: () => void;
408
415
  }
@@ -247,6 +247,26 @@ describe('SDF Text Utils', () => {
247
247
  expect(result[0].length).toBeGreaterThan(1);
248
248
  expect(result[0][0]?.[0]).toBe('hello world test');
249
249
  });
250
+
251
+ it('should return non-empty output when maxWidth is smaller than glyph and suffix width', () => {
252
+ const result = wrapLine(
253
+ testMeasureText,
254
+ 'hello',
255
+ 'Arial',
256
+ 5,
257
+ 0,
258
+ 10,
259
+ '...',
260
+ 30,
261
+ 'break-word',
262
+ 1,
263
+ );
264
+
265
+ expect(result[0]).toHaveLength(1);
266
+ expect(result[0][0]?.[0]).toBe('...');
267
+ expect(result[0][0]?.[2]).toBe(true);
268
+ expect(result[1]).toBe(0);
269
+ });
250
270
  });
251
271
 
252
272
  describe('wrapText', () => {
@@ -143,6 +143,24 @@ export class ImageTexture extends Texture {
143
143
  }
144
144
 
145
145
  override async getTextureSource(): Promise<TextureData> {
146
+ // Compressed textures are not supported by the Canvas2D renderer.
147
+ // Fail fast here before incurring a network fetch or binary decode.
148
+ if (this.txManager.renderer?.mode === 'canvas') {
149
+ const { src, type } = this.props;
150
+ if (
151
+ type === 'compressed' ||
152
+ (typeof src === 'string' && isCompressedTextureContainer(src) === true)
153
+ ) {
154
+ const err = new Error(
155
+ `ImageTexture: Compressed textures are not supported in Canvas2D render mode (src: ${String(
156
+ src,
157
+ )})`,
158
+ );
159
+ this.setState('failed', err);
160
+ return { data: null };
161
+ }
162
+ }
163
+
146
164
  let resp: TextureData;
147
165
  try {
148
166
  resp = await this.determineImageTypeAndLoadImage();
@@ -252,6 +252,11 @@ export abstract class Texture extends EventEmitter {
252
252
  return false;
253
253
  }
254
254
 
255
+ // Don't cleanup a texture that is in the process of loading
256
+ if (this.state === 'loading') {
257
+ return false;
258
+ }
259
+
255
260
  // Don't cleanup if not renderable
256
261
  if (this.renderable === true) {
257
262
  return false;
@@ -353,6 +358,7 @@ export abstract class Texture extends EventEmitter {
353
358
  */
354
359
  free(): void {
355
360
  this.ctxTexture?.free();
361
+ this.ctxTexture = undefined;
356
362
  }
357
363
 
358
364
  /**
@@ -740,12 +740,13 @@ export class Inspector {
740
740
  }
741
741
 
742
742
  createDiv(
743
- id: number,
743
+ node: CoreNode,
744
744
  properties: CoreNodeProps | CoreTextNodeProps,
745
745
  ): HTMLElement {
746
746
  const div = document.createElement('div');
747
747
  div.style.position = 'absolute';
748
- div.id = id.toString();
748
+ div.id = node.id.toString();
749
+ div.setAttribute('type', node.constructor.name);
749
750
 
750
751
  // set initial properties
751
752
  for (const key in properties) {
@@ -780,7 +781,7 @@ export class Inspector {
780
781
  }
781
782
 
782
783
  createNode(node: CoreNode): CoreNode {
783
- const div = this.createDiv(node.id, node.props);
784
+ const div = this.createDiv(node, node.props);
784
785
  (div as HTMLElement & { node: CoreNode }).node = node;
785
786
  (node as CoreNode & { div: HTMLElement }).div = div;
786
787
 
@@ -796,7 +797,7 @@ export class Inspector {
796
797
  // eslint-disable-next-line
797
798
  // @ts-ignore - textProps is a private property and keeping it that way
798
799
  // but we need it from the inspector to set the initial properties on the div element
799
- const div = this.createDiv(node.id, node.textProps);
800
+ const div = this.createDiv(node, node.textProps);
800
801
  (div as HTMLElement & { node: CoreNode }).node = node;
801
802
  (node as CoreTextNode & { div: HTMLElement }).div = div;
802
803
 
@@ -897,16 +898,16 @@ export class Inspector {
897
898
  };
898
899
  // Define traps for each property in knownProperties
899
900
  knownProperties.forEach((property) => {
900
- let originalProp = Object.getOwnPropertyDescriptor(node, property);
901
-
902
- if (originalProp === undefined) {
903
- // Search the prototype chain for the property descriptor
904
- const proto = Object.getPrototypeOf(node) as CoreNode | CoreTextNode;
905
- originalProp = Object.getOwnPropertyDescriptor(proto, property);
906
- }
907
-
908
- if (originalProp === undefined) {
909
- return;
901
+ let proto: CoreNode | ObjectConstructor | null = node;
902
+ let originalProp: PropertyDescriptor | undefined | null = Object.getOwnPropertyDescriptor(proto, property);
903
+
904
+ // Search the prototype chain for the property descriptor
905
+ while(originalProp === undefined) {
906
+ proto = Object.getPrototypeOf(proto) as ObjectConstructor;
907
+ if (proto === null) {
908
+ return;
909
+ }
910
+ originalProp = Object.getOwnPropertyDescriptor(proto, property);
910
911
  }
911
912
 
912
913
  if (property === 'text') {
@@ -1101,7 +1102,7 @@ export class Inspector {
1101
1102
  value: any,
1102
1103
  props: CoreNodeProps | CoreTextNodeProps,
1103
1104
  ) {
1104
- if (this.root === null || value === undefined || value === null) {
1105
+ if (this.root === null || value === undefined) {
1105
1106
  return;
1106
1107
  }
1107
1108
 
@@ -1109,17 +1110,16 @@ export class Inspector {
1109
1110
  * Special case for parent property
1110
1111
  */
1111
1112
  if (property === 'parent') {
1112
- const parentId: number = value.id;
1113
-
1114
- // only way to detect if the parent is the root node
1115
- // if you are reading this and have a better way, please let me know
1116
- if (parentId === 1) {
1117
- this.root.appendChild(div);
1118
- return;
1113
+ if (value) {
1114
+ // detect if the parent is the root node
1115
+ if (value.id === value.stage.root.id) {
1116
+ this.root.appendChild(div);
1117
+ } else {
1118
+ value.div.appendChild(div);
1119
+ }
1120
+ } else {
1121
+ div.parentNode?.removeChild(div);
1119
1122
  }
1120
-
1121
- const parent = document.getElementById(parentId.toString());
1122
- parent?.appendChild(div);
1123
1123
  return;
1124
1124
  }
1125
1125
 
@@ -1,10 +0,0 @@
1
- import type { Stage } from "../Stage";
2
- import type { FontLoadOptions, TextRenderer, TextRenderers } from "./TextRenderer";
3
- export default class TextGenerator {
4
- readonly stage: Stage;
5
- private layoutCache;
6
- fontEngines: Record<string, TextRenderer>;
7
- constructor(stage: Stage, fontEngines: TextRenderer[]);
8
- loadFont(rendererType: TextRenderers, options: FontLoadOptions): any;
9
- destroy(): void;
10
- }
@@ -1,36 +0,0 @@
1
- export default class TextGenerator {
2
- stage;
3
- layoutCache = new Map();
4
- fontEngines = {};
5
- constructor(stage, fontEngines) {
6
- this.stage = stage;
7
- if (stage.renderer.mode === 'canvas') {
8
- //filter out SDF renderer if the main renderer is canvas, since SDF rendering is not supported in that case
9
- fontEngines = fontEngines.filter(engine => {
10
- if (engine.type === 'canvas') {
11
- return true;
12
- }
13
- console.warn(`SDF text rendering is not supported in canvas mode. The SDF text renderer will be ignored.`);
14
- return false;
15
- });
16
- }
17
- for (let i = 0; i < fontEngines.length; i++) {
18
- const engine = fontEngines[i];
19
- this.fontEngines[engine.type] = engine;
20
- engine.init(stage);
21
- }
22
- }
23
- loadFont(rendererType, options) {
24
- const rendererTypeKey = String(rendererType);
25
- const fontEngine = this.fontEngines[rendererTypeKey];
26
- if (fontEngine === undefined) {
27
- throw new Error(`Font handler for renderer type '${rendererTypeKey}' not found. Available types: ${Object.keys(this.fontEngines).join(', ')}`);
28
- }
29
- return fontEngine.font.loadFont(this.stage, options);
30
- }
31
- destroy() {
32
- // Clean up resources if necessary
33
- this.layoutCache.clear();
34
- }
35
- }
36
- //# sourceMappingURL=TextGenerator.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"TextGenerator.js","sourceRoot":"","sources":["../../../../src/core/text-rendering/TextGenerator.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,OAAO,OAAO,aAAa;IAKX;IAJb,WAAW,GAA4B,IAAI,GAAG,EAAE,CAAC;IAEzD,WAAW,GAAiC,EAAE,CAAC;IAE/C,YAAqB,KAAY,EAAE,WAA2B;QAAzC,UAAK,GAAL,KAAK,CAAO;QAC/B,IAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACpC,2GAA2G;YAC3G,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;gBACxC,IAAG,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC5B,OAAO,IAAI,CAAC;gBACd,CAAC;gBACD,OAAO,CAAC,IAAI,CAAC,4FAA4F,CAAC,CAAC;gBAC3G,OAAO,KAAK,CAAC;YACf,CAAC,CAAC,CAAC;QACL,CAAC;QAED,KAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3C,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAE,CAAC;YAC/B,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;YACvC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAGD,QAAQ,CAAC,YAA2B,EAAE,OAAwB;QAC5D,MAAM,eAAe,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;QAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;QAErD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CACb,mCAAmC,eAAe,iCAAiC,MAAM,CAAC,IAAI,CAC5F,IAAI,CAAC,WAAW,CACjB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACf,CAAC;QACJ,CAAC;QAED,OAAO,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACvD,CAAC;IAED,OAAO;QAEL,kCAAkC;QAClC,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;CACF"}
@@ -1,106 +0,0 @@
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 { CoreRenderOp } from '../CoreRenderOp.js';
21
- import type { WebGlCtxTexture } from './WebGlCtxTexture.js';
22
- import type { WebGlRenderer } from './WebGlRenderer.js';
23
- import type { BufferCollection } from './internal/BufferCollection.js';
24
- import type { WebGlShaderNode } from './WebGlShaderNode.js';
25
- import type { RectWithValid } from '../../lib/utils.js';
26
- import type { Dimensions } from '../../../common/CommonTypes.js';
27
- import type { Stage } from '../../Stage.js';
28
-
29
- /**
30
- * Can render multiple quads with multiple textures (up to vertex shader texture limit)
31
- *
32
- */
33
- export class SdfRenderOp extends CoreRenderOp {
34
- public numQuads = 0;
35
- public readonly isCoreNode = false as const;
36
- public renderOpTextures: WebGlCtxTexture[] = [];
37
- public time: number = 0;
38
- readonly stage: Stage;
39
-
40
- constructor(
41
- readonly renderer: WebGlRenderer,
42
- readonly shader: WebGlShaderNode,
43
- readonly sdfShaderProps: Record<string, unknown>,
44
- readonly quadBufferCollection: BufferCollection,
45
- readonly worldAlpha: number,
46
- readonly clippingRect: RectWithValid,
47
- readonly w: number,
48
- readonly h: number,
49
- readonly rtt: boolean,
50
- readonly parentHasRenderTexture: boolean,
51
- readonly framebufferDimensions: Dimensions | null,
52
- ) {
53
- super();
54
- this.stage = renderer.stage;
55
- }
56
-
57
- addTexture(texture: WebGlCtxTexture): number {
58
- const { renderOpTextures } = this;
59
- const length = renderOpTextures.length;
60
-
61
- // We only support 1 texture (atlas) for SDF for now, but following the pattern
62
- for (let i = 0; i < length; i++) {
63
- if (renderOpTextures[i] === texture) {
64
- return i;
65
- }
66
- }
67
-
68
- renderOpTextures.push(texture);
69
- return length;
70
- }
71
-
72
- draw() {
73
- const { glw, stage } = this.renderer;
74
- const canvas = stage.platform!.canvas!;
75
-
76
- stage.shManager.useShader(this.shader.program);
77
- this.shader.program.bindRenderOp(this);
78
-
79
- // Clipping
80
- if (this.clippingRect.valid === true) {
81
- const pixelRatio = this.parentHasRenderTexture ? 1 : stage.pixelRatio;
82
- const clipX = Math.round(this.clippingRect.x * pixelRatio);
83
- const clipWidth = Math.round(this.clippingRect.w * pixelRatio);
84
- const clipHeight = Math.round(this.clippingRect.h * pixelRatio);
85
- let clipY = Math.round(
86
- canvas.height - clipHeight - this.clippingRect.y * pixelRatio,
87
- );
88
- // if parent has render texture, we need to adjust the scissor rect
89
- // to be relative to the parent's framebuffer
90
- if (this.parentHasRenderTexture) {
91
- clipY = this.framebufferDimensions
92
- ? this.framebufferDimensions.h - this.h
93
- : 0;
94
- }
95
-
96
- glw.setScissorTest(true);
97
- glw.scissor(clipX, clipY, clipWidth, clipHeight);
98
- } else {
99
- glw.setScissorTest(false);
100
- }
101
-
102
- // SDF rendering uses drawArrays with explicit triangle vertices (6 vertices per quad)
103
- // Note: buffers should be bound by bindRenderOp -> bindBufferCollection
104
- glw.drawArrays(glw.TRIANGLES, 0, 6 * this.numQuads);
105
- }
106
- }