Core: Renamed Symbol and PlacedSymbol classes and properties.

- Symbol -> SymbolDefinition
- PlacedSymbol -> SymbolItem
- Symbol#definition -> SymbolDefinition#item
- PlacedSymbol#symbol -> SymbolItem#definition
- Deprecate Project#symbols

Closes 
This commit is contained in:
Jürg Lehni 2016-01-31 16:52:51 +01:00
parent 5cbc8ef775
commit bc2729683c
28 changed files with 212 additions and 186 deletions

View file

@ -17,7 +17,7 @@
strokeColor: 'black' strokeColor: 'black'
}); });
var symbol = new Symbol(path); var symbol = new SymbolDefinition(path);
// Place the instances of the symbol: // Place the instances of the symbol:
for (var i = 0; i < count; i++) { for (var i = 0; i < count; i++) {

View file

@ -103,7 +103,7 @@
var explosionPath = new Path.Circle(new Point(), 1); var explosionPath = new Path.Circle(new Point(), 1);
explosionPath.fillColor = 'white'; explosionPath.fillColor = 'white';
explosionPath.strokeColor = null; explosionPath.strokeColor = null;
return new Symbol(explosionPath); return new SymbolDefinition(explosionPath);
} }
}; };
@ -322,7 +322,7 @@
var rockSymbols = []; var rockSymbols = [];
for (var i = 0; i < shapes.length; i++) { for (var i = 0; i < shapes.length; i++) {
rockSymbols[i] = new Symbol(shapes[i]); rockSymbols[i] = new SymbolDefinition(shapes[i]);
} }
var explosions = new Group(); var explosions = new Group();

View file

@ -17,7 +17,7 @@
destination: path.bounds.rightCenter destination: path.bounds.rightCenter
} }
var symbol = new Symbol(path); var symbol = new SymbolDefinition(path);
symbol.place(view.center); symbol.place(view.center);
window._json = project.exportJSON(); window._json = project.exportJSON();

View file

@ -11,7 +11,7 @@
to: [200, 100], to: [200, 100],
fillColor: 'red' fillColor: 'red'
}); });
var symbol = new Symbol(ellipse); var symbol = new SymbolDefinition(ellipse);
var p1 = symbol.place([100, 100]); var p1 = symbol.place([100, 100]);
p1.rotate(45); p1.rotate(45);
var p2 = symbol.place([300, 200]); var p2 = symbol.place([300, 200]);

View file

@ -12,7 +12,7 @@ new Path.Rectangle(view.bounds).fillColor = 'black';
var head = new Path.Ellipse([0, 0], [13, 8]); var head = new Path.Ellipse([0, 0], [13, 8]);
head.fillColor = 'white'; head.fillColor = 'white';
head.strokeColor = null; head.strokeColor = null;
var headSymbol = new Symbol(head); var headSymbol = new SymbolDefinition(head);
var size = view.size; var size = view.size;

View file

@ -53,7 +53,7 @@
strokeColor: 'black' strokeColor: 'black'
}); });
var symbol = new Symbol(path); var symbol = new SymbolDefinition(path);
// Place the instances of the symbol: // Place the instances of the symbol:
for (var i = 0; i < count; i++) { for (var i = 0; i < count; i++) {

View file

@ -13,7 +13,7 @@
to: [200, 100], to: [200, 100],
fillColor: 'red' fillColor: 'red'
}); });
var symbol = new Symbol(ellipse); var symbol = new SymbolDefinition(ellipse);
var p1 = symbol.place([100, 100]); var p1 = symbol.place([100, 100]);
p1.rotate(45); p1.rotate(45);
var p2 = symbol.place([300, 200]); var p2 = symbol.place([300, 200]);

View file

@ -21,8 +21,8 @@
var image = new Raster('ducky'); var image = new Raster('ducky');
image.fitBounds(background.bounds); image.fitBounds(background.bounds);
background = new Symbol(background); background = new SymbolDefinition(background);
image = new Symbol(image); image = new SymbolDefinition(image);
var all = new Group(); var all = new Group();
function makeExample(point, blendMode) { function makeExample(point, blendMode) {

View file

@ -26,7 +26,10 @@ paper = new (PaperScope.inject(Base.exports, {
DomElement: DomElement, DomElement: DomElement,
// Export jsdom document and window too, for Node.js // Export jsdom document and window too, for Node.js
document: document, document: document,
window: window window: window,
// TODO: Remove in 2017 (deprecated January 2016):
Symbol: SymbolDefinition,
PlacedSymbol: SymbolItem
}))(); }))();
// If we're on node, require some additional functionality now before finishing: // If we're on node, require some additional functionality now before finishing:

View file

@ -109,7 +109,7 @@ var HitResult = Base.extend(/** @lends HitResult# */{
getOptions: function(options) { getOptions: function(options) {
return new Base({ return new Base({
// Type of item, for instanceof check: Group, Layer, Path, // Type of item, for instanceof check: Group, Layer, Path,
// CompoundPath, Shape, Raster, PlacedSymbol, ... // CompoundPath, Shape, Raster, SymbolItem, ...
type: null, type: null,
// Tolerance // Tolerance
tolerance: paper.settings.hitTolerance, tolerance: paper.settings.hitTolerance,

View file

@ -46,7 +46,7 @@ var Item = Base.extend(Emitter, /** @lends Item# */{
_class: 'Item', _class: 'Item',
// All items apply their matrix by default. // All items apply their matrix by default.
// Exceptions are Raster, PlacedSymbol, Clip and Shape. // Exceptions are Raster, SymbolItem, Clip and Shape.
_applyMatrix: true, _applyMatrix: true,
_canApplyMatrix: true, _canApplyMatrix: true,
_canScaleStroke: false, _canScaleStroke: false,
@ -267,7 +267,7 @@ new function() { // // Scope to inject various item event handlers
* @name Item#className * @name Item#className
* @type String * @type String
* @values 'Group', 'Layer', 'Path', 'CompoundPath', 'Shape', 'Raster', * @values 'Group', 'Layer', 'Path', 'CompoundPath', 'Shape', 'Raster',
* 'PlacedSymbol', 'PointText' * 'SymbolItem', 'PointText'
*/ */
/** /**
@ -833,7 +833,7 @@ new function() { // // Scope to inject various item event handlers
_getBounds: function(getter, matrix, cacheItem, internal) { _getBounds: function(getter, matrix, cacheItem, internal) {
// NOTE: We cannot cache these results here, since we do not get // NOTE: We cannot cache these results here, since we do not get
// _changed() notifications here for changing geometry in children. // _changed() notifications here for changing geometry in children.
// But cacheName is used in sub-classes such as PlacedSymbol and Raster. // But cacheName is used in sub-classes such as SymbolItem and Raster.
var children = this._children; var children = this._children;
// TODO: What to return if nothing is defined, e.g. empty Groups? // TODO: What to return if nothing is defined, e.g. empty Groups?
// Scriptographer behaves weirdly then too. // Scriptographer behaves weirdly then too.
@ -1702,7 +1702,7 @@ new function() { // // Scope to inject various item event handlers
* {Number} the tolerance of the hit-test * {Number} the tolerance of the hit-test
* @option options.class {Function} only hit-test again a certain item class * @option options.class {Function} only hit-test again a certain item class
* and its sub-classes: {@values Group, Layer, Path, CompoundPath, * and its sub-classes: {@values Group, Layer, Path, CompoundPath,
* Shape, Raster, PlacedSymbol, PointText, ...} * Shape, Raster, SymbolItem, PointText, ...}
* @option options.fill {Boolean} hit-test the fill of items * @option options.fill {Boolean} hit-test the fill of items
* @option options.stroke {Boolean} hit-test the stroke of path and shape * @option options.stroke {Boolean} hit-test the stroke of path and shape
* items, taking into account the setting of stroke color and width * items, taking into account the setting of stroke color and width
@ -3182,7 +3182,7 @@ new function() { // // Scope to inject various item event handlers
_matrix.prepend(matrix); _matrix.prepend(matrix);
// Call #_transformContent() now, if we need to directly apply the // Call #_transformContent() now, if we need to directly apply the
// internal _matrix transformations to the item's content. // internal _matrix transformations to the item's content.
// Application is not possible on Raster, PointText, PlacedSymbol, since // Application is not possible on Raster, PointText, SymbolItem, since
// the matrix is where the actual transformation state is stored. // the matrix is where the actual transformation state is stored.
if (applyMatrix = applyMatrix && this._transformContent(_matrix, if (applyMatrix = applyMatrix && this._transformContent(_matrix,
_applyRecursively, _setApplyMatrix)) { _applyRecursively, _setApplyMatrix)) {

View file

@ -55,7 +55,6 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{
this._children = []; this._children = [];
this._namedChildren = {}; this._namedChildren = {};
this._activeLayer = null; this._activeLayer = null;
this.symbols = [];
this._currentStyle = new Style(null, null, this); this._currentStyle = new Style(null, null, this);
// If no view is provided, we create a 1x1 px canvas view just so we // If no view is provided, we create a 1x1 px canvas view just so we
// have something to do size calculations with. // have something to do size calculations with.
@ -121,14 +120,12 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{
*/ */
/** /**
* Clears the project by removing all {@link Project#layers} and * Clears the project by removing all {@link Project#layers}.
* {@link Project#symbols}.
*/ */
clear: function() { clear: function() {
var children = this._children; var children = this._children;
for (var i = children.length - 1; i >= 0; i--) for (var i = children.length - 1; i >= 0; i--)
children[i].remove(); children[i].remove();
this.symbols = [];
}, },
/** /**
@ -244,11 +241,35 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{
}, },
/** /**
* The symbols contained within the project. * The symbol definitions shared by all symbol items contained place ind
* project.
* *
* @name Project#symbols * @bean
* @type Symbol[] * @type SymbolDefinition[]
*/ */
getSymbolDefinitions: function() {
var definitions = [],
ids = {};
this.getItems({
class: SymbolItem,
match: function(item) {
var definition = item._definition,
id = definition._id;
if (!ids[id]) {
ids[id] = true;
definitions.push(definition);
}
return false; // No need to collect them.
}
});
return definitions;
},
/**
* @bean
* @deprecated use {@link #getSymbolDefinitions()} instead.
*/
getSymbols: 'getSymbolDefinitions',
/** /**
* The selected items contained within the project. * The selected items contained within the project.
@ -318,7 +339,7 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{
* {Number} the tolerance of the hit-test * {Number} the tolerance of the hit-test
* @option options.class {Function} only hit-test again a certain item class * @option options.class {Function} only hit-test again a certain item class
* and its sub-classes: {@values Group, Layer, Path, CompoundPath, * and its sub-classes: {@values Group, Layer, Path, CompoundPath,
* Shape, Raster, PlacedSymbol, PointText, ...} * Shape, Raster, SymbolItem, PointText, ...}
* @option options.fill {Boolean} hit-test the fill of items * @option options.fill {Boolean} hit-test the fill of items
* @option options.stroke {Boolean} hit-test the stroke of path items, * @option options.stroke {Boolean} hit-test the stroke of path items,
* taking into account the setting of stroke color and width * taking into account the setting of stroke color and width

View file

@ -31,7 +31,7 @@ var Raster = Item.extend(/** @lends Raster# */{
}, },
// TODO: Implement type, width, height. // TODO: Implement type, width, height.
// TODO: Have PlacedSymbol & Raster inherit from a shared class? // TODO: Have SymbolItem & Raster inherit from a shared class?
/** /**
* Creates a new raster item from the passed argument, and places it in the * Creates a new raster item from the passed argument, and places it in the
* active layer. `object` can either be a DOM Image, a Canvas, or a string * active layer. `object` can either be a DOM Image, a Canvas, or a string
@ -206,7 +206,7 @@ var Raster = Item.extend(/** @lends Raster# */{
/** /**
* @private * @private
* @bean * @bean
* @deprecated use {@link #resolution} instead. * @deprecated use {@link #getResolution()} instead.
*/ */
getPpi: '#getResolution', getPpi: '#getResolution',

View file

@ -64,7 +64,7 @@ var Shape = Item.extend(/** @lends Shape# */{
/** /**
* @private * @private
* @bean * @bean
* @deprecated use {@link #type} instead. * @deprecated use {@link #getType()} instead.
*/ */
getShape: '#getType', getShape: '#getType',
setShape: '#setType', setShape: '#setType',

View file

@ -11,7 +11,7 @@
*/ */
/** /**
* @name Symbol * @name SymbolDefinition
* *
* @class Symbols allow you to place multiple instances of an item in your * @class Symbols allow you to place multiple instances of an item in your
* project. This can save memory, since all instances of a symbol simply refer * project. This can save memory, since all instances of a symbol simply refer
@ -19,14 +19,14 @@
* internal properties such as segment lists and gradient positions don't need * internal properties such as segment lists and gradient positions don't need
* to be updated with every transformation. * to be updated with every transformation.
*/ */
var Symbol = Base.extend(/** @lends Symbol# */{ var SymbolDefinition = Base.extend(/** @lends SymbolDefinition# */{
_class: 'Symbol', _class: 'SymbolDefinition',
/** /**
* Creates a Symbol item. * Creates a Symbol definition.
* *
* @param {Item} item the source item which is copied as the definition of * @param {Item} item the source item which is removed from the scene graph
* the symbol * and becomes the symbol's definition.
* @param {Boolean} [dontCenter=false] * @param {Boolean} [dontCenter=false]
* *
* @example {@paperscript split=true height=240} * @example {@paperscript split=true height=240}
@ -37,16 +37,13 @@ var Symbol = Base.extend(/** @lends Symbol# */{
* strokeColor: 'black' * strokeColor: 'black'
* }; * };
* *
* // Create a symbol from the path: * // Create a symbol definition from the path:
* var symbol = new Symbol(path); * var definition = new SymbolDefinition(path);
* *
* // Remove the path: * // Place 100 instances of the symbol definition:
* path.remove();
*
* // Place 100 instances of the symbol:
* for (var i = 0; i < 100; i++) { * for (var i = 0; i < 100; i++) {
* // Place an instance of the symbol in the project: * // Place an instance of the symbol definition in the project:
* var instance = symbol.place(); * var instance = definition.place();
* *
* // Move the instance to a random position within the view: * // Move the instance to a random position within the view:
* instance.position = Point.random() * view.size; * instance.position = Point.random() * view.size;
@ -59,31 +56,26 @@ var Symbol = Base.extend(/** @lends Symbol# */{
* instance.scale(0.25 + Math.random() * 0.75); * instance.scale(0.25 + Math.random() * 0.75);
* } * }
*/ */
initialize: function Symbol(item, dontCenter) { initialize: function SymbolDefinition(item, dontCenter) {
// Define this Symbols's unique id.
this._id = UID.get(); this._id = UID.get();
this.project = paper.project; this.project = paper.project;
this.project.symbols.push(this);
if (item) if (item)
this.setDefinition(item, dontCenter); this.setItem(item, dontCenter);
}, },
_serialize: function(options, dictionary) { _serialize: function(options, dictionary) {
return dictionary.add(this, function() { return dictionary.add(this, function() {
return Base.serialize([this._class, this._definition], return Base.serialize([this._class, this._item],
options, false, dictionary); options, false, dictionary);
}); });
}, },
// TODO: Symbol#remove()
// TODO: Symbol#name (accessible by name through project#symbols)
/** /**
* The project that this symbol belongs to. * The project that this symbol belongs to.
* *
* @type Project * @type Project
* @readonly * @readonly
* @name Symbol#project * @name SymbolDefinition#project
*/ */
/** /**
@ -101,23 +93,23 @@ var Symbol = Base.extend(/** @lends Symbol# */{
}, },
/** /**
* The symbol definition. * The item used as the symbol's definition.
* *
* @bean * @bean
* @type Item * @type Item
*/ */
getDefinition: function() { getItem: function() {
return this._definition; return this._item;
}, },
setDefinition: function(item, _dontCenter) { setItem: function(item, _dontCenter) {
// Make sure we're not stealing another symbol's definition // Make sure we're not stealing another symbol's definition
if (item._parentSymbol) if (item._parentSymbol)
item = item.clone(); item = item.clone();
// Remove previous definition's reference to this symbol // Remove previous definition's reference to this symbol
if (this._definition) if (this._item)
this._definition._parentSymbol = null; this._item._parentSymbol = null;
this._definition = item; this._item = item;
// Remove item from DOM, as it's embedded in Symbol now. // Remove item from DOM, as it's embedded in Symbol now.
item.remove(); item.remove();
item.setSelected(false); item.setSelected(false);
@ -128,14 +120,21 @@ var Symbol = Base.extend(/** @lends Symbol# */{
this._changed(/*#=*/Change.GEOMETRY); this._changed(/*#=*/Change.GEOMETRY);
}, },
/**
* @bean
* @deprecated use {@link #getItem()} instead.
*/
getDefinition: '#getItem',
setDefinition: '#setItem',
/** /**
* Places in instance of the symbol in the project. * Places in instance of the symbol in the project.
* *
* @param {Point} [position] the position of the placed symbol * @param {Point} [position] the position of the placed symbol
* @return {PlacedSymbol} * @return {SymbolItem}
*/ */
place: function(position) { place: function(position) {
return new PlacedSymbol(this, position); return new SymbolItem(this, position);
}, },
/** /**
@ -144,7 +143,7 @@ var Symbol = Base.extend(/** @lends Symbol# */{
* @return {Symbol} * @return {Symbol}
*/ */
clone: function() { clone: function() {
return new Symbol(this._definition.clone(false)); return new SymbolDefinition(this._item.clone(false));
}, },
/** /**
@ -155,7 +154,7 @@ var Symbol = Base.extend(/** @lends Symbol# */{
*/ */
equals: function(symbol) { equals: function(symbol) {
return symbol === this return symbol === this
|| symbol && this.definition.equals(symbol.definition) || symbol && this._item.equals(symbol._item)
|| false; || false;
} }
}); });

View file

@ -11,18 +11,18 @@
*/ */
/** /**
* @name PlacedSymbol * @name SymbolItem
* *
* @class A PlacedSymbol represents an instance of a symbol which has been * @class A symbol item represents an instance of a symbol which has been
* placed in a Paper.js project. * placed in a Paper.js project.
* *
* @extends Item * @extends Item
*/ */
var PlacedSymbol = Item.extend(/** @lends PlacedSymbol# */{ var SymbolItem = Item.extend(/** @lends SymbolItem# */{
_class: 'PlacedSymbol', _class: 'SymbolItem',
_applyMatrix: false, _applyMatrix: false,
_canApplyMatrix: false, _canApplyMatrix: false,
// PlacedSymbol uses strokeBounds for bounds // SymbolItem uses strokeBounds for bounds
_boundsGetter: { getBounds: 'getStrokeBounds' }, _boundsGetter: { getBounds: 'getStrokeBounds' },
_boundsSelected: true, _boundsSelected: true,
_serializeFields: { _serializeFields: {
@ -30,9 +30,9 @@ var PlacedSymbol = Item.extend(/** @lends PlacedSymbol# */{
}, },
/** /**
* Creates a new PlacedSymbol Item. * Creates a new symbol item.
* *
* @param {Symbol} symbol the symbol to place * @param {Symbol} definition the symbol definition to place
* @param {Point} [point] the center point of the placed symbol * @param {Point} [point] the center point of the placed symbol
* *
* @example {@paperscript split=true height=240} * @example {@paperscript split=true height=240}
@ -47,16 +47,13 @@ var PlacedSymbol = Item.extend(/** @lends PlacedSymbol# */{
* strokeColor: 'black' * strokeColor: 'black'
* }); * });
* *
* // Create a symbol from the path: * // Create a symbol definition from the path:
* var symbol = new Symbol(path); * var definition = new SymbolDefinition(path);
*
* // Remove the path:
* path.remove();
* *
* // Place 100 instances of the symbol: * // Place 100 instances of the symbol:
* for (var i = 0; i < 100; i++) { * for (var i = 0; i < 100; i++) {
* // Place an instance of the symbol in the project: * // Place an instance of the symbol in the project:
* var instance = new PlacedSymbol(symbol); * var instance = new SymbolItem(definition);
* *
* // Move the instance to a random position within the view: * // Move the instance to a random position within the view:
* instance.position = Point.random() * view.size; * instance.position = Point.random() * view.size;
@ -69,7 +66,7 @@ var PlacedSymbol = Item.extend(/** @lends PlacedSymbol# */{
* instance.scale(0.25 + Math.random() * 0.75); * instance.scale(0.25 + Math.random() * 0.75);
* } * }
*/ */
initialize: function PlacedSymbol(arg0, arg1) { initialize: function SymbolItem(arg0, arg1) {
// Support two forms of item initialization: Passing one object literal // Support two forms of item initialization: Passing one object literal
// describing all the different properties to be set, or a symbol (arg0) // describing all the different properties to be set, or a symbol (arg0)
// and a point where it should be placed (arg1). // and a point where it should be placed (arg1).
@ -77,47 +74,56 @@ var PlacedSymbol = Item.extend(/** @lends PlacedSymbol# */{
// Otherwise we need to set symbol from arg0. // Otherwise we need to set symbol from arg0.
if (!this._initialize(arg0, if (!this._initialize(arg0,
arg1 !== undefined && Point.read(arguments, 1))) arg1 !== undefined && Point.read(arguments, 1)))
this.setSymbol(arg0 instanceof Symbol ? arg0 : new Symbol(arg0)); this.setDefinition(arg0 instanceof SymbolDefinition ?
arg0 : new SymbolDefinition(arg0));
}, },
_equals: function(item) { _equals: function(item) {
return this._symbol === item._symbol; // TODO: Compare position too!
return this._definition === item._definition;
}, },
copyContent: function(source) { copyContent: function(source) {
this.setSymbol(source._symbol); this.setDefinition(source._definition);
}, },
/** /**
* The symbol that the placed symbol refers to. * The symbol definition that the placed symbol refers to.
* *
* @bean * @bean
* @type Symbol * @type SymbolDefinition
*/ */
getSymbol: function() { getDefinition: function() {
return this._symbol; return this._definition;
}, },
setSymbol: function(symbol) { setDefinition: function(definition) {
this._symbol = symbol; this._definition = definition;
this._changed(/*#=*/Change.GEOMETRY); this._changed(/*#=*/Change.GEOMETRY);
}, },
/**
* @bean
* @deprecated use {@link #getDefinition()} instead.
*/
getSymbol: '#getDefinition',
setSymbol: '#setDefinition',
isEmpty: function() { isEmpty: function() {
return this._symbol._definition.isEmpty(); return this._definition._item.isEmpty();
}, },
_getBounds: function(getter, matrix, cacheItem, internal) { _getBounds: function(getter, matrix, cacheItem, internal) {
var definition = this.symbol._definition; var item = this._definition._item;
// Redirect the call to the symbol definition to calculate the bounds // Redirect the call to the definition item to calculate the bounds.
return definition._getCachedBounds(getter, return item._getCachedBounds(getter,
matrix && matrix.appended(definition._matrix), matrix && matrix.appended(item._matrix),
cacheItem, internal); cacheItem, internal);
}, },
_hitTestSelf: function(point, options) { _hitTestSelf: function(point, options) {
var res = this._symbol._definition._hitTest(point, options); var res = this._definition._item._hitTest(point, options);
// TODO: When the symbol's definition is a path, should hitResult // TODO: When the symbol's definition is a path, should hitResult
// contain information like HitResult#curve? // contain information like HitResult#curve?
if (res) if (res)
@ -126,8 +132,8 @@ var PlacedSymbol = Item.extend(/** @lends PlacedSymbol# */{
}, },
_draw: function(ctx, param) { _draw: function(ctx, param) {
this.symbol._definition.draw(ctx, param); this._definition._item.draw(ctx, param);
} }
// TODO: PlacedSymbol#embed() // TODO: SymbolItem#embed()
}); });

View file

@ -56,15 +56,14 @@ var paper = function(window, undefined) {
/*#*/ include('basic/Matrix.js'); /*#*/ include('basic/Matrix.js');
/*#*/ include('basic/Line.js'); /*#*/ include('basic/Line.js');
/*#*/ include('project/Project.js'); /*#*/ include('item/Project.js');
/*#*/ include('project/Symbol.js');
/*#*/ include('item/Item.js'); /*#*/ include('item/Item.js');
/*#*/ include('item/Group.js'); /*#*/ include('item/Group.js');
/*#*/ include('item/Layer.js'); /*#*/ include('item/Layer.js');
/*#*/ include('item/Shape.js'); /*#*/ include('item/Shape.js');
/*#*/ include('item/Raster.js'); /*#*/ include('item/Raster.js');
/*#*/ include('item/PlacedSymbol.js'); /*#*/ include('item/SymbolItem.js');
/*#*/ include('item/SymbolDefinition.js');
/*#*/ include('item/HitResult.js'); /*#*/ include('item/HitResult.js');
/*#*/ include('path/Segment.js'); /*#*/ include('path/Segment.js');

View file

@ -323,7 +323,7 @@ var Style = Base.extend(new function() {
/** /**
* @bean * @bean
* @private * @private
* @deprecated use {@link #fontFamily} instead. * @deprecated use {@link #getFontFamily()} instead.
*/ */
getFont: '#getFontFamily', getFont: '#getFontFamily',
setFont: '#setFontFamily', setFont: '#setFontFamily',

View file

@ -187,20 +187,20 @@ new function() {
return createElement('path', attrs); return createElement('path', attrs);
} }
function exportPlacedSymbol(item, options) { function exportSymbolItem(item, options) {
var attrs = getTransform(item._matrix, true), var attrs = getTransform(item._matrix, true),
symbol = item.getSymbol(), definition = item._definition,
symbolNode = getDefinition(symbol, 'symbol'), node = getDefinition(definition, 'symbol'),
definition = symbol.getDefinition(), definitionItem = definition._item,
bounds = definition.getBounds(); bounds = definitionItem.getBounds();
if (!symbolNode) { if (!node) {
symbolNode = createElement('symbol', { node = createElement('symbol', {
viewBox: formatter.rectangle(bounds) viewBox: formatter.rectangle(bounds)
}); });
symbolNode.appendChild(exportSVG(definition, options)); node.appendChild(exportSVG(definitionItem, options));
setDefinition(symbol, symbolNode, 'symbol'); setDefinition(definition, node, 'symbol');
} }
attrs.href = '#' + symbolNode.id; attrs.href = '#' + node.id;
attrs.x += bounds.x; attrs.x += bounds.x;
attrs.y += bounds.y; attrs.y += bounds.y;
attrs.width = formatter.number(bounds.width); attrs.width = formatter.number(bounds.width);
@ -278,7 +278,7 @@ new function() {
Path: exportPath, Path: exportPath,
Shape: exportShape, Shape: exportShape,
CompoundPath: exportCompoundPath, CompoundPath: exportCompoundPath,
PlacedSymbol: exportPlacedSymbol, SymbolItem: exportSymbolItem,
PointText: exportText PointText: exportText
}; };

View file

@ -102,7 +102,7 @@ new function() {
if (childNode.nodeType === 1 if (childNode.nodeType === 1
&& childNode.nodeName.toLowerCase() !== 'defs' && childNode.nodeName.toLowerCase() !== 'defs'
&& (child = importSVG(childNode, options, false)) && (child = importSVG(childNode, options, false))
&& !(child instanceof Symbol)) && !(child instanceof SymbolDefinition))
children.push(child); children.push(child);
} }
item.addChildren(children); item.addChildren(children);
@ -246,8 +246,9 @@ new function() {
// http://www.w3.org/TR/SVG/struct.html#SymbolElement // http://www.w3.org/TR/SVG/struct.html#SymbolElement
symbol: function(node, type, options, isRoot) { symbol: function(node, type, options, isRoot) {
// Pass true for dontCenter: return new SymbolDefinition(
return new Symbol(importGroup(node, type, options, isRoot), true); // Pass true for dontCenter:
importGroup(node, type, options, isRoot), true);
}, },
// http://www.w3.org/TR/SVG/struct.html#DefsElement // http://www.w3.org/TR/SVG/struct.html#DefsElement
@ -259,13 +260,13 @@ new function() {
// as a property on node. // as a property on node.
// TODO: Support overflow and width, height, in combination with // TODO: Support overflow and width, height, in combination with
// overflow: hidden. Paper.js currently does not support // overflow: hidden. Paper.js currently does not support
// PlacedSymbol clipping, but perhaps it should? // SymbolItem clipping, but perhaps it should?
var id = (getValue(node, 'href', true) || '').substring(1), var id = (getValue(node, 'href', true) || '').substring(1),
definition = definitions[id], definition = definitions[id],
point = getPoint(node, 'x', 'y'); point = getPoint(node, 'x', 'y');
// Use place if we're dealing with a symbol: // Use place if we're dealing with a symbol:
return definition return definition
? definition instanceof Symbol ? definition instanceof SymbolDefinition
// When placing symbols, we nee to take both point and // When placing symbols, we nee to take both point and
// matrix into account. This just does the right thing: // matrix into account. This just does the right thing:
? definition.place(point) ? definition.place(point)
@ -459,7 +460,7 @@ new function() {
// http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute // http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute
// TODO: implement preserveAspectRatio attribute // TODO: implement preserveAspectRatio attribute
// viewBox will be applied both to the group that's created for the // viewBox will be applied both to the group that's created for the
// content in Symbol.definition, and the Symbol itself. // content in SymbolDefinition#item, and the SymbolItem itself.
var rect = new Rectangle(convertValue(value, 'array')), var rect = new Rectangle(convertValue(value, 'array')),
size = getSize(node, 'width', 'height', true); size = getSize(node, 'width', 'height', true);
if (item instanceof Group) { if (item instanceof Group) {
@ -468,17 +469,17 @@ new function() {
var scale = size ? rect.getSize().divide(size) : 1, var scale = size ? rect.getSize().divide(size) : 1,
matrix = new Matrix().translate(rect.getPoint()).scale(scale); matrix = new Matrix().translate(rect.getPoint()).scale(scale);
item.transform(matrix.invert()); item.transform(matrix.invert());
} else if (item instanceof Symbol) { } else if (item instanceof SymbolDefinition) {
// The symbol is wrapping a group. Note that viewBox was already // The symbol is wrapping a group. Note that viewBox was already
// applied to the group, and above code was executed for it. // applied to the group, and the above code was executed for it.
// All that is left to handle here on the Symbol level is // All that is left to handle here for SymbolDefinition is
// clipping. We can't do it at group level because // clipping. We can't do it at group level because
// applyAttributes() gets called for groups before their // applyAttributes() gets called for groups before their
// children are added, for styling reasons. See importGroup() // children are added, for styling reasons. See importGroup()
if (size) if (size)
rect.setSize(size); rect.setSize(size);
var clip = getAttribute(node, 'overflow', styles) != 'visible', var clip = getAttribute(node, 'overflow', styles) != 'visible',
group = item._definition; group = item._item;
if (clip && !rect.contains(group.getBounds())) { if (clip && !rect.contains(group.getBounds())) {
// Add a clip path at the top of this symbol's group // Add a clip path at the top of this symbol's group
clip = new Shape.Rectangle(rect).transform(group._matrix); clip = new Shape.Rectangle(rect).transform(group._matrix);

View file

@ -159,7 +159,7 @@ var TextItem = Item.extend(/** @lends TextItem# */{
/** /**
* @bean * @bean
* @private * @private
* @deprecated use {@link #style} instead. * @deprecated use {@link #getStyle()} instead.
*/ */
getCharacterStyle: '#getStyle', getCharacterStyle: '#getStyle',
setCharacterStyle: '#setStyle', setCharacterStyle: '#setStyle',
@ -167,7 +167,7 @@ var TextItem = Item.extend(/** @lends TextItem# */{
/** /**
* @bean * @bean
* @private * @private
* @deprecated use {@link #style} instead. * @deprecated use {@link #getStyle()} instead.
*/ */
getParagraphStyle: '#getStyle', getParagraphStyle: '#getStyle',
setParagraphStyle: '#setStyle' setParagraphStyle: '#setStyle'

View file

@ -34,8 +34,7 @@ if (isNode) {
} }
// The unit-tests expect the paper classes to be global. // The unit-tests expect the paper classes to be global.
if (!('Base' in root)) paper.install(root);
paper.install(root);
// Override console.error, so that we can catch errors that are only logged to // Override console.error, so that we can catch errors that are only logged to
// the console. // the console.
@ -109,7 +108,7 @@ var equals = function(actual, expected, message, options) {
// A list of classes that should be identical after their owners were cloned. // A list of classes that should be identical after their owners were cloned.
var identicalAfterCloning = { var identicalAfterCloning = {
Gradient: true, Gradient: true,
Symbol: true SymbolDefinition: true
}; };
// Register a jsDump parser for Base. // Register a jsDump parser for Base.
@ -337,11 +336,6 @@ var comparators = {
} }
}, },
Symbol: function(actual, expected, message, options) {
equals(actual.definition, expected.definition, message + '.definition',
options);
},
Segment: function(actual, expected, message, options) { Segment: function(actual, expected, message, options) {
compareProperties(actual, expected, ['handleIn', 'handleOut', 'point', compareProperties(actual, expected, ['handleIn', 'handleOut', 'point',
'selected'], message, options); 'selected'], message, options);
@ -390,23 +384,28 @@ var comparators = {
['shape', 'size', 'radius']); ['shape', 'size', 'radius']);
}, },
PlacedSymbol: function(actual, expected, message, options) { PointText: function(actual, expected, message, options) {
compareItem(actual, expected, message, options,
['content', 'point']);
},
SymbolItem: function(actual, expected, message, options) {
compareItem(actual, expected, message, compareItem(actual, expected, message,
// Cloning PlacedSymbols does not result in cloned Symbols // Cloning SymbolItems does not result in cloned
// SymbolDefinitions
options && options.cloned options && options.cloned
? new Base(options, { cloned: false }) ? new Base(options, { cloned: false })
: options, : options,
['symbol']); ['symbol']);
}, },
PointText: function(actual, expected, message, options) { SymbolDefinition: function(actual, expected, message, options) {
compareItem(actual, expected, message, options, equals(actual.definition, expected.definition, message + '.definition',
['content', 'point']); options);
}, },
Project: function(actual, expected, message, options) { Project: function(actual, expected, message, options) {
compareProperties(actual, expected, ['symbols', 'layers'], compareProperties(actual, expected, ['layers'], message, options);
message, options);
} }
}; };

View file

@ -521,7 +521,7 @@ test('hit-testing of items that come after a transformed group.', function() {
return hitResult && hitResult.item; return hitResult && hitResult.item;
}, path2, 'Hit testing project for point2 should give us path2.'); }, path2, 'Hit testing project for point2 should give us path2.');
group.translate(delta) group.translate(delta);
hitResult = paper.project.hitTest(point1); hitResult = paper.project.hitTest(point1);
equals(function() { equals(function() {
@ -561,8 +561,8 @@ test('hit-testing of placed symbols.', function() {
var path = new Path.Circle([0, 0], 20); var path = new Path.Circle([0, 0], 20);
path.fillColor = 'black'; path.fillColor = 'black';
var symbol = new Symbol(path); var definition = new SymbolDefinition(path);
var placedItem = symbol.place(point); var placedItem = definition.place(point);
var hitResult = placedItem.hitTest(point); var hitResult = placedItem.hitTest(point);
equals(function() { equals(function() {
return hitResult && hitResult.item == placedItem; return hitResult && hitResult.item == placedItem;

View file

@ -612,7 +612,8 @@ test('Item#className', function() {
equals(new Path().className, 'Path'); equals(new Path().className, 'Path');
equals(new CompoundPath().className, 'CompoundPath'); equals(new CompoundPath().className, 'CompoundPath');
equals(new Raster().className, 'Raster'); equals(new Raster().className, 'Raster');
equals(new PlacedSymbol().className, 'PlacedSymbol'); equals(new SymbolItem().className, 'SymbolItem');
equals(new PlacedSymbol().className, 'SymbolItem'); // deprecated
equals(new PointText().className, 'PointText'); equals(new PointText().className, 'PointText');
}); });

View file

@ -113,13 +113,13 @@ test('PointText#clone()', function() {
cloneAndCompare(pointText); cloneAndCompare(pointText);
}); });
test('PlacedSymbol#clone()', function() { test('SymbolItem#clone()', function() {
var path = new Path.Circle([150, 150], 60); var path = new Path.Circle([150, 150], 60);
var symbol = new Symbol(path); var definition = new SymbolDefinition(path);
var placedSymbol = new PlacedSymbol(symbol); var item = new SymbolItem(definition);
placedSymbol.position = [100, 100]; item.position = [100, 100];
placedSymbol.rotate(90); item.rotate(90);
cloneAndCompare(placedSymbol); cloneAndCompare(item);
}); });
test('Symbol#clone()', function() { test('Symbol#clone()', function() {
@ -134,14 +134,11 @@ test('Symbol#clone()', function() {
miterLimit: 5 miterLimit: 5
}; };
path.selected = true; path.selected = true;
var symbol = new Symbol(path); var definition = new SymbolDefinition(path);
var copy = symbol.clone(); var copy = definition.clone();
equals(symbol.definition, copy.definition, 'symbol.definition'); equals(definition.item, copy.item, 'definition.item');
equals(function() { equals(function() {
return symbol.project == copy.project; return definition.project == copy.project;
}, true);
equals(function() {
return paper.project.symbols.length == 2;
}, true); }, true);
}); });

View file

@ -86,7 +86,7 @@ test('Rectangle testing', function() {
path1.fillColor = 'red'; path1.fillColor = 'red';
path1.name = 'square1'; path1.name = 'square1';
path1.strokeCap = 'square'; path1.strokeCap = 'square';
path1.opacity = .1; path1.opacity = 0.1;
path1.dashArray = [5, 2]; path1.dashArray = [5, 2];
path1.dashOffset = 0; path1.dashOffset = 0;
@ -121,10 +121,10 @@ test('Symbols', function() {
to: [200, 100], to: [200, 100],
fillColor: 'red' fillColor: 'red'
}); });
var symbol = new Symbol(ellipse); var definition = new SymbolDefinition(ellipse);
var p1 = symbol.place([100, 100]); var p1 = definition.place([100, 100]);
p1.rotate(45); p1.rotate(45);
var p2 = symbol.place([300, 200]); var p2 = definition.place([300, 200]);
p2.rotate(-30); p2.rotate(-30);
testExportImportJSON(paper.project); testExportImportJSON(paper.project);
@ -157,7 +157,7 @@ test('transform test 1', function() {
for(var i = 0; i < clones; i++) { for(var i = 0; i < clones; i++) {
var clonedPath = circlePath.clone(); var clonedPath = circlePath.clone();
clonedPath.rotate(angle * i, circlePath.bounds.topLeft); clonedPath.rotate(angle * i, circlePath.bounds.topLeft);
}; }
testExportImportJSON(paper.project); testExportImportJSON(paper.project);
}); });

View file

@ -12,7 +12,7 @@
QUnit.module('Symbol & Placed Symbol'); QUnit.module('Symbol & Placed Symbol');
test('placedSymbol bounds', function() { test('SymbolItem#bounds', function() {
var path = new Path.Circle([50, 50], 50); var path = new Path.Circle([50, 50], 50);
path.strokeColor = 'black'; path.strokeColor = 'black';
path.strokeWidth = 1; path.strokeWidth = 1;
@ -21,30 +21,30 @@ test('placedSymbol bounds', function() {
equals(path.strokeBounds, equals(path.strokeBounds,
new Rectangle(-0.5, -0.5, 101, 101), new Rectangle(-0.5, -0.5, 101, 101),
'Path initial bounds'); 'Path initial bounds');
var symbol = new Symbol(path); var definition = new SymbolDefinition(path);
var placedSymbol = new PlacedSymbol(symbol); var item = new SymbolItem(definition);
equals(placedSymbol.bounds, equals(item.bounds,
new Rectangle(-50.5, -50.5, 101, 101), new Rectangle(-50.5, -50.5, 101, 101),
'PlacedSymbol initial bounds'); 'SymbolItem initial bounds');
placedSymbol.scale(1, 0.5); item.scale(1, 0.5);
equals(placedSymbol.bounds, equals(item.bounds,
new Rectangle(-50.5, -25.25, 101, 50.5), new Rectangle(-50.5, -25.25, 101, 50.5),
'Bounds after scale'); 'Bounds after scale');
placedSymbol.rotate(40); item.rotate(40);
equals(placedSymbol.bounds, equals(item.bounds,
new Rectangle(-41.96283, -37.79252, 83.92567, 75.58503), new Rectangle(-41.96283, -37.79252, 83.92567, 75.58503),
'Bounds after rotation'); 'Bounds after rotation');
}); });
test('bounds of group of symbol instances', function() { test('bounds of group of SymbolItem instances', function() {
var path = new Path.Circle(new Point(), 10); var path = new Path.Circle(new Point(), 10);
var symbol = new Symbol(path); var definition = new SymbolDefinition(path);
var instances = []; var instances = [];
for (var i = 0; i < 10; i++) { for (var i = 0; i < 10; i++) {
var instance = symbol.place(new Point(i * 20, 20)); var instance = definition.place(new Point(i * 20, 20));
instances.push(instance); instances.push(instance);
} }
var group = new Group(instances); var group = new Group(instances);
@ -53,7 +53,7 @@ test('bounds of group of symbol instances', function() {
'Group bounds'); 'Group bounds');
}); });
test('bounds of a symbol that contains a group of items', function() { test('bounds of a SymbolItem that contains a group of items', function() {
var path = new Path.Circle(new Point(), 10); var path = new Path.Circle(new Point(), 10);
var path2 = path.clone(); var path2 = path.clone();
path2.position.x += 20; path2.position.x += 20;
@ -67,8 +67,8 @@ test('bounds of a symbol that contains a group of items', function() {
equals(group.bounds, equals(group.bounds,
new Rectangle(-10, -10, 40, 20), new Rectangle(-10, -10, 40, 20),
'Group bounds'); 'Group bounds');
var symbol = new Symbol(group); var definition = new SymbolDefinition(group);
var instance = symbol.place(new Point(50, 50)); var instance = definition.place(new Point(50, 50));
equals(instance.bounds, equals(instance.bounds,
new Rectangle(30, 40, 40, 20), new Rectangle(30, 40, 40, 20),
'Instance bounds'); 'Instance bounds');
@ -77,16 +77,16 @@ test('bounds of a symbol that contains a group of items', function() {
test('Changing the definition of a symbol should change the bounds of all instances of it.', function() { test('Changing the definition of a symbol should change the bounds of all instances of it.', function() {
var path = new Path.Circle(new Point(), 10); var path = new Path.Circle(new Point(), 10);
var path2 = new Path.Circle(new Point(), 20); var path2 = new Path.Circle(new Point(), 20);
var symbol = new Symbol(path); var definition = new SymbolDefinition(path);
var instance = symbol.place(new Point(0, 0)); var instance = definition.place(new Point(0, 0));
equals(instance.bounds, equals(instance.bounds,
new Rectangle(-10, -10, 20, 20), new Rectangle(-10, -10, 20, 20),
'Initial bounds'); 'Initial bounds');
symbol.definition = path2; definition.item = path2;
equals(instance.bounds, equals(instance.bounds,
new Rectangle(-20, -20, 40, 40), new Rectangle(-20, -20, 40, 40),
'Bounds after changing symbol definition'); 'Bounds after changing symbol definition');
symbol.definition.scale(0.5, 0.5); definition.item.scale(0.5, 0.5);
equals(instance.bounds, equals(instance.bounds,
new Rectangle(-10, -10, 20, 20), new Rectangle(-10, -10, 20, 20),
'Bounds after modifying symbol definition'); 'Bounds after modifying symbol definition');
@ -95,25 +95,25 @@ test('Changing the definition of a symbol should change the bounds of all instan
test('Symbol definition selection', function() { test('Symbol definition selection', function() {
var path = new Path.Circle([50, 50], 50); var path = new Path.Circle([50, 50], 50);
path.selected = true; path.selected = true;
var symbol = new Symbol(path); var definition = new SymbolDefinition(path);
equals(function() { equals(function() {
return symbol.definition.selected == false; return definition.item.selected === false;
}, true); }, true);
equals(function() { equals(function() {
return paper.project.selectedItems.length == 0; return paper.project.selectedItems.length === 0;
}, true); }, true);
}); });
test('Symbol#place()', function() { test('Symbol#place()', function() {
var path = new Path.Circle([50, 50], 50); var path = new Path.Circle([50, 50], 50);
var symbol = new Symbol(path); var definition = new SymbolDefinition(path);
var placedSymbol = symbol.place(); var placedSymbol = definition.place();
equals(function() { equals(function() {
return placedSymbol.parent == paper.project.activeLayer; return placedSymbol.parent == paper.project.activeLayer;
}, true); }, true);
equals(function() { equals(function() {
return placedSymbol.symbol == symbol; return placedSymbol.definition == definition;
}, true); }, true);
equals(function() { equals(function() {
@ -123,8 +123,8 @@ test('Symbol#place()', function() {
test('Symbol#place(position)', function() { test('Symbol#place(position)', function() {
var path = new Path.Circle([50, 50], 50); var path = new Path.Circle([50, 50], 50);
var symbol = new Symbol(path); var definition = new SymbolDefinition(path);
var placedSymbol = symbol.place(new Point(100, 100)); var placedSymbol = definition.place(new Point(100, 100));
equals(function() { equals(function() {
return placedSymbol.position.toString(); return placedSymbol.position.toString();
}, '{ x: 100, y: 100 }'); }, '{ x: 100, y: 100 }');

View file

@ -51,7 +51,7 @@
/*#*/ include('PathItem_Contains.js'); /*#*/ include('PathItem_Contains.js');
/*#*/ include('PlacedSymbol.js'); /*#*/ include('SymbolItem.js');
/*#*/ include('Raster.js'); /*#*/ include('Raster.js');