@codexo/exojs 0.8.3 → 0.9.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 (317) hide show
  1. package/CHANGELOG.md +107 -0
  2. package/README.md +26 -5
  3. package/dist/esm/animation/Tween.d.ts +20 -3
  4. package/dist/esm/animation/Tween.js +16 -8
  5. package/dist/esm/animation/Tween.js.map +1 -1
  6. package/dist/esm/animation/TweenManager.d.ts +16 -1
  7. package/dist/esm/animation/TweenManager.js +27 -2
  8. package/dist/esm/animation/TweenManager.js.map +1 -1
  9. package/dist/esm/audio/AudioAnalyser.d.ts +2 -0
  10. package/dist/esm/audio/AudioAnalyser.js +24 -9
  11. package/dist/esm/audio/AudioAnalyser.js.map +1 -1
  12. package/dist/esm/audio/AudioBus.d.ts +1 -0
  13. package/dist/esm/audio/AudioBus.js +8 -4
  14. package/dist/esm/audio/AudioBus.js.map +1 -1
  15. package/dist/esm/audio/AudioListener.d.ts +1 -0
  16. package/dist/esm/audio/AudioListener.js +7 -5
  17. package/dist/esm/audio/AudioListener.js.map +1 -1
  18. package/dist/esm/audio/AudioManager.d.ts +8 -2
  19. package/dist/esm/audio/AudioManager.js +14 -1
  20. package/dist/esm/audio/AudioManager.js.map +1 -1
  21. package/dist/esm/audio/BeatDetector.d.ts +2 -0
  22. package/dist/esm/audio/BeatDetector.js +27 -661
  23. package/dist/esm/audio/BeatDetector.js.map +1 -1
  24. package/dist/esm/audio/Music.d.ts +1 -0
  25. package/dist/esm/audio/Music.js +7 -3
  26. package/dist/esm/audio/Music.js.map +1 -1
  27. package/dist/esm/audio/OscillatorSound.d.ts +1 -0
  28. package/dist/esm/audio/OscillatorSound.js +7 -3
  29. package/dist/esm/audio/OscillatorSound.js.map +1 -1
  30. package/dist/esm/audio/Sound.d.ts +1 -0
  31. package/dist/esm/audio/Sound.js +7 -3
  32. package/dist/esm/audio/Sound.js.map +1 -1
  33. package/dist/esm/audio/audio-context.d.ts +2 -2
  34. package/dist/esm/audio/audio-context.js +4 -4
  35. package/dist/esm/audio/audio-context.js.map +1 -1
  36. package/dist/esm/audio/filters/ChorusFilter.d.ts +1 -0
  37. package/dist/esm/audio/filters/ChorusFilter.js +7 -3
  38. package/dist/esm/audio/filters/ChorusFilter.js.map +1 -1
  39. package/dist/esm/audio/filters/CompressorFilter.d.ts +1 -0
  40. package/dist/esm/audio/filters/CompressorFilter.js +7 -3
  41. package/dist/esm/audio/filters/CompressorFilter.js.map +1 -1
  42. package/dist/esm/audio/filters/DelayFilter.d.ts +1 -0
  43. package/dist/esm/audio/filters/DelayFilter.js +7 -3
  44. package/dist/esm/audio/filters/DelayFilter.js.map +1 -1
  45. package/dist/esm/audio/filters/EqualizerFilter.d.ts +1 -0
  46. package/dist/esm/audio/filters/EqualizerFilter.js +7 -3
  47. package/dist/esm/audio/filters/EqualizerFilter.js.map +1 -1
  48. package/dist/esm/audio/filters/GranularFilter.js +1 -86
  49. package/dist/esm/audio/filters/GranularFilter.js.map +1 -1
  50. package/dist/esm/audio/filters/HighpassFilter.d.ts +1 -0
  51. package/dist/esm/audio/filters/HighpassFilter.js +7 -3
  52. package/dist/esm/audio/filters/HighpassFilter.js.map +1 -1
  53. package/dist/esm/audio/filters/LowpassFilter.d.ts +1 -0
  54. package/dist/esm/audio/filters/LowpassFilter.js +7 -3
  55. package/dist/esm/audio/filters/LowpassFilter.js.map +1 -1
  56. package/dist/esm/audio/filters/PitchShiftFilter.js +1 -71
  57. package/dist/esm/audio/filters/PitchShiftFilter.js.map +1 -1
  58. package/dist/esm/audio/filters/ReverbFilter.d.ts +1 -0
  59. package/dist/esm/audio/filters/ReverbFilter.js +7 -3
  60. package/dist/esm/audio/filters/ReverbFilter.js.map +1 -1
  61. package/dist/esm/audio/filters/VocoderFilter.js +1 -89
  62. package/dist/esm/audio/filters/VocoderFilter.js.map +1 -1
  63. package/dist/esm/audio/filters/WorkletFilter.d.ts +2 -0
  64. package/dist/esm/audio/filters/WorkletFilter.js +10 -5
  65. package/dist/esm/audio/filters/WorkletFilter.js.map +1 -1
  66. package/dist/esm/audio/index.d.ts +15 -10
  67. package/dist/esm/audio/worklet/registerWorklet.d.ts +1 -1
  68. package/dist/esm/audio/worklet/registerWorklet.js +2 -2
  69. package/dist/esm/audio/worklet/registerWorklet.js.map +1 -1
  70. package/dist/esm/audio/worklets/beat-detector.worklet.d.ts +1 -0
  71. package/dist/esm/audio/worklets/beat-detector.worklet.js +647 -0
  72. package/dist/esm/audio/worklets/beat-detector.worklet.js.map +1 -0
  73. package/dist/esm/audio/worklets/granular.worklet.d.ts +1 -0
  74. package/dist/esm/audio/worklets/granular.worklet.js +89 -0
  75. package/dist/esm/audio/worklets/granular.worklet.js.map +1 -0
  76. package/dist/esm/audio/worklets/pitch-shift.worklet.d.ts +1 -0
  77. package/dist/esm/audio/worklets/pitch-shift.worklet.js +74 -0
  78. package/dist/esm/audio/worklets/pitch-shift.worklet.js.map +1 -0
  79. package/dist/esm/audio/worklets/vocoder.worklet.d.ts +1 -0
  80. package/dist/esm/audio/worklets/vocoder.worklet.js +92 -0
  81. package/dist/esm/audio/worklets/vocoder.worklet.js.map +1 -0
  82. package/dist/esm/core/Application.d.ts +62 -24
  83. package/dist/esm/core/Application.js +116 -40
  84. package/dist/esm/core/Application.js.map +1 -1
  85. package/dist/esm/core/Color.d.ts +0 -8
  86. package/dist/esm/core/Color.js +0 -24
  87. package/dist/esm/core/Color.js.map +1 -1
  88. package/dist/esm/core/Scene.d.ts +32 -72
  89. package/dist/esm/core/Scene.js +56 -36
  90. package/dist/esm/core/Scene.js.map +1 -1
  91. package/dist/esm/core/SceneManager.d.ts +11 -25
  92. package/dist/esm/core/SceneManager.js +37 -100
  93. package/dist/esm/core/SceneManager.js.map +1 -1
  94. package/dist/esm/core/SceneNode.d.ts +28 -14
  95. package/dist/esm/core/SceneNode.js +66 -33
  96. package/dist/esm/core/SceneNode.js.map +1 -1
  97. package/dist/esm/core/Signal.d.ts +24 -28
  98. package/dist/esm/core/Signal.js +64 -50
  99. package/dist/esm/core/Signal.js.map +1 -1
  100. package/dist/esm/core/Timer.d.ts +1 -0
  101. package/dist/esm/core/Timer.js +3 -0
  102. package/dist/esm/core/Timer.js.map +1 -1
  103. package/dist/esm/debug/BoundingBoxesLayer.js +1 -1
  104. package/dist/esm/debug/BoundingBoxesLayer.js.map +1 -1
  105. package/dist/esm/debug/HitTestLayer.js +1 -1
  106. package/dist/esm/debug/HitTestLayer.js.map +1 -1
  107. package/dist/esm/debug/PerformanceLayer.js +1 -2
  108. package/dist/esm/debug/PerformanceLayer.js.map +1 -1
  109. package/dist/esm/debug/PointerStackLayer.js +1 -2
  110. package/dist/esm/debug/PointerStackLayer.js.map +1 -1
  111. package/dist/esm/debug/RenderPassInspectorLayer.js +1 -2
  112. package/dist/esm/debug/RenderPassInspectorLayer.js.map +1 -1
  113. package/dist/esm/index.js +23 -7
  114. package/dist/esm/index.js.map +1 -1
  115. package/dist/esm/input/InputManager.d.ts +1 -0
  116. package/dist/esm/input/InputManager.js +30 -3
  117. package/dist/esm/input/InputManager.js.map +1 -1
  118. package/dist/esm/input/InteractionManager.d.ts +5 -2
  119. package/dist/esm/input/InteractionManager.js +29 -18
  120. package/dist/esm/input/InteractionManager.js.map +1 -1
  121. package/dist/esm/input/Pointer.js +3 -2
  122. package/dist/esm/input/Pointer.js.map +1 -1
  123. package/dist/esm/input/internal/interactionManagerRegistry.d.ts +9 -0
  124. package/dist/esm/input/internal/interactionManagerRegistry.js +10 -0
  125. package/dist/esm/input/internal/interactionManagerRegistry.js.map +1 -0
  126. package/dist/esm/math/AbstractVector.d.ts +1 -7
  127. package/dist/esm/math/AbstractVector.js +6 -20
  128. package/dist/esm/math/AbstractVector.js.map +1 -1
  129. package/dist/esm/math/Circle.js +0 -2
  130. package/dist/esm/math/Circle.js.map +1 -1
  131. package/dist/esm/math/Collision.d.ts +9 -3
  132. package/dist/esm/math/Ellipse.d.ts +2 -5
  133. package/dist/esm/math/Ellipse.js +10 -7
  134. package/dist/esm/math/Ellipse.js.map +1 -1
  135. package/dist/esm/math/ObservableVector.d.ts +1 -1
  136. package/dist/esm/math/ObservableVector.js +3 -3
  137. package/dist/esm/math/ObservableVector.js.map +1 -1
  138. package/dist/esm/math/Polygon.d.ts +0 -2
  139. package/dist/esm/math/Polygon.js +1 -9
  140. package/dist/esm/math/Polygon.js.map +1 -1
  141. package/dist/esm/math/Rectangle.js +0 -2
  142. package/dist/esm/math/Rectangle.js.map +1 -1
  143. package/dist/esm/math/collision-detection.d.ts +19 -4
  144. package/dist/esm/math/collision-detection.js +61 -4
  145. package/dist/esm/math/collision-detection.js.map +1 -1
  146. package/dist/esm/math/swept-collision.d.ts +16 -12
  147. package/dist/esm/math/swept-collision.js +109 -19
  148. package/dist/esm/math/swept-collision.js.map +1 -1
  149. package/dist/esm/particles/ParticleSystem.js +1 -1
  150. package/dist/esm/particles/ParticleSystem.js.map +1 -1
  151. package/dist/esm/particles/index.d.ts +1 -0
  152. package/dist/esm/rendering/CallbackRenderPass.d.ts +1 -0
  153. package/dist/esm/rendering/CallbackRenderPass.js +1 -0
  154. package/dist/esm/rendering/CallbackRenderPass.js.map +1 -1
  155. package/dist/esm/rendering/Container.d.ts +2 -1
  156. package/dist/esm/rendering/Container.js +17 -16
  157. package/dist/esm/rendering/Container.js.map +1 -1
  158. package/dist/esm/rendering/RenderBackend.d.ts +1 -0
  159. package/dist/esm/rendering/RenderNode.d.ts +1 -3
  160. package/dist/esm/rendering/RenderNode.js +12 -19
  161. package/dist/esm/rendering/RenderNode.js.map +1 -1
  162. package/dist/esm/rendering/RenderPass.d.ts +1 -0
  163. package/dist/esm/rendering/RenderStats.d.ts +9 -0
  164. package/dist/esm/rendering/RenderStats.js +2 -0
  165. package/dist/esm/rendering/RenderStats.js.map +1 -1
  166. package/dist/esm/rendering/RendererRegistry.d.ts +1 -0
  167. package/dist/esm/rendering/RendererRegistry.js +1 -0
  168. package/dist/esm/rendering/RendererRegistry.js.map +1 -1
  169. package/dist/esm/rendering/View.d.ts +23 -0
  170. package/dist/esm/rendering/View.js +42 -0
  171. package/dist/esm/rendering/View.js.map +1 -1
  172. package/dist/esm/rendering/index.d.ts +89 -59
  173. package/dist/esm/rendering/mesh/Mesh.js +1 -1
  174. package/dist/esm/rendering/mesh/Mesh.js.map +1 -1
  175. package/dist/esm/rendering/mesh/MeshShader.d.ts +1 -0
  176. package/dist/esm/rendering/mesh/MeshShader.js +1 -0
  177. package/dist/esm/rendering/mesh/MeshShader.js.map +1 -1
  178. package/dist/esm/rendering/shader/Shader.d.ts +1 -0
  179. package/dist/esm/rendering/shader/Shader.js +1 -0
  180. package/dist/esm/rendering/shader/Shader.js.map +1 -1
  181. package/dist/esm/rendering/shader/ShaderUniform.d.ts +1 -0
  182. package/dist/esm/rendering/shader/ShaderUniform.js +1 -0
  183. package/dist/esm/rendering/shader/ShaderUniform.js.map +1 -1
  184. package/dist/esm/rendering/sprite/Sprite.d.ts +3 -2
  185. package/dist/esm/rendering/sprite/Sprite.js +15 -13
  186. package/dist/esm/rendering/sprite/Sprite.js.map +1 -1
  187. package/dist/esm/rendering/text/AbstractText.d.ts +36 -0
  188. package/dist/esm/rendering/text/AbstractText.js +49 -0
  189. package/dist/esm/rendering/text/AbstractText.js.map +1 -0
  190. package/dist/esm/rendering/text/BitmapText.d.ts +97 -0
  191. package/dist/esm/rendering/text/BitmapText.js +220 -0
  192. package/dist/esm/rendering/text/BitmapText.js.map +1 -0
  193. package/dist/esm/rendering/text/BmFont.d.ts +50 -0
  194. package/dist/esm/rendering/text/BmFont.js +24 -0
  195. package/dist/esm/rendering/text/BmFont.js.map +1 -0
  196. package/dist/esm/rendering/text/GlyphAtlas.d.ts +104 -0
  197. package/dist/esm/rendering/text/GlyphAtlas.js +347 -0
  198. package/dist/esm/rendering/text/GlyphAtlas.js.map +1 -0
  199. package/dist/esm/rendering/text/GlyphAtlasPool.d.ts +40 -0
  200. package/dist/esm/rendering/text/GlyphAtlasPool.js +67 -0
  201. package/dist/esm/rendering/text/GlyphAtlasPool.js.map +1 -0
  202. package/dist/esm/rendering/text/GlyphSdf.d.ts +92 -0
  203. package/dist/esm/rendering/text/GlyphSdf.js +220 -0
  204. package/dist/esm/rendering/text/GlyphSdf.js.map +1 -0
  205. package/dist/esm/rendering/text/HTMLText.d.ts +107 -0
  206. package/dist/esm/rendering/text/HTMLText.js +284 -0
  207. package/dist/esm/rendering/text/HTMLText.js.map +1 -0
  208. package/dist/esm/rendering/text/LayoutOptions.d.ts +30 -0
  209. package/dist/esm/rendering/text/Text.d.ts +89 -20
  210. package/dist/esm/rendering/text/Text.js +176 -101
  211. package/dist/esm/rendering/text/Text.js.map +1 -1
  212. package/dist/esm/rendering/text/TextLayout.d.ts +20 -8
  213. package/dist/esm/rendering/text/TextLayout.js +234 -25
  214. package/dist/esm/rendering/text/TextLayout.js.map +1 -1
  215. package/dist/esm/rendering/text/TextStyle.d.ts +154 -87
  216. package/dist/esm/rendering/text/TextStyle.js +257 -203
  217. package/dist/esm/rendering/text/TextStyle.js.map +1 -1
  218. package/dist/esm/rendering/text/types.d.ts +73 -13
  219. package/dist/esm/rendering/texture/Texture.d.ts +1 -0
  220. package/dist/esm/rendering/texture/Texture.js +1 -0
  221. package/dist/esm/rendering/texture/Texture.js.map +1 -1
  222. package/dist/esm/rendering/types.d.ts +3 -1
  223. package/dist/esm/rendering/types.js +2 -0
  224. package/dist/esm/rendering/types.js.map +1 -1
  225. package/dist/esm/rendering/video/Video.d.ts +2 -1
  226. package/dist/esm/rendering/video/Video.js +9 -5
  227. package/dist/esm/rendering/video/Video.js.map +1 -1
  228. package/dist/esm/rendering/webgl2/WebGl2Backend.js +41 -5
  229. package/dist/esm/rendering/webgl2/WebGl2Backend.js.map +1 -1
  230. package/dist/esm/rendering/webgl2/WebGl2MeshRenderer.js +4 -4
  231. package/dist/esm/rendering/webgl2/WebGl2MeshRenderer.js.map +1 -1
  232. package/dist/esm/rendering/webgl2/WebGl2TextRenderer.d.ts +56 -0
  233. package/dist/esm/rendering/webgl2/WebGl2TextRenderer.js +482 -0
  234. package/dist/esm/rendering/webgl2/WebGl2TextRenderer.js.map +1 -0
  235. package/dist/esm/rendering/webgl2/glsl/text-color.frag.js +4 -0
  236. package/dist/esm/rendering/webgl2/glsl/text-color.frag.js.map +1 -0
  237. package/dist/esm/rendering/webgl2/glsl/text-msdf.frag.js +4 -0
  238. package/dist/esm/rendering/webgl2/glsl/text-msdf.frag.js.map +1 -0
  239. package/dist/esm/rendering/webgl2/glsl/text-sdf.frag.js +4 -0
  240. package/dist/esm/rendering/webgl2/glsl/text-sdf.frag.js.map +1 -0
  241. package/dist/esm/rendering/webgl2/glsl/text.vert.js +4 -0
  242. package/dist/esm/rendering/webgl2/glsl/text.vert.js.map +1 -0
  243. package/dist/esm/rendering/webgpu/WebGpuBackend.js +16 -8
  244. package/dist/esm/rendering/webgpu/WebGpuBackend.js.map +1 -1
  245. package/dist/esm/rendering/webgpu/WebGpuBlendState.js +26 -0
  246. package/dist/esm/rendering/webgpu/WebGpuBlendState.js.map +1 -1
  247. package/dist/esm/rendering/webgpu/WebGpuMeshRenderer.d.ts +2 -2
  248. package/dist/esm/rendering/webgpu/WebGpuMeshRenderer.js +23 -15
  249. package/dist/esm/rendering/webgpu/WebGpuMeshRenderer.js.map +1 -1
  250. package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.js +9 -1
  251. package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.js.map +1 -1
  252. package/dist/esm/rendering/webgpu/WebGpuTextRenderer.d.ts +70 -0
  253. package/dist/esm/rendering/webgpu/WebGpuTextRenderer.js +773 -0
  254. package/dist/esm/rendering/webgpu/WebGpuTextRenderer.js.map +1 -0
  255. package/dist/esm/rendering/webgpu/compute/WebGpuComputePipeline.js +96 -0
  256. package/dist/esm/rendering/webgpu/compute/WebGpuComputePipeline.js.map +1 -0
  257. package/dist/esm/rendering/webgpu/compute/WebGpuStorageBuffer.js +68 -0
  258. package/dist/esm/rendering/webgpu/compute/WebGpuStorageBuffer.js.map +1 -0
  259. package/dist/esm/resources/Asset.d.ts +23 -0
  260. package/dist/esm/resources/Asset.js +23 -0
  261. package/dist/esm/resources/Asset.js.map +1 -0
  262. package/dist/esm/resources/AssetDefinitions.d.ts +137 -0
  263. package/dist/esm/resources/Assets.d.ts +35 -0
  264. package/dist/esm/resources/Assets.js +32 -0
  265. package/dist/esm/resources/Assets.js.map +1 -0
  266. package/dist/esm/resources/IndexedDbDatabase.js +17 -1
  267. package/dist/esm/resources/IndexedDbDatabase.js.map +1 -1
  268. package/dist/esm/resources/IndexedDbStore.js +17 -1
  269. package/dist/esm/resources/IndexedDbStore.js.map +1 -1
  270. package/dist/esm/resources/Loader.d.ts +244 -18
  271. package/dist/esm/resources/Loader.js +456 -50
  272. package/dist/esm/resources/Loader.js.map +1 -1
  273. package/dist/esm/resources/LoadingQueue.d.ts +28 -0
  274. package/dist/esm/resources/LoadingQueue.js +59 -0
  275. package/dist/esm/resources/LoadingQueue.js.map +1 -0
  276. package/dist/esm/resources/factories/BmFontFactory.d.ts +25 -0
  277. package/dist/esm/resources/factories/BmFontFactory.js +96 -0
  278. package/dist/esm/resources/factories/BmFontFactory.js.map +1 -0
  279. package/dist/esm/resources/factories/CsvFactory.d.ts +35 -0
  280. package/dist/esm/resources/factories/CsvFactory.js +87 -0
  281. package/dist/esm/resources/factories/CsvFactory.js.map +1 -0
  282. package/dist/esm/resources/factories/MusicFactory.d.ts +8 -2
  283. package/dist/esm/resources/factories/MusicFactory.js +25 -14
  284. package/dist/esm/resources/factories/MusicFactory.js.map +1 -1
  285. package/dist/esm/resources/factories/SoundFactory.d.ts +2 -2
  286. package/dist/esm/resources/factories/SoundFactory.js.map +1 -1
  287. package/dist/esm/resources/factories/SubtitleFactory.d.ts +28 -0
  288. package/dist/esm/resources/factories/SubtitleFactory.js +203 -0
  289. package/dist/esm/resources/factories/SubtitleFactory.js.map +1 -0
  290. package/dist/esm/resources/factories/SvgFactory.d.ts +18 -1
  291. package/dist/esm/resources/factories/SvgFactory.js +21 -2
  292. package/dist/esm/resources/factories/SvgFactory.js.map +1 -1
  293. package/dist/esm/resources/factories/VideoFactory.d.ts +8 -2
  294. package/dist/esm/resources/factories/VideoFactory.js +27 -20
  295. package/dist/esm/resources/factories/VideoFactory.js.map +1 -1
  296. package/dist/esm/resources/factories/XmlFactory.d.ts +24 -0
  297. package/dist/esm/resources/factories/XmlFactory.js +37 -0
  298. package/dist/esm/resources/factories/XmlFactory.js.map +1 -0
  299. package/dist/esm/resources/index.d.ts +8 -1
  300. package/dist/esm/resources/tokens.d.ts +49 -3
  301. package/dist/esm/resources/tokens.js +50 -4
  302. package/dist/esm/resources/tokens.js.map +1 -1
  303. package/dist/exo.esm.js +6635 -2550
  304. package/dist/exo.esm.js.map +1 -1
  305. package/package.json +19 -6
  306. package/dist/esm/input/interaction-hooks.d.ts +0 -34
  307. package/dist/esm/input/interaction-hooks.js +0 -35
  308. package/dist/esm/input/interaction-hooks.js.map +0 -1
  309. package/dist/esm/rendering/text/DynamicGlyphAtlas.d.ts +0 -33
  310. package/dist/esm/rendering/text/DynamicGlyphAtlas.js +0 -134
  311. package/dist/esm/rendering/text/DynamicGlyphAtlas.js.map +0 -1
  312. package/dist/esm/rendering/text/atlas-singleton.d.ts +0 -7
  313. package/dist/esm/rendering/text/atlas-singleton.js +0 -17
  314. package/dist/esm/rendering/text/atlas-singleton.js.map +0 -1
  315. package/dist/esm/resources/factories/VttFactory.d.ts +0 -24
  316. package/dist/esm/resources/factories/VttFactory.js +0 -158
  317. package/dist/esm/resources/factories/VttFactory.js.map +0 -1
@@ -0,0 +1,347 @@
1
+ import { Signal } from '../../core/Signal.js';
2
+ import { DataTexture } from '../texture/DataTexture.js';
3
+ import { Texture } from '../texture/Texture.js';
4
+ import { GlyphSdf } from './GlyphSdf.js';
5
+
6
+ /**
7
+ * SDF buffer radius in pixels — the maximum distance outside a glyph that the
8
+ * SDF field encodes. Determines the maximum usable outline/shadow reach.
9
+ * Exported so applications can import this constant when computing shader uniforms.
10
+ */
11
+ // eslint-disable-next-line @typescript-eslint/naming-convention
12
+ const SDF_RADIUS = 8;
13
+ const glyphPadding = 2;
14
+ class ShelfPacker {
15
+ _shelves = [];
16
+ _width;
17
+ _height;
18
+ constructor(width, height) {
19
+ this._width = width;
20
+ this._height = height;
21
+ }
22
+ insert(width, height) {
23
+ for (const shelf of this._shelves) {
24
+ if (shelf.height >= height && shelf.cursorX + width <= this._width) {
25
+ const x = shelf.cursorX;
26
+ shelf.cursorX += width;
27
+ return { x, y: shelf.y };
28
+ }
29
+ }
30
+ const last = this._shelves[this._shelves.length - 1];
31
+ const bottomY = last === undefined ? 0 : last.y + last.height;
32
+ if (bottomY + height > this._height) {
33
+ return null;
34
+ }
35
+ this._shelves.push({ y: bottomY, height, cursorX: width });
36
+ return { x: 0, y: bottomY };
37
+ }
38
+ reset() {
39
+ this._shelves.length = 0;
40
+ }
41
+ }
42
+ function makeCtx(width, height) {
43
+ if (typeof OffscreenCanvas !== 'undefined') {
44
+ const canvas = new OffscreenCanvas(width, height);
45
+ const ctx = canvas.getContext('2d');
46
+ if (!ctx)
47
+ throw new Error('GlyphAtlas: could not obtain OffscreenCanvas 2D context.');
48
+ return { canvas, ctx };
49
+ }
50
+ const canvas = document.createElement('canvas');
51
+ canvas.width = width;
52
+ canvas.height = height;
53
+ const ctx = canvas.getContext('2d');
54
+ if (!ctx)
55
+ throw new Error('GlyphAtlas: could not obtain canvas 2D context.');
56
+ return { canvas, ctx };
57
+ }
58
+ /**
59
+ * A single texture page within a {@link GlyphAtlas}. Glyphs are packed into
60
+ * the page using a shelf-bin algorithm.
61
+ *
62
+ * In `'sdf'` mode the page owns a `DataTexture` (`r8`) populated by tiny-sdf
63
+ * output. In `'color'` mode a Canvas 2D context preserves full glyph colours
64
+ * for emoji.
65
+ * @advanced
66
+ */
67
+ class AtlasPage {
68
+ texture;
69
+ index;
70
+ mode;
71
+ _packer;
72
+ _width;
73
+ _height;
74
+ // SDF mode
75
+ _sdfBuffer = null;
76
+ _sdfTexture = null;
77
+ // Canvas mode
78
+ _ctx = null;
79
+ _colorGlyphs;
80
+ constructor(index, width, height, mode) {
81
+ this.index = index;
82
+ this.mode = mode;
83
+ this._width = width;
84
+ this._height = height;
85
+ this._colorGlyphs = mode === 'color';
86
+ this._packer = new ShelfPacker(width, height);
87
+ if (mode === 'sdf') {
88
+ this._sdfBuffer = new Uint8Array(width * height);
89
+ this._sdfTexture = new DataTexture({ width, height, format: 'r8', data: this._sdfBuffer });
90
+ this._sdfTexture.setSize(width, height);
91
+ this.texture = this._sdfTexture;
92
+ }
93
+ else {
94
+ const { canvas, ctx } = makeCtx(width, height);
95
+ this._ctx = ctx;
96
+ this.texture = new Texture(canvas);
97
+ this.texture.setSize(width, height);
98
+ }
99
+ }
100
+ insert(w, h) {
101
+ return this._packer.insert(w, h);
102
+ }
103
+ /**
104
+ * Copy R8 SDF data into the page buffer at the given slot origin.
105
+ * Only valid in `'sdf'` mode.
106
+ *
107
+ * `data` is a `Uint8ClampedArray` of single-channel SDF values as produced
108
+ * by {@link GlyphSdf.draw}. Each value is one byte (0 = far outside the
109
+ * glyph, 255 = deep inside, ~128 = glyph edge).
110
+ */
111
+ writeSdf(data, slotX, slotY, srcW, srcH) {
112
+ const buf = this._sdfBuffer;
113
+ const dstW = this._width;
114
+ for (let row = 0; row < srcH; row++) {
115
+ const srcOff = row * srcW;
116
+ const dstOff = (slotY + row) * dstW + slotX;
117
+ buf.set(data.subarray(srcOff, srcOff + srcW), dstOff);
118
+ }
119
+ this._sdfTexture.commitRect(slotX, slotY, srcW, srcH);
120
+ }
121
+ measureGlyph(char, font) {
122
+ if (this._ctx !== null) {
123
+ this._ctx.font = font;
124
+ this._ctx.textBaseline = 'alphabetic';
125
+ return this._ctx.measureText(char);
126
+ }
127
+ const c = typeof OffscreenCanvas !== 'undefined' ? new OffscreenCanvas(1, 1) : document.createElement('canvas');
128
+ const ctx = c.getContext('2d');
129
+ ctx.font = font;
130
+ ctx.textBaseline = 'alphabetic';
131
+ return ctx.measureText(char);
132
+ }
133
+ /** Rasterize a white glyph into the canvas at the given padded slot origin (canvas mode only). */
134
+ rasterize(char, slotX, slotY, ascent, bbLeft, font) {
135
+ const ctx = this._ctx;
136
+ ctx.font = font;
137
+ ctx.textBaseline = 'alphabetic';
138
+ if (!this._colorGlyphs) {
139
+ ctx.fillStyle = '#ffffff';
140
+ }
141
+ ctx.fillText(char, slotX + glyphPadding + bbLeft, slotY + glyphPadding + ascent);
142
+ }
143
+ uploadDirtyRegion() {
144
+ if (this._sdfTexture !== null) {
145
+ this._sdfTexture.commit();
146
+ }
147
+ else {
148
+ this.texture.updateSource();
149
+ }
150
+ }
151
+ reset() {
152
+ this._packer.reset();
153
+ if (this._sdfBuffer !== null && this._sdfTexture !== null) {
154
+ this._sdfBuffer.fill(0);
155
+ this._sdfTexture.commit();
156
+ }
157
+ else if (this._ctx !== null) {
158
+ this._ctx.clearRect(0, 0, this._width, this._height);
159
+ this.texture.updateSource();
160
+ }
161
+ }
162
+ }
163
+ // ── GlyphAtlas ───────────────────────────────────────────────────────────────
164
+ /**
165
+ * A per-font-variant glyph atlas with automatic multi-page growth.
166
+ *
167
+ * In `'sdf'` mode (default) each atlas page is a single-channel R8
168
+ * `DataTexture` populated by {@link GlyphSdf}. One `GlyphSdf` instance is kept per
169
+ * font size so the atlas can mix sizes efficiently.
170
+ *
171
+ * In `'color'` mode pages are RGBA canvas textures that preserve full glyph
172
+ * colour data for emoji and colour fonts.
173
+ * @advanced
174
+ */
175
+ class GlyphAtlas {
176
+ _pages = [];
177
+ _cache = new Map();
178
+ _kerningCache = new Map();
179
+ _pageSize;
180
+ _family;
181
+ _fontStyle;
182
+ _fontWeight;
183
+ _mode;
184
+ _sdfRadius;
185
+ /**
186
+ * Dispatched whenever a new atlas page is allocated.
187
+ *
188
+ * Listen here to detect unexpected atlas growth (e.g. many unique CJK glyphs
189
+ * or an oversized font size). The payload is the zero-based page index.
190
+ *
191
+ * ```ts
192
+ * const atlas = pool.getAtlas('Roboto', 'normal', '400');
193
+ * atlas.onPageAdded.on(idx => console.warn(`Atlas page ${idx} added`));
194
+ * ```
195
+ */
196
+ onPageAdded = new Signal();
197
+ /** {@link GlyphSdf} instances keyed by font size — only used in SDF mode. */
198
+ _sdfInstances = new Map();
199
+ constructor(family, fontStyle, fontWeight, pageSize = 1024, mode = 'sdf', sdfRadius = SDF_RADIUS) {
200
+ this._family = family;
201
+ this._fontStyle = fontStyle;
202
+ this._fontWeight = fontWeight;
203
+ this._pageSize = pageSize;
204
+ this._mode = mode;
205
+ this._sdfRadius = sdfRadius;
206
+ this._addPage();
207
+ }
208
+ get pages() {
209
+ return this._pages;
210
+ }
211
+ get mode() {
212
+ return this._mode;
213
+ }
214
+ getGlyph(char, size) {
215
+ const key = `${char}:${size}`;
216
+ const cached = this._cache.get(key);
217
+ if (cached !== undefined)
218
+ return cached;
219
+ return this._mode === 'sdf' ? this._rasterizeSdf(char, size, key) : this._rasterizeCanvas(char, size, key);
220
+ }
221
+ getKerning(prev, next, fontSize) {
222
+ const key = `${prev}${next}:${fontSize}`;
223
+ const cached = this._kerningCache.get(key);
224
+ if (cached !== undefined)
225
+ return cached;
226
+ const font = this._cssFont(fontSize);
227
+ const page = this._pages[0];
228
+ const pair = page.measureGlyph(prev + next, font).width;
229
+ const a = page.measureGlyph(prev, font).width;
230
+ const b = page.measureGlyph(next, font).width;
231
+ const kerning = pair - a - b;
232
+ this._kerningCache.set(key, kerning);
233
+ return kerning;
234
+ }
235
+ clear() {
236
+ this._cache.clear();
237
+ this._kerningCache.clear();
238
+ this._sdfInstances.clear();
239
+ for (const page of this._pages) {
240
+ page.reset();
241
+ }
242
+ this._pages = [];
243
+ this._addPage();
244
+ }
245
+ // ── Private ──────────────────────────────────────────────────────────────
246
+ _addPage() {
247
+ const index = this._pages.length;
248
+ const page = new AtlasPage(index, this._pageSize, this._pageSize, this._mode);
249
+ this._pages.push(page);
250
+ if (index > 0)
251
+ this.onPageAdded.dispatch(index);
252
+ return page;
253
+ }
254
+ _cssFont(size) {
255
+ const style = this._fontStyle !== 'normal' ? `${this._fontStyle} ` : '';
256
+ return `${style}${this._fontWeight} ${size}px ${this._family}`;
257
+ }
258
+ _getSdf(fontSize) {
259
+ let instance = this._sdfInstances.get(fontSize);
260
+ if (instance === undefined) {
261
+ instance = new GlyphSdf({
262
+ fontSize,
263
+ fontFamily: this._family,
264
+ fontWeight: this._fontWeight,
265
+ fontStyle: this._fontStyle,
266
+ buffer: this._sdfRadius,
267
+ radius: this._sdfRadius,
268
+ cutoff: 0.5,
269
+ });
270
+ this._sdfInstances.set(fontSize, instance);
271
+ }
272
+ return instance;
273
+ }
274
+ _rasterizeSdf(char, size, key) {
275
+ const result = this._getSdf(size).draw(char);
276
+ const { page, slot } = this._allocateSlot(result.width, result.height);
277
+ page.writeSdf(result.data, slot.x, slot.y, result.width, result.height);
278
+ const ps = this._pageSize;
279
+ const info = {
280
+ x: slot.x,
281
+ y: slot.y,
282
+ width: result.width,
283
+ height: result.height,
284
+ advance: result.glyphAdvance,
285
+ ascent: result.glyphTop + result.glyphHeight, // distance from tile top to glyph bottom
286
+ page: page.index,
287
+ uvLeft: slot.x / ps,
288
+ uvTop: slot.y / ps,
289
+ uvRight: (slot.x + result.width) / ps,
290
+ uvBottom: (slot.y + result.height) / ps,
291
+ // Shift the quad left/up by the SDF buffer so the glyph content aligns
292
+ // with the logical cursor position (bearing = −buffer on both axes).
293
+ xBearing: -result.glyphLeft,
294
+ yBearing: -result.glyphTop,
295
+ };
296
+ this._cache.set(key, info);
297
+ return info;
298
+ }
299
+ _rasterizeCanvas(char, size, key) {
300
+ const font = this._cssFont(size);
301
+ const metrics = this._pages[0].measureGlyph(char, font);
302
+ const ascent = Math.ceil(metrics.fontBoundingBoxAscent ?? metrics.actualBoundingBoxAscent ?? size * 0.8);
303
+ const descent = Math.ceil(metrics.fontBoundingBoxDescent ?? metrics.actualBoundingBoxDescent ?? size * 0.2);
304
+ const advance = metrics.width;
305
+ const bbLeft = metrics.actualBoundingBoxLeft ?? 0;
306
+ const bbRight = metrics.actualBoundingBoxRight ?? 0;
307
+ const glyphWidth = Math.max(1, Math.ceil(bbLeft + bbRight) || Math.ceil(advance));
308
+ const glyphHeight = Math.max(1, ascent + descent);
309
+ const slotW = glyphWidth + glyphPadding * 2;
310
+ const slotH = glyphHeight + glyphPadding * 2;
311
+ const { page, slot } = this._allocateSlot(slotW, slotH);
312
+ page.rasterize(char, slot.x, slot.y, ascent, bbLeft, font);
313
+ page.uploadDirtyRegion();
314
+ const ps = this._pageSize;
315
+ const info = {
316
+ x: slot.x,
317
+ y: slot.y,
318
+ width: glyphWidth,
319
+ height: glyphHeight,
320
+ advance,
321
+ ascent,
322
+ page: page.index,
323
+ uvLeft: slot.x / ps,
324
+ uvTop: slot.y / ps,
325
+ uvRight: (slot.x + slotW) / ps,
326
+ uvBottom: (slot.y + slotH) / ps,
327
+ };
328
+ this._cache.set(key, info);
329
+ return info;
330
+ }
331
+ _allocateSlot(w, h) {
332
+ for (const page of this._pages) {
333
+ const slot = page.insert(w, h);
334
+ if (slot !== null)
335
+ return { page, slot };
336
+ }
337
+ const newPage = this._addPage();
338
+ const slot = newPage.insert(w, h);
339
+ if (slot === null) {
340
+ throw new Error(`GlyphAtlas: glyph (${w}×${h}px) exceeds page size (${this._pageSize}px).`);
341
+ }
342
+ return { page: newPage, slot };
343
+ }
344
+ }
345
+
346
+ export { AtlasPage, GlyphAtlas, SDF_RADIUS };
347
+ //# sourceMappingURL=GlyphAtlas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GlyphAtlas.js","sources":["../../../../../src/rendering/text/GlyphAtlas.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import { type AtlasMode, GlyphAtlas } from './GlyphAtlas';
2
+ /**
3
+ * Manages one {@link GlyphAtlas} per font variant + mode combination.
4
+ *
5
+ * The pool key is `"${family}:${fontStyle}:${fontWeight}:${mode}"`. All text
6
+ * nodes sharing the same font variant and mode draw from the same atlas pages,
7
+ * so identical glyphs are rasterized only once regardless of which node first
8
+ * requests them.
9
+ *
10
+ * Use {@link getDefaultGlyphAtlasPool} to obtain the shared process-wide
11
+ * instance. Tests can mock that function to inject a fake pool.
12
+ * @advanced
13
+ */
14
+ export declare class GlyphAtlasPool {
15
+ private readonly _atlases;
16
+ private readonly _pageSize;
17
+ constructor(pageSize?: number);
18
+ /**
19
+ * Returns (or lazily creates) the atlas for the given font variant and mode.
20
+ * Defaults to `'sdf'` mode (R8 DataTexture, tiny-sdf rasterization).
21
+ *
22
+ * Nodes with different `sdfRadius` values get separate atlas instances so
23
+ * each can encode a different outline/shadow reach without conflict.
24
+ */
25
+ getAtlas(family: string, fontStyle: 'normal' | 'italic', fontWeight: string, mode?: AtlasMode, sdfRadius?: number): GlyphAtlas;
26
+ clearAll(): void;
27
+ }
28
+ /**
29
+ * Returns the shared process-wide {@link GlyphAtlasPool}, creating it lazily
30
+ * on first call. All {@link Text} instances use this pool by default.
31
+ */
32
+ export declare function getDefaultGlyphAtlasPool(): GlyphAtlasPool;
33
+ /**
34
+ * Override the default pool. Passing no argument (or `undefined`) causes the
35
+ * next {@link getDefaultGlyphAtlasPool} call to create a fresh instance.
36
+ *
37
+ * Intended for tests: call with a mock pool in `beforeEach` and with no
38
+ * argument in `afterEach` to restore default behaviour.
39
+ */
40
+ export declare function resetDefaultGlyphAtlasPool(pool?: GlyphAtlasPool): void;
@@ -0,0 +1,67 @@
1
+ import { SDF_RADIUS, GlyphAtlas } from './GlyphAtlas.js';
2
+
3
+ /**
4
+ * Manages one {@link GlyphAtlas} per font variant + mode combination.
5
+ *
6
+ * The pool key is `"${family}:${fontStyle}:${fontWeight}:${mode}"`. All text
7
+ * nodes sharing the same font variant and mode draw from the same atlas pages,
8
+ * so identical glyphs are rasterized only once regardless of which node first
9
+ * requests them.
10
+ *
11
+ * Use {@link getDefaultGlyphAtlasPool} to obtain the shared process-wide
12
+ * instance. Tests can mock that function to inject a fake pool.
13
+ * @advanced
14
+ */
15
+ class GlyphAtlasPool {
16
+ _atlases = new Map();
17
+ _pageSize;
18
+ constructor(pageSize = 1024) {
19
+ this._pageSize = pageSize;
20
+ }
21
+ /**
22
+ * Returns (or lazily creates) the atlas for the given font variant and mode.
23
+ * Defaults to `'sdf'` mode (R8 DataTexture, tiny-sdf rasterization).
24
+ *
25
+ * Nodes with different `sdfRadius` values get separate atlas instances so
26
+ * each can encode a different outline/shadow reach without conflict.
27
+ */
28
+ getAtlas(family, fontStyle, fontWeight, mode = 'sdf', sdfRadius = SDF_RADIUS) {
29
+ const key = `${family}:${fontStyle}:${fontWeight}:${mode}:${sdfRadius}`;
30
+ let atlas = this._atlases.get(key);
31
+ if (atlas === undefined) {
32
+ atlas = new GlyphAtlas(family, fontStyle, fontWeight, this._pageSize, mode, sdfRadius);
33
+ this._atlases.set(key, atlas);
34
+ }
35
+ return atlas;
36
+ }
37
+ clearAll() {
38
+ for (const atlas of this._atlases.values()) {
39
+ atlas.clear();
40
+ }
41
+ }
42
+ }
43
+ // ── Module-level default pool ────────────────────────────────────────────────
44
+ let _defaultPool = null;
45
+ /**
46
+ * Returns the shared process-wide {@link GlyphAtlasPool}, creating it lazily
47
+ * on first call. All {@link Text} instances use this pool by default.
48
+ */
49
+ function getDefaultGlyphAtlasPool() {
50
+ if (_defaultPool === null) {
51
+ _defaultPool = new GlyphAtlasPool();
52
+ }
53
+ return _defaultPool;
54
+ }
55
+ /**
56
+ * Override the default pool. Passing no argument (or `undefined`) causes the
57
+ * next {@link getDefaultGlyphAtlasPool} call to create a fresh instance.
58
+ *
59
+ * Intended for tests: call with a mock pool in `beforeEach` and with no
60
+ * argument in `afterEach` to restore default behaviour.
61
+ */
62
+ function resetDefaultGlyphAtlasPool(pool) {
63
+ _defaultPool = pool ?? null;
64
+ }
65
+
66
+ export { GlyphAtlasPool, getDefaultGlyphAtlasPool, resetDefaultGlyphAtlasPool };
67
+ //# sourceMappingURL=GlyphAtlasPool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GlyphAtlasPool.js","sources":["../../../../../src/rendering/text/GlyphAtlasPool.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAEA;;;;;;;;;;;AAWG;MACU,cAAc,CAAA;AACR,IAAA,QAAQ,GAAG,IAAI,GAAG,EAAsB;AACxC,IAAA,SAAS;IAE1B,WAAA,CAAmB,QAAQ,GAAG,IAAI,EAAA;AAChC,QAAA,IAAI,CAAC,SAAS,GAAG,QAAQ;IAC3B;AAEA;;;;;;AAMG;AACI,IAAA,QAAQ,CAAC,MAAc,EAAE,SAA8B,EAAE,UAAkB,EAAE,IAAA,GAAkB,KAAK,EAAE,SAAS,GAAG,UAAU,EAAA;AACjI,QAAA,MAAM,GAAG,GAAG,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA,EAAI,UAAU,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,EAAI,SAAS,EAAE;QACvE,IAAI,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;AAElC,QAAA,IAAI,KAAK,KAAK,SAAS,EAAE;AACvB,YAAA,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,SAAS,CAAC;YACtF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC;QAC/B;AAEA,QAAA,OAAO,KAAK;IACd;IAEO,QAAQ,GAAA;QACb,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE;YAC1C,KAAK,CAAC,KAAK,EAAE;QACf;IACF;AACD;AAED;AAEA,IAAI,YAAY,GAA0B,IAAI;AAE9C;;;AAGG;SACa,wBAAwB,GAAA;AACtC,IAAA,IAAI,YAAY,KAAK,IAAI,EAAE;AACzB,QAAA,YAAY,GAAG,IAAI,cAAc,EAAE;IACrC;AACA,IAAA,OAAO,YAAY;AACrB;AAEA;;;;;;AAMG;AACG,SAAU,0BAA0B,CAAC,IAAqB,EAAA;AAC9D,IAAA,YAAY,GAAG,IAAI,IAAI,IAAI;AAC7B;;;;"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Signed Distance Field generator for individual glyphs.
3
+ *
4
+ * Uses the Canvas 2D API to rasterize each character, then applies a 2D
5
+ * Euclidean Distance Transform (Felzenszwalb & Huttenlocher, 2012) to
6
+ * produce a single-channel R8 SDF buffer.
7
+ *
8
+ * Output encoding: 128/255 ≈ 0.502 is the glyph edge. Values above 0.5
9
+ * are inside the glyph, values below 0.5 are outside. The range encoded
10
+ * by the SDF extends `radius` pixels beyond the geometric edge.
11
+ *
12
+ * Compatible with `cutoff = 0.5` in the shader's `smoothstep(0.5 − soft, 0.5 + soft, sd)`.
13
+ */
14
+ export interface GlyphSdfOptions {
15
+ /** Font size in pixels used for rasterization. */
16
+ fontSize: number;
17
+ /** CSS font-family string. */
18
+ fontFamily: string;
19
+ fontWeight?: string;
20
+ fontStyle?: string;
21
+ /**
22
+ * Pixels of SDF padding added around the glyph bounding box on each side.
23
+ * Determines the maximum reach of outline and shadow effects.
24
+ * Defaults to 8.
25
+ */
26
+ buffer?: number;
27
+ /**
28
+ * EDT search radius. Values above `radius` pixels from the edge are
29
+ * clamped. Must be ≥ `buffer` for full-range SDF coverage.
30
+ * Defaults to `buffer`.
31
+ */
32
+ radius?: number;
33
+ /**
34
+ * SDF normalisation cutoff (0..1). Value at the glyph edge = 1 − cutoff.
35
+ * Use `0.5` so the shader's threshold of 0.5 matches the edge exactly.
36
+ * Defaults to 0.5.
37
+ */
38
+ cutoff?: number;
39
+ }
40
+ /** Result of {@link GlyphSdf.draw}. */
41
+ export interface GlyphSdfResult {
42
+ /** R8 SDF values: 0 = far outside, 255 = deep inside, ~128 = edge. */
43
+ data: Uint8ClampedArray;
44
+ /** Tile width in pixels (= glyphWidth + 2 × buffer). */
45
+ width: number;
46
+ /** Tile height in pixels (= glyphHeight + 2 × buffer). */
47
+ height: number;
48
+ /** Actual glyph width in pixels (bounding box, no padding). */
49
+ glyphWidth: number;
50
+ /** Actual glyph height in pixels (ascent + descent, no padding). */
51
+ glyphHeight: number;
52
+ /** Pixels from tile top to glyph top = buffer. */
53
+ glyphTop: number;
54
+ /** Pixels from tile left to glyph left = buffer. */
55
+ glyphLeft: number;
56
+ /** Logical horizontal advance for cursor movement. */
57
+ glyphAdvance: number;
58
+ }
59
+ /**
60
+ * SDF generator for a single font variant.
61
+ *
62
+ * Maintains an internal canvas that is resized per glyph and a set of reusable
63
+ * EDT working arrays that grow on demand (no per-call allocations once the
64
+ * largest glyph has been processed).
65
+ * @advanced
66
+ */
67
+ export declare class GlyphSdf {
68
+ private readonly _buffer;
69
+ private readonly _radius;
70
+ private readonly _cutoff;
71
+ private readonly _font;
72
+ private _canvasW;
73
+ private _canvasH;
74
+ private readonly _canvas;
75
+ private readonly _ctx;
76
+ private _gridOuter;
77
+ private _gridInner;
78
+ private _f;
79
+ private _d;
80
+ private _z;
81
+ private _v;
82
+ private _out;
83
+ constructor(options: GlyphSdfOptions);
84
+ /**
85
+ * Rasterize `char` and compute its SDF.
86
+ *
87
+ * Returns a new {@link GlyphSdfResult} each call. The `data` buffer is a
88
+ * fresh `Uint8ClampedArray`; the caller may hold a reference to it safely
89
+ * across subsequent `draw()` calls.
90
+ */
91
+ draw(char: string): GlyphSdfResult;
92
+ }