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/zh-CN/gui/build.md
CHANGED
|
@@ -7,13 +7,29 @@
|
|
|
7
7
|
- 源码位于 `runtime/ext_gui/`(C/C++),外加 `vendor/` 下的 vendored 库
|
|
8
8
|
(被 gitignore;按需获取)。媒体解码位于 `runtime/ext_media/`,单独构建。
|
|
9
9
|
- `npm run gui`(`scripts/build-gui.ts`)获取固定版本的 SDL3(`SDL3_TAG`,
|
|
10
|
-
默认 `release-3.2.10`),构建静态 SDL3,获取并构建静态 FreeType
|
|
11
|
-
(`FREETYPE_VERSION`)与 HarfBuzz
|
|
10
|
+
默认 `release-3.2.10`),构建静态 SDL3,获取并构建静态 **FreeType**
|
|
11
|
+
(`FREETYPE_VERSION`,默认 `2.13.3`)与 **HarfBuzz**(`HARFBUZZ_VERSION`,
|
|
12
|
+
默认 `10.1.0`)供可选的 `shaping` 特性使用,并获取、构建静态
|
|
12
13
|
**glslang**(`GLSLANG_VERSION`,默认 `16.6.0`)、固定版本的 SPIR-V 头文件
|
|
13
|
-
(`SPIRV_HEADERS_VERSION
|
|
14
|
-
`vulkan-sdk-1.4.313.0`)。glslang 是 WebGL
|
|
15
|
-
SPIRV-Cross 把它的 SPIR-V 转成 Metal 后端使用的
|
|
16
|
-
[WebGL](./webgl.md)
|
|
14
|
+
(`SPIRV_HEADERS_VERSION`)以及——**仅 macOS**——**SPIRV-Cross**
|
|
15
|
+
(`SPIRV_CROSS_VERSION`,默认 `vulkan-sdk-1.4.313.0`)。glslang 是 WebGL
|
|
16
|
+
背后的运行时 GLSL ES 编译器,SPIRV-Cross 把它的 SPIR-V 转成 Metal 后端使用的
|
|
17
|
+
MSL(见 [WebGL](./webgl.md)),两者都与其他库一样合并进归档。Metal 是唯一消费
|
|
18
|
+
MSL 的 SDL_GPU 后端,因此 Windows/Linux 上脚本既不获取也不合并 SPIRV-Cross:
|
|
19
|
+
那里的 `webgl_msl.cpp` 编译为空,合并进来只会多出约 2.5 MiB 不可达代码。
|
|
20
|
+
默认文本路径使用内置的 **stb_truetype**(`runtime/ext_gui/stb_truetype.h`);
|
|
21
|
+
HarfBuzz/FreeType 只在 `shaping` 特性启用时被取出。
|
|
22
|
+
每个库(SDL3、FreeType、HarfBuzz、glslang、SPIRV-Cross 与引擎)都用
|
|
23
|
+
`-ffunction-sections -fdata-sections` 编译;SDL 关闭引擎从不调用的子系统
|
|
24
|
+
(`SDL_JOYSTICK`、`SDL_HAPTIC`、`SDL_SENSOR`、`SDL_CAMERA`、`SDL_RENDER`、
|
|
25
|
+
`SDL_OPENGL`/`SDL_OPENGLES`、`SDL_OFFSCREEN`、`SDL_HIDAPI`);HarfBuzz 关闭
|
|
26
|
+
整形后端从不使用的 API(`HB_NO_DRAW`/`PAINT`/`COLOR`/`NAME`/`STYLE`/`METRICS`/…,
|
|
27
|
+
但保留 `CFF`/`OPEN`/`VAR` 以支持 OTF 与可变字体),并以
|
|
28
|
+
`HB_NO_PRAGMA_GCC_DIAGNOSTIC_ERROR` 编译:`src/hb.hh` 会把自身警告集提升为
|
|
29
|
+
错误,而两个精简宏(`HB_NO_MMAP` 与 `HB_NO_OT_FONT_GLYPH_NAMES`)会让
|
|
30
|
+
macOS/CoreText 的辅助函数变成未引用。链接器随后丢弃
|
|
31
|
+
不可达函数(`--gc-sections`、`-dead_strip` 或 link.exe 默认的 `/OPT:REF`)。
|
|
32
|
+
随后编译引擎,并把
|
|
17
33
|
所有内容合并到 `runtime/lib/<os>-<arch>/gui.a`(Windows 上 MSVC ABI 则为
|
|
18
34
|
`gui.lib`),与 `core.a` 采用相同约定,静态打包这些库。合并使用 macOS 上的
|
|
19
35
|
`libtool` 与其他平台上的 `ar -M`(GNU/LLVM);CMake 归档会在构建根目录或
|
|
@@ -23,12 +39,15 @@
|
|
|
23
39
|
demuxer/parser/decoder 的最小静态构建,用它编译
|
|
24
40
|
`runtime/ext_media/media.cpp`,并把所有内容合并到
|
|
25
41
|
`runtime/lib/<os>-<arch>/media.a`(Windows 上 MSVC ABI 则为 `media.lib`)。
|
|
26
|
-
`gui.a` **不会**链接 FFmpeg
|
|
42
|
+
`gui.a` **不会**链接 FFmpeg:编译器为可能播放媒体的程序选中 `media` 链接特性后
|
|
43
|
+
才链接 `media.a`(见[链接特性](#链接特性))。
|
|
27
44
|
- `src/extensions/gui/index.ts` 通过 `nativeObjects()` 暴露引擎归档(经由
|
|
28
45
|
`findRuntimeLibrary`,因此 `.a`/`.lib` 都可用),并通过 `linkerFlags()`
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
46
|
+
暴露操作系统框架。它的 `linkFeatures()`(位于
|
|
47
|
+
`src/extensions/gui/features.ts`)声明 `media`、`gpu`、`images`、`shaping` 与 `webgl`;driver 只在该特性
|
|
48
|
+
启用时编译对应的 bridge。
|
|
49
|
+
- glslang(以及 macOS 上的 SPIRV-Cross)与 SDL3 一样合并进 `gui.a`,但引擎只
|
|
50
|
+
通过 `gpu` 特性的分发表访问它;从不编译 GLSL 的程序不会取出这些归档成员。
|
|
32
51
|
- `scripts/build-gui.ts` 使用与驱动**相同**的 clang
|
|
33
52
|
(`src/driver/toolchain-provider.ts`);Windows 上就是 Visual Studio 自带的、
|
|
34
53
|
面向 MSVC 的 LLVM,并配套使用其同目录下的 `clang++`/`llvm-ar` 来配置 CMake、
|
|
@@ -53,9 +72,10 @@
|
|
|
53
72
|
- CI 在组装发布归档之前构建 `gui.a`/`gui.lib` 与 `media.a`/`media.lib`,因此它们
|
|
54
73
|
会随 `runtime/lib/<slug>/` 一起发布(发布 tarball 会复制整个 `runtime/` 树)。
|
|
55
74
|
同一批目录还会打进可选的 `@xbintsc/<slug>` npm 包,因此发布覆盖的宿主平台从
|
|
56
|
-
npm 安装后也能使用 `--ext gui
|
|
75
|
+
npm 安装后也能使用 `--ext gui`(`media`/`gpu`/`images`/`shaping`/`webgl` 自动选择)。归档在 Linux(Xvfb 下,使用
|
|
57
76
|
lavapipe 软件 Vulkan 驱动)与 macOS 上构建并运行
|
|
58
|
-
示例;Windows x64
|
|
77
|
+
示例;Windows x64 也会构建两个归档并链接一个会触发 `media` 特性的 `gui` 程序
|
|
78
|
+
(另有一条显式 `--feature media` 的构建),因此 MSVC
|
|
59
79
|
构建在 CI 中得到验证,只是*运行*示例仍为试验性(托管 runner 没有 GPU/Vulkan
|
|
60
80
|
驱动)。macOS 的运行同样是试验性的:Intel runner 的虚拟 GPU 缺少
|
|
61
81
|
`MTLGPUFamilyMac2`,引擎会以 **77**(“此机器无法运行 GUI”)退出,任务记录为跳过,
|
|
@@ -69,8 +89,9 @@
|
|
|
69
89
|
configure/make 构建树本身不缓存(其中记录了另一台机器的绝对路径与编译选项)。
|
|
70
90
|
- 现有的缓存指纹已经会对 `nativeObjects()` 的内容与 `runtimeSources()` 的内容
|
|
71
91
|
做哈希,因此重建任一归档都会自动使缓存二进制失效。
|
|
72
|
-
- CMake 构建树位于其源码**旁边**(`vendor/sdl-build
|
|
73
|
-
`vendor/harfbuzz-build
|
|
92
|
+
- CMake 构建树位于其源码**旁边**(`vendor/sdl-build-lean`、
|
|
93
|
+
`vendor/freetype-build-lean`、`vendor/harfbuzz-build-lean`、
|
|
94
|
+
`vendor/glslang-build-lean`、`vendor/spirv-cross-build-lean`),绝不放在源码内部:`CMakeCache.txt` 记录的是配置它
|
|
74
95
|
的那台机器,而 SDL 的视频后端是 `option()`,因此先运行的那次配置会一直生效。
|
|
75
96
|
所以一个同时携带 `build/` 的 `vendor/SDL` 缓存树,会把某台机器的
|
|
76
97
|
`SDL_X11`/`SDL_WAYLAND` 选择带进另一台机器的配置——即使头文件已安装,SDL 也会
|
|
@@ -79,6 +100,78 @@
|
|
|
79
100
|
检查 X11/Wayland 头文件,并按名称报告缺失的开发包(当头文件位于该检查未知的
|
|
80
101
|
前缀下时,可设置 `xbintsc_SKIP_HEADER_CHECK=1`)。
|
|
81
102
|
|
|
103
|
+
## 链接特性
|
|
104
|
+
|
|
105
|
+
用户只启用一个 `gui` 扩展,但其中的重型部分是可选的**链接特性**,按程序选择:
|
|
106
|
+
|
|
107
|
+
| 特性 | 链接什么 | 程序可能用到时 |
|
|
108
|
+
| --- | --- | --- |
|
|
109
|
+
| `media` | `media_bridge.c` + `media.a`(FFmpeg) | HTML 里有 `<video>`/`<audio>`、`createElement("video"/"audio")`、`new Audio()`、`decodeAudioData`,或运行时拼出的 HTML |
|
|
110
|
+
| `gpu` | `gpu_bridge.c`(实现本身已在 `gui.a`) | `getContext("webgl"/"webgl2"/"experimental-webgl")`(或运行时决定的 kind)、任意 `webgl` 字符串、`mix-blend-mode`/`mixBlendMode`,或运行时拼出的 HTML |
|
|
111
|
+
| `images` | `image_bridge.c`(实现本身已在 `gui.a`) | `<img>`、内联 `<svg>`、`background-image`/`url(...)`、`.svg` 路径、`drawImage`/`createImageBitmap`/`Image`,或运行时拼出的 HTML |
|
|
112
|
+
| `shaping` | `text_bridge.c`(实现本身已在 `gui.a`) | 非 ASCII 文本(CJK/西里尔/希腊文等)、转义或实体码点、作者的 `@font-face` 规则(自定义字体可能是 CFF/OTF),或运行时拼出的 HTML |
|
|
113
|
+
| `webgl` | `webgl_bridge.c`(实现本身已在 `gui.a`,依赖 `gpu`) | WebGL 的 `getContext(...)`、`webgl` 字符串,或运行时拼出的 HTML |
|
|
114
|
+
|
|
115
|
+
driver 会扫描打包后的 AST(`src/driver/usage.ts`):所有字符串字面量(包括导入的
|
|
116
|
+
`.html` 与内联进来的 CSS)、标识符与属性名、每个 `getContext(...)` 的 kind,以及
|
|
117
|
+
HTML/CSS 是否可能来自编译器看不见的数据。简单的 `const` 别名会被解析;无法解析的
|
|
118
|
+
markup 会让程序按“动态 markup”保守处理,启用可选特性。
|
|
119
|
+
|
|
120
|
+
特性启用时,driver 只为本构建编译它的 C **bridge**,并链接在 `gui.a` 之前:
|
|
121
|
+
|
|
122
|
+
- `media` → `runtime/ext_media/media_bridge.c`;构造函数安装解码表并引用
|
|
123
|
+
`xt_media_backend_*`,从而把 FFmpeg 成员从 `media.a` 里取出。
|
|
124
|
+
- `gpu` → `runtime/ext_gui/gpu_bridge.c`;构造函数调用 `gpu_feature.cpp` 里的
|
|
125
|
+
`xt_gpu_feature_register`,安装 `XtGpuShaderApi` 表并引用 `compile_glsl` /
|
|
126
|
+
`cross_compile_msl` / 反射函数,从而取出 glslang(macOS 上还有 SPIRV-Cross)。
|
|
127
|
+
- `images` → `runtime/ext_gui/image_bridge.c`;构造函数通过 `image_feature.cpp`
|
|
128
|
+
安装 `XtImageApi`,其引用取出 stb_image 与 NanoSVG。layout、paint、canvas
|
|
129
|
+
`drawImage` 与应用图标都走这张表,因此纯文本页面不链接这两个解码器。
|
|
130
|
+
- `shaping` → `runtime/ext_gui/text_bridge.c`;构造函数通过 `text_hb.cpp` 安装
|
|
131
|
+
`TextApi`,其引用取出 HarfBuzz 与 FreeType。没有它时引擎使用内置 stb_truetype,
|
|
132
|
+
纯拉丁页面两个库都不链接。
|
|
133
|
+
- `webgl` → `runtime/ext_gui/webgl_bridge.c`;构造函数通过 `webgl_feature.cpp` 安装
|
|
134
|
+
`XtWebglApi`,其引用取出 WebGL context 与 DOM 绑定。core 的 `getContext`、
|
|
135
|
+
canvas 宽高 setter、`createImageBitmap`、host type 与 renderer 都走这张表,因此
|
|
136
|
+
不用 WebGL 的页面不链接任何 `webgl_*`/`dom_api_webgl*`。
|
|
137
|
+
|
|
138
|
+
bridge 就是让链接器搜索归档的“强引用”;没有 bridge 时引擎的表保持 null,
|
|
139
|
+
实现成员永不被取出。因此大库可以留在现有归档里,不需要新的包布局。
|
|
140
|
+
|
|
141
|
+
覆盖方式:`--feature media,gpu,images,shaping,webgl`(或 `all`)强制开启;
|
|
142
|
+
`--no-feature media` 即使检测到也不链接。`webgl` 依赖 `gpu`,resolver 会一起
|
|
143
|
+
激活;配置应用图标会强制 `images`,因为图标走同一条解码管线。`--ext media` 是
|
|
144
|
+
`--ext gui --feature media` 的弃用别名。
|
|
145
|
+
自动检测到的特性归档缺失时构建打印 warning 并继续(元素/上下文按文档降级);
|
|
146
|
+
显式强制的特性则报错。
|
|
147
|
+
|
|
148
|
+
> 检测是静态的。用 `fetch`、`readFileSync` 等运行时数据拼 HTML/CSS 的页面应传
|
|
149
|
+
> `--feature all`(或具体特性)。`--verbose` 会打印选中的集合,例如
|
|
150
|
+
> `xbintsc: link features: none`。
|
|
151
|
+
|
|
152
|
+
### 二进制体积
|
|
153
|
+
|
|
154
|
+
DOM-only 程序的小体积来自上述 lean 构建。Windows x64 上,一个 `hello` 规模的程序
|
|
155
|
+
从约 6.4 MiB 降到约 3.1 MiB:SDL 按上面的选项配置,function/data sections 让
|
|
156
|
+
`/OPT:REF` 丢弃页面触达不到的函数,WebGL/图片链接特性保持关闭,文本改用内置
|
|
157
|
+
stb_truetype 而不是 HarfBuzz + FreeType。剩余重量主要是静态 CRT、lean SDL
|
|
158
|
+
(约 1 MiB)、stb_truetype(约 0.1 MiB)以及 DOM/CSS/layout/paint 引擎本身
|
|
159
|
+
(约 1.2 MiB)。Linux 与 macOS 使用各自的链接器 section(`--gc-sections`/
|
|
160
|
+
`-dead_strip`),数字会有差异,但相对排序相同。
|
|
161
|
+
|
|
162
|
+
WebGL 与图片/SVG 是链接特性(约 0.4 MiB 的 WebGL context/DOM 代码与 0.23 MiB 的
|
|
163
|
+
stb_image/NanoSVG,DOM-only 页面不链接)。Canvas2D、Web Audio 与
|
|
164
|
+
`mix-blend-mode` 合成器尚未按需化;不使用它们的程序仍要付出其 API 面积(每项大约
|
|
165
|
+
0.1–0.2 MiB)。
|
|
166
|
+
|
|
167
|
+
文本替换是有意的取舍。默认后端是 stb_truetype:只接受 TrueType 轮廓,整形是逐码点
|
|
168
|
+
映射加字体的 `kern` 表,因此 CFF/OTF 与可变字体、OpenType 连字以及复杂文种
|
|
169
|
+
(阿拉伯/印度/泰文)整形不可用;fallback 链仍会在主字体缺字时切换到其他字体。
|
|
170
|
+
选中可选的 **`shaping`** 特性(非 ASCII 文本或作者的 `@font-face` 规则会自动
|
|
171
|
+
选中,也可用 `--feature shaping`)会重新链接 HarfBuzz + FreeType(约 1.2 MiB),
|
|
172
|
+
恢复完整的 OpenType 整形与 CFF/OTF/可变字体支持。纯拉丁 DOM 页面因此保持约
|
|
173
|
+
3.1 MiB;中文/复杂文种页面更接近 4.3 MiB。
|
|
174
|
+
|
|
82
175
|
## 运行示例
|
|
83
176
|
|
|
84
177
|
```sh
|
|
@@ -117,9 +210,10 @@ Chocolatey/独立 LLVM,CI、本地构建与预编译归档共用同一条编
|
|
|
117
210
|
|
|
118
211
|
`examples/gui/media.ts`(配合 `media.html`)演示 `<video>`/`<audio>`:它在
|
|
119
212
|
`<video>` 上叠一个 CSS 进度条,并用 `play()`/`pause()`/`currentTime`/
|
|
120
|
-
`volume`
|
|
213
|
+
`volume` 驱动播放。编译器从 `media.html` 里看到这些元素后会自动选中 `media`
|
|
214
|
+
特性;先用 `npm run media` 构建一次 `media.a`。
|
|
121
215
|
媒体 `src` 相对于进程工作目录解析,因此从仓库根目录运行:
|
|
122
|
-
`xbintsc run examples/gui/media.ts --ext gui
|
|
216
|
+
`xbintsc run examples/gui/media.ts --ext gui`。几何报告见该目录的 README。
|
|
123
217
|
|
|
124
218
|
这些测试套件在 Windows 上默认跳过(归档可以在本机通过 Vulkan 运行,但 CI
|
|
125
219
|
runner 没有可用的 GPU 驱动)。如果本机有 `gui.lib` 与可用的 GPU,可用
|
package/doc/zh-CN/gui/canvas.md
CHANGED
|
@@ -156,7 +156,7 @@ canvas 由脚本重绘而不是引擎重绘,因此开销按绘制调用计。
|
|
|
156
156
|
(奇数长度列表会复制一遍,负数/非有限值会被忽略,全零列表表示实线)。
|
|
157
157
|
|
|
158
158
|
文本:`measureText(text)`(返回 `{ width }`)、`fillText(text, x, y, maxWidth?)` 与
|
|
159
|
-
`strokeText(text, x, y, maxWidth?)`。文本经
|
|
159
|
+
`strokeText(text, x, y, maxWidth?)`。文本经 stb_truetype 整形与光栅化(与 HTML
|
|
160
160
|
文本相同的技术栈),按变换的近似缩放绘制。正的 `maxWidth` 会按比例压缩步进与字形位图,
|
|
161
161
|
使文本宽度不超过该值(与 canvas API 一致),而不是忽略该参数。**仅支持平移与均匀
|
|
162
162
|
缩放**——旋转或斜切变换仍会把每个字形放到其变换后的基线点,但不会旋转字形位图。
|
package/doc/zh-CN/gui/dom.md
CHANGED
|
@@ -20,11 +20,24 @@ doctype 跳过,实体解码(命名 + 十进制/十六进制),空元素
|
|
|
20
20
|
(`=`、`~=`、`|=`、`^=`、`$=`、`*=`)、四种组合器(后代、子、相邻兄弟与
|
|
21
21
|
通用兄弟)、伪类 `:first-child`、`:last-child`、`:only-child`、`:empty`、
|
|
22
22
|
`:root`、`:not(...)`、`:nth-child(an+b)`、`:disabled`、`:checked`、有状态的
|
|
23
|
-
`:hover
|
|
23
|
+
`:hover`、`:focus`、`:focus-visible`(目前等同 `:focus`)与 `:active`
|
|
24
|
+
(见[输入](./input.md)),以及伪元素
|
|
24
25
|
`::before`/`::after`(也接受旧式 `:before`/`:after`)。值:长度
|
|
25
26
|
(`px`、`%`、`em`、`rem`、`vw`、`vh`、`pt`、`pc`、`in`、`cm`、`mm`、`q`)、
|
|
26
27
|
颜色(十六进制、`rgb()`/`rgba()`、一个命名子集)、数字、关键字与简写
|
|
27
|
-
(`margin`/`padding`/`border`/`flex
|
|
28
|
+
(`margin`/`padding`/`border`/`flex`/`font`/`outline`)。
|
|
29
|
+
`display: inline-flex`/`inline-grid` 生成行内级 flex/grid 容器;`grid-area`、
|
|
30
|
+
`aspect-ratio`、`letter-spacing`、`text-transform`、`writing-mode`
|
|
31
|
+
(`vertical-rl`/`vertical-lr` 文本)、`vertical-align`(长度形式)、百分比
|
|
32
|
+
`border-radius`、`background-size`(`url()` 图层按尺寸与默认 repeat 平铺)与
|
|
33
|
+
`currentColor` 都已支持。`font-variant-numeric`、`text-wrap`、`text-rendering`、
|
|
34
|
+
`touch-action`、`user-select`、`overscroll-behavior`、`scroll-behavior`、
|
|
35
|
+
`isolation`、`vector-effect` 会被接受但不产生引擎行为(文本栈不暴露 OpenType 特性,引擎也没有触摸/选择/平滑滚动子系统);
|
|
36
|
+
`cursor` 映射到 SDL 系统光标。文档 CSS 可用 `fill`、`fill-opacity`、`fill-rule`、
|
|
37
|
+
`stroke`、`stroke-opacity`、`stroke-width`、`stroke-dasharray`、
|
|
38
|
+
`stroke-dashoffset`、`stroke-linecap`、`stroke-linejoin` 给 SVG 子元素上色;
|
|
39
|
+
序列化器会把它们写成 NanoSVG 可读的内联样式。`skewX()`/`skewY()`/`skew()`
|
|
40
|
+
变换函数也已支持。`transform`
|
|
28
41
|
(`translate`/`translate3d`/`translateX`/`translateY`、
|
|
29
42
|
`scale`/`scale3d`/`scaleX`/`scaleY`、`rotate`/`rotateZ`、`matrix`;`3d`
|
|
30
43
|
拼写的 `z` 参数会被丢弃)与 `transform-origin`
|
|
@@ -32,7 +45,7 @@ doctype 跳过,实体解码(命名 + 十进制/十六进制),空元素
|
|
|
32
45
|
函数会让整条声明失效(见[布局](./layout.md#变换m15))。M19 增加了
|
|
33
46
|
`background-image` 层列表(线性/径向)、`clip-path`
|
|
34
47
|
(`inset`/`circle`/`ellipse`/`polygon`)、`filter`/`backdrop-filter` 函数列表、
|
|
35
|
-
`text-shadow` 与 `content`。
|
|
48
|
+
`text-shadow`、`box-shadow` 与 `content`。
|
|
36
49
|
|
|
37
50
|
**层叠与计算样式**(`runtime/ext_gui/style.{h,cpp}`):一份小的内置 UA
|
|
38
51
|
样式表,作者规则按 `(!important, 特异性, 源码顺序)` 排序,然后是内联
|
|
@@ -20,6 +20,15 @@
|
|
|
20
20
|
`WebGLRenderer` 直接运行在真实后端上,不再有 Canvas2D 回退。阴影贴图
|
|
21
21
|
(比较型 `sampler2DShadow` 采样深度纹理)、立方体贴图/环境贴图与 HDR 渲染目标
|
|
22
22
|
均已支持。
|
|
23
|
+
- **部分 Intel Mac 上比较型采样器会被错误编译。** 在 Intel GPU(在 Intel Iris
|
|
24
|
+
Plus Graphics + macOS 26 上观察到)上,Metal 着色器编译器会丢弃调用
|
|
25
|
+
`sample_compare` 的片元函数:绘制不产生任何像素,于是
|
|
26
|
+
`texture(sampler2DShadow, …)` 读到黑色,阴影贴图消失。MSL 本身是正确的
|
|
27
|
+
(`depth2d<float>` + `sample_compare`),采样器也带比较操作,而同一个程序在
|
|
28
|
+
打开 Metal GPU 着色器校验后渲染正常——在这类机器上以
|
|
29
|
+
`MTL_SHADER_VALIDATION=1` 运行即可让
|
|
30
|
+
`tests/e2e/gui-webgl2-shadow-sampler.test.ts` 通过。这指向驱动的着色器编译器
|
|
31
|
+
而非引擎,因此以环境变量作为绕过办法;其他 Apple GPU 未必存在该问题。
|
|
23
32
|
|
|
24
33
|
|
|
25
34
|
- **自动关闭时的偶发崩溃。** 设置 `XT_GUI_AUTOCLOSE_MS` 结束运行时,约五次中有两次会以原生
|
|
@@ -39,21 +48,30 @@
|
|
|
39
48
|
`tests/e2e/gui-example-browser.test.ts` 中。
|
|
40
49
|
- **`display: none -> flex` 的重排。** 通过类名切换让隐藏元素显示在 flex 容器上时,也曾观察
|
|
41
50
|
到同样的崩溃;`examples/gui/pelican-bike` 改用 `opacity` 显示游戏结束遮罩。
|
|
42
|
-
- **CSS 覆盖范围是有意为之的子集。** 已实现 Grid、`
|
|
51
|
+
- **CSS 覆盖范围是有意为之的子集。** 已实现 Grid、`calc()`(含嵌套算术及
|
|
52
|
+
`min()`/`max()`/`clamp()` 内的 `calc()`)、`clamp()`/`min()`/`max()`/`env()`、
|
|
43
53
|
`var()` 自定义属性、`inset` 简写、`box-sizing`、`visibility`/`pointer-events`、
|
|
44
54
|
`@media` 查询、生成内容(`::before`/`::after`)、线性/径向多层背景、
|
|
45
|
-
`text-shadow
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
`
|
|
52
|
-
|
|
55
|
+
`text-shadow`(真正的高斯)、`box-shadow`(外阴影/内阴影、spread、多层)、
|
|
56
|
+
`clip-path`(`inset`/`circle`/`ellipse`/`polygon`)、`filter` 颜色函数、
|
|
57
|
+
`@keyframes` 动画、完整的 `transition` 时间函数、`letter-spacing`、
|
|
58
|
+
`text-transform`、行内级 `flex`/`grid`、`grid-area`、`aspect-ratio`、自动
|
|
59
|
+
外边距、百分比 `border-radius`、`outline`、`url()` 图层的 `background-size`
|
|
60
|
+
平铺,以及 SVG 子元素上的文档 CSS(`fill`/`stroke`/…)均已实现。仍有限制:
|
|
61
|
+
`background-clip`、`background-position`、`background-repeat` 未实现
|
|
62
|
+
(`background-size` 只覆盖默认平铺场景);`font-variant-numeric`、
|
|
63
|
+
`text-wrap`、`text-rendering`、`touch-action`、`user-select`、
|
|
64
|
+
`overscroll-behavior`、`scroll-behavior`、`isolation`、`vector-effect`
|
|
65
|
+
可解析但不产生行为;竖排书写模式仅
|
|
66
|
+
支持文本(嵌套/混排内容回退横排);组 `opacity` 是按图形 alpha
|
|
67
|
+
近似而非真正的组合成;D3D12/DXIL 后端没有混合与 `backdrop-filter` 合成器,
|
|
68
|
+
那里会退回普通 source-over 绘制并跳过背景滤镜。`filter: blur()` 仍是按图形做
|
|
69
|
+
九次偏移的近似,而不是真正的组模糊,重叠的子元素会加深;`drop-shadow` 用盒子
|
|
70
|
+
轮廓近似;最多只交叉两层嵌套 `clip-path`(更深时保留外侧两层);
|
|
53
71
|
图像/画布除图像着色器能携带的亮度与透明度染色外不做颜色滤镜。Canvas 纹理使用
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
72
|
+
最近邻采样。背景渐变(线性与径向)都逐像素光栅化成纹理,盒子大于纹理时再拉伸
|
|
73
|
+
(径向每边最大 1024 px;线性沿渐变线最大 4096 px,且沿渐变线之外只有一像素厚),
|
|
74
|
+
因此超大盒子上的硬色标会略微变软。
|
|
57
75
|
- **SVG 是 NanoSVG 的子集。** SVG *文件*(`<img src="logo.svg">`)与内联
|
|
58
76
|
`<svg>` 子树共用 vendored 的 NanoSVG 解析/光栅化器(`runtime/ext_gui/svg.cpp`、
|
|
59
77
|
`inline_svg.cpp`),它会渲染 `path`/`rect`/`circle`/`ellipse`/`line`/
|
|
@@ -79,6 +97,17 @@
|
|
|
79
97
|
`win.stats()` 的 `textCacheBytes`/`textShapeHits` 能看出它是否成为瓶颈。
|
|
80
98
|
元素自带的 `style="…"` 内联属性在该元素每次重算样式时都会重新解析。
|
|
81
99
|
|
|
100
|
+
- **文本整形是简单整形器。** stb_truetype 覆盖拉丁/CJK/西里尔/希腊文、基础
|
|
101
|
+
`kern` 与逐码点回退,但不执行 OpenType 连字或复杂文种(阿拉伯/印度/泰文)整形,
|
|
102
|
+
且只接受 TrueType 轮廓(不支持 CFF/OTF 或可变字体);彩色 emoji 也不会以彩色
|
|
103
|
+
渲染。这是 DOM-only 二进制约 3 MiB 的代价;可选的 `shaping` 特性会重新链接
|
|
104
|
+
HarfBuzz + FreeType,恢复完整整形。
|
|
105
|
+
- **链接特性检测是静态的。** `media`/`gpu`/`images`/`shaping`/`webgl` 从打包后的 HTML/CSS/TS(包括导入的
|
|
106
|
+
`.html` 与其内联 CSS)里选择。用运行时数据(`fetch`、`readFileSync`、函数返回值)
|
|
107
|
+
拼 HTML/CSS 的页面无法被看到;扫描器在能证明 sink 是动态时会保守地启用可选特性,
|
|
108
|
+
但对于它无法分类的不透明值,需要显式 `--feature media`/`gpu`/`images`/`shaping`/`webgl`(或 `all`)。
|
|
109
|
+
`--verbose` 会打印选中的集合。见[链接特性](./build.md#链接特性)。
|
|
110
|
+
|
|
82
111
|
## 待决问题
|
|
83
112
|
|
|
84
113
|
- Linux 首发是只发布 X11、Wayland,还是两者都发布。(决定:先 X11,
|
|
@@ -97,7 +126,8 @@
|
|
|
97
126
|
- Windows:`scripts/build-gui.ts` 会生成 MSVC 兼容的 `gui.lib`
|
|
98
127
|
(COFF 对象 + `ar -M`/`llvm-ar`)。Windows x64 的 CI job 使用 Visual Studio
|
|
99
128
|
工具链(`.github/actions/vs-toolchain` 导入 `vcvarsall` 并采用 VS 自带的
|
|
100
|
-
LLVM
|
|
129
|
+
LLVM)构建它、链接一个会触发 `media` 链接特性的 `gui` 程序,并随 x64 发布归档
|
|
130
|
+
一起发布。示例在
|
|
101
131
|
托管 runner 上的*运行*仍为试验性,因为那里没有 GPU/Vulkan 驱动(SDL_GPU 在
|
|
102
132
|
Windows 上选择 **Vulkan** 后端,因此不需要 DXIL/`dxc` 工具链)。Windows
|
|
103
133
|
arm64 仍跳过两个归档。在开发者机器上构建并运行
|
|
@@ -105,12 +135,12 @@
|
|
|
105
135
|
- **Windows:x64 在 CI 中构建,arm64 与运行时验证仍为试验性。**
|
|
106
136
|
`scripts/build-media.ts` 用 FFmpeg 的 MSVC 工具链
|
|
107
137
|
(`--toolchain=msvc --cc=clang-cl`)生成 `media.lib`,其 COFF 对象与静态 CRT
|
|
108
|
-
和 `gui.lib`
|
|
138
|
+
和 `gui.lib` 一致,自动选中的 `media` 特性在 Windows 上可以正常链接并播放。构建它需要
|
|
109
139
|
POSIX shell 运行 FFmpeg 的 `configure` 以及 GNU make;shell 来自 Git for
|
|
110
140
|
Windows(克隆 SDL3 本来就需要 Git),make 是原生 GNU make(Chocolatey 的
|
|
111
141
|
`make`,或 `xbintsc_MAKE`)。CI 会显式安装 make,在
|
|
112
142
|
Windows x64 上使用与本地构建相同的 Visual Studio `vcvarsall` + 自带 LLVM
|
|
113
|
-
构建 `gui.lib` 与 `media.lib
|
|
143
|
+
构建 `gui.lib` 与 `media.lib`,链接一个会触发该特性的 `gui` 程序,并把两个归档放进
|
|
114
144
|
Windows x64 发布包;示例的*运行*仍因托管 runner 没有 GPU/Vulkan 驱动而保持
|
|
115
145
|
试验性。Windows arm64 仍跳过两个归档;`<video controls>` 同样推迟——预期模式
|
|
116
146
|
是 TS + CSS 叠层,如 `examples/gui/media.ts`。
|
package/doc/zh-CN/gui/layout.md
CHANGED
|
@@ -18,11 +18,14 @@
|
|
|
18
18
|
基于单词的断行、`text-align` 与 `line-height`。行内元素获得其后代几何信息
|
|
19
19
|
的并集;`display: inline-block` 以 shrink-to-fit 宽度原子化布局。每一行会收缩到
|
|
20
20
|
与之重叠的浮动(`float: left|right`)所留出的空白带,因此后续行会绕开它们。
|
|
21
|
-
每个文本片段会记住它覆盖的 run,以便绘制时对它整形。文本使用
|
|
21
|
+
每个文本片段会记住它覆盖的 run,以便绘制时对它整形。文本使用 stb_truetype
|
|
22
22
|
技术栈测量(见[文本技术栈](./rendering.md))。
|
|
23
23
|
- **Flexbox** —— `row`/`column`(以及 `-reverse` 变体),支持 `gap`、
|
|
24
24
|
`flex-basis`/`flex-grow`/`flex-shrink`、`justify-content` 与 `align-items`
|
|
25
|
-
(当交叉轴尺寸确定时包括 `stretch
|
|
25
|
+
(当交叉轴尺寸确定时包括 `stretch`)。两个方向的主轴尺寸都先取
|
|
26
|
+
`flex-basis`(为 `auto` 时用测量尺寸):有剩余空间按 `flex-grow` 分配,
|
|
27
|
+
空间不足按 `flex-shrink` 收缩;单个项的 `align-self` 可覆盖容器的
|
|
28
|
+
`align-items`。`flex-wrap: wrap` 会把项断成多行,
|
|
26
29
|
`align-content`(`stretch`/`flex-start`/`flex-end`/`center`/`space-between`/
|
|
27
30
|
`space-around`)在交叉轴上分配这些行,`wrap-reverse` 则翻转交叉轴。
|
|
28
31
|
flex 项的外边距参与其外框尺寸,因此
|
|
@@ -33,11 +36,25 @@
|
|
|
33
36
|
`repeat(...)`)、`gap`/`row-gap`/`column-gap`、按行自动放置、简单的
|
|
34
37
|
`grid-column`/`grid-row` 线定位,以及 `align/justify-items` 与
|
|
35
38
|
`align/justify-self`(含 `place-items`/`place-self`)。隐式行/列由项目撑开;
|
|
36
|
-
|
|
39
|
+
网格高度确定时,先布置固定行与 auto 行,剩余高度再按 `fr` 分给 `fr` 行,
|
|
40
|
+
因此 `aspect-ratio` 可以驱动 `repeat(n, 1fr)` 网格。单单元格网格配合
|
|
41
|
+
`place-items: center` 可把卡片居中到整个覆盖层。项目测量是
|
|
37
42
|
两遍布局(先固有尺寸、再最终放置),因此两遍之间会清空文本片段。
|
|
38
|
-
-
|
|
39
|
-
|
|
40
|
-
|
|
43
|
+
- **行内级容器、自动外边距与宽高比** —— `display: inline-flex`/`inline-grid`
|
|
44
|
+
仍用 flex/grid 算法排列子元素,但作为单个原子行内盒参与父级行流
|
|
45
|
+
(`vertical-align` 的长度值会平移它)。块级盒的 `margin-left: auto` /
|
|
46
|
+
`margin-right: auto` 会吸收行内剩余空间(双 auto 则居中);flex 项主轴的 auto
|
|
47
|
+
外边距在 `justify-content` 之前吸收该行剩余空间,因此可把页脚或按钮提示推到
|
|
48
|
+
末端。`aspect-ratio` 在 `height: auto` 时由已用宽度推导高度(反向的由高推宽
|
|
49
|
+
未实现)。`border-radius` 支持百分比,并按 border box 较小边解析。
|
|
50
|
+
- **竖排书写模式** —— `writing-mode: vertical-rl|vertical-lr` 按每列一个字符
|
|
51
|
+
步进排字:CJK/假名/谚文字符保持直立,其他文字在绘制时旋转 90°。高度确定时
|
|
52
|
+
另起一列;flex 容器的 row/column 轴随书写模式互换。这是面向文本的实现:
|
|
53
|
+
竖排容器中的嵌套块与横竖混排内容仍回退为横排。
|
|
54
|
+
- **CSS 值函数与自定义属性** —— `calc()` 算术(含嵌套 `calc()` 以及其它函数
|
|
55
|
+
内部的 `calc()`)、`clamp(min, value, max)`、`min(...)` 与 `max(...)` 在计算
|
|
56
|
+
样式中保留表达式,布局时结合元素字号与视口(`vw`/`vh`)求值;桌面窗口中
|
|
57
|
+
`env(safe-area-inset-*)` 解析为 0。`var(--name[, fallback])` 在
|
|
41
58
|
层叠期间从继承的自定义属性替换。`inset` 是四值 `top/right/bottom/left`
|
|
42
59
|
简写;`box-sizing: border-box` 会从显式宽高里扣除 padding 与边框;
|
|
43
60
|
`visibility: hidden` 跳过绘制与命中测试;`pointer-events: none` 使盒子不接收输入
|
package/doc/zh-CN/gui/media.md
CHANGED
|
@@ -62,7 +62,8 @@ opacity、`display`——与任何其他元素一样。盒子内部的艺术内
|
|
|
62
62
|
|
|
63
63
|
## 视频与音频(M13)
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
媒体播放拆在 `gui` 扩展内部,因此只做界面的 GUI 程序不必为用不到的解码器付出
|
|
66
|
+
体积。解码是可选的 **`media` 链接特性**,不是独立扩展:
|
|
66
67
|
|
|
67
68
|
- **`gui`**(`gui.a`/`gui.lib`)负责 `<video>`/`<audio>` 元素、DOM API、渲染器
|
|
68
69
|
集成与 SDL 音频 sink,但**不含 FFmpeg**。`runtime/ext_gui/media.{h,cpp}`
|
|
@@ -71,12 +72,16 @@ opacity、`display`——与任何其他元素一样。盒子内部的艺术内
|
|
|
71
72
|
- **`media`**(`media.a`,Windows 上 MSVC ABI 则为 `media.lib`;
|
|
72
73
|
`runtime/ext_media/`)是可选的解码后端:`runtime/ext_media/media.cpp`
|
|
73
74
|
封装静态 vendored 的 **FFmpeg** 构建,`runtime/ext_media/media_bridge.c`
|
|
74
|
-
|
|
75
|
-
|
|
75
|
+
把它注册进引擎。编译器在程序可能用到媒体时(导入 HTML 里的
|
|
76
|
+
`<video>`/`<audio>`、`createElement("video"/"audio")`、`new Audio()`、
|
|
77
|
+
`decodeAudioData`,或运行时拼出的 HTML)自动选中该特性,只在那时才编译
|
|
78
|
+
bridge 并链接 `media.a`。`--feature media` 强制开启,`--no-feature media`
|
|
79
|
+
保持关闭;见[链接特性](./build.md#链接特性)。
|
|
76
80
|
|
|
77
|
-
没有 `media`
|
|
78
|
-
`error`。任何没有构建该归档的宿主(先运行 `npm run media
|
|
79
|
-
|
|
81
|
+
没有 `media` 特性时,元素仍然存在、DOM API 仍可调用,但打开源会失败并触发
|
|
82
|
+
`error`。任何没有构建该归档的宿主(先运行 `npm run media`)都是如此——自动
|
|
83
|
+
检测到但归档缺失时构建给出 warning 并按此降级,显式 `--feature media` 则直接
|
|
84
|
+
报错。Windows 已不再特殊:`media.lib` 是用 clang-cl 为 MSVC ABI 编译的 FFmpeg,
|
|
80
85
|
因此可以和 `gui.lib` 一起链接并正常播放。两条路径都没有 WebView,也没有平台
|
|
81
86
|
媒体框架。
|
|
82
87
|
|
|
@@ -63,15 +63,22 @@
|
|
|
63
63
|
|
|
64
64
|
窗口背景(`setBackground`)是渲染通道的清除色。
|
|
65
65
|
|
|
66
|
+
`url()` 图层上的 `background-size` 会按平铺尺寸为每块生成一个图像四边形
|
|
67
|
+
(默认 `repeat`,上限 4096 块),而不是把图片拉伸到整个盒子;百分比尺寸相对
|
|
68
|
+
盒子解析,`auto` 保留盒子的对应尺寸。`outline` 在边框之后、内容之前绘制边框盒
|
|
69
|
+
之外的四条矩形(含 offset)。竖排文本通过把字形四边形旋转 90° 绘制
|
|
70
|
+
(CJK 字形保持直立并在列内居中)。
|
|
71
|
+
|
|
66
72
|
### 背景、生成内容与特效(M19)
|
|
67
73
|
|
|
68
74
|
`background-color` 与每一条 `background-image` 层都会绘制。逗号分隔的层列表按
|
|
69
75
|
从底到上的顺序绘制(声明中的第一层在最上面),两种渐变均受支持:
|
|
70
76
|
|
|
71
|
-
-
|
|
77
|
+
- **线性**渐变沿 CSS 渐变线(过盒子中心、按声明角度,盒子在该方向上的投影即
|
|
78
|
+
渐变线长度,因此百分比与 `calc()` 内的百分比都相对该长度解算)逐像素解算,
|
|
79
|
+
与径向渐变相同。渐变只沿线变化,所以纹理只有一行(或一列)设备像素;支持
|
|
72
80
|
`to <side>`、`deg`/`grad`/`rad`/`turn`、百分比或长度(`px`/`em`/…)偏移、
|
|
73
|
-
`color <start> <end>`
|
|
74
|
-
最近的轴向);
|
|
81
|
+
`color <start> <end>` 简写与多色标;
|
|
75
82
|
- **径向**渐变由 `renderer_gradient.cpp` 逐像素解算成一张 RGBA 纹理,作为单个
|
|
76
83
|
图像四边形绘制(`PaintGradient`)。若沿用嵌套色带,由于每条色带都会覆盖整个
|
|
77
84
|
内部区域,alpha 会叠加多次——淡出到 `transparent` 的暗角会把整个场景涂成实心
|
|
@@ -80,21 +87,39 @@
|
|
|
80
87
|
的椭圆保持盒子的宽高比并缩放到刚好接触对应边或角,与 CSS 一致。色标在预乘
|
|
81
88
|
alpha 空间中插值,最后一个色标会延伸覆盖结束形状之外的剩余盒子。
|
|
82
89
|
|
|
90
|
+
两种渐变共用这条逐像素路径:用一串纯色矩形绘制时,半透明色标会逐条叠加 alpha,
|
|
91
|
+
而且宽度小于一条色带的色标无法表达——`transparent … calc(100% - 1px),
|
|
92
|
+
rgba(…) calc(100% - 1px)` 这样的 1px 分割线要么落在两次采样之间(直接消失),
|
|
93
|
+
要么被撑成一整条色带。`calc()` 给出的色标位置会保留相对渐变线的百分比,解算后
|
|
94
|
+
为负的偏移也停留在声明的位置,而不会被当成「未声明偏移」重新分配。
|
|
95
|
+
|
|
83
96
|
`repeating-linear-gradient()` 与 `repeating-radial-gradient()` 会在整个盒子上
|
|
84
97
|
从 0 平铺到最后一个色标的偏移量;色标列表不会被强制结束在 100%,因此
|
|
85
98
|
`red 0%, blue 10%` 每 10% 重复一次。普通渐变的最后一个色标若小于 100%,则剩余
|
|
86
99
|
区域保持该颜色,与 CSS 一致。
|
|
87
100
|
|
|
88
|
-
|
|
89
|
-
|
|
101
|
+
背景色位于所有层下方。若渐变色标带透明度,渐变也会半透明;两种渐变都逐像素精确,
|
|
102
|
+
因此硬色标与 1px 细节保持锐利,不再出现条带。
|
|
90
103
|
|
|
91
104
|
**生成内容**不需要新的显示列表类型:`::before`/`::after` 是 `style.cpp` 中
|
|
92
105
|
每次重算样式时重建的普通布局盒,因此其背景、边框、文本与 transform 都走同一条
|
|
93
106
|
绘制路径。`content` 支持字符串、`attr()` 与 open/close quote。
|
|
94
107
|
|
|
95
|
-
**`text-shadow`**
|
|
96
|
-
|
|
97
|
-
|
|
108
|
+
**`text-shadow`** 在不带模糊时作为阴影 `PaintText` run 排在真实 run 之前,文本
|
|
109
|
+
管线无需新 shader 就能清晰绘制。带模糊的阴影是真正的高斯:`paint_shadow.cpp`
|
|
110
|
+
光栅化字形覆盖度,用可分离核做卷积(`sigma = blur / 2`,截断在 ±3σ),再发出
|
|
111
|
+
一个带色调的图像四边形。掩码按 文本/字体/模糊 缓存,因此动画颜色只改变色调。
|
|
112
|
+
|
|
113
|
+
**`box-shadow`** 使用同一套高斯掩码:圆角矩形轮廓被光栅化(spread 扩张或收缩)、
|
|
114
|
+
卷积,再合成到背景之后;`inset` 阴影反转掩码、裁剪到 padding box 并绘制在背景
|
|
115
|
+
之上。零模糊的外阴影仍使用精确的圆角矩形。声明列表按最后一层最先绘制,与 CSS
|
|
116
|
+
一致。
|
|
117
|
+
|
|
118
|
+
**`backdrop-filter`** 与 `mix-blend-mode` 共用离屏机制:绘制器到达该盒子时,
|
|
119
|
+
渲染器把此前场景复制到暂存纹理,用全屏 shader 应用高斯和一个合并的颜色矩阵
|
|
120
|
+
(brightness/contrast/grayscale/sepia/invert/saturate/hue-rotate/opacity 相乘),
|
|
121
|
+
再通过盒子的圆角边框盒掩码合成回来。因此 `backdrop-filter` 在 `paintList()` 中
|
|
122
|
+
显示为 `backdrop …` op。
|
|
98
123
|
|
|
99
124
|
**`clip-path`** 在 `paint_clip.cpp` 中解析为设备空间多边形(每个点都应用盒子的
|
|
100
125
|
transform),用耳切法三角化,并存入 `DisplayList::clip_paths`。每个 op 的
|
|
@@ -107,8 +132,8 @@ shader 改动,但边缘是硬边(没有解析抗锯齿)。支持两层嵌
|
|
|
107
132
|
`invert`、`saturate`、`hue-rotate`、`opacity`)会折进每个绘制颜色,因此盒子与
|
|
108
133
|
其后代都会看到滤镜。`blur()` 与 `drop-shadow()` 是显示列表层面的近似:模糊把每个
|
|
109
134
|
图形展开成九个半透明副本,投影用盒子/文字轮廓。这样普通绘制保持单渲染通道,代价
|
|
110
|
-
|
|
111
|
-
|
|
135
|
+
是组语义:被模糊/滤镜的组内重叠后代可能加深。`backdrop-filter` 是例外,它有
|
|
136
|
+
自己的离屏快照/滤镜通道(见上)。
|
|
112
137
|
|
|
113
138
|
**`mix-blend-mode`** 是唯一真正需要离屏图层的例外。非 `normal` 的盒子会被
|
|
114
139
|
`LayerBegin`/`LayerEnd` 标记包住(在 `paintList()` 中显示为 `layer blend=…` /
|
|
@@ -120,29 +145,48 @@ shader 合成到场景上。全部十六种 CSS 模式(`multiply`、`screen`
|
|
|
120
145
|
再由 SPIRV-Cross 交叉编译为 MSL(Metal);每个嵌套层级的两张场景纹理跨帧复用,
|
|
121
146
|
并通过 ping-pong 让背景在写入时仍可采样。既不吃 SPIR-V 也不吃 MSL 的后端
|
|
122
147
|
(这里的 D3D12/DXIL 路径没有 shader 编译器)仍用普通 source-over 混合绘制该组。
|
|
123
|
-
`backdrop-filter`
|
|
148
|
+
`backdrop-filter` 使用同一条运行时编译路径;shader 后端不可用时会跳过它,页面
|
|
149
|
+
其余内容仍照常绘制。
|
|
124
150
|
|
|
125
151
|
## 文本技术栈(M4b)
|
|
126
152
|
|
|
127
|
-
`runtime/ext_gui/text.{h,cpp}`
|
|
128
|
-
|
|
153
|
+
`runtime/ext_gui/text.{h,cpp}` 是前端,通过一个小型后端表分发。默认后端是内置的
|
|
154
|
+
**stb_truetype**(`text_stb.cpp`、`runtime/ext_gui/stb_truetype.h`)。可选的
|
|
155
|
+
**`shaping`** 链接特性会安装 `text_hb.cpp`(HarfBuzz + FreeType 后端),非 ASCII
|
|
156
|
+
文本或作者的 `@font-face` 规则会自动选中它。两个后端共享 `text_font_db.cpp` 中的
|
|
157
|
+
字体数据库(发现与索引)、`text_fonts.cpp` 中的 CSS 匹配器和
|
|
158
|
+
`text_font_sfnt.cpp` 中的 sfnt 元数据读取器,因此同一个 CSS 样式无论链接哪个整形
|
|
159
|
+
后端都会解析到同一个真实字面。
|
|
129
160
|
|
|
130
|
-
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
161
|
+
- 字体从已安装的系统字面解析。`font-family` 列表按大小写不敏感匹配;
|
|
162
|
+
`sans-serif`、`serif`、`monospace`(以及 `system-ui`/`ui-*` 别名)映射到平台
|
|
163
|
+
默认族,其他族名会一次性扫描平台字体目录。`font-weight`(1–1000)和
|
|
164
|
+
`font-style: italic` 按 CSS Fonts 的字重匹配顺序选择该族真实的粗体/斜体字面;
|
|
165
|
+
缺少对应字重时选择最接近的字面,族没有斜体字面时使用其直立字面——不做合成
|
|
166
|
+
粗体或斜体。字面按 `(文件, 集合索引, 字号)` 缓存。`XT_GUI_FONT` /
|
|
167
|
+
`XT_GUI_FONT_MONO` 仍可覆盖通用族的默认值。
|
|
168
|
+
- 支持作者 **`@font-face`**:加载本地 sfnt 字面(`.ttf`、`.ttc`、`.otf`、
|
|
169
|
+
`.otc`)。`src` 列表从左到右尝试;`local(...)`、远程 URL 和 `data:` 条目会被
|
|
170
|
+
跳过。相对 URL 按本地 `file:` 路径处理,相对进程工作目录解析(与图片资源的
|
|
171
|
+
策略一致);也接受 `file://` URL(包括百分号编码路径)。`font-weight` /
|
|
172
|
+
`font-style` 描述符选择字面,支持 `font-weight: 100 900` 这类范围;同族同
|
|
173
|
+
描述符的后一条规则覆盖前一条。CSS 匹配声明中的族名,即使它与字体文件内部的
|
|
174
|
+
族名不同。所有来源都不可读时,该族会继续回退到 CSS 列表中的下一个族。
|
|
175
|
+
- 默认候选优先选择 **CJK 覆盖的 TrueType/TTC** 字面(Windows 的 Microsoft
|
|
176
|
+
YaHei、macOS 的 PingFang/STHeiti、Linux 的 Noto Sans CJK/WenQuanYi),
|
|
177
|
+
再是纯拉丁字面。同一族的字重/样式变体会跨文件解析;stb_truetype 无法解析的
|
|
178
|
+
候选(例如 CFF/OTF 集合)会被跳过,`shaping` 后端则会加载它。
|
|
134
179
|
- **主字面缺少的码点会回退到其他字面。** 引擎维护一条小的回退链——先平台的
|
|
135
180
|
符号字体(Segoe UI Symbol、Apple Symbols、Noto Sans Symbols、DejaVu Sans),
|
|
136
|
-
|
|
181
|
+
再是默认的 sans、serif 和 monospace 字面——并为每个码点解析出回退链中第一个
|
|
182
|
+
拥有该字形的字面。
|
|
137
183
|
run 以每个字面一段的方式整形,因此混合 run(拉丁文加箭头、制表符或几何图形,
|
|
138
184
|
或 CJK 中的拉丁文)会绘制每个字形,而不是把缺失的字形当作 `.notdef` 丢弃。
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
`xt_text_metrics` 返回 FreeType 的 ascent / descent / 正常行高。当找不到
|
|
145
|
-
字体文件时,模块回退到确定性的逐字节近似,因此布局仍可工作。
|
|
185
|
+
每个整形后的字形携带自己的字面(`ShapedGlyph::font`),渲染器据此从正确的
|
|
186
|
+
图集条目光栅化;`xt_text_scale` 把字面映射到显示的缩放系数。
|
|
187
|
+
- `xt_text_measure_width` 把每个码点映射为字形并累加 advance 与字体的 `kern`
|
|
188
|
+
表;`xt_text_metrics` 返回 stb_truetype 的 ascent / descent / 正常行高。
|
|
189
|
+
当找不到字体文件时,模块回退到确定性的逐字节近似,因此布局仍可工作。
|
|
146
190
|
- `xt_text_shape_run` 返回定位后的字形,`xt_text_rasterize` 渲染 8 位位图;
|
|
147
191
|
渲染器把它们打包进图集。在 HiDPI 显示器上,字形以
|
|
148
192
|
`font_size * SDL_GetWindowPixelDensity` 光栅化,而四边形以逻辑像素定位,
|
|
@@ -150,6 +194,13 @@ shader 合成到场景上。全部十六种 CSS 模式(`multiply`、`screen`
|
|
|
150
194
|
- 布局使用这些真实度量进行文本宽度、断行与 `line-height: normal` 计算;
|
|
151
195
|
`measureText`/`fontMetrics` 把它们暴露给测试。
|
|
152
196
|
|
|
197
|
+
整形取舍:默认是简单整形器,不是完整的 OpenType 引擎。它覆盖拉丁/CJK/西里尔/
|
|
198
|
+
希腊文、基础字距与逐码点回退,但不执行连字或复杂文种(阿拉伯/印度/泰文)整形,
|
|
199
|
+
且 stb_truetype 只接受 TrueType 轮廓,不支持 CFF/OTF 或可变字体。该选择让
|
|
200
|
+
DOM-only 二进制约 3 MiB。可选的 **`shaping`** 链接特性会安装 HarfBuzz + FreeType
|
|
201
|
+
后端(约 1.2 MiB),恢复完整 OpenType 整形与 CFF/OTF/可变字体支持;非 ASCII 文本
|
|
202
|
+
会自动选中,也可用 `--feature shaping` 强制。
|
|
203
|
+
|
|
153
204
|
## 性能(M20)
|
|
154
205
|
|
|
155
206
|
引擎是保留模式管线:一次 DOM 变更会重算样式、重新布局、重建显示列表并上传
|
|
@@ -167,7 +218,14 @@ shader 合成到场景上。全部十六种 CSS 模式(`multiply`、`screen`
|
|
|
167
218
|
`(face, text) -> 字形 + 前进宽度`。它使用两代、每代最多 2 MiB 字形 / 8,192 条
|
|
168
219
|
条目;某一代写满时丢弃**备用**代并切换过去,因此热路径上没有 LRU 记账。
|
|
169
220
|
一个词只整形一次,之后每次布局和重绘都复用它。主字体查找也按
|
|
170
|
-
|
|
221
|
+
(字体族、字重、样式、字号)缓存;字体数据库本身只在第一次遇到非通用族名时
|
|
222
|
+
扫描一次平台目录。
|
|
223
|
+
- **空写不生效。** 当节点已经显示该值时,`textContent` 与 `style.<属性>` 不做任何
|
|
224
|
+
事:文档不会被标脏,也就没有重算样式、重新布局、重绘或上传。因此每帧都写入相同
|
|
225
|
+
计时文本、相同血条宽度或相同 transform 的 HUD 不产生任何开销 —— 在此之前,每次
|
|
226
|
+
赋值都会重建文本节点(一次分配,收集器随后还要清扫)或重写整条内联样式,并把
|
|
227
|
+
文档标脏触发全文重算。`classList` 与 `removeAttribute` 早就是这样;`setAttribute`
|
|
228
|
+
仍会无条件标脏。
|
|
171
229
|
- **帧循环。** 只有文档发生变化(或首帧)时才把媒体/画布表与 DOM 对齐,不再每帧
|
|
172
230
|
遍历整棵树。只有确实发生了事情才提交呈现(present)——DOM 变更、滚动、动画帧、
|
|
173
231
|
过渡、新的视频/画布帧、expose/resize 事件——因此静态页面完全不获取 swapchain、
|
package/doc/zh-CN/gui/runtime.md
CHANGED
|
@@ -48,6 +48,9 @@ deferred` 才是页面自身造成的工作。调试"漏掉的失效"时可用
|
|
|
48
48
|
动画帧回调,因此页面可以自行停止);
|
|
49
49
|
- 只有在**仍有回调**时才重新排程,空闲页面会让事件循环排空并退出进程 ——
|
|
50
50
|
这正是浏览器标签页的生命周期;
|
|
51
|
+
- 下一次 tick 排在**帧开始 + 16 ms**,而不是帧结束后再等 16 ms:帧自身耗时不再
|
|
52
|
+
叠加到间隔上,10 ms 的帧以 16 ms 周期运行(而不是 26 ms),比 16 ms 更慢的页面
|
|
53
|
+
则以全速运行,而不是每帧再落后一帧的时间;
|
|
51
54
|
- 当 `xt_gui_run_active()` 为真(程序自己调用了 `run()`)时它会让路,避免同一
|
|
52
55
|
窗口每 tick 被渲染两次;
|
|
53
56
|
- `XT_GUI_AUTOCLOSE_MS=n` 让帧泵在 `n` 毫秒后退出,测试用它来运行不会自行
|