1*1a4ecc79Sslatteng /* dvar.c 1.2 83/07/09 2f92359bfSslatteng * 3f92359bfSslatteng * Varian driver for the new troff 4f92359bfSslatteng * 5f92359bfSslatteng * Authors: BWK(BELL) 6f92359bfSslatteng * VCAT(berkley) 7f92359bfSslatteng * Richard L. Hyde, Perdue University 8f92359bfSslatteng * and David Slattengren, 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 63f92359bfSslatteng #define DEBUGABLE /* Yes, debugable... */ 64f92359bfSslatteng #define NFONTS 25 /* total number of fonts useable */ 65f92359bfSslatteng #define MAXSTATE 6 /* number of environments rememberable */ 66f92359bfSslatteng #define OPENREAD 0 /* mode for openning files */ 67f92359bfSslatteng #define RESTART 1 /* upon exit, return either RESTART */ 68f92359bfSslatteng #define ABORT 2 /* or ABORT */ 69f92359bfSslatteng #define FATAL 1 /* type of error */ 70f92359bfSslatteng #define BMASK 0377 /* byte grabber */ 71f92359bfSslatteng #define FONTDIR "/usr/lib/font" /* default place to look for fonts */ 72f92359bfSslatteng #define MAXWRIT 4096 /* max characters allowed to write at once */ 73f92359bfSslatteng 74f92359bfSslatteng #define hmot(n) hpos += n 75f92359bfSslatteng #define hgoto(n) hpos = n 76f92359bfSslatteng #define vmot(n) vgoto(vpos + n) 77f92359bfSslatteng 78f92359bfSslatteng 79*1a4ecc79Sslatteng char SccsId[]= "dvar.c 1.2 83/07/09"; 80f92359bfSslatteng 81f92359bfSslatteng int output = 0; /* do we do output at all? */ 82f92359bfSslatteng int nolist = 0; /* output page list if > 0 */ 83f92359bfSslatteng int olist[20]; /* pairs of page numbers */ 84f92359bfSslatteng int spage = 9999; /* stop every spage pages */ 85f92359bfSslatteng int scount = 0; 86f92359bfSslatteng struct dev dev; 87f92359bfSslatteng struct font *fontbase[NFONTS+1]; 88f92359bfSslatteng short *pstab; /* point size table pointer */ 89f92359bfSslatteng int res; /* input was computed according to this resolution */ 90f92359bfSslatteng int nsizes; /* number of sizes device is capable of printing */ 91f92359bfSslatteng int nfonts; /* number of fonts device is capable of printing */ 92f92359bfSslatteng int smnt; /* index of first special font */ 93f92359bfSslatteng int nchtab; 94f92359bfSslatteng char *chname; 95f92359bfSslatteng short *chtab; 96f92359bfSslatteng char *fitab[NFONTS+1]; 97f92359bfSslatteng char *widtab[NFONTS+1]; 98f92359bfSslatteng char *codetab[NFONTS+1]; /* device codes */ 99f92359bfSslatteng char *fontdir = FONTDIR; 100f92359bfSslatteng struct { /* table of what font */ 101f92359bfSslatteng char *name; /* name is on what */ 102f92359bfSslatteng int number; /* position in font tables */ 103f92359bfSslatteng } fontname[NFONTS+1]; 104f92359bfSslatteng 105f92359bfSslatteng #ifdef DEBUGABLE 106f92359bfSslatteng int dbg = 0; 107f92359bfSslatteng #endif 108f92359bfSslatteng int maxH; /* farthest down we've been on the current page */ 109f92359bfSslatteng int size = -1; /* current point size being use */ 110f92359bfSslatteng int font = -1; /* current font - not using any to start with */ 111f92359bfSslatteng int hpos; /* horizontal position we are to be at next; left = 0 */ 112f92359bfSslatteng int vpos; /* current vertical position (down positive) */ 113f92359bfSslatteng int horig; /* h origin of current block (just a marker) */ 114f92359bfSslatteng int vorig; /* v origin of current block (just a marker) */ 115f92359bfSslatteng int lastw; /* width of last character printed */ 116f92359bfSslatteng 117f92359bfSslatteng 118f92359bfSslatteng #define DISPATCHSIZE 256 /* must be a power of two */ 119f92359bfSslatteng #define CHARMASK (DISPATCHSIZE-1) 120f92359bfSslatteng #define DSIZ ((sizeof *dispatch)*DISPATCHSIZE) 121f92359bfSslatteng #define OUTFILE fileno (stdout) 122f92359bfSslatteng #define RES 200 /* resolution of the device */ 123f92359bfSslatteng #define TRAILER (10 * RES) /* position of trailer */ 124f92359bfSslatteng 125*1a4ecc79Sslatteng #define RASTER_LENGTH 2112 /* device line length */ 126f92359bfSslatteng #define BYTES_PER_LINE (RASTER_LENGTH/8) 127*1a4ecc79Sslatteng #define NLINES 1600 /* device page width */ 128f92359bfSslatteng #define BUFFER_SIZE (NLINES*BYTES_PER_LINE) /* number of chars in picture */ 129f92359bfSslatteng 130f92359bfSslatteng 131f92359bfSslatteng int pltmode[] = { VPLOT }; 132f92359bfSslatteng int prtmode[] = { VPRINT }; 133f92359bfSslatteng char buffer[BUFFER_SIZE]; /* Big line buffers */ 134f92359bfSslatteng char *buf0p = &buffer[0]; /* Zero origin in circular buffer */ 135f92359bfSslatteng 136f92359bfSslatteng char *calloc(); 137f92359bfSslatteng char *nalloc(); 138f92359bfSslatteng char *allpanic(); 139f92359bfSslatteng 140f92359bfSslatteng struct header { 141f92359bfSslatteng short magic; 142f92359bfSslatteng unsigned short size; 143f92359bfSslatteng short maxx; 144f92359bfSslatteng short maxy; 145f92359bfSslatteng short xtnd; 146f92359bfSslatteng } header; 147f92359bfSslatteng 148f92359bfSslatteng struct dispatch{ 149f92359bfSslatteng unsigned short addr; 150f92359bfSslatteng short nbytes; 151f92359bfSslatteng char up; 152f92359bfSslatteng char down; 153f92359bfSslatteng char left; 154f92359bfSslatteng char right; 155f92359bfSslatteng short width; 156f92359bfSslatteng }; 157f92359bfSslatteng 158f92359bfSslatteng struct fontdes { 159f92359bfSslatteng int fnum; 160f92359bfSslatteng int psize; 161f92359bfSslatteng struct dispatch *disp; 162f92359bfSslatteng char *bits; 163f92359bfSslatteng } fontdes[NFONTS] = { 164f92359bfSslatteng -1, 165f92359bfSslatteng -1 166f92359bfSslatteng }; 167f92359bfSslatteng 168f92359bfSslatteng struct dispatch *dispatch; 169f92359bfSslatteng int cfnum = -1; 170f92359bfSslatteng int cpsize = 10; 171f92359bfSslatteng int cfont = 1; 172f92359bfSslatteng char *bits; 173f92359bfSslatteng int fontwanted = 1; /* flag: "has a new font been requested?" */ 174f92359bfSslatteng int nfontnum = -1; 175f92359bfSslatteng int npsize = 10; 176f92359bfSslatteng 177f92359bfSslatteng 178f92359bfSslatteng 179f92359bfSslatteng main(argc, argv) 180f92359bfSslatteng char *argv[]; 181f92359bfSslatteng { 182f92359bfSslatteng FILE *fp; 183f92359bfSslatteng int done(); 184f92359bfSslatteng 185f92359bfSslatteng while (argc > 1 && argv[1][0] == '-') { 186f92359bfSslatteng switch (argv[1][1]) { 187f92359bfSslatteng case 'f': 188f92359bfSslatteng case 'F': 189f92359bfSslatteng fontdir = argv[2]; 190f92359bfSslatteng argv++; 191f92359bfSslatteng argc--; 192f92359bfSslatteng break; 193f92359bfSslatteng case 'o': 194f92359bfSslatteng outlist(&argv[1][2]); 195f92359bfSslatteng break; 196f92359bfSslatteng #ifdef DEBUGABLE 197f92359bfSslatteng case 'd': 198f92359bfSslatteng dbg = atoi(&argv[1][2]); 199f92359bfSslatteng if (dbg == 0) dbg = 1; 200f92359bfSslatteng break; 201f92359bfSslatteng #endif 202f92359bfSslatteng case 's': 203f92359bfSslatteng spage = atoi(&argv[1][2]); 204f92359bfSslatteng if (spage <= 0) 205f92359bfSslatteng spage = 9999; 206f92359bfSslatteng break; 207f92359bfSslatteng } 208f92359bfSslatteng argc--; 209f92359bfSslatteng argv++; 210f92359bfSslatteng } 211f92359bfSslatteng 212f92359bfSslatteng /* noversatec 213f92359bfSslatteng ioctl(OUTFILE, VSETSTATE, pltmode); 214f92359bfSslatteng noversatec */ 215f92359bfSslatteng 216f92359bfSslatteng if (argc <= 1) 217f92359bfSslatteng conv(stdin); 218f92359bfSslatteng else 219f92359bfSslatteng while (--argc > 0) { 220f92359bfSslatteng if (strcmp(*++argv, "-") == 0) 221f92359bfSslatteng fp = stdin; 222f92359bfSslatteng else if ((fp = fopen(*argv, "r")) == NULL) 223f92359bfSslatteng error(FATAL, "can't open %s", *argv); 224f92359bfSslatteng conv(fp); 225f92359bfSslatteng fclose(fp); 226f92359bfSslatteng } 227f92359bfSslatteng done(); 228f92359bfSslatteng exit(0); 229f92359bfSslatteng } 230f92359bfSslatteng 231f92359bfSslatteng outlist(s) /* process list of page numbers to be printed */ 232f92359bfSslatteng char *s; 233f92359bfSslatteng { 234f92359bfSslatteng int n1, n2, i; 235f92359bfSslatteng 236f92359bfSslatteng nolist = 0; 237f92359bfSslatteng while (*s) { 238f92359bfSslatteng n1 = 0; 239f92359bfSslatteng if (isdigit(*s)) 240f92359bfSslatteng do 241f92359bfSslatteng n1 = 10 * n1 + *s++ - '0'; 242f92359bfSslatteng while (isdigit(*s)); 243f92359bfSslatteng else 244f92359bfSslatteng n1 = -9999; 245f92359bfSslatteng n2 = n1; 246f92359bfSslatteng if (*s == '-') { 247f92359bfSslatteng s++; 248f92359bfSslatteng n2 = 0; 249f92359bfSslatteng if (isdigit(*s)) 250f92359bfSslatteng do 251f92359bfSslatteng n2 = 10 * n2 + *s++ - '0'; 252f92359bfSslatteng while (isdigit(*s)); 253f92359bfSslatteng else 254f92359bfSslatteng n2 = 9999; 255f92359bfSslatteng } 256f92359bfSslatteng olist[nolist++] = n1; 257f92359bfSslatteng olist[nolist++] = n2; 258f92359bfSslatteng if (*s != '\0') 259f92359bfSslatteng s++; 260f92359bfSslatteng } 261f92359bfSslatteng olist[nolist] = 0; 262f92359bfSslatteng #ifdef DEBUGABLE 263f92359bfSslatteng if (dbg) 264f92359bfSslatteng for (i=0; i<nolist; i += 2) 265f92359bfSslatteng fprintf(stderr,"%3d %3d\n", olist[i], olist[i+1]); 266f92359bfSslatteng #endif 267f92359bfSslatteng } 268f92359bfSslatteng 269f92359bfSslatteng conv(fp) 270f92359bfSslatteng register FILE *fp; 271f92359bfSslatteng { 272f92359bfSslatteng register int c, k; 273f92359bfSslatteng int m, n, n1, m1; 274f92359bfSslatteng char str[100], buf[300]; 275f92359bfSslatteng 276f92359bfSslatteng while ((c = getc(fp)) != EOF) { 277f92359bfSslatteng switch (c) { 278f92359bfSslatteng case '\n': /* when input is text */ 279f92359bfSslatteng case ' ': 280f92359bfSslatteng case 0: /* occasional noise creeps in */ 281f92359bfSslatteng break; 282f92359bfSslatteng case '{': /* push down current environment */ 283f92359bfSslatteng t_push(); 284f92359bfSslatteng break; 285f92359bfSslatteng case '}': 286f92359bfSslatteng t_pop(); 287f92359bfSslatteng break; 288f92359bfSslatteng case '0': case '1': case '2': case '3': case '4': 289f92359bfSslatteng case '5': case '6': case '7': case '8': case '9': 290f92359bfSslatteng /* two motion digits plus a character */ 291f92359bfSslatteng hmot((c-'0')*10 + getc(fp)-'0'); 292f92359bfSslatteng put1(getc(fp)); 293f92359bfSslatteng break; 294f92359bfSslatteng case 'c': /* single ascii character */ 295f92359bfSslatteng put1(getc(fp)); 296f92359bfSslatteng break; 297f92359bfSslatteng case 'C': 298f92359bfSslatteng fscanf(fp, "%s", str); 299f92359bfSslatteng put1s(str); 300f92359bfSslatteng break; 301f92359bfSslatteng case 't': /* straight text */ 302f92359bfSslatteng fgets(buf, sizeof(buf), fp); 303f92359bfSslatteng t_text(buf); 304f92359bfSslatteng break; 305f92359bfSslatteng case 'D': /* draw function */ 306f92359bfSslatteng fgets(buf, sizeof(buf), fp); 307f92359bfSslatteng switch (buf[0]) { 308f92359bfSslatteng case 'l': /* draw a line */ 309f92359bfSslatteng sscanf(buf+1, "%d %d", &n, &m); 310f92359bfSslatteng drawline(n, m); 311f92359bfSslatteng break; 312f92359bfSslatteng case 'c': /* circle */ 313f92359bfSslatteng sscanf(buf+1, "%d", &n); 314f92359bfSslatteng drawcirc(n); 315f92359bfSslatteng break; 316f92359bfSslatteng case 'e': /* ellipse */ 317f92359bfSslatteng sscanf(buf+1, "%d %d", &m, &n); 318f92359bfSslatteng drawellip(m, n); 319f92359bfSslatteng break; 320f92359bfSslatteng case 'a': /* arc */ 321f92359bfSslatteng sscanf(buf+1, "%d %d %d %d", &n, &m, &n1, &m1); 322f92359bfSslatteng drawarc(n, m, n1, m1); 323f92359bfSslatteng break; 324f92359bfSslatteng case '~': /* wiggly line */ 325*1a4ecc79Sslatteng case 'g': /* gremlin spline */ 326*1a4ecc79Sslatteng drawwig(buf+1, fp, buf[0] == '~'); 327*1a4ecc79Sslatteng break; 328*1a4ecc79Sslatteng case 't': /* line thickness */ 329*1a4ecc79Sslatteng sscanf(buf+1, "%d", &n); 330*1a4ecc79Sslatteng drawthick(n); 331*1a4ecc79Sslatteng break; 332*1a4ecc79Sslatteng case 's': /* line style */ 333*1a4ecc79Sslatteng sscanf(buf+1, "%d", &n); 334*1a4ecc79Sslatteng drawstyle(n); 335f92359bfSslatteng break; 336f92359bfSslatteng default: 337f92359bfSslatteng error(FATAL, "unknown drawing function %s\n", buf); 338f92359bfSslatteng break; 339f92359bfSslatteng } 340f92359bfSslatteng break; 341f92359bfSslatteng case 's': 342f92359bfSslatteng fscanf(fp, "%d", &n); /* ignore fractional sizes */ 343f92359bfSslatteng setsize(t_size(n)); 344f92359bfSslatteng break; 345f92359bfSslatteng case 'f': 346f92359bfSslatteng fscanf(fp, "%s", str); 347f92359bfSslatteng setfont(t_font(str)); 348f92359bfSslatteng break; 349f92359bfSslatteng case 'H': /* absolute horizontal motion */ 350f92359bfSslatteng /* fscanf(fp, "%d", &n); */ 351f92359bfSslatteng while ((c = getc(fp)) == ' ') 352f92359bfSslatteng ; 353f92359bfSslatteng k = 0; 354f92359bfSslatteng do { 355f92359bfSslatteng k = 10 * k + c - '0'; 356f92359bfSslatteng } while (isdigit(c = getc(fp))); 357f92359bfSslatteng ungetc(c, fp); 358f92359bfSslatteng hgoto(k); 359f92359bfSslatteng break; 360f92359bfSslatteng case 'h': /* relative horizontal motion */ 361f92359bfSslatteng while ((c = getc(fp)) == ' ') 362f92359bfSslatteng ; 363f92359bfSslatteng k = 0; 364f92359bfSslatteng do { 365f92359bfSslatteng k = 10 * k + c - '0'; 366f92359bfSslatteng } while (isdigit(c = getc(fp))); 367f92359bfSslatteng ungetc(c, fp); 368f92359bfSslatteng hmot(k); 369f92359bfSslatteng break; 370f92359bfSslatteng case 'w': /* word space */ 371f92359bfSslatteng break; 372f92359bfSslatteng case 'V': 373f92359bfSslatteng fscanf(fp, "%d", &n); 374f92359bfSslatteng vgoto(n); 375f92359bfSslatteng break; 376f92359bfSslatteng case 'v': 377f92359bfSslatteng fscanf(fp, "%d", &n); 378f92359bfSslatteng vmot(n); 379f92359bfSslatteng break; 380f92359bfSslatteng case 'p': /* new page */ 381f92359bfSslatteng fscanf(fp, "%d", &n); 382f92359bfSslatteng t_page(n); 383f92359bfSslatteng break; 384f92359bfSslatteng case 'n': /* end of line */ 385f92359bfSslatteng while (getc(fp) != '\n') 386f92359bfSslatteng ; 387f92359bfSslatteng t_newline(); 388f92359bfSslatteng break; 389f92359bfSslatteng case '#': /* comment */ 390f92359bfSslatteng while (getc(fp) != '\n') 391f92359bfSslatteng ; 392f92359bfSslatteng break; 393f92359bfSslatteng case 'x': /* device control */ 394f92359bfSslatteng devcntrl(fp); 395f92359bfSslatteng break; 396f92359bfSslatteng default: 397f92359bfSslatteng error(!FATAL, "unknown input character %o %c\n", c, c); 398f92359bfSslatteng done(); 399f92359bfSslatteng } 400f92359bfSslatteng } 401f92359bfSslatteng } 402f92359bfSslatteng 403f92359bfSslatteng devcntrl(fp) /* interpret device control functions */ 404f92359bfSslatteng FILE *fp; 405f92359bfSslatteng { 406f92359bfSslatteng char str[20], str1[50], buf[50]; 407f92359bfSslatteng int c, n; 408f92359bfSslatteng 409f92359bfSslatteng fscanf(fp, "%s", str); 410f92359bfSslatteng switch (str[0]) { /* crude for now */ 411f92359bfSslatteng case 'i': /* initialize */ 412f92359bfSslatteng fileinit(); 413f92359bfSslatteng t_init(); 414f92359bfSslatteng break; 415f92359bfSslatteng case 't': /* trailer */ 416f92359bfSslatteng t_trailer(); 417f92359bfSslatteng break; 418f92359bfSslatteng case 'p': /* pause -- can restart */ 419f92359bfSslatteng t_reset('p'); 420f92359bfSslatteng break; 421f92359bfSslatteng case 's': /* stop */ 422f92359bfSslatteng t_reset('s'); 423f92359bfSslatteng break; 424f92359bfSslatteng case 'r': /* resolution assumed when prepared */ 425f92359bfSslatteng fscanf(fp, "%d", &res); 426f92359bfSslatteng break; 427f92359bfSslatteng case 'f': /* font used */ 428f92359bfSslatteng fscanf(fp, "%d %s", &n, str); 429f92359bfSslatteng fgets(buf, sizeof buf, fp); /* in case there's a filename */ 430f92359bfSslatteng ungetc('\n', fp); /* fgets goes too far */ 431f92359bfSslatteng str1[0] = 0; /* in case nothing comes in */ 432f92359bfSslatteng sscanf(buf, "%s", str1); 433f92359bfSslatteng loadfont(n, str, str1); 434f92359bfSslatteng break; 435f92359bfSslatteng /* these don't belong here... */ 436f92359bfSslatteng case 'H': /* char height */ 437f92359bfSslatteng fscanf(fp, "%d", &n); 438f92359bfSslatteng t_charht(n); 439f92359bfSslatteng break; 440f92359bfSslatteng case 'S': /* slant */ 441f92359bfSslatteng fscanf(fp, "%d", &n); 442f92359bfSslatteng t_slant(n); 443f92359bfSslatteng break; 444f92359bfSslatteng } 445f92359bfSslatteng while ((c = getc(fp)) != '\n') /* skip rest of input line */ 446f92359bfSslatteng if (c == EOF) 447f92359bfSslatteng break; 448f92359bfSslatteng } 449f92359bfSslatteng 450f92359bfSslatteng /* fileinit: read in font and code files, etc. 451f92359bfSslatteng Must open table for device, read in resolution, 452f92359bfSslatteng size info, font info, etc. and set params 453f92359bfSslatteng */ 454f92359bfSslatteng fileinit() 455f92359bfSslatteng { 456f92359bfSslatteng int i, fin, nw; 457f92359bfSslatteng char *filebase, *p; 458f92359bfSslatteng char temp[60]; 459f92359bfSslatteng 460f92359bfSslatteng sprintf(temp, "%s/devver/DESC.out", fontdir); 461f92359bfSslatteng if ((fin = open(temp, 0)) < 0) 462f92359bfSslatteng error(FATAL, "can't open tables for %s\n", temp); 463f92359bfSslatteng read(fin, &dev, sizeof(struct dev)); 464f92359bfSslatteng nfonts = dev.nfonts; 465f92359bfSslatteng nsizes = dev.nsizes; 466f92359bfSslatteng nchtab = dev.nchtab; 467f92359bfSslatteng filebase = calloc(1,dev.filesize); /* enough room for whole file */ 468f92359bfSslatteng read(fin, filebase, dev.filesize); /* all at once */ 469f92359bfSslatteng pstab = (short *) filebase; 470f92359bfSslatteng chtab = pstab + nsizes + 1; 471f92359bfSslatteng chname = (char *) (chtab + dev.nchtab); 472f92359bfSslatteng p = chname + dev.lchname; 473f92359bfSslatteng for (i = 1; i <= nfonts; i++) { 474f92359bfSslatteng fontbase[i] = (struct font *) p; 475f92359bfSslatteng nw = *p & BMASK; /* 1st thing is width count */ 476f92359bfSslatteng if (smnt == 0 && fontbase[i]->specfont == 1) 477f92359bfSslatteng smnt = i; /* first special font */ 478f92359bfSslatteng p += sizeof(struct font); /* that is on the beginning */ 479f92359bfSslatteng widtab[i] = p; 480f92359bfSslatteng codetab[i] = p + 2 * nw; 481f92359bfSslatteng fitab[i] = p + 3 * nw; 482f92359bfSslatteng p += 3 * nw + dev.nchtab + 128 - 32; 483f92359bfSslatteng t_fp(i, fontbase[i]->namefont, fontbase[i]->intname); 484f92359bfSslatteng #ifdef DEBUGABLE 485f92359bfSslatteng if (dbg > 1) fontprint(i); 486f92359bfSslatteng #endif 487f92359bfSslatteng } 488f92359bfSslatteng fontbase[0] = (struct font *) 489f92359bfSslatteng calloc(1,3*255 + dev.nchtab + (128-32) + sizeof (struct font)); 490f92359bfSslatteng widtab[0] = (char *) fontbase[0] + sizeof (struct font); 491f92359bfSslatteng fontbase[0]->nwfont = 255; 492f92359bfSslatteng close(fin); 493f92359bfSslatteng } 494f92359bfSslatteng 495f92359bfSslatteng fontprint(i) /* debugging print of font i (0,...) */ 496f92359bfSslatteng { 497f92359bfSslatteng int j, n; 498f92359bfSslatteng char *p; 499f92359bfSslatteng 500f92359bfSslatteng fprintf(stderr,"font %d:\n", i); 501f92359bfSslatteng p = (char *) fontbase[i]; 502f92359bfSslatteng n = fontbase[i]->nwfont & BMASK; 503f92359bfSslatteng fprintf(stderr, 504f92359bfSslatteng "base=0%o, nchars=%d, spec=%d, name=%s, widtab=0%o, fitab=0%o\n",p, 505f92359bfSslatteng n,fontbase[i]->specfont,fontbase[i]->namefont,widtab[i],fitab[i]); 506f92359bfSslatteng fprintf(stderr,"widths:\n"); 507f92359bfSslatteng for (j=0; j <= n; j++) { 508f92359bfSslatteng fprintf(stderr," %2d", widtab[i][j] & BMASK); 509f92359bfSslatteng if (j % 20 == 19) fprintf(stderr,"\n"); 510f92359bfSslatteng } 511f92359bfSslatteng fprintf(stderr,"\ncodetab:\n"); 512f92359bfSslatteng for (j=0; j <= n; j++) { 513f92359bfSslatteng fprintf(stderr," %2d", codetab[i][j] & BMASK); 514f92359bfSslatteng if (j % 20 == 19) fprintf(stderr,"\n"); 515f92359bfSslatteng } 516f92359bfSslatteng fprintf(stderr,"\nfitab:\n"); 517f92359bfSslatteng for (j=0; j <= dev.nchtab + 128-32; j++) { 518f92359bfSslatteng fprintf(stderr," %2d", fitab[i][j] & BMASK); 519f92359bfSslatteng if (j % 20 == 19) fprintf(stderr,"\n"); 520f92359bfSslatteng } 521f92359bfSslatteng fprintf(stderr,"\n"); 522f92359bfSslatteng } 523f92359bfSslatteng 524f92359bfSslatteng loadfont(n, s, s1) /* load font info for font s on position n (0...) */ 525f92359bfSslatteng int n; 526f92359bfSslatteng char *s, *s1; 527f92359bfSslatteng { 528f92359bfSslatteng char temp[60]; 529f92359bfSslatteng int fin, nw, norig; 530f92359bfSslatteng 531f92359bfSslatteng if (n < 0 || n > NFONTS) 532f92359bfSslatteng error(FATAL, "illegal fp command %d %s", n, s); 533f92359bfSslatteng if (strcmp(s, fontbase[n]->namefont) == 0) 534f92359bfSslatteng return; 535f92359bfSslatteng if (s1 == NULL || s1[0] == '\0') 536f92359bfSslatteng sprintf(temp, "%s/devver/%s.out", fontdir, s); 537f92359bfSslatteng else 538f92359bfSslatteng sprintf(temp, "%s/%s.out", s1, s); 539f92359bfSslatteng if ((fin = open(temp, 0)) < 0) 540f92359bfSslatteng error(FATAL, "can't open font table %s", temp); 541f92359bfSslatteng norig = fontbase[n]->nwfont & BMASK; 542f92359bfSslatteng read(fin, fontbase[n], 3*norig + nchtab+128-32 + sizeof(struct font)); 543f92359bfSslatteng if ((fontbase[n]->nwfont & BMASK) > norig) 544f92359bfSslatteng error(FATAL, "Font %s too big for position %d\n", s, n); 545f92359bfSslatteng close(fin); 546f92359bfSslatteng nw = fontbase[n]->nwfont & BMASK; 547f92359bfSslatteng widtab[n] = (char *) fontbase[n] + sizeof(struct font); 548f92359bfSslatteng codetab[n] = (char *) widtab[n] + 2 * nw; 549f92359bfSslatteng fitab[n] = (char *) widtab[n] + 3 * nw; 550f92359bfSslatteng t_fp(n, fontbase[n]->namefont, fontbase[n]->intname); 551f92359bfSslatteng fontbase[n]->nwfont = norig; /* to later use full original size */ 552f92359bfSslatteng #ifdef DEBUGABLE 553f92359bfSslatteng if (dbg > 1) fontprint(n); 554f92359bfSslatteng #endif 555f92359bfSslatteng } 556f92359bfSslatteng 557f92359bfSslatteng done() 558f92359bfSslatteng { 559f92359bfSslatteng t_reset('s'); 560f92359bfSslatteng exit(0); 561f92359bfSslatteng } 562f92359bfSslatteng /*VARARGS1*/ 563f92359bfSslatteng error(f, s, a1, a2, a3, a4, a5, a6, a7) { 564f92359bfSslatteng fprintf(stderr, "dver: "); 565f92359bfSslatteng fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7); 566f92359bfSslatteng fprintf(stderr, "\n"); 567f92359bfSslatteng if (f) 568f92359bfSslatteng done(); 569f92359bfSslatteng } 570f92359bfSslatteng 571f92359bfSslatteng 572f92359bfSslatteng /******************************************************************************* 573f92359bfSslatteng * Routine: 574f92359bfSslatteng * Results: 575f92359bfSslatteng * Side Efct: 576f92359bfSslatteng ******************************************************************************/ 577f92359bfSslatteng 578f92359bfSslatteng t_init() /* initialize device */ 579f92359bfSslatteng { 580f92359bfSslatteng int i; 581f92359bfSslatteng 582f92359bfSslatteng hpos = vpos = 0; 583f92359bfSslatteng 584f92359bfSslatteng setsize(t_size(10)); /* start somewhere */ 585f92359bfSslatteng setfont(1); 586f92359bfSslatteng } 587f92359bfSslatteng 588f92359bfSslatteng 589f92359bfSslatteng struct state { 590f92359bfSslatteng int ssize; 591f92359bfSslatteng int sfont; 592f92359bfSslatteng int shpos; 593f92359bfSslatteng int svpos; 594f92359bfSslatteng int shorig; 595f92359bfSslatteng int svorig; 596f92359bfSslatteng }; 597f92359bfSslatteng struct state state[MAXSTATE]; 598f92359bfSslatteng struct state *statep = state; 599f92359bfSslatteng 600f92359bfSslatteng t_push() /* begin a new block */ 601f92359bfSslatteng { 602f92359bfSslatteng statep->ssize = size; 603f92359bfSslatteng statep->sfont = font; 604f92359bfSslatteng statep->shorig = horig; 605f92359bfSslatteng statep->svorig = vorig; 606f92359bfSslatteng statep->shpos = hpos; 607f92359bfSslatteng statep->svpos = vpos; 608f92359bfSslatteng horig = hpos; 609f92359bfSslatteng vorig = vpos; 610f92359bfSslatteng hpos = vpos = 0; 611f92359bfSslatteng if (statep++ >= state+MAXSTATE) 612f92359bfSslatteng error(FATAL, "{ nested too deep"); 613f92359bfSslatteng hpos = vpos = 0; 614f92359bfSslatteng } 615f92359bfSslatteng 616f92359bfSslatteng t_pop() /* pop to previous state */ 617f92359bfSslatteng { 618f92359bfSslatteng if (--statep < state) 619f92359bfSslatteng error(FATAL, "extra }"); 620f92359bfSslatteng size = statep->ssize; 621f92359bfSslatteng font = statep->sfont; 622f92359bfSslatteng hpos = statep->shpos; 623f92359bfSslatteng vpos = statep->svpos; 624f92359bfSslatteng horig = statep->shorig; 625f92359bfSslatteng vorig = statep->svorig; 626f92359bfSslatteng } 627f92359bfSslatteng 628f92359bfSslatteng t_page(n) /* do whatever new page functions */ 629f92359bfSslatteng { 630f92359bfSslatteng int i; 631f92359bfSslatteng 632f92359bfSslatteng 633f92359bfSslatteng if (output) { 634f92359bfSslatteng if (++scount >= spage) { 635f92359bfSslatteng t_reset('p'); 636f92359bfSslatteng scount = 0; 637f92359bfSslatteng } 638f92359bfSslatteng slop_lines(maxH); 639f92359bfSslatteng /* noversatec 640f92359bfSslatteng ioctl(OUTFILE, VSETSTATE, prtmode); 641f92359bfSslatteng if (write(OUTFILE, "\f", 2) != 2) 642f92359bfSslatteng exit(RESTART); 643f92359bfSslatteng ioctl(OUTFILE, VSETSTATE, pltmode); 644f92359bfSslatteng noversatec */ 645f92359bfSslatteng size = BYTES_PER_LINE * maxH; 646f92359bfSslatteng vclear(buf0p, size); 647f92359bfSslatteng buf0p = buffer; 648f92359bfSslatteng } 649f92359bfSslatteng 650f92359bfSslatteng maxH = 0; 651f92359bfSslatteng 652f92359bfSslatteng vpos = 0; 653f92359bfSslatteng output = 1; 654f92359bfSslatteng if (nolist == 0) 655f92359bfSslatteng return; /* no -o specified */ 656f92359bfSslatteng output = 0; 657f92359bfSslatteng for (i = 0; i < nolist; i += 2) 658f92359bfSslatteng if (n >= olist[i] && n <= olist[i+1]) { 659f92359bfSslatteng output = 1; 660f92359bfSslatteng break; 661f92359bfSslatteng } 662f92359bfSslatteng } 663f92359bfSslatteng 664f92359bfSslatteng t_newline() /* do whatever for the end of a line */ 665f92359bfSslatteng { 666f92359bfSslatteng hpos = 0; /* because we're now back at the left margin */ 667f92359bfSslatteng } 668f92359bfSslatteng 669f92359bfSslatteng t_size(n) /* convert integer to internal size number*/ 670f92359bfSslatteng int n; 671f92359bfSslatteng { 672f92359bfSslatteng int i; 673f92359bfSslatteng 674f92359bfSslatteng if (n <= pstab[0]) 675f92359bfSslatteng return(1); 676f92359bfSslatteng else if (n >= pstab[nsizes-1]) 677f92359bfSslatteng return(nsizes); 678f92359bfSslatteng for (i = 0; n > pstab[i]; i++) 679f92359bfSslatteng ; 680f92359bfSslatteng return(i+1); 681f92359bfSslatteng } 682f92359bfSslatteng 683f92359bfSslatteng t_charht(n) /* set character height to n */ 684f92359bfSslatteng int n; 685f92359bfSslatteng { 686f92359bfSslatteng #ifdef DEBUGABLE 687f92359bfSslatteng if (dbg)fprintf(stderr,"can't set height on versatec yet\n"); 688f92359bfSslatteng #endif 689f92359bfSslatteng } 690f92359bfSslatteng 691f92359bfSslatteng t_slant(n) /* set slant to n */ 692f92359bfSslatteng int n; 693f92359bfSslatteng { 694f92359bfSslatteng #ifdef DEBUGABLE 695f92359bfSslatteng if (dbg)fprintf(stderr,"can't set slant on versatec yet\n"); 696f92359bfSslatteng #endif 697f92359bfSslatteng } 698f92359bfSslatteng 699f92359bfSslatteng t_font(s) /* convert string to internal font number */ 700f92359bfSslatteng char *s; 701f92359bfSslatteng { 702f92359bfSslatteng int n; 703f92359bfSslatteng 704f92359bfSslatteng n = atoi(s); 705f92359bfSslatteng if (n < 0 || n > nfonts) 706f92359bfSslatteng n = 1; 707f92359bfSslatteng return(n); 708f92359bfSslatteng } 709f92359bfSslatteng 710f92359bfSslatteng t_text(s) /* print string s as text */ 711f92359bfSslatteng char *s; 712f92359bfSslatteng { 713f92359bfSslatteng int c; 714f92359bfSslatteng char str[100]; 715f92359bfSslatteng 716f92359bfSslatteng if (!output) 717f92359bfSslatteng return; 718f92359bfSslatteng while (c = *s++) { 719f92359bfSslatteng if (c == '\\') { 720f92359bfSslatteng switch (c = *s++) { 721f92359bfSslatteng case '\\': 722f92359bfSslatteng case 'e': 723f92359bfSslatteng put1('\\'); 724f92359bfSslatteng break; 725f92359bfSslatteng case '(': 726f92359bfSslatteng str[0] = *s++; 727f92359bfSslatteng str[1] = *s++; 728f92359bfSslatteng str[2] = '\0'; 729f92359bfSslatteng put1s(str); 730f92359bfSslatteng break; 731f92359bfSslatteng } 732f92359bfSslatteng } else { 733f92359bfSslatteng put1(c); 734f92359bfSslatteng } 735f92359bfSslatteng hmot(lastw); 736f92359bfSslatteng #ifdef DEBUGABLE 737f92359bfSslatteng if (dbg) fprintf(stderr,"width = %d\n", lastw); 738f92359bfSslatteng #endif 739f92359bfSslatteng } 740f92359bfSslatteng } 741f92359bfSslatteng 742f92359bfSslatteng t_reset(c) 743f92359bfSslatteng { 744f92359bfSslatteng 745f92359bfSslatteng 746f92359bfSslatteng output = 1; 747f92359bfSslatteng switch(c){ 748f92359bfSslatteng case 'p': 749f92359bfSslatteng slop_lines(maxH); 750f92359bfSslatteng maxH = 0; 751f92359bfSslatteng buf0p = buffer; 752f92359bfSslatteng break; 753f92359bfSslatteng case 's': 754f92359bfSslatteng slop_lines(maxH); 755f92359bfSslatteng t_done(); 756f92359bfSslatteng break; /* no Return */ 757f92359bfSslatteng } 758f92359bfSslatteng } 759f92359bfSslatteng 760f92359bfSslatteng t_done() /* clean up and get ready to die */ 761f92359bfSslatteng { 762f92359bfSslatteng /* noversatec 763f92359bfSslatteng ioctl(OUTFILE, VSETSTATE, prtmode); 764f92359bfSslatteng if (write(OUTFILE, "\f", 2) != 2) 765f92359bfSslatteng exit(RESTART); 766f92359bfSslatteng noversatec */ 767f92359bfSslatteng } 768f92359bfSslatteng 769f92359bfSslatteng t_trailer() 770f92359bfSslatteng { 771f92359bfSslatteng vpos = 0; 772f92359bfSslatteng vgoto(TRAILER); 773f92359bfSslatteng vpos = 0; 774f92359bfSslatteng } 775f92359bfSslatteng 776f92359bfSslatteng vgoto(n) 777f92359bfSslatteng { 778f92359bfSslatteng /* check to see if n would move use past buf0p */ 779f92359bfSslatteng if (n < 0) { 780f92359bfSslatteng fprintf (stderr, "ERROR vgoto past the beginning"); 781f92359bfSslatteng done(); 782f92359bfSslatteng } 783f92359bfSslatteng /* check for end of page */ 784f92359bfSslatteng if (n > RES * 11) n -= RES * 11; /* wrap around on to the top */ 785f92359bfSslatteng vpos = n; 786f92359bfSslatteng } 787f92359bfSslatteng 788f92359bfSslatteng put1s(s) /* s is a funny char name */ 789f92359bfSslatteng char *s; 790f92359bfSslatteng { 791f92359bfSslatteng int i; 792f92359bfSslatteng 793f92359bfSslatteng if (!output) 794f92359bfSslatteng return; 795f92359bfSslatteng #ifdef DEBUGABLE 796f92359bfSslatteng if (dbg) fprintf(stderr,"%s ", s); 797f92359bfSslatteng #endif 798f92359bfSslatteng for (i = 0; i < nchtab; i++) 799f92359bfSslatteng if (strcmp(&chname[chtab[i]], s) == 0) 800f92359bfSslatteng break; 801f92359bfSslatteng if (i < nchtab) 802f92359bfSslatteng put1(i + 128); 803f92359bfSslatteng } 804f92359bfSslatteng 805f92359bfSslatteng put1(c) /* output char c */ 806f92359bfSslatteng int c; 807f92359bfSslatteng { 808f92359bfSslatteng char *pw; 809f92359bfSslatteng register char *p; 810f92359bfSslatteng register int i, k; 811f92359bfSslatteng int j, ofont, code; 812f92359bfSslatteng 813f92359bfSslatteng if (!output) 814f92359bfSslatteng return; 815f92359bfSslatteng c -= 32; 816f92359bfSslatteng if (c <= 0) { 817f92359bfSslatteng #ifdef DEBUGABLE 818f92359bfSslatteng if (dbg) fprintf(stderr,"non-exist 0%o\n", c + 32); 819f92359bfSslatteng #endif 820f92359bfSslatteng lastw = (widtab[font][0] * pstab[size-1] + dev.unitwidth/2) 821f92359bfSslatteng / dev.unitwidth; 822f92359bfSslatteng return; 823f92359bfSslatteng } 824f92359bfSslatteng k = ofont = font; 825f92359bfSslatteng i = fitab[font][c] & BMASK; 826f92359bfSslatteng if (i != 0) { /* it's on this font */ 827f92359bfSslatteng p = codetab[font]; /* get the printing value of ch */ 828f92359bfSslatteng pw = widtab[font]; /* get the width */ 829f92359bfSslatteng } else if (smnt > 0) { /* on special (we hope) */ 830f92359bfSslatteng for (k=smnt, j=0; j <= nfonts; j++, k = (k+1) % (nfonts+1)){ 831f92359bfSslatteng if (fitab[k] == 0) 832f92359bfSslatteng continue; 833f92359bfSslatteng if ((i = fitab[k][c] & BMASK) != 0) { 834f92359bfSslatteng p = codetab[k]; 835f92359bfSslatteng pw = widtab[k]; 836f92359bfSslatteng setfont(k); 837f92359bfSslatteng break; 838f92359bfSslatteng } 839f92359bfSslatteng } 840f92359bfSslatteng } 841f92359bfSslatteng if (i == 0 || (code = p[i] & BMASK) == 0 || k > nfonts) { 842f92359bfSslatteng #ifdef DEBUGABLE 843f92359bfSslatteng if (dbg) fprintf(stderr,"not found 0%o\n", c+32); 844f92359bfSslatteng #endif 845f92359bfSslatteng return; 846f92359bfSslatteng } 847f92359bfSslatteng #ifdef DEBUGABLE 848f92359bfSslatteng if (dbg) { 849f92359bfSslatteng if (isprint(c+32)) 850f92359bfSslatteng fprintf(stderr,"%c %d\n", c+32, code); 851f92359bfSslatteng else 852f92359bfSslatteng fprintf(stderr,"%03o %d\n", c+32, code); 853f92359bfSslatteng } 854f92359bfSslatteng #endif 855f92359bfSslatteng outc(code); /* character is < 254 */ 856f92359bfSslatteng if (font != ofont) 857f92359bfSslatteng setfont(ofont); 858f92359bfSslatteng lastw = ((pw[i]&077) * pstab[size-1] + dev.unitwidth/2) / dev.unitwidth; 859f92359bfSslatteng } 860f92359bfSslatteng 861f92359bfSslatteng 862f92359bfSslatteng 863f92359bfSslatteng setsize(n) /* set point size to n (internal) */ 864f92359bfSslatteng int n; 865f92359bfSslatteng { 866f92359bfSslatteng 867f92359bfSslatteng if (n == size) 868f92359bfSslatteng return; /* already there */ 869f92359bfSslatteng if (vloadfont(font,pstab[n-1]) != -1) 870f92359bfSslatteng size = n; 871f92359bfSslatteng } 872f92359bfSslatteng 873f92359bfSslatteng t_fp(n, s, si) /* font position n now contains font s, intname si */ 874f92359bfSslatteng int n; 875f92359bfSslatteng char *s, *si; 876f92359bfSslatteng { 877f92359bfSslatteng register i; 878f92359bfSslatteng 879f92359bfSslatteng fontname[n].name = s; 880f92359bfSslatteng fontname[n].number = atoi(si); 881f92359bfSslatteng for(i = 0;i < NFONTS;i++)/* free the bits of that font */ 882f92359bfSslatteng if (fontdes[i].fnum == n){ 883f92359bfSslatteng nfree(fontdes[i].bits); 884f92359bfSslatteng fontdes[i].bits = 0; 885f92359bfSslatteng fontdes[i].fnum = -1; 886f92359bfSslatteng } 887f92359bfSslatteng } 888f92359bfSslatteng 889f92359bfSslatteng setfont(n) /* set font to n */ 890f92359bfSslatteng int n; 891f92359bfSslatteng { 892f92359bfSslatteng if (n < 0 || n > NFONTS) 893f92359bfSslatteng error(FATAL, "illegal font %d\n", n); 894f92359bfSslatteng if (vloadfont(n,pstab[size - 1]) != -1) 895f92359bfSslatteng font = n; 896f92359bfSslatteng } 897f92359bfSslatteng 898f92359bfSslatteng vloadfont(fnum, fsize) 899f92359bfSslatteng register int fnum; 900f92359bfSslatteng register int fsize; 901f92359bfSslatteng { 902f92359bfSslatteng register int i; 903f92359bfSslatteng 904f92359bfSslatteng fontwanted = 0; 905f92359bfSslatteng if (fnum == cfnum && fsize == cpsize) 906f92359bfSslatteng return(0); 907f92359bfSslatteng for (i = 0; i < NFONTS; i++) { 908f92359bfSslatteng if (fontdes[i].fnum == fnum && fontdes[i].psize == fsize) { 909f92359bfSslatteng cfnum = fontdes[i].fnum; 910f92359bfSslatteng cpsize = fontdes[i].psize; 911f92359bfSslatteng dispatch = &fontdes[i].disp[0]; 912f92359bfSslatteng bits = fontdes[i].bits; 913f92359bfSslatteng cfont = i; 914f92359bfSslatteng return (0); 915f92359bfSslatteng } 916f92359bfSslatteng } 917f92359bfSslatteng /* this is a new font */ 918f92359bfSslatteng if (fnum < 0 || fnum > NFONTS || fontname[fnum].name == 0) { 919f92359bfSslatteng fprintf(stderr, "Internal error: illegal font %d name %s size\n", 920f92359bfSslatteng fontname[fnum].name,fnum,fsize); 921f92359bfSslatteng return(-1); 922f92359bfSslatteng } 923f92359bfSslatteng /* Need to verify the existance of that font/size here*/ 924f92359bfSslatteng nfontnum = fnum; 925f92359bfSslatteng npsize = fsize; 926f92359bfSslatteng fontwanted++; 927f92359bfSslatteng return (0); 928f92359bfSslatteng } 929f92359bfSslatteng 930f92359bfSslatteng 931f92359bfSslatteng getfont() 932f92359bfSslatteng { 933f92359bfSslatteng register int fnum, fsize, fontd; 934f92359bfSslatteng int d; 935f92359bfSslatteng char cbuf[BUFSIZ]; 936f92359bfSslatteng 937f92359bfSslatteng fnum = nfontnum; 938f92359bfSslatteng fsize = npsize; 939*1a4ecc79Sslatteng sprintf(cbuf, "/usr/lib/vfont/%s.%dr",fontname[fnum].name, fsize); 940f92359bfSslatteng fontd = open(cbuf, OPENREAD); 941f92359bfSslatteng if (fontd == -1) { 942f92359bfSslatteng perror(cbuf); 943f92359bfSslatteng error(0,"fnum = %d size = %d name = %s\n", 944f92359bfSslatteng fnum,fsize,fontname[fnum]); 945f92359bfSslatteng fontwanted = 0; 946f92359bfSslatteng return (-1); 947f92359bfSslatteng } 948f92359bfSslatteng if (read(fontd, &header, sizeof (header)) != sizeof (header) 949f92359bfSslatteng || header.magic != 0436) 950f92359bfSslatteng fprintf(stderr, "%s: Bad font file", cbuf); 951f92359bfSslatteng else { 952f92359bfSslatteng cfont = relfont(); 953f92359bfSslatteng if ((bits=nalloc(header.size+DSIZ+1,1))== NULL) 954f92359bfSslatteng if ((bits=allpanic(header.size+DSIZ+1))== NULL) { 955f92359bfSslatteng fprintf(stderr,"%s: ran out of memory\n", cbuf); 956f92359bfSslatteng exit(ABORT); 957f92359bfSslatteng } 958f92359bfSslatteng 959f92359bfSslatteng /* 960f92359bfSslatteng * have allocated one chunk of mem for font, dispatch. 961f92359bfSslatteng * get the dispatch addr, align to word boundary. 962f92359bfSslatteng */ 963f92359bfSslatteng 964f92359bfSslatteng d = (int) bits+header.size; 965f92359bfSslatteng d += 1; 966f92359bfSslatteng d &= ~1; 967f92359bfSslatteng if (read (fontd, d, DSIZ) != DSIZ 968f92359bfSslatteng || read (fontd, bits, header.size) != header.size) 969f92359bfSslatteng fprintf(stderr, "bad font header"); 970f92359bfSslatteng else { 971f92359bfSslatteng close(fontd); 972f92359bfSslatteng cfnum = fontdes[cfont].fnum = fnum; 973f92359bfSslatteng cpsize = fontdes[cfont].psize = fsize; 974f92359bfSslatteng fontdes [cfont].bits = bits; 975f92359bfSslatteng fontdes [cfont].disp = (struct dispatch *) d; 976f92359bfSslatteng dispatch = &fontdes[cfont].disp[0]; 977f92359bfSslatteng fontwanted = 0; 978f92359bfSslatteng return (0); 979f92359bfSslatteng } 980f92359bfSslatteng } 981f92359bfSslatteng close(fontd); 982f92359bfSslatteng fontwanted = 0; 983f92359bfSslatteng return(-1); 984f92359bfSslatteng } 985f92359bfSslatteng 986f92359bfSslatteng /* 987f92359bfSslatteng * "release" a font position - find an empty one, if possible 988f92359bfSslatteng */ 989f92359bfSslatteng 990f92359bfSslatteng relfont() 991f92359bfSslatteng { 992f92359bfSslatteng register int newfont; 993f92359bfSslatteng 994f92359bfSslatteng for (newfont = 0; newfont < NFONTS; newfont++) 995f92359bfSslatteng if (fontdes [newfont].bits == (char *) -1 || !fontdes [newfont].bits) 996f92359bfSslatteng break; 997f92359bfSslatteng if (fontdes [newfont].bits != (char *) -1 && fontdes [newfont].bits) { 998f92359bfSslatteng nfree (fontdes [newfont].bits); 999f92359bfSslatteng fontdes [newfont].bits = (char *)0; 1000f92359bfSslatteng #ifdef DEBUGABLE 1001f92359bfSslatteng if (dbg) fprintf (stderr, "freeing position %d\n", newfont); 1002f92359bfSslatteng } else { 1003f92359bfSslatteng if (dbg) 1004f92359bfSslatteng fprintf (stderr, "taking, not freeing, position %d\n", newfont); 1005f92359bfSslatteng #endif 1006f92359bfSslatteng } 1007f92359bfSslatteng fontdes[newfont].bits = 0; 1008f92359bfSslatteng return (newfont); 1009f92359bfSslatteng } 1010f92359bfSslatteng 1011f92359bfSslatteng char *allpanic (nbytes) 1012f92359bfSslatteng int nbytes; 1013f92359bfSslatteng { 1014f92359bfSslatteng register int i; 1015f92359bfSslatteng 1016f92359bfSslatteng for (i = 0; i <= NFONTS; i++) 1017f92359bfSslatteng if (fontdes[i].bits != (char *)-1 && fontdes[i].bits != (char *)0) 1018f92359bfSslatteng nfree(fontdes[i].bits); 1019f92359bfSslatteng for (i = 0; i <= NFONTS; i++) { 1020f92359bfSslatteng fontdes[i].fnum = fontdes[i].psize = -1; 1021f92359bfSslatteng fontdes[i].bits = 0; 1022f92359bfSslatteng cfnum = cpsize = -1; 1023f92359bfSslatteng } 1024f92359bfSslatteng return(nalloc(nbytes,1)); 1025f92359bfSslatteng } 1026f92359bfSslatteng 1027f92359bfSslatteng int M[] = { 0xffffffff, 0xfefefefe, 0xfcfcfcfc, 0xf8f8f8f8, 1028f92359bfSslatteng 0xf0f0f0f0, 0xe0e0e0e0, 0xc0c0c0c0, 0x80808080, 0x0 }; 1029f92359bfSslatteng int N[] = { 0x00000000, 0x01010101, 0x03030303, 0x07070707, 1030f92359bfSslatteng 0x0f0f0f0f, 0x1f1f1f1f, 0x3f3f3f3f, 0x7f7f7f7f, 0xffffffff }; 1031f92359bfSslatteng int strim[] = { 0xffffffff, 0xffffff00, 0xffff0000, 0xff000000, 0 }; 1032f92359bfSslatteng 1033f92359bfSslatteng outc(code) 1034f92359bfSslatteng int code; /* character to print */ 1035f92359bfSslatteng { 1036f92359bfSslatteng register struct dispatch *dis; /* ptr to character font record */ 1037f92359bfSslatteng register char *addr; /* addr of font data */ 1038f92359bfSslatteng int llen; /* length of each font line */ 1039f92359bfSslatteng int nlines; /* number of font lines */ 1040f92359bfSslatteng register char *scanp; /* ptr to output buffer */ 1041f92359bfSslatteng int scanp_inc; /* increment to start of next buffer */ 1042f92359bfSslatteng int offset; /* bit offset to start of font data */ 1043f92359bfSslatteng int i; /* loop counter */ 1044f92359bfSslatteng register int count; /* font data ptr */ 1045f92359bfSslatteng register unsigned fontdata; /* font data temporary */ 1046f92359bfSslatteng register int off8; /* offset + 8 */ 1047f92359bfSslatteng 1048f92359bfSslatteng if (fontwanted) 1049f92359bfSslatteng getfont(); 1050f92359bfSslatteng dis = dispatch + code; 1051f92359bfSslatteng if (dis->nbytes) { 1052f92359bfSslatteng addr = bits + dis->addr; 1053*1a4ecc79Sslatteng llen = (dis->up + dis->down + 7) >> 3; 1054*1a4ecc79Sslatteng nlines = dis->right + dis->left; 1055*1a4ecc79Sslatteng if ((i = hpos + dis->right) > maxH) maxH = i; /* remember page len */ 1056*1a4ecc79Sslatteng scanp = buf0p + (hpos - dis->left) * BYTES_PER_LINE 1057*1a4ecc79Sslatteng - (1 + ((dis->down + vpos) >> 3)); 1058f92359bfSslatteng if (scanp < &buffer[0]) 1059f92359bfSslatteng scanp += sizeof buffer; 1060f92359bfSslatteng scanp_inc = BYTES_PER_LINE - llen; 1061*1a4ecc79Sslatteng off8 = ((dis->down + vpos) &07); 1062*1a4ecc79Sslatteng offset = off8 - 8; 1063f92359bfSslatteng for (i = 0; i < nlines; i++) { 1064f92359bfSslatteng if (scanp >= &buffer[BUFFER_SIZE]) 1065f92359bfSslatteng scanp -= sizeof buffer; 1066f92359bfSslatteng count = llen; 1067f92359bfSslatteng if (scanp + count <= &buffer[BUFFER_SIZE]) { 1068f92359bfSslatteng do { 1069f92359bfSslatteng fontdata = *(unsigned *)addr; 1070f92359bfSslatteng addr += 4; 1071f92359bfSslatteng if (count < 4) 1072f92359bfSslatteng fontdata &= ~strim[count]; 1073f92359bfSslatteng *(unsigned*)scanp |=(fontdata << offset) & ~M[off8]; 1074f92359bfSslatteng scanp++; 1075f92359bfSslatteng *(unsigned*)scanp |=(fontdata << off8) & ~N[off8]; 1076f92359bfSslatteng scanp += 3; 1077f92359bfSslatteng count -= 4; 1078f92359bfSslatteng } while (count > 0); 1079f92359bfSslatteng } 1080f92359bfSslatteng scanp += scanp_inc+count; 1081f92359bfSslatteng addr += count; 1082f92359bfSslatteng } 1083f92359bfSslatteng return; 1084f92359bfSslatteng } 1085f92359bfSslatteng return; 1086f92359bfSslatteng } 1087f92359bfSslatteng 1088f92359bfSslatteng slop_lines(nlines) 1089f92359bfSslatteng int nlines; 1090f92359bfSslatteng 1091f92359bfSslatteng /* Output "nlines" lines from the buffer, and clear that section of the */ 1092f92359bfSslatteng /* buffer. */ 1093f92359bfSslatteng 1094f92359bfSslatteng { 1095f92359bfSslatteng unsigned usize; 1096f92359bfSslatteng 1097f92359bfSslatteng usize = BYTES_PER_LINE * nlines; 1098f92359bfSslatteng writev(buf0p,usize); 1099f92359bfSslatteng vclear(buf0p, usize); 1100f92359bfSslatteng /* noversatec 1101f92359bfSslatteng ioctl(OUTFILE, VSETSTATE, pltmode); 1102f92359bfSslatteng noversatec */ 1103f92359bfSslatteng } 1104f92359bfSslatteng 1105f92359bfSslatteng writev(buf,usize) 1106f92359bfSslatteng char *buf; 1107f92359bfSslatteng unsigned usize; 1108f92359bfSslatteng { 1109f92359bfSslatteng register int tsize = 0; 1110f92359bfSslatteng 1111f92359bfSslatteng while (usize){ 1112f92359bfSslatteng buf += tsize; 1113f92359bfSslatteng tsize = usize > MAXWRIT ? MAXWRIT : usize; 1114f92359bfSslatteng #ifdef DEBUGABLE 1115f92359bfSslatteng if (dbg)fprintf(stderr,"buf = %d size = %d\n",buf,tsize); 1116f92359bfSslatteng #endif 1117f92359bfSslatteng if ((tsize = write(OUTFILE, buf, tsize)) < 0) { 1118f92359bfSslatteng perror("dver: write failed"); 1119f92359bfSslatteng exit(RESTART); 1120f92359bfSslatteng } 1121f92359bfSslatteng usize -= tsize; 1122f92359bfSslatteng } 1123f92359bfSslatteng } 1124f92359bfSslatteng 1125f92359bfSslatteng vclear (ptr, nbytes) 1126f92359bfSslatteng char *ptr; 1127f92359bfSslatteng unsigned nbytes; 1128f92359bfSslatteng { 1129f92359bfSslatteng register tsize = 0; 1130f92359bfSslatteng 1131f92359bfSslatteng while (nbytes){ 1132f92359bfSslatteng if ((unsigned)(16*1024) < nbytes) { 1133f92359bfSslatteng tsize = 16 * 1024; 1134f92359bfSslatteng } else 1135f92359bfSslatteng tsize = nbytes; 1136f92359bfSslatteng nbytes -= tsize; 1137f92359bfSslatteng #ifdef DEBUGABLE 1138f92359bfSslatteng if (dbg) fprintf(stderr,"clearing ptr = %d size = %d\n",ptr,tsize); 1139f92359bfSslatteng #endif 1140f92359bfSslatteng clear(ptr,tsize); 1141f92359bfSslatteng ptr += tsize; 1142f92359bfSslatteng } 1143f92359bfSslatteng } 1144f92359bfSslatteng 1145f92359bfSslatteng /*ARGSUSED*/ 1146f92359bfSslatteng clear(lp, nbytes) 1147f92359bfSslatteng int *lp; 1148f92359bfSslatteng int nbytes; 1149f92359bfSslatteng { 1150f92359bfSslatteng asm("movc5 $0,(sp),$0,8(ap),*4(ap)"); 1151f92359bfSslatteng } 1152f92359bfSslatteng 1153f92359bfSslatteng char * 1154f92359bfSslatteng nalloc(i, j) 1155f92359bfSslatteng int i, j; 1156f92359bfSslatteng { 1157f92359bfSslatteng register char *cp; 1158f92359bfSslatteng 1159f92359bfSslatteng cp = calloc(i, j); 1160f92359bfSslatteng #ifdef DEBUGABLE 1161f92359bfSslatteng if (dbg) fprintf(stderr, "allocated %d bytes at %x\n", i * j, cp); 1162f92359bfSslatteng #endif 1163f92359bfSslatteng return(cp); 1164f92359bfSslatteng } 1165f92359bfSslatteng 1166f92359bfSslatteng nfree(cp) 1167f92359bfSslatteng char *cp; 1168f92359bfSslatteng { 1169f92359bfSslatteng #ifdef DEBUGABLE 1170f92359bfSslatteng if (dbg) fprintf(stderr, "freeing at %x\n", cp); 1171f92359bfSslatteng #endif 1172f92359bfSslatteng free(cp); 1173f92359bfSslatteng } 1174f92359bfSslatteng 1175f92359bfSslatteng 1176f92359bfSslatteng /* 1177f92359bfSslatteng * Points should be in the range 0 <= x < RASTER_LENGTH, 0 <= y < NLINES. 1178f92359bfSslatteng * The origin is the top left-hand corner with increasing x towards the 1179f92359bfSslatteng * right and increasing y going down. 1180f92359bfSslatteng * The output array is NLINES x BYTES_PER_LINE pixels. 1181f92359bfSslatteng */ 1182f92359bfSslatteng point(x, y) 1183*1a4ecc79Sslatteng register int x; 1184*1a4ecc79Sslatteng register int y; 1185f92359bfSslatteng { 1186*1a4ecc79Sslatteng if ((unsigned)(y=RASTER_LENGTH-y) < RASTER_LENGTH && (unsigned)x < NLINES) { 1187*1a4ecc79Sslatteng buffer [x * BYTES_PER_LINE + (y >> 3)] |= 1 << (7 - (y & 07)); 1188f92359bfSslatteng } 1189f92359bfSslatteng } 1190