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