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