xbintsc 0.5.45 → 0.5.52

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 (286) hide show
  1. package/AGENTS.md +1 -1
  2. package/README.md +5 -4
  3. package/README.zh-CN.md +4 -3
  4. package/dist/src/cli/extensions.d.ts +24 -0
  5. package/dist/src/cli/extensions.js +62 -0
  6. package/dist/src/cli/extensions.js.map +1 -0
  7. package/dist/src/cli/help.d.ts +1 -1
  8. package/dist/src/cli/help.js +3 -1
  9. package/dist/src/cli/help.js.map +1 -1
  10. package/dist/src/cli/hints.js +8 -3
  11. package/dist/src/cli/hints.js.map +1 -1
  12. package/dist/src/cli/main.js +21 -28
  13. package/dist/src/cli/main.js.map +1 -1
  14. package/dist/src/diagnostics/diagnostic.d.ts +3 -1
  15. package/dist/src/diagnostics/diagnostic.js +2 -0
  16. package/dist/src/diagnostics/diagnostic.js.map +1 -1
  17. package/dist/src/driver/build-key.d.ts +2 -0
  18. package/dist/src/driver/build-key.js +1 -0
  19. package/dist/src/driver/build-key.js.map +1 -1
  20. package/dist/src/driver/compiler.js +61 -8
  21. package/dist/src/driver/compiler.js.map +1 -1
  22. package/dist/src/driver/config.d.ts +4 -0
  23. package/dist/src/driver/config.js +2 -0
  24. package/dist/src/driver/config.js.map +1 -1
  25. package/dist/src/driver/link-features.d.ts +37 -0
  26. package/dist/src/driver/link-features.js +123 -0
  27. package/dist/src/driver/link-features.js.map +1 -0
  28. package/dist/src/driver/options.d.ts +10 -0
  29. package/dist/src/driver/runtime-objects.d.ts +5 -0
  30. package/dist/src/driver/runtime-objects.js +20 -1
  31. package/dist/src/driver/runtime-objects.js.map +1 -1
  32. package/dist/src/driver/usage.d.ts +23 -0
  33. package/dist/src/driver/usage.js +353 -0
  34. package/dist/src/driver/usage.js.map +1 -0
  35. package/dist/src/driver/version.d.ts +1 -1
  36. package/dist/src/driver/version.js +1 -1
  37. package/dist/src/extensions/catalog.js +1 -2
  38. package/dist/src/extensions/catalog.js.map +1 -1
  39. package/dist/src/extensions/gui/features.d.ts +34 -0
  40. package/dist/src/extensions/gui/features.js +165 -0
  41. package/dist/src/extensions/gui/features.js.map +1 -0
  42. package/dist/src/extensions/gui/index.js +10 -4
  43. package/dist/src/extensions/gui/index.js.map +1 -1
  44. package/dist/src/extensions/link-feature.d.ts +70 -0
  45. package/dist/src/extensions/link-feature.js +18 -0
  46. package/dist/src/extensions/link-feature.js.map +1 -0
  47. package/dist/src/extensions/registry.d.ts +24 -4
  48. package/dist/src/extensions/registry.js +26 -3
  49. package/dist/src/extensions/registry.js.map +1 -1
  50. package/dist/src/index.d.ts +3 -2
  51. package/dist/src/index.js +0 -1
  52. package/dist/src/index.js.map +1 -1
  53. package/dist/tests/cli/hints.test.js +5 -7
  54. package/dist/tests/cli/hints.test.js.map +1 -1
  55. package/dist/tests/driver/link-features.test.js +105 -0
  56. package/dist/tests/driver/link-features.test.js.map +1 -0
  57. package/dist/tests/driver/usage.test.d.ts +1 -0
  58. package/dist/tests/driver/usage.test.js +88 -0
  59. package/dist/tests/driver/usage.test.js.map +1 -0
  60. package/dist/tests/e2e/gui-audio.test.js +4 -4
  61. package/dist/tests/e2e/gui-audio.test.js.map +1 -1
  62. package/dist/tests/e2e/gui-css-coverage.test.d.ts +9 -0
  63. package/dist/tests/e2e/gui-css-coverage.test.js +333 -0
  64. package/dist/tests/e2e/gui-css-coverage.test.js.map +1 -0
  65. package/dist/tests/e2e/gui-css-features.test.d.ts +6 -0
  66. package/dist/tests/e2e/gui-css-features.test.js +270 -0
  67. package/dist/tests/e2e/gui-css-features.test.js.map +1 -0
  68. package/dist/tests/e2e/gui-effects.test.js +92 -11
  69. package/dist/tests/e2e/gui-effects.test.js.map +1 -1
  70. package/dist/tests/e2e/gui-feature-linking.test.d.ts +9 -0
  71. package/dist/tests/e2e/gui-feature-linking.test.js +68 -0
  72. package/dist/tests/e2e/gui-feature-linking.test.js.map +1 -0
  73. package/dist/tests/e2e/gui-font-face.test.d.ts +10 -0
  74. package/dist/tests/e2e/gui-font-face.test.js +142 -0
  75. package/dist/tests/e2e/gui-font-face.test.js.map +1 -0
  76. package/dist/tests/e2e/gui-fonts.test.d.ts +10 -0
  77. package/dist/tests/e2e/gui-fonts.test.js +150 -0
  78. package/dist/tests/e2e/gui-fonts.test.js.map +1 -0
  79. package/dist/tests/e2e/gui-helpers.d.ts +10 -1
  80. package/dist/tests/e2e/gui-helpers.js +6 -0
  81. package/dist/tests/e2e/gui-helpers.js.map +1 -1
  82. package/dist/tests/e2e/gui-layout.test.js +7 -3
  83. package/dist/tests/e2e/gui-layout.test.js.map +1 -1
  84. package/dist/tests/e2e/gui-media-disabled.test.d.ts +5 -4
  85. package/dist/tests/e2e/gui-media-disabled.test.js +7 -6
  86. package/dist/tests/e2e/gui-media-disabled.test.js.map +1 -1
  87. package/dist/tests/e2e/gui-media.test.d.ts +5 -4
  88. package/dist/tests/e2e/gui-media.test.js +9 -9
  89. package/dist/tests/e2e/gui-media.test.js.map +1 -1
  90. package/dist/tests/e2e/gui-paint.test.js +5 -2
  91. package/dist/tests/e2e/gui-paint.test.js.map +1 -1
  92. package/dist/tests/e2e/gui-shaping.test.d.ts +5 -0
  93. package/dist/tests/e2e/gui-shaping.test.js +47 -0
  94. package/dist/tests/e2e/gui-shaping.test.js.map +1 -0
  95. package/dist/tests/e2e/gui-track-sizing.test.d.ts +6 -0
  96. package/dist/tests/e2e/gui-track-sizing.test.js +173 -0
  97. package/dist/tests/e2e/gui-track-sizing.test.js.map +1 -0
  98. package/dist/tests/e2e/gui-transform.test.js +3 -2
  99. package/dist/tests/e2e/gui-transform.test.js.map +1 -1
  100. package/dist/tests/e2e/gui-webgl-pipeline-cache.test.d.ts +18 -0
  101. package/dist/tests/e2e/gui-webgl-pipeline-cache.test.js +120 -0
  102. package/dist/tests/e2e/gui-webgl-pipeline-cache.test.js.map +1 -0
  103. package/dist/tests/extensions/gui-features.test.d.ts +1 -0
  104. package/dist/tests/extensions/gui-features.test.js +175 -0
  105. package/dist/tests/extensions/gui-features.test.js.map +1 -0
  106. package/doc/ai/cli.md +5 -1
  107. package/doc/ai/extensions.md +56 -26
  108. package/doc/ai/troubleshooting.md +10 -7
  109. package/doc/ai/zh-CN/cli.md +5 -1
  110. package/doc/ai/zh-CN/extensions.md +48 -22
  111. package/doc/ai/zh-CN/troubleshooting.md +6 -5
  112. package/doc/gui/animation.md +39 -9
  113. package/doc/gui/api.md +2 -1
  114. package/doc/gui/build.md +137 -19
  115. package/doc/gui/canvas.md +1 -1
  116. package/doc/gui/dom.md +20 -4
  117. package/doc/gui/known-issues.md +63 -26
  118. package/doc/gui/layout.md +31 -8
  119. package/doc/gui/media.md +13 -7
  120. package/doc/gui/rendering.md +114 -39
  121. package/doc/gui/runtime.md +5 -0
  122. package/doc/gui/webgl.md +24 -6
  123. package/doc/gui.md +110 -47
  124. package/doc/implemented/cli.md +2 -0
  125. package/doc/implemented/extensions.md +9 -3
  126. package/doc/npm-package.md +4 -4
  127. package/doc/xbintsc.config.schema.json +10 -0
  128. package/doc/zh-CN/gui/animation.md +33 -10
  129. package/doc/zh-CN/gui/api.md +2 -1
  130. package/doc/zh-CN/gui/build.md +110 -16
  131. package/doc/zh-CN/gui/canvas.md +1 -1
  132. package/doc/zh-CN/gui/dom.md +16 -3
  133. package/doc/zh-CN/gui/known-issues.md +45 -15
  134. package/doc/zh-CN/gui/layout.md +23 -6
  135. package/doc/zh-CN/gui/media.md +11 -6
  136. package/doc/zh-CN/gui/rendering.md +84 -26
  137. package/doc/zh-CN/gui/runtime.md +3 -0
  138. package/doc/zh-CN/gui/webgl.md +3 -3
  139. package/doc/zh-CN/gui.md +92 -41
  140. package/doc/zh-CN/implemented/cli.md +2 -0
  141. package/doc/zh-CN/implemented/extensions.md +9 -3
  142. package/doc/zh-CN/npm-package.md +4 -3
  143. package/package.json +7 -7
  144. package/runtime/ext_gui/animation_values.cpp +425 -0
  145. package/runtime/ext_gui/animation_values.h +64 -0
  146. package/runtime/ext_gui/browser.cpp +22 -15
  147. package/runtime/ext_gui/browser_loop.cpp +13 -1
  148. package/runtime/ext_gui/canvas.h +1 -1
  149. package/runtime/ext_gui/canvas_raster.cpp +1 -1
  150. package/runtime/ext_gui/canvas_text.cpp +1 -1
  151. package/runtime/ext_gui/css.cpp +172 -21
  152. package/runtime/ext_gui/css.h +75 -4
  153. package/runtime/ext_gui/css_match.cpp +4 -0
  154. package/runtime/ext_gui/css_sheet.cpp +218 -2
  155. package/runtime/ext_gui/document.cpp +42 -192
  156. package/runtime/ext_gui/document.h +25 -12
  157. package/runtime/ext_gui/document_animation.cpp +428 -0
  158. package/runtime/ext_gui/dom_api_canvas.cpp +15 -8
  159. package/runtime/ext_gui/dom_api_canvas_extra.cpp +44 -20
  160. package/runtime/ext_gui/dom_api_canvas_image.cpp +3 -1
  161. package/runtime/ext_gui/dom_api_node_read.cpp +10 -0
  162. package/runtime/ext_gui/dom_api_offscreen.cpp +3 -1
  163. package/runtime/ext_gui/dom_api_style.cpp +7 -0
  164. package/runtime/ext_gui/dom_api_webgl_internal.h +4 -0
  165. package/runtime/ext_gui/dom_api_webgl_source.cpp +5 -2
  166. package/runtime/ext_gui/effect_values.cpp +245 -21
  167. package/runtime/ext_gui/gpu_bridge.c +28 -0
  168. package/runtime/ext_gui/gpu_feature.cpp +30 -0
  169. package/runtime/ext_gui/gpu_shader.cpp +22 -0
  170. package/runtime/ext_gui/gpu_shader_api.h +50 -0
  171. package/runtime/ext_gui/gradient_values.cpp +24 -0
  172. package/runtime/ext_gui/grid_values.cpp +23 -0
  173. package/runtime/ext_gui/gui.cpp +6 -37
  174. package/runtime/ext_gui/gui_canvas.cpp +14 -6
  175. package/runtime/ext_gui/gui_cursor.cpp +50 -0
  176. package/runtime/ext_gui/gui_engine.h +1 -18
  177. package/runtime/ext_gui/gui_events.cpp +19 -6
  178. package/runtime/ext_gui/gui_internal.h +3 -0
  179. package/runtime/ext_gui/gui_webgl.cpp +25 -10
  180. package/runtime/ext_gui/image_api.cpp +18 -0
  181. package/runtime/ext_gui/image_api.h +43 -0
  182. package/runtime/ext_gui/image_bitmap_browser.cpp +20 -11
  183. package/runtime/ext_gui/image_bridge.c +22 -0
  184. package/runtime/ext_gui/image_feature.cpp +107 -0
  185. package/runtime/ext_gui/inline_svg.cpp +95 -8
  186. package/runtime/ext_gui/inline_svg.h +5 -1
  187. package/runtime/ext_gui/layout.cpp +15 -9
  188. package/runtime/ext_gui/layout.h +8 -2
  189. package/runtime/ext_gui/layout_flex.cpp +134 -29
  190. package/runtime/ext_gui/layout_flow.cpp +58 -7
  191. package/runtime/ext_gui/layout_flow_internal.h +39 -4
  192. package/runtime/ext_gui/layout_grid.cpp +31 -0
  193. package/runtime/ext_gui/layout_inline.cpp +26 -2
  194. package/runtime/ext_gui/layout_vertical.cpp +196 -0
  195. package/runtime/ext_gui/media.cpp +4 -2
  196. package/runtime/ext_gui/media.h +3 -3
  197. package/runtime/ext_gui/media_api.h +7 -6
  198. package/runtime/ext_gui/paint.cpp +67 -9
  199. package/runtime/ext_gui/paint.h +61 -8
  200. package/runtime/ext_gui/paint_backdrop.cpp +211 -0
  201. package/runtime/ext_gui/paint_background.cpp +175 -97
  202. package/runtime/ext_gui/paint_effects.cpp +12 -6
  203. package/runtime/ext_gui/paint_internal.h +27 -0
  204. package/runtime/ext_gui/paint_outline.cpp +44 -0
  205. package/runtime/ext_gui/paint_shadow.cpp +368 -0
  206. package/runtime/ext_gui/renderer.cpp +15 -7
  207. package/runtime/ext_gui/renderer.h +11 -2
  208. package/runtime/ext_gui/renderer_backdrop.cpp +374 -0
  209. package/runtime/ext_gui/renderer_bitmap.cpp +82 -0
  210. package/runtime/ext_gui/renderer_gradient.cpp +51 -17
  211. package/runtime/ext_gui/renderer_image.cpp +19 -7
  212. package/runtime/ext_gui/renderer_internal.h +21 -0
  213. package/runtime/ext_gui/renderer_layer.cpp +37 -6
  214. package/runtime/ext_gui/renderer_text.cpp +2 -1
  215. package/runtime/ext_gui/stb_truetype.h +5077 -0
  216. package/runtime/ext_gui/style.cpp +62 -8
  217. package/runtime/ext_gui/style.h +111 -4
  218. package/runtime/ext_gui/style_cascade.cpp +83 -0
  219. package/runtime/ext_gui/style_internal.h +13 -1
  220. package/runtime/ext_gui/style_length.cpp +92 -0
  221. package/runtime/ext_gui/style_print.cpp +83 -2
  222. package/runtime/ext_gui/style_svg.cpp +40 -0
  223. package/runtime/ext_gui/style_text.cpp +302 -0
  224. package/runtime/ext_gui/style_ui.cpp +150 -0
  225. package/runtime/ext_gui/style_values.cpp +76 -62
  226. package/runtime/ext_gui/style_values_internal.h +23 -0
  227. package/runtime/ext_gui/text.cpp +27 -499
  228. package/runtime/ext_gui/text.h +18 -9
  229. package/runtime/ext_gui/text_api.h +45 -0
  230. package/runtime/ext_gui/text_bridge.c +23 -0
  231. package/runtime/ext_gui/text_cache.cpp +12 -3
  232. package/runtime/ext_gui/text_font_db.cpp +427 -0
  233. package/runtime/ext_gui/text_font_paths.cpp +250 -0
  234. package/runtime/ext_gui/text_font_paths.h +39 -0
  235. package/runtime/ext_gui/text_font_sfnt.cpp +396 -0
  236. package/runtime/ext_gui/text_font_sfnt.h +44 -0
  237. package/runtime/ext_gui/text_fonts.cpp +348 -0
  238. package/runtime/ext_gui/text_fonts.h +78 -0
  239. package/runtime/ext_gui/text_fonts_internal.h +77 -0
  240. package/runtime/ext_gui/text_glyph_cache.cpp +2 -2
  241. package/runtime/ext_gui/text_hb.cpp +438 -0
  242. package/runtime/ext_gui/text_stb.cpp +369 -0
  243. package/runtime/ext_gui/transform.cpp +107 -9
  244. package/runtime/ext_gui/transform.h +5 -0
  245. package/runtime/ext_gui/webgl_api.cpp +19 -0
  246. package/runtime/ext_gui/webgl_api.h +53 -0
  247. package/runtime/ext_gui/webgl_bridge.c +25 -0
  248. package/runtime/ext_gui/webgl_draw_setup.cpp +42 -1
  249. package/runtime/ext_gui/webgl_feature.cpp +82 -0
  250. package/runtime/ext_gui/webgl_feature.h +28 -0
  251. package/runtime/ext_gui/webgl_msl.cpp +41 -0
  252. package/runtime/ext_gui/webgl_msl.h +6 -0
  253. package/runtime/ext_gui/webgl_shader.cpp +40 -32
  254. package/runtime/ext_gui/window.cpp +7 -7
  255. package/runtime/ext_media/decode_audio.cpp +1 -1
  256. package/runtime/ext_media/media.cpp +1 -1
  257. package/runtime/ext_media/media_bridge.c +7 -7
  258. package/scripts/build-gui.ts +97 -98
  259. package/scripts/check-file-length.ts +1 -0
  260. package/scripts/gui-build-options.ts +122 -0
  261. package/src/cli/extensions.ts +72 -0
  262. package/src/cli/help.ts +3 -1
  263. package/src/cli/hints.ts +9 -3
  264. package/src/cli/main.ts +21 -27
  265. package/src/diagnostics/diagnostic.ts +2 -0
  266. package/src/driver/build-key.ts +3 -0
  267. package/src/driver/compiler.ts +63 -8
  268. package/src/driver/config.ts +6 -0
  269. package/src/driver/link-features.ts +163 -0
  270. package/src/driver/options.ts +10 -0
  271. package/src/driver/runtime-objects.ts +26 -1
  272. package/src/driver/usage.ts +376 -0
  273. package/src/driver/version.ts +1 -1
  274. package/src/extensions/catalog.ts +1 -2
  275. package/src/extensions/gui/features.ts +166 -0
  276. package/src/extensions/gui/index.ts +10 -4
  277. package/src/extensions/link-feature.ts +72 -0
  278. package/src/extensions/registry.ts +45 -4
  279. package/src/index.ts +3 -2
  280. package/dist/src/extensions/media/index.d.ts +0 -28
  281. package/dist/src/extensions/media/index.js +0 -59
  282. package/dist/src/extensions/media/index.js.map +0 -1
  283. package/dist/tests/extensions/media.test.js +0 -63
  284. package/dist/tests/extensions/media.test.js.map +0 -1
  285. package/src/extensions/media/index.ts +0 -65
  286. /package/dist/tests/{extensions/media.test.d.ts → driver/link-features.test.d.ts} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gui-css-features.test.js","sourceRoot":"","sources":["../../../tests/e2e/gui-css-features.test.ts"],"names":[],"mappings":"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"}
