From 15b7cfec0b986875da8aa96594cd696a555956f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Sat, 7 May 2011 13:09:04 +0100 Subject: [PATCH 1/6] Shorten Item#translate(). --- src/item/Item.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/item/Item.js b/src/item/Item.js index e11d478d..8fe9dfbb 100644 --- a/src/item/Item.js +++ b/src/item/Item.js @@ -602,8 +602,7 @@ var Item = this.Item = Base.extend({ */ translate: function(delta) { var mx = new Matrix(); - mx.translate.apply(mx, arguments); - return this.transform(mx); + return this.transform(mx.translate.apply(mx, arguments)); }, /** From 1413094be2901be946c9721466e618b0001656ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Sat, 7 May 2011 13:12:46 +0100 Subject: [PATCH 2/6] Shorten PlacedSymbol#initialize(). --- src/item/PlacedSymbol.js | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/src/item/PlacedSymbol.js b/src/item/PlacedSymbol.js index b46deaa3..e65cc5b2 100644 --- a/src/item/PlacedSymbol.js +++ b/src/item/PlacedSymbol.js @@ -19,22 +19,12 @@ var PlacedSymbol = this.PlacedSymbol = Item.extend({ initialize: function(symbol, matrixOrOffset) { this.base(); - if (symbol instanceof Symbol) { - this.symbol = symbol; - } else { - this.symbol = new Symbol(symbol); - } - this._position = this.symbol._definition.getPosition(); - if (matrixOrOffset !== undefined) { - if (matrixOrOffset instanceof Matrix) { - this.matrix = matrixOrOffset; - } else { - this.matrix = new Matrix().translate(Point.read(arguments, 1)); - } - this._position = this.matrix._transformPoint(this._position); - } else { - this.matrix = new Matrix(); - } + this.symbol = symbol instanceof Symbol ? symbol : new Symbol(symbol); + this.matrix = matrixOrOffset !== undefined + ? matrixOrOffset instanceof Matrix + ? matrixOrOffset + : new Matrix().translate(Point.read(arguments, 1)) + : new Matrix(); }, _transform: function(matrix, flags) { From 53cc1cd908816f4a4b93a09f9fe64a522bfbec63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Sat, 7 May 2011 13:13:19 +0100 Subject: [PATCH 3/6] Apply #position optimisation through caching to all items, not just PlacedSymbol. --- src/item/Item.js | 11 ++++++++--- src/item/PlacedSymbol.js | 6 ------ src/path/Path.js | 4 +++- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/item/Item.js b/src/item/Item.js index 8fe9dfbb..b9fc62c8 100644 --- a/src/item/Item.js +++ b/src/item/Item.js @@ -542,14 +542,16 @@ var Item = this.Item = Base.extend({ * */ getPosition: function() { - return this.getBounds().getCenter(); + // Cache position value + if (!this._position) + this._position = this.getBounds().getCenter(); + return this._position.clone(); }, setPosition: function(point) { point = Point.read(arguments); - if (point) { + if (point) this.translate(point.subtract(this.getPosition())); - } }, /** @@ -563,6 +565,9 @@ var Item = this.Item = Base.extend({ // TODO: Call transform on chidren only if 'children' flag is provided if (this._transform) this._transform(matrix, flags); + // Transform position as well + if (this._position) + this._position = matrix._transformPoint(this._position); if (this.children) { for (var i = 0, l = this.children.length; i < l; i++) { var child = this.children[i]; diff --git a/src/item/PlacedSymbol.js b/src/item/PlacedSymbol.js index e65cc5b2..e293128c 100644 --- a/src/item/PlacedSymbol.js +++ b/src/item/PlacedSymbol.js @@ -32,12 +32,6 @@ var PlacedSymbol = this.PlacedSymbol = Item.extend({ // raster, simply preconcatenate the internal matrix with the provided // one. this.matrix.preConcatenate(matrix); - // Transform position as well - this._position = matrix._transformPoint(this._position); - }, - - getPosition: function() { - return this._position.clone(); }, getBounds: function() { diff --git a/src/path/Path.js b/src/path/Path.js index 554d9913..57d59e8b 100644 --- a/src/path/Path.js +++ b/src/path/Path.js @@ -29,10 +29,12 @@ var Path = this.Path = PathItem.extend({ }, _changed: function() { - // Clear cached values. + // TODO: Implement ChangeFlags, e.g. STROKE, COLOR, FILL, GEOMETRY, + // and only clear caches if affected by change. delete this._length; delete this._bounds; delete this._strokeBounds; + delete this._position; }, /** From dabc2b97edbe5bab99b0b916764e3ff66f1ad120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Sat, 7 May 2011 13:39:17 +0100 Subject: [PATCH 4/6] Implement change-notification in a proper way, using ChangeFlags that tell it what exactly has changed, and clearing caches accordingly. --- src/item/ChangeFlags.js | 21 +++++++++++++++++++++ src/item/Item.js | 6 ++++++ src/item/PathStyle.js | 16 +++++++++++----- src/load.js | 1 + src/paper.js | 1 + src/path/Path.js | 27 ++++++++++++++------------- src/path/Segment.js | 2 +- 7 files changed, 55 insertions(+), 19 deletions(-) create mode 100644 src/item/ChangeFlags.js diff --git a/src/item/ChangeFlags.js b/src/item/ChangeFlags.js new file mode 100644 index 00000000..301868b6 --- /dev/null +++ b/src/item/ChangeFlags.js @@ -0,0 +1,21 @@ +/* + * Paper.js + * + * This file is part of Paper.js, a JavaScript Vector Graphics Library, + * based on Scriptographer.org and designed to be largely API compatible. + * http://paperjs.org/ + * http://scriptographer.org/ + * + * Distributed under the MIT license. See LICENSE file for details. + * + * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey + * http://lehni.org/ & http://jonathanpuckey.com/ + * + * All rights reserved. + */ + +var ChangeFlags = { + PATH: 1, // Path geometry + STROKE: 2, // Stroke geometry + STYLE: 4 // Fille style or stroke color / dash +}; \ No newline at end of file diff --git a/src/item/Item.js b/src/item/Item.js index b9fc62c8..d5a7d3fc 100644 --- a/src/item/Item.js +++ b/src/item/Item.js @@ -22,6 +22,12 @@ var Item = this.Item = Base.extend({ this.setStyle(this._document.getCurrentStyle()); }, + _changed: function(flags) { + if (flags & ChangeFlags.PATH) { + delete this._position; + } + }, + /** * When passed a document, copies the item to the document, * or duplicates it within the same document. When passed an item, diff --git a/src/item/PathStyle.js b/src/item/PathStyle.js index 51867351..3e7df09e 100644 --- a/src/item/PathStyle.js +++ b/src/item/PathStyle.js @@ -17,7 +17,13 @@ var PathStyle = this.PathStyle = Base.extend(new function() { var keys = ['windingRule', 'resolution', 'strokeColor', 'strokeWidth', 'strokeCap', 'strokeJoin', 'dashOffset','dashArray', 'miterLimit', - 'strokeOverprint', 'fillColor', 'fillOverprint']; + 'strokeOverprint', 'fillColor', 'fillOverprint'], + strokeFlags = { + strokeWidth: true, + strokeCap: true, + strokeJoin: true, + miterLimit: true + }; var fields = { beans: true, @@ -63,10 +69,10 @@ var PathStyle = this.PathStyle = Base.extend(new function() { var old = this['_' + key]; if (old != value && !(old && old.equals && old.equals(value))) { this['_' + key] = value; - // TODO: Tell _item what exactly has changed. Maybe introduce - // ChangeFlags, e.g. STROKE, COLOR, FILL, GEOMETRY, etc? - if (this._item && this._item._changed) - this._item._changed(); + if (this._item) { + this._item._changed(ChangeFlags.STYLE + | (strokeFlags[key] ? ChangeFlags.STROKE : 0)); + } } } return this; diff --git a/src/load.js b/src/load.js index 784e1a45..2de4c0d9 100644 --- a/src/load.js +++ b/src/load.js @@ -36,6 +36,7 @@ var sources = [ 'src/document/Document.js', 'src/document/Symbol.js', + 'src/item/ChangeFlags.js', 'src/item/Item.js', 'src/item/Group.js', 'src/item/Layer.js', diff --git a/src/paper.js b/src/paper.js index 7cc38f9e..77e5dcef 100644 --- a/src/paper.js +++ b/src/paper.js @@ -100,6 +100,7 @@ Base.inject({ //#include "document/Document.js" //#include "document/Symbol.js" +//#include "item/ChangeFlags.js" //#include "item/Item.js" //#include "item/Group.js" //#include "item/Layer.js" diff --git a/src/path/Path.js b/src/path/Path.js index 57d59e8b..78074654 100644 --- a/src/path/Path.js +++ b/src/path/Path.js @@ -28,13 +28,15 @@ var Path = this.Path = PathItem.extend({ || typeof segments[0] !== 'object' ? arguments : segments); }, - _changed: function() { - // TODO: Implement ChangeFlags, e.g. STROKE, COLOR, FILL, GEOMETRY, - // and only clear caches if affected by change. - delete this._length; - delete this._bounds; - delete this._strokeBounds; - delete this._position; + _changed: function(flags) { + if (flags & ChangeFlags.PATH) { + delete this._length; + delete this._bounds; + delete this._position; + delete this._strokeBounds; + } else if (flags & ChangeFlags.STROKE) { + delete this._strokeBounds; + } }, /** @@ -114,7 +116,7 @@ var Path = this.Path = PathItem.extend({ this._curves[i = length - 1] = Curve.create(this, this._segments[i], this._segments[0]); } - this._changed(); + this._changed(ChangeFlags.PATH); } }, @@ -129,7 +131,7 @@ var Path = this.Path = PathItem.extend({ this._segments[i]._transformCoordinates(matrix, coords, true); } } - this._changed(); + this._changed(ChangeFlags.PATH); }, /** @@ -177,7 +179,7 @@ var Path = this.Path = PathItem.extend({ if (curve) curve._segment1 = segments[index + amount]; } - this._changed(); + this._changed(ChangeFlags.PATH); return segs; }, @@ -261,7 +263,7 @@ var Path = this.Path = PathItem.extend({ if (last && this._closed && (curve = curves[curves.length - 1])) curve._segment2 = segments[0]; } - this._changed(); + this._changed(ChangeFlags.PATH); return removed; }, @@ -306,7 +308,6 @@ var Path = this.Path = PathItem.extend({ segment._handleIn = segment._handleOut; segment._handleOut = handleIn; } - this._changed(); }, join: function(path) { @@ -341,7 +342,7 @@ var Path = this.Path = PathItem.extend({ last1.remove(); this.setClosed(true); } - this._changed(); + this._changed(ChangeFlags.PATH); return true; } return false; diff --git a/src/path/Segment.js b/src/path/Segment.js index a2672f78..d4145173 100644 --- a/src/path/Segment.js +++ b/src/path/Segment.js @@ -69,7 +69,7 @@ var Segment = this.Segment = Base.extend({ } } } - this._path._changed(); + this._path._changed(ChangeFlags.PATH); } }, From 430a8fb2908ac1bd26416fb84c44f0206add5024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Sat, 7 May 2011 13:39:40 +0100 Subject: [PATCH 5/6] Do not pass document as the item for Document#currentStyle. --- src/document/Document.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/document/Document.js b/src/document/Document.js index 9759bce1..df689f1e 100644 --- a/src/document/Document.js +++ b/src/document/Document.js @@ -98,7 +98,7 @@ var Document = this.Document = Base.extend({ }, setCurrentStyle: function(style) { - this._currentStyle = PathStyle.create(this, style); + this._currentStyle = PathStyle.create(null, style); }, activate: function() { From 1e1a58e540dde8446137957de19e3aa3280da5bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Sat, 7 May 2011 13:44:38 +0100 Subject: [PATCH 6/6] Correct case on example files. --- examples/Animated/{animatedStar.html => AnimatedStar.html} | 0 examples/Animated/{lines.html => Lines.html} | 0 examples/Scripts/{arcTo.html => Arcs.html} | 0 examples/Scripts/{circle.html => Circle.html} | 0 examples/Scripts/{letter.html => Letter.html} | 0 examples/Scripts/{roundRectangle.html => RoundRectangle.html} | 0 examples/Scripts/{strokeBounds.html => StrokeBounds.html} | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename examples/Animated/{animatedStar.html => AnimatedStar.html} (100%) rename examples/Animated/{lines.html => Lines.html} (100%) rename examples/Scripts/{arcTo.html => Arcs.html} (100%) rename examples/Scripts/{circle.html => Circle.html} (100%) rename examples/Scripts/{letter.html => Letter.html} (100%) rename examples/Scripts/{roundRectangle.html => RoundRectangle.html} (100%) rename examples/Scripts/{strokeBounds.html => StrokeBounds.html} (100%) diff --git a/examples/Animated/animatedStar.html b/examples/Animated/AnimatedStar.html similarity index 100% rename from examples/Animated/animatedStar.html rename to examples/Animated/AnimatedStar.html diff --git a/examples/Animated/lines.html b/examples/Animated/Lines.html similarity index 100% rename from examples/Animated/lines.html rename to examples/Animated/Lines.html diff --git a/examples/Scripts/arcTo.html b/examples/Scripts/Arcs.html similarity index 100% rename from examples/Scripts/arcTo.html rename to examples/Scripts/Arcs.html diff --git a/examples/Scripts/circle.html b/examples/Scripts/Circle.html similarity index 100% rename from examples/Scripts/circle.html rename to examples/Scripts/Circle.html diff --git a/examples/Scripts/letter.html b/examples/Scripts/Letter.html similarity index 100% rename from examples/Scripts/letter.html rename to examples/Scripts/Letter.html diff --git a/examples/Scripts/roundRectangle.html b/examples/Scripts/RoundRectangle.html similarity index 100% rename from examples/Scripts/roundRectangle.html rename to examples/Scripts/RoundRectangle.html diff --git a/examples/Scripts/strokeBounds.html b/examples/Scripts/StrokeBounds.html similarity index 100% rename from examples/Scripts/strokeBounds.html rename to examples/Scripts/StrokeBounds.html