/*
* 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() + 500.0) / 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 ;
}
}
}
|