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