@quillmark/wasm 0.67.0 → 0.68.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/README.md +72 -32
- package/bundler/wasm.d.ts +136 -23
- package/bundler/wasm_bg.js +131 -31
- package/bundler/wasm_bg.wasm +0 -0
- package/bundler/wasm_bg.wasm.d.ts +2 -0
- package/node-esm/wasm.d.ts +136 -23
- package/node-esm/wasm.js +131 -31
- package/node-esm/wasm_bg.wasm +0 -0
- package/node-esm/wasm_bg.wasm.d.ts +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -79,53 +79,77 @@ O(1) getter for the number of composable cards (excluding the main card).
|
|
|
79
79
|
Use this to validate indices before calling card mutators (`removeCard`,
|
|
80
80
|
`updateCardField`, etc.) without allocating the full `cards` array.
|
|
81
81
|
|
|
82
|
+
### `quill.render(parsed, opts?)` vs. `quill.open(parsed)`
|
|
83
|
+
|
|
84
|
+
Use **`Quill.render`** for one-shot exports (PDF/SVG/PNG) — compiles, emits
|
|
85
|
+
artifacts, done. Use **`RenderSession`** (returned by `Quill.open`) for
|
|
86
|
+
reactive previews where you'll paint or re-emit pages multiple times: the
|
|
87
|
+
session retains the compiled snapshot so subsequent `paint` / `render`
|
|
88
|
+
calls skip recompilation. Don't open a session per export.
|
|
89
|
+
|
|
82
90
|
### `quill.render(parsed, opts?)`
|
|
83
91
|
Render with a pre-parsed `Document`.
|
|
84
92
|
|
|
85
93
|
### `quill.open(parsed)` + `session.render(opts?)`
|
|
86
94
|
Open once, render all or selected pages (`opts.pages`).
|
|
87
95
|
|
|
88
|
-
The session also exposes `pageCount`, `backendId`, `
|
|
89
|
-
session-level diagnostics attached at `open` time),
|
|
90
|
-
`paint(ctx, page,
|
|
96
|
+
The session also exposes `pageCount`, `backendId`, `supportsCanvas`,
|
|
97
|
+
`warnings` (snapshot of session-level diagnostics attached at `open` time),
|
|
98
|
+
`pageSize(page)`, and `paint(ctx, page, opts?)` for canvas previews. See
|
|
99
|
+
below.
|
|
100
|
+
|
|
101
|
+
A document that compiles to zero pages still produces a valid session
|
|
102
|
+
(`pageCount === 0`); `paint(ctx, 0)` and `pageSize(0)` then throw
|
|
103
|
+
`page index 0 out of range (pageCount=0)`. Branch on `pageCount === 0` to
|
|
104
|
+
render a "no pages to preview" UI without relying on the throw.
|
|
91
105
|
|
|
92
106
|
### Canvas Preview (Typst only)
|
|
93
107
|
|
|
94
|
-
`session.paint(ctx, page,
|
|
95
|
-
`CanvasRenderingContext2D
|
|
96
|
-
`
|
|
108
|
+
`session.paint(ctx, page, opts?)` rasterizes a page directly into a
|
|
109
|
+
`CanvasRenderingContext2D` (main thread) or
|
|
110
|
+
`OffscreenCanvasRenderingContext2D` (Worker), skipping PNG/SVG byte
|
|
111
|
+
round-trips.
|
|
112
|
+
|
|
113
|
+
The painter owns `canvas.width` / `canvas.height` — it sizes the backing
|
|
114
|
+
store itself. Consumers own `canvas.style.*` (or the layout system that
|
|
115
|
+
sets them) and read `layoutWidth` / `layoutHeight` from the returned
|
|
116
|
+
`PaintResult`.
|
|
97
117
|
|
|
98
118
|
```ts
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
// (e.g. repaint after a zoom that didn't change scale), call
|
|
107
|
-
// ctx.clearRect(0, 0, canvas.width, canvas.height) before paint instead.
|
|
108
|
-
canvas.width = Math.round(widthPt * scale); // device px
|
|
109
|
-
canvas.height = Math.round(heightPt * scale);
|
|
110
|
-
canvas.style.width = `${widthPt * userZoom}px`;
|
|
111
|
-
canvas.style.height = `${heightPt * userZoom}px`;
|
|
112
|
-
|
|
113
|
-
session.paint(canvas.getContext("2d"), 0, scale);
|
|
119
|
+
const result = session.paint(canvas.getContext("2d"), 0, {
|
|
120
|
+
layoutScale: 1, // layout px per Typst pt
|
|
121
|
+
densityScale: window.devicePixelRatio, // backing-store density
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
canvas.style.width = `${result.layoutWidth}px`;
|
|
125
|
+
canvas.style.height = `${result.layoutHeight}px`;
|
|
114
126
|
```
|
|
115
127
|
|
|
116
|
-
- `
|
|
117
|
-
|
|
118
|
-
|
|
128
|
+
- `layoutScale` (default 1) sets the canvas's display-box size:
|
|
129
|
+
`layoutWidth = widthPt * layoutScale`. For on-screen canvases this is
|
|
130
|
+
CSS pixels per Typst point. Defaults to 1 (one CSS pixel per pt).
|
|
131
|
+
- `densityScale` (default 1) is the backing-store density multiplier.
|
|
132
|
+
Fold `window.devicePixelRatio`, in-app zoom, and `visualViewport.scale`
|
|
133
|
+
(pinch-zoom) into a single value here. Pass `devicePixelRatio` for
|
|
134
|
+
crisp output on high-DPI displays.
|
|
135
|
+
- The effective rasterization scale is `layoutScale * densityScale`. If
|
|
136
|
+
that would exceed the safe maximum (16384 px per side), `densityScale`
|
|
137
|
+
is clamped proportionally; compare `result.pixelWidth` against
|
|
138
|
+
`Math.round(result.layoutWidth * densityScale)` to detect.
|
|
139
|
+
- `paint` is always a full repaint — setting the backing-store width /
|
|
140
|
+
height clears it. No `clearRect` required.
|
|
119
141
|
- `pageCount` and `pageSize(page)` are stable for the session's
|
|
120
142
|
lifetime (immutable snapshot) — cache them.
|
|
121
|
-
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
- Backend support:
|
|
127
|
-
|
|
128
|
-
`
|
|
143
|
+
- Worker support: pass an `OffscreenCanvasRenderingContext2D` and the
|
|
144
|
+
same call signature works. `layoutWidth` / `layoutHeight` are
|
|
145
|
+
informational in that mode (no CSS layout box); fold everything into
|
|
146
|
+
`densityScale`. Loading the WASM module inside a Worker is the host's
|
|
147
|
+
responsibility.
|
|
148
|
+
- Backend support: gated by `supportsCanvas`. Probe upfront with
|
|
149
|
+
`quill.supportsCanvas` (or `session.supportsCanvas`) before mounting a
|
|
150
|
+
canvas-based UI; the throw on `paint` / `pageSize` remains the
|
|
151
|
+
enforcement contract and includes the resolved `backendId` for
|
|
152
|
+
debugging.
|
|
129
153
|
|
|
130
154
|
### Errors
|
|
131
155
|
|
|
@@ -160,6 +184,22 @@ without manual `.free()` discipline. `.free()` is still emitted as an eager
|
|
|
160
184
|
teardown hook for callers that want deterministic release. Requires
|
|
161
185
|
Node 14.6+ / current evergreen browsers (all supported targets).
|
|
162
186
|
|
|
187
|
+
For environments where `using` (the [explicit resource management][erm]
|
|
188
|
+
proposal) hasn't landed, use an explicit `try` / `finally`:
|
|
189
|
+
|
|
190
|
+
```ts
|
|
191
|
+
const session = quill.open(doc);
|
|
192
|
+
try {
|
|
193
|
+
for (let p = 0; p < session.pageCount; p++) {
|
|
194
|
+
session.paint(ctx, p);
|
|
195
|
+
}
|
|
196
|
+
} finally {
|
|
197
|
+
session.free();
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
[erm]: https://github.com/tc39/proposal-explicit-resource-management
|
|
202
|
+
|
|
163
203
|
## Notes
|
|
164
204
|
|
|
165
205
|
- Parsed markdown requires top-level `QUILL` in frontmatter. Empty input
|
package/bundler/wasm.d.ts
CHANGED
|
@@ -17,14 +17,72 @@ export interface CardInput {
|
|
|
17
17
|
/**
|
|
18
18
|
* Page dimensions in Typst points (1 pt = 1/72 inch).
|
|
19
19
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
20
|
+
* Report-only: the painter sizes the canvas itself based on
|
|
21
|
+
* `PaintOptions`. `pageSize` is exposed for callers that need page
|
|
22
|
+
* geometry up-front (e.g. to lay out a scrollable list of canvases
|
|
23
|
+
* before any pixels are rendered).
|
|
22
24
|
*/
|
|
23
25
|
export interface PageSize {
|
|
24
26
|
widthPt: number;
|
|
25
27
|
heightPt: number;
|
|
26
28
|
}
|
|
27
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Inputs to `RenderSession.paint`. Both fields are optional and default
|
|
32
|
+
* to `1`.
|
|
33
|
+
*
|
|
34
|
+
* - `layoutScale` — layout-space pixels per Typst point. For on-screen
|
|
35
|
+
* canvases this is CSS pixels per pt; the page's layout-pixel size is
|
|
36
|
+
* `widthPt * layoutScale × heightPt * layoutScale`. The painter
|
|
37
|
+
* surfaces these dimensions as `layoutWidth` / `layoutHeight` so
|
|
38
|
+
* consumers can drive `canvas.style.*` (or any layout system).
|
|
39
|
+
* - `densityScale` — backing-store density multiplier. Fold
|
|
40
|
+
* `window.devicePixelRatio`, in-app zoom, and `visualViewport.scale`
|
|
41
|
+
* (pinch-zoom) into a single value here. Defaults to `1`, which
|
|
42
|
+
* produces a non-retina backing store — pass `window.devicePixelRatio`
|
|
43
|
+
* for crisp output on high-DPI displays.
|
|
44
|
+
*
|
|
45
|
+
* The effective rasterization scale is `layoutScale * densityScale`.
|
|
46
|
+
* Both must be finite and `> 0`. For `OffscreenCanvasRenderingContext2D`
|
|
47
|
+
* the two collapse to a single scalar; folding everything into
|
|
48
|
+
* `densityScale` is the simplest convention.
|
|
49
|
+
*/
|
|
50
|
+
export interface PaintOptions {
|
|
51
|
+
layoutScale?: number;
|
|
52
|
+
densityScale?: number;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Returned by `RenderSession.paint`.
|
|
57
|
+
*
|
|
58
|
+
* - `layoutWidth` / `layoutHeight` — layout-pixel dimensions of the
|
|
59
|
+
* canvas's display box. For on-screen canvases this is CSS pixels:
|
|
60
|
+
* set `canvas.style.width = layoutWidth + "px"` and
|
|
61
|
+
* `canvas.style.height = layoutHeight + "px"` (or feed these into
|
|
62
|
+
* your layout system). Independent of `densityScale`.
|
|
63
|
+
* - `pixelWidth` / `pixelHeight` — integer backing-store pixel
|
|
64
|
+
* dimensions the painter wrote to `canvas.width` / `canvas.height`.
|
|
65
|
+
* Equal to `round(layoutWidth * densityScale)` ×
|
|
66
|
+
* `round(layoutHeight * densityScale)` *unless* the requested backing
|
|
67
|
+
* exceeded the painter's safe maximum (16384 px per side), in which
|
|
68
|
+
* case `densityScale` was clamped to fit. Detect clamping via
|
|
69
|
+
* `pixelWidth < round(layoutWidth * densityScale)`.
|
|
70
|
+
*
|
|
71
|
+
* The painter owns `canvas.width` / `canvas.height`; consumers must not
|
|
72
|
+
* write to them. The painter does **not** touch `canvas.style.*`;
|
|
73
|
+
* consumers own layout.
|
|
74
|
+
*
|
|
75
|
+
* For `OffscreenCanvasRenderingContext2D` (Worker rasterization, no
|
|
76
|
+
* DOM), `layoutWidth` / `layoutHeight` are informational — there's no
|
|
77
|
+
* CSS layout box to apply them to.
|
|
78
|
+
*/
|
|
79
|
+
export interface PaintResult {
|
|
80
|
+
layoutWidth: number;
|
|
81
|
+
layoutHeight: number;
|
|
82
|
+
pixelWidth: number;
|
|
83
|
+
pixelHeight: number;
|
|
84
|
+
}
|
|
85
|
+
|
|
28
86
|
|
|
29
87
|
export interface Artifact {
|
|
30
88
|
format: OutputFormat;
|
|
@@ -368,6 +426,15 @@ export class Quill {
|
|
|
368
426
|
* immutable once constructed.
|
|
369
427
|
*/
|
|
370
428
|
readonly metadata: any;
|
|
429
|
+
/**
|
|
430
|
+
* Whether this quill's backend supports canvas preview.
|
|
431
|
+
*
|
|
432
|
+
* `true` iff `RenderSession.paint` and `RenderSession.pageSize` will
|
|
433
|
+
* succeed for sessions opened by this quill. Use this as a precondition
|
|
434
|
+
* probe before mounting a canvas-based preview UI; the throw on `paint`
|
|
435
|
+
* remains the enforcement contract.
|
|
436
|
+
*/
|
|
437
|
+
readonly supportsCanvas: boolean;
|
|
371
438
|
}
|
|
372
439
|
|
|
373
440
|
/**
|
|
@@ -391,6 +458,21 @@ export class Quillmark {
|
|
|
391
458
|
quill(tree: Map<string, Uint8Array>): Quill;
|
|
392
459
|
}
|
|
393
460
|
|
|
461
|
+
/**
|
|
462
|
+
* An iterative render handle backed by an immutable compiled snapshot.
|
|
463
|
+
*
|
|
464
|
+
* Created via [`Quill::open`]. Holds the compiled output so that
|
|
465
|
+
* [`RenderSession::render`], [`RenderSession::paint`], and
|
|
466
|
+
* [`RenderSession::page_size`] can be called repeatedly without
|
|
467
|
+
* recompiling.
|
|
468
|
+
*
|
|
469
|
+
* **Empty documents.** A document that compiles to zero pages still
|
|
470
|
+
* produces a valid session (`pageCount === 0`). Iterating
|
|
471
|
+
* `0..pageCount` is then a no-op; calling `paint(ctx, 0)` or
|
|
472
|
+
* `pageSize(0)` throws `"... page index 0 out of range
|
|
473
|
+
* (pageCount=0)"`. Hosts that surface "no pages to preview" UI should
|
|
474
|
+
* branch on `pageCount === 0` rather than on a thrown error.
|
|
475
|
+
*/
|
|
394
476
|
export class RenderSession {
|
|
395
477
|
private constructor();
|
|
396
478
|
free(): void;
|
|
@@ -398,6 +480,11 @@ export class RenderSession {
|
|
|
398
480
|
/**
|
|
399
481
|
* Page dimensions in Typst points (1 pt = 1/72 inch).
|
|
400
482
|
*
|
|
483
|
+
* Report-only: the painter sizes the canvas itself based on
|
|
484
|
+
* `PaintOptions`. Exposed for consumers that need page geometry
|
|
485
|
+
* up-front (e.g. to lay out a scrollable list of canvases before
|
|
486
|
+
* any pixels are rendered).
|
|
487
|
+
*
|
|
401
488
|
* Stable for a given `page` across the session's lifetime — the
|
|
402
489
|
* compiled document is an immutable snapshot, so callers can cache
|
|
403
490
|
* results.
|
|
@@ -409,33 +496,51 @@ export class RenderSession {
|
|
|
409
496
|
/**
|
|
410
497
|
* Paint `page` into a 2D canvas context.
|
|
411
498
|
*
|
|
412
|
-
*
|
|
413
|
-
* `
|
|
414
|
-
*
|
|
415
|
-
*
|
|
416
|
-
*
|
|
417
|
-
* `canvas.width
|
|
418
|
-
*
|
|
419
|
-
* `canvas.
|
|
420
|
-
*
|
|
421
|
-
*
|
|
422
|
-
* `
|
|
423
|
-
*
|
|
424
|
-
*
|
|
425
|
-
* `
|
|
426
|
-
*
|
|
427
|
-
*
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
*
|
|
431
|
-
|
|
432
|
-
|
|
499
|
+
* Accepts either a `CanvasRenderingContext2D` (main thread) or an
|
|
500
|
+
* `OffscreenCanvasRenderingContext2D` (Worker / off-DOM rasterization).
|
|
501
|
+
* Both dispatch to the same Rust rasterizer; the dispatch happens at
|
|
502
|
+
* the JS boundary so neither context type is privileged.
|
|
503
|
+
*
|
|
504
|
+
* The painter owns `canvas.width` / `canvas.height` and writes them
|
|
505
|
+
* itself; consumers must not. The painter does not touch
|
|
506
|
+
* `canvas.style.*` — that's layout, owned by the consumer (see
|
|
507
|
+
* `PaintResult.layoutWidth` / `layoutHeight`).
|
|
508
|
+
*
|
|
509
|
+
* `opts.layoutScale` (default 1.0) is layout-space pixels per Typst
|
|
510
|
+
* point and determines the canvas's display-box size. `opts.densityScale`
|
|
511
|
+
* (default 1.0) is the rasterization density multiplier the consumer
|
|
512
|
+
* folds `window.devicePixelRatio`, in-app zoom, and
|
|
513
|
+
* `visualViewport.scale` (pinch-zoom) into. The effective
|
|
514
|
+
* rasterization scale is `layoutScale * densityScale`.
|
|
515
|
+
*
|
|
516
|
+
* If `layoutScale * densityScale` would exceed the safe backing-store
|
|
517
|
+
* maximum (16384 px per side), `densityScale` is clamped
|
|
518
|
+
* proportionally so the largest dimension fits. The actual
|
|
519
|
+
* backing-store dimensions are reported in the returned
|
|
520
|
+
* `PaintResult` — compare against
|
|
521
|
+
* `round(layoutWidth * densityScale)` to detect clamping.
|
|
522
|
+
*
|
|
523
|
+
* Each call resets the backing store (`paint` is always a full
|
|
524
|
+
* repaint). Consumers do not need to call `clearRect`.
|
|
525
|
+
*
|
|
526
|
+
* Throws when:
|
|
527
|
+
* - the backend does not support canvas preview (message includes the
|
|
528
|
+
* resolved `backendId`),
|
|
529
|
+
* - `page` is out of range,
|
|
530
|
+
* - `ctx` is neither `CanvasRenderingContext2D` nor
|
|
531
|
+
* `OffscreenCanvasRenderingContext2D`,
|
|
532
|
+
* - `opts.layoutScale` or `opts.densityScale` is non-finite or `<= 0`.
|
|
533
|
+
*/
|
|
534
|
+
paint(ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D, page: number, opts: PaintOptions | undefined): PaintResult;
|
|
433
535
|
/**
|
|
434
536
|
* Render all or selected pages from this session.
|
|
435
537
|
*/
|
|
436
538
|
render(opts?: RenderOptions | null): RenderResult;
|
|
437
539
|
/**
|
|
438
540
|
* The backend that produced this session (e.g. `"typst"`).
|
|
541
|
+
*
|
|
542
|
+
* Equal to the `backendId` of the [`Quill`] that opened this session
|
|
543
|
+
* (sessions inherit their quill's backend), so checking either is fine.
|
|
439
544
|
*/
|
|
440
545
|
readonly backendId: string;
|
|
441
546
|
/**
|
|
@@ -445,6 +550,14 @@ export class RenderSession {
|
|
|
445
550
|
* document is an immutable snapshot.
|
|
446
551
|
*/
|
|
447
552
|
readonly pageCount: number;
|
|
553
|
+
/**
|
|
554
|
+
* Whether this session's backend supports canvas preview.
|
|
555
|
+
*
|
|
556
|
+
* `true` iff [`paint`](Self::paint) and [`page_size`](Self::page_size)
|
|
557
|
+
* will succeed. Equal to `Quill.supportsCanvas` for the quill that
|
|
558
|
+
* opened this session.
|
|
559
|
+
*/
|
|
560
|
+
readonly supportsCanvas: boolean;
|
|
448
561
|
/**
|
|
449
562
|
* Session-level warnings attached at `quill.open(...)` time.
|
|
450
563
|
*
|
package/bundler/wasm_bg.js
CHANGED
|
@@ -685,6 +685,19 @@ export class Quill {
|
|
|
685
685
|
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
686
686
|
}
|
|
687
687
|
}
|
|
688
|
+
/**
|
|
689
|
+
* Whether this quill's backend supports canvas preview.
|
|
690
|
+
*
|
|
691
|
+
* `true` iff `RenderSession.paint` and `RenderSession.pageSize` will
|
|
692
|
+
* succeed for sessions opened by this quill. Use this as a precondition
|
|
693
|
+
* probe before mounting a canvas-based preview UI; the throw on `paint`
|
|
694
|
+
* remains the enforcement contract.
|
|
695
|
+
* @returns {boolean}
|
|
696
|
+
*/
|
|
697
|
+
get supportsCanvas() {
|
|
698
|
+
const ret = wasm.quill_supportsCanvas(this.__wbg_ptr);
|
|
699
|
+
return ret !== 0;
|
|
700
|
+
}
|
|
688
701
|
}
|
|
689
702
|
if (Symbol.dispose) Quill.prototype[Symbol.dispose] = Quill.prototype.free;
|
|
690
703
|
|
|
@@ -739,6 +752,21 @@ export class Quillmark {
|
|
|
739
752
|
}
|
|
740
753
|
if (Symbol.dispose) Quillmark.prototype[Symbol.dispose] = Quillmark.prototype.free;
|
|
741
754
|
|
|
755
|
+
/**
|
|
756
|
+
* An iterative render handle backed by an immutable compiled snapshot.
|
|
757
|
+
*
|
|
758
|
+
* Created via [`Quill::open`]. Holds the compiled output so that
|
|
759
|
+
* [`RenderSession::render`], [`RenderSession::paint`], and
|
|
760
|
+
* [`RenderSession::page_size`] can be called repeatedly without
|
|
761
|
+
* recompiling.
|
|
762
|
+
*
|
|
763
|
+
* **Empty documents.** A document that compiles to zero pages still
|
|
764
|
+
* produces a valid session (`pageCount === 0`). Iterating
|
|
765
|
+
* `0..pageCount` is then a no-op; calling `paint(ctx, 0)` or
|
|
766
|
+
* `pageSize(0)` throws `"... page index 0 out of range
|
|
767
|
+
* (pageCount=0)"`. Hosts that surface "no pages to preview" UI should
|
|
768
|
+
* branch on `pageCount === 0` rather than on a thrown error.
|
|
769
|
+
*/
|
|
742
770
|
export class RenderSession {
|
|
743
771
|
static __wrap(ptr) {
|
|
744
772
|
ptr = ptr >>> 0;
|
|
@@ -759,6 +787,9 @@ export class RenderSession {
|
|
|
759
787
|
}
|
|
760
788
|
/**
|
|
761
789
|
* The backend that produced this session (e.g. `"typst"`).
|
|
790
|
+
*
|
|
791
|
+
* Equal to the `backendId` of the [`Quill`] that opened this session
|
|
792
|
+
* (sessions inherit their quill's backend), so checking either is fine.
|
|
762
793
|
* @returns {string}
|
|
763
794
|
*/
|
|
764
795
|
get backendId() {
|
|
@@ -791,6 +822,11 @@ export class RenderSession {
|
|
|
791
822
|
/**
|
|
792
823
|
* Page dimensions in Typst points (1 pt = 1/72 inch).
|
|
793
824
|
*
|
|
825
|
+
* Report-only: the painter sizes the canvas itself based on
|
|
826
|
+
* `PaintOptions`. Exposed for consumers that need page geometry
|
|
827
|
+
* up-front (e.g. to lay out a scrollable list of canvases before
|
|
828
|
+
* any pixels are rendered).
|
|
829
|
+
*
|
|
794
830
|
* Stable for a given `page` across the session's lifetime — the
|
|
795
831
|
* compiled document is an immutable snapshot, so callers can cache
|
|
796
832
|
* results.
|
|
@@ -818,41 +854,58 @@ export class RenderSession {
|
|
|
818
854
|
/**
|
|
819
855
|
* Paint `page` into a 2D canvas context.
|
|
820
856
|
*
|
|
821
|
-
*
|
|
822
|
-
* `
|
|
823
|
-
*
|
|
857
|
+
* Accepts either a `CanvasRenderingContext2D` (main thread) or an
|
|
858
|
+
* `OffscreenCanvasRenderingContext2D` (Worker / off-DOM rasterization).
|
|
859
|
+
* Both dispatch to the same Rust rasterizer; the dispatch happens at
|
|
860
|
+
* the JS boundary so neither context type is privileged.
|
|
861
|
+
*
|
|
862
|
+
* The painter owns `canvas.width` / `canvas.height` and writes them
|
|
863
|
+
* itself; consumers must not. The painter does not touch
|
|
864
|
+
* `canvas.style.*` — that's layout, owned by the consumer (see
|
|
865
|
+
* `PaintResult.layoutWidth` / `layoutHeight`).
|
|
866
|
+
*
|
|
867
|
+
* `opts.layoutScale` (default 1.0) is layout-space pixels per Typst
|
|
868
|
+
* point and determines the canvas's display-box size. `opts.densityScale`
|
|
869
|
+
* (default 1.0) is the rasterization density multiplier the consumer
|
|
870
|
+
* folds `window.devicePixelRatio`, in-app zoom, and
|
|
871
|
+
* `visualViewport.scale` (pinch-zoom) into. The effective
|
|
872
|
+
* rasterization scale is `layoutScale * densityScale`.
|
|
824
873
|
*
|
|
825
|
-
*
|
|
826
|
-
*
|
|
827
|
-
*
|
|
828
|
-
*
|
|
829
|
-
*
|
|
830
|
-
*
|
|
831
|
-
* `ctx.clearRect(0, 0, canvas.width, canvas.height)` first to avoid
|
|
832
|
-
* stale pixels showing through transparent regions.
|
|
874
|
+
* If `layoutScale * densityScale` would exceed the safe backing-store
|
|
875
|
+
* maximum (16384 px per side), `densityScale` is clamped
|
|
876
|
+
* proportionally so the largest dimension fits. The actual
|
|
877
|
+
* backing-store dimensions are reported in the returned
|
|
878
|
+
* `PaintResult` — compare against
|
|
879
|
+
* `round(layoutWidth * densityScale)` to detect clamping.
|
|
833
880
|
*
|
|
834
|
-
*
|
|
835
|
-
* not
|
|
881
|
+
* Each call resets the backing store (`paint` is always a full
|
|
882
|
+
* repaint). Consumers do not need to call `clearRect`.
|
|
836
883
|
*
|
|
837
|
-
* Throws
|
|
838
|
-
*
|
|
839
|
-
*
|
|
840
|
-
*
|
|
884
|
+
* Throws when:
|
|
885
|
+
* - the backend does not support canvas preview (message includes the
|
|
886
|
+
* resolved `backendId`),
|
|
887
|
+
* - `page` is out of range,
|
|
888
|
+
* - `ctx` is neither `CanvasRenderingContext2D` nor
|
|
889
|
+
* `OffscreenCanvasRenderingContext2D`,
|
|
890
|
+
* - `opts.layoutScale` or `opts.densityScale` is non-finite or `<= 0`.
|
|
891
|
+
* @param {CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D} ctx
|
|
841
892
|
* @param {number} page
|
|
842
|
-
* @param {
|
|
893
|
+
* @param {PaintOptions | undefined} opts
|
|
894
|
+
* @returns {PaintResult}
|
|
843
895
|
*/
|
|
844
|
-
paint(ctx, page,
|
|
896
|
+
paint(ctx, page, opts) {
|
|
845
897
|
try {
|
|
846
898
|
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
847
|
-
wasm.rendersession_paint(retptr, this.__wbg_ptr,
|
|
899
|
+
wasm.rendersession_paint(retptr, this.__wbg_ptr, addHeapObject(ctx), page, addHeapObject(opts));
|
|
848
900
|
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
849
901
|
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
850
|
-
|
|
851
|
-
|
|
902
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
903
|
+
if (r2) {
|
|
904
|
+
throw takeObject(r1);
|
|
852
905
|
}
|
|
906
|
+
return takeObject(r0);
|
|
853
907
|
} finally {
|
|
854
908
|
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
855
|
-
heap[stack_pointer++] = undefined;
|
|
856
909
|
}
|
|
857
910
|
}
|
|
858
911
|
/**
|
|
@@ -875,6 +928,18 @@ export class RenderSession {
|
|
|
875
928
|
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
876
929
|
}
|
|
877
930
|
}
|
|
931
|
+
/**
|
|
932
|
+
* Whether this session's backend supports canvas preview.
|
|
933
|
+
*
|
|
934
|
+
* `true` iff [`paint`](Self::paint) and [`page_size`](Self::page_size)
|
|
935
|
+
* will succeed. Equal to `Quill.supportsCanvas` for the quill that
|
|
936
|
+
* opened this session.
|
|
937
|
+
* @returns {boolean}
|
|
938
|
+
*/
|
|
939
|
+
get supportsCanvas() {
|
|
940
|
+
const ret = wasm.rendersession_supportsCanvas(this.__wbg_ptr);
|
|
941
|
+
return ret !== 0;
|
|
942
|
+
}
|
|
878
943
|
/**
|
|
879
944
|
* Session-level warnings attached at `quill.open(...)` time.
|
|
880
945
|
*
|
|
@@ -997,6 +1062,14 @@ export function __wbg_call_14b169f759b26747() { return handleError(function (arg
|
|
|
997
1062
|
const ret = getObject(arg0).call(getObject(arg1));
|
|
998
1063
|
return addHeapObject(ret);
|
|
999
1064
|
}, arguments); }
|
|
1065
|
+
export function __wbg_canvas_2c0c6d263d4c52ad(arg0) {
|
|
1066
|
+
const ret = getObject(arg0).canvas;
|
|
1067
|
+
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
|
1068
|
+
}
|
|
1069
|
+
export function __wbg_canvas_374da9f3c5b3dd0e(arg0) {
|
|
1070
|
+
const ret = getObject(arg0).canvas;
|
|
1071
|
+
return addHeapObject(ret);
|
|
1072
|
+
}
|
|
1000
1073
|
export function __wbg_done_9158f7cc8751ba32(arg0) {
|
|
1001
1074
|
const ret = getObject(arg0).done;
|
|
1002
1075
|
return ret;
|
|
@@ -1073,6 +1146,16 @@ export function __wbg_instanceof_ArrayBuffer_7c8433c6ed14ffe3(arg0) {
|
|
|
1073
1146
|
const ret = result;
|
|
1074
1147
|
return ret;
|
|
1075
1148
|
}
|
|
1149
|
+
export function __wbg_instanceof_CanvasRenderingContext2d_24a3fe06e62b98d7(arg0) {
|
|
1150
|
+
let result;
|
|
1151
|
+
try {
|
|
1152
|
+
result = getObject(arg0) instanceof CanvasRenderingContext2D;
|
|
1153
|
+
} catch (_) {
|
|
1154
|
+
result = false;
|
|
1155
|
+
}
|
|
1156
|
+
const ret = result;
|
|
1157
|
+
return ret;
|
|
1158
|
+
}
|
|
1076
1159
|
export function __wbg_instanceof_Map_1b76fd4635be43eb(arg0) {
|
|
1077
1160
|
let result;
|
|
1078
1161
|
try {
|
|
@@ -1083,6 +1166,16 @@ export function __wbg_instanceof_Map_1b76fd4635be43eb(arg0) {
|
|
|
1083
1166
|
const ret = result;
|
|
1084
1167
|
return ret;
|
|
1085
1168
|
}
|
|
1169
|
+
export function __wbg_instanceof_OffscreenCanvasRenderingContext2d_285a274020b4f230(arg0) {
|
|
1170
|
+
let result;
|
|
1171
|
+
try {
|
|
1172
|
+
result = getObject(arg0) instanceof OffscreenCanvasRenderingContext2D;
|
|
1173
|
+
} catch (_) {
|
|
1174
|
+
result = false;
|
|
1175
|
+
}
|
|
1176
|
+
const ret = result;
|
|
1177
|
+
return ret;
|
|
1178
|
+
}
|
|
1086
1179
|
export function __wbg_instanceof_Uint8Array_152ba1f289edcf3f(arg0) {
|
|
1087
1180
|
let result;
|
|
1088
1181
|
try {
|
|
@@ -1167,6 +1260,9 @@ export function __wbg_prototypesetcall_a6b02eb00b0f4ce2(arg0, arg1, arg2) {
|
|
|
1167
1260
|
export function __wbg_putImageData_c810e62ea70e761d() { return handleError(function (arg0, arg1, arg2, arg3) {
|
|
1168
1261
|
getObject(arg0).putImageData(getObject(arg1), arg2, arg3);
|
|
1169
1262
|
}, arguments); }
|
|
1263
|
+
export function __wbg_putImageData_cb4de9afd58963be() { return handleError(function (arg0, arg1, arg2, arg3) {
|
|
1264
|
+
getObject(arg0).putImageData(getObject(arg1), arg2, arg3);
|
|
1265
|
+
}, arguments); }
|
|
1170
1266
|
export function __wbg_set_022bee52d0b05b19() { return handleError(function (arg0, arg1, arg2) {
|
|
1171
1267
|
const ret = Reflect.set(getObject(arg0), getObject(arg1), getObject(arg2));
|
|
1172
1268
|
return ret;
|
|
@@ -1184,6 +1280,18 @@ export function __wbg_set_fde2cec06c23692b(arg0, arg1, arg2) {
|
|
|
1184
1280
|
const ret = getObject(arg0).set(getObject(arg1), getObject(arg2));
|
|
1185
1281
|
return addHeapObject(ret);
|
|
1186
1282
|
}
|
|
1283
|
+
export function __wbg_set_height_24d07d982f176ac6(arg0, arg1) {
|
|
1284
|
+
getObject(arg0).height = arg1 >>> 0;
|
|
1285
|
+
}
|
|
1286
|
+
export function __wbg_set_height_be9b2b920bd68401(arg0, arg1) {
|
|
1287
|
+
getObject(arg0).height = arg1 >>> 0;
|
|
1288
|
+
}
|
|
1289
|
+
export function __wbg_set_width_5cda41d4d06a14dd(arg0, arg1) {
|
|
1290
|
+
getObject(arg0).width = arg1 >>> 0;
|
|
1291
|
+
}
|
|
1292
|
+
export function __wbg_set_width_adc925bca9c5351a(arg0, arg1) {
|
|
1293
|
+
getObject(arg0).width = arg1 >>> 0;
|
|
1294
|
+
}
|
|
1187
1295
|
export function __wbg_stack_3b0d974bbf31e44f(arg0, arg1) {
|
|
1188
1296
|
const ret = getObject(arg1).stack;
|
|
1189
1297
|
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
@@ -1255,12 +1363,6 @@ function _assertClass(instance, klass) {
|
|
|
1255
1363
|
}
|
|
1256
1364
|
}
|
|
1257
1365
|
|
|
1258
|
-
function addBorrowedObject(obj) {
|
|
1259
|
-
if (stack_pointer == 1) throw new Error('out of js stack');
|
|
1260
|
-
heap[--stack_pointer] = obj;
|
|
1261
|
-
return stack_pointer;
|
|
1262
|
-
}
|
|
1263
|
-
|
|
1264
1366
|
function debugString(val) {
|
|
1265
1367
|
// primitive types
|
|
1266
1368
|
const type = typeof val;
|
|
@@ -1427,8 +1529,6 @@ function passStringToWasm0(arg, malloc, realloc) {
|
|
|
1427
1529
|
return ptr;
|
|
1428
1530
|
}
|
|
1429
1531
|
|
|
1430
|
-
let stack_pointer = 1024;
|
|
1431
|
-
|
|
1432
1532
|
function takeObject(idx) {
|
|
1433
1533
|
const ret = getObject(idx);
|
|
1434
1534
|
dropObject(idx);
|
package/bundler/wasm_bg.wasm
CHANGED
|
Binary file
|
|
@@ -35,6 +35,7 @@ export const quill_form: (a: number, b: number, c: number) => void;
|
|
|
35
35
|
export const quill_metadata: (a: number) => number;
|
|
36
36
|
export const quill_open: (a: number, b: number, c: number) => void;
|
|
37
37
|
export const quill_render: (a: number, b: number, c: number, d: number) => void;
|
|
38
|
+
export const quill_supportsCanvas: (a: number) => number;
|
|
38
39
|
export const quillmark_new: () => number;
|
|
39
40
|
export const quillmark_quill: (a: number, b: number, c: number) => void;
|
|
40
41
|
export const rendersession_backendId: (a: number, b: number) => void;
|
|
@@ -42,6 +43,7 @@ export const rendersession_pageCount: (a: number) => number;
|
|
|
42
43
|
export const rendersession_pageSize: (a: number, b: number, c: number) => void;
|
|
43
44
|
export const rendersession_paint: (a: number, b: number, c: number, d: number, e: number) => void;
|
|
44
45
|
export const rendersession_render: (a: number, b: number, c: number) => void;
|
|
46
|
+
export const rendersession_supportsCanvas: (a: number) => number;
|
|
45
47
|
export const rendersession_warnings: (a: number) => number;
|
|
46
48
|
export const lut_inverse_interp16: (a: number, b: number, c: number) => number;
|
|
47
49
|
export const qcms_profile_precache_output_transform: (a: number) => void;
|
package/node-esm/wasm.d.ts
CHANGED
|
@@ -17,14 +17,72 @@ export interface CardInput {
|
|
|
17
17
|
/**
|
|
18
18
|
* Page dimensions in Typst points (1 pt = 1/72 inch).
|
|
19
19
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
20
|
+
* Report-only: the painter sizes the canvas itself based on
|
|
21
|
+
* `PaintOptions`. `pageSize` is exposed for callers that need page
|
|
22
|
+
* geometry up-front (e.g. to lay out a scrollable list of canvases
|
|
23
|
+
* before any pixels are rendered).
|
|
22
24
|
*/
|
|
23
25
|
export interface PageSize {
|
|
24
26
|
widthPt: number;
|
|
25
27
|
heightPt: number;
|
|
26
28
|
}
|
|
27
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Inputs to `RenderSession.paint`. Both fields are optional and default
|
|
32
|
+
* to `1`.
|
|
33
|
+
*
|
|
34
|
+
* - `layoutScale` — layout-space pixels per Typst point. For on-screen
|
|
35
|
+
* canvases this is CSS pixels per pt; the page's layout-pixel size is
|
|
36
|
+
* `widthPt * layoutScale × heightPt * layoutScale`. The painter
|
|
37
|
+
* surfaces these dimensions as `layoutWidth` / `layoutHeight` so
|
|
38
|
+
* consumers can drive `canvas.style.*` (or any layout system).
|
|
39
|
+
* - `densityScale` — backing-store density multiplier. Fold
|
|
40
|
+
* `window.devicePixelRatio`, in-app zoom, and `visualViewport.scale`
|
|
41
|
+
* (pinch-zoom) into a single value here. Defaults to `1`, which
|
|
42
|
+
* produces a non-retina backing store — pass `window.devicePixelRatio`
|
|
43
|
+
* for crisp output on high-DPI displays.
|
|
44
|
+
*
|
|
45
|
+
* The effective rasterization scale is `layoutScale * densityScale`.
|
|
46
|
+
* Both must be finite and `> 0`. For `OffscreenCanvasRenderingContext2D`
|
|
47
|
+
* the two collapse to a single scalar; folding everything into
|
|
48
|
+
* `densityScale` is the simplest convention.
|
|
49
|
+
*/
|
|
50
|
+
export interface PaintOptions {
|
|
51
|
+
layoutScale?: number;
|
|
52
|
+
densityScale?: number;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Returned by `RenderSession.paint`.
|
|
57
|
+
*
|
|
58
|
+
* - `layoutWidth` / `layoutHeight` — layout-pixel dimensions of the
|
|
59
|
+
* canvas's display box. For on-screen canvases this is CSS pixels:
|
|
60
|
+
* set `canvas.style.width = layoutWidth + "px"` and
|
|
61
|
+
* `canvas.style.height = layoutHeight + "px"` (or feed these into
|
|
62
|
+
* your layout system). Independent of `densityScale`.
|
|
63
|
+
* - `pixelWidth` / `pixelHeight` — integer backing-store pixel
|
|
64
|
+
* dimensions the painter wrote to `canvas.width` / `canvas.height`.
|
|
65
|
+
* Equal to `round(layoutWidth * densityScale)` ×
|
|
66
|
+
* `round(layoutHeight * densityScale)` *unless* the requested backing
|
|
67
|
+
* exceeded the painter's safe maximum (16384 px per side), in which
|
|
68
|
+
* case `densityScale` was clamped to fit. Detect clamping via
|
|
69
|
+
* `pixelWidth < round(layoutWidth * densityScale)`.
|
|
70
|
+
*
|
|
71
|
+
* The painter owns `canvas.width` / `canvas.height`; consumers must not
|
|
72
|
+
* write to them. The painter does **not** touch `canvas.style.*`;
|
|
73
|
+
* consumers own layout.
|
|
74
|
+
*
|
|
75
|
+
* For `OffscreenCanvasRenderingContext2D` (Worker rasterization, no
|
|
76
|
+
* DOM), `layoutWidth` / `layoutHeight` are informational — there's no
|
|
77
|
+
* CSS layout box to apply them to.
|
|
78
|
+
*/
|
|
79
|
+
export interface PaintResult {
|
|
80
|
+
layoutWidth: number;
|
|
81
|
+
layoutHeight: number;
|
|
82
|
+
pixelWidth: number;
|
|
83
|
+
pixelHeight: number;
|
|
84
|
+
}
|
|
85
|
+
|
|
28
86
|
|
|
29
87
|
export interface Artifact {
|
|
30
88
|
format: OutputFormat;
|
|
@@ -368,6 +426,15 @@ export class Quill {
|
|
|
368
426
|
* immutable once constructed.
|
|
369
427
|
*/
|
|
370
428
|
readonly metadata: any;
|
|
429
|
+
/**
|
|
430
|
+
* Whether this quill's backend supports canvas preview.
|
|
431
|
+
*
|
|
432
|
+
* `true` iff `RenderSession.paint` and `RenderSession.pageSize` will
|
|
433
|
+
* succeed for sessions opened by this quill. Use this as a precondition
|
|
434
|
+
* probe before mounting a canvas-based preview UI; the throw on `paint`
|
|
435
|
+
* remains the enforcement contract.
|
|
436
|
+
*/
|
|
437
|
+
readonly supportsCanvas: boolean;
|
|
371
438
|
}
|
|
372
439
|
|
|
373
440
|
/**
|
|
@@ -391,6 +458,21 @@ export class Quillmark {
|
|
|
391
458
|
quill(tree: Map<string, Uint8Array>): Quill;
|
|
392
459
|
}
|
|
393
460
|
|
|
461
|
+
/**
|
|
462
|
+
* An iterative render handle backed by an immutable compiled snapshot.
|
|
463
|
+
*
|
|
464
|
+
* Created via [`Quill::open`]. Holds the compiled output so that
|
|
465
|
+
* [`RenderSession::render`], [`RenderSession::paint`], and
|
|
466
|
+
* [`RenderSession::page_size`] can be called repeatedly without
|
|
467
|
+
* recompiling.
|
|
468
|
+
*
|
|
469
|
+
* **Empty documents.** A document that compiles to zero pages still
|
|
470
|
+
* produces a valid session (`pageCount === 0`). Iterating
|
|
471
|
+
* `0..pageCount` is then a no-op; calling `paint(ctx, 0)` or
|
|
472
|
+
* `pageSize(0)` throws `"... page index 0 out of range
|
|
473
|
+
* (pageCount=0)"`. Hosts that surface "no pages to preview" UI should
|
|
474
|
+
* branch on `pageCount === 0` rather than on a thrown error.
|
|
475
|
+
*/
|
|
394
476
|
export class RenderSession {
|
|
395
477
|
private constructor();
|
|
396
478
|
free(): void;
|
|
@@ -398,6 +480,11 @@ export class RenderSession {
|
|
|
398
480
|
/**
|
|
399
481
|
* Page dimensions in Typst points (1 pt = 1/72 inch).
|
|
400
482
|
*
|
|
483
|
+
* Report-only: the painter sizes the canvas itself based on
|
|
484
|
+
* `PaintOptions`. Exposed for consumers that need page geometry
|
|
485
|
+
* up-front (e.g. to lay out a scrollable list of canvases before
|
|
486
|
+
* any pixels are rendered).
|
|
487
|
+
*
|
|
401
488
|
* Stable for a given `page` across the session's lifetime — the
|
|
402
489
|
* compiled document is an immutable snapshot, so callers can cache
|
|
403
490
|
* results.
|
|
@@ -409,33 +496,51 @@ export class RenderSession {
|
|
|
409
496
|
/**
|
|
410
497
|
* Paint `page` into a 2D canvas context.
|
|
411
498
|
*
|
|
412
|
-
*
|
|
413
|
-
* `
|
|
414
|
-
*
|
|
415
|
-
*
|
|
416
|
-
*
|
|
417
|
-
* `canvas.width
|
|
418
|
-
*
|
|
419
|
-
* `canvas.
|
|
420
|
-
*
|
|
421
|
-
*
|
|
422
|
-
* `
|
|
423
|
-
*
|
|
424
|
-
*
|
|
425
|
-
* `
|
|
426
|
-
*
|
|
427
|
-
*
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
*
|
|
431
|
-
|
|
432
|
-
|
|
499
|
+
* Accepts either a `CanvasRenderingContext2D` (main thread) or an
|
|
500
|
+
* `OffscreenCanvasRenderingContext2D` (Worker / off-DOM rasterization).
|
|
501
|
+
* Both dispatch to the same Rust rasterizer; the dispatch happens at
|
|
502
|
+
* the JS boundary so neither context type is privileged.
|
|
503
|
+
*
|
|
504
|
+
* The painter owns `canvas.width` / `canvas.height` and writes them
|
|
505
|
+
* itself; consumers must not. The painter does not touch
|
|
506
|
+
* `canvas.style.*` — that's layout, owned by the consumer (see
|
|
507
|
+
* `PaintResult.layoutWidth` / `layoutHeight`).
|
|
508
|
+
*
|
|
509
|
+
* `opts.layoutScale` (default 1.0) is layout-space pixels per Typst
|
|
510
|
+
* point and determines the canvas's display-box size. `opts.densityScale`
|
|
511
|
+
* (default 1.0) is the rasterization density multiplier the consumer
|
|
512
|
+
* folds `window.devicePixelRatio`, in-app zoom, and
|
|
513
|
+
* `visualViewport.scale` (pinch-zoom) into. The effective
|
|
514
|
+
* rasterization scale is `layoutScale * densityScale`.
|
|
515
|
+
*
|
|
516
|
+
* If `layoutScale * densityScale` would exceed the safe backing-store
|
|
517
|
+
* maximum (16384 px per side), `densityScale` is clamped
|
|
518
|
+
* proportionally so the largest dimension fits. The actual
|
|
519
|
+
* backing-store dimensions are reported in the returned
|
|
520
|
+
* `PaintResult` — compare against
|
|
521
|
+
* `round(layoutWidth * densityScale)` to detect clamping.
|
|
522
|
+
*
|
|
523
|
+
* Each call resets the backing store (`paint` is always a full
|
|
524
|
+
* repaint). Consumers do not need to call `clearRect`.
|
|
525
|
+
*
|
|
526
|
+
* Throws when:
|
|
527
|
+
* - the backend does not support canvas preview (message includes the
|
|
528
|
+
* resolved `backendId`),
|
|
529
|
+
* - `page` is out of range,
|
|
530
|
+
* - `ctx` is neither `CanvasRenderingContext2D` nor
|
|
531
|
+
* `OffscreenCanvasRenderingContext2D`,
|
|
532
|
+
* - `opts.layoutScale` or `opts.densityScale` is non-finite or `<= 0`.
|
|
533
|
+
*/
|
|
534
|
+
paint(ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D, page: number, opts: PaintOptions | undefined): PaintResult;
|
|
433
535
|
/**
|
|
434
536
|
* Render all or selected pages from this session.
|
|
435
537
|
*/
|
|
436
538
|
render(opts?: RenderOptions | null): RenderResult;
|
|
437
539
|
/**
|
|
438
540
|
* The backend that produced this session (e.g. `"typst"`).
|
|
541
|
+
*
|
|
542
|
+
* Equal to the `backendId` of the [`Quill`] that opened this session
|
|
543
|
+
* (sessions inherit their quill's backend), so checking either is fine.
|
|
439
544
|
*/
|
|
440
545
|
readonly backendId: string;
|
|
441
546
|
/**
|
|
@@ -445,6 +550,14 @@ export class RenderSession {
|
|
|
445
550
|
* document is an immutable snapshot.
|
|
446
551
|
*/
|
|
447
552
|
readonly pageCount: number;
|
|
553
|
+
/**
|
|
554
|
+
* Whether this session's backend supports canvas preview.
|
|
555
|
+
*
|
|
556
|
+
* `true` iff [`paint`](Self::paint) and [`page_size`](Self::page_size)
|
|
557
|
+
* will succeed. Equal to `Quill.supportsCanvas` for the quill that
|
|
558
|
+
* opened this session.
|
|
559
|
+
*/
|
|
560
|
+
readonly supportsCanvas: boolean;
|
|
448
561
|
/**
|
|
449
562
|
* Session-level warnings attached at `quill.open(...)` time.
|
|
450
563
|
*
|
package/node-esm/wasm.js
CHANGED
|
@@ -689,6 +689,19 @@ export class Quill {
|
|
|
689
689
|
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
690
690
|
}
|
|
691
691
|
}
|
|
692
|
+
/**
|
|
693
|
+
* Whether this quill's backend supports canvas preview.
|
|
694
|
+
*
|
|
695
|
+
* `true` iff `RenderSession.paint` and `RenderSession.pageSize` will
|
|
696
|
+
* succeed for sessions opened by this quill. Use this as a precondition
|
|
697
|
+
* probe before mounting a canvas-based preview UI; the throw on `paint`
|
|
698
|
+
* remains the enforcement contract.
|
|
699
|
+
* @returns {boolean}
|
|
700
|
+
*/
|
|
701
|
+
get supportsCanvas() {
|
|
702
|
+
const ret = wasm.quill_supportsCanvas(this.__wbg_ptr);
|
|
703
|
+
return ret !== 0;
|
|
704
|
+
}
|
|
692
705
|
}
|
|
693
706
|
if (Symbol.dispose) Quill.prototype[Symbol.dispose] = Quill.prototype.free;
|
|
694
707
|
|
|
@@ -743,6 +756,21 @@ export class Quillmark {
|
|
|
743
756
|
}
|
|
744
757
|
if (Symbol.dispose) Quillmark.prototype[Symbol.dispose] = Quillmark.prototype.free;
|
|
745
758
|
|
|
759
|
+
/**
|
|
760
|
+
* An iterative render handle backed by an immutable compiled snapshot.
|
|
761
|
+
*
|
|
762
|
+
* Created via [`Quill::open`]. Holds the compiled output so that
|
|
763
|
+
* [`RenderSession::render`], [`RenderSession::paint`], and
|
|
764
|
+
* [`RenderSession::page_size`] can be called repeatedly without
|
|
765
|
+
* recompiling.
|
|
766
|
+
*
|
|
767
|
+
* **Empty documents.** A document that compiles to zero pages still
|
|
768
|
+
* produces a valid session (`pageCount === 0`). Iterating
|
|
769
|
+
* `0..pageCount` is then a no-op; calling `paint(ctx, 0)` or
|
|
770
|
+
* `pageSize(0)` throws `"... page index 0 out of range
|
|
771
|
+
* (pageCount=0)"`. Hosts that surface "no pages to preview" UI should
|
|
772
|
+
* branch on `pageCount === 0` rather than on a thrown error.
|
|
773
|
+
*/
|
|
746
774
|
export class RenderSession {
|
|
747
775
|
static __wrap(ptr) {
|
|
748
776
|
ptr = ptr >>> 0;
|
|
@@ -763,6 +791,9 @@ export class RenderSession {
|
|
|
763
791
|
}
|
|
764
792
|
/**
|
|
765
793
|
* The backend that produced this session (e.g. `"typst"`).
|
|
794
|
+
*
|
|
795
|
+
* Equal to the `backendId` of the [`Quill`] that opened this session
|
|
796
|
+
* (sessions inherit their quill's backend), so checking either is fine.
|
|
766
797
|
* @returns {string}
|
|
767
798
|
*/
|
|
768
799
|
get backendId() {
|
|
@@ -795,6 +826,11 @@ export class RenderSession {
|
|
|
795
826
|
/**
|
|
796
827
|
* Page dimensions in Typst points (1 pt = 1/72 inch).
|
|
797
828
|
*
|
|
829
|
+
* Report-only: the painter sizes the canvas itself based on
|
|
830
|
+
* `PaintOptions`. Exposed for consumers that need page geometry
|
|
831
|
+
* up-front (e.g. to lay out a scrollable list of canvases before
|
|
832
|
+
* any pixels are rendered).
|
|
833
|
+
*
|
|
798
834
|
* Stable for a given `page` across the session's lifetime — the
|
|
799
835
|
* compiled document is an immutable snapshot, so callers can cache
|
|
800
836
|
* results.
|
|
@@ -822,41 +858,58 @@ export class RenderSession {
|
|
|
822
858
|
/**
|
|
823
859
|
* Paint `page` into a 2D canvas context.
|
|
824
860
|
*
|
|
825
|
-
*
|
|
826
|
-
* `
|
|
827
|
-
*
|
|
861
|
+
* Accepts either a `CanvasRenderingContext2D` (main thread) or an
|
|
862
|
+
* `OffscreenCanvasRenderingContext2D` (Worker / off-DOM rasterization).
|
|
863
|
+
* Both dispatch to the same Rust rasterizer; the dispatch happens at
|
|
864
|
+
* the JS boundary so neither context type is privileged.
|
|
865
|
+
*
|
|
866
|
+
* The painter owns `canvas.width` / `canvas.height` and writes them
|
|
867
|
+
* itself; consumers must not. The painter does not touch
|
|
868
|
+
* `canvas.style.*` — that's layout, owned by the consumer (see
|
|
869
|
+
* `PaintResult.layoutWidth` / `layoutHeight`).
|
|
870
|
+
*
|
|
871
|
+
* `opts.layoutScale` (default 1.0) is layout-space pixels per Typst
|
|
872
|
+
* point and determines the canvas's display-box size. `opts.densityScale`
|
|
873
|
+
* (default 1.0) is the rasterization density multiplier the consumer
|
|
874
|
+
* folds `window.devicePixelRatio`, in-app zoom, and
|
|
875
|
+
* `visualViewport.scale` (pinch-zoom) into. The effective
|
|
876
|
+
* rasterization scale is `layoutScale * densityScale`.
|
|
828
877
|
*
|
|
829
|
-
*
|
|
830
|
-
*
|
|
831
|
-
*
|
|
832
|
-
*
|
|
833
|
-
*
|
|
834
|
-
*
|
|
835
|
-
* `ctx.clearRect(0, 0, canvas.width, canvas.height)` first to avoid
|
|
836
|
-
* stale pixels showing through transparent regions.
|
|
878
|
+
* If `layoutScale * densityScale` would exceed the safe backing-store
|
|
879
|
+
* maximum (16384 px per side), `densityScale` is clamped
|
|
880
|
+
* proportionally so the largest dimension fits. The actual
|
|
881
|
+
* backing-store dimensions are reported in the returned
|
|
882
|
+
* `PaintResult` — compare against
|
|
883
|
+
* `round(layoutWidth * densityScale)` to detect clamping.
|
|
837
884
|
*
|
|
838
|
-
*
|
|
839
|
-
* not
|
|
885
|
+
* Each call resets the backing store (`paint` is always a full
|
|
886
|
+
* repaint). Consumers do not need to call `clearRect`.
|
|
840
887
|
*
|
|
841
|
-
* Throws
|
|
842
|
-
*
|
|
843
|
-
*
|
|
844
|
-
*
|
|
888
|
+
* Throws when:
|
|
889
|
+
* - the backend does not support canvas preview (message includes the
|
|
890
|
+
* resolved `backendId`),
|
|
891
|
+
* - `page` is out of range,
|
|
892
|
+
* - `ctx` is neither `CanvasRenderingContext2D` nor
|
|
893
|
+
* `OffscreenCanvasRenderingContext2D`,
|
|
894
|
+
* - `opts.layoutScale` or `opts.densityScale` is non-finite or `<= 0`.
|
|
895
|
+
* @param {CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D} ctx
|
|
845
896
|
* @param {number} page
|
|
846
|
-
* @param {
|
|
897
|
+
* @param {PaintOptions | undefined} opts
|
|
898
|
+
* @returns {PaintResult}
|
|
847
899
|
*/
|
|
848
|
-
paint(ctx, page,
|
|
900
|
+
paint(ctx, page, opts) {
|
|
849
901
|
try {
|
|
850
902
|
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
851
|
-
wasm.rendersession_paint(retptr, this.__wbg_ptr,
|
|
903
|
+
wasm.rendersession_paint(retptr, this.__wbg_ptr, addHeapObject(ctx), page, addHeapObject(opts));
|
|
852
904
|
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
853
905
|
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
854
|
-
|
|
855
|
-
|
|
906
|
+
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
|
|
907
|
+
if (r2) {
|
|
908
|
+
throw takeObject(r1);
|
|
856
909
|
}
|
|
910
|
+
return takeObject(r0);
|
|
857
911
|
} finally {
|
|
858
912
|
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
859
|
-
heap[stack_pointer++] = undefined;
|
|
860
913
|
}
|
|
861
914
|
}
|
|
862
915
|
/**
|
|
@@ -879,6 +932,18 @@ export class RenderSession {
|
|
|
879
932
|
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
880
933
|
}
|
|
881
934
|
}
|
|
935
|
+
/**
|
|
936
|
+
* Whether this session's backend supports canvas preview.
|
|
937
|
+
*
|
|
938
|
+
* `true` iff [`paint`](Self::paint) and [`page_size`](Self::page_size)
|
|
939
|
+
* will succeed. Equal to `Quill.supportsCanvas` for the quill that
|
|
940
|
+
* opened this session.
|
|
941
|
+
* @returns {boolean}
|
|
942
|
+
*/
|
|
943
|
+
get supportsCanvas() {
|
|
944
|
+
const ret = wasm.rendersession_supportsCanvas(this.__wbg_ptr);
|
|
945
|
+
return ret !== 0;
|
|
946
|
+
}
|
|
882
947
|
/**
|
|
883
948
|
* Session-level warnings attached at `quill.open(...)` time.
|
|
884
949
|
*
|
|
@@ -1004,6 +1069,14 @@ function __wbg_get_imports() {
|
|
|
1004
1069
|
const ret = getObject(arg0).call(getObject(arg1));
|
|
1005
1070
|
return addHeapObject(ret);
|
|
1006
1071
|
}, arguments); },
|
|
1072
|
+
__wbg_canvas_2c0c6d263d4c52ad: function(arg0) {
|
|
1073
|
+
const ret = getObject(arg0).canvas;
|
|
1074
|
+
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
|
1075
|
+
},
|
|
1076
|
+
__wbg_canvas_374da9f3c5b3dd0e: function(arg0) {
|
|
1077
|
+
const ret = getObject(arg0).canvas;
|
|
1078
|
+
return addHeapObject(ret);
|
|
1079
|
+
},
|
|
1007
1080
|
__wbg_done_9158f7cc8751ba32: function(arg0) {
|
|
1008
1081
|
const ret = getObject(arg0).done;
|
|
1009
1082
|
return ret;
|
|
@@ -1080,6 +1153,16 @@ function __wbg_get_imports() {
|
|
|
1080
1153
|
const ret = result;
|
|
1081
1154
|
return ret;
|
|
1082
1155
|
},
|
|
1156
|
+
__wbg_instanceof_CanvasRenderingContext2d_24a3fe06e62b98d7: function(arg0) {
|
|
1157
|
+
let result;
|
|
1158
|
+
try {
|
|
1159
|
+
result = getObject(arg0) instanceof CanvasRenderingContext2D;
|
|
1160
|
+
} catch (_) {
|
|
1161
|
+
result = false;
|
|
1162
|
+
}
|
|
1163
|
+
const ret = result;
|
|
1164
|
+
return ret;
|
|
1165
|
+
},
|
|
1083
1166
|
__wbg_instanceof_Map_1b76fd4635be43eb: function(arg0) {
|
|
1084
1167
|
let result;
|
|
1085
1168
|
try {
|
|
@@ -1090,6 +1173,16 @@ function __wbg_get_imports() {
|
|
|
1090
1173
|
const ret = result;
|
|
1091
1174
|
return ret;
|
|
1092
1175
|
},
|
|
1176
|
+
__wbg_instanceof_OffscreenCanvasRenderingContext2d_285a274020b4f230: function(arg0) {
|
|
1177
|
+
let result;
|
|
1178
|
+
try {
|
|
1179
|
+
result = getObject(arg0) instanceof OffscreenCanvasRenderingContext2D;
|
|
1180
|
+
} catch (_) {
|
|
1181
|
+
result = false;
|
|
1182
|
+
}
|
|
1183
|
+
const ret = result;
|
|
1184
|
+
return ret;
|
|
1185
|
+
},
|
|
1093
1186
|
__wbg_instanceof_Uint8Array_152ba1f289edcf3f: function(arg0) {
|
|
1094
1187
|
let result;
|
|
1095
1188
|
try {
|
|
@@ -1174,6 +1267,9 @@ function __wbg_get_imports() {
|
|
|
1174
1267
|
__wbg_putImageData_c810e62ea70e761d: function() { return handleError(function (arg0, arg1, arg2, arg3) {
|
|
1175
1268
|
getObject(arg0).putImageData(getObject(arg1), arg2, arg3);
|
|
1176
1269
|
}, arguments); },
|
|
1270
|
+
__wbg_putImageData_cb4de9afd58963be: function() { return handleError(function (arg0, arg1, arg2, arg3) {
|
|
1271
|
+
getObject(arg0).putImageData(getObject(arg1), arg2, arg3);
|
|
1272
|
+
}, arguments); },
|
|
1177
1273
|
__wbg_set_022bee52d0b05b19: function() { return handleError(function (arg0, arg1, arg2) {
|
|
1178
1274
|
const ret = Reflect.set(getObject(arg0), getObject(arg1), getObject(arg2));
|
|
1179
1275
|
return ret;
|
|
@@ -1191,6 +1287,18 @@ function __wbg_get_imports() {
|
|
|
1191
1287
|
const ret = getObject(arg0).set(getObject(arg1), getObject(arg2));
|
|
1192
1288
|
return addHeapObject(ret);
|
|
1193
1289
|
},
|
|
1290
|
+
__wbg_set_height_24d07d982f176ac6: function(arg0, arg1) {
|
|
1291
|
+
getObject(arg0).height = arg1 >>> 0;
|
|
1292
|
+
},
|
|
1293
|
+
__wbg_set_height_be9b2b920bd68401: function(arg0, arg1) {
|
|
1294
|
+
getObject(arg0).height = arg1 >>> 0;
|
|
1295
|
+
},
|
|
1296
|
+
__wbg_set_width_5cda41d4d06a14dd: function(arg0, arg1) {
|
|
1297
|
+
getObject(arg0).width = arg1 >>> 0;
|
|
1298
|
+
},
|
|
1299
|
+
__wbg_set_width_adc925bca9c5351a: function(arg0, arg1) {
|
|
1300
|
+
getObject(arg0).width = arg1 >>> 0;
|
|
1301
|
+
},
|
|
1194
1302
|
__wbg_stack_3b0d974bbf31e44f: function(arg0, arg1) {
|
|
1195
1303
|
const ret = getObject(arg1).stack;
|
|
1196
1304
|
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
@@ -1269,12 +1377,6 @@ function _assertClass(instance, klass) {
|
|
|
1269
1377
|
}
|
|
1270
1378
|
}
|
|
1271
1379
|
|
|
1272
|
-
function addBorrowedObject(obj) {
|
|
1273
|
-
if (stack_pointer == 1) throw new Error('out of js stack');
|
|
1274
|
-
heap[--stack_pointer] = obj;
|
|
1275
|
-
return stack_pointer;
|
|
1276
|
-
}
|
|
1277
|
-
|
|
1278
1380
|
function debugString(val) {
|
|
1279
1381
|
// primitive types
|
|
1280
1382
|
const type = typeof val;
|
|
@@ -1441,8 +1543,6 @@ function passStringToWasm0(arg, malloc, realloc) {
|
|
|
1441
1543
|
return ptr;
|
|
1442
1544
|
}
|
|
1443
1545
|
|
|
1444
|
-
let stack_pointer = 1024;
|
|
1445
|
-
|
|
1446
1546
|
function takeObject(idx) {
|
|
1447
1547
|
const ret = getObject(idx);
|
|
1448
1548
|
dropObject(idx);
|
package/node-esm/wasm_bg.wasm
CHANGED
|
Binary file
|
|
@@ -35,6 +35,7 @@ export const quill_form: (a: number, b: number, c: number) => void;
|
|
|
35
35
|
export const quill_metadata: (a: number) => number;
|
|
36
36
|
export const quill_open: (a: number, b: number, c: number) => void;
|
|
37
37
|
export const quill_render: (a: number, b: number, c: number, d: number) => void;
|
|
38
|
+
export const quill_supportsCanvas: (a: number) => number;
|
|
38
39
|
export const quillmark_new: () => number;
|
|
39
40
|
export const quillmark_quill: (a: number, b: number, c: number) => void;
|
|
40
41
|
export const rendersession_backendId: (a: number, b: number) => void;
|
|
@@ -42,6 +43,7 @@ export const rendersession_pageCount: (a: number) => number;
|
|
|
42
43
|
export const rendersession_pageSize: (a: number, b: number, c: number) => void;
|
|
43
44
|
export const rendersession_paint: (a: number, b: number, c: number, d: number, e: number) => void;
|
|
44
45
|
export const rendersession_render: (a: number, b: number, c: number) => void;
|
|
46
|
+
export const rendersession_supportsCanvas: (a: number) => number;
|
|
45
47
|
export const rendersession_warnings: (a: number) => number;
|
|
46
48
|
export const lut_inverse_interp16: (a: number, b: number, c: number) => number;
|
|
47
49
|
export const qcms_profile_precache_output_transform: (a: number) => void;
|