@lightningjs/renderer 3.0.0-beta23 → 3.0.0-beta24

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 (50) hide show
  1. package/dist/exports/index.d.ts +3 -1
  2. package/dist/exports/index.js +2 -0
  3. package/dist/exports/index.js.map +1 -1
  4. package/dist/src/core/CoreNode.d.ts +0 -1
  5. package/dist/src/core/CoreNode.js +40 -30
  6. package/dist/src/core/CoreNode.js.map +1 -1
  7. package/dist/src/core/lib/collectionUtils.d.ts +0 -1
  8. package/dist/src/core/lib/collectionUtils.js +0 -29
  9. package/dist/src/core/lib/collectionUtils.js.map +1 -1
  10. package/dist/src/core/renderers/canvas/CanvasRenderer.js +2 -2
  11. package/dist/src/core/renderers/canvas/CanvasRenderer.js.map +1 -1
  12. package/dist/src/core/renderers/canvas/CanvasShaderNode.js +3 -3
  13. package/dist/src/core/renderers/canvas/CanvasShaderNode.js.map +1 -1
  14. package/dist/src/core/renderers/webgl/WebGlRenderer.js +4 -4
  15. package/dist/src/core/renderers/webgl/WebGlRenderer.js.map +1 -1
  16. package/dist/src/core/renderers/webgl/WebGlShaderNode.js +3 -3
  17. package/dist/src/core/renderers/webgl/WebGlShaderNode.js.map +1 -1
  18. package/dist/src/core/renderers/webgl/WebGlShaderProgram.js +0 -3
  19. package/dist/src/core/renderers/webgl/WebGlShaderProgram.js.map +1 -1
  20. package/dist/src/core/renderers/webgl/internal/ShaderUtils.js +3 -2
  21. package/dist/src/core/renderers/webgl/internal/ShaderUtils.js.map +1 -1
  22. package/dist/src/core/shaders/webgl/RoundedWithBorder.js +10 -13
  23. package/dist/src/core/shaders/webgl/RoundedWithBorder.js.map +1 -1
  24. package/dist/src/core/shaders/webgl/RoundedWithBorderAndShadow.js +13 -17
  25. package/dist/src/core/shaders/webgl/RoundedWithBorderAndShadow.js.map +1 -1
  26. package/dist/src/core/text-rendering/SdfFontHandler.js +10 -20
  27. package/dist/src/core/text-rendering/SdfFontHandler.js.map +1 -1
  28. package/dist/src/core/text-rendering/SdfTextRenderer.js +10 -12
  29. package/dist/src/core/text-rendering/SdfTextRenderer.js.map +1 -1
  30. package/dist/src/core/textures/SubTexture.js +3 -3
  31. package/dist/src/core/textures/SubTexture.js.map +1 -1
  32. package/dist/src/core/textures/Texture.js +1 -1
  33. package/dist/src/core/textures/Texture.js.map +1 -1
  34. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  35. package/exports/index.ts +3 -1
  36. package/package.json +1 -1
  37. package/src/core/CoreNode.ts +44 -37
  38. package/src/core/lib/collectionUtils.ts +0 -36
  39. package/src/core/renderers/canvas/CanvasRenderer.ts +2 -2
  40. package/src/core/renderers/canvas/CanvasShaderNode.ts +3 -3
  41. package/src/core/renderers/webgl/WebGlRenderer.ts +4 -4
  42. package/src/core/renderers/webgl/WebGlShaderNode.ts +3 -3
  43. package/src/core/renderers/webgl/WebGlShaderProgram.ts +0 -4
  44. package/src/core/renderers/webgl/internal/ShaderUtils.ts +4 -2
  45. package/src/core/shaders/webgl/RoundedWithBorder.ts +10 -13
  46. package/src/core/shaders/webgl/RoundedWithBorderAndShadow.ts +13 -17
  47. package/src/core/text-rendering/SdfFontHandler.ts +10 -17
  48. package/src/core/text-rendering/SdfTextRenderer.ts +11 -16
  49. package/src/core/textures/SubTexture.ts +3 -3
  50. package/src/core/textures/Texture.ts +1 -1
@@ -221,9 +221,11 @@ export function createProgram(
221
221
  return program;
222
222
  }
223
223
 
224
- console.warn(glw.getProgramInfoLog(program));
224
+ const infoLog =
225
+ glw.getProgramInfoLog(program) || 'Unknown program link error';
226
+ console.warn(infoLog);
225
227
  glw.deleteProgram(program);
226
- return undefined;
228
+ throw new Error(`Unable to link shader program: ${infoLog}`);
227
229
  }
