@solidtv/renderer 1.0.4 → 1.0.6

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 (49) hide show
  1. package/dist/src/core/CoreNode.d.ts +34 -1
  2. package/dist/src/core/CoreNode.js +48 -56
  3. package/dist/src/core/CoreNode.js.map +1 -1
  4. package/dist/src/core/CoreTextNode.d.ts +2 -0
  5. package/dist/src/core/CoreTextNode.js +35 -18
  6. package/dist/src/core/CoreTextNode.js.map +1 -1
  7. package/dist/src/core/CoreTextureManager.js +0 -1
  8. package/dist/src/core/CoreTextureManager.js.map +1 -1
  9. package/dist/src/core/Stage.js +3 -0
  10. package/dist/src/core/Stage.js.map +1 -1
  11. package/dist/src/core/TextureMemoryManager.d.ts +0 -13
  12. package/dist/src/core/TextureMemoryManager.js +0 -24
  13. package/dist/src/core/TextureMemoryManager.js.map +1 -1
  14. package/dist/src/core/animations/AnimationManager.d.ts +1 -0
  15. package/dist/src/core/animations/AnimationManager.js.map +1 -1
  16. package/dist/src/core/animations/CoreAnimation.d.ts +1 -0
  17. package/dist/src/core/animations/CoreAnimation.js +1 -0
  18. package/dist/src/core/animations/CoreAnimation.js.map +1 -1
  19. package/dist/src/core/renderers/webgl/WebGlRenderer.js +4 -6
  20. package/dist/src/core/renderers/webgl/WebGlRenderer.js.map +1 -1
  21. package/dist/src/core/text-rendering/CanvasTextRenderer.js +12 -1
  22. package/dist/src/core/text-rendering/CanvasTextRenderer.js.map +1 -1
  23. package/dist/src/core/text-rendering/SdfFontHandler.js +5 -4
  24. package/dist/src/core/text-rendering/SdfFontHandler.js.map +1 -1
  25. package/dist/src/core/text-rendering/SdfTextRenderer.js +16 -6
  26. package/dist/src/core/text-rendering/SdfTextRenderer.js.map +1 -1
  27. package/dist/src/core/text-rendering/TextRenderer.d.ts +0 -31
  28. package/dist/src/main-api/Inspector.js +78 -5
  29. package/dist/src/main-api/Inspector.js.map +1 -1
  30. package/dist/src/main-api/Renderer.js +4 -2
  31. package/dist/src/main-api/Renderer.js.map +1 -1
  32. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  33. package/dist/tsconfig.tsbuildinfo +1 -0
  34. package/package.json +1 -1
  35. package/src/core/CoreNode.test.ts +47 -46
  36. package/src/core/CoreNode.ts +86 -55
  37. package/src/core/CoreTextNode.ts +38 -23
  38. package/src/core/CoreTextureManager.ts +0 -2
  39. package/src/core/Stage.ts +3 -0
  40. package/src/core/TextureMemoryManager.ts +0 -27
  41. package/src/core/animations/AnimationManager.ts +1 -0
  42. package/src/core/animations/CoreAnimation.ts +2 -1
  43. package/src/core/renderers/webgl/WebGlRenderer.ts +4 -6
  44. package/src/core/text-rendering/CanvasTextRenderer.ts +14 -1
  45. package/src/core/text-rendering/SdfFontHandler.ts +6 -5
  46. package/src/core/text-rendering/SdfTextRenderer.ts +19 -6
  47. package/src/core/text-rendering/TextRenderer.ts +0 -31
  48. package/src/main-api/Inspector.ts +87 -5
  49. package/src/main-api/Renderer.ts +4 -2
@@ -13,7 +13,8 @@ import type { BufferCollection } from './renderers/webgl/internal/BufferCollecti
13
13
  import type { CoreRenderer } from './renderers/CoreRenderer.js';
14
14
  import type { Stage } from './Stage.js';
