stroke-outline 0.0.0-stage → 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Yuki Kishino
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,97 @@
1
- # Temporary Holding Version
1
+ # stroke-outline
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Turn vector paths into the filled outline of their stroke — the geometry a
4
+ canvas draws for `stroke()`, returned as a path you can fill, cache, hit-test
5
+ or tessellate. A WebAssembly build of a C++ library; works in browsers, workers
6
+ and Node.
7
+
8
+ ```js
9
+ import { init } from 'stroke-outline';
10
+
11
+ const so = await init(); // loads the WASM once; reuse the result
12
+
13
+ // stroke SVG path data
14
+ const outline = so.buildOutline('M 10 10 H 90 A 20 20 0 0 1 90 50', { lineWidth: 8, lineCap: 'round' });
15
+ outline.toSVG(); // SVG path data — <path d>, new Path2D(...), a file
16
+ outline.commands; // [{ type: 'moveTo', x, y }, { type: 'cubicTo', c1x, ... }, ...]
17
+ outline.error; // null, or { message } if the SVG data was malformed
18
+
19
+ // parse SVG once, then stroke it as often as you like
20
+ const icon = so.pathFromSVG('M 0 0 H 100 V 100 H 0 Z M 30 30 V 70 H 70 V 30 Z');
21
+ const thin = so.buildOutline(icon, { lineWidth: 2 });
22
+ const thick = so.buildOutline(icon, { lineWidth: 12, align: 'inside' });
23
+ thinEl.setAttribute('d', thin.toSVG());
24
+ thickEl.setAttribute('d', thick.toSVG());
25
+
26
+ // or build paths in code
27
+ const path = new so.Path().moveTo(0, 0).lineTo(100, 0).arcTo(30, 30, 0, false, true, 100, 60);
28
+ const dashed = so.buildOutline(path, { lineWidth: 6, align: 'inside', dash: [12, 6] });
29
+ ctx.fill(new Path2D(dashed.toSVG())); // each dash is its own subpath
30
+ ```
31
+
32
+ **Fill outlines with the nonzero rule** (the default for canvas `fill()` and
33
+ SVG). Outlines may overlap themselves; nonzero renders that correctly. With
34
+ `clipToShape: true`, closed paths come out as simple contours that also fill
35
+ correctly with even-odd.
36
+
37
+ ## API
38
+
39
+ - `init()` → `Promise<StrokeOutline>`. Loads the WASM module; call it once and
40
+ reuse the result.
41
+ - `so.buildOutline(pathOrSvg, options?)` → the outline as a `Path`. Takes a `Path` or
42
+ SVG path data; malformed data is stroked up to the first error, and the
43
+ outline's `error` says why (as for `pathFromSVG`, below).
44
+ - `new so.Path()` with `moveTo`, `lineTo`, `quadTo`, `cubicTo`,
45
+ `arcTo(rx, ry, xAxisRotationDeg, largeArc, sweep, x, y)` and `close`, all
46
+ chainable; `.commands` and `.toSVG(precision = 3)`.
47
+ - `so.pathFromSVG(d)` → `Path`. Malformed path data keeps everything before
48
+ the first error (as SVG renders it), and `path.error` is
49
+ `{ message }`, saying what went wrong and where
50
+ (`'expected a number at position 11'`, an index into `d`). `error` is `null`
51
+ for valid data and for paths built in code. Use it to parse once and stroke
52
+ many times, or to read the input's commands.
53
+ - `precision` is a minimum number of decimals; small paths get more, so
54
+ rounding stays within ~1e-4 of their size.
55
+ - `so.module` is the raw Embind module, for anything not wrapped here.
56
+
57
+ Nothing needs freeing: the wrapper releases every WASM-side object itself.
58
+
59
+ ### Options
60
+
61
+ All optional; omitted ones take these defaults.
62
+
63
+ | Option | Default | |
64
+ | --- | --- | --- |
65
+ | `lineWidth` | `1` | must be a positive finite number, else nothing is stroked |
66
+ | `lineJoin` | `'miter'` | `'miter'`, `'bevel'`, `'round'` |
67
+ | `lineCap` | `'butt'` | `'butt'`, `'square'`, `'round'` |
68
+ | `miterLimit` | `4` | below 1 behaves as 1 (always bevel) |
69
+ | `align` | `'center'` | `'center'`, `'inside'`, `'outside'` — closed subpaths, relative to the whole fill (holes included) |
70
+ | `fillRule` | `'nonzero'` | `'nonzero'`, `'evenodd'` — how subpaths form the fill, for `align` and `clipToShape` |
71
+ | `clipToShape` | `false` | resolve over-wide or overlapping strokes into simple contours |
72
+ | `dash` | none | e.g. `[10, 5]`; `[0, gap]` with round caps draws dots |
73
+ | `dashOffset` | `0` | |
74
+
75
+ An unknown option value (e.g. `lineJoin: 'rounded'`) throws a `TypeError`.
76
+
77
+ ## Bundlers
78
+
79
+ The WebAssembly binary is embedded in the package's JavaScript, so there is no
80
+ `.wasm` file to serve or configure: it works as is in Vite (dev and build),
81
+ webpack, Rollup, esbuild and Node.
82
+
83
+ ## Building from source
84
+
85
+ ```sh
86
+ # from the repository root: build the WASM module (publishes it into js/src/wasm)
87
+ cmake --preset wasm && cmake --build --preset wasm-release
88
+ cd js
89
+ npm install
90
+ npm test # builds dist/ and runs the tests in Node
91
+ npm pack # the tarball that would be published
92
+ ```
93
+
94
+ ## License
95
+
96
+ MIT — see `LICENSE`. Includes code ported from svg-arc-to-cubic-bezier
97
+ (Colin Meinke, ISC license); see `THIRD_PARTY_NOTICES`.
@@ -0,0 +1,29 @@
1
+ Third-party notices
2
+ ===================
3
+
4
+ This project includes code derived from the following third-party software.
5
+
6
+ -------------------------------------------------------------------------------
7
+ svg-arc-to-cubic-bezier
8
+ https://github.com/colinmeinke/svg-arc-to-cubic-bezier
9
+
10
+ Used in: src/io/svg_arc.cpp (SVG elliptical arc to cubic bézier conversion),
11
+ ported to C++. Also compiled into the WebAssembly module.
12
+
13
+ Internet Systems Consortium license
14
+ ===================================
15
+
16
+ Copyright (c) `2017`, `Colin Meinke`
17
+
18
+ Permission to use, copy, modify, and/or distribute this software for any purpose
19
+ with or without fee is hereby granted, provided that the above copyright notice
20
+ and this permission notice appear in all copies.
21
+
22
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
23
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
24
+ FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
25
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
26
+ OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27
+ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
28
+ THIS SOFTWARE.
29
+ -------------------------------------------------------------------------------
@@ -0,0 +1,102 @@
1
+ import type { MainModule } from './wasm/stroke_outline.js';
2
+ export type LineJoin = 'miter' | 'bevel' | 'round';
3
+ export type LineCap = 'butt' | 'square' | 'round';
4
+ export type StrokeAlign = 'center' | 'inside' | 'outside';
5
+ export type FillRule = 'nonzero' | 'evenodd';
6
+ export interface StrokeOptions {
7
+ /** Stroke width; must be a positive finite number. Default 1. */
8
+ lineWidth?: number;
9
+ /** Default 'miter'. */
10
+ lineJoin?: LineJoin;
11
+ /** Default 'butt'. */
12
+ lineCap?: LineCap;
13
+ /** Miter length / line width beyond which a miter is beveled. Default 4. */
14
+ miterLimit?: number;
15
+ /** Inside/outside apply to closed subpaths, relative to the whole fill. Default 'center'. */
16
+ align?: StrokeAlign;
17
+ /** How subpaths combine into a fill (for align and clipToShape). Default 'nonzero'. */
18
+ fillRule?: FillRule;
19
+ /** Resolve over-wide/overlapping strokes into simple contours. Default false. */
20
+ clipToShape?: boolean;
21
+ /** Dash pattern, e.g. [10, 5]. Empty or omitted: solid. [0, gap] with round caps: dots. */
22
+ dash?: number[];
23
+ /** Where the dash pattern starts. Default 0. */
24
+ dashOffset?: number;
25
+ }
26
+ /** One path command; coordinates are absolute. */
27
+ export type PathCommand = {
28
+ type: 'moveTo';
29
+ x: number;
30
+ y: number;
31
+ } | {
32
+ type: 'lineTo';
33
+ x: number;
34
+ y: number;
35
+ } | {
36
+ type: 'quadTo';
37
+ cx: number;
38
+ cy: number;
39
+ x: number;
40
+ y: number;
41
+ } | {
42
+ type: 'cubicTo';
43
+ c1x: number;
44
+ c1y: number;
45
+ c2x: number;
46
+ c2y: number;
47
+ x: number;
48
+ y: number;
49
+ } | {
50
+ type: 'close';
51
+ };
52
+ /** Why SVG path data stopped parsing. */
53
+ export interface SvgError {
54
+ /**
55
+ * What went wrong, and where (an index into the string):
56
+ * `'expected a number at position 11'`, or, when the data ends too early,
57
+ * `'expected a number at position 10 (end of data)'`.
58
+ */
59
+ message: string;
60
+ }
61
+ export interface Path {
62
+ moveTo(x: number, y: number): Path;
63
+ lineTo(x: number, y: number): Path;
64
+ quadTo(cx: number, cy: number, x: number, y: number): Path;
65
+ cubicTo(c1x: number, c1y: number, c2x: number, c2y: number, x: number, y: number): Path;
66
+ /** SVG elliptical arc to (x, y), expanded to cubics. */
67
+ arcTo(rx: number, ry: number, xAxisRotationDeg: number, largeArc: boolean, sweep: boolean, x: number, y: number): Path;
68
+ close(): Path;
69
+ /** The commands so far (absolute coordinates). */
70
+ readonly commands: readonly PathCommand[];
71
+ /**
72
+ * For a path parsed from malformed SVG data, or the outline of one: why and
73
+ * where parsing stopped (the path holds everything before it, as SVG
74
+ * renders it). Otherwise null.
75
+ */
76
+ readonly error: SvgError | null;
77
+ /** SVG path data; `precision` is the minimum number of decimals (default 3). */
78
+ toSVG(precision?: number): string;
79
+ }
80
+ export interface StrokeOutline {
81
+ /** A new, empty path. */
82
+ Path: new () => Path;
83
+ /**
84
+ * Parse SVG path data. Malformed data keeps everything before the first
85
+ * error, as SVG renders it; `path.error` says whether, why and where.
86
+ */
87
+ pathFromSVG(d: string): Path;
88
+ /**
89
+ * Stroke a path, or SVG path data; returns the outline as a new path (fill
90
+ * it with nonzero). Malformed SVG data is stroked up to the first error, as
91
+ * SVG renders it, and the outline's `error` says why and where.
92
+ */
93
+ buildOutline(path: Path | string, options?: StrokeOptions): Path;
94
+ /** The underlying Embind module, for anything not wrapped here. */
95
+ readonly module: MainModule;
96
+ }
97
+ /**
98
+ * Load the WASM module and return the API. Call once and reuse the result.
99
+ * The WebAssembly binary is embedded in the package, so there is no file to
100
+ * serve or locate.
101
+ */
102
+ export declare function init(): Promise<StrokeOutline>;
package/dist/index.js ADDED
@@ -0,0 +1,212 @@
1
+ // The stroke-outline JavaScript API: a thin, typed wrapper over the WASM module.
2
+ //
3
+ // import { init } from 'stroke-outline';
4
+ // const so = await init();
5
+ // const outline = so.buildOutline('M 0 0 L 100 0', { lineWidth: 8, lineCap: 'round' });
6
+ // ctx.fill(new Path2D(outline.toSVG()));
7
+ //
8
+ // Options are partial: anything omitted takes the C++ default. Nothing here
9
+ // needs freeing; the wrapper releases every WASM-side object itself.
10
+ import createModule from './wasm/stroke_outline.js';
11
+ /**
12
+ * Load the WASM module and return the API. Call once and reuse the result.
13
+ * The WebAssembly binary is embedded in the package, so there is no file to
14
+ * serve or locate.
15
+ */
16
+ export async function init() {
17
+ return createApi(await createModule());
18
+ }
19
+ function createApi(module) {
20
+ const ZERO = { x: 0, y: 0 };
21
+ const joins = { miter: module.LineJoin.Miter, bevel: module.LineJoin.Bevel, round: module.LineJoin.Round };
22
+ const caps = { butt: module.LineCap.Butt, square: module.LineCap.Square, round: module.LineCap.Round };
23
+ const aligns = {
24
+ center: module.StrokeAlign.Center,
25
+ inside: module.StrokeAlign.Inside,
26
+ outside: module.StrokeAlign.Outside,
27
+ };
28
+ const fillRules = { nonzero: module.FillRule.NonZero, evenodd: module.FillRule.EvenOdd };
29
+ function pick(table, value, name, fallback) {
30
+ if (value === undefined)
31
+ return fallback;
32
+ if (!(value in table))
33
+ throw new TypeError(`stroke-outline: unknown ${name} '${value}'`);
34
+ return table[value];
35
+ }
36
+ function settings(options = {}) {
37
+ const d = module.defaultStrokeSettings();
38
+ return {
39
+ lineWidth: options.lineWidth ?? d.lineWidth,
40
+ lineJoin: pick(joins, options.lineJoin, 'lineJoin', d.lineJoin),
41
+ lineCap: pick(caps, options.lineCap, 'lineCap', d.lineCap),
42
+ miterLimit: options.miterLimit ?? d.miterLimit,
43
+ align: pick(aligns, options.align, 'align', d.align),
44
+ fillRule: pick(fillRules, options.fillRule, 'fillRule', d.fillRule),
45
+ clipToShape: options.clipToShape ?? d.clipToShape,
46
+ dashPattern: options.dash ?? d.dashPattern,
47
+ dashOffset: options.dashOffset ?? d.dashOffset,
48
+ };
49
+ }
50
+ function toWasm(commands) {
51
+ const vec = new module.PathCommandVector();
52
+ for (const c of commands) {
53
+ let command;
54
+ switch (c.type) {
55
+ case 'moveTo':
56
+ command = { verb: module.Verb.MoveTo, ctrl1: ZERO, ctrl2: ZERO, to: { x: c.x, y: c.y } };
57
+ break;
58
+ case 'lineTo':
59
+ command = { verb: module.Verb.LineTo, ctrl1: ZERO, ctrl2: ZERO, to: { x: c.x, y: c.y } };
60
+ break;
61
+ case 'quadTo':
62
+ command = {
63
+ verb: module.Verb.QuadraticTo,
64
+ ctrl1: { x: c.cx, y: c.cy },
65
+ ctrl2: ZERO,
66
+ to: { x: c.x, y: c.y },
67
+ };
68
+ break;
69
+ case 'cubicTo':
70
+ command = {
71
+ verb: module.Verb.CubicTo,
72
+ ctrl1: { x: c.c1x, y: c.c1y },
73
+ ctrl2: { x: c.c2x, y: c.c2y },
74
+ to: { x: c.x, y: c.y },
75
+ };
76
+ break;
77
+ case 'close':
78
+ command = { verb: module.Verb.Close, ctrl1: ZERO, ctrl2: ZERO, to: ZERO };
79
+ break;
80
+ }
81
+ vec.push_back(command);
82
+ }
83
+ return vec;
84
+ }
85
+ // Read a vector into plain commands and free it.
86
+ function fromWasm(vec) {
87
+ try {
88
+ const out = [];
89
+ for (let i = 0; i < vec.size(); i++) {
90
+ const c = vec.get(i);
91
+ switch (c.verb.value) {
92
+ case module.Verb.MoveTo.value:
93
+ out.push({ type: 'moveTo', x: c.to.x, y: c.to.y });
94
+ break;
95
+ case module.Verb.LineTo.value:
96
+ out.push({ type: 'lineTo', x: c.to.x, y: c.to.y });
97
+ break;
98
+ case module.Verb.QuadraticTo.value:
99
+ out.push({ type: 'quadTo', cx: c.ctrl1.x, cy: c.ctrl1.y, x: c.to.x, y: c.to.y });
100
+ break;
101
+ case module.Verb.CubicTo.value:
102
+ out.push({
103
+ type: 'cubicTo',
104
+ c1x: c.ctrl1.x,
105
+ c1y: c.ctrl1.y,
106
+ c2x: c.ctrl2.x,
107
+ c2y: c.ctrl2.y,
108
+ x: c.to.x,
109
+ y: c.to.y,
110
+ });
111
+ break;
112
+ case module.Verb.Close.value:
113
+ out.push({ type: 'close' });
114
+ break;
115
+ }
116
+ }
117
+ return out;
118
+ }
119
+ finally {
120
+ vec.delete();
121
+ }
122
+ }
123
+ function withWasm(commands, use) {
124
+ const vec = toWasm(commands);
125
+ try {
126
+ return use(vec);
127
+ }
128
+ finally {
129
+ vec.delete();
130
+ }
131
+ }
132
+ class PathImpl {
133
+ list = [];
134
+ // Current point and subpath start, for arcs and close.
135
+ x = 0;
136
+ y = 0;
137
+ startX = 0;
138
+ startY = 0;
139
+ error;
140
+ constructor(commands = [], error = null) {
141
+ for (const c of commands)
142
+ this.push(c);
143
+ this.error = error;
144
+ }
145
+ push(c) {
146
+ this.list.push(c);
147
+ if (c.type === 'close') {
148
+ this.x = this.startX;
149
+ this.y = this.startY;
150
+ }
151
+ else {
152
+ this.x = c.x;
153
+ this.y = c.y;
154
+ if (c.type === 'moveTo') {
155
+ this.startX = c.x;
156
+ this.startY = c.y;
157
+ }
158
+ }
159
+ return this;
160
+ }
161
+ get commands() {
162
+ return this.list;
163
+ }
164
+ moveTo(x, y) {
165
+ return this.push({ type: 'moveTo', x, y });
166
+ }
167
+ lineTo(x, y) {
168
+ return this.push({ type: 'lineTo', x, y });
169
+ }
170
+ quadTo(cx, cy, x, y) {
171
+ return this.push({ type: 'quadTo', cx, cy, x, y });
172
+ }
173
+ cubicTo(c1x, c1y, c2x, c2y, x, y) {
174
+ return this.push({ type: 'cubicTo', c1x, c1y, c2x, c2y, x, y });
175
+ }
176
+ arcTo(rx, ry, rotation, largeArc, sweep, x, y) {
177
+ // From the current point. A degenerate arc comes back as a straight line.
178
+ for (const c of fromWasm(module.arcToCommands(this.x, this.y, rx, ry, rotation, largeArc, sweep, x, y)))
179
+ this.push(c);
180
+ return this;
181
+ }
182
+ close() {
183
+ return this.push({ type: 'close' });
184
+ }
185
+ toSVG(precision = 3) {
186
+ return withWasm(this.list, vec => module.pathToSvg(vec, precision));
187
+ }
188
+ }
189
+ return {
190
+ Path: PathImpl,
191
+ pathFromSVG: d => {
192
+ const parsed = module.parseSvgPathChecked(d);
193
+ const error = parsed.ok ? null : { message: String(parsed.message) };
194
+ return new PathImpl(fromWasm(parsed.commands), error);
195
+ },
196
+ buildOutline: (path, options) => {
197
+ const s = settings(options);
198
+ if (typeof path !== 'string')
199
+ return new PathImpl(withWasm(path.commands, vec => fromWasm(module.buildStrokeOutline(vec, s))));
200
+ // SVG data: stroke the parsed commands where they are, in WASM memory.
201
+ const parsed = module.parseSvgPathChecked(path);
202
+ try {
203
+ const error = parsed.ok ? null : { message: String(parsed.message) };
204
+ return new PathImpl(fromWasm(module.buildStrokeOutline(parsed.commands, s)), error);
205
+ }
206
+ finally {
207
+ parsed.commands.delete();
208
+ }
209
+ },
210
+ module,
211
+ };
212
+ }
@@ -0,0 +1,96 @@
1
+ // TypeScript bindings for emscripten-generated code. Automatically generated at compile time.
2
+ interface WasmModule {
3
+ }
4
+
5
+ type EmbindString = ArrayBuffer|Uint8Array|Uint8ClampedArray|Int8Array|string;
6
+ export interface ClassHandle {
7
+ isAliasOf(other: ClassHandle): boolean;
8
+ delete(): void;
9
+ deleteLater(): this;
10
+ isDeleted(): boolean;
11
+ // @ts-ignore - If targeting lower than ESNext, this symbol might not exist.
12
+ [Symbol.dispose](): void;
13
+ clone(): this;
14
+ }
15
+ export type Vec2 = {
16
+ x: number,
17
+ y: number
18
+ };
19
+
20
+ export interface VerbValue<T extends number> {
21
+ value: T;
22
+ }
23
+ export type Verb = VerbValue<0>|VerbValue<1>|VerbValue<2>|VerbValue<3>|VerbValue<4>;
24
+
25
+ export interface LineJoinValue<T extends number> {
26
+ value: T;
27
+ }
28
+ export type LineJoin = LineJoinValue<0>|LineJoinValue<1>|LineJoinValue<2>;
29
+
30
+ export interface LineCapValue<T extends number> {
31
+ value: T;
32
+ }
33
+ export type LineCap = LineCapValue<0>|LineCapValue<1>|LineCapValue<2>;
34
+
35
+ export interface StrokeAlignValue<T extends number> {
36
+ value: T;
37
+ }
38
+ export type StrokeAlign = StrokeAlignValue<0>|StrokeAlignValue<1>|StrokeAlignValue<2>;
39
+
40
+ export interface FillRuleValue<T extends number> {
41
+ value: T;
42
+ }
43
+ export type FillRule = FillRuleValue<0>|FillRuleValue<1>;
44
+
45
+ export type PathCommand = {
46
+ verb: Verb,
47
+ ctrl1: Vec2,
48
+ ctrl2: Vec2,
49
+ to: Vec2
50
+ };
51
+
52
+ export type StrokeSettings = {
53
+ lineWidth: number,
54
+ lineJoin: LineJoin,
55
+ lineCap: LineCap,
56
+ miterLimit: number,
57
+ align: StrokeAlign,
58
+ fillRule: FillRule,
59
+ clipToShape: boolean,
60
+ dashPattern: any,
61
+ dashOffset: number
62
+ };
63
+
64
+ export interface PathCommandVector extends ClassHandle, Iterable<PathCommand> {
65
+ push_back(_0: PathCommand): void;
66
+ resize(_0: number, _1: PathCommand): void;
67
+ size(): number;
68
+ get(_0: number): PathCommand | undefined;
69
+ set(_0: number, _1: PathCommand): boolean;
70
+ }
71
+
72
+ export type SvgParse = {
73
+ commands: PathCommandVector,
74
+ ok: boolean,
75
+ message: EmbindString
76
+ };
77
+
78
+ interface EmbindModule {
79
+ Verb: {MoveTo: VerbValue<0>, LineTo: VerbValue<1>, QuadraticTo: VerbValue<2>, CubicTo: VerbValue<3>, Close: VerbValue<4>};
80
+ LineJoin: {Miter: LineJoinValue<0>, Bevel: LineJoinValue<1>, Round: LineJoinValue<2>};
81
+ LineCap: {Butt: LineCapValue<0>, Square: LineCapValue<1>, Round: LineCapValue<2>};
82
+ StrokeAlign: {Center: StrokeAlignValue<0>, Inside: StrokeAlignValue<1>, Outside: StrokeAlignValue<2>};
83
+ FillRule: {NonZero: FillRuleValue<0>, EvenOdd: FillRuleValue<1>};
84
+ PathCommandVector: {
85
+ new(): PathCommandVector;
86
+ };
87
+ buildStrokeOutline(_0: PathCommandVector, _1: StrokeSettings): PathCommandVector;
88
+ defaultStrokeSettings(): StrokeSettings;
89
+ parseSvgPath(_0: EmbindString): PathCommandVector;
90
+ parseSvgPathChecked(_0: EmbindString): SvgParse;
91
+ pathToSvg(_0: PathCommandVector, _1: number): string;
92
+ arcToCommands(_0: number, _1: number, _2: number, _3: number, _4: number, _5: boolean, _6: boolean, _7: number, _8: number): PathCommandVector;
93
+ }
94
+
95
+ export type MainModule = WasmModule & EmbindModule;
96
+ export default function MainModuleFactory (options?: unknown): Promise<MainModule>;