1 5f1cf8e6 2004-05-16 devnull const int NOGOAL = -1;
3 5f1cf8e6 2004-05-16 devnull class stream;
5 5f1cf8e6 2004-05-16 devnull enum primeflush { NO, YES, EXPECTED, UNEXPECTED }; // mergestream::prime()
7 5f1cf8e6 2004-05-16 devnull // Ranges do two things. They interpose a layer between slugs and the rest
8 5f1cf8e6 2004-05-16 devnull // of the program; this is important because of the grossness of the slug
9 5f1cf8e6 2004-05-16 devnull // data structure (made necessary by its origins in troff output). Ranges also
10 5f1cf8e6 2004-05-16 devnull // group together other ranges into meaningful chunks like unbreakable stream
11 5f1cf8e6 2004-05-16 devnull // objects, floatable objects, and page headers and footers.
12 5f1cf8e6 2004-05-16 devnull // Member function height() returns a range's height as of the latest composition.
13 5f1cf8e6 2004-05-16 devnull // Member function rawht() returns the range's original height in the input.
14 5f1cf8e6 2004-05-16 devnull class range {
15 5f1cf8e6 2004-05-16 devnull protected:
16 5f1cf8e6 2004-05-16 devnull slug *first; // earliest slug in range
17 5f1cf8e6 2004-05-16 devnull int accumV; // accumulated V to this point
19 5f1cf8e6 2004-05-16 devnull range() { first = 0; accumV = 0; }
20 5f1cf8e6 2004-05-16 devnull range(slug *p) { first = p; accumV = 0; }
21 05f5d46b 2006-02-17 devnull virtual ~range() { }
22 5f1cf8e6 2004-05-16 devnull char *headstr() {
23 5f1cf8e6 2004-05-16 devnull return first ? first->headstr() : (char*)""; }
24 5f1cf8e6 2004-05-16 devnull char *typename() { return first->typename(); }
25 5f1cf8e6 2004-05-16 devnull int serialno() { return first->serialno(); }
26 5f1cf8e6 2004-05-16 devnull int lineno() { return first->lineno(); }
27 5f1cf8e6 2004-05-16 devnull virtual void dump() { first->dump(); }
28 5f1cf8e6 2004-05-16 devnull virtual void rdump() { dump(); }
29 5f1cf8e6 2004-05-16 devnull virtual int print(int cv, int col) {
30 5f1cf8e6 2004-05-16 devnull first->slugout(col); return cv; }
31 5f1cf8e6 2004-05-16 devnull virtual int floatable() { return 0; }
32 5f1cf8e6 2004-05-16 devnull virtual int brkafter() { return 1; }
33 5f1cf8e6 2004-05-16 devnull virtual int isnested() { return 0; }
34 5f1cf8e6 2004-05-16 devnull virtual int issp() { return 0; }
35 5f1cf8e6 2004-05-16 devnull virtual int isvbox() { return 0; }
36 5f1cf8e6 2004-05-16 devnull virtual int isneed() { return 0; }
37 5f1cf8e6 2004-05-16 devnull virtual int iscmd() { return 0; }
38 5f1cf8e6 2004-05-16 devnull virtual int cmdtype() { return -1; }
39 5f1cf8e6 2004-05-16 devnull virtual int isparm() { return 0; }
40 5f1cf8e6 2004-05-16 devnull virtual int parmtype() { return -1; }
41 5f1cf8e6 2004-05-16 devnull virtual int parm() { return -1; }
42 5f1cf8e6 2004-05-16 devnull virtual int breakable() { return 0; }
43 5f1cf8e6 2004-05-16 devnull virtual int forceflush() { return UNEXPECTED; }
44 5f1cf8e6 2004-05-16 devnull virtual int pn() { return 0; }
45 5f1cf8e6 2004-05-16 devnull virtual stream *children() { return 0; } // see page::peeloff()
46 5f1cf8e6 2004-05-16 devnull virtual void killkids() { }
47 5f1cf8e6 2004-05-16 devnull virtual void enqueue(int = 0);
48 5f1cf8e6 2004-05-16 devnull virtual int height() { return 0; }
49 5f1cf8e6 2004-05-16 devnull virtual int rawht() { return 0; }
50 5f1cf8e6 2004-05-16 devnull virtual int needht() { return 0; }
51 5f1cf8e6 2004-05-16 devnull virtual void reheight(int *, int *) { }
52 5f1cf8e6 2004-05-16 devnull virtual void rerawht(int *, int *) { }
53 5f1cf8e6 2004-05-16 devnull virtual void setheight(int) { }
54 5f1cf8e6 2004-05-16 devnull virtual void restore() { } // goals of floatables
55 5f1cf8e6 2004-05-16 devnull virtual int goal() { return NOGOAL; }
56 5f1cf8e6 2004-05-16 devnull int accum() { return accumV; }
57 5f1cf8e6 2004-05-16 devnull void setaccum(int n) { accumV = n; }
58 5f1cf8e6 2004-05-16 devnull virtual void setgoal(int) { }
59 5f1cf8e6 2004-05-16 devnull virtual void pickgoal(int, double) { }
60 5f1cf8e6 2004-05-16 devnull virtual int numcol() { return first->numcol(); }
61 5f1cf8e6 2004-05-16 devnull virtual int issentinel() { return 0; }
62 5f1cf8e6 2004-05-16 devnull virtual range *clone() { return 0; }
63 5f1cf8e6 2004-05-16 devnull virtual int breaking() { return 0; }
64 5f1cf8e6 2004-05-16 devnull virtual void setbreaking() { }
67 5f1cf8e6 2004-05-16 devnull class vboxrange : public range {
68 5f1cf8e6 2004-05-16 devnull int dv; // inherited from slug
69 5f1cf8e6 2004-05-16 devnull int base; // inherited from slug
70 5f1cf8e6 2004-05-16 devnull int brk; // 0 => ok to break after, 1 => no break
72 5f1cf8e6 2004-05-16 devnull vboxrange(slug *p) : range(p) { dv = p->dv; base = p->base; brk = p->parm; }
73 5f1cf8e6 2004-05-16 devnull void dump() {
74 5f1cf8e6 2004-05-16 devnull printf("#### VBOX brk? %d dv %d ht %d\n", brk, dv, dv+base); }
75 5f1cf8e6 2004-05-16 devnull int print(int cv, int col) {
76 5f1cf8e6 2004-05-16 devnull printf("V%d\n", cv += dv); first->slugout(col); return cv+base; }
77 5f1cf8e6 2004-05-16 devnull int brkafter() { return !brk; }
78 5f1cf8e6 2004-05-16 devnull int isvbox() { return 1; }
79 5f1cf8e6 2004-05-16 devnull int forceflush() { return NO; }
80 5f1cf8e6 2004-05-16 devnull int height() { return dv + base; }
81 5f1cf8e6 2004-05-16 devnull int rawht() { return first->dv + first->base; }
82 5f1cf8e6 2004-05-16 devnull void reheight(int *cv, int *mv) {
83 5f1cf8e6 2004-05-16 devnull *cv += dv+base; *mv = max(*mv, *cv); }
84 5f1cf8e6 2004-05-16 devnull void rerawht(int *cv, int *mv) {
85 5f1cf8e6 2004-05-16 devnull *cv += rawht(); *mv = max(*mv, *cv); }
88 5f1cf8e6 2004-05-16 devnull class sprange : public range {
91 5f1cf8e6 2004-05-16 devnull sprange(slug *p) : range(p) { dv = first->dv; }
92 5f1cf8e6 2004-05-16 devnull void dump() {
93 5f1cf8e6 2004-05-16 devnull printf("#### SP dv %d (originally %d)\n", dv, first->dv); }
94 5f1cf8e6 2004-05-16 devnull int print(int cv, int col) {
95 5f1cf8e6 2004-05-16 devnull first->slugout(col); return cv + dv; }
96 5f1cf8e6 2004-05-16 devnull int issp() { return 1; }
97 5f1cf8e6 2004-05-16 devnull int forceflush() { return YES; }
98 5f1cf8e6 2004-05-16 devnull int height() { return dv; }
99 5f1cf8e6 2004-05-16 devnull int rawht() { return first->dv; }
100 5f1cf8e6 2004-05-16 devnull void reheight(int *, int *);
101 5f1cf8e6 2004-05-16 devnull void rerawht(int *, int *);
102 5f1cf8e6 2004-05-16 devnull void setheight(int n) { dv = n; }
105 5f1cf8e6 2004-05-16 devnull class tmrange : public range {
107 5f1cf8e6 2004-05-16 devnull tmrange(slug *p) : range(p) { }
108 5f1cf8e6 2004-05-16 devnull int forceflush() { return NO; }
109 5f1cf8e6 2004-05-16 devnull int print(int cv, int col) { first->slugout(col); return cv; }
112 5f1cf8e6 2004-05-16 devnull class coordrange : public range {
114 5f1cf8e6 2004-05-16 devnull coordrange(slug *p) : range(p) { }
115 5f1cf8e6 2004-05-16 devnull int forceflush() { return NO; }
116 5f1cf8e6 2004-05-16 devnull int print(int cv, int col)
117 5f1cf8e6 2004-05-16 devnull { first->slugout(col); printf(" Y %d\n", cv); return cv; }
120 5f1cf8e6 2004-05-16 devnull class nerange : public range {
122 5f1cf8e6 2004-05-16 devnull nerange(slug *p) : range(p) { }
123 5f1cf8e6 2004-05-16 devnull int isneed() { return 1; }
124 5f1cf8e6 2004-05-16 devnull int forceflush() { return YES; }
125 5f1cf8e6 2004-05-16 devnull int needht() { return first->dv; }
128 5f1cf8e6 2004-05-16 devnull class mcrange : public range {
130 5f1cf8e6 2004-05-16 devnull mcrange(slug *p) : range(p) { }
131 5f1cf8e6 2004-05-16 devnull int forceflush() { return YES; }
134 5f1cf8e6 2004-05-16 devnull class cmdrange : public range {
136 5f1cf8e6 2004-05-16 devnull cmdrange(slug *p) : range(p) { }
137 5f1cf8e6 2004-05-16 devnull int iscmd() { return 1; }
138 5f1cf8e6 2004-05-16 devnull int forceflush() { return YES; }
139 5f1cf8e6 2004-05-16 devnull int cmdtype() { return first->parm; }
142 5f1cf8e6 2004-05-16 devnull class parmrange : public range {
144 5f1cf8e6 2004-05-16 devnull parmrange(slug *p) : range(p) { }
145 5f1cf8e6 2004-05-16 devnull int isparm() { return 1; }
146 5f1cf8e6 2004-05-16 devnull int forceflush() { return YES; }
147 5f1cf8e6 2004-05-16 devnull int parmtype() { return first->parm; }
148 5f1cf8e6 2004-05-16 devnull int parm() { return first->parm2; }
151 5f1cf8e6 2004-05-16 devnull class bsrange : public range {
153 5f1cf8e6 2004-05-16 devnull bsrange(slug *p) : range(p) { }
154 5f1cf8e6 2004-05-16 devnull int forceflush() { return NO; }
155 5f1cf8e6 2004-05-16 devnull int print(int cv, int col) { first->slugout(col); return cv; }
158 5f1cf8e6 2004-05-16 devnull class endrange : public range {
160 5f1cf8e6 2004-05-16 devnull endrange(slug *p) : range(p) { }
161 5f1cf8e6 2004-05-16 devnull int forceflush() { return UNEXPECTED; }
164 5f1cf8e6 2004-05-16 devnull class eofrange : public range {
166 5f1cf8e6 2004-05-16 devnull eofrange(slug *p) : range(p) { }
167 5f1cf8e6 2004-05-16 devnull int forceflush() { return UNEXPECTED; }
170 5f1cf8e6 2004-05-16 devnull extern eofrange *lastrange; // the EOF block (trailer, etc.) goes here
172 5f1cf8e6 2004-05-16 devnull int measure(stream *);
173 5f1cf8e6 2004-05-16 devnull int rawmeasure(stream *);
175 5f1cf8e6 2004-05-16 devnull // A nestrange packages together a sequence of ranges, its subrange.
176 5f1cf8e6 2004-05-16 devnull // Other parts of the program reach in and alter the dimensions of
177 5f1cf8e6 2004-05-16 devnull // some of these ranges, so when the height of a range is requested
178 5f1cf8e6 2004-05-16 devnull // it is computed completely afresh.
179 5f1cf8e6 2004-05-16 devnull // (Note: the alternative, of keeping around many copies of ranges
180 5f1cf8e6 2004-05-16 devnull // with different dimensions, was abandoned because of the difficulty
181 5f1cf8e6 2004-05-16 devnull // of ensuring that exactly one copy of each original range would be
182 5f1cf8e6 2004-05-16 devnull // output.)
183 5f1cf8e6 2004-05-16 devnull class nestrange : public range {
184 5f1cf8e6 2004-05-16 devnull protected:
185 5f1cf8e6 2004-05-16 devnull stream *subrange;
186 5f1cf8e6 2004-05-16 devnull int isbreaking;
187 5f1cf8e6 2004-05-16 devnull int rawdv;
189 5f1cf8e6 2004-05-16 devnull nestrange() : range() { subrange = 0; isbreaking = 0; rawdv = -1; }
190 5f1cf8e6 2004-05-16 devnull nestrange(slug *p, stream *s) : range(p)
191 5f1cf8e6 2004-05-16 devnull { subrange = s; isbreaking = 0; rawdv = -1; }
192 5f1cf8e6 2004-05-16 devnull void rdump();
193 5f1cf8e6 2004-05-16 devnull virtual void restore();
194 5f1cf8e6 2004-05-16 devnull stream *children() { return subrange; }
195 5f1cf8e6 2004-05-16 devnull void killkids();
196 5f1cf8e6 2004-05-16 devnull int height() { return measure(subrange); }
197 5f1cf8e6 2004-05-16 devnull int rawht() { if (rawdv < 0 || isbreaking) rawdv = rawmeasure(subrange);
198 5f1cf8e6 2004-05-16 devnull return rawdv; }
199 5f1cf8e6 2004-05-16 devnull void reheight(int *cv, int *mv) {
200 5f1cf8e6 2004-05-16 devnull *mv += measure(subrange); *cv = max(*mv, *cv); }
201 5f1cf8e6 2004-05-16 devnull void rerawht(int *cv, int *mv) {
202 5f1cf8e6 2004-05-16 devnull *mv += rawht(); *cv = max(*mv, *cv); }
203 5f1cf8e6 2004-05-16 devnull int isnested() { return 1; }
204 5f1cf8e6 2004-05-16 devnull int forceflush() { return EXPECTED; }
205 5f1cf8e6 2004-05-16 devnull int print(int cv, int col);
206 5f1cf8e6 2004-05-16 devnull int breaking() { return isbreaking; }
207 5f1cf8e6 2004-05-16 devnull void setbreaking() { isbreaking++; }
210 5f1cf8e6 2004-05-16 devnull class usrange : public nestrange {
212 5f1cf8e6 2004-05-16 devnull usrange() { }
213 5f1cf8e6 2004-05-16 devnull usrange(slug *p, stream *s) : nestrange(p, s) {}
214 5f1cf8e6 2004-05-16 devnull void dump() { printf("#### US dv %d\n", height()); }
215 5f1cf8e6 2004-05-16 devnull range *clone();
218 5f1cf8e6 2004-05-16 devnull class ufrange : public nestrange {
219 5f1cf8e6 2004-05-16 devnull int goalV, goal2;
221 5f1cf8e6 2004-05-16 devnull ufrange() { }
222 5f1cf8e6 2004-05-16 devnull ufrange(slug *p, stream *s) : nestrange(p, s) {
223 5f1cf8e6 2004-05-16 devnull goalV = p->parm; goal2 = p->parm2; }
224 5f1cf8e6 2004-05-16 devnull void dump() { printf("#### UF dv %d goal %d goal2 %d\n",
225 5f1cf8e6 2004-05-16 devnull height(), goalV, goal2); }
226 5f1cf8e6 2004-05-16 devnull int floatable() { return 1; }
227 5f1cf8e6 2004-05-16 devnull void enqueue(int = 0);
228 5f1cf8e6 2004-05-16 devnull range *clone();
229 5f1cf8e6 2004-05-16 devnull int goal() { return goalV; }
230 5f1cf8e6 2004-05-16 devnull void setgoal(int n) { goalV = goal2 = n; }
231 5f1cf8e6 2004-05-16 devnull void pickgoal(int acv, double scale);
232 5f1cf8e6 2004-05-16 devnull void restore() { goalV = first->parm; goal2 = first->ht; }
235 5f1cf8e6 2004-05-16 devnull class bfrange : public nestrange {
236 5f1cf8e6 2004-05-16 devnull int goalV, goal2;
238 5f1cf8e6 2004-05-16 devnull bfrange() { }
239 5f1cf8e6 2004-05-16 devnull bfrange(slug *p, stream *s) : nestrange(p, s) {
240 5f1cf8e6 2004-05-16 devnull goalV = p->parm; goal2 = p->parm2; }
241 5f1cf8e6 2004-05-16 devnull void dump() { printf("#### BF dv %d goal %d goal2 %d\n",
242 5f1cf8e6 2004-05-16 devnull height(), goalV, goal2); }
243 5f1cf8e6 2004-05-16 devnull int floatable() { return 1; }
244 5f1cf8e6 2004-05-16 devnull void enqueue(int = 0);
245 5f1cf8e6 2004-05-16 devnull range *clone();
246 5f1cf8e6 2004-05-16 devnull int goal() { return goalV; }
247 5f1cf8e6 2004-05-16 devnull void setgoal(int n) { goalV = goal2 = n; }
248 5f1cf8e6 2004-05-16 devnull void pickgoal(int acv, double scale);
249 5f1cf8e6 2004-05-16 devnull void restore() { goalV = first->parm; goal2 = first->parm2; }
250 5f1cf8e6 2004-05-16 devnull int breakable() { return 1; } // can be broken
253 5f1cf8e6 2004-05-16 devnull class ptrange : public nestrange {
254 5f1cf8e6 2004-05-16 devnull int pgno;
256 5f1cf8e6 2004-05-16 devnull int pn() { return pgno; }
257 5f1cf8e6 2004-05-16 devnull ptrange(slug *p, stream *s) : nestrange(p, s) { pgno = p->parm; }
258 5f1cf8e6 2004-05-16 devnull void dump() { printf("#### PT pgno %d dv %d\n", pgno, height()); }
261 5f1cf8e6 2004-05-16 devnull class btrange : public nestrange {
262 5f1cf8e6 2004-05-16 devnull int pgno;
264 5f1cf8e6 2004-05-16 devnull btrange(slug *p, stream *s) : nestrange(p, s) { pgno = p->parm; }
265 5f1cf8e6 2004-05-16 devnull void dump() { printf("#### BT pgno %d dv %d\n", pgno, height()); }
268 5f1cf8e6 2004-05-16 devnull // A stream is a sequence of ranges; we use this data structure a lot
269 5f1cf8e6 2004-05-16 devnull // to traverse various sequences that crop up in page-making.
270 5f1cf8e6 2004-05-16 devnull class stream {
271 5f1cf8e6 2004-05-16 devnull protected:
273 5f1cf8e6 2004-05-16 devnull struct strblk { // ranges are linked by these blocks
274 5f1cf8e6 2004-05-16 devnull strblk *next;
275 5f1cf8e6 2004-05-16 devnull range *rp;
277 5f1cf8e6 2004-05-16 devnull strblk *first;
278 5f1cf8e6 2004-05-16 devnull strblk *last;
279 5f1cf8e6 2004-05-16 devnull strblk *curr;
281 5f1cf8e6 2004-05-16 devnull stream() { curr = last = first = 0; }
282 5f1cf8e6 2004-05-16 devnull stream(range *r) { curr = last = first = new strblk;
283 5f1cf8e6 2004-05-16 devnull last->rp = r; last->next = 0; }
284 5f1cf8e6 2004-05-16 devnull void freeall(); // note: not a destructor
285 5f1cf8e6 2004-05-16 devnull void dump(); // top level
286 5f1cf8e6 2004-05-16 devnull void rdump(); // recursive
287 5f1cf8e6 2004-05-16 devnull int restoreall();
288 5f1cf8e6 2004-05-16 devnull range *current() { return curr->rp; }
289 5f1cf8e6 2004-05-16 devnull range *next() { return curr && curr->next ? curr->next->rp : 0; }
290 5f1cf8e6 2004-05-16 devnull void advance() { curr = curr->next; }
291 5f1cf8e6 2004-05-16 devnull range *append(range *r);
292 5f1cf8e6 2004-05-16 devnull void split();
293 5f1cf8e6 2004-05-16 devnull int more() { return curr && curr->rp; }
294 5f1cf8e6 2004-05-16 devnull int height();
295 5f1cf8e6 2004-05-16 devnull int rawht();
298 5f1cf8e6 2004-05-16 devnull // A generator iterates through all the ranges of a stream
299 5f1cf8e6 2004-05-16 devnull // (not just the root ranges of nestranges).
300 5f1cf8e6 2004-05-16 devnull class generator {
301 5f1cf8e6 2004-05-16 devnull stream s;
302 5f1cf8e6 2004-05-16 devnull generator *child;
304 5f1cf8e6 2004-05-16 devnull generator() { child = 0; }
305 5f1cf8e6 2004-05-16 devnull generator(stream *sp) { s = *sp; child = 0; }
306 5f1cf8e6 2004-05-16 devnull range *next();
309 5f1cf8e6 2004-05-16 devnull extern stream ptlist, btlist; // page titles
311 05f5d46b 2006-02-17 devnull #undef INFINITY
312 5f1cf8e6 2004-05-16 devnull #define INFINITY 1000001
314 5f1cf8e6 2004-05-16 devnull // A queue is a distinguished kind of stream.
315 5f1cf8e6 2004-05-16 devnull // It keeps its contents in order by the serial numbers of the ranges.
316 5f1cf8e6 2004-05-16 devnull // A queue can be blocked from dequeuing something to indicate
317 5f1cf8e6 2004-05-16 devnull // that it's not worth considering the queue again on a given page.
318 5f1cf8e6 2004-05-16 devnull class queue : public stream {
319 5f1cf8e6 2004-05-16 devnull strblk *newguy;
320 5f1cf8e6 2004-05-16 devnull protected:
321 5f1cf8e6 2004-05-16 devnull int blocked;
322 5f1cf8e6 2004-05-16 devnull void check(char *);
324 5f1cf8e6 2004-05-16 devnull queue() : blocked(0) { }
325 5f1cf8e6 2004-05-16 devnull range *enqueue(range *r);
326 5f1cf8e6 2004-05-16 devnull range *dequeue();
327 5f1cf8e6 2004-05-16 devnull void block() { blocked = 1; }
328 5f1cf8e6 2004-05-16 devnull void unblock() { blocked = 0; }
329 5f1cf8e6 2004-05-16 devnull int more() { return !blocked && stream::more(); }
330 5f1cf8e6 2004-05-16 devnull int empty() { return !stream::more(); }
331 5f1cf8e6 2004-05-16 devnull int serialno() { return empty() ? INFINITY : current()->serialno(); }
334 5f1cf8e6 2004-05-16 devnull // functions in range.c
335 5f1cf8e6 2004-05-16 devnull void checkout();
336 5f1cf8e6 2004-05-16 devnull void startup(FILE *);