/* * This is the main routine for the first (prescanning) pass. */ #include "dvips.h" /* The copyright notice in that file is included too! */ /* * These are all the external routines it calls: */ #include "protos.h" /* * These are the globals it accesses. */ #ifdef DEBUG extern integer debug_flag; #endif /* DEBUG */ extern fontdesctype *fonthead ; extern real conv ; extern real vconv ; extern real alpha ; extern integer firstpage, lastpage ; extern integer firstseq, lastseq ; extern integer maxsecsize ; extern Boolean notfirst, notlast ; extern Boolean evenpages, oddpages, pagelist ; extern integer fontmem ; extern integer pagecount ; extern integer pagenum ; extern integer maxpages ; extern sectiontype *sections ; extern FILE *dvifile ; extern integer num, den ; extern double mag ; extern int overridemag ; extern integer swmem ; extern int quiet ; extern int actualdpi ; extern int vactualdpi ; extern Boolean reverse ; extern int totalpages ; extern integer fsizetol ; extern char *oname ; extern Boolean pprescan ; extern Boolean abspage ; extern char preamblecomment[] ; /* * This routine handles the processing of the preamble in the dvi file. */ void readpreamble P1H(void) { register int i ; char *p ; if (dvibyte()!=247) error("! Bad DVI file: first byte not preamble") ; if (dvibyte()!=2) error("! Bad DVI file: id byte not 2") ; num = signedquad() ; den = signedquad() ; if (overridemag > 0) (void)signedquad() ; else if (overridemag < 0) mag = (mag * signedquad()) / 1000.0 ; else mag = signedquad() ; conv = (real) num * DPI * mag / ( den * 254000000.0 ) ; vconv = (real) num * VDPI * mag / ( den * 254000000.0 ) ; alpha = (((real)den / 7227.0) / 0x100000) * (25400000.0 / (real) num) ; fsizetol = 1 + (integer)(DPI/(72270.0 * conv)) ; if (!pprescan) { for (i=dvibyte(),p=preamblecomment;i>0;i--,p++) *p=dvibyte() ; *p='\0' ; if (!quiet) { (void)fprintf(stderr, "'") ; #ifdef VMCMS /* IBM: VM/CMS */ for(p=preamblecomment;*p;p++) (void)putc(ascii2ebcdic[*p], stderr) ; #else #ifdef MVSXA /* IBM: MVS/XA */ for(p=preamblecomment;*p;p++) (void)putc(ascii2ebcdic[*p], stderr) ; #else for(p=preamblecomment;*p;p++) (void)putc(*p, stderr) ; #endif /* IBM: VM/CMS */ #endif (void)fprintf(stderr, "' -> %s\n", oname) ; } } else skipover(dvibyte()) ; } /* * Finally, here's our main prescan routine. */ static integer firstmatch = -1, lastmatch = -1 ; void prescanpages P1H(void) { register int cmd ; short ret = 0 ; register integer thispageloc, thissecloc ; register fontdesctype *f ; register shalfword c ; register long thissectionmem = 0 ; integer mpagenum ; integer pageseq = 0 ; int ntfirst = notfirst ; readpreamble() ; /* * Now we look for the first page to process. If we get to the end of * the file before the page, we complain (fatally). * Incidentally, we don't use the DVI file's bop backpointer to skip * over pages at high speed, because we want to look to for special * header that might be in skipped pages. */ while (1) { cmd = skipnop() ; if (cmd==248) error("! End of document before first specified page") ; if (cmd!=139) error("! Bad DVI file: expected bop") ; thispageloc = ftell(dvifile) ; /* the location FOLLOWING the bop */ #ifdef DEBUG if (dd(D_PAGE)) #ifdef SHORTINT (void)fprintf(stderr,"bop at %ld\n", thispageloc) ; #else /* ~SHORTINT */ (void)fprintf(stderr,"bop at %d\n", (int)thispageloc) ; #endif /* ~SHORTINT */ #endif /* DEBUG */ pagenum = signedquad() ; pageseq++ ; mpagenum = abspage ? pageseq : pagenum ; if (mpagenum == firstpage && ntfirst) firstmatch++ ; if (mpagenum == lastpage && notlast) lastmatch++ ; if (ntfirst && mpagenum == firstpage && firstmatch == firstseq) ntfirst = 0 ; if (ntfirst || ((evenpages && (pagenum & 1)) || (oddpages && (pagenum & 1)==0) || (pagelist && !InPageList(pagenum)))) { skipover(40) ; skippage() ; } else { if (notlast && mpagenum == lastpage) lastmatch-- ; break ; } } /* * Here we scan for each of the sections. First we initialize some of * the variables we need. */ while (maxpages > 0 && cmd != 248) { for (f=fonthead; f; f=f->next) { f->psname = 0 ; if (f->loaded==1) for (c=255; c>=0; c--) f->chardesc[c].flags &= (STATUSFLAGS) ; } fontmem = swmem - OVERCOST ; if (fontmem <= 1000) error("! Too little VM in printer") ; /* The section begins at the bop command just before thispageloc (which may * be a page that was aborted because the previous section overflowed memory). */ pagecount = 0 ; (void)fseek(dvifile, (long)thispageloc, 0) ; pagenum = signedquad() ; skipover(40) ; thissecloc = thispageloc ; /* * Now we have the loop that actually scans the pages. The scanpage routine * returns 1 if the page scans okay; it returns 2 if the memory ran out * before any pages were completed (in which case we'll try to carry on * and hope for the best); it returns 0 if a page was aborted for lack * of memory. After each page, we mark the characters seen on that page * as seen for this section so that they will be downloaded. */ ret = 0 ; while (maxpages>0) { if (!(evenpages && (pagenum & 1)) && !(oddpages && (pagenum & 1)==0) && !(pagelist && !InPageList(pagenum))) { ret = scanpage() ; if (ret == 0) break ; pagecount++ ; maxpages-- ; } else skippage() ; thissectionmem = swmem - fontmem - OVERCOST ; mpagenum = abspage ? pageseq : pagenum ; pageseq++ ; if (mpagenum == lastpage && notlast) lastmatch++ ; if (notlast && mpagenum == lastpage && lastmatch == lastseq) maxpages = -1 ; /* we are done after this page. */ if (reverse) thissecloc = thispageloc ; for (f=fonthead; f; f=f->next) if (f->loaded==1) { if (f->psflag & THISPAGE) f->psflag = PREVPAGE ; for (c=255; c>=0; c--) if (f->chardesc[c].flags & THISPAGE) f->chardesc[c].flags = PREVPAGE | (f->chardesc[c].flags & (STATUSFLAGS)) ; } cmd=skipnop() ; if (cmd==248) break ; if (cmd!=139) error("! Bad DVI file: expected bop") ; thispageloc = ftell(dvifile) ; #ifdef DEBUG if (dd(D_PAGE)) #ifdef SHORTINT (void)fprintf(stderr,"bop at %ld\n", thispageloc) ; #else /* ~SHORTINT */ (void)fprintf(stderr,"bop at %d\n", (int)thispageloc) ; #endif /* ~SHORTINT */ #endif /* DEBUG */ pagenum = signedquad() ; skipover(40) ; if (ret==2 || (maxsecsize && pagecount >= maxsecsize)) break ; } /* * Now we have reached the end of a section for some reason. * If there are any pages, we save the pagecount, section location, * and continue. */ if (pagecount>0) { register int fc = 0 ; register sectiontype *sp ; register charusetype *cp ; totalpages += pagecount ; for (f=fonthead; f; f=f->next) if (f->loaded==1 && f->psname) fc++ ; sp = (sectiontype *)mymalloc((integer)(sizeof(sectiontype) + fc * sizeof(charusetype) + sizeof(fontdesctype *))) ; sp->bos = thissecloc ; if (reverse) { sp->next = sections ; sections = sp ; } else { register sectiontype *p ; sp->next = NULL ; if (sections == NULL) sections = sp ; else { for (p=sections; p->next != NULL; p = p->next) ; p->next = sp ; } } sp->numpages = pagecount ; #ifdef DEBUG if (dd(D_PAGE)) #ifdef SHORTINT (void)fprintf(stderr,"Have a section: %ld pages at %ld fontmem %ld\n", #else /* ~SHORTINT */ (void)fprintf(stderr,"Have a section: %d pages at %d fontmem %d\n", #endif /* ~SHORTINT */ (integer)pagecount, (integer)thissecloc, (integer)thissectionmem) ; #endif /* DEBUG */ cp = (charusetype *) (sp + 1) ; fc = 0 ; for (f=fonthead; f; f=f->next) if (f->loaded==1 && f->psname) { register halfword b, bit ; cp->psfused = (f->psflag & PREVPAGE) ; f->psflag = 0 ; cp->fd = f ; c = 0 ; for (b=0; b<16; b++) { cp->bitmap[b] = 0 ; for (bit=32768; bit!=0; bit>>=1) { if (f->chardesc[c].flags & PREVPAGE) cp->bitmap[b] |= bit ; c++ ; } } cp++ ; } cp->fd = NULL ; } } }