@lightningjs/renderer 3.0.2 → 3.0.3

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 (97) hide show
  1. package/README.md +56 -196
  2. package/dist/src/core/CoreNode.js +25 -4
  3. package/dist/src/core/CoreNode.js.map +1 -1
  4. package/dist/src/core/CoreTextNode.d.ts +9 -2
  5. package/dist/src/core/CoreTextNode.js +32 -11
  6. package/dist/src/core/CoreTextNode.js.map +1 -1
  7. package/dist/src/core/CoreTextureManager.d.ts +8 -0
  8. package/dist/src/core/CoreTextureManager.js +13 -1
  9. package/dist/src/core/CoreTextureManager.js.map +1 -1
  10. package/dist/src/core/Stage.d.ts +8 -0
  11. package/dist/src/core/Stage.js +23 -0
  12. package/dist/src/core/Stage.js.map +1 -1
  13. package/dist/src/core/TextureMemoryManager.d.ts +8 -13
  14. package/dist/src/core/TextureMemoryManager.js +22 -27
  15. package/dist/src/core/TextureMemoryManager.js.map +1 -1
  16. package/dist/src/core/lib/ImageWorker.d.ts +2 -2
  17. package/dist/src/core/lib/ImageWorker.js +31 -12
  18. package/dist/src/core/lib/ImageWorker.js.map +1 -1
  19. package/dist/src/core/lib/WebGlContextWrapper.d.ts +105 -56
  20. package/dist/src/core/lib/WebGlContextWrapper.js +164 -158
  21. package/dist/src/core/lib/WebGlContextWrapper.js.map +1 -1
  22. package/dist/src/core/lib/textureCompression.js +19 -10
  23. package/dist/src/core/lib/textureCompression.js.map +1 -1
  24. package/dist/src/core/lib/validateImageBitmap.d.ts +2 -1
  25. package/dist/src/core/lib/validateImageBitmap.js +4 -4
  26. package/dist/src/core/lib/validateImageBitmap.js.map +1 -1
  27. package/dist/src/core/platform.js +2 -2
  28. package/dist/src/core/platform.js.map +1 -1
  29. package/dist/src/core/platforms/Platform.d.ts +4 -0
  30. package/dist/src/core/platforms/Platform.js.map +1 -1
  31. package/dist/src/core/platforms/web/WebPlatform.d.ts +2 -0
  32. package/dist/src/core/platforms/web/WebPlatform.js +13 -0
  33. package/dist/src/core/platforms/web/WebPlatform.js.map +1 -1
  34. package/dist/src/core/renderers/CoreRenderer.d.ts +6 -0
  35. package/dist/src/core/renderers/CoreRenderer.js +8 -0
  36. package/dist/src/core/renderers/CoreRenderer.js.map +1 -1
  37. package/dist/src/core/renderers/canvas/CanvasRenderer.d.ts +1 -0
  38. package/dist/src/core/renderers/canvas/CanvasRenderer.js +5 -0
  39. package/dist/src/core/renderers/canvas/CanvasRenderer.js.map +1 -1
  40. package/dist/src/core/renderers/webgl/WebGlRenderOp.d.ts +45 -0
  41. package/dist/src/core/renderers/webgl/WebGlRenderOp.js +127 -0
  42. package/dist/src/core/renderers/webgl/WebGlRenderOp.js.map +1 -0
  43. package/dist/src/core/renderers/webgl/WebGlRenderer.d.ts +2 -0
  44. package/dist/src/core/renderers/webgl/WebGlRenderer.js +30 -22
  45. package/dist/src/core/renderers/webgl/WebGlRenderer.js.map +1 -1
  46. package/dist/src/core/text-rendering/CanvasFont.d.ts +14 -0
  47. package/dist/src/core/text-rendering/CanvasFont.js +120 -0
  48. package/dist/src/core/text-rendering/CanvasFont.js.map +1 -0
  49. package/dist/src/core/text-rendering/CanvasTextRenderer.d.ts +1 -2
  50. package/dist/src/core/text-rendering/CanvasTextRenderer.js +11 -19
  51. package/dist/src/core/text-rendering/CanvasTextRenderer.js.map +1 -1
  52. package/dist/src/core/text-rendering/CoreFont.d.ts +33 -0
  53. package/dist/src/core/text-rendering/CoreFont.js +48 -0
  54. package/dist/src/core/text-rendering/CoreFont.js.map +1 -0
  55. package/dist/src/core/text-rendering/FontManager.d.ts +11 -0
  56. package/dist/src/core/text-rendering/FontManager.js +41 -0
  57. package/dist/src/core/text-rendering/FontManager.js.map +1 -0
  58. package/dist/src/core/text-rendering/SdfFont.d.ts +29 -0
  59. package/dist/src/core/text-rendering/SdfFont.js +142 -0
  60. package/dist/src/core/text-rendering/SdfFont.js.map +1 -0
  61. package/dist/src/core/text-rendering/SdfTextRenderer.d.ts +2 -2
  62. package/dist/src/core/text-rendering/SdfTextRenderer.js +141 -132
  63. package/dist/src/core/text-rendering/SdfTextRenderer.js.map +1 -1
  64. package/dist/src/core/text-rendering/TextGenerator.d.ts +10 -0
  65. package/dist/src/core/text-rendering/TextGenerator.js +36 -0
  66. package/dist/src/core/text-rendering/TextGenerator.js.map +1 -0
  67. package/dist/src/core/text-rendering/TextRenderer.d.ts +26 -20
  68. package/dist/src/core/text-rendering/Utils.d.ts +2 -0
  69. package/dist/src/core/text-rendering/Utils.js +3 -0
  70. package/dist/src/core/text-rendering/Utils.js.map +1 -1
  71. package/dist/src/main-api/Renderer.d.ts +14 -0
  72. package/dist/src/main-api/Renderer.js +29 -3
  73. package/dist/src/main-api/Renderer.js.map +1 -1
  74. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  75. package/package.json +2 -1
  76. package/src/core/CoreNode.ts +29 -4
  77. package/src/core/CoreTextNode.test.ts +237 -0
  78. package/src/core/CoreTextNode.ts +53 -33
  79. package/src/core/CoreTextureManager.ts +14 -2
  80. package/src/core/Stage.ts +29 -0
  81. package/src/core/TextureMemoryManager.test.ts +134 -0
  82. package/src/core/TextureMemoryManager.ts +23 -30
  83. package/src/core/platforms/Platform.ts +5 -0
  84. package/src/core/platforms/web/WebPlatform.ts +13 -0
  85. package/src/core/renderers/CoreRenderer.ts +10 -0
  86. package/src/core/renderers/canvas/CanvasRenderer.ts +6 -0
  87. package/src/core/renderers/webgl/WebGlRenderer.rtt.test.ts +551 -0
  88. package/src/core/renderers/webgl/WebGlRenderer.ts +38 -28
  89. package/src/core/text-rendering/CanvasTextRenderer.ts +13 -41
  90. package/src/core/text-rendering/SdfTextRenderer.ts +166 -163
  91. package/src/core/text-rendering/TextRenderer.ts +23 -21
  92. package/src/core/text-rendering/Utils.ts +5 -1
  93. package/src/main-api/Renderer.test.ts +153 -0
  94. package/src/main-api/Renderer.ts +33 -3
  95. package/dist/src/core/renderers/webgl/WebGlCoreShader.destroy.d.ts +0 -1
  96. package/dist/src/core/renderers/webgl/WebGlCoreShader.destroy.js +0 -2
  97. package/dist/src/core/renderers/webgl/WebGlCoreShader.destroy.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CoreFont.js","sourceRoot":"","sources":["../../../../src/core/text-rendering/CoreFont.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAE5D,MAAM,CAAN,IAAY,SAKX;AALD,WAAY,SAAS;IACnB,+CAAO,CAAA;IACP,+CAAO,CAAA;IACP,6CAAM,CAAA;IACN,6CAAM,CAAA;AACR,CAAC,EALW,SAAS,KAAT,SAAS,QAKpB;AAOD;;GAEG;AACH,MAAM,OAAgB,QAAS,SAAQ,YAAY;IACvC,YAAY,GAAkC,MAAM,CAAC,MAAM,CACnE,IAAI,CAC2B,CAAC;IACxB,iBAAiB,GACzB,MAAM,CAAC,MAAM,CAAC,IAAI,CAA0C,CAAC;IAExD,YAAY,CAAe;IAC3B,KAAK,CAAY;IACjB,MAAM,CAAS;IACf,OAAO,CAAe;IAE7B,YAAY,YAA0B,EAAE,KAAoB;QAC1D,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC;QAC/B,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;IAES,QAAQ;QAChB,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;QACvC,KAAK,IAAI,GAAG,IAAI,YAAY,EAAE,CAAC;YAC7B,YAAY,CAAC,GAAG,CAAE,CAAC,aAAa,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACnD,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC;IAChC,CAAC;IAEM,OAAO,CAAC,IAAkB;QAC/B,IAAI,CAAC,YAAa,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;IACrC,CAAC;IAEM,WAAW,CAAC,IAAkB;QACnC,IAAI,IAAI,CAAC,YAAa,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC,YAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAEM,OAAO;QACZ,OAAO,IAAI,CAAC,YAAY,CAAC;QACzB,OAAO,IAAI,CAAC,iBAAiB,CAAC;QAC9B,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;CAMF"}
