12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199 |
- /*
- *
- * posttek - PostScript translator for tektronix 4014 files
- *
- * A program that can be used to translate tektronix 4014 files into PostScript.
- * Most of the code was borrowed from the tektronix 4014 emulator that was written
- * for DMDs. Things have been cleaned up some, but there's still plently that
- * could be done.
- *
- * The PostScript prologue is copied from *prologue before any of the input files
- * are translated. The program expects that the following PostScript procedures
- * are defined in that file:
- *
- * setup
- *
- * mark ... setup -
- *
- * Handles special initialization stuff that depends on how the program
- * was called. Expects to find a mark followed by key/value pairs on the
- * stack. The def operator is applied to each pair up to the mark, then
- * the default state is set up.
- *
- * pagesetup
- *
- * page pagesetup -
- *
- * Does whatever is needed to set things up for the next page. Expects
- * to find the current page number on the stack.
- *
- * v
- *
- * mark dx1 dy1 ... dxn dyn x y v mark
- *
- * Draws the vector described by the numbers on the stack. The top two
- * numbers are the starting point. The rest are relative displacements
- * from the preceeding point. Must make sure we don't put too much on
- * the stack!
- *
- * t
- *
- * x y string t -
- *
- * Prints the string that's on the top of the stack starting at point
- * (x, y).
- *
- * p
- *
- * x y p -
- *
- * Marks the point (x, y) with a circle whose radius varies with the
- * current intensity setting.
- *
- * i
- *
- * percent focus i -
- *
- * Changes the size of the circle used to mark individual points to
- * percent of maximum for focused mode (focus=1) or defocused mode
- * (focus=0). The implementation leaves much to be desired!
- *
- * l
- *
- * mark array l mark
- *
- * Set the line drawing mode according to the description given in array.
- * The arrays that describe the different line styles are declared in
- * STYLES (file posttek.h). The array really belongs in the prologue!
- *
- * w
- *
- * n w -
- *
- * Adjusts the line width for vector drawing. Used to select normal (n=0)
- * or defocused (n=1) mode.
- *
- * f
- *
- * size f -
- *
- * Changes the size of the font that's used to print characters in alpha
- * mode. size is the tektronix character width and is used to choose an
- * appropriate point size in the current font.
- *
- * done
- *
- * done
- *
- * Makes sure the last page is printed. Only needed when we're printing
- * more than one page on each sheet of paper.
- *
- * The default line width is zero, which forces lines to be one pixel wide. That
- * works well on 'write to black' engines but won't be right for 'write to white'
- * engines. The line width can be changed using the -w option, or you can change
- * the initialization of linewidth in the prologue.
- *
- * Many default values, like the magnification and orientation, are defined in
- * the prologue, which is where they belong. If they're changed (by options), an
- * appropriate definition is made after the prologue is added to the output file.
- * The -P option passes arbitrary PostScript through to the output file. Among
- * other things it can be used to set (or change) values that can't be accessed by
- * other options.
- *
- */
- #include <stdio.h>
- #include <signal.h>
- #include <sys/types.h>
- #include <fcntl.h>
- #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 */
- /*****************************************************************************/
|