public List getNextKnuthElements()

in fop-core/src/main/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java [214:345]


    public List getNextKnuthElements(LayoutContext context, int alignment, Stack lmStack,
            Position restartPosition, LayoutManager restartAtLM) {
        referenceIPD = context.getRefIPD();
        LayoutContext childLC;

        List<ListElement> returnList = new LinkedList<ListElement>();

        if (!breakBeforeServed(context, returnList)) {
            return returnList;
        }

        addFirstVisibleMarks(returnList, context, alignment);

        // label
        childLC = makeChildLayoutContext(context);
        childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE);
        label.initialize();
        boolean labelDone = false;
        Stack labelLMStack = null;
        Position labelRestartPosition = null;
        LayoutManager labelRestartLM = null;
        if (restartPosition != null && restartPosition instanceof ListItemPosition) {
            ListItemPosition lip = (ListItemPosition) restartPosition;
            if (lip.labelLastIndex <= lip.labelFirstIndex) {
                labelDone = true;
            } else {
                labelRestartPosition = lip.getOriginalLabelPosition();
                labelRestartLM = labelRestartPosition.getLM();
                LayoutManager lm = labelRestartLM;
                labelLMStack = new Stack();
                while (lm != this) {
                    labelLMStack.push(lm);
                    lm = lm.getParent();
                    if (lm instanceof ListItemContentLayoutManager) {
                        lm = lm.getParent();
                    }
                }
            }
        }
        labelList = !labelDone ? label.getNextKnuthElements(childLC, alignment, labelLMStack,
                labelRestartPosition, labelRestartLM) : (List) new LinkedList<KnuthElement>();

        //Space resolution as if the contents were placed in a new reference area
        //(see 6.8.3, XSL 1.0, section on Constraints, last paragraph)
        SpaceResolver.resolveElementList(labelList);
        ElementListObserver.observe(labelList, "list-item-label", label.getPartFO().getId());

        context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending());
        this.keepWithNextPendingOnLabel = childLC.getKeepWithNextPending();

        // body
        childLC = makeChildLayoutContext(context);
        childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE);
        body.initialize();
        boolean bodyDone = false;
        Stack bodyLMStack = null;
        Position bodyRestartPosition = null;
        LayoutManager bodyRestartLM = null;
        if (restartPosition != null && restartPosition instanceof ListItemPosition) {
            ListItemPosition lip = (ListItemPosition) restartPosition;
            if (lip.bodyLastIndex <= lip.bodyFirstIndex) {
                bodyDone = true;
            } else {
                bodyRestartPosition = lip.getOriginalBodyPosition();
                bodyRestartLM = bodyRestartPosition.getLM();
                LayoutManager lm = bodyRestartLM;
                bodyLMStack = new Stack();
                while (lm != this) {
                    bodyLMStack.push(lm);
                    lm = lm.getParent();
                    if (lm instanceof ListItemContentLayoutManager) {
                        lm = lm.getParent();
                    }
                }
            }
        }
        bodyList = !bodyDone ? body.getNextKnuthElements(childLC, alignment, bodyLMStack,
                bodyRestartPosition, bodyRestartLM) : (List) new LinkedList<KnuthElement>();

        //Space resolution as if the contents were placed in a new reference area
        //(see 6.8.3, XSL 1.0, section on Constraints, last paragraph)
        SpaceResolver.resolveElementList(bodyList);
        ElementListObserver.observe(bodyList, "list-item-body", body.getPartFO().getId());

        context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending());
        this.keepWithNextPendingOnBody = childLC.getKeepWithNextPending();

        List<ListElement> returnedList = new LinkedList<ListElement>();
        if (!labelList.isEmpty() && labelList.get(0) instanceof KnuthBlockBox) {
            KnuthBlockBox kbb = (KnuthBlockBox) labelList.get(0);
            if (kbb.getWidth() == 0 && kbb.hasFloatAnchors()) {
                List<FloatContentLayoutManager> floats = kbb.getFloatContentLMs();
                returnedList.add(new KnuthBlockBox(0, Collections.emptyList(), null, false, floats));
                Keep keep = getKeepTogether();
                returnedList.add(new BreakElement(new LeafPosition(this, 0), keep.getPenalty(), keep
                        .getContext(), context));
                labelList.remove(0);
                labelList.remove(0);
            }
        }
        if (!bodyList.isEmpty() && bodyList.get(0) instanceof KnuthBlockBox) {
            KnuthBlockBox kbb = (KnuthBlockBox) bodyList.get(0);
            if (kbb.getWidth() == 0 && kbb.hasFloatAnchors()) {
                List<FloatContentLayoutManager> floats = kbb.getFloatContentLMs();
                returnedList.add(new KnuthBlockBox(0, Collections.emptyList(), null, false, floats));
                Keep keep = getKeepTogether();
                returnedList.add(new BreakElement(new LeafPosition(this, 0), keep.getPenalty(), keep
                        .getContext(), context));
                bodyList.remove(0);
                bodyList.remove(0);
            }
        }

        // create a combined list
        returnedList.addAll(getCombinedKnuthElementsForListItem(labelList, bodyList, context));

        // "wrap" the Position inside each element
        wrapPositionElements(returnedList, returnList, true);

        addLastVisibleMarks(returnList, context, alignment);

        addKnuthElementsForBreakAfter(returnList, context);

        context.updateKeepWithNextPending(this.keepWithNextPendingOnLabel);
        context.updateKeepWithNextPending(this.keepWithNextPendingOnBody);
        context.updateKeepWithNextPending(getKeepWithNext());
        context.updateKeepWithPreviousPending(getKeepWithPrevious());

        setFinished(true);
        resetSpaces();
        return returnList;
    }