@@ -0,0 +1,11 @@
1
+ import type { Stage } from '../Stage.js';
2
+ import type { CoreFont } from './CoreFont.js';
3
+ import type { FontLoadOptions, TextRenderer, TextRenderers } from './TextRenderer.js';
4
+ export declare class CoreFontManager {
5
+ private fonts;
6
+ private renderers;
7
+ constructor(stage: Stage, textRenderers: TextRenderer[]);
8
+ loadFont(type: TextRenderers, options: FontLoadOptions): void;
9
+ unloadFont(fontFamily: string): void;
10
+ getFont(fontFamily: string): CoreFont | undefined;
11
+ }
@@ -0,0 +1,41 @@
1
+ export class CoreFontManager {
2
+ fonts = Object.create(null);
3
+ renderers = Object.create(null);
4
+ constructor(stage, textRenderers) {
5
+ for (let i = 0; i < textRenderers.length; i++) {
6
+ const renderer = textRenderers[i];
7
+ this.renderers[renderer.type] = renderer;
8
+ renderer.init(stage, this);
9
+ }
10
+ }
11
+ loadFont(type, options) {
12
+ const targetRenderer = this.renderers[type];
13
+ if (targetRenderer === undefined) {
14
+ console.error('renderer type for this font does not exist');
15
+ return;
16
+ }
17
+ const font = targetRenderer.createFont(options);
18
+ if (font === undefined) {
19
+ return;
20
+ }
21
+ font.load();
22
+ this.fonts[options.fontFamily] = font;
23
+ }
24
+ unloadFont(fontFamily) {
25
+ const targetFont = this.fonts[fontFamily];
26
+ if (targetFont === undefined) {
27
+ return;
28
+ }
29
+ targetFont.destroy();
30
+ delete this.fonts[fontFamily];
31
+ }
32
+ getFont(fontFamily) {
33
+ const font = this.fonts[fontFamily];
34
+ if (font === undefined) {
35
+ console.warn('fontFamily not registered');
36
+ return;
37
+ }
38
+ return font;
39
+ }
40
+ }
41
+ //# sourceMappingURL=FontManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FontManager.js","sourceRoot":"","sources":["../../../../src/core/text-rendering/FontManager.ts"],"names":[],"mappings":"AAQA,MAAM,OAAO,eAAe;IAClB,KAAK,GAA6B,MAAM,CAAC,MAAM,CAAC,IAAI,CAG3D,CAAC;IACM,SAAS,GAAiC,MAAM,CAAC,MAAM,CAC7D,IAAI,CAC2B,CAAC;IAElC,YAAY,KAAY,EAAE,aAA6B;QACrD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9C,MAAM,QAAQ,GAAG,aAAa,CAAC,CAAC,CAAE,CAAC;YACnC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC;YACzC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,QAAQ,CAAC,IAAmB,EAAE,OAAwB;QACpD,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;YACjC,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;YAC5D,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GAAG,cAAc,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAChD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC;IACxC,CAAC;IAED,UAAU,CAAC,UAAkB;QAC3B,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC1C,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,OAAO;QACT,CAAC;QACD,UAAU,CAAC,OAAO,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAChC,CAAC;IAED,OAAO,CAAC,UAAkB;QACxB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACpC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,OAAO,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;YAC1C,OAAO;QACT,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
@@ -0,0 +1,29 @@
1
+ import type { Stage } from '../Stage.js';
2
+ import type { ImageTexture } from '../textures/ImageTexture.js';
3
+ import { CoreFont, type CoreFontProps } from './CoreFont.js';
4
+ import { type SdfFontData } from './SdfFontHandler.js';
5
+ import type { NormalizedFontMetrics, TextRenderer } from './TextRenderer.js';
6
+ export type SdfFontProps = CoreFontProps & {
7
+ atlasUrl: string;
8
+ atlasDataUrl: string;
9
+ };
10
+ export declare class SdfFont extends CoreFont {
11
+ private stage;
12
+ type: string;
13
+ atlasUrl: string;
14
+ atlasDataUrl: string;
15
+ atlasTexture?: ImageTexture;
16
+ private glyphMap?;
17
+ private kerningTable?;
18
+ private data?;
19
+ constructor(textRenderer: TextRenderer, props: SdfFontProps, stage: Stage);
20
+ load(): void;
21
+ private hardFail;
22
+ private processFontData;
23
+ measureText(text: string, letterSpacing: number): number;
24
+ getMetrics(fontSize: number): NormalizedFontMetrics;
25
+ getGlyph(codepoint: number): import("./SdfFontHandler.js").SdfGlyph | null;
26
+ getKerning(firstGlyph: number, secondGlyph: number): number;
27
+ getAtlas(): ImageTexture;
28
+ getData(): SdfFontData;
29
+ }
@@ -0,0 +1,142 @@
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 2025 Comcast Cable Communications Management, LLC.
6
+ *
7
+ * Licensed under the Apache License, Version 2.0 (the License);
8
+ * you may not use this file except in compliance with the License.
9
+ * You may obtain a copy of the License at
10
+ *
11
+ * http://www.apache.org/licenses/LICENSE-2.0
12
+ *
13
+ * Unless required by applicable law or agreed to in writing, software
14
+ * distributed under the License is distributed on an "AS IS" BASIS,
15
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ */
19
+ import { CoreFont, FontState } from './CoreFont.js';
20
+ import { buildGlyphMap, buildKerningTable, } from './SdfFontHandler.js';
21
+ import { normalizeFontMetrics } from './TextLayoutEngine.js';
22
+ import { hasZeroWidthSpace } from './Utils.js';
23
+ export class SdfFont extends CoreFont {
24
+ stage;
25
+ type = 'sdf';
26
+ atlasUrl;
27
+ atlasDataUrl;
28
+ atlasTexture;
29
+ glyphMap;
30
+ kerningTable;
31
+ data;
32
+ constructor(textRenderer, props, stage) {
33
+ super(textRenderer, props);
34
+ this.stage = stage;
35
+ this.atlasUrl = props.atlasUrl;
36
+ this.atlasDataUrl = props.atlasDataUrl;
37
+ }
38
+ load() {
39
+ new Promise(async () => {
40
+ const atlasData = await fetch(this.atlasDataUrl);
41
+ if (atlasData.ok === false) {
42
+ this.hardFail(`Failed to load font data: ${atlasData.statusText}`);
43
+ }
44
+ const fontData = (await atlasData.json());
45
+ if (fontData.chars === undefined) {
46
+ this.hardFail('Invalid SDF font data format');
47
+ }
48
+ const atlasTexture = this.stage.txManager.createTexture('ImageTexture', {
49
+ src: this.atlasUrl,
50
+ premultiplyAlpha: false,
51
+ });
52
+ atlasTexture.setRenderableOwner(this.family, true);
53
+ atlasTexture.preventCleanup = true;
54
+ atlasTexture.on('loaded', () => {
55
+ this.onLoaded();
56
+ });
57
+ atlasTexture.on('failed', (error) => {
58
+ console.error(`Failed to load SDF font: ${this.family}`, error);
59
+ this.emit('failed');
60
+ });
61
+ this.atlasTexture = atlasTexture;
62
+ this.processFontData(fontData);
63
+ });
64
+ }
65
+ hardFail(message) {
66
+ this.state = FontState.Failed;
67
+ throw new Error(message);
68
+ }
69
+ processFontData(fontData) {
70
+ this.glyphMap = buildGlyphMap(fontData.chars);
71
+ this.kerningTable = buildKerningTable(fontData.kernings);
72
+ this.metrics = this.metrics ||
73
+ fontData.lightningMetrics || {
74
+ ascender: 800,
75
+ descender: -200,
76
+ lineGap: 200,
77
+ unitsPerEm: 1000,
78
+ };
79
+ this.data = fontData;
80
+ }
81
+ measureText(text, letterSpacing) {
82
+ if (text.length === 1) {
83
+ const char = text.charAt(0);
84
+ const codepoint = text.codePointAt(0);
85
+ if (codepoint === undefined)
86
+ return 0;
87
+ if (hasZeroWidthSpace(char) === true)
88
+ return 0;
89
+ const glyph = this.getGlyph(codepoint);
90
+ if (glyph === null)
91
+ return 0;
92
+ return glyph.xadvance + letterSpacing;
93
+ }
94
+ let width = 0;
95
+ let prevCodepoint = 0;
96
+ for (let i = 0; i < text.length; i++) {
97
+ const char = text.charAt(i);
98
+ const codepoint = text.codePointAt(i);
99
+ if (codepoint === undefined)
100
+ continue;
101
+ // Skip zero-width spaces in width calculations
102
+ if (hasZeroWidthSpace(char)) {
103
+ continue;
104
+ }
105
+ const glyph = this.getGlyph(codepoint);
106
+ if (glyph === null)
107
+ continue;
108
+ let advance = glyph.xadvance;
109
+ // Add kerning if there's a previous character
110
+ if (prevCodepoint !== 0) {
111
+ const kerning = this.getKerning(prevCodepoint, codepoint);
112
+ advance += kerning;
113
+ }
114
+ width += advance + letterSpacing;
115
+ prevCodepoint = codepoint;
116
+ }
117
+ return width;
118
+ }
119
+ getMetrics(fontSize) {
120
+ let m = this.normalizedMetrics[fontSize];
121
+ if (m !== undefined) {
122
+ return m;
123
+ }
124
+ m = this.normalizedMetrics[fontSize] = normalizeFontMetrics(this.metrics, fontSize);
125
+ return m;
126
+ }
127
+ getGlyph(codepoint) {
128
+ const gm = this.glyphMap;
129
+ return gm[codepoint] || gm[63] || null;
130
+ }
131
+ getKerning(firstGlyph, secondGlyph) {
132
+ const seconds = this.kerningTable[secondGlyph];
133
+ return (seconds !== undefined && seconds[firstGlyph]) || 0;
134
+ }
135
+ getAtlas() {
136
+ return this.atlasTexture;
137
+ }
138
+ getData() {
139
+ return this.data;
140
+ }
141
+ }
142
+ //# sourceMappingURL=SdfFont.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SdfFont.js","sourceRoot":"","sources":["../../../../src/core/text-rendering/SdfFont.ts"],"names":[],"mappings":"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"}
@@ -10,8 +10,8 @@ declare const SdfTextRenderer: {
10
10
  type: "sdf";
11
11
  font: FontHandler;
12
12
  renderText: (props: CoreTextNodeProps) => TextRenderInfo;
13
- addQuads: (layout?: TextLayout) => Float32Array | null;
14
- renderQuads: (renderer: CoreRenderer, layout: TextLayout, vertexBuffer: Float32Array, renderProps: TextRenderProps) => void;
13
+ renderQuads: (renderer: CoreRenderer, layout: TextLayout, renderProps: TextRenderProps) => void;
15
14
  init: (stage: Stage) => void;
15
+ clearCache: () => void;
16
16
  };
