From 2c8f4f94535e7ad40f9eff2b091319b962cf9bd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Tue, 19 Jul 2016 14:55:57 +0200 Subject: [PATCH] Boolean: Fix sort function to produce correct resutls on all browsers. --- src/path/CurveLocation.js | 12 ++++++------ src/path/PathItem.Boolean.js | 26 ++++++++++++++++++-------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/path/CurveLocation.js b/src/path/CurveLocation.js index ac523485..b006e39f 100644 --- a/src/path/CurveLocation.js +++ b/src/path/CurveLocation.js @@ -563,13 +563,13 @@ new function() { // Scope for statics path2 = loc2.getPath(), // NOTE: equals() takes the intersection location into account, // while this calculation of diff doesn't! - diff = path1 === path2 - //Sort by both index and time. The two values added - // together provides a convenient sorting index. - ? (loc.getIndex() + loc.getTime()) - - (loc2.getIndex() + loc2.getTime()) + diff = path1 !== path2 // Sort by path id to group all locs on same path. - : path1._id - path2._id; + ? path1._id - path2._id + // Sort by both index and time on the same path. The two values + // added together provides a convenient sorting index. + : (loc.getIndex() + loc.getTime()) + - (loc2.getIndex() + loc2.getTime()); if (diff < 0) { r = m - 1; } else { diff --git a/src/path/PathItem.Boolean.js b/src/path/PathItem.Boolean.js index 52e9bd79..933e30e1 100644 --- a/src/path/PathItem.Boolean.js +++ b/src/path/PathItem.Boolean.js @@ -633,15 +633,25 @@ PathItem.inject(new function() { return null; } - // Sort segments to give non-ambiguous segments the preference as - // starting points when tracing: prefer segments with no intersections - // over intersections, and process intersections with overlaps last: + // Sort segments to give non-overlapping segments the preference as + // starting points when tracing. segments.sort(function(a, b) { - var i1 = a._intersection, - i2 = b._intersection, - o1 = !!(i1 && i1._overlap), - o2 = !!(i2 && i2._overlap); - return !i1 && !i2 ? -1 : o1 ^ o2 ? o1 ? 1 : -1 : 0; + var path1 = a._path, + path2 = b._path, + inter1 = a._intersection, + inter2 = b._intersection, + over1 = !!(inter1 && inter1._overlap), + over2 = !!(inter2 && inter2._overlap); + return path1 !== path2 + // Sort by path id to group all segments on same path. + ? path1._id - path2._id + // If only one of the two segments on the same path is an + // overlap, sort it so it comes after the other. + : over1 ^ over2 + ? over1 ? 1 : -1 + // All other segments, intersection or not, are sorted + // by their natural order within the path. + : a._index - b._index; }); for (var i = 0, l = segments.length; i < l; i++) {