1 #include "tdef.h" 2 extern 3 #include "d.h" 4 extern 5 #include "v.h" 6 /* 7 troff10.c 8 9 CAT interface 10 */ 11 12 #include <sgtty.h> 13 #include "ext.h" 14 int vpos = 0; /* absolute vertical position on page */ 15 int hpos = 0; /* ditto horizontal */ 16 17 #define T_IESC 16 18 19 short *chtab; 20 char *chname; 21 char *fontab[NFONT+1]; 22 char *kerntab[NFONT+1]; 23 char *fitab[NFONT+1]; 24 25 int Inch; 26 int Hor; 27 int Vert; 28 int Unitwidth; 29 int nfonts; 30 int nsizes; 31 int nchtab; 32 int nstips; 33 int xstip = ~ST; 34 tchar * stiplab; 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_narsp; 46 int c_hnarsp; 47 int c_fi; 48 int c_fl; 49 int c_ff; 50 int c_ffi; 51 int c_ffl; 52 int c_acute; 53 int c_grave; 54 int c_under; 55 int c_rooten; 56 int c_boxrule; 57 int c_lefthand; 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 *setbrk(), *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 fprintf(stderr, "troff: can't open tables for %s\n", termtab); 78 done3(1); 79 } 80 read(fin, &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.nstips; 89 /* "unsigned" so very large files will work properly */ 90 stiplab = (tchar *) setbrk((nstips + 1) * sizeof(tchar)); 91 filebase = setbrk((unsigned short) dev.filesize + 2*EXTRAFONT); 92 /* 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 & BMASK; /* 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 p += sizeof(struct font); /* that's what's on the beginning */ 104 fontab[i] = p; 105 kerntab[i] = p + nw; 106 fitab[i] = p + 3 * nw; /* skip width, kern, code */ 107 p += 3 * nw + dev.nchtab + 128 - 32; 108 } 109 for (i = 1; i <= nstips; i++) { /* make stipple names tchars */ 110 stiplab[i] = PAIR(*p, *(p+1)); 111 while (*(p++)); 112 } 113 fontbase[0] = (struct font *) p; /* the last shall be first */ 114 fontbase[0]->nwfont = EXTRAFONT - dev.nchtab - (128-32) - sizeof (struct font); 115 fontab[0] = p + sizeof (struct font); 116 close(fin); 117 /* there are a lot of things that used to be constant 118 /* that now require code to be executed. 119 */ 120 sps = SPS; 121 ics = ICS; 122 for (i = 0; i < 16; i++) 123 tabtab[i] = DTAB * (i + 1); 124 pl = 11 * INCH; 125 po = PO; 126 spacesz = SS; 127 lss = lss1 = VS; 128 ll = ll1 = lt = lt1 = LL; 129 specnames(); /* install names like "hyphen", etc. */ 130 if (ascii) 131 return; 132 fprintf(ptid, "x T %s\n", devname); 133 fprintf(ptid, "x res %d %d %d\n", Inch, Hor, Vert); 134 fprintf(ptid, "x init\n"); /* do initialization for particular device */ 135 for (i = 1; i <= nfonts; i++) 136 fprintf(ptid, "x font %d %s\n", i, fontbase[i]->namefont); 137 /* 138 fprintf(ptid, "x xxx fonts=%d sizes=%d unit=%d\n", nfonts, nsizes, Unitwidth); 139 fprintf(ptid, "x xxx nchtab=%d lchname=%d nfitab=%d\n", 140 dev.nchtab, dev.lchname, dev.nchtab+128-32); 141 fprintf(ptid, "x xxx sizes:\nx xxx "); 142 for (i = 0; i < nsizes; i++) 143 fprintf(ptid, " %d", pstab[i]); 144 fprintf(ptid, "\nx xxx chars:\nx xxx "); 145 for (i = 0; i < dev.nchtab; i++) 146 fprintf(ptid, " %s", &chname[chtab[i]]); 147 fprintf(ptid, "\nx xxx\n"); 148 */ 149 } 150 151 specnames() 152 { 153 static struct { 154 int *n; 155 char *v; 156 } spnames[] = { 157 &c_hyphen, "hy", 158 &c_emdash, "em", 159 &c_rule, "ru", 160 &c_minus, "\\-", 161 &c_narsp, "\\|", 162 &c_hnarsp, "\\^", 163 &c_fi, "fi", 164 &c_fl, "fl", 165 &c_ff, "ff", 166 &c_ffi, "Fi", 167 &c_ffl, "Fl", 168 &c_acute, "aa", 169 &c_grave, "ga", 170 &c_under, "ul", 171 &c_rooten, "rn", 172 &c_boxrule, "br", 173 &c_lefthand, "lh", 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 tchar i; 195 { 196 register dv, ik; 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 fprintf(ptid, "x xxx end of line: hpos=%d, vpos=%d\n", hpos, vpos); 238 */ 239 fprintf(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 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 == CHARHT) { 264 fprintf(ptid, "x H %d\n", sbits(i)); 265 return(outsize); 266 } 267 if (k == SLANT) { 268 fprintf(ptid, "x S %d\n", sfbits(i)-180); 269 return(outsize); 270 } 271 if (k == WORDSP) { 272 oput('w'); 273 return(outsize); 274 } 275 if (k == FONTPOS) { 276 char temp[3]; 277 n = i >> 16; 278 temp[0] = n & BMASK; 279 temp[1] = n >> BYTE; 280 temp[2] = 0; 281 ptfpcmd(0, temp); 282 return(outsize); 283 } 284 xbitf = 2; 285 if (sfbits(i) == oldbits) { 286 xfont = pfont; 287 xpts = ppts; 288 xbitf = 0; 289 } else 290 xbits(i); 291 if (k < 040 && k != DRAWFCN) 292 return(outsize); 293 w = getcw(k - 32); 294 j = z = 0; 295 if (k != DRAWFCN) { 296 if (cs) { 297 if (bd) 298 w += (bd - 1) * HOR; 299 j = (cs - w) / 2; 300 w = cs - j; 301 if (bd) 302 w -= (bd - 1) * HOR; 303 } 304 if (iszbit(i)) { 305 if (cs) 306 w = -j; 307 else 308 w = 0; 309 z = 1; 310 } 311 } 312 esc += j; 313 if (xfont != mfont) 314 ptfont(); 315 if (xpts != mpts) 316 ptps(); 317 if (lead) 318 ptlead(); 319 /* put out the real character here */ 320 if (k == DRAWFCN) { 321 if (esc) 322 ptesc(); 323 dx = absmot(pi[2]); 324 if (isnmot(pi[2])) 325 dx = -dx; 326 dy = absmot(pi[3]); 327 if (isnmot(pi[3])) 328 dy = -dy; 329 switch (cbits(pi[1])) { 330 case DRAWCIRCLE: /* circle */ 331 fprintf(ptid, "D%c %d\n", DRAWCIRCLE, dx); /* dx is diameter */ 332 hpos += dx; 333 break; 334 case DRAWSTYLE: 335 fprintf(ptid, "D%c %d\n", DRAWSTYLE, dx); 336 break; 337 case DRAWTHICK: 338 fprintf(ptid, "D%c %d\n", DRAWTHICK, dx); 339 break; 340 case DRAWELLIPSE: 341 fprintf(ptid, "D%c %d %d\n", DRAWELLIPSE, dx, dy); 342 hpos += dx; 343 break; 344 case DRAWLINE: /* line */ 345 fprintf(ptid, "D%c %d %d\n", DRAWLINE, dx, dy); 346 hpos += dx; 347 vpos += dy; 348 break; 349 case DRAWARC: /* arc */ 350 dx2 = absmot(pi[4]); 351 if (isnmot(pi[4])) 352 dx2 = -dx2; 353 dy2 = absmot(pi[5]); 354 if (isnmot(pi[5])) 355 dy2 = -dy2; 356 fprintf(ptid, "D%c %d %d %d %d\n", DRAWARC, 357 dx, dy, dx2, dy2); 358 hpos += dx + dx2; 359 vpos += dy + dy2; 360 break; 361 case DRAWWIG: /* wiggly line -or- */ 362 case DRAWCURVE: /* gremlin-style curve */ 363 fprintf(ptid, "D%c %d %d", cbits(pi[1]), dx, dy); 364 hpos += dx; 365 vpos += dy; 366 writecoords: 367 for (n = 4; cbits(pi[n]) != '.'; n += 2) { 368 dx = absmot(pi[n]); 369 if (isnmot(pi[n])) 370 dx = -dx; 371 dy = absmot(pi[n+1]); 372 if (isnmot(pi[n+1])) 373 dy = -dy; 374 fprintf(ptid, " %d %d", dx, dy); 375 hpos += dx; 376 vpos += dy; 377 } 378 fprintf(ptid, "\n"); 379 break; 380 381 case DRAWPOLY: /* polygon with stipple */ 382 case DRAWUBPOLY:/* polygon, stipple, no border */ 383 if (xstip != stip) ptstip(); 384 fprintf(ptid, "D%c %d", cbits(pi[1]), dx); 385 goto writecoords; 386 } 387 for (n = 2; cbits(pi[n]) != '.'; n++) 388 ; 389 return(n + 1); /* leave here so the emboldening */ 390 } else if (k < 128) { /* doesn't screw up the graphics */ 391 /* try to go faster and compress output */ 392 /* by printing nnc for small positive motion followed by c */ 393 /* kludgery; have to make sure set all the vars too */ 394 if (esc > 0 && esc < 100) { 395 oput(esc / 10 + '0'); 396 oput(esc % 10 + '0'); 397 oput(k); 398 hpos += esc; 399 esc = 0; 400 } else { 401 if (esc) 402 ptesc(); 403 fprintf(ptid, "c%c\n", k); 404 } 405 } else { 406 if (esc) 407 ptesc(); 408 fprintf(ptid, "C%s\n", &chname[chtab[k - 128]]); 409 } 410 if (bd) { 411 bd -= HOR; 412 if (esc += bd) 413 ptesc(); 414 if (k < 128) { 415 fprintf(ptid, "c%c\n", k); 416 } else 417 fprintf(ptid, "C%s\n", &chname[chtab[k - 128]]); 418 if (z) 419 esc -= bd; 420 } 421 esc += w; 422 return(outsize); 423 } 424 425 ptps() 426 { 427 register i, j, k; 428 429 i = xpts; 430 for (j = 0; i > (k = pstab[j]); j++) 431 if (!k) { 432 k = pstab[--j]; 433 break; 434 } 435 fprintf(ptid, "s%d\n", k); /* really should put out string rep of size */ 436 mpts = i; 437 } 438 439 ptstip() 440 { 441 xstip = stip; 442 fprintf(ptid, "i%d\n", xstip); 443 } 444 445 446 ptfont() 447 { 448 mfont = xfont; 449 fprintf(ptid, "f%d\n", xfont); 450 } 451 452 ptfpcmd(f, s) 453 int f; 454 char *s; 455 { 456 if (ascii) 457 return; 458 fprintf(ptid, "x font %d %s\n", f, s); 459 ptfont(); /* make sure that it gets noticed */ 460 } 461 462 ptlead() 463 { 464 vpos += lead; 465 if (!ascii) 466 fprintf(ptid, "V%d\n", vpos); 467 lead = 0; 468 } 469 470 ptesc() 471 { 472 hpos += esc; 473 if (esc > 0) 474 fprintf(ptid, "h%d", esc); 475 else 476 fprintf(ptid, "H%d\n", hpos); 477 esc = 0; 478 } 479 480 newpage(n) /* called at end of each output page (we hope) */ 481 { 482 ptlead(); 483 vpos = 0; 484 if (ascii) 485 return; 486 flusho(); 487 fprintf(ptid, "p%d\n", n); /* new page */ 488 ptps(); 489 ptfont(); 490 } 491 492 pttrailer() 493 { 494 fprintf(ptid, "x trailer\n"); 495 } 496 497 ptstop() 498 { 499 fprintf(ptid, "x stop\n"); 500 } 501 502 dostop() 503 { 504 if (ascii) 505 return; 506 ptlead(); 507 vpos = 0; 508 /* fprintf(ptid, "x xxx end of page\n");*/ 509 if (!nofeed) 510 pttrailer(); 511 ptlead(); 512 fprintf(ptid, "x pause\n"); 513 flusho(); 514 mpts = mfont = 0; 515 paper = 0; 516 esc = T_IESC; /* this is a dreg */ 517 ptesc(); 518 esc = po; 519 hpos = vpos = 0; /* probably in wrong place */ 520 } 521