Annotation of researchv10no/cmd/post.src/post.src.cpio, revision 1.1
1.1 ! root 1: 0707070014231030370407550057030000000000400277220522634650100001100000000000post.src 0707070014230361420407550057030057030000021040140522633073100002000000000000post.src/common 0707070014230361431006440057030057030000011040300522627500500003200000007173post.src/common/request.c /*
! 2: *
! 3: * Things used to handle special requests (eg. manual feed) globally or on a per
! 4: * page basis. Requests are passed through to the translator using the -R option.
! 5: * The argument to -R can be "request", "request:page", or "request:page:file".
! 6: * If page is omitted (as in the first form) or set to 0 request will be applied
! 7: * to the global environment. In all other cases it applies only to the selected
! 8: * page. If a file is given, page must be supplied, and the lookup is in that file
! 9: * rather than *requestfile.
! 10: *
! 11: */
! 12:
! 13: #include <stdio.h>
! 14:
! 15: #include "gen.h" /* general purpose definitions */
! 16: #include "request.h" /* a few special definitions */
! 17: #include "path.h" /* for the default request file */
! 18:
! 19: Request request[MAXREQUEST]; /* next page or global request */
! 20: int nextreq = 0; /* goes in request[nextreq] */
! 21: char *requestfile = REQUESTFILE; /* default lookup file */
! 22:
! 23: /*****************************************************************************/
! 24:
! 25: saverequest(want)
! 26:
! 27: char *want; /* grab code for this stuff */
! 28:
! 29: {
! 30:
! 31: char *page; /* and save it for this page */
! 32: char *strtok();
! 33:
! 34: /*
! 35: *
! 36: * Save the request until we get to appropriate page - don't even bother with
! 37: * the lookup right now. Format of *want string is "request", "request:page", or
! 38: * "request:page:file", and we assume we can change the string here as needed.
! 39: * If page is omitted or given as 0 the request will be done globally. If *want
! 40: * includes a file, request and page must also be given, and in that case *file
! 41: * will be used for the lookup.
! 42: *
! 43: */
! 44:
! 45: if ( nextreq < MAXREQUEST ) {
! 46: request[nextreq].want = strtok(want, ": ");
! 47: if ( (page = strtok(NULL, ": ")) == NULL )
! 48: request[nextreq].page = 0;
! 49: else request[nextreq].page = atoi(page);
! 50: if ( (request[nextreq].file = strtok(NULL, ": ")) == NULL )
! 51: request[nextreq].file = requestfile;
! 52: nextreq++;
! 53: } else error(NON_FATAL, "too many requests - ignoring %s", want);
! 54:
! 55: } /* End of saverequest */
! 56:
! 57: /*****************************************************************************/
! 58:
! 59: writerequest(page, fp_out)
! 60:
! 61: int page; /* write everything for this page */
! 62: FILE *fp_out; /* to this file */
! 63:
! 64: {
! 65:
! 66: int i; /* loop index */
! 67:
! 68: /*
! 69: *
! 70: * Writes out all the requests that have been saved for page. Page 0 refers to
! 71: * the global environment and is done during initial setup.
! 72: *
! 73: */
! 74:
! 75: for ( i = 0; i < nextreq; i++ )
! 76: if ( request[i].page == page )
! 77: dumprequest(request[i].want, request[i].file, fp_out);
! 78:
! 79: } /* End of writerequest */
! 80:
! 81: /*****************************************************************************/
! 82:
! 83: dumprequest(want, file, fp_out)
! 84:
! 85: char *want; /* look for this string */
! 86: char *file; /* in this file */
! 87: FILE *fp_out; /* and write the value out here */
! 88:
! 89: {
! 90:
! 91: char buf[100]; /* line buffer for reading *file */
! 92: FILE *fp_in;
! 93:
! 94: /*
! 95: *
! 96: * Looks for *want in the request file and if it's found the associated value
! 97: * is copied to the output file. Keywords (ie. the *want strings) begin an @ in
! 98: * the first column of file, while the values (ie. the stuff that's copied to
! 99: * the output file) starts on the next line and extends to the next keyword or
! 100: * to the end of file.
! 101: *
! 102: */
! 103:
! 104: if ( (fp_in = fopen(file, "r")) != NULL ) {
! 105: while ( fgets(buf, sizeof(buf), fp_in) != NULL )
! 106: if ( buf[0] == '@' && strncmp(want, &buf[1], strlen(want)) == 0 )
! 107: while ( fgets(buf, sizeof(buf), fp_in) != NULL )
! 108: if ( buf[0] == '#' || buf[0] == '%' )
! 109: continue;
! 110: else if ( buf[0] != '@' )
! 111: fprintf(fp_out, "%s", buf);
! 112: else break;
! 113: fclose(fp_in);
! 114: } /* End if */
! 115:
! 116: } /* End of dumprequest */
! 117:
! 118: /*****************************************************************************/
! 119:
! 120: 0707070014230361441006440057030057030000011040150522627500500003200000001035post.src/common/tempnam.c #include <stdio.h>
! 121: #include <errno.h>
! 122:
! 123: #if defined(V9) || defined(BSD4_2)
! 124: char *tempnam(dir, pfx)
! 125: char *dir, *pfx;
! 126: {
! 127: int pid;
! 128: unsigned int len;
! 129: char *tnm, *malloc();
! 130: static int seq = 0;
! 131:
! 132: pid = getpid();
! 133: len = strlen(dir) + strlen(pfx) + 10;
! 134: if ((tnm = malloc(len)) != NULL) {
! 135: sprintf(tnm, "%s", dir);
! 136: if (access(tnm, 7) == -1)
! 137: return(NULL);
! 138: do {
! 139: sprintf(tnm, "%s/%s%d%d", dir, pfx, pid, seq++);
! 140: errno = 0;
! 141: if (access(tnm, 7) == -1)
! 142: if (errno == ENOENT)
! 143: return(tnm);
! 144: } while (1);
! 145: }
! 146: return(tnm);
! 147: }
! 148: #endif
! 149: 0707070014230361451006440057030057030000011040160522627500500003200000001432post.src/common/request.h /*
! 150: *
! 151: * Things used to handle special PostScript requests (like manual feed) globally
! 152: * or on a per page basis. All the translators I've supplied accept the -R option
! 153: * that can be used to insert special PostScript code before the global setup is
! 154: * done, or at the start of named pages. The argument to the -R option is a string
! 155: * that can be "request", "request:page", or "request:page:file". If page isn't
! 156: * given (as in the first form) or if it's 0 in the last two, the request applies
! 157: * to the global environment, otherwise request holds only for the named page.
! 158: * If a file name is given a page number must be supplied, and in that case the
! 159: * request will be looked up in that file.
! 160: *
! 161: */
! 162:
! 163: #define MAXREQUEST 30
! 164:
! 165: typedef struct {
! 166: char *want;
! 167: int page;
! 168: char *file;
! 169: } Request;
! 170:
! 171: 0707070014230361461006440057030057030000011041310522633073100002700000002213post.src/common/path.h /*
! 172: *
! 173: * pathname definitions for important files and directories.
! 174: *
! 175: */
! 176:
! 177: #define DPOST "/usr/lib/postscript/dpost.ps"
! 178: #define POSTBGI "/usr/lib/postscript/postbgi.ps"
! 179: #define POSTDAISY "/usr/lib/postscript/postdaisy.ps"
! 180: #define POSTDMD "/usr/lib/postscript/postdmd.ps"
! 181: #define POSTMD "/usr/lib/postscript/postmd.ps"
! 182: #define POSTPLOT "/usr/lib/postscript/postplot.ps"
! 183: #define POSTPRINT "/usr/lib/postscript/postprint.ps"
! 184: #define POSTNPRINT "/usr/lib/postscript/postnprint.ps"
! 185: #define POSTTEK "/usr/lib/postscript/posttek.ps"
! 186: #define POSTGIF "/usr/lib/postscript/postgif.ps"
! 187:
! 188: #define BASELINE "/usr/lib/postscript/baseline.ps"
! 189: #define COLOR "/usr/lib/postscript/color.ps"
! 190: #define DRAW "/usr/lib/postscript/draw.ps"
! 191: #define FORMFILE "/usr/lib/postscript/forms.ps"
! 192: #define SHADEFILE "/usr/lib/postscript/shade.ps"
! 193: #define KERNING "/usr/lib/postscript/kerning.ps"
! 194: #define REQUESTFILE "/usr/lib/postscript/ps.requests"
! 195: #define ROUNDPAGE "/usr/lib/postscript/roundpage.ps"
! 196:
! 197: #define ENCODINGDIR "/usr/lib/postscript"
! 198: #define HOSTDIR "/usr/lib/font/postscript"
! 199: #define FONTDIR "/usr/lib/font"
! 200: #define POSTLIBDIR "/usr/lib/postscript"
! 201: #define TEMPDIR "/tmp"
! 202:
! 203: 0707070014230357551006400057030057030000011024350522633073100002600000002157post.src/common/gen.h /*
! 204: *
! 205: * A few definitions that shouldn't have to change. Used by most programs in
! 206: * this package.
! 207: *
! 208: */
! 209:
! 210: #define PROGRAMVERSION "3.3.2"
! 211:
! 212: #define NON_FATAL 0
! 213: #define FATAL 1
! 214: #define USER_FATAL 2
! 215:
! 216: #define OFF 0
! 217: #define ON 1
! 218:
! 219: #define FALSE 0
! 220: #define TRUE 1
! 221:
! 222: #define BYTE 8
! 223: #define BMASK 0377
! 224:
! 225: #define POINTS 72.3
! 226:
! 227: #ifndef PI
! 228: #define PI 3.141592654
! 229: #endif
! 230:
! 231: #define ONEBYTE 0
! 232: #define UTFENCODING 1
! 233:
! 234: #define READING ONEBYTE
! 235: #define WRITING ONEBYTE
! 236:
! 237: /*
! 238: *
! 239: * DOROUND controls whether some translators include file ROUNDPAGE (path.h)
! 240: * after the prologue. Used to round page dimensions obtained from the clippath
! 241: * to know paper sizes. Enabled by setting DOROUND to TRUE (or 1).
! 242: *
! 243: */
! 244:
! 245: #define DOROUND TRUE
! 246:
! 247: /*
! 248: *
! 249: * Default resolution and the height and width of a page (in case we need to get
! 250: * to upper left corner) - only used in BoundingBox calculations!!
! 251: *
! 252: */
! 253:
! 254: #define DEFAULT_RES 72
! 255: #define PAGEHEIGHT 11.0 * DEFAULT_RES
! 256: #define PAGEWIDTH 8.5 * DEFAULT_RES
! 257:
! 258: /*
! 259: *
! 260: * Simple macros.
! 261: *
! 262: */
! 263:
! 264: #define ABS(A) ((A) >= 0 ? (A) : -(A))
! 265: #define MIN(A, B) ((A) < (B) ? (A) : (B))
! 266: #define MAX(A, B) ((A) > (B) ? (A) : (B))
! 267:
! 268: 0707070014230361501006440057030057030000011040500522627500500002700000007564post.src/common/misc.c /*
! 269: *
! 270: * General purpose routines.
! 271: *
! 272: */
! 273:
! 274: #include <stdio.h>
! 275: #include <ctype.h>
! 276: #include <fcntl.h>
! 277:
! 278: #include "gen.h"
! 279: #include "ext.h"
! 280: #include "path.h"
! 281:
! 282: int nolist = 0; /* number of specified ranges */
! 283: int olist[50]; /* processing range pairs */
! 284:
! 285: /*****************************************************************************/
! 286:
! 287: out_list(str)
! 288:
! 289: char *str;
! 290:
! 291: {
! 292:
! 293: int start, stop;
! 294:
! 295: /*
! 296: *
! 297: * Grab page ranges from str, save them in olist[], and update the nolist
! 298: * count. Range syntax matches nroff/troff syntax.
! 299: *
! 300: */
! 301:
! 302: while ( *str && nolist < sizeof(olist) - 2 ) {
! 303: start = stop = str_convert(&str, 0);
! 304:
! 305: if ( *str == '-' && *str++ )
! 306: stop = str_convert(&str, 9999);
! 307:
! 308: if ( start > stop )
! 309: error(FATAL, "illegal range %d-%d", start, stop);
! 310:
! 311: olist[nolist++] = start;
! 312: olist[nolist++] = stop;
! 313:
! 314: if ( *str != '\0' ) str++;
! 315: } /* End while */
! 316:
! 317: olist[nolist] = 0;
! 318:
! 319: } /* End of out_list */
! 320:
! 321: /*****************************************************************************/
! 322:
! 323: in_olist(num)
! 324:
! 325: int num;
! 326:
! 327: {
! 328:
! 329: int i;
! 330:
! 331: /*
! 332: *
! 333: * Return ON if num is in the current page range list. Print everything if
! 334: * there's no list.
! 335: *
! 336: */
! 337: if ( nolist == 0 )
! 338: return(ON);
! 339:
! 340: for ( i = 0; i < nolist; i += 2 )
! 341: if ( num >= olist[i] && num <= olist[i+1] )
! 342: return(ON);
! 343:
! 344: return(OFF);
! 345:
! 346: } /* End of in_olist */
! 347:
! 348: /*****************************************************************************/
! 349:
! 350: setencoding(name)
! 351:
! 352: char *name;
! 353:
! 354: {
! 355:
! 356: char path[150];
! 357:
! 358: /*
! 359: *
! 360: * Include the font encoding file selected by name. It's a full pathname if
! 361: * it begins with /, otherwise append suffix ".enc" and look for the file in
! 362: * ENCODINGDIR. Missing files are silently ignored.
! 363: *
! 364: */
! 365:
! 366: if ( name == NULL )
! 367: name = "Default";
! 368:
! 369: if ( *name == '/' )
! 370: strcpy(path, name);
! 371: else sprintf(path, "%s/%s.enc", ENCODINGDIR, name);
! 372:
! 373: if ( cat(path) == TRUE )
! 374: writing = strncmp(name, "UTF", 3) == 0;
! 375:
! 376: } /* End of setencoding */
! 377:
! 378: /*****************************************************************************/
! 379:
! 380: cat(file)
! 381:
! 382: char *file;
! 383:
! 384: {
! 385:
! 386: int fd_in;
! 387: int fd_out;
! 388: char buf[512];
! 389: int count;
! 390:
! 391: /*
! 392: *
! 393: * Copy *file to stdout. Return FALSE is there was a problem.
! 394: *
! 395: */
! 396:
! 397: fflush(stdout);
! 398:
! 399: if ( (fd_in = open(file, O_RDONLY)) == -1 )
! 400: return(FALSE);
! 401:
! 402: fd_out = fileno(stdout);
! 403: while ( (count = read(fd_in, buf, sizeof(buf))) > 0 )
! 404: write(fd_out, buf, count);
! 405:
! 406: close(fd_in);
! 407:
! 408: return(TRUE);
! 409:
! 410: } /* End of cat */
! 411:
! 412: /*****************************************************************************/
! 413:
! 414: str_convert(str, err)
! 415:
! 416: char **str;
! 417: int err;
! 418:
! 419: {
! 420:
! 421: int i;
! 422:
! 423: /*
! 424: *
! 425: * Grab the next integer from **str and return its value or err if *str
! 426: * isn't an integer. *str is modified after each digit is read.
! 427: *
! 428: */
! 429:
! 430: if ( ! isdigit(**str) )
! 431: return(err);
! 432:
! 433: for ( i = 0; isdigit(**str); *str += 1 )
! 434: i = 10 * i + **str - '0';
! 435:
! 436: return(i);
! 437:
! 438: } /* End of str_convert */
! 439:
! 440: /*****************************************************************************/
! 441:
! 442: error(kind, mesg, a1, a2, a3)
! 443:
! 444: int kind;
! 445: char *mesg;
! 446: unsigned a1, a2, a3;
! 447:
! 448: {
! 449:
! 450: /*
! 451: *
! 452: * Print an error message and quit if kind is FATAL.
! 453: *
! 454: */
! 455:
! 456: if ( mesg != NULL && *mesg != '\0' ) {
! 457: fprintf(stderr, "%s: ", prog_name);
! 458: fprintf(stderr, mesg, a1, a2, a3);
! 459: if ( lineno > 0 )
! 460: fprintf(stderr, " (line %d)", lineno);
! 461: if ( position > 0 )
! 462: fprintf(stderr, " (near byte %d)", position);
! 463: putc('\n', stderr);
! 464: } /* End if */
! 465:
! 466: if ( kind == FATAL && ignore == OFF ) {
! 467: if ( temp_file != NULL )
! 468: unlink(temp_file);
! 469: exit(x_stat | 01);
! 470: } /* End if */
! 471:
! 472: } /* End of error */
! 473:
! 474: /*****************************************************************************/
! 475:
! 476: void interrupt(sig)
! 477:
! 478: int sig;
! 479:
! 480: {
! 481:
! 482: /*
! 483: *
! 484: * Signal handler for translators.
! 485: *
! 486: */
! 487:
! 488: if ( temp_file != NULL )
! 489: unlink(temp_file);
! 490:
! 491: exit(1);
! 492:
! 493: } /* End of interrupt */
! 494:
! 495: /*****************************************************************************/
! 496:
! 497: 0707070014230361511006440057030057030000011040540522627500500002600000002032post.src/common/ext.h /*
! 498: *
! 499: * External varibles - most are in glob.c.
! 500: *
! 501: */
! 502:
! 503: extern char **argv; /* global so everyone can use them */
! 504: extern int argc;
! 505:
! 506: extern int x_stat; /* program exit status */
! 507: extern int debug; /* debug flag */
! 508: extern int ignore; /* what we do with FATAL errors */
! 509:
! 510: extern long lineno; /* line number */
! 511: extern long position; /* byte position */
! 512: extern char *prog_name; /* and program name - for errors */
! 513: extern char *temp_file; /* temporary file - for some programs */
! 514: extern char *fontencoding; /* text font encoding scheme */
! 515:
! 516: extern int dobbox; /* enable BoundingBox stuff if TRUE */
! 517: extern double pageheight; /* only for BoundingBox calculations! */
! 518: extern double pagewidth;
! 519:
! 520: extern int reading; /* input */
! 521: extern int writing; /* and output encoding */
! 522:
! 523: extern char *optarg; /* for getopt() */
! 524: extern int optind;
! 525:
! 526: extern void interrupt();
! 527: extern char *malloc();
! 528: extern char *calloc();
! 529: extern char *tempnam();
! 530: extern char *strtok();
! 531: extern long ftell();
! 532: extern double atof();
! 533: extern double sqrt();
! 534: extern double atan2();
! 535:
! 536: 0707070014230361521006440057030057030000011040170522627500500002700000001461post.src/common/glob.c /*
! 537: *
! 538: * Global varibles - for PostScript translators.
! 539: *
! 540: */
! 541:
! 542: #include <stdio.h>
! 543: #include "gen.h"
! 544:
! 545: char **argv; /* global so everyone can use them */
! 546: int argc;
! 547:
! 548: int x_stat = 0; /* program exit status */
! 549: int debug = OFF; /* debug flag */
! 550: int ignore = OFF; /* what we do with FATAL errors */
! 551:
! 552: long lineno = 0; /* line number */
! 553: long position = 0; /* byte position */
! 554: char *prog_name = ""; /* and program name - for errors */
! 555: char *temp_file = NULL; /* temporary file - for some programs */
! 556: char *fontencoding = NULL; /* text font encoding scheme */
! 557:
! 558: int dobbox = FALSE; /* enable BoundingBox stuff if TRUE */
! 559: double pageheight = PAGEHEIGHT; /* only for BoundingBox calculations! */
! 560: double pagewidth = PAGEWIDTH;
! 561:
! 562: int reading = READING; /* input */
! 563: int writing = WRITING; /* and output encoding */
! 564:
! 565: 0707070014230361531006440057030057030000011040700522627500500003300000007534post.src/common/comments.h /*
! 566: *
! 567: * Currently defined file structuring comments from Adobe - plus a few others.
! 568: * Ones that end with a colon expect arguments, while those ending with a newline
! 569: * stand on their own. Truly overkill on Adobe's part and mine for including them
! 570: * all!
! 571: *
! 572: * All PostScript files should begin with a header that starts with one of the
! 573: * following comments.
! 574: *
! 575: */
! 576:
! 577: #define NONCONFORMING "%!PS\n"
! 578: #define MINCONFORMING "%!PS-Adobe-\n"
! 579: #define OLDCONFORMING "%!PS-Adobe-1.0\n"
! 580:
! 581: #define CONFORMING "%!PS-Adobe-2.0\n"
! 582: #define CONFORMINGEPS "%!PS-Adobe-2.0 EPS\n"
! 583: #define CONFORMINGQUERY "%!PS-Adobe-2.0 Query\n"
! 584: #define CONFORMINGEXITSERVER "%!PS-Adobe-2.0 ExitServer\n"
! 585:
! 586: /*
! 587: *
! 588: * Header comments - immediately follow the appropriate document classification
! 589: * comment.
! 590: *
! 591: */
! 592:
! 593: #define TITLE "%%Title:"
! 594: #define CREATOR "%%Creator:"
! 595: #define CREATIONDATE "%%CreationDate:"
! 596: #define FOR "%%For:"
! 597: #define ROUTING "%%Routing:"
! 598: #define BOUNDINGBOX "%%BoundingBox:"
! 599: #define PAGES "%%Pages:"
! 600: #define REQUIREMENTS "%%Requirements:"
! 601:
! 602: #define DOCUMENTFONTS "%%DocumentFonts:"
! 603: #define DOCUMENTNEEDEDFONTS "%%DocumentNeededFonts:"
! 604: #define DOCUMENTSUPPLIEDFONTS "%%DocumentSuppliedFonts:"
! 605: #define DOCUMENTNEEDEDPROCSETS "%%DocumentNeededProcSets:"
! 606: #define DOCUMENTSUPPLIEDPROCSETS "%%DocumentSuppliedProcSets:"
! 607: #define DOCUMENTNEEDEDFILES "%%DocumentNeededFiles:"
! 608: #define DOCUMENTSUPPLIEDFILES "%%DocumentSuppliedFiles:"
! 609: #define DOCUMENTPAPERSIZES "%%DocumentPaperSizes:"
! 610: #define DOCUMENTPAPERFORMS "%%DocumentPaperForms:"
! 611: #define DOCUMENTPAPERCOLORS "%%DocumentPaperColors:"
! 612: #define DOCUMENTPAPERWEIGHTS "%%DocumentPaperWeights:"
! 613: #define DOCUMENTPRINTERREQUIRED "%%DocumentPrinterREquired:"
! 614: #define ENDCOMMENTS "%%EndComments\n"
! 615: #define ENDPROLOG "%%EndProlog\n"
! 616:
! 617: /*
! 618: *
! 619: * Body comments - can appear anywhere in a document.
! 620: *
! 621: */
! 622:
! 623: #define BEGINSETUP "%%BeginSetup\n"
! 624: #define ENDSETUP "%%EndSetup\n"
! 625: #define BEGINDOCUMENT "%%BeginDocument:"
! 626: #define ENDDOCUMENT "%%EndDocument\n"
! 627: #define BEGINFILE "%%BeginFile:"
! 628: #define ENDFILE "%%EndFile\n"
! 629: #define BEGINPROCSET "%%BeginProcSet:"
! 630: #define ENDPROCSET "%%EndProcSet\n"
! 631: #define BEGINBINARY "%%BeginBinary:"
! 632: #define ENDBINARY "%%EndBinary\n"
! 633: #define BEGINPAPERSIZE "%%BeginePaperSize:"
! 634: #define ENDPAPERSIZE "%%EndPaperSize\n"
! 635: #define BEGINFEATURE "%%BeginFeature:"
! 636: #define ENDFEATURE "%%EndFeature\n"
! 637: #define BEGINEXITSERVER "%%BeginExitServer:"
! 638: #define ENDEXITSERVER "%%EndExitServer\n"
! 639: #define TRAILER "%%Trailer\n"
! 640:
! 641: /*
! 642: *
! 643: * Page level comments - usually will occur once per page.
! 644: *
! 645: */
! 646:
! 647: #define PAGE "%%Page:"
! 648: #define PAGEFONTS "%%PageFonts:"
! 649: #define PAGEFILES "%%PageFiles:"
! 650: #define PAGEBOUNDINGBOX "%%PageBoundingBox:"
! 651: #define BEGINPAGESETUP "%%BeginPageSetup\n"
! 652: #define BEGINOBJECT "%%BeginObject:"
! 653: #define ENDOBJECT "%%EndObject\n"
! 654:
! 655: /*
! 656: *
! 657: * Resource requirements - again can appear anywhere in a document.
! 658: *
! 659: */
! 660:
! 661: #define INCLUDEFONT "%%IncludeFont:"
! 662: #define INCLUDEPROCSET "%%IncludeProcSet:"
! 663: #define INCLUDEFILE "%%IncludeFile:"
! 664: #define EXECUTEFILE "%%ExecuteFile:"
! 665: #define CHANGEFONT "%%ChangeFont:"
! 666: #define PAPERFORM "%%PaparForm:"
! 667: #define PAPERCOLOR "%%PaperColor:"
! 668: #define PAPERWEIGHT "%%PaperWeight:"
! 669: #define PAPERSIZE "%%PaperSize:"
! 670: #define FEATURE "%%Feature:"
! 671: #define ENDOFFILE "%%EOF\n"
! 672:
! 673: #define CONTINUECOMMENT "%%+"
! 674: #define ATEND "(atend)"
! 675:
! 676: /*
! 677: *
! 678: * Some non-standard document comments. Global definitions are occasionally used
! 679: * in dpost and are marked by BEGINGLOBAL and ENDGLOBAL. The resulting document
! 680: * violates page independence, but can easily be converted to a conforming file
! 681: * using a utililty program.
! 682: *
! 683: */
! 684:
! 685: #define BEGINSCRIPT "%%BeginScript\n"
! 686: #define BEGINGLOBAL "%%BeginGlobal\n"
! 687: #define ENDGLOBAL "%%EndGlobal\n"
! 688: #define ENDPAGE "%%EndPage:"
! 689: #define FORMSPERPAGE "%%FormsPerPage:"
! 690: #define VERSION "%%Version:"
! 691:
! 692: 0707070014230361541006440057030057030000011041100522627500600002700000012551post.src/common/bbox.c /*
! 693: *
! 694: * Boundingbox code for PostScript translators. The boundingbox for each page
! 695: * is accumulated in bbox - the one for the whole document goes in docbbox. A
! 696: * call to writebbox() puts out an appropriate comment, updates docbbox, and
! 697: * resets bbox for the next page. The assumption made at the end of writebbox()
! 698: * is that we're really printing the current page only if output is now going
! 699: * to stdout - a valid assumption for all supplied translators. Needs the math
! 700: * library.
! 701: *
! 702: */
! 703:
! 704: #include <stdio.h>
! 705: #include <ctype.h>
! 706: #include <fcntl.h>
! 707: #include <math.h>
! 708:
! 709: #include "comments.h" /* PostScript file structuring comments */
! 710: #include "gen.h" /* a few general purpose definitions */
! 711: #include "ext.h" /* external variable declarations */
! 712:
! 713: typedef struct bbox {
! 714: int set;
! 715: double llx, lly;
! 716: double urx, ury;
! 717: } Bbox;
! 718:
! 719: Bbox bbox = {FALSE, 0.0, 0.0, 0.0, 0.0};
! 720: Bbox docbbox = {FALSE, 0.0, 0.0, 0.0, 0.0};
! 721:
! 722: double ctm[6] = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0};
! 723: double matrix1[6], matrix2[6];
! 724:
! 725: /*****************************************************************************/
! 726:
! 727: cover(x, y)
! 728:
! 729: double x, y;
! 730:
! 731: {
! 732:
! 733: /*
! 734: *
! 735: * Adds point (x, y) to bbox. Coordinates are in user space - the transformation
! 736: * to default coordinates happens in writebbox().
! 737: *
! 738: */
! 739:
! 740: if ( bbox.set == FALSE ) {
! 741: bbox.llx = bbox.urx = x;
! 742: bbox.lly = bbox.ury = y;
! 743: bbox.set = TRUE;
! 744: } else {
! 745: if ( x < bbox.llx )
! 746: bbox.llx = x;
! 747: if ( y < bbox.lly )
! 748: bbox.lly = y;
! 749: if ( x > bbox.urx )
! 750: bbox.urx = x;
! 751: if ( y > bbox.ury )
! 752: bbox.ury = y;
! 753: } /* End else */
! 754:
! 755: } /* End of cover */
! 756:
! 757: /*****************************************************************************/
! 758:
! 759: writebbox(fp, keyword, slop)
! 760:
! 761: FILE *fp; /* the comment is written here */
! 762: char *keyword; /* the boundingbox comment string */
! 763: int slop; /* expand (or contract?) the box a bit */
! 764:
! 765: {
! 766:
! 767: Bbox ubbox; /* user space bounding box */
! 768: double x, y;
! 769:
! 770: /*
! 771: *
! 772: * Transforms the numbers in the bbox[] using ctm[], adjusts the corners a bit
! 773: * (depending on slop) and then writes comment. If *keyword is BoundingBox use
! 774: * whatever's been saved in docbbox, otherwise assume the comment is just for
! 775: * the current page.
! 776: *
! 777: */
! 778:
! 779: if ( strcmp(keyword, BOUNDINGBOX) == 0 )
! 780: bbox = docbbox;
! 781:
! 782: if ( bbox.set == TRUE ) {
! 783: ubbox = bbox;
! 784: bbox.set = FALSE; /* so cover() works properly */
! 785: x = ctm[0] * ubbox.llx + ctm[2] * ubbox.lly + ctm[4];
! 786: y = ctm[1] * ubbox.llx + ctm[3] * ubbox.lly + ctm[5];
! 787: cover(x, y);
! 788: x = ctm[0] * ubbox.llx + ctm[2] * ubbox.ury + ctm[4];
! 789: y = ctm[1] * ubbox.llx + ctm[3] * ubbox.ury + ctm[5];
! 790: cover(x, y);
! 791: x = ctm[0] * ubbox.urx + ctm[2] * ubbox.ury + ctm[4];
! 792: y = ctm[1] * ubbox.urx + ctm[3] * ubbox.ury + ctm[5];
! 793: cover(x, y);
! 794: x = ctm[0] * ubbox.urx + ctm[2] * ubbox.lly + ctm[4];
! 795: y = ctm[1] * ubbox.urx + ctm[3] * ubbox.lly + ctm[5];
! 796: cover(x, y);
! 797: bbox.llx -= slop + 0.5;
! 798: bbox.lly -= slop + 0.5;
! 799: bbox.urx += slop + 0.5;
! 800: bbox.ury += slop + 0.5;
! 801: fprintf(fp, "%s %d %d %d %d\n", keyword, (int)bbox.llx, (int)bbox.lly,(int)bbox.urx, (int)bbox.ury);
! 802: bbox = ubbox;
! 803: } /* End if */
! 804:
! 805: resetbbox((fp == stdout) ? TRUE : FALSE);
! 806:
! 807: } /* End of writebbox */
! 808:
! 809: /*****************************************************************************/
! 810:
! 811: resetbbox(output)
! 812:
! 813: int output;
! 814:
! 815: {
! 816:
! 817: /*
! 818: *
! 819: * Adds bbox to docbbox and resets bbox for the next page. Only update docbbox
! 820: * if we really did output on the last page.
! 821: *
! 822: */
! 823:
! 824: if ( docbbox.set == TRUE ) {
! 825: cover(docbbox.llx, docbbox.lly);
! 826: cover(docbbox.urx, docbbox.ury);
! 827: } /* End if */
! 828:
! 829: if ( output == TRUE ) {
! 830: docbbox = bbox;
! 831: docbbox.set = TRUE;
! 832: } /* End if */
! 833:
! 834: bbox.set = FALSE;
! 835:
! 836: } /* End of resetbbox */
! 837:
! 838: /*****************************************************************************/
! 839:
! 840: scale(sx, sy)
! 841:
! 842: double sx, sy;
! 843:
! 844: {
! 845:
! 846: /*
! 847: *
! 848: * Scales the default matrix.
! 849: *
! 850: */
! 851:
! 852: matrix1[0] = sx;
! 853: matrix1[1] = 0;
! 854: matrix1[2] = 0;
! 855: matrix1[3] = sy;
! 856: matrix1[4] = 0;
! 857: matrix1[5] = 0;
! 858:
! 859: concat(matrix1);
! 860:
! 861: } /* End of scale */
! 862:
! 863: /*****************************************************************************/
! 864:
! 865: translate(tx, ty)
! 866:
! 867: double tx, ty;
! 868:
! 869: {
! 870:
! 871: /*
! 872: *
! 873: * Translates the default matrix.
! 874: *
! 875: */
! 876:
! 877: matrix1[0] = 1.0;
! 878: matrix1[1] = 0.0;
! 879: matrix1[2] = 0.0;
! 880: matrix1[3] = 1.0;
! 881: matrix1[4] = tx;
! 882: matrix1[5] = ty;
! 883:
! 884: concat(matrix1);
! 885:
! 886: } /* End of translate */
! 887:
! 888: /*****************************************************************************/
! 889:
! 890: rotate(angle)
! 891:
! 892: double angle;
! 893:
! 894: {
! 895:
! 896: /*
! 897: *
! 898: * Rotates by angle degrees.
! 899: *
! 900: */
! 901:
! 902: angle *= 3.1416 / 180;
! 903:
! 904: matrix1[0] = matrix1[3] = cos(angle);
! 905: matrix1[1] = sin(angle);
! 906: matrix1[2] = -matrix1[1];
! 907: matrix1[4] = 0.0;
! 908: matrix1[5] = 0.0;
! 909:
! 910: concat(matrix1);
! 911:
! 912: } /* End of rotate */
! 913:
! 914: /*****************************************************************************/
! 915:
! 916: concat(m1)
! 917:
! 918: double m1[];
! 919:
! 920: {
! 921:
! 922: double m2[6];
! 923:
! 924: /*
! 925: *
! 926: * Replaces the ctm[] by the result of the matrix multiplication m1[] x ctm[].
! 927: *
! 928: */
! 929:
! 930: m2[0] = ctm[0];
! 931: m2[1] = ctm[1];
! 932: m2[2] = ctm[2];
! 933: m2[3] = ctm[3];
! 934: m2[4] = ctm[4];
! 935: m2[5] = ctm[5];
! 936:
! 937: ctm[0] = m1[0] * m2[0] + m1[1] * m2[2];
! 938: ctm[1] = m1[0] * m2[1] + m1[1] * m2[3];
! 939: ctm[2] = m1[2] * m2[0] + m1[3] * m2[2];
! 940: ctm[3] = m1[2] * m2[1] + m1[3] * m2[3];
! 941: ctm[4] = m1[4] * m2[0] + m1[5] * m2[2] + m2[4];
! 942: ctm[5] = m1[4] * m2[1] + m1[5] * m2[3] + m2[5];
! 943:
! 944: } /* End of concat */
! 945:
! 946: /*****************************************************************************/
! 947:
! 948: 0707070014230361551006440057030057030000011040560522627500600003500000001604post.src/common/pathtemplate /*
! 949: *
! 950: * pathname definitions for important files and directories.
! 951: *
! 952: */
! 953:
! 954: #define DPOST "POSTLIB/dpost.ps"
! 955: #define POSTBGI "POSTLIB/postbgi.ps"
! 956: #define POSTDAISY "POSTLIB/postdaisy.ps"
! 957: #define POSTDMD "POSTLIB/postdmd.ps"
! 958: #define POSTMD "POSTLIB/postmd.ps"
! 959: #define POSTPLOT "POSTLIB/postplot.ps"
! 960: #define POSTPRINT "POSTLIB/postprint.ps"
! 961: #define POSTNPRINT "POSTLIB/postnprint.ps"
! 962: #define POSTTEK "POSTLIB/posttek.ps"
! 963: #define POSTGIF "POSTLIB/postgif.ps"
! 964:
! 965: #define BASELINE "POSTLIB/baseline.ps"
! 966: #define COLOR "POSTLIB/color.ps"
! 967: #define DRAW "POSTLIB/draw.ps"
! 968: #define FORMFILE "POSTLIB/forms.ps"
! 969: #define SHADEFILE "POSTLIB/shade.ps"
! 970: #define KERNING "POSTLIB/kerning.ps"
! 971: #define REQUESTFILE "POSTLIB/ps.requests"
! 972: #define ROUNDPAGE "POSTLIB/roundpage.ps"
! 973:
! 974: #define ENCODINGDIR "POSTLIB"
! 975: #define HOSTDIR "HOSTDIR"
! 976: #define FONTDIR "FONTDIR"
! 977: #define POSTLIBDIR "POSTLIB"
! 978: #define TEMPDIR "/tmp"
! 979:
! 980: 0707070014230357541006400057030057030000011040360522633073100003200000002342post.src/common/common.mk MAKE=/bin/make
! 981: MAKEFILE=common.mk
! 982:
! 983: SYSTEM=V9
! 984: VERSION=3.3.2
! 985:
! 986: FONTDIR=/usr/lib/font
! 987: HOSTDIR=/usr/lib/font/postscript
! 988: POSTLIB=/usr/lib/postscript
! 989:
! 990: ROUNDPAGE=TRUE
! 991:
! 992: CFLGS=-O
! 993: LDFLGS=-s
! 994:
! 995: CFLAGS=$(CFLGS)
! 996: LDFLAGS=$(LDFLGS)
! 997:
! 998: all :
! 999:
! 1000: install : all
! 1001:
! 1002: clean :
! 1003: rm -f *.o
! 1004:
! 1005: clobber : clean
! 1006:
! 1007: bbox.o : bbox.c ext.h gen.h
! 1008: $(CC) $(CFLAGS) -c bbox.c
! 1009:
! 1010: glob.o : glob.c gen.h
! 1011: $(CC) $(CFLAGS) -c glob.c
! 1012:
! 1013: misc.o : misc.c ext.h gen.h path.h
! 1014: $(CC) $(CFLAGS) -c misc.c
! 1015:
! 1016: request.o : request.c gen.h path.h request.h
! 1017: $(CC) $(CFLAGS) -c request.c
! 1018:
! 1019: rune.o : rune.c rune.h
! 1020: $(CC) $(CFLAGS) -c rune.c
! 1021:
! 1022: tempnam.o : tempnam.c
! 1023: $(CC) $(CFLAGS) -D$(SYSTEM) -c tempnam.c
! 1024:
! 1025: changes :
! 1026: @trap "" 1 2 3 15; \
! 1027: sed \
! 1028: -e "s'^SYSTEM=.*'SYSTEM=$(SYSTEM)'" \
! 1029: -e "s'^VERSION=.*'VERSION=$(VERSION)'" \
! 1030: -e "s'^FONTDIR=.*'FONTDIR=$(FONTDIR)'" \
! 1031: -e "s'^HOSTDIR=.*'HOSTDIR=$(HOSTDIR)'" \
! 1032: -e "s'^POSTLIB=.*'POSTLIB=$(POSTLIB)'" \
! 1033: -e "s'^ROUNDPAGE=.*'ROUNDPAGE=$(ROUNDPAGE)'" \
! 1034: $(MAKEFILE) >XXX.mk; \
! 1035: mv XXX.mk $(MAKEFILE); \
! 1036: sed \
! 1037: -e 's:"FONTDIR:"$(FONTDIR):' \
! 1038: -e 's:"HOSTDIR:"$(HOSTDIR):' \
! 1039: -e 's:"POSTLIB:"$(POSTLIB):' \
! 1040: pathtemplate >path.h; \
! 1041: sed \
! 1042: -e "s'^#define.*DOROUND.*'#define DOROUND $(ROUNDPAGE)'" \
! 1043: gen.h >Xgen.h; \
! 1044: mv Xgen.h gen.h
! 1045:
! 1046: 0707070014230361571006440057030057030000011040570522627500600002700000000566post.src/common/rune.h /*
! 1047: *
! 1048: * Rune declarations - for supporting UTF encoding.
! 1049: *
! 1050: */
! 1051:
! 1052: #define RUNELIB 1
! 1053:
! 1054: #ifdef RUNELIB
! 1055: typedef unsigned short Rune;
! 1056:
! 1057: enum
! 1058: {
! 1059: UTFmax = 3, /* maximum bytes per rune */
! 1060: Runesync = 0x21, /* cannot represent part of a utf sequence (<) */
! 1061: Runeself = 0xA0, /* rune and utf sequences are the same (<) */
! 1062: Runeerror = 0x80, /* decoding error in utf */
! 1063: };
! 1064: #endif
! 1065: 0707070014230361601006440057030057030000011040740522627500600002700000004760post.src/common/rune.c /*
! 1066: *
! 1067: * Rune library routines for supporting UTF encoding.
! 1068: *
! 1069: */
! 1070:
! 1071: #include "rune.h"
! 1072:
! 1073: #ifdef RUNELIB
! 1074: enum
! 1075: {
! 1076: Char1 = Runeself, Rune1 = Runeself,
! 1077: Char21 = 0xA1, Rune21 = 0x0100,
! 1078: Char22 = 0xF6, Rune22 = 0x4016,
! 1079: Char3 = 0xFC, Rune3 = 0x10000, /* really 0x38E2E */
! 1080: Esc = 0xBE, Bad = Runeerror,
! 1081: };
! 1082:
! 1083: static unsigned char U[256];
! 1084: static unsigned char T[256];
! 1085:
! 1086: static
! 1087: void
! 1088: mktable()
! 1089: {
! 1090: int i, u;
! 1091:
! 1092: for(i=0; i<256; i++) {
! 1093: u = i + (0x5E-0xA0);
! 1094: if(i < 0xA0)
! 1095: u = i + (0xDF-0x7F);
! 1096: if(i < 0x7F)
! 1097: u = i + (0x00-0x21);
! 1098: if(i < 0x21)
! 1099: u = i + (0xBE-0x00);
! 1100: U[i] = u;
! 1101: T[u] = i;
! 1102: }
! 1103: }
! 1104:
! 1105: int
! 1106: chartorune(rune, str)
! 1107: Rune *rune;
! 1108: char *str;
! 1109: {
! 1110: int c, c1, c2;
! 1111: long l;
! 1112:
! 1113: if(U[0] == 0)
! 1114: mktable();
! 1115:
! 1116: /*
! 1117: * one character sequence
! 1118: * 00000-0009F => 00-9F
! 1119: */
! 1120: c = *(unsigned char*)str;
! 1121: if(c < Char1) {
! 1122: *rune = c;
! 1123: return 1;
! 1124: }
! 1125:
! 1126: /*
! 1127: * two character sequence
! 1128: * 000A0-000FF => A0; A0-FF
! 1129: */
! 1130: c1 = *(unsigned char*)(str+1);
! 1131: if(c < Char21) {
! 1132: if(c1 >= Rune1 && c1 < Rune21) {
! 1133: *rune = c1;
! 1134: return 2;
! 1135: }
! 1136: goto bad;
! 1137: }
! 1138:
! 1139: /*
! 1140: * two character sequence
! 1141: * 00100-04015 => A1-F5; 21-7E/A0-FF
! 1142: */
! 1143: c1 = U[c1];
! 1144: if(c1 >= Esc)
! 1145: goto bad;
! 1146: if(c < Char22) {
! 1147: *rune = (c-Char21)*Esc + c1 + Rune21;
! 1148: return 2;
! 1149: }
! 1150:
! 1151: /*
! 1152: * three character sequence
! 1153: * 04016-38E2D => A6-FB; 21-7E/A0-FF
! 1154: */
! 1155: c2 = U[*(unsigned char*)(str+2)];
! 1156: if(c2 >= Esc)
! 1157: goto bad;
! 1158: if(c < Char3) {
! 1159: l = (c-Char22)*Esc*Esc + c1*Esc + c2 + Rune22;
! 1160: if(l >= Rune3)
! 1161: goto bad;
! 1162: *rune = l;
! 1163: return 3;
! 1164: }
! 1165:
! 1166: /*
! 1167: * bad decoding
! 1168: */
! 1169: bad:
! 1170: *rune = Bad;
! 1171: return 1;
! 1172: }
! 1173:
! 1174: int
! 1175: runetochar(str, rune)
! 1176: char *str;
! 1177: Rune *rune;
! 1178: {
! 1179: long c;
! 1180:
! 1181: if(T[0] == 0)
! 1182: mktable();
! 1183:
! 1184: /*
! 1185: * one character sequence
! 1186: * 00000-0009F => 00-9F
! 1187: */
! 1188: c = *rune;
! 1189: if(c < Rune1) {
! 1190: str[0] = c;
! 1191: return 1;
! 1192: }
! 1193:
! 1194: /*
! 1195: * two character sequence
! 1196: * 000A0-000FF => A0; A0-FF
! 1197: */
! 1198: if(c < Rune21) {
! 1199: str[0] = Char1;
! 1200: str[1] = c;
! 1201: return 2;
! 1202: }
! 1203:
! 1204: /*
! 1205: * two character sequence
! 1206: * 00100-04015 => A1-F5; 21-7E/A0-FF
! 1207: */
! 1208: if(c < Rune22) {
! 1209: c -= Rune21;
! 1210: str[0] = c/Esc + Char21;
! 1211: str[1] = T[c%Esc];
! 1212: return 2;
! 1213: }
! 1214:
! 1215: /*
! 1216: * three character sequence
! 1217: * 04016-38E2D => A6-FB; 21-7E/A0-FF
! 1218: */
! 1219: c -= Rune22;
! 1220: str[0] = c/(Esc*Esc) + Char22;
! 1221: str[1] = T[c/Esc%Esc];
! 1222: str[2] = T[c%Esc];
! 1223: return 3;
! 1224: }
! 1225:
! 1226: int
! 1227: runelen(c)
! 1228: long c;
! 1229: {
! 1230: Rune rune;
! 1231: char str[10];
! 1232:
! 1233: rune = c;
! 1234: return runetochar(str, &rune);
! 1235: }
! 1236:
! 1237: int
! 1238: fullrune(str, n)
! 1239: char *str;
! 1240: int n;
! 1241: {
! 1242: int c;
! 1243:
! 1244: if(n > 0) {
! 1245: c = *(unsigned char*)str;
! 1246: if(c < Char1)
! 1247: return 1;
! 1248: if(n > 1)
! 1249: if(c < Char22 || n > 2)
! 1250: return 1;
! 1251: }
! 1252: return 0;
! 1253: }
! 1254:
! 1255: #endif RUNELIB
! 1256: 0707070014231030400407550057030057030000020277230522633100400001700000000000post.src/dpost 0707070014231030411006440057030057030000010277240522627500600002600000002711post.src/dpost/README
! 1257: Troff to PostScript translator. The big change is in the font table
! 1258: routines. The old binary format and makedev are gone. Troff and dpost
! 1259: now both read ASCII tables. Translating the ASCII font tables in dpost
! 1260: (and troff) means some startup overhead. Both programs run a bit slower,
! 1261: but it's a small price to pay for the added flexibility.
! 1262:
! 1263: Long PostScript font names can now be included in the font tables.
! 1264: They should follow the fontname keyword as in,
! 1265:
! 1266: fontname Times-Roman
! 1267:
! 1268: The fontname field helps with the DocumentFonts comment, font name
! 1269: abbreviations (formally required to be in the prologue), and is used
! 1270: to manage host resident fonts.
! 1271:
! 1272: dpost can also now calculate a reasonably tight BoundingBox, which
! 1273: helps picture inclusion. By default the calculations are disabled.
! 1274: Use the -B option when you BoundingBox and PageBoundingBox comments.
! 1275: If you're stubborn and always want the comment set dobbox (in file
! 1276: dpost.c) to TRUE. You'll still need -B to get the the best fit.
! 1277:
! 1278: Most other changes are bug fixes. Color support has been improved,
! 1279: and now works with the drawing routines. The different text encoding
! 1280: schemes are all still in. Level 2 is well tested and is now the default.
! 1281: For a different default change DFLTENCODING (file dpost.h). Don't make
! 1282: level 3 the default unless you can live with ragged right margins.
! 1283:
! 1284: A typical command line would be,
! 1285:
! 1286: pic file | tbl | eqn | troff -mm | dpost >file.ps
! 1287:
! 1288: file.ps is PostScript and can be sent directly to a printer.
! 1289:
! 1290: 0707070014231030421006440057030057030000010277400522627500600002700000015654post.src/dpost/color.c /*
! 1291: *
! 1292: * Routines that handle color requests passed through as device control commands
! 1293: * in the form "x X SetColor:red". The following PostScript procedures are needed:
! 1294: *
! 1295: * setcolor
! 1296: *
! 1297: * mark /color setcolor mark
! 1298: * mark /color1 /color2 setcolor mark
! 1299: *
! 1300: * Called whenever we want to change PostScript's current color graphics
! 1301: * state parameter. One or two color arguments can be given. In each case
! 1302: * the colors are looked up in the PostScript colordict dictionary that's
! 1303: * defined in *colorfile. Two named colors implies reverse video printing
! 1304: * with the background given in /color2 and the text printed in /color1.
! 1305: * Unknown colors are mapped into defaults - black for a single color and
! 1306: * white on black for reverse video.
! 1307: *
! 1308: * drawrvbox
! 1309: *
! 1310: * leftx rightx drawrvbox -
! 1311: *
! 1312: * Fills a box that extends from leftx to rightx with the background color
! 1313: * that was requested when setcolor set things up for reverse video mode.
! 1314: * The vertical extent of the box is determined using FontBBox just before
! 1315: * the first string is printed, and the height remains in effect until
! 1316: * there's an explicit color change. In otherwords font or size changes
! 1317: * won't always produce correct result in reverse video mode.
! 1318: *
! 1319: * setdecoding
! 1320: *
! 1321: * num setdecoding -
! 1322: *
! 1323: * Selects the text decoding procedure (ie. what's assigned to PostScript
! 1324: * procedure t) from the decodingdefs array defined in the prologue. num
! 1325: * should be the value assigned to variable encoding (in dpost) and will
! 1326: * remain constant throughout a job, unless special features, like reverse
! 1327: * video printing, are requested. The text encoding scheme can be set on
! 1328: * the command line using the -e option. Print time and the size of the
! 1329: * output file will usually decrease as the value assigned to encoding
! 1330: * increases.
! 1331: *
! 1332: *
! 1333: * The recognized collection of "x X SetColor:" commands are:
! 1334: *
! 1335: * x X SetColor: selects black
! 1336: * x X SetColor:color selects color
! 1337: * x X SetColor:color1 on color2 reverse video
! 1338: * x X SetColor:color1 color2 reverse video again
! 1339: * x X SetColor:num1 num2 num3 rgb explicit rgb color request
! 1340: * x X SetColor:num1 num2 num3 hsb explicit hsb color request
! 1341: *
! 1342: * In the last three examples num1, num2, and num3 should be numbers between 0 and
! 1343: * 1 inclusive and are passed on as aguments to the approrpriate PostScript color
! 1344: * command (eg. setrgbcolor). Unknown color names (ie. the ones that setcolor
! 1345: * doesn't find in colordict) are mapped into defaults. For one color the default
! 1346: * is black, while for reverse video it's white text on a black background.
! 1347: *
! 1348: * dpost makes sure the current color is maintained across page boundaries, which
! 1349: * may not be what you want if you're using a macro package like mm that puts out
! 1350: * page footers and headers. Adding a color request to troff and keeping track of
! 1351: * the color in each environment may be the best solution.
! 1352: *
! 1353: * To get reverse video printing follow the "x X SetColor:" command with two or
! 1354: * three arguments. "x X SetColor:white on black" or "x X SetColor:white black"
! 1355: * both produce white text on a black background. Any two colors named in colordict
! 1356: * (in file *colorfile) can be chosen so "x X SetColor:yellow on blue" also works.
! 1357: * Each reverse video mode request selects the vertical extent of the background
! 1358: * box based on the font and size in use just before the first string is printed.
! 1359: * Font and/or size changes aren't guaranteed to work properly in reverse video
! 1360: * printing.
! 1361: *
! 1362: */
! 1363:
! 1364: #include <stdio.h>
! 1365: #include <ctype.h>
! 1366:
! 1367: #include "gen.h" /* general purpose definitions */
! 1368: #include "ext.h" /* external variable definitions */
! 1369:
! 1370: #define DEFAULTCOLOR "black"
! 1371:
! 1372: char color[50] = DEFAULTCOLOR; /* current color */
! 1373: int gotcolor = FALSE; /* TRUE after *colorfile is downloaded */
! 1374: int wantcolor = FALSE; /* TRUE if we really ask for a color */
! 1375:
! 1376: /*
! 1377: *
! 1378: * All these should be defined in dpost.c.
! 1379: *
! 1380: */
! 1381:
! 1382: extern int lastend;
! 1383: extern int encoding;
! 1384: extern int maxencoding;
! 1385: extern int realencoding;
! 1386:
! 1387: extern char *colorfile;
! 1388: extern FILE *tf;
! 1389:
! 1390: /*****************************************************************************/
! 1391:
! 1392: getcolor()
! 1393:
! 1394: {
! 1395:
! 1396: /*
! 1397: *
! 1398: * Responsible for making sure the PostScript color procedures are downloaded from
! 1399: * *colorfile. Done at most once per job, and only if the job really uses color.
! 1400: * For now I've decided not to quit if we can't read the color file.
! 1401: *
! 1402: */
! 1403:
! 1404: if ( gotcolor == FALSE )
! 1405: exportfile(colorfile);
! 1406:
! 1407: if ( tf == stdout )
! 1408: gotcolor = TRUE;
! 1409:
! 1410: } /* End of getcolor */
! 1411:
! 1412: /*****************************************************************************/
! 1413:
! 1414: newcolor(name)
! 1415:
! 1416: char *name; /* of the color */
! 1417:
! 1418: {
! 1419:
! 1420: char *p; /* next character in *name */
! 1421: int i; /* goes in color[i] */
! 1422:
! 1423: /*
! 1424: *
! 1425: * Converts *name to lower case and saves the result in color[] for use as the
! 1426: * current color. The first time something other than DEFAULTCOLOR is requested
! 1427: * sets wantcolor to TRUE. Characters are converted to lower case as they're put
! 1428: * in color[] and we quit when we find a newline or get to the end of *name. The
! 1429: * isupper() test is for Berkley systems.
! 1430: *
! 1431: */
! 1432:
! 1433: for ( p = name; *p && (*p == ' ' || *p == ':'); p++ ) ;
! 1434:
! 1435: for ( i = 0; i < sizeof(color) - 1 && *p != '\n' && *p; i++, p++ )
! 1436: if ( isupper(*p) )
! 1437: color[i] = tolower(*p);
! 1438: else color[i] = *p;
! 1439:
! 1440: if ( i == 0 )
! 1441: strcpy(color, DEFAULTCOLOR);
! 1442: else color[i] = '\0';
! 1443:
! 1444: if ( strcmp(color, DEFAULTCOLOR) != 0 )
! 1445: wantcolor = TRUE;
! 1446:
! 1447: } /* End of newcolor */
! 1448:
! 1449: /*****************************************************************************/
! 1450:
! 1451: setcolor()
! 1452:
! 1453: {
! 1454:
! 1455: int newencoding; /* text encoding scheme that's needed */
! 1456: char *p; /* for converting what's in color[] */
! 1457:
! 1458: /*
! 1459: *
! 1460: * Sets the color being used by the printer to whatever's stored as the current
! 1461: * color (ie. the string in color[]). wantcolor is only set to TRUE if we've been
! 1462: * through newcolor() and asked for something other than DEFAULTCOLOR (probably
! 1463: * black). While in reverse video mode encoding gets set to maxencoding + 1 in
! 1464: * dpost and 0 on the printer. Didn't see much point in trying to extend reverse
! 1465: * video to all the different encoding schemes. realencoding is restored when we
! 1466: * leave reverse video mode.
! 1467: *
! 1468: */
! 1469:
! 1470: if ( wantcolor == TRUE ) {
! 1471: flushtext();
! 1472: getcolor();
! 1473:
! 1474: lastend = -1;
! 1475: newencoding = realencoding;
! 1476:
! 1477: if ( islower(color[0]) == 0 ) /* explicit rgb or hsb request */
! 1478: fprintf(tf, "%s\n", color);
! 1479: else {
! 1480: putc('/', tf);
! 1481: for ( p = color; *p && *p != ' '; p++ )
! 1482: putc(*p, tf);
! 1483: for ( ; *p && *p == ' '; p++ ) ;
! 1484: if ( strncmp(p, "on ", 3) == 0 ) p += 3;
! 1485: if ( *p != '\0' ) {
! 1486: fprintf(tf, " /%s", p);
! 1487: newencoding = maxencoding + 1;
! 1488: } /* End if */
! 1489: fprintf(tf, " setcolor\n");
! 1490: } /* End else */
! 1491:
! 1492: if ( newencoding != encoding ) {
! 1493: encoding = newencoding;
! 1494: fprintf(tf, "%d setdecoding\n", encoding);
! 1495: resetpos();
! 1496: } /* End if */
! 1497: } /* End if */
! 1498:
! 1499: } /* End of setcolor */
! 1500:
! 1501: /*****************************************************************************/
! 1502:
! 1503: 0707070014231027441006400057030057030000010254600522633100400002700000012240post.src/dpost/dpost.1