@quillmark/wasm 0.67.0 → 0.69.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 +84 -32
- package/bundler/wasm.d.ts +247 -27
- package/bundler/wasm_bg.js +135 -35
- package/bundler/wasm_bg.wasm +0 -0
- package/bundler/wasm_bg.wasm.d.ts +2 -0
- package/package.json +7 -10
- package/node-esm/wasm.d.ts +0 -464
- package/node-esm/wasm.js +0 -1477
- package/node-esm/wasm_bg.wasm +0 -0
- package/node-esm/wasm_bg.wasm.d.ts +0 -64
package/README.md
CHANGED
|
@@ -79,53 +79,89 @@ 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.form(doc)`
|
|
83
|
+
|
|
84
|
+
Returns `{ main, cards, diagnostics }` — a schema-aware snapshot of `doc`
|
|
85
|
+
without invoking the backend. `diagnostics` contains validation errors and
|
|
86
|
+
warnings; an empty array means the document is valid. Useful for validating
|
|
87
|
+
content without rendering:
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
const form = quill.form(Document.fromMarkdown(markdown));
|
|
91
|
+
const errors = form.diagnostics.filter(d => d.severity === "error");
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### `quill.render(parsed, opts?)` vs. `quill.open(parsed)`
|
|
95
|
+
|
|
96
|
+
Use **`Quill.render`** for one-shot exports (PDF/SVG/PNG) — compiles, emits
|
|
97
|
+
artifacts, done. Use **`RenderSession`** (returned by `Quill.open`) for
|
|
98
|
+
reactive previews where you'll paint or re-emit pages multiple times: the
|
|
99
|
+
session retains the compiled snapshot so subsequent `paint` / `render`
|
|
100
|
+
calls skip recompilation. Don't open a session per export.
|
|
101
|
+
|
|
82
102
|
### `quill.render(parsed, opts?)`
|
|
83
103
|
Render with a pre-parsed `Document`.
|
|
84
104
|
|
|
85
105
|
### `quill.open(parsed)` + `session.render(opts?)`
|
|
86
106
|
Open once, render all or selected pages (`opts.pages`).
|
|
87
107
|
|
|
88
|
-
The session also exposes `pageCount`, `backendId`, `
|
|
89
|
-
session-level diagnostics attached at `open` time),
|
|
90
|
-
`paint(ctx, page,
|
|
108
|
+
The session also exposes `pageCount`, `backendId`, `supportsCanvas`,
|
|
109
|
+
`warnings` (snapshot of session-level diagnostics attached at `open` time),
|
|
110
|
+
`pageSize(page)`, and `paint(ctx, page, opts?)` for canvas previews. See
|
|
111
|
+
below.
|
|
112
|
+
|
|
113
|
+
A document that compiles to zero pages still produces a valid session
|
|
114
|
+
(`pageCount === 0`); `paint(ctx, 0)` and `pageSize(0)` then throw
|
|
115
|
+
`page index 0 out of range (pageCount=0)`. Branch on `pageCount === 0` to
|
|
116
|
+
render a "no pages to preview" UI without relying on the throw.
|
|
91
117
|
|
|
92
118
|
### Canvas Preview (Typst only)
|
|
93
119
|
|
|
94
|
-
`session.paint(ctx, page,
|
|
95
|
-
`CanvasRenderingContext2D
|
|
96
|
-
`
|
|
120
|
+
`session.paint(ctx, page, opts?)` rasterizes a page directly into a
|
|
121
|
+
`CanvasRenderingContext2D` (main thread) or
|
|
122
|
+
`OffscreenCanvasRenderingContext2D` (Worker), skipping PNG/SVG byte
|
|
123
|
+
round-trips.
|
|
124
|
+
|
|
125
|
+
The painter owns `canvas.width` / `canvas.height` — it sizes the backing
|
|
126
|
+
store itself. Consumers own `canvas.style.*` (or the layout system that
|
|
127
|
+
sets them) and read `layoutWidth` / `layoutHeight` from the returned
|
|
128
|
+
`PaintResult`.
|
|
97
129
|
|
|
98
130
|
```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);
|
|
131
|
+
const result = session.paint(canvas.getContext("2d"), 0, {
|
|
132
|
+
layoutScale: 1, // layout px per Typst pt
|
|
133
|
+
densityScale: window.devicePixelRatio, // backing-store density
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
canvas.style.width = `${result.layoutWidth}px`;
|
|
137
|
+
canvas.style.height = `${result.layoutHeight}px`;
|
|
114
138
|
```
|
|
115
139
|
|
|
116
|
-
- `
|
|
117
|
-
|
|
118
|
-
|
|
140
|
+
- `layoutScale` (default 1) sets the canvas's display-box size:
|
|
141
|
+
`layoutWidth = widthPt * layoutScale`. For on-screen canvases this is
|
|
142
|
+
CSS pixels per Typst point. Defaults to 1 (one CSS pixel per pt).
|
|
143
|
+
- `densityScale` (default 1) is the backing-store density multiplier.
|
|
144
|
+
Fold `window.devicePixelRatio`, in-app zoom, and `visualViewport.scale`
|
|
145
|
+
(pinch-zoom) into a single value here. Pass `devicePixelRatio` for
|
|
146
|
+
crisp output on high-DPI displays.
|
|
147
|
+
- The effective rasterization scale is `layoutScale * densityScale`. If
|
|
148
|
+
that would exceed the safe maximum (16384 px per side), `densityScale`
|
|
149
|
+
is clamped proportionally; compare `result.pixelWidth` against
|
|
150
|
+
`Math.round(result.layoutWidth * densityScale)` to detect.
|
|
151
|
+
- `paint` is always a full repaint — setting the backing-store width /
|
|
152
|
+
height clears it. No `clearRect` required.
|
|
119
153
|
- `pageCount` and `pageSize(page)` are stable for the session's
|
|
120
154
|
lifetime (immutable snapshot) — cache them.
|
|
121
|
-
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
- Backend support:
|
|
127
|
-
|
|
128
|
-
`
|
|
155
|
+
- Worker support: pass an `OffscreenCanvasRenderingContext2D` and the
|
|
156
|
+
same call signature works. `layoutWidth` / `layoutHeight` are
|
|
157
|
+
informational in that mode (no CSS layout box); fold everything into
|
|
158
|
+
`densityScale`. Loading the WASM module inside a Worker is the host's
|
|
159
|
+
responsibility.
|
|
160
|
+
- Backend support: gated by `supportsCanvas`. Probe upfront with
|
|
161
|
+
`quill.supportsCanvas` (or `session.supportsCanvas`) before mounting a
|
|
162
|
+
canvas-based UI; the throw on `paint` / `pageSize` remains the
|
|
163
|
+
enforcement contract and includes the resolved `backendId` for
|
|
164
|
+
debugging.
|
|
129
165
|
|
|
130
166
|
### Errors
|
|
131
167
|
|
|
@@ -160,6 +196,22 @@ without manual `.free()` discipline. `.free()` is still emitted as an eager
|
|
|
160
196
|
teardown hook for callers that want deterministic release. Requires
|
|
161
197
|
Node 14.6+ / current evergreen browsers (all supported targets).
|
|
162
198
|
|
|
199
|
+
For environments where `using` (the [explicit resource management][erm]
|
|
200
|
+
proposal) hasn't landed, use an explicit `try` / `finally`:
|
|
201
|
+
|
|
202
|
+
```ts
|
|
203
|
+
const session = quill.open(doc);
|
|
204
|
+
try {
|
|
205
|
+
for (let p = 0; p < session.pageCount; p++) {
|
|
206
|
+
session.paint(ctx, p);
|
|
207
|
+
}
|
|
208
|
+
} finally {
|
|
209
|
+
session.free();
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
[erm]: https://github.com/tc39/proposal-explicit-resource-management
|
|
214
|
+
|
|
163
215
|
## Notes
|
|
164
216
|
|
|
165
217
|
- Parsed markdown requires top-level `QUILL` in frontmatter. Empty input
|
package/bundler/wasm.d.ts
CHANGED
|
@@ -17,14 +17,179 @@ 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
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
/** UI layout hints for a single field. */
|
|
89
|
+
export interface QuillFieldUi {
|
|
90
|
+
group?: string;
|
|
91
|
+
order?: number;
|
|
92
|
+
compact?: boolean;
|
|
93
|
+
multiline?: boolean;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** UI layout hints for a card (main or named card type). */
|
|
97
|
+
export interface QuillCardUi {
|
|
98
|
+
hide_body?: boolean;
|
|
99
|
+
default_title?: string;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Schema entry for a single field declared in a quill's `Quill.yaml`. */
|
|
103
|
+
export interface QuillFieldSchema {
|
|
104
|
+
type: "string" | "number" | "integer" | "boolean" | "array" | "object" | "date" | "datetime" | "markdown";
|
|
105
|
+
title?: string;
|
|
106
|
+
description?: string;
|
|
107
|
+
default?: unknown;
|
|
108
|
+
examples?: unknown;
|
|
109
|
+
required?: boolean;
|
|
110
|
+
enum?: string[];
|
|
111
|
+
ui?: QuillFieldUi;
|
|
112
|
+
properties?: Record<string, QuillFieldSchema>;
|
|
113
|
+
items?: QuillFieldSchema;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Schema entry for the main card or a named card type. */
|
|
117
|
+
export interface QuillCardSchema {
|
|
118
|
+
title?: string;
|
|
119
|
+
description?: string;
|
|
120
|
+
fields: Record<string, QuillFieldSchema>;
|
|
121
|
+
ui?: QuillCardUi;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Public schema contract returned as `QuillMetadata.schema`.
|
|
126
|
+
*
|
|
127
|
+
* Identical to `QuillConfig::public_schema()` on the Rust side.
|
|
128
|
+
*/
|
|
129
|
+
export interface QuillSchema {
|
|
130
|
+
name: string;
|
|
131
|
+
main: QuillCardSchema;
|
|
132
|
+
/** Present only when the quill declares at least one named card type. */
|
|
133
|
+
card_types?: Record<string, QuillCardSchema>;
|
|
134
|
+
/** The quill's bundled example document, if declared. */
|
|
135
|
+
example?: string;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Read-only snapshot of the loaded quill's engine info and declared schema.
|
|
140
|
+
* Returned by `Quill.metadata`.
|
|
141
|
+
*
|
|
142
|
+
* Well-known keys are strongly typed; any additional keys declared under
|
|
143
|
+
* `quill:` in `Quill.yaml` appear as `unknown`.
|
|
144
|
+
*/
|
|
145
|
+
export interface QuillMetadata {
|
|
146
|
+
schema: QuillSchema;
|
|
147
|
+
backend: string;
|
|
148
|
+
version: string;
|
|
149
|
+
author: string;
|
|
150
|
+
description: string;
|
|
151
|
+
supportedFormats: OutputFormat[];
|
|
152
|
+
[key: string]: unknown;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** Source of a field's effective value in a form view. */
|
|
156
|
+
export type FormFieldSource = "document" | "default" | "missing";
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* A single field's view within a `FormCard`.
|
|
160
|
+
*
|
|
161
|
+
* - `value` — the document-supplied value (`null` when absent).
|
|
162
|
+
* - `default` — the schema default (`null` when no default is declared).
|
|
163
|
+
* - `source` — where the effective value comes from.
|
|
164
|
+
*/
|
|
165
|
+
export interface FormFieldValue {
|
|
166
|
+
value: unknown;
|
|
167
|
+
default: unknown;
|
|
168
|
+
source: FormFieldSource;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* A card viewed through its schema, as returned by `Quill.form`,
|
|
173
|
+
* `Quill.blankMain`, and `Quill.blankCard`.
|
|
174
|
+
*/
|
|
175
|
+
export interface FormCard {
|
|
176
|
+
schema: QuillCardSchema;
|
|
177
|
+
values: Record<string, FormFieldValue>;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Schema-aware form view of a document, returned by `Quill.form`.
|
|
182
|
+
*
|
|
183
|
+
* - `main` — the main card viewed through the quill's main schema.
|
|
184
|
+
* - `cards` — composable card blocks, in document order (unknown tags excluded).
|
|
185
|
+
* - `diagnostics` — diagnostics from unknown card tags and validation.
|
|
186
|
+
*/
|
|
187
|
+
export interface Form {
|
|
188
|
+
main: FormCard;
|
|
189
|
+
cards: FormCard[];
|
|
190
|
+
diagnostics: Diagnostic[];
|
|
191
|
+
}
|
|
192
|
+
|
|
28
193
|
|
|
29
194
|
export interface Artifact {
|
|
30
195
|
format: OutputFormat;
|
|
@@ -299,7 +464,7 @@ export class Quill {
|
|
|
299
464
|
*
|
|
300
465
|
* [`Form::cards`]: quillmark::form::Form::cards
|
|
301
466
|
*/
|
|
302
|
-
blankCard(card_type: string):
|
|
467
|
+
blankCard(card_type: string): FormCard | null;
|
|
303
468
|
/**
|
|
304
469
|
* A blank form for the main card — no document values supplied.
|
|
305
470
|
*
|
|
@@ -309,7 +474,7 @@ export class Quill {
|
|
|
309
474
|
*
|
|
310
475
|
* [`Form::main`]: quillmark::form::Form::main
|
|
311
476
|
*/
|
|
312
|
-
blankMain():
|
|
477
|
+
blankMain(): FormCard;
|
|
313
478
|
/**
|
|
314
479
|
* The schema-aware form view of `doc`.
|
|
315
480
|
*
|
|
@@ -329,7 +494,7 @@ export class Quill {
|
|
|
329
494
|
*
|
|
330
495
|
* [`Form`]: quillmark::form::Form
|
|
331
496
|
*/
|
|
332
|
-
form(doc: Document):
|
|
497
|
+
form(doc: Document): Form;
|
|
333
498
|
/**
|
|
334
499
|
* Open an iterative render session for page-selective rendering.
|
|
335
500
|
*/
|
|
@@ -367,7 +532,16 @@ export class Quill {
|
|
|
367
532
|
* Equivalent by value for the lifetime of the handle; the quill is
|
|
368
533
|
* immutable once constructed.
|
|
369
534
|
*/
|
|
370
|
-
readonly metadata:
|
|
535
|
+
readonly metadata: QuillMetadata;
|
|
536
|
+
/**
|
|
537
|
+
* Whether this quill's backend supports canvas preview.
|
|
538
|
+
*
|
|
539
|
+
* `true` iff `RenderSession.paint` and `RenderSession.pageSize` will
|
|
540
|
+
* succeed for sessions opened by this quill. Use this as a precondition
|
|
541
|
+
* probe before mounting a canvas-based preview UI; the throw on `paint`
|
|
542
|
+
* remains the enforcement contract.
|
|
543
|
+
*/
|
|
544
|
+
readonly supportsCanvas: boolean;
|
|
371
545
|
}
|
|
372
546
|
|
|
373
547
|
/**
|
|
@@ -391,6 +565,21 @@ export class Quillmark {
|
|
|
391
565
|
quill(tree: Map<string, Uint8Array>): Quill;
|
|
392
566
|
}
|
|
393
567
|
|
|
568
|
+
/**
|
|
569
|
+
* An iterative render handle backed by an immutable compiled snapshot.
|
|
570
|
+
*
|
|
571
|
+
* Created via [`Quill::open`]. Holds the compiled output so that
|
|
572
|
+
* [`RenderSession::render`], [`RenderSession::paint`], and
|
|
573
|
+
* [`RenderSession::page_size`] can be called repeatedly without
|
|
574
|
+
* recompiling.
|
|
575
|
+
*
|
|
576
|
+
* **Empty documents.** A document that compiles to zero pages still
|
|
577
|
+
* produces a valid session (`pageCount === 0`). Iterating
|
|
578
|
+
* `0..pageCount` is then a no-op; calling `paint(ctx, 0)` or
|
|
579
|
+
* `pageSize(0)` throws `"... page index 0 out of range
|
|
580
|
+
* (pageCount=0)"`. Hosts that surface "no pages to preview" UI should
|
|
581
|
+
* branch on `pageCount === 0` rather than on a thrown error.
|
|
582
|
+
*/
|
|
394
583
|
export class RenderSession {
|
|
395
584
|
private constructor();
|
|
396
585
|
free(): void;
|
|
@@ -398,6 +587,11 @@ export class RenderSession {
|
|
|
398
587
|
/**
|
|
399
588
|
* Page dimensions in Typst points (1 pt = 1/72 inch).
|
|
400
589
|
*
|
|
590
|
+
* Report-only: the painter sizes the canvas itself based on
|
|
591
|
+
* `PaintOptions`. Exposed for consumers that need page geometry
|
|
592
|
+
* up-front (e.g. to lay out a scrollable list of canvases before
|
|
593
|
+
* any pixels are rendered).
|
|
594
|
+
*
|
|
401
595
|
* Stable for a given `page` across the session's lifetime — the
|
|
402
596
|
* compiled document is an immutable snapshot, so callers can cache
|
|
403
597
|
* results.
|
|
@@ -409,33 +603,51 @@ export class RenderSession {
|
|
|
409
603
|
/**
|
|
410
604
|
* Paint `page` into a 2D canvas context.
|
|
411
605
|
*
|
|
412
|
-
*
|
|
413
|
-
* `
|
|
414
|
-
*
|
|
415
|
-
*
|
|
416
|
-
*
|
|
417
|
-
* `canvas.width
|
|
418
|
-
*
|
|
419
|
-
* `canvas.
|
|
420
|
-
*
|
|
421
|
-
*
|
|
422
|
-
* `
|
|
423
|
-
*
|
|
424
|
-
*
|
|
425
|
-
* `
|
|
426
|
-
*
|
|
427
|
-
*
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
*
|
|
431
|
-
|
|
432
|
-
|
|
606
|
+
* Accepts either a `CanvasRenderingContext2D` (main thread) or an
|
|
607
|
+
* `OffscreenCanvasRenderingContext2D` (Worker / off-DOM rasterization).
|
|
608
|
+
* Both dispatch to the same Rust rasterizer; the dispatch happens at
|
|
609
|
+
* the JS boundary so neither context type is privileged.
|
|
610
|
+
*
|
|
611
|
+
* The painter owns `canvas.width` / `canvas.height` and writes them
|
|
612
|
+
* itself; consumers must not. The painter does not touch
|
|
613
|
+
* `canvas.style.*` — that's layout, owned by the consumer (see
|
|
614
|
+
* `PaintResult.layoutWidth` / `layoutHeight`).
|
|
615
|
+
*
|
|
616
|
+
* `opts.layoutScale` (default 1.0) is layout-space pixels per Typst
|
|
617
|
+
* point and determines the canvas's display-box size. `opts.densityScale`
|
|
618
|
+
* (default 1.0) is the rasterization density multiplier the consumer
|
|
619
|
+
* folds `window.devicePixelRatio`, in-app zoom, and
|
|
620
|
+
* `visualViewport.scale` (pinch-zoom) into. The effective
|
|
621
|
+
* rasterization scale is `layoutScale * densityScale`.
|
|
622
|
+
*
|
|
623
|
+
* If `layoutScale * densityScale` would exceed the safe backing-store
|
|
624
|
+
* maximum (16384 px per side), `densityScale` is clamped
|
|
625
|
+
* proportionally so the largest dimension fits. The actual
|
|
626
|
+
* backing-store dimensions are reported in the returned
|
|
627
|
+
* `PaintResult` — compare against
|
|
628
|
+
* `round(layoutWidth * densityScale)` to detect clamping.
|
|
629
|
+
*
|
|
630
|
+
* Each call resets the backing store (`paint` is always a full
|
|
631
|
+
* repaint). Consumers do not need to call `clearRect`.
|
|
632
|
+
*
|
|
633
|
+
* Throws when:
|
|
634
|
+
* - the backend does not support canvas preview (message includes the
|
|
635
|
+
* resolved `backendId`),
|
|
636
|
+
* - `page` is out of range,
|
|
637
|
+
* - `ctx` is neither `CanvasRenderingContext2D` nor
|
|
638
|
+
* `OffscreenCanvasRenderingContext2D`,
|
|
639
|
+
* - `opts.layoutScale` or `opts.densityScale` is non-finite or `<= 0`.
|
|
640
|
+
*/
|
|
641
|
+
paint(ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D, page: number, opts: PaintOptions | undefined): PaintResult;
|
|
433
642
|
/**
|
|
434
643
|
* Render all or selected pages from this session.
|
|
435
644
|
*/
|
|
436
645
|
render(opts?: RenderOptions | null): RenderResult;
|
|
437
646
|
/**
|
|
438
647
|
* The backend that produced this session (e.g. `"typst"`).
|
|
648
|
+
*
|
|
649
|
+
* Equal to the `backendId` of the [`Quill`] that opened this session
|
|
650
|
+
* (sessions inherit their quill's backend), so checking either is fine.
|
|
439
651
|
*/
|
|
440
652
|
readonly backendId: string;
|
|
441
653
|
/**
|
|
@@ -445,6 +657,14 @@ export class RenderSession {
|
|
|
445
657
|
* document is an immutable snapshot.
|
|
446
658
|
*/
|
|
447
659
|
readonly pageCount: number;
|
|
660
|
+
/**
|
|
661
|
+
* Whether this session's backend supports canvas preview.
|
|
662
|
+
*
|
|
663
|
+
* `true` iff [`paint`](Self::paint) and [`page_size`](Self::page_size)
|
|
664
|
+
* will succeed. Equal to `Quill.supportsCanvas` for the quill that
|
|
665
|
+
* opened this session.
|
|
666
|
+
*/
|
|
667
|
+
readonly supportsCanvas: boolean;
|
|
448
668
|
/**
|
|
449
669
|
* Session-level warnings attached at `quill.open(...)` time.
|
|
450
670
|
*
|