diff --git a/plugins/mergePaths.js b/plugins/mergePaths.js index 2b22e6d5e..0c6691a8f 100644 --- a/plugins/mergePaths.js +++ b/plugins/mergePaths.js @@ -1,5 +1,8 @@ 'use strict'; +const { computeStyle } = require('../lib/style.js'); +const { path2js, js2path, intersects } = require('./_path.js'); + exports.type = 'perItem'; exports.active = true; @@ -7,17 +10,13 @@ exports.active = true; exports.description = 'merges multiple paths in one if possible'; exports.params = { - collapseRepeated: true, - force: false, - leadingZero: true, - negativeExtraSpace: true, - noSpaceAfterFlags: false, // a20 60 45 0 1 30 20 → a20 60 45 0130 20 + collapseRepeated: true, + force: false, + leadingZero: true, + negativeExtraSpace: true, + noSpaceAfterFlags: false, // a20 60 45 0 1 30 20 → a20 60 45 0130 20 }; -var path2js = require('./_path.js').path2js, - js2path = require('./_path.js').js2path, - intersects = require('./_path.js').intersects; - /** * Merge multiple Paths into one. * @@ -26,48 +25,56 @@ var path2js = require('./_path.js').path2js, * * @author Kir Belevich, Lev Solntsev */ -exports.fn = function(item, params) { - - if (!item.isElem() || item.isEmpty()) return; - - var prevContentItem = null, - prevContentItemKeys = null; - - item.content = item.content.filter(function(contentItem) { - - if (prevContentItem && - prevContentItem.isElem('path') && - prevContentItem.isEmpty() && - prevContentItem.hasAttr('d') && - contentItem.isElem('path') && - contentItem.isEmpty() && - contentItem.hasAttr('d') - ) { - - if (!prevContentItemKeys) { - prevContentItemKeys = Object.keys(prevContentItem.attrs); - } - - var contentItemAttrs = Object.keys(contentItem.attrs), - equalData = prevContentItemKeys.length == contentItemAttrs.length && - contentItemAttrs.every(function(key) { - return key == 'd' || - prevContentItem.hasAttr(key) && - prevContentItem.attr(key).value == contentItem.attr(key).value; - }), - prevPathJS = path2js(prevContentItem), - curPathJS = path2js(contentItem); - - if (equalData && (params.force || !intersects(prevPathJS, curPathJS))) { - js2path(prevContentItem, prevPathJS.concat(curPathJS), params); - return false; - } - } - - prevContentItem = contentItem; - prevContentItemKeys = null; +exports.fn = function (item, params) { + if (!item.isElem() || item.isEmpty()) return; + + var prevContentItem = null, + prevContentItemKeys = null; + + item.content = item.content.filter(function (contentItem) { + if ( + prevContentItem && + prevContentItem.isElem('path') && + prevContentItem.isEmpty() && + prevContentItem.hasAttr('d') && + contentItem.isElem('path') && + contentItem.isEmpty() && + contentItem.hasAttr('d') + ) { + const computedStyle = computeStyle(contentItem); + // keep path to not break markers + if ( + computedStyle['marker-start'] || + computedStyle['marker-mid'] || + computedStyle['marker-end'] + ) { return true; - - }); - + } + if (!prevContentItemKeys) { + prevContentItemKeys = Object.keys(prevContentItem.attrs); + } + + var contentItemAttrs = Object.keys(contentItem.attrs), + equalData = + prevContentItemKeys.length == contentItemAttrs.length && + contentItemAttrs.every(function (key) { + return ( + key == 'd' || + (prevContentItem.hasAttr(key) && + prevContentItem.attr(key).value == contentItem.attr(key).value) + ); + }), + prevPathJS = path2js(prevContentItem), + curPathJS = path2js(contentItem); + + if (equalData && (params.force || !intersects(prevPathJS, curPathJS))) { + js2path(prevContentItem, prevPathJS.concat(curPathJS), params); + return false; + } + } + + prevContentItem = contentItem; + prevContentItemKeys = null; + return true; + }); }; diff --git a/test/plugins/mergePaths.07.svg b/test/plugins/mergePaths.07.svg new file mode 100644 index 000000000..b53a27a29 --- /dev/null +++ b/test/plugins/mergePaths.07.svg @@ -0,0 +1,35 @@ +Merged paths loose their ends and markers are rendered incorrectly + +=== + + + + + + + + + + + + + + +@@@ + + + + + + + + + + + + +