1 #ifndef lint 2 /* 3 static char sccsid[] = "@(#)t10.c 2.4 (CWI) 89/08/14"; 4 */ 5 static char sccsid[] = "@(#)t10.c 2.6 (Berkeley) 11/03/90"; 6 #endif lint 7 #include "tdef.h" 8 #include <sgtty.h> 9 #include <ctype.h> 10 #include "ext.h" 11 /* 12 * troff10.c 13 * 14 * typesetter interface 15 */ 16 17 int vpos = 0; /* absolute vertical position on page */ 18 int hpos = 0; /* ditto horizontal */ 19 20 short *chtab; 21 char *chname; 22 char *fontab[NFONT+1]; 23 char *kerntab[NFONT+1]; 24 char *fitab[NFONT+1]; 25 char *codetab[NFONT+1]; 26 27 int Inch; 28 int Hor; 29 int Vert; 30 int Unitwidth; 31 int nfonts; /* highest font num. in fontab */ 32 int physfonts; /* highest font num. known to printer */ 33 int zfont; /* internal font num. mapped to 0 on printer */ 34 int nsizes; 35 int nchtab; 36 int nstips; 37 tchar *stiplab; 38 39 /* these characters are used as various signals or values 40 /* in miscellaneous places. 41 /* values are set in specnames in t10.c 42 */ 43 44 int c_hyphen; 45 int c_emdash; 46 int c_rule; 47 int c_minus; 48 int c_fi; 49 int c_fl; 50 int c_ff; 51 int c_ffi; 52 int c_ffl; 53 int c_acute; 54 int c_grave; 55 int c_under; 56 int c_rooten; 57 int c_boxrule; 58 int c_lefthand; 59 int c_dagger; 60 61 #include "dev.h" 62 struct dev dev; 63 struct Font *fontbase[NFONT+1]; 64 65 66 ptinit() 67 { 68 int i, fin, nw; 69 char *filebase, *p; 70 71 /* open table for device, 72 /* read in resolution, size info, font info, etc. 73 /* and set params 74 */ 75 strcat(termtab, "/dev"); 76 strcat(termtab, devname); 77 strcat(termtab, "/DESC.out"); /* makes "..../devXXX/DESC.out" */ 78 if ((fin = open(termtab, 0)) < 0) { 79 errprint("can't open tables for %s", termtab); 80 done3(1); 81 } 82 if (read(fin, (char *) &dev, sizeof(struct dev)) < sizeof(struct dev)) { 83 errprint("short read on %s", termtab); 84 done3(1); 85 } 86 Inch = dev.res; 87 Hor = dev.hor; 88 Vert = dev.vert; 89 Unitwidth = dev.unitwidth; 90 physfonts = nfonts = dev.nfonts; 91 nsizes = dev.nsizes; 92 nchtab = dev.nchtab; 93 nstips = dev.nstip; 94 stiplab = (tchar *) malloc((nstips + 1) * sizeof(tchar)); 95 filebase = malloc(dev.filesize + EXTRAFONT); 96 if (read(fin, filebase, dev.filesize) < dev.filesize) { 97 errprint("short read on %s", termtab); 98 done3(1); 99 } 100 pstab = (short *) filebase; 101 chtab = pstab + nsizes + 1; 102 chname = (char *) (chtab + dev.nchtab); 103 p = chname + dev.lchname; 104 for (i = 1; i <= nfonts; i++) { 105 fontbase[i] = (struct Font *) p; 106 nw = *p & BYTEMASK; /* 1st thing is width count */ 107 fontlab[i] = PAIR(fontbase[i]->namefont[0], fontbase[i]->namefont[1]); 108 /* for now, still 2 char names */ 109 if (smnt == 0 && fontbase[i]->specfont == 1) 110 smnt = i; /* first special font */ 111 p += sizeof(struct Font); /* that's what's on the beginning */ 112 fontab[i] = p; 113 kerntab[i] = p + nw; 114 codetab[i] = p + 2 * nw; 115 fitab[i] = p + 3 * nw; /* skip width, kern, code */ 116 p += 3 * nw + dev.nchtab + 128 - 32; 117 } 118 for (i = 1; i <= nstips; i++) { /* make stipple names tchars */ 119 stiplab[i] = PAIR(*p, *(p+1)); 120 while (*(p++)); 121 } 122 fontbase[0] = (struct Font *) p; /* the last shall be first */ 123 fontbase[0]->nwfont = MAXCHARS; 124 fontab[0] = p + sizeof (struct Font); 125 close(fin); 126 /* there are a lot of things that used to be constant 127 /* that now require code to be executed. 128 */ 129 sps = SPS; 130 ics = ICS; 131 for (i = 0; i < 16; i++) 132 tabtab[i] = DTAB * (i + 1); 133 pl = 11 * INCH; 134 po = PO; 135 spacesz = SS; 136 lss = lss1 = VS; 137 ll = ll1 = lt = lt1 = LL; 138 specnames(); /* install names like "hyphen", etc. */ 139 if (ascii) 140 return; 141 fdprintf(ptid, "x T %s\n", devname); 142 fdprintf(ptid, "x res %d %d %d\n", Inch, Hor, Vert); 143 fdprintf(ptid, "x init\n"); /* do initialization for particular device */ 144 #ifdef notdef 145 for (i = 1; i <= nfonts; i++) 146 fdprintf(ptid, "x font %d %s\n", i, fontbase[i]->namefont); 147 fdprintf(ptid, "x xxx fonts=%d sizes=%d unit=%d\n", nfonts, nsizes, Unitwidth); 148 fdprintf(ptid, "x xxx nchtab=%d lchname=%d nfitab=%d\n", 149 dev.nchtab, dev.lchname, dev.nchtab+128-32); 150 fdprintf(ptid, "x xxx sizes:\nx xxx "); 151 for (i = 0; i < nsizes; i++) 152 fdprintf(ptid, " %d", pstab[i]); 153 fdprintf(ptid, "\nx xxx chars:\nx xxx "); 154 for (i = 0; i < dev.nchtab; i++) 155 fdprintf(ptid, " %s", &chname[chtab[i]]); 156 fdprintf(ptid, "\nx xxx\n"); 157 #endif 158 } 159 160 specnames() 161 { 162 static struct { 163 int *n; 164 char *v; 165 } spnames[] = { 166 &c_hyphen, "hy", 167 &c_emdash, "em", 168 &c_rule, "ru", 169 &c_minus, "\\-", 170 &c_fi, "fi", 171 &c_fl, "fl", 172 &c_ff, "ff", 173 &c_ffi, "Fi", 174 &c_ffl, "Fl", 175 &c_acute, "aa", 176 &c_grave, "ga", 177 &c_under, "ul", 178 &c_rooten, "rn", 179 &c_boxrule, "br", 180 &c_lefthand, "lh", 181 &c_dagger, "dg", 182 0, 0 183 }; 184 int i; 185 186 for (i = 0; spnames[i].n; i++) 187 *spnames[i].n = findch(spnames[i].v); 188 } 189 190 findch(s) /* find char s in chname */ 191 register char *s; 192 { 193 register int i; 194 195 for (i = 0; i < nchtab; i++) 196 if (strcmp(s, &chname[chtab[i]]) == 0) 197 return(i + 128); 198 return(0); 199 } 200 201 ptout(i) 202 register tchar i; 203 { 204 register dv; 205 register tchar *k; 206 int temp, a, b; 207 208 if (cbits(i) != '\n') { 209 *olinep++ = i; 210 return; 211 } 212 if (olinep == oline) { 213 lead += lss; 214 return; 215 } 216 217 hpos = po; /* ??? */ 218 esc = 0; /* ??? */ 219 ptesc(); /* the problem is to get back to the left end of the line */ 220 dv = 0; 221 for (k = oline; k < olinep; k++) { 222 if (ismot(*k) && isvmot(*k)) { 223 temp = absmot(*k); 224 if (isnmot(*k)) 225 temp = -temp; 226 dv += temp; 227 } 228 } 229 if (dv) { 230 vflag++; 231 *olinep++ = makem(-dv); 232 vflag = 0; 233 } 234 235 b = dip->blss + lss; 236 lead += dip->blss + lss; 237 dip->blss = 0; 238 for (k = oline; k < olinep; ) 239 k += ptout0(k); /* now passing a pointer! */ 240 olinep = oline; 241 lead += dip->alss; 242 a = dip->alss; 243 dip->alss = 0; 244 /* 245 fdprintf(ptid, "x xxx end of line: hpos=%d, vpos=%d\n", hpos, vpos); 246 */ 247 fdprintf(ptid, "n%d %d\n", b, a); /* be nice to chuck */ 248 } 249 250 ptout0(pi) 251 tchar *pi; 252 { 253 register short j, k, w; 254 short z, dx, dy, dx2, dy2, n; 255 register tchar i; 256 int outsize; /* size of object being printed */ 257 258 outsize = 1; /* default */ 259 i = *pi; 260 k = cbits(i); 261 if (ismot(i)) { 262 j = absmot(i); 263 if (isnmot(i)) 264 j = -j; 265 if (isvmot(i)) 266 lead += j; 267 else 268 esc += j; 269 return(outsize); 270 } 271 if (k == XON) { 272 int c; 273 if (xfont != mfont) 274 ptfont(); 275 if (xpts != mpts) 276 ptps(); 277 if (lead) 278 ptlead(); 279 if (esc) /* for psfig ???*/ 280 ptesc(); 281 fdprintf(ptid, "x X "); 282 for (j = 1; (c=cbits(pi[j])) != XOFF; j++) 283 outascii(pi[j]); 284 oput('\n'); 285 return j+1; 286 } 287 ; 288 if (k == CHARHT) { 289 if (xpts != mpts) 290 ptps(); 291 fdprintf(ptid, "x H %d\n", sbits(i)); 292 return(outsize); 293 } 294 if (k == SLANT) { 295 fdprintf(ptid, "x S %d\n", sfbits(i)-180); 296 return(outsize); 297 } 298 if (k == WORDSP) { 299 oput('w'); 300 return(outsize); 301 } 302 if (sfbits(i) == oldbits) { 303 xfont = pfont; 304 xpts = ppts; 305 } else 306 xbits(i, 2); 307 if (k < 040 && k != DRAWFCN) 308 return(outsize); 309 /* 310 * Bug fix, if k == DRAWFCN, thewidcache gets a negative index. 311 * This worked by magic on the vax and tahoe, but caused somtimes 312 * a segment violaton on the suns. 313 * 314 * The code was plainly wrong (jna). 315 */ 316 if ( k != DRAWFCN) { 317 if (widcache[k-32].fontpts == (xfont<<8) + xpts && !setwdf) { 318 w = widcache[k-32].width; 319 bd = 0; 320 cs = 0; 321 } else 322 w = getcw(k-32); 323 } 324 j = z = 0; 325 if (k != DRAWFCN) { 326 if (cs) { 327 if (bd) 328 w += (bd - 1) * HOR; 329 j = (cs - w) / 2; 330 w = cs - j; 331 if (bd) 332 w -= (bd - 1) * HOR; 333 } 334 if (iszbit(i)) { 335 if (cs) 336 w = -j; 337 else 338 w = 0; 339 z = 1; 340 } 341 } 342 esc += j; 343 if (xfont != mfont) 344 ptfont(); 345 if (xpts != mpts) 346 ptps(); 347 if (lead) 348 ptlead(); 349 /* put out the real character here */ 350 if (k == DRAWFCN) { 351 if (esc) 352 ptesc(); 353 dx = absmot(pi[3]); 354 if (isnmot(pi[3])) 355 dx = -dx; 356 dy = absmot(pi[4]); 357 if (isnmot(pi[4])) 358 dy = -dy; 359 switch (cbits(pi[1])) { 360 case DRAWCIRCLE: /* circle */ 361 fdprintf(ptid, "D%c %d\n", DRAWCIRCLE, dx); /* dx is diameter */ 362 w = 0; 363 hpos += dx; 364 break; 365 case DRAWELLIPSE: 366 fdprintf(ptid, "D%c %d %d\n", DRAWELLIPSE, dx, dy); 367 w = 0; 368 hpos += dx; 369 break; 370 case DRAWLINE: /* line */ 371 k = cbits(pi[2]); 372 fdprintf(ptid, "D%c %d %d ", DRAWLINE, dx, dy); 373 if (k < 128) 374 fdprintf(ptid, "%c\n", k); 375 else 376 fdprintf(ptid, "%s\n", &chname[chtab[k - 128]]); 377 w = 0; 378 hpos += dx; 379 vpos += dy; 380 break; 381 case DRAWARC: /* arc */ 382 dx2 = absmot(pi[5]); 383 if (isnmot(pi[5])) 384 dx2 = -dx2; 385 dy2 = absmot(pi[6]); 386 if (isnmot(pi[6])) 387 dy2 = -dy2; 388 fdprintf(ptid, "D%c %d %d %d %d\n", DRAWARC, 389 dx, dy, dx2, dy2); 390 w = 0; 391 hpos += dx + dx2; 392 vpos += dy + dy2; 393 break; 394 case DRAWSPLINE: /* spline */ 395 default: /* something else; copy it like spline */ 396 fdprintf(ptid, "D%c %d %d", cbits(pi[1]), dx, dy); 397 w = 0; 398 hpos += dx; 399 vpos += dy; 400 if (cbits(pi[3]) == DRAWFCN || cbits(pi[4]) == DRAWFCN) { 401 /* it was somehow defective */ 402 fdprintf(ptid, "\n"); 403 break; 404 } 405 for (n = 5; cbits(pi[n]) != DRAWFCN; n += 2) { 406 dx = absmot(pi[n]); 407 if (isnmot(pi[n])) 408 dx = -dx; 409 dy = absmot(pi[n+1]); 410 if (isnmot(pi[n+1])) 411 dy = -dy; 412 fdprintf(ptid, " %d %d", dx, dy); 413 hpos += dx; 414 vpos += dy; 415 } 416 fdprintf(ptid, "\n"); 417 break; 418 } 419 for (n = 3; cbits(pi[n]) != DRAWFCN; n++) 420 ; 421 outsize = n + 1; 422 } else if (k < 128) { 423 /* try to go faster and compress output */ 424 /* by printing nnc for small positive motion followed by c */ 425 /* kludgery; have to make sure set all the vars too */ 426 if (esc > 0 && esc < 100) { 427 oput(esc / 10 + '0'); 428 oput(esc % 10 + '0'); 429 oput(k); 430 hpos += esc; 431 esc = 0; 432 } else { 433 if (esc) 434 ptesc(); 435 oput('c'); 436 oput(k); 437 oput('\n'); 438 } 439 } else { 440 if (esc) 441 ptesc(); 442 if (k >= nchtab + 128) 443 fdprintf(ptid, "N%d\n", k - (nchtab+128)); 444 else 445 fdprintf(ptid, "C%s\n", &chname[chtab[k - 128]]); 446 } 447 if (bd) { 448 bd -= HOR; 449 if (esc += bd) 450 ptesc(); 451 if (k < 128) { 452 fdprintf(ptid, "c%c\n", k); 453 } else if (k >= nchtab + 128) { 454 fdprintf(ptid, "N%d\n", k - (nchtab+128)); 455 } else 456 fdprintf(ptid, "C%s\n", &chname[chtab[k - 128]]); 457 if (z) 458 esc -= bd; 459 } 460 esc += w; 461 return(outsize); 462 } 463 464 ptps() 465 { 466 register i, j, k; 467 468 i = xpts; 469 for (j = 0; i > (k = pstab[j]); j++) 470 if (!k) { 471 k = pstab[--j]; 472 break; 473 } 474 fdprintf(ptid, "s%d\n", k); /* really should put out string rep of size */ 475 mpts = i; 476 } 477 478 ptfont() 479 { 480 extern char *unpair(); 481 mfont = xfont; 482 if( xfont > physfonts) { 483 if (xfont != zfont) { 484 register char *temp = unpair(fontlab[xfont]); 485 ptfpcmd(0, temp); /* Put the desired font in the 486 * fontcache of the filter */ 487 } 488 fdprintf(ptid, "f0\n"); /* make sure that it gets noticed */ 489 zfont = xfont; 490 } else 491 fdprintf(ptid, "f%d\n", xfont); 492 } 493 494 ptfpcmd(f, s) 495 int f; 496 char *s; 497 { 498 if (ascii) 499 return; 500 fdprintf(ptid, "x font %d %s\n", f, s); 501 } 502 503 ptlead() 504 { 505 vpos += lead; 506 if (!ascii) 507 fdprintf(ptid, "V%d\n", vpos); 508 lead = 0; 509 } 510 511 ptesc() 512 { 513 hpos += esc; 514 if (esc > 0) { 515 oput('h'); 516 if (esc>=10 && esc<100) { 517 oput(esc/10 + '0'); 518 oput(esc%10 + '0'); 519 } else 520 fdprintf(ptid, "%d", esc); 521 } else 522 fdprintf(ptid, "H%d\n", hpos); 523 esc = 0; 524 } 525 526 newpage(n) /* called at end of each output page (we hope) */ 527 { 528 int i; 529 530 ptlead(); 531 vpos = 0; 532 if (ascii) 533 return; 534 fdprintf(ptid, "p%d\n", n); /* new page */ 535 if (fontbase[zfont]->namefont && fontbase[zfont]->namefont[0]) 536 fdprintf(ptid, "x font 0 %s\n", fontbase[zfont]->namefont); 537 for (i = 1; i <= physfonts; i++) 538 if (fontbase[i]->namefont && fontbase[i]->namefont[0]) 539 fdprintf(ptid, "x font %d %s\n", i, fontbase[i]->namefont); 540 ptps(); 541 ptfont(); 542 } 543 544 pttrailer() 545 { 546 fdprintf(ptid, "x trailer\n"); 547 } 548 549 ptstop() 550 { 551 fdprintf(ptid, "x stop\n"); 552 } 553 554 dostop() 555 { 556 if (ascii) 557 return; 558 ptlead(); 559 vpos = 0; 560 /* fdprintf(ptid, "x xxx end of page\n");*/ 561 if (!nofeed) 562 pttrailer(); 563 ptlead(); 564 fdprintf(ptid, "x pause\n"); 565 flusho(); 566 mpts = mfont = 0; 567 ptesc(); 568 esc = po; 569 hpos = vpos = 0; /* probably in wrong place */ 570 } 571