diff --git a/src/basic/Line.js b/src/basic/Line.js index 3f74d033..9d82b0c9 100644 --- a/src/basic/Line.js +++ b/src/basic/Line.js @@ -34,8 +34,8 @@ var Line = this.Line = Base.extend(/** @lends Line# */{ // intersection outside the line segment are allowed. // With two parameters, the 2nd parameter is a direction, and infinite // is automatially true, since we're describing an infinite line. - point1 = Point.read(arguments, 0, 1); - point2 = Point.read(arguments, 1, 1); + point1 = Point.read(arguments); + point2 = Point.read(arguments); if (arguments.length == 3) { this.point = point1; this.vector = point2.subtract(point1); diff --git a/src/basic/Matrix.js b/src/basic/Matrix.js index 875d014c..c69028c2 100644 --- a/src/basic/Matrix.js +++ b/src/basic/Matrix.js @@ -128,24 +128,20 @@ var Matrix = this.Matrix = Base.extend(/** @lends Matrix# */{ * @param {Point} [center] The center for the scaling transformation * @return {Matrix} This affine transform */ - scale: function(/* scale | */ hor, ver, center) { - if (arguments.length < 2 || typeof ver === 'object') { - // hor is the single scale parameter, representing both hor and ver - // Read center first from argument 1, then set ver = hor (thus - // modifing the content of argument 1!) - center = Point.read(arguments, 1); - ver = hor; - } else { - center = Point.read(arguments, 2); - } - if (center) - this.translate(center); - this._a *= hor; - this._c *= hor; - this._b *= ver; - this._d *= ver; - if (center) - this.translate(center.negate()); + scale: function(scale, center) { + // Do not modify scale, center, since that would arguments of which + // we're reading from! + var _scale = Point.read(arguments), + _center = Point.read(arguments); + // TODO: Isn't center always set this way?? + if (_center) + this.translate(_center); + this._a *= _scale.x; + this._c *= _scale.x; + this._b *= _scale.y; + this._d *= _scale.y; + if (_center) + this.translate(_center.negate()); return this; }, @@ -168,7 +164,8 @@ var Matrix = this.Matrix = Base.extend(/** @lends Matrix# */{ */ translate: function(point) { point = Point.read(arguments); - var x = point.x, y = point.y; + var x = point.x, + y = point.y; this._tx += x * this._a + y * this._b; this._ty += x * this._c + y * this._d; return this; @@ -219,24 +216,21 @@ var Matrix = this.Matrix = Base.extend(/** @lends Matrix# */{ * @param {Point} [center] The center for the shear transformation * @return {Matrix} This affine transform */ - shear: function(/* point | */ hor, ver, center) { - // See #scale() for explanation of this: - if (arguments.length < 2 || typeof ver === 'object') { - center = Point.read(arguments, 1); - ver = hor; - } else { - center = Point.read(arguments, 2); - } - if (center) - this.translate(center); + shear: function(point, center) { + // Do not modify point, center, since that would arguments of which + // we're reading from! + var _point = Point.read(arguments), + _center = Point.read(arguments); + if (_center) + this.translate(_center); var a = this._a, c = this._c; - this._a += ver * this._b; - this._c += ver * this._d; - this._b += hor * a; - this._d += hor * c; - if (center) - this.translate(center.negate()); + this._a += _point.y * this._b; + this._c += _point.y * this._d; + this._b += _point.x * a; + this._d += _point.x * c; + if (_center) + this.translate(_center.negate()); return this; }, diff --git a/src/basic/Point.js b/src/basic/Point.js index 8a1d86c0..975397ab 100644 --- a/src/basic/Point.js +++ b/src/basic/Point.js @@ -28,6 +28,9 @@ * console.log(point.y); // 5 */ var Point = this.Point = Base.extend(/** @lends Point# */{ + // Tell Base.read that the Point constructor supporst reading with index + _readIndex: true, + /** * Creates a Point object with the given x and y coordinates. * @@ -132,25 +135,36 @@ var Point = this.Point = Base.extend(/** @lends Point# */{ initialize: function(arg0, arg1) { var type = typeof arg0; if (type === 'number') { + var hasY = typeof arg1 === 'number'; this.x = arg0; - this.y = typeof arg1 === 'number' ? arg1 : arg0; + this.y = hasY ? arg1 : arg0; + if (this._read) + this._read = hasY ? 2 : 1; } else if (type === 'undefined' || arg0 === null) { this.x = this.y = 0; - } else if (typeof arg0.x !== 'undefined') { - this.x = arg0.x; - this.y = arg0.y; - } else if (Array.isArray(arg0)) { - this.x = arg0[0]; - this.y = arg0.length > 1 ? arg0[1] : arg0[0]; - } else if (typeof arg0.width !== 'undefined') { - this.x = arg0.width; - this.y = arg0.height; - } else if (typeof arg0.angle !== 'undefined') { - this.x = arg0.length; - this.y = 0; - this.setAngle(arg0.angle); + if (this._read) + this._read = arg0 === null ? 1 : 0; } else { - this.x = this.y = 0; + if (typeof arg0.x !== 'undefined') { + this.x = arg0.x; + this.y = arg0.y; + } else if (Array.isArray(arg0)) { + this.x = arg0[0]; + this.y = arg0.length > 1 ? arg0[1] : arg0[0]; + } else if (typeof arg0.width !== 'undefined') { + this.x = arg0.width; + this.y = arg0.height; + } else if (typeof arg0.angle !== 'undefined') { + this.x = arg0.length; + this.y = 0; + this.setAngle(arg0.angle); + } else { + this.x = this.y = 0; + if (this._read) + this._read = 0; + } + if (this._read) + this._read = 1; } }, @@ -787,11 +801,11 @@ var Point = this.Point = Base.extend(/** @lends Point# */{ * console.log(minPoint); // {x: 10, y: 5} */ min: function(point1, point2) { - point1 = Point.read(arguments, 0, 1); - point2 = Point.read(arguments, 1, 1); + var _point1 = Point.read(arguments); + _point2 = Point.read(arguments); return Point.create( - Math.min(point1.x, point2.x), - Math.min(point1.y, point2.y) + Math.min(_point1.x, _point2.x), + Math.min(_point1.y, _point2.y) ); }, @@ -811,11 +825,11 @@ var Point = this.Point = Base.extend(/** @lends Point# */{ * console.log(maxPoint); // {x: 200, y: 100} */ max: function(point1, point2) { - point1 = Point.read(arguments, 0, 1); - point2 = Point.read(arguments, 1, 1); + var _point1 = Point.read(arguments); + _point2 = Point.read(arguments); return Point.create( - Math.max(point1.x, point2.x), - Math.max(point1.y, point2.y) + Math.max(_point1.x, _point2.x), + Math.max(_point1.y, _point2.y) ); }, diff --git a/src/basic/Rectangle.js b/src/basic/Rectangle.js index 1e91e117..8f886c64 100644 --- a/src/basic/Rectangle.js +++ b/src/basic/Rectangle.js @@ -22,6 +22,9 @@ * rectangular path, it is not an item. */ var Rectangle = this.Rectangle = Base.extend(/** @lends Rectangle# */{ + // Tell Base.read that the Rectangle constructor supporst reading with index + _readIndex: true, + /** * Creates a Rectangle object. * @@ -54,21 +57,34 @@ var Rectangle = this.Rectangle = Base.extend(/** @lends Rectangle# */{ * @param {Rectangle} rt */ initialize: function(arg0, arg1, arg2, arg3) { - if (arguments.length == 4) { + var type = typeof arg0; + if (type === 'number') { // new Rectangle(x, y, width, height) this.x = arg0; this.y = arg1; this.width = arg2; this.height = arg3; - } else if (arguments.length == 2) { - if (arg1 && arg1.x !== undefined) { + if (this._read) + this._read = 4; + } else if (type === 'undefined' || arg0 === null) { + // new Rectangle(), new Rectangle(null) + this.x = this.y = this.width = this.height = 0; + if (this._read) + this._read = arg0 === null ? 1 : 0; + } else if (arguments.length > 1 && typeof arg0.width === 'undefined') { + // We're checking arg0.width to rule out Rectangles, which are + // handled separately below. + // Read a point argument and look at the next value to see wether + // it's a size or a point, then read accordingly + var point = Point.read(arguments), + next = Base.peekValue(arguments); + this.x = point.x; + this.y = point.y; + if (next && next.x !== undefined) { // new Rectangle(point1, point2) - var point1 = Point.read(arguments, 0, 1); - var point2 = Point.read(arguments, 1, 1); - this.x = point1.x; - this.y = point1.y; - this.width = point2.x - point1.x; - this.height = point2.y - point1.y; + var point2 = Point.read(arguments); + this.width = point2.x - point.x; + this.height = point2.y - point.y; if (this.width < 0) { this.x = point2.x; this.width = -this.width; @@ -79,22 +95,22 @@ var Rectangle = this.Rectangle = Base.extend(/** @lends Rectangle# */{ } } else { // new Rectangle(point, size) - var point = Point.read(arguments, 0, 1); - var size = Size.read(arguments, 1, 1); - this.x = point.x; - this.y = point.y; + var size = Size.read(arguments); this.width = size.width; this.height = size.height; } + if (this._read) + this._read = arguments._index; } else if (arg0) { - // Use 0 as defaults, in case we're reading from a Point or Size + // new Rectangle(rect) + // Use 0 as defaults, in case we're not reading from a Rectangle, + // but a Point or Size instead this.x = arg0.x || 0; this.y = arg0.y || 0; this.width = arg0.width || 0; this.height = arg0.height || 0; - } else { - // new Rectangle() - this.x = this.y = this.width = this.height = 0; + if (this._read) + this._read = 1; } }, diff --git a/src/basic/Size.js b/src/basic/Size.js index 2ffdbad1..48c8b270 100644 --- a/src/basic/Size.js +++ b/src/basic/Size.js @@ -27,6 +27,9 @@ * console.log(size.height); // 5 */ var Size = this.Size = Base.extend(/** @lends Size# */{ + // Tell Base.read that the Point constructor supporst reading with index + _readIndex: true, + // DOCS: improve Size class description /** * Creates a Size object with the given width and height values. @@ -91,28 +94,34 @@ var Size = this.Size = Base.extend(/** @lends Size# */{ * console.log(size.height); // 50 */ initialize: function(arg0, arg1) { - if (arg1 !== undefined) { + var type = typeof arg0; + if (type === 'number') { + var hasHeight = typeof arg1 === 'number'; this.width = arg0; - this.height = arg1; - } else if (arg0 !== undefined) { - if (arg0 == null) { - this.width = this.height = 0; - } else if (arg0.width !== undefined) { + this.height = hasHeight ? arg1 : arg0; + if (this._read) + this._read = hasHeight ? 2 : 1; + } else if (type === 'undefined' || arg0 === null) { + this.width = this.height = 0; + if (this._read) + this._read = arg0 === null ? 1 : 0; + } else { + if (typeof arg0.width !== 'undefined') { this.width = arg0.width; this.height = arg0.height; - } else if (arg0.x !== undefined) { - this.width = arg0.x; - this.height = arg0.y; } else if (Array.isArray(arg0)) { this.width = arg0[0]; this.height = arg0.length > 1 ? arg0[1] : arg0[0]; - } else if (typeof arg0 === 'number') { - this.width = this.height = arg0; + } else if (typeof arg0.x !== 'undefined') { + this.width = arg0.x; + this.height = arg0.y; } else { this.width = this.height = 0; + if (this._read) + this._read = 0; } - } else { - this.width = this.height = 0; + if (this._read) + this._read = 1; } }, diff --git a/src/color/Color.js b/src/color/Color.js index ab16f827..fd33ce1d 100644 --- a/src/color/Color.js +++ b/src/color/Color.js @@ -207,16 +207,20 @@ var Color = this.Color = Base.extend(new function() { }; var fields = /** @lends Color# */{ + // Tell Base.read that we do not want null to be converted to a color. _readNull: true, + // Tell Base.read that the Point constructor supporst reading with index + _readIndex: true, initialize: function(arg) { var isArray = Array.isArray(arg), - type = this._colorType; + type = this._colorType, + res; if (typeof arg === 'object' && !isArray) { if (!type) { // Called on the abstract Color class. Guess color type // from arg - return arg.red !== undefined + res = arg.red !== undefined ? new RgbColor(arg.red, arg.green, arg.blue, arg.alpha) : arg.gray !== undefined ? new GrayColor(arg.gray, arg.alpha) @@ -227,33 +231,41 @@ var Color = this.Color = Base.extend(new function() { ? new HsbColor(arg.hue, arg.saturation, arg.brightness, arg.alpha) : new RgbColor(); // Fallback + if (this._read) + res._read = 1; } else { // Called on a subclass instance. Return the converted // color. - return Color.read(arguments).convert(type); + res = Color.read(arguments).convert(type); + if (this._read) + res._read = arguments._read; } } else if (typeof arg === 'string') { var rgbColor = arg.match(/^#[0-9a-f]{3,6}$/i) ? hexToRgbColor(arg) : nameToRgbColor(arg); - return type + res = type ? rgbColor.convert(type) : rgbColor; + if (this._read) + res._read = 1; } else { var components = isArray ? arg : Array.prototype.slice.call(arguments); if (!type) { // Called on the abstract Color class. Guess color type // from arg - //if (components.length >= 4) - // return new CmykColor(components); - if (components.length >= 3) - return new RgbColor(components); - return new GrayColor(components); + // var ctor = components.length >= 4 + // ? CmykColor + // : components.length >= 3 + var ctor = components.length >= 3 + ? RgbColor + : GrayColor; + res = new ctor(components); } else { // Called on a subclass instance. Just copy over // components. - Base.each(this._components, + res = Base.each(this._components, function(name, i) { var value = components[i]; // Set internal propery directly @@ -262,7 +274,10 @@ var Color = this.Color = Base.extend(new function() { }, this); } + if (this._read) + res._read = res._components.length; } + return res; }, /** diff --git a/src/core/Base.js b/src/core/Base.js index 5fca29da..c2561a2d 100644 --- a/src/core/Base.js +++ b/src/core/Base.js @@ -63,18 +63,45 @@ this.Base = Base.inject(/** @lends Base# */{ * cloned if they are already provided in the required type */ read: function(list, start, length, clone) { - var start = start || 0, - length = length || list.length - start; - var obj = list[start]; + var proto = this.prototype, + readIndex = proto._readIndex, + index = start || readIndex && list._index || 0; + if (!length) + length = list.length - index; + var obj = list[index]; if (obj instanceof this // If the class defines _readNull, return null when nothing // was provided - || this.prototype._readNull && obj == null && length <= 1) + || proto._readNull && obj == null && length <= 1) { + if (readIndex) + list._index = index + 1; return obj && clone ? obj.clone() : obj; + } obj = new this(this.dont); - return obj.initialize.apply(obj, start > 0 || length < list.length - ? Array.prototype.slice.call(list, start, start + length) + if (readIndex) + obj._read = true; + obj = obj.initialize.apply(obj, index > 0 || length < list.length + ? Array.prototype.slice.call(list, index, index + length) : list) || obj; + if (readIndex) { + list._index = index + obj._read; + // Have arguments._read point to the amount of args read in the + // last read() call + list._read = obj._read; + delete obj._read; + } + return obj; + }, + + peekValue: function(list, start) { + return list[list._index = start || list._index || 0]; + }, + + readValue: function(list, start) { + var value = this.peekValue(list, start); + list._index++; + list._read = 1; + return value; }, /** diff --git a/src/item/HitResult.js b/src/item/HitResult.js index 758181f0..ef56d46d 100644 --- a/src/item/HitResult.js +++ b/src/item/HitResult.js @@ -107,10 +107,9 @@ HitResult = Base.extend(/** @lends HitResult# */{ * @private */ getOptions: function(point, options) { + // Use _merged property to not repeatetly call merge in recursion. return options && options._merged ? options : Base.merge({ - // Use the converted options object to perform point conversion - // only once. - point: Point.read(arguments, 0, 1), + point: Point.read([point]), // Type of item, for instanceof check: PathItem, TexItem, etc type: null, // Tolerance diff --git a/src/item/Item.js b/src/item/Item.js index 97b21162..508caaf1 100644 --- a/src/item/Item.js +++ b/src/item/Item.js @@ -115,7 +115,7 @@ var Item = this.Item = Base.extend(Callback, /** @lends Item# */{ this._matrix = pointOrMatrix !== undefined ? pointOrMatrix instanceof Matrix ? pointOrMatrix.clone() - : new Matrix().translate(Point.read(arguments, 0)) + : new Matrix().translate(Point.read(arguments)) : new Matrix(); }, diff --git a/src/item/Raster.js b/src/item/Raster.js index f52378c6..0ac4347d 100644 --- a/src/item/Raster.js +++ b/src/item/Raster.js @@ -338,17 +338,16 @@ var Raster = this.Raster = PlacedItem.extend(/** @lends Raster# */{ * @param color the color that the pixel will be set to */ setPixel: function(point, color) { - var hasPoint = arguments.length == 2; - point = Point.read(arguments, 0, hasPoint ? 1 : 2); - color = Color.read(arguments, hasPoint ? 1 : 2); + var _point = Point.read(arguments), + _color = Color.read(arguments); var ctx = this.getContext(true), imageData = ctx.createImageData(1, 1), alpha = color.getAlpha(); - imageData.data[0] = color.getRed() * 255; - imageData.data[1] = color.getGreen() * 255; - imageData.data[2] = color.getBlue() * 255; + imageData.data[0] = _color.getRed() * 255; + imageData.data[1] = _color.getGreen() * 255; + imageData.data[2] = _color.getBlue() * 255; imageData.data[3] = alpha != null ? alpha * 255 : 255; - ctx.putImageData(imageData, point.x, point.y); + ctx.putImageData(imageData, _point.x, _point.y); }, // DOCS: document Raster#createData diff --git a/src/path/Path.Constructors.js b/src/path/Path.Constructors.js index 04918c4c..91996170 100644 --- a/src/path/Path.Constructors.js +++ b/src/path/Path.Constructors.js @@ -41,10 +41,9 @@ Path.inject({ statics: new function() { * path.strokeColor = 'black'; */ Line: function() { - var step = Math.floor(arguments.length / 2); return new Path( - Segment.read(arguments, 0, step), - Segment.read(arguments, step, step) + Point.read(arguments), + Point.read(arguments) ); }, @@ -125,32 +124,27 @@ Path.inject({ statics: new function() { * var path = new Path.RoundRectangle(rectangle, cornerSize); */ RoundRectangle: function(rect, size) { - if (arguments.length == 2) { - rect = Rectangle.read(arguments, 0, 1); - size = Size.read(arguments, 1, 1); - } else if (arguments.length == 6) { - rect = Rectangle.read(arguments, 0, 4); - size = Size.read(arguments, 4, 2); - } - size = Size.min(size, rect.getSize(true).divide(2)); - var path = new Path(), - uSize = size.multiply(kappa * 2), - bl = rect.getBottomLeft(true), - tl = rect.getTopLeft(true), - tr = rect.getTopRight(true), - br = rect.getBottomRight(true); + var _rect = Rectangle.read(arguments), + _size = Size.min(Size.read(arguments), + _rect.getSize(true).divide(2)), + path = new Path(), + uSize = _size.multiply(kappa * 2), + bl = _rect.getBottomLeft(true), + tl = _rect.getTopLeft(true), + tr = _rect.getTopRight(true), + br = _rect.getBottomRight(true); path._add([ - new Segment(bl.add(size.width, 0), null, [-uSize.width, 0]), - new Segment(bl.subtract(0, size.height), [0, uSize.height], null), + new Segment(bl.add(_size.width, 0), null, [-uSize.width, 0]), + new Segment(bl.subtract(0, _size.height), [0, uSize.height], null), - new Segment(tl.add(0, size.height), null, [0, -uSize.height]), - new Segment(tl.add(size.width, 0), [-uSize.width, 0], null), + new Segment(tl.add(0, _size.height), null, [0, -uSize.height]), + new Segment(tl.add(_size.width, 0), [-uSize.width, 0], null), - new Segment(tr.subtract(size.width, 0), null, [uSize.width, 0]), - new Segment(tr.add(0, size.height), [0, -uSize.height], null), + new Segment(tr.subtract(_size.width, 0), null, [uSize.width, 0]), + new Segment(tr.add(0, _size.height), [0, -uSize.height], null), - new Segment(br.subtract(0, size.height), null, [0, uSize.height]), - new Segment(br.subtract(size.width, 0), [uSize.width, 0], null) + new Segment(br.subtract(0, _size.height), null, [0, uSize.height]), + new Segment(br.subtract(_size.width, 0), [uSize.width, 0], null) ]); path._closed = true; return path; @@ -204,14 +198,10 @@ Path.inject({ statics: new function() { * var path = new Path.Circle(new Point(100, 100), 50); */ Circle: function(center, radius) { - if (arguments.length == 3) { - center = Point.read(arguments, 0, 2); - radius = arguments[2]; - } else { - center = Point.read(arguments, 0, 1); - } - return Path.Oval(new Rectangle(center.subtract(radius), - Size.create(radius * 2, radius * 2))); + var _center = Point.read(arguments), + _radius = Base.readValue(arguments); + return Path.Oval(new Rectangle(_center.subtract(_radius), + Size.create(_radius * 2, _radius * 2))); }, /** @@ -261,15 +251,17 @@ Path.inject({ statics: new function() { * decahedron.fillColor = 'black'; */ RegularPolygon: function(center, numSides, radius) { - center = Point.read(arguments, 0, 1); - var path = new Path(), - step = 360 / numSides, - three = !(numSides % 3), - vector = new Point(0, three ? -radius : radius), + var _center = Point.read(arguments), + _numSides = Base.readValue(arguments), + _radius = Base.readValue(arguments), + path = new Path(), + step = 360 / _numSides, + three = !(_numSides % 3), + vector = new Point(0, three ? -_radius : _radius), offset = three ? -1 : 0.5, - segments = new Array(numSides); - for (var i = 0; i < numSides; i++) { - segments[i] = new Segment(center.add( + segments = new Array(_numSides); + for (var i = 0; i < _numSides; i++) { + segments[i] = new Segment(_center.add( vector.rotate((i + offset) * step))); } path._add(segments); @@ -299,15 +291,17 @@ Path.inject({ statics: new function() { * path.fillColor = 'black'; */ Star: function(center, numPoints, radius1, radius2) { - center = Point.read(arguments, 0, 1); - numPoints *= 2; - var path = new Path(), - step = 360 / numPoints, + var _center = Point.read(arguments), + _numPoints = Base.readValue(arguments) * 2, + _radius1 = Base.readValue(arguments), + _radius2 = Base.readValue(arguments), + path = new Path(), + step = 360 / _numPoints, vector = new Point(0, -1), - segments = new Array(numPoints); - for (var i = 0; i < numPoints; i++) { - segments[i] = new Segment(center.add( - vector.rotate(step * i).multiply(i % 2 ? radius2 : radius1))); + segments = new Array(_numPoints); + for (var i = 0; i < _numPoints; i++) { + segments[i] = new Segment(_center.add( + vector.rotate(step * i).multiply(i % 2 ? _radius2 : _radius1))); } path._add(segments); path._closed = true; diff --git a/src/path/Path.js b/src/path/Path.js index dfda51df..5298176d 100644 --- a/src/path/Path.js +++ b/src/path/Path.js @@ -1667,20 +1667,20 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{ }, cubicCurveTo: function(handle1, handle2, to) { - handle1 = Point.read(arguments, 0, 1); - handle2 = Point.read(arguments, 1, 1); - to = Point.read(arguments, 2, 1); + var _handle1 = Point.read(arguments); + _handle2 = Point.read(arguments); + _to = Point.read(arguments); // First modify the current segment: var current = getCurrentSegment(this); // Convert to relative values: - current.setHandleOut(handle1.subtract(current._point)); + current.setHandleOut(_handle1.subtract(current._point)); // And add the new segment, with handleIn set to c2 - this._add([ new Segment(to, handle2.subtract(to)) ]); + this._add([ new Segment(_to, _handle2.subtract(to)) ]); }, quadraticCurveTo: function(handle, to) { - handle = Point.read(arguments, 0, 1); - to = Point.read(arguments, 1, 1); + var _handle = Point.read(arguments), + to = Point.read(arguments); // This is exact: // If we have the three quad points: A E D, // and the cubic is A B C D, @@ -1688,26 +1688,26 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{ // C = E + 1/3 (D - E) var current = getCurrentSegment(this)._point; this.cubicCurveTo( - handle.add(current.subtract(handle).multiply(1/3)), - handle.add(to.subtract(handle).multiply(1/3)), - to + _handle.add(current.subtract(_handle).multiply(1 / 3)), + _handle.add(to.subtract(_handle).multiply(1 / 3)), + _to ); }, curveTo: function(through, to, parameter) { - through = Point.read(arguments, 0, 1); - to = Point.read(arguments, 1, 1); - var t = Base.pick(parameter, 0.5), + var _through = Point.read(arguments), + _to = Point.read(arguments), + t = Base.pick(Base.readValue(arguments), 0.5), t1 = 1 - t, current = getCurrentSegment(this)._point, // handle = (through - (1 - t)^2 * current - t^2 * to) / // (2 * (1 - t) * t) - handle = through.subtract(current.multiply(t1 * t1)) - .subtract(to.multiply(t * t)).divide(2 * t * t1); + handle = _through.subtract(current.multiply(t1 * t1)) + .subtract(_to.multiply(t * t)).divide(2 * t * t1); if (handle.isNaN()) throw new Error( 'Cannot put a curve through points with parameter = ' + t); - this.quadraticCurveTo(handle, to); + this.quadraticCurveTo(handle, _to); }, // PORT: New implementation back to Scriptographer @@ -1715,17 +1715,20 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{ // Get the start point: var current = getCurrentSegment(this), from = current._point, - through; - if (clockwise === undefined) - clockwise = true; - if (typeof clockwise === 'boolean') { - to = Point.read(arguments, 0, 1); + through, + point = Point.read(arguments), + next = Base.peekValue(arguments); + if (/boolean|undefined/.test(typeof next)) { + // arcTo(to, clockwise) + to = point; + clockwise = next; var middle = from.add(to).divide(2), through = middle.add(middle.subtract(from).rotate( clockwise ? -90 : 90)); } else { - through = Point.read(arguments, 0, 1); - to = Point.read(arguments, 1, 1); + // arcTo(through, to) + through = point; + to = Point.read(arguments); } // Construct the two perpendicular middle lines to (from, through) // and (through, to), and intersect them to get the center diff --git a/src/path/SegmentPoint.js b/src/path/SegmentPoint.js index c0492796..ca5f2b3f 100644 --- a/src/path/SegmentPoint.js +++ b/src/path/SegmentPoint.js @@ -73,7 +73,7 @@ var SegmentPoint = Point.extend({ } else { // If not Point-like already, read Point from pt = 3rd argument if ((x = pt.x) === undefined) { - pt = Point.read(arguments, 2, 1); + pt = Point.read(arguments, 2); x = pt.x; } y = pt.y;