@lightningjs/renderer 3.0.0-beta20 → 3.0.0-beta22

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 (159) hide show
  1. package/dist/exports/index.d.ts +1 -0
  2. package/dist/exports/index.js +1 -0
  3. package/dist/exports/index.js.map +1 -1
  4. package/dist/src/common/CommonTypes.d.ts +2 -1
  5. package/dist/src/core/CoreNode.d.ts +53 -7
  6. package/dist/src/core/CoreNode.js +175 -65
  7. package/dist/src/core/CoreNode.js.map +1 -1
  8. package/dist/src/core/CoreTextNode.d.ts +1 -1
  9. package/dist/src/core/CoreTextNode.js +3 -5
  10. package/dist/src/core/CoreTextNode.js.map +1 -1
  11. package/dist/src/core/CoreTextureManager.js +1 -1
  12. package/dist/src/core/CoreTextureManager.js.map +1 -1
  13. package/dist/src/core/Stage.d.ts +2 -1
  14. package/dist/src/core/Stage.js +9 -7
  15. package/dist/src/core/Stage.js.map +1 -1
  16. package/dist/src/core/TextureMemoryManager.d.ts +1 -1
  17. package/dist/src/core/TextureMemoryManager.js +3 -3
  18. package/dist/src/core/TextureMemoryManager.js.map +1 -1
  19. package/dist/src/core/lib/ImageWorker.d.ts +2 -2
  20. package/dist/src/core/lib/ImageWorker.js +30 -11
  21. package/dist/src/core/lib/ImageWorker.js.map +1 -1
  22. package/dist/src/core/lib/WebGlContextWrapper.js +1 -1
  23. package/dist/src/core/lib/WebGlContextWrapper.js.map +1 -1
  24. package/dist/src/core/lib/utils.d.ts +6 -2
  25. package/dist/src/core/lib/utils.js +21 -21
  26. package/dist/src/core/lib/utils.js.map +1 -1
  27. package/dist/src/core/renderers/CoreRenderer.d.ts +1 -31
  28. package/dist/src/core/renderers/CoreRenderer.js.map +1 -1
  29. package/dist/src/core/renderers/CoreShaderNode.d.ts +4 -0
  30. package/dist/src/core/renderers/CoreShaderNode.js +15 -0
  31. package/dist/src/core/renderers/CoreShaderNode.js.map +1 -1
  32. package/dist/src/core/renderers/canvas/CanvasRenderer.d.ts +3 -3
  33. package/dist/src/core/renderers/canvas/CanvasRenderer.js +38 -33
  34. package/dist/src/core/renderers/canvas/CanvasRenderer.js.map +1 -1
  35. package/dist/src/core/renderers/canvas/CanvasShaderNode.d.ts +1 -2
  36. package/dist/src/core/renderers/canvas/CanvasShaderNode.js.map +1 -1
  37. package/dist/src/core/renderers/webgl/SdfRenderOp.d.ts +33 -0
  38. package/dist/src/core/renderers/webgl/SdfRenderOp.js +97 -0
  39. package/dist/src/core/renderers/webgl/SdfRenderOp.js.map +1 -0
  40. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js +1 -1
  41. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js.map +1 -1
  42. package/dist/src/core/renderers/webgl/WebGlCtxTexture.js +12 -8
  43. package/dist/src/core/renderers/webgl/WebGlCtxTexture.js.map +1 -1
  44. package/dist/src/core/renderers/webgl/WebGlRenderer.d.ts +6 -18
  45. package/dist/src/core/renderers/webgl/WebGlRenderer.js +48 -61
  46. package/dist/src/core/renderers/webgl/WebGlRenderer.js.map +1 -1
  47. package/dist/src/core/renderers/webgl/WebGlShaderNode.d.ts +2 -4
  48. package/dist/src/core/renderers/webgl/WebGlShaderNode.js.map +1 -1
  49. package/dist/src/core/renderers/webgl/WebGlShaderProgram.d.ts +3 -4
  50. package/dist/src/core/renderers/webgl/WebGlShaderProgram.js +40 -29
  51. package/dist/src/core/renderers/webgl/WebGlShaderProgram.js.map +1 -1
  52. package/dist/src/core/renderers/webgl/shaders/effects/LinearGradientEffect.js +8 -24
  53. package/dist/src/core/renderers/webgl/shaders/effects/LinearGradientEffect.js.map +1 -1
  54. package/dist/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.js +8 -25
  55. package/dist/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.js.map +1 -1
  56. package/dist/src/core/shaders/canvas/Border.d.ts +8 -2
  57. package/dist/src/core/shaders/canvas/Border.js +62 -23
  58. package/dist/src/core/shaders/canvas/Border.js.map +1 -1
  59. package/dist/src/core/shaders/canvas/HolePunch.js +2 -1
  60. package/dist/src/core/shaders/canvas/HolePunch.js.map +1 -1
  61. package/dist/src/core/shaders/canvas/LinearGradient.js +5 -3
  62. package/dist/src/core/shaders/canvas/LinearGradient.js.map +1 -1
  63. package/dist/src/core/shaders/canvas/RadialGradient.js +7 -5
  64. package/dist/src/core/shaders/canvas/RadialGradient.js.map +1 -1
  65. package/dist/src/core/shaders/canvas/Rounded.js +2 -2
  66. package/dist/src/core/shaders/canvas/Rounded.js.map +1 -1
  67. package/dist/src/core/shaders/canvas/RoundedWithBorder.d.ts +6 -3
  68. package/dist/src/core/shaders/canvas/RoundedWithBorder.js +39 -9
  69. package/dist/src/core/shaders/canvas/RoundedWithBorder.js.map +1 -1
  70. package/dist/src/core/shaders/canvas/RoundedWithBorderAndShadow.d.ts +2 -3
  71. package/dist/src/core/shaders/canvas/RoundedWithBorderAndShadow.js +44 -7
  72. package/dist/src/core/shaders/canvas/RoundedWithBorderAndShadow.js.map +1 -1
  73. package/dist/src/core/shaders/canvas/RoundedWithShadow.js +5 -4
  74. package/dist/src/core/shaders/canvas/RoundedWithShadow.js.map +1 -1
  75. package/dist/src/core/shaders/canvas/Shadow.js +4 -2
  76. package/dist/src/core/shaders/canvas/Shadow.js.map +1 -1
  77. package/dist/src/core/shaders/canvas/utils/render.d.ts +1 -1
  78. package/dist/src/core/shaders/canvas/utils/render.js +31 -18
  79. package/dist/src/core/shaders/canvas/utils/render.js.map +1 -1
  80. package/dist/src/core/shaders/templates/BorderTemplate.d.ts +10 -0
  81. package/dist/src/core/shaders/templates/BorderTemplate.js +20 -0
  82. package/dist/src/core/shaders/templates/BorderTemplate.js.map +1 -1
  83. package/dist/src/core/shaders/webgl/Border.js +66 -14
  84. package/dist/src/core/shaders/webgl/Border.js.map +1 -1
  85. package/dist/src/core/shaders/webgl/RoundedWithBorder.js +90 -31
  86. package/dist/src/core/shaders/webgl/RoundedWithBorder.js.map +1 -1
  87. package/dist/src/core/shaders/webgl/RoundedWithBorderAndShadow.js +98 -38
  88. package/dist/src/core/shaders/webgl/RoundedWithBorderAndShadow.js.map +1 -1
  89. package/dist/src/core/shaders/webgl/RoundedWithShadow.js +5 -4
  90. package/dist/src/core/shaders/webgl/RoundedWithShadow.js.map +1 -1
  91. package/dist/src/core/shaders/webgl/Shadow.js +12 -6
  92. package/dist/src/core/shaders/webgl/Shadow.js.map +1 -1
  93. package/dist/src/core/text-rendering/CanvasFont.d.ts +14 -0
  94. package/dist/src/core/text-rendering/CanvasFont.js +115 -0
  95. package/dist/src/core/text-rendering/CanvasFont.js.map +1 -0
  96. package/dist/src/core/text-rendering/CoreFont.d.ts +33 -0
  97. package/dist/src/core/text-rendering/CoreFont.js +48 -0
  98. package/dist/src/core/text-rendering/CoreFont.js.map +1 -0
  99. package/dist/src/core/text-rendering/FontManager.d.ts +11 -0
  100. package/dist/src/core/text-rendering/FontManager.js +41 -0
  101. package/dist/src/core/text-rendering/FontManager.js.map +1 -0
  102. package/dist/src/core/text-rendering/SdfFont.d.ts +29 -0
  103. package/dist/src/core/text-rendering/SdfFont.js +142 -0
  104. package/dist/src/core/text-rendering/SdfFont.js.map +1 -0
  105. package/dist/src/core/text-rendering/SdfTextRenderer.js +12 -20
  106. package/dist/src/core/text-rendering/SdfTextRenderer.js.map +1 -1
  107. package/dist/src/core/textures/Texture.d.ts +4 -3
  108. package/dist/src/core/textures/Texture.js.map +1 -1
  109. package/dist/src/main-api/Inspector.d.ts +5 -1
  110. package/dist/src/main-api/Inspector.js +164 -1
  111. package/dist/src/main-api/Inspector.js.map +1 -1
  112. package/dist/src/main-api/Renderer.d.ts +10 -0
  113. package/dist/src/main-api/Renderer.js +2 -0
  114. package/dist/src/main-api/Renderer.js.map +1 -1
  115. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  116. package/exports/index.ts +5 -0
  117. package/package.json +1 -1
  118. package/src/common/CommonTypes.ts +2 -1
  119. package/src/core/Autosizer.ts +224 -0
  120. package/src/core/CoreNode.test.ts +116 -2
  121. package/src/core/CoreNode.ts +247 -78
  122. package/src/core/CoreTextNode.ts +3 -5
  123. package/src/core/CoreTextureManager.ts +1 -1
  124. package/src/core/Stage.ts +10 -7
  125. package/src/core/TextureMemoryManager.ts +3 -3
  126. package/src/core/lib/ImageWorker.ts +36 -11
  127. package/src/core/lib/WebGlContextWrapper.ts +1 -1
  128. package/src/core/lib/utils.ts +28 -25
  129. package/src/core/renderers/CoreRenderer.ts +1 -32
  130. package/src/core/renderers/CoreShaderNode.ts +20 -0
  131. package/src/core/renderers/canvas/CanvasRenderer.ts +43 -51
  132. package/src/core/renderers/canvas/CanvasShaderNode.ts +1 -2
  133. package/src/core/renderers/webgl/SdfRenderOp.ts +105 -0
  134. package/src/core/renderers/webgl/WebGlCtxTexture.ts +16 -9
  135. package/src/core/renderers/webgl/WebGlRenderer.ts +56 -78
  136. package/src/core/renderers/webgl/WebGlShaderNode.ts +2 -7
  137. package/src/core/renderers/webgl/WebGlShaderProgram.ts +48 -38
  138. package/src/core/shaders/canvas/Border.ts +86 -29
  139. package/src/core/shaders/canvas/HolePunch.ts +2 -1
  140. package/src/core/shaders/canvas/LinearGradient.ts +8 -6
  141. package/src/core/shaders/canvas/RadialGradient.ts +7 -10
  142. package/src/core/shaders/canvas/Rounded.ts +5 -5
  143. package/src/core/shaders/canvas/RoundedWithBorder.ts +68 -18
  144. package/src/core/shaders/canvas/RoundedWithBorderAndShadow.ts +71 -23
  145. package/src/core/shaders/canvas/RoundedWithShadow.ts +6 -5
  146. package/src/core/shaders/canvas/Shadow.ts +7 -5
  147. package/src/core/shaders/canvas/utils/render.ts +45 -36
  148. package/src/core/shaders/templates/BorderTemplate.ts +30 -0
  149. package/src/core/shaders/webgl/Border.ts +66 -15
  150. package/src/core/shaders/webgl/RoundedWithBorder.ts +90 -31
  151. package/src/core/shaders/webgl/RoundedWithBorderAndShadow.ts +98 -38
  152. package/src/core/shaders/webgl/RoundedWithShadow.ts +5 -4
  153. package/src/core/shaders/webgl/Shadow.ts +12 -6
  154. package/src/core/text-rendering/SdfTextRenderer.ts +18 -21
  155. package/src/core/textures/Texture.ts +10 -6
  156. package/src/main-api/Inspector.ts +221 -3
  157. package/src/main-api/Renderer.ts +13 -0
  158. package/dist/tsconfig.tsbuildinfo +0 -1
  159. package/src/core/renderers/webgl/WebGlRenderOp.ts +0 -170
