xbintsc 0.5.41 → 0.5.42
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/dist/src/cli/help.d.ts +1 -1
- package/dist/src/driver/version.d.ts +1 -1
- package/dist/src/driver/version.js +1 -1
- package/dist/tests/e2e/gui-data-url.test.d.ts +10 -0
- package/dist/tests/e2e/gui-data-url.test.js +127 -0
- package/dist/tests/e2e/gui-data-url.test.js.map +1 -0
- package/dist/tests/e2e/gui-effects.test.js +96 -0
- package/dist/tests/e2e/gui-effects.test.js.map +1 -1
- package/dist/tests/e2e/gui-paint.test.js +77 -0
- package/dist/tests/e2e/gui-paint.test.js.map +1 -1
- package/doc/gui/canvas.md +6 -2
- package/doc/gui/known-issues.md +15 -9
- package/doc/gui/media.md +11 -2
- package/doc/gui/rendering.md +43 -18
- package/doc/gui.md +5 -4
- package/doc/zh-CN/gui/canvas.md +6 -4
- package/doc/zh-CN/gui/known-issues.md +11 -8
- package/doc/zh-CN/gui/media.md +9 -2
- package/doc/zh-CN/gui/rendering.md +30 -11
- package/doc/zh-CN/gui.md +1 -1
- package/package.json +7 -7
- package/runtime/ext_gui/dom_api_canvas.cpp +42 -24
- package/runtime/ext_gui/gradient_values.cpp +44 -48
- package/runtime/ext_gui/gui_events.cpp +16 -13
- package/runtime/ext_gui/image.cpp +180 -25
- package/runtime/ext_gui/image.h +6 -4
- package/runtime/ext_gui/paint.cpp +53 -3
- package/runtime/ext_gui/paint.h +11 -1
- package/runtime/ext_gui/paint_background.cpp +92 -11
- package/runtime/ext_gui/paint_effects.cpp +2 -1
- package/runtime/ext_gui/paint_internal.h +5 -1
- package/runtime/ext_gui/renderer.cpp +81 -13
- package/runtime/ext_gui/renderer.h +19 -5
- package/runtime/ext_gui/renderer_internal.h +26 -0
- package/runtime/ext_gui/renderer_layer.cpp +552 -0
- package/runtime/ext_gui/style.h +29 -1
- package/runtime/ext_gui/style_print.cpp +10 -2
- package/runtime/ext_gui/style_values.cpp +10 -0
- package/src/driver/version.ts +1 -1
package/dist/src/cli/help.d.ts
CHANGED
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
* It lives apart from the command dispatch so the executable entry point stays
|
|
5
5
|
* under the repository's per-file line budget; the text is data, not logic.
|
|
6
6
|
*/
|
|
7
|
-
export declare const HELP = "xbintsc 0.5.
|
|
7
|
+
export declare const HELP = "xbintsc 0.5.42 - TypeScript binary compiler\n\nUsage:\n xbintsc build <file.ts> [options] Compile to a native binary\n xbintsc run <file.ts> [-- args] Compile and execute\n xbintsc check <file.ts> Parse, bind and check without linking\n xbintsc watch <file.ts> [options] Rebuild whenever the source tree changes\n xbintsc emit <file.ts> Print LLVM IR\n xbintsc doctor Report the resolved toolchain\n xbintsc version Print the version\n xbintsc help Show this message\n\nOptions:\n -o, --output <path> Output path\n --out <dir> Output directory (default: build/)\n --emit <kind> exe | obj | ir (default: exe)\n -O0..-O3 Optimization level (default: -O2)\n --ext <names> Comma separated extensions (e.g. node,gui,media)\n --ext-native <m> Register a C++/Rust extension from a JSON manifest\n (comma separated for several)\n --config <path> Use a project config (default: auto-detect\n xbintsc.config.json)\n --no-config Do not read any project config\n --icon <path> Embed an application icon (PNG/ICO/ICNS)\n --bundle macOS: also produce a .app bundle\n --app-name <name> Bundle / display name\n --app-id <id> macOS bundle identifier (e.g. com.example.demo)\n --force Ignore the incremental cache\n --verbose Print progress information\n --time Print per-phase build timings\n --debug Emit debug info (DWARF/CodeView) and keep frame pointers\n --check Run the semantic checker (default)\n --no-check Skip the semantic checker; only erase type syntax\n --lto Compile program and runtime to LTO bitcode; link with lld\n --pgo-generate [dir] Build an instrumented binary writing profiles to dir\n --pgo-use [dir] Build with the profiles collected from --pgo-generate\n --json Print diagnostics as a JSON array on stdout\n --no-hints Do not append the \"hint: \u2026 see <doc>\" line to failures\n\nxbintsc compiles a subset of TypeScript to a native binary. Types are erased;\nonly inference-free facts (names, redeclarations, call arity) are checked.\nNode built-ins need --ext node, packages in node_modules are bundled at build\ntime, and clang 16+ is required to link.\n\nInstalled as a project dependency (npm):\n npx xbintsc doctor\n npx xbintsc build <entry.ts> --out build\n npx xbintsc run <entry.ts>\nThe first build compiles the C runtime; later builds reuse the cache.\n\nDocs: doc/ai/README.md (task guide) - doc/ai/language-support.md (subset) -\ndoc/ai/troubleshooting.md (failures) - llms.txt (index of every document).\nWhen installed from npm, these live under node_modules/xbintsc/doc/ and\nnode_modules/xbintsc/doc/npm-package.md is the project guide.\n";
|
|
@@ -9,5 +9,5 @@
|
|
|
9
9
|
* `main`/`master` only (see `.githooks/pre-commit`), so feature branches never
|
|
10
10
|
* change this line and merging two of them cannot conflict here.
|
|
11
11
|
*/
|
|
12
|
-
export const COMPILER_VERSION = "0.5.
|
|
12
|
+
export const COMPILER_VERSION = "0.5.42";
|
|
13
13
|
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* End-to-end tests for `data:` image URLs: raster and SVG, base64 and
|
|
3
|
+
* percent-encoded payloads, in `<img>`, `canvas.drawImage(String, …)` and CSS
|
|
4
|
+
* `background-image`.
|
|
5
|
+
*
|
|
6
|
+
* The SVG below deliberately exercises the decoder, not NanoSVG's feature set:
|
|
7
|
+
* the engine rasterises NanoSVG's subset, so an SVG that uses filters still
|
|
8
|
+
* decodes but renders the shapes without the filter effect.
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* End-to-end tests for `data:` image URLs: raster and SVG, base64 and
|
|
3
|
+
* percent-encoded payloads, in `<img>`, `canvas.drawImage(String, …)` and CSS
|
|
4
|
+
* `background-image`.
|
|
5
|
+
*
|
|
6
|
+
* The SVG below deliberately exercises the decoder, not NanoSVG's feature set:
|
|
7
|
+
* the engine rasterises NanoSVG's subset, so an SVG that uses filters still
|
|
8
|
+
* decodes but renders the shapes without the filter effect.
|
|
9
|
+
*/
|
|
10
|
+
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
|
11
|
+
import { createGuiHarness, guiAvailable } from "./gui-helpers.js";
|
|
12
|
+
const harness = createGuiHarness();
|
|
13
|
+
/* 4x4 PNG: left half red, right half blue. */
|
|
14
|
+
const PNG = "iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAAFElEQVR42mP4z8DwH4Sh1H8G0gUALFAf4eNWqTEAAAAASUVORK5CYII=";
|
|
15
|
+
const SVG = '<svg xmlns="http://www.w3.org/2000/svg" width="8" height="6"><rect width="8" height="6" fill="#ff0000"/></svg>';
|
|
16
|
+
const SVG_B64 = Buffer.from(SVG).toString("base64");
|
|
17
|
+
const SVG_ENC = encodeURIComponent(SVG);
|
|
18
|
+
/** The `feTurbulence` example from the request: `<filter>` is not in NanoSVG's
|
|
19
|
+
* subset, but the document still decodes (the rect renders, unfiltered). */
|
|
20
|
+
const NOISE = "data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.8'/%3E%3C/svg%3E";
|
|
21
|
+
const PAGE = `
|
|
22
|
+
<html><head><style>body { margin: 0; }</style></head><body>
|
|
23
|
+
<img id="vec" src="data:image/svg+xml,${SVG_ENC}">
|
|
24
|
+
<img id="vec64" src="data:image/svg+xml;base64,${SVG_B64}">
|
|
25
|
+
<img id="noise" src="${NOISE}">
|
|
26
|
+
<div id="bg" style="width:20px;height:20px"></div>
|
|
27
|
+
<canvas id="c" width="240" height="240"></canvas>
|
|
28
|
+
</body></html>`;
|
|
29
|
+
describe.skipIf(!guiAvailable)("gui extension — data URL images", () => {
|
|
30
|
+
beforeAll(() => harness.setup());
|
|
31
|
+
afterAll(() => harness.cleanup());
|
|
32
|
+
it("decodes SVG data URLs in <img>, drawImage and CSS backgrounds", () => {
|
|
33
|
+
const { value, stderr } = harness.compileAndRun("data-url-svg", `
|
|
34
|
+
import { createWindow, run } from "gui";
|
|
35
|
+
|
|
36
|
+
const win = createWindow({ title: "data-url", width: 500, height: 400 });
|
|
37
|
+
win.on("ready", () => {
|
|
38
|
+
const doc: any = document;
|
|
39
|
+
const ctx: any = doc.getElementById("c").getContext("2d");
|
|
40
|
+
const px = (x: number, y: number): string => {
|
|
41
|
+
const d = ctx.getImageData(x, y, 1, 1).data;
|
|
42
|
+
return d[0] + "," + d[1] + "," + d[2] + "," + d[3];
|
|
43
|
+
};
|
|
44
|
+
const clear = (): void => { ctx.clearRect(0, 0, 240, 240); };
|
|
45
|
+
const box = (id: string): string => {
|
|
46
|
+
const r: any = doc.getElementById(id).getBoundingClientRect();
|
|
47
|
+
return r.width + "x" + r.height;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const png = "data:image/png;base64,${PNG}";
|
|
51
|
+
const svgEnc = "data:image/svg+xml,${SVG_ENC}";
|
|
52
|
+
const svg64 = "data:image/svg+xml;base64,${SVG_B64}";
|
|
53
|
+
const noise = "${NOISE}";
|
|
54
|
+
|
|
55
|
+
console.log("vec-box=" + box("vec"));
|
|
56
|
+
console.log("vec64-box=" + box("vec64"));
|
|
57
|
+
console.log("noise-box=" + box("noise"));
|
|
58
|
+
|
|
59
|
+
// A raster data URL drawn from its string, without an <img>.
|
|
60
|
+
clear();
|
|
61
|
+
ctx.drawImage(png, 0, 0);
|
|
62
|
+
console.log("png-string=" + px(0, 0) + ":" + px(3, 0));
|
|
63
|
+
|
|
64
|
+
// SVG data URLs in both encodings, as a string and as an <img>.
|
|
65
|
+
clear();
|
|
66
|
+
ctx.drawImage(svgEnc, 0, 0);
|
|
67
|
+
console.log("svg-enc-string=" + px(0, 0) + ":" + px(7, 5));
|
|
68
|
+
|
|
69
|
+
clear();
|
|
70
|
+
ctx.drawImage(svg64, 0, 0);
|
|
71
|
+
console.log("svg64-string=" + px(0, 0));
|
|
72
|
+
|
|
73
|
+
clear();
|
|
74
|
+
ctx.drawImage(svgEnc, 0, 0, 16, 12);
|
|
75
|
+
console.log("svg-scaled=" + px(0, 0) + ":" + px(15, 11));
|
|
76
|
+
|
|
77
|
+
clear();
|
|
78
|
+
ctx.drawImage(doc.getElementById("vec"), 0, 0);
|
|
79
|
+
console.log("svg-img=" + px(0, 0));
|
|
80
|
+
|
|
81
|
+
clear();
|
|
82
|
+
ctx.drawImage(doc.getElementById("vec64"), 0, 0);
|
|
83
|
+
console.log("svg64-img=" + px(0, 0));
|
|
84
|
+
|
|
85
|
+
// The request's feTurbulence document: it decodes (opaque rect), while
|
|
86
|
+
// the filter itself remains outside NanoSVG's subset.
|
|
87
|
+
clear();
|
|
88
|
+
ctx.drawImage(noise, 0, 0, 32, 32);
|
|
89
|
+
console.log("noise-alpha=" + ctx.getImageData(0, 0, 1, 1).data[3]);
|
|
90
|
+
|
|
91
|
+
// SVG data URL as a CSS background.
|
|
92
|
+
const bg: any = doc.getElementById("bg");
|
|
93
|
+
bg.style.backgroundImage = 'url("' + svgEnc + '")';
|
|
94
|
+
console.log("bg-css=" + getComputedStyle(bg).backgroundImage.substring(0, 26));
|
|
95
|
+
let hits = 0;
|
|
96
|
+
for (const line of win.paintList().split("\\n")) {
|
|
97
|
+
if (line.indexOf("src=data:image/svg+xml") >= 0) hits++;
|
|
98
|
+
}
|
|
99
|
+
console.log("paint-svg=" + hits);
|
|
100
|
+
|
|
101
|
+
// Let one rendered frame decode the background texture (stderr reports
|
|
102
|
+
// a failure), then close.
|
|
103
|
+
requestAnimationFrame(() => {
|
|
104
|
+
requestAnimationFrame(() => {
|
|
105
|
+
win.close();
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
win.loadHTML(\`${PAGE}\`);
|
|
110
|
+
run();
|
|
111
|
+
`, { autocloseMs: 3000 });
|
|
112
|
+
expect(value("vec-box")).toBe("8x6");
|
|
113
|
+
expect(value("vec64-box")).toBe("8x6");
|
|
114
|
+
expect(value("noise-box")).toBe("180x180");
|
|
115
|
+
expect(value("png-string")).toBe("255,0,0,255:0,0,255,255");
|
|
116
|
+
expect(value("svg-enc-string")).toBe("255,0,0,255:255,0,0,255");
|
|
117
|
+
expect(value("svg64-string")).toBe("255,0,0,255");
|
|
118
|
+
expect(value("svg-scaled")).toBe("255,0,0,255:255,0,0,255");
|
|
119
|
+
expect(value("svg-img")).toBe("255,0,0,255");
|
|
120
|
+
expect(value("svg64-img")).toBe("255,0,0,255");
|
|
121
|
+
expect(Number(value("noise-alpha"))).toBeGreaterThan(0);
|
|
122
|
+
expect(value("bg-css")).toMatch(/^url\(data:image\/svg\+xml/);
|
|
123
|
+
expect(value("paint-svg")).toBe("4");
|
|
124
|
+
expect(stderr).not.toContain("could not decode image");
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
//# sourceMappingURL=gui-data-url.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gui-data-url.test.js","sourceRoot":"","sources":["../../../tests/e2e/gui-data-url.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAElE,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;AAEnC,8CAA8C;AAC9C,MAAM,GAAG,GACP,0GAA0G,CAAC;AAC7G,MAAM,GAAG,GACP,gHAAgH,CAAC;AACnH,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACpD,MAAM,OAAO,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;AAExC;4EAC4E;AAC5E,MAAM,KAAK,GACT,4SAA4S,CAAC;AAE/S,MAAM,IAAI,GAAG;;wCAE2B,OAAO;iDACE,OAAO;uBACjC,KAAK;;;eAGb,CAAC;AAEhB,QAAQ,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,iCAAiC,EAAE,GAAG,EAAE;IACrE,SAAS,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IACjC,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAElC,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAC7C,cAAc,EACd;;;;;;;;;;;;;;;;;6CAiBuC,GAAG;6CACH,OAAO;mDACD,OAAO;yBACjC,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBAwDP,IAAI;;OAEpB,EACD,EAAE,WAAW,EAAE,IAAI,EAAE,CACtB,CAAC;QAEF,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC3C,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAC5D,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAChE,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAClD,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAC5D,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC7C,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACxD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAC;QAC9D,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -138,6 +138,102 @@ describe.skipIf(!guiAvailable)("gui extension — effects", () => {
|
|
|
138
138
|
// Radial bands plus the linear strips.
|
|
139
139
|
expect(Number(value("count"))).toBeGreaterThan(30);
|
|
140
140
|
});
|
|
141
|
+
it("tiles repeating gradients across the whole box", () => {
|
|
142
|
+
const { value, stdout } = harness.compileAndRun("repeating-gradient", `
|
|
143
|
+
import { createWindow, run } from "gui";
|
|
144
|
+
|
|
145
|
+
const HTML = \`
|
|
146
|
+
<html><head><style>
|
|
147
|
+
body { margin: 0; }
|
|
148
|
+
#r {
|
|
149
|
+
width: 100px; height: 40px;
|
|
150
|
+
background: repeating-linear-gradient(90deg,
|
|
151
|
+
#ff0000 0%, #ff0000 10%, #0000ff 10%, #0000ff 20%);
|
|
152
|
+
}
|
|
153
|
+
</style></head><body><div id="r"></div></body></html>
|
|
154
|
+
\`;
|
|
155
|
+
|
|
156
|
+
const win = createWindow({ title: "repeating-gradient", width: 400, height: 300 });
|
|
157
|
+
win.on("ready", () => {
|
|
158
|
+
console.log("image=" + win.computedStyle("#r", "background-image"));
|
|
159
|
+
console.log("list-start");
|
|
160
|
+
console.log(win.paintList());
|
|
161
|
+
console.log("list-end");
|
|
162
|
+
win.close();
|
|
163
|
+
});
|
|
164
|
+
win.loadHTML(HTML);
|
|
165
|
+
run();
|
|
166
|
+
`);
|
|
167
|
+
const list = stdout.slice(stdout.indexOf("list-start"), stdout.indexOf("list-end"));
|
|
168
|
+
// The computed value keeps the repeating function name ...
|
|
169
|
+
expect(value("image")).toBe("repeating-linear-gradient()");
|
|
170
|
+
// ... and the whole 100px box is tiled: a 20% period gives five red and
|
|
171
|
+
// five blue bands, not one ramp that holds the final colour.
|
|
172
|
+
expect((list.match(/#ff0000ff/g) ?? []).length).toBeGreaterThan(4);
|
|
173
|
+
expect((list.match(/#0000ffff/g) ?? []).length).toBeGreaterThan(4);
|
|
174
|
+
});
|
|
175
|
+
it("resolves pixel offsets in repeating gradients", () => {
|
|
176
|
+
const { value, stdout } = harness.compileAndRun("repeating-gradient-px", `
|
|
177
|
+
import { createWindow, run } from "gui";
|
|
178
|
+
|
|
179
|
+
const HTML = \`
|
|
180
|
+
<html><head><style>
|
|
181
|
+
body { margin: 0; }
|
|
182
|
+
#r {
|
|
183
|
+
width: 100px; height: 20px;
|
|
184
|
+
background: repeating-linear-gradient(90deg,
|
|
185
|
+
#123456 0px 10px, #abcdef 10px 20px);
|
|
186
|
+
}
|
|
187
|
+
</style></head><body><div id="r"></div></body></html>
|
|
188
|
+
\`;
|
|
189
|
+
|
|
190
|
+
const win = createWindow({ title: "repeating-gradient-px", width: 400, height: 300 });
|
|
191
|
+
win.on("ready", () => {
|
|
192
|
+
console.log("image=" + win.computedStyle("#r", "background-image"));
|
|
193
|
+
console.log("list-start");
|
|
194
|
+
console.log(win.paintList());
|
|
195
|
+
console.log("list-end");
|
|
196
|
+
win.close();
|
|
197
|
+
});
|
|
198
|
+
win.loadHTML(HTML);
|
|
199
|
+
run();
|
|
200
|
+
`);
|
|
201
|
+
const list = stdout.slice(stdout.indexOf("list-start"), stdout.indexOf("list-end"));
|
|
202
|
+
expect(value("image")).toBe("repeating-linear-gradient()");
|
|
203
|
+
expect((list.match(/#123456ff/g) ?? []).length).toBeGreaterThan(4);
|
|
204
|
+
expect((list.match(/#abcdefff/g) ?? []).length).toBeGreaterThan(4);
|
|
205
|
+
});
|
|
206
|
+
it("tiles repeating radial gradients", () => {
|
|
207
|
+
const { value, stdout } = harness.compileAndRun("repeating-radial-gradient", `
|
|
208
|
+
import { createWindow, run } from "gui";
|
|
209
|
+
|
|
210
|
+
const HTML = \`
|
|
211
|
+
<html><head><style>
|
|
212
|
+
body { margin: 0; }
|
|
213
|
+
#r {
|
|
214
|
+
width: 40px; height: 40px;
|
|
215
|
+
background: repeating-radial-gradient(circle at 50% 50%,
|
|
216
|
+
#ff0000 0%, #ff0000 5%, #0000ff 5%, #0000ff 10%);
|
|
217
|
+
}
|
|
218
|
+
</style></head><body><div id="r"></div></body></html>
|
|
219
|
+
\`;
|
|
220
|
+
|
|
221
|
+
const win = createWindow({ title: "repeating-radial-gradient", width: 400, height: 300 });
|
|
222
|
+
win.on("ready", () => {
|
|
223
|
+
console.log("image=" + win.computedStyle("#r", "background-image"));
|
|
224
|
+
console.log("list-start");
|
|
225
|
+
console.log(win.paintList());
|
|
226
|
+
console.log("list-end");
|
|
227
|
+
win.close();
|
|
228
|
+
});
|
|
229
|
+
win.loadHTML(HTML);
|
|
230
|
+
run();
|
|
231
|
+
`);
|
|
232
|
+
const list = stdout.slice(stdout.indexOf("list-start"), stdout.indexOf("list-end"));
|
|
233
|
+
expect(value("image")).toBe("repeating-radial-gradient()");
|
|
234
|
+
expect(list).toContain("#ff0000ff");
|
|
235
|
+
expect(list).toContain("#0000ffff");
|
|
236
|
+
});
|
|
141
237
|
it("paints text-shadow copies behind the text", () => {
|
|
142
238
|
const { value, stdout } = harness.compileAndRun("text-shadow", `
|
|
143
239
|
import { createWindow, run } from "gui";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gui-effects.test.js","sourceRoot":"","sources":["../../../tests/e2e/gui-effects.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"gui-effects.test.js","sourceRoot":"","sources":["../../../tests/e2e/gui-effects.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAElE,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;AAEnC,QAAQ,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,yBAAyB,EAAE,GAAG,EAAE;IAC7D,SAAS,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IACjC,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAElC,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;QAC1E,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,aAAa,CACrC,OAAO,EACP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BC,CACF,CAAC;QACF,wEAAwE;QACxE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC1C,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC1C,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC1C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAC/E,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAC7C,QAAQ,EACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BC,CACF,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;QACpF,qDAAqD;QACrD,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpC,qEAAqE;QACrE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACpC,0DAA0D;QAC1D,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACxC,2EAA2E;QAC3E,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;QACzC,MAAM,CAAC,GAAG,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;QACnC,wEAAwE;QACxE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAC7C,aAAa,EACb;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BC,CACF,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;QACpF,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QACtD,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QACtD,wEAAwE;QACxE,8CAA8C;QAC9C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAC3C,uCAAuC;QACvC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAC7C,oBAAoB,EACpB;;;;;;;;;;;;;;;;;;;;;;;;OAwBC,CACF,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;QACpF,2DAA2D;QAC3D,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QAC3D,wEAAwE;QACxE,6DAA6D;QAC7D,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACnE,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAC7C,uBAAuB,EACvB;;;;;;;;;;;;;;;;;;;;;;;;OAwBC,CACF,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;QACpF,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QAC3D,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACnE,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAC7C,2BAA2B,EAC3B;;;;;;;;;;;;;;;;;;;;;;;;OAwBC,CACF,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;QACpF,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QAC3D,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAC7C,aAAa,EACb;;;;;;;;;;;;;;;;;;;;OAoBC,CACF,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;QACpF,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QACvD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;QAC/C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,+BAA+B,CAAC,CAAC;QACxD,oDAAoD;QACpD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAC7C,WAAW,EACX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BC,CACF,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;QACpF,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QAC1D,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC1C,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC3C,oEAAoE;QACpE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QACtC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAC7C,QAAQ,EACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCC,CACF,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;QACpF,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;QAC7D,2EAA2E;QAC3E,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;QAC5D,+DAA+D;QAC/D,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACpC,yCAAyC;QACzC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACpC,gEAAgE;QAChE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAClD,4DAA4D;QAC5D,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -187,5 +187,82 @@ describe.skipIf(!guiAvailable)("gui extension — paint", () => {
|
|
|
187
187
|
// Anything above 0 is painted in full (there is no partial compositing yet).
|
|
188
188
|
expect(list).toContain("#ff0000ff");
|
|
189
189
|
});
|
|
190
|
+
it("applies fractional `opacity` to every painted colour in the subtree", () => {
|
|
191
|
+
const { value, stdout } = harness.compileAndRun("opacity-half", `
|
|
192
|
+
import { createWindow, run } from "gui";
|
|
193
|
+
|
|
194
|
+
const HTML = \`
|
|
195
|
+
<html><head><style>
|
|
196
|
+
body { margin: 0; background-color: #000000; }
|
|
197
|
+
#half { width: 40px; height: 20px; background: #ff0000; opacity: 0.5; }
|
|
198
|
+
#nested { width: 20px; height: 10px; background: #00ff00; color: #00ff00; opacity: 0.5; }
|
|
199
|
+
#label { color: #ffff00; }
|
|
200
|
+
</style></head><body>
|
|
201
|
+
<div id="half"><div id="nested"><span id="label">faded</span></div></div>
|
|
202
|
+
</body></html>
|
|
203
|
+
\`;
|
|
204
|
+
|
|
205
|
+
const win = createWindow({ title: "opacity-half", width: 400, height: 300 });
|
|
206
|
+
win.on("ready", () => {
|
|
207
|
+
console.log("opacity=" + win.computedStyle("#nested", "opacity"));
|
|
208
|
+
console.log("list-start");
|
|
209
|
+
console.log(win.paintList());
|
|
210
|
+
console.log("list-end");
|
|
211
|
+
win.close();
|
|
212
|
+
});
|
|
213
|
+
win.loadHTML(HTML);
|
|
214
|
+
run();
|
|
215
|
+
`);
|
|
216
|
+
const list = stdout.slice(stdout.indexOf("list-start"), stdout.indexOf("list-end"));
|
|
217
|
+
expect(value("opacity")).toBe("0.5");
|
|
218
|
+
// #half's red background, then #nested's 0.5 on top of it, then the text's
|
|
219
|
+
// inherited 0.25: alpha is multiplied down the paint chain instead of
|
|
220
|
+
// treating any value above zero as opaque.
|
|
221
|
+
expect(list).toContain("color=#ff000080");
|
|
222
|
+
expect(list).toContain("color=#00ff0040");
|
|
223
|
+
expect(list).toContain("color=#ffff0040");
|
|
224
|
+
});
|
|
225
|
+
it("wraps `mix-blend-mode` boxes in a compositing layer", () => {
|
|
226
|
+
const { value, stdout, stderr } = harness.compileAndRun("mix-blend-mode", `
|
|
227
|
+
import { createWindow, run } from "gui";
|
|
228
|
+
|
|
229
|
+
const HTML = \`
|
|
230
|
+
<html><head><style>
|
|
231
|
+
body { margin: 0; }
|
|
232
|
+
#card { width: 100px; height: 100px; background: #ffffff; }
|
|
233
|
+
#multiply { width: 50px; height: 50px; background: #ff0000; mix-blend-mode: multiply; }
|
|
234
|
+
#overlay { width: 20px; height: 20px; background: #00ff00; mix-blend-mode: overlay; }
|
|
235
|
+
</style></head><body>
|
|
236
|
+
<div id="card"><div id="multiply"><div id="overlay"></div></div></div>
|
|
237
|
+
</body></html>
|
|
238
|
+
\`;
|
|
239
|
+
|
|
240
|
+
const win = createWindow({ title: "mix-blend-mode", width: 400, height: 300 });
|
|
241
|
+
win.on("ready", () => {
|
|
242
|
+
console.log("multiply=" + win.computedStyle("#multiply", "mix-blend-mode"));
|
|
243
|
+
console.log("overlay=" + win.computedStyle("#overlay", "mix-blend-mode"));
|
|
244
|
+
console.log("list-start");
|
|
245
|
+
console.log(win.paintList());
|
|
246
|
+
console.log("list-end");
|
|
247
|
+
win.close();
|
|
248
|
+
});
|
|
249
|
+
win.loadHTML(HTML);
|
|
250
|
+
run();
|
|
251
|
+
`);
|
|
252
|
+
const list = stdout.slice(stdout.indexOf("list-start"), stdout.indexOf("list-end"));
|
|
253
|
+
expect(value("multiply")).toBe("multiply");
|
|
254
|
+
expect(value("overlay")).toBe("overlay");
|
|
255
|
+
// The card paints normally; the multiply element and its overlay child are
|
|
256
|
+
// separate nested groups (the renderer composites each as a unit).
|
|
257
|
+
expect(list).toContain("layer blend=multiply");
|
|
258
|
+
expect(list).toContain("layer blend=overlay");
|
|
259
|
+
expect(list).toContain("end-layer");
|
|
260
|
+
expect(list).toContain("color=#ffffffff");
|
|
261
|
+
expect(list).toContain("color=#ff0000ff");
|
|
262
|
+
expect(list).toContain("color=#00ff00ff");
|
|
263
|
+
// The offscreen blend pipeline and its runtime-compiled shader must not
|
|
264
|
+
// fall back on this GPU backend.
|
|
265
|
+
expect(stderr).not.toContain("mix-blend-mode");
|
|
266
|
+
});
|
|
190
267
|
});
|
|
191
268
|
//# sourceMappingURL=gui-paint.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gui-paint.test.js","sourceRoot":"","sources":["../../../tests/e2e/gui-paint.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"gui-paint.test.js","sourceRoot":"","sources":["../../../tests/e2e/gui-paint.test.ts"],"names":[],"mappings":"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"}
|
package/doc/gui/canvas.md
CHANGED
|
@@ -206,7 +206,10 @@ engine's 9-argument form is destination-first) forms. A full affine transform
|
|
|
206
206
|
(rotation/skew/scale) is honoured: the destination rectangle becomes a
|
|
207
207
|
parallelogram and every device pixel is inverse-mapped to the source rectangle.
|
|
208
208
|
`source` may be an `<img>` element (decoded through the image module), another
|
|
209
|
-
`<canvas>`, an `OffscreenCanvas`,
|
|
209
|
+
`<canvas>`, an `OffscreenCanvas`, an `ImageBitmap`, or — an engine extension — a
|
|
210
|
+
string path/`data:` URL that is decoded directly, so an SVG or bitmap data URL
|
|
211
|
+
can be drawn without an `<img>`. A vector source is rasterised at the destination
|
|
212
|
+
size (`dw`/`dh`), keeping a scaled SVG crisp. Sampling is bilinear when
|
|
210
213
|
`imageSmoothingEnabled` is `true` (the default) and nearest-neighbour when it is
|
|
211
214
|
`false`.
|
|
212
215
|
|
|
@@ -230,7 +233,8 @@ from a microtask (the bytes are on `__xt_gui_blob_data`; there is no
|
|
|
230
233
|
shape and `transferToImageBitmap()` snapshots the bitmap.
|
|
231
234
|
|
|
232
235
|
CSS backgrounds: `background-image: url(...)` accepts a file path or a `data:`
|
|
233
|
-
URL
|
|
236
|
+
URL (a raster payload or an SVG document, base64 or percent-encoded), so a
|
|
237
|
+
canvas can be used as a CSS background by exporting it first
|
|
234
238
|
(`element.style.backgroundImage = "url(" + canvas.toDataURL() + ")"`). An image
|
|
235
239
|
layer is stretched to the element's border box; `background-size`,
|
|
236
240
|
`background-position` and tiling are not modelled.
|
package/doc/gui/known-issues.md
CHANGED
|
@@ -59,18 +59,22 @@
|
|
|
59
59
|
`pointer-events`, `@media` queries, generated content (`::before`/`::after`),
|
|
60
60
|
multi-layer linear/radial backgrounds, `text-shadow`, `clip-path`
|
|
61
61
|
(`inset`/`circle`/`ellipse`/`polygon`) and `filter` colour functions are
|
|
62
|
-
implemented. Known limits: `
|
|
63
|
-
`background-position`/`size`/`repeat
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
implemented. Known limits: `background-clip`,
|
|
63
|
+
`background-position`/`size`/`repeat` and `backdrop-filter` compositing are not
|
|
64
|
+
implemented (`backdrop-filter` parses and cascades, but sampling the backdrop
|
|
65
|
+
needs an offscreen layer, so it paints nothing); `mix-blend-mode` and repeating
|
|
66
|
+
gradients are implemented (see [Rendering](./rendering.md)), but group
|
|
67
|
+
`opacity` is a per-shape alpha rather than a true group composite, and the
|
|
68
|
+
blend compositor is unavailable on the D3D12/DXIL backend, where groups fall
|
|
69
|
+
back to normal source-over painting;
|
|
66
70
|
`filter: blur()` is a nine-tap per-shape spread rather than a true group blur,
|
|
67
71
|
so overlapping descendants can darken; `drop-shadow` is approximated from box
|
|
68
72
|
silhouettes; at most two nested `clip-path` shapes are intersected (deeper
|
|
69
73
|
nesting keeps the outer two); and images/canvases are not colour-filtered
|
|
70
74
|
except for the brightness/opacity tint the image shader can carry. Canvas
|
|
71
75
|
textures are sampled nearest-neighbour. Background gradients remain solid
|
|
72
|
-
bands (18 for linear, 32 concentric ellipses for radial
|
|
73
|
-
may show slight banding.
|
|
76
|
+
bands (18 for linear, 32 concentric ellipses for radial; 64 for repeating
|
|
77
|
+
gradients), so a soft gradient may show slight banding.
|
|
74
78
|
- **SVG is NanoSVG's subset.** SVG *files* (`<img src="logo.svg">`) and inline
|
|
75
79
|
`<svg>` trees share the vendored NanoSVG parser/rasteriser
|
|
76
80
|
(`runtime/ext_gui/svg.cpp`, `inline_svg.cpp`), which renders
|
|
@@ -78,9 +82,11 @@
|
|
|
78
82
|
gradients and class-based `<style>` rules. `<text>`, `<use>`, filters, masks
|
|
79
83
|
and clip paths are not rendered, and CSS applied by the document cascade does
|
|
80
84
|
not reach inside the artwork (fill/stroke are SVG presentation attributes,
|
|
81
|
-
not CSS properties here).
|
|
82
|
-
|
|
83
|
-
|
|
85
|
+
not CSS properties here). An SVG whose only artwork comes from a filter
|
|
86
|
+
(`feTurbulence` noise, blur, …) therefore shows the unfiltered shapes — often
|
|
87
|
+
a solid rect — rather than the filter result. Vector art that needs those has
|
|
88
|
+
to be rasterised beforehand, drawn from boxes, or restricted to the supported
|
|
89
|
+
syntax. See [Media](./media.md#images-m6a).
|
|
84
90
|
- **Rendering is still whole-document per change.** A DOM mutation recomputes
|
|
85
91
|
the cascade and lays out the complete document again (there is no incremental
|
|
86
92
|
subtree invalidation), and a change that only affects paint (a hover colour,
|
package/doc/gui/media.md
CHANGED
|
@@ -43,6 +43,15 @@ subtree, whose DOM nodes are serialized into a document first
|
|
|
43
43
|
without limit.
|
|
44
44
|
- The parse is cached per path; the parse and rasteriser state are released in
|
|
45
45
|
`xt_svg_shutdown` (`xt_image_shutdown`).
|
|
46
|
+
- `data:` URLs are decoded in memory and work wherever a path does:
|
|
47
|
+
`<img src>`, CSS `background-image` and `canvas.drawImage(url, …)`. Both the
|
|
48
|
+
`;base64` form and a percent-encoded (or plain) payload are accepted, and the
|
|
49
|
+
`base64` flag is case-insensitive. The MIME type only classifies the payload:
|
|
50
|
+
`image/svg+xml` (or an SVG sniff when the type is generic or absent) goes
|
|
51
|
+
through NanoSVG — a data-URL SVG is rasterised at the drawn size exactly like
|
|
52
|
+
an SVG file — while PNG/JPEG/BMP/GIF/TGA go through `stb_image`. NanoSVG's
|
|
53
|
+
subset still applies: an SVG whose only artwork comes from `<filter>`
|
|
54
|
+
(`feTurbulence`, …) decodes and lays out, but the filter itself is ignored.
|
|
46
55
|
|
|
47
56
|
Document CSS styles the `<svg>` **box** — size, margins, background, borders,
|
|
48
57
|
`transform`, opacity, `display` — exactly as it styles any other element. The
|
|
@@ -55,8 +64,8 @@ renderer caches one texture per markup-and-size pair, so a program that rewrites
|
|
|
55
64
|
its artwork every frame keeps a texture per variant; prefer animating the box
|
|
56
65
|
(`transform`, `opacity`) or swapping between a small set of documents.
|
|
57
66
|
|
|
58
|
-
Still to do for images:
|
|
59
|
-
`
|
|
67
|
+
Still to do for images: `object-fit` and 9-slice borders. (CSS
|
|
68
|
+
`background-image: url(...)` and `data:` URLs are supported.)
|
|
60
69
|
|
|
61
70
|
Both kinds of SVG share NanoSVG's subset: `path`, `rect`, `circle`, `ellipse`,
|
|
62
71
|
`line`, `polyline`, `polygon`, groups (`g`), `defs` with linear/radial gradients
|
package/doc/gui/rendering.md
CHANGED
|
@@ -15,12 +15,14 @@ up to two indices into the display list's triangulated `clip-path` polygons, so
|
|
|
15
15
|
`overflow`/`clip-path` clipping and `z-index` ordering survive into the renderer.
|
|
16
16
|
`DisplayList::dump()` feeds `paintList()`/`paintCount()`.
|
|
17
17
|
|
|
18
|
-
`opacity`
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
`opacity` multiplies the alpha of every colour painted by the box and its
|
|
19
|
+
descendants (the values multiply down the paint chain), so fractional opacity and
|
|
20
|
+
the `opacity` transitions the CSS parser accepts are visible. It is a
|
|
21
|
+
per-shape approximation, not an offscreen group: overlapping children of a
|
|
22
|
+
translucent box composite individually, whereas a browser composes the group
|
|
23
|
+
once and then applies the alpha. `opacity: 0` still skips the whole subtree.
|
|
24
|
+
Hiding and revealing a layer with `opacity: 0` on the hidden state is what
|
|
25
|
+
`examples/gui/pelican-bike`'s game-over overlay does.
|
|
24
26
|
|
|
25
27
|
`runtime/ext_gui/renderer.{h,cpp}` turns that list into batched vertex buffers
|
|
26
28
|
per window (shapes, glyph quads and images) and merges consecutive ops that
|
|
@@ -80,14 +82,23 @@ The window background (`setBackground`) is the render-pass clear colour.
|
|
|
80
82
|
comma-separated layer list is painted bottom-up (the first declaration layer is
|
|
81
83
|
topmost), and both gradient kinds are supported:
|
|
82
84
|
|
|
83
|
-
- a **linear** gradient is sampled at 18 points
|
|
84
|
-
`to <side>`, `deg`/`grad`/`rad`/`turn`, percentage
|
|
85
|
-
(
|
|
86
|
-
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
85
|
+
- a **linear** gradient is sampled at 18 points (64 when repeating) and emitted
|
|
86
|
+
as solid rectangles; `to <side>`, `deg`/`grad`/`rad`/`turn`, percentage or
|
|
87
|
+
length (`px`/`em`/…) offsets, the `color <start> <end>` shorthand and
|
|
88
|
+
multi-stop colours work (the band walk is axis-aligned, so an oblique angle
|
|
89
|
+
uses the nearest axis);
|
|
90
|
+
- a **radial** gradient is 32 concentric ellipses (64 when repeating). Each is a
|
|
91
|
+
unit-radius rounded rectangle mapped through the shape pipeline's transform
|
|
92
|
+
slot, so a circle or ellipse keeps the distance-field antialiasing.
|
|
93
|
+
Shape/size keywords (`circle`/`ellipse`, `closest-side`/`farthest-side`/
|
|
94
|
+
`closest-corner`/`farthest-corner`, explicit radii) and `at <position>` are
|
|
95
|
+
parsed.
|
|
96
|
+
|
|
97
|
+
`repeating-linear-gradient()` and `repeating-radial-gradient()` tile the stop
|
|
98
|
+
pattern from 0 to the last stop's offset across the whole box; the stop list is
|
|
99
|
+
not forced to end at 100%, so `red 0%, blue 10%` repeats every 10%. A normal
|
|
100
|
+
gradient whose last stop is below 100% holds that colour for the rest of the box,
|
|
101
|
+
as in CSS.
|
|
91
102
|
|
|
92
103
|
The background colour sits under every layer. Gradients are partially
|
|
93
104
|
transparent if their stops are, and the band approximation can show banding and
|
|
@@ -117,10 +128,24 @@ nesting keeps the outermost two.
|
|
|
117
128
|
colour, so a box and its descendants see the filter. `blur()` and
|
|
118
129
|
`drop-shadow()` are approximations at the display-list level: blur spreads nine
|
|
119
130
|
translucent copies per shape, drop-shadow is a box/text silhouette. This keeps
|
|
120
|
-
the
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
131
|
+
the ordinary painter single-pass at the cost of group semantics: overlapping
|
|
132
|
+
descendants of a blurred/filtered group can darken, and `backdrop-filter` cannot
|
|
133
|
+
sample what is behind the element, so it parses and cascades but paints nothing.
|
|
134
|
+
|
|
135
|
+
**`mix-blend-mode`** is the exception that does need an offscreen layer. A box
|
|
136
|
+
with a non-`normal` mode is wrapped in `LayerBegin`/`LayerEnd` markers (visible
|
|
137
|
+
in `paintList()` as `layer blend=…` / `end-layer`); the renderer draws that group
|
|
138
|
+
to a full-viewport offscreen texture and composites it over the scene with a
|
|
139
|
+
small GLSL blend shader. All sixteen CSS modes (`multiply`, `screen`, `overlay`,
|
|
140
|
+
`darken`, `lighten`, `color-dodge`, `color-burn`, `hard-light`, `soft-light`,
|
|
141
|
+
`difference`, `exclusion`, `hue`, `saturation`, `color`, `luminosity`) are
|
|
142
|
+
implemented with the compositing-spec formulas. The shader is compiled at run
|
|
143
|
+
time by the bundled glslang (SPIR-V for Vulkan) and cross-compiled to MSL by
|
|
144
|
+
SPIRV-Cross (Metal); the two scene textures per nesting level are reused across
|
|
145
|
+
frames and ping-pong so the backdrop stays sampleable while it is written.
|
|
146
|
+
Backends that consume neither format — the D3D12/DXIL path, which has no shader
|
|
147
|
+
compiler here — keep painting the group with ordinary source-over blending.
|
|
148
|
+
`backdrop-filter` still paints nothing.
|
|
124
149
|
|
|
125
150
|
## Text stack (M4b)
|
|
126
151
|
|
package/doc/gui.md
CHANGED
|
@@ -40,10 +40,11 @@ them) can be translated, scaled and rotated without reflowing anything — and
|
|
|
40
40
|
[Animation](./gui/animation.md#css-transforms-m15).
|
|
41
41
|
**M17** adds real **WebGL 1.0**, and **M18** adds **WebGL 2.0**: `<canvas>.getContext("webgl2")` accepts `#version 300 es` shaders, vertex-array objects, instanced draws and sampler objects, all compiled to SPIR-V by the bundled glslang (and to MSL by the bundled SPIRV-Cross on Metal) and rendered through SDL_GPU. Geometry, lighting, texture sampling and blending run on the GPU and the page composites the colour texture without a readback — see [WebGL](./gui/webgl.md).
|
|
42
42
|
**M19** fills in the decorative CSS layer: `@media` queries, generated content
|
|
43
|
-
(`::before`/`::after`), multi-layer linear/radial backgrounds,
|
|
44
|
-
`clip-path
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
(`::before`/`::after`), multi-layer linear/radial/repeating backgrounds,
|
|
44
|
+
`text-shadow`, `clip-path`, `mix-blend-mode` (through an offscreen compositor)
|
|
45
|
+
and the `filter` colour/shadow effects. `backdrop-filter` still needs a backdrop
|
|
46
|
+
snapshot, and true group blur remains an approximation — see
|
|
47
|
+
[Rendering](./gui/rendering.md#backgrounds-generated-content-and-effects-m19).
|
|
47
48
|
**M20** makes large documents interactive: `@media` is evaluated once per rule,
|
|
48
49
|
layout and paint share a bounded shaping cache, and a frame only does (and
|
|
49
50
|
presents) the work a change requires — see
|