xbintsc 0.5.23 → 0.5.32

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 (481) hide show
  1. package/AGENTS.md +11 -2
  2. package/README.md +47 -16
  3. package/README.zh-CN.md +21 -2
  4. package/dist/scripts/support-matrix.d.ts +18 -0
  5. package/dist/scripts/support-matrix.js +141 -0
  6. package/dist/scripts/support-matrix.js.map +1 -0
  7. package/dist/src/ast/common.d.ts +2 -2
  8. package/dist/src/ast/declarations.d.ts +7 -1
  9. package/dist/src/ast/expressions.d.ts +5 -0
  10. package/dist/src/ast/kinds.d.ts +2 -0
  11. package/dist/src/ast/kinds.js +2 -0
  12. package/dist/src/ast/kinds.js.map +1 -1
  13. package/dist/src/binder/binder.d.ts +2 -1
  14. package/dist/src/binder/binder.js +2 -0
  15. package/dist/src/binder/binder.js.map +1 -1
  16. package/dist/src/binder/declarations.d.ts +9 -0
  17. package/dist/src/binder/declarations.js +64 -0
  18. package/dist/src/binder/declarations.js.map +1 -1
  19. package/dist/src/binder/references.js +99 -4
  20. package/dist/src/binder/references.js.map +1 -1
  21. package/dist/src/binder/types.d.ts +32 -0
  22. package/dist/src/binder/types.js.map +1 -1
  23. package/dist/src/canonical.d.ts +29 -0
  24. package/dist/src/canonical.js +35 -0
  25. package/dist/src/canonical.js.map +1 -0
  26. package/dist/src/checker/assignability.d.ts +13 -0
  27. package/dist/src/checker/assignability.js +146 -0
  28. package/dist/src/checker/assignability.js.map +1 -0
  29. package/dist/src/checker/calls.d.ts +13 -0
  30. package/dist/src/checker/calls.js +127 -0
  31. package/dist/src/checker/calls.js.map +1 -0
  32. package/dist/src/checker/checker.d.ts +26 -0
  33. package/dist/src/checker/checker.js +31 -0
  34. package/dist/src/checker/checker.js.map +1 -0
  35. package/dist/src/checker/declarations.d.ts +9 -0
  36. package/dist/src/checker/declarations.js +15 -0
  37. package/dist/src/checker/declarations.js.map +1 -0
  38. package/dist/src/checker/flow.d.ts +21 -0
  39. package/dist/src/checker/flow.js +241 -0
  40. package/dist/src/checker/flow.js.map +1 -0
  41. package/dist/src/checker/globals.d.ts +9 -0
  42. package/dist/src/checker/globals.js +29 -0
  43. package/dist/src/checker/globals.js.map +1 -0
  44. package/dist/src/checker/source.d.ts +38 -0
  45. package/dist/src/checker/source.js +48 -0
  46. package/dist/src/checker/source.js.map +1 -0
  47. package/dist/src/checker/type-infer.d.ts +18 -0
  48. package/dist/src/checker/type-infer.js +173 -0
  49. package/dist/src/checker/type-infer.js.map +1 -0
  50. package/dist/src/checker/type-model.d.ts +73 -0
  51. package/dist/src/checker/type-model.js +151 -0
  52. package/dist/src/checker/type-model.js.map +1 -0
  53. package/dist/src/checker/type-system.d.ts +58 -0
  54. package/dist/src/checker/type-system.js +569 -0
  55. package/dist/src/checker/type-system.js.map +1 -0
  56. package/dist/src/checker/typecheck-types.d.ts +22 -0
  57. package/dist/src/checker/typecheck-types.js +109 -0
  58. package/dist/src/checker/typecheck-types.js.map +1 -0
  59. package/dist/src/checker/typecheck.d.ts +62 -0
  60. package/dist/src/checker/typecheck.js +574 -0
  61. package/dist/src/checker/typecheck.js.map +1 -0
  62. package/dist/src/checker/undefined.d.ts +14 -0
  63. package/dist/src/checker/undefined.js +32 -0
  64. package/dist/src/checker/undefined.js.map +1 -0
  65. package/dist/src/checker/walk.d.ts +10 -0
  66. package/dist/src/checker/walk.js +15 -0
  67. package/dist/src/checker/walk.js.map +1 -0
  68. package/dist/src/cli/help.d.ts +7 -0
  69. package/dist/src/cli/help.js +64 -0
  70. package/dist/src/cli/help.js.map +1 -0
  71. package/dist/src/cli/hints.js +2 -1
  72. package/dist/src/cli/hints.js.map +1 -1
  73. package/dist/src/cli/main.js +12 -48
  74. package/dist/src/cli/main.js.map +1 -1
  75. package/dist/src/codegen/generator/calls/access.js +8 -8
  76. package/dist/src/codegen/generator/calls/access.js.map +1 -1
  77. package/dist/src/codegen/generator/calls/invocation.js +9 -4
  78. package/dist/src/codegen/generator/calls/invocation.js.map +1 -1
  79. package/dist/src/codegen/generator/calls/super.d.ts +9 -1
  80. package/dist/src/codegen/generator/calls/super.js +56 -5
  81. package/dist/src/codegen/generator/calls/super.js.map +1 -1
  82. package/dist/src/codegen/generator/context.d.ts +13 -2
  83. package/dist/src/codegen/generator/context.js +25 -19
  84. package/dist/src/codegen/generator/context.js.map +1 -1
  85. package/dist/src/codegen/generator/debug.js +2 -1
  86. package/dist/src/codegen/generator/debug.js.map +1 -1
  87. package/dist/src/codegen/generator/expressions/primary.d.ts +4 -1
  88. package/dist/src/codegen/generator/expressions/primary.js +68 -8
  89. package/dist/src/codegen/generator/expressions/primary.js.map +1 -1
  90. package/dist/src/codegen/generator/generator.js +11 -1
  91. package/dist/src/codegen/generator/generator.js.map +1 -1
  92. package/dist/src/codegen/generator/module.d.ts +3 -0
  93. package/dist/src/codegen/generator/module.js +116 -26
  94. package/dist/src/codegen/generator/module.js.map +1 -1
  95. package/dist/src/codegen/generator/state.d.ts +11 -1
  96. package/dist/src/codegen/generator/state.js.map +1 -1
  97. package/dist/src/codegen/generator/statements/variables.js +26 -7
  98. package/dist/src/codegen/generator/statements/variables.js.map +1 -1
  99. package/dist/src/codegen/generator/tables.d.ts +2 -0
  100. package/dist/src/codegen/generator/tables.js +4 -0
  101. package/dist/src/codegen/generator/tables.js.map +1 -1
  102. package/dist/src/driver/build-key.d.ts +2 -0
  103. package/dist/src/driver/build-key.js +1 -0
  104. package/dist/src/driver/build-key.js.map +1 -1
  105. package/dist/src/driver/bundler/graph.js +5 -1
  106. package/dist/src/driver/bundler/graph.js.map +1 -1
  107. package/dist/src/driver/bundler/merge.js +16 -1
  108. package/dist/src/driver/bundler/merge.js.map +1 -1
  109. package/dist/src/driver/bundler/types.d.ts +12 -0
  110. package/dist/src/driver/compiler.d.ts +1 -1
  111. package/dist/src/driver/compiler.js +3 -0
  112. package/dist/src/driver/compiler.js.map +1 -1
  113. package/dist/src/driver/fingerprint.js +2 -1
  114. package/dist/src/driver/fingerprint.js.map +1 -1
  115. package/dist/src/driver/frontend.d.ts +8 -6
  116. package/dist/src/driver/frontend.js +4 -0
  117. package/dist/src/driver/frontend.js.map +1 -1
  118. package/dist/src/driver/options.d.ts +6 -0
  119. package/dist/src/driver/version.d.ts +1 -1
  120. package/dist/src/driver/version.js +1 -1
  121. package/dist/src/extensions/gui/css.d.ts +26 -0
  122. package/dist/src/extensions/gui/css.js +100 -0
  123. package/dist/src/extensions/gui/css.js.map +1 -0
  124. package/dist/src/extensions/gui/html.js +28 -7
  125. package/dist/src/extensions/gui/html.js.map +1 -1
  126. package/dist/src/extensions/gui/index.js +79 -2
  127. package/dist/src/extensions/gui/index.js.map +1 -1
  128. package/dist/src/extensions/gui/three.d.ts +16 -0
  129. package/dist/src/extensions/gui/three.js +22 -0
  130. package/dist/src/extensions/gui/three.js.map +1 -0
  131. package/dist/src/extensions/media/index.d.ts +6 -5
  132. package/dist/src/extensions/media/index.js +12 -14
  133. package/dist/src/extensions/media/index.js.map +1 -1
  134. package/dist/src/extensions/registry.d.ts +38 -0
  135. package/dist/src/extensions/registry.js +10 -0
  136. package/dist/src/extensions/registry.js.map +1 -1
  137. package/dist/src/index.d.ts +1 -0
  138. package/dist/src/index.js +1 -0
  139. package/dist/src/index.js.map +1 -1
  140. package/dist/src/parser/declarations/classes.js +7 -0
  141. package/dist/src/parser/declarations/classes.js.map +1 -1
  142. package/dist/src/parser/expressions.js +14 -1
  143. package/dist/src/parser/expressions.js.map +1 -1
  144. package/dist/src/parser/literals.js +6 -2
  145. package/dist/src/parser/literals.js.map +1 -1
  146. package/dist/tests/binder/binder.test.js +29 -0
  147. package/dist/tests/binder/binder.test.js.map +1 -1
  148. package/dist/tests/canonical.test.d.ts +1 -0
  149. package/dist/tests/canonical.test.js +19 -0
  150. package/dist/tests/canonical.test.js.map +1 -0
  151. package/dist/tests/checker/checker.test.d.ts +1 -0
  152. package/dist/tests/checker/checker.test.js +245 -0
  153. package/dist/tests/checker/checker.test.js.map +1 -0
  154. package/dist/tests/cli/check.test.js +20 -0
  155. package/dist/tests/cli/check.test.js.map +1 -1
  156. package/dist/tests/conformance/matrix.test.d.ts +6 -0
  157. package/dist/tests/conformance/matrix.test.js +23 -0
  158. package/dist/tests/conformance/matrix.test.js.map +1 -0
  159. package/dist/tests/conformance/test262/manifest.d.ts +115 -0
  160. package/dist/tests/conformance/test262/manifest.js +257 -0
  161. package/dist/tests/conformance/test262/manifest.js.map +1 -0
  162. package/dist/tests/conformance/test262.test.d.ts +11 -0
  163. package/dist/tests/conformance/test262.test.js +74 -0
  164. package/dist/tests/conformance/test262.test.js.map +1 -0
  165. package/dist/tests/docs/structure.test.js +9 -11
  166. package/dist/tests/docs/structure.test.js.map +1 -1
  167. package/dist/tests/e2e/child-process.test.js +3 -2
  168. package/dist/tests/e2e/child-process.test.js.map +1 -1
  169. package/dist/tests/e2e/compile-builtins.test.js +45 -0
  170. package/dist/tests/e2e/compile-builtins.test.js.map +1 -1
  171. package/dist/tests/e2e/compile-objects-classes.test.js +77 -0
  172. package/dist/tests/e2e/compile-objects-classes.test.js.map +1 -1
  173. package/dist/tests/e2e/differential-syntax.test.d.ts +5 -0
  174. package/dist/tests/e2e/differential-syntax.test.js +95 -0
  175. package/dist/tests/e2e/differential-syntax.test.js.map +1 -0
  176. package/dist/tests/e2e/differential-values.test.js +15 -0
  177. package/dist/tests/e2e/differential-values.test.js.map +1 -1
  178. package/dist/tests/e2e/gui-browser.test.d.ts +13 -0
  179. package/dist/tests/e2e/gui-browser.test.js +163 -0
  180. package/dist/tests/e2e/gui-browser.test.js.map +1 -0
  181. package/dist/tests/e2e/gui-effects.test.d.ts +6 -0
  182. package/dist/tests/e2e/gui-effects.test.js +262 -0
  183. package/dist/tests/e2e/gui-effects.test.js.map +1 -0
  184. package/dist/tests/e2e/gui-example-browser.test.js +2 -2
  185. package/dist/tests/e2e/gui-example-browser.test.js.map +1 -1
  186. package/dist/tests/e2e/gui-example-canvas.test.js +5 -4
  187. package/dist/tests/e2e/gui-example-canvas.test.js.map +1 -1
  188. package/dist/tests/e2e/gui-example-svg.test.js +4 -3
  189. package/dist/tests/e2e/gui-example-svg.test.js.map +1 -1
  190. package/dist/tests/e2e/gui-example-webgl.test.d.ts +10 -0
  191. package/dist/tests/e2e/gui-example-webgl.test.js +75 -0
  192. package/dist/tests/e2e/gui-example-webgl.test.js.map +1 -0
  193. package/dist/tests/e2e/gui-example-webgl2.test.d.ts +8 -0
  194. package/dist/tests/e2e/gui-example-webgl2.test.js +72 -0
  195. package/dist/tests/e2e/gui-example-webgl2.test.js.map +1 -0
  196. package/dist/tests/e2e/gui-example.test.js +4 -3
  197. package/dist/tests/e2e/gui-example.test.js.map +1 -1
  198. package/dist/tests/e2e/gui-helpers.js +4 -3
  199. package/dist/tests/e2e/gui-helpers.js.map +1 -1
  200. package/dist/tests/e2e/gui-layout.test.js +48 -0
  201. package/dist/tests/e2e/gui-layout.test.js.map +1 -1
  202. package/dist/tests/e2e/gui-media.test.js +10 -8
  203. package/dist/tests/e2e/gui-media.test.js.map +1 -1
  204. package/dist/tests/e2e/gui-webgl.test.d.ts +11 -0
  205. package/dist/tests/e2e/gui-webgl.test.js +179 -0
  206. package/dist/tests/e2e/gui-webgl.test.js.map +1 -0
  207. package/dist/tests/e2e/gui-webgl2.test.d.ts +10 -0
  208. package/dist/tests/e2e/gui-webgl2.test.js +238 -0
  209. package/dist/tests/e2e/gui-webgl2.test.js.map +1 -0
  210. package/dist/tests/e2e/harness.d.ts +9 -0
  211. package/dist/tests/e2e/harness.js +14 -2
  212. package/dist/tests/e2e/harness.js.map +1 -1
  213. package/dist/tests/e2e/native-extensions.test.js +2 -1
  214. package/dist/tests/e2e/native-extensions.test.js.map +1 -1
  215. package/dist/tests/e2e/property-descriptors.test.js +20 -0
  216. package/dist/tests/e2e/property-descriptors.test.js.map +1 -1
  217. package/dist/tests/e2e/unicode-output.test.js +5 -3
  218. package/dist/tests/e2e/unicode-output.test.js.map +1 -1
  219. package/dist/tests/e2e/weak-collections.test.js +16 -2
  220. package/dist/tests/e2e/weak-collections.test.js.map +1 -1
  221. package/dist/tests/extensions/gui.test.js +41 -0
  222. package/dist/tests/extensions/gui.test.js.map +1 -1
  223. package/dist/tests/extensions/media.test.js +7 -3
  224. package/dist/tests/extensions/media.test.js.map +1 -1
  225. package/dist/tests/helpers.d.ts +1 -0
  226. package/dist/tests/helpers.js +1 -0
  227. package/dist/tests/helpers.js.map +1 -1
  228. package/dist/tests/parser/declarations.test.js +20 -0
  229. package/dist/tests/parser/declarations.test.js.map +1 -1
  230. package/dist/tests/parser/expressions.test.js +36 -0
  231. package/dist/tests/parser/expressions.test.js.map +1 -1
  232. package/dist/tests/platform.d.ts +32 -0
  233. package/dist/tests/platform.js +40 -0
  234. package/dist/tests/platform.js.map +1 -0
  235. package/dist/tests/platform.test.d.ts +12 -0
  236. package/dist/tests/platform.test.js +51 -0
  237. package/dist/tests/platform.test.js.map +1 -0
  238. package/dist/tests/version.test.js +4 -4
  239. package/dist/tests/version.test.js.map +1 -1
  240. package/doc/ai/README.md +10 -4
  241. package/doc/ai/build-recipe.md +1 -0
  242. package/doc/ai/cli.md +17 -5
  243. package/doc/ai/contributing.md +59 -2
  244. package/doc/ai/extensions.md +38 -7
  245. package/doc/ai/language-support.md +25 -16
  246. package/doc/ai/troubleshooting.md +12 -8
  247. package/doc/ai/zh-CN/README.md +9 -4
  248. package/doc/ai/zh-CN/build-recipe.md +1 -0
  249. package/doc/ai/zh-CN/cli.md +13 -3
  250. package/doc/ai/zh-CN/contributing.md +49 -3
  251. package/doc/ai/zh-CN/extensions.md +33 -6
  252. package/doc/ai/zh-CN/language-support.md +23 -14
  253. package/doc/ai/zh-CN/troubleshooting.md +10 -6
  254. package/doc/gui/api.md +47 -1
  255. package/doc/gui/build.md +72 -16
  256. package/doc/gui/canvas.md +11 -3
  257. package/doc/gui/dom.md +33 -18
  258. package/doc/gui/known-issues.md +58 -15
  259. package/doc/gui/layout.md +18 -0
  260. package/doc/gui/media.md +17 -13
  261. package/doc/gui/rendering.md +50 -3
  262. package/doc/gui/runtime.md +18 -0
  263. package/doc/gui/webgl.md +256 -0
  264. package/doc/gui-scripts.md +7 -0
  265. package/doc/gui.md +108 -17
  266. package/doc/implemented/binder.md +2 -0
  267. package/doc/implemented/checker.md +117 -0
  268. package/doc/implemented/cli.md +13 -1
  269. package/doc/implemented/codegen.md +3 -2
  270. package/doc/implemented/driver.md +2 -2
  271. package/doc/implemented/operators.md +2 -1
  272. package/doc/implemented/parser.md +3 -2
  273. package/doc/implemented/pipeline.md +8 -1
  274. package/doc/implemented/stdlib.md +2 -1
  275. package/doc/implemented/tests.md +3 -1
  276. package/doc/implemented.md +2 -0
  277. package/doc/npm-package.md +419 -0
  278. package/doc/requirements.md +22 -10
  279. package/doc/support-matrix.md +83 -0
  280. package/doc/unimplemented/classes.md +3 -0
  281. package/doc/unimplemented/deviations.md +3 -2
  282. package/doc/unimplemented/toolchain.md +1 -1
  283. package/doc/unimplemented/types.md +24 -8
  284. package/doc/unimplemented.md +1 -1
  285. package/doc/zh-CN/gui/api.md +43 -1
  286. package/doc/zh-CN/gui/build.md +64 -15
  287. package/doc/zh-CN/gui/canvas.md +9 -2
  288. package/doc/zh-CN/gui/dom.md +20 -7
  289. package/doc/zh-CN/gui/known-issues.md +46 -13
  290. package/doc/zh-CN/gui/layout.md +14 -0
  291. package/doc/zh-CN/gui/media.md +15 -11
  292. package/doc/zh-CN/gui/rendering.md +41 -4
  293. package/doc/zh-CN/gui/runtime.md +16 -0
  294. package/doc/zh-CN/gui/webgl.md +115 -0
  295. package/doc/zh-CN/gui-scripts.md +5 -0
  296. package/doc/zh-CN/gui.md +89 -14
  297. package/doc/zh-CN/implemented/binder.md +2 -0
  298. package/doc/zh-CN/implemented/checker.md +99 -0
  299. package/doc/zh-CN/implemented/cli.md +12 -1
  300. package/doc/zh-CN/implemented/codegen.md +3 -2
  301. package/doc/zh-CN/implemented/driver.md +2 -2
  302. package/doc/zh-CN/implemented/operators.md +1 -1
  303. package/doc/zh-CN/implemented/parser.md +3 -2
  304. package/doc/zh-CN/implemented/pipeline.md +3 -1
  305. package/doc/zh-CN/implemented/stdlib.md +2 -1
  306. package/doc/zh-CN/implemented/tests.md +3 -1
  307. package/doc/zh-CN/implemented.md +2 -0
  308. package/doc/zh-CN/npm-package.md +394 -0
  309. package/doc/zh-CN/post/announce.md +47 -47
  310. package/doc/zh-CN/requirements.md +16 -7
  311. package/doc/zh-CN/support-matrix.md +82 -0
  312. package/doc/zh-CN/unimplemented/classes.md +3 -0
  313. package/doc/zh-CN/unimplemented/deviations.md +3 -2
  314. package/doc/zh-CN/unimplemented/toolchain.md +1 -1
  315. package/doc/zh-CN/unimplemented/types.md +16 -6
  316. package/doc/zh-CN/unimplemented.md +1 -1
  317. package/llms.txt +6 -1
  318. package/package.json +2 -1
  319. package/runtime/ext_gui/audio.cpp +316 -0
  320. package/runtime/ext_gui/browser.cpp +573 -0
  321. package/runtime/ext_gui/browser_escape.cpp +85 -0
  322. package/runtime/ext_gui/browser_loop.cpp +83 -0
  323. package/runtime/ext_gui/canvas.cpp +12 -21
  324. package/runtime/ext_gui/canvas_internal.h +10 -0
  325. package/runtime/ext_gui/canvas_raster.cpp +79 -1
  326. package/runtime/ext_gui/clip_values.cpp +246 -0
  327. package/runtime/ext_gui/css.cpp +94 -0
  328. package/runtime/ext_gui/css.h +22 -1
  329. package/runtime/ext_gui/css_match.cpp +3 -0
  330. package/runtime/ext_gui/css_selector.cpp +9 -0
  331. package/runtime/ext_gui/css_sheet.cpp +89 -45
  332. package/runtime/ext_gui/document.cpp +4 -1
  333. package/runtime/ext_gui/document.h +2 -0
  334. package/runtime/ext_gui/dom.h +16 -0
  335. package/runtime/ext_gui/dom_api.cpp +37 -0
  336. package/runtime/ext_gui/dom_api_canvas.cpp +17 -80
  337. package/runtime/ext_gui/dom_api_canvas_extra.cpp +130 -1
  338. package/runtime/ext_gui/dom_api_canvas_pending.cpp +41 -0
  339. package/runtime/ext_gui/dom_api_document.cpp +96 -5
  340. package/runtime/ext_gui/dom_api_events.cpp +20 -0
  341. package/runtime/ext_gui/dom_api_internal.h +278 -0
  342. package/runtime/ext_gui/dom_api_proto.cpp +6 -0
  343. package/runtime/ext_gui/dom_api_webgl.cpp +376 -0
  344. package/runtime/ext_gui/dom_api_webgl2.cpp +434 -0
  345. package/runtime/ext_gui/dom_api_webgl2_draw.cpp +269 -0
  346. package/runtime/ext_gui/dom_api_webgl_buffer.cpp +212 -0
  347. package/runtime/ext_gui/dom_api_webgl_rt.h +30 -0
  348. package/runtime/ext_gui/dom_api_webgl_shader.cpp +443 -0
  349. package/runtime/ext_gui/dom_api_webgl_state.cpp +444 -0
  350. package/runtime/ext_gui/dom_api_webgl_texture.cpp +445 -0
  351. package/runtime/ext_gui/effect_values.cpp +312 -0
  352. package/runtime/ext_gui/gradient_values.cpp +476 -0
  353. package/runtime/ext_gui/grid_values.cpp +230 -0
  354. package/runtime/ext_gui/gui.cpp +90 -23
  355. package/runtime/ext_gui/gui_canvas.cpp +50 -2
  356. package/runtime/ext_gui/gui_engine.h +71 -0
  357. package/runtime/ext_gui/gui_events.cpp +4 -1
  358. package/runtime/ext_gui/gui_media.cpp +1 -1
  359. package/runtime/ext_gui/gui_webgl.cpp +83 -0
  360. package/runtime/ext_gui/layout.cpp +21 -0
  361. package/runtime/ext_gui/layout_flow.cpp +81 -4
  362. package/runtime/ext_gui/layout_flow_internal.h +31 -0
  363. package/runtime/ext_gui/layout_grid.cpp +374 -0
  364. package/runtime/ext_gui/media.h +1 -1
  365. package/runtime/ext_gui/media_api.h +2 -2
  366. package/runtime/ext_gui/media_query.cpp +211 -0
  367. package/runtime/ext_gui/paint.cpp +111 -77
  368. package/runtime/ext_gui/paint.h +33 -3
  369. package/runtime/ext_gui/paint_background.cpp +229 -0
  370. package/runtime/ext_gui/paint_clip.cpp +268 -0
  371. package/runtime/ext_gui/paint_effects.cpp +324 -0
  372. package/runtime/ext_gui/paint_internal.h +85 -0
  373. package/runtime/ext_gui/renderer.cpp +8 -31
  374. package/runtime/ext_gui/renderer_clip.cpp +196 -0
  375. package/runtime/ext_gui/renderer_image.cpp +13 -8
  376. package/runtime/ext_gui/renderer_internal.h +15 -8
  377. package/runtime/ext_gui/renderer_text.cpp +6 -31
  378. package/runtime/ext_gui/style.cpp +343 -20
  379. package/runtime/ext_gui/style.h +144 -3
  380. package/runtime/ext_gui/style_print.cpp +134 -1
  381. package/runtime/ext_gui/style_values.cpp +152 -126
  382. package/runtime/ext_gui/style_values_internal.h +35 -0
  383. package/runtime/ext_gui/webgl.h +466 -0
  384. package/runtime/ext_gui/webgl2_constants.h +274 -0
  385. package/runtime/ext_gui/webgl_buffer.cpp +565 -0
  386. package/runtime/ext_gui/webgl_constants.h +317 -0
  387. package/runtime/ext_gui/webgl_context.cpp +466 -0
  388. package/runtime/ext_gui/webgl_draw.cpp +495 -0
  389. package/runtime/ext_gui/webgl_glsl.h +125 -0
  390. package/runtime/ext_gui/webgl_glsl_compile.cpp +431 -0
  391. package/runtime/ext_gui/webgl_glsl_rewrite.cpp +349 -0
  392. package/runtime/ext_gui/webgl_glsl_scan.cpp +581 -0
  393. package/runtime/ext_gui/webgl_msl.cpp +62 -0
  394. package/runtime/ext_gui/webgl_msl.h +33 -0
  395. package/runtime/ext_gui/webgl_pipeline.cpp +274 -0
  396. package/runtime/ext_gui/webgl_program_internal.h +18 -0
  397. package/runtime/ext_gui/webgl_shader.cpp +582 -0
  398. package/runtime/ext_gui/webgl_texture.cpp +293 -0
  399. package/runtime/ext_gui/webgl_uniform.cpp +167 -0
  400. package/runtime/ext_gui/webgl_webgl2.cpp +224 -0
  401. package/runtime/ext_gui/window.cpp +9 -0
  402. package/runtime/ext_media/media.cpp +1 -1
  403. package/runtime/ext_media/media_bridge.c +9 -3
  404. package/runtime/ext_node/path/path.c +7 -7
  405. package/runtime/ext_node/url/url.c +4 -2
  406. package/runtime/rt.h +15 -0
  407. package/runtime/rt_internal.h +1 -0
  408. package/runtime/xt_constructors.c +2 -1
  409. package/runtime/xt_containers/access.inc +8 -0
  410. package/runtime/xt_containers/objects.inc +22 -2
  411. package/runtime/xt_io/exception.inc +4 -2
  412. package/runtime/xt_regex/api.inc +2 -0
  413. package/runtime/xt_regex/matcher.inc +16 -3
  414. package/runtime/xt_regex/parser.inc +8 -2
  415. package/runtime/xt_regex/types.inc +3 -0
  416. package/runtime/xt_stdlib/math.inc +62 -0
  417. package/runtime/xt_stdlib2/date.inc +7 -1
  418. package/runtime/xt_stdlib2/objects.inc +14 -0
  419. package/runtime/xt_stdlib2/regexp-match.inc +60 -21
  420. package/runtime/xt_stdlib2/regexp.inc +1 -0
  421. package/runtime/xt_typed_array.c +1 -1
  422. package/scripts/build-gui.ts +90 -3
  423. package/scripts/build-media.ts +323 -58
  424. package/scripts/setup-vs-toolchain.ps1 +152 -0
  425. package/scripts/support-matrix.ts +167 -0
  426. package/src/ast/common.ts +2 -0
  427. package/src/ast/declarations.ts +12 -1
  428. package/src/ast/expressions.ts +6 -0
  429. package/src/ast/kinds.ts +2 -0
  430. package/src/binder/binder.ts +3 -0
  431. package/src/binder/declarations.ts +70 -0
  432. package/src/binder/references.ts +97 -4
  433. package/src/binder/types.ts +30 -0
  434. package/src/canonical.ts +37 -0
  435. package/src/checker/assignability.ts +134 -0
  436. package/src/checker/calls.ts +135 -0
  437. package/src/checker/checker.ts +47 -0
  438. package/src/checker/declarations.ts +26 -0
  439. package/src/checker/flow.ts +236 -0
  440. package/src/checker/globals.ts +40 -0
  441. package/src/checker/source.ts +53 -0
  442. package/src/checker/type-infer.ts +185 -0
  443. package/src/checker/type-model.ts +212 -0
  444. package/src/checker/type-system.ts +578 -0
  445. package/src/checker/typecheck-types.ts +112 -0
  446. package/src/checker/typecheck.ts +586 -0
  447. package/src/checker/undefined.ts +43 -0
  448. package/src/checker/walk.ts +16 -0
  449. package/src/cli/help.ts +65 -0
  450. package/src/cli/hints.ts +2 -1
  451. package/src/cli/main.ts +12 -49
  452. package/src/codegen/generator/calls/access.ts +8 -8
  453. package/src/codegen/generator/calls/invocation.ts +8 -5
  454. package/src/codegen/generator/calls/super.ts +67 -5
  455. package/src/codegen/generator/context.ts +31 -19
  456. package/src/codegen/generator/debug.ts +2 -1
  457. package/src/codegen/generator/expressions/primary.ts +84 -13
  458. package/src/codegen/generator/generator.ts +11 -1
  459. package/src/codegen/generator/module.ts +115 -24
  460. package/src/codegen/generator/state.ts +11 -1
  461. package/src/codegen/generator/statements/variables.ts +26 -6
  462. package/src/codegen/generator/tables.ts +5 -0
  463. package/src/driver/build-key.ts +3 -0
  464. package/src/driver/bundler/graph.ts +6 -2
  465. package/src/driver/bundler/merge.ts +14 -1
  466. package/src/driver/bundler/types.ts +13 -0
  467. package/src/driver/compiler.ts +4 -1
  468. package/src/driver/fingerprint.ts +2 -1
  469. package/src/driver/frontend.ts +13 -2
  470. package/src/driver/options.ts +6 -0
  471. package/src/driver/version.ts +1 -1
  472. package/src/extensions/gui/css.ts +113 -0
  473. package/src/extensions/gui/html.ts +31 -11
  474. package/src/extensions/gui/index.ts +81 -2
  475. package/src/extensions/gui/three.ts +25 -0
  476. package/src/extensions/media/index.ts +13 -16
  477. package/src/extensions/registry.ts +48 -0
  478. package/src/index.ts +1 -0
  479. package/src/parser/declarations/classes.ts +7 -0
  480. package/src/parser/expressions.ts +13 -1
  481. package/src/parser/literals.ts +6 -2
