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