New file |
0,0 → 1,266 |
/* |
Copyright (c) 2004-2006, The Dojo Foundation |
All Rights Reserved. |
|
Licensed under the Academic Free License version 2.1 or above OR the |
modified BSD license. For more information on Dojo licensing, see: |
|
http://dojotoolkit.org/community/licensing.shtml |
*/ |
|
dojo.provide("dojo.gfx.path"); |
dojo.require("dojo.math"); |
dojo.require("dojo.gfx.shape"); |
dojo.declare("dojo.gfx.path.Path", dojo.gfx.Shape, {initializer:function (rawNode) { |
this.shape = dojo.lang.shallowCopy(dojo.gfx.defaultPath, true); |
this.segments = []; |
this.absolute = true; |
this.last = {}; |
this.attach(rawNode); |
}, setAbsoluteMode:function (mode) { |
this.absolute = typeof (mode) == "string" ? (mode == "absolute") : mode; |
return this; |
}, getAbsoluteMode:function () { |
return this.absolute; |
}, getBoundingBox:function () { |
return "l" in this.bbox ? {x:this.bbox.l, y:this.bbox.t, width:this.bbox.r - this.bbox.l, height:this.bbox.b - this.bbox.t} : null; |
}, getLastPosition:function () { |
return "x" in this.last ? this.last : null; |
}, _updateBBox:function (x, y) { |
if ("l" in this.bbox) { |
if (this.bbox.l > x) { |
this.bbox.l = x; |
} |
if (this.bbox.r < x) { |
this.bbox.r = x; |
} |
if (this.bbox.t > y) { |
this.bbox.t = y; |
} |
if (this.bbox.b < y) { |
this.bbox.b = y; |
} |
} else { |
this.bbox = {l:x, b:y, r:x, t:y}; |
} |
}, _updateWithSegment:function (segment) { |
var n = segment.args; |
var l = n.length; |
switch (segment.action) { |
case "M": |
case "L": |
case "C": |
case "S": |
case "Q": |
case "T": |
for (var i = 0; i < l; i += 2) { |
this._updateBBox(this.bbox, n[i], n[i + 1]); |
} |
this.last.x = n[l - 2]; |
this.last.y = n[l - 1]; |
this.absolute = true; |
break; |
case "H": |
for (var i = 0; i < l; ++i) { |
this._updateBBox(this.bbox, n[i], this.last.y); |
} |
this.last.x = n[l - 1]; |
this.absolute = true; |
break; |
case "V": |
for (var i = 0; i < l; ++i) { |
this._updateBBox(this.bbox, this.last.x, n[i]); |
} |
this.last.y = n[l - 1]; |
this.absolute = true; |
break; |
case "m": |
var start = 0; |
if (!("x" in this.last)) { |
this._updateBBox(this.bbox, this.last.x = n[0], this.last.y = n[1]); |
start = 2; |
} |
for (var i = start; i < l; i += 2) { |
this._updateBBox(this.bbox, this.last.x += n[i], this.last.y += n[i + 1]); |
} |
this.absolute = false; |
break; |
case "l": |
case "t": |
for (var i = 0; i < l; i += 2) { |
this._updateBBox(this.bbox, this.last.x += n[i], this.last.y += n[i + 1]); |
} |
this.absolute = false; |
break; |
case "h": |
for (var i = 0; i < l; ++i) { |
this._updateBBox(this.bbox, this.last.x += n[i], this.last.y); |
} |
this.absolute = false; |
break; |
case "v": |
for (var i = 0; i < l; ++i) { |
this._updateBBox(this.bbox, this.last.x, this.last.y += n[i]); |
} |
this.absolute = false; |
break; |
case "c": |
for (var i = 0; i < l; i += 6) { |
this._updateBBox(this.bbox, this.last.x + n[i], this.last.y + n[i + 1]); |
this._updateBBox(this.bbox, this.last.x + n[i + 2], this.last.y + n[i + 3]); |
this._updateBBox(this.bbox, this.last.x += n[i + 4], this.last.y += n[i + 5]); |
} |
this.absolute = false; |
break; |
case "s": |
case "q": |
for (var i = 0; i < l; i += 4) { |
this._updateBBox(this.bbox, this.last.x + n[i], this.last.y + n[i + 1]); |
this._updateBBox(this.bbox, this.last.x += n[i + 2], this.last.y += n[i + 3]); |
} |
this.absolute = false; |
break; |
case "A": |
for (var i = 0; i < l; i += 7) { |
this._updateBBox(this.bbox, n[i + 5], n[i + 6]); |
} |
this.last.x = n[l - 2]; |
this.last.y = n[l - 1]; |
this.absolute = true; |
break; |
case "a": |
for (var i = 0; i < l; i += 7) { |
this._updateBBox(this.bbox, this.last.x += n[i + 5], this.last.y += n[i + 6]); |
} |
this.absolute = false; |
break; |
} |
var path = [segment.action]; |
for (var i = 0; i < l; ++i) { |
path.push(dojo.gfx.formatNumber(n[i], true)); |
} |
if (typeof (this.shape.path) == "string") { |
this.shape.path += path.join(""); |
} else { |
this.shape.path = this.shape.path.concat(path); |
} |
}, _validSegments:{m:2, l:2, h:1, v:1, c:6, s:4, q:4, t:2, a:7, z:0}, _pushSegment:function (action, args) { |
var group = this._validSegments[action.toLowerCase()]; |
if (typeof (group) == "number") { |
if (group) { |
if (args.length >= group) { |
var segment = {action:action, args:args.slice(0, args.length - args.length % group)}; |
this.segments.push(segment); |
this._updateWithSegment(segment); |
} |
} else { |
var segment = {action:action, args:[]}; |
this.segments.push(segment); |
this._updateWithSegment(segment); |
} |
} |
}, _collectArgs:function (array, args) { |
for (var i = 0; i < args.length; ++i) { |
var t = args[i]; |
if (typeof (t) == "boolean") { |
array.push(t ? 1 : 0); |
} else { |
if (typeof (t) == "number") { |
array.push(t); |
} else { |
if (t instanceof Array) { |
this._collectArgs(array, t); |
} else { |
if ("x" in t && "y" in t) { |
array.push(t.x); |
array.push(t.y); |
} |
} |
} |
} |
} |
}, moveTo:function () { |
var args = []; |
this._collectArgs(args, arguments); |
this._pushSegment(this.absolute ? "M" : "m", args); |
return this; |
}, lineTo:function () { |
var args = []; |
this._collectArgs(args, arguments); |
this._pushSegment(this.absolute ? "L" : "l", args); |
return this; |
}, hLineTo:function () { |
var args = []; |
this._collectArgs(args, arguments); |
this._pushSegment(this.absolute ? "H" : "h", args); |
return this; |
}, vLineTo:function () { |
var args = []; |
this._collectArgs(args, arguments); |
this._pushSegment(this.absolute ? "V" : "v", args); |
return this; |
}, curveTo:function () { |
var args = []; |
this._collectArgs(args, arguments); |
this._pushSegment(this.absolute ? "C" : "c", args); |
return this; |
}, smoothCurveTo:function () { |
var args = []; |
this._collectArgs(args, arguments); |
this._pushSegment(this.absolute ? "S" : "s", args); |
return this; |
}, qCurveTo:function () { |
var args = []; |
this._collectArgs(args, arguments); |
this._pushSegment(this.absolute ? "Q" : "q", args); |
return this; |
}, qSmoothCurveTo:function () { |
var args = []; |
this._collectArgs(args, arguments); |
this._pushSegment(this.absolute ? "T" : "t", args); |
return this; |
}, arcTo:function () { |
var args = []; |
this._collectArgs(args, arguments); |
for (var i = 2; i < args.length; i += 7) { |
args[i] = -args[i]; |
} |
this._pushSegment(this.absolute ? "A" : "a", args); |
return this; |
}, closePath:function () { |
this._pushSegment("Z", []); |
return this; |
}, _setPath:function (path) { |
var p = path.match(dojo.gfx.pathRegExp); |
this.segments = []; |
this.absolute = true; |
this.bbox = {}; |
this.last = {}; |
if (!p) { |
return; |
} |
var action = ""; |
var args = []; |
for (var i = 0; i < p.length; ++i) { |
var t = p[i]; |
var x = parseFloat(t); |
if (isNaN(x)) { |
if (action) { |
this._pushSegment(action, args); |
} |
args = []; |
action = t; |
} else { |
args.push(x); |
} |
} |
this._pushSegment(action, args); |
}, setShape:function (newShape) { |
this.shape = dojo.gfx.makeParameters(this.shape, typeof (newShape) == "string" ? {path:newShape} : newShape); |
var path = this.shape.path; |
this.shape.path = []; |
this._setPath(path); |
this.shape.path = this.shape.path.join(""); |
return this; |
}, _2PI:Math.PI * 2}); |
|