home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / gle / gle / run.c < prev    next >
C/C++ Source or Header  |  1992-11-29  |  26KB  |  1,135 lines

  1. #include "all.h"
  2.  
  3. #include <math.h>
  4.  
  5. #include "mygraph.h"   /* Prototypes for all the graph routines */
  6. int text_def(char *ss);
  7. int g_psarrow(double x1, double y1, double x2, double y2, int flag);
  8. int g_arrowline(double dx, double dy, int flag);
  9. int g_arrowpoints(double cx,double cy,double dx,double dy, double *ax1,double *ay1
  10.     ,double *ax2,double *ay2, double *nx, double *ny);
  11. int name_join(char *a, char *b, int j);
  12. int box_start(void);
  13. int box_end(void);
  14. int g_arrow(double dx, double dy);
  15. int run_bigfile(char *ss);
  16. #define MAXBOX 10
  17. extern int this_line;
  18. extern int trace_on;
  19. static char *box_name[MAXBOX];
  20. static double box_y1[MAXBOX], box_x1[MAXBOX], box_y2[MAXBOX], box_x2[MAXBOX];
  21. static int box_nobox[MAXBOX];
  22. static long box_fill[MAXBOX];
  23. static double box_add[MAXBOX];
  24. static int path_clip[4],path_stroke[4];
  25. static long path_fill[4];
  26. static double path_x[4],path_y[4];
  27. static int npath,nbox;
  28. int done_open;
  29. #define true (!false)
  30. #define false 0
  31. /*---------------------------------------------------------------------------*/
  32. /* gle FILE io stuff.  (fopen fclose fread fwrite) */
  33. #define F_MAXCHAN 5
  34. static int f_end[F_MAXCHAN];
  35. static char *f_buff[F_MAXCHAN];
  36. static FILE *f_chan[F_MAXCHAN];
  37. static int f_read[F_MAXCHAN];
  38. static char *f_nexttok[F_MAXCHAN];
  39. int f_getchan(void);
  40. void f_readahead(int chn);
  41. int f_testchan(int chn);
  42. void siffree(char **s);
  43. void f_getline(int chn);
  44. char *f_gettok(int chn);
  45. static int chn;
  46. int f_eof(int chn);
  47. char *f_getnext(int chn);
  48. /*---------------------------------------------------------------------------*/
  49. /* pos=   Offset to find the data            */
  50. /* idx=   For switches, which can only have one value.     */
  51. /* The pos is the order the items will be placed in the pcode */
  52. /*
  53. /* Switches     long     placed in directly, 1 present, 0 not present
  54. /* expressions     LONG*     pointed to, 0 if not present.
  55. /* color/fill    LONG*     Pointer to exp 0 if not present.
  56. /* marker    LONG*    Pointer to exp 0 if not present.
  57. /* lstyle     LONG*    Pointer to exp 0 if not present.
  58. /* font     long*     Pointer to string expression.
  59. */
  60.  
  61. extern char *mainkey[];
  62. extern int gle_debug;
  63. int can_fillpath;
  64. int init_run_done;
  65.  
  66. #define readval(x) eval(pcode,&cp,&x,ostr,&otyp)
  67. #define readxy(x,y) {eval(pcode,&cp,&x,ostr,&otyp);eval(pcode,&cp,&y,ostr,&otyp);}
  68. #define readstr(s) eval(pcode,&cp,&x,s,&otyp)
  69. #define readlong(i) i = *(pcode+cp++)
  70. #define readvalp(x,p) {zzcp=0; eval(p,&zzcp,&x,ostr,&otyp);}
  71. #define dbg if ((gle_debug & 16)>0)
  72. static int for_level,for_skip,for_loop,if_findelse,if_findendif,if_level;
  73. for_init()
  74. {
  75.     for_loop = 0;
  76.     for_level = 0;
  77.     for_skip = 0;
  78.     if_findelse = 0;
  79.     if_findendif = 0;
  80.     if_level = 0;
  81. }
  82. /*---------------------------------------------------------------------------*/
  83. /* Input is pcode, output is text equiv.*/
  84. do_pcode(int *srclin, long *pcode, int plen, int *pend)
  85. /* srclin = The source line number */
  86. /* pcode =  a pointer to the pcode output buffer */
  87. /* plne =   a pointer to the length of the pcode output */
  88. {
  89.     double oval;
  90.     union {double d; long l; long ll[2];} both;
  91.     int otyp,cp=0,i,zzcp;
  92.     static double loopstep[30];
  93.     static int loopadr[30],nloop;
  94.     double lll,rrr,uuu,ddd;
  95.     char ostr[255];
  96.     char *pss;
  97.     char *zzz;
  98.     int p;
  99.     union ppboth {long l; short s[2];} bth;
  100.     double x,y,sx,sy,ox,oy,x1,y1,x2,y2,x3,y3,a1,a2,r,z;
  101.     int t,j,jj,ptr,ptr_fill,mask_just,mask_nostroke,marrow;
  102.     static char ss[255],ss2[80];
  103.  
  104.  
  105.     if (!init_run_done) {
  106.         init_run_done = true;
  107.         g_get_type(ss);
  108.         if (strstr(ss,"FILLPATH")!=NULL) can_fillpath = true;
  109.     }
  110.  
  111.     this_line = *srclin;
  112.     /* dbg gprint("Gle debug %d \n ",gle_debug);
  113.     dbg gprint("PP> ");
  114.     dbg for (i=0; i<plen; i++) {
  115.         bth.l = *(pcode+i);
  116.         dbg gprint("%ld  ",bth.l);
  117.     }
  118.     dbg gprint("\n");
  119.     dbg gprint("HEX> ");
  120.     dbg for (i=0; i<plen; i++) {
  121.         bth.l = *(pcode+i);
  122.         dbg gprint("%lx  ",bth.l);
  123.     }
  124.     dbg gprint("\n");
  125.     */
  126.     if (plen==0) return;
  127.     if (*(pcode)==0) return;
  128.     p = *(pcode+((cp)++));
  129.     cmd_name(p,&pss);
  130.     dbg gprint("Command %d {%s} \n",p,pss);
  131.     sprintf(ss,"Command %d {%s} \n",p,pss);
  132.     g_source(ss);
  133.     if (if_findelse) {
  134.         dbg gprint("SKIP in skip findelse \n");
  135.         switch (p) {
  136.             case 13 : /* else */
  137.                 if (if_level==0) {
  138.                     if_findelse = false;
  139.                 }
  140.                 break;
  141.             case 14 : /* end xxx */
  142.                 readlong(jj);
  143.                 if (jj==6) { /* end if */
  144.                     if (if_level==0) {
  145.                         if_findelse = false;
  146.                     } else if_level--;
  147.                 }
  148.                 break;
  149.             case 22 : /* if */
  150.                 if_level++;
  151.                 break;
  152.         }
  153.         return;
  154.     }
  155.     if (if_findendif) {
  156.         dbg gprint("SKIP, findendif \n");
  157.         switch (p) {
  158.             case 14 : /* end xxx */
  159.                 readlong(jj);
  160.                 if (jj==6) { /* end if */
  161.                     if (if_level==0) {
  162.                         if_findendif = false;
  163.                     } else if_level--;
  164.                 } else gprint("Wrong end %d \n",jj);
  165.                 break;
  166.             case 22 : /* if */
  167.                 if_level++;
  168.                 break;
  169.         }
  170.         return;
  171.     }
  172.     if (for_skip ) {
  173.         switch (p) {
  174.             case 47: /* until */
  175.             case 18 : /* for */
  176.                 for_level++;
  177.                 break;
  178.             case 30 : /* next */
  179.                 if (for_level==0) {
  180.                     for_skip = false;
  181.                 } else for_level--;
  182.                 break;
  183.         }
  184.         return;
  185.     }
  186.     if (!done_open) {
  187.         if (p!=42 && p!=53 && p!=0) {
  188.             gprint("No SIZE command at top of graph, assuming 10cm by 10cm\n");
  189.             g_open(10.0,10.0);
  190.             done_open = true;
  191.             return;
  192.         }
  193.     }
  194.     switch (p) {
  195.       case 53: /* comment */
  196.       case 0: /* blank line */
  197.         break;
  198.       case 1:  /* ALINE x y ARROW both | start | end */
  199.         readval(x);
  200.         readval(y);
  201.         dbg gprint("x=%f, y=%f \n",x,y);
  202.         marrow = *(pcode + (cp++));
  203.         dbg gprint("arrow mask %d \n",marrow);
  204.         g_arrowline(x,y,marrow);
  205.         break;
  206.       case 2:  /* AMOVE */
  207.         readval(x);
  208.         readval(y);
  209.         g_move(x,y);
  210.         break;
  211.       case 3: /* ARC */
  212.         readval(r);
  213.         readxy(a1,a2);
  214.         g_get_xy(&ox,&oy);
  215.         g_arc(r,a1,a2,ox,oy);
  216.         break;
  217.       case 4: /* ARCTO */
  218.         readxy(x1,y1);
  219.         readxy(x2,y2);
  220.         readval(r);
  221.         g_get_xy(&ox,&oy);
  222.         g_arcto(x1+ox,y1+oy,x2+ox+x1,y2+oy+y1,r);
  223.         break;
  224.       case 51: /* Assignment  var=exp */
  225.         readlong(jj);
  226.         readval(x);
  227.         if (otyp==1) var_set(jj,x);
  228.         if (otyp==2) var_setstr(jj,ostr);
  229.         break;
  230.       case 5:  /* BEGIN box | path | scale | rotate | EXTERNAL */
  231.         g_flush();
  232.         i = *(pcode + cp++);
  233.         dbg gprint(" begin %d \n",i);
  234.         switch (i) {
  235.             case 1: /* PATH stroke fill clip */
  236.                 npath++;
  237.                 g_get_xy(&path_x[npath],&path_y[npath]);
  238.                 path_stroke[npath] = *(pcode + cp);
  239.                 ptr = *(pcode + ++cp);
  240.                 path_fill[npath] = 0;
  241.                 if (ptr) {
  242.                     readvalp(z,pcode+cp+ptr);
  243.                     memcpy(&path_fill[npath],&z,4);
  244.                 }
  245.                 path_clip[npath] = *(pcode + ++cp);
  246.                 g_set_path(true);
  247.                 g_newpath();
  248.                 break;
  249.             case 2: /* BOX   add,fill,nobox,name */
  250.                 box_start();
  251.                 ptr = *(pcode + cp);
  252.                 if (ptr) readvalp(box_add[nbox],pcode+cp+ptr);
  253.                 ptr = *(pcode + ++cp);
  254.                 if (ptr) {
  255.                     readvalp(z,pcode+cp+ptr);
  256.                     memcpy(&box_fill[nbox],&z,4);
  257.                 }
  258.                 box_nobox[nbox] = *(pcode + ++cp);
  259.                 ptr = *(pcode + ++cp);
  260.                 if (ptr) {
  261.                     readvalp(z,pcode+cp+ptr);
  262.                     box_name[nbox] = sdup(ostr);
  263.                 }
  264.                 break;
  265.             case 3: /* SCALE */
  266.                 readxy(x,y);
  267.                 g_gsave();
  268.                 g_scale(x,y);
  269.                 break;
  270.             case 4: /* ROTATE */
  271.                 readval(x);
  272.                 g_gsave();
  273.                 g_rotate(x);
  274.                 break;
  275.             case 5: /* TRANSLATE */
  276.                 readval(x); readval(y);
  277.                 g_gsave();
  278.                 g_translate(x,y);
  279.                 g_rmove(0.0,0.0);
  280.                 break;
  281.             case 6: /* if */
  282.             case 7: /* sub */
  283.                 gprint("odd begin %d\n",i);
  284.                 break;
  285.             case 8: /* name */
  286.                 box_start();
  287.                 box_nobox[nbox] = true;
  288.                 readval(z);
  289.                 box_name[nbox] = sdup(ostr);
  290.                 break;
  291.             case 9: /* text */
  292.                 ptr = *(pcode + cp);
  293.                 z = 0;
  294.                 if (ptr) readvalp(z,pcode+cp+ptr);
  295.                 begin_text(srclin,pcode,&cp,z);
  296.                 break;
  297.             case 18: /* tab  (tabbing, table) */
  298.                 begin_tab(srclin,pcode,&cp);
  299.                 break;
  300.             case 10: /* graph */
  301.                 begin_graph(srclin,pcode,&cp);
  302.                 break;
  303.             case 11: /* xaxis */
  304.             case 12: /* yaxis */
  305.             case 13: /* x2axis */
  306.             case 14: /* y2axis */
  307.                 break;
  308.             case 16: /* KEY */
  309.                 begin_key(srclin,pcode,&cp);
  310.                 break;
  311.             case 19: /* begin  clip */
  312.                 g_beginclip();
  313.                 break;
  314.             case 17: /* ORIGIN */
  315.                 g_gsave();
  316.                 g_get_xy(&x,&y);
  317.                 g_translate(x,y);
  318.                 g_move(0.0,0.0);
  319.                 break;
  320.             default: /* error  */
  321.                 gprint("Error, illegal begin option %d \n",i);
  322.                 break;
  323.         }
  324.         break;
  325.       case 6: /* BEZIER */
  326.         readxy(x1,y1);
  327.         readxy(x2,y2);
  328.         readxy(x3,y3);
  329.         g_bezier(x1,y1,x2,y2,x3,y3);
  330.         break;
  331.       case 7:  /* BOX x y left|center|right FILL fexp NAME string */
  332.         readval(x);
  333.         readval(y);
  334.         g_get_xy(&ox,&oy);
  335.         x += ox;
  336.         y += oy;
  337.         dbg gprint("x=%f, y=%f \n",x,y);
  338.         mask_just = *(pcode + cp++);
  339.         g_dojust(&ox,&oy,&x,&y,mask_just);
  340.  
  341.         mask_nostroke = *(pcode + cp);
  342.         ptr_fill = *(pcode + ++cp);
  343.         if (ptr_fill) {
  344.             readvalp(z,pcode + cp + ptr_fill);
  345.             memcpy(&both.d,&z,sizeof(z));
  346.             g_set_fill(both.l);
  347.             g_box_fill(ox,oy,x,y);
  348.         }
  349.         if (!mask_nostroke)
  350.             g_box_stroke(ox,oy,x,y);
  351.         ptr = *(pcode + ++cp); /* name */
  352.         if (ptr) {
  353.             readvalp(z,pcode + cp + ptr);
  354.             name_set(ostr,ox,oy,x,y);
  355.         }
  356.         dbg gprint("justify mask %d ",mask_just);
  357.         dbg gprint("nostroke mask %d ",mask_nostroke);
  358.         dbg gprint("fill pointer %d \n",ptr_fill);
  359.         break;
  360.       case 52:  /* CALL or @   (nope, do this inside ASSIGN */
  361.         readval(r);
  362.         break;
  363.       case 8:  /* CIRCLE */
  364.         readval(r);
  365.         g_get_xy(&ox,&oy);
  366.         sx = ox; sy = oy;
  367.         mask_just = *(pcode + cp++);
  368.         x = ox + r;
  369.         y = oy + r;
  370.         g_dojust(&ox,&oy,&x,&y,mask_just);
  371.         g_move(ox,oy);
  372.         mask_nostroke = *(pcode + cp++);
  373.         ptr_fill = *(pcode + cp);
  374.         if (ptr_fill) {
  375.             readvalp(z,pcode + cp + ptr_fill);
  376.             memcpy(&both.l,&z,4);
  377.             g_set_fill(both.l);
  378.             g_circle_fill(r);
  379.         }
  380.         if (!mask_nostroke)
  381.             g_circle_stroke(r);
  382.         g_move(sx,sy);
  383.         break;
  384.       case 9: /* CLOSEPATH */
  385.         g_closepath();
  386.         break;
  387.       case 10: /* CURVE  x y x y ...  change to BEGIN CURVE ... END CURVE */
  388.         g_curve(pcode+cp);
  389.         break;
  390.       case 11: /* DEFINE  MARKER name  subname */
  391.         break;
  392.       case 12: /* DFONT */
  393.         readstr(ss);
  394.         g_dfont(ss);
  395.         break;
  396.       case 13: /* ELSE */
  397.         if_findendif = true;
  398.         break;
  399.       case 14: /* END */
  400.         readlong(jj);
  401.         switch (jj) {
  402.           case 1: /* end path  (stroke,fill,clip) */
  403.             if (path_fill[npath]!=0) {
  404.                 g_set_fill(path_fill[npath]);
  405.                 g_fill();
  406.             }
  407.             if (path_stroke[npath]==true) g_stroke();
  408.             if (path_clip[npath]==true) g_clip();
  409.             if (npath==0) {
  410.                 gprint("Too many end path's \n");
  411.                 break;
  412.             }
  413.             g_move(path_x[npath],path_y[npath]);
  414.             npath--;
  415.             g_set_path(false);
  416.             break;
  417.           case 2: /* end box */
  418.             box_end();
  419.             break;
  420.           case 3: /* end scale */
  421.           case 4: /* end rotate */
  422.           case 5: /* end translate */
  423.             g_grestore();
  424.             break;
  425.           case 6: /* end if */
  426.             /* do nothing,  all done elsewhere I think?? */
  427.             break;
  428.           case 8: /* end name */
  429.             box_end();
  430.             break;
  431.           case 19: /* clip */
  432.             g_endclip();
  433.             break;
  434.           case 18: /* tab */
  435.           case 9: /* text */
  436.             break;
  437.           case 17: /* end origin */
  438.             g_grestore();
  439.             break;
  440.            default :
  441.             gprint("Not a valid end %d \n",jj);
  442.         }
  443.         break;
  444.       case 15: /* FCLOSE */
  445.         readval(x);
  446.         chn = x;
  447.         chn = f_testchan(chn);
  448.         if (f_chan[chn]!=NULL) fclose(f_chan[chn]);
  449.         f_chan[chn] = NULL;
  450.         siffree(&f_buff[chn]);
  451.         siffree(&f_nexttok[chn]);
  452.         f_buff[chn] = NULL;
  453.         break;
  454.       case 16: /* FILL */
  455.         g_fill();
  456.         break;
  457.       case 61 : /* fread CHAN a$ x   */
  458.       case 62 : /* freadln */
  459.         readlong(t);
  460.         if (t!=49) gprint("FREAD, PCODE ERROR, %d  cp %d plen %d\n",t,cp,plen);
  461.         readlong(i);
  462.         readlong(t);
  463.         var_get(i,&x);
  464.         chn = x;
  465.         chn = f_testchan(chn);
  466.         if (p==61 && cp>=plen) gprint("FREAD requires at least two parameters\n");
  467.         while (cp<plen) {
  468.             readlong(t);
  469.             if (t!=49) gprint("FREAD2, PCODE ERROR, %d  cp %d plen %d\n",t,cp,plen);
  470.             readlong(i); /* variable number */
  471.             readlong(t); /* type of variable */
  472.             if (t==1) {
  473.                 x = atof(f_gettok(chn));
  474.                 var_set(i,x);
  475.             } else {
  476.                 var_setstr(i,f_gettok(chn));
  477.             }
  478.         }
  479.         if (p==62) f_getline(chn);
  480.         break;
  481.       case 63 : /* fwrite */
  482.       case 64 : /* fwriteln */
  483.         strcpy(ss2,"");
  484.         readlong(t);
  485.         readlong(t);
  486.         readval(x);
  487.         chn = x;
  488.         chn = f_testchan(chn);
  489.         if (f_read[chn]==0) gprint("You cannot WRITE from a file open for READ {#%d %d} \n",chn,f_read[chn]);
  490.         while (cp<plen) {
  491.             readlong(t);
  492.             if (t!=49) gprint("WRITE, PCODE ERROR, %d  cp %d plen %d\n",t,cp,plen);
  493.             readlong(t);
  494.             if (t==1) {
  495.                 readval(x);
  496.                 sprintf(ss,"%g ",x);
  497.             } else readstr(ss);
  498.             strcat(ss2,ss);
  499.         }
  500.         if (p==64) strcat(ss2,"\n");
  501.         fprintf(f_chan[chn],"%s",ss2);
  502.         break;
  503.       case 17: /* FOPEN "a.a" inchan read|write */
  504.         readstr(ss);
  505.         readlong(i); /* channel variable */
  506.         readlong(jj); /* 0 = read, 1 = write */
  507.         chn = f_getchan();
  508.         f_read[chn] = jj;    
  509.         var_set(i,chn);
  510.         if (f_chan[chn]!=NULL) fclose(f_chan[chn]);
  511.         if (jj==0) f_chan[chn] = fopen(ss,"r");
  512.         else     f_chan[chn] = fopen(ss,"w");
  513.         if (f_chan[chn]==NULL) gprint("Can't open {%s}  \n",
  514.             ss);
  515.         dbg gprint("Opened {%s} chan %d, access %d  vari %d \n",ss,chn,jj,i);
  516.         f_end[chn] = false;
  517.         if (f_read[chn]==0) f_readahead(chn);
  518.         break;
  519.       case 18: /* FOR   v,exp,exp,op,exp */
  520.         if (for_loop) {
  521.             readlong(jj);
  522.             readval(x);
  523.             readval(y);
  524.             var_get(jj,&x);
  525.             x = x + loopstep[nloop];
  526.             var_set(jj,x);
  527.             var_get(jj,&x);
  528.             dbg gprint("got back %f \n",x);
  529.             if ( (x > y  && loopstep[nloop]>=0) ||
  530.                  (y > x  && loopstep[nloop]<=0) ) {
  531.                 for_skip = true;
  532.                 nloop--;
  533.             }
  534.             for_loop = false;
  535.             break;
  536.         }
  537.         loopadr[++nloop] = *srclin;
  538.         readlong(jj);      /* variable */
  539.         readval(x);
  540.         readval(y);
  541.         var_set(jj,x);
  542.         loopstep[nloop] = 1;
  543.         p = *(pcode + cp);
  544.         if (p) {
  545.             readvalp(z,pcode + cp + p);
  546.             loopstep[nloop] = z;
  547.         }
  548.         break;
  549.       case 19: /* GOTO */
  550.       case 20: /* GSAVE */
  551.         g_gsave();
  552.         break;
  553.       case 54: /* GRESTORE */
  554.         g_grestore();
  555.         break;
  556.       case 21: /* ICON */
  557.         break;
  558.       case 22: /* IF EXP */
  559.         readval(x);
  560.         dbg gprint("If expression = %f \n",x);
  561.         if (x==0) if_findelse = true;    /* exp was false */
  562.         break;
  563.       case 23: /* INCLUDE (done in pass,  already included) */
  564.         break;
  565.       case 24: /* INPUT */
  566.       case 25: /* JOIN  str1,type,str2 */
  567.         {
  568.             char ss1[90];
  569.             readval(z);
  570.             strcpy(ss1,ostr);
  571.             readlong(jj);
  572.             readval(z);
  573.             name_join(ss1,ostr,(int) jj);
  574.         }
  575.         break;
  576.       case 26: /* MARKER */
  577.         readval(x);
  578.         memcpy(&both.d,&x,sizeof(x));
  579.         jj = both.l;
  580.         g_get_hei(&z);
  581.         y = 1;
  582.         if (*(pcode+cp)!=0) readval(y);
  583.         y = y * z;
  584.         g_marker((int) both.l,y);
  585.         break;
  586.       case 27: /* MOVE  name */
  587.         readval(z);
  588.         name_get(ostr,&ox,&oy,&x,&y);
  589.         x = ox;
  590.         y = oy;
  591.         g_dojust(&ox,&oy,&x,&y,jj);
  592.         g_move(x+(x-ox),y+(y-oy));
  593.         break;
  594.       case 28: /* NARC */
  595.         readval(r);
  596.         readxy(a1,a2);
  597.         g_get_xy(&ox,&oy);
  598.         g_narc(r,a1,a2,ox,oy);
  599.         break;
  600.       case 29: /* NEWPATH */
  601.         g_newpath();
  602.         break;
  603.       case 30:  /* NEXT */
  604.         if (nloop==0) {
  605.             gprint("Next without for\n");
  606.             break;
  607.         }
  608.         *srclin = loopadr[nloop]-1;
  609.         dbg gprint("%FOR   Setting line back to %d  nloop %d \n ",*srclin,nloop);
  610.         for_loop = true;
  611.         break;
  612.       case 31: /* PIE ,, not implemented yet */
  613.         break;
  614.       case 57: /* plotter fonts */
  615.         plotter_fonts();
  616.         break;
  617.       case 58: /* bigfile "filename" */
  618.         readstr(ss);
  619.         strlwr(ss);        /* bit of a kludge but ... */
  620.         run_bigfile(ss);
  621.         break;
  622.       case 55: /* Postscrip fiename x y */
  623.         readstr(ss);
  624.             strlwr(ss);
  625.         readxy(x1,y1);
  626.         g_postscript(ss,x1,y1);
  627.         break;
  628.       case 32: /* PRINT */
  629.         break;
  630.       case 33: /* RBEZIER */
  631.         readxy(x1,y1);
  632.         readxy(x2,y2);
  633.         readxy(x3,y3);
  634.         g_get_xy(&ox,&oy);
  635.         x1 += ox;  x2 += ox;  x3 += ox;
  636.         y1 += oy;  y2 += oy;  y3 += oy;
  637.         g_bezier(x1,y1,x2,y2,x3,y3);
  638.         break;
  639.       case 34: /* REGION */
  640.         break;
  641.       case 50: /* RETURN exp */
  642.         readval(x);
  643.         sub_set_return(x);
  644.         break;
  645.       case 35: /* REVERSE */
  646.         g_reverse();
  647.         break;
  648.       case 36:  /* RLINE */
  649.         readval(x);
  650.         readval(y);
  651.         g_get_xy(&ox,&oy);
  652.         marrow = *(pcode + (cp++));
  653.         dbg gprint("RLINE getxy %f %f \n",ox,oy);
  654.         g_arrowline(x+ox,y+oy,marrow);
  655.         break;
  656.       case 37:  /* RMOVE */
  657.         readval(x);
  658.         readval(y);
  659.         g_get_xy(&ox,&oy);
  660.         g_move(x+ox,y+oy);
  661.         break;
  662.       case 38: /* ROTATE */
  663.         readval(x);
  664.         g_rotate(x);
  665.         break;
  666.       case 39: /* SAVE  name */
  667.         g_get_xy(&x,&y);
  668.         readval(z);
  669.         name_set(ostr,x,y,x,y);
  670.         break;
  671.       case 40: /* SCALE */
  672.         readxy(x,y);
  673.         g_scale(x,y);
  674.         break;
  675.       case 41: /* SET */
  676.         for (i=1;i<plen;i++) {
  677.         cp = i+1;
  678.         dbg gprint("set sub command %d \n",(*(pcode+i)-500));
  679.         switch (*(pcode+i)-500) {
  680.         /* FIDDLE CP SO THAT READVAL WORKS *** */
  681.           case 1: /* height */
  682.             readval(x);
  683.             g_set_hei(x);
  684.             break;
  685.           case 2: /* font */
  686.             readval(x);
  687.             memcpy(&both.l,&x,4);
  688.             g_set_font(both.l);
  689.             break;
  690.           case 3: /* justify */
  691.             readlong(jj);
  692.             g_set_just(jj);
  693.             break;
  694.           case 4: /* color */
  695.             readval(x);
  696.             memcpy(&both.l,&x,4);
  697.             g_set_color(both.l);
  698.             break;
  699.           case 5: /* dashlen */
  700.             readval(x);
  701.             g_set_line_styled(x);
  702.             break;
  703.           case 6: /* dash */
  704.             readval(x);
  705.             i = x;
  706.             sprintf(ss,"%d",i);
  707.             g_set_line_style(ss);
  708.             break;
  709.           case 7: /* lwidth */
  710.             readval(x);
  711.             g_set_line_width(x);
  712.             break;
  713.           case 10: /* fontlwidth */
  714.             readval(x);
  715.             g_set_font_width(x);
  716.             break;
  717.           case 8: /* join */
  718.             readlong(jj);
  719.             g_set_line_join(jj);
  720.             break;
  721.           case 9: /* cap */
  722.             readlong(jj);
  723.             g_set_line_cap(jj);
  724.             break;
  725.           default :
  726.             gprint("Not a valid set sub command {%d} i=%d \n",*(pcode+i),i);
  727.           }
  728.         i = cp-1;
  729.         }
  730.         break;
  731.       case 42: /* size x y [box]*/
  732.         readxy(x,y);
  733.         g_open(x,y);
  734.         g_get_xy(&ox,&oy);
  735.         done_open = true;
  736.         mask_just = *(pcode + cp++);
  737.         if (mask_just) { /* then draw box */
  738.             g_box_stroke(ox,oy,x,y);
  739.         }
  740.         break;
  741.       case 43: /* STROKE */
  742.         g_stroke();
  743.         break;
  744.       case 44: /* SUB */
  745.         readlong(jj);
  746.         sub_get_startend(jj,&i,&j);
  747.         *srclin = j;    /* skip past the subroutine */
  748.         break;
  749.       case 45: /* TEXT */
  750.         strcpy(ss,(char *) (pcode+cp));
  751.     /*    readstr(ss); */
  752.         g_text(ss);
  753.         g_get_bounds(&x1,&y1,&x2,&y2);
  754.  
  755.         break;
  756.       case 60: /* DEFMARKER */
  757.         break;
  758.       case 59: /* TEXTDEF */
  759.         strcpy(ss,(char *) (pcode+cp));
  760.         text_def(ss);
  761.         break;
  762.       case 46: /* TRANSLATE */
  763.         readxy(x,y);
  764.         g_translate(x,y);
  765.         break;
  766.       case 47: /* UNTIL */
  767.         readval(x);
  768.         if (!for_loop) loopadr[++nloop] = *srclin;
  769.         for_loop = true;
  770.         if (x) {for_skip = true; for_loop = false;}
  771.         break;
  772.       case 48: /* WHILE */
  773.         break;
  774.       case 49: /* WRITE */
  775.         g_get_xy(&ox,&oy); 
  776.         strcpy(ss2,"");
  777.         while (cp<plen) {
  778.             readlong(t);
  779.             if (t!=49) gprint("WRITE, PCODE ERROR, %d  cp %d plen %d\n",t,cp,plen);
  780.             readlong(t);
  781.             if (t==1) {
  782.                 readval(x);
  783.                 sprintf(ss,"%g ",x);
  784.             } else readstr(ss);
  785.             strcat(ss2,ss);
  786.         }
  787.         g_text(ss2);
  788.         g_move(ox,oy); 
  789.         break;
  790.       default :
  791.         gprint("Not a recognized command \n");
  792.     }
  793.     *pend = cp;
  794. }
  795. /* should be in core.c */
  796. g_arrowline(double x2, double y2, int flag)
  797. {
  798.     double x1,y1;
  799.     if ((flag&3)==0) {
  800.         g_line(x2,y2);
  801.         return;
  802.     }
  803.     g_get_xy(&x1,&y1);
  804.     if (!can_fillpath) {
  805.         if (flag & 1)  g_arrow(x2-x1,y2-y1);
  806.         g_line(x2,y2);
  807.         if (flag & 2)  g_arrow(x1-x2,y1-y2);
  808.         return;
  809.     }
  810.     g_psarrow(x1,y1,x2,y2,flag);
  811. }
  812. g_psarrow(double x1, double y1, double x2, double y2, int flag)
  813. {
  814.     double ax1,ax2,ay1,ay2,dx,dy,nx,ny,nnx,nny,xx2,yy2;
  815.     long cur_color;
  816.     xx2 = x2; yy2 = y2;
  817.     dx = x2-x1;  dy = y2-y1;
  818.     g_arrowpoints(x1,y1,dx,dy,&ax1,&ay1,&ax2,&ay2,&nx,&ny);
  819.     g_set_path(true);
  820.     g_newpath();
  821.     if ((flag & 1)>0) {
  822.         g_move(ax2,ay2);
  823.         g_line(x1,y1);
  824.         g_line(ax1,ay1);
  825.         g_closepath();
  826.         x1 = nx; y1 = ny;
  827.     }
  828.      g_arrowpoints(x2,y2,-dx,-dy,&ax1,&ay1,&ax2,&ay2,&nx,&ny);
  829.     if ((flag & 2)>0) {
  830.         g_move(ax2,ay2);
  831.         g_line(x2,y2);
  832.         g_line(ax1,ay1);
  833.         g_closepath();
  834.         xx2 = nx; yy2 = ny;
  835.     }
  836.     g_get_color(&cur_color);
  837.     g_set_fill(cur_color);
  838.     g_fill();
  839.     g_set_path(false);
  840.     g_newpath();
  841.     g_move(x1,y1);
  842.     g_line(xx2,yy2);
  843.     g_move(x2,y2);
  844. }
  845. g_arrowpoints(double cx,double cy,double dx,double dy, double *ax1,
  846.     double *ay1,double *ax2,double *ay2, double *nnx, double *nny)
  847. {
  848.     double radius,angle,alen,nx,ny,width,arrow_angle;
  849.     g_get_line_width(&width);
  850.     if (width==0) width = .02;
  851.     arrow_angle = 10;
  852.     if (width>.1) arrow_angle = 20;
  853.     if (width>.3) arrow_angle = 30;
  854.     g_get_hei(&alen);  alen = alen/2;
  855.     if (sin(arrow_angle*3.14159/180)*alen < width/1.5) {
  856.         alen = (width/1.5) / sin(arrow_angle*3.141592/180);
  857.     }
  858.     xy_polar(dx,dy,&radius,&angle);
  859.     if (radius<0) alen = -alen;
  860.     polar_xy(alen,angle+arrow_angle,&dx,&dy);
  861.     *ax2 = cx+dx;  *ay2 = cy+dy;
  862.     polar_xy(alen,angle-arrow_angle,&dx,&dy);
  863.     *ax1 = cx+dx;  *ay1 = cy+dy;
  864.  
  865.     polar_xy(alen*cos(arrow_angle*3.141592/180),angle,&nx,&ny);
  866.     alen = width/2;
  867.     if (radius<0) alen = -alen;
  868.  
  869.     cx += nx; cy += ny;
  870.     *nnx = cx; *nny = cy;
  871. }
  872. g_arrow(double dx, double dy)
  873. {
  874.     double cx,cy,radius,angle,alen;
  875.     g_get_xy(&cx,&cy);
  876.     xy_polar(dx,dy,&radius,&angle);
  877.     g_get_hei(&alen);  alen = alen/2;
  878.     if (radius<0) alen = -alen;
  879.     polar_xy(alen,angle+10.0,&dx,&dy);
  880.     g_line(cx+dx,cy+dy);
  881.     g_move(cx,cy);
  882.     polar_xy(alen,angle-10.0,&dx,&dy);
  883.     g_line(cx+dx,cy+dy);
  884.     g_move(cx,cy);
  885. }
  886.  
  887. box_start(void)
  888. {
  889.     g_get_bounds(&box_x1[nbox],&box_y1[nbox],&box_x2[nbox],&box_y2[nbox]);
  890.     g_init_bounds();
  891.     nbox++;
  892.     box_add[nbox]=0;
  893.     box_fill[nbox] = 0;
  894.     box_name[nbox] = 0;
  895. }
  896. box_end(void)
  897. {
  898.     double x1,y1,x2,y2,ox,oy;
  899.     if (nbox==0) {
  900.         gprint("Too many end boxes \n");
  901.         return;
  902.     }
  903.     g_get_bounds(&x1,&y1,&x2,&y2);
  904.     if (x1>(x2+100)) return;
  905.     x1 -= box_add[nbox];    y1 -= box_add[nbox];
  906.     x2 += box_add[nbox];    y2 += box_add[nbox];
  907.     g_get_xy(&ox,&oy);
  908.     if (box_fill[nbox]!=0) {
  909.         g_set_fill(box_fill[nbox]);
  910.         g_box_fill(x1,y1,x2,y2);
  911.     }
  912.     if (!box_nobox[nbox]) {
  913.         g_box_stroke(x1,y1,x2,y2);
  914.     }
  915.     if (box_name[nbox]!=0) {
  916.         name_set(box_name[nbox],x1,y1,x2,y2);
  917.         myfree(box_name[nbox]);
  918.     }
  919.     nbox--;
  920.     if (box_x1[nbox] <= box_x2[nbox]) {
  921.         g_set_bounds(box_x1[nbox],box_y1[nbox]);
  922.         g_set_bounds(box_x2[nbox],box_y2[nbox]);
  923.     }
  924.     g_move(ox,oy);
  925. }
  926. int nm_adjust(int jj,double *sx, double *sy, double ex, double ey,
  927.     double x1, double y1, double x2, double y2);
  928. int nm_point(int jj,double *rx, double *ry, double x1,double y1,double x2,double y2);
  929. int nm_split(char *s, char *n, char *p);
  930. name_join(char *o1,char *o2,int marrow)
  931. {
  932.     char n1[40],n2[40],p1[9],p2[9],*ss;
  933.     double ox,oy,sx,sy,ex,ey,x,y,x1,y1,x2,y2,x3,y3,x4,y4;
  934.     int i,jj1,jj2;
  935.  
  936.     strupr(o1);    strupr(o2);
  937.     if (strstr(o1,".H")!=0 || strstr(o1,".V")!=0) {
  938.         ss = o1; o1 = o2; o2 = ss;
  939.         if (marrow==2) marrow = 1;
  940.         else if (marrow==1) marrow = 2;
  941.     }
  942.     nm_split(o1,n1,p1);
  943.     nm_split(o2,n2,p2);
  944.  
  945.     x1 = 1e30; x3 = 1e30;
  946.     name_get(n1,&x1,&y1,&x2,&y2);
  947.     name_get(n2,&x3,&y3,&x4,&y4);
  948.     if (x1==1e30 || x3 == 1e30) return;
  949.     jj1 = pass_justify(p1);
  950.     jj2 = pass_justify(p2);
  951.  
  952.     nm_point(jj1,&sx,&sy,x1,y1,x2,y2);
  953.     ex = sx; ey = sy;
  954.     nm_point(jj2,&ex,&ey,x3,y3,x4,y4);
  955.  
  956.     nm_adjust(jj1,&sx,&sy,ex,ey,x1,y1,x2,y2);
  957.     nm_adjust(jj2,&ex,&ey,sx,sy,x3,y3,x4,y4);
  958.  
  959.     g_get_xy(&ox,&oy);
  960.     g_move(sx,sy);
  961.     if (marrow==2) marrow = 1;
  962.     else if (marrow==1) marrow = 2;
  963.     g_arrowline(ex,ey,marrow);
  964.  
  965. /*     g_line(ex,ey);
  966.     x = ex-sx;
  967.     y = ey-sy;
  968.     if (x!=0 || y!=0) {
  969.         if (marrow & 1)  g_arrow(-x,-y);
  970.         g_move(sx,sy);
  971.         if (marrow & 2)  g_arrow(x,y);
  972.         g_move(ox,oy);
  973.  
  974.  
  975.     }
  976.  
  977. */
  978. }
  979. nm_point(int jj,double *rx, double *ry, double x1,double y1,double x2,double y2)
  980. {
  981.     int jx,jy;
  982.     double w,y,d;
  983.  
  984.     if ((jj == 0x2000)) { /* virtical */
  985.         if (y2<*ry) *ry = y2;
  986.         if (y1>*ry) *ry = y1;
  987.         return;
  988.     }
  989.     if ((jj == 0x3000)) { /* horizontal centre   */
  990.         if (x2<*rx) *rx = x2;
  991.         if (x1>*rx) *rx = x1;
  992.         return;
  993.     }
  994.     jx = (jj & 0xf0) / 16;
  995.     jy = jj & 0x0f;
  996.     d = jx * (x2-x1)/2;
  997.     *rx = x1 + d;
  998.     d = jy * (y2-y1)/2;
  999.     *ry = y1 + d;
  1000. }
  1001. nm_adjust(int jj,double *sx, double *sy, double ex, double ey,
  1002.     double x1, double y1, double x2, double y2)
  1003. {
  1004.     double r1,r2,xa,da,ca,dr,dx,dy,pi,rz,r;
  1005.     pi = 3.1415925;
  1006.     if ((jj & 0xf000)==0x5000) {
  1007.         r1 = (x2-x1)/2;
  1008.         r2 = (y2-y1)/2;
  1009.             xy_polar(*sx - ex,*sy - ey,&dr,&da);
  1010.         xa = da - 180;
  1011. xxxa:        if (xa > 180) xa = xa - 180;
  1012.         if (xa < 0) xa = xa + 180;
  1013.         if ((xa<0) || (xa> 180)) goto xxxa;
  1014.         if (r1==0) return;
  1015.         ca = atan(r2/r1)*180/pi;
  1016.         if (xa < 90) {
  1017.             rz = r1/cos(pi*xa/180);
  1018.             if (xa>ca) rz = r2/sin(pi*xa/180);
  1019.         } else {
  1020.             xa = xa - 90;
  1021.             rz = r2/cos(pi*xa/180);
  1022.             if (xa>(90-ca)) rz = r1/sin(pi*xa/180);
  1023.         }
  1024.         dr = dr - rz ;
  1025.         polar_xy(dr,da,&dx,&dy);
  1026.         *sx = ex + dx;
  1027.         *sy = ey + dy;
  1028.     }
  1029.     if ((jj & 0xff00)==0x1000) {
  1030.         r = (x2-x1)/2;
  1031.         xy_polar(*sx-ex,*sy-ey,&dr,&da);
  1032.         dr = dr - r;
  1033.         polar_xy(dr,da,&dx,&dy);
  1034.         *sx = ex + dx;
  1035.         *sy = ey + dy;
  1036.     }
  1037. }
  1038. nm_split(char *s, char *n, char *p)
  1039. {
  1040.     char *d;
  1041.     d = strchr(s,'.');
  1042.     if (d!=0) {
  1043.         ncpy(n,s,d-s);
  1044.         strcpy(p,d+1);
  1045.     } else {
  1046.         strcpy(n,s);
  1047.         strcpy(p,"BO");
  1048.     }
  1049. }
  1050.  
  1051. int f_getchan(void)
  1052. {
  1053.     int i;
  1054.     for (i=0; i<F_MAXCHAN; i++) {
  1055.         if (f_chan[i]==NULL) {
  1056.             return i;
  1057.         }
  1058.     }
  1059.     gprint("Fatal error, ran out of file handles, don't open so many\n");
  1060.     return 0;
  1061. }
  1062. void f_getline(int chn)
  1063. {
  1064.     char buff[1002];
  1065.     if (f_chan[chn]==NULL) {return;}
  1066.     if (f_read[chn]!=0) gprint("You cannot read from a file open for WRITe #%d %d \n",chn,f_read[chn]);
  1067.     if (fgets(buff,1000,f_chan[chn])==NULL) {
  1068.         f_end[chn] = true;
  1069.     }
  1070.     if (feof(f_chan[chn])) f_end[chn] = true;
  1071.     if (f_buff[chn]!=NULL) myfree(f_buff[chn]);
  1072.     f_buff[chn] = sdup(buff);
  1073. }
  1074. int f_eof(int chn)
  1075. {
  1076.     return f_end[chn];
  1077. }
  1078. char *f_gettok(int chn)
  1079. {
  1080.     static char thistok[80];
  1081.     if (f_end[chn]) gprint("Reading past end of file %d\n",chn);
  1082.     strcpy(thistok,f_nexttok[chn]);
  1083.     f_readahead(chn);
  1084.     return thistok;
  1085. }
  1086. void f_init()
  1087. {
  1088.     int i;
  1089.     for (i=0;i<F_MAXCHAN; i++) {
  1090.         if (f_chan[i] != NULL) {fclose(f_chan[i]); f_chan[i] = NULL;}
  1091.         siffree(&f_buff[i]);
  1092.         siffree(&f_nexttok[chn]);
  1093.     }
  1094. }
  1095. void f_readahead(chn)
  1096. {
  1097.     siffree(&f_nexttok[chn]);
  1098.     f_nexttok[chn] = sdup(f_getnext(chn));
  1099. }    
  1100. char *f_getnext(int chn)
  1101. {
  1102.     char *s;
  1103.     int blen;
  1104.     static char tk[81];
  1105.     if (f_buff[chn]==NULL) f_getline(chn);
  1106.     tk[0] = 0;
  1107. try_again:
  1108.     if (f_buff[chn]==NULL) return tk;
  1109.     blen = strlen(f_buff[chn]);
  1110.     s = strtok(f_buff[chn]," ,=\t\n\x0a\x0c\x0d");    
  1111.     if (s==NULL) goto next_line;
  1112.     strcpy(tk,s);
  1113.     if (strlen(s)==blen) f_buff[0] = 0;
  1114.     else strcpy(f_buff[chn],s+1+strlen(s));
  1115.     if (*s == '"' || *s == '!' || *s == ';') goto next_line;
  1116.     return tk;
  1117. next_line:
  1118.     if (f_eof(chn)) return tk;
  1119.     f_getline(chn);
  1120.     goto try_again;
  1121. }
  1122. void siffree(char **s) 
  1123. {
  1124.     if (*s != NULL) myfree(*s);
  1125.     *s = NULL;
  1126. }
  1127. int f_testchan(int chn)
  1128. {
  1129.     if (chn<0 || chn>F_MAXCHAN) {
  1130.         gprint("Error in channel number %d\n",chn);
  1131.         return 0;
  1132.     }
  1133.     return chn;
  1134. }
  1135.