Blame


1 5f1cf8e6 2004-05-16 devnull #include "misc.h"
2 5f1cf8e6 2004-05-16 devnull #include "slug.h"
3 5f1cf8e6 2004-05-16 devnull #include "range.h"
4 5f1cf8e6 2004-05-16 devnull #include "page.h"
5 5f1cf8e6 2004-05-16 devnull
6 5f1cf8e6 2004-05-16 devnull queue squeue;
7 5f1cf8e6 2004-05-16 devnull queue bfqueue;
8 5f1cf8e6 2004-05-16 devnull queue ufqueue;
9 5f1cf8e6 2004-05-16 devnull
10 5f1cf8e6 2004-05-16 devnull // We use the stream function current() to access a queue's head.
11 5f1cf8e6 2004-05-16 devnull // Thus, queue member curr should always point to its first range.
12 5f1cf8e6 2004-05-16 devnull void queue::check(char *whence)
13 5f1cf8e6 2004-05-16 devnull {
14 5f1cf8e6 2004-05-16 devnull if (dbg & 8) {
15 5f1cf8e6 2004-05-16 devnull char *p;
16 5f1cf8e6 2004-05-16 devnull if (this == &squeue)
17 5f1cf8e6 2004-05-16 devnull p = "squeue";
18 5f1cf8e6 2004-05-16 devnull else if (this == &bfqueue)
19 5f1cf8e6 2004-05-16 devnull p = "bfqueue";
20 5f1cf8e6 2004-05-16 devnull else if (this == &ufqueue)
21 5f1cf8e6 2004-05-16 devnull p = "ufqueue";
22 5f1cf8e6 2004-05-16 devnull else
23 5f1cf8e6 2004-05-16 devnull p = "weird queue";
24 5f1cf8e6 2004-05-16 devnull printf("#checking %s\n", p);
25 5f1cf8e6 2004-05-16 devnull }
26 5f1cf8e6 2004-05-16 devnull if (first != curr)
27 5f1cf8e6 2004-05-16 devnull ERROR "check(%s): first != curr, line %d\n", whence, curr->rp->lineno() FATAL;
28 5f1cf8e6 2004-05-16 devnull }
29 5f1cf8e6 2004-05-16 devnull
30 5f1cf8e6 2004-05-16 devnull // When ranges are told to enqueue themselves, they are being rejected from the
31 5f1cf8e6 2004-05-16 devnull // stage back onto their original queues.
32 5f1cf8e6 2004-05-16 devnull // They reset any parameters that may have been altered by staging or trial
33 5f1cf8e6 2004-05-16 devnull // composition.
34 5f1cf8e6 2004-05-16 devnull
35 5f1cf8e6 2004-05-16 devnull void range::enqueue(int block)
36 5f1cf8e6 2004-05-16 devnull {
37 5f1cf8e6 2004-05-16 devnull squeue.enqueue(this);
38 5f1cf8e6 2004-05-16 devnull if (block)
39 5f1cf8e6 2004-05-16 devnull squeue.block();
40 5f1cf8e6 2004-05-16 devnull }
41 5f1cf8e6 2004-05-16 devnull
42 5f1cf8e6 2004-05-16 devnull void ufrange::enqueue(int block)
43 5f1cf8e6 2004-05-16 devnull {
44 5f1cf8e6 2004-05-16 devnull restore(); // both goal positions
45 5f1cf8e6 2004-05-16 devnull ufqueue.enqueue(this);
46 5f1cf8e6 2004-05-16 devnull if (block)
47 5f1cf8e6 2004-05-16 devnull ufqueue.block();
48 5f1cf8e6 2004-05-16 devnull }
49 5f1cf8e6 2004-05-16 devnull
50 5f1cf8e6 2004-05-16 devnull void bfrange::enqueue(int block)
51 5f1cf8e6 2004-05-16 devnull {
52 5f1cf8e6 2004-05-16 devnull restore(); // both goal positions
53 5f1cf8e6 2004-05-16 devnull bfqueue.enqueue(this);
54 5f1cf8e6 2004-05-16 devnull if (block)
55 5f1cf8e6 2004-05-16 devnull bfqueue.block();
56 5f1cf8e6 2004-05-16 devnull }
57 5f1cf8e6 2004-05-16 devnull
58 5f1cf8e6 2004-05-16 devnull int anymore()
59 5f1cf8e6 2004-05-16 devnull {
60 5f1cf8e6 2004-05-16 devnull return !(squeue.empty() && ufqueue.empty() && bfqueue.empty());
61 5f1cf8e6 2004-05-16 devnull }
62 5f1cf8e6 2004-05-16 devnull
63 5f1cf8e6 2004-05-16 devnull void mergestream::unblock()
64 5f1cf8e6 2004-05-16 devnull {
65 5f1cf8e6 2004-05-16 devnull squeue.unblock();
66 5f1cf8e6 2004-05-16 devnull bfqueue.unblock();
67 5f1cf8e6 2004-05-16 devnull ufqueue.unblock();
68 5f1cf8e6 2004-05-16 devnull }
69 5f1cf8e6 2004-05-16 devnull
70 5f1cf8e6 2004-05-16 devnull // Fill the staging area with a minimal chunk of input ranges.
71 5f1cf8e6 2004-05-16 devnull int mergestream::prime()
72 5f1cf8e6 2004-05-16 devnull {
73 5f1cf8e6 2004-05-16 devnull if (dbg & 4)
74 5f1cf8e6 2004-05-16 devnull printf("#entering mergestream::prime()\n");
75 5f1cf8e6 2004-05-16 devnull if (!empty())
76 5f1cf8e6 2004-05-16 devnull return 1;
77 5f1cf8e6 2004-05-16 devnull int brkok = 1; // is it OK to break after the last
78 5f1cf8e6 2004-05-16 devnull // VBOX that was added to the stage?
79 5f1cf8e6 2004-05-16 devnull int needheight = -1; // minimum acceptable height of the
80 5f1cf8e6 2004-05-16 devnull // chunk being constructed on stage
81 5f1cf8e6 2004-05-16 devnull // If the range at the head of any queue is breaking,
82 5f1cf8e6 2004-05-16 devnull // deal with it first.
83 5f1cf8e6 2004-05-16 devnull if (squeue.more() && squeue.current()->breaking())
84 5f1cf8e6 2004-05-16 devnull enqueue(squeue.dequeue());
85 5f1cf8e6 2004-05-16 devnull else if (bfqueue.more() && (bfqueue.current()->breaking() ||
86 5f1cf8e6 2004-05-16 devnull (bfqueue.serialno() < squeue.serialno())))
87 5f1cf8e6 2004-05-16 devnull enqueue(bfqueue.dequeue());
88 5f1cf8e6 2004-05-16 devnull else if (ufqueue.more() && (ufqueue.current()->breaking() ||
89 5f1cf8e6 2004-05-16 devnull (ufqueue.serialno() < squeue.serialno())))
90 5f1cf8e6 2004-05-16 devnull enqueue(ufqueue.dequeue());
91 5f1cf8e6 2004-05-16 devnull else while (squeue.more()) {
92 5f1cf8e6 2004-05-16 devnull // Fill the stage with enough ranges to be a valid chunk.
93 5f1cf8e6 2004-05-16 devnull range *r = squeue.dequeue();
94 5f1cf8e6 2004-05-16 devnull if (r->isvbox()) { // VBOX
95 5f1cf8e6 2004-05-16 devnull if (dbg & 16)
96 5f1cf8e6 2004-05-16 devnull printf("#VBOX: !empty: %d; brkok: %d; vsince: %d\n",
97 5f1cf8e6 2004-05-16 devnull !empty(), brkok, currpage->vsince);
98 5f1cf8e6 2004-05-16 devnull if (!empty() // there's something there
99 5f1cf8e6 2004-05-16 devnull && brkok
100 5f1cf8e6 2004-05-16 devnull // it's OK to break here
101 5f1cf8e6 2004-05-16 devnull && currpage->vsince >= 2
102 5f1cf8e6 2004-05-16 devnull // enough stream has gone onto this page
103 5f1cf8e6 2004-05-16 devnull && rawht() >= needheight
104 5f1cf8e6 2004-05-16 devnull // current need has been satisfied
105 5f1cf8e6 2004-05-16 devnull ) {
106 5f1cf8e6 2004-05-16 devnull // the stage already contains enough
107 5f1cf8e6 2004-05-16 devnull // ranges, so this one can wait
108 5f1cf8e6 2004-05-16 devnull r->enqueue();
109 5f1cf8e6 2004-05-16 devnull break;
110 5f1cf8e6 2004-05-16 devnull } else {
111 5f1cf8e6 2004-05-16 devnull if (r->rawht() > 0) {
112 5f1cf8e6 2004-05-16 devnull ++currpage->vsince;
113 5f1cf8e6 2004-05-16 devnull brkok = r->brkafter();
114 5f1cf8e6 2004-05-16 devnull }
115 5f1cf8e6 2004-05-16 devnull enqueue(r);
116 5f1cf8e6 2004-05-16 devnull }
117 5f1cf8e6 2004-05-16 devnull } else if (r->isnested() || r->issp()) { // US, SP
118 5f1cf8e6 2004-05-16 devnull if (!empty() && rawht() >= needheight) {
119 5f1cf8e6 2004-05-16 devnull // enough already, wait
120 5f1cf8e6 2004-05-16 devnull r->enqueue();
121 5f1cf8e6 2004-05-16 devnull break;
122 5f1cf8e6 2004-05-16 devnull }
123 5f1cf8e6 2004-05-16 devnull currpage->vsince = 0;
124 5f1cf8e6 2004-05-16 devnull enqueue(r);
125 5f1cf8e6 2004-05-16 devnull if (height() >= needheight)
126 5f1cf8e6 2004-05-16 devnull break;
127 5f1cf8e6 2004-05-16 devnull } else if (r->isneed()) { // NE
128 5f1cf8e6 2004-05-16 devnull if (!empty() && rawht() >= needheight) {
129 5f1cf8e6 2004-05-16 devnull // not currently working on an unsatisfied NEed
130 5f1cf8e6 2004-05-16 devnull r->enqueue();
131 5f1cf8e6 2004-05-16 devnull break;
132 5f1cf8e6 2004-05-16 devnull }
133 5f1cf8e6 2004-05-16 devnull // deal with overlapping NEeds
134 5f1cf8e6 2004-05-16 devnull needheight = rawht() + max(needheight - rawht(), r->needht());
135 5f1cf8e6 2004-05-16 devnull enqueue(r);
136 5f1cf8e6 2004-05-16 devnull } else if (r->forceflush() == NO) {
137 5f1cf8e6 2004-05-16 devnull enqueue(r);
138 5f1cf8e6 2004-05-16 devnull } else if (r->forceflush() == YES) {
139 5f1cf8e6 2004-05-16 devnull currpage->vsince = 0;
140 5f1cf8e6 2004-05-16 devnull if (!empty()) {
141 5f1cf8e6 2004-05-16 devnull // ready or not, r must wait
142 5f1cf8e6 2004-05-16 devnull r->enqueue();
143 5f1cf8e6 2004-05-16 devnull break;
144 5f1cf8e6 2004-05-16 devnull }
145 5f1cf8e6 2004-05-16 devnull enqueue(r);
146 5f1cf8e6 2004-05-16 devnull break;
147 5f1cf8e6 2004-05-16 devnull } else
148 5f1cf8e6 2004-05-16 devnull ERROR "unexpected %s[%s] in prime(), line %d\n",
149 5f1cf8e6 2004-05-16 devnull r->typename(), r->headstr(), r->lineno() FATAL;
150 5f1cf8e6 2004-05-16 devnull }
151 5f1cf8e6 2004-05-16 devnull return more(); // 0 if nothing was staged
152 5f1cf8e6 2004-05-16 devnull }
153 5f1cf8e6 2004-05-16 devnull
154 5f1cf8e6 2004-05-16 devnull void page::cmdproc()
155 5f1cf8e6 2004-05-16 devnull {
156 5f1cf8e6 2004-05-16 devnull if (stage->next())
157 5f1cf8e6 2004-05-16 devnull ERROR "more than a single command on bsqueue\n" FATAL;
158 5f1cf8e6 2004-05-16 devnull switch (stage->current()->cmdtype()) {
159 5f1cf8e6 2004-05-16 devnull case FC: // freeze the current 2-column range and start a new one
160 5f1cf8e6 2004-05-16 devnull adddef(stage->dequeue());
161 5f1cf8e6 2004-05-16 devnull twocol->compose(FINAL);
162 5f1cf8e6 2004-05-16 devnull adddef(twocol);
163 5f1cf8e6 2004-05-16 devnull twocol = new multicol(this);
164 5f1cf8e6 2004-05-16 devnull break;
165 5f1cf8e6 2004-05-16 devnull case BP: // force a page break
166 5f1cf8e6 2004-05-16 devnull adddef(stage->dequeue());
167 5f1cf8e6 2004-05-16 devnull squeue.block();
168 5f1cf8e6 2004-05-16 devnull break;
169 5f1cf8e6 2004-05-16 devnull case FL: // flush out all floatables that precede this range:
170 5f1cf8e6 2004-05-16 devnull // no more stream input allowed until they're past
171 5f1cf8e6 2004-05-16 devnull if (stage->serialno() > ufqueue.serialno() ||
172 5f1cf8e6 2004-05-16 devnull stage->serialno() > bfqueue.serialno()) {
173 5f1cf8e6 2004-05-16 devnull range *r = stage->dequeue();
174 5f1cf8e6 2004-05-16 devnull r->enqueue(ANDBLOCK);
175 5f1cf8e6 2004-05-16 devnull } else
176 5f1cf8e6 2004-05-16 devnull adddef(stage->dequeue());
177 5f1cf8e6 2004-05-16 devnull break;
178 5f1cf8e6 2004-05-16 devnull default:
179 5f1cf8e6 2004-05-16 devnull stage->current()->dump();
180 5f1cf8e6 2004-05-16 devnull ERROR "unknown command\n" FATAL;
181 5f1cf8e6 2004-05-16 devnull }
182 5f1cf8e6 2004-05-16 devnull }
183 5f1cf8e6 2004-05-16 devnull
184 5f1cf8e6 2004-05-16 devnull void page::parmproc()
185 5f1cf8e6 2004-05-16 devnull {
186 5f1cf8e6 2004-05-16 devnull if (stage->next())
187 5f1cf8e6 2004-05-16 devnull ERROR "more than a single parameter on bsqueue\n" FATAL;
188 5f1cf8e6 2004-05-16 devnull switch (stage->current()->parmtype()) {
189 5f1cf8e6 2004-05-16 devnull case NP: // page top margin
190 5f1cf8e6 2004-05-16 devnull if (blank())
191 5f1cf8e6 2004-05-16 devnull pagetop = stage->current()->parm();
192 5f1cf8e6 2004-05-16 devnull pagesize = pagebot - pagetop;
193 5f1cf8e6 2004-05-16 devnull break;
194 5f1cf8e6 2004-05-16 devnull case FO:
195 5f1cf8e6 2004-05-16 devnull if (blank())
196 5f1cf8e6 2004-05-16 devnull pagebot = stage->current()->parm();
197 5f1cf8e6 2004-05-16 devnull pagesize = pagebot - pagetop;
198 5f1cf8e6 2004-05-16 devnull break;
199 5f1cf8e6 2004-05-16 devnull case PL:
200 5f1cf8e6 2004-05-16 devnull if (blank())
201 5f1cf8e6 2004-05-16 devnull physbot = stage->current()->parm();
202 5f1cf8e6 2004-05-16 devnull break;
203 5f1cf8e6 2004-05-16 devnull case MF:
204 5f1cf8e6 2004-05-16 devnull minfull = 0.01*stage->current()->parm();
205 5f1cf8e6 2004-05-16 devnull break;
206 5f1cf8e6 2004-05-16 devnull case CT:
207 5f1cf8e6 2004-05-16 devnull coltol = 0.01*stage->current()->parm();
208 5f1cf8e6 2004-05-16 devnull break;
209 5f1cf8e6 2004-05-16 devnull case WARN:
210 5f1cf8e6 2004-05-16 devnull wantwarn = stage->current()->parm();
211 5f1cf8e6 2004-05-16 devnull break;
212 5f1cf8e6 2004-05-16 devnull case DBG:
213 5f1cf8e6 2004-05-16 devnull dbg = stage->current()->parm();
214 5f1cf8e6 2004-05-16 devnull break;
215 5f1cf8e6 2004-05-16 devnull default:
216 5f1cf8e6 2004-05-16 devnull stage->current()->dump();
217 5f1cf8e6 2004-05-16 devnull ERROR "unknown parameter\n" FATAL;
218 5f1cf8e6 2004-05-16 devnull }
219 5f1cf8e6 2004-05-16 devnull adddef(stage->dequeue());
220 5f1cf8e6 2004-05-16 devnull }
221 5f1cf8e6 2004-05-16 devnull
222 5f1cf8e6 2004-05-16 devnull // Process the contents of the staging area; a relic that used to do more.
223 5f1cf8e6 2004-05-16 devnull void mergestream::pend()
224 5f1cf8e6 2004-05-16 devnull {
225 5f1cf8e6 2004-05-16 devnull if (dbg & 4)
226 5f1cf8e6 2004-05-16 devnull printf("#entering mergestream::pend()\n");
227 5f1cf8e6 2004-05-16 devnull if (!more())
228 5f1cf8e6 2004-05-16 devnull return;
229 5f1cf8e6 2004-05-16 devnull if (current()->iscmd())
230 5f1cf8e6 2004-05-16 devnull currpage->cmdproc();
231 5f1cf8e6 2004-05-16 devnull else if (current()->isparm())
232 5f1cf8e6 2004-05-16 devnull currpage->parmproc();
233 5f1cf8e6 2004-05-16 devnull else
234 5f1cf8e6 2004-05-16 devnull currpage->tryout();
235 5f1cf8e6 2004-05-16 devnull }