1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1989 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * University Copyright- Copyright (c) 1982, 1986, 1988 32 * The Regents of the University of California 33 * All Rights Reserved 34 * 35 * University Acknowledgment- Portions of this document are derived from 36 * software developed by the University of California, Berkeley, and its 37 * contributors. 38 */ 39 40 #include "tdef.h" 41 #include <ctype.h> 42 #include "ext.h" 43 /* 44 * troff10.c 45 * 46 * typesetter interface 47 */ 48 49 int vpos = 0; /* absolute vertical position on page */ 50 int hpos = 0; /* ditto horizontal */ 51 52 short *chtab; 53 char *chname; 54 char *fontab[NFONT+1]; 55 char *kerntab[NFONT+1]; 56 char *fitab[NFONT+1]; 57 char *codetab[NFONT+1]; 58 59 int Inch; 60 int Hor; 61 int Vert; 62 int Unitwidth; 63 int nfonts; 64 int nsizes; 65 int nchtab; 66 67 /* these characters are used as various signals or values 68 * in miscellaneous places. 69 * values are set in specnames in t10.c 70 */ 71 72 int c_hyphen; 73 int c_emdash; 74 int c_rule; 75 int c_minus; 76 int c_fi; 77 int c_fl; 78 int c_ff; 79 int c_ffi; 80 int c_ffl; 81 int c_acute; 82 int c_grave; 83 int c_under; 84 int c_rooten; 85 int c_boxrule; 86 int c_lefthand; 87 int c_dagger; 88 89 #include "dev.h" 90 struct dev dev; 91 struct Font *fontbase[NFONT+1]; 92 93 tchar *ptout0(); 94 95 96 int 97 ptinit() 98 { 99 int i, fin, nw; 100 char *setbrk(), *filebase, *p; 101 102 /* open table for device, 103 * read in resolution, size info, font info, etc. 104 * and set params 105 */ 106 strcat(termtab, "/dev"); 107 strcat(termtab, devname); 108 strcat(termtab, "/DESC.out"); /* makes "..../devXXX/DESC.out" */ 109 if ((fin = open(termtab, 0)) < 0) { 110 errprint(gettext("can't open tables for %s"), termtab); 111 done3(1); 112 } 113 read(fin, (char *) &dev, sizeof(struct dev )); 114 Inch = dev.res; 115 Hor = dev.hor; 116 Vert = dev.vert; 117 Unitwidth = dev.unitwidth; 118 nfonts = dev.nfonts; 119 nsizes = dev.nsizes; 120 nchtab = dev.nchtab; 121 if (nchtab >= NCHARS - 128) { 122 errprint(gettext("too many special characters in file %s"), 123 termtab); 124 done3(1); 125 } 126 filebase = setbrk(dev.filesize + 2*EXTRAFONT); /* enough room for whole file */ 127 read(fin, filebase, dev.filesize); /* all at once */ 128 pstab = (short *) filebase; 129 chtab = pstab + nsizes + 1; 130 chname = (char *) (chtab + dev.nchtab); 131 p = chname + dev.lchname; 132 for (i = 1; i <= nfonts; i++) { 133 fontbase[i] = (struct Font *) p; 134 nw = *p & BYTEMASK; /* 1st thing is width count */ 135 fontlab[i] = PAIR(fontbase[i]->namefont[0], fontbase[i]->namefont[1]); 136 /* for now, still 2 char names */ 137 if (smnt == 0 && fontbase[i]->specfont == 1) 138 smnt = i; /* first special font */ 139 p += sizeof(struct Font); /* that's what's on the beginning */ 140 fontab[i] = p; 141 kerntab[i] = p + nw; 142 codetab[i] = p + 2 * nw; 143 fitab[i] = p + 3 * nw; /* skip width, kern, code */ 144 p += 3 * nw + dev.nchtab + 128 - 32; 145 } 146 fontbase[0] = (struct Font *) p; /* the last shall be first */ 147 fontbase[0]->nwfont = EXTRAFONT - dev.nchtab - (128-32) - sizeof (struct Font); 148 fontab[0] = p + sizeof (struct Font); 149 close(fin); 150 /* there are a lot of things that used to be constant 151 * that now require code to be executed. 152 */ 153 sps = SPS; 154 ics = ICS; 155 for (i = 0; i < 16; i++) 156 tabtab[i] = DTAB * (i + 1); 157 pl = 11 * INCH; 158 po = PO; 159 spacesz = SS; 160 lss = lss1 = VS; 161 ll = ll1 = lt = lt1 = LL; 162 specnames(); /* install names like "hyphen", etc. */ 163 if (ascii) 164 return (0); 165 fdprintf(ptid, "x T %s\n", devname); 166 fdprintf(ptid, "x res %d %d %d\n", Inch, Hor, Vert); 167 fdprintf(ptid, "x init\n"); /* do initialization for particular device */ 168 /* 169 for (i = 1; i <= nfonts; i++) 170 fdprintf(ptid, "x font %d %s\n", i, fontbase[i]->namefont); 171 fdprintf(ptid, "x xxx fonts=%d sizes=%d unit=%d\n", nfonts, nsizes, Unitwidth); 172 fdprintf(ptid, "x xxx nchtab=%d lchname=%d nfitab=%d\n", 173 dev.nchtab, dev.lchname, dev.nchtab+128-32); 174 fdprintf(ptid, "x xxx sizes:\nx xxx "); 175 for (i = 0; i < nsizes; i++) 176 fdprintf(ptid, " %d", pstab[i]); 177 fdprintf(ptid, "\nx xxx chars:\nx xxx "); 178 for (i = 0; i < dev.nchtab; i++) 179 fdprintf(ptid, " %s", &chname[chtab[i]]); 180 fdprintf(ptid, "\nx xxx\n"); 181 */ 182 183 return (0); 184 } 185 186 int 187 specnames() 188 { 189 static struct { 190 int *n; 191 char *v; 192 } spnames[] = { 193 &c_hyphen, "hy", 194 &c_emdash, "em", 195 &c_rule, "ru", 196 &c_minus, "\\-", 197 &c_fi, "fi", 198 &c_fl, "fl", 199 &c_ff, "ff", 200 &c_ffi, "Fi", 201 &c_ffl, "Fl", 202 &c_acute, "aa", 203 &c_grave, "ga", 204 &c_under, "ul", 205 &c_rooten, "rn", 206 &c_boxrule, "br", 207 &c_lefthand, "lh", 208 &c_dagger, "dg", 209 0, 0 210 }; 211 int i; 212 213 for (i = 0; spnames[i].n; i++) 214 *spnames[i].n = findch(spnames[i].v); 215 216 return (0); 217 } 218 219 int 220 findch(s) /* find char s in chname */ 221 char *s; 222 { 223 int i; 224 225 for (i = 0; i < nchtab; i++) 226 if (strcmp(s, &chname[chtab[i]]) == 0) 227 return(i + 128); 228 return(0); 229 } 230 231 int 232 ptout(i) 233 tchar i; 234 { 235 int dv; 236 tchar *k; 237 int temp, a, b; 238 239 if (cbits(i) != '\n') { 240 *olinep++ = i; 241 return (0); 242 } 243 if (olinep == oline) { 244 lead += lss; 245 return (0); 246 } 247 248 hpos = po; /* ??? */ 249 esc = 0; /* ??? */ 250 ptesc(); /* the problem is to get back to the left end of the line */ 251 dv = 0; 252 for (k = oline; k < olinep; k++) { 253 if (ismot(*k) && isvmot(*k)) { 254 temp = absmot(*k); 255 if (isnmot(*k)) 256 temp = -temp; 257 dv += temp; 258 } 259 } 260 if (dv) { 261 vflag++; 262 *olinep++ = makem(-dv); 263 vflag = 0; 264 } 265 266 b = dip->blss + lss; 267 lead += dip->blss + lss; 268 dip->blss = 0; 269 for (k = oline; k < olinep; ) 270 k = ptout0(k); /* now passing a pointer! */ 271 olinep = oline; 272 lead += dip->alss; 273 a = dip->alss; 274 dip->alss = 0; 275 /* 276 fdprintf(ptid, "x xxx end of line: hpos=%d, vpos=%d\n", hpos, vpos); 277 */ 278 fdprintf(ptid, "n%d %d\n", b, a); /* be nice to chuck */ 279 280 return (0); 281 } 282 283 tchar * 284 ptout0(pi) 285 tchar *pi; 286 { 287 short j, k, w; 288 short z, dx, dy, dx2, dy2, n; 289 tchar i; 290 int outsize; /* size of object being printed */ 291 292 outsize = 1; /* default */ 293 i = *pi; 294 k = cbits(i); 295 if (ismot(i)) { 296 j = absmot(i); 297 if (isnmot(i)) 298 j = -j; 299 if (isvmot(i)) 300 lead += j; 301 else 302 esc += j; 303 return(pi+outsize); 304 } 305 if (k == XON) { 306 if (xfont != mfont) 307 ptfont(); 308 if (xpts != mpts) 309 ptps(); 310 if (lead) 311 ptlead(); 312 fdprintf(ptid, "x X "); 313 /* 314 * not guaranteed of finding a XOFF if a word overflow 315 * error occured, so also bound this loop by olinep 316 */ 317 pi++; 318 while( cbits(*pi) != XOFF && pi < olinep ) 319 outascii(*pi++); 320 oput('\n'); 321 if ( cbits(*pi) == XOFF ) 322 pi++; 323 return pi; 324 } 325 ; 326 if (k == CHARHT) { 327 if (xpts != mpts) 328 ptps(); 329 fdprintf(ptid, "x H %d\n", sbits(i)); 330 return(pi+outsize); 331 } 332 if (k == SLANT) { 333 fdprintf(ptid, "x S %d\n", sfbits(i)-180); 334 return(pi+outsize); 335 } 336 if (k == WORDSP) { 337 oput('w'); 338 return(pi+outsize); 339 } 340 if (k == FONTPOS) { 341 char temp[3]; 342 n = i >> 16; 343 temp[0] = n & BYTEMASK; 344 temp[1] = n >> BYTE; 345 temp[2] = 0; 346 ptfpcmd(0, temp); 347 return(pi+outsize); 348 } 349 if (sfbits(i) == oldbits) { 350 xfont = pfont; 351 xpts = ppts; 352 } else 353 xbits(i, 2); 354 if (k < 040 && k != DRAWFCN) 355 return(pi+outsize); 356 if (k >= 32) { 357 if (widcache[k-32].fontpts == (xfont<<8) + xpts && !setwdf) { 358 w = widcache[k-32].width; 359 bd = 0; 360 cs = 0; 361 } else 362 w = getcw(k-32); 363 } 364 j = z = 0; 365 if (k != DRAWFCN) { 366 if (cs) { 367 if (bd) 368 w += (bd - 1) * HOR; 369 j = (cs - w) / 2; 370 w = cs - j; 371 if (bd) 372 w -= (bd - 1) * HOR; 373 } 374 if (iszbit(i)) { 375 if (cs) 376 w = -j; 377 else 378 w = 0; 379 z = 1; 380 } 381 } 382 esc += j; 383 if (xfont != mfont) 384 ptfont(); 385 if (xpts != mpts) 386 ptps(); 387 if (lead) 388 ptlead(); 389 /* put out the real character here */ 390 if (k == DRAWFCN) { 391 if (esc) 392 ptesc(); 393 dx = absmot(pi[3]); 394 if (isnmot(pi[3])) 395 dx = -dx; 396 dy = absmot(pi[4]); 397 if (isnmot(pi[4])) 398 dy = -dy; 399 switch (cbits(pi[1])) { 400 case DRAWCIRCLE: /* circle */ 401 fdprintf(ptid, "D%c %d\n", DRAWCIRCLE, dx); /* dx is diameter */ 402 w = 0; 403 hpos += dx; 404 break; 405 case DRAWELLIPSE: 406 fdprintf(ptid, "D%c %d %d\n", DRAWELLIPSE, dx, dy); 407 w = 0; 408 hpos += dx; 409 break; 410 case DRAWLINE: /* line */ 411 k = cbits(pi[2]); 412 fdprintf(ptid, "D%c %d %d ", DRAWLINE, dx, dy); 413 if (k < 128) 414 fdprintf(ptid, "%c\n", k); 415 else 416 fdprintf(ptid, "%s\n", &chname[chtab[k - 128]]); 417 w = 0; 418 hpos += dx; 419 vpos += dy; 420 break; 421 case DRAWARC: /* arc */ 422 dx2 = absmot(pi[5]); 423 if (isnmot(pi[5])) 424 dx2 = -dx2; 425 dy2 = absmot(pi[6]); 426 if (isnmot(pi[6])) 427 dy2 = -dy2; 428 fdprintf(ptid, "D%c %d %d %d %d\n", DRAWARC, 429 dx, dy, dx2, dy2); 430 w = 0; 431 hpos += dx + dx2; 432 vpos += dy + dy2; 433 break; 434 case DRAWSPLINE: /* spline */ 435 default: /* something else; copy it like spline */ 436 fdprintf(ptid, "D%c %d %d", cbits(pi[1]), dx, dy); 437 w = 0; 438 hpos += dx; 439 vpos += dy; 440 if (cbits(pi[3]) == DRAWFCN || cbits(pi[4]) == DRAWFCN) { 441 /* it was somehow defective */ 442 fdprintf(ptid, "\n"); 443 break; 444 } 445 for (n = 5; cbits(pi[n]) != DRAWFCN; n += 2) { 446 dx = absmot(pi[n]); 447 if (isnmot(pi[n])) 448 dx = -dx; 449 dy = absmot(pi[n+1]); 450 if (isnmot(pi[n+1])) 451 dy = -dy; 452 fdprintf(ptid, " %d %d", dx, dy); 453 hpos += dx; 454 vpos += dy; 455 } 456 fdprintf(ptid, "\n"); 457 break; 458 } 459 for (n = 3; cbits(pi[n]) != DRAWFCN; n++) 460 ; 461 outsize = n + 1; 462 } else if (k < 128) { 463 /* try to go faster and compress output */ 464 /* by printing nnc for small positive motion followed by c */ 465 /* kludgery; have to make sure set all the vars too */ 466 if (esc > 0 && esc < 100) { 467 oput(esc / 10 + '0'); 468 oput(esc % 10 + '0'); 469 oput(k); 470 hpos += esc; 471 esc = 0; 472 } else { 473 if (esc) 474 ptesc(); 475 oput('c'); 476 oput(k); 477 oput('\n'); 478 } 479 } else { 480 if (esc) 481 ptesc(); 482 if (k >= nchtab + 128) 483 fdprintf(ptid, "N%d\n", k - (nchtab+128)); 484 else 485 fdprintf(ptid, "C%s\n", &chname[chtab[k - 128]]); 486 } 487 if (bd) { 488 bd -= HOR; 489 if (esc += bd) 490 ptesc(); 491 if (k < 128) { 492 fdprintf(ptid, "c%c\n", k); 493 } else if (k >= nchtab + 128) { 494 fdprintf(ptid, "N%d\n", k - (nchtab+128)); 495 } else 496 fdprintf(ptid, "C%s\n", &chname[chtab[k - 128]]); 497 if (z) 498 esc -= bd; 499 } 500 esc += w; 501 return(pi+outsize); 502 } 503 504 int 505 ptps() 506 { 507 int i, j, k; 508 509 i = xpts; 510 for (j = 0; i > (k = pstab[j]); j++) 511 if (!k) { 512 k = pstab[--j]; 513 break; 514 } 515 fdprintf(ptid, "s%d\n", k); /* really should put out string rep of size */ 516 mpts = i; 517 518 return (0); 519 } 520 521 int 522 ptfont() 523 { 524 mfont = xfont; 525 fdprintf(ptid, "f%d\n", xfont); 526 527 return (0); 528 } 529 530 int 531 ptfpcmd(f, s) 532 int f; 533 char *s; 534 { 535 if (ascii) 536 return (0); 537 fdprintf(ptid, "x font %d %s\n", f, s); 538 ptfont(); /* make sure that it gets noticed */ 539 540 return (0); 541 } 542 543 int 544 ptlead() 545 { 546 vpos += lead; 547 if (!ascii) 548 fdprintf(ptid, "V%d\n", vpos); 549 lead = 0; 550 551 return (0); 552 } 553 554 555 int 556 ptesc() 557 { 558 hpos += esc; 559 if (esc > 0) { 560 oput('h'); 561 if (esc>=10 && esc<100) { 562 oput(esc/10 + '0'); 563 oput(esc%10 + '0'); 564 } else 565 fdprintf(ptid, "%d", esc); 566 } else 567 fdprintf(ptid, "H%d\n", hpos); 568 esc = 0; 569 570 return (0); 571 } 572 573 574 int 575 newpage(n) /* called at end of each output page (we hope) */ 576 { 577 int i; 578 579 ptlead(); 580 vpos = 0; 581 if (ascii) 582 return (0); 583 fdprintf(ptid, "p%d\n", n); /* new page */ 584 for (i = 0; i <= nfonts; i++) 585 if (fontbase[i]->namefont[0] != '\0') 586 fdprintf(ptid, "x font %d %s\n", i, 587 fontbase[i]->namefont); 588 ptps(); 589 ptfont(); 590 591 return (0); 592 } 593 594 int 595 pttrailer() 596 { 597 fdprintf(ptid, "x trailer\n"); 598 599 return (0); 600 } 601 602 int 603 ptstop() 604 { 605 fdprintf(ptid, "x stop\n"); 606 607 return (0); 608 } 609 610 int 611 dostop() 612 { 613 if (ascii) 614 return (0); 615 ptlead(); 616 vpos = 0; 617 /* fdprintf(ptid, "x xxx end of page\n");*/ 618 if (!nofeed) 619 pttrailer(); 620 ptlead(); 621 fdprintf(ptid, "x pause\n"); 622 flusho(); 623 mpts = mfont = 0; 624 ptesc(); 625 esc = po; 626 hpos = vpos = 0; /* probably in wrong place */ 627 628 return (0); 629 } 630