rsalz@uunet.UU.NET (Rich Salz) (10/10/87)
Submitted-by: rsk@j.cc.purdue.edu (Whitewater Wombat) Posting-number: Volume 12, Issue 3 Archive-name: crc.pch # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # README # gd.c # gp.c # gplp.c # hpd.c # font-mods cat << \SHAR_EOF > README This patch contains two different items: first, the four drivers omitted from the original release. This was a botch on my part--we don't use these drivers, and so when I packed up the sources to ship them out, I didn't include them. The drivers are supposed to handle Printronix, Versatec, Grinnel, Comtal, and HP devices. The second item, "font-mods", is some recent work done by Malcolm Slaney which allows the font used by this package to be kept in memory. It's not in "patch" format--I'm enclosing exactly what I received. Finally, I have received some correspondence from various folks about this package...which I'm in the process of answering. However, please note that I do NOT officially support this package, and so I can only put a little bit of time into this. -- Rich Kulawiec, rsk@s.cc.purdue.edu, s.cc.purdue.edu!rsk SHAR_EOF cat << \SHAR_EOF > gd.c /* gd - graphics driver for the Comtal and the Grinnel The CRC graphics package Carl Crawford Purdue University W. Lafayette, IN 47907 September 1981 Cleaned up to support the new improved Grinnell Malcolm Slaney October 1983 */ #include <stdio.h> #include <signal.h> #include <sys/types.h> #include <netinet/in.h> #define L (512 / sizeof(short)) #define M (16384 / L) #define COMTAL 0 #define GRINNELL 1 #define IMAGE 0 #define OVERLAY 1 #define Grinnell "/dev/Gr/" #define Comtal "/dev/ct" #define Overlay "gov" char OutputDevice[BUFSIZ]; char buf[512],bb[512],*bf,*cf; unsigned short ibuf[L*M],kbuf[L*M]; unsigned short *pp,*qq; int Device = COMTAL; /* Comtal or Grinnell */ int Mode = OVERLAY; /* Overlay or Image Plane */ int Number = 0; /* Device Number */ int blank; /* 1=don't blank device */ FILE *fdi, *fdo, *fd;/* file descriptors */ FILE *ifd, *popen(); char *ifn; /* input file name */ char *pname; /* program name */ char fill[256*8]; /* speed buffer for comtal image and grinnel */ char *cp,*po; /* character pointers */ int net = 1; /* 1 send output across network */ char host[10] = "arpa"; /* last resort host */ int ks; int nleft, nread; char *table[] = { "if", 0 }; main(argc,argv) int argc; char **argv; { register i,j; int k; char c; /* parse command line */ pname = *argv; while(argv++ , --argc){ if(argv[0][0] == '-')while(c = *++*argv)switch(c){ case 'b': /* blank */ blank = 1; break; case 'G': /* Grinnell */ Device = GRINNELL;; break; case 'c': case 'C': /* Comtal */ Device = COMTAL; break; case 'i': Mode = IMAGE; break; case 'o': Mode = OVERLAY; break; case '0': /* device 0 */ case '1': case '2': case '3': case '4': Number = c; break; case 'm': /* override machine */ strcpy(host,*argv+1); net = 1; goto noption; default: fprintf(stderr,"bad flag: -%c\n",c); exit(1); } else switch(comm(*argv)){ case 1: ifn = *argv + 3; break; } noption: ; } /* find out where to send output to */ if((ifd = fopen((Device == COMTAL ? "/usr/lib/graphics/gd.site.Ct" : "/usr/lib/graphics/gd.site.Gr"), "r")) != NULL) { fgets(host,10,ifd); fclose(ifd); host[strlen(host)-1] = 0; if(strcmp(host,"local") == 0){ net = 0; }else{ net = 1; } } if(ifn){ if((fd = fopen(ifn,"r")) == NULL) err("can't open: ",ifn); }else{ fd = stdin; } /* send to remote machine if necessary */ if(net){ short s; sprintf(buf,"exec %s %s %s /usr/lib/graphics/gd -%s%s%c%s", Device == GRINNELL ? "/usr/ucb/rsh" : "/usr/ecn/ns", host, Device == GRINNELL ? "" : "-S", Device == GRINNELL ? "G" : "C", Mode == IMAGE ? "i" : "o", Number ? Number : '0', blank ? "b" : ""); if((fdo = popen(buf,"w")) == NULL){ fprintf(stderr,"can't execute pipe to '%s'\n", Device == GRINNELL ? "rsh" : "ns"); exit(1); } gdread(fileno(fd), ibuf, sizeof(short)*L*M); s = 1; if (Mode == OVERLAY && htons(s) != s && strcmp(host, "dipl") == 0) { unsigned short *sp; int i; for (i = L*M, sp = ibuf ; i > 0 ; i--, sp++) *sp = htons(*sp); } write(fileno(fdo), ibuf, sizeof(short)*L*M); if(pclose(fdo)){ fprintf(stderr,"%s:/usr/lib/graphics/ngd died\n",host); exit(1); } exit(0); } /* use local devices */ /* find name of machine */ bzero(host, sizeof(host)); gethostname(host, sizeof(host)-1); sprintf(OutputDevice,"%s%s%c", Device == GRINNELL ? Grinnell : Comtal, Mode == OVERLAY ? Overlay : "", Number ? Number : '0'); if (Mode == OVERLAY){ if(blank)if((fdi = fopen(OutputDevice,"r")) == NULL){ fprintf(stderr,"can't open: %s:%s\n",host,OutputDevice); exit(1); } if((fdo = fopen(OutputDevice,"w")) == NULL){ fprintf(stderr,"can't open: %s:%s\n",host,OutputDevice); exit(1); } gdread(fileno(fd), ibuf, sizeof(short)*M*L); if (blank) { gdread(fileno(fdi), kbuf, sizeof(short)*M*L); for(j = 0, pp = ibuf, qq = kbuf ; j < M * L ; j++) *pp++ |= *qq++; } write(fileno(fdo), ibuf, sizeof(ibuf)); } else { if(Device == COMTAL && !Number){ if((fdi = fopen("/dev/ct/tc","r")) == NULL){ fprintf(stderr,"can't open: %s!/dev/ct/tc\n", host); exit(1); } fread(buf,sizeof(char),512,fdi); fclose(fdi); Number = ((buf[4]>>1)&3)+'0'; sprintf(OutputDevice,"%s%s%c", Device == GRINNELL ? Grinnell : Comtal, Mode == OVERLAY ? Overlay : "", Number ? Number : '0'); } if(blank)if((fdi = fopen(OutputDevice,"r")) == NULL){ fprintf(stderr,"can't open: %s!%s\n",host,OutputDevice); exit(1); } if((fdo = fopen(OutputDevice,"w")) == NULL){ fprintf(stderr,"can't open: %s!%s\n",host,OutputDevice); exit(1); } for(i=0,cp=fill;i<256;i++){ if(i & 0200) *cp++ = 255; else *cp++ = 0; if(i & 0100) *cp++ = 255; else *cp++ = 0; if(i & 0040) *cp++ = 255; else *cp++ = 0; if(i & 0020) *cp++ = 255; else *cp++ = 0; if(i & 0010) *cp++ = 255; else *cp++ = 0; if(i & 0004) *cp++ = 255; else *cp++ = 0; if(i & 0002) *cp++ = 255; else *cp++ = 0; if(i & 0001) *cp++ = 255; else *cp++ = 0; } for(k = 0 ; k < 512 ; k++){ bf = buf; if(fread(ibuf,sizeof(short),32,fd) != 32) err("unexpected EOF",""); for( j = 0,cp = (char *)ibuf ; j < 32 ; j++){ po = fill + ((0377 &(int)*(cp+1)) << 3); *bf++ = *po++; *bf++ = *po++; *bf++ = *po++; *bf++ = *po++; *bf++ = *po++; *bf++ = *po++; *bf++ = *po++; *bf++ = *po++; po = fill + ((0377 &(int)*cp) << 3); *bf++ = *po++; *bf++ = *po++; *bf++ = *po++; *bf++ = *po++; *bf++ = *po++; *bf++ = *po++; *bf++ = *po++; *bf++ = *po++; cp += 2; } if(blank){ fread(bb,sizeof(char),512,fdi); for(j=0,bf=buf,cf=bb;j<512;j++)*bf++ |= *cf++; } fwrite(buf,sizeof(char),512,fdo); } if(blank) fclose(fdi); fclose(fdo); } } comm(s) char *s; { register int i,j,r; for(i=0;table[i];i++){ for(j=0;(r=table[i][j]) == s[j] && r;j++); if(r == 0 && s[j] == '=' && s[j+1] )return(i+1); } fprintf(stderr,"bad option: %s\n",s); exit(1); } err(s1,s2) char *s1,*s2; { fprintf(stderr,"%s: %s%s\n",pname,s1,s2); exit(1); } gdread(fd, buf, nleft) int fd; char *buf; int nleft; { int nread; for ( ; nleft > 0 ; ) { nread = read(fd, buf, nleft); if (nread <= 0) err("unexpected EOF",""); buf += nread; nleft -= nread; } } SHAR_EOF cat << \SHAR_EOF > gp.c /* gp - print bit planes on the Versatec The CRC graphics package Carl Crawford Purdue University West Lafayette, IN 47901 October 1981 */ #include <stdio.h> #define L 32 #define M 512 FILE *ofd,*ifd[20],*popen(); FILE *fd; /* for getting site name */ short buf[L],ibuf[L],obuf[132]; int nf; /* number of inout files */ int form[3] = {3,0,020}; /* stty stuff for some Versatecs */ int silent; /* 1=don't print output message */ char host[10] = "a"; /* last resort site */ int outlen; /* size of versatec line */ int net = 1; /* 1=go across network */ int full; /* 1= 4:1 0= 2:1 */ char gov[] = "/dev/ct/gov0"; char cbuf[100]; /* character buffer for site determination */ int dumb; /* 1=dumb Versatec */ main(argc, argv) int argc; char **argv; { char c; short map(),map2(); int i; register j; register short *p,*q; if(argc == 1)synerr(); /* the file /u/lib/graphics/gp.site contains information about which versatec to use. it two fields: "host # ". the host is the network machine where graphics will be sent to. the # is the length of the line. 100 for normal versatecs and 132 for the old one at APPA. if host is 'local' then the versatec connected directly to the machine will be used. care should be used so that loops do not occur by sending output back and forth between machines. */ if((fd = fopen("/usr/lib/graphics/gp.site","r")) != NULL){ fgets(host,10,fd); for(i=0;i<10;i++){ if(host[i] == ' ' || host[i] == '\n'){ host[i] = 0; break; } } outlen = atoi(host + i + 1); if(outlen == 132 ) dumb = 1; fclose(fd); if(strcmp(host,"local") == 0){ net = 0; }else{ net = 1; } } while(argv++ , --argc){ if(**argv == '-')while(c = *++*argv)switch(c){ case 'h': /* 2:1 scaling */ full = 0; break; case 'f': /* 4:1 scaling */ full = 1; break; case 'i': /* standard input */ ifd[nf++] = stdin; break; case 's': /* silent mode */ silent = 1; break; case 'm': /* set up machine */ strcpy(host,*argv+1); net = 1; goto nloop; default: fprintf(stderr,"bad flag: -%c\n",c); exit(1); }else{ if(dumb){ if(**argv >= '0' && **argv <= '2' && !*(*argv + 1)){ gov[11] = **argv; ifd[nf++] = fopen(gov,"r"); *argv = gov; }else{ ifd[nf++] = fopen(*argv,"r"); } }else{ ifd[nf++] = fopen(*argv,"r"); } if(ifd[nf-1] == NULL){ fprintf(stderr,"can't open: %s\n",*argv); exit(1); } } nloop: ; } if(!nf)synerr(); if(!dumb)full = 0; if(net){ sprintf(cbuf,"exec ns %s -S gp -i",host); if(silent)strcat(cbuf," -s"); if(full)strcat(cbuf,"-f"); silent = 1; if((ofd = popen(cbuf,"w")) == NULL){ fprintf(stderr,"can't execute pipe to '%s'\n",host); exit(1); } }else{ if((fd=fopen("/etc/cpu","r")) != NULL){ fgets(host,10,fd); host[strlen(host)-1] = 0; fclose(fd); } if( (ofd = fopen("/dev/vc","w")) == NULL){ fprintf(stderr,"Versatec in use on '%s'\n",host); exit(1); } } if(!net && !dumb)stty(fileno(ofd),form); for(i=0;i<M;i++){ input(); if(net){ fwrite(ibuf,sizeof(short),L,ofd); }else{ p = ibuf; q = obuf + 20; if(full)q -= 18; for(j=0;j<L;j++){ if(full){ *q++ = map(12, *p); *q++ = map(8, *p); *q++ = map(4, *p); *q++ = map(0, *p++); }else{ *q = map2(8, *p) << 8; *q++ |= map2(12, *p); *q = map2(0, *p) << 8; *q++ |= map2(4, *p++); } } for(j=0;j<(2<<full);j++){ fwrite(obuf,sizeof(short),outlen,ofd); } } } if(!net){ if(!dumb){ stty(fileno(ofd),form); }else{ for(i=0;i<outlen;obuf[i++] = 0); for(i=0;i<1500;i++)fwrite(obuf,sizeof(short),outlen,ofd); } }else{ pclose(ofd); } if(!silent)fprintf(stderr,"output at '%s'\n",host); } #define K0 0000000 #define K4 0000017 #define K8 0000360 #define K1 0007400 #define K2 0170000 short tab[] = { (K0), (K1), (K2), (K1|K2), (K4), (K4|K1), (K4|K2), (K4|K2|K1), (K8|K0), (K8|K1), (K8|K2), (K8|K1|K2), (K8|K4), (K8|K4|K1), (K8|K4|K2), (K8|K4|K2|K1) }; short map(n,d) int n; short d; { return( tab[ (d>>n)&017 ] ); } #undef K0 #undef K1 #undef K2 #undef K4 #undef K8 #define K0 0000000 #define K1 0000003 #define K2 0000014 #define K4 0000060 #define K8 0000300 short tab2[] = { (K0), (K1), (K2), (K1|K2), (K4), (K4|K1), (K4|K2), (K4|K2|K1), (K8|K0), (K8|K1), (K8|K2), (K8|K1|K2), (K8|K4), (K8|K4|K1), (K8|K4|K2), (K8|K4|K2|K1) }; short map2(n,d) int n; short d; { return( tab2[ (d>>n)&017 ] ); } input() { register int i, j; fread(ibuf,sizeof(short),L,ifd[0]); i = 1; while(i < nf){ fread(buf,sizeof(short),L,ifd[i++]); for(j=0; j<L; j++) ibuf[j] |= buf[j]; } } synerr() { fprintf(stderr,"syntax: gp [-ifhsm] file1 file2 ... filen\n"); exit(1); } SHAR_EOF cat << \SHAR_EOF > gplp.c #include <stdio.h> /* gplp - print bit planes on a Printronix line-printer syntax: gplp [-XX] [-i] file1 file2 ... filen The CRC graphics package carl crawford purdue university w. lafayette, in 47907 july 1979 ***************************************************************** Modified by Tony Andrews : July, 1982 Added "-s" option to compensate for different vertical and horizontal pixed densities on the printronix. Define "NSQ" to delete the changes making the code identical to the original. The compensation is a simple compression so characters will be distorted somewhat. To avoid a major overhaul of the argument processing, the "-s" must come after the "-i" (if present) and before any file names. */ #define L 32 #define M 512 FILE *ofd; /* output file descriptor */ FILE *fd; /* input file descriptor */ char PLOT = 005; char ENDLINE = 012; int nfile; char swtab[64]; char site[10] = "-ep"; /* last resort line-printer */ #ifndef NSQ int sflag = 0; short mask[16]; #define MASK(x) (((short)0x0001) << (15-x)) #endif main(argc,argv) int argc; char **argv; { FILE *ifd[20]; short ibuf[33],buf[33]; char obuf[100],*ob; register int i,j,k; char swap(); FILE *popen(); ibuf[32] = 0; /* clear last byte in vector */ #ifndef NSQ for(i=0;i<16;i++) /* used to speed up masking later */ mask[i] = MASK(i); #endif if((fd = fopen("/usr/lib/graphics/gplp.site","r")) != NULL){ fgets(site,10,fd); fclose(fd); site[strlen(site) - 1] = 0; } if(argv[1][0] == '-' && argv[1][1] && argv[1][2] && !argv[1][3]){ if(argv[1][1] != 'p' || argv[1][2] != 'l'){ site[1] = argv[1][1]; site[2] = argv[1][2]; site[3] = 0; } argc--; argv++; } if(argv[1][0] == '-' && argv[1][1] && argv[1][2] && argv[1][3] && !argv[1][4]){ if(argv[1][1] != 'p' || argv[1][2] != 'l'){ site[1] = argv[1][1]; site[2] = argv[1][2]; site[3] = argv[1][3]; site[4] = 0; } argc--; argv++; } if(argv[1][0] == '-' && argv[1][1] == 'i' && argv[1][2] == '\0'){ ifd[nfile++] = stdin; argv++; argc--; } #ifndef NSQ if(argv[1][0] == '-' && argv[1][1] == 's' && argv[1][2] == '\0'){ sflag++; argv++; argc--; } #endif if(argc == 1 && !nfile)synerr(); while(--argc){ if((ifd[nfile++] = fopen(argv[1],"r")) == NULL){ fprintf(stderr,"gplp: can't open: %s\n",argv[1]); exit(1); } ++argv; } if (site[0] == '-') strcpy(&site[0],&site[1]); sprintf(obuf,"exec lpr -l -P%s", site); if((ofd = popen(obuf,"w")) == NULL){ fprintf(stderr,"gplp: can't pipe to lpr\n"); exit(1); } for(i=0;i<64;i++)swtab[i] = swap((char) i); for(j=0;j<M;j++){ if(fread(ibuf,sizeof(short),L,ifd[0]) != L){ fprintf(stderr,"gplp: unexpected EOF\n"); exit(1); } i = 0; while(++i < nfile){ if(fread(buf,sizeof(short),L,ifd[i]) != L){ fprintf(stderr,"gplp: unexpected EOF\n"); exit(1); } for(k=0;k<L;k++)ibuf[k] |= buf[k]; } #ifndef NSQ if(sflag) adjust(ibuf); #endif ob = obuf; *ob++ = PLOT; for(i=0;i<L;i += 3){ *ob++ = swtab[(ibuf[i] >> 10) & 077]; *ob++ = swtab[(ibuf[i] >>4) & 077]; *ob++ = swtab[((ibuf[i+1] >> 14) & 03) | ((ibuf[i] << 2) & 074)]; *ob++ = swtab[(ibuf[i+1] >> 8) & 077]; *ob++ = swtab[(ibuf[i+1] >> 2) & 077]; *ob++ = swtab[((ibuf[i+2] >> 12) & 017) | ((ibuf[i+1] << 4) & 060)]; *ob++ = swtab[(ibuf[i+2] >> 6) & 077]; *ob++ = swtab[ibuf[i+2] & 077]; } while(*(--ob) == 0100); *(++ob) = ENDLINE; fwrite(obuf,1,ob - obuf + 1,ofd); } fputc('\f',ofd); /* eject page */ pclose(ofd); wait(0); } char swap(cc) char cc; { register int i; register char tmp; tmp = 0; for(i=0;i<6;i++){ cc <<= 1; tmp |= (cc & 0100); tmp >>= 1; } return(tmp | 0100); } synerr() { fprintf(stderr,"syntax: gplp [-XX] [-i] file1 file2 ... filen\n"); exit(1); } #ifndef NSQ adjust(buf) short *buf; { register int i; short tbuf[33]; for(i=0; i<L ;i++) /* clear output buffer */ tbuf[i] = 0; for(i=0; i<M ;i++) if(biton(buf,i)) setbit(tbuf,(int) ( (60.0/72.0) * (float) i)); for(i=0; i<L ;i++) /* move adjusted buffer back */ buf[i] = tbuf[i]; /* into the original */ } biton(b,n) short *b; int n; { register int index,offset; index = n >> 4; offset= n & 0x000f; return(b[index] & mask[offset]); } setbit(b,n) short *b; int n; { register int index,offset; index = n >> 4; offset= n & 0x000f; b[index] |= mask[offset]; } #endif SHAR_EOF cat << \SHAR_EOF > hpd.c #define OLDHP /* hpd - HP daemon program The CRC graphics package Carl Crawford Purdue University W. Lafayette, IN 47907 March 1980 */ #include <stdio.h> #include <signal.h> #ifdef vax #include <sys/file.h> #endif vax #define ETX 3 /* <etx> */ #define ESC 27 /* <esc> */ #ifndef OLDHP #include <sgtty.h> struct sgttyb Tty,tty; char pbuf[BUFSIZ]; #endif int flag,tickle; char ansbuff[32]; /* return from HP */ int fd,fdi; /* HP file descriptors */ char buf[512]; /* input buffer */ char name[100]; /* path to device */ int c; /* input character */ FILE *ifd; /* input to program */ int net = 1; /* 1=send output across network */ char host[10] = "a"; /* last resort plotter site */ main(argc,argv) int argc; char **argv; { register i,j; char *p; int clean(),timeout(); #ifdef OLDHP /* find out default host for plotter */ if((ifd = fopen("/usr/lib/graphics/hpd.site","r")) != NULL){ fgets(host,10,ifd); fclose(ifd); host[strlen(host)-1] = 0; if(strcmp(host,"local") == 0){ net = 0; }else{ net = 1; } } /* see if -mHOST is on the command line */ if(argc >= 2){ if(argv[1][0] == '-' && argv[1][1] == 'm' && argv[1][2]){ strcpy(host,argv[1]+2); net = 1; argc--; argv++; } } /* see if path to plotter is specified */ if(argc == 2){ strcpy(name,argv[1]); }else{ strcpy(name,"/dev/plt0"); } /* pipe to another machine if necessary */ if(net){ execl("/bin/ns","ns",host,"-S","/usr/lib/graphics/hpd",name,0); execl("/usr/bin/ns","ns",host,"-S","/usr/lib/graphics/hpd",name,0); execl("/usr/ecn/ns","ns",host,"-S","/usr/lib/graphics/hpd",name,0); fprintf(stderr,"hpd: can't exec ns\n"); exit(1); } /* drive plotter local to this machine */ /* find out name of machine */ if((ifd=fopen("/etc/cpu","r")) != NULL){ fgets(host,10,ifd); host[strlen(host)-1] = 0; fclose(ifd); } /* open plotter for input and output */ fdi = open(name,0); if(fdi == -1)noplot(); fd = open(name,1); if(fd == -1)noplot(); #ifdef vax flock(fdi,LOCK_EX); #endif vax #endif OLDHP #ifndef OLDHP setbuf(stdout,pbuf); fdi = fd = 1; gtty(fd,&Tty); tty = Tty; tty.sg_flags &= ~ECHO; stty(fd,&tty); #endif /* catch interrupts and reset plotter */ if (signal(SIGHUP,SIG_IGN) != SIG_IGN) signal(SIGHUP,clean); if (signal(SIGINT,SIG_IGN) != SIG_IGN) signal(SIGINT,clean); if (signal(SIGQUIT,SIG_IGN) != SIG_IGN) signal(SIGQUIT,clean); i = 0; while(1){ if((c = getchar()) != EOF)buf[i++] = c; if(i == 512 || c == EOF || c == '}'){ if (write(fd,buf,i) < 0) { perror("hpd: write failed"); exit(69); } flag = 1; alarm(180); /* have driver time out */ signal(SIGALRM,timeout); /* wait for buffer to empty out */ while(flag){ tickle = '\05'; if (write(fd,&tickle,1) < 0) { perror("hpd: write failed"); exit(69); } if ((i = read(fdi,ansbuff,30)) < 0) { perror("hpd: read failed"); exit(69); } p = ansbuff; for(j = 0;j < i;j++)if(*p++ == 'G')flag = 0; #ifdef OLDHP if(c == EOF && !flag)exit(1); #else if(c == EOF && !flag)clean(); #endif } alarm(0); i = 0; } } } noplot() { fprintf(stderr,"Can't open HP plotter on %s!%s\n",host,name); exit(1); } clean() { int i = 0; /* reset plotter and put the pen back */ #ifdef OLDHP buf[i++] = ESC; buf[i++] = '.'; buf[i++] = 'K'; #endif buf[i++] = ETX; buf[i++] = '}'; buf[i++] = 'v'; buf[i++] = 0100; #ifndef OLDHP buf[i++] = ESC; buf[i++] = '.'; buf[i++] = ')'; #endif write(fd,buf,i); #ifndef OLDHP stty(fd,&Tty); #endif exit(1); } timeout() { fprintf(stderr,"Time out HP running on %s!%s\n",host,name); clean(); } SHAR_EOF cat << \SHAR_EOF > font-mods The following changes, WHICH I HAVE NOT TESTED, are designed to all the font that qplot/plot3d uses to be kept in memory, rather than on disk. The original package kept the font on disk, because it was designed to run on a PDP-11...but most machines around today shouldn't have a problem keeping the font in memory, and should enjoy a performance increase as a result. I will be installing and testing these changes shortly (I hope) so I'll be able to judge for myself. :-) These changes were done by Malcolm Slaney, who comments: OK....I think only two files have changed. They are charfont/genfont.c and lib/symbol.c. They are appended to this letter. When these changes are installed you can get rid of the font.5x7 that must be kept in a well known place. Oh, yes, there is a change to the charfont/Makefile. ---------------------------- charfont/genfont.c --------------------- /* genfont - generate character font files The CRC graphics package Carl Crawford Purdue University W. Lafayette, IN 47907 October 1981 */ /* The file generated by 'genfont' used to have the following format: short height Default character height. short size Bytes of core required to hold coordinates. short pnt[256] Indexes to 1st coordinate of each symbol. short crd[size] Coordinates of symbols Where each crd[i] has the following format: EVSXXXXXXSYYYYYY (a 'short' is assumed to be 16 bits) III IIIIIIII III I I----- Y coordinate (sign magnitude format) IIIIIIIII II I----- X coordinate (sign magnitude format) II----- Line segment visible flag (0=invisible, 1=visible) I----- 1=more coordinates; 0=last coordinate The new output of this program is a file that can be included directly into a C program. Back in the days of PDP 11's it was important to keep the program small. Now it is better to reduce the amount of IO needed and to make maintance easier by removing the character description file.........................................Malcolm.... May 1987. The file used as input to 'genfont' as the following format: \n/x0,y0,v0/x1,y1,v2/.../xm,ym,vm<cr> . . . where: 'n' is the character in octal. xi, i=1,2,..m is the x coordinate of the i'th segment yi, i=1,2,..m is the x coordinate of the i'th segment vi, i=1,2,..m is the visible indicator of the i'th segment v = 0 => invisible = 1 => visible */ #include <stdio.h> FILE *ifd; /* input file descriptor */ char InputBuffer[512]; /* input character buffer */ short OutputBuffer[512]; /* output buffer for packed coords. */ int OutputBufferPointer; /* Current position in output buffer */ int FilePosition; /* position within file */ int XPosition; /* x position */ int YPosition; /* y position */ int VisibFlag; /* visib flag */ short PackedChar; /* formed coordinate */ int CharIndex; /* character number */ struct{ /* header structure */ short height; short coordsz; short pntrlst[256]; }fontcom; main(argc, argv) int argc; char **argv; { int i; if(argc != 2) synerr(); if((ifd = fopen(argv[1],"r"))==NULL) err("can't open: ",argv[1]); for (i=0; i<256; i++) fontcom.pntrlst[i] = -1; /* get height of font */ if(gread()) err("can't read height",""); fontcom.height = atoi(InputBuffer); printf("short pntcoord[] = {\n"); /* loop through all the entries */ OutputBufferPointer = 0; while(!gread()){ if (*InputBuffer == '\\') { WriteCharacter(CharIndex); CharIndex = atoi(InputBuffer+1); CharIndex = (CharIndex/100*64) + (((CharIndex/10)%10)*8) + CharIndex%10; if (CharIndex<0 || CharIndex>255) err("invalid character number ",InputBuffer+1); fontcom.pntrlst[CharIndex] = FilePosition; }else{ XPosition = atoi(InputBuffer); if(gread())err("incomplete coordinate specified",""); YPosition = atoi(InputBuffer); if(gread())err("incomplete coordinate specified",""); VisibFlag = atoi(InputBuffer)&&01; PackedChar = (VisibFlag<<14) | ((abs(XPosition)%128)<<7) | (abs(YPosition)%128); if(XPosition < 0) PackedChar |= 0020000; if(YPosition < 0) PackedChar |= 0100; OutputBuffer[OutputBufferPointer++] = PackedChar; FilePosition++; } } /* clean up last character */ WriteCharacter(CharIndex); /* write header */ printf("};\n"); printf("struct {\n"); printf(" short height;\n"); printf(" short pntrlst[257];\n"); printf("} fontcom = { %d,", fontcom.height); for (i=0;i<256;i++){ if (i%8 == 0) printf("\n "); printf("%d, ",fontcom.pntrlst[i]); } printf("0};\n"); exit(0); } WriteCharacter(Index) int Index; { int i; if (OutputBufferPointer){ printf("/* %c(0%03o) */\n",CharIndex, CharIndex); OutputBuffer[OutputBufferPointer-1] |= 0100000; for (i=0;i<OutputBufferPointer;i++) printf("%d,",OutputBuffer[i]); printf("\n"); OutputBufferPointer = 0; } } gread() { char *c; c = InputBuffer; while((*c = fgetc(ifd)) != EOF){ if(*c == ',' || *c == '/' || *c == '\n')return(0); c++; } return(1); } err(s1,s2) char *s1,*s2; { fputs(s1,stderr); fputs(s2,stderr); fputc('\n',stderr); exit(1); } synerr(){ err("syntax: genfont <output file> <input file>",""); } --------------------------- lib/symbol.c --------------------- /* symbol - plot strings The CRC graphics package Carl Crawford Purdue University W. Lafayette, IN 47907 */ #include "crc.h" symbol(x,y,height,str,angle) float x,y,angle; float height; char *str; { int f,vis; int charfont(); float xx,yy,t1,t2,ca,sa,d2r; static float oangle,oheight; static int first = 1; /* ==1 if first call */ int dollar; char cc; if(DEV == TEK && DEVN == 2 && index(str,'$') == 0) { register int i; plot(x,y,3); if(oangle != angle || first) { plotp(ESC); /* Graphic text rotation */ plotp('M'); plotp('R'); tint((int) angle); tint(0); oangle = angle; } if(oheight != height || first) { plotp(ESC); /* Graphic test size */ plotp('M'); plotp('C'); tint((int)(190*height)); tint((int)(265*height)); tint((int)( 75*height)); oheight = height; } first = 0; plotp(ESC); /* Output graphic string */ plotp('L'); plotp('T'); tint(strlen(str)); for(i=0; str[i]; i++) plotp(str[i]); return; } d2r = 4.0 * atan(1.0) / 180.0; dollar = 0; angle *= d2r; sa = sin(angle); ca = cos(angle); plot(x,y,3); while(cc = *str){ if(cc == '$' && dollar == 0){ dollar = 1; str++; } else{ if(dollar == 1){ dollar = 0; cc += 0200; } /* /* kludge bad font defintition for '.' */ /* if(cc == '.' && DEV <= MBIT) /* cc = ','; */ do{ f = charfont(cc,height,&xx,&yy,&vis); t1 = ca * xx - sa * yy; t2 = sa * xx + ca *yy; plot(t1+x,t2+y,3-vis); } while(f); x += t1; y += t2; str++; } } } /* Charfont is a program that looks up the end points of line segments for plotting characters. Each time 'charfont' is called, it returns the relative coordinates, which when added to the current location yields the final end point for a line seg- ment. The initial point of the line segment is the current loca- tion. Whether the line segment is to be visible or not is indi- cated by the returned value in "visflg". */ #include "font.5x7.h" charfont(symbol,height,x,y,visflg) char symbol; float height, *x, *y; int *visflg; { int i; static short *pntr; static float scale; register int temp; /* find coordinate of first point */ if (pntr == 0) { if ( (i=fontcom.pntrlst[symbol&0377]) == -1) { /* assume space if can't find it */ if ( (i=fontcom.pntrlst[' ']) == -1) { /* set if no space */ *x = 0.0; *y = 0.0; *visflg = 0; return(0); } } pntr = pntcoord+i; scale = height/fontcom.height; } temp = *pntr++; /* get X coordiante */ *x = ((temp>>7)&077)*scale; if (temp&0020000)*x = (-(*x)); /* get Y coordinate */ *y = (temp&077)*scale; if (temp&0100)*y = (-(*y)); /* get visib flag */ *visflg = (temp&040000)>>14; /* check for last coordinate */ if (temp < 0) { pntr = 0; return(0); } return(1); } /* The font file used by 'fontinit' to read in the data for 'charfont' has the following format: short height Default character height. short pnt[256] Indexes to 1st coordinate of each symbol. short crd[size] Coordinates of symbols Where each crd[i] has the following format: EVSXXXXXXSYYYYYY III IIIIIIII III I I----- Y coordinate (sign magnitude format) IIIIIIIII II I----- X coordinate (sign magnitude format) II----- Line segment visible flag (0=invisible, 1=visible) I----- 1=more coordinates; 0=last coordinate */ tint(i) int i; { int negative,lo,hi1,hi2; negative = 1; if(i < 0){ i = -i; negative = 0; } lo = (i % 16) + 32; if(negative)lo += 16; i /= 16; hi1 = (i % 64) + 64; i /= 64; hi2 = (i % 64) + 64; if(hi2 == 64){ if(hi1 == 64){ plotp(lo); return; } plotp(hi1); plotp(lo); return; } plotp(hi2); plotp(hi1); plotp(lo); } --------------------------- charfont/Makefile -------------------- CFLAGS=-O GLIBDIR=/usp0/malcolm/crc/lib/graphics all: genfont font.5x7 font.5x7: ifont.5x7 genfont genfont ifont.5x7 > font.5x7 genfont: genfont.c cc $(CFLAGS) genfont.c -o genfont install: font.5x7 cp font.5x7 ../lib/font.5x7.h clean: rm -f font.5x7 genfont SHAR_EOF # End of shell archive exit$