Subversion Repositories wimsdev

Rev

Blame | Last modification | View Log | RSS feed

  1. /* This notice must be untouched at all times.
  2.  
  3. wz_jsgraphics.js    v. 3.03
  4. The latest version is available at
  5. http://www.walterzorn.com
  6. or http://www.devira.com
  7. or http://www.walterzorn.de
  8.  
  9. Copyright (c) 2002-2004 Walter Zorn. All rights reserved.
  10. Created 3. 11. 2002 by Walter Zorn (Web: http://www.walterzorn.com )
  11. Last modified: 28. 1. 2008
  12.  
  13. Performance optimizations for Internet Explorer
  14. by Thomas Frank and John Holdsworth.
  15. fillPolygon method implemented by Matthieu Haller.
  16.  
  17. High Performance JavaScript Graphics Library.
  18. Provides methods
  19. - to draw lines, rectangles, ellipses, polygons
  20.         with specifiable line thickness,
  21. - to fill rectangles, polygons, ellipses and arcs
  22. - to draw text.
  23. NOTE: Operations, functions and branching have rather been optimized
  24. to efficiency and speed than to shortness of source code.
  25.  
  26. LICENSE: LGPL
  27.  
  28. This library is free software; you can redistribute it and/or
  29. modify it under the terms of the GNU Lesser General Public
  30. License (LGPL) as published by the Free Software Foundation; either
  31. version 2.1 of the License, or (at your option) any later version.
  32.  
  33. This library is distributed in the hope that it will be useful,
  34. but WITHOUT ANY WARRANTY; without even the implied warranty of
  35. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  36. Lesser General Public License for more details.
  37.  
  38. You should have received a copy of the GNU Lesser General Public
  39. License along with this library; if not, write to the Free Software
  40. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA,
  41. or see http://www.gnu.org/copyleft/lesser.html
  42. */
  43.  
  44.  
  45. var jg_ok, jg_ie, jg_fast, jg_dom, jg_moz;
  46.  
  47.  
  48. function _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.  
  62. function _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.  
  71. function _pntCnvIe()
  72. {
  73.         if(this.cnv) this.cnv.insertAdjacentHTML("BeforeEnd", jg_fast? this._htmRpc() : this.htm);
  74.         this.htm = "";
  75. }
  76.  
  77. function _pntDoc()
  78. {
  79.         this.wnd.document.write(jg_fast? this._htmRpc() : this.htm);
  80.         this.htm = '';
  81. }
  82.  
  83. function _pntN()
  84. {
  85.         ;
  86. }
  87.  
  88. function _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.  
  101. function _mkDivIe(x, y, w, h)
  102. {
  103.         this.htm += '%%'+this.color+';'+x+';'+y+';'+w+';'+h+';';
  104. }
  105.  
  106. function _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.  
  120. var _regex =  /%%([^;]+);([^;]+);([^;]+);([^;]+);([^;]+);/g;
  121. function _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.  
  129. function _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.  
  137. function _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.  
  216. function _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.  
  313. function _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.  
  367. function _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.  
  413. function _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.  
  561. function _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.  
  593. function _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.  
  602. function _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.  
  610. function 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. }
  618. var Font = new jsgFont();
  619.  
  620. function jsgStroke()
  621. {
  622.         this.DOTTED = -1;
  623. }
  624. var Stroke = new jsgStroke();
  625.  
  626. function 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.
  802. This javascript function is an adaptation of the gdImageFilledPolygon for Walter Zorn lib.
  803. C source of GD 1.8.4 found at http://www.boutell.com/gd/
  804.  
  805. THANKS to Kirsten Schulz for the polygon fixes!
  806.  
  807. The intersection finding technique of this code could be improved
  808. by remembering the previous intertersection, and by using the slope.
  809. That could help to adjust intersections to produce a nice
  810. interior_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.
  892. Allows to specify the size of the text rectangle and to align the
  893. text 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.                         // w (width) and h (height) arguments are now optional.
  914.                         // Added by Mahmut Keygubatli, 14.1.2008
  915.                         (w? ('width:' +  w + 'px;') : '') +
  916.                         (h? ('height:' + h + 'px;'):'')+'">'+
  917.                         '<img src="' + imgSrc +'"'+ (w ? (' width="' + w + '"'):'')+ (h ? (' height="' + h + '"'):'') + (a? (' '+a) : '') + '>'+
  918.                         '<\/div>';
  919.         };
  920.  
  921.         this.clear = function()
  922.         {
  923.                 this.htm = "";
  924.                 if(this.cnv) this.cnv.innerHTML = "";
  925.         };
  926.  
  927.         this._mkOvQds = function(cx, cy, x, y, w, h, wod, hod)
  928.         {
  929.                 var xl = cx - x, xr = cx + x + wod - w, yt = cy - y, yb = cy + y + hod - h;
  930.                 if(xr > xl+w)
  931.                 {
  932.                         this._mkDiv(xr, yt, w, h);
  933.                         this._mkDiv(xr, yb, w, h);
  934.                 }
  935.                 else
  936.                         w = xr - xl + w;
  937.                 this._mkDiv(xl, yt, w, h);
  938.                 this._mkDiv(xl, yb, w, h);
  939.         };
  940.        
  941.         this._mkArcDiv = function(x, y, oy, cx, cy, iOdds, aBndA, aBndZ, iSects)
  942.         {
  943.                 var xrDef = cx + x + (iOdds & 0xffff), y2, h = oy - y, xl, xr, w;
  944.  
  945.                 if(!h) h = 1;
  946.                 x = cx - x;
  947.  
  948.                 if(iSects & 0xff0000) // Start-angle > end-angle
  949.                 {
  950.                         y2 = cy - y - h;
  951.                         if(iSects & 0x00ff)
  952.                         {
  953.                                 if(iSects & 0x02)
  954.                                 {
  955.                                         xl = Math.max(x, aBndZ[y]);
  956.                                         w = xrDef - xl;
  957.                                         if(w > 0) this._mkDiv(xl, y2, w, h);
  958.                                 }
  959.                                 if(iSects & 0x01)
  960.                                 {
  961.                                         xr = Math.min(xrDef, aBndA[y]);
  962.                                         w = xr - x;
  963.                                         if(w > 0) this._mkDiv(x, y2, w, h);
  964.                                 }
  965.                         }
  966.                         else
  967.                                 this._mkDiv(x, y2, xrDef - x, h);
  968.                         y2 = cy + y + (iOdds >> 16);
  969.                         if(iSects & 0xff00)
  970.                         {
  971.                                 if(iSects & 0x0100)
  972.                                 {
  973.                                         xl = Math.max(x, aBndA[y]);
  974.                                         w = xrDef - xl;
  975.                                         if(w > 0) this._mkDiv(xl, y2, w, h);
  976.                                 }
  977.                                 if(iSects & 0x0200)
  978.                                 {
  979.                                         xr = Math.min(xrDef, aBndZ[y]);
  980.                                         w = xr - x;
  981.                                         if(w > 0) this._mkDiv(x, y2, w, h);
  982.                                 }
  983.                         }
  984.                         else
  985.                                 this._mkDiv(x, y2, xrDef - x, h);
  986.                 }
  987.                 else
  988.                 {
  989.                         if(iSects & 0x00ff)
  990.                         {
  991.                                 if(iSects & 0x02)
  992.                                         xl = Math.max(x, aBndZ[y]);
  993.                                 else
  994.                                         xl = x;
  995.                                 if(iSects & 0x01)
  996.                                         xr = Math.min(xrDef, aBndA[y]);
  997.                                 else
  998.                                         xr = xrDef;
  999.                                 y2 = cy - y - h;
  1000.                                 w = xr - xl;
  1001.                                 if(w > 0) this._mkDiv(xl, y2, w, h);
  1002.                         }
  1003.                         if(iSects & 0xff00)
  1004.                         {
  1005.                                 if(iSects & 0x0100)
  1006.                                         xl = Math.max(x, aBndA[y]);
  1007.                                 else
  1008.                                         xl = x;
  1009.                                 if(iSects & 0x0200)
  1010.                                         xr = Math.min(xrDef, aBndZ[y]);
  1011.                                 else
  1012.                                         xr = xrDef;
  1013.                                 y2 = cy + y + (iOdds >> 16);
  1014.                                 w = xr - xl;
  1015.                                 if(w > 0) this._mkDiv(xl, y2, w, h);
  1016.                         }
  1017.                 }
  1018.         };
  1019.  
  1020.         this.setStroke(1);
  1021.         this.setFont("verdana,geneva,helvetica,sans-serif", "12px", Font.PLAIN);
  1022.         this.color = "#000000";
  1023.         this.htm = "";
  1024.         this.wnd = wnd || window;
  1025.  
  1026.         if(!jg_ok) _chkDHTM();
  1027.         if(jg_ok)
  1028.         {
  1029.                 if(cnv)
  1030.                 {
  1031.                         if(typeof(cnv) == "string")
  1032.                                 this.cont = document.all? (this.wnd.document.all[cnv] || null)
  1033.                                         : document.getElementById? (this.wnd.document.getElementById(cnv) || null)
  1034.                                         : null;
  1035.                         else if(cnv == window.document)
  1036.                                 this.cont = document.getElementsByTagName("body")[0];
  1037.                         // If cnv is a direct reference to a canvas DOM node
  1038.                         // (option suggested by Andreas Luleich)
  1039.                         else this.cont = cnv;
  1040.                         // Create new canvas inside container DIV. Thus the drawing and clearing
  1041.                         // methods won't interfere with the container's inner html.
  1042.                         // Solution suggested by Vladimir.
  1043.                         this.cnv = this.wnd.document.createElement("div");
  1044.                         this.cnv.style.fontSize=0;
  1045.                         this.cont.appendChild(this.cnv);
  1046.                         this.paint = jg_dom? _pntCnvDom : _pntCnvIe;
  1047.                 }
  1048.                 else
  1049.                         this.paint = _pntDoc;
  1050.         }
  1051.         else
  1052.                 this.paint = _pntN;
  1053.  
  1054.         this.setPrintable(false);
  1055. }
  1056.  
  1057. function _mkLinVirt(aLin, x1, y1, x2, y2)
  1058. {
  1059.         var dx = Math.abs(x2-x1), dy = Math.abs(y2-y1),
  1060.         x = x1, y = y1,
  1061.         xIncr = (x1 > x2)? -1 : 1,
  1062.         yIncr = (y1 > y2)? -1 : 1,
  1063.         p,
  1064.         i = 0;
  1065.         if(dx >= dy)
  1066.         {
  1067.                 var pr = dy<<1,
  1068.                 pru = pr - (dx<<1);
  1069.                 p = pr-dx;
  1070.                 while(dx > 0)
  1071.                 {--dx;
  1072.                         if(p > 0)    //  Increment y
  1073.                         {
  1074.                                 aLin[i++] = x;
  1075.                                 y += yIncr;
  1076.                                 p += pru;
  1077.                         }
  1078.                         else p += pr;
  1079.                         x += xIncr;
  1080.                 }
  1081.         }
  1082.         else
  1083.         {
  1084.                 var pr = dx<<1,
  1085.                 pru = pr - (dy<<1);
  1086.                 p = pr-dy;
  1087.                 while(dy > 0)
  1088.                 {--dy;
  1089.                         y += yIncr;
  1090.                         aLin[i++] = x;
  1091.                         if(p > 0)    //  Increment x
  1092.                         {
  1093.                                 x += xIncr;
  1094.                                 p += pru;
  1095.                         }
  1096.                         else p += pr;
  1097.                 }
  1098.         }
  1099.         for(var len = aLin.length, i = len-i; i;)
  1100.                 aLin[len-(i--)] = x;
  1101. };
  1102.  
  1103. function _CompInt(x, y)
  1104. {
  1105.         return(x - y);
  1106. }
  1107.  
  1108.