From d2b799f4dbed33a512a77ed518d087fe9d6e1204 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Mon, 31 Dec 2012 22:21:50 +0100 Subject: [PATCH] Fix various issues with Path#curves synchronization. --- src/path/Path.js | 53 +++++++++++++++++++++++---------------- test/tests/Path_Curves.js | 8 ++++++ 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/src/path/Path.js b/src/path/Path.js index c753333d..51b028e3 100644 --- a/src/path/Path.js +++ b/src/path/Path.js @@ -311,17 +311,19 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{ } } // Keep the curves list in sync all the time in case it as requested - // already. We need to step one index down from the inserted segment to - // get its curve: - if (curves && --index >= 0) { + // already. + if (curves) { + // We need to step one index down from the inserted segment to + // get its curve, except for the first segment. + // TODO: + if (index > 0) + index--; // Insert a new curve as well and update the curves above - curves.splice(index, 0, Curve.create(this, segments[index], - segments[index + 1])); - // Adjust segment1 now for the curves above the inserted one - var curve = curves[index + amount]; - if (curve) { - curve._segment1 = segments[index + amount]; - } + for (var i = index, l = index + amount; i < l; i++) + curves.splice(i, 0, Curve.create(this, segments[i], + segments[i + 1] || segments[0])); + // Adjust segments for the curves before and after the removed ones + this._adjustCurves(index - 1, index + amount); } this._changed(/*#=*/ Change.GEOMETRY); return segs; @@ -567,7 +569,6 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{ to = Base.pick(to, this._segments.length); var segments = this._segments, curves = this._curves, - last = to >= segments.length, removed = segments.splice(from, to - from), amount = removed.length; if (!amount) @@ -588,23 +589,31 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{ // If we're removing the last segment, remove the last curve. Also // take into account closed paths, which have one curve more than // segments. - curves.splice(from == segments.length + (this._closed ? 1 : 0) - ? from - 1 : from, amount); + var index = from == segments.length + (this._closed ? 1 : 0) + ? from - 1 : from; + curves.splice(index, amount); // Adjust segments for the curves before and after the removed ones - var curve; - if (curve = curves[from - 1]) - curve._segment2 = segments[from]; - if (curve = curves[from]) - curve._segment1 = segments[from]; - // If the last segment of a closing path was removed, we need to - // readjust the last curve of the list now. - if (last && this._closed && (curve = curves[curves.length - 1])) - curve._segment2 = segments[0]; + this._adjustCurves(index - 1, index + amount); } this._changed(/*#=*/ Change.GEOMETRY); return removed; }, + /** + * Adjusts segments of curves before and after inserted / removed segments. + */ + _adjustCurves: function(left, right) { + var segments = this._segments, + curves = this._curves, + curve; + // If it's the first segment, correct the last segment of closed + // paths too: + if (curve = curves[this._closed && left == -1 ? segments.length - 1 : left]) + curve._segment2 = segments[left + 1] || segments[0]; + if (curve = curves[right]) + curve._segment1 = segments[right]; + }, + /** * Specifies whether an path is selected and will also return {@code true} * if the path is partially selected, i.e. one or more of its segments is diff --git a/test/tests/Path_Curves.js b/test/tests/Path_Curves.js index 562530fd..90cf48ff 100644 --- a/test/tests/Path_Curves.js +++ b/test/tests/Path_Curves.js @@ -46,6 +46,14 @@ test('path.curves Synchronisation', function() { equals(path.curves[0].length, 200, 'Curve length should be updated when path is transformed'); }); +test('path.curves on Closed Paths', function() { + var path = new Path.Circle(new Point(100, 100) , 100); + equals(path.curves.toString(), "{ point1: { x: 0, y: 100 }, handle1: { x: 0, y: -55.22847 }, handle2: { x: -55.22847, y: 0 }, point2: { x: 100, y: 0 } },{ point1: { x: 100, y: 0 }, handle1: { x: 55.22847, y: 0 }, handle2: { x: 0, y: -55.22847 }, point2: { x: 200, y: 100 } },{ point1: { x: 200, y: 100 }, handle1: { x: 0, y: 55.22847 }, handle2: { x: 55.22847, y: 0 }, point2: { x: 100, y: 200 } },{ point1: { x: 100, y: 200 }, handle1: { x: -55.22847, y: 0 }, handle2: { x: 0, y: 55.22847 }, point2: { x: 0, y: 100 } }"); + path.removeSegments(0, 1); + equals(path.curves.toString(), "{ point1: { x: 100, y: 0 }, handle1: { x: 55.22847, y: 0 }, handle2: { x: 0, y: -55.22847 }, point2: { x: 200, y: 100 } },{ point1: { x: 200, y: 100 }, handle1: { x: 0, y: 55.22847 }, handle2: { x: 55.22847, y: 0 }, point2: { x: 100, y: 200 } },{ point1: { x: 100, y: 200 }, handle1: { x: -55.22847, y: 0 }, handle2: { x: -55.22847, y: 0 }, point2: { x: 100, y: 0 } }"); +}); + + test('path.flatten(maxDistance)', function() { var path = new Path.Circle(new Size(80, 50), 35);