@lightningjs/renderer 3.0.0-beta22 → 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 (190) hide show
  1. package/README.md +93 -0
  2. package/dist/exports/index.d.ts +3 -1
  3. package/dist/exports/index.js +2 -0
  4. package/dist/exports/index.js.map +1 -1
  5. package/dist/exports/platform.d.ts +7 -0
  6. package/dist/exports/platform.js +27 -0
  7. package/dist/exports/platform.js.map +1 -0
  8. package/dist/src/core/AutosizeManager.d.ts +29 -0
  9. package/dist/src/core/AutosizeManager.js +169 -0
  10. package/dist/src/core/AutosizeManager.js.map +1 -0
  11. package/dist/src/core/CoreNode.d.ts +0 -1
  12. package/dist/src/core/CoreNode.js +47 -41
  13. package/dist/src/core/CoreNode.js.map +1 -1
  14. package/dist/src/core/CoreTextureManager.d.ts +0 -13
  15. package/dist/src/core/CoreTextureManager.js +4 -78
  16. package/dist/src/core/CoreTextureManager.js.map +1 -1
  17. package/dist/src/core/Stage.js +2 -12
  18. package/dist/src/core/Stage.js.map +1 -1
  19. package/dist/src/core/animations/Animation.d.ts +21 -0
  20. package/dist/src/core/animations/Animation.js +194 -0
  21. package/dist/src/core/animations/Animation.js.map +1 -0
  22. package/dist/src/core/animations/CoreAnimationController.d.ts +1 -1
  23. package/dist/src/core/animations/CoreAnimationController.js +4 -2
  24. package/dist/src/core/animations/CoreAnimationController.js.map +1 -1
  25. package/dist/src/core/animations/Playback.d.ts +64 -0
  26. package/dist/src/core/animations/Playback.js +169 -0
  27. package/dist/src/core/animations/Playback.js.map +1 -0
  28. package/dist/src/core/animations/Transition.d.ts +27 -0
  29. package/dist/src/core/animations/Transition.js +52 -0
  30. package/dist/src/core/animations/Transition.js.map +1 -0
  31. package/dist/src/core/animations/utils.d.ts +2 -0
  32. package/dist/src/core/animations/utils.js +136 -0
  33. package/dist/src/core/animations/utils.js.map +1 -0
  34. package/dist/src/core/lib/collectionUtils.d.ts +0 -1
  35. package/dist/src/core/lib/collectionUtils.js +0 -28
  36. package/dist/src/core/lib/collectionUtils.js.map +1 -1
  37. package/dist/src/core/lib/utils.d.ts +0 -5
  38. package/dist/src/core/lib/utils.js +0 -63
  39. package/dist/src/core/lib/utils.js.map +1 -1
  40. package/dist/src/core/platforms/GlContextWrapper.d.ts +136 -0
  41. package/dist/src/core/platforms/GlContextWrapper.js +32 -0
  42. package/dist/src/core/platforms/GlContextWrapper.js.map +1 -0
  43. package/dist/src/core/platforms/Platform.d.ts +74 -13
  44. package/dist/src/core/platforms/Platform.js +18 -0
  45. package/dist/src/core/platforms/Platform.js.map +1 -1
  46. package/dist/src/core/platforms/web/WebGlContextWrapper.d.ts +776 -0
  47. package/dist/src/core/platforms/web/WebGlContextWrapper.js +1208 -0
  48. package/dist/src/core/platforms/web/WebGlContextWrapper.js.map +1 -0
  49. package/dist/src/core/platforms/web/WebPlatform.d.ts +13 -2
  50. package/dist/src/core/platforms/web/WebPlatform.js +109 -8
  51. package/dist/src/core/platforms/web/WebPlatform.js.map +1 -1
  52. package/dist/src/core/platforms/web/WebPlatformChrome50.d.ts +17 -0
  53. package/dist/src/core/platforms/web/WebPlatformChrome50.js +50 -0
  54. package/dist/src/core/platforms/web/WebPlatformChrome50.js.map +1 -0
  55. package/dist/src/core/platforms/web/WebPlatformLegacy.d.ts +18 -0
  56. package/dist/src/core/platforms/web/WebPlatformLegacy.js +99 -0
  57. package/dist/src/core/platforms/web/WebPlatformLegacy.js.map +1 -0
  58. package/dist/src/core/platforms/web/WebPlatformNext.d.ts +21 -0
  59. package/dist/src/core/platforms/web/WebPlatformNext.js +52 -0
  60. package/dist/src/core/platforms/web/WebPlatformNext.js.map +1 -0
  61. package/dist/src/core/platforms/web/lib/ImageWorker.d.ts +15 -0
  62. package/dist/src/core/platforms/web/lib/ImageWorker.js +189 -0
  63. package/dist/src/core/platforms/web/lib/ImageWorker.js.map +1 -0
  64. package/dist/src/core/platforms/web/lib/createImageBitmap.d.ts +1 -0
  65. package/dist/src/core/platforms/web/lib/createImageBitmap.js +27 -0
  66. package/dist/src/core/platforms/web/lib/createImageBitmap.js.map +1 -0
  67. package/dist/src/core/platforms/web/lib/textureCompression.d.ts +26 -0
  68. package/dist/src/core/platforms/web/lib/textureCompression.js +301 -0
  69. package/dist/src/core/platforms/web/lib/textureCompression.js.map +1 -0
  70. package/dist/src/core/platforms/web/lib/textureSvg.d.ts +7 -0
  71. package/dist/src/core/platforms/web/lib/textureSvg.js +51 -0
  72. package/dist/src/core/platforms/web/lib/textureSvg.js.map +1 -0
  73. package/dist/src/core/platforms/web/lib/utils.d.ts +5 -0
  74. package/dist/src/core/platforms/web/lib/utils.js +86 -0
  75. package/dist/src/core/platforms/web/lib/utils.js.map +1 -0
  76. package/dist/src/core/renderers/CoreRenderer.d.ts +1 -9
  77. package/dist/src/core/renderers/CoreRenderer.js +2 -4
  78. package/dist/src/core/renderers/CoreRenderer.js.map +1 -1
  79. package/dist/src/core/renderers/canvas/CanvasRenderer.d.ts +3 -2
  80. package/dist/src/core/renderers/canvas/CanvasRenderer.js +6 -5
  81. package/dist/src/core/renderers/canvas/CanvasRenderer.js.map +1 -1
  82. package/dist/src/core/renderers/canvas/CanvasShaderNode.js +3 -3
  83. package/dist/src/core/renderers/canvas/CanvasShaderNode.js.map +1 -1
  84. package/dist/src/core/renderers/webgl/SdfRenderOp.js +3 -2
  85. package/dist/src/core/renderers/webgl/SdfRenderOp.js.map +1 -1
  86. package/dist/src/core/renderers/webgl/WebGlCtxRenderTexture.d.ts +2 -2
  87. package/dist/src/core/renderers/webgl/WebGlCtxRenderTexture.js.map +1 -1
  88. package/dist/src/core/renderers/webgl/WebGlCtxSubTexture.d.ts +2 -2
  89. package/dist/src/core/renderers/webgl/WebGlCtxSubTexture.js.map +1 -1
  90. package/dist/src/core/renderers/webgl/WebGlCtxTexture.d.ts +3 -3
  91. package/dist/src/core/renderers/webgl/WebGlCtxTexture.js +1 -2
  92. package/dist/src/core/renderers/webgl/WebGlCtxTexture.js.map +1 -1
  93. package/dist/src/core/renderers/webgl/WebGlRenderer.d.ts +5 -5
  94. package/dist/src/core/renderers/webgl/WebGlRenderer.js +10 -11
  95. package/dist/src/core/renderers/webgl/WebGlRenderer.js.map +1 -1
  96. package/dist/src/core/renderers/webgl/WebGlShaderNode.d.ts +2 -2
  97. package/dist/src/core/renderers/webgl/WebGlShaderNode.js +3 -3
  98. package/dist/src/core/renderers/webgl/WebGlShaderNode.js.map +1 -1
  99. package/dist/src/core/renderers/webgl/WebGlShaderProgram.d.ts +2 -2
  100. package/dist/src/core/renderers/webgl/WebGlShaderProgram.js +0 -3
  101. package/dist/src/core/renderers/webgl/WebGlShaderProgram.js.map +1 -1
  102. package/dist/src/core/renderers/webgl/internal/RendererUtils.d.ts +4 -4
  103. package/dist/src/core/renderers/webgl/internal/RendererUtils.js.map +1 -1
  104. package/dist/src/core/renderers/webgl/internal/ShaderUtils.d.ts +3 -3
  105. package/dist/src/core/renderers/webgl/internal/ShaderUtils.js +3 -2
  106. package/dist/src/core/renderers/webgl/internal/ShaderUtils.js.map +1 -1
  107. package/dist/src/core/renderers/webgl/shaders/effects/LinearGradientEffect.js +24 -8
  108. package/dist/src/core/renderers/webgl/shaders/effects/LinearGradientEffect.js.map +1 -1
  109. package/dist/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.js +25 -8
  110. package/dist/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.js.map +1 -1
  111. package/dist/src/core/shaders/webgl/Border.js +6 -4
  112. package/dist/src/core/shaders/webgl/Border.js.map +1 -1
  113. package/dist/src/core/shaders/webgl/RoundedWithBorder.js +16 -17
  114. package/dist/src/core/shaders/webgl/RoundedWithBorder.js.map +1 -1
  115. package/dist/src/core/shaders/webgl/RoundedWithBorderAndShadow.js +19 -21
  116. package/dist/src/core/shaders/webgl/RoundedWithBorderAndShadow.js.map +1 -1
  117. package/dist/src/core/shaders/webgl/SdfShadowShader.d.ts +9 -0
  118. package/dist/src/core/shaders/webgl/SdfShadowShader.js +100 -0
  119. package/dist/src/core/shaders/webgl/SdfShadowShader.js.map +1 -0
  120. package/dist/src/core/text-rendering/CanvasFont.d.ts +1 -1
  121. package/dist/src/core/text-rendering/CanvasFont.js +2 -6
  122. package/dist/src/core/text-rendering/CanvasFont.js.map +1 -1
  123. package/dist/src/core/text-rendering/CoreFont.d.ts +1 -1
  124. package/dist/src/core/text-rendering/CoreFont.js +1 -1
  125. package/dist/src/core/text-rendering/CoreFont.js.map +1 -1
  126. package/dist/src/core/text-rendering/FontManager.js +2 -1
  127. package/dist/src/core/text-rendering/FontManager.js.map +1 -1
  128. package/dist/src/core/text-rendering/SdfFontHandler.js +10 -20
  129. package/dist/src/core/text-rendering/SdfFontHandler.js.map +1 -1
  130. package/dist/src/core/text-rendering/SdfTextRenderer.js +10 -12
  131. package/dist/src/core/text-rendering/SdfTextRenderer.js.map +1 -1
  132. package/dist/src/core/textures/ImageTexture.d.ts +24 -11
  133. package/dist/src/core/textures/ImageTexture.js +32 -95
  134. package/dist/src/core/textures/ImageTexture.js.map +1 -1
  135. package/dist/src/core/textures/SubTexture.js +3 -3
  136. package/dist/src/core/textures/SubTexture.js.map +1 -1
  137. package/dist/src/core/textures/Texture.d.ts +1 -1
  138. package/dist/src/core/textures/Texture.js +1 -1
  139. package/dist/src/core/textures/Texture.js.map +1 -1
  140. package/dist/src/main-api/Renderer.js +18 -21
  141. package/dist/src/main-api/Renderer.js.map +1 -1
  142. package/dist/src/utils.d.ts +0 -2
  143. package/dist/src/utils.js +0 -36
  144. package/dist/src/utils.js.map +1 -1
  145. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  146. package/dist/tsconfig.tsbuildinfo +1 -0
  147. package/exports/index.ts +3 -1
  148. package/exports/platform.ts +31 -0
  149. package/package.json +3 -2
  150. package/src/core/CoreNode.ts +52 -49
  151. package/src/core/CoreTextureManager.ts +10 -103
  152. package/src/core/Stage.ts +1 -14
  153. package/src/core/animations/CoreAnimationController.ts +5 -2
  154. package/src/core/lib/collectionUtils.ts +0 -35
  155. package/src/core/lib/utils.ts +0 -78
  156. package/src/core/platforms/GlContextWrapper.ts +291 -0
  157. package/src/core/platforms/Platform.ts +121 -28
  158. package/src/core/{lib → platforms/web}/WebGlContextWrapper.ts +129 -4
  159. package/src/core/platforms/web/WebPlatform.ts +171 -22
  160. package/src/core/platforms/web/WebPlatformChrome50.ts +57 -0
  161. package/src/core/platforms/web/WebPlatformLegacy.ts +140 -0
  162. package/src/core/platforms/web/WebPlatformNext.ts +57 -0
  163. package/src/core/{lib → platforms/web/lib}/ImageWorker.ts +10 -74
  164. package/src/core/platforms/web/lib/createImageBitmap.ts +40 -0
  165. package/src/core/{lib → platforms/web/lib}/textureCompression.ts +19 -138
  166. package/src/core/{lib → platforms/web/lib}/textureSvg.ts +3 -15
  167. package/src/core/platforms/web/lib/utils.ts +105 -0
  168. package/src/core/renderers/CoreRenderer.ts +2 -11
  169. package/src/core/renderers/canvas/CanvasRenderer.ts +8 -6
  170. package/src/core/renderers/canvas/CanvasShaderNode.ts +3 -3
  171. package/src/core/renderers/webgl/SdfRenderOp.ts +3 -2
  172. package/src/core/renderers/webgl/WebGlCtxRenderTexture.ts +2 -2
  173. package/src/core/renderers/webgl/WebGlCtxSubTexture.ts +2 -2
  174. package/src/core/renderers/webgl/WebGlCtxTexture.ts +3 -4
  175. package/src/core/renderers/webgl/WebGlRenderer.ts +15 -22
  176. package/src/core/renderers/webgl/WebGlShaderNode.ts +5 -5
  177. package/src/core/renderers/webgl/WebGlShaderProgram.ts +2 -6
  178. package/src/core/renderers/webgl/internal/RendererUtils.ts +4 -8
  179. package/src/core/renderers/webgl/internal/ShaderUtils.ts +7 -5
  180. package/src/core/shaders/webgl/Border.ts +6 -4
  181. package/src/core/shaders/webgl/RoundedWithBorder.ts +16 -17
  182. package/src/core/shaders/webgl/RoundedWithBorderAndShadow.ts +19 -21
  183. package/src/core/text-rendering/SdfFontHandler.ts +10 -17
  184. package/src/core/text-rendering/SdfTextRenderer.ts +11 -16
  185. package/src/core/textures/ImageTexture.ts +42 -161
  186. package/src/core/textures/SubTexture.ts +3 -3
  187. package/src/core/textures/Texture.ts +2 -2
  188. package/src/main-api/Renderer.ts +24 -22
  189. package/src/utils.ts +0 -47
  190. package/src/core/lib/validateImageBitmap.ts +0 -87
