src/java/org/apache/fop/layoutmgr/PageBreaker.java
private void redoLayout(PageBreakingAlgorithm alg, int partCount,
            BlockSequence originalList, BlockSequence effectiveList) {

        int newStartPos = 0;
        int restartPoint = pageProvider.getStartingPartIndexForLastPage(partCount);
        if (restartPoint > 0) {
            //Add definitive areas for the parts before the
            //restarting point
            addAreas(alg, restartPoint, originalList, effectiveList);
            //Get page break from which we restart
            PageBreakPosition pbp = alg.getPageBreaks().get(restartPoint - 1);
            newStartPos = alg.par.getFirstBoxIndex(pbp.getLeafPos() + 1);
            //Handle page break right here to avoid any side-effects
            if (newStartPos > 0) {
                handleBreakTrait(Constants.EN_PAGE);
            }
        }

        AbstractBreaker.log.debug("Restarting at " + restartPoint
                + ", new start position: " + newStartPos);

        pageBreakHandled = true;
        //Update so the available BPD is reported correctly
        int currentPageNum = pslm.getCurrentPageNum();

        pageProvider.setStartOfNextElementList(currentPageNum,
                pslm.getCurrentPV().getCurrentSpan().getCurrentFlowIndex(), this.spanAllActive);

        //Make sure we only add the areas we haven't added already
        effectiveList.ignoreAtStart = newStartPos;

        PageBreakingAlgorithm algRestart;
        if (needColumnBalancing) {
            AbstractBreaker.log.debug("Column balancing now!!!");
            AbstractBreaker.log.debug("===================================================");

            //Restart last page
            algRestart = new BalancingColumnBreakingAlgorithm(
                    getTopLevelLM(), getPageProvider(), createLayoutListener(),
                    alignment, Constants.EN_START, footnoteSeparatorLength,
                    isPartOverflowRecoveryActivated(),
                    pslm.getCurrentPV().getBodyRegion().getColumnCount());
            AbstractBreaker.log.debug("===================================================");
        } else  {
            // Handle special page-master for last page
            BodyRegion currentBody = pageProvider.getPage(false, currentPageNum)
                    .getPageViewport().getBodyRegion();

            setLastPageIndex(currentPageNum);

            BodyRegion lastBody = pageProvider.getPage(false, currentPageNum)
                    .getPageViewport().getBodyRegion();
            lastBody.getMainReference().setSpans(currentBody.getMainReference().getSpans());
            AbstractBreaker.log.debug("Last page handling now!!!");
            AbstractBreaker.log.debug("===================================================");
            //Restart last page
            algRestart = new PageBreakingAlgorithm(
                    getTopLevelLM(), getPageProvider(), createLayoutListener(),
                    alg.getAlignment(), alg.getAlignmentLast(),
                    footnoteSeparatorLength,
                    isPartOverflowRecoveryActivated(), false, false);
            AbstractBreaker.log.debug("===================================================");
        }

        int optimalPageCount = algRestart.findBreakingPoints(effectiveList,
                    newStartPos,
                    1, true, BreakingAlgorithm.ALL_BREAKS);
        AbstractBreaker.log.debug("restart: optimalPageCount= " + optimalPageCount
                + " pageBreaks.size()= " + algRestart.getPageBreaks().size());

        boolean fitsOnePage
            = optimalPageCount <= pslm.getCurrentPV()
                .getBodyRegion().getMainReference().getCurrentSpan().getColumnCount();

        if (needColumnBalancing) {
            if (!fitsOnePage) {
                AbstractBreaker.log.warn(
                        "Breaking algorithm produced more columns than are available.");
                /* reenable when everything works
                throw new IllegalStateException(
                        "Breaking algorithm must not produce more columns than available.");
                */
            }
        } else {
            if (fitsOnePage) {
                //Replace last page
                pslm.setCurrentPage(pageProvider.getPage(false, currentPageNum));
            } else {
                //Last page-master cannot hold the content.
                //Add areas now...
                addAreas(alg, restartPoint, partCount - restartPoint, originalList, effectiveList);
                //...and add a blank last page
                setLastPageIndex(currentPageNum + 1);
                pslm.setCurrentPage(pslm.makeNewPage(true));
                return;
            }
        }

        addAreas(algRestart, optimalPageCount, originalList, effectiveList);
    }
/**
     * Restart the algorithm at the break corresponding to the given partCount. Used to
     * re-do the part after the last break in case of either column-balancing or a last
     * page-master.
     */
Restart the algorithm at the break corresponding to the given partCount. Used to
re-do the part after the last break in case of either column-balancing or a last
page-master.
Restart the algorithm at the break corresponding to the given partCount . Used to re - do the part after the last break in case of either column - balancing or a last page - master .
private void redoLayout(PageBreakingAlgorithm alg, int partCount,
            BlockSequence originalList, BlockSequence effectiveList) {
        int newStartPos = 0;
        int restartPoint = pageProvider.getStartingPartIndexForLastPage(partCount);
        if (restartPoint > 0) {
            addAreas(alg, restartPoint, originalList, effectiveList);
            PageBreakPosition pbp = alg.getPageBreaks().get(restartPoint - 1);
            newStartPos = alg.par.getFirstBoxIndex(pbp.getLeafPos() + 1);
            if (newStartPos > 0) {
                handleBreakTrait(Constants.EN_PAGE);
            }
        }
        AbstractBreaker.log.debug("Restarting at " + restartPoint
                + ", new start position: " + newStartPos);
        pageBreakHandled = true;
        int currentPageNum = pslm.getCurrentPageNum();
        pageProvider.setStartOfNextElementList(currentPageNum,
                pslm.getCurrentPV().getCurrentSpan().getCurrentFlowIndex(), this.spanAllActive);
        effectiveList.ignoreAtStart = newStartPos;
        PageBreakingAlgorithm algRestart;
        if (needColumnBalancing) {
            AbstractBreaker.log.debug("Column balancing now!!!");
            AbstractBreaker.log.debug("===================================================");
            algRestart = new BalancingColumnBreakingAlgorithm(
                    getTopLevelLM(), getPageProvider(), createLayoutListener(),
                    alignment, Constants.EN_START, footnoteSeparatorLength,
                    isPartOverflowRecoveryActivated(),
                    pslm.getCurrentPV().getBodyRegion().getColumnCount());
            AbstractBreaker.log.debug("===================================================");
        } else  {
            BodyRegion currentBody = pageProvider.getPage(false, currentPageNum)
                    .getPageViewport().getBodyRegion();
            setLastPageIndex(currentPageNum);
            BodyRegion lastBody = pageProvider.getPage(false, currentPageNum)
                    .getPageViewport().getBodyRegion();
            lastBody.getMainReference().setSpans(currentBody.getMainReference().getSpans());
            AbstractBreaker.log.debug("Last page handling now!!!");
            AbstractBreaker.log.debug("===================================================");
            algRestart = new PageBreakingAlgorithm(
                    getTopLevelLM(), getPageProvider(), createLayoutListener(),
                    alg.getAlignment(), alg.getAlignmentLast(),
                    footnoteSeparatorLength,
                    isPartOverflowRecoveryActivated(), false, false);
            AbstractBreaker.log.debug("===================================================");
        }
        int optimalPageCount = algRestart.findBreakingPoints(effectiveList,
                    newStartPos,
                    1, true, BreakingAlgorithm.ALL_BREAKS);
        AbstractBreaker.log.debug("restart: optimalPageCount= " + optimalPageCount
                + " pageBreaks.size()= " + algRestart.getPageBreaks().size());
        boolean fitsOnePage
            = optimalPageCount <= pslm.getCurrentPV()
                .getBodyRegion().getMainReference().getCurrentSpan().getColumnCount();
        if (needColumnBalancing) {
            if (!fitsOnePage) {
                AbstractBreaker.log.warn(
                        "Breaking algorithm produced more columns than are available.");
                /* reenable when everything works
                throw new IllegalStateException(
                        "Breaking algorithm must not produce more columns than available.");
                */
            }
        } else {
            if (fitsOnePage) {
                pslm.setCurrentPage(pageProvider.getPage(false, currentPageNum));
            } else {
                addAreas(alg, restartPoint, partCount - restartPoint, originalList, effectiveList);
                setLastPageIndex(currentPageNum + 1);
                pslm.setCurrentPage(pslm.makeNewPage(true));
                return;
            }
        }
        addAreas(algRestart, optimalPageCount, originalList, effectiveList);
    }
private void redoLayout ( PageBreakingAlgorithm alg , int partCount , BlockSequence originalList , BlockSequence effectiveList ) { int newStartPos = 0 ; int restartPoint = pageProvider . getStartingPartIndexForLastPage ( partCount ) ; if ( restartPoint > 0 ) { addAreas ( alg , restartPoint , originalList , effectiveList ) ; PageBreakPosition pbp = alg . getPageBreaks ( ) . get ( restartPoint - 1 ) ; newStartPos = alg . par . getFirstBoxIndex ( pbp . getLeafPos ( ) + 1 ) ; if ( newStartPos > 0 ) { handleBreakTrait ( Constants . EN_PAGE ) ; } } AbstractBreaker . log . debug ( "Restarting at " + restartPoint + ", new start position: " + newStartPos ) ; pageBreakHandled = true ; int currentPageNum = pslm . getCurrentPageNum ( ) ; pageProvider . setStartOfNextElementList ( currentPageNum , pslm . getCurrentPV ( ) . getCurrentSpan ( ) . getCurrentFlowIndex ( ) , this . spanAllActive ) ; effectiveList . ignoreAtStart = newStartPos ; PageBreakingAlgorithm algRestart ; if ( needColumnBalancing ) { AbstractBreaker . log . debug ( "Column balancing now!!!" ) ; AbstractBreaker . log . debug ( "===================================================" ) ; algRestart = new BalancingColumnBreakingAlgorithm ( getTopLevelLM ( ) , getPageProvider ( ) , createLayoutListener ( ) , alignment , Constants . EN_START , footnoteSeparatorLength , isPartOverflowRecoveryActivated ( ) , pslm . getCurrentPV ( ) . getBodyRegion ( ) . getColumnCount ( ) ) ; AbstractBreaker . log . debug ( "===================================================" ) ; } else { BodyRegion currentBody = pageProvider . getPage ( false , currentPageNum ) . getPageViewport ( ) . getBodyRegion ( ) ; setLastPageIndex ( currentPageNum ) ; BodyRegion lastBody = pageProvider . getPage ( false , currentPageNum ) . getPageViewport ( ) . getBodyRegion ( ) ; lastBody . getMainReference ( ) . setSpans ( currentBody . getMainReference ( ) . getSpans ( ) ) ; AbstractBreaker . log . debug ( "Last page handling now!!!" ) ; AbstractBreaker . log . debug ( "===================================================" ) ; algRestart = new PageBreakingAlgorithm ( getTopLevelLM ( ) , getPageProvider ( ) , createLayoutListener ( ) , alg . getAlignment ( ) , alg . getAlignmentLast ( ) , footnoteSeparatorLength , isPartOverflowRecoveryActivated ( ) , false , false ) ; AbstractBreaker . log . debug ( "===================================================" ) ; } int optimalPageCount = algRestart . findBreakingPoints ( effectiveList , newStartPos , 1 , true , BreakingAlgorithm . ALL_BREAKS ) ; AbstractBreaker . log . debug ( "restart: optimalPageCount= " + optimalPageCount + " pageBreaks.size()= " + algRestart . getPageBreaks ( ) . size ( ) ) ; boolean fitsOnePage = optimalPageCount <= pslm . getCurrentPV ( ) . getBodyRegion ( ) . getMainReference ( ) . getCurrentSpan ( ) . getColumnCount ( ) ; if ( needColumnBalancing ) { if ( ! fitsOnePage ) { AbstractBreaker . log . warn ( "Breaking algorithm produced more columns than are available." ) ; /* reenable when everything works
                throw new IllegalStateException(
                        "Breaking algorithm must not produce more columns than available.");
                */ } } else { if ( fitsOnePage ) { pslm . setCurrentPage ( pageProvider . getPage ( false , currentPageNum ) ) ; } else { addAreas ( alg , restartPoint , partCount - restartPoint , originalList , effectiveList ) ; setLastPageIndex ( currentPageNum + 1 ) ; pslm . setCurrentPage ( pslm . makeNewPage ( true ) ) ; return ; } } addAreas ( algRestart , optimalPageCount , originalList , effectiveList ) ; }
Restart the algorithm at the break corresponding to the given partCount.
Restart the algorithm at the break corresponding to the given partCount .
//Add definitive areas for the parts before the //restarting point //Get page break from which we restart //Handle page break right here to avoid any side-effects //Update so the available BPD is reported correctly //Make sure we only add the areas we haven't added already //Restart last page // Handle special page-master for last page //Restart last page //Replace last page //Last page-master cannot hold the content. //Add areas now... //...and add a blank last page