home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD1.bin / useful / text / tex / pastex / archives / dvidvi1_0.lha / DviDvi / dvidvi.c < prev    next >
C/C++ Source or Header  |  1993-07-28  |  33KB  |  1,295 lines

  1. /*
  2.  *   This program converts dvi files to dvi files;
  3.  *   the command line options are:
  4.  *
  5.  *    page n is first page selected          -f n
  6.  *    page n is last page selected          -l n
  7.  *    print at most n pages              -n n
  8.  *    include pages (ranges allowed)        -i { n1..n2 | n1 }[,...]
  9.  *    exclude pages (ranges allowed)        -x { n1..n2 | n1 }[,...]
  10.  *    work in quiet mode              -q
  11.  *    reverse pages                  -r
  12.  *    select even                  -m 2:1
  13.  *    select odd                  -m 2:0
  14.  *    print both on same page           -m 2:0,1(5.5in,0in)
  15.  *    do folded brochures              -m 4:-3,0(5.5in,0in)
  16.  *                          -m 4:1,-2(5.5in,0in)
  17.  *    etc.
  18.  *
  19.  *    scale magnification              -sm m
  20.  *    scale document-width              -sw m
  21.  *    scale document-height              -sh m
  22.  *
  23.  *    The arguments m are instances of magsteps. For example -sm 2
  24.  *    multiplies the document-magnification by magstep(2) (1.44) and
  25.  *    -sw -2 multiplies the document-with by magstep(2) (0.694).
  26.  *
  27.  *    The original program is by Tomas Rokicki (version 0.5) but it was
  28.  *    modified and improved by Esteban ZIMANYI ezimanyi@rc1.vub.ac.be
  29.  *    to give version 1.0.
  30.  *
  31.  *    This version has been tested for the IBM PC and compatibles under
  32.  *    compilers Turbo C 2.0 and Microsoft C 6.0.
  33.  *
  34.  *    The options -sm, -sw and -sh were added by Jochen Wiedmann to support
  35.  *    PasTeX on the Amiga. This was needed because PasTeX doesn't ignore
  36.  *    the Width- and Height-Parameters included in the Postamble. PasTeX
  37.  *    needs them to be rearranged to work fine.
  38.  *
  39.  */
  40. #define SEEK_SET 0
  41. #define SEEK_CUR 1
  42. #define SEEK_END 2
  43.  
  44. #define BANNER "\nThis is dvidvi 1.0, Copyright (C) 1988-91, Radical Eye Software\n"
  45. #define STRINGSIZE (500)  /* maximum number of strings in program */
  46.  
  47. #ifndef VMS
  48. #include <stdio.h>
  49. #include <string.h>
  50. #include <math.h>
  51. #else /* VMS */
  52. #include "sys$library:stdio.h"       /* AKT: added sys$library: */
  53. #include <alloc.h>
  54. #endif /* VMS */
  55. #define MAXPPERP (32)
  56.  
  57. /* defines READBIN, WRITEBIN, PATHSEP and DIRSEP*/
  58.  
  59. #ifdef MSDOS
  60. #define READBIN     "rb"    /* MSDOS must use binary mode */
  61. #define WRITEBIN    "wb"
  62. #define PATHSEP     ';'
  63. #define DIRSEP        '\\'
  64. #else
  65. #ifdef VMS
  66. #define READBIN     "rb"    /* VMS must use binary mode */
  67. #define WRITEBIN    "wb"
  68. #define PATHSEP     ','
  69. #define DIRSEP        ':'
  70. #else
  71. #define READBIN     "r"     /* UNIX doesn't care */
  72. #define WRITEBIN    "w"
  73. #define PATHSEP     ':'
  74. #define DIRSEP        '/'
  75. #endif
  76. #endif
  77.  
  78. #ifdef XENIX
  79. #define SHORTINT
  80. #else
  81. #undef SHORTINT
  82. #endif
  83. #ifdef MSDOS
  84. #define SHORTINT
  85. #endif
  86.  
  87. /*
  88.  *   Type declarations.  integer must be a 32-bit signed; shalfword must
  89.  *   be a sixteen-bit signed; halfword must be a sixteen-bit unsigned;
  90.  *   quarterword must be an eight-bit unsigned.
  91.  */
  92. typedef long integer;
  93. typedef char boolean;
  94. typedef short shalfword ;
  95. typedef unsigned long longword;
  96. typedef unsigned short halfword ;
  97. typedef unsigned char quarterword ;
  98. typedef short Boolean ;
  99.  
  100. /*
  101.  *   Some globals to keep everyone happy.
  102.  */
  103. integer numpages ;    /* the total number of pages in the dvi file. */
  104. integer TeXfonts[256] ; /* information about each font */
  105. char fontseen[256] ; /* have we defined this font yet? */
  106. int modulo ;         /* our mod value */
  107. struct pagespec {
  108.    int pageno, reversed ;
  109.    long hoffset, voffset ; /* in scaled points */
  110. } pages[MAXPPERP] ;  /* the organization of the pages on output */
  111. int pagesperpage ;   /* how many pages crammed onto each page? */
  112. FILE *infile ;         /* input dvi file (cannot be a stream) */
  113. FILE *outfile ;      /* output dvi file */
  114.  
  115. char *temp ;    /* a temporary place to put things */
  116. char *nextstring, *maxstring ;
  117. char *oname ;              /* output dvi file name */
  118. char *iname ;              /* input dvi file name */
  119. char *strings ;           /* pointer of the string pool */
  120.  
  121. char banner[] = BANNER ;      /* the startup message */
  122. integer inlength ;    /* the length of the input dvi file */
  123. integer postloc ;    /* location of the postamble */
  124. integer mag ;        /* magnification factor */
  125. integer pagecount ;    /* number of actual pages */
  126. integer landscape = 0;       /* if landscape special, here it is! */
  127. int rem0special ;    /* should we remove the first first-page special? */
  128. integer prevpp = -1 ;       /* previous page pointer on output */
  129. integer outputpages ;    /* number of pages output */
  130. integer dviloc ;    /* our position in the output file */
  131. integer pagefake ;    /* number of pages, rounded up to multiple of modulo */
  132.  
  133. Boolean firsttransf = 0, lasttransf = 0;
  134. integer firstpage ;    /* first page selected (option -p) */
  135. integer lastpage ;    /* last page selected (option -l) */
  136. integer maxpages ;    /* maximum number of page selected (option -n) */
  137. short quiet ;          /* quiet mode (option -q) */
  138. Boolean exctransf[40][2] ; /* if the ranges of pages to exclude (option -x)
  139.                 have to be transformed */
  140. integer exclude[40][2] ; /* the ranges of pages to exclude (option -x)
  141.              It is supposed that there are at most 40 ranges
  142.              to exclude in the command line */
  143. short excludeseq ;     /* number of ranges to exclude (option -x) */
  144. Boolean inctransf[40][2] ; /* if the ranges of pages to exclude (option -x)
  145.                 have to be transformed */
  146. integer include[40][2] ; /* the ranges of pages to include (option -i)
  147.              It is supposed that there are at most 40 ranges
  148.              to include in the command line */
  149. short includeseq ;     /* number of ranges to include (option -i) */
  150. integer *pageloc ;
  151. integer *pagenumbers ;
  152. int prettycolumn ;     /* the column we are at when running pretty */
  153.  
  154.  
  155. /*  Added 28.07.1993,    Jochen Wiedmann     */
  156. double scale_magstep = 0.0;
  157. double scale_width = 0.0;
  158. double scale_height = 0.0;
  159. /*                        */
  160.  
  161.  
  162. /*
  163.  *   This array holds values that indicate the length of a command, if
  164.  *   we aren't concerned with that command (which is most of them) or
  165.  *   zero, if it is a special case.  This makes running through the
  166.  *   dvi file a lot easier (and probably faster) than any form of
  167.  *   dispatch table, especially since we really don't care what the
  168.  *   pages are made of.
  169.  */
  170. short comlen[256] = {
  171.    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0-15 */
  172.    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 16-31 */
  173.    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 32-47 */
  174.    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 48-63 */
  175.    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 64-79 */
  176.    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80-95 */
  177.    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 96-111 */
  178.    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 112-127 */
  179.    2, 3, 4, 5, 9, 2, 3, 4, 5, 9, 1, 0, 0, 1, 1, 2, /* 128-143 */
  180.    3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 2, 3, 4, /* 144-159 */
  181.    5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, /* 160-175 */
  182.    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 176-191 */
  183.    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 192-207 */
  184.    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 208-223 */
  185.    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 5, 0, /* 224-239 */
  186.    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };/* 240-255 */
  187.  
  188. /*
  189.  *   Input bytes from the dvi file.
  190.  *   These routines could probably be sped up significantly; but they are
  191.  *   very machine dependent, so I will leave such tuning to the installer.
  192.  *   They simply get and return bytes in batches of one, two, three, and four,
  193.  *   updating the current position as necessary.
  194.  */
  195.  
  196. void
  197. abortpage()
  198. {
  199.    error("! unexpected eof on DVI file") ;
  200. }
  201.  
  202. shalfword dvibyte()
  203. {
  204.   register shalfword i ;
  205.   if ((i=getc(infile))==EOF)
  206.     abortpage() ;
  207.   return(i) ;
  208. }
  209.  
  210. halfword  twobytes()
  211. {
  212.   register halfword i ;
  213.   i = dvibyte() ;
  214.   return(i*256+dvibyte()) ; }
  215.  
  216. integer   threebytes()
  217. {
  218.   register integer i ;
  219.   i = twobytes() ;
  220.   return(i*256+dvibyte()) ; }
  221.  
  222. longword  fourbytes()
  223. {
  224.   register longword i;
  225.   i = twobytes();
  226.   return((i<<16)+twobytes());
  227. }
  228.  
  229. shalfword
  230. signedbyte()
  231. {
  232.   register shalfword i ;
  233.   if ((i=getc(infile))==EOF)
  234.     abortpage() ;
  235.   if (i<128) return(i) ;
  236.   else return(i-256) ;
  237. }
  238.  
  239. shalfword
  240. signedpair()
  241. {
  242.   register shalfword i ;
  243.   i = signedbyte() ;
  244.   return(i*256+dvibyte()) ;
  245. }
  246.  
  247. integer
  248. signedtrio()
  249. {
  250.   register integer i ;
  251.   i = signedpair() ;
  252.   return(i*256+dvibyte()) ;
  253. }
  254.  
  255. integer
  256. signedquad()
  257. {
  258.   register integer i ;
  259.   i = signedpair() ;
  260.   return(i*65536+twobytes())