Implement an optimization in _changed() notifications where not all curves need to updated if only segments change that already have told their curves about the change.

This commit is contained in:
Jürg Lehni 2014-03-17 14:35:33 +01:00
parent 72ba453ba2
commit 0fe52a7d39
3 changed files with 27 additions and 19 deletions

View file

@ -13,23 +13,26 @@
var ChangeFlag = {
// Anything affecting the appearance of an item, including GEOMETRY,
// STROKE, STYLE and ATTRIBUTE (except for the invisible ones: locked, name)
APPEARANCE: 1,
APPEARANCE: 0x1,
// Change in item hierarchy
HIERARCHY: 2,
HIERARCHY: 0x2,
// Item geometry (path, bounds)
GEOMETRY: 4,
GEOMETRY: 0x4,
// Only segment(s) have changed, and affected curves have alredy been
// notified. This is to implement an optimization in _changed() calls.
SEGMENTS: 0x8,
// Stroke geometry (excluding color)
STROKE: 8,
STROKE: 0x10,
// Fill style or stroke color / dash
STYLE: 16,
STYLE: 0x20,
// Item attributes: visible, blendMode, locked, name, opacity, clipMask ...
ATTRIBUTE: 32,
ATTRIBUTE: 0x40,
// Text content
CONTENT: 64,
CONTENT: 0x80,
// Raster pixels
PIXELS: 128,
PIXELS: 0x100,
// Clipping in one of the child items
CLIPPING: 256
CLIPPING: 0x200
};
// Shortcuts to often used ChangeFlag values including APPEARANCE
@ -39,6 +42,7 @@ var Change = {
HIERARCHY: ChangeFlag.HIERARCHY | ChangeFlag.GEOMETRY
| ChangeFlag.APPEARANCE,
GEOMETRY: ChangeFlag.GEOMETRY | ChangeFlag.APPEARANCE,
SEGMENTS: ChangeFlag.SEGMENTS | ChangeFlag.GEOMETRY | ChangeFlag.APPEARANCE,
STROKE: ChangeFlag.STROKE | ChangeFlag.STYLE | ChangeFlag.APPEARANCE,
STYLE: ChangeFlag.STYLE | ChangeFlag.APPEARANCE,
ATTRIBUTE: ChangeFlag.ATTRIBUTE | ChangeFlag.APPEARANCE,

View file

@ -138,14 +138,19 @@ var Path = PathItem.extend(/** @lends Path# */{
_changed: function _changed(flags) {
_changed.base.call(this, flags);
if (flags & /*#=*/ ChangeFlag.GEOMETRY) {
// Clear cached native Path
(this._compound ? this._parent : this)._currentPath = undefined;
// Clear cached native Path. Clear on the parent too, for
// CompoundPaths and Groups (ab)used as clipping paths.
this._currentPath = undefined;
var parent = this._parent;
if (parent)
parent._currentPath = undefined;
// Clockwise state becomes undefined as soon as geometry changes.
this._length = this._clockwise = undefined;
// Curves are no longer valid
if (this._curves) {
// Only notify all curves if we're not told that only one Segment
// has changed and took already care of notifications.
if (this._curves && !(flags & /*#=*/ ChangeFlag.SEGMENTS)) {
for (var i = 0, l = this._curves.length; i < l; i++)
this._curves[i]._changed(/*#=*/ Change.GEOMETRY);
this._curves[i]._changed();
}
// Clear cached curves used for winding direction and containment
// calculation.
@ -327,7 +332,7 @@ var Path = PathItem.extend(/** @lends Path# */{
this._curves[length - 1] = new Curve(this,
this._segments[length - 1], this._segments[0]);
}
this._changed(/*#=*/ Change.GEOMETRY);
this._changed(/*#=*/ Change.SEGMENTS);
}
},
@ -414,7 +419,7 @@ var Path = PathItem.extend(/** @lends Path# */{
// Adjust segments for the curves before and after the removed ones
this._adjustCurves(from, to);
}
this._changed(/*#=*/ Change.GEOMETRY);
this._changed(/*#=*/ Change.SEGMENTS);
return segs;
},
@ -738,7 +743,7 @@ var Path = PathItem.extend(/** @lends Path# */{
// Adjust segments for the curves before and after the removed ones
this._adjustCurves(index, index);
}
this._changed(/*#=*/ Change.GEOMETRY);
this._changed(/*#=*/ Change.SEGMENTS);
return removed;
},
@ -1280,7 +1285,6 @@ var Path = PathItem.extend(/** @lends Path# */{
last1.remove();
this.setClosed(true);
}
this._changed(/*#=*/ Change.GEOMETRY);
return true;
}
return false;

View file

@ -170,7 +170,7 @@ var Segment = Base.extend(/** @lends Segment# */{
&& (curveOut = curves[index]))
curveOut._changed();
}
path._changed(/*#=*/ Change.GEOMETRY);
path._changed(/*#=*/ Change.SEGMENTS);
},
/**