1*69c7ec87Sslatteng /* dvar.c 1.12 84/05/24 2f92359bfSslatteng * 3f92359bfSslatteng * Varian driver for the new troff 4f92359bfSslatteng * 5f92359bfSslatteng * Authors: BWK(BELL) 6f92359bfSslatteng * VCAT(berkley) 7f92359bfSslatteng * Richard L. Hyde, Perdue University 84da297a9Sslatteng * and David Slattengren, U.C. Berkeley 9f92359bfSslatteng */ 10f92359bfSslatteng 11f92359bfSslatteng 12f92359bfSslatteng /******************************************************************************* 13f92359bfSslatteng 14f92359bfSslatteng output language from troff: 15f92359bfSslatteng all numbers are character strings 16f92359bfSslatteng 17f92359bfSslatteng #..\n comment 18f92359bfSslatteng sn size in points 19f92359bfSslatteng fn font as number from 1 to n 20*69c7ec87Sslatteng in stipple `font' as number from 1 to n 21f92359bfSslatteng cx ascii character x 22f92359bfSslatteng Cxyz funny char \(xyz. terminated by white space 23f92359bfSslatteng Hn go to absolute horizontal position n 24f92359bfSslatteng Vn go to absolute vertical position n (down is positive) 25f92359bfSslatteng hn go n units horizontally (relative) 26f92359bfSslatteng vn ditto vertically 27f92359bfSslatteng nnc move right nn, then print c (exactly 2 digits!) 28f92359bfSslatteng (this wart is an optimization that shrinks output file size 29f92359bfSslatteng about 35% and run-time about 15% while preserving ascii-ness) 30f92359bfSslatteng p new page begins -- set v to 0 31f92359bfSslatteng nb a end of line (information only -- no action needed) 32f92359bfSslatteng b = space before line, a = after 33f92359bfSslatteng w paddable word space -- no action needed 34f92359bfSslatteng 35f92359bfSslatteng Dt ..\n draw operation 't': 36*69c7ec87Sslatteng Dt d set line thickness to d 37*69c7ec87Sslatteng Ds d set line style (mask) to d 38f92359bfSslatteng Dl x y line from here by x,y 39f92359bfSslatteng Dc d circle of diameter d with left side here 40f92359bfSslatteng De x y ellipse of axes x,y with left side here 41f92359bfSslatteng Da x y r arc counter-clockwise by x,y of radius r 42f92359bfSslatteng D~ x y x y ... B-spline curve by x,y then x,y ... 43*69c7ec87Sslatteng Dg x y x y ... gremlin spline curve by x,y then x,y ... 44*69c7ec87Sslatteng Dp s x y ... polygon by x,y then ... filled with stipple s 45f92359bfSslatteng 46f92359bfSslatteng x ..\n device control functions: 47f92359bfSslatteng x i init 48f92359bfSslatteng x T s name of device is s 49f92359bfSslatteng x r n h v resolution is n/inch h = min horizontal motion, v = min vert 50f92359bfSslatteng x p pause (can restart) 51f92359bfSslatteng x s stop -- done for ever 52f92359bfSslatteng x t generate trailer 53f92359bfSslatteng x f n s font position n contains font s 54f92359bfSslatteng x H n set character height to n 55f92359bfSslatteng x S n set slant to N 56f92359bfSslatteng 57f92359bfSslatteng Subcommands like "i" are often spelled out like "init". 58f92359bfSslatteng 59f92359bfSslatteng *******************************************************************************/ 60f92359bfSslatteng 61f92359bfSslatteng 62f92359bfSslatteng #include <stdio.h> 63f92359bfSslatteng #include <ctype.h> 64f92359bfSslatteng #include <sys/vcmd.h> 65f92359bfSslatteng #include "dev.h" 66f92359bfSslatteng 67f92359bfSslatteng 681c9df754Sslatteng /* #define DEBUGABLE /* No, not debugable... */ 691c9df754Sslatteng #define DRIVER /* Yes, we're driving directly */ 701c9df754Sslatteng /* #define FULLPAGE /* No, don't output full pages */ 71*69c7ec87Sslatteng #define NFONTS 65 /* total number of fonts useable */ 72f92359bfSslatteng #define MAXSTATE 6 /* number of environments rememberable */ 73f92359bfSslatteng #define OPENREAD 0 /* mode for openning files */ 74f92359bfSslatteng #define RESTART 1 /* upon exit, return either RESTART */ 75f92359bfSslatteng #define ABORT 2 /* or ABORT */ 76f92359bfSslatteng #define FATAL 1 /* type of error */ 77f92359bfSslatteng #define BMASK 0377 /* byte grabber */ 7822d5b456Sslatteng #ifndef FONTDIR 794da297a9Sslatteng #define FONTDIR "/usr/lib/font" /* default place to find font descriptions */ 8022d5b456Sslatteng #endif 814da297a9Sslatteng #define BITDIR "/usr/lib/vfont" /* default place to look for font rasters */ 82f92359bfSslatteng #define MAXWRIT 4096 /* max characters allowed to write at once */ 83f92359bfSslatteng 84ebd02298Sslatteng #define hmot(n) hgoto(hpos + n) 85f92359bfSslatteng #define vmot(n) vgoto(vpos + n) 86f92359bfSslatteng 87f92359bfSslatteng 88*69c7ec87Sslatteng char SccsId[]= "dvar.c 1.12 84/05/24"; 89f92359bfSslatteng 90f92359bfSslatteng int output = 0; /* do we do output at all? */ 91f92359bfSslatteng int nolist = 0; /* output page list if > 0 */ 92f92359bfSslatteng int olist[20]; /* pairs of page numbers */ 93f92359bfSslatteng int spage = 9999; /* stop every spage pages */ 94f92359bfSslatteng int scount = 0; 95f92359bfSslatteng struct dev dev; 96f92359bfSslatteng struct font *fontbase[NFONTS+1]; 97f92359bfSslatteng short * pstab; /* point size table pointer */ 98f92359bfSslatteng int nsizes; /* number of sizes device is capable of printing */ 99f92359bfSslatteng int nfonts; /* number of fonts device is capable of printing */ 100*69c7ec87Sslatteng int nstips; /* number of stipple fonts device can print */ 101f92359bfSslatteng int nchtab; 102f92359bfSslatteng char * chname; 103f92359bfSslatteng short * chtab; 1044da297a9Sslatteng char * fitab[NFONTS+1]; /* font inclusion table - maps ascii to ch # */ 1054da297a9Sslatteng char * widtab[NFONTS+1]; /* width table for each font */ 106f92359bfSslatteng char * codetab[NFONTS+1]; /* device codes */ 1074da297a9Sslatteng char * fontdir = FONTDIR; /* place to find devxxx directories */ 1084da297a9Sslatteng char * bitdir = BITDIR; /* place to find raster fonts and fontmap */ 1091c9df754Sslatteng char * fontname[NFONTS+1]; /* table of what font is on what position */ 1104da297a9Sslatteng struct { /* table of what font */ 1114da297a9Sslatteng char fname[3]; /* name maps to what */ 1124da297a9Sslatteng char *ffile; /* filename in bitdirectory */ 1134da297a9Sslatteng } fontmap[NFONTS+1]; 1144da297a9Sslatteng 115f92359bfSslatteng 116f92359bfSslatteng #ifdef DEBUGABLE 117f92359bfSslatteng int dbg = 0; 118f92359bfSslatteng #endif 1194da297a9Sslatteng int size = -1; /* current point size (internal pstable index) */ 120f92359bfSslatteng int font = -1; /* current font - not using any to start with */ 121*69c7ec87Sslatteng int stip = -1; /* current stipple font - not using any to start with */ 122*69c7ec87Sslatteng int stipmem = 0; /* current member to use from stipple font */ 123f92359bfSslatteng int hpos; /* horizontal position we are to be at next; left = 0 */ 124f92359bfSslatteng int vpos; /* current vertical position (down positive) */ 1254da297a9Sslatteng extern linethickness; /* thickness (in pixels) of any drawn object */ 126ebd02298Sslatteng extern linmod; /* line style (a bit mask - dotted, etc.) of objects */ 127f92359bfSslatteng int lastw; /* width of last character printed */ 128f92359bfSslatteng 129f92359bfSslatteng 130f92359bfSslatteng #define DISPATCHSIZE 256 /* must be a power of two */ 131f92359bfSslatteng #define CHARMASK (DISPATCHSIZE-1) 132f92359bfSslatteng #define DSIZ ((sizeof *dispatch)*DISPATCHSIZE) 133f92359bfSslatteng #define OUTFILE fileno (stdout) 1344da297a9Sslatteng #define RES 200 /* resolution of the device (dots/in) */ 135f92359bfSslatteng 1361a4ecc79Sslatteng #define RASTER_LENGTH 2112 /* device line length */ 137f92359bfSslatteng #define BYTES_PER_LINE (RASTER_LENGTH/8) 1381c9df754Sslatteng #ifndef FULLPAGE 1391c9df754Sslatteng # define NLINES 1600 /* page width, 8 inches */ 1401c9df754Sslatteng #endif 1411c9df754Sslatteng #ifdef FULLPAGE 142ebd02298Sslatteng # define NLINES 1700 /* page width, 8.5 inches */ 1431c9df754Sslatteng #endif 144f92359bfSslatteng #define BUFFER_SIZE (NLINES*BYTES_PER_LINE) /* number of chars in picture */ 145f92359bfSslatteng 146f92359bfSslatteng 147f92359bfSslatteng int pltmode[] = { VPLOT }; 148f92359bfSslatteng int prtmode[] = { VPRINT }; 149cb97edc8Sslatteng char buffer1[BUFFER_SIZE]; /* Big line buffers */ 150cb97edc8Sslatteng char buffer2[BUFFER_SIZE]; 151cb97edc8Sslatteng char * fill = &buffer1[0]; /* Zero origin in filling buffer */ 152cb97edc8Sslatteng char * empty = &buffer2[0]; /* Zero origin in emptying buffer */ 153cb97edc8Sslatteng char * elevel = &buffer2[0]; /* current position in emptying buffer */ 154cb97edc8Sslatteng int emptypos = NLINES; /* amount of emptying done (initially "done") */ 155cb97edc8Sslatteng 156f92359bfSslatteng 157f92359bfSslatteng char * calloc(); 158f92359bfSslatteng char * nalloc(); 159f92359bfSslatteng char * allpanic(); 1604dabf413Sslatteng char * operand(); 161f92359bfSslatteng 162f92359bfSslatteng struct header { 163f92359bfSslatteng short magic; 164f92359bfSslatteng unsigned short size; 165f92359bfSslatteng short maxx; 166f92359bfSslatteng short maxy; 167f92359bfSslatteng short xtnd; 168f92359bfSslatteng } header; 169f92359bfSslatteng 170f92359bfSslatteng struct dispatch{ 171f92359bfSslatteng unsigned short addr; 172f92359bfSslatteng short nbytes; 173f92359bfSslatteng char up; 174f92359bfSslatteng char down; 175f92359bfSslatteng char left; 176f92359bfSslatteng char right; 177f92359bfSslatteng short width; 178f92359bfSslatteng }; 179f92359bfSslatteng 180f92359bfSslatteng struct fontdes { 181cb97edc8Sslatteng int fnum; /* if == -1, then this position is empty */ 182f92359bfSslatteng int psize; 183f92359bfSslatteng struct dispatch *disp; 184f92359bfSslatteng char *bits; 185cb97edc8Sslatteng } fontdes[NFONTS+1]; /* initialized at program start */ 186f92359bfSslatteng 187f92359bfSslatteng struct dispatch *dispatch; 188*69c7ec87Sslatteng struct dispatch *stip_disp; 189f92359bfSslatteng int cfnum = -1; 190f92359bfSslatteng int cpsize = 10; 191f92359bfSslatteng int cfont = 1; 192f92359bfSslatteng char *bits; 193*69c7ec87Sslatteng char *stip_bits; 194*69c7ec87Sslatteng int bordered = 1; /* flag: "do polygons get bordered?" */ 195f92359bfSslatteng int fontwanted = 1; /* flag: "has a new font been requested?" */ 196f92359bfSslatteng int nfontnum = -1; 197f92359bfSslatteng int npsize = 10; 198f92359bfSslatteng 199f92359bfSslatteng 200f92359bfSslatteng 201f92359bfSslatteng main(argc, argv) 202f92359bfSslatteng char *argv[]; 203f92359bfSslatteng { 204cb97edc8Sslatteng register FILE *fp; 205cb97edc8Sslatteng register int i; 206f92359bfSslatteng 207cb97edc8Sslatteng for (i = 0; i <= NFONTS; fontdes[i++].fnum = -1); 2084dabf413Sslatteng while (--argc > 0 && **++argv == '-') { 2094dabf413Sslatteng switch ((*argv)[1]) { 210f92359bfSslatteng case 'F': 2111c9df754Sslatteng bitdir = operand(&argc, &argv); 2124da297a9Sslatteng break; 2134da297a9Sslatteng case 'f': 2141c9df754Sslatteng fontdir = operand(&argc, &argv); 215f92359bfSslatteng break; 216f92359bfSslatteng case 'o': 2174dabf413Sslatteng outlist(operand(&argc, &argv)); 218f92359bfSslatteng break; 219f92359bfSslatteng #ifdef DEBUGABLE 220f92359bfSslatteng case 'd': 2214dabf413Sslatteng dbg = atoi(operand(&argc, &argv)); 222f92359bfSslatteng if (dbg == 0) dbg = 1; 223f92359bfSslatteng break; 224f92359bfSslatteng #endif 225f92359bfSslatteng case 's': 2264dabf413Sslatteng spage = atoi(operand(&argc, &argv)); 227f92359bfSslatteng if (spage <= 0) 228f92359bfSslatteng spage = 9999; 229f92359bfSslatteng break; 230f92359bfSslatteng } 231f92359bfSslatteng } 232f92359bfSslatteng 2331c9df754Sslatteng #ifdef DRIVER 234f92359bfSslatteng ioctl(OUTFILE, VSETSTATE, pltmode); 2351c9df754Sslatteng #endif 236f92359bfSslatteng 2374dabf413Sslatteng if (argc < 1) 238f92359bfSslatteng conv(stdin); 239f92359bfSslatteng else 2404dabf413Sslatteng while (argc--) { 2414dabf413Sslatteng if (strcmp(*argv, "-") == 0) 242f92359bfSslatteng fp = stdin; 243f92359bfSslatteng else if ((fp = fopen(*argv, "r")) == NULL) 244f92359bfSslatteng error(FATAL, "can't open %s", *argv); 245f92359bfSslatteng conv(fp); 246f92359bfSslatteng fclose(fp); 2474dabf413Sslatteng argv++; 248f92359bfSslatteng } 249f92359bfSslatteng exit(0); 250f92359bfSslatteng } 251f92359bfSslatteng 2524dabf413Sslatteng 2534dabf413Sslatteng /*----------------------------------------------------------------------------* 2544dabf413Sslatteng | Routine: char * operand (& argc, & argv) 2554dabf413Sslatteng | 2564dabf413Sslatteng | Results: returns address of the operand given with a command-line 2574dabf413Sslatteng | option. It uses either "-Xoperand" or "-X operand", whichever 2584dabf413Sslatteng | is present. The program is terminated if no option is present. 2594dabf413Sslatteng | 2604dabf413Sslatteng | Side Efct: argc and argv are updated as necessary. 2614dabf413Sslatteng *----------------------------------------------------------------------------*/ 2624dabf413Sslatteng 2634dabf413Sslatteng char *operand(argcp, argvp) 2644dabf413Sslatteng int * argcp; 2654dabf413Sslatteng char ***argvp; 2664dabf413Sslatteng { 2674dabf413Sslatteng if ((**argvp)[2]) return(**argvp + 2); /* operand immediately follows */ 2684dabf413Sslatteng if ((--*argcp) <= 0) /* no operand */ 2694dabf413Sslatteng error (FATAL, "command-line option operand missing.\n"); 2704dabf413Sslatteng return(*(++(*argvp))); /* operand next word */ 2714dabf413Sslatteng } 2724dabf413Sslatteng 2734dabf413Sslatteng 274f92359bfSslatteng outlist(s) /* process list of page numbers to be printed */ 275f92359bfSslatteng char *s; 276f92359bfSslatteng { 277f92359bfSslatteng int n1, n2, i; 278f92359bfSslatteng 279f92359bfSslatteng nolist = 0; 280f92359bfSslatteng while (*s) { 281f92359bfSslatteng n1 = 0; 282f92359bfSslatteng if (isdigit(*s)) 283f92359bfSslatteng do 284f92359bfSslatteng n1 = 10 * n1 + *s++ - '0'; 285f92359bfSslatteng while (isdigit(*s)); 286f92359bfSslatteng else 287f92359bfSslatteng n1 = -9999; 288f92359bfSslatteng n2 = n1; 289f92359bfSslatteng if (*s == '-') { 290f92359bfSslatteng s++; 291f92359bfSslatteng n2 = 0; 292f92359bfSslatteng if (isdigit(*s)) 293f92359bfSslatteng do 294f92359bfSslatteng n2 = 10 * n2 + *s++ - '0'; 295f92359bfSslatteng while (isdigit(*s)); 296f92359bfSslatteng else 297f92359bfSslatteng n2 = 9999; 298f92359bfSslatteng } 299f92359bfSslatteng olist[nolist++] = n1; 300f92359bfSslatteng olist[nolist++] = n2; 301f92359bfSslatteng if (*s != '\0') 302f92359bfSslatteng s++; 303f92359bfSslatteng } 304f92359bfSslatteng olist[nolist] = 0; 305f92359bfSslatteng #ifdef DEBUGABLE 306f92359bfSslatteng if (dbg) 307f92359bfSslatteng for (i=0; i<nolist; i += 2) 308f92359bfSslatteng fprintf(stderr,"%3d %3d\n", olist[i], olist[i+1]); 309f92359bfSslatteng #endif 310f92359bfSslatteng } 311f92359bfSslatteng 312f92359bfSslatteng conv(fp) 313f92359bfSslatteng register FILE *fp; 314f92359bfSslatteng { 315f92359bfSslatteng register int c, k; 316f92359bfSslatteng int m, n, n1, m1; 317f92359bfSslatteng char str[100], buf[300]; 318f92359bfSslatteng 319f92359bfSslatteng while ((c = getc(fp)) != EOF) { 320f92359bfSslatteng switch (c) { 321f92359bfSslatteng case '\n': /* when input is text */ 322f92359bfSslatteng case ' ': 323f92359bfSslatteng case 0: /* occasional noise creeps in */ 324f92359bfSslatteng break; 325f92359bfSslatteng case '{': /* push down current environment */ 326f92359bfSslatteng t_push(); 327f92359bfSslatteng break; 328f92359bfSslatteng case '}': 329f92359bfSslatteng t_pop(); 330f92359bfSslatteng break; 331f92359bfSslatteng case '0': case '1': case '2': case '3': case '4': 332f92359bfSslatteng case '5': case '6': case '7': case '8': case '9': 333f92359bfSslatteng /* two motion digits plus a character */ 334f92359bfSslatteng hmot((c-'0')*10 + getc(fp)-'0'); 335f92359bfSslatteng put1(getc(fp)); 336f92359bfSslatteng break; 337f92359bfSslatteng case 'c': /* single ascii character */ 338f92359bfSslatteng put1(getc(fp)); 339f92359bfSslatteng break; 340f92359bfSslatteng case 'C': 341f92359bfSslatteng fscanf(fp, "%s", str); 342f92359bfSslatteng put1s(str); 343f92359bfSslatteng break; 344f92359bfSslatteng case 't': /* straight text */ 345f92359bfSslatteng fgets(buf, sizeof(buf), fp); 346f92359bfSslatteng t_text(buf); 347f92359bfSslatteng break; 348f92359bfSslatteng case 'D': /* draw function */ 349289ea231Sslatteng if (fgets(buf, sizeof(buf), fp) == NULL) 350289ea231Sslatteng error(FATAL, "unexpected end of input");; 351f92359bfSslatteng switch (buf[0]) { 352f92359bfSslatteng case 'l': /* draw a line */ 353f92359bfSslatteng sscanf(buf+1, "%d %d", &n, &m); 354f92359bfSslatteng drawline(n, m); 355f92359bfSslatteng break; 356f92359bfSslatteng case 'c': /* circle */ 357f92359bfSslatteng sscanf(buf+1, "%d", &n); 358f92359bfSslatteng drawcirc(n); 359f92359bfSslatteng break; 360f92359bfSslatteng case 'e': /* ellipse */ 361f92359bfSslatteng sscanf(buf+1, "%d %d", &m, &n); 362f92359bfSslatteng drawellip(m, n); 363f92359bfSslatteng break; 364f92359bfSslatteng case 'a': /* arc */ 365f92359bfSslatteng sscanf(buf+1, "%d %d %d %d", &n, &m, &n1, &m1); 366f92359bfSslatteng drawarc(n, m, n1, m1); 367f92359bfSslatteng break; 368*69c7ec87Sslatteng case 'P': /* unbordered polygon */ 369*69c7ec87Sslatteng bordered = 0; /* unset border flag */ 370*69c7ec87Sslatteng case 'p': /* polygon */ 371*69c7ec87Sslatteng sscanf(buf+1, "%d", &m); /* get stipple */ 372*69c7ec87Sslatteng n = 1; /* number first */ 373*69c7ec87Sslatteng while (buf[++n] == ' '); 374*69c7ec87Sslatteng while (isdigit(buf[++n])); 375*69c7ec87Sslatteng setfill(m); /* set up stipple */ 376*69c7ec87Sslatteng drawwig(buf+n, fp, -1); /* draw polygon */ 377*69c7ec87Sslatteng bordered = 1; /* ALWAYS set after */ 378*69c7ec87Sslatteng break; 379f92359bfSslatteng case '~': /* wiggly line */ 380*69c7ec87Sslatteng drawwig(buf+1, fp, 1); 381*69c7ec87Sslatteng break; 3821a4ecc79Sslatteng case 'g': /* gremlin spline */ 383*69c7ec87Sslatteng drawwig(buf+1, fp, 0); 3841a4ecc79Sslatteng break; 3851a4ecc79Sslatteng case 't': /* line thickness */ 3861a4ecc79Sslatteng sscanf(buf+1, "%d", &n); 3871a4ecc79Sslatteng drawthick(n); 3881a4ecc79Sslatteng break; 3891a4ecc79Sslatteng case 's': /* line style */ 3901a4ecc79Sslatteng sscanf(buf+1, "%d", &n); 3911a4ecc79Sslatteng drawstyle(n); 392f92359bfSslatteng break; 393f92359bfSslatteng default: 394ebd02298Sslatteng error(FATAL, "unknown drawing function %s", buf); 395f92359bfSslatteng break; 396f92359bfSslatteng } 397f92359bfSslatteng break; 398f92359bfSslatteng case 's': 399f92359bfSslatteng fscanf(fp, "%d", &n); /* ignore fractional sizes */ 400f92359bfSslatteng setsize(t_size(n)); 401f92359bfSslatteng break; 402f92359bfSslatteng case 'f': 403f92359bfSslatteng fscanf(fp, "%s", str); 404f92359bfSslatteng setfont(t_font(str)); 405f92359bfSslatteng break; 406*69c7ec87Sslatteng case 'i': 407*69c7ec87Sslatteng fscanf(fp, "%d", &n); 408*69c7ec87Sslatteng setstip(n); 409*69c7ec87Sslatteng break; 410f92359bfSslatteng case 'H': /* absolute horizontal motion */ 411f92359bfSslatteng /* fscanf(fp, "%d", &n); */ 412f92359bfSslatteng while ((c = getc(fp)) == ' ') 413f92359bfSslatteng ; 414f92359bfSslatteng k = 0; 415f92359bfSslatteng do { 416f92359bfSslatteng k = 10 * k + c - '0'; 417f92359bfSslatteng } while (isdigit(c = getc(fp))); 418f92359bfSslatteng ungetc(c, fp); 419f92359bfSslatteng hgoto(k); 420f92359bfSslatteng break; 421f92359bfSslatteng case 'h': /* relative horizontal motion */ 422f92359bfSslatteng while ((c = getc(fp)) == ' ') 423f92359bfSslatteng ; 424f92359bfSslatteng k = 0; 425f92359bfSslatteng do { 426f92359bfSslatteng k = 10 * k + c - '0'; 427f92359bfSslatteng } while (isdigit(c = getc(fp))); 428f92359bfSslatteng ungetc(c, fp); 429f92359bfSslatteng hmot(k); 430f92359bfSslatteng break; 431f92359bfSslatteng case 'w': /* word space */ 432f92359bfSslatteng break; 433f92359bfSslatteng case 'V': 434f92359bfSslatteng fscanf(fp, "%d", &n); 435f92359bfSslatteng vgoto(n); 436f92359bfSslatteng break; 437f92359bfSslatteng case 'v': 438f92359bfSslatteng fscanf(fp, "%d", &n); 439f92359bfSslatteng vmot(n); 440f92359bfSslatteng break; 441f92359bfSslatteng case 'p': /* new page */ 442f92359bfSslatteng fscanf(fp, "%d", &n); 443f92359bfSslatteng t_page(n); 444f92359bfSslatteng break; 445f92359bfSslatteng case 'n': /* end of line */ 446f92359bfSslatteng t_newline(); 447289ea231Sslatteng 448f92359bfSslatteng case '#': /* comment */ 449289ea231Sslatteng do 450289ea231Sslatteng c = getc(fp); 451289ea231Sslatteng while (c != '\n' && c != EOF); 452f92359bfSslatteng break; 453f92359bfSslatteng case 'x': /* device control */ 45419de12e6Sslatteng if (devcntrl(fp)) return; 455f92359bfSslatteng break; 456f92359bfSslatteng default: 457ebd02298Sslatteng error(FATAL, "unknown input character %o %c", c, c); 458f92359bfSslatteng } 459cb97edc8Sslatteng if (emptypos < NLINES) { /* for each input operation */ 460cb97edc8Sslatteng slop_lines(1); /* put out an output line */ 461cb97edc8Sslatteng #ifdef DRIVER 462cb97edc8Sslatteng if (emptypos == NLINES) { 463cb97edc8Sslatteng ioctl(OUTFILE, VSETSTATE, prtmode); 464cb97edc8Sslatteng if (write(OUTFILE, "\f", 2) != 2) 465cb97edc8Sslatteng exit(RESTART); 466cb97edc8Sslatteng ioctl(OUTFILE, VSETSTATE, pltmode); 467cb97edc8Sslatteng } 468cb97edc8Sslatteng #endif 469cb97edc8Sslatteng } 470f92359bfSslatteng } 471f92359bfSslatteng } 472f92359bfSslatteng 47319de12e6Sslatteng int devcntrl(fp) /* interpret device control functions */ 47419de12e6Sslatteng FILE *fp; /* returns -1 upon "stop" command */ 475f92359bfSslatteng { 476f92359bfSslatteng char str[20], str1[50], buf[50]; 477f92359bfSslatteng int c, n; 478f92359bfSslatteng 479f92359bfSslatteng fscanf(fp, "%s", str); 480f92359bfSslatteng switch (str[0]) { /* crude for now */ 481f92359bfSslatteng case 'i': /* initialize */ 482f92359bfSslatteng fileinit(); 483f92359bfSslatteng t_init(); 484f92359bfSslatteng break; 485f92359bfSslatteng case 't': /* trailer */ 486f92359bfSslatteng break; 487f92359bfSslatteng case 'p': /* pause -- can restart */ 488f92359bfSslatteng t_reset('p'); 489f92359bfSslatteng break; 490f92359bfSslatteng case 's': /* stop */ 491f92359bfSslatteng t_reset('s'); 49219de12e6Sslatteng return -1; 493f92359bfSslatteng case 'r': /* resolution assumed when prepared */ 4944da297a9Sslatteng fscanf(fp, "%d", &n); 495*69c7ec87Sslatteng if (n!=RES) error(FATAL,"Input computed for wrong printer"); 496f92359bfSslatteng break; 497f92359bfSslatteng case 'f': /* font used */ 498f92359bfSslatteng fscanf(fp, "%d %s", &n, str); 499f92359bfSslatteng fgets(buf, sizeof buf, fp); /* in case there's a filename */ 500f92359bfSslatteng ungetc('\n', fp); /* fgets goes too far */ 501f92359bfSslatteng str1[0] = 0; /* in case nothing comes in */ 502f92359bfSslatteng sscanf(buf, "%s", str1); 503f92359bfSslatteng loadfont(n, str, str1); 504f92359bfSslatteng break; 505f92359bfSslatteng /* these don't belong here... */ 506f92359bfSslatteng case 'H': /* char height */ 507f92359bfSslatteng fscanf(fp, "%d", &n); 508f92359bfSslatteng t_charht(n); 509f92359bfSslatteng break; 510f92359bfSslatteng case 'S': /* slant */ 511f92359bfSslatteng fscanf(fp, "%d", &n); 512f92359bfSslatteng t_slant(n); 513f92359bfSslatteng break; 514f92359bfSslatteng } 515f92359bfSslatteng while ((c = getc(fp)) != '\n') /* skip rest of input line */ 516f92359bfSslatteng if (c == EOF) 51719de12e6Sslatteng return -1; 51819de12e6Sslatteng return 0; 519f92359bfSslatteng } 520f92359bfSslatteng 521f92359bfSslatteng /* fileinit: read in font and code files, etc. 522f92359bfSslatteng Must open table for device, read in resolution, 5234da297a9Sslatteng size info, font info, etc. and set params. 5244da297a9Sslatteng Also read in font name mapping. 525f92359bfSslatteng */ 5264da297a9Sslatteng 527f92359bfSslatteng fileinit() 528f92359bfSslatteng { 5294da297a9Sslatteng register int i; 5304da297a9Sslatteng register int fin; 5314da297a9Sslatteng register int nw; 5324da297a9Sslatteng register char *filebase; 5334da297a9Sslatteng register char *p; 5344da297a9Sslatteng register FILE *fp; 5354da297a9Sslatteng char temp[100]; 5364da297a9Sslatteng 5374da297a9Sslatteng /* first, read in font map file. The file must be of Format: 5384da297a9Sslatteng XX FILENAME (XX = troff font name) 5394da297a9Sslatteng with one entry per text line of the file. 5404da297a9Sslatteng Extra stuff after FILENAME is ignored */ 5414da297a9Sslatteng 5424da297a9Sslatteng sprintf(temp, "%s/fontmap", bitdir); 5434da297a9Sslatteng if ((fp = fopen(temp, "r")) == NULL) 5444da297a9Sslatteng error(FATAL, "Can't open %s", temp); 5454da297a9Sslatteng for (i = 0; i <= NFONTS && fgets(temp, 100, fp) != NULL; i++) { 5464da297a9Sslatteng sscanf(temp, "%2s", fontmap[i].fname); 5474da297a9Sslatteng p = &temp[0]; 5484da297a9Sslatteng while (*p != ' ' && *p != ' ') p++; 5494da297a9Sslatteng while (*p == ' ' || *p == ' ') p++; 5504da297a9Sslatteng filebase = p; 5514da297a9Sslatteng for (nw = 1; *p != '\n' && *p != ' ' && *p != '\t'; p++) nw++; 5524da297a9Sslatteng fontmap[i].ffile = nalloc(1, nw); 5534da297a9Sslatteng sscanf(filebase, "%s", fontmap[i].ffile); 5544da297a9Sslatteng } 5554da297a9Sslatteng fontmap[++i].fname[0] = '0'; /* finish off with zeros */ 5564da297a9Sslatteng fontmap[i].ffile = (char *) 0; 5574da297a9Sslatteng fclose(fp); 5584da297a9Sslatteng #ifdef DEBUGABLE 5594da297a9Sslatteng if(dbg) { 5604da297a9Sslatteng fprintf(stderr, "font map:\n"); 5614da297a9Sslatteng for (i = 0; fontmap[i].ffile; i++) 5624da297a9Sslatteng fprintf(stderr,"%s = %s\n", fontmap[i].fname, fontmap[i].ffile); 5634da297a9Sslatteng } 5644da297a9Sslatteng #endif 565f92359bfSslatteng 566cb97edc8Sslatteng sprintf(temp, "%s/devva/DESC.out", fontdir); 567f92359bfSslatteng if ((fin = open(temp, 0)) < 0) 568ebd02298Sslatteng error(FATAL, "can't open tables for %s", temp); 569f92359bfSslatteng read(fin, &dev, sizeof(struct dev)); 570f92359bfSslatteng nfonts = dev.nfonts; 571*69c7ec87Sslatteng nstips = dev.nstips; 572f92359bfSslatteng nsizes = dev.nsizes; 573f92359bfSslatteng nchtab = dev.nchtab; 574f92359bfSslatteng filebase = calloc(1, dev.filesize); /* enough room for whole file */ 575f92359bfSslatteng read(fin, filebase, dev.filesize); /* all at once */ 576f92359bfSslatteng pstab = (short *) filebase; 577f92359bfSslatteng chtab = pstab + nsizes + 1; 578f92359bfSslatteng chname = (char *) (chtab + dev.nchtab); 579f92359bfSslatteng p = chname + dev.lchname; 580f92359bfSslatteng for (i = 1; i <= nfonts; i++) { 581f92359bfSslatteng fontbase[i] = (struct font *) p; 582f92359bfSslatteng nw = *p & BMASK; /* 1st thing is width count */ 5831c9df754Sslatteng p += sizeof(struct font); 584f92359bfSslatteng widtab[i] = p; 585f92359bfSslatteng codetab[i] = p + 2 * nw; 586f92359bfSslatteng fitab[i] = p + 3 * nw; 587f92359bfSslatteng p += 3 * nw + dev.nchtab + 128 - 32; 588f92359bfSslatteng t_fp(i, fontbase[i]->namefont, fontbase[i]->intname); 589f92359bfSslatteng #ifdef DEBUGABLE 590f92359bfSslatteng if (dbg > 1) fontprint(i); 591f92359bfSslatteng #endif 592f92359bfSslatteng } 593*69c7ec87Sslatteng for (i = 1; i <= nstips; i++) { /* add in stipple "filenames" */ 594*69c7ec87Sslatteng if (nfonts + i <= NFONTS) 595*69c7ec87Sslatteng t_fp(nfonts + i, p, (char *)0); 596*69c7ec87Sslatteng p += strlen(p) + 1; 597*69c7ec87Sslatteng } 598f92359bfSslatteng fontbase[0] = (struct font *) 599f92359bfSslatteng calloc(1,3*255 + dev.nchtab + (128-32) + sizeof (struct font)); 600f92359bfSslatteng widtab[0] = (char *) fontbase[0] + sizeof (struct font); 601f92359bfSslatteng fontbase[0]->nwfont = 255; 602f92359bfSslatteng close(fin); 6034da297a9Sslatteng 604f92359bfSslatteng } 605f92359bfSslatteng 6064da297a9Sslatteng 6076dfd4b55Sslatteng #ifdef DEBUGABLE 608f92359bfSslatteng fontprint(i) /* debugging print of font i (0,...) */ 609f92359bfSslatteng { 610f92359bfSslatteng int j, n; 611f92359bfSslatteng char *p; 612f92359bfSslatteng 613f92359bfSslatteng fprintf(stderr,"font %d:\n", i); 614f92359bfSslatteng p = (char *) fontbase[i]; 615f92359bfSslatteng n = fontbase[i]->nwfont & BMASK; 616f92359bfSslatteng fprintf(stderr, 617f92359bfSslatteng "base=0%o, nchars=%d, spec=%d, name=%s, widtab=0%o, fitab=0%o\n",p, 618f92359bfSslatteng n,fontbase[i]->specfont,fontbase[i]->namefont,widtab[i],fitab[i]); 619f92359bfSslatteng fprintf(stderr,"widths:\n"); 620f92359bfSslatteng for (j=0; j <= n; j++) { 621f92359bfSslatteng fprintf(stderr," %2d", widtab[i][j] & BMASK); 622f92359bfSslatteng if (j % 20 == 19) fprintf(stderr,"\n"); 623f92359bfSslatteng } 624f92359bfSslatteng fprintf(stderr,"\ncodetab:\n"); 625f92359bfSslatteng for (j=0; j <= n; j++) { 626f92359bfSslatteng fprintf(stderr," %2d", codetab[i][j] & BMASK); 627f92359bfSslatteng if (j % 20 == 19) fprintf(stderr,"\n"); 628f92359bfSslatteng } 629f92359bfSslatteng fprintf(stderr,"\nfitab:\n"); 630f92359bfSslatteng for (j=0; j <= dev.nchtab + 128-32; j++) { 631f92359bfSslatteng fprintf(stderr," %2d", fitab[i][j] & BMASK); 632f92359bfSslatteng if (j % 20 == 19) fprintf(stderr,"\n"); 633f92359bfSslatteng } 634f92359bfSslatteng fprintf(stderr,"\n"); 635f92359bfSslatteng } 6366dfd4b55Sslatteng #endif 637f92359bfSslatteng 63819de12e6Sslatteng 639f92359bfSslatteng loadfont(n, s, s1) /* load font info for font s on position n (0...) */ 640f92359bfSslatteng int n; 641f92359bfSslatteng char *s, *s1; 642f92359bfSslatteng { 643f92359bfSslatteng char temp[60]; 64419de12e6Sslatteng register int fin; 64519de12e6Sslatteng register int nw; 64619de12e6Sslatteng register int norig; 6474da297a9Sslatteng 648f92359bfSslatteng if (n < 0 || n > NFONTS) 649f92359bfSslatteng error(FATAL, "illegal fp command %d %s", n, s); 650f92359bfSslatteng if (strcmp(s, fontbase[n]->namefont) == 0) 651f92359bfSslatteng return; 65219de12e6Sslatteng 65319de12e6Sslatteng for (fin = 1; fin <= NFONTS; fin++) /* first check to see if the */ 65419de12e6Sslatteng if (strcmp(s, fontbase[fin]->namefont) == 0) { /* font is loaded */ 65519de12e6Sslatteng register char *c; /* somewhere else */ 65619de12e6Sslatteng 65719de12e6Sslatteng #define ptrswap(x, y) { c = (char*) (x); x = y; y = c; } 6586dfd4b55Sslatteng #define ptrfswap(x, y) { c = (char*) (x); x = y; y = (struct font *) c; } 65919de12e6Sslatteng 6606dfd4b55Sslatteng ptrfswap(fontbase[n], fontbase[fin]); 66119de12e6Sslatteng ptrswap(codetab[n], codetab[fin]); 66219de12e6Sslatteng ptrswap(widtab[n], widtab[fin]); 66319de12e6Sslatteng ptrswap(fitab[n], fitab[fin]); 66419de12e6Sslatteng t_fp(n, fontbase[n]->namefont, fontbase[n]->intname); 66519de12e6Sslatteng t_fp(fin, fontbase[fin]->namefont, fontbase[fin]->intname); 66619de12e6Sslatteng return; 66719de12e6Sslatteng } 66819de12e6Sslatteng 669f92359bfSslatteng if (s1 == NULL || s1[0] == '\0') 670cb97edc8Sslatteng sprintf(temp, "%s/devva/%s.out", fontdir, s); 671f92359bfSslatteng else 672f92359bfSslatteng sprintf(temp, "%s/%s.out", s1, s); 673f92359bfSslatteng if ((fin = open(temp, 0)) < 0) 674f92359bfSslatteng error(FATAL, "can't open font table %s", temp); 675f92359bfSslatteng norig = fontbase[n]->nwfont & BMASK; 676f92359bfSslatteng read(fin, fontbase[n], 3*norig + nchtab+128-32 + sizeof(struct font)); 677f92359bfSslatteng if ((fontbase[n]->nwfont & BMASK) > norig) 678ebd02298Sslatteng error(FATAL, "Font %s too big for position %d", s, n); 679f92359bfSslatteng close(fin); 680f92359bfSslatteng nw = fontbase[n]->nwfont & BMASK; 681f92359bfSslatteng widtab[n] = (char *) fontbase[n] + sizeof(struct font); 682f92359bfSslatteng codetab[n] = (char *) widtab[n] + 2 * nw; 683f92359bfSslatteng fitab[n] = (char *) widtab[n] + 3 * nw; 684f92359bfSslatteng t_fp(n, fontbase[n]->namefont, fontbase[n]->intname); 685f92359bfSslatteng fontbase[n]->nwfont = norig; /* to later use full original size */ 686f92359bfSslatteng #ifdef DEBUGABLE 687f92359bfSslatteng if (dbg > 1) fontprint(n); 688f92359bfSslatteng #endif 689f92359bfSslatteng } 690f92359bfSslatteng 691ebd02298Sslatteng 692f92359bfSslatteng /*VARARGS1*/ 693f92359bfSslatteng error(f, s, a1, a2, a3, a4, a5, a6, a7) { 694ebd02298Sslatteng fprintf(stderr, "dvar: "); 695f92359bfSslatteng fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7); 696f92359bfSslatteng fprintf(stderr, "\n"); 6971c9df754Sslatteng if (f) exit(ABORT); 698f92359bfSslatteng } 699f92359bfSslatteng 700f92359bfSslatteng 701f92359bfSslatteng t_init() /* initialize device */ 702f92359bfSslatteng { 703f92359bfSslatteng int i; 704f92359bfSslatteng 705f92359bfSslatteng hpos = vpos = 0; 706f92359bfSslatteng 707f92359bfSslatteng setsize(t_size(10)); /* start somewhere */ 708f92359bfSslatteng setfont(1); 709f92359bfSslatteng } 710f92359bfSslatteng 711f92359bfSslatteng 712f92359bfSslatteng struct state { 713f92359bfSslatteng int ssize; 714f92359bfSslatteng int sfont; 715f92359bfSslatteng int shpos; 716f92359bfSslatteng int svpos; 717ebd02298Sslatteng int sstyle; 718ebd02298Sslatteng int sthick; 719f92359bfSslatteng }; 720f92359bfSslatteng struct state state[MAXSTATE]; 721f92359bfSslatteng struct state *statep = state; 722f92359bfSslatteng 723f92359bfSslatteng t_push() /* begin a new block */ 724f92359bfSslatteng { 725f92359bfSslatteng statep->ssize = size; 726f92359bfSslatteng statep->sfont = font; 727ebd02298Sslatteng statep->sstyle = linmod; 728ebd02298Sslatteng statep->sthick = linethickness; 729f92359bfSslatteng statep->shpos = hpos; 730f92359bfSslatteng statep->svpos = vpos; 731f92359bfSslatteng if (statep++ >= state+MAXSTATE) 732f92359bfSslatteng error(FATAL, "{ nested too deep"); 733f92359bfSslatteng } 734f92359bfSslatteng 735f92359bfSslatteng t_pop() /* pop to previous state */ 736f92359bfSslatteng { 737f92359bfSslatteng if (--statep < state) 738f92359bfSslatteng error(FATAL, "extra }"); 739f92359bfSslatteng size = statep->ssize; 740f92359bfSslatteng font = statep->sfont; 741f92359bfSslatteng hpos = statep->shpos; 742f92359bfSslatteng vpos = statep->svpos; 743ebd02298Sslatteng linmod = statep->sstyle; 744ebd02298Sslatteng linethickness = statep->sthick; 745f92359bfSslatteng } 746f92359bfSslatteng 747f92359bfSslatteng t_page(n) /* do whatever new page functions */ 748f92359bfSslatteng { 749f92359bfSslatteng int i; 750f92359bfSslatteng 751f92359bfSslatteng 752cb97edc8Sslatteng if (emptypos < NLINES) { /* finish off last page, if */ 753cb97edc8Sslatteng slop_lines(NLINES - emptypos); /* it's not done yet */ 7541c9df754Sslatteng #ifdef DRIVER 755f92359bfSslatteng ioctl(OUTFILE, VSETSTATE, prtmode); 756f92359bfSslatteng if (write(OUTFILE, "\f", 2) != 2) 757f92359bfSslatteng exit(RESTART); 758f92359bfSslatteng ioctl(OUTFILE, VSETSTATE, pltmode); 7591c9df754Sslatteng #endif 760f92359bfSslatteng } 761cb97edc8Sslatteng if (output) { 762cb97edc8Sslatteng emptypos = 0; /* set emptying to be started */ 763cb97edc8Sslatteng elevel = fill; /* swap buffer pointers */ 764cb97edc8Sslatteng fill = empty; 765cb97edc8Sslatteng empty = elevel; 766cb97edc8Sslatteng } 767f92359bfSslatteng 768f92359bfSslatteng vpos = 0; 769f92359bfSslatteng output = 1; 770f92359bfSslatteng if (nolist == 0) 771f92359bfSslatteng return; /* no -o specified */ 772f92359bfSslatteng output = 0; 773f92359bfSslatteng for (i = 0; i < nolist; i += 2) 774f92359bfSslatteng if (n >= olist[i] && n <= olist[i+1]) { 775f92359bfSslatteng output = 1; 776f92359bfSslatteng break; 777f92359bfSslatteng } 778f92359bfSslatteng } 779f92359bfSslatteng 780f92359bfSslatteng t_newline() /* do whatever for the end of a line */ 781f92359bfSslatteng { 782f92359bfSslatteng hpos = 0; /* because we're now back at the left margin */ 783f92359bfSslatteng } 784f92359bfSslatteng 785f92359bfSslatteng t_size(n) /* convert integer to internal size number*/ 786f92359bfSslatteng int n; 787f92359bfSslatteng { 788f92359bfSslatteng int i; 789f92359bfSslatteng 790f92359bfSslatteng if (n <= pstab[0]) 7914da297a9Sslatteng return(0); 792f92359bfSslatteng else if (n >= pstab[nsizes - 1]) 7934da297a9Sslatteng return(nsizes - 1); 794f92359bfSslatteng for (i = 0; n > pstab[i]; i++) 795f92359bfSslatteng ; 7964da297a9Sslatteng return(i); 797f92359bfSslatteng } 798f92359bfSslatteng 799f92359bfSslatteng t_charht(n) /* set character height to n */ 800f92359bfSslatteng int n; 801f92359bfSslatteng { 802f92359bfSslatteng #ifdef DEBUGABLE 8034da297a9Sslatteng if (dbg) error(!FATAL, "can't set height on varian"); 804f92359bfSslatteng #endif 805f92359bfSslatteng } 806f92359bfSslatteng 807f92359bfSslatteng t_slant(n) /* set slant to n */ 808f92359bfSslatteng int n; 809f92359bfSslatteng { 810f92359bfSslatteng #ifdef DEBUGABLE 8114da297a9Sslatteng if (dbg) error(!FATAL, "can't set slant on varian"); 812f92359bfSslatteng #endif 813f92359bfSslatteng } 814f92359bfSslatteng 815f92359bfSslatteng t_font(s) /* convert string to internal font number */ 816f92359bfSslatteng char *s; 817f92359bfSslatteng { 818f92359bfSslatteng int n; 819f92359bfSslatteng 820f92359bfSslatteng n = atoi(s); 821f92359bfSslatteng if (n < 0 || n > nfonts) 822f92359bfSslatteng n = 1; 823f92359bfSslatteng return(n); 824f92359bfSslatteng } 825f92359bfSslatteng 826f92359bfSslatteng t_text(s) /* print string s as text */ 827f92359bfSslatteng char *s; 828f92359bfSslatteng { 829f92359bfSslatteng int c; 830f92359bfSslatteng char str[100]; 831f92359bfSslatteng 832f92359bfSslatteng if (!output) 833f92359bfSslatteng return; 834f92359bfSslatteng while (c = *s++) { 835f92359bfSslatteng if (c == '\\') { 836f92359bfSslatteng switch (c = *s++) { 837f92359bfSslatteng case '\\': 838f92359bfSslatteng case 'e': 839f92359bfSslatteng put1('\\'); 840f92359bfSslatteng break; 841f92359bfSslatteng case '(': 842f92359bfSslatteng str[0] = *s++; 843f92359bfSslatteng str[1] = *s++; 844f92359bfSslatteng str[2] = '\0'; 845f92359bfSslatteng put1s(str); 846f92359bfSslatteng break; 847f92359bfSslatteng } 848f92359bfSslatteng } else { 849f92359bfSslatteng put1(c); 850f92359bfSslatteng } 851f92359bfSslatteng hmot(lastw); 852f92359bfSslatteng #ifdef DEBUGABLE 853f92359bfSslatteng if (dbg) fprintf(stderr,"width = %d\n", lastw); 854f92359bfSslatteng #endif 855f92359bfSslatteng } 856f92359bfSslatteng } 857f92359bfSslatteng 858cb97edc8Sslatteng 859f92359bfSslatteng t_reset(c) 860f92359bfSslatteng { 861cb97edc8Sslatteng if (c == 's') { 862cb97edc8Sslatteng t_page(); 863cb97edc8Sslatteng output = 0; 864cb97edc8Sslatteng t_page(); 8651c9df754Sslatteng #ifdef DRIVER 866f92359bfSslatteng ioctl(OUTFILE, VSETSTATE, prtmode); 867f92359bfSslatteng if (write(OUTFILE, "\f", 2) != 2) 868f92359bfSslatteng exit(RESTART); 8691c9df754Sslatteng #endif 870f92359bfSslatteng } 871f92359bfSslatteng } 872f92359bfSslatteng 873ebd02298Sslatteng 874ebd02298Sslatteng /*----------------------------------------------------------------------------* 875ebd02298Sslatteng | Routine: hgoto (horizontal_spot) 876ebd02298Sslatteng | 877ebd02298Sslatteng | Results: hpos is set to n. If n overlaps in either direction, it wraps 878ebd02298Sslatteng | around to the other end of the page. 879ebd02298Sslatteng *----------------------------------------------------------------------------*/ 880ebd02298Sslatteng 881ebd02298Sslatteng hgoto(n) 882ebd02298Sslatteng int n; 883f92359bfSslatteng { 884ebd02298Sslatteng if (n < 0) 885ebd02298Sslatteng n += NLINES; 886ebd02298Sslatteng else if (n >= NLINES) 887ebd02298Sslatteng n -= NLINES; 888ebd02298Sslatteng hpos = n; 889f92359bfSslatteng } 890ebd02298Sslatteng 891ebd02298Sslatteng 892ebd02298Sslatteng /*----------------------------------------------------------------------------* 893ebd02298Sslatteng | Routine: vgoto (vertical_spot) 894ebd02298Sslatteng | 895ebd02298Sslatteng | Results: vpos is set to n. If n overlaps in either direction, it wraps 896ebd02298Sslatteng | around to the other end of the page. 897ebd02298Sslatteng *----------------------------------------------------------------------------*/ 898ebd02298Sslatteng 899ebd02298Sslatteng vgoto(n) 900ebd02298Sslatteng int n; 901ebd02298Sslatteng { 902ebd02298Sslatteng if (n < 0) 903ebd02298Sslatteng n += RASTER_LENGTH; 904ebd02298Sslatteng else if (n > RASTER_LENGTH) 905ebd02298Sslatteng n -= RASTER_LENGTH; 906f92359bfSslatteng vpos = n; 907f92359bfSslatteng } 908f92359bfSslatteng 909f92359bfSslatteng put1s(s) /* s is a funny char name */ 910f92359bfSslatteng char *s; 911f92359bfSslatteng { 912f92359bfSslatteng int i; 913f92359bfSslatteng 914f92359bfSslatteng if (!output) 915f92359bfSslatteng return; 916f92359bfSslatteng #ifdef DEBUGABLE 917f92359bfSslatteng if (dbg) fprintf(stderr,"%s ", s); 918f92359bfSslatteng #endif 919f92359bfSslatteng for (i = 0; i < nchtab; i++) 920f92359bfSslatteng if (strcmp(&chname[chtab[i]], s) == 0) 921f92359bfSslatteng break; 922f92359bfSslatteng if (i < nchtab) 923f92359bfSslatteng put1(i + 128); 924f92359bfSslatteng } 925f92359bfSslatteng 926f92359bfSslatteng put1(c) /* output char c */ 927f92359bfSslatteng int c; 928f92359bfSslatteng { 929f92359bfSslatteng char *pw; 930f92359bfSslatteng register char *p; 931f92359bfSslatteng register int i, k; 932f92359bfSslatteng int j, ofont, code; 933f92359bfSslatteng 934f92359bfSslatteng if (!output) 935f92359bfSslatteng return; 936f92359bfSslatteng c -= 32; 937f92359bfSslatteng if (c <= 0) { 938f92359bfSslatteng #ifdef DEBUGABLE 939f92359bfSslatteng if (dbg) fprintf(stderr,"non-exist 0%o\n", c + 32); 940f92359bfSslatteng #endif 9414da297a9Sslatteng lastw = (widtab[font][0] * pstab[size] + dev.unitwidth/2) 942f92359bfSslatteng / dev.unitwidth; 943f92359bfSslatteng return; 944f92359bfSslatteng } 945f92359bfSslatteng k = ofont = font; 946f92359bfSslatteng i = fitab[font][c] & BMASK; 947f92359bfSslatteng if (i != 0) { /* it's on this font */ 948f92359bfSslatteng p = codetab[font]; /* get the printing value of ch */ 949f92359bfSslatteng pw = widtab[font]; /* get the width */ 9506dfd4b55Sslatteng } else { /* on another font - run down the font list */ 9516dfd4b55Sslatteng for (j=0; j++ <= nfonts; k = (k+1) % (nfonts+1)) { 952f92359bfSslatteng if (fitab[k] == 0) 953f92359bfSslatteng continue; 954f92359bfSslatteng if ((i=fitab[k][c] & BMASK) != 0) { 955f92359bfSslatteng p = codetab[k]; 956f92359bfSslatteng pw = widtab[k]; 957f92359bfSslatteng setfont(k); 958f92359bfSslatteng break; 959f92359bfSslatteng } 960f92359bfSslatteng } 9616dfd4b55Sslatteng } 9621c9df754Sslatteng 9636dfd4b55Sslatteng if (i == 0) { 964f92359bfSslatteng #ifdef DEBUGABLE 965f92359bfSslatteng if (dbg) fprintf(stderr,"not found 0%o\n", c+32); 966f92359bfSslatteng #endif 967f92359bfSslatteng return; 968f92359bfSslatteng } 9696dfd4b55Sslatteng code = p[i] & BMASK; 970f92359bfSslatteng #ifdef DEBUGABLE 971f92359bfSslatteng if (dbg) { 972f92359bfSslatteng if (isprint(c+32)) 973f92359bfSslatteng fprintf(stderr,"%c %d\n", c+32, code); 974f92359bfSslatteng else 975f92359bfSslatteng fprintf(stderr,"%03o %d\n", c+32, code); 976f92359bfSslatteng } 977f92359bfSslatteng #endif 978f92359bfSslatteng outc(code); /* character is < 254 */ 979f92359bfSslatteng if (font != ofont) 980f92359bfSslatteng setfont(ofont); 9814da297a9Sslatteng lastw = ((pw[i]&077) * pstab[size] + dev.unitwidth/2) / dev.unitwidth; 982f92359bfSslatteng } 983f92359bfSslatteng 984f92359bfSslatteng 985f92359bfSslatteng 986f92359bfSslatteng setsize(n) /* set point size to n (internal) */ 987f92359bfSslatteng int n; 988f92359bfSslatteng { 989f92359bfSslatteng 990f92359bfSslatteng if (n == size) 991f92359bfSslatteng return; /* already there */ 9924da297a9Sslatteng if (vloadfont(font, pstab[n]) != -1) 993f92359bfSslatteng size = n; 994f92359bfSslatteng } 995f92359bfSslatteng 996f92359bfSslatteng t_fp(n, s, si) /* font position n now contains font s, intname si */ 9971c9df754Sslatteng int n; /* internal name is ignored */ 998f92359bfSslatteng char *s, *si; 999f92359bfSslatteng { 10004da297a9Sslatteng register int i; 1001f92359bfSslatteng 10024da297a9Sslatteng 10034da297a9Sslatteng /* first convert s to filename if possible */ 10044da297a9Sslatteng for (i = 0; fontmap[i].ffile != (char *) 0; i++) { 10054da297a9Sslatteng #ifdef DEBUGABLE 10064da297a9Sslatteng if(dbg>1)fprintf(stderr,"testing :%s:%s:\n",s,fontmap[i].fname); 10074da297a9Sslatteng #endif 10084da297a9Sslatteng if (strcmp(s, fontmap[i].fname) == 0) { 10094da297a9Sslatteng s = fontmap[i].ffile; 10104da297a9Sslatteng #ifdef DEBUGABLE 10114da297a9Sslatteng if(dbg)fprintf(stderr, "found :%s:\n",fontmap[i].ffile); 10124da297a9Sslatteng #endif 10134da297a9Sslatteng break; 10144da297a9Sslatteng } 10154da297a9Sslatteng } 10161c9df754Sslatteng fontname[n] = s; 1017cb97edc8Sslatteng for(i = 0;i <= NFONTS;i++) /* free the bits of that font */ 1018f92359bfSslatteng if (fontdes[i].fnum == n){ 1019f92359bfSslatteng nfree(fontdes[i].bits); 1020f92359bfSslatteng fontdes[i].fnum = -1; 1021f92359bfSslatteng } 1022f92359bfSslatteng } 1023f92359bfSslatteng 10244da297a9Sslatteng 1025f92359bfSslatteng setfont(n) /* set font to n */ 1026f92359bfSslatteng int n; 1027f92359bfSslatteng { 1028*69c7ec87Sslatteng if (n < 0 || n > nfonts) 1029ebd02298Sslatteng error(FATAL, "illegal font %d", n); 10304da297a9Sslatteng if (vloadfont(n,pstab[size]) != -1) 1031f92359bfSslatteng font = n; 1032f92359bfSslatteng } 1033f92359bfSslatteng 1034*69c7ec87Sslatteng 1035*69c7ec87Sslatteng setstip(n) /* set stipple font to n */ 1036*69c7ec87Sslatteng int n; 1037*69c7ec87Sslatteng { 1038*69c7ec87Sslatteng if (n < 1 || n > nstips) 1039*69c7ec87Sslatteng error(FATAL, "illegal stipple %d", n); 1040*69c7ec87Sslatteng stip = n; 1041*69c7ec87Sslatteng } 1042*69c7ec87Sslatteng 1043*69c7ec87Sslatteng 1044f92359bfSslatteng vloadfont(fnum, fsize) 1045f92359bfSslatteng register int fnum; 1046f92359bfSslatteng register int fsize; 1047f92359bfSslatteng { 1048f92359bfSslatteng register int i; 1049f92359bfSslatteng 1050f92359bfSslatteng fontwanted = 0; 1051f92359bfSslatteng if (fnum == cfnum && fsize == cpsize) 1052f92359bfSslatteng return(0); 1053f92359bfSslatteng for (i = 0; i < NFONTS; i++) { 1054f92359bfSslatteng if (fontdes[i].fnum == fnum && fontdes[i].psize == fsize) { 1055f92359bfSslatteng cfnum = fontdes[i].fnum; 1056f92359bfSslatteng cpsize = fontdes[i].psize; 1057f92359bfSslatteng dispatch = &fontdes[i].disp[0]; 1058f92359bfSslatteng bits = fontdes[i].bits; 1059f92359bfSslatteng cfont = i; 1060f92359bfSslatteng return (0); 1061f92359bfSslatteng } 1062f92359bfSslatteng } 1063f92359bfSslatteng /* this is a new font */ 10641c9df754Sslatteng if (fnum < 0 || fnum > NFONTS || fontname[fnum] == 0) { 1065f92359bfSslatteng fprintf(stderr, "Internal error: illegal font %d name %s size\n", 10661c9df754Sslatteng fontname[fnum], fnum, fsize); 1067f92359bfSslatteng return(-1); 1068f92359bfSslatteng } 1069f92359bfSslatteng /* Need to verify the existance of that font/size here*/ 1070f92359bfSslatteng nfontnum = fnum; 1071f92359bfSslatteng npsize = fsize; 1072f92359bfSslatteng fontwanted++; 1073f92359bfSslatteng return (0); 1074f92359bfSslatteng } 1075f92359bfSslatteng 1076f92359bfSslatteng 1077f92359bfSslatteng getfont() 1078f92359bfSslatteng { 10794da297a9Sslatteng register int fnum; 10804da297a9Sslatteng register int fsize; 10814da297a9Sslatteng register int fontd; 10824da297a9Sslatteng register int d; 10831c9df754Sslatteng register int sizehunt = size; 1084f92359bfSslatteng char cbuf[BUFSIZ]; 1085f92359bfSslatteng 1086f92359bfSslatteng fnum = nfontnum; 1087f92359bfSslatteng fsize = npsize; 10884da297a9Sslatteng /* try to open font file - if unsuccessful, hunt for */ 10894da297a9Sslatteng /* a file of same style, different size to substitute */ 10904da297a9Sslatteng d = -1; /* direction to look in pstab (smaller first) */ 10914da297a9Sslatteng do { 10921c9df754Sslatteng sprintf(cbuf, "%s/%s.%dr", bitdir, fontname[fnum], fsize); 1093f92359bfSslatteng fontd = open(cbuf, OPENREAD); 10944da297a9Sslatteng if (fontd == -1) { /* File wasn't found. Try another ps */ 10951c9df754Sslatteng sizehunt += d; 10961c9df754Sslatteng if (sizehunt < 0) { /* past beginning - look higher */ 10974da297a9Sslatteng d = 1; 10981c9df754Sslatteng sizehunt = size + 1; 10994da297a9Sslatteng } 11001c9df754Sslatteng if (sizehunt > nsizes) { /* past top - forget it */ 11014da297a9Sslatteng d = 0; 11024da297a9Sslatteng } else { 11031c9df754Sslatteng fsize = pstab[sizehunt]; 11044da297a9Sslatteng } 11054da297a9Sslatteng } 11064da297a9Sslatteng } while (fontd == -1 && d != 0); 11074da297a9Sslatteng 11084da297a9Sslatteng if (fontd == -1) { /* completely unsuccessful */ 1109f92359bfSslatteng perror(cbuf); 11104da297a9Sslatteng error(!FATAL,"fnum = %d, psize = %d, name = %s", 11111c9df754Sslatteng fnum, npsize, fontname[fnum]); 1112f92359bfSslatteng fontwanted = 0; 1113f92359bfSslatteng return (-1); 1114f92359bfSslatteng } 1115f92359bfSslatteng if (read(fontd, &header, sizeof (header)) != sizeof (header) 1116f92359bfSslatteng || header.magic != 0436) 1117f92359bfSslatteng fprintf(stderr, "%s: Bad font file", cbuf); 1118f92359bfSslatteng else { 1119f92359bfSslatteng cfont = relfont(); 1120f92359bfSslatteng if ((bits=nalloc(header.size+DSIZ+1,1))== NULL) 1121f92359bfSslatteng if ((bits=allpanic(header.size+DSIZ+1))== NULL) { 11221c9df754Sslatteng error(FATAL,"%s: ran out of memory", cbuf); 1123f92359bfSslatteng } 1124f92359bfSslatteng 1125f92359bfSslatteng /* 1126f92359bfSslatteng * have allocated one chunk of mem for font, dispatch. 1127f92359bfSslatteng * get the dispatch addr, align to word boundary. 1128f92359bfSslatteng */ 1129f92359bfSslatteng 1130f92359bfSslatteng d = (int) bits+header.size; 1131f92359bfSslatteng d += 1; 1132f92359bfSslatteng d &= ~1; 1133f92359bfSslatteng if (read (fontd, d, DSIZ) != DSIZ 1134f92359bfSslatteng || read (fontd, bits, header.size) != header.size) 1135f92359bfSslatteng fprintf(stderr, "bad font header"); 1136f92359bfSslatteng else { 1137f92359bfSslatteng close(fontd); 1138f92359bfSslatteng cfnum = fontdes[cfont].fnum = fnum; 1139f92359bfSslatteng cpsize = fontdes[cfont].psize = fsize; 1140f92359bfSslatteng fontdes [cfont].bits = bits; 1141f92359bfSslatteng fontdes [cfont].disp = (struct dispatch *) d; 1142f92359bfSslatteng dispatch = &fontdes[cfont].disp[0]; 1143f92359bfSslatteng fontwanted = 0; 1144f92359bfSslatteng return (0); 1145f92359bfSslatteng } 1146f92359bfSslatteng } 1147f92359bfSslatteng close(fontd); 1148f92359bfSslatteng fontwanted = 0; 1149f92359bfSslatteng return(-1); 1150f92359bfSslatteng } 1151f92359bfSslatteng 1152f92359bfSslatteng /* 1153f92359bfSslatteng * "release" a font position - find an empty one, if possible 1154f92359bfSslatteng */ 1155f92359bfSslatteng 1156f92359bfSslatteng relfont() 1157f92359bfSslatteng { 1158f92359bfSslatteng register int newfont; 1159f92359bfSslatteng 1160f92359bfSslatteng for (newfont = 0; newfont < NFONTS; newfont++) 1161cb97edc8Sslatteng if (fontdes [newfont].fnum == -1) 1162f92359bfSslatteng break; 1163cb97edc8Sslatteng if (fontdes [newfont].fnum != -1) { 1164f92359bfSslatteng nfree (fontdes [newfont].bits); 1165f92359bfSslatteng #ifdef DEBUGABLE 1166f92359bfSslatteng if (dbg) fprintf (stderr, "freeing position %d\n", newfont); 1167f92359bfSslatteng } else { 1168f92359bfSslatteng if (dbg) 1169f92359bfSslatteng fprintf (stderr, "taking, not freeing, position %d\n", newfont); 1170f92359bfSslatteng #endif 1171f92359bfSslatteng } 1172cb97edc8Sslatteng fontdes[newfont].fnum = -1; 1173f92359bfSslatteng return (newfont); 1174f92359bfSslatteng } 1175f92359bfSslatteng 1176f92359bfSslatteng char *allpanic (nbytes) 1177f92359bfSslatteng int nbytes; 1178f92359bfSslatteng { 1179f92359bfSslatteng register int i; 1180f92359bfSslatteng 1181f92359bfSslatteng for (i = 0; i <= NFONTS; i++) { 1182cb97edc8Sslatteng if (fontdes[i].fnum != -1) nfree(fontdes[i].bits); 1183cb97edc8Sslatteng fontdes[i].fnum = -1; 1184f92359bfSslatteng cfnum = cpsize = -1; 1185f92359bfSslatteng } 1186f92359bfSslatteng return(nalloc(nbytes,1)); 1187f92359bfSslatteng } 1188f92359bfSslatteng 1189f92359bfSslatteng int M[] = { 0xffffffff, 0xfefefefe, 0xfcfcfcfc, 0xf8f8f8f8, 1190f92359bfSslatteng 0xf0f0f0f0, 0xe0e0e0e0, 0xc0c0c0c0, 0x80808080, 0x0 }; 1191f92359bfSslatteng int N[] = { 0x00000000, 0x01010101, 0x03030303, 0x07070707, 1192f92359bfSslatteng 0x0f0f0f0f, 0x1f1f1f1f, 0x3f3f3f3f, 0x7f7f7f7f, 0xffffffff }; 1193f92359bfSslatteng int strim[] = { 0xffffffff, 0xffffff00, 0xffff0000, 0xff000000, 0 }; 1194f92359bfSslatteng 1195f92359bfSslatteng outc(code) 1196f92359bfSslatteng int code; /* character to print */ 1197f92359bfSslatteng { 1198f92359bfSslatteng register struct dispatch *dis; /* ptr to character font record */ 1199f92359bfSslatteng register char *addr; /* addr of font data */ 1200f92359bfSslatteng int llen; /* length of each font line */ 1201f92359bfSslatteng int nlines; /* number of font lines */ 1202f92359bfSslatteng register char *scanp; /* ptr to output buffer */ 1203f92359bfSslatteng int scanp_inc; /* increment to start of next buffer */ 1204f92359bfSslatteng int offset; /* bit offset to start of font data */ 12054da297a9Sslatteng register int i; /* loop counter */ 1206f92359bfSslatteng register int count; /* font data ptr */ 1207f92359bfSslatteng register unsigned fontdata; /* font data temporary */ 1208f92359bfSslatteng register int off8; /* offset + 8 */ 1209f92359bfSslatteng 1210f92359bfSslatteng if (fontwanted) 1211f92359bfSslatteng getfont(); 1212f92359bfSslatteng dis = dispatch + code; 1213f92359bfSslatteng if (dis->nbytes) { 1214f92359bfSslatteng addr = bits + dis->addr; 12151a4ecc79Sslatteng llen = (dis->up + dis->down + 7) >> 3; 12161a4ecc79Sslatteng nlines = dis->right + dis->left; 1217cb97edc8Sslatteng scanp = fill + (hpos + 1 - dis->left) * BYTES_PER_LINE 1218cb97edc8Sslatteng - (1 + ((dis->down + vpos - 1) >> 3)); 1219cb97edc8Sslatteng if (scanp < fill) 1220cb97edc8Sslatteng scanp += BUFFER_SIZE; 1221f92359bfSslatteng scanp_inc = BYTES_PER_LINE - llen; 1222cb97edc8Sslatteng off8 = ((dis->down + vpos - 1) &07); 12231a4ecc79Sslatteng offset = off8 - 8; 1224f92359bfSslatteng for (i = 0; i < nlines; i++) { 1225cb97edc8Sslatteng if (scanp >= fill + BUFFER_SIZE) 12261c9df754Sslatteng scanp -= BUFFER_SIZE; 1227f92359bfSslatteng count = llen; 1228cb97edc8Sslatteng if (scanp + count < fill + BUFFER_SIZE) { 1229f92359bfSslatteng do { 1230f92359bfSslatteng fontdata = *(unsigned *)addr; 1231f92359bfSslatteng addr += 4; 1232f92359bfSslatteng if (count < 4) 1233f92359bfSslatteng fontdata &= ~strim[count]; 1234f92359bfSslatteng *(unsigned*)scanp |=(fontdata << offset) & ~M[off8]; 1235f92359bfSslatteng scanp++; 1236f92359bfSslatteng *(unsigned*)scanp |=(fontdata << off8) & ~N[off8]; 1237f92359bfSslatteng scanp += 3; 1238f92359bfSslatteng count -= 4; 1239f92359bfSslatteng } while (count > 0); 1240f92359bfSslatteng } 1241f92359bfSslatteng scanp += scanp_inc+count; 1242f92359bfSslatteng addr += count; 1243f92359bfSslatteng } 1244f92359bfSslatteng return; 1245f92359bfSslatteng } 1246f92359bfSslatteng return; 1247f92359bfSslatteng } 1248f92359bfSslatteng 1249*69c7ec87Sslatteng 1250*69c7ec87Sslatteng /*----------------------------------------------------------------------------* 1251*69c7ec87Sslatteng | Routine: setfill(stipple_number) 1252*69c7ec87Sslatteng | 1253*69c7ec87Sslatteng | Results: sets the fill-pattern pointers (stip_disp and 1254*69c7ec87Sslatteng | stip_bits) for a particular stipple. Takes stipple 1255*69c7ec87Sslatteng | font from current "stip" number. 1256*69c7ec87Sslatteng *----------------------------------------------------------------------------*/ 1257*69c7ec87Sslatteng 1258*69c7ec87Sslatteng setfill(number) 1259*69c7ec87Sslatteng int number; 1260*69c7ec87Sslatteng { 1261*69c7ec87Sslatteng int curfont; /* places to save current text font */ 1262*69c7ec87Sslatteng int cursize; 1263*69c7ec87Sslatteng 1264*69c7ec87Sslatteng /* set global stipmem for polygon */ 1265*69c7ec87Sslatteng if (number < 0 || number >= DISPATCHSIZE) 1266*69c7ec87Sslatteng stipmem = 0; 1267*69c7ec87Sslatteng else 1268*69c7ec87Sslatteng stipmem = number; 1269*69c7ec87Sslatteng 1270*69c7ec87Sslatteng curfont = cfnum; /* get pointers to */ 1271*69c7ec87Sslatteng cursize = cpsize; /* the inuse font */ 1272*69c7ec87Sslatteng if (vloadfont(nfonts + stip, 0)) { 1273*69c7ec87Sslatteng stip_disp = (struct dispatch *) NULL; /* stipple not here */ 1274*69c7ec87Sslatteng } else { 1275*69c7ec87Sslatteng if (fontwanted) { 1276*69c7ec87Sslatteng if (getfont()) { 1277*69c7ec87Sslatteng stip_disp = (struct dispatch *) NULL; 1278*69c7ec87Sslatteng } else { 1279*69c7ec87Sslatteng stip_disp = dispatch; /* save for polygon routine */ 1280*69c7ec87Sslatteng stip_bits = bits; 1281*69c7ec87Sslatteng } 1282*69c7ec87Sslatteng } else { 1283*69c7ec87Sslatteng stip_disp = dispatch; /* save for polygon routine */ 1284*69c7ec87Sslatteng stip_bits = bits; 1285*69c7ec87Sslatteng } 1286*69c7ec87Sslatteng } 1287*69c7ec87Sslatteng vloadfont(curfont, cursize); 1288*69c7ec87Sslatteng } 1289*69c7ec87Sslatteng 1290*69c7ec87Sslatteng 1291f92359bfSslatteng slop_lines(nlines) 1292f92359bfSslatteng int nlines; 1293f92359bfSslatteng 1294f92359bfSslatteng /* Output "nlines" lines from the buffer, and clear that section of the */ 1295cb97edc8Sslatteng /* buffer. Also updates the pointers to the emptying buffer */ 1296f92359bfSslatteng 1297f92359bfSslatteng { 1298f92359bfSslatteng unsigned usize; 1299f92359bfSslatteng 1300f92359bfSslatteng usize = BYTES_PER_LINE * nlines; 1301cb97edc8Sslatteng vwrite(elevel, usize); 1302cb97edc8Sslatteng vclear(elevel, usize); 1303cb97edc8Sslatteng elevel += usize; 1304cb97edc8Sslatteng emptypos += nlines; 1305f92359bfSslatteng } 1306f92359bfSslatteng 13074da297a9Sslatteng vwrite(buf,usize) 1308f92359bfSslatteng char *buf; 1309f92359bfSslatteng unsigned usize; 1310f92359bfSslatteng { 1311f92359bfSslatteng register int tsize = 0; 1312f92359bfSslatteng 1313f92359bfSslatteng while (usize){ 1314f92359bfSslatteng buf += tsize; 1315f92359bfSslatteng tsize = usize > MAXWRIT ? MAXWRIT : usize; 1316f92359bfSslatteng #ifdef DEBUGABLE 1317f92359bfSslatteng if (dbg)fprintf(stderr,"buf = %d size = %d\n",buf,tsize); 1318f92359bfSslatteng #endif 1319f92359bfSslatteng if ((tsize = write(OUTFILE, buf, tsize)) < 0) { 1320ebd02298Sslatteng perror("dvar: write failed"); 1321f92359bfSslatteng exit(RESTART); 1322f92359bfSslatteng } 1323f92359bfSslatteng usize -= tsize; 1324f92359bfSslatteng } 1325f92359bfSslatteng } 1326f92359bfSslatteng 1327f92359bfSslatteng vclear (ptr, nbytes) 1328f92359bfSslatteng char *ptr; 1329f92359bfSslatteng unsigned nbytes; 1330f92359bfSslatteng { 1331f92359bfSslatteng register tsize = 0; 1332f92359bfSslatteng 1333f92359bfSslatteng while (nbytes){ 1334f92359bfSslatteng if ((unsigned)(16*1024) < nbytes) { 1335f92359bfSslatteng tsize = 16 * 1024; 1336f92359bfSslatteng } else 1337f92359bfSslatteng tsize = nbytes; 1338f92359bfSslatteng nbytes -= tsize; 1339f92359bfSslatteng #ifdef DEBUGABLE 1340f92359bfSslatteng if (dbg) fprintf(stderr,"clearing ptr = %d size = %d\n",ptr,tsize); 1341f92359bfSslatteng #endif 1342f92359bfSslatteng clear(ptr,tsize); 1343f92359bfSslatteng ptr += tsize; 1344f92359bfSslatteng } 1345f92359bfSslatteng } 1346f92359bfSslatteng 1347f92359bfSslatteng /*ARGSUSED*/ 1348f92359bfSslatteng clear(lp, nbytes) 1349f92359bfSslatteng int *lp; 1350f92359bfSslatteng int nbytes; 1351f92359bfSslatteng { 1352f92359bfSslatteng asm("movc5 $0,(sp),$0,8(ap),*4(ap)"); 1353f92359bfSslatteng } 1354f92359bfSslatteng 1355f92359bfSslatteng char * 1356f92359bfSslatteng nalloc(i, j) 1357f92359bfSslatteng int i, j; 1358f92359bfSslatteng { 1359f92359bfSslatteng register char *cp; 1360f92359bfSslatteng 1361f92359bfSslatteng cp = calloc(i, j); 1362f92359bfSslatteng #ifdef DEBUGABLE 1363f92359bfSslatteng if (dbg) fprintf(stderr, "allocated %d bytes at %x\n", i * j, cp); 1364f92359bfSslatteng #endif 1365f92359bfSslatteng return(cp); 1366f92359bfSslatteng } 1367f92359bfSslatteng 1368f92359bfSslatteng nfree(cp) 1369f92359bfSslatteng char *cp; 1370f92359bfSslatteng { 1371f92359bfSslatteng #ifdef DEBUGABLE 1372f92359bfSslatteng if (dbg) fprintf(stderr, "freeing at %x\n", cp); 1373f92359bfSslatteng #endif 1374f92359bfSslatteng free(cp); 1375f92359bfSslatteng } 1376f92359bfSslatteng 1377f92359bfSslatteng 1378f92359bfSslatteng /* 1379f92359bfSslatteng * Points should be in the range 0 <= x < RASTER_LENGTH, 0 <= y < NLINES. 1380f92359bfSslatteng * The origin is the top left-hand corner with increasing x towards the 13814da297a9Sslatteng * right and increasing y going down. X and Y should be sent as (0,0) being 13824da297a9Sslatteng * at the bottom left. The output array is NLINES x BYTES_PER_LINE pixels. 1383f92359bfSslatteng */ 1384f92359bfSslatteng point(x, y) 13851a4ecc79Sslatteng register int x; 13861a4ecc79Sslatteng register int y; 1387f92359bfSslatteng { 1388*69c7ec87Sslatteng if ((unsigned)(y=(RASTER_LENGTH-1)-y)<RASTER_LENGTH && (unsigned)x<NLINES) { 1389cb97edc8Sslatteng *(fill + x * BYTES_PER_LINE + (y >> 3)) |= 1 << (7 - (y & 07)); 1390f92359bfSslatteng } 1391f92359bfSslatteng } 1392*69c7ec87Sslatteng 1393*69c7ec87Sslatteng 1394*69c7ec87Sslatteng #define pv(x) ((polyvector *)x) 1395*69c7ec87Sslatteng 1396*69c7ec87Sslatteng typedef struct poly { 1397*69c7ec87Sslatteng struct poly *next; /* doublely-linked lists of vectors */ 1398*69c7ec87Sslatteng struct poly *prev; 1399*69c7ec87Sslatteng int param; /* bressenham line algorithm parameter */ 1400*69c7ec87Sslatteng short dy; /* delta-y for calculating line */ 1401*69c7ec87Sslatteng short dx; /* delta-x for calculating line */ 1402*69c7ec87Sslatteng short curry; /* current y in this vector */ 1403*69c7ec87Sslatteng short endx; /* where vector ends */ 1404*69c7ec87Sslatteng } polyvector; 1405*69c7ec87Sslatteng 1406*69c7ec87Sslatteng 1407*69c7ec87Sslatteng /*----------------------------------------------------------------------------* 1408*69c7ec87Sslatteng | Routine: polygon ( x_coordinates, y_coordinates, num_of_points ) 1409*69c7ec87Sslatteng | 1410*69c7ec87Sslatteng | Results: draws a polygon starting at (x[1], y[1]) going through 1411*69c7ec87Sslatteng | each of (x_coordinates, y_coordinates), and fills it 1412*69c7ec87Sslatteng | with a stipple pattern from stip_disp and stip_bits, 1413*69c7ec87Sslatteng | which point to the stipple font. The pattern is defined 1414*69c7ec87Sslatteng | by "stip" and "stipmem". 1415*69c7ec87Sslatteng | 1416*69c7ec87Sslatteng | The scan-line algorithm implemented scans from left to 1417*69c7ec87Sslatteng | right (low x to high x). It also scans, within a line, 1418*69c7ec87Sslatteng | from bottom to top (high y to low y). 1419*69c7ec87Sslatteng | 1420*69c7ec87Sslatteng | polygons are clipped to page boundary. 1421*69c7ec87Sslatteng | 1422*69c7ec87Sslatteng | Bugs: stipple pattern MUST be a power of two bytes "wide" and 1423*69c7ec87Sslatteng | square. The square restriction comes from the fact that 1424*69c7ec87Sslatteng | the varian and versatec are respectively rotated. 1425*69c7ec87Sslatteng *----------------------------------------------------------------------------*/ 1426*69c7ec87Sslatteng 1427*69c7ec87Sslatteng polygon(x, y, npts) 1428*69c7ec87Sslatteng int x[]; 1429*69c7ec87Sslatteng int y[]; 1430*69c7ec87Sslatteng int npts; 1431*69c7ec87Sslatteng { 1432*69c7ec87Sslatteng int nextx; /* at what x value the next vector starts */ 1433*69c7ec87Sslatteng int maxx, minx, maxy, miny; /* finds bounds of polygon */ 1434*69c7ec87Sslatteng polyvector *activehead; /* doing fill, is active edge list */ 1435*69c7ec87Sslatteng polyvector *waitinghead; /* edges waiting to be active */ 1436*69c7ec87Sslatteng register polyvector *vectptr; /* random vector */ 1437*69c7ec87Sslatteng register int i; /* random register */ 1438*69c7ec87Sslatteng 1439*69c7ec87Sslatteng char *topstipple; /* points to beginning of stipple glyph */ 1440*69c7ec87Sslatteng char *leftstipple; /* points to beginning of line of stipple */ 1441*69c7ec87Sslatteng char *bottompage; /* points to the edge of a raster line */ 1442*69c7ec87Sslatteng int bytewidth; /* glyph width in bytes */ 1443*69c7ec87Sslatteng int mask; /* mask to pick off pixel index into stipple */ 1444*69c7ec87Sslatteng int bytemask; /* mask to pick off byte index into stipple */ 1445*69c7ec87Sslatteng 1446*69c7ec87Sslatteng 1447*69c7ec87Sslatteng if (bordered) { 1448*69c7ec87Sslatteng for (i = 1; i < npts; i++) /* first draw outlines */ 1449*69c7ec87Sslatteng HGtline(x[i], y[i], x[i+1], y[i+1]); 1450*69c7ec87Sslatteng } 1451*69c7ec87Sslatteng 1452*69c7ec87Sslatteng /* if no stipple, don't fill */ 1453*69c7ec87Sslatteng if (stip_disp == (struct dispatch *) NULL || stip_bits == (char *) NULL) 1454*69c7ec87Sslatteng return; 1455*69c7ec87Sslatteng 1456*69c7ec87Sslatteng stip_disp += stipmem; /* set up parameters for */ 1457*69c7ec87Sslatteng if (!stip_disp->nbytes) { /* tiling with the stipple */ 1458*69c7ec87Sslatteng #ifdef DEBUGABLE 1459*69c7ec87Sslatteng error(!FATAL, "member not found: member %d, stipple %d", stipmem, stip); 1460*69c7ec87Sslatteng #endif 1461*69c7ec87Sslatteng return; 1462*69c7ec87Sslatteng } 1463*69c7ec87Sslatteng topstipple = stip_bits + stip_disp->addr; 1464*69c7ec87Sslatteng bytewidth = stip_disp->up + stip_disp->down; 1465*69c7ec87Sslatteng for (i = 1 << 30; i && i != bytewidth; i = i >> 1) 1466*69c7ec87Sslatteng ; 1467*69c7ec87Sslatteng if (i==0 || bytewidth<8 || bytewidth != stip_disp->right+stip_disp->left) { 1468*69c7ec87Sslatteng error(!FATAL, "invalid stipple: number %d, member %d", stip, stipmem); 1469*69c7ec87Sslatteng return; 1470*69c7ec87Sslatteng } 1471*69c7ec87Sslatteng mask = bytewidth - 1; 1472*69c7ec87Sslatteng bytewidth = bytewidth >> 3; 1473*69c7ec87Sslatteng bytemask = bytewidth - 1; 1474*69c7ec87Sslatteng 1475*69c7ec87Sslatteng /* allocate space for raster-fill algorithm*/ 1476*69c7ec87Sslatteng if ((vectptr = pv( nalloc(sizeof(polyvector), npts + 6) )) == NULL) { 1477*69c7ec87Sslatteng error(!FATAL, "unable to allocate space for polygon"); 1478*69c7ec87Sslatteng return; 1479*69c7ec87Sslatteng } 1480*69c7ec87Sslatteng #ifdef DEBUGABLE 1481*69c7ec87Sslatteng if (dbg) fprintf(stderr, "polygon, %d points\n", npts); 1482*69c7ec87Sslatteng #endif 1483*69c7ec87Sslatteng 1484*69c7ec87Sslatteng waitinghead = vectptr; 1485*69c7ec87Sslatteng minx = maxx = x[1]; 1486*69c7ec87Sslatteng miny = maxy = y[1]; 1487*69c7ec87Sslatteng (vectptr++)->prev = pv( NULL ); /* put dummy entry at start */ 1488*69c7ec87Sslatteng waitinghead->next = vectptr; 1489*69c7ec87Sslatteng vectptr->prev = waitinghead; 1490*69c7ec87Sslatteng i = 1; /* starting point of coords */ 1491*69c7ec87Sslatteng if (y[1] != y[npts] || x[1] != x[npts]) { 1492*69c7ec87Sslatteng y[0] = y[npts]; /* close polygon if it's not */ 1493*69c7ec87Sslatteng x[0] = x[npts]; 1494*69c7ec87Sslatteng i = 0; 1495*69c7ec87Sslatteng } 1496*69c7ec87Sslatteng while (i < npts) { /* set up the vectors */ 1497*69c7ec87Sslatteng register int j; /* indexes to work off of */ 1498*69c7ec87Sslatteng register int k; 1499*69c7ec87Sslatteng 1500*69c7ec87Sslatteng if (miny > y[i]) miny = y[i]; /* remember limits */ 1501*69c7ec87Sslatteng else if (maxy < y[i]) maxy = y[i]; 1502*69c7ec87Sslatteng if (maxx < x[i]) maxx = x[i]; 1503*69c7ec87Sslatteng else if (minx > x[i]) minx = x[i]; 1504*69c7ec87Sslatteng 1505*69c7ec87Sslatteng j = i; /* j "points" to the higher (lesser) point */ 1506*69c7ec87Sslatteng k = ++i; 1507*69c7ec87Sslatteng if (x[j] == x[k]) /* ignore vertical lines */ 1508*69c7ec87Sslatteng continue; 1509*69c7ec87Sslatteng 1510*69c7ec87Sslatteng if (x[j] > x[k]) { 1511*69c7ec87Sslatteng j++; 1512*69c7ec87Sslatteng k--; 1513*69c7ec87Sslatteng } 1514*69c7ec87Sslatteng vectptr->next = vectptr + 1; 1515*69c7ec87Sslatteng vectptr->param = x[j]; /* starting point of vector */ 1516*69c7ec87Sslatteng vectptr->dy = y[k] - y[j]; /* line-calculating parameters */ 1517*69c7ec87Sslatteng vectptr->dx = x[k] - x[j]; 1518*69c7ec87Sslatteng vectptr->curry = y[j]; /* starting point */ 1519*69c7ec87Sslatteng (vectptr++)->endx = x[k]; /* ending point */ 1520*69c7ec87Sslatteng vectptr->prev = vectptr - 1; 1521*69c7ec87Sslatteng } 1522*69c7ec87Sslatteng /* set now because we didn't know minx before */ 1523*69c7ec87Sslatteng leftstipple = topstipple + (minx & mask) * bytewidth; 1524*69c7ec87Sslatteng bottompage = fill + minx * BYTES_PER_LINE; 1525*69c7ec87Sslatteng waitinghead->param = minx - 1; 1526*69c7ec87Sslatteng /* if no useable vectors, quit */ 1527*69c7ec87Sslatteng if (vectptr == waitinghead + 1) 1528*69c7ec87Sslatteng goto leavepoly; 1529*69c7ec87Sslatteng 1530*69c7ec87Sslatteng vectptr->param = maxx + 1; /* dummy entry at end, too */ 1531*69c7ec87Sslatteng vectptr->next = pv( NULL ); 1532*69c7ec87Sslatteng 1533*69c7ec87Sslatteng activehead = ++vectptr; /* two dummy entries for active list */ 1534*69c7ec87Sslatteng vectptr->curry = maxy + 1; /* head */ 1535*69c7ec87Sslatteng vectptr->endx = maxx + 1; 1536*69c7ec87Sslatteng vectptr->param = vectptr->dx = vectptr->dy = 0; 1537*69c7ec87Sslatteng activehead->next = ++vectptr; 1538*69c7ec87Sslatteng activehead->prev = vectptr; 1539*69c7ec87Sslatteng 1540*69c7ec87Sslatteng vectptr->prev = activehead; /* tail */ 1541*69c7ec87Sslatteng vectptr->next = activehead; 1542*69c7ec87Sslatteng vectptr->curry = miny - 1; 1543*69c7ec87Sslatteng vectptr->endx = maxx + 1; 1544*69c7ec87Sslatteng vectptr->param = vectptr->dx = vectptr->dy = 0; 1545*69c7ec87Sslatteng 1546*69c7ec87Sslatteng 1547*69c7ec87Sslatteng /* main loop -- gets vectors off the waiting list, */ 1548*69c7ec87Sslatteng /* then displays spans while updating the vectors in */ 1549*69c7ec87Sslatteng /* the active list */ 1550*69c7ec87Sslatteng while (minx <= maxx) { 1551*69c7ec87Sslatteng i = maxx + 1; /* this is the NEXT time to get a new vector */ 1552*69c7ec87Sslatteng for (vectptr = waitinghead->next; vectptr != pv( NULL ); ) { 1553*69c7ec87Sslatteng if (minx == vectptr->param) { 1554*69c7ec87Sslatteng /* the entry in waiting list (vectptr) is */ 1555*69c7ec87Sslatteng /* ready to go into active list. Need to */ 1556*69c7ec87Sslatteng /* convert some vector stuff and sort the */ 1557*69c7ec87Sslatteng /* entry into the list. */ 1558*69c7ec87Sslatteng register polyvector *p; /* random vector pointers */ 1559*69c7ec87Sslatteng register polyvector *v; 1560*69c7ec87Sslatteng 1561*69c7ec87Sslatteng /* convert this */ 1562*69c7ec87Sslatteng if (vectptr->dy < 0) /* entry to active */ 1563*69c7ec87Sslatteng vectptr->param = (vectptr->dy >> 1) - (vectptr->dx >> 1); 1564*69c7ec87Sslatteng else 1565*69c7ec87Sslatteng vectptr->param = -((vectptr->dx >> 1) + (vectptr->dy >> 1)); 1566*69c7ec87Sslatteng 1567*69c7ec87Sslatteng p = vectptr; /* remove from the */ 1568*69c7ec87Sslatteng vectptr = vectptr->next; /* waiting list */ 1569*69c7ec87Sslatteng vectptr->prev = p->prev; 1570*69c7ec87Sslatteng p->prev->next = vectptr; 1571*69c7ec87Sslatteng /* find where it goes */ 1572*69c7ec87Sslatteng /* in the active list */ 1573*69c7ec87Sslatteng /* (sorted greatest first) */ 1574*69c7ec87Sslatteng for (v = activehead->next; v->curry > p->curry; v = v->next) 1575*69c7ec87Sslatteng ; 1576*69c7ec87Sslatteng p->next = v; /* insert into active list */ 1577*69c7ec87Sslatteng p->prev = v->prev; /* before the one it stopped on */ 1578*69c7ec87Sslatteng v->prev = p; 1579*69c7ec87Sslatteng p->prev->next = p; 1580*69c7ec87Sslatteng } else { 1581*69c7ec87Sslatteng if (i > vectptr->param) { 1582*69c7ec87Sslatteng i = vectptr->param; 1583*69c7ec87Sslatteng } 1584*69c7ec87Sslatteng vectptr = vectptr->next; 1585*69c7ec87Sslatteng } 1586*69c7ec87Sslatteng } 1587*69c7ec87Sslatteng nextx = i; 1588*69c7ec87Sslatteng 1589*69c7ec87Sslatteng /* print the polygon while there */ 1590*69c7ec87Sslatteng /* are no more vectors to add */ 1591*69c7ec87Sslatteng while (minx < nextx) { 1592*69c7ec87Sslatteng /* remove any finished vectors */ 1593*69c7ec87Sslatteng vectptr = activehead->next; 1594*69c7ec87Sslatteng do { 1595*69c7ec87Sslatteng if (vectptr->endx <= minx) { 1596*69c7ec87Sslatteng vectptr->prev->next = vectptr->next; 1597*69c7ec87Sslatteng vectptr->next->prev = vectptr->prev; 1598*69c7ec87Sslatteng } 1599*69c7ec87Sslatteng } while ((vectptr = vectptr->next) != activehead); 1600*69c7ec87Sslatteng 1601*69c7ec87Sslatteng /* draw the span */ 1602*69c7ec87Sslatteng if (((unsigned) minx) < NLINES) { 1603*69c7ec87Sslatteng vectptr = activehead->next; 1604*69c7ec87Sslatteng while (vectptr->next != activehead) { 1605*69c7ec87Sslatteng register int start; /* get the beginning */ 1606*69c7ec87Sslatteng register int length; /* and the end of span */ 1607*69c7ec87Sslatteng register char *glyph; 1608*69c7ec87Sslatteng register char *raster; 1609*69c7ec87Sslatteng 1610*69c7ec87Sslatteng start = (RASTER_LENGTH - 1) - vectptr->curry; 1611*69c7ec87Sslatteng vectptr = vectptr->next; 1612*69c7ec87Sslatteng length = RASTER_LENGTH - vectptr->curry; 1613*69c7ec87Sslatteng vectptr = vectptr->next; 1614*69c7ec87Sslatteng 1615*69c7ec87Sslatteng /* bound the polygon to the page */ 1616*69c7ec87Sslatteng if (start >= RASTER_LENGTH) 1617*69c7ec87Sslatteng break; 1618*69c7ec87Sslatteng if (start < 0) start = 0; 1619*69c7ec87Sslatteng if (length > RASTER_LENGTH) length = RASTER_LENGTH; 1620*69c7ec87Sslatteng length -= start; /* length is in pixels */ 1621*69c7ec87Sslatteng 1622*69c7ec87Sslatteng i = start & 7; 1623*69c7ec87Sslatteng start = start >> 3; /* start is in bytes */ 1624*69c7ec87Sslatteng raster = bottompage + start; 1625*69c7ec87Sslatteng glyph = leftstipple + (start & bytemask); 1626*69c7ec87Sslatteng 1627*69c7ec87Sslatteng if (i) { /* do any piece of byte */ 1628*69c7ec87Sslatteng register char data; /* that hangs on the front */ 1629*69c7ec87Sslatteng 1630*69c7ec87Sslatteng data = (*(glyph++)) & (0x7f >> --i); 1631*69c7ec87Sslatteng length -= 7 - i; 1632*69c7ec87Sslatteng if (length < 0) { /* less than one byte wide? */ 1633*69c7ec87Sslatteng data &= 0xff << -length; 1634*69c7ec87Sslatteng length = 0; /* force clean stoppage */ 1635*69c7ec87Sslatteng } 1636*69c7ec87Sslatteng *(raster++) |= data; 1637*69c7ec87Sslatteng /* update glyph ptr after first byte */ 1638*69c7ec87Sslatteng if (!(++start & bytemask)) 1639*69c7ec87Sslatteng glyph = leftstipple; 1640*69c7ec87Sslatteng } 1641*69c7ec87Sslatteng /* fill the line of raster */ 1642*69c7ec87Sslatteng while ((length -= 8) >= 0) { 1643*69c7ec87Sslatteng *(raster++) |= *(glyph++); 1644*69c7ec87Sslatteng if (!(++start & bytemask)) 1645*69c7ec87Sslatteng glyph = leftstipple; 1646*69c7ec87Sslatteng } 1647*69c7ec87Sslatteng if (length & 7) { /* add any part hanging off the end */ 1648*69c7ec87Sslatteng *raster |= (*glyph) & (0xff << -length); 1649*69c7ec87Sslatteng } 1650*69c7ec87Sslatteng } 1651*69c7ec87Sslatteng } 1652*69c7ec87Sslatteng 1653*69c7ec87Sslatteng #ifdef DEBUGABLE 1654*69c7ec87Sslatteng if (dbg) { 1655*69c7ec87Sslatteng vectptr = activehead; 1656*69c7ec87Sslatteng do { 1657*69c7ec87Sslatteng fprintf (stderr, "%d ", vectptr->curry); 1658*69c7ec87Sslatteng vectptr = vectptr->next; 1659*69c7ec87Sslatteng } while (vectptr != activehead); 1660*69c7ec87Sslatteng } 1661*69c7ec87Sslatteng #endif 1662*69c7ec87Sslatteng /* update the vectors */ 1663*69c7ec87Sslatteng vectptr = activehead->next; 1664*69c7ec87Sslatteng do { 1665*69c7ec87Sslatteng if (vectptr->dy > 0) { 1666*69c7ec87Sslatteng while (vectptr->param >= 0) { 1667*69c7ec87Sslatteng vectptr->param -= vectptr->dx; 1668*69c7ec87Sslatteng vectptr->curry++; 1669*69c7ec87Sslatteng } 1670*69c7ec87Sslatteng vectptr->param += vectptr->dy; 1671*69c7ec87Sslatteng } else if (vectptr->dy < 0) { 1672*69c7ec87Sslatteng while (vectptr->param >= 0) { 1673*69c7ec87Sslatteng vectptr->param -= vectptr->dx; 1674*69c7ec87Sslatteng vectptr->curry--; 1675*69c7ec87Sslatteng } 1676*69c7ec87Sslatteng vectptr->param -= vectptr->dy; 1677*69c7ec87Sslatteng } 1678*69c7ec87Sslatteng /* must sort the vectors if updates */ 1679*69c7ec87Sslatteng /* caused them to cross */ 1680*69c7ec87Sslatteng /* also move to next vector here */ 1681*69c7ec87Sslatteng if (vectptr->curry > vectptr->prev->curry) { 1682*69c7ec87Sslatteng register polyvector *v; /* vector to move */ 1683*69c7ec87Sslatteng register polyvector *p; /* vector to put it after */ 1684*69c7ec87Sslatteng 1685*69c7ec87Sslatteng v = vectptr; 1686*69c7ec87Sslatteng p = v->prev; 1687*69c7ec87Sslatteng while (v->curry > p->curry) /* find the */ 1688*69c7ec87Sslatteng p = p->prev; /* right vector */ 1689*69c7ec87Sslatteng 1690*69c7ec87Sslatteng vectptr = vectptr->next; /* remove from spot */ 1691*69c7ec87Sslatteng vectptr->prev = v->prev; 1692*69c7ec87Sslatteng v->prev->next = vectptr; 1693*69c7ec87Sslatteng 1694*69c7ec87Sslatteng v->prev = p; /* put in new spot */ 1695*69c7ec87Sslatteng v->next = p->next; 1696*69c7ec87Sslatteng p->next = v; 1697*69c7ec87Sslatteng v->next->prev = v; 1698*69c7ec87Sslatteng } else { 1699*69c7ec87Sslatteng vectptr = vectptr->next; 1700*69c7ec87Sslatteng } 1701*69c7ec87Sslatteng } while (vectptr != activehead); 1702*69c7ec87Sslatteng #ifdef DEBUGABLE 1703*69c7ec87Sslatteng if (dbg) fprintf(stderr, "line done\n"); 1704*69c7ec87Sslatteng #endif 1705*69c7ec87Sslatteng 1706*69c7ec87Sslatteng if (++minx & mask) { 1707*69c7ec87Sslatteng leftstipple += bytewidth; 1708*69c7ec87Sslatteng } else { 1709*69c7ec87Sslatteng leftstipple = topstipple; 1710*69c7ec87Sslatteng } 1711*69c7ec87Sslatteng bottompage += BYTES_PER_LINE; 1712*69c7ec87Sslatteng } /* while (minx < nextx) */ 1713*69c7ec87Sslatteng } /* while (minx <= maxx) */ 1714*69c7ec87Sslatteng 1715*69c7ec87Sslatteng leavepoly: 1716*69c7ec87Sslatteng nfree(waitinghead); 1717*69c7ec87Sslatteng } /* polygon function */ 1718