source: source/wz_jsgraphics.js @ 196:9930e7d487d8

Last change on this file since 196:9930e7d487d8 was 167:986132e819d5, checked in by fnevgeny, 15 years ago

Updated wz_jsgraphics.

File size: 23.4 KB
Line 
1/* This notice must be untouched at all times.
2
3wz_jsgraphics.js    v. 3.05
4The latest version is available at
5http://www.walterzorn.com
6or http://www.devira.com
7or http://www.walterzorn.de
8
9Copyright (c) 2002-2009 Walter Zorn. All rights reserved.
10Created 3. 11. 2002 by Walter Zorn (Web: http://www.walterzorn.com )
11Last modified: 2. 2. 2009
12
13Performance optimizations for Internet Explorer
14by Thomas Frank and John Holdsworth.
15fillPolygon method implemented by Matthieu Haller.
16
17High Performance JavaScript Graphics Library.
18Provides methods
19- to draw lines, rectangles, ellipses, polygons
20        with specifiable line thickness,
21- to fill rectangles, polygons, ellipses and arcs
22- to draw text.
23NOTE: Operations, functions and branching have rather been optimized
24to efficiency and speed than to shortness of source code.
25
26LICENSE: LGPL
27
28This library is free software; you can redistribute it and/or
29modify it under the terms of the GNU Lesser General Public
30License (LGPL) as published by the Free Software Foundation; either
31version 2.1 of the License, or (at your option) any later version.
32
33This library is distributed in the hope that it will be useful,
34but WITHOUT ANY WARRANTY; without even the implied warranty of
35MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
36Lesser General Public License for more details.
37
38You should have received a copy of the GNU Lesser General Public
39License along with this library; if not, write to the Free Software
40Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA,
41or see http://www.gnu.org/copyleft/lesser.html
42*/
43
44
45var jg_ok, jg_ie, jg_fast, jg_dom, jg_moz;
46
47
48function _chkDHTM(wnd, x, i)
49// Under XUL, owner of 'document' must be specified explicitly
50{
51        x = wnd.document.body || null;
52        jg_ie = x && typeof x.insertAdjacentHTML != "undefined" && wnd.document.createElement;
53        jg_dom = (x && !jg_ie &&
54                typeof x.appendChild != "undefined" &&
55                typeof wnd.document.createRange != "undefined" &&
56                typeof (i = wnd.document.createRange()).setStartBefore != "undefined" &&
57                typeof i.createContextualFragment != "undefined");
58        jg_fast = jg_ie && wnd.document.all && !wnd.opera;
59        jg_moz = jg_dom && typeof x.style.MozOpacity != "undefined";
60        jg_ok = !!(jg_ie || jg_dom);
61}
62
63function _pntCnvDom()
64{
65        var x = this.wnd.document.createRange();
66        x.setStartBefore(this.cnv);
67        x = x.createContextualFragment(jg_fast? this._htmRpc() : this.htm);
68        if(this.cnv) this.cnv.appendChild(x);
69        this.htm = "";
70}
71
72function _pntCnvIe()
73{
74        if(this.cnv) this.cnv.insertAdjacentHTML("BeforeEnd", jg_fast? this._htmRpc() : this.htm);
75        this.htm = "";
76}
77
78function _pntDoc()
79{
80        this.wnd.document.write(jg_fast? this._htmRpc() : this.htm);
81        this.htm = '';
82}
83
84function _pntN()
85{
86        ;
87}
88
89function _mkDiv(x, y, w, h)
90{
91        this.htm += '<div style="position:absolute;'+
92                'left:' + x + 'px;'+
93                'top:' + y + 'px;'+
94                'width:' + w + 'px;'+
95                'height:' + h + 'px;'+
96                'clip:rect(0,'+w+'px,'+h+'px,0);'+
97                'background-color:' + this.color +
98                (!jg_moz? ';overflow:hidden' : '')+
99                ';"><\/div>';
100}
101
102function _mkDivIe(x, y, w, h)
103{
104        this.htm += '%%'+this.color+';'+x+';'+y+';'+w+';'+h+';';
105}
106
107function _mkDivPrt(x, y, w, h)
108{
109        this.htm += '<div style="position:absolute;'+
110                'border-left:' + w + 'px solid ' + this.color + ';'+
111                'left:' + x + 'px;'+
112                'top:' + y + 'px;'+
113                'width:0px;'+
114                'height:' + h + 'px;'+
115                'clip:rect(0,'+w+'px,'+h+'px,0);'+
116                'background-color:' + this.color +
117                (!jg_moz? ';overflow:hidden' : '')+
118                ';"><\/div>';
119}
120
121var _regex =  /%%([^;]+);([^;]+);([^;]+);([^;]+);([^;]+);/g;
122function _htmRpc()
123{
124        return this.htm.replace(
125                _regex,
126                '<div style="overflow:hidden;position:absolute;background-color:'+
127                '$1;left:$2px;top:$3px;width:$4px;height:$5px"></div>\n');
128}
129
130function _htmPrtRpc()
131{
132        return this.htm.replace(
133                _regex,
134                '<div style="overflow:hidden;position:absolute;background-color:'+
135                '$1;left:$2px;top:$3px;width:$4px;height:$5px;border-left:$4px solid $1"></div>\n');
136}
137
138function _mkLin(x1, y1, x2, y2)
139{
140        if(x1 > x2)
141        {
142                var _x2 = x2;
143                var _y2 = y2;
144                x2 = x1;
145                y2 = y1;
146                x1 = _x2;
147                y1 = _y2;
148        }
149        var dx = x2-x1, dy = Math.abs(y2-y1),
150        x = x1, y = y1,
151        yIncr = (y1 > y2)? -1 : 1;
152
153        if(dx >= dy)
154        {
155                var pr = dy<<1,
156                pru = pr - (dx<<1),
157                p = pr-dx,
158                ox = x;
159                while(dx > 0)
160                {--dx;
161                        ++x;
162                        if(p > 0)
163                        {
164                                this._mkDiv(ox, y, x-ox, 1);
165                                y += yIncr;
166                                p += pru;
167                                ox = x;
168                        }
169                        else p += pr;
170                }
171                this._mkDiv(ox, y, x2-ox+1, 1);
172        }
173
174        else
175        {
176                var pr = dx<<1,
177                pru = pr - (dy<<1),
178                p = pr-dy,
179                oy = y;
180                if(y2 <= y1)
181                {
182                        while(dy > 0)
183                        {--dy;
184                                if(p > 0)
185                                {
186                                        this._mkDiv(x++, y, 1, oy-y+1);
187                                        y += yIncr;
188                                        p += pru;
189                                        oy = y;
190                                }
191                                else
192                                {
193                                        y += yIncr;
194                                        p += pr;
195                                }
196                        }
197                        this._mkDiv(x2, y2, 1, oy-y2+1);
198                }
199                else
200                {
201                        while(dy > 0)
202                        {--dy;
203                                y += yIncr;
204                                if(p > 0)
205                                {
206                                        this._mkDiv(x++, oy, 1, y-oy);
207                                        p += pru;
208                                        oy = y;
209                                }
210                                else p += pr;
211                        }
212                        this._mkDiv(x2, oy, 1, y2-oy+1);
213                }
214        }
215}
216
217function _mkLin2D(x1, y1, x2, y2)
218{
219        if(x1 > x2)
220        {
221                var _x2 = x2;
222                var _y2 = y2;
223                x2 = x1;
224                y2 = y1;
225                x1 = _x2;
226                y1 = _y2;
227        }
228        var dx = x2-x1, dy = Math.abs(y2-y1),
229        x = x1, y = y1,
230        yIncr = (y1 > y2)? -1 : 1;
231
232        var s = this.stroke;
233        if(dx >= dy)
234        {
235                if(dx > 0 && s-3 > 0)
236                {
237                        var _s = (s*dx*Math.sqrt(1+dy*dy/(dx*dx))-dx-(s>>1)*dy) / dx;
238                        _s = (!(s-4)? Math.ceil(_s) : Math.round(_s)) + 1;
239                }
240                else var _s = s;
241                var ad = Math.ceil(s/2);
242
243                var pr = dy<<1,
244                pru = pr - (dx<<1),
245                p = pr-dx,
246                ox = x;
247                while(dx > 0)
248                {--dx;
249                        ++x;
250                        if(p > 0)
251                        {
252                                this._mkDiv(ox, y, x-ox+ad, _s);
253                                y += yIncr;
254                                p += pru;
255                                ox = x;
256                        }
257                        else p += pr;
258                }
259                this._mkDiv(ox, y, x2-ox+ad+1, _s);
260        }
261
262        else
263        {
264                if(s-3 > 0)
265                {
266                        var _s = (s*dy*Math.sqrt(1+dx*dx/(dy*dy))-(s>>1)*dx-dy) / dy;
267                        _s = (!(s-4)? Math.ceil(_s) : Math.round(_s)) + 1;
268                }
269                else var _s = s;
270                var ad = Math.round(s/2);
271
272                var pr = dx<<1,
273                pru = pr - (dy<<1),
274                p = pr-dy,
275                oy = y;
276                if(y2 <= y1)
277                {
278                        ++ad;
279                        while(dy > 0)
280                        {--dy;
281                                if(p > 0)
282                                {
283                                        this._mkDiv(x++, y, _s, oy-y+ad);
284                                        y += yIncr;
285                                        p += pru;
286                                        oy = y;
287                                }
288                                else
289                                {
290                                        y += yIncr;
291                                        p += pr;
292                                }
293                        }
294                        this._mkDiv(x2, y2, _s, oy-y2+ad);
295                }
296                else
297                {
298                        while(dy > 0)
299                        {--dy;
300                                y += yIncr;
301                                if(p > 0)
302                                {
303                                        this._mkDiv(x++, oy, _s, y-oy+ad);
304                                        p += pru;
305                                        oy = y;
306                                }
307                                else p += pr;
308                        }
309                        this._mkDiv(x2, oy, _s, y2-oy+ad+1);
310                }
311        }
312}
313
314function _mkLinDott(x1, y1, x2, y2)
315{
316        if(x1 > x2)
317        {
318                var _x2 = x2;
319                var _y2 = y2;
320                x2 = x1;
321                y2 = y1;
322                x1 = _x2;
323                y1 = _y2;
324        }
325        var dx = x2-x1, dy = Math.abs(y2-y1),
326        x = x1, y = y1,
327        yIncr = (y1 > y2)? -1 : 1,
328        drw = true;
329        if(dx >= dy)
330        {
331                var pr = dy<<1,
332                pru = pr - (dx<<1),
333                p = pr-dx;
334                while(dx > 0)
335                {--dx;
336                        if(drw) this._mkDiv(x, y, 1, 1);
337                        drw = !drw;
338                        if(p > 0)
339                        {
340                                y += yIncr;
341                                p += pru;
342                        }
343                        else p += pr;
344                        ++x;
345                }
346        }
347        else
348        {
349                var pr = dx<<1,
350                pru = pr - (dy<<1),
351                p = pr-dy;
352                while(dy > 0)
353                {--dy;
354                        if(drw) this._mkDiv(x, y, 1, 1);
355                        drw = !drw;
356                        y += yIncr;
357                        if(p > 0)
358                        {
359                                ++x;
360                                p += pru;
361                        }
362                        else p += pr;
363                }
364        }
365        if(drw) this._mkDiv(x, y, 1, 1);
366}
367
368function _mkOv(left, top, width, height)
369{
370        var a = (++width)>>1, b = (++height)>>1,
371        wod = width&1, hod = height&1,
372        cx = left+a, cy = top+b,
373        x = 0, y = b,
374        ox = 0, oy = b,
375        aa2 = (a*a)<<1, aa4 = aa2<<1, bb2 = (b*b)<<1, bb4 = bb2<<1,
376        st = (aa2>>1)*(1-(b<<1)) + bb2,
377        tt = (bb2>>1) - aa2*((b<<1)-1),
378        w, h;
379        while(y > 0)
380        {
381                if(st < 0)
382                {
383                        st += bb2*((x<<1)+3);
384                        tt += bb4*(++x);
385                }
386                else if(tt < 0)
387                {
388                        st += bb2*((x<<1)+3) - aa4*(y-1);
389                        tt += bb4*(++x) - aa2*(((y--)<<1)-3);
390                        w = x-ox;
391                        h = oy-y;
392                        if((w&2) && (h&2))
393                        {
394                                this._mkOvQds(cx, cy, x-2, y+2, 1, 1, wod, hod);
395                                this._mkOvQds(cx, cy, x-1, y+1, 1, 1, wod, hod);
396                        }
397                        else this._mkOvQds(cx, cy, x-1, oy, w, h, wod, hod);
398                        ox = x;
399                        oy = y;
400                }
401                else
402                {
403                        tt -= aa2*((y<<1)-3);
404                        st -= aa4*(--y);
405                }
406        }
407        w = a-ox+1;
408        h = (oy<<1)+hod;
409        y = cy-oy;
410        this._mkDiv(cx-a, y, w, h);
411        this._mkDiv(cx+ox+wod-1, y, w, h);
412}
413
414function _mkOv2D(left, top, width, height)
415{
416        var s = this.stroke;
417        width += s+1;
418        height += s+1;
419        var a = width>>1, b = height>>1,
420        wod = width&1, hod = height&1,
421        cx = left+a, cy = top+b,
422        x = 0, y = b,
423        aa2 = (a*a)<<1, aa4 = aa2<<1, bb2 = (b*b)<<1, bb4 = bb2<<1,
424        st = (aa2>>1)*(1-(b<<1)) + bb2,
425        tt = (bb2>>1) - aa2*((b<<1)-1);
426
427        if(s-4 < 0 && (!(s-2) || width-51 > 0 && height-51 > 0))
428        {
429                var ox = 0, oy = b,
430                w, h,
431                pxw;
432                while(y > 0)
433                {
434                        if(st < 0)
435                        {
436                                st += bb2*((x<<1)+3);
437                                tt += bb4*(++x);
438                        }
439                        else if(tt < 0)
440                        {
441                                st += bb2*((x<<1)+3) - aa4*(y-1);
442                                tt += bb4*(++x) - aa2*(((y--)<<1)-3);
443                                w = x-ox;
444                                h = oy-y;
445
446                                if(w-1)
447                                {
448                                        pxw = w+1+(s&1);
449                                        h = s;
450                                }
451                                else if(h-1)
452                                {
453                                        pxw = s;
454                                        h += 1+(s&1);
455                                }
456                                else pxw = h = s;
457                                this._mkOvQds(cx, cy, x-1, oy, pxw, h, wod, hod);
458                                ox = x;
459                                oy = y;
460                        }
461                        else
462                        {
463                                tt -= aa2*((y<<1)-3);
464                                st -= aa4*(--y);
465                        }
466                }
467                this._mkDiv(cx-a, cy-oy, s, (oy<<1)+hod);
468                this._mkDiv(cx+a+wod-s, cy-oy, s, (oy<<1)+hod);
469        }
470
471        else
472        {
473                var _a = (width-(s<<1))>>1,
474                _b = (height-(s<<1))>>1,
475                _x = 0, _y = _b,
476                _aa2 = (_a*_a)<<1, _aa4 = _aa2<<1, _bb2 = (_b*_b)<<1, _bb4 = _bb2<<1,
477                _st = (_aa2>>1)*(1-(_b<<1)) + _bb2,
478                _tt = (_bb2>>1) - _aa2*((_b<<1)-1),
479
480                pxl = new Array(),
481                pxt = new Array(),
482                _pxb = new Array();
483                pxl[0] = 0;
484                pxt[0] = b;
485                _pxb[0] = _b-1;
486                while(y > 0)
487                {
488                        if(st < 0)
489                        {
490                                pxl[pxl.length] = x;
491                                pxt[pxt.length] = y;
492                                st += bb2*((x<<1)+3);
493                                tt += bb4*(++x);
494                        }
495                        else if(tt < 0)
496                        {
497                                pxl[pxl.length] = x;
498                                st += bb2*((x<<1)+3) - aa4*(y-1);
499                                tt += bb4*(++x) - aa2*(((y--)<<1)-3);
500                                pxt[pxt.length] = y;
501                        }
502                        else
503                        {
504                                tt -= aa2*((y<<1)-3);
505                                st -= aa4*(--y);
506                        }
507
508                        if(_y > 0)
509                        {
510                                if(_st < 0)
511                                {
512                                        _st += _bb2*((_x<<1)+3);
513                                        _tt += _bb4*(++_x);
514                                        _pxb[_pxb.length] = _y-1;
515                                }
516                                else if(_tt < 0)
517                                {
518                                        _st += _bb2*((_x<<1)+3) - _aa4*(_y-1);
519                                        _tt += _bb4*(++_x) - _aa2*(((_y--)<<1)-3);
520                                        _pxb[_pxb.length] = _y-1;
521                                }
522                                else
523                                {
524                                        _tt -= _aa2*((_y<<1)-3);
525                                        _st -= _aa4*(--_y);
526                                        _pxb[_pxb.length-1]--;
527                                }
528                        }
529                }
530
531                var ox = -wod, oy = b,
532                _oy = _pxb[0],
533                l = pxl.length,
534                w, h;
535                for(var i = 0; i < l; i++)
536                {
537                        if(typeof _pxb[i] != "undefined")
538                        {
539                                if(_pxb[i] < _oy || pxt[i] < oy)
540                                {
541                                        x = pxl[i];
542                                        this._mkOvQds(cx, cy, x, oy, x-ox, oy-_oy, wod, hod);
543                                        ox = x;
544                                        oy = pxt[i];
545                                        _oy = _pxb[i];
546                                }
547                        }
548                        else
549                        {
550                                x = pxl[i];
551                                this._mkDiv(cx-x, cy-oy, 1, (oy<<1)+hod);
552                                this._mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod);
553                                ox = x;
554                                oy = pxt[i];
555                        }
556                }
557                this._mkDiv(cx-a, cy-oy, 1, (oy<<1)+hod);
558                this._mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod);
559        }
560}
561
562function _mkOvDott(left, top, width, height)
563{
564        var a = (++width)>>1, b = (++height)>>1,
565        wod = width&1, hod = height&1, hodu = hod^1,
566        cx = left+a, cy = top+b,
567        x = 0, y = b,
568        aa2 = (a*a)<<1, aa4 = aa2<<1, bb2 = (b*b)<<1, bb4 = bb2<<1,
569        st = (aa2>>1)*(1-(b<<1)) + bb2,
570        tt = (bb2>>1) - aa2*((b<<1)-1),
571        drw = true;
572        while(y > 0)
573        {
574                if(st < 0)
575                {
576                        st += bb2*((x<<1)+3);
577                        tt += bb4*(++x);
578                }
579                else if(tt < 0)
580                {
581                        st += bb2*((x<<1)+3) - aa4*(y-1);
582                        tt += bb4*(++x) - aa2*(((y--)<<1)-3);
583                }
584                else
585                {
586                        tt -= aa2*((y<<1)-3);
587                        st -= aa4*(--y);
588                }
589                if(drw && y >= hodu) this._mkOvQds(cx, cy, x, y, 1, 1, wod, hod);
590                drw = !drw;
591        }
592}
593
594function _mkRect(x, y, w, h)
595{
596        var s = this.stroke;
597        this._mkDiv(x, y, w, s);
598        this._mkDiv(x+w, y, s, h);
599        this._mkDiv(x, y+h, w+s, s);
600        this._mkDiv(x, y+s, s, h-s);
601}
602
603function _mkRectDott(x, y, w, h)
604{
605        this.drawLine(x, y, x+w, y);
606        this.drawLine(x+w, y, x+w, y+h);
607        this.drawLine(x, y+h, x+w, y+h);
608        this.drawLine(x, y, x, y+h);
609}
610
611function jsgFont()
612{
613        this.PLAIN = 'font-weight:normal;';
614        this.BOLD = 'font-weight:bold;';
615        this.ITALIC = 'font-style:italic;';
616        this.ITALIC_BOLD = this.ITALIC + this.BOLD;
617        this.BOLD_ITALIC = this.ITALIC_BOLD;
618}
619var Font = new jsgFont();
620
621function jsgStroke()
622{
623        this.DOTTED = -1;
624}
625var Stroke = new jsgStroke();
626
627function jsGraphics(cnv, wnd)
628{
629        this.setColor = function(x)
630        {
631                this.color = x.toLowerCase();
632        };
633
634        this.setStroke = function(x)
635        {
636                this.stroke = x;
637                if(!(x+1))
638                {
639                        this.drawLine = _mkLinDott;
640                        this._mkOv = _mkOvDott;
641                        this.drawRect = _mkRectDott;
642                }
643                else if(x-1 > 0)
644                {
645                        this.drawLine = _mkLin2D;
646                        this._mkOv = _mkOv2D;
647                        this.drawRect = _mkRect;
648                }
649                else
650                {
651                        this.drawLine = _mkLin;
652                        this._mkOv = _mkOv;
653                        this.drawRect = _mkRect;
654                }
655        };
656
657        this.setPrintable = function(arg)
658        {
659                this.printable = arg;
660                if(jg_fast)
661                {
662                        this._mkDiv = _mkDivIe;
663                        this._htmRpc = arg? _htmPrtRpc : _htmRpc;
664                }
665                else this._mkDiv = arg? _mkDivPrt : _mkDiv;
666        };
667
668        this.setFont = function(fam, sz, sty)
669        {
670                this.ftFam = fam;
671                this.ftSz = sz;
672                this.ftSty = sty || Font.PLAIN;
673        };
674
675        this.drawPolyline = this.drawPolyLine = function(x, y)
676        {
677                for (var i=x.length - 1; i;)
678                {--i;
679                        this.drawLine(x[i], y[i], x[i+1], y[i+1]);
680                }
681        };
682
683        this.fillRect = function(x, y, w, h)
684        {
685                this._mkDiv(x, y, w, h);
686        };
687
688        this.drawPolygon = function(x, y)
689        {
690                this.drawPolyline(x, y);
691                this.drawLine(x[x.length-1], y[x.length-1], x[0], y[0]);
692        };
693
694        this.drawEllipse = this.drawOval = function(x, y, w, h)
695        {
696                this._mkOv(x, y, w, h);
697        };
698
699        this.fillEllipse = this.fillOval = function(left, top, w, h)
700        {
701                var a = w>>1, b = h>>1,
702                wod = w&1, hod = h&1,
703                cx = left+a, cy = top+b,
704                x = 0, y = b, oy = b,
705                aa2 = (a*a)<<1, aa4 = aa2<<1, bb2 = (b*b)<<1, bb4 = bb2<<1,
706                st = (aa2>>1)*(1-(b<<1)) + bb2,
707                tt = (bb2>>1) - aa2*((b<<1)-1),
708                xl, dw, dh;
709                if(w) while(y > 0)
710                {
711                        if(st < 0)
712                        {
713                                st += bb2*((x<<1)+3);
714                                tt += bb4*(++x);
715                        }
716                        else if(tt < 0)
717                        {
718                                st += bb2*((x<<1)+3) - aa4*(y-1);
719                                xl = cx-x;
720                                dw = (x<<1)+wod;
721                                tt += bb4*(++x) - aa2*(((y--)<<1)-3);
722                                dh = oy-y;
723                                this._mkDiv(xl, cy-oy, dw, dh);
724                                this._mkDiv(xl, cy+y+hod, dw, dh);
725                                oy = y;
726                        }
727                        else
728                        {
729                                tt -= aa2*((y<<1)-3);
730                                st -= aa4*(--y);
731                        }
732                }
733                this._mkDiv(cx-a, cy-oy, w, (oy<<1)+hod);
734        };
735
736        this.fillArc = function(iL, iT, iW, iH, fAngA, fAngZ)
737        {
738                var a = iW>>1, b = iH>>1,
739                iOdds = (iW&1) | ((iH&1) << 16),
740                cx = iL+a, cy = iT+b,
741                x = 0, y = b, ox = x, oy = y,
742                aa2 = (a*a)<<1, aa4 = aa2<<1, bb2 = (b*b)<<1, bb4 = bb2<<1,
743                st = (aa2>>1)*(1-(b<<1)) + bb2,
744                tt = (bb2>>1) - aa2*((b<<1)-1),
745                // Vars for radial boundary lines
746                xEndA, yEndA, xEndZ, yEndZ,
747                iSects = (1 << (Math.floor((fAngA %= 360.0)/180.0) << 3))
748                                | (2 << (Math.floor((fAngZ %= 360.0)/180.0) << 3))
749                                | ((fAngA >= fAngZ) << 16),
750                aBndA = new Array(b+1), aBndZ = new Array(b+1);
751               
752                // Set up radial boundary lines
753                fAngA *= Math.PI/180.0;
754                fAngZ *= Math.PI/180.0;
755                xEndA = cx+Math.round(a*Math.cos(fAngA));
756                yEndA = cy+Math.round(-b*Math.sin(fAngA));
757                _mkLinVirt(aBndA, cx, cy, xEndA, yEndA);
758                xEndZ = cx+Math.round(a*Math.cos(fAngZ));
759                yEndZ = cy+Math.round(-b*Math.sin(fAngZ));
760                _mkLinVirt(aBndZ, cx, cy, xEndZ, yEndZ);
761
762                while(y > 0)
763                {
764                        if(st < 0) // Advance x
765                        {
766                                st += bb2*((x<<1)+3);
767                                tt += bb4*(++x);
768                        }
769                        else if(tt < 0) // Advance x and y
770                        {
771                                st += bb2*((x<<1)+3) - aa4*(y-1);
772                                ox = x;
773                                tt += bb4*(++x) - aa2*(((y--)<<1)-3);
774                                this._mkArcDiv(ox, y, oy, cx, cy, iOdds, aBndA, aBndZ, iSects);
775                                oy = y;
776                        }
777                        else // Advance y
778                        {
779                                tt -= aa2*((y<<1)-3);
780                                st -= aa4*(--y);
781                                if(y && (aBndA[y] != aBndA[y-1] || aBndZ[y] != aBndZ[y-1]))
782                                {
783                                        this._mkArcDiv(x, y, oy, cx, cy, iOdds, aBndA, aBndZ, iSects);
784                                        ox = x;
785                                        oy = y;
786                                }
787                        }
788                }
789                this._mkArcDiv(x, 0, oy, cx, cy, iOdds, aBndA, aBndZ, iSects);
790                if(iOdds >> 16) // Odd height
791                {
792                        if(iSects >> 16) // Start-angle > end-angle
793                        {
794                                var xl = (yEndA <= cy || yEndZ > cy)? (cx - x) : cx;
795                                this._mkDiv(xl, cy, x + cx - xl + (iOdds & 0xffff), 1);
796                        }
797                        else if((iSects & 0x01) && yEndZ > cy)
798                                this._mkDiv(cx - x, cy, x, 1);
799                }
800        };
801
802/* fillPolygon method, implemented by Matthieu Haller.
803This javascript function is an adaptation of the gdImageFilledPolygon for Walter Zorn lib.
804C source of GD 1.8.4 found at http://www.boutell.com/gd/
805
806THANKS to Kirsten Schulz for the polygon fixes!
807
808The intersection finding technique of this code could be improved
809by remembering the previous intertersection, and by using the slope.
810That could help to adjust intersections to produce a nice
811interior_extrema. */
812        this.fillPolygon = function(array_x, array_y)
813        {
814                var i;
815                var y;
816                var miny, maxy;
817                var x1, y1;
818                var x2, y2;
819                var ind1, ind2;
820                var ints;
821
822                var n = array_x.length;
823                if(!n) return;
824
825                miny = array_y[0];
826                maxy = array_y[0];
827                for(i = 1; i < n; i++)
828                {
829                        if(array_y[i] < miny)
830                                miny = array_y[i];
831
832                        if(array_y[i] > maxy)
833                                maxy = array_y[i];
834                }
835                for(y = miny; y <= maxy; y++)
836                {
837                        var polyInts = new Array();
838                        ints = 0;
839                        for(i = 0; i < n; i++)
840                        {
841                                if(!i)
842                                {
843                                        ind1 = n-1;
844                                        ind2 = 0;
845                                }
846                                else
847                                {
848                                        ind1 = i-1;
849                                        ind2 = i;
850                                }
851                                y1 = array_y[ind1];
852                                y2 = array_y[ind2];
853                                if(y1 < y2)
854                                {
855                                        x1 = array_x[ind1];
856                                        x2 = array_x[ind2];
857                                }
858                                else if(y1 > y2)
859                                {
860                                        y2 = array_y[ind1];
861                                        y1 = array_y[ind2];
862                                        x2 = array_x[ind1];
863                                        x1 = array_x[ind2];
864                                }
865                                else continue;
866
867                                 //  Modified 11. 2. 2004 Walter Zorn
868                                if((y >= y1) && (y < y2))
869                                        polyInts[ints++] = Math.round((y-y1) * (x2-x1) / (y2-y1) + x1);
870
871                                else if((y == maxy) && (y > y1) && (y <= y2))
872                                        polyInts[ints++] = Math.round((y-y1) * (x2-x1) / (y2-y1) + x1);
873                        }
874                        polyInts.sort(_CompInt);
875                        for(i = 0; i < ints; i+=2)
876                                this._mkDiv(polyInts[i], y, polyInts[i+1]-polyInts[i]+1, 1);
877                }
878        };
879
880        this.drawString = function(txt, x, y)
881        {
882                this.htm += '<div style="position:absolute;white-space:nowrap;'+
883                        'left:' + x + 'px;'+
884                        'top:' + y + 'px;'+
885                        'font-family:' +  this.ftFam + ';'+
886                        'font-size:' + this.ftSz + ';'+
887                        'color:' + this.color + ';' + this.ftSty + '">'+
888                        txt +
889                        '<\/div>';
890        };
891
892/* drawStringRect() added by Rick Blommers.
893Allows to specify the size of the text rectangle and to align the
894text both horizontally (e.g. right) and vertically within that rectangle */
895        this.drawStringRect = function(txt, x, y, width, halign)
896        {
897                this.htm += '<div style="position:absolute;overflow:hidden;'+
898                        'left:' + x + 'px;'+
899                        'top:' + y + 'px;'+
900                        'width:'+width +'px;'+
901                        'text-align:'+halign+';'+
902                        'font-family:' +  this.ftFam + ';'+
903                        'font-size:' + this.ftSz + ';'+
904                        'color:' + this.color + ';' + this.ftSty + '">'+
905                        txt +
906                        '<\/div>';
907        };
908
909        this.drawImage = function(imgSrc, x, y, w, h, a)
910        {
911                this.htm += '<div style="position:absolute;'+
912                        'left:' + x + 'px;'+
913                        'top:' + y + 'px;'+
914                        // w (width) and h (height) arguments are now optional.
915                        // Added by Mahmut Keygubatli, 14.1.2008
916                        (w? ('width:' +  w + 'px;') : '') +
917                        (h? ('height:' + h + 'px;'):'')+'">'+
918                        '<img src="' + imgSrc +'"'+ (w ? (' width="' + w + '"'):'')+ (h ? (' height="' + h + '"'):'') + (a? (' '+a) : '') + '>'+
919                        '<\/div>';
920        };
921
922        this.clear = function()
923        {
924                this.htm = "";
925                if(this.cnv) this.cnv.innerHTML = "";
926        };
927
928        this._mkOvQds = function(cx, cy, x, y, w, h, wod, hod)
929        {
930                var xl = cx - x, xr = cx + x + wod - w, yt = cy - y, yb = cy + y + hod - h;
931                if(xr > xl+w)
932                {
933                        this._mkDiv(xr, yt, w, h);
934                        this._mkDiv(xr, yb, w, h);
935                }
936                else
937                        w = xr - xl + w;
938                this._mkDiv(xl, yt, w, h);
939                this._mkDiv(xl, yb, w, h);
940        };
941       
942        this._mkArcDiv = function(x, y, oy, cx, cy, iOdds, aBndA, aBndZ, iSects)
943        {
944                var xrDef = cx + x + (iOdds & 0xffff), y2, h = oy - y, xl, xr, w;
945
946                if(!h) h = 1;
947                x = cx - x;
948
949                if(iSects & 0xff0000) // Start-angle > end-angle
950                {
951                        y2 = cy - y - h;
952                        if(iSects & 0x00ff)
953                        {
954                                if(iSects & 0x02)
955                                {
956                                        xl = Math.max(x, aBndZ[y]);
957                                        w = xrDef - xl;
958                                        if(w > 0) this._mkDiv(xl, y2, w, h);
959                                }
960                                if(iSects & 0x01)
961                                {
962                                        xr = Math.min(xrDef, aBndA[y]);
963                                        w = xr - x;
964                                        if(w > 0) this._mkDiv(x, y2, w, h);
965                                }
966                        }
967                        else
968                                this._mkDiv(x, y2, xrDef - x, h);
969                        y2 = cy + y + (iOdds >> 16);
970                        if(iSects & 0xff00)
971                        {
972                                if(iSects & 0x0100)
973                                {
974                                        xl = Math.max(x, aBndA[y]);
975                                        w = xrDef - xl;
976                                        if(w > 0) this._mkDiv(xl, y2, w, h);
977                                }
978                                if(iSects & 0x0200)
979                                {
980                                        xr = Math.min(xrDef, aBndZ[y]);
981                                        w = xr - x;
982                                        if(w > 0) this._mkDiv(x, y2, w, h);
983                                }
984                        }
985                        else
986                                this._mkDiv(x, y2, xrDef - x, h);
987                }
988                else
989                {
990                        if(iSects & 0x00ff)
991                        {
992                                if(iSects & 0x02)
993                                        xl = Math.max(x, aBndZ[y]);
994                                else
995                                        xl = x;
996                                if(iSects & 0x01)
997                                        xr = Math.min(xrDef, aBndA[y]);
998                                else
999                                        xr = xrDef;
1000                                y2 = cy - y - h;
1001                                w = xr - xl;
1002                                if(w > 0) this._mkDiv(xl, y2, w, h);
1003                        }
1004                        if(iSects & 0xff00)
1005                        {
1006                                if(iSects & 0x0100)
1007                                        xl = Math.max(x, aBndA[y]);
1008                                else
1009                                        xl = x;
1010                                if(iSects & 0x0200)
1011                                        xr = Math.min(xrDef, aBndZ[y]);
1012                                else
1013                                        xr = xrDef;
1014                                y2 = cy + y + (iOdds >> 16);
1015                                w = xr - xl;
1016                                if(w > 0) this._mkDiv(xl, y2, w, h);
1017                        }
1018                }
1019        };
1020
1021        this.setStroke(1);
1022        this.setFont("verdana,geneva,helvetica,sans-serif", "12px", Font.PLAIN);
1023        this.color = "#000000";
1024        this.htm = "";
1025        this.wnd = wnd || window;
1026
1027        if(!jg_ok) _chkDHTM(this.wnd);
1028        if(jg_ok)
1029        {
1030                if(cnv)
1031                {
1032                        if(typeof(cnv) == "string")
1033                                this.cont = document.all? (this.wnd.document.all[cnv] || null)
1034                                        : document.getElementById? (this.wnd.document.getElementById(cnv) || null)
1035                                        : null;
1036                        else if(cnv == window.document)
1037                                this.cont = document.getElementsByTagName("body")[0];
1038                        // If cnv is a direct reference to a canvas DOM node
1039                        // (option suggested by Andreas Luleich)
1040                        else this.cont = cnv;
1041                        // Create new canvas inside container DIV. Thus the drawing and clearing
1042                        // methods won't interfere with the container's inner html.
1043                        // Solution suggested by Vladimir.
1044                        this.cnv = this.wnd.document.createElement("div");
1045                        this.cnv.style.fontSize=0;
1046                        this.cont.appendChild(this.cnv);
1047                        this.paint = jg_dom? _pntCnvDom : _pntCnvIe;
1048                }
1049                else
1050                        this.paint = _pntDoc;
1051        }
1052        else
1053                this.paint = _pntN;
1054
1055        this.setPrintable(false);
1056}
1057
1058function _mkLinVirt(aLin, x1, y1, x2, y2)
1059{
1060        var dx = Math.abs(x2-x1), dy = Math.abs(y2-y1),
1061        x = x1, y = y1,
1062        xIncr = (x1 > x2)? -1 : 1,
1063        yIncr = (y1 > y2)? -1 : 1,
1064        p,
1065        i = 0;
1066        if(dx >= dy)
1067        {
1068                var pr = dy<<1,
1069                pru = pr - (dx<<1);
1070                p = pr-dx;
1071                while(dx > 0)
1072                {--dx;
1073                        if(p > 0)    //  Increment y
1074                        {
1075                                aLin[i++] = x;
1076                                y += yIncr;
1077                                p += pru;
1078                        }
1079                        else p += pr;
1080                        x += xIncr;
1081                }
1082        }
1083        else
1084        {
1085                var pr = dx<<1,
1086                pru = pr - (dy<<1);
1087                p = pr-dy;
1088                while(dy > 0)
1089                {--dy;
1090                        y += yIncr;
1091                        aLin[i++] = x;
1092                        if(p > 0)    //  Increment x
1093                        {
1094                                x += xIncr;
1095                                p += pru;
1096                        }
1097                        else p += pr;
1098                }
1099        }
1100        for(var len = aLin.length, i = len-i; i;)
1101                aLin[len-(i--)] = x;
1102};
1103
1104function _CompInt(x, y)
1105{
1106        return(x - y);
1107}
1108
Note: See TracBrowser for help on using the repository browser.