diff --git a/src/path/CompoundPath.js b/src/path/CompoundPath.js index 68bd5aef..fa8fcd3a 100644 --- a/src/path/CompoundPath.js +++ b/src/path/CompoundPath.js @@ -251,11 +251,11 @@ var CompoundPath = PathItem.extend(/** @lends CompoundPath# */{ * @bean * @type Number */ - getArea: function(_closed) { + getArea: function() { var children = this._children, area = 0; for (var i = 0, l = children.length; i < l; i++) - area += children[i].getArea(_closed); + area += children[i].getArea(); return area; }, diff --git a/src/path/Curve.js b/src/path/Curve.js index 0e68157c..41d5d328 100644 --- a/src/path/Curve.js +++ b/src/path/Curve.js @@ -577,17 +577,21 @@ var Curve = Base.extend(/** @lends Curve# */{ }, statics: /** @lends Curve */{ - getValues: function(segment1, segment2, matrix) { + getValues: function(segment1, segment2, matrix, straight) { var p1 = segment1._point, h1 = segment1._handleOut, h2 = segment2._handleIn, p2 = segment2._point, - values = [ - p1._x, p1._y, - p1._x + h1._x, p1._y + h1._y, - p2._x + h2._x, p2._y + h2._y, - p2._x, p2._y - ]; + x1 = p1.x, y1 = p1.y, + x2 = p2.x, y2 = p2.y, + values = straight + ? [ x1, y1, x1, y1, x2, y2, x2, y2 ] + : [ + x1, y1, + x1 + h1._x, y1 + h1._y, + x2 + h2._x, y2 + h2._y, + x2, y2 + ]; if (matrix) matrix._transformCoordinates(values, values, 4); return values; diff --git a/src/path/Path.js b/src/path/Path.js index 783b57d5..efbe9269 100644 --- a/src/path/Path.js +++ b/src/path/Path.js @@ -828,29 +828,23 @@ var Path = PathItem.extend(/** @lends Path# */{ * @bean * @type Number */ - getArea: function(_closed) { - // Cache the area for the open path, and the the final curve separately, - // so open and closed area can be returned at almost no additional cost. - var closed = Base.pick(_closed, this._closed), - cached = this._area; - if (cached == null) { + getArea: function() { + var area = this._area; + if (area == null) { var segments = this._segments, - sum = 0, - close = 0; + closed = this._closed; + area = 0; for (var i = 0, l = segments.length; i < l; i++) { - var next = i + 1, - last = next >= l, - area = Curve.getArea(Curve.getValues( - segments[i], segments[last ? 0 : i + 1])); - if (last) { - close = area; - } else { - sum += area; - } + var last = i + 1 === l; + area += Curve.getArea(Curve.getValues( + segments[i], segments[last ? 0 : i + 1], + // If this is the last curve and the last is not closed, + // connect with a straight curve and ignore the handles. + null, last && !closed)); } - cached = this._area = [sum, close]; + this._area = area; } - return cached[0] + (closed ? cached[1] : 0); + return area; }, /** diff --git a/src/path/PathItem.Boolean.js b/src/path/PathItem.Boolean.js index af237081..44c1a1d8 100644 --- a/src/path/PathItem.Boolean.js +++ b/src/path/PathItem.Boolean.js @@ -95,7 +95,7 @@ PathItem.inject(new function() { // Give both paths the same orientation except for subtraction // and exclusion, where we need them at opposite orientation. if (_path2 && (operator.subtract || operator.exclude) - ^ (_path2.isClockwise(true) ^ _path1.isClockwise(true))) + ^ (_path2.isClockwise() ^ _path1.isClockwise())) _path2.reverse(); // Split curves at crossings on both paths. Note that for self- // intersection, path2 is null and getIntersections() handles it. @@ -510,15 +510,10 @@ PathItem.inject(new function() { // - `true`: Connect with a curve that takes the segment handles // into account, just like how closed paths behave. if (!path._closed) { - var s1 = path.getLastCurve().getSegment2(), - s2 = curve.getSegment1(), - p1 = s1._point, - p2 = s2._point, - x1 = p1._x, y1 = p1._y, - x2 = p2._x, y2 = p2._y; - vClose = closed - ? Curve.getValues(s1, s2) - : [x1, y1, x1, y1, x2, y2, x2, y2]; + vClose = Curve.getValues( + path.getLastCurve().getSegment2(), + curve.getSegment1(), + null, !closed); // This closing curve is a potential candidate for the last // non-horizontal curve. if (vClose[io] !== vClose[io + 6]) { @@ -850,7 +845,7 @@ PathItem.inject(new function() { // close to each other that they are considered the same // location, but the winding calculation still produces a valid // number due to their slight differences producing a tiny area. - var area = path.getArea(true); + var area = path.getArea(); if (abs(area) >= /*#=*/Numerical.GEOMETRIC_EPSILON) { // This path wasn't finished and is hence invalid. // Report the error to the console for the time being.