@weasel-js/svg 1.6.1 → 1.7.1
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 +71 -0
- package/dist/index.d.ts +217 -16
- package/dist/index.js +1135 -482
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -66,6 +66,14 @@ That cuts both ways on import: a `fill="url(#mesh1) #c04a3f"` from Inkscape,
|
|
|
66
66
|
whose mesh gradients this package does not model, imports as flat `#c04a3f`
|
|
67
67
|
rather than as a dropped fill.
|
|
68
68
|
|
|
69
|
+
`serializeSvg` is synchronous, so a kind loaded on demand (`mesh-gradient`, or
|
|
70
|
+
one declared with `registerPaintKindLoader`) that has not landed yet has no
|
|
71
|
+
`toSvg` to call, and its def is left out with a warning. `await warmSvg(nodes)`
|
|
72
|
+
first loads the kinds those nodes paint with, and the faces a sub- or
|
|
73
|
+
superscript run with its own `baselineShift` takes its size from — nothing
|
|
74
|
+
else, so an unrelated kind that fails to load cannot fail the export.
|
|
75
|
+
`svgNeeds(nodes)` lists the same things without loading them.
|
|
76
|
+
|
|
69
77
|
### A gradient's blend space
|
|
70
78
|
|
|
71
79
|
A gradient's `interpolate` — `'oklab'` or `'oklch'` — has no SVG spelling
|
|
@@ -83,6 +91,69 @@ gradient — it just blends the stops in sRGB, which moves the midpoint rather
|
|
|
83
91
|
than losing the paint. A space this package does not know is dropped on import
|
|
84
92
|
rather than carried through.
|
|
85
93
|
|
|
94
|
+
## Scene nodes, both ways
|
|
95
|
+
|
|
96
|
+
`svgNodesToKitDrafts(parseSvg(text), nextId)` lowers a document to scene-node
|
|
97
|
+
drafts the kit's built-in path, text and image painters draw, and registers
|
|
98
|
+
the document's markers. Containers carry no opacity, so an element or group
|
|
99
|
+
`opacity` is multiplied into the paints of the leaves under it. `nextId` is
|
|
100
|
+
handed the node each id is for, and `options.leaf` maps each leaf's kit data
|
|
101
|
+
into data of your own shape, from the source node's metadata too.
|
|
102
|
+
|
|
103
|
+
`svgNodesFromKit(scene)` goes the other way: containers become groups, and
|
|
104
|
+
each leaf is written the way its painter draws it, with the pose baked into
|
|
105
|
+
the geometry and box-relative paints resolved into that box. Hand
|
|
106
|
+
`serializeSvg` the result. Options pick the roots, skip nodes (a hidden
|
|
107
|
+
layer), replace a leaf's lowering or decorate a group. The per-leaf pieces are
|
|
108
|
+
public too: `svgLeafFromKit`, `svgPaintFromKit`, `svgStrokeFromKit`,
|
|
109
|
+
`svgImageFromKit`.
|
|
110
|
+
|
|
111
|
+
## Stroke markers
|
|
112
|
+
|
|
113
|
+
A marker reference goes out as `marker-start` / `-mid` / `-end="url(#id)"` with
|
|
114
|
+
one `<marker>` def per distinct reference. The path keeps its full-length `d`:
|
|
115
|
+
baking the kit's inset in would have a re-import trim the line a second time.
|
|
116
|
+
The cost is that other renderers draw the line under a hollow head.
|
|
117
|
+
|
|
118
|
+
| Reference | Def id | What the def carries |
|
|
119
|
+
|---|---|---|
|
|
120
|
+
| `'arrow'` | `arrow` | `markerUnits="strokeWidth"` |
|
|
121
|
+
| `{ key: 'arrow', size: 3 }` | `arrow-s3` | `markerUnits="userSpaceOnUse"`, `wzl:key="arrow"`, `wzl:size="3"` |
|
|
122
|
+
| `{ key: 'arrow', size: { px: 6 } }` | `arrow-s6px` | the same, drawn at 6 user units, `wzl:size="6px"` |
|
|
123
|
+
|
|
124
|
+
Any entry with a nonzero inset adds `wzl:inset` in marker units, and the root
|
|
125
|
+
declares the `wzl` namespace whenever one of these attributes appears. `orient`
|
|
126
|
+
is `auto-start-reverse`, because the kit turns every start head around, or an
|
|
127
|
+
entry's fixed angle in degrees. An entry with its own `toSvg` writes its own
|
|
128
|
+
def and gets none of the `wzl` attributes (a sized reference to one warns). A
|
|
129
|
+
reference to a key nothing registered writes no attribute.
|
|
130
|
+
|
|
131
|
+
On import, `url(#id)` naming a registered key reads back as that key, so an
|
|
132
|
+
unsized built-in needs no def. A def with `wzl:key` and `wzl:size` reads back
|
|
133
|
+
as that sized reference, registering the def's geometry under the key if
|
|
134
|
+
nothing else has. Any other `<marker>` becomes an entry in
|
|
135
|
+
`ParseResult.markers`, keyed by its id plus a hash of what it draws, and
|
|
136
|
+
`svgNodesToKitDrafts` registers it. It is minted per reference rather than per
|
|
137
|
+
def, because a `userSpaceOnUse` size and an `orient="auto"` start both depend on
|
|
138
|
+
the referencing stroke. `wzl:inset` restores the inset; without it the inset is
|
|
139
|
+
0. A reference to a marker neither registered nor defined warns and is dropped.
|
|
140
|
+
|
|
141
|
+
## Stylesheets
|
|
142
|
+
|
|
143
|
+
`<style>` rules cascade with the presentation attributes and `style=""`. A parse
|
|
144
|
+
is one static render, so `@media` and `<style media>` are answered once, against
|
|
145
|
+
a fixed environment: a `screen` whose viewport is the root's `width`/`height`
|
|
146
|
+
(else its `viewBox`, else 300 × 150), `prefers-color-scheme: light`, and no
|
|
147
|
+
hover or pointer. Pass `parseSvg(svg, { media: { prefersColorScheme: 'dark',
|
|
148
|
+
width: 1200 } })` to render for different media; `evaluateMediaQuery` answers a
|
|
149
|
+
query against the same environment.
|
|
150
|
+
|
|
151
|
+
`@supports` asks whether this parser honors a declaration, not whether a browser
|
|
152
|
+
parses it: `(fill: red)` holds, `(display: grid)` and `(clip-path: url(#c))` do
|
|
153
|
+
not, because nothing reads them from a stylesheet. `@import` is not fetched, and
|
|
154
|
+
each one is reported in `warnings`. Rules inside `@layer`, `@container` and
|
|
155
|
+
other at-rules are skipped.
|
|
156
|
+
|
|
86
157
|
## Raster images
|
|
87
158
|
|
|
88
159
|
`<image>` parses to an `SvgImageNode` holding the `href` verbatim — an
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,44 @@
|
|
|
1
1
|
import { Mat3 } from '@weasel-js/geom';
|
|
2
|
-
import { Path, FillStyle, ScreenLength, StrokeAlign, StyledRun, TextStyle, TextVerticalAlign, Stroke, MarkerEntry, TilePatternSpec, ImageNodeData, IngestCtx } from '@weasel-js/core';
|
|
2
|
+
import { Path, FillStyle, ScreenLength, StrokeAlign, MarkerRef, StyledRun, TextStyle, TextVerticalAlign, Stroke, MarkerEntry, RenderNeeds, TilePatternSpec, ImageNodeData, IngestCtx } from '@weasel-js/core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Media Queries 4 evaluation against a fixed environment.
|
|
6
|
+
*
|
|
7
|
+
* A parse represents one static render, so `@media` and `<style media>` are
|
|
8
|
+
* answered once, against an {@link SvgMediaEnvironment}, rather than tracked
|
|
9
|
+
* as live conditions.
|
|
10
|
+
*/
|
|
11
|
+
/** The media a parse is taken to be rendered on. */
|
|
12
|
+
interface SvgMediaEnvironment {
|
|
13
|
+
/** Media type; `all` always matches as well. */
|
|
14
|
+
readonly type: string;
|
|
15
|
+
/** Viewport width in CSS px. */
|
|
16
|
+
readonly width: number;
|
|
17
|
+
/** Viewport height in CSS px. */
|
|
18
|
+
readonly height: number;
|
|
19
|
+
/** Device pixels per CSS px. */
|
|
20
|
+
readonly resolution: number;
|
|
21
|
+
readonly prefersColorScheme: 'light' | 'dark';
|
|
22
|
+
readonly prefersReducedMotion: 'no-preference' | 'reduce';
|
|
23
|
+
/** Answers both `hover` and `any-hover`. */
|
|
24
|
+
readonly hover: 'none' | 'hover';
|
|
25
|
+
/** Answers both `pointer` and `any-pointer`. */
|
|
26
|
+
readonly pointer: 'none' | 'coarse' | 'fine';
|
|
27
|
+
/** How often the output can change once rendered. */
|
|
28
|
+
readonly update: 'none' | 'slow' | 'fast';
|
|
29
|
+
/** Bits per color component; 0 on a monochrome device. */
|
|
30
|
+
readonly color: number;
|
|
31
|
+
/** Bits per pixel of a monochrome device; 0 otherwise. */
|
|
32
|
+
readonly monochrome: number;
|
|
33
|
+
}
|
|
34
|
+
/** A static, light-scheme screen render with no pointer. Width and height are the replaced-element default. */
|
|
35
|
+
declare const DEFAULT_MEDIA_ENVIRONMENT: SvgMediaEnvironment;
|
|
36
|
+
/**
|
|
37
|
+
* Whether a media query list matches `env`. An empty list matches; a
|
|
38
|
+
* malformed query in the list is `not all`, leaving its neighbors intact; an
|
|
39
|
+
* unknown feature or value is unknown, which never matches, even under `not`.
|
|
40
|
+
*/
|
|
41
|
+
declare function evaluateMediaQuery(list: string, env: SvgMediaEnvironment): boolean;
|
|
3
42
|
|
|
4
43
|
/**
|
|
5
44
|
* Public types for `@weasel-js/svg`. The package exposes a flat,
|
|
@@ -99,10 +138,12 @@ interface SvgStroke {
|
|
|
99
138
|
* writes the stroke centered and says so through `onWarn`; the parser
|
|
100
139
|
* never sets it. */
|
|
101
140
|
align?: StrokeAlign;
|
|
102
|
-
/** `marker-start` / `marker-mid` / `marker-end
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
141
|
+
/** `marker-start` / `marker-mid` / `marker-end` as the kit's `MarkerRef`: the
|
|
142
|
+
* bare `url(#id)` key, or a key with the `size` the serializer writes into a
|
|
143
|
+
* def of its own. */
|
|
144
|
+
markerStart?: MarkerRef;
|
|
145
|
+
markerMid?: MarkerRef;
|
|
146
|
+
markerEnd?: MarkerRef;
|
|
106
147
|
}
|
|
107
148
|
/**
|
|
108
149
|
* Leaf node: a path geometry plus fill/stroke. All other v1 shapes
|
|
@@ -253,6 +294,14 @@ interface ParseOptions {
|
|
|
253
294
|
* the structured `meta` bag; they are silently dropped at serialize time.
|
|
254
295
|
*/
|
|
255
296
|
namespaces?: Record<string, string>;
|
|
297
|
+
/**
|
|
298
|
+
* The media `@media` rules and `<style media>` are evaluated against. A
|
|
299
|
+
* parse is one static render: by default a `screen` whose viewport is the
|
|
300
|
+
* root's `width` / `height` (else its `viewBox`, else 300 × 150), with a
|
|
301
|
+
* light color scheme and no hover or pointer. Fields given here replace
|
|
302
|
+
* those defaults.
|
|
303
|
+
*/
|
|
304
|
+
media?: Partial<SvgMediaEnvironment>;
|
|
256
305
|
}
|
|
257
306
|
/** Output of {@link parseSvg}. */
|
|
258
307
|
interface ParseResult {
|
|
@@ -350,12 +399,24 @@ interface SerializeOptions {
|
|
|
350
399
|
declare function parseSvg(svg: string, opts?: ParseOptions): ParseResult;
|
|
351
400
|
|
|
352
401
|
/**
|
|
353
|
-
*
|
|
354
|
-
*
|
|
355
|
-
*
|
|
356
|
-
*
|
|
402
|
+
* Map between SVG `<linearGradient>` / `<radialGradient>` elements and
|
|
403
|
+
* weasel's `FillStyle` gradient variants. Definitions are indexed by id
|
|
404
|
+
* wherever in the document they appear, and looked up when a `fill` /
|
|
405
|
+
* `stroke` attribute references one as `url(#id)`. On serialize, we
|
|
406
|
+
* emit a fresh `<defs>` block with stable generated ids.
|
|
357
407
|
*/
|
|
358
408
|
|
|
409
|
+
/** `true` when SVG has a paint server for this kind, so the reference needs no
|
|
410
|
+
* fallback color and the root needs no foreign namespace. */
|
|
411
|
+
/** Whether SVG has its own paint server for paint kind `kind`: solids, the
|
|
412
|
+
* linear and radial gradients, and patterns. Any other kind is written in
|
|
413
|
+
* weasel's namespace with a fallback color, which other renderers paint flat. */
|
|
414
|
+
declare function nativeSvgKind(kind: string): boolean;
|
|
415
|
+
/** Whether a gradient interpolating through `space` blends the same in every
|
|
416
|
+
* SVG renderer — only sRGB, the default. A perceptual space still exports,
|
|
417
|
+
* but renderers other than weasel blend it in sRGB. */
|
|
418
|
+
declare function nativeSvgSpace(space: string | null | undefined): boolean;
|
|
419
|
+
|
|
359
420
|
/**
|
|
360
421
|
* Walk the tree and produce an SVG document string. The root `<svg>`'s
|
|
361
422
|
* `viewBox` is taken from `opts.viewBox` if supplied, otherwise computed
|
|
@@ -363,6 +424,23 @@ declare function parseSvg(svg: string, opts?: ParseOptions): ParseResult;
|
|
|
363
424
|
*/
|
|
364
425
|
declare function serializeSvg(nodes: SvgNode[], opts?: SerializeOptions): string;
|
|
365
426
|
|
|
427
|
+
/**
|
|
428
|
+
* What `serializeSvg(nodes)` reads that loads on demand: the paint kind of
|
|
429
|
+
* every fill and stroke it writes as a paint server, and the face of every
|
|
430
|
+
* run whose script size it takes from font metrics. The kinds come from the
|
|
431
|
+
* serializer's own paint pre-pass, so the two cannot disagree. Registered
|
|
432
|
+
* kinds are included.
|
|
433
|
+
*/
|
|
434
|
+
declare function svgNeeds(nodes: readonly SvgNode[]): RenderNeeds;
|
|
435
|
+
/**
|
|
436
|
+
* Load what {@link svgNeeds} lists, so a `serializeSvg(nodes)` issued after it
|
|
437
|
+
* resolves writes every paint server's def and every script size from the
|
|
438
|
+
* face it renders in. Only those load: a lazily registered kind or font the
|
|
439
|
+
* nodes do not use is never fetched, and cannot fail the export. A kind
|
|
440
|
+
* nothing registered is passed over; the export warns about it instead.
|
|
441
|
+
*/
|
|
442
|
+
declare function warmSvg(nodes: readonly SvgNode[]): Promise<void>;
|
|
443
|
+
|
|
366
444
|
/**
|
|
367
445
|
* Map between SVG `<pattern>` elements and weasel's `pattern` `FillStyle`.
|
|
368
446
|
* The counterpart to `gradients.ts` for the other paint-server kind.
|
|
@@ -390,6 +468,102 @@ declare function tilePreviewSvg(spec: TilePatternSpec, background?: string): str
|
|
|
390
468
|
/** `tilePreviewSvg` packed as a `url(...)` value for CSS `background-image`. */
|
|
391
469
|
declare function tilePreviewCssUrl(spec: TilePatternSpec, background?: string): string;
|
|
392
470
|
|
|
471
|
+
/**
|
|
472
|
+
* `@supports` evaluation. A declaration test asks whether this parser would
|
|
473
|
+
* honor the declaration ({@link isDeclarationHonored}), not whether a browser
|
|
474
|
+
* could parse it — the answer decides whether the guarded rules apply here.
|
|
475
|
+
*/
|
|
476
|
+
interface SupportsOptions {
|
|
477
|
+
/** Answers `selector(…)`; without it every selector test is false. */
|
|
478
|
+
readonly selector?: (selector: string) => boolean;
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Whether a `@supports` condition holds. `selector()` defers to
|
|
482
|
+
* `opts.selector`; any other function and any unrecognized parenthesized
|
|
483
|
+
* content is false, so `not` of one is true. A malformed condition is false.
|
|
484
|
+
*/
|
|
485
|
+
declare function evaluateSupports(condition: string, opts?: SupportsOptions): boolean;
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* The kit-to-SVG direction: scene leaves back to `SvgNode`s, the inverse of
|
|
489
|
+
* `svgNodesToKitDrafts`. Each leaf is written as the built-in painter that
|
|
490
|
+
* draws it would draw it — the pose baked into the geometry, box-relative
|
|
491
|
+
* paints resolved into that box — so `serializeSvg` over the result shows what
|
|
492
|
+
* the canvas shows.
|
|
493
|
+
*/
|
|
494
|
+
|
|
495
|
+
/** A leaf's box: where it is drawn, and the frame its box-relative paints
|
|
496
|
+
* resolve against. */
|
|
497
|
+
interface SvgKitPose {
|
|
498
|
+
x: number;
|
|
499
|
+
y: number;
|
|
500
|
+
width: number;
|
|
501
|
+
height: number;
|
|
502
|
+
rotation?: number;
|
|
503
|
+
}
|
|
504
|
+
/** The leaf data the kit's path, text and image painters read — what
|
|
505
|
+
* `svgNodesToKitDrafts` writes. */
|
|
506
|
+
interface SvgKitLeafData {
|
|
507
|
+
path?: Path;
|
|
508
|
+
fill?: FillStyle | null;
|
|
509
|
+
stroke?: Stroke | null;
|
|
510
|
+
text?: string;
|
|
511
|
+
style?: TextStyle;
|
|
512
|
+
runs?: readonly StyledRun[];
|
|
513
|
+
verticalAlign?: TextVerticalAlign;
|
|
514
|
+
image?: ImageNodeData['image'];
|
|
515
|
+
}
|
|
516
|
+
/** A kit paint as an `SvgPaint`. `null` is `fill="none"`; a box-relative
|
|
517
|
+
* gradient or pattern is resolved into `box`, since the geometry it paints
|
|
518
|
+
* is written already placed there. */
|
|
519
|
+
declare function svgPaintFromKit(fill: FillStyle | null, box: SvgKitPose): SvgPaint;
|
|
520
|
+
/** A kit `Stroke` as an `SvgStroke` — the inverse of `strokeDataFromSvg`.
|
|
521
|
+
* One with no paint or no width draws nothing and is written as no stroke. */
|
|
522
|
+
declare function svgStrokeFromKit(stroke: Stroke | null | undefined, box: SvgKitPose): SvgStroke | undefined;
|
|
523
|
+
/** Write a `kit:image` leaf as an `SvgImageNode` — the inverse of the image
|
|
524
|
+
* arm of `svgNodesToKitDrafts`. The pose is the image's box. */
|
|
525
|
+
declare function svgImageFromKit(image: ImageNodeData['image'], pose: SvgKitPose): SvgImageNode;
|
|
526
|
+
/**
|
|
527
|
+
* Write one leaf as the `SvgNode` its built-in painter draws — image, text or
|
|
528
|
+
* path, in the order the painters claim a node. `null` for data none of them
|
|
529
|
+
* draws.
|
|
530
|
+
*
|
|
531
|
+
* A path with no `fill` takes `kit:path`'s fallback: the default shape fill
|
|
532
|
+
* when it has no stroke, and no fill when it has one.
|
|
533
|
+
*/
|
|
534
|
+
declare function svgLeafFromKit(data: SvgKitLeafData, pose: SvgKitPose): SvgPathNode | SvgTextNode | SvgImageNode | null;
|
|
535
|
+
/** One node as {@link svgNodesFromKit} reads it. */
|
|
536
|
+
interface SvgKitTreeNode {
|
|
537
|
+
kind: string;
|
|
538
|
+
data: unknown;
|
|
539
|
+
pose: SvgKitPose;
|
|
540
|
+
}
|
|
541
|
+
/** The read side of a scene that {@link svgNodesFromKit} walks. A kit
|
|
542
|
+
* `Scene` is one as it stands. */
|
|
543
|
+
interface SvgKitTree<TId extends string = string> {
|
|
544
|
+
readonly roots: readonly TId[];
|
|
545
|
+
childrenOf(id: TId): readonly TId[];
|
|
546
|
+
get(id: TId): SvgKitTreeNode | undefined;
|
|
547
|
+
}
|
|
548
|
+
/** Options for {@link svgNodesFromKit}. */
|
|
549
|
+
interface SvgNodesFromKitOptions<TId extends string = string> {
|
|
550
|
+
/** Walk these ids, in this order, instead of the tree's roots. */
|
|
551
|
+
roots?: readonly TId[];
|
|
552
|
+
/** `false` leaves a node out, with everything under it — a hidden layer. */
|
|
553
|
+
include?(id: TId): boolean;
|
|
554
|
+
/** Lower a leaf yourself; `null` leaves it out. Defaults to {@link svgLeafFromKit}. */
|
|
555
|
+
leaf?(id: TId, node: SvgKitTreeNode): SvgNode | null;
|
|
556
|
+
/** Decorate the group written for a container, e.g. with `meta`. */
|
|
557
|
+
group?(id: TId, group: SvgGroupNode): SvgGroupNode;
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Walk a scene's container tree into `SvgNode`s ready for `serializeSvg`:
|
|
561
|
+
* every `container` becomes a group of its children, in z-order, and every
|
|
562
|
+
* leaf goes through {@link svgLeafFromKit} unless `options.leaf` says
|
|
563
|
+
* otherwise.
|
|
564
|
+
*/
|
|
565
|
+
declare function svgNodesFromKit<TId extends string>(tree: SvgKitTree<TId>, options?: SvgNodesFromKitOptions<TId>): SvgNode[];
|
|
566
|
+
|
|
393
567
|
/** Axis-aligned box, in the coordinate space of the SVG being unpacked. Used
|
|
394
568
|
* for the bounds a draft occupies before it becomes a scene node. */
|
|
395
569
|
interface SvgDraftBounds {
|
|
@@ -406,7 +580,7 @@ type DraftPose = SvgDraftBounds & {
|
|
|
406
580
|
* order (a draft's `parentId` always names an earlier draft, or `null` for
|
|
407
581
|
* roots). Leaf `data` is kit-painter-native (see module doc).
|
|
408
582
|
*/
|
|
409
|
-
type SvgSceneDraft = {
|
|
583
|
+
type SvgSceneDraft<TData = Record<string, unknown>> = {
|
|
410
584
|
kind: 'container';
|
|
411
585
|
id: string;
|
|
412
586
|
parentId: string | null;
|
|
@@ -416,8 +590,30 @@ type SvgSceneDraft = {
|
|
|
416
590
|
id: string;
|
|
417
591
|
parentId: string | null;
|
|
418
592
|
pose: DraftPose;
|
|
419
|
-
data:
|
|
593
|
+
data: TData;
|
|
420
594
|
};
|
|
595
|
+
/** A leaf `SvgNode`: everything but a group. */
|
|
596
|
+
type SvgLeafNode = Exclude<SvgNode, SvgGroupNode>;
|
|
597
|
+
/** Options for {@link svgNodesToKitDrafts}. */
|
|
598
|
+
interface SvgNodesToKitDraftsOptions<TData> {
|
|
599
|
+
/** Lower a leaf yourself, from the kit data the default writes for it and
|
|
600
|
+
* the node it came from — for data shaped other than the kit painters', or
|
|
601
|
+
* metadata the document carries. `null` leaves it out. */
|
|
602
|
+
leaf?(id: string, draft: {
|
|
603
|
+
pose: DraftPose;
|
|
604
|
+
data: SvgKitLeafData;
|
|
605
|
+
}, source: SvgLeafNode): TData | null;
|
|
606
|
+
}
|
|
607
|
+
/** Lower an `SvgPaint` onto the `kit:path` painter's `data.fill` — a
|
|
608
|
+
* `FillStyle`, or `null` for SVG's `fill="none"` (the painter skips the
|
|
609
|
+
* fill rather than falling back to its default). A solid paint keeps its
|
|
610
|
+
* `fill-opacity`.
|
|
611
|
+
*
|
|
612
|
+
* A gradient rides through as the `FillStyle` it already is, normalized to
|
|
613
|
+
* the leaf's own box: `objectBoundingBox` gradients already are, and a
|
|
614
|
+
* `userSpaceOnUse` one is rebased so it survives the fit-clamp and the
|
|
615
|
+
* drop-point placement that move the geometry out from under it. */
|
|
616
|
+
declare function fillDataFromSvg(paint: SvgPaint | undefined, box: SvgDraftBounds): FillStyle | null | undefined;
|
|
421
617
|
/** Lower an `SvgStroke` onto the leaf's `data.stroke`.
|
|
422
618
|
*
|
|
423
619
|
* Everything the SVG carried — paint, width, cap, join, dash, miter limit,
|
|
@@ -426,16 +622,21 @@ type SvgSceneDraft = {
|
|
|
426
622
|
* `userSpaceOnUse` gradient survives the fit-clamp and the drop-point
|
|
427
623
|
* placement. */
|
|
428
624
|
declare function strokeDataFromSvg(stroke: SvgStroke | undefined, box: SvgDraftBounds): Stroke | undefined;
|
|
429
|
-
/** Write a `kit:image` leaf as an `SvgImageNode` — the inverse of the image
|
|
430
|
-
* arm of {@link svgNodesToKitDrafts}. The pose is the image's box. */
|
|
431
|
-
declare function svgImageFromKit(image: ImageNodeData['image'], pose: DraftPose): SvgImageNode;
|
|
432
625
|
/**
|
|
433
626
|
* Walk an `SvgNode[]` tree and emit a flat, parent-before-child list of
|
|
434
627
|
* {@link SvgSceneDraft}s. Each `<g>` becomes a container whose pose is the
|
|
435
628
|
* union AABB of its descendants (the kit `group` action's convention);
|
|
436
629
|
* path/text leaves carry kit-painter-native data. Empty groups are dropped.
|
|
630
|
+
*
|
|
631
|
+
* Handed a whole `ParseResult`, it also registers the document's markers
|
|
632
|
+
* (`parsed.markers`), without which the strokes naming them draw bare.
|
|
633
|
+
* Containers carry no opacity, so an element or group `opacity` is multiplied
|
|
634
|
+
* into the paints of every leaf under it.
|
|
635
|
+
*
|
|
636
|
+
* `nextId` is handed the node each id is for. `options.leaf` replaces a leaf's
|
|
637
|
+
* data; a group whose leaves it all leaves out is dropped like an empty one.
|
|
437
638
|
*/
|
|
438
|
-
declare function svgNodesToKitDrafts(
|
|
639
|
+
declare function svgNodesToKitDrafts<TData = Record<string, unknown>>(input: ParseResult | readonly SvgNode[], nextId: (source: SvgNode) => string, options?: SvgNodesToKitDraftsOptions<TData>): SvgSceneDraft<TData>[];
|
|
439
640
|
/**
|
|
440
641
|
* Parse each file and insert its node tree — one undoable `applyOps` batch
|
|
441
642
|
* per file. See the module doc for placement and wrapping policy. A file
|
|
@@ -444,4 +645,4 @@ declare function svgNodesToKitDrafts(nodes: readonly SvgNode[], nextId: () => st
|
|
|
444
645
|
*/
|
|
445
646
|
declare function unpackSvgFiles(files: File[], ctx: IngestCtx): Promise<void>;
|
|
446
647
|
|
|
447
|
-
export { IDENTITY_MATRIX, type Matrix, type NamespaceMeta, type NamespacedElement, type ParseOptions, type ParseResult, type SerializeOptions, type SvgDraftBounds, type SvgGroupNode, type SvgImageNode, type SvgNode, type SvgPaint, type SvgPathNode, type SvgSceneDraft, type SvgStroke, type SvgTextNode, parseSvg, serializeSvg, strokeDataFromSvg, svgImageFromKit, svgNodesToKitDrafts, tilePreviewCssUrl, tilePreviewSvg, unpackSvgFiles };
|
|
648
|
+
export { DEFAULT_MEDIA_ENVIRONMENT, IDENTITY_MATRIX, type Matrix, type NamespaceMeta, type NamespacedElement, type ParseOptions, type ParseResult, type SerializeOptions, type SupportsOptions, type SvgDraftBounds, type SvgGroupNode, type SvgImageNode, type SvgKitLeafData, type SvgKitPose, type SvgKitTree, type SvgKitTreeNode, type SvgLeafNode, type SvgMediaEnvironment, type SvgNode, type SvgNodesFromKitOptions, type SvgNodesToKitDraftsOptions, type SvgPaint, type SvgPathNode, type SvgSceneDraft, type SvgStroke, type SvgTextNode, evaluateMediaQuery, evaluateSupports, fillDataFromSvg, nativeSvgKind, nativeSvgSpace, parseSvg, serializeSvg, strokeDataFromSvg, svgImageFromKit, svgLeafFromKit, svgNeeds, svgNodesFromKit, svgNodesToKitDrafts, svgPaintFromKit, svgStrokeFromKit, tilePreviewCssUrl, tilePreviewSvg, unpackSvgFiles, warmSvg };
|