Back to index

tetex-bin  3.0
dosection.c
Go to the documentation of this file.
00001 /*
00002  *  Code to output PostScript commands for one section of the document.
00003  */
00004 #include "dvips.h" /* The copyright notice in that file is included too! */
00005 /*
00006  *   These are the external routines we call.
00007  */
00008 #include "protos.h"
00009 
00010 /*
00011  *   These are the external variables we access.
00012  */
00013 extern shalfword linepos ;
00014 extern FILE *dvifile ;
00015 extern FILE *bitfile ;
00016 extern integer pagenum ;
00017 extern long bytesleft ;
00018 extern quarterword *raster ;
00019 extern int quiet ;
00020 extern Boolean reverse, multiplesects, disablecomments ;
00021 extern Boolean evenpages, oddpages, pagelist ;
00022 extern int actualdpi ;
00023 extern int vactualdpi ;
00024 extern int prettycolumn ;
00025 extern integer hpapersize, vpapersize ;
00026 extern integer pagecopies ;
00027 static int psfont ;
00028 extern double mag ;
00029 extern char *fulliname ;
00030 #ifdef HPS
00031 int pagecounter ;
00032 extern Boolean HPS_FLAG ;
00033 #endif
00034 /*
00035  *   Now we have the main procedure.
00036  */
00037 void
00038 dosection P2C(sectiontype *, s, int, c)
00039 {
00040    charusetype *cu ;
00041    integer prevptr ;
00042    int np ;
00043    int k ;
00044    integer thispage = 0 ;
00045    char buf[104];
00046 
00047    dopsfont(s) ;
00048 #ifdef HPS
00049         if (HPS_FLAG) pagecounter = 0;
00050 #endif
00051 
00052    if (multiplesects) {
00053      setup() ;
00054    }
00055    cmdout("TeXDict") ;
00056    cmdout("begin") ;
00057    numout(hpapersize) ;
00058    numout(vpapersize) ;
00059    doubleout(mag) ;
00060    numout((integer)DPI) ;
00061    numout((integer)VDPI) ;
00062    sprintf(buf, "(%.99s)", fulliname) ;
00063    cmdout(buf) ;
00064    cmdout("@start") ;
00065    if (multiplesects)
00066       cmdout("bos") ;
00067 /*
00068  *   We insure raster is even-word aligned, because download might want that.
00069  */
00070    if (bytesleft & 1) {
00071       bytesleft-- ;
00072       raster++ ;
00073    }
00074    cleanres() ;
00075    cu = (charusetype *) (s + 1) ;
00076    psfont = 1 ;
00077    while (cu->fd) {
00078       if (cu->psfused)
00079          cu->fd->psflag = EXISTS ;
00080       download(cu++, psfont++) ;
00081    }
00082    fonttableout() ;
00083    if (! multiplesects) {
00084       cmdout("end") ;
00085       setup() ;
00086    }
00087    for (cu=(charusetype *)(s+1); cu->fd; cu++)
00088       cu->fd->psflag = 0 ;
00089    while (c > 0) {
00090       c-- ;
00091       prevptr = s->bos ;
00092       if (! reverse)
00093          (void)fseek(dvifile, (long)prevptr, 0) ;
00094       np = s->numpages ;
00095       while (np-- != 0) {
00096          if (reverse)
00097             (void)fseek(dvifile, (long)prevptr, 0) ;
00098          pagenum = signedquad() ;
00099         if ((evenpages && (pagenum & 1)) || (oddpages && (pagenum & 1)==0) ||
00100          (pagelist && !InPageList(pagenum))) {
00101            if (reverse) {
00102                skipover(36) ;
00103                prevptr = signedquad()+1 ;
00104            } else {
00105                skipover(40) ;
00106               skippage() ;
00107               skipnop() ;
00108            }
00109            ++np ;    /* this page wasn't counted for s->numpages */
00110            continue;
00111         }
00112 /*
00113  *   We want to take the base 10 log of the number.  It's probably
00114  *   small, so we do it quick.
00115  */
00116          if (! quiet) {
00117             int t = pagenum, i = 0 ;
00118             if (t < 0) {
00119                t = -t ;
00120                i++ ;
00121             }
00122             do {
00123                i++ ;
00124                t /= 10 ;
00125             } while (t > 0) ;
00126             if (pagecopies < 20)
00127                i += pagecopies - 1 ;
00128             if (i + prettycolumn > STDOUTSIZE) {
00129                fprintf(stderr, "\n") ;
00130                prettycolumn = 0 ;
00131             }
00132             prettycolumn += i + 1 ;
00133 #ifdef SHORTINT
00134             (void)fprintf(stderr, "[%ld", pagenum) ;
00135 #else  /* ~SHORTINT */
00136             (void)fprintf(stderr, "[%d", pagenum) ;
00137 #endif /* ~SHORTINT */
00138             (void)fflush(stderr) ;
00139          }
00140          skipover(36) ;
00141          prevptr = signedquad()+1 ;
00142          for (k=0; k<pagecopies; k++) {
00143             if (k == 0) {
00144                if (pagecopies > 1)
00145                   thispage = ftell(dvifile) ;
00146             } else {
00147                (void)fseek(dvifile, (long)thispage, 0) ;
00148                if (prettycolumn + 1 > STDOUTSIZE) {
00149                   (void)fprintf(stderr, "\n") ;
00150                   prettycolumn = 0 ;
00151                }
00152                (void)fprintf(stderr, ".") ;
00153                (void)fflush(stderr) ;
00154                prettycolumn++ ;
00155             }
00156             dopage() ;
00157          }
00158          if (! quiet) {
00159             (void)fprintf(stderr, "] ") ;
00160             (void)fflush(stderr) ;
00161             prettycolumn += 2 ;
00162          }
00163          if (! reverse)
00164             (void)skipnop() ;
00165       }
00166    }
00167    if (! multiplesects && ! disablecomments) {
00168       newline() ;
00169       (void)fprintf(bitfile, "%%%%Trailer\n") ;
00170    }
00171    if (multiplesects) {
00172       if (! disablecomments) {
00173          newline() ;
00174          (void)fprintf(bitfile, "%%DVIPSSectionTrailer\n") ;
00175       }
00176       cmdout("eos") ;
00177       cmdout("end") ;
00178    }
00179 #ifdef HPS
00180    if (HPS_FLAG) cmdout("\nend") ; /* close off HPSDict */
00181 #endif
00182    if (multiplesects && ! disablecomments) {
00183       newline() ;
00184       (void)fprintf(bitfile, "%%DVIPSEndSection\n") ;
00185       linepos = 0 ;
00186    }
00187 }
00188 /*
00189  * Handle a list of pages for dvips.  Code based on dvi2ps 2.49,
00190  * maintained by Piet van Oostrum, piet@cs.ruu.nl.  Collected and
00191  * modularized for inclusion in dvips by metcalf@lcs.mit.edu.
00192  */
00193 
00194 #include <ctype.h>
00195 #define MAXPAGE (1000000000) /* assume no pages out of this range */
00196 struct p_list_str {
00197     struct p_list_str *next;       /* next in a series of alternates */
00198     integer ps_low, ps_high;       /* allowed range */
00199 } *ppages = 0;       /* the list of allowed pages */
00200 
00201 /*-->InPageList*/
00202 /**********************************************************************/
00203 /******************************  InPageList  **************************/
00204 /**********************************************************************/
00205 /* Return true iff i is one of the desired output pages */
00206 
00207 int InPageList P1C(integer, i)
00208 {
00209     register struct p_list_str *pl = ppages;
00210 
00211     while (pl) {
00212            if ( i >= pl -> ps_low && i <= pl -> ps_high)
00213               return 1;            /* success */
00214        pl = pl -> next;
00215     }
00216     return 0;
00217 }
00218 
00219 void InstallPL P2C(integer, pslow, integer, pshigh)
00220 {
00221     register struct p_list_str   *pl;
00222 
00223     pl = (struct p_list_str *)mymalloc((integer)(sizeof *pl));
00224     pl -> next = ppages;
00225     pl -> ps_low = pslow;
00226     pl -> ps_high = pshigh;
00227     ppages = pl;
00228 }
00229 
00230 /* Parse a string representing a list of pages.  Return 0 iff ok.  As a
00231    side effect, the page selection(s) is (are) prepended to ppages. */
00232 
00233 int
00234 ParsePages P1C(register char  *, s)
00235 {
00236     register int    c ;            /* current character */
00237     register integer  n = 0,       /* current numeric value */
00238                   innumber; /* true => gathering a number */
00239     integer ps_low = 0, ps_high = 0 ;
00240     int     range,          /* true => saw a range indicator */
00241            negative = 0;    /* true => number being built is negative */
00242 
00243 #define white(x) ((x) == ' ' || (x) == '\t' || (x) == ',')
00244 
00245     range = 0;
00246     innumber = 0;
00247     for (;;) {
00248        c = *s++;
00249        if ( !innumber && !range) {/* nothing special going on */
00250            if (c == 0)
00251               return 0;
00252            if (white (c))
00253               continue;
00254        }
00255        if (c == '-' && !innumber) {
00256               innumber++;
00257               negative++;
00258               n = 0;
00259               continue;
00260        }
00261        if ('0' <= c && c <= '9') { /* accumulate numeric value */
00262            if (!innumber) {
00263               innumber++;
00264               negative = 0;
00265               n = c - '0';
00266               continue;
00267            }
00268            n *= 10;
00269            n += negative ? '0' - c : c - '0';
00270            continue;
00271        }
00272        if (c == '-' || c == ':') {/* here's a range */
00273            if (range)
00274               return (-1);
00275            if (innumber) {  /* have a lower bound */
00276               ps_low = n;
00277            }
00278            else
00279               ps_low = -MAXPAGE;
00280            range++;
00281            innumber = 0;
00282            continue;
00283        }
00284        if (c == 0 || white (c)) {/* end of this range */
00285            if (!innumber) { /* no upper bound */
00286               ps_high = MAXPAGE;
00287               if (!range)   /* no lower bound either */
00288                   ps_low = -MAXPAGE;
00289            }
00290            else {           /* have an upper bound */
00291               ps_high = n;
00292               if (!range) { /* no range => lower bound == upper */
00293                   ps_low = ps_high;
00294               }
00295            }
00296            InstallPL (ps_low, ps_high);
00297            if (c == 0)
00298               return 0;
00299            range = 0;
00300            innumber = 0;
00301            continue;
00302        }
00303        return (-1);
00304     }
00305 #undef white
00306 }