diff --git a/src/item/Item.js b/src/item/Item.js
index 95dfd543..3858f3e8 100644
--- a/src/item/Item.js
+++ b/src/item/Item.js
@@ -1633,11 +1633,15 @@ var Item = Base.extend(Callback, /** @lends Item# */{
};
}, /** @lends Item# */{
/**
- * {@grouptitle Importing To / Exporting From JSON & SVG}
+ * {@grouptitle Importing / Exporting JSON and SVG}
*
* Exports (serializes) the item with its content and child items to a JSON
* data string.
*
+ * The options object offers control over some aspects of the SVG export:
+ * options.precision: {@code Number} – the amount of fractional
+ * digits in numbers used in JSON data.
+ *
* @name Item#exportJSON
* @function
* @param {Object} [options={ precision: 5 }] the serialization options
@@ -1646,8 +1650,9 @@ var Item = Base.extend(Callback, /** @lends Item# */{
/**
* Imports (deserializes) the stored JSON data into this item's
- * {@link Item#children} list. Note that the item is not cleared first.
- * You can call {@link Item#removeChildren()} to do so.
+ * {@link Item#children} list.
+ * Note that the item is not cleared first. You can call
+ * {@link Item#removeChildren()} to do so.
*
* @param {String} json the JSON data to import from.
*/
@@ -1658,20 +1663,36 @@ var Item = Base.extend(Callback, /** @lends Item# */{
/**
* Exports the item with its content and child items as an SVG DOM.
*
+ * The options object offers control over some aspects of the SVG export:
+ * options.asString: {@code Boolean} – wether a SVG node or a String
+ * is to be returned.
+ * options.precision: {@code Number} – the amount of fractional
+ * digits in numbers used in SVG data.
+ * options.matchShapes: {@code Boolean} – wether imported path
+ * items should tried to be converted to shape items, if their geometries
+ * match.
+ *
* @name Item#exportSVG
* @function
- * @param {Object} [options={ asString: false, precision: 5 }] the export
- * options.
+ * @param {Object} [options={ asString: false, precision: 5,
+ * matchShapes: false }] the export options.
* @return {SVGSVGElement} the item converted to an SVG node
*/
/**
* Converts the provided SVG content into Paper.js items and adds them to
* the this item's children list.
+ * Note that the item is not cleared first. You can call
+ * {@link Item#removeChildren()} to do so.
+ *
+ * The options object offers control over some aspects of the SVG import:
+ * options.expandShapes: {@code Boolean} – wether imported shape
+ * items should be expanded to path items.
*
* @name Item#importSVG
* @function
* @param {SVGSVGElement|String} svg the SVG content to import
+ * @param {Object} [options={ expandShapes: false }] the import options
* @return {Item} the imported Paper.js parent item
*/
diff --git a/src/project/Project.js b/src/project/Project.js
index f3bd6d09..e2741a4d 100644
--- a/src/project/Project.js
+++ b/src/project/Project.js
@@ -292,11 +292,15 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{
};
}, /** @lends Project# */{
/**
- * {@grouptitle Importing To / Exporting From JSON & SVG}
+ * {@grouptitle Importing / Exporting JSON and SVG}
*
* Exports (serializes) the project with all its layers and child items to
* a JSON data string.
*
+ * The options object offers control over some aspects of the SVG export:
+ * options.precision: {@code Number} – the amount of fractional
+ * digits in numbers used in JSON data.
+ *
* @name Project#exportJSON
* @function
* @param {Object} [options={ precision: 5 }] the serialization options
@@ -304,9 +308,9 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{
*/
/**
- * Imports (deserializes) the stored JSON data into the project. Note that
- * the project is not cleared first. You can call {@link Project#clear()} to
- * do so.
+ * Imports (deserializes) the stored JSON data into the project.
+ * Note that the project is not cleared first. You can call
+ * {@link Project#clear()} to do so.
*
* @param {String} json the JSON data to import from.
*/
@@ -319,20 +323,36 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{
* Exports the project with all its layers and child items as an SVG DOM,
* all contained in one top level SVG group node.
*
+ * The options object offers control over some aspects of the SVG export:
+ * options.asString: {@code Boolean} – wether a SVG node or a String
+ * is to be returned.
+ * options.precision: {@code Number} – the amount of fractional
+ * digits in numbers used in SVG data.
+ * options.matchShapes: {@code Boolean} – wether imported path
+ * items should tried to be converted to shape items, if their geometries
+ * match.
+ *
* @name Project#exportSVG
* @function
- * @param {Object} [options={ asString: false, precision: 5 }] the export
- * options.
+ * @param {Object} [options={ asString: false, precision: 5,
+ * matchShapes: false }] the export options.
* @return {SVGSVGElement} the project converted to an SVG node
*/
/**
* Converts the provided SVG content into Paper.js items and adds them to
* the active layer of this project.
+ * Note that the project is not cleared first. You can call
+ * {@link Project#clear()} to do so.
+ *
+ * The options object offers control over some aspects of the SVG import:
+ * options.expandShapes: {@code Boolean} – wether imported shape
+ * items should be expanded to path items.
*
* @name Project#importSVG
* @function
* @param {SVGSVGElement|String} svg the SVG content to import
+ * @param {Object} [options={ expandShapes: false }] the import options
* @return {Item} the imported Paper.js parent item
*/
diff --git a/src/svg/SVGExport.js b/src/svg/SVGExport.js
index 52affd13..11ccc42a 100644
--- a/src/svg/SVGExport.js
+++ b/src/svg/SVGExport.js
@@ -15,6 +15,7 @@
* Paper.js DOM to a SVG DOM.
*/
new function() {
+ // TODO: Consider moving formatter into options object, and pass it along.
var formatter;
function setAttributes(node, attrs) {
@@ -76,13 +77,13 @@ new function() {
return attrs;
}
- function exportGroup(item) {
+ function exportGroup(item, options) {
var attrs = getTransform(item),
children = item._children;
var node = createElement('g', attrs);
for (var i = 0, l = children.length; i < l; i++) {
var child = children[i];
- var childNode = exportSVG(child);
+ var childNode = exportSVG(child, options);
if (childNode) {
if (child.isClipMask()) {
var clip = createElement('clipPath');
@@ -111,7 +112,12 @@ new function() {
return createElement('image', attrs);
}
- function exportPath(item) {
+ function exportPath(item, options) {
+ if (options.matchShapes) {
+ var shape = item.toShape(false);
+ if (shape)
+ return exportShape(shape, options);
+ }
var segments = item._segments,
type,
attrs;
@@ -180,7 +186,7 @@ new function() {
return createElement('path', attrs);
}
- function exportPlacedSymbol(item) {
+ function exportPlacedSymbol(item, options) {
var attrs = getTransform(item, true),
symbol = item.getSymbol(),
symbolNode = getDefinition(symbol, 'symbol'),
@@ -190,7 +196,7 @@ new function() {
symbolNode = createElement('symbol', {
viewBox: formatter.rectangle(bounds)
});
- symbolNode.appendChild(exportSVG(definition));
+ symbolNode.appendChild(exportSVG(definition, options));
setDefinition(symbol, symbolNode, 'symbol');
}
attrs.href = '#' + symbolNode.id;
@@ -369,9 +375,9 @@ new function() {
: svg;
}
- function exportSVG(item) {
+ function exportSVG(item, options) {
var exporter = exporters[item._type],
- node = exporter && exporter(item, item._type);
+ node = exporter && exporter(item, options);
if (node && item._data)
node.setAttribute('data-paper-data', JSON.stringify(item._data));
return node && applyStyle(item, node);
@@ -387,7 +393,7 @@ new function() {
Item.inject({
exportSVG: function(options) {
options = setOptions(options);
- return exportDefinitions(exportSVG(this), options);
+ return exportDefinitions(exportSVG(this, options), options);
}
});
@@ -406,7 +412,7 @@ new function() {
'xmlns:xlink': 'http://www.w3.org/1999/xlink'
});
for (var i = 0, l = layers.length; i < l; i++)
- node.appendChild(exportSVG(layers[i]));
+ node.appendChild(exportSVG(layers[i], options));
return exportDefinitions(node, options);
}
});