17
17
  export default SdfTextRenderer;
@@ -16,7 +16,7 @@
16
16
  * See the License for the specific language governing permissions and
17
17
  * limitations under the License.
18
18
  */
19
- import { hasZeroWidthSpace } from './Utils.js';
19
+ import { getLayoutCacheKey, hasZeroWidthSpace } from './Utils.js';
20
20
  import * as SdfFontHandler from './SdfFontHandler.js';
21
21
  import { WebGlRenderer } from '../renderers/webgl/WebGlRenderer.js';
22
22
  import { SdfRenderOp } from '../renderers/webgl/SdfRenderOp.js';
@@ -38,6 +38,7 @@ const init = (stage) => {
38
38
  sdfShader = stage.shManager.createShader('Sdf');
39
39
  };
40
40
  const font = SdfFontHandler;
41
+ const layoutCache = new Map();
41
42
  /**
42
43
  * SDF text renderer using MSDF/SDF fonts with WebGL
43
44
  *
@@ -53,6 +54,17 @@ const renderText = (props) => {
53
54
  height: 0,
54
55
  };
55
56
  }
57
+ const cacheKey = getLayoutCacheKey(props);
58
+ let layout = layoutCache.get(cacheKey);
59
+ if (layout !== undefined) {
60
+ return {
61
+ width: layout.width,
62
+ height: layout.height,
63
+ remainingLines: layout.remainingLines,
64
+ hasRemainingText: layout.hasRemainingText,
65
+ layout, // Cache layout for addQuads
66
+ };
67
+ }
56
68
  // Get font cache for this font family
57
69
  const fontData = SdfFontHandler.getFontData(props.fontFamily);
58
70
  if (fontData === undefined) {
@@ -63,89 +75,27 @@ const renderText = (props) => {
63
75
  };
64
76
  }
65
77
  // Calculate text layout and generate glyph data for caching
66
- const layout = generateTextLayout(props, fontData);
78
+ layout = generateTextLayout(props, fontData);
79
+ layoutCache.set(cacheKey, layout);
67
80
  // For SDF renderer, ImageData is null since we render via WebGL
68
81
  return {
69
- remainingLines: 0,
70
- hasRemainingText: false,
71
82
  width: layout.width,
72
83
  height: layout.height,
84
+ remainingLines: layout.remainingLines,
85
+ hasRemainingText: layout.hasRemainingText,
73
86
  layout, // Cache layout for addQuads
74
87
  };
75
88
  };
76
- /**
77
- * Add quads for rendering using cached layout data
78
- */
79
- const addQuads = (layout) => {
80
- if (layout === undefined) {
81
- return null; // No layout data available
82
- }
83
- const glyphs = layout.glyphs;
84
- const glyphsLength = glyphs.length;
85
- if (glyphsLength === 0) {
86
- return null;
87
- }
88
- const vertexBuffer = new Float32Array(glyphsLength * VERTICES_PER_GLYPH * FLOATS_PER_VERTEX);
89
- let bufferIndex = 0;
90
- let glyphIndex = 0;
91
- while (glyphIndex < glyphsLength) {
92
- const glyph = glyphs[glyphIndex];
93
- glyphIndex++;
94
- if (glyph === undefined) {
95
- continue;
96
- }
97
- const x1 = glyph.x;
98
- const y1 = glyph.y;
99
- const x2 = x1 + glyph.width;
100
- const y2 = y1 + glyph.height;
101
- const u1 = glyph.atlasX;
102
- const v1 = glyph.atlasY;
103
- const u2 = u1 + glyph.atlasWidth;
104
- const v2 = v1 + glyph.atlasHeight;
105
- // Triangle 1: Top-left, top-right, bottom-left
106
- // Vertex 1: Top-left
107
- vertexBuffer[bufferIndex++] = x1;
108
- vertexBuffer[bufferIndex++] = y1;
109
- vertexBuffer[bufferIndex++] = u1;
110
- vertexBuffer[bufferIndex++] = v1;
111
- // Vertex 2: Top-right
112
- vertexBuffer[bufferIndex++] = x2;
113
- vertexBuffer[bufferIndex++] = y1;
114
- vertexBuffer[bufferIndex++] = u2;
115
- vertexBuffer[bufferIndex++] = v1;
116
- // Vertex 3: Bottom-left
117
- vertexBuffer[bufferIndex++] = x1;
118
- vertexBuffer[bufferIndex++] = y2;
119
- vertexBuffer[bufferIndex++] = u1;
120
- vertexBuffer[bufferIndex++] = v2;
121
- // Triangle 2: Top-right, bottom-right, bottom-left
122
- // Vertex 4: Top-right (duplicate)
123
- vertexBuffer[bufferIndex++] = x2;
124
- vertexBuffer[bufferIndex++] = y1;
125
- vertexBuffer[bufferIndex++] = u2;
126
- vertexBuffer[bufferIndex++] = v1;
127
- // Vertex 5: Bottom-right
128
- vertexBuffer[bufferIndex++] = x2;
129
- vertexBuffer[bufferIndex++] = y2;
130
- vertexBuffer[bufferIndex++] = u2;
131
- vertexBuffer[bufferIndex++] = v2;
132
- // Vertex 6: Bottom-left (duplicate)
133
- vertexBuffer[bufferIndex++] = x1;
134
- vertexBuffer[bufferIndex++] = y2;
135
- vertexBuffer[bufferIndex++] = u1;
136
- vertexBuffer[bufferIndex++] = v2;
137
- }
138
- return vertexBuffer;
139
- };
140
89
  /**
141
90
  * Create and submit WebGL render operations for SDF text
142
91
  * This is called from CoreTextNode during rendering to add SDF text to the render pipeline
143
92
  */
