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