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