228
230
 
229
231
  export const DefaultVertexSource = `
@@ -69,20 +69,18 @@ export const RoundedWithBorder: WebGlShaderType<RoundedWithBorderProps> = {
69
69
  varying vec4 v_innerBorderRadius;
70
70
  varying vec4 v_outerBorderRadius;
71
71
  varying vec2 v_halfDimensions;
72
- varying float v_edgeWidth;
73
- varying float v_borderZero;
74
72
 
75
73
  void main() {
76
74
  vec2 vertexPos = a_position * u_pixelRatio;
77
75
  vec2 screenSpace = vec2(2.0 / u_resolution.x, -2.0 / u_resolution.y);
78
76
  vec2 edge = clamp(a_nodeCoords * 2.0 - vec2(1.0), -1.0, 1.0);
79
77
  vec2 edgeOffset = vec2(0.0);
78
+ float borderZero = 1.0 - step(0.001, dot(abs(u_borderWidth), vec4(1.0)));
80
79
 
81
- v_borderZero = u_borderWidth == vec4(0.0) ? 1.0 : 0.0;
82
80
  v_innerSize = vec2(0.0);
83
81
  v_outerSize = vec2(0.0);
84
82
 
85
- if(v_borderZero == 0.0) {
83
+ if(borderZero == 0.0) {
86
84
  vec4 adjustedBorderWidth = u_borderWidth - 1.0 + clamp(u_borderWidth, -1.0, 1.0);
87
85
 
88
86
  float borderTop = adjustedBorderWidth.x;
@@ -143,7 +141,6 @@ export const RoundedWithBorder: WebGlShaderType<RoundedWithBorderProps> = {
143
141
  v_textureCoords = a_textureCoords + (screenSpace + edgeOffset) / (u_dimensions);
144
142
 
145
143
  v_halfDimensions = u_dimensions * 0.5;
146
- v_edgeWidth = 1.0 / u_pixelRatio;
147
144
  }
148
145
  `,
