1 /*
2  *  Code to output PostScript commands for one section of the document.
3  */
4 #include "dvips.h" /* The copyright notice in that file is included too! */
5 /*
6  *   The external declarations:
7  */
8 #include "protos.h"
9 
10 static int psfont;
11 #ifdef HPS
12 int pagecounter;
13 #endif
14 
15 /*
16  *   Now we have the main procedure.
17  */
18 void
dosection(sectiontype * s,int c)19 dosection(sectiontype *s, int c)
20 {
21    charusetype *cu;
22    integer prevptr;
23    int np;
24    int k;
25    integer thispage = 0;
26    char buf[104];
27 
28    dopsfont(s);
29 #ifdef HPS
30 	 if (HPS_FLAG) pagecounter = 0;
31 #endif
32 
33    if (multiplesects) {
34      setup();
35    }
36    cmdout("TeXDict");
37    cmdout("begin");
38    numout(hpapersize);
39    numout(vpapersize);
40    doubleout(mag);
41    numout((integer)DPI);
42    numout((integer)VDPI);
43    snprintf(buf, sizeof(buf), "(%.99s)", fulliname);
44    cmdout(buf);
45    newline();
46    cmdout("@start");
47    if (multiplesects)
48       cmdout("bos");
49 /*
50  *   We insure raster is even-word aligned, because download might want that.
51  */
52    if (bytesleft & 1) {
53       bytesleft--;
54       raster++;
55    }
56    cleanres();
57    cu = (charusetype *) (s + 1);
58    psfont = 1;
59    while (cu->fd) {
60       if (cu->psfused)
61          cu->fd->psflag = EXISTS;
62       download(cu++, psfont++);
63    }
64    fonttableout();
65    if (! multiplesects) {
66       cmdout("end");
67       setup();
68    }
69    for (cu=(charusetype *)(s+1); cu->fd; cu++)
70       cu->fd->psflag = 0;
71    while (c > 0) {
72       c--;
73       prevptr = s->bos;
74       if (! reverse)
75          fseek(dvifile, (long)prevptr, 0);
76       np = s->numpages;
77       while (np-- != 0) {
78          if (reverse)
79             fseek(dvifile, (long)prevptr, 0);
80          pagenum = signedquad();
81 	 if ((evenpages && (pagenum & 1)) || (oddpages && (pagenum & 1)==0) ||
82 	  (pagelist && !InPageList(pagenum))) {
83 	    if (reverse) {
84                skipover(36);
85                prevptr = signedquad()+1;
86 	    } else {
87                skipover(40);
88 	       skippage();
89 	       skipnop();
90 	    }
91 	    ++np;	/* this page wasn't counted for s->numpages */
92 	    continue;
93 	 }
94 /*
95  *   We want to take the base 10 log of the number.  It's probably
96  *   small, so we do it quick.
97  */
98          if (! quiet) {
99             int t = pagenum, i = 0;
100             if (t < 0) {
101                t = -t;
102                i++;
103             }
104             do {
105                i++;
106                t /= 10;
107             } while (t > 0);
108             if (pagecopies < 20)
109                i += pagecopies - 1;
110             if (i + prettycolumn > STDOUTSIZE) {
111                fprintf(stderr, "\n");
112                prettycolumn = 0;
113             }
114             prettycolumn += i + 1;
115 #ifdef SHORTINT
116             fprintf(stderr, "[%ld", pagenum);
117 #else  /* ~SHORTINT */
118             fprintf(stderr, "[%d", pagenum);
119 #endif /* ~SHORTINT */
120             fflush(stderr);
121          }
122          skipover(36);
123          prevptr = signedquad()+1;
124          for (k=0; k<pagecopies; k++) {
125             if (k == 0) {
126                if (pagecopies > 1)
127                   thispage = ftell(dvifile);
128             } else {
129                fseek(dvifile, (long)thispage, 0);
130                if (prettycolumn + 1 > STDOUTSIZE) {
131                   fprintf(stderr, "\n");
132                   prettycolumn = 0;
133                }
134                fprintf(stderr, ".");
135                fflush(stderr);
136                prettycolumn++;
137             }
138             dopage();
139          }
140          if (! quiet) {
141             fprintf(stderr, "] ");
142             fflush(stderr);
143             prettycolumn += 2;
144          }
145          if (! reverse)
146             skipnop();
147       }
148    }
149    if (! multiplesects && ! disablecomments) {
150       newline();
151       fprintf(bitfile, "%%%%Trailer\n");
152    }
153    if (multiplesects) {
154       if (! disablecomments) {
155          newline();
156          fprintf(bitfile, "%%DVIPSSectionTrailer\n");
157       }
158       cmdout("eos");
159       cmdout("end");
160    }
161 #ifdef HPS
162    if (HPS_FLAG) cmdout("\nend"); /* close off HPSDict */
163 #endif
164    if (multiplesects && ! disablecomments) {
165       newline();
166       fprintf(bitfile, "%%DVIPSEndSection\n");
167       linepos = 0;
168    }
169 }
170 /*
171  * Handle a list of pages for dvips.  Code based on dvi2ps 2.49,
172  * maintained by Piet van Oostrum, piet@cs.ruu.nl.  Collected and
173  * modularized for inclusion in dvips by metcalf@lcs.mit.edu.
174  */
175 
176 #include <ctype.h>
177 #define MAXPAGE (1000000000) /* assume no pages out of this range */
178 struct p_list_str {
179     struct p_list_str *next;	/* next in a series of alternates */
180     integer ps_low, ps_high;	/* allowed range */
181 } *ppages = 0;	/* the list of allowed pages */
182 
183 /*-->InPageList*/
184 /**********************************************************************/
185 /******************************  InPageList  **************************/
186 /**********************************************************************/
187 /* Return true iff i is one of the desired output pages */
188 
189 int
InPageList(integer i)190 InPageList(integer i)
191 {
192     register struct p_list_str *pl = ppages;
193 
194     while (pl) {
195 	    if ( i >= pl -> ps_low && i <= pl -> ps_high)
196 		return 1;		/* success */
197 	pl = pl -> next;
198     }
199     return 0;
200 }
201 
202 static void
InstallPL(integer pslow,integer pshigh)203 InstallPL(integer pslow, integer pshigh)
204 {
205     register struct p_list_str   *pl;
206 
207     pl = (struct p_list_str *)mymalloc((integer)(sizeof *pl));
208     pl -> next = ppages;
209     pl -> ps_low = pslow;
210     pl -> ps_high = pshigh;
211     ppages = pl;
212 }
213 
214 /* Parse a string representing a list of pages.  Return 0 iff ok.  As a
215    side effect, the page selection(s) is (are) prepended to ppages. */
216 
217 int
ParsePages(register char * s)218 ParsePages(register char *s)
219 {
220     register int    c;		/* current character */
221     register integer  n = 0,	/* current numeric value */
222 		    innumber;	/* true => gathering a number */
223     integer ps_low = 0, ps_high = 0;
224     int     range,		/* true => saw a range indicator */
225 	    negative = 0;	/* true => number being built is negative */
226 
227 #define white(x) ((x) == ' ' || (x) == '\t' || (x) == ',')
228 
229     range = 0;
230     innumber = 0;
231     for (;;) {
232 	c = *s++;
233 	if ( !innumber && !range) {/* nothing special going on */
234 	    if (c == 0)
235 		return 0;
236 	    if (white (c))
237 		continue;
238 	}
239 	if (c == '-' && !innumber) {
240 		innumber++;
241 		negative++;
242 		n = 0;
243 		continue;
244 	}
245 	if ('0' <= c && c <= '9') {	/* accumulate numeric value */
246 	    if (!innumber) {
247 		innumber++;
248 		negative = 0;
249 		n = c - '0';
250 		continue;
251 	    }
252 	    n *= 10;
253 	    n += negative ? '0' - c : c - '0';
254 	    continue;
255 	}
256 	if (c == '-' || c == ':') {/* here's a range */
257 	    if (range)
258 		return (-1);
259 	    if (innumber) {	/* have a lower bound */
260 		ps_low = n;
261 	    }
262 	    else
263 		ps_low = -MAXPAGE;
264 	    range++;
265 	    innumber = 0;
266 	    continue;
267 	}
268 	if (c == 0 || white (c)) {/* end of this range */
269 	    if (!innumber) {	/* no upper bound */
270 		ps_high = MAXPAGE;
271 		if (!range)	/* no lower bound either */
272 		    ps_low = -MAXPAGE;
273 	    }
274 	    else {		/* have an upper bound */
275 		ps_high = n;
276 		if (!range) {	/* no range => lower bound == upper */
277 		    ps_low = ps_high;
278 		}
279 	    }
280 	    InstallPL (ps_low, ps_high);
281 	    if (c == 0)
282 		return 0;
283 	    range = 0;
284 	    innumber = 0;
285 	    continue;
286 	}
287 	return (-1);
288     }
289 #undef white
290 }
291