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