📄 vplotf.c
字号:
/* * Copyright (c) 1983 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */#ifndef lintstatic char sccsid[] = "@(#)vplotf.c 1.1 92/07/30 SMI"; /* from UCB 5.2 11/11/85 */#endif not lint/* * Lpd filter to read standard graphics input and produce a plot on the * Varian or Versatec */#include <stdio.h>#include <vfont.h>#include <sys/vcmd.h>#define mapx(x) ((DevRange*((x)-botx)/del)+centx)#define mapy(y) ((DevRange*(del-(y)+boty)/del)-centy)#define SOLID -1#define DOTTED 014#define SHORTDASHED 034#define DOTDASHED 054#define LONGDASHED 074static char *Sid = "@(#)\t5/16/83";int linmod = SOLID;int done1;char chrtab[][16];char *obuf;int bufsize;int lastx;int lasty;int radius, startx, starty, endx, endy;double topx;double topy;double botx;double boty;int centx = 0;int centy = 0;double delx;double dely;double del;int warned = 0; /* Indicates whether the warning message about * unimplemented routines has been printed */int plotmd[] = {VPLOT};int prtmd[] = {VPRINT};int varian; /* 0 for versatec, 1 for varian. */int BYTES_PER_LINE; /* number of bytes per raster line. */int PAGE_LINES; /* number of raster lines per page. */int DevRange = 1536; /* output array size (square) in pixels */int DevRange8 = 1536/8; /* output array size in bytes */int lines; /* number of raster lines printed */char zeros[880]; /* one raster line */char *name, *host, *acctfile;/* variables used to print from font file */int fontSet = 0; /* Has the font file been read */struct header header;struct dispatch dispatch[256];char *bits;char *fontFile = "/usr/lib/vfont/R.8";main(argc, argv) int argc; char *argv[];{ register char *cp, *arg; register n, again; while (--argc) { if (**++argv == '-') { switch (argv[0][1]) { case 'x': BYTES_PER_LINE = atoi(&argv[0][2]) / 8; if (varian = BYTES_PER_LINE == 264) { DevRange = 1536; DevRange8 = 1536/8; } else { DevRange = 2048; DevRange8 = 2048/8; } break; case 'y': PAGE_LINES = atoi(&argv[0][2]); break; case 'n': argc--; name = *++argv; break; case 'h': argc--; host = *++argv; } } else acctfile = *argv; } /* init constants for scaling */ topx = topy = DevRange; botx = boty = 0; delx = dely = del = DevRange; centx = (DevRange - mapx(topx))/2; centy = mapy(topy)/2; if ((obuf = (char *) malloc(bufsize = DevRange * DevRange8)) == NULL) { fprintf(stderr, "vplotf: ran out of memory\n"); exit(2); } do { arg = &obuf[bufsize]; for (cp = obuf; cp < arg; ) *cp++ = 0; again = getpict(); ioctl(1, VSETSTATE, plotmd); n = BYTES_PER_LINE - DevRange8; for (cp = obuf; cp < arg; cp += DevRange8) { if (write(1, cp, DevRange8) != DevRange8) exit(1); if (n && write(1, zeros, n) != n) exit(1); lines++; } ioctl(1, VSETSTATE, prtmd); if (varian) write(1, "\f", 2); else write(1, "\n\n\n\n\n", 6); } while (again); account(name, host, *argv); exit(0); /* NOTREACHED */}account(who, from, acctfile) char *who, *from, *acctfile;{ register FILE *a; if (who == NULL || acctfile == NULL) return; if (access(acctfile, 02) || (a = fopen(acctfile, "a")) == NULL) return; /* * Varian accounting is done by 8.5 inch pages; * Versatec accounting is by the (12 inch) foot. */ fprintf(a, "t%6.2f\t", (double)lines / (double)PAGE_LINES); if (from != NULL) fprintf(a, "%s:", from); fprintf(a, "%s\n", who); fclose(a);}getpict(){ register x1, y1; for (;;) switch (x1 = getc(stdin)) { case '\n': continue; case 's': botx = getinteger(stdin); boty = getinteger(stdin); topx = getinteger(stdin); topy = getinteger(stdin); delx = topx-botx; dely = topy-boty; if (dely/delx > 1536./2048.) del = dely; else del = delx; centx = 0; centx = (DevRange - mapx(topx))/2; centy = 0; centy = mapy(topy) / 2; continue; case 'b': x1 = getc(stdin); continue; case 'l': done1 |= 01; x1 = mapx(getinteger(stdin)); y1 = mapy(getinteger(stdin)); lastx = mapx(getinteger(stdin)); lasty = mapy(getinteger(stdin)); line(x1, y1, lastx, lasty); continue; case 'c': x1 = mapx(getinteger(stdin)); y1 = mapy(getinteger(stdin)); radius = mapx(getinteger(stdin)); circle(x1, y1, radius); continue; case 'a': x1 = mapx(getinteger(stdin)); y1 = mapy(getinteger(stdin)); startx = mapx(getinteger(stdin)); starty = mapy(getinteger(stdin)); endx = mapx(getinteger(stdin)); endy = mapy(getinteger(stdin)); if (!warned) { fprintf(stderr,"Arcs are unimplemented\n"); warned++; } continue; case 'm': lastx = mapx(getinteger(stdin)); lasty = mapy(getinteger(stdin)); continue; case 't': lastx = lastx - 6; lasty = lasty + 6; done1 |= 01; while ((x1 = getc(stdin)) != '\n') plotch(x1); continue; case 'e': if (done1) return(1); continue; case 'p': done1 |= 01; lastx = mapx(getinteger(stdin)); lasty = mapy(getinteger(stdin)); point(lastx, lasty); point(lastx+1, lasty); point(lastx, lasty+1); point(lastx+1, lasty+1); continue; case 'n': done1 |= 01; x1 = mapx(getinteger(stdin)); y1 = mapy(getinteger(stdin)); line(lastx, lasty, x1, y1); lastx = x1; lasty = y1; continue; case 'f': getinteger(stdin); getc(stdin); switch (getc(stdin)) { case 't': linmod = DOTTED; break; default: case 'i': linmod = SOLID; break; case 'g': linmod = LONGDASHED; break; case 'r': linmod = SHORTDASHED; break; case 'd': linmod = DOTDASHED; break; } while ((x1 = getc(stdin)) != '\n') if (x1 == EOF) return(0); continue; case 'd': getinteger(stdin); getinteger(stdin); getinteger(stdin); x1 = getinteger(stdin); while (--x1 >= 0) getinteger(stdin); continue; case 0: /* ignore null characters */ continue; case 255: case EOF: return(0); default: fprintf(stderr, "Input format error %c(%o)\n",x1,x1); exit(2); }}plotch(ch)char ch;{ register int i,j,k; register char *ptr,c; int nbytes; if (!fontSet) InitFont(); /* Read font if not already read */ ptr = bits + dispatch[ch].addr; for (i = dispatch[ch].up; i > -dispatch[ch].down; --i) { nbytes = (dispatch[ch].right + dispatch[ch].left + 7)/8; for (j = 0; j < nbytes; j++) { c = *ptr++; for (k = 7; k >= 0; k--) if ((c >> k) & 1) point(lastx+7-k+j*8-dispatch[ch].left, lasty-i); } } if (ch != ' ') lastx += dispatch[ch].width; else lastx += dispatch['a'].width;}InitFont(){ char *s; int fonts; int i; fontSet = 1; /* Get the font file */ s = fontFile; if ((fonts = open(s, 0)) == -1) { perror(s); fprintf(stderr, "Can't get font file"); exit(2); } /* Get the header and check magic number */ if (read(fonts, &header, sizeof(header)) != sizeof(header)) { perror(s); fprintf(stderr, "Bad read in font file"); exit(2); } if (header.magic != 0436) { fprintf(stderr,"Bad magic numer in font file"); exit(2); } /* Get dispatches */ if (read(fonts, dispatch, sizeof(dispatch)) != sizeof(dispatch)) { perror(s); fprintf(stderr, "Bad read in font file"); exit(2); } /* Allocate space for bit map and read in bits */ bits = (char *) malloc(header.size); if (read(fonts, bits, header.size) != header.size) { perror(s); fprintf(stderr,"Can't read bit map in font file"); exit(2); } /* Close font file */ if (close(fonts) != 0) { perror(s); fprintf(stderr,"Can't close font file"); exit(2); }}line(x0, y0, x1, y1)register x0, y0;{ int dx, dy; int xinc, yinc; register res1; int res2; int slope; xinc = 1; yinc = 1; if ((dx = x1-x0) < 0) { xinc = -1; dx = -dx; } if ((dy = y1-y0) < 0) { yinc = -1; dy = -dy; } slope = xinc*yinc; res1 = 0; res2 = 0; if (dx >= dy) while (x0 != x1) { if ((x0+slope*y0) & linmod) point(x0, y0); if (res1 > res2) { res2 += dx - res1; res1 = 0; y0 += yinc; } res1 += dy; x0 += xinc; } else while (y0 != y1) { if ((x0+slope*y0) & linmod) point(x0, y0); if (res1 > res2) { res2 += dy - res1; res1 = 0; x0 += xinc; } res1 += dx; y0 += yinc; } if ((x1+slope*y1) & linmod) point(x1, y1);}#define labs(a) ((a) >= 0 ? (a) : -(a))circle(x,y,c){ register dx, dy; long ep; int de; dx = 0; ep = 0; for (dy=c; dy>=dx; dy--) { for (;;) { point(x+dx, y+dy); point(x-dx, y+dy); point(x+dx, y-dy); point(x-dx, y-dy); point(x+dy, y+dx); point(x-dy, y+dx); point(x+dy, y-dx); point(x-dy, y-dx); ep += 2*dx + 1; de = -2*dy + 1; dx++; if (labs(ep) >= labs(ep+de)) { ep += de; break; } } }}/* * Points should be in the range 0 <= x (or y) <= DevRange. * The origin is the top left-hand corner with increasing x towards the * right and increasing y going down. */point(x, y)register unsigned x, y;{ register unsigned byte; if (x < DevRange && y < DevRange) { byte = y * DevRange8 + (x >> 3); obuf[byte] |= 1 << (7 - (x & 07)); }}getinteger(f)FILE *f;{ register int low, high, result; low = getc(f); high = getc(f); result = ((high << 8) | low); if (high > 127) result |= ~0xffff; return(result);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -