10 // We use the stream function current() to access a queue's head.
11 // Thus, queue member curr should always point to its first range.
12 void queue::check(char *whence)
18 else if (this == &bfqueue)
20 else if (this == &ufqueue)
24 printf("#checking %s\n", p);
27 ERROR "check(%s): first != curr, line %d\n", whence, curr->rp->lineno() FATAL;
30 // When ranges are told to enqueue themselves, they are being rejected from the
31 // stage back onto their original queues.
32 // They reset any parameters that may have been altered by staging or trial
35 void range::enqueue(int block)
42 void ufrange::enqueue(int block)
44 restore(); // both goal positions
45 ufqueue.enqueue(this);
50 void bfrange::enqueue(int block)
52 restore(); // both goal positions
53 bfqueue.enqueue(this);
60 return !(squeue.empty() && ufqueue.empty() && bfqueue.empty());
63 void mergestream::unblock()
70 // Fill the staging area with a minimal chunk of input ranges.
71 int mergestream::prime()
74 printf("#entering mergestream::prime()\n");
77 int brkok = 1; // is it OK to break after the last
78 // VBOX that was added to the stage?
79 int needheight = -1; // minimum acceptable height of the
80 // chunk being constructed on stage
81 // If the range at the head of any queue is breaking,
82 // deal with it first.
83 if (squeue.more() && squeue.current()->breaking())
84 enqueue(squeue.dequeue());
85 else if (bfqueue.more() && (bfqueue.current()->breaking() ||
86 (bfqueue.serialno() < squeue.serialno())))
87 enqueue(bfqueue.dequeue());
88 else if (ufqueue.more() && (ufqueue.current()->breaking() ||
89 (ufqueue.serialno() < squeue.serialno())))
90 enqueue(ufqueue.dequeue());
91 else while (squeue.more()) {
92 // Fill the stage with enough ranges to be a valid chunk.
93 range *r = squeue.dequeue();
94 if (r->isvbox()) { // VBOX
96 printf("#VBOX: !empty: %d; brkok: %d; vsince: %d\n",
97 !empty(), brkok, currpage->vsince);
98 if (!empty() // there's something there
100 // it's OK to break here
101 && currpage->vsince >= 2
102 // enough stream has gone onto this page
103 && rawht() >= needheight
104 // current need has been satisfied
106 // the stage already contains enough
107 // ranges, so this one can wait
111 if (r->rawht() > 0) {
113 brkok = r->brkafter();
117 } else if (r->isnested() || r->issp()) { // US, SP
118 if (!empty() && rawht() >= needheight) {
119 // enough already, wait
123 currpage->vsince = 0;
125 if (height() >= needheight)
127 } else if (r->isneed()) { // NE
128 if (!empty() && rawht() >= needheight) {
129 // not currently working on an unsatisfied NEed
133 // deal with overlapping NEeds
134 needheight = rawht() + max(needheight - rawht(), r->needht());
136 } else if (r->forceflush() == NO) {
138 } else if (r->forceflush() == YES) {
139 currpage->vsince = 0;
141 // ready or not, r must wait
148 ERROR "unexpected %s[%s] in prime(), line %d\n",
149 r->typename(), r->headstr(), r->lineno() FATAL;
151 return more(); // 0 if nothing was staged
157 ERROR "more than a single command on bsqueue\n" FATAL;
158 switch (stage->current()->cmdtype()) {
159 case FC: // freeze the current 2-column range and start a new one
160 adddef(stage->dequeue());
161 twocol->compose(FINAL);
163 twocol = new multicol(this);
165 case BP: // force a page break
166 adddef(stage->dequeue());
169 case FL: // flush out all floatables that precede this range:
170 // no more stream input allowed until they're past
171 if (stage->serialno() > ufqueue.serialno() ||
172 stage->serialno() > bfqueue.serialno()) {
173 range *r = stage->dequeue();
174 r->enqueue(ANDBLOCK);
176 adddef(stage->dequeue());
179 stage->current()->dump();
180 ERROR "unknown command\n" FATAL;
184 void page::parmproc()
187 ERROR "more than a single parameter on bsqueue\n" FATAL;
188 switch (stage->current()->parmtype()) {
189 case NP: // page top margin
191 pagetop = stage->current()->parm();
192 pagesize = pagebot - pagetop;
196 pagebot = stage->current()->parm();
197 pagesize = pagebot - pagetop;
201 physbot = stage->current()->parm();
204 minfull = 0.01*stage->current()->parm();
207 coltol = 0.01*stage->current()->parm();
210 wantwarn = stage->current()->parm();
213 dbg = stage->current()->parm();
216 stage->current()->dump();
217 ERROR "unknown parameter\n" FATAL;
219 adddef(stage->dequeue());
222 // Process the contents of the staging area; a relic that used to do more.
223 void mergestream::pend()
226 printf("#entering mergestream::pend()\n");
229 if (current()->iscmd())
231 else if (current()->isparm())
232 currpage->parmproc();