@vvfx/svg2ir 0.0.1-beta.0 → 0.0.1-beta.12
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 +86 -48
- package/dist/{svg2ge-adapter → adapter/svg2ge}/assemble.d.ts +2 -2
- package/dist/adapter/svg2ge/convert.d.ts +7 -0
- package/dist/{svg2ge-adapter → adapter/svg2ge}/normalize-shape-animation.d.ts +1 -1
- package/dist/{svg2ge-adapter → adapter/svg2ge}/post-process/apply-shape-geometry-animation.d.ts +1 -1
- package/dist/{svg2ge-adapter → adapter/svg2ge}/post-process/apply-shape-paint-animation.d.ts +1 -1
- package/dist/{svg2ge-adapter → adapter/svg2ge}/post-process/rewrite-text-components.d.ts +1 -1
- package/dist/{svg2ge-adapter → adapter/svg2ge}/pre-process.d.ts +1 -1
- package/dist/{svg2ge-adapter → adapter/svg2ge}/types.d.ts +2 -2
- package/dist/adapter/svg2layers/assemble.d.ts +23 -0
- package/dist/adapter/svg2layers/baking/build-baked-layers.d.ts +13 -0
- package/dist/adapter/svg2layers/baking/normalize-layer-blending.d.ts +10 -0
- package/dist/adapter/svg2layers/baking/plan-graphic-baking.d.ts +18 -0
- package/dist/adapter/svg2layers/baking/resolve-baking-warnings.d.ts +4 -0
- package/dist/adapter/svg2layers/convert.d.ts +4 -0
- package/dist/{svg2layers-adapter → adapter/svg2layers}/converter/diagnostics/collect-warnings.d.ts +1 -1
- package/dist/adapter/svg2layers/converter/image/inspect-mask.d.ts +3 -0
- package/dist/{svg2layers-adapter → adapter/svg2layers}/converter/layers/build-layers.d.ts +1 -1
- package/dist/{svg2layers-adapter → adapter/svg2layers}/converter/layers/conversion-session.d.ts +2 -2
- package/dist/{svg2layers-adapter → adapter/svg2layers}/converter/text/parse-text-runs.d.ts +1 -1
- package/dist/{svg2layers-adapter → adapter/svg2layers}/converter/text/text-layout.d.ts +2 -2
- package/dist/{svg2layers-adapter → adapter/svg2layers}/matrix.d.ts +1 -1
- package/dist/adapter/svg2layers/strip-layer-animation.d.ts +5 -0
- package/dist/{svg2layers-adapter → adapter/svg2layers}/types.d.ts +8 -1
- package/dist/common/types.d.ts +7 -3
- package/dist/index.d.ts +6 -6
- package/dist/index.js +1324 -103
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1323 -103
- package/dist/index.mjs.map +1 -1
- package/dist/node.js +1326 -105
- package/dist/node.js.map +1 -1
- package/dist/node.mjs +1325 -105
- 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 +5 -2
- package/dist/svg2ir/converter/layers/conversion-session.d.ts +2 -0
- package/dist/svg2ir/converter/text/font-metrics.d.ts +2 -0
- package/package.json +5 -5
- package/dist/convert.d.ts +0 -19
- package/dist/svg2ge-adapter/convert.d.ts +0 -5
- package/dist/svg2layers-adapter/assemble.d.ts +0 -8
- package/dist/svg2layers-adapter/convert.d.ts +0 -4
- /package/dist/{svg2ge-adapter → adapter/svg2ge}/converter/animation.d.ts +0 -0
- /package/dist/{svg2ge-adapter → adapter/svg2ge}/converter/data-path.d.ts +0 -0
- /package/dist/{svg2ge-adapter → adapter/svg2ge}/post-process/apply-fonts.d.ts +0 -0
- /package/dist/{svg2ge-adapter → adapter/svg2ge}/post-process/paint-animation-sampling.d.ts +0 -0
- /package/dist/{svg2ge-adapter → adapter/svg2ge}/post-process/restore-gradient-uv.d.ts +0 -0
- /package/dist/{svg2layers-adapter → adapter/svg2layers}/converter/image/convert-image-layer.d.ts +0 -0
- /package/dist/{svg2layers-adapter → adapter/svg2layers}/converter/layers/registry.d.ts +0 -0
- /package/dist/{svg2layers-adapter → adapter/svg2layers}/converter/layers/resolve-visual-state.d.ts +0 -0
- /package/dist/{svg2layers-adapter → adapter/svg2layers}/converter/text/convert-text-layer.d.ts +0 -0
- /package/dist/{svg2layers-adapter → adapter/svg2layers}/converter/transform/build-transform.d.ts +0 -0
- /package/dist/{svg2layers-adapter → adapter/svg2layers}/post-process/inline-image-resources.d.ts +0 -0
package/dist/index.js
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.12
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
'use strict';
|
|
@@ -1507,7 +1507,7 @@ function parseHexColor(raw) {
|
|
|
1507
1507
|
return null;
|
|
1508
1508
|
}
|
|
1509
1509
|
var hex = match[1];
|
|
1510
|
-
var expanded = hex.length <= 4 ?
|
|
1510
|
+
var expanded = hex.length <= 4 ? Array.from(hex).map(function(char) {
|
|
1511
1511
|
return "" + char + char;
|
|
1512
1512
|
}).join('') : hex;
|
|
1513
1513
|
var r = parseInt(expanded.slice(0, 2), 16) / 255;
|
|
@@ -2608,7 +2608,24 @@ function parseSMILTag(tag, root, beginCache, comparisonDuration, valueParser, un
|
|
|
2608
2608
|
return maxEnd;
|
|
2609
2609
|
}
|
|
2610
2610
|
|
|
2611
|
-
/**
|
|
2611
|
+
/** Structural source identity, independent of optional or duplicate SVG IDs. */ function buildElementTreePath(element) {
|
|
2612
|
+
var indices = [];
|
|
2613
|
+
var current = element;
|
|
2614
|
+
while(isElementNode(current.parentNode)){
|
|
2615
|
+
var parent = current.parentNode;
|
|
2616
|
+
indices.unshift(Array.from(parent.children).indexOf(current));
|
|
2617
|
+
current = parent;
|
|
2618
|
+
}
|
|
2619
|
+
return indices.join('/');
|
|
2620
|
+
}
|
|
2621
|
+
function isElementNode(node) {
|
|
2622
|
+
return (node == null ? void 0 : node.nodeType) === 1;
|
|
2623
|
+
}
|
|
2624
|
+
|
|
2625
|
+
/** SVG 转换诊断码;用于报告烘焙、降级和不支持的特性。 */ var SVG2IR_WARNING_CODES = {
|
|
2626
|
+
/** 图形或图形组已栅格化,矢量编辑能力变化通过 warning 报告。 */ LAYERS_GRAPHIC_BAKED: 'svg2ge_layers_graphic_baked',
|
|
2627
|
+
LAYERS_BLEND_MODE_DOWNGRADED: 'svg2ge_layers_blend_mode_downgraded',
|
|
2628
|
+
LAYERS_ANIMATION_STRIPPED: 'svg2ge_layers_animation_stripped',
|
|
2612
2629
|
LAYERS_UNSUPPORTED_TYPE: 'svg2ge_layers_unsupported_type',
|
|
2613
2630
|
LAYERS_UNSUPPORTED_FEATURE: 'svg2ge_layers_unsupported_feature',
|
|
2614
2631
|
LAYERS_INVALID_DATA: 'svg2ge_layers_invalid_data',
|
|
@@ -3963,7 +3980,7 @@ function distPointToSegment(p, a, b) {
|
|
|
3963
3980
|
return transformVector(gChain, t);
|
|
3964
3981
|
});
|
|
3965
3982
|
return {
|
|
3966
|
-
mode:
|
|
3983
|
+
mode: 'add',
|
|
3967
3984
|
path: {
|
|
3968
3985
|
points: pts,
|
|
3969
3986
|
inTangents: inTangents,
|
|
@@ -5920,12 +5937,16 @@ function applyClipMask(es, el, layer, clipMasks) {
|
|
|
5920
5937
|
}
|
|
5921
5938
|
if (isClip) {
|
|
5922
5939
|
return _extends({}, layer, {
|
|
5923
|
-
|
|
5940
|
+
masks: [
|
|
5941
|
+
baseMask
|
|
5942
|
+
]
|
|
5924
5943
|
});
|
|
5925
5944
|
}
|
|
5926
5945
|
var rebased = rebaseMaskToLocal(baseMask, layer);
|
|
5927
5946
|
return rebased ? _extends({}, layer, {
|
|
5928
|
-
|
|
5947
|
+
masks: [
|
|
5948
|
+
rebased
|
|
5949
|
+
]
|
|
5929
5950
|
}) : layer;
|
|
5930
5951
|
}
|
|
5931
5952
|
/** 将 SVG 绝对 mask 点转换为 image 的 asset-local 坐标。 */ function rebaseMaskToLocal(mask, layer) {
|
|
@@ -5963,7 +5984,7 @@ function applyClipMask(es, el, layer, clipMasks) {
|
|
|
5963
5984
|
outTangents: mask.path.outTangents,
|
|
5964
5985
|
closed: mask.path.closed
|
|
5965
5986
|
},
|
|
5966
|
-
mode:
|
|
5987
|
+
mode: 'add'
|
|
5967
5988
|
};
|
|
5968
5989
|
}
|
|
5969
5990
|
// shape 没有 asset 尺寸,mask 需要转换到以 layer anchor 为基准的 element-local 空间。
|
|
@@ -5993,7 +6014,7 @@ function applyClipMask(es, el, layer, clipMasks) {
|
|
|
5993
6014
|
outTangents: mask.path.outTangents,
|
|
5994
6015
|
closed: mask.path.closed
|
|
5995
6016
|
},
|
|
5996
|
-
mode:
|
|
6017
|
+
mode: 'add'
|
|
5997
6018
|
};
|
|
5998
6019
|
}
|
|
5999
6020
|
/** shape layer 的 element-local bbox(以 layer.transform.anchor=localCenter 为原点)。
|
|
@@ -6128,8 +6149,9 @@ function readVec3(channel) {
|
|
|
6128
6149
|
node
|
|
6129
6150
|
], Array.from(node.querySelectorAll('*')));
|
|
6130
6151
|
var hasUnsupportedRule = ruleNodes.some(function(candidate) {
|
|
6152
|
+
var _ref, _ref1;
|
|
6131
6153
|
var _candidate_getAttribute, _candidate_getAttribute1;
|
|
6132
|
-
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()) !== '';
|
|
6154
|
+
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 : '') !== '';
|
|
6133
6155
|
});
|
|
6134
6156
|
if (hasUnsupportedRule) {
|
|
6135
6157
|
warn(SVG2IR_WARNING_CODES.CLIP_RULE_DROPPED, "" + tag + " 内显式 clip-rule/fill-rule 未映射,IR 只保留 mask 几何,不保留该规则。");
|
|
@@ -6961,7 +6983,7 @@ function createSVGConversionSession(es, options) {
|
|
|
6961
6983
|
};
|
|
6962
6984
|
var withGroupParent = function withGroupParent(layer, element) {
|
|
6963
6985
|
var parentIndex = nearestMaskedGroupAncestor(element);
|
|
6964
|
-
if (parentIndex == null
|
|
6986
|
+
if (parentIndex == null) {
|
|
6965
6987
|
return layer;
|
|
6966
6988
|
}
|
|
6967
6989
|
return _extends({}, layer, {
|
|
@@ -6970,8 +6992,10 @@ function createSVGConversionSession(es, options) {
|
|
|
6970
6992
|
};
|
|
6971
6993
|
var appendLayer = function appendLayer(layer, element, applyElementClip) {
|
|
6972
6994
|
if (applyElementClip === void 0) applyElementClip = true;
|
|
6995
|
+
var _options_layerSourceCollector;
|
|
6973
6996
|
var clippedLayer = applyElementClip ? applyClipMask(es, element, layer, clipMasks) : layer;
|
|
6974
6997
|
layers.push(withGroupParent(clippedLayer, element));
|
|
6998
|
+
(_options_layerSourceCollector = options.layerSourceCollector) == null ? void 0 : _options_layerSourceCollector.set(layer.id, buildElementTreePath(element.node));
|
|
6975
6999
|
};
|
|
6976
7000
|
var appendAsset = function appendAsset(asset) {
|
|
6977
7001
|
if (registeredAssetIds.has(asset.id)) {
|
|
@@ -7314,7 +7338,9 @@ function convertGroupElement(element, context) {
|
|
|
7314
7338
|
value: 1
|
|
7315
7339
|
}
|
|
7316
7340
|
},
|
|
7317
|
-
|
|
7341
|
+
masks: [
|
|
7342
|
+
groupMask
|
|
7343
|
+
]
|
|
7318
7344
|
};
|
|
7319
7345
|
context.appendLayer(nullLayer, element, false);
|
|
7320
7346
|
context.groupMaskGNodeToIndex.set(element.node, layerIndex);
|
|
@@ -10379,7 +10405,7 @@ function mapFontWeight(raw, fontFamily) {
|
|
|
10379
10405
|
seen.set(Math.round(w * 100), ch);
|
|
10380
10406
|
}
|
|
10381
10407
|
}
|
|
10382
|
-
return
|
|
10408
|
+
return Array.from(seen.entries()).map(function(param) {
|
|
10383
10409
|
var k = param[0], ch = param[1];
|
|
10384
10410
|
return {
|
|
10385
10411
|
ch: ch,
|
|
@@ -10429,6 +10455,9 @@ function mapFontWeight(raw, fontFamily) {
|
|
|
10429
10455
|
// latin / digit / 标点:典型比例字体 sans-serif 大写字母约 0.65em,数字稍窄。
|
|
10430
10456
|
return /[0-9]/.test(ch) ? 0.55 : 0.62;
|
|
10431
10457
|
}
|
|
10458
|
+
/** 去除单个字体族名的 CSS 字符串引号。 */ function normalizeFontFamilyName(fontFamily) {
|
|
10459
|
+
return fontFamily.trim().replace(/^(['"])(.*)\1$/, '$2');
|
|
10460
|
+
}
|
|
10432
10461
|
/** 构造与 Effects Runtime getFontDesc 一致的 CSS font 简写字符串,用于 Canvas measureText。 */ function buildCanvasFontDesc(fontSize, fontFamily, fontWeight, fontStyle) {
|
|
10433
10462
|
var weightStr = String(fontWeight);
|
|
10434
10463
|
var genericFamilies = [
|
|
@@ -10437,7 +10466,8 @@ function mapFontWeight(raw, fontFamily) {
|
|
|
10437
10466
|
'monospace',
|
|
10438
10467
|
'courier'
|
|
10439
10468
|
];
|
|
10440
|
-
var
|
|
10469
|
+
var family = normalizeFontFamilyName(fontFamily);
|
|
10470
|
+
var familyName = genericFamilies.includes(family) ? family : '"' + family + '"';
|
|
10441
10471
|
var desc = fontSize + "px " + familyName;
|
|
10442
10472
|
if (weightStr !== 'normal' && weightStr !== '') {
|
|
10443
10473
|
desc = weightStr + " " + desc;
|
|
@@ -10448,13 +10478,13 @@ function mapFontWeight(raw, fontFamily) {
|
|
|
10448
10478
|
return desc;
|
|
10449
10479
|
}
|
|
10450
10480
|
/** 文本宽度估算。优先使用调用方提供的 Canvas measureText,否则使用字符级启发式系数。 */ function estimateTextWidth(content, fontSize, letterSpacing, measureText, fontFamily, fontWeight, fontStyle) {
|
|
10451
|
-
var
|
|
10481
|
+
var chars = Array.from(content);
|
|
10482
|
+
var len = chars.length;
|
|
10452
10483
|
if (measureText != null && fontFamily !== '') {
|
|
10453
10484
|
var fontDesc = buildCanvasFontDesc(fontSize, fontFamily, fontWeight, fontStyle);
|
|
10454
10485
|
var width = measureText(fontDesc, content).width;
|
|
10455
10486
|
return width + letterSpacing * Math.max(len - 1, 0);
|
|
10456
10487
|
}
|
|
10457
|
-
var chars = [].concat(content);
|
|
10458
10488
|
var width1 = chars.reduce(function(s, ch) {
|
|
10459
10489
|
return s + charWidthCoef(ch) * fontSize;
|
|
10460
10490
|
}, 0);
|
|
@@ -12051,7 +12081,16 @@ function createSVGElementConverterRegistry(session) {
|
|
|
12051
12081
|
}
|
|
12052
12082
|
|
|
12053
12083
|
function buildSVGLayers(es, options) {
|
|
12054
|
-
var
|
|
12084
|
+
var currentPath;
|
|
12085
|
+
var warningSourceCollector = options.warningSourceCollector;
|
|
12086
|
+
var session = createSVGConversionSession(es, warningSourceCollector == null ? options : _extends({}, options, {
|
|
12087
|
+
emit: function emit(warning) {
|
|
12088
|
+
if (currentPath != null) {
|
|
12089
|
+
warningSourceCollector.set(warning, currentPath);
|
|
12090
|
+
}
|
|
12091
|
+
options.emit(warning);
|
|
12092
|
+
}
|
|
12093
|
+
}));
|
|
12055
12094
|
var converters = createSVGElementConverterRegistry(session);
|
|
12056
12095
|
for(var _iterator = _create_for_of_iterator_helper_loose(session.all), _step; !(_step = _iterator()).done;){
|
|
12057
12096
|
var element = _step.value;
|
|
@@ -12059,6 +12098,9 @@ function buildSVGLayers(es, options) {
|
|
|
12059
12098
|
var _element_node_tagName, _element_node;
|
|
12060
12099
|
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 : '';
|
|
12061
12100
|
var selector = describeElement(element);
|
|
12101
|
+
if (warningSourceCollector != null) {
|
|
12102
|
+
currentPath = buildElementTreePath(element.node);
|
|
12103
|
+
}
|
|
12062
12104
|
if (isInInactiveSwitchBranch(element)) {
|
|
12063
12105
|
continue;
|
|
12064
12106
|
}
|
|
@@ -12092,11 +12134,10 @@ function buildSVGLayers(es, options) {
|
|
|
12092
12134
|
|
|
12093
12135
|
var ParseableSVG = /*#__PURE__*/ function() {
|
|
12094
12136
|
function ParseableSVG(svgStr, _options) {
|
|
12095
|
-
var
|
|
12096
|
-
|
|
12097
|
-
|
|
12137
|
+
var _SVG;
|
|
12138
|
+
// svg.js parses a fragment; remove only the prolog and let the DOM handle nested markup.
|
|
12139
|
+
var content = svgStr.replace(/^\uFEFF/, '').replace(/^(?:\s|<\?xml\b[\s\S]*?\?>|<!DOCTYPE\b[^>]*>|<!--[\s\S]*?-->)+/i, '');
|
|
12098
12140
|
// svg.js SVG(string) 的 d.ts 标为 Element,但对完整 <svg> 文档运行时返回根 SVG 文档实例。
|
|
12099
|
-
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;
|
|
12100
12141
|
// svg.js 对非 SVG 字符串(如 'not svg')解析返 null。兜底空 svg:让 svg2ir 上层
|
|
12101
12142
|
// hasSVGRootElement 检查(非 svg 抛 INVALID_SVG)生效,而非在构造期抛错。
|
|
12102
12143
|
this.svg = (_SVG = svg_js.SVG(content)) != null ? _SVG : svg_js.SVG('<svg xmlns="http://www.w3.org/2000/svg"/>');
|
|
@@ -12299,6 +12340,8 @@ function parseSVGToIRScene(svgString, options) {
|
|
|
12299
12340
|
value: scannedSmilDuration
|
|
12300
12341
|
};
|
|
12301
12342
|
var layerBuildOptions = {
|
|
12343
|
+
layerSourceCollector: options == null ? void 0 : options.layerSourceCollector,
|
|
12344
|
+
warningSourceCollector: options == null ? void 0 : options.warningSourceCollector,
|
|
12302
12345
|
frameRate: frameRate,
|
|
12303
12346
|
durationSeconds: effectiveDuration,
|
|
12304
12347
|
emit: emit,
|
|
@@ -12478,6 +12521,8 @@ function parseSVGToIRWithPreservedData(source, options, collectors) {
|
|
|
12478
12521
|
var svgString = readSVGString(source);
|
|
12479
12522
|
var irScene = parseSVGToIRScene(svgString, _extends({}, options, {
|
|
12480
12523
|
onWarning: emitWarning,
|
|
12524
|
+
layerSourceCollector: collectors == null ? void 0 : collectors.layerSourceCollector,
|
|
12525
|
+
warningSourceCollector: collectors == null ? void 0 : collectors.warningSourceCollector,
|
|
12481
12526
|
textDataCollector: collectors == null ? void 0 : collectors.textDataByLayerId,
|
|
12482
12527
|
paintAnimationsCollector: collectors == null ? void 0 : collectors.paintAnimationsByLayerId,
|
|
12483
12528
|
shapeAnimationCollector: collectors == null ? void 0 : collectors.shapeAnimationsByLayerId
|
|
@@ -12653,7 +12698,8 @@ function collectLayerWarning(warnings, options, code, message, selector) {
|
|
|
12653
12698
|
});
|
|
12654
12699
|
warnings.push(warning);
|
|
12655
12700
|
options.onWarning == null ? void 0 : options.onWarning.call(options, warning);
|
|
12656
|
-
|
|
12701
|
+
var advisory = code === SVG2IR_WARNING_CODES.LAYERS_TEXT_BOUNDS_ESTIMATED || code === SVG2IR_WARNING_CODES.LAYERS_GRAPHIC_BAKED;
|
|
12702
|
+
if (options.strict === true && !advisory) {
|
|
12657
12703
|
throw new SVGConverterError(SVG_CONVERTER_ERROR_CODES.LAYERS_CONVERSION_FAILED, warning.message, {
|
|
12658
12704
|
stage: 'layers',
|
|
12659
12705
|
sourceId: selector,
|
|
@@ -12697,21 +12743,36 @@ function transformBoxCorners(matrix, box) {
|
|
|
12697
12743
|
transformPoint(matrix, box[0], box[3])
|
|
12698
12744
|
];
|
|
12699
12745
|
}
|
|
12700
|
-
function mapPointsToBBox(points) {
|
|
12746
|
+
function mapPointsToBBox(points, roundCoordinates) {
|
|
12747
|
+
if (roundCoordinates === void 0) roundCoordinates = true;
|
|
12701
12748
|
var _Math, _Math1, _Math2, _Math3;
|
|
12702
|
-
|
|
12703
|
-
|
|
12749
|
+
var bbox = [
|
|
12750
|
+
(_Math = Math).min.apply(_Math, [].concat(points.map(function(point) {
|
|
12704
12751
|
return point[0];
|
|
12705
|
-
})))
|
|
12706
|
-
|
|
12752
|
+
}))),
|
|
12753
|
+
(_Math1 = Math).min.apply(_Math1, [].concat(points.map(function(point) {
|
|
12707
12754
|
return point[1];
|
|
12708
|
-
})))
|
|
12709
|
-
|
|
12755
|
+
}))),
|
|
12756
|
+
(_Math2 = Math).max.apply(_Math2, [].concat(points.map(function(point) {
|
|
12710
12757
|
return point[0];
|
|
12711
|
-
})))
|
|
12712
|
-
|
|
12758
|
+
}))),
|
|
12759
|
+
(_Math3 = Math).max.apply(_Math3, [].concat(points.map(function(point) {
|
|
12713
12760
|
return point[1];
|
|
12714
|
-
})))
|
|
12761
|
+
})))
|
|
12762
|
+
];
|
|
12763
|
+
if (bbox.some(function(value) {
|
|
12764
|
+
return !Number.isFinite(value);
|
|
12765
|
+
})) {
|
|
12766
|
+
throwInvalidLayerData('Non-finite pixel geometry.');
|
|
12767
|
+
}
|
|
12768
|
+
if (!roundCoordinates) {
|
|
12769
|
+
return bbox;
|
|
12770
|
+
}
|
|
12771
|
+
return [
|
|
12772
|
+
roundPixel(bbox[0]),
|
|
12773
|
+
roundPixel(bbox[1]),
|
|
12774
|
+
roundPixel(bbox[2]),
|
|
12775
|
+
roundPixel(bbox[3])
|
|
12715
12776
|
];
|
|
12716
12777
|
}
|
|
12717
12778
|
function roundPixel(value) {
|
|
@@ -12919,7 +12980,7 @@ function parseTextRuns(layer, font, preserved) {
|
|
|
12919
12980
|
return spans.filter(function(span) {
|
|
12920
12981
|
return span.text !== '' || span.newLine;
|
|
12921
12982
|
}).map(function(span) {
|
|
12922
|
-
var fontSize = span.fontSize == null || span.fontSize === '' ? base.fontSize : Number.
|
|
12983
|
+
var fontSize = span.fontSize == null || span.fontSize === '' ? base.fontSize : Number.parseFloat(span.fontSize);
|
|
12923
12984
|
if (!Number.isFinite(fontSize) || fontSize <= 0) {
|
|
12924
12985
|
throwInvalidLayerData('Invalid text fragment font size.');
|
|
12925
12986
|
}
|
|
@@ -12948,7 +13009,7 @@ function mapTextColor(color) {
|
|
|
12948
13009
|
};
|
|
12949
13010
|
}
|
|
12950
13011
|
|
|
12951
|
-
function buildTextRunLayout(runs, family, spacing, content, size, conversionOptions, warnings, id, segmented) {
|
|
13012
|
+
function buildTextRunLayout(runs, family, spacing, content, size, conversionOptions, warnings, id, segmented, renderScale) {
|
|
12952
13013
|
var _loop = function() {
|
|
12953
13014
|
var run = _step.value;
|
|
12954
13015
|
run.text.split('\n').forEach(function(text, index) {
|
|
@@ -12963,6 +13024,10 @@ function buildTextRunLayout(runs, family, spacing, content, size, conversionOpti
|
|
|
12963
13024
|
});
|
|
12964
13025
|
};
|
|
12965
13026
|
if (segmented === void 0) segmented = false;
|
|
13027
|
+
if (renderScale === void 0) renderScale = [
|
|
13028
|
+
1,
|
|
13029
|
+
1
|
|
13030
|
+
];
|
|
12966
13031
|
var _Math;
|
|
12967
13032
|
var rows = [
|
|
12968
13033
|
[]
|
|
@@ -12975,33 +13040,44 @@ function buildTextRunLayout(runs, family, spacing, content, size, conversionOpti
|
|
|
12975
13040
|
}).map(function(row) {
|
|
12976
13041
|
var _Math, _Math1;
|
|
12977
13042
|
var parts = row.map(function(run) {
|
|
12978
|
-
//
|
|
13043
|
+
// 基线沿用参考字号指标,字宽按实际输出字号单独测量。
|
|
12979
13044
|
var measurementSize = segmented ? 10 : run.fontSize;
|
|
12980
13045
|
var scale = run.fontSize / measurementSize;
|
|
12981
|
-
var
|
|
13046
|
+
var weight = run.bold ? 'bold' : 'normal';
|
|
13047
|
+
var style = run.italic ? 'italic' : 'normal';
|
|
13048
|
+
var font = buildCanvasFontDesc(measurementSize, family, weight, style);
|
|
12982
13049
|
var metrics = conversionOptions.measureText == null ? void 0 : conversionOptions.measureText.call(conversionOptions, font, segmented ? 'x' : run.text);
|
|
12983
|
-
var
|
|
12984
|
-
|
|
12985
|
-
];
|
|
12986
|
-
var
|
|
12987
|
-
|
|
12988
|
-
var
|
|
12989
|
-
|
|
12990
|
-
|
|
12991
|
-
|
|
12992
|
-
|
|
12993
|
-
|
|
12994
|
-
|
|
12995
|
-
|
|
12996
|
-
var
|
|
12997
|
-
|
|
13050
|
+
var characters = Array.from(run.text);
|
|
13051
|
+
// 片段协议不输出额外字重和斜体,测宽使用同样的普通样式。
|
|
13052
|
+
var widthFontSize = run.fontSize * renderScale[1];
|
|
13053
|
+
var widthFont = buildCanvasFontDesc(widthFontSize, family, 'normal', 'normal');
|
|
13054
|
+
var measureWidth = function measureWidth(text) {
|
|
13055
|
+
var width = conversionOptions.measureText == null ? void 0 : conversionOptions.measureText.call(conversionOptions, widthFont, text).width;
|
|
13056
|
+
if (width != null && Number.isFinite(width) && width >= 0) {
|
|
13057
|
+
return width;
|
|
13058
|
+
}
|
|
13059
|
+
estimated = true;
|
|
13060
|
+
return estimateTextWidth(text, widthFontSize, 0, undefined, family, 'normal', 'normal');
|
|
13061
|
+
};
|
|
13062
|
+
// 字距和字宽交替累加,保持与 Artis 逐字测宽的计算顺序一致。
|
|
13063
|
+
var renderedWidth = 0;
|
|
13064
|
+
characters.forEach(function(character, index) {
|
|
13065
|
+
if (index > 0) {
|
|
13066
|
+
renderedWidth += spacing * renderScale[0];
|
|
13067
|
+
}
|
|
13068
|
+
renderedWidth += measureWidth(character);
|
|
13069
|
+
});
|
|
13070
|
+
var width = renderedWidth / renderScale[0];
|
|
13071
|
+
var fallback = resolveFontMetrics(undefined, family, weight, style, run.fontSize);
|
|
13072
|
+
var ascent = (metrics == null ? void 0 : metrics.fontBoundingBoxAscent) == null ? fallback.asc : metrics.fontBoundingBoxAscent * scale;
|
|
13073
|
+
var descent = (metrics == null ? void 0 : metrics.fontBoundingBoxDescent) == null ? fallback.desc : metrics.fontBoundingBoxDescent * scale;
|
|
12998
13074
|
estimated || (estimated = (metrics == null ? void 0 : metrics.fontBoundingBoxAscent) == null || metrics.fontBoundingBoxDescent == null);
|
|
12999
|
-
if (!Number.isFinite(
|
|
13075
|
+
if (!Number.isFinite(width) || width < 0 || !Number.isFinite(ascent) || !Number.isFinite(descent)) {
|
|
13000
13076
|
throwInvalidLayerData('Text measurement returned invalid metrics.');
|
|
13001
13077
|
}
|
|
13002
13078
|
return {
|
|
13003
13079
|
run: run,
|
|
13004
|
-
width:
|
|
13080
|
+
width: width,
|
|
13005
13081
|
ascent: ascent,
|
|
13006
13082
|
descent: descent
|
|
13007
13083
|
};
|
|
@@ -13114,7 +13190,10 @@ function convertIRTextLayer(layer, state, session, id) {
|
|
|
13114
13190
|
var positioned = buildTextRunLayout(runs, font.family, layer.content.letterSpacing, layer.content, [
|
|
13115
13191
|
bounds.width,
|
|
13116
13192
|
height
|
|
13117
|
-
], options, warnings, id, preserved != null
|
|
13193
|
+
], options, warnings, id, preserved != null, [
|
|
13194
|
+
scaleX,
|
|
13195
|
+
scaleY
|
|
13196
|
+
]);
|
|
13118
13197
|
if (positioned.length === 0) {
|
|
13119
13198
|
return undefined;
|
|
13120
13199
|
}
|
|
@@ -13128,25 +13207,25 @@ function convertIRTextLayer(layer, state, session, id) {
|
|
|
13128
13207
|
part.box[3] + centerY
|
|
13129
13208
|
]);
|
|
13130
13209
|
});
|
|
13131
|
-
var bbox = mapPointsToBBox(polygons.flat());
|
|
13132
|
-
var rotation =
|
|
13210
|
+
var bbox = mapPointsToBBox(polygons.flat(), false);
|
|
13211
|
+
var rotation = Math.atan2(matrix.b, matrix.a) * 180 / Math.PI;
|
|
13133
13212
|
var fragments = positioned.map(function(part, index) {
|
|
13134
13213
|
var polygon = polygons[index].map(function(point) {
|
|
13135
13214
|
return [
|
|
13136
|
-
|
|
13137
|
-
|
|
13215
|
+
point[0] - bbox[0],
|
|
13216
|
+
point[1] - bbox[1]
|
|
13138
13217
|
];
|
|
13139
13218
|
});
|
|
13140
13219
|
return {
|
|
13141
13220
|
content: part.run.text,
|
|
13142
|
-
bbox: mapPointsToBBox(polygon),
|
|
13221
|
+
bbox: mapPointsToBBox(polygon, false),
|
|
13143
13222
|
polygon: polygon,
|
|
13144
|
-
font_family: font.family,
|
|
13145
|
-
font_size:
|
|
13223
|
+
font_family: normalizeFontFamilyName(font.family),
|
|
13224
|
+
font_size: part.run.fontSize * scaleY,
|
|
13146
13225
|
color: part.run.color,
|
|
13147
|
-
letter_spacing:
|
|
13226
|
+
letter_spacing: layer.content.letterSpacing * scaleX,
|
|
13148
13227
|
direction: 'horizontal',
|
|
13149
|
-
rotation: rotation
|
|
13228
|
+
rotation: rotation === 0 ? 0 : rotation
|
|
13150
13229
|
};
|
|
13151
13230
|
});
|
|
13152
13231
|
return {
|
|
@@ -13185,7 +13264,43 @@ function createLayerConverterRegistry(session) {
|
|
|
13185
13264
|
]);
|
|
13186
13265
|
}
|
|
13187
13266
|
|
|
13267
|
+
/** 完全覆盖图片的直边矩形 mask 不改变可见内容。 */ function maskCoversImage(mask, bounds) {
|
|
13268
|
+
var _Math, _Math1, _Math2, _Math3;
|
|
13269
|
+
var path = mask.path;
|
|
13270
|
+
var epsilon = 1e-6;
|
|
13271
|
+
if (mask.mode === 'subtract' || mask.inverted === true || !path.closed || path.points.length !== 4) {
|
|
13272
|
+
return false;
|
|
13273
|
+
}
|
|
13274
|
+
if (path.inTangents.length !== 4 || path.outTangents.length !== 4 || [].concat(path.inTangents, path.outTangents).some(function(tangent) {
|
|
13275
|
+
return tangent.x !== 0 || tangent.y !== 0;
|
|
13276
|
+
})) {
|
|
13277
|
+
return false;
|
|
13278
|
+
}
|
|
13279
|
+
var straightEdges = path.points.every(function(point, index) {
|
|
13280
|
+
var next = path.points[(index + 1) % 4];
|
|
13281
|
+
var opposite = path.points[(index + 2) % 4];
|
|
13282
|
+
var dx = Math.abs(next.x - point.x);
|
|
13283
|
+
var dy = Math.abs(next.y - point.y);
|
|
13284
|
+
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);
|
|
13285
|
+
});
|
|
13286
|
+
if (!straightEdges) {
|
|
13287
|
+
return false;
|
|
13288
|
+
}
|
|
13289
|
+
var xs = path.points.map(function(point) {
|
|
13290
|
+
return point.x;
|
|
13291
|
+
});
|
|
13292
|
+
var ys = path.points.map(function(point) {
|
|
13293
|
+
return point.y;
|
|
13294
|
+
});
|
|
13295
|
+
var left = (_Math = Math).min.apply(_Math, [].concat(xs));
|
|
13296
|
+
var right = (_Math1 = Math).max.apply(_Math1, [].concat(xs));
|
|
13297
|
+
var top = (_Math2 = Math).min.apply(_Math2, [].concat(ys));
|
|
13298
|
+
var bottom = (_Math3 = Math).max.apply(_Math3, [].concat(ys));
|
|
13299
|
+
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;
|
|
13300
|
+
}
|
|
13301
|
+
|
|
13188
13302
|
function resolveIRVisualState(layer, session) {
|
|
13303
|
+
var _layer_masks;
|
|
13189
13304
|
if (!layer.visible) {
|
|
13190
13305
|
return undefined;
|
|
13191
13306
|
}
|
|
@@ -13193,19 +13308,22 @@ function resolveIRVisualState(layer, session) {
|
|
|
13193
13308
|
if (!state.visible || state.opacity <= 0) {
|
|
13194
13309
|
return undefined;
|
|
13195
13310
|
}
|
|
13196
|
-
|
|
13311
|
+
var unsupportedMask = ((_layer_masks = layer.masks) != null ? _layer_masks : []).some(function(mask) {
|
|
13312
|
+
return layer.type !== 'image' || !maskCoversImage(mask, layer.localBounds);
|
|
13313
|
+
});
|
|
13314
|
+
if (unsupportedMask || layer.matte != null) {
|
|
13197
13315
|
throwUnsupportedLayerFeature('Mask or clipping is not supported by the flat layer protocol.');
|
|
13198
13316
|
}
|
|
13199
13317
|
if (Math.abs(state.opacity - 1) > 1e-6) {
|
|
13200
13318
|
throwUnsupportedLayerFeature('Layer opacity cannot be expressed by the target protocol.');
|
|
13201
13319
|
}
|
|
13202
13320
|
if (layer.blendMode != null && layer.blendMode !== animationIr.IRBlendMode.Normal) {
|
|
13203
|
-
|
|
13321
|
+
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);
|
|
13204
13322
|
}
|
|
13205
13323
|
return state;
|
|
13206
13324
|
}
|
|
13207
13325
|
|
|
13208
|
-
function buildIRStaticLayers(session) {
|
|
13326
|
+
function buildIRStaticLayers(session, sourceIds) {
|
|
13209
13327
|
var composition = session.composition, maskSourceIds = session.maskSourceIds, options = session.options, warnings = session.warnings;
|
|
13210
13328
|
var registry = createLayerConverterRegistry(session);
|
|
13211
13329
|
var result = [];
|
|
@@ -13230,6 +13348,7 @@ function buildIRStaticLayers(session) {
|
|
|
13230
13348
|
var converted = converter.convert(layer, state, converter.layerType + "_" + String(index).padStart(4, '0'));
|
|
13231
13349
|
if (converted != null) {
|
|
13232
13350
|
result.push(converted);
|
|
13351
|
+
sourceIds == null ? void 0 : sourceIds.set(converted, layer.id);
|
|
13233
13352
|
layerCounts.set(converter.layerType, index);
|
|
13234
13353
|
}
|
|
13235
13354
|
} catch (error) {
|
|
@@ -13242,9 +13361,9 @@ function buildIRStaticLayers(session) {
|
|
|
13242
13361
|
return result;
|
|
13243
13362
|
}
|
|
13244
13363
|
|
|
13245
|
-
function assembleSVGStaticLayers(scene, options, warnings, preservedData) {
|
|
13364
|
+
function assembleSVGStaticLayers(scene, options, warnings, preservedData, sourceIds) {
|
|
13246
13365
|
var session = buildLayerConversionSession(scene, options, warnings, preservedData);
|
|
13247
|
-
var data = buildIRStaticLayers(session);
|
|
13366
|
+
var data = buildIRStaticLayers(session, sourceIds);
|
|
13248
13367
|
var composition = session.composition;
|
|
13249
13368
|
if (composition.backgroundColor != null) {
|
|
13250
13369
|
collectLayerWarning(warnings, options, SVG2IR_WARNING_CODES.LAYERS_UNSUPPORTED_TYPE, 'Composition background color is not an image or text layer.');
|
|
@@ -13257,6 +13376,1035 @@ function assembleSVGStaticLayers(scene, options, warnings, preservedData) {
|
|
|
13257
13376
|
data: data
|
|
13258
13377
|
};
|
|
13259
13378
|
}
|
|
13379
|
+
/** Replace baked sources, combine native and raster layers in painter order, then report final diagnostics. */ function assembleSVGLayers(input) {
|
|
13380
|
+
var _warnings, _ordered;
|
|
13381
|
+
var _input_context = input.context, scene = _input_context.ir, contextWarnings = _input_context.warnings, preservedData = _input_context.preservedData, layerSources = _input_context.layerSources, warningSources = _input_context.warningSources;
|
|
13382
|
+
var options = input.options, baking = input.baking;
|
|
13383
|
+
var warnings = contextWarnings.filter(function(warning) {
|
|
13384
|
+
return !baking.resolvesWarning(warning, warningSources.get(warning));
|
|
13385
|
+
});
|
|
13386
|
+
var composition = adapter.getIRSceneEntryComposition(scene);
|
|
13387
|
+
var nativeScene = _extends({}, scene, {
|
|
13388
|
+
compositions: scene.compositions.map(function(candidate) {
|
|
13389
|
+
return candidate === composition ? _extends({}, candidate, {
|
|
13390
|
+
layers: candidate.layers.filter(function(layer) {
|
|
13391
|
+
return !baking.replacesSource(layerSources.get(layer.id));
|
|
13392
|
+
})
|
|
13393
|
+
}) : candidate;
|
|
13394
|
+
})
|
|
13395
|
+
});
|
|
13396
|
+
var sourceIds = new Map();
|
|
13397
|
+
(_warnings = warnings).push.apply(_warnings, [].concat(baking.warnings));
|
|
13398
|
+
var native = assembleSVGStaticLayers(nativeScene, _extends({}, options, {
|
|
13399
|
+
strict: false,
|
|
13400
|
+
onWarning: undefined
|
|
13401
|
+
}), warnings, preservedData, sourceIds);
|
|
13402
|
+
var ordered = native.data.map(function(layer) {
|
|
13403
|
+
var _layerSources_get, _sourceIds_get;
|
|
13404
|
+
return {
|
|
13405
|
+
path: (_layerSources_get = layerSources.get((_sourceIds_get = sourceIds.get(layer)) != null ? _sourceIds_get : '')) != null ? _layerSources_get : '',
|
|
13406
|
+
layer: layer
|
|
13407
|
+
};
|
|
13408
|
+
});
|
|
13409
|
+
(_ordered = ordered).push.apply(_ordered, [].concat(baking.layers));
|
|
13410
|
+
ordered.sort(function(left, right) {
|
|
13411
|
+
return comparePaths(left.path, right.path);
|
|
13412
|
+
});
|
|
13413
|
+
var counts = {
|
|
13414
|
+
image: 0,
|
|
13415
|
+
text: 0
|
|
13416
|
+
};
|
|
13417
|
+
var data = ordered.map(function(param) {
|
|
13418
|
+
var layer = param.layer;
|
|
13419
|
+
return _extends({}, layer, {
|
|
13420
|
+
id: layer.type + "_" + String(++counts[layer.type]).padStart(4, '0')
|
|
13421
|
+
});
|
|
13422
|
+
});
|
|
13423
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(warnings), _step; !(_step = _iterator()).done;){
|
|
13424
|
+
var warning = _step.value;
|
|
13425
|
+
options.onWarning == null ? void 0 : options.onWarning.call(options, warning);
|
|
13426
|
+
if (options.strict === true) {
|
|
13427
|
+
var message = warning.message.replace(/^\[svg2ge:layers\] /, '');
|
|
13428
|
+
collectLayerWarning([], _extends({}, options, {
|
|
13429
|
+
onWarning: undefined
|
|
13430
|
+
}), warning.code, message, warning.elementSelector);
|
|
13431
|
+
}
|
|
13432
|
+
}
|
|
13433
|
+
return {
|
|
13434
|
+
size: native.size,
|
|
13435
|
+
data: data,
|
|
13436
|
+
warnings: warnings
|
|
13437
|
+
};
|
|
13438
|
+
}
|
|
13439
|
+
function comparePaths(left, right) {
|
|
13440
|
+
var a = left.split('/').map(Number);
|
|
13441
|
+
var b = right.split('/').map(Number);
|
|
13442
|
+
for(var index = 0; index < Math.min(a.length, b.length); index++){
|
|
13443
|
+
if (a[index] !== b[index]) {
|
|
13444
|
+
return a[index] - b[index];
|
|
13445
|
+
}
|
|
13446
|
+
}
|
|
13447
|
+
return a.length - b.length;
|
|
13448
|
+
}
|
|
13449
|
+
|
|
13450
|
+
var animatedElements = new Set([
|
|
13451
|
+
'animate',
|
|
13452
|
+
'animatetransform',
|
|
13453
|
+
'animatemotion',
|
|
13454
|
+
'set'
|
|
13455
|
+
]);
|
|
13456
|
+
var declarations$1 = new Set([
|
|
13457
|
+
'defs',
|
|
13458
|
+
'style',
|
|
13459
|
+
'title',
|
|
13460
|
+
'desc',
|
|
13461
|
+
'metadata',
|
|
13462
|
+
'symbol',
|
|
13463
|
+
'clippath',
|
|
13464
|
+
'mask',
|
|
13465
|
+
'filter',
|
|
13466
|
+
'lineargradient',
|
|
13467
|
+
'radialgradient',
|
|
13468
|
+
'pattern',
|
|
13469
|
+
'marker'
|
|
13470
|
+
]);
|
|
13471
|
+
/** Preserve selector context until styles are frozen, then isolate the requested paint subtree. */ function prepareSVGSnapshot(source, path, size, inspect) {
|
|
13472
|
+
var parsed = new DOMParser().parseFromString(source, 'image/svg+xml');
|
|
13473
|
+
if (parsed.querySelector('parsererror') != null) {
|
|
13474
|
+
throw new Error('Invalid SVG document.');
|
|
13475
|
+
}
|
|
13476
|
+
var root = parsed.documentElement;
|
|
13477
|
+
var elements = [].concat([
|
|
13478
|
+
root
|
|
13479
|
+
], Array.from(root.querySelectorAll('*')));
|
|
13480
|
+
var selected = elements.find(function(element) {
|
|
13481
|
+
return buildElementTreePath(element) === path;
|
|
13482
|
+
});
|
|
13483
|
+
if (selected == null) {
|
|
13484
|
+
throw new Error('The graphic source element could not be located.');
|
|
13485
|
+
}
|
|
13486
|
+
if (root.querySelector('script, foreignObject') != null) {
|
|
13487
|
+
throw new Error('Scripts and foreignObject are outside static graphic baking support.');
|
|
13488
|
+
}
|
|
13489
|
+
if (Array.from(root.querySelectorAll('style')).some(function(element) {
|
|
13490
|
+
var _element_textContent;
|
|
13491
|
+
return /@import|@font-face/i.test((_element_textContent = element.textContent) != null ? _element_textContent : '');
|
|
13492
|
+
})) {
|
|
13493
|
+
throw new Error('External stylesheets and fonts require explicit resource preparation.');
|
|
13494
|
+
}
|
|
13495
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(elements), _step; !(_step = _iterator()).done;){
|
|
13496
|
+
var element = _step.value;
|
|
13497
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(Array.from(element.attributes)), _step1; !(_step1 = _iterator1()).done;){
|
|
13498
|
+
var attribute = _step1.value;
|
|
13499
|
+
if (/^on/i.test(attribute.name)) {
|
|
13500
|
+
element.removeAttributeNode(attribute);
|
|
13501
|
+
}
|
|
13502
|
+
}
|
|
13503
|
+
}
|
|
13504
|
+
var frame = document.createElement('iframe');
|
|
13505
|
+
frame.setAttribute('sandbox', 'allow-same-origin');
|
|
13506
|
+
frame.style.cssText = "position:fixed;left:-100000px;top:0;width:" + size[0] + "px;height:" + size[1] + "px;border:0;";
|
|
13507
|
+
document.body.appendChild(frame);
|
|
13508
|
+
try {
|
|
13509
|
+
var _loop = function() {
|
|
13510
|
+
var element = _step3.value;
|
|
13511
|
+
var _element_getAttribute;
|
|
13512
|
+
var computed = frameWindow.getComputedStyle(element);
|
|
13513
|
+
var inside = target.contains(element);
|
|
13514
|
+
var ancestor = element !== target && element.contains(target);
|
|
13515
|
+
if ((inside || ancestor) && (computed.animationName !== 'none' || hasAnimationChildren(element))) {
|
|
13516
|
+
throw new Error('Animated graphics require an explicit sampling policy.');
|
|
13517
|
+
}
|
|
13518
|
+
// Freezing inherited defaults on a definition changes <use> instance inheritance.
|
|
13519
|
+
// Freeze only authored declarations, after matching selectors in the intact source tree.
|
|
13520
|
+
var authored = frameDocument.createElement('div').style;
|
|
13521
|
+
authored.cssText = (_element_getAttribute = element.getAttribute('style')) != null ? _element_getAttribute : '';
|
|
13522
|
+
var names = new Set(Array.from(authored));
|
|
13523
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(styleRules), _step; !(_step = _iterator()).done;){
|
|
13524
|
+
var rule = _step.value;
|
|
13525
|
+
if (element.matches(rule.selectorText)) {
|
|
13526
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(Array.from(rule.style)), _step1; !(_step1 = _iterator1()).done;){
|
|
13527
|
+
var name = _step1.value;
|
|
13528
|
+
names.add(name);
|
|
13529
|
+
}
|
|
13530
|
+
}
|
|
13531
|
+
}
|
|
13532
|
+
var properties = Array.from(names, function(name) {
|
|
13533
|
+
var value = computed.getPropertyValue(name);
|
|
13534
|
+
value = value.replace(/url\(["']?([^)'"\s]+)["']?\)/g, function(_match, url) {
|
|
13535
|
+
return 'url("' + normalizeReference(url) + '")';
|
|
13536
|
+
});
|
|
13537
|
+
return name + ":" + value + " !important;";
|
|
13538
|
+
});
|
|
13539
|
+
var isTemplate = templateRoots.some(function(template) {
|
|
13540
|
+
return template.contains(element);
|
|
13541
|
+
});
|
|
13542
|
+
frozenStyles.push(isTemplate ? null : properties.join(''));
|
|
13543
|
+
};
|
|
13544
|
+
var frameDocument = frame.contentDocument;
|
|
13545
|
+
var frameWindow = frame.contentWindow;
|
|
13546
|
+
if (frameDocument == null || frameWindow == null) {
|
|
13547
|
+
throw new Error('Unable to create isolated SVG context.');
|
|
13548
|
+
}
|
|
13549
|
+
frameDocument.body.style.cssText = 'margin:0;';
|
|
13550
|
+
var mounted = frameDocument.importNode(root, true);
|
|
13551
|
+
mounted.setAttribute('width', String(size[0]));
|
|
13552
|
+
mounted.setAttribute('height', String(size[1]));
|
|
13553
|
+
frameDocument.body.appendChild(mounted);
|
|
13554
|
+
var mountedElements = [].concat([
|
|
13555
|
+
mounted
|
|
13556
|
+
], Array.from(mounted.querySelectorAll('*')));
|
|
13557
|
+
var selectedIndex = elements.indexOf(selected);
|
|
13558
|
+
var target = mountedElements[selectedIndex];
|
|
13559
|
+
var normalizeReference = function normalizeReference(url) {
|
|
13560
|
+
if (url.startsWith('#')) {
|
|
13561
|
+
return url;
|
|
13562
|
+
}
|
|
13563
|
+
var hash = url.indexOf('#');
|
|
13564
|
+
if (hash >= 0 && url.slice(0, hash) === frameDocument.baseURI.split('#')[0]) {
|
|
13565
|
+
return url.slice(hash);
|
|
13566
|
+
}
|
|
13567
|
+
throw new Error('External paint resources require explicit resource preparation.');
|
|
13568
|
+
};
|
|
13569
|
+
var frozenStyles = [];
|
|
13570
|
+
var templateRoots = Array.from(mounted.querySelectorAll('use')).flatMap(function(element) {
|
|
13571
|
+
var _ref, _element_getAttribute;
|
|
13572
|
+
var href = (_ref = (_element_getAttribute = element.getAttribute('href')) != null ? _element_getAttribute : element.getAttribute('xlink:href')) != null ? _ref : '';
|
|
13573
|
+
var template = href.startsWith('#') ? mountedElements.find(function(candidate) {
|
|
13574
|
+
return candidate.id === href.slice(1);
|
|
13575
|
+
}) : null;
|
|
13576
|
+
return template == null ? [] : [
|
|
13577
|
+
template
|
|
13578
|
+
];
|
|
13579
|
+
});
|
|
13580
|
+
var styleRules = [];
|
|
13581
|
+
var collectRules = function collectRules1(rules) {
|
|
13582
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(Array.from(rules)), _step; !(_step = _iterator()).done;){
|
|
13583
|
+
var rule = _step.value;
|
|
13584
|
+
if (isStyleRule$2(rule)) {
|
|
13585
|
+
styleRules.push(rule);
|
|
13586
|
+
} else if (hasNestedRules$1(rule)) {
|
|
13587
|
+
if (isMediaRule(rule) && !frameWindow.matchMedia(rule.conditionText).matches) {
|
|
13588
|
+
continue;
|
|
13589
|
+
}
|
|
13590
|
+
collectRules(rule.cssRules);
|
|
13591
|
+
}
|
|
13592
|
+
}
|
|
13593
|
+
};
|
|
13594
|
+
for(var _iterator2 = _create_for_of_iterator_helper_loose(Array.from(frameDocument.styleSheets)), _step2; !(_step2 = _iterator2()).done;){
|
|
13595
|
+
var sheet = _step2.value;
|
|
13596
|
+
collectRules(sheet.cssRules);
|
|
13597
|
+
}
|
|
13598
|
+
for(var _iterator3 = _create_for_of_iterator_helper_loose(mountedElements), _step3; !(_step3 = _iterator3()).done;)_loop();
|
|
13599
|
+
for(var index = 0; index < mountedElements.length; index++){
|
|
13600
|
+
var style = frozenStyles[index];
|
|
13601
|
+
if (style != null) {
|
|
13602
|
+
mountedElements[index].setAttribute('style', style);
|
|
13603
|
+
}
|
|
13604
|
+
}
|
|
13605
|
+
var byId = new Map(mountedElements.filter(function(element) {
|
|
13606
|
+
return element.id !== '';
|
|
13607
|
+
}).map(function(element) {
|
|
13608
|
+
return [
|
|
13609
|
+
element.id,
|
|
13610
|
+
element
|
|
13611
|
+
];
|
|
13612
|
+
}));
|
|
13613
|
+
var seen = new Set();
|
|
13614
|
+
var checkDependencies = function checkDependencies1(element) {
|
|
13615
|
+
if (seen.has(element)) {
|
|
13616
|
+
return;
|
|
13617
|
+
}
|
|
13618
|
+
seen.add(element);
|
|
13619
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(Array.from(element.attributes)), _step; !(_step = _iterator()).done;){
|
|
13620
|
+
var attribute = _step.value;
|
|
13621
|
+
if (attribute.localName === 'href' && element.tagName.toLowerCase() === 'a') {
|
|
13622
|
+
continue;
|
|
13623
|
+
}
|
|
13624
|
+
if (attribute.localName === 'href' && !attribute.value.startsWith('#') && !([
|
|
13625
|
+
'image',
|
|
13626
|
+
'feimage'
|
|
13627
|
+
].includes(element.tagName.toLowerCase()) && /^data:image\//i.test(attribute.value))) {
|
|
13628
|
+
throw new Error('External SVG references require explicit resource preparation.');
|
|
13629
|
+
}
|
|
13630
|
+
var normalized = attribute.value.replace(/url\(\s*["']?([^)'"\s]+)["']?\s*\)/g, function(_match, url) {
|
|
13631
|
+
return 'url("' + normalizeReference(url) + '")';
|
|
13632
|
+
});
|
|
13633
|
+
var ids = Array.from(normalized.matchAll(/url\(["']?#([^)'"\s]+)["']?\)/g), function(match) {
|
|
13634
|
+
return match[1];
|
|
13635
|
+
});
|
|
13636
|
+
if (normalized !== attribute.value) {
|
|
13637
|
+
element.setAttribute(attribute.name, normalized);
|
|
13638
|
+
}
|
|
13639
|
+
if (attribute.localName === 'href' && attribute.value.startsWith('#')) {
|
|
13640
|
+
ids.push(attribute.value.slice(1));
|
|
13641
|
+
}
|
|
13642
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(ids), _step1; !(_step1 = _iterator1()).done;){
|
|
13643
|
+
var id = _step1.value;
|
|
13644
|
+
var dependency = byId.get(id);
|
|
13645
|
+
if (dependency == null) {
|
|
13646
|
+
throw new Error("Missing SVG reference: #" + id + ".");
|
|
13647
|
+
}
|
|
13648
|
+
checkDependencies(dependency);
|
|
13649
|
+
}
|
|
13650
|
+
}
|
|
13651
|
+
for(var _iterator2 = _create_for_of_iterator_helper_loose(Array.from(element.children)), _step2; !(_step2 = _iterator2()).done;){
|
|
13652
|
+
var child = _step2.value;
|
|
13653
|
+
if (!declarations$1.has(child.tagName.toLowerCase())) {
|
|
13654
|
+
checkDependencies(child);
|
|
13655
|
+
}
|
|
13656
|
+
}
|
|
13657
|
+
};
|
|
13658
|
+
checkDependencies(target);
|
|
13659
|
+
for(var _iterator4 = _create_for_of_iterator_helper_loose(seen), _step4; !(_step4 = _iterator4()).done;){
|
|
13660
|
+
var dependency = _step4.value;
|
|
13661
|
+
if (frameWindow.getComputedStyle(dependency).animationName !== 'none' || hasAnimationChildren(dependency)) {
|
|
13662
|
+
throw new Error('Animated graphics require an explicit sampling policy.');
|
|
13663
|
+
}
|
|
13664
|
+
}
|
|
13665
|
+
inspect == null ? void 0 : inspect({
|
|
13666
|
+
root: mounted,
|
|
13667
|
+
target: target,
|
|
13668
|
+
elements: mountedElements,
|
|
13669
|
+
dependencies: seen,
|
|
13670
|
+
readStyle: function readStyle(element) {
|
|
13671
|
+
return frameWindow.getComputedStyle(element);
|
|
13672
|
+
}
|
|
13673
|
+
});
|
|
13674
|
+
var isolate = function isolate1(element) {
|
|
13675
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(Array.from(element.children)), _step; !(_step = _iterator()).done;){
|
|
13676
|
+
var child = _step.value;
|
|
13677
|
+
var tag = child.tagName.toLowerCase();
|
|
13678
|
+
if (declarations$1.has(tag) || child === target || target.contains(child)) {
|
|
13679
|
+
continue;
|
|
13680
|
+
}
|
|
13681
|
+
if (child.contains(target)) {
|
|
13682
|
+
isolate(child);
|
|
13683
|
+
} else {
|
|
13684
|
+
var definitions = frameDocument.createElementNS('http://www.w3.org/2000/svg', 'defs');
|
|
13685
|
+
child.replaceWith(definitions);
|
|
13686
|
+
definitions.appendChild(child);
|
|
13687
|
+
}
|
|
13688
|
+
}
|
|
13689
|
+
};
|
|
13690
|
+
if (target !== mounted) {
|
|
13691
|
+
isolate(mounted);
|
|
13692
|
+
}
|
|
13693
|
+
return new XMLSerializer().serializeToString(mounted);
|
|
13694
|
+
} finally{
|
|
13695
|
+
frame.remove();
|
|
13696
|
+
}
|
|
13697
|
+
}
|
|
13698
|
+
/** Only animations attached to this element reject its own bake scope, not unrelated subtrees. */ function hasAnimationChildren(element) {
|
|
13699
|
+
return Array.from(element.children).some(function(child) {
|
|
13700
|
+
return animatedElements.has(child.tagName.toLowerCase());
|
|
13701
|
+
});
|
|
13702
|
+
}
|
|
13703
|
+
function isStyleRule$2(rule) {
|
|
13704
|
+
return rule.type === 1;
|
|
13705
|
+
}
|
|
13706
|
+
function hasNestedRules$1(rule) {
|
|
13707
|
+
return 'cssRules' in rule;
|
|
13708
|
+
}
|
|
13709
|
+
function isMediaRule(rule) {
|
|
13710
|
+
return rule.type === 4;
|
|
13711
|
+
}
|
|
13712
|
+
|
|
13713
|
+
/** Render an SVG subtree as a cropped PNG, or return null if it has no visible pixels. */ function rasterizeSVG(source, path, size, scale, inspect) {
|
|
13714
|
+
if (scale === void 0) scale = 2;
|
|
13715
|
+
return _async_to_generator(function() {
|
|
13716
|
+
var snapshot, canvas;
|
|
13717
|
+
return _ts_generator(this, function(_state) {
|
|
13718
|
+
switch(_state.label){
|
|
13719
|
+
case 0:
|
|
13720
|
+
if (!Number.isFinite(scale) || scale <= 0) {
|
|
13721
|
+
throw new RangeError('rasterScale must be finite and positive.');
|
|
13722
|
+
}
|
|
13723
|
+
if (Math.ceil(size[0] * scale) * Math.ceil(size[1] * scale) > 16777216) {
|
|
13724
|
+
throw new RangeError('SVG rasterization exceeds the 16 megapixel working limit; reduce rasterScale.');
|
|
13725
|
+
}
|
|
13726
|
+
snapshot = prepareSVGSnapshot(source, path, size, inspect);
|
|
13727
|
+
return [
|
|
13728
|
+
4,
|
|
13729
|
+
renderSVG(snapshot, size, scale)
|
|
13730
|
+
];
|
|
13731
|
+
case 1:
|
|
13732
|
+
canvas = _state.sent();
|
|
13733
|
+
return [
|
|
13734
|
+
2,
|
|
13735
|
+
cropRasterImage(canvas, scale)
|
|
13736
|
+
];
|
|
13737
|
+
}
|
|
13738
|
+
});
|
|
13739
|
+
})();
|
|
13740
|
+
}
|
|
13741
|
+
/** No DOM access at module initialization: the Node entry also imports this module. */ function canRasterizeSVG() {
|
|
13742
|
+
return typeof window !== 'undefined' && typeof document !== 'undefined' && typeof window.HTMLCanvasElement === 'function' && typeof window.Image === 'function' && typeof window.getComputedStyle === 'function';
|
|
13743
|
+
}
|
|
13744
|
+
function renderSVG(svg, size, scale) {
|
|
13745
|
+
return _async_to_generator(function() {
|
|
13746
|
+
var canvas, context, image, url;
|
|
13747
|
+
return _ts_generator(this, function(_state) {
|
|
13748
|
+
switch(_state.label){
|
|
13749
|
+
case 0:
|
|
13750
|
+
canvas = document.createElement('canvas');
|
|
13751
|
+
canvas.width = Math.ceil(size[0] * scale);
|
|
13752
|
+
canvas.height = Math.ceil(size[1] * scale);
|
|
13753
|
+
context = canvas.getContext('2d');
|
|
13754
|
+
if (context == null) {
|
|
13755
|
+
throw new Error('A 2D canvas context is required for SVG rasterization.');
|
|
13756
|
+
}
|
|
13757
|
+
image = new Image();
|
|
13758
|
+
url = URL.createObjectURL(new Blob([
|
|
13759
|
+
svg
|
|
13760
|
+
], {
|
|
13761
|
+
type: 'image/svg+xml'
|
|
13762
|
+
}));
|
|
13763
|
+
_state.label = 1;
|
|
13764
|
+
case 1:
|
|
13765
|
+
_state.trys.push([
|
|
13766
|
+
1,
|
|
13767
|
+
,
|
|
13768
|
+
3,
|
|
13769
|
+
4
|
|
13770
|
+
]);
|
|
13771
|
+
return [
|
|
13772
|
+
4,
|
|
13773
|
+
new Promise(function(resolve, reject) {
|
|
13774
|
+
image.onload = function() {
|
|
13775
|
+
return resolve();
|
|
13776
|
+
};
|
|
13777
|
+
image.onerror = function() {
|
|
13778
|
+
return reject(new Error('The prepared SVG could not be decoded.'));
|
|
13779
|
+
};
|
|
13780
|
+
image.src = url;
|
|
13781
|
+
})
|
|
13782
|
+
];
|
|
13783
|
+
case 2:
|
|
13784
|
+
_state.sent();
|
|
13785
|
+
context.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
13786
|
+
return [
|
|
13787
|
+
2,
|
|
13788
|
+
canvas
|
|
13789
|
+
];
|
|
13790
|
+
case 3:
|
|
13791
|
+
URL.revokeObjectURL(url);
|
|
13792
|
+
return [
|
|
13793
|
+
7
|
|
13794
|
+
];
|
|
13795
|
+
case 4:
|
|
13796
|
+
return [
|
|
13797
|
+
2
|
|
13798
|
+
];
|
|
13799
|
+
}
|
|
13800
|
+
});
|
|
13801
|
+
})();
|
|
13802
|
+
}
|
|
13803
|
+
/** Trim transparent pixels after rendering, retaining strokes, blur and filter extents. */ function cropRasterImage(canvas, scale) {
|
|
13804
|
+
var context = canvas.getContext('2d');
|
|
13805
|
+
if (context == null) {
|
|
13806
|
+
throw new Error('A 2D canvas context is required for SVG rasterization.');
|
|
13807
|
+
}
|
|
13808
|
+
var data = context.getImageData(0, 0, canvas.width, canvas.height).data;
|
|
13809
|
+
var left = canvas.width;
|
|
13810
|
+
var top = canvas.height;
|
|
13811
|
+
var right = 0;
|
|
13812
|
+
var bottom = 0;
|
|
13813
|
+
for(var y = 0; y < canvas.height; y++){
|
|
13814
|
+
for(var x = 0; x < canvas.width; x++){
|
|
13815
|
+
if (data[(y * canvas.width + x) * 4 + 3] === 0) {
|
|
13816
|
+
continue;
|
|
13817
|
+
}
|
|
13818
|
+
left = Math.min(left, x);
|
|
13819
|
+
top = Math.min(top, y);
|
|
13820
|
+
right = Math.max(right, x + 1);
|
|
13821
|
+
bottom = Math.max(bottom, y + 1);
|
|
13822
|
+
}
|
|
13823
|
+
}
|
|
13824
|
+
if (right <= left || bottom <= top) {
|
|
13825
|
+
return null;
|
|
13826
|
+
}
|
|
13827
|
+
var cropped = document.createElement('canvas');
|
|
13828
|
+
cropped.width = right - left;
|
|
13829
|
+
cropped.height = bottom - top;
|
|
13830
|
+
var croppedContext = cropped.getContext('2d');
|
|
13831
|
+
if (croppedContext == null) {
|
|
13832
|
+
throw new Error('A 2D canvas context is required for SVG rasterization.');
|
|
13833
|
+
}
|
|
13834
|
+
croppedContext.drawImage(canvas, left, top, cropped.width, cropped.height, 0, 0, cropped.width, cropped.height);
|
|
13835
|
+
return {
|
|
13836
|
+
url: cropped.toDataURL('image/png'),
|
|
13837
|
+
bbox: [
|
|
13838
|
+
left / scale,
|
|
13839
|
+
top / scale,
|
|
13840
|
+
right / scale,
|
|
13841
|
+
bottom / scale
|
|
13842
|
+
]
|
|
13843
|
+
};
|
|
13844
|
+
}
|
|
13845
|
+
|
|
13846
|
+
var normalValues = new Set([
|
|
13847
|
+
'normal',
|
|
13848
|
+
'initial',
|
|
13849
|
+
'inherit',
|
|
13850
|
+
'unset',
|
|
13851
|
+
'revert',
|
|
13852
|
+
'revert-layer'
|
|
13853
|
+
]);
|
|
13854
|
+
/** Replace non-normal mix-blend-mode declarations with normal and report each downgrade. */ function normalizeLayerBlending(source) {
|
|
13855
|
+
var _loop = function() {
|
|
13856
|
+
var element = _step.value;
|
|
13857
|
+
var _element_getAttribute;
|
|
13858
|
+
var _readPresentationAttribute;
|
|
13859
|
+
var tag = element.tagName.toLowerCase();
|
|
13860
|
+
var id = (_element_getAttribute = element.getAttribute('id')) != null ? _element_getAttribute : '';
|
|
13861
|
+
var selector = id === '' ? tag : tag + "#" + id;
|
|
13862
|
+
var mode = (_readPresentationAttribute = readPresentationAttribute(element, 'mix-blend-mode')) == null ? void 0 : _readPresentationAttribute.replace(/\/\*[\s\S]*?\*\//g, '').trim();
|
|
13863
|
+
if (mode != null && !normalValues.has(mode.toLowerCase())) {
|
|
13864
|
+
downgrades.push({
|
|
13865
|
+
mode: mode,
|
|
13866
|
+
selector: selector
|
|
13867
|
+
});
|
|
13868
|
+
}
|
|
13869
|
+
var style = element.getAttribute('style');
|
|
13870
|
+
if (style != null) {
|
|
13871
|
+
var normalized = normalizeBlendDeclarations(style);
|
|
13872
|
+
if (normalized !== style) {
|
|
13873
|
+
element.setAttribute('style', normalized);
|
|
13874
|
+
changed = true;
|
|
13875
|
+
}
|
|
13876
|
+
}
|
|
13877
|
+
var attribute = element.getAttribute('mix-blend-mode');
|
|
13878
|
+
if (attribute != null && !normalValues.has(attribute.trim().toLowerCase())) {
|
|
13879
|
+
element.setAttribute('mix-blend-mode', 'normal');
|
|
13880
|
+
changed = true;
|
|
13881
|
+
}
|
|
13882
|
+
if (tag === 'style') {
|
|
13883
|
+
var _element_textContent;
|
|
13884
|
+
var text = (_element_textContent = element.textContent) != null ? _element_textContent : '';
|
|
13885
|
+
var normalized1 = normalizeBlendDeclarations(text, function(value) {
|
|
13886
|
+
return downgrades.push({
|
|
13887
|
+
mode: value,
|
|
13888
|
+
selector: selector
|
|
13889
|
+
});
|
|
13890
|
+
});
|
|
13891
|
+
if (normalized1 !== text) {
|
|
13892
|
+
element.textContent = normalized1;
|
|
13893
|
+
changed = true;
|
|
13894
|
+
}
|
|
13895
|
+
}
|
|
13896
|
+
};
|
|
13897
|
+
var svg = svg_js.SVG(source);
|
|
13898
|
+
var downgrades = [];
|
|
13899
|
+
var changed = false;
|
|
13900
|
+
for(var _iterator = _create_for_of_iterator_helper_loose([].concat([
|
|
13901
|
+
svg.node
|
|
13902
|
+
], Array.from(svg.node.querySelectorAll('*')))), _step; !(_step = _iterator()).done;)_loop();
|
|
13903
|
+
return {
|
|
13904
|
+
source: changed ? svg.svg() : source,
|
|
13905
|
+
downgrades: downgrades
|
|
13906
|
+
};
|
|
13907
|
+
}
|
|
13908
|
+
/** Match declaration boundaries without changing strings, comments or function arguments. */ function normalizeBlendDeclarations(source, onDowngrade) {
|
|
13909
|
+
var replacements = [];
|
|
13910
|
+
var start = 0;
|
|
13911
|
+
var colon = -1;
|
|
13912
|
+
var parentheses = 0;
|
|
13913
|
+
var quote;
|
|
13914
|
+
var comment = false;
|
|
13915
|
+
var finish = function finish(end) {
|
|
13916
|
+
if (colon < start) {
|
|
13917
|
+
return;
|
|
13918
|
+
}
|
|
13919
|
+
var name = source.slice(start, colon).replace(/\/\*[\s\S]*?\*\//g, '').trim().toLowerCase();
|
|
13920
|
+
if (name !== 'mix-blend-mode') {
|
|
13921
|
+
return;
|
|
13922
|
+
}
|
|
13923
|
+
var value = source.slice(colon + 1, end).replace(/\/\*[\s\S]*?\*\//g, '').trim();
|
|
13924
|
+
var mode = value.replace(/\s*!important\s*$/i, '').trim();
|
|
13925
|
+
if (mode === '' || normalValues.has(mode.toLowerCase())) {
|
|
13926
|
+
return;
|
|
13927
|
+
}
|
|
13928
|
+
onDowngrade == null ? void 0 : onDowngrade(mode);
|
|
13929
|
+
replacements.push({
|
|
13930
|
+
start: colon + 1,
|
|
13931
|
+
end: end,
|
|
13932
|
+
value: /!important\s*$/i.test(value) ? ' normal !important' : ' normal'
|
|
13933
|
+
});
|
|
13934
|
+
};
|
|
13935
|
+
for(var index = 0; index < source.length; index++){
|
|
13936
|
+
var character = source[index];
|
|
13937
|
+
var next = source[index + 1];
|
|
13938
|
+
if (comment) {
|
|
13939
|
+
if (character === '*' && next === '/') {
|
|
13940
|
+
comment = false;
|
|
13941
|
+
index++;
|
|
13942
|
+
}
|
|
13943
|
+
continue;
|
|
13944
|
+
}
|
|
13945
|
+
if (quote != null) {
|
|
13946
|
+
if (character === '\\') {
|
|
13947
|
+
index++;
|
|
13948
|
+
} else if (character === quote) {
|
|
13949
|
+
quote = undefined;
|
|
13950
|
+
}
|
|
13951
|
+
continue;
|
|
13952
|
+
}
|
|
13953
|
+
if (character === '/' && next === '*') {
|
|
13954
|
+
comment = true;
|
|
13955
|
+
index++;
|
|
13956
|
+
continue;
|
|
13957
|
+
}
|
|
13958
|
+
if (character === '"' || character === "'") {
|
|
13959
|
+
quote = character;
|
|
13960
|
+
continue;
|
|
13961
|
+
}
|
|
13962
|
+
if (character === '(') {
|
|
13963
|
+
parentheses++;
|
|
13964
|
+
continue;
|
|
13965
|
+
}
|
|
13966
|
+
if (character === ')') {
|
|
13967
|
+
parentheses = Math.max(0, parentheses - 1);
|
|
13968
|
+
continue;
|
|
13969
|
+
}
|
|
13970
|
+
if (parentheses > 0) {
|
|
13971
|
+
continue;
|
|
13972
|
+
}
|
|
13973
|
+
if (character === ':' && colon < start) {
|
|
13974
|
+
colon = index;
|
|
13975
|
+
}
|
|
13976
|
+
if (character === ';' || character === '}' || character === '{') {
|
|
13977
|
+
if (character !== '{') {
|
|
13978
|
+
finish(index);
|
|
13979
|
+
}
|
|
13980
|
+
start = index + 1;
|
|
13981
|
+
colon = -1;
|
|
13982
|
+
}
|
|
13983
|
+
}
|
|
13984
|
+
finish(source.length);
|
|
13985
|
+
var result = '';
|
|
13986
|
+
var cursor = 0;
|
|
13987
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(replacements), _step; !(_step = _iterator()).done;){
|
|
13988
|
+
var replacement = _step.value;
|
|
13989
|
+
result += source.slice(cursor, replacement.start) + replacement.value;
|
|
13990
|
+
cursor = replacement.end;
|
|
13991
|
+
}
|
|
13992
|
+
return result + source.slice(cursor);
|
|
13993
|
+
}
|
|
13994
|
+
|
|
13995
|
+
var declarations = new Set([
|
|
13996
|
+
'defs',
|
|
13997
|
+
'style',
|
|
13998
|
+
'title',
|
|
13999
|
+
'desc',
|
|
14000
|
+
'metadata',
|
|
14001
|
+
'symbol',
|
|
14002
|
+
'clippath',
|
|
14003
|
+
'mask',
|
|
14004
|
+
'filter',
|
|
14005
|
+
'lineargradient',
|
|
14006
|
+
'radialgradient',
|
|
14007
|
+
'pattern',
|
|
14008
|
+
'marker'
|
|
14009
|
+
]);
|
|
14010
|
+
var graphics = new Set([
|
|
14011
|
+
'path',
|
|
14012
|
+
'rect',
|
|
14013
|
+
'circle',
|
|
14014
|
+
'ellipse',
|
|
14015
|
+
'line',
|
|
14016
|
+
'polyline',
|
|
14017
|
+
'polygon',
|
|
14018
|
+
'use'
|
|
14019
|
+
]);
|
|
14020
|
+
var containers = new Set([
|
|
14021
|
+
'svg',
|
|
14022
|
+
'g',
|
|
14023
|
+
'a',
|
|
14024
|
+
'switch'
|
|
14025
|
+
]);
|
|
14026
|
+
var groupEffects = [
|
|
14027
|
+
'opacity',
|
|
14028
|
+
'filter',
|
|
14029
|
+
'mask',
|
|
14030
|
+
'clip-path'
|
|
14031
|
+
];
|
|
14032
|
+
var native = new Set([
|
|
14033
|
+
'text',
|
|
14034
|
+
'image',
|
|
14035
|
+
'foreignobject'
|
|
14036
|
+
]);
|
|
14037
|
+
/** Select graphic-only subtrees; keep native text and images as separate layers. */ function planGraphicBaking(source) {
|
|
14038
|
+
var root = svg_js.SVG(source).node;
|
|
14039
|
+
var scopes = [];
|
|
14040
|
+
var warnings = [];
|
|
14041
|
+
var effectRules = collectGroupEffectRules(root);
|
|
14042
|
+
var byId = new Map(Array.from(root.querySelectorAll('[id]')).map(function(element) {
|
|
14043
|
+
var _element_getAttribute;
|
|
14044
|
+
return [
|
|
14045
|
+
(_element_getAttribute = element.getAttribute('id')) != null ? _element_getAttribute : '',
|
|
14046
|
+
element
|
|
14047
|
+
];
|
|
14048
|
+
}));
|
|
14049
|
+
var tagOf = function tagOf(element) {
|
|
14050
|
+
return element.tagName.toLowerCase();
|
|
14051
|
+
};
|
|
14052
|
+
var selectorOf = function selectorOf(element) {
|
|
14053
|
+
var _element_getAttribute;
|
|
14054
|
+
var id = (_element_getAttribute = element.getAttribute('id')) != null ? _element_getAttribute : '';
|
|
14055
|
+
return "" + tagOf(element) + (id === '' ? '' : "#" + id);
|
|
14056
|
+
};
|
|
14057
|
+
var references = function references(element) {
|
|
14058
|
+
var ids = Array.from(element.attributes).flatMap(function(attribute) {
|
|
14059
|
+
var values = Array.from(attribute.value.matchAll(/url\(\s*['"]?#([^)'"\s]+)['"]?\s*\)/g), function(match) {
|
|
14060
|
+
return match[1];
|
|
14061
|
+
});
|
|
14062
|
+
if (attribute.localName === 'href' && attribute.value.startsWith('#')) {
|
|
14063
|
+
values.push(attribute.value.slice(1));
|
|
14064
|
+
}
|
|
14065
|
+
return values;
|
|
14066
|
+
});
|
|
14067
|
+
return ids.flatMap(function(id) {
|
|
14068
|
+
var target = byId.get(id);
|
|
14069
|
+
return target == null ? [] : [
|
|
14070
|
+
target
|
|
14071
|
+
];
|
|
14072
|
+
});
|
|
14073
|
+
};
|
|
14074
|
+
var containsNative = function containsNative1(element, seen) {
|
|
14075
|
+
if (seen === void 0) seen = new Set();
|
|
14076
|
+
if (seen.has(element)) {
|
|
14077
|
+
return false;
|
|
14078
|
+
}
|
|
14079
|
+
seen.add(element);
|
|
14080
|
+
if (native.has(tagOf(element))) {
|
|
14081
|
+
return true;
|
|
14082
|
+
}
|
|
14083
|
+
return Array.from(element.children).some(function(child) {
|
|
14084
|
+
return !declarations.has(tagOf(child)) && containsNative(child, seen);
|
|
14085
|
+
}) || references(element).some(function(target) {
|
|
14086
|
+
return containsNative(target, seen);
|
|
14087
|
+
});
|
|
14088
|
+
};
|
|
14089
|
+
var hasGraphics = function hasGraphics1(element) {
|
|
14090
|
+
return graphics.has(tagOf(element)) || Array.from(element.children).some(function(child) {
|
|
14091
|
+
return !declarations.has(tagOf(child)) && hasGraphics(child);
|
|
14092
|
+
});
|
|
14093
|
+
};
|
|
14094
|
+
var hasGroupEffect = function hasGroupEffect(element) {
|
|
14095
|
+
var _element_getAttribute;
|
|
14096
|
+
var style = (_element_getAttribute = element.getAttribute('style')) != null ? _element_getAttribute : '';
|
|
14097
|
+
return effectRules.some(function(rule) {
|
|
14098
|
+
return element.matches(rule.selectorText);
|
|
14099
|
+
}) || hasGraphicGroupEffect(function(name) {
|
|
14100
|
+
var _element_getAttribute;
|
|
14101
|
+
var _exec_, _exec;
|
|
14102
|
+
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();
|
|
14103
|
+
});
|
|
14104
|
+
};
|
|
14105
|
+
var visit = function visit1(element) {
|
|
14106
|
+
var _element_getAttribute, _ref;
|
|
14107
|
+
var _exec_, _exec;
|
|
14108
|
+
var tag = tagOf(element);
|
|
14109
|
+
var style = (_element_getAttribute = element.getAttribute('style')) != null ? _element_getAttribute : '';
|
|
14110
|
+
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');
|
|
14111
|
+
if (display === 'none') {
|
|
14112
|
+
return;
|
|
14113
|
+
}
|
|
14114
|
+
if (declarations.has(tag) || native.has(tag)) {
|
|
14115
|
+
return;
|
|
14116
|
+
}
|
|
14117
|
+
if (!containers.has(tag) && !graphics.has(tag)) {
|
|
14118
|
+
return;
|
|
14119
|
+
}
|
|
14120
|
+
if (!hasGraphics(element)) {
|
|
14121
|
+
return;
|
|
14122
|
+
}
|
|
14123
|
+
if ((graphics.has(tag) || tag === 'switch') && !containsNative(element)) {
|
|
14124
|
+
scopes.push({
|
|
14125
|
+
path: buildElementTreePath(element),
|
|
14126
|
+
selector: selectorOf(element),
|
|
14127
|
+
isGroup: containers.has(tag)
|
|
14128
|
+
});
|
|
14129
|
+
return;
|
|
14130
|
+
}
|
|
14131
|
+
if (hasGroupEffect(element) && !containsNative(element)) {
|
|
14132
|
+
scopes.push({
|
|
14133
|
+
path: buildElementTreePath(element),
|
|
14134
|
+
selector: selectorOf(element),
|
|
14135
|
+
isGroup: containers.has(tag)
|
|
14136
|
+
});
|
|
14137
|
+
return;
|
|
14138
|
+
}
|
|
14139
|
+
if (hasGroupEffect(element)) {
|
|
14140
|
+
warnings.push({
|
|
14141
|
+
message: 'A compositing group contains native text or images; its graphics cannot be baked separately.',
|
|
14142
|
+
selector: selectorOf(element)
|
|
14143
|
+
});
|
|
14144
|
+
return;
|
|
14145
|
+
}
|
|
14146
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(Array.from(element.children)), _step; !(_step = _iterator()).done;){
|
|
14147
|
+
var child = _step.value;
|
|
14148
|
+
visit(child);
|
|
14149
|
+
}
|
|
14150
|
+
};
|
|
14151
|
+
visit(root);
|
|
14152
|
+
return {
|
|
14153
|
+
scopes: scopes,
|
|
14154
|
+
warnings: warnings
|
|
14155
|
+
};
|
|
14156
|
+
}
|
|
14157
|
+
function collectGroupEffectRules(root) {
|
|
14158
|
+
var result = [];
|
|
14159
|
+
if (typeof CSSStyleSheet !== 'function') {
|
|
14160
|
+
return result;
|
|
14161
|
+
}
|
|
14162
|
+
var visit = function visit1(rules) {
|
|
14163
|
+
var _loop = function() {
|
|
14164
|
+
var rule = _step.value;
|
|
14165
|
+
if (isStyleRule$1(rule)) {
|
|
14166
|
+
var affectsGroup = hasGraphicGroupEffect(function(name) {
|
|
14167
|
+
var value = rule.style.getPropertyValue(name).trim();
|
|
14168
|
+
return value === '' || value === 'initial' || value === 'unset' ? undefined : value;
|
|
14169
|
+
});
|
|
14170
|
+
if (affectsGroup) {
|
|
14171
|
+
result.push(rule);
|
|
14172
|
+
}
|
|
14173
|
+
} else if (hasNestedRules(rule)) {
|
|
14174
|
+
visit(rule.cssRules);
|
|
14175
|
+
}
|
|
14176
|
+
};
|
|
14177
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(Array.from(rules)), _step; !(_step = _iterator()).done;)_loop();
|
|
14178
|
+
};
|
|
14179
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(Array.from(root.querySelectorAll('style'))), _step; !(_step = _iterator()).done;){
|
|
14180
|
+
var style = _step.value;
|
|
14181
|
+
var _style_textContent;
|
|
14182
|
+
var sheet = new CSSStyleSheet();
|
|
14183
|
+
sheet.replaceSync((_style_textContent = style.textContent) != null ? _style_textContent : '');
|
|
14184
|
+
visit(sheet.cssRules);
|
|
14185
|
+
}
|
|
14186
|
+
return result;
|
|
14187
|
+
}
|
|
14188
|
+
/** Reject text/image dependencies and effects that cannot be rendered independently. */ function validateGraphicSnapshot(context) {
|
|
14189
|
+
var _loop = function() {
|
|
14190
|
+
var element = _step1.value;
|
|
14191
|
+
var computed = readStyle(element);
|
|
14192
|
+
var ancestor = element !== target && element.contains(target);
|
|
14193
|
+
var groupEffect = ancestor && hasGraphicGroupEffect(function(name) {
|
|
14194
|
+
return name === 'mask' ? computed.maskImage : computed.getPropertyValue(name);
|
|
14195
|
+
});
|
|
14196
|
+
if (ancestor && (groupEffect || computed.mixBlendMode !== 'normal')) {
|
|
14197
|
+
throw new Error('A mixed group effect cannot be applied independently to its graphics.');
|
|
14198
|
+
}
|
|
14199
|
+
if (target.contains(element) && target !== root && computed.mixBlendMode !== 'normal') {
|
|
14200
|
+
throw new Error('Blend modes that depend on an external backdrop cannot be baked independently.');
|
|
14201
|
+
}
|
|
14202
|
+
};
|
|
14203
|
+
var root = context.root, target = context.target, elements = context.elements, dependencies = context.dependencies, readStyle = context.readStyle;
|
|
14204
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(dependencies), _step; !(_step = _iterator()).done;){
|
|
14205
|
+
var element = _step.value;
|
|
14206
|
+
if ([
|
|
14207
|
+
'text',
|
|
14208
|
+
'image',
|
|
14209
|
+
'foreignobject'
|
|
14210
|
+
].includes(element.tagName.toLowerCase())) {
|
|
14211
|
+
throw new Error('Graphic dependencies contain native text or images; they must remain editable.');
|
|
14212
|
+
}
|
|
14213
|
+
}
|
|
14214
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(elements), _step1; !(_step1 = _iterator1()).done;)_loop();
|
|
14215
|
+
}
|
|
14216
|
+
function isStyleRule$1(rule) {
|
|
14217
|
+
return rule.type === 1;
|
|
14218
|
+
}
|
|
14219
|
+
function hasNestedRules(rule) {
|
|
14220
|
+
return 'cssRules' in rule;
|
|
14221
|
+
}
|
|
14222
|
+
function hasGraphicGroupEffect(readValue) {
|
|
14223
|
+
return groupEffects.some(function(name) {
|
|
14224
|
+
var value = readValue(name);
|
|
14225
|
+
return value != null && value !== 'none' && value !== 'normal' && value !== '1';
|
|
14226
|
+
});
|
|
14227
|
+
}
|
|
14228
|
+
|
|
14229
|
+
/** Mask and clipPath definitions do not produce visible layers. */ function collectNonRenderingDeclarationPaths(source) {
|
|
14230
|
+
var root = svg_js.SVG(source).node;
|
|
14231
|
+
var elements = Array.from(root.querySelectorAll('*')).filter(function(element) {
|
|
14232
|
+
var tag = element.tagName.toLowerCase();
|
|
14233
|
+
return tag === 'mask' || tag === 'clippath';
|
|
14234
|
+
});
|
|
14235
|
+
return new Set(elements.map(buildElementTreePath));
|
|
14236
|
+
}
|
|
14237
|
+
/** A stylesheet diagnostic is resolved only when every element it can affect was baked. */ function collectBakedStylesheetPaths(source, isBaked) {
|
|
14238
|
+
var resolved = new Set();
|
|
14239
|
+
if (typeof DOMParser === 'undefined' || typeof CSSStyleSheet !== 'function') {
|
|
14240
|
+
return resolved;
|
|
14241
|
+
}
|
|
14242
|
+
var root = new DOMParser().parseFromString(source, 'image/svg+xml').documentElement;
|
|
14243
|
+
var allUsesBaked = Array.from(root.querySelectorAll('use')).every(function(element) {
|
|
14244
|
+
return isBaked(buildElementTreePath(element));
|
|
14245
|
+
});
|
|
14246
|
+
var isHandled = function isHandled(element) {
|
|
14247
|
+
if (isBaked(buildElementTreePath(element))) {
|
|
14248
|
+
return true;
|
|
14249
|
+
}
|
|
14250
|
+
if (element.closest('defs, symbol, marker, pattern, clipPath, mask, filter') != null) {
|
|
14251
|
+
return allUsesBaked;
|
|
14252
|
+
}
|
|
14253
|
+
return false;
|
|
14254
|
+
};
|
|
14255
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(Array.from(root.querySelectorAll('style'))), _step; !(_step = _iterator()).done;){
|
|
14256
|
+
var style = _step.value;
|
|
14257
|
+
var _style_textContent;
|
|
14258
|
+
var sheet = new CSSStyleSheet();
|
|
14259
|
+
sheet.replaceSync((_style_textContent = style.textContent) != null ? _style_textContent : '');
|
|
14260
|
+
var rules = Array.from(sheet.cssRules);
|
|
14261
|
+
var handled = rules.every(function(rule) {
|
|
14262
|
+
if (!isStyleRule(rule)) {
|
|
14263
|
+
return false;
|
|
14264
|
+
}
|
|
14265
|
+
if (Array.from(rule.style).every(function(name) {
|
|
14266
|
+
return name === 'mix-blend-mode';
|
|
14267
|
+
})) {
|
|
14268
|
+
return true;
|
|
14269
|
+
}
|
|
14270
|
+
var matched = [].concat([
|
|
14271
|
+
root
|
|
14272
|
+
], Array.from(root.querySelectorAll('*'))).filter(function(element) {
|
|
14273
|
+
return element.matches(rule.selectorText);
|
|
14274
|
+
});
|
|
14275
|
+
return matched.every(isHandled);
|
|
14276
|
+
});
|
|
14277
|
+
if (handled) {
|
|
14278
|
+
resolved.add(buildElementTreePath(style));
|
|
14279
|
+
}
|
|
14280
|
+
}
|
|
14281
|
+
return resolved;
|
|
14282
|
+
}
|
|
14283
|
+
function isStyleRule(rule) {
|
|
14284
|
+
return rule.type === 1;
|
|
14285
|
+
}
|
|
14286
|
+
|
|
14287
|
+
/** Rasterize graphics and track the source layers and warnings they replace. */ function buildBakedLayers(source, size, options, rasterScale) {
|
|
14288
|
+
return _async_to_generator(function() {
|
|
14289
|
+
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;
|
|
14290
|
+
return _ts_generator(this, function(_state) {
|
|
14291
|
+
switch(_state.label){
|
|
14292
|
+
case 0:
|
|
14293
|
+
deferredOptions = _extends({}, options, {
|
|
14294
|
+
strict: false,
|
|
14295
|
+
onWarning: undefined
|
|
14296
|
+
});
|
|
14297
|
+
bakedPaths = [];
|
|
14298
|
+
baked = [];
|
|
14299
|
+
bakingWarnings = [];
|
|
14300
|
+
blending = normalizeLayerBlending(source);
|
|
14301
|
+
plan = planGraphicBaking(blending.source);
|
|
14302
|
+
for(_iterator = _create_for_of_iterator_helper_loose(blending.downgrades); !(_step = _iterator()).done;){
|
|
14303
|
+
downgrade = _step.value;
|
|
14304
|
+
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);
|
|
14305
|
+
}
|
|
14306
|
+
for(_iterator1 = _create_for_of_iterator_helper_loose(plan.warnings); !(_step1 = _iterator1()).done;){
|
|
14307
|
+
warning = _step1.value;
|
|
14308
|
+
collectLayerWarning(bakingWarnings, deferredOptions, SVG2IR_WARNING_CODES.LAYERS_UNSUPPORTED_FEATURE, warning.message, warning.selector);
|
|
14309
|
+
}
|
|
14310
|
+
_iterator2 = _create_for_of_iterator_helper_loose(plan.scopes);
|
|
14311
|
+
_state.label = 1;
|
|
14312
|
+
case 1:
|
|
14313
|
+
if (!!(_step2 = _iterator2()).done) return [
|
|
14314
|
+
3,
|
|
14315
|
+
6
|
|
14316
|
+
];
|
|
14317
|
+
scope = _step2.value;
|
|
14318
|
+
_state.label = 2;
|
|
14319
|
+
case 2:
|
|
14320
|
+
_state.trys.push([
|
|
14321
|
+
2,
|
|
14322
|
+
4,
|
|
14323
|
+
,
|
|
14324
|
+
5
|
|
14325
|
+
]);
|
|
14326
|
+
if (!canRasterizeSVG()) {
|
|
14327
|
+
throw new Error('Graphic baking requires a browser with SVG and Canvas support.');
|
|
14328
|
+
}
|
|
14329
|
+
return [
|
|
14330
|
+
4,
|
|
14331
|
+
rasterizeSVG(blending.source, scope.path, size, rasterScale, validateGraphicSnapshot)
|
|
14332
|
+
];
|
|
14333
|
+
case 3:
|
|
14334
|
+
image = _state.sent();
|
|
14335
|
+
bakedPaths.push(scope.path);
|
|
14336
|
+
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.';
|
|
14337
|
+
collectLayerWarning(bakingWarnings, deferredOptions, SVG2IR_WARNING_CODES.LAYERS_GRAPHIC_BAKED, message, scope.selector);
|
|
14338
|
+
if (image == null) {
|
|
14339
|
+
return [
|
|
14340
|
+
3,
|
|
14341
|
+
5
|
|
14342
|
+
];
|
|
14343
|
+
}
|
|
14344
|
+
_image_bbox = image.bbox, left = _image_bbox[0], top = _image_bbox[1], right = _image_bbox[2], bottom = _image_bbox[3];
|
|
14345
|
+
width = right - left;
|
|
14346
|
+
height = bottom - top;
|
|
14347
|
+
baked.push({
|
|
14348
|
+
path: scope.path,
|
|
14349
|
+
layer: {
|
|
14350
|
+
id: '',
|
|
14351
|
+
type: 'image',
|
|
14352
|
+
role: 'content',
|
|
14353
|
+
bbox: image.bbox,
|
|
14354
|
+
size: [
|
|
14355
|
+
width,
|
|
14356
|
+
height
|
|
14357
|
+
],
|
|
14358
|
+
rotation: [
|
|
14359
|
+
0,
|
|
14360
|
+
0,
|
|
14361
|
+
0
|
|
14362
|
+
],
|
|
14363
|
+
url: image.url,
|
|
14364
|
+
width: width,
|
|
14365
|
+
height: height
|
|
14366
|
+
}
|
|
14367
|
+
});
|
|
14368
|
+
return [
|
|
14369
|
+
3,
|
|
14370
|
+
5
|
|
14371
|
+
];
|
|
14372
|
+
case 4:
|
|
14373
|
+
error = _state.sent();
|
|
14374
|
+
reason = _instanceof(error, Error) ? error.message : String(error);
|
|
14375
|
+
collectLayerWarning(bakingWarnings, deferredOptions, SVG2IR_WARNING_CODES.LAYERS_UNSUPPORTED_FEATURE, "Graphic baking failed: " + reason, scope.selector);
|
|
14376
|
+
return [
|
|
14377
|
+
3,
|
|
14378
|
+
5
|
|
14379
|
+
];
|
|
14380
|
+
case 5:
|
|
14381
|
+
return [
|
|
14382
|
+
3,
|
|
14383
|
+
1
|
|
14384
|
+
];
|
|
14385
|
+
case 6:
|
|
14386
|
+
replacesSource = function replacesSource(path) {
|
|
14387
|
+
return path != null && bakedPaths.some(function(scope) {
|
|
14388
|
+
return scope === '' || path === scope || path.startsWith("" + scope + "/");
|
|
14389
|
+
});
|
|
14390
|
+
};
|
|
14391
|
+
handledStyles = collectBakedStylesheetPaths(blending.source, replacesSource);
|
|
14392
|
+
declarations = collectNonRenderingDeclarationPaths(source);
|
|
14393
|
+
return [
|
|
14394
|
+
2,
|
|
14395
|
+
{
|
|
14396
|
+
layers: baked,
|
|
14397
|
+
warnings: bakingWarnings,
|
|
14398
|
+
replacesSource: replacesSource,
|
|
14399
|
+
resolvesWarning: function resolvesWarning(warning, path) {
|
|
14400
|
+
return replacesSource(path) || warning.code === SVG2IR_WARNING_CODES.ELEMENT_DROPPED && path != null && (handledStyles.has(path) || declarations.has(path));
|
|
14401
|
+
}
|
|
14402
|
+
}
|
|
14403
|
+
];
|
|
14404
|
+
}
|
|
14405
|
+
});
|
|
14406
|
+
})();
|
|
14407
|
+
}
|
|
13260
14408
|
|
|
13261
14409
|
function encodeBase64(data) {
|
|
13262
14410
|
var chunks = [];
|
|
@@ -13445,30 +14593,115 @@ function fetchImageResource(url) {
|
|
|
13445
14593
|
}).apply(this, arguments);
|
|
13446
14594
|
}
|
|
13447
14595
|
|
|
13448
|
-
|
|
13449
|
-
|
|
13450
|
-
|
|
14596
|
+
var animatedTags = new Set([
|
|
14597
|
+
'animate',
|
|
14598
|
+
'animatetransform',
|
|
14599
|
+
'animatemotion',
|
|
14600
|
+
'set'
|
|
14601
|
+
]);
|
|
14602
|
+
/** Static layers cannot sample animation; drop SMIL nodes so elements keep their authored state. */ function stripLayerAnimation(source) {
|
|
14603
|
+
var svg = svg_js.SVG(source);
|
|
14604
|
+
if ((svg == null ? void 0 : svg.node) == null) {
|
|
14605
|
+
return {
|
|
14606
|
+
source: source,
|
|
14607
|
+
removed: 0
|
|
14608
|
+
};
|
|
14609
|
+
}
|
|
14610
|
+
var elements = Array.from(svg.node.querySelectorAll('*')).filter(function(element) {
|
|
14611
|
+
return animatedTags.has(element.tagName.toLowerCase());
|
|
14612
|
+
});
|
|
14613
|
+
if (elements.length === 0) {
|
|
14614
|
+
return {
|
|
14615
|
+
source: source,
|
|
14616
|
+
removed: 0
|
|
14617
|
+
};
|
|
14618
|
+
}
|
|
14619
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(elements), _step; !(_step = _iterator()).done;){
|
|
14620
|
+
var element = _step.value;
|
|
14621
|
+
element.remove();
|
|
14622
|
+
}
|
|
14623
|
+
return {
|
|
14624
|
+
source: svg.svg(),
|
|
14625
|
+
removed: elements.length
|
|
14626
|
+
};
|
|
14627
|
+
}
|
|
14628
|
+
|
|
14629
|
+
function convertSVGToLayers() {
|
|
14630
|
+
return _async_to_generator(function(source, options, preservedData) {
|
|
14631
|
+
var loadImage, _options_rasterScale, rasterScale, conversionOptions, layerSources, warningSources, collected, stripped, staticSource, parsed, context, composition, baking, assembled, _tmp, _tmp1;
|
|
13451
14632
|
return _ts_generator(this, function(_state) {
|
|
13452
14633
|
switch(_state.label){
|
|
13453
14634
|
case 0:
|
|
13454
|
-
|
|
13455
|
-
|
|
13456
|
-
|
|
13457
|
-
|
|
13458
|
-
|
|
14635
|
+
if (options === void 0) options = {};
|
|
14636
|
+
loadImage = options.loadImage, _options_rasterScale = options.rasterScale, rasterScale = _options_rasterScale === void 0 ? 2 : _options_rasterScale, conversionOptions = _object_without_properties_loose(options, [
|
|
14637
|
+
"loadImage",
|
|
14638
|
+
"rasterScale"
|
|
14639
|
+
]);
|
|
14640
|
+
layerSources = new Map();
|
|
14641
|
+
warningSources = new Map();
|
|
14642
|
+
collected = {
|
|
14643
|
+
textDataByLayerId: new Map(),
|
|
14644
|
+
paintAnimationsByLayerId: new Map(),
|
|
14645
|
+
shapeAnimationsByLayerId: new Map()
|
|
14646
|
+
};
|
|
14647
|
+
stripped = stripLayerAnimation(source);
|
|
14648
|
+
staticSource = stripped.source;
|
|
14649
|
+
// Preserve original layer IDs while gathering the source identities required by baking and assembly.
|
|
14650
|
+
parsed = parseSVGToIRWithPreservedData(staticSource, _extends({}, conversionOptions, {
|
|
14651
|
+
strict: false,
|
|
14652
|
+
onWarning: undefined
|
|
14653
|
+
}), _extends({}, collected, {
|
|
14654
|
+
layerSourceCollector: layerSources,
|
|
14655
|
+
warningSourceCollector: warningSources
|
|
14656
|
+
}));
|
|
14657
|
+
context = {
|
|
14658
|
+
source: staticSource,
|
|
14659
|
+
ir: parsed.ir,
|
|
14660
|
+
warnings: parsed.warnings,
|
|
14661
|
+
preservedData: preservedData != null ? preservedData : collected,
|
|
14662
|
+
layerSources: layerSources,
|
|
14663
|
+
warningSources: warningSources
|
|
13459
14664
|
};
|
|
14665
|
+
if (stripped.removed > 0) {
|
|
14666
|
+
collectLayerWarning(context.warnings, _extends({}, conversionOptions, {
|
|
14667
|
+
strict: false,
|
|
14668
|
+
onWarning: undefined
|
|
14669
|
+
}), SVG2IR_WARNING_CODES.LAYERS_ANIMATION_STRIPPED, "" + stripped.removed + " animated element(s) were removed; static layers output does not sample animation.");
|
|
14670
|
+
}
|
|
14671
|
+
composition = context.ir.compositions[0];
|
|
13460
14672
|
return [
|
|
13461
14673
|
4,
|
|
13462
|
-
|
|
14674
|
+
buildBakedLayers(context.source, [
|
|
14675
|
+
composition.width,
|
|
14676
|
+
composition.height
|
|
14677
|
+
], conversionOptions, rasterScale)
|
|
13463
14678
|
];
|
|
13464
14679
|
case 1:
|
|
14680
|
+
baking = _state.sent();
|
|
14681
|
+
assembled = assembleSVGLayers({
|
|
14682
|
+
context: context,
|
|
14683
|
+
options: conversionOptions,
|
|
14684
|
+
baking: baking
|
|
14685
|
+
});
|
|
14686
|
+
_tmp = [
|
|
14687
|
+
{},
|
|
14688
|
+
assembled
|
|
14689
|
+
];
|
|
14690
|
+
_tmp1 = {};
|
|
14691
|
+
return [
|
|
14692
|
+
4,
|
|
14693
|
+
inlineImageResources(assembled.data, loadImage)
|
|
14694
|
+
];
|
|
14695
|
+
case 2:
|
|
13465
14696
|
return [
|
|
13466
14697
|
2,
|
|
13467
|
-
(
|
|
14698
|
+
_extends.apply(void 0, _tmp.concat([
|
|
14699
|
+
(_tmp1.data = _state.sent(), _tmp1)
|
|
14700
|
+
]))
|
|
13468
14701
|
];
|
|
13469
14702
|
}
|
|
13470
14703
|
});
|
|
13471
|
-
})();
|
|
14704
|
+
}).apply(this, arguments);
|
|
13472
14705
|
}
|
|
13473
14706
|
|
|
13474
14707
|
/**
|
|
@@ -13493,7 +14726,8 @@ function convertSVGToLayers(source, options, loadImage, preservedData) {
|
|
|
13493
14726
|
JSONSceneVersion["3_4"] = "3.4";
|
|
13494
14727
|
JSONSceneVersion["3_5"] = "3.5";
|
|
13495
14728
|
JSONSceneVersion["3_6"] = "3.6";
|
|
13496
|
-
JSONSceneVersion["
|
|
14729
|
+
JSONSceneVersion["3_7"] = "3.7";
|
|
14730
|
+
JSONSceneVersion["LATEST"] = "3.7";
|
|
13497
14731
|
})(JSONSceneVersion || (JSONSceneVersion = {}));
|
|
13498
14732
|
|
|
13499
14733
|
/*********************************************/ /* 元素属性参数类型 */ /*********************************************/ /**
|
|
@@ -13808,10 +15042,12 @@ var CameraClipMode;
|
|
|
13808
15042
|
* 直线
|
|
13809
15043
|
*/ ValueType[ValueType["LINE"] = 5] = "LINE";
|
|
13810
15044
|
/**
|
|
13811
|
-
*
|
|
15045
|
+
* 曲线(Hermite 曲线)
|
|
15046
|
+
* @deprecated 使用 BEZIER_CURVE 替代,此类型仅用于旧数据迁移兼容
|
|
13812
15047
|
*/ ValueType[ValueType["CURVE"] = 6] = "CURVE";
|
|
13813
15048
|
/**
|
|
13814
15049
|
* 贝塞尔路径
|
|
15050
|
+
* @deprecated 使用 BEZIER_CURVE_PATH 替代,此类型仅用于旧数据迁移兼容
|
|
13815
15051
|
*/ ValueType[ValueType["BEZIER_PATH"] = 7] = "BEZIER_PATH";
|
|
13816
15052
|
/**
|
|
13817
15053
|
* 颜色
|
|
@@ -14248,6 +15484,7 @@ var DataType;
|
|
|
14248
15484
|
DataType["AnimationGraphAsset"] = "AnimationGraphAsset";
|
|
14249
15485
|
DataType["CompositionComponent"] = "CompositionComponent";
|
|
14250
15486
|
DataType["FFDComponent"] = "FFDComponent";
|
|
15487
|
+
DataType["FrameComponent"] = "FrameComponent";
|
|
14251
15488
|
DataType["Animator"] = "Animator";
|
|
14252
15489
|
// Non-EffectObject
|
|
14253
15490
|
DataType["TimelineClip"] = "TimelineClip";
|
|
@@ -15872,7 +17109,8 @@ function asRecordArray(value) {
|
|
|
15872
17109
|
}
|
|
15873
17110
|
|
|
15874
17111
|
/** 从已解析的 IR 和 SVG 保留数据生成 GE 场景。 */ function assembleSVGGE(parsed, options, preservedData) {
|
|
15875
|
-
var ir = parsed.ir
|
|
17112
|
+
var ir = parsed.ir;
|
|
17113
|
+
var warnings = [].concat(parsed.warnings);
|
|
15876
17114
|
var fonts = (options != null ? options : {}).fonts;
|
|
15877
17115
|
var irForGE = expandIRHoldTransitions(ir);
|
|
15878
17116
|
if ((preservedData == null ? void 0 : preservedData.shapeAnimationsByLayerId) != null) {
|
|
@@ -15980,34 +17218,17 @@ function cleanFontName(raw) {
|
|
|
15980
17218
|
return value;
|
|
15981
17219
|
}
|
|
15982
17220
|
|
|
15983
|
-
|
|
17221
|
+
function convertSVGToGE(sourceOrContext, options, preservedData) {
|
|
15984
17222
|
var _ref = options != null ? options : {}; _ref.fonts; var parserOptions = _object_without_properties_loose(_ref, [
|
|
15985
17223
|
"fonts"
|
|
15986
17224
|
]);
|
|
15987
|
-
var
|
|
15988
|
-
return assembleSVGGE(
|
|
15989
|
-
}
|
|
15990
|
-
|
|
15991
|
-
function convertSVG(source, options, preservedData) {
|
|
15992
|
-
var _ref = options != null ? options : {}, _ref_outputFormat = _ref.outputFormat, outputFormat = _ref_outputFormat === void 0 ? 'ge' : _ref_outputFormat;
|
|
15993
|
-
if (outputFormat !== 'ge' && outputFormat !== 'layers') {
|
|
15994
|
-
throw new TypeError('[svg2ir] outputFormat must be ge or layers.');
|
|
15995
|
-
}
|
|
15996
|
-
if ((options == null ? void 0 : options.outputFormat) === 'layers') {
|
|
15997
|
-
options.outputFormat; var loadImage = options.loadImage, parserOptions = _object_without_properties_loose(options, [
|
|
15998
|
-
"outputFormat",
|
|
15999
|
-
"loadImage"
|
|
16000
|
-
]);
|
|
16001
|
-
return convertSVGToLayers(source, parserOptions, loadImage, preservedData);
|
|
16002
|
-
}
|
|
16003
|
-
var _ref1 = options != null ? options : {}; _ref1.outputFormat; var geOptions = _object_without_properties_loose(_ref1, [
|
|
16004
|
-
"outputFormat"
|
|
16005
|
-
]);
|
|
16006
|
-
return convertSVGToGE(source, geOptions, preservedData);
|
|
17225
|
+
var context = typeof sourceOrContext === 'string' ? parseSVGToIRWithPreservedData(sourceOrContext, parserOptions) : sourceOrContext;
|
|
17226
|
+
return assembleSVGGE(context, options, preservedData != null ? preservedData : typeof sourceOrContext === 'string' ? undefined : sourceOrContext.preservedData);
|
|
16007
17227
|
}
|
|
16008
17228
|
|
|
16009
|
-
exports.convertSVG = convertSVG;
|
|
16010
17229
|
exports.convertSVGToGE = convertSVGToGE;
|
|
16011
17230
|
exports.convertSVGToIR = convertSVGToIR;
|
|
17231
|
+
exports.convertSVGToLayers = convertSVGToLayers;
|
|
17232
|
+
exports.inferNumericWeightFromFamily = inferNumericWeightFromFamily;
|
|
16012
17233
|
exports.splitSVG = splitSVG;
|
|
16013
17234
|
//# sourceMappingURL=index.js.map
|