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