xbintsc 0.5.41 → 0.5.43
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 +144 -4
- 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/api.md +1 -1
- package/doc/gui/canvas.md +6 -2
- package/doc/gui/known-issues.md +18 -10
- package/doc/gui/media.md +11 -2
- package/doc/gui/rendering.md +48 -19
- package/doc/gui.md +12 -8
- package/doc/zh-CN/gui/api.md +1 -1
- package/doc/zh-CN/gui/canvas.md +6 -4
- package/doc/zh-CN/gui/known-issues.md +12 -8
- package/doc/zh-CN/gui/media.md +9 -2
- package/doc/zh-CN/gui/rendering.md +37 -15
- package/doc/zh-CN/gui.md +7 -6
- 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 +69 -4
- package/runtime/ext_gui/paint.h +57 -1
- package/runtime/ext_gui/paint_background.cpp +197 -41
- 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_gradient.cpp +156 -0
- package/runtime/ext_gui/renderer_image.cpp +6 -1
- package/runtime/ext_gui/renderer_internal.h +48 -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.43 - 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.43";
|
|
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"}
|
|
@@ -130,13 +130,153 @@ describe.skipIf(!guiAvailable)("gui extension — effects", () => {
|
|
|
130
130
|
const list = stdout.slice(stdout.indexOf("list-start"), stdout.indexOf("list-end"));
|
|
131
131
|
expect(value("image")).toContain("radial-gradient()");
|
|
132
132
|
expect(value("image")).toContain("linear-gradient()");
|
|
133
|
-
//
|
|
134
|
-
//
|
|
133
|
+
// The radial layer is one rasterised gradient carrying its stops; the linear
|
|
134
|
+
// layer is still painted as solid bands.
|
|
135
|
+
expect(list).toContain("gradient=radial");
|
|
135
136
|
expect(list).toContain("#ff0000ff");
|
|
136
137
|
expect(list).toContain("#00ff00ff");
|
|
137
138
|
expect(list).toMatch(/#0000[0-9a-f]{2}ff/);
|
|
138
|
-
//
|
|
139
|
-
|
|
139
|
+
// Eighteen linear strips plus the background colour: the gradient image is
|
|
140
|
+
// not a stack of rectangles.
|
|
141
|
+
expect(Number(value("count"))).toBe(19);
|
|
142
|
+
});
|
|
143
|
+
it("rasterises a translucent radial vignette as one gradient image", () => {
|
|
144
|
+
const { value, stdout } = harness.compileAndRun("vignette", `
|
|
145
|
+
import { createWindow, run } from "gui";
|
|
146
|
+
|
|
147
|
+
const HTML = \`
|
|
148
|
+
<html><head><style>
|
|
149
|
+
body { margin: 0; }
|
|
150
|
+
#scene { position: relative; width: 200px; height: 100px; background: #3366cc; }
|
|
151
|
+
#dim {
|
|
152
|
+
position: absolute; inset: -5%; z-index: 2; pointer-events: none;
|
|
153
|
+
background: radial-gradient(ellipse at center,
|
|
154
|
+
transparent 45%, rgba(0, 0, 0, 0.46) 76%, rgba(0, 0, 0, 0.88) 100%);
|
|
155
|
+
}
|
|
156
|
+
</style></head><body>
|
|
157
|
+
<div id="scene"><div id="dim"></div></div>
|
|
158
|
+
</body></html>
|
|
159
|
+
\`;
|
|
160
|
+
|
|
161
|
+
const win = createWindow({ title: "vignette", width: 400, height: 300 });
|
|
162
|
+
win.on("ready", () => {
|
|
163
|
+
console.log("image=" + win.computedStyle("#dim", "background-image"));
|
|
164
|
+
console.log("count=" + win.paintCount());
|
|
165
|
+
console.log("list-start");
|
|
166
|
+
console.log(win.paintList());
|
|
167
|
+
console.log("list-end");
|
|
168
|
+
win.close();
|
|
169
|
+
});
|
|
170
|
+
win.loadHTML(HTML);
|
|
171
|
+
run();
|
|
172
|
+
`);
|
|
173
|
+
const list = stdout.slice(stdout.indexOf("list-start"), stdout.indexOf("list-end"));
|
|
174
|
+
expect(value("image")).toContain("radial-gradient()");
|
|
175
|
+
// A single op whose stops keep the alpha ramp. Painting this as nested
|
|
176
|
+
// translucent ellipses composited the alpha once per band and turned the
|
|
177
|
+
// whole scene solid black.
|
|
178
|
+
expect((list.match(/gradient=radial/g) ?? []).length).toBe(1);
|
|
179
|
+
expect(list).toContain("#00000000@0.4500");
|
|
180
|
+
expect(list).toContain("#000000e0@1.0000");
|
|
181
|
+
// Only the scene background is a rectangle; the vignette is not bands.
|
|
182
|
+
expect(value("count")).toBe("1");
|
|
183
|
+
});
|
|
184
|
+
it("tiles repeating gradients across the whole box", () => {
|
|
185
|
+
const { value, stdout } = harness.compileAndRun("repeating-gradient", `
|
|
186
|
+
import { createWindow, run } from "gui";
|
|
187
|
+
|
|
188
|
+
const HTML = \`
|
|
189
|
+
<html><head><style>
|
|
190
|
+
body { margin: 0; }
|
|
191
|
+
#r {
|
|
192
|
+
width: 100px; height: 40px;
|
|
193
|
+
background: repeating-linear-gradient(90deg,
|
|
194
|
+
#ff0000 0%, #ff0000 10%, #0000ff 10%, #0000ff 20%);
|
|
195
|
+
}
|
|
196
|
+
</style></head><body><div id="r"></div></body></html>
|
|
197
|
+
\`;
|
|
198
|
+
|
|
199
|
+
const win = createWindow({ title: "repeating-gradient", width: 400, height: 300 });
|
|
200
|
+
win.on("ready", () => {
|
|
201
|
+
console.log("image=" + win.computedStyle("#r", "background-image"));
|
|
202
|
+
console.log("list-start");
|
|
203
|
+
console.log(win.paintList());
|
|
204
|
+
console.log("list-end");
|
|
205
|
+
win.close();
|
|
206
|
+
});
|
|
207
|
+
win.loadHTML(HTML);
|
|
208
|
+
run();
|
|
209
|
+
`);
|
|
210
|
+
const list = stdout.slice(stdout.indexOf("list-start"), stdout.indexOf("list-end"));
|
|
211
|
+
// The computed value keeps the repeating function name ...
|
|
212
|
+
expect(value("image")).toBe("repeating-linear-gradient()");
|
|
213
|
+
// ... and the whole 100px box is tiled: a 20% period gives five red and
|
|
214
|
+
// five blue bands, not one ramp that holds the final colour.
|
|
215
|
+
expect((list.match(/#ff0000ff/g) ?? []).length).toBeGreaterThan(4);
|
|
216
|
+
expect((list.match(/#0000ffff/g) ?? []).length).toBeGreaterThan(4);
|
|
217
|
+
});
|
|
218
|
+
it("resolves pixel offsets in repeating gradients", () => {
|
|
219
|
+
const { value, stdout } = harness.compileAndRun("repeating-gradient-px", `
|
|
220
|
+
import { createWindow, run } from "gui";
|
|
221
|
+
|
|
222
|
+
const HTML = \`
|
|
223
|
+
<html><head><style>
|
|
224
|
+
body { margin: 0; }
|
|
225
|
+
#r {
|
|
226
|
+
width: 100px; height: 20px;
|
|
227
|
+
background: repeating-linear-gradient(90deg,
|
|
228
|
+
#123456 0px 10px, #abcdef 10px 20px);
|
|
229
|
+
}
|
|
230
|
+
</style></head><body><div id="r"></div></body></html>
|
|
231
|
+
\`;
|
|
232
|
+
|
|
233
|
+
const win = createWindow({ title: "repeating-gradient-px", width: 400, height: 300 });
|
|
234
|
+
win.on("ready", () => {
|
|
235
|
+
console.log("image=" + win.computedStyle("#r", "background-image"));
|
|
236
|
+
console.log("list-start");
|
|
237
|
+
console.log(win.paintList());
|
|
238
|
+
console.log("list-end");
|
|
239
|
+
win.close();
|
|
240
|
+
});
|
|
241
|
+
win.loadHTML(HTML);
|
|
242
|
+
run();
|
|
243
|
+
`);
|
|
244
|
+
const list = stdout.slice(stdout.indexOf("list-start"), stdout.indexOf("list-end"));
|
|
245
|
+
expect(value("image")).toBe("repeating-linear-gradient()");
|
|
246
|
+
expect((list.match(/#123456ff/g) ?? []).length).toBeGreaterThan(4);
|
|
247
|
+
expect((list.match(/#abcdefff/g) ?? []).length).toBeGreaterThan(4);
|
|
248
|
+
});
|
|
249
|
+
it("tiles repeating radial gradients", () => {
|
|
250
|
+
const { value, stdout } = harness.compileAndRun("repeating-radial-gradient", `
|
|
251
|
+
import { createWindow, run } from "gui";
|
|
252
|
+
|
|
253
|
+
const HTML = \`
|
|
254
|
+
<html><head><style>
|
|
255
|
+
body { margin: 0; }
|
|
256
|
+
#r {
|
|
257
|
+
width: 40px; height: 40px;
|
|
258
|
+
background: repeating-radial-gradient(circle at 50% 50%,
|
|
259
|
+
#ff0000 0%, #ff0000 5%, #0000ff 5%, #0000ff 10%);
|
|
260
|
+
}
|
|
261
|
+
</style></head><body><div id="r"></div></body></html>
|
|
262
|
+
\`;
|
|
263
|
+
|
|
264
|
+
const win = createWindow({ title: "repeating-radial-gradient", width: 400, height: 300 });
|
|
265
|
+
win.on("ready", () => {
|
|
266
|
+
console.log("image=" + win.computedStyle("#r", "background-image"));
|
|
267
|
+
console.log("list-start");
|
|
268
|
+
console.log(win.paintList());
|
|
269
|
+
console.log("list-end");
|
|
270
|
+
win.close();
|
|
271
|
+
});
|
|
272
|
+
win.loadHTML(HTML);
|
|
273
|
+
run();
|
|
274
|
+
`);
|
|
275
|
+
const list = stdout.slice(stdout.indexOf("list-start"), stdout.indexOf("list-end"));
|
|
276
|
+
expect(value("image")).toBe("repeating-radial-gradient()");
|
|
277
|
+
expect(list).toContain("gradient=repeating-radial");
|
|
278
|
+
expect(list).toContain("#ff0000ff");
|
|
279
|
+
expect(list).toContain("#0000ffff");
|
|
140
280
|
});
|
|
141
281
|
it("paints text-shadow copies behind the text", () => {
|
|
142
282
|
const { value, stdout } = harness.compileAndRun("text-shadow", `
|
|
@@ -1 +1 @@
|
|
|
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,
|
|
1
|
+
{"version":3,"file":"gui-effects.test.js","sourceRoot":"","sources":["../../../tests/e2e/gui-effects.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -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/api.md
CHANGED
|
@@ -187,7 +187,7 @@ win.queryCount(selector) // number of matching elements
|
|
|
187
187
|
win.getBoundingClientRect(selector) // { x, y, width, height } (border box, transformed)
|
|
188
188
|
win.documentTree() // serialized DOM (debugging)
|
|
189
189
|
win.layoutTree() // serialized layout boxes (debugging)
|
|
190
|
-
win.paintCount() // number of
|
|
190
|
+
win.paintCount() // number of filled rectangles in the display list
|
|
191
191
|
win.paintList() // serialized display list (debugging)
|
|
192
192
|
win.inlineSvg(selector) // serialized inline <svg>: { markup, width, height, shapes }
|
|
193
193
|
win.measureText(text, fontSize?, family?) // shaped advance width in pixels
|
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,24 @@
|
|
|
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
|
-
textures are sampled nearest-neighbour.
|
|
72
|
-
bands (18
|
|
73
|
-
|
|
75
|
+
textures are sampled nearest-neighbour. A background linear gradient remains
|
|
76
|
+
solid bands (18 strips, 64 while repeating), so a large soft ramp may show
|
|
77
|
+
slight banding; a radial gradient is rasterised per pixel into a texture
|
|
78
|
+
(capped at 1024 px per edge, then stretched, so a hard stop in a very large
|
|
79
|
+
box comes out slightly soft).
|
|
74
80
|
- **SVG is NanoSVG's subset.** SVG *files* (`<img src="logo.svg">`) and inline
|
|
75
81
|
`<svg>` trees share the vendored NanoSVG parser/rasteriser
|
|
76
82
|
(`runtime/ext_gui/svg.cpp`, `inline_svg.cpp`), which renders
|
|
@@ -78,9 +84,11 @@
|
|
|
78
84
|
gradients and class-based `<style>` rules. `<text>`, `<use>`, filters, masks
|
|
79
85
|
and clip paths are not rendered, and CSS applied by the document cascade does
|
|
80
86
|
not reach inside the artwork (fill/stroke are SVG presentation attributes,
|
|
81
|
-
not CSS properties here).
|
|
82
|
-
|
|
83
|
-
|
|
87
|
+
not CSS properties here). An SVG whose only artwork comes from a filter
|
|
88
|
+
(`feTurbulence` noise, blur, …) therefore shows the unfiltered shapes — often
|
|
89
|
+
a solid rect — rather than the filter result. Vector art that needs those has
|
|
90
|
+
to be rasterised beforehand, drawn from boxes, or restricted to the supported
|
|
91
|
+
syntax. See [Media](./media.md#images-m6a).
|
|
84
92
|
- **Rendering is still whole-document per change.** A DOM mutation recomputes
|
|
85
93
|
the cascade and lays out the complete document again (there is no incremental
|
|
86
94
|
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
|