Rev 20 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
20 | reyssat | 1 | /* This notice must be untouched at all times. |
2 | |||
3 | wz_jsgraphics.js v. 2.36 |
||
4 | The latest version is available at |
||
5 | http://www.walterzorn.com |
||
6 | or http://www.devira.com |
||
7 | or http://www.walterzorn.de |
||
8 | |||
9 | Copyright (c) 2002-2004 Walter Zorn. All rights reserved. |
||
10 | Created 3. 11. 2002 by Walter Zorn (Web: http://www.walterzorn.com ) |
||
11 | Last modified: 21. 6. 2006 |
||
12 | |||
13 | Performance optimizations for Internet Explorer |
||
14 | by Thomas Frank and John Holdsworth. |
||
15 | fillPolygon method implemented by Matthieu Haller. |
||
16 | |||
17 | High Performance JavaScript Graphics Library. |
||
18 | Provides methods |
||
19 | - to draw lines, rectangles, ellipses, polygons |
||
20 | with specifiable line thickness, |
||
21 | - to fill rectangles and ellipses |
||
22 | - to draw text. |
||
23 | NOTE: Operations, functions and branching have rather been optimized |
||
24 | to efficiency and speed than to shortness of source code. |
||
25 | |||
26 | LICENSE: LGPL |
||
27 | |||
28 | This library is free software; you can redistribute it and/or |
||
29 | modify it under the terms of the GNU Lesser General Public |
||
30 | License (LGPL) as published by the Free Software Foundation; either |
||
31 | version 2.1 of the License, or (at your option) any later version. |
||
32 | |||
33 | This library is distributed in the hope that it will be useful, |
||
34 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
35 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||
36 | Lesser General Public License for more details. |
||
37 | |||
38 | You should have received a copy of the GNU Lesser General Public |
||
39 | License along with this library; if not, write to the Free Software |
||
40 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, |
||
41 | or see http://www.gnu.org/copyleft/lesser.html |
||
42 | */ |
||
43 | |||
44 | |||
45 | var jg_ihtm, jg_ie, jg_fast, jg_dom, jg_moz, |
||
46 | jg_n4 = (document.layers && typeof document.classes != "undefined"); |
||
47 | |||
48 | |||
49 | function chkDHTM(x, i) |
||
50 | { |
||
51 | x = document.body || null; |
||
52 | jg_ie = x && typeof x.insertAdjacentHTML != "undefined"; |
||
53 | jg_dom = (x && !jg_ie && |
||
54 | typeof x.appendChild != "undefined" && |
||
55 | typeof document.createRange != "undefined" && |
||
56 | typeof (i = document.createRange()).setStartBefore != "undefined" && |
||
57 | typeof i.createContextualFragment != "undefined"); |
||
58 | jg_ihtm = !jg_ie && !jg_dom && x && typeof x.innerHTML != "undefined"; |
||
59 | jg_fast = jg_ie && document.all && !window.opera; |
||
60 | jg_moz = jg_dom && typeof x.style.MozOpacity != "undefined"; |
||
61 | } |
||
62 | |||
63 | |||
64 | function pntDoc() |
||
65 | { |
||
66 | this.wnd.document.write(jg_fast? this.htmRpc() : this.htm); |
||
67 | this.htm = ''; |
||
68 | } |
||
69 | |||
70 | |||
71 | function pntCnvDom() |
||
72 | { |
||
73 | var x = this.wnd.document.createRange(); |
||
74 | x.setStartBefore(this.cnv); |
||
75 | x = x.createContextualFragment(jg_fast? this.htmRpc() : this.htm); |
||
76 | if(this.cnv) this.cnv.appendChild(x); |
||
77 | this.htm = ''; |
||
78 | } |
||
79 | |||
80 | |||
81 | function pntCnvIe() |
||
82 | { |
||
83 | if(this.cnv) this.cnv.insertAdjacentHTML("BeforeEnd", jg_fast? this.htmRpc() : this.htm); |
||
84 | this.htm = ''; |
||
85 | } |
||
86 | |||
87 | |||
88 | function pntCnvIhtm() |
||
89 | { |
||
90 | if(this.cnv) this.cnv.innerHTML += this.htm; |
||
91 | this.htm = ''; |
||
92 | } |
||
93 | |||
94 | |||
95 | function pntCnv() |
||
96 | { |
||
97 | this.htm = ''; |
||
98 | } |
||
99 | |||
100 | |||
101 | function mkDiv(x, y, w, h) |
||
102 | { |
||
103 | this.htm += '<div style="position:absolute;'+ |
||
104 | 'left:' + x + 'px;'+ |
||
105 | 'top:' + y + 'px;'+ |
||
106 | 'width:' + w + 'px;'+ |
||
107 | 'height:' + h + 'px;'+ |
||
108 | 'clip:rect(0,'+w+'px,'+h+'px,0);'+ |
||
109 | 'background-color:' + this.color + |
||
110 | (!jg_moz? ';overflow:hidden' : '')+ |
||
111 | ';"><\/div>'; |
||
112 | } |
||
113 | |||
114 | |||
115 | function mkDivIe(x, y, w, h) |
||
116 | { |
||
117 | this.htm += '%%'+this.color+';'+x+';'+y+';'+w+';'+h+';'; |
||
118 | } |
||
119 | |||
120 | |||
121 | function mkDivPrt(x, y, w, h) |
||
122 | { |
||
123 | this.htm += '<div style="position:absolute;'+ |
||
124 | 'border-left:' + w + 'px solid ' + this.color + ';'+ |
||
125 | 'left:' + x + 'px;'+ |
||
126 | 'top:' + y + 'px;'+ |
||
127 | 'width:0px;'+ |
||
128 | 'height:' + h + 'px;'+ |
||
129 | 'clip:rect(0,'+w+'px,'+h+'px,0);'+ |
||
130 | 'background-color:' + this.color + |
||
131 | (!jg_moz? ';overflow:hidden' : '')+ |
||
132 | ';"><\/div>'; |
||
133 | } |
||
134 | |||
135 | |||
136 | function mkLyr(x, y, w, h) |
||
137 | { |
||
138 | this.htm += '<layer '+ |
||
139 | 'left="' + x + '" '+ |
||
140 | 'top="' + y + '" '+ |
||
141 | 'width="' + w + '" '+ |
||
142 | 'height="' + h + '" '+ |
||
143 | 'bgcolor="' + this.color + '"><\/layer>\n'; |
||
144 | } |
||
145 | |||
146 | |||
147 | var regex = /%%([^;]+);([^;]+);([^;]+);([^;]+);([^;]+);/g; |
||
148 | function htmRpc() |
||
149 | { |
||
150 | return this.htm.replace( |
||
151 | regex, |
||
152 | '<div style="overflow:hidden;position:absolute;background-color:'+ |
||
153 | '$1;left:$2;top:$3;width:$4;height:$5"></div>\n'); |
||
154 | } |
||
155 | |||
156 | |||
157 | function htmPrtRpc() |
||
158 | { |
||
159 | return this.htm.replace( |
||
160 | regex, |
||
161 | '<div style="overflow:hidden;position:absolute;background-color:'+ |
||
162 | '$1;left:$2;top:$3;width:$4;height:$5;border-left:$4px solid $1"></div>\n'); |
||
163 | } |
||
164 | |||
165 | |||
166 | function mkLin(x1, y1, x2, y2) |
||
167 | { |
||
168 | if (x1 > x2) |
||
169 | { |
||
170 | var _x2 = x2; |
||
171 | var _y2 = y2; |
||
172 | x2 = x1; |
||
173 | y2 = y1; |
||
174 | x1 = _x2; |
||
175 | y1 = _y2; |
||
176 | } |
||
177 | var dx = x2-x1, dy = Math.abs(y2-y1), |
||
178 | x = x1, y = y1, |
||
179 | yIncr = (y1 > y2)? -1 : 1; |
||
180 | |||
181 | if (dx >= dy) |
||
182 | { |
||
183 | var pr = dy<<1, |
||
184 | pru = pr - (dx<<1), |
||
185 | p = pr-dx, |
||
186 | ox = x; |
||
187 | while ((dx--) > 0) |
||
188 | { |
||
189 | ++x; |
||
190 | if (p > 0) |
||
191 | { |
||
192 | this.mkDiv(ox, y, x-ox, 1); |
||
193 | y += yIncr; |
||
194 | p += pru; |
||
195 | ox = x; |
||
196 | } |
||
197 | else p += pr; |
||
198 | } |
||
199 | this.mkDiv(ox, y, x2-ox+1, 1); |
||
200 | } |
||
201 | |||
202 | else |
||
203 | { |
||
204 | var pr = dx<<1, |
||
205 | pru = pr - (dy<<1), |
||
206 | p = pr-dy, |
||
207 | oy = y; |
||
208 | if (y2 <= y1) |
||
209 | { |
||
210 | while ((dy--) > 0) |
||
211 | { |
||
212 | if (p > 0) |
||
213 | { |
||
214 | this.mkDiv(x++, y, 1, oy-y+1); |
||
215 | y += yIncr; |
||
216 | p += pru; |
||
217 | oy = y; |
||
218 | } |
||
219 | else |
||
220 | { |
||
221 | y += yIncr; |
||
222 | p += pr; |
||
223 | } |
||
224 | } |
||
225 | this.mkDiv(x2, y2, 1, oy-y2+1); |
||
226 | } |
||
227 | else |
||
228 | { |
||
229 | while ((dy--) > 0) |
||
230 | { |
||
231 | y += yIncr; |
||
232 | if (p > 0) |
||
233 | { |
||
234 | this.mkDiv(x++, oy, 1, y-oy); |
||
235 | p += pru; |
||
236 | oy = y; |
||
237 | } |
||
238 | else p += pr; |
||
239 | } |
||
240 | this.mkDiv(x2, oy, 1, y2-oy+1); |
||
241 | } |
||
242 | } |
||
243 | } |
||
244 | |||
245 | |||
246 | function mkLin2D(x1, y1, x2, y2) |
||
247 | { |
||
248 | if (x1 > x2) |
||
249 | { |
||
250 | var _x2 = x2; |
||
251 | var _y2 = y2; |
||
252 | x2 = x1; |
||
253 | y2 = y1; |
||
254 | x1 = _x2; |
||
255 | y1 = _y2; |
||
256 | } |
||
257 | var dx = x2-x1, dy = Math.abs(y2-y1), |
||
258 | x = x1, y = y1, |
||
259 | yIncr = (y1 > y2)? -1 : 1; |
||
260 | |||
261 | var s = this.stroke; |
||
262 | if (dx >= dy) |
||
263 | { |
||
264 | if (dx > 0 && s-3 > 0) |
||
265 | { |
||
266 | var _s = (s*dx*Math.sqrt(1+dy*dy/(dx*dx))-dx-(s>>1)*dy) / dx; |
||
267 | _s = (!(s-4)? Math.ceil(_s) : Math.round(_s)) + 1; |
||
268 | } |
||
269 | else var _s = s; |
||
270 | var ad = Math.ceil(s/2); |
||
271 | |||
272 | var pr = dy<<1, |
||
273 | pru = pr - (dx<<1), |
||
274 | p = pr-dx, |
||
275 | ox = x; |
||
276 | while ((dx--) > 0) |
||
277 | { |
||
278 | ++x; |
||
279 | if (p > 0) |
||
280 | { |
||
281 | this.mkDiv(ox, y, x-ox+ad, _s); |
||
282 | y += yIncr; |
||
283 | p += pru; |
||
284 | ox = x; |
||
285 | } |
||
286 | else p += pr; |
||
287 | } |
||
288 | this.mkDiv(ox, y, x2-ox+ad+1, _s); |
||
289 | } |
||
290 | |||
291 | else |
||
292 | { |
||
293 | if (s-3 > 0) |
||
294 | { |
||
295 | var _s = (s*dy*Math.sqrt(1+dx*dx/(dy*dy))-(s>>1)*dx-dy) / dy; |
||
296 | _s = (!(s-4)? Math.ceil(_s) : Math.round(_s)) + 1; |
||
297 | } |
||
298 | else var _s = s; |
||
299 | var ad = Math.round(s/2); |
||
300 | |||
301 | var pr = dx<<1, |
||
302 | pru = pr - (dy<<1), |
||
303 | p = pr-dy, |
||
304 | oy = y; |
||
305 | if (y2 <= y1) |
||
306 | { |
||
307 | ++ad; |
||
308 | while ((dy--) > 0) |
||
309 | { |
||
310 | if (p > 0) |
||
311 | { |
||
312 | this.mkDiv(x++, y, _s, oy-y+ad); |
||
313 | y += yIncr; |
||
314 | p += pru; |
||
315 | oy = y; |
||
316 | } |
||
317 | else |
||
318 | { |
||
319 | y += yIncr; |
||
320 | p += pr; |
||
321 | } |
||
322 | } |
||
323 | this.mkDiv(x2, y2, _s, oy-y2+ad); |
||
324 | } |
||
325 | else |
||
326 | { |
||
327 | while ((dy--) > 0) |
||
328 | { |
||
329 | y += yIncr; |
||
330 | if (p > 0) |
||
331 | { |
||
332 | this.mkDiv(x++, oy, _s, y-oy+ad); |
||
333 | p += pru; |
||
334 | oy = y; |
||
335 | } |
||
336 | else p += pr; |
||
337 | } |
||
338 | this.mkDiv(x2, oy, _s, y2-oy+ad+1); |
||
339 | } |
||
340 | } |
||
341 | } |
||
342 | |||
343 | |||
344 | function mkLinDott(x1, y1, x2, y2) |
||
345 | { |
||
346 | if (x1 > x2) |
||
347 | { |
||
348 | var _x2 = x2; |
||
349 | var _y2 = y2; |
||
350 | x2 = x1; |
||
351 | y2 = y1; |
||
352 | x1 = _x2; |
||
353 | y1 = _y2; |
||
354 | } |
||
355 | var dx = x2-x1, dy = Math.abs(y2-y1), |
||
356 | x = x1, y = y1, |
||
357 | yIncr = (y1 > y2)? -1 : 1, |
||
358 | drw = true; |
||
359 | if (dx >= dy) |
||
360 | { |
||
361 | var pr = dy<<1, |
||
362 | pru = pr - (dx<<1), |
||
363 | p = pr-dx; |
||
364 | while ((dx--) > 0) |
||
365 | { |
||
366 | if (drw) this.mkDiv(x, y, 1, 1); |
||
367 | drw = !drw; |
||
368 | if (p > 0) |
||
369 | { |
||
370 | y += yIncr; |
||
371 | p += pru; |
||
372 | } |
||
373 | else p += pr; |
||
374 | ++x; |
||
375 | } |
||
376 | if (drw) this.mkDiv(x, y, 1, 1); |
||
377 | } |
||
378 | |||
379 | else |
||
380 | { |
||
381 | var pr = dx<<1, |
||
382 | pru = pr - (dy<<1), |
||
383 | p = pr-dy; |
||
384 | while ((dy--) > 0) |
||
385 | { |
||
386 | if (drw) this.mkDiv(x, y, 1, 1); |
||
387 | drw = !drw; |
||
388 | y += yIncr; |
||
389 | if (p > 0) |
||
390 | { |
||
391 | ++x; |
||
392 | p += pru; |
||
393 | } |
||
394 | else p += pr; |
||
395 | } |
||
396 | if (drw) this.mkDiv(x, y, 1, 1); |
||
397 | } |
||
398 | } |
||
399 | |||
400 | |||
401 | function mkOv(left, top, width, height) |
||
402 | { |
||
403 | var a = width>>1, b = height>>1, |
||
404 | wod = width&1, hod = (height&1)+1, |
||
405 | cx = left+a, cy = top+b, |
||
406 | x = 0, y = b, |
||
407 | ox = 0, oy = b, |
||
408 | aa = (a*a)<<1, bb = (b*b)<<1, |
||
409 | st = (aa>>1)*(1-(b<<1)) + bb, |
||
410 | tt = (bb>>1) - aa*((b<<1)-1), |
||
411 | w, h; |
||
412 | while (y > 0) |
||
413 | { |
||
414 | if (st < 0) |
||
415 | { |
||
416 | st += bb*((x<<1)+3); |
||
417 | tt += (bb<<1)*(++x); |
||
418 | } |
||
419 | else if (tt < 0) |
||
420 | { |
||
421 | st += bb*((x<<1)+3) - (aa<<1)*(y-1); |
||
422 | tt += (bb<<1)*(++x) - aa*(((y--)<<1)-3); |
||
423 | w = x-ox; |
||
424 | h = oy-y; |
||
425 | if (w&2 && h&2) |
||
426 | { |
||
427 | this.mkOvQds(cx, cy, -x+2, ox+wod, -oy, oy-1+hod, 1, 1); |
||
428 | this.mkOvQds(cx, cy, -x+1, x-1+wod, -y-1, y+hod, 1, 1); |
||
429 | } |
||
430 | else this.mkOvQds(cx, cy, -x+1, ox+wod, -oy, oy-h+hod, w, h); |
||
431 | ox = x; |
||
432 | oy = y; |
||
433 | } |
||
434 | else |
||
435 | { |
||
436 | tt -= aa*((y<<1)-3); |
||
437 | st -= (aa<<1)*(--y); |
||
438 | } |
||
439 | } |
||
440 | this.mkDiv(cx-a, cy-oy, a-ox+1, (oy<<1)+hod); |
||
441 | this.mkDiv(cx+ox+wod, cy-oy, a-ox+1, (oy<<1)+hod); |
||
442 | } |
||
443 | |||
444 | |||
445 | function mkOv2D(left, top, width, height) |
||
446 | { |
||
447 | var s = this.stroke; |
||
448 | width += s-1; |
||
449 | height += s-1; |
||
450 | var a = width>>1, b = height>>1, |
||
451 | wod = width&1, hod = (height&1)+1, |
||
452 | cx = left+a, cy = top+b, |
||
453 | x = 0, y = b, |
||
454 | aa = (a*a)<<1, bb = (b*b)<<1, |
||
455 | st = (aa>>1)*(1-(b<<1)) + bb, |
||
456 | tt = (bb>>1) - aa*((b<<1)-1); |
||
457 | |||
458 | if (s-4 < 0 && (!(s-2) || width-51 > 0 && height-51 > 0)) |
||
459 | { |
||
460 | var ox = 0, oy = b, |
||
461 | w, h, |
||
462 | pxl, pxr, pxt, pxb, pxw; |
||
463 | while (y > 0) |
||
464 | { |
||
465 | if (st < 0) |
||
466 | { |
||
467 | st += bb*((x<<1)+3); |
||
468 | tt += (bb<<1)*(++x); |
||
469 | } |
||
470 | else if (tt < 0) |
||
471 | { |
||
472 | st += bb*((x<<1)+3) - (aa<<1)*(y-1); |
||
473 | tt += (bb<<1)*(++x) - aa*(((y--)<<1)-3); |
||
474 | w = x-ox; |
||
475 | h = oy-y; |
||
476 | |||
477 | if (w-1) |
||
478 | { |
||
479 | pxw = w+1+(s&1); |
||
480 | h = s; |
||
481 | } |
||
482 | else if (h-1) |
||
483 | { |
||
484 | pxw = s; |
||
485 | h += 1+(s&1); |
||
486 | } |
||
487 | else pxw = h = s; |
||
488 | this.mkOvQds(cx, cy, -x+1, ox-pxw+w+wod, -oy, -h+oy+hod, pxw, h); |
||
489 | ox = x; |
||
490 | oy = y; |
||
491 | } |
||
492 | else |
||
493 | { |
||
494 | tt -= aa*((y<<1)-3); |
||
495 | st -= (aa<<1)*(--y); |
||
496 | } |
||
497 | } |
||
498 | this.mkDiv(cx-a, cy-oy, s, (oy<<1)+hod); |
||
499 | this.mkDiv(cx+a+wod-s+1, cy-oy, s, (oy<<1)+hod); |
||
500 | } |
||
501 | |||
502 | else |
||
503 | { |
||
504 | var _a = (width-((s-1)<<1))>>1, |
||
505 | _b = (height-((s-1)<<1))>>1, |
||
506 | _x = 0, _y = _b, |
||
507 | _aa = (_a*_a)<<1, _bb = (_b*_b)<<1, |
||
508 | _st = (_aa>>1)*(1-(_b<<1)) + _bb, |
||
509 | _tt = (_bb>>1) - _aa*((_b<<1)-1), |
||
510 | |||
511 | pxl = new Array(), |
||
512 | pxt = new Array(), |
||
513 | _pxb = new Array(); |
||
514 | pxl[0] = 0; |
||
515 | pxt[0] = b; |
||
516 | _pxb[0] = _b-1; |
||
517 | while (y > 0) |
||
518 | { |
||
519 | if (st < 0) |
||
520 | { |
||
521 | st += bb*((x<<1)+3); |
||
522 | tt += (bb<<1)*(++x); |
||
523 | pxl[pxl.length] = x; |
||
524 | pxt[pxt.length] = y; |
||
525 | } |
||
526 | else if (tt < 0) |
||
527 | { |
||
528 | st += bb*((x<<1)+3) - (aa<<1)*(y-1); |
||
529 | tt += (bb<<1)*(++x) - aa*(((y--)<<1)-3); |
||
530 | pxl[pxl.length] = x; |
||
531 | pxt[pxt.length] = y; |
||
532 | } |
||
533 | else |
||
534 | { |
||
535 | tt -= aa*((y<<1)-3); |
||
536 | st -= (aa<<1)*(--y); |
||
537 | } |
||
538 | |||
539 | if (_y > 0) |
||
540 | { |
||
541 | if (_st < 0) |
||
542 | { |
||
543 | _st += _bb*((_x<<1)+3); |
||
544 | _tt += (_bb<<1)*(++_x); |
||
545 | _pxb[_pxb.length] = _y-1; |
||
546 | } |
||
547 | else if (_tt < 0) |
||
548 | { |
||
549 | _st += _bb*((_x<<1)+3) - (_aa<<1)*(_y-1); |
||
550 | _tt += (_bb<<1)*(++_x) - _aa*(((_y--)<<1)-3); |
||
551 | _pxb[_pxb.length] = _y-1; |
||
552 | } |
||
553 | else |
||
554 | { |
||
555 | _tt -= _aa*((_y<<1)-3); |
||
556 | _st -= (_aa<<1)*(--_y); |
||
557 | _pxb[_pxb.length-1]--; |
||
558 | } |
||
559 | } |
||
560 | } |
||
561 | |||
562 | var ox = 0, oy = b, |
||
563 | _oy = _pxb[0], |
||
564 | l = pxl.length, |
||
565 | w, h; |
||
566 | for (var i = 0; i < l; i++) |
||
567 | { |
||
568 | if (typeof _pxb[i] != "undefined") |
||
569 | { |
||
570 | if (_pxb[i] < _oy || pxt[i] < oy) |
||
571 | { |
||
572 | x = pxl[i]; |
||
573 | this.mkOvQds(cx, cy, -x+1, ox+wod, -oy, _oy+hod, x-ox, oy-_oy); |
||
574 | ox = x; |
||
575 | oy = pxt[i]; |
||
576 | _oy = _pxb[i]; |
||
577 | } |
||
578 | } |
||
579 | else |
||
580 | { |
||
581 | x = pxl[i]; |
||
582 | this.mkDiv(cx-x+1, cy-oy, 1, (oy<<1)+hod); |
||
583 | this.mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod); |
||
584 | ox = x; |
||
585 | oy = pxt[i]; |
||
586 | } |
||
587 | } |
||
588 | this.mkDiv(cx-a, cy-oy, 1, (oy<<1)+hod); |
||
589 | this.mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod); |
||
590 | } |
||
591 | } |
||
592 | |||
593 | |||
594 | function mkOvDott(left, top, width, height) |
||
595 | { |
||
596 | var a = width>>1, b = height>>1, |
||
597 | wod = width&1, hod = height&1, |
||
598 | cx = left+a, cy = top+b, |
||
599 | x = 0, y = b, |
||
600 | aa2 = (a*a)<<1, aa4 = aa2<<1, bb = (b*b)<<1, |
||
601 | st = (aa2>>1)*(1-(b<<1)) + bb, |
||
602 | tt = (bb>>1) - aa2*((b<<1)-1), |
||
603 | drw = true; |
||
604 | while (y > 0) |
||
605 | { |
||
606 | if (st < 0) |
||
607 | { |
||
608 | st += bb*((x<<1)+3); |
||
609 | tt += (bb<<1)*(++x); |
||
610 | } |
||
611 | else if (tt < 0) |
||
612 | { |
||
613 | st += bb*((x<<1)+3) - aa4*(y-1); |
||
614 | tt += (bb<<1)*(++x) - aa2*(((y--)<<1)-3); |
||
615 | } |
||
616 | else |
||
617 | { |
||
618 | tt -= aa2*((y<<1)-3); |
||
619 | st -= aa4*(--y); |
||
620 | } |
||
621 | if (drw) this.mkOvQds(cx, cy, -x, x+wod, -y, y+hod, 1, 1); |
||
622 | drw = !drw; |
||
623 | } |
||
624 | } |
||
625 | |||
626 | |||
627 | function mkRect(x, y, w, h) |
||
628 | { |
||
629 | var s = this.stroke; |
||
630 | this.mkDiv(x, y, w, s); |
||
631 | this.mkDiv(x+w, y, s, h); |
||
632 | this.mkDiv(x, y+h, w+s, s); |
||
633 | this.mkDiv(x, y+s, s, h-s); |
||
634 | } |
||
635 | |||
636 | |||
637 | function mkRectDott(x, y, w, h) |
||
638 | { |
||
639 | this.drawLine(x, y, x+w, y); |
||
640 | this.drawLine(x+w, y, x+w, y+h); |
||
641 | this.drawLine(x, y+h, x+w, y+h); |
||
642 | this.drawLine(x, y, x, y+h); |
||
643 | } |
||
644 | |||
645 | |||
646 | function jsgFont() |
||
647 | { |
||
648 | this.PLAIN = 'font-weight:normal;'; |
||
649 | this.BOLD = 'font-weight:bold;'; |
||
650 | this.ITALIC = 'font-style:italic;'; |
||
651 | this.ITALIC_BOLD = this.ITALIC + this.BOLD; |
||
652 | this.BOLD_ITALIC = this.ITALIC_BOLD; |
||
653 | } |
||
654 | var Font = new jsgFont(); |
||
655 | |||
656 | |||
657 | function jsgStroke() |
||
658 | { |
||
659 | this.DOTTED = -1; |
||
660 | } |
||
661 | var Stroke = new jsgStroke(); |
||
662 | |||
663 | |||
664 | function jsGraphics(id, wnd) |
||
665 | { |
||
666 | this.setColor = new Function('arg', 'this.color = arg.toLowerCase();'); |
||
667 | |||
668 | this.setStroke = function(x) |
||
669 | { |
||
670 | this.stroke = x; |
||
671 | if (!(x+1)) |
||
672 | { |
||
673 | this.drawLine = mkLinDott; |
||
674 | this.mkOv = mkOvDott; |
||
675 | this.drawRect = mkRectDott; |
||
676 | } |
||
677 | else if (x-1 > 0) |
||
678 | { |
||
679 | this.drawLine = mkLin2D; |
||
680 | this.mkOv = mkOv2D; |
||
681 | this.drawRect = mkRect; |
||
682 | } |
||
683 | else |
||
684 | { |
||
685 | this.drawLine = mkLin; |
||
686 | this.mkOv = mkOv; |
||
687 | this.drawRect = mkRect; |
||
688 | } |
||
689 | }; |
||
690 | |||
691 | |||
692 | this.setPrintable = function(arg) |
||
693 | { |
||
694 | this.printable = arg; |
||
695 | if (jg_fast) |
||
696 | { |
||
697 | this.mkDiv = mkDivIe; |
||
698 | this.htmRpc = arg? htmPrtRpc : htmRpc; |
||
699 | } |
||
700 | else this.mkDiv = jg_n4? mkLyr : arg? mkDivPrt : mkDiv; |
||
701 | }; |
||
702 | |||
703 | |||
704 | this.setFont = function(fam, sz, sty) |
||
705 | { |
||
706 | this.ftFam = fam; |
||
707 | this.ftSz = sz; |
||
708 | this.ftSty = sty || Font.PLAIN; |
||
709 | }; |
||
710 | |||
711 | |||
712 | this.drawPolyline = this.drawPolyLine = function(x, y, s) |
||
713 | { |
||
714 | for (var i=0 ; i<x.length-1 ; i++ ) |
||
715 | this.drawLine(x[i], y[i], x[i+1], y[i+1]); |
||
716 | }; |
||
717 | |||
718 | |||
719 | this.fillRect = function(x, y, w, h) |
||
720 | { |
||
721 | this.mkDiv(x, y, w, h); |
||
722 | }; |
||
723 | |||
724 | |||
725 | this.drawPolygon = function(x, y) |
||
726 | { |
||
727 | this.drawPolyline(x, y); |
||
728 | this.drawLine(x[x.length-1], y[x.length-1], x[0], y[0]); |
||
729 | }; |
||
730 | |||
731 | |||
732 | this.drawEllipse = this.drawOval = function(x, y, w, h) |
||
733 | { |
||
734 | this.mkOv(x, y, w, h); |
||
735 | }; |
||
736 | |||
737 | |||
738 | this.fillEllipse = this.fillOval = function(left, top, w, h) |
||
739 | { |
||
740 | var a = (w -= 1)>>1, b = (h -= 1)>>1, |
||
741 | wod = (w&1)+1, hod = (h&1)+1, |
||
742 | cx = left+a, cy = top+b, |
||
743 | x = 0, y = b, |
||
744 | ox = 0, oy = b, |
||
745 | aa2 = (a*a)<<1, aa4 = aa2<<1, bb = (b*b)<<1, |
||
746 | st = (aa2>>1)*(1-(b<<1)) + bb, |
||
747 | tt = (bb>>1) - aa2*((b<<1)-1), |
||
748 | pxl, dw, dh; |
||
749 | if (w+1) while (y > 0) |
||
750 | { |
||
751 | if (st < 0) |
||
752 | { |
||
753 | st += bb*((x<<1)+3); |
||
754 | tt += (bb<<1)*(++x); |
||
755 | } |
||
756 | else if (tt < 0) |
||
757 | { |
||
758 | st += bb*((x<<1)+3) - aa4*(y-1); |
||
759 | pxl = cx-x; |
||
760 | dw = (x<<1)+wod; |
||
761 | tt += (bb<<1)*(++x) - aa2*(((y--)<<1)-3); |
||
762 | dh = oy-y; |
||
763 | this.mkDiv(pxl, cy-oy, dw, dh); |
||
764 | this.mkDiv(pxl, cy+y+hod, dw, dh); |
||
765 | ox = x; |
||
766 | oy = y; |
||
767 | } |
||
768 | else |
||
769 | { |
||
770 | tt -= aa2*((y<<1)-3); |
||
771 | st -= aa4*(--y); |
||
772 | } |
||
773 | } |
||
774 | this.mkDiv(cx-a, cy-oy, w+1, (oy<<1)+hod); |
||
775 | }; |
||
776 | |||
777 | |||
778 | /* fillPolygon method, implemented by Matthieu Haller. |
||
779 | This javascript function is an adaptation of the gdImageFilledPolygon for Walter Zorn lib. |
||
780 | C source of GD 1.8.4 found at http://www.boutell.com/gd/ |
||
781 | |||
782 | THANKS to Kirsten Schulz for the polygon fixes! |
||
783 | |||
784 | The intersection finding technique of this code could be improved |
||
785 | by remembering the previous intertersection, and by using the slope. |
||
786 | That could help to adjust intersections to produce a nice |
||
787 | interior_extrema. */ |
||
788 | this.fillPolygon = function(array_x, array_y) |
||
789 | { |
||
790 | var i; |
||
791 | var y; |
||
792 | var miny, maxy; |
||
793 | var x1, y1; |
||
794 | var x2, y2; |
||
795 | var ind1, ind2; |
||
796 | var ints; |
||
797 | |||
798 | var n = array_x.length; |
||
799 | |||
800 | if (!n) return; |
||
801 | |||
802 | |||
803 | miny = array_y[0]; |
||
804 | maxy = array_y[0]; |
||
805 | for (i = 1; i < n; i++) |
||
806 | { |
||
807 | if (array_y[i] < miny) |
||
808 | miny = array_y[i]; |
||
809 | |||
810 | if (array_y[i] > maxy) |
||
811 | maxy = array_y[i]; |
||
812 | } |
||
813 | for (y = miny; y <= maxy; y++) |
||
814 | { |
||
815 | var polyInts = new Array(); |
||
816 | ints = 0; |
||
817 | for (i = 0; i < n; i++) |
||
818 | { |
||
819 | if (!i) |
||
820 | { |
||
821 | ind1 = n-1; |
||
822 | ind2 = 0; |
||
823 | } |
||
824 | else |
||
825 | { |
||
826 | ind1 = i-1; |
||
827 | ind2 = i; |
||
828 | } |
||
829 | y1 = array_y[ind1]; |
||
830 | y2 = array_y[ind2]; |
||
831 | if (y1 < y2) |
||
832 | { |
||
833 | x1 = array_x[ind1]; |
||
834 | x2 = array_x[ind2]; |
||
835 | } |
||
836 | else if (y1 > y2) |
||
837 | { |
||
838 | y2 = array_y[ind1]; |
||
839 | y1 = array_y[ind2]; |
||
840 | x2 = array_x[ind1]; |
||
841 | x1 = array_x[ind2]; |
||
842 | } |
||
843 | else continue; |
||
844 | |||
845 | // modified 11. 2. 2004 Walter Zorn |
||
846 | if ((y >= y1) && (y < y2)) |
||
847 | polyInts[ints++] = Math.round((y-y1) * (x2-x1) / (y2-y1) + x1); |
||
848 | |||
849 | else if ((y == maxy) && (y > y1) && (y <= y2)) |
||
850 | polyInts[ints++] = Math.round((y-y1) * (x2-x1) / (y2-y1) + x1); |
||
851 | } |
||
852 | polyInts.sort(integer_compare); |
||
853 | for (i = 0; i < ints; i+=2) |
||
854 | this.mkDiv(polyInts[i], y, polyInts[i+1]-polyInts[i]+1, 1); |
||
855 | } |
||
856 | }; |
||
857 | |||
858 | |||
859 | this.drawString = function(txt, x, y) |
||
860 | { |
||
861 | this.htm += '<div style="position:absolute;white-space:nowrap;'+ |
||
862 | 'left:' + x + 'px;'+ |
||
863 | 'top:' + y + 'px;'+ |
||
864 | 'font-family:' + this.ftFam + ';'+ |
||
865 | 'font-size:' + this.ftSz + ';'+ |
||
866 | 'color:' + this.color + ';' + this.ftSty + '">'+ |
||
867 | txt + |
||
868 | '<\/div>'; |
||
869 | }; |
||
870 | |||
871 | |||
872 | /* drawStringRect() added by Rick Blommers. |
||
873 | Allows to specify the size of the text rectangle and to align the |
||
874 | text both horizontally (e.g. right) and vertically within that rectangle */ |
||
875 | this.drawStringRect = function(txt, x, y, width, halign) |
||
876 | { |
||
877 | this.htm += '<div style="position:absolute;overflow:hidden;'+ |
||
878 | 'left:' + x + 'px;'+ |
||
879 | 'top:' + y + 'px;'+ |
||
880 | 'width:'+width +'px;'+ |
||
881 | 'text-align:'+halign+';'+ |
||
882 | 'font-family:' + this.ftFam + ';'+ |
||
883 | 'font-size:' + this.ftSz + ';'+ |
||
884 | 'color:' + this.color + ';' + this.ftSty + '">'+ |
||
885 | txt + |
||
886 | '<\/div>'; |
||
887 | }; |
||
888 | |||
889 | |||
890 | this.drawImage = function(imgSrc, x, y, w, h, a) |
||
891 | { |
||
892 | this.htm += '<div style="position:absolute;'+ |
||
893 | 'left:' + x + 'px;'+ |
||
894 | 'top:' + y + 'px;'+ |
||
895 | 'width:' + w + 'px;'+ |
||
896 | 'height:' + h + 'px;">'+ |
||
5818 | bpr | 897 | '<img src="' + imgSrc + '" width="' + w + '" height="' + h + '"' + (a? (' '+a) : '') + '/>'+ |
20 | reyssat | 898 | '<\/div>'; |
899 | }; |
||
900 | |||
901 | |||
902 | this.clear = function() |
||
903 | { |
||
904 | this.htm = ""; |
||
905 | if (this.cnv) this.cnv.innerHTML = this.defhtm; |
||
906 | }; |
||
907 | |||
908 | |||
909 | this.mkOvQds = function(cx, cy, xl, xr, yt, yb, w, h) |
||
910 | { |
||
911 | this.mkDiv(xr+cx, yt+cy, w, h); |
||
912 | this.mkDiv(xr+cx, yb+cy, w, h); |
||
913 | this.mkDiv(xl+cx, yb+cy, w, h); |
||
914 | this.mkDiv(xl+cx, yt+cy, w, h); |
||
915 | }; |
||
916 | |||
917 | this.setStroke(1); |
||
918 | this.setFont('verdana,geneva,helvetica,sans-serif', String.fromCharCode(0x31, 0x32, 0x70, 0x78), Font.PLAIN); |
||
919 | this.color = '#000000'; |
||
920 | this.htm = ''; |
||
921 | this.wnd = wnd || window; |
||
922 | |||
923 | if (!(jg_ie || jg_dom || jg_ihtm)) chkDHTM(); |
||
924 | if (typeof id != 'string' || !id) this.paint = pntDoc; |
||
925 | else |
||
926 | { |
||
927 | this.cnv = document.all? (this.wnd.document.all[id] || null) |
||
928 | : document.getElementById? (this.wnd.document.getElementById(id) || null) |
||
929 | : null; |
||
930 | this.defhtm = (this.cnv && this.cnv.innerHTML)? this.cnv.innerHTML : ''; |
||
931 | this.paint = jg_dom? pntCnvDom : jg_ie? pntCnvIe : jg_ihtm? pntCnvIhtm : pntCnv; |
||
932 | } |
||
933 | |||
934 | this.setPrintable(false); |
||
935 | } |
||
936 | |||
937 | |||
938 | |||
939 | function integer_compare(x,y) |
||
940 | { |
||
941 | return (x < y) ? -1 : ((x > y)*1); |
||
942 | } |
||
943 |