@weasel-js/svg 1.11.1 → 1.12.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/dist/index.d.ts +57 -11
- package/dist/index.js +201 -53
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Affine } from '@weasel-js/geom';
|
|
2
2
|
export { pathToD as serializePathD } from '@weasel-js/geom';
|
|
3
|
-
import { Path, Paint, ScreenLength, StrokeAlign, MarkerRef, VertexWidth, StrokeNib, StyledRun, TextStyle, TextVerticalAlign, Fill, Stroke, PoseLinear, MarkerEntry, TextPoseLayout, RenderNeeds, TilePatternSpec, ImageNodeData, IngestCtx } from '@weasel-js/core';
|
|
3
|
+
import { Path, Paint, ScreenLength, StrokeAlign, MarkerRef, VertexWidth, StrokeNib, StyledRun, TextStyle, TextVerticalAlign, Fill, Stroke, PoseLinear, MarkerEntry, TextPoseLayout, RenderNeeds, TilePatternSpec, Inherit, ImageNodeData, IngestCtx } from '@weasel-js/core';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Media Queries 4 evaluation against a fixed environment.
|
|
@@ -134,6 +134,17 @@ interface SvgStroke {
|
|
|
134
134
|
vertexWidths?: VertexWidth[];
|
|
135
135
|
nib?: StrokeNib;
|
|
136
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* Which of a node's paints its own element sets none of, so that it takes the
|
|
139
|
+
* paint of the enclosing `<g>` that does. Its `fill` and `stroke` still hold
|
|
140
|
+
* what that resolves to.
|
|
141
|
+
*/
|
|
142
|
+
interface SvgInherits {
|
|
143
|
+
fill?: true;
|
|
144
|
+
/** Set only when the element sets no `stroke-*` or `marker-*` property
|
|
145
|
+
* either: the stroke is taken whole. */
|
|
146
|
+
stroke?: true;
|
|
147
|
+
}
|
|
137
148
|
/**
|
|
138
149
|
* Leaf node: a path geometry plus fill/stroke. Other shapes (`<rect>`,
|
|
139
150
|
* `<ellipse>`, etc.) are lowered to this on parse.
|
|
@@ -143,6 +154,7 @@ interface SvgPathNode {
|
|
|
143
154
|
path: Path;
|
|
144
155
|
fill: SvgPaint;
|
|
145
156
|
stroke?: SvgStroke;
|
|
157
|
+
inherits?: SvgInherits;
|
|
146
158
|
/** Element-level opacity (`opacity="..."`), 0..1. */
|
|
147
159
|
opacity?: number;
|
|
148
160
|
/** Element-level rotation in **radians**, pivoting around the AABB
|
|
@@ -172,6 +184,12 @@ interface SvgGroupNode {
|
|
|
172
184
|
* unions them and a `Path` holds one outline. */
|
|
173
185
|
clip?: Path;
|
|
174
186
|
opacity?: number;
|
|
187
|
+
/** The fill its children take when they set none — written as the group's
|
|
188
|
+
* own `fill`. Absent when neither it nor an enclosing group sets one. */
|
|
189
|
+
fill?: SvgPaint;
|
|
190
|
+
/** As `fill`, for the stroke; absent too when the one in effect is none. */
|
|
191
|
+
stroke?: SvgStroke;
|
|
192
|
+
inherits?: SvgInherits;
|
|
175
193
|
/** Kept by `ParseOptions.keepHidden` from content SVG does not render:
|
|
176
194
|
* `display="none"` here, or a leaf under `visibility="hidden"`. Written
|
|
177
195
|
* back as `display="none"`. */
|
|
@@ -218,6 +236,7 @@ interface SvgTextNode {
|
|
|
218
236
|
*/
|
|
219
237
|
fill?: Fill | null;
|
|
220
238
|
stroke?: Stroke;
|
|
239
|
+
inherits?: SvgInherits;
|
|
221
240
|
/** Element-level opacity (`opacity="..."`), 0..1. */
|
|
222
241
|
opacity?: number;
|
|
223
242
|
/** Element-level rotation in **radians**, pivoting around the unrotated
|
|
@@ -491,6 +510,21 @@ declare function tilePreviewSvg(spec: TilePatternSpec, background?: string): str
|
|
|
491
510
|
/** `tilePreviewSvg` packed as a `url(...)` value for CSS `background-image`. */
|
|
492
511
|
declare function tilePreviewCssUrl(spec: TilePatternSpec, background?: string): string;
|
|
493
512
|
|
|
513
|
+
/** CSS Selectors 4 specificity. */
|
|
514
|
+
/** A selector's specificity as (ids, classes, types). */
|
|
515
|
+
type Specificity = readonly [number, number, number];
|
|
516
|
+
/** Negative when `a` is less specific than `b`, positive when more, 0 when equal. */
|
|
517
|
+
declare function compareSpecificity(a: Specificity, b: Specificity): number;
|
|
518
|
+
/** CSS Selectors 4 specificity of one complex selector (no comma list). */
|
|
519
|
+
declare function specificity(selector: string): Specificity;
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* Split `s` on `sep` wherever it sits outside strings and (), [] nesting.
|
|
523
|
+
* With `dropBlocks`, a `{…}` block at depth zero is discarded along with the
|
|
524
|
+
* prelude before it, back to the previous separator.
|
|
525
|
+
*/
|
|
526
|
+
declare function splitTopLevel(s: string, sep: string, dropBlocks?: boolean): string[];
|
|
527
|
+
|
|
494
528
|
/**
|
|
495
529
|
* `@supports` evaluation. A declaration test asks whether this parser would
|
|
496
530
|
* honor the declaration ({@link isDeclarationHonored}), not whether a browser
|
|
@@ -532,8 +566,9 @@ interface SvgKitPose {
|
|
|
532
566
|
* `svgNodesToKitDrafts` writes. */
|
|
533
567
|
interface SvgKitLeafData {
|
|
534
568
|
path?: Path;
|
|
535
|
-
|
|
536
|
-
|
|
569
|
+
/** `'inherit'` takes the enclosing container's. */
|
|
570
|
+
fill?: Fill | Inherit | null;
|
|
571
|
+
stroke?: Stroke | Inherit | null;
|
|
537
572
|
text?: string;
|
|
538
573
|
style?: TextStyle;
|
|
539
574
|
runs?: readonly StyledRun[];
|
|
@@ -552,7 +587,7 @@ interface SvgKitLeafData {
|
|
|
552
587
|
declare function svgPaintFromKit(fill: Paint | null, box: SvgKitPose): SvgPaint;
|
|
553
588
|
/** A kit `Stroke` as an `SvgStroke` — the inverse of `strokeDataFromSvg`.
|
|
554
589
|
* One with no paint or no width draws nothing and is written as no stroke. */
|
|
555
|
-
declare function svgStrokeFromKit(
|
|
590
|
+
declare function svgStrokeFromKit(raw: Stroke | null | undefined, box: SvgKitPose): SvgStroke | undefined;
|
|
556
591
|
/** Write a `kit:image` leaf as an `SvgImageNode` — the inverse of the image
|
|
557
592
|
* arm of `svgNodesToKitDrafts`. The pose is the image's box. */
|
|
558
593
|
declare function svgImageFromKit(image: ImageNodeData['image'], pose: SvgKitPose): SvgImageNode;
|
|
@@ -562,10 +597,12 @@ declare function svgImageFromKit(image: ImageNodeData['image'], pose: SvgKitPose
|
|
|
562
597
|
* draws. A text node with a `background` is a group: the box, then the text.
|
|
563
598
|
* One that clips is a group clipped to its box as it is drawn, turned with it.
|
|
564
599
|
*
|
|
565
|
-
*
|
|
566
|
-
*
|
|
567
|
-
*
|
|
568
|
-
*
|
|
600
|
+
* An `'inherit'` fill or stroke is none here, with no container to read;
|
|
601
|
+
* {@link svgNodesFromKit} resolves it first.
|
|
602
|
+
*
|
|
603
|
+
* A fill or stroke that paints nothing is written `none`. Under a pose
|
|
604
|
+
* `transform` a stroke's width takes the uniform part of the stretch, as
|
|
605
|
+
* `parseSvg` reads a stroke under a skewed element.
|
|
569
606
|
*/
|
|
570
607
|
declare function svgLeafFromKit(data: SvgKitLeafData, pose: SvgKitPose): SvgPathNode | SvgTextNode | SvgImageNode | SvgGroupNode | null;
|
|
571
608
|
/** One node as {@link svgNodesFromKit} reads it. */
|
|
@@ -593,8 +630,11 @@ interface SvgNodesFromKitOptions<TId extends string = string> {
|
|
|
593
630
|
roots?: readonly TId[];
|
|
594
631
|
/** `false` leaves a node out, with everything under it — a hidden layer. */
|
|
595
632
|
include?(id: TId): boolean;
|
|
596
|
-
/** Lower a leaf yourself; `null` leaves it out. Defaults to {@link svgLeafFromKit}.
|
|
597
|
-
|
|
633
|
+
/** Lower a leaf yourself; `null` leaves it out. Defaults to {@link svgLeafFromKit}.
|
|
634
|
+
* `inherited` is what the leaf's `'inherit'` fields resolve to; write those
|
|
635
|
+
* as these, and the walk marks the result as inheriting where SVG's
|
|
636
|
+
* cascade can carry them. */
|
|
637
|
+
leaf?(id: TId, node: SvgKitTreeNode, inherited: SvgKitInherited): SvgNode | null;
|
|
598
638
|
/** Decorate the group written for a container, e.g. with `meta`. */
|
|
599
639
|
group?(id: TId, group: SvgGroupNode): SvgGroupNode;
|
|
600
640
|
}
|
|
@@ -605,6 +645,12 @@ interface SvgNodesFromKitOptions<TId extends string = string> {
|
|
|
605
645
|
* otherwise. A hidden node is written hidden, with its subtree as it is.
|
|
606
646
|
*/
|
|
607
647
|
declare function svgNodesFromKit<TId extends string>(tree: SvgKitTree<TId>, options?: SvgNodesFromKitOptions<TId>): SvgNode[];
|
|
648
|
+
/** What a leaf's `'inherit'` fill and stroke resolve to — its nearest
|
|
649
|
+
* enclosing container's; `null` for none. */
|
|
650
|
+
interface SvgKitInherited {
|
|
651
|
+
fill: Fill | null;
|
|
652
|
+
stroke: Stroke | null;
|
|
653
|
+
}
|
|
608
654
|
|
|
609
655
|
/** Axis-aligned box, in the coordinate space of the SVG being unpacked. Used
|
|
610
656
|
* for the bounds a draft occupies before it becomes a scene node. */
|
|
@@ -703,4 +749,4 @@ declare function svgNodesToKitDrafts<TData = Record<string, unknown>>(input: Par
|
|
|
703
749
|
*/
|
|
704
750
|
declare function unpackSvgFiles(files: File[], ctx: IngestCtx): Promise<void>;
|
|
705
751
|
|
|
706
|
-
export { DEFAULT_MEDIA_ENVIRONMENT, IDENTITY_MATRIX, type Matrix, type NamespaceMeta, type NamespacedElement, type ParseOptions, type ParseResult, type SerializeOptions, type SupportsOptions, type SvgDraftBounds, type SvgDraftPose, 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, escapeAttr, escapeText, evaluateMediaQuery, evaluateSupports, fillDataFromSvg, nativeSvgKind, nativeSvgSpace, parseSvg, serializeSvg, strokeDataFromSvg, svgImageFromKit, svgLeafFromKit, svgNeeds, svgNodesFromKit, svgNodesToKitDrafts, svgPaintFromKit, svgStrokeFromKit, tilePreviewCssUrl, tilePreviewSvg, unpackSvgFiles, warmSvg };
|
|
752
|
+
export { DEFAULT_MEDIA_ENVIRONMENT, IDENTITY_MATRIX, type Matrix, type NamespaceMeta, type NamespacedElement, type ParseOptions, type ParseResult, type SerializeOptions, type Specificity, type SupportsOptions, type SvgDraftBounds, type SvgDraftPose, 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, compareSpecificity, escapeAttr, escapeText, evaluateMediaQuery, evaluateSupports, fillDataFromSvg, nativeSvgKind, nativeSvgSpace, parseSvg, serializeSvg, specificity, splitTopLevel, strokeDataFromSvg, svgImageFromKit, svgLeafFromKit, svgNeeds, svgNodesFromKit, svgNodesToKitDrafts, svgPaintFromKit, svgStrokeFromKit, tilePreviewCssUrl, tilePreviewSvg, unpackSvgFiles, warmSvg };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { identity, multiply, pathToD, invert, splitByClosure, fillsOpenSubpaths, rotateAboutPoint, hasOpenSubpath, splitSubpaths } from '@weasel-js/geom';
|
|
2
2
|
export { pathToD as serializePathD } from '@weasel-js/geom';
|
|
3
|
-
import { isTileKind, boundsOfPath, transformPath, isSolidPaint, warmFonts, warmPaintKinds, isPaintKindKnown, solid, fillToBoundsFrame, getMarker, registerMarker, dwarn, unionAABB, createInsertOp, fillInPoseFrame, pathThroughPoseFrame,
|
|
3
|
+
import { isTileKind, boundsOfPath, transformPath, isSolidPaint, warmFonts, warmPaintKinds, isPaintKindKnown, solid, fillToBoundsFrame, getMarker, registerMarker, dwarn, unionAABB, createInsertOp, fillInPoseFrame, resolveStroke, pathThroughPoseFrame, resolveFill, pathInPoseFrame, poseLinearOf, poseFrameOf, INHERIT, DEFAULT_TEXT_FILL, resolveScreenLength, pathFromD, isPatternPaint, resolveTextStyle, strokeToPath, toRuns, resolveRunFace, parseColor, rgbaToHex, layoutRuns, resolveRuns, resolveAlign, PathBuilder, PATH_M, PATH_L, PATH_Z, scaleVertexWidth, getPaintKind, resolveMarkerSize, paragraphDirection, scriptMetricsFor, vertexHalfWidths, isTilePaint, tileSpecOf } from '@weasel-js/core';
|
|
4
4
|
import { tileGeometry } from '@weasel-js/core/patterns-builtin';
|
|
5
5
|
|
|
6
6
|
// src/types.ts
|
|
@@ -3024,6 +3024,32 @@ function markerEntryFrom(el, id, role, strokeWidth, gradients, onWarn) {
|
|
|
3024
3024
|
};
|
|
3025
3025
|
}
|
|
3026
3026
|
|
|
3027
|
+
// src/groupPaint.ts
|
|
3028
|
+
var NO_GROUP_PAINT = { fill: false, stroke: false };
|
|
3029
|
+
var STROKE_PROPS = INHERITED_PROPERTIES.filter((p) => p.startsWith("stroke") || p.startsWith("marker"));
|
|
3030
|
+
var sets = (el, prop) => {
|
|
3031
|
+
const v = ownProp(el, prop);
|
|
3032
|
+
return v != null && v.trim() !== "inherit";
|
|
3033
|
+
};
|
|
3034
|
+
var setsFill = (el) => sets(el, "fill");
|
|
3035
|
+
var setsStroke = (el) => STROKE_PROPS.some((p) => sets(el, p));
|
|
3036
|
+
function viewportPaintFrom(el, from) {
|
|
3037
|
+
return { fill: from.fill && !setsFill(el), stroke: from.stroke && !setsStroke(el) };
|
|
3038
|
+
}
|
|
3039
|
+
function inheritsFrom(el, from) {
|
|
3040
|
+
const fill = from.fill && !setsFill(el);
|
|
3041
|
+
const stroke = from.stroke && !setsStroke(el);
|
|
3042
|
+
return fill || stroke ? { inherits: { ...fill ? { fill: true } : {}, ...stroke ? { stroke: true } : {} } } : {};
|
|
3043
|
+
}
|
|
3044
|
+
function groupPaint(el, from, style, ctm, gradients, onWarn) {
|
|
3045
|
+
const children = { fill: from.fill || setsFill(el), stroke: from.stroke || setsStroke(el) };
|
|
3046
|
+
const paint = {};
|
|
3047
|
+
if (children.fill) paint.fill = paintThroughMatrix(readPaint2(style, "fill", "#000000", gradients, onWarn), ctm);
|
|
3048
|
+
const stroke = children.stroke ? readStroke(style, gradients, onWarn) : void 0;
|
|
3049
|
+
if (stroke) paint.stroke = strokeThroughMatrix(stroke, ctm);
|
|
3050
|
+
return { paint: { ...paint, ...inheritsFrom(el, from) }, children };
|
|
3051
|
+
}
|
|
3052
|
+
|
|
3027
3053
|
// src/parse.ts
|
|
3028
3054
|
var SUPPORTED_GROUP_TAGS = /* @__PURE__ */ new Set(["g", "svg"]);
|
|
3029
3055
|
function parseSvg(svg, opts = {}) {
|
|
@@ -3056,7 +3082,7 @@ function parseSvg(svg, opts = {}) {
|
|
|
3056
3082
|
for (const [id, paint] of collectPatterns(root, onWarn)) gradients.set(id, paint);
|
|
3057
3083
|
const rootStyle = deriveStyle(EMPTY_STYLE, root);
|
|
3058
3084
|
const clips = collectClipPaths(root, onWarn);
|
|
3059
|
-
const nodes = parseChildren(root, IDENTITY_MATRIX, rootStyle, gradients, clips, onWarn, uriToPrefix, opts.keepHidden === true);
|
|
3085
|
+
const nodes = parseChildren(root, IDENTITY_MATRIX, rootStyle, NO_GROUP_PAINT, gradients, clips, onWarn, uriToPrefix, opts.keepHidden === true);
|
|
3060
3086
|
const markers = ingestMarkers(root, nodes, gradients, onWarn);
|
|
3061
3087
|
const result = { nodes, warnings };
|
|
3062
3088
|
if (markers.length > 0) result.markers = markers;
|
|
@@ -3157,7 +3183,7 @@ function collectElementMeta(el, uriToPrefix) {
|
|
|
3157
3183
|
}
|
|
3158
3184
|
return Object.keys(meta).length > 0 ? meta : void 0;
|
|
3159
3185
|
}
|
|
3160
|
-
function parseChildren(parent, ctm, style, gradients, clips, onWarn, uriToPrefix, keepHidden) {
|
|
3186
|
+
function parseChildren(parent, ctm, style, from, gradients, clips, onWarn, uriToPrefix, keepHidden) {
|
|
3161
3187
|
const out = [];
|
|
3162
3188
|
for (let i = 0; i < parent.children.length; i++) {
|
|
3163
3189
|
const el = parent.children[i];
|
|
@@ -3165,7 +3191,7 @@ function parseChildren(parent, ctm, style, gradients, clips, onWarn, uriToPrefix
|
|
|
3165
3191
|
if (ns && ns !== "http://www.w3.org/2000/svg" || isStrokeOutline(el)) continue;
|
|
3166
3192
|
const hidden = isHiddenElement(el, style);
|
|
3167
3193
|
if (hidden && !keepHidden) continue;
|
|
3168
|
-
const node = unwrapStrokeGroup(el, parseElement(el, ctm, style, gradients, clips, onWarn, uriToPrefix, keepHidden));
|
|
3194
|
+
const node = unwrapStrokeGroup(el, parseElement(el, ctm, style, from, gradients, clips, onWarn, uriToPrefix, keepHidden));
|
|
3169
3195
|
if (!node) continue;
|
|
3170
3196
|
const parsed = Array.isArray(node) ? node : [node];
|
|
3171
3197
|
if (hidden) for (const n of parsed) n.hidden = true;
|
|
@@ -3173,7 +3199,7 @@ function parseChildren(parent, ctm, style, gradients, clips, onWarn, uriToPrefix
|
|
|
3173
3199
|
}
|
|
3174
3200
|
return out;
|
|
3175
3201
|
}
|
|
3176
|
-
function parseElement(el, ctm, style, gradients, clips, onWarn, uriToPrefix, keepHidden) {
|
|
3202
|
+
function parseElement(el, ctm, style, from, gradients, clips, onWarn, uriToPrefix, keepHidden) {
|
|
3177
3203
|
const tag = el.tagName.toLowerCase();
|
|
3178
3204
|
if (IGNORED_TAGS.has(tag)) return null;
|
|
3179
3205
|
if (tag === "g" && el.hasAttribute("data-weasel-image")) {
|
|
@@ -3188,20 +3214,7 @@ function parseElement(el, ctm, style, gradients, clips, onWarn, uriToPrefix, kee
|
|
|
3188
3214
|
if (clipRaw != null && readProperty("clip-path", clipRaw) !== "none") {
|
|
3189
3215
|
onWarn(`clip-path on <${tag}> is not modeled; only a <g> clips, so it is drawn unclipped`);
|
|
3190
3216
|
}
|
|
3191
|
-
if (tag === "g")
|
|
3192
|
-
const local = parseTransform(el.getAttribute("transform"), onWarn);
|
|
3193
|
-
const childCtm = multiply(ctm, local);
|
|
3194
|
-
const childStyle = deriveStyle(style, el);
|
|
3195
|
-
const children = parseChildren(el, childCtm, childStyle, gradients, clips, onWarn, uriToPrefix, keepHidden);
|
|
3196
|
-
const opacity2 = ownValue(el, "opacity");
|
|
3197
|
-
const group = { kind: "group", children };
|
|
3198
|
-
const clip = clipFor(el, childCtm, clips, onWarn);
|
|
3199
|
-
if (clip) group.clip = clip;
|
|
3200
|
-
if (opacity2 != null) group.opacity = opacity2;
|
|
3201
|
-
const meta2 = collectElementMeta(el, uriToPrefix);
|
|
3202
|
-
if (meta2) group.meta = meta2;
|
|
3203
|
-
return group;
|
|
3204
|
-
}
|
|
3217
|
+
if (tag === "g") return parseGroup(el, ctm, style, from, gradients, clips, onWarn, uriToPrefix, keepHidden);
|
|
3205
3218
|
if (SUPPORTED_GROUP_TAGS.has(tag)) {
|
|
3206
3219
|
const childStyle = deriveStyle(style, el);
|
|
3207
3220
|
const x = parseFloat(el.getAttribute("x") ?? "0");
|
|
@@ -3210,13 +3223,14 @@ function parseElement(el, ctm, style, gradients, clips, onWarn, uriToPrefix, kee
|
|
|
3210
3223
|
if (el.hasAttribute("viewBox")) {
|
|
3211
3224
|
onWarn("nested <svg> viewBox is not modeled; its children are not rescaled");
|
|
3212
3225
|
}
|
|
3213
|
-
return parseChildren(el, multiply(ctm, offset), childStyle, gradients, clips, onWarn, uriToPrefix, keepHidden);
|
|
3226
|
+
return parseChildren(el, multiply(ctm, offset), childStyle, viewportPaintFrom(el, from), gradients, clips, onWarn, uriToPrefix, keepHidden);
|
|
3214
3227
|
}
|
|
3215
3228
|
if (tag === "text") {
|
|
3216
3229
|
const textNode = parseTextElement(el, ctm, style, gradients, onWarn);
|
|
3217
3230
|
if (textNode && !Array.isArray(textNode) && textNode.kind === "text") {
|
|
3218
3231
|
const meta2 = collectElementMeta(el, uriToPrefix);
|
|
3219
3232
|
if (meta2) textNode.meta = meta2;
|
|
3233
|
+
Object.assign(textNode, inheritsFrom(el, from));
|
|
3220
3234
|
}
|
|
3221
3235
|
return textNode;
|
|
3222
3236
|
}
|
|
@@ -3271,6 +3285,7 @@ function parseElement(el, ctm, style, gradients, clips, onWarn, uriToPrefix, kee
|
|
|
3271
3285
|
if (stroke) node.stroke = stroke;
|
|
3272
3286
|
if (opacity != null) node.opacity = opacity;
|
|
3273
3287
|
if (rotation != null) node.rotation = rotation;
|
|
3288
|
+
Object.assign(node, inheritsFrom(el, from));
|
|
3274
3289
|
if (tag === "line" && (leafStyle["fill"] ?? null) == null) {
|
|
3275
3290
|
node.fill = { kind: "none" };
|
|
3276
3291
|
}
|
|
@@ -3278,6 +3293,20 @@ function parseElement(el, ctm, style, gradients, clips, onWarn, uriToPrefix, kee
|
|
|
3278
3293
|
if (meta) node.meta = meta;
|
|
3279
3294
|
return node;
|
|
3280
3295
|
}
|
|
3296
|
+
function parseGroup(el, ctm, style, from, gradients, clips, onWarn, uriToPrefix, keepHidden) {
|
|
3297
|
+
const childCtm = multiply(ctm, parseTransform(el.getAttribute("transform"), onWarn));
|
|
3298
|
+
const childStyle = deriveStyle(style, el);
|
|
3299
|
+
const paint = groupPaint(el, from, childStyle, childCtm, gradients, onWarn);
|
|
3300
|
+
const children = parseChildren(el, childCtm, childStyle, paint.children, gradients, clips, onWarn, uriToPrefix, keepHidden);
|
|
3301
|
+
const opacity = ownValue(el, "opacity");
|
|
3302
|
+
const group = { kind: "group", children, ...paint.paint };
|
|
3303
|
+
const clip = clipFor(el, childCtm, clips, onWarn);
|
|
3304
|
+
if (clip) group.clip = clip;
|
|
3305
|
+
if (opacity != null) group.opacity = opacity;
|
|
3306
|
+
const meta = collectElementMeta(el, uriToPrefix);
|
|
3307
|
+
if (meta) group.meta = meta;
|
|
3308
|
+
return group;
|
|
3309
|
+
}
|
|
3281
3310
|
function isHiddenElement(el, style) {
|
|
3282
3311
|
const tag = el.tagName.toLowerCase();
|
|
3283
3312
|
if (IGNORED_TAGS.has(tag)) return false;
|
|
@@ -3512,6 +3541,61 @@ function strokeAttrsFor(stroke, registry, warn) {
|
|
|
3512
3541
|
}
|
|
3513
3542
|
return attrs;
|
|
3514
3543
|
}
|
|
3544
|
+
|
|
3545
|
+
// src/groupPaintXml.ts
|
|
3546
|
+
var FILL_ATTRS = ["fill", "fill-opacity"];
|
|
3547
|
+
var STROKE_ATTRS = [
|
|
3548
|
+
"stroke",
|
|
3549
|
+
"stroke-width",
|
|
3550
|
+
"stroke-opacity",
|
|
3551
|
+
"stroke-linecap",
|
|
3552
|
+
"stroke-linejoin",
|
|
3553
|
+
"stroke-dasharray",
|
|
3554
|
+
"stroke-dashoffset",
|
|
3555
|
+
"stroke-miterlimit",
|
|
3556
|
+
"marker-start",
|
|
3557
|
+
"marker-mid",
|
|
3558
|
+
"marker-end"
|
|
3559
|
+
];
|
|
3560
|
+
var INITIAL = {
|
|
3561
|
+
"fill": "#000000",
|
|
3562
|
+
"fill-opacity": "1",
|
|
3563
|
+
"stroke": "none",
|
|
3564
|
+
"stroke-width": "1",
|
|
3565
|
+
"stroke-opacity": "1",
|
|
3566
|
+
"stroke-linecap": "butt",
|
|
3567
|
+
"stroke-linejoin": "miter",
|
|
3568
|
+
"stroke-dasharray": "none",
|
|
3569
|
+
"stroke-dashoffset": "0",
|
|
3570
|
+
"stroke-miterlimit": "4",
|
|
3571
|
+
"marker-start": "none",
|
|
3572
|
+
"marker-mid": "none",
|
|
3573
|
+
"marker-end": "none"
|
|
3574
|
+
};
|
|
3575
|
+
function groupPaintAttrs(node, registry, warn) {
|
|
3576
|
+
const out = [];
|
|
3577
|
+
if (node.fill && !node.inherits?.fill) out.push(...paintAttrs(node.fill, "fill", registry));
|
|
3578
|
+
if (node.stroke && !node.inherits?.stroke) out.push(...strokeAttrsFor(node.stroke, registry, warn));
|
|
3579
|
+
return out;
|
|
3580
|
+
}
|
|
3581
|
+
function attrNames(attrs) {
|
|
3582
|
+
return attrs.map((a) => a.slice(0, a.indexOf("=")));
|
|
3583
|
+
}
|
|
3584
|
+
var START_TAG = /<(path|text)\b([^>]*?)(\/?)>/g;
|
|
3585
|
+
var ATTR = /\s([\w:-]+)="[^"]*"/g;
|
|
3586
|
+
function fitLeafXml(xml, inherits, painted) {
|
|
3587
|
+
if (painted.size === 0 && !inherits) return xml;
|
|
3588
|
+
const dropped = /* @__PURE__ */ new Set([...inherits?.fill ? FILL_ATTRS : [], ...inherits?.stroke ? STROKE_ATTRS : []]);
|
|
3589
|
+
let first = true;
|
|
3590
|
+
return xml.replace(START_TAG, (_tag, name, body, close2) => {
|
|
3591
|
+
let attrs = body;
|
|
3592
|
+
if (first) attrs = attrs.replace(ATTR, (whole, n) => dropped.has(n) ? "" : whole);
|
|
3593
|
+
first = false;
|
|
3594
|
+
const has = new Set([...attrs.matchAll(ATTR)].map((m) => m[1]));
|
|
3595
|
+
const resets = [...painted].filter((n) => !has.has(n) && !dropped.has(n) && n in INITIAL);
|
|
3596
|
+
return `<${name}${attrs}${resets.map((n) => ` ${n}="${INITIAL[n]}"`).join("")}${close2}>`;
|
|
3597
|
+
});
|
|
3598
|
+
}
|
|
3515
3599
|
function textXml(node, registry, namespaces, warn, given) {
|
|
3516
3600
|
const layout = given && layoutMeasured(given, node.text) ? given : null;
|
|
3517
3601
|
const x = node.x + anchorOffset(node.style, node.width, node.text);
|
|
@@ -3665,6 +3749,7 @@ function prettyXml(xml) {
|
|
|
3665
3749
|
}
|
|
3666
3750
|
|
|
3667
3751
|
// src/serialize.ts
|
|
3752
|
+
var NOTHING_PAINTED = /* @__PURE__ */ new Set();
|
|
3668
3753
|
function serializeSvg(nodes, opts = {}) {
|
|
3669
3754
|
const registry = new PaintServerRegistry();
|
|
3670
3755
|
registerPaintServers(nodes, registry);
|
|
@@ -3707,6 +3792,8 @@ function registerPaintServers(nodes, registry) {
|
|
|
3707
3792
|
for (const n of nodes) {
|
|
3708
3793
|
if (n.kind === "group") {
|
|
3709
3794
|
if (n.clip) registry.clipId(n.clip);
|
|
3795
|
+
if (n.fill?.kind === "gradient" && !n.inherits?.fill) registry.register(n.fill.paint);
|
|
3796
|
+
if (n.stroke?.paint.kind === "gradient" && !n.inherits?.stroke) registry.register(n.stroke.paint.paint);
|
|
3710
3797
|
registerPaintServers(n.children, registry);
|
|
3711
3798
|
} else if (n.kind === "path") {
|
|
3712
3799
|
if (n.fill.kind === "gradient") registry.register(n.fill.paint);
|
|
@@ -3732,17 +3819,18 @@ function registerMarkers(stroke, registry) {
|
|
|
3732
3819
|
if (ref !== void 0) registry.markerId(ref);
|
|
3733
3820
|
}
|
|
3734
3821
|
}
|
|
3735
|
-
function nodeXml(node, registry, namespaces, warn, layoutOf) {
|
|
3736
|
-
const
|
|
3822
|
+
function nodeXml(node, registry, namespaces, warn, layoutOf, painted = NOTHING_PAINTED) {
|
|
3823
|
+
const kind = kindXml(node, registry, namespaces, warn, layoutOf, painted);
|
|
3824
|
+
const xml = node.kind === "path" || node.kind === "text" ? fitLeafXml(kind, node.inherits, painted) : kind;
|
|
3737
3825
|
if (!node.hidden) return xml;
|
|
3738
3826
|
return xml.replace(/^<[\w:]+/, (open) => `${open} display="none"`).replace(/<path (?=[^>]*:role="stroke-outline")/, '<path display="none" ');
|
|
3739
3827
|
}
|
|
3740
|
-
function kindXml(node, registry, namespaces, warn, layoutOf) {
|
|
3741
|
-
if (node.kind === "group") return groupXml(node, registry, namespaces, warn, layoutOf);
|
|
3828
|
+
function kindXml(node, registry, namespaces, warn, layoutOf, painted) {
|
|
3829
|
+
if (node.kind === "group") return groupXml(node, registry, namespaces, warn, layoutOf, painted);
|
|
3742
3830
|
if (node.kind === "text") return textXml(node, registry, namespaces, warn, layoutOf?.(node));
|
|
3743
3831
|
if (node.kind === "image") return imageXml(node, namespaces);
|
|
3744
3832
|
const drawn = pathAsSvgDraws(node);
|
|
3745
|
-
return drawn.kind === "group" ? groupXml(drawn, registry, namespaces, warn, layoutOf) : pathXml(drawn, registry, namespaces, warn);
|
|
3833
|
+
return drawn.kind === "group" ? groupXml(drawn, registry, namespaces, warn, layoutOf, painted) : pathXml(drawn, registry, namespaces, warn);
|
|
3746
3834
|
}
|
|
3747
3835
|
function imageXml(node, namespaces) {
|
|
3748
3836
|
const box = `x="${trimNumber(node.x)}" y="${trimNumber(node.y)}" width="${trimNumber(node.width)}" height="${trimNumber(node.height)}"`;
|
|
@@ -3766,8 +3854,11 @@ function imageXml(node, namespaces) {
|
|
|
3766
3854
|
const head = ['<g data-weasel-image="true"', ...outer].join(" ");
|
|
3767
3855
|
return `${head}${metaAttrs}><svg ${box} viewBox="${viewBox}" preserveAspectRatio="none"><image ${href} x="0" y="0" width="1" height="1" preserveAspectRatio="none"${flip}/></svg>${metaEls}</g>`;
|
|
3768
3856
|
}
|
|
3769
|
-
function groupXml(node, registry, namespaces, warn, layoutOf) {
|
|
3857
|
+
function groupXml(node, registry, namespaces, warn, layoutOf, painted = NOTHING_PAINTED) {
|
|
3770
3858
|
const attrs = [];
|
|
3859
|
+
const paint = groupPaintAttrs(node, registry, warn);
|
|
3860
|
+
for (const a of paint) attrs.push(a);
|
|
3861
|
+
const below = paint.length === 0 ? painted : /* @__PURE__ */ new Set([...painted, ...attrNames(paint)]);
|
|
3771
3862
|
if (node.transform) {
|
|
3772
3863
|
const m = formatMatrix(node.transform);
|
|
3773
3864
|
if (m) attrs.push(`transform="${m}"`);
|
|
@@ -3780,7 +3871,7 @@ function groupXml(node, registry, namespaces, warn, layoutOf) {
|
|
|
3780
3871
|
}
|
|
3781
3872
|
const metaAttrs = metaAttrsXml(node.meta, namespaces);
|
|
3782
3873
|
const head = attrs.length > 0 ? `<g ${attrs.join(" ")}${metaAttrs}>` : `<g${metaAttrs}>`;
|
|
3783
|
-
const body = node.children.map((c) => nodeXml(c, registry, namespaces, warn, layoutOf)).join("");
|
|
3874
|
+
const body = node.children.map((c) => nodeXml(c, registry, namespaces, warn, layoutOf, below)).join("");
|
|
3784
3875
|
return `${head}${body}${metaElementsXml(node.meta, namespaces)}</g>`;
|
|
3785
3876
|
}
|
|
3786
3877
|
function pathXml(node, registry, namespaces, warn) {
|
|
@@ -3867,6 +3958,19 @@ function fadeRun(run, k) {
|
|
|
3867
3958
|
...run.stroke ? { stroke: fadeStroke(run.stroke, k) } : {}
|
|
3868
3959
|
};
|
|
3869
3960
|
}
|
|
3961
|
+
|
|
3962
|
+
// src/draftTakes.ts
|
|
3963
|
+
var NO_TAKES = {};
|
|
3964
|
+
function takesOf(n, from, k) {
|
|
3965
|
+
const inherits = n.kind === "path" || n.kind === "text" || n.kind === "group" ? n.inherits : void 0;
|
|
3966
|
+
return { fill: inherits?.fill === true && from.fill === k, stroke: inherits?.stroke === true && from.stroke === k };
|
|
3967
|
+
}
|
|
3968
|
+
var solidOrNone = (p) => p === void 0 || p.kind === "solid" || p.kind === "none";
|
|
3969
|
+
function groupTakes(group, takes, k) {
|
|
3970
|
+
const fill = group.inherits?.fill ? takes.fill : solidOrNone(group.fill);
|
|
3971
|
+
const stroke = group.inherits?.stroke ? takes.stroke : solidOrNone(group.stroke?.paint);
|
|
3972
|
+
return { ...fill ? { fill: k } : {}, ...stroke ? { stroke: k } : {} };
|
|
3973
|
+
}
|
|
3870
3974
|
var CASCADE_OFFSET_PX = 24;
|
|
3871
3975
|
var VIEWPORT_FIT = 0.9;
|
|
3872
3976
|
function readFileText(file) {
|
|
@@ -3931,8 +4035,9 @@ function svgNodesToKitDrafts(input, nextId, options = {}) {
|
|
|
3931
4035
|
drafts.push({ kind: "leaf", id, parentId, pose, data: out, ...source.hidden ? { hidden: true } : {} });
|
|
3932
4036
|
return pose;
|
|
3933
4037
|
};
|
|
3934
|
-
const visit = (n, parentId, inherited2) => {
|
|
4038
|
+
const visit = (n, parentId, inherited2, from) => {
|
|
3935
4039
|
const k = inherited2 * (n.opacity ?? 1);
|
|
4040
|
+
const takes = takesOf(n, from, k);
|
|
3936
4041
|
if (n.kind === "group") {
|
|
3937
4042
|
const draft = {
|
|
3938
4043
|
kind: "container",
|
|
@@ -3944,7 +4049,7 @@ function svgNodesToKitDrafts(input, nextId, options = {}) {
|
|
|
3944
4049
|
};
|
|
3945
4050
|
drafts.push(draft);
|
|
3946
4051
|
const at = drafts.length - 1;
|
|
3947
|
-
const acc = unionAABB(n.children.map((c) => visit(c, draft.id, k)));
|
|
4052
|
+
const acc = unionAABB(n.children.map((c) => visit(c, draft.id, k, groupTakes(n, takes, k))));
|
|
3948
4053
|
if (!acc) {
|
|
3949
4054
|
const kept = drafts.length > at + 1 || (options.keepEmpty?.(n) ?? false);
|
|
3950
4055
|
if (!kept) drafts.splice(at, 1);
|
|
@@ -3952,6 +4057,7 @@ function svgNodesToKitDrafts(input, nextId, options = {}) {
|
|
|
3952
4057
|
return null;
|
|
3953
4058
|
}
|
|
3954
4059
|
draft.pose = n.clip ? boxOfPath(n.clip) : acc;
|
|
4060
|
+
Object.assign(draft.data, containerPaint(n, takes, draft.pose, k));
|
|
3955
4061
|
return draft.pose;
|
|
3956
4062
|
}
|
|
3957
4063
|
if (n.kind === "text") {
|
|
@@ -3969,16 +4075,15 @@ function svgNodesToKitDrafts(input, nextId, options = {}) {
|
|
|
3969
4075
|
width: pose2.width,
|
|
3970
4076
|
height: pose2.height
|
|
3971
4077
|
};
|
|
3972
|
-
const fill2 = n.fill === void 0
|
|
4078
|
+
const fill2 = n.fill === void 0 ? DEFAULT_TEXT_FILL : n.fill;
|
|
3973
4079
|
return pushLeaf(n, parentId, pose2, {
|
|
3974
4080
|
text: n.text,
|
|
3975
4081
|
...n.style ? { style: n.style } : {},
|
|
3976
4082
|
...n.verticalAlign ? { verticalAlign: n.verticalAlign } : {},
|
|
3977
4083
|
...n.runs ? { runs: n.runs.map((r) => fadeRun(runInBoxFrame(r, box), k)) } : {},
|
|
3978
|
-
//
|
|
3979
|
-
|
|
3980
|
-
...
|
|
3981
|
-
...n.stroke !== void 0 ? { stroke: fadeStroke(strokeInBoxFrame(n.stroke, box), k) } : {}
|
|
4084
|
+
// `null` is the document saying `fill="none"`.
|
|
4085
|
+
...takes.fill ? { fill: INHERIT } : { fill: fill2 && mapFillPaint(fill2, (p) => fadeFill(fillInBoxFrame(p, box), k)) },
|
|
4086
|
+
...takes.stroke ? { stroke: INHERIT } : n.stroke !== void 0 ? { stroke: fadeStroke(strokeInBoxFrame(n.stroke, box), k) } : {}
|
|
3982
4087
|
});
|
|
3983
4088
|
}
|
|
3984
4089
|
if (n.kind === "image") {
|
|
@@ -4002,13 +4107,21 @@ function svgNodesToKitDrafts(input, nextId, options = {}) {
|
|
|
4002
4107
|
const strokeFromSvg = strokeDataFromSvg(n.stroke, b);
|
|
4003
4108
|
return pushLeaf(n, parentId, pose, {
|
|
4004
4109
|
path: n.path,
|
|
4005
|
-
...fill !== void 0 ? { fill: fill && { paint: fadeFill(fill, k) } } : {},
|
|
4006
|
-
...strokeFromSvg !== void 0 ? { stroke: fadeStroke(strokeFromSvg, k) } : {}
|
|
4110
|
+
...takes.fill ? { fill: INHERIT } : fill !== void 0 ? { fill: fill && { paint: fadeFill(fill, k) } } : {},
|
|
4111
|
+
...takes.stroke ? { stroke: INHERIT } : strokeFromSvg !== void 0 ? { stroke: fadeStroke(strokeFromSvg, k) } : {}
|
|
4007
4112
|
});
|
|
4008
4113
|
};
|
|
4009
|
-
for (const n of nodes) visit(n, null, 1);
|
|
4114
|
+
for (const n of nodes) visit(n, null, 1, NO_TAKES);
|
|
4010
4115
|
return drafts;
|
|
4011
4116
|
}
|
|
4117
|
+
function containerPaint(n, takes, box, k) {
|
|
4118
|
+
const fill = fillDataFromSvg(n.fill, box);
|
|
4119
|
+
const stroke = strokeDataFromSvg(n.stroke, box);
|
|
4120
|
+
return {
|
|
4121
|
+
...takes.fill ? { fill: INHERIT } : fill ? { fill: { paint: fadeFill(fill, k) } } : {},
|
|
4122
|
+
...takes.stroke ? { stroke: INHERIT } : stroke ? { stroke: fadeStroke(stroke, k) } : {}
|
|
4123
|
+
};
|
|
4124
|
+
}
|
|
4012
4125
|
function boxOfPath(path) {
|
|
4013
4126
|
const b = boundsOfPath(path);
|
|
4014
4127
|
return { x: b.x, y: b.y, width: b.width, height: b.height };
|
|
@@ -4097,8 +4210,9 @@ function svgPaintFromKit(fill, box) {
|
|
|
4097
4210
|
}
|
|
4098
4211
|
return { kind: "gradient", paint: fillInPoseFrame(fill, box) };
|
|
4099
4212
|
}
|
|
4100
|
-
function svgStrokeFromKit(
|
|
4101
|
-
|
|
4213
|
+
function svgStrokeFromKit(raw, box) {
|
|
4214
|
+
const stroke = resolveStroke(raw);
|
|
4215
|
+
if (!stroke) return void 0;
|
|
4102
4216
|
const width2 = stroke.width ?? 1;
|
|
4103
4217
|
if (!((typeof width2 === "object" ? width2.px : width2) > 0)) return void 0;
|
|
4104
4218
|
const opacity = stroke.paint.opacity;
|
|
@@ -4152,17 +4266,16 @@ function svgLeafFromKit(data, pose) {
|
|
|
4152
4266
|
const text = svgTextFromKit({ ...data, text: data.text }, pose);
|
|
4153
4267
|
const boxPath = { kind: "rect", x: pose.x, y: pose.y, width: pose.width, height: pose.height };
|
|
4154
4268
|
const clip = data.overflow === "clip" ? { clip: pathThroughPoseFrame(boxPath, pose) } : {};
|
|
4155
|
-
if (!data.background
|
|
4269
|
+
if (!resolveFill(data.background)) return clip.clip ? { kind: "group", children: [text], ...clip } : text;
|
|
4156
4270
|
const box = svgLeafFromKit({ path: boxPath, fill: data.background }, pose);
|
|
4157
4271
|
return { kind: "group", children: [box, text], ...clip };
|
|
4158
4272
|
}
|
|
4159
4273
|
if (!data.path) return null;
|
|
4160
|
-
const stroke = svgStrokeFromKit(data.stroke, pose);
|
|
4161
|
-
const fill = data.fill !== void 0 ? data.fill : stroke ? null : DEFAULT_SHAPE_FILL;
|
|
4274
|
+
const stroke = svgStrokeFromKit(resolveStroke(data.stroke), pose);
|
|
4162
4275
|
const node = {
|
|
4163
4276
|
kind: "path",
|
|
4164
4277
|
path: pathInPoseFrame(data.path, pose),
|
|
4165
|
-
fill: svgPaintFromKit(fill?.paint ?? null, pose)
|
|
4278
|
+
fill: svgPaintFromKit(resolveFill(data.fill)?.paint ?? null, pose)
|
|
4166
4279
|
};
|
|
4167
4280
|
if (stroke) node.stroke = stroke;
|
|
4168
4281
|
const frame = poseLinearOf(pose) && poseFrameOf(pose);
|
|
@@ -4186,25 +4299,32 @@ function svgTextFromKit(data, pose) {
|
|
|
4186
4299
|
if (data.style) node.style = data.style;
|
|
4187
4300
|
if (data.runs) node.runs = data.runs.map((r) => runInPoseFrame(r, pose));
|
|
4188
4301
|
if (data.verticalAlign) node.verticalAlign = data.verticalAlign;
|
|
4189
|
-
|
|
4190
|
-
|
|
4302
|
+
const fill = resolveFill(data.fill);
|
|
4303
|
+
node.fill = fill && mapFillPaint(fill, (p) => fillInPoseFrame(p, pose));
|
|
4304
|
+
const stroke = resolveStroke(data.stroke);
|
|
4305
|
+
if (stroke) node.stroke = strokeInPoseFrame(stroke, pose);
|
|
4191
4306
|
if (pose.rotation) node.rotation = pose.rotation;
|
|
4192
4307
|
if (pose.transform) node.transform = pose.transform;
|
|
4193
4308
|
return node;
|
|
4194
4309
|
}
|
|
4195
4310
|
function svgNodesFromKit(tree, options = {}) {
|
|
4196
4311
|
const { include, leaf, group } = options;
|
|
4197
|
-
const emit = (id) => {
|
|
4312
|
+
const emit = (id, up) => {
|
|
4198
4313
|
const node = tree.get(id);
|
|
4199
|
-
const out2 = node && (!include || include(id)) ? lower(id, node) : null;
|
|
4314
|
+
const out2 = node && (!include || include(id)) ? lower(id, node, up) : null;
|
|
4200
4315
|
return out2 && node?.hidden === true ? { ...out2, hidden: true } : out2;
|
|
4201
4316
|
};
|
|
4202
|
-
const lower = (id, node) => {
|
|
4317
|
+
const lower = (id, node, up) => {
|
|
4203
4318
|
if (node.kind === "container") {
|
|
4319
|
+
const own2 = node.data;
|
|
4320
|
+
const below = {
|
|
4321
|
+
fill: own2?.fill === INHERIT ? up.fill : resolveFill(own2?.fill),
|
|
4322
|
+
stroke: own2?.stroke === INHERIT ? up.stroke : resolveStroke(own2?.stroke)
|
|
4323
|
+
};
|
|
4204
4324
|
const emitChildren = () => {
|
|
4205
4325
|
const children = [];
|
|
4206
4326
|
for (const c of tree.childrenOf(id)) {
|
|
4207
|
-
const child = emit(c);
|
|
4327
|
+
const child = emit(c, below);
|
|
4208
4328
|
if (child) children.push(child);
|
|
4209
4329
|
}
|
|
4210
4330
|
return children;
|
|
@@ -4213,7 +4333,7 @@ function svgNodesFromKit(tree, options = {}) {
|
|
|
4213
4333
|
const clip = path ? pathThroughPoseFrame(pathInPoseFrame(path, node.pose), node.pose) : void 0;
|
|
4214
4334
|
const copies = node.copiesFromPose?.(node.pose, node) ?? [];
|
|
4215
4335
|
const content = () => ({ kind: "group", children: emitChildren(), ...clip ? { clip } : {} });
|
|
4216
|
-
let g = content();
|
|
4336
|
+
let g = { ...content(), ...groupPaintFromKit(own2, below, node.pose) };
|
|
4217
4337
|
if (copies.length > 0) {
|
|
4218
4338
|
g = {
|
|
4219
4339
|
kind: "group",
|
|
@@ -4222,16 +4342,44 @@ function svgNodesFromKit(tree, options = {}) {
|
|
|
4222
4342
|
}
|
|
4223
4343
|
return group ? group(id, g) : g;
|
|
4224
4344
|
}
|
|
4225
|
-
|
|
4345
|
+
const data = node.data ?? {};
|
|
4346
|
+
return markInherits(leaf ? leaf(id, node, up) : svgLeafFromKit(resolvedData(data, up), node.pose), data, up);
|
|
4226
4347
|
};
|
|
4227
4348
|
const out = [];
|
|
4228
4349
|
for (const id of options.roots ?? tree.roots) {
|
|
4229
|
-
const n = emit(id);
|
|
4350
|
+
const n = emit(id, NO_UP_PAINT);
|
|
4230
4351
|
if (n) out.push(n);
|
|
4231
4352
|
}
|
|
4232
4353
|
return out;
|
|
4233
4354
|
}
|
|
4355
|
+
var NO_UP_PAINT = { fill: null, stroke: null };
|
|
4356
|
+
var carries = (p) => p != null && isSolidPaint(p.paint);
|
|
4357
|
+
function groupPaintFromKit(own2, below, pose) {
|
|
4358
|
+
const out = {};
|
|
4359
|
+
if (below.fill?.paint) out.fill = svgPaintFromKit(below.fill.paint, pose);
|
|
4360
|
+
const stroke = svgStrokeFromKit(below.stroke, pose);
|
|
4361
|
+
if (stroke) out.stroke = stroke;
|
|
4362
|
+
const fill = own2?.fill === INHERIT && carries(below.fill);
|
|
4363
|
+
const strokes = own2?.stroke === INHERIT && carries(below.stroke);
|
|
4364
|
+
if (fill || strokes) out.inherits = { ...fill ? { fill: true } : {}, ...strokes ? { stroke: true } : {} };
|
|
4365
|
+
return out;
|
|
4366
|
+
}
|
|
4367
|
+
function resolvedData(data, up) {
|
|
4368
|
+
if (data.fill !== INHERIT && data.stroke !== INHERIT) return data;
|
|
4369
|
+
return {
|
|
4370
|
+
...data,
|
|
4371
|
+
...data.fill === INHERIT ? { fill: up.fill } : {},
|
|
4372
|
+
...data.stroke === INHERIT ? { stroke: up.stroke } : {}
|
|
4373
|
+
};
|
|
4374
|
+
}
|
|
4375
|
+
function markInherits(out, data, up) {
|
|
4376
|
+
if (out === null || out.kind !== "path" && out.kind !== "text") return out;
|
|
4377
|
+
const fill = data.fill === INHERIT && carries(up.fill);
|
|
4378
|
+
const stroke = data.stroke === INHERIT && carries(up.stroke);
|
|
4379
|
+
if (fill || stroke) out.inherits = { ...fill ? { fill: true } : {}, ...stroke ? { stroke: true } : {} };
|
|
4380
|
+
return out;
|
|
4381
|
+
}
|
|
4234
4382
|
|
|
4235
|
-
export { DEFAULT_MEDIA_ENVIRONMENT, IDENTITY_MATRIX, escapeAttr, escapeText, evaluateMediaQuery, evaluateSupports, fillDataFromSvg, nativeSvgKind, nativeSvgSpace, parseSvg, serializeSvg, strokeDataFromSvg, svgImageFromKit, svgLeafFromKit, svgNeeds, svgNodesFromKit, svgNodesToKitDrafts, svgPaintFromKit, svgStrokeFromKit, tilePreviewCssUrl, tilePreviewSvg, unpackSvgFiles, warmSvg };
|
|
4383
|
+
export { DEFAULT_MEDIA_ENVIRONMENT, IDENTITY_MATRIX, compareSpecificity, escapeAttr, escapeText, evaluateMediaQuery, evaluateSupports, fillDataFromSvg, nativeSvgKind, nativeSvgSpace, parseSvg, serializeSvg, specificity, splitTopLevel, strokeDataFromSvg, svgImageFromKit, svgLeafFromKit, svgNeeds, svgNodesFromKit, svgNodesToKitDrafts, svgPaintFromKit, svgStrokeFromKit, tilePreviewCssUrl, tilePreviewSvg, unpackSvgFiles, warmSvg };
|
|
4236
4384
|
//# sourceMappingURL=index.js.map
|
|
4237
4385
|
//# sourceMappingURL=index.js.map
|