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 >
C/C++ Source or Header  |  1993-08-12  |  18KB  |  653 lines

  1. /*
  2.  *   This routine handles special commands;
  3.  *   predospecial() is for the prescan, dospecial() for the real thing.
  4.  */
  5. #include "dvips.h" /* The copyright notice in that file is included too! */
  6.  
  7. #include <ctype.h>
  8. extern int atoi();
  9. extern void fil2ps();
  10. extern FILE *search();
  11. extern int system();
  12. /*
  13.  *   These are the external routines called:
  14.  */
  15. /**/
  16. #ifdef TPIC
  17. /*
  18.  * Fri Mar  9 1990  jourdan@minos.inria.fr (MJ)
  19.  * Upgraded to accommodate tpic release 2.0 extended output language.
  20.  * Should prove upward compatible!
  21.  */
  22. extern void setPenSize();
  23. extern void flushPath();
  24. extern void flushDashed();
  25. extern void flushDashed();
  26. extern void addPath();
  27. extern void arc();
  28. extern void flushSpline();
  29. extern void shadeLast();
  30. extern void whitenLast();
  31. extern void blackenLast();
  32. extern void SetShade() ;
  33. #endif
  34. extern shalfword dvibyte() ;
  35. extern int add_header() ;
  36. extern void hvpos() ;
  37. extern void figcopyfile() ;
  38. extern void nlcmdout() ;
  39. extern void cmdout() ;
  40. extern void numout() ;
  41. extern void scout() ;
  42. extern void stringend() ;
  43. extern void error() ;
  44. extern void psflush() ;
  45. extern void emspecial() ;
  46. /* IBM: color - begin */
  47. extern void pushcolor() ;
  48. extern void popcolor() ;
  49. extern void resetcolorstack() ;
  50. extern void background() ;
  51. /* IBM: color - end */
  52. extern char errbuf[] ;
  53. extern shalfword linepos;
  54. extern Boolean usesspecial ;
  55. extern Boolean usescolor ;   /* IBM: color */
  56. extern int landscape ;
  57. extern char *paperfmt ;
  58. extern char *nextstring;
  59. extern char *maxstring;
  60. extern char *oname;
  61. extern FILE *bitfile;
  62. extern int quiet;
  63. extern fontdesctype *curfnt ;
  64. extern int actualdpi ;
  65. extern int vactualdpi ;
  66. extern integer hh, vv;
  67. extern int lastfont ;
  68. extern real conv ;
  69. extern real vconv ;
  70. extern integer hpapersize, vpapersize ;
  71. extern Boolean pprescan ;
  72. extern char *figpath ;
  73. extern int prettycolumn ;
  74. extern Boolean disablecomments ;
  75.  
  76. #ifdef DEBUG
  77. extern integer debug_flag;
  78. #endif
  79. extern void scanfontcomments() ;
  80. extern void handlepapersize() ;
  81.  
  82. static int specialerrors = 20 ;
  83.  
  84. struct bangspecial {
  85.    struct bangspecial *next ;
  86.    char actualstuff[1] ; /* more space will actually be allocated */
  87. } *bangspecials = NULL ;
  88.  
  89. void specerror(s)
  90. char *s ;
  91. {
  92.    if (specialerrors > 0) {
  93.       error(s) ;
  94.       specialerrors-- ;
  95.    } else if (specialerrors == 0) {
  96.       error("more errors in special, being ignored . . .") ;
  97.       specialerrors-- ;
  98.    }
  99. }
  100.  
  101. static void trytobreakout(p)
  102. register char *p ;
  103. {
  104.    register int i ;
  105.    register int instring = 0 ;
  106.    int lastc = 0 ;
  107.  
  108.    i = 0 ;
  109.    (void)putc('\n', bitfile) ;
  110.    while (*p) {
  111.       if (i > 65 && *p == ' ' && instring == 0) {
  112.          (void)putc('\n', bitfile) ;
  113.          i = 0 ;
  114.       } else {
  115.          (void)putc(*p, bitfile) ;
  116.          i++ ;
  117.       }
  118.       if (*p == '(' && lastc != '\\')
  119.          instring = 1 ;
  120.       else if (*p == ')' && lastc != '\\')
  121.          instring = 0 ;
  122.       lastc = *p ;
  123.       p++ ;
  124.    }
  125.    (void)putc('\n', bitfile) ;
  126. }
  127.  
  128. static void dobs(q)
  129. register struct bangspecial *q ;
  130. {
  131.    if (q) {
  132.       dobs(q->next) ;
  133.       trytobreakout(q->actualstuff) ;
  134.    }
  135. }
  136.  
  137. void
  138. outbangspecials() {
  139.    if (bangspecials) {
  140.       cmdout("TeXDict") ;
  141.       cmdout("begin") ;
  142.       cmdout("@defspecial\n") ;
  143.       dobs(bangspecials) ;
  144.       cmdout("\n@fedspecial") ;
  145.       cmdout("end") ;
  146.    }
  147. }
  148.  
  149. /* We recommend that new specials be handled by the following general
  150.  * (and extensible) scheme, in which the user specifies one or more
  151.  * `key=value' pairs separated by spaces.
  152.  * The known keys are given in KeyTab; they take values
  153.  * of one of the following types:
  154.  *
  155.  * None: no value, just a keyword (in which case the = sign is omitted)
  156.  * String: the value should be "<string without double-quotes"
  157.  *                          or '<string without single-quotes'
  158.  * Integer: the value should be a decimal integer (%d format)
  159.  * Number: the value should be a decimal integer or real (%f format)
  160.  * Dimension: like Number, but will be multiplied by the scaledsize
  161.  *       of the current font and converted to default PostScript units
  162.  * (Actually, strings are allowed in all cases; the delimiting quotes
  163.  *  are simply stripped off if present.)
  164.  *
  165.  */
  166.  
  167. typedef enum {None, String, Integer, Number, Dimension} ValTyp;
  168. typedef struct {
  169.    char    *Entry;
  170.    ValTyp  Type;
  171. } KeyDesc;
  172.  
  173. #define NKEYS    (sizeof(KeyTab)/sizeof(KeyTab[0]))
  174.  
  175. KeyDesc KeyTab[] = {{"psfile",  String}, /* j==0 in the routine below */
  176.                     {"ifffile", String}, /* j==1 */
  177.                     {"tekfile", String}, /* j==2 */
  178.                     {"hsize",   Number},
  179.                     {"vsize",   Number},
  180.                     {"hoffset", Number},
  181.                     {"voffset", Number},
  182.                     {"hscale",  Number},
  183.                     {"vscale",  Number},
  184.                     {"angle",   Number},
  185.                     {"llx", Number},
  186.                     {"lly", Number},
  187.                     {"urx", Number},
  188.                     {"ury", Number},
  189.                     {"rwi", Number},
  190.                     {"rhi", Number},
  191.                     {"clip", None}};
  192.  
  193. #ifdef VMS
  194. #ifndef __GNUC__    /* GNUC tolower is too simple */
  195. #define Tolower tolower
  196. #endif
  197. #else
  198. #ifdef VMCMS    /* IBM: VM/CMS */
  199. #define Tolower __tolower
  200. #else
  201. #ifdef MVSXA    /* IBM: MVS/XA */
  202. #define Tolower __tolower
  203. #else
  204. /*
  205.  * compare strings, ignore case
  206.  */
  207. char Tolower(c)
  208. register char c ;
  209. {
  210.    if ('A' <= c && c <= 'Z')
  211.       return(c+32) ;
  212.    else
  213.       return(c) ;
  214. }
  215. #endif
  216. #endif  /* IBM: VM/CMS */
  217. #endif
  218. int IsSame(a, b)
  219. char *a, *b;
  220. {
  221.    for( ; *a != '\0'; ) {
  222.       if( Tolower(*a) != Tolower(*b) ) 
  223.          return( 0 );
  224.       a++ ;
  225.       b++ ;
  226.    }
  227.    return( *b == '\0' );
  228. }
  229.  
  230. char *KeyStr, *ValStr ; /* Key and String values found */
  231. long ValInt ; /* Integer value found */
  232. float ValNum ; /* Number or Dimension value found */
  233.  
  234. char  *GetKeyVal(str,tno) /* returns NULL if none found, else next scan point */
  235.    char *str ; /* starting point for scan */
  236.    int  *tno ; /* table entry number of keyword, or -1 if keyword not found */
  237. {
  238.    register char *s ;
  239.    register int i ;
  240.    register char t ;
  241.  
  242.    for (s=str; *s <= ' ' && *s; s++) ; /* skip over blanks */
  243.    if (*s == '\0')
  244.       return (NULL) ;
  245.    KeyStr = s ;
  246.    while (*s>' ' && *s!='=') s++ ;
  247.    if (0 != (t = *s))
  248.       *s++ = 0 ;
  249.  
  250.    for(i=0; i<NKEYS; i++)
  251.       if( IsSame(KeyStr, KeyTab[i].Entry) )
  252.          goto found ;
  253.    *tno = -1;
  254.    return (s) ;
  255.  
  256. found: *tno = i ;
  257.    if (KeyTab[i].Type == None)
  258.       return (s) ;
  259.  
  260.    if (t && t <= ' ') {
  261.       for (; *s <= ' ' && *s; s++) ; /* now look for the value part */
  262.       if ((t = *s)=='=')
  263.          s++ ;
  264.    }
  265.    ValStr = "" ;
  266.    if ( t == '=' ) {
  267.       while (*s <= ' ' && *s)
  268.          s++ ;
  269.       if (*s=='\'' || *s=='\"')
  270.          t = *s++ ;               /* get string delimiter */
  271.       else t = ' ' ;
  272.       ValStr = s ;
  273.       while (*s!=t && *s)
  274.          s++ ;
  275.       if (*s)
  276.          *s++ = 0 ;
  277.    }
  278.    switch (KeyTab[i].Type) {
  279.  case Integer:
  280.       if(sscanf(ValStr,"%ld",&ValInt)!=1) {
  281.           sprintf(errbuf,"Non-integer value (%s) given for keyword %s",
  282.               ValStr, KeyStr) ;
  283.           specerror(errbuf) ;
  284.           ValInt = 0 ;
  285.       }
  286.       break ;
  287.  case Number:
  288.  case Dimension:
  289.       if(sscanf(ValStr,"%f",&ValNum)!=1) {  
  290.           sprintf(errbuf,"Non-numeric value (%s) given for keyword %s",
  291.               ValStr, KeyStr) ;
  292.           specerror(errbuf) ;
  293.           ValNum = 0.0 ;
  294.       }
  295.       if (KeyTab[i].Type==Dimension) {
  296.          if (curfnt==NULL)
  297.             error("! No font selected") ;
  298.          ValNum = ValNum * ((double)curfnt->scaledsize) * conv * 72 / DPI ;
  299.       }
  300.       break ;
  301.  default: break ;
  302.    }
  303.    return (s) ;
  304. }
  305.  
  306. /*
  307.  *   Now our routines.  We get the number of bytes specified and place them
  308.  *   into the string buffer, and then parse it. Numerous conventions are
  309.  *   supported here for historical reasons.
  310.  */
  311.  
  312. void predospecial(numbytes, scanning)
  313. integer numbytes ;
  314. Boolean scanning ;
  315. {
  316.    register char *p = nextstring ;
  317.    register int i = 0 ;
  318.    int j ;
  319.  
  320.    if (nextstring + numbytes > maxstring)
  321.       error("! out of string space in predospecial") ;
  322.    for (i=numbytes; i>0; i--)
  323. #ifdef VMCMS /* IBM: VM/CMS */
  324.       *p++ = ascii2ebcdic