@@ -29,6 +29,8 @@ export const RoundedWithBorder: WebGlShaderType<RoundedWithBorderProps> = {
29
29
  update(node: CoreNode) {
30
30
  this.uniformRGBA('u_borderColor', this.props!['border-color']);
31
31
  this.uniform4fa('u_borderWidth', this.props!['border-w'] as Vec4);
32
+ this.uniform1f('u_borderGap', this.props!['border-gap'] as number);
33
+ this.uniform1f('u_borderAlign', this.props!['border-align'] as number);
32
34
 
33
35
  this.uniform4fa(
34
36
  'u_radius',
@@ -53,41 +55,93 @@ export const RoundedWithBorder: WebGlShaderType<RoundedWithBorderProps> = {
53
55
 
54
56
  uniform vec4 u_radius;
55
57
  uniform vec4 u_borderWidth;
58
+ uniform float u_borderGap;
59
+ uniform float u_borderAlign;
56
60
 
57
61
  varying vec4 v_color;
58
62
  varying vec2 v_textureCoords;
59
63
  varying vec2 v_nodeCoords;
60
64
 
61
- varying vec4 v_innerRadius;
62
65
  varying vec2 v_innerSize;
66
+ varying vec2 v_outerSize;
67
+ varying vec2 v_outerBorderUv;
68
+ varying vec2 v_innerBorderUv;
69
+ varying vec4 v_innerBorderRadius;
70
+ varying vec4 v_outerBorderRadius;
63
71
  varying vec2 v_halfDimensions;
72
+ varying float v_edgeWidth;
64
73
  varying float v_borderZero;
65
74
 
66
75
  void main() {
67
- vec2 normalized = a_position * u_pixelRatio;
76
+ vec2 vertexPos = a_position * u_pixelRatio;
68
77
  vec2 screenSpace = vec2(2.0 / u_resolution.x, -2.0 / u_resolution.y);
69
-
70
- v_color = a_color;
71
- v_nodeCoords = a_nodeCoords;
72
- v_textureCoords = a_textureCoords;
73
-
74
- v_halfDimensions = u_dimensions * 0.5;
78
+ vec2 edge = clamp(a_nodeCoords * 2.0 - vec2(1.0), -1.0, 1.0);
79
+ vec2 edgeOffset = vec2(0.0);
75
80
 
76
81
  v_borderZero = u_borderWidth == vec4(0.0) ? 1.0 : 0.0;
82
+ v_innerSize = vec2(0.0);
83
+ v_outerSize = vec2(0.0);
77
84
 
78
85
  if(v_borderZero == 0.0) {
79
- v_innerRadius = vec4(
80
- max(0.0, u_radius.x - max(u_borderWidth.x, u_borderWidth.w) - 0.5),
81
- max(0.0, u_radius.y - max(u_borderWidth.x, u_borderWidth.y) - 0.5),
82
- max(0.0, u_radius.z - max(u_borderWidth.z, u_borderWidth.y) - 0.5),
83
- max(0.0, u_radius.w - max(u_borderWidth.z, u_borderWidth.w) - 0.5)
86
+ float borderTop = u_borderWidth.x;
87
+ float borderRight = u_borderWidth.y;
88
+ float borderBottom = u_borderWidth.z;
89
+ float borderLeft = u_borderWidth.w;
90
+
91
+ v_outerBorderUv = vec2(0.0);
92
+ v_innerBorderUv = vec2(0.0);
93
+
94
+ vec2 borderSize = vec2(borderRight + borderLeft, borderTop + borderBottom);
95
+ vec2 extraSize = borderSize * u_borderAlign;
96
+ float gapLeft = step(0.001, borderLeft) * u_borderGap;
97
+ float gapRight = step(0.001, borderRight) * u_borderGap;
98
+ float gapTop = step(0.001, borderTop) * u_borderGap;
99
+ float gapBottom = step(0.001, borderBottom) * u_borderGap;
100
+ vec2 gapSize = vec2(gapLeft + gapRight, gapTop + gapBottom);
101
+
102
+ v_outerSize = (u_dimensions + gapSize + extraSize) * 0.5;
103
+ v_innerSize = v_outerSize - borderSize * 0.5;
104
+
105
+ // Use sign() to avoid branching
106
+ vec2 borderDiff = vec2(borderRight - borderLeft, borderBottom - borderTop);
107
+ vec2 signDiff = sign(borderDiff);
108
+ borderDiff = abs(borderDiff);
109
+
110
+ vec2 gapDiff = vec2(gapRight - gapLeft, gapBottom - gapTop);
111
+ vec2 signGapDiff = sign(gapDiff);
112
+ gapDiff = abs(gapDiff);
113
+
114
+ v_outerBorderUv = -signDiff * borderDiff * u_borderAlign * 0.5 - signGapDiff * gapDiff * 0.5;
115
+ v_innerBorderUv = v_outerBorderUv + signDiff * borderDiff * 0.5;
116
+
117
+ v_outerBorderRadius = vec4(
118
+ max(0.0, u_radius.x + max(borderTop * u_borderAlign + u_borderGap, borderLeft * u_borderAlign + u_borderGap)),
119
+ max(0.0, u_radius.y + max(borderTop * u_borderAlign + u_borderGap, borderRight * u_borderAlign + u_borderGap)),
120
+ max(0.0, u_radius.z + max(borderBottom * u_borderAlign + u_borderGap, borderRight * u_borderAlign + u_borderGap)),
121
+ max(0.0, u_radius.w + max(borderBottom * u_borderAlign + u_borderGap, borderLeft * u_borderAlign + u_borderGap))
84
122
  );
85
123
 
86
- v_innerSize = (vec2(u_dimensions.x - (u_borderWidth[3] + u_borderWidth[1]) + 1.0, u_dimensions.y - (u_borderWidth[0] + u_borderWidth[2])) - 2.0) * 0.5;
124
+ v_innerBorderRadius = vec4(
125
+ max(0.0, v_outerBorderRadius.x - max(borderTop, borderLeft)),
126
+ max(0.0, v_outerBorderRadius.y - max(borderTop, borderRight)),
127
+ max(0.0, v_outerBorderRadius.z - max(borderBottom, borderRight)),
128
+ max(0.0, v_outerBorderRadius.w - max(borderBottom, borderLeft))
129
+ );
130
+
131
+ vec2 edgeOffsetExtra = step(u_dimensions * 0.5, v_outerSize) * edge * (extraSize + u_borderGap);
132
+ edgeOffset = edgeOffsetExtra;
133
+
134
+ vertexPos = (a_position + edge + edgeOffset) * u_pixelRatio;
87
135
  }
88
136
 
89
- gl_Position = vec4(normalized.x * screenSpace.x - 1.0, normalized.y * -abs(screenSpace.y) + 1.0, 0.0, 1.0);
90
- gl_Position.y = -sign(screenSpace.y) * gl_Position.y;
137
+ gl_Position = vec4(vertexPos.x * screenSpace.x - 1.0, -sign(screenSpace.y) * (vertexPos.y * -abs(screenSpace.y)) + 1.0, 0.0, 1.0);
138
+
139
+ v_color = a_color;
140
+ v_nodeCoords = a_nodeCoords + (screenSpace + edgeOffset) / (u_dimensions);
141
+ v_textureCoords = a_textureCoords + (screenSpace + edgeOffset) / (u_dimensions);
142
+
143
+ v_halfDimensions = u_dimensions * 0.5;
144
+ v_edgeWidth = 1.0 / u_pixelRatio;
91
145
  }
92
146
  `,
93
147
  fragment: `
@@ -104,17 +158,23 @@ export const RoundedWithBorder: WebGlShaderType<RoundedWithBorderProps> = {
104
158
  uniform sampler2D u_texture;
105
159
 
106
160
  uniform vec4 u_radius;
107
-
108
161
  uniform vec4 u_borderWidth;
109
162
  uniform vec4 u_borderColor;
163
+ uniform float u_borderGap;
164
+ uniform float u_borderAlign;
110
165
 
111
166
  varying vec4 v_color;
112
167
  varying vec2 v_textureCoords;
113
168
  varying vec2 v_nodeCoords;
114
169
 
115
- varying vec2 v_halfDimensions;
116
- varying vec4 v_innerRadius;
117
170
  varying vec2 v_innerSize;
171
+ varying vec2 v_outerSize;
172
+ varying vec2 v_outerBorderUv;
173
+ varying vec2 v_innerBorderUv;
174
+ varying vec4 v_innerBorderRadius;
175
+ varying vec4 v_outerBorderRadius;
176
+ varying vec2 v_halfDimensions;
177
+ varying float v_edgeWidth;
118
178
  varying float v_borderZero;
119
179
 
120
180
  float roundedBox(vec2 p, vec2 s, vec4 r) {
@@ -126,27 +186,26 @@ export const RoundedWithBorder: WebGlShaderType<RoundedWithBorderProps> = {
126
186
 
127
187
  void main() {
128
188
  vec4 color = texture2D(u_texture, v_textureCoords) * v_color;
129
-
189
+ vec4 resultColor = vec4(0.0);
130
190
  vec2 boxUv = v_nodeCoords.xy * u_dimensions - v_halfDimensions;
131
- float outerDist = roundedBox(boxUv, v_halfDimensions, u_radius);
132
191
 
133
- float edgeWidth = 1.0 / u_pixelRatio;
134
- float outerAlpha = 1.0 - smoothstep(-0.5 * edgeWidth, 0.5 * edgeWidth, outerDist);
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);
194
+ resultColor = mix(resultColor, color, nodeAlpha);
135
195
 
136
196
  if(v_borderZero == 1.0) {
137
- gl_FragColor = mix(vec4(0.0), color, outerAlpha) * u_alpha;
197
+ gl_FragColor = resultColor * u_alpha;
138
198
  return;
139
199
  }
140
200
 
141
- boxUv.x += u_borderWidth.y > u_borderWidth.w ? (u_borderWidth.y - u_borderWidth.w) * 0.5 : -(u_borderWidth.w - u_borderWidth.y) * 0.5;
142
- boxUv.y += u_borderWidth.z > u_borderWidth.x ? ((u_borderWidth.z - u_borderWidth.x) * 0.5 + 0.5) : -(u_borderWidth.x - u_borderWidth.z) * 0.5;
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);
143
203
 
144
- float innerDist = roundedBox(boxUv, v_innerSize, v_innerRadius);
145
- float innerAlpha = 1.0 - smoothstep(-0.5 * edgeWidth, 0.5 * edgeWidth, innerDist);
204
+ float borderDist = max(-innerDist, outerDist);
205
+ float borderAlpha = (1.0 - smoothstep(-0.5 * v_edgeWidth, 0.5 * v_edgeWidth, borderDist)) * u_borderColor.a;
146
206
 
147
- vec4 resColor = mix(u_borderColor, color, innerAlpha);
148
- resColor = mix(vec4(0.0), resColor, outerAlpha);
149
- gl_FragColor = resColor * u_alpha;
207
+ resultColor = mix(resultColor, vec4(u_borderColor.rgb, 1.0), borderAlpha);
208
+ gl_FragColor = resultColor * u_alpha;
150
209
  }
151
210
  `,
152
211
  };
@@ -31,6 +31,8 @@ export const RoundedWithBorderAndShadow: WebGlShaderType<RoundedWithBorderAndSha
31
31
  const props = this.props!;
32
32
  this.uniformRGBA('u_borderColor', props['border-color']);
33
33
  this.uniform4fa('u_borderWidth', props['border-w'] as Vec4);
34
+ this.uniform1f('u_borderGap', this.props!['border-gap'] as number);
35
+ this.uniform1f('u_borderAlign', this.props!['border-align'] as number);
34
36
 
35
37
  this.uniformRGBA('u_shadowColor', props['shadow-color']);
36
38
  this.uniform4fa('u_shadow', props['shadow-projection']);
@@ -60,45 +62,94 @@ export const RoundedWithBorderAndShadow: WebGlShaderType<RoundedWithBorderAndSha
60
62
  uniform vec4 u_shadow;
61
63
  uniform vec4 u_radius;
62
64
  uniform vec4 u_borderWidth;
65
+ uniform float u_borderGap;
66
+ uniform float u_borderAlign;
63
67
 
64
68
  varying vec4 v_color;
65
69
  varying vec2 v_textureCoords;
66
70
  varying vec2 v_nodeCoords;
67
71
 
68
- varying vec4 v_innerRadius;
69
72
  varying vec2 v_innerSize;
73
+ varying vec2 v_outerSize;
74
+ varying vec2 v_outerBorderUv;
75
+ varying vec2 v_innerBorderUv;
76
+ varying vec4 v_innerBorderRadius;
77
+ varying vec4 v_outerBorderRadius;
70
78
  varying vec2 v_halfDimensions;
79
+ varying float v_edgeWidth;
71
80
  varying float v_borderZero;
72
81
 
73
82
  void main() {
74
83
  vec2 screenSpace = vec2(2.0 / u_resolution.x, -2.0 / u_resolution.y);
75
- vec2 outerEdge = clamp(a_nodeCoords * 2.0 - vec2(1.0), -1.0, 1.0);
84
+ vec2 edge = clamp(a_nodeCoords * 2.0 - vec2(1.0), -1.0, 1.0);
76
85
 
77
- vec2 shadowEdge = outerEdge * ((u_shadow.w * 2.0)+ u_shadow.z) + u_shadow.xy;
78
- vec2 normVertexPos = a_position * u_pixelRatio;
79
-
80
- vec2 vertexPos = (a_position + outerEdge + shadowEdge) * u_pixelRatio;
81
- gl_Position = vec4(vertexPos.x * screenSpace.x - 1.0, -sign(screenSpace.y) * (vertexPos.y * -abs(screenSpace.y)) + 1.0, 0.0, 1.0);
82
-
83
- v_halfDimensions = u_dimensions * 0.5;
84
-
85
- v_color = a_color;
86
- v_nodeCoords = a_nodeCoords + (screenSpace + shadowEdge) / (u_dimensions);
87
- v_textureCoords = a_textureCoords + (screenSpace + shadowEdge) / (u_dimensions);
86
+ vec2 edgeOffset = edge * ((u_shadow.w * 2.0)+ u_shadow.z) + u_shadow.xy;
87
+ vec2 vertexPos = (a_position + edge + edgeOffset) * u_pixelRatio;
88
88
 
89
89
  v_borderZero = u_borderWidth == vec4(0.0) ? 1.0 : 0.0;
90
90
 
91
+ v_innerSize = vec2(0.0);
92
+ v_outerSize = vec2(0.0);
91
93
 
92
94
  if(v_borderZero == 0.0) {
93
- v_innerRadius = vec4(
94
- max(0.0, u_radius.x - max(u_borderWidth.x, u_borderWidth.w) - 0.5),
95
- max(0.0, u_radius.y - max(u_borderWidth.x, u_borderWidth.y) - 0.5),
96
- max(0.0, u_radius.z - max(u_borderWidth.z, u_borderWidth.y) - 0.5),
97
- max(0.0, u_radius.w - max(u_borderWidth.z, u_borderWidth.w) - 0.5)
95
+ float borderTop = u_borderWidth.x;
96
+ float borderRight = u_borderWidth.y;
97
+ float borderBottom = u_borderWidth.z;
98
+ float borderLeft = u_borderWidth.w;
99
+
100
+ v_outerBorderUv = vec2(0.0);
101
+ v_innerBorderUv = vec2(0.0);
102
+
103
+ vec2 borderSize = vec2(borderRight + borderLeft, borderTop + borderBottom);
104
+ vec2 extraSize = borderSize * u_borderAlign;
105
+ float gapLeft = step(0.001, borderLeft) * u_borderGap;
106
+ float gapRight = step(0.001, borderRight) * u_borderGap;
107
+ float gapTop = step(0.001, borderTop) * u_borderGap;
108
+ float gapBottom = step(0.001, borderBottom) * u_borderGap;
109
+ vec2 gapSize = vec2(gapLeft + gapRight, gapTop + gapBottom);
110
+
111
+ v_outerSize = (u_dimensions + gapSize + extraSize) * 0.5;
112
+ v_innerSize = v_outerSize - borderSize * 0.5;
113
+
114
+ // Use sign() to avoid branching
115
+ vec2 borderDiff = vec2(borderRight - borderLeft, borderBottom - borderTop);
116
+ vec2 signDiff = sign(borderDiff);
117
+ borderDiff = abs(borderDiff);
118
+
119
+ vec2 gapDiff = vec2(gapRight - gapLeft, gapBottom - gapTop);
120
+ vec2 signGapDiff = sign(gapDiff);
121
+ gapDiff = abs(gapDiff);
122
+
123
+ v_outerBorderUv = -signDiff * borderDiff * u_borderAlign * 0.5 - signGapDiff * gapDiff * 0.5;
124
+ v_innerBorderUv = v_outerBorderUv + signDiff * borderDiff * 0.5;
125
+
126
+ v_outerBorderRadius = vec4(
127
+ max(0.0, u_radius.x + max(borderTop * u_borderAlign + u_borderGap, borderLeft * u_borderAlign + u_borderGap)),
128
+ max(0.0, u_radius.y + max(borderTop * u_borderAlign + u_borderGap, borderRight * u_borderAlign + u_borderGap)),
129
+ max(0.0, u_radius.z + max(borderBottom * u_borderAlign + u_borderGap, borderRight * u_borderAlign + u_borderGap)),
130
+ max(0.0, u_radius.w + max(borderBottom * u_borderAlign + u_borderGap, borderLeft * u_borderAlign + u_borderGap))
98
131
  );
99
132
 
100
- v_innerSize = (vec2(u_dimensions.x - (u_borderWidth[3] + u_borderWidth[1]) - 1.0, u_dimensions.y - (u_borderWidth[0] + u_borderWidth[2])) - 2.0) * 0.5;
133
+ v_innerBorderRadius = vec4(
134
+ max(0.0, v_outerBorderRadius.x - max(borderTop, borderLeft)),
135
+ max(0.0, v_outerBorderRadius.y - max(borderTop, borderRight)),
136
+ max(0.0, v_outerBorderRadius.z - max(borderBottom, borderRight)),
137
+ max(0.0, v_outerBorderRadius.w - max(borderBottom, borderLeft))
138
+ );
139
+
140
+ vec2 edgeOffsetExtra = step(u_dimensions * 0.5, v_outerSize) * edge * (extraSize + u_borderGap);
141
+ edgeOffset += edgeOffsetExtra;
142
+
143
+ vertexPos = (a_position + edge + edgeOffset) * u_pixelRatio;
101
144
  }
145
+
146
+ gl_Position = vec4(vertexPos.x * screenSpace.x - 1.0, -sign(screenSpace.y) * (vertexPos.y * -abs(screenSpace.y)) + 1.0, 0.0, 1.0);
147
+
148
+ v_halfDimensions = u_dimensions * 0.5;
149
+ v_edgeWidth = 1.0 / u_pixelRatio;
150
+ v_color = a_color;
151
+ v_nodeCoords = a_nodeCoords + (screenSpace + edgeOffset) / (u_dimensions);
152
+ v_textureCoords = a_textureCoords + (screenSpace + edgeOffset) / (u_dimensions);
102
153
  }
103
154
  `,
104
155
  fragment: `
@@ -125,9 +176,14 @@ export const RoundedWithBorderAndShadow: WebGlShaderType<RoundedWithBorderAndSha
125
176
  varying vec2 v_textureCoords;
126
177
  varying vec2 v_nodeCoords;
127
178
 
128
- varying vec2 v_halfDimensions;
129
- varying vec4 v_innerRadius;
130
179
  varying vec2 v_innerSize;
180
+ varying vec2 v_outerSize;
181
+ varying vec2 v_outerBorderUv;
182
+ varying vec2 v_innerBorderUv;
183
+ varying vec4 v_innerBorderRadius;
184
+ varying vec4 v_outerBorderRadius;
185
+ varying vec2 v_halfDimensions;
186
+ varying float v_edgeWidth;
131
187
  varying float v_borderZero;
132
188
 
133
189
  float roundedBox(vec2 p, vec2 s, vec4 r) {
@@ -147,30 +203,34 @@ export const RoundedWithBorderAndShadow: WebGlShaderType<RoundedWithBorderAndSha
147
203
 
148
204
  void main() {
149
205
  vec4 color = texture2D(u_texture, v_textureCoords) * v_color;
150
-
206
+ vec4 resultColor = vec4(0.0);
151
207
  vec2 boxUv = v_nodeCoords.xy * u_dimensions - v_halfDimensions;
152
- float outerDist = roundedBox(boxUv, v_halfDimensions - 1.0, u_radius);
153
-
154
- float edgeWidth = 1.0 / u_pixelRatio;
155
- float outerAlpha = 1.0 - smoothstep(-0.5 * edgeWidth, 0.5 * edgeWidth, outerDist);
156
-
157
- float shadowAlpha = shadowBox(boxUv - u_shadow.xy, v_halfDimensions + u_shadow.w, u_radius + u_shadow.z);
158
- vec4 shadow = mix(vec4(0.0), u_shadowColor, shadowAlpha);
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);
210
+ float shadowAlpha;
159
211
 
160
212
  if(v_borderZero == 1.0) {
161
- gl_FragColor = mix(shadow, color, outerAlpha) * u_alpha;
213
+ shadowAlpha = shadowBox(boxUv - u_shadow.xy, v_halfDimensions + u_shadow.w - v_edgeWidth, u_radius + u_shadow.z);
214
+ resultColor = mix(resultColor, u_shadowColor, shadowAlpha);
215
+ gl_FragColor = mix(resultColor, color, nodeAlpha) * u_alpha;
162
216
  return;
163
217
  }
164
218
 
165
- boxUv.x += u_borderWidth.y > u_borderWidth.w ? (u_borderWidth.y - u_borderWidth.w) * 0.5 : -(u_borderWidth.w - u_borderWidth.y) * 0.5;
166
- boxUv.y += u_borderWidth.z > u_borderWidth.x ? ((u_borderWidth.z - u_borderWidth.x) * 0.5 + 0.5) : -(u_borderWidth.x - u_borderWidth.z) * 0.5;
167
-
168
- float innerDist = roundedBox(boxUv, v_innerSize, v_innerRadius);
169
- float innerAlpha = 1.0 - smoothstep(-0.5 * edgeWidth, 0.5 * edgeWidth, innerDist);
219
+ 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);
221
+ }
222
+ else {
223
+ shadowAlpha = shadowBox(boxUv - u_shadow.xy, v_halfDimensions + u_shadow.w - v_edgeWidth, u_radius + u_shadow.z);
224
+ }
170
225
 
171
- vec4 resColor = mix(u_borderColor, color, innerAlpha);
172
- resColor = mix(shadow, resColor, outerAlpha);
173
- gl_FragColor = resColor * u_alpha;
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);
228
+ float borderDist = max(-innerDist, outerDist);
229
+ float borderAlpha = (1.0 - smoothstep(-0.5 * v_edgeWidth, 0.5 * v_edgeWidth, borderDist)) * u_borderColor.a;
230
+ resultColor = mix(resultColor, u_shadowColor, shadowAlpha);
231
+ resultColor = mix(resultColor, color, nodeAlpha);
232
+ resultColor = mix(resultColor, vec4(u_borderColor.rgb, 1.0), borderAlpha);
233
+ gl_FragColor = resultColor * u_alpha;
174
234
  }
175
235
  `,
176
236
  };
@@ -59,6 +59,8 @@ export const RoundedWithShadow: WebGlShaderType<RoundedWithShadowProps> = {
59
59
  varying vec2 v_textureCoords;
60
60
  varying vec2 v_nodeCoords;
61
61
 
62
+ varying float v_edgeWidth;
63
+
62
64
  float roundedBox(vec2 p, vec2 s, vec4 r) {
63
65
  r.xy = (p.x > 0.0) ? r.yz : r.xw;
64
66
  r.x = (p.y > 0.0) ? r.y : r.x;
@@ -79,12 +81,11 @@ export const RoundedWithShadow: WebGlShaderType<RoundedWithShadowProps> = {
79
81
  vec2 halfDimensions = (u_dimensions * 0.5);
80
82
 
81
83
  vec2 boxUv = v_nodeCoords.xy * u_dimensions - halfDimensions;
82
- float boxDist = roundedBox(boxUv, halfDimensions, u_radius);
84
+ float boxDist = roundedBox(boxUv, halfDimensions - v_edgeWidth, u_radius);
83
85
 
84
- float edgeWidth = 1.0 / u_pixelRatio;
85
- float roundedAlpha = 1.0 - smoothstep(-0.5 * edgeWidth, 0.5 * edgeWidth, boxDist);
86
+ float roundedAlpha = 1.0 - smoothstep(-0.5 * v_edgeWidth, 0.5 * v_edgeWidth, boxDist);
86
87
 
87
- float shadowAlpha = shadowBox(boxUv - u_shadow.xy, halfDimensions + u_shadow.w, u_radius + u_shadow.z);
88
+ float shadowAlpha = shadowBox(boxUv - u_shadow.xy, halfDimensions + u_shadow.w - v_edgeWidth, u_radius + u_shadow.z);
88
89
 
89
90
  vec4 resColor = vec4(0.0);
90
91
  resColor = mix(resColor, u_shadow_color, shadowAlpha);
@@ -50,12 +50,14 @@ export const Shadow: WebGlShaderType<ShadowProps> = {
50
50
  varying vec2 v_textureCoords;
51
51
  varying vec2 v_nodeCoords;
52
52
 
53
+ varying float v_edgeWidth;
54
+ varying vec2 v_halfDimensions;
55
+
53
56
  void main() {
54
57
  vec2 screenSpace = vec2(2.0 / u_resolution.x, -2.0 / u_resolution.y);
55
58
  vec2 outerEdge = clamp(a_nodeCoords * 2.0 - vec2(1.0), -1.0, 1.0);
56
59
 
57
60
  vec2 shadowEdge = outerEdge * ((u_shadow.w * 2.0)+ u_shadow.z) + u_shadow.xy;
58
- vec2 normVertexPos = a_position * u_pixelRatio;
59
61
 
60
62
  vec2 vertexPos = (a_position + outerEdge + shadowEdge) * u_pixelRatio;
61
63
  gl_Position = vec4(vertexPos.x * screenSpace.x - 1.0, -sign(screenSpace.y) * (vertexPos.y * -abs(screenSpace.y)) + 1.0, 0.0, 1.0);
@@ -63,6 +65,9 @@ export const Shadow: WebGlShaderType<ShadowProps> = {
63
65
  v_color = a_color;
64
66
  v_nodeCoords = a_nodeCoords + (screenSpace + shadowEdge) / (u_dimensions);
65
67
  v_textureCoords = a_textureCoords + (screenSpace + shadowEdge) / (u_dimensions);
68
+
69
+ v_halfDimensions = u_dimensions * 0.5;
70
+ v_edgeWidth = 1.0 / u_pixelRatio;
66
71
  }
67
72
  `,
68
73
  fragment: `
@@ -85,6 +90,9 @@ export const Shadow: WebGlShaderType<ShadowProps> = {
85
90
  varying vec2 v_textureCoords;
86
91
  varying vec2 v_nodeCoords;
87
92
 
93
+ varying vec2 v_halfDimensions;
94
+ varying float v_edgeWidth;
95
+
88
96
  float box(vec2 p, vec2 s) {
89
97
  vec2 q = abs(p) - s;
90
98
  return (min(max(q.x, q.y), 0.0) + length(max(q, 0.0))) + 2.0;
@@ -98,13 +106,11 @@ export const Shadow: WebGlShaderType<ShadowProps> = {
98
106
 
99
107
  void main() {
100
108
  vec4 color = texture2D(u_texture, v_textureCoords) * v_color;
101
- vec2 halfDimensions = (u_dimensions * 0.5);
102
-
103
- vec2 boxUv = v_nodeCoords.xy * u_dimensions - halfDimensions;
104
- float boxDist = box(boxUv, halfDimensions);
109
+ vec2 boxUv = v_nodeCoords.xy * u_dimensions - v_halfDimensions;
110
+ float boxDist = box(boxUv, v_halfDimensions - v_edgeWidth);
105
111
 
106
112
  float boxAlpha = 1.0 - smoothstep(0.0, u_pixelRatio, boxDist);
107
- float shadowDist = shadowBox(boxUv - u_shadow.xy, halfDimensions + u_shadow.w, u_shadow.z);
113
+ float shadowDist = shadowBox(boxUv - u_shadow.xy, v_halfDimensions + u_shadow.w - v_edgeWidth, u_shadow.z);
108
114
 
109
115
  vec4 resColor = vec4(0.0);
110
116
  resColor = mix(resColor, u_color, shadowDist);
@@ -29,7 +29,7 @@ import { hasZeroWidthSpace } from './Utils.js';
29
29
  import * as SdfFontHandler from './SdfFontHandler.js';
30
30
  import type { CoreRenderer } from '../renderers/CoreRenderer.js';
31
31
  import { WebGlRenderer } from '../renderers/webgl/WebGlRenderer.js';
32
- import { WebGlRenderOp } from '../renderers/webgl/WebGlRenderOp.js';
32
+ import { SdfRenderOp } from '../renderers/webgl/SdfRenderOp.js';
33
33
  import { Sdf, type SdfShaderProps } from '../shaders/webgl/SdfShader.js';
34
34
  import { BufferCollection } from '../renderers/webgl/internal/BufferCollection.js';
35
35
  import type { WebGlCtxTexture } from '../renderers/webgl/WebGlCtxTexture.js';
@@ -238,28 +238,25 @@ const renderQuads = (
238
238
  glw.arrayBufferData(buffer, vertexBuffer, glw.STATIC_DRAW as number);
239
239
  }
240
240
 
241
- const renderOp = new WebGlRenderOp(
241
+ const renderOp = new SdfRenderOp(
242
242
  renderer as WebGlRenderer,
243
+ sdfShader!, // Ensure sdfShader is not null
243
244
  {
244
- sdfShaderProps: {
245
- transform: globalTransform,
246
- color: mergeColorAlpha(color, worldAlpha),
247
- size: layout.fontScale, // Use proper font scaling in shader
248
- distanceRange: layout.distanceRange,
249
- } satisfies SdfShaderProps,
250
- sdfBuffers: webGlBuffers,
251
- shader: sdfShader,
252
- alpha: worldAlpha,
253
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment
254
- clippingRect: renderProps.clippingRect as any,
255
- height: layout.height,
256
- width: layout.width,
257
- rtt: false,
258
- parentHasRenderTexture: renderProps.parentHasRenderTexture,
259
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment
260
- framebufferDimensions: renderProps.framebufferDimensions as any,
261
- },
262
- 0,
245
+ transform: globalTransform,
246
+ color: mergeColorAlpha(color, worldAlpha),
247
+ size: layout.fontScale, // Use proper font scaling in shader
248
+ distanceRange: layout.distanceRange,
249
+ } satisfies SdfShaderProps,
250
+ webGlBuffers,
251
+ worldAlpha,
252
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
253
+ renderProps.clippingRect as any,
254
+ layout.width,
255
+ layout.height,
256
+ false,
257
+ renderProps.parentHasRenderTexture,
258
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
259
+ renderProps.framebufferDimensions as any,
263
260
  );
264
261
 
265
262
  // Add atlas texture and set quad count
@@ -23,6 +23,7 @@ import type { Dimensions } from '../../common/CommonTypes.js';
23
23
  import { EventEmitter } from '../../common/EventEmitter.js';
24
24
  import type { CoreContextTexture } from '../renderers/CoreContextTexture.js';
25
25
  import type { Bound } from '../lib/utils.js';
26
+ import type { TextureError } from '../TextureError.js';
26
27
 
27
28
  /**
28
29
  * Event handler for when a Texture is freed
@@ -86,7 +87,10 @@ export interface CompressedData {
86
87
  /**
87
88
  * Event handler for when a Texture fails to load
88
89
  */
89
- export type TextureFailedEventHandler = (target: any, error: Error) => void;
90
+ export type TextureFailedEventHandler = (
91
+ target: any,
92
+ error: TextureError,
93
+ ) => void;
90
94
 
91
95
  /**
92
96
  * TextureData that is used to populate a CoreContextTexture
@@ -151,7 +155,7 @@ export abstract class Texture extends EventEmitter {
151
155
  * `null`.
152
156
  */
153
157
  private _dimensions: Dimensions | null = null;
154
- private _error: Error | null = null;
158
+ private _error: TextureError | null = null;
155
159
 
156
160
  // aggregate state
157
161
  public state: TextureState = 'initial';
@@ -205,7 +209,7 @@ export abstract class Texture extends EventEmitter {
205
209
  return this._dimensions;
206
210
  }
207
211
 
208
- get error(): Error | null {
212
+ get error(): TextureError | null {
209
213
  return this._error;
210
214
  }
211
215
 
@@ -393,13 +397,13 @@ export abstract class Texture extends EventEmitter {
393
397
 
394
398
  public setState(
395
399
  state: TextureState,
396
- errorOrDimensions?: Error | Dimensions,
400
+ errorOrDimensions?: TextureError | Dimensions,
397
401
  ): void {
398
402
  if (this.state === state) {
399
403
  return;
400
404
  }
401
405
 
402
- let payload: Error | Dimensions | null = null;
406
+ let payload: TextureError | Dimensions | null = null;
403
407
  if (state === 'loaded') {
404
408
  if (
405
409
  errorOrDimensions !== undefined &&
@@ -413,7 +417,7 @@ export abstract class Texture extends EventEmitter {
413
417
 
414
418
  payload = this._dimensions;
415
419
  } else if (state === 'failed') {
416
- this._error = errorOrDimensions as Error;
420
+ this._error = errorOrDimensions as TextureError;
417
421
  payload = this._error;
418
422
 
419
423
  // increment the retry count for the texture