home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / d / dvips549.zip / DVIPS / PPRESCAN.C < prev    next >
C/C++ Source or Header  |  1992-10-14  |  9KB  |  259 lines

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