home *** CD-ROM | disk | FTP | other *** search
- /* plot - interface routine for HP 7470A or 7475A plotter
-
- history...
- 15 Jul 90 Ver 1.20: can get parameters from configuration file
- 20 Jun 90 Ver 1.10: open->fopen.
- 25 Apr 89 dummy routines for flipping lines and setting background
- color.
- 23 Jun 86 Adapted from Houstin Instruments plotter routine
- 19 Feb 87 enquiry/acknowledge handshake added
- 22 Oct 87 switched to XON/XOFF handshaking
- 23 Oct 87 shifting origin of plot here, rather than trying to
- use plotter commands
- 27 Oct 87 switched to hardware handshaking (the HP default)
- Environment variable "plot_setup" can contain an
- alternate setup string.
-
- bugs...
- default file name should not be a port?
- environment function -> TC library routine
- How small can the margins be?
- Linestyles aren't working.
- bench needs to check for "erasing"
- g3x needs to call set_height to set character size.
- */
-
- #include <stdio.h>
- #include <string.h>
- #include <math.h>
- #include "g.h"
- #include "config.h"
-
- #define EOT 3
- #define ESC 27
- #define BUFSIZE 80
-
- /* default margins, defined assuming portrait orientation */
- #define LMARGIN 1.30
- #define RMARGIN 1.00
- #define TMARGIN 1.5
- #define BMARGIN 1.5
-
- #define WAIT
- /* #define WAIT wait(); /* if flow control is implemented here */
-
-
- /* imported variables */
-
- extern char *default_script_file;
-
- /* exported graphics variables */
-
- char *machine = "Hewlett Packard 7470A";
- char *interface_version = "1.20";
- char *config_file = NULL;
- static char default_config_file[] = "GRAPHHP.CFG";
- int plotting_device = 1;
- int erasing = 0;
- int flipping = 0;
-
- int max_color = 5; /* for calling pgm, colors are 0...max_color */
-
- int current_color = 0;
- int pen_diameter = 12;
- int pixels_wide = 10000; /* width of screen in pixels */
- int pixels_high = 7200; /* height of screen in pixels */
- double best_width = 1.;
- double best_height = .720; /* relative height/width parameters */
-
- int char_rows = 66; /* text parameters */
- int char_columns = 133;
- int char_height = 167;
- int char_width = 100;
- int x_offset = 0;
- int y_offset = 0;
- int char_v_adjusted = 1;
- int char_h_adjusted = 1;
-
- int has_cursor_keys = 0;
- int up_arrow = 0x48; /* cursor keys */
- int down_arrow = 0x50;
- int left_arrow = 0x4b;
- int right_arrow = 0x4d;
- int escaped_arrows = 1; /* cursor keys are preceded by 0 */
- int escape_char = 0;
-
- static int x0=0; /* origin of plot */
- static int y0=0;
-
- /* an 'A' on row r, column c has lower left corner on raster
- r*char_height + y_offset
- at pixel
- c*char_width + x_offset */
-
-
- struct PRIM_ATTR prim_attr=
- {5, /* # colors */
- 1, /* # intensities */
- 0, /* nonzero if supported in hardware */
- 6, /* # linestyles in hardware */
- 1, /* # linestyles in software */
- 1, /* # linewidths */
- 0, /* nonzero if supported in hardware */
- 1, /* minimum linewidth */
- 1, /* maximum linewidth */
- 6, /* # pens in hardware */
- 0, /* # pens in software */
- 5, /* # fonts */
- 99, /* # character sizes */
- 1, /* nonzero if supported in hardware */
- 14, /* minimum character height (pixels) */
- 7200, /* maximum character height (pixels) */
- 0, /* # markers in hardware */
- 0, /* # markers in software */
- 0 /* # pick IDs in hardware */
- };
-
-
- static draw();
- static erase();
- static text();
- static character();
- char *getenv();
-
- static font=0;
- static int plotter_type;
- FILE *plot_file;
- static file_open = 0;
- static int style_code=1;
- static int color_code=0;
- static cx=0, cy=0, /* actual position of pen */
- down=0, /* nonzero if pen is down AND "PD" command issued */
- up=0; /* nonzero if pen is up AND "PU" command issued */
-
- static set_style(style) int style;
- { /* implementing 6 styles, as follows:
- code 0 solid
- codes 1-5 HP styles 2-6
- */
- if(style<=0)
- {style=0;
- if(style_code==style) return;
- WAIT
- fprintf(plot_file,"LT;");
- }
- else
- {if(style>=prim_attr.hardware_linestyles)
- style=prim_attr.hardware_linestyles-1;
- if(style_code==style) return;
- WAIT
- fprintf(plot_file,"LT%d,3;",style+1);
- /* pattern length is set to 3% of plotter diagonal
- (default is 4%) */
- }
- style_code=style;
- up=down=0;
- }
-
- set_color(color) int color;
- { if(color<0) color=0;
- else if(color>max_color) color=max_color;
- if(color_code==color+1) return;
- color_code=color+1;
- WAIT
- fprintf(plot_file,"SP%d;",color_code);
- up=down=0;
- }
-
- /* If no color has been set, use default (1st pen) */
- static get_pen()
- { if(color_code==0) set_color(0);
- }
-
- set_intensity(intensity) double intensity; {}
- set_background_color(color) int color; {}
- set_background_intensity(intensity) double intensity; {}
-
- inquire_color() {return (color_code-1);}
- double inquire_intensity() {return 1.;}
-
- /* draw - draw a straight line */
-
- static int draw(x1,y1,x2,y2) int x1,y1,x2,y2;
- { int t,d1,d2;
- get_pen();
- y1= pixels_high-1-y1; y2= pixels_high-1-y2;
- d1=maximum(abs(cx-x1),abs(cy-y1));
- d2=maximum(abs(cx-x2),abs(cy-y2));
- #ifdef DEBUG
- printf("\nat (%d,%d) drawing (%d,%d)(%d away) to (%d,%d)(%d away)",
- cx,cy,x1,y1,d1,x2,y2,d2);
- #endif
- if(d2<d1)
- {t=x1; x1=x2; x2=t; t=y1; y1=y2; y2=t; t=d1; d1=d2; d2=t;
- #ifdef DEBUG
- puts("swapping");
- #endif
- }
- #ifdef DEBUG
- putchar('\n');
- #endif
- WAIT
- if(d1)
- {if(!up) fprintf(plot_file,"\nPU");
- fprintf(plot_file,"%d,%d,\nPD",x1+x0,y1+y0); down=1; up=0;
- }
- else if (!down) {fprintf(plot_file,"\nPD"); down=1; up=0;}
- fprintf(plot_file,"%d,%d,",x2+x0,y2+y0);
- cx=x2; cy=y2;
- }
-
- /* gotoxy - move pen to new position (used before text display) */
-
- gotoxy(x,y) int x,y;
- { y= pixels_high-1-y;
- if (x<0) x=0; else if (x>=pixels_wide) x=pixels_wide-1;
- if (y<0) y=0; else if (y>=pixels_high) y=pixels_high-1;
- if(x==cx && y==cy) return;
- WAIT
- if(!up) {fprintf(plot_file,"PU"); down=0; up=1;}
- fprintf(plot_file,"%d,%d,",x+x0,y+y0);
- cx=x; cy=y;
- }
-
- static nil() {}
-
- /* exported function pointers */
- int (*draw_line)() = draw;
- int (*erase_line)() = nil;
- int (*draw_text)() = text;
- int (*draw_char)() = character;
- int (*flip_line)() = draw;
-
- /* init - initialize the graphics system */
- init_graphics()
- { int d1, d2, c, i, vel;
- double w, wmax, h, hmax, left, top;
- char buf[BUFSIZE], inbuf[BUFSIZE], *s, *t;
- char *setup_string;
-
- static int offset_ask = 1,
- size_ask = 1,
- /* plotter_ask = 1, */
- velocity_ask = 1,
- file_ask = 0;
- static double offset[2] = {BMARGIN, LMARGIN};
- static double velocity = {38.};
- static double size[2] = {11. - BMARGIN - TMARGIN, 8.5 - LMARGIN - RMARGIN};
- static char *port_name = NULL;
-
- static PARAM parmv[] = {
- {'o', REAL, &offset_ask, offset, 2},
- {'l', REAL, &offset_ask, &offset[0]},
- {'t', REAL, &offset_ask, &offset[1]},
- {'s', REAL, &size_ask, size, 2},
- {'w', REAL, &size_ask, &size[0]},
- {'h', REAL, &size_ask, &size[1]},
- /* {'p', BOOLEAN, &orientation_ask, &portrait, 0}, */
- /* {'l', BOOLEAN, &orientation_ask, &landscape, 0}, */
- {'f', STRING, &file_ask, &port_name, 1},
- /* {'n', STRING, &plotter_ask, &plotter_name, 1}, */
- {'v', REAL, &velocity_ask, &velocity, 1},
- {'\0'}};
-
- if(config_file == NULL) config_file = default_config_file;
- config(config_file, NULL, parmv, buf, BUFSIZE);
-
- if(port_name == NULL && version() >= 0x200)
- port_name = getenv("PLOT_PORT");
- if(port_name == NULL)
- {port_name = strncpy(buf, default_script_file, BUFSIZE-4);
- s = strchr(port_name, '.');
- if(s != NULL) *s = 0;
- strcat(port_name, ".hp");
- }
-
- if(file_ask)
- {port_name = strncpy(buf, port_name, BUFSIZE);
- printf("Enter output file (default %s): ",buf);
- gets(inbuf);
- if(inbuf[0]) strcpy(buf,inbuf);
- }
- else
- printf("\noutput written to %s\n", port_name);
-
- unlink(port_name); /* delete the file if it exists */
- plot_file=fopen(port_name,"w"); /* this will open a file or device */
- if(plot_file==NULL) {printf("can\'t open output file %s", port_name); exit();}
- file_open = 1;
-
- setup_string = NULL;
- if(version()>=0x200) setup_string = getenv("PLOT_SETUP");
- if(setup_string == NULL) setup_string = strcpy(buf," DF; \033.R ");
- /*
- default conditions
- reset handshake to hardware flow control
- (The plotter uses RS-232 connector pin 20, or DTR.
- It pulls the pin low to stop data transmission.)
- */
- fixup_escapes(setup_string);
- fprintf(plot_file,"\033.Y DT%c; %s\n", EOT, setup_string);
- /*
- plotter on
- set end of text character
- */
-
- vel=velocity;
- if(velocity_ask)
- {printf("\nEnter pen velocity (default %d cm/sec): ",
- vel);
- gets(buf);
- if(buf[0]) sscanf(buf,"%d",&vel);
- }
- if(vel<=0) vel=38;
- fprintf(plot_file,"VS%d;",vel); /* set velocity */
-
- w=h=0.;
-
- /* set margins */
- left = offset[0];
- top = offset[1];
- while(1)
- {if(offset_ask)
- {printf("\nEnter left and top margin in inches \n");
- printf(" (default %5.2f and %5.2f): ",
- left,top);
- gets(buf); if(buf[0]) sscanf(buf,"%lf %lf",&left,&top);
- }
- if(left<0.2 || left>10.)
- printf("left margin outside valid range .2 - 10.\n");
- if(top<1.3 || top>7.2)
- printf("top margin outside valid range 1.3 - 7.2\n");
- else
- break;
- left = BMARGIN;
- top = LMARGIN;
- offset_ask = 1;
- }
-
- w=size[0]; h=size[1];
- while(1)
- {if(size_ask)
- {
- printf("\nEnter width and height of plot area in inches \n");
- printf(" (default, %5.3f by %5.3f): ", w, h);
- gets(buf); if(buf[0]) sscanf(buf,"%lf %lf",&w,&h);
- }
-
- hmax = wmax = 48.;
- h = floor(h*100. + .5)/100.;
- w = floor(w*100. + .5)/100.;
-
- if(w < .1 || w > wmax)
- printf("width outside valid range 0.1 to %2.3f\n", wmax);
- else if(h < .1 || h > hmax)
- printf("height outside valid range 0.1 to %2.3f\n", hmax);
- else break;
- /* set defaults for next time */
- h = 6.25;
- w = 8.;
- size_ask = 1;
- }
-
- x0=(int)((left)/.001);
- y0=(int)((8.5-top-h)/.001);
-
- pixels_wide=w/.001;
- pixels_high=h/.001;
-
- if(pixels_wide>=pixels_high) /* landscape style */
- {best_width=1.;
- best_height=(double)pixels_high/pixels_wide;
- }
- else /* portrait style */
- {best_height=1.;
- best_width=(double)pixels_wide/pixels_high;
- }
- set_height(char_width, char_height);
- }
-
- /* character sizes in units of .005 inch */
- /* interpret escape sequences in setup string...
- "$e" -> escape char,
- "\n" -> line feed
- "\r" -> carriage return
- "\t" -> tab
- "\c" -> c (escape an otherwise special character) */
- fixup_escapes(s) char *s;
- { char *t;
- for (t=s; *s; s++)
- {if(*s=='$' && s[1]=='e') {*t++=0x1b; s++;}
- else if(*s=='\\' && s[1]=='n') {*t++='\n'; s++;}
- else if(*s=='\\' && s[1]=='t') {*t++='\t'; s++;}
- else if(*s=='\\' && s[1]=='r') {*t++='\r'; s++;}
- else if(*s=='\\') {*t++=s[1]; s++;}
- else *t++=*s;
- }
- *t=0;
- }
-
- static text(s) char *s;
- { char *t,c;
- get_pen();
- t=s;
- while(*t)
- {c= *t&127;
- if(c<32 || c>126 || c==EOT) *t=' ';
- t++;
- }
- WAIT
- fprintf(plot_file,"LB%s%c\n",s,EOT);
- up=down=0; cx=cy=-2000;
- }
-
- static character(c) char c;
- { if(c<32 || c>126 || c==EOT) return;
- get_pen();
- WAIT
- fprintf(plot_file,"LB%c%c",c,EOT);
- up=down=0; cx=cy=-2000;
- }
-
- static set_height(w, h)
- int w, h; /* width and height in units of .001" */
- { if(h<40) h=40;
- else if(h>7100) h=7100;
- if(w<30) w=30;
- else if(w>5300) w=5300;
- char_width=w; char_height=h;
- char_columns=pixels_wide/char_width;
- char_rows=pixels_high/char_height;
- x_offset=0; y_offset=char_height-1;
- WAIT
- /* note char width is 67% of char spacing, and
- char height is 50% of line spacing */
- fprintf(plot_file, "SI%4.3f,%4.3f;\n", w*.00254*.67, h*.00254*.5);
- up=down=0;
- }
-
- version() /* return MS-DOS version number. Version 2.01 returned as 0x201 */
- {
- #ifdef __DESMET__
- extern unsigned _rax;
- _rax=0x3000;
- _doint(0x21);
- return ( (_rax&0xff)<<8 | (_rax&0xff00)>>8 );
- #else
- #include <dos.h>
- return ( (_version&0xff)<<8 | (_version&0xff00)>>8 );
- #endif
- }
-
- #ifdef __DESMET__
- /* search environment for given string */
-
- getenv(target) char *target;
- { char buf[256],*s,t[25],*env, *malloc();
- int nt,offset;
-
- s=t;
- while(*target) *s++=toupper(*target++);
- *s++= '='; *s=0;
- nt = strlen(t);
- offset=0;
- _lmove(2,44,_showcs()-0x10,&env,_showds());
- while(1)
- {_lmove(256,offset,env,buf,_showds());
- s=buf;
- if(*s)
- {/* printf("examining entry: %s \n",s); getchar(); */
- if (strncmp(t,s,nt)==0)
- {env = malloc(strlen(s+nt)+1);
- if(env == NULL) return NULL;
- return strcpy(env, s+nt);
- }
- }
- else return NULL;
- offset+=strlen(buf)+1;
- }
- }
- #endif /* DESMET */
-
- /* finish - close down the graphics system */
-
- finish_graphics()
- { if(file_open)
- {WAIT
-
- /* pen up, stow pen, plotter off */
- fprintf(plot_file,"PU0,7200; SP; \033.Z \n");
-
- fclose(plot_file);
- file_open = 0;
- }
- }
-
- clear_graphics()
- { WAIT
- fprintf(plot_file,"PU"); up=down=0;
- puts("please replace paper (press spacebar when finished)");
- getchar();
- }
-
-
- /* pointers to optional functions (NULL if not implemented) */
-
- int (*new_linewidth)()=0; /* (*new_linewidth)(width) int width; */
- int (*new_linestyle)()=set_style; /* (*new_linestyle)(style) int style; */
- int (*new_charsize)()=set_height; /* (*new_charsize)(w,h) int w,h; */
- int (*draw_marker)()=0; /* (*draw_marker)(n) int n; */
-
- #ifdef MAIN
-
- main()
- { char buf[100];
- printf("Interface %s for the %s\n",interface_version,machine);
- init_graphics();
- printf("screen width %d pixels\nheight %d pixels\n",
- pixels_wide,pixels_high);
- printf("height:width ratio %f:%f\n",best_height,best_width);
- printf("%d colors\n",max_color+1);
- printf("primitive attributes...\n");
- printf("color_count= %d \n",prim_attr.color_count);
- printf("intensity_count= %d \n",prim_attr.intensity_count);
- printf("intensities_in_hardware= %d \n",prim_attr.intensities_in_hardware);
- printf("hardware_linestyles= %d \n",prim_attr.hardware_linestyles);
- printf("software_linestyles= %d \n",prim_attr.software_linestyles);
- printf("linewidth_count= %d \n",prim_attr.linewidth_count);
- printf("linewidths_in_hardware= %d \n",prim_attr.linewidths_in_hardware);
- printf("linewidth_minimum= %d \n",prim_attr.linewidth_minimum);
- printf("linewidth_maximum= %d \n",prim_attr.linewidth_maximum);
- printf("hardware_pens= %d \n",prim_attr.hardware_pens);
- printf("software_pens= %d \n",prim_attr.software_pens);
- printf("charfont_count= %d \n",prim_attr.charfont_count);
- printf("charsize_count= %d \n",prim_attr.charsize_count);
- printf("charsize_in_hardware= %d \n",prim_attr.charsize_in_hardware);
- printf("charsize_minimum= %d \n",prim_attr.charsize_minimum);
- printf("charsize_maximum= %d \n",prim_attr.charsize_maximum);
- printf("hardware_markers= %d \n",prim_attr.hardware_markers);
- printf("software_markers= %d \n",prim_attr.software_markers);
- printf("pick_id_count= %d \n",prim_attr.pick_id_count);
- (*draw_line)(2,4,200,-400);
- (*draw_line)(20,40,100,-200);
- (*erase_line)(2,4,200,-400);
- (*draw_line)(10,30,100,300);
- (*draw_line)(10,40,500,890);
- (*draw_line)(10,40,500,32);
- (*draw_line)(10,1000,78,8900);
- gotoxy(10,-20);
- (*draw_text)(" ello\nDolly ");
- (*draw_char)('H');
- finish_graphics();
- }
-
- #endif
-
- maximum(a,b) int a,b;
- { if (a>b) return a;
- return b;
- }
-
- /*
- /* wait() /* wait for plotter buffer space */
- /* {
- /* fprintf(plot_file,"\022?"); /* enquiry is DC2 '?' */
- /* fgetc(plot_file);
- /* }
- /**/
-