From acfe6cddeb2d548048972bff6d9f355e2c1383af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Thu, 14 Jul 2016 10:49:12 +0200 Subject: [PATCH] Boolean: Improve handling of open paths. Relates to #1089 --- src/path/PathItem.Boolean.js | 22 +++++++++++++--------- src/path/PathItem.js | 2 +- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/path/PathItem.Boolean.js b/src/path/PathItem.Boolean.js index 93e292be..ae0bc239 100644 --- a/src/path/PathItem.Boolean.js +++ b/src/path/PathItem.Boolean.js @@ -47,10 +47,12 @@ PathItem.inject(new function() { * remove empty curves, #resolveCrossings() to resolve self-intersection * make sure all paths have correct winding direction. */ - function preparePath(path, resolve) { + function preparePath(path, closed) { var res = path.clone(false).reduce({ simplify: true }) .transform(null, true, true); - return resolve ? res.resolveCrossings() : res; + if (closed) + res.setClosed(true); + return closed ? res.resolveCrossings() : res; } function createResult(ctor, paths, reduce, path1, path2) { @@ -74,8 +76,10 @@ PathItem.inject(new function() { // Add a simple boolean property to check for a given operation, // e.g. `if (operator.unite)` operator[operation] = true; - // If path1 is open, delegate to computeOpenBoolean() - if (!path1._children && !path1._closed) + // If path1 is open, delegate to computeOpenBoolean(). + // NOTE: Do not access private _closed property here, since path1 may + // be a CompoundPath. + if (!path1.isClosed()) return computeOpenBoolean(path1, path2, operator); // We do not modify the operands themselves, but create copies instead, // fas produced by the calls to preparePath(). @@ -144,11 +148,11 @@ PathItem.inject(new function() { function computeOpenBoolean(path1, path2, operator) { // Only support subtract and intersect operations between an open - // and a closed path. Assume that compound-paths are closed. - // TODO: Should we complain about not supported operations? - if (!path2 || !path2._children && !path2._closed - || !operator.subtract && !operator.intersect) - return null; + // and a closed path. + if (!path2 || !operator.subtract && !operator.intersect) { + throw new Error('Boolean operations on open paths only support ' + + 'subtraction and intersection with another path.'); + } var _path1 = preparePath(path1, false), _path2 = preparePath(path2, false), crossings = _path1.getCrossings(_path2), diff --git a/src/path/PathItem.js b/src/path/PathItem.js index cd15f1b0..5fbef743 100644 --- a/src/path/PathItem.js +++ b/src/path/PathItem.js @@ -188,7 +188,7 @@ var PathItem = Item.extend(/** @lends PathItem# */{ _contains: function(point) { // NOTE: point is reverse transformed by _matrix, so we don't need to - // apply here. + // apply the matrix here. /*#*/ if (__options.nativeContains || !__options.booleanOperations) { // To compare with native canvas approach: var ctx = CanvasProvider.getContext(1, 1);