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
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
# 扩展:Node 模块、GUI
|
|
1
|
+
# 扩展:Node 模块、GUI、链接特性、C++/Rust 库
|
|
2
2
|
|
|
3
3
|
编译器核心与平台无关。任何与平台相关的东西——Node 的 `fs`、一个 HTML/CSS 渲染器、
|
|
4
4
|
你自己的 C++ 库——都以**扩展**的形式接入:它既贡献模块绑定,也贡献要一起编译/链接的
|
|
5
|
-
C/C++
|
|
5
|
+
C/C++ 源码或目标文件。扩展里的重型可选部分(FFmpeg、glslang)做成**链接特性**,
|
|
6
|
+
由程序用法选择,而不是单独的扩展开关。
|
|
6
7
|
|
|
7
8
|
## 最容易踩的规则
|
|
8
9
|
|
|
@@ -70,8 +71,9 @@ import { createWindow, run } from "gui";
|
|
|
70
71
|
`<style>` 块(运行时解析器只读取内联 `<style>`);并让随包引入的 Three.js 的
|
|
71
72
|
`WebGLRenderer` 先探测 WebGL 上下文:引擎有上下文时使用 Three.js 自己的渲染器,
|
|
72
73
|
直接使用真实的 WebGL 2 后端(只修补其着色器循环展开,不再打包 Canvas2D 回退)。
|
|
73
|
-
`<img>`
|
|
74
|
-
|
|
74
|
+
`<img>` 由引擎自身解码;`<video>`/`<audio>` 解码(FFmpeg)与 GLSL 翻译(glslang)
|
|
75
|
+
是**可选的链接特性**,由程序自动选择——见
|
|
76
|
+
[可选链接特性](#可选链接特性media-gpu-images-shaping-webgl)。也支持 `<canvas>`:
|
|
75
77
|
`getContext("2d")` 返回的上下文,其填充、路径、
|
|
76
78
|
渐变、文本与 `drawImage` 由自研 CPU 光栅器处理(另有线段端点/连接、虚线描边、
|
|
77
79
|
`ellipse` 与 `roundRect`),元素句柄还暴露 `width`/`height`。CSS
|
|
@@ -79,8 +81,13 @@ import { createWindow, run } from "gui";
|
|
|
79
81
|
图像与子元素)可以被平移、缩放与旋转而不触发任何重排——可以用
|
|
80
82
|
`requestAnimationFrame` 逐帧驱动,或写成 `transition: transform`(见
|
|
81
83
|
`examples/gui/pelican-svg`)。CSS 子集还覆盖 `@media`、`::before`/`::after`
|
|
82
|
-
生成内容、线性/径向多层背景、`text-shadow
|
|
83
|
-
|
|
84
|
+
生成内容、线性/径向多层背景、`calc()`、真正的 `text-shadow`/`box-shadow`
|
|
85
|
+
高斯模糊、`clip-path`、`filter` 颜色效果、`backdrop-filter` 合成、
|
|
86
|
+
`@keyframes` 与 `transition`/`animation` 时间函数、`letter-spacing`、
|
|
87
|
+
`text-transform`、行内级 `flex`/`grid`、`grid-area`、`aspect-ratio`、自动
|
|
88
|
+
外边距、百分比 `border-radius`、`outline`、`url()` 图层的平铺
|
|
89
|
+
`background-size`、SVG 子元素上的文档 CSS,以及仅文本的竖排书写模式。`filter: blur()`
|
|
90
|
+
仍是有文档说明的近似。
|
|
84
91
|
因为主体是 C++,它以各平台预编译的 `gui.a`/`gui.lib` 形式分发。如果该
|
|
85
92
|
平台的归档不存在,构建会以明确的提示失败;设计与路线图见 [../../zh-CN/gui.md](../../zh-CN/gui.md)(总览;引擎按功能拆分在 [`doc/zh-CN/gui/`](../../zh-CN/gui/) 下),
|
|
86
93
|
脚本接口见 [../../zh-CN/gui-scripts.md](../../zh-CN/gui-scripts.md)。Canvas API
|
|
@@ -91,38 +98,57 @@ import { createWindow, run } from "gui";
|
|
|
91
98
|
`getComputedStyle`、`alert`/`prompt`、`escape`、`Event` 家族,以及可用的 Web Audio
|
|
92
99
|
实现(`AudioContext` 提供 gain、oscillator、buffer-source、biquad、compressor、
|
|
93
100
|
stereo-panner、constant-source 与 delay 节点、真实的 48 kHz 混音器、逐采样的
|
|
94
|
-
AudioParam 自动化,`decodeAudioData` 引擎内解码 WAV,压缩格式则通过 `media
|
|
101
|
+
AudioParam 自动化,`decodeAudioData` 引擎内解码 WAV,压缩格式则通过 `media` 特性)—— 另外还有帧泵:
|
|
95
102
|
它在 `loadHTML` 时启动,仅在仍有动画帧回调时重新排程,因此从不调用 `run()` 的页面
|
|
96
103
|
也能绘制并最终退出。**WebGL 1.0 与 2.0 已实现**:`canvas.getContext("webgl")` /
|
|
97
104
|
`"webgl2"` 返回 GPU 上下文,其 GLSL ES 着色器由内置 glslang 编译为 SPIR-V
|
|
98
105
|
(Vulkan 直接消费,Metal 上由内置 SPIRV-Cross 转成 MSL),
|
|
99
106
|
并通过 SDL_GPU 绘制;页面直接合成颜色纹理而无须 CPU 读回,WebGL 2 还增加
|
|
100
107
|
VAO、实例化、整数属性、采样器对象、`texStorage2D` 与缓冲拷贝(见
|
|
101
|
-
[../../zh-CN/gui/webgl.md](../../zh-CN/gui/webgl.md))。WebXR
|
|
102
|
-
`
|
|
108
|
+
[../../zh-CN/gui/webgl.md](../../zh-CN/gui/webgl.md))。WebXR 与流式接口**尚未实现**:
|
|
109
|
+
`typeof` 会回答
|
|
103
110
|
`"undefined"`,让页面走自己的降级分支。`fetch` 不是 GUI 扩展的功能——它由核心
|
|
104
111
|
运行时提供(`http://`,以及本地 `file://` 与相对路径;不支持 HTTPS 与流式),
|
|
105
112
|
因此 GUI 程序同样可用。见 [../../implemented/fetch.md](../../implemented/fetch.md)。
|
|
106
113
|
|
|
107
|
-
###
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
`
|
|
111
|
-
|
|
114
|
+
### 可选链接特性(media、gpu、images、shaping、webgl)
|
|
115
|
+
|
|
116
|
+
`gui` 仍然只有一个扩展,但其中的重型部分是可选的**链接特性**。编译器扫描打包后的
|
|
117
|
+
HTML/CSS/TS(导入的 `.html` 与内联 CSS 都属于 bundle),按程序自动选择;不需要额外
|
|
118
|
+
扩展参数:
|
|
119
|
+
|
|
120
|
+
- **`media`** —— `<video>`/`<audio>` 与压缩格式 `decodeAudioData` 的 FFmpeg 解码。
|
|
121
|
+
由 `<video>`/`<audio>` 元素、`createElement("video"/"audio")`、`new Audio()`、
|
|
122
|
+
`decodeAudioData` 或运行时拼出的 markup 触发,链接 FFmpeg 后端
|
|
123
|
+
`media.a`/`media.lib`。
|
|
124
|
+
- **`gpu`** —— WebGL 与 `mix-blend-mode` 共用的 glslang/SPIRV-Cross GLSL 翻译器。
|
|
125
|
+
由 `getContext("webgl"/"webgl2"/…)`(或运行时决定的 kind)、任意 `webgl` 字符串、
|
|
126
|
+
`mix-blend-mode` 触发。
|
|
127
|
+
- **`images`** —— `<img>`、内联 `<svg>`、CSS `background-image`/`url(...)`、
|
|
128
|
+
`drawImage`/`createImageBitmap`/`Image` 与应用图标所需的 stb_image/NanoSVG 解码。
|
|
129
|
+
纯文本页面两个解码器都不链接。
|
|
130
|
+
- **`shaping`** —— HarfBuzz + FreeType 提供的完整 OpenType 整形(连字、复杂文种)
|
|
131
|
+
与 CFF/OTF/可变字体支持。非 ASCII 文本(或转义/实体码点)或作者的
|
|
132
|
+
`@font-face` 规则会自动选中;纯拉丁页面保持 stb_truetype 后端,两个库都不链接。
|
|
133
|
+
- **`webgl`** —— WebGL context 与 DOM 绑定。由 WebGL 的 `getContext(...)` 或
|
|
134
|
+
`webgl` 字符串触发;它依赖 `gpu`,两者一起激活。不用 WebGL 的页面两者都不链接。
|
|
135
|
+
|
|
136
|
+
用 `--feature media,gpu,images,shaping,webgl`(或 `all`)覆盖扫描,用 `--no-feature media`
|
|
137
|
+
强制不链接。`--verbose` 会打印选中的集合。只渲染 HTML/CSS/2D canvas 的程序既不链接
|
|
138
|
+
FFmpeg、glslang,也不链接图片解码器、HarfBuzz/FreeType 或 WebGL context;用运行时数据拼 HTML/CSS 的
|
|
139
|
+
页面应传 `--feature all`,因为扫描看不到它。
|
|
140
|
+
自动检测到的特性归档缺失时构建打印 warning,能力在运行时降级(媒体元素触发
|
|
141
|
+
`error`);显式强制的特性则报错。
|
|
112
142
|
|
|
113
143
|
DOM API 与普通 HTML 媒体元素一致:`play()` / `pause()` / `load()`,以及
|
|
114
144
|
`paused` / `ended` / `duration` / `currentTime` / `volume` / `muted` / `loop` /
|
|
115
145
|
`autoplay` / `videoWidth` / `videoHeight` / `readyState` / `src` 属性,还有
|
|
116
146
|
`loadedmetadata`/`play`/`pause`/`ended`/`timeupdate`/`error` 事件。没有内置
|
|
117
147
|
控件——用元素和 CSS 自绘控件(见 `examples/gui/media.ts`)。视频帧与音频 PCM
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
自带的 bash)与原生 GNU make(Chocolatey `make`,或 `xbintsc_MAKE`)。见
|
|
123
|
-
[../../zh-CN/gui/build.md](../../zh-CN/gui/build.md)。
|
|
124
|
-
没有归档、或宿主上还没运行 `npm run media` 时,媒体元素会触发 `error`;见
|
|
125
|
-
[../../zh-CN/gui/known-issues.md](../../zh-CN/gui/known-issues.md)。
|
|
148
|
+
都在主线程解码;视频走图像纹理路径。Windows 上构建归档需要 POSIX shell(Git for
|
|
149
|
+
Windows 自带的 bash)与原生 GNU make(Chocolatey `make`,或 `xbintsc_MAKE`)。见
|
|
150
|
+
[../../zh-CN/gui/build.md](../../zh-CN/gui/build.md) 与
|
|
151
|
+
[../../zh-CN/gui/media.md](../../zh-CN/gui/media.md)。
|
|
126
152
|
|
|
127
153
|
## 第三方 npm 包
|
|
128
154
|
|
|
@@ -113,14 +113,15 @@ npm 包会提供它(去掉 `--omit=optional` 重新安装),但普通源码
|
|
|
113
113
|
|
|
114
114
|
### `media native library not found at …`
|
|
115
115
|
|
|
116
|
-
`<video>`/`<audio>`
|
|
116
|
+
`<video>`/`<audio>` 解码需要可选的 `media` 链接特性及其归档(`media.a`,Windows 上是
|
|
117
117
|
`media.lib`)。发布为其构建时,`@xbintsc/<os>-<arch>` npm 包会提供它;否则用
|
|
118
|
-
`npm run media`
|
|
119
|
-
|
|
120
|
-
|
|
118
|
+
`npm run media` 构建。自动选中该特性而归档缺失时,构建打印 **warning** 后继续,
|
|
119
|
+
媒体元素只会触发 `error`;显式 `--feature media`(或弃用的 `--ext media`)则直接
|
|
120
|
+
报错。可以用 `--no-feature media` 主动关闭。Windows 上 FFmpeg 的
|
|
121
121
|
构建还需要 POSIX shell(Git for Windows 的 bash)与原生 GNU make
|
|
122
122
|
(Chocolatey `make`,或 `xbintsc_MAKE`)。脚本会指出缺失的是哪一个。见
|
|
123
|
-
[../../zh-CN/gui/build.md](../../zh-CN/gui/build.md)
|
|
123
|
+
[../../zh-CN/gui/build.md](../../zh-CN/gui/build.md) 与
|
|
124
|
+
[../../zh-CN/gui/build.md#链接特性](../../zh-CN/gui/build.md#链接特性)。
|
|
124
125
|
|
|
125
126
|
### `Icon file not found` / 图标工具缺失
|
|
126
127
|
|
package/doc/gui/animation.md
CHANGED
|
@@ -30,21 +30,27 @@ running transition is recorded and re-applied every frame until it finishes;
|
|
|
30
30
|
the engine advances the clock with real frame deltas (`XtDocument::advance`),
|
|
31
31
|
and `win.advance(ms)` lets tests step it deterministically.
|
|
32
32
|
|
|
33
|
-
- Supported properties: `background-color`, `color`, `border-color`,
|
|
34
|
-
`border-radius
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
- Supported properties: `background-color`, `color`, `border-color`, `opacity`,
|
|
34
|
+
`border-radius`, `transform`, `text-shadow`, `box-shadow`, every box offset
|
|
35
|
+
and size length (`width`/`height`/`top`/`left`/`margin-*`/`padding-*`/…), the
|
|
36
|
+
gap/flex-basis lengths and `filter` (matching filter lists interpolate their
|
|
37
|
+
blur lengths, amounts and drop-shadow colours). `transition: all` covers the
|
|
38
|
+
whole list. Lengths
|
|
39
|
+
interpolate when their units line up (a mixed-unit change is CSS's discrete
|
|
40
|
+
fallback); `opacity`, colours and `transform` interpolate normally.
|
|
38
41
|
- Both the `transition` shorthand and the `transition-property` / `-duration` /
|
|
39
42
|
`-delay` / `-timing-function` longhands are parsed; time values accept `s` and
|
|
40
|
-
`ms`;
|
|
41
|
-
|
|
43
|
+
`ms`; `calc()` is accepted inside the shorthand and longhands.
|
|
44
|
+
- Timing functions are `linear`, `ease`, `ease-in`, `ease-out`, `ease-in-out`,
|
|
45
|
+
`cubic-bezier(x1, y1, x2, y2)`, `steps(n, start|end)` and their `jump-*`
|
|
46
|
+
spellings. The engine solves the cubic Bézier numerically; keyword curves use
|
|
47
|
+
the CSS control points.
|
|
42
48
|
- Retargeting mid-flight starts a new transition from the current interpolated
|
|
43
49
|
value, so reversing a hover animates smoothly from wherever it was.
|
|
44
50
|
- `computedStyle()` reports the displayed (interpolated) value, so transitions
|
|
45
51
|
are directly observable in tests.
|
|
46
52
|
|
|
47
|
-
`transform` lists interpolate **element-wise** (`
|
|
53
|
+
`transform` lists interpolate **element-wise** (`animation_values.cpp`,
|
|
48
54
|
`xt_transform_interpolate`), which is what makes the common pair
|
|
49
55
|
`translateY(-4px) rotate(-0.35deg)` <-> `none` glide instead of jumping: the
|
|
50
56
|
missing side is filled with identity ops of the same kind. Two lists whose shapes
|
|
@@ -52,6 +58,29 @@ or units do not line up (`rotate(10deg)` vs `rotate(10rad)`, or a different numb
|
|
|
52
58
|
of functions) are not interpolated at all — the transition snaps to the target,
|
|
53
59
|
which is CSS's discrete fallback rather than a wrong-looking sweep.
|
|
54
60
|
|
|
61
|
+
## CSS animations (`@keyframes`)
|
|
62
|
+
|
|
63
|
+
`@keyframes` rules are parsed into `StyleSheet::keyframes` (offsets from
|
|
64
|
+
`from`/`to`/percent selectors, sorted). `animation` and every `animation-*`
|
|
65
|
+
longhand are supported: name, duration, delay, timing function, iteration count
|
|
66
|
+
(including `infinite`), direction (`normal`/`reverse`/`alternate`/
|
|
67
|
+
`alternate-reverse`), fill mode (`none`/`forwards`/`backwards`/`both`) and
|
|
68
|
+
`paused`/`running`.
|
|
69
|
+
|
|
70
|
+
`XtDocument` starts one active animation per element/name when the computed
|
|
71
|
+
style first declares it, restarts it when the shorthand changes, and leaves it
|
|
72
|
+
alone across unrelated restyles. Each frame it resolves the local time to an
|
|
73
|
+
iteration progress, applies the timing function **per keyframe interval**, and
|
|
74
|
+
interpolates every animatable property. A property that a middle keyframe does
|
|
75
|
+
not mention keeps interpolating between the nearest keyframes that do declare
|
|
76
|
+
it (so a transform declared at 0% and 100% runs straight through a 50% step that
|
|
77
|
+
only changes `opacity`). Missing 0%/100% steps use the element's underlying
|
|
78
|
+
style. `forwards`/`backwards` hold the edge value outside the active time, and
|
|
79
|
+
`computedStyle()` reports the animated value.
|
|
80
|
+
|
|
81
|
+
Animations and transitions share `animation_values.cpp`, so both understand the
|
|
82
|
+
same property set, shadow lists and `transform` identity filling.
|
|
83
|
+
|
|
55
84
|
## CSS transforms (M15)
|
|
56
85
|
|
|
57
86
|
`transform` and `transform-origin` are supported as *paint-time* effects
|
|
@@ -93,5 +122,6 @@ Both are exercised by `examples/gui/pelican-svg` (per-frame sway plus a
|
|
|
93
122
|
hover transition on the caption) and pinned by
|
|
94
123
|
`tests/e2e/gui-transform.test.ts`.
|
|
95
124
|
|
|
96
|
-
|
|
125
|
+
`calc()` can be used in any animated length (for example
|
|
126
|
+
`transition: width 300ms ease-out; width: calc(100% - 20px)`).
|
|
97
127
|
|
package/doc/gui/api.md
CHANGED
|
@@ -137,7 +137,8 @@ evaluated per sample, so a ramp keeps moving while the page is idle.
|
|
|
137
137
|
procedurally. `decodeAudioData(bytes)` returns a promise for a decoded
|
|
138
138
|
AudioBuffer: WAV (PCM 8/16/24/32-bit, IEEE float 32/64, A-law and µ-law) is
|
|
139
139
|
decoded by the engine itself; MP3, AAC/M4A, Vorbis, Opus and FLAC need the
|
|
140
|
-
optional `media`
|
|
140
|
+
optional `media` link feature (auto-selected when the program calls
|
|
141
|
+
`decodeAudioData`), whose FFmpeg decoder is used as
|
|
141
142
|
the fallback. `bytes` may be an ArrayBuffer, a typed array, a Node `Buffer`, or
|
|
142
143
|
the raw byte string `fs.readFileSync` returns (this runtime has no dedicated
|
|
143
144
|
binary type, and that string's storage is exactly the file bytes). The result
|
package/doc/gui/build.md
CHANGED
|
@@ -8,13 +8,33 @@
|
|
|
8
8
|
`runtime/ext_media/` and is built separately.
|
|
9
9
|
- `npm run gui` (`scripts/build-gui.ts`) fetches a pinned SDL3 (`SDL3_TAG`,
|
|
10
10
|
default `release-3.2.10`), builds a static SDL3, fetches and builds static
|
|
11
|
-
FreeType (`FREETYPE_VERSION
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
**FreeType** (`FREETYPE_VERSION`, default `2.13.3`) and **HarfBuzz**
|
|
12
|
+
(`HARFBUZZ_VERSION`, default `10.1.0`) for the optional `shaping` feature,
|
|
13
|
+
and fetches and builds static **glslang** (`GLSLANG_VERSION`, default
|
|
14
|
+
`16.6.0`) against the pinned SPIR-V headers (`SPIRV_HEADERS_VERSION`), and —
|
|
15
|
+
**on macOS only** — **SPIRV-Cross** (`SPIRV_CROSS_VERSION`, default
|
|
16
|
+
`vulkan-sdk-1.4.313.0`). glslang is the runtime GLSL ES compiler behind WebGL
|
|
17
|
+
and SPIRV-Cross turns its SPIR-V into MSL for the Metal backend (see
|
|
18
|
+
[WebGL](./webgl.md)); both are merged into the archive like the other
|
|
19
|
+
libraries. Metal is the only SDL_GPU backend that consumes MSL, so on
|
|
20
|
+
Windows/Linux the script neither fetches nor merges SPIRV-Cross:
|
|
21
|
+
`webgl_msl.cpp` compiles to nothing there and the ~2.5 MiB it contributes
|
|
22
|
+
would be unreachable. The default text path uses the bundled
|
|
23
|
+
**stb_truetype** (`runtime/ext_gui/stb_truetype.h`); HarfBuzz + FreeType are
|
|
24
|
+
only extracted when the `shaping` feature is active.
|
|
25
|
+
Every library (SDL3, FreeType, HarfBuzz, glslang, SPIRV-Cross and the engine)
|
|
26
|
+
is compiled with `-ffunction-sections -fdata-sections`, and SDL is configured
|
|
27
|
+
without the subsystems the engine never calls (`SDL_JOYSTICK`, `SDL_HAPTIC`,
|
|
28
|
+
`SDL_SENSOR`, `SDL_CAMERA`, `SDL_RENDER`, `SDL_OPENGL`/`SDL_OPENGLES`,
|
|
29
|
+
`SDL_OFFSCREEN`, `SDL_HIDAPI`). HarfBuzz omits the APIs the shaping backend
|
|
30
|
+
never uses (`HB_NO_DRAW`/`PAINT`/`COLOR`/`NAME`/`STYLE`/`METRICS`/…, while
|
|
31
|
+
keeping `CFF`/`OPEN`/`VAR` for OTF and variable fonts) and is built with
|
|
32
|
+
`HB_NO_PRAGMA_GCC_DIAGNOSTIC_ERROR`, because `src/hb.hh` raises its warning
|
|
33
|
+
set to errors and two lean defines leave macOS/CoreText helpers unreferenced
|
|
34
|
+
(`HB_NO_MMAP` and `HB_NO_OT_FONT_GLYPH_NAMES`). The linker then drops
|
|
35
|
+
the unreachable functions (`--gc-sections`, `-dead_strip`, or link.exe's
|
|
36
|
+
default `/OPT:REF`). The
|
|
37
|
+
script then compiles the engine and
|
|
18
38
|
merges everything into `runtime/lib/<os>-<arch>/gui.a` (or
|
|
19
39
|
`gui.lib` with the MSVC ABI on Windows), same convention as `core.a`,
|
|
20
40
|
statically bundling all three. The merge uses `libtool` on macOS and
|
|
@@ -25,13 +45,17 @@
|
|
|
25
45
|
minimal static build with only the demuxers/parsers/decoders the media
|
|
26
46
|
elements need, compiles `runtime/ext_media/media.cpp` against it and merges
|
|
27
47
|
everything into `runtime/lib/<os>-<arch>/media.a` (`media.lib` with the MSVC
|
|
28
|
-
ABI on Windows). `gui.a` does **not** link FFmpeg:
|
|
29
|
-
|
|
48
|
+
ABI on Windows). `gui.a` does **not** link FFmpeg: the compiler selects the
|
|
49
|
+
`media` link feature for a program that may play media and only then links
|
|
50
|
+
`media.a` (see [Link features](#link-features)).
|
|
30
51
|
- `src/extensions/gui/index.ts` exposes the engine archive through
|
|
31
52
|
`nativeObjects()` (via `findRuntimeLibrary`, so `.a`/`.lib` both work) and the
|
|
32
|
-
OS frameworks through `linkerFlags()`. `
|
|
33
|
-
|
|
34
|
-
|
|
53
|
+
OS frameworks through `linkerFlags()`. Its `linkFeatures()` (in
|
|
54
|
+
`src/extensions/gui/features.ts`) declares `media`, `gpu`, `images`, `shaping` and `webgl`; the driver
|
|
55
|
+
compiles their bridges only when a feature is active.
|
|
56
|
+
- glslang (and SPIRV-Cross on macOS) is merged into `gui.a` like SDL3, but the
|
|
57
|
+
engine reaches it only through the `gpu` feature's dispatch table. A program
|
|
58
|
+
that never compiles GLSL does not extract those archive members.
|
|
35
59
|
- `scripts/build-gui.ts` compiles with the *same* clang the driver resolves
|
|
36
60
|
(`src/driver/toolchain-provider.ts`); on Windows that is the MSVC-targeting
|
|
37
61
|
LLVM bundled with Visual Studio, and its sibling `clang++`/`llvm-ar` are used
|
|
@@ -59,11 +83,12 @@
|
|
|
59
83
|
- CI builds `gui.a`/`gui.lib` and `media.a`/`media.lib` before assembling the
|
|
60
84
|
release archive so they ship inside `runtime/lib/<slug>/` (the release tarball
|
|
61
85
|
copies the whole `runtime/` tree). The same folders are packed into the
|
|
62
|
-
optional `@xbintsc/<slug>` npm package, so `--ext gui
|
|
86
|
+
optional `@xbintsc/<slug>` npm package, so `--ext gui` (with automatic
|
|
87
|
+
`media`/`gpu`/`images`/`shaping`/`webgl` selection) works from
|
|
63
88
|
an npm install on the hosts the release builds for. The archives are built and
|
|
64
89
|
the examples are run on Linux (under Xvfb, with the lavapipe software Vulkan
|
|
65
90
|
driver) and macOS;
|
|
66
|
-
the Windows x64 job builds both archives and links a `gui
|
|
91
|
+
the Windows x64 job builds both archives and links a `gui` program, so
|
|
67
92
|
the MSVC build is validated even though *running* the examples there stays
|
|
68
93
|
provisional (the hosted runner has no GPU/Vulkan driver). The macOS run is
|
|
69
94
|
provisional too: the Intel runner's virtualised GPU lacks
|
|
@@ -82,8 +107,9 @@
|
|
|
82
107
|
- The existing cache fingerprint already hashes `nativeObjects()` contents and
|
|
83
108
|
`runtimeSources()` content, so rebuilding either archive invalidates cached
|
|
84
109
|
binaries automatically.
|
|
85
|
-
- CMake build trees live *next to* their sources (`vendor/sdl-build`,
|
|
86
|
-
`vendor/freetype-build`, `vendor/harfbuzz-build
|
|
110
|
+
- CMake build trees live *next to* their sources (`vendor/sdl-build-lean`,
|
|
111
|
+
`vendor/freetype-build-lean`, `vendor/harfbuzz-build-lean`,
|
|
112
|
+
`vendor/glslang-build-lean`, `vendor/spirv-cross-build-lean`), never inside them: a
|
|
87
113
|
`CMakeCache.txt` records the machine it was configured on, and SDL's video
|
|
88
114
|
backends are `option()`s, so the first configure to run wins. A cached
|
|
89
115
|
`vendor/SDL` tree that also carried `build/` therefore restored one machine's
|
|
@@ -95,6 +121,97 @@
|
|
|
95
121
|
`xbintsc_SKIP_HEADER_CHECK=1` when they live under a prefix that check does
|
|
96
122
|
not know).
|
|
97
123
|
|
|
124
|
+
## Link features
|
|
125
|
+
|
|
126
|
+
`gui` is the only user-facing extension, but two heavy halves are **optional link
|
|
127
|
+
features** selected per program:
|
|
128
|
+
|
|
129
|
+
| Feature | What it links | Selected when the program may use it |
|
|
130
|
+
| --- | --- | --- |
|
|
131
|
+
| `media` | `media_bridge.c` + `media.a` (FFmpeg) | an HTML `<video>`/`<audio>` tag, `createElement("video"/"audio")`, `new Audio()`, `decodeAudioData`, or runtime-built markup |
|
|
132
|
+
| `gpu` | `gpu_bridge.c` (the implementation is already in `gui.a`) | a `getContext("webgl"/"webgl2"/"experimental-webgl")` (or a kind decided at run time), any `webgl` string, `mix-blend-mode`/`mixBlendMode`, or runtime-built markup |
|
|
133
|
+
| `images` | `image_bridge.c` (the implementation is already in `gui.a`) | `<img>`, inline `<svg>`, `background-image`/`url(...)`, a `.svg` path, `drawImage`/`createImageBitmap`/`Image`, or runtime-built markup |
|
|
134
|
+
| `shaping` | `text_bridge.c` (the implementation is already in `gui.a`) | non-ASCII text (CJK/Cyrillic/Greek/…), an escaped/entity codepoint, an author `@font-face` rule (custom fonts may be CFF/OTF), or runtime-built markup |
|
|
135
|
+
| `webgl` | `webgl_bridge.c` (the implementation is already in `gui.a`; requires `gpu`) | a WebGL `getContext(...)`, a `webgl` string, or runtime-built markup |
|
|
136
|
+
|
|
137
|
+
The driver scans the bundled AST (`src/driver/usage.ts`): every string literal
|
|
138
|
+
(including imported `.html` and the CSS inlined from it), identifiers and
|
|
139
|
+
property names, each `getContext(...)` kind, and whether HTML/CSS can be built
|
|
140
|
+
from data the compiler cannot see. Simple `const` aliases are resolved;
|
|
141
|
+
anything unresolved makes the program “dynamic markup” and enables the optional
|
|
142
|
+
features conservatively.
|
|
143
|
+
|
|
144
|
+
When a feature is active, the driver compiles its C **bridge only for that
|
|
145
|
+
build** and links it before `gui.a`:
|
|
146
|
+
|
|
147
|
+
- `media` → `runtime/ext_media/media_bridge.c`; its constructor installs the
|
|
148
|
+
decoder table and references `xt_media_backend_*`, which is what extracts the
|
|
149
|
+
FFmpeg members from `media.a`.
|
|
150
|
+
- `gpu` → `runtime/ext_gui/gpu_bridge.c`; its constructor calls
|
|
151
|
+
`xt_gpu_feature_register` in `gpu_feature.cpp`, which installs the
|
|
152
|
+
`XtGpuShaderApi` table and references `compile_glsl` / `cross_compile_msl` /
|
|
153
|
+
the reflection helpers, extracting glslang (and SPIRV-Cross on macOS).
|
|
154
|
+
- `images` → `runtime/ext_gui/image_bridge.c`; its constructor installs
|
|
155
|
+
`XtImageApi` via `image_feature.cpp`, which references stb_image and NanoSVG.
|
|
156
|
+
Layout, paint, the canvas `drawImage` path and the app-icon path call through
|
|
157
|
+
that table, so a text-only page links neither decoder.
|
|
158
|
+
- `shaping` → `runtime/ext_gui/text_bridge.c`; its constructor installs
|
|
159
|
+
`TextApi` via `text_hb.cpp`, which references HarfBuzz and FreeType. Without
|
|
160
|
+
it the engine uses the built-in stb_truetype backend, so a Latin-only page
|
|
161
|
+
links neither library.
|
|
162
|
+
- `webgl` → `runtime/ext_gui/webgl_bridge.c`; its constructor installs
|
|
163
|
+
`XtWebglApi` via `webgl_feature.cpp`, which references the WebGL context and
|
|
164
|
+
DOM bindings. The core reaches `getContext`, the canvas width/height setters,
|
|
165
|
+
`createImageBitmap`, the host types and the renderer through that table, so a
|
|
166
|
+
page with no WebGL links none of `webgl_*`/`dom_api_webgl*`.
|
|
167
|
+
|
|
168
|
+
A bridge is the “strong reference” that makes the linker search the archive; with
|
|
169
|
+
no bridge, the engine's table stays null and the implementation members are never
|
|
170
|
+
extracted. That is why the large libraries can stay in the existing archives
|
|
171
|
+
without a new package layout.
|
|
172
|
+
|
|
173
|
+
Overrides: `--feature media,gpu,images,shaping,webgl` (or `all`) forces a
|
|
174
|
+
feature on; `--no-feature media` keeps it out even when detection finds a use.
|
|
175
|
+
`webgl` requires `gpu`, and the resolver activates both together. An app icon
|
|
176
|
+
forces `images` because the icon is decoded through the same pipeline. `--ext media`
|
|
177
|
+
is a deprecated alias for `--ext gui --feature media`. If an auto-detected
|
|
178
|
+
feature's archive is missing, the build warns and continues (the element/context
|
|
179
|
+
degrades as documented); a forced feature makes it an error.
|
|
180
|
+
|
|
181
|
+
> Detection is static by design. A page that builds HTML/CSS from `fetch`,
|
|
182
|
+
> `readFileSync` or other runtime data should pass `--feature all` (or the
|
|
183
|
+
> specific feature). `--verbose` prints the selected set, e.g.
|
|
184
|
+
> `xbintsc: link features: none`.
|
|
185
|
+
|
|
186
|
+
### Binary size
|
|
187
|
+
|
|
188
|
+
The lean build is what makes a DOM-only program small. On Windows x64 a
|
|
189
|
+
`hello`-sized program drops from roughly 6.4 MiB to about 3.1 MiB once SDL is
|
|
190
|
+
configured as above, function/data sections let `/OPT:REF` discard what the page
|
|
191
|
+
never reaches, the WebGL/images link features stay off, and text uses the
|
|
192
|
+
bundled stb_truetype instead of HarfBuzz + FreeType. The remaining weight is
|
|
193
|
+
mostly the static CRT, the lean SDL (~1 MiB), stb_truetype (~0.1 MiB), and the
|
|
194
|
+
DOM/CSS/layout/paint engine itself (~1.2 MiB). Linux and macOS use their own
|
|
195
|
+
linker sections (`--gc-sections`/`-dead_strip`) and differ somewhat, but the
|
|
196
|
+
relative ranking is the same.
|
|
197
|
+
|
|
198
|
+
WebGL and images/SVG are link features (roughly 0.4 MiB of WebGL context/DOM
|
|
199
|
+
code and 0.23 MiB of stb_image/NanoSVG that a DOM-only page does not link).
|
|
200
|
+
Canvas2D, Web Audio and the `mix-blend-mode` compositor are not gated yet; a
|
|
201
|
+
program that uses none of them still pays for their API surface (roughly
|
|
202
|
+
0.1–0.2 MiB each).
|
|
203
|
+
|
|
204
|
+
The text trade-off is deliberate. The default backend is stb_truetype: only
|
|
205
|
+
TrueType outlines and a per-codepoint mapping plus the font's `kern` table, so
|
|
206
|
+
CFF/OTF and variable fonts, OpenType ligatures and complex-script shaping
|
|
207
|
+
(Arabic/Indic/Thai) are not available. The fallback chain still selects another
|
|
208
|
+
face for codepoints the primary lacks. Selecting the optional **`shaping`**
|
|
209
|
+
feature (automatically for non-ASCII text or an author `@font-face` rule, or
|
|
210
|
+
with `--feature shaping`) links HarfBuzz + FreeType back in (~1.2 MiB) and
|
|
211
|
+
restores full OpenType shaping and CFF/OTF/variable-font support. A Latin-only
|
|
212
|
+
DOM page therefore stays near 3.1 MiB; a Chinese/complex-script page is closer
|
|
213
|
+
to 4.3 MiB.
|
|
214
|
+
|
|
98
215
|
## Running the example
|
|
99
216
|
|
|
100
217
|
```sh
|
|
@@ -133,10 +250,11 @@ its README for controls and the geometry report it prints.
|
|
|
133
250
|
|
|
134
251
|
`media.ts` (with `media.html`) demonstrates `<video>`/`<audio>`: it overlays a
|
|
135
252
|
CSS progress bar on the video and drives playback with `play()` / `pause()` /
|
|
136
|
-
`currentTime` / `volume`.
|
|
137
|
-
|
|
253
|
+
`currentTime` / `volume`. The compiler sees the elements in `media.html` and
|
|
254
|
+
links the `media` feature automatically; build `media.a` once with
|
|
255
|
+
`npm run media`. Media `src` paths resolve relative to the process working
|
|
138
256
|
directory, so run it from the repository root:
|
|
139
|
-
`xbintsc run examples/gui/media.ts --ext gui
|
|
257
|
+
`xbintsc run examples/gui/media.ts --ext gui`.
|
|
140
258
|
|
|
141
259
|
Set `XT_GUI_AUTOCLOSE_MS=<n>` to close all windows after `n` milliseconds,
|
|
142
260
|
which the e2e test (`tests/e2e/gui-*.test.ts`) uses to run headlessly.
|
package/doc/gui/canvas.md
CHANGED
|
@@ -191,7 +191,7 @@ non-finite entries are ignored, an all-zero list means a solid line).
|
|
|
191
191
|
|
|
192
192
|
Text: `measureText(text)` (returns `{ width }`), `fillText(text, x, y,
|
|
193
193
|
maxWidth?)` and `strokeText(text, x, y, maxWidth?)`. Text is shaped with
|
|
194
|
-
|
|
194
|
+
stb_truetype (shaped and rasterised) (the same stack as HTML text) at the
|
|
195
195
|
transform's approximate scale. A positive `maxWidth` condenses advances and
|
|
196
196
|
glyph bitmaps horizontally so the run is at most that wide (as the canvas API
|
|
197
197
|
specifies) instead of being ignored.
|
package/doc/gui/dom.md
CHANGED
|
@@ -21,11 +21,26 @@ commas, brackets or parentheses without splitting the list. Selectors: type,
|
|
|
21
21
|
`.class`, `#id`, attribute (`=`, `~=`, `|=`, `^=`, `$=`, `*=`), the four
|
|
22
22
|
combinators (descendant, child, adjacent and general sibling), the pseudo-classes
|
|
23
23
|
`:first-child`, `:last-child`, `:only-child`, `:empty`, `:root`, `:not(...)`,
|
|
24
|
-
`:nth-child(an+b)`, `:disabled`, `:checked`, plus the stateful `:hover
|
|
25
|
-
`:focus` (
|
|
24
|
+
`:nth-child(an+b)`, `:disabled`, `:checked`, plus the stateful `:hover`,
|
|
25
|
+
`:focus`, `:focus-visible` (currently an alias of `:focus`) and `:active` (see
|
|
26
|
+
[Input](./input.md)), and the pseudo-elements `::before`/`::after`
|
|
26
27
|
(legacy `:before`/`:after` too). Values: lengths (`px`, `%`, `em`, `rem`, `vw`,
|
|
27
28
|
`vh`, `pt`, `pc`, `in`, `cm`, `mm`, `q`), colors (hex, `rgb()`/`rgba()`, a named
|
|
28
|
-
subset), numbers, keywords and shorthands (`margin`/`padding`/`border`/`flex
|
|
29
|
+
subset), numbers, keywords and shorthands (`margin`/`padding`/`border`/`flex`/
|
|
30
|
+
`font`/`outline`). `display: inline-flex`/`inline-grid` make a flex/grid
|
|
31
|
+
container inline-level; `grid-area`, `aspect-ratio`, `letter-spacing`,
|
|
32
|
+
`text-transform`, `writing-mode` (`vertical-rl`/`vertical-lr` text),
|
|
33
|
+
`vertical-align` (length form), percentage `border-radius`, `background-size`
|
|
34
|
+
(size + default repeat for `url()` layers) and `currentColor` are parsed too.
|
|
35
|
+
`font-variant-numeric`, `text-wrap`, `text-rendering`, `touch-action`,
|
|
36
|
+
`user-select`, `overscroll-behavior`, `scroll-behavior`, `isolation` and
|
|
37
|
+
`vector-effect` are accepted but have no engine behaviour (the text stack exposes no OpenType features and the engine
|
|
38
|
+
has no touch/selection/smooth-scroll subsystem); `cursor` maps to the SDL system
|
|
39
|
+
cursor. A document rule may style SVG children with the presentation properties
|
|
40
|
+
`fill`, `fill-opacity`, `fill-rule`, `stroke`, `stroke-opacity`, `stroke-width`,
|
|
41
|
+
`stroke-dasharray`, `stroke-dashoffset`, `stroke-linecap` and `stroke-linejoin`;
|
|
42
|
+
the serializer writes them into the inline `<svg>` markup as NanoSVG-readable
|
|
43
|
+
inline styles. `skewX()`/`skewY()`/`skew()` transform functions are supported.
|
|
29
44
|
`transform` (`translate`/`translate3d`/`translateX`/`translateY`, `scale`/
|
|
30
45
|
`scale3d`/`scaleX`/`scaleY`, `rotate`/`rotateZ`, `matrix`; the `3d` spellings'
|
|
31
46
|
`z` argument is dropped) and `transform-origin` are parsed into the computed
|
|
@@ -33,7 +48,8 @@ style as a list of operations plus two (unresolved) origin lengths; an
|
|
|
33
48
|
unsupported function invalidates the whole declaration
|
|
34
49
|
([Layout](./layout.md#transforms-m15)). M19 adds `background-image` layer lists
|
|
35
50
|
(linear/radial), `clip-path` (`inset`/`circle`/`ellipse`/`polygon`), the
|
|
36
|
-
`filter`/`backdrop-filter` function lists, `text-shadow` and
|
|
51
|
+
`filter`/`backdrop-filter` function lists, `text-shadow`, `box-shadow` and
|
|
52
|
+
`content`.
|
|
37
53
|
|
|
38
54
|
**Cascade & computed style** (`runtime/ext_gui/style.{h,cpp}`): a small built-in
|
|
39
55
|
UA stylesheet, author rules sorted by `(!important, specificity, source order)`,
|
package/doc/gui/known-issues.md
CHANGED
|
@@ -22,6 +22,16 @@
|
|
|
22
22
|
shader unroller; `WebGLRenderer` runs on the real backend and there is no
|
|
23
23
|
Canvas2D fallback. Shadow maps (comparative `sampler2DShadow` targeting depth
|
|
24
24
|
textures), cube textures/environment maps and HDR render targets are supported.
|
|
25
|
+
- **Comparative samplers can miscompile on Intel Macs.** On an Intel GPU (seen
|
|
26
|
+
on Intel Iris Plus Graphics with macOS 26), the Metal shader compiler drops a
|
|
27
|
+
fragment function that calls `sample_compare`: the draw produces no pixels at
|
|
28
|
+
all, so `texture(sampler2DShadow, …)` reads black and shadow maps disappear.
|
|
29
|
+
The MSL is correct (`depth2d<float>` + `sample_compare`), the sampler carries
|
|
30
|
+
the comparison op, and the same program renders correctly once Metal GPU
|
|
31
|
+
shader validation is enabled — running with `MTL_SHADER_VALIDATION=1` makes
|
|
32
|
+
`tests/e2e/gui-webgl2-shadow-sampler.test.ts` pass on such a machine. That
|
|
33
|
+
points at the driver's shader compiler rather than the engine, so the
|
|
34
|
+
workaround is the environment variable; other Apple GPUs may not show it.
|
|
25
35
|
|
|
26
36
|
|
|
27
37
|
|
|
@@ -54,29 +64,37 @@
|
|
|
54
64
|
*class change* on a flex container has also been observed to crash the same
|
|
55
65
|
way; `examples/gui/pelican-bike` reveals its game-over overlay with `opacity`
|
|
56
66
|
instead.
|
|
57
|
-
- **CSS coverage is a deliberate subset.** Grid, `
|
|
58
|
-
`
|
|
59
|
-
`
|
|
60
|
-
|
|
61
|
-
(`
|
|
62
|
-
|
|
63
|
-
`
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
`
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
67
|
+
- **CSS coverage is a deliberate subset.** Grid, `calc()` (including
|
|
68
|
+
nested arithmetic and `calc()` inside `min()`/`max()`/`clamp()`),
|
|
69
|
+
`clamp()`/`min()`/`max()`/`env()`, `var()` custom properties, the `inset`
|
|
70
|
+
shorthand, `box-sizing`, `visibility` and `pointer-events`, `@media` queries,
|
|
71
|
+
generated content (`::before`/`::after`), multi-layer linear/radial
|
|
72
|
+
backgrounds, `text-shadow` (true Gaussian), `box-shadow` (outer/inset, spread,
|
|
73
|
+
multiple layers), `clip-path` (`inset`/`circle`/`ellipse`/`polygon`),
|
|
74
|
+
`filter` colour functions, `@keyframes` animations, the full `transition`
|
|
75
|
+
timing-function set, `letter-spacing`, `text-transform`, inline-level
|
|
76
|
+
`flex`/`grid`, `grid-area`, `aspect-ratio`, auto margins, percentage
|
|
77
|
+
`border-radius`, `outline`, `background-size` tiling for `url()` layers and
|
|
78
|
+
document CSS on SVG children (`fill`/`stroke`/…) are implemented. Known
|
|
79
|
+
limits: `background-clip`, `background-position` and `background-repeat`
|
|
80
|
+
remain unimplemented (`background-size` covers the tiled default);
|
|
81
|
+
`font-variant-numeric`, `text-wrap`, `text-rendering`, `touch-action`,
|
|
82
|
+
`user-select`, `overscroll-behavior`, `scroll-behavior`, `isolation` and
|
|
83
|
+
`vector-effect` are parsed but inert; vertical writing mode is text-only (nested/mixed content falls back to
|
|
84
|
+
horizontal); group `opacity` is
|
|
85
|
+
a per-shape alpha rather than a true group composite; the blend and
|
|
86
|
+
`backdrop-filter` compositors are unavailable on the D3D12/DXIL backend, where
|
|
87
|
+
groups fall back to normal source-over painting and the backdrop filter is
|
|
88
|
+
skipped. `filter: blur()` is still a nine-tap per-shape spread rather than a
|
|
89
|
+
true group blur, so overlapping descendants can darken; `drop-shadow` is
|
|
90
|
+
approximated from box silhouettes; at most two nested `clip-path` shapes are
|
|
91
|
+
intersected (deeper nesting keeps the outer two); and images/canvases are not
|
|
92
|
+
colour-filtered except for the brightness/opacity tint the image shader can
|
|
93
|
+
carry. Canvas textures are sampled nearest-neighbour. Background gradients
|
|
94
|
+
(linear and radial) are rasterised per pixel into a texture and then stretched
|
|
95
|
+
when the box is larger than the texture (1024 px per edge for a radial ramp,
|
|
96
|
+
4096 px along the line for a linear one, which is only one texel thick across
|
|
97
|
+
it), so a hard stop in a very large box can come out slightly soft.
|
|
80
98
|
- **SVG is NanoSVG's subset.** SVG *files* (`<img src="logo.svg">`) and inline
|
|
81
99
|
`<svg>` trees share the vendored NanoSVG parser/rasteriser
|
|
82
100
|
(`runtime/ext_gui/svg.cpp`, `inline_svg.cpp`), which renders
|
|
@@ -111,6 +129,22 @@
|
|
|
111
129
|
bottleneck. Inline `style="…"` attributes are re-parsed on each restyle of
|
|
112
130
|
the element that carries them.
|
|
113
131
|
|
|
132
|
+
- **Text shaping is a simple shaper.** stb_truetype handles Latin/CJK/Cyrillic/
|
|
133
|
+
Greek with basic `kern` and per-codepoint fallback, but it does not run
|
|
134
|
+
OpenType ligatures or complex-script shaping (Arabic/Indic/Thai), and it only
|
|
135
|
+
accepts TrueType outlines (no CFF/OTF or variable fonts). Colour emoji are not
|
|
136
|
+
rendered as colour. This is the price of the ~3 MiB DOM-only binary; the
|
|
137
|
+
optional `shaping` feature restores HarfBuzz + FreeType (and full
|
|
138
|
+
complex-script shaping).
|
|
139
|
+
- **Link-feature detection is static.** `media`/`gpu`/`images`/`shaping`/`webgl` are selected from the
|
|
140
|
+
bundled HTML/CSS/TS (including imported `.html` and the CSS inlined from it).
|
|
141
|
+
A page that builds markup or CSS from runtime data (`fetch`, `readFileSync`,
|
|
142
|
+
a value returned by a function) cannot be seen; the scanner falls back to
|
|
143
|
+
enabling both when it can prove the sink is dynamic, but an opaque value that
|
|
144
|
+
it cannot classify needs an explicit `--feature media`/`gpu`/`images`/`shaping`/`webgl` (or `all`).
|
|
145
|
+
`--verbose` prints the selected set. See
|
|
146
|
+
[Link features](./build.md#link-features).
|
|
147
|
+
|
|
114
148
|
## Open questions
|
|
115
149
|
|
|
116
150
|
- Whether Linux ships X11, Wayland, or both in the first cut. (Decision:
|
|
@@ -130,7 +164,8 @@
|
|
|
130
164
|
- Windows: an MSVC-compatible `gui.lib` (COFF objects + `ar -M`/`llvm-ar`) is
|
|
131
165
|
produced by `scripts/build-gui.ts`. The Windows x64 CI job builds it with the
|
|
132
166
|
Visual Studio toolchain (`.github/actions/vs-toolchain` imports `vcvarsall`
|
|
133
|
-
and uses VS's bundled LLVM), links a `gui
|
|
167
|
+
and uses VS's bundled LLVM), links a `gui` program that exercises the `media`
|
|
168
|
+
link feature, and ships it in the
|
|
134
169
|
x64 release. *Running* the examples on the hosted runner stays provisional
|
|
135
170
|
because it has no GPU/Vulkan driver (SDL_GPU selects the **Vulkan** backend
|
|
136
171
|
there, so no DXIL/`dxc` toolchain is needed). Windows arm64 still skips both
|
|
@@ -139,12 +174,14 @@
|
|
|
139
174
|
- **Windows: x64 builds in CI, arm64 and runtime validation stay provisional.**
|
|
140
175
|
`media.lib` is produced by `scripts/build-media.ts` with FFmpeg's MSVC
|
|
141
176
|
toolchain (`--toolchain=msvc --cc=clang-cl`) so its COFF objects and static CRT
|
|
142
|
-
match `gui.lib`, and
|
|
177
|
+
match `gui.lib`, and the auto-selected `media` feature links and plays there.
|
|
178
|
+
Building it needs a
|
|
143
179
|
POSIX shell to run FFmpeg's `configure` and GNU make; the shell comes from Git
|
|
144
180
|
for Windows (already needed to clone SDL3), and make is a native GNU make
|
|
145
181
|
(Chocolatey's `make`, or `xbintsc_MAKE`). CI installs make explicitly,
|
|
146
182
|
builds `gui.lib` + `media.lib` on Windows x64 (using the same Visual Studio
|
|
147
|
-
`vcvarsall` + bundled LLVM as a local build), links a `gui
|
|
183
|
+
`vcvarsall` + bundled LLVM as a local build), links a `gui` program that
|
|
184
|
+
exercises the feature, and
|
|
148
185
|
ships both archives in the Windows x64 release; the example *run* remains
|
|
149
186
|
provisional because hosted runners have no GPU/Vulkan driver. Windows arm64
|
|
150
187
|
still skips both archives, and `<video controls>` is likewise deferred — the
|