t10.c (9444B)
1 #include "tdef.h" 2 #include "fns.h" 3 #include "ext.h" 4 5 /* 6 * troff10.c 7 * 8 * typesetter interface 9 */ 10 11 int vpos = 0; /* absolute vertical position on page */ 12 int hpos = 0; /* ditto horizontal */ 13 14 extern Font fonts[MAXFONTS+1]; 15 16 int Inch; 17 int Hor; 18 int Vert; 19 int Unitwidth; 20 int nfonts; 21 22 23 24 void t_ptinit(void) 25 { 26 int i; 27 char buf[100], *p; 28 29 hmot = t_hmot; 30 makem = t_makem; 31 setabs = t_setabs; 32 setch = t_setch; 33 sethl = t_sethl; 34 setht = t_setht; 35 setslant = t_setslant; 36 vmot = t_vmot; 37 xlss = t_xlss; 38 findft = t_findft; 39 width = t_width; 40 mchbits = t_mchbits; 41 ptlead = t_ptlead; 42 ptout = t_ptout; 43 ptpause = t_ptpause; 44 setfont = t_setfont; 45 setps = t_setps; 46 setwd = t_setwd; 47 48 /* open table for device, */ 49 /* read in resolution, size info, font info, etc., set params */ 50 if ((p = getenv("TYPESETTER")) != 0) 51 strcpy(devname, p); 52 if (termtab[0] == 0) 53 strcpy(termtab, DWBfontdir); 54 if (fontdir[0] == 0) 55 strcpy(fontdir, DWBfontdir); 56 if (devname[0] == 0) 57 strcpy(devname, TDEVNAME); 58 hyf = 1; 59 lg = 1; 60 61 sprintf(buf, "/dev%s/DESC", devname); 62 strcat(termtab, buf); 63 if (getdesc(termtab) < 0) { 64 ERROR "can't open DESC file %s", termtab WARN; 65 done3(1); 66 } 67 if (!ascii) { 68 OUT "x T %s\n", devname PUT; 69 OUT "x res %d %d %d\n", Inch, Hor, Vert PUT; 70 OUT "x init\n" PUT; 71 } 72 for (i = 1; i <= nfonts; i++) 73 setfp(i, fontlab[i], (char *) 0, 0); 74 sps = EM/3; /* space size */ 75 ics = EM; /* insertion character space */ 76 for (i = 0; i < (NTAB - 1) && DTAB * (i + 1) < TABMASK; i++) 77 tabtab[i] = DTAB * (i + 1); 78 tabtab[NTAB-1] = 0; 79 pl = 11 * INCH; /* paper length */ 80 po = PO; /* page offset */ 81 spacesz = SS; 82 lss = lss1 = VS; 83 ll = ll1 = lt = lt1 = LL; 84 t_specnames(); /* install names like "hyphen", etc. */ 85 } 86 87 void t_specnames(void) 88 { 89 int i; 90 91 for (i = 0; spnames[i].n; i++) 92 *spnames[i].n = chadd(spnames[i].v, Troffchar, Install); 93 } 94 95 void t_ptout(Tchar i) 96 { 97 int dv; 98 Tchar *k; 99 int temp, a, b; 100 int diff; 101 102 if (cbits(i) != '\n') { 103 if (olinep >= oline + olnsize) { 104 diff = olinep - oline; 105 olnsize += OLNSIZE; 106 if ((oline = (Tchar *)realloc((char *)oline, olnsize * sizeof(Tchar))) != NULL) { 107 if (diff && olinep) 108 olinep = oline + diff; 109 } else { 110 ERROR "Output line overflow." WARN; 111 done(2); 112 } 113 } 114 *olinep++ = i; 115 return; 116 } 117 if (olinep == oline) { 118 lead += lss; 119 return; 120 } 121 122 hpos = po; /* ??? */ 123 esc = 0; /* ??? */ 124 ptesc(); /* the problem is to get back to the left end of the line */ 125 dv = 0; 126 for (k = oline; k < olinep; k++) { 127 if (ismot(*k) && isvmot(*k)) { 128 temp = absmot(*k); 129 if (isnmot(*k)) 130 temp = -temp; 131 dv += temp; 132 } 133 } 134 if (dv) { 135 vflag++; 136 *olinep++ = makem(-dv); 137 vflag = 0; 138 } 139 140 b = dip->blss + lss; 141 lead += dip->blss + lss; 142 dip->blss = 0; 143 for (k = oline; k < olinep; ) 144 k += ptout0(k); /* now passing a pointer! */ 145 olinep = oline; 146 lead += dip->alss; 147 a = dip->alss; 148 dip->alss = 0; 149 /* 150 OUT "x xxx end of line: hpos=%d, vpos=%d\n", hpos, vpos PUT; 151 */ 152 OUT "n%d %d\n", b, a PUT; /* be nice to chuck */ 153 } 154 155 int ptout0(Tchar *pi) 156 { 157 int j, k, w; 158 int z, dx, dy, dx2, dy2, n; 159 Tchar i; 160 int outsize; /* size of object being printed */ 161 162 w = 0; 163 outsize = 1; /* default */ 164 i = *pi; 165 k = cbits(i); 166 if (ismot(i)) { 167 j = absmot(i); 168 if (isnmot(i)) 169 j = -j; 170 if (isvmot(i)) 171 lead += j; 172 else 173 esc += j; 174 return(outsize); 175 } 176 if (k == CHARHT) { 177 xpts = fbits(i); /* sneaky, font bits as size bits */ 178 if (xpts != mpts) 179 ptps(); 180 OUT "x H %ld\n", sbits(i) PUT; 181 return(outsize); 182 } 183 if (k == SLANT) { 184 OUT "x S %ld\n", sfbits(i)-180 PUT; 185 return(outsize); 186 } 187 if (k == WORDSP) { 188 oput('w'); 189 return(outsize); 190 } 191 if (sfbits(i) == oldbits) { 192 xfont = pfont; 193 xpts = ppts; 194 } else 195 xbits(i, 2); 196 if (k == XON) { 197 extern int xon; 198 ptflush(); /* guarantee that everything is out */ 199 if (esc) 200 ptesc(); 201 if (xfont != mfont) 202 ptfont(); 203 if (xpts != mpts) 204 ptps(); 205 if (lead) 206 ptlead(); 207 OUT "x X " PUT; 208 xon++; 209 for (j = 1; cbits(pi[j]) != XOFF; j++) 210 outascii(pi[j]); 211 oput('\n'); 212 xon--; 213 return j+1; 214 } 215 if (k < 040 && k != DRAWFCN) 216 return(outsize); 217 j = z = 0; 218 if (k != DRAWFCN) { 219 if (widcache[k].fontpts == (xfont<<8) + xpts && !setwdf) { 220 w = widcache[k].width; 221 bd = 0; 222 cs = 0; 223 } else 224 w = getcw(k); 225 if (cs) { 226 if (bd) 227 w += (bd - 1) * HOR; 228 j = (cs - w) / 2; 229 w = cs - j; 230 if (bd) 231 w -= (bd - 1) * HOR; 232 } 233 if (iszbit(i)) { 234 if (cs) 235 w = -j; 236 else 237 w = 0; 238 z = 1; 239 } 240 } 241 esc += j; 242 if (xfont != mfont) 243 ptfont(); 244 if (xpts != mpts) 245 ptps(); 246 if (lead) 247 ptlead(); 248 /* put out the real character here */ 249 if (k == DRAWFCN) { 250 if (esc) 251 ptesc(); 252 w = 0; 253 dx = absmot(pi[3]); 254 if (isnmot(pi[3])) 255 dx = -dx; 256 dy = absmot(pi[4]); 257 if (isnmot(pi[4])) 258 dy = -dy; 259 switch (cbits(pi[1])) { 260 case DRAWCIRCLE: /* circle */ 261 OUT "D%c %d\n", DRAWCIRCLE, dx PUT; /* dx is diameter */ 262 hpos += dx; 263 break; 264 case DRAWELLIPSE: 265 OUT "D%c %d %d\n", DRAWELLIPSE, dx, dy PUT; 266 hpos += dx; 267 break; 268 case DRAWBUILD: 269 k = cbits(pi[2]); 270 OUT "D%c %d ", DRAWBUILD, dx PUT; 271 if (k < ALPHABET) 272 OUT "%c\n", k PUT; 273 else 274 ptchname(k); 275 hpos += dx; 276 break; 277 case DRAWLINE: /* line */ 278 k = cbits(pi[2]); 279 OUT "D%c %d %d ", DRAWLINE, dx, dy PUT; 280 if (k < ALPHABET) 281 OUT "%c\n", k PUT; 282 else 283 ptchname(k); 284 hpos += dx; 285 vpos += dy; 286 break; 287 case DRAWARC: /* arc */ 288 dx2 = absmot(pi[5]); 289 if (isnmot(pi[5])) 290 dx2 = -dx2; 291 dy2 = absmot(pi[6]); 292 if (isnmot(pi[6])) 293 dy2 = -dy2; 294 OUT "D%c %d %d %d %d\n", DRAWARC, 295 dx, dy, dx2, dy2 PUT; 296 hpos += dx + dx2; 297 vpos += dy + dy2; 298 break; 299 300 case 's': /* using 's' internally to avoid .tr ~ */ 301 pi[1] = '~'; 302 case DRAWSPLINE: /* spline */ 303 default: /* something else; copy it like spline */ 304 OUT "D%c %d %d", (char)cbits(pi[1]), dx, dy PUT; 305 hpos += dx; 306 vpos += dy; 307 if (cbits(pi[3]) == DRAWFCN || cbits(pi[4]) == DRAWFCN) { 308 /* it was somehow defective */ 309 OUT "\n" PUT; 310 break; 311 } 312 for (n = 5; cbits(pi[n]) != DRAWFCN; n += 2) { 313 dx = absmot(pi[n]); 314 if (isnmot(pi[n])) 315 dx = -dx; 316 dy = absmot(pi[n+1]); 317 if (isnmot(pi[n+1])) 318 dy = -dy; 319 OUT " %d %d", dx, dy PUT; 320 hpos += dx; 321 vpos += dy; 322 } 323 OUT "\n" PUT; 324 break; 325 } 326 for (n = 3; cbits(pi[n]) != DRAWFCN; n++) 327 ; 328 outsize = n + 1; 329 } else if (k < ALPHABET) { 330 /* try to go faster and compress output */ 331 /* by printing nnc for small positive motion followed by c */ 332 /* kludgery; have to make sure set all the vars too */ 333 if (esc > 0 && esc < 100) { 334 oput(esc / 10 + '0'); 335 oput(esc % 10 + '0'); 336 oput(k); 337 hpos += esc; 338 esc = 0; 339 } else { 340 if (esc) 341 ptesc(); 342 oput('c'); 343 oput(k); 344 oput('\n'); 345 } 346 } else { 347 if (esc) 348 ptesc(); 349 ptchname(k); 350 } 351 if (bd) { 352 bd -= HOR; 353 if (esc += bd) 354 ptesc(); 355 if (k < ALPHABET) 356 OUT "c%c\n", k PUT; 357 else 358 ptchname(k); 359 if (z) 360 esc -= bd; 361 } 362 esc += w; 363 return(outsize); 364 } 365 366 void ptchname(int k) 367 { 368 char *chn = chname(k); 369 370 switch (chn[0]) { 371 case MBchar: 372 OUT "c%s\n", chn+1 PUT; /* \n not needed? */ 373 break; 374 case Number: 375 OUT "N%s\n", chn+1 PUT; 376 break; 377 case Troffchar: 378 OUT "C%s\n", chn+1 PUT; 379 break; 380 default: 381 ERROR "illegal char type %s", chn WARN; 382 break; 383 } 384 } 385 386 void ptflush(void) /* get us to a clean output state */ 387 { 388 if (TROFF) { 389 /* ptesc(); but always H, no h */ 390 hpos += esc; 391 OUT "\nH%d\n", hpos PUT; 392 esc = 0; 393 ptps(); 394 ptfont(); 395 ptlead(); 396 } 397 } 398 399 void ptps(void) 400 { 401 int i, j, k; 402 403 i = xpts; 404 for (j = 0; i > (k = pstab[j]); j++) 405 if (!k) { 406 k = pstab[--j]; 407 break; 408 } 409 if (!ascii) 410 OUT "s%d\n", k PUT; /* really should put out string rep of size */ 411 mpts = i; 412 } 413 414 void ptfont(void) 415 { 416 mfont = xfont; 417 if (ascii) 418 return; 419 if (xfont > nfonts) { 420 ptfpcmd(0, fonts[xfont].longname, 0); /* Put the desired font in the 421 * fontcache of the filter */ 422 OUT "f0\n" PUT; /* make sure that it gets noticed */ 423 } else 424 OUT "f%d\n", xfont PUT; 425 } 426 427 void ptfpcmd(int f, char *s, char *longname) 428 { 429 if (f > nfonts) /* a bit risky? */ 430 f = 0; 431 if (longname) { 432 OUT "x font %d %s %s\n", f, s, longname PUT; 433 } else { 434 OUT "x font %d %s\n", f, s PUT; 435 } 436 /* OUT "f%d\n", xfont PUT; /* need this for buggy version of adobe transcript */ 437 /* which apparently believes that x font means */ 438 /* to set the font, not just the position. */ 439 } 440 441 void t_ptlead(void) 442 { 443 vpos += lead; 444 if (!ascii) 445 OUT "V%d\n", vpos PUT; 446 lead = 0; 447 } 448 449 void ptesc(void) 450 { 451 hpos += esc; 452 if (!ascii) 453 if (esc > 0) { 454 oput('h'); 455 if (esc>=10 && esc<100) { 456 oput(esc/10 + '0'); 457 oput(esc%10 + '0'); 458 } else 459 OUT "%d", esc PUT; 460 } else 461 OUT "H%d\n", hpos PUT; 462 esc = 0; 463 } 464 465 void ptpage(int n) /* called at end of each output page, we hope */ 466 { 467 int i; 468 469 if (NROFF) 470 return; 471 ptlead(); 472 vpos = 0; 473 if (ascii) 474 return; 475 OUT "p%d\n", n PUT; /* new page */ 476 for (i = 0; i <= nfonts; i++) 477 if (fontlab[i]) { 478 if (fonts[i].truename) 479 OUT "x font %d %s %s\n", i, fonts[i].longname, fonts[i].truename PUT; 480 else 481 OUT "x font %d %s\n", i, fonts[i].longname PUT; 482 } 483 ptps(); 484 ptfont(); 485 } 486 487 void pttrailer(void) 488 { 489 if (TROFF) 490 OUT "x trailer\n" PUT; 491 } 492 493 void ptstop(void) 494 { 495 if (TROFF) 496 OUT "x stop\n" PUT; 497 } 498 499 void t_ptpause(void) 500 { 501 if (ascii) 502 return; 503 ptlead(); 504 vpos = 0; 505 pttrailer(); 506 ptlead(); 507 OUT "x pause\n" PUT; 508 flusho(); 509 mpts = mfont = 0; 510 ptesc(); 511 esc = po; 512 hpos = vpos = 0; /* probably in wrong place */ 513 }