home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / d / dots151.zip / GRAPHSRC.ZIP / GHP.C < prev    next >
C/C++ Source or Header  |  1990-07-15  |  16KB  |  568 lines

  1. /*    plot - interface routine for HP 7470A or 7475A plotter
  2.  
  3.     history...
  4.         15 Jul 90    Ver 1.20: can get parameters from configuration file
  5.         20 Jun 90    Ver 1.10: open->fopen.
  6.         25 Apr 89    dummy routines for flipping lines and setting background
  7.                     color.
  8.         23 Jun 86    Adapted from Houstin Instruments plotter routine
  9.         19 Feb 87    enquiry/acknowledge handshake added
  10.         22 Oct 87    switched to XON/XOFF handshaking
  11.         23 Oct 87    shifting origin of plot here, rather than trying to
  12.                     use plotter commands
  13.         27 Oct 87    switched to hardware handshaking (the HP default)
  14.                     Environment variable "plot_setup" can contain an
  15.                     alternate setup string.
  16.  
  17.     bugs...
  18. default file name should not be a port?
  19. environment function -> TC library routine
  20.         How small can the margins be?
  21.         Linestyles aren't working.
  22.         bench needs to check for "erasing"
  23.         g3x needs to call set_height to set character size.
  24. */
  25.  
  26. #include <stdio.h>
  27. #include <string.h>
  28. #include <math.h>
  29. #include "g.h"
  30. #include "config.h"
  31.  
  32. #define EOT 3
  33. #define ESC 27
  34. #define BUFSIZE 80
  35.  
  36.                 /* default margins, defined assuming portrait orientation */
  37. #define LMARGIN 1.30
  38. #define RMARGIN 1.00
  39. #define TMARGIN 1.5
  40. #define BMARGIN 1.5
  41.  
  42. #define WAIT
  43. /*  #define WAIT wait();     /*   if flow control is implemented here */
  44.  
  45.  
  46. /*    imported variables    */
  47.  
  48. extern char *default_script_file;
  49.  
  50. /*    exported graphics variables    */
  51.  
  52. char *machine        =    "Hewlett Packard 7470A";
  53. char *interface_version    =    "1.20";
  54. char *config_file    =    NULL;
  55. static char default_config_file[] = "GRAPHHP.CFG";
  56. int plotting_device    =    1;
  57. int erasing            =    0;
  58. int flipping        =    0;
  59.  
  60. int max_color        =    5;        /* for calling pgm, colors are 0...max_color */
  61.  
  62. int current_color    =    0;
  63. int pen_diameter    =    12;
  64. int pixels_wide        =    10000;        /* width of screen in pixels */
  65. int pixels_high        =    7200;        /* height of screen in pixels */
  66. double best_width    =    1.;
  67. double best_height    =    .720;        /* relative height/width parameters */
  68.  
  69. int char_rows        =    66;            /* text parameters */
  70. int    char_columns    =    133;
  71. int    char_height        =    167;
  72. int    char_width        =    100;
  73. int    x_offset        =    0;
  74. int    y_offset        =    0;
  75. int    char_v_adjusted    =    1;
  76. int    char_h_adjusted    =    1;
  77.  
  78. int has_cursor_keys    =    0;
  79. int    up_arrow        =    0x48;        /* cursor keys */
  80. int    down_arrow        =    0x50;
  81. int    left_arrow        =    0x4b;
  82. int    right_arrow        =    0x4d;
  83. int    escaped_arrows    =    1;            /* cursor keys are preceded by 0 */
  84. int    escape_char        =    0;
  85.  
  86. static int x0=0;    /* origin of plot */
  87. static int y0=0;
  88.  
  89. /* an 'A' on row r, column c  has lower left corner on raster 
  90.                 r*char_height + y_offset 
  91.     at pixel
  92.                 c*char_width + x_offset            */
  93.  
  94.  
  95. struct PRIM_ATTR prim_attr=
  96.     {5,     /* # colors                          */
  97.     1,      /* # intensities                     */
  98.     0,      /* nonzero if supported in hardware  */
  99.     6,      /* # linestyles in hardware          */
  100.     1,      /* # linestyles in software          */
  101.     1,      /* # linewidths                      */
  102.     0,      /* nonzero if supported in hardware  */
  103.     1,      /* minimum linewidth                 */
  104.     1,      /* maximum linewidth                 */
  105.     6,      /* # pens in hardware                */
  106.     0,      /* # pens in software                */
  107.     5,      /* # fonts                           */
  108.     99,     /* # character sizes                 */
  109.     1,      /* nonzero if supported in hardware  */
  110.     14,     /* minimum character height (pixels) */
  111.     7200,   /* maximum character height (pixels) */
  112.     0,      /* # markers in hardware             */
  113.     0,      /* # markers in software             */
  114.     0       /* # pick IDs in hardware            */
  115.     };
  116.  
  117.  
  118. static draw();
  119. static erase();
  120. static text();
  121. static character();
  122. char *getenv();
  123.  
  124. static font=0;
  125. static int plotter_type;
  126. FILE *plot_file;
  127. static file_open = 0;
  128. static int style_code=1;
  129. static int color_code=0;
  130. static cx=0, cy=0,    /*    actual position of pen  */
  131. down=0,                /*    nonzero if pen is down AND "PD" command issued */
  132. up=0;                /*    nonzero if pen is up AND "PU" command issued */
  133.  
  134. static set_style(style) int style;
  135. {    /*    implementing 6 styles, as follows:
  136.         code 0         solid
  137.         codes  1-5     HP styles 2-6
  138.    */
  139.     if(style<=0) 
  140.         {style=0;
  141.         if(style_code==style) return;
  142.         WAIT
  143.         fprintf(plot_file,"LT;");
  144.         }
  145.     else
  146.         {if(style>=prim_attr.hardware_linestyles)
  147.             style=prim_attr.hardware_linestyles-1;
  148.         if(style_code==style) return;
  149.         WAIT
  150.         fprintf(plot_file,"LT%d,3;",style+1);
  151.             /* pattern length is set to 3% of plotter diagonal 
  152.                 (default is 4%) */
  153.         }
  154.     style_code=style;
  155.     up=down=0;
  156. }
  157.  
  158. set_color(color) int color;
  159. {    if(color<0) color=0;
  160.     else if(color>max_color) color=max_color;
  161.     if(color_code==color+1) return;
  162.     color_code=color+1;
  163.     WAIT
  164.     fprintf(plot_file,"SP%d;",color_code);
  165.     up=down=0;
  166. }
  167.  
  168. /*    If no color has been set, use default (1st pen) */
  169. static get_pen()
  170. {    if(color_code==0) set_color(0);
  171. }    
  172.  
  173. set_intensity(intensity) double intensity; {}
  174. set_background_color(color) int color; {}
  175. set_background_intensity(intensity) double intensity; {}
  176.  
  177. inquire_color() {return (color_code-1);}
  178. double inquire_intensity() {return 1.;}
  179.  
  180. /*    draw - draw a straight line     */
  181.  
  182. static int draw(x1,y1,x2,y2) int x1,y1,x2,y2;
  183. {    int t,d1,d2;
  184.     get_pen();
  185.     y1= pixels_high-1-y1; y2= pixels_high-1-y2;
  186.     d1=maximum(abs(cx-x1),abs(cy-y1));
  187.     d2=maximum(abs(cx-x2),abs(cy-y2));
  188. #ifdef DEBUG
  189.     printf("\nat (%d,%d)  drawing (%d,%d)(%d away) to (%d,%d)(%d away)",
  190.      cx,cy,x1,y1,d1,x2,y2,d2);
  191. #endif
  192.     if(d2<d1)
  193.         {t=x1; x1=x2; x2=t; t=y1; y1=y2; y2=t; t=d1; d1=d2; d2=t;
  194. #ifdef DEBUG
  195.         puts("swapping");
  196. #endif
  197.         }
  198. #ifdef DEBUG
  199.     putchar('\n');
  200. #endif
  201.     WAIT
  202.     if(d1)
  203.         {if(!up) fprintf(plot_file,"\nPU");
  204.         fprintf(plot_file,"%d,%d,\nPD",x1+x0,y1+y0); down=1; up=0;
  205.         }
  206.     else if (!down) {fprintf(plot_file,"\nPD"); down=1; up=0;}
  207.     fprintf(plot_file,"%d,%d,",x2+x0,y2+y0);
  208.     cx=x2; cy=y2;
  209. }
  210.  
  211. /*    gotoxy - move pen to new position (used before text display) */
  212.  
  213. gotoxy(x,y) int x,y;
  214. {    y= pixels_high-1-y;
  215.     if (x<0) x=0; else if (x>=pixels_wide) x=pixels_wide-1;
  216.     if (y<0) y=0; else if (y>=pixels_high) y=pixels_high-1;
  217.     if(x==cx && y==cy) return;
  218.     WAIT
  219.     if(!up) {fprintf(plot_file,"PU"); down=0; up=1;}
  220.     fprintf(plot_file,"%d,%d,",x+x0,y+y0);
  221.     cx=x; cy=y;
  222. }
  223.  
  224. static nil() {}
  225.  
  226. /* exported function pointers */
  227. int (*draw_line)()    =    draw;
  228. int (*erase_line)()    =    nil;
  229. int (*draw_text)()    =    text;
  230. int (*draw_char)()    =    character;
  231. int (*flip_line)()    =    draw;
  232.  
  233. /*        init - initialize the graphics system    */
  234. init_graphics()
  235. {    int d1, d2, c, i, vel;
  236.     double w, wmax, h, hmax, left, top;
  237.     char buf[BUFSIZE], inbuf[BUFSIZE], *s, *t;
  238.     char *setup_string;
  239.  
  240.     static int offset_ask = 1,
  241.         size_ask = 1,
  242. /*        plotter_ask = 1, */
  243.         velocity_ask = 1,
  244.         file_ask = 0;
  245.     static double offset[2] = {BMARGIN, LMARGIN};
  246.     static double velocity = {38.};
  247.     static double size[2] = {11. - BMARGIN - TMARGIN, 8.5 - LMARGIN - RMARGIN};
  248.     static char *port_name = NULL;
  249.  
  250.     static PARAM parmv[] = {
  251.                 {'o', REAL, &offset_ask, offset, 2},
  252.                 {'l', REAL, &offset_ask, &offset[0]},
  253.                 {'t', REAL, &offset_ask, &offset[1]},
  254.                 {'s', REAL, &size_ask, size, 2},
  255.                 {'w', REAL, &size_ask, &size[0]},
  256.                 {'h', REAL, &size_ask, &size[1]},
  257. /*                {'p', BOOLEAN, &orientation_ask, &portrait, 0}, */
  258. /*                {'l', BOOLEAN, &orientation_ask, &landscape, 0}, */
  259.                 {'f', STRING, &file_ask, &port_name, 1},
  260. /*                {'n', STRING, &plotter_ask, &plotter_name, 1}, */
  261.                 {'v', REAL, &velocity_ask, &velocity, 1},
  262.                 {'\0'}};
  263.  
  264.     if(config_file == NULL) config_file = default_config_file;
  265.     config(config_file, NULL, parmv, buf, BUFSIZE);
  266.  
  267.     if(port_name == NULL && version() >= 0x200)
  268.         port_name = getenv("PLOT_PORT");
  269.     if(port_name == NULL) 
  270.         {port_name = strncpy(buf, default_script_file, BUFSIZE-4);
  271.         s = strchr(port_name, '.');
  272.         if(s != NULL) *s = 0;
  273.         strcat(port_name, ".hp");
  274.         }
  275.  
  276.     if(file_ask)
  277.         {port_name = strncpy(buf, port_name, BUFSIZE);
  278.         printf("Enter output file                        (default %s): ",buf);
  279.         gets(inbuf);
  280.         if(inbuf[0]) strcpy(buf,inbuf);
  281.         }
  282.     else
  283.         printf("\noutput written to %s\n", port_name);
  284.  
  285.     unlink(port_name);                /* delete the file if it exists */
  286.     plot_file=fopen(port_name,"w");        /* this will open a file or device */
  287.     if(plot_file==NULL) {printf("can\'t open output file %s", port_name); exit();}
  288.     file_open = 1;
  289.  
  290.     setup_string = NULL;
  291.     if(version()>=0x200) setup_string = getenv("PLOT_SETUP");
  292.     if(setup_string == NULL) setup_string = strcpy(buf," DF; \033.R ");
  293.     /*    
  294.         default conditions
  295.         reset handshake to hardware flow control 
  296.             (The plotter uses RS-232 connector pin 20, or DTR.  
  297.             It pulls the pin low to stop data transmission.)
  298.     */
  299.     fixup_escapes(setup_string);
  300.     fprintf(plot_file,"\033.Y DT%c; %s\n", EOT, setup_string);
  301.     /*    
  302.         plotter on
  303.         set end of text character
  304.     */
  305.  
  306.     vel=velocity;
  307.     if(velocity_ask)
  308.         {printf("\nEnter pen velocity                 (default %d cm/sec): ",
  309.                                                                     vel);
  310.         gets(buf);
  311.         if(buf[0]) sscanf(buf,"%d",&vel);
  312.         }
  313.     if(vel<=0) vel=38;
  314.     fprintf(plot_file,"VS%d;",vel);             /* set velocity */
  315.  
  316.     w=h=0.;
  317.  
  318.                                  /* set margins */
  319.     left = offset[0];
  320.     top = offset[1];
  321.     while(1)
  322.         {if(offset_ask)
  323.             {printf("\nEnter left and top margin in inches \n");
  324.             printf("                             (default %5.2f and %5.2f): ",
  325.                                                                     left,top);
  326.             gets(buf); if(buf[0]) sscanf(buf,"%lf %lf",&left,&top);
  327.             }
  328.         if(left<0.2 || left>10.)
  329.             printf("left margin outside valid range .2 - 10.\n");
  330.         if(top<1.3 || top>7.2)
  331.             printf("top margin outside valid range 1.3 - 7.2\n");
  332.         else  
  333.             break;
  334.         left = BMARGIN;
  335.         top = LMARGIN;
  336.         offset_ask = 1;
  337.         }
  338.  
  339.     w=size[0]; h=size[1];
  340.     while(1)
  341.         {if(size_ask)
  342.             {
  343.             printf("\nEnter width and height of plot area in inches \n");
  344.             printf("                             (default, %5.3f by %5.3f): ", w, h);
  345.             gets(buf); if(buf[0]) sscanf(buf,"%lf %lf",&w,&h);
  346.             }
  347.  
  348.         hmax = wmax = 48.;
  349.         h = floor(h*100. + .5)/100.;
  350.         w = floor(w*100. + .5)/100.;
  351.  
  352.         if(w < .1 || w > wmax)
  353.             printf("width outside valid range 0.1 to %2.3f\n", wmax);
  354.         else if(h < .1 || h > hmax)
  355.             printf("height outside valid range 0.1 to %2.3f\n", hmax);
  356.         else break;
  357.                             /* set defaults for next time */
  358.         h = 6.25;
  359.         w = 8.;
  360.         size_ask = 1;
  361.         }
  362.  
  363.     x0=(int)((left)/.001);
  364.     y0=(int)((8.5-top-h)/.001);
  365.  
  366.     pixels_wide=w/.001;
  367.     pixels_high=h/.001;
  368.  
  369.     if(pixels_wide>=pixels_high)         /* landscape style */
  370.         {best_width=1.;
  371.         best_height=(double)pixels_high/pixels_wide;
  372.         }
  373.     else                                 /* portrait style */
  374.         {best_height=1.;
  375.         best_width=(double)pixels_wide/pixels_high;
  376.         }
  377.     set_height(char_width, char_height);
  378. }
  379.  
  380. /* character sizes in units of .005 inch */
  381.      /* interpret escape sequences in setup string...
  382.                          "$e" -> escape char, 
  383.                          "\n" -> line feed 
  384.                          "\r" -> carriage return
  385.                          "\t" -> tab
  386.                          "\c" -> c (escape an otherwise special character) */
  387. fixup_escapes(s) char *s;
  388. {    char *t;
  389.     for (t=s; *s; s++)
  390.         {if(*s=='$' && s[1]=='e') {*t++=0x1b; s++;}
  391.         else if(*s=='\\' && s[1]=='n') {*t++='\n'; s++;}
  392.         else if(*s=='\\' && s[1]=='t') {*t++='\t'; s++;}
  393.         else if(*s=='\\' && s[1]=='r') {*t++='\r'; s++;}
  394.         else if(*s=='\\') {*t++=s[1]; s++;}
  395.         else *t++=*s;
  396.         }
  397.     *t=0;
  398. }
  399.  
  400. static text(s) char *s;
  401. {    char *t,c;
  402.     get_pen();
  403.     t=s;
  404.     while(*t)
  405.         {c= *t&127;
  406.         if(c<32 || c>126 || c==EOT) *t=' ';
  407.         t++;
  408.         }
  409.     WAIT
  410.     fprintf(plot_file,"LB%s%c\n",s,EOT);
  411.     up=down=0; cx=cy=-2000;
  412. }
  413.  
  414. static character(c) char c;
  415. {    if(c<32 || c>126 || c==EOT) return;
  416.     get_pen();
  417.     WAIT
  418.     fprintf(plot_file,"LB%c%c",c,EOT);
  419.     up=down=0; cx=cy=-2000;
  420. }
  421.  
  422. static set_height(w, h)
  423. int w, h;  /* width and height in units of .001" */
  424. {    if(h<40) h=40;
  425.     else if(h>7100) h=7100;
  426.     if(w<30) w=30;
  427.     else if(w>5300) w=5300;
  428.     char_width=w; char_height=h;
  429.     char_columns=pixels_wide/char_width;
  430.     char_rows=pixels_high/char_height;
  431.     x_offset=0; y_offset=char_height-1;
  432.     WAIT
  433.         /*    note char width is 67% of char spacing, and
  434.             char height is 50% of line spacing  */
  435.     fprintf(plot_file, "SI%4.3f,%4.3f;\n", w*.00254*.67, h*.00254*.5);
  436.     up=down=0;
  437. }
  438.  
  439. version()    /* return MS-DOS version number. Version 2.01 returned as 0x201 */
  440. {
  441. #ifdef __DESMET__
  442.     extern unsigned _rax;
  443.     _rax=0x3000;
  444.     _doint(0x21);
  445.     return ( (_rax&0xff)<<8 | (_rax&0xff00)>>8 );
  446. #else
  447. #include <dos.h>
  448.     return ( (_version&0xff)<<8 | (_version&0xff00)>>8 );
  449. #endif
  450. }
  451.  
  452. #ifdef __DESMET__
  453. /*    search environment for given string */
  454.  
  455. getenv(target) char *target;
  456. {    char buf[256],*s,t[25],*env, *malloc();
  457.     int nt,offset;
  458.  
  459.     s=t;
  460.     while(*target) *s++=toupper(*target++);
  461.     *s++= '='; *s=0;
  462.     nt = strlen(t);
  463.     offset=0;
  464.     _lmove(2,44,_showcs()-0x10,&env,_showds());
  465.     while(1)
  466.         {_lmove(256,offset,env,buf,_showds());
  467.         s=buf;
  468.         if(*s)
  469.             {/* printf("examining entry: %s \n",s); getchar(); */
  470.             if (strncmp(t,s,nt)==0) 
  471.                 {env = malloc(strlen(s+nt)+1);
  472.                 if(env == NULL) return NULL;
  473.                 return strcpy(env, s+nt);
  474.                 }
  475.             }
  476.         else return NULL;
  477.         offset+=strlen(buf)+1;
  478.         }
  479. }
  480. #endif /* DESMET */
  481.  
  482. /*        finish - close down the graphics system     */
  483.  
  484. finish_graphics()
  485. {    if(file_open)
  486.         {WAIT
  487.  
  488.             /* pen up, stow pen, plotter off */
  489.         fprintf(plot_file,"PU0,7200; SP; \033.Z \n"); 
  490.  
  491.         fclose(plot_file);
  492.         file_open = 0;
  493.         }
  494. }
  495.  
  496. clear_graphics()
  497. {    WAIT
  498.     fprintf(plot_file,"PU"); up=down=0;
  499.     puts("please replace paper (press spacebar when finished)");
  500.     getchar();
  501. }
  502.  
  503.  
  504. /*    pointers to optional functions (NULL if not implemented)    */
  505.  
  506. int    (*new_linewidth)()=0;    /* (*new_linewidth)(width) int width; */
  507. int    (*new_linestyle)()=set_style;    /* (*new_linestyle)(style) int style; */
  508. int    (*new_charsize)()=set_height;    /* (*new_charsize)(w,h) int w,h; */
  509. int    (*draw_marker)()=0;    /* (*draw_marker)(n) int n; */
  510.  
  511. #ifdef MAIN
  512.  
  513. main()
  514. {    char buf[100];
  515.     printf("Interface %s for the %s\n",interface_version,machine);
  516.     init_graphics();
  517.     printf("screen width %d pixels\nheight %d pixels\n",
  518.         pixels_wide,pixels_high);
  519.     printf("height:width ratio %f:%f\n",best_height,best_width);
  520.     printf("%d colors\n",max_color+1);
  521.     printf("primitive attributes...\n");
  522.     printf("color_count=               %d \n",prim_attr.color_count);
  523.     printf("intensity_count=           %d \n",prim_attr.intensity_count);
  524.     printf("intensities_in_hardware=   %d \n",prim_attr.intensities_in_hardware);
  525.     printf("hardware_linestyles=       %d \n",prim_attr.hardware_linestyles);
  526.     printf("software_linestyles=       %d \n",prim_attr.software_linestyles);
  527.     printf("linewidth_count=           %d \n",prim_attr.linewidth_count);
  528.     printf("linewidths_in_hardware=    %d \n",prim_attr.linewidths_in_hardware);
  529.     printf("linewidth_minimum=         %d \n",prim_attr.linewidth_minimum);
  530.     printf("linewidth_maximum=         %d \n",prim_attr.linewidth_maximum);
  531.     printf("hardware_pens=             %d \n",prim_attr.hardware_pens);
  532.     printf("software_pens=             %d \n",prim_attr.software_pens);
  533.     printf("charfont_count=            %d \n",prim_attr.charfont_count);
  534.     printf("charsize_count=            %d \n",prim_attr.charsize_count);
  535.     printf("charsize_in_hardware=      %d \n",prim_attr.charsize_in_hardware);
  536.     printf("charsize_minimum=          %d \n",prim_attr.charsize_minimum);
  537.     printf("charsize_maximum=          %d \n",prim_attr.charsize_maximum);
  538.     printf("hardware_markers=          %d \n",prim_attr.hardware_markers);
  539.     printf("software_markers=          %d \n",prim_attr.software_markers);
  540.     printf("pick_id_count=             %d \n",prim_attr.pick_id_count);
  541.     (*draw_line)(2,4,200,-400);
  542.     (*draw_line)(20,40,100,-200);
  543.     (*erase_line)(2,4,200,-400);
  544.     (*draw_line)(10,30,100,300);
  545.     (*draw_line)(10,40,500,890);
  546.     (*draw_line)(10,40,500,32);
  547.     (*draw_line)(10,1000,78,8900);
  548.     gotoxy(10,-20);
  549.     (*draw_text)(" ello\nDolly ");
  550.     (*draw_char)('H');
  551.     finish_graphics();
  552. }
  553.  
  554. #endif
  555.  
  556. maximum(a,b) int a,b;
  557. {    if (a>b) return a;
  558.     return b;
  559. }
  560.  
  561. /*
  562. /*    wait()    /* wait for plotter buffer space */
  563. /*    {
  564. /*        fprintf(plot_file,"\022?");  /* enquiry is DC2 '?' */
  565. /*        fgetc(plot_file);
  566. /*    }
  567. /**/
  568.