@@ -130,15 +130,16 @@ describe.skipIf(!guiAvailable)("gui extension — effects", () => {
130
130
  const list = stdout.slice(stdout.indexOf("list-start"), stdout.indexOf("list-end"));
131
131
  expect(value("image")).toContain("radial-gradient()");
132
132
  expect(value("image")).toContain("linear-gradient()");
133
- // The radial layer is one rasterised gradient carrying its stops; the linear
134
- // layer is still painted as solid bands.
133
+ // Both layers are one rasterised gradient carrying its stops: a band walk
134
+ // would composite a translucent stop once per band and cannot place a stop
135
+ // narrower than a band.
135
136
  expect(list).toContain("gradient=radial");
137
+ expect(list).toContain("gradient=linear");
136
138
  expect(list).toContain("#ff0000ff");
137
139
  expect(list).toContain("#00ff00ff");
138
140
  expect(list).toMatch(/#0000[0-9a-f]{2}ff/);
139
- // Eighteen linear strips plus the background colour: the gradient image is
140
- // not a stack of rectangles.
141
- expect(Number(value("count"))).toBe(19);
141
+ // Only the background colour is a rectangle: the gradient layers are images.
142
+ expect(Number(value("count"))).toBe(1);
142
143
  });
143
144
  it("rasterises a translucent radial vignette as one gradient image", () => {
144
145
  const { value, stdout } = harness.compileAndRun("vignette", `
@@ -210,10 +211,13 @@ describe.skipIf(!guiAvailable)("gui extension — effects", () => {
210
211
  const list = stdout.slice(stdout.indexOf("list-start"), stdout.indexOf("list-end"));
211
212
  // The computed value keeps the repeating function name ...
212
213
  expect(value("image")).toBe("repeating-linear-gradient()");
213
- // ... and the whole 100px box is tiled: a 20% period gives five red and
214
- // five blue bands, not one ramp that holds the final colour.
215
- expect((list.match(/#ff0000ff/g) ?? []).length).toBeGreaterThan(4);
216
- expect((list.match(/#0000ffff/g) ?? []).length).toBeGreaterThan(4);
214
+ // ... and the ramp is one per-pixel gradient image carrying both stops and
215
+ // the period the renderer tiles: a 20% period repeats five times over the
216
+ // 100px box, so the dump's stops stop at 0.2 rather than holding at 1.0.
217
+ expect(list).toContain("gradient=repeating-linear");
218
+ expect(list).toContain("#ff0000ff@0.0000");
219
+ expect(list).toContain("#0000ffff@0.1000");
220
+ expect(list).toContain("#0000ffff@0.2000");
217
221
  });
218
222
  it("resolves pixel offsets in repeating gradients", () => {
219
223
  const { value, stdout } = harness.compileAndRun("repeating-gradient-px", `
@@ -243,8 +247,85 @@ describe.skipIf(!guiAvailable)("gui extension — effects", () => {
243
247
  `);
244
248
  const list = stdout.slice(stdout.indexOf("list-start"), stdout.indexOf("list-end"));
245
249
  expect(value("image")).toBe("repeating-linear-gradient()");
246
- expect((list.match(/#123456ff/g) ?? []).length).toBeGreaterThan(4);
247
- expect((list.match(/#abcdefff/g) ?? []).length).toBeGreaterThan(4);
250
+ // 10px of a 100px line is 0.1: pixel offsets resolve against the gradient
251
+ // line exactly like percentages, and become the tiling period.
252
+ expect(list).toContain("gradient=repeating-linear");
253
+ expect(list).toContain("#123456ff@0.1000");
254
+ expect(list).toContain("#abcdefff@0.2000");
255
+ });
256
+ it("resolves percentages inside calc() gradient stops against the gradient line", () => {
257
+ const { value, stdout } = harness.compileAndRun("gradient-calc-offsets", `
258
+ import { createWindow, run } from "gui";
259
+
260
+ const HTML = \`
261
+ <html><head><style>
262
+ body { margin: 0; }
263
+ #c {
264
+ width: 100px; height: 20px;
265
+ background: linear-gradient(90deg,
266
+ #ff0000 0 calc(50% - 1px), #0000ff calc(50% - 1px) 100%);
267
+ }
268
+ </style></head><body><div id="c"></div></body></html>
269
+ \`;
270
+
271
+ const win = createWindow({ title: "gradient-calc-offsets", width: 400, height: 300 });
272
+ win.on("ready", () => {
273
+ console.log("image=" + win.computedStyle("#c", "background-image"));
274
+ console.log("list-start");
275
+ console.log(win.paintList());
276
+ console.log("list-end");
277
+ win.close();
278
+ });
279
+ win.loadHTML(HTML);
280
+ run();
281
+ `);
282
+ const list = stdout.slice(stdout.indexOf("list-start"), stdout.indexOf("list-end"));
283
+ expect(value("image")).toBe("linear-gradient()");
284
+ // 50% - 1px of a 100px line is 49px, i.e. 0.49 — not 1/3 and 2/3, which is
285
+ // what resolving the `%` against a zero base (=-1px, then re-distributed as
286
+ // an omitted offset) used to produce.
287
+ expect(list).toContain("#ff0000ff@0.4900");
288
+ expect(list).toContain("#0000ffff@0.4900");
289
+ expect(list).toContain("#0000ffff@1.0000");
290
+ expect(list).not.toContain("@0.3333");
291
+ expect(list).not.toContain("@0.6667");
292
+ });
293
+ it("keeps a repeating 1px divider a divider, not a solid band", () => {
294
+ const { value, stdout } = harness.compileAndRun("gradient-hairline", `
295
+ import { createWindow, run } from "gui";
296
+
297
+ const HTML = \`
298
+ <html><head><style>
299
+ body { margin: 0; }
300
+ #h {
301
+ width: 372px; height: 17px;
302
+ background: repeating-linear-gradient(90deg,
303
+ transparent 0 calc(10% - 1px), rgba(4, 7, 11, 0.65) calc(10% - 1px) 10%);
304
+ }
305
+ </style></head><body><div id="h"></div></body></html>
306
+ \`;
307
+
308
+ const win = createWindow({ title: "gradient-hairline", width: 600, height: 300 });
309
+ win.on("ready", () => {
310
+ console.log("image=" + win.computedStyle("#h", "background-image"));
311
+ console.log("count=" + win.paintCount());
312
+ console.log("list-start");
313
+ console.log(win.paintList());
314
+ console.log("list-end");
315
+ win.close();
316
+ });
317
+ win.loadHTML(HTML);
318
+ run();
319
+ `);
320
+ const list = stdout.slice(stdout.indexOf("list-start"), stdout.indexOf("list-end"));
321
+ expect(value("image")).toBe("repeating-linear-gradient()");
322
+ // One gradient image, not a rectangle per band ...
323
+ expect(list).toContain("gradient=repeating-linear");
324
+ expect(Number(value("count"))).toBe(0);
325
+ // ... and the 1px stop keeps its position instead of landing at 1/3, 2/3.
326
+ expect(list).toContain("#00000000@0.0973");
327
+ expect(list).toContain("#04070ba6@0.0973");
328
+ expect(list).toContain("#04070ba6@0.1000");
248
329
  });
249
330
  it("tiles repeating radial gradients", () => {
250
331
  const { value, stdout } = harness.compileAndRun("repeating-radial-gradient", `
@@ -1 +1 @@
1
- {"version":3,"file":"gui-effects.test.js","sourceRoot":"","sources":["../../../tests/e2e/gui-effects.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gui-effects.test.js","sourceRoot":"","sources":["../../../tests/e2e/gui-effects.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * End-to-end proof that optional link features really are symbol-level: a
3
+ * DOM-only GUI program must not contain FFmpeg or glslang, while a WebGL or
4
+ * media program must.
5
+ *
6
+ * These tests only *build*; they never open a window, so they do not need a GPU.
7
+ * They still need the prebuilt `gui.a`/`gui.lib`, hence `guiAvailable`.
8
+ */
9
+ export {};
@@ -0,0 +1,68 @@
1
+ /**
2
+ * End-to-end proof that optional link features really are symbol-level: a
3
+ * DOM-only GUI program must not contain FFmpeg or glslang, while a WebGL or
4
+ * media program must.
5
+ *
6
+ * These tests only *build*; they never open a window, so they do not need a GPU.
7
+ * They still need the prebuilt `gui.a`/`gui.lib`, hence `guiAvailable`.
8
+ */
9
+ import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
10
+ import { tmpdir } from "node:os";
11
+ import { join } from "node:path";
12
+ import { describe, expect, it } from "vitest";
13
+ import { build } from "../../src/driver/compiler.js";
14
+ import { findRuntimeLibrary } from "../../src/driver/runtime-lib.js";
15
+ import { createDefaultRegistry } from "../../src/extensions/registry.js";
16
+ import { guiExtension } from "../../src/extensions/gui/index.js";
17
+ import { guiAvailable } from "./gui-helpers.js";
18
+ /** Build one program against `gui` and return its binary. */
19
+ function buildBinary(name, source) {
20
+ const directory = mkdtempSync(join(tmpdir(), `xbintsc-link-${name}-`));
21
+ try {
22
+ const entry = join(directory, "app.ts");
23
+ writeFileSync(entry, source);
24
+ const result = build(entry, {
25
+ emit: "exe",
26
+ outDir: join(directory, "out"),
27
+ cacheDir: join(directory, ".cache"),
28
+ extensions: createDefaultRegistry().register(guiExtension),
29
+ });
30
+ expect(result.diagnostics.filter((diagnostic) => diagnostic.category === "error")).toEqual([]);
31
+ return readFileSync(result.outputPath);
32
+ }
33
+ finally {
34
+ rmSync(directory, { recursive: true, force: true });
35
+ }
36
+ }
37
+ /** Whether the binary contains an ASCII marker from a statically linked library. */
38
+ function contains(binary, marker) {
39
+ return binary.includes(Buffer.from(marker));
40
+ }
41
+ const WINDOW = `import { createWindow } from "gui";
42
+ const win = createWindow({ title: "link features", width: 120, height: 80 });
43
+ `;
44
+ describe.skipIf(!guiAvailable)("link features are selected per program", () => {
45
+ it("leaves FFmpeg, glslang and FreeType out of a DOM-only program", () => {
46
+ const binary = buildBinary("dom", `${WINDOW}win.loadHTML("<div>hello</div>");`);
47
+ expect(contains(binary, "glslang initialization failed")).toBe(false);
48
+ expect(contains(binary, "matroska")).toBe(false);
49
+ expect(contains(binary, "FREETYPE_PROPERTIES")).toBe(false);
50
+ });
51
+ it("links glslang when the program may create a WebGL context", () => {
52
+ const binary = buildBinary("webgl", `${WINDOW}const canvas: any = win.document.createElement("canvas");
53
+ canvas.getContext("webgl2");
54
+ `);
55
+ expect(contains(binary, "glslang initialization failed")).toBe(true);
56
+ });
57
+ it("links FreeType when the program may render non-ASCII text", () => {
58
+ const binary = buildBinary("shaping", `${WINDOW}win.loadHTML("<div>中文</div>");`);
59
+ expect(contains(binary, "FREETYPE_PROPERTIES")).toBe(true);
60
+ });
61
+ it("links FFmpeg when the program may play a media element", () => {
62
+ if (findRuntimeLibrary("media") === undefined)
63
+ return;
64
+ const binary = buildBinary("media", `${WINDOW}win.loadHTML("<video src='x.mp4'></video>");`);
65
+ expect(contains(binary, "matroska")).toBe(true);
66
+ });
67
+ });
68
+ //# sourceMappingURL=gui-feature-linking.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gui-feature-linking.test.js","sourceRoot":"","sources":["../../../tests/e2e/gui-feature-linking.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * GUI e2e: author `@font-face` rules load real local font files.
3
+ *
4
+ * The program is spawned with the suite's work directory as CWD, so a relative
5
+ * `src: url("./fonts/…")` exercises the documented `file:` resolution. The same
6
+ * measurements run once with the default (auto-selected) shaping backend and
7
+ * once with `--no-feature shaping`, because custom files may be TrueType (both
8
+ * backends) or CFF (shaping only).
9
+ */
10
+ export {};
@@ -0,0 +1,142 @@
1
+ /**
2
+ * GUI e2e: author `@font-face` rules load real local font files.
3
+ *
4
+ * The program is spawned with the suite's work directory as CWD, so a relative
5
+ * `src: url("./fonts/…")` exercises the documented `file:` resolution. The same
6
+ * measurements run once with the default (auto-selected) shaping backend and
7
+ * once with `--no-feature shaping`, because custom files may be TrueType (both
8
+ * backends) or CFF (shaping only).
9
+ */
10
+ import { copyFileSync, existsSync, mkdirSync } from "node:fs";
11
+ import { join } from "node:path";
12
+ import { pathToFileURL } from "node:url";
13
+ import { afterAll, beforeAll, describe, expect, it } from "vitest";
14
+ import { createGuiHarness, guiAvailable } from "./gui-helpers.js";
15
+ const harness = createGuiHarness();
16
+ /** A serif fixture whose regular and bold faces are visibly different. */
17
+ function detectCustomFonts() {
18
+ const pairs = [
19
+ [
20
+ "/System/Library/Fonts/Supplemental/Georgia.ttf",
21
+ "/System/Library/Fonts/Supplemental/Georgia Bold.ttf",
22
+ ],
23
+ [
24
+ "/usr/share/fonts/truetype/dejavu/DejaVuSerif.ttf",
25
+ "/usr/share/fonts/truetype/dejavu/DejaVuSerif-Bold.ttf",
26
+ ],
27
+ [
28
+ "/usr/share/fonts/TTF/DejaVuSerif.ttf",
29
+ "/usr/share/fonts/TTF/DejaVuSerif-Bold.ttf",
30
+ ],
31
+ [
32
+ "/usr/share/fonts/truetype/liberation/LiberationSerif-Regular.ttf",
33
+ "/usr/share/fonts/truetype/liberation/LiberationSerif-Bold.ttf",
34
+ ],
35
+ ["C:\\Windows\\Fonts\\georgia.ttf", "C:\\Windows\\Fonts\\georgiab.ttf"],
36
+ ["C:\\Windows\\Fonts\\times.ttf", "C:\\Windows\\Fonts\\timesbd.ttf"],
37
+ ];
38
+ for (const [regular, bold] of pairs) {
39
+ if (existsSync(regular) && existsSync(bold))
40
+ return { regular, bold };
41
+ }
42
+ return undefined;
43
+ }
44
+ const customFonts = detectCustomFonts();
45
+ function sampleHtml(fileUrl) {
46
+ return `<html><head><style>
47
+ body { margin: 0; }
48
+ .sample { display: inline-block; white-space: nowrap; font-size: 40px; }
49
+ @font-face {
50
+ font-family: "Xt Relative";
51
+ src: local("No Such Local Font"),
52
+ url("./fonts/absent.woff2") format("woff2"),
53
+ url("./fonts/custom-regular.ttf") format("truetype");
54
+ font-weight: 400;
55
+ }
56
+ @font-face {
57
+ font-family: "Xt Relative";
58
+ src: url("./fonts/custom-bold.ttf") format("truetype");
59
+ font-weight: 700;
60
+ }
61
+ @font-face {
62
+ font-family: "Xt File";
63
+ src: url("${fileUrl}");
64
+ }
65
+ @font-face {
66
+ font-family: "Xt Missing";
67
+ src: url("./fonts/does-not-exist.ttf");
68
+ }
69
+ #regular { font-family: "Xt Relative"; font-weight: 400; }
70
+ #bold { font-family: "Xt Relative"; font-weight: 700; }
71
+ #file { font-family: "Xt File"; }
72
+ #missing { font-family: "Xt Missing", sans-serif; }
73
+ #control { font-family: sans-serif; }
74
+ </style></head><body>
75
+ <div id="regular" class="sample">mmmmmmmmmm</div>
76
+ <div id="bold" class="sample">mmmmmmmmmm</div>
77
+ <div id="file" class="sample">mmmmmmmmmm</div>
78
+ <div id="missing" class="sample">mmmmmmmmmm</div>
79
+ <div id="control" class="sample">mmmmmmmmmm</div>
80
+ </body></html>`;
81
+ }
82
+ function measure(options) {
83
+ const fileUrl = pathToFileURL(join(harness.workdir, "fonts", "custom-regular.ttf")).href;
84
+ const html = sampleHtml(fileUrl);
85
+ const { value } = harness.compileAndRun(options.name, `
86
+ import { createWindow, run } from "gui";
87
+ const HTML = ${JSON.stringify(html)};
88
+ const win = createWindow({ title: "font-face", width: 900, height: 500 });
89
+ win.on("ready", () => {
90
+ console.log("regular=" + win.getBoundingClientRect("#regular").width);
91
+ console.log("bold=" + win.getBoundingClientRect("#bold").width);
92
+ console.log("file=" + win.getBoundingClientRect("#file").width);
93
+ console.log("missing=" + win.getBoundingClientRect("#missing").width);
94
+ console.log("control=" + win.getBoundingClientRect("#control").width);
95
+ win.close();
96
+ });
97
+ win.loadHTML(HTML);
98
+ run();
99
+ `, {
100
+ cwd: harness.workdir,
101
+ autocloseMs: 4000,
102
+ ...(options.features !== undefined ? { features: options.features } : {}),
103
+ ...(options.noFeatures !== undefined ? { noFeatures: options.noFeatures } : {}),
104
+ });
105
+ return {
106
+ regular: Number(value("regular")),
107
+ bold: Number(value("bold")),
108
+ file: Number(value("file")),
109
+ missing: Number(value("missing")),
110
+ control: Number(value("control")),
111
+ };
112
+ }
113
+ function expectCustomFonts(result) {
114
+ expect(result.regular).toBeGreaterThan(0);
115
+ // The custom family is a serif fixture; if @font-face had not resolved, the
116
+ // element would have measured exactly like the generic sans control.
117
+ expect(Math.abs(result.regular - result.control)).toBeGreaterThan(1);
118
+ // The 700 descriptor selects the bold file rather than reusing the 400 face.
119
+ expect(result.bold).toBeGreaterThan(result.regular);
120
+ // An absolute `file:` URL resolves to the same regular face.
121
+ expect(result.file).toBeCloseTo(result.regular, 3);
122
+ // A family whose only source is missing falls through to the next family.
123
+ expect(result.missing).toBeCloseTo(result.control, 3);
124
+ }
125
+ describe.skipIf(!guiAvailable)("gui extension — author @font-face", () => {
126
+ beforeAll(() => {
127
+ harness.setup();
128
+ if (customFonts !== undefined) {
129
+ mkdirSync(join(harness.workdir, "fonts"), { recursive: true });
130
+ copyFileSync(customFonts.regular, join(harness.workdir, "fonts", "custom-regular.ttf"));
131
+ copyFileSync(customFonts.bold, join(harness.workdir, "fonts", "custom-bold.ttf"));
132
+ }
133
+ });
134
+ afterAll(() => harness.cleanup());
135
+ it.skipIf(customFonts === undefined)("loads relative and file: sources through stb_truetype", () => {
136
+ expectCustomFonts(measure({ name: "font-face-stb", noFeatures: ["shaping"] }));
137
+ });
138
+ it.skipIf(customFonts === undefined)("loads the same sources through the shaping backend", () => {
139
+ expectCustomFonts(measure({ name: "font-face-shaping", features: ["shaping"] }));
140
+ });
141
+ });
142
+ //# sourceMappingURL=gui-font-face.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gui-font-face.test.js","sourceRoot":"","sources":["../../../tests/e2e/gui-font-face.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * GUI e2e: CSS `font-family` / `font-weight` select real installed faces.
3
+ *
4
+ * The assertions are made through layout widths, which is what a page actually
5
+ * sees: a bold face with wider advances makes the inline-block wider, and two
6
+ * different families lay the same text out differently. The suites pick a
7
+ * family whose bold face exists on the host, so a host without one skips them
8
+ * instead of asserting a synthetic-bold behaviour the engine does not have.
9
+ */
10
+ export {};
@@ -0,0 +1,150 @@
1
+ /**
2
+ * GUI e2e: CSS `font-family` / `font-weight` select real installed faces.
3
+ *
4
+ * The assertions are made through layout widths, which is what a page actually
5
+ * sees: a bold face with wider advances makes the inline-block wider, and two
6
+ * different families lay the same text out differently. The suites pick a
7
+ * family whose bold face exists on the host, so a host without one skips them
8
+ * instead of asserting a synthetic-bold behaviour the engine does not have.
9
+ */
10
+ import { existsSync } from "node:fs";
11
+ import { afterAll, beforeAll, describe, expect, it } from "vitest";
12
+ import { createGuiHarness, guiAvailable } from "./gui-helpers.js";
13
+ const harness = createGuiHarness();
14
+ function anyExists(paths) {
15
+ return paths.some((path) => existsSync(path));
16
+ }
17
+ /** A family whose regular and bold faces are both present, plus a distinct
18
+ * serif family for the family-selection test. */
19
+ function detectFonts() {
20
+ let sans = "";
21
+ if (anyExists(["C:\\Windows\\Fonts\\arialbd.ttf"]))
22
+ sans = "Arial";
23
+ else if (anyExists(["/System/Library/Fonts/Supplemental/Arial Bold.ttf"]))
24
+ sans = "Arial";
25
+ else if (anyExists(["/System/Library/Fonts/Helvetica.ttc"]))
26
+ sans = "Helvetica";
27
+ else if (anyExists([
28
+ "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf",
29
+ "/usr/share/fonts/TTF/DejaVuSans-Bold.ttf",
30
+ ])) {
31
+ sans = "DejaVu Sans";
32
+ }
33
+ else if (anyExists([
34
+ "/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf",
35
+ "/usr/share/fonts/truetype/liberation2/LiberationSans-Bold.ttf",
36
+ ])) {
37
+ sans = "Liberation Sans";
38
+ }
39
+ if (sans === "")
40
+ return undefined;
41
+ let serif = "";
42
+ if (anyExists(["C:\\Windows\\Fonts\\times.ttf"]))
43
+ serif = "Times New Roman";
44
+ else if (anyExists(["/System/Library/Fonts/Supplemental/Times New Roman.ttf"])) {
45
+ serif = "Times New Roman";
46
+ }
47
+ else if (anyExists([
48
+ "/usr/share/fonts/truetype/dejavu/DejaVuSerif.ttf",
49
+ "/usr/share/fonts/TTF/DejaVuSerif.ttf",
50
+ ])) {
51
+ serif = "DejaVu Serif";
52
+ }
53
+ else if (anyExists([
54
+ "/usr/share/fonts/truetype/liberation/LiberationSerif-Regular.ttf",
55
+ "/usr/share/fonts/truetype/liberation2/LiberationSerif-Regular.ttf",
56
+ ])) {
57
+ serif = "Liberation Serif";
58
+ }
59
+ if (serif === "")
60
+ return undefined;
61
+ return { sans, serif };
62
+ }
63
+ const fonts = detectFonts();
64
+ /** A two-row page with the same text at the same size, styled by `#a` / `#b`. */
65
+ function sampleHtml(css) {
66
+ return `<html><head><style>
67
+ body { margin: 0; }
68
+ .sample { display: inline-block; white-space: nowrap; font-size: 40px; }
69
+ ${css}
70
+ </style></head><body>
71
+ <div id="a" class="sample">mmmmmmmmmm</div>
72
+ <div id="b" class="sample">mmmmmmmmmm</div>
73
+ </body></html>`;
74
+ }
75
+ function measure(source) {
76
+ const { value } = harness.compileAndRun("fonts", source, {
77
+ autocloseMs: 4000,
78
+ });
79
+ return { a: Number(value("a")), b: Number(value("b")) };
80
+ }
81
+ describe.skipIf(!guiAvailable)("gui extension — real font selection", () => {
82
+ beforeAll(() => harness.setup());
83
+ afterAll(() => harness.cleanup());
84
+ it.skipIf(fonts === undefined)("uses the bold face for font-weight: 700", () => {
85
+ const fixture = fonts;
86
+ const html = sampleHtml(`
87
+ #a { font-family: "${fixture.sans}"; font-weight: 400; }
88
+ #b { font-family: "${fixture.sans}"; font-weight: 700; }
89
+ `);
90
+ const { a, b } = measure(`
91
+ import { createWindow, run } from "gui";
92
+ const HTML = ${JSON.stringify(html)};
93
+ const win = createWindow({ title: "font-weight", width: 900, height: 300 });
94
+ win.on("ready", () => {
95
+ console.log("a=" + win.getBoundingClientRect("#a").width);
96
+ console.log("b=" + win.getBoundingClientRect("#b").width);
97
+ win.close();
98
+ });
99
+ win.loadHTML(HTML);
100
+ run();
101
+ `);
102
+ expect(a).toBeGreaterThan(0);
103
+ // The host fixture has a real bold face and its advances are wider here.
104
+ expect(b).toBeGreaterThan(a);
105
+ });
106
+ it.skipIf(fonts === undefined)("uses the requested font-family", () => {
107
+ const fixture = fonts;
108
+ const html = sampleHtml(`
109
+ #a { font-family: "${fixture.sans}"; }
110
+ #b { font-family: "${fixture.serif}"; }
111
+ `);
112
+ const { a, b } = measure(`
113
+ import { createWindow, run } from "gui";
114
+ const HTML = ${JSON.stringify(html)};
115
+ const win = createWindow({ title: "font-family", width: 900, height: 300 });
116
+ win.on("ready", () => {
117
+ console.log("a=" + win.getBoundingClientRect("#a").width);
118
+ console.log("b=" + win.getBoundingClientRect("#b").width);
119
+ win.close();
120
+ });
121
+ win.loadHTML(HTML);
122
+ run();
123
+ `);
124
+ expect(a).toBeGreaterThan(0);
125
+ expect(b).toBeGreaterThan(0);
126
+ expect(Math.abs(a - b)).toBeGreaterThan(1);
127
+ });
128
+ it.skipIf(fonts === undefined)("falls through a missing family to the next one", () => {
129
+ const fixture = fonts;
130
+ const html = sampleHtml(`
131
+ #a { font-family: "${fixture.sans}"; }
132
+ #b { font-family: "No Such Installed Family", "${fixture.sans}"; }
133
+ `);
134
+ const { a, b } = measure(`
135
+ import { createWindow, run } from "gui";
136
+ const HTML = ${JSON.stringify(html)};
137
+ const win = createWindow({ title: "font-family-fallback", width: 900, height: 300 });
138
+ win.on("ready", () => {
139
+ console.log("a=" + win.getBoundingClientRect("#a").width);
140
+ console.log("b=" + win.getBoundingClientRect("#b").width);
141
+ win.close();
142
+ });
143
+ win.loadHTML(HTML);
144
+ run();
145
+ `);
146
+ expect(a).toBeGreaterThan(0);
147
+ expect(b).toBeCloseTo(a, 3);
148
+ });
149
+ });
150
+ //# sourceMappingURL=gui-fonts.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gui-fonts.test.js","sourceRoot":"","sources":["../../../tests/e2e/gui-fonts.test.ts"],"names":[],"mappings":"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"}
@@ -38,8 +38,12 @@ export interface GuiRunResult {
38
38
  export interface GuiRunOptions {
39
39
  /** Extra files written into the work directory before the build. */
40
40
  files?: Record<string, string>;
41
- /** Additional extensions to register next to `gui` (e.g. `media`). */
41
+ /** Additional extensions to register next to `gui` (e.g. `node`). */
42
42
  extensions?: readonly Extension[];
43
+ /** Optional link features to force on (`media`, `gpu`, `images`, `shaping`, `webgl`, `all`). */
44
+ features?: readonly string[];
45
+ /** Optional link features to keep out even when auto-detection finds a use. */
46
+ noFeatures?: readonly string[];
43
47
  /**
44
48
  * Milliseconds the frame loop may run before `XT_GUI_AUTOCLOSE_MS` closes
45
49
  * every window. A program whose handlers close the window does not need this
@@ -57,8 +61,13 @@ export interface GuiRunOptions {
57
61
  * way to report its result.
58
62
  */
59
63
  console?: boolean;
64
+ /** Working directory for the compiled program (defaults to the test process
65
+ * CWD). Relative image/font paths resolve against it. */
66
+ cwd?: string;
60
67
  }
61
68
  export interface GuiHarness {
69
+ /** Absolute path of the per-suite temporary directory (`setup()` creates it). */
70
+ readonly workdir: string;
62
71
  /** Absolute path of the 4x4 test PNG written during `setup()`. */
63
72
  readonly logoPath: string;
64
73
  /**