@lightningjs/renderer 0.6.0 → 0.7.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 (204) hide show
  1. package/README.md +1 -1
  2. package/dist/src/common/CommonTypes.d.ts +8 -0
  3. package/dist/src/core/CoreNode.d.ts +63 -15
  4. package/dist/src/core/CoreNode.js +266 -117
  5. package/dist/src/core/CoreNode.js.map +1 -1
  6. package/dist/src/core/CoreTextNode.d.ts +11 -0
  7. package/dist/src/core/CoreTextNode.js +58 -0
  8. package/dist/src/core/CoreTextNode.js.map +1 -1
  9. package/dist/src/core/CoreTextureManager.d.ts +3 -1
  10. package/dist/src/core/CoreTextureManager.js +4 -1
  11. package/dist/src/core/CoreTextureManager.js.map +1 -1
  12. package/dist/src/core/Stage.d.ts +12 -2
  13. package/dist/src/core/Stage.js +36 -24
  14. package/dist/src/core/Stage.js.map +1 -1
  15. package/dist/src/core/animations/CoreAnimation.js +11 -2
  16. package/dist/src/core/animations/CoreAnimation.js.map +1 -1
  17. package/dist/src/core/lib/ContextSpy.d.ts +12 -0
  18. package/dist/src/core/lib/ContextSpy.js +38 -0
  19. package/dist/src/core/lib/ContextSpy.js.map +1 -0
  20. package/dist/src/core/lib/ImageWorker.d.ts +16 -0
  21. package/dist/src/core/lib/ImageWorker.js +111 -0
  22. package/dist/src/core/lib/ImageWorker.js.map +1 -0
  23. package/dist/src/core/lib/WebGlContext.d.ts +414 -0
  24. package/dist/src/core/lib/WebGlContext.js +640 -0
  25. package/dist/src/core/lib/WebGlContext.js.map +1 -0
  26. package/dist/src/core/lib/WebGlContextWrapper.d.ts +500 -0
  27. package/dist/src/core/lib/WebGlContextWrapper.js +784 -0
  28. package/dist/src/core/lib/WebGlContextWrapper.js.map +1 -0
  29. package/dist/src/core/platform.js +4 -0
  30. package/dist/src/core/platform.js.map +1 -1
  31. package/dist/src/core/renderers/webgl/WebGlCoreCtxSubTexture.d.ts +2 -1
  32. package/dist/src/core/renderers/webgl/WebGlCoreCtxSubTexture.js +2 -2
  33. package/dist/src/core/renderers/webgl/WebGlCoreCtxSubTexture.js.map +1 -1
  34. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.d.ts +3 -2
  35. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js +23 -21
  36. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js.map +1 -1
  37. package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.d.ts +3 -2
  38. package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.js +9 -13
  39. package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.js.map +1 -1
  40. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.d.ts +4 -1
  41. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js +33 -31
  42. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js.map +1 -1
  43. package/dist/src/core/renderers/webgl/WebGlCoreShader.d.ts +2 -1
  44. package/dist/src/core/renderers/webgl/WebGlCoreShader.js +24 -24
  45. package/dist/src/core/renderers/webgl/WebGlCoreShader.js.map +1 -1
  46. package/dist/src/core/renderers/webgl/internal/RendererUtils.d.ts +8 -5
  47. package/dist/src/core/renderers/webgl/internal/RendererUtils.js +11 -13
  48. package/dist/src/core/renderers/webgl/internal/RendererUtils.js.map +1 -1
  49. package/dist/src/core/renderers/webgl/internal/ShaderUtils.d.ts +3 -2
  50. package/dist/src/core/renderers/webgl/internal/ShaderUtils.js +15 -15
  51. package/dist/src/core/renderers/webgl/internal/ShaderUtils.js.map +1 -1
  52. package/dist/src/core/renderers/webgl/shaders/DefaultShader.js +3 -6
  53. package/dist/src/core/renderers/webgl/shaders/DefaultShader.js.map +1 -1
  54. package/dist/src/core/renderers/webgl/shaders/DefaultShaderBatched.js +3 -3
  55. package/dist/src/core/renderers/webgl/shaders/DefaultShaderBatched.js.map +1 -1
  56. package/dist/src/core/renderers/webgl/shaders/DynamicShader.d.ts +1 -0
  57. package/dist/src/core/renderers/webgl/shaders/DynamicShader.js +32 -12
  58. package/dist/src/core/renderers/webgl/shaders/DynamicShader.js.map +1 -1
  59. package/dist/src/core/renderers/webgl/shaders/RoundedRectangle.js +3 -3
  60. package/dist/src/core/renderers/webgl/shaders/RoundedRectangle.js.map +1 -1
  61. package/dist/src/core/renderers/webgl/shaders/SdfShader.js +3 -3
  62. package/dist/src/core/renderers/webgl/shaders/SdfShader.js.map +1 -1
  63. package/dist/src/core/renderers/webgl/shaders/effects/BorderEffect.js +1 -1
  64. package/dist/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.d.ts +14 -1
  65. package/dist/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.js +15 -5
  66. package/dist/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.js.map +1 -1
  67. package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.js +7 -8
  68. package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.js.map +1 -1
  69. package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.d.ts +2 -1
  70. package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.js +4 -2
  71. package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.js.map +1 -1
  72. package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.js +40 -13
  73. package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.js.map +1 -1
  74. package/dist/src/core/text-rendering/renderers/LightningTextTextureRenderer.d.ts +1 -1
  75. package/dist/src/core/text-rendering/renderers/LightningTextTextureRenderer.js +6 -6
  76. package/dist/src/core/text-rendering/renderers/LightningTextTextureRenderer.js.map +1 -1
  77. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.d.ts +3 -2
  78. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js +82 -50
  79. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js.map +1 -1
  80. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/findNearestMultiple.d.ts +8 -0
  81. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/findNearestMultiple.js +29 -0
  82. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/findNearestMultiple.js.map +1 -0
  83. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.d.ts +4 -3
  84. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.js +15 -11
  85. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.js.map +1 -1
  86. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.d.ts +3 -2
  87. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.js +30 -26
  88. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.js.map +1 -1
  89. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/SdfBufferHelper.d.ts +19 -0
  90. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/SdfBufferHelper.js +84 -0
  91. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/SdfBufferHelper.js.map +1 -0
  92. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutLine.d.ts +8 -0
  93. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutLine.js +40 -0
  94. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutLine.js.map +1 -0
  95. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutText2.d.ts +2 -0
  96. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutText2.js +41 -0
  97. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutText2.js.map +1 -0
  98. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/utils.d.ts +1 -0
  99. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/utils.js +4 -0
  100. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/utils.js.map +1 -0
  101. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2.d.ts +1 -0
  102. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2.js +2 -0
  103. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2.js.map +1 -0
  104. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/roundUpToMultiple.d.ts +9 -0
  105. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/roundUpToMultiple.js +32 -0
  106. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/roundUpToMultiple.js.map +1 -0
  107. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.d.ts +26 -0
  108. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.js +70 -0
  109. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.js.map +1 -0
  110. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.d.ts +16 -0
  111. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.js +39 -0
  112. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.js.map +1 -0
  113. package/dist/src/core/text-rendering/renderers/TextRenderer.d.ts +50 -0
  114. package/dist/src/core/text-rendering/renderers/TextRenderer.js +19 -0
  115. package/dist/src/core/text-rendering/renderers/TextRenderer.js.map +1 -1
  116. package/dist/src/core/textures/ImageTexture.js +14 -9
  117. package/dist/src/core/textures/ImageTexture.js.map +1 -1
  118. package/dist/src/core/utils.d.ts +1 -6
  119. package/dist/src/core/utils.js +3 -2
  120. package/dist/src/core/utils.js.map +1 -1
  121. package/dist/src/main-api/ICoreDriver.d.ts +2 -1
  122. package/dist/src/main-api/RendererMain.d.ts +25 -0
  123. package/dist/src/main-api/RendererMain.js +14 -5
  124. package/dist/src/main-api/RendererMain.js.map +1 -1
  125. package/dist/src/render-drivers/main/MainCoreDriver.d.ts +2 -1
  126. package/dist/src/render-drivers/main/MainCoreDriver.js +6 -4
  127. package/dist/src/render-drivers/main/MainCoreDriver.js.map +1 -1
  128. package/dist/src/render-drivers/main/MainOnlyTextNode.d.ts +10 -0
  129. package/dist/src/render-drivers/main/MainOnlyTextNode.js +45 -0
  130. package/dist/src/render-drivers/main/MainOnlyTextNode.js.map +1 -1
  131. package/dist/src/render-drivers/threadx/TextNodeStruct.d.ts +10 -0
  132. package/dist/src/render-drivers/threadx/TextNodeStruct.js +45 -0
  133. package/dist/src/render-drivers/threadx/TextNodeStruct.js.map +1 -1
  134. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.d.ts +2 -1
  135. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js +8 -1
  136. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js.map +1 -1
  137. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.d.ts +5 -0
  138. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.js +5 -0
  139. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.js.map +1 -1
  140. package/dist/src/render-drivers/threadx/ThreadXRendererMessage.d.ts +4 -1
  141. package/dist/src/render-drivers/threadx/ThreadXRendererMessage.js.map +1 -1
  142. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.d.ts +5 -0
  143. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js +10 -0
  144. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js.map +1 -1
  145. package/dist/src/render-drivers/threadx/worker/renderer.js +5 -3
  146. package/dist/src/render-drivers/threadx/worker/renderer.js.map +1 -1
  147. package/dist/src/utils.d.ts +2 -1
  148. package/dist/src/utils.js +22 -3
  149. package/dist/src/utils.js.map +1 -1
  150. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  151. package/package.json +3 -2
  152. package/src/common/CommonTypes.ts +9 -0
  153. package/src/core/CoreNode.ts +325 -148
  154. package/src/core/CoreTextNode.ts +72 -0
  155. package/src/core/CoreTextureManager.ts +4 -2
  156. package/src/core/Stage.ts +60 -34
  157. package/src/core/animations/CoreAnimation.ts +11 -2
  158. package/src/core/lib/ContextSpy.ts +41 -0
  159. package/src/core/lib/ImageWorker.ts +124 -0
  160. package/src/core/lib/WebGlContextWrapper.ts +965 -0
  161. package/src/core/platform.ts +5 -0
  162. package/src/core/renderers/webgl/WebGlCoreCtxSubTexture.ts +3 -2
  163. package/src/core/renderers/webgl/WebGlCoreCtxTexture.ts +29 -28
  164. package/src/core/renderers/webgl/WebGlCoreRenderOp.ts +10 -14
  165. package/src/core/renderers/webgl/WebGlCoreRenderer.ts +34 -63
  166. package/src/core/renderers/webgl/WebGlCoreShader.ts +34 -25
  167. package/src/core/renderers/webgl/internal/RendererUtils.ts +13 -16
  168. package/src/core/renderers/webgl/internal/ShaderUtils.ts +16 -15
  169. package/src/core/renderers/webgl/shaders/DefaultShader.ts +3 -7
  170. package/src/core/renderers/webgl/shaders/DefaultShaderBatched.ts +3 -3
  171. package/src/core/renderers/webgl/shaders/DynamicShader.ts +42 -14
  172. package/src/core/renderers/webgl/shaders/RoundedRectangle.ts +3 -3
  173. package/src/core/renderers/webgl/shaders/SdfShader.ts +3 -3
  174. package/src/core/renderers/webgl/shaders/effects/BorderEffect.ts +1 -1
  175. package/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.ts +35 -5
  176. package/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.ts +7 -8
  177. package/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.test.ts +9 -3
  178. package/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.ts +4 -2
  179. package/src/core/text-rendering/renderers/CanvasTextRenderer.ts +44 -15
  180. package/src/core/text-rendering/renderers/LightningTextTextureRenderer.ts +7 -7
  181. package/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.ts +115 -63
  182. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.ts +26 -18
  183. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.ts +40 -28
  184. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/measureText.test.ts +6 -1
  185. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.test.ts +205 -0
  186. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/{makeRenderWindow.ts → setRenderWindow.ts} +50 -21
  187. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.ts +40 -0
  188. package/src/core/text-rendering/renderers/TextRenderer.ts +73 -0
  189. package/src/core/textures/ImageTexture.ts +17 -9
  190. package/src/core/utils.ts +87 -85
  191. package/src/env.d.ts +7 -0
  192. package/src/main-api/ICoreDriver.ts +2 -1
  193. package/src/main-api/RendererMain.ts +43 -5
  194. package/src/render-drivers/main/MainCoreDriver.ts +8 -5
  195. package/src/render-drivers/main/MainOnlyTextNode.ts +55 -1
  196. package/src/render-drivers/threadx/TextNodeStruct.ts +45 -0
  197. package/src/render-drivers/threadx/ThreadXCoreDriver.ts +10 -2
  198. package/src/render-drivers/threadx/ThreadXMainTextNode.ts +10 -0
  199. package/src/render-drivers/threadx/ThreadXRendererMessage.ts +5 -1
  200. package/src/render-drivers/threadx/worker/ThreadXRendererTextNode.ts +15 -0
  201. package/src/render-drivers/threadx/worker/renderer.ts +6 -4
  202. package/src/utils.ts +25 -4
  203. package/src/core/scene/Scene.ts +0 -120
  204. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.test.ts +0 -136
