home *** CD-ROM | disk | FTP | other *** search
- /*
- * This is dvips, a freely redistributable PostScript driver
- * for dvi files. It is (C) Copyright 1987 by Tomas Rokicki.
- * You may modify and use this program to your heart's content,
- * so long as you send modifications to Tomas Rokicki. It can
- * be included in any distribution, commercial or otherwise, so
- * long as the banner string defined in structures.h is not
- * modified (except for the version number) and this banner is
- * printed on program invocation, or can be printed on program
- * invocation with the -? option.
- */
- #define COLOR
- /*
- * dospecial of dvisw package. (C) 1986 Radical Eye Software.
- * This routine handles special commands. Currently the only
- * special command handled is the landscape special.
- */
- #include "structures.h"
- #include <dpsclient/dpsclient.h>
- #include "paths.h"
- #include <string.h>
- /*
- * These are the external routines called:
- */
- #ifdef TPIC
- extern void setPenSize();
- extern void flushPath();
- extern void flushDashed();
- extern void flushDashed();
- extern void addPath();
- extern void arc();
- extern void flushSpline();
- extern void shadeLast();
- extern void whitenLast();
- extern void blackenLast();
- #endif
- #ifdef COLOR
- extern void pushcolor() ;
- extern void popcolor() ;
- extern void resetcolorstack() ;
- extern void background() ;
- static Boolean usescolor ;
- #endif
- extern void pswrite(), error(), tolandscape(), add_header(), hvpos() ;
- extern void copyfile(), figcopyfile() ;
- extern void handlepapersize(), newpapersize() ;
- extern int dvibyte() ;
- extern char *malloc(), *newstring() ;
- int GetKeyVal(), IsSame() ;
- extern FILE *search() ;
- extern void texflush() ;
- extern char *inputspath ;
- extern Boolean prescan;
- extern void writeconsole() ;
- extern Boolean firstpage ;
- extern Boolean mocked ;
- extern Boolean landscape, orientationset ;
- extern int debugon ;
- extern char *configpath, *headerpath ;
- extern void TPSbop(), TPSeop() ;
- char nextstring[8192] ;
- extern char temperrorbuf[] ;
- char *maxstring = nextstring + 8100 ;
- static integer hpapersize, vpapersize ;
- /*
- * These definitions are used by the \special command.
- */
- typedef enum {None, String, Integer, Number, Dimension} ValTyp;
- typedef struct {
- char *Key; /* the keyword string */
- char *Val; /* the value string */
- ValTyp vt; /* the value type */
- union { /* the decoded value */
- long i;
- float n;
- } v;
- } KeyWord;
- typedef struct {
- char *Entry;
- ValTyp Type;
- } KeyDesc;
- /*
- * Now our routine. We get the number of bytes specified and place them
- * into the string buffer, and then parse it for alpha. Interpret a
- * \special command, made up of keyword=value pairs.
- */
-
- #define NKEYS (sizeof(KeyTab)/sizeof(KeyTab[0]))
-
- KeyDesc KeyTab[] = {{"psfile", String},
- {"ifffile", String},
- {"tekfile", String},
- {"hsize", Number},
- {"vsize", Number},
- {"hoffset", Number},
- {"voffset", Number},
- {"hscale", Number},
- {"vscale", Number},
- {"angle", Number},
- {"llx", Number},
- {"lly", Number},
- {"urx", Number},
- {"ury", Number},
- {"rwi", Number},
- {"rhi", Number},
- {"clip", None}};
-
- char *GetKeyStr();
- void fil2ps();
- char task[7] = "\0";
-
- struct bangspecial {
- struct bangspecial *next ;
- char actualstuff[4] ;
- } *bangspecials = NULL ;
-
- static void trytobreakout(p)
- register char *p ;
- {
- pswrite(" ") ;
- pswrite(p) ;
- pswrite(" ") ;
- }
-
- static void dobs(q)
- register struct bangspecial *q ;
- {
- if (q) {
- dobs(q->next) ;
- trytobreakout(q->actualstuff) ;
- }
- }
-
- void special_header() {
- static int sent = 0 ;
-
- if (! sent) {
- texflush() ;
- #ifdef POPRESTORE
- TPSeop() ;
- #endif
- add_header("special.pro") ;
- #ifdef POPRESTORE
- TPSbop() ;
- #endif
- hvpos() ;
- sent = 1 ;
- }
- }
-
- void outbangspecials() {
- if (bangspecials) {
- special_header() ;
- pswrite(" @defspecial ") ;
- dobs(bangspecials) ;
- pswrite(" @fedspecial ") ;
- }
- }
-
- #define TRUE (1)
- #define FALSE (0)
-
- void dospecial(numbytes)
- integer numbytes ;
- {
- register char *p = nextstring ;
- register int i = 0 ;
- int j ;
- Boolean ps = TRUE ;
- char spbuf[100] ;
- char fbuf[100] ;
- char *sf = NULL ;
- char *f = NULL ;
- KeyWord k ;
-
- temperrorbuf[0] = 0 ;
- if (nextstring + i > maxstring)
- error("! out of string space in dospecial") ;
- for (i=numbytes; i>0; i--)
- *p++ = dvibyte() ;
- *p = 0 ;
- p = nextstring ;
- #ifdef DEBUG
- if (debugon > 3) {
- printf("{%s}", p) ;
- fflush(stdout) ;
- }
- #endif
- while (*p <= ' ' && *p)
- p++ ;
-
- if (strncmp(p, "landscape", 9)==0) {
- if (prescan && firstpage)
- tolandscape() ;
- return ;
- } else if (strncmp(p, "papersize", 9)==0) {
- p += 9 ;
- while (*p == '=' || *p == ' ')
- p++ ;
- handlepapersize(p, &hpapersize, &vpapersize) ;
- if (prescan && firstpage)
- newpapersize(hpapersize, vpapersize) ;
- return ;
- }
- /* ignore this special for now */
- if (strncmp(p, "hp:", 3)==0)
- return ;
- if (! prescan)
- special_header() ;
- if (strncmp(p, "header", 6)==0) {
- if (prescan) {
- char *q ;
- p += 6 ;
- while ((*p <= ' ' || *p == '=' || *p == ')') && *p != 0)
- p++ ;
- q = p ;
- p = p + strlen(p) - 1 ;
- if (*p == ')') {
- p-- ;
- while (*p <= ' ')
- p-- ;
- p[1] = 0 ;
- }
- add_header(q) ;
- }
- return ;
- #ifdef COLOR
- }
- if (strncmp(p, "background", 10) == 0) {
- if (usescolor == 0) {
- add_header("color.pro") ;
- usescolor = 1 ;
- }
- p +=11 ;
- while ( *p <= ' ' ) p++ ;
- background(p) ;
- return ;
- }
- if (strncmp(p, "color", 5) == 0) {
- if (usescolor == 0) {
- add_header("color.pro") ;
- usescolor = 1 ;
- }
- p += 6 ;
- while ( *p <= ' ' ) p++ ;
- if (strncmp(p, "push", 4) == 0 ) {
- p += 4 ;
- while (*p && *p <= ' ' ) p++ ;
- pushcolor(p,!prescan) ;
- } else if (strncmp(p, "pop", 3) == 0 ) {
- popcolor(!prescan) ;
- } else {
- resetcolorstack(p,!prescan) ;
- }
- return ;
- #endif
- } else if (strncmp(p, "ps:", 3)==0) {
- if (! prescan) {
- hvpos() ;
- texflush() ;
- if (strncmp(p, "ps::[begin]", 11) == 0)
- pswrite(&p[11]);
- else if (strncmp(p, "ps::[end]", 9) == 0)
- pswrite(&p[9]);
- else if (strncmp(p, "ps: plotfile ", 13) == 0) {
- char *sfp ;
- p += 13;
- while (*p == ' ') p++ ;
- if (*p == '"') {
- p++ ;
- for (sfp = p; *sfp && *sfp != '"'; sfp++) ;
- } else {
- for (sfp = p; *sfp && *sfp != ' '; sfp++) ;
- }
- *sfp = 0 ;
- if (*p == '`')
- figcopyfile (p+1, 1);
- else
- figcopyfile (p, 0);
- } else if (strncmp(p, "ps::", 4) == 0)
- pswrite(&p[4]);
- else
- pswrite(&p[3]);
- return;
- }
- }
- #ifdef TPIC
- else if (strncmp(p, "pn ", 3) == 0) {if (!prescan) setPenSize(p+2);}
- else if (strncmp(p, "fp",2) == 0) {if (!prescan) flushPath();}
- else if (strncmp(p, "da ", 3) == 0) {if (!prescan) flushDashed(p+2, 0);}
- else if (strncmp(p, "dt ", 3) == 0) {if (!prescan) flushDashed(p+2, 1);}
- else if (strncmp(p, "pa ", 3) == 0) {if (!prescan) addPath(p+2);}
- else if (strncmp(p, "ar ", 3) == 0) {if (!prescan) arc(p+2);}
- else if (strncmp(p, "sp", 2) == 0) {if (!prescan) flushSpline();}
- else if (strncmp(p, "sh", 2) == 0) {if (!prescan) shadeLast();}
- else if (strncmp(p, "wh", 2) == 0) {if (!prescan) whitenLast();}
- else if (strncmp(p, "bk", 2) == 0) {if (!prescan) blackenLast();}
- else if (strncmp(p, "tx ", 3) == 0)
- {error("\\special texture command -- ignored");}
- #endif
- else {
- if (prescan && *p == '!' && firstpage) {
- struct bangspecial *q ;
- void *mymalloc() ;
-
- p++ ;
- q = (struct bangspecial *)mymalloc(sizeof(struct bangspecial) + strlen(p)) ;
- strcpy(q->actualstuff, p) ;
- q->next = bangspecials ;
- bangspecials = q ;
- return ;
- }
-
- if (! prescan) {
- if (*p == '"') {
- hvpos();
- pswrite(" @beginspecial @setspecial ") ;
- trytobreakout(p+1) ;
- pswrite(" @endspecial ") ;
- return ;
- } else if (*p == '!')
- return ;
-
- spbuf[0] = '\0';
-
- hvpos();
-
- pswrite(" @beginspecial ");
-
- /* get all keyword-value pairs; for compatibility,
- single words are taken as file names */
-
- while( (p=GetKeyStr(p,&k)) != NULL ) {
- if( GetKeyVal( &k, KeyTab, NKEYS, &j ) && j != -1 ) {
- if( j >= 0 && j <= 2 ) {
- if( sf ) {
- fprintf(stderr, " more than one \\special file name given: %s ignored.", sf );
- }
- strcpy(fbuf, k.Key);
- strcpy(spbuf, k.Val);
- f = fbuf;
- sf = spbuf;
- if( j == 1 || j == 2)
- ps = FALSE;
- } else { /* keywords are output as PS procedure calls */
- if(k.vt == Integer)
- sprintf(temperrorbuf, "%ld @%s ", k.v.i, KeyTab[j].Entry);
- else if (k.vt == None)
- sprintf(temperrorbuf, " @%s ", KeyTab[j].Entry);
- else
- sprintf(temperrorbuf, "%f @%s ", k.v.n, KeyTab[j].Entry);
- pswrite(temperrorbuf) ;
- }
- } else {
- fprintf(stderr, " invalid keyword or value in \\special: \"%s\" ignored.", k.Key );
- }
- }
-
- pswrite(" @setspecial ");
-
- if( sf ) {
- if (*sf == '`')
- figcopyfile(sf+1, 1);
- else
- figcopyfile(sf, 0);
- } else
- fprintf(stderr, " no special file name provided.");
- pswrite(" @endspecial ");
- }
- }
- }
-
- /*
- * extract first keyword-value pair from string (value part may be null)
- * return pointer to remainder of string return NULL if none found
- */
-
- char KeyStr[200];
- char ValStr[200];
-
- char *GetKeyStr( str, kw )
- char *str;
- KeyWord *kw;
- {
- char *s, *k, *v, t;
-
- if( !str )
- return( NULL );
-
- for( s=str; *s == ' '; s++ ) /* skip over blanks */
- ;
- if( *s == '\0' )
- return( NULL );
-
- /* extract keyword portion */
-
- for( k=KeyStr; *s != ' ' && *s != '\0' && *s != '='; *k++ = *s++ )
- ;
- *k = '\0';
- kw->Key = KeyStr;
- kw->Val = v = NULL;
- kw->vt = None;
-
- for( ; *s && *s == ' '; s++ ) /* skip over blanks */
- ;
- if( *s != '=' ) /* look for "=" */
- return( s );
-
- for( s++ ; *s && *s == ' '; s++ ) /* skip over blanks */
- ;
- if( *s == '\'' || *s == '\"' ) /* get string delimiter */
- t = *s++;
- else
- t = ' ';
-
- /* copy value portion up to delimiter */
-
- for( v=ValStr; *s != t && *s != '\0'; *v++ = *s++ )
- ;
- if( t != ' ' && *s == t )
- s++;
- *v = '\0';
- kw->Val = ValStr;
- kw->vt = String;
-
- return( s );
- }
-
- /*
- * get next keyword-value pair decode value according to table entry
- */
-
- int GetKeyVal( kw, tab, nt, tno)
- KeyWord *kw;
- KeyDesc tab[];
- int nt;
- int *tno;
- {
- int i;
- char c = '\0';
-
- *tno = -1;
-
- for(i=0; i<nt; i++)
- if( IsSame(kw->Key, tab[i].Entry) ) {
- *tno = i;
- switch( tab[i].Type ) {
- case None:
- if( kw->vt != None )
- return( 0 );
- break;
- case String:
- if( kw->vt != String )
- return( 0 );
- break;
- case Integer:
- if( kw->vt != String )
- return( 0 );
- if( sscanf(kw->Val,"%ld%c", &(kw->v.i), &c) != 1 || c != '\0' )
- return( 0 );
- break;
- case Number:
- case Dimension:
- if( kw->vt != String )
- return( 0 );
- if( sscanf(kw->Val,"%f%c", &(kw->v.n), &c) != 1 || c != '\0' )
- return( 0 );
- break;
- }
- kw->vt = tab[i].Type;
- return( 1 );
- }
-
- return( 1 );
- }
-
- /*
- * compare strings, ignore case
- */
- int Tolower(c)
- register int c ;
- {
- if ('A' <= c && c <= 'Z')
- return(c+32) ;
- else
- return(c) ;
- }
- int IsSame(a, b)
- char *a, *b;
- {
- for( ; *a != '\0'; )
- if( Tolower(*a++) != Tolower(*b++) )
- return( 0 );
- return( *a == *b ? 1 : 0 );
- }
-
- void pswrite(s)
- char *s ;
- {
- DPSWritePostScript(DPSGetCurrentContext(), s, strlen(s)) ;
- }
-
- void qstatus() ;
-
- /*
- * This routine copies a file down the pipe. Search path uses the
- * header path.
- *
- * We add code to handle the case of MS-DOS font files.
- *
- * Format: 80 {01,02} four byte length in littleendian order data
- * repeated possibly multiple times.
- */
- static char *hxdata = "0123456789ABCDEF" ;
- static int infigure ;
- void
- copyfile(s)
- char *s ;
- {
- FILE *f = NULL ;
- int c, prevc = '\n' ;
- long len ;
- char nextstring[2000] ;
-
- switch (infigure) {
- case 1:
- f = search(inputspath, s, "r") ;
- (void)sprintf(temperrorbuf, "Couldn't open figure file %s", s) ;
- break ;
- default:
- f = search(headerpath, s, "r") ;
- (void)sprintf(temperrorbuf, "Couldn't open header file %s", s) ;
- break ;
- case 2:
- #ifdef SECURE
- (void)sprintf(temperrorbuf, "<%s>: Tick filename execution disabled", s) ;
- #else
- writeconsole(s) ;
- f = popen(s, "r") ;
- (void)sprintf(temperrorbuf, "Failure to execute %s; continuing", s) ;
- #endif
- break;
- }
- if (f==NULL) {
- pswrite(" MockPic ") ;
- /* error(temperrorbuf) ; can't do this; will crash window server to run
- an alert here; no idea why. */
- } else {
- sprintf(temperrorbuf, "Inserting %s", s) ;
- qstatus(temperrorbuf) ;
- c = getc(f) ;
- if (c == 0x80) {
- while (1) {
- char *p = nextstring ;
-
- c = getc(f) ;
- switch(c) {
- case 1:
- case 2:
- len = getc(f) ;
- len += getc(f) * 256L ;
- len += getc(f) * 65536L ;
- len += getc(f) * 256L * 65536 ;
- if (c == 1) {
- while (len > 0) {
- c = getc(f) ;
- if (c == EOF) {
- error("premature EOF in MS-DOS font file") ;
- len = 0 ;
- } else if (c == 10 || c == 13) {
- *p++ = 10 ;
- *p++ = 0 ;
- pswrite(nextstring) ;
- p = nextstring ;
- len-- ;
- } else {
- *p++ = c ;
- len-- ;
- }
- }
- } else {
- if (p > nextstring) {
- *p++ = 10 ;
- *p++ = 0 ;
- pswrite(nextstring) ;
- p = nextstring ;
- }
- prevc = 0 ;
- while (len > 0) {
- c = getc(f) ;
- if (c == EOF) {
- error("premature EOF in MS-DOS font file") ;
- len = 0 ;
- } else {
- *p++ = hxdata[c >> 4] ;
- *p++ = hxdata[c & 15] ;
- len-- ;
- prevc += 2 ;
- if (prevc >= 76) {
- *p++ = 10 ;
- *p = 0 ;
- pswrite(nextstring) ;
- p = nextstring ;
- prevc = 0 ;
- }
- }
- }
- if (prevc) {
- *p++ = 10 ;
- *p = 0 ;
- pswrite(nextstring) ;
- p = nextstring ;
- prevc = 0 ;
- }
- }
- break ;
- case 3:
- goto msdosdone ;
- default:
- error("saw type other than 1, 2, or 3 in MS-DOS font file") ;
- break ;
- }
- c = getc(f) ;
- if (c == EOF)
- break ;
- if (c != 0x80) {
- error("saw non-MSDOS header in MSDOS font file") ;
- break ;
- }
- }
- msdosdone: ;
- } else {
- ungetc(c, f) ;
- while (fgets(nextstring, 2000, f))
- pswrite(nextstring) ;
- }
- if (infigure == 2)
- (void)pclose(f) ;
- else
- (void)fclose(f) ;
- }
- }
-
- /*
- * For included PostScript graphics, we use the above routine, but
- * with no fatal error message.
- */
- void figcopyfile(s, systemtype)
- char *s ;
- int systemtype ;
- {
- infigure = (systemtype ? 2 : 1) ;
- if (mocked)
- pswrite(" MockPic ");
- else
- copyfile(s) ;
- infigure = 0 ;
- }
-
- void cleartheair() {
- outbangspecials() ;
- }
- struct header_list {
- char *name ;
- struct header_list *next ;
- } *header_head ;
- /*
- * The external routines we use.
- */
- extern void copyfile() ;
- #ifdef DEBUG
- extern integer debug_flag ;
- #endif
- /*
- * This more general routine adds a name to a list of unique
- * names.
- */
- int
- add_name(s, what)
- char *s ;
- struct header_list **what ;
- {
- struct header_list *p, *q ;
-
- for (p = *what ; p != NULL; p = p->next)
- if (strcmp(p->name, s)==0)
- return 0 ;
- q = (struct header_list *)malloc((unsigned)sizeof(struct header_list)) ;
- if (q==NULL)
- error("! out of memory") ;
- q->next = NULL ;
- q->name = newstring(s) ;
- if (*what == NULL)
- *what = q ;
- else {
- for (p = *what; p->next != NULL; p = p->next) ;
- p->next = q ;
- }
- return 1 ;
- }
- /*
- * This routine is responsible for adding a header file.
- */
- void add_header(s)
- char *s ;
- {
- if (add_name(s, &header_head))
- copyfile(s) ;
- }
-