home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fonts 1
/
freshfonts1.bin
/
bbs
/
programs
/
amiga
/
pastex13.lha
/
DVIPS
/
dvips5519.lha
/
dvips
/
dospecial.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-12
|
18KB
|
653 lines
/*
* This routine handles special commands;
* predospecial() is for the prescan, dospecial() for the real thing.
*/
#include "dvips.h" /* The copyright notice in that file is included too! */
#include <ctype.h>
extern int atoi();
extern void fil2ps();
extern FILE *search();
extern int system();
/*
* These are the external routines called:
*/
/**/
#ifdef TPIC
/*
* Fri Mar 9 1990 jourdan@minos.inria.fr (MJ)
* Upgraded to accommodate tpic release 2.0 extended output language.
* Should prove upward compatible!
*/
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();
extern void SetShade() ;
#endif
extern shalfword dvibyte() ;
extern int add_header() ;
extern void hvpos() ;
extern void figcopyfile() ;
extern void nlcmdout() ;
extern void cmdout() ;
extern void numout() ;
extern void scout() ;
extern void stringend() ;
extern void error() ;
extern void psflush() ;
extern void emspecial() ;
/* IBM: color - begin */
extern void pushcolor() ;
extern void popcolor() ;
extern void resetcolorstack() ;
extern void background() ;
/* IBM: color - end */
extern char errbuf[] ;
extern shalfword linepos;
extern Boolean usesspecial ;
extern Boolean usescolor ; /* IBM: color */
extern int landscape ;
extern char *paperfmt ;
extern char *nextstring;
extern char *maxstring;
extern char *oname;
extern FILE *bitfile;
extern int quiet;
extern fontdesctype *curfnt ;
extern int actualdpi ;
extern int vactualdpi ;
extern integer hh, vv;
extern int lastfont ;
extern real conv ;
extern real vconv ;
extern integer hpapersize, vpapersize ;
extern Boolean pprescan ;
extern char *figpath ;
extern int prettycolumn ;
extern Boolean disablecomments ;
#ifdef DEBUG
extern integer debug_flag;
#endif
extern void scanfontcomments() ;
extern void handlepapersize() ;
static int specialerrors = 20 ;
struct bangspecial {
struct bangspecial *next ;
char actualstuff[1] ; /* more space will actually be allocated */
} *bangspecials = NULL ;
void specerror(s)
char *s ;
{
if (specialerrors > 0) {
error(s) ;
specialerrors-- ;
} else if (specialerrors == 0) {
error("more errors in special, being ignored . . .") ;
specialerrors-- ;
}
}
static void trytobreakout(p)
register char *p ;
{
register int i ;
register int instring = 0 ;
int lastc = 0 ;
i = 0 ;
(void)putc('\n', bitfile) ;
while (*p) {
if (i > 65 && *p == ' ' && instring == 0) {
(void)putc('\n', bitfile) ;
i = 0 ;
} else {
(void)putc(*p, bitfile) ;
i++ ;
}
if (*p == '(' && lastc != '\\')
instring = 1 ;
else if (*p == ')' && lastc != '\\')
instring = 0 ;
lastc = *p ;
p++ ;
}
(void)putc('\n', bitfile) ;
}
static void dobs(q)
register struct bangspecial *q ;
{
if (q) {
dobs(q->next) ;
trytobreakout(q->actualstuff) ;
}
}
void
outbangspecials() {
if (bangspecials) {
cmdout("TeXDict") ;
cmdout("begin") ;
cmdout("@defspecial\n") ;
dobs(bangspecials) ;
cmdout("\n@fedspecial") ;
cmdout("end") ;
}
}
/* We recommend that new specials be handled by the following general
* (and extensible) scheme, in which the user specifies one or more
* `key=value' pairs separated by spaces.
* The known keys are given in KeyTab; they take values
* of one of the following types:
*
* None: no value, just a keyword (in which case the = sign is omitted)
* String: the value should be "<string without double-quotes"
* or '<string without single-quotes'
* Integer: the value should be a decimal integer (%d format)
* Number: the value should be a decimal integer or real (%f format)
* Dimension: like Number, but will be multiplied by the scaledsize
* of the current font and converted to default PostScript units
* (Actually, strings are allowed in all cases; the delimiting quotes
* are simply stripped off if present.)
*
*/
typedef enum {None, String, Integer, Number, Dimension} ValTyp;
typedef struct {
char *Entry;
ValTyp Type;
} KeyDesc;
#define NKEYS (sizeof(KeyTab)/sizeof(KeyTab[0]))
KeyDesc KeyTab[] = {{"psfile", String}, /* j==0 in the routine below */
{"ifffile", String}, /* j==1 */
{"tekfile", String}, /* j==2 */
{"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}};
#ifdef VMS
#ifndef __GNUC__ /* GNUC tolower is too simple */
#define Tolower tolower
#endif
#else
#ifdef VMCMS /* IBM: VM/CMS */
#define Tolower __tolower
#else
#ifdef MVSXA /* IBM: MVS/XA */
#define Tolower __tolower
#else
/*
* compare strings, ignore case
*/
char Tolower(c)
register char c ;
{
if ('A' <= c && c <= 'Z')
return(c+32) ;
else
return(c) ;
}
#endif
#endif /* IBM: VM/CMS */
#endif
int IsSame(a, b)
char *a, *b;
{
for( ; *a != '\0'; ) {
if( Tolower(*a) != Tolower(*b) )
return( 0 );
a++ ;
b++ ;
}
return( *b == '\0' );
}
char *KeyStr, *ValStr ; /* Key and String values found */
long ValInt ; /* Integer value found */
float ValNum ; /* Number or Dimension value found */
char *GetKeyVal(str,tno) /* returns NULL if none found, else next scan point */
char *str ; /* starting point for scan */
int *tno ; /* table entry number of keyword, or -1 if keyword not found */
{
register char *s ;
register int i ;
register char t ;
for (s=str; *s <= ' ' && *s; s++) ; /* skip over blanks */
if (*s == '\0')
return (NULL) ;
KeyStr = s ;
while (*s>' ' && *s!='=') s++ ;
if (0 != (t = *s))
*s++ = 0 ;
for(i=0; i<NKEYS; i++)
if( IsSame(KeyStr, KeyTab[i].Entry) )
goto found ;
*tno = -1;
return (s) ;
found: *tno = i ;
if (KeyTab[i].Type == None)
return (s) ;
if (t && t <= ' ') {
for (; *s <= ' ' && *s; s++) ; /* now look for the value part */
if ((t = *s)=='=')
s++ ;
}
ValStr = "" ;
if ( t == '=' ) {
while (*s <= ' ' && *s)
s++ ;
if (*s=='\'' || *s=='\"')
t = *s++ ; /* get string delimiter */
else t = ' ' ;
ValStr = s ;
while (*s!=t && *s)
s++ ;
if (*s)
*s++ = 0 ;
}
switch (KeyTab[i].Type) {
case Integer:
if(sscanf(ValStr,"%ld",&ValInt)!=1) {
sprintf(errbuf,"Non-integer value (%s) given for keyword %s",
ValStr, KeyStr) ;
specerror(errbuf) ;
ValInt = 0 ;
}
break ;
case Number:
case Dimension:
if(sscanf(ValStr,"%f",&ValNum)!=1) {
sprintf(errbuf,"Non-numeric value (%s) given for keyword %s",
ValStr, KeyStr) ;
specerror(errbuf) ;
ValNum = 0.0 ;
}
if (KeyTab[i].Type==Dimension) {
if (curfnt==NULL)
error("! No font selected") ;
ValNum = ValNum * ((double)curfnt->scaledsize) * conv * 72 / DPI ;
}
break ;
default: break ;
}
return (s) ;
}
/*
* Now our routines. We get the number of bytes specified and place them
* into the string buffer, and then parse it. Numerous conventions are
* supported here for historical reasons.
*/
void predospecial(numbytes, scanning)
integer numbytes ;
Boolean scanning ;
{
register char *p = nextstring ;
register int i = 0 ;
int j ;
if (nextstring + numbytes > maxstring)
error("! out of string space in predospecial") ;
for (i=numbytes; i>0; i--)
#ifdef VMCMS /* IBM: VM/CMS */
*p++ = ascii2ebcdic