@bloopjs/toodle 0.0.100

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 (358) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +44 -0
  3. package/dist/Toodle.d.ts +304 -0
  4. package/dist/Toodle.d.ts.map +1 -0
  5. package/dist/colors/mod.d.ts +872 -0
  6. package/dist/colors/mod.d.ts.map +1 -0
  7. package/dist/coreTypes/Color.d.ts +7 -0
  8. package/dist/coreTypes/Color.d.ts.map +1 -0
  9. package/dist/coreTypes/Point.d.ts +8 -0
  10. package/dist/coreTypes/Point.d.ts.map +1 -0
  11. package/dist/coreTypes/Size.d.ts +5 -0
  12. package/dist/coreTypes/Size.d.ts.map +1 -0
  13. package/dist/coreTypes/Transform.d.ts +16 -0
  14. package/dist/coreTypes/Transform.d.ts.map +1 -0
  15. package/dist/coreTypes/Vec2.d.ts +8 -0
  16. package/dist/coreTypes/Vec2.d.ts.map +1 -0
  17. package/dist/coreTypes/mod.d.ts +6 -0
  18. package/dist/coreTypes/mod.d.ts.map +1 -0
  19. package/dist/docs/snippets/add-remove-children.d.ts +1 -0
  20. package/dist/docs/snippets/basic-quad.d.ts +1 -0
  21. package/dist/docs/snippets/filter-linear.d.ts +1 -0
  22. package/dist/docs/snippets/filter-nearest.d.ts +1 -0
  23. package/dist/docs/snippets/flipxy.d.ts +1 -0
  24. package/dist/docs/snippets/hello-text.d.ts +1 -0
  25. package/dist/docs/snippets/jumbo-textures.d.ts +1 -0
  26. package/dist/docs/snippets/layer.d.ts +1 -0
  27. package/dist/docs/snippets/layout-edges.d.ts +1 -0
  28. package/dist/docs/snippets/layout-screen-and-world-space.d.ts +1 -0
  29. package/dist/docs/snippets/postprocess.d.ts +1 -0
  30. package/dist/docs/snippets/quad-size-scale.d.ts +1 -0
  31. package/dist/docs/snippets/quickstart.d.ts +1 -0
  32. package/dist/docs/snippets/repeat-texture-loading.d.ts +1 -0
  33. package/dist/docs/snippets/screen-shaders.d.ts +1 -0
  34. package/dist/docs/snippets/shader-color-flash.d.ts +1 -0
  35. package/dist/docs/snippets/shader-default.d.ts +1 -0
  36. package/dist/docs/snippets/shader-fill.d.ts +1 -0
  37. package/dist/docs/snippets/shapes-line.d.ts +1 -0
  38. package/dist/docs/snippets/sprite-region.d.ts +1 -0
  39. package/dist/docs/snippets/text-alignment.d.ts +1 -0
  40. package/dist/docs/snippets/text-shrink-to-fit.d.ts +1 -0
  41. package/dist/docs/snippets/text-word-wrap.d.ts +1 -0
  42. package/dist/docs/snippets/texture-bundles-prebaked.d.ts +1 -0
  43. package/dist/docs/snippets/texture-bundles.d.ts +1 -0
  44. package/dist/docs/snippets/transforms.d.ts +1 -0
  45. package/dist/docs/snippets/transparent-cropping.d.ts +1 -0
  46. package/dist/examples/0-hello.d.ts +1 -0
  47. package/dist/examples/1-hello.d.ts +1 -0
  48. package/dist/examples/1-hello.d.ts.map +1 -0
  49. package/dist/examples/1-quad.d.ts +1 -0
  50. package/dist/examples/10-resize.d.ts +1 -0
  51. package/dist/examples/10-resize.d.ts.map +1 -0
  52. package/dist/examples/11-bundle-test.d.ts +1 -0
  53. package/dist/examples/11-bundle-test.d.ts.map +1 -0
  54. package/dist/examples/12-transparent-pixel-cropping.d.ts +1 -0
  55. package/dist/examples/12-transparent-pixel-cropping.d.ts.map +1 -0
  56. package/dist/examples/13-crop.d.ts +1 -0
  57. package/dist/examples/13-crop.d.ts.map +1 -0
  58. package/dist/examples/14-bundle-bench.d.ts +1 -0
  59. package/dist/examples/14-bundle-bench.d.ts.map +1 -0
  60. package/dist/examples/15-text-layer.d.ts +1 -0
  61. package/dist/examples/15-text-layer.d.ts.map +1 -0
  62. package/dist/examples/16-jumbo-texture.d.ts +1 -0
  63. package/dist/examples/16-jumbo-textures.d.ts +1 -0
  64. package/dist/examples/16-screen-shader.d.ts +1 -0
  65. package/dist/examples/16-screen-shader.d.ts.map +1 -0
  66. package/dist/examples/17-lighting.d.ts +1 -0
  67. package/dist/examples/17-lighting.d.ts.map +1 -0
  68. package/dist/examples/17-translations.d.ts +1 -0
  69. package/dist/examples/18-blur.d.ts +1 -0
  70. package/dist/examples/19-postprocess.d.ts +1 -0
  71. package/dist/examples/19-screenshader.d.ts +1 -0
  72. package/dist/examples/2-shapes.d.ts +1 -0
  73. package/dist/examples/2-shapes.d.ts.map +1 -0
  74. package/dist/examples/3-shader.d.ts +1 -0
  75. package/dist/examples/3-shader.d.ts.map +1 -0
  76. package/dist/examples/4-shader-bench.d.ts +1 -0
  77. package/dist/examples/4-shader-bench.d.ts.map +1 -0
  78. package/dist/examples/5-z.d.ts +1 -0
  79. package/dist/examples/5-z.d.ts.map +1 -0
  80. package/dist/examples/6-atlas.d.ts +1 -0
  81. package/dist/examples/6-atlas.d.ts.map +1 -0
  82. package/dist/examples/7-text.d.ts +1 -0
  83. package/dist/examples/7-text.d.ts.map +1 -0
  84. package/dist/examples/8-text-bench.d.ts +1 -0
  85. package/dist/examples/8-text-bench.d.ts.map +1 -0
  86. package/dist/examples/9-alignment.d.ts +1 -0
  87. package/dist/examples/9-alignment.d.ts.map +1 -0
  88. package/dist/examples/main.d.ts +1 -0
  89. package/dist/examples/main.d.ts.map +1 -0
  90. package/dist/examples/util.d.ts +82 -0
  91. package/dist/examples/util.d.ts.map +1 -0
  92. package/dist/limits.d.ts +23 -0
  93. package/dist/limits.d.ts.map +1 -0
  94. package/dist/math/angle.d.ts +13 -0
  95. package/dist/math/angle.d.ts.map +1 -0
  96. package/dist/math/matrix.d.ts +26 -0
  97. package/dist/math/matrix.d.ts.map +1 -0
  98. package/dist/math/mod.d.ts +3 -0
  99. package/dist/math/mod.d.ts.map +1 -0
  100. package/dist/mod.d.ts +17 -0
  101. package/dist/mod.d.ts.map +1 -0
  102. package/dist/mod.js +19665 -0
  103. package/dist/mod.js.map +41 -0
  104. package/dist/postprocess.d.ts +10 -0
  105. package/dist/postprocess.d.ts.map +1 -0
  106. package/dist/scene/Batcher.d.ts +20 -0
  107. package/dist/scene/Batcher.d.ts.map +1 -0
  108. package/dist/scene/Camera.d.ts +16 -0
  109. package/dist/scene/Camera.d.ts.map +1 -0
  110. package/dist/scene/JumboQuadNode.d.ts +29 -0
  111. package/dist/scene/JumboQuadNode.d.ts.map +1 -0
  112. package/dist/scene/QuadNode.d.ts +159 -0
  113. package/dist/scene/QuadNode.d.ts.map +1 -0
  114. package/dist/scene/RenderComponent.d.ts +11 -0
  115. package/dist/scene/RenderComponent.d.ts.map +1 -0
  116. package/dist/scene/SceneNode.d.ts +300 -0
  117. package/dist/scene/SceneNode.d.ts.map +1 -0
  118. package/dist/scene/mod.d.ts +5 -0
  119. package/dist/scene/mod.d.ts.map +1 -0
  120. package/dist/screen/mod.d.ts +2 -0
  121. package/dist/screen/mod.d.ts.map +1 -0
  122. package/dist/screen/resolution.d.ts +5 -0
  123. package/dist/screen/resolution.d.ts.map +1 -0
  124. package/dist/shaders/EngineUniform.d.ts +9 -0
  125. package/dist/shaders/EngineUniform.d.ts.map +1 -0
  126. package/dist/shaders/IShader.d.ts +15 -0
  127. package/dist/shaders/IShader.d.ts.map +1 -0
  128. package/dist/shaders/QuadShader.d.ts +18 -0
  129. package/dist/shaders/QuadShader.d.ts.map +1 -0
  130. package/dist/shaders/ShaderDescriptor.d.ts +7 -0
  131. package/dist/shaders/ShaderDescriptor.d.ts.map +1 -0
  132. package/dist/shaders/mod.d.ts +6 -0
  133. package/dist/shaders/mod.d.ts.map +1 -0
  134. package/dist/shaders/parser.d.ts +8 -0
  135. package/dist/shaders/parser.d.ts.map +1 -0
  136. package/dist/shaders/postprocess/blur.d.ts +3 -0
  137. package/dist/shaders/postprocess/blur.d.ts.map +1 -0
  138. package/dist/shaders/postprocess/mod.d.ts +17 -0
  139. package/dist/shaders/postprocess/mod.d.ts.map +1 -0
  140. package/dist/shaders/samplers.d.ts +3 -0
  141. package/dist/shaders/samplers.d.ts.map +1 -0
  142. package/dist/shaders/wgsl/example.wgsl.d.ts +3 -0
  143. package/dist/shaders/wgsl/example.wgsl.d.ts.map +1 -0
  144. package/dist/shaders/wgsl/hello.wgsl.d.ts +3 -0
  145. package/dist/shaders/wgsl/hello.wgsl.d.ts.map +1 -0
  146. package/dist/shaders/wgsl/helloInstanced.wgsl.d.ts +3 -0
  147. package/dist/shaders/wgsl/helloInstanced.wgsl.d.ts.map +1 -0
  148. package/dist/shaders/wgsl/quad.wgsl.d.ts +3 -0
  149. package/dist/shaders/wgsl/quad.wgsl.d.ts.map +1 -0
  150. package/dist/src/Toodle.d.ts +303 -0
  151. package/dist/src/Toodle.d.ts.map +1 -0
  152. package/dist/src/colors/mod.d.ts +871 -0
  153. package/dist/src/coreTypes/Color.d.ts +6 -0
  154. package/dist/src/coreTypes/Color.d.ts.map +1 -0
  155. package/dist/src/coreTypes/Point.d.ts +7 -0
  156. package/dist/src/coreTypes/Point.d.ts.map +1 -0
  157. package/dist/src/coreTypes/Size.d.ts +4 -0
  158. package/dist/src/coreTypes/Size.d.ts.map +1 -0
  159. package/dist/src/coreTypes/Transform.d.ts +15 -0
  160. package/dist/src/coreTypes/Transform.d.ts.map +1 -0
  161. package/dist/src/coreTypes/Vec2.d.ts +7 -0
  162. package/dist/src/coreTypes/Vec2.d.ts.map +1 -0
  163. package/dist/src/coreTypes/mod.d.ts +5 -0
  164. package/dist/src/coreTypes/mod.d.ts.map +1 -0
  165. package/dist/src/limits.d.ts +22 -0
  166. package/dist/src/limits.d.ts.map +1 -0
  167. package/dist/src/math/angle.d.ts +12 -0
  168. package/dist/src/math/angle.d.ts.map +1 -0
  169. package/dist/src/math/matrix.d.ts +25 -0
  170. package/dist/src/math/matrix.d.ts.map +1 -0
  171. package/dist/src/math/mod.d.ts +2 -0
  172. package/dist/src/math/mod.d.ts.map +1 -0
  173. package/dist/src/mod.d.ts +16 -0
  174. package/dist/src/mod.d.ts.map +1 -0
  175. package/dist/src/postprocess.d.ts +10 -0
  176. package/dist/src/postprocess.d.ts.map +1 -0
  177. package/dist/src/scene/Batcher.d.ts +19 -0
  178. package/dist/src/scene/Batcher.d.ts.map +1 -0
  179. package/dist/src/scene/Camera.d.ts +15 -0
  180. package/dist/src/scene/Camera.d.ts.map +1 -0
  181. package/dist/src/scene/JumboQuadNode.d.ts +28 -0
  182. package/dist/src/scene/QuadNode.d.ts +158 -0
  183. package/dist/src/scene/QuadNode.d.ts.map +1 -0
  184. package/dist/src/scene/RenderComponent.d.ts +10 -0
  185. package/dist/src/scene/RenderComponent.d.ts.map +1 -0
  186. package/dist/src/scene/SceneNode.d.ts +299 -0
  187. package/dist/src/scene/SceneNode.d.ts.map +1 -0
  188. package/dist/src/scene/mod.d.ts +4 -0
  189. package/dist/src/scene/mod.d.ts.map +1 -0
  190. package/dist/src/screen/mod.d.ts +1 -0
  191. package/dist/src/screen/mod.d.ts.map +1 -0
  192. package/dist/src/screen/resolution.d.ts +4 -0
  193. package/dist/src/screen/resolution.d.ts.map +1 -0
  194. package/dist/src/shaders/EngineUniform.d.ts +8 -0
  195. package/dist/src/shaders/EngineUniform.d.ts.map +1 -0
  196. package/dist/src/shaders/IShader.d.ts +14 -0
  197. package/dist/src/shaders/IShader.d.ts.map +1 -0
  198. package/dist/src/shaders/QuadShader.d.ts +17 -0
  199. package/dist/src/shaders/QuadShader.d.ts.map +1 -0
  200. package/dist/src/shaders/ShaderDescriptor.d.ts +6 -0
  201. package/dist/src/shaders/ShaderDescriptor.d.ts.map +1 -0
  202. package/dist/src/shaders/mod.d.ts +5 -0
  203. package/dist/src/shaders/mod.d.ts.map +1 -0
  204. package/dist/src/shaders/parser.d.ts +7 -0
  205. package/dist/src/shaders/parser.d.ts.map +1 -0
  206. package/dist/src/shaders/postprocess/blur.d.ts +2 -0
  207. package/dist/src/shaders/postprocess/mod.d.ts +16 -0
  208. package/dist/src/shaders/postprocess/postprocess.d.ts +8 -0
  209. package/dist/src/shaders/postprocess/util.d.ts +2 -0
  210. package/dist/src/shaders/samplers.d.ts +2 -0
  211. package/dist/src/shaders/samplers.d.ts.map +1 -0
  212. package/dist/src/shaders/wgsl/example.wgsl.d.ts +2 -0
  213. package/dist/src/shaders/wgsl/example.wgsl.d.ts.map +1 -0
  214. package/dist/src/shaders/wgsl/hello.wgsl.d.ts +2 -0
  215. package/dist/src/shaders/wgsl/hello.wgsl.d.ts.map +1 -0
  216. package/dist/src/shaders/wgsl/helloInstanced.wgsl.d.ts +2 -0
  217. package/dist/src/shaders/wgsl/helloInstanced.wgsl.d.ts.map +1 -0
  218. package/dist/src/shaders/wgsl/quad.wgsl.d.ts +2 -0
  219. package/dist/src/shaders/wgsl/quad.wgsl.d.ts.map +1 -0
  220. package/dist/src/text/FontPipeline.d.ts +13 -0
  221. package/dist/src/text/FontPipeline.d.ts.map +1 -0
  222. package/dist/src/text/MsdfFont.d.ts +81 -0
  223. package/dist/src/text/MsdfFont.d.ts.map +1 -0
  224. package/dist/src/text/TextFormatting.d.ts +18 -0
  225. package/dist/src/text/TextFormatting.d.ts.map +1 -0
  226. package/dist/src/text/TextNode.d.ts +18 -0
  227. package/dist/src/text/TextNode.d.ts.map +1 -0
  228. package/dist/src/text/TextShader.d.ts +14 -0
  229. package/dist/src/text/TextShader.d.ts.map +1 -0
  230. package/dist/src/text/mod.d.ts +3 -0
  231. package/dist/src/text/mod.d.ts.map +1 -0
  232. package/dist/src/text/shaping.d.ts +38 -0
  233. package/dist/src/text/shaping.d.ts.map +1 -0
  234. package/dist/src/text/text.wgsl.d.ts +2 -0
  235. package/dist/src/text/text.wgsl.d.ts.map +1 -0
  236. package/dist/src/textures/AssetManager.d.ts +181 -0
  237. package/dist/src/textures/AssetManager.d.ts.map +1 -0
  238. package/dist/src/textures/NewTextureComputeShader.d.ts +28 -0
  239. package/dist/src/textures/TextureComputeShader.d.ts +20 -0
  240. package/dist/src/textures/TextureComputeShader.d.ts.map +1 -0
  241. package/dist/src/textures/crop.wgsl.d.ts +2 -0
  242. package/dist/src/textures/mod.d.ts +1 -0
  243. package/dist/src/textures/mod.d.ts.map +1 -0
  244. package/dist/src/textures/pixel-scraping.wgsl.d.ts +2 -0
  245. package/dist/src/textures/pixel-scraping.wgsl.d.ts.map +1 -0
  246. package/dist/src/textures/texture-processing.wgsl.d.ts +2 -0
  247. package/dist/src/textures/types.d.ts +176 -0
  248. package/dist/src/textures/types.d.ts.map +1 -0
  249. package/dist/src/textures/util.d.ts +7 -0
  250. package/dist/src/textures/util.d.ts.map +1 -0
  251. package/dist/src/utils/assert.d.ts +1 -0
  252. package/dist/src/utils/assert.d.ts.map +1 -0
  253. package/dist/src/utils/boilerplate.d.ts +10 -0
  254. package/dist/src/utils/boilerplate.d.ts.map +1 -0
  255. package/dist/src/utils/error.d.ts +7 -0
  256. package/dist/src/utils/error.d.ts.map +1 -0
  257. package/dist/src/utils/mod.d.ts +2 -0
  258. package/dist/src/utils/mod.d.ts.map +1 -0
  259. package/dist/src/utils/pool.d.ts +22 -0
  260. package/dist/src/utils/pool.d.ts.map +1 -0
  261. package/dist/test/math/matrix.test.d.ts +1 -0
  262. package/dist/test/scene/Batcher.test.d.ts +1 -0
  263. package/dist/test/scene/SceneNode.test.d.ts +1 -0
  264. package/dist/test/shader/parser.test.d.ts +1 -0
  265. package/dist/text/FontPipeline.d.ts +14 -0
  266. package/dist/text/FontPipeline.d.ts.map +1 -0
  267. package/dist/text/MsdfFont.d.ts +82 -0
  268. package/dist/text/MsdfFont.d.ts.map +1 -0
  269. package/dist/text/TextFormatting.d.ts +19 -0
  270. package/dist/text/TextFormatting.d.ts.map +1 -0
  271. package/dist/text/TextNode.d.ts +19 -0
  272. package/dist/text/TextNode.d.ts.map +1 -0
  273. package/dist/text/TextShader.d.ts +15 -0
  274. package/dist/text/TextShader.d.ts.map +1 -0
  275. package/dist/text/mod.d.ts +4 -0
  276. package/dist/text/mod.d.ts.map +1 -0
  277. package/dist/text/shaping.d.ts +39 -0
  278. package/dist/text/shaping.d.ts.map +1 -0
  279. package/dist/text/text.wgsl.d.ts +3 -0
  280. package/dist/text/text.wgsl.d.ts.map +1 -0
  281. package/dist/textures/AssetManager.d.ts +182 -0
  282. package/dist/textures/AssetManager.d.ts.map +1 -0
  283. package/dist/textures/TextureComputeShader.d.ts +21 -0
  284. package/dist/textures/TextureComputeShader.d.ts.map +1 -0
  285. package/dist/textures/mod.d.ts +2 -0
  286. package/dist/textures/mod.d.ts.map +1 -0
  287. package/dist/textures/pixel-scraping.wgsl.d.ts +3 -0
  288. package/dist/textures/pixel-scraping.wgsl.d.ts.map +1 -0
  289. package/dist/textures/types.d.ts +177 -0
  290. package/dist/textures/types.d.ts.map +1 -0
  291. package/dist/textures/util.d.ts +8 -0
  292. package/dist/textures/util.d.ts.map +1 -0
  293. package/dist/utils/assert.d.ts +2 -0
  294. package/dist/utils/assert.d.ts.map +1 -0
  295. package/dist/utils/boilerplate.d.ts +11 -0
  296. package/dist/utils/boilerplate.d.ts.map +1 -0
  297. package/dist/utils/error.d.ts +8 -0
  298. package/dist/utils/error.d.ts.map +1 -0
  299. package/dist/utils/mod.d.ts +3 -0
  300. package/dist/utils/mod.d.ts.map +1 -0
  301. package/dist/utils/pool.d.ts +23 -0
  302. package/dist/utils/pool.d.ts.map +1 -0
  303. package/package.json +47 -0
  304. package/src/Toodle.ts +853 -0
  305. package/src/colors/mod.ts +151 -0
  306. package/src/coreTypes/Color.ts +1 -0
  307. package/src/coreTypes/Point.ts +7 -0
  308. package/src/coreTypes/Size.ts +4 -0
  309. package/src/coreTypes/Transform.ts +16 -0
  310. package/src/coreTypes/Vec2.ts +7 -0
  311. package/src/coreTypes/mod.ts +5 -0
  312. package/src/globals.d.ts +4 -0
  313. package/src/limits.ts +23 -0
  314. package/src/math/angle.ts +17 -0
  315. package/src/math/matrix.ts +99 -0
  316. package/src/math/mod.ts +2 -0
  317. package/src/mod.ts +22 -0
  318. package/src/scene/Batcher.ts +61 -0
  319. package/src/scene/Camera.ts +69 -0
  320. package/src/scene/JumboQuadNode.ts +219 -0
  321. package/src/scene/QuadNode.ts +403 -0
  322. package/src/scene/RenderComponent.ts +12 -0
  323. package/src/scene/SceneNode.ts +668 -0
  324. package/src/scene/mod.ts +4 -0
  325. package/src/screen/mod.ts +1 -0
  326. package/src/screen/resolution.ts +1 -0
  327. package/src/shaders/EngineUniform.ts +11 -0
  328. package/src/shaders/IShader.ts +20 -0
  329. package/src/shaders/QuadShader.ts +288 -0
  330. package/src/shaders/ShaderDescriptor.ts +6 -0
  331. package/src/shaders/mod.ts +5 -0
  332. package/src/shaders/parser.ts +221 -0
  333. package/src/shaders/postprocess/blur.ts +245 -0
  334. package/src/shaders/postprocess/mod.ts +71 -0
  335. package/src/shaders/samplers.ts +13 -0
  336. package/src/shaders/wgsl/example.wgsl.ts +24 -0
  337. package/src/shaders/wgsl/hello.wgsl.ts +62 -0
  338. package/src/shaders/wgsl/helloInstanced.wgsl.ts +46 -0
  339. package/src/shaders/wgsl/quad.wgsl.ts +140 -0
  340. package/src/text/FontPipeline.ts +212 -0
  341. package/src/text/MsdfFont.ts +190 -0
  342. package/src/text/TextFormatting.ts +28 -0
  343. package/src/text/TextNode.ts +82 -0
  344. package/src/text/TextShader.ts +223 -0
  345. package/src/text/mod.ts +8 -0
  346. package/src/text/shaping.ts +280 -0
  347. package/src/text/text.wgsl.ts +149 -0
  348. package/src/textures/AssetManager.ts +746 -0
  349. package/src/textures/TextureComputeShader.ts +434 -0
  350. package/src/textures/mod.ts +1 -0
  351. package/src/textures/pixel-scraping.wgsl.ts +131 -0
  352. package/src/textures/types.ts +182 -0
  353. package/src/textures/util.ts +352 -0
  354. package/src/utils/assert.ts +5 -0
  355. package/src/utils/boilerplate.ts +110 -0
  356. package/src/utils/error.ts +14 -0
  357. package/src/utils/mod.ts +2 -0
  358. package/src/utils/pool.ts +42 -0
@@ -0,0 +1,212 @@
1
+ import type { MsdfFont } from "./MsdfFont";
2
+ import msdfShader from "./text.wgsl";
3
+
4
+ /**
5
+ * A webgpu pipeline for rendering blocks of text with a given font.
6
+ */
7
+ export class FontPipeline {
8
+ constructor(
9
+ public pipeline: GPURenderPipeline,
10
+ public font: MsdfFont,
11
+ public fontBindGroup: GPUBindGroup,
12
+ public maxCharCount: number,
13
+ ) {}
14
+
15
+ static async create(
16
+ device: GPUDevice,
17
+ font: MsdfFont,
18
+ colorFormat: GPUTextureFormat,
19
+ maxCharCount: number,
20
+ ): Promise<FontPipeline> {
21
+ const pipeline = await pipelinePromise(device, colorFormat, font.name);
22
+ const texture = device.createTexture({
23
+ label: `MSDF font ${font.name}`,
24
+ size: [font.imageBitmap.width, font.imageBitmap.height, 1],
25
+ format: "rgba8unorm",
26
+ usage:
27
+ GPUTextureUsage.TEXTURE_BINDING |
28
+ GPUTextureUsage.COPY_DST |
29
+ GPUTextureUsage.RENDER_ATTACHMENT,
30
+ });
31
+ device.queue.copyExternalImageToTexture(
32
+ { source: font.imageBitmap },
33
+ { texture },
34
+ [font.imageBitmap.width, font.imageBitmap.height],
35
+ );
36
+
37
+ const charsGpuBuffer = device.createBuffer({
38
+ label: `MSDF font ${font.name} character layout buffer`,
39
+ size: font.charCount * Float32Array.BYTES_PER_ELEMENT * 8,
40
+ usage: GPUBufferUsage.STORAGE,
41
+ mappedAtCreation: true,
42
+ });
43
+
44
+ const charsArray = new Float32Array(charsGpuBuffer.getMappedRange());
45
+ // todo: don't double copy this
46
+ charsArray.set(font.charBuffer, 0);
47
+ charsGpuBuffer.unmap();
48
+
49
+ const fontDataBuffer = device.createBuffer({
50
+ label: `MSDF font ${font.name} metadata buffer`,
51
+ size: Float32Array.BYTES_PER_ELEMENT * 4,
52
+ usage: GPUBufferUsage.UNIFORM,
53
+ mappedAtCreation: true,
54
+ });
55
+ const fontDataArray = new Float32Array(fontDataBuffer.getMappedRange());
56
+ fontDataArray[0] = font.lineHeight;
57
+ fontDataBuffer.unmap();
58
+
59
+ // create a texture view
60
+ const fontBindGroup = device.createBindGroup({
61
+ layout: pipeline.getBindGroupLayout(0),
62
+ entries: [
63
+ // msdf texture
64
+ {
65
+ binding: 0,
66
+ resource: texture.createView(),
67
+ },
68
+ // msdf texture sampler
69
+ {
70
+ binding: 1,
71
+ resource: device.createSampler(sampler),
72
+ },
73
+ // buffer of character uv and offset data
74
+ {
75
+ binding: 2,
76
+ resource: {
77
+ buffer: charsGpuBuffer,
78
+ },
79
+ },
80
+ // buffer of font metadata, e.g. line height
81
+ {
82
+ binding: 3,
83
+ resource: {
84
+ buffer: fontDataBuffer,
85
+ },
86
+ },
87
+ ],
88
+ });
89
+ return new FontPipeline(pipeline, font, fontBindGroup, maxCharCount);
90
+ }
91
+ }
92
+
93
+ export function pipelinePromise(
94
+ device: GPUDevice,
95
+ colorFormat: GPUTextureFormat,
96
+ label: string,
97
+ ) {
98
+ const shader = device.createShaderModule({
99
+ label: `${label} shader`,
100
+ code: msdfShader,
101
+ });
102
+
103
+ return device.createRenderPipelineAsync({
104
+ label: `${label} pipeline`,
105
+ layout: device.createPipelineLayout({
106
+ bindGroupLayouts: [
107
+ device.createBindGroupLayout(fontBindGroupLayout),
108
+ device.createBindGroupLayout(textUniformBindGroupLayout),
109
+ device.createBindGroupLayout(engineUniformBindGroupLayout),
110
+ ],
111
+ }),
112
+ vertex: {
113
+ module: shader,
114
+ entryPoint: "vertexMain",
115
+ },
116
+ fragment: {
117
+ module: shader,
118
+ entryPoint: "fragmentMain",
119
+ targets: [
120
+ {
121
+ format: colorFormat,
122
+ blend: {
123
+ color: {
124
+ srcFactor: "src-alpha",
125
+ dstFactor: "one-minus-src-alpha",
126
+ },
127
+ alpha: {
128
+ srcFactor: "one",
129
+ dstFactor: "one",
130
+ },
131
+ },
132
+ },
133
+ ],
134
+ },
135
+ primitive: {
136
+ topology: "triangle-strip",
137
+ stripIndexFormat: "uint32",
138
+ },
139
+ });
140
+ }
141
+
142
+ if (typeof GPUShaderStage === "undefined") {
143
+ // polyfill GPUShaderStage so that toodle can be imported in non-browser environments
144
+ // eg for automated testing
145
+ globalThis.GPUShaderStage = {
146
+ VERTEX: 1,
147
+ FRAGMENT: 2,
148
+ COMPUTE: 4,
149
+ };
150
+ }
151
+
152
+ const fontBindGroupLayout: GPUBindGroupLayoutDescriptor = {
153
+ label: "MSDF font group layout",
154
+ entries: [
155
+ {
156
+ binding: 0,
157
+ visibility: GPUShaderStage.FRAGMENT,
158
+ texture: {},
159
+ },
160
+ {
161
+ binding: 1,
162
+ visibility: GPUShaderStage.FRAGMENT,
163
+ sampler: {},
164
+ },
165
+ {
166
+ binding: 2,
167
+ visibility: GPUShaderStage.VERTEX,
168
+ buffer: { type: "read-only-storage" },
169
+ },
170
+ {
171
+ binding: 3,
172
+ visibility: GPUShaderStage.VERTEX,
173
+ buffer: {},
174
+ },
175
+ ],
176
+ };
177
+
178
+ const engineUniformBindGroupLayout: GPUBindGroupLayoutDescriptor = {
179
+ label: "Uniform bind group",
180
+ entries: [
181
+ {
182
+ binding: 0,
183
+ visibility: GPUShaderStage.VERTEX,
184
+ buffer: {},
185
+ },
186
+ ],
187
+ };
188
+
189
+ const sampler: GPUSamplerDescriptor = {
190
+ label: "MSDF text sampler",
191
+ minFilter: "linear",
192
+ magFilter: "linear",
193
+ mipmapFilter: "linear",
194
+ maxAnisotropy: 16,
195
+ };
196
+
197
+ const textUniformBindGroupLayout: GPUBindGroupLayoutDescriptor = {
198
+ label: "MSDF text block uniform",
199
+ entries: [
200
+ {
201
+ // text data - matrix, color, font size, characters
202
+ binding: 0,
203
+ visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
204
+ buffer: { type: "read-only-storage" },
205
+ },
206
+ {
207
+ binding: 1,
208
+ visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
209
+ buffer: { type: "read-only-storage" },
210
+ },
211
+ ],
212
+ };
@@ -0,0 +1,190 @@
1
+ // MsdfFont has the cpu data for a font
2
+
3
+ // The kerning map stores a spare map of character ID pairs with an associated
4
+ // X offset that should be applied to the character spacing when the second
5
+ // character ID is rendered after the first.
6
+ import { warnOnce } from "../utils/error";
7
+
8
+ export type KerningMap = Map<number, Map<number, number>>;
9
+
10
+ export interface MsdfChar {
11
+ id: number;
12
+ index: number;
13
+ char: string;
14
+ width: number;
15
+ height: number;
16
+ xoffset: number;
17
+ yoffset: number;
18
+ xadvance: number;
19
+ chnl: number;
20
+ x: number;
21
+ y: number;
22
+ page: number;
23
+ charIndex: number;
24
+ }
25
+
26
+ export class MsdfFont {
27
+ /** the name of the font */
28
+ name: string;
29
+ /** the set of available characters in the font texture */
30
+ charset: string[];
31
+ charCount: number;
32
+ lineHeight: number;
33
+
34
+ /** a binary buffer of character data for loading into the gpu */
35
+ charBuffer: Float32Array;
36
+
37
+ #kernings: KerningMap;
38
+ #chars: Map<number, MsdfChar>;
39
+ #fallbackCharCode?: number;
40
+
41
+ constructor(
42
+ public id: string,
43
+ public json: MsdfFontJson,
44
+ public imageBitmap: ImageBitmap,
45
+ ) {
46
+ const charArray = Object.values(json.chars);
47
+ this.charCount = charArray.length;
48
+ this.lineHeight = json.common.lineHeight;
49
+ this.charset = json.info.charset;
50
+ this.name = json.info.face;
51
+
52
+ this.#kernings = new Map();
53
+ if (json.kernings) {
54
+ for (const kearning of json.kernings) {
55
+ let charKerning = this.#kernings.get(kearning.first);
56
+ if (!charKerning) {
57
+ charKerning = new Map<number, number>();
58
+ this.#kernings.set(kearning.first, charKerning);
59
+ }
60
+ charKerning.set(kearning.second, kearning.amount);
61
+ }
62
+ }
63
+
64
+ this.#chars = new Map<number, MsdfChar>();
65
+ const charCount = Object.values(json.chars).length;
66
+ this.charBuffer = new Float32Array(charCount * 8);
67
+ let offset = 0;
68
+ const u = 1 / json.common.scaleW;
69
+ const v = 1 / json.common.scaleH;
70
+
71
+ for (const [i, char] of json.chars.entries()) {
72
+ this.#chars.set(char.id, char);
73
+ this.#chars.get(char.id)!.charIndex = i;
74
+ this.charBuffer[offset] = char.x * u; // texOffset.x
75
+ this.charBuffer[offset + 1] = char.y * v; // texOffset.y
76
+ this.charBuffer[offset + 2] = char.width * u; // texExtent.x
77
+ this.charBuffer[offset + 3] = char.height * v; // texExtent.y
78
+ this.charBuffer[offset + 4] = char.width; // size.x
79
+ this.charBuffer[offset + 5] = char.height; // size.y
80
+ this.charBuffer[offset + 6] = char.xoffset; // offset.x
81
+ this.charBuffer[offset + 7] = -char.yoffset; // offset.y
82
+ offset += 8;
83
+ }
84
+ }
85
+
86
+ getChar(charCode: number): MsdfChar {
87
+ const char = this.#chars.get(charCode)!;
88
+ if (!char) {
89
+ const fallbackCharacter = this.#chars.get(
90
+ this.#fallbackCharCode ?? this.#chars.keys().toArray()[0],
91
+ )!;
92
+ warnOnce(
93
+ `unknown_char_${this.name}`,
94
+ `Couldn't find character ${charCode} in characters for font ${this.name} -- defaulting to first available character "${fallbackCharacter.char}"`,
95
+ );
96
+ return fallbackCharacter;
97
+ }
98
+ return char;
99
+ }
100
+
101
+ // Gets the distance in pixels a line should advance for a given character code. If the upcoming
102
+ // character code is given any kerning between the two characters will be taken into account.
103
+ getXAdvance(charCode: number, nextCharCode = -1): number {
104
+ const char = this.getChar(charCode);
105
+ if (nextCharCode >= 0) {
106
+ const kerning = this.#kernings.get(charCode);
107
+ if (kerning) {
108
+ return char.xadvance + (kerning.get(nextCharCode) ?? 0);
109
+ }
110
+ }
111
+ return char.xadvance;
112
+ }
113
+
114
+ static async create(id: string, fontJsonUrl: URL): Promise<MsdfFont> {
115
+ const response = await fetch(fontJsonUrl);
116
+ const json = (await response.json()) as MsdfFontJson;
117
+
118
+ const i = fontJsonUrl.href.lastIndexOf("/");
119
+ const baseUrl = i !== -1 ? fontJsonUrl.href.substring(0, i + 1) : undefined;
120
+
121
+ if (json.pages.length < 1) {
122
+ throw new Error(
123
+ `Can't create an msdf font without a reference to the page url in the json`,
124
+ );
125
+ }
126
+ if (json.pages.length > 1) {
127
+ throw new Error(`Can't create an msdf font with more than one page`);
128
+ }
129
+
130
+ const textureUrl = baseUrl + json.pages[0];
131
+ const textureResponse = await fetch(textureUrl);
132
+ const bitmap = await createImageBitmap(await textureResponse.blob());
133
+
134
+ return new MsdfFont(id, json, bitmap);
135
+ }
136
+
137
+ set fallbackCharacter(character: string) {
138
+ const charCode: number = character.charCodeAt(0);
139
+ if (this.#chars.has(charCode)) {
140
+ this.#fallbackCharCode = charCode;
141
+ } else {
142
+ const fallbackCode = this.#chars.keys().toArray()[0];
143
+ console.warn(
144
+ `${character} character does not exist in font ${this.name} defaulting to "${this.#chars.get(fallbackCode)?.char}".`,
145
+ );
146
+ this.#fallbackCharCode = fallbackCode;
147
+ }
148
+ }
149
+ }
150
+
151
+ type MsdfFontJson = {
152
+ pages: string[];
153
+ chars: MsdfChar[];
154
+ info: {
155
+ face: string;
156
+ size: string;
157
+ bold: number;
158
+ italic: number;
159
+ charset: string[];
160
+ unicode: number;
161
+ stretchH: number;
162
+ smooth: number;
163
+ aa: number;
164
+ padding: number[];
165
+ spacing: number[];
166
+ };
167
+ common: {
168
+ lineHeight: number;
169
+ base: number;
170
+ scaleW: number;
171
+ scaleH: number;
172
+ pages: number;
173
+ packed: number;
174
+ alphaChnl: number;
175
+ redChnl: number;
176
+ greenChnl: number;
177
+ blueChnl: number;
178
+ };
179
+ distanceField: { fieldType: string; distanceRange: number };
180
+ kernings: Kerning[];
181
+ };
182
+
183
+ type Kerning = { first: number; second: number; amount: number };
184
+
185
+ export enum WhitespaceKeyCodes {
186
+ HorizontalTab = 9,
187
+ Newline = 10,
188
+ CarriageReturn = 13,
189
+ Space = 32,
190
+ }
@@ -0,0 +1,28 @@
1
+ import type { Color } from "../coreTypes/Color";
2
+
3
+ export interface TextFormatting {
4
+ /*Horizontal alignment of the text, defaults to center*/
5
+ align?: "left" | "right" | "center";
6
+ /*Font size in pixels. 10 means that a character with an em height of 1 will be 10 pixels high.*/
7
+ fontSize?: number;
8
+ /*RGBA color of the text, defaults to white.*/
9
+ color?: Color;
10
+
11
+ /*Options for word wrapping.*/
12
+ wordWrap?: WordWrapOptions;
13
+
14
+ /*Options for shrinking the text to fit within the bounds.*/
15
+ shrinkToFit?: ShrinkToFitOptions;
16
+ }
17
+
18
+ export type WordWrapOptions = {
19
+ emWidth: number;
20
+ breakOn?: "word" | "character";
21
+ };
22
+
23
+ export type ShrinkToFitOptions = {
24
+ minFontSize: number;
25
+ maxFontSize?: number;
26
+ maxLines?: number;
27
+ padding?: number;
28
+ };
@@ -0,0 +1,82 @@
1
+ import type { Color } from "../coreTypes/Color";
2
+ import { type NodeOptions, SceneNode } from "../scene/SceneNode";
3
+ import type { MsdfFont } from "./MsdfFont";
4
+ import { measureText } from "./shaping";
5
+ import type { TextFormatting } from "./TextFormatting";
6
+ import type { TextShader } from "./TextShader";
7
+
8
+ export const DEFAULT_FONT_SIZE = 14;
9
+
10
+ export class TextNode extends SceneNode {
11
+ #text: string;
12
+ #formatting: TextFormatting;
13
+ #font: MsdfFont;
14
+
15
+ constructor(shader: TextShader, text: string, opts: TextOptions = {}) {
16
+ const { width, height } = measureText(shader.font, text, opts.wordWrap);
17
+
18
+ if (text.length > shader.maxCharCount) {
19
+ throw new Error(
20
+ `Text: ${text} exceeds ${shader.maxCharCount} characters. Try using fewer characters or increase the limit in Toodle.attach.`,
21
+ );
22
+ }
23
+
24
+ const em2px = shader.font.lineHeight / (opts.fontSize ?? DEFAULT_FONT_SIZE);
25
+
26
+ if (!opts.shrinkToFit && !opts.idealSize) {
27
+ opts.idealSize = { width: width / em2px, height: height / em2px };
28
+ }
29
+
30
+ super({
31
+ ...opts,
32
+ render: {
33
+ shader,
34
+ writeInstance: (_node, _array, _offset) => {
35
+ throw new Error(
36
+ "not implemented - needs access to text uniform buffer, dimensions and a model matrix",
37
+ );
38
+ },
39
+ },
40
+ });
41
+
42
+ this.#font = shader.font;
43
+ this.#text = text;
44
+ this.#formatting = opts;
45
+ }
46
+
47
+ get text() {
48
+ return this.#text;
49
+ }
50
+
51
+ get formatting() {
52
+ return this.#formatting;
53
+ }
54
+
55
+ get font() {
56
+ return this.#font;
57
+ }
58
+
59
+ set text(text: string) {
60
+ if (!text) {
61
+ throw new Error("text cannot be empty");
62
+ }
63
+ this.#text = text;
64
+ this.setDirty();
65
+ }
66
+
67
+ get tint() {
68
+ return this.#formatting.color || { r: 1, g: 1, b: 1, a: 1 };
69
+ }
70
+
71
+ set tint(tint: Color) {
72
+ this.#formatting.color = tint;
73
+ this.setDirty();
74
+ }
75
+
76
+ set formatting(formatting: TextFormatting) {
77
+ this.#formatting = formatting;
78
+ this.setDirty();
79
+ }
80
+ }
81
+
82
+ export type TextOptions = Omit<NodeOptions, "render"> & TextFormatting;