source: source/wz_jsgraphics.js @ 240:1effc3e5d945

Last change on this file since 240:1effc3e5d945 was 200:81258d8764d5, checked in by fnevgeny, 13 years ago

Added string rotation.

File size: 24.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/* ES: added rotation, using
896http://stackoverflow.com/questions/272799/vertical-rotated-text-in-html-table */
897        this.drawStringRect = function(txt, x, y, width, halign, angle)
898        {
899                var angleSty = '';
900                if (angle) {
901                    angle = parseInt(angle);
902                    var rot = angle/90;
903                    angleSty = 
904                        '-moz-transform: rotate(' + angle + 'deg);'                                    +    /* FF3.5+          */ 
905                        '-o-transform: rotate(' + angle + 'deg);'                                      +    /* Opera 10.5      */
906                        '-webkit-transform: rotate(' + angle + 'deg);'                                 +    /* Saf3.1+, Chrome */
907                        'filter:  progid:DXImageTransform.Microsoft.BasicImage(rotation=' + rot + ');' +    /* IE6,IE7         */       
908                        '-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=' + rot + ');'; /* IE8             */           
909                }
910               
911                this.htm += '<div style="position:absolute;overflow:hidden;'+
912                        'left:' + x + 'px;'+
913                        'top:' + y + 'px;'+
914                        'width:'+width +'px;'+
915                        'text-align:'+halign+';'+
916                        'font-family:' +  this.ftFam + ';'+
917                        'font-size:' + this.ftSz + ';'+
918                        'color:' + this.color + ';' + this.ftSty + angleSty + '">'+
919                        txt +
920                        '<\/div>';
921        };
922
923        this.drawImage = function(imgSrc, x, y, w, h, a)
924        {
925                this.htm += '<div style="position:absolute;'+
926                        'left:' + x + 'px;'+
927                        'top:' + y + 'px;'+
928                        // w (width) and h (height) arguments are now optional.
929                        // Added by Mahmut Keygubatli, 14.1.2008
930                        (w? ('width:' +  w + 'px;') : '') +
931                        (h? ('height:' + h + 'px;'):'')+'">'+
932                        '<img src="' + imgSrc +'"'+ (w ? (' width="' + w + '"'):'')+ (h ? (' height="' + h + '"'):'') + (a? (' '+a) : '') + '>'+
933                        '<\/div>';
934        };
935
936        this.clear = function()
937        {
938                this.htm = "";
939                if(this.cnv) this.cnv.innerHTML = "";
940        };
941
942        this._mkOvQds = function(cx, cy, x, y, w, h, wod, hod)
943        {
944                var xl = cx - x, xr = cx + x + wod - w, yt = cy - y, yb = cy + y + hod - h;
945                if(xr > xl+w)
946                {
947                        this._mkDiv(xr, yt, w, h);
948                        this._mkDiv(xr, yb, w, h);
949                }
950                else
951                        w = xr - xl + w;
952                this._mkDiv(xl, yt, w, h);
953                this._mkDiv(xl, yb, w, h);
954        };
955       
956        this._mkArcDiv = function(x, y, oy, cx, cy, iOdds, aBndA, aBndZ, iSects)
957        {
958                var xrDef = cx + x + (iOdds & 0xffff), y2, h = oy - y, xl, xr, w;
959
960                if(!h) h = 1;
961                x = cx - x;
962
963                if(iSects & 0xff0000) // Start-angle > end-angle
964                {
965                        y2 = cy - y - h;
966                        if(iSects & 0x00ff)
967                        {
968                                if(iSects & 0x02)
969                                {
970                                        xl = Math.max(x, aBndZ[y]);
971                                        w = xrDef - xl;
972                                        if(w > 0) this._mkDiv(xl, y2, w, h);
973                                }
974                                if(iSects & 0x01)
975                                {
976                                        xr = Math.min(xrDef, aBndA[y]);
977                                        w = xr - x;
978                                        if(w > 0) this._mkDiv(x, y2, w, h);
979                                }
980                        }
981                        else
982                                this._mkDiv(x, y2, xrDef - x, h);
983                        y2 = cy + y + (iOdds >> 16);
984                        if(iSects & 0xff00)
985                        {
986                                if(iSects & 0x0100)
987                                {
988                                        xl = Math.max(x, aBndA[y]);
989                                        w = xrDef - xl;
990                                        if(w > 0) this._mkDiv(xl, y2, w, h);
991                                }
992                                if(iSects & 0x0200)
993                                {
994                                        xr = Math.min(xrDef, aBndZ[y]);
995                                        w = xr - x;
996                                        if(w > 0) this._mkDiv(x, y2, w, h);
997                                }
998                        }
999                        else
1000                                this._mkDiv(x, y2, xrDef - x, h);
1001                }
1002                else
1003                {
1004                        if(iSects & 0x00ff)
1005                        {
1006                                if(iSects & 0x02)
1007                                        xl = Math.max(x, aBndZ[y]);
1008                                else
1009                                        xl = x;
1010                                if(iSects & 0x01)
1011                                        xr = Math.min(xrDef, aBndA[y]);
1012                                else
1013                                        xr = xrDef;
1014                                y2 = cy - y - h;
1015                                w = xr - xl;
1016                                if(w > 0) this._mkDiv(xl, y2, w, h);
1017                        }
1018                        if(iSects & 0xff00)
1019                        {
1020                                if(iSects & 0x0100)
1021                                        xl = Math.max(x, aBndA[y]);
1022                                else
1023                                        xl = x;
1024                                if(iSects & 0x0200)
1025                                        xr = Math.min(xrDef, aBndZ[y]);
1026                                else
1027                                        xr = xrDef;
1028                                y2 = cy + y + (iOdds >> 16);
1029                                w = xr - xl;
1030                                if(w > 0) this._mkDiv(xl, y2, w, h);
1031                        }
1032                }
1033        };
1034
1035        this.setStroke(1);
1036        this.setFont("verdana,geneva,helvetica,sans-serif", "12px", Font.PLAIN);
1037        this.color = "#000000";
1038        this.htm = "";
1039        this.wnd = wnd || window;
1040
1041        if(!jg_ok) _chkDHTM(this.wnd);
1042        if(jg_ok)
1043        {
1044                if(cnv)
1045                {
1046                        if(typeof(cnv) == "string")
1047                                this.cont = document.all? (this.wnd.document.all[cnv] || null)
1048                                        : document.getElementById? (this.wnd.document.getElementById(cnv) || null)
1049                                        : null;
1050                        else if(cnv == window.document)
1051                                this.cont = document.getElementsByTagName("body")[0];
1052                        // If cnv is a direct reference to a canvas DOM node
1053                        // (option suggested by Andreas Luleich)
1054                        else this.cont = cnv;
1055                        // Create new canvas inside container DIV. Thus the drawing and clearing
1056                        // methods won't interfere with the container's inner html.
1057                        // Solution suggested by Vladimir.
1058                        this.cnv = this.wnd.document.createElement("div");
1059                        this.cnv.style.fontSize=0;
1060                        this.cont.appendChild(this.cnv);
1061                        this.paint = jg_dom? _pntCnvDom : _pntCnvIe;
1062                }
1063                else
1064                        this.paint = _pntDoc;
1065        }
1066        else
1067                this.paint = _pntN;
1068
1069        this.setPrintable(false);
1070}
1071
1072function _mkLinVirt(aLin, x1, y1, x2, y2)
1073{
1074        var dx = Math.abs(x2-x1), dy = Math.abs(y2-y1),
1075        x = x1, y = y1,
1076        xIncr = (x1 > x2)? -1 : 1,
1077        yIncr = (y1 > y2)? -1 : 1,
1078        p,
1079        i = 0;
1080        if(dx >= dy)
1081        {
1082                var pr = dy<<1,
1083                pru = pr - (dx<<1);
1084                p = pr-dx;
1085                while(dx > 0)
1086                {--dx;
1087                        if(p > 0)    //  Increment y
1088                        {
1089                                aLin[i++] = x;
1090                                y += yIncr;
1091                                p += pru;
1092                        }
1093                        else p += pr;
1094                        x += xIncr;
1095                }
1096        }
1097        else
1098        {
1099                var pr = dx<<1,
1100                pru = pr - (dy<<1);
1101                p = pr-dy;
1102                while(dy > 0)
1103                {--dy;
1104                        y += yIncr;
1105                        aLin[i++] = x;
1106                        if(p > 0)    //  Increment x
1107                        {
1108                                x += xIncr;
1109                                p += pru;
1110                        }
1111                        else p += pr;
1112                }
1113        }
1114        for(var len = aLin.length, i = len-i; i;)
1115                aLin[len-(i--)] = x;
1116};
1117
1118function _CompInt(x, y)
1119{
1120        return(x - y);
1121}
1122
Note: See TracBrowser for help on using the repository browser.