/* * Code to output PostScript commands for one section of the document. */ #include "dvips.h" /* The copyright notice in that file is included too! */ /* * These are the external routines we call. */ #include "protos.h" /* * These are the external variables we access. */ extern shalfword linepos ; extern FILE *dvifile ; extern FILE *bitfile ; extern integer pagenum ; extern long bytesleft ; extern quarterword *raster ; extern int quiet ; extern Boolean reverse, multiplesects, disablecomments ; extern Boolean evenpages, oddpages, pagelist ; extern int actualdpi ; extern int vactualdpi ; extern int prettycolumn ; extern integer hpapersize, vpapersize ; extern integer pagecopies ; static int psfont ; extern double mag ; extern char *fulliname ; #ifdef HPS int pagecounter ; extern Boolean HPS_FLAG ; #endif /* * Now we have the main procedure. */ void dosection P2C(sectiontype *, s, int, c) { charusetype *cu ; integer prevptr ; int np ; int k ; integer thispage = 0 ; char buf[104]; dopsfont(s) ; #ifdef HPS if (HPS_FLAG) pagecounter = 0; #endif if (multiplesects) { setup() ; } else { cmdout("TeXDict") ; cmdout("begin") ; } numout(hpapersize) ; numout(vpapersize) ; doubleout(mag) ; numout((integer)DPI) ; numout((integer)VDPI) ; sprintf(buf, "(%.99s)", fulliname) ; cmdout(buf) ; cmdout("@start") ; if (multiplesects) cmdout("bos") ; /* * We insure raster is even-word aligned, because download might want that. */ if (bytesleft & 1) { bytesleft-- ; raster++ ; } cleanres() ; cu = (charusetype *) (s + 1) ; psfont = 1 ; while (cu->fd) { if (cu->psfused) cu->fd->psflag = EXISTS ; download(cu++, psfont++) ; } fonttableout() ; if (! multiplesects) { cmdout("end") ; setup() ; } for (cu=(charusetype *)(s+1); cu->fd; cu++) cu->fd->psflag = 0 ; while (c > 0) { c-- ; prevptr = s->bos ; if (! reverse) (void)fseek(dvifile, (long)prevptr, 0) ; np = s->numpages ; while (np-- != 0) { if (reverse) (void)fseek(dvifile, (long)prevptr, 0) ; pagenum = signedquad() ; if ((evenpages && (pagenum & 1)) || (oddpages && (pagenum & 1)==0) || (pagelist && !InPageList(pagenum))) { if (reverse) { skipover(36) ; prevptr = signedquad()+1 ; } else { skipover(40) ; skippage() ; skipnop() ; } ++np ; /* this page wasn't counted for s->numpages */ continue; } /* * We want to take the base 10 log of the number. It's probably * small, so we do it quick. */ if (! quiet) { int t = pagenum, i = 0 ; if (t < 0) { t = -t ; i++ ; } do { i++ ; t /= 10 ; } while (t > 0) ; if (pagecopies < 20) i += pagecopies - 1 ; if (i + prettycolumn > STDOUTSIZE) { fprintf(stderr, "\n") ; prettycolumn = 0 ; } prettycolumn += i + 1 ; #ifdef SHORTINT (void)fprintf(stderr, "[%ld", pagenum) ; #else /* ~SHORTINT */ (void)fprintf(stderr, "[%d", pagenum) ; #endif /* ~SHORTINT */ (void)fflush(stderr) ; } skipover(36) ; prevptr = signedquad()+1 ; for (k=0; k 1) thispage = ftell(dvifile) ; } else { (void)fseek(dvifile, (long)thispage, 0) ; if (prettycolumn + 1 > STDOUTSIZE) { (void)fprintf(stderr, "\n") ; prettycolumn = 0 ; } (void)fprintf(stderr, ".") ; (void)fflush(stderr) ; prettycolumn++ ; } dopage() ; } if (! quiet) { (void)fprintf(stderr, "] ") ; (void)fflush(stderr) ; prettycolumn += 2 ; } if (! reverse) (void)skipnop() ; } } if (! multiplesects && ! disablecomments) { newline() ; (void)fprintf(bitfile, "%%%%Trailer\n") ; } if (multiplesects) { if (! disablecomments) { newline() ; (void)fprintf(bitfile, "%%DVIPSSectionTrailer\n") ; } cmdout("eos") ; } cmdout("end") ; #ifdef HPS if (HPS_FLAG) cmdout("\nend") ; /* close off HPSDict */ #endif if (multiplesects && ! disablecomments) { newline() ; (void)fprintf(bitfile, "%%DVIPSEndSection\n") ; linepos = 0 ; } } /* * Handle a list of pages for dvips. Code based on dvi2ps 2.49, * maintained by Piet van Oostrum, piet@cs.ruu.nl. Collected and * modularized for inclusion in dvips by metcalf@lcs.mit.edu. */ #include #define MAXPAGE (1000000000) /* assume no pages out of this range */ struct p_list_str { struct p_list_str *next; /* next in a series of alternates */ integer ps_low, ps_high; /* allowed range */ } *ppages = 0; /* the list of allowed pages */ /*-->InPageList*/ /**********************************************************************/ /****************************** InPageList **************************/ /**********************************************************************/ /* Return true iff i is one of the desired output pages */ int InPageList P1C(integer, i) { register struct p_list_str *pl = ppages; while (pl) { if ( i >= pl -> ps_low && i <= pl -> ps_high) return 1; /* success */ pl = pl -> next; } return 0; } void InstallPL P2C(integer, pslow, integer, pshigh) { register struct p_list_str *pl; pl = (struct p_list_str *)mymalloc((integer)(sizeof *pl)); pl -> next = ppages; pl -> ps_low = pslow; pl -> ps_high = pshigh; ppages = pl; } /* Parse a string representing a list of pages. Return 0 iff ok. As a side effect, the page selection(s) is (are) prepended to ppages. */ int ParsePages P1C(register char *, s) { register int c ; /* current character */ register integer n = 0, /* current numeric value */ innumber; /* true => gathering a number */ integer ps_low = 0, ps_high = 0 ; int range, /* true => saw a range indicator */ negative = 0; /* true => number being built is negative */ #define white(x) ((x) == ' ' || (x) == '\t' || (x) == ',') range = 0; innumber = 0; for (;;) { c = *s++; if ( !innumber && !range) {/* nothing special going on */ if (c == 0) return 0; if (white (c)) continue; } if (c == '-' && !innumber) { innumber++; negative++; n = 0; continue; } if ('0' <= c && c <= '9') { /* accumulate numeric value */ if (!innumber) { innumber++; negative = 0; n = c - '0'; continue; } n *= 10; n += negative ? '0' - c : c - '0'; continue; } if (c == '-' || c == ':') {/* here's a range */ if (range) return (-1); if (innumber) { /* have a lower bound */ ps_low = n; } else ps_low = -MAXPAGE; range++; innumber = 0; continue; } if (c == 0 || white (c)) {/* end of this range */ if (!innumber) { /* no upper bound */ ps_high = MAXPAGE; if (!range) /* no lower bound either */ ps_low = -MAXPAGE; } else { /* have an upper bound */ ps_high = n; if (!range) { /* no range => lower bound == upper */ ps_low = ps_high; } } InstallPL (ps_low, ps_high); if (c == 0) return 0; range = 0; innumber = 0; continue; } return (-1); } #undef white }