1 #ifndef lint 2 static char *sccsid = "@(#)dhar.c 1.2 CWI 1.2 10/24/85"; 3 #endif 4 /* 5 * Drive the Harris 7500 tyepsetter 6 * 75XX 7 * Other machines of that harris serie will probably run as well with this 8 * 9 * Author: jaap akkerhuis, Oc 1982, Mathematisch Cetrum. 10 * 11 */ 12 /* 13 output language from troff: 14 all numbers are character strings 15 16 sn size in points 17 fn font as number from 1-n 18 cx ascii character x 19 Cxyz funny char xyz. terminated by white space 20 Hn go to absolute horizontal position n 21 Vn go to absolute vertical position n (down is positive) 22 hn go n units horizontally (relative) 23 vn ditto vertically 24 nnc move right nn, then print c (exactly 2 digits!) 25 (this wart is an optimization that shrinks output file size 26 about 35% and run-time about 15% while preserving ascii-ness) 27 Dt ...\n draw operation 't': 28 Dl x y line from here by x,y 29 Dc d circle of diameter d with left side here 30 De x y ellipse of axes x,y with left side here 31 Da x y r arc counter-clockwise by x,y of radius r 32 D~ x y x y ... wiggly line by x,y then x,y ... 33 w paddable words space -- no action needed 34 nb a end of line (information only -- no action needed) 35 b = space before line, a = after 36 p new page begins -- set v to 0 37 tstring print string as plain text 38 #...\n comment 39 x ...\n device control functions: 40 x i init 41 x T s name of device is s 42 x r n h v resolution is n/inch 43 h = min horizontal motion, v = min vert 44 x p pause (can restart) 45 x s stop -- done for ever 46 x t generate trailer 47 x f n s font position n contains font s 48 x H n set character height to n 49 x S n set slant to N 50 51 Subcommands like "i" are often spelled out like "init". 52 */ 53 /* 54 * MC:jna 55 * The output language signs { and } are not described 56 * 57 */ 58 59 #include <stdio.h> 60 #include <ctype.h> 61 #include <signal.h> 62 63 #include "../dev.h" 64 #define NFONT 10 65 66 int output = 0; /* do we do output at all? */ 67 int nolist = 0; /* output page list if > 0 */ 68 int olist[20]; /* pairs of page numbers */ 69 int spage = 9999; /* stop every spage pages */ 70 int scount = 0; 71 72 struct dev dev; 73 struct Font *fontbase[NFONT+1]; 74 short *pstab; 75 int nsizes; 76 int nfonts; 77 int smnt; /* index of first special font */ 78 int nchtab; 79 char *chname; 80 short *chtab; 81 char *fitab[NFONT+1]; 82 char *widthtab[NFONT+1]; /* widtab would be a better name */ 83 char *codetab[NFONT+1]; /* device codes */ 84 short *fonttab[NFONT+1]; /*MC:jna optional fontcodes */ 85 86 #define FATAL 1 87 #define BMASK 0377 88 #define BYTE 8 89 int dbg = 0; 90 int eflag; 91 int cflag; 92 int res; /* input assumed computed according to this resolution */ 93 int tf = 0; /* output file will be har.in or standout */ 94 char *fontdir = "/usr/local/lib/ditroff/font"; 95 extern char devname[]; 96 97 #define abs(n) ((n) >= 0 ? (n) : -(n)) 98 99 int font = 1; /* current font */ 100 int hpos; /* horizontal position where we are supposed to be next (left = 0) */ 101 int lastw; /* width of last printed char, (for t_text()) */ 102 int vpos; /* current vertical position (down positive) */ 103 int horig; /* h origin of current block; hpos rel to this */ 104 int vorig; 105 int htrue = 0; 106 int vtrue = 0; 107 int DX = 4; /* step size in x for drawing */ 108 int DY = 4; /* step size in y for drawing */ 109 int drawdot = '.'; /* draw with this character */ 110 int drawsize = 1; /* shrink by this factor when drawing */ 111 /* drawsize will be set in t_init as well! */ 112 113 main(argc, argv) 114 char *argv[]; 115 { 116 FILE *fp; 117 int i; 118 int done(); 119 while (argc > 1 && argv[1][0] == '-') { 120 switch (argv[1][1]) { 121 case 'f': 122 case 'F': 123 fontdir = argv[2]; 124 argv++; 125 argc--; 126 break; 127 case 't': 128 tf = 1; /* stdout */ 129 break; 130 case 'o': 131 outlist(&argv[1][2]); 132 break; 133 case 'd': 134 dbg = atoi(&argv[1][2]); 135 if (dbg == 0) dbg = 1; 136 break; 137 case 's': 138 spage = atoi(&argv[1][2]); 139 if (spage <= 0) 140 spage = 9999; 141 break; 142 case 'e': 143 eflag++; 144 break; 145 case 'c': 146 cflag++; 147 break; 148 } 149 argc--; 150 argv++; 151 } 152 /* 153 * Stop every 4 pages to prevent the 154 * Harris to Cut the paper every 6 feet, 155 * wat will likely to be in the middle of 156 * a page. Every for page is proved to be 157 * reasonable. 158 */ 159 if (spage == 0 || 9999) 160 spage = 4; 161 162 if (signal(SIGINT, done) == SIG_IGN) { 163 signal(SIGINT, SIG_IGN); 164 signal(SIGQUIT, SIG_IGN); 165 signal(SIGHUP, SIG_IGN); 166 } else { 167 signal(SIGQUIT, done); 168 signal(SIGHUP, done); 169 } 170 signal(SIGTERM, done); 171 if (argc <= 1) 172 conv(stdin); 173 else 174 while (--argc > 0) { 175 if (strcmp(*++argv, "-") == 0) 176 fp = stdin; 177 else if ((fp = fopen(*argv, "r")) == NULL) 178 error(FATAL, "can't open %s", *argv); 179 conv(fp); 180 fclose(fp); 181 } 182 account(); 183 done(); 184 } 185 186 outlist(s) /* process list of page numbers to be printed */ 187 char *s; 188 { 189 int n1, n2, i; 190 191 nolist = 0; 192 while (*s) { 193 n1 = 0; 194 if (isdigit(*s)) 195 do 196 n1 = 10 * n1 + *s++ - '0'; 197 while (isdigit(*s)); 198 else 199 n1 = -9999; 200 n2 = n1; 201 if (*s == '-') { 202 s++; 203 n2 = 0; 204 if (isdigit(*s)) 205 do 206 n2 = 10 * n2 + *s++ - '0'; 207 while (isdigit(*s)); 208 else 209 n2 = 9999; 210 } 211 olist[nolist++] = n1; 212 olist[nolist++] = n2; 213 if (*s != '\0') 214 s++; 215 } 216 olist[nolist] = 0; 217 if (dbg) 218 for (i=0; i<nolist; i += 2) 219 printf("%3d %3d\n", olist[i], olist[i+1]); 220 } 221 222 conv(fp) 223 register FILE *fp; 224 { 225 register int c, k; 226 int m, n, i, n1, m1; 227 char str[100], buf[300]; 228 229 while ((c = getc(fp)) != EOF) { 230 switch (c) { 231 case '\n': /* when input is text */ 232 case ' ': 233 case 0: /* occasional noise creeps in */ 234 break; 235 case '{': /* push down current environment */ 236 t_push(); 237 break; 238 case '}': 239 t_pop(); 240 break; 241 case '0': case '1': case '2': case '3': case '4': 242 case '5': case '6': case '7': case '8': case '9': 243 /* two motion digits plus a character */ 244 hmot((c-'0')*10 + getc(fp)-'0'); 245 put1(getc(fp)); 246 break; 247 case 'c': /* single ascii character */ 248 put1(getc(fp)); 249 break; 250 case 'C': 251 fscanf(fp, "%s", str); 252 put1s(str); 253 break; 254 case 't': /* straight text */ 255 fgets(buf, sizeof(buf), fp); 256 t_text(buf); 257 break; 258 case 'D': /* draw function */ 259 fgets(buf, sizeof(buf), fp); 260 switch (buf[0]) { 261 case 'l': /* draw a line */ 262 sscanf(buf+1, "%d %d", &n, &m); 263 drawline(n, m, "."); 264 break; 265 case 'c': /* circle */ 266 sscanf(buf+1, "%d", &n); 267 drawcirc(n); 268 break; 269 case 'e': /* ellipse */ 270 sscanf(buf+1, "%d %d", &m, &n); 271 drawellip(m, n); 272 break; 273 case 'a': /* arc */ 274 sscanf(buf+1, "%d %d %d %d", &n, &m, &n1, &m1); 275 drawarc(n, m, n1, m1); 276 break; 277 case '~': /* wiggly line */ 278 drawwig(buf+1); 279 break; 280 default: 281 error(FATAL, "unknown drawing function %s\n", buf); 282 break; 283 } 284 break; 285 case 's': 286 fscanf(fp, "%d", &n); /* ignore fractional sizes */ 287 setsize(t_size(n)); 288 break; 289 case 'f': 290 fscanf(fp, "%s", str); 291 setfont(t_font(str)); 292 break; 293 case 'H': /* absolute horizontal motion */ 294 /* fscanf(fp, "%d", &n); */ 295 while ((c = getc(fp)) == ' ') 296 ; 297 k = 0; 298 do { 299 k = 10 * k + c - '0'; 300 } while (isdigit(c = getc(fp))); 301 ungetc(c, fp); 302 hgoto(k); 303 break; 304 case 'h': /* relative horizontal motion */ 305 /* fscanf(fp, "%d", &n); */ 306 while ((c = getc(fp)) == ' ') 307 ; 308 k = 0; 309 do { 310 k = 10 * k + c - '0'; 311 } while (isdigit(c = getc(fp))); 312 ungetc(c, fp); 313 hmot(k); 314 break; 315 case 'w': /* word space */ 316 break; 317 case 'V': 318 fscanf(fp, "%d", &n); 319 vgoto(n); 320 break; 321 case 'v': 322 fscanf(fp, "%d", &n); 323 vmot(n); 324 break; 325 case 'p': /* new page */ 326 fscanf(fp, "%d", &n); 327 t_page(n); 328 break; 329 case 'n': /* end of line */ 330 while (getc(fp) != '\n') 331 ; 332 t_newline(); 333 break; 334 case '#': /* comment */ 335 while (getc(fp) != '\n') 336 ; 337 break; 338 case 'x': /* device control */ 339 devcntrl(fp); 340 break; 341 default: 342 error(!FATAL, "unknown input character %o %c\n", c, c); 343 done(); 344 } 345 } 346 } 347 348 devcntrl(fp) /* interpret device control functions */ 349 FILE *fp; 350 { 351 char str[20], str1[50], buf[50]; 352 int c, n; 353 354 fscanf(fp, "%s", str); 355 switch (str[0]) { /* crude for now */ 356 case 'i': /* initialize */ 357 fileinit(); 358 t_init(0); 359 break; 360 case 'T': /* device name */ 361 fscanf(fp, "%s", devname); 362 break; 363 case 't': /* trailer */ 364 t_trailer(); 365 break; 366 case 'p': /* pause -- can restart */ 367 t_reset('p'); 368 break; 369 case 's': /* stop */ 370 t_reset('s'); 371 break; 372 case 'r': /* resolution assumed when prepared */ 373 fscanf(fp, "%d", &res); 374 break; 375 case 'f': /* font used */ 376 fscanf(fp, "%d %s", &n, str); 377 fgets(buf, sizeof buf, fp); /* in case there's a filename */ 378 ungetc('\n', fp); /* fgets goes too far */ 379 str1[0] = 0; /* in case there's nothing to come in */ 380 sscanf(buf, "%s", str1); 381 loadfont(n, str, str1); 382 break; 383 /* these don't belong here... */ 384 case 'H': /* char height */ 385 fscanf(fp, "%d", &n); 386 t_charht(t_size(n)); 387 break; 388 case 'S': /* slant */ 389 fscanf(fp, "%d", &n); 390 t_slant(n); 391 break; 392 } 393 while ((c = getc(fp)) != '\n') /* skip rest of input line */ 394 if (c == EOF) 395 break; 396 } 397 398 fileinit() /* read in font and code files, etc. */ 399 { 400 int i, fin, nw; 401 char *malloc(), *filebase, *p; 402 char temp[60]; 403 404 /* open table for device, 405 /* read in resolution, size info, font info, etc. 406 /* and set params 407 */ 408 sprintf(temp, "%s/dev%s/DESC.out", fontdir, devname); 409 if ((fin = open(temp, 0)) < 0) 410 error(FATAL, "can't open tables for %s\n", temp); 411 read(fin, &dev, sizeof(struct dev)); 412 nfonts = dev.nfonts; 413 nsizes = dev.nsizes; 414 nchtab = dev.nchtab; 415 filebase = malloc(dev.filesize); /* enough room for whole file */ 416 read(fin, filebase, dev.filesize); /* all at once */ 417 pstab = (short *) filebase; 418 chtab = pstab + nsizes + 1; 419 chname = (char *) (chtab + dev.nchtab); 420 p = chname + dev.lchname; 421 for (i = 1; i <= nfonts; i++) { 422 fontbase[i] = (struct Font *) p; 423 nw = *p & BMASK; /* 1st thing is width count */ 424 if (smnt == 0 && fontbase[i]->specfont == 1) 425 smnt = i; /* first special font */ 426 p += sizeof(struct Font); /* that's what's on the beginning */ 427 widthtab[i] = p; 428 codetab[i] = p + 2 * nw; 429 fitab[i] = p + 3 * nw; 430 p += 3 * nw + dev.nchtab + 128 - 32; 431 if(fontbase[i]->fonttab == 1) { /*MC:jna There is a fonttable */ 432 fonttab[i] = (short *)p; /*MC:jna get it */ 433 p += nw * sizeof( short ); /* and skip it */ 434 } 435 t_fp(i, fontbase[i]->namefont, fontbase[i]->intname); 436 if(dbg > 2) fontprint(i); 437 } 438 /*MC:jna 439 * 440 * Make space for the font cache for NCH characters 441 * also reserve space for fonttable, if any is to come 442 * 443 */ 444 fontbase[0] = (struct Font *) malloc(3*255 + dev.nchtab + (128-32) + sizeof (struct Font) + 255 * sizeof( short)); 445 widthtab[0] = (char *) fontbase[0] + sizeof (struct Font); 446 fontbase[0]->nwfont = 255; 447 fontbase[0]->fonttab = 2; /* there is room for a fonttable! */ 448 close(fin); 449 } 450 451 fontprint(i) /* debugging print of font i (0,...) */ 452 { 453 int j, k, n; 454 char *p; 455 456 printf("font %d:\n", i); 457 p = (char *) fontbase[i]; 458 n = fontbase[i]->nwfont & BMASK; 459 printf("base=0%o, nchars=%d, spec=%d, name=%s, widtab=0%o, fitab=0%o\n", 460 p, n, fontbase[i]->specfont, fontbase[i]->namefont, widthtab[i], fitab[i]); 461 if( fontbase[i]->fonttab == 1) 462 printf("base fonttab=0%o\n", fonttab[i]); 463 printf("widths:\n"); 464 for (j=0; j <= n; j++) { 465 printf(" %2d", widthtab[i][j] & BMASK); 466 if (j % 20 == 19) printf("\n"); 467 } 468 printf("\ncodetab:\n"); 469 for (j=0; j <= n; j++) { 470 printf(" %2d", codetab[i][j] & BMASK); 471 if (j % 20 == 19) printf("\n"); 472 } 473 printf("\nfitab:\n"); 474 for (j=0; j <= dev.nchtab + 128-32; j++) { 475 printf(" %2d", fitab[i][j] & BMASK); 476 if (j % 20 == 19) printf("\n"); 477 } 478 if(fontbase[i]->fonttab == 1) { 479 printf("\nfonttab:\n"); 480 for (j=0; j <= n; j++) { 481 printf(" %d", fonttab[i][j] ); 482 if (j % 20 == 19) printf("\n"); 483 } 484 } 485 printf("\n"); 486 } 487 488 loadfont(n, s, s1) /* load font info for font s on position n (0...) */ 489 int n; 490 char *s, *s1; 491 { 492 char temp[60]; 493 int fin, nw, norig, forig; 494 char *p; 495 496 if (n < 0 || n > NFONT) 497 error(FATAL, "illegal fp command %d %s", n, s); 498 if (strcmp(s, fontbase[n]->namefont) == 0) 499 return; 500 if (s1 == NULL || s1[0] == '\0') 501 sprintf(temp, "%s/dev%s/%s.out", fontdir, devname, s); 502 else 503 sprintf(temp, "%s/%s.out", s1, s); 504 if ((fin = open(temp, 0)) < 0) 505 error(FATAL, "can't open font table %s", temp); 506 norig = fontbase[n]->nwfont & BMASK; 507 forig = fontbase[n]->fonttab; 508 if(dbg > 3) 509 printf("nworig, %d, fonttaborig %d\n", norig, forig); 510 /* 511 *MC:jna norig is the original amount of chars in 512 * the (premounted) font) 513 * 514 * first geuss there is no fonttab 515 */ 516 read(fin, fontbase[n], 3*norig + nchtab+128-32 + sizeof(struct Font)); 517 if ((fontbase[n]->nwfont & BMASK) > norig || (forig == 0 && fontbase[n]->fonttab == 1)) 518 error(FATAL, "Font %s too big for position %d\n", s, n); 519 /* 520 *MC:jna This means it is wise to make the default mounted 521 * fonts larger then any other mounttable fonts. 522 * And because of the kludge with the fonttable, 523 * Make sure that they all contain fonttables! 524 * It will make your life easier. 525 */ 526 nw = fontbase[n]->nwfont & BMASK; 527 if(dbg > 3) 528 printf("nw %d\n", nw); 529 if(fontbase[n]->fonttab == 1) { 530 lseek(fin, 0L, 0); 531 read(fin, fontbase[n], 3*norig + nchtab+128-32 + nw*sizeof(short) + sizeof(struct Font)); 532 /* 533 * There turned out to be a fonttab, so we have to read it in 534 *MC:jna a bit stupid, but the laziest way (for me) 535 */ 536 } 537 close(fin); 538 widthtab[n] = (char *) fontbase[n] + sizeof(struct Font); 539 codetab[n] = (char *) widthtab[n] + 2 * nw; 540 fitab[n] = (char *) widthtab[n] + 3 * nw; 541 if(fontbase[n]->fonttab == 1) 542 fonttab[n] = (short *) (widthtab[n] + 3*nw + nchtab+128-32); 543 t_fp(n, fontbase[n]->namefont, fontbase[n]->intname); 544 fontbase[n]->nwfont = norig; /* so can later use full original size */ 545 if(fontbase[n]->fonttab == 0 && forig != 0) 546 fontbase[n]->fonttab = 2; 547 /* so we signal that there is place 548 * for a fonttab! */ 549 550 if (dbg > 2) fontprint(n); 551 } 552 553 done() 554 { 555 t_reset('s'); 556 exit(0); 557 } 558 559 extern int ex(); 560 561 /*VARARGS*/ 562 error(f, s, a1, a2, a3, a4, a5, a6, a7) 563 int f; 564 { 565 fprintf(stderr, "dhar: "); 566 fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7); 567 fprintf(stderr, "\n"); 568 fflush(stderr); 569 if (f) { 570 ex(); 571 exit(1); 572 } 573 } 574 575 /****************************************************************************** 576 ****************************************************************************** 577 * 578 * Here begins the stuff that really depends on the harris 579 * 580 * For the time being, no use is made of the ruling functions of the Harris 581 * 582 ****************************************************************************** 583 ****************************************************************************** 584 */ 585 586 /* 587 * The basic idea is to delay the output as long as possible 588 * until you really have to. 589 * Until that time we just keep a machine status. 590 * 591 */ 592 593 #include "hcodes.h" 594 595 char devname[20] = "har"; 596 int fcut; 597 int nocutting; 598 int papuse; 599 char harcode; 600 601 t_init(reinit) /* initialize device */ 602 int reinit; 603 { 604 register int i; 605 extern int size; 606 607 hpos = vpos = 0; 608 609 if( strcmp( devname, "har") != NULL ) 610 error(FATAL, "This input is not for the harris"); 611 612 if (!tf) 613 if ( ( tf = creat("@har.in", 0664)) < 0) 614 error(FATAL, "Cannot create outputfile"); 615 616 /* if there is a drawing character, use it */ 617 for ( i = 0; i < nchtab; i++) 618 if (strcmp(&chname[chtab[i]], "l.") == 0) 619 break; 620 if ( i < nchtab) { 621 drawdot = i + 128; 622 drawsize = 1; 623 } else { 624 drawdot = '.'; 625 drawsize = 3; /* 1/3 size */ 626 } 627 628 output = 1; 629 630 oput(VMV); oput(0); oput(0); 631 /* See Harris Manual appendix D */ 632 oput(HPO);oput(0);oput(0); 633 634 /* some initial size */ 635 size = 10; 636 putsize(); 637 putfont(999); 638 oput(STA);oput(0);oput(0360); 639 640 if( eflag ) { 641 operator("Translating"); 642 oput(EST); /* enable slave Translator */ 643 fprintf(stderr,"Slave code translator enabled\n"); 644 } else 645 operator("dhar started"); 646 647 oput(OB0); /* reset oblique */ 648 oput(NAD); /* No automatic displacement */ 649 output = 0; 650 } 651 652 /* 653 * The reason of struct state is never explained by bwk 654 * but it looks like an stack of environments being pushed and popped 655 * 656 */ 657 658 #define MAXSTATE 5 659 660 struct state { 661 int ssize; 662 int sfont; 663 int shpos; 664 int svpos; 665 int shorig; 666 int svorig; 667 }; 668 struct state state[MAXSTATE]; 669 struct state *statep = state; 670 671 t_push() /* begin a new block */ 672 { 673 extern size; 674 675 error(!FATAL, "Different environment entered!"); 676 hflush(); 677 statep->ssize = size; 678 statep->sfont = font; 679 statep->shorig = horig; 680 statep->svorig = vorig; 681 statep->shpos = hpos; 682 statep->svpos = vpos; 683 horig = hpos; 684 vorig = vpos; 685 hpos = vpos = 0; 686 if (statep++ >= state+MAXSTATE) 687 error(FATAL, "{ nested too deep"); 688 hpos = vpos = 0; 689 } 690 691 t_pop() /* pop to previous state */ 692 { 693 extern size; 694 if (--statep < state) 695 error(FATAL, "extra }"); 696 size = statep->ssize; 697 font = statep->sfont; 698 hpos = statep->shpos; 699 vpos = statep->svpos; 700 horig = statep->shorig; 701 vorig = statep->svorig; 702 } 703 704 int pageno = 0; 705 706 t_page(n) /* do whatever new page functions */ 707 { 708 int i; 709 710 if (output) { 711 papuse++; 712 /* 713 * accounting in pages, for the time being. 714 * New harprot should do the real accounting 715 */ 716 if (++scount >= spage) { 717 t_reset('p'); 718 scount = 0; 719 } 720 } 721 vpos = 0; 722 output = 1; 723 ++pageno; 724 if (nolist == 0) 725 return; /* no -o specified */ 726 output = 0; 727 for (i = 0; i < nolist; i += 2) 728 if (n >= olist[i] && n <= olist[i+1]) { 729 output = 1; 730 break; 731 } 732 } 733 734 t_newline() /* do whatever for the end of a line */ 735 { 736 hpos = 0; /* because we're now back at the left margin */ 737 } 738 739 /* 740 * A PSZ command on the Harris will change the horizontal & vertical size 741 * A HPZ command will change just the Horizontal size. 742 * 743 * so size will contain horizontal size, and versize the vertical 744 */ 745 int size; /* current sizenumber (a legal index in pstab) */ 746 int horsize; /* current horizontal size */ 747 int versize; /* current vertcal size */ 748 int vsizeflag; /* if set, versize differs from size */ 749 750 t_size(n) /* convert integer to internal size number*/ 751 int n; 752 { 753 int i; 754 755 if (n <= pstab[0]) 756 return(1); 757 else if (n >= pstab[nsizes-1]) 758 return(nsizes); 759 for (i = 0; n > pstab[i]; i++) 760 ; 761 return(i+1); 762 } 763 764 t_charht(n) /* set character height to n */ 765 int n; 766 { 767 versize = pstab[n-1]; 768 if( versize != horsize ) 769 vsizeflag = 1; 770 putsize(); 771 } 772 773 int sltab[] = { 0, 9, 12, 15, -1}; /* possible slanting factors */ 774 int slctab[] = { OB0, OB1, OB2, OB3 }; /* slanting codes */ 775 int slant; /* current general slanting factor (of slant cmd) */ 776 int fslant; /* slanting factor of current font */ 777 778 /* 779 * current font has to be slanted, the slant will be set to fslant. 780 * if the has been a slant command, the slant will be set to "slant", 781 * overiding the fslant. 782 * if slant is reset to 0, and there fslant != 0, slant will be set to "fslant" 783 * 784 * fslant will be manupulated by setfont (slanting can be an attribute 785 * to a (Harris-)font. 786 * 787 * There are to many slants in this comment 788 */ 789 790 t_slant(n) /* do slant cmd */ 791 int n; 792 { slant = n; 793 setslant(n); 794 } 795 796 setslant(n) /* set slant to n */ 797 int n; 798 { int j; 799 static int aslant; /* the actual slanting factor */ 800 801 if( n == aslant) 802 return; 803 if( n == 0 && fslant) { /* back to slant of font */ 804 setslant( fslant ); 805 return; 806 } 807 for (j = 0; n > ( aslant = sltab[j]); j++) 808 if ( aslant == -1) { 809 aslant = sltab[--j]; 810 break; 811 } 812 hflush(); 813 oput( slctab[j] ); 814 if (dbg) 815 printf("slant to %d\n", aslant); 816 } 817 818 slantfont(n) /* set fontslant */ 819 int n; 820 { 821 fslant = n; 822 if(slant) 823 return; /* slant of slanting command 824 * overrides fslant */ 825 setslant( fslant); /* set slanting */ 826 } 827 828 t_font(s) /* convert string to internal font number */ 829 char *s; 830 { 831 int n; 832 833 n = atoi(s); 834 if (n < 0 || n > nfonts) 835 n = 1; 836 return(n); 837 } 838 839 t_text(s) /* print string s as text, the real \! implemantation */ 840 char *s; 841 { 842 int c, w; 843 char str[100]; 844 845 error(!FATAL, "t_text not well implented (yet)!"); 846 if (!output) 847 return; 848 while (c = *s++) { 849 if (c == '\\') { 850 switch (c = *s++) { 851 case '\\': 852 case 'e': 853 put1('\\'); 854 break; 855 case '(': 856 str[0] = *s++; 857 str[1] = *s++; 858 str[2] = '\0'; 859 put1s(str); 860 break; 861 } 862 } else { 863 put1(c); 864 } 865 hmot(lastw); 866 if (dbg) printf("width = %d\n", lastw); 867 } 868 } 869 870 t_reset(c) 871 { 872 int n; 873 874 if (output) 875 /* 876 papuse++ 877 */ 878 ; 879 switch(c) { 880 case 'p': 881 cut(); /* 882 * interpret pauses as comment for cutting 883 * the paper 884 */ 885 if(dbg) 886 printf("reset p\n"); 887 break; 888 case 's': 889 cut(); 890 nocutting++; 891 if(dbg) 892 printf("reset s\n"); 893 ex(); 894 break; 895 default: 896 error(!FATAL, "Unknown reset function"); 897 break; 898 } 899 } 900 901 cut() 902 { 903 if (cflag || nocutting) 904 return; 905 hflush(); 906 oput(CUT); 907 hpos = 0; 908 fcut = 1; 909 if (dbg) 910 printf("Cut\n"); 911 } 912 913 account() /* record paper use */ 914 { 915 /* Don somewhere els */ 916 } 917 918 t_trailer() 919 { 920 } 921 922 hflush() /* do the actual motion */ 923 { 924 if (!output) 925 return; 926 hor_move( hpos - htrue ); 927 } 928 929 hor_move( amount ) 930 int amount; 931 { int high, low; 932 933 #ifdef VAX 934 if ( abs(amount) > 0177777) 935 error(FATAL, "Impossible escape"); 936 #endif 937 if ( amount == 0 && harcode == 0) 938 return; /* really nothing to do */ 939 if(dbg > 1) 940 printf("h_move %d\n", amount); 941 low = amount & BMASK; 942 high = ( amount >> BYTE) & BMASK; 943 /* 944 * if there is a code wating for output, 945 * send that one to be output, plus the movement, 946 * else send the MAB 947 * and the movement 948 */ 949 oput( harcode ? harcode : MAB); 950 harcode = 0; 951 oput(high); 952 oput(low); 953 htrue = hpos; 954 } 955 956 957 hmot(n) 958 { 959 hpos += n; 960 } 961 962 hgoto(n) 963 { 964 hpos = n; 965 } 966 967 vgoto(n) 968 { 969 vmot(n - vpos); 970 } 971 972 vmot(n) /* generate n units of vertical motion */ 973 int n; 974 { 975 if (!output) 976 return; 977 if (n != 0) { 978 ver_move( n ); 979 vpos += n; 980 } 981 } 982 983 ver_move( amount ) 984 int amount; 985 { int high, low; 986 987 #ifdef VAX 988 if ( abs(amount) > 0177777) 989 error(FATAL, "Impossible leading"); 990 #endif 991 if(dbg > 1) 992 printf("v_move %d\n", amount); 993 low = amount & BMASK; 994 high = ( amount >> BYTE) & BMASK; 995 hflush(); 996 oput(VMV); 997 oput(high); 998 oput(low); 999 } 1000 1001 put1s(s) /* s is a funny char name */ 1002 char *s; 1003 { 1004 int i; 1005 1006 if (!output) 1007 return; 1008 /* 1009 if(strcmp("ul", s) == 0) { 1010 set_ul(); 1011 return; 1012 } 1013 if(strcmp("ru", s) == 0) { 1014 set_ru(); 1015 return; 1016 } 1017 */ 1018 for (i = 0; i < nchtab; i++) 1019 if (strcmp(&chname[chtab[i]], s) == 0) 1020 break; 1021 /* 1022 printf("i+128: %d,s: %s, chname: %s\n", i+128, s, &chname[chtab[i]]); 1023 */ 1024 if (i < nchtab) 1025 put1(i + 128); 1026 else 1027 if(dbg) 1028 printf("Special char %s doesn't exist\n", s); 1029 } 1030 1031 /* 1032 * The Harris doesn'nt have a proper underrule or rule 1033 * 1034 * Try to generate one with the RULE command. 1035 * 1036 */ 1037 1038 #define UL_DOWN 7 /* 7 half decipoints at pointsize 10 */ 1039 1040 set_ul() 1041 { int move; 1042 int tmp; 1043 1044 hflush(); 1045 move = UL_DOWN * versize; 1046 ver_move( move); 1047 tmp = get_width("ul") / 2; 1048 /* 1049 * we assume that dev.unitwidth is 10, so getwidth 1050 * will return the value in half decipoints! 1051 */ 1052 set_line(tmp); 1053 ver_move( -move); 1054 } 1055 1056 #define RU_DOWN 1 /* 2 half decipoints at pointsize 10 */ 1057 1058 set_ru() 1059 { 1060 int tmp, move; 1061 1062 hflush(); 1063 move = RU_DOWN * versize; 1064 ver_move( move); 1065 tmp = get_width("ul") / 2; 1066 set_line(tmp); 1067 ver_move( -move); 1068 } 1069 1070 #define HEIGHT 6 /* thickness (decipoints) at pointsize 10 */ 1071 #define MIN_VAL 2 /* Minimum value for rule height & length */ 1072 #define MAX_H 720 /* Maximum for height */ 1073 #define MAX_L 8160 /* Maximum length of the SMC 68 Pica machine */ 1074 1075 /* 1076 * set line of length decipoints. 1077 */ 1078 1079 set_line( length ) 1080 int length; 1081 { 1082 int height; 1083 char one, two, three, four; 1084 1085 /* 1086 printf("Line %d decipoints\n", i); 1087 */ 1088 1089 height = (HEIGHT * versize + dev.unitwidth/2) / dev.unitwidth; 1090 if ( height < MIN_VAL) 1091 height = MIN_VAL; 1092 if (height > MAX_H) 1093 height = MAX_H; 1094 if (length > MAX_L) 1095 length = MAX_L; 1096 if (dbg) 1097 printf("Line: length %d height %d\n", length, height); 1098 1099 one = ( height >> BYTE ) | RUL; 1100 two = height & BMASK; 1101 three = length >> BYTE; 1102 four = length & BMASK; 1103 oput(one); oput(two); oput(three); oput(four); 1104 } 1105 1106 /* 1107 * get the width of a char, to be used only by set_ul() and set-ru() 1108 */ 1109 1110 int 1111 get_width( s ) 1112 char *s; 1113 { 1114 int c; 1115 int width; 1116 int j, i, k, ofont; 1117 char *pw; 1118 1119 for (c = 0; c < nchtab; c++) 1120 if (strcmp(&chname[chtab[c]], s) == 0) 1121 break; 1122 if (c < nchtab) 1123 c += 128-32; 1124 if (c <= 0 || c >= nchtab + 128-32) { 1125 if (dbg) printf("non-exist 0%o\n", c+32); 1126 return; 1127 } 1128 k = ofont = font; 1129 i = fitab[font][c] & BMASK; 1130 if (i != 0) { /* it's on this font */ 1131 pw = widthtab[font]; 1132 } else if (smnt > 0) { /* on special (we hope) */ 1133 for (k=smnt, j=0; j <= nfonts; j++, k = (k+1) % (nfonts+1)) 1134 /* 1135 * Look for the character, start at the special font 1136 * and search further in a wrap around manner 1137 */ 1138 if ((i = fitab[k][c] & BMASK) != 0) { 1139 pw = widthtab[k]; 1140 setfont(k); 1141 break; 1142 } 1143 } 1144 if (i == 0 || (width = pw[i] & BMASK) == 0 || k > nfonts) { 1145 /* device drivers do width & 077, not really necessary */ 1146 if (dbg) { 1147 printf("Width not found \\(%s\n", s); 1148 } 1149 return; 1150 } 1151 width = (width * horsize + dev.unitwidth/2) / dev.unitwidth; 1152 if (font != ofont) 1153 setfont(ofont); 1154 return( width); 1155 } 1156 1157 /* font position info: */ 1158 1159 struct { 1160 char *name; 1161 int number; 1162 } fontname[NFONT+1]; 1163 1164 put1(c) /* output char c */ 1165 int c; 1166 { 1167 char *pw; 1168 register char *p; 1169 register int i, k; 1170 int j, ofont, code; 1171 short f; 1172 1173 if (!output) 1174 return; 1175 c -= 32; 1176 if (c <= 0) { 1177 if (dbg) printf("non-exist 0%o\n", c+32); 1178 lastw = widthtab[font][0] * pstab[size-1] /dev.unitwidth; 1179 return; 1180 } 1181 k = ofont = font; 1182 i = fitab[font][c] & BMASK; 1183 if (i != 0) { /* it's on this font */ 1184 p = codetab[font]; 1185 pw = widthtab[font]; 1186 } else if (smnt > 0) { /* on special (we hope) */ 1187 for (k=smnt, j=0; j <= nfonts; j++, k = (k+1) % (nfonts+1)) 1188 /* 1189 * Look for the character, start at the special font 1190 * and search further in a wrap around manner 1191 */ 1192 if ((i = fitab[k][c] & BMASK) != 0) { 1193 p = codetab[k]; 1194 pw = widthtab[k]; 1195 setfont(k); 1196 break; 1197 } 1198 } 1199 if (i == 0 || (code = p[i] & BMASK) == 0 || k > nfonts) { 1200 if (dbg) { 1201 if (isprint(c+32) && isascii(c+32)) 1202 printf("not found %c\n", c+32); 1203 else 1204 printf("not found \\(%s\n", &chname[chtab[c -128+32]]); 1205 } 1206 return; 1207 } 1208 if (fontbase[k]->fonttab == 1) 1209 f = fonttab[k][i]; 1210 else 1211 f = fontname[k].number; 1212 hflush(); 1213 if (dbg) { 1214 if (isprint(c+32) && isascii(c+32)) { /* My God! */ 1215 printf("%c %d %d\n", c+32, code, f); 1216 } 1217 else 1218 printf("\\(%s %d %d\n", &chname[chtab[c -128+32]], code, f); 1219 } 1220 if(code == 0 || code > 0200) { 1221 error(FATAL,"Illegal code 0%o found for char %03o\n", code, c+32); 1222 } 1223 putcode(code, f); /* character is < 254 */ 1224 if (font != ofont) /* char on special font, reset */ 1225 setfont(ofont); 1226 lastw = pw[i] & BMASK; 1227 /*HIRO*/ 1228 if( dbg) 1229 fprintf(stderr,"lastw %d pw[i] %d\n", lastw,pw[i]); 1230 lastw = (lastw * pstab[size-1] + dev.unitwidth/2) / dev.unitwidth; 1231 } 1232 1233 putcode(code, f) 1234 char code; short f; 1235 { 1236 static short phfont; 1237 1238 #ifdef VAX 1239 if ( f > 0177777) 1240 error(FATAL, "Impossible font selected"); 1241 #endif 1242 1243 if( harcode) { /* if character pending */ 1244 hflush(); /* update position and flush pending char */ 1245 } 1246 if ( f != phfont ) { 1247 if(dbg > 1) 1248 printf("font to %d\n", f); 1249 putfont(f); 1250 } 1251 harcode = code; 1252 phfont = f; 1253 } 1254 1255 putfont(f) 1256 int f; 1257 { int high, low; 1258 1259 low = f & BMASK; 1260 high = (f >> BYTE ) & BMASK; 1261 oput(FNT); 1262 oput(high); 1263 oput(low); 1264 } 1265 1266 setsize(n) /* set point size to a true pointsize */ 1267 int n; 1268 { 1269 1270 if (!output) 1271 return; 1272 horsize = pstab[n-1]; 1273 vsizeflag = 0; 1274 size = n; 1275 putsize(); 1276 } 1277 1278 /* 1279 * Do the actual sizechange(s). 1280 */ 1281 1282 putsize() 1283 { 1284 if(!vsizeflag) { 1285 flushchar(); 1286 sizecmd( PSZ, horsize); 1287 } 1288 else { 1289 flushchar(); 1290 sizecmd( PSZ, versize); 1291 sizecmd( HPZ, horsize); 1292 } 1293 } 1294 1295 sizecmd( cmd, n) 1296 int cmd, n; 1297 { 1298 int i, low, high; 1299 1300 i = 10 * n; 1301 if(dbg) 1302 printf("size to %d\n", n); 1303 if( i > 01777) 1304 error(FATAL, "Impossible pointsize requested"); 1305 low = i & BMASK; 1306 high = (i >> BYTE) & BMASK; 1307 if( high > 03 ) 1308 error(FATAL, "system error in point size cmd"); 1309 oput( cmd | high); 1310 oput(low); 1311 } 1312 1313 t_fp(n, s, si) /* font position n now contains font s, intname si */ 1314 int n; 1315 char *s, *si; 1316 { 1317 fontname[n].name = s; 1318 fontname[n].number = atoi(si); 1319 } 1320 1321 setfont(n) /* set font to n (internal)*/ 1322 int n; 1323 { 1324 if (!output) 1325 return; 1326 if (n < 0 || n > NFONT) 1327 error(FATAL, "illegal font %d\n", n); 1328 font = n; 1329 slantfont(fontbase[n]->slant & BMASK); 1330 } 1331 1332 /* 1333 putint(n) 1334 { 1335 if (dbg) { 1336 printf("%02d\n", n); 1337 return; 1338 } 1339 putc(n>>8, tf); 1340 putc(n, tf); 1341 } 1342 */ 1343