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 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 /* 34 * University Copyright- Copyright (c) 1982, 1986, 1988 35 * The Regents of the University of California 36 * All Rights Reserved 37 * 38 * University Acknowledgment- Portions of this document are derived from 39 * software developed by the University of California, Berkeley, and its 40 * contributors. 41 */ 42 43 #include "tdef.h" 44 #include <ctype.h> 45 #include "ext.h" 46 /* 47 * troff10.c 48 * 49 * typesetter interface 50 */ 51 52 int vpos = 0; /* absolute vertical position on page */ 53 int hpos = 0; /* ditto horizontal */ 54 55 short *chtab; 56 char *chname; 57 char *fontab[NFONT+1]; 58 char *kerntab[NFONT+1]; 59 char *fitab[NFONT+1]; 60 char *codetab[NFONT+1]; 61 62 int Inch; 63 int Hor; 64 int Vert; 65 int Unitwidth; 66 int nfonts; 67 int nsizes; 68 int nchtab; 69 70 /* these characters are used as various signals or values 71 * in miscellaneous places. 72 * values are set in specnames in t10.c 73 */ 74 75 int c_hyphen; 76 int c_emdash; 77 int c_rule; 78 int c_minus; 79 int c_fi; 80 int c_fl; 81 int c_ff; 82 int c_ffi; 83 int c_ffl; 84 int c_acute; 85 int c_grave; 86 int c_under; 87 int c_rooten; 88 int c_boxrule; 89 int c_lefthand; 90 int c_dagger; 91 92 #include "dev.h" 93 struct dev dev; 94 struct Font *fontbase[NFONT+1]; 95 96 tchar *ptout0(); 97 98 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; 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 186 specnames() 187 { 188 static struct { 189 int *n; 190 char *v; 191 } spnames[] = { 192 &c_hyphen, "hy", 193 &c_emdash, "em", 194 &c_rule, "ru", 195 &c_minus, "\\-", 196 &c_fi, "fi", 197 &c_fl, "fl", 198 &c_ff, "ff", 199 &c_ffi, "Fi", 200 &c_ffl, "Fl", 201 &c_acute, "aa", 202 &c_grave, "ga", 203 &c_under, "ul", 204 &c_rooten, "rn", 205 &c_boxrule, "br", 206 &c_lefthand, "lh", 207 &c_dagger, "dg", 208 0, 0 209 }; 210 int i; 211 212 for (i = 0; spnames[i].n; i++) 213 *spnames[i].n = findch(spnames[i].v); 214 } 215 216 findch(s) /* find char s in chname */ 217 register char *s; 218 { 219 register int i; 220 221 for (i = 0; i < nchtab; i++) 222 if (strcmp(s, &chname[chtab[i]]) == 0) 223 return(i + 128); 224 return(0); 225 } 226 227 ptout(i) 228 register tchar i; 229 { 230 register dv; 231 register tchar *k; 232 int temp, a, b; 233 234 if (cbits(i) != '\n') { 235 *olinep++ = i; 236 return; 237 } 238 if (olinep == oline) { 239 lead += lss; 240 return; 241 } 242 243 hpos = po; /* ??? */ 244 esc = 0; /* ??? */ 245 ptesc(); /* the problem is to get back to the left end of the line */ 246 dv = 0; 247 for (k = oline; k < olinep; k++) { 248 if (ismot(*k) && isvmot(*k)) { 249 temp = absmot(*k); 250 if (isnmot(*k)) 251 temp = -temp; 252 dv += temp; 253 } 254 } 255 if (dv) { 256 vflag++; 257 *olinep++ = makem(-dv); 258 vflag = 0; 259 } 260 261 b = dip->blss + lss; 262 lead += dip->blss + lss; 263 dip->blss = 0; 264 for (k = oline; k < olinep; ) 265 k = ptout0(k); /* now passing a pointer! */ 266 olinep = oline; 267 lead += dip->alss; 268 a = dip->alss; 269 dip->alss = 0; 270 /* 271 fdprintf(ptid, "x xxx end of line: hpos=%d, vpos=%d\n", hpos, vpos); 272 */ 273 fdprintf(ptid, "n%d %d\n", b, a); /* be nice to chuck */ 274 } 275 276 tchar * 277 ptout0(pi) 278 tchar *pi; 279 { 280 register short j, k, w; 281 short z, dx, dy, dx2, dy2, n; 282 register tchar i; 283 int outsize; /* size of object being printed */ 284 285 outsize = 1; /* default */ 286 i = *pi; 287 k = cbits(i); 288 if (ismot(i)) { 289 j = absmot(i); 290 if (isnmot(i)) 291 j = -j; 292 if (isvmot(i)) 293 lead += j; 294 else 295 esc += j; 296 return(pi+outsize); 297 } 298 if (k == XON) { 299 if (xfont != mfont) 300 ptfont(); 301 if (xpts != mpts) 302 ptps(); 303 if (lead) 304 ptlead(); 305 fdprintf(ptid, "x X "); 306 /* 307 * not guaranteed of finding a XOFF if a word overflow 308 * error occured, so also bound this loop by olinep 309 */ 310 pi++; 311 while( cbits(*pi) != XOFF && pi < olinep ) 312 outascii(*pi++); 313 oput('\n'); 314 if ( cbits(*pi) == XOFF ) 315 pi++; 316 return pi; 317 } 318 ; 319 if (k == CHARHT) { 320 if (xpts != mpts) 321 ptps(); 322 fdprintf(ptid, "x H %d\n", sbits(i)); 323 return(pi+outsize); 324 } 325 if (k == SLANT) { 326 fdprintf(ptid, "x S %d\n", sfbits(i)-180); 327 return(pi+outsize); 328 } 329 if (k == WORDSP) { 330 oput('w'); 331 return(pi+outsize); 332 } 333 if (k == FONTPOS) { 334 char temp[3]; 335 n = i >> 16; 336 temp[0] = n & BYTEMASK; 337 temp[1] = n >> BYTE; 338 temp[2] = 0; 339 ptfpcmd(0, temp); 340 return(pi+outsize); 341 } 342 if (sfbits(i) == oldbits) { 343 xfont = pfont; 344 xpts = ppts; 345 } else 346 xbits(i, 2); 347 if (k < 040 && k != DRAWFCN) 348 return(pi+outsize); 349 if (k >= 32) { 350 if (widcache[k-32].fontpts == (xfont<<8) + xpts && !setwdf) { 351 w = widcache[k-32].width; 352 bd = 0; 353 cs = 0; 354 } else 355 w = getcw(k-32); 356 } 357 j = z = 0; 358 if (k != DRAWFCN) { 359 if (cs) { 360 if (bd) 361 w += (bd - 1) * HOR; 362 j = (cs - w) / 2; 363 w = cs - j; 364 if (bd) 365 w -= (bd - 1) * HOR; 366 } 367 if (iszbit(i)) { 368 if (cs) 369 w = -j; 370 else 371 w = 0; 372 z = 1; 373 } 374 } 375 esc += j; 376 if (xfont != mfont) 377 ptfont(); 378 if (xpts != mpts) 379 ptps(); 380 if (lead) 381 ptlead(); 382 /* put out the real character here */ 383 if (k == DRAWFCN) { 384 if (esc) 385 ptesc(); 386 dx = absmot(pi[3]); 387 if (isnmot(pi[3])) 388 dx = -dx; 389 dy = absmot(pi[4]); 390 if (isnmot(pi[4])) 391 dy = -dy; 392 switch (cbits(pi[1])) { 393 case DRAWCIRCLE: /* circle */ 394 fdprintf(ptid, "D%c %d\n", DRAWCIRCLE, dx); /* dx is diameter */ 395 w = 0; 396 hpos += dx; 397 break; 398 case DRAWELLIPSE: 399 fdprintf(ptid, "D%c %d %d\n", DRAWELLIPSE, dx, dy); 400 w = 0; 401 hpos += dx; 402 break; 403 case DRAWLINE: /* line */ 404 k = cbits(pi[2]); 405 fdprintf(ptid, "D%c %d %d ", DRAWLINE, dx, dy); 406 if (k < 128) 407 fdprintf(ptid, "%c\n", k); 408 else 409 fdprintf(ptid, "%s\n", &chname[chtab[k - 128]]); 410 w = 0; 411 hpos += dx; 412 vpos += dy; 413 break; 414 case DRAWARC: /* arc */ 415 dx2 = absmot(pi[5]); 416 if (isnmot(pi[5])) 417 dx2 = -dx2; 418 dy2 = absmot(pi[6]); 419 if (isnmot(pi[6])) 420 dy2 = -dy2; 421 fdprintf(ptid, "D%c %d %d %d %d\n", DRAWARC, 422 dx, dy, dx2, dy2); 423 w = 0; 424 hpos += dx + dx2; 425 vpos += dy + dy2; 426 break; 427 case DRAWSPLINE: /* spline */ 428 default: /* something else; copy it like spline */ 429 fdprintf(ptid, "D%c %d %d", cbits(pi[1]), dx, dy); 430 w = 0; 431 hpos += dx; 432 vpos += dy; 433 if (cbits(pi[3]) == DRAWFCN || cbits(pi[4]) == DRAWFCN) { 434 /* it was somehow defective */ 435 fdprintf(ptid, "\n"); 436 break; 437 } 438 for (n = 5; cbits(pi[n]) != DRAWFCN; n += 2) { 439 dx = absmot(pi[n]); 440 if (isnmot(pi[n])) 441 dx = -dx; 442 dy = absmot(pi[n+1]); 443 if (isnmot(pi[n+1])) 444 dy = -dy; 445 fdprintf(ptid, " %d %d", dx, dy); 446 hpos += dx; 447 vpos += dy; 448 } 449 fdprintf(ptid, "\n"); 450 break; 451 } 452 for (n = 3; cbits(pi[n]) != DRAWFCN; n++) 453 ; 454 outsize = n + 1; 455 } else if (k < 128) { 456 /* try to go faster and compress output */ 457 /* by printing nnc for small positive motion followed by c */ 458 /* kludgery; have to make sure set all the vars too */ 459 if (esc > 0 && esc < 100) { 460 oput(esc / 10 + '0'); 461 oput(esc % 10 + '0'); 462 oput(k); 463 hpos += esc; 464 esc = 0; 465 } else { 466 if (esc) 467 ptesc(); 468 oput('c'); 469 oput(k); 470 oput('\n'); 471 } 472 } else { 473 if (esc) 474 ptesc(); 475 if (k >= nchtab + 128) 476 fdprintf(ptid, "N%d\n", k - (nchtab+128)); 477 else 478 fdprintf(ptid, "C%s\n", &chname[chtab[k - 128]]); 479 } 480 if (bd) { 481 bd -= HOR; 482 if (esc += bd) 483 ptesc(); 484 if (k < 128) { 485 fdprintf(ptid, "c%c\n", k); 486 } else if (k >= nchtab + 128) { 487 fdprintf(ptid, "N%d\n", k - (nchtab+128)); 488 } else 489 fdprintf(ptid, "C%s\n", &chname[chtab[k - 128]]); 490 if (z) 491 esc -= bd; 492 } 493 esc += w; 494 return(pi+outsize); 495 } 496 497 ptps() 498 { 499 register i, j, k; 500 501 i = xpts; 502 for (j = 0; i > (k = pstab[j]); j++) 503 if (!k) { 504 k = pstab[--j]; 505 break; 506 } 507 fdprintf(ptid, "s%d\n", k); /* really should put out string rep of size */ 508 mpts = i; 509 } 510 511 ptfont() 512 { 513 mfont = xfont; 514 fdprintf(ptid, "f%d\n", xfont); 515 } 516 517 ptfpcmd(f, s) 518 int f; 519 char *s; 520 { 521 if (ascii) 522 return; 523 fdprintf(ptid, "x font %d %s\n", f, s); 524 ptfont(); /* make sure that it gets noticed */ 525 } 526 527 ptlead() 528 { 529 vpos += lead; 530 if (!ascii) 531 fdprintf(ptid, "V%d\n", vpos); 532 lead = 0; 533 } 534 535 ptesc() 536 { 537 hpos += esc; 538 if (esc > 0) { 539 oput('h'); 540 if (esc>=10 && esc<100) { 541 oput(esc/10 + '0'); 542 oput(esc%10 + '0'); 543 } else 544 fdprintf(ptid, "%d", esc); 545 } else 546 fdprintf(ptid, "H%d\n", hpos); 547 esc = 0; 548 } 549 550 newpage(n) /* called at end of each output page (we hope) */ 551 { 552 int i; 553 554 ptlead(); 555 vpos = 0; 556 if (ascii) 557 return; 558 fdprintf(ptid, "p%d\n", n); /* new page */ 559 for (i = 0; i <= nfonts; i++) 560 if (fontbase[i]->namefont && fontbase[i]->namefont[0]) 561 fdprintf(ptid, "x font %d %s\n", i, fontbase[i]->namefont); 562 ptps(); 563 ptfont(); 564 } 565 566 pttrailer() 567 { 568 fdprintf(ptid, "x trailer\n"); 569 } 570 571 ptstop() 572 { 573 fdprintf(ptid, "x stop\n"); 574 } 575 576 dostop() 577 { 578 if (ascii) 579 return; 580 ptlead(); 581 vpos = 0; 582 /* fdprintf(ptid, "x xxx end of page\n");*/ 583 if (!nofeed) 584 pttrailer(); 585 ptlead(); 586 fdprintf(ptid, "x pause\n"); 587 flusho(); 588 mpts = mfont = 0; 589 ptesc(); 590 esc = po; 591 hpos = vpos = 0; /* probably in wrong place */ 592 } 593