source: source/wz_jsgraphics.js @ 118:e32d45d47e18

Last change on this file since 118:e32d45d47e18 was 30:e1d0ed7a5346, checked in by fnevgeny, 17 years ago

Added canvas/Canvas and canvas/Plotter classes based on the wz_jsgraphics
library.

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