149
146
  fragment: `
@@ -176,8 +173,6 @@ export const RoundedWithBorder: WebGlShaderType<RoundedWithBorderProps> = {
176
173
  varying vec4 v_innerBorderRadius;
177
174
  varying vec4 v_outerBorderRadius;
178
175
  varying vec2 v_halfDimensions;
179
- varying float v_edgeWidth;
180
- varying float v_borderZero;
181
176
 
182
177
  float roundedBox(vec2 p, vec2 s, vec4 r) {
183
178
  r.xy = (p.x > 0.0) ? r.yz : r.xw;
@@ -190,21 +185,23 @@ export const RoundedWithBorder: WebGlShaderType<RoundedWithBorderProps> = {
190
185
  vec4 color = texture2D(u_texture, v_textureCoords) * v_color;
191
186
  vec4 resultColor = vec4(0.0);
192
187
  vec2 boxUv = v_nodeCoords.xy * u_dimensions - v_halfDimensions;
188
+ float borderZero = 1.0 - step(0.001, dot(abs(u_borderWidth), vec4(1.0)));
189
+ float edgeWidth = 1.0 / u_pixelRatio;
193
190
 
194
- float nodeDist = roundedBox(boxUv, v_halfDimensions - v_edgeWidth, u_radius);
195
- float nodeAlpha = 1.0 - smoothstep(-0.5 * v_edgeWidth, 0.5 * v_edgeWidth, nodeDist);
191
+ float nodeDist = roundedBox(boxUv, v_halfDimensions - edgeWidth, u_radius);
192
+ float nodeAlpha = 1.0 - smoothstep(-0.5 * edgeWidth, 0.5 * edgeWidth, nodeDist);
196
193
  resultColor = mix(resultColor, color, nodeAlpha);
197
194
 
198
- if(v_borderZero == 1.0) {
195
+ if(borderZero == 1.0) {
199
196
  gl_FragColor = resultColor * u_alpha;
200
197
  return;
201
198
  }
202
199
 
203
- float outerDist = roundedBox(boxUv + v_outerBorderUv, v_outerSize - v_edgeWidth, v_outerBorderRadius);
204
- float innerDist = roundedBox(boxUv + v_innerBorderUv, v_innerSize - v_edgeWidth, v_innerBorderRadius);
200
+ float outerDist = roundedBox(boxUv + v_outerBorderUv, v_outerSize - edgeWidth, v_outerBorderRadius);
201
+ float innerDist = roundedBox(boxUv + v_innerBorderUv, v_innerSize - edgeWidth, v_innerBorderRadius);
205
202
 
206
203
  float borderDist = max(-innerDist, outerDist);
207
- float borderAlpha = (1.0 - smoothstep(-0.5 * v_edgeWidth, 0.5 * v_edgeWidth, borderDist)) * u_borderColor.a;
204
+ float borderAlpha = (1.0 - smoothstep(-0.5 * edgeWidth, 0.5 * edgeWidth, borderDist)) * u_borderColor.a;
208
205
 
209
206
  resultColor = mix(resultColor, vec4(u_borderColor.rgb, 1.0), borderAlpha);
210
207
  gl_FragColor = resultColor * u_alpha;
@@ -76,22 +76,19 @@ export const RoundedWithBorderAndShadow: WebGlShaderType<RoundedWithBorderAndSha
76
76
  varying vec4 v_innerBorderRadius;
77
77
  varying vec4 v_outerBorderRadius;
78
78
  varying vec2 v_halfDimensions;
79
- varying float v_edgeWidth;
80
- varying float v_borderZero;
81
79
 
82
80
  void main() {
83
81
  vec2 screenSpace = vec2(2.0 / u_resolution.x, -2.0 / u_resolution.y);
84
82
  vec2 edge = clamp(a_nodeCoords * 2.0 - vec2(1.0), -1.0, 1.0);
83
+ float borderZero = 1.0 - step(0.001, dot(abs(u_borderWidth), vec4(1.0)));
85
84
 
86
85
  vec2 edgeOffset = edge * ((u_shadow.w * 2.0)+ u_shadow.z) + u_shadow.xy;
87
86
  vec2 vertexPos = (a_position + edge + edgeOffset) * u_pixelRatio;
88
87
 
89
- v_borderZero = u_borderWidth == vec4(0.0) ? 1.0 : 0.0;
90
-
91
88
  v_innerSize = vec2(0.0);
92
89
  v_outerSize = vec2(0.0);
93
90
 
94
- if(v_borderZero == 0.0) {
91
+ if(borderZero == 0.0) {
95
92
  vec4 adjustedBorderWidth = u_borderWidth - 1.0 + clamp(u_borderWidth, -1.0, 1.0);
96
93
 
97
94
  float borderTop = adjustedBorderWidth.x;
@@ -148,7 +145,6 @@ export const RoundedWithBorderAndShadow: WebGlShaderType<RoundedWithBorderAndSha
148
145
  gl_Position = vec4(vertexPos.x * screenSpace.x - 1.0, -sign(screenSpace.y) * (vertexPos.y * -abs(screenSpace.y)) + 1.0, 0.0, 1.0);
149
146
 
150
147
  v_halfDimensions = u_dimensions * 0.5;
151
- v_edgeWidth = 1.0 / u_pixelRatio;
152
148
  v_color = a_color;
153
149
  v_nodeCoords = a_nodeCoords + (screenSpace + edgeOffset) / (u_dimensions);
154
150
  v_textureCoords = a_textureCoords + (screenSpace + edgeOffset) / (u_dimensions);
@@ -185,8 +181,6 @@ export const RoundedWithBorderAndShadow: WebGlShaderType<RoundedWithBorderAndSha
185
181
  varying vec4 v_innerBorderRadius;
186
182
  varying vec4 v_outerBorderRadius;
187
183
  varying vec2 v_halfDimensions;
188
- varying float v_edgeWidth;
189
- varying float v_borderZero;
190
184
 
191
185
  float roundedBox(vec2 p, vec2 s, vec4 r) {
192
186
  r.xy = (p.x > 0.0) ? r.yz : r.xw;
@@ -207,28 +201,30 @@ export const RoundedWithBorderAndShadow: WebGlShaderType<RoundedWithBorderAndSha
207
201
  vec4 color = texture2D(u_texture, v_textureCoords) * v_color;
208
202
  vec4 resultColor = vec4(0.0);
209
203
  vec2 boxUv = v_nodeCoords.xy * u_dimensions - v_halfDimensions;
210
- float nodeDist = roundedBox(boxUv, v_halfDimensions - v_edgeWidth, u_radius);
211
- float nodeAlpha = 1.0 - smoothstep(-0.5 * v_edgeWidth, 0.5 * v_edgeWidth, nodeDist);
204
+ float borderZero = 1.0 - step(0.001, dot(abs(u_borderWidth), vec4(1.0)));
205
+ float edgeWidth = 1.0 / u_pixelRatio;
206
+ float nodeDist = roundedBox(boxUv, v_halfDimensions - edgeWidth, u_radius);
207
+ float nodeAlpha = 1.0 - smoothstep(-0.5 * edgeWidth, 0.5 * edgeWidth, nodeDist);
212
208
  float shadowAlpha;
213
209
 
214
- if(v_borderZero == 1.0) {
215
- shadowAlpha = shadowBox(boxUv - u_shadow.xy, v_halfDimensions + u_shadow.w - v_edgeWidth, u_radius + u_shadow.z);
210
+ if(borderZero == 1.0) {
211
+ shadowAlpha = shadowBox(boxUv - u_shadow.xy, v_halfDimensions + u_shadow.w - edgeWidth, u_radius + u_shadow.z);
216
212
  resultColor = mix(resultColor, u_shadowColor, shadowAlpha);
217
213
  gl_FragColor = mix(resultColor, color, nodeAlpha) * u_alpha;
218
214
  return;
219
215
  }
220
216
 
221
217
  if(v_outerSize.x > v_halfDimensions.x || v_outerSize.y > v_halfDimensions.y) {
222
- shadowAlpha = shadowBox(boxUv + v_outerBorderUv - u_shadow.xy, v_outerSize + u_shadow.w - v_edgeWidth, v_outerBorderRadius + u_shadow.z);
218
+ shadowAlpha = shadowBox(boxUv + v_outerBorderUv - u_shadow.xy, v_outerSize + u_shadow.w - edgeWidth, v_outerBorderRadius + u_shadow.z);
223
219
  }
224
220
  else {
225
- shadowAlpha = shadowBox(boxUv - u_shadow.xy, v_halfDimensions + u_shadow.w - v_edgeWidth, u_radius + u_shadow.z);
221
+ shadowAlpha = shadowBox(boxUv - u_shadow.xy, v_halfDimensions + u_shadow.w - edgeWidth, u_radius + u_shadow.z);
226
222
  }
227
223
 
228
- float outerDist = roundedBox(boxUv + v_outerBorderUv, v_outerSize - v_edgeWidth, v_outerBorderRadius);
229
- float innerDist = roundedBox(boxUv + v_innerBorderUv, v_innerSize - v_edgeWidth, v_innerBorderRadius);
224
+ float outerDist = roundedBox(boxUv + v_outerBorderUv, v_outerSize - edgeWidth, v_outerBorderRadius);
225
+ float innerDist = roundedBox(boxUv + v_innerBorderUv, v_innerSize - edgeWidth, v_innerBorderRadius);
230
226
  float borderDist = max(-innerDist, outerDist);
231
- float borderAlpha = (1.0 - smoothstep(-0.5 * v_edgeWidth, 0.5 * v_edgeWidth, borderDist)) * u_borderColor.a;
227
+ float borderAlpha = (1.0 - smoothstep(-0.5 * edgeWidth, 0.5 * edgeWidth, borderDist)) * u_borderColor.a;
232
228
  resultColor = mix(resultColor, u_shadowColor, shadowAlpha);
233
229
  resultColor = mix(resultColor, color, nodeAlpha);
234
230
  resultColor = mix(resultColor, vec4(u_borderColor.rgb, 1.0), borderAlpha);
@@ -550,22 +550,15 @@ export const measureText = (
550
550
  fontFamily: string,
551
551
  letterSpacing: number,
552
552
  ): number => {
553
- if (text.length === 1) {
554
- const char = text.charAt(0);
555
- const codepoint = text.codePointAt(0);
556
- if (codepoint === undefined) return 0;
557
- if (hasZeroWidthSpace(char) === true) return 0;
553
+ if (text.length === 0) return 0;
558
554
 
559
- const glyph = getGlyph(fontFamily, codepoint);
560
- if (glyph === null) return 0;
561
- return glyph.xadvance + letterSpacing;
562
- }
563
555
  let width = 0;
564
- let prevCodepoint = 0;
565
- for (let i = 0; i < text.length; i++) {
566
- const char = text.charAt(i);
567
- const codepoint = text.codePointAt(i);
568
- if (codepoint === undefined) continue;
556
+ let prevGlyphId = 0;
557
+ for (const char of text) {
558
+ const codepoint = char.codePointAt(0);
559
+ if (codepoint === undefined) {
560
+ continue;
561
+ }
569
562
 
570
563
  // Skip zero-width spaces in width calculations
571
564
  if (hasZeroWidthSpace(char)) {
@@ -578,13 +571,13 @@ export const measureText = (
578
571
  let advance = glyph.xadvance;
579
572
 
580
573
  // Add kerning if there's a previous character
581
- if (prevCodepoint !== 0) {
582
- const kerning = getKerning(fontFamily, prevCodepoint, codepoint);
574
+ if (prevGlyphId !== 0) {
575
+ const kerning = getKerning(fontFamily, prevGlyphId, glyph.id);
583
576
  advance += kerning;
584
577
  }
585
578
 
586
579
  width += advance + letterSpacing;
587
- prevCodepoint = codepoint;
580
+ prevGlyphId = glyph.id;
588
581
  }
589
582
 
590
583
  return width;
@@ -277,7 +277,6 @@ const generateTextLayout = (
277
277
  const fontFamily = props.fontFamily;
278
278
  const lineHeight = props.lineHeight;
279
279
  const metrics = SdfFontHandler.getFontMetrics(fontFamily, fontSize);
280
- const verticalAlign = props.verticalAlign;
281
280
 
282
281
  const fontData = fontCache.data;
283
282
  const commonFontData = fontData.common;
@@ -323,14 +322,12 @@ const generateTextLayout = (
323
322
  for (let i = 0; i < lineAmount; i++) {
324
323
  const line = lines[i] as TextLineStruct;
325
324
  const textLine = line[0];
326
- const textLineLength = textLine.length;
327
- let prevCodepoint = 0;
325
+ let prevGlyphId = 0;
328
326
  currentX = line[3];
329
327
  //convert Y coord to vertex value
330
328
  currentY = line[4] / fontScale;
331
329
 
332
- for (let j = 0; j < textLineLength; j++) {
333
- const char = textLine.charAt(j);
330
+ for (const char of textLine) {
334
331
  if (hasZeroWidthSpace(char) === true) {
335
332
  continue;
336
333
  }
@@ -343,19 +340,17 @@ const generateTextLayout = (
343
340
  if (glyph === null) {
344
341
  continue;
345
342
  }
346
- // Calculate advance with kerning (in design units)
347
- let advance = glyph.xadvance;
343
+ // Kerning offsets the current glyph relative to the previous glyph.
344
+ let kerning = 0;
348
345
 
349
346
  // Add kerning if there's a previous character
350
- if (prevCodepoint !== 0) {
351
- const kerning = SdfFontHandler.getKerning(
352
- fontFamily,
353
- prevCodepoint,
354
- codepoint,
355
- );
356
- advance += kerning;
347
+ if (prevGlyphId !== 0) {
348
+ kerning = SdfFontHandler.getKerning(fontFamily, prevGlyphId, glyph.id);
357
349
  }
358
350
 
351
+ // Apply pair kerning before placing this glyph.
352
+ currentX += kerning;
353
+
359
354
  // Calculate glyph position and atlas coordinates (in design units)
360
355
  const glyphLayout: GlyphLayout = {
361
356
  codepoint,
@@ -375,8 +370,8 @@ const generateTextLayout = (
375
370
  glyphs.push(glyphLayout);
376
371
 
377
372
  // Advance position with letter spacing (in design units)
378
- currentX += advance + letterSpacing;
379
- prevCodepoint = codepoint;
373
+ currentX += glyph.xadvance + letterSpacing;
374
+ prevGlyphId = glyph.id;
380
375
  }
381
376
  currentY += lineHeightPx;
382
377
  }
@@ -91,14 +91,14 @@ export class SubTexture extends Texture {
91
91
  super(txManager);
92
92
  this.props = props;
93
93
 
94
- assertTruthy(this.props.texture, 'SubTexture requires a parent texture');
94
+ assertTruthy(props.texture, 'SubTexture requires a parent texture');
95
95
  assertTruthy(
96
- this.props.texture instanceof ImageTexture,
96
+ props.texture instanceof ImageTexture,
97
97
  'SubTexture requires an ImageTexture parent',
98
98
  );
99
99
 
100
100
  // Resolve parent texture from cache or fallback to provided texture
101
- this.parentTexture = txManager.resolveParentTexture(this.props.texture);
101
+ this.parentTexture = txManager.resolveParentTexture(props.texture);
102
102
 
103
103
  if (this.renderableOwners.length > 0) {
104
104
  this.parentTexture.setRenderableOwner(this.subtextureId, true);
@@ -202,7 +202,7 @@ export abstract class Texture extends EventEmitter {
202
202
 
203
203
  constructor(protected txManager: CoreTextureManager) {
204
204
  super();
205
- this.maxRetryCount = this.txManager.maxRetryCount;
205
+ this.maxRetryCount = txManager.maxRetryCount;
206
206
  }
207
207
 
208
208
  get dimensions(): Dimensions | null {