144
- const renderQuads = (renderer, layout, vertexBuffer, renderProps) => {
93
+ const renderQuads = (renderer, layout, renderProps) => {
145
94
  const fontFamily = renderProps.fontFamily;
146
95
  const color = renderProps.color;
147
96
  const worldAlpha = renderProps.worldAlpha;
148
97
  const globalTransform = renderProps.globalTransform;
98
+ const vertexBuffer = layout.vertexBuffer;
149
99
  const atlasTexture = SdfFontHandler.getAtlas(fontFamily);
150
100
  if (atlasTexture === null) {
151
101
  console.warn(`SDF atlas texture not found for font: ${fontFamily}`);
@@ -154,53 +104,66 @@ const renderQuads = (renderer, layout, vertexBuffer, renderProps) => {
154
104
  // We can safely assume this is a WebGL renderer else this wouldn't be called
155
105
  const glw = renderer.glw;
156
106
  const stride = 4 * Float32Array.BYTES_PER_ELEMENT;
157
- const webGlBuffer = glw.createBuffer();
158
- if (!webGlBuffer) {
159
- console.warn('Failed to create WebGL buffer for SDF text');
160
- return;
161
- }
162
- const webGlBuffers = new BufferCollection([
163
- {
164
- buffer: webGlBuffer,
165
- attributes: {
166
- a_position: {
167
- name: 'a_position',
168
- size: 2,
169
- type: glw.FLOAT,
170
- normalized: false,
171
- stride,
172
- offset: 0,
173
- },
174
- a_textureCoords: {
175
- name: 'a_textureCoords',
176
- size: 2,
177
- type: glw.FLOAT,
178
- normalized: false,
179
- stride,
180
- offset: 2 * Float32Array.BYTES_PER_ELEMENT,
107
+ /**
108
+ * Wraps a WebGLBuffer in a BufferCollection with the standard SDF vertex
109
+ * layout, creates and submits an SdfRenderOp. Called by both the cache-miss
110
+ * and cache-hit paths so attribute/op setup only exists in one place.
111
+ */
112
+ const buildAndSubmitRenderOp = (gpuBuffer) => {
113
+ const webGlBuffers = new BufferCollection([
114
+ {
115
+ buffer: gpuBuffer,
116
+ attributes: {
117
+ a_position: {
118
+ name: 'a_position',
119
+ size: 2,
120
+ type: glw.FLOAT,
121
+ normalized: false,
122
+ stride,
123
+ offset: 0,
124
+ },
125
+ a_textureCoords: {
126
+ name: 'a_textureCoords',
127
+ size: 2,
128
+ type: glw.FLOAT,
129
+ normalized: false,
130
+ stride,
131
+ offset: 2 * Float32Array.BYTES_PER_ELEMENT,
132
+ },
181
133
  },
182
134
  },
183
- },
184
- ]);
185
- const buffer = webGlBuffers.getBuffer('a_position');
186
- if (buffer !== undefined) {
187
- glw.arrayBufferData(buffer, vertexBuffer, glw.STATIC_DRAW);
135
+ ]);
136
+ const renderOp = new SdfRenderOp(renderer, sdfShader, {
137
+ transform: globalTransform,
138
+ color: mergeColorAlpha(color, worldAlpha),
139
+ size: layout.fontScale,
140
+ distanceRange: layout.distanceRange,
141
+ }, webGlBuffers, worldAlpha,
142
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
143
+ renderProps.clippingRect, layout.width, layout.height, false, renderProps.parentHasRenderTexture,
144
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
145
+ renderProps.framebufferDimensions);
146
+ renderOp.addTexture(atlasTexture.ctxTexture);
147
+ renderOp.numQuads = layout.glyphCount;
148
+ renderer.addRenderOp(renderOp);
149
+ };
150
+ // Reuse the cached WebGLBuffer if one was provided — avoids a createBuffer
151
+ // call every frame on nodes whose text has not changed.
152
+ const glBufferRefBox = renderProps.glBufferRef;
153
+ if (glBufferRefBox.current === null) {
154
+ // Cache miss: allocate a new buffer, upload vertex data, then cache it.
155
+ const newBuffer = glw.createBuffer();
156
+ if (newBuffer === null) {
157
+ console.warn('Failed to create WebGL buffer for SDF text');
158
+ return;
159
+ }
160
+ // Upload vertex data directly into the new buffer.
161
+ glw.arrayBufferData(newBuffer, vertexBuffer, glw.STATIC_DRAW);
162
+ // Write back into the ref box so the owning node can reuse it next frame.
163
+ glBufferRefBox.current = newBuffer;
188
164
  }
189
- const renderOp = new SdfRenderOp(renderer, sdfShader, // Ensure sdfShader is not null
190
- {
191
- transform: globalTransform,
192
- color: mergeColorAlpha(color, worldAlpha),
193
- size: layout.fontScale, // Use proper font scaling in shader
194
- distanceRange: layout.distanceRange,
195
- }, webGlBuffers, worldAlpha,
196
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
197
- renderProps.clippingRect, layout.width, layout.height, false, renderProps.parentHasRenderTexture,
198
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
199
- renderProps.framebufferDimensions);
200
- // Add atlas texture and set quad count
201
- renderOp.addTexture(atlasTexture.ctxTexture);
202
- renderOp.numQuads = layout.glyphs.length;
203
- renderer.addRenderOp(renderOp);
165
+ // Cache hit (or freshly allocated): build the render op and submit.
166
+ buildAndSubmitRenderOp(glBufferRefBox.current);
204
167
  };
205
168
  /**
206
169
  * Generate complete text layout with glyph positioning for caching
@@ -222,7 +185,23 @@ const generateTextLayout = (props, fontCache) => {
222
185
  const maxHeight = props.maxHeight;
223
186
  const [lines, remainingLines, hasRemainingText, bareLineHeight, lineHeightPx, effectiveWidth, effectiveHeight,] = mapTextLayout(SdfFontHandler.measureText, metrics, props.text, props.textAlign, fontFamily, lineHeight, props.overflowSuffix, props.wordBreak, letterSpacing, props.maxLines, maxWidth, maxHeight);
224
187
  const lineAmount = lines.length;
225
- const glyphs = [];
188
+ let bufferIndex = 0;
189
+ let glyphCount = 0;
190
+ // Count total glyphs (excluding spaces) for buffer allocation
191
+ for (let i = 0; i < lineAmount; i++) {
192
+ const textLine = lines[i][0];
193
+ for (const char of textLine) {
194
+ if (hasZeroWidthSpace(char) === true) {
195
+ continue;
196
+ }
197
+ const codepoint = char.codePointAt(0);
198
+ if (codepoint === undefined) {
199
+ continue;
200
+ }
201
+ glyphCount++;
202
+ }
203
+ }
204
+ const vertexBuffer = new Float32Array(glyphCount * VERTICES_PER_GLYPH * FLOATS_PER_VERTEX);
226
205
  let currentX = 0;
227
206
  let currentY = 0;
228
207
  for (let i = 0; i < lineAmount; i++) {
@@ -253,22 +232,46 @@ const generateTextLayout = (props, fontCache) => {
253
232
  }
254
233
  // Apply pair kerning before placing this glyph.
255
234
  currentX += kerning;
256
- // Calculate glyph position and atlas coordinates (in design units)
257
- const glyphLayout = {
258
- codepoint,
259
- glyphId: glyph.id,
260
- x: currentX + glyph.xoffset,
261
- y: currentY + glyph.yoffset,
262
- width: glyph.width,
263
- height: glyph.height,
264
- xOffset: glyph.xoffset,
265
- yOffset: glyph.yoffset,
266
- atlasX: glyph.x / atlasWidth,
267
- atlasY: glyph.y / atlasHeight,
268
- atlasWidth: glyph.width / atlasWidth,
269
- atlasHeight: glyph.height / atlasHeight,
270
- };
271
- glyphs.push(glyphLayout);
235
+ const x1 = currentX + glyph.xoffset;
236
+ const y1 = currentY + glyph.yoffset;
237
+ const x2 = x1 + glyph.width;
238
+ const y2 = y1 + glyph.height;
239
+ const u1 = glyph.x / atlasWidth;
240
+ const v1 = glyph.y / atlasHeight;
241
+ const u2 = u1 + glyph.width / atlasWidth;
242
+ const v2 = v1 + glyph.height / atlasHeight;
243
+ // Triangle 1: Top-left, top-right, bottom-left
244
+ // Vertex 1: Top-left
245
+ vertexBuffer[bufferIndex++] = x1;
246
+ vertexBuffer[bufferIndex++] = y1;
247
+ vertexBuffer[bufferIndex++] = u1;
248
+ vertexBuffer[bufferIndex++] = v1;
249
+ // Vertex 2: Top-right
250
+ vertexBuffer[bufferIndex++] = x2;
251
+ vertexBuffer[bufferIndex++] = y1;
252
+ vertexBuffer[bufferIndex++] = u2;
253
+ vertexBuffer[bufferIndex++] = v1;
254
+ // Vertex 3: Bottom-left
255
+ vertexBuffer[bufferIndex++] = x1;
256
+ vertexBuffer[bufferIndex++] = y2;
257
+ vertexBuffer[bufferIndex++] = u1;
258
+ vertexBuffer[bufferIndex++] = v2;
259
+ // Triangle 2: Top-right, bottom-right, bottom-left
260
+ // Vertex 4: Top-right (duplicate)
261
+ vertexBuffer[bufferIndex++] = x2;
262
+ vertexBuffer[bufferIndex++] = y1;
263
+ vertexBuffer[bufferIndex++] = u2;
264
+ vertexBuffer[bufferIndex++] = v1;
265
+ // Vertex 5: Bottom-right
266
+ vertexBuffer[bufferIndex++] = x2;
267
+ vertexBuffer[bufferIndex++] = y2;
268
+ vertexBuffer[bufferIndex++] = u2;
269
+ vertexBuffer[bufferIndex++] = v2;
270
+ // Vertex 6: Bottom-left (duplicate)
271
+ vertexBuffer[bufferIndex++] = x1;
272
+ vertexBuffer[bufferIndex++] = y2;
273
+ vertexBuffer[bufferIndex++] = u1;
274
+ vertexBuffer[bufferIndex++] = v2;
272
275
  // Advance position with letter spacing (in design units)
273
276
  currentX += glyph.xadvance + letterSpacing;
274
277
  prevGlyphId = glyph.id;
@@ -277,15 +280,21 @@ const generateTextLayout = (props, fontCache) => {
277
280
  }
278
281
  // Convert final dimensions to pixel space for the layout
279
282
  return {
280
- glyphs,
283
+ vertexBuffer,
284
+ glyphCount,
281
285
  distanceRange: fontScale * fontData.distanceField.distanceRange,
282
286
  width: effectiveWidth * fontScale,
283
287
  height: effectiveHeight,
284
288
  fontScale: fontScale,
285
289
  lineHeight: lineHeightPx,
286
290
  fontFamily,
291
+ remainingLines,
292
+ hasRemainingText,
287
293
  };
288
294
  };
295
+ const clearCache = () => {
296
+ layoutCache.clear();
297
+ };
289
298
  /**
290
299
  * SDF Text Renderer - implements TextRenderer interface
291
300
  */
@@ -293,9 +302,9 @@ const SdfTextRenderer = {
293
302
  type,
294
303
  font,
295
304
  renderText,
296
- addQuads,
297
305
  renderQuads,
298
306
  init,
307
+ clearCache,
299
308
  };
300
309
  export default SdfTextRenderer;
301
310
  //# sourceMappingURL=SdfTextRenderer.js.map