1*30594Ssam /* psdit.c 1.1 87/03/08 */ 2*30594Ssam #ifndef lint 3*30594Ssam static char Notice[] = "Copyright (c) 1984, 1985 Adobe Systems Incorporated"; 4*30594Ssam static char *RCSID="$Header: psdit.c,v 2.1 85/11/24 11:50:41 shore Rel $"; 5*30594Ssam #endif 6*30594Ssam /* psdit.c 7*30594Ssam * 8*30594Ssam * Copyright (c) 1984, 1985 Adobe Systems Incorporated 9*30594Ssam * 10*30594Ssam * ditroff intermediate file to PostScript translator 11*30594Ssam * 12*30594Ssam * Original Version: Barry Hayes spring/summer 1984 13*30594Ssam * Edit History: 14*30594Ssam * Andrew Shore: Sat Nov 23 20:05:26 1985 15*30594Ssam * End Edit History. 16*30594Ssam * 17*30594Ssam * RCSLOG: 18*30594Ssam * $Log: psdit.c,v $ 19*30594Ssam * Revision 2.1 85/11/24 11:50:41 shore 20*30594Ssam * Product Release 2.0 21*30594Ssam * 22*30594Ssam * Revision 1.8 85/11/23 20:09:44 shore 23*30594Ssam * test for termination of included PostScript was bad 24*30594Ssam * 25*30594Ssam * Revision 1.7 85/11/21 14:23:56 shore 26*30594Ssam * added envget check for PSLIBDIR 27*30594Ssam * 28*30594Ssam * Revision 1.6 85/11/20 00:43:43 shore 29*30594Ssam * support for included PostScript 30*30594Ssam * big rework on FlushShow, word "breaks" 31*30594Ssam * removed FlushFont and made them instant 32*30594Ssam * Still no Gremlin support yet 33*30594Ssam * 34*30594Ssam * Revision 1.5 85/10/03 10:48:09 shore 35*30594Ssam * added FlushShow to xf fix ! 36*30594Ssam * 37*30594Ssam * Revision 1.4 85/10/02 16:20:32 shore 38*30594Ssam * fixed xf bug 39*30594Ssam * mounting a font causes a font switch! 40*30594Ssam * 41*30594Ssam * Revision 1.3 85/07/09 13:10:20 shore 42*30594Ssam * added fclose on map file 43*30594Ssam * 44*30594Ssam * Revision 1.2 85/05/14 11:24:23 shore 45*30594Ssam * added flush to trailer 46*30594Ssam * fixed read bug when mounting fonts 47*30594Ssam * 48*30594Ssam * 49*30594Ssam */ 50*30594Ssam 51*30594Ssam /* 52*30594Ssam output language from troff: 53*30594Ssam all numbers are character strings 54*30594Ssam 55*30594Ssam sn size in points 56*30594Ssam fn font as number from 1-n 57*30594Ssam cx ascii character x 58*30594Ssam Cxyz funny char xyz. terminated by white space 59*30594Ssam Hn go to absolute horizontal position n 60*30594Ssam Vn go to absolute vertical position n (down is positive) 61*30594Ssam hn go n units horizontally (relative) 62*30594Ssam vn ditto vertically 63*30594Ssam nnc move right nn, then print c (exactly 2 digits!) 64*30594Ssam (this wart is an optimization that shrinks output file size 65*30594Ssam about 35% and run-time about 15% while preserving ascii-ness) 66*30594Ssam Dt ...\n draw operation 't': 67*30594Ssam Dl x y line from here by x,y 68*30594Ssam Dc d circle of diameter d with left side here 69*30594Ssam De x y ellipse of axes x,y with left side here 70*30594Ssam Da x y r arc counter-clockwise by x,y of radius r 71*30594Ssam D~ x y x y ... wiggly line by x,y then x,y ... 72*30594Ssam nb a end of line (information only -- no action needed) 73*30594Ssam a = space before line, a = after 74*30594Ssam w paddable word space -- no action needed 75*30594Ssam pn new page begins -- set v to 0 76*30594Ssam { push current environment (font info & location) 77*30594Ssam } pop a saved environment 78*30594Ssam txxxx print string xxxx using natural widths 79*30594Ssam #...\n comment 80*30594Ssam x ...\n device control functions: 81*30594Ssam x i[nit] init 82*30594Ssam x T s name of device is s 83*30594Ssam x r[es] n h v resolution is n/inch 84*30594Ssam h = min horizontal motion, v = min vert 85*30594Ssam x p[ause] pause (can restart) 86*30594Ssam x s[top] stop -- done for ever 87*30594Ssam x t[railer] generate trailer 88*30594Ssam x f[font] n s font position n contains font s 89*30594Ssam x H[eight] n set character height to n 90*30594Ssam x S[slant] n set slant to N 91*30594Ssam 92*30594Ssam Adobe Extension for included PostScript: 93*30594Ssam % 94*30594Ssam (raw postscript...) 95*30594Ssam .\n 96*30594Ssam 97*30594Ssam */ 98*30594Ssam 99*30594Ssam #include <stdio.h> 100*30594Ssam #include <ctype.h> 101*30594Ssam #include <signal.h> 102*30594Ssam #include <pwd.h> 103*30594Ssam #ifdef SYSV 104*30594Ssam extern struct passwd *getpwuid(); 105*30594Ssam #endif 106*30594Ssam #include "transcript.h" 107*30594Ssam 108*30594Ssam #include "dev.h" 109*30594Ssam 110*30594Ssam char *malloc(); 111*30594Ssam 112*30594Ssam #define NFONT 10 113*30594Ssam 114*30594Ssam /* DIT state consists of: */ 115*30594Ssam private int hpos; /* current horizontal position */ 116*30594Ssam private int vpos; /* current vertical position */ 117*30594Ssam private int fontsize; /* current font size */ 118*30594Ssam private int fontheight; /* current character height */ 119*30594Ssam private int fontslant; /* current font slant */ 120*30594Ssam private int font; /* current font */ 121*30594Ssam private int resolution; /* device resolution */ 122*30594Ssam private int minhoriz; /* minimum horizontal motion */ 123*30594Ssam private int minvert; /* minimum vertical motion */ 124*30594Ssam 125*30594Ssam private int onspecial; 126*30594Ssam private int specfont; 127*30594Ssam private int prevfont; 128*30594Ssam private int pfont; 129*30594Ssam 130*30594Ssam /* {} push/pop stack */ 131*30594Ssam #define DSTACK 10 132*30594Ssam private struct ditstack { 133*30594Ssam int hpos, vpos, fontsize, fontheight, fontslant, font; 134*30594Ssam } ditstack[DSTACK]; 135*30594Ssam private int dlevel = 0; 136*30594Ssam 137*30594Ssam #define ErrorTolerance 48 138*30594Ssam #define PSWID 0x00000FFF 139*30594Ssam #define ISPSPROC 0x000FF000 140*30594Ssam 141*30594Ssam 142*30594Ssam /* PSscale is equivalent to (x * PSmag / 72000) + 0.5 */ 143*30594Ssam #define PSmag 16 144*30594Ssam #define PSscale(x) (((x)+2250)/4500) 145*30594Ssam 146*30594Ssam /* we maintain PS coords with PSmag times the precision */ 147*30594Ssam /* current PS state is: */ 148*30594Ssam 149*30594Ssam private int PSx; /* current horizontal position */ 150*30594Ssam private int PSy; /* current vertical position */ 151*30594Ssam private int savex, savey; /* position of start of current show string */ 152*30594Ssam 153*30594Ssam /* ps move types -- note that XMOVE|YMOVE == XYMOVE ! */ 154*30594Ssam #define NONE 0 155*30594Ssam #define XMOVE 1 156*30594Ssam #define YMOVE 2 157*30594Ssam #define XYMOVE 3 158*30594Ssam 159*30594Ssam private int movepending = NONE; 160*30594Ssam 161*30594Ssam /* buffer string for show -- save up adjacent chars */ 162*30594Ssam #define SHOWSIZE 400 163*30594Ssam private char showbuf[SHOWSIZE + 3]; /* extras are for quoting */ 164*30594Ssam private int showind = 0; /* index into string of next available byte */ 165*30594Ssam private int PSshowlen = 0; /* size in big units of buffered string */ 166*30594Ssam private int nshow = 0; /* actual number of show chars in showbuf */ 167*30594Ssam private int startx; /* troff starting pos of current string */ 168*30594Ssam private int thisw; 169*30594Ssam 170*30594Ssam /* #define NONE 0 */ 171*30594Ssam #define HMOT 1 172*30594Ssam #define VMOT 2 173*30594Ssam #define CPUT 4 174*30594Ssam #define BRK 8 175*30594Ssam #define FNT 16 176*30594Ssam private int lastcmd; 177*30594Ssam 178*30594Ssam private int output = 0; /* do we do output at all? */ 179*30594Ssam private int nolist = 0; /* output page list if > 0 */ 180*30594Ssam private int olist[20]; /* pairs of page numbers */ 181*30594Ssam private int spage = 9999; /* stop every spage pages */ 182*30594Ssam private int scount = 0; 183*30594Ssam private int stopped = 0; 184*30594Ssam private int pageno = 0; 185*30594Ssam private int firstpage = TRUE; 186*30594Ssam 187*30594Ssam private struct dev dev; 188*30594Ssam private struct font *fontbase[NFONT+1]; 189*30594Ssam private short *pstab; 190*30594Ssam private int dres; /* resolution from DESC */ 191*30594Ssam private int nsizes; /* number of point sizes from DESC */ 192*30594Ssam private int nfonts; /* number of fonts from DESC */ 193*30594Ssam private int smnt; /* index of first special font */ 194*30594Ssam private int nchtab; 195*30594Ssam private char *chname; 196*30594Ssam private short *chtab; 197*30594Ssam private char *fitab[NFONT+1]; 198*30594Ssam private char *widthtab[NFONT+1]; /* widtab would be a better name */ 199*30594Ssam private char *codetab[NFONT+1]; /* device codes */ 200*30594Ssam 201*30594Ssam private int *pswidths[NFONT+1]; /* ps width tables */ 202*30594Ssam private int fontdelta[NFONT+1]; /* nonzero if xf overwrites font i */ 203*30594Ssam 204*30594Ssam /* font position info: */ 205*30594Ssam private struct { 206*30594Ssam char *name; 207*30594Ssam int number; 208*30594Ssam } fontname[NFONT+1]; 209*30594Ssam 210*30594Ssam #define FATAL 1 211*30594Ssam #define BMASK 0377 212*30594Ssam 213*30594Ssam #ifdef DEBUG 214*30594Ssam int dbg = 0; 215*30594Ssam int fdbg = 0; 216*30594Ssam #define debugp(xxx) {if(dbg != 0){dbg--; printf xxx ; VOIDC fflush(stdout);}} 217*30594Ssam #else 218*30594Ssam #define debugp(x) 219*30594Ssam #endif 220*30594Ssam 221*30594Ssam private FILE *tf = stdout; /* output file */ 222*30594Ssam private char devname[20] = "psc"; 223*30594Ssam 224*30594Ssam private char *infilename = "stdin"; /* input file name */ 225*30594Ssam private char *prologfile = PSDITPRO; 226*30594Ssam private char *ditdir = DitDir; 227*30594Ssam 228*30594Ssam private char *prog; /* argv[0] - program name */ 229*30594Ssam 230*30594Ssam main(argc, argv) 231*30594Ssam int argc; 232*30594Ssam char *argv[]; 233*30594Ssam { 234*30594Ssam FILE *fp; 235*30594Ssam VOID done(); 236*30594Ssam 237*30594Ssam prog = argv[0]; 238*30594Ssam while (argc > 1 && argv[1][0] == '-') { 239*30594Ssam switch (argv[1][1]) { 240*30594Ssam case 'f': 241*30594Ssam case 'F': 242*30594Ssam if (argv[1][2]) 243*30594Ssam ditdir = &argv[1][2]; 244*30594Ssam else { 245*30594Ssam ditdir = argv[2]; 246*30594Ssam argv++; 247*30594Ssam argc--; 248*30594Ssam } 249*30594Ssam break; 250*30594Ssam case 'p': 251*30594Ssam if (argv[1][2]) 252*30594Ssam prologfile = &argv[1][2]; 253*30594Ssam break; 254*30594Ssam case 'o': 255*30594Ssam outlist (&argv[1][2]); 256*30594Ssam break; 257*30594Ssam case 'd': 258*30594Ssam #ifdef DEBUG 259*30594Ssam dbg = atoi (&argv[1][2]); 260*30594Ssam if (dbg == 0) 261*30594Ssam dbg = 1; 262*30594Ssam tf = stdout; 263*30594Ssam #endif DEBUG 264*30594Ssam break; 265*30594Ssam case 'b': /* ignore busy */ 266*30594Ssam break; 267*30594Ssam case 'w': /* ignore wait */ 268*30594Ssam break; 269*30594Ssam case 's': 270*30594Ssam spage = atoi (&argv[1][2]); 271*30594Ssam if (spage <= 0) 272*30594Ssam spage = 9999; 273*30594Ssam break; 274*30594Ssam } 275*30594Ssam argc--; 276*30594Ssam argv++; 277*30594Ssam } 278*30594Ssam 279*30594Ssam if (signal (SIGINT, done) == SIG_IGN) { 280*30594Ssam signal (SIGINT, SIG_IGN); 281*30594Ssam signal (SIGQUIT, SIG_IGN); 282*30594Ssam signal (SIGHUP, SIG_IGN); 283*30594Ssam } 284*30594Ssam else { 285*30594Ssam signal (SIGQUIT, done); 286*30594Ssam signal (SIGHUP, done); 287*30594Ssam } 288*30594Ssam signal (SIGTERM, done); 289*30594Ssam 290*30594Ssam preface (); 291*30594Ssam 292*30594Ssam if (argc <= 1) 293*30594Ssam conv (stdin); 294*30594Ssam else 295*30594Ssam while (--argc > 0) { 296*30594Ssam if (strcmp (*++argv, "-") == 0) 297*30594Ssam fp = stdin; 298*30594Ssam else if ((fp = fopen (*argv, "r")) == NULL) { 299*30594Ssam fprintf (stderr, "%s: can't open %s\n", prog, *argv); 300*30594Ssam pexit(prog,2); 301*30594Ssam } 302*30594Ssam infilename = *argv; 303*30594Ssam conv (fp); 304*30594Ssam VOIDC fclose (fp); 305*30594Ssam } 306*30594Ssam done (); 307*30594Ssam } 308*30594Ssam 309*30594Ssam private outlist(s) /* process list of page numbers to be printed */ 310*30594Ssam char *s; 311*30594Ssam { 312*30594Ssam int n1, n2, i; 313*30594Ssam 314*30594Ssam nolist = 0; 315*30594Ssam while (*s) { 316*30594Ssam n1 = 0; 317*30594Ssam if (isdigit (*s)) { 318*30594Ssam do { 319*30594Ssam n1 = 10 * n1 + *s++ - '0'; 320*30594Ssam } 321*30594Ssam while (isdigit (*s)); 322*30594Ssam } 323*30594Ssam else { 324*30594Ssam n1 = -9999; 325*30594Ssam } 326*30594Ssam n2 = n1; 327*30594Ssam if (*s == '-') { 328*30594Ssam s++; 329*30594Ssam n2 = 0; 330*30594Ssam if (isdigit (*s)) { 331*30594Ssam do { 332*30594Ssam n2 = 10 * n2 + *s++ - '0'; 333*30594Ssam } 334*30594Ssam while (isdigit (*s)); 335*30594Ssam } 336*30594Ssam else { 337*30594Ssam n2 = 9999; 338*30594Ssam } 339*30594Ssam } 340*30594Ssam olist[nolist++] = n1; 341*30594Ssam olist[nolist++] = n2; 342*30594Ssam if (*s != '\0') { 343*30594Ssam s++; 344*30594Ssam } 345*30594Ssam } 346*30594Ssam olist[nolist] = 0; 347*30594Ssam #ifdef DEBUG 348*30594Ssam if (dbg) 349*30594Ssam for (i = 0; i < nolist; i += 2) 350*30594Ssam printf ("%3d %3d\n", olist[i], olist[i + 1]); 351*30594Ssam #endif 352*30594Ssam } 353*30594Ssam 354*30594Ssam private conv(fp) /* convert a file */ 355*30594Ssam register FILE *fp; 356*30594Ssam { 357*30594Ssam register int c, k; 358*30594Ssam int m, n, n1, m1; 359*30594Ssam char str[100], buf[300]; 360*30594Ssam 361*30594Ssam while ((c = getc(fp)) != EOF) { 362*30594Ssam switch (c) { 363*30594Ssam case '\n': case ' ': case '\0': 364*30594Ssam break; 365*30594Ssam case '{': /* push down current environment */ 366*30594Ssam t_push(); 367*30594Ssam break; 368*30594Ssam case '}': 369*30594Ssam t_pop(); 370*30594Ssam break; 371*30594Ssam case '0': case '1': case '2': case '3': case '4': 372*30594Ssam case '5': case '6': case '7': case '8': case '9': 373*30594Ssam /* two motion digits plus a character */ 374*30594Ssam hmot((c - '0') * 10 + getc (fp) - '0'); 375*30594Ssam lastcmd = HMOT; 376*30594Ssam put1(getc(fp), (char *) 0); 377*30594Ssam lastcmd = CPUT; 378*30594Ssam break; 379*30594Ssam case 'c': /* single ascii character */ 380*30594Ssam put1(getc(fp), (char *) 0); 381*30594Ssam lastcmd = CPUT; 382*30594Ssam break; 383*30594Ssam case 'C': 384*30594Ssam fscanf(fp, "%s", str); 385*30594Ssam put1s(str); 386*30594Ssam lastcmd = CPUT; 387*30594Ssam break; 388*30594Ssam case 't': /* straight text */ 389*30594Ssam fgets(buf, sizeof (buf), fp); 390*30594Ssam t_text (buf); 391*30594Ssam lastcmd = CPUT; 392*30594Ssam break; 393*30594Ssam case 'D': /* draw function */ 394*30594Ssam fgets(buf, sizeof (buf), fp); 395*30594Ssam switch (buf[0]) { 396*30594Ssam case 'l': /* draw a line */ 397*30594Ssam sscanf (buf + 1, "%d %d", &n, &m); 398*30594Ssam drawline (n, m); 399*30594Ssam break; 400*30594Ssam case 'c': /* circle */ 401*30594Ssam sscanf (buf + 1, "%d", &n); 402*30594Ssam drawcirc (n); 403*30594Ssam break; 404*30594Ssam case 'e': /* ellipse */ 405*30594Ssam sscanf (buf + 1, "%d %d", &m, &n); 406*30594Ssam drawellip (m, n); 407*30594Ssam break; 408*30594Ssam case 'a': /* arc */ 409*30594Ssam sscanf (buf + 1, "%d %d %d %d", &n, &m, &n1, &m1); 410*30594Ssam drawarc (n, m, n1, m1); 411*30594Ssam break; 412*30594Ssam case '~': /* wiggly line */ 413*30594Ssam drawwig (buf + 1); 414*30594Ssam break; 415*30594Ssam default: 416*30594Ssam fprintf(stderr,"%s: unknown drawing function %s\n", 417*30594Ssam prog,buf); 418*30594Ssam exit(2); 419*30594Ssam break; 420*30594Ssam } 421*30594Ssam break; 422*30594Ssam case 's': 423*30594Ssam fscanf (fp, "%d", &n); 424*30594Ssam t_size (n); 425*30594Ssam lastcmd = FNT; 426*30594Ssam break; 427*30594Ssam case 'f': 428*30594Ssam fscanf (fp, "%s", str); 429*30594Ssam setfont (t_font (str)); 430*30594Ssam lastcmd = FNT; 431*30594Ssam break; 432*30594Ssam case 'H': /* absolute horizontal motion */ 433*30594Ssam while ((c = getc (fp)) == ' '); 434*30594Ssam k = 0; 435*30594Ssam do { 436*30594Ssam k = 10 * k + c - '0'; 437*30594Ssam } while (isdigit (c = getc (fp))); 438*30594Ssam ungetc (c, fp); 439*30594Ssam hgoto (k); 440*30594Ssam lastcmd = HMOT; 441*30594Ssam break; 442*30594Ssam case 'h': /* relative horizontal motion */ 443*30594Ssam while ((c = getc (fp)) == ' '); 444*30594Ssam k = 0; 445*30594Ssam do { 446*30594Ssam k = 10 * k + c - '0'; 447*30594Ssam } while (isdigit (c = getc (fp))); 448*30594Ssam ungetc (c, fp); 449*30594Ssam hmot (k); 450*30594Ssam lastcmd = HMOT; 451*30594Ssam break; 452*30594Ssam case 'w': 453*30594Ssam FlushShow(1); 454*30594Ssam lastcmd = BRK; 455*30594Ssam break; 456*30594Ssam case 'V': 457*30594Ssam fscanf (fp, "%d", &n); 458*30594Ssam vgoto (n); 459*30594Ssam lastcmd = VMOT; 460*30594Ssam break; 461*30594Ssam case 'v': 462*30594Ssam fscanf (fp, "%d", &n); 463*30594Ssam vmot (n); 464*30594Ssam lastcmd = VMOT; 465*30594Ssam break; 466*30594Ssam case 'p': /* new page */ 467*30594Ssam fscanf (fp, "%d", &n); 468*30594Ssam t_page (n); 469*30594Ssam lastcmd = NONE; 470*30594Ssam break; 471*30594Ssam case 'n': /* end of line -- ignore */ 472*30594Ssam while (getc (fp) != '\n'); 473*30594Ssam FlushShow(1); 474*30594Ssam lastcmd = BRK; 475*30594Ssam break; 476*30594Ssam case '#': /* comment */ 477*30594Ssam /* maybe should pass through as a PS comment */ 478*30594Ssam while (getc (fp) != '\n'); 479*30594Ssam break; 480*30594Ssam case 'x': /* device control */ 481*30594Ssam devcntrl (fp); 482*30594Ssam break; 483*30594Ssam case '%': /* imbedded PostScript */ 484*30594Ssam /* copy everything up to but NOT including a line */ 485*30594Ssam /* with at single "." */ 486*30594Ssam FlushShow(0);MoveTo();DoMove(); 487*30594Ssam printf("\n%% included PostScript\n"); 488*30594Ssam while (fgets(buf, sizeof buf, fp) != NULL) { 489*30594Ssam if (strcmp(".\n",buf) == 0) break; 490*30594Ssam fputs(buf,stdout); 491*30594Ssam } 492*30594Ssam break; 493*30594Ssam default: 494*30594Ssam fprintf(stderr,"%s: bad input char \\%03o (%c)\n",prog,c,c); 495*30594Ssam exit(2); 496*30594Ssam done (); 497*30594Ssam } 498*30594Ssam } 499*30594Ssam } 500*30594Ssam 501*30594Ssam 502*30594Ssam /* put in PostScript prolog */ 503*30594Ssam private preface() 504*30594Ssam { 505*30594Ssam register FILE *prolog; 506*30594Ssam char hostname[256]; 507*30594Ssam char tempfile[512]; 508*30594Ssam struct passwd *pswd; 509*30594Ssam long clock; 510*30594Ssam char *libdir; 511*30594Ssam 512*30594Ssam fprintf (tf, "%%!%s\n", COMMENTVERSION); 513*30594Ssam pswd = getpwuid (getuid ()); 514*30594Ssam VOIDC gethostname (hostname, sizeof hostname); 515*30594Ssam fprintf (tf, "%%%%Creator: %s:%s (%s)\n", hostname, 516*30594Ssam pswd->pw_name, pswd->pw_gecos); 517*30594Ssam fprintf (tf, "%%%%Title: %s (ditroff)\n", infilename); 518*30594Ssam fprintf (tf, "%%%%CreationDate: %s", 519*30594Ssam (time (&clock), ctime (&clock))); 520*30594Ssam fprintf (tf, "%%%%EndComments\n"); 521*30594Ssam 522*30594Ssam if ((libdir = envget("PSLIBDIR")) == NULL) libdir = LibDir; 523*30594Ssam mstrcat(tempfile, libdir, prologfile, sizeof tempfile); 524*30594Ssam if ((copyfile(tempfile, stdout)) != 0) { 525*30594Ssam fprintf(stderr,"%s: can't copy prolog file %s\n",prog, tempfile); 526*30594Ssam exit(2); 527*30594Ssam } 528*30594Ssam printf ("ditstart\n"); 529*30594Ssam } 530*30594Ssam 531*30594Ssam private devcntrl(fp) /* interpret device control functions */ 532*30594Ssam FILE *fp; 533*30594Ssam { 534*30594Ssam char str[20], str1[50], buf[50]; 535*30594Ssam int c, n, res, minh, minv; 536*30594Ssam 537*30594Ssam fscanf (fp, "%s", str); 538*30594Ssam switch (str[0]) { /* crude for now */ 539*30594Ssam case 'i': /* initialize */ 540*30594Ssam fileinit (); 541*30594Ssam t_init (); 542*30594Ssam lastcmd = NONE; 543*30594Ssam break; 544*30594Ssam case 'T': /* device name */ 545*30594Ssam fscanf (fp, "%s", devname); 546*30594Ssam if (strcmp (devname, "psc")) { 547*30594Ssam fprintf(stderr,"%s: device not psc\n",prog); 548*30594Ssam exit(2); 549*30594Ssam } 550*30594Ssam printf ("(%s)xT\n", devname); 551*30594Ssam lastcmd = NONE; 552*30594Ssam break; 553*30594Ssam case 't': /* trailer */ 554*30594Ssam t_trailer (); 555*30594Ssam lastcmd = NONE; 556*30594Ssam break; 557*30594Ssam case 'p': /* pause -- can restart */ 558*30594Ssam t_reset ('p'); 559*30594Ssam lastcmd = NONE; 560*30594Ssam break; 561*30594Ssam case 's': /* stop */ 562*30594Ssam t_reset ('s'); 563*30594Ssam lastcmd = NONE; 564*30594Ssam break; 565*30594Ssam case 'r': /* resolution assumed when prepared */ 566*30594Ssam fscanf (fp, "%d %d %d", &res, &minh, &minv); 567*30594Ssam t_res (res, minh, minv); 568*30594Ssam lastcmd = NONE; 569*30594Ssam break; 570*30594Ssam case 'f': /* font used */ 571*30594Ssam fscanf (fp, "%d %s", &n, str); 572*30594Ssam fgets (buf, sizeof buf, fp);/* in case theres a filename */ 573*30594Ssam ungetc ('\n', fp); /* fgets goes too far */ 574*30594Ssam str1[0] = 0; /* in case there is nothing to come in */ 575*30594Ssam sscanf (buf, "%s", str1); 576*30594Ssam loadfont (n, str, str1); 577*30594Ssam lastcmd = FNT; 578*30594Ssam break; 579*30594Ssam case 'H': /* char height */ 580*30594Ssam fscanf (fp, "%d", &n); 581*30594Ssam t_charht (n); 582*30594Ssam lastcmd = FNT; 583*30594Ssam break; 584*30594Ssam case 'S': /* slant */ 585*30594Ssam fscanf (fp, "%d", &n); 586*30594Ssam t_slant (n); 587*30594Ssam lastcmd = FNT; 588*30594Ssam break; 589*30594Ssam } 590*30594Ssam /* skip rest of input line */ 591*30594Ssam while ((c = getc (fp)) != '\n') {if (c == EOF) break;}; 592*30594Ssam } 593*30594Ssam 594*30594Ssam private fileinit() /* read in font and code files, etc. */ 595*30594Ssam { 596*30594Ssam int i, fin, nw; 597*30594Ssam char *filebase, *p; 598*30594Ssam char temp[60]; 599*30594Ssam unsigned msize; 600*30594Ssam 601*30594Ssam /* open table for device, 602*30594Ssam * read in resolution, size info, font info, etc. and set params */ 603*30594Ssam 604*30594Ssam sprintf (temp, "%s/dev%s/DESC.out", ditdir, devname); 605*30594Ssam if ((fin = open (temp, 0)) < 0) { 606*30594Ssam fprintf (stderr, "%s: can't open %s - %s\n", prog, devname, temp); 607*30594Ssam pexit(prog,2); 608*30594Ssam } 609*30594Ssam if (read(fin,(char *)&dev, (int) sizeof(struct dev)) != sizeof(struct dev)) { 610*30594Ssam fprintf (stderr, "%s: can't read %s\n", prog, temp); 611*30594Ssam pexit(prog,2); 612*30594Ssam } 613*30594Ssam dres = dev.res; 614*30594Ssam nfonts = dev.nfonts; 615*30594Ssam nsizes = dev.nsizes; 616*30594Ssam nchtab = dev.nchtab; 617*30594Ssam /* enough room for whole file */ 618*30594Ssam filebase = malloc ((unsigned) dev.filesize); 619*30594Ssam if (read (fin, filebase, dev.filesize) != dev.filesize) { 620*30594Ssam fprintf (stderr, "%s: trouble reading %s\n", prog, temp); 621*30594Ssam pexit(prog,2); 622*30594Ssam } 623*30594Ssam pstab = (short *) filebase; /* point size table */ 624*30594Ssam chtab = pstab + nsizes + 1; /* char index table */ 625*30594Ssam chname = (char *) (chtab + dev.nchtab); /* char name table */ 626*30594Ssam p = chname + dev.lchname; /* end of char name table */ 627*30594Ssam /* parse the preloaded font tables */ 628*30594Ssam for (i = 1; i <= nfonts; i++) { 629*30594Ssam fontdelta[i] = 0; 630*30594Ssam fontbase[i] = (struct font *) p; 631*30594Ssam nw = *p & BMASK; /* number of width entries */ 632*30594Ssam if ((smnt == 0) && (fontbase[i]->specfont == 1)) 633*30594Ssam smnt = i; /* first special font */ 634*30594Ssam p += sizeof (struct font); /* skip header */ 635*30594Ssam widthtab[i] = p; /* width table */ 636*30594Ssam /* kern table is next */ 637*30594Ssam codetab[i] = p + 2 * nw; /* device codes */ 638*30594Ssam fitab[i] = p + 3 * nw; /* font index table */ 639*30594Ssam 640*30594Ssam p += 3 * nw + dev.nchtab + (128 - 32); /* next font */ 641*30594Ssam t_fp (i, fontbase[i]->namefont, fontbase[i]->intname); 642*30594Ssam loadpswidths (i, fontbase[i]->namefont); 643*30594Ssam sayload (i, fontbase[i]->namefont, (char *) 0); 644*30594Ssam #ifdef DEBUG 645*30594Ssam if (fdbg > 1) 646*30594Ssam fontprint (i); 647*30594Ssam #endif 648*30594Ssam } 649*30594Ssam fontdelta[0] = 0; 650*30594Ssam msize = 3*255 + dev.nchtab + (128-32) + sizeof (struct font); 651*30594Ssam fontbase[0] = (struct font *) malloc(msize); 652*30594Ssam widthtab[0] = (char *) fontbase[0] + sizeof (struct font); 653*30594Ssam fontbase[0]->nwfont = 255; 654*30594Ssam close (fin); 655*30594Ssam } 656*30594Ssam 657*30594Ssam private loadpswidths(i,name) 658*30594Ssam int i; 659*30594Ssam char *name; 660*30594Ssam { 661*30594Ssam char temp[60]; 662*30594Ssam register FILE *auxin; 663*30594Ssam register int j; 664*30594Ssam int cc, wid, funny; 665*30594Ssam 666*30594Ssam sprintf(temp, "%s/dev%s/%s.aux", ditdir, devname, name); 667*30594Ssam auxin = fopen(temp, "r"); 668*30594Ssam /* allocate table */ 669*30594Ssam if (pswidths[i] == NULL) { 670*30594Ssam pswidths[i] = (int *) malloc(256 * (sizeof (int))); 671*30594Ssam } 672*30594Ssam /* initialize to not-there */ 673*30594Ssam for (j = 0; j <= 255; pswidths[i][j++] = -1); 674*30594Ssam /* read them in */ 675*30594Ssam while (fscanf(auxin, "%d %d %d", &cc, &wid, &funny) != EOF) { 676*30594Ssam pswidths[i][cc] = wid | (funny << 12); 677*30594Ssam } 678*30594Ssam VOIDC fclose(auxin); 679*30594Ssam } 680*30594Ssam 681*30594Ssam #ifdef DEBUG 682*30594Ssam private fontprint(i) /* debugging print of font i (0,...) */ 683*30594Ssam int i; 684*30594Ssam { 685*30594Ssam int j, n; 686*30594Ssam char *p; 687*30594Ssam 688*30594Ssam printf ("font %d:\n", i); 689*30594Ssam p = (char *) fontbase[i]; 690*30594Ssam n = fontbase[i]->nwfont & BMASK; 691*30594Ssam printf ("base=0%o, nchars=%d, spec=%d, name=%s, widtab=0%o, fitab=0%o\n", 692*30594Ssam p, n, fontbase[i]->specfont, 693*30594Ssam fontbase[i]->namefont, widthtab[i], fitab[i]); 694*30594Ssam printf ("widths:\n"); 695*30594Ssam for (j = 0; j <= n; j++) { 696*30594Ssam printf (" %2d", widthtab[i][j] & BMASK); 697*30594Ssam if (j % 20 == 19) 698*30594Ssam printf ("\n"); 699*30594Ssam } 700*30594Ssam printf ("\ncodetab:\n"); 701*30594Ssam for (j = 0; j <= n; j++) { 702*30594Ssam printf (" %2d", codetab[i][j] & BMASK); 703*30594Ssam if (j % 20 == 19) 704*30594Ssam printf ("\n"); 705*30594Ssam } 706*30594Ssam printf ("\nfitab:\n"); 707*30594Ssam for (j = 0; j <= dev.nchtab + 128 - 32; j++) { 708*30594Ssam printf (" %2d", fitab[i][j] & BMASK); 709*30594Ssam if (j % 20 == 19) 710*30594Ssam printf ("\n"); 711*30594Ssam } 712*30594Ssam printf ("\n"); 713*30594Ssam } 714*30594Ssam #endif 715*30594Ssam 716*30594Ssam private loadfont(n, s, s1) /* load font info for font s on position n */ 717*30594Ssam int n; 718*30594Ssam char *s, *s1; 719*30594Ssam { 720*30594Ssam char temp[60]; 721*30594Ssam int fin, nw, norig; 722*30594Ssam int bcount; 723*30594Ssam 724*30594Ssam if (n < 0 || n > NFONT) { 725*30594Ssam fprintf(stderr,"%s: illegal fp command %d %s\n", prog, n, s); 726*30594Ssam exit(2); 727*30594Ssam } 728*30594Ssam if (strcmp(s, fontbase[n]->namefont) == 0) return; 729*30594Ssam if (fontbase[n]->namefont != 0) { 730*30594Ssam fontdelta[n] = 1; 731*30594Ssam } 732*30594Ssam if (s1 == NULL || s1[0] == '\0') { 733*30594Ssam sprintf (temp, "%s/dev%s/%s.out", ditdir, devname, s); 734*30594Ssam } 735*30594Ssam else { 736*30594Ssam sprintf (temp, "%s/%s.out", s1, s); 737*30594Ssam } 738*30594Ssam if ((fin = open (temp, 0)) < 0) { 739*30594Ssam fprintf(stderr,"%s: can't open font table %s\n", prog, temp); 740*30594Ssam pexit(prog,2); 741*30594Ssam } 742*30594Ssam norig = fontbase[n]->nwfont & BMASK; 743*30594Ssam bcount = 3 * norig + nchtab + 128 - 32 + sizeof (struct font); 744*30594Ssam VOIDC read (fin, (char *)fontbase[n], bcount); 745*30594Ssam if ((fontbase[n]->nwfont & BMASK) > norig) { 746*30594Ssam fprintf(stderr,"%s: Font %s too big for position %d\n", prog, s, n); 747*30594Ssam exit(2); 748*30594Ssam } 749*30594Ssam close (fin); 750*30594Ssam nw = fontbase[n]->nwfont & BMASK; 751*30594Ssam widthtab[n] = (char *) fontbase[n] + sizeof (struct font); 752*30594Ssam codetab[n] = (char *) widthtab[n] + 2 * nw; 753*30594Ssam fitab[n] = (char *) widthtab[n] + 3 * nw; 754*30594Ssam t_fp (n, fontbase[n]->namefont, fontbase[n]->intname); 755*30594Ssam loadpswidths (n, fontbase[n]->namefont); 756*30594Ssam sayload (n, s, s1); 757*30594Ssam fontbase[n]->nwfont = norig; /* so can later use full original size */ 758*30594Ssam #ifdef DEBUG 759*30594Ssam if (fdbg > 1) 760*30594Ssam fontprint (n); 761*30594Ssam #endif 762*30594Ssam } 763*30594Ssam 764*30594Ssam private sayload(n, s, s1) /* position n contains font s (internal s1) */ 765*30594Ssam int n; 766*30594Ssam char *s, *s1; 767*30594Ssam { 768*30594Ssam char pass[60]; 769*30594Ssam FILE *ptrfile; 770*30594Ssam char Adobefont[60]; 771*30594Ssam 772*30594Ssam if (s1 == NULL || s1[0] == '\0') { 773*30594Ssam sprintf (pass, "%s/dev%s/%s.map", ditdir, devname, s); 774*30594Ssam } 775*30594Ssam else { 776*30594Ssam sprintf (pass, "%s/%s.map", s1, s); 777*30594Ssam } 778*30594Ssam 779*30594Ssam if ((ptrfile = fopen (pass, "r")) == NULL) { 780*30594Ssam fprintf(stderr,"%s: can't open font map file %s\n", prog, pass); 781*30594Ssam pexit(prog,2); 782*30594Ssam } 783*30594Ssam 784*30594Ssam fscanf (ptrfile, "%s", Adobefont); 785*30594Ssam FlushShow(0); 786*30594Ssam printf ("%d(%s)xf %d f\n", n, Adobefont, n); 787*30594Ssam font = n; 788*30594Ssam VOIDC fclose(ptrfile); 789*30594Ssam } 790*30594Ssam 791*30594Ssam private VOID done() 792*30594Ssam { 793*30594Ssam if (tf == NULL) 794*30594Ssam exit (1); 795*30594Ssam t_reset ('s'); 796*30594Ssam exit (0); 797*30594Ssam } 798*30594Ssam 799*30594Ssam private t_init() /* "x i" - initialize device */ 800*30594Ssam { 801*30594Ssam movepending = NONE; 802*30594Ssam savex = savey = 0; 803*30594Ssam 804*30594Ssam t_size (10); /* start somewhere */ 805*30594Ssam t_slant (0); 806*30594Ssam setfont (1); /* set font */ 807*30594Ssam printf("xi\n"); 808*30594Ssam printf("%%%%EndProlog\n"); 809*30594Ssam } 810*30594Ssam 811*30594Ssam private t_push() /* begin a new block */ 812*30594Ssam { 813*30594Ssam FlushShow(1);MoveTo();DoMove(); 814*30594Ssam if (dlevel == DSTACK) { 815*30594Ssam fprintf(stderr,"%s: ditroff push/pop overflow!\n",prog); 816*30594Ssam exit(2); 817*30594Ssam } 818*30594Ssam ditstack[dlevel].hpos = hpos; 819*30594Ssam ditstack[dlevel].vpos = vpos; 820*30594Ssam ditstack[dlevel].fontsize = fontsize; 821*30594Ssam ditstack[dlevel].fontheight = fontheight; 822*30594Ssam ditstack[dlevel].fontslant = fontslant; 823*30594Ssam ditstack[dlevel].font = font; 824*30594Ssam dlevel++; 825*30594Ssam printf ("\nditpush\n"); 826*30594Ssam } 827*30594Ssam 828*30594Ssam private t_pop() /* pop to previous state */ 829*30594Ssam { 830*30594Ssam FlushShow(1);MoveTo();DoMove(); 831*30594Ssam if (dlevel == 0) { 832*30594Ssam fprintf(stderr,"%s: ditroff push/pop underflow!\n",prog); 833*30594Ssam exit(2); 834*30594Ssam } 835*30594Ssam dlevel--; 836*30594Ssam hpos = ditstack[dlevel].hpos; 837*30594Ssam vpos = ditstack[dlevel].vpos; 838*30594Ssam fontsize = ditstack[dlevel].fontsize; 839*30594Ssam fontheight = ditstack[dlevel].fontheight; 840*30594Ssam fontslant = ditstack[dlevel].fontslant; 841*30594Ssam font = ditstack[dlevel].font; 842*30594Ssam printf ("%d s %d xH %d xS %d f\n",fontsize,fontheight,fontslant,font); 843*30594Ssam startx = savex = hpos; 844*30594Ssam savey = vpos; 845*30594Ssam PSx = hpos * PSmag; 846*30594Ssam PSy = vpos * PSmag; 847*30594Ssam printf("%d %d MXY\n",savex,savey); 848*30594Ssam movepending = NONE; 849*30594Ssam printf("\nditpop\n"); 850*30594Ssam } 851*30594Ssam 852*30594Ssam private t_page(n) /* do whatever new page functions */ 853*30594Ssam { 854*30594Ssam int i; 855*30594Ssam 856*30594Ssam if (output) { 857*30594Ssam if (++scount >= spage) { 858*30594Ssam t_reset ('p'); 859*30594Ssam scount = 0; 860*30594Ssam } 861*30594Ssam } 862*30594Ssam output = 1; 863*30594Ssam FlushShow(0); 864*30594Ssam if (!firstpage) { 865*30594Ssam printf("\n%d p",n); 866*30594Ssam } 867*30594Ssam firstpage = FALSE; 868*30594Ssam printf ("\n%%%%Page: %d %d\n", n, ++pageno, n); 869*30594Ssam for (i = 0; i <= nfonts; i++) { 870*30594Ssam if (fontdelta[i] != 0) { 871*30594Ssam sayload (i, fontname[i].name, (char *) 0); 872*30594Ssam } 873*30594Ssam } 874*30594Ssam vpos = 0; 875*30594Ssam PSy = 0; 876*30594Ssam printf ("%d s %d xH %d xS %d f\n",fontsize,fontheight,fontslant,font); 877*30594Ssam if (nolist == 0) 878*30594Ssam return; 879*30594Ssam output = 0; 880*30594Ssam for (i = 0; i < nolist; i += 2) 881*30594Ssam if (n >= olist[i] && n <= olist[i + 1]) { 882*30594Ssam output = 1; 883*30594Ssam break; 884*30594Ssam } 885*30594Ssam } 886*30594Ssam 887*30594Ssam private t_size(n) /* convert integer to internal size number*/ 888*30594Ssam int n; 889*30594Ssam { 890*30594Ssam FlushShow(1); 891*30594Ssam if (fontsize != n) { 892*30594Ssam fontsize = n; 893*30594Ssam printf("%d s\n",fontsize); 894*30594Ssam } 895*30594Ssam } 896*30594Ssam 897*30594Ssam private t_charht(n) /* set character height to n */ 898*30594Ssam int n; 899*30594Ssam { 900*30594Ssam FlushShow(1); 901*30594Ssam if (fontheight != n) { 902*30594Ssam fontheight = n; 903*30594Ssam printf("%d xH\n",fontheight); 904*30594Ssam } 905*30594Ssam } 906*30594Ssam 907*30594Ssam private t_slant(n) /* set slant to n */ 908*30594Ssam int n; 909*30594Ssam { 910*30594Ssam FlushShow(1); 911*30594Ssam if (fontslant != n) { 912*30594Ssam fontslant = n; 913*30594Ssam printf("%d xS\n",fontslant); 914*30594Ssam } 915*30594Ssam } 916*30594Ssam 917*30594Ssam private t_font(s) /* convert string to internal font number */ 918*30594Ssam char *s; 919*30594Ssam { 920*30594Ssam int n; 921*30594Ssam 922*30594Ssam n = atoi (s); 923*30594Ssam if (n < 0 || n > nfonts) n = 1; 924*30594Ssam return (n); 925*30594Ssam } 926*30594Ssam 927*30594Ssam private t_text(s) /* print string s as text??? */ 928*30594Ssam char *s; 929*30594Ssam { 930*30594Ssam fprintf(stderr,"%s: ditroff t <%s> unimplemented!\n",prog,s); 931*30594Ssam } 932*30594Ssam 933*30594Ssam private t_reset(c) 934*30594Ssam { 935*30594Ssam output = 1; /* by God */ 936*30594Ssam if (c == 'p') { 937*30594Ssam printf ("\nxp\n"); 938*30594Ssam } 939*30594Ssam else { 940*30594Ssam if (!stopped) 941*30594Ssam printf ("\nxs\n"); 942*30594Ssam stopped = 1; 943*30594Ssam } 944*30594Ssam fflush (tf); 945*30594Ssam } 946*30594Ssam 947*30594Ssam private t_res(res, minh, minv) 948*30594Ssam int res, minh, minv; 949*30594Ssam { 950*30594Ssam resolution = res; 951*30594Ssam minhoriz = minh; 952*30594Ssam minvert = minv; 953*30594Ssam printf ("%d %d %d xr\n", res, minh, minv); 954*30594Ssam } 955*30594Ssam 956*30594Ssam private t_trailer() 957*30594Ssam { 958*30594Ssam FlushShow(0); 959*30594Ssam printf("\n%d p",pageno); 960*30594Ssam printf("\n%%%%Trailer\n"); 961*30594Ssam printf("xt\n"); 962*30594Ssam } 963*30594Ssam 964*30594Ssam private put1s(s) /* s is a funny char name */ 965*30594Ssam char *s; 966*30594Ssam { 967*30594Ssam int i; 968*30594Ssam 969*30594Ssam if (!output) return; 970*30594Ssam debugp(("%s ", s)); 971*30594Ssam 972*30594Ssam /* search for s in the funny char name table */ 973*30594Ssam for (i = 0; i < nchtab; i++) { 974*30594Ssam if (strcmp(&chname[chtab[i]], s) == 0) break; 975*30594Ssam } 976*30594Ssam 977*30594Ssam if (i < nchtab) { 978*30594Ssam put1(i + 128, s); 979*30594Ssam } 980*30594Ssam else { 981*30594Ssam debugp(("not found ")); 982*30594Ssam putnf (0, s); 983*30594Ssam } 984*30594Ssam } 985*30594Ssam 986*30594Ssam #define needsescape(c) ((c=='\\') || (c=='(') || (c==')')) 987*30594Ssam 988*30594Ssam private put1(c, s) /* output char c */ 989*30594Ssam int c; 990*30594Ssam char *s; 991*30594Ssam { 992*30594Ssam char *pw; 993*30594Ssam register char *p; 994*30594Ssam register int i, k; 995*30594Ssam register int cc; 996*30594Ssam int ofont, code; 997*30594Ssam int psinfo, pswid, tw; 998*30594Ssam 999*30594Ssam if (!output) return; 1000*30594Ssam if (c == 32) { 1001*30594Ssam thisw = 0; 1002*30594Ssam FlushShow(0); 1003*30594Ssam return; 1004*30594Ssam } 1005*30594Ssam if (c < 32) { 1006*30594Ssam debugp(("non-exist 0%o\n",c)); 1007*30594Ssam return; 1008*30594Ssam } 1009*30594Ssam 1010*30594Ssam c -= 32; /* offset char code */ 1011*30594Ssam k = ofont = pfont = font; 1012*30594Ssam if (onspecial) pfont = prevfont; 1013*30594Ssam 1014*30594Ssam if ((i = (fitab[pfont][c] & BMASK)) != 0) {/* char on this font */ 1015*30594Ssam p = codetab[pfont]; 1016*30594Ssam pw = widthtab[pfont]; 1017*30594Ssam if (onspecial) { 1018*30594Ssam setfont(prevfont); 1019*30594Ssam thisw = 0; 1020*30594Ssam onspecial = 0; 1021*30594Ssam } 1022*30594Ssam } 1023*30594Ssam else if (smnt > 0) { /* on special (we hope) */ 1024*30594Ssam for (k = smnt; k <= nfonts; k += 1) 1025*30594Ssam if ((i = (fitab[k][c] & BMASK)) != 0) { 1026*30594Ssam p = codetab[k]; 1027*30594Ssam pw = widthtab[k]; 1028*30594Ssam prevfont = pfont; 1029*30594Ssam if (onspecial && (k == specfont)) break; 1030*30594Ssam setfont (k); 1031*30594Ssam thisw = 0; 1032*30594Ssam onspecial = 1; 1033*30594Ssam specfont = k; 1034*30594Ssam break; 1035*30594Ssam } 1036*30594Ssam } 1037*30594Ssam if ((i == 0) || (k > nfonts) || ((code = p[i] & BMASK) == 0)) { 1038*30594Ssam debugp(("not found 0%o\n", c+32)); 1039*30594Ssam putnf (c + 32, s); 1040*30594Ssam return; 1041*30594Ssam } 1042*30594Ssam /* when we get here, 1043*30594Ssam * c == biased character code 1044*30594Ssam * k == font number 1045*30594Ssam * i == index into codetab and widthtab for this character 1046*30594Ssam * p == codetab for this font 1047*30594Ssam * pw == width tab for this font 1048*30594Ssam * code == character code for this char 1049*30594Ssam */ 1050*30594Ssam 1051*30594Ssam cc = c + 32; 1052*30594Ssam debugp(((isascii(cc) && isprint(cc)) ? "%c %d\n":"%03o %d\n", 1053*30594Ssam cc, code)); 1054*30594Ssam psinfo = pswidths[font][code]; /* PS specific char info */ 1055*30594Ssam pswid = psinfo & PSWID; /* PS character width */ 1056*30594Ssam thisw = pw[i] & BMASK; /* troff char width */ 1057*30594Ssam tw = thisw = (thisw * fontsize + dev.unitwidth/2) / dev.unitwidth; 1058*30594Ssam 1059*30594Ssam if ((psinfo & ISPSPROC) && (psinfo != -1)) { 1060*30594Ssam /* character is implemented by a PostScript proc */ 1061*30594Ssam showspecial(s, code, pswid); 1062*30594Ssam if (pswid > 0) { 1063*30594Ssam PSx += PSscale(pswid * fontsize * dres); 1064*30594Ssam } 1065*30594Ssam thisw = 0; 1066*30594Ssam } 1067*30594Ssam else { 1068*30594Ssam showchar(code); 1069*30594Ssam if (pswid > 0) { 1070*30594Ssam PSshowlen += PSscale(pswid * fontsize * dres); 1071*30594Ssam } 1072*30594Ssam } 1073*30594Ssam 1074*30594Ssam /* 1075*30594Ssam if (font != ofont) { 1076*30594Ssam setfont(ofont); 1077*30594Ssam startx = hpos + tw; 1078*30594Ssam thisw = 0; 1079*30594Ssam lastcmd = FNT; 1080*30594Ssam } 1081*30594Ssam */ 1082*30594Ssam debugp(("...width (%d)\n", pw[i]&BMASK)); 1083*30594Ssam } 1084*30594Ssam 1085*30594Ssam 1086*30594Ssam private putnf(c, s) /* note that a character wasnt found */ 1087*30594Ssam int c; 1088*30594Ssam char *s; 1089*30594Ssam { 1090*30594Ssam 1091*30594Ssam FlushShow(0); 1092*30594Ssam thisw = 0; 1093*30594Ssam if ((s == NULL) || (*s == '\0')) printf("(\%3o)cb\n", c); 1094*30594Ssam else if ((strcmp(s, "\\|") == 0) || (strcmp(s, "\\^") == 0) 1095*30594Ssam || (strcmp (s, "\\&") == 0)) 1096*30594Ssam return; 1097*30594Ssam else 1098*30594Ssam printf("(%s)cb\n", s); 1099*30594Ssam } 1100*30594Ssam 1101*30594Ssam 1102*30594Ssam private t_fp(n, s, si) /* font position n now contains font s, intname si */ 1103*30594Ssam int n; /* position */ 1104*30594Ssam char *s; /* font (ditname) */ 1105*30594Ssam char *si; /* font (intname = number) */ 1106*30594Ssam { 1107*30594Ssam fontname[n].name = s; 1108*30594Ssam fontname[n].number = atoi (si); 1109*30594Ssam } 1110*30594Ssam 1111*30594Ssam private setfont(n) /* set font to n */ 1112*30594Ssam int n; 1113*30594Ssam { 1114*30594Ssam FlushShow(1); 1115*30594Ssam 1116*30594Ssam if (n < 0 || n > NFONT) { 1117*30594Ssam fprintf(stderr,"%s: illegal font %d\n", prog,n); 1118*30594Ssam } 1119*30594Ssam if (font != n) { 1120*30594Ssam font = n; 1121*30594Ssam printf("%d f\n",font); 1122*30594Ssam } 1123*30594Ssam onspecial = 0; 1124*30594Ssam } 1125*30594Ssam 1126*30594Ssam private drawline(dx, dy) /* draw line from here to dx, dy */ 1127*30594Ssam int dx, dy; 1128*30594Ssam { 1129*30594Ssam FlushShow(0); MoveTo(); DoMove(); 1130*30594Ssam printf("%d %d Dl\n", dx, dy); 1131*30594Ssam hpos += dx; 1132*30594Ssam PSx = hpos * PSmag; 1133*30594Ssam vpos += dy; 1134*30594Ssam PSy = vpos * PSmag; 1135*30594Ssam } 1136*30594Ssam 1137*30594Ssam private drawwig(s) /* draw wiggly line */ 1138*30594Ssam char *s; 1139*30594Ssam { 1140*30594Ssam FlushShow(0); MoveTo(); DoMove(); 1141*30594Ssam printf("D~ %s D~~\n",s); 1142*30594Ssam } 1143*30594Ssam 1144*30594Ssam private drawcirc(d) 1145*30594Ssam int d; 1146*30594Ssam { 1147*30594Ssam FlushShow(0); MoveTo(); DoMove(); 1148*30594Ssam printf("%d Dc\n",d); 1149*30594Ssam } 1150*30594Ssam 1151*30594Ssam private drawarc(dx1, dy1, dx2, dy2) 1152*30594Ssam int dx1, dy1, dx2, dy2; 1153*30594Ssam { 1154*30594Ssam FlushShow(0); MoveTo(); DoMove(); 1155*30594Ssam printf("%d %d %d %d Da\n", dx1, dy1, dx2, dy2); 1156*30594Ssam hpos += dx1 + dx2; 1157*30594Ssam PSx = hpos * PSmag; 1158*30594Ssam vpos += dy1 + dy2; 1159*30594Ssam PSy = vpos * PSmag; 1160*30594Ssam } 1161*30594Ssam 1162*30594Ssam private drawellip(a, b) 1163*30594Ssam int a, b; 1164*30594Ssam { 1165*30594Ssam FlushShow(0);MoveTo();DoMove(); 1166*30594Ssam printf("%d %d De\n",a,b); 1167*30594Ssam } 1168*30594Ssam 1169*30594Ssam private hmot(a) /* relative horizontal motion */ 1170*30594Ssam int a; 1171*30594Ssam { 1172*30594Ssam register int aa; 1173*30594Ssam aa = abs(a); 1174*30594Ssam if ((aa < 8) || (aa > (10 * thisw)) || (a >= 100) 1175*30594Ssam || ((thisw != 0) && (abs(thisw - a) > 4))) { 1176*30594Ssam FlushShow(1); 1177*30594Ssam } 1178*30594Ssam hpos += a; 1179*30594Ssam if (lastcmd != CPUT) startx = hpos; 1180*30594Ssam } 1181*30594Ssam 1182*30594Ssam private hgoto(a) /* absolute horizontal motion */ 1183*30594Ssam int a; 1184*30594Ssam { 1185*30594Ssam FlushShow(1); 1186*30594Ssam startx = hpos = a; 1187*30594Ssam thisw = 0; 1188*30594Ssam } 1189*30594Ssam 1190*30594Ssam private vmot(a) /* relative vertical motion */ 1191*30594Ssam int a; 1192*30594Ssam { 1193*30594Ssam FlushShow(1); 1194*30594Ssam vpos += a; 1195*30594Ssam thisw = 0; 1196*30594Ssam } 1197*30594Ssam 1198*30594Ssam private vgoto(a) /* absolute vertical motion */ 1199*30594Ssam int a; 1200*30594Ssam { 1201*30594Ssam FlushShow(1); 1202*30594Ssam vpos = a; 1203*30594Ssam thisw = 0; 1204*30594Ssam } 1205*30594Ssam 1206*30594Ssam private showspecial(s,cc,wid) 1207*30594Ssam char *s; 1208*30594Ssam int cc; 1209*30594Ssam int wid; 1210*30594Ssam { 1211*30594Ssam char *sp; 1212*30594Ssam 1213*30594Ssam FlushShow(0); 1214*30594Ssam MoveTo(); 1215*30594Ssam DoMove(); 1216*30594Ssam putchar('('); 1217*30594Ssam for (sp = s; *sp != '\0'; sp++) { 1218*30594Ssam if (needsescape(*sp)) { 1219*30594Ssam putchar('\\'); 1220*30594Ssam } 1221*30594Ssam putchar(*sp); 1222*30594Ssam } 1223*30594Ssam printf(")%d %d oc\n",cc,wid); 1224*30594Ssam } 1225*30594Ssam 1226*30594Ssam private showchar(c) 1227*30594Ssam int c; 1228*30594Ssam { 1229*30594Ssam if (showind == 0) {MoveTo();} 1230*30594Ssam else if ((vpos * PSmag) != PSy) { 1231*30594Ssam FlushShow(0); 1232*30594Ssam MoveTo(); 1233*30594Ssam } 1234*30594Ssam if (showind >= SHOWSIZE) FlushShow(0); 1235*30594Ssam if (isascii(c) && isprint(c)) { 1236*30594Ssam switch (c) { 1237*30594Ssam case '\\': case '(': case ')': 1238*30594Ssam showbuf[showind++] = '\\'; 1239*30594Ssam /* fall through */ 1240*30594Ssam 1241*30594Ssam default: 1242*30594Ssam showbuf[showind++] = c; 1243*30594Ssam } 1244*30594Ssam } 1245*30594Ssam else { 1246*30594Ssam showbuf[showind++] = '\\'; 1247*30594Ssam showbuf[showind++] = ((c>>6)&03) + '0'; 1248*30594Ssam showbuf[showind++] = ((c>>3)&07) + '0'; 1249*30594Ssam showbuf[showind++] = (c&07) + '0'; 1250*30594Ssam } 1251*30594Ssam showbuf[showind] = '\0'; 1252*30594Ssam nshow++; 1253*30594Ssam } 1254*30594Ssam 1255*30594Ssam private MoveTo() { 1256*30594Ssam int x, y; 1257*30594Ssam x = hpos * PSmag; 1258*30594Ssam y = vpos * PSmag; 1259*30594Ssam 1260*30594Ssam if (x != PSx) { 1261*30594Ssam startx = savex = hpos; 1262*30594Ssam PSx = x; 1263*30594Ssam movepending |= XMOVE; 1264*30594Ssam } 1265*30594Ssam if (y != PSy) { 1266*30594Ssam savey = vpos; 1267*30594Ssam PSy = y; 1268*30594Ssam movepending |= YMOVE; 1269*30594Ssam } 1270*30594Ssam } 1271*30594Ssam 1272*30594Ssam private FlushMove() { 1273*30594Ssam switch (movepending) { 1274*30594Ssam case NONE: 1275*30594Ssam break; 1276*30594Ssam case XMOVE: 1277*30594Ssam printf("%d",savex); 1278*30594Ssam break; 1279*30594Ssam case YMOVE: 1280*30594Ssam printf("%d",savey); 1281*30594Ssam break; 1282*30594Ssam case XYMOVE: 1283*30594Ssam printf("%d %d",savex,savey); 1284*30594Ssam break; 1285*30594Ssam default: 1286*30594Ssam fprintf(stderr,"%s: invalid move code %d\n",prog, movepending); 1287*30594Ssam exit(2); 1288*30594Ssam } 1289*30594Ssam } 1290*30594Ssam 1291*30594Ssam private char *movecmds[] = { 1292*30594Ssam "MX","MY","MXY" 1293*30594Ssam }; 1294*30594Ssam 1295*30594Ssam private DoMove() { 1296*30594Ssam FlushMove(); 1297*30594Ssam if (movepending != NONE) { 1298*30594Ssam printf(" %s\n",movecmds[movepending-1]); 1299*30594Ssam movepending = NONE; 1300*30594Ssam } 1301*30594Ssam } 1302*30594Ssam 1303*30594Ssam private char showops[] = "SXYN"; 1304*30594Ssam 1305*30594Ssam private FlushShow(t) int t; { 1306*30594Ssam long err, tlen; 1307*30594Ssam float cerror; 1308*30594Ssam 1309*30594Ssam if (showind == 0) {thisw = 0; return;} 1310*30594Ssam if (movepending != NONE) { 1311*30594Ssam FlushMove(); 1312*30594Ssam } 1313*30594Ssam tlen = hpos - startx; 1314*30594Ssam if (lastcmd == CPUT) tlen += thisw; 1315*30594Ssam err = tlen * PSmag - PSshowlen; 1316*30594Ssam if ((nshow != 1) && (abs(err) > ErrorTolerance)) { 1317*30594Ssam cerror = ((float) err) / ((nshow - 1) * PSmag); 1318*30594Ssam #ifdef DEBUG 1319*30594Ssam fprintf(stderr,"F%d lc %d thisw %d ",t,lastcmd,thisw); 1320*30594Ssam fprintf(stderr,"x %ld h %ld tn %ld %ld ", 1321*30594Ssam startx, hpos, tlen*PSmag,PSshowlen); 1322*30594Ssam fprintf(stderr,"error %d %.4f %s\n",nshow,cerror,showbuf); 1323*30594Ssam fflush(stderr); 1324*30594Ssam #endif 1325*30594Ssam printf(" %.4f(%s)A%c\n", cerror, showbuf, showops[movepending]); 1326*30594Ssam } 1327*30594Ssam else { 1328*30594Ssam printf("(%s)%c\n", showbuf, showops[movepending]); 1329*30594Ssam } 1330*30594Ssam 1331*30594Ssam showind = 0; 1332*30594Ssam nshow = 0; 1333*30594Ssam showbuf[showind] = '\0'; 1334*30594Ssam PSx += PSshowlen; 1335*30594Ssam PSshowlen = 0; 1336*30594Ssam startx = hpos; 1337*30594Ssam if (lastcmd == CPUT) startx += thisw; 1338*30594Ssam thisw = 0; 1339*30594Ssam movepending = NONE; 1340*30594Ssam } 1341