@@ -17,6 +17,8 @@
17
17
  * limitations under the License.
18
18
  */
19
19
 
20
+ import type { WebGlContextWrapper } from '../../../lib/WebGlContextWrapper.js';
21
+
20
22
  export interface CoreWebGlParameters {
21
23
  MAX_RENDERBUFFER_SIZE: number;
22
24
  MAX_TEXTURE_SIZE: number;
@@ -32,10 +34,10 @@ export interface CoreWebGlParameters {
32
34
 
33
35
  /**
34
36
  * Get device specific webgl parameters
35
- * @param gl
37
+ * @param glw
36
38
  */
37
39
  export function getWebGlParameters(
38
- gl: WebGLRenderingContext | WebGL2RenderingContext,
40
+ glw: WebGlContextWrapper,
39
41
  ): CoreWebGlParameters {
40
42
  const params: CoreWebGlParameters = {
41
43
  MAX_RENDERBUFFER_SIZE: 0,
@@ -55,7 +57,7 @@ export function getWebGlParameters(
55
57
  const keys = Object.keys(params) as Array<keyof CoreWebGlParameters>;
56
58
  keys.forEach((key) => {
57
59
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
58
- params[key] = gl.getParameter(gl[key]);
60
+ params[key] = glw.getParameter(glw[key]);
59
61
  });
60
62
 
61
63
  return params;
@@ -77,10 +79,10 @@ export interface CoreWebGlExtensions {
77
79
 
78
80
  /**
79
81
  * Get device webgl extensions
80
- * @param gl
82
+ * @param glw
81
83
  */
82
84
  export function getWebGlExtensions(
83
- gl: WebGLRenderingContext,
85
+ glw: WebGlContextWrapper,
84
86
  ): CoreWebGlExtensions {
85
87
  const extensions: CoreWebGlExtensions = {
86
88
  ANGLE_instanced_arrays: null,
@@ -98,7 +100,7 @@ export function getWebGlExtensions(
98
100
  const keys = Object.keys(extensions) as Array<keyof CoreWebGlExtensions>;
99
101
  keys.forEach((key) => {
100
102
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
101
- extensions[key] = gl.getExtension(key);
103
+ extensions[key] = glw.getExtension(key);
102
104
  });
103
105
 
104
106
  return extensions;
@@ -107,15 +109,11 @@ export function getWebGlExtensions(
107
109
  /**
108
110
  * Allocate big memory chunk that we
109
111
  * can re-use to draw quads
112
+ *
113
+ * @param glw
110
114
  * @param size
111
115
  */
112
- export function createIndexBuffer(
113
- gl: WebGLRenderingContext | WebGL2RenderingContext,
114
- size: number,
115
- ) {
116
- if (!gl) {
117
- throw new Error('No WebGL context');
118
- }
116
+ export function createIndexBuffer(glw: WebGlContextWrapper, size: number) {
119
117
  const maxQuads = ~~(size / 80);
120
118
  const indices = new Uint16Array(maxQuads * 6);
121
119
 
@@ -128,7 +126,6 @@ export function createIndexBuffer(
128
126
  indices[i + 5] = j + 3;
129
127
  }
130
128
 
131
- const buffer = gl.createBuffer();
132
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);
133
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
129
+ const buffer = glw.createBuffer();
130
+ glw.elementArrayBufferData(buffer, indices, glw.STATIC_DRAW);
134
131
  }
@@ -17,6 +17,7 @@
17
17
  * limitations under the License.
18
18
  */
19
19
 
20
+ import type { WebGlContextWrapper } from '../../../lib/WebGlContextWrapper.js';
20
21
  import type { WebGlCoreRenderer } from '../WebGlCoreRenderer.js';
21
22
 
22
23
  //#region Types
@@ -93,43 +94,43 @@ export interface ShaderProgramSources {
93
94
  //#endregion Types
94
95
 
95
96
  export function createShader(
96
- gl: WebGLRenderingContext,
97
+ glw: WebGlContextWrapper,
97
98
  type: number,
98
99
  source: string,
99
100
  ) {
100
- const shader = gl.createShader(type);
101
+ const shader = glw.createShader(type);
101
102
  if (!shader) {
102
103
  throw new Error();
103
104
  }
104
- gl.shaderSource(shader, source);
105
- gl.compileShader(shader);
106
- const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
105
+ glw.shaderSource(shader, source);
106
+ glw.compileShader(shader);
107
+ const success = glw.getShaderParameter(shader, glw.COMPILE_STATUS);
107
108
  if (success) {
108
109
  return shader;
109
110
  }
110
111
 
111
- console.log(gl.getShaderInfoLog(shader));
112
- gl.deleteShader(shader);
112
+ console.log(glw.getShaderInfoLog(shader));
113
+ glw.deleteShader(shader);
113
114
  }
114
115
 
115
116
  export function createProgram(
116
- gl: WebGLRenderingContext,
117
+ glw: WebGlContextWrapper,
117
118
  vertexShader: WebGLShader,
118
119
  fragmentShader: WebGLShader,
119
120
  ) {
120
- const program = gl.createProgram();
121
+ const program = glw.createProgram();
121
122
  if (!program) {
122
123
  throw new Error();
123
124
  }
124
- gl.attachShader(program, vertexShader);
125
- gl.attachShader(program, fragmentShader);
126
- gl.linkProgram(program);
127
- const success = gl.getProgramParameter(program, gl.LINK_STATUS);
125
+ glw.attachShader(program, vertexShader);
126
+ glw.attachShader(program, fragmentShader);
127
+ glw.linkProgram(program);
128
+ const success = glw.getProgramParameter(program, glw.LINK_STATUS);
128
129
  if (success) {
129
130
  return program;
130
131
  }
131
132
 
132
- console.log(gl.getProgramInfoLog(program));
133
- gl.deleteProgram(program);
133
+ console.log(glw.getProgramInfoLog(program));
134
+ glw.deleteProgram(program);
134
135
  return undefined;
135
136
  }
@@ -36,13 +36,9 @@ export class DefaultShader extends WebGlCoreShader {
36
36
  }
37
37
 
38
38
  override bindTextures(textures: WebGlCoreCtxTexture[]) {
39
- const { gl } = this;
40
- if (gl.getParameter(gl.TEXTURE_BINDING_2D) === textures[0]!.ctxTexture) {
41
- return;
42
- }
43
-
44
- gl.activeTexture(gl.TEXTURE0);
45
- gl.bindTexture(gl.TEXTURE_2D, textures[0]!.ctxTexture);
39
+ const { glw } = this;
40
+ glw.activeTexture(0);
41
+ glw.bindTexture(textures[0]!.ctxTexture);
46
42
  }
47
43
 
48
44
  static override shaderSources: ShaderProgramSources = {
@@ -44,7 +44,7 @@ export class DefaultShaderBatched extends WebGlCoreShader {
44
44
  }
45
45
 
46
46
  override bindTextures(texture: WebGlCoreCtxTexture[]) {
47
- const { renderer, gl } = this;
47
+ const { renderer, glw } = this;
48
48
  if (
49
49
  texture.length > renderer.system.parameters.MAX_VERTEX_TEXTURE_IMAGE_UNITS
50
50
  ) {
@@ -53,8 +53,8 @@ export class DefaultShaderBatched extends WebGlCoreShader {
53
53
  );
54
54
  }
55
55
  texture.forEach((t, i) => {
56
- gl.activeTexture(gl.TEXTURE0 + i);
57
- gl.bindTexture(gl.TEXTURE_2D, t.ctxTexture);
56
+ glw.activeTexture(i);
57
+ glw.bindTexture(t.ctxTexture);
58
58
  });
59
59
  const samplers = Array.from(Array(texture.length).keys());
60
60
  this.setUniform('u_textures[0]', samplers);
@@ -27,6 +27,7 @@ import type { UniformInfo } from '../internal/ShaderUtils.js';
27
27
  import type { WebGlCoreCtxTexture } from '../WebGlCoreCtxTexture.js';
28
28
  import { ShaderEffect } from './effects/ShaderEffect.js';
29
29
  import type { EffectMap } from '../../../CoreShaderManager.js';
30
+ import memize from 'memize';
30
31
 
31
32
  /**
32
33
  * Allows the `keyof EffectMap` to be mapped over and form an discriminated
@@ -79,6 +80,27 @@ export interface SpecificEffectDesc<
79
80
  props?: ExtractProps<EffectMap[FxType]>;
80
81
  }
81
82
 
83
+ const effectCache = new Map<string, EffectDesc[]>();
84
+ const getResolvedEffect = (
85
+ effects: EffectDesc[] | undefined,
86
+ effectContructors: Partial<EffectMap> | undefined,
87
+ ): EffectDesc[] => {
88
+ const key = JSON.stringify(effects);
89
+ if (effectCache.has(key)) {
90
+ return effectCache.get(key)!;
91
+ }
92
+
93
+ const value = (effects ?? []).map((effect) => ({
94
+ type: effect.type,
95
+ props: effectContructors![effect.type]!.resolveDefaults(
96
+ (effect.props || {}) as any,
97
+ ),
98
+ })) as EffectDesc[];
99
+
100
+ effectCache.set(key, value);
101
+ return value;
102
+ };
103
+
82
104
  export class DynamicShader extends WebGlCoreShader {
83
105
  effects: Array<InstanceType<EffectMap[keyof EffectMap]>> = [];
84
106
 
@@ -108,19 +130,22 @@ export class DynamicShader extends WebGlCoreShader {
108
130
  this.effects = shader.effects as Array<
109
131
  InstanceType<EffectMap[keyof EffectMap]>
110
132
  >;
133
+
134
+ this.calculateProps = memize(this.calculateProps.bind(this));
111
135
  }
112
136
 
113
137
  override bindTextures(textures: WebGlCoreCtxTexture[]) {
114
- const { gl } = this;
115
- gl.activeTexture(gl.TEXTURE0);
116
- gl.bindTexture(gl.TEXTURE_2D, textures[0]!.ctxTexture);
138
+ const { glw } = this;
139
+ glw.activeTexture(0);
140
+ glw.bindTexture(textures[0]!.ctxTexture);
117
141
  }
118
142
 
119
- protected override bindProps(props: Required<DynamicShaderProps>): void {
120
- const effects = this.renderer.shManager.getRegisteredEffects();
121
- props.effects?.forEach((eff, index) => {
143
+ private calculateProps(effects: EffectDesc[]) {
144
+ const regEffects = this.renderer.shManager.getRegisteredEffects();
145
+ const results: { name: string; value: unknown }[] = [];
146
+ effects?.forEach((eff, index) => {
122
147
  const effect = this.effects[index]!;
123
- const fxClass = effects[effect.name as keyof EffectMap]!;
148
+ const fxClass = regEffects[effect.name as keyof EffectMap]!;
124
149
  const props = eff.props ?? {};
125
150
  const uniInfo = effect.uniformInfo;
126
151
  Object.keys(props).forEach((p) => {
@@ -132,9 +157,17 @@ export class DynamicShader extends WebGlCoreShader {
132
157
  if (Array.isArray(value)) {
133
158
  value = new Float32Array(value);
134
159
  }
135
- this.setUniform(propInfo.name, value);
160
+ results.push({ name: propInfo.name, value });
136
161
  });
137
162
  });
163
+ return results;
164
+ }
165
+
166
+ protected override bindProps(props: Required<DynamicShaderProps>): void {
167
+ const results = this.calculateProps(props.effects);
168
+ results.forEach((r) => {
169
+ this.setUniform(r.name, r.value);
170
+ });
138
171
  }
139
172
 
140
173
  static createShader(
@@ -333,12 +366,7 @@ export class DynamicShader extends WebGlCoreShader {
333
366
  effectContructors?: Partial<EffectMap>,
334
367
  ): Required<DynamicShaderProps> {
335
368
  return {
336
- effects: (props.effects ?? []).map((effect) => ({
337
- type: effect.type,
338
- props: effectContructors![effect.type]!.resolveDefaults(
339
- (effect.props || {}) as any,
340
- ),
341
- })) as MapEffectDescs<keyof EffectMap>[],
369
+ effects: getResolvedEffect(props.effects, effectContructors),
342
370
  $dimensions: {
343
371
  width: 0,
344
372
  height: 0,
@@ -71,9 +71,9 @@ export class RoundedRectangle extends WebGlCoreShader {
71
71
  }
72
72
 
73
73
  override bindTextures(textures: WebGlCoreCtxTexture[]) {
74
- const { gl } = this;
75
- gl.activeTexture(gl.TEXTURE0);
76
- gl.bindTexture(gl.TEXTURE_2D, textures[0]!.ctxTexture);
74
+ const { glw } = this;
75
+ glw.activeTexture(0);
76
+ glw.bindTexture(textures[0]!.ctxTexture);
77
77
  }
78
78
 
79
79
  protected override bindProps(props: Required<RoundedRectangleProps>): void {
@@ -80,9 +80,9 @@ export class SdfShader extends WebGlCoreShader {
80
80
  }
81
81
 
82
82
  override bindTextures(textures: WebGlCoreCtxTexture[]) {
83
- const { gl } = this;
84
- gl.activeTexture(gl.TEXTURE0);
85
- gl.bindTexture(gl.TEXTURE_2D, textures[0]!.ctxTexture);
83
+ const { glw } = this;
84
+ glw.activeTexture(0);
85
+ glw.bindTexture(textures[0]!.ctxTexture);
86
86
  }
87
87
 
88
88
  protected override bindProps(props: SdfShaderProps): void {
@@ -77,7 +77,7 @@ export class BorderEffect extends ShaderEffect {
77
77
 
78
78
  static override onEffectMask = `
79
79
  float mask = clamp(shaderMask + width, 0.0, 1.0) - clamp(shaderMask, 0.0, 1.0);
80
- return mix(shaderColor, maskColor, mask);
80
+ return mix(shaderColor, mix(shaderColor, maskColor, maskColor.a), mask);
81
81
  `;
82
82
 
83
83
  static override onColorize = `
@@ -16,7 +16,23 @@
16
16
  * See the License for the specific language governing permissions and
17
17
  * limitations under the License.
18
18
  */
19
- import { ShaderEffect } from './ShaderEffect.js';
19
+ import {
20
+ ShaderEffect,
21
+ type DefaultEffectProps,
22
+ type ShaderEffectUniforms,
23
+ } from './ShaderEffect.js';
24
+
25
+ /**
26
+ * Properties of the {@link GrayscaleEffect} effect
27
+ */
28
+ export interface GrayscaleEffectProps extends DefaultEffectProps {
29
+ /**
30
+ * Grey scale amount between 0 - 1.
31
+ *
32
+ * @default 1
33
+ */
34
+ amount?: number;
35
+ }
20
36
 
21
37
  /**
22
38
  * Grayscale effect grayscales the color values of the current mask color
@@ -28,10 +44,24 @@ export class GrayscaleEffect extends ShaderEffect {
28
44
  return `grayscale`;
29
45
  }
30
46
 
47
+ static override resolveDefaults(
48
+ props: GrayscaleEffectProps,
49
+ ): Required<GrayscaleEffectProps> {
50
+ return {
51
+ amount: props.amount ?? 1,
52
+ };
53
+ }
54
+
55
+ static override uniforms: ShaderEffectUniforms = {
56
+ amount: {
57
+ value: 1,
58
+ method: 'uniform1f',
59
+ type: 'float',
60
+ },
61
+ };
62
+
31
63
  static override onColorize = `
32
- vec3 color = pow(maskColor.rgb, vec3(2.0));
33
- float gray = dot(color, vec3(0.2126, 0.7152, 0.0722));
34
- float gammaGray = sqrt(gray);
35
- return vec4(gammaGray, gammaGray, gammaGray, 1.0);
64
+ float grayness = 0.2 * maskColor.r + 0.6 * maskColor.g + 0.2 * maskColor.b;
65
+ return vec4(amount * vec3(grayness) + (1.0 - amount) * maskColor.rgb, maskColor.a);
36
66
  `;
37
67
  }
@@ -82,24 +82,23 @@ export class SdfTrFontFace<
82
82
  },
83
83
  );
84
84
 
85
- // TODO: Add texture loaded support
86
- // this.texture.on('loaded', () => {
87
- // this.checkLoaded();
88
- // });
85
+ this.texture.on('loaded', () => {
86
+ this.checkLoaded();
87
+ });
89
88
 
90
89
  // Set this.data to the fetched data from dataUrl
91
90
  fetch(atlasDataUrl)
92
91
  .then(async (response) => {
93
92
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
94
93
  (this.data as SdfFontData) = await response.json();
95
- // We know `data` is defined here, because we just set it
96
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
97
- (this.shaper as FontShaper) = new SdfFontShaper(this.data!);
98
94
  // Add all the glyphs to the glyph map
99
95
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
100
96
  this.data!.chars.forEach((glyph) => {
101
97
  this.glyphMap.set(glyph.id, glyph);
102
98
  });
99
+ // We know `data` is defined here, because we just set it
100
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
101
+ (this.shaper as FontShaper) = new SdfFontShaper(this.data!, this.glyphMap);
103
102
  this.checkLoaded();
104
103
  })
105
104
  .catch(console.error);
@@ -120,7 +119,7 @@ export class SdfTrFontFace<
120
119
 
121
120
  private checkLoaded(): void {
122
121
  if (this.loaded) return;
123
- if (/*this.texture.loaded && */ this.data) {
122
+ if (this.texture.state === 'loaded' && this.data) {
124
123
  (this.loaded as boolean) = true;
125
124
  this.emit('loaded');
126
125
  }
@@ -24,12 +24,17 @@ import { SdfFontShaper, type SdfFontData } from './SdfFontShaper.js';
24
24
  import { getUnicodeCodepoints } from '../../../renderers/SdfTextRenderer/internal/getUnicodeCodepoints.js';
25
25
  import sdfData from 'test/mockdata/Ubuntu-Bold.msdf.json';
26
26
 
27
+ const glyphMap = new Map<number, SdfFontData['chars'][0]>();
28
+ sdfData.chars.forEach((glyph) => {
29
+ glyphMap.set(glyph.id, glyph);
30
+ });
31
+
27
32
  // TODO: Need tests for
28
33
  // - mapped = false
29
34
 
30
35
  describe('SdfFontShaper', () => {
31
36
  it('should be able to shape text.', () => {
32
- const shaper = new SdfFontShaper(sdfData as unknown as SdfFontData);
37
+ const shaper = new SdfFontShaper(sdfData as unknown as SdfFontData, glyphMap);
33
38
  const peekableCodepoints = new PeekableIterator(
34
39
  getUnicodeCodepoints('Hi!'),
35
40
  );
@@ -83,7 +88,7 @@ describe('SdfFontShaper', () => {
83
88
  });
84
89
 
85
90
  it('should be able to shape text that we know have kerning pairs.', () => {
86
- const shaper = new SdfFontShaper(sdfData as unknown as SdfFontData);
91
+ const shaper = new SdfFontShaper(sdfData as unknown as SdfFontData, glyphMap);
87
92
  const peekableCodepoints = new PeekableIterator(
88
93
  getUnicodeCodepoints('WeVo'),
89
94
  );
@@ -125,7 +130,8 @@ describe('SdfFontShaper', () => {
125
130
  });
126
131
 
127
132
  it('should be able to shape text with letterSpacing.', () => {
128
- const shaper = new SdfFontShaper(sdfData as unknown as SdfFontData);
133
+
134
+ const shaper = new SdfFontShaper(sdfData as unknown as SdfFontData, glyphMap);
129
135
  const peekableCodepoints = new PeekableIterator(
130
136
  getUnicodeCodepoints('We!'),
131
137
  );
@@ -36,11 +36,13 @@ type KerningTable = Record<
36
36
 
37
37
  export class SdfFontShaper extends FontShaper {
38
38
  private readonly data: SdfFontData;
39
+ private readonly glyphMap: Map<number, SdfFontData['chars'][0]>;
39
40
  private readonly kernings: KerningTable;
40
41
 
41
- constructor(data: SdfFontData) {
42
+ constructor(data: SdfFontData, glyphMap: Map<number, SdfFontData['chars'][0]>) {
42
43
  super();
43
44
  this.data = data;
45
+ this.glyphMap = glyphMap;
44
46
 
45
47
  const kernings: KerningTable = (this.kernings = {});
46
48
  data.kernings.forEach((kerning) => {
@@ -59,7 +61,7 @@ export class SdfFontShaper extends FontShaper {
59
61
  let lastGlyphId: number | undefined = undefined;
60
62
  while ((codepointResult = codepoints.peek()) && !codepointResult.done) {
61
63
  const codepoint = codepointResult.value;
62
- const glyph = this.data.chars.find((char) => char.id === codepoint);
64
+ const glyph = this.glyphMap.get(codepoint);
63
65
  codepoints.next();
64
66
  if (glyph !== undefined) {
65
67
  // We found a glyph for this codepoint
@@ -18,7 +18,7 @@
18
18
  */
19
19
 
20
20
  import { EventEmitter } from '../../../common/EventEmitter.js';
21
- import { assertTruthy } from '../../../utils.js';
21
+ import { assertTruthy, mergeColorAlphaPremultiplied } from '../../../utils.js';
22
22
  import type { Stage } from '../../Stage.js';
23
23
  import type { Matrix3d } from '../../lib/Matrix3d.js';
24
24
  import {
@@ -114,7 +114,11 @@ export class CanvasTextRenderer extends TextRenderer<CanvasTextRendererState> {
114
114
  } else {
115
115
  this.canvas = document.createElement('canvas');
116
116
  }
117
- let context = this.canvas.getContext('2d');
117
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
118
+ let context = this.canvas.getContext('2d') as
119
+ | OffscreenCanvasRenderingContext2D
120
+ | CanvasRenderingContext2D
121
+ | null;
118
122
  if (!context) {
119
123
  // A browser may appear to support OffscreenCanvas but not actually support the Canvas '2d' context
120
124
  // Here we try getting the context again after falling back to an HTMLCanvasElement.
@@ -205,6 +209,26 @@ export class CanvasTextRenderer extends TextRenderer<CanvasTextRendererState> {
205
209
  state.props.letterSpacing = value;
206
210
  this.invalidateLayoutCache(state);
207
211
  },
212
+ lineHeight: (state, value) => {
213
+ state.props.lineHeight = value;
214
+ this.invalidateLayoutCache(state);
215
+ },
216
+ maxLines: (state, value) => {
217
+ state.props.maxLines = value;
218
+ this.invalidateLayoutCache(state);
219
+ },
220
+ textBaseline: (state, value) => {
221
+ state.props.textBaseline = value;
222
+ this.invalidateLayoutCache(state);
223
+ },
224
+ verticalAlign: (state, value) => {
225
+ state.props.verticalAlign = value;
226
+ this.invalidateLayoutCache(state);
227
+ },
228
+ overflowSuffix: (state, value) => {
229
+ state.props.overflowSuffix = value;
230
+ this.invalidateLayoutCache(state);
231
+ },
208
232
  // debug: (state, value) => {
209
233
  // state.props.debug = value;
210
234
  // },
@@ -317,6 +341,11 @@ export class CanvasTextRenderer extends TextRenderer<CanvasTextRendererState> {
317
341
  wordWrapWidth:
318
342
  state.props.contain === 'none' ? undefined : state.props.width,
319
343
  letterSpacing: state.props.letterSpacing,
344
+ lineHeight: state.props.lineHeight,
345
+ maxLines: state.props.maxLines,
346
+ textBaseline: state.props.textBaseline,
347
+ verticalAlign: state.props.verticalAlign,
348
+ overflowSuffix: state.props.overflowSuffix,
320
349
  };
321
350
  // const renderInfoCalculateTime = performance.now();
322
351
  state.renderInfo = state.lightning2TextRenderer.calculateRenderInfo();
@@ -543,15 +572,15 @@ export class CanvasTextRenderer extends TextRenderer<CanvasTextRendererState> {
543
572
  // Color alpha of text is not properly rendered to the Canvas texture, so we
544
573
  // need to apply it here.
545
574
  const combinedAlpha = alpha * getNormalizedAlphaComponent(color);
546
-
575
+ const quadColor = mergeColorAlphaPremultiplied(0xffffffff, combinedAlpha);
547
576
  if (canvasPages[0].valid) {
548
577
  this.stage.renderer.addQuad({
549
578
  alpha: combinedAlpha,
550
579
  clippingRect,
551
- colorBl: 0xffffffff,
552
- colorBr: 0xffffffff,
553
- colorTl: 0xffffffff,
554
- colorTr: 0xffffffff,
580
+ colorBl: quadColor,
581
+ colorBr: quadColor,
582
+ colorTl: quadColor,
583
+ colorTr: quadColor,
555
584
  width: canvasPages[0].texture?.dimensions?.width || 0,
556
585
  height: canvasPages[0].texture?.dimensions?.height || 0,
557
586
  texture: canvasPages[0].texture!,
@@ -571,10 +600,10 @@ export class CanvasTextRenderer extends TextRenderer<CanvasTextRendererState> {
571
600
  this.stage.renderer.addQuad({
572
601
  alpha: combinedAlpha,
573
602
  clippingRect,
574
- colorBl: 0xffffffff,
575
- colorBr: 0xffffffff,
576
- colorTl: 0xffffffff,
577
- colorTr: 0xffffffff,
603
+ colorBl: quadColor,
604
+ colorBr: quadColor,
605
+ colorTl: quadColor,
606
+ colorTr: quadColor,
578
607
  width: canvasPages[1].texture?.dimensions?.width || 0,
579
608
  height: canvasPages[1].texture?.dimensions?.height || 0,
580
609
  texture: canvasPages[1].texture!,
@@ -594,10 +623,10 @@ export class CanvasTextRenderer extends TextRenderer<CanvasTextRendererState> {
594
623
  this.stage.renderer.addQuad({
595
624
  alpha: combinedAlpha,
596
625
  clippingRect,
597
- colorBl: 0xffffffff,
598
- colorBr: 0xffffffff,
599
- colorTl: 0xffffffff,
600
- colorTr: 0xffffffff,
626
+ colorBl: quadColor,
627
+ colorBr: quadColor,
628
+ colorTl: quadColor,
629
+ colorTr: quadColor,
601
630
  width: canvasPages[2].texture?.dimensions?.width || 0,
602
631
  height: canvasPages[2].texture?.dimensions?.height || 0,
603
632
  texture: canvasPages[2].texture!,
@@ -73,7 +73,7 @@ export interface Settings {
73
73
  verticalAlign: TextVerticalAlign;
74
74
  offsetY: number | null;
75
75
  maxLines: number;
76
- maxLinesSuffix: string;
76
+ overflowSuffix: string;
77
77
  precision: number;
78
78
  textColor: RGBA;
79
79
  paddingLeft: number;
@@ -248,7 +248,7 @@ export class LightningTextTextureRenderer {
248
248
  suffix = '';
249
249
  break;
250
250
  case 'ellipsis':
251
- suffix = this._settings.maxLinesSuffix;
251
+ suffix = this._settings.overflowSuffix;
252
252
  break;
253
253
  default:
254
254
  suffix = this._settings.textOverflow;
@@ -283,10 +283,10 @@ export class LightningTextTextureRenderer {
283
283
  const usedLines = lines.slice(0, this._settings.maxLines);
284
284
 
285
285
  let otherLines = null;
286
- if (this._settings.maxLinesSuffix) {
286
+ if (this._settings.overflowSuffix) {
287
287
  // Wrap again with max lines suffix enabled.
288
- const w = this._settings.maxLinesSuffix
289
- ? this.measureText(this._settings.maxLinesSuffix)
288
+ const w = this._settings.overflowSuffix
289
+ ? this.measureText(this._settings.overflowSuffix)
290
290
  : 0;
291
291
  const al = this.wrapText(
292
292
  usedLines[usedLines.length - 1]!,
@@ -295,7 +295,7 @@ export class LightningTextTextureRenderer {
295
295
  textIndent,
296
296
  );
297
297
  usedLines[usedLines.length - 1] = `${al.l[0]!}${
298
- this._settings.maxLinesSuffix
298
+ this._settings.overflowSuffix
299
299
  }`;
300
300
  otherLines = [al.l.length > 1 ? al.l[1] : ''];
301
301
  } else {
@@ -676,7 +676,7 @@ export class LightningTextTextureRenderer {
676
676
  verticalAlign: 'top',
677
677
  offsetY: null,
678
678
  maxLines: 0,
679
- maxLinesSuffix: '..',
679
+ overflowSuffix: '...',
680
680
  textColor: [1.0, 1.0, 1.0, 1.0],
681
681
  paddingLeft: 0,
682
682
  paddingRight: 0,