1 #ifndef lint 2 static char sccsid[] = "@(#)t10.c 2.1 (CWI) 85/07/18"; 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 fdprintf(ptid, "x X "); 269 for (j = 1; (c=cbits(pi[j])) != XOFF; j++) 270 outascii(pi[j]); 271 oput('\n'); 272 return j+1; 273 } 274 ; 275 if (k == CHARHT) { 276 if (xpts != mpts) 277 ptps(); 278 fdprintf(ptid, "x H %d\n", sbits(i)); 279 return(outsize); 280 } 281 if (k == SLANT) { 282 fdprintf(ptid, "x S %d\n", sfbits(i)-180); 283 return(outsize); 284 } 285 if (k == WORDSP) { 286 oput('w'); 287 return(outsize); 288 } 289 if (sfbits(i) == oldbits) { 290 xfont = pfont; 291 xpts = ppts; 292 } else 293 xbits(i, 2); 294 if (k < 040 && k != DRAWFCN) 295 return(outsize); 296 if (widcache[k-32].fontpts == (xfont<<8) + xpts && !setwdf) { 297 w = widcache[k-32].width; 298 bd = 0; 299 cs = 0; 300 } else 301 w = getcw(k-32); 302 j = z = 0; 303 if (k != DRAWFCN) { 304 if (cs) { 305 if (bd) 306 w += (bd - 1) * HOR; 307 j = (cs - w) / 2; 308 w = cs - j; 309 if (bd) 310 w -= (bd - 1) * HOR; 311 } 312 if (iszbit(i)) { 313 if (cs) 314 w = -j; 315 else 316 w = 0; 317 z = 1; 318 } 319 } 320 esc += j; 321 if (xfont != mfont) 322 ptfont(); 323 if (xpts != mpts) 324 ptps(); 325 if (lead) 326 ptlead(); 327 /* put out the real character here */ 328 if (k == DRAWFCN) { 329 if (esc) 330 ptesc(); 331 dx = absmot(pi[3]); 332 if (isnmot(pi[3])) 333 dx = -dx; 334 dy = absmot(pi[4]); 335 if (isnmot(pi[4])) 336 dy = -dy; 337 switch (cbits(pi[1])) { 338 case DRAWCIRCLE: /* circle */ 339 fdprintf(ptid, "D%c %d\n", DRAWCIRCLE, dx); /* dx is diameter */ 340 w = 0; 341 hpos += dx; 342 break; 343 case DRAWELLIPSE: 344 fdprintf(ptid, "D%c %d %d\n", DRAWELLIPSE, dx, dy); 345 w = 0; 346 hpos += dx; 347 break; 348 case DRAWLINE: /* line */ 349 k = cbits(pi[2]); 350 fdprintf(ptid, "D%c %d %d ", DRAWLINE, dx, dy); 351 if (k < 128) 352 fdprintf(ptid, "%c\n", k); 353 else 354 fdprintf(ptid, "%s\n", &chname[chtab[k - 128]]); 355 w = 0; 356 hpos += dx; 357 vpos += dy; 358 break; 359 case DRAWARC: /* arc */ 360 dx2 = absmot(pi[5]); 361 if (isnmot(pi[5])) 362 dx2 = -dx2; 363 dy2 = absmot(pi[6]); 364 if (isnmot(pi[6])) 365 dy2 = -dy2; 366 fdprintf(ptid, "D%c %d %d %d %d\n", DRAWARC, 367 dx, dy, dx2, dy2); 368 w = 0; 369 hpos += dx + dx2; 370 vpos += dy + dy2; 371 break; 372 case DRAWSPLINE: /* spline */ 373 default: /* something else; copy it like spline */ 374 fdprintf(ptid, "D%c %d %d", cbits(pi[1]), dx, dy); 375 w = 0; 376 hpos += dx; 377 vpos += dy; 378 if (cbits(pi[3]) == DRAWFCN || cbits(pi[4]) == DRAWFCN) { 379 /* it was somehow defective */ 380 fdprintf(ptid, "\n"); 381 break; 382 } 383 for (n = 5; cbits(pi[n]) != DRAWFCN; n += 2) { 384 dx = absmot(pi[n]); 385 if (isnmot(pi[n])) 386 dx = -dx; 387 dy = absmot(pi[n+1]); 388 if (isnmot(pi[n+1])) 389 dy = -dy; 390 fdprintf(ptid, " %d %d", dx, dy); 391 hpos += dx; 392 vpos += dy; 393 } 394 fdprintf(ptid, "\n"); 395 break; 396 } 397 for (n = 3; cbits(pi[n]) != DRAWFCN; n++) 398 ; 399 outsize = n + 1; 400 } else if (k < 128) { 401 /* try to go faster and compress output */ 402 /* by printing nnc for small positive motion followed by c */ 403 /* kludgery; have to make sure set all the vars too */ 404 if (esc > 0 && esc < 100) { 405 oput(esc / 10 + '0'); 406 oput(esc % 10 + '0'); 407 oput(k); 408 hpos += esc; 409 esc = 0; 410 } else { 411 if (esc) 412 ptesc(); 413 oput('c'); 414 oput(k); 415 oput('\n'); 416 } 417 } else { 418 if (esc) 419 ptesc(); 420 if (k >= nchtab + 128) 421 fdprintf(ptid, "N%d\n", k - (nchtab+128)); 422 else 423 fdprintf(ptid, "C%s\n", &chname[chtab[k - 128]]); 424 } 425 if (bd) { 426 bd -= HOR; 427 if (esc += bd) 428 ptesc(); 429 if (k < 128) { 430 fdprintf(ptid, "c%c\n", k); 431 } else if (k >= nchtab + 128) { 432 fdprintf(ptid, "N%d\n", k - (nchtab+128)); 433 } else 434 fdprintf(ptid, "C%s\n", &chname[chtab[k - 128]]); 435 if (z) 436 esc -= bd; 437 } 438 esc += w; 439 return(outsize); 440 } 441 442 ptps() 443 { 444 register i, j, k; 445 446 i = xpts; 447 for (j = 0; i > (k = pstab[j]); j++) 448 if (!k) { 449 k = pstab[--j]; 450 break; 451 } 452 fdprintf(ptid, "s%d\n", k); /* really should put out string rep of size */ 453 mpts = i; 454 } 455 456 ptfont() 457 { 458 extern char *unpair(); 459 mfont = xfont; 460 if( xfont > nfonts) { 461 register char *temp = unpair(fontlab[xfont]); 462 ptfpcmd(0, temp); /* Put the desired font in the 463 * fontcache of the filter */ 464 fdprintf(ptid, "f0\n"); /* make sure that it gets noticed */ 465 } else 466 fdprintf(ptid, "f%d\n", xfont); 467 } 468 469 ptfpcmd(f, s) 470 int f; 471 char *s; 472 { 473 if (ascii) 474 return; 475 fdprintf(ptid, "x font %d %s\n", f, s); 476 } 477 478 ptlead() 479 { 480 vpos += lead; 481 if (!ascii) 482 fdprintf(ptid, "V%d\n", vpos); 483 lead = 0; 484 } 485 486 ptesc() 487 { 488 hpos += esc; 489 if (esc > 0) { 490 oput('h'); 491 if (esc>=10 && esc<100) { 492 oput(esc/10 + '0'); 493 oput(esc%10 + '0'); 494 } else 495 fdprintf(ptid, "%d", esc); 496 } else 497 fdprintf(ptid, "H%d\n", hpos); 498 esc = 0; 499 } 500 501 newpage(n) /* called at end of each output page (we hope) */ 502 { 503 int i; 504 505 ptlead(); 506 vpos = 0; 507 if (ascii) 508 return; 509 fdprintf(ptid, "p%d\n", n); /* new page */ 510 for (i = 0; i <= nfonts; i++) 511 if (fontbase[i]->namefont && fontbase[i]->namefont[0]) 512 fdprintf(ptid, "x font %d %s\n", i, fontbase[i]->namefont); 513 ptps(); 514 ptfont(); 515 } 516 517 pttrailer() 518 { 519 fdprintf(ptid, "x trailer\n"); 520 } 521 522 ptstop() 523 { 524 fdprintf(ptid, "x stop\n"); 525 } 526 527 dostop() 528 { 529 if (ascii) 530 return; 531 ptlead(); 532 vpos = 0; 533 /* fdprintf(ptid, "x xxx end of page\n");*/ 534 if (!nofeed) 535 pttrailer(); 536 ptlead(); 537 fdprintf(ptid, "x pause\n"); 538 flusho(); 539 mpts = mfont = 0; 540 ptesc(); 541 esc = po; 542 hpos = vpos = 0; /* probably in wrong place */ 543 } 544