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.
- package/AGENTS.md +1 -1
- package/README.md +5 -4
- package/README.zh-CN.md +4 -3
- package/dist/src/cli/extensions.d.ts +24 -0
- package/dist/src/cli/extensions.js +62 -0
- package/dist/src/cli/extensions.js.map +1 -0
- package/dist/src/cli/help.d.ts +1 -1
- package/dist/src/cli/help.js +3 -1
- package/dist/src/cli/help.js.map +1 -1
- package/dist/src/cli/hints.js +8 -3
- package/dist/src/cli/hints.js.map +1 -1
- package/dist/src/cli/main.js +21 -28
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/diagnostics/diagnostic.d.ts +3 -1
- package/dist/src/diagnostics/diagnostic.js +2 -0
- package/dist/src/diagnostics/diagnostic.js.map +1 -1
- package/dist/src/driver/build-key.d.ts +2 -0
- package/dist/src/driver/build-key.js +1 -0
- package/dist/src/driver/build-key.js.map +1 -1
- package/dist/src/driver/compiler.js +61 -8
- package/dist/src/driver/compiler.js.map +1 -1
- package/dist/src/driver/config.d.ts +4 -0
- package/dist/src/driver/config.js +2 -0
- package/dist/src/driver/config.js.map +1 -1
- package/dist/src/driver/link-features.d.ts +37 -0
- package/dist/src/driver/link-features.js +123 -0
- package/dist/src/driver/link-features.js.map +1 -0
- package/dist/src/driver/options.d.ts +10 -0
- package/dist/src/driver/runtime-objects.d.ts +5 -0
- package/dist/src/driver/runtime-objects.js +20 -1
- package/dist/src/driver/runtime-objects.js.map +1 -1
- package/dist/src/driver/usage.d.ts +23 -0
- package/dist/src/driver/usage.js +353 -0
- package/dist/src/driver/usage.js.map +1 -0
- package/dist/src/driver/version.d.ts +1 -1
- package/dist/src/driver/version.js +1 -1
- package/dist/src/extensions/catalog.js +1 -2
- package/dist/src/extensions/catalog.js.map +1 -1
- package/dist/src/extensions/gui/features.d.ts +34 -0
- package/dist/src/extensions/gui/features.js +165 -0
- package/dist/src/extensions/gui/features.js.map +1 -0
- package/dist/src/extensions/gui/index.js +10 -4
- package/dist/src/extensions/gui/index.js.map +1 -1
- package/dist/src/extensions/link-feature.d.ts +70 -0
- package/dist/src/extensions/link-feature.js +18 -0
- package/dist/src/extensions/link-feature.js.map +1 -0
- package/dist/src/extensions/registry.d.ts +24 -4
- package/dist/src/extensions/registry.js +26 -3
- package/dist/src/extensions/registry.js.map +1 -1
- package/dist/src/index.d.ts +3 -2
- package/dist/src/index.js +0 -1
- package/dist/src/index.js.map +1 -1
- package/dist/tests/cli/hints.test.js +5 -7
- package/dist/tests/cli/hints.test.js.map +1 -1
- package/dist/tests/driver/link-features.test.js +105 -0
- package/dist/tests/driver/link-features.test.js.map +1 -0
- package/dist/tests/driver/usage.test.d.ts +1 -0
- package/dist/tests/driver/usage.test.js +88 -0
- package/dist/tests/driver/usage.test.js.map +1 -0
- package/dist/tests/e2e/gui-audio.test.js +4 -4
- package/dist/tests/e2e/gui-audio.test.js.map +1 -1
- package/dist/tests/e2e/gui-css-coverage.test.d.ts +9 -0
- package/dist/tests/e2e/gui-css-coverage.test.js +333 -0
- package/dist/tests/e2e/gui-css-coverage.test.js.map +1 -0
- package/dist/tests/e2e/gui-css-features.test.d.ts +6 -0
- package/dist/tests/e2e/gui-css-features.test.js +270 -0
- package/dist/tests/e2e/gui-css-features.test.js.map +1 -0
- package/dist/tests/e2e/gui-effects.test.js +92 -11
- package/dist/tests/e2e/gui-effects.test.js.map +1 -1
- package/dist/tests/e2e/gui-feature-linking.test.d.ts +9 -0
- package/dist/tests/e2e/gui-feature-linking.test.js +68 -0
- package/dist/tests/e2e/gui-feature-linking.test.js.map +1 -0
- package/dist/tests/e2e/gui-font-face.test.d.ts +10 -0
- package/dist/tests/e2e/gui-font-face.test.js +142 -0
- package/dist/tests/e2e/gui-font-face.test.js.map +1 -0
- package/dist/tests/e2e/gui-fonts.test.d.ts +10 -0
- package/dist/tests/e2e/gui-fonts.test.js +150 -0
- package/dist/tests/e2e/gui-fonts.test.js.map +1 -0
- package/dist/tests/e2e/gui-helpers.d.ts +10 -1
- package/dist/tests/e2e/gui-helpers.js +6 -0
- package/dist/tests/e2e/gui-helpers.js.map +1 -1
- package/dist/tests/e2e/gui-layout.test.js +7 -3
- package/dist/tests/e2e/gui-layout.test.js.map +1 -1
- package/dist/tests/e2e/gui-media-disabled.test.d.ts +5 -4
- package/dist/tests/e2e/gui-media-disabled.test.js +7 -6
- package/dist/tests/e2e/gui-media-disabled.test.js.map +1 -1
- package/dist/tests/e2e/gui-media.test.d.ts +5 -4
- package/dist/tests/e2e/gui-media.test.js +9 -9
- package/dist/tests/e2e/gui-media.test.js.map +1 -1
- package/dist/tests/e2e/gui-paint.test.js +5 -2
- package/dist/tests/e2e/gui-paint.test.js.map +1 -1
- package/dist/tests/e2e/gui-shaping.test.d.ts +5 -0
- package/dist/tests/e2e/gui-shaping.test.js +47 -0
- package/dist/tests/e2e/gui-shaping.test.js.map +1 -0
- package/dist/tests/e2e/gui-track-sizing.test.d.ts +6 -0
- package/dist/tests/e2e/gui-track-sizing.test.js +173 -0
- package/dist/tests/e2e/gui-track-sizing.test.js.map +1 -0
- package/dist/tests/e2e/gui-transform.test.js +3 -2
- package/dist/tests/e2e/gui-transform.test.js.map +1 -1
- package/dist/tests/e2e/gui-webgl-pipeline-cache.test.d.ts +18 -0
- package/dist/tests/e2e/gui-webgl-pipeline-cache.test.js +120 -0
- package/dist/tests/e2e/gui-webgl-pipeline-cache.test.js.map +1 -0
- package/dist/tests/extensions/gui-features.test.d.ts +1 -0
- package/dist/tests/extensions/gui-features.test.js +175 -0
- package/dist/tests/extensions/gui-features.test.js.map +1 -0
- package/doc/ai/cli.md +5 -1
- package/doc/ai/extensions.md +56 -26
- package/doc/ai/troubleshooting.md +10 -7
- package/doc/ai/zh-CN/cli.md +5 -1
- package/doc/ai/zh-CN/extensions.md +48 -22
- package/doc/ai/zh-CN/troubleshooting.md +6 -5
- package/doc/gui/animation.md +39 -9
- package/doc/gui/api.md +2 -1
- package/doc/gui/build.md +137 -19
- package/doc/gui/canvas.md +1 -1
- package/doc/gui/dom.md +20 -4
- package/doc/gui/known-issues.md +63 -26
- package/doc/gui/layout.md +31 -8
- package/doc/gui/media.md +13 -7
- package/doc/gui/rendering.md +114 -39
- package/doc/gui/runtime.md +5 -0
- package/doc/gui/webgl.md +24 -6
- package/doc/gui.md +110 -47
- package/doc/implemented/cli.md +2 -0
- package/doc/implemented/extensions.md +9 -3
- package/doc/npm-package.md +4 -4
- package/doc/xbintsc.config.schema.json +10 -0
- package/doc/zh-CN/gui/animation.md +33 -10
- package/doc/zh-CN/gui/api.md +2 -1
- package/doc/zh-CN/gui/build.md +110 -16
- package/doc/zh-CN/gui/canvas.md +1 -1
- package/doc/zh-CN/gui/dom.md +16 -3
- package/doc/zh-CN/gui/known-issues.md +45 -15
- package/doc/zh-CN/gui/layout.md +23 -6
- package/doc/zh-CN/gui/media.md +11 -6
- package/doc/zh-CN/gui/rendering.md +84 -26
- package/doc/zh-CN/gui/runtime.md +3 -0
- package/doc/zh-CN/gui/webgl.md +3 -3
- package/doc/zh-CN/gui.md +92 -41
- package/doc/zh-CN/implemented/cli.md +2 -0
- package/doc/zh-CN/implemented/extensions.md +9 -3
- package/doc/zh-CN/npm-package.md +4 -3
- package/package.json +7 -7
- package/runtime/ext_gui/animation_values.cpp +425 -0
- package/runtime/ext_gui/animation_values.h +64 -0
- package/runtime/ext_gui/browser.cpp +22 -15
- package/runtime/ext_gui/browser_loop.cpp +13 -1
- package/runtime/ext_gui/canvas.h +1 -1
- package/runtime/ext_gui/canvas_raster.cpp +1 -1
- package/runtime/ext_gui/canvas_text.cpp +1 -1
- package/runtime/ext_gui/css.cpp +172 -21
- package/runtime/ext_gui/css.h +75 -4
- package/runtime/ext_gui/css_match.cpp +4 -0
- package/runtime/ext_gui/css_sheet.cpp +218 -2
- package/runtime/ext_gui/document.cpp +42 -192
- package/runtime/ext_gui/document.h +25 -12
- package/runtime/ext_gui/document_animation.cpp +428 -0
- package/runtime/ext_gui/dom_api_canvas.cpp +15 -8
- package/runtime/ext_gui/dom_api_canvas_extra.cpp +44 -20
- package/runtime/ext_gui/dom_api_canvas_image.cpp +3 -1
- package/runtime/ext_gui/dom_api_node_read.cpp +10 -0
- package/runtime/ext_gui/dom_api_offscreen.cpp +3 -1
- package/runtime/ext_gui/dom_api_style.cpp +7 -0
- package/runtime/ext_gui/dom_api_webgl_internal.h +4 -0
- package/runtime/ext_gui/dom_api_webgl_source.cpp +5 -2
- package/runtime/ext_gui/effect_values.cpp +245 -21
- package/runtime/ext_gui/gpu_bridge.c +28 -0
- package/runtime/ext_gui/gpu_feature.cpp +30 -0
- package/runtime/ext_gui/gpu_shader.cpp +22 -0
- package/runtime/ext_gui/gpu_shader_api.h +50 -0
- package/runtime/ext_gui/gradient_values.cpp +24 -0
- package/runtime/ext_gui/grid_values.cpp +23 -0
- package/runtime/ext_gui/gui.cpp +6 -37
- package/runtime/ext_gui/gui_canvas.cpp +14 -6
- package/runtime/ext_gui/gui_cursor.cpp +50 -0
- package/runtime/ext_gui/gui_engine.h +1 -18
- package/runtime/ext_gui/gui_events.cpp +19 -6
- package/runtime/ext_gui/gui_internal.h +3 -0
- package/runtime/ext_gui/gui_webgl.cpp +25 -10
- package/runtime/ext_gui/image_api.cpp +18 -0
- package/runtime/ext_gui/image_api.h +43 -0
- package/runtime/ext_gui/image_bitmap_browser.cpp +20 -11
- package/runtime/ext_gui/image_bridge.c +22 -0
- package/runtime/ext_gui/image_feature.cpp +107 -0
- package/runtime/ext_gui/inline_svg.cpp +95 -8
- package/runtime/ext_gui/inline_svg.h +5 -1
- package/runtime/ext_gui/layout.cpp +15 -9
- package/runtime/ext_gui/layout.h +8 -2
- package/runtime/ext_gui/layout_flex.cpp +134 -29
- package/runtime/ext_gui/layout_flow.cpp +58 -7
- package/runtime/ext_gui/layout_flow_internal.h +39 -4
- package/runtime/ext_gui/layout_grid.cpp +31 -0
- package/runtime/ext_gui/layout_inline.cpp +26 -2
- package/runtime/ext_gui/layout_vertical.cpp +196 -0
- package/runtime/ext_gui/media.cpp +4 -2
- package/runtime/ext_gui/media.h +3 -3
- package/runtime/ext_gui/media_api.h +7 -6
- package/runtime/ext_gui/paint.cpp +67 -9
- package/runtime/ext_gui/paint.h +61 -8
- package/runtime/ext_gui/paint_backdrop.cpp +211 -0
- package/runtime/ext_gui/paint_background.cpp +175 -97
- package/runtime/ext_gui/paint_effects.cpp +12 -6
- package/runtime/ext_gui/paint_internal.h +27 -0
- package/runtime/ext_gui/paint_outline.cpp +44 -0
- package/runtime/ext_gui/paint_shadow.cpp +368 -0
- package/runtime/ext_gui/renderer.cpp +15 -7
- package/runtime/ext_gui/renderer.h +11 -2
- package/runtime/ext_gui/renderer_backdrop.cpp +374 -0
- package/runtime/ext_gui/renderer_bitmap.cpp +82 -0
- package/runtime/ext_gui/renderer_gradient.cpp +51 -17
- package/runtime/ext_gui/renderer_image.cpp +19 -7
- package/runtime/ext_gui/renderer_internal.h +21 -0
- package/runtime/ext_gui/renderer_layer.cpp +37 -6
- package/runtime/ext_gui/renderer_text.cpp +2 -1
- package/runtime/ext_gui/stb_truetype.h +5077 -0
- package/runtime/ext_gui/style.cpp +62 -8
- package/runtime/ext_gui/style.h +111 -4
- package/runtime/ext_gui/style_cascade.cpp +83 -0
- package/runtime/ext_gui/style_internal.h +13 -1
- package/runtime/ext_gui/style_length.cpp +92 -0
- package/runtime/ext_gui/style_print.cpp +83 -2
- package/runtime/ext_gui/style_svg.cpp +40 -0
- package/runtime/ext_gui/style_text.cpp +302 -0
- package/runtime/ext_gui/style_ui.cpp +150 -0
- package/runtime/ext_gui/style_values.cpp +76 -62
- package/runtime/ext_gui/style_values_internal.h +23 -0
- package/runtime/ext_gui/text.cpp +27 -499
- package/runtime/ext_gui/text.h +18 -9
- package/runtime/ext_gui/text_api.h +45 -0
- package/runtime/ext_gui/text_bridge.c +23 -0
- package/runtime/ext_gui/text_cache.cpp +12 -3
- package/runtime/ext_gui/text_font_db.cpp +427 -0
- package/runtime/ext_gui/text_font_paths.cpp +250 -0
- package/runtime/ext_gui/text_font_paths.h +39 -0
- package/runtime/ext_gui/text_font_sfnt.cpp +396 -0
- package/runtime/ext_gui/text_font_sfnt.h +44 -0
- package/runtime/ext_gui/text_fonts.cpp +348 -0
- package/runtime/ext_gui/text_fonts.h +78 -0
- package/runtime/ext_gui/text_fonts_internal.h +77 -0
- package/runtime/ext_gui/text_glyph_cache.cpp +2 -2
- package/runtime/ext_gui/text_hb.cpp +438 -0
- package/runtime/ext_gui/text_stb.cpp +369 -0
- package/runtime/ext_gui/transform.cpp +107 -9
- package/runtime/ext_gui/transform.h +5 -0
- package/runtime/ext_gui/webgl_api.cpp +19 -0
- package/runtime/ext_gui/webgl_api.h +53 -0
- package/runtime/ext_gui/webgl_bridge.c +25 -0
- package/runtime/ext_gui/webgl_draw_setup.cpp +42 -1
- package/runtime/ext_gui/webgl_feature.cpp +82 -0
- package/runtime/ext_gui/webgl_feature.h +28 -0
- package/runtime/ext_gui/webgl_msl.cpp +41 -0
- package/runtime/ext_gui/webgl_msl.h +6 -0
- package/runtime/ext_gui/webgl_shader.cpp +40 -32
- package/runtime/ext_gui/window.cpp +7 -7
- package/runtime/ext_media/decode_audio.cpp +1 -1
- package/runtime/ext_media/media.cpp +1 -1
- package/runtime/ext_media/media_bridge.c +7 -7
- package/scripts/build-gui.ts +97 -98
- package/scripts/check-file-length.ts +1 -0
- package/scripts/gui-build-options.ts +122 -0
- package/src/cli/extensions.ts +72 -0
- package/src/cli/help.ts +3 -1
- package/src/cli/hints.ts +9 -3
- package/src/cli/main.ts +21 -27
- package/src/diagnostics/diagnostic.ts +2 -0
- package/src/driver/build-key.ts +3 -0
- package/src/driver/compiler.ts +63 -8
- package/src/driver/config.ts +6 -0
- package/src/driver/link-features.ts +163 -0
- package/src/driver/options.ts +10 -0
- package/src/driver/runtime-objects.ts +26 -1
- package/src/driver/usage.ts +376 -0
- package/src/driver/version.ts +1 -1
- package/src/extensions/catalog.ts +1 -2
- package/src/extensions/gui/features.ts +166 -0
- package/src/extensions/gui/index.ts +10 -4
- package/src/extensions/link-feature.ts +72 -0
- package/src/extensions/registry.ts +45 -4
- package/src/index.ts +3 -2
- package/dist/src/extensions/media/index.d.ts +0 -28
- package/dist/src/extensions/media/index.js +0 -59
- package/dist/src/extensions/media/index.js.map +0 -1
- package/dist/tests/extensions/media.test.js +0 -63
- package/dist/tests/extensions/media.test.js.map +0 -1
- package/src/extensions/media/index.ts +0 -65
- /package/dist/tests/{extensions/media.test.d.ts → driver/link-features.test.d.ts} +0 -0
package/doc/gui.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# xbintsc GUI extension (self-hosted HTML/CSS renderer)
|
|
2
2
|
|
|
3
|
-
Status: **
|
|
3
|
+
Status: **M22** — features (M1–M15) are complete: HTML parsing, CSS selector
|
|
4
4
|
matching, the cascade, computed styles and layout (block, inline, Flexbox and
|
|
5
5
|
CSS positioning) are
|
|
6
6
|
in place, and the engine *paints*: it builds a display list of rectangles, images
|
|
@@ -21,13 +21,15 @@ what `examples/gui/pelican-bike` — a playable 2D game — is built on. **M12**
|
|
|
21
21
|
DOM node lifetime explicit (what a mutation releases, what it keeps) and gives the
|
|
22
22
|
engine bounded memory: see [Node lifetime](./gui/dom.md#node-lifetime) and
|
|
23
23
|
[Memory & GC](./gui/runtime.md#memory--gc). **M13** plays real
|
|
24
|
-
`<video>`/`<audio>` — the optional
|
|
25
|
-
thread with a vendored minimal FFmpeg, video frames go through the image
|
|
26
|
-
path and audio to an SDL stream, with the DOM media API exposing
|
|
27
|
-
`play`/`pause`/`currentTime`/… and media events.
|
|
24
|
+
`<video>`/`<audio>` — the optional **`media` link feature** decodes them on the
|
|
25
|
+
main thread with a vendored minimal FFmpeg, video frames go through the image
|
|
26
|
+
texture path and audio to an SDL stream, with the DOM media API exposing
|
|
27
|
+
`play`/`pause`/`currentTime`/… and media events. The compiler selects the
|
|
28
|
+
feature from the program (a `<video>`/`<audio>` element, `new Audio()`,
|
|
29
|
+
`decodeAudioData`, or markup built at run time), so a DOM/CSS program does not
|
|
28
30
|
link FFmpeg. The browser globals also get a real `AudioContext`: a 48 kHz mixer
|
|
29
31
|
in `runtime/ext_gui/audio_mixer.cpp` plus `decodeAudioData` (WAV in-engine,
|
|
30
|
-
compressed formats through `media`) — see
|
|
32
|
+
compressed formats through the `media` feature) — see
|
|
31
33
|
[GUI API](./gui/api.md#web-audio).
|
|
32
34
|
**M14** adds `<canvas>` with a self-written 2D software rasteriser (anti-aliased
|
|
33
35
|
fills, paths, text and `drawImage`) uploaded through the image texture path —
|
|
@@ -38,17 +40,21 @@ them) can be translated, scaled and rotated without reflowing anything — and
|
|
|
38
40
|
`transition: transform`, so those poses animate. See
|
|
39
41
|
[Layout](./gui/layout.md#transforms-m15) and
|
|
40
42
|
[Animation](./gui/animation.md#css-transforms-m15).
|
|
41
|
-
**M17** adds real **WebGL 1.0**, and **M18** adds **WebGL 2.0**: `<canvas>.getContext("webgl2")` accepts `#version 300 es` shaders, vertex-array objects, instanced draws and sampler objects, all compiled to SPIR-V by the bundled glslang (and to MSL by the bundled SPIRV-Cross on Metal) and rendered through SDL_GPU. Geometry, lighting, texture sampling and blending run on the GPU and the page composites the colour texture without a readback — see [WebGL](./gui/webgl.md).
|
|
43
|
+
**M17** adds real **WebGL 1.0**, and **M18** adds **WebGL 2.0**: `<canvas>.getContext("webgl2")` accepts `#version 300 es` shaders, vertex-array objects, instanced draws and sampler objects, all compiled to SPIR-V by the bundled glslang (and to MSL by the bundled SPIRV-Cross on Metal) and rendered through SDL_GPU. Geometry, lighting, texture sampling and blending run on the GPU and the page composites the colour texture without a readback — see [WebGL](./gui/webgl.md). glslang is an optional **`gpu` link feature** shared with `mix-blend-mode`; the WebGL context/DOM bindings are the separate **`webgl` feature**, which requires `gpu`. A DOM/2D-canvas page links neither.
|
|
42
44
|
**M19** fills in the decorative CSS layer: `@media` queries, generated content
|
|
43
45
|
(`::before`/`::after`), multi-layer linear/radial/repeating backgrounds,
|
|
44
46
|
`text-shadow`, `clip-path`, `mix-blend-mode` (through an offscreen compositor)
|
|
45
|
-
and the `filter` colour
|
|
46
|
-
snapshot, and true group blur remains an approximation — see
|
|
47
|
+
and the `filter` colour effects. See
|
|
47
48
|
[Rendering](./gui/rendering.md#backgrounds-generated-content-and-effects-m19).
|
|
48
49
|
**M20** makes large documents interactive: `@media` is evaluated once per rule,
|
|
49
50
|
layout and paint share a bounded shaping cache, and a frame only does (and
|
|
50
51
|
presents) the work a change requires — see
|
|
51
52
|
[Performance](./gui/rendering.md#performance-m20).
|
|
53
|
+
**M21** completes the value/animation gaps: `calc()` arithmetic everywhere a
|
|
54
|
+
length is accepted, true Gaussian `text-shadow`/`box-shadow`, backdrop
|
|
55
|
+
compositing, `@keyframes` and the full transition timing-function set. See
|
|
56
|
+
[Rendering](./gui/rendering.md#backgrounds-generated-content-and-effects-m19)
|
|
57
|
+
and [Animation](./gui/animation.md#css-animations-keyframes).
|
|
52
58
|
This overview records the locked decisions, the architecture, the milestone plan
|
|
53
59
|
and the current progress; the engine itself is documented by function in the
|
|
54
60
|
pages above.
|
|
@@ -100,7 +106,8 @@ pages above.
|
|
|
100
106
|
| 4 | The engine is **not self-hosted** (it is C/C++, not TS), but must not affect the compiler's platform-agnostic design. Delivered as a per-platform prebuilt archive linked via `nativeObjects`. |
|
|
101
107
|
| 5 | The **event loop is generic**: the runtime exposes a generic main-loop hook and a poll primitive; nothing GUI-specific enters `runtime/`. |
|
|
102
108
|
| 6 | **Multiple windows** are supported by the core object model. |
|
|
103
|
-
| 7 | Third-party low-level libs are **statically linked into the extension archives** so releases stay self-contained; only OS frameworks are added at link time. `gui.a` carries SDL3
|
|
109
|
+
| 7 | Third-party low-level libs are **statically linked into the extension archives** so releases stay self-contained; only OS frameworks are added at link time. `gui.a` carries SDL3, FreeType/HarfBuzz for the optional `shaping` feature, glslang and (on macOS only) SPIRV-Cross; the default text path uses the bundled stb_truetype. glslang and SPIRV-Cross are only *extracted* when the compiler selects the **`gpu` link feature**; Metal is the only SDL_GPU backend that consumes MSL, so merging SPIRV-Cross elsewhere would add ~2.5 MiB no driver can ask for. The WebGL context/DOM code is the **`webgl` feature** (requires `gpu`), and stb_image/NanoSVG are the **`images` feature**. The optional `media.a` carries FFmpeg and is linked only when the **`media` link feature** is selected. All features are chosen from the program's static usage; `--feature`/`--no-feature` override the scan. |
|
|
110
|
+
| 8 | **Heavy optional halves are link features, not extensions.** FFmpeg and glslang are selected by what the bundled HTML/CSS/TS may use, and a small C bridge (linked only when active) installs the feature's dispatch table and forces the linker to extract the implementation. This keeps one user-facing `gui` extension while a DOM-only program pays for neither stack. |
|
|
104
111
|
|
|
105
112
|
## Architecture
|
|
106
113
|
|
|
@@ -120,7 +127,7 @@ pages above.
|
|
|
120
127
|
│
|
|
121
128
|
▼
|
|
122
129
|
windowing + input (SDL3) ── multiple windows
|
|
123
|
-
text (
|
|
130
|
+
text (stb_truetype) ── glyph atlas
|
|
124
131
|
images (stb_image; SVG via NanoSVG)
|
|
125
132
|
media DOM + audio sink ── optional media.a (FFmpeg) installs the decoder
|
|
126
133
|
```
|
|
@@ -134,14 +141,19 @@ with `nativeObjects()`, `linkerFlags()` and `modules()`.
|
|
|
134
141
|
| --- | --- | --- |
|
|
135
142
|
| Window + input + multi-window | **SDL3** | cross-platform windows, HiDPI, IME, clipboard, DnD, close/hide events |
|
|
136
143
|
| GPU | **SDL_GPU** (SDL3) | one render path over Metal / Vulkan / D3D12; avoids three backends |
|
|
137
|
-
| Text shaping | **
|
|
138
|
-
| Glyph raster | **FreeType
|
|
144
|
+
| Text shaping | **stb_truetype** simple shaper; optional **`shaping`** feature links HarfBuzz + FreeType | default keeps the DOM-only binary near 3 MiB; `shaping` restores ligatures and complex-script shaping |
|
|
145
|
+
| Glyph raster | **stb_truetype**; FreeType only under `shaping` | TrueType outlines → grayscale atlas by default |
|
|
139
146
|
| Images | **stb_image** (vendored header) for bitmaps, **NanoSVG** (vendored headers) for SVG | single headers to start; SVG files rasterise on demand |
|
|
140
|
-
| Video + audio | **FFmpeg** (statically vendored, minimal build, optional `media`
|
|
147
|
+
| Video + audio | **FFmpeg** (statically vendored, minimal build, optional `media` link feature) | decodes the common container/codec set; no WebView or platform media framework |
|
|
141
148
|
|
|
142
|
-
Pinned versions: SDL3 `release-3.2.10`, FreeType `2.13.3`, HarfBuzz `10.1.0
|
|
143
|
-
|
|
144
|
-
`
|
|
149
|
+
Pinned versions: SDL3 `release-3.2.10`, FreeType `2.13.3`, HarfBuzz `10.1.0`
|
|
150
|
+
(for the optional `shaping` feature), glslang `16.6.0`, SPIRV-Cross
|
|
151
|
+
`vulkan-sdk-1.4.313.0`, FFmpeg `7.1` for the optional `media` archive
|
|
152
|
+
(overridable with `SDL3_TAG` / `FREETYPE_VERSION` / `HARFBUZZ_VERSION` /
|
|
153
|
+
`GLSLANG_VERSION` / `SPIRV_CROSS_VERSION` / `FFMPEG_VERSION`). The default text
|
|
154
|
+
backend is the bundled `stb_truetype.h`; it accepts TrueType outlines (not
|
|
155
|
+
CFF/OTF or variable fonts). The `shaping` feature swaps in HarfBuzz + FreeType
|
|
156
|
+
for full OpenType shaping.
|
|
145
157
|
|
|
146
158
|
Alternative if SDL3 is rejected: **GLFW + OpenGL 3.3** (simpler, but OpenGL is
|
|
147
159
|
deprecated on macOS and gives no modern GPU abstraction). **wgpu-native** if the
|
|
@@ -169,10 +181,13 @@ engine were Rust.
|
|
|
169
181
|
4. **M4 — paint + text + display list**
|
|
170
182
|
- **M4a — display list + GPU shapes** ✅ background/border display list,
|
|
171
183
|
rounded-rect SDL_GPU pipeline (`paint.*`, `renderer.*`).
|
|
172
|
-
- **M4b-1 — text stack + metrics** ✅
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
184
|
+
- **M4b-1 — text stack + metrics** ✅ the text module (`text.*`) with font
|
|
185
|
+
resolution/caching and shaping-based metrics used by layout
|
|
186
|
+
(`measureText`/`fontMetrics`); the CSS family list, weight and italic style
|
|
187
|
+
select real installed faces, and author `@font-face` rules load local font
|
|
188
|
+
files (relative URLs resolve as `file:` paths against the process working
|
|
189
|
+
directory). Originally HarfBuzz + FreeType, now the bundled stb_truetype.
|
|
190
|
+
- **M4b-2 — glyph rendering** ✅ stb_truetype rasterisation, a shared shelf-packed
|
|
176
191
|
glyph atlas, textured text quads in the display list and HiDPI-aware raster
|
|
177
192
|
scaling. Gradients remain.
|
|
178
193
|
5. **M5 — input + events** ✅
|
|
@@ -186,8 +201,8 @@ engine were Rust.
|
|
|
186
201
|
per-file GPU textures and textured quads (`image.*`, `svg.*`, `paint.*`,
|
|
187
202
|
`renderer.*`).
|
|
188
203
|
- **M6b — transitions/animations** ✅ `transition` shorthand + longhands,
|
|
189
|
-
|
|
190
|
-
|
|
204
|
+
retargeting, `cubic-bezier()`/`steps()`, `win.advance(ms)` and (M21)
|
|
205
|
+
`@keyframes` with every animation longhand.
|
|
191
206
|
7. **M7 — CI & releases** ✅ (Linux/macOS/Windows x64 build) / 🚧 (run + Windows arm64)
|
|
192
207
|
- `compile-examples` builds `gui.a` and `media.a` on Linux and macOS
|
|
193
208
|
(required), then runs the examples and `tests/e2e/gui-*.test.ts` under
|
|
@@ -199,16 +214,17 @@ engine were Rust.
|
|
|
199
214
|
(`package-release` copies all of `runtime/`) and inside the optional
|
|
200
215
|
`@xbintsc/<os>-<arch>` npm package. Windows x64 is included; Windows arm64
|
|
201
216
|
still skips them.
|
|
202
|
-
- `vendor/` (SDL3/FreeType/HarfBuzz for the GUI archive, FFmpeg for `media`)
|
|
217
|
+
- `vendor/` (SDL3/FreeType/HarfBuzz/glslang for the GUI archive, FFmpeg for `media`)
|
|
203
218
|
is cached per OS/arch, keyed by `scripts/build-gui.ts` /
|
|
204
219
|
`scripts/build-media.ts`. Windows x64 gets its own source cache plus the
|
|
205
220
|
installed `vendor/ffmpeg-build-msvc/dist` prefix.
|
|
206
|
-
- Windows x64 builds both archives in CI and links a `gui
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
221
|
+
- Windows x64 builds both archives in CI and links a `gui` program that
|
|
222
|
+
exercises the `media` link feature (plus an explicit `--feature media`
|
|
223
|
+
build), using the same Visual Studio `vcvarsall` + bundled LLVM toolchain
|
|
224
|
+
as a local build (`.github/actions/vs-toolchain`); the host has no
|
|
225
|
+
GPU/Vulkan driver, so *running* the GUI/media examples there remains
|
|
226
|
+
provisional (a failure is logged without annotating the run). The Windows
|
|
227
|
+
arm64 job still skips both archives (see
|
|
212
228
|
[Open questions](./gui/known-issues.md#open-questions)).
|
|
213
229
|
8. **M8 — interactive DOM** ✅
|
|
214
230
|
- Element/document handles with stable identity, read/write properties via
|
|
@@ -260,15 +276,17 @@ engine were Rust.
|
|
|
260
276
|
`tests/e2e/gui-retention.test.ts` (see [Memory & GC](./gui/runtime.md#memory--gc)).
|
|
261
277
|
13. **M13 — video & audio** ✅
|
|
262
278
|
- `<video>` / `<audio>` decode through a statically vendored minimal FFmpeg
|
|
263
|
-
in the optional `media`
|
|
279
|
+
in the optional `media` link feature (`runtime/ext_media/media.cpp`); the
|
|
280
|
+
compiler selects it from the program and only then compiles the bridge and
|
|
281
|
+
links `media.a`. Frames
|
|
264
282
|
upload to GPU textures through the existing image pipeline, audio is
|
|
265
283
|
pushed to an SDL stream on the main thread by the GUI's audio sink, and
|
|
266
284
|
the DOM media API plus `loadedmetadata`/`play`/`pause`/`ended`/
|
|
267
285
|
`timeupdate`/`error` events are exposed on element handles
|
|
268
286
|
(`dom_api_media.cpp`, `dom_api_proto.cpp`). Controlled from TS + CSS;
|
|
269
287
|
there are no built-in controls. Example in `examples/gui/media.*`, e2e in
|
|
270
|
-
`tests/e2e/gui-media.test.ts` (
|
|
271
|
-
`tests/e2e/gui-media-disabled.test.ts` (
|
|
288
|
+
`tests/e2e/gui-media.test.ts` (auto-selected) and
|
|
289
|
+
`tests/e2e/gui-media-disabled.test.ts` (`--no-feature media`).
|
|
272
290
|
14. **M14 — `<canvas>` 2D** ✅
|
|
273
291
|
- `<canvas>` is a replaced element (`xtgui::Canvas2D`, `layout.*`), the
|
|
274
292
|
`getContext("2d")` handle and drawing API live in `dom_api_canvas.cpp`,
|
|
@@ -336,16 +354,18 @@ engine were Rust.
|
|
|
336
354
|
- Generated content: `::before`/`::after` selectors, inherited pseudo styles,
|
|
337
355
|
`content` strings/escapes/`attr()`, and synthetic layout boxes that never
|
|
338
356
|
leak into DOM traversal.
|
|
339
|
-
- Multi-layer `background-image` with linear
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
- `text-shadow`
|
|
357
|
+
- Multi-layer `background-image` with linear and radial gradients rasterised
|
|
358
|
+
per pixel into one image texture (`renderer_gradient.cpp`), so hard stops
|
|
359
|
+
and sub-pixel details (a 1px divider) are exact.
|
|
360
|
+
- `text-shadow` and `box-shadow` (outer/inset, spread, multiple layers),
|
|
361
|
+
blurred with a true separable Gaussian over the shape mask (M21).
|
|
343
362
|
- `clip-path` polygons (`inset`/`circle`/`ellipse`/`polygon`) resolved to
|
|
344
363
|
device space, ear-clipped and intersected with shape geometry in
|
|
345
364
|
`renderer_clip.cpp` — no stencil/shader change.
|
|
346
365
|
- `filter` colour functions, nine-tap `blur()` and silhouette
|
|
347
|
-
`drop-shadow()`; `backdrop-filter`
|
|
348
|
-
|
|
366
|
+
`drop-shadow()`; `backdrop-filter` snapshots the scene, applies a Gaussian
|
|
367
|
+
and one combined colour matrix, and composites through the border-box mask
|
|
368
|
+
(M21).
|
|
349
369
|
- E2E coverage in `tests/e2e/gui-effects.test.ts`; see
|
|
350
370
|
[Rendering](./gui/rendering.md#backgrounds-generated-content-and-effects-m19).
|
|
351
371
|
20. **M20 — rendering performance** ✅
|
|
@@ -360,6 +380,28 @@ engine were Rust.
|
|
|
360
380
|
dirty frame, and redundant render-state binds removed.
|
|
361
381
|
- `win.stats()`/`XT_GUI_PERF` counters and `tests/e2e/gui-perf.test.ts`; see
|
|
362
382
|
[Performance](./gui/rendering.md#performance-m20).
|
|
383
|
+
21. **M21 — CSS value/animation completeness** ✅
|
|
384
|
+
- `calc()` is parsed as an unresolved expression tree and resolved by both
|
|
385
|
+
layout (`toPx`) and paint; nested arithmetic, `calc()` inside
|
|
386
|
+
`min`/`max`/`clamp`, and calc in shadows/transforms/filters are covered.
|
|
387
|
+
- `box-shadow` (outer/inset, spread, multiple layers) and blurred
|
|
388
|
+
`text-shadow` are rasterised into a Gaussian mask, cached and composited
|
|
389
|
+
as one tinted image quad.
|
|
390
|
+
- `backdrop-filter` snapshots the painted scene and composites a Gaussian +
|
|
391
|
+
colour matrix through the border-box mask in a runtime-compiled shader.
|
|
392
|
+
- `@keyframes` plus every `animation-*` longhand (delay, iterations,
|
|
393
|
+
direction, fill mode, paused/running) share the property interpolator with
|
|
394
|
+
transitions; transitions now cover opacity, layout lengths, box shadows
|
|
395
|
+
and `cubic-bezier()`/`steps()`/`step-start`/`step-end`.
|
|
396
|
+
- E2E: `tests/e2e/gui-css-features.test.ts`.
|
|
397
|
+
22. **M22 — CSS coverage for the boxing UI** ✅
|
|
398
|
+
- `letter-spacing`, `text-transform`, the `font` shorthand, length-form
|
|
399
|
+
`vertical-align`, `writing-mode` (text-only vertical layout), percentage
|
|
400
|
+
`border-radius`, `inline-flex`/`inline-grid`, `grid-area`, `aspect-ratio`,
|
|
401
|
+
auto margins, `outline` + `:focus-visible`/`:active`, `currentColor`,
|
|
402
|
+
`skewX()`/`skewY()`, `background-size` tiling for `url()` layers and
|
|
403
|
+
document CSS on SVG children (`fill`/`stroke`/…) are now honoured.
|
|
404
|
+
- E2E: `tests/e2e/gui-css-coverage.test.ts`.
|
|
363
405
|
|
|
364
406
|
## Progress log
|
|
365
407
|
|
|
@@ -373,9 +415,10 @@ engine were Rust.
|
|
|
373
415
|
coverage.
|
|
374
416
|
- **M4a** ✅ display list (`paint.*`) and the SDL_GPU 2D renderer with an MSL
|
|
375
417
|
rounded-rect pipeline (`renderer.*`), `paintList`/`paintCount`, e2e coverage.
|
|
376
|
-
- **M4b-1** ✅
|
|
377
|
-
|
|
378
|
-
|
|
418
|
+
- **M4b-1** ✅ the text module (`text.*`) with font resolution, shaping and
|
|
419
|
+
metrics, real text metrics in layout, `measureText`/`fontMetrics`, e2e
|
|
420
|
+
coverage. Originally HarfBuzz + FreeType; now stb_truetype (see the stack
|
|
421
|
+
table and the size trade-off in [build](./gui/build.md#binary-size)).
|
|
379
422
|
- **M4b-2** ✅ glyph atlas + textured text pipeline in `renderer.*`, shaped text
|
|
380
423
|
runs in `paint.*`, `xt_text_shape_run`/`xt_text_rasterize` in `text.*`, HiDPI
|
|
381
424
|
raster scaling, e2e coverage.
|
|
@@ -430,17 +473,19 @@ engine were Rust.
|
|
|
430
473
|
ratcheting upwards. `win.stats()` exposes the engine counters and
|
|
431
474
|
`tests/e2e/gui-retention.test.ts` pins them; a game loop rewriting its sprite
|
|
432
475
|
every frame now runs in constant memory (see [Memory & GC](./gui/runtime.md#memory--gc)).
|
|
433
|
-
- **M13** ✅ `<video>` / `<audio>` support. The optional `media`
|
|
476
|
+
- **M13** ✅ `<video>` / `<audio>` support. The optional `media` **link feature**
|
|
434
477
|
vendors and builds a minimal static FFmpeg (`scripts/build-media.ts`) and
|
|
435
478
|
merges it into `media.a` (or `media.lib` from clang-cl/MSVC objects on
|
|
436
|
-
Windows)
|
|
479
|
+
Windows). The compiler selects the feature from the program and only then
|
|
480
|
+
compiles `media_bridge.c` and links `media.a`; a DOM/CSS program never links
|
|
481
|
+
FFmpeg. `runtime/ext_media/media.cpp` decodes video to RGBA
|
|
437
482
|
frames and audio to 48 kHz stereo PCM on the main thread,
|
|
438
483
|
`runtime/ext_gui/gui_media.cpp` owns the players, implements the SDL audio
|
|
439
484
|
sink and pumps the media clock and events each frame,
|
|
440
485
|
`renderer_image.cpp` uploads each new video frame through the image texture
|
|
441
486
|
path, and `dom_api_media.cpp` exposes `play`/`pause`/`load` plus the media
|
|
442
|
-
properties on element handles. `gui.a` stays FFmpeg-free
|
|
443
|
-
|
|
487
|
+
properties on element handles. `gui.a` stays FFmpeg-free.
|
|
488
|
+
`examples/gui/media.*` demonstrates
|
|
444
489
|
the TS-plus-CSS-controls pattern and `tests/e2e/gui-media.test.ts` pins it.
|
|
445
490
|
- **M14** ✅ `<canvas>` support. A new replaced element (`layout.*`) carries an
|
|
446
491
|
intrinsic size from its `width`/`height` attributes (default `300x150`),
|
|
@@ -507,9 +552,27 @@ engine were Rust.
|
|
|
507
552
|
`paint_background.cpp` resolves and paints it (radial layers become one
|
|
508
553
|
`PaintGradient`, which `renderer_gradient.cpp` rasterises into a texture),
|
|
509
554
|
`paint_effects.cpp` applies filter colour functions plus nine-tap
|
|
510
|
-
blur/drop-shadow
|
|
555
|
+
blur/drop-shadow, `paint_shadow.cpp` rasterises Gaussian text/box shadows,
|
|
556
|
+
`paint_backdrop.cpp` + `renderer_layer.cpp` composite `backdrop-filter`, and
|
|
511
557
|
`paint_clip.cpp`/`renderer_clip.cpp` clip geometry against triangulated
|
|
512
558
|
`clip-path` polygons. E2E: `tests/e2e/gui-effects.test.ts`.
|
|
559
|
+
- **M22** ✅ CSS coverage for the boxing UI. The cascade/declaration parser
|
|
560
|
+
gained `letter-spacing`, `text-transform`, the `font` shorthand,
|
|
561
|
+
`vertical-align`, `writing-mode`, percentage `border-radius`, `outline`,
|
|
562
|
+
`background-size`, `currentColor` and the SVG presentation properties;
|
|
563
|
+
layout gained inline-level flex/grid, `grid-area`, `aspect-ratio`, auto
|
|
564
|
+
margins and text-only vertical writing mode; paint gained outline edges,
|
|
565
|
+
sized/tiled image backgrounds and rotated vertical text; `:focus-visible` is
|
|
566
|
+
an alias of `:focus` and `:active` is tracked from pointer down/up. E2E:
|
|
567
|
+
`tests/e2e/gui-css-coverage.test.ts`.
|
|
568
|
+
- **M21** ✅ CSS value/animation completeness. `calc()` is parsed as an
|
|
569
|
+
unresolved expression tree and resolved by layout/paint; `box-shadow` and
|
|
570
|
+
blurred `text-shadow` use a separable Gaussian mask cached as a texture;
|
|
571
|
+
`backdrop-filter` gets an offscreen snapshot pass; `@keyframes` (plus every
|
|
572
|
+
`animation-*` longhand, delay, iteration, direction and fill mode) shares the
|
|
573
|
+
property interpolator with transitions, which now also cover opacity, layout
|
|
574
|
+
lengths, box shadows and `cubic-bezier()`/`steps()`. E2E:
|
|
575
|
+
`tests/e2e/gui-css-features.test.ts`.
|
|
513
576
|
- **M20** ✅ rendering performance. `@media` is evaluated once per rule per
|
|
514
577
|
restyle, generated content is skipped for sheets without `::before`/`::after`,
|
|
515
578
|
and `:hover`/`:focus` only restyle when the sheet tracks them
|
package/doc/implemented/cli.md
CHANGED
|
@@ -29,6 +29,8 @@ default; `--no-check` skips it (and is part of the cache key). See
|
|
|
29
29
|
--emit <kind> exe | obj | ir (default: exe)
|
|
30
30
|
-O0..-O3 Optimization level (default: -O2)
|
|
31
31
|
--ext <names> Comma separated extensions (e.g. node)
|
|
32
|
+
--feature <names> Force optional link features on (media,gpu,images,shaping,webgl,all)
|
|
33
|
+
--no-feature <n> Keep optional link features out even when detected
|
|
32
34
|
--ext-native <m> Register a C++/Rust extension from a JSON manifest
|
|
33
35
|
--config <path> Use a project config (default: xbintsc.config.json)
|
|
34
36
|
--no-config Do not read any project config
|
|
@@ -2,10 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
> Part of [Implemented syntax and features](../implemented.md) · [简体中文](../zh-CN/implemented/extensions.md)
|
|
4
4
|
|
|
5
|
-
Location: `src/extensions/registry.ts`, `src/extensions/node
|
|
5
|
+
Location: `src/extensions/registry.ts`, `src/extensions/node/`, `src/extensions/link-feature.ts`, `src/driver/usage.ts`, `src/driver/link-features.ts`
|
|
6
6
|
|
|
7
|
-
- An extension is a plain object: `runtimeSources()` (extra C sources), `linkerFlags()` (extra link flags), `builtins()` (global identifier → runtime symbol, uniform `(argc, argv)` ABI)
|
|
8
|
-
- `ExtensionRegistry`: register / unregister / lookup / aggregate builtins, modules, runtime sources and link
|
|
7
|
+
- An extension is a plain object: `runtimeSources()` (extra C sources), `linkerFlags()` (extra link flags), `builtins()` (global identifier → runtime symbol, uniform `(argc, argv)` ABI), `modules()` (import specifier → named exports / namespace) and `linkFeatures()` (optional heavy capabilities).
|
|
8
|
+
- `ExtensionRegistry`: register / unregister / lookup / aggregate builtins, modules, runtime sources, link flags and link features.
|
|
9
|
+
- **Optional link features** (`media`, `gpu`, `images`, `shaping`, `webgl`):
|
|
10
|
+
- A feature declares `runtimeSources()` (a C bridge compiled only when active), `nativeObjects()` (archives linked only when active), `linkerFlags()`, optional `requires` (another feature it depends on) and `used(usage)`.
|
|
11
|
+
- The driver builds `ProgramUsage` from the bundled AST (`collectUsage` in `src/driver/usage.ts`): string literals (including imported HTML and inlined CSS), identifiers/property names, `getContext(...)` kinds, and whether markup can be built at run time. Simple `const` aliases are resolved; unresolved markup makes the program conservative.
|
|
12
|
+
- `resolveLinkFeatures` applies `--feature` / `--no-feature` (and `all`), expands `requires`, reports an unavailable auto-detected feature as a warning and a forced one as an error, and returns the bridges/archives/flags to link.
|
|
13
|
+
- The bridge is the strong reference: its constructor installs the feature's dispatch table and its references force the linker to extract the implementation. With no bridge, the table stays null and the implementation members are never linked.
|
|
14
|
+
- Current clients: `media` (FFmpeg, `runtime/ext_media/media_bridge.c` + `media.a`), `gpu` (glslang/SPIRV-Cross, `runtime/ext_gui/gpu_bridge.c` + `gpu_feature.cpp` inside `gui.a`), `images` (stb_image/NanoSVG, `runtime/ext_gui/image_bridge.c` + `image_feature.cpp`), `shaping` (HarfBuzz/FreeType, `runtime/ext_gui/text_bridge.c` + `text_hb.cpp`), and `webgl` (context/DOM bindings, `runtime/ext_gui/webgl_bridge.c` + `webgl_feature.cpp`, requiring `gpu`).
|
|
9
15
|
- The built-in core extension `core`: exposes `print` (mapped to `xt_println`), always registered.
|
|
10
16
|
- The Node extension `node`:
|
|
11
17
|
- Modular organisation: `src/extensions/node/fs/` + `runtime/ext_node/fs/read_file.c`
|
package/doc/npm-package.md
CHANGED
|
@@ -69,8 +69,8 @@ The package does **not** contain:
|
|
|
69
69
|
If npm skips the optional package (`--omit=optional`, a package manager that
|
|
70
70
|
does not install optional dependencies, or a host the release does not build
|
|
71
71
|
for), the driver falls back to compiling the C runtime from the shipped sources
|
|
72
|
-
and caches the objects; that build works but is slower, and `--ext gui`
|
|
73
|
-
|
|
72
|
+
and caches the objects; that build works but is slower, and `--ext gui` (plus
|
|
73
|
+
the auto-selected `media`/`gpu`/`images`/`shaping`/`webgl` link features) needs the archive to be present.
|
|
74
74
|
|
|
75
75
|
## Requirements
|
|
76
76
|
|
|
@@ -398,7 +398,7 @@ jobs:
|
|
|
398
398
|
| --- | --- | --- |
|
|
399
399
|
| Needs Node.js | Yes, 22+ | No |
|
|
400
400
|
| First build | Links the prebuilt runtime from the optional platform package | Links the prebuilt runtime |
|
|
401
|
-
| GUI
|
|
401
|
+
| GUI engine + media archive | Included on Linux/macOS and Windows x64 (the hosts the release builds them for) | Included in Linux/macOS and Windows x64 archives |
|
|
402
402
|
| Installation | `npm install` + lockfile / provenance | Download, verify `.sha256`, unpack |
|
|
403
403
|
| Programmatic API | Yes | No (CLI only) |
|
|
404
404
|
| Cross-compiles | No — host only | No — host only |
|
|
@@ -439,7 +439,7 @@ the same file under `node_modules/xbintsc/doc/ai/`.
|
|
|
439
439
|
| The first build takes a long time | The optional `@xbintsc/<os>-<arch>` package was skipped (or this host has no prebuilt package), so the runtime C sources are compiled and cached. Check `npm ls @xbintsc/<os>-<arch>` and reinstall without `--omit=optional`; `--time` confirms. |
|
|
440
440
|
| Permission errors writing `.xbintsc/` | Set `xbintsc_CACHE_DIR` to a writable directory, or run from a writable working directory. |
|
|
441
441
|
| `module 'fs' is provided by the 'node' extension` | Add `--ext node`, or `"extensions": ["node"]` in the config. |
|
|
442
|
-
| `GUI native library not found` / `media native library not found` | The optional platform package that ships `gui.a`/`gui.lib` or `media.a`/`media.lib` was skipped, or this host has no prebuilt GUI/media archive (Windows arm64). Reinstall without `--omit=optional`, use a Linux/macOS/Windows x64 release archive, or build the archive from a source checkout. |
|
|
442
|
+
| `GUI native library not found` / `media native library not found` | The optional platform package that ships `gui.a`/`gui.lib` or `media.a`/`media.lib` was skipped, or this host has no prebuilt GUI/media archive (Windows arm64). Reinstall without `--omit=optional`, use a Linux/macOS/Windows x64 release archive, or build the archive from a source checkout. An auto-detected `media` feature with a missing archive only warns; `--feature media` makes it an error. |
|
|
443
443
|
| `require("xbintsc")` fails | The package is ESM-only; use `import` (or dynamic `import()`). |
|
|
444
444
|
| Windows link errors about missing MSVC libraries | Run from a Native Tools prompt, install the VS C++ build tools, and check `npx xbintsc doctor`. |
|
|
445
445
|
| `npm ci --omit=dev` then the build cannot find `xbintsc` | Install devDependencies for the build stage, or move `xbintsc` to `dependencies`. |
|
|
@@ -48,6 +48,16 @@
|
|
|
48
48
|
"items": { "type": "string" },
|
|
49
49
|
"description": "Paths to native C++/Rust extension manifests."
|
|
50
50
|
},
|
|
51
|
+
"features": {
|
|
52
|
+
"type": "array",
|
|
53
|
+
"items": { "type": "string" },
|
|
54
|
+
"description": "Optional link features to force on, e.g. [\"media\", \"gpu\", \"images\", \"shaping\", \"webgl\"] or [\"all\"]."
|
|
55
|
+
},
|
|
56
|
+
"noFeatures": {
|
|
57
|
+
"type": "array",
|
|
58
|
+
"items": { "type": "string" },
|
|
59
|
+
"description": "Optional link features to keep out even when auto-detection finds a use."
|
|
60
|
+
},
|
|
51
61
|
"force": {
|
|
52
62
|
"type": "boolean",
|
|
53
63
|
"description": "Ignore the incremental cache."
|
|
@@ -30,27 +30,49 @@ transition 的属性时,会记录一个正在运行的 transition,并在每
|
|
|
30
30
|
结束;引擎用真实帧间隔推进时钟(`XtDocument::advance`),`win.advance(ms)`
|
|
31
31
|
让测试可以确定性地推进。
|
|
32
32
|
|
|
33
|
-
- 支持的属性:`background-color`、`color`、`border-color`、
|
|
34
|
-
`border-radius
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
- 支持的属性:`background-color`、`color`、`border-color`、`opacity`、
|
|
34
|
+
`border-radius`、`transform`、`text-shadow`、`box-shadow`、所有盒模型
|
|
35
|
+
偏移/尺寸长度(`width`/`height`/`top`/`left`/`margin-*`/`padding-*`/…)、
|
|
36
|
+
gap/flex-basis 长度,以及 `filter`(形状一致的滤镜列表会插值模糊长度、数值与
|
|
37
|
+
drop-shadow 颜色);`transition: all` 覆盖整个列表。单位一致的长度会插值
|
|
38
|
+
(单位变化按 CSS 的离散回退处理),`opacity`、颜色与 `transform` 正常插值。
|
|
38
39
|
- `transition` 简写与 `transition-property` / `-duration` / `-delay` /
|
|
39
|
-
`-timing-function` 长写都会被解析;时间值接受 `s` 与 `ms
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
`-timing-function` 长写都会被解析;时间值接受 `s` 与 `ms`;简写/长写内
|
|
41
|
+
都接受 `calc()`。
|
|
42
|
+
- 缓动函数支持 `linear`、`ease`、`ease-in`、`ease-out`、`ease-in-out`、
|
|
43
|
+
`cubic-bezier(x1, y1, x2, y2)`、`steps(n, start|end)` 及其 `jump-*` 拼写;
|
|
44
|
+
三次贝塞尔用数值求解,关键字曲线使用 CSS 控制点。
|
|
42
45
|
- 在动画中途重定向会从当前插值启动一个新 transition,因此反转悬停会从它
|
|
43
46
|
当前所在位置平滑动画。
|
|
44
47
|
- `computedStyle()` 报告显示(已插值)的值,因此 transition 在测试中可直接
|
|
45
48
|
观察。
|
|
46
49
|
|
|
47
|
-
`transform` 列表按**逐项**插值(`
|
|
50
|
+
`transform` 列表按**逐项**插值(`animation_values.cpp`、`xt_transform_interpolate`),
|
|
48
51
|
这正是让常见的一对 `translateY(-4px) rotate(-0.35deg)` 与 `none` 之间平滑
|
|
49
52
|
滑行而不是跳变的原因:缺失的一侧会用同类型的单位(identity)操作补齐。两个
|
|
50
53
|
列表形状或单位对不上时(`rotate(10deg)` 对 `rotate(10rad)`,或函数个数不同)
|
|
51
54
|
完全不做插值——transition 直接吸附到目标值,即 CSS 的离散回退,而不是一段
|
|
52
55
|
看起来错误的扫过。
|
|
53
56
|
|
|
57
|
+
## CSS 动画(`@keyframes`)
|
|
58
|
+
|
|
59
|
+
`@keyframes` 会被解析进 `StyleSheet::keyframes`(`from`/`to`/百分比选择器产生的
|
|
60
|
+
偏移会排序)。支持 `animation` 简写及全部 `animation-*` 长写:名称、时长、
|
|
61
|
+
延迟、时间函数、迭代次数(含 `infinite`)、方向
|
|
62
|
+
(`normal`/`reverse`/`alternate`/`alternate-reverse`)、填充模式
|
|
63
|
+
(`none`/`forwards`/`backwards`/`both`)与 `paused`/`running`。
|
|
64
|
+
|
|
65
|
+
当计算样式首次声明某个元素/名称时,`XtDocument` 启动一个活动动画;简写变化时
|
|
66
|
+
重新启动,无关的 restyle 不会打断它。每帧把本地时间解析为迭代进度,**逐个
|
|
67
|
+
关键帧区间**应用时间函数,并插值所有可动画属性。中间关键帧没有提到的属性会
|
|
68
|
+
在最近两个声明了它的关键帧之间继续插值(因此 0% 与 100% 声明的 transform
|
|
69
|
+
即使 50% 只改 `opacity` 也会贯穿全程)。缺失的 0%/100% 步骤使用元素的底层
|
|
70
|
+
样式;`forwards`/`backwards` 在活动时间之外保持边缘值,`computedStyle()`
|
|
71
|
+
报告动画后的值。
|
|
72
|
+
|
|
73
|
+
动画与 transition 共享 `animation_values.cpp`,因此属性集合、阴影列表与
|
|
74
|
+
`transform` 的 identity 补齐行为一致。
|
|
75
|
+
|
|
54
76
|
## CSS transform(M15)
|
|
55
77
|
|
|
56
78
|
`transform` 与 `transform-origin` 作为*绘制期*效果得到支持
|
|
@@ -89,5 +111,6 @@ const tick = (t: number): void => {
|
|
|
89
111
|
两种方式都由 `examples/gui/pelican-svg` 演示(逐帧摇摆 + 悬停时说明文字的
|
|
90
112
|
transition),并由 `tests/e2e/gui-transform.test.ts` 固定住。
|
|
91
113
|
|
|
92
|
-
|
|
114
|
+
任意可动画长度都可以使用 `calc()`(例如
|
|
115
|
+
`transition: width 300ms ease-out; width: calc(100% - 20px)`)。
|
|
93
116
|
|
package/doc/zh-CN/gui/api.md
CHANGED
|
@@ -128,7 +128,8 @@ requestAnimationFrame(frame);
|
|
|
128
128
|
`getChannelData(i)` 是真正的 `Float32Array`,可以用代码逐样本填充。
|
|
129
129
|
`decodeAudioData(bytes)` 返回解码后的 AudioBuffer Promise:WAV(PCM 8/16/24/32 位、
|
|
130
130
|
IEEE float 32/64、A-law 与 µ-law)由引擎自身解码;MP3、AAC/M4A、Vorbis、Opus 与 FLAC
|
|
131
|
-
需要可选的 `media`
|
|
131
|
+
需要可选的 `media` 链接特性(程序调用 `decodeAudioData` 时自动选中),以其中的
|
|
132
|
+
FFmpeg 解码器作为回退。
|
|
132
133
|
`bytes` 可以是 ArrayBuffer、类型化数组、Node `Buffer`,或 `fs.readFileSync`
|
|
133
134
|
返回的原始字节字符串(本运行时没有专门的二进制类型,而该字符串的存储正是文件字节)。
|
|
134
135
|
解码结果会重采样到上下文的 48 kHz,因此 `buffer.sampleRate` 与
|