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