@@ -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 type { WebGlContextWrapper } from '../../lib/WebGlContextWrapper.js';
19
+ import type { GlContextWrapper } from '../../platforms/GlContextWrapper.js';
20
20
  import { Default } from '../../shaders/webgl/Default.js';
21
21
  import type { CoreShaderProgram } from '../CoreShaderProgram.js';
22
22
  import type { WebGlCtxTexture } from './WebGlCtxTexture.js';
@@ -44,7 +44,7 @@ export class WebGlShaderProgram implements CoreShaderProgram {
44
44
  */
45
45
  protected vao: WebGLVertexArrayObject | undefined;
46
46
  protected renderer: WebGlRenderer;
47
- protected glw: WebGlContextWrapper;
47
+ protected glw: GlContextWrapper;
48
48
  protected attributeLocations: string[];
49
49
  protected uniformLocations: Record<string, WebGLUniformLocation> | null;
50
50
  protected lifecycle: Pick<WebGlShaderType, 'update' | 'canBatch'>;
@@ -112,10 +112,6 @@ export class WebGlShaderProgram implements CoreShaderProgram {
112
112
  }
113
113
 
114
114
  const program = createProgram(glw, vertexShader, fragmentShader);
115
- if (!program) {
116
- throw new Error();
117
- }
118
-
119
115
  this.program = program;
120
116
  this.attributeLocations = glw.getAttributeLocations(program);
121
117
 
@@ -17,7 +17,7 @@
17
17
  * limitations under the License.
18
18
  */
19
19
 
20
- import type { WebGlContextWrapper } from '../../../lib/WebGlContextWrapper.js';
20
+ import type { GlContextWrapper } from '../../../platforms/GlContextWrapper.js';
21
21
 
22
22
  export interface CoreWebGlParameters {
23
23
  MAX_RENDERBUFFER_SIZE: number;
@@ -36,9 +36,7 @@ export interface CoreWebGlParameters {
36
36
  * Get device specific webgl parameters
37
37
  * @param glw
38
38
  */
39
- export function getWebGlParameters(
40
- glw: WebGlContextWrapper,
41
- ): CoreWebGlParameters {
39
+ export function getWebGlParameters(glw: GlContextWrapper): CoreWebGlParameters {
42
40
  const params: CoreWebGlParameters = {
43
41
  MAX_RENDERBUFFER_SIZE: 0,
44
42
  MAX_TEXTURE_SIZE: 0,
@@ -81,9 +79,7 @@ export interface CoreWebGlExtensions {
81
79
  * Get device webgl extensions
82
80
  * @param glw
83
81
  */
84
- export function getWebGlExtensions(
85
- glw: WebGlContextWrapper,
86
- ): CoreWebGlExtensions {
82
+ export function getWebGlExtensions(glw: GlContextWrapper): CoreWebGlExtensions {
87
83
  const extensions: CoreWebGlExtensions = {
88
84
  ANGLE_instanced_arrays: null,
89
85
  WEBGL_compressed_texture_s3tc: null,
@@ -113,7 +109,7 @@ export function getWebGlExtensions(
113
109
  * @param glw
114
110
  * @param size
115
111
  */
116
- export function createIndexBuffer(glw: WebGlContextWrapper, size: number) {
112
+ export function createIndexBuffer(glw: GlContextWrapper, size: number) {
117
113
  const maxQuads = ~~(size / 80);
118
114
  const indices = new Uint16Array(maxQuads * 6);
119
115
 
@@ -17,7 +17,7 @@
17
17
  * limitations under the License.
18
18
  */
19
19
 
20
- import type { WebGlContextWrapper } from '../../../lib/WebGlContextWrapper.js';
20
+ import type { GlContextWrapper } from '../../../platforms/GlContextWrapper.js';
21
21
 
22
22
  //#region Types
23
23
  export interface AttributeInfo {
@@ -178,7 +178,7 @@ export interface ShaderProgramSources {
178
178
  //#endregion Types
179
179
 
180
180
  export function createShader(
181
- glw: WebGlContextWrapper,
181
+ glw: GlContextWrapper,
182
182
  type: number,
183
183
  source: string,
184
184
  ) {
@@ -204,7 +204,7 @@ export function createShader(
204
204
  }
205
205
 
206
206
  export function createProgram(
207
- glw: WebGlContextWrapper,
207
+ glw: GlContextWrapper,
208
208
  vertexShader: WebGLShader,
209
209
  fragmentShader: WebGLShader,
210
210
  ) {
@@ -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 = `
@@ -66,10 +66,12 @@ export const Border: WebGlShaderType<BorderProps> = {
66
66
  vec2 edge = clamp(a_nodeCoords * 2.0 - vec2(1.0), -1.0, 1.0);
67
67
  v_edgeWidth = 1.0 / u_pixelRatio;
68
68
 
69
- float borderTop = u_borderWidth.x;
70
- float borderRight = u_borderWidth.y;
71
- float borderBottom = u_borderWidth.z;
72
- float borderLeft = u_borderWidth.w;
69
+ vec4 adjustedBorderWidth = u_borderWidth - 1.0 + clamp(u_borderWidth, -1.0, 1.0);
70
+
71
+ float borderTop = adjustedBorderWidth.x;
72
+ float borderRight = adjustedBorderWidth.y;
73
+ float borderBottom = adjustedBorderWidth.z;
74
+ float borderLeft = adjustedBorderWidth.w;
73
75
 
74
76
  v_outerBorderUv = vec2(0.0);
75
77
  v_innerBorderUv = vec2(0.0);
@@ -69,24 +69,24 @@ 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) {
86
- float borderTop = u_borderWidth.x;
87
- float borderRight = u_borderWidth.y;
88
- float borderBottom = u_borderWidth.z;
89
- float borderLeft = u_borderWidth.w;
83
+ if(borderZero == 0.0) {
84
+ vec4 adjustedBorderWidth = u_borderWidth - 1.0 + clamp(u_borderWidth, -1.0, 1.0);
85
+
86
+ float borderTop = adjustedBorderWidth.x;
87
+ float borderRight = adjustedBorderWidth.y;
88
+ float borderBottom = adjustedBorderWidth.z;
89
+ float borderLeft = adjustedBorderWidth.w;
90
90
 
91
91
  v_outerBorderUv = vec2(0.0);
92
92
  v_innerBorderUv = vec2(0.0);
@@ -141,7 +141,6 @@ export const RoundedWithBorder: WebGlShaderType<RoundedWithBorderProps> = {
141
141
  v_textureCoords = a_textureCoords + (screenSpace + edgeOffset) / (u_dimensions);
142
142
 
143
143
  v_halfDimensions = u_dimensions * 0.5;
144
- v_edgeWidth = 1.0 / u_pixelRatio;
145
144
  }
146
145
  `,
147
146
  fragment: `
@@ -174,8 +173,6 @@ export const RoundedWithBorder: WebGlShaderType<RoundedWithBorderProps> = {
174
173
  varying vec4 v_innerBorderRadius;
175
174
  varying vec4 v_outerBorderRadius;
176
175
  varying vec2 v_halfDimensions;
177
- varying float v_edgeWidth;
178
- varying float v_borderZero;
179
176
 
180
177
  float roundedBox(vec2 p, vec2 s, vec4 r) {
181
178
  r.xy = (p.x > 0.0) ? r.yz : r.xw;
@@ -188,21 +185,23 @@ export const RoundedWithBorder: WebGlShaderType<RoundedWithBorderProps> = {
188
185
  vec4 color = texture2D(u_texture, v_textureCoords) * v_color;
189
186
  vec4 resultColor = vec4(0.0);
190
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;
191
190
 
192
- float nodeDist = roundedBox(boxUv, v_halfDimensions - v_edgeWidth, u_radius);
193
- 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);
194
193
  resultColor = mix(resultColor, color, nodeAlpha);
195
194
 
196
- if(v_borderZero == 1.0) {
195
+ if(borderZero == 1.0) {
197
196
  gl_FragColor = resultColor * u_alpha;
198
197
  return;
199
198
  }
200
199
 
201
- float outerDist = roundedBox(boxUv + v_outerBorderUv, v_outerSize - v_edgeWidth, v_outerBorderRadius);
202
- 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);
203
202
 
204
203
  float borderDist = max(-innerDist, outerDist);
205
- 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;
206
205
 
207
206
  resultColor = mix(resultColor, vec4(u_borderColor.rgb, 1.0), borderAlpha);
208
207
  gl_FragColor = resultColor * u_alpha;
@@ -76,26 +76,25 @@ 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) {
95
- float borderTop = u_borderWidth.x;
96
- float borderRight = u_borderWidth.y;
97
- float borderBottom = u_borderWidth.z;
98
- float borderLeft = u_borderWidth.w;
91
+ if(borderZero == 0.0) {
92
+ vec4 adjustedBorderWidth = u_borderWidth - 1.0 + clamp(u_borderWidth, -1.0, 1.0);
93
+
94
+ float borderTop = adjustedBorderWidth.x;
95
+ float borderRight = adjustedBorderWidth.y;
96
+ float borderBottom = adjustedBorderWidth.z;
97
+ float borderLeft = adjustedBorderWidth.w;
99
98
 
100
99
  v_outerBorderUv = vec2(0.0);
101
100
  v_innerBorderUv = vec2(0.0);
@@ -146,7 +145,6 @@ export const RoundedWithBorderAndShadow: WebGlShaderType<RoundedWithBorderAndSha
146
145
  gl_Position = vec4(vertexPos.x * screenSpace.x - 1.0, -sign(screenSpace.y) * (vertexPos.y * -abs(screenSpace.y)) + 1.0, 0.0, 1.0);
147
146
 
148
147
  v_halfDimensions = u_dimensions * 0.5;
149
- v_edgeWidth = 1.0 / u_pixelRatio;
150
148
  v_color = a_color;
151
149
  v_nodeCoords = a_nodeCoords + (screenSpace + edgeOffset) / (u_dimensions);
152
150
  v_textureCoords = a_textureCoords + (screenSpace + edgeOffset) / (u_dimensions);
@@ -183,8 +181,6 @@ export const RoundedWithBorderAndShadow: WebGlShaderType<RoundedWithBorderAndSha
183
181
  varying vec4 v_innerBorderRadius;
184
182
  varying vec4 v_outerBorderRadius;
185
183
  varying vec2 v_halfDimensions;
186
- varying float v_edgeWidth;
187
- varying float v_borderZero;
188
184
 
189
185
  float roundedBox(vec2 p, vec2 s, vec4 r) {
190
186
  r.xy = (p.x > 0.0) ? r.yz : r.xw;
@@ -205,28 +201,30 @@ export const RoundedWithBorderAndShadow: WebGlShaderType<RoundedWithBorderAndSha
205
201
  vec4 color = texture2D(u_texture, v_textureCoords) * v_color;
206
202
  vec4 resultColor = vec4(0.0);
207
203
  vec2 boxUv = v_nodeCoords.xy * u_dimensions - v_halfDimensions;
208
- float nodeDist = roundedBox(boxUv, v_halfDimensions - v_edgeWidth, u_radius);
209
- 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);
210
208
  float shadowAlpha;
211
209
 
212
- if(v_borderZero == 1.0) {
213
- 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);
214
212
  resultColor = mix(resultColor, u_shadowColor, shadowAlpha);
215
213
  gl_FragColor = mix(resultColor, color, nodeAlpha) * u_alpha;
216
214
  return;
217
215
  }
218
216
 
219
217
  if(v_outerSize.x > v_halfDimensions.x || v_outerSize.y > v_halfDimensions.y) {
220
- 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);
221
219
  }
222
220
  else {
223
- 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);
224
222
  }
225
223
 
226
- float outerDist = roundedBox(boxUv + v_outerBorderUv, v_outerSize - v_edgeWidth, v_outerBorderRadius);
227
- 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);
228
226
  float borderDist = max(-innerDist, outerDist);
229
- 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;
230
228
  resultColor = mix(resultColor, u_shadowColor, shadowAlpha);
231
229
  resultColor = mix(resultColor, color, nodeAlpha);
232
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
  }
@@ -19,19 +19,8 @@
19
19
 
20
20
  import type { CoreTextureManager } from '../CoreTextureManager.js';
21
21
  import { Texture, TextureType, type TextureData } from './Texture.js';
22
- import {
23
- isCompressedTextureContainer,
24
- loadCompressedTexture,
25
- } from '../lib/textureCompression.js';
26
- import {
27
- convertUrlToAbsolute,
28
- dataURIToBlob,
29
- isBase64Image,
30
- } from '../lib/utils.js';
31
- import { isSvgImage, loadSvg } from '../lib/textureSvg.js';
32
- import { fetchJson } from '../lib/utils.js';
33
22
  import type { Platform } from '../platforms/Platform.js';
34
- import { isProductionEnvironment } from '../../utils.js';
23
+ import type { CompressedImageData } from '../platforms/web/lib/textureCompression.js';
35
24
 
36
25
  /**
37
26
  * Properties of the {@link ImageTexture}
@@ -117,6 +106,11 @@ export interface ImageTextureProps {
117
106
  maxRetryCount?: number;
118
107
  }
119
108
 
109
+ export interface ImageResponse {
110
+ data: ImageBitmap | ImageData | CompressedImageData | HTMLImageElement | null;
111
+ premultiplyAlpha: boolean | null;
112
+ }
113
+
120
114
  /**
121
115
  * Texture consisting of an image loaded from a URL
122
116
  *
@@ -148,125 +142,6 @@ export class ImageTexture extends Texture {
148
142
  this.maxRetryCount = props.maxRetryCount as number;
149
143
  }
150
144
 
151
- hasAlphaChannel(mimeType: string) {
152
- return mimeType.indexOf('image/png') !== -1;
153
- }
154
-
155
- async loadImageFallback(src: string | Blob, hasAlpha: boolean) {
156
- const img = new Image();
157
-
158
- if (typeof src === 'string' && isBase64Image(src) === false) {
159
- img.crossOrigin = 'anonymous';
160
- }
161
-
162
- return new Promise<{
163
- data: HTMLImageElement | null;
164
- premultiplyAlpha: boolean;
165
- }>((resolve, reject) => {
166
- img.onload = () => {
167
- resolve({ data: img, premultiplyAlpha: hasAlpha });
168
- };
169
-
170
- img.onerror = (err) => {
171
- const errorMessage =
172
- err instanceof Error
173
- ? err.message
174
- : err instanceof Event
175
- ? `Image loading failed for ${img.src}`
176
- : 'Unknown image loading error';
177
- reject(new Error(`Image loading failed: ${errorMessage}`));
178
- };
179
-
180
- if (src instanceof Blob) {
181
- img.src = URL.createObjectURL(src);
182
- } else {
183
- img.src = src;
184
- }
185
- });
186
- }
187
-
188
- async createImageBitmap(
189
- blob: Blob,
190
- premultiplyAlpha: boolean | null,
191
- sx: number | null,
192
- sy: number | null,
193
- sw: number | null,
194
- sh: number | null,
195
- ): Promise<{
196
- data: ImageBitmap | HTMLImageElement;
197
- premultiplyAlpha: boolean;
198
- }> {
199
- const hasAlphaChannel = premultiplyAlpha ?? blob.type.includes('image/png');
200
- const imageBitmapSupported = this.txManager.imageBitmapSupported;
201
-
202
- if (imageBitmapSupported.full === true && sw !== null && sh !== null) {
203
- // createImageBitmap with crop
204
- const bitmap = await this.platform.createImageBitmap(
205
- blob,
206
- sx || 0,
207
- sy || 0,
208
- sw,
209
- sh,
210
- {
211
- premultiplyAlpha: hasAlphaChannel ? 'premultiply' : 'none',
212
- colorSpaceConversion: 'none',
213
- imageOrientation: 'none',
214
- },
215
- );
216
- return { data: bitmap, premultiplyAlpha: hasAlphaChannel };
217
- } else if (imageBitmapSupported.basic === true) {
218
- // basic createImageBitmap without options or crop
219
- // this is supported for Chrome v50 to v52/54 that doesn't support options
220
- return {
221
- data: await this.platform.createImageBitmap(blob),
222
- premultiplyAlpha: hasAlphaChannel,
223
- };
224
- }
225
-
226
- // default createImageBitmap without crop but with options
227
- const bitmap = await this.platform.createImageBitmap(blob, {
228
- premultiplyAlpha: hasAlphaChannel ? 'premultiply' : 'none',
229
- colorSpaceConversion: 'none',
230
- imageOrientation: 'none',
231
- });
232
- return { data: bitmap, premultiplyAlpha: hasAlphaChannel };
233
- }
234
-
235
- async loadImage(src: string) {
236
- const { premultiplyAlpha, sx, sy, sw, sh } = this.props;
237
-
238
- if (this.txManager.hasCreateImageBitmap === true) {
239
- if (
240
- isBase64Image(src) === false &&
241
- this.txManager.hasWorker === true &&
242
- this.txManager.imageWorkerManager !== null
243
- ) {
244
- return this.txManager.imageWorkerManager.getImage(
245
- src,
246
- premultiplyAlpha,
247
- sx,
248
- sy,
249
- sw,
250
- sh,
251
- );
252
- }
253
-
254
- let blob;
255
-
256
- if (isBase64Image(src) === true) {
257
- blob = dataURIToBlob(src);
258
- } else {
259
- blob = await fetchJson(src, 'blob').then(
260
- (response) => response as Blob,
261
- );
262
- }
263
-
264
- return this.createImageBitmap(blob, premultiplyAlpha, sx, sy, sw, sh);
265
- }
266
-
267
- return this.loadImageFallback(src, premultiplyAlpha ?? true);
268
- }
269
-
270
145
  override async getTextureSource(): Promise<TextureData> {
271
146
  let resp: TextureData;
272
147
  try {
@@ -293,7 +168,10 @@ export class ImageTexture extends Texture {
293
168
  }
294
169
 
295
170
  determineImageTypeAndLoadImage() {
296
- const { src, premultiplyAlpha, type } = this.props;
171
+ const { src, premultiplyAlpha, type, w, h, sx, sy, sw, sh } = this.props;
172
+ const platform = this.platform;
173
+ const premultiply = premultiplyAlpha ?? true;
174
+
297
175
  if (src === null) {
298
176
  return {
299
177
  data: null,
@@ -302,13 +180,9 @@ export class ImageTexture extends Texture {
302
180
 
303
181
  if (typeof src !== 'string') {
304
182
  if (src instanceof Blob) {
305
- if (this.txManager.hasCreateImageBitmap === true) {
306
- const { sx, sy, sw, sh } = this.props;
307
- return this.createImageBitmap(src, premultiplyAlpha, sx, sy, sw, sh);
308
- } else {
309
- return this.loadImageFallback(src, premultiplyAlpha ?? true);
310
- }
183
+ return platform.createImage(src, premultiply, sx, sy, sw, sh);
311
184
  }
185
+
312
186
  if (src instanceof ImageData) {
313
187
  return {
314
188
  data: src,
@@ -321,45 +195,28 @@ export class ImageTexture extends Texture {
321
195
  };
322
196
  }
323
197
 
324
- const absoluteSrc = convertUrlToAbsolute(src);
325
198
  if (type === 'regular') {
326
- return this.loadImage(absoluteSrc);
199
+ return platform.loadImage(src, premultiply, sx, sy, sw, sh);
327
200
  }
328
201
 
329
202
  if (type === 'svg') {
330
- return loadSvg(
331
- absoluteSrc,
332
- this.props.w,
333
- this.props.h,
334
- this.props.sx,
335
- this.props.sy,
336
- this.props.sw,
337
- this.props.sh,
338
- );
203
+ return platform.loadSvg(src, w, h, sx, sy, sw, sh);
339
204
  }
340
205
 
341
206
  if (isSvgImage(src) === true) {
342
- return loadSvg(
343
- absoluteSrc,
344
- this.props.w,
345
- this.props.h,
346
- this.props.sx,
347
- this.props.sy,
348
- this.props.sw,
349
- this.props.sh,
350
- );
207
+ return platform.loadSvg(src, w, h, sx, sy, sw, sh);
351
208
  }
352
209
 
353
210
  if (type === 'compressed') {
354
- return loadCompressedTexture(absoluteSrc);
211
+ return platform.loadCompressedTexture(src);
355
212
  }
356
213
 
357
214
  if (isCompressedTextureContainer(src) === true) {
358
- return loadCompressedTexture(absoluteSrc);
215
+ return platform.loadCompressedTexture(src);
359
216
  }
360
217
 
361
218
  // default
362
- return this.loadImage(absoluteSrc);
219
+ return platform.loadImage(src, premultiply, sx, sy, sw, sh);
363
220
  }
364
221
 
365
222
  /**
@@ -409,3 +266,27 @@ export class ImageTexture extends Texture {
409
266
 
410
267
  static z$__type__Props: ImageTextureProps;
411
268
  }
269
+
270
+ /**
271
+ * Tests if the given location is a SVG
272
+ * @param url
273
+ * @remarks
274
+ * This function is used to determine if the given image url is a SVG
275
+ * image
276
+ * @returns
277
+ */
278
+ export function isSvgImage(url: string): boolean {
279
+ return /\.(svg)(\?.*)?$/.test(url);
280
+ }
281
+
282
+ /**
283
+ * Tests if the given location is a compressed texture container
284
+ * @param url
285
+ * @remarks
286
+ * This function is used to determine if the given image url is a compressed
287
+ * and only supports the following extensions: .ktx and .pvr
288
+ * @returns
289
+ */
290
+ export function isCompressedTextureContainer(src: string): boolean {
291
+ return /\.(ktx|pvr)$/.test(src);
292
+ }