diff --git a/src/path/PathItem.Boolean.js b/src/path/PathItem.Boolean.js index c78d6b9d..eba29940 100644 --- a/src/path/PathItem.Boolean.js +++ b/src/path/PathItem.Boolean.js @@ -748,13 +748,29 @@ PathItem.inject(new function() { // While subtracting, we need to omit this curve if it is // contributing to the second operand and is outside the // first operand. - var wind = !(operator.subtract && path2 && ( - operand === path1 && - path2._getWinding(pt, dir, true).winding || - operand === path2 && - !path1._getWinding(pt, dir, true).winding)) - ? getWinding(pt, curves, dir, true) - : { winding: 0, quality: 1 }; + var wind = null; + if (operator.subtract && path2) { + // calculate path winding at point depending on operand + var pathWinding = operand === path1 + ? path2._getWinding(pt, dir, true) + : path1._getWinding(pt, dir, true); + // if curve should be omitted + if (operand === path1 && pathWinding.winding || + operand === path2 && !pathWinding.winding) { + // if quality is not good enough + if (pathWinding.quality < 1) { + // skip this point + continue; + } else { + // omit curve + wind = {winding: 0, quality: 1}; + } + } + } + // default case + if (wind === null) { + wind = getWinding(pt, curves, dir, true); + } if (wind.quality > winding.quality) winding = wind; break; diff --git a/test/tests/Path_Boolean.js b/test/tests/Path_Boolean.js index 083b212b..ed9061f8 100644 --- a/test/tests/Path_Boolean.js +++ b/test/tests/Path_Boolean.js @@ -1189,3 +1189,17 @@ test('Isolated edge-cases from @iconexperience\'s boolean-test suite', function( compareBoolean(path1.intersect(path2), result[1], 'path1.intersect(path2); // Test ' + (i + 1)); } }); + +test('#1506', function () { + var path1 = new Path('M250,175c27.61424,0 50,22.38576 50,50c0,27.61424 -22.38576,50 -50,50c-9.10718,0 -17.64567,-2.43486 -25,-6.68911c14.94503,-8.64524 25,-24.80383 25,-43.31089c0,-18.50706 -10.05497,-34.66565 -25,-43.31089c7.35433,-4.25425 15.89282,-6.68911 25,-6.68911z'); + var path2 = new Path('M250,225c0,-27.61424 22.38576,-50 50,-50c27.61424,0 50,22.38576 50,50c0,27.61424 -22.38576,50 -50,50c-27.61424,0 -50,-22.38576 -50,-50z'); + var result = 'M250,175c9.10718,0 17.64567,2.43486 25,6.68911c-14.94503,8.64523 -25,24.80383 -25,43.31089c0,18.50706 10.05497,34.66566 25,43.31089c-7.35433,4.25425 -15.89282,6.68911 -25,6.68911c-9.10718,0 -17.64567,-2.43486 -25,-6.68911c14.94503,-8.64524 25,-24.80383 25,-43.31089c0,-18.50706 -10.05497,-34.66565 -25,-43.31089c7.35433,-4.25425 15.89282,-6.68911 25,-6.68911z'; + compareBoolean(path1.subtract(path2), result); +}); + +test('#1513', function () { + var path1 = PathItem.create('M100,200v-100h200v100z'); + var path2 = PathItem.create('M200,100c55.22847,0 100,44.77153 100,100h-200c0,-55.22847 44.77153,-100 100,-100z'); + var result = 'M100,100h200v100c0,-55.22847 -44.77153,-100 -100,-100c-55.22847,0 -100,44.77153 -100,100z'; + compareBoolean(path1.subtract(path2), result); +}); \ No newline at end of file