15
15
  import {
16
- type Texture,
16
+ Texture,
17
+ TextureType,
17
18
  type TextureCoords,
18
19
  type TextureFailedEventHandler,
19
20
  type TextureFreedEventHandler,
@@ -695,6 +696,38 @@ export interface CoreNodeProps {
695
696
  * @default false
696
697
  */
697
698
  preventDestroy?: boolean;
699
+
700
+ /**
701
+ * The name of the framework component that created this node.
702
+ *
703
+ * @remarks
704
+ * When set, the Inspector will create a custom HTML element with this name
705
+ * so that the Chrome DevTools Elements panel displays the component name
706
+ * instead of a generic `<div>`. The value should match the JSX component
707
+ * name as written in source (e.g. `"MyButton"`).
708
+ *
709
+ * This is typically injected by a Babel plugin (e.g. `jsx-locator`) and is
710
+ * only meaningful when the Inspector is enabled.
711
+ *
712
+ * @default `undefined`
713
+ */
714
+ componentName?: string;
715
+
716
+ /**
717
+ * The source file path of the framework component that created this node.
718
+ *
719
+ * @remarks
720
+ * When set alongside {@link componentName}, the Inspector will attach a
721
+ * `data-location` attribute to the DOM element, enabling click-to-source
722
+ * navigation from Chrome DevTools.
723
+ *
724
+ * The value should be an absolute or project-relative path to the component
725
+ * source file, optionally followed by `:line:column`
726
+ * (e.g. `"/src/components/MyButton.tsx:12:3"`).
727
+ *
728
+ * @default `undefined`
729
+ */
730
+ componentLocation?: string;
698
731
  }
699
732
 
700
733
  /**
@@ -806,51 +839,19 @@ export class CoreNode extends EventEmitter {
806
839
  let initialUpdateType =
807
840
  UpdateType.Local | UpdateType.RenderBounds | UpdateType.RenderState;
808
841
 
809
- // Fast-path assign only known keys
810
- const p = (this.props = {
811
- x: props.x,
812
- y: props.y,
813
- w: props.w,
814
- h: props.h,
815
- alpha: props.alpha,
816
- autosize: props.autosize,
817
- clipping: props.clipping,
818
- color: props.color,
819
- colorTop: props.colorTop,
820
- colorBottom: props.colorBottom,
821
- colorLeft: props.colorLeft,
822
- colorRight: props.colorRight,
823
- colorTl: props.colorTl,
824
- colorTr: props.colorTr,
825
- colorBl: props.colorBl,
826
- colorBr: props.colorBr,
827
- scaleX: props.scaleX,
828
- scaleY: props.scaleY,
829
- rotation: props.rotation,
830
- pivotX: props.pivotX,
831
- pivotY: props.pivotY,
832
- mountX: props.mountX,
833
- mountY: props.mountY,
834
- mount: props.mount,
835
- pivot: props.pivot,
836
- zIndex: props.zIndex,
837
- textureOptions: props.textureOptions,
838
- data: props.data,
839
- imageType: props.imageType,
840
- srcX: props.srcX,
841
- srcY: props.srcY,
842
- srcWidth: props.srcWidth,
843
- srcHeight: props.srcHeight,
844
- parent: props.parent,
845
- texture: null,
846
- shader: null,
847
- src: null,
848
- rtt: false,
849
- boundsMargin: null,
850
- scale: null,
851
- interactive: props.interactive,
852
- preventDestroy: props.preventDestroy,
853
- });
842
+ // Use the incoming props object directly — resolveNodeDefaults already
843
+ // creates a fresh object with a consistent shape. Save fields that are
844
+ // re-applied through setters, then null them on props so the setters
845
+ // detect the change.
846
+ const { texture, shader, src, rtt, boundsMargin, interactive, parent } =
847
+ props;
848
+ const p = (this.props = props);
849
+ p.texture = null;
850
+ p.shader = null;
851
+ p.src = null;
852
+ p.rtt = false;
853
+ p.boundsMargin = null;
854
+ p.scale = null;
854
855
 
855
856
  //check if any color props are set for premultiplied color updates
856
857
  if (
@@ -873,17 +874,17 @@ export class CoreNode extends EventEmitter {
873
874
  this.zIndex = p.zIndex;
874
875
  }
875
876
 
876
- if (props.parent !== null) {
877
- props.parent.addChild(this);
877
+ if (parent !== null) {
878
+ parent.addChild(this);
878
879
  }
879
880
 
880
- // Assign props to instances
881
- this.texture = props.texture;
882
- this.shader = props.shader;
883
- this.src = props.src;
884
- this.rtt = props.rtt;
885
- this.boundsMargin = props.boundsMargin;
886
- this.interactive = props.interactive;
881
+ // Assign saved values through setters
882
+ this.texture = texture;
883
+ this.shader = shader;
884
+ this.src = src;
885
+ this.rtt = rtt;
886
+ this.boundsMargin = boundsMargin;
887
+ this.interactive = interactive;
887
888
 
888
889
  // Initialize autosize if enabled
889
890
  if (p.autosize === true) {
@@ -2740,6 +2741,11 @@ export class CoreNode extends EventEmitter {
2740
2741
  this.loadTexture();
2741
2742
  }
2742
2743
 
2744
+ if (this.texture?.type === TextureType.subTexture && this.textureLoaded) {
2745
+ // When setting the texture value of a subtexture but the atlas is already loaded,
2746
+ // requestRenderListUpdate is not triggered, but we still need to update the quad
2747
+ this.isQuadDirty = true;
2748
+ }
2743
2749
  this.setUpdateType(UpdateType.IsRenderable);
2744
2750
  this.updateIsSimple();
2745
2751
  }
@@ -2768,6 +2774,14 @@ export class CoreNode extends EventEmitter {
2768
2774
  return this.props.interactive;
2769
2775
  }
2770
2776
 
2777
+ get componentName(): string | undefined {
2778
+ return this.props.componentName;
2779
+ }
2780
+
2781
+ get componentLocation(): string | undefined {
2782
+ return this.props.componentLocation;
2783
+ }
2784
+
2771
2785
  setRTTUpdates(type: number) {
2772
2786
  this.hasRTTupdates = true;
2773
2787
  this.parent?.setRTTUpdates(type);
@@ -2795,6 +2809,15 @@ export class CoreNode extends EventEmitter {
2795
2809
  values.start = (this as any)[name] ?? 0;
2796
2810
  values.target = value;
2797
2811
  controller.progress = 0;
2812
+
2813
+ if (settings.adaptiveDuration === true) {
2814
+ const now = performance.now();
2815
+ const elapsed = now - controller.lastRunTime;
2816
+ controller.lastRunTime = now;
2817
+ const duration = settings.duration ?? controller.duration;
2818
+ controller.duration = elapsed < duration ? elapsed : duration;
2819
+ }
2820
+
2798
2821
  return controller.start();
2799
2822
  }
2800
2823
  }
@@ -2810,6 +2833,14 @@ export class CoreNode extends EventEmitter {
2810
2833
  return controller.start();
2811
2834
  }
2812
2835
 
2836
+ animateToTarget(prop: string): number | undefined {
2837
+ const animation = this._animations[prop];
2838
+ if (!animation) {
2839
+ return undefined;
2840
+ }
2841
+ return animation.controller.props?.[prop]?.target;
2842
+ }
2843
+
2813
2844
  flush() {
2814
2845
  // no-op
2815
2846
  }
@@ -6,7 +6,7 @@ import type {
6
6
  TextRenderInfo,
7
7
  SdfVertexCache,
8
8
  } from './text-rendering/TextRenderer.js';
9
- import { USE_RTT } from '../utils.js';
9
+ import { USE_RTT, premultiplyColorABGR } from '../utils.js';
10
10
  import {
11
11
  CoreNode,
12
12
  CoreNodeRenderState,
@@ -239,27 +239,23 @@ export class CoreTextNode extends CoreNode implements CoreTextNodeProps {
239
239
  // Handle Canvas renderer (uses ImageData)
240
240
  if (textRendererType === 'canvas') {
241
241
  if (result.imageData === undefined) {
242
- this.emit('failed', {
243
- type: 'text',
244
- error: new Error(
245
- 'Canvas text rendering failed, no image data returned',
246
- ),
247
- } satisfies NodeTextFailedPayload);
248
- return;
249
- }
250
-
251
- this.texture = this.stage.txManager.createTexture('ImageTexture', {
252
- premultiplyAlpha: true,
253
- src: result.imageData as ImageData,
254
- });
255
- // It isn't renderable until the texture is loaded we have to set it to false here to avoid it
256
- // being detected as a renderable default color node in the next frame
257
- // it will be corrected once the texture is loaded
258
- this.setRenderable(false);
259
-
260
- if (this.renderState > CoreNodeRenderState.OutOfBounds) {
261
- // We do want the texture to load immediately
262
- this.texture.setRenderableOwner(this._id, true);
242
+ // Empty text returns no imageData — mark not renderable and continue
243
+ // to update dimensions (w=0, h=0) rather than emitting a failure.
244
+ this.setRenderable(false);
245
+ } else {
246
+ this.texture = this.stage.txManager.createTexture('ImageTexture', {
247
+ premultiplyAlpha: true,
248
+ src: result.imageData as ImageData,
249
+ });
250
+ // It isn't renderable until the texture is loaded we have to set it to false here to avoid it
251
+ // being detected as a renderable default color node in the next frame
252
+ // it will be corrected once the texture is loaded
253
+ this.setRenderable(false);
254
+
255
+ if (this.renderState > CoreNodeRenderState.OutOfBounds) {
256
+ // We do want the texture to load immediately
257
+ this.texture.setRenderableOwner(this._id, true);
258
+ }
263
259
  }
264
260
  }
265
261
 
@@ -300,8 +296,15 @@ export class CoreTextNode extends CoreNode implements CoreTextNodeProps {
300
296
  return;
301
297
  }
302
298
 
303
- // Canvas renderer: use standard texture rendering via CoreNode
299
+ // Canvas renderer: color is baked into the texture to preserve
300
+ // native emoji colors. Use white tint with worldAlpha only.
304
301
  if (this._type === 'canvas') {
302
+ const white = premultiplyColorABGR(0xffffffff, this.worldAlpha);
303
+ this.premultipliedColorTl =
304
+ this.premultipliedColorTr =
305
+ this.premultipliedColorBl =
306
+ this.premultipliedColorBr =
307
+ white;
305
308
  super.renderQuads(renderer);
306
309
  return;
307
310
  }
@@ -558,6 +561,18 @@ export class CoreTextNode extends CoreNode implements CoreTextNodeProps {
558
561
  }
559
562
  }
560
563
 
564
+ override get color(): number {
565
+ return this.props.color;
566
+ }
567
+
568
+ override set color(value: number) {
569
+ super.color = value;
570
+ if (this._type === 'canvas') {
571
+ this._layoutGenerated = false;
572
+ this.setUpdateType(UpdateType.Local);
573
+ }
574
+ }
575
+
561
576
  get forceLoad() {
562
577
  return this.textProps.forceLoad;
563
578
  }
@@ -340,8 +340,6 @@ export class CoreTextureManager extends EventEmitter {
340
340
  * @param immediate - Whether to prioritize the texture for immediate loading
341
341
  */
342
342
  async loadTexture(texture: Texture, priority?: boolean): Promise<void> {
343
- this.stage.txMemManager.removeFromOrphanedTextures(texture);
344
-
345
343
  if (texture.type === TextureType.subTexture) {
346
344
  // ignore subtextures - they get loaded through their parent
347
345
  return;
package/src/core/Stage.ts CHANGED
@@ -979,6 +979,9 @@ export class Stage {
979
979
  data,
980
980
  imageType: props.imageType,
981
981
  interactive: props.interactive ?? false,
982
+ preventDestroy: props.preventDestroy,
983
+ componentName: props.componentName,
984
+ componentLocation: props.componentLocation,
982
985
  };
983
986
  }
984
987
 
@@ -98,7 +98,6 @@ export interface MemoryInfo {
98
98
  export class TextureMemoryManager {
99
99
  private memUsed = 0;
100
100
  private loadedTextures: Set<Texture> = new Set();
101
- private orphanedTextures: Set<Texture> = new Set();
102
101
  private criticalThreshold: number = 124e6;
103
102
  private targetThreshold: number = 0.5;
104
103
  private cleanupInterval: number = 5000;
@@ -127,32 +126,6 @@ export class TextureMemoryManager {
127
126
  this.updateSettings(settings);
128
127
  }
129
128
 
130
- /**
131
- * Add a texture to the orphaned textures list
132
- *
133
- * @param texture - The texture to add to the orphaned textures list
134
- */
135
- addToOrphanedTextures(texture: Texture) {
136
- // if the texture is already in the orphaned textures list add it at the end
137
- if (this.orphanedTextures.has(texture)) {
138
- this.orphanedTextures.delete(texture);
139
- }
140
-
141
- // If the texture can be cleaned up, add it to the orphaned textures list
142
- if (texture.preventCleanup === false) {
143
- this.orphanedTextures.add(texture);
144
- }
145
- }
146
-
147
- /**
148
- * Remove a texture from the orphaned textures list
149
- *
150
- * @param texture - The texture to remove from the orphaned textures list
151
- */
152
- removeFromOrphanedTextures(texture: Texture) {
153
- this.orphanedTextures.delete(texture);
154
- }
155
-
156
129
  /**
157
130
  * Set the memory usage of a texture
158
131
  *
@@ -16,6 +16,7 @@ export interface AnimationConfig extends IAnimationController {
16
16
  manager: AnimationManager;
17
17
  node: CoreNode;
18
18
  duration: number;
19
+ lastRunTime: number;
19
20
  delayFor: number;
20
21
  delay: number;
21
22
  progress: number;
@@ -8,6 +8,7 @@ import type {
8
8
 
9
9
  export interface AnimationSettings {
10
10
  duration: number;
11
+ adaptiveDuration: boolean;
11
12
  delay: number;
12
13
  easing: string | TimingFunction;
13
14
  loop: boolean;
@@ -23,7 +24,6 @@ export function createAnimation(
23
24
  ): AnimationConfig {
24
25
  const easing = settings.easing || 'linear';
25
26
  const delay = settings.delay ?? 0;
26
-
27
27
  let propValues: Record<string, PropValues> | null = null;
28
28
  let shaderPropValues: Record<string, PropValues> | null = null;
29
29
 
@@ -73,6 +73,7 @@ export function createAnimation(
73
73
  shaderProps: shaderPropValues,
74
74
  stoppedResolve: null,
75
75
  stoppedPromise: null,
76
+ lastRunTime: settings.adaptiveDuration ? performance.now() : 0,
76
77
 
77
78
  start() {
78
79
  if (this.state !== 'running' && this.state !== 'scheduled') {
@@ -600,18 +600,16 @@ export class WebGlRenderer extends CoreRenderer {
600
600
 
601
601
  // Pre-compute the merged color (with alpha) packed as ABGR for
602
602
  // UNSIGNED_BYTE normalized attribute.
603
+ // NOTE: Do NOT premultiply RGB by alpha here — the SDF fragment shader
604
+ // already multiplies v_color.rgb by the computed opacity (which includes
605
+ // v_color.a).
603
606
  const mergedColor = mergeColorAlpha(color, worldAlpha);
604
607
  const r = mergedColor >>> 24;
605
608
  const g = (mergedColor >>> 16) & 0xff;
606
609
  const b = (mergedColor >>> 8) & 0xff;
607
610
  const a = mergedColor & 0xff;
608
- // Premultiply alpha into RGB for correct blending
609
- const na = a / 255;
610
- const pr = (r * na) | 0;
611
- const pg = (g * na) | 0;
612
- const pb = (b * na) | 0;
613
611
  // Pack as ABGR uint32 (little-endian read as vec4(r,g,b,a) normalized)
614
- const packedColor = ((a << 24) | (pb << 16) | (pg << 8) | pr) >>> 0;
612
+ const packedColor = ((a << 24) | (b << 16) | (g << 8) | r) >>> 0;
615
613
 
616
614
  // Transform matrix components (column-major 3x3)
617
615
  // Pre-multiply fontScale here to save 4 multiplications per glyph in the hot loop
@@ -77,6 +77,14 @@ const renderText = (props: CoreTextNodeProps): TextRenderInfo => {
77
77
  assertTruthy(canvas, 'Canvas is not initialized');
78
78
  assertTruthy(context, 'Canvas context is not available');
79
79
  assertTruthy(measureContext, 'Canvas measureContext is not available');
80
+
81
+ if (props.text.length === 0) {
82
+ return {
83
+ width: 0,
84
+ height: 0,
85
+ };
86
+ }
87
+
80
88
  // Extract already normalized properties
81
89
  const {
82
90
  text,
@@ -130,7 +138,12 @@ const renderText = (props: CoreTextNodeProps): TextRenderInfo => {
130
138
 
131
139
  canvas.width = canvasW;
132
140
  canvas.height = canvasH;
133
- context.fillStyle = 'white';
141
+ const color = props.color ?? 0xffffffff;
142
+ const r = (color >>> 24) & 0xff;
143
+ const g = (color >>> 16) & 0xff;
144
+ const b = (color >>> 8) & 0xff;
145
+ const a = color & 0xff;
146
+ context.fillStyle = `rgba(${r},${g},${b},${a / 255})`;
134
147
  context.font = font;
135
148
  context.textBaseline = 'hanging';
136
149
 
@@ -417,12 +417,13 @@ export const isFontLoaded = (fontFamily: string): boolean => {
417
417
  */
418
418
  export const getFontMetrics = (
419
419
  fontFamily: string,
420
-
421
420
  fontSize: number,
422
421
  ): NormalizedFontMetrics => {
423
- const out = normalizedMetrics.get(fontFamily);
424
- if (out !== undefined) {
425
- return out;
422
+ const label = fontFamily + '_' + fontSize;
423
+ const metricsCache = normalizedMetrics.get(label);
424
+
425
+ if (metricsCache !== undefined) {
426
+ return metricsCache;
426
427
  }
427
428
  let metrics = fontCache.get(fontFamily)!.metrics;
428
429
  return processFontMetrics(fontFamily, fontSize, metrics);
@@ -433,7 +434,7 @@ export const processFontMetrics = (
433
434
  fontSize: number,
434
435
  metrics: FontMetrics,
435
436
  ): NormalizedFontMetrics => {
436
- const label = fontFamily + fontSize;
437
+ const label = fontFamily + '_' + fontSize;
437
438
  const normalized = normalizeFontMetrics(metrics, fontSize);
438
439
  normalizedMetrics.set(label, normalized);
439
440
  return normalized;
@@ -32,6 +32,10 @@ const init = (stage: Stage): void => {
32
32
  };
33
33
 
34
34
  const font: FontHandler = SdfFontHandler;
35
+ const layoutCache = new Map<string, TextLayout>();
36
+
37
+ const getLayoutCacheKey = (props: CoreTextNodeProps): string =>
38
+ `${props.fontFamily}-${props.fontSize}-${props.letterSpacing}-${props.lineHeight}-${props.maxHeight}-${props.maxWidth}-${props.textAlign}-${props.text}`;
35
39
 
36
40
  /**
37
41
  * SDF text renderer using MSDF/SDF fonts with WebGL
@@ -49,6 +53,18 @@ const renderText = (props: CoreTextNodeProps): TextRenderInfo => {
49
53
  };
50
54
  }
51
55
 
56
+ const cacheKey = getLayoutCacheKey(props);
57
+ let layout = layoutCache.get(cacheKey);
58
+ if (layout !== undefined) {
59
+ return {
60
+ remainingLines: 0,
61
+ hasRemainingText: false,
62
+ width: layout.width,
63
+ height: layout.height,
64
+ layout,
65
+ };
66
+ }
67
+
52
68
  // Get font cache for this font family
53
69
  const fontData = SdfFontHandler.getFontData(props.fontFamily);
54
70
  if (fontData === undefined) {
@@ -60,7 +76,8 @@ const renderText = (props: CoreTextNodeProps): TextRenderInfo => {
60
76
  }
61
77
 
62
78
  // Calculate text layout and generate glyph data for caching
63
- const layout = generateTextLayout(props, fontData);
79
+ layout = generateTextLayout(props, fontData);
80
+ layoutCache.set(cacheKey, layout);
64
81
 
65
82
  // For SDF renderer, ImageData is null since we render via WebGL
66
83
  return {
@@ -68,7 +85,7 @@ const renderText = (props: CoreTextNodeProps): TextRenderInfo => {
68
85
  hasRemainingText: false,
69
86
  width: layout.width,
70
87
  height: layout.height,
71
- layout, // Cache layout for addQuads
88
+ layout,
72
89
  };
73
90
  };
74
91
 
@@ -302,14 +319,10 @@ const generateTextLayout = (
302
319
 
303
320
  // Calculate glyph position and atlas coordinates (in design units)
304
321
  const glyphLayout: GlyphLayout = {
305
- codepoint,
306
- glyphId: glyph.id,
307
322
  x: currentX + glyph.xoffset,
308
323
  y: currentY + glyph.yoffset,
309
324
  width: glyph.width,
310
325
  height: glyph.height,
311
- xOffset: glyph.xoffset,
312
- yOffset: glyph.yoffset,
313
326
  atlasX: glyph.x * invAtlasWidth,
314
327
  atlasY: glyph.y * invAtlasHeight,
315
328
  atlasWidth: glyph.width * invAtlasWidth,
@@ -236,41 +236,10 @@ export interface TrProps extends TrFontProps {
236
236
  * Glyph layout information for WebGL rendering
237
237
  */
238
238
  export interface GlyphLayout {
239
- /**
240
- * Unicode codepoint
241
- */
242
- codepoint: number;
243
- /**
244
- * Glyph ID in the font atlas
245
- */
246
- glyphId: number;
247
- /**
248
- * X position relative to text origin
249
- */
250
239
  x: number;
251
- /**
252
- * Y position relative to text origin
253
- */
254
240
  y: number;
255
- /**
256
- * Width of glyph in font units
257
- */
258
241
  width: number;
259
- /**
260
- * Height of glyph in font units
261
- */
262
242
  height: number;
263
- /**
264
- * X offset for glyph positioning
265
- */
266
- xOffset: number;
267
- /**
268
- * Y offset for glyph positioning
269
- */
270
- yOffset: number;
271
- /**
272
- * Atlas texture coordinates (normalized 0-1)
273
- */
274
243
  atlasX: number;
275
244
  atlasY: number;
276
245
  atlasWidth: number;