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