home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 3.3J / os33j.iso / NextLibrary / TeX / tex / src / dvips / prescan.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-27  |  9.1 KB  |  290 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. extern void error() ;
  9. extern shalfword dvibyte() ;
  10. extern integer signedquad() ;
  11. extern int skipnop() ;
  12. extern void skipover() ;
  13. extern short scanpage() ;
  14. extern void skippage() ;
  15. extern int InPageList() ;
  16. /*
  17.  *   These are the globals it accesses.
  18.  */
  19. #ifdef DEBUG
  20. extern integer debug_flag;
  21. #endif  /* DEBUG */
  22. extern fontdesctype *fonthead ;
  23. extern real conv ;
  24. extern real vconv ;
  25. extern real alpha ;
  26. extern integer firstpage, lastpage ;
  27. extern integer firstseq, lastseq ;
  28. extern integer maxsecsize ;
  29. extern Boolean notfirst, notlast ;
  30. extern Boolean evenpages, oddpages, pagelist ;
  31. extern integer fontmem ;
  32. extern integer pagecount ;
  33. extern integer pagenum ;
  34. extern integer maxpages ;
  35. extern sectiontype *sections ;
  36. extern FILE *dvifile ;
  37. extern integer num, den, mag ;
  38. extern int overridemag ;
  39. extern integer swmem ;
  40. extern int quiet ;
  41. extern int actualdpi ;
  42. extern int vactualdpi ;
  43. extern Boolean reverse ;
  44. extern int totalpages ;
  45. extern integer fsizetol ;
  46. extern char *oname ;
  47. extern Boolean pprescan ;
  48. extern Boolean abspage ;
  49. extern char preamblecomment[] ;
  50. /*
  51.  *   This routine handles the processing of the preamble in the dvi file.
  52.  */
  53. void
  54. readpreamble()
  55. {
  56.    register int i ;
  57.    char *p ;
  58.  
  59.    if (dvibyte()!=247) error("! Bad DVI file: first byte not preamble") ;
  60.    if (dvibyte()!=2) error("! Bad DVI file: id byte not 2") ;
  61.    num = signedquad() ;
  62.    den = signedquad() ;
  63.    if (overridemag > 0) (void)signedquad() ;
  64.    else if (overridemag < 0) mag = (mag * signedquad() + 500) / 1000 ;
  65.    else mag = signedquad() ;
  66.    conv = (real) num * DPI * (real) mag / ( den * 254000000.0 ) ; 
  67.    vconv = (real) num * VDPI * (real) mag / ( den * 254000000.0 ) ; 
  68.    alpha = (((real)den / 7227.0) / 0x100000) * (25400000.0 / (real) num) ;
  69.    fsizetol = 1 + (integer)(DPI/(72270.0 * conv)) ;
  70.    if (!pprescan) {
  71.      for (i=dvibyte(),p=preamblecomment;i>0;i--,p++) *p=dvibyte() ;
  72.      *p='\0' ;
  73.      if (!quiet) {
  74.         (void)fprintf(stderr, "'") ;
  75. #ifdef VMCMS /* IBM: VM/CMS */
  76.         for(p=preamblecomment;*p;p++) (void)putc(ascii2ebcdic[*p], stderr) ;
  77. #else
  78. #ifdef MVSXA /* IBM: MVS/XA */
  79.         for(p=preamblecomment;*p;p++) (void)putc(ascii2ebcdic[*p], stderr) ;
  80. #else
  81.         for(p=preamblecomment;*p;p++) (void)putc(*p, stderr) ;
  82. #endif  /* IBM: VM/CMS */
  83. #endif
  84.         (void)fprintf(stderr, "' -> %s\n", oname) ;
  85.       }
  86.    } else
  87.       skipover(dvibyte()) ;
  88. }
  89.  
  90. /*
  91.  *   Finally, here's our main prescan routine.
  92.  */
  93. static integer firstmatch = -1, lastmatch = -1 ;
  94. void
  95. prescanpages()
  96. {
  97.    register int cmd ;
  98.    short ret = 0 ;
  99.    register integer thispageloc, thissecloc ;
  100.    register fontdesctype *f ;
  101.    register shalfword c ;
  102.    register long thissectionmem = 0 ;
  103.    integer mpagenum ;
  104.    integer pageseq = 0 ;
  105.  
  106.    readpreamble() ;
  107. /*
  108.  *   Now we look for the first page to process.  If we get to the end of
  109.  *   the file before the page, we complain (fatally).
  110.  *   Incidentally, we don't use the DVI file's bop backpointer to skip
  111.  *   over pages at high speed, because we want to look to for special
  112.  *   header that might be in skipped pages.
  113.  */
  114.    while (1) {
  115.       cmd = skipnop() ;
  116.       if (cmd==248)
  117.          error("! End of document before first specified page") ;
  118.       if (cmd!=139)
  119.          error("! Bad DVI file: expected bop") ;
  120.       thispageloc = ftell(dvifile) ; /* the location FOLLOWING the bop */
  121. #ifdef DEBUG
  122.       if (dd(D_PAGE))
  123. #ifdef SHORTINT
  124.       (void)fprintf(stderr,"bop at %ld\n", thispageloc) ;
  125. #else   /* ~SHORTINT */
  126.       (void)fprintf(stderr,"bop at %d\n", (int)thispageloc) ;
  127. #endif  /* ~SHORTINT */
  128. #endif  /* DEBUG */
  129.       pagenum = signedquad() ;
  130.       pageseq++ ;
  131.       mpagenum = abspage ? pageseq : pagenum ;
  132.       if (mpagenum == firstpage && notfirst)
  133.          firstmatch++ ;
  134.       if (mpagenum == lastpage && notlast)
  135.          lastmatch++ ;
  136.       if ((notfirst && (mpagenum != firstpage || firstmatch != firstseq)) ||
  137.       ((evenpages && (pagenum & 1)) || (oddpages && (pagenum & 1)==0) ||
  138.        (pagelist && !InPageList(pagenum)))) {
  139.          skipover(40) ;
  140.          skippage() ;
  141.       } else {
  142.          if (notlast && mpagenum == lastpage)
  143.             lastmatch-- ;
  144.          break ;
  145.       }
  146.    }
  147. /*
  148.  *   Here we scan for each of the sections.  First we initialize some of
  149.  *   the variables we need.
  150.  */
  151.    while (maxpages > 0 && cmd != 248) {
  152.       for (f=fonthead; f; f=f->next) {
  153.          f->psname = 0 ;
  154.          if (f->loaded==1)
  155.             for (c=255; c>=0; c--)
  156.                f->chardesc[c].flags &= (STATUSFLAGS) ;
  157.       }
  158.       fontmem = swmem - OVERCOST ;
  159.       if (fontmem <= 1000)
  160.          error("! Too little VM in printer") ;
  161.  
  162. /*   The section begins at the bop command just before thispageloc (which may
  163.  *   be a page that was aborted because the previous section overflowed memory).
  164.  */
  165.       pagecount = 0 ;
  166.       (void)fseek(dvifile, (long)thispageloc, 0) ;
  167.       pagenum = signedquad() ;
  168.       skipover(40) ;
  169.       thissecloc = thispageloc ;
  170. /*
  171.  *   Now we have the loop that actually scans the pages.  The scanpage routine
  172.  *   returns 1 if the page scans okay; it returns 2 if the memory ran out
  173.  *   before any pages were completed (in which case we'll try to carry on
  174.  *   and hope for the best); it returns 0 if a page was aborted for lack
  175.  *   of memory. After each page, we mark the characters seen on that page
  176.  *   as seen for this section so that they will be downloaded.
  177.  */
  178.       while (maxpages>0) {
  179.      if (!(evenpages && (pagenum & 1)) &&
  180.              !(oddpages && (pagenum & 1)==0) &&
  181.              !(pagelist && !InPageList(pagenum))) {
  182.             ret = scanpage() ;
  183.             if (ret == 0)
  184.                break ;
  185.             pagecount++ ;
  186.             maxpages-- ;
  187.      } else
  188.             skippage() ;
  189.          thissectionmem = swmem - fontmem - OVERCOST ;
  190.          mpagenum = abspage ? pageseq : pagenum ;
  191.          pageseq++ ;
  192.          if (mpagenum == lastpage && notlast)
  193.             lastmatch++ ;
  194.          if (notlast && mpagenum == lastpage && lastmatch == lastseq)
  195.             maxpages = -1 ; /* we are done after this page. */
  196.          if (reverse)
  197.             thissecloc = thispageloc ;
  198.          for (f=fonthead; f; f=f->next)
  199.             if (f->loaded==1) {
  200.                if (f->psflag & THISPAGE)
  201.                   f->psflag = PREVPAGE ;
  202.                for (c=255; c>=0; c--)
  203.                   if (f->chardesc[c].flags & THISPAGE)
  204.                      f->chardesc[c].flags = PREVPAGE |
  205.                (f->chardesc[c].flags & (STATUSFLAGS)) ;
  206.             }
  207.          cmd=skipnop() ;
  208.          if (cmd==248) break ;
  209.          if (cmd!=139)
  210.             error("! Bad DVI file: expected bop") ;
  211.          thispageloc = ftell(dvifile) ;
  212. #ifdef DEBUG
  213.          if (dd(D_PAGE))
  214. #ifdef SHORTINT
  215.          (void)fprintf(stderr,"bop at %ld\n", thispageloc) ;
  216. #else   /* ~SHORTINT */
  217.          (void)fprintf(stderr,"bop at %d\n", (int)thispageloc) ;
  218. #endif  /* ~SHORTINT */
  219. #endif  /* DEBUG */
  220.          pagenum = signedquad() ;
  221.          skipover(40) ;
  222.          if (ret==2 || (maxsecsize && pagecount >= maxsecsize))
  223.             break ;
  224.       }
  225. /*
  226.  *   Now we have reached the end of a section for some reason.
  227.  *   If there are any pages, we save the pagecount, section location,
  228.  *   and continue.
  229.  */
  230.       if (pagecount>0) {
  231.          register int fc = 0 ;
  232.          register sectiontype *sp ;
  233.          register charusetype *cp ;
  234.  
  235.          totalpages += pagecount ;
  236.          for (f=fonthead; f; f=f->next)
  237.             if (f->loaded==1 && f->psname)
  238.                fc++ ;
  239.          sp = (sectiontype *)mymalloc((integer)(sizeof(sectiontype) + 
  240.             fc * sizeof(charusetype) + sizeof(fontdesctype *))) ;
  241.          sp->bos = thissecloc ;
  242.          if (reverse) {
  243.             sp->next = sections ;
  244.             sections = sp ;
  245.          } else {
  246.             register sectiontype *p ;
  247.  
  248.             sp->next = NULL ;
  249.             if (sections == NULL)
  250.                sections = sp ;
  251.             else {
  252.                for (p=sections; p->next != NULL; p = p->next) ;
  253.                p->next = sp ;
  254.             }
  255.          }
  256.          sp->numpages = pagecount ;
  257. #ifdef DEBUG
  258.         if (dd(D_PAGE))
  259. #ifdef SHORTINT
  260.          (void)fprintf(stderr,"Have a section: %ld pages at %ld fontmem %ld\n", 
  261. #else   /* ~SHORTINT */
  262.          (void)fprintf(stderr,"Have a section: %d pages at %d fontmem %d\n", 
  263. #endif  /* ~SHORTINT */
  264.          (integer)pagecount, (integer)thissecloc, (integer)thissectionmem) ;
  265. #endif  /* DEBUG */
  266.          cp = (charusetype *) (sp + 1) ;
  267.          fc = 0 ;
  268.          for (f=fonthead; f; f=f->next)
  269.             if (f->loaded==1 && f->psname) {
  270.                register halfword b, bit ;
  271.  
  272.                cp->psfused = (f->psflag & PREVPAGE) ;
  273.                f->psflag = 0 ;
  274.                cp->fd = f ;
  275.                c = 0 ;
  276.                for (b=0; b<16; b++) {
  277.                   cp->bitmap[b] = 0 ;
  278.                   for (bit=32768; bit!=0; bit>>=1) {
  279.                      if (f->chardesc[c].flags & PREVPAGE)
  280.                         cp->bitmap[b] |= bit ;
  281.                   c++ ;
  282.                   }
  283.                }
  284.                cp++ ;
  285.             }
  286.          cp->fd = NULL ;
  287.       }
  288.    }
  289. }
  290.