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