public LinkedList getCombinedKnuthElementsForRowGroup()

in fop-core/src/main/java/org/apache/fop/layoutmgr/table/TableStepper.java [177:293]


    public LinkedList getCombinedKnuthElementsForRowGroup(LayoutContext context, EffRow[] rows,
            int bodyType) {
        setup(rows);
        activateCells(activeCells, 0);
        calcTotalHeight();

        int cumulateLength = 0; // Length of the content accumulated before the break
        TableContentPosition lastTCPos = null;
        LinkedList returnList = new LinkedList();
        int laststep = 0;
        int step = getFirstStep();
        do {
            int maxRemainingHeight = getMaxRemainingHeight();
            int penaltyOrGlueLen = step + maxRemainingHeight - totalHeight;
            int boxLen = step - cumulateLength - Math.max(0, penaltyOrGlueLen)/* penalty, if any */;
            cumulateLength += boxLen + Math.max(0, -penaltyOrGlueLen)/* the glue, if any */;

            if (log.isDebugEnabled()) {
                log.debug("Next step: " + step + " (+" + (step - laststep) + ")");
                log.debug("           max remaining height: " + maxRemainingHeight);
                if (penaltyOrGlueLen >= 0) {
                    log.debug("           box = " + boxLen + " penalty = " + penaltyOrGlueLen);
                } else {
                    log.debug("           box = " + boxLen + " glue = " + (-penaltyOrGlueLen));
                }
            }

            LinkedList footnoteList = new LinkedList();
            //Put all involved grid units into a list
            List cellParts = new java.util.ArrayList(activeCells.size());
            for (Object activeCell2 : activeCells) {
                ActiveCell activeCell = (ActiveCell) activeCell2;
                CellPart part = activeCell.createCellPart();
                cellParts.add(part);
                activeCell.addFootnotes(footnoteList);
            }

            //Create elements for step
            TableContentPosition tcpos = new TableContentPosition(getTableLM(),
                    cellParts, rowGroup[activeRowIndex]);
            if (delayingNextRow) {
                tcpos.setNewPageRow(rowGroup[activeRowIndex + 1]);
            }
            if (returnList.size() == 0) {
                tcpos.setFlag(TableContentPosition.FIRST_IN_ROWGROUP, true);
            }
            lastTCPos = tcpos;

            // TODO TableStepper should remain as footnote-agnostic as possible
            if (footnoteList.isEmpty()) {
                returnList.add(new KnuthBox(boxLen, tcpos, false));
            } else {
                returnList.add(new KnuthBlockBox(boxLen, footnoteList, tcpos, false));
            }

            int effPenaltyLen = Math.max(0, penaltyOrGlueLen);
            TableHFPenaltyPosition penaltyPos = new TableHFPenaltyPosition(getTableLM());
            if (bodyType == TableRowIterator.BODY) {
                if (!getTableLM().getTable().omitHeaderAtBreak()) {
                    effPenaltyLen += tclm.getHeaderNetHeight();
                    penaltyPos.headerElements = tclm.getHeaderElements();
                }
                if (!getTableLM().getTable().omitFooterAtBreak()) {
                    effPenaltyLen += tclm.getFooterNetHeight();
                    penaltyPos.footerElements = tclm.getFooterElements();
                }
            }

            Keep keep = getTableLM().getKeepTogether();
            int stepPenalty = 0;
            for (Object activeCell1 : activeCells) {
                ActiveCell activeCell = (ActiveCell) activeCell1;
                keep = keep.compare(activeCell.getKeepWithNext());
                stepPenalty = Math.max(stepPenalty, activeCell.getPenaltyValue());
            }
            if (!rowFinished) {
                keep = keep.compare(rowGroup[activeRowIndex].getKeepTogether());
            } else if (activeRowIndex < rowGroup.length - 1) {
                keep = keep.compare(rowGroup[activeRowIndex].getKeepWithNext());
                keep = keep.compare(rowGroup[activeRowIndex + 1].getKeepWithPrevious());
                nextBreakClass = BreakUtil.compareBreakClasses(nextBreakClass,
                        rowGroup[activeRowIndex].getBreakAfter());
                nextBreakClass = BreakUtil.compareBreakClasses(nextBreakClass,
                        rowGroup[activeRowIndex + 1].getBreakBefore());
            }
            int p = keep.getPenalty();
            if (rowHeightSmallerThanFirstStep) {
                rowHeightSmallerThanFirstStep = false;
                p = KnuthPenalty.INFINITE;
            }
            p = Math.max(p, stepPenalty);
            int breakClass = keep.getContext();
            if (nextBreakClass != Constants.EN_AUTO) {
                log.trace("Forced break encountered");
                p = -KnuthPenalty.INFINITE; //Overrides any keeps (see 4.8 in XSL 1.0)
                breakClass = nextBreakClass;
            }
            returnList.add(new BreakElement(penaltyPos, effPenaltyLen, p, breakClass, context));

            laststep = step;
            step = getNextStep();
            if (penaltyOrGlueLen < 0) {
                int shrink = 0;
                int stretch = 0;
                int width = -penaltyOrGlueLen;
                LayoutManager bslm = getTableLM().getParent();
                if (bslm instanceof BlockStackingLayoutManager && ((BlockStackingLayoutManager)bslm).isRestartAtLM()
                        && keep.getPenalty() == KnuthPenalty.INFINITE) {
                    width = 0;
                }
                returnList.add(new KnuthGlue(width, stretch, shrink, new Position(null), true));
            }
        } while (step >= 0);
        assert !returnList.isEmpty();
        lastTCPos.setFlag(TableContentPosition.LAST_IN_ROWGROUP, true);
        return returnList;
    }