Exemplo n.º 1
0
void page::cmdproc()
{
	if (stage->next())
		ERROR "more than a single command on bsqueue\n" FATAL;
	switch (stage->current()->cmdtype()) {
	case FC:	// freeze the current 2-column range and start a new one
		adddef(stage->dequeue());
		twocol->compose(FINAL);
		adddef(twocol);
		twocol = new multicol(this);
		break;
	case BP:	// force a page break
		adddef(stage->dequeue());
		squeue.block();
		break;
	case FL:	// flush out all floatables that precede this range:
			// no more stream input allowed until they're past
		if (stage->serialno() > ufqueue.serialno() ||
			stage->serialno() > bfqueue.serialno()) {
			range *r = stage->dequeue();
			r->enqueue(ANDBLOCK);
		} else
			adddef(stage->dequeue());
		break;
	default:
		stage->current()->dump();
		ERROR "unknown command\n" FATAL;
	}
}
Exemplo n.º 2
0
// 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
}