@lightningjs/renderer 1.0.1 → 2.1.0

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 (103) hide show
  1. package/README.md +17 -0
  2. package/dist/exports/canvas.d.ts +20 -0
  3. package/dist/exports/canvas.js +39 -0
  4. package/dist/exports/canvas.js.map +1 -0
  5. package/dist/exports/index.d.ts +3 -5
  6. package/dist/exports/index.js +2 -4
  7. package/dist/exports/index.js.map +1 -1
  8. package/dist/exports/inspector.d.ts +4 -0
  9. package/dist/exports/inspector.js +23 -0
  10. package/dist/exports/inspector.js.map +1 -0
  11. package/dist/exports/utils.d.ts +2 -0
  12. package/dist/exports/utils.js +2 -0
  13. package/dist/exports/utils.js.map +1 -1
  14. package/dist/exports/webgl.d.ts +19 -0
  15. package/dist/exports/webgl.js +38 -0
  16. package/dist/exports/webgl.js.map +1 -0
  17. package/dist/src/common/EventEmitter.d.ts +1 -1
  18. package/dist/src/common/IAnimationController.d.ts +1 -1
  19. package/dist/src/common/IEventEmitter.d.ts +8 -0
  20. package/dist/src/common/IEventEmitter.js +18 -0
  21. package/dist/src/common/IEventEmitter.js.map +1 -0
  22. package/dist/src/core/CoreNode.d.ts +66 -2
  23. package/dist/src/core/CoreNode.js +128 -24
  24. package/dist/src/core/CoreNode.js.map +1 -1
  25. package/dist/src/core/CoreTextNode.d.ts +2 -2
  26. package/dist/src/core/CoreTextNode.js +20 -30
  27. package/dist/src/core/CoreTextNode.js.map +1 -1
  28. package/dist/src/core/Stage.d.ts +11 -5
  29. package/dist/src/core/Stage.js +58 -30
  30. package/dist/src/core/Stage.js.map +1 -1
  31. package/dist/src/core/TextureMemoryManager.js +4 -2
  32. package/dist/src/core/TextureMemoryManager.js.map +1 -1
  33. package/dist/src/core/animations/CoreAnimation.js +1 -1
  34. package/dist/src/core/animations/CoreAnimation.js.map +1 -1
  35. package/dist/src/core/lib/ImageWorker.d.ts +1 -1
  36. package/dist/src/core/lib/ImageWorker.js +25 -3
  37. package/dist/src/core/lib/ImageWorker.js.map +1 -1
  38. package/dist/src/core/lib/textureSvg.d.ts +16 -0
  39. package/dist/src/core/lib/textureSvg.js +63 -0
  40. package/dist/src/core/lib/textureSvg.js.map +1 -0
  41. package/dist/src/core/renderers/canvas/CanvasCoreTexture.js +2 -1
  42. package/dist/src/core/renderers/canvas/CanvasCoreTexture.js.map +1 -1
  43. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js +2 -1
  44. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js.map +1 -1
  45. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js +10 -6
  46. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js.map +1 -1
  47. package/dist/src/core/renderers/webgl/shaders/DynamicShader.js +2 -1
  48. package/dist/src/core/renderers/webgl/shaders/DynamicShader.js.map +1 -1
  49. package/dist/src/core/text-rendering/TrFontManager.js +11 -4
  50. package/dist/src/core/text-rendering/TrFontManager.js.map +1 -1
  51. package/dist/src/core/text-rendering/font-face-types/WebTrFontFace.js +13 -5
  52. package/dist/src/core/text-rendering/font-face-types/WebTrFontFace.js.map +1 -1
  53. package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.d.ts +1 -0
  54. package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.js +1 -0
  55. package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.js.map +1 -1
  56. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.d.ts +1 -0
  57. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js +1 -0
  58. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js.map +1 -1
  59. package/dist/src/core/text-rendering/renderers/TextRenderer.d.ts +1 -0
  60. package/dist/src/core/text-rendering/renderers/TextRenderer.js.map +1 -1
  61. package/dist/src/core/textures/ImageTexture.d.ts +52 -0
  62. package/dist/src/core/textures/ImageTexture.js +78 -31
  63. package/dist/src/core/textures/ImageTexture.js.map +1 -1
  64. package/dist/src/core/textures/Texture.d.ts +1 -0
  65. package/dist/src/core/textures/Texture.js +1 -0
  66. package/dist/src/core/textures/Texture.js.map +1 -1
  67. package/dist/src/main-api/Inspector.js +2 -2
  68. package/dist/src/main-api/Inspector.js.map +1 -1
  69. package/dist/src/main-api/Renderer.d.ts +50 -8
  70. package/dist/src/main-api/Renderer.js +8 -7
  71. package/dist/src/main-api/Renderer.js.map +1 -1
  72. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  73. package/dist/tsconfig.tsbuildinfo +1 -0
  74. package/exports/canvas.ts +39 -0
  75. package/exports/index.ts +4 -4
  76. package/exports/inspector.ts +24 -0
  77. package/exports/utils.ts +2 -0
  78. package/exports/webgl.ts +38 -0
  79. package/package.json +5 -7
  80. package/src/common/EventEmitter.ts +1 -1
  81. package/src/common/IAnimationController.ts +1 -1
  82. package/src/common/IEventEmitter.ts +28 -0
  83. package/src/core/CoreNode.test.ts +1 -0
  84. package/src/core/CoreNode.ts +229 -40
  85. package/src/core/CoreTextNode.ts +58 -65
  86. package/src/core/Stage.ts +92 -40
  87. package/src/core/TextureMemoryManager.ts +4 -2
  88. package/src/core/animations/CoreAnimation.ts +2 -1
  89. package/src/core/lib/ImageWorker.ts +44 -7
  90. package/src/core/lib/textureSvg.ts +78 -0
  91. package/src/core/renderers/canvas/CanvasCoreTexture.ts +4 -1
  92. package/src/core/renderers/webgl/WebGlCoreCtxTexture.ts +2 -1
  93. package/src/core/renderers/webgl/WebGlCoreRenderer.ts +11 -6
  94. package/src/core/renderers/webgl/shaders/DynamicShader.ts +1 -0
  95. package/src/core/text-rendering/TrFontManager.ts +15 -4
  96. package/src/core/text-rendering/font-face-types/WebTrFontFace.ts +15 -8
  97. package/src/core/text-rendering/renderers/CanvasTextRenderer.ts +2 -0
  98. package/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.ts +2 -0
  99. package/src/core/text-rendering/renderers/TextRenderer.ts +1 -0
  100. package/src/core/textures/ImageTexture.ts +159 -35
  101. package/src/core/textures/Texture.ts +2 -0
  102. package/src/main-api/Inspector.ts +2 -2
  103. package/src/main-api/Renderer.ts +59 -15
@@ -178,6 +178,11 @@ export enum UpdateType {
178
178
  */
179
179
  ParentRenderTexture = 4096,
180
180
 
181
+ /**
182
+ * Render Bounds update
183
+ */
184
+ RenderBounds = 8192,
185
+
181
186
  /**
182
187
  * None
183
188
  */
@@ -405,6 +410,11 @@ export interface CoreNodeProps {
405
410
  */
406
411
  texture: Texture | null;
407
412
 
413
+ /**
414
+ * Whether to prevent the node from being cleaned up
415
+ * @default false
416
+ */
417
+ preventCleanup: boolean;
408
418
  /**
409
419
  * Options to associate with the Node's Texture
410
420
  */
@@ -613,6 +623,47 @@ export interface CoreNodeProps {
613
623
  * @default `undefined`
614
624
  */
615
625
  data?: CustomDataMap;
626
+
627
+ /**
628
+ * Image Type to explicitly set the image type that is being loaded
629
+ *
630
+ * @remarks
631
+ * This property must be used with a `src` that points at an image. In some cases
632
+ * the extension doesn't provide a reliable representation of the image type. In such
633
+ * cases set the ImageType explicitly.
634
+ *
635
+ * `regular` is used for normal images such as png, jpg, etc
636
+ * `compressed` is used for ETC1/ETC2 compressed images with a PVR or KTX container
637
+ * `svg` is used for scalable vector graphics
638
+ *
639
+ * @default `undefined`
640
+ */
641
+ imageType?: 'regular' | 'compressed' | 'svg' | null;
642
+
643
+ /**
644
+ * She width of the rectangle from which the Image Texture will be extracted.
645
+ * This value can be negative. If not provided, the image's source natural
646
+ * width will be used.
647
+ */
648
+ srcWidth?: number;
649
+ /**
650
+ * The height of the rectangle from which the Image Texture will be extracted.
651
+ * This value can be negative. If not provided, the image's source natural
652
+ * height will be used.
653
+ */
654
+ srcHeight?: number;
655
+ /**
656
+ * The x coordinate of the reference point of the rectangle from which the Texture
657
+ * will be extracted. `width` and `height` are provided. And only works when
658
+ * createImageBitmap is available. Only works when createImageBitmap is supported on the browser.
659
+ */
660
+ srcX?: number;
661
+ /**
662
+ * The y coordinate of the reference point of the rectangle from which the Texture
663
+ * will be extracted. Only used when source `srcWidth` width and `srcHeight` height
664
+ * are provided. Only works when createImageBitmap is supported on the browser.
665
+ */
666
+ srcY?: number;
616
667
  }
617
668
 
618
669
  /**
@@ -692,6 +743,10 @@ export class CoreNode extends EventEmitter {
692
743
  this.rtt = props.rtt;
693
744
 
694
745
  this.updateScaleRotateTransform();
746
+
747
+ this.setUpdateType(
748
+ UpdateType.Local | UpdateType.RenderBounds | UpdateType.RenderState,
749
+ );
695
750
  }
696
751
 
697
752
  //#region Textures
@@ -704,6 +759,7 @@ export class CoreNode extends EventEmitter {
704
759
  // We do this in a microtask to allow listeners to be attached in the same
705
760
  // synchronous task after calling loadTexture()
706
761
  queueMicrotask(() => {
762
+ texture.preventCleanup = this.props.preventCleanup;
707
763
  // Preload texture if required
708
764
  if (this.textureOptions.preload) {
709
765
  texture.ctxTexture.load();
@@ -941,16 +997,42 @@ export class CoreNode extends EventEmitter {
941
997
 
942
998
  this.calculateRenderCoords();
943
999
  this.updateBoundingRect();
944
- this.setUpdateType(
945
- UpdateType.Clipping | UpdateType.RenderState | UpdateType.Children,
946
- );
1000
+
1001
+ this.setUpdateType(UpdateType.RenderState | UpdateType.Children);
1002
+
1003
+ if (this.clipping === true) {
1004
+ this.setUpdateType(UpdateType.Clipping);
1005
+ }
1006
+
947
1007
  childUpdateType |= UpdateType.Global;
948
1008
  }
949
1009
 
1010
+ if (this.updateType & UpdateType.RenderBounds) {
1011
+ this.createRenderBounds();
1012
+ this.setUpdateType(UpdateType.RenderState);
1013
+ this.setUpdateType(UpdateType.Children);
1014
+ }
1015
+
1016
+ if (this.updateType & UpdateType.RenderState) {
1017
+ this.updateRenderState();
1018
+ this.setUpdateType(UpdateType.IsRenderable);
1019
+ }
1020
+
1021
+ if (this.updateType & UpdateType.IsRenderable) {
1022
+ this.updateIsRenderable();
1023
+ }
1024
+
1025
+ if (this.renderState === CoreNodeRenderState.OutOfBounds) {
1026
+ this.updateType = 0;
1027
+ return;
1028
+ }
1029
+
950
1030
  if (this.updateType & UpdateType.Clipping) {
951
1031
  this.calculateClippingRect(parentClippingRect);
952
1032
  this.setUpdateType(UpdateType.Children);
1033
+
953
1034
  childUpdateType |= UpdateType.Clipping;
1035
+ childUpdateType |= UpdateType.RenderBounds;
954
1036
  }
955
1037
 
956
1038
  if (this.updateType & UpdateType.WorldAlpha) {
@@ -1003,17 +1085,8 @@ export class CoreNode extends EventEmitter {
1003
1085
  }
1004
1086
  }
1005
1087
 
1006
- if (this.updateType & UpdateType.RenderState) {
1007
- this.updateRenderState(parentClippingRect);
1008
- this.setUpdateType(UpdateType.IsRenderable);
1009
- }
1010
-
1011
- if (this.updateType & UpdateType.IsRenderable) {
1012
- this.updateIsRenderable();
1013
- }
1014
-
1015
1088
  // No need to update zIndex if there is no parent
1016
- if (parent && this.updateType & UpdateType.CalculatedZIndex) {
1089
+ if (parent !== null && this.updateType & UpdateType.CalculatedZIndex) {
1017
1090
  this.calculateZIndex();
1018
1091
  // Tell parent to re-sort children
1019
1092
  parent.setUpdateType(UpdateType.ZIndexSortedChildren);
@@ -1021,8 +1094,8 @@ export class CoreNode extends EventEmitter {
1021
1094
 
1022
1095
  if (
1023
1096
  this.updateType & UpdateType.Children &&
1024
- this.children.length &&
1025
- !this.rtt
1097
+ this.children.length > 0 &&
1098
+ this.rtt === false
1026
1099
  ) {
1027
1100
  this.children.forEach((child) => {
1028
1101
  // Trigger the depenedent update types on the child
@@ -1104,39 +1177,78 @@ export class CoreNode extends EventEmitter {
1104
1177
  return false;
1105
1178
  }
1106
1179
 
1107
- checkRenderBounds(parentClippingRect: RectWithValid): CoreNodeRenderState {
1180
+ checkRenderBounds(): CoreNodeRenderState {
1108
1181
  assertTruthy(this.renderBound);
1109
- const rectW = parentClippingRect.width || this.stage.root.width;
1110
- const rectH = parentClippingRect.height || this.stage.root.height;
1111
- this.strictBound = createBound(
1112
- parentClippingRect.x,
1113
- parentClippingRect.y,
1114
- parentClippingRect.x + rectW,
1115
- parentClippingRect.y + rectH,
1116
- this.strictBound,
1117
- );
1182
+ assertTruthy(this.strictBound);
1183
+ assertTruthy(this.preloadBound);
1118
1184
 
1119
1185
  if (boundInsideBound(this.renderBound, this.strictBound)) {
1120
1186
  return CoreNodeRenderState.InViewport;
1121
1187
  }
1122
1188
 
1189
+ if (boundInsideBound(this.renderBound, this.preloadBound)) {
1190
+ return CoreNodeRenderState.InBounds;
1191
+ }
1192
+
1193
+ return CoreNodeRenderState.OutOfBounds;
1194
+ }
1195
+
1196
+ createPreloadBounds(strictBound: Bound): Bound {
1123
1197
  const renderM = this.stage.boundsMargin;
1124
- this.preloadBound = createBound(
1125
- this.strictBound.x1 - renderM[3],
1126
- this.strictBound.y1 - renderM[0],
1127
- this.strictBound.x2 + renderM[1],
1128
- this.strictBound.y2 + renderM[2],
1198
+ return createBound(
1199
+ strictBound.x1 - renderM[3],
1200
+ strictBound.y1 - renderM[0],
1201
+ strictBound.x2 + renderM[1],
1202
+ strictBound.y2 + renderM[2],
1129
1203
  this.preloadBound,
1130
1204
  );
1205
+ }
1131
1206
 
1132
- if (boundInsideBound(this.renderBound, this.preloadBound)) {
1133
- return CoreNodeRenderState.InBounds;
1207
+ createRenderBounds(): void {
1208
+ assertTruthy(this.stage);
1209
+
1210
+ // no clipping, use parent's bounds
1211
+ if (this.clipping === false) {
1212
+ if (this.parent !== null) {
1213
+ this.strictBound =
1214
+ this.parent.strictBound ??
1215
+ createBound(0, 0, this.stage.root.width, this.stage.root.height);
1216
+
1217
+ this.preloadBound =
1218
+ this.parent.preloadBound ??
1219
+ this.createPreloadBounds(this.strictBound);
1220
+ return;
1221
+ } else {
1222
+ this.strictBound = createBound(
1223
+ 0,
1224
+ 0,
1225
+ this.stage.root.width,
1226
+ this.stage.root.height,
1227
+ );
1228
+
1229
+ this.preloadBound = this.createPreloadBounds(this.strictBound);
1230
+ return;
1231
+ }
1134
1232
  }
1135
- return CoreNodeRenderState.OutOfBounds;
1233
+
1234
+ // clipping is enabled create our own bounds
1235
+ const { x, y, width, height } = this.props;
1236
+ const { tx, ty } = this.globalTransform || {};
1237
+ const _x = tx ?? x;
1238
+ const _y = ty ?? y;
1239
+ this.strictBound = createBound(
1240
+ _x,
1241
+ _y,
1242
+ _x + width,
1243
+ _y + height,
1244
+ this.strictBound,
1245
+ );
1246
+
1247
+ this.preloadBound = this.createPreloadBounds(this.strictBound);
1136
1248
  }
1137
1249
 
1138
- updateRenderState(parentClippingRect: RectWithValid) {
1139
- const renderState = this.checkRenderBounds(parentClippingRect);
1250
+ updateRenderState() {
1251
+ const renderState = this.checkRenderBounds();
1140
1252
 
1141
1253
  if (renderState === this.renderState) {
1142
1254
  return;
@@ -1253,7 +1365,7 @@ export class CoreNode extends EventEmitter {
1253
1365
 
1254
1366
  const isRotated = gt.tb !== 0 || gt.tc !== 0;
1255
1367
 
1256
- if (clipping && !isRotated) {
1368
+ if (clipping === true && isRotated === false) {
1257
1369
  clippingRect.x = gt.tx;
1258
1370
  clippingRect.y = gt.ty;
1259
1371
  clippingRect.width = this.width * gt.ta;
@@ -1263,10 +1375,10 @@ export class CoreNode extends EventEmitter {
1263
1375
  clippingRect.valid = false;
1264
1376
  }
1265
1377
 
1266
- if (parentClippingRect.valid && clippingRect.valid) {
1378
+ if (parentClippingRect.valid === true && clippingRect.valid === true) {
1267
1379
  // Intersect parent clipping rect with node clipping rect
1268
1380
  intersectRect(parentClippingRect, clippingRect, clippingRect);
1269
- } else if (parentClippingRect.valid) {
1381
+ } else if (parentClippingRect.valid === true) {
1270
1382
  // Copy parent clipping rect
1271
1383
  copyRect(parentClippingRect, clippingRect);
1272
1384
  clippingRect.valid = true;
@@ -1387,6 +1499,14 @@ export class CoreNode extends EventEmitter {
1387
1499
  return this._id;
1388
1500
  }
1389
1501
 
1502
+ get data(): CustomDataMap | undefined {
1503
+ return this.props.data;
1504
+ }
1505
+
1506
+ set data(d: CustomDataMap | undefined) {
1507
+ this.props.data = d;
1508
+ }
1509
+
1390
1510
  get x(): number {
1391
1511
  return this.props.x;
1392
1512
  }
@@ -1401,12 +1521,17 @@ export class CoreNode extends EventEmitter {
1401
1521
  get absX(): number {
1402
1522
  return (
1403
1523
  this.props.x +
1524
+ -this.props.width * this.props.mountX +
1404
1525
  (this.props.parent?.absX || this.props.parent?.globalTransform?.tx || 0)
1405
1526
  );
1406
1527
  }
1407
1528
 
1408
1529
  get absY(): number {
1409
- return this.props.y + (this.props.parent?.absY ?? 0);
1530
+ return (
1531
+ this.props.y +
1532
+ -this.props.height * this.props.mountY +
1533
+ (this.props.parent?.absY ?? 0)
1534
+ );
1410
1535
  }
1411
1536
 
1412
1537
  get y(): number {
@@ -1599,7 +1724,9 @@ export class CoreNode extends EventEmitter {
1599
1724
 
1600
1725
  set clipping(value: boolean) {
1601
1726
  this.props.clipping = value;
1602
- this.setUpdateType(UpdateType.Clipping);
1727
+ this.setUpdateType(
1728
+ UpdateType.Clipping | UpdateType.RenderBounds | UpdateType.Children,
1729
+ );
1603
1730
  }
1604
1731
 
1605
1732
  get color(): number {
@@ -1765,6 +1892,17 @@ export class CoreNode extends EventEmitter {
1765
1892
  }
1766
1893
  }
1767
1894
  this.updateScaleRotateTransform();
1895
+
1896
+ // fetch render bounds from parent
1897
+ this.setUpdateType(UpdateType.RenderBounds | UpdateType.Children);
1898
+ }
1899
+
1900
+ get preventCleanup(): boolean {
1901
+ return this.props.preventCleanup;
1902
+ }
1903
+
1904
+ set preventCleanup(value: boolean) {
1905
+ this.props.preventCleanup = value;
1768
1906
  }
1769
1907
 
1770
1908
  get rtt(): boolean {
@@ -1845,9 +1983,60 @@ export class CoreNode extends EventEmitter {
1845
1983
 
1846
1984
  this.texture = this.stage.txManager.loadTexture('ImageTexture', {
1847
1985
  src: imageUrl,
1986
+ width: this.props.width,
1987
+ height: this.props.height,
1988
+ type: this.props.imageType,
1989
+ sx: this.props.srcX,
1990
+ sy: this.props.srcY,
1991
+ sw: this.props.srcWidth,
1992
+ sh: this.props.srcHeight,
1848
1993
  });
1849
1994
  }
1850
1995
 
1996
+ set imageType(type: 'regular' | 'compressed' | 'svg' | null) {
1997
+ if (this.props.imageType === type) {
1998
+ return;
1999
+ }
2000
+
2001
+ this.props.imageType = type;
2002
+ }
2003
+
2004
+ get imageType() {
2005
+ return this.props.imageType || null;
2006
+ }
2007
+
2008
+ get srcHeight(): number | undefined {
2009
+ return this.props.srcHeight;
2010
+ }
2011
+
2012
+ set srcHeight(value: number) {
2013
+ this.props.srcHeight = value;
2014
+ }
2015
+
2016
+ get srcWidth(): number | undefined {
2017
+ return this.props.srcWidth;
2018
+ }
2019
+
2020
+ set srcWidth(value: number) {
2021
+ this.props.srcWidth = value;
2022
+ }
2023
+
2024
+ get srcX(): number | undefined {
2025
+ return this.props.srcX;
2026
+ }
2027
+
2028
+ set srcX(value: number) {
2029
+ this.props.srcX = value;
2030
+ }
2031
+
2032
+ get srcY(): number | undefined {
2033
+ return this.props.srcY;
2034
+ }
2035
+
2036
+ set srcY(value: number) {
2037
+ this.props.srcY = value;
2038
+ }
2039
+
1851
2040
  /**
1852
2041
  * Returns the framebuffer dimensions of the node.
1853
2042
  * If the node has a render texture, the dimensions are the same as the node's dimensions.
@@ -75,37 +75,41 @@ export class CoreTextNode extends CoreNode implements CoreTextNodeProps {
75
75
  private _textRendererOverride: CoreTextNodeProps['textRendererOverride'] =
76
76
  null;
77
77
 
78
- constructor(stage: Stage, props: CoreTextNodeProps) {
78
+ constructor(
79
+ stage: Stage,
80
+ props: CoreTextNodeProps,
81
+ textRenderer: TextRenderer,
82
+ ) {
79
83
  super(stage, props);
80
84
  this._textRendererOverride = props.textRendererOverride;
81
- const { resolvedTextRenderer, textRendererState } =
82
- this.resolveTextRendererAndState({
83
- x: this.absX,
84
- y: this.absY,
85
- width: props.width,
86
- height: props.height,
87
- textAlign: props.textAlign,
88
- color: props.color,
89
- zIndex: props.zIndex,
90
- contain: props.contain,
91
- scrollable: props.scrollable,
92
- scrollY: props.scrollY,
93
- offsetY: props.offsetY,
94
- letterSpacing: props.letterSpacing,
95
- debug: props.debug,
96
- fontFamily: props.fontFamily,
97
- fontSize: props.fontSize,
98
- fontStretch: props.fontStretch,
99
- fontStyle: props.fontStyle,
100
- fontWeight: props.fontWeight,
101
- text: props.text,
102
- lineHeight: props.lineHeight,
103
- maxLines: props.maxLines,
104
- textBaseline: props.textBaseline,
105
- verticalAlign: props.verticalAlign,
106
- overflowSuffix: props.overflowSuffix,
107
- });
108
- this.textRenderer = resolvedTextRenderer;
85
+ this.textRenderer = textRenderer;
86
+ const textRendererState = this.createState({
87
+ x: this.absX,
88
+ y: this.absY,
89
+ width: props.width,
90
+ height: props.height,
91
+ textAlign: props.textAlign,
92
+ color: props.color,
93
+ zIndex: props.zIndex,
94
+ contain: props.contain,
95
+ scrollable: props.scrollable,
96
+ scrollY: props.scrollY,
97
+ offsetY: props.offsetY,
98
+ letterSpacing: props.letterSpacing,
99
+ debug: props.debug,
100
+ fontFamily: props.fontFamily,
101
+ fontSize: props.fontSize,
102
+ fontStretch: props.fontStretch,
103
+ fontStyle: props.fontStyle,
104
+ fontWeight: props.fontWeight,
105
+ text: props.text,
106
+ lineHeight: props.lineHeight,
107
+ maxLines: props.maxLines,
108
+ textBaseline: props.textBaseline,
109
+ verticalAlign: props.verticalAlign,
110
+ overflowSuffix: props.overflowSuffix,
111
+ });
112
+
109
113
  this.trState = textRendererState;
110
114
  }
111
115
 
@@ -199,13 +203,23 @@ export class CoreTextNode extends CoreNode implements CoreTextNodeProps {
199
203
 
200
204
  set textRendererOverride(value: CoreTextNodeProps['textRendererOverride']) {
201
205
  this._textRendererOverride = value;
202
-
203
206
  this.textRenderer.destroyState(this.trState);
204
207
 
205
- const { resolvedTextRenderer, textRendererState } =
206
- this.resolveTextRendererAndState(this.trState.props);
207
- this.textRenderer = resolvedTextRenderer;
208
- this.trState = textRendererState;
208
+ const textRenderer = this.stage.resolveTextRenderer(
209
+ this.trState.props,
210
+ this._textRendererOverride,
211
+ );
212
+
213
+ if (!textRenderer) {
214
+ console.warn(
215
+ 'Text Renderer not found for font',
216
+ this.trState.props.fontFamily,
217
+ );
218
+ return;
219
+ }
220
+
221
+ this.textRenderer = textRenderer;
222
+ this.trState = this.createState(this.trState.props);
209
223
  }
210
224
 
211
225
  get fontSize(): CoreTextNodeProps['fontSize'] {
@@ -301,9 +315,7 @@ export class CoreTextNode extends CoreNode implements CoreTextNodeProps {
301
315
  }
302
316
 
303
317
  set lineHeight(value: CoreTextNodeProps['lineHeight']) {
304
- if (this.textRenderer.set.lineHeight) {
305
- this.textRenderer.set.lineHeight(this.trState, value);
306
- }
318
+ this.textRenderer.set.lineHeight(this.trState, value);
307
319
  }
308
320
 
309
321
  get maxLines(): CoreTextNodeProps['maxLines'] {
@@ -311,9 +323,7 @@ export class CoreTextNode extends CoreNode implements CoreTextNodeProps {
311
323
  }
312
324
 
313
325
  set maxLines(value: CoreTextNodeProps['maxLines']) {
314
- if (this.textRenderer.set.maxLines) {
315
- this.textRenderer.set.maxLines(this.trState, value);
316
- }
326
+ this.textRenderer.set.maxLines(this.trState, value);
317
327
  }
318
328
 
319
329
  get textBaseline(): CoreTextNodeProps['textBaseline'] {
@@ -321,9 +331,7 @@ export class CoreTextNode extends CoreNode implements CoreTextNodeProps {
321
331
  }
322
332
 
323
333
  set textBaseline(value: CoreTextNodeProps['textBaseline']) {
324
- if (this.textRenderer.set.textBaseline) {
325
- this.textRenderer.set.textBaseline(this.trState, value);
326
- }
334
+ this.textRenderer.set.textBaseline(this.trState, value);
327
335
  }
328
336
 
329
337
  get verticalAlign(): CoreTextNodeProps['verticalAlign'] {
@@ -331,9 +339,7 @@ export class CoreTextNode extends CoreNode implements CoreTextNodeProps {
331
339
  }
332
340
 
333
341
  set verticalAlign(value: CoreTextNodeProps['verticalAlign']) {
334
- if (this.textRenderer.set.verticalAlign) {
335
- this.textRenderer.set.verticalAlign(this.trState, value);
336
- }
342
+ this.textRenderer.set.verticalAlign(this.trState, value);
337
343
  }
338
344
 
339
345
  get overflowSuffix(): CoreTextNodeProps['overflowSuffix'] {
@@ -341,9 +347,7 @@ export class CoreTextNode extends CoreNode implements CoreTextNodeProps {
341
347
  }
342
348
 
343
349
  set overflowSuffix(value: CoreTextNodeProps['overflowSuffix']) {
344
- if (this.textRenderer.set.overflowSuffix) {
345
- this.textRenderer.set.overflowSuffix(this.trState, value);
346
- }
350
+ this.textRenderer.set.overflowSuffix(this.trState, value);
347
351
  }
348
352
 
349
353
  get debug(): CoreTextNodeProps['debug'] {
@@ -365,7 +369,7 @@ export class CoreTextNode extends CoreNode implements CoreTextNodeProps {
365
369
  }
366
370
 
367
371
  override checkRenderProps(): boolean {
368
- if (this.trState.props.text !== '') {
372
+ if (this.trState && this.trState.props.text !== '') {
369
373
  return true;
370
374
  }
371
375
  return super.checkRenderProps();
@@ -433,25 +437,14 @@ export class CoreTextNode extends CoreNode implements CoreTextNodeProps {
433
437
  * @param props
434
438
  * @returns
435
439
  */
436
- private resolveTextRendererAndState(props: TrProps): {
437
- resolvedTextRenderer: TextRenderer;
438
- textRendererState: TextRendererState;
439
- } {
440
- const resolvedTextRenderer = this.stage.resolveTextRenderer(
441
- props,
442
- this._textRendererOverride,
443
- );
444
-
445
- const textRendererState = resolvedTextRenderer.createState(props, this);
440
+ private createState(props: TrProps) {
441
+ const textRendererState = this.textRenderer.createState(props, this);
446
442
 
447
443
  textRendererState.emitter.on('loaded', this.onTextLoaded);
448
444
  textRendererState.emitter.on('failed', this.onTextFailed);
449
445
 
450
- resolvedTextRenderer.scheduleUpdateState(textRendererState);
446
+ this.textRenderer.scheduleUpdateState(textRendererState);
451
447
 
452
- return {
453
- resolvedTextRenderer,
454
- textRendererState,
455
- };
448
+ return textRendererState;
456
449
  }
457
450
  }