| 1318 |
alexandre_ |
1 |
/*
|
|
|
2 |
Copyright (c) 2004-2006, The Dojo Foundation
|
|
|
3 |
All Rights Reserved.
|
|
|
4 |
|
|
|
5 |
Licensed under the Academic Free License version 2.1 or above OR the
|
|
|
6 |
modified BSD license. For more information on Dojo licensing, see:
|
|
|
7 |
|
|
|
8 |
http://dojotoolkit.org/community/licensing.shtml
|
|
|
9 |
*/
|
|
|
10 |
|
| 1422 |
alexandre_ |
11 |
|
|
|
12 |
|
| 1318 |
alexandre_ |
13 |
dojo.provide("dojo.gfx.path");
|
|
|
14 |
dojo.require("dojo.math");
|
|
|
15 |
dojo.require("dojo.gfx.shape");
|
|
|
16 |
dojo.declare("dojo.gfx.path.Path", dojo.gfx.Shape, {initializer:function (rawNode) {
|
|
|
17 |
this.shape = dojo.lang.shallowCopy(dojo.gfx.defaultPath, true);
|
|
|
18 |
this.segments = [];
|
|
|
19 |
this.absolute = true;
|
|
|
20 |
this.last = {};
|
|
|
21 |
this.attach(rawNode);
|
|
|
22 |
}, setAbsoluteMode:function (mode) {
|
|
|
23 |
this.absolute = typeof (mode) == "string" ? (mode == "absolute") : mode;
|
|
|
24 |
return this;
|
|
|
25 |
}, getAbsoluteMode:function () {
|
|
|
26 |
return this.absolute;
|
|
|
27 |
}, getBoundingBox:function () {
|
|
|
28 |
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;
|
|
|
29 |
}, getLastPosition:function () {
|
|
|
30 |
return "x" in this.last ? this.last : null;
|
|
|
31 |
}, _updateBBox:function (x, y) {
|
|
|
32 |
if ("l" in this.bbox) {
|
|
|
33 |
if (this.bbox.l > x) {
|
|
|
34 |
this.bbox.l = x;
|
|
|
35 |
}
|
|
|
36 |
if (this.bbox.r < x) {
|
|
|
37 |
this.bbox.r = x;
|
|
|
38 |
}
|
|
|
39 |
if (this.bbox.t > y) {
|
|
|
40 |
this.bbox.t = y;
|
|
|
41 |
}
|
|
|
42 |
if (this.bbox.b < y) {
|
|
|
43 |
this.bbox.b = y;
|
|
|
44 |
}
|
|
|
45 |
} else {
|
|
|
46 |
this.bbox = {l:x, b:y, r:x, t:y};
|
|
|
47 |
}
|
|
|
48 |
}, _updateWithSegment:function (segment) {
|
|
|
49 |
var n = segment.args;
|
|
|
50 |
var l = n.length;
|
|
|
51 |
switch (segment.action) {
|
|
|
52 |
case "M":
|
|
|
53 |
case "L":
|
|
|
54 |
case "C":
|
|
|
55 |
case "S":
|
|
|
56 |
case "Q":
|
|
|
57 |
case "T":
|
|
|
58 |
for (var i = 0; i < l; i += 2) {
|
|
|
59 |
this._updateBBox(this.bbox, n[i], n[i + 1]);
|
|
|
60 |
}
|
|
|
61 |
this.last.x = n[l - 2];
|
|
|
62 |
this.last.y = n[l - 1];
|
|
|
63 |
this.absolute = true;
|
|
|
64 |
break;
|
|
|
65 |
case "H":
|
|
|
66 |
for (var i = 0; i < l; ++i) {
|
|
|
67 |
this._updateBBox(this.bbox, n[i], this.last.y);
|
|
|
68 |
}
|
|
|
69 |
this.last.x = n[l - 1];
|
|
|
70 |
this.absolute = true;
|
|
|
71 |
break;
|
|
|
72 |
case "V":
|
|
|
73 |
for (var i = 0; i < l; ++i) {
|
|
|
74 |
this._updateBBox(this.bbox, this.last.x, n[i]);
|
|
|
75 |
}
|
|
|
76 |
this.last.y = n[l - 1];
|
|
|
77 |
this.absolute = true;
|
|
|
78 |
break;
|
|
|
79 |
case "m":
|
|
|
80 |
var start = 0;
|
|
|
81 |
if (!("x" in this.last)) {
|
|
|
82 |
this._updateBBox(this.bbox, this.last.x = n[0], this.last.y = n[1]);
|
|
|
83 |
start = 2;
|
|
|
84 |
}
|
|
|
85 |
for (var i = start; i < l; i += 2) {
|
|
|
86 |
this._updateBBox(this.bbox, this.last.x += n[i], this.last.y += n[i + 1]);
|
|
|
87 |
}
|
|
|
88 |
this.absolute = false;
|
|
|
89 |
break;
|
|
|
90 |
case "l":
|
|
|
91 |
case "t":
|
|
|
92 |
for (var i = 0; i < l; i += 2) {
|
|
|
93 |
this._updateBBox(this.bbox, this.last.x += n[i], this.last.y += n[i + 1]);
|
|
|
94 |
}
|
|
|
95 |
this.absolute = false;
|
|
|
96 |
break;
|
|
|
97 |
case "h":
|
|
|
98 |
for (var i = 0; i < l; ++i) {
|
|
|
99 |
this._updateBBox(this.bbox, this.last.x += n[i], this.last.y);
|
|
|
100 |
}
|
|
|
101 |
this.absolute = false;
|
|
|
102 |
break;
|
|
|
103 |
case "v":
|
|
|
104 |
for (var i = 0; i < l; ++i) {
|
|
|
105 |
this._updateBBox(this.bbox, this.last.x, this.last.y += n[i]);
|
|
|
106 |
}
|
|
|
107 |
this.absolute = false;
|
|
|
108 |
break;
|
|
|
109 |
case "c":
|
|
|
110 |
for (var i = 0; i < l; i += 6) {
|
|
|
111 |
this._updateBBox(this.bbox, this.last.x + n[i], this.last.y + n[i + 1]);
|
|
|
112 |
this._updateBBox(this.bbox, this.last.x + n[i + 2], this.last.y + n[i + 3]);
|
|
|
113 |
this._updateBBox(this.bbox, this.last.x += n[i + 4], this.last.y += n[i + 5]);
|
|
|
114 |
}
|
|
|
115 |
this.absolute = false;
|
|
|
116 |
break;
|
|
|
117 |
case "s":
|
|
|
118 |
case "q":
|
|
|
119 |
for (var i = 0; i < l; i += 4) {
|
|
|
120 |
this._updateBBox(this.bbox, this.last.x + n[i], this.last.y + n[i + 1]);
|
|
|
121 |
this._updateBBox(this.bbox, this.last.x += n[i + 2], this.last.y += n[i + 3]);
|
|
|
122 |
}
|
|
|
123 |
this.absolute = false;
|
|
|
124 |
break;
|
|
|
125 |
case "A":
|
|
|
126 |
for (var i = 0; i < l; i += 7) {
|
|
|
127 |
this._updateBBox(this.bbox, n[i + 5], n[i + 6]);
|
|
|
128 |
}
|
|
|
129 |
this.last.x = n[l - 2];
|
|
|
130 |
this.last.y = n[l - 1];
|
|
|
131 |
this.absolute = true;
|
|
|
132 |
break;
|
|
|
133 |
case "a":
|
|
|
134 |
for (var i = 0; i < l; i += 7) {
|
|
|
135 |
this._updateBBox(this.bbox, this.last.x += n[i + 5], this.last.y += n[i + 6]);
|
|
|
136 |
}
|
|
|
137 |
this.absolute = false;
|
|
|
138 |
break;
|
|
|
139 |
}
|
|
|
140 |
var path = [segment.action];
|
|
|
141 |
for (var i = 0; i < l; ++i) {
|
|
|
142 |
path.push(dojo.gfx.formatNumber(n[i], true));
|
|
|
143 |
}
|
|
|
144 |
if (typeof (this.shape.path) == "string") {
|
|
|
145 |
this.shape.path += path.join("");
|
|
|
146 |
} else {
|
|
|
147 |
this.shape.path = this.shape.path.concat(path);
|
|
|
148 |
}
|
|
|
149 |
}, _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) {
|
|
|
150 |
var group = this._validSegments[action.toLowerCase()];
|
|
|
151 |
if (typeof (group) == "number") {
|
|
|
152 |
if (group) {
|
|
|
153 |
if (args.length >= group) {
|
|
|
154 |
var segment = {action:action, args:args.slice(0, args.length - args.length % group)};
|
|
|
155 |
this.segments.push(segment);
|
|
|
156 |
this._updateWithSegment(segment);
|
|
|
157 |
}
|
|
|
158 |
} else {
|
|
|
159 |
var segment = {action:action, args:[]};
|
|
|
160 |
this.segments.push(segment);
|
|
|
161 |
this._updateWithSegment(segment);
|
|
|
162 |
}
|
|
|
163 |
}
|
|
|
164 |
}, _collectArgs:function (array, args) {
|
|
|
165 |
for (var i = 0; i < args.length; ++i) {
|
|
|
166 |
var t = args[i];
|
|
|
167 |
if (typeof (t) == "boolean") {
|
|
|
168 |
array.push(t ? 1 : 0);
|
|
|
169 |
} else {
|
|
|
170 |
if (typeof (t) == "number") {
|
|
|
171 |
array.push(t);
|
|
|
172 |
} else {
|
|
|
173 |
if (t instanceof Array) {
|
|
|
174 |
this._collectArgs(array, t);
|
|
|
175 |
} else {
|
|
|
176 |
if ("x" in t && "y" in t) {
|
|
|
177 |
array.push(t.x);
|
|
|
178 |
array.push(t.y);
|
|
|
179 |
}
|
|
|
180 |
}
|
|
|
181 |
}
|
|
|
182 |
}
|
|
|
183 |
}
|
|
|
184 |
}, moveTo:function () {
|
|
|
185 |
var args = [];
|
|
|
186 |
this._collectArgs(args, arguments);
|
|
|
187 |
this._pushSegment(this.absolute ? "M" : "m", args);
|
|
|
188 |
return this;
|
|
|
189 |
}, lineTo:function () {
|
|
|
190 |
var args = [];
|
|
|
191 |
this._collectArgs(args, arguments);
|
|
|
192 |
this._pushSegment(this.absolute ? "L" : "l", args);
|
|
|
193 |
return this;
|
|
|
194 |
}, hLineTo:function () {
|
|
|
195 |
var args = [];
|
|
|
196 |
this._collectArgs(args, arguments);
|
|
|
197 |
this._pushSegment(this.absolute ? "H" : "h", args);
|
|
|
198 |
return this;
|
|
|
199 |
}, vLineTo:function () {
|
|
|
200 |
var args = [];
|
|
|
201 |
this._collectArgs(args, arguments);
|
|
|
202 |
this._pushSegment(this.absolute ? "V" : "v", args);
|
|
|
203 |
return this;
|
|
|
204 |
}, curveTo:function () {
|
|
|
205 |
var args = [];
|
|
|
206 |
this._collectArgs(args, arguments);
|
|
|
207 |
this._pushSegment(this.absolute ? "C" : "c", args);
|
|
|
208 |
return this;
|
|
|
209 |
}, smoothCurveTo:function () {
|
|
|
210 |
var args = [];
|
|
|
211 |
this._collectArgs(args, arguments);
|
|
|
212 |
this._pushSegment(this.absolute ? "S" : "s", args);
|
|
|
213 |
return this;
|
|
|
214 |
}, qCurveTo:function () {
|
|
|
215 |
var args = [];
|
|
|
216 |
this._collectArgs(args, arguments);
|
|
|
217 |
this._pushSegment(this.absolute ? "Q" : "q", args);
|
|
|
218 |
return this;
|
|
|
219 |
}, qSmoothCurveTo:function () {
|
|
|
220 |
var args = [];
|
|
|
221 |
this._collectArgs(args, arguments);
|
|
|
222 |
this._pushSegment(this.absolute ? "T" : "t", args);
|
|
|
223 |
return this;
|
|
|
224 |
}, arcTo:function () {
|
|
|
225 |
var args = [];
|
|
|
226 |
this._collectArgs(args, arguments);
|
|
|
227 |
for (var i = 2; i < args.length; i += 7) {
|
|
|
228 |
args[i] = -args[i];
|
|
|
229 |
}
|
|
|
230 |
this._pushSegment(this.absolute ? "A" : "a", args);
|
|
|
231 |
return this;
|
|
|
232 |
}, closePath:function () {
|
|
|
233 |
this._pushSegment("Z", []);
|
|
|
234 |
return this;
|
|
|
235 |
}, _setPath:function (path) {
|
|
|
236 |
var p = path.match(dojo.gfx.pathRegExp);
|
|
|
237 |
this.segments = [];
|
|
|
238 |
this.absolute = true;
|
|
|
239 |
this.bbox = {};
|
|
|
240 |
this.last = {};
|
|
|
241 |
if (!p) {
|
|
|
242 |
return;
|
|
|
243 |
}
|
|
|
244 |
var action = "";
|
|
|
245 |
var args = [];
|
|
|
246 |
for (var i = 0; i < p.length; ++i) {
|
|
|
247 |
var t = p[i];
|
|
|
248 |
var x = parseFloat(t);
|
|
|
249 |
if (isNaN(x)) {
|
|
|
250 |
if (action) {
|
|
|
251 |
this._pushSegment(action, args);
|
|
|
252 |
}
|
|
|
253 |
args = [];
|
|
|
254 |
action = t;
|
|
|
255 |
} else {
|
|
|
256 |
args.push(x);
|
|
|
257 |
}
|
|
|
258 |
}
|
|
|
259 |
this._pushSegment(action, args);
|
|
|
260 |
}, setShape:function (newShape) {
|
|
|
261 |
this.shape = dojo.gfx.makeParameters(this.shape, typeof (newShape) == "string" ? {path:newShape} : newShape);
|
|
|
262 |
var path = this.shape.path;
|
|
|
263 |
this.shape.path = [];
|
|
|
264 |
this._setPath(path);
|
|
|
265 |
this.shape.path = this.shape.path.join("");
|
|
|
266 |
return this;
|
|
|
267 |
}, _2PI:Math.PI * 2});
|
|
|
268 |
|