@vvfx/svg2ir 0.0.1-beta.0 → 0.0.1-beta.11
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 +62 -33
- package/dist/common/types.d.ts +6 -2
- package/dist/convert.d.ts +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1226 -37
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1226 -38
- package/dist/index.mjs.map +1 -1
- package/dist/node.js +1228 -39
- package/dist/node.js.map +1 -1
- package/dist/node.mjs +1228 -40
- package/dist/node.mjs.map +1 -1
- package/dist/parse-svg/build-element-tree-path.d.ts +2 -0
- package/dist/svg-rasterizer/prepare-snapshot.d.ts +9 -0
- package/dist/svg-rasterizer/rasterize-svg.d.ts +11 -0
- package/dist/svg2ir/assemble.d.ts +3 -1
- package/dist/svg2ir/convert.d.ts +3 -1
- package/dist/svg2ir/converter/layers/conversion-session.d.ts +2 -0
- package/dist/svg2ir/converter/text/font-metrics.d.ts +2 -0
- package/dist/svg2layers-adapter/assemble.d.ts +15 -2
- package/dist/svg2layers-adapter/baking/build-baked-layers.d.ts +13 -0
- package/dist/svg2layers-adapter/baking/normalize-layer-blending.d.ts +10 -0
- package/dist/svg2layers-adapter/baking/plan-graphic-baking.d.ts +18 -0
- package/dist/svg2layers-adapter/baking/resolve-baking-warnings.d.ts +4 -0
- package/dist/svg2layers-adapter/convert.d.ts +2 -2
- package/dist/svg2layers-adapter/converter/image/inspect-mask.d.ts +3 -0
- package/dist/svg2layers-adapter/converter/layers/build-layers.d.ts +1 -1
- package/dist/svg2layers-adapter/strip-layer-animation.d.ts +5 -0
- package/package.json +1 -1
package/dist/node.mjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Description: SVG to Animation IR and Galacean Effects conversion engine
|
|
4
4
|
* Author: Ant Group CO., Ltd.
|
|
5
5
|
* Contributors: 鳞息
|
|
6
|
-
* Version: v0.0.1-beta.
|
|
6
|
+
* Version: v0.0.1-beta.11
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { createSVGWindow } from 'svgdom';
|
|
@@ -79,11 +79,10 @@ function readInlineStyleProperty(style, propertyName) {
|
|
|
79
79
|
|
|
80
80
|
var ParseableSVG = /*#__PURE__*/ function() {
|
|
81
81
|
function ParseableSVG(svgStr, _options) {
|
|
82
|
-
var
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
var _SVG;
|
|
83
|
+
// svg.js parses a fragment; remove only the prolog and let the DOM handle nested markup.
|
|
84
|
+
var content = svgStr.replace(/^\uFEFF/, '').replace(/^(?:\s|<\?xml\b[\s\S]*?\?>|<!DOCTYPE\b[^>]*>|<!--[\s\S]*?-->)+/i, '');
|
|
85
85
|
// svg.js SVG(string) 的 d.ts 标为 Element,但对完整 <svg> 文档运行时返回根 SVG 文档实例。
|
|
86
|
-
var content = typeof svgStr === 'string' ? (_ref = (_svgStr_match = svgStr.match(RegExp("<svg\\s+.*?>.*?<\\/svg>", "s"))) == null ? void 0 : _svgStr_match[0]) != null ? _ref : svgStr : svgStr;
|
|
87
86
|
// svg.js 对非 SVG 字符串(如 'not svg')解析返 null。兜底空 svg:让 svg2ir 上层
|
|
88
87
|
// hasSVGRootElement 检查(非 svg 抛 INVALID_SVG)生效,而非在构造期抛错。
|
|
89
88
|
this.svg = (_SVG = SVG(content)) != null ? _SVG : SVG('<svg xmlns="http://www.w3.org/2000/svg"/>');
|
|
@@ -225,10 +224,10 @@ var editableSVGModule = /*#__PURE__*/Object.freeze({
|
|
|
225
224
|
default: ParseableSVG
|
|
226
225
|
});
|
|
227
226
|
|
|
228
|
-
var window = createSVGWindow();
|
|
227
|
+
var window$1 = createSVGWindow();
|
|
229
228
|
// svgdom 的 window 是最小 DOM stub(非完整 Window),运行时被 svg.js registerWindow 接受;
|
|
230
229
|
// d.ts 标 Window 类型过严,svgdom 的 window 是最小 DOM stub,这里断言对齐运行时用法。
|
|
231
|
-
registerWindow(window, window.document);
|
|
230
|
+
registerWindow(window$1, window$1.document);
|
|
232
231
|
|
|
233
232
|
var editableSVGNodeModule = /*#__PURE__*/Object.freeze({
|
|
234
233
|
__proto__: null,
|
|
@@ -1725,7 +1724,7 @@ function parseHexColor(raw) {
|
|
|
1725
1724
|
return null;
|
|
1726
1725
|
}
|
|
1727
1726
|
var hex = match[1];
|
|
1728
|
-
var expanded = hex.length <= 4 ?
|
|
1727
|
+
var expanded = hex.length <= 4 ? Array.from(hex).map(function(char) {
|
|
1729
1728
|
return "" + char + char;
|
|
1730
1729
|
}).join('') : hex;
|
|
1731
1730
|
var r = parseInt(expanded.slice(0, 2), 16) / 255;
|
|
@@ -2826,7 +2825,24 @@ function parseSMILTag(tag, root, beginCache, comparisonDuration, valueParser, un
|
|
|
2826
2825
|
return maxEnd;
|
|
2827
2826
|
}
|
|
2828
2827
|
|
|
2829
|
-
/**
|
|
2828
|
+
/** Structural source identity, independent of optional or duplicate SVG IDs. */ function buildElementTreePath(element) {
|
|
2829
|
+
var indices = [];
|
|
2830
|
+
var current = element;
|
|
2831
|
+
while(isElementNode(current.parentNode)){
|
|
2832
|
+
var parent = current.parentNode;
|
|
2833
|
+
indices.unshift(Array.from(parent.children).indexOf(current));
|
|
2834
|
+
current = parent;
|
|
2835
|
+
}
|
|
2836
|
+
return indices.join('/');
|
|
2837
|
+
}
|
|
2838
|
+
function isElementNode(node) {
|
|
2839
|
+
return (node == null ? void 0 : node.nodeType) === 1;
|
|
2840
|
+
}
|
|
2841
|
+
|
|
2842
|
+
/** SVG 转换诊断码;用于报告烘焙、降级和不支持的特性。 */ var SVG2IR_WARNING_CODES = {
|
|
2843
|
+
/** 图形或图形组已栅格化,矢量编辑能力变化通过 warning 报告。 */ LAYERS_GRAPHIC_BAKED: 'svg2ge_layers_graphic_baked',
|
|
2844
|
+
LAYERS_BLEND_MODE_DOWNGRADED: 'svg2ge_layers_blend_mode_downgraded',
|
|
2845
|
+
LAYERS_ANIMATION_STRIPPED: 'svg2ge_layers_animation_stripped',
|
|
2830
2846
|
LAYERS_UNSUPPORTED_TYPE: 'svg2ge_layers_unsupported_type',
|
|
2831
2847
|
LAYERS_UNSUPPORTED_FEATURE: 'svg2ge_layers_unsupported_feature',
|
|
2832
2848
|
LAYERS_INVALID_DATA: 'svg2ge_layers_invalid_data',
|
|
@@ -6316,8 +6332,9 @@ function readVec3(channel) {
|
|
|
6316
6332
|
node
|
|
6317
6333
|
], Array.from(node.querySelectorAll('*')));
|
|
6318
6334
|
var hasUnsupportedRule = ruleNodes.some(function(candidate) {
|
|
6335
|
+
var _ref, _ref1;
|
|
6319
6336
|
var _candidate_getAttribute, _candidate_getAttribute1;
|
|
6320
|
-
return ((_candidate_getAttribute = candidate.getAttribute('clip-rule')) == null ? void 0 : _candidate_getAttribute.trim()) !== '' || ((_candidate_getAttribute1 = candidate.getAttribute('fill-rule')) == null ? void 0 : _candidate_getAttribute1.trim()) !== '';
|
|
6337
|
+
return ((_ref = (_candidate_getAttribute = candidate.getAttribute('clip-rule')) == null ? void 0 : _candidate_getAttribute.trim()) != null ? _ref : '') !== '' || ((_ref1 = (_candidate_getAttribute1 = candidate.getAttribute('fill-rule')) == null ? void 0 : _candidate_getAttribute1.trim()) != null ? _ref1 : '') !== '';
|
|
6321
6338
|
});
|
|
6322
6339
|
if (hasUnsupportedRule) {
|
|
6323
6340
|
warn(SVG2IR_WARNING_CODES.CLIP_RULE_DROPPED, "" + tag + " 内显式 clip-rule/fill-rule 未映射,IR 只保留 mask 几何,不保留该规则。");
|
|
@@ -7158,8 +7175,10 @@ function createSVGConversionSession(es, options) {
|
|
|
7158
7175
|
};
|
|
7159
7176
|
var appendLayer = function appendLayer(layer, element, applyElementClip) {
|
|
7160
7177
|
if (applyElementClip === void 0) applyElementClip = true;
|
|
7178
|
+
var _options_layerSourceCollector;
|
|
7161
7179
|
var clippedLayer = applyElementClip ? applyClipMask(es, element, layer, clipMasks) : layer;
|
|
7162
7180
|
layers.push(withGroupParent(clippedLayer, element));
|
|
7181
|
+
(_options_layerSourceCollector = options.layerSourceCollector) == null ? void 0 : _options_layerSourceCollector.set(layer.id, buildElementTreePath(element.node));
|
|
7163
7182
|
};
|
|
7164
7183
|
var appendAsset = function appendAsset(asset) {
|
|
7165
7184
|
if (registeredAssetIds.has(asset.id)) {
|
|
@@ -10567,7 +10586,7 @@ function mapFontWeight(raw, fontFamily) {
|
|
|
10567
10586
|
seen.set(Math.round(w * 100), ch);
|
|
10568
10587
|
}
|
|
10569
10588
|
}
|
|
10570
|
-
return
|
|
10589
|
+
return Array.from(seen.entries()).map(function(param) {
|
|
10571
10590
|
var k = param[0], ch = param[1];
|
|
10572
10591
|
return {
|
|
10573
10592
|
ch: ch,
|
|
@@ -10617,6 +10636,9 @@ function mapFontWeight(raw, fontFamily) {
|
|
|
10617
10636
|
// latin / digit / 标点:典型比例字体 sans-serif 大写字母约 0.65em,数字稍窄。
|
|
10618
10637
|
return /[0-9]/.test(ch) ? 0.55 : 0.62;
|
|
10619
10638
|
}
|
|
10639
|
+
/** 去除单个字体族名的 CSS 字符串引号。 */ function normalizeFontFamilyName(fontFamily) {
|
|
10640
|
+
return fontFamily.trim().replace(/^(['"])(.*)\1$/, '$2');
|
|
10641
|
+
}
|
|
10620
10642
|
/** 构造与 Effects Runtime getFontDesc 一致的 CSS font 简写字符串,用于 Canvas measureText。 */ function buildCanvasFontDesc(fontSize, fontFamily, fontWeight, fontStyle) {
|
|
10621
10643
|
var weightStr = String(fontWeight);
|
|
10622
10644
|
var genericFamilies = [
|
|
@@ -10625,7 +10647,8 @@ function mapFontWeight(raw, fontFamily) {
|
|
|
10625
10647
|
'monospace',
|
|
10626
10648
|
'courier'
|
|
10627
10649
|
];
|
|
10628
|
-
var
|
|
10650
|
+
var family = normalizeFontFamilyName(fontFamily);
|
|
10651
|
+
var familyName = genericFamilies.includes(family) ? family : '"' + family + '"';
|
|
10629
10652
|
var desc = fontSize + "px " + familyName;
|
|
10630
10653
|
if (weightStr !== 'normal' && weightStr !== '') {
|
|
10631
10654
|
desc = weightStr + " " + desc;
|
|
@@ -10636,13 +10659,13 @@ function mapFontWeight(raw, fontFamily) {
|
|
|
10636
10659
|
return desc;
|
|
10637
10660
|
}
|
|
10638
10661
|
/** 文本宽度估算。优先使用调用方提供的 Canvas measureText,否则使用字符级启发式系数。 */ function estimateTextWidth(content, fontSize, letterSpacing, measureText, fontFamily, fontWeight, fontStyle) {
|
|
10639
|
-
var
|
|
10662
|
+
var chars = Array.from(content);
|
|
10663
|
+
var len = chars.length;
|
|
10640
10664
|
if (measureText != null && fontFamily !== '') {
|
|
10641
10665
|
var fontDesc = buildCanvasFontDesc(fontSize, fontFamily, fontWeight, fontStyle);
|
|
10642
10666
|
var width = measureText(fontDesc, content).width;
|
|
10643
10667
|
return width + letterSpacing * Math.max(len - 1, 0);
|
|
10644
10668
|
}
|
|
10645
|
-
var chars = [].concat(content);
|
|
10646
10669
|
var width1 = chars.reduce(function(s, ch) {
|
|
10647
10670
|
return s + charWidthCoef(ch) * fontSize;
|
|
10648
10671
|
}, 0);
|
|
@@ -12239,7 +12262,16 @@ function createSVGElementConverterRegistry(session) {
|
|
|
12239
12262
|
}
|
|
12240
12263
|
|
|
12241
12264
|
function buildSVGLayers(es, options) {
|
|
12242
|
-
var
|
|
12265
|
+
var currentPath;
|
|
12266
|
+
var warningSourceCollector = options.warningSourceCollector;
|
|
12267
|
+
var session = createSVGConversionSession(es, warningSourceCollector == null ? options : _extends({}, options, {
|
|
12268
|
+
emit: function emit(warning) {
|
|
12269
|
+
if (currentPath != null) {
|
|
12270
|
+
warningSourceCollector.set(warning, currentPath);
|
|
12271
|
+
}
|
|
12272
|
+
options.emit(warning);
|
|
12273
|
+
}
|
|
12274
|
+
}));
|
|
12243
12275
|
var converters = createSVGElementConverterRegistry(session);
|
|
12244
12276
|
for(var _iterator = _create_for_of_iterator_helper_loose(session.all), _step; !(_step = _iterator()).done;){
|
|
12245
12277
|
var element = _step.value;
|
|
@@ -12247,6 +12279,9 @@ function buildSVGLayers(es, options) {
|
|
|
12247
12279
|
var _element_node_tagName, _element_node;
|
|
12248
12280
|
var tag = (_ref = (_element_node = element.node) == null ? void 0 : (_element_node_tagName = _element_node.tagName) == null ? void 0 : _element_node_tagName.toLowerCase()) != null ? _ref : '';
|
|
12249
12281
|
var selector = describeElement(element);
|
|
12282
|
+
if (warningSourceCollector != null) {
|
|
12283
|
+
currentPath = buildElementTreePath(element.node);
|
|
12284
|
+
}
|
|
12250
12285
|
if (isInInactiveSwitchBranch(element)) {
|
|
12251
12286
|
continue;
|
|
12252
12287
|
}
|
|
@@ -12312,6 +12347,8 @@ function parseSVGToIRScene(svgString, options) {
|
|
|
12312
12347
|
value: scannedSmilDuration
|
|
12313
12348
|
};
|
|
12314
12349
|
var layerBuildOptions = {
|
|
12350
|
+
layerSourceCollector: options == null ? void 0 : options.layerSourceCollector,
|
|
12351
|
+
warningSourceCollector: options == null ? void 0 : options.warningSourceCollector,
|
|
12315
12352
|
frameRate: frameRate,
|
|
12316
12353
|
durationSeconds: effectiveDuration,
|
|
12317
12354
|
emit: emit,
|
|
@@ -12491,6 +12528,8 @@ function parseSVGToIRWithPreservedData(source, options, collectors) {
|
|
|
12491
12528
|
var svgString = readSVGString(source);
|
|
12492
12529
|
var irScene = parseSVGToIRScene(svgString, _extends({}, options, {
|
|
12493
12530
|
onWarning: emitWarning,
|
|
12531
|
+
layerSourceCollector: collectors == null ? void 0 : collectors.layerSourceCollector,
|
|
12532
|
+
warningSourceCollector: collectors == null ? void 0 : collectors.warningSourceCollector,
|
|
12494
12533
|
textDataCollector: collectors == null ? void 0 : collectors.textDataByLayerId,
|
|
12495
12534
|
paintAnimationsCollector: collectors == null ? void 0 : collectors.paintAnimationsByLayerId,
|
|
12496
12535
|
shapeAnimationCollector: collectors == null ? void 0 : collectors.shapeAnimationsByLayerId
|
|
@@ -12666,7 +12705,8 @@ function collectLayerWarning(warnings, options, code, message, selector) {
|
|
|
12666
12705
|
});
|
|
12667
12706
|
warnings.push(warning);
|
|
12668
12707
|
options.onWarning == null ? void 0 : options.onWarning.call(options, warning);
|
|
12669
|
-
|
|
12708
|
+
var advisory = code === SVG2IR_WARNING_CODES.LAYERS_TEXT_BOUNDS_ESTIMATED || code === SVG2IR_WARNING_CODES.LAYERS_GRAPHIC_BAKED;
|
|
12709
|
+
if (options.strict === true && !advisory) {
|
|
12670
12710
|
throw new SVGConverterError(SVG_CONVERTER_ERROR_CODES.LAYERS_CONVERSION_FAILED, warning.message, {
|
|
12671
12711
|
stage: 'layers',
|
|
12672
12712
|
sourceId: selector,
|
|
@@ -12991,9 +13031,12 @@ function buildTextRunLayout(runs, family, spacing, content, size, conversionOpti
|
|
|
12991
13031
|
// 分段文字使用统一参考字号度量字宽和字体边界,再按片段字号缩放。
|
|
12992
13032
|
var measurementSize = segmented ? 10 : run.fontSize;
|
|
12993
13033
|
var scale = run.fontSize / measurementSize;
|
|
12994
|
-
var
|
|
13034
|
+
var weight = run.bold ? 'bold' : 'normal';
|
|
13035
|
+
var style = run.italic ? 'italic' : 'normal';
|
|
13036
|
+
var font = buildCanvasFontDesc(measurementSize, family, weight, style);
|
|
12995
13037
|
var metrics = conversionOptions.measureText == null ? void 0 : conversionOptions.measureText.call(conversionOptions, font, segmented ? 'x' : run.text);
|
|
12996
|
-
var
|
|
13038
|
+
var characters = Array.from(run.text);
|
|
13039
|
+
var chunks = segmented ? characters : [
|
|
12997
13040
|
run.text
|
|
12998
13041
|
];
|
|
12999
13042
|
var advance = 0;
|
|
@@ -13002,12 +13045,13 @@ function buildTextRunLayout(runs, family, spacing, content, size, conversionOpti
|
|
|
13002
13045
|
var width = segmented ? conversionOptions.measureText == null ? void 0 : conversionOptions.measureText.call(conversionOptions, font, chunk).width : metrics == null ? void 0 : metrics.width;
|
|
13003
13046
|
var valid = width != null && Number.isFinite(width) && width >= 0;
|
|
13004
13047
|
estimated || (estimated = !valid);
|
|
13005
|
-
advance += valid ? width :
|
|
13048
|
+
advance += valid ? width : estimateTextWidth(chunk, measurementSize, 0, undefined, family, weight, style);
|
|
13006
13049
|
}
|
|
13007
|
-
var characterCount =
|
|
13050
|
+
var characterCount = characters.length;
|
|
13008
13051
|
var width1 = advance * scale + Math.max(0, characterCount - 1) * spacing;
|
|
13009
|
-
var
|
|
13010
|
-
var
|
|
13052
|
+
var fallback = resolveFontMetrics(undefined, family, weight, style, run.fontSize);
|
|
13053
|
+
var ascent = (metrics == null ? void 0 : metrics.fontBoundingBoxAscent) == null ? fallback.asc : metrics.fontBoundingBoxAscent * scale;
|
|
13054
|
+
var descent = (metrics == null ? void 0 : metrics.fontBoundingBoxDescent) == null ? fallback.desc : metrics.fontBoundingBoxDescent * scale;
|
|
13011
13055
|
estimated || (estimated = (metrics == null ? void 0 : metrics.fontBoundingBoxAscent) == null || metrics.fontBoundingBoxDescent == null);
|
|
13012
13056
|
if (!Number.isFinite(width1) || width1 < 0 || !Number.isFinite(ascent) || !Number.isFinite(descent)) {
|
|
13013
13057
|
throwInvalidLayerData('Text measurement returned invalid metrics.');
|
|
@@ -13154,6 +13198,7 @@ function convertIRTextLayer(layer, state, session, id) {
|
|
|
13154
13198
|
content: part.run.text,
|
|
13155
13199
|
bbox: mapPointsToBBox(polygon),
|
|
13156
13200
|
polygon: polygon,
|
|
13201
|
+
// Keep the authored font-family string, quotes included; consumers resolve families themselves.
|
|
13157
13202
|
font_family: font.family,
|
|
13158
13203
|
font_size: roundPixel(part.run.fontSize * scaleY),
|
|
13159
13204
|
color: part.run.color,
|
|
@@ -13198,6 +13243,41 @@ function createLayerConverterRegistry(session) {
|
|
|
13198
13243
|
]);
|
|
13199
13244
|
}
|
|
13200
13245
|
|
|
13246
|
+
/** 完全覆盖图片的直边矩形 mask 不改变可见内容。 */ function maskCoversImage(mask, bounds) {
|
|
13247
|
+
var _Math, _Math1, _Math2, _Math3;
|
|
13248
|
+
var path = mask.path;
|
|
13249
|
+
var epsilon = 1e-6;
|
|
13250
|
+
if (mask.mode === 'subtract' || mask.inverted === true || !path.closed || path.points.length !== 4) {
|
|
13251
|
+
return false;
|
|
13252
|
+
}
|
|
13253
|
+
if (path.inTangents.length !== 4 || path.outTangents.length !== 4 || [].concat(path.inTangents, path.outTangents).some(function(tangent) {
|
|
13254
|
+
return tangent.x !== 0 || tangent.y !== 0;
|
|
13255
|
+
})) {
|
|
13256
|
+
return false;
|
|
13257
|
+
}
|
|
13258
|
+
var straightEdges = path.points.every(function(point, index) {
|
|
13259
|
+
var next = path.points[(index + 1) % 4];
|
|
13260
|
+
var opposite = path.points[(index + 2) % 4];
|
|
13261
|
+
var dx = Math.abs(next.x - point.x);
|
|
13262
|
+
var dy = Math.abs(next.y - point.y);
|
|
13263
|
+
return Number.isFinite(point.x) && Number.isFinite(point.y) && Math.abs(opposite.x - point.x) > epsilon && Math.abs(opposite.y - point.y) > epsilon && (dx <= epsilon && dy > epsilon || dy <= epsilon && dx > epsilon);
|
|
13264
|
+
});
|
|
13265
|
+
if (!straightEdges) {
|
|
13266
|
+
return false;
|
|
13267
|
+
}
|
|
13268
|
+
var xs = path.points.map(function(point) {
|
|
13269
|
+
return point.x;
|
|
13270
|
+
});
|
|
13271
|
+
var ys = path.points.map(function(point) {
|
|
13272
|
+
return point.y;
|
|
13273
|
+
});
|
|
13274
|
+
var left = (_Math = Math).min.apply(_Math, [].concat(xs));
|
|
13275
|
+
var right = (_Math1 = Math).max.apply(_Math1, [].concat(xs));
|
|
13276
|
+
var top = (_Math2 = Math).min.apply(_Math2, [].concat(ys));
|
|
13277
|
+
var bottom = (_Math3 = Math).max.apply(_Math3, [].concat(ys));
|
|
13278
|
+
return bounds.width > 0 && bounds.height > 0 && left <= bounds.x + epsilon && right >= bounds.x + bounds.width - epsilon && top <= bounds.y + epsilon && bottom >= bounds.y + bounds.height - epsilon;
|
|
13279
|
+
}
|
|
13280
|
+
|
|
13201
13281
|
function resolveIRVisualState(layer, session) {
|
|
13202
13282
|
if (!layer.visible) {
|
|
13203
13283
|
return undefined;
|
|
@@ -13206,19 +13286,20 @@ function resolveIRVisualState(layer, session) {
|
|
|
13206
13286
|
if (!state.visible || state.opacity <= 0) {
|
|
13207
13287
|
return undefined;
|
|
13208
13288
|
}
|
|
13209
|
-
|
|
13289
|
+
var unsupportedMask = layer.mask != null && (layer.type !== 'image' || !maskCoversImage(layer.mask, layer.localBounds));
|
|
13290
|
+
if (unsupportedMask || layer.matte != null) {
|
|
13210
13291
|
throwUnsupportedLayerFeature('Mask or clipping is not supported by the flat layer protocol.');
|
|
13211
13292
|
}
|
|
13212
13293
|
if (Math.abs(state.opacity - 1) > 1e-6) {
|
|
13213
13294
|
throwUnsupportedLayerFeature('Layer opacity cannot be expressed by the target protocol.');
|
|
13214
13295
|
}
|
|
13215
13296
|
if (layer.blendMode != null && layer.blendMode !== IRBlendMode.Normal) {
|
|
13216
|
-
|
|
13297
|
+
collectLayerWarning(session.warnings, session.options, SVG2IR_WARNING_CODES.LAYERS_BLEND_MODE_DOWNGRADED, 'Blend mode "' + String(layer.blendMode) + '" was downgraded to "normal"; the layer is retained.', layer.id);
|
|
13217
13298
|
}
|
|
13218
13299
|
return state;
|
|
13219
13300
|
}
|
|
13220
13301
|
|
|
13221
|
-
function buildIRStaticLayers(session) {
|
|
13302
|
+
function buildIRStaticLayers(session, sourceIds) {
|
|
13222
13303
|
var composition = session.composition, maskSourceIds = session.maskSourceIds, options = session.options, warnings = session.warnings;
|
|
13223
13304
|
var registry = createLayerConverterRegistry(session);
|
|
13224
13305
|
var result = [];
|
|
@@ -13243,6 +13324,7 @@ function buildIRStaticLayers(session) {
|
|
|
13243
13324
|
var converted = converter.convert(layer, state, converter.layerType + "_" + String(index).padStart(4, '0'));
|
|
13244
13325
|
if (converted != null) {
|
|
13245
13326
|
result.push(converted);
|
|
13327
|
+
sourceIds == null ? void 0 : sourceIds.set(converted, layer.id);
|
|
13246
13328
|
layerCounts.set(converter.layerType, index);
|
|
13247
13329
|
}
|
|
13248
13330
|
} catch (error) {
|
|
@@ -13255,9 +13337,9 @@ function buildIRStaticLayers(session) {
|
|
|
13255
13337
|
return result;
|
|
13256
13338
|
}
|
|
13257
13339
|
|
|
13258
|
-
function assembleSVGStaticLayers(scene, options, warnings, preservedData) {
|
|
13340
|
+
function assembleSVGStaticLayers(scene, options, warnings, preservedData, sourceIds) {
|
|
13259
13341
|
var session = buildLayerConversionSession(scene, options, warnings, preservedData);
|
|
13260
|
-
var data = buildIRStaticLayers(session);
|
|
13342
|
+
var data = buildIRStaticLayers(session, sourceIds);
|
|
13261
13343
|
var composition = session.composition;
|
|
13262
13344
|
if (composition.backgroundColor != null) {
|
|
13263
13345
|
collectLayerWarning(warnings, options, SVG2IR_WARNING_CODES.LAYERS_UNSUPPORTED_TYPE, 'Composition background color is not an image or text layer.');
|
|
@@ -13270,6 +13352,1034 @@ function assembleSVGStaticLayers(scene, options, warnings, preservedData) {
|
|
|
13270
13352
|
data: data
|
|
13271
13353
|
};
|
|
13272
13354
|
}
|
|
13355
|
+
/** Replace baked sources, combine native and raster layers in painter order, then report final diagnostics. */ function assembleSVGLayers(input) {
|
|
13356
|
+
var _warnings, _ordered;
|
|
13357
|
+
var scene = input.scene, options = input.options, preservedData = input.preservedData, layerSources = input.layerSources, warningSources = input.warningSources, baking = input.baking;
|
|
13358
|
+
var warnings = input.warnings.filter(function(warning) {
|
|
13359
|
+
return !baking.resolvesWarning(warning, warningSources.get(warning));
|
|
13360
|
+
});
|
|
13361
|
+
var composition = getIRSceneEntryComposition(scene);
|
|
13362
|
+
var nativeScene = _extends({}, scene, {
|
|
13363
|
+
compositions: scene.compositions.map(function(candidate) {
|
|
13364
|
+
return candidate === composition ? _extends({}, candidate, {
|
|
13365
|
+
layers: candidate.layers.filter(function(layer) {
|
|
13366
|
+
return !baking.replacesSource(layerSources.get(layer.id));
|
|
13367
|
+
})
|
|
13368
|
+
}) : candidate;
|
|
13369
|
+
})
|
|
13370
|
+
});
|
|
13371
|
+
var sourceIds = new Map();
|
|
13372
|
+
(_warnings = warnings).push.apply(_warnings, [].concat(baking.warnings));
|
|
13373
|
+
var native = assembleSVGStaticLayers(nativeScene, _extends({}, options, {
|
|
13374
|
+
strict: false,
|
|
13375
|
+
onWarning: undefined
|
|
13376
|
+
}), warnings, preservedData, sourceIds);
|
|
13377
|
+
var ordered = native.data.map(function(layer) {
|
|
13378
|
+
var _layerSources_get, _sourceIds_get;
|
|
13379
|
+
return {
|
|
13380
|
+
path: (_layerSources_get = layerSources.get((_sourceIds_get = sourceIds.get(layer)) != null ? _sourceIds_get : '')) != null ? _layerSources_get : '',
|
|
13381
|
+
layer: layer
|
|
13382
|
+
};
|
|
13383
|
+
});
|
|
13384
|
+
(_ordered = ordered).push.apply(_ordered, [].concat(baking.layers));
|
|
13385
|
+
ordered.sort(function(left, right) {
|
|
13386
|
+
return comparePaths(left.path, right.path);
|
|
13387
|
+
});
|
|
13388
|
+
var counts = {
|
|
13389
|
+
image: 0,
|
|
13390
|
+
text: 0
|
|
13391
|
+
};
|
|
13392
|
+
var data = ordered.map(function(param) {
|
|
13393
|
+
var layer = param.layer;
|
|
13394
|
+
return _extends({}, layer, {
|
|
13395
|
+
id: layer.type + "_" + String(++counts[layer.type]).padStart(4, '0')
|
|
13396
|
+
});
|
|
13397
|
+
});
|
|
13398
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(warnings), _step; !(_step = _iterator()).done;){
|
|
13399
|
+
var warning = _step.value;
|
|
13400
|
+
options.onWarning == null ? void 0 : options.onWarning.call(options, warning);
|
|
13401
|
+
if (options.strict === true) {
|
|
13402
|
+
var message = warning.message.replace(/^\[svg2ge:layers\] /, '');
|
|
13403
|
+
collectLayerWarning([], _extends({}, options, {
|
|
13404
|
+
onWarning: undefined
|
|
13405
|
+
}), warning.code, message, warning.elementSelector);
|
|
13406
|
+
}
|
|
13407
|
+
}
|
|
13408
|
+
return {
|
|
13409
|
+
size: native.size,
|
|
13410
|
+
data: data,
|
|
13411
|
+
warnings: warnings
|
|
13412
|
+
};
|
|
13413
|
+
}
|
|
13414
|
+
function comparePaths(left, right) {
|
|
13415
|
+
var a = left.split('/').map(Number);
|
|
13416
|
+
var b = right.split('/').map(Number);
|
|
13417
|
+
for(var index = 0; index < Math.min(a.length, b.length); index++){
|
|
13418
|
+
if (a[index] !== b[index]) {
|
|
13419
|
+
return a[index] - b[index];
|
|
13420
|
+
}
|
|
13421
|
+
}
|
|
13422
|
+
return a.length - b.length;
|
|
13423
|
+
}
|
|
13424
|
+
|
|
13425
|
+
var animatedElements = new Set([
|
|
13426
|
+
'animate',
|
|
13427
|
+
'animatetransform',
|
|
13428
|
+
'animatemotion',
|
|
13429
|
+
'set'
|
|
13430
|
+
]);
|
|
13431
|
+
var declarations$1 = new Set([
|
|
13432
|
+
'defs',
|
|
13433
|
+
'style',
|
|
13434
|
+
'title',
|
|
13435
|
+
'desc',
|
|
13436
|
+
'metadata',
|
|
13437
|
+
'symbol',
|
|
13438
|
+
'clippath',
|
|
13439
|
+
'mask',
|
|
13440
|
+
'filter',
|
|
13441
|
+
'lineargradient',
|
|
13442
|
+
'radialgradient',
|
|
13443
|
+
'pattern',
|
|
13444
|
+
'marker'
|
|
13445
|
+
]);
|
|
13446
|
+
/** Preserve selector context until styles are frozen, then isolate the requested paint subtree. */ function prepareSVGSnapshot(source, path, size, inspect) {
|
|
13447
|
+
var parsed = new DOMParser().parseFromString(source, 'image/svg+xml');
|
|
13448
|
+
if (parsed.querySelector('parsererror') != null) {
|
|
13449
|
+
throw new Error('Invalid SVG document.');
|
|
13450
|
+
}
|
|
13451
|
+
var root = parsed.documentElement;
|
|
13452
|
+
var elements = [].concat([
|
|
13453
|
+
root
|
|
13454
|
+
], Array.from(root.querySelectorAll('*')));
|
|
13455
|
+
var selected = elements.find(function(element) {
|
|
13456
|
+
return buildElementTreePath(element) === path;
|
|
13457
|
+
});
|
|
13458
|
+
if (selected == null) {
|
|
13459
|
+
throw new Error('The graphic source element could not be located.');
|
|
13460
|
+
}
|
|
13461
|
+
if (root.querySelector('script, foreignObject') != null) {
|
|
13462
|
+
throw new Error('Scripts and foreignObject are outside static graphic baking support.');
|
|
13463
|
+
}
|
|
13464
|
+
if (Array.from(root.querySelectorAll('style')).some(function(element) {
|
|
13465
|
+
var _element_textContent;
|
|
13466
|
+
return /@import|@font-face/i.test((_element_textContent = element.textContent) != null ? _element_textContent : '');
|
|
13467
|
+
})) {
|
|
13468
|
+
throw new Error('External stylesheets and fonts require explicit resource preparation.');
|
|
13469
|
+
}
|
|
13470
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(elements), _step; !(_step = _iterator()).done;){
|
|
13471
|
+
var element = _step.value;
|
|
13472
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(Array.from(element.attributes)), _step1; !(_step1 = _iterator1()).done;){
|
|
13473
|
+
var attribute = _step1.value;
|
|
13474
|
+
if (/^on/i.test(attribute.name)) {
|
|
13475
|
+
element.removeAttributeNode(attribute);
|
|
13476
|
+
}
|
|
13477
|
+
}
|
|
13478
|
+
}
|
|
13479
|
+
var frame = document.createElement('iframe');
|
|
13480
|
+
frame.setAttribute('sandbox', 'allow-same-origin');
|
|
13481
|
+
frame.style.cssText = "position:fixed;left:-100000px;top:0;width:" + size[0] + "px;height:" + size[1] + "px;border:0;";
|
|
13482
|
+
document.body.appendChild(frame);
|
|
13483
|
+
try {
|
|
13484
|
+
var _loop = function() {
|
|
13485
|
+
var element = _step3.value;
|
|
13486
|
+
var _element_getAttribute;
|
|
13487
|
+
var computed = frameWindow.getComputedStyle(element);
|
|
13488
|
+
var inside = target.contains(element);
|
|
13489
|
+
var ancestor = element !== target && element.contains(target);
|
|
13490
|
+
if ((inside || ancestor) && (computed.animationName !== 'none' || hasAnimationChildren(element))) {
|
|
13491
|
+
throw new Error('Animated graphics require an explicit sampling policy.');
|
|
13492
|
+
}
|
|
13493
|
+
// Freezing inherited defaults on a definition changes <use> instance inheritance.
|
|
13494
|
+
// Freeze only authored declarations, after matching selectors in the intact source tree.
|
|
13495
|
+
var authored = frameDocument.createElement('div').style;
|
|
13496
|
+
authored.cssText = (_element_getAttribute = element.getAttribute('style')) != null ? _element_getAttribute : '';
|
|
13497
|
+
var names = new Set(Array.from(authored));
|
|
13498
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(styleRules), _step; !(_step = _iterator()).done;){
|
|
13499
|
+
var rule = _step.value;
|
|
13500
|
+
if (element.matches(rule.selectorText)) {
|
|
13501
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(Array.from(rule.style)), _step1; !(_step1 = _iterator1()).done;){
|
|
13502
|
+
var name = _step1.value;
|
|
13503
|
+
names.add(name);
|
|
13504
|
+
}
|
|
13505
|
+
}
|
|
13506
|
+
}
|
|
13507
|
+
var properties = Array.from(names, function(name) {
|
|
13508
|
+
var value = computed.getPropertyValue(name);
|
|
13509
|
+
value = value.replace(/url\(["']?([^)'"\s]+)["']?\)/g, function(_match, url) {
|
|
13510
|
+
return 'url("' + normalizeReference(url) + '")';
|
|
13511
|
+
});
|
|
13512
|
+
return name + ":" + value + " !important;";
|
|
13513
|
+
});
|
|
13514
|
+
var isTemplate = templateRoots.some(function(template) {
|
|
13515
|
+
return template.contains(element);
|
|
13516
|
+
});
|
|
13517
|
+
frozenStyles.push(isTemplate ? null : properties.join(''));
|
|
13518
|
+
};
|
|
13519
|
+
var frameDocument = frame.contentDocument;
|
|
13520
|
+
var frameWindow = frame.contentWindow;
|
|
13521
|
+
if (frameDocument == null || frameWindow == null) {
|
|
13522
|
+
throw new Error('Unable to create isolated SVG context.');
|
|
13523
|
+
}
|
|
13524
|
+
frameDocument.body.style.cssText = 'margin:0;';
|
|
13525
|
+
var mounted = frameDocument.importNode(root, true);
|
|
13526
|
+
mounted.setAttribute('width', String(size[0]));
|
|
13527
|
+
mounted.setAttribute('height', String(size[1]));
|
|
13528
|
+
frameDocument.body.appendChild(mounted);
|
|
13529
|
+
var mountedElements = [].concat([
|
|
13530
|
+
mounted
|
|
13531
|
+
], Array.from(mounted.querySelectorAll('*')));
|
|
13532
|
+
var selectedIndex = elements.indexOf(selected);
|
|
13533
|
+
var target = mountedElements[selectedIndex];
|
|
13534
|
+
var normalizeReference = function normalizeReference(url) {
|
|
13535
|
+
if (url.startsWith('#')) {
|
|
13536
|
+
return url;
|
|
13537
|
+
}
|
|
13538
|
+
var hash = url.indexOf('#');
|
|
13539
|
+
if (hash >= 0 && url.slice(0, hash) === frameDocument.baseURI.split('#')[0]) {
|
|
13540
|
+
return url.slice(hash);
|
|
13541
|
+
}
|
|
13542
|
+
throw new Error('External paint resources require explicit resource preparation.');
|
|
13543
|
+
};
|
|
13544
|
+
var frozenStyles = [];
|
|
13545
|
+
var templateRoots = Array.from(mounted.querySelectorAll('use')).flatMap(function(element) {
|
|
13546
|
+
var _ref, _element_getAttribute;
|
|
13547
|
+
var href = (_ref = (_element_getAttribute = element.getAttribute('href')) != null ? _element_getAttribute : element.getAttribute('xlink:href')) != null ? _ref : '';
|
|
13548
|
+
var template = href.startsWith('#') ? mountedElements.find(function(candidate) {
|
|
13549
|
+
return candidate.id === href.slice(1);
|
|
13550
|
+
}) : null;
|
|
13551
|
+
return template == null ? [] : [
|
|
13552
|
+
template
|
|
13553
|
+
];
|
|
13554
|
+
});
|
|
13555
|
+
var styleRules = [];
|
|
13556
|
+
var collectRules = function collectRules1(rules) {
|
|
13557
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(Array.from(rules)), _step; !(_step = _iterator()).done;){
|
|
13558
|
+
var rule = _step.value;
|
|
13559
|
+
if (isStyleRule$2(rule)) {
|
|
13560
|
+
styleRules.push(rule);
|
|
13561
|
+
} else if (hasNestedRules$1(rule)) {
|
|
13562
|
+
if (isMediaRule(rule) && !frameWindow.matchMedia(rule.conditionText).matches) {
|
|
13563
|
+
continue;
|
|
13564
|
+
}
|
|
13565
|
+
collectRules(rule.cssRules);
|
|
13566
|
+
}
|
|
13567
|
+
}
|
|
13568
|
+
};
|
|
13569
|
+
for(var _iterator2 = _create_for_of_iterator_helper_loose(Array.from(frameDocument.styleSheets)), _step2; !(_step2 = _iterator2()).done;){
|
|
13570
|
+
var sheet = _step2.value;
|
|
13571
|
+
collectRules(sheet.cssRules);
|
|
13572
|
+
}
|
|
13573
|
+
for(var _iterator3 = _create_for_of_iterator_helper_loose(mountedElements), _step3; !(_step3 = _iterator3()).done;)_loop();
|
|
13574
|
+
for(var index = 0; index < mountedElements.length; index++){
|
|
13575
|
+
var style = frozenStyles[index];
|
|
13576
|
+
if (style != null) {
|
|
13577
|
+
mountedElements[index].setAttribute('style', style);
|
|
13578
|
+
}
|
|
13579
|
+
}
|
|
13580
|
+
var byId = new Map(mountedElements.filter(function(element) {
|
|
13581
|
+
return element.id !== '';
|
|
13582
|
+
}).map(function(element) {
|
|
13583
|
+
return [
|
|
13584
|
+
element.id,
|
|
13585
|
+
element
|
|
13586
|
+
];
|
|
13587
|
+
}));
|
|
13588
|
+
var seen = new Set();
|
|
13589
|
+
var checkDependencies = function checkDependencies1(element) {
|
|
13590
|
+
if (seen.has(element)) {
|
|
13591
|
+
return;
|
|
13592
|
+
}
|
|
13593
|
+
seen.add(element);
|
|
13594
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(Array.from(element.attributes)), _step; !(_step = _iterator()).done;){
|
|
13595
|
+
var attribute = _step.value;
|
|
13596
|
+
if (attribute.localName === 'href' && element.tagName.toLowerCase() === 'a') {
|
|
13597
|
+
continue;
|
|
13598
|
+
}
|
|
13599
|
+
if (attribute.localName === 'href' && !attribute.value.startsWith('#') && !([
|
|
13600
|
+
'image',
|
|
13601
|
+
'feimage'
|
|
13602
|
+
].includes(element.tagName.toLowerCase()) && /^data:image\//i.test(attribute.value))) {
|
|
13603
|
+
throw new Error('External SVG references require explicit resource preparation.');
|
|
13604
|
+
}
|
|
13605
|
+
var normalized = attribute.value.replace(/url\(\s*["']?([^)'"\s]+)["']?\s*\)/g, function(_match, url) {
|
|
13606
|
+
return 'url("' + normalizeReference(url) + '")';
|
|
13607
|
+
});
|
|
13608
|
+
var ids = Array.from(normalized.matchAll(/url\(["']?#([^)'"\s]+)["']?\)/g), function(match) {
|
|
13609
|
+
return match[1];
|
|
13610
|
+
});
|
|
13611
|
+
if (normalized !== attribute.value) {
|
|
13612
|
+
element.setAttribute(attribute.name, normalized);
|
|
13613
|
+
}
|
|
13614
|
+
if (attribute.localName === 'href' && attribute.value.startsWith('#')) {
|
|
13615
|
+
ids.push(attribute.value.slice(1));
|
|
13616
|
+
}
|
|
13617
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(ids), _step1; !(_step1 = _iterator1()).done;){
|
|
13618
|
+
var id = _step1.value;
|
|
13619
|
+
var dependency = byId.get(id);
|
|
13620
|
+
if (dependency == null) {
|
|
13621
|
+
throw new Error("Missing SVG reference: #" + id + ".");
|
|
13622
|
+
}
|
|
13623
|
+
checkDependencies(dependency);
|
|
13624
|
+
}
|
|
13625
|
+
}
|
|
13626
|
+
for(var _iterator2 = _create_for_of_iterator_helper_loose(Array.from(element.children)), _step2; !(_step2 = _iterator2()).done;){
|
|
13627
|
+
var child = _step2.value;
|
|
13628
|
+
if (!declarations$1.has(child.tagName.toLowerCase())) {
|
|
13629
|
+
checkDependencies(child);
|
|
13630
|
+
}
|
|
13631
|
+
}
|
|
13632
|
+
};
|
|
13633
|
+
checkDependencies(target);
|
|
13634
|
+
for(var _iterator4 = _create_for_of_iterator_helper_loose(seen), _step4; !(_step4 = _iterator4()).done;){
|
|
13635
|
+
var dependency = _step4.value;
|
|
13636
|
+
if (frameWindow.getComputedStyle(dependency).animationName !== 'none' || hasAnimationChildren(dependency)) {
|
|
13637
|
+
throw new Error('Animated graphics require an explicit sampling policy.');
|
|
13638
|
+
}
|
|
13639
|
+
}
|
|
13640
|
+
inspect == null ? void 0 : inspect({
|
|
13641
|
+
root: mounted,
|
|
13642
|
+
target: target,
|
|
13643
|
+
elements: mountedElements,
|
|
13644
|
+
dependencies: seen,
|
|
13645
|
+
readStyle: function readStyle(element) {
|
|
13646
|
+
return frameWindow.getComputedStyle(element);
|
|
13647
|
+
}
|
|
13648
|
+
});
|
|
13649
|
+
var isolate = function isolate1(element) {
|
|
13650
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(Array.from(element.children)), _step; !(_step = _iterator()).done;){
|
|
13651
|
+
var child = _step.value;
|
|
13652
|
+
var tag = child.tagName.toLowerCase();
|
|
13653
|
+
if (declarations$1.has(tag) || child === target || target.contains(child)) {
|
|
13654
|
+
continue;
|
|
13655
|
+
}
|
|
13656
|
+
if (child.contains(target)) {
|
|
13657
|
+
isolate(child);
|
|
13658
|
+
} else {
|
|
13659
|
+
var definitions = frameDocument.createElementNS('http://www.w3.org/2000/svg', 'defs');
|
|
13660
|
+
child.replaceWith(definitions);
|
|
13661
|
+
definitions.appendChild(child);
|
|
13662
|
+
}
|
|
13663
|
+
}
|
|
13664
|
+
};
|
|
13665
|
+
if (target !== mounted) {
|
|
13666
|
+
isolate(mounted);
|
|
13667
|
+
}
|
|
13668
|
+
return new XMLSerializer().serializeToString(mounted);
|
|
13669
|
+
} finally{
|
|
13670
|
+
frame.remove();
|
|
13671
|
+
}
|
|
13672
|
+
}
|
|
13673
|
+
/** Only animations attached to this element reject its own bake scope, not unrelated subtrees. */ function hasAnimationChildren(element) {
|
|
13674
|
+
return Array.from(element.children).some(function(child) {
|
|
13675
|
+
return animatedElements.has(child.tagName.toLowerCase());
|
|
13676
|
+
});
|
|
13677
|
+
}
|
|
13678
|
+
function isStyleRule$2(rule) {
|
|
13679
|
+
return rule.type === 1;
|
|
13680
|
+
}
|
|
13681
|
+
function hasNestedRules$1(rule) {
|
|
13682
|
+
return 'cssRules' in rule;
|
|
13683
|
+
}
|
|
13684
|
+
function isMediaRule(rule) {
|
|
13685
|
+
return rule.type === 4;
|
|
13686
|
+
}
|
|
13687
|
+
|
|
13688
|
+
/** Render an SVG subtree as a cropped PNG, or return null if it has no visible pixels. */ function rasterizeSVG(source, path, size, scale, inspect) {
|
|
13689
|
+
if (scale === void 0) scale = 2;
|
|
13690
|
+
return _async_to_generator(function() {
|
|
13691
|
+
var snapshot, canvas;
|
|
13692
|
+
return _ts_generator(this, function(_state) {
|
|
13693
|
+
switch(_state.label){
|
|
13694
|
+
case 0:
|
|
13695
|
+
if (!Number.isFinite(scale) || scale <= 0) {
|
|
13696
|
+
throw new RangeError('rasterScale must be finite and positive.');
|
|
13697
|
+
}
|
|
13698
|
+
if (Math.ceil(size[0] * scale) * Math.ceil(size[1] * scale) > 16777216) {
|
|
13699
|
+
throw new RangeError('SVG rasterization exceeds the 16 megapixel working limit; reduce rasterScale.');
|
|
13700
|
+
}
|
|
13701
|
+
snapshot = prepareSVGSnapshot(source, path, size, inspect);
|
|
13702
|
+
return [
|
|
13703
|
+
4,
|
|
13704
|
+
renderSVG(snapshot, size, scale)
|
|
13705
|
+
];
|
|
13706
|
+
case 1:
|
|
13707
|
+
canvas = _state.sent();
|
|
13708
|
+
return [
|
|
13709
|
+
2,
|
|
13710
|
+
cropRasterImage(canvas, scale)
|
|
13711
|
+
];
|
|
13712
|
+
}
|
|
13713
|
+
});
|
|
13714
|
+
})();
|
|
13715
|
+
}
|
|
13716
|
+
/** No DOM access at module initialization: the Node entry also imports this module. */ function canRasterizeSVG() {
|
|
13717
|
+
return typeof window !== 'undefined' && typeof document !== 'undefined' && typeof window.HTMLCanvasElement === 'function' && typeof window.Image === 'function' && typeof window.getComputedStyle === 'function';
|
|
13718
|
+
}
|
|
13719
|
+
function renderSVG(svg, size, scale) {
|
|
13720
|
+
return _async_to_generator(function() {
|
|
13721
|
+
var canvas, context, image, url;
|
|
13722
|
+
return _ts_generator(this, function(_state) {
|
|
13723
|
+
switch(_state.label){
|
|
13724
|
+
case 0:
|
|
13725
|
+
canvas = document.createElement('canvas');
|
|
13726
|
+
canvas.width = Math.ceil(size[0] * scale);
|
|
13727
|
+
canvas.height = Math.ceil(size[1] * scale);
|
|
13728
|
+
context = canvas.getContext('2d');
|
|
13729
|
+
if (context == null) {
|
|
13730
|
+
throw new Error('A 2D canvas context is required for SVG rasterization.');
|
|
13731
|
+
}
|
|
13732
|
+
image = new Image();
|
|
13733
|
+
url = URL.createObjectURL(new Blob([
|
|
13734
|
+
svg
|
|
13735
|
+
], {
|
|
13736
|
+
type: 'image/svg+xml'
|
|
13737
|
+
}));
|
|
13738
|
+
_state.label = 1;
|
|
13739
|
+
case 1:
|
|
13740
|
+
_state.trys.push([
|
|
13741
|
+
1,
|
|
13742
|
+
,
|
|
13743
|
+
3,
|
|
13744
|
+
4
|
|
13745
|
+
]);
|
|
13746
|
+
return [
|
|
13747
|
+
4,
|
|
13748
|
+
new Promise(function(resolve, reject) {
|
|
13749
|
+
image.onload = function() {
|
|
13750
|
+
return resolve();
|
|
13751
|
+
};
|
|
13752
|
+
image.onerror = function() {
|
|
13753
|
+
return reject(new Error('The prepared SVG could not be decoded.'));
|
|
13754
|
+
};
|
|
13755
|
+
image.src = url;
|
|
13756
|
+
})
|
|
13757
|
+
];
|
|
13758
|
+
case 2:
|
|
13759
|
+
_state.sent();
|
|
13760
|
+
context.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
13761
|
+
return [
|
|
13762
|
+
2,
|
|
13763
|
+
canvas
|
|
13764
|
+
];
|
|
13765
|
+
case 3:
|
|
13766
|
+
URL.revokeObjectURL(url);
|
|
13767
|
+
return [
|
|
13768
|
+
7
|
|
13769
|
+
];
|
|
13770
|
+
case 4:
|
|
13771
|
+
return [
|
|
13772
|
+
2
|
|
13773
|
+
];
|
|
13774
|
+
}
|
|
13775
|
+
});
|
|
13776
|
+
})();
|
|
13777
|
+
}
|
|
13778
|
+
/** Trim transparent pixels after rendering, retaining strokes, blur and filter extents. */ function cropRasterImage(canvas, scale) {
|
|
13779
|
+
var context = canvas.getContext('2d');
|
|
13780
|
+
if (context == null) {
|
|
13781
|
+
throw new Error('A 2D canvas context is required for SVG rasterization.');
|
|
13782
|
+
}
|
|
13783
|
+
var data = context.getImageData(0, 0, canvas.width, canvas.height).data;
|
|
13784
|
+
var left = canvas.width;
|
|
13785
|
+
var top = canvas.height;
|
|
13786
|
+
var right = 0;
|
|
13787
|
+
var bottom = 0;
|
|
13788
|
+
for(var y = 0; y < canvas.height; y++){
|
|
13789
|
+
for(var x = 0; x < canvas.width; x++){
|
|
13790
|
+
if (data[(y * canvas.width + x) * 4 + 3] === 0) {
|
|
13791
|
+
continue;
|
|
13792
|
+
}
|
|
13793
|
+
left = Math.min(left, x);
|
|
13794
|
+
top = Math.min(top, y);
|
|
13795
|
+
right = Math.max(right, x + 1);
|
|
13796
|
+
bottom = Math.max(bottom, y + 1);
|
|
13797
|
+
}
|
|
13798
|
+
}
|
|
13799
|
+
if (right <= left || bottom <= top) {
|
|
13800
|
+
return null;
|
|
13801
|
+
}
|
|
13802
|
+
var cropped = document.createElement('canvas');
|
|
13803
|
+
cropped.width = right - left;
|
|
13804
|
+
cropped.height = bottom - top;
|
|
13805
|
+
var croppedContext = cropped.getContext('2d');
|
|
13806
|
+
if (croppedContext == null) {
|
|
13807
|
+
throw new Error('A 2D canvas context is required for SVG rasterization.');
|
|
13808
|
+
}
|
|
13809
|
+
croppedContext.drawImage(canvas, left, top, cropped.width, cropped.height, 0, 0, cropped.width, cropped.height);
|
|
13810
|
+
return {
|
|
13811
|
+
url: cropped.toDataURL('image/png'),
|
|
13812
|
+
bbox: [
|
|
13813
|
+
left / scale,
|
|
13814
|
+
top / scale,
|
|
13815
|
+
right / scale,
|
|
13816
|
+
bottom / scale
|
|
13817
|
+
]
|
|
13818
|
+
};
|
|
13819
|
+
}
|
|
13820
|
+
|
|
13821
|
+
var normalValues = new Set([
|
|
13822
|
+
'normal',
|
|
13823
|
+
'initial',
|
|
13824
|
+
'inherit',
|
|
13825
|
+
'unset',
|
|
13826
|
+
'revert',
|
|
13827
|
+
'revert-layer'
|
|
13828
|
+
]);
|
|
13829
|
+
/** Replace non-normal mix-blend-mode declarations with normal and report each downgrade. */ function normalizeLayerBlending(source) {
|
|
13830
|
+
var _loop = function() {
|
|
13831
|
+
var element = _step.value;
|
|
13832
|
+
var _element_getAttribute;
|
|
13833
|
+
var _readPresentationAttribute;
|
|
13834
|
+
var tag = element.tagName.toLowerCase();
|
|
13835
|
+
var id = (_element_getAttribute = element.getAttribute('id')) != null ? _element_getAttribute : '';
|
|
13836
|
+
var selector = id === '' ? tag : tag + "#" + id;
|
|
13837
|
+
var mode = (_readPresentationAttribute = readPresentationAttribute(element, 'mix-blend-mode')) == null ? void 0 : _readPresentationAttribute.replace(/\/\*[\s\S]*?\*\//g, '').trim();
|
|
13838
|
+
if (mode != null && !normalValues.has(mode.toLowerCase())) {
|
|
13839
|
+
downgrades.push({
|
|
13840
|
+
mode: mode,
|
|
13841
|
+
selector: selector
|
|
13842
|
+
});
|
|
13843
|
+
}
|
|
13844
|
+
var style = element.getAttribute('style');
|
|
13845
|
+
if (style != null) {
|
|
13846
|
+
var normalized = normalizeBlendDeclarations(style);
|
|
13847
|
+
if (normalized !== style) {
|
|
13848
|
+
element.setAttribute('style', normalized);
|
|
13849
|
+
changed = true;
|
|
13850
|
+
}
|
|
13851
|
+
}
|
|
13852
|
+
var attribute = element.getAttribute('mix-blend-mode');
|
|
13853
|
+
if (attribute != null && !normalValues.has(attribute.trim().toLowerCase())) {
|
|
13854
|
+
element.setAttribute('mix-blend-mode', 'normal');
|
|
13855
|
+
changed = true;
|
|
13856
|
+
}
|
|
13857
|
+
if (tag === 'style') {
|
|
13858
|
+
var _element_textContent;
|
|
13859
|
+
var text = (_element_textContent = element.textContent) != null ? _element_textContent : '';
|
|
13860
|
+
var normalized1 = normalizeBlendDeclarations(text, function(value) {
|
|
13861
|
+
return downgrades.push({
|
|
13862
|
+
mode: value,
|
|
13863
|
+
selector: selector
|
|
13864
|
+
});
|
|
13865
|
+
});
|
|
13866
|
+
if (normalized1 !== text) {
|
|
13867
|
+
element.textContent = normalized1;
|
|
13868
|
+
changed = true;
|
|
13869
|
+
}
|
|
13870
|
+
}
|
|
13871
|
+
};
|
|
13872
|
+
var svg = SVG(source);
|
|
13873
|
+
var downgrades = [];
|
|
13874
|
+
var changed = false;
|
|
13875
|
+
for(var _iterator = _create_for_of_iterator_helper_loose([].concat([
|
|
13876
|
+
svg.node
|
|
13877
|
+
], Array.from(svg.node.querySelectorAll('*')))), _step; !(_step = _iterator()).done;)_loop();
|
|
13878
|
+
return {
|
|
13879
|
+
source: changed ? svg.svg() : source,
|
|
13880
|
+
downgrades: downgrades
|
|
13881
|
+
};
|
|
13882
|
+
}
|
|
13883
|
+
/** Match declaration boundaries without changing strings, comments or function arguments. */ function normalizeBlendDeclarations(source, onDowngrade) {
|
|
13884
|
+
var replacements = [];
|
|
13885
|
+
var start = 0;
|
|
13886
|
+
var colon = -1;
|
|
13887
|
+
var parentheses = 0;
|
|
13888
|
+
var quote;
|
|
13889
|
+
var comment = false;
|
|
13890
|
+
var finish = function finish(end) {
|
|
13891
|
+
if (colon < start) {
|
|
13892
|
+
return;
|
|
13893
|
+
}
|
|
13894
|
+
var name = source.slice(start, colon).replace(/\/\*[\s\S]*?\*\//g, '').trim().toLowerCase();
|
|
13895
|
+
if (name !== 'mix-blend-mode') {
|
|
13896
|
+
return;
|
|
13897
|
+
}
|
|
13898
|
+
var value = source.slice(colon + 1, end).replace(/\/\*[\s\S]*?\*\//g, '').trim();
|
|
13899
|
+
var mode = value.replace(/\s*!important\s*$/i, '').trim();
|
|
13900
|
+
if (mode === '' || normalValues.has(mode.toLowerCase())) {
|
|
13901
|
+
return;
|
|
13902
|
+
}
|
|
13903
|
+
onDowngrade == null ? void 0 : onDowngrade(mode);
|
|
13904
|
+
replacements.push({
|
|
13905
|
+
start: colon + 1,
|
|
13906
|
+
end: end,
|
|
13907
|
+
value: /!important\s*$/i.test(value) ? ' normal !important' : ' normal'
|
|
13908
|
+
});
|
|
13909
|
+
};
|
|
13910
|
+
for(var index = 0; index < source.length; index++){
|
|
13911
|
+
var character = source[index];
|
|
13912
|
+
var next = source[index + 1];
|
|
13913
|
+
if (comment) {
|
|
13914
|
+
if (character === '*' && next === '/') {
|
|
13915
|
+
comment = false;
|
|
13916
|
+
index++;
|
|
13917
|
+
}
|
|
13918
|
+
continue;
|
|
13919
|
+
}
|
|
13920
|
+
if (quote != null) {
|
|
13921
|
+
if (character === '\\') {
|
|
13922
|
+
index++;
|
|
13923
|
+
} else if (character === quote) {
|
|
13924
|
+
quote = undefined;
|
|
13925
|
+
}
|
|
13926
|
+
continue;
|
|
13927
|
+
}
|
|
13928
|
+
if (character === '/' && next === '*') {
|
|
13929
|
+
comment = true;
|
|
13930
|
+
index++;
|
|
13931
|
+
continue;
|
|
13932
|
+
}
|
|
13933
|
+
if (character === '"' || character === "'") {
|
|
13934
|
+
quote = character;
|
|
13935
|
+
continue;
|
|
13936
|
+
}
|
|
13937
|
+
if (character === '(') {
|
|
13938
|
+
parentheses++;
|
|
13939
|
+
continue;
|
|
13940
|
+
}
|
|
13941
|
+
if (character === ')') {
|
|
13942
|
+
parentheses = Math.max(0, parentheses - 1);
|
|
13943
|
+
continue;
|
|
13944
|
+
}
|
|
13945
|
+
if (parentheses > 0) {
|
|
13946
|
+
continue;
|
|
13947
|
+
}
|
|
13948
|
+
if (character === ':' && colon < start) {
|
|
13949
|
+
colon = index;
|
|
13950
|
+
}
|
|
13951
|
+
if (character === ';' || character === '}' || character === '{') {
|
|
13952
|
+
if (character !== '{') {
|
|
13953
|
+
finish(index);
|
|
13954
|
+
}
|
|
13955
|
+
start = index + 1;
|
|
13956
|
+
colon = -1;
|
|
13957
|
+
}
|
|
13958
|
+
}
|
|
13959
|
+
finish(source.length);
|
|
13960
|
+
var result = '';
|
|
13961
|
+
var cursor = 0;
|
|
13962
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(replacements), _step; !(_step = _iterator()).done;){
|
|
13963
|
+
var replacement = _step.value;
|
|
13964
|
+
result += source.slice(cursor, replacement.start) + replacement.value;
|
|
13965
|
+
cursor = replacement.end;
|
|
13966
|
+
}
|
|
13967
|
+
return result + source.slice(cursor);
|
|
13968
|
+
}
|
|
13969
|
+
|
|
13970
|
+
var declarations = new Set([
|
|
13971
|
+
'defs',
|
|
13972
|
+
'style',
|
|
13973
|
+
'title',
|
|
13974
|
+
'desc',
|
|
13975
|
+
'metadata',
|
|
13976
|
+
'symbol',
|
|
13977
|
+
'clippath',
|
|
13978
|
+
'mask',
|
|
13979
|
+
'filter',
|
|
13980
|
+
'lineargradient',
|
|
13981
|
+
'radialgradient',
|
|
13982
|
+
'pattern',
|
|
13983
|
+
'marker'
|
|
13984
|
+
]);
|
|
13985
|
+
var graphics = new Set([
|
|
13986
|
+
'path',
|
|
13987
|
+
'rect',
|
|
13988
|
+
'circle',
|
|
13989
|
+
'ellipse',
|
|
13990
|
+
'line',
|
|
13991
|
+
'polyline',
|
|
13992
|
+
'polygon',
|
|
13993
|
+
'use'
|
|
13994
|
+
]);
|
|
13995
|
+
var containers = new Set([
|
|
13996
|
+
'svg',
|
|
13997
|
+
'g',
|
|
13998
|
+
'a',
|
|
13999
|
+
'switch'
|
|
14000
|
+
]);
|
|
14001
|
+
var groupEffects = [
|
|
14002
|
+
'opacity',
|
|
14003
|
+
'filter',
|
|
14004
|
+
'mask',
|
|
14005
|
+
'clip-path'
|
|
14006
|
+
];
|
|
14007
|
+
var native = new Set([
|
|
14008
|
+
'text',
|
|
14009
|
+
'image',
|
|
14010
|
+
'foreignobject'
|
|
14011
|
+
]);
|
|
14012
|
+
/** Select graphic-only subtrees; keep native text and images as separate layers. */ function planGraphicBaking(source) {
|
|
14013
|
+
var root = SVG(source).node;
|
|
14014
|
+
var scopes = [];
|
|
14015
|
+
var warnings = [];
|
|
14016
|
+
var effectRules = collectGroupEffectRules(root);
|
|
14017
|
+
var byId = new Map(Array.from(root.querySelectorAll('[id]')).map(function(element) {
|
|
14018
|
+
var _element_getAttribute;
|
|
14019
|
+
return [
|
|
14020
|
+
(_element_getAttribute = element.getAttribute('id')) != null ? _element_getAttribute : '',
|
|
14021
|
+
element
|
|
14022
|
+
];
|
|
14023
|
+
}));
|
|
14024
|
+
var tagOf = function tagOf(element) {
|
|
14025
|
+
return element.tagName.toLowerCase();
|
|
14026
|
+
};
|
|
14027
|
+
var selectorOf = function selectorOf(element) {
|
|
14028
|
+
var _element_getAttribute;
|
|
14029
|
+
var id = (_element_getAttribute = element.getAttribute('id')) != null ? _element_getAttribute : '';
|
|
14030
|
+
return "" + tagOf(element) + (id === '' ? '' : "#" + id);
|
|
14031
|
+
};
|
|
14032
|
+
var references = function references(element) {
|
|
14033
|
+
var ids = Array.from(element.attributes).flatMap(function(attribute) {
|
|
14034
|
+
var values = Array.from(attribute.value.matchAll(/url\(\s*['"]?#([^)'"\s]+)['"]?\s*\)/g), function(match) {
|
|
14035
|
+
return match[1];
|
|
14036
|
+
});
|
|
14037
|
+
if (attribute.localName === 'href' && attribute.value.startsWith('#')) {
|
|
14038
|
+
values.push(attribute.value.slice(1));
|
|
14039
|
+
}
|
|
14040
|
+
return values;
|
|
14041
|
+
});
|
|
14042
|
+
return ids.flatMap(function(id) {
|
|
14043
|
+
var target = byId.get(id);
|
|
14044
|
+
return target == null ? [] : [
|
|
14045
|
+
target
|
|
14046
|
+
];
|
|
14047
|
+
});
|
|
14048
|
+
};
|
|
14049
|
+
var containsNative = function containsNative1(element, seen) {
|
|
14050
|
+
if (seen === void 0) seen = new Set();
|
|
14051
|
+
if (seen.has(element)) {
|
|
14052
|
+
return false;
|
|
14053
|
+
}
|
|
14054
|
+
seen.add(element);
|
|
14055
|
+
if (native.has(tagOf(element))) {
|
|
14056
|
+
return true;
|
|
14057
|
+
}
|
|
14058
|
+
return Array.from(element.children).some(function(child) {
|
|
14059
|
+
return !declarations.has(tagOf(child)) && containsNative(child, seen);
|
|
14060
|
+
}) || references(element).some(function(target) {
|
|
14061
|
+
return containsNative(target, seen);
|
|
14062
|
+
});
|
|
14063
|
+
};
|
|
14064
|
+
var hasGraphics = function hasGraphics1(element) {
|
|
14065
|
+
return graphics.has(tagOf(element)) || Array.from(element.children).some(function(child) {
|
|
14066
|
+
return !declarations.has(tagOf(child)) && hasGraphics(child);
|
|
14067
|
+
});
|
|
14068
|
+
};
|
|
14069
|
+
var hasGroupEffect = function hasGroupEffect(element) {
|
|
14070
|
+
var _element_getAttribute;
|
|
14071
|
+
var style = (_element_getAttribute = element.getAttribute('style')) != null ? _element_getAttribute : '';
|
|
14072
|
+
return effectRules.some(function(rule) {
|
|
14073
|
+
return element.matches(rule.selectorText);
|
|
14074
|
+
}) || hasGraphicGroupEffect(function(name) {
|
|
14075
|
+
var _element_getAttribute;
|
|
14076
|
+
var _exec_, _exec;
|
|
14077
|
+
return (_element_getAttribute = element.getAttribute(name)) != null ? _element_getAttribute : (_exec = new RegExp("(?:^|;)\\s*" + name + "\\s*:\\s*([^;]+)").exec(style)) == null ? void 0 : (_exec_ = _exec[1]) == null ? void 0 : _exec_.trim();
|
|
14078
|
+
});
|
|
14079
|
+
};
|
|
14080
|
+
var visit = function visit1(element) {
|
|
14081
|
+
var _element_getAttribute, _ref;
|
|
14082
|
+
var _exec_, _exec;
|
|
14083
|
+
var tag = tagOf(element);
|
|
14084
|
+
var style = (_element_getAttribute = element.getAttribute('style')) != null ? _element_getAttribute : '';
|
|
14085
|
+
var display = (_ref = (_exec = /(?:^|;)\s*display\s*:\s*([^;]+)/.exec(style)) == null ? void 0 : (_exec_ = _exec[1]) == null ? void 0 : _exec_.trim()) != null ? _ref : element.getAttribute('display');
|
|
14086
|
+
if (display === 'none') {
|
|
14087
|
+
return;
|
|
14088
|
+
}
|
|
14089
|
+
if (declarations.has(tag) || native.has(tag)) {
|
|
14090
|
+
return;
|
|
14091
|
+
}
|
|
14092
|
+
if (!containers.has(tag) && !graphics.has(tag)) {
|
|
14093
|
+
return;
|
|
14094
|
+
}
|
|
14095
|
+
if (!hasGraphics(element)) {
|
|
14096
|
+
return;
|
|
14097
|
+
}
|
|
14098
|
+
if ((graphics.has(tag) || tag === 'switch') && !containsNative(element)) {
|
|
14099
|
+
scopes.push({
|
|
14100
|
+
path: buildElementTreePath(element),
|
|
14101
|
+
selector: selectorOf(element),
|
|
14102
|
+
isGroup: containers.has(tag)
|
|
14103
|
+
});
|
|
14104
|
+
return;
|
|
14105
|
+
}
|
|
14106
|
+
if (hasGroupEffect(element) && !containsNative(element)) {
|
|
14107
|
+
scopes.push({
|
|
14108
|
+
path: buildElementTreePath(element),
|
|
14109
|
+
selector: selectorOf(element),
|
|
14110
|
+
isGroup: containers.has(tag)
|
|
14111
|
+
});
|
|
14112
|
+
return;
|
|
14113
|
+
}
|
|
14114
|
+
if (hasGroupEffect(element)) {
|
|
14115
|
+
warnings.push({
|
|
14116
|
+
message: 'A compositing group contains native text or images; its graphics cannot be baked separately.',
|
|
14117
|
+
selector: selectorOf(element)
|
|
14118
|
+
});
|
|
14119
|
+
return;
|
|
14120
|
+
}
|
|
14121
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(Array.from(element.children)), _step; !(_step = _iterator()).done;){
|
|
14122
|
+
var child = _step.value;
|
|
14123
|
+
visit(child);
|
|
14124
|
+
}
|
|
14125
|
+
};
|
|
14126
|
+
visit(root);
|
|
14127
|
+
return {
|
|
14128
|
+
scopes: scopes,
|
|
14129
|
+
warnings: warnings
|
|
14130
|
+
};
|
|
14131
|
+
}
|
|
14132
|
+
function collectGroupEffectRules(root) {
|
|
14133
|
+
var result = [];
|
|
14134
|
+
if (typeof CSSStyleSheet !== 'function') {
|
|
14135
|
+
return result;
|
|
14136
|
+
}
|
|
14137
|
+
var visit = function visit1(rules) {
|
|
14138
|
+
var _loop = function() {
|
|
14139
|
+
var rule = _step.value;
|
|
14140
|
+
if (isStyleRule$1(rule)) {
|
|
14141
|
+
var affectsGroup = hasGraphicGroupEffect(function(name) {
|
|
14142
|
+
var value = rule.style.getPropertyValue(name).trim();
|
|
14143
|
+
return value === '' || value === 'initial' || value === 'unset' ? undefined : value;
|
|
14144
|
+
});
|
|
14145
|
+
if (affectsGroup) {
|
|
14146
|
+
result.push(rule);
|
|
14147
|
+
}
|
|
14148
|
+
} else if (hasNestedRules(rule)) {
|
|
14149
|
+
visit(rule.cssRules);
|
|
14150
|
+
}
|
|
14151
|
+
};
|
|
14152
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(Array.from(rules)), _step; !(_step = _iterator()).done;)_loop();
|
|
14153
|
+
};
|
|
14154
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(Array.from(root.querySelectorAll('style'))), _step; !(_step = _iterator()).done;){
|
|
14155
|
+
var style = _step.value;
|
|
14156
|
+
var _style_textContent;
|
|
14157
|
+
var sheet = new CSSStyleSheet();
|
|
14158
|
+
sheet.replaceSync((_style_textContent = style.textContent) != null ? _style_textContent : '');
|
|
14159
|
+
visit(sheet.cssRules);
|
|
14160
|
+
}
|
|
14161
|
+
return result;
|
|
14162
|
+
}
|
|
14163
|
+
/** Reject text/image dependencies and effects that cannot be rendered independently. */ function validateGraphicSnapshot(context) {
|
|
14164
|
+
var _loop = function() {
|
|
14165
|
+
var element = _step1.value;
|
|
14166
|
+
var computed = readStyle(element);
|
|
14167
|
+
var ancestor = element !== target && element.contains(target);
|
|
14168
|
+
var groupEffect = ancestor && hasGraphicGroupEffect(function(name) {
|
|
14169
|
+
return name === 'mask' ? computed.maskImage : computed.getPropertyValue(name);
|
|
14170
|
+
});
|
|
14171
|
+
if (ancestor && (groupEffect || computed.mixBlendMode !== 'normal')) {
|
|
14172
|
+
throw new Error('A mixed group effect cannot be applied independently to its graphics.');
|
|
14173
|
+
}
|
|
14174
|
+
if (target.contains(element) && target !== root && computed.mixBlendMode !== 'normal') {
|
|
14175
|
+
throw new Error('Blend modes that depend on an external backdrop cannot be baked independently.');
|
|
14176
|
+
}
|
|
14177
|
+
};
|
|
14178
|
+
var root = context.root, target = context.target, elements = context.elements, dependencies = context.dependencies, readStyle = context.readStyle;
|
|
14179
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(dependencies), _step; !(_step = _iterator()).done;){
|
|
14180
|
+
var element = _step.value;
|
|
14181
|
+
if ([
|
|
14182
|
+
'text',
|
|
14183
|
+
'image',
|
|
14184
|
+
'foreignobject'
|
|
14185
|
+
].includes(element.tagName.toLowerCase())) {
|
|
14186
|
+
throw new Error('Graphic dependencies contain native text or images; they must remain editable.');
|
|
14187
|
+
}
|
|
14188
|
+
}
|
|
14189
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(elements), _step1; !(_step1 = _iterator1()).done;)_loop();
|
|
14190
|
+
}
|
|
14191
|
+
function isStyleRule$1(rule) {
|
|
14192
|
+
return rule.type === 1;
|
|
14193
|
+
}
|
|
14194
|
+
function hasNestedRules(rule) {
|
|
14195
|
+
return 'cssRules' in rule;
|
|
14196
|
+
}
|
|
14197
|
+
function hasGraphicGroupEffect(readValue) {
|
|
14198
|
+
return groupEffects.some(function(name) {
|
|
14199
|
+
var value = readValue(name);
|
|
14200
|
+
return value != null && value !== 'none' && value !== 'normal' && value !== '1';
|
|
14201
|
+
});
|
|
14202
|
+
}
|
|
14203
|
+
|
|
14204
|
+
/** Mask and clipPath definitions do not produce visible layers. */ function collectNonRenderingDeclarationPaths(source) {
|
|
14205
|
+
var root = SVG(source).node;
|
|
14206
|
+
var elements = Array.from(root.querySelectorAll('*')).filter(function(element) {
|
|
14207
|
+
var tag = element.tagName.toLowerCase();
|
|
14208
|
+
return tag === 'mask' || tag === 'clippath';
|
|
14209
|
+
});
|
|
14210
|
+
return new Set(elements.map(buildElementTreePath));
|
|
14211
|
+
}
|
|
14212
|
+
/** A stylesheet diagnostic is resolved only when every element it can affect was baked. */ function collectBakedStylesheetPaths(source, isBaked) {
|
|
14213
|
+
var resolved = new Set();
|
|
14214
|
+
if (typeof DOMParser === 'undefined' || typeof CSSStyleSheet !== 'function') {
|
|
14215
|
+
return resolved;
|
|
14216
|
+
}
|
|
14217
|
+
var root = new DOMParser().parseFromString(source, 'image/svg+xml').documentElement;
|
|
14218
|
+
var allUsesBaked = Array.from(root.querySelectorAll('use')).every(function(element) {
|
|
14219
|
+
return isBaked(buildElementTreePath(element));
|
|
14220
|
+
});
|
|
14221
|
+
var isHandled = function isHandled(element) {
|
|
14222
|
+
if (isBaked(buildElementTreePath(element))) {
|
|
14223
|
+
return true;
|
|
14224
|
+
}
|
|
14225
|
+
if (element.closest('defs, symbol, marker, pattern, clipPath, mask, filter') != null) {
|
|
14226
|
+
return allUsesBaked;
|
|
14227
|
+
}
|
|
14228
|
+
return false;
|
|
14229
|
+
};
|
|
14230
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(Array.from(root.querySelectorAll('style'))), _step; !(_step = _iterator()).done;){
|
|
14231
|
+
var style = _step.value;
|
|
14232
|
+
var _style_textContent;
|
|
14233
|
+
var sheet = new CSSStyleSheet();
|
|
14234
|
+
sheet.replaceSync((_style_textContent = style.textContent) != null ? _style_textContent : '');
|
|
14235
|
+
var rules = Array.from(sheet.cssRules);
|
|
14236
|
+
var handled = rules.every(function(rule) {
|
|
14237
|
+
if (!isStyleRule(rule)) {
|
|
14238
|
+
return false;
|
|
14239
|
+
}
|
|
14240
|
+
if (Array.from(rule.style).every(function(name) {
|
|
14241
|
+
return name === 'mix-blend-mode';
|
|
14242
|
+
})) {
|
|
14243
|
+
return true;
|
|
14244
|
+
}
|
|
14245
|
+
var matched = [].concat([
|
|
14246
|
+
root
|
|
14247
|
+
], Array.from(root.querySelectorAll('*'))).filter(function(element) {
|
|
14248
|
+
return element.matches(rule.selectorText);
|
|
14249
|
+
});
|
|
14250
|
+
return matched.every(isHandled);
|
|
14251
|
+
});
|
|
14252
|
+
if (handled) {
|
|
14253
|
+
resolved.add(buildElementTreePath(style));
|
|
14254
|
+
}
|
|
14255
|
+
}
|
|
14256
|
+
return resolved;
|
|
14257
|
+
}
|
|
14258
|
+
function isStyleRule(rule) {
|
|
14259
|
+
return rule.type === 1;
|
|
14260
|
+
}
|
|
14261
|
+
|
|
14262
|
+
/** Rasterize graphics and track the source layers and warnings they replace. */ function buildBakedLayers(source, size, options, rasterScale) {
|
|
14263
|
+
return _async_to_generator(function() {
|
|
14264
|
+
var deferredOptions, bakedPaths, baked, bakingWarnings, blending, plan, _iterator, _step, downgrade, _iterator1, _step1, warning, _iterator2, _step2, scope, image, message, _image_bbox, left, top, right, bottom, width, height, error, reason, replacesSource, handledStyles, declarations;
|
|
14265
|
+
return _ts_generator(this, function(_state) {
|
|
14266
|
+
switch(_state.label){
|
|
14267
|
+
case 0:
|
|
14268
|
+
deferredOptions = _extends({}, options, {
|
|
14269
|
+
strict: false,
|
|
14270
|
+
onWarning: undefined
|
|
14271
|
+
});
|
|
14272
|
+
bakedPaths = [];
|
|
14273
|
+
baked = [];
|
|
14274
|
+
bakingWarnings = [];
|
|
14275
|
+
blending = normalizeLayerBlending(source);
|
|
14276
|
+
plan = planGraphicBaking(blending.source);
|
|
14277
|
+
for(_iterator = _create_for_of_iterator_helper_loose(blending.downgrades); !(_step = _iterator()).done;){
|
|
14278
|
+
downgrade = _step.value;
|
|
14279
|
+
collectLayerWarning(bakingWarnings, deferredOptions, SVG2IR_WARNING_CODES.LAYERS_BLEND_MODE_DOWNGRADED, 'mix-blend-mode "' + downgrade.mode + '" was downgraded to "normal"; the layer is retained.', downgrade.selector);
|
|
14280
|
+
}
|
|
14281
|
+
for(_iterator1 = _create_for_of_iterator_helper_loose(plan.warnings); !(_step1 = _iterator1()).done;){
|
|
14282
|
+
warning = _step1.value;
|
|
14283
|
+
collectLayerWarning(bakingWarnings, deferredOptions, SVG2IR_WARNING_CODES.LAYERS_UNSUPPORTED_FEATURE, warning.message, warning.selector);
|
|
14284
|
+
}
|
|
14285
|
+
_iterator2 = _create_for_of_iterator_helper_loose(plan.scopes);
|
|
14286
|
+
_state.label = 1;
|
|
14287
|
+
case 1:
|
|
14288
|
+
if (!!(_step2 = _iterator2()).done) return [
|
|
14289
|
+
3,
|
|
14290
|
+
6
|
|
14291
|
+
];
|
|
14292
|
+
scope = _step2.value;
|
|
14293
|
+
_state.label = 2;
|
|
14294
|
+
case 2:
|
|
14295
|
+
_state.trys.push([
|
|
14296
|
+
2,
|
|
14297
|
+
4,
|
|
14298
|
+
,
|
|
14299
|
+
5
|
|
14300
|
+
]);
|
|
14301
|
+
if (!canRasterizeSVG()) {
|
|
14302
|
+
throw new Error('Graphic baking requires a browser with SVG and Canvas support.');
|
|
14303
|
+
}
|
|
14304
|
+
return [
|
|
14305
|
+
4,
|
|
14306
|
+
rasterizeSVG(blending.source, scope.path, size, rasterScale, validateGraphicSnapshot)
|
|
14307
|
+
];
|
|
14308
|
+
case 3:
|
|
14309
|
+
image = _state.sent();
|
|
14310
|
+
bakedPaths.push(scope.path);
|
|
14311
|
+
message = image == null ? 'Graphic rasterization produced no visible pixels; no image layer was emitted.' : scope.isGroup ? 'Graphic group baked into a single PNG; child graphics and paint/effect parameters are no longer editable.' : 'Graphic baked into a PNG; vector geometry and paint/effect parameters are no longer editable.';
|
|
14312
|
+
collectLayerWarning(bakingWarnings, deferredOptions, SVG2IR_WARNING_CODES.LAYERS_GRAPHIC_BAKED, message, scope.selector);
|
|
14313
|
+
if (image == null) {
|
|
14314
|
+
return [
|
|
14315
|
+
3,
|
|
14316
|
+
5
|
|
14317
|
+
];
|
|
14318
|
+
}
|
|
14319
|
+
_image_bbox = image.bbox, left = _image_bbox[0], top = _image_bbox[1], right = _image_bbox[2], bottom = _image_bbox[3];
|
|
14320
|
+
width = right - left;
|
|
14321
|
+
height = bottom - top;
|
|
14322
|
+
baked.push({
|
|
14323
|
+
path: scope.path,
|
|
14324
|
+
layer: {
|
|
14325
|
+
id: '',
|
|
14326
|
+
type: 'image',
|
|
14327
|
+
role: 'content',
|
|
14328
|
+
bbox: image.bbox,
|
|
14329
|
+
size: [
|
|
14330
|
+
width,
|
|
14331
|
+
height
|
|
14332
|
+
],
|
|
14333
|
+
rotation: [
|
|
14334
|
+
0,
|
|
14335
|
+
0,
|
|
14336
|
+
0
|
|
14337
|
+
],
|
|
14338
|
+
url: image.url,
|
|
14339
|
+
width: width,
|
|
14340
|
+
height: height
|
|
14341
|
+
}
|
|
14342
|
+
});
|
|
14343
|
+
return [
|
|
14344
|
+
3,
|
|
14345
|
+
5
|
|
14346
|
+
];
|
|
14347
|
+
case 4:
|
|
14348
|
+
error = _state.sent();
|
|
14349
|
+
reason = _instanceof(error, Error) ? error.message : String(error);
|
|
14350
|
+
collectLayerWarning(bakingWarnings, deferredOptions, SVG2IR_WARNING_CODES.LAYERS_UNSUPPORTED_FEATURE, "Graphic baking failed: " + reason, scope.selector);
|
|
14351
|
+
return [
|
|
14352
|
+
3,
|
|
14353
|
+
5
|
|
14354
|
+
];
|
|
14355
|
+
case 5:
|
|
14356
|
+
return [
|
|
14357
|
+
3,
|
|
14358
|
+
1
|
|
14359
|
+
];
|
|
14360
|
+
case 6:
|
|
14361
|
+
replacesSource = function replacesSource(path) {
|
|
14362
|
+
return path != null && bakedPaths.some(function(scope) {
|
|
14363
|
+
return scope === '' || path === scope || path.startsWith("" + scope + "/");
|
|
14364
|
+
});
|
|
14365
|
+
};
|
|
14366
|
+
handledStyles = collectBakedStylesheetPaths(blending.source, replacesSource);
|
|
14367
|
+
declarations = collectNonRenderingDeclarationPaths(source);
|
|
14368
|
+
return [
|
|
14369
|
+
2,
|
|
14370
|
+
{
|
|
14371
|
+
layers: baked,
|
|
14372
|
+
warnings: bakingWarnings,
|
|
14373
|
+
replacesSource: replacesSource,
|
|
14374
|
+
resolvesWarning: function resolvesWarning(warning, path) {
|
|
14375
|
+
return replacesSource(path) || warning.code === SVG2IR_WARNING_CODES.ELEMENT_DROPPED && path != null && (handledStyles.has(path) || declarations.has(path));
|
|
14376
|
+
}
|
|
14377
|
+
}
|
|
14378
|
+
];
|
|
14379
|
+
}
|
|
14380
|
+
});
|
|
14381
|
+
})();
|
|
14382
|
+
}
|
|
13273
14383
|
|
|
13274
14384
|
function encodeBase64(data) {
|
|
13275
14385
|
var chunks = [];
|
|
@@ -13458,26 +14568,103 @@ function fetchImageResource(url) {
|
|
|
13458
14568
|
}).apply(this, arguments);
|
|
13459
14569
|
}
|
|
13460
14570
|
|
|
13461
|
-
|
|
14571
|
+
var animatedTags = new Set([
|
|
14572
|
+
'animate',
|
|
14573
|
+
'animatetransform',
|
|
14574
|
+
'animatemotion',
|
|
14575
|
+
'set'
|
|
14576
|
+
]);
|
|
14577
|
+
/** Static layers cannot sample animation; drop SMIL nodes so elements keep their authored state. */ function stripLayerAnimation(source) {
|
|
14578
|
+
var svg = SVG(source);
|
|
14579
|
+
if ((svg == null ? void 0 : svg.node) == null) {
|
|
14580
|
+
return {
|
|
14581
|
+
source: source,
|
|
14582
|
+
removed: 0
|
|
14583
|
+
};
|
|
14584
|
+
}
|
|
14585
|
+
var elements = Array.from(svg.node.querySelectorAll('*')).filter(function(element) {
|
|
14586
|
+
return animatedTags.has(element.tagName.toLowerCase());
|
|
14587
|
+
});
|
|
14588
|
+
if (elements.length === 0) {
|
|
14589
|
+
return {
|
|
14590
|
+
source: source,
|
|
14591
|
+
removed: 0
|
|
14592
|
+
};
|
|
14593
|
+
}
|
|
14594
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(elements), _step; !(_step = _iterator()).done;){
|
|
14595
|
+
var element = _step.value;
|
|
14596
|
+
element.remove();
|
|
14597
|
+
}
|
|
14598
|
+
return {
|
|
14599
|
+
source: svg.svg(),
|
|
14600
|
+
removed: elements.length
|
|
14601
|
+
};
|
|
14602
|
+
}
|
|
14603
|
+
|
|
14604
|
+
function convertSVGToLayers(source, options, loadImage, preservedData, rasterScale) {
|
|
14605
|
+
if (rasterScale === void 0) rasterScale = 2;
|
|
13462
14606
|
return _async_to_generator(function() {
|
|
13463
|
-
var
|
|
14607
|
+
var layerSources, warningSources, collected, stripped, staticSource, parsed, composition, baking, assembled, _tmp, _tmp1;
|
|
13464
14608
|
return _ts_generator(this, function(_state) {
|
|
13465
14609
|
switch(_state.label){
|
|
13466
14610
|
case 0:
|
|
13467
|
-
|
|
13468
|
-
|
|
13469
|
-
|
|
13470
|
-
|
|
13471
|
-
|
|
14611
|
+
layerSources = new Map();
|
|
14612
|
+
warningSources = new Map();
|
|
14613
|
+
collected = {
|
|
14614
|
+
textDataByLayerId: new Map(),
|
|
14615
|
+
paintAnimationsByLayerId: new Map(),
|
|
14616
|
+
shapeAnimationsByLayerId: new Map()
|
|
13472
14617
|
};
|
|
14618
|
+
stripped = stripLayerAnimation(source);
|
|
14619
|
+
staticSource = stripped.source;
|
|
14620
|
+
// Preserve original layer IDs while gathering the source identities required by baking and assembly.
|
|
14621
|
+
parsed = parseSVGToIRWithPreservedData(staticSource, _extends({}, options, {
|
|
14622
|
+
strict: false,
|
|
14623
|
+
onWarning: undefined
|
|
14624
|
+
}), _extends({}, collected, {
|
|
14625
|
+
layerSourceCollector: layerSources,
|
|
14626
|
+
warningSourceCollector: warningSources
|
|
14627
|
+
}));
|
|
14628
|
+
if (stripped.removed > 0) {
|
|
14629
|
+
collectLayerWarning(parsed.warnings, _extends({}, options, {
|
|
14630
|
+
strict: false,
|
|
14631
|
+
onWarning: undefined
|
|
14632
|
+
}), SVG2IR_WARNING_CODES.LAYERS_ANIMATION_STRIPPED, "" + stripped.removed + " animated element(s) were removed; static layers output does not sample animation.");
|
|
14633
|
+
}
|
|
14634
|
+
composition = parsed.ir.compositions[0];
|
|
13473
14635
|
return [
|
|
13474
14636
|
4,
|
|
13475
|
-
|
|
14637
|
+
buildBakedLayers(staticSource, [
|
|
14638
|
+
composition.width,
|
|
14639
|
+
composition.height
|
|
14640
|
+
], options, rasterScale)
|
|
13476
14641
|
];
|
|
13477
14642
|
case 1:
|
|
14643
|
+
baking = _state.sent();
|
|
14644
|
+
assembled = assembleSVGLayers({
|
|
14645
|
+
scene: parsed.ir,
|
|
14646
|
+
options: options,
|
|
14647
|
+
warnings: parsed.warnings,
|
|
14648
|
+
preservedData: preservedData != null ? preservedData : collected,
|
|
14649
|
+
layerSources: layerSources,
|
|
14650
|
+
warningSources: warningSources,
|
|
14651
|
+
baking: baking
|
|
14652
|
+
});
|
|
14653
|
+
_tmp = [
|
|
14654
|
+
{},
|
|
14655
|
+
assembled
|
|
14656
|
+
];
|
|
14657
|
+
_tmp1 = {};
|
|
14658
|
+
return [
|
|
14659
|
+
4,
|
|
14660
|
+
inlineImageResources(assembled.data, loadImage)
|
|
14661
|
+
];
|
|
14662
|
+
case 2:
|
|
13478
14663
|
return [
|
|
13479
14664
|
2,
|
|
13480
|
-
(
|
|
14665
|
+
_extends.apply(void 0, _tmp.concat([
|
|
14666
|
+
(_tmp1.data = _state.sent(), _tmp1)
|
|
14667
|
+
]))
|
|
13481
14668
|
];
|
|
13482
14669
|
}
|
|
13483
14670
|
});
|
|
@@ -16007,11 +17194,12 @@ function convertSVG(source, options, preservedData) {
|
|
|
16007
17194
|
throw new TypeError('[svg2ir] outputFormat must be ge or layers.');
|
|
16008
17195
|
}
|
|
16009
17196
|
if ((options == null ? void 0 : options.outputFormat) === 'layers') {
|
|
16010
|
-
options.outputFormat; var loadImage = options.loadImage, parserOptions = _object_without_properties_loose(options, [
|
|
17197
|
+
options.outputFormat; var loadImage = options.loadImage, rasterScale = options.rasterScale, parserOptions = _object_without_properties_loose(options, [
|
|
16011
17198
|
"outputFormat",
|
|
16012
|
-
"loadImage"
|
|
17199
|
+
"loadImage",
|
|
17200
|
+
"rasterScale"
|
|
16013
17201
|
]);
|
|
16014
|
-
return convertSVGToLayers(source, parserOptions, loadImage, preservedData);
|
|
17202
|
+
return convertSVGToLayers(source, parserOptions, loadImage, preservedData, rasterScale);
|
|
16015
17203
|
}
|
|
16016
17204
|
var _ref1 = options != null ? options : {}; _ref1.outputFormat; var geOptions = _object_without_properties_loose(_ref1, [
|
|
16017
17205
|
"outputFormat"
|
|
@@ -16021,5 +17209,5 @@ function convertSVG(source, options, preservedData) {
|
|
|
16021
17209
|
|
|
16022
17210
|
setEditableSVGConstructor(resolveEditableSVGConstructor(editableSVGNodeModule));
|
|
16023
17211
|
|
|
16024
|
-
export { convertSVG, convertSVGToGE, convertSVGToIR, splitSVG };
|
|
17212
|
+
export { convertSVG, convertSVGToGE, convertSVGToIR, inferNumericWeightFromFamily, splitSVG };
|
|
16025
17213
|
//# sourceMappingURL=node.mjs.map
|