LinkedList returnList = new LinkedList();
BlockLevelLayoutManager curLM; // currently active LM
BlockLevelLayoutManager prevLM = null; // previously active LM
while ((curLM = (BlockLevelLayoutManager) getChildLM()) != null) {
LayoutContext childLC = new LayoutContext(0);
// curLM is a ?
childLC.setStackLimit(MinOptMax.subtract(context
.getStackLimit(), stackLimit));
childLC.setRefIPD(cellIPD);
// get elements from curLM
returnedList = curLM.getNextKnuthElements(childLC, alignment);
if (childLC.isKeepWithNextPending()) {
log.debug("child LM signals pending keep with next");
}
if (contentList.size() == 0 && childLC.isKeepWithPreviousPending()) {
context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false);
}
if (returnedList.size() == 1
&& ((ListElement)returnedList.getFirst()).isForcedBreak()) {
// a descendant of this block has break-before
if (returnList.size() == 0) {
// the first child (or its first child ...) has
// break-before;
// all this block, including space before, will be put in
// the
// following page
}
contentList.addAll(returnedList);
// "wrap" the Position inside each element
// moving the elements from contentList to returnList
returnedList = new LinkedList();
wrapPositionElements(contentList, returnList);
//Space resolution
SpaceResolver.resolveElementList(returnList);
return returnList;
} else {
if (prevLM != null) {
// there is a block handled by prevLM
// before the one handled by curLM
if (mustKeepTogether()
|| context.isKeepWithNextPending()
|| childLC.isKeepWithPreviousPending()) {
//Clear keep pending flag
context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false);
childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false);
// add an infinite penalty to forbid a break between
// blocks
contentList.add(new BreakElement(
new Position(this), KnuthElement.INFINITE, context));
//contentList.add(new KnuthPenalty(0,
// KnuthElement.INFINITE, false,
// new Position(this), false));
} else if (!((ListElement) contentList.getLast()).isGlue()) {
// add a null penalty to allow a break between blocks
contentList.add(new BreakElement(
new Position(this), 0, context));
//contentList.add(new KnuthPenalty(0, 0, false,
// new Position(this), false));
} else {
// the last element in contentList is a glue;
// it is a feasible breakpoint, there is no need to add
// a penalty
}
}
contentList.addAll(returnedList);
if (returnedList.size() == 0) {
//Avoid NoSuchElementException below (happens with empty blocks)
continue;
}
if (((ListElement)returnedList.getLast()).isForcedBreak()) {
// a descendant of this block has break-after
if (curLM.isFinished()) {
// there is no other content in this block;
// it's useless to add space after before a page break
setFinished(true);
}
returnedList = new LinkedList();
wrapPositionElements(contentList, returnList);
//Space resolution
SpaceResolver.resolveElementList(returnList);
return returnList;
}
}
if (childLC.isKeepWithNextPending()) {
//Clear and propagate
childLC.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false);
context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING);
}
prevLM = curLM;
}