From d730b75073553c6039833ffb9f4253159127b660 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=BCrg=20Lehni?= <juerg@scratchdisk.com>
Date: Thu, 20 Feb 2014 01:56:49 +0100
Subject: [PATCH] Simplify and clean-up PathItem._splitPath() code.

---
 src/path/PathItem.js | 94 ++++++++++++++++++++------------------------
 1 file changed, 43 insertions(+), 51 deletions(-)

diff --git a/src/path/PathItem.js b/src/path/PathItem.js
index bb85c4e6..ca373029 100644
--- a/src/path/PathItem.js
+++ b/src/path/PathItem.js
@@ -289,7 +289,8 @@ var PathItem = Item.extend(/** @lends PathItem# */{
 /*#*/ } // !__options.nativeContains
 	},
 
-	statics: {
+// Mess with indentation in order to get more line-space below...
+statics: {
 	/**
 	 * Private method for splitting a PathItem at the given intersections.
 	 * The routine works for both self intersections and intersections 
@@ -297,60 +298,51 @@ var PathItem = Item.extend(/** @lends PathItem# */{
 	 * @param {CurveLocation[]} intersections Array of CurveLocation objects
 	 */
 	_splitPath: function(intersections) {
-		var loc, i, j, node1, node2, t, segment,
-			path1, isLinear, crv, crvNew,
-			newSegments = [],
-			tolerance = /*#=*/ Numerical.EPSILON;
-		for (i = intersections.length - 1; i >= 0; i--) {
-			node1 = intersections[i];
-			path1 = node1.getPath();
-			// Check if we are splitting same curve multiple times
-			if (node2 && node2.getPath() === path1 &&
-					node2._curve === node1._curve) {
-				// Use the result of last split and interpolate the parameter.
-				crv = crvNew;
-				t = node1._parameter / node2._parameter;
-			} else {
-				crv = node1._curve;
-				t = node1._parameter;
-				isLinear = crv.isLinear();
-				newSegments.length = 0;
-			}
-			// Split the curve at t, while ignoring linearity of curves
-			if (!(crvNew = crv.divide(t, true, true))) {
-				if (t >= 1-tolerance) {
-					segment = crv._segment2;
-				} else if (t <= tolerance) {
-					segment = crv._segment1;
-				} else {
-					// Determine the closest segment by comparing curve lengths
-					segment = crv.getPartLength(0, t) < crv.getPartLength(t, 1)
-							? crv._segment1 : crv._segment2;
-				}
-				crvNew = crv;
-			} else {
-				segment = crvNew.getSegment1();
-				crvNew = crvNew.getPrevious();
-			}
-			// Link the new segment with the intersection on the other curve
-			segment._intersection = node1.getIntersection();
-			node1._segment = segment;
-			node2 = node1;
+		var linearSegments;
+
+		function resetLinear() {
 			// Reset linear segments if they were part of a linear curve 
 			// and if we are done with the entire curve.
-			newSegments.push(segment);
-			loc = intersections[i - 1];
-			if (!(loc && loc.getPath() === path1 && loc._curve === node1._curve)
-					&& isLinear) {
-				for (j = newSegments.length-1; j >= 0; j--) {
-					segment = newSegments[j];
-					// FIXME: Don't reset the appropriate handle if the
-					// intersections were on t == 0 && t == 1
-					segment._handleOut.set(0, 0);
+			for (var i = 0, l = linearSegments.length - 1; i <= l; i++) {
+				var segment = linearSegments[i];
+				if (i > 0)
 					segment._handleIn.set(0, 0);
-				}
+				if (i < l)
+					segment._handleOut.set(0, 0);
 			}
 		}
+
+		for (var i = intersections.length - 1, curve, prevLoc; i >= 0; i--) {
+			var loc = intersections[i],
+				t = loc._parameter;
+			// Check if we are splitting same curve multiple times
+			if (prevLoc && prevLoc._curve === loc._curve) {
+				// Scale parameter after previous split.
+				t /= prevLoc._parameter;
+			} else {
+				if (linearSegments)
+					resetLinear();
+				curve = loc._curve;
+				linearSegments = curve.isLinear() && [];
+			}
+			var newCurve,
+				segment;
+			// Split the curve at t, while ignoring linearity of curves
+			if (newCurve = curve.divide(t, true, true)) {
+				segment = newCurve._segment1;
+				curve = newCurve.getPrevious();
+			} else {
+				segment = t < 0.5 ? curve._segment1 : curve._segment2;
+			}
+			// Link the new segment with the intersection on the other curve
+			segment._intersection = loc.getIntersection();
+			loc._segment = segment;
+			if (linearSegments)
+				linearSegments.push(segment);
+			prevLoc = loc;
+		}
+		if (linearSegments)
+			resetLinear();
 	},
 
 	/**
@@ -641,7 +633,7 @@ var PathItem = Item.extend(/** @lends PathItem# */{
 		}
 		return locations;
 	},
-	}
+}
 
 	/**
 	 * Smooth bezier curves without changing the amount of segments or their