/* * This is the main routine for the first (prescanning) pass. */ #include "dvips.h" /* The copyright notice in that file is included too! */ /* * The external declarations: */ #include "protos.h" /* * This routine handles the processing of the preamble in the dvi file. */ void readpreamble(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) 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) { fprintf(stderr, "'"); #ifdef VMCMS /* IBM: VM/CMS */ for(p=preamblecomment;*p;p++) putc(ascii2ebcdic[*p], stderr); #else #ifdef MVSXA /* IBM: MVS/XA */ for(p=preamblecomment;*p;p++) putc(ascii2ebcdic[*p], stderr); #else for(p=preamblecomment;*p;p++) putc_str(*p, stderr); #endif /* IBM: VM/CMS */ #endif fprintf_str(stderr, "' -> %s\n", oname); } } else skipover(dvibyte()); } /* * Finally, here's our main prescan routine. */ static integer firstmatch = -1, lastmatch = -1; void prescanpages(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 fprintf(stderr,"bop at %ld\n", thispageloc); #else /* ~SHORTINT */ 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; 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 fprintf(stderr,"bop at %ld\n", thispageloc); #else /* ~SHORTINT */ 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 fprintf(stderr,"Have a section: %ld pages at %ld fontmem %ld\n", #else /* ~SHORTINT */ 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; } } }