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