@@ -105,6 +105,33 @@ struct FloatContext {
105
105
  inline float toPx(const Length &length, float base, float em, float root, float vw, float vh,
106
106
  float fallback) {
107
107
  switch (length.unit) {
108
+ case Unit::Clamp: {
109
+ if (length.args.size() < 3) return fallback;
110
+ float low = toPx(length.args[0], base, em, root, vw, vh, fallback);
111
+ float value = toPx(length.args[1], base, em, root, vw, vh, fallback);
112
+ float high = toPx(length.args[2], base, em, root, vw, vh, fallback);
113
+ return value < low ? low : (value > high ? high : value);
114
+ }
115
+ case Unit::Min: {
116
+ float best = fallback;
117
+ bool first = true;
118
+ for (const Length &arg : length.args) {
119
+ float value = toPx(arg, base, em, root, vw, vh, fallback);
120
+ if (first || value < best) best = value;
121
+ first = false;
122
+ }
123
+ return first ? fallback : best;
124
+ }
125
+ case Unit::Max: {
126
+ float best = fallback;
127
+ bool first = true;
128
+ for (const Length &arg : length.args) {
129
+ float value = toPx(arg, base, em, root, vw, vh, fallback);
130
+ if (first || value > best) best = value;
131
+ first = false;
132
+ }
133
+ return first ? fallback : best;
134
+ }
108
135
  case Unit::Px:
109
136
  case Unit::Number:
110
137
  return length.value;
@@ -242,6 +269,10 @@ struct Layouter {
242
269
 
243
270
  float layoutFlex(LayoutBox *container, float contentWidth, float definiteHeight) const;
244
271
 
272
+ /** Grid formatting context (explicit/implicit tracks, gaps, auto-placement
273
+ * and item alignment). Returns the used content height. */
274
+ float layoutGrid(LayoutBox *container, float contentWidth, float definiteHeight) const;
275
+
245
276
  /** Flex row main-axis layout, wrapping items into lines when `flex-wrap`
246
277
  * allows it. Returns the used cross size. */
247
278
  float layoutFlexRow(LayoutBox *container, const std::vector<LayoutBox *> &items,
@@ -0,0 +1,374 @@
1
+ /*
2
+ * xbintsc GUI engine — CSS Grid formatting context.
3
+ *
4
+ * The engine deliberately implements a focused subset of grid: a track list
5
+ * (`grid-template-columns/rows` with fixed, `auto`, `fr`, `minmax(...)` and
6
+ * `repeat(...)`), `gap`, row-major auto-placement, simple line placement
7
+ * (`grid-column` / `grid-row`), and item alignment (`align/justify-items`,
8
+ * `align/justify-self`, `place-items`). That is enough for application shells
9
+ * such as a HUD with three columns or a centred overlay card, without turning
10
+ * the engine into a full CSS layout implementation.
11
+ */
12
+
13
+ #include "layout_flow_internal.h"
14
+
15
+ namespace xtgui {
16
+ namespace layout_flow_detail {
17
+
18
+ namespace {
19
+
20
+ struct GridPlacement {
21
+ LayoutBox *box = nullptr;
22
+ int col = 0;
23
+ int col_span = 1;
24
+ int row = 0;
25
+ int row_span = 1;
26
+ bool explicit_col = false;
27
+ bool explicit_row = false;
28
+ };
29
+
30
+ int lineToIndex(int line, int line_count) {
31
+ /* CSS grid lines are 1-based; -1 is the last line and -N counts back. */
32
+ if (line > 0) return line - 1;
33
+ if (line < 0) return line_count + line;
34
+ return 0;
35
+ }
36
+
37
+ float trackPx(const Layouter &layouter, const GridTrack &track, bool maximum, float base,
38
+ float em) {
39
+ const Length &length = maximum ? track.max : track.min;
40
+ if (length.unit == Unit::Auto || length.unit == Unit::Invalid || length.unit == Unit::None)
41
+ return -1.0f;
42
+ return layouter.px(length, base, em, 0.0f);
43
+ }
44
+
45
+ /* One free-cell cursor over a dynamically grown occupancy matrix. */
46
+ struct Occupancy {
47
+ std::vector<std::vector<bool>> cells;
48
+ int columns = 1;
49
+
50
+ void ensure(int row, int col) {
51
+ if ((int)cells.size() <= row) cells.resize((size_t)row + 1);
52
+ for (std::vector<bool> &line : cells)
53
+ if ((int)line.size() < columns) line.resize((size_t)columns, false);
54
+ if ((int)cells[row].size() <= col) cells[row].resize((size_t)col + 1, false);
55
+ }
56
+
57
+ bool free(int row, int col, int row_span, int col_span) const {
58
+ for (int r = row; r < row + row_span; r++) {
59
+ if (r >= (int)cells.size()) continue;
60
+ for (int c = col; c < col + col_span; c++) {
61
+ if (c >= (int)cells[r].size()) continue;
62
+ if (cells[r][c]) return false;
63
+ }
64
+ }
65
+ return true;
66
+ }
67
+
68
+ void mark(int row, int col, int row_span, int col_span) {
69
+ for (int r = row; r < row + row_span; r++) {
70
+ for (int c = col; c < col + col_span; c++) {
71
+ ensure(r, c);
72
+ cells[r][c] = true;
73
+ }
74
+ }
75
+ }
76
+ };
77
+
78
+ bool isGridItem(const LayoutBox *box) {
79
+ return box != nullptr && box->display != Display::None &&
80
+ box->style != nullptr && !Layouter::isAbsoluteChild(box) &&
81
+ !isCollapsibleText(box);
82
+ }
83
+
84
+ } // namespace
85
+
86
+ float Layouter::layoutGrid(LayoutBox *container, float contentWidth,
87
+ float definiteHeight) const {
88
+ const XtStyle &style = *container->style;
89
+ std::vector<LayoutBox *> children;
90
+ for (const std::unique_ptr<LayoutBox> &child : container->children)
91
+ if (isGridItem(child.get())) children.push_back(child.get());
92
+ if (children.empty()) return 0;
93
+
94
+ std::vector<GridTrack> columns = style.grid_columns;
95
+ std::vector<GridTrack> rows = style.grid_rows;
96
+ int columnCount = (int)columns.size();
97
+ if (columnCount < 1) columnCount = 1;
98
+ if ((int)columns.size() < columnCount) columns.push_back(GridTrack{});
99
+
100
+ /* Resolve explicit line numbers far enough to know how many columns exist. */
101
+ std::vector<GridPlacement> placements;
102
+ placements.reserve(children.size());
103
+ int maxExplicitColumn = 0;
104
+ int maxExplicitRow = 0;
105
+ for (LayoutBox *box : children) {
106
+ GridPlacement placement;
107
+ placement.box = box;
108
+ const XtStyle &item = *box->style;
109
+ if (item.grid_column_start != 0 || item.grid_column_end != 0) placement.explicit_col = true;
110
+ if (item.grid_row_start != 0 || item.grid_row_end != 0) placement.explicit_row = true;
111
+ int start = lineToIndex(item.grid_column_start, columnCount + 1);
112
+ int end = item.grid_column_end == 0 ? start + 1
113
+ : lineToIndex(item.grid_column_end, columnCount + 1);
114
+ if (start < 0) start = 0;
115
+ if (end <= start) end = start + 1;
116
+ placement.col = start;
117
+ placement.col_span = end - start;
118
+ if (placement.explicit_col) maxExplicitColumn = std::max(maxExplicitColumn, end);
119
+ int rowStart = lineToIndex(item.grid_row_start, 1 << 20);
120
+ int rowEnd = item.grid_row_end == 0 ? rowStart + 1 : lineToIndex(item.grid_row_end, 1 << 20);
121
+ if (rowStart < 0) rowStart = 0;
122
+ if (rowEnd <= rowStart) rowEnd = rowStart + 1;
123
+ placement.row = rowStart;
124
+ placement.row_span = rowEnd - rowStart;
125
+ if (placement.explicit_row) maxExplicitRow = std::max(maxExplicitRow, rowEnd);
126
+ placements.push_back(placement);
127
+ }
128
+ if (maxExplicitColumn > columnCount) {
129
+ while ((int)columns.size() < maxExplicitColumn) columns.push_back(GridTrack{});
130
+ columnCount = maxExplicitColumn;
131
+ }
132
+
133
+ /* Place explicit items first, then auto-place the rest row-major. */
134
+ Occupancy occupied;
135
+ occupied.columns = columnCount;
136
+ for (GridPlacement &placement : placements) {
137
+ if (!placement.explicit_col && !placement.explicit_row) continue;
138
+ int row = placement.explicit_row ? placement.row : 0;
139
+ int col = placement.explicit_col ? placement.col : 0;
140
+ if (placement.explicit_col && !placement.explicit_row) {
141
+ while (!occupied.free(row, col, placement.row_span, placement.col_span)) row++;
142
+ } else if (!placement.explicit_col && placement.explicit_row) {
143
+ while (!occupied.free(row, col, placement.row_span, placement.col_span)) col++;
144
+ } else {
145
+ while (!occupied.free(row, col, placement.row_span, placement.col_span)) {
146
+ col++;
147
+ if (col + placement.col_span > columnCount) {
148
+ col = 0;
149
+ row++;
150
+ }
151
+ }
152
+ }
153
+ placement.row = row;
154
+ placement.col = col;
155
+ occupied.mark(row, col, placement.row_span, placement.col_span);
156
+ }
157
+ int cursorRow = 0;
158
+ int cursorCol = 0;
159
+ for (GridPlacement &placement : placements) {
160
+ if (placement.explicit_col || placement.explicit_row) continue;
161
+ while (!occupied.free(cursorRow, cursorCol, placement.row_span, placement.col_span)) {
162
+ cursorCol++;
163
+ if (cursorCol + placement.col_span > columnCount) {
164
+ cursorCol = 0;
165
+ cursorRow++;
166
+ }
167
+ }
168
+ placement.row = cursorRow;
169
+ placement.col = cursorCol;
170
+ occupied.mark(cursorRow, cursorCol, placement.row_span, placement.col_span);
171
+ cursorCol += placement.col_span;
172
+ if (cursorCol >= columnCount) {
173
+ cursorCol = 0;
174
+ cursorRow++;
175
+ }
176
+ }
177
+
178
+ /* Measure each item once to learn its intrinsic width/height. */
179
+ std::vector<float> naturalWidth(placements.size(), 0.0f);
180
+ std::vector<float> naturalHeight(placements.size(), 0.0f);
181
+ for (size_t i = 0; i < placements.size(); i++) {
182
+ LayoutBox *box = placements[i].box;
183
+ resolveEdges(box, contentWidth);
184
+ float preferred = preferredContentWidth(box, contentWidth);
185
+ if (preferred < 0) preferred = 0;
186
+ naturalWidth[i] = preferred;
187
+ }
188
+
189
+ /* Resolve column widths. */
190
+ float gapX = px(style.column_gap, contentWidth, style.font_size, 0.0f);
191
+ if (gapX < 0) gapX = 0;
192
+ float gapY = px(style.row_gap, contentWidth, style.font_size, 0.0f);
193
+ if (gapY < 0) gapY = 0;
194
+
195
+ std::vector<float> columnWidth(columns.size(), 0.0f);
196
+ float totalFr = 0;
197
+ for (size_t c = 0; c < columns.size(); c++) {
198
+ totalFr += columns[c].fr;
199
+ float fixed = trackPx(*this, columns[c], true, contentWidth, style.font_size);
200
+ if (columns[c].fr <= 0 && fixed >= 0) columnWidth[c] = fixed;
201
+ if (columns[c].fr <= 0 && fixed < 0) {
202
+ /* Auto track: size to the widest single-column item. */
203
+ float best = 0;
204
+ for (size_t i = 0; i < placements.size(); i++) {
205
+ if (placements[i].col != (int)c || placements[i].col_span != 1) continue;
206
+ LayoutBox *itemBox = placements[i].box;
207
+ float outer = naturalWidth[i] + itemBox->border_left + itemBox->border_right +
208
+ itemBox->padding_left + itemBox->padding_right + itemBox->margin_left +
209
+ itemBox->margin_right;
210
+ if (outer > best) best = outer;
211
+ }
212
+ columnWidth[c] = best;
213
+ }
214
+ }
215
+ if (totalFr <= 0 && columns.size() == 1 && columns[0].fr <= 0) {
216
+ columnWidth[0] = contentWidth;
217
+ }
218
+ if (totalFr > 0) {
219
+ float fixedTotal = gapX * (float)(columns.size() - 1);
220
+ for (size_t c = 0; c < columns.size(); c++)
221
+ if (columns[c].fr <= 0) fixedTotal += columnWidth[c];
222
+ float remaining = contentWidth - fixedTotal;
223
+ if (remaining < 0) remaining = 0;
224
+ for (int pass = 0; pass < 2; pass++) {
225
+ float used = 0;
226
+ for (size_t c = 0; c < columns.size(); c++) {
227
+ if (columns[c].fr <= 0) continue;
228
+ float share = remaining * columns[c].fr / totalFr;
229
+ float minimum = trackPx(*this, columns[c], false, contentWidth, style.font_size);
230
+ if (minimum > share) share = minimum;
231
+ columnWidth[c] = share;
232
+ used += share;
233
+ }
234
+ if (used <= remaining + 0.01f) break;
235
+ /* The minimums forced a deficit; shrink the fr share proportionally. */
236
+ float scale = remaining / used;
237
+ for (size_t c = 0; c < columns.size(); c++)
238
+ if (columns[c].fr > 0) columnWidth[c] *= scale;
239
+ break;
240
+ }
241
+ } else {
242
+ /* Fill the container with auto tracks so a single-cell overlay centres in
243
+ * the whole area rather than hugging its content. */
244
+ float used = gapX * (float)(columns.size() - 1);
245
+ for (float width : columnWidth) used += width;
246
+ float extra = contentWidth - used;
247
+ if (extra > 0) {
248
+ int autos = 0;
249
+ for (const GridTrack &track : columns)
250
+ if (track.fr <= 0 && trackPx(*this, track, true, contentWidth, style.font_size) < 0) autos++;
251
+ if (autos > 0)
252
+ for (size_t c = 0; c < columns.size(); c++)
253
+ if (trackPx(*this, columns[c], true, contentWidth, style.font_size) < 0)
254
+ columnWidth[c] += extra / (float)autos;
255
+ }
256
+ }
257
+
258
+ /* Rows: resolve explicit tracks and grow implicit ones from item heights. */
259
+ int rowCount = maxExplicitRow;
260
+ for (const GridPlacement &placement : placements)
261
+ rowCount = std::max(rowCount, placement.row + placement.row_span);
262
+ if (rowCount < 1) rowCount = 1;
263
+ while ((int)rows.size() < rowCount) rows.push_back(GridTrack{});
264
+ std::vector<float> rowHeight(rows.size(), 0.0f);
265
+ for (size_t r = 0; r < rows.size(); r++) {
266
+ float fixed = trackPx(*this, rows[r], true, contentWidth, style.font_size);
267
+ if (fixed >= 0) rowHeight[r] = fixed;
268
+ }
269
+
270
+ /* Lay each item out at its column width to learn its height. */
271
+ std::vector<float> itemHeight(placements.size(), 0.0f);
272
+ for (size_t i = 0; i < placements.size(); i++) {
273
+ GridPlacement &placement = placements[i];
274
+ LayoutBox *box = placement.box;
275
+ float cellWidth = 0;
276
+ for (int c = placement.col; c < placement.col + placement.col_span && c < columnCount; c++)
277
+ cellWidth += columnWidth[(size_t)c];
278
+ cellWidth += gapX * (float)(placement.col_span - 1);
279
+ float availableWidth = cellWidth - box->margin_left - box->margin_right;
280
+ if (availableWidth < 0) availableWidth = 0;
281
+ float contentAvail = availableWidth - box->border_left - box->border_right -
282
+ box->padding_left - box->padding_right;
283
+ if (contentAvail < 0) contentAvail = 0;
284
+ bool stretch = true;
285
+ AlignItems justify = box->style->has_justify_self ? box->style->justify_self : style.justify_items;
286
+ stretch = justify == AlignItems::Stretch;
287
+ float forced = stretch ? -1.0f : naturalWidth[i];
288
+ if (forced > contentAvail) forced = contentAvail;
289
+ setContainingBlock(box, containingBlockAncestor(box));
290
+ layoutBlock(box, container->content_x, container->content_y, availableWidth, -1, forced, -1,
291
+ true);
292
+ itemHeight[i] = box->height + box->margin_top + box->margin_bottom;
293
+ }
294
+ for (size_t i = 0; i < placements.size(); i++) {
295
+ GridPlacement &placement = placements[i];
296
+ if (trackPx(*this, rows[(size_t)placement.row], true, contentWidth, style.font_size) >= 0)
297
+ continue;
298
+ for (int r = placement.row; r < placement.row + placement.row_span && r < (int)rowHeight.size();
299
+ r++) {
300
+ if (itemHeight[i] > rowHeight[(size_t)r]) rowHeight[(size_t)r] = itemHeight[i];
301
+ }
302
+ }
303
+
304
+ float totalHeight = gapY * (float)(rows.size() - 1);
305
+ for (float value : rowHeight) totalHeight += value;
306
+ if (rows.size() == 1 && definiteHeight >= 0 && definiteHeight > totalHeight)
307
+ totalHeight = definiteHeight;
308
+ if (rows.size() == 1 && definiteHeight >= 0) rowHeight[0] = totalHeight;
309
+
310
+ /* Place the items. */
311
+ std::vector<float> columnX(columnWidth.size(), 0.0f);
312
+ float x = container->content_x;
313
+ for (size_t c = 0; c < columnWidth.size(); c++) {
314
+ columnX[c] = x;
315
+ x += columnWidth[c] + gapX;
316
+ }
317
+ std::vector<float> rowY(rowHeight.size(), 0.0f);
318
+ float y = container->content_y;
319
+ for (size_t r = 0; r < rowHeight.size(); r++) {
320
+ rowY[r] = y;
321
+ y += rowHeight[r] + gapY;
322
+ }
323
+
324
+ for (size_t i = 0; i < placements.size(); i++) {
325
+ GridPlacement &placement = placements[i];
326
+ LayoutBox *box = placement.box;
327
+ float cellX = columnX[(size_t)placement.col];
328
+ float cellY = rowY[(size_t)placement.row];
329
+ float cellW = 0;
330
+ for (int c = placement.col; c < placement.col + placement.col_span && c < columnCount; c++)
331
+ cellW += columnWidth[(size_t)c];
332
+ cellW += gapX * (float)(placement.col_span - 1);
333
+ float cellH = 0;
334
+ for (int r = placement.row; r < placement.row + placement.row_span && r < (int)rowHeight.size();
335
+ r++)
336
+ cellH += rowHeight[(size_t)r];
337
+ cellH += gapY * (float)(placement.row_span - 1);
338
+
339
+ float availW = cellW - box->margin_left - box->margin_right;
340
+ float availH = cellH - box->margin_top - box->margin_bottom;
341
+ if (availW < 0) availW = 0;
342
+ if (availH < 0) availH = 0;
343
+
344
+ AlignItems justify = box->style->has_justify_self ? box->style->justify_self : style.justify_items;
345
+ AlignItems align = box->style->has_align_self ? box->style->align_self : style.align_items;
346
+ bool stretchW = justify == AlignItems::Stretch;
347
+ bool stretchH = align == AlignItems::Stretch && isAuto(box->style->height);
348
+
349
+ float forcedW = stretchW ? -1.0f : naturalWidth[i];
350
+ float forcedH = -1.0f;
351
+ if (stretchH && cellH > 0) {
352
+ float contentH = availH - box->border_top - box->border_bottom - box->padding_top -
353
+ box->padding_bottom;
354
+ if (contentH < 0) contentH = 0;
355
+ forcedH = contentH;
356
+ }
357
+ setContainingBlock(box, containingBlockAncestor(box));
358
+ layoutBlock(box, cellX, cellY, availW, -1, forcedW, forcedH, true);
359
+
360
+ float dx = 0;
361
+ if (justify == AlignItems::Center) dx = (availW - box->width) / 2.0f;
362
+ else if (justify == AlignItems::FlexEnd) dx = availW - box->width;
363
+ float dy = box->margin_top;
364
+ if (align == AlignItems::Center) dy = box->margin_top + (availH - box->height) / 2.0f;
365
+ else if (align == AlignItems::FlexEnd) dy = cellH - box->margin_bottom - box->height;
366
+ if (stretchH) dy = box->margin_top;
367
+ translate(box, dx, dy);
368
+ }
369
+
370
+ return totalHeight;
371
+ }
372
+
373
+ } // namespace layout_flow_detail
374
+ } // namespace xtgui
@@ -54,7 +54,7 @@ enum MediaEvent {
54
54
  * The audio output the decoder writes PCM to.
55
55
  *
56
56
  * The engine implements it with an SDL audio stream (`gui_media.cpp`), which
57
- * keeps SDL out of the optional `media.a`. The fixed format is 48 kHz stereo
57
+ * keeps SDL out of the optional `media.a`/`media.lib`. The fixed format is 48 kHz stereo
58
58
  * float: the decoder resamples every source stream to it with swresample.
59
59
  */
60
60
  class AudioSink {
@@ -7,7 +7,7 @@
7
7
  * The engine knows how to model `<video>`/`<audio>` elements and how to draw
8
8
  * their frames, but it deliberately contains no decoder: FFmpeg lives in the
9
9
  * separate `media` compile extension (`runtime/ext_media/`, linked as
10
- * `media.a`). Keeping the boundary C-only means the backend can be a prebuilt
10
+ * `media.a`, or `media.lib` with the MSVC ABI on Windows). Keeping the boundary C-only means the backend can be a prebuilt
11
11
  * C++ archive that is compiled independently of the engine.
12
12
  *
13
13
  * Registration is push-based: the backend's bridge translation unit is linked
@@ -51,7 +51,7 @@ typedef struct XtMediaApi {
51
51
  void xt_media_install(const XtMediaApi *api);
52
52
 
53
53
  /** Decoder backend entry points, implemented by `runtime/ext_media/media.cpp`
54
- * (inside `media.a`). The bridge references them, which is what makes the
54
+ * (inside `media.a`/`media.lib`). The bridge references them, which is what makes the
55
55
  * linker extract the archive member when the media extension is enabled. */
56
56
  XtMediaPlayerHandle xt_media_backend_open(const char *path, char *error,
57
57
  size_t error_size, void *audio_sink);
@@ -0,0 +1,211 @@
1
+ /*
2
+ * xbintsc GUI engine — `@media` query evaluation.
3
+ *
4
+ * The CSS parser keeps each rule's raw media prelude and this unit decides
5
+ * whether it applies to the current viewport. The subset mirrors what a desktop
6
+ * window can answer: width/height ranges, orientation, hover/pointer class and
7
+ * the two accessibility preferences. Unknown features evaluate to false, which
8
+ * is what a browser does (and keeps e.g. `@media print` blocks inert).
9
+ */
10
+ #include "css_internal.h"
11
+
12
+ #include <cmath>
13
+ #include <string>
14
+ #include <vector>
15
+
16
+ namespace xtgui {
17
+
18
+ namespace {
19
+
20
+ std::string lowerTrim(const std::string &text) { return xt_css_lower(xt_css_trim(text)); }
21
+
22
+ /** Split `text` on the word `and` at nesting depth zero. */
23
+ std::vector<std::string> splitAnd(const std::string &text) {
24
+ std::vector<std::string> parts;
25
+ std::string current;
26
+ int depth = 0;
27
+ for (size_t i = 0; i < text.size();) {
28
+ char c = text[i];
29
+ if (c == '(') depth++;
30
+ else if (c == ')') depth--;
31
+ bool atWord = (c == 'a' || c == 'A') && i + 3 <= text.size() &&
32
+ xt_css_lower(text.substr(i, 3)) == "and" &&
33
+ (i == 0 || xt_is_css_space(text[i - 1])) &&
34
+ (i + 3 == text.size() || xt_is_css_space(text[i + 3]));
35
+ if (atWord && depth == 0) {
36
+ std::string part = xt_css_trim(current);
37
+ if (!part.empty()) parts.push_back(part);
38
+ current.clear();
39
+ i += 3;
40
+ continue;
41
+ }
42
+ current.push_back(c);
43
+ i++;
44
+ }
45
+ std::string part = xt_css_trim(current);
46
+ if (!part.empty()) parts.push_back(part);
47
+ return parts;
48
+ }
49
+
50
+ /** Resolve a media-feature length. `rem`/`em` assume the 16px initial font. */
51
+ bool mediaLength(const std::string &raw, float vw, float vh, float *out) {
52
+ Length length = xt_css_parse_length(raw);
53
+ switch (length.unit) {
54
+ case Unit::Px:
55
+ case Unit::Number:
56
+ *out = length.value;
57
+ return true;
58
+ case Unit::Em:
59
+ case Unit::Rem:
60
+ *out = length.value * 16.0f;
61
+ return true;
62
+ case Unit::Vw:
63
+ *out = vw * length.value / 100.0f;
64
+ return true;
65
+ case Unit::Vh:
66
+ *out = vh * length.value / 100.0f;
67
+ return true;
68
+ default:
69
+ return false;
70
+ }
71
+ }
72
+
73
+ /** Compare `actual` with a feature value, honouring a min-/max- prefix. */
74
+ bool compareLength(const std::string &name, const std::string &rawValue, float actual, float vw,
75
+ float vh) {
76
+ float value = 0.0f;
77
+ if (!mediaLength(rawValue, vw, vh, &value)) return false;
78
+ const bool min = name.rfind("min-", 0) == 0;
79
+ const bool max = name.rfind("max-", 0) == 0;
80
+ if (min) return actual >= value;
81
+ if (max) return actual <= value;
82
+ return std::fabs(actual - value) < 0.01f;
83
+ }
84
+
85
+ bool splitFeature(const std::string &inner, std::string *name, std::string *value) {
86
+ int depth = 0;
87
+ for (size_t i = 0; i < inner.size(); i++) {
88
+ char c = inner[i];
89
+ if (c == '(') depth++;
90
+ else if (c == ')') depth--;
91
+ else if (c == ':' && depth == 0) {
92
+ *name = lowerTrim(inner.substr(0, i));
93
+ *value = lowerTrim(inner.substr(i + 1));
94
+ return true;
95
+ }
96
+ }
97
+ return false;
98
+ }
99
+
100
+ /** `(width >= 600px)` / `(600px <= width)` range syntax. */
101
+ bool evaluateRange(const std::string &inner, float vw, float vh, bool *matched) {
102
+ static const char *const ops[] = {">=", "<=", ">", "<", "="};
103
+ for (const char *op : ops) {
104
+ size_t pos = inner.find(op);
105
+ if (pos == std::string::npos) continue;
106
+ std::string left = lowerTrim(inner.substr(0, pos));
107
+ std::string right = lowerTrim(inner.substr(pos + std::string(op).size()));
108
+ std::string opText(op);
109
+ /* `600px < width` means width > 600px: flip the comparison. */
110
+ bool flipped = left != "width" && left != "height";
111
+ std::string feature = flipped ? right : left;
112
+ std::string valueText = flipped ? left : right;
113
+ float actual = 0.0f;
114
+ if (feature == "width") actual = vw;
115
+ else if (feature == "height") actual = vh;
116
+ else return false;
117
+ float value = 0.0f;
118
+ if (!mediaLength(valueText, vw, vh, &value)) return false;
119
+ if (flipped) {
120
+ if (opText == ">") opText = "<";
121
+ else if (opText == "<") opText = ">";
122
+ else if (opText == ">=") opText = "<=";
123
+ else if (opText == "<=") opText = ">=";
124
+ }
125
+ if (opText == ">=") *matched = actual >= value;
126
+ else if (opText == "<=") *matched = actual <= value;
127
+ else if (opText == ">") *matched = actual > value;
128
+ else if (opText == "<") *matched = actual < value;
129
+ else *matched = std::fabs(actual - value) < 0.01f;
130
+ return true;
131
+ }
132
+ return false;
133
+ }
134
+
135
+ bool evaluateFeature(const std::string &inner, float vw, float vh) {
136
+ bool rangeMatched = false;
137
+ if (evaluateRange(inner, vw, vh, &rangeMatched)) return rangeMatched;
138
+
139
+ std::string name;
140
+ std::string value;
141
+ if (!splitFeature(inner, &name, &value)) return false;
142
+ if (name.empty() || value.empty()) return false;
143
+
144
+ if (name == "width" || name == "min-width" || name == "max-width") {
145
+ return compareLength(name, value, vw, vw, vh);
146
+ }
147
+ if (name == "height" || name == "min-height" || name == "max-height") {
148
+ return compareLength(name, value, vh, vw, vh);
149
+ }
150
+ if (name == "orientation") {
151
+ if (value == "landscape") return vw >= vh;
152
+ if (value == "portrait") return vh > vw;
153
+ return false;
154
+ }
155
+ if (name == "hover" || name == "any-hover") return value == "hover";
156
+ if (name == "pointer" || name == "any-pointer") return value == "fine";
157
+ if (name == "prefers-color-scheme") return value == "light";
158
+ if (name == "prefers-reduced-motion") return value == "no-preference";
159
+ if (name == "prefers-contrast") return value == "no-preference";
160
+ if (name == "scripting") return value == "enabled";
161
+ if (name == "display-mode") return value == "browser";
162
+ return false;
163
+ }
164
+
165
+ } // namespace
166
+
167
+ bool xt_css_media_matches(const std::string &query, float viewport_width, float viewport_height) {
168
+ std::string text = lowerTrim(query);
169
+ if (text.empty()) return true;
170
+
171
+ bool any = false;
172
+ for (const std::string &rawQuery : xt_css_split_commas(text)) {
173
+ std::string part = lowerTrim(rawQuery);
174
+ bool negate = false;
175
+ if (part.rfind("not ", 0) == 0) {
176
+ negate = true;
177
+ part = xt_css_trim(part.substr(4));
178
+ } else if (part.rfind("only ", 0) == 0) {
179
+ part = xt_css_trim(part.substr(5));
180
+ }
181
+ bool matched = true;
182
+ bool first = true;
183
+ for (const std::string &segment : splitAnd(part)) {
184
+ std::string token = xt_css_trim(segment);
185
+ if (token.empty()) continue;
186
+ if (first && token[0] != '(') {
187
+ /* Media type: a desktop window is `screen`, never `print`. */
188
+ if (token == "all" || token == "screen") {
189
+ matched = true;
190
+ } else {
191
+ matched = false;
192
+ }
193
+ } else {
194
+ std::string inner = token;
195
+ if (inner.front() == '(' && inner.back() == ')') {
196
+ inner = xt_css_trim(inner.substr(1, inner.size() - 2));
197
+ }
198
+ if (!evaluateFeature(inner, viewport_width, viewport_height)) matched = false;
199
+ }
200
+ first = false;
201
+ }
202
+ if (negate) matched = !matched;
203
+ if (matched) {
204
+ any = true;
205
+ break;
206
+ }
207
+ }
208
+ return any;
209
+ }
210
+
211
+ } // namespace xtgui