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