1*1c9df754Sslatteng /* dvar.c 1.6 83/10/06 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 20f92359bfSslatteng cx ascii character x 21f92359bfSslatteng Cxyz funny char \(xyz. terminated by white space 22f92359bfSslatteng Hn go to absolute horizontal position n 23f92359bfSslatteng Vn go to absolute vertical position n (down is positive) 24f92359bfSslatteng hn go n units horizontally (relative) 25f92359bfSslatteng vn ditto vertically 26f92359bfSslatteng nnc move right nn, then print c (exactly 2 digits!) 27f92359bfSslatteng (this wart is an optimization that shrinks output file size 28f92359bfSslatteng about 35% and run-time about 15% while preserving ascii-ness) 29f92359bfSslatteng p new page begins -- set v to 0 30f92359bfSslatteng nb a end of line (information only -- no action needed) 31f92359bfSslatteng b = space before line, a = after 32f92359bfSslatteng w paddable word space -- no action needed 33f92359bfSslatteng 34f92359bfSslatteng Dt ..\n draw operation 't': 35f92359bfSslatteng Dl x y line from here by x,y 36f92359bfSslatteng Dc d circle of diameter d with left side here 37f92359bfSslatteng De x y ellipse of axes x,y with left side here 38f92359bfSslatteng Da x y r arc counter-clockwise by x,y of radius r 39f92359bfSslatteng D~ x y x y ... B-spline curve by x,y then x,y ... 40f92359bfSslatteng 41f92359bfSslatteng x ..\n device control functions: 42f92359bfSslatteng x i init 43f92359bfSslatteng x T s name of device is s 44f92359bfSslatteng x r n h v resolution is n/inch h = min horizontal motion, v = min vert 45f92359bfSslatteng x p pause (can restart) 46f92359bfSslatteng x s stop -- done for ever 47f92359bfSslatteng x t generate trailer 48f92359bfSslatteng x f n s font position n contains font s 49f92359bfSslatteng x H n set character height to n 50f92359bfSslatteng x S n set slant to N 51f92359bfSslatteng 52f92359bfSslatteng Subcommands like "i" are often spelled out like "init". 53f92359bfSslatteng 54f92359bfSslatteng *******************************************************************************/ 55f92359bfSslatteng 56f92359bfSslatteng 57f92359bfSslatteng #include <stdio.h> 58f92359bfSslatteng #include <ctype.h> 59f92359bfSslatteng #include <sys/vcmd.h> 60f92359bfSslatteng #include "dev.h" 61f92359bfSslatteng 62f92359bfSslatteng 63*1c9df754Sslatteng /* #define DEBUGABLE /* No, not debugable... */ 64*1c9df754Sslatteng #define DRIVER /* Yes, we're driving directly */ 65*1c9df754Sslatteng /* #define FULLPAGE /* No, don't output full pages */ 664da297a9Sslatteng #define NFONTS 60 /* total number of fonts useable */ 67f92359bfSslatteng #define MAXSTATE 6 /* number of environments rememberable */ 68f92359bfSslatteng #define OPENREAD 0 /* mode for openning files */ 69f92359bfSslatteng #define RESTART 1 /* upon exit, return either RESTART */ 70f92359bfSslatteng #define ABORT 2 /* or ABORT */ 71f92359bfSslatteng #define FATAL 1 /* type of error */ 72f92359bfSslatteng #define BMASK 0377 /* byte grabber */ 734da297a9Sslatteng #define FONTDIR "/usr/lib/font" /* default place to find font descriptions */ 744da297a9Sslatteng #define BITDIR "/usr/lib/vfont" /* default place to look for font rasters */ 75f92359bfSslatteng #define MAXWRIT 4096 /* max characters allowed to write at once */ 76f92359bfSslatteng 77ebd02298Sslatteng #define hmot(n) hgoto(hpos + n) 78f92359bfSslatteng #define vmot(n) vgoto(vpos + n) 79f92359bfSslatteng 80f92359bfSslatteng 81*1c9df754Sslatteng char SccsId[]= "dvar.c 1.6 83/10/06"; 82f92359bfSslatteng 83f92359bfSslatteng int output = 0; /* do we do output at all? */ 84f92359bfSslatteng int nolist = 0; /* output page list if > 0 */ 85f92359bfSslatteng int olist[20]; /* pairs of page numbers */ 86f92359bfSslatteng int spage = 9999; /* stop every spage pages */ 87f92359bfSslatteng int scount = 0; 88f92359bfSslatteng struct dev dev; 89f92359bfSslatteng struct font *fontbase[NFONTS+1]; 90f92359bfSslatteng short * pstab; /* point size table pointer */ 91f92359bfSslatteng int nsizes; /* number of sizes device is capable of printing */ 92f92359bfSslatteng int nfonts; /* number of fonts device is capable of printing */ 93f92359bfSslatteng int nchtab; 94f92359bfSslatteng char * chname; 95f92359bfSslatteng short * chtab; 964da297a9Sslatteng char * fitab[NFONTS+1]; /* font inclusion table - maps ascii to ch # */ 974da297a9Sslatteng char * widtab[NFONTS+1]; /* width table for each font */ 98f92359bfSslatteng char * codetab[NFONTS+1]; /* device codes */ 994da297a9Sslatteng char * fontdir = FONTDIR; /* place to find devxxx directories */ 1004da297a9Sslatteng char * bitdir = BITDIR; /* place to find raster fonts and fontmap */ 101*1c9df754Sslatteng char * fontname[NFONTS+1]; /* table of what font is on what position */ 1024da297a9Sslatteng struct { /* table of what font */ 1034da297a9Sslatteng char fname[3]; /* name maps to what */ 1044da297a9Sslatteng char *ffile; /* filename in bitdirectory */ 1054da297a9Sslatteng } fontmap[NFONTS+1]; 1064da297a9Sslatteng 107f92359bfSslatteng 108f92359bfSslatteng #ifdef DEBUGABLE 109f92359bfSslatteng int dbg = 0; 110f92359bfSslatteng #endif 1114da297a9Sslatteng int size = -1; /* current point size (internal pstable index) */ 112f92359bfSslatteng int font = -1; /* current font - not using any to start with */ 113f92359bfSslatteng int hpos; /* horizontal position we are to be at next; left = 0 */ 114f92359bfSslatteng int vpos; /* current vertical position (down positive) */ 1154da297a9Sslatteng extern linethickness; /* thickness (in pixels) of any drawn object */ 116ebd02298Sslatteng extern linmod; /* line style (a bit mask - dotted, etc.) of objects */ 117f92359bfSslatteng int lastw; /* width of last character printed */ 118f92359bfSslatteng 119f92359bfSslatteng 120f92359bfSslatteng #define DISPATCHSIZE 256 /* must be a power of two */ 121f92359bfSslatteng #define CHARMASK (DISPATCHSIZE-1) 122f92359bfSslatteng #define DSIZ ((sizeof *dispatch)*DISPATCHSIZE) 123f92359bfSslatteng #define OUTFILE fileno (stdout) 1244da297a9Sslatteng #define RES 200 /* resolution of the device (dots/in) */ 125f92359bfSslatteng 1261a4ecc79Sslatteng #define RASTER_LENGTH 2112 /* device line length */ 127f92359bfSslatteng #define BYTES_PER_LINE (RASTER_LENGTH/8) 128*1c9df754Sslatteng #ifndef FULLPAGE 129*1c9df754Sslatteng # define NLINES 1600 /* page width, 8 inches */ 130*1c9df754Sslatteng #endif 131*1c9df754Sslatteng #ifdef FULLPAGE 132ebd02298Sslatteng # define NLINES 1700 /* page width, 8.5 inches */ 133*1c9df754Sslatteng #endif 134f92359bfSslatteng #define BUFFER_SIZE (NLINES*BYTES_PER_LINE) /* number of chars in picture */ 135f92359bfSslatteng 136f92359bfSslatteng 137f92359bfSslatteng int pltmode[] = { VPLOT }; 138f92359bfSslatteng int prtmode[] = { VPRINT }; 139f92359bfSslatteng char buffer[BUFFER_SIZE]; /* Big line buffers */ 140f92359bfSslatteng char * buf0p = &buffer[0]; /* Zero origin in circular buffer */ 141f92359bfSslatteng 142f92359bfSslatteng char * calloc(); 143f92359bfSslatteng char * nalloc(); 144f92359bfSslatteng char * allpanic(); 1454dabf413Sslatteng char * operand(); 146f92359bfSslatteng 147f92359bfSslatteng struct header { 148f92359bfSslatteng short magic; 149f92359bfSslatteng unsigned short size; 150f92359bfSslatteng short maxx; 151f92359bfSslatteng short maxy; 152f92359bfSslatteng short xtnd; 153f92359bfSslatteng } header; 154f92359bfSslatteng 155f92359bfSslatteng struct dispatch{ 156f92359bfSslatteng unsigned short addr; 157f92359bfSslatteng short nbytes; 158f92359bfSslatteng char up; 159f92359bfSslatteng char down; 160f92359bfSslatteng char left; 161f92359bfSslatteng char right; 162f92359bfSslatteng short width; 163f92359bfSslatteng }; 164f92359bfSslatteng 165f92359bfSslatteng struct fontdes { 166f92359bfSslatteng int fnum; 167f92359bfSslatteng int psize; 168f92359bfSslatteng struct dispatch *disp; 169f92359bfSslatteng char *bits; 170f92359bfSslatteng } fontdes[NFONTS] = { 171f92359bfSslatteng -1, 172f92359bfSslatteng -1 173f92359bfSslatteng }; 174f92359bfSslatteng 175f92359bfSslatteng struct dispatch *dispatch; 176f92359bfSslatteng int cfnum = -1; 177f92359bfSslatteng int cpsize = 10; 178f92359bfSslatteng int cfont = 1; 179f92359bfSslatteng char *bits; 180f92359bfSslatteng int fontwanted = 1; /* flag: "has a new font been requested?" */ 181f92359bfSslatteng int nfontnum = -1; 182f92359bfSslatteng int npsize = 10; 183f92359bfSslatteng 184f92359bfSslatteng 185f92359bfSslatteng 186f92359bfSslatteng main(argc, argv) 187f92359bfSslatteng char *argv[]; 188f92359bfSslatteng { 189f92359bfSslatteng FILE *fp; 190f92359bfSslatteng 1914dabf413Sslatteng while (--argc > 0 && **++argv == '-') { 1924dabf413Sslatteng switch ((*argv)[1]) { 193f92359bfSslatteng case 'F': 194*1c9df754Sslatteng bitdir = operand(&argc, &argv); 1954da297a9Sslatteng break; 1964da297a9Sslatteng case 'f': 197*1c9df754Sslatteng fontdir = operand(&argc, &argv); 198f92359bfSslatteng break; 199f92359bfSslatteng case 'o': 2004dabf413Sslatteng outlist(operand(&argc, &argv)); 201f92359bfSslatteng break; 202f92359bfSslatteng #ifdef DEBUGABLE 203f92359bfSslatteng case 'd': 2044dabf413Sslatteng dbg = atoi(operand(&argc, &argv)); 205f92359bfSslatteng if (dbg == 0) dbg = 1; 206f92359bfSslatteng break; 207f92359bfSslatteng #endif 208f92359bfSslatteng case 's': 2094dabf413Sslatteng spage = atoi(operand(&argc, &argv)); 210f92359bfSslatteng if (spage <= 0) 211f92359bfSslatteng spage = 9999; 212f92359bfSslatteng break; 213f92359bfSslatteng } 214f92359bfSslatteng } 215f92359bfSslatteng 216*1c9df754Sslatteng #ifdef DRIVER 217f92359bfSslatteng ioctl(OUTFILE, VSETSTATE, pltmode); 218*1c9df754Sslatteng #endif 219f92359bfSslatteng 2204dabf413Sslatteng if (argc < 1) 221f92359bfSslatteng conv(stdin); 222f92359bfSslatteng else 2234dabf413Sslatteng while (argc--) { 2244dabf413Sslatteng if (strcmp(*argv, "-") == 0) 225f92359bfSslatteng fp = stdin; 226f92359bfSslatteng else if ((fp = fopen(*argv, "r")) == NULL) 227f92359bfSslatteng error(FATAL, "can't open %s", *argv); 228f92359bfSslatteng conv(fp); 229f92359bfSslatteng fclose(fp); 2304dabf413Sslatteng argv++; 231f92359bfSslatteng } 232f92359bfSslatteng exit(0); 233f92359bfSslatteng } 234f92359bfSslatteng 2354dabf413Sslatteng 2364dabf413Sslatteng /*----------------------------------------------------------------------------* 2374dabf413Sslatteng | Routine: char * operand (& argc, & argv) 2384dabf413Sslatteng | 2394dabf413Sslatteng | Results: returns address of the operand given with a command-line 2404dabf413Sslatteng | option. It uses either "-Xoperand" or "-X operand", whichever 2414dabf413Sslatteng | is present. The program is terminated if no option is present. 2424dabf413Sslatteng | 2434dabf413Sslatteng | Side Efct: argc and argv are updated as necessary. 2444dabf413Sslatteng *----------------------------------------------------------------------------*/ 2454dabf413Sslatteng 2464dabf413Sslatteng char *operand(argcp, argvp) 2474dabf413Sslatteng int * argcp; 2484dabf413Sslatteng char ***argvp; 2494dabf413Sslatteng { 2504dabf413Sslatteng if ((**argvp)[2]) return(**argvp + 2); /* operand immediately follows */ 2514dabf413Sslatteng if ((--*argcp) <= 0) /* no operand */ 2524dabf413Sslatteng error (FATAL, "command-line option operand missing.\n"); 2534dabf413Sslatteng return(*(++(*argvp))); /* operand next word */ 2544dabf413Sslatteng } 2554dabf413Sslatteng 2564dabf413Sslatteng 257f92359bfSslatteng outlist(s) /* process list of page numbers to be printed */ 258f92359bfSslatteng char *s; 259f92359bfSslatteng { 260f92359bfSslatteng int n1, n2, i; 261f92359bfSslatteng 262f92359bfSslatteng nolist = 0; 263f92359bfSslatteng while (*s) { 264f92359bfSslatteng n1 = 0; 265f92359bfSslatteng if (isdigit(*s)) 266f92359bfSslatteng do 267f92359bfSslatteng n1 = 10 * n1 + *s++ - '0'; 268f92359bfSslatteng while (isdigit(*s)); 269f92359bfSslatteng else 270f92359bfSslatteng n1 = -9999; 271f92359bfSslatteng n2 = n1; 272f92359bfSslatteng if (*s == '-') { 273f92359bfSslatteng s++; 274f92359bfSslatteng n2 = 0; 275f92359bfSslatteng if (isdigit(*s)) 276f92359bfSslatteng do 277f92359bfSslatteng n2 = 10 * n2 + *s++ - '0'; 278f92359bfSslatteng while (isdigit(*s)); 279f92359bfSslatteng else 280f92359bfSslatteng n2 = 9999; 281f92359bfSslatteng } 282f92359bfSslatteng olist[nolist++] = n1; 283f92359bfSslatteng olist[nolist++] = n2; 284f92359bfSslatteng if (*s != '\0') 285f92359bfSslatteng s++; 286f92359bfSslatteng } 287f92359bfSslatteng olist[nolist] = 0; 288f92359bfSslatteng #ifdef DEBUGABLE 289f92359bfSslatteng if (dbg) 290f92359bfSslatteng for (i=0; i<nolist; i += 2) 291f92359bfSslatteng fprintf(stderr,"%3d %3d\n", olist[i], olist[i+1]); 292f92359bfSslatteng #endif 293f92359bfSslatteng } 294f92359bfSslatteng 295f92359bfSslatteng conv(fp) 296f92359bfSslatteng register FILE *fp; 297f92359bfSslatteng { 298f92359bfSslatteng register int c, k; 299f92359bfSslatteng int m, n, n1, m1; 300f92359bfSslatteng char str[100], buf[300]; 301f92359bfSslatteng 302f92359bfSslatteng while ((c = getc(fp)) != EOF) { 303f92359bfSslatteng switch (c) { 304f92359bfSslatteng case '\n': /* when input is text */ 305f92359bfSslatteng case ' ': 306f92359bfSslatteng case 0: /* occasional noise creeps in */ 307f92359bfSslatteng break; 308f92359bfSslatteng case '{': /* push down current environment */ 309f92359bfSslatteng t_push(); 310f92359bfSslatteng break; 311f92359bfSslatteng case '}': 312f92359bfSslatteng t_pop(); 313f92359bfSslatteng break; 314f92359bfSslatteng case '0': case '1': case '2': case '3': case '4': 315f92359bfSslatteng case '5': case '6': case '7': case '8': case '9': 316f92359bfSslatteng /* two motion digits plus a character */ 317f92359bfSslatteng hmot((c-'0')*10 + getc(fp)-'0'); 318f92359bfSslatteng put1(getc(fp)); 319f92359bfSslatteng break; 320f92359bfSslatteng case 'c': /* single ascii character */ 321f92359bfSslatteng put1(getc(fp)); 322f92359bfSslatteng break; 323f92359bfSslatteng case 'C': 324f92359bfSslatteng fscanf(fp, "%s", str); 325f92359bfSslatteng put1s(str); 326f92359bfSslatteng break; 327f92359bfSslatteng case 't': /* straight text */ 328f92359bfSslatteng fgets(buf, sizeof(buf), fp); 329f92359bfSslatteng t_text(buf); 330f92359bfSslatteng break; 331f92359bfSslatteng case 'D': /* draw function */ 332f92359bfSslatteng fgets(buf, sizeof(buf), fp); 333f92359bfSslatteng switch (buf[0]) { 334f92359bfSslatteng case 'l': /* draw a line */ 335f92359bfSslatteng sscanf(buf+1, "%d %d", &n, &m); 336f92359bfSslatteng drawline(n, m); 337f92359bfSslatteng break; 338f92359bfSslatteng case 'c': /* circle */ 339f92359bfSslatteng sscanf(buf+1, "%d", &n); 340f92359bfSslatteng drawcirc(n); 341f92359bfSslatteng break; 342f92359bfSslatteng case 'e': /* ellipse */ 343f92359bfSslatteng sscanf(buf+1, "%d %d", &m, &n); 344f92359bfSslatteng drawellip(m, n); 345f92359bfSslatteng break; 346f92359bfSslatteng case 'a': /* arc */ 347f92359bfSslatteng sscanf(buf+1, "%d %d %d %d", &n, &m, &n1, &m1); 348f92359bfSslatteng drawarc(n, m, n1, m1); 349f92359bfSslatteng break; 350f92359bfSslatteng case '~': /* wiggly line */ 3511a4ecc79Sslatteng case 'g': /* gremlin spline */ 3521a4ecc79Sslatteng drawwig(buf+1, fp, buf[0] == '~'); 3531a4ecc79Sslatteng break; 3541a4ecc79Sslatteng case 't': /* line thickness */ 3551a4ecc79Sslatteng sscanf(buf+1, "%d", &n); 3561a4ecc79Sslatteng drawthick(n); 3571a4ecc79Sslatteng break; 3581a4ecc79Sslatteng case 's': /* line style */ 3591a4ecc79Sslatteng sscanf(buf+1, "%d", &n); 3601a4ecc79Sslatteng drawstyle(n); 361f92359bfSslatteng break; 362f92359bfSslatteng default: 363ebd02298Sslatteng error(FATAL, "unknown drawing function %s", buf); 364f92359bfSslatteng break; 365f92359bfSslatteng } 366f92359bfSslatteng break; 367f92359bfSslatteng case 's': 368f92359bfSslatteng fscanf(fp, "%d", &n); /* ignore fractional sizes */ 369f92359bfSslatteng setsize(t_size(n)); 370f92359bfSslatteng break; 371f92359bfSslatteng case 'f': 372f92359bfSslatteng fscanf(fp, "%s", str); 373f92359bfSslatteng setfont(t_font(str)); 374f92359bfSslatteng break; 375f92359bfSslatteng case 'H': /* absolute horizontal motion */ 376f92359bfSslatteng /* fscanf(fp, "%d", &n); */ 377f92359bfSslatteng while ((c = getc(fp)) == ' ') 378f92359bfSslatteng ; 379f92359bfSslatteng k = 0; 380f92359bfSslatteng do { 381f92359bfSslatteng k = 10 * k + c - '0'; 382f92359bfSslatteng } while (isdigit(c = getc(fp))); 383f92359bfSslatteng ungetc(c, fp); 384f92359bfSslatteng hgoto(k); 385f92359bfSslatteng break; 386f92359bfSslatteng case 'h': /* relative horizontal motion */ 387f92359bfSslatteng while ((c = getc(fp)) == ' ') 388f92359bfSslatteng ; 389f92359bfSslatteng k = 0; 390f92359bfSslatteng do { 391f92359bfSslatteng k = 10 * k + c - '0'; 392f92359bfSslatteng } while (isdigit(c = getc(fp))); 393f92359bfSslatteng ungetc(c, fp); 394f92359bfSslatteng hmot(k); 395f92359bfSslatteng break; 396f92359bfSslatteng case 'w': /* word space */ 397f92359bfSslatteng break; 398f92359bfSslatteng case 'V': 399f92359bfSslatteng fscanf(fp, "%d", &n); 400f92359bfSslatteng vgoto(n); 401f92359bfSslatteng break; 402f92359bfSslatteng case 'v': 403f92359bfSslatteng fscanf(fp, "%d", &n); 404f92359bfSslatteng vmot(n); 405f92359bfSslatteng break; 406f92359bfSslatteng case 'p': /* new page */ 407f92359bfSslatteng fscanf(fp, "%d", &n); 408f92359bfSslatteng t_page(n); 409f92359bfSslatteng break; 410f92359bfSslatteng case 'n': /* end of line */ 411f92359bfSslatteng while (getc(fp) != '\n') 412f92359bfSslatteng ; 413f92359bfSslatteng t_newline(); 414f92359bfSslatteng break; 415f92359bfSslatteng case '#': /* comment */ 416f92359bfSslatteng while (getc(fp) != '\n') 417f92359bfSslatteng ; 418f92359bfSslatteng break; 419f92359bfSslatteng case 'x': /* device control */ 420f92359bfSslatteng devcntrl(fp); 421f92359bfSslatteng break; 422f92359bfSslatteng default: 423ebd02298Sslatteng error(FATAL, "unknown input character %o %c", c, c); 424f92359bfSslatteng } 425f92359bfSslatteng } 426f92359bfSslatteng } 427f92359bfSslatteng 428f92359bfSslatteng devcntrl(fp) /* interpret device control functions */ 429f92359bfSslatteng FILE *fp; 430f92359bfSslatteng { 431f92359bfSslatteng char str[20], str1[50], buf[50]; 432f92359bfSslatteng int c, n; 433f92359bfSslatteng 434f92359bfSslatteng fscanf(fp, "%s", str); 435f92359bfSslatteng switch (str[0]) { /* crude for now */ 436f92359bfSslatteng case 'i': /* initialize */ 437f92359bfSslatteng fileinit(); 438f92359bfSslatteng t_init(); 439f92359bfSslatteng break; 440f92359bfSslatteng case 't': /* trailer */ 441f92359bfSslatteng break; 442f92359bfSslatteng case 'p': /* pause -- can restart */ 443f92359bfSslatteng t_reset('p'); 444f92359bfSslatteng break; 445f92359bfSslatteng case 's': /* stop */ 446f92359bfSslatteng t_reset('s'); 447f92359bfSslatteng break; 448f92359bfSslatteng case 'r': /* resolution assumed when prepared */ 4494da297a9Sslatteng fscanf(fp, "%d", &n); 4504da297a9Sslatteng if (n!=RES) error(FATAL,"Input computed with wrong resolution"); 451f92359bfSslatteng break; 452f92359bfSslatteng case 'f': /* font used */ 453f92359bfSslatteng fscanf(fp, "%d %s", &n, str); 454f92359bfSslatteng fgets(buf, sizeof buf, fp); /* in case there's a filename */ 455f92359bfSslatteng ungetc('\n', fp); /* fgets goes too far */ 456f92359bfSslatteng str1[0] = 0; /* in case nothing comes in */ 457f92359bfSslatteng sscanf(buf, "%s", str1); 458f92359bfSslatteng loadfont(n, str, str1); 459f92359bfSslatteng break; 460f92359bfSslatteng /* these don't belong here... */ 461f92359bfSslatteng case 'H': /* char height */ 462f92359bfSslatteng fscanf(fp, "%d", &n); 463f92359bfSslatteng t_charht(n); 464f92359bfSslatteng break; 465f92359bfSslatteng case 'S': /* slant */ 466f92359bfSslatteng fscanf(fp, "%d", &n); 467f92359bfSslatteng t_slant(n); 468f92359bfSslatteng break; 469f92359bfSslatteng } 470f92359bfSslatteng while ((c = getc(fp)) != '\n') /* skip rest of input line */ 471f92359bfSslatteng if (c == EOF) 472f92359bfSslatteng break; 473f92359bfSslatteng } 474f92359bfSslatteng 475f92359bfSslatteng /* fileinit: read in font and code files, etc. 476f92359bfSslatteng Must open table for device, read in resolution, 4774da297a9Sslatteng size info, font info, etc. and set params. 4784da297a9Sslatteng Also read in font name mapping. 479f92359bfSslatteng */ 4804da297a9Sslatteng 481f92359bfSslatteng fileinit() 482f92359bfSslatteng { 4834da297a9Sslatteng register int i; 4844da297a9Sslatteng register int fin; 4854da297a9Sslatteng register int nw; 4864da297a9Sslatteng register char *filebase; 4874da297a9Sslatteng register char *p; 4884da297a9Sslatteng register FILE *fp; 4894da297a9Sslatteng char temp[100]; 4904da297a9Sslatteng 4914da297a9Sslatteng /* first, read in font map file. The file must be of Format: 4924da297a9Sslatteng XX FILENAME (XX = troff font name) 4934da297a9Sslatteng with one entry per text line of the file. 4944da297a9Sslatteng Extra stuff after FILENAME is ignored */ 4954da297a9Sslatteng 4964da297a9Sslatteng sprintf(temp, "%s/fontmap", bitdir); 4974da297a9Sslatteng if ((fp = fopen(temp, "r")) == NULL) 4984da297a9Sslatteng error(FATAL, "Can't open %s", temp); 4994da297a9Sslatteng for (i = 0; i <= NFONTS && fgets(temp, 100, fp) != NULL; i++) { 5004da297a9Sslatteng sscanf(temp, "%2s", fontmap[i].fname); 5014da297a9Sslatteng p = &temp[0]; 5024da297a9Sslatteng while (*p != ' ' && *p != ' ') p++; 5034da297a9Sslatteng while (*p == ' ' || *p == ' ') p++; 5044da297a9Sslatteng filebase = p; 5054da297a9Sslatteng for (nw = 1; *p != '\n' && *p != ' ' && *p != '\t'; p++) nw++; 5064da297a9Sslatteng fontmap[i].ffile = nalloc(1, nw); 5074da297a9Sslatteng sscanf(filebase, "%s", fontmap[i].ffile); 5084da297a9Sslatteng } 5094da297a9Sslatteng fontmap[++i].fname[0] = '0'; /* finish off with zeros */ 5104da297a9Sslatteng fontmap[i].ffile = (char *) 0; 5114da297a9Sslatteng fclose(fp); 5124da297a9Sslatteng #ifdef DEBUGABLE 5134da297a9Sslatteng if(dbg) { 5144da297a9Sslatteng fprintf(stderr, "font map:\n"); 5154da297a9Sslatteng for (i = 0; fontmap[i].ffile; i++) 5164da297a9Sslatteng fprintf(stderr,"%s = %s\n", fontmap[i].fname, fontmap[i].ffile); 5174da297a9Sslatteng } 5184da297a9Sslatteng #endif 519f92359bfSslatteng 520ebd02298Sslatteng sprintf(temp, "%s/devvar/DESC.out", fontdir); 521f92359bfSslatteng if ((fin = open(temp, 0)) < 0) 522ebd02298Sslatteng error(FATAL, "can't open tables for %s", temp); 523f92359bfSslatteng read(fin, &dev, sizeof(struct dev)); 524f92359bfSslatteng nfonts = dev.nfonts; 525f92359bfSslatteng nsizes = dev.nsizes; 526f92359bfSslatteng nchtab = dev.nchtab; 527f92359bfSslatteng filebase = calloc(1, dev.filesize); /* enough room for whole file */ 528f92359bfSslatteng read(fin, filebase, dev.filesize); /* all at once */ 529f92359bfSslatteng pstab = (short *) filebase; 530f92359bfSslatteng chtab = pstab + nsizes + 1; 531f92359bfSslatteng chname = (char *) (chtab + dev.nchtab); 532f92359bfSslatteng p = chname + dev.lchname; 533f92359bfSslatteng for (i = 1; i <= nfonts; i++) { 534f92359bfSslatteng fontbase[i] = (struct font *) p; 535f92359bfSslatteng nw = *p & BMASK; /* 1st thing is width count */ 536*1c9df754Sslatteng p += sizeof(struct font); 537f92359bfSslatteng widtab[i] = p; 538f92359bfSslatteng codetab[i] = p + 2 * nw; 539f92359bfSslatteng fitab[i] = p + 3 * nw; 540f92359bfSslatteng p += 3 * nw + dev.nchtab + 128 - 32; 541f92359bfSslatteng t_fp(i, fontbase[i]->namefont, fontbase[i]->intname); 542f92359bfSslatteng #ifdef DEBUGABLE 543f92359bfSslatteng if (dbg > 1) fontprint(i); 544f92359bfSslatteng #endif 545f92359bfSslatteng } 546f92359bfSslatteng fontbase[0] = (struct font *) 547f92359bfSslatteng calloc(1,3*255 + dev.nchtab + (128-32) + sizeof (struct font)); 548f92359bfSslatteng widtab[0] = (char *) fontbase[0] + sizeof (struct font); 549f92359bfSslatteng fontbase[0]->nwfont = 255; 550f92359bfSslatteng close(fin); 5514da297a9Sslatteng 552f92359bfSslatteng } 553f92359bfSslatteng 5544da297a9Sslatteng 555f92359bfSslatteng fontprint(i) /* debugging print of font i (0,...) */ 556f92359bfSslatteng { 557f92359bfSslatteng int j, n; 558f92359bfSslatteng char *p; 559f92359bfSslatteng 560f92359bfSslatteng fprintf(stderr,"font %d:\n", i); 561f92359bfSslatteng p = (char *) fontbase[i]; 562f92359bfSslatteng n = fontbase[i]->nwfont & BMASK; 563f92359bfSslatteng fprintf(stderr, 564f92359bfSslatteng "base=0%o, nchars=%d, spec=%d, name=%s, widtab=0%o, fitab=0%o\n",p, 565f92359bfSslatteng n,fontbase[i]->specfont,fontbase[i]->namefont,widtab[i],fitab[i]); 566f92359bfSslatteng fprintf(stderr,"widths:\n"); 567f92359bfSslatteng for (j=0; j <= n; j++) { 568f92359bfSslatteng fprintf(stderr," %2d", widtab[i][j] & BMASK); 569f92359bfSslatteng if (j % 20 == 19) fprintf(stderr,"\n"); 570f92359bfSslatteng } 571f92359bfSslatteng fprintf(stderr,"\ncodetab:\n"); 572f92359bfSslatteng for (j=0; j <= n; j++) { 573f92359bfSslatteng fprintf(stderr," %2d", codetab[i][j] & BMASK); 574f92359bfSslatteng if (j % 20 == 19) fprintf(stderr,"\n"); 575f92359bfSslatteng } 576f92359bfSslatteng fprintf(stderr,"\nfitab:\n"); 577f92359bfSslatteng for (j=0; j <= dev.nchtab + 128-32; j++) { 578f92359bfSslatteng fprintf(stderr," %2d", fitab[i][j] & BMASK); 579f92359bfSslatteng if (j % 20 == 19) fprintf(stderr,"\n"); 580f92359bfSslatteng } 581f92359bfSslatteng fprintf(stderr,"\n"); 582f92359bfSslatteng } 583f92359bfSslatteng 584f92359bfSslatteng loadfont(n, s, s1) /* load font info for font s on position n (0...) */ 585f92359bfSslatteng int n; 586f92359bfSslatteng char *s, *s1; 587f92359bfSslatteng { 588f92359bfSslatteng char temp[60]; 589f92359bfSslatteng int fin, nw, norig; 590f92359bfSslatteng 5914da297a9Sslatteng 592f92359bfSslatteng if (n < 0 || n > NFONTS) 593f92359bfSslatteng error(FATAL, "illegal fp command %d %s", n, s); 594f92359bfSslatteng if (strcmp(s, fontbase[n]->namefont) == 0) 595f92359bfSslatteng return; 596f92359bfSslatteng if (s1 == NULL || s1[0] == '\0') 597ebd02298Sslatteng sprintf(temp, "%s/devvar/%s.out", fontdir, s); 598f92359bfSslatteng else 599f92359bfSslatteng sprintf(temp, "%s/%s.out", s1, s); 600f92359bfSslatteng if ((fin = open(temp, 0)) < 0) 601f92359bfSslatteng error(FATAL, "can't open font table %s", temp); 602f92359bfSslatteng norig = fontbase[n]->nwfont & BMASK; 603f92359bfSslatteng read(fin, fontbase[n], 3*norig + nchtab+128-32 + sizeof(struct font)); 604f92359bfSslatteng if ((fontbase[n]->nwfont & BMASK) > norig) 605ebd02298Sslatteng error(FATAL, "Font %s too big for position %d", s, n); 606f92359bfSslatteng close(fin); 607f92359bfSslatteng nw = fontbase[n]->nwfont & BMASK; 608f92359bfSslatteng widtab[n] = (char *) fontbase[n] + sizeof(struct font); 609f92359bfSslatteng codetab[n] = (char *) widtab[n] + 2 * nw; 610f92359bfSslatteng fitab[n] = (char *) widtab[n] + 3 * nw; 611f92359bfSslatteng t_fp(n, fontbase[n]->namefont, fontbase[n]->intname); 612f92359bfSslatteng fontbase[n]->nwfont = norig; /* to later use full original size */ 613f92359bfSslatteng #ifdef DEBUGABLE 614f92359bfSslatteng if (dbg > 1) fontprint(n); 615f92359bfSslatteng #endif 616f92359bfSslatteng } 617f92359bfSslatteng 618ebd02298Sslatteng 619f92359bfSslatteng /*VARARGS1*/ 620f92359bfSslatteng error(f, s, a1, a2, a3, a4, a5, a6, a7) { 621ebd02298Sslatteng fprintf(stderr, "dvar: "); 622f92359bfSslatteng fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7); 623f92359bfSslatteng fprintf(stderr, "\n"); 624*1c9df754Sslatteng if (f) exit(ABORT); 625f92359bfSslatteng } 626f92359bfSslatteng 627f92359bfSslatteng 628f92359bfSslatteng t_init() /* initialize device */ 629f92359bfSslatteng { 630f92359bfSslatteng int i; 631f92359bfSslatteng 632f92359bfSslatteng hpos = vpos = 0; 633f92359bfSslatteng 634f92359bfSslatteng setsize(t_size(10)); /* start somewhere */ 635f92359bfSslatteng setfont(1); 636f92359bfSslatteng } 637f92359bfSslatteng 638f92359bfSslatteng 639f92359bfSslatteng struct state { 640f92359bfSslatteng int ssize; 641f92359bfSslatteng int sfont; 642f92359bfSslatteng int shpos; 643f92359bfSslatteng int svpos; 644ebd02298Sslatteng int sstyle; 645ebd02298Sslatteng int sthick; 646f92359bfSslatteng }; 647f92359bfSslatteng struct state state[MAXSTATE]; 648f92359bfSslatteng struct state *statep = state; 649f92359bfSslatteng 650f92359bfSslatteng t_push() /* begin a new block */ 651f92359bfSslatteng { 652f92359bfSslatteng statep->ssize = size; 653f92359bfSslatteng statep->sfont = font; 654ebd02298Sslatteng statep->sstyle = linmod; 655ebd02298Sslatteng statep->sthick = linethickness; 656f92359bfSslatteng statep->shpos = hpos; 657f92359bfSslatteng statep->svpos = vpos; 658f92359bfSslatteng if (statep++ >= state+MAXSTATE) 659f92359bfSslatteng error(FATAL, "{ nested too deep"); 660f92359bfSslatteng } 661f92359bfSslatteng 662f92359bfSslatteng t_pop() /* pop to previous state */ 663f92359bfSslatteng { 664f92359bfSslatteng if (--statep < state) 665f92359bfSslatteng error(FATAL, "extra }"); 666f92359bfSslatteng size = statep->ssize; 667f92359bfSslatteng font = statep->sfont; 668f92359bfSslatteng hpos = statep->shpos; 669f92359bfSslatteng vpos = statep->svpos; 670ebd02298Sslatteng linmod = statep->sstyle; 671ebd02298Sslatteng linethickness = statep->sthick; 672f92359bfSslatteng } 673f92359bfSslatteng 674f92359bfSslatteng t_page(n) /* do whatever new page functions */ 675f92359bfSslatteng { 676f92359bfSslatteng int i; 677f92359bfSslatteng 678f92359bfSslatteng 679f92359bfSslatteng if (output) { 680f92359bfSslatteng if (++scount >= spage) { 681f92359bfSslatteng t_reset('p'); 682f92359bfSslatteng scount = 0; 683f92359bfSslatteng } 684ebd02298Sslatteng slop_lines(NLINES); 685*1c9df754Sslatteng #ifdef DRIVER 686f92359bfSslatteng ioctl(OUTFILE, VSETSTATE, prtmode); 687f92359bfSslatteng if (write(OUTFILE, "\f", 2) != 2) 688f92359bfSslatteng exit(RESTART); 689f92359bfSslatteng ioctl(OUTFILE, VSETSTATE, pltmode); 690*1c9df754Sslatteng #endif 691f92359bfSslatteng } 692f92359bfSslatteng 693f92359bfSslatteng vpos = 0; 694f92359bfSslatteng output = 1; 695f92359bfSslatteng if (nolist == 0) 696f92359bfSslatteng return; /* no -o specified */ 697f92359bfSslatteng output = 0; 698f92359bfSslatteng for (i = 0; i < nolist; i += 2) 699f92359bfSslatteng if (n >= olist[i] && n <= olist[i+1]) { 700f92359bfSslatteng output = 1; 701f92359bfSslatteng break; 702f92359bfSslatteng } 703f92359bfSslatteng } 704f92359bfSslatteng 705f92359bfSslatteng t_newline() /* do whatever for the end of a line */ 706f92359bfSslatteng { 707f92359bfSslatteng hpos = 0; /* because we're now back at the left margin */ 708f92359bfSslatteng } 709f92359bfSslatteng 710f92359bfSslatteng t_size(n) /* convert integer to internal size number*/ 711f92359bfSslatteng int n; 712f92359bfSslatteng { 713f92359bfSslatteng int i; 714f92359bfSslatteng 715f92359bfSslatteng if (n <= pstab[0]) 7164da297a9Sslatteng return(0); 717f92359bfSslatteng else if (n >= pstab[nsizes - 1]) 7184da297a9Sslatteng return(nsizes - 1); 719f92359bfSslatteng for (i = 0; n > pstab[i]; i++) 720f92359bfSslatteng ; 7214da297a9Sslatteng return(i); 722f92359bfSslatteng } 723f92359bfSslatteng 724f92359bfSslatteng t_charht(n) /* set character height to n */ 725f92359bfSslatteng int n; 726f92359bfSslatteng { 727f92359bfSslatteng #ifdef DEBUGABLE 7284da297a9Sslatteng if (dbg) error(!FATAL, "can't set height on varian"); 729f92359bfSslatteng #endif 730f92359bfSslatteng } 731f92359bfSslatteng 732f92359bfSslatteng t_slant(n) /* set slant to n */ 733f92359bfSslatteng int n; 734f92359bfSslatteng { 735f92359bfSslatteng #ifdef DEBUGABLE 7364da297a9Sslatteng if (dbg) error(!FATAL, "can't set slant on varian"); 737f92359bfSslatteng #endif 738f92359bfSslatteng } 739f92359bfSslatteng 740f92359bfSslatteng t_font(s) /* convert string to internal font number */ 741f92359bfSslatteng char *s; 742f92359bfSslatteng { 743f92359bfSslatteng int n; 744f92359bfSslatteng 745f92359bfSslatteng n = atoi(s); 746f92359bfSslatteng if (n < 0 || n > nfonts) 747f92359bfSslatteng n = 1; 748f92359bfSslatteng return(n); 749f92359bfSslatteng } 750f92359bfSslatteng 751f92359bfSslatteng t_text(s) /* print string s as text */ 752f92359bfSslatteng char *s; 753f92359bfSslatteng { 754f92359bfSslatteng int c; 755f92359bfSslatteng char str[100]; 756f92359bfSslatteng 757f92359bfSslatteng if (!output) 758f92359bfSslatteng return; 759f92359bfSslatteng while (c = *s++) { 760f92359bfSslatteng if (c == '\\') { 761f92359bfSslatteng switch (c = *s++) { 762f92359bfSslatteng case '\\': 763f92359bfSslatteng case 'e': 764f92359bfSslatteng put1('\\'); 765f92359bfSslatteng break; 766f92359bfSslatteng case '(': 767f92359bfSslatteng str[0] = *s++; 768f92359bfSslatteng str[1] = *s++; 769f92359bfSslatteng str[2] = '\0'; 770f92359bfSslatteng put1s(str); 771f92359bfSslatteng break; 772f92359bfSslatteng } 773f92359bfSslatteng } else { 774f92359bfSslatteng put1(c); 775f92359bfSslatteng } 776f92359bfSslatteng hmot(lastw); 777f92359bfSslatteng #ifdef DEBUGABLE 778f92359bfSslatteng if (dbg) fprintf(stderr,"width = %d\n", lastw); 779f92359bfSslatteng #endif 780f92359bfSslatteng } 781f92359bfSslatteng } 782f92359bfSslatteng 783f92359bfSslatteng t_reset(c) 784f92359bfSslatteng { 785f92359bfSslatteng output = 1; 786f92359bfSslatteng switch(c){ 787f92359bfSslatteng case 'p': 788ebd02298Sslatteng slop_lines(NLINES); 789f92359bfSslatteng break; 790f92359bfSslatteng case 's': 791ebd02298Sslatteng slop_lines(NLINES); 792*1c9df754Sslatteng #ifdef DRIVER 793f92359bfSslatteng ioctl(OUTFILE, VSETSTATE, prtmode); 794f92359bfSslatteng if (write(OUTFILE, "\f", 2) != 2) 795f92359bfSslatteng exit(RESTART); 796*1c9df754Sslatteng #endif 7974da297a9Sslatteng break; /* no Return */ 798f92359bfSslatteng } 799f92359bfSslatteng } 800f92359bfSslatteng 801ebd02298Sslatteng 802ebd02298Sslatteng /*----------------------------------------------------------------------------* 803ebd02298Sslatteng | Routine: hgoto (horizontal_spot) 804ebd02298Sslatteng | 805ebd02298Sslatteng | Results: hpos is set to n. If n overlaps in either direction, it wraps 806ebd02298Sslatteng | around to the other end of the page. 807ebd02298Sslatteng *----------------------------------------------------------------------------*/ 808ebd02298Sslatteng 809ebd02298Sslatteng hgoto(n) 810ebd02298Sslatteng int n; 811f92359bfSslatteng { 812ebd02298Sslatteng if (n < 0) 813ebd02298Sslatteng n += NLINES; 814ebd02298Sslatteng else if (n >= NLINES) 815ebd02298Sslatteng n -= NLINES; 816ebd02298Sslatteng hpos = n; 817f92359bfSslatteng } 818ebd02298Sslatteng 819ebd02298Sslatteng 820ebd02298Sslatteng /*----------------------------------------------------------------------------* 821ebd02298Sslatteng | Routine: vgoto (vertical_spot) 822ebd02298Sslatteng | 823ebd02298Sslatteng | Results: vpos is set to n. If n overlaps in either direction, it wraps 824ebd02298Sslatteng | around to the other end of the page. 825ebd02298Sslatteng *----------------------------------------------------------------------------*/ 826ebd02298Sslatteng 827ebd02298Sslatteng vgoto(n) 828ebd02298Sslatteng int n; 829ebd02298Sslatteng { 830ebd02298Sslatteng if (n < 0) 831ebd02298Sslatteng n += RASTER_LENGTH; 832ebd02298Sslatteng else if (n > RASTER_LENGTH) 833ebd02298Sslatteng n -= RASTER_LENGTH; 834f92359bfSslatteng vpos = n; 835f92359bfSslatteng } 836f92359bfSslatteng 837f92359bfSslatteng put1s(s) /* s is a funny char name */ 838f92359bfSslatteng char *s; 839f92359bfSslatteng { 840f92359bfSslatteng int i; 841f92359bfSslatteng 842f92359bfSslatteng if (!output) 843f92359bfSslatteng return; 844f92359bfSslatteng #ifdef DEBUGABLE 845f92359bfSslatteng if (dbg) fprintf(stderr,"%s ", s); 846f92359bfSslatteng #endif 847f92359bfSslatteng for (i = 0; i < nchtab; i++) 848f92359bfSslatteng if (strcmp(&chname[chtab[i]], s) == 0) 849f92359bfSslatteng break; 850f92359bfSslatteng if (i < nchtab) 851f92359bfSslatteng put1(i + 128); 852f92359bfSslatteng } 853f92359bfSslatteng 854f92359bfSslatteng put1(c) /* output char c */ 855f92359bfSslatteng int c; 856f92359bfSslatteng { 857f92359bfSslatteng char *pw; 858f92359bfSslatteng register char *p; 859f92359bfSslatteng register int i, k; 860f92359bfSslatteng int j, ofont, code; 861f92359bfSslatteng 862f92359bfSslatteng if (!output) 863f92359bfSslatteng return; 864f92359bfSslatteng c -= 32; 865f92359bfSslatteng if (c <= 0) { 866f92359bfSslatteng #ifdef DEBUGABLE 867f92359bfSslatteng if (dbg) fprintf(stderr,"non-exist 0%o\n", c + 32); 868f92359bfSslatteng #endif 8694da297a9Sslatteng lastw = (widtab[font][0] * pstab[size] + dev.unitwidth/2) 870f92359bfSslatteng / dev.unitwidth; 871f92359bfSslatteng return; 872f92359bfSslatteng } 873f92359bfSslatteng k = ofont = font; 874f92359bfSslatteng i = fitab[font][c] & BMASK; 875f92359bfSslatteng if (i != 0) { /* it's on this font */ 876f92359bfSslatteng p = codetab[font]; /* get the printing value of ch */ 877f92359bfSslatteng pw = widtab[font]; /* get the width */ 878*1c9df754Sslatteng } else /* on another font (we hope) */ 879*1c9df754Sslatteng for (k=font, j=0; j <= nfonts; j++, k = (k+1) % (nfonts+1)){ 880f92359bfSslatteng if (fitab[k] == 0) 881f92359bfSslatteng continue; 882f92359bfSslatteng if ((i = fitab[k][c] & BMASK) != 0) { 883f92359bfSslatteng p = codetab[k]; 884f92359bfSslatteng pw = widtab[k]; 885f92359bfSslatteng setfont(k); 886f92359bfSslatteng break; 887f92359bfSslatteng } 888f92359bfSslatteng } 889*1c9df754Sslatteng 890f92359bfSslatteng if (i == 0 || (code = p[i] & BMASK) == 0 || k > nfonts) { 891f92359bfSslatteng #ifdef DEBUGABLE 892f92359bfSslatteng if (dbg) fprintf(stderr,"not found 0%o\n", c+32); 893f92359bfSslatteng #endif 894f92359bfSslatteng return; 895f92359bfSslatteng } 896f92359bfSslatteng #ifdef DEBUGABLE 897f92359bfSslatteng if (dbg) { 898f92359bfSslatteng if (isprint(c+32)) 899f92359bfSslatteng fprintf(stderr,"%c %d\n", c+32, code); 900f92359bfSslatteng else 901f92359bfSslatteng fprintf(stderr,"%03o %d\n", c+32, code); 902f92359bfSslatteng } 903f92359bfSslatteng #endif 904f92359bfSslatteng outc(code); /* character is < 254 */ 905f92359bfSslatteng if (font != ofont) 906f92359bfSslatteng setfont(ofont); 9074da297a9Sslatteng lastw = ((pw[i]&077) * pstab[size] + dev.unitwidth/2) / dev.unitwidth; 908f92359bfSslatteng } 909f92359bfSslatteng 910f92359bfSslatteng 911f92359bfSslatteng 912f92359bfSslatteng setsize(n) /* set point size to n (internal) */ 913f92359bfSslatteng int n; 914f92359bfSslatteng { 915f92359bfSslatteng 916f92359bfSslatteng if (n == size) 917f92359bfSslatteng return; /* already there */ 9184da297a9Sslatteng if (vloadfont(font, pstab[n]) != -1) 919f92359bfSslatteng size = n; 920f92359bfSslatteng } 921f92359bfSslatteng 922f92359bfSslatteng t_fp(n, s, si) /* font position n now contains font s, intname si */ 923*1c9df754Sslatteng int n; /* internal name is ignored */ 924f92359bfSslatteng char *s, *si; 925f92359bfSslatteng { 9264da297a9Sslatteng register int i; 927f92359bfSslatteng 9284da297a9Sslatteng 9294da297a9Sslatteng /* first convert s to filename if possible */ 9304da297a9Sslatteng for (i = 0; fontmap[i].ffile != (char *) 0; i++) { 9314da297a9Sslatteng #ifdef DEBUGABLE 9324da297a9Sslatteng if(dbg>1)fprintf(stderr,"testing :%s:%s:\n",s,fontmap[i].fname); 9334da297a9Sslatteng #endif 9344da297a9Sslatteng if (strcmp(s, fontmap[i].fname) == 0) { 9354da297a9Sslatteng s = fontmap[i].ffile; 9364da297a9Sslatteng #ifdef DEBUGABLE 9374da297a9Sslatteng if(dbg)fprintf(stderr, "found :%s:\n",fontmap[i].ffile); 9384da297a9Sslatteng #endif 9394da297a9Sslatteng break; 9404da297a9Sslatteng } 9414da297a9Sslatteng } 942*1c9df754Sslatteng fontname[n] = s; 943f92359bfSslatteng for(i = 0;i < NFONTS;i++) /* free the bits of that font */ 944f92359bfSslatteng if (fontdes[i].fnum == n){ 945f92359bfSslatteng nfree(fontdes[i].bits); 946f92359bfSslatteng fontdes[i].bits = 0; 947f92359bfSslatteng fontdes[i].fnum = -1; 948f92359bfSslatteng } 949f92359bfSslatteng } 950f92359bfSslatteng 9514da297a9Sslatteng 952f92359bfSslatteng setfont(n) /* set font to n */ 953f92359bfSslatteng int n; 954f92359bfSslatteng { 955f92359bfSslatteng if (n < 0 || n > NFONTS) 956ebd02298Sslatteng error(FATAL, "illegal font %d", n); 9574da297a9Sslatteng if (vloadfont(n,pstab[size]) != -1) 958f92359bfSslatteng font = n; 959f92359bfSslatteng } 960f92359bfSslatteng 961f92359bfSslatteng vloadfont(fnum, fsize) 962f92359bfSslatteng register int fnum; 963f92359bfSslatteng register int fsize; 964f92359bfSslatteng { 965f92359bfSslatteng register int i; 966f92359bfSslatteng 967f92359bfSslatteng fontwanted = 0; 968f92359bfSslatteng if (fnum == cfnum && fsize == cpsize) 969f92359bfSslatteng return(0); 970f92359bfSslatteng for (i = 0; i < NFONTS; i++) { 971f92359bfSslatteng if (fontdes[i].fnum == fnum && fontdes[i].psize == fsize) { 972f92359bfSslatteng cfnum = fontdes[i].fnum; 973f92359bfSslatteng cpsize = fontdes[i].psize; 974f92359bfSslatteng dispatch = &fontdes[i].disp[0]; 975f92359bfSslatteng bits = fontdes[i].bits; 976f92359bfSslatteng cfont = i; 977f92359bfSslatteng return (0); 978f92359bfSslatteng } 979f92359bfSslatteng } 980f92359bfSslatteng /* this is a new font */ 981*1c9df754Sslatteng if (fnum < 0 || fnum > NFONTS || fontname[fnum] == 0) { 982f92359bfSslatteng fprintf(stderr, "Internal error: illegal font %d name %s size\n", 983*1c9df754Sslatteng fontname[fnum], fnum, fsize); 984f92359bfSslatteng return(-1); 985f92359bfSslatteng } 986f92359bfSslatteng /* Need to verify the existance of that font/size here*/ 987f92359bfSslatteng nfontnum = fnum; 988f92359bfSslatteng npsize = fsize; 989f92359bfSslatteng fontwanted++; 990f92359bfSslatteng return (0); 991f92359bfSslatteng } 992f92359bfSslatteng 993f92359bfSslatteng 994f92359bfSslatteng getfont() 995f92359bfSslatteng { 9964da297a9Sslatteng register int fnum; 9974da297a9Sslatteng register int fsize; 9984da297a9Sslatteng register int fontd; 9994da297a9Sslatteng register int d; 1000*1c9df754Sslatteng register int sizehunt = size; 1001f92359bfSslatteng char cbuf[BUFSIZ]; 1002f92359bfSslatteng 1003f92359bfSslatteng fnum = nfontnum; 1004f92359bfSslatteng fsize = npsize; 10054da297a9Sslatteng /* try to open font file - if unsuccessful, hunt for */ 10064da297a9Sslatteng /* a file of same style, different size to substitute */ 10074da297a9Sslatteng d = -1; /* direction to look in pstab (smaller first) */ 10084da297a9Sslatteng do { 1009*1c9df754Sslatteng sprintf(cbuf, "%s/%s.%dr", bitdir, fontname[fnum], fsize); 1010f92359bfSslatteng fontd = open(cbuf, OPENREAD); 10114da297a9Sslatteng if (fontd == -1) { /* File wasn't found. Try another ps */ 1012*1c9df754Sslatteng sizehunt += d; 1013*1c9df754Sslatteng if (sizehunt < 0) { /* past beginning - look higher */ 10144da297a9Sslatteng d = 1; 1015*1c9df754Sslatteng sizehunt = size + 1; 10164da297a9Sslatteng } 1017*1c9df754Sslatteng if (sizehunt > nsizes) { /* past top - forget it */ 10184da297a9Sslatteng d = 0; 10194da297a9Sslatteng } else { 1020*1c9df754Sslatteng fsize = pstab[sizehunt]; 10214da297a9Sslatteng } 10224da297a9Sslatteng } 10234da297a9Sslatteng } while (fontd == -1 && d != 0); 10244da297a9Sslatteng 10254da297a9Sslatteng if (fontd == -1) { /* completely unsuccessful */ 1026f92359bfSslatteng perror(cbuf); 10274da297a9Sslatteng error(!FATAL,"fnum = %d, psize = %d, name = %s", 1028*1c9df754Sslatteng fnum, npsize, fontname[fnum]); 1029f92359bfSslatteng fontwanted = 0; 1030f92359bfSslatteng return (-1); 1031f92359bfSslatteng } 1032f92359bfSslatteng if (read(fontd, &header, sizeof (header)) != sizeof (header) 1033f92359bfSslatteng || header.magic != 0436) 1034f92359bfSslatteng fprintf(stderr, "%s: Bad font file", cbuf); 1035f92359bfSslatteng else { 1036f92359bfSslatteng cfont = relfont(); 1037f92359bfSslatteng if ((bits=nalloc(header.size+DSIZ+1,1))== NULL) 1038f92359bfSslatteng if ((bits=allpanic(header.size+DSIZ+1))== NULL) { 1039*1c9df754Sslatteng error(FATAL,"%s: ran out of memory", cbuf); 1040f92359bfSslatteng } 1041f92359bfSslatteng 1042f92359bfSslatteng /* 1043f92359bfSslatteng * have allocated one chunk of mem for font, dispatch. 1044f92359bfSslatteng * get the dispatch addr, align to word boundary. 1045f92359bfSslatteng */ 1046f92359bfSslatteng 1047f92359bfSslatteng d = (int) bits+header.size; 1048f92359bfSslatteng d += 1; 1049f92359bfSslatteng d &= ~1; 1050f92359bfSslatteng if (read (fontd, d, DSIZ) != DSIZ 1051f92359bfSslatteng || read (fontd, bits, header.size) != header.size) 1052f92359bfSslatteng fprintf(stderr, "bad font header"); 1053f92359bfSslatteng else { 1054f92359bfSslatteng close(fontd); 1055f92359bfSslatteng cfnum = fontdes[cfont].fnum = fnum; 1056f92359bfSslatteng cpsize = fontdes[cfont].psize = fsize; 1057f92359bfSslatteng fontdes [cfont].bits = bits; 1058f92359bfSslatteng fontdes [cfont].disp = (struct dispatch *) d; 1059f92359bfSslatteng dispatch = &fontdes[cfont].disp[0]; 1060f92359bfSslatteng fontwanted = 0; 1061f92359bfSslatteng return (0); 1062f92359bfSslatteng } 1063f92359bfSslatteng } 1064f92359bfSslatteng close(fontd); 1065f92359bfSslatteng fontwanted = 0; 1066f92359bfSslatteng return(-1); 1067f92359bfSslatteng } 1068f92359bfSslatteng 1069f92359bfSslatteng /* 1070f92359bfSslatteng * "release" a font position - find an empty one, if possible 1071f92359bfSslatteng */ 1072f92359bfSslatteng 1073f92359bfSslatteng relfont() 1074f92359bfSslatteng { 1075f92359bfSslatteng register int newfont; 1076f92359bfSslatteng 1077f92359bfSslatteng for (newfont = 0; newfont < NFONTS; newfont++) 1078f92359bfSslatteng if (fontdes [newfont].bits == (char *) -1 || !fontdes [newfont].bits) 1079f92359bfSslatteng break; 1080f92359bfSslatteng if (fontdes [newfont].bits != (char *) -1 && fontdes [newfont].bits) { 1081f92359bfSslatteng nfree (fontdes [newfont].bits); 1082f92359bfSslatteng fontdes [newfont].bits = (char *)0; 1083f92359bfSslatteng #ifdef DEBUGABLE 1084f92359bfSslatteng if (dbg) fprintf (stderr, "freeing position %d\n", newfont); 1085f92359bfSslatteng } else { 1086f92359bfSslatteng if (dbg) 1087f92359bfSslatteng fprintf (stderr, "taking, not freeing, position %d\n", newfont); 1088f92359bfSslatteng #endif 1089f92359bfSslatteng } 1090f92359bfSslatteng fontdes[newfont].bits = 0; 1091f92359bfSslatteng return (newfont); 1092f92359bfSslatteng } 1093f92359bfSslatteng 1094f92359bfSslatteng char *allpanic (nbytes) 1095f92359bfSslatteng int nbytes; 1096f92359bfSslatteng { 1097f92359bfSslatteng register int i; 1098f92359bfSslatteng 1099f92359bfSslatteng for (i = 0; i <= NFONTS; i++) 1100f92359bfSslatteng if (fontdes[i].bits != (char *)-1 && fontdes[i].bits != (char *)0) 1101f92359bfSslatteng nfree(fontdes[i].bits); 1102f92359bfSslatteng for (i = 0; i <= NFONTS; i++) { 1103f92359bfSslatteng fontdes[i].fnum = fontdes[i].psize = -1; 1104f92359bfSslatteng fontdes[i].bits = 0; 1105f92359bfSslatteng cfnum = cpsize = -1; 1106f92359bfSslatteng } 1107f92359bfSslatteng return(nalloc(nbytes,1)); 1108f92359bfSslatteng } 1109f92359bfSslatteng 1110f92359bfSslatteng int M[] = { 0xffffffff, 0xfefefefe, 0xfcfcfcfc, 0xf8f8f8f8, 1111f92359bfSslatteng 0xf0f0f0f0, 0xe0e0e0e0, 0xc0c0c0c0, 0x80808080, 0x0 }; 1112f92359bfSslatteng int N[] = { 0x00000000, 0x01010101, 0x03030303, 0x07070707, 1113f92359bfSslatteng 0x0f0f0f0f, 0x1f1f1f1f, 0x3f3f3f3f, 0x7f7f7f7f, 0xffffffff }; 1114f92359bfSslatteng int strim[] = { 0xffffffff, 0xffffff00, 0xffff0000, 0xff000000, 0 }; 1115f92359bfSslatteng 1116f92359bfSslatteng outc(code) 1117f92359bfSslatteng int code; /* character to print */ 1118f92359bfSslatteng { 1119f92359bfSslatteng register struct dispatch *dis; /* ptr to character font record */ 1120f92359bfSslatteng register char *addr; /* addr of font data */ 1121f92359bfSslatteng int llen; /* length of each font line */ 1122f92359bfSslatteng int nlines; /* number of font lines */ 1123f92359bfSslatteng register char *scanp; /* ptr to output buffer */ 1124f92359bfSslatteng int scanp_inc; /* increment to start of next buffer */ 1125f92359bfSslatteng int offset; /* bit offset to start of font data */ 11264da297a9Sslatteng register int i; /* loop counter */ 1127f92359bfSslatteng register int count; /* font data ptr */ 1128f92359bfSslatteng register unsigned fontdata; /* font data temporary */ 1129f92359bfSslatteng register int off8; /* offset + 8 */ 1130f92359bfSslatteng 1131f92359bfSslatteng if (fontwanted) 1132f92359bfSslatteng getfont(); 1133f92359bfSslatteng dis = dispatch + code; 1134f92359bfSslatteng if (dis->nbytes) { 1135f92359bfSslatteng addr = bits + dis->addr; 11361a4ecc79Sslatteng llen = (dis->up + dis->down + 7) >> 3; 11371a4ecc79Sslatteng nlines = dis->right + dis->left; 11381a4ecc79Sslatteng scanp = buf0p + (hpos - dis->left) * BYTES_PER_LINE 11391a4ecc79Sslatteng - (1 + ((dis->down + vpos) >> 3)); 1140f92359bfSslatteng if (scanp < &buffer[0]) 1141f92359bfSslatteng scanp += sizeof buffer; 1142f92359bfSslatteng scanp_inc = BYTES_PER_LINE - llen; 11431a4ecc79Sslatteng off8 = ((dis->down + vpos) &07); 11441a4ecc79Sslatteng offset = off8 - 8; 1145f92359bfSslatteng for (i = 0; i < nlines; i++) { 1146f92359bfSslatteng if (scanp >= &buffer[BUFFER_SIZE]) 1147*1c9df754Sslatteng scanp -= BUFFER_SIZE; 1148f92359bfSslatteng count = llen; 1149*1c9df754Sslatteng if (scanp + count < &buffer[BUFFER_SIZE]) { 1150f92359bfSslatteng do { 1151f92359bfSslatteng fontdata = *(unsigned *)addr; 1152f92359bfSslatteng addr += 4; 1153f92359bfSslatteng if (count < 4) 1154f92359bfSslatteng fontdata &= ~strim[count]; 1155f92359bfSslatteng *(unsigned*)scanp |=(fontdata << offset) & ~M[off8]; 1156f92359bfSslatteng scanp++; 1157f92359bfSslatteng *(unsigned*)scanp |=(fontdata << off8) & ~N[off8]; 1158f92359bfSslatteng scanp += 3; 1159f92359bfSslatteng count -= 4; 1160f92359bfSslatteng } while (count > 0); 1161f92359bfSslatteng } 1162f92359bfSslatteng scanp += scanp_inc+count; 1163f92359bfSslatteng addr += count; 1164f92359bfSslatteng } 1165f92359bfSslatteng return; 1166f92359bfSslatteng } 1167f92359bfSslatteng return; 1168f92359bfSslatteng } 1169f92359bfSslatteng 1170f92359bfSslatteng slop_lines(nlines) 1171f92359bfSslatteng int nlines; 1172f92359bfSslatteng 1173f92359bfSslatteng /* Output "nlines" lines from the buffer, and clear that section of the */ 1174f92359bfSslatteng /* buffer. */ 1175f92359bfSslatteng 1176f92359bfSslatteng { 1177f92359bfSslatteng unsigned usize; 1178f92359bfSslatteng 1179f92359bfSslatteng usize = BYTES_PER_LINE * nlines; 11804da297a9Sslatteng vwrite(buf0p, usize); 1181f92359bfSslatteng vclear(buf0p, usize); 1182*1c9df754Sslatteng #ifdef DRIVER 1183f92359bfSslatteng ioctl(OUTFILE, VSETSTATE, pltmode); 1184*1c9df754Sslatteng #endif 1185f92359bfSslatteng } 1186f92359bfSslatteng 11874da297a9Sslatteng vwrite(buf,usize) 1188f92359bfSslatteng char *buf; 1189f92359bfSslatteng unsigned usize; 1190f92359bfSslatteng { 1191f92359bfSslatteng register int tsize = 0; 1192f92359bfSslatteng 1193f92359bfSslatteng while (usize){ 1194f92359bfSslatteng buf += tsize; 1195f92359bfSslatteng tsize = usize > MAXWRIT ? MAXWRIT : usize; 1196f92359bfSslatteng #ifdef DEBUGABLE 1197f92359bfSslatteng if (dbg)fprintf(stderr,"buf = %d size = %d\n",buf,tsize); 1198f92359bfSslatteng #endif 1199f92359bfSslatteng if ((tsize = write(OUTFILE, buf, tsize)) < 0) { 1200ebd02298Sslatteng perror("dvar: write failed"); 1201f92359bfSslatteng exit(RESTART); 1202f92359bfSslatteng } 1203f92359bfSslatteng usize -= tsize; 1204f92359bfSslatteng } 1205f92359bfSslatteng } 1206f92359bfSslatteng 1207f92359bfSslatteng vclear (ptr, nbytes) 1208f92359bfSslatteng char *ptr; 1209f92359bfSslatteng unsigned nbytes; 1210f92359bfSslatteng { 1211f92359bfSslatteng register tsize = 0; 1212f92359bfSslatteng 1213f92359bfSslatteng while (nbytes){ 1214f92359bfSslatteng if ((unsigned)(16*1024) < nbytes) { 1215f92359bfSslatteng tsize = 16 * 1024; 1216f92359bfSslatteng } else 1217f92359bfSslatteng tsize = nbytes; 1218f92359bfSslatteng nbytes -= tsize; 1219f92359bfSslatteng #ifdef DEBUGABLE 1220f92359bfSslatteng if (dbg) fprintf(stderr,"clearing ptr = %d size = %d\n",ptr,tsize); 1221f92359bfSslatteng #endif 1222f92359bfSslatteng clear(ptr,tsize); 1223f92359bfSslatteng ptr += tsize; 1224f92359bfSslatteng } 1225f92359bfSslatteng } 1226f92359bfSslatteng 1227f92359bfSslatteng /*ARGSUSED*/ 1228f92359bfSslatteng clear(lp, nbytes) 1229f92359bfSslatteng int *lp; 1230f92359bfSslatteng int nbytes; 1231f92359bfSslatteng { 1232f92359bfSslatteng asm("movc5 $0,(sp),$0,8(ap),*4(ap)"); 1233f92359bfSslatteng } 1234f92359bfSslatteng 1235f92359bfSslatteng char * 1236f92359bfSslatteng nalloc(i, j) 1237f92359bfSslatteng int i, j; 1238f92359bfSslatteng { 1239f92359bfSslatteng register char *cp; 1240f92359bfSslatteng 1241f92359bfSslatteng cp = calloc(i, j); 1242f92359bfSslatteng #ifdef DEBUGABLE 1243f92359bfSslatteng if (dbg) fprintf(stderr, "allocated %d bytes at %x\n", i * j, cp); 1244f92359bfSslatteng #endif 1245f92359bfSslatteng return(cp); 1246f92359bfSslatteng } 1247f92359bfSslatteng 1248f92359bfSslatteng nfree(cp) 1249f92359bfSslatteng char *cp; 1250f92359bfSslatteng { 1251f92359bfSslatteng #ifdef DEBUGABLE 1252f92359bfSslatteng if (dbg) fprintf(stderr, "freeing at %x\n", cp); 1253f92359bfSslatteng #endif 1254f92359bfSslatteng free(cp); 1255f92359bfSslatteng } 1256f92359bfSslatteng 1257f92359bfSslatteng 1258f92359bfSslatteng /* 1259f92359bfSslatteng * Points should be in the range 0 <= x < RASTER_LENGTH, 0 <= y < NLINES. 1260f92359bfSslatteng * The origin is the top left-hand corner with increasing x towards the 12614da297a9Sslatteng * right and increasing y going down. X and Y should be sent as (0,0) being 12624da297a9Sslatteng * at the bottom left. The output array is NLINES x BYTES_PER_LINE pixels. 1263f92359bfSslatteng */ 1264f92359bfSslatteng point(x, y) 12651a4ecc79Sslatteng register int x; 12661a4ecc79Sslatteng register int y; 1267f92359bfSslatteng { 12681a4ecc79Sslatteng if ((unsigned)(y=RASTER_LENGTH-y) < RASTER_LENGTH && (unsigned)x < NLINES) { 12691a4ecc79Sslatteng buffer [x * BYTES_PER_LINE + (y >> 3)] |= 1 << (7 - (y & 07)); 1270f92359bfSslatteng } 1271f92359bfSslatteng } 1272