From e5888a1ffdae813d7575f5fb02275c6bb07e5199 Mon Sep 17 00:00:00 2001 From: Taru Karttunen Date: Wed, 30 Mar 2011 15:46:40 +0300 Subject: Import sources from 2011-03-30 iso image --- sys/src/cmd/postscript/posttek/README | 4 + sys/src/cmd/postscript/posttek/mkfile | 33 + sys/src/cmd/postscript/posttek/posttek.c | 1199 +++++++++++++++++++++++++++++ sys/src/cmd/postscript/posttek/posttek.h | 183 +++++ sys/src/cmd/postscript/posttek/posttek.ps | 106 +++ 5 files changed, 1525 insertions(+) create mode 100755 sys/src/cmd/postscript/posttek/README create mode 100755 sys/src/cmd/postscript/posttek/mkfile create mode 100755 sys/src/cmd/postscript/posttek/posttek.c create mode 100755 sys/src/cmd/postscript/posttek/posttek.h create mode 100755 sys/src/cmd/postscript/posttek/posttek.ps (limited to 'sys/src/cmd/postscript/posttek') diff --git a/sys/src/cmd/postscript/posttek/README b/sys/src/cmd/postscript/posttek/README new file mode 100755 index 000000000..f46380669 --- /dev/null +++ b/sys/src/cmd/postscript/posttek/README @@ -0,0 +1,4 @@ + +Tektronix 4014 to PostScript translator. Much of the code was +borrowed from the 5620 Tektronix emulator. + diff --git a/sys/src/cmd/postscript/posttek/mkfile b/sys/src/cmd/postscript/posttek/mkfile new file mode 100755 index 000000000..d5549b2d5 --- /dev/null +++ b/sys/src/cmd/postscript/posttek/mkfile @@ -0,0 +1,33 @@ + +#include +#include +#include + +#include "comments.h" /* PostScript file structuring comments */ +#include "gen.h" /* general purpose definitions */ +#include "path.h" /* for the prologue */ +#include "ext.h" /* external variable definitions */ +#include "posttek.h" /* control codes and other definitions */ + +char *optnames = "a:c:f:m:n:o:p:w:x:y:A:C:E:J:L:P:R:DI"; + +char *prologue = POSTTEK; /* default PostScript prologue */ +char *formfile = FORMFILE; /* stuff for multiple pages per sheet */ + +int formsperpage = 1; /* page images on each piece of paper */ +int copies = 1; /* and this many copies of each sheet */ + +int charheight[] = CHARHEIGHT; /* height */ +int charwidth[] = CHARWIDTH; /* and width arrays for tek characters */ +int tekfont = TEKFONT; /* index into charheight[] and charwidth[] */ + +char intensity[] = INTENSITY; /* special point intensity array */ +char *styles[] = STYLES; /* description of line styles */ +int linestyle = 0; /* index into styles[] */ +int linetype = 0; /* 0 for normal, 1 for defocused */ + +int dispmode = ALPHA; /* current tektronix state */ +int points = 0; /* points making up the current vector */ +int characters = 0; /* characters waiting to be printed */ +int pen = UP; /* just for point plotting */ +int margin = 0; /* left edge - ALPHA state */ + +Point cursor; /* should be current cursor position */ + +Fontmap fontmap[] = FONTMAP; /* for translating font names */ +char *fontname = "Courier"; /* use this PostScript font */ + +int page = 0; /* page we're working on */ +int printed = 0; /* printed this many pages */ + +FILE *fp_in; /* read from this file */ +FILE *fp_out = stdout; /* and write stuff here */ +FILE *fp_acct = NULL; /* for accounting data */ + +/*****************************************************************************/ + +main(agc, agv) + + int agc; + char *agv[]; + +{ + +/* + * + * A simple program that can be used to translate tektronix 4014 files into + * PostScript. Most of the code was taken from the DMD tektronix 4014 emulator, + * although things have been cleaned up some. + * + */ + + argv = agv; /* so everyone can use them */ + argc = agc; + + prog_name = argv[0]; /* just for error messages */ + + init_signals(); /* sets up interrupt handling */ + header(); /* PostScript header comments */ + options(); /* handle the command line options */ + setup(); /* for PostScript */ + arguments(); /* followed by each input file */ + done(); /* print the last page etc. */ + account(); /* job accounting data */ + + exit(x_stat); /* nothing could be wrong */ + +} /* End of main */ + +/*****************************************************************************/ + +init_signals() + +{ + +/* + * + * Make sure we handle interrupts. + * + */ + + if ( signal(SIGINT, interrupt) == SIG_IGN ) { + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + signal(SIGHUP, SIG_IGN); + } else { + signal(SIGHUP, interrupt); + signal(SIGQUIT, interrupt); + } /* End else */ + + signal(SIGTERM, interrupt); + +} /* End of init_signals */ + +/*****************************************************************************/ + +header() + +{ + + int ch; /* return value from getopt() */ + int old_optind = optind; /* for restoring optind - should be 1 */ + +/* + * + * Scans the option list looking for things, like the prologue file, that we need + * right away but could be changed from the default. Doing things this way is an + * attempt to conform to Adobe's latest file structuring conventions. In particular + * they now say there should be nothing executed in the prologue, and they have + * added two new comments that delimit global initialization calls. Once we know + * where things really are we write out the job header, follow it by the prologue, + * and then add the ENDPROLOG and BEGINSETUP comments. + * + */ + + while ( (ch = getopt(argc, argv, optnames)) != EOF ) + if ( ch == 'L' ) + prologue = optarg; + else if ( ch == '?' ) + error(FATAL, ""); + + optind = old_optind; /* get ready for option scanning */ + + fprintf(stdout, "%s", CONFORMING); + fprintf(stdout, "%s %s\n", VERSION, PROGRAMVERSION); + fprintf(stdout, "%s %s\n", DOCUMENTFONTS, ATEND); + fprintf(stdout, "%s %s\n", PAGES, ATEND); + fprintf(stdout, "%s", ENDCOMMENTS); + + if ( cat(prologue) == FALSE ) + error(FATAL, "can't read %s", prologue); + + fprintf(stdout, "%s", ENDPROLOG); + fprintf(stdout, "%s", BEGINSETUP); + fprintf(stdout, "mark\n"); + +} /* End of header */ + +/*****************************************************************************/ + +options() + +{ + + int ch; /* value returned by getopt() */ + +/* + * + * Reads and processes the command line options. Added the -P option so arbitrary + * PostScript code can be passed through. Expect it could be useful for changing + * definitions in the prologue for which options have not been defined. + * + */ + + while ( (ch = getopt(argc, argv, optnames)) != EOF ) { + switch ( ch ) { + case 'a': /* aspect ratio */ + fprintf(stdout, "/aspectratio %s def\n", optarg); + break; + + case 'c': /* copies */ + copies = atoi(optarg); + fprintf(stdout, "/#copies %s store\n", optarg); + break; + + case 'f': /* use this PostScript font */ + fontname = get_font(optarg); + fprintf(stdout, "/font /%s def\n", fontname); + break; + + case 'm': /* magnification */ + fprintf(stdout, "/magnification %s def\n", optarg); + break; + + case 'n': /* forms per page */ + formsperpage = atoi(optarg); + fprintf(stdout, "%s %s\n", FORMSPERPAGE, optarg); + fprintf(stdout, "/formsperpage %s def\n", optarg); + break; + + case 'o': /* output page list */ + out_list(optarg); + break; + + case 'p': /* landscape or portrait mode */ + if ( *optarg == 'l' ) + fprintf(stdout, "/landscape true def\n"); + else fprintf(stdout, "/landscape false def\n"); + break; + + case 'w': /* line width */ + fprintf(stdout, "/linewidth %s def\n", optarg); + break; + + case 'x': /* shift horizontally */ + fprintf(stdout, "/xoffset %s def\n", optarg); + break; + + case 'y': /* and vertically on the page */ + fprintf(stdout, "/yoffset %s def\n", optarg); + break; + + case 'A': /* force job accounting */ + case 'J': + if ( (fp_acct = fopen(optarg, "a")) == NULL ) + error(FATAL, "can't open accounting file %s", optarg); + break; + + case 'C': /* copy file straight to output */ + if ( cat(optarg) == FALSE ) + error(FATAL, "can't read %s", optarg); + break; + + case 'E': /* text font encoding */ + fontencoding = optarg; + break; + + case 'L': /* PostScript prologue file */ + prologue = optarg; + break; + + case 'P': /* PostScript pass through */ + fprintf(stdout, "%s\n", optarg); + break; + + case 'R': /* special global or page level request */ + saverequest(optarg); + break; + + case 'D': /* debug flag */ + debug = ON; + break; + + case 'I': /* ignore FATAL errors */ + ignore = ON; + break; + + case '?': /* don't know the option */ + error(FATAL, ""); + break; + + default: /* don't know what to do for ch */ + error(FATAL, "missing case for option %c", ch); + break; + } /* End switch */ + } /* End while */ + + argc -= optind; + argv += optind; + +} /* End of options */ + +/*****************************************************************************/ + +char *get_font(name) + + char *name; /* name the user asked for */ + +{ + + int i; /* for looking through fontmap[] */ + +/* + * + * Called from options() to map a user's font name into a legal PostScript name. + * If the lookup fails *name is returned to the caller. That should let you choose + * any PostScript font. + * + */ + + for ( i = 0; fontmap[i].name != NULL; i++ ) + if ( strcmp(name, fontmap[i].name) == 0 ) + return(fontmap[i].val); + + return(name); + +} /* End of get_font */ + +/*****************************************************************************/ + +setup() + +{ + +/* + * + * Handles things that must be done after the options are read but before the + * input files are processed. + * + */ + + writerequest(0, stdout); /* global requests eg. manual feed */ + setencoding(fontencoding); + fprintf(stdout, "setup\n"); + + if ( formsperpage > 1 ) { + if ( cat(formfile) == FALSE ) + error(FATAL, "can't read %s", formfile); + fprintf(stdout, "%d setupforms\n", formsperpage); + } /* End if */ + + fprintf(stdout, "%s", ENDSETUP); + +} /* End of setup */ + +/*****************************************************************************/ + +arguments() + +{ + +/* + * + * Makes sure all the non-option command line arguments are processed. If we get + * here and there aren't any arguments left, or if '-' is one of the input files + * we'll process stdin. + * + */ + + if ( argc < 1 ) + statemachine(fp_in = stdin); + else { /* at least one argument is left */ + while ( argc > 0 ) { + if ( strcmp(*argv, "-") == 0 ) + fp_in = stdin; + else if ( (fp_in = fopen(*argv, "r")) == NULL ) + error(FATAL, "can't open %s", *argv); + statemachine(fp_in); + if ( fp_in != stdin ) + fclose(fp_in); + argc--; + argv++; + } /* End while */ + } /* End else */ + +} /* End of arguments */ + +/*****************************************************************************/ + +done() + +{ + +/* + * + * Finished with all the input files, so mark the end of the pages with a TRAILER + * comment, make sure the last page prints, and add things like the PAGES comment + * that can only be determined after all the input files have been read. + * + */ + + fprintf(stdout, "%s", TRAILER); + fprintf(stdout, "done\n"); + fprintf(stdout, "%s %s\n", DOCUMENTFONTS, fontname); + fprintf(stdout, "%s %d\n", PAGES, printed); + +} /* End of done */ + +/*****************************************************************************/ + +account() + +{ + +/* + * + * Writes an accounting record to *fp_acct provided it's not NULL. Accounting + * is requested using the -A or -J options. + * + */ + + if ( fp_acct != NULL ) + fprintf(fp_acct, " print %d\n copies %d\n", printed, copies); + +} /* End of account */ + +/*****************************************************************************/ + +statemachine(fp) + + FILE *fp; /* used to set fp_in */ + +{ + +/* + * + * Controls the translation of the next input file. Tektronix states (dispmode) + * are typically changed in control() and esc(). + * + */ + + redirect(-1); /* get ready for the first page */ + formfeed(); + dispmode = RESET; + + while ( 1 ) + switch ( dispmode ) { + case RESET: + reset(); + break; + + case ALPHA: + alpha(); + break; + + case GIN: + gin(); + break; + + case GRAPH: + graph(); + break; + + case POINT: + case SPECIALPOINT: + point(); + break; + + case INCREMENTAL: + incremental(); + break; + + case EXIT: + formfeed(); + return; + } /* End switch */ + +} /* End of statemachine */ + +/*****************************************************************************/ + +reset() + +{ + +/* + * + * Called to reset things, typically only at the beginning of each input file. + * + */ + + tekfont = -1; + home(); + setfont(TEKFONT); + setmode(ALPHA); + +} /* End of reset */ + +/*****************************************************************************/ + +alpha() + +{ + + int c; /* next character */ + int x, y; /* cursor will be here when we're done */ + +/* + * + * Takes care of printing characters in the current font. + * + */ + + if ( (c = nextchar()) == OUTMODED ) + return; + + if ( (c < 040) && ((c = control(c)) <= 0) ) + return; + + x = cursor.x; /* where the cursor is right now */ + y = cursor.y; + + switch ( c ) { + case DEL: + return; + + case BS: + if ((x -= charwidth[tekfont]) < margin) + x = TEKXMAX - charwidth[tekfont]; + break; + + case NL: + y -= charheight[tekfont]; + break; + + case CR: + x = margin; + break; + + case VT: + if ((y += charheight[tekfont]) >= TEKYMAX) + y = 0; + break; + + case HT: + case ' ': + default: + if ( characters++ == 0 ) + fprintf(fp_out, "%d %d (", cursor.x, cursor.y); + switch ( c ) { + case '(': + case ')': + case '\\': + putc('\\', fp_out); + + default: + putc(c, fp_out); + } /* End switch */ + x += charwidth[tekfont]; + move(x, y); + break; + } /* End switch */ + + if (x >= TEKXMAX) { + x = margin; + y -= charheight[tekfont]; + } /* End if */ + + if (y < 0) { + y = TEKYMAX - charheight[tekfont]; + x -= margin; + margin = (TEKXMAX/2) - margin; + if ((x += margin) > TEKXMAX) + x -= margin; + } /* End if */ + + if ( y != cursor.y || x != cursor.x ) + text(); + + move(x, y); + +} /* End of alpha */ + +/*****************************************************************************/ + +graph() + +{ + + int c; /* next character */ + int b; /* for figuring out loy */ + int x, y; /* next point in the vector */ + static int hix, hiy; /* upper */ + static int lox, loy; /* and lower part of the address */ + static int extra; /* for extended addressing */ + +/* + * + * Handles things when we're in GRAPH, POINT, or SPECIALPOINT mode. + * + */ + + if ((c = nextchar()) < 040) { + control(c); + return; + } /* End if */ + + if ((c & 0140) == 040) { /* new hiy */ + hiy = c & 037; + do + if (((c = nextchar()) < 040) && ((c = control(c)) == OUTMODED)) + return; + while (c == 0); + } /* End if */ + + if ((c & 0140) == 0140) { /* new loy */ + b = c & 037; + do + if (((c = nextchar()) < 040) && ((c = control(c)) == OUTMODED)) + return; + while (c == 0); + if ((c & 0140) == 0140) { /* no, it was extra */ + extra = b; + loy = c & 037; + do + if (((c = nextchar()) < 040) && ((c = control(c)) == OUTMODED)) + return; + while (c == 0); + } else loy = b; + } /* End if */ + + if ((c & 0140) == 040) { /* new hix */ + hix = c & 037; + do + if (((c = nextchar()) < 040) && ((c = control(c)) == OUTMODED)) + return; + while (c == 0); + } /* End if */ + + lox = c & 037; /* this should be lox */ + if (extra & 020) + margin = TEKXMAX/2; + + x = (hix<<7) | (lox<<2) | (extra & 03); + y = (hiy<<7) | (loy<<2) | ((extra & 014)>>2); + + if ( points > 100 ) { /* don't put too much on the stack */ + draw(); + points = 1; + } /* End if */ + + if ( points++ ) + fprintf(fp_out, "%d %d\n", cursor.x - x, cursor.y - y); + + move(x, y); /* adjust the cursor */ + +} /* End of graph */ + +/*****************************************************************************/ + +point() + +{ + + int c; /* next input character */ + +/* + * + * Special point mode permits gray scaling by varying the size of the stored + * point, which is controlled by an intensity character that preceeds each point + * address. + * + */ + + if ( dispmode == SPECIALPOINT ) { + if ( (c = nextchar()) < 040 || c > 0175 ) + return(control(c)); + + fprintf(fp_out, "%d %d i\n", intensity[c - ' '], c & 0100); + } /* End if */ + + graph(); + draw(); + +} /* End of point */ + +/*****************************************************************************/ + +incremental() + +{ + + int c; /* for the next few characters */ + int x, y; /* cursor position when we're done */ + +/* + * + * Handles incremental plot mode. It's entered after the RS control code and is + * used to mark points relative to our current position. It's typically followed + * by one or two bytes that set the pen state and are used to increment the + * current position. + * + */ + + if ( (c = nextchar()) == OUTMODED ) + return; + + if ( (c < 040) && ((c = control(c)) <= 0) ) + return; + + x = cursor.x; /* where we are right now */ + y = cursor.y; + + if ( c & 060 ) + pen = ( c & 040 ) ? UP : DOWN; + + if ( c & 04 ) y++; + if ( c & 010 ) y--; + if ( c & 01 ) x++; + if ( c & 02 ) x--; + + move(x, y); + + if ( pen == DOWN ) { + points = 1; + draw(); + } /* End if */ + +} /* End of incremental */ + +/*****************************************************************************/ + +gin() + +{ + +/* + * + * All we really have to do for GIN mode is make sure it's properly ended. + * + */ + + control(nextchar()); + +} /* End of gin */ + +/*****************************************************************************/ + +control(c) + + int c; /* check this control character */ + +{ + +/* + * + * Checks character c and does special things, like mode changes, that depend + * not only on the character, but also on the current state. If the mode changed + * becuase of c, OUTMODED is returned to the caller. In all other cases the + * return value is c or 0, if c doesn't make sense in the current mode. + * + */ + + switch ( c ) { + case BEL: + return(0); + + case BS: + case HT: + case VT: + return(dispmode == ALPHA ? c : 0); + + case CR: + if ( dispmode != ALPHA ) { + setmode(ALPHA); + ungetc(c, fp_in); + return(OUTMODED); + } else return(c); + + case FS: + if ( (dispmode == ALPHA) || (dispmode == GRAPH) ) { + setmode(POINT); + return(OUTMODED); + } /* End if */ + return(0); + + case GS: + if ( (dispmode == ALPHA) || (dispmode == GRAPH) ) { + setmode(GRAPH); + return(OUTMODED); + } /* End if */ + return(0); + + case NL: + ungetc(CR, fp_in); + return(dispmode == ALPHA ? c : 0); + + case RS: + if ( dispmode != GIN ) { + setmode(INCREMENTAL); + return(OUTMODED); + } /* End if */ + return(0); + + case US: + if ( dispmode == ALPHA ) + return(0); + setmode(ALPHA); + return(OUTMODED); + + case ESC: + return(esc()); + + case OUTMODED: + return(c); + + default: + return(c < 040 ? 0 : c); + } /* End switch */ + +} /* End of control */ + +/*****************************************************************************/ + +esc() + +{ + + int c; /* next input character */ + int ignore; /* skip it if nonzero */ + +/* + * + * Handles tektronix escape code. Called from control() whenever an ESC character + * is found in the input file. + * + */ + + do { + c = nextchar(); + ignore = 0; + switch ( c ) { + case CAN: + return(0); + + case CR: + ignore = 1; + break; + + case ENQ: + setmode(ALPHA); + return(OUTMODED); + + case ETB: + return(0); + + case FF: + formfeed(); + setmode(ALPHA); + return(OUTMODED); + + case FS: + if ( (dispmode == INCREMENTAL) || ( dispmode == GIN) ) + return(0); + setmode(SPECIALPOINT); + return(OUTMODED); + + case SI: + case SO: + return(0); + + case SUB: + setmode(GIN); + return(OUTMODED); + + case OUTMODED: + return(OUTMODED); + + case '8': + case '9': + case ':': + case ';': + setfont(c - '8'); + return(0); + + default: + if ( c == '?' && dispmode == GRAPH ) + return(DEL); + if ( (c<'`') || (c>'w') ) + break; + c -= '`'; + if ( (c & 010) != linetype ) + fprintf(fp_out, "%d w\n", (linetype = (c & 010))/010); + if ( ((c + 1) & 7) >= 6 ) + break; + if ( (c + 1) & 7 ) + if ( (c & 7) != linestyle ) { + linestyle = c & 7; + setmode(dispmode); + fprintf(fp_out, "%s l\n", styles[linestyle]); + } /* End if */ + return(0); + } /* End switch */ + + } while (ignore); + + return(0); + +} /* End of esc */ + +/*****************************************************************************/ + +move(x, y) + + int x, y; /* move the cursor here */ + +{ + +/* + * + * Moves the cursor to the point (x, y). + * + */ + + cursor.x = x; + cursor.y = y; + +} /* End of move */ + +/*****************************************************************************/ + +setmode(mode) + + int mode; /* this should be the new mode */ + +{ + +/* + * + * Makes sure the current mode is properly ended and then sets dispmode to mode. + * + */ + + switch ( dispmode ) { + case ALPHA: + text(); + break; + + case GRAPH: + draw(); + break; + + case INCREMENTAL: + pen = UP; + break; + } /* End switch */ + + dispmode = mode; + +} /* End of setmode */ + +/*****************************************************************************/ + +home() + +{ + +/* + * + * Makes sure the cursor is positioned at the upper left corner of the page. + * + */ + + margin = 0; + move(0, TEKYMAX); + +} /* End of home */ + +/*****************************************************************************/ + +setfont(newfont) + + int newfont; /* use this font next */ + +{ + +/* + * + * Generates the call to the procedure that's responsible for changing the + * tektronix font (really just the size). + * + */ + + if ( newfont != tekfont ) { + setmode(dispmode); + fprintf(fp_out, "%d f\n", charwidth[newfont]); + } /* End if */ + + tekfont = newfont; + +} /* End of setfont */ + +/*****************************************************************************/ + +text() + +{ + +/* + * + * Makes sure any text we've put on the stack is printed. + * + */ + + if ( dispmode == ALPHA && characters > 0 ) + fprintf(fp_out, ") t\n"); + + characters = 0; + +} /* End of text */ + +/*****************************************************************************/ + +draw() + +{ + +/* + * + * Called whenever we need to draw a vector or plot a point. Nothing will be + * done if points is 0 or if it's 1 and we're in GRAPH mode. + * + */ + + if ( points > 1 ) /* it's a vector */ + fprintf(fp_out, "%d %d v\n", cursor.x, cursor.y); + else if ( points == 1 && dispmode != GRAPH ) + fprintf(fp_out, "%d %d p\n", cursor.x, cursor.y); + + points = 0; + +} /* End of draw */ + +/*****************************************************************************/ + +formfeed() + +{ + +/* + * + * Usually called when we've finished the last page and want to get ready for the + * next one. Also used at the beginning and end of each input file, so we have to + * be careful about exactly what's done. + * + */ + + setmode(dispmode); /* end any outstanding text or graphics */ + + if ( fp_out == stdout ) /* count the last page */ + printed++; + + fprintf(fp_out, "cleartomark\n"); + fprintf(fp_out, "showpage\n"); + fprintf(fp_out, "saveobj restore\n"); + fprintf(fp_out, "%s %d %d\n", ENDPAGE, page, printed); + + if ( ungetc(getc(fp_in), fp_in) == EOF ) + redirect(-1); + else redirect(++page); + + fprintf(fp_out, "%s %d %d\n", PAGE, page, printed+1); + fprintf(fp_out, "/saveobj save def\n"); + fprintf(fp_out, "mark\n"); + writerequest(printed+1, fp_out); + fprintf(fp_out, "%d pagesetup\n", printed+1); + fprintf(fp_out, "%d f\n", charwidth[tekfont]); + fprintf(fp_out, "%s l\n", styles[linestyle]); + + home(); + +} /* End of formfeed */ + +/*****************************************************************************/ + +nextchar() + +{ + + int ch; /* next input character */ + +/* + * + * Reads the next character from the current input file and returns it to the + * caller. When we're finished with the file dispmode is set to EXIT and OUTMODED + * is returned to the caller. + * + */ + + if ( (ch = getc(fp_in)) == EOF ) { + setmode(EXIT); + ch = OUTMODED; + } /* End if */ + + return(ch); + +} /* End of nextchar */ + +/*****************************************************************************/ + +redirect(pg) + + int pg; /* next page we're printing */ + +{ + + static FILE *fp_null = NULL; /* if output is turned off */ + +/* + * + * If we're not supposed to print page pg, fp_out will be directed to /dev/null, + * otherwise output goes to stdout. + * + */ + + if ( pg >= 0 && in_olist(pg) == ON ) + fp_out = stdout; + else if ( (fp_out = fp_null) == NULL ) + fp_out = fp_null = fopen("/dev/null", "w"); + +} /* End of redirect */ + +/*****************************************************************************/ + diff --git a/sys/src/cmd/postscript/posttek/posttek.h b/sys/src/cmd/postscript/posttek/posttek.h new file mode 100755 index 000000000..99d10133c --- /dev/null +++ b/sys/src/cmd/postscript/posttek/posttek.h @@ -0,0 +1,183 @@ +/* + * + * Tektronix 4014 control codes. + * + */ + +#define NUL '\000' +#define SOH '\001' +#define STX '\002' +#define ETX '\003' +#define EOT '\004' +#define ENQ '\005' +#define ACK '\006' +#define BEL '\007' +#define BS '\010' +#define HT '\011' +#define NL '\012' +#define VT '\013' +#define FF '\014' +#define CR '\015' +#define SO '\016' +#define SI '\017' +#define DLE '\020' +#define DC1 '\021' +#define DC2 '\022' +#define DC3 '\023' +#define DC4 '\024' +#define NAK '\025' +#define SYN '\026' +#define ETB '\027' +#define CAN '\030' +#define EM '\031' +#define SUB '\032' +#define ESC '\033' +#define FS '\034' +#define GS '\035' +#define RS '\036' +#define US '\037' +#define DEL '\177' + +/* + * + * A few definitions used to classify the different tektronix states. OUTMODED + * is returned by control() and esc(), and typically means the state has changed. + * + */ + +#define OUTMODED -1 +#define ALPHA 0 +#define GIN 1 +#define GRAPH 2 +#define POINT 3 +#define SPECIALPOINT 4 +#define INCREMENTAL 5 +#define RESET 6 +#define EXIT 7 + +/* + * + * The pen state, either UP or DOWN, controls whether vectors are drawn. + * + */ + +#define UP 0 +#define DOWN 1 + +/* + * + * Coordinates of the upper right corner of the screen - almost the real screen + * dimensions. + * + */ + +#define TEKXMAX 4096 +#define TEKYMAX 3120 + +/* + * + * The size of the spot in SPECIALPOINT mode is controlled by a non-linear + * function that has a domain that consists of the integers from 040 to 0175. + * The next definition is used to initialize the special point mode intensity + * array that implements the function. Data came from table F-6 in the tektronix + * 4014 manual. + * + */ + +#define INTENSITY \ + \ + { \ + 14, 16, 17, 19, 20, 22, 23, 25, \ + 28, 31, 34, 38, 41, 44, 47, 50, \ + 56, 62, 69, 75, 81, 88, 94,100, \ + 56, 62, 69, 75, 81, 88, 94,100, \ + 0, 1, 1, 1, 1, 1, 1, 2, \ + 2, 2, 2, 2, 3, 3, 3, 3, \ + 4, 4, 4, 5, 5, 5, 6, 6, \ + 7, 8, 9, 10, 11, 12, 12, 13, \ + 14, 16, 17, 19, 20, 22, 23, 25, \ + 28, 31, 34, 38, 41, 44, 47, 50, \ + 56, 62, 69, 75, 81, 88, 94,100, \ + 56, 62, 69, 75, 81, 88, 94,100, \ + } + +/* + * + * The next two definitions give the height and width of characters in the four + * different sizes available on tektronix terminals. TEKFONT is the default index + * into CHARHEIGHT and CHARWIDTH. + * + */ + +#define CHARHEIGHT {88, 82, 53, 48} +#define CHARWIDTH {56, 51, 34, 31} +#define TEKFONT 2 + +/* + * + * The entries defined in STYLES are passed on to the PostScript operator setdash. + * They're used to implement the different tektronix line styles. Belongs in the + * prologue! + * + */ + +#define STYLES \ + \ + { \ + "[]", \ + "[.5 2]", \ + "[.5 2 4 2]", \ + "[4 4]", \ + "[8 4]", \ + "[]" \ + } + +/* + * + * Variables of type Point are used to keep track of the cursor position. + * + */ + +typedef struct { + int x; + int y; +} Point; + +/* + * + * An array of type Fontmap helps convert font names requested by users into + * legitimate PostScript names. The array is initialized using FONTMAP, which must + * end with an entry that has NULL defined as its name field. + * + */ + +typedef struct { + char *name; /* user's font name */ + char *val; /* corresponding PostScript name */ +} Fontmap; + +#define FONTMAP \ + \ + { \ + "R", "Courier", \ + "I", "Courier-Oblique", \ + "B", "Courier-Bold", \ + "CO", "Courier", \ + "CI", "Courier-Oblique", \ + "CB", "Courier-Bold", \ + "CW", "Courier", \ + "PO", "Courier", \ + "courier", "Courier", \ + "cour", "Courier", \ + "co", "Courier", \ + NULL, NULL \ + } + +/* + * + * Some of the non-integer valued functions in posttek.c. + * + */ + +char *get_font(); + diff --git a/sys/src/cmd/postscript/posttek/posttek.ps b/sys/src/cmd/postscript/posttek/posttek.ps new file mode 100755 index 000000000..ee2428ced --- /dev/null +++ b/sys/src/cmd/postscript/posttek/posttek.ps @@ -0,0 +1,106 @@ +% +% Version 3.3.2 prologue for tektronix 4014 files. +% + +/#copies 1 store +/aspectratio 1 def +/fixlinewidth true def +/font /Courier def +/formsperpage 1 def +/landscape true def +/linewidth 0 def +/magnification 1 def +/margin 10 def +/orientation 0 def +/rotation 1 def +/screenheight 3120 def +/screenwidth 4150 def +/spotsize 1 def +/xoffset 0 def +/yoffset 0 def + +/useclippath true def +/pagebbox [0 0 612 792] def + +/inch {72 mul} bind def +/min {2 copy gt {exch} if pop} bind def + +/kshow {kshow} bind def % so later references don't bind + +/setup { + counttomark 2 idiv {def} repeat pop + + landscape {/orientation 90 orientation add def} if + + pagedimensions + /scaling + height margin sub screenheight div + width margin sub screenwidth div + min def + xcenter ycenter translate + orientation rotation mul rotate + xoffset inch yoffset inch translate + magnification dup aspectratio mul scale + scaling scaling scale + screenwidth 2 div neg screenheight 2 div neg translate + + tietodevicespace + linewidth scaling div setlinewidth + 1 setlinecap + newpath +} def + +/pagedimensions { + useclippath { + /pagebbox [clippath pathbbox newpath] def + } if + pagebbox aload pop + 4 -1 roll exch 4 1 roll 4 copy + landscape {4 2 roll} if + sub /width exch def + sub /height exch def + add 2 div /xcenter exch def + add 2 div /ycenter exch def + userdict /gotpagebbox true put +} def + +/pagesetup {/page exch def} bind def + +/tietodevicespace { + fixlinewidth linewidth 0 gt and linewidth 1 lt and { + /moveto { + 2 copy /Y exch def /X exch def + transform round exch round exch itransform + moveto + } bind def + /lineto { + 2 copy /Y exch def /X exch def + transform round exch round exch itransform + lineto + } bind def + /rlineto {Y add exch X add exch lineto} bind def + /v V 0 get bind def + } if +} def + +/V [{moveto counttomark 2 idiv {rlineto} repeat stroke}] def +/v V 0 get bind def +/p {newpath spotsize 0 360 arc fill} bind def + +/l {{scaling div} forall counttomark array astore 0 setdash} bind def +/w {linewidth 0 eq {.3} {linewidth} ifelse mul linewidth add scaling div setlinewidth} bind def +/i {3 mul 4 sub -100 div mul .5 add /spotsize exch def} bind def + +/f {/charwidth exch def font findfont charwidth .6 div scalefont setfont} bind def + +/t { + 3 1 roll moveto + currentpoint { + pop pop + exch charwidth add exch + moveto currentpoint + } 4 -1 roll kshow + pop pop +} bind def + +/done {/lastpage where {pop lastpage} if} def -- cgit v1.2.3