home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 3 / Meeting_Pearls_III.iso / Pearls / texmf / source / dvips / pprescan.c < prev    next >
C/C++ Source or Header  |  1994-03-29  |  9KB  |  286 lines

  1. /*
  2.  *   This is the main routine for the first (prescanning) pass.
  3.  */
  4. #include "dvips.h" /* The copyright notice in that file is included too! */
  5. /*
  6.  *   These are all the external routines it calls:
  7.  */
  8. #ifdef AMIGA
  9. #include "pprescan_protos.h"
  10. #include "dviinput_protos.h"
  11. #include "fontdef_protos.h"
  12. #include "resident_protos.h"
  13. #include "virtualfont_protos.h"
  14. #include "dvips_protos.h"
  15. #include "repack_protos.h"
  16. #include "skippage_protos.h"
  17. #include "prescan_protos.h"
  18. #include "dospecial_protos.h"
  19. #include "color_protos.h"
  20. #include "dosection_protos.h"
  21. static void ppreselectfont(fontdesctype *);
  22. static void pscanpage(void);
  23. #else
  24. extern shalfword dvibyte() ;
  25. extern halfword twobytes() ;
  26. extern integer threebytes() ;
  27. extern integer signedquad() ;
  28. extern shalfword signedbyte() ;
  29. extern shalfword signedpair() ;
  30. extern integer signedtrio() ;
  31. extern void skipover() ;
  32. extern void fontdef() ;
  33. extern void predospecial() ;
  34. extern int residentfont() ;
  35. extern Boolean virtualfont() ;
  36. extern void error() ;
  37. extern long getlong() ;
  38. extern int skipnop() ;
  39. extern void skippage() ;
  40. extern void readpreamble() ;
  41. extern void bopcolor() ;
  42. extern int InPageList() ;
  43. #endif
  44. /*
  45.  *   These are the globals it accesses.
  46.  */
  47. #ifdef DEBUG
  48. extern integer debug_flag;
  49. #endif  /* DEBUG */
  50. extern fontdesctype *fonthead ;
  51. extern integer firstpage, lastpage ;
  52. extern integer firstseq, lastseq ;
  53. extern Boolean notfirst, notlast ;
  54. extern Boolean evenpages, oddpages, pagelist ;
  55. extern integer maxpages ;
  56. extern Boolean abspage ;
  57. extern FILE *dvifile ;
  58. extern fontdesctype *curfnt ;
  59. extern fontdesctype *baseFonts[] ;
  60. extern fontmaptype *ffont ;
  61. extern quarterword *curpos, *curlim ;
  62. extern integer pagenum ;
  63. extern char errbuf[] ;
  64. extern frametype frames[] ;
  65. /*
  66.  *  We declare this to tell everyone we are prescanning early.
  67.  */
  68. Boolean pprescan ;
  69. /*
  70.  * When a font is selected during the pre-prescan, this routine makes sure
  71.  * that the tfm or vf (but not pk) file is loaded.
  72.  */
  73. static void
  74. ppreselectfont(f)
  75. fontdesctype *f ;
  76. {
  77.    int i ;
  78.  
  79.    curfnt = f ;
  80.    if (curfnt->loaded == 0) {
  81.       if (!residentfont(curfnt))
  82.          if (!virtualfont(curfnt)) {
  83.             for (i=0; i<256; i++)
  84.                curfnt->chardesc[i].flags = 0 ;
  85.             curfnt->loaded = 3 ; /* we're scanning for sizes */
  86.          }
  87.    }
  88. }
  89. /*
  90.  *   Now our scanpage routine.
  91.  */
  92. static void
  93. pscanpage()
  94. {
  95.    register shalfword cmd ;
  96.    register chardesctype *cd ;
  97.    register fontmaptype *cfnt = 0 ;
  98.    integer fnt ;
  99.    register frametype *frp = frames ;
  100.  
  101. #ifdef DEBUG
  102.    if (dd(D_PAGE))
  103. #ifdef SHORTINT
  104.    (void)fprintf(stderr,"PPrescanning page %ld\n", pagenum) ;
  105. #else   /* ~SHORTINT */
  106.    (void)fprintf(stderr,"PPrescanning page %d\n", pagenum) ;
  107. #endif  /* ~SHORTINT */
  108. #endif  /* DEBUG */
  109.    curfnt = NULL ;
  110.    curpos = NULL ;
  111.    bopcolor(0) ;
  112.    while (1) {
  113.       switch (cmd=dvibyte()) {
  114. case 129: case 130: case 131: case 134: case 135: case 136: case 139:
  115. case 247: case 248: case 249: case 250: case 251: case 252: case 253:
  116. case 254: case 255: /* unimplemented or illegal commands */
  117.          (void)sprintf(errbuf,
  118.             "! DVI file contains unexpected command (%d)",cmd) ;
  119.          error(errbuf) ;
  120. case 132: case 137: /* eight-byte commands setrule, putrule */
  121.          (void)dvibyte() ;
  122.          (void)dvibyte() ;
  123.          (void)dvibyte() ;
  124.          (void)dvibyte() ;
  125. case 146: case 151: case 156: case 160: case 165: case 170:
  126.    /* four-byte commands right4, w4, x4, down4, y4, z4 */
  127.          (void)dvibyte() ;
  128. case 145: case 150: case 155: case 159: case 164: case 169:
  129.    /* three-byte commands right3, w3, x3, down3, y3, z3 */
  130.          (void)dvibyte() ;
  131. case 144: case 149: case 154: case 158: case 163: case 168:
  132.    /* two-byte commands right2, w2, x2, down2, y2, z2 */
  133.          (void)dvibyte() ;
  134. case 143: case 148: case 153: case 157: case 162: case 167:
  135.    /* one-byte commands right1, w1, x1, down1, y1, z1 */
  136.          (void)dvibyte() ;
  137. case 147: case 152: case 161: case 166: /* w0, x0, y0, z0 */
  138. case 138: case 141: case 142: /* nop, push, pop */
  139.          break ;
  140. case 133: case 128: cmd = dvibyte() ; /* set1 commands drops through */
  141. default:    /* these are commands 0 (setchar0) thru 127 (setchar 127) */
  142.          if (curfnt==NULL)
  143.             error("! Bad DVI file: no font selected") ;
  144.          if (curfnt->loaded == 2) { /* scanning a virtual font character */
  145.             frp->curp = curpos ;
  146.             frp->curl = curlim ;
  147.             frp->ff = ffont ;
  148.             frp->curf = curfnt ;
  149.             if (++frp == &frames[MAXFRAME] )
  150.                error("! virtual recursion stack overflow") ;
  151.             cd = curfnt->chardesc + cmd ;
  152.             if (cd->packptr == 0)
  153.     error("! a non-existent virtual char is being used; check vf/tfm files") ;
  154.             curpos = cd->packptr + 2 ;
  155.             curlim = curpos + (256*(long)(*cd->packptr)+(*(cd->packptr+1))) ;
  156.             ffont = curfnt->localfonts ;
  157.             if (ffont==NULL)
  158.                curfnt = NULL ;
  159.             else
  160.                ppreselectfont(ffont->desc) ;
  161.          } else if (curfnt->loaded == 3)
  162.             curfnt->chardesc[cmd].flags = EXISTS ;
  163.          break ;
  164. case 171: case 172: case 173: case 174: case 175: case 176: case 177:
  165. case 178: case 179: case 180: case 181: case 182: case 183: case 184:
  166. case 185: case 186: case 187: case 188: case 189: case 190: case 191:
  167. case 192: case 193: case 194: case 195: case 196: case 197: case 198:
  168. case 199: case 200: case 201: case 202: case 203: case 204: case 205:
  169. case 206: case 207: case 208: case 209: case 210: case 211: case 212:
  170. case 213: case 214: case 215: case 216: case 217: case 218: case 219:
  171. case 220: case 221: case 222: case 223: case 224: case 225: case 226:
  172. case 227: case 228: case 229: case 230: case 231: case 232: case 233:
  173. case 234: case 235: case 236: case 237: case 238: /* font selection commands */
  174.          if (cmd < 235) fnt = cmd - 171 ; /* fntnum0 thru fntnum63 */
  175.          else {
  176.             fnt = dvibyte() ; /* fnt1 */
  177.             while (cmd-- > 235)
  178.                fnt = (fnt << 8) + dvibyte() ;
  179.          }
  180.          if (curpos || fnt > 255) {
  181.             for (cfnt=ffont; cfnt; cfnt = cfnt->next)
  182.                if (cfnt->fontnum == fnt) goto fontfound ;
  183.          } else
  184.             if (0 != (curfnt = baseFonts[fnt]))
  185.                goto fontfound2 ;
  186.             error("! no font selected") ;
  187. fontfound:  curfnt = cfnt->desc ;
  188. fontfound2: ppreselectfont(curfnt) ;
  189.             break ;
  190. case 239: predospecial((integer)dvibyte(), 1) ; break ; /* xxx1 */
  191. case 240: predospecial((integer)twobytes(), 1) ; break ; /* xxx2 */
  192. case 241: predospecial(threebytes(), 1) ; break ; /* xxx3 */
  193. case 242: predospecial(signedquad(), 1) ; break ; /* xxx4 */
  194. case 243: case 244: case 245: case 246: fontdef(cmd-242) ; break ; /* fntdef1 */
  195. case 140: /* eop or end of virtual char */
  196.          if (curpos) {
  197.             --frp ;
  198.             curfnt = frp->curf ;
  199.             ffont = frp->ff ;
  200.             curlim = frp->curl ;
  201.             curpos = frp->curp ;
  202.             break ;
  203.          }
  204.          return ;
  205.       }
  206.    }
  207. }
  208. /*
  209.  *   Finally, here's our main pprescan routine.
  210.  */
  211. static integer firstmatch = -1, lastmatch = -1 ;
  212. void
  213. pprescanpages()
  214. {
  215.    register int cmd ;
  216.    integer lmaxpages = maxpages ;
  217.    integer mpagenum ;
  218.    integer pageseq = 0 ;
  219.    int ntfirst = notfirst ;
  220.  
  221.    pprescan = 1 ;
  222.    readpreamble() ;
  223. /*
  224.  *   Now we look for the first page to process.  If we get to the end of
  225.  *   the file before the page, we complain (fatally).
  226.  *   Incidentally, we don't use the DVI file's bop backpointer to skip
  227.  *   over pages at high speed, because we want to look to for special
  228.  *   header that might be in skipped pages.
  229.  */
  230.    while (1) {
  231.       cmd = skipnop() ;
  232.       if (cmd==248)
  233.          error("! End of document before first specified page") ;
  234.       if (cmd!=139)
  235.          error("! Bad DVI file: expected bop") ;
  236.       pagenum = signedquad() ;
  237.       pageseq++ ;
  238.       mpagenum = abspage ? pageseq : pagenum ;
  239.       if (mpagenum == firstpage && ntfirst)
  240.          firstmatch++ ;
  241.       if (mpagenum == lastpage && notlast)
  242.          lastmatch++ ;
  243.       if (ntfirst && mpagenum == firstpage && firstmatch == firstseq)
  244.          ntfirst = 0 ;
  245.       if (ntfirst ||
  246.       ((evenpages && (pagenum & 1)) || (oddpages && (pagenum & 1)==0) ||
  247.        (pagelist && !InPageList(pagenum)))) {
  248.          skipover(40) ;
  249.          skippage() ;
  250.       } else {
  251.          if (notlast && mpagenum == lastpage)
  252.             lastmatch-- ;
  253.          break ;
  254.       }
  255.    }
  256. /*
  257.  *   Here we scan for each of the sections.  First we initialize some of
  258.  *   the variables we need.  We don't have to be as smart as before in
  259.  *   skipping pages.
  260.  */
  261.    skipover(40) ;
  262.    while (lmaxpages > 0) {
  263.       if (!(evenpages && (pagenum & 1)) &&
  264.          !(oddpages && (pagenum & 1)==0) &&
  265.          !(pagelist && !InPageList(pagenum))) {
  266.          pscanpage() ;
  267.          lmaxpages-- ;
  268.       } else
  269.          skippage() ;
  270.       mpagenum = abspage ? pageseq : pagenum ;
  271.       if (mpagenum == lastpage && notlast)
  272.          lastmatch++ ;
  273.       if (notlast && mpagenum == lastpage && lastmatch == lastseq)
  274.          lmaxpages = -1 ; /* we are done after this page. */
  275.       cmd=skipnop() ;
  276.       if (cmd==248) break ;
  277.       if (cmd!=139)
  278.          error("! Bad DVI file: expected bop") ;
  279.       pagenum = signedquad() ;
  280.       skipover(40) ;
  281.       pageseq++ ;
  282.    }
  283.    fseek(dvifile, 0L, 0) ;
  284.    pprescan = 0 ;
  285. }
  286.