Back to index

tetex-bin  3.0
prescan.c
Go to the documentation of this file.
00001 /*
00002  *   This is the main routine for the first (prescanning) pass.
00003  */
00004 #include "dvips.h" /* The copyright notice in that file is included too! */
00005 
00006 /*
00007  *   These are all the external routines it calls:
00008  */
00009 #include "protos.h"
00010 
00011 /*
00012  *   These are the globals it accesses.
00013  */
00014 #ifdef DEBUG
00015 extern integer debug_flag;
00016 #endif  /* DEBUG */
00017 extern fontdesctype *fonthead ;
00018 extern real conv ;
00019 extern real vconv ;
00020 extern real alpha ;
00021 extern integer firstpage, lastpage ;
00022 extern integer firstseq, lastseq ;
00023 extern integer maxsecsize ;
00024 extern Boolean notfirst, notlast ;
00025 extern Boolean evenpages, oddpages, pagelist ;
00026 extern integer fontmem ;
00027 extern integer pagecount ;
00028 extern integer pagenum ;
00029 extern integer maxpages ;
00030 extern sectiontype *sections ;
00031 extern FILE *dvifile ;
00032 extern integer num, den ;
00033 extern double mag ;
00034 extern int overridemag ;
00035 extern integer swmem ;
00036 extern int quiet ;
00037 extern int actualdpi ;
00038 extern int vactualdpi ;
00039 extern Boolean reverse ;
00040 extern int totalpages ;
00041 extern integer fsizetol ;
00042 extern char *oname ;
00043 extern Boolean pprescan ;
00044 extern Boolean abspage ;
00045 extern char preamblecomment[] ;
00046 /*
00047  *   This routine handles the processing of the preamble in the dvi file.
00048  */
00049 void
00050 readpreamble P1H(void)
00051 {
00052    register int i ;
00053    char *p ;
00054 
00055    if (dvibyte()!=247) error("! Bad DVI file: first byte not preamble") ;
00056    if (dvibyte()!=2) error("! Bad DVI file: id byte not 2") ;
00057    num = signedquad() ;
00058    den = signedquad() ;
00059    if (overridemag > 0) (void)signedquad() ;
00060    else if (overridemag < 0) mag = (mag * signedquad()) / 1000.0 ;
00061    else mag = signedquad() ;
00062    conv = (real) num * DPI * mag / ( den * 254000000.0 ) ; 
00063    vconv = (real) num * VDPI * mag / ( den * 254000000.0 ) ; 
00064    alpha = (((real)den / 7227.0) / 0x100000) * (25400000.0 / (real) num) ;
00065    fsizetol = 1 + (integer)(DPI/(72270.0 * conv)) ;
00066    if (!pprescan) {
00067      for (i=dvibyte(),p=preamblecomment;i>0;i--,p++) *p=dvibyte() ;
00068      *p='\0' ;
00069      if (!quiet) {
00070         (void)fprintf(stderr, "'") ;
00071 #ifdef VMCMS /* IBM: VM/CMS */
00072         for(p=preamblecomment;*p;p++) (void)putc(ascii2ebcdic[*p], stderr) ;
00073 #else
00074 #ifdef MVSXA /* IBM: MVS/XA */
00075         for(p=preamblecomment;*p;p++) (void)putc(ascii2ebcdic[*p], stderr) ;
00076 #else
00077         for(p=preamblecomment;*p;p++) (void)putc(*p, stderr) ;
00078 #endif  /* IBM: VM/CMS */
00079 #endif
00080         (void)fprintf(stderr, "' -> %s\n", oname) ;
00081       }
00082    } else
00083       skipover(dvibyte()) ;
00084 }
00085 
00086 /*
00087  *   Finally, here's our main prescan routine.
00088  */
00089 static integer firstmatch = -1, lastmatch = -1 ;
00090 void
00091 prescanpages P1H(void)
00092 {
00093    register int cmd ;
00094    short ret = 0 ;
00095    register integer thispageloc, thissecloc ;
00096    register fontdesctype *f ;
00097    register shalfword c ;
00098    register long thissectionmem = 0 ;
00099    integer mpagenum ;
00100    integer pageseq = 0 ;
00101    int ntfirst = notfirst ;
00102 
00103    readpreamble() ;
00104 /*
00105  *   Now we look for the first page to process.  If we get to the end of
00106  *   the file before the page, we complain (fatally).
00107  *   Incidentally, we don't use the DVI file's bop backpointer to skip
00108  *   over pages at high speed, because we want to look to for special
00109  *   header that might be in skipped pages.
00110  */
00111    while (1) {
00112       cmd = skipnop() ;
00113       if (cmd==248)
00114          error("! End of document before first specified page") ;
00115       if (cmd!=139)
00116          error("! Bad DVI file: expected bop") ;
00117       thispageloc = ftell(dvifile) ; /* the location FOLLOWING the bop */
00118 #ifdef DEBUG
00119       if (dd(D_PAGE))
00120 #ifdef SHORTINT
00121       (void)fprintf(stderr,"bop at %ld\n", thispageloc) ;
00122 #else   /* ~SHORTINT */
00123       (void)fprintf(stderr,"bop at %d\n", (int)thispageloc) ;
00124 #endif  /* ~SHORTINT */
00125 #endif  /* DEBUG */
00126       pagenum = signedquad() ;
00127       pageseq++ ;
00128       mpagenum = abspage ? pageseq : pagenum ;
00129       if (mpagenum == firstpage && ntfirst)
00130          firstmatch++ ;
00131       if (mpagenum == lastpage && notlast)
00132          lastmatch++ ;
00133       if (ntfirst && mpagenum == firstpage && firstmatch == firstseq)
00134          ntfirst = 0 ;
00135       if (ntfirst ||
00136          ((evenpages && (pagenum & 1)) || (oddpages && (pagenum & 1)==0) ||
00137           (pagelist && !InPageList(pagenum)))) {
00138          skipover(40) ;
00139          skippage() ;
00140       } else {
00141          if (notlast && mpagenum == lastpage)
00142             lastmatch-- ;
00143          break ;
00144       }
00145    }
00146 /*
00147  *   Here we scan for each of the sections.  First we initialize some of
00148  *   the variables we need.
00149  */
00150    while (maxpages > 0 && cmd != 248) {
00151       for (f=fonthead; f; f=f->next) {
00152          f->psname = 0 ;
00153          if (f->loaded==1)
00154             for (c=255; c>=0; c--)
00155                f->chardesc[c].flags &= (STATUSFLAGS) ;
00156       }
00157       fontmem = swmem - OVERCOST ;
00158       if (fontmem <= 1000)
00159          error("! Too little VM in printer") ;
00160 
00161 /*   The section begins at the bop command just before thispageloc (which may
00162  *   be a page that was aborted because the previous section overflowed memory).
00163  */
00164       pagecount = 0 ;
00165       (void)fseek(dvifile, (long)thispageloc, 0) ;
00166       pagenum = signedquad() ;
00167       skipover(40) ;
00168       thissecloc = thispageloc ;
00169 /*
00170  *   Now we have the loop that actually scans the pages.  The scanpage routine
00171  *   returns 1 if the page scans okay; it returns 2 if the memory ran out
00172  *   before any pages were completed (in which case we'll try to carry on
00173  *   and hope for the best); it returns 0 if a page was aborted for lack
00174  *   of memory. After each page, we mark the characters seen on that page
00175  *   as seen for this section so that they will be downloaded.
00176  */
00177       ret = 0 ;
00178       while (maxpages>0) {
00179         if (!(evenpages && (pagenum & 1)) &&
00180              !(oddpages && (pagenum & 1)==0) &&
00181              !(pagelist && !InPageList(pagenum))) {
00182             ret = scanpage() ;
00183             if (ret == 0)
00184                break ;
00185             pagecount++ ;
00186             maxpages-- ;
00187         } else
00188             skippage() ;
00189          thissectionmem = swmem - fontmem - OVERCOST ;
00190          mpagenum = abspage ? pageseq : pagenum ;
00191          pageseq++ ;
00192          if (mpagenum == lastpage && notlast)
00193             lastmatch++ ;
00194          if (notlast && mpagenum == lastpage && lastmatch == lastseq)
00195             maxpages = -1 ; /* we are done after this page. */
00196          if (reverse)
00197             thissecloc = thispageloc ;
00198          for (f=fonthead; f; f=f->next)
00199             if (f->loaded==1) {
00200                if (f->psflag & THISPAGE)
00201                   f->psflag = PREVPAGE ;
00202                for (c=255; c>=0; c--)
00203                   if (f->chardesc[c].flags & THISPAGE)
00204                      f->chardesc[c].flags = PREVPAGE |
00205                (f->chardesc[c].flags & (STATUSFLAGS)) ;
00206             }
00207          cmd=skipnop() ;
00208          if (cmd==248) break ;
00209          if (cmd!=139)
00210             error("! Bad DVI file: expected bop") ;
00211          thispageloc = ftell(dvifile) ;
00212 #ifdef DEBUG
00213          if (dd(D_PAGE))
00214 #ifdef SHORTINT
00215          (void)fprintf(stderr,"bop at %ld\n", thispageloc) ;
00216 #else   /* ~SHORTINT */
00217          (void)fprintf(stderr,"bop at %d\n", (int)thispageloc) ;
00218 #endif  /* ~SHORTINT */
00219 #endif  /* DEBUG */
00220          pagenum = signedquad() ;
00221          skipover(40) ;
00222          if (ret==2 || (maxsecsize && pagecount >= maxsecsize))
00223             break ;
00224       }
00225 /*
00226  *   Now we have reached the end of a section for some reason.
00227  *   If there are any pages, we save the pagecount, section location,
00228  *   and continue.
00229  */
00230       if (pagecount>0) {
00231          register int fc = 0 ;
00232          register sectiontype *sp ;
00233          register charusetype *cp ;
00234 
00235          totalpages += pagecount ;
00236          for (f=fonthead; f; f=f->next)
00237             if (f->loaded==1 && f->psname)
00238                fc++ ;
00239          sp = (sectiontype *)mymalloc((integer)(sizeof(sectiontype) + 
00240             fc * sizeof(charusetype) + sizeof(fontdesctype *))) ;
00241          sp->bos = thissecloc ;
00242          if (reverse) {
00243             sp->next = sections ;
00244             sections = sp ;
00245          } else {
00246             register sectiontype *p ;
00247 
00248             sp->next = NULL ;
00249             if (sections == NULL)
00250                sections = sp ;
00251             else {
00252                for (p=sections; p->next != NULL; p = p->next) ;
00253                p->next = sp ;
00254             }
00255          }
00256          sp->numpages = pagecount ;
00257 #ifdef DEBUG
00258         if (dd(D_PAGE))
00259 #ifdef SHORTINT
00260          (void)fprintf(stderr,"Have a section: %ld pages at %ld fontmem %ld\n", 
00261 #else   /* ~SHORTINT */
00262          (void)fprintf(stderr,"Have a section: %d pages at %d fontmem %d\n", 
00263 #endif  /* ~SHORTINT */
00264          (integer)pagecount, (integer)thissecloc, (integer)thissectionmem) ;
00265 #endif  /* DEBUG */
00266          cp = (charusetype *) (sp + 1) ;
00267          fc = 0 ;
00268          for (f=fonthead; f; f=f->next)
00269             if (f->loaded==1 && f->psname) {
00270                register halfword b, bit ;
00271 
00272                cp->psfused = (f->psflag & PREVPAGE) ;
00273                f->psflag = 0 ;
00274                cp->fd = f ;
00275                c = 0 ;
00276                for (b=0; b<16; b++) {
00277                   cp->bitmap[b] = 0 ;
00278                   for (bit=32768; bit!=0; bit>>=1) {
00279                      if (f->chardesc[c].flags & PREVPAGE)
00280                         cp->bitmap[b] |= bit ;
00281                   c++ ;
00282                   }
00283                }
00284                cp++ ;
00285             }
00286          cp->fd = NULL ;
00287       }
00288    }
00289 }