SvgImport: Implement options.insert to control insertion.

Also use settings.insertItems for faster import. Closes #763
This commit is contained in:
Jürg Lehni 2016-02-14 22:51:50 +01:00
parent 8d5c922c50
commit dba4eb371d
4 changed files with 40 additions and 21 deletions

View file

@ -47,7 +47,7 @@ var PathItem = Item.extend(/** @lends PathItem# */{
// First split the path data into parts of command-coordinates pairs
// Commands are any of these characters: mzlhvcsqta
var parts = data.match(/[mlhvcsqtaz][^mlhvcsqtaz]*/ig),
var parts = data && data.match(/[mlhvcsqtaz][^mlhvcsqtaz]*/ig),
coords,
relative = false,
previous,

View file

@ -141,7 +141,8 @@ new function() {
param = { pathData: data };
// If there are multiple moveTo commands or a closePath command followed
// by other commands, we have a CompoundPath:
return (data.match(/m/gi) || []).length > 1 || /z\S+/i.test(data)
// TODO: PathItem.create()?
return (data && data.match(/m/gi) || []).length > 1 || /z\b/i.test(data)
? new CompoundPath(param)
: new Path(param);
}
@ -184,7 +185,7 @@ new function() {
destination = getPoint(node, 'x2', 'y2', false, scaleToBounds);
}
var color = applyAttributes(
new Color(gradient, origin, destination, highlight), node);
new Color(gradient, origin, destination, highlight), node);
// TODO: Consider adding support for _scaleToBounds to Color instead?
color._scaleToBounds = scaleToBounds;
// We don't return the gradient, since we only need a reference to it in
@ -588,12 +589,16 @@ new function() {
}
// Have items imported from SVG not bake in all transformations to their
// content and children, as this is how SVG works too, but preserve the
// current setting so we can restore it after.
// current setting so we can restore it after. Also don't insert them
// into the scene graph automatically, as we do so by hand.
var settings = paper.settings,
applyMatrix = settings.applyMatrix;
applyMatrix = settings.applyMatrix,
insertItems = settings.insertItems;
settings.applyMatrix = false;
settings.insertItems = false;
var importer = importers[type],
item = importer && importer(node, type, options, isRoot) || null;
settings.insertItems = insertItems;
settings.applyMatrix = applyMatrix;
if (item) {
// Do not apply attributes if this is a #document node.
@ -709,7 +714,10 @@ new function() {
// NOTE: Documentation is in Item#importSVG()
Item.inject({
importSVG: function(node, options) {
return this.addChild(importSVG(node, options));
var res = importSVG(node, options);
if (!options || options.insert !== false)
this.addChild(res);
return res;
}
});
@ -717,7 +725,12 @@ new function() {
Project.inject({
importSVG: function(node, options) {
this.activate();
return importSVG(node, options);
var res = importSVG(node, options);
if (!options || options.insert !== false) {
// TODO: Implement support for Layer parsing / insertion.
this.getActiveLayer().addChild(res);
}
return res;
}
});
};

View file

@ -462,19 +462,13 @@ var compareBoolean = function(actual, expected, message, options) {
};
var createSVG = function(str, attrs) {
if (attrs) {
// Similar to SvgElement.create():
var node = document.createElementNS('http://www.w3.org/2000/svg', str);
for (var key in attrs)
node.setAttribute(key, attrs[key]);
// Paper.js paths do not have a fill by default, SVG does.
node.setAttribute('fill', 'none');
return node;
} else {
return new window.DOMParser().parseFromString(
'<svg xmlns="http://www.w3.org/2000/svg">' + str + '</svg>',
'text/xml');
}
// Similar to SvgElement.create():
var node = document.createElementNS('http://www.w3.org/2000/svg', str);
for (var key in attrs)
node.setAttribute(key, attrs[key]);
// Paper.js paths do not have a fill by default, SVG does.
node.setAttribute('fill', 'none');
return node;
};
var compareSVG = function(done, actual, expected, message, options) {

View file

@ -115,11 +115,23 @@ test('Import SVG polyline', function() {
});
test('Import complex CompoundPath and clone', function() {
var svg = createSVG('<path fill="red" d="M4,14h20v-2H4V14z M15,26h7v-2h-7V26z M15,22h9v-2h-9V22z M15,18h9v-2h-9V18z M4,26h9V16H4V26z M28,10V6H0v22c0,0,0,4,4,4 h25c0,0,3-0.062,3-4V10H28z M4,30c-2,0-2-2-2-2V8h24v20c0,0.921,0.284,1.558,0.676,2H4z"/>');
var svg = '<svg xmlns="http://www.w3.org/2000/svg"><path fill="red" d="M4,14h20v-2H4V14z M15,26h7v-2h-7V26z M15,22h9v-2h-9V22z M15,18h9v-2h-9V18z M4,26h9V16H4V26z M28,10V6H0v22c0,0,0,4,4,4 h25c0,0,3-0.062,3-4V10H28z M4,30c-2,0-2-2-2-2V8h24v20c0,0.921,0.284,1.558,0.676,2H4z"/></svg>';
var item = paper.project.importSVG(svg);
equals(item.clone(), item, null, { cloned: true });
});
test('Import SVG without insertion', function() {
var svg = createSVG('path', { d: '' });
var imported = paper.project.importSVG(svg, { insert: true });
equals(function() {
return imported.parent === project.activeLayer;
}, true);
var imported = paper.project.importSVG(svg, { insert: false });
equals(function() {
return imported.parent === null;
}, true);
});
function importSVG(assert, url, message, options) {
var done = assert.async();
project.importSVG(url, {