Subversion Repositories wimsdev

Rev

Rev 13512 | Rev 13961 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. #include "canvasdraw.h"
  2.  
  3. /* not used ?? */
  4. /*
  5. char *data2js_array(int data[],int len);
  6. char *xy2js_array(int xy[],int len);
  7. */
  8. void add_js_multidraw(FILE *js_include_file,int canvas_root_id,char *draw_types,char *button_style){
  9. /*
  10.  
  11. just for the javascript switches():
  12. point = 0       points =1
  13. circle = 2      circles = 3
  14. line =4         lines = 5
  15. segment = 6     segments = 7
  16. arrow = 8       arrows = 9
  17. triangle = 10   triangles = 11
  18. polygon = 12
  19. text = 13
  20. rect = 14
  21. rects =15
  22. poly = 16
  23. polys = 17
  24. paralelogram = 18
  25. 28/6/2015:
  26. the next js-code block (parsing/scanning the multidraw objects array) is -for now- generic,
  27. e.g. not responsive to the actual draw_types used.
  28.  
  29. TODO: examine/parse the *draw_Types and make the js-code accordingly (e.g. specific and not generic)
  30. */
  31.  
  32. fprintf(js_include_file,"\n<!-- begin multidraw  -->\n\
  33. var canvas_userdraw = create_canvas%d(999,xsize,ysize);\
  34. var context_userdraw = canvas_userdraw.getContext(\"2d\");\
  35. var click_cnt = 0;\
  36. if(wims_status != \"done\"){\
  37. canvas_div.addEventListener('mousedown',user_draw,false);\
  38. canvas_div.addEventListener('mousemove',user_drag,false);\
  39. canvas_div.addEventListener('touchstart'  , function(e) { e.preventDefault(); user_draw(e.changedTouches[0]);},false);\
  40. canvas_div.addEventListener( 'touchmove'  , function(e) { e.preventDefault(); user_drag(e.changedTouches[0]);},false);\
  41. };\
  42. clear_draw_area%d = function(type,name){\
  43.  switch(type){\
  44.   case 0: context_points.clearRect(0,0,xsize,ysize);points_x = [];points_y = [];break;\
  45.   case 1: points_x.pop();points_y.pop();draw_points();break;\
  46.   case 2: context_circles.clearRect(0,0,xsize,ysize);circles_x = [];circles_y = []; multi_radius = [];break;\
  47.   case 3: circles_x.pop();circles_y.pop(); multi_radius.pop();draw_circles();break;\
  48.   case 4: context_lines.clearRect(0,0,xsize,ysize);lines_x = [];lines_y = [];break;\
  49.   case 5: lines_x.pop();lines_y.pop();lines_x.pop();lines_y.pop();draw_lines();break;\
  50.   case 6: context_segments.clearRect(0,0,xsize,ysize);segments_x = [];segments_y = [];break;\
  51.   case 7: segments_x.pop();segments_y.pop();segments_x.pop();segments_y.pop();draw_segments();break;\
  52.   case 8: context_arrows.clearRect(0,0,xsize,ysize);arrows_x = [];arrows_y = [];break;\
  53.   case 9: arrows_x.pop();arrows_y.pop();arrows_x.pop();arrows_y.pop();draw_arrows();break;\
  54.   case 10:context_triangles.clearRect(0,0,xsize,ysize); triangles_x = [];triangles_y = [];break;\
  55.   case 11:for(var p=0;p<3;p++){triangles_x.pop();triangles_y.pop();};draw_triangles();break;\
  56.   case 12:context_closedpoly.clearRect(0,0,xsize,ysize);closedpoly_x = [];closedpoly_y = [];break;\
  57.   case 13:context_text.clearRect(0,0,xsize,ysize);text_x.pop();text_y.pop();text_abc.pop();draw_text();break;\
  58.   case 14:context_rects.clearRect(0,0,xsize,ysize);rects_x = [];rects_y = [];break;\
  59.   case 15:rects_x.pop();rects_y.pop();rects_x.pop();rects_y.pop();draw_rects();break;\
  60.   case 16:context_polys.clearRect(0,0,xsize,ysize); polys_x = [];polys_y = [];break;\
  61.   case 17:for(var p=0;p<polynum;p++){polys_x.pop();polys_y.pop();};draw_polys();break;\
  62.   case 18:context_parallelogram.clearRect(0,0,xsize,ysize); parallelogram_x = [];parallelogram_y = [];break;\
  63.   case 19:for(var p = 0; p < 4;p++){ parallelogram_x.pop();parallelogram_y.pop();};draw_parallelogram();break;\
  64.   default:break;\
  65. };\
  66. };\
  67. function user_draw(evt){\
  68. var canvas_rect = canvas_userdraw.getBoundingClientRect();\
  69. var y = evt.clientY - canvas_rect.top;\
  70. var x = evt.clientX - canvas_rect.left;\
  71. switch(userdraw_primitive){\
  72.  case 0: points(x,y,0,0);break;\
  73.  case 1: points(x,y,0,1);break;\
  74.  case 2: circles(x,y,0,0);break;\
  75.  case 3: circles(x,y,0,1);break;\
  76.  case 4: lines(x,y,0,0);break;\
  77.  case 5: lines(x,y,0,1);break;\
  78.  case 6: segments(x,y,0,0);break;\
  79.  case 7: segments(x,y,0,1);break;\
  80.  case 8: arrows(x,y,0,0);break;\
  81.  case 9: arrows(x,y,0,1);break;\
  82.  case 10: triangles(x,y,0,0);break;\
  83.  case 11: triangles(x,y,0,1);break;\
  84.  case 12: closedpoly(x,y,0,0);break;\
  85.  case 13: text(x,y,0,1);break;\
  86.  case 14: rects(x,y,0,0);break;\
  87.  case 15: rects(x,y,0,1);break;\
  88.  case 16: polys(x,y,0,0);break;\
  89.  case 17: polys(x,y,0,1);break;\
  90.  case 18: parallelogram(x,y,0,0);break;\
  91.  case 19: parallelogram(x,y,0,1);break;\
  92.  default:break;\
  93. };\
  94. };\
  95. function user_drag(evt){\
  96. var canvas_rect = canvas_userdraw.getBoundingClientRect();\
  97. var y = evt.clientY - canvas_rect.top;\
  98. var x = evt.clientX - canvas_rect.left;\
  99. switch(userdraw_primitive){\
  100.  case 0: break;\
  101.  case 1: break;\
  102.  case 2: circles(x,y,1,0);break;\
  103.  case 3: circles(x,y,1,1);break;\
  104.  case 4: lines(x,y,1,0);break;\
  105.  case 5: lines(x,y,1,1);break;\
  106.  case 6: segments(x,y,1,0);break;\
  107.  case 7: segments(x,y,1,1);break;\
  108.  case 8: arrows(x,y,1,0);break;\
  109.  case 9: arrows(x,y,1,1);break;\
  110.  case 10: triangles(x,y,1,0);break;\
  111.  case 11: triangles(x,y,1,1);break;\
  112.  case 12: closedpoly(x,y,1,0);break;\
  113.  case 13: break;\
  114.  case 14: rects(x,y,1,0);break;\
  115.  case 15: rects(x,y,1,1);break;\
  116.  case 16: polys(x,y,1,0);break;\
  117.  case 17: polys(x,y,1,1);break;\
  118.  case 18: parallelogram(x,y,1,0);break;\
  119.  case 19: parallelogram(x,y,1,1);break;\
  120.  default:break;\
  121. };\
  122. };\
  123. var draw_things = [\"%s\"];\
  124. var tooltip_div = document.getElementById(\"tooltip_placeholder_div%d\");\
  125. var inner_html=\"\";\
  126. var button_style = \"%s\";\
  127. var id_x;\
  128. var id_y;\
  129. var id_r;\
  130. if( typeof(multilabel[multilabel.length - 1 ]) === 'undefined' ){multilabel[multilabel.length - 1] = 'stop drawing';};\
  131. for(var p = 0;p < draw_things.length;p++){\
  132. var desc;\
  133. id_r = 0;\
  134. if( multistrokeopacity[p] > 1 ){ multistrokeopacity[p] = (0.0039215*multistrokeopacity[p]).toFixed(2); };\
  135. if( multifillopacity[p] > 1 ){ multifillopacity[p] =  (0.0039215*multifillopacity[p]).toFixed(2); };\
  136. if( draw_things[p] == 'point' || draw_things[p] == 'points' ){\
  137.  var canvas_points = create_canvas%d(1000,xsize,ysize);\
  138.  var context_points = canvas_points.getContext(\"2d\");\
  139.  context_points.strokeStyle = \"rgba(\"+multistrokecolors[p]+\",\"+multistrokeopacity[p]+\")\";\
  140.  context_points.fillStyle = context_points.strokeStyle;\
  141.  context_points.lineWidth = multilinewidth[p];\
  142.  if(multilinewidth[p]%%2 == 1){ context_points.translate(0.5,0.5);};\
  143.  var points_x = new Array();var points_y = new Array();\
  144.  var points_snap = multisnaptogrid[p];\
  145.  if(draw_things[p] == 'point' ){desc = 0;}else{desc = 1;};\
  146.  id_x = 'input_points_x';id_y = 'input_points_y';\
  147. }\
  148. else\
  149. {\
  150.  if( draw_things[p] == 'circle' || draw_things[p] == 'circles' ){\
  151.   var canvas_circles = create_canvas%d(1001,xsize,ysize);\
  152.   var context_circles = canvas_circles.getContext(\"2d\");\
  153.   context_circles.lineWidth = multilinewidth[p];\
  154.   if(multilinewidth[p]%%2 == 1){ context_circles.translate(0.5,0.5);};\
  155.   context_circles.strokeStyle = \"rgba(\"+multistrokecolors[p]+\",\"+multistrokeopacity[p]+\")\";\
  156.   if(multifill[p] == '1' ){ context_circles.fillStyle = \"rgba(\"+multifillcolors[p]+\",\"+multifillopacity[p]+\")\";}else{context_circles.fillStyle = \"rgba( 255,255,255,0)\"; };\
  157.   if(multidash[p] == '1' ){ if( context_circles.setLineDash ){context_circles.setLineDash([2,4]);}else{if(context_circles.mozDash){context_circles.mozDash = [2,4]};};};\
  158.   var circles_x = new Array();var circles_y = new Array();var multi_radius = new Array();\
  159.   var circles_snap = multisnaptogrid[p];\
  160.   if( draw_things[p] == 'circle' ){desc = 2;}else{desc = 3;};\
  161.   id_x = 'input_circles_x';id_y = 'input_circles_y';id_r = 'input_circles_r';\
  162.  }\
  163.  else\
  164.  {\
  165.   if( draw_things[p] == 'line' || draw_things[p] == 'lines' ){\
  166.    var canvas_lines = create_canvas%d(1002,xsize,ysize);\
  167.    var context_lines = canvas_lines.getContext(\"2d\");\
  168.    context_lines.lineWidth = multilinewidth[p];\
  169.    if(multilinewidth[p]%%2 == 1){ context_lines.translate(0.5,0.5);};\
  170.    context_lines.strokeStyle = \"rgba(\"+multistrokecolors[p]+\",\"+multistrokeopacity[p]+\")\";\
  171.    if(multidash[p] == '1' ){ if( context_lines.setLineDash ){context_lines.setLineDash([2,4]);}else{if(context_lines.mozDash){context_lines.mozDash = [2,4]};};};\
  172.    var lines_x = new Array();var lines_y = new Array();\
  173.    var lines_snap = multisnaptogrid[p];\
  174.    if(draw_things[p] == 'line' ){desc = 4;}else{desc = 5;};\
  175.    id_x = 'input_lines_x';id_y = 'input_lines_y';\
  176.   }\
  177.   else\
  178.   {\
  179.    if( draw_things[p] == 'segment' || draw_things[p] == 'segments' ){\
  180.     var canvas_segments = create_canvas%d(1003,xsize,ysize);\
  181.     var context_segments = canvas_segments.getContext(\"2d\");\
  182.     context_segments.lineWidth = multilinewidth[p];\
  183.     if(multilinewidth[p]%%2 == 1){ context_segments.translate(0.5,0.5);};\
  184.     context_segments.strokeStyle = \"rgba(\"+multistrokecolors[p]+\",\"+multistrokeopacity[p]+\")\";\
  185.     if(multidash[p] == '1' ){ if( context_segments.setLineDash ){context_segments.setLineDash([2,4]);}else{if(context_segments.mozDash){context_segments.mozDash = [2,4]};};};\
  186.     var segments_x = new Array();var segments_y = new Array();\
  187.     var segments_snap = multisnaptogrid[p];\
  188.     if( draw_things[p] == 'segment' ){desc = 6;}else{ desc = 7;};\
  189.     id_x = 'input_segments_x';id_y = 'input_segments_y';\
  190.    }\
  191.    else\
  192.    {\
  193.     if( draw_things[p] == 'arrow' || draw_things[p] == 'arrows' ){\
  194.      var canvas_arrows = create_canvas%d(1004,xsize,ysize);\
  195.      var context_arrows =  canvas_arrows.getContext(\"2d\");\
  196.      context_arrows.lineWidth = multilinewidth[p];\
  197.      if(multilinewidth[p]%%2 == 1){ context_arrows.translate(0.5,0.5);};\
  198.      context_arrows.lineCap = \"round\";\
  199.      context_arrows.strokeStyle = \"rgba(\"+multistrokecolors[p]+\",\"+multistrokeopacity[p]+\")\";\
  200.      context_arrows.fillStyle = context_arrows.strokeStyle;\
  201.      if(multidash[p] == '1' ){ if( context_arrows.setLineDash ){context_arrows.setLineDash([2,4]);}else{if(context_arrows.mozDash){context_arrows.mozDash = [2,4]};};};\
  202.      var arrows_x = new Array();var arrows_y = new Array();\
  203.      var arrows_snap = multisnaptogrid[p];\
  204.      if( draw_things[p] == 'arrow' ){desc = 8;}else{desc = 9;};\
  205.      id_x = 'input_arrows_x';id_y = 'input_arrows_y';\
  206.     }\
  207.     else\
  208.     {\
  209.      if( draw_things[p] == 'rect' || draw_things[p] == 'rects' ){\
  210.       var canvas_rects = create_canvas%d(1008,xsize,ysize);\
  211.       var context_rects = canvas_rects.getContext(\"2d\");\
  212.       context_rects.lineWidth = multilinewidth[p];\
  213.       if(multilinewidth[p]%%2 == 1){ context_rects.translate(0.5,0.5);};\
  214.       context_rects.strokeStyle = \"rgba(\"+multistrokecolors[p]+\",\"+multistrokeopacity[p]+\")\";\
  215.       if(multidash[p] == '1' ){ if( context_rects.setlineDash ){context_rects.setlineDash([2,4]);}else{if(context_rects.mozDash){context_rects.mozDash = [2,4]};};};\
  216.       if(multifill[p] == '1' ){ context_rects.fillStyle = \"rgba(\"+multifillcolors[p]+\",\"+multifillopacity[p]+\")\";}else{context_rects.fillStyle = \"rgba( 255,255,255,0)\"; };\
  217.       var rects_x = new Array();var rects_y = new Array();\
  218.       var rects_snap = multisnaptogrid[p];\
  219.       if(draw_things[p] == 'rect' ){desc = 14;}else{desc = 15;};\
  220.       id_x = 'input_rects_x';id_y = 'input_rects_y';\
  221.      }\
  222.      else\
  223.      {\
  224.       if( draw_things[p] == 'closedpoly'){\
  225.        var canvas_closedpoly = create_canvas%d(1006,xsize,ysize);\
  226.        var context_closedpoly =  canvas_closedpoly.getContext(\"2d\");\
  227.        context_closedpoly.lineCap = \"round\";\
  228.        context_closedpoly.lineWidth = multilinewidth[p];\
  229.        if(multilinewidth[p]%%2 == 1){ context_closedpoly.translate(0.5,0.5);};\
  230.        context_closedpoly.lineCap = \"round\";\
  231.        context_closedpoly.strokeStyle = \"rgba(\"+multistrokecolors[p]+\",\"+multistrokeopacity[p]+\")\";\
  232.        if(multifill[p] == '1' ){ context_closedpoly.fillStyle = \"rgba(\"+multifillcolors[p]+\",\"+multifillopacity[p]+\")\";}else{context_closedpoly.fillStyle = \"rgba( 255,255,255,0)\"; };\
  233.        if(multidash[p] == '1' ){ if( context_closedpoly.setLineDash ){context_closedpoly.setLineDash([2,4]);}else{if(context_closedpoly.mozDash){context_closedpoly.mozDash = [2,4]};};};\
  234.        var closedpoly_x = new Array();var closedpoly_y = new Array();\
  235.        var closedpoly_snap = multisnaptogrid[p];\
  236.        desc = 12;\
  237.        id_x = 'input_closedpoly_x';id_y = 'input_closedpoly_y';\
  238.       }\
  239.       else\
  240.       {\
  241.        if( draw_things[p] == 'triangle' || draw_things[p] == 'triangles' ){\
  242.         var canvas_triangles = create_canvas%d(1005,xsize,ysize);\
  243.         var context_triangles = canvas_triangles.getContext(\"2d\");\
  244.         context_triangles.lineCap = \"round\";\
  245.         context_triangles.lineWidth = multilinewidth[p];\
  246.         if(multilinewidth[p]%%2 == 1){ context_triangles.translate(0.5,0.5);};\
  247.         context_triangles.strokeStyle = \"rgba(\"+multistrokecolors[p]+\",\"+multistrokeopacity[p]+\")\";\
  248.         if(multifill[p] == '1' ){ context_triangles.fillStyle = \"rgba(\"+multifillcolors[p]+\",\"+multifillopacity[p]+\")\";}else{context_triangles.fillStyle = \"rgba( 255,255,255,0)\"; };\
  249.         if(multidash[p] == '1' ){ if( context_triangles.setLineDash ){context_triangles.setLineDash([2,4]);}else{if(context_triangles.mozDash){context_triangles.mozDash = [2,4]};};};\
  250.         var triangles_x = new Array();var triangles_y = new Array();\
  251.         var triangles_snap = multisnaptogrid[p];\
  252.         if( draw_things[p] == 'triangle'){desc = 10;};\
  253.         if( draw_things[p] == 'triangles'){desc = 11;};\
  254.         id_x = 'input_triangles_x';id_y = 'input_triangles_y';id_r = 'input_triangles_r';\
  255.        }\
  256.        else\
  257.        {\
  258.         if( draw_things[p].indexOf('para') != -1 ){\
  259.          var canvas_parallelogram = create_canvas%d(1010,xsize,ysize);\
  260.          var context_parallelogram = canvas_parallelogram.getContext(\"2d\");\
  261.          context_parallelogram.lineCap = \"round\";\
  262.          context_parallelogram.lineWidth = multilinewidth[p];\
  263.          if(multilinewidth[p]%%2 == 1){ context_parallelogram.translate(0.5,0.5);};\
  264.          context_parallelogram.strokeStyle = \"rgba(\"+multistrokecolors[p]+\",\"+multistrokeopacity[p]+\")\";\
  265.          if(multifill[p] == '1' ){ context_parallelogram.fillStyle = \"rgba(\"+multifillcolors[p]+\",\"+multifillopacity[p]+\")\";}else{context_parallelogram.fillStyle = \"rgba( 255,255,255,0)\"; };\
  266.          if(multidash[p] == '1' ){ if( context_parallelogram.setLineDash ){context_parallelogram.setLineDash([2,4]);}else{if(context_parallelogram.mozDash){context_parallelogram.mozDash = [2,4]};};};\
  267.          var parallelogram_x = new Array();var parallelogram_y = new Array();\
  268.          var parallelogram_snap = multisnaptogrid[p];\
  269.          if( draw_things[p] == 'parallelogram'){multiuserinput[p] =  0;desc = 18;};\
  270.          if( draw_things[p] == 'parallelograms'){multiuserinput[p] =  0;desc = 19;};\
  271.          id_x = 'input_parallelogram_x';id_y = 'input_parallelogram_y';id_r = 'input_parallelogram_r';\
  272.         }\
  273.         else\
  274.         {\
  275.          if( draw_things[p].indexOf('poly') != -1 ){\
  276.           var canvas_polys = create_canvas%d(1009,xsize,ysize);\
  277.           var context_polys = canvas_polys.getContext(\"2d\");\
  278.           context_polys.lineCap = \"round\";\
  279.           context_polys.lineWidth = multilinewidth[p];\
  280.           if(multilinewidth[p]%%2 == 1){ context_polys.translate(0.5,0.5);};\
  281.           context_polys.strokeStyle = \"rgba(\"+multistrokecolors[p]+\",\"+multistrokeopacity[p]+\")\";\
  282.           if(multifill[p] == '1' ){ context_polys.fillStyle = \"rgba(\"+multifillcolors[p]+\",\"+multifillopacity[p]+\")\";}else{context_polys.fillStyle = \"rgba( 255,255,255,0)\"; };\
  283.           if(multidash[p] == '1' ){ if( context_polys.setLineDash ){context_polys.setLineDash([2,4]);}else{if(context_polys.mozDash){context_polys.mozDash = [2,4]};};};\
  284.           var polys_x = new Array();var polys_y = new Array();\
  285.           var polys_snap = multisnaptogrid[p];\
  286.           if( draw_things[p].indexOf('polys') != -1){desc = 17;}else{desc = 16;}\
  287.           multiuserinput[p] = 0;\
  288.           id_x = 'input_polys_x';id_y = 'input_polys_y';id_r = 'input_polys_r';\
  289.          }\
  290.          else\
  291.          {\
  292.           if( draw_things[p] == 'text' ){\
  293.            var canvas_text = create_canvas%d(1007,xsize,ysize);\
  294.            var context_text = canvas_text.getContext(\"2d\");\
  295.            context_text.font = multifont_family;\
  296.            context_text.fillStyle = \"rgba(\"+multifont_color+\",\"+multistrokeopacity[p]+\")\";\
  297.            var text_snap = multisnaptogrid[p];\
  298.            var text_x = new Array;var text_y = new Array; var text_abc = new Array();\
  299.            id_x = 'input_text_x';id_y = 'input_text_y';id_r = 'input_text_r';\
  300.            desc = 13;\
  301.           };\
  302.          };\
  303.         };\
  304.        };\
  305.       };\
  306.      };\
  307.     };\
  308.    };\
  309.   };\
  310.  };\
  311. };\
  312. inner_html+=\"<tr style='background-color:rgba(\"+multistrokecolors[p]+\",0.4)'><td><input type='button' id='canvasdraw_\"+draw_things[p]+\"' style=\"+button_style+\" onclick='javascript:userdraw_primitive=\"+desc+\";click_cnt = 0;' value='\"+multilabel[p]+\"' /></td><td><input type='button' style='\"+button_style+\"' onclick='javascript:clear_draw_area%d(\"+desc+\",\"+p+\");' value='delete' /></td>\";\
  313. if(multiuserinput[p] == '1'){ \
  314.  if(desc == 0 || desc == 1 ){\
  315.   inner_html+=\"<td><b>(</b><input type='text' size='5' value='' id='\"+id_x+\"' style='\"+button_style+\"' /><b>:</b> <input type='text' size='5' value='' id='\"+id_y+\"' style='\"+button_style+\"' /> <b>)</b></td>\";\
  316.  }\
  317.  else\
  318.  {\
  319.   if(desc == 2 || desc == 3){\
  320.    inner_html+=\"<td><b>M&nbsp;:&nbsp;(<input type='text' size='5' value='' id='\"+id_x+\"' style='\"+button_style+\"' /> : <input type='text' size='5' value='' id='\"+id_y+\"' style='\"+button_style+\"' />)&nbsp;&nbsp;R</b>&nbsp;:&nbsp;<input type='text' size='3' value='' id='\"+id_r+\"' style='\"+button_style+\"' /></b></td>\";\
  321.   }\
  322.   else\
  323.   {\
  324.    if(desc >3 && desc <10 || desc == 14 || desc == 15){\
  325.     inner_html+=\"<td><b>(</b><input type='text' size='5' value='x1 : y1' id='\"+id_x+\"' style='\"+button_style+\";text-align:center;' /><b>) --- (</b> <input type='text' size='5' value='x2 : y2' id='\"+id_y+\"' style='\"+button_style+\";text-align:center;' /> <b>)</b></td>\";\
  326.    }\
  327.    else\
  328.    {\
  329.     if( desc == 10 || desc == 11){\
  330.      inner_html+=\"<td><b>(<input type='text' size='5' value='x1 : y1' id='\"+id_x+\"' style='\"+button_style+\"' />) -- (<input type='text' size='5' value='x2 : y2' id='\"+id_y+\"' style='\"+button_style+\"' />) -- (<input type='text' size='5' value='x3 : y3' id='\"+id_r+\"' style='\"+button_style+\"' />)</b></td>\";\
  331.     }\
  332.     else\
  333.     {\
  334.      if( desc == 12 || desc == 16 || desc == 17 || desc == 18 || desc == 19){\
  335.       inner_html+=\"<td><b>(<input type='text' size='8' value='x1,x2...x_n' id='\"+id_x+\"' style='\"+button_style+\"' /> ---- <input type='text' size='8' value='y1,y2...y_n' id='\"+id_y+\"' style='\"+button_style+\"' />)</b></td>\";\
  336.      }\
  337.      else\
  338.      {\
  339.       if( desc == 13 ){\
  340.        inner_html+=\"<td><b>(&nbsp;<input type='text' size='2' value='' id='\"+id_x+\"' style='\"+button_style+\"' /> - <input type='text' size='2' value='' id='\"+id_y+\"' style='\"+button_style+\"' />&nbsp;)</b><input type='text' size='4' value='' id='\"+id_r+\"' style='\"+button_style+\"' /></td>\";\
  341.       };\
  342.      };\
  343.     };\
  344.    };\
  345.   };\
  346.  };\
  347.  inner_html+=\"<td><input type='button' id='canvasdraw_ok_button'  style='\"+button_style+\"' onclick='javascript:update_draw_area%d(\"+desc+\",\"+id_x+\",\"+id_y+\",\"+id_r+\")' value='OK'/ ></td></tr>\";\
  348. }\
  349. else\
  350. {\
  351.  if( desc == 13 ){\
  352.   inner_html+=\"<td><input type='text' size='4' value='' id='\"+id_r+\"' style='\"+button_style+\"' /></td><td></td><td></td></tr>\";\
  353.  }\
  354.  else\
  355.  {\
  356.   inner_html+\"<td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>\";\
  357.  };\
  358. };\
  359. };\
  360. if( wims_status != 'done' ){\
  361. tooltip_div.innerHTML = \"<table style='margin: 0 auto;'>\"+inner_html+\"<tr><td>&nbsp;</td><td><input type='button' id='canvasdraw_stop_drawing' style='\"+button_style+\"' value='\"+multilabel[multilabel.length - 1]+\"' onclick='javascript:userdraw_primitive=null;' /></td><td>&nbsp;</td></tr></table>\";\
  362. };\
  363. function x_snap_check(x,snap){\
  364. if( snap == 1 || snap == 2 ){\
  365.  return snap_to_x(x);\
  366. };\
  367. return x;\
  368. };\
  369. function y_snap_check(y,snap){\
  370. if( snap == 1 || snap == 3 ){\
  371.  return snap_to_y(y);\
  372. };\
  373. return y;\
  374. };\
  375. function coord_split(coord){if(coord.indexOf(':') > 0 ){return coord.split(':');}else{if(coord.indexOf(';') > 0 ){return coord.split(';');}else{if(coord.indexOf(',') > 0 ){return coord.split(',');}else{alert(coord+'--> X : Y ');return;};};};};\
  376. function scale_xy(type,xy){var tmp_xmin = xmin;var tmp_xmax = xmax;var tmp_ymin = ymin;var tmp_ymax = ymax;xmin=zoom_xy[0];xmax=zoom_xy[1];ymin=zoom_xy[2];ymax=zoom_xy[3];if(type == 1 ){for(var p=0;p<xy.length;p++){xy[p] = px2x(xy[p]);};}else{for(var p=0;p<xy.length;p++){xy[p] = px2y(xy[p]);};};xmin = tmp_xmin;ymin = tmp_ymin;xmax = tmp_xmax;ymax = tmp_ymax;if(type == 1){for(var p=0;p<xy.length;p++){xy[p] = x2px(xy[p]);}}else{for(var p=0;p<xy.length;p++){xy[p] = y2px(xy[p]);};};return xy;};\
  377. function scale_multi_radius(r){for(var p = 0 ; p < r.length;p++ ){r[p] = zoom_xy[0]/xmin*r[p];};return r;};\
  378. redraw_all%d = function(){\
  379. if( points_x && points_x.length > 0 ){points_x = scale_xy(1,points_x);points_y = scale_xy(1,points_y);draw_points();};\
  380. if( circles_x && circles_x.length > 0 ){circles_x = scale_xy(1,circles_x);circles_y = scale_xy(1,circles_y);multi_radius = scale_multi_radius(multi_radius);draw_circles();};\n\
  381. if( segments_x && segments_x.length > 0 ){segments_x = scale_xy(1,segments_x);segments_y = scale_xy(1,segments_y);draw_segments();};\
  382. if( arrows_x && arrows_x.length > 0 ){arrows_x = scale_xy(1,arrows_x);arrows_y = scale_xy(2,arrows_y);draw_arrows();};\
  383. if( lines_x && lines_x.length > 0 ){lines_x = scale_xy(1,lines_x);lines_y = scale_xy(2,lines_y);draw_lines();};\
  384. if( triangles_x && triangles_x.length > 0 ){triangles_x = scale_xy(1,triangles_x);triangles_y = scale_xy(2,triangles_y);draw_triangles();};\
  385. if( rects_x && rects_x.length > 0 ){rects_x = scale_xy(1,rects_x);rects_y = scale_xy(2,rects_y);draw_rects();};\
  386. if( closedpoly_x && closedpoly_x.length > 0 ){closedpoly_x = scale_xy(1,closedpoly_x);closedpoly_y = scale_xy(2,closedpoly_y);draw_closedpoly();};\
  387. if( text_x && text_x.length > 0 ){text_x = scale_xy(1,text_x);text_y = scale_xy(2,text_y);draw_text();};\
  388. if( polys_x && polys_x.length > 0 ){polys_x = scale_xy(1,polys_x);polys_y = scale_xy(2,polys_y);draw_polys();};\
  389. if( parallelogram_x && parallelogram_x.length > 0 ){parallelogram_x = scale_xy(1,parallelogram_x);parallelogram_y = scale_xy(2,parallelogram_y);draw_parallelogram();};\
  390. return;\
  391. };\
  392. update_draw_area%d = function(desc,id_x,id_y,id_r){\
  393. var x1,x2,x3,y1,y2,y3,r,A,B;\
  394. x1 = document.getElementById(id_x.id).value;\
  395. y1 = document.getElementById(id_y.id).value;\
  396. if(desc > 3 && desc < 12 || desc == 14 || desc == 15){\
  397.  A = coord_split(x1);B = coord_split(y1);\
  398.  if(A.length != 2 || B.length != 2){alert(' X : Y ');return;};\
  399.  x1 = x2px(safe_eval(A[0]));y1 = y2px(safe_eval(A[1]));\
  400.  x2 = x2px(safe_eval(B[0]));y2 = y2px(safe_eval(B[1]));\
  401.  if(desc == 10 || desc == 11 ){\
  402.   r = document.getElementById(id_r.id).value;\
  403.   A = coord_split(r);\
  404.   x3 = x2px(safe_eval(A[0]));y3 = y2px(safe_eval(A[1]));\
  405.  };\
  406. }\
  407. else\
  408. {\
  409.  if( desc < 4 ){\
  410.   x1 = x2px(safe_eval(x1));y1 = y2px( safe_eval(y1));\
  411.  };\
  412. };\
  413. switch(desc){\
  414.  case 0: points(x1,y1,0,0);break;\
  415.  case 1: points(x1,y1,0,1);break;\
  416.  case 2: r = scale_x_radius(safe_eval(document.getElementById(id_r.id).value));multi_radius[0] = r;circles_x[0] = x1;circles_y[0] = y1;draw_circles();break;\
  417.  case 3: r = scale_x_radius(safe_eval(document.getElementById(id_r.id).value));multi_radius.push(r);circles_x.push(x1);circles_y.push(y1);draw_circles();break;\
  418.  case 4: lines_x[0] = x1;lines_x[1] = x2;lines_y[0] = y1;lines_y[1] = y2;calc_lines();draw_lines();break;\
  419.  case 5: lines_x.push(x1);lines_x.push(x2);lines_y.push(y1);lines_y.push(y2);calc_lines();draw_lines();break;\
  420.  case 6: segments_x[0] = x1;segments_x[1] = x2;segments_y[0] = y1;segments_y[1] = y2;draw_segments();break;\
  421.  case 7: segments_x.push(x1);segments_x.push(x2);segments_y.push(y1);segments_y.push(y2);draw_segments();break;\
  422.  case 8: arrows_x[0] = x1;arrows_x[1] = x2;arrows_y[0] = y1;arrows_y[1] = y2;draw_arrows();break;\
  423.  case 9: arrows_x.push(x1);arrows_x.push(x2);arrows_y.push(y1);arrows_y.push(y2);draw_arrows();break;\
  424.  case 10: triangles_x[0] = x1;triangles_x[1] = x2;triangles_x[2] = x3;triangles_y[0] = y1;triangles_y[1] = y2;triangles_y[2] = y3;draw_triangles();break;\
  425.  case 11: triangles_x.push(x1);triangles_x.push(x2);triangles_x.push(x3);triangles_y.push(y1);triangles_y.push(y2);triangles_y.push(y3);draw_triangles();break;\
  426.  case 12:\
  427.  A = coord_split(x1);B = coord_split(y1);\
  428.  var plus_len = A.length;if( plus_len != B.length){alert('mismatch between the number of x-values and  y-values');return;};\
  429.  for(var p = 0 ; p < plus_len ; p++){\
  430.   x1 = x2px(safe_eval(A[p]));\
  431.   y1 = y2px(safe_eval(B[p]));\
  432.   closedpoly_x.push(x1);\
  433.   closedpoly_y.push(y1);\
  434.  };\
  435.   x1 = x2px(safe_eval(A[0]));\
  436.   y1 = y2px(safe_eval(B[0]));\
  437.   closedpoly_x.push(x1);\
  438.   closedpoly_y.push(y1);\
  439.  draw_closedpoly();break;\
  440.  case 13: text_abc.push( document.getElementById(id_r.id).value);text(x2px(safe_eval(x1)),y2px(safe_eval(y1)),0,1);draw_text();break;\
  441.  case 14: rects_x[0] = x1;rects_x[1] = x2;rects_y[0] = y1;rects_y[1] = y2;draw_rects();break;\
  442.  case 15: rects_x.push(x1);rects_x.push(x2);rects_y.push(y1);rects_y.push(y2);draw_rects();break;\
  443.  case 16: polys_x[0] = x1;polys_x[1] = x2;polys_x[2] = x3;polys_y[0] = y1;polys_y[1] = y2;polys_y[2] = y3;draw_polys();break;\
  444.  case 17: polys_x.push(x1);polys_x.push(x2);polys_x.push(x3);polys_y.push(y1);polys_y.push(y2);polys_y.push(y3);draw_polys();break;\
  445.  case 18: parallelogram_x[0] = x1;parallelogram_x[1] = x2;parallelogram_x[2] = x3;parallelogram_y[0] = y1;parallelogram_y[1] = y2;parallelogram_y[2] = y3;draw_parallelogram();break;\
  446.  case 19: parallelogram_x.push(x1);parallelogram_x.push(x2);parallelogram_x.push(x3);parallelogram_y.push(y1);parallelogram_y.push(y2);parallelogram_y.push(y3);draw_parallelogram();break;\
  447.  default:break;\
  448. };\
  449. };\
  450. <!-- end multidraw -->\n",canvas_root_id,canvas_root_id,draw_types,canvas_root_id,button_style,
  451.  canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,
  452.  canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id );
  453.  
  454. /*
  455.  now add specific draw functions according to draw_types
  456.  these will be somewhat simpler and less fancy-full than for the 'single object' userdraw command...
  457.  the 'switch function' in the mouselisteners will probably eat more CPU...so the rest needs to be faster:
  458.  we don't want to imitate these horribly slow js-libraries like JSXgraph
  459.  
  460. 28/6/2015
  461. TODO: add a selection of the 'generic js-code' from above into these C-code selector parts !
  462. */
  463.  
  464. /*
  465.  3/8/2017 : multidraw text is allways centered on click-coordinates !
  466. */
  467.  if( strstr(draw_types,"text") != 0){
  468.   fprintf(js_include_file,"function text(x,y,event_which,num){\
  469.   if(event_which == 1){ return; };\
  470.   if( num == 0 ){\
  471.    text_x[0] = x_snap_check(x,text_snap);\
  472.     text_y[0] = y_snap_check(y,text_snap);\
  473.   }else{\
  474.    text_x.push(x_snap_check(x,text_snap));\
  475.    text_y.push(y_snap_check(y,text_snap));\
  476.   };\
  477.   draw_text();\
  478.  };\
  479.  function draw_text(){\
  480.   var half = 0;\
  481.   context_text.clearRect(0,0,xsize,ysize);\
  482.   for(var p = 0 ; p < text_x.length ; p++ ){\
  483.    if( typeof(text_abc[p]) == 'undefined'){text_abc.push(document.getElementById('input_text_r').value);};\
  484.    half = 0.5*( context_text.measureText(text_abc[p]).width );\
  485.    context_text.fillText(text_abc[p],text_x[p] - half,text_y[p]);\
  486.   };\
  487.  };");
  488.  }
  489.  
  490.  if( strstr(draw_types,"point") != 0){
  491.   fprintf(js_include_file,"function points(x,y,event_which,num){\
  492.   if(event_which == 1){ return; };\
  493.   if( num == 0 ){\
  494.     points_x[0] = x_snap_check(x,points_snap);\
  495.     points_y[0] = y_snap_check(y,points_snap);\
  496.   }else{\
  497.    points_x.push(x_snap_check(x,points_snap));\
  498.    points_y.push(y_snap_check(y,points_snap));\
  499.   };\
  500.   draw_points();\
  501.  };\
  502.  function draw_points(){\
  503.   var radius = 2*(context_points.lineWidth);\
  504.   context_points.clearRect(0,0,xsize,ysize);\
  505.   for(var p = 0 ; p < points_x.length ; p++ ){\
  506.    context_points.beginPath();\
  507.    context_points.arc(points_x[p],points_y[p],radius,0,2*Math.PI,false);\
  508.    context_points.closePath();\
  509.    context_points.fill();\
  510.   };\
  511.  };");
  512.  }
  513.  if( strstr(draw_types,"circle") != 0){
  514.   fprintf(js_include_file,"function circles(x,y,event_which,num){\
  515.   var last = circles_x.length - 1;\
  516.   var xc = circles_x[last];\
  517.   var yc = circles_y[last];\
  518.   if(event_which == 0){\
  519.    circles_x.push(x_snap_check(x,circles_snap));circles_y.push(y_snap_check(y,circles_snap));multi_radius.push(4);\
  520.    click_cnt++;\
  521.   }\
  522.   else\
  523.   {\
  524.    if( click_cnt == 1 ){\
  525.     multi_radius[last] = parseInt(Math.sqrt( (x - xc)*(x - xc) + (y - yc)*(y - yc) ));\
  526.    };\
  527.   };\
  528.   if( click_cnt == 2 ){\
  529.    click_cnt = 0;\
  530.    circles_x.pop();circles_y.pop();multi_radius.pop();\
  531.    if( num == 0 ){\
  532.     last = circles_x.length - 1;xc = circles_x[last];yc = circles_y[last];var r = multi_radius[last];\
  533.     circles_x = new Array();circles_y = new Array();multi_radius = new Array();\
  534.     circles_x[0] = x_snap_check(xc,circles_snap);circles_y[0] = y_snap_check(yc,circles_snap);multi_radius[0] = r;\
  535.    }\
  536.   };\
  537.   draw_circles();\
  538. };\
  539. function draw_circles(){\
  540.   context_circles.clearRect(0,0,xsize,ysize);\
  541.   for(var p = 0 ; p < circles_x.length ; p++ ){\
  542.    context_circles.beginPath();\
  543.    context_circles.arc(circles_x[p],circles_y[p],multi_radius[p],0,2*Math.PI,false);\
  544.    context_circles.closePath();\
  545.    context_circles.fill();\
  546.    context_circles.stroke();\
  547.   };\
  548.   return;\
  549. };");
  550.  }
  551.  
  552.  if( strstr(draw_types,"segment") != 0){
  553.   fprintf(js_include_file,"function segments(x,y,event_which,num){\
  554.   var last = segments_x.length - 1;\
  555.   if(event_which == 0){\
  556.    if(num == 0){\
  557.     segments_x[0] = x_snap_check(x,segments_snap);segments_y[0] = y_snap_check(y,segments_snap);\
  558.    }\
  559.    else\
  560.    {\
  561.     segments_x.push(x_snap_check(x,segments_snap));segments_y.push(y_snap_check(y,segments_snap));\
  562.    };\
  563.    click_cnt++;\
  564.   }\
  565.   else\
  566.   {\
  567.    if( click_cnt == 1 ){\
  568.     segments_x.push(x_snap_check(x,segments_snap));segments_y.push(y_snap_check(y,segments_snap));\
  569.     draw_segments();\
  570.     segments_x.pop();segments_y.pop();\
  571.    };\
  572.   };\
  573.   if( click_cnt == 2 ){\
  574.    segments_x[last+num] = x_snap_check(x,segments_snap);segments_y[last+num] = y_snap_check(y,segments_snap);\
  575.    click_cnt = 0;\
  576.    draw_segments();\
  577.   };\
  578.  };\
  579.  function draw_segments(){\
  580.   var len = segments_x.length;\
  581.   if( len%%2 == 0 ){\
  582.    context_segments.clearRect(0,0,xsize,ysize);\
  583.    for(var p = 0 ; p < len ; p = p+2 ){\
  584.     context_segments.beginPath();\
  585.     context_segments.moveTo(segments_x[p],segments_y[p]);\
  586.     context_segments.lineTo(segments_x[p+1],segments_y[p+1]);\
  587.     context_segments.closePath();\
  588.     context_segments.stroke();\
  589.    };\
  590.   };\
  591.   return;\
  592.  };");
  593.  }
  594.  if( strstr(draw_types,"arrow") != 0){
  595.   fprintf(js_include_file,"function arrows(x,y,event_which,num){\
  596.   var last = arrows_x.length - 1;\
  597.   if(event_which == 0){\
  598.    if(num == 0){\
  599.     arrows_x[0] =  x_snap_check(x,arrows_snap);arrows_y[0] = y_snap_check(y,arrows_snap);\
  600.    }\
  601.    else\
  602.    {\
  603.     arrows_x.push(x_snap_check(x,arrows_snap));arrows_y.push(y_snap_check(y,arrows_snap));\
  604.    };\
  605.    click_cnt++;\
  606.   }\
  607.   else\
  608.   {\
  609.    if( click_cnt == 1 ){\
  610.     arrows_x.push(x_snap_check(x,arrows_snap));arrows_y.push(y_snap_check(y,arrows_snap));\
  611.     draw_arrows();\
  612.     arrows_x.pop();arrows_y.pop();\
  613.    };\
  614.   };\
  615.   if( click_cnt == 2 ){\
  616.    arrows_x[last+num] = x_snap_check(x,arrows_snap);arrows_y[last+num] = y_snap_check(y,arrows_snap);\
  617.    click_cnt = 0;\
  618.    draw_arrows();\
  619.   };\
  620.  };\
  621.  function draw_arrows(){\
  622.   var len = arrows_x.length;\
  623.   var x1,y1,x2,y2,dx,dy,h;\
  624.   if( len%%2 == 0 ){\
  625.    context_arrows.clearRect(0,0,xsize,ysize);\
  626.    for(var p = 0 ; p < len ; p = p+2 ){\
  627.     context_arrows.save();\
  628.     x1 = arrows_x[p];y1 = arrows_y[p];x2 = arrows_x[p+1];y2 = arrows_y[p+1];dx = x2 - x1;dy = y2 - y1;\
  629.     h = Math.sqrt(dx*dx+dy*dy);\
  630.     context_arrows.beginPath();\
  631.     context_arrows.moveTo(x1,y1);\
  632.     context_arrows.lineTo(x2,y2);\
  633.     context_arrows.closePath();\
  634.     context_arrows.stroke();\
  635.     context_arrows.translate(x2,y2);\
  636.     context_arrows.rotate(Math.atan2(dy,dx));\
  637.     context_arrows.beginPath();\
  638.     context_arrows.moveTo(0,0);\
  639.     context_arrows.lineTo(-1*arrow_head,-0.5*arrow_head);\
  640.     context_arrows.lineTo(-1*arrow_head, 0.5*arrow_head);\
  641.     context_arrows.closePath();\
  642.     context_arrows.fill();\
  643.     context_arrows.stroke();\
  644.     context_arrows.restore();\
  645.    };\
  646.   };\
  647.  return;\
  648. };");
  649.  }
  650.  
  651.  
  652.  if( strstr(draw_types,"line") != 0){
  653.   fprintf(js_include_file,"function calc_lines(){\
  654.   var marge = 2;var len = lines_x.length;\
  655.   var x = lines_x;var y = lines_y;\
  656.   lines_x = new Array(len);\
  657.   lines_y = new Array(len);\
  658.   var pp;\
  659.   for(var p = 0 ; p< len ;p = p+2){\
  660.    pp = p+1;\
  661.    if(x[p] < x[pp]+marge && x[p] > x[pp]-marge){\
  662.     lines_x[p] = x[p];lines_x[pp] = x[pp];\
  663.     lines_y[p] = 0;lines_y[pp] = ysize;\
  664.    }\
  665.    else\
  666.    {\
  667.     if(y[p] < y[pp]+marge && y[p] > y[pp]-marge){\
  668.      lines_x[p] = 0;lines_x[pp] = xsize;\
  669.      lines_y[p] = y[p];lines_y[pp] = y[pp];\
  670.     }\
  671.     else\
  672.     {\
  673.      lines_x[p] = 0;lines_x[pp] = xsize;\
  674.      lines_y[p] = y[p] - (x[p])*(y[pp] - y[p])/(x[pp] - x[p]);\
  675.      lines_y[pp] = y[p] + (xsize - x[p])*(y[pp] - y[p])/(x[pp] - x[p]);\
  676.     };\
  677.    };\
  678.   };\
  679.   return;\
  680.  }\
  681.  function lines(x,y,event_which,num){\
  682.   if(event_which == 0){\
  683.    if( num == 0 && click_cnt == 0 ){lines_x = [];lines_y = [];};\
  684.    lines_x.push(x_snap_check(x,lines_snap));lines_y.push(y_snap_check(y,lines_snap));\
  685.    click_cnt++;\
  686.   }\
  687.   else\
  688.   {\
  689.    if( click_cnt == 1 ){\
  690.     lines_x.push(x_snap_check(x,lines_snap));lines_y.push(y_snap_check(y,lines_snap));\
  691.     draw_lines();\
  692.     lines_x.pop();lines_y.pop();\
  693.    };\
  694.   };\
  695.   if( click_cnt == 2 ){\
  696.    click_cnt = 0;\
  697.    calc_lines();\
  698.    draw_lines();\
  699.   };\
  700.  };\
  701.  function draw_lines(){\
  702.   var len = lines_x.length;\
  703.   if( len %%2 == 0 ){\
  704.    context_lines.clearRect(0,0,xsize,ysize);\
  705.    for(var p = 0 ; p < len ; p = p+2 ){\
  706.     context_lines.beginPath();\
  707.     context_lines.moveTo(lines_x[p],lines_y[p]);\
  708.     context_lines.lineTo(lines_x[p+1],lines_y[p+1]);\
  709.     context_lines.closePath();\
  710.     context_lines.stroke();\
  711.    };\
  712.   };\
  713.   return;\
  714.  };");
  715.  }
  716.  
  717.  if( strstr(draw_types,"rect") != 0){
  718.   fprintf(js_include_file,"\
  719.  function rects(x,y,event_which,num){\
  720.   if(event_which == 0){\
  721.    if( num == 0 && click_cnt == 0 ){rects_x = [];rects_y = [];};\
  722.    rects_x.push(x_snap_check(x,rects_snap));rects_y.push(y_snap_check(y,rects_snap));\
  723.    click_cnt++;\
  724.   }\
  725.   else\
  726.   {\
  727.    if( click_cnt == 1 ){\
  728.     rects_x.push(x_snap_check(x,rects_snap));rects_y.push(y_snap_check(y,rects_snap));\
  729.     draw_rects();\
  730.     rects_x.pop();rects_y.pop();\
  731.    };\
  732.   };\
  733.   if( click_cnt == 2 ){\
  734.    click_cnt = 0;\
  735.    draw_rects();\
  736.   };\
  737.  };\
  738.  function draw_rects(){\
  739.   var len = rects_x.length;\
  740.   if( len %%2 == 0 ){\
  741.    context_rects.clearRect(0,0,xsize,ysize);\
  742.    for(var p = 0 ; p < len ; p = p+2 ){\
  743.     context_rects.beginPath();\
  744.     context_rects.rect(rects_x[p],rects_y[p],rects_x[p+1]-rects_x[p],rects_y[p+1]-rects_y[p]);\
  745.     context_rects.closePath();\
  746.     context_rects.fill();\
  747.     context_rects.stroke();\
  748.    };\
  749.   };\
  750.   return;\
  751.  };");
  752.  }
  753.  
  754.  if( strstr(draw_types,"closedpoly") != 0 ){
  755.   fprintf(js_include_file,"\
  756.  function check_closed(x1,y1,X,Y){\
  757.   var marge=10;\
  758.   var len = X.length-1;\
  759.   for(var p = 0 ; p < len ; p++){\
  760.    if(x1 < X[p] + marge && x1 > X[p] - marge ){\
  761.     if(y1 < Y[p] + marge && y1 > Y[p] - marge ){\
  762.      return 1;\
  763.     };\
  764.    };\
  765.   };\
  766.   return 0;\
  767.  };\
  768.  function closedpoly(x,y,event_which,num){\
  769.   if(event_which == 0){\
  770.    if(click_cnt == 0){\
  771.     closedpoly_x = [];closedpoly_y = [];\
  772.     closedpoly_x[0] = x_snap_check(x,closedpoly_snap);closedpoly_y[0] = y_snap_check(y,closedpoly_snap);\
  773.    }\
  774.    else\
  775.    {\
  776.     closedpoly_x.push(x_snap_check(x,closedpoly_snap));closedpoly_y.push(y_snap_check(y,closedpoly_snap));\
  777.    };\
  778.    click_cnt++;\
  779.    if( click_cnt > 2 ){\
  780.     if( check_closed(x,y,closedpoly_x,closedpoly_y) == 1){\
  781.      draw_closedpoly();\
  782.      click_cnt = 0;\
  783.     };\
  784.    }\
  785.   }\
  786.   else\
  787.   {\
  788.    if( click_cnt > 0 ){\
  789.     closedpoly_x.push(x_snap_check(x,closedpoly_snap));closedpoly_y.push(y_snap_check(y,closedpoly_snap));\
  790.     draw_closedpoly();\
  791.     closedpoly_x.pop();closedpoly_y.pop();\
  792.    };\
  793.   };\
  794.  };\
  795.  function draw_closedpoly(){\
  796.   var len = closedpoly_x.length;\
  797.   context_closedpoly.clearRect(0,0,xsize,ysize);\
  798.   var p = 0;\
  799.   context_closedpoly.beginPath();\
  800.   context_closedpoly.moveTo(closedpoly_x[0],closedpoly_y[0]);\
  801.   for(var p = 1 ; p < len ; p++){\
  802.    context_closedpoly.lineTo(closedpoly_x[p],closedpoly_y[p]);\
  803.   };\
  804.   context_closedpoly.lineTo(closedpoly_x[0],closedpoly_y[0]);\
  805.   context_closedpoly.closePath();\
  806.   context_closedpoly.fill();\
  807.   context_closedpoly.stroke();\
  808.   return;\
  809.  };");
  810.  }
  811. /* the next : just one type allowed triangel;.poly[3-9],parallelogram */
  812.  if( strstr(draw_types,"triangle") != 0 ){
  813.    fprintf(js_include_file,"\
  814.   function triangles(x,y,event_which,num){\
  815.    var last = triangles_x.length - 1;\
  816.    if(event_which == 0){\
  817.     if(num == 0 && click_cnt == 0){\
  818.      triangles_x = [];triangles_y = [];\
  819.      triangles_x[0] = x_snap_check(x,triangles_snap);triangles_y[0] = y_snap_check(y,triangles_snap);\
  820.     }\
  821.     else\
  822.     {\
  823.      triangles_x.push(x_snap_check(x,triangles_snap));triangles_y.push(y_snap_check(y,triangles_snap));\
  824.     };\
  825.     click_cnt++;\
  826.    }\
  827.    else\
  828.    {\
  829.     if( click_cnt < 3 ){\
  830.      triangles_x.push(x_snap_check(x,triangles_snap));triangles_y.push(y_snap_check(y,triangles_snap));\
  831.      draw_triangles();\
  832.      triangles_x.pop();triangles_y.pop();\
  833.     };\
  834.    };\
  835.    if( click_cnt == 3 ){\
  836.     triangles_x.pop();triangles_y.pop();\
  837.     triangles_x.push(x_snap_check(x,triangles_snap));triangles_y.push(y_snap_check(y,triangles_snap));\
  838.     click_cnt = 0;\
  839.     draw_triangles();\
  840.    };\
  841.   };\
  842.   function draw_triangles(){\
  843.    var len = triangles_x.length - 1;\
  844.    context_triangles.clearRect(0,0,xsize,ysize);\
  845.    for(var p = 0 ; p < len ; p = p+3){\
  846.     context_triangles.beginPath();\
  847.     context_triangles.moveTo(triangles_x[p],triangles_y[p]);\
  848.     for( var m = p+1 ;m < p+3 ; m++){\
  849.      context_triangles.lineTo(triangles_x[m],triangles_y[m]);\
  850.     };\
  851.     context_triangles.lineTo(triangles_x[p],triangles_y[p]);\
  852.     context_triangles.closePath();\
  853.     context_triangles.fill();\
  854.     context_triangles.stroke();\
  855.    };\
  856.    return;\
  857.   };");
  858.  }
  859.    /* need to rethink the parallelogram !!! 26/6/2015 */
  860.  if(strstr( draw_types,"parallelogram") != 0){
  861.   fprintf(js_include_file,"\
  862.    function parallelogram(x,y,event_which,num){\
  863.     var l2 = parallelogram_x.length;\
  864.     var l1 = l2 - 1;\
  865.     var l0 = l2 - 2;\
  866.    if(event_which == 0){\
  867.     if(click_cnt == 0){\
  868.      if(num == 0){parallelogram_x = [];parallelogram_y = [];};\
  869.      parallelogram_x.push(x_snap_check(x,parallelogram_snap));parallelogram_y.push(y_snap_check(y,parallelogram_snap));\
  870.     }\
  871.     else\
  872.     {\
  873.      parallelogram_x.push(x_snap_check(x,parallelogram_snap));parallelogram_y.push(y_snap_check(y,parallelogram_snap));\
  874.      if(click_cnt == 2){\
  875.       parallelogram_x.push(x_snap_check(parallelogram_x[l2]-parallelogram_x[l1] + parallelogram_x[l0]));\
  876.       parallelogram_y.push(y_snap_check(parallelogram_y[l2]-parallelogram_y[l1] + parallelogram_y[l0]));\
  877.      };\
  878.     };\
  879.     click_cnt++;\
  880.    }\
  881.    else\
  882.    {\
  883.     if(click_cnt == 1){\
  884.      parallelogram_x.push(x_snap_check(parallelogram_x[l1]));\
  885.      parallelogram_y.push(y_snap_check(parallelogram_y[l1]));\
  886.      parallelogram_x.push(x_snap_check(x,parallelogram_snap));\
  887.      parallelogram_y.push(y_snap_check(y,parallelogram_snap));\
  888.      draw_parallelogram();\
  889.      parallelogram_x.pop();parallelogram_y.pop();\
  890.      parallelogram_x.pop();parallelogram_y.pop();\
  891.     }\
  892.     else\
  893.     {\
  894.      if(click_cnt > 1 && click_cnt < 3){\
  895.       parallelogram_x.push(x_snap_check(x,parallelogram_snap));parallelogram_y.push(y_snap_check(y,parallelogram_snap));\
  896.       parallelogram_x.push(x_snap_check(parallelogram_x[l2]-parallelogram_x[l1] + parallelogram_x[l0]));\
  897.       parallelogram_y.push(y_snap_check(parallelogram_y[l2]-parallelogram_y[l1] + parallelogram_y[l0]));\
  898.       draw_parallelogram();\
  899.       parallelogram_x.pop();parallelogram_y.pop();\
  900.       parallelogram_x.pop();parallelogram_y.pop();\
  901.      };\
  902.     };\
  903.    };\
  904.    if( click_cnt == 3 ){\
  905.     parallelogram_x.pop();parallelogram_y.pop();\
  906.     parallelogram_x.push(x_snap_check(parallelogram_x[l2]-parallelogram_x[l1] + parallelogram_x[l0]));\
  907.     parallelogram_y.push(y_snap_check(parallelogram_y[l2]-parallelogram_y[l1] + parallelogram_y[l0]));\
  908.     parallelogram_x.push(x_snap_check(x,parallelogram_snap));parallelogram_y.push(y_snap_check(y,parallelogram_snap));\
  909.     parallelogram_x.pop();parallelogram_y.pop();\
  910.     click_cnt = 0;\
  911.     draw_parallelogram();\
  912.    };\
  913.   };\
  914.   function draw_parallelogram(){\
  915.    var len = parallelogram_x.length-1;\
  916.    context_parallelogram.clearRect(0,0,xsize,ysize);\
  917.    for(var p = 0 ; p < len ; p = p+4){\
  918.     context_parallelogram.beginPath();\
  919.     context_parallelogram.moveTo(parallelogram_x[p],parallelogram_y[p]);\
  920.     for( var m = p+1 ;m < p+4 ; m++){\
  921.      context_parallelogram.lineTo(parallelogram_x[m],parallelogram_y[m]);\
  922.     };\
  923.     context_parallelogram.lineTo(parallelogram_x[p],parallelogram_y[p]);\
  924.     context_parallelogram.closePath();\
  925.     context_parallelogram.fill();\
  926.     context_parallelogram.stroke();\
  927.    };\
  928.    return;\
  929.   };");
  930.   }
  931.  
  932.   if( strstr( draw_types,("poly")) != 0 ){
  933.    char *p = draw_types; int polynum=-1;
  934.    while( *p ){ if( isdigit(*p) ){ polynum = atoi(p);break; } else { p++;} }
  935.    if(polynum != -1 ){
  936.     fprintf(js_include_file,"var polynum = %d;\
  937.    function polys(x,y,event_which,num){\
  938.     var last = polys_x.length - 1;\
  939.     if(event_which == 0){\
  940.      if(num == 0 && click_cnt == 0){\
  941.       polys_x = [];polys_y = [];\
  942.       polys_x[0] = x_snap_check(x,polys_snap);polys_y[0] = y_snap_check(y,polys_snap);\
  943.      }\
  944.      else\
  945.      {\
  946.       polys_x.push(x_snap_check(x,polys_snap));polys_y.push(y_snap_check(y,polys_snap));\
  947.      };\
  948.      click_cnt++;\
  949.     }\
  950.     else\
  951.     {\
  952.      if( click_cnt < polynum ){\
  953.       polys_x.push(x_snap_check(x,polys_snap));polys_y.push(y_snap_check(y,polys_snap));\
  954.       draw_polys();\
  955.       polys_x.pop();polys_y.pop();\
  956.      };\
  957.     };\
  958.     if( click_cnt == polynum ){\
  959.      polys_x.pop();polys_y.pop();\
  960.      polys_x.push(x_snap_check(x,polys_snap));polys_y.push(y_snap_check(y,polys_snap));\
  961.      click_cnt = 0;\
  962.      draw_polys();\
  963.     };\
  964.    };\
  965.    function draw_polys(){\
  966.     var len = polys_x.length - 1;\
  967.     context_polys.clearRect(0,0,xsize,ysize);\
  968.     for(var p = 0 ; p < len ; p = p+polynum){\
  969.      context_polys.beginPath();\
  970.      context_polys.moveTo(polys_x[p],polys_y[p]);\
  971.      for( var m = p+1 ;m < p+polynum ; m++){\
  972.       context_polys.lineTo(polys_x[m],polys_y[m]);\
  973.      };\
  974.      context_polys.lineTo(polys_x[p],polys_y[p]);\
  975.      context_polys.closePath();\
  976.      context_polys.fill();\
  977.      context_polys.stroke();\
  978.     };\
  979.     return;\
  980.    };",polynum);
  981.    }
  982.   }
  983. } /* end 'void add_js_multidraw()' */
  984.  
  985. void add_js_circles(FILE *js_include_file,int num,char *draw_type,int line_width, int radius ,char *stroke_color,double stroke_opacity,int use_filled,char *fill_color,double fill_opacity,int use_dashed,int dashtype0,int dashtype1){
  986. fprintf(js_include_file,"\n<!-- begin userdraw \"%s\" on final canvas -->\n\
  987. var num = %d;\
  988. userdraw_radius[0] = %d;\
  989. var line_width = %d;\
  990. var stroke_color = \"%s\";\
  991. var stroke_opacity = %f;\
  992. var use_filled = %d;\
  993. var fill_color = \"%s\";\
  994. var fill_opacity = %f;\
  995. var use_dashed = %d;\
  996. var dashtype1 = %d;\
  997. var dashtype0 = %d;\
  998. var click_cnt = 0;\
  999. var x0,y0,x1,y1;\
  1000. var mouse;\
  1001. function user_draw(evt){\
  1002. mouse = dragstuff.getMouse(evt,canvas_userdraw);\
  1003. x0 = mouse.x;\
  1004. y0 = mouse.y;\
  1005. if(y0 < ysize + 1){\
  1006.  if( use_snap_to_points != 0 ){\
  1007.   var xy = new Array(2);\
  1008.   if( use_snap_to_points == 1 ){\
  1009.    xy = snap_to_points(x0,y0);\
  1010.   }\
  1011.   else\
  1012.   {\
  1013.    xy = snap_to_fun(x0,y0);\
  1014.   };\
  1015.   x0 = xy[0];y0 = xy[1];\
  1016.  }\
  1017.  else\
  1018.  {\
  1019.   if( x_use_snap_to_grid == 1 ){\
  1020.    x0 = snap_to_x(x0);\
  1021.   };\
  1022.   if( y_use_snap_to_grid == 1 ){\
  1023.    y0 = snap_to_y(y0);\
  1024.   };\
  1025.  };\
  1026.  if(evt.which == 1 || evt.identifier == 0){\
  1027.   if( click_cnt == 0 ){\
  1028.    userdraw_x[xy_cnt] = x0;\
  1029.    userdraw_y[xy_cnt] = y0;\
  1030.    userdraw_radius[xy_cnt] = line_width;\
  1031.    click_cnt = 1;\
  1032.    draw_circles(context_userdraw,userdraw_x,userdraw_y,userdraw_radius,line_width,stroke_color,stroke_opacity,use_filled,fill_color,fill_opacity,use_dashed,dashtype0,dashtype1);\
  1033.   }\
  1034.   else\
  1035.   {\
  1036.    click_cnt = 0;\
  1037.    if( num != 1 ){ xy_cnt++; }\
  1038.   }\
  1039.  }\
  1040.  else\
  1041.  {\
  1042.    canvas_remove(x0,y0);\
  1043.  }\
  1044. }\
  1045. };\
  1046. function user_drag(evt){\
  1047. if( click_cnt == 1 ){\
  1048.  mouse = dragstuff.getMouse(evt,canvas_userdraw);\
  1049.  x1 = mouse.x;\
  1050.  y1 = mouse.y;\
  1051.  if( use_snap_to_points != 0 ){\
  1052.   var xy = new Array(2);\
  1053.   if( use_snap_to_points == 1 ){\
  1054.    xy = snap_to_points(x1,y1);\
  1055.   }\
  1056.   else\
  1057.   {\
  1058.    xy = snap_to_fun(x1,y1);\
  1059.   };\
  1060.   x1 = xy[0];y1 = xy[1];\
  1061.  }\
  1062.  else\
  1063.  {\
  1064.   if( x_use_snap_to_grid == 1 ){\
  1065.     x1 = snap_to_x(x1);\
  1066.   };\
  1067.   if( y_use_snap_to_grid == 1 ){\
  1068.    y1 = snap_to_y(y1);\
  1069.   };\
  1070.  };\
  1071.  userdraw_radius[xy_cnt] = parseInt(Math.sqrt( (x1-x0)*(x1-x0) + (y1-y0)*(y1-y0) ));\
  1072.  userdraw_x[xy_cnt] = x0;\
  1073.  userdraw_y[xy_cnt] = y0;\
  1074.  context_userdraw.clearRect(0,0,xsize,ysize);\
  1075.  draw_circles(context_userdraw,userdraw_x,userdraw_y,userdraw_radius,line_width,stroke_color,stroke_opacity,use_filled,fill_color,fill_opacity,use_dashed,dashtype0,dashtype1);\
  1076. };\
  1077. };\
  1078. function canvas_remove(x,y){\
  1079. var marge = 10*line_width;\
  1080. var diff1;var diff2;\
  1081. for(var p = 0;p < userdraw_x.length ; p++){\
  1082.  diff1 = (x-userdraw_x[p])*(x - userdraw_x[p]) + (y - userdraw_y[p])*(y - userdraw_y[p]) - userdraw_radius[p]*userdraw_radius[p];\
  1083.  diff2 = (x-userdraw_x[p])*(x - userdraw_x[p]) + (y - userdraw_y[p])*(y - userdraw_y[p]) - (userdraw_radius[p] - marge)*(userdraw_radius[p] - marge);\
  1084.  if( diff1 < 0 && diff2 > 0 ){\
  1085.   if(confirm(\"remove circle ?\")){\
  1086.    if( num == 1 ){ userdraw_x = [];userdraw_y = []; userdraw_radius = [];xy_cnt = 0;context_userdraw.clearRect(0,0,xsize,ysize); return;}\
  1087.    else\
  1088.    {\
  1089.     userdraw_x.splice(p,1);\
  1090.     userdraw_y.splice(p,1);\
  1091.     userdraw_radius.splice(p,1);\
  1092.     xy_cnt--;\
  1093.     context_userdraw = null;context_userdraw = canvas_userdraw.getContext(\"2d\");context_userdraw.clearRect(0,0,xsize,ysize);\
  1094.     draw_circles(context_userdraw,userdraw_x,userdraw_y,userdraw_radius,line_width,stroke_color,stroke_opacity,use_filled,fill_color,fill_opacity,use_dashed,dashtype0,dashtype1);\
  1095.    };\
  1096.   };\
  1097.   return;\
  1098.  }\
  1099. }\
  1100. };",draw_type,num,radius,line_width,stroke_color,stroke_opacity,use_filled,fill_color,fill_opacity,use_dashed,dashtype0,dashtype1);
  1101. }
  1102.  
  1103.  
  1104. /*  function draw_circles(ctx,x_points,y_points,radius,line_width,stroke_color,stroke_opacity,use_filled,fill_color,fill_opacity,use_dashed,dashtype0,dashtype1);*/
  1105. void add_js_points(FILE *js_include_file,int num,char *draw_type,int line_width, int radius ,char *stroke_color,double stroke_opacity,int use_filled,char *fill_color,double fill_opacity,int use_dashed,int dashtype0,int dashtype1){
  1106. fprintf(js_include_file,"\n<!-- begin userdraw \"%s\" on final canvas -->\n\
  1107. var num = %d;\
  1108. userdraw_radius[0] = %d;\
  1109. var line_width = %d;\
  1110. var stroke_color = \"%s\";\
  1111. var stroke_opacity = %f;\
  1112. var use_filled = %d;\
  1113. var fill_color = \"%s\";\
  1114. var fill_opacity = %f;\
  1115. var use_dashed = %d;\
  1116. var dashtype1 = %d;\
  1117. var dashtype0 = %d;\
  1118. var x0,y0,x1,y1;\
  1119. var canvas_rect;\
  1120. function user_draw(evt){\
  1121. var mouse = dragstuff.getMouse(evt,canvas_userdraw);\
  1122. x0 = mouse.x;\
  1123. y0 = mouse.y;\
  1124. if( use_snap_to_points != 0 ){\
  1125.  var xy = new Array(2);\
  1126.  if( use_snap_to_points == 1 ){\
  1127.   xy = snap_to_points(x0,y0);\
  1128.  }\
  1129.  else\
  1130.  {\
  1131.   xy = snap_to_fun(x0,y0);\
  1132.  };\
  1133.  x0 = xy[0];y0 = xy[1];\
  1134. }\
  1135. else\
  1136. {\
  1137.  if( x_use_snap_to_grid == 1 ){\
  1138.   x0 = snap_to_x(x0);\
  1139.  };\
  1140.  if( y_use_snap_to_grid == 1 ){\
  1141.   y0 = snap_to_y(y0);\
  1142.  };\
  1143. };\
  1144. if(evt.which == 1 || evt.identifier == 0){\
  1145.  userdraw_x[xy_cnt] = x0;\
  1146.  userdraw_y[xy_cnt] = y0;\
  1147.  userdraw_radius[xy_cnt] = line_width;\
  1148.  if( num != 1 ){ xy_cnt++; }else{context_userdraw.clearRect(0,0,xsize,ysize);};\
  1149.  draw_circles(context_userdraw,userdraw_x,userdraw_y,userdraw_radius,line_width,stroke_color,stroke_opacity,use_filled,fill_color,fill_opacity,use_dashed,dashtype0,dashtype1);\
  1150. }\
  1151. else\
  1152. {\
  1153.  canvas_remove(x0,y0);\
  1154. };\
  1155. };\
  1156. function user_drag(evt){ return;};\
  1157. function canvas_remove(x,y){\
  1158. var marge = 4*line_width;\
  1159. for(var p = 0;p < userdraw_x.length ; p++){\
  1160.  if(userdraw_x[p] < x + marge && userdraw_x[p] > x - marge ){\
  1161.   if(userdraw_y[p] < y + marge && userdraw_y[p] > y - marge ){\
  1162.    userdraw_x.splice(p,1);userdraw_y.splice(p,1);\
  1163.    context_userdraw = null;context_userdraw = canvas_userdraw.getContext(\"2d\");context_userdraw.clearRect(0,0,xsize,ysize);\
  1164.    draw_circles(context_userdraw,userdraw_x,userdraw_y,userdraw_radius,line_width,stroke_color,stroke_opacity,use_filled,fill_color,fill_opacity,use_dashed,dashtype0,dashtype1);\
  1165.    xy_cnt--;\
  1166.    return;\
  1167.   };\
  1168.  };\
  1169. };\
  1170. };",draw_type,num,radius,line_width,stroke_color,stroke_opacity,use_filled,fill_color,fill_opacity,use_dashed,dashtype0,dashtype1);
  1171. }
  1172.  
  1173. void add_js_inputs(FILE *js_include_file,int canvas_root_id,int num,int input_cnt,char *input_style,int line_width,int use_offset){
  1174. fprintf(js_include_file,"\n<!-- user draw inputfields -->\n\
  1175. var canvas_rect;\
  1176. var input_cnt = %d;\
  1177. var start_input_cnt = input_cnt;\
  1178. function user_drag(evt){return;}\
  1179. function user_draw(evt){\
  1180. canvas_rect = canvas_userdraw.getBoundingClientRect();\
  1181. var x = evt.clientX - canvas_rect.left;\
  1182. var y = evt.clientY - canvas_rect.top;\
  1183. if( use_snap_to_points != 0 ){\
  1184.  var xy = new Array(2);\
  1185.  if( use_snap_to_points == 1 ){\
  1186.   xy = snap_to_points(x,y);\
  1187.  }\
  1188.  else\
  1189.  {\
  1190.   xy = snap_to_fun(x,y);\
  1191.  };\
  1192.  x = xy[0];y = xy[1];\
  1193. }\
  1194. else\
  1195. {\
  1196.  if( x_use_snap_to_grid == 1 ){\
  1197.   x = snap_to_x(x);\
  1198.  };\
  1199.  if( y_use_snap_to_grid == 1 ){\
  1200.   y = snap_to_y(y);\
  1201.  };\
  1202. };\
  1203. var num = %d;var inputs;\
  1204. if(evt.which == 1){\
  1205.  var inputs;var xi;var yi;var wi;var hi;\
  1206.  var found = 0;\
  1207.  if( start_input_cnt < input_cnt){\
  1208.   for(var p = start_input_cnt ; p < input_cnt ; p++ ){\
  1209.    inputs = document.getElementById(\"canvas_input\"+p);\
  1210.    xi = findPosX(inputs) - canvas_rect.left;\
  1211.    yi = findPosY(inputs) - canvas_rect.top;\
  1212.    wi = 4 + inputs.clientWidth;\
  1213.    hi = 4 + inputs.clientHeight;\
  1214.    if( x > xi - wi && x < xi + wi && y > yi - hi && y < yi + hi ){\
  1215.     found = 1;\
  1216.    };\
  1217.   };\
  1218.  };\
  1219.  if( found == 0 ){\
  1220.   if( num == 1 ){\
  1221.    inputs = document.getElementById(\"canvas_input\"+start_input_cnt);\
  1222.    try{canvas_div.removeChild(inputs);}catch(e){};\
  1223.    input_cnt = 0;\
  1224.   };\
  1225.   userdraw_x.push(x);userdraw_y.push(y);\
  1226.   draw_inputs(%d,input_cnt,x,y,%d,1,\"%s\",\"?\",%d);\
  1227.   input_cnt++;\
  1228.  };\
  1229. }\
  1230. else\
  1231. {\
  1232.  for(var p = start_input_cnt ; p < input_cnt; p++){\
  1233.   inputs = document.getElementById(\"canvas_input\"+p);\
  1234.   try{canvas_div.removeChild(inputs);}catch(e){};\
  1235.  };\
  1236.  userdraw_x = [];userdraw_y = [];\
  1237.  input_cnt = start_input_cnt;\
  1238. };\
  1239. };",input_cnt,num,canvas_root_id,line_width,input_style,use_offset);
  1240. }
  1241.  
  1242. void add_zoom_buttons(FILE *js_include_file,int canvas_root_id,char *stroke_color,double stroke_opacity){
  1243. fprintf(js_include_file,"\n<!-- draw zoom buttons -->\n\
  1244. var draw_zoom_buttons = function(){\
  1245. var obj;var canvas_type =%d;\
  1246. if( document.getElementById(\"wims_canvas%d\"+canvas_type) ){\
  1247.  obj = document.getElementById(\"wims_canvas%d\"+canvas_type);\
  1248. }\
  1249. else\
  1250. {\
  1251.  obj = create_canvas%d(canvas_type,xsize,ysize);\
  1252. };\
  1253. var ctx = obj.getContext(\"2d\");\
  1254. ctx.font =\"18px Ariel\";\
  1255. ctx.textAlign = \"right\";\
  1256. ctx.fillStyle=\"rgba(%s,%f)\";\
  1257. ctx.fillText(\"+\",xsize,ysize);\
  1258. ctx.fillText(\"\\u2212\",xsize - 15,ysize);\
  1259. ctx.fillText(\"\\u2192\",xsize - 30,ysize-2);\
  1260. ctx.fillText(\"\\u2190\",xsize - 45,ysize-2);\
  1261. ctx.fillText(\"\\u2191\",xsize - 60,ysize-2);\
  1262. ctx.fillText(\"\\u2193\",xsize - 75,ysize-2);\
  1263. ctx.fillText(\"\\u00D7\",xsize - 90,ysize-2);\
  1264. ctx.stroke();\
  1265. };\ndraw_zoom_buttons();",BG_CANVAS,canvas_root_id,canvas_root_id,canvas_root_id,stroke_color,stroke_opacity);
  1266. }
  1267.  
  1268. void add_js_crosshairs(FILE *js_include_file,int num,char *draw_type,int line_width, int crosshair_size ,char *stroke_color,double stroke_opacity){
  1269. fprintf(js_include_file,"\n<!-- begin userdraw \"%s\" on currect active canvas -->\n\
  1270. var num = %d;\
  1271. var crosshair_size = %d;\
  1272. var line_width = %d;\
  1273. var stroke_color = \"%s\";\
  1274. var stroke_opacity = %f;\
  1275. context_userdraw.lineWidth = line_width;\
  1276. context_userdraw.strokeStyle=\"rgba(\"+stroke_color+\",\"+stroke_opacity+\")\";\
  1277. function user_drag(evt){return;}\
  1278. function user_draw(evt){\
  1279. var mouse = dragstuff.getMouse(evt,canvas_userdraw);\
  1280. var x = mouse.x;\
  1281. var y = mouse.y;\
  1282. if( use_snap_to_points != 0 ){\
  1283.  var xy = new Array(2);\
  1284.  if( use_snap_to_points == 1 ){\
  1285.   xy = snap_to_points(x,y);\
  1286.  }\
  1287.  else\
  1288.  {\
  1289.   xy = snap_to_fun(x,y);\
  1290.  };\
  1291.  x = xy[0];y = xy[1];\
  1292. }\
  1293. else\
  1294. {\
  1295.  if( x_use_snap_to_grid == 1 ){\
  1296.   x = snap_to_x(x);\
  1297.  };\
  1298.  if( y_use_snap_to_grid == 1 ){\
  1299.   y = snap_to_y(y);\
  1300.  };\
  1301. };\
  1302. var x1,y1,x2,y2;\
  1303. if(evt.which == 1 || evt.identifier == 0 ){\
  1304.   userdraw_x[xy_cnt] = x;\
  1305.   userdraw_y[xy_cnt] = y;\
  1306.   x1 = x - crosshair_size;\
  1307.   x2 = x + crosshair_size;\
  1308.   y1 = y - crosshair_size;\
  1309.   y2 = y + crosshair_size;\
  1310.   if( num != 1 ){ xy_cnt++;\
  1311.    for(var p = 0; p < xy_cnt - 1 ;p++){\
  1312.     if(x1 < userdraw_x[p] && x2 > userdraw_x[p]){\
  1313.      if(y1 < userdraw_y[p] && y2 > userdraw_y[p]){\
  1314.       canvas_remove(x,y);\
  1315.       context_userdraw = null;context_userdraw = canvas_userdraw.getContext(\"2d\");\
  1316.      }\
  1317.     }\
  1318.    }\
  1319.   };\
  1320.   context_userdraw.beginPath();\
  1321.   context_userdraw.moveTo(x1,y1);\
  1322.   context_userdraw.lineTo(x2,y2);\
  1323.   context_userdraw.closePath();\
  1324.   context_userdraw.stroke();\
  1325.   context_userdraw.beginPath();\
  1326.   context_userdraw.moveTo(x2,y1);\
  1327.   context_userdraw.lineTo(x1,y2);\
  1328.   context_userdraw.closePath();\
  1329.   context_userdraw.stroke();\
  1330.   context_userdraw.clearRect(0,0,xsize,ysize);\
  1331.   draw_crosshairs(context_userdraw,userdraw_x,userdraw_y,line_width,crosshair_size,stroke_color,stroke_opacity,0,0,0,[0,0]);\
  1332. }\
  1333. else\
  1334. {\
  1335. canvas_remove(x,y);\
  1336. }\
  1337. }\
  1338. function canvas_remove(x,y){\
  1339. var marge = 2*crosshair_size;\
  1340. for(var p = 0;p < userdraw_x.length ; p++){\
  1341.  if(userdraw_x[p] < x + marge && userdraw_x[p] > x - marge ){\
  1342.   if(userdraw_y[p] < y + marge && userdraw_y[p] > y - marge ){\
  1343.    userdraw_x.splice(p,1);userdraw_y.splice(p,1);\
  1344.    context_userdraw = null;context_userdraw = canvas_userdraw.getContext(\"2d\");context_userdraw.clearRect(0,0,xsize,ysize);\
  1345.    xy_cnt--;\
  1346.    draw_crosshairs(context_userdraw,userdraw_x,userdraw_y,line_width,crosshair_size,stroke_color,stroke_opacity,0,0,0,[0,0]);\
  1347.    return;\
  1348.   }\
  1349.  }\
  1350. }\
  1351. };",draw_type,num,crosshair_size,line_width,stroke_color,stroke_opacity);
  1352. }
  1353.  
  1354. /* need to rewrite not using clickcnt and xy_cnt */
  1355. void add_js_rect(FILE *js_include_file,int num,int roundrect,char *draw_type,int line_width,char *stroke_color,double stroke_opacity,int use_filled,char *fill_color,double fill_opacity,int use_dashed,int dashtype0,int dashtype1){
  1356. fprintf(js_include_file,"\n<!-- begin userdraw \"%s\" on currect active canvas -->\n\
  1357. var roundrect = %d;\
  1358. var line_width = %d;\
  1359. var stroke_color = \"%s\";\
  1360. var stroke_opacity = %f;\
  1361. var use_filled = %d;\
  1362. var fill_color = \"%s\";\
  1363. var fill_opacity = %f;\
  1364. var use_dashed = %d;\
  1365. var dashtype0 = %d;\
  1366. var dashtype1 = %d;\
  1367. var num = %d;\
  1368. var use_rotate = 0;\
  1369. var angle = 0;\
  1370. var closed_path = 1;\
  1371. var clickcnt = 0;\
  1372. xy_cnt = 0;\
  1373. var x0,y0,x1,y1;\
  1374. var marge = 10*line_width;\
  1375. function user_draw(evt){\
  1376. var mouse = dragstuff.getMouse(evt,canvas_userdraw);\
  1377. x0 = mouse.x;\
  1378. y0 = mouse.y;\
  1379. if( use_snap_to_points != 0 ){\
  1380.  var xy = new Array(2);\
  1381.  if( use_snap_to_points == 1 ){\
  1382.   xy = snap_to_points(x0,y0);\
  1383.  }\
  1384.  else\
  1385.  {\
  1386.   xy = snap_to_fun(x0,y0);\
  1387.  };\
  1388.  x0 = xy[0];y0 = xy[1];\
  1389. }\
  1390. else\
  1391. {\
  1392.  if( x_use_snap_to_grid == 1 ){\
  1393.   x0 = snap_to_x(x0);\
  1394.  };\
  1395.  if( y_use_snap_to_grid == 1 ){\
  1396.   y0 = snap_to_y(y0);\
  1397.  };\
  1398. };\
  1399. if( evt.which == 1 || evt.identifier == 0 ){\
  1400.  if(clickcnt == 0 ){\
  1401.   clickcnt = 1;\
  1402.   userdraw_x[xy_cnt] = x0;userdraw_y[xy_cnt] = y0;xy_cnt++;\
  1403.  }\
  1404.  else\
  1405.  {\
  1406.   clickcnt = 0;\
  1407.   var lu = userdraw_x.length - 1;\
  1408.   if( userdraw_x[lu] == userdraw_x[lu-1] && userdraw_y[lu] == userdraw_y[lu-1]){userdraw_x.pop();userdraw_y.pop();clickcnt=1;return;};\
  1409.   if(roundrect == 0 ){\
  1410.    draw_rects(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_filled,fill_color,fill_opacity,use_dashed,dashtype0,dashtype1,use_rotate,angle,0,[1,0,0,1,0,0]);\
  1411.   }\
  1412.   else\
  1413.   {\
  1414.    draw_roundrects(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_filled,fill_color,fill_opacity,use_dashed,dashtype0,dashtype1,use_rotate,angle,0,[1,0,0,1,0,0]);\
  1415.   }\
  1416.   if( num != 1 ){ xy_cnt++; }else{xy_cnt--;}\
  1417.  }\
  1418. }\
  1419. else\
  1420. {\
  1421.  canvas_remove(x0,y0);\
  1422. };\
  1423. };\
  1424. function user_drag(evt){\
  1425. var mouse = dragstuff.getMouse(evt,canvas_userdraw);\
  1426. x1 = mouse.x;\
  1427. y1 = mouse.y;\
  1428. if( clickcnt == 1 ){\
  1429.  var xy = new Array(2);\
  1430.  if( use_snap_to_points != 0 ){\
  1431.   if( use_snap_to_points == 1 ){\
  1432.    xy = snap_to_points(x1,y1);\
  1433.   }\
  1434.   else\
  1435.   {\
  1436.    xy = snap_to_fun(x1,y1);\
  1437.   };\
  1438.   x1 = xy[0];y1 = xy[1];\
  1439.  }\
  1440.  else\
  1441.  {\
  1442.   if( x_use_snap_to_grid == 1 ){\
  1443.    x1 = snap_to_x(x1);\
  1444.   };\
  1445.   if( y_use_snap_to_grid == 1 ){\
  1446.   y1 = snap_to_y(y1);\
  1447.   };\
  1448.  };\
  1449.  userdraw_x[xy_cnt] = x1;\
  1450.  userdraw_y[xy_cnt] = y1;\
  1451.  context_userdraw.clearRect(0,0,xsize,ysize);\
  1452.  if( roundrect == 0 ){\
  1453.   draw_rects(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_filled,fill_color,fill_opacity,use_dashed,dashtype0,dashtype1,use_rotate,angle,0,[1,0,0,1,0,0]);\
  1454.  }\
  1455.  else\
  1456.  {\
  1457.   draw_roundrects(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_filled,fill_color,fill_opacity,use_dashed,dashtype0,dashtype1,use_rotate,angle,0,[1,0,0,1,0,0]);\
  1458.  };\
  1459. };\
  1460. };\
  1461. function canvas_remove(x,y){\
  1462. for(var p = 0;p < userdraw_x.length ; p++){\
  1463.  if(userdraw_x[p] < x + marge && userdraw_x[p] > x - marge ){\
  1464.   if(userdraw_y[p] < y + marge && userdraw_y[p] > y - marge ){\
  1465.    if( confirm(\"remove rectangle ?\" )){\
  1466.     if( p%%2 == 0 ){\
  1467.      userdraw_x.splice(p,2);userdraw_y.splice(p,2);\
  1468.     }\
  1469.     else\
  1470.     {\
  1471.      userdraw_x.splice(p-1,2);userdraw_y.splice(p-1,2);\
  1472.     }\
  1473.     xy_cnt = xy_cnt - 2;\
  1474.     context_userdraw.clearRect(0,0,xsize,ysize);\
  1475.     if(xy_cnt < 2){xy_cnt = 0;click_cnt = 0;userdraw_x = [];userdraw_y = [];return;};\
  1476.     if( roundrect == 0 ){\
  1477.      draw_rects(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_filled,fill_color,fill_opacity,use_dashed,dashtype0,dashtype1,use_rotate,angle,0,[1,0,0,1,0,0]);\
  1478.     }\
  1479.     else\
  1480.     {\
  1481.      draw_roundrects(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_filled,fill_color,fill_opacity,use_dashed,dashtype0,dashtype1,use_rotate,angle,0,[1,0,0,1,0,0]);\
  1482.     }\
  1483.     return;\
  1484.    };\
  1485.   };\
  1486.  };\
  1487. };\
  1488. };",draw_type,roundrect,line_width,stroke_color,stroke_opacity,use_filled,fill_color,fill_opacity,use_dashed,dashtype0,dashtype1,num);
  1489. }
  1490.  
  1491. void add_js_poly(FILE *js_include_file,int num,char *draw_type,int line_width,char *stroke_color,double stroke_opacity,int use_filled,char *fill_color,double fill_opacity,int use_dashed,int dashtype0,int dashtype1){
  1492. fprintf(js_include_file,"\n<!-- begin userdraw \"%s\" on currect active canvas -->\n\
  1493. var num = %d;\
  1494. var line_width = %d;\
  1495. var stroke_color = \"%s\";\
  1496. var stroke_opacity = %f;\
  1497. var use_filled = %d;\
  1498. var fill_color = \"%s\";\
  1499. var fill_opacity = %f;\
  1500. var use_dashed = %d;\
  1501. var dashtype0 = %d;\
  1502. var dashtype1 = %d;\
  1503. var use_rotate = 0;\
  1504. var angle = 0;\
  1505. var use_translate = 0;\
  1506. var vector=[0,0];\
  1507. var closed_path = 1;\
  1508. var done = 1;\
  1509. var x,y;\
  1510. var marge = 10*line_width;\
  1511. var canvas_rect;\
  1512. function user_draw(evt){\
  1513. var mouse = dragstuff.getMouse(evt,canvas_userdraw);\
  1514. x = mouse.x;\
  1515. y = mouse.y;\
  1516. var xy = new Array(2);\
  1517. if( use_snap_to_points != 0 ){\
  1518.  if( use_snap_to_points == 1 ){\
  1519.   xy = snap_to_points(x,y);\
  1520.  }\
  1521.  else\
  1522.  {\
  1523.   xy = snap_to_fun(x,y);\
  1524.  };\
  1525.  x = xy[0];y = xy[1];\
  1526. }\
  1527. else\
  1528. {\
  1529.  if( x_use_snap_to_grid == 1 ){\
  1530.   x = snap_to_x(x);\
  1531.  };\
  1532.  if( y_use_snap_to_grid == 1 ){\
  1533.   y = snap_to_y(y);\
  1534.  };\
  1535. };\
  1536. if( evt.which == 1 || evt.identifier == 0 ){\
  1537.  if( num == -1 && xy_cnt > 2 ){\
  1538.   if( x - marge < userdraw_x[0] && x + marge > userdraw_x[0]){\
  1539.    if( y - marge < userdraw_y[0] && y + marge > userdraw_y[0]){\
  1540.     userdraw_x.splice(xy_cnt,1);userdraw_y.splice(xy_cnt,1);\
  1541.     draw_paths(context_userdraw,userdraw_x,userdraw_y,line_width,closed_path,stroke_color,stroke_opacity,use_filled,fill_color,fill_opacity,use_dashed,dashtype0,dashtype1,use_rotate,angle,0,[1,0,0,1,0,0]);\
  1542.     done = 1;return;\
  1543.    };\
  1544.   };\
  1545.  }\
  1546.  else\
  1547.  {\
  1548.   if( xy_cnt == num - 1){\
  1549.    draw_paths(context_userdraw,userdraw_x,userdraw_y,line_width,closed_path,stroke_color,stroke_opacity,use_filled,fill_color,fill_opacity,use_dashed,dashtype0,dashtype1,use_rotate,angle,0,[1,0,0,1,0,0]);\
  1550.    done = 1;return;\
  1551.   };\
  1552.  };\
  1553.  done = 0;\
  1554.  userdraw_x[xy_cnt] = x;userdraw_y[xy_cnt] = y;xy_cnt++;\
  1555.  user_drag(evt);\
  1556. }\
  1557. else\
  1558. {\
  1559.  canvas_remove(x,y);\
  1560.  return;\
  1561. }\
  1562. };\
  1563. function user_drag(evt){\
  1564. if( done == 0 ){\
  1565.  var mouse = dragstuff.getMouse(evt,canvas_userdraw);\
  1566.  x = mouse.x;\
  1567.  y = mouse.y;\
  1568.  if( use_snap_to_points != 0 ){\
  1569.   var xy = new Array(2);\
  1570.   if( use_snap_to_points == 1 ){\
  1571.    xy = snap_to_points(x,y);\
  1572.   }\
  1573.   else\
  1574.   {\
  1575.    xy = snap_to_fun(x,y);\
  1576.   };\
  1577.   x = xy[0];y = xy[1];\
  1578.  }\
  1579.  else\
  1580.  {\
  1581.   if( x_use_snap_to_grid == 1 ){\
  1582.    x = snap_to_x(x);\
  1583.   };\
  1584.   if( y_use_snap_to_grid == 1 ){\
  1585.    y = snap_to_y(y);\
  1586.   };\
  1587.  };\
  1588.  context_userdraw.clearRect(0,0,xsize,ysize);\
  1589.  userdraw_x[xy_cnt] = x;userdraw_y[xy_cnt] = y;\
  1590.  draw_paths(context_userdraw,userdraw_x,userdraw_y,line_width,closed_path,stroke_color,stroke_opacity,use_filled,fill_color,fill_opacity,use_dashed,dashtype0,dashtype1,use_rotate,angle,0,[1,0,0,1,0,0]);\
  1591. }\
  1592. }\
  1593. function canvas_remove(x,y){\
  1594. for(var p = 0;p < userdraw_x.length ; p++){\
  1595.  if(userdraw_x[p] < x + marge && userdraw_x[p] > x - marge ){\
  1596.   if(userdraw_y[p] < y + marge && userdraw_y[p] > y - marge ){\
  1597.    if( confirm(\"remove polygone ?\" )){\
  1598.     context_userdraw = null;context_userdraw = canvas_userdraw.getContext(\"2d\");context_userdraw.clearRect(0,0,xsize,ysize);\
  1599.     xy_cnt = 0;userdraw_x = [];userdraw_y = [];done = 1;\
  1600.    }\
  1601.    return;\
  1602.   }\
  1603.  }\
  1604. }\
  1605. };",draw_type,num,line_width,stroke_color,stroke_opacity,use_filled,fill_color,fill_opacity,use_dashed,dashtype0,dashtype1);
  1606. }
  1607.  
  1608. /*
  1609.   canvas_rect = canvas_userdraw.getBoundingClientRect();\
  1610.   var x = evt.clientX - canvas_rect.left;\
  1611.   var y = evt.clientY - canvas_rect.top;\
  1612. */
  1613. void add_js_polyline(FILE *js_include_file,char *draw_type,int line_width, char *stroke_color,double stroke_opacity,int use_dashed,int dashtype0,int dashtype1){
  1614. fprintf(js_include_file,"\n<!-- begin userdraw \"%s\" on final canvas -->\n\
  1615. var cnt = 0;\
  1616. var line_width = %d;\
  1617. var stroke_color = \"%s\";\
  1618. var stroke_opacity = %f;\
  1619. var use_dashed = %d;\
  1620. var dashtype0 = %d;\
  1621. var dashtype1 = %d;\
  1622. var x,y;\
  1623. function user_draw(evt){\
  1624. var mouse = dragstuff.getMouse(evt,canvas_userdraw);\
  1625. x = mouse.x;\
  1626. y = mouse.y;\
  1627. var lu = userdraw_x.length;\
  1628. if( use_snap_to_points != 0 ){\
  1629.  var xy = new Array(2);\
  1630.  if( use_snap_to_points == 1 ){\
  1631.   xy = snap_to_points(x,y);\
  1632.  }\
  1633.  else\
  1634.  {\
  1635.   xy = snap_to_fun(x,y);\
  1636.  };\
  1637.  x = xy[0];y = xy[1];\
  1638. }\
  1639. else\
  1640. {\
  1641.  if( x_use_snap_to_grid == 1 ){\
  1642.   x = snap_to_x(x);\
  1643.  };\
  1644.  if( y_use_snap_to_grid == 1 ){\
  1645.   y = snap_to_y(y);\
  1646.  };\
  1647. };\
  1648. if( evt.which == 1 || evt.identifier == 0 ){\
  1649.  userdraw_x[lu] = x;userdraw_y[lu] = y;\
  1650.  if( cnt == 0 ){\
  1651.   user_drag(evt);\
  1652.   cnt = 1;\
  1653.  }\
  1654.  else\
  1655.  {\
  1656.    cnt = 0;\
  1657.    draw_polyline(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);\
  1658.  }\
  1659. }\
  1660. else\
  1661. {\
  1662.  canvas_remove(x,y);\
  1663. }\
  1664. };\
  1665. function user_drag(evt){\
  1666. if( cnt == 0){\
  1667.  var mouse = dragstuff.getMouse(evt,canvas_userdraw);\
  1668.  x = mouse.x;\
  1669.  y = mouse.y;\
  1670.  if( use_snap_to_points != 0 ){\
  1671.   var xy = new Array(2);\
  1672.   if( use_snap_to_points == 1 ){\
  1673.    xy = snap_to_points(x,y);\
  1674.   }\
  1675.   else\
  1676.   {\
  1677.    xy = snap_to_fun(x,y);\
  1678.   };\
  1679.   x = xy[0];y = xy[1];\
  1680.  }\
  1681.  else\
  1682.  {\
  1683.   if( x_use_snap_to_grid == 1 ){\
  1684.    x = snap_to_x(x);\
  1685.   };\
  1686.   if( y_use_snap_to_grid == 1 ){\
  1687.    y = snap_to_y(y);\
  1688.   };\
  1689.  };\
  1690.  var lu = userdraw_x.length;\
  1691.  if( lu > 0 ){\
  1692.   userdraw_x[lu - 1] = x; userdraw_y[lu - 1] = y;\
  1693.   draw_polyline(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);\
  1694.  };\
  1695. }\
  1696. };\
  1697. function canvas_remove(x,y){\
  1698. if( confirm(\"remove line ?\" )){\
  1699.  context_userdraw.clearRect(0,0,xsize,ysize);\
  1700.  userdraw_x = [];userdraw_y = [];cnt = 1;\
  1701.  xy_cnt=0;\
  1702.  return;\
  1703. }\
  1704. };",draw_type,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);
  1705. }
  1706.  
  1707. void add_js_segments(FILE *js_include_file,int num,char *draw_type,int line_width, char *stroke_color,double stroke_opacity,int use_dashed,int dashtype0,int dashtype1){
  1708. fprintf(js_include_file,"\n<!-- begin userdraw \"%s\" on final canvas -->\n\
  1709. var num = %d;\
  1710. var line_width = %d;\
  1711. var stroke_color = \"%s\";\
  1712. var stroke_opacity = %f;\
  1713. var use_dashed = %d;\
  1714. var dashtype0 = %d;\
  1715. var dashtype1 = %d;\
  1716. var x0,y0;\
  1717. function user_draw(evt){\
  1718. var lu = userdraw_x.length;\
  1719. if( lu != 0 && lu%%2 == 0){\
  1720.  draw_segments(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);\
  1721. }\
  1722. var mouse = dragstuff.getMouse(evt,canvas_userdraw);\
  1723. var x = mouse.x;\
  1724. var y = mouse.y;\
  1725. if( use_snap_to_points != 0 ){\
  1726.  var xy = new Array(2);\
  1727.  if( use_snap_to_points == 1 ){\
  1728.   xy = snap_to_points(x,y);\
  1729.  }\
  1730.  else\
  1731.  {\
  1732.   xy = snap_to_fun(x,y);\
  1733.  };\
  1734.  x = xy[0];y = xy[1];\
  1735. }\
  1736. else\
  1737. {\
  1738.  if( x_use_snap_to_grid == 1 ){\
  1739.   x = snap_to_x(x);\
  1740.  };\
  1741.  if( y_use_snap_to_grid == 1 ){\
  1742.   y = snap_to_y(y);\
  1743.  };\
  1744. };\
  1745. if( evt.which == 1 || evt.identifier == 0){\
  1746.  if( lu%%2 == 0){\
  1747.   x0 = x;y0 = y;\
  1748.   if(num == 1){ userdraw_x = [];userdraw_y = [];userdraw_x[0] = x0;userdraw_y[0] = y0;} else {userdraw_x[lu] = x0;userdraw_y[lu] = y0;};\
  1749.   draw_circles(context_userdraw,[x0],[y0],[line_width],line_width,stroke_color,stroke_opacity,1,stroke_color,stroke_opacity,0,1,1);\
  1750.   user_drag(evt);\
  1751.  }\
  1752.  else\
  1753.  {\
  1754.   if( num == 1 ){ userdraw_x[1] = x;userdraw_y[1] = y;} else {userdraw_x[lu] = x;userdraw_y[lu] = y;};\
  1755.   if( userdraw_x[lu] == userdraw_x[lu-1] && userdraw_y[lu] == userdraw_y[lu-1]){userdraw_x.splice(lu,2);userdraw_y.splice(lu,2);};\
  1756.   draw_segments(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);\
  1757.  }\
  1758. }\
  1759. else\
  1760. {\
  1761.  canvas_remove(x,y);\
  1762. }\
  1763. };\
  1764. function user_drag(evt){\
  1765. var mouse = dragstuff.getMouse(evt,canvas_userdraw);\
  1766. var x = mouse.x;\
  1767. var y = mouse.y;\
  1768. var lu = userdraw_x.length;\
  1769. if( use_snap_to_points != 0 ){\
  1770.  var xy = new Array(2);\
  1771.  if( use_snap_to_points == 1 ){\
  1772.   xy = snap_to_points(x,y);\
  1773.  }\
  1774.  else\
  1775.  {\
  1776.   xy = snap_to_fun(x,y);\
  1777.  };\
  1778.  x = xy[0];y = xy[1];\
  1779. }\
  1780. else\
  1781. {\
  1782.  if( x_use_snap_to_grid == 1 ){\
  1783.   x = snap_to_x(x);\
  1784.  };\
  1785.  if( y_use_snap_to_grid == 1 ){\
  1786.   y = snap_to_y(y);\
  1787.  };\
  1788. };\
  1789. if( lu%%2 != 0 ){\
  1790.  context_userdraw.clearRect(0,0,xsize,ysize);\
  1791.  draw_circles(context_userdraw,[x0],[y0],[line_width],line_width,stroke_color,stroke_opacity,1,stroke_color,stroke_opacity,0,1,1);\
  1792.  draw_circles(context_userdraw,[x],[y],[line_width],line_width,stroke_color,stroke_opacity,1,stroke_color,stroke_opacity,0,1,1);\
  1793.  draw_segments(context_userdraw,[x0,x],[y0,y],line_width,stroke_color,stroke_opacity);\
  1794.  if( lu > 0){\
  1795.   draw_segments(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);\
  1796.  }\
  1797. }\
  1798. };\
  1799. function canvas_remove(x,y){\
  1800. var marge = 10*line_width;\
  1801. for(var p = 0;p < userdraw_x.length ; p++){\
  1802.  if(userdraw_x[p] < x + marge && userdraw_x[p] > x - marge ){\
  1803.   if(userdraw_y[p] < y + marge && userdraw_y[p] > y - marge ){\
  1804.    if( confirm(\"remove line ?\" )){\
  1805.     context_userdraw = null;context_userdraw = canvas_userdraw.getContext(\"2d\");context_userdraw.clearRect(0,0,xsize,ysize);\
  1806.     if( p%%2 == 0 ){\
  1807.      userdraw_x.splice(p,2);userdraw_y.splice(p,2);\
  1808.     }\
  1809.     else\
  1810.     {\
  1811.      userdraw_x.splice(p-1,2);userdraw_y.splice(p-1,2);\
  1812.     }\
  1813.     if(userdraw_x.length < 2){ userdraw_x = [];userdraw_y = [];return;};\
  1814.     xy_cnt = xy_cnt - 2;\
  1815.     draw_segments(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);\
  1816.    }\
  1817.    return;\
  1818.   }\
  1819.  }\
  1820. }\
  1821. };",draw_type,num,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);
  1822. }
  1823.  
  1824. void add_js_demilines(FILE *js_include_file,int num,char *draw_type,int line_width, char *stroke_color,double stroke_opacity,int use_dashed,int dashtype0,int dashtype1){
  1825. fprintf(js_include_file,"\n<!-- begin userdraw \"%s\" on final canvas -->\n\
  1826. var num = %d;\
  1827. var line_width = %d;\
  1828. var stroke_color = \"%s\";\
  1829. var stroke_opacity = %f;\
  1830. var use_dashed = %d;\
  1831. var dashtype0 = %d;\
  1832. var dashtype1 = %d;\
  1833. var x0,y0;\
  1834. function user_draw(evt){\
  1835. var lu = userdraw_x.length;\
  1836. if( lu != 0 && lu%%2 == 0){\
  1837.  draw_demilines(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);\
  1838. }\
  1839. var mouse = dragstuff.getMouse(evt,canvas_userdraw);\
  1840. var x = mouse.x;\
  1841. var y = mouse.y;\
  1842. if( use_snap_to_points != 0 ){\
  1843.  var xy = new Array(2);\
  1844.  if( use_snap_to_points == 1 ){\
  1845.   xy = snap_to_points(x,y);\
  1846.  }\
  1847.  else\
  1848.  {\
  1849.   xy = snap_to_fun(x,y);\
  1850.  };\
  1851.  x = xy[0];y = xy[1];\
  1852. }\
  1853. else\
  1854. {\
  1855.  if( x_use_snap_to_grid == 1 ){\
  1856.   x = snap_to_x(x);\
  1857.  };\
  1858.  if( y_use_snap_to_grid == 1 ){\
  1859.   y = snap_to_y(y);\
  1860.  };\
  1861. };\
  1862. if( evt.which == 1 || evt.identifier == 0 ){\
  1863.  if( lu%%2 == 0){\
  1864.   x0 = x;y0 = y;\
  1865.   if(num == 1){ userdraw_x = [];userdraw_y = [];userdraw_x[0] = x0;userdraw_y[0] = y0;} else {userdraw_x[lu] = x0;userdraw_y[lu] = y0;}\
  1866.   draw_circles(context_userdraw,[x0],[y0],[line_width],line_width,stroke_color,stroke_opacity,1,stroke_color,stroke_opacity,0,1,1);\
  1867.   user_drag(evt);\
  1868.  }\
  1869.  else\
  1870.  {\
  1871.   if( num == 1 ){ userdraw_x[1] = x;userdraw_y[1] = y;} else {userdraw_x[lu] = x;userdraw_y[lu] = y;};\
  1872.   if( userdraw_x[lu] == userdraw_x[lu-1] && userdraw_y[lu] == userdraw_y[lu-1]){userdraw_x.splice(lu,2);userdraw_y.splice(lu,2);};\
  1873.   draw_demilines(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);\
  1874.  }\
  1875. }\
  1876. else\
  1877. {\
  1878.  canvas_remove(x,y);\
  1879. }\
  1880. };\
  1881. function user_drag(evt){\
  1882. var mouse = dragstuff.getMouse(evt,canvas_userdraw);\
  1883. var x = mouse.x;\
  1884. var y = mouse.y;\
  1885. var lu = userdraw_x.length;\
  1886. if( use_snap_to_points != 0 ){\
  1887.  var xy = new Array(2);\
  1888.  if( use_snap_to_points == 1 ){\
  1889.   xy = snap_to_points(x,y);\
  1890.  }\
  1891.  else\
  1892.  {\
  1893.   xy = snap_to_fun(x,y);\
  1894.  };\
  1895.  x = xy[0];y = xy[1];\
  1896. }\
  1897. else\
  1898. {\
  1899.  if( x_use_snap_to_grid == 1 ){\
  1900.   x = snap_to_x(x);\
  1901.  };\
  1902.  if( y_use_snap_to_grid == 1 ){\
  1903.   y = snap_to_y(y);\
  1904.  };\
  1905. };\
  1906. if( lu%%2 != 0 ){\
  1907.  context_userdraw.clearRect(0,0,xsize,ysize);\
  1908.  draw_circles(context_userdraw,[x0],[y0],[line_width],line_width,stroke_color,stroke_opacity,1,stroke_color,stroke_opacity,0,1,1);\
  1909.  draw_circles(context_userdraw,[x],[y],[line_width],line_width,stroke_color,stroke_opacity,1,stroke_color,stroke_opacity,0,1,1);\
  1910.  draw_demilines(context_userdraw,[x0,x],[y0,y],line_width,stroke_color,stroke_opacity);\
  1911.  if( lu > 0){\
  1912.   draw_demilines(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);\
  1913.  }\
  1914. }\
  1915. };\
  1916. function canvas_remove(x,y){\
  1917. var marge = 10*line_width;\
  1918. for(var p = 0;p < userdraw_x.length ; p++){\
  1919.  if(userdraw_x[p] < x + marge && userdraw_x[p] > x - marge ){\
  1920.   if(userdraw_y[p] < y + marge && userdraw_y[p] > y - marge ){\
  1921.    if( confirm(\"remove line ?\" )){\
  1922.     context_userdraw = null;context_userdraw = canvas_userdraw.getContext(\"2d\");context_userdraw.clearRect(0,0,xsize,ysize);\
  1923.     if( p%%2 == 0 ){\
  1924.      userdraw_x.splice(p,2);userdraw_y.splice(p,2);\
  1925.     }\
  1926.     else\
  1927.     {\
  1928.      userdraw_x.splice(p-1,2);userdraw_y.splice(p-1,2);\
  1929.     }\
  1930.     xy_cnt = xy_cnt - 2;\
  1931.     if(userdraw_x.length < 2){ userdraw_x = [];userdraw_y = [];return;};\
  1932.     draw_demilines(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);\
  1933.    }\
  1934.    return;\
  1935.   }\
  1936.  }\
  1937. }\
  1938. };",draw_type,num,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);
  1939. }
  1940.  
  1941.  
  1942. /*
  1943. num=1 single horizontal line
  1944. num=2 multiple horizontal lines
  1945. num=3 single vertical line
  1946. num=4 multiple vertical lines
  1947. */
  1948. void add_js_hlines(FILE *js_include_file,int num,char *draw_type,int line_width, char *stroke_color,double stroke_opacity,int use_dashed,int dashtype0,int dashtype1){
  1949. fprintf(js_include_file,"\n<!-- begin userdraw \"%s\" on final canvas -->\n\
  1950. var num = %d;\
  1951. var line_width = %d;\
  1952. var stroke_color = \"%s\";\
  1953. var stroke_opacity = %f;\
  1954. var use_dashed = %d;\
  1955. var dashtype0 = %d;\
  1956. var dashtype1 = %d;\
  1957. var x0,y0;\
  1958. function user_draw(evt){\
  1959. if( evt.which == 1 || evt.identifier == 0){\
  1960.  var mouse = dragstuff.getMouse(evt,canvas_userdraw);\
  1961.  var x = mouse.x;\
  1962.  var y = mouse.y;\
  1963.  if( use_snap_to_points != 0 ){\
  1964.   var xy = new Array(2);\
  1965.   if( use_snap_to_points == 1 ){\
  1966.    xy = snap_to_points(x,y);\
  1967.   }\
  1968.   else\
  1969.   {\
  1970.    xy = snap_to_fun(x,y);\
  1971.   };\
  1972.   x = xy[0];y = xy[1];\
  1973.  }\
  1974.  else\
  1975.  {\
  1976.   if( x_use_snap_to_grid == 1 ){\
  1977.    x = snap_to_x(x);\
  1978.   };\
  1979.   if( y_use_snap_to_grid == 1 ){\
  1980.    y = snap_to_y(y);\
  1981.   };\
  1982.  };\
  1983.  var lu = userdraw_x.length;\
  1984.  switch(num){\
  1985.   case 1: userdraw_x[0] = x;userdraw_x[1] = xmax;userdraw_y[0] = y; userdraw_y[1] = y;break;\
  1986.   case 2: userdraw_x[lu] = x;userdraw_x[lu+1] = xmax;userdraw_y[lu] = y;userdraw_y[lu+1] = y;break;\
  1987.   case 3: userdraw_x[0] = x;userdraw_x[1] = x;userdraw_y[0] = y; userdraw_y[1] = ymax;break;\
  1988.   case 4: userdraw_x[lu] = x;userdraw_x[lu+1] = x;userdraw_y[lu] = y;userdraw_y[lu+1] = ymax;break;\
  1989.  };\
  1990.  context_userdraw.clearRect(0,0,xsize,ysize);\
  1991.  draw_lines(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);\
  1992. }\
  1993. else\
  1994. {\
  1995.  userdraw_x = [];userdraw_y = [];context_userdraw.clearRect(0,0,xsize,ysize);return;\
  1996. };\
  1997. };\
  1998. function user_drag(evt){ return evt; };",draw_type,num,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);
  1999. }
  2000.  
  2001.  
  2002.  
  2003. void add_js_lines(FILE *js_include_file,int num,char *draw_type,int line_width, char *stroke_color,double stroke_opacity,int use_dashed,int dashtype0,int dashtype1){
  2004. fprintf(js_include_file,"\n<!-- begin userdraw \"%s\" on final canvas -->\n\
  2005. var num = %d;\
  2006. var line_width = %d;\
  2007. var stroke_color = \"%s\";\
  2008. var stroke_opacity = %f;\
  2009. var use_dashed = %d;\
  2010. var dashtype0 = %d;\
  2011. var dashtype1 = %d;\
  2012. var x0,y0;\
  2013. function user_draw(evt){\
  2014. var lu = userdraw_x.length;\
  2015. if( lu != 0 && lu%%2 == 0){\
  2016.  draw_lines(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);\
  2017. }\
  2018. var mouse = dragstuff.getMouse(evt,canvas_userdraw);\
  2019. var x = mouse.x;\
  2020. var y = mouse.y;\
  2021. if( use_snap_to_points != 0 ){\
  2022.  var xy = new Array(2);\
  2023.  if( use_snap_to_points == 1 ){\
  2024.   xy = snap_to_points(x,y);\
  2025.  }\
  2026.  else\
  2027.  {\
  2028.   xy = snap_to_fun(x,y);\
  2029.  };\
  2030.  x = xy[0];y = xy[1];\
  2031. }\
  2032. else\
  2033. {\
  2034.  if( x_use_snap_to_grid == 1 ){\
  2035.   x = snap_to_x(x);\
  2036.  };\
  2037.  if( y_use_snap_to_grid == 1 ){\
  2038.   y = snap_to_y(y);\
  2039.  };\
  2040. };\
  2041. if( evt.which == 1 || evt.identifier == 0 ){\
  2042.  if( lu%%2 == 0){\
  2043.   x0 = x;y0 = y;\
  2044.   if(num == 1){ userdraw_x = [];userdraw_y = [];userdraw_x[0] = x0;userdraw_y[0] = y0;} else {userdraw_x[lu] = x0;userdraw_y[lu] = y0;}\
  2045.   draw_circles(context_userdraw,[x0],[y0],[line_width],line_width,stroke_color,stroke_opacity,1,stroke_color,stroke_opacity,0,1,1);\
  2046.   user_drag(evt);\
  2047.  }\
  2048.  else\
  2049.  {\
  2050.   if( num == 1 ){ userdraw_x[1] = x;userdraw_y[1] = y;} else {userdraw_x[lu] = x;userdraw_y[lu] = y;};\
  2051.   if( userdraw_x[lu] == userdraw_x[lu-1] && userdraw_y[lu] == userdraw_y[lu-1]){userdraw_x.splice(lu,2);userdraw_y.splice(lu,2);};\
  2052.   draw_lines(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);\
  2053.  };\
  2054. }\
  2055. else\
  2056. {\
  2057.  canvas_remove(x,y);\
  2058. };\
  2059. };\
  2060. function user_drag(evt){\
  2061. var mouse = dragstuff.getMouse(evt,canvas_userdraw);\
  2062. var x = mouse.x;\
  2063. var y = mouse.y;\
  2064. var lu = userdraw_x.length;\
  2065. if( use_snap_to_points != 0 ){\
  2066.  var xy = new Array(2);\
  2067.  if( use_snap_to_points == 1 ){\
  2068.   xy = snap_to_points(x,y);\
  2069.  }\
  2070.  else\
  2071.  {\
  2072.   xy = snap_to_fun(x,y);\
  2073.  };\
  2074.  x = xy[0];y = xy[1];\
  2075. }\
  2076. else\
  2077. {\
  2078.  if( x_use_snap_to_grid == 1 ){\
  2079.   x = snap_to_x(x);\
  2080.  };\
  2081.  if( y_use_snap_to_grid == 1 ){\
  2082.   y = snap_to_y(y);\
  2083.  };\
  2084. };\
  2085. if( lu%%2 != 0 ){\
  2086.  context_userdraw.clearRect(0,0,xsize,ysize);\
  2087.  draw_circles(context_userdraw,[x0],[y0],[line_width],line_width,stroke_color,stroke_opacity,1,stroke_color,stroke_opacity,0,1,1);\
  2088.  draw_circles(context_userdraw,[x],[y],[line_width],line_width,stroke_color,stroke_opacity,1,stroke_color,stroke_opacity,0,1,1);\
  2089.  draw_lines(context_userdraw,[x0,x],[y0,y],line_width,stroke_color,stroke_opacity);\
  2090.  if( lu > 0){\
  2091.   draw_lines(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);\
  2092.  }\
  2093. }\
  2094. };\
  2095. function canvas_remove(x,y){\
  2096. var marge = 10*line_width;\
  2097. for(var p = 0;p < userdraw_x.length ; p++){\
  2098.  if(userdraw_x[p] < x + marge && userdraw_x[p] > x - marge ){\
  2099.   if(userdraw_y[p] < y + marge && userdraw_y[p] > y - marge ){\
  2100.    if( confirm(\"remove line ?\" )){\
  2101.     context_userdraw = null;context_userdraw = canvas_userdraw.getContext(\"2d\");context_userdraw.clearRect(0,0,xsize,ysize);\
  2102.     if( p%%2 == 0 ){\
  2103.      userdraw_x.splice(p,2);userdraw_y.splice(p,2);\
  2104.     }\
  2105.     else\
  2106.     {\
  2107.      userdraw_x.splice(p-1,2);userdraw_y.splice(p-1,2);\
  2108.     }\
  2109.     xy_cnt--;\
  2110.     if(userdraw_x.length < 2){ userdraw_x = [];userdraw_y = [];return;};\
  2111.     draw_lines(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);\
  2112.    }\
  2113.    return;\
  2114.   }\
  2115.  }\
  2116. }\
  2117. };",draw_type,num,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);
  2118. }
  2119.  
  2120.  
  2121. void add_js_arrows(FILE *js_include_file,int num,char *draw_type,int line_width,int type, char *stroke_color,double stroke_opacity,int use_dashed,int dashtype0,int dashtype1,int arrow_head){
  2122. /*
  2123. constants in draw_arrows() ... for this moment: ;var use_rotate = 0;var angle = 0;var use_translate = 0 ;var vector = [0,0];\
  2124. */
  2125. fprintf(js_include_file,"\n<!-- begin userdraw \"%s\" on final canvas -->\n\
  2126. var num = %d;\
  2127. var line_width = %d;\
  2128. var stroke_color = \"%s\";\
  2129. var stroke_opacity = %f;\
  2130. var use_dashed = %d;\
  2131. var dashtype0 = %d;\
  2132. var dashtype1 = %d;\
  2133. var arrow_head = %d;\
  2134. var x0,y0;\
  2135. var type = %d;\
  2136. var use_rotate = 0;var angle = 0;var use_translate = 0 ;var vector = [0,0];\
  2137. function user_draw(evt){\
  2138. var lu = userdraw_x.length;\
  2139. if( lu != 0 && lu%%2 == 0){\
  2140.  draw_arrows(context_userdraw,userdraw_x,userdraw_y,arrow_head,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1,type,use_rotate,angle,0,[1,0,0,1,0,0]);\
  2141. }\
  2142. var mouse = dragstuff.getMouse(evt,canvas_userdraw);\
  2143. var x = mouse.x;\
  2144. var y = mouse.y;\
  2145. if( use_snap_to_points != 0 ){\
  2146.  var xy = new Array(2);\
  2147.  if( use_snap_to_points == 1 ){\
  2148.   xy = snap_to_points(x,y);\
  2149.  }\
  2150.  else\
  2151.  {\
  2152.   xy = snap_to_fun(x,y);\
  2153.  };\
  2154.  x = xy[0];y = xy[1];\
  2155. }\
  2156. else\
  2157. {\
  2158.  if( x_use_snap_to_grid == 1 ){\
  2159.   x = snap_to_x(x);\
  2160.  };\
  2161.  if( y_use_snap_to_grid == 1 ){\
  2162.   y = snap_to_y(y);\
  2163.  };\
  2164. };\
  2165. if( evt.which == 1 || evt.identifier == 0 ){\
  2166.  if( lu%%2 == 0){\
  2167.   x0 = x;y0 = y;\
  2168.   if(num == 1){ userdraw_x = [];userdraw_y = [];userdraw_x[0] = x0;userdraw_y[0] = y0;} else {userdraw_x[lu] = x0;userdraw_y[lu] = y0;}\
  2169.   user_drag(evt);\
  2170.  }\
  2171.  else\
  2172.  {\
  2173.   if( num == 1 ){ userdraw_x[1] = x;userdraw_y[1] = y;} else {userdraw_x[lu] = x;userdraw_y[lu] = y;};\
  2174.   if( userdraw_x[lu] == userdraw_x[lu-1] && userdraw_y[lu] == userdraw_y[lu-1]){userdraw_x.splice(lu,2);userdraw_y.splice(lu,2);};\
  2175.   draw_arrows(context_userdraw,userdraw_x,userdraw_y,arrow_head,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1,type,use_rotate,angle,0,[1,0,0,1,0,0]);\
  2176.  };\
  2177. }\
  2178. else\
  2179. {\
  2180.  canvas_remove(x,y);\
  2181. };\
  2182. };\
  2183. function user_drag(evt){\
  2184. var mouse = dragstuff.getMouse(evt,canvas_userdraw);\
  2185. var x = mouse.x;\
  2186. var y = mouse.y;\
  2187. var lu = userdraw_x.length;\
  2188. if( use_snap_to_points != 0 ){\
  2189.  var xy = new Array(2);\
  2190.  if( use_snap_to_points == 1 ){\
  2191.   xy = snap_to_points(x,y);\
  2192.  }\
  2193.  else\
  2194.  {\
  2195.   xy = snap_to_fun(x,y);\
  2196.  };\
  2197.  x = xy[0];y = xy[1];\
  2198. }\
  2199. else\
  2200. {\
  2201.  if( x_use_snap_to_grid == 1 ){\
  2202.   x = snap_to_x(x);\
  2203.  };\
  2204.  if( y_use_snap_to_grid == 1 ){\
  2205.   y = snap_to_y(y);\
  2206.  };\
  2207. };\
  2208. if( lu%%2 != 0 ){\
  2209.  context_userdraw.clearRect(0,0,xsize,ysize);\
  2210.  draw_arrows(context_userdraw,[x0,x],[y0,y],arrow_head,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1,type,use_rotate,angle,0,[1,0,0,1,0,0]);\
  2211.  if( lu > 0){\
  2212.    draw_arrows(context_userdraw,userdraw_x,userdraw_y,arrow_head,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1,type,use_rotate,angle,0,[1,0,0,1,0,0]);\
  2213.  }\
  2214. }\
  2215. };\
  2216. function canvas_remove(x,y){\
  2217. var marge = 10*line_width;\
  2218. for(var p = 0;p < userdraw_x.length ; p++){\
  2219.  if(userdraw_x[p] < x + marge && userdraw_x[p] > x - marge ){\
  2220.   if(userdraw_y[p] < y + marge && userdraw_y[p] > y - marge ){\
  2221.    if( confirm(\"remove line ?\" )){\
  2222.     context_userdraw = null;context_userdraw = canvas_userdraw.getContext(\"2d\");context_userdraw.clearRect(0,0,xsize,ysize);\
  2223.     if( p%%2 == 0 ){\
  2224.      userdraw_x.splice(p,2);userdraw_y.splice(p,2);\
  2225.     }\
  2226.     else\
  2227.     {\
  2228.      userdraw_x.splice(p-1,2);userdraw_y.splice(p-1,2);\
  2229.     }\
  2230.     xy_cnt = xy_cnt - 2;\
  2231.     if(userdraw_x.length < 2){ userdraw_x = [];userdraw_y = [];return;};\
  2232.     draw_arrows(context_userdraw,userdraw_x,userdraw_y,arrow_head,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1,type,use_rotate,angle,0,[1,0,0,1,0,0],type,use_rotate,angle,0,[1,0,0,1,0,0]);\
  2233.    }\
  2234.    return;\
  2235.   }\
  2236.  }\
  2237. }\
  2238. };",draw_type,num,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1,arrow_head,type);
  2239.  
  2240. }
  2241.  
  2242. void add_js_paths(FILE *js_include_file,int num,char *draw_type,int line_width, int closed_path,char *stroke_color,double stroke_opacity,int use_filled, char *fill_color,double fill_opacity,int use_dashed,int dashtype0,int dashtype1){
  2243. fprintf(js_include_file,"\n<!-- begin userdraw \"%s\" on final canvas -->\n\
  2244. var path_cnt = 0;\
  2245. var temp_x = [];\
  2246. var temp_y = [];\
  2247. var num = %d;\
  2248. xy_cnt=0;\
  2249. var line_width = %d;\
  2250. var stroke_color = \"%s\";\
  2251. var stroke_opacity = %f;\
  2252. var fill_color = \"%s\";\
  2253. var fill_opacity = %f;\
  2254. var use_filled = %d;\
  2255. var use_dashed = %d;\
  2256. var dashtype0 = %d;\
  2257. var dashtype1 = %d;\
  2258. var closed_path = 0;\
  2259. var click_cnt=0;\
  2260. function user_draw(evt){\
  2261. var mouse = dragstuff.getMouse(evt,canvas_userdraw);\
  2262. var x = mouse.x;\
  2263. var y = mouse.y;\
  2264. if( use_snap_to_points != 0 ){\
  2265.  var xy = new Array(2);\
  2266.  if( use_snap_to_points == 1 ){\
  2267.   xy = snap_to_points(x,y);\
  2268.  }\
  2269.  else\
  2270.  {\
  2271.   xy = snap_to_fun(x,y);\
  2272.  };\
  2273.  x = xy[0];y = xy[1];\
  2274. }\
  2275. else\
  2276. {\
  2277.  if( x_use_snap_to_grid == 1 ){\
  2278.   x = snap_to_x(x);\
  2279.  };\
  2280.  if( y_use_snap_to_grid == 1 ){\
  2281.   y = snap_to_y(y);\
  2282.  };\
  2283. };\
  2284. if(evt.which == 1 || evt.identifier == 0){\
  2285.  if( click_cnt == 0 ){\
  2286.   click_cnt = 1;\
  2287.   user_drag(evt);\
  2288.  }\
  2289.  else\
  2290.  {\
  2291.   userdraw_x[path_cnt] = new Array();\
  2292.   userdraw_y[path_cnt] = new Array();\
  2293.   userdraw_x[path_cnt] = temp_x;\
  2294.   userdraw_y[path_cnt] = temp_y;\
  2295.   path_cnt++;\
  2296.   temp_x = [];\
  2297.   temp_y = [];\
  2298.   click_cnt = 0;\
  2299.   xy_cnt = 0;\
  2300.  };\
  2301. }\
  2302. else\
  2303. {\
  2304.   canvas_remove(x,y);\
  2305. };\
  2306. context_userdraw.clearRect(0,0,xsize,ysize);\
  2307. for(var p=0; p < path_cnt; p++){\
  2308.  if(userdraw_x[p] != null){\
  2309.   draw_paths(context_userdraw,userdraw_x[p],userdraw_y[p],line_width,0,stroke_color,stroke_opacity,use_filled,fill_color,fill_opacity,use_dashed,dashtype0,dashtype1);\
  2310.  };\
  2311. };\
  2312. };\
  2313. function user_drag(evt){\
  2314. if(click_cnt == 1 ){\
  2315.  var mouse = dragstuff.getMouse(evt,canvas_userdraw);\
  2316.  temp_x[xy_cnt] = mouse.x;\
  2317.  temp_y[xy_cnt] = mouse.y;\
  2318.  if( x_use_snap_to_grid == 1 ){\
  2319.   temp_x[xy_cnt] = snap_to_x(temp_x[xy_cnt]);\
  2320.  };\
  2321.  if( y_use_snap_to_grid == 1 ){\
  2322.   temp_y[xy_cnt] = snap_to_y(temp_y[xy_cnt]);\
  2323.  };\
  2324.  xy_cnt++;\
  2325.  draw_paths(context_userdraw,temp_x,temp_y,line_width,0,stroke_color,stroke_opacity,use_filled,fill_color,fill_opacity,use_dashed,dashtype0,dashtype1);\
  2326. };\
  2327. };\
  2328. function canvas_remove(x,y){\
  2329. var marge = 4*line_width;\
  2330. var tmpx = [];\
  2331. var tmpy = [];\
  2332. for(var i = 0 ; i < path_cnt; i++){\
  2333.  tmpx = userdraw_x[i];\
  2334.  if(tmpx != null){\
  2335.   tmpy = userdraw_y[i];\
  2336.   for(var p = 0;p<tmpx.length;p++){\
  2337.    if( x + marge > tmpx[p] &&  x - marge < tmpx[p] ){\
  2338.     if( y + marge > tmpy[p] &&  y - marge < tmpy[p] ){\
  2339.      if(confirm(\"Remove this drawing ?\")){\
  2340.       userdraw_x[i] = null;\
  2341.       userdraw_y[i] = null;\
  2342.       xy_cnt = 0;click_cnt = 0;\
  2343.       return;\
  2344.      };\
  2345.     };\
  2346.    };\
  2347.   };\
  2348.  };\
  2349. };\
  2350. };",draw_type,num,line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype0,dashtype1);
  2351. }
  2352.  
  2353. void add_js_load_image(FILE *js_include_file,int canvas_root_id){
  2354. fprintf(js_include_file,"\n<!-- begin get_image_from_url -->\n\
  2355. var image_cnt = 0;\
  2356. if( typeof(image_patterns) !== 'object'){var image_patterns = [];};\
  2357. var get_image_from_url = function(url){\
  2358. var idx = Math.ceil(1000*(Math.random()));\
  2359. var canvas = create_canvas%d(idx,xsize,ysize);\
  2360. canvas.style.visibility = 'hidden';\
  2361. var ctx = canvas.getContext(\"2d\");\
  2362. var img = new Image();\
  2363. img.src = url;\
  2364. img.onload = function(){\
  2365.  var pat = ctx.createPattern(img,\"repeat\");\
  2366.  image_patterns.push(pat);\
  2367. };\
  2368. };",canvas_root_id);}
  2369.  
  2370. void add_js_popup(int canvas_root_id,int xsize,int ysize,char *getfile_cmd){
  2371. fprintf(stdout,"\n<!-- begin command popup %d -->\n\
  2372. <script type=\"text/javascript\">\n\
  2373. if( wims_status != 'done'){\n\
  2374. var popup = window.open('','','toolbar=no,scrollbars=yes,menubar=no,location=no,resizable=yes,top=4,left=4,status=no, width = %dpx, height = %dpx');\n\
  2375. var popupHTML =\"<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>\\n<html><head></head>\\n<body><div style='width:%dpx;height:%dpx;position:relative' id='canvas_div%d'></div><div id='tooltip_placeholder_div%d' style='display:block;position:relative;margin-left:auto;margin-right:auto;margin-bottom:4px;'><span id='tooltip_placeholder%d' style='display:none;'></span></div></body></html>\";\n\
  2376. popup.document.write(popupHTML);\n\
  2377. var s0 = popup.document.createElement(\"script\");\n\
  2378. s0.text=\"var wims_status = window.opener.wims_status; var use_dragdrop_reply = window.opener.use_dragdrop_reply;window.opener.canvas_scripts.push('%d');\";\n\
  2379. popup.document.getElementsByTagName(\"HEAD\")[0].appendChild(s0);\n\
  2380. var s1 = popup.document.createElement(\"script\");\n\
  2381. s1.type = \"text/javascript\";\n\
  2382. s1.src = \"%s\"\n\
  2383. popup.document.getElementsByTagName(\"HEAD\")[0].appendChild(s1);\n\
  2384. popup.document.close();\n\
  2385. }else{\n\
  2386. var canvas_div = document.getElementById('canvas_div%d');\n\
  2387. canvas_div.style.display='block';\n\
  2388. };\n\
  2389. \n</script>\n\
  2390. <!-- end command popup %d -->\n",
  2391. canvas_root_id,
  2392. xsize+40,ysize+40,
  2393. xsize,ysize,
  2394. canvas_root_id,
  2395. canvas_root_id,
  2396. canvas_root_id,
  2397. canvas_root_id,
  2398. getfile_cmd,
  2399. canvas_root_id,
  2400. canvas_root_id);
  2401. }
  2402.  
  2403. void add_js_tooltip(int canvas_root_id,char *tooltip_text,char *bgcolor,int xsize,int ysize){
  2404. fprintf(stdout,"\n<!-- begin command intooltip %d -->\n\
  2405. <script type=\"text/javascript\">\n\
  2406. var xsize = %d;\
  2407. var ysize = %d;\
  2408. var tooltip%d_obj_x = 0;\
  2409. var tooltip%d_obj_y = 0;\
  2410. var tooltip%d_flipflop = 0;\
  2411. var tooltip%d_obj = document.getElementById(\"canvas_div%d\");\
  2412. tooltip%d_obj.style.display=\"none\";\
  2413. tooltip%d_obj.style.position=\"absolute\";\
  2414. var tooltip%d_link = document.createElement(\"a\");\
  2415. tooltip%d_link.addEventListener(\"mousemove\",tooltip%d_drag,false);\
  2416. tooltip%d_link.setAttribute(\"onclick\",\"tooltip%d_show()\");\
  2417. tooltip%d_link.innerHTML  = \"%s\";\
  2418. var tooltip_placeholder = document.getElementById(\"tooltip_placeholder%d\");\
  2419. tooltip_placeholder.style.display=\"block\";\
  2420. tooltip_placeholder.style.position=\"absolute\";\
  2421. tooltip_placeholder.style.backgroundColor=\"%s\";\
  2422. tooltip_placeholder.appendChild(tooltip%d_link);\
  2423. function tooltip%d_drag(action){\
  2424. if(!action){ action = event; }\
  2425. if(action.clientX){\
  2426.  tooltip%d_obj.style.left = (tooltip%d_mouseX(action) + 10) +\"px\";\
  2427.  var ytop = tooltip%d_mouseY(action);\
  2428.  if(ytop + ysize < window.innerHeight){\
  2429.   tooltip%d_obj.style.top = (ytop - 10) +\"px\";\
  2430.  }\
  2431.  else\
  2432.  {\
  2433.   tooltip%d_obj.style.top = parseInt(ytop - 0.8*ysize) +\"px\";\
  2434.  }\
  2435. }\
  2436. else\
  2437. {\
  2438.  return null;\
  2439. }\
  2440. }\
  2441. function tooltip%d_mouseX(action){\
  2442. if(action.pageX){\
  2443.  return action.pageX;\
  2444. }\
  2445. else\
  2446. {\
  2447.  if(action.clientX){\
  2448.   return action.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);\
  2449.  }\
  2450.  else\
  2451.  {\
  2452.   return null;\
  2453.  }\
  2454. }\
  2455. }\
  2456. function tooltip%d_mouseY(action){\
  2457. if(action.pageY){\
  2458.  return action.pageY;\
  2459. }\
  2460. else\
  2461. {\
  2462.  if(action.clientY){\
  2463.   return action.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop :document.body.scrollTop);\
  2464.  }\
  2465.  else\
  2466.  {\
  2467.   return null;\
  2468.  }\
  2469. }\
  2470. }\
  2471. function tooltip%d_show(){\
  2472. if(tooltip%d_flipflop == 0){\
  2473.  tooltip%d_obj.style.display = \"block\";\
  2474.  tooltip%d_flipflop = 1;\
  2475. }\
  2476. else\
  2477. {\
  2478.  tooltip%d_flipflop = 0;\
  2479.  tooltip%d_obj.style.display = \"none\";\
  2480. }\
  2481. };\n</script>\n<!-- end command intooltip %d -->\n",canvas_root_id,xsize,ysize,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,tooltip_text,canvas_root_id,bgcolor,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id);
  2482.  
  2483. }
  2484.  
  2485. void add_js_arc(FILE *js_include_file,int canvas_root_id,int num,int line_width,char *stroke_color,double stroke_opacity,char *fill_color,double fill_opacity,int use_dashed,int dashtype0,int dashtype1){
  2486. fprintf(js_include_file,"\n<!-- begin userdraw \"arc\" on final canvas -->\n\
  2487. var canvas_rect;\
  2488. function user_draw(evt){\
  2489. var num = %d;\
  2490. var x,xc,x1,x2,y,yc,y1,y2;var lu = userdraw_x.length;\
  2491. if( num == 1 && lu == 3 ){ userdraw_x = [];userdraw_y = [];userdraw_radius = [];};\
  2492. if(evt.which == 1 || evt.identifier == 0 ){\
  2493.  var mouse = dragstuff.getMouse(evt,canvas_userdraw);\
  2494.  x = mouse.x;\
  2495.  y = mouse.y;\
  2496.  if( use_snap_to_points != 0 ){\
  2497.   var xy = new Array(2);\
  2498.   if( use_snap_to_points == 1 ){\
  2499.    xy = snap_to_points(x,y);\
  2500.   }\
  2501.   else\
  2502.   {\
  2503.    xy = snap_to_fun(x,y);\
  2504.   };\
  2505.   x = xy[0];y = xy[1];\
  2506.  }\
  2507.  else\
  2508.  {\
  2509.   if( x_use_snap_to_grid == 1 ){x = snap_to_x(x);};\
  2510.   if( y_use_snap_to_grid == 1 ){y = snap_to_y(y);};\
  2511.  };\
  2512.  if(num == 1 && lu == 3){userdraw_x = [];userdraw_y = [];userdraw_radius = [];};\
  2513.  lu = userdraw_x.push(x);userdraw_y.push(y);\
  2514.  if( lu != 0 && lu%%3 == 0){\
  2515.   context_userdraw.clearRect(0,0,xsize,ysize);\
  2516.   userdraw_radius = [];\
  2517.   for(var p = 0 ; p < lu; p = p + 3){\
  2518.     xc = userdraw_x[p];\
  2519.     yc = userdraw_y[p];\
  2520.     x1 = userdraw_x[p+1];\
  2521.     x2 = userdraw_x[p+2];\
  2522.     y1 = userdraw_y[p+1];\
  2523.     y2 = userdraw_y[p+2];\
  2524.     draw_userarc(context_userdraw,xc,yc,x1,y1,x2,y2,%d,\"%s\",%.2f,\"%s\",%.2f,%d,%d,%d);\
  2525.   };\
  2526.  };\
  2527. }\
  2528. else\
  2529. {\
  2530.  if( confirm(\"remove drawing ?\") ){\
  2531.   context_userdraw.clearRect(0,0,xsize,ysize);userdraw_x = [];userdraw_y = [];userdraw_radius = [];return;\
  2532.  };\
  2533. };\
  2534. };\
  2535. function user_drag(evt){ \
  2536. var lu = userdraw_x.length;\
  2537. if( (lu+1)%%3 == 0) {\
  2538.  var mouse = dragstuff.getMouse(evt,canvas_userdraw);\
  2539.  var x2 = mouse.x;\
  2540.  var y2 = mouse.y;\
  2541.  var xc = userdraw_x[lu-2];\
  2542.  var yc = userdraw_y[lu-2];\
  2543.  var x1 = userdraw_x[lu-1];\
  2544.  var y1 = userdraw_y[lu-1];\
  2545.  context_userdraw.clearRect(0,0,xsize,ysize);\
  2546.  draw_userarc(context_userdraw,xc,yc,x1,y1,x2,y2,1,\"255,0,0\",0.6,\"255,255,0\",0.4,0,2,2);\
  2547. };\
  2548. return;\
  2549. };\
  2550. var draw_userarc = function(ctx,xc,yc,x1,y1,x2,y2,line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_dashed,dashtype0,dashtype1){\
  2551. ctx.save();\
  2552. if( use_dashed == 1){if(ctx.setLineDash){ctx.setLineDash([dashtype0,dashtype1]);}else{if(ctx.mozDash){ ctx.mozDash = [dashtype0,dashtype1];};};};\
  2553. ctx.lineWidth = line_width;\
  2554. ctx.strokeStyle =  \"rgba(\"+stroke_color+\",\"+stroke_opacity+\")\";\
  2555. ctx.fillStyle = \"rgba(\"+fill_color+\",\"+fill_opacity+\")\";\
  2556. var alpha = find_angle(xc,yc,x2,y2);\
  2557. if( %d == 1 ){userdraw_radius[0] = alpha;ctx.clearRect(0,0,xsize,ysize);}else{userdraw_radius.push(alpha);};\
  2558. var r = Math.sqrt(Math.pow(xc-x2,2)+Math.pow(yc-y2,2));\
  2559. var start = find_angle(xc,yc,x1,y1);\
  2560. ctx.translate(xc,yc);\
  2561. ctx.rotate(start);\
  2562. ctx.beginPath();\
  2563. ctx.arc(0,0,r,0,alpha,false);\
  2564. ctx.lineTo(0,0);\
  2565. ctx.closePath();\
  2566. ctx.fill();\
  2567. ctx.stroke();\
  2568. ctx.restore();\
  2569. };",num,line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_dashed,dashtype0,dashtype1,num);
  2570. }
  2571.  
  2572. void add_js_text(FILE *js_include_file,int canvas_root_id,int font_size,char *font_family,char *font_color,double stroke_opacity){
  2573. fprintf(js_include_file,"\n<!-- begin command userdraw text -->\n\
  2574. canvas_div.addEventListener(\"keydown\",function(e){ e.preventDefault();user_text(e);},false);\
  2575. context_userdraw = canvas_userdraw.getContext(\"2d\");\
  2576. var font_color = \"%s\";\
  2577. var font_opacity = %f;\
  2578. var mask_opacity = 0.5*font_opacity;\
  2579. var font_size = %d;\
  2580. var font_family = \"%s\";\
  2581. context_userdraw.fillStyle = \"rgba(\"+font_color+\",\"+font_opacity+\")\";\
  2582. context_userdraw.font = font_family;\
  2583. context_userdraw.save();\
  2584. var tmp_font_size = parseInt(context_userdraw.measureText(\"m\").width);\
  2585. if( font_size > tmp_font_size ){context_userdraw.font = font_size+\"px Ariel\";};\
  2586. var userdraw_text = new Array();\
  2587. var temp_userdraw_txt=\"\";\
  2588. var x_txt = 0;\
  2589. var y_txt = 0;\
  2590. function user_draw(evt){\
  2591. var mouse = dragstuff.getMouse(evt,canvas_userdraw);\
  2592. x_txt = mouse.x;\
  2593. y_txt = mouse.y;\
  2594. if( use_snap_to_points != 0 ){\
  2595.  var xy = new Array(2);\
  2596.  if( use_snap_to_points == 1 ){\
  2597.   xy = snap_to_points(x_txt,y_txt);\
  2598.  }\
  2599.  else\
  2600.  {\
  2601.   xy = snap_to_fun(x_txt,y_txt);\
  2602.  };\
  2603.  x_txt = xy[0];y_txt = xy[1];\
  2604. }\
  2605. else\
  2606. {\
  2607.  if( x_use_snap_to_grid == 1 ){\
  2608.   x_txt = snap_to_x(x_txt);\
  2609.  };\
  2610.  if( y_use_snap_to_grid == 1 ){\
  2611.   y_txt = snap_to_y(y_txt);\
  2612.  };\
  2613. };\
  2614. return;\
  2615. };\
  2616. function user_drag(evt){return;};\
  2617. function redraw_all_user_text(){\
  2618. var len = userdraw_x.length;\
  2619. context_userdraw.clearRect(0,0,xsize,ysize);\
  2620. for(var p = 0 ; p < len ; p++){\
  2621.  context_userdraw.fillText(userdraw_text[p],userdraw_x[p],userdraw_y[p]);\
  2622. };\
  2623. };\
  2624. function user_text(evt){\
  2625. var kc = evt.keyCode;\
  2626. if( kc== 8 || kc == 27 || kc == 46 ){\
  2627.  var len = userdraw_x.length;\
  2628.  for( var p=0 ; p < len ; p++){\
  2629.   var tmp = userdraw_text[p];\
  2630.   var w = context_userdraw.measureText(tmp).width;\
  2631.   if( y_txt <= userdraw_y[p] && y_txt > userdraw_y[p] - font_size){\
  2632.    if( x_txt < userdraw_x[p] + w && x_txt > userdraw_x[p] ){\
  2633.     if (confirm(\"delete : \"+tmp+\"?\")){\
  2634.      userdraw_text.splice(p,1);\
  2635.      userdraw_x.splice(p,1);\
  2636.      userdraw_y.splice(p,1);\
  2637.      temp_userdraw_txt = \"\";\
  2638.      redraw_all_user_text();\
  2639.      return;\
  2640.     };\
  2641.    };\
  2642.   };\
  2643.  };\
  2644. }\
  2645. else\
  2646. {\
  2647.  if( kc < 126 && kc > 40 ){\
  2648.   temp_userdraw_txt=temp_userdraw_txt+String.fromCharCode(kc);\
  2649.   context_userdraw.save();\
  2650.   context_userdraw.fillStyle = \"rgba(\"+font_color+\",\"+mask_opacity+\")\";\
  2651.   context_userdraw.fillText(temp_userdraw_txt,x_txt,y_txt);\
  2652.   context_userdraw.restore();\
  2653.  }\
  2654.  else\
  2655.  {\
  2656.   if(kc == 13 ){\
  2657.    w = context_userdraw.measureText(temp_userdraw_txt).width;\
  2658.    if(w < 1){ return;};\
  2659.    userdraw_x.push(x_txt);\
  2660.    userdraw_y.push(y_txt);\
  2661.    userdraw_text.push(temp_userdraw_txt);\
  2662.    redraw_all_user_text();\
  2663.    temp_userdraw_txt=\"\";\
  2664.    return;\
  2665.   };\
  2666.  };\
  2667. };\
  2668. };",font_color,stroke_opacity,font_size,font_family);
  2669.  
  2670. }
  2671.  
  2672. /*
  2673.  
  2674. type = 0 : x-values only [command mousex]
  2675. type = 1 : y-values only [command mousey]
  2676. type = 2 : (x:y)         [command mouse]
  2677. type = 3 : degree        [command mouse_degree]
  2678. type = 4 : radian
  2679. type = 5 : radius
  2680.  
  2681.   var mouse = dragstuff.getMouse(evt,canvas_div);\
  2682.   var x = evt.clientX - mouse_canvas_rect.left;\
  2683.   var y = evt.clientY - mouse_canvas_rect.top;\
  2684.  
  2685. */
  2686. void add_js_mouse(FILE *js_include_file,int canvas_cnt,int canvas_root_id,int precision,char *stroke_color,int font_size,double stroke_opacity,int type){
  2687. fprintf(js_include_file,"\n<!-- begin command mouse on mouse canvas -->\n\
  2688. function use_mouse_coordinates(){\
  2689. var display_type = %d;\
  2690. var canvas_type = %d;\
  2691. var mouse_canvas = create_canvas%d(canvas_type,xsize,ysize);\
  2692. var mouse_context = mouse_canvas.getContext(\"2d\");\
  2693. mouse_canvas.addEventListener(\"mousemove\",show_coordinate%d,false);\
  2694. mouse_canvas.addEventListener(\"touchmove\", function(e){ e.preventDefault();show_coordinate%d(e.changedTouches[0]);},false);\
  2695. var prec = Math.log(%d)/(Math.log(10));\
  2696. function show_coordinate%d(evt){\
  2697.  var mouse = dragstuff.getMouse(evt,mouse_canvas);\
  2698.  var x = mouse.x;\
  2699.  var y = mouse.y;\
  2700.  var m_data = \"\";\
  2701.  switch(display_type){\
  2702.   case 0: m_data = \" \"+(px2x(x)).toFixed(prec)+\" \"+unit_x;break;\
  2703.   case 1: m_data = \" \"+(px2y(y)).toFixed(prec)+\" \"+unit_y;break;\
  2704.   case 2: m_data = \"(\"+(px2x(x)).toFixed(prec)+\":\"+(px2y(y)).toFixed(prec)+\")\";break;\
  2705.   case 3: if(userdraw_radius[0]){ m_data = \" \"+( ( userdraw_radius[0])/(Math.PI/180) ).toFixed(prec)+\" \\u00B0 \";};break;\
  2706.   case 4: if(userdraw_radius[0]){ m_data = \" \"+(userdraw_radius[0]).toFixed(prec)+\" rad \";};break;\
  2707.   case 5: if( userdraw_x.length > 0 ){var L = userdraw_x.length;m_data = \" R = \"+((xmax - xmin)*(distance(x,y,userdraw_x[L-1],userdraw_y[L-1]))/xsize).toFixed(prec)+\" \"+unit_x;};break;\
  2708.   default:break;\
  2709.  };\
  2710.  var s = parseInt(0.8*%d*(m_data.toString()).length);\
  2711.  mouse_context.font = \"%dpx Ariel\";\
  2712.  mouse_context.fillStyle = \"rgba(%s,%f)\";\
  2713.  mouse_context.clearRect(0,0,s,1.2*%d);\
  2714.  mouse_context.fillText(m_data,0,%d);\
  2715. };\
  2716. };",type,MOUSE_CANVAS,canvas_root_id,canvas_root_id,canvas_root_id,precision,canvas_root_id,font_size,font_size,stroke_color,stroke_opacity,font_size,font_size);
  2717. }
  2718. /* to avoid easy js-code injection...but is it a real problem ? */
  2719. void add_safe_eval(FILE *js_include_file){
  2720. fprintf(js_include_file," \nfunction safe_eval(exp){\
  2721. exp = exp.replace(/pi/g,'3.14159');\
  2722. if(exp.indexOf('^') != -1){\
  2723.  exp = exp.replace(/[a-zA-Z]/g,' ');\
  2724.  exp = exp.replace(/\\*10\\^-/g,'e-');\
  2725.  exp = exp.replace(/\\*10\\^/g,'e+');\
  2726.  exp = exp.replace(/10\\^-/g,'1e-');exp = exp.replace(/10\\^/g,'1e+');\
  2727.  exp = eval(exp);\
  2728.  if(isNaN(exp)){alert(\"invalid input\\ntry just a real number \\ne.g. no calculations...\");return null;}\
  2729.  return exp;\
  2730. };\
  2731. var reg = /(?:[a-z$_][a-z0-9$_]*)|(?:[;={}\\[\\]\"'!&<>^\\\\?:])/ig;\
  2732. var valid = true;\
  2733. exp = exp.replace(reg,function($0){\
  2734.  if(Math.hasOwnProperty($0)){\
  2735.   return \"Math.\"+$0;\
  2736.  }\
  2737.  else\
  2738.  {\
  2739.   valid = false;\
  2740.  }\
  2741. }\
  2742. );\
  2743. if( !valid ){\
  2744.  alert(\"hmmm \"+exp+\" ?\"); exp = null;\
  2745. }\
  2746. else\
  2747. {\
  2748.  try{ exp = eval(exp); } catch(e){alert(\"Invalid arithmetic expression\"); exp = null;};\
  2749. };\
  2750. return exp;\
  2751. };");
  2752. }
  2753.  
  2754. /*
  2755. add display of slider value in mouse context
  2756. use_slider_display = 1 : x/y -values
  2757. use_slider_display = 10 : x-values only
  2758. use_slider_display = 11 : y-values only
  2759.  
  2760. use_slider_display = 2 : angle in degrees
  2761. use_slider_display = 3 : angle in radians
  2762. */
  2763. void add_slider_display(FILE *js_include_file,int canvas_root_id,int precision,int font_size,char *font_color,double stroke_opacity){
  2764. fprintf(js_include_file,"<!-- begin add_slider_display -->\n\
  2765. function show_slider_value(value,use_slider_display){\
  2766. var current_canvas = create_canvas%d(%d,xsize,ysize);\
  2767. var current_context = current_canvas.getContext(\"2d\");\
  2768. current_context.clearRect(0,0,xsize,ysize);\
  2769. var prec = Math.log(%d)/(Math.log(10));\
  2770. var string;\
  2771. switch(use_slider_display){\
  2772.  case 1: string = \" \"+value[0].toFixed(prec)+\" \"+unit_x+\":\"+value[1].toFixed(prec)+\" \"+unit_y; break;\
  2773.  case 10: string = \" \"+value[0].toFixed(prec)+\" \"+unit_x; break;\
  2774.  case 11: string = \" \"+value[1].toFixed(prec)+\" \"+unit_y; break;\
  2775.  case 2: value[1] = value[1]*180/Math.PI;string = \" \"+value[1].toFixed(prec)+\"\\u00B0\";break;\
  2776.  case 3: string = \" \"+value[1].toFixed(prec)+\" rad\";break;\
  2777.  default: string = \" \";break;\
  2778. };\
  2779. var s = parseInt(1.2*%d*(string).length);\
  2780. current_context.font = \"%dpx Ariel\";\
  2781. current_context.strokeStyle = \"rgba(%s,%.2f)\";\
  2782. current_context.clearRect(0,0,s,1.2*%d);\
  2783. current_context.fillText(string,0,%d);\
  2784. };\n",canvas_root_id,MOUSE_CANVAS,precision,font_size,font_size,font_color,stroke_opacity,font_size,font_size);
  2785. }
  2786. /*
  2787. add slider
  2788. return value is array : value[0] is the actual value between value_1 and value_2
  2789.  
  2790.  var x_px = evt.clientX\
  2791. */
  2792. void add_slider(FILE *js_include_file,int canvas_root_id,double v1,double v2,int width,int height,int type,char *label,int slider_cnt,char *stroke_color,char *fill_color,int line_width,double opacity,char *font_family,char *font_color,int use_slider_display){
  2793. fprintf(js_include_file,"\n<!-- begin add_slider no. %d -->\n\
  2794. function add_slider_%d(){\
  2795. if( wims_status == \"done\" ){return;};\
  2796. var tooltip_div = document.getElementById(\"tooltip_placeholder_div%d\");\
  2797. var slider_type = %d;\
  2798. var span = document.createElement(\"span\");\
  2799. span.setAttribute(\"style\",\"font:%s;color:%s\");\
  2800. var title = document.createTextNode(\" %s \");\
  2801. var br = document.createElement(\"br\");\
  2802. span.appendChild(title);\
  2803. span.appendChild(br);\
  2804. tooltip_div.appendChild(span);\
  2805. var slider_fillcolor = \"%s\";\
  2806. var slider_strokecolor = \"%s\";\
  2807. var slider_linewidth = \"%d\";\
  2808. var slider_canvas = document.createElement(\"canvas\");\
  2809. slider_canvas.id = \"slider_canvas%d\";\
  2810. tooltip_div.appendChild(slider_canvas);\
  2811. br = document.createElement(\"br\");\
  2812. tooltip_div.appendChild(br);\
  2813. var slider_width = %d;\
  2814. var slider_height = %d;\
  2815. var slider_center = %d;\
  2816. var slider_radius = 2*slider_linewidth;\
  2817. var slider_opacity = %f;\
  2818. slider_canvas.width = slider_width;\
  2819. slider_canvas.height = slider_height;\
  2820. var slider_ctx = slider_canvas.getContext(\"2d\");\
  2821. slider_ctx.font = \"%s\";\
  2822. slider_ctx.strokeStyle = \"rgba(\"+slider_strokecolor+\",\"+slider_opacity+\")\";\
  2823. slider_ctx.fillStyle = \"rgba(\"+slider_fillcolor+\",\"+slider_opacity+\")\";\
  2824. slider_ctx.lineWidth = slider_linewidth;\
  2825. slider_ctx.beginPath();\
  2826. slider_ctx.arc(10,slider_center,slider_radius,0,2*Math.PI,false);\
  2827. slider_ctx.moveTo(10,slider_center);\
  2828. slider_ctx.lineTo(slider_width-10,slider_center);\
  2829. slider_ctx.rect(0,0,slider_width,slider_height);\
  2830. slider_ctx.closePath();\
  2831. slider_ctx.fill();\
  2832. slider_ctx.stroke();\
  2833. slider_canvas.addEventListener(\"mousemove\",slider_%d,false);\
  2834. slider_canvas.addEventListener(\"touchmove\", function(e){ e.preventDefault();slider_%d(e.changedTouches[0]);},false);\
  2835. function slider_%d(evt){\
  2836. var value_1 = %f;\
  2837. var value_2 = %f;\
  2838. var canvas_rect = (slider_canvas).getBoundingClientRect();\
  2839. slider_ctx.clearRect(0,0,slider_width,slider_height);\
  2840. var x_px = evt.clientX - canvas_rect.left;\
  2841. var x;var y;\
  2842. if( slider_type == 1 ){\
  2843.  x = x_px*(value_2 - value_1)/slider_width + value_1;\
  2844.  y = 0;\
  2845. }else{\
  2846.  y = x_px*(value_2 - value_1)/slider_width + value_1;\
  2847.  x = 0;\
  2848. };\
  2849. slider_ctx.beginPath();\
  2850. slider_ctx.arc(x_px,slider_center,slider_radius,0,2*Math.PI,false);\
  2851. slider_ctx.moveTo(10,slider_center);\
  2852. slider_ctx.lineTo(slider_width-10,slider_center);\
  2853. slider_ctx.rect(0,0,slider_width,slider_height);\
  2854. slider_ctx.closePath();\
  2855. slider_ctx.fill();\
  2856. slider_ctx.stroke();\
  2857. dragstuff.Slide( [x,y] , %d );\
  2858. if(%d != 0 ){show_slider_value([x,y],%d);};\
  2859. return;\
  2860. };\
  2861. };\
  2862. add_slider_%d();\n",slider_cnt,slider_cnt,canvas_root_id,type,font_family,font_color,label,fill_color,stroke_color,line_width,slider_cnt,width,height,(int)(0.5*height),opacity,font_family,slider_cnt,slider_cnt,slider_cnt,v1,v2,slider_cnt,use_slider_display,use_slider_display,slider_cnt);
  2863. }
  2864.  
  2865.  
  2866. /*
  2867. add xyslider
  2868.  return value is array : value[0] is the actual x-value between value_1 and value_2, value[1] is y-value between value_1 and value_2
  2869. */
  2870. void add_xyslider(FILE *js_include_file, int canvas_root_id,double v1,double v2,int width,int height,int type,char *label,int slider_cnt,char *stroke_color,char *fill_color,int line_width,double opacity,char *font_family,char *font_color,int use_slider_display){
  2871. fprintf(js_include_file,"\n<!-- begin add_slider no. %d -->\n\
  2872. function add_slider_%d(){\
  2873. if( wims_status == \"done\" ){return;};\
  2874. var tooltip_div = document.getElementById(\"tooltip_placeholder_div%d\");\
  2875. var slider_type = %d;\
  2876. var span = document.createElement(\"span\");\
  2877. span.setAttribute(\"style\",\"font:%s;color:%s\");\
  2878. var title = document.createTextNode(\" %s \");\
  2879. var br = document.createElement(\"br\");\
  2880. span.appendChild(title);\
  2881. span.appendChild(br);\
  2882. tooltip_div.appendChild(span);\
  2883. var slider_fillcolor = \"%s\";\
  2884. var slider_click = 0;\
  2885. var slider_strokecolor = \"%s\";\
  2886. var slider_linewidth = \"%d\";\
  2887. var slider_canvas = document.createElement(\"canvas\");\
  2888. slider_canvas.id = \"slider_canvas%d\";\
  2889. tooltip_div.appendChild(slider_canvas);\
  2890. br = document.createElement(\"br\");\
  2891. tooltip_div.appendChild(br);\
  2892. var slider_width = %d;\
  2893. var slider_height = %d;\
  2894. var slider_center = %d;\
  2895. var slider_radius = 4*slider_linewidth;\
  2896. var slider_opacity = %f;\
  2897. slider_canvas.width = slider_width;\
  2898. slider_canvas.height = slider_height;\
  2899. var slider_ctx = slider_canvas.getContext(\"2d\");\
  2900. slider_ctx.font = \"%s\";\
  2901. slider_ctx.strokeStyle = \"rgba(\"+slider_strokecolor+\",\"+slider_opacity+\")\";\
  2902. slider_ctx.fillStyle = \"rgba(\"+slider_fillcolor+\",\"+slider_opacity+\")\";\
  2903. slider_ctx.lineWidth = slider_linewidth;\
  2904. slider_ctx.beginPath();\
  2905. slider_ctx.arc(10,slider_center,slider_radius,0,2*Math.PI,false);\
  2906. slider_ctx.fill();\
  2907. slider_ctx.closePath();\
  2908. slider_ctx.rect(0,0,slider_width,slider_height);\
  2909. slider_ctx.stroke();\
  2910. slider_canvas.addEventListener(\"mousemove\",sliderdrag_%d,false);\
  2911. slider_canvas.addEventListener(\"mousedown\",sliderclick_%d,false);\
  2912. slider_canvas.addEventListener(\"touchmove\",function(e){ e.preventDefault();sliderdrag_%d(e.changedTouches[0]);},false);\
  2913. slider_canvas.addEventListener(\"touchstart\", function(e){ e.preventDefault();sliderclick_%d(e.changedTouches[0]);},false);\
  2914. var canvas_rect = (slider_canvas).getBoundingClientRect();\
  2915. function sliderdrag_%d(evt){\
  2916. if(slider_click == 1){\
  2917.  var value_1 = %f;\
  2918.  var value_2 = %f;\
  2919.  var canvas_rect = (slider_canvas).getBoundingClientRect();\
  2920.  slider_ctx.clearRect(0,0,slider_width,slider_height);\
  2921.  var x_px = evt.clientX - canvas_rect.left;\
  2922.  var y_px = evt.clientY - canvas_rect.top;\
  2923.  slider_ctx.clearRect(0,0,slider_width,slider_height);\
  2924.  var x = x_px*(value_2 - value_1)/slider_width + value_1;\
  2925.  var y = y_px*(value_2 - value_1)/slider_height + value_1;\
  2926.  x = parseFloat(eval(slider_function%d.x));\
  2927.  y = parseFloat(eval(slider_function%d.y));\
  2928.  slider_ctx.beginPath();\
  2929.  slider_ctx.arc(x_px,y_px,slider_radius,0,2*Math.PI,false);\
  2930.  slider_ctx.fill();\
  2931.  slider_ctx.rect(0,0,slider_width,slider_height);\
  2932.  slider_ctx.closePath();\
  2933.  slider_ctx.stroke();\
  2934.  dragstuff.Slide( [x,y] , %d );\
  2935.  if(%d != 0 ){show_slider_value([x,y],%d);}\
  2936. };\
  2937. };\
  2938. function sliderclick_%d(evt){\
  2939.  if(slider_click == 1){slider_click = 0;}else{slider_click = 1;};\
  2940. };\
  2941. };\n\
  2942. add_slider_%d();",slider_cnt,slider_cnt,canvas_root_id,type,font_family,font_color,label,fill_color,stroke_color,line_width,canvas_root_id,width,height,(int)(0.5*height),opacity,font_family,slider_cnt,slider_cnt,slider_cnt,slider_cnt,slider_cnt,v1,v2,slider_cnt,slider_cnt,slider_cnt,use_slider_display,slider_cnt,slider_cnt,slider_cnt);
  2943. }
  2944.  
  2945.  
  2946. /*
  2947. adds inputfield for x-value: returns the js-calculated y-value after click on 'OK' button
  2948. draws a non-configurable crosshair on this calculated location
  2949. */
  2950. void add_calc_y(FILE *js_include_file,int canvas_root_id,char *jsmath,int font_size,char *input_style){
  2951. fprintf(js_include_file,"\n<!-- begin add_calc_y -->\n\
  2952. use_jsmath=1;\
  2953. function add_calc_y(){\
  2954. if( wims_status == \"done\" ){return;};\
  2955. var fun = to_js_math(\"%s\");if(fun == null){return;};\
  2956. function eval_jsmath(x){return parseFloat(eval(fun));};\
  2957. var tooltip_div = document.getElementById(\"tooltip_placeholder_div%d\");\
  2958. var calc_div = document.createElement('div');\
  2959. calc_div.id = \"calc_div\";\
  2960. tooltip_div.appendChild(calc_div);\
  2961. var label_x = \"x\";var label_y = \"y\";\
  2962. if( typeof(xaxislabel) !== 'undefined' ){label_x = xaxislabel;}\
  2963. if( typeof(yaxislabel) !== 'undefined' ){label_y = yaxislabel;}\
  2964. calc_div.innerHTML=\"<br /><span style='font-style:italic;font-size:%dpx'>\"+label_x+\" : <input type='text' size='4' value='' id='calc_input_x' style='%s' />&nbsp;\"+ label_y+\" : <input type='text' size='5' value='' id='calc_output_y' style='%s' readonly /><input id='calc_button' type='button' value='OK' onclick=''  style='color:red;background-color:lightblue;' /></span> \";\
  2965. var calc_button = document.getElementById(\"calc_button\");\
  2966. calc_button.addEventListener(\"mousedown\",show_it,false);\
  2967. calc_button.addEventListener(\"touchstart\", function(e){ e.preventDefault();show_it(e.changedTouches[0]);},false);\
  2968. function show_it(){\
  2969.  var x_value=document.getElementById(\"calc_input_x\").value;\
  2970.  var y_value = eval_jsmath(x_value);\
  2971.  document.getElementById(\"calc_output_y\").value = y_value;\
  2972.  if(isNaN(y_value)){return;};\
  2973.  var canvas = create_canvas%d(123,xsize,ysize);\
  2974.  var ctx = canvas.getContext(\"2d\");\
  2975.  draw_crosshairs(ctx,[x2px(x_value)],[y2px(y_value)],1,5,\"#000000\",1,0,0,0,[0,0]);return;\
  2976. };\
  2977. };\
  2978. ;add_calc_y();",jsmath,canvas_root_id,font_size,input_style,input_style,canvas_root_id);
  2979. }
  2980. /*
  2981.  x-value of the mouse will be used to calculate via javascript the corresponding y-value using the verbatim js-math function
  2982.  a configurable crosshair and vertical/horizontal crosshair lines will be drawn
  2983.  function is called "use_mouse_coordinates() and thus can not be combined with command 'mouse'
  2984. */
  2985. void add_trace_js_mouse(FILE *js_include_file,int canvas_cnt,int canvas_root_id,char *stroke_color,char *jsmath,int font_size,double stroke_opacity,int line_width,int crosshair_size,char *input_style){
  2986. fprintf(js_include_file,"\n<!-- begin command add_trace_jsmath  trace_canvas -->\n\
  2987. use_jsmath=1;\
  2988. function use_trace_jsmath(){\
  2989. if( wims_status == \"done\" ){return;};\
  2990. var label_x = \"x\";var label_y = \"y\";\
  2991. if( typeof(xaxislabel) !== 'undefined' ){label_x = xaxislabel;}\
  2992. if( typeof(yaxislabel) !== 'undefined' ){label_y = yaxislabel;}\
  2993. var trace_canvas = create_canvas%d(%d,xsize,ysize);\
  2994. var trace_context = trace_canvas.getContext(\"2d\");\
  2995. var tooltip_div = document.getElementById(\"tooltip_placeholder_div%d\");\
  2996. var trace_div = document.createElement('div');\
  2997. trace_div.id = \"trace_div\";\
  2998. tooltip_div.appendChild(trace_div);\
  2999. trace_div.innerHTML = \"<br /><span style='font-style:italic;font-size:%dpx'>\"+label_x+\" : <input type='text' size='4' value='' id='trace_input_x' style='%s' />\"+label_y+\" : <input type='text' size='5' value='' id='trace_input_y' style='%s' readonly /></span> \";\
  3000. canvas_div.addEventListener(\"mousemove\",trace,false);\
  3001. canvas_div.addEventListener(\"touchmove\",function(e){ e.preventDefault();trace(e.changedTouches[0]);},false);\
  3002. var fun = to_js_math(\"%s\");if(fun == null){return;};\
  3003. function eval_jsmath(x){return parseFloat(eval(fun));};\
  3004. function trace(evt){\
  3005.  var mouse = dragstuff.getMouse(evt,trace_canvas);\
  3006.  var x_px = mouse.x;\
  3007.  var x = px2x(x_px);\
  3008.  var y = eval_jsmath(x);\
  3009.  if(isNaN(y)){return;};\
  3010.  var y_px = y2px(y);\
  3011.  trace_context.clearRect(0,0,xsize,ysize);\
  3012.  draw_crosshairs(trace_context,[x_px],[y_px],%d,%d,\"%s\",%f,0,0,0,[0,0]);\
  3013.  document.getElementById(\"trace_input_x\").value = x;\
  3014.  document.getElementById(\"trace_input_y\").value = y;\
  3015. };\
  3016. return;\
  3017. };use_trace_jsmath();",canvas_root_id,canvas_cnt,canvas_root_id,font_size,input_style,input_style,jsmath,line_width,crosshair_size,stroke_color,stroke_opacity);
  3018. }
  3019.  
  3020. /*
  3021. add a table with 2 textarea's labeled 'x' 'y' ( or 'xlabel' 'ylabel' if defined)
  3022. add two buttons: OK and NOK (OK draws; NOK will delete last item pair from userdraw_x / userdraw_y array's
  3023. */
  3024. void add_textarea_xy(FILE *js_include_file, int canvas_root_id, char *input_style){
  3025. fprintf(js_include_file,"\n<!-- begin add_textarea_xy -->\n\
  3026. function add_textarea_xy(){\
  3027. if( wims_status == \"done\" ){return;};\
  3028. var tooltip_div = document.getElementById(\"tooltip_placeholder_div%d\");\
  3029. var textarea_div = document.createElement('div');\
  3030. textarea_div.id = \"textarea_div\";\
  3031. tooltip_div.appendChild(textarea_div);\
  3032. var label_x = \"x\";var label_y = \"y\";\
  3033. if( typeof(xaxislabel) !== 'undefined' ){label_x = xaxislabel;}\
  3034. if( typeof(yaxislabel) !== 'undefined' ){label_y = yaxislabel;}\
  3035. textarea_div.innerHTML=\"\
  3036. <table style=\'border:1px solid black;background-color:#ffffa0\' >\
  3037. <tr>\
  3038. <td><input id='textarea_ok_button' type='button' value='OK' onclick='' style='color:red;background-color:lightblue;'/></td>\
  3039. <td><input id='textarea_nok_button' type='button' value='NOK' onclick='' style='color:blue;background-color:red;'/></td>\
  3040. </tr>\
  3041. <tr>\
  3042. <td><em>\"+label_x+\"</em></td>\
  3043. <td><em>\"+label_y+\"</em></td>\
  3044. </tr>\
  3045. <tr>\
  3046. <td><textarea rows='5' cols='2' id='userinput_x' style='%s' ></textarea></td>\
  3047. <td><textarea rows='5' cols='2' id='userinput_y' style='%s' ></textarea></td>\
  3048. </tr>\
  3049. </table>\";\
  3050. var textarea_ok_button = document.getElementById(\"textarea_ok_button\");\
  3051. var textarea_nok_button = document.getElementById(\"textarea_nok_button\");\
  3052. textarea_ok_button.addEventListener(\"mousedown\",function(e){user_redraw(1);return;},false);\
  3053. textarea_nok_button.addEventListener(\"mousedown\",function(e){user_redraw(-1);return;},false);\
  3054. return;\
  3055. };add_textarea_xy();",canvas_root_id,input_style,input_style);
  3056. }
  3057.  
  3058. /*
  3059.  
  3060. */
  3061. void add_setlimits(FILE *js_include_file, int canvas_root_id,int font_size,char *input_style){
  3062. fprintf(js_include_file,"\n<!-- begin add_setlimits -->\n\
  3063. use_pan_and_zoom = 1;\
  3064. function use_setlimits(){\
  3065. if( wims_status == \"done\" ){return;};\
  3066. var label_x = \"x\";var label_y = \"y\";\
  3067. if( typeof(xaxislabel) !== 'undefined' ){label_x = xaxislabel;}\
  3068. if( typeof(yaxislabel) !== 'undefined' ){label_y = yaxislabel;}\
  3069. var tooltip_div = document.getElementById(\"tooltip_placeholder_div%d\");\
  3070. var setlim_div = document.createElement('div');\
  3071. setlim_div.id = \"setlim_div\";\
  3072. tooltip_div.appendChild(setlim_div);\
  3073. setlim_div.innerHTML=\"<br /><span style='font-style:italic;font-size:%dpx'>\"+label_x+\"min = <input type='text' size='4' value='\"+xmin+\"' id='userinput_xmin' style='%s' /> \"+label_x+\"max = <input type='text' size='4' value='\"+xmax+\"' id='userinput_xmax' style='%s' /><br />\"+label_y+\"min = <input type='text' size='4' value='\"+ymin+\"' id='userinput_ymin' style='%s' /> \"+label_y+\"max = <input type='text' size='4' value='\"+ymax+\"' id='userinput_ymax' style='%s' /><br /><input id='set_limits' type='button' value='OK' onclick='' style='color:red;background-color:lightblue;' />\";\
  3074. var setlimit_button = document.getElementById(\"set_limits\");\
  3075. function set_limits(e){\
  3076. xmin = safe_eval(document.getElementById('userinput_xmin').value);\
  3077. xmax = safe_eval(document.getElementById('userinput_xmax').value);\
  3078. ymin = safe_eval(document.getElementById('userinput_ymin').value);\
  3079. ymax = safe_eval(document.getElementById('userinput_ymax').value);\
  3080. if(xmin > xmax || ymin > ymax){alert(\"your limits are not correct...\");return;}\
  3081. try{start_canvas%d(1234)}catch(e){};try{dragstuff.Zoom(xmin,xmax,ymin,ymax)}catch(e){};return;};\
  3082. setlimit_button.addEventListener(\"mousedown\",function(e){set_limits();},false);\
  3083. };use_setlimits();",canvas_root_id,font_size,input_style,input_style,input_style,input_style,canvas_root_id);
  3084. }
  3085.  
  3086.  
  3087. void add_rawmath(FILE *js_include_file){
  3088. fprintf(js_include_file,"\n<!-- begin add_rawmath() -->\n\
  3089. function rawmath(i){\
  3090. i=i.toLowerCase();\
  3091. i=i.replace(/\\ /g,\"\");i=i.replace(/\\*\\*/g,\"^\");\
  3092. if(i.indexOf(\"e+\")!=-1){i=i.replace(\"e+\",\"*10^\");};\
  3093. if(i.indexOf(\"e-\")!=-1){i=i.replace(\"e-\",\"*10^-\");};\
  3094. i=i.replace(/\\*\\*/g,\"*\");\
  3095. if(i.charAt(0)==\"*\"){i=i.substring(1,i.length);};\
  3096. var fun=[\"asin\",\"acos\",\"atan\",\"sin\",\"cos\",\"tan\",\"log\",\"ln\",\"pi\",\"e\",\"x\",\"y\"];\
  3097. var cons=[\"pi\",\"e\",\"0\",\"1\",\"2\",\"3\",\"4\",\"5\",\"6\",\"7\",\"8\",\"9\"];\
  3098. var cntl = 0;var cntr = 0;\
  3099. var len = i.length;\
  3100. for( var p = 0;p < len; p++){\
  3101.  if(i.charAt(p) == '('){cntl++;}\
  3102.  if(i.charAt(p) == ')'){cntr++;}\
  3103. };\
  3104. if(cntl != cntr){alert(\"unmatched parenthesis !!\");return null;};\
  3105. for(var p = 0; p < 12 ; p++){\
  3106.  for(var d = 0; d < 12 ; d++){\
  3107.   while(i.indexOf(cons[d]+\"\"+fun[p])!=-1){\
  3108.    i = i.replace(cons[d]+\"\"+fun[p],cons[d]+\"*\"+fun[p]);\
  3109.   };\
  3110.   while(i.indexOf(fun[p]+\"\"+cons[d])!=-1){\
  3111.    i = i.replace(fun[p]+\"\"+cons[d],fun[p]+\"*\"+cons[d]);\
  3112.   };\
  3113.  };\
  3114. };\
  3115. if(i.indexOf(\"(\")!=-1){\
  3116.  for(var p = 0;p < 12; p++){\
  3117.   if(i.indexOf(cons[p]+\"(\")!=-1){\
  3118.    i = i.replace(cons[p]+\"(\",cons[p]+\"*(\");\
  3119.   };\
  3120.   if(i.indexOf(\")\"+cons[p])!=-1){\
  3121.    i = i.replace(\")\"+cons[p],\")*\"+cons[p]);\
  3122.   };\
  3123.  };\
  3124.  i = i.replace(/\\)\\(/g,\")*(\");\
  3125. };\
  3126. return i;\
  3127. }\n");
  3128. }
  3129. void add_input_jsfunction(FILE *js_include_file, int canvas_root_id,char *input_style,char *input_label,int input_cnt,char *stroke_color,float stroke_opacity,int line_width,int use_dashed,int dashtype0,int dashtype1,int font_size){
  3130. fprintf(js_include_file,"\n<!-- begin add_input_jsfunction -->\n\
  3131. function clear_jsfunction(canvas_plot_id,input_field){\
  3132. try{\
  3133.  var canvas_plot = document.getElementById(\"wims_canvas%d\"+canvas_plot_id);\
  3134.  var canvas_plot_ctx = canvas_plot.getContext(\"2d\");\
  3135.  if( confirm(\"clear function plot?\") ){\
  3136.   canvas_plot_ctx.clearRect(0,0,xsize,ysize);\
  3137.   document.getElementById(input_field).value = \"\";\
  3138.  };\
  3139.  return;\
  3140. }catch(e){alert(e+\"nothing to remove...\");};\
  3141. return;\
  3142. };\
  3143. function add_input_jsfunction(input_cnt,input_style,input_label,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1){\
  3144. var canvas_plot_id = %d+input_cnt;\
  3145. var input_field = \"canvas_input\"+input_cnt;\
  3146. var update_button_id = \"update_button\"+input_cnt;\
  3147. var delete_button_id = \"delete_button\"+input_cnt;\
  3148. if( wims_status == \"done\" ){return;};\
  3149. var tooltip_div = document.getElementById(\"tooltip_placeholder_div%d\");\
  3150. var input_jsfunction_div = document.createElement('div');\
  3151. input_jsfunction_div.id = \"input_jsfunction_div\"+input_cnt;\
  3152. tooltip_div.appendChild(input_jsfunction_div);\
  3153. input_jsfunction_div.innerHTML=\"<br /><br /><span style='font-style:italic;font-size:%dpx;color:rgb(\"+stroke_color+\")'><b>\"+input_label+\" <input type='text' size='16' value='' id='\"+input_field+\"' style='\"+input_style+\"' /></b><input id='\"+update_button_id+\"' type='button' value='OK' onclick='' style='color:red;background-color:lightblue;'/><input id='\"+delete_button_id+\"' type='button' value='NOK' onclick='' style='color:blue;background-color:red;'/></span> \";\
  3154. var update_button = document.getElementById(update_button_id);\
  3155. var delete_button = document.getElementById(delete_button_id);\
  3156. update_button.addEventListener(\"mousedown\",function(e){jsplot(canvas_plot_id,[rawmath(document.getElementById(input_field).value)],[line_width],[stroke_color],[stroke_opacity],[use_dashed],dashtype0,dashtype1,0,0,300,0,0);return;},false);\
  3157. delete_button.addEventListener(\"mousedown\",function(e){clear_jsfunction(canvas_plot_id,input_field);return;},false);\
  3158. };\
  3159. add_input_jsfunction(%d,\"%s\",\"%s\",%d,\"%s\",%.2f,%d,%d,%d);\n",canvas_root_id,USERDRAW_JSPLOT,canvas_root_id,font_size,input_cnt,input_style,input_label,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);
  3160. }
  3161.  
  3162.  
  3163. /*
  3164. adds 2 inputfields (x:y) and 'ok' | 'nok' button
  3165. these are used for user drawing with inputfields...
  3166. */
  3167.  
  3168. void add_input_xy(FILE *js_include_file, int canvas_root_id,int font_size,char *input_style){
  3169. fprintf(js_include_file,"\n<!-- begin add_input_xy -->\n\
  3170. function add_input_xy(){\
  3171. if( wims_status == \"done\" ){return;};\
  3172. var tooltip_div = document.getElementById(\"tooltip_placeholder_div%d\");\
  3173. var input_xy_div = document.createElement('div');\
  3174. input_xy_div.id = \"input_xy_div\";\
  3175. tooltip_div.appendChild(input_xy_div);\
  3176. var label_x = \"x\";var label_y = \"y\";\
  3177. input_xy_div.innerHTML=\"<br /><span style='font-style:italic;font-size:%dpx'><b>( <input type='text' size='5' value='' id='userinput_x' style='%s' /> : <input type='text' size='5' value='' id='userinput_y' style='%s' /> )</b><input id='update_button' type='button' value='OK' onclick=''  style='color:red;background-color:lightblue;'/><input id='delete_button' type='button' value='NOK' onclick='' style='color:blue;background-color:red;'/></span> \";\
  3178. var update_button = document.getElementById(\"update_button\");\
  3179. var delete_button = document.getElementById(\"delete_button\");\
  3180. update_button.addEventListener(\"mousedown\",function(e){user_redraw(1);return;},false);\
  3181. delete_button.addEventListener(\"mousedown\",function(e){user_redraw(-1);return;},false);\
  3182. };add_input_xy();",canvas_root_id,font_size,input_style,input_style);
  3183. }
  3184.  
  3185. /* adds 4 inputfields (x1:y1) --- (x2:y2) and 'ok' + 'nok' button */
  3186. void add_input_x1y1x2y2(FILE *js_include_file, int canvas_root_id,int font_size,char *input_style){
  3187. fprintf(js_include_file,"\n<!-- begin add_input_x1y1x2y2 -->\n\
  3188. function add_input_x1y1x2y2(){\
  3189. if( wims_status == \"done\" ){return;};\
  3190. var tooltip_div = document.getElementById(\"tooltip_placeholder_div%d\");\
  3191. var input_x1y1x2y2_div = document.createElement('div');\
  3192. input_x1y1x2y2_div.id = \"input_x1y1x2y2_div\";\
  3193. tooltip_div.appendChild(input_x1y1x2y2_div);\
  3194. input_x1y1x2y2_div.innerHTML=\"<br /><span style='font-size:%dpx'><b>( <input type='text' size='5' value='' id='userinput_x1' style='%s' /> : <input type='text' size='5' value='' id='userinput_y1' style='%s' /> ) ----- ( <input type='text' size='5' value='' id='userinput_x2' style='%s' /> : <input type='text' size='5' value='' id='userinput_y2' style='%s'/> )</b><input id='update_button' type='button' value='OK' onclick='' style='color:red;background-color:lightblue;'/><input id='delete_button' type='button' value='NOK' onclick='' style='color:blue;background-color:red;' /></span> \";\
  3195. var update_button = document.getElementById(\"update_button\");\
  3196. var delete_button = document.getElementById(\"delete_button\");\
  3197. update_button.addEventListener(\"mousedown\",function(e){user_redraw(1);return;},false);\
  3198. delete_button.addEventListener(\"mousedown\",function(e){user_redraw(-1);return;},false);\
  3199. };add_input_x1y1x2y2();",canvas_root_id,font_size,input_style,input_style,input_style,input_style);
  3200. }
  3201.  
  3202. /* adds 3 inputfields Center (x:y) Radius r and 'ok'+'nok' buttons */
  3203. void add_input_xyr(FILE *js_include_file, int canvas_root_id,int font_size,char *input_style){
  3204. fprintf(js_include_file,"\n<!-- begin add_input_xyr -->\n\
  3205. function add_input_xyr(){\
  3206. if( wims_status == \"done\" ){return;};\
  3207. var tooltip_div = document.getElementById(\"tooltip_placeholder_div%d\");\
  3208. var input_xyr_div = document.createElement('div');\
  3209. input_xyr_div.id = \"input_xyr_div\";\
  3210. tooltip_div.appendChild(input_xyr_div);\
  3211. input_xyr_div.innerHTML=\"<br /><span style='font-style:italic;font-size:%dpx'><b>Center : ( <input type='text' size='5' value='' id='userinput_x' style='%s' /> : <input type='text' size='5' value='' id='userinput_y' style='%s' /> ) Radius : <input type='text' size='5' value='' id='userinput_r' style='%s' /></b><input id='update_button' type='button' value='OK' onclick='' style='color:red;background-color:lightblue;'/><input id='delete_button' type='button' value='NOK' onclick='' style='color:blue;background-color:red;'/></span> \";\
  3212. var update_button = document.getElementById(\"update_button\");\
  3213. var delete_button = document.getElementById(\"delete_button\");\
  3214. update_button.addEventListener(\"mousedown\",function(e){user_redraw(1);return;},false);\
  3215. delete_button.addEventListener(\"mousedown\",function(e){user_redraw(-1);return;},false);\
  3216. };add_input_xyr();",canvas_root_id,font_size,input_style,input_style,input_style);
  3217. }
  3218.  
  3219. /* THESE JS-FUNCTIONS COULD BE MADE LESS COPY & PASTE "PROGRAMMING" */
  3220.  
  3221. /* draw circle(s) / point(s) via 3 inputfields */
  3222. void add_input_circle(FILE *js_include_file,int type,int num){
  3223. /*
  3224. type = 0 : a point ...radius is fixed
  3225. type = 1 : a circle ... read inputfield userinput_r
  3226. num = 1 : a single point / circle
  3227. num = 2 : multiple points / circles
  3228. */
  3229. fprintf(js_include_file,"\n<!-- begin add_input_circle -->\n\
  3230. function user_redraw(t){\
  3231. var type = %d;\
  3232. var num = %d;\
  3233. var lu = userdraw_x.length;\
  3234. if( t == -1 && lu > 0){userdraw_x.splice(lu-1,1);userdraw_y.splice(lu-1,1);if(type == 1){userdraw_radius.splice(lu-1,1);};context_userdraw.clearRect(0,0,xsize,ysize);draw_circles(context_userdraw,userdraw_x,userdraw_y,userdraw_radius,line_width,stroke_color,stroke_opacity,use_filled,fill_color,fill_opacity,use_dashed,dashtype0,dashtype1);xy_cnt = userdraw_x.length;return;};\
  3235. var add_x = safe_eval( document.getElementById(\"userinput_x\").value );\
  3236. var add_y = safe_eval( document.getElementById(\"userinput_y\").value );\
  3237. if( add_x != null && add_y != null ){if( type == 1 ){var add_r = safe_eval( document.getElementById(\"userinput_r\").value );if( add_r == null ){alert(\"illegal radius input \");return;};if( num == 1 ){userdraw_radius[0] = parseInt(Math.abs(xsize*(add_r)/(xmax - xmin)));}else{userdraw_radius.push( parseInt(Math.abs(xsize*(add_r)/(xmax - xmin))) );};}else{userdraw_radius[lu] = userdraw_radius[0];};if( num == 1 ){userdraw_x[0] = x2px(add_x);userdraw_y[0] = y2px(add_y);xy_cnt=1;}else{userdraw_x.push(x2px(add_x));userdraw_y.push(y2px(add_y));xy_cnt = userdraw_x.length;};context_userdraw.clearRect(0,0,xsize,ysize);draw_circles(context_userdraw,userdraw_x,userdraw_y,userdraw_radius,line_width,stroke_color,stroke_opacity,use_filled,fill_color,fill_opacity,use_dashed,dashtype0,dashtype1);};\
  3238. return;\
  3239. };",type,num);
  3240. }
  3241. /* draw crosshairs via inputfields x/y */
  3242. void add_input_crosshair(FILE *js_include_file,int num){
  3243. fprintf(js_include_file,"\n<!-- begin add_input_crosshair -->\n\
  3244. function user_redraw(t){\
  3245. var lu = userdraw_x.length;\
  3246. if( t == -1 && lu > 0){\
  3247.  userdraw_x.splice(lu-1,1);\
  3248.  userdraw_y.splice(lu-1,1);\
  3249.  context_userdraw.clearRect(0,0,xsize,ysize);\
  3250.  draw_crosshairs(context_userdraw,userdraw_x,userdraw_y,line_width,crosshair_size,stroke_color,stroke_opacity,0,0,0,[0,0]);\
  3251.  return;\
  3252. };\
  3253. var add_x = safe_eval( document.getElementById(\"userinput_x\").value );\
  3254. var add_y = safe_eval( document.getElementById(\"userinput_y\").value );\
  3255. if( add_x != null && add_y != null ){\
  3256.  if( %d == 1 ){\
  3257.   userdraw_x[0] = x2px(add_x);\
  3258.   userdraw_y[0] = y2px(add_y);\
  3259.  }\
  3260.  else\
  3261.  {\
  3262.    userdraw_x[lu] = x2px(add_x);\
  3263.    userdraw_y[lu] = y2px(add_y);\
  3264.    xy_cnt++;\
  3265.  };\
  3266.  context_userdraw.clearRect(0,0,xsize,ysize);\
  3267.  draw_crosshairs(context_userdraw,userdraw_x,userdraw_y,line_width,crosshair_size,stroke_color,stroke_opacity,0,0,0,[0,0]);\
  3268. };\
  3269. return;\
  3270. };",num);
  3271. }
  3272.  
  3273. /* draw arrows via inputfields x/y */
  3274. void add_input_arrow(FILE *js_include_file,int num){
  3275. fprintf(js_include_file,"\n<!-- begin add_input_arrow -->\n\
  3276. function user_redraw(t){\
  3277. var lu = userdraw_x.length;\
  3278. if( t == -1 && lu > 1 ){\
  3279.  userdraw_x.splice(lu-2,2);\
  3280.  userdraw_y.splice(lu-2,2);\
  3281.  context_userdraw.clearRect(0,0,xsize,ysize);\
  3282.  draw_arrows(context_userdraw,userdraw_x,userdraw_y,arrow_head,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1,type,use_rotate,angle,0,[1,0,0,1,0,0]);\
  3283.  return;\
  3284. };\
  3285. var add_x1 = safe_eval( document.getElementById(\"userinput_x1\").value );\
  3286. var add_y1 = safe_eval( document.getElementById(\"userinput_y1\").value );\
  3287. var add_x2 = safe_eval( document.getElementById(\"userinput_x2\").value );\
  3288. var add_y2 = safe_eval( document.getElementById(\"userinput_y2\").value );\
  3289. if( add_x1 != null && add_y1 != null && add_x2 != null && add_y2 != null ){\
  3290.  if( %d == 2 ){\
  3291.    var s = userdraw_x.length;\
  3292.    userdraw_x[lu] = x2px(add_x1);\
  3293.    userdraw_y[lu] = y2px(add_y1);\
  3294.    userdraw_x[lu+1] = x2px(add_x2);\
  3295.    userdraw_y[lu+1] = y2px(add_y2);\
  3296.  }\
  3297.  else\
  3298.  {\
  3299.   userdraw_x[0] = x2px(add_x1);\
  3300.   userdraw_y[0] = y2px(add_y1);\
  3301.   userdraw_x[1] = x2px(add_x2);\
  3302.   userdraw_y[1] = y2px(add_y2);\
  3303.  };\
  3304.  context_userdraw.clearRect(0,0,xsize,ysize);\
  3305.  draw_arrows(context_userdraw,userdraw_x,userdraw_y,arrow_head,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1,type,use_rotate,angle,0,[1,0,0,1,0,0]);\
  3306. };\
  3307. return;\
  3308. };",num);
  3309. }
  3310.  
  3311. /* draw line via inputfields x/y */
  3312. void add_input_line(FILE *js_include_file,int num){
  3313. fprintf(js_include_file,"\n<!-- begin line via inputfields  -->\n\
  3314. function user_redraw(t){\
  3315. var lu = userdraw_x.length;\
  3316. if( t == -1 && lu > 1){\
  3317.  userdraw_x.splice(lu-2,2);\
  3318.  userdraw_y.splice(lu-2,2);\
  3319.  context_userdraw.clearRect(0,0,xsize,ysize);\
  3320.  draw_lines(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1,1,0,0);\
  3321.  return;\
  3322. };\
  3323. var add_x1 = safe_eval( document.getElementById(\"userinput_x1\").value );\
  3324. var add_y1 = safe_eval( document.getElementById(\"userinput_y1\").value );\
  3325. var add_x2 = safe_eval( document.getElementById(\"userinput_x2\").value );\
  3326. var add_y2 = safe_eval( document.getElementById(\"userinput_y2\").value );\
  3327. if( add_x1 != null && add_y1 != null && add_x2 != null && add_y2 != null ){\
  3328.  if( %d == 2 ){\
  3329.    userdraw_x[lu] = x2px(add_x1);\
  3330.    userdraw_y[lu] = y2px(add_y1);\
  3331.    userdraw_x[lu+1] = x2px(add_x2);\
  3332.    userdraw_y[lu+1] = y2px(add_y2);\
  3333.  }\
  3334.  else\
  3335.  {\
  3336.   userdraw_x[0] = x2px(add_x1);\
  3337.   userdraw_y[0] = y2px(add_y1);\
  3338.   userdraw_x[1] = x2px(add_x2);\
  3339.   userdraw_y[1] = y2px(add_y2);\
  3340.  };\
  3341.  context_userdraw.clearRect(0,0,xsize,ysize);\
  3342.  draw_lines(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1,1,0,0);\
  3343. };\
  3344. return;\
  3345. };",num);
  3346. }
  3347.  
  3348.  
  3349. /* draw polyline via inputfields x/y */
  3350. void add_input_polyline(FILE *js_include_file){
  3351. fprintf(js_include_file,"\n<!-- begin polyline_segment via inputfields -->\n\
  3352. function user_redraw(t){\
  3353. var lu = userdraw_x.length;\
  3354. cnt = 1;\
  3355. if( t == -1 && lu > 0){\
  3356.  userdraw_x.splice(lu-1,1);\
  3357.  userdraw_y.splice(lu-1,1);\
  3358.  context_userdraw.clearRect(0,0,xsize,ysize);\
  3359.  draw_polyline(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);\
  3360.  return;\
  3361. };\
  3362. var add_x = safe_eval( document.getElementById(\"userinput_x\").value );\
  3363. var add_y = safe_eval( document.getElementById(\"userinput_y\").value );\
  3364. if(add_x != null && add_y != null ){\
  3365.  userdraw_x.push(x2px(add_x));\
  3366.  userdraw_y.push(y2px(add_y));\
  3367.  context_userdraw.clearRect(0,0,xsize,ysize);\
  3368.  draw_polyline(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);\
  3369. };\
  3370. return;\
  3371. };");
  3372. }
  3373. /* draw segment(s) via inputfields x/y */
  3374. void add_input_segment(FILE *js_include_file,int num){
  3375. fprintf(js_include_file,"\n<!-- begin add_input_segment -->\n\
  3376. function user_redraw(t){\
  3377. var lu = userdraw_x.length;\
  3378. if( t == -1 && lu > 1){\
  3379.  userdraw_x.splice(lu-2,2);\
  3380.  userdraw_y.splice(lu-2,2);\
  3381.  context_userdraw.clearRect(0,0,xsize,ysize);\
  3382.  draw_segments(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);\
  3383.  return;\
  3384. };\
  3385. var add_x1 = safe_eval( document.getElementById(\"userinput_x1\").value );\
  3386. var add_y1 = safe_eval( document.getElementById(\"userinput_y1\").value );\
  3387. var add_x2 = safe_eval( document.getElementById(\"userinput_x2\").value );\
  3388. var add_y2 = safe_eval( document.getElementById(\"userinput_y2\").value );\
  3389. if( add_x1 != null && add_y1 != null && add_x2 != null && add_y2 != null ){\
  3390.  if( %d == 2 ){\
  3391.    var s = userdraw_x.length;\
  3392.    userdraw_x[s] = x2px(add_x1);\
  3393.    userdraw_y[s] = y2px(add_y1);\
  3394.    userdraw_x[s+1] = x2px(add_x2);\
  3395.    userdraw_y[s+1] = y2px(add_y2);\
  3396.  }\
  3397.  else\
  3398.  {\
  3399.   userdraw_x[0] = x2px(add_x1);\
  3400.   userdraw_y[0] = y2px(add_y1);\
  3401.   userdraw_x[1] = x2px(add_x2);\
  3402.   userdraw_y[1] = y2px(add_y2);\
  3403.  };\
  3404.  context_userdraw.clearRect(0,0,xsize,ysize);\
  3405.  draw_segments(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);\
  3406. };\
  3407. return;\
  3408. };",num);
  3409. }
  3410.  
  3411. /* draw demilines(s) via inputfields x/y */
  3412. void add_input_demiline(FILE *js_include_file,int num){
  3413. fprintf(js_include_file,"\n<!-- begin add_input_segment -->\n\
  3414. function user_redraw(t){\
  3415. var lu = userdraw_x.length;\
  3416. if( t == -1 && lu > 1){\
  3417.  userdraw_x.splice(lu-2,2);\
  3418.  userdraw_y.splice(lu-2,2);\
  3419.  context_userdraw.clearRect(0,0,xsize,ysize);\
  3420.  draw_demilines(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);\
  3421.  return;\
  3422. };\
  3423. var add_x1 = safe_eval( document.getElementById(\"userinput_x1\").value );\
  3424. var add_y1 = safe_eval( document.getElementById(\"userinput_y1\").value );\
  3425. var add_x2 = safe_eval( document.getElementById(\"userinput_x2\").value );\
  3426. var add_y2 = safe_eval( document.getElementById(\"userinput_y2\").value );\
  3427. if( add_x1 != null && add_y1 != null && add_x2 != null && add_y2 != null ){\
  3428.  if( %d == 2 ){\
  3429.    var s = userdraw_x.length;\
  3430.    userdraw_x[s] = x2px(add_x1);\
  3431.    userdraw_y[s] = y2px(add_y1);\
  3432.    userdraw_x[s+1] = x2px(add_x2);\
  3433.    userdraw_y[s+1] = y2px(add_y2);\
  3434.  }\
  3435.  else\
  3436.  {\
  3437.   userdraw_x[0] = x2px(add_x1);\
  3438.   userdraw_y[0] = y2px(add_y1);\
  3439.   userdraw_x[1] = x2px(add_x2);\
  3440.   userdraw_y[1] = y2px(add_y2);\
  3441.  };\
  3442.  context_userdraw.clearRect(0,0,xsize,ysize);\
  3443.  draw_demilines(context_userdraw,userdraw_x,userdraw_y,line_width,stroke_color,stroke_opacity,use_dashed,dashtype0,dashtype1);\
  3444. };\
  3445. return;\
  3446. };",num);
  3447. }
  3448.  
  3449. /* draw polygon via 2 textarea's x/y : split into lines ! */
  3450. void add_textarea_polygon(FILE *js_include_file){
  3451. fprintf(js_include_file,"\n<!-- begin polygon via 2 textareas x / y -->\n\
  3452. function user_redraw(t){\
  3453. var lu = userdraw_x.length;\
  3454. if( t == -1 && lu > 0){\
  3455.  if( lu < 3 ){\
  3456.   userdraw_x = [];\
  3457.   userdraw_y = [];\
  3458.  }\
  3459.  else\
  3460.  {\
  3461.  userdraw_x.splice(lu-1,1);\
  3462.  userdraw_y.splice(lu-1,1);\
  3463.  };\
  3464.  context_userdraw.clearRect(0,0,xsize,ysize);\
  3465.  draw_paths(context_userdraw,userdraw_x,userdraw_y,line_width,closed_path,stroke_color,stroke_opacity,use_filled,fill_color,fill_opacity,use_dashed,dashtype0,use_rotate,angle,0,[1,0,0,1,0,0]);\
  3466.  cnt = 1; return;\
  3467. };\
  3468. var add_x_values = (document.getElementById(\"userinput_x\").value).split('\\n');\
  3469. var add_y_values = (document.getElementById(\"userinput_y\").value).split('\\n');\
  3470. var lx = add_x_values.length;\
  3471. var ly = add_y_values.length;\
  3472. if( lx != ly){ if(lx > ly){alert(\'x/y mismatch\\ntoo few y-values\');return}else{alert(\'x/y mismatch\\ntoo many y-values\');return}};\
  3473. var add_x;var add_y;\
  3474. for(var p = 0 ; p < lx ; p++){\
  3475.  add_x = safe_eval( add_x_values[p] );\
  3476.  add_y = safe_eval( add_y_values[p] );\
  3477.  if( add_x == null || add_y == null ){return;};\
  3478.  userdraw_x[lu+p] = x2px(add_x);\
  3479.  userdraw_y[lu+p] = y2px(add_y);\
  3480.  if(p>100){alert(\"hmmmm\");return;};\
  3481. };\
  3482. draw_paths(context_userdraw,userdraw_x,userdraw_y,line_width,closed_path,stroke_color,stroke_opacity,use_filled,fill_color,fill_opacity,use_dashed,dashtype0,use_rotate,angle,0,[1,0,0,1,0,0]);\
  3483. cnt = 1;\
  3484. return;\
  3485. };");
  3486. }
  3487.  
  3488. void add_jsplot(FILE *js_include_file,int canvas_root_id){
  3489. fprintf(js_include_file,"\n<!-- begin jsplot() -->\n\
  3490. var x_anim_points;var y_anim_points;var animation_steps;var animation_funs;\
  3491. var jsplot = function(canvas_type,funs,linewidth,color,opacity,use_dashed,dashtype0,dashtype1,trange,plotsteps,use_parametric,use_animate){\
  3492. var obj = create_canvas%d(canvas_type,xsize,ysize);\
  3493. var ctx = obj.getContext(\"2d\");\
  3494. ctx.clearRect(0,0,xsize,ysize);\
  3495. animation_funs = funs.length;\
  3496. function eval_jsmath(x,func){return parseFloat(eval(func));};\
  3497. if( typeof(multilinewidth) !== 'undefined' && multilinewidth != null ){ linewidth = multilinewidth;};\
  3498. if( typeof(multistrokecolors) !== 'undefined' && multistrokecolors != null){ color = multistrokecolors;};\
  3499. if( typeof(multistrokeopacity) !== 'undefined' && multistrokeopacity != null ){ opacity = multistrokeopacity;};\
  3500. if( typeof(multidash) !== 'undefined' && multidash != null ){use_dashed = multidash;};\
  3501. x_anim_points = [];y_anim_points = [];var idx=0;\
  3502. if( use_parametric == 1){\n\
  3503.  for(var i = 0 ; i < animation_funs; i=i+2){\
  3504.   var fun_x = to_js_math(funs[i]);\
  3505.   var fun_y = to_js_math(funs[i+1]);\
  3506.   if(fun_x == null || fun_y == null){alert(\"Syntax Error...\\nAttention : try use very precise notation !\\nlike :\\n6*(0.25)^(1.23)\\n1/(sin(5*x))\\n(3*x+4)/(x^(2*pi)) \");return;};\
  3507.   try{ parseFloat( eval_jsmath( px2x(0),fun_x ) );}catch(e){alert(\"\\nSyntax Error...\\nAttention : try use very precise notation !\\nlike :\\n6*(0.25)^(1.23)\\n1/(sin(5*x))\\n(3*x+4)/(x^(2*pi))\");return;};\
  3508.   ctx.lineWidth = linewidth[i] || linewidth;\
  3509.   ctx.strokeStyle='rgba('+color[i] || color +','+opacity[i] || opacity +')';\
  3510.   if(use_dashed[i] == \"1\" || use_dashed == \"1\"){if(ctx.setLineDash){ctx.setLineDash([dashtype0,dashtype1]);}else{ctx.mozDash =[dashtype0,dashtype1];}};\
  3511.   var y1;var x1;var y2;var x2;\
  3512.   ctx.beginPath();\
  3513.   var tmin = trange[0];var tmax = trange[1];\
  3514.   var step = parseFloat((tmax - tmin)/plotsteps);\
  3515.   for(var p = tmin ; p < tmax; p = p+step ){\
  3516.    x1 = x2px(parseFloat(eval_jsmath(p,fun_x)));\
  3517.    y1 = y2px(parseFloat(eval_jsmath(p,fun_y)));\
  3518.    x2 = x2px(parseFloat(eval_jsmath(p+step,fun_x)));\
  3519.    y2 = y2px(parseFloat(eval_jsmath(p+step,fun_y)));\
  3520.    x_anim_points[idx] = x1;y_anim_points[idx] = y1;idx++;\
  3521.     ctx.moveTo(x1,y1);\
  3522.     ctx.lineTo(x2,y2);\
  3523.     ctx.moveTo(x1,y1);\
  3524.     ctx.lineTo(x2,y2);\
  3525.   };\
  3526.   ctx.closePath();\
  3527.   ctx.stroke();\
  3528.  };\
  3529.  animation_funs = 0.5*animation_funs;\
  3530. }else{\
  3531.  for(var i = 0 ; i < animation_funs; i++){\
  3532.   var fun = to_js_math(funs[i]);\
  3533.   if(fun == null){alert(\"Syntax Error...\\nAttention : try use very precise notation !\\nlike :\\n6*(0.25)^(1.23)\\n1/(sin(5*x))\\n(3*x+4)/(x^(2*pi)) \");return;};\
  3534.   try{ parseFloat( eval_jsmath( px2x(0),fun ) );}catch(e){alert(\"\\nSyntax Error...\\nAttention : try use very precise notation !\\nlike :\\n6*(0.25)^(1.23)\\n1/(sin(5*x))\\n(3*x+4)/(x^(2*pi))\");return;};\
  3535.   if(use_dashed[i] == \"1\" || use_dashed == \"1\"){if(ctx.setLineDash){ctx.setLineDash([dashtype0,dashtype1]);}else{ctx.mozDash =[dashtype0,dashtype1];}};\
  3536.   ctx.lineWidth = linewidth[i] || linewidth;\
  3537.   ctx.strokeStyle='rgba('+color[i] || color +','+opacity[i] || opacity +')';\
  3538.   var y1;var x1;var y2;var x2;\
  3539.   ctx.beginPath();\
  3540.   for(var p = 0 ; p<xsize;p++){\
  3541.    x1 = px2x(p);\
  3542.    y1 = y2px(parseFloat(eval_jsmath(x1,fun)));\
  3543.    x2 = px2x(p+1);\
  3544.    y2 = y2px(parseFloat(eval_jsmath(x2,fun)));\
  3545.    x_anim_points[idx] = p;y_anim_points[idx] = y1;idx++;\
  3546.    if(Math.abs(y2-y1) < ysize ){\
  3547.     ctx.moveTo(p,y1);\
  3548.     ctx.lineTo(p+1,y2);\
  3549.    };\
  3550.   };\
  3551.   ctx.closePath();\
  3552.   ctx.stroke();\
  3553.  };\
  3554. };\
  3555. if( use_animate == 1 ){animation_steps = idx;animate_this();}\
  3556. };",canvas_root_id);
  3557. }
  3558.  
  3559. void add_to_js_math(FILE *js_include_file){
  3560. fprintf(js_include_file,"\n<!-- begin to_js_math() -->\n\
  3561. var to_js_math = function(math_fun){\
  3562. if(math_fun == null){return;};\
  3563. var infun=[\"sqrt\",\"^\",\"asin\",\"acos\",\"atan\",\"log\",\"pi\",\"abs\",\"sin\",\"cos\",\"tan\",\"e\"];\
  3564. var outfun=[\"Math.sqrt\",\"Math.pow\",\"Math.asin\",\"Math.acos\",\"Math.atan\",\"Math.log\",\"(3.14159265358979)\",\"Math.abs\",\"Math.sin\",\"Math.cos\",\"Math.tan\",\"(2.718281828459045)\"];\
  3565. var len = infun.length;var in_fun;var In_Fun;var out_fun;var w_cnt;\
  3566. for(var p=0 ; p < len ; p++){\
  3567.  in_fun = infun[p];In_Fun = in_fun.toUpperCase();out_fun = outfun[p];w_cnt=0;\
  3568.  if(math_fun.indexOf(in_fun) != -1){\
  3569.   if(in_fun == \"^\"){\
  3570.    var tab = [];var small_trick = \"___small_trick___\";\
  3571.    while (math_fun.indexOf(\"(\") != -1){\
  3572.     math_fun = math_fun.replace(/(\\([^\\(\\)]*\\))/g, function(m, t){tab.push(t);return (small_trick + (tab.length - 1));});\
  3573.     w_cnt++;if(w_cnt>1000){alert(\"hmmm \"+math_fun+\" ?\\nUse command plot for more complex math functions...\");return null;};\
  3574.    };\
  3575.    tab.push(math_fun);w_cnt = 0;math_fun = small_trick + (tab.length - 1);\
  3576.    while (math_fun.indexOf(small_trick) != -1){\
  3577.     math_fun = math_fun.replace(new RegExp(small_trick + \"(\\\\d+)\", \"g\"), function(m, d){return tab[d].replace(/(\\w*)\\^(\\w*)/g, out_fun+\"($1,$2)\");});\
  3578.     w_cnt++;if(w_cnt>1000){alert(\"hmmm \"+math_fun+\" ?\\nUse command plot for more complex math functions...\");return null;};\
  3579.    };\
  3580.   }\
  3581.   else\
  3582.   {\
  3583.    while( math_fun.indexOf(in_fun) != -1 ){\
  3584.     math_fun = math_fun.replace(in_fun,out_fun);\
  3585.     math_fun = math_fun.replace(in_fun,In_Fun);\
  3586.     w_cnt++;if(w_cnt>1000){alert(\"hmmm \"+math_fun+\" ?\\nUse command plot for more complex math functions...\");return null;};\
  3587.    };\
  3588.   };\
  3589.  };\
  3590. };\
  3591. for(var p=0 ; p < len ; p++){\
  3592.  in_fun = infun[p];In_Fun = in_fun.toUpperCase();w_cnt = 0;\
  3593.  if(math_fun.indexOf(In_Fun) != -1 ){\
  3594.   while(math_fun.indexOf(In_Fun) != -1){\
  3595.    math_fun = math_fun.replace(In_Fun,in_fun);\
  3596.    w_cnt++;if(w_cnt>1000){alert(\"hmmm \"+math_fun+\" ?\\nUse command plot for more complex math functions...\");return null;};\
  3597.   };\
  3598.  };\
  3599. };\
  3600. return math_fun;\
  3601. };\n");
  3602. }
  3603.  
  3604. void add_clear_button(FILE *js_include_file,int canvas_root_id,char *input_style,char *button_text){
  3605. /* 25/11/2014 added clearing of reply array
  3606. all members will be set to 0 eg reply[0] = 0 , reply[1] = 0 ...
  3607. hope this does not interfere with existing work...
  3608. */
  3609. /*
  3610. 5/2016 changed  to 'setAttribute()' because of trouble on Chromium/Safari/IE
  3611. 10/2016 corrected contex-reset-flaw when using "userdraw text,color" and added inputs to the things we can remove
  3612. 7/2017 added 'userdraw clickfill,color' to removable things...one user_filling per click
  3613. */
  3614. fprintf(js_include_file,"<!-- add clear button -->\n\
  3615. clear_draw_area%d = function(){\
  3616. if(typeof(fill_canvas_no) === 'object'){\
  3617.  var len = fill_canvas_no.length;\
  3618.  for(var p = len; p >= 0; p = p - 1){\
  3619.   var chk = document.getElementById('wims_canvas%d'+fill_canvas_no[p]);\
  3620.   if( chk ){\
  3621.     var fill_ctx = chk.getContext(\"2d\");\
  3622.     fill_ctx.clearRect(0,0,xsize,ysize);\
  3623.     fill_canvas_no.splice(p,1);\
  3624.     userdraw_x.splice(p,1);\
  3625.     userdraw_y.splice(p,1);\
  3626.     userdraw_radius.splice(p,1);\
  3627.     return;\
  3628.   };\
  3629.  };\
  3630.  return;\
  3631. };\
  3632. if( typeof(context_userdraw) === 'object' ){\
  3633.  context_userdraw.clearRect(0,0,xsize,ysize);\
  3634.  if( typeof(userdraw_text) != 'undefined'){ userdraw_text = []; };\
  3635.  if( document.getElementById(\"canvas_input0\") ){\
  3636.   var p = 0;var inp;\
  3637.   while( document.getElementById(\"canvas_input\"+p) ){\
  3638.    inp = document.getElementById(\"canvas_input\"+p);\
  3639.    canvas_div.removeChild(inp);\
  3640.    p++;\
  3641.   };\
  3642.   input_cnt = 0;start_input_cnt = 0; \
  3643.  };\
  3644.  userdraw_x = [];userdraw_y = [];userdraw_radius = [];xy_cnt = 0;\
  3645.  for(var p = 0;p < reply.length; p++){\
  3646.   reply[p] = 0;\
  3647.  };\
  3648. };\
  3649. return;\
  3650. };\
  3651. function add_clear_button(){\
  3652. var tooltip_placeholder_div = document.getElementById(\"tooltip_placeholder_div%d\");\
  3653. var button = document.createElement('input');\
  3654. button.setAttribute(\"type\" , \"button\");\
  3655. button.setAttribute(\"id\" , \"clearbutton%d\");\
  3656. button.setAttribute(\"style\" , \"%s\");\
  3657. button.setAttribute(\"value\" , \"%s\");\
  3658. button.setAttribute(\"onclick\",\"clear_draw_area%d()\");\
  3659. tooltip_placeholder_div.appendChild(button);\
  3660. };\
  3661. add_clear_button();\
  3662. ",canvas_root_id,canvas_root_id,canvas_root_id,canvas_root_id,input_style,button_text,canvas_root_id);
  3663. }
  3664.  
  3665. void add_color_palette(FILE *js_include_file,int canvas_root_id,char *input_style){
  3666. fprintf(js_include_file,"<!-- add color palette -->\n\
  3667. function add_color_palette(){\
  3668. var tooltip_placeholder_div = document.getElementById(\"tooltip_placeholder_div%d\");\
  3669. var clen = palettecolors.length;\
  3670. for( var p = 0 ; p < clen ; p++ ){\n\
  3671.  var button = document.createElement('input');\
  3672.  button.setAttribute('type', 'button');\
  3673.  button.setAttribute('value', '  ');\
  3674.  button.setAttribute('id',palettecolors[p]);\
  3675.  button.setAttribute('style', \"%s\");\
  3676.  button.setAttribute('style','background-color:rgb('+palettecolors[p]+')');\
  3677.  button.setAttribute(\"backgroundColor\",palettecolors[p]);\
  3678.  button.addEventListener('mousedown',function(e){var id = this.getAttribute('id');multifillcolors[0]=id;multifillcolors[1]=id;multifillcolors[2]=id;},false);\
  3679.  tooltip_placeholder_div.appendChild(button);\
  3680. };\
  3681. };\
  3682. add_color_palette();\
  3683. ",canvas_root_id,input_style);
  3684. }
  3685.  
  3686.  
  3687. /* GNU libmatheval library for evaluating mathematical functions. */
  3688. char *eval(int xsize,int ysize,char *fun,double xmin,double xmax,double ymin,double ymax,int plotsteps,int precision){
  3689.     void *f;
  3690.     double x;
  3691.     double y;
  3692.     int xv;
  3693.     int i = 0;
  3694.     int xstep =(int)(xsize/plotsteps);
  3695.     if( xstep == 0 ){xstep = 1;}
  3696.     double a = (xmax - xmin)/xsize;
  3697.     f = eval_create(fun);
  3698.     assert (f);
  3699.     if( f == NULL ){canvas_error("I'm having trouble parsing your \"expression\" ") ;}
  3700.     /* we supply the true x/y values...draw_curve() will convert these (x:y) to pixels : used for pan/scale */
  3701.     double xydata[MAX_BUFFER+1];/* hmmm */
  3702.     int lim_ymin =(int)( ymin - 4*fabs(ymin));/* 19-4-2015 replacing "abs" by "fabs"*/
  3703.     int lim_ymax =(int)( ymax + 4*fabs(ymax));/* 19-4-2015 replacing "abs" by "fabs"*/
  3704.     for ( xv = 0 ;xv < xsize ; xv = xv+xstep ){
  3705.         x = (double) (xv*a + xmin);
  3706.         if( i < MAX_BUFFER - 2){
  3707.             y = eval_x(f, x);
  3708.             if(y < lim_ymax && y > lim_ymin ){
  3709.                 xydata[i++] = x;
  3710.                 xydata[i++] = y;
  3711.             }
  3712.         }
  3713.         else
  3714.         {
  3715.             canvas_error("\nYour curve plotting produces too many data \n Use less plotsteps or some other means to reduce the amount of data... ");
  3716.         }
  3717.     }
  3718.     eval_destroy(f);
  3719.     return double_xy2js_array(xydata,i,find_number_of_digits(precision));
  3720. }
  3721. /* plot a very primitive (!) levelcurve : not to be compared with "flydraw levelcurve" */
  3722. char *eval_levelcurve(int xsize,int ysize,char *fun,double xmin,double xmax,double ymin,double ymax,int plotsteps,int precision,double level){
  3723.     void *f = eval_create(fun);
  3724.     assert (f);
  3725.     if( f == NULL ){canvas_error("I'm having trouble parsing your \"expression\" ") ;}
  3726.     double a = (double)((xmax - xmin)/plotsteps);
  3727.     double b = (double)((ymax - ymin)/plotsteps);
  3728.     double x;double y;double diff;
  3729.     double xydata[MAX_BUFFER+1];
  3730.     int i = 0;
  3731.     ymin = ymin - 1;
  3732.     xmin = xmin - 1;
  3733.     ymax = ymax + 1;
  3734.     xmax = xmax + 1;
  3735.     for( x = xmin ;x < xmax ; x = x + a ){
  3736.         for ( y = ymin ;y < ymax ; y = y + b ){
  3737.             if( i < MAX_BUFFER - 2){
  3738.                 diff = level - eval_x_y(f, x,y);
  3739.                 if(diff < 0.1 && diff > -0.1){
  3740.                     xydata[i++] = x;
  3741.                     xydata[i++] = y;
  3742.                 }
  3743.             }
  3744.             else
  3745.             {
  3746.                 canvas_error("\nYour curve plotting produces too many data \n Use less plotsteps, decrease image size...\nor some other means to reduce the amount of data... ");
  3747.             }
  3748.         }
  3749.     }
  3750.     eval_destroy(f);
  3751.     return double_xy2js_array(xydata,i,find_number_of_digits(precision));
  3752. }
  3753.  
  3754. /* plot parametric function */
  3755. char *eval_parametric(int xsize,int ysize,char *fun1,char* fun2,double xmin,double xmax,double ymin,double ymax,
  3756.  double tmin,double tmax,int plotsteps,int precision){
  3757.     void *fx;
  3758.     void *fy;
  3759.     double t;
  3760.     int i = 0;
  3761.     double tstep = (tmax-tmin)/plotsteps;
  3762.     if( tstep == 0 ){canvas_error("zero step for t variable : reduce plotsteps or inrease trange");}
  3763.     fx = eval_create(fun1);
  3764.     fy = eval_create(fun2);
  3765.     assert(fx);
  3766.     assert(fy);
  3767.     if( fx == NULL || fy == NULL ){canvas_error("I'm having trouble parsing your \"expression\" ") ;}
  3768.     /* we supply the true x/y values...draw_curve() will convert these (x:y) to pixels : used for pan/scale */
  3769.     double xydata[MAX_BUFFER+1];/* hmmm */
  3770.     double x; /* real x-values */
  3771.     double y; /* real y-values */
  3772.     int lim_ymin =(int)( ymin - 4*fabs(ymin));/* 19-4-2015 replacing "abs" by "fabs"*/
  3773.     int lim_ymax =(int)( ymax + 4*fabs(ymax));/* 19-4-2015 replacing "abs" by "fabs"*/
  3774.     for( t = tmin ;t <= tmax ; t = t + tstep ){
  3775.         if( i < MAX_BUFFER - 2 ){
  3776.             y = eval_t(fy, t);
  3777.             if(y > lim_ymin && y < lim_ymax){
  3778.                 x = eval_t(fx, t);
  3779.                 xydata[i++] = x;
  3780.                 xydata[i++] = y;
  3781.             }
  3782.         }
  3783.         else
  3784.         {
  3785.             canvas_error("\nYour curve plotting produces too many data \n Use less plotsteps or some other means to reduce the amount of data... ");
  3786.         }
  3787.     }
  3788.     eval_destroy(fx);
  3789.     eval_destroy(fy);
  3790.     return double_xy2js_array(xydata,i,find_number_of_digits(precision));
  3791. }
  3792.  
  3793. char *double_xy2js_array(double xy[],int len,int decimals){
  3794.  /*
  3795.     1,2,3,4,5,6,7,8 --> [1,3,5,7],[2,4,6,8]
  3796.     int xy[] is already checked for errors or overflow in "get_real()"
  3797.     just to be sure we double check the size of "temp"
  3798. */
  3799.     char temp[2*MAX_BUFFER], *string;
  3800.     char *tmp = my_newmem(16);/* <= 9999999999999999  */
  3801.     memset(temp,'\0',2*MAX_BUFFER);/* clear memory */
  3802.     int i;int space_left;
  3803.     temp[0] = '[';/* start js-array */
  3804.     for(i = 0; i < len;i = i + 2){ /*  x_points[] */
  3805.         if(i == len - 2){sprintf(tmp, "%.*f",decimals, xy[i]);}else{sprintf(tmp, "%.*f,",decimals,xy[i]);}
  3806.         space_left = (int) (sizeof(temp) - strlen(temp) - strlen(tmp) - 1);
  3807.         if( space_left > 0 ){ strncat(temp,tmp,space_left - 1);}else{canvas_error("can not parse integer to js-array:\nYour curve plotting produces too many data \nreduce your image size or plotsteps ");}
  3808.     }
  3809.     strncat(temp,"],[",3); /* close js x_values array and start new */
  3810.     for(i = 1; i < len;i = i + 2){ /* y_points */
  3811.         if(i == len - 1){ sprintf(tmp, "%.*f",decimals,xy[i]);}else{sprintf(tmp, "%.*f,",decimals,xy[i]);}
  3812.         space_left = (int) (sizeof(temp) - strlen(temp) - strlen(tmp) - 1);
  3813.         if( space_left > 0 ){ strncat(temp,tmp,space_left - 1);}else{canvas_error("can not parse integer to js-array:\nYour curve plotting produces too many data \nreduce your image size or plotsteps");}
  3814.     }
  3815.     strncat(temp,"]",1);
  3816.     string=(char *)my_newmem(sizeof(temp));
  3817.     snprintf(string,sizeof(temp),"%s",temp);
  3818.     return string;
  3819. }
  3820.  
  3821. char *xy2js_array(int xy[],int len){
  3822.  /*
  3823.     1,2,3,4,5,6,7,8 --> [1,3,5,7],[2,4,6,8]
  3824.     int xy[] is already checked for errors or overflow in "get_real()"
  3825.     just to be sure we double check the size of "temp"
  3826. */
  3827.     char temp[MAX_BUFFER], *string;
  3828.     char *tmp = my_newmem(16);/* <= 9999999999999999  */
  3829.     memset(temp,'\0',MAX_BUFFER);/* clear memory */
  3830.     int i;int space_left;
  3831.     temp[0] = '[';/* start js-array */
  3832.     for(i = 0; i < len;i = i + 2){ /*  x_points[] */
  3833.         if(i == len - 2){sprintf(tmp, "%d", xy[i]);}else{sprintf(tmp, "%d,", xy[i]);}
  3834.         space_left = (int) (sizeof(temp) - strlen(temp) - strlen(tmp) - 1);
  3835.         if( space_left > 0 ){ strncat(temp,tmp,space_left - 1);}else{canvas_error("can not parse integer to js-array:\nYour curve plotting produces too many data \nreduce image size or plotsteps ");}
  3836.     }
  3837.     strncat(temp,"],[",3); /* close js x_values array and start new */
  3838.     for(i = 1; i < len;i = i + 2){ /* y_points */
  3839.         if(i == len - 1){ sprintf(tmp, "%d", xy[i]);}else{sprintf(tmp, "%d,", xy[i]);}
  3840.         space_left = (int) (sizeof(temp) - strlen(temp) - strlen(tmp) - 1);
  3841.         if( space_left > 0 ){ strncat(temp,tmp,space_left - 1);}else{canvas_error("can not parse integer to js-array:\nYour curve plotting produces too many data\nreduce image size or plotsteps \n");}
  3842.     }
  3843.     strncat(temp,"]",1);
  3844.     string=(char *)my_newmem(sizeof(temp));
  3845.     snprintf(string,sizeof(temp),"%s",temp);
  3846.     return string;
  3847. }
  3848.  
  3849. char *data2js_array(int data[],int len){
  3850.  /*
  3851.     1,2,3,4,5,6,7,8 --> [1,2,3,4,5,6,7,8]
  3852.     int data[] is already checked for errors or overflow in "get_real()"
  3853.     just to be sure we double check the size of "temp"
  3854. */
  3855.     char temp[MAX_BUFFER], *string;
  3856.     char *tmp = my_newmem(16);/* <= 9999999999999999  */
  3857.     memset(temp,'\0',MAX_BUFFER);/* clear memory */
  3858.     int i;int space_left;
  3859.     temp[0] = '[';/* start js-array */
  3860.     for(i = 0; i < len; i++){
  3861.         if(i == len - 1){sprintf(tmp, "%d", data[i]);}else{sprintf(tmp, "%d,", data[i]);}
  3862.         space_left = (int) (sizeof(temp) - strlen(temp) - strlen(tmp) - 1);
  3863.         if( space_left > 0 ){ strncat(temp,tmp,space_left - 1);}else{canvas_error("can not parse integer to js-array:\nYour curve plotting produces too many data \nreduce image size or plotsteps ");}
  3864.     }
  3865.     strncat(temp,"]",1);
  3866.     string=(char *)my_newmem(sizeof(temp));
  3867.     snprintf(string,sizeof(temp),"%s",temp);
  3868.     return string;
  3869. }
  3870.  
  3871.  
  3872. void *my_newmem(size_t size){
  3873.         void    *p;
  3874.         if ((p = malloc(size +1)) == NULL){canvas_error("canvasdraw: ran out of memory\n");}
  3875.         return p;
  3876. }
  3877.  
  3878. int find_number_of_digits(int i){
  3879.     if(i < 0 ){ i = -1*i;}
  3880.     int digits = 0;
  3881.     while ( i > 0){
  3882.         digits++;
  3883.         i = i/10;
  3884.     }
  3885.     return digits;
  3886. }
  3887.  
  3888. struct colors colors[]={
  3889.  {"#FF0000","red","255,0,0"},
  3890.  {"#00FF00","lime","0,255,0"},
  3891.  {"#0000FF","blue","0,0,255"},
  3892.  {"#FFA500","orange","255,165,0"},
  3893.  {"#E9967A","darksalmon","233,150,122"},
  3894.  {"#F0FFFF","azure","240,255,255"},
  3895.  {"#CD5C5C","indianred","205,92,92"},
  3896.  {"#E0FFFF","lightcyan","224,255,255"},
  3897.  {"#FFE4E1","mistyrose","255,228,225"},
  3898.  {"#DC143C","crimson","220,20,60"},
  3899.  {"#FFC0CB","pink","255,192,203"},
  3900.  {"#FFD700","gold","255,215,0"},
  3901.  {"#E6E6FA","lavender","230,230,250"},
  3902.  {"#808080","gray","128,128,128"},
  3903.  {"#F0F8FF","aliceblue","240,248,255"},
  3904.  {"#C71585","mediumvioletred","199,21,133"},
  3905.  {"#FFF0F5","lavenderblush","255,240,245"},
  3906.  {"#DAA520","goldenrod","218,165,32"},
  3907.  {"#FFB6C1","lightpink","255,182,193"},
  3908.  {"#00FFFF","aqua","0,255,255"},
  3909.  {"#FF69B4","hotpink","255,105,180"},
  3910.  {"#00FFFF","cyan","0,255,255"},
  3911.  {"#FF1493","deeppink","255,20,147"},
  3912.  {"#7FFFD4","aquamarine","127,255,212"},
  3913.  {"#FA8072","salmon","250,128,114"},
  3914.  {"#DEB887","burlywood","222,184,135"},
  3915.  {"#DB7093","palevioletred","219,112,147"},
  3916.  {"#D2B48C","tan","210,180,140"},
  3917.  {"#BDB76B","darkkhaki","189,183,107"},
  3918.  {"#B22222","firebrick","178,34,34"},
  3919.  {"#FF4500","orangered","255,69,0"},
  3920.  {"#8B4513","saddlebrown","139,69,19"},
  3921.  {"#FF8C00","darkorange","255,140,0"},
  3922.  {"#FFFFE0","lightyellow","255,255,224"},
  3923.  {"#FFFF00","yellow","255,255,0"},
  3924.  {"#FFFACD","lemonchiffon","255,250,205"},
  3925.  {"#F5F5DC","beige","245,245,220"},
  3926.  {"#FFEFD5","papayawhip","255,239,213"},
  3927.  {"#FAFAD2","lightgoldenrodyellow","250,250,210"},
  3928.  {"#FFE4B5","moccasin","255,228,181"},
  3929.  {"#B8860B","darkgoldenrod","184,134,11"},
  3930.  {"#FFF8DC","cornsilk","255,248,220"},
  3931.  {"#FFEBCD","blanchedalmond","255,235,205"},
  3932.  {"#FFE4C4","bisque","255,228,196"},
  3933.  {"#FFDEAD","navajowhite","255,222,173"},
  3934.  {"#F5DEB3","wheat","245,222,179"},
  3935.  {"#CD853F","peru","205,133,63"},
  3936.  {"#D2691E","chocolate","210,105,30"},
  3937.  {"#A0522D","sienna","160,82,45"},
  3938.  {"#A52A2A","brown","165,42,42"},
  3939.  {"#BC8F8F","rosybrown","188,143,143"},
  3940.  {"#F08080","lightcoral","240,128,128"},
  3941.  {"#FFA07A","lightsalmon","255,160,122"},
  3942.  {"#8B0000","darkred","139,0,0"},
  3943.  {"#800000","maroon","128,0,0"},
  3944.  {"#FAA460","sandybrown","250,164,96"},
  3945.  {"#FF7F50","coral","255,127,80"},
  3946.  {"#FF6347","tomato","255,99,71"},
  3947.  {"#FFDAB9","peachpuff","255,218,185"},
  3948.  {"#EEE8AA","palegoldenrod","238,232,170"},
  3949.  {"#F0E68C","khaki","240,230,140"},
  3950.  {"#D8BFD8","thistle","216,191,216"},
  3951.  {"#DDA0DD","plum","221,160,221"},
  3952.  {"#FF00FF","fuchsia","255,0,255"},
  3953.  {"#FF00FF","magenta","255,0,255"},
  3954.  {"#EE82EE","violet","238,130,238"},
  3955.  {"#DA70D6","orchid","218,112,214"},
  3956.  {"#BA55D3","mediumorchid","186,85,211"},
  3957.  {"#9370DB","mediumpurple","147,112,219"},
  3958.  {"#8A2BE2","blueviolet","138,43,226"},
  3959.  {"#9400D3","darkviolet","148,0,211"},
  3960.  {"#9932CC","darkorchid","153,50,204"},
  3961.  {"#8B008B","darkmagenta","139,0,139"},
  3962.  {"#800080","purple","128,0,128"},
  3963.  {"#4B0082","indigo","75,0,130"},
  3964.  {"#483D8B","darkslateblue","72,61,139"},
  3965.  {"#6A5ACD","slateblue","106,90,205"},
  3966.  {"#7B68EE","mediumslateblue","123,104,238"},
  3967.  {"#98FB98","palegreen","152,251,152"},
  3968.  {"#ADFF2F","greenyellow","173,255,47"},
  3969.  {"#7FFF00","chartreuse","127,255,0"},
  3970.  {"#7CFC00","lawngreen","124,252,0"},
  3971.  {"#00FF7F","springgreen","0,255,127"},
  3972.  {"#00FA9A","mediumspringgreen","0,250,154"},
  3973.  {"#90EE90","lightgreen","144,238,144"},
  3974.  {"#32CD32","limegreen","50,205,50"},
  3975.  {"#3CB371","mediumseagreen","60,179,113"},
  3976.  {"#2E8B57","seagreen","46,139,87"},
  3977.  {"#228B22","forestgreen","34,139,34"},
  3978.  {"#008000","green","0,128,0"},
  3979.  {"#006400","darkgreen","0,100,0"},
  3980.  {"#9ACD32","yellowgreen","154,205,50"},
  3981.  {"#6B8E23","olivedrab","107,142,35"},
  3982.  {"#808000","olive","128,128,0"},
  3983.  {"#556B2F","darkolivegreen","85,107,47"},
  3984.  {"#8FBC8F","darkseagreen","143,188,143"},
  3985.  {"#66CDAA","mediumaquamarine","102,205,170"},
  3986.  {"#20B2AA","lightseagreen","32,178,170"},
  3987.  {"#008B8B","darkcyan","0,139,139"},
  3988.  {"#008080","teal","0,128,128"},
  3989.  {"#AFEEEE","paleturquoise","175,238,238"},
  3990.  {"#40E0D0","turquoise","64,224,208"},
  3991.  {"#48D1CC","mediumturquoise","72,209,204"},
  3992.  {"#00CED1","darkturquoise","0,206,209"},
  3993.  {"#5F9EA0","cadetblue","95,158,160"},
  3994.  {"#4682B4","steelblue","70,130,180"},
  3995.  {"#B0C4DE","lightsteelblue","176,196,222"},
  3996.  {"#B0E0E6","powderblue","176,224,230"},
  3997.  {"#ADD8E6","lightblue","173,216,230"},
  3998.  {"#87CEEB","skyblue","135,206,235"},
  3999.  {"#87CEFA","lightskyblue","135,206,250"},
  4000.  {"#00BFFF","deepskyblue","0,191,255"},
  4001.  {"#1E90FF","dodgerblue","30,144,255"},
  4002.  {"#6495ED","cornflowerblue","100,149,237"},
  4003.  {"#4169E1","royalblue","65,105,225"},
  4004.  {"#0000CD","mediumblue","0,0,205"},
  4005.  {"#00008B","darkblue","0,0,139"},
  4006.  {"#000080","navy","0,0,128"},
  4007.  {"#191970","midnightblue","25,25,112"},
  4008.  {"#DCDCDC","gainsboro","220,220,220"},
  4009.  {"#D3D3D3","lightgrey","211,211,211"},
  4010.  {"#808080","grey","128,128,128"},
  4011.  {"#C0C0C0","silver","192,192,192"},
  4012.  {"#A9A9A9","darkgray","169,169,169"},
  4013.  {"#778899","lightslategray","119,136,153"},
  4014.  {"#708090","slategray","112,128,144"},
  4015.  {"#696969","dimgray","105,105,105"},
  4016.  {"#2F4F4F","darkslategray","47,79,79"},
  4017.  {"#0a0a0a","black","10,10,10"},
  4018.  {"#F5FFFA","mintcream","245,255,250"},
  4019.  {"#FFFFFF","white","255,255,255"},
  4020.  {"#F0FFF0","honeydew","240,255,240"},
  4021.  {"#F5F5F5","whitesmoke","245,245,245"},
  4022.  {"#F8F8FF","ghostwhite","248,248,255"},
  4023.  {"#FFFFF0","ivory","255,255,240"},
  4024.  {"#FFFAFA","snow","255,250,250"},
  4025.  {"#FFFAF0","floralwhite","255,250,240"},
  4026.  {"#FFF5EE","seashell","255,245,238"},
  4027.  {"#FDF5E6","oldlace","253,245,230"},
  4028.  {"#FAF0E6","linen","250,240,230"},
  4029.  {"#FAEBD7","antiquewhite","250,235,215"},
  4030.  };
  4031. int NUMBER_OF_COLORNAMES=(sizeof(colors)/sizeof(colors[0]));
  4032.  
  4033. void add_drag_code(FILE *js_include_file,int canvas_cnt,int canvas_root_id ){
  4034. /* in drag& drop / onclick library:
  4035.     obj_type = 1 == rect / rects
  4036.     obj_type = 2 == point / points (do not scale with zoom)
  4037.     obj_type = 3 == ellipse
  4038.     obj_type = 4 == polyline / segment / segments /line / vline / hline
  4039.     obj_type = 5 == closed path (polygon)
  4040.     obj_type = 6 == roundrect /roundrects
  4041.     obj_type = 7 == crosshair / crosshairs
  4042.     obj_type = 8 == arrow / arrows
  4043.     obj_type = 9 == curve
  4044.     obj_type = 10== arrow2 / arrows2
  4045.     obj_type = 11== parallel  (no drag or onclick)
  4046.     obj_type = 12== arc : radius is in pixels , so no zooming in/out
  4047.     obj_type = 13== circle / circles (will scale on zoom)
  4048.     obj_type = 14== text (will not scale or pan on zoom)
  4049.     obj_type = 15== animated point on curve
  4050.     obj_type = 16== pixels
  4051.     obj_type = 17== new arc [command angle] :radius in x-range, so will scale on zooming in/out
  4052.     obj_type = 18== halfline
  4053.     obj_type = 19== yerrorbars
  4054.     obj_type = 20== xerrorbars
  4055.    
  4056.    
  4057.     arc
  4058. x[0] = x[1] = xc = double_data[0]                                                              
  4059. y[0] = y[1] = yc = double_data[1]                                                              
  4060. w[0] = width = int_data[0]                                                                      
  4061. w[1] = height = int_data[1]                                                                    
  4062. h[0] = start_angle = double_data[2]                                                            
  4063. h[1] = end_angle = double_data[3]  
  4064.       myState.selection.line_width = org_line_width;myState.selection.font_family = org_font_family;break;\
  4065.  
  4066. use_offset only for text shape objects...
  4067.  0=none;
  4068.  1=yoffset
  4069.  2=xoffset
  4070.  3=xyoffset
  4071.  4=centered
  4072. */
  4073. fprintf(js_include_file,"\n<!-- begin drag_drop_onclick shape library -->\n\
  4074. if( typeof(dragdrop_precision) == 'undefined' ){var dragdrop_precision = 100;};\
  4075. function Shape(click_cnt,onclick,direction,type,x,y,w,h,line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype0,dashtype1,use_rotate,angle,text,font_size,font_family,use_affine,affine_matrix,slider,slider_cnt,rotation_center,use_offset,use_pattern){\
  4076. this.stroke_opacity = stroke_opacity || 1.0;\
  4077. this.stroke_color = \"rgba(\"+stroke_color+\",\"+stroke_opacity+\")\" || '#FF0000';\
  4078. this.fill_opacity = fill_opacity || 1.0;\
  4079. this.fill_color = \"rgba(\"+fill_color+\",\"+fill_opacity+\")\" || '#FF0000';\
  4080. this.use_pattern = use_pattern || 0;\
  4081. if( use_pattern > 0 ){ this.pattern = create_Pattern(x,y,this.use_pattern,this.fill_color); }else{ this.pattern = 0; }\
  4082. this.slider = slider || 0;\
  4083. this.slider_cnt = slider_cnt || 0;\
  4084. this.text = text || 0;\
  4085. this.font_size = font_size || 12;\
  4086. if( this.font_size == 12 ){ this.font_size = parseInt(font_family); };\
  4087. this.font_family = font_family || this.font_size+'px Ariel';\
  4088. this.use_rotate = use_rotate || 0;\
  4089. this.angle = angle*(Math.PI/180) || 0;\
  4090. this.use_affine = use_affine || 0;\
  4091. this.affine_matrix = affine_matrix || [1,0,0,1,0,0];\
  4092. this.click_cnt = click_cnt || 0;\
  4093. this.onclick = onclick || 0;\
  4094. if(this.onclick == 1 ){reply[click_cnt] = 0;};\
  4095. this.direction = direction || 0;\
  4096. this.type = type || 1;\
  4097. this.xorg = x;\
  4098. this.yorg = y;\
  4099. this.use_once = true;\
  4100. this.x = [x.length];\
  4101. this.y = [x.length];\
  4102. this.w = [x.length];\
  4103. this.h = [x.length];\
  4104. for(var p=0;p<x.length;p++){\
  4105.  this.x[p] = x2px(x[p]-xstart);\
  4106.  this.y[p] = y2px(y[p]-ystart);\
  4107.  if( p > w.length){\
  4108.    this.w[p] = w[0];\
  4109.    this.h[p] = h[0];\
  4110.  }\
  4111.  else\
  4112.  {\
  4113.    this.w[p] = w[p];\
  4114.    this.h[p] = h[p];\
  4115.  }\
  4116. };\
  4117. if( rotation_center != null ){\
  4118.  this.rotation_center = [x2px(rotation_center[0]),y2px(rotation_center[1])];\
  4119. }else{this.rotation_center = [this.x[0],this.y[0]];};\
  4120. this.line_width = line_width || 30;\
  4121. this.org_line_width = line_width || 30;\
  4122. this.use_filled = use_filled || 0;\
  4123. this.use_dashed = use_dashed || 0;\
  4124. this.dashtype0 = dashtype0 || 4;\
  4125. this.dashtype1 = dashtype1 || 4;\
  4126. this.use_offset = use_offset || 0;\
  4127. };\
  4128. var create_Pattern = function(x0,y0,type,color){\
  4129. document.body.style.cursor = 'wait';\
  4130. var idx = Math.ceil(1000*(Math.random()));\
  4131. var canvas = create_canvas%d(idx,xsize,ysize);\
  4132. canvas.style.visibility = 'hidden';\
  4133. var ctx = canvas.getContext(\"2d\");\
  4134. var x;var y;var dx = 6;var dy = 6;\
  4135. ctx.lineWidth = 1;\
  4136. ctx.strokeStyle = color;\
  4137. ctx.fillStyle = color;\
  4138. var pat;\
  4139. switch(type){\
  4140.  case 2: for( x = 0 ; x < xsize ; x = x + dx ){ctx.beginPath();ctx.moveTo(x,0);ctx.lineTo(x,ysize);ctx.closePath();ctx.stroke();};for( y = 0 ; y < ysize; y = y + dy ){ctx.beginPath();ctx.moveTo(0,y);ctx.lineTo(xsize,y);ctx.closePath();ctx.stroke();}; pat = ctx.createPattern(canvas,\"no-repeat\");break;\
  4141.  case 3: y = ysize;ctx.beginPath();for( x = 0 ; x < xsize ; x = x + dx ){ctx.moveTo(x,0);ctx.lineTo(xsize,y);y = y - dy;};y = 0;for( x = xsize ; x > 0 ; x = x - dx){ctx.moveTo(x,ysize);ctx.lineTo(0,y); y = y + dy;};ctx.closePath();ctx.stroke(); pat = ctx.createPattern(canvas,\"no-repeat\");break;\
  4142.  case 4: y = ysize;ctx.beginPath();for( x = 0 ; x < xsize ; x = x + dx ){ctx.moveTo(x,0); ctx.lineTo(xsize,y); y = y - dy;};y = 0;for( x = xsize ; x > 0 ; x = x - dx){ctx.moveTo(x,ysize);ctx.lineTo(0,y);y = y + dy;};y = 0;for( x = 0 ; x < xsize ; x = x + dx ){ctx.moveTo(x,0); ctx.lineTo(0,y); y = y + dy;};y = 0;for( x = 0 ; x < xsize ; x = x + dx ){ctx.moveTo(xsize,y);ctx.lineTo(x,ysize);y = y + dy;};ctx.closePath(); ctx.stroke(); pat = ctx.createPattern(canvas,\"no-repeat\");break;\
  4143.  case 5: for( x = 0 ; x < xsize ; x = x + dx ){for( y = 0 ; y < ysize ; y = y + dy ){ctx.beginPath();ctx.arc(x,y,1,0,2*Math.PI,false);ctx.closePath();ctx.fill();};}; pat = ctx.createPattern(canvas,\"no-repeat\");break;\
  4144.  case 6: alert('wait for image '+(image_cnt+1)+'...');pat = image_patterns[image_cnt];image_cnt++;break;\
  4145.  default: break;\
  4146. };\
  4147. document.body.style.cursor = 'default';\
  4148. return pat;\
  4149. };\
  4150. Shape.prototype.draw = function(ctx)\
  4151. {\
  4152. ctx.lineWidth = this.line_width;\
  4153. ctx.strokeStyle = this.stroke_color;\
  4154. if( this.use_pattern > 0 ){ ctx.fillStyle = this.pattern; }else{ ctx.fillStyle = this.fill_color; };\
  4155. ctx.lineJoin = \"round\";\
  4156. ctx.save();\
  4157. if(this.use_rotate == 1){\
  4158.   ctx.translate(this.rotation_center[0],this.rotation_center[1]);\
  4159.   ctx.rotate(this.angle);\
  4160.   ctx.translate(-1*(this.rotation_center[0]),-1*(this.rotation_center[1]));\
  4161. };\
  4162. if( this.use_affine == 1 ){\
  4163.  ctx.setTransform(this.affine_matrix[0],this.affine_matrix[1],this.affine_matrix[2],this.affine_matrix[3],this.affine_matrix[4],this.affine_matrix[5]);\
  4164. };\
  4165. ctx.beginPath();\
  4166.  switch(this.type){\
  4167.  case 1: for(var p = 0 ; p < this.x.length;p = p+4){ctx.rect(this.x[p], this.y[p], this.x[p+1]-this.x[p], this.y[p+2] - this.y[p]);};break;\
  4168.  case 2: ctx.arc(this.x[0],this.y[0],0.5*this.w[0],0,2*Math.PI,false);break;\
  4169.  case 3: ctx.save();var w = 0.5*(scale_x_radius(this.w[0]));var h = 0.5*(scale_y_radius(this.h[0]));ctx.scale(1,h/w);ctx.beginPath();ctx.arc(this.x[0], w/h*this.y[0], w, 0, 2 * Math.PI);if(this.use_filled == 1){ ctx.fillStyle = this.fill_color; ctx.fill(); };ctx.closePath();ctx.stroke();ctx.restore();break;\
  4170.  case 4: for(var p = 0; p < this.x.length - 1;p++){ctx.moveTo(this.x[p], this.y[p]);ctx.lineTo(this.x[p+1],this.y[p+1]);};break;\
  4171.  case 5: ctx.moveTo(this.x[0],this.y[0]);for(var p = 1; p < this.x.length;p++){ctx.lineTo(this.x[p],this.y[p]);};ctx.lineTo(this.x[0],this.y[0]);break;\
  4172.  case 6: var w = this.x[1] - this.x[0];var h = this.y[1] - this.y[0];var r = this.w[0];ctx.beginPath();ctx.moveTo(this.x[0] + r, this.y[0]);ctx.lineTo(this.x[0] + w - r, this.y[0]);ctx.quadraticCurveTo(this.x[0] + w, this.y[0], this.x[0] + w, this.y[0] + r);ctx.lineTo(this.x[0] + w, this.y[0] + h - r);ctx.quadraticCurveTo(this.x[0] + w, this.y[0] + h, this.x[0] + w - r, this.y[0] + h);ctx.lineTo(this.x[0] + r, this.y[0] + h);ctx.quadraticCurveTo(this.x[0], this.y[0] + h, this.x[0], this.y[0] + h - r);ctx.lineTo(this.x[0], this.y[0] + r);ctx.quadraticCurveTo(this.x[0], this.y[0], this.x[0] + r, this.y[0]);ctx.closePath();break;\
  4173.  case 7: ctx.moveTo(this.x[0]-this.w[0],this.y[0]-this.h[0]);ctx.lineTo(this.x[0]+this.w[0],this.y[0]+this.h[0]);ctx.moveTo(this.x[0]-this.w[0],this.y[0]+this.h[0]);ctx.lineTo(this.x[0]+this.w[0],this.y[0]-this.h[0]);break;\
  4174.  case 8: var dx;var dy;var len;var arrow_head = this.w[0];for(var p = 0; p < this.x.length - 1;p++){ctx.save();if(this.use_dashed == 1 ){if( ctx.setLineDash ){ ctx.setLineDash([this.dashtype0,this.dashtype1]);}else{ ctx.mozDash = [this.dashtype0,this.dashtype1];};};dx = this.x[p+1] - this.x[p];dy = this.y[p+1] - this.y[p];len = Math.sqrt(dx*dx+dy*dy);ctx.translate(this.x[p+1],this.y[p+1]);ctx.rotate(Math.atan2(dy,dx));ctx.lineCap = \"round\";ctx.beginPath();ctx.moveTo(0,0);ctx.lineTo(-len,0);ctx.closePath();ctx.stroke();ctx.beginPath();ctx.moveTo(0,0);ctx.lineTo(-1*arrow_head,-0.5*arrow_head);ctx.lineTo(-1*arrow_head, 0.5*arrow_head);ctx.closePath();ctx.fill();ctx.restore();};break;\
  4175.  case 9: ctx.moveTo(this.x[0], this.y[0]);for(var p = 1; p < this.x.length - 1;p++){if( Math.abs(this.y[p] - this.y[p-1]) < ysize && Math.abs(this.y[p+1] - this.y[p]) < ysize ){ctx.lineTo(this.x[p],this.y[p]);}else{ctx.moveTo(this.x[p],this.y[p]);};};break;\
  4176.  case 10: var dx;var dy;var len;ctx.save();if(this.use_dashed == 1 ){if( ctx.setLineDash ){ ctx.setLineDash([this.dashtype0,this.dashtype1]);}else{ ctx.mozDash = [this.dashtype0,this.dashtype1];};};dx = this.x[1] - this.x[0];dy = this.y[1] - this.y[0];len = Math.sqrt(dx*dx+dy*dy);ctx.translate(this.x[1],this.y[1]);ctx.rotate(Math.atan2(dy,dx));ctx.beginPath();ctx.moveTo(0,0);ctx.lineTo(-len,0);ctx.closePath();ctx.stroke();ctx.beginPath();ctx.moveTo(0,0);ctx.lineTo(-1*this.w[0],0.5*this.w[0]);ctx.lineTo(-1*this.w[0],-0.5*this.w[0]);ctx.closePath();ctx.lineCap = \"round\";ctx.fill();ctx.restore();ctx.save();ctx.translate(this.x[0],this.y[0]);ctx.rotate(Math.atan2(dy,dx));ctx.beginPath();ctx.moveTo(0,0);ctx.lineTo(this.w[0],0.4*this.w[0]);ctx.lineTo(this.w[0],-0.4*this.w[0]);ctx.closePath();ctx.lineCap = \"round\";ctx.fill(); break;\
  4177.  case 11: var x1 = this.x[0];var y1 = this.y[0];var x2 = this.x[1];var y2 = this.y[1];var dx = this.x[2];var dy = this.y[2];var n  = this.w[0];for(var p = 0 ; p < n ; p++ ){ctx.beginPath();ctx.moveTo(x1,y1);ctx.lineTo(x2,y2);ctx.stroke();x1 = x1 + dx;y1 = y1 + dy;x2 = x2 + dx;y2 = y2 + dy;ctx.closePath();};break;\
  4178.  case 12: ctx.save();var start;var end;if(this.h[0] < this.h[1]){start = this.h[0];end = this.h[1]}else{start = this.h[1];end = this.h[0];};start=360-start;end=360-end;var w = 0.5*(scale_x_radius(this.w[0]));var h = 0.5*(scale_y_radius(this.w[1]));ctx.scale(1,h/w);ctx.arc(this.x[0], w/h*this.y[0], w,start*(Math.PI / 180), end*(Math.PI / 180),true);ctx.stroke();if(this.use_filled == 1){ ctx.fillStyle = this.fill_color; ctx.lineTo(this.x[0],this.y[0]);ctx.fill(); };ctx.restore();break;\
  4179.  case 13: for(var p = 0; p < this.x.length; p++){ ctx.arc(this.x[p],this.y[p],scale_x_radius(this.w[p]),0,2*Math.PI,false);};break;\
  4180.  case 14: if( this.font_family == null ){ ctx.font = this.font_size+\"px Ariel\";}else{ctx.font = this.font_family ;};\
  4181.  if( this.use_offset > 0 && this.use_once == true ){\
  4182.  this.use_once = false;if(this.use_offset == 1){this.y[0] = this.y[0] - 0.4*(this.font_size);}\
  4183.  else{if(this.use_offset == 2){this.x[0] = this.x[0] + 0.5*ctx.measureText('i').width;}\
  4184.  else{if(this.use_offset == 3){this.y[0] = this.y[0] - 0.4*(this.font_size);this.x[0] = this.x[0] + 0.5*ctx.measureText(\"W\").width;}\
  4185.  else{if(this.use_offset == 4){this.y[0] = this.y[0] + 0.4*(this.font_size);this.x[0] = this.x[0] - 0.5*(ctx.measureText(this.text).width);};};};};};\
  4186.  ctx.fillText(this.text,this.x[0],this.y[0]);break;\
  4187.  case 15: break;\
  4188.  case 16: for(var p = 0; p < this.x.length;p++){ctx.fillRect( this.x[p], this.y[p],this.line_width,this.line_width );};break;\
  4189.  case 17: ctx.save();var start;var end;if(this.h[0] < this.h[1]){start = this.h[0];end = this.h[1]}else{start = this.h[1];end = this.h[0];};start=360-start;end=360-end;var r = scale_x_radius(this.w[0]);ctx.arc(this.x[0], this.y[0], r, start*(Math.PI / 180), end*(Math.PI / 180),true);if(this.use_filled){ctx.lineTo(this.x[0],this.y[0]);ctx.fill();};ctx.restore();break;\
  4190.  case 18: for(var p=0 ; p < this.x.length ;p=p+2){ctx.moveTo(this.x[p], this.y[p]);ctx.lineTo(this.x[p+1],this.y[p+1]);};break;\
  4191.  case 19: ctx.arc(this.x[0],this.y[0],this.line_width,0,2*Math.PI,false);var E1 = y2px(px2y(this.y[0]) - this.h[0]);var E2 = y2px(px2y(this.y[0]) + this.w[0]);ctx.moveTo(this.x[0],E1);ctx.lineTo(this.x[0],E2);ctx.moveTo(this.x[0] - 2*(this.line_width),E1);ctx.lineTo(this.x[0] + 2*(this.line_width),E1);ctx.moveTo(this.x[0] - 2*(this.line_width),E2);ctx.lineTo(this.x[0] + 2*(this.line_width),E2);break;\
  4192.  case 20: ctx.arc(this.x[0],this.y[0],this.line_width,0,2*Math.PI,false);var E1 = x2px(px2x(this.x[0]) - this.w[0]);var E2 = x2px(px2x(this.x[0]) + this.h[0]);ctx.moveTo(E1,this.y[0]);ctx.lineTo(E2,this.y[0]);ctx.moveTo(E1,this.y[0]-2*(this.line_width));ctx.lineTo(E1,this.y[0]+2*(this.line_width));ctx.moveTo(E2,this.y[0]-2*(this.line_width));ctx.lineTo(E2,this.y[0]+2*(this.line_width));break;\
  4193.  default: alert(\"draw primitive unknown\");break;\
  4194. };\
  4195. if(this.use_filled == 1){ ctx.fill();}\
  4196. if(this.use_dashed == 1 ){if( ctx.setLineDash ){ ctx.setLineDash([this.dashtype0,this.dashtype1]);}else{ ctx.mozDash = [this.dashtype0,this.dashtype1];};};\
  4197. ctx.stroke();\
  4198. ctx.restore();\
  4199. };\
  4200. Shape.prototype.contains = function(mx, my){\
  4201. var marge = 2*this.line_width;\
  4202. switch(this.type){\
  4203.  case 1: for(var p = 0 ; p < this.x.length; p++ ){if( mx < this.x[p] + marge &&  mx > this.x[p] - marge ){if( my < this.y[p]+marge && my > this.y[p] - marge ){return p;};};};break;\
  4204.  case 2: for(var p = 0 ; p < this.x.length; p++ ){if( Math.abs(distance(this.x[p],this.y[p],mx,my) ) < this.w[p] + 4*marge ){return p;break;};};break;\
  4205.  case 3: for(var p = 0 ; p < this.x.length; p++ ){if( Math.abs(distance(this.x[p],this.y[p],mx,my) ) < scale_x_radius(this.w[p]) + marge ){return p;break;};};break;\
  4206.  case 4: var diff;var q;var r;for(var p = 0 ; p < this.x.length-1; p = p+2  ){if( ((this.x[p+1] - this.x[p]) != 0)  && ((this.y[p+1]-this.y[p]) != 0) ){r = (this.y[p+1]-this.y[p])/(this.x[p+1]-this.x[p]);q = this.y[p] - (r)*(this.x[p]);diff = distance_to_line(r,q,mx,my);}else{if( (this.y[p+1]-this.y[p]) != 0 ){diff = Math.abs(this.x[p] - mx);}else{diff = Math.abs(this.y[p] - my);};};if( diff  < marge ){ return p;};}; break;\
  4207.  case 5: marge = 2*marge;for(var p = 0 ; p < this.x.length; p++ ){if( mx < this.x[p] + marge &&  mx > this.x[p] - marge ){if( my < this.y[p]+marge && my > this.y[p] - marge ){return p;};};};break;\
  4208.  case 6: marge = 0.5*this.w[0];for(var p = 0 ; p < this.x.length; p++ ){if( mx < this.x[p] + marge &&  mx > this.x[p] - marge ){if( my < this.y[p]+marge && my > this.y[p] - marge ){return p;};};};break;\
  4209.  case 7: for(var p = 0 ; p < this.x.length; p++ ){if( (this.x[p] - this.w[p] <= mx) && (this.x[p] + this.w[p] >= mx) &&  (this.y[p] - this.h[p] <= my) && (this.y[p] + this.h[p] >= my) ){return p;};};break;\
  4210.  case 8: var diff;var q;var r;for(var p = 0 ; p < this.x.length-1; p = p+2  ){if( ((this.x[p+1] - this.x[p]) != 0)  && ((this.y[p+1]-this.y[p]) != 0) ){r = (this.y[p+1]-this.y[p])/(this.x[p+1]-this.x[p]);q = this.y[p] - (r)*(this.x[p]);diff = distance_to_line(r,q,mx,my);}else{if( (this.y[p+1]-this.y[p]) != 0 ){diff = Math.abs(this.x[p] - mx);}else{diff = Math.abs(this.y[p] - my);};};if( diff  < marge ){ return p;};}; break;\
  4211.  case 9: for(var p = 0 ; p < this.x.length; p++ ){if( (this.x[p] - this.line_width <= mx) && (this.x[p] + this.w[p] + this.line_width >= mx) &&  (this.y[p] - this.line_width <= my) && (this.y[p] + this.h[p] +this.line_width  >= my) ){return p;};};break;\
  4212.  case 10: var diff;var q;var r;for(var p = 0 ; p < this.x.length-1; p = p+2  ){if( ((this.x[p+1] - this.x[p]) != 0)  && ((this.y[p+1]-this.y[p]) != 0) ){r = (this.y[p+1]-this.y[p])/(this.x[p+1]-this.x[p]);q = this.y[p] - (r)*(this.x[p]);diff = distance_to_line(r,q,mx,my);}else{if( (this.y[p+1]-this.y[p]) != 0 ){diff = Math.abs(this.x[p] - mx);}else{diff = Math.abs(this.y[p] - my);};};if( diff  < marge ){ return p;};}; break;\
  4213.  case 11: break;\
  4214.  case 12: break;\
  4215.  case 13: for(var p = 0 ; p < this.x.length; p++ ){if( Math.abs(distance(this.x[p],this.y[p],mx,my) ) < scale_x_radius(this.w[p]) + marge ){return p;break;};};break;\
  4216.  case 14: for(var p = 0 ; p < this.x.length; p++ ){if(this.y[p] < my + 0.5*(this.font_size) && this.y[p] > my - 0.5*(this.font_size)){var w = parseInt(0.8*(this.font_size)*((this.text).length));if(this.x[p] < mx + w && this.x[p] > mx - w ){ return p;break;};};};break;\
  4217.  case 15: break;\
  4218.  case 16: break;\
  4219.  case 17: break;\
  4220.  case 18: var diff;var q;var r;if(((this.x[1] - this.x[0]) != 0) && ((this.y[1]-this.y[0]) != 0)){r = (this.y[1]-this.y[0])/(this.x[1]-this.x[0]);q = this.y[0] - (r)*(this.x[0]);diff = distance_to_line(r,q,mx,my);}else{if((this.y[1]-this.y[0])!= 0){diff = Math.abs(this.x[0] - mx);}else{diff = Math.abs(this.y[0] - my);};};if( diff  < marge ){ return 0;};break;\
  4221.  default: for(var p = 0 ; p < this.x.length; p++ ){if( (this.x[p] - this.line_width <= mx) && (this.x[p] + this.w[p] + this.line_width >= mx) &&  (this.y[p] - this.line_width <= my) && (this.y[p] + this.h[p] +this.line_width  >= my) ){return p;};};break;\
  4222. };\
  4223. return -1;\
  4224. };\
  4225. var reply = [];\
  4226. function CanvasState(canvas,container_div){\
  4227. this.canvas = canvas;\
  4228. this.width = canvas.width;\
  4229. this.height = canvas.height;\
  4230. var ctx = canvas.getContext(\"2d\");\
  4231. this.ctx = ctx;\
  4232. this.valid = false;\
  4233. this.shapes = [];\
  4234. this.moved = [];\
  4235. this.dragging = false;\
  4236. this.selection = null;\
  4237. var myState = this;\
  4238. container_div.addEventListener( 'mouseup'    , mouseup,  false);\
  4239. container_div.addEventListener( 'mousemove'  , mousemove,false);\
  4240. container_div.addEventListener( 'mousedown'  , mousedown,false);\
  4241. container_div.addEventListener('touchstart'  , function(e) { e.preventDefault(); mousedown(e.changedTouches[0]);},false);\
  4242. container_div.addEventListener( 'touchmove'  , function(e) { e.preventDefault(); mousemove(e.changedTouches[0]);},false);\
  4243. container_div.addEventListener( 'touchend'   , function(e) { e.preventDefault(); mouseup(  e.changedTouches[0]);},false);\
  4244. function mousedown(e){\
  4245.  var mouse = myState.getMouse(e,canvas);\
  4246.  var mx = mouse.x;\
  4247.  var my = mouse.y;\
  4248.  if( use_pan_and_zoom == 1 && my > ysize - 15){\
  4249.   check_zoom_or_pan(mx);\
  4250.  }\
  4251.  else\
  4252.  {\
  4253.   if( wims_status == \"done\"){return null;};\
  4254.   var shapes = myState.shapes;\
  4255.   var l = shapes.length;\
  4256.   var chk = -1;\
  4257.   for(var i=0;i<l;i++){\
  4258.    chk = shapes[i].contains(mx, my);\
  4259.    if ( chk != -1 ){\
  4260.     if( myState.moved[shapes[i].click_cnt] != 1){\
  4261.      myState.moved[shapes[i].click_cnt] = 1;\
  4262.      myState.x_start = shapes[i].x[chk];\
  4263.      myState.y_start = shapes[i].y[chk];\
  4264.     };\
  4265.     myState.chk = chk;\
  4266.     myState.selection = shapes[i];\
  4267.     myState.valid = false;\
  4268.     switch(shapes[i].onclick){\
  4269.      case 0: myState.dragging = false;break;\
  4270.      case 1: \
  4271.       if( reply[myState.selection.click_cnt] == 0 ){\
  4272.        myState.selection.line_width = 3*(myState.selection.org_line_width);\
  4273.        reply[myState.selection.click_cnt] = 1;\
  4274.       }else{ reply[myState.selection.click_cnt] = 0;myState.selection.line_width = myState.selection.org_line_width;};\
  4275.       myState.dragging = false;myState.draw();\
  4276.       break;\
  4277.      case 2: myState.dragging = true;break;\
  4278.      default:break;\
  4279.     };\
  4280.     return;\
  4281.    };\
  4282.   };\
  4283.  };\
  4284.  myState.selection = null;\
  4285.  myState.valid = true;\
  4286.  return;\
  4287. };\
  4288. function mouseup(e){;\
  4289.  if(myState.selection != null ){\
  4290.   if(myState.selection.onclick == 2 ){\
  4291.    if( x_use_snap_to_grid == 1 || y_use_snap_to_grid == 1 || use_snap_to_points != 0){\
  4292.     var mouse = myState.getMouse(e,canvas);\
  4293.     var dx=mouse.x;\
  4294.     var dy=mouse.y;\
  4295.     if( use_snap_to_points != 0){\
  4296.      var xy = new Array(2);\
  4297.      if(use_snap_to_points == 1 ){\
  4298.       xy = snap_to_points(dx,dy);\
  4299.      }\
  4300.      else\
  4301.      {\
  4302.       xy = snap_to_fun(dx,dy);\
  4303.      };\
  4304.      dx = xy[0] - myState.selection.x[myState.chk];\
  4305.      dy = xy[1] - myState.selection.y[myState.chk];\
  4306.     }\
  4307.     else\
  4308.     {\
  4309.      if( x_use_snap_to_grid == 1 && y_use_snap_to_grid == 1 ){ \
  4310.       dx = snap_to_x(dx) - myState.selection.x[myState.chk];\
  4311.       dy = snap_to_y(dy) - myState.selection.y[myState.chk];\
  4312.      }else{\
  4313.       if( x_use_snap_to_grid == 1 ){ \
  4314.        dx = snap_to_x(dx) - myState.selection.x[myState.chk];\
  4315.        dy = 0;\
  4316.       }\
  4317.       else\
  4318.       {\
  4319.        dx = 0;\
  4320.        dy = snap_to_y(dy) - myState.selection.y[myState.chk];\
  4321.       };\
  4322.      };\
  4323.     };\
  4324.     switch(myState.selection.direction){\
  4325.      case 0: myState.selection = move(myState.selection,dx,dy);break;\
  4326.      case 1: myState.selection = move(myState.selection,dx,0);break;\
  4327.      case 2: myState.selection = move(myState.selection,0,dy); break;\
  4328.     };\
  4329.    };\
  4330.    reply[myState.selection.click_cnt] = myState.selection.click_cnt+\":\"+px2x(myState.x_start)+\":\"+px2y(myState.y_start)+\":\"+(Math.round(dragdrop_precision*(px2x(myState.selection.x[myState.chk]))))/dragdrop_precision+\":\"+(Math.round(dragdrop_precision*(px2y(myState.selection.y[myState.chk]))))/dragdrop_precision;\
  4331.    myState.valid = false;\
  4332.    myState.draw();\
  4333.    myState.valid = true;\
  4334.   };\
  4335.  };\
  4336.  myState.dragging = false;\
  4337. };\
  4338. function mousemove(e){\
  4339.  if(myState.dragging){\
  4340.   var mouse = myState.getMouse(e,canvas);\
  4341.   var dx=mouse.x - myState.selection.x[myState.chk];\
  4342.   var dy=mouse.y - myState.selection.y[myState.chk];\
  4343.   switch(myState.selection.direction){\
  4344.    case 0: myState.selection = move(myState.selection,dx,dy);break;\
  4345.    case 1: myState.selection = move(myState.selection,dx,0);break;\
  4346.    case 2: myState.selection = move(myState.selection,0,dy); break;\
  4347.    default:break;\
  4348.   };\
  4349.   myState.valid = false;\
  4350.  };\
  4351. };\
  4352. function check_zoom_or_pan(x){\
  4353.  var key = -1;\
  4354.  for(var p = 15 ; p < 106 ; p = p+15){\
  4355.    key++;\
  4356.    if(x > xsize - p){start_canvas%d(key);return;}\
  4357.  }\
  4358.  return;\
  4359. };\
  4360. this.interval = 30;\
  4361. setInterval(function() { myState.draw(); }, myState.interval);\
  4362. };\
  4363. CanvasState.prototype.addShape = function(shape){\
  4364. this.shapes.push(shape);\
  4365. this.valid = false;\
  4366. };\
  4367. CanvasState.prototype.clear = function(){\
  4368. this.ctx.clearRect(0, 0, this.width, this.height);\
  4369. };\
  4370. CanvasState.prototype.draw = function(){\
  4371. if(this.valid == false ){\
  4372.  var shapes = this.shapes;\
  4373.  this.clear();\
  4374.  var l = shapes.length;var shape;\
  4375.  for(var i = 0; i < l; i++){\
  4376.   shape = shapes[i];\
  4377.   shape.draw(this.ctx);\
  4378.  };\
  4379.  this.valid = true;\
  4380. }\
  4381. };\
  4382. CanvasState.prototype.Slide = function(slider_value,slider_count){\
  4383. this.ctx.clearRect(0,0,xsize,ysize);\
  4384. var what;var len = this.shapes.length;var shape;var lu;\
  4385. for(var i = 0; i < len ; i++){\
  4386.  if( this.shapes[i] ){\
  4387.   shape = this.shapes[i];\
  4388.   if( shape.slider != 0 ){\
  4389.    if(shape.slider_cnt == slider_count ){\
  4390.     what = shape.slider;\
  4391.     lu = shape.x.length;\
  4392.     reply[shape.click_cnt] = shape.click_cnt+\":\"+slider_value;\
  4393.     switch(what){\
  4394.      case 3: if(shape.type == 12 || shape.type == 17){\
  4395.       shape.h[1] = 180*slider_value[0]/Math.PI;}\
  4396.       else\
  4397.       {shape.use_rotate = 1;shape.angle = -1*slider_value[1];};break;\
  4398.      default:slide(shape,slider_value[0],slider_value[1]);break;\
  4399.     };\
  4400.    };\
  4401.   };\
  4402.   this.valid = false;\
  4403.   shape.draw(this.ctx);\
  4404.  };\
  4405. };\
  4406. };\
  4407. CanvasState.prototype.Zoom = function(xmin,xmax,ymin,ymax){\
  4408. (this.ctx).clearRect(0,0,this.width,this.height);\
  4409. var len = this.shapes.length;var shape;\
  4410. for(var i = 0; i < len ; i++){\
  4411.  shape = this.shapes[i];\
  4412.  for(var p = 0 ; p < shape.x.length;p++){\
  4413.   shape.x[p] = x2px(shape.xorg[p]);\
  4414.   shape.y[p] = y2px(shape.yorg[p]);\
  4415.  }\
  4416.  this.valid = false;\
  4417.  shape.draw(this.ctx);\
  4418. };\
  4419. };\
  4420. CanvasState.prototype.getMouse = function(e,element){\
  4421. var mx,my;var offsetX = 0,offsetY = 0;\
  4422.  while( ( element = element.offsetParent) ){\
  4423.   offsetX += element.offsetLeft;\
  4424.   offsetY += element.offsetTop;\
  4425.  };\
  4426. if(isTouch){\
  4427.  mx = e.pageX - offsetX;\
  4428.  my = e.pageY - offsetY;\
  4429. }\
  4430. else\
  4431. {\
  4432.  mx = e.clientX - offsetX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);\
  4433.  my = e.clientY - offsetY + (document.documentElement.scrollTop ? document.documentElement.scrollTop :document.body.scrollTop);\
  4434. };\
  4435. return {x: mx, y: my};\
  4436. };\
  4437. CanvasState.prototype.read_dragdrop = function(){\
  4438. if( wims_status == \"done\" || use_dragdrop_reply == -1 ){return null;};\
  4439. var moved_objects = new Array();\
  4440. var c = 0;\
  4441. for(var p = 0 ; p < reply.length ; p++){\
  4442.  if( reply[p] != null ){\
  4443.   moved_objects[c] = reply[p];\
  4444.   c++;\
  4445.  };\
  4446. }\
  4447. return moved_objects;\
  4448. };\
  4449. var obj = create_canvas%d(%d,xsize,ysize);\
  4450. var container_div = document.getElementById(\"canvas_div%d\");\
  4451. var dragstuff = new CanvasState(obj,container_div);\
  4452. read_dragdrop%d = dragstuff.read_dragdrop;\n",canvas_root_id,canvas_root_id,canvas_root_id,DRAG_CANVAS,canvas_root_id,canvas_root_id);
  4453. }
  4454.  
  4455. /*
  4456. #define BG_CANVAS 0 may be used for floodfill
  4457. #define STATIC_CANVAS 1 may be used for floodfill
  4458. #define MOUSE_CANVAS 2 xx
  4459. #define GRID_CANVAS 3 may be used for floodfill
  4460. #define DRAG_CANVAS 4 default for floodfill
  4461. #define DRAW_CANVAS 5 may be used for floodfill
  4462.  
  4463. */
  4464. void add_js_clickfill(FILE *js_include_file,int canvas_root_id,char *clickcolor,int opacity){
  4465. fprintf(js_include_file,"\n<!-- begin command clickfill -->\n\
  4466. function user_drag(evt){return;};\
  4467. if( typeof(fill_canvas_no) != 'object' ){ var fill_canvas_no = []; };\
  4468. fill_canvas_no.push(%d);\
  4469. function user_draw(evt){\
  4470. var mouse = dragstuff.getMouse(evt,canvas_userdraw);\
  4471. var x = mouse.x;\
  4472. var y = mouse.y;\
  4473. if( use_snap_to_points != 0 ){\
  4474.  var xy = new Array(2);\
  4475.  if( use_snap_to_points == 1 ){\
  4476.   xy = snap_to_points(x,y);\
  4477.  }\
  4478.  else\
  4479.  {\
  4480.   xy = snap_to_fun(x,y);\
  4481.  };\
  4482.  x = xy[0];y = xy[1];\
  4483. }\
  4484. else\
  4485. {\
  4486.  if( x_use_snap_to_grid == 1 ){\
  4487.    x = snap_to_x(x);\
  4488.  };\
  4489.  if( y_use_snap_to_grid == 1 ){\
  4490.   y = snap_to_y(y);\
  4491.  };\
  4492. };\
  4493. var len = fill_canvas_no.length;\
  4494. var last = fill_canvas_no[len - 1];\
  4495. var color = [ %s,%d ];\
  4496. if( typeof(multifillcolors) === 'object'){\
  4497.  var numx = userdraw_x.length;var numc = multifillcolors.length-1;var num = numx%%numc;\
  4498.  var tc = (multifillcolors[num]).split(',');\
  4499.  color = [ tc[0],tc[1],tc[2],%d ];\
  4500.  if( typeof( palettecolors ) === 'object'){\
  4501.   var idx = palettecolors.indexOf( multifillcolors[num]);\
  4502.   userdraw_radius.push(idx);\
  4503.  }else{ userdraw_radius.push(num);};\
  4504. }\
  4505. else\
  4506. {\
  4507.  userdraw_radius.push(0);\
  4508. };\
  4509. document.body.style.cursor = 'wait';\
  4510. var special_ctx;\
  4511. var use_special = false;\
  4512. if( typeof(grid_fill_pattern) != 'undefined' ){\
  4513.  special_ctx = grid_fill_pattern;\
  4514.  use_special = true;\
  4515. };\
  4516. if( typeof(diamond_fill_pattern) != 'undefined' ){\
  4517.  special_ctx = diamond_fill_pattern;\
  4518.  use_special = true;\
  4519. };\
  4520. if( typeof(hatch_fill_pattern) != 'undefined' ){\
  4521.  special_ctx = hatch_fill_pattern;\
  4522.  use_special = true;\
  4523. };\
  4524. if( typeof(dot_fill_pattern) != 'undefined' ){\
  4525.  special_ctx = dot_fill_pattern;\
  4526.  use_special = true;\
  4527. };\
  4528. if( typeof(text_fill_pattern) != 'undefined' ){\
  4529.  special_ctx = text_fill_pattern;\
  4530.  use_special = true;\
  4531. };\
  4532. if( use_special ){\
  4533.  setTimeout(function(){ filltoborder( px2x(mouse.x),px2y(mouse.y),color,color,last,true,special_ctx);},500);\
  4534. }\
  4535. else\
  4536. {\
  4537.  setTimeout(function(){ filltoborder( px2x(mouse.x),px2y(mouse.y),color,color,last,false,null);},500);\
  4538. };\
  4539. fill_canvas_no.push(last+1);\
  4540. userdraw_x.push(x);\
  4541. userdraw_y.push(y);\
  4542. document.body.style.cursor = 'default';\
  4543. return;\
  4544. };",CLICKFILL_CANVAS,clickcolor,opacity,opacity);
  4545. }
  4546.  
  4547. /* 10/2016 does not react to border color !! just any border will stop the filling */
  4548. void add_js_filltoborder(FILE *js_include_file,int canvas_root_id,int canvas_type){
  4549. fprintf(js_include_file,"\n<!-- begin command filltoborder -->\n\
  4550. var filltoborder = function(xs,ys,bordercolor,color,fill_canvas_no,use_special_filling,fill_ctx){\
  4551. document.body.style.cursor = 'wait';\
  4552. var canvas = document.getElementById(\"wims_canvas%d%d\");\
  4553. if( ! canvas ){ return; };\
  4554. document.body.style.cursor = 'wait';\
  4555. var ctx = canvas.getContext(\"2d\");\
  4556. ctx.save();\
  4557. xs = x2px(xs);\
  4558. ys = y2px(ys);\
  4559. if( xs < 0 || xs > xsize || ys < 0 || ys > ysize ){ document.body.style.cursor = 'default';return; };\
  4560. var image = ctx.getImageData(0, 0, xsize, ysize);\
  4561. var imageData = image.data;\
  4562. var pixelStack = [[xs, ys]];\
  4563. var px1;\
  4564. var newPos;\
  4565. var pixelPos;\
  4566. var found_left_border;\
  4567. var found_right_border;\
  4568. function _getPixel(pixelPos){\
  4569.  return {r:imageData[pixelPos], g:imageData[pixelPos+1], b:imageData[pixelPos+2], a:imageData[pixelPos+3]};\
  4570. };\
  4571. var _setPixel;\
  4572. if( use_special_filling ){\
  4573.  var fill_image = fill_ctx.getImageData(0, 0, xsize, ysize);\
  4574.  var fill_data = fill_image.data;\
  4575.  _setPixel = function(pixelPos){\
  4576.   var n;var o;\
  4577.   for(var p = 0;p < 3; p++){\
  4578.    n = fill_data[pixelPos+p];\
  4579.    o = imageData[pixelPos+p];\
  4580.    if( n != o ){ imageData[pixelPos+p] = n; } else { if( o == 255 ){ o = 253;} imageData[pixelPos+p] = o+1;};\
  4581.   };\
  4582.   imageData[pixelPos+3] = 255;\
  4583.  };\
  4584. }\
  4585. else\
  4586. {\
  4587.  _setPixel = function(pixelPos){\
  4588.   imageData[pixelPos] = color.r;\
  4589.   imageData[pixelPos+1] = color.g;\
  4590.   imageData[pixelPos+2] = color.b;\
  4591.   imageData[pixelPos+3] = color.a;\
  4592.  };\
  4593. };\
  4594. function _comparePixel(px2){\
  4595.  if(px2.r === px1.r && px2.g === px1.g && px2.b === px1.b ){ return true;};\
  4596.  return false;\
  4597. };\
  4598. px1 = _getPixel(((ys * xsize) + xs) * 4);\
  4599. color = {\
  4600.  r: parseInt(color[0], 10),\
  4601.  g: parseInt(color[1], 10),\
  4602.  b: parseInt(color[2], 10),\
  4603.  a: parseInt(color[3] || 255, 10)\
  4604. };\
  4605. bordercolor = {\
  4606.  r: parseInt(bordercolor[0], 10),\
  4607.  g: parseInt(bordercolor[1], 10),\
  4608.  b: parseInt(bordercolor[2], 10),\
  4609.  a: parseInt(bordercolor[3] || 255, 10)\
  4610. };\
  4611. if( _comparePixel(color) ) { return true; }\
  4612. while (pixelStack.length) {\
  4613.  newPos = pixelStack.pop();\
  4614.  xs = newPos[0];ys = newPos[1];\
  4615.  pixelPos = (ys*xsize + xs) * 4;\
  4616.  while(ys >= 0 && _comparePixel(_getPixel(pixelPos))){\
  4617.   ys -= 1;\
  4618.   pixelPos -= xsize * 4;\
  4619.  }\
  4620.  pixelPos += xsize * 4;\
  4621.  ys += 1;\
  4622.  found_left_border = false;\
  4623.  found_right_border = false;\
  4624.  while( ys <= ysize-1 && _comparePixel(_getPixel(pixelPos))  ){\
  4625.   ys += 1;\
  4626.   _setPixel(pixelPos);\
  4627.   if( xs > 1 ){\
  4628.    if( _comparePixel(_getPixel(pixelPos - 4)) ){\
  4629.    if( !found_left_border ){\
  4630.     pixelStack.push( [xs - 1, ys] );\
  4631.     found_left_border = true;\
  4632.    };\
  4633.   }\
  4634.   else if( found_left_border ){\
  4635.     found_left_border = false;\
  4636.    }\
  4637.   }\
  4638.   if( xs < xsize - 1 ){\
  4639.    if( _comparePixel(_getPixel(pixelPos + 4)) ){\
  4640.     if( !found_right_border){\
  4641.      pixelStack.push( [xs + 1, ys] );\
  4642.      found_right_border = true;\
  4643.     }\
  4644.    }\
  4645.    else if(found_right_border){\
  4646.      found_right_border = false;\
  4647.     }\
  4648.    }\
  4649.   pixelPos += xsize * 4;\
  4650.  }\
  4651. };\
  4652. var fill_canvas = create_canvas%d(fill_canvas_no,xsize,ysize);\
  4653. var fill_canvas_ctx = fill_canvas.getContext(\"2d\");\
  4654. fill_canvas_ctx.clearRect(0,0,xsize,ysize);\
  4655. fill_canvas_ctx.putImageData(image, 0, 0);\
  4656. document.body.style.cursor = 'default';};",canvas_root_id,canvas_type,canvas_root_id);
  4657. }
  4658.  
  4659. void add_js_ruler(FILE *js_include_file,
  4660. int canvas_root_id,double x,double y,double sizex,double sizey,char *font,
  4661. char *stroke_color,double stroke_opacity,char *fill_color,double fill_opacity,
  4662. int line_width,int dynamic){
  4663.  fprintf(js_include_file,"\n<!-- begin command ruler -->\n\
  4664. var ruler_data = new Array(3);\
  4665. var ruler%d = function(){\
  4666.  var full = 2*Math.PI;\
  4667.  var once = true;\
  4668.  var canvas = create_canvas%d(3000,xsize,ysize);\
  4669.  var ctx = canvas.getContext(\"2d\");\
  4670.  var canvas_temp =  document.createElement(\"canvas\");\
  4671.  var size_x = xsize*(%f)/(xmax - xmin);\
  4672.  var size_y = ysize*(%f)/(ymax - ymin);\
  4673.  var dx = xsize/(xmax - xmin);\
  4674.  var dy = 0.8*ysize/(ymax - ymin);\
  4675.  canvas_temp.width = xsize;\
  4676.  canvas_temp.height = ysize;\
  4677.  var ctx_temp = canvas_temp.getContext(\"2d\");\
  4678.  var xcenter = x2px(%f);\
  4679.  var ycenter = y2px(%f);\
  4680.  var ruler_x = xcenter;\
  4681.  var ruler_y = ycenter;\
  4682.  ctx_temp.font = \"%s\";\
  4683.  ctx_temp.strokeStyle = \"rgba(%s,%f)\";\
  4684.  ctx_temp.fillStyle = \"rgba(%s,%f)\";\
  4685.  ctx_temp.lineWidth = %d;\
  4686.  ctx_temp.save();\
  4687.  if(once){\
  4688.   ctx_temp.beginPath();\
  4689.   ctx_temp.moveTo(ruler_x,ruler_y);\
  4690.   ctx_temp.lineTo(ruler_x+size_x,ruler_y);\
  4691.   ctx_temp.lineTo(ruler_x+size_x,ruler_y-size_y);\
  4692.   ctx_temp.lineTo(ruler_x,ruler_y-size_y);\
  4693.   ctx_temp.lineTo(ruler_x,ruler_y);\
  4694.   ctx_temp.closePath();\
  4695.   ctx_temp.fill();\
  4696.   ctx_temp.stroke();\
  4697.   ctx_temp.fillStyle = ctx_temp.strokeStyle;\
  4698.   var txtsize;\
  4699.   var num = 1;\
  4700.   for(var p = dx ; p < size_x ; p = p+dx){\
  4701.     txtsize = 0.5*(ctx_temp.measureText(num).width);\
  4702.     ctx_temp.fillText(num,ruler_x + p -txtsize,ruler_y - 0.9*dy);\
  4703.     num++;\
  4704.   };\
  4705.   ctx_temp.strokeStyle = \"rgba(0,0,255,0.6)\";\
  4706.   ctx_temp.lineWidth = 2;\
  4707.   for(var p = 0; p < size_x ; p = p+dx){\
  4708.    ctx_temp.beginPath();\
  4709.    ctx_temp.moveTo(ruler_x+p,ruler_y);\
  4710.    ctx_temp.lineTo(ruler_x+p,ruler_y-0.8*dy);\
  4711.    ctx_temp.closePath();\
  4712.    ctx_temp.stroke();\
  4713.   };\
  4714.   ctx_temp.strokeStyle = \"rgba(0,0,255,0.6)\";\
  4715.   ctx_temp.lineWidth = 1;\
  4716.   for(var p = 0; p < size_x ; p = p+0.5*dx){\
  4717.    ctx_temp.beginPath();\
  4718.    ctx_temp.moveTo(ruler_x+p,ruler_y);\
  4719.    ctx_temp.lineTo(ruler_x+p,ruler_y-0.6*dy);\
  4720.    ctx_temp.closePath();\
  4721.    ctx_temp.stroke();\
  4722.   };\
  4723.   ctx_temp.strokeStyle = \"rgba(255,0,0,0.6)\";\
  4724.   ctx_temp.lineWidth = 0.5;\
  4725.   for(var p = 0; p < size_x ; p = p+0.1*dx){\
  4726.    ctx_temp.beginPath();\
  4727.    ctx_temp.moveTo(ruler_x+p,ruler_y);\
  4728.    ctx_temp.lineTo(ruler_x+p,ruler_y-0.4*dy);\
  4729.    ctx_temp.closePath();\
  4730.    ctx_temp.stroke();\
  4731.   };\
  4732.   ctx_temp.drawImage(canvas,ruler_x,ruler_y);\
  4733.   once = false;\
  4734.  }",canvas_root_id,canvas_root_id,sizex,sizey,x,y,font,stroke_color,stroke_opacity,fill_color,fill_opacity,line_width);
  4735.  
  4736.  if( dynamic == -1 ){
  4737.  fprintf(js_include_file,"\
  4738. ctx.drawImage(canvas_temp,0,0);\
  4739.   if(wims_status != \"done\"){\
  4740.    canvas_div.addEventListener( 'mouseup'   , ruler_stop,false);\
  4741.    canvas_div.addEventListener( 'mousedown' , ruler_start,false);\
  4742.    canvas_div.addEventListener( 'mousemove' , ruler_move,false);\
  4743.    canvas_div.addEventListener( 'touchstart', function(e){ e.preventDefault();ruler_start(e.changedTouches[0]);},false);\
  4744.    canvas_div.addEventListener( 'touchmove', function(e){ e.preventDefault();ruler_move(e.changedTouches[0]);},false);\
  4745.    canvas_div.addEventListener( 'touchend', function(e){ e.preventDefault();ruler_stop(e.changedTouches[0]);},false);\
  4746.   };\
  4747.   function ruler_stop(evt){\
  4748.    ruler_data[0] = ruler_x;\
  4749.    ruler_data[1] = ruler_y;\
  4750.    ruler_data[2] = angle;\
  4751.    return;\
  4752.   };\
  4753.   var ruler_click_cnt = 0;\
  4754.   function ruler_start(evt){\
  4755.    var mouse = dragstuff.getMouse(evt,canvas);\
  4756.    var mouse_y = mouse.y;\
  4757.    if( mouse_y > ysize - 20 ){return;};\
  4758.    var mouse_x = mouse.x;\
  4759.    if( mouse_x > ruler_x - 50 && mouse_x < ruler_x + size_x + 50){\
  4760.     if( mouse_y > ruler_y - 50 && mouse_y < ruler_y + size_y + 50){\
  4761.      ruler_click_cnt++;\
  4762.      ruler_move(evt);\
  4763.      return;\
  4764.     };\
  4765.    }else{ruler_click_cnt = 0; return;};\
  4766.   };\
  4767.   var angle = 0;\
  4768.   function ruler_move(evt){\
  4769.    var mouse = dragstuff.getMouse(evt,canvas);\
  4770.    switch(ruler_click_cnt){\
  4771.     case 1:\
  4772.      angle = 0;\
  4773.      ruler_y = mouse.y;\
  4774.      if( ruler_y > ysize - 20 ){ruler_y = 0.5*ysize;ruler_x = 0.5*xsize;return;};\
  4775.      ruler_x = mouse.x;\
  4776.      if( x_use_snap_to_grid == 1 ){\
  4777.       ruler_x = snap_to_x(ruler_x);\
  4778.      };\
  4779.      if( y_use_snap_to_grid == 1 ){\
  4780.       ruler_y = snap_to_y(ruler_y);\
  4781.      };\
  4782.      ctx.clearRect(0,0,xsize,ysize);\
  4783.      ctx.save();\
  4784.      ctx.translate(ruler_x - xcenter,ruler_y - ycenter);\
  4785.      ctx.drawImage(canvas_temp,0,0);\
  4786.      ctx.restore();\
  4787.      break;\
  4788.     case 2:\
  4789.      angle = find_angle(ruler_x,ruler_y,mouse.x,mouse.y);\
  4790.      ctx.clearRect(0,0,xsize,ysize);\
  4791.      ctx.save();\
  4792.      ctx.translate(ruler_x,ruler_y);\
  4793.      ctx.rotate(angle);\
  4794.      ctx.translate( -1*xcenter, -1*ycenter );\
  4795.      ctx.drawImage( canvas_temp,0,0 );\
  4796.      ctx.restore();\
  4797.      userdraw_radius[0] = 2*Math.PI - angle;\
  4798.      break;\
  4799.     case 3:ruler_click_cnt = 0;break;\
  4800.     default:ruler_stop(evt);break;\
  4801.    };\
  4802.   };\
  4803.  };\
  4804.  ruler%d();\n",canvas_root_id);
  4805.  }
  4806.  else
  4807.  {
  4808.   fprintf(js_include_file,"\
  4809.   ctx.clearRect(0,0,xsize,ysize);\
  4810.   ctx.save();\
  4811.   ctx.translate(ruler_x,ruler_y);\
  4812.   ctx.rotate(%d*Math.PI/180);\
  4813.   ctx.translate( -1*xcenter, -1*ycenter );\
  4814.   ctx.drawImage( canvas_temp,0,0 );\
  4815.   ctx.restore();\
  4816.  };\
  4817.  ruler%d();",dynamic,canvas_root_id);
  4818.  }
  4819. }
  4820.  
  4821. void add_js_protractor(FILE *js_include_file,int canvas_root_id,int type,double xcenter,double ycenter,int size,char *font,char *stroke_color,double stroke_opacity,char *fill_color,double fill_opacity,int line_width,int use_scale,int dynamic){
  4822.  
  4823. /*
  4824. use_slider_display = 2 : angle in degrees
  4825. use_slider_display = 3 : angle in radians
  4826. void add_slider_display(FILE *js_include_file,int canvas_root_id,int precision,int font_size,char *font_color,double stroke_opacity){
  4827. fprintf(js_include_file,"<!-- begin add_slider_display -->\n\
  4828. function show_slider_value(value,use_slider_display)
  4829. */
  4830.  
  4831. if( type == 1 ){ /* geodriehoek */
  4832.  fprintf(js_include_file,"\n<!-- begin command protractor type 1 -->\n\
  4833. var protractor_data = new Array(3);\
  4834. var protractor%d = function(){\
  4835.  var once = true;\
  4836.  var full = 2*Math.PI;\
  4837.  var canvas = create_canvas%d(2000,xsize,ysize);\
  4838.  var ctx = canvas.getContext(\"2d\");\
  4839.  var canvas_temp =  document.createElement(\"canvas\");\
  4840.  var size = parseInt(xsize*(%d)/(xmax - xmin));\
  4841.  canvas_temp.width = xsize;\
  4842.  canvas_temp.height = ysize;\
  4843.  var ctx_temp = canvas_temp.getContext(\"2d\");\
  4844.  var type = %d;\
  4845.  var xcenter = x2px(%f);\
  4846.  var ycenter = y2px(%f);\
  4847.  var half = 0.5*size;\
  4848.  var radius1 = 0.6*half;\
  4849.  var radius2 = 0.65*half;\
  4850.  var radius3 = 0.7*half;\
  4851.  ctx_temp.font = \"%s\";\
  4852.  ctx_temp.strokeStyle = \"rgba(%s,%f)\";\
  4853.  ctx_temp.fillStyle = \"rgba(%s,%f)\";\
  4854.  ctx_temp.lineWidth =%d;\
  4855.  var use_scale = %d;\
  4856.  if( once ){\
  4857.   ctx_temp.clearRect(0,0,canvas_temp.width,canvas_temp.height);\
  4858.   ctx_temp.beginPath();\
  4859.   ctx_temp.moveTo(xcenter-half,ycenter );\
  4860.   ctx_temp.lineTo(xcenter,ycenter-half);\
  4861.   ctx_temp.lineTo(xcenter+half,ycenter);\
  4862.   ctx_temp.lineTo(xcenter-half,ycenter);\
  4863.   ctx_temp.moveTo(xcenter,ycenter );\
  4864.   ctx_temp.lineTo(xcenter+0.5*half,ycenter-0.5*half);\
  4865.   ctx_temp.moveTo(xcenter,ycenter );\
  4866.   ctx_temp.lineTo(xcenter-0.5*half,ycenter-0.5*half);\
  4867.   ctx_temp.moveTo(xcenter,ycenter );\
  4868.   ctx_temp.lineTo(xcenter,ycenter-half);\
  4869.   ctx_temp.closePath();\
  4870.   ctx_temp.fill();\
  4871.   ctx_temp.stroke();\
  4872.   ctx_temp.beginPath();\
  4873.   ctx_temp.arc(xcenter,ycenter,radius1,0,Math.PI,false);\
  4874.   ctx_temp.closePath();\
  4875.   if( use_scale == 1 ){\
  4876.    ctx_temp.fillStyle = ctx_temp.strokeStyle;\
  4877.    var txtsize;\
  4878.    for(var p = 45 ; p < 180;p = p+45){\
  4879.     txtsize = 0.5*(ctx_temp.measureText(p).width);\
  4880.     ctx_temp.fillText(p,xcenter+0.5*half*Math.cos(p*Math.PI/180) - txtsize,ycenter-0.5*half*Math.sin(p*Math.PI/180));\
  4881.    };\
  4882.   };\
  4883.   for(var p = 10 ; p < 180;p = p+10){\
  4884.    ctx_temp.beginPath();\
  4885.    ctx_temp.moveTo(xcenter+radius1*Math.cos(p*Math.PI/180),ycenter-radius1*Math.sin(p*Math.PI/180));\
  4886.    ctx_temp.lineTo(xcenter+radius3*Math.cos(p*Math.PI/180),ycenter-radius3*Math.sin(p*Math.PI/180));\
  4887.    ctx_temp.closePath();\
  4888.    ctx_temp.stroke();\
  4889.   };\
  4890.   for(var p = 0 ; p < 180;p=p+2){\
  4891.    if(p%%10 != 0){\
  4892.     ctx_temp.beginPath();\
  4893.     ctx_temp.moveTo(xcenter+radius1*Math.cos(p*Math.PI/180),ycenter-radius1*Math.sin(p*Math.PI/180));\
  4894.     ctx_temp.lineTo(xcenter+radius2*Math.cos(p*Math.PI/180),ycenter-radius2*Math.sin(p*Math.PI/180));\
  4895.     ctx_temp.closePath();\
  4896.     ctx_temp.stroke();\
  4897.    };\
  4898.   };\
  4899.   ctx_temp.drawImage(canvas,xcenter,ycenter);\
  4900.   ctx_temp.save();\
  4901.   once = false;\
  4902.  };\
  4903.  ",canvas_root_id,canvas_root_id,size,type,xcenter,ycenter,font,stroke_color,stroke_opacity,fill_color,fill_opacity,line_width,use_scale);
  4904. }
  4905.  
  4906. if( type != 1 ){
  4907.  fprintf(js_include_file,"\n<!-- begin command protractor type 0 -->\n\
  4908. var protractor_data = new Array(3);\
  4909. var protractor%d = function(){\
  4910.  var once = true;\
  4911.  var full = 2*Math.PI;\
  4912.  var canvas = create_canvas%d(2000,xsize,ysize);\
  4913.  var ctx = canvas.getContext(\"2d\");\
  4914.  var canvas_temp =  document.createElement(\"canvas\");\
  4915.  var size = parseInt(xsize*(%d)/(xmax - xmin));\
  4916.  canvas_temp.width = xsize;\
  4917.  canvas_temp.height = ysize;\
  4918.  var ctx_temp = canvas_temp.getContext(\"2d\");\
  4919.  var type = %d;\
  4920.  var xcenter = x2px(%f);\
  4921.  var ycenter = y2px(%f);\
  4922.  var half = 0.5*size;\
  4923.  var radius1 = 0.8*half;\
  4924.  var radius2 = 0.9*half;\
  4925.  var radius3 = half;\
  4926.  ctx_temp.font = \"%s\";\
  4927.  ctx_temp.strokeStyle = \"rgba(%s,%f)\";\
  4928.  ctx_temp.fillStyle = \"rgba(%s,%f)\";\
  4929.  ctx_temp.lineWidth =%d;\
  4930.  var use_scale = %d;\
  4931.  if( once ){\
  4932.   ctx_temp.clearRect(0,0,xsize,ysize);\
  4933.   ctx_temp.arc(xcenter,ycenter,radius1,0,2*Math.PI,false);\
  4934.   ctx_temp.arc(xcenter,ycenter,radius2,0,2*Math.PI,false);\
  4935.   ctx_temp.arc(xcenter,ycenter,radius3,0,2*Math.PI,false);\
  4936.   ctx_temp.fill();\
  4937.   ctx_temp.stroke();\
  4938.   if( use_scale == 1 ){\
  4939.    ctx_temp.fillStyle = ctx_temp.strokeStyle;\
  4940.    var txtsize;\
  4941.    for(var p = 0 ; p < 360;p = p+45){\
  4942.     txtsize = 0.5*(ctx_temp.measureText(p).width);\
  4943.     ctx_temp.fillText(p,xcenter+0.6*half*Math.cos(p*Math.PI/180) - txtsize,ycenter-0.6*half*Math.sin(p*Math.PI/180));\
  4944.    };\
  4945.   };\
  4946.   ctx_temp.strokeStyle = \"rgba(255,0,0,0.4)\";\
  4947.   for(var p = 0 ; p < 360;p = p+10){\
  4948.    ctx_temp.beginPath();\
  4949.    ctx_temp.moveTo(xcenter+radius1*Math.cos(p*Math.PI/180),ycenter-radius1*Math.sin(p*Math.PI/180));\
  4950.    ctx_temp.lineTo(xcenter+radius3*Math.cos(p*Math.PI/180),ycenter-radius3*Math.sin(p*Math.PI/180));\
  4951.    ctx_temp.closePath();\
  4952.    ctx_temp.stroke();\
  4953.   };\
  4954.   ctx_temp.strokeStyle = \"rgba(0,0,255,0.4)\";\
  4955.   for(var p = 0 ; p < 360;p=p+2){\
  4956.     ctx_temp.beginPath();\
  4957.     ctx_temp.moveTo(xcenter+radius2*Math.cos(p*Math.PI/180),ycenter-radius2*Math.sin(p*Math.PI/180));\
  4958.     ctx_temp.lineTo(xcenter+radius3*Math.cos(p*Math.PI/180),ycenter-radius3*Math.sin(p*Math.PI/180));\
  4959.     ctx_temp.closePath();\
  4960.     ctx_temp.stroke();\
  4961.   };\
  4962.   ctx_temp.strokeStyle = \"rgba(0,0,0,0.6)\";\
  4963.   for(var p = 0 ; p < 360;p=p+45){\
  4964.     ctx_temp.beginPath();\
  4965.     ctx_temp.moveTo(xcenter,ycenter);\
  4966.     ctx_temp.lineTo(xcenter+radius3*Math.cos(p*Math.PI/180),ycenter-radius3*Math.sin(p*Math.PI/180));\
  4967.     ctx_temp.closePath();\
  4968.     ctx_temp.stroke();\
  4969.   };\
  4970.   ctx_temp.drawImage(canvas,0,0);\
  4971.   ctx_temp.save();\
  4972.   once = false;\
  4973.  };\n",canvas_root_id,canvas_root_id,size,type,xcenter,ycenter,font,stroke_color,stroke_opacity,fill_color,fill_opacity,line_width,use_scale);
  4974. }
  4975. if( dynamic == -1 ){ /* rotate the protractors */
  4976.  fprintf(js_include_file,"\
  4977.  var protractor_x = xcenter;\
  4978.  var protractor_y = ycenter;\
  4979.  ctx.drawImage(canvas_temp,0,0);\
  4980.  var angle = 0;\
  4981.  if(wims_status != \"done\"){\
  4982.   canvas_div.addEventListener( 'mouseup'   , protractor_stop,false);\
  4983.   canvas_div.addEventListener( 'mousedown' , protractor_start,false);\
  4984.   canvas_div.addEventListener( 'mousemove' , protractor_move,false);\
  4985.   canvas_div.addEventListener( 'touchstart', function(e){ e.preventDefault();protractor_start(e.changedTouches[0]);},false);\
  4986.   canvas_div.addEventListener( 'touchmove', function(e){ e.preventDefault();protractor_move(e.changedTouches[0]);},false);\
  4987.   canvas_div.addEventListener( 'touchend', function(e){ e.preventDefault();protractor_stop(e.changedTouches[0]);},false);\
  4988.  };\
  4989.  function protractor_stop(evt){\
  4990.   protractor_data[0] = protractor_x;\
  4991.   protractor_data[1] = protractor_y;\
  4992.   protractor_data[2] = angle;\
  4993.   return;\
  4994.  };\
  4995.  var protractor_click_cnt = 0;\
  4996.  function protractor_start(evt){\
  4997.   var mouse = dragstuff.getMouse(evt,canvas);\
  4998.   var mouse_y = mouse.y;\
  4999.   if( mouse_y > ysize - 20 ){return;};\
  5000.   var mouse_x = mouse.x;\
  5001.   if( mouse_x > protractor_x - half && mouse_x < protractor_x + half ){\
  5002.    if( mouse_y > protractor_y - half && mouse_y < protractor_y + half ){\
  5003.     protractor_click_cnt++;\
  5004.     protractor_move(evt);\
  5005.     return;\
  5006.    };\
  5007.   }else{protractor_click_cnt = 0; return;};\
  5008.  };\
  5009.  function protractor_move(evt){\
  5010.   var mouse = dragstuff.getMouse(evt,canvas);\
  5011.   switch(protractor_click_cnt){\
  5012.    case 1:\
  5013.      angle = 0;\
  5014.      protractor_y = mouse.y;\
  5015.      if( protractor_y > ysize - 20 ){protractor_y = 0.5*ysize;protractor_x = 0.5*xsize;return;};\
  5016.      protractor_x = mouse.x;\
  5017.      if( x_use_snap_to_grid == 1 ){\
  5018.       protractor_x = snap_to_x(protractor_x);\
  5019.      };\
  5020.      if( y_use_snap_to_grid == 1 ){\
  5021.       protractor_y = snap_to_y(protractor_y);\
  5022.      };\
  5023.      ctx.clearRect(0,0,xsize,ysize);\
  5024.      ctx.save();\
  5025.      ctx.translate(protractor_x - xcenter,protractor_y - ycenter);\
  5026.      ctx.drawImage(canvas_temp,0,0);\
  5027.      ctx.restore();\
  5028.      break;\
  5029.    case 2:\
  5030.     angle = find_angle(protractor_x,protractor_y,mouse.x,mouse.y);\
  5031.     ctx.clearRect(0,0,xsize,ysize);\
  5032.     ctx.save();\
  5033.     ctx.translate(protractor_x,protractor_y);\
  5034.     ctx.rotate(angle);\
  5035.     ctx.translate( -1*xcenter, -1*ycenter );\
  5036.     ctx.drawImage( canvas_temp,0,0 );\
  5037.     ctx.restore();\
  5038.     userdraw_radius[0] =2*Math.PI- angle;\
  5039.     break;\
  5040.    case 3:protractor_click_cnt = 0;break;\
  5041.    default:protractor_stop(evt);\
  5042.   };\
  5043.  };\
  5044. };\
  5045. protractor%d();\n\
  5046. ",canvas_root_id);
  5047. }
  5048. else
  5049. {
  5050.  fprintf(js_include_file,"\
  5051.  ctx.save();\
  5052.  ctx.translate(xcenter,ycenter);\
  5053.  ctx.rotate(%d*Math.PI/180);\
  5054.  ctx.translate( -1*xcenter, -1*ycenter );\
  5055.  ctx.drawImage( canvas_temp,0,0 );\
  5056.  ctx.restore();\
  5057. };\
  5058. protractor%d();\
  5059. ",dynamic,canvas_root_id);
  5060. } /* end dynamic == -1*/
  5061.  
  5062. }
  5063.  
  5064.