Merge remote branch 'origin/master'

This commit is contained in:
Jonathan Puckey 2011-05-02 12:25:32 +02:00
commit 2ee7081c14
7 changed files with 134 additions and 99 deletions

View file

@ -149,29 +149,20 @@ var Point = this.Point = Base.extend({
},
setLength: function(length) {
// Whenever setting x/y, use #set() instead of direct assignment,
// so LinkedPoint does not report changes twice.
if (this.isZero()) {
if (this._angle != null) {
var a = this._angle;
// Use #set() instead of direct assignment, so LinkedPoint
// can optimise
this.set(
Math.cos(a) * length,
Math.sin(a) * length
);
} else {
// Assume angle = 0
this.x = length;
// y is already 0
}
var angle = this._angle || 0;
this.set(
Math.cos(angle) * length,
Math.sin(angle) * length
);
} else {
var scale = length / this.getLength();
if (scale == 0) {
// Calculate angle now, so it will be preserved even when
// x and y are 0
// Force calculation of angle now, so it will be preserved even when
// x and y are 0
if (scale == 0)
this.getAngle();
}
// Use #set() instead of direct assignment, so LinkedPoint
// can optimise
this.set(
this.x * scale,
this.y * scale
@ -181,30 +172,18 @@ var Point = this.Point = Base.extend({
},
normalize: function(length) {
if (length === null)
if (length === undefined)
length = 1;
var len = this.getLength();
var scale = len != 0 ? length / len : 0;
var res = Point.create(this.x * scale, this.y * scale);
var current = this.getLength(),
scale = current != 0 ? length / current : 0,
point = Point.create(this.x * scale, this.y * scale);
// Preserve angle.
res._angle = this._angle;
return res;
point._angle = this._angle;
return point;
},
getQuadrant: function() {
if (this.x >= 0) {
if (this.y >= 0) {
return 1;
} else {
return 4;
}
} else {
if (this.y >= 0) {
return 2;
} else {
return 3;
}
}
return this.x >= 0 ? this.y >= 0 ? 1 : 4 : this.y >= 0 ? 2 : 3;
},
/**
@ -230,8 +209,8 @@ var Point = this.Point = Base.extend({
angle = this._angle = angle * Math.PI / 180;
if (!this.isZero()) {
var length = this.getLength();
// Use #set() instead of direct assignment, so LinkedPoint
// can optimise
// Use #set() instead of direct assignment of x/y, so LinkedPoint
// does not report changes twice.
this.set(
Math.cos(angle) * length,
Math.sin(angle) * length
@ -514,7 +493,8 @@ var Point = this.Point = Base.extend({
min: function(point1, point2) {
return Point.create(
Math.min(point1.x, point2.x),
Math.min(point1.y, point2.y));
Math.min(point1.y, point2.y)
);
},
/**
@ -536,7 +516,8 @@ var Point = this.Point = Base.extend({
max: function(point1, point2) {
return Point.create(
Math.max(point1.x, point2.x),
Math.max(point1.y, point2.y));
Math.max(point1.y, point2.y)
);
},
/**

View file

@ -173,15 +173,15 @@ var Color = this.Color = Base.extend(new function() {
},
toString: function() {
var string = '';
var parts = [];
for (var i = 0, l = this._components.length; i < l; i++) {
var component = this._components[i];
var value = this['_' + component];
if (component === 'alpha' && value == null)
value = 1;
string += (i > 0 ? ', ' : '') + component + ': ' + value;
parts.push(component + ': ' + value);
}
return '{ ' + string + ' }';
return '{ ' + parts.join(', ') + ' }';
},
toCssString: function() {

View file

@ -35,6 +35,11 @@ var Curve = this.Curve = Base.extend({
}
},
_changed: function() {
// Clear cached values.
delete this._length;
},
_updateSegments: function() {
if (this._path) {
this._index2 = this._index1 + 1;
@ -153,11 +158,19 @@ var Curve = this.Curve = Base.extend({
},
getLength: function(/* from, to */) {
var from = arguments[0],
to = arguments[1];
fullLength = arguments.length == 0 || from == 0 && to == 1;
if (fullLength && this._length != null)
return this._length;
// Hide parameters from Bootstrap so it injects bean too
var args = this.getCurveValues();
if (arguments.length > 0)
args.push(arguments[0], arguments[1]);
return Curve.getLength.apply(Curve, args);
if (!fullLength)
args.push(from, to);
var length = Curve.getLength.apply(Curve, args);
if (fullLength)
this._length = length;
return length;
},
/**
@ -203,13 +216,13 @@ var Curve = this.Curve = Base.extend({
},
toString: function() {
return '{ point1: ' + this._segment1._point
+ (!this._segment1._handleOut.isZero()
? ', handle1: ' + this._segment1._handleOut : '')
+ (this._segment2._handleIn.isZero()
? ', handle2: ' + this._segment2._handleIn : '')
+ ', point2: ' + this._segment2._point
+ ' }';
var parts = [ 'point1: ' + this._segment1._point ];
if (!this._segment1._handleOut.isZero())
parts.push('handle1: ' + this._segment1._handleOut);
if (!this._segment2._handleIn.isZero())
parts.push('handle2: ' + this._segment2._handleIn);
parts.push('point2: ' + this._segment2._point);
return '{ ' + parts.join(', ') + ' }';
},
statics: {

View file

@ -28,6 +28,13 @@ var Path = this.Path = PathItem.extend({
|| typeof segments[0] !== 'object' ? arguments : segments);
},
_changed: function() {
// Clear cached values.
delete this._length;
delete this._bounds;
delete this._strokeBounds;
},
/**
* The segments contained within the path.
*/
@ -102,6 +109,7 @@ var Path = this.Path = PathItem.extend({
if (closed)
this._curves[i = length - 1] = Curve.create(this, i);
}
this._changed();
}
},
@ -116,6 +124,7 @@ var Path = this.Path = PathItem.extend({
this._segments[i]._transformCoordinates(matrix, coords, true);
}
}
this._changed();
},
/**
@ -163,6 +172,7 @@ var Path = this.Path = PathItem.extend({
if (this._closed)
this._curves[l - 1]._updateSegments();
}
this._changed();
return segment;
},
@ -199,6 +209,7 @@ var Path = this.Path = PathItem.extend({
segment._selectionState = 0;
}
}
this._changed();
return segments;
}
return null;
@ -245,6 +256,7 @@ var Path = this.Path = PathItem.extend({
segment._handleIn = segment._handleOut;
segment._handleOut = handleIn;
}
this._changed();
},
join: function(path) {
@ -282,17 +294,20 @@ var Path = this.Path = PathItem.extend({
last1.remove();
this.setClosed(true);
}
this._changed();
return true;
}
return false;
},
getLength: function() {
var curves = this.getCurves();
var length = 0;
for (var i = 0, l = curves.length; i < l; i++)
length += curves[i].getLength();
return length;
if (this._length == null) {
var curves = this.getCurves();
this._length = 0;
for (var i = 0, l = curves.length; i < l; i++)
this._length += curves[i].getLength();
}
return this._length;
},
_getOffset: function(location) {
@ -977,9 +992,12 @@ var Path = this.Path = PathItem.extend({
getBounds: function(/* matrix */) {
// Pass the matrix hidden from Bootstrap, so it still inject
// getBounds as bean too.
var bounds = getBounds(this, arguments[0]);
return LinkedRectangle.create(this, 'setBounds',
bounds.x, bounds.y, bounds.width, bounds.height);
if (!this._bounds) {
var bounds = getBounds(this, arguments[0]);
this._bounds = LinkedRectangle.create(this, 'setBounds',
bounds.x, bounds.y, bounds.width, bounds.height);
}
return this._bounds;
},
/**

View file

@ -51,6 +51,28 @@ var Segment = this.Segment = Base.extend({
this._handleOut = SegmentPoint.create(this, 0, 0);
},
_changed: function(point) {
if (this._path) {
// Delegate changes to affected curves if they exist
if (this._path._curves) {
var curve = this.getCurve(), other;
if (curve) {
curve._changed();
// Get the other affected curve, which is the previous one
// for _point or _handleIn changing when this segment is
// _segment1 of the curve, for all other cases it's the next
// (e.g. _handleOut or this segment == _segment2)
if (other = (curve[point == this._point
|| point == this._handleIn && curve._segment1 == this
? 'getPrevious' : 'getNext']())) {
other._changed();
}
}
}
this._path._changed();
}
},
getPoint: function() {
return this._point;
},
@ -71,7 +93,7 @@ var Segment = this.Segment = Base.extend({
// See #setPoint:
this._handleIn.set(point.x, point.y);
// Update corner accordingly
// this.corner = !this._handleIn.isParallel(this._handleOut);
// this.corner = !this._handleIn.isColinear(this._handleOut);
},
getHandleInIfSet: function() {
@ -88,7 +110,7 @@ var Segment = this.Segment = Base.extend({
// See #setPoint:
this._handleOut.set(point.x, point.y);
// Update corner accordingly
// this.corner = !this._handleIn.isParallel(this._handleOut);
// this.corner = !this._handleIn.isColinear(this._handleOut);
},
getHandleOutIfSet: function() {
@ -105,7 +127,7 @@ var Segment = this.Segment = Base.extend({
},
getCurve: function() {
if (this._path != null) {
if (this._path) {
var index = this._index;
// The last segment of an open path belongs to the last curve
if (!this._path._closed && index == this._path._segments.length - 1)
@ -208,12 +230,12 @@ var Segment = this.Segment = Base.extend({
},
toString: function() {
return '{ point: ' + this._point
+ (!this._handleIn.isZero()
? ', handleIn: ' + this._handleIn : '')
+ (this._handleOut.isZero()
? ', handleOut: ' + this._handleOut : '')
+ ' }';
var parts = [ 'point: ' + this._point ];
if (!this._handleIn.isZero())
parts.push('handleIn: ' + this._handleIn);
if (!this._handleOut.isZero())
parts.push('handleOut: ' + this._handleOut);
return '{ ' + parts.join(', ') + ' }';
},
_transformCoordinates: function(matrix, coords, change) {
@ -228,47 +250,47 @@ var Segment = this.Segment = Base.extend({
handleIn = matrix && this.getHandleInIfSet() || this._handleIn,
handleOut = matrix && this.getHandleOutIfSet() || this._handleOut,
x = point._x,
y = point._y;
y = point._y,
i = 2;
coords[0] = x;
coords[1] = y;
var index = 2;
// We need to convert handles to absolute coordinates in order
// to transform them.
if (handleIn) {
coords[index++] = handleIn._x + x;
coords[index++] = handleIn._y + y;
coords[i++] = handleIn._x + x;
coords[i++] = handleIn._y + y;
}
if (handleOut) {
coords[index++] = handleOut._x + x;
coords[index++] = handleOut._y + y;
coords[i++] = handleOut._x + x;
coords[i++] = handleOut._y + y;
}
if (matrix) {
matrix.transform(coords, 0, coords, 0, index / 2);
matrix.transform(coords, 0, coords, 0, i / 2);
x = coords[0];
y = coords[1];
if (change) {
// If change is true, we need to set the new values back
point._x = x;
point._y = y;
index = 2;
i = 2;
if (handleIn) {
handleIn._x = coords[index++] - x;
handleIn._y = coords[index++] - y;
handleIn._x = coords[i++] - x;
handleIn._y = coords[i++] - y;
}
if (handleOut) {
handleOut._x = coords[index++] - x;
handleOut._y = coords[index++] - y;
handleOut._x = coords[i++] - x;
handleOut._y = coords[i++] - y;
}
} else {
// We want to receive the results in coords, so make sure
// handleIn and out are defined too, even if they're 0
if (!handleIn) {
coords[index++] = x;
coords[index++] = y;
coords[i++] = x;
coords[i++] = y;
}
if (!handleOut) {
coords[index++] = x;
coords[index++] = y;
coords[i++] = x;
coords[i++] = y;
}
}
}

View file

@ -8,7 +8,7 @@ var SegmentPoint = Point.extend({
set: function(x, y) {
this._x = x;
this._y = y;
// this._segment._markDirty(DirtyFlags.BOUNDS);
this._segment._changed(this);
return this;
},
@ -18,7 +18,7 @@ var SegmentPoint = Point.extend({
setX: function(x) {
this._x = x;
// this._segment._markDirty(DirtyFlags.BOUNDS);
this._segment._changed(this);
},
getY: function() {
@ -27,7 +27,7 @@ var SegmentPoint = Point.extend({
setY: function(y) {
this._y = y;
// this._segment._markDirty(DirtyFlags.BOUNDS);
this._segment._changed(this);
},
setSelected: function(selected) {
@ -39,15 +39,16 @@ var SegmentPoint = Point.extend({
},
statics: {
create: function(segment, arg1, arg2) {
var point;
if (arguments.length == 2) {
point = new SegmentPoint(arg1);
} else {
point = new SegmentPoint(SegmentPoint.dont);
point._x = arg1;
point._y = arg2;
create: function(segment, x, y) {
if (y === undefined) {
// Use the normal point constructor to read in point values
var tmp = new Point(x);
x = tmp.x;
y = tmp.y;
}
var point = new SegmentPoint(SegmentPoint.dont);
point._x = x;
point._y = y;
point._segment = segment;
return point;
}