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 // First split the path data into parts of command-coordinates pairs
// Commands are any of these characters: mzlhvcsqta // Commands are any of these characters: mzlhvcsqta
var parts = data.match(/[mlhvcsqtaz][^mlhvcsqtaz]*/ig), var parts = data && data.match(/[mlhvcsqtaz][^mlhvcsqtaz]*/ig),
coords, coords,
relative = false, relative = false,
previous, previous,

View file

@ -141,7 +141,8 @@ new function() {
param = { pathData: data }; param = { pathData: data };
// If there are multiple moveTo commands or a closePath command followed // If there are multiple moveTo commands or a closePath command followed
// by other commands, we have a CompoundPath: // 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 CompoundPath(param)
: new Path(param); : new Path(param);
} }
@ -184,7 +185,7 @@ new function() {
destination = getPoint(node, 'x2', 'y2', false, scaleToBounds); destination = getPoint(node, 'x2', 'y2', false, scaleToBounds);
} }
var color = applyAttributes( 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? // TODO: Consider adding support for _scaleToBounds to Color instead?
color._scaleToBounds = scaleToBounds; color._scaleToBounds = scaleToBounds;
// We don't return the gradient, since we only need a reference to it in // 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 // 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 // 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, var settings = paper.settings,
applyMatrix = settings.applyMatrix; applyMatrix = settings.applyMatrix,
insertItems = settings.insertItems;
settings.applyMatrix = false; settings.applyMatrix = false;
settings.insertItems = false;
var importer = importers[type], var importer = importers[type],
item = importer && importer(node, type, options, isRoot) || null; item = importer && importer(node, type, options, isRoot) || null;
settings.insertItems = insertItems;
settings.applyMatrix = applyMatrix; settings.applyMatrix = applyMatrix;
if (item) { if (item) {
// Do not apply attributes if this is a #document node. // Do not apply attributes if this is a #document node.
@ -709,7 +714,10 @@ new function() {
// NOTE: Documentation is in Item#importSVG() // NOTE: Documentation is in Item#importSVG()
Item.inject({ Item.inject({
importSVG: function(node, options) { 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({ Project.inject({
importSVG: function(node, options) { importSVG: function(node, options) {
this.activate(); 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) { var createSVG = function(str, attrs) {
if (attrs) { // Similar to SvgElement.create():
// Similar to SvgElement.create(): var node = document.createElementNS('http://www.w3.org/2000/svg', str);
var node = document.createElementNS('http://www.w3.org/2000/svg', str); for (var key in attrs)
for (var key in attrs) node.setAttribute(key, attrs[key]);
node.setAttribute(key, attrs[key]); // Paper.js paths do not have a fill by default, SVG does.
// Paper.js paths do not have a fill by default, SVG does. node.setAttribute('fill', 'none');
node.setAttribute('fill', 'none'); return node;
return node;
} else {
return new window.DOMParser().parseFromString(
'<svg xmlns="http://www.w3.org/2000/svg">' + str + '</svg>',
'text/xml');
}
}; };
var compareSVG = function(done, actual, expected, message, options) { 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() { 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); var item = paper.project.importSVG(svg);
equals(item.clone(), item, null, { cloned: true }); 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) { function importSVG(assert, url, message, options) {
var done = assert.async(); var done = assert.async();
project.importSVG(url, { project.importSVG(url, {