示例#1
0
文件: queue.c 项目: n-t-roff/DWB3.3
// Fill the staging area with a minimal chunk of input ranges.
int mergestream::prime()
{
	if (dbg & 4)
		printf("#entering mergestream::prime()\n");
	if (!empty())
		return 1;
	int brkok = 1;			// is it OK to break after the last
					// VBOX that was added to the stage?
	int needheight = -1;		// minimum acceptable height of the
					// chunk being constructed on stage
	// If the range at the head of any queue is breaking,
	// deal with it first.
	if (squeue.more() && squeue.current()->breaking())
		enqueue(squeue.dequeue());
	else if (bfqueue.more() && (bfqueue.current()->breaking() ||
		(bfqueue.serialno() < squeue.serialno())))
		enqueue(bfqueue.dequeue());
	else if (ufqueue.more() && (ufqueue.current()->breaking() ||
		(ufqueue.serialno() < squeue.serialno())))
		enqueue(ufqueue.dequeue());
	else while (squeue.more()) {
		// Fill the stage with enough ranges to be a valid chunk.
		range *r = squeue.dequeue();
		if (r->isvbox()) {	// VBOX
			if (dbg & 16)
				printf("#VBOX: !empty: %d; brkok: %d; vsince: %d\n",
					!empty(), brkok, currpage->vsince);
			if (!empty()	// there's something there
				&& brkok
					// it's OK to break here
				&& currpage->vsince >= 2
					// enough stream has gone onto this page
				&& rawht() >= needheight
					// current need has been satisfied
				) {
					// the stage already contains enough
					// ranges, so this one can wait
				r->enqueue();
				break;
			} else {
				if (r->rawht() > 0) {
					++currpage->vsince;
					brkok = r->brkafter();
				}
				enqueue(r);
			}
		} else if (r->isnested() || r->issp()) {	// US, SP
			if (!empty() && rawht() >= needheight) {
					// enough already, wait
				r->enqueue();
				break;
			}
			currpage->vsince = 0;
			enqueue(r);
			if (height() >= needheight)
				break;
		} else if (r->isneed()) {	// NE
			if (!empty() && rawht() >= needheight) {
					// not currently working on an unsatisfied NEed 
				r->enqueue();
				break;
			}
					// deal with overlapping NEeds
			needheight = rawht() + max(needheight - rawht(), r->needht());
			enqueue(r);
		} else if (r->forceflush() == NO) {
			enqueue(r);
		} else if (r->forceflush() == YES) {
			currpage->vsince = 0;
			if (!empty()) {
					// ready or not, r must wait
				r->enqueue();
				break;
			}
			enqueue(r);
			break;
		} else
			ERROR "unexpected  %s[%s] in prime(), line %d\n",
				r->type_name(), r->headstr(), r->lineno() FATAL;
	}
	return more();			// 0 if nothing was staged
}