You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by vh...@apache.org on 2009/09/18 19:10:52 UTC

svn commit: r816718 [6/11] - in /xmlgraphics/fop/branches/Temp_Accessibility: ./ examples/fo/advanced/ hyph/ lib/ src/codegen/unicode/java/org/apache/fop/hyphenation/ src/codegen/unicode/java/org/apache/fop/text/linebreak/ src/codegen/unicode/java/org/...

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/PageBreaker.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/PageBreaker.java?rev=816718&r1=816717&r2=816718&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/PageBreaker.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/PageBreaker.java Fri Sep 18 17:10:42 2009
@@ -28,7 +28,6 @@
 import org.apache.fop.area.PageViewport;
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.FObj;
-import org.apache.fop.fo.pagination.PageSequence;
 import org.apache.fop.fo.pagination.Region;
 import org.apache.fop.fo.pagination.RegionBody;
 import org.apache.fop.fo.pagination.StaticContent;
@@ -78,6 +77,14 @@
         return pslm.getPageProvider();
     }
 
+    /**
+     * Starts the page breaking process.
+     * @param flowBPD the constant available block-progression-dimension (used for every part)
+     */
+    void doLayout(int flowBPD) {
+        doLayout(flowBPD, false);
+    }
+
     /** {@inheritDoc} */
     protected PageBreakingLayoutListener createLayoutListener() {
         return new PageBreakingLayoutListener() {
@@ -122,6 +129,12 @@
     /** {@inheritDoc} */
     protected int getNextBlockList(LayoutContext childLC,
             int nextSequenceStartsOn) {
+        return getNextBlockList(childLC, nextSequenceStartsOn, null, null, null);
+    }
+
+    /** {@inheritDoc} */
+    protected int getNextBlockList(LayoutContext childLC, int nextSequenceStartsOn,
+            Position positionAtIPDChange, LayoutManager restartLM, List firstElements) {
         if (!firstPart) {
             // if this is the first page that will be created by
             // the current BlockSequence, it could have a break
@@ -133,19 +146,13 @@
         pageBreakHandled = true;
         pageProvider.setStartOfNextElementList(pslm.getCurrentPageNum(),
                 pslm.getCurrentPV().getCurrentSpan().getCurrentFlowIndex());
-        return super.getNextBlockList(childLC, nextSequenceStartsOn);
+        return super.getNextBlockList(childLC, nextSequenceStartsOn, positionAtIPDChange,
+                restartLM, firstElements);
     }
 
-    /** {@inheritDoc} */
-    protected List getNextKnuthElements(LayoutContext context, int alignment) {
-        List contentList = null;
-
-        while (!childFLM.isFinished() && contentList == null) {
-            contentList = childFLM.getNextKnuthElements(context, alignment);
-        }
+    private boolean containsFootnotes(List contentList, LayoutContext context) {
 
-        // scan contentList, searching for footnotes
-        boolean bFootnotesPresent = false;
+        boolean containsFootnotes = false;
         if (contentList != null) {
             ListIterator contentListIterator = contentList.listIterator();
             while (contentListIterator.hasNext()) {
@@ -153,7 +160,7 @@
                 if (element instanceof KnuthBlockBox
                     && ((KnuthBlockBox) element).hasAnchors()) {
                     // element represents a line with footnote citations
-                    bFootnotesPresent = true;
+                    containsFootnotes = true;
                     LayoutContext footnoteContext = new LayoutContext(context);
                     footnoteContext.setStackLimitBP(context.getStackLimitBP());
                     footnoteContext.setRefIPD(pslm.getCurrentPV()
@@ -173,31 +180,64 @@
                 }
             }
         }
+        return containsFootnotes;
+    }
+
+    private void handleFootnoteSeparator() {
+        StaticContent footnoteSeparator;
+        footnoteSeparator = pslm.getPageSequence().getStaticContent("xsl-footnote-separator");
+        if (footnoteSeparator != null) {
+            // the footnote separator can contain page-dependent content such as
+            // page numbers or retrieve markers, so its areas cannot simply be
+            // obtained now and repeated in each page;
+            // we need to know in advance the separator bpd: the actual separator
+            // could be different from page to page, but its bpd would likely be
+            // always the same
 
-        if (bFootnotesPresent) {
+            // create a Block area that will contain the separator areas
+            separatorArea = new Block();
+            separatorArea.setIPD(pslm.getCurrentPV()
+                        .getRegionReference(Constants.FO_REGION_BODY).getIPD());
+            // create a StaticContentLM for the footnote separator
+            footnoteSeparatorLM
+                    = pslm.getLayoutManagerMaker().makeStaticContentLayoutManager(
+                        pslm, footnoteSeparator, separatorArea);
+            footnoteSeparatorLM.doLayout();
+
+            footnoteSeparatorLength = new MinOptMax(separatorArea.getBPD());
+        }
+    }
+
+    /** {@inheritDoc} */
+    protected List getNextKnuthElements(LayoutContext context, int alignment) {
+        List contentList = null;
+
+        while (!childFLM.isFinished() && contentList == null) {
+            contentList = childFLM.getNextKnuthElements(context, alignment);
+        }
+
+        // scan contentList, searching for footnotes
+        if (containsFootnotes(contentList, context)) {
             // handle the footnote separator
-            StaticContent footnoteSeparator;
-            footnoteSeparator = pslm.getPageSequence().getStaticContent("xsl-footnote-separator");
-            if (footnoteSeparator != null) {
-                // the footnote separator can contain page-dependent content such as
-                // page numbers or retrieve markers, so its areas cannot simply be
-                // obtained now and repeated in each page;
-                // we need to know in advance the separator bpd: the actual separator
-                // could be different from page to page, but its bpd would likely be
-                // always the same
-
-                // create a Block area that will contain the separator areas
-                separatorArea = new Block();
-                separatorArea.setIPD(pslm.getCurrentPV()
-                            .getRegionReference(Constants.FO_REGION_BODY).getIPD());
-                // create a StaticContentLM for the footnote separator
-                footnoteSeparatorLM = (StaticContentLayoutManager)
-                    pslm.getLayoutManagerMaker().makeStaticContentLayoutManager(
-                    pslm, footnoteSeparator, separatorArea);
-                footnoteSeparatorLM.doLayout();
+            handleFootnoteSeparator();
+        }
+        return contentList;
+    }
 
-                footnoteSeparatorLength = new MinOptMax(separatorArea.getBPD());
-            }
+    /** {@inheritDoc} */
+    protected List getNextKnuthElements(LayoutContext context, int alignment,
+            Position positionAtIPDChange, LayoutManager restartAtLM) {
+        List contentList = null;
+
+        do {
+            contentList = childFLM.getNextKnuthElements(context, alignment, positionAtIPDChange,
+                    restartAtLM);
+        } while (!childFLM.isFinished() && contentList == null);
+
+        // scan contentList, searching for footnotes
+        if (containsFootnotes(contentList, context)) {
+            // handle the footnote separator
+            handleFootnoteSeparator();
         }
         return contentList;
     }
@@ -241,49 +281,61 @@
     }
 
     /**
-     * Performs phase 3 operation
-     *
-     * @param alg page breaking algorithm
-     * @param partCount part count
-     * @param originalList the block sequence original list
-     * @param effectiveList the block sequence effective list
+     * {@inheritDoc}
+     * This implementation checks whether to trigger column-balancing,
+     * or whether to take into account a 'last-page' condition.
      */
     protected void doPhase3(PageBreakingAlgorithm alg, int partCount,
             BlockSequence originalList, BlockSequence effectiveList) {
+
         if (needColumnBalancing) {
-            doPhase3WithColumnBalancing(alg, partCount, originalList, effectiveList);
-        } else {
-            if (!hasMoreContent() && pslm.getPageSequence().hasPagePositionLast()) {
-                //last part is reached and we have a "last page" condition
-                doPhase3WithLastPage(alg, partCount, originalList, effectiveList);
-            } else {
-                //Directly add areas after finding the breaks
-                addAreas(alg, partCount, originalList, effectiveList);
+            //column balancing for the last part
+            doPhase3(alg, partCount, originalList, effectiveList, false);
+            return;
+        }
+
+        boolean lastPageMasterDefined = pslm.getPageSequence().hasPagePositionLast();
+        if (!hasMoreContent()) {
+            //last part is reached
+            if (lastPageMasterDefined) {
+                //last-page condition
+                doPhase3(alg, partCount, originalList, effectiveList, true);
+                return;
             }
         }
+
+        //nothing special: just add the areas now
+        addAreas(alg, partCount, originalList, effectiveList);
     }
 
-    private void doPhase3WithLastPage(PageBreakingAlgorithm alg, int partCount,
-            BlockSequence originalList, BlockSequence effectiveList) {
-        int newStartPos;
+    /**
+     * Restart the algorithm at the break corresponding
+     * to the given partCount
+     * (currently only used to redo the part after the
+     *  last break in case of column-balancing
+     *  and/or a last page-master)
+     */
+    private void doPhase3(PageBreakingAlgorithm alg, int partCount,
+            BlockSequence originalList, BlockSequence effectiveList,
+            boolean isLastPart) {
+
+
+        int newStartPos = 0;
         int restartPoint = pageProvider.getStartingPartIndexForLastPage(partCount);
         if (restartPoint > 0) {
-            //Add definitive areas before last page
+            //Add definitive areas for the parts before the
+            //restarting point
             addAreas(alg, restartPoint, originalList, effectiveList);
             //Get page break from which we restart
             PageBreakPosition pbp = (PageBreakPosition)
                     alg.getPageBreaks().get(restartPoint - 1);
-            //Set starting position to the first element *after* the page-break
             newStartPos = pbp.getLeafPos() + 1;
             //Handle page break right here to avoid any side-effects
             if (newStartPos > 0) {
                 handleBreakTrait(Constants.EN_PAGE);
             }
-        } else {
-            newStartPos = 0;
         }
-        AbstractBreaker.log.debug("Last page handling now!!!");
-        AbstractBreaker.log.debug("===================================================");
+
         AbstractBreaker.log.debug("Restarting at " + restartPoint
                 + ", new start position: " + newStartPos);
 
@@ -292,95 +344,78 @@
         int currentPageNum = pslm.getCurrentPageNum();
         pageProvider.setStartOfNextElementList(currentPageNum,
                 pslm.getCurrentPV().getCurrentSpan().getCurrentFlowIndex());
-        pageProvider.setLastPageIndex(currentPageNum);
 
-        //Restart last page
-        PageBreakingAlgorithm algRestart = new PageBreakingAlgorithm(
-                getTopLevelLM(),
-                getPageProvider(), createLayoutListener(),
-                alg.getAlignment(), alg.getAlignmentLast(),
-                footnoteSeparatorLength,
-                isPartOverflowRecoveryActivated(), false, false);
-        //alg.setConstantLineWidth(flowBPD);
-        int iOptPageCount = algRestart.findBreakingPoints(effectiveList,
-                    newStartPos,
-                    1, true, BreakingAlgorithm.ALL_BREAKS);
-        AbstractBreaker.log.debug("restart: iOptPageCount= " + iOptPageCount
-                + " pageBreaks.size()= " + algRestart.getPageBreaks().size());
+        PageBreakingAlgorithm algRestart = null;
+        int optimalPageCount;
         //Make sure we only add the areas we haven't added already
         effectiveList.ignoreAtStart = newStartPos;
-        boolean replaceLastPage
-                = iOptPageCount <= pslm.getCurrentPV().getBodyRegion().getColumnCount();
-        if (replaceLastPage) {
-            //Replace last page
-            pslm.setCurrentPage(pageProvider.getPage(false, currentPageNum));
-            addAreas(algRestart, iOptPageCount, originalList, effectiveList);
-        } else {
-            addAreas(alg, restartPoint, partCount - restartPoint, originalList, effectiveList);
-            //Add blank last page
-            pageProvider.setLastPageIndex(currentPageNum + 1);
-            pslm.setCurrentPage(pslm.makeNewPage(true, true));
-        }
-        AbstractBreaker.log.debug("===================================================");
-    }
 
-    private void doPhase3WithColumnBalancing(PageBreakingAlgorithm alg, int partCount,
-            BlockSequence originalList, BlockSequence effectiveList) {
-        AbstractBreaker.log.debug("Column balancing now!!!");
-        AbstractBreaker.log.debug("===================================================");
-        int newStartPos;
-        int restartPoint = pageProvider.getStartingPartIndexForLastPage(partCount);
-        if (restartPoint > 0) {
-            //Add definitive areas
-            addAreas(alg, restartPoint, originalList, effectiveList);
-            //Get page break from which we restart
-            PageBreakPosition pbp = (PageBreakPosition)
-                    alg.getPageBreaks().get(restartPoint - 1);
-            newStartPos = pbp.getLeafPos();
-            //Handle page break right here to avoid any side-effects
-            if (newStartPos > 0) {
-                handleBreakTrait(Constants.EN_PAGE);
-            }
-        } else {
-            newStartPos = 0;
+        if (isLastPart) {
+            pageProvider.setLastPageIndex(currentPageNum);
         }
-        AbstractBreaker.log.debug("Restarting at " + restartPoint
-                + ", new start position: " + newStartPos);
 
-        pageBreakHandled = true;
-        //Update so the available BPD is reported correctly
-        pageProvider.setStartOfNextElementList(pslm.getCurrentPageNum(),
-                pslm.getCurrentPV().getCurrentSpan().getCurrentFlowIndex());
+        if (needColumnBalancing) {
+            AbstractBreaker.log.debug("Column balancing now!!!");
+            AbstractBreaker.log.debug("===================================================");
 
-        //Restart last page
-        PageBreakingAlgorithm algRestart = new BalancingColumnBreakingAlgorithm(
-                getTopLevelLM(),
-                getPageProvider(), createLayoutListener(),
-                alignment, Constants.EN_START, footnoteSeparatorLength,
-                isPartOverflowRecoveryActivated(),
-                pslm.getCurrentPV().getBodyRegion().getColumnCount());
-        //alg.setConstantLineWidth(flowBPD);
-        int iOptPageCount = algRestart.findBreakingPoints(effectiveList,
+            //Restart last page
+            algRestart = new BalancingColumnBreakingAlgorithm(
+                    getTopLevelLM(), getPageProvider(), createLayoutListener(),
+                    alignment, Constants.EN_START, footnoteSeparatorLength,
+                    isPartOverflowRecoveryActivated(),
+                    pslm.getCurrentPV().getBodyRegion().getColumnCount());
+            AbstractBreaker.log.debug("===================================================");
+        } else  {
+            //plain last page, no column balancing
+            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("===================================================");
+        }
+
+        optimalPageCount = algRestart.findBreakingPoints(effectiveList,
                     newStartPos,
                     1, true, BreakingAlgorithm.ALL_BREAKS);
-        AbstractBreaker.log.debug("restart: iOptPageCount= " + iOptPageCount
+        AbstractBreaker.log.debug("restart: optimalPageCount= " + optimalPageCount
                 + " pageBreaks.size()= " + algRestart.getPageBreaks().size());
-        if (iOptPageCount > pslm.getCurrentPV().getBodyRegion().getColumnCount()) {
-            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.");
-            */
+
+        boolean fitsOnePage
+                = optimalPageCount <= pslm.getCurrentPV().getBodyRegion().getColumnCount();
+
+        if (isLastPart) {
+            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
+                pageProvider.setLastPageIndex(currentPageNum + 1);
+                pslm.setCurrentPage(pslm.makeNewPage(true, true));
+                return;
+            }
+        } else {
+            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.");
+                */
+            }
         }
-        //Make sure we only add the areas we haven't added already
-        effectiveList.ignoreAtStart = newStartPos;
-        addAreas(algRestart, iOptPageCount, originalList, effectiveList);
-        AbstractBreaker.log.debug("===================================================");
+
+        addAreas(algRestart, optimalPageCount, originalList, effectiveList);
     }
 
     protected void startPart(BlockSequence list, int breakClass) {
-        AbstractBreaker.log.debug("startPart() breakClass=" + breakClass);
+        AbstractBreaker.log.debug("startPart() breakClass=" + getBreakClassName(breakClass));
         if (pslm.getCurrentPage() == null) {
             throw new IllegalStateException("curPage must not be null");
         }
@@ -416,7 +451,7 @@
             || pbp.footnoteFirstElementIndex <= pbp.footnoteLastElementIndex) {
             // call addAreas() for each FootnoteBodyLM
             for (int i = pbp.footnoteFirstListIndex; i <= pbp.footnoteLastListIndex; i++) {
-                LinkedList elementList = alg.getFootnoteList(i);
+                List elementList = alg.getFootnoteList(i);
                 int firstIndex = (i == pbp.footnoteFirstListIndex
                         ? pbp.footnoteFirstElementIndex : 0);
                 int lastIndex = (i == pbp.footnoteLastListIndex
@@ -441,9 +476,7 @@
         pslm.getCurrentPV().getCurrentSpan().notifyFlowsFinished();
     }
 
-    /**
-     * @return the current child flow layout manager
-     */
+    /** @return the current child flow layout manager */
     protected LayoutManager getCurrentChildLM() {
         return childFLM;
     }
@@ -462,45 +495,51 @@
      */
     private void handleBreakTrait(int breakVal) {
         Page curPage = pslm.getCurrentPage();
-        if (breakVal == Constants.EN_ALL) {
+        switch (breakVal) {
+        case Constants.EN_ALL:
             //break due to span change in multi-column layout
             curPage.getPageViewport().createSpan(true);
             return;
-        } else if (breakVal == Constants.EN_NONE) {
+        case Constants.EN_NONE:
             curPage.getPageViewport().createSpan(false);
             return;
-        } else if (breakVal == Constants.EN_COLUMN
-                || breakVal <= 0
-                || breakVal == Constants.EN_AUTO) {
+        case Constants.EN_COLUMN:
+        case Constants.EN_AUTO:
+        case Constants.EN_PAGE:
+        case -1:
             PageViewport pv = curPage.getPageViewport();
 
             //Check if previous page was spanned
             boolean forceNewPageWithSpan = false;
             RegionBody rb = (RegionBody)curPage.getSimplePageMaster().getRegion(
                     Constants.FO_REGION_BODY);
-            if (breakVal < 0
-                    && rb.getColumnCount() > 1
-                    && pv.getCurrentSpan().getColumnCount() == 1) {
-                forceNewPageWithSpan = true;
-            }
+            forceNewPageWithSpan
+                    = (rb.getColumnCount() > 1
+                        && pv.getCurrentSpan().getColumnCount() == 1);
 
             if (forceNewPageWithSpan) {
+                log.trace("Forcing new page with span");
                 curPage = pslm.makeNewPage(false, false);
                 curPage.getPageViewport().createSpan(true);
             } else if (pv.getCurrentSpan().hasMoreFlows()) {
+                log.trace("Moving to next flow");
                 pv.getCurrentSpan().moveToNextFlow();
             } else {
-                curPage = pslm.makeNewPage(false, false);
+                log.trace("Making new page");
+                /*curPage = */pslm.makeNewPage(false, false);
             }
             return;
-        }
-        log.debug("handling break-before after page " + pslm.getCurrentPageNum()
-            + " breakVal=" + breakVal);
-        if (needBlankPageBeforeNew(breakVal)) {
-            curPage = pslm.makeNewPage(true, false);
-        }
-        if (needNewPage(breakVal)) {
-            curPage = pslm.makeNewPage(false, false);
+        default:
+            log.debug("handling break-before after page " + pslm.getCurrentPageNum()
+                + " breakVal=" + getBreakClassName(breakVal));
+            if (needBlankPageBeforeNew(breakVal)) {
+                log.trace("Inserting blank page");
+                /*curPage = */pslm.makeNewPage(true, false);
+            }
+            if (needNewPage(breakVal)) {
+                log.trace("Making new page");
+                /*curPage = */pslm.makeNewPage(false, false);
+            }
         }
     }
 
@@ -540,4 +579,4 @@
             return true;
         }
     }
-}
\ No newline at end of file
+}

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java?rev=816718&r1=816717&r2=816718&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java Fri Sep 18 17:10:42 2009
@@ -20,16 +20,19 @@
 package org.apache.fop.layoutmgr;
 
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.ListIterator;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.FObj;
 import org.apache.fop.layoutmgr.AbstractBreaker.PageBreakPosition;
 import org.apache.fop.traits.MinOptMax;
+import org.apache.fop.util.ListUtil;
 
 class PageBreakingAlgorithm extends BreakingAlgorithm {
 
@@ -47,9 +50,9 @@
      * List&lt;List&lt;KnuthElement&gt;&gt;, it contains the sequences of KnuthElement
      * representing the footnotes bodies.
      */
-    private ArrayList footnotesList = null;
+    private List footnotesList = null;
     /** Cumulated bpd of unhandled footnotes. */
-    private ArrayList lengthList = null;
+    private List lengthList = null;
     /** Length of all the footnotes which will be put on the current page. */
     private int totalFootnotesLength = 0;
     /**
@@ -58,6 +61,7 @@
      * footnotes from its preceding pages.
      */
     private int insertedFootnotesLength = 0;
+
     /** True if footnote citations have been met since the beginning of the page sequence. */
     private boolean footnotesPending = false;
     /**
@@ -92,6 +96,14 @@
     //Controls whether a single part should be forced if possible (ex. block-container)
     private boolean favorSinglePart = false;
 
+    private boolean ipdChange;
+    private KnuthNode bestNodeForIPDChange;
+
+    //Used to keep track of switches in keep-context
+    private int currentKeepContext = Constants.EN_AUTO;
+    private KnuthNode lastBeforeKeepContextSwitch;
+
+
     public PageBreakingAlgorithm(LayoutManager topLevelLM,
                                  PageProvider pageProvider,
                                  PageBreakingLayoutListener layoutListener,
@@ -178,6 +190,7 @@
         }
     }
 
+    /** {@inheritDoc} */
     protected void initialize() {
         super.initialize();
         insertedFootnotesLength = 0;
@@ -185,6 +198,73 @@
         footnoteElementIndex = -1;
     }
 
+    /**
+     * {@inheritDoc}
+     * Overridden to defer a part to the next page, if it
+     * must be kept within one page, but is too large to fit in
+     * the last column.
+     */
+    protected KnuthNode recoverFromTooLong(KnuthNode lastTooLong) {
+
+        if (log.isDebugEnabled()) {
+            log.debug("Recovering from too long: " + lastTooLong);
+            log.debug("\tlastTooShort = " + getLastTooShort());
+            log.debug("\tlastBeforeKeepContextSwitch = " + lastBeforeKeepContextSwitch);
+            log.debug("\tcurrentKeepContext = " + AbstractBreaker.getBreakClassName(currentKeepContext));
+        }
+
+        if (lastBeforeKeepContextSwitch == null
+                || currentKeepContext == Constants.EN_AUTO) {
+            return super.recoverFromTooLong(lastTooLong);
+        }
+
+        KnuthNode node = lastBeforeKeepContextSwitch;
+        lastBeforeKeepContextSwitch = null;
+        // content would overflow, insert empty page/column(s) and try again
+        while (!pageProvider.endPage(node.line - 1)) {
+            log.trace("Adding node for empty column");
+            node = createNode(
+                    node.position,
+                    node.line + 1, 1,
+                    0, 0, 0,
+                    0, 0, 0,
+                    0, 0, node);
+        }
+        return node;
+    }
+
+    /**
+     * Compare two KnuthNodes and return the node with the least demerit.
+     *
+     * @param node1 The first knuth node.
+     * @param node2 The other knuth node.
+     * @return the node with the least demerit.
+     */
+    protected KnuthNode compareNodes(KnuthNode node1, KnuthNode node2) {
+
+        /* if either node is null, return the other one */
+        if (node1 == null || node2 == null) {
+            return (node1 == null) ? node2 : node1;
+        }
+
+        /* if either one of the nodes corresponds to a mere column-break,
+         * and the other one corresponds to a page-break, return the page-break node
+         */
+        if (pageProvider != null) {
+            if (pageProvider.endPage(node1.line - 1)
+                    && !pageProvider.endPage(node2.line - 1)) {
+                return node1;
+            } else if (pageProvider.endPage(node2.line - 1)
+                    && !pageProvider.endPage(node1.line - 1)) {
+                return node2;
+            }
+        }
+
+        /* all other cases: use superclass implementation */
+        return super.compareNodes(node1, node2);
+    }
+
+    /** {@inheritDoc} */
     protected KnuthNode createNode(int position, int line, int fitness,
                                    int totalWidth, int totalStretch, int totalShrink,
                                    double adjustRatio, int availableShrink, int availableStretch,
@@ -196,6 +276,7 @@
                                  difference, totalDemerits, previous);
     }
 
+    /** {@inheritDoc} */
     protected KnuthNode createNode(int position, int line, int fitness,
                                    int totalWidth, int totalStretch, int totalShrink) {
         return new KnuthPageNode(position, line, fitness,
@@ -209,11 +290,13 @@
     }
 
     /**
+     * {@inheritDoc}
      * Page-breaking specific handling of the given box. Currently it adds the footnotes
      * cited in the given box to the list of to-be-handled footnotes.
      * @param box a block-level element possibly containing foonotes citations
      */
     protected void handleBox(KnuthBox box) {
+        super.handleBox(box);
         if (box instanceof KnuthBlockBox
             && ((KnuthBlockBox) box).hasAnchors()) {
             handleFootnotes(((KnuthBlockBox) box).getElementLists());
@@ -225,6 +308,28 @@
     }
 
     /**
+     * {@inheritDoc}
+     * Overridden to consider penalties with value {@link KnuthElement#INFINITE}
+     * as legal break-points, if the current keep-context allows this
+     * (a keep-*.within-page="always" constraint still permits column-breaks)
+     */
+    protected void handlePenaltyAt(KnuthPenalty penalty, int position,
+                                   int allowedBreaks) {
+        super.handlePenaltyAt(penalty, position, allowedBreaks);
+        /* if the penalty had value INFINITE, default implementation
+         * will not have considered it a legal break, but it could still
+         * be one.
+         */
+        if (penalty.getP() == KnuthPenalty.INFINITE) {
+            int breakClass = penalty.getBreakClass();
+            if (breakClass == Constants.EN_PAGE
+                    || breakClass == Constants.EN_COLUMN) {
+                considerLegalBreak(penalty, position);
+            }
+        }
+    }
+
+    /**
      * Handles the footnotes cited inside a block-level box. Updates footnotesList and the
      * value of totalFootnotesLength with the lengths of the given footnotes.
      * @param elementLists list of KnuthElement sequences corresponding to the footnotes
@@ -244,9 +349,9 @@
         }
 
         // compute the total length of the footnotes
-        ListIterator elementListsIterator = elementLists.listIterator();
-        while (elementListsIterator.hasNext()) {
-            LinkedList noteList = (LinkedList) elementListsIterator.next();
+        for (Iterator elementListsIterator = elementLists.iterator();
+                elementListsIterator.hasNext();) {
+            final List noteList = (List) elementListsIterator.next();
 
             //Space resolution (Note: this does not respect possible stacking constraints
             //between footnotes!)
@@ -254,21 +359,23 @@
 
             int noteLength = 0;
             footnotesList.add(noteList);
-            ListIterator noteListIterator = noteList.listIterator();
-            while (noteListIterator.hasNext()) {
-                KnuthElement element = (KnuthElement) noteListIterator.next();
+            for (Iterator noteListIterator = noteList.iterator();
+                    noteListIterator.hasNext();) {
+                final KnuthElement element = (KnuthElement) noteListIterator.next();
                 if (element.isBox() || element.isGlue()) {
                     noteLength += element.getW();
                 }
             }
-            int prevLength = (lengthList.size() == 0
+            int prevLength = (lengthList == null || lengthList.isEmpty())
                     ? 0
-                    : ((Integer) lengthList.get(lengthList.size() - 1)).intValue());
+                    : ((Integer) ListUtil.getLast(lengthList)).intValue();
+            //TODO: replace with Integer.valueOf() once we switch to Java 5
             lengthList.add(new Integer(prevLength + noteLength));
             totalFootnotesLength += noteLength;
         }
     }
 
+    /** {@inheritDoc} */
     protected int restartFrom(KnuthNode restartingNode, int currentIndex) {
         int returnValue = super.restartFrom(restartingNode, currentIndex);
         newFootnotes = false;
@@ -276,10 +383,10 @@
             // remove from footnotesList the note lists that will be met
             // after the restarting point
             for (int j = currentIndex; j >= restartingNode.position; j--) {
-                KnuthElement resettedElement = getElement(j);
-                if (resettedElement instanceof KnuthBlockBox
-                    && ((KnuthBlockBox) resettedElement).hasAnchors()) {
-                    resetFootnotes(((KnuthBlockBox) resettedElement).getElementLists());
+                final KnuthElement resetElement = getElement(j);
+                if (resetElement instanceof KnuthBlockBox
+                        && ((KnuthBlockBox) resetElement).hasAnchors()) {
+                    resetFootnotes(((KnuthBlockBox) resetElement).getElementLists());
                 }
             }
         }
@@ -288,12 +395,12 @@
 
     private void resetFootnotes(List elementLists) {
         for (int i = 0; i < elementLists.size(); i++) {
-            /*LinkedList removedList = (LinkedList)*/footnotesList.remove(footnotesList.size() - 1);
-            lengthList.remove(lengthList.size() - 1);
+            /*LinkedList removedList = (LinkedList)*/ListUtil.removeLast(footnotesList);
+            ListUtil.removeLast(lengthList);
 
             // update totalFootnotesLength
-            if (lengthList.size() > 0) {
-                totalFootnotesLength = ((Integer) lengthList.get(lengthList.size() - 1)).intValue();
+            if (!lengthList.isEmpty()) {
+                totalFootnotesLength = ((Integer) ListUtil.getLast(lengthList)).intValue();
             } else {
                 totalFootnotesLength = 0;
             }
@@ -304,16 +411,72 @@
         }
     }
 
+    /** {@inheritDoc} */
     protected void considerLegalBreak(KnuthElement element, int elementIdx) {
+        if (element.isPenalty()) {
+            int breakClass = ((KnuthPenalty) element).getBreakClass();
+            switch (breakClass) {
+            case Constants.EN_PAGE:
+                if (this.currentKeepContext != breakClass) {
+                    this.lastBeforeKeepContextSwitch = getLastTooShort();
+                }
+                this.currentKeepContext = breakClass;
+                break;
+            case Constants.EN_COLUMN:
+                if (this.currentKeepContext != breakClass) {
+                    this.lastBeforeKeepContextSwitch = getLastTooShort();
+                }
+                this.currentKeepContext = breakClass;
+                break;
+            case Constants.EN_AUTO:
+                this.currentKeepContext = breakClass;
+                break;
+            default:
+                //nop
+            }
+        }
         super.considerLegalBreak(element, elementIdx);
         newFootnotes = false;
     }
 
+    /** {@inheritDoc} */
+    protected boolean elementCanEndLine(KnuthElement element, int line, int difference) {
+        if (!(element.isPenalty()) || pageProvider == null) {
+            return true;
+        } else {
+            KnuthPenalty p = (KnuthPenalty) element;
+            if (p.getP() <= 0) {
+                return true;
+            } else {
+                int context = p.getBreakClass();
+                switch (context) {
+                case Constants.EN_LINE:
+                case Constants.EN_COLUMN:
+                    return p.getP() < KnuthPenalty.INFINITE;
+                case Constants.EN_PAGE:
+                    return p.getP() < KnuthPenalty.INFINITE
+                            || !pageProvider.endPage(line - 1);
+                case Constants.EN_AUTO:
+                    log.debug("keep is not auto but context is");
+                    return true;
+                default:
+                    if (p.getP() < KnuthPenalty.INFINITE) {
+                        log.debug("Non recognized keep context:" + context);
+                        return true;
+                    } else {
+                        return false;
+                    }
+                }
+            }
+        }
+    }
+
+    /** {@inheritDoc} */
     protected int computeDifference(KnuthNode activeNode, KnuthElement element,
                                     int elementIndex) {
         KnuthPageNode pageNode = (KnuthPageNode) activeNode;
         int actualWidth = totalWidth - pageNode.totalWidth;
-        int footnoteSplit;
+        int footnoteSplit = 0;
         boolean canDeferOldFootnotes;
         if (element.isPenalty()) {
             actualWidth += element.getW();
@@ -332,7 +495,7 @@
                     insertedFootnotesLength = pageNode.totalFootnotes + allFootnotes;
                     footnoteListIndex = footnotesList.size() - 1;
                     footnoteElementIndex
-                        = ((LinkedList) footnotesList.get(footnoteListIndex)).size() - 1;
+                        = getFootnoteList(footnoteListIndex).size() - 1;
                 } else if (((canDeferOldFootnotes
                                 = checkCanDeferOldFootnotes(pageNode, elementIndex))
                             || newFootnotes)
@@ -358,7 +521,7 @@
                     insertedFootnotesLength = pageNode.totalFootnotes + allFootnotes;
                     footnoteListIndex = footnotesList.size() - 1;
                     footnoteElementIndex
-                        = ((LinkedList) footnotesList.get(footnoteListIndex)).size() - 1;
+                        = getFootnoteList(footnoteListIndex).size() - 1;
                 }
             } else {
                 // all footnotes have already been placed on previous pages
@@ -375,7 +538,8 @@
         }
     }
 
-    /** Checks whether footnotes from preceding pages may be deferred to the page after
+    /**
+     * Checks whether footnotes from preceding pages may be deferred to the page after
      * the given element.
      * @param node active node for the preceding page break
      * @param contentElementIndex index of the Knuth element considered for the
@@ -448,7 +612,7 @@
         return ((newFootnotes
                  && firstNewFootnoteIndex != 0
                  && (listIndex < firstNewFootnoteIndex - 1
-                     || elementIndex < ((LinkedList) footnotesList.get(listIndex)).size() - 1))
+                     || elementIndex < getFootnoteList(listIndex).size() - 1))
                 || length < totalFootnotesLength);
     }
 
@@ -457,6 +621,7 @@
      * @param activeNode currently considered previous page break
      * @param availableLength available space for footnotes
      * @param canDeferOldFootnotes
+     * @return ...
      */
     private int getFootnoteSplit(KnuthPageNode activeNode, int availableLength,
                 boolean canDeferOldFootnotes) {
@@ -473,6 +638,7 @@
      * @param prevLength total length of footnotes inserted so far
      * @param availableLength available space for footnotes on this page
      * @param canDeferOldFootnotes
+     * @return ...
      */
     private int getFootnoteSplit(int prevListIndex, int prevElementIndex, int prevLength,
                                  int availableLength, boolean canDeferOldFootnotes) {
@@ -491,7 +657,7 @@
             // already placed in a page: advance to the next element
             int listIndex = prevListIndex;
             int elementIndex = prevElementIndex;
-            if (elementIndex == ((LinkedList) footnotesList.get(listIndex)).size() - 1) {
+            if (elementIndex == getFootnoteList(listIndex).size() - 1) {
                 listIndex++;
                 elementIndex = 0;
             } else {
@@ -501,9 +667,7 @@
             // try adding whole notes
             if (footnotesList.size() - 1 > listIndex) {
                 // add the previous footnotes: these cannot be broken or deferred
-                if (!canDeferOldFootnotes
-                    && newFootnotes
-                    && firstNewFootnoteIndex > 0) {
+                if (!canDeferOldFootnotes && newFootnotes && firstNewFootnoteIndex > 0) {
                     splitLength = ((Integer) lengthList.get(firstNewFootnoteIndex - 1)).intValue()
                                   - prevLength;
                     listIndex = firstNewFootnoteIndex;
@@ -524,8 +688,7 @@
             }
 
             // try adding a split of the next note
-            noteListIterator = ((LinkedList) footnotesList.get(listIndex))
-                    .listIterator(elementIndex);
+            noteListIterator = getFootnoteList(listIndex).listIterator(elementIndex);
 
             int prevSplitLength = 0;
             int prevIndex = -1;
@@ -539,7 +702,7 @@
                     prevIndex = index;
                 }
                 // get a sub-sequence from the note element list
-                boolean bPrevIsBox = false;
+                boolean boxPreceding = false;
                 while (noteListIterator.hasNext()) {
                     // as this method is called only if it is not possible to insert
                     // all footnotes, and we have already tried (and failed) to insert
@@ -549,15 +712,15 @@
                     if (element.isBox()) {
                         // element is a box
                         splitLength += element.getW();
-                        bPrevIsBox = true;
+                        boxPreceding = true;
                     } else if (element.isGlue()) {
                         // element is a glue
-                        if (bPrevIsBox) {
+                        if (boxPreceding) {
                             // end of the sub-sequence
                             index = noteListIterator.previousIndex();
                             break;
                         }
-                        bPrevIsBox = false;
+                        boxPreceding = false;
                         splitLength += element.getW();
                     } else {
                         // element is a penalty
@@ -569,11 +732,13 @@
                     }
                 }
             }
+
             // if prevSplitLength is 0, this means that the available length isn't enough
             // to insert even the smallest split of the last footnote, so we cannot end a
             // page here
             // if prevSplitLength is > 0 we can insert some footnote content in this page
             // and insert the remaining in the following one
+            //TODO: check this conditional, as the first one is always false...?
             if (!somethingAdded) {
                 // there was not enough space to add a piece of the first new footnote
                 // this is not a good break
@@ -583,12 +748,13 @@
                 footnoteListIndex = (prevIndex != -1) ? listIndex : listIndex - 1;
                 footnoteElementIndex = (prevIndex != -1)
                     ? prevIndex
-                    : ((LinkedList) footnotesList.get(footnoteListIndex)).size() - 1;
+                    : getFootnoteList(footnoteListIndex).size() - 1;
             }
             return prevSplitLength;
         }
     }
 
+    /** {@inheritDoc} */
     protected double computeAdjustmentRatio(KnuthNode activeNode, int difference) {
         // compute the adjustment ratio
         if (difference > 0) {
@@ -618,18 +784,23 @@
         }
     }
 
+    /** {@inheritDoc} */
     protected double computeDemerits(KnuthNode activeNode, KnuthElement element,
                                     int fitnessClass, double r) {
         double demerits = 0;
         // compute demerits
         double f = Math.abs(r);
         f = 1 + 100 * f * f * f;
-        if (element.isPenalty() && element.getP() >= 0) {
-            f += element.getP();
-            demerits = f * f;
-        } else if (element.isPenalty() && !element.isForcedBreak()) {
+        if (element.isPenalty()) {
             double penalty = element.getP();
-            demerits = f * f - penalty * penalty;
+            if (penalty >= 0) {
+                f += penalty;
+                demerits = f * f;
+            } else if (!element.isForcedBreak()) {
+                demerits = f * f - penalty * penalty;
+            } else {
+                demerits = f * f;
+            }
         } else {
             demerits = f * f;
         }
@@ -654,7 +825,7 @@
             }
             if (footnoteListIndex < footnotesList.size()) {
                 if (footnoteElementIndex
-                        < ((LinkedList) footnotesList.get(footnoteListIndex)).size() - 1) {
+                        < getFootnoteList(footnoteListIndex).size() - 1) {
                     // add demerits for the footnote split between pages
                     demerits += splitFootnoteDemerits;
                 }
@@ -680,6 +851,7 @@
     }
 
     private void createFootnotePages(KnuthPageNode lastNode) {
+
         insertedFootnotesLength = lastNode.totalFootnotes;
         footnoteListIndex = lastNode.footnoteListIndex;
         footnoteElementIndex = lastNode.footnoteElementIndex;
@@ -689,18 +861,16 @@
 
         // create pages containing the remaining footnote bodies
         while (insertedFootnotesLength < totalFootnotesLength) {
+            final int tmpLength = ((Integer) lengthList.get(footnoteListIndex)).intValue();
             // try adding some more content
-            if (((Integer) lengthList.get(footnoteListIndex)).intValue() - insertedFootnotesLength
-                <= availableBPD) {
+            if ((tmpLength - insertedFootnotesLength) <= availableBPD) {
                 // add a whole footnote
-                availableBPD -= ((Integer) lengthList.get(footnoteListIndex)).intValue()
-                                - insertedFootnotesLength;
-                insertedFootnotesLength = ((Integer)lengthList.get(footnoteListIndex)).intValue();
+                availableBPD -= tmpLength - insertedFootnotesLength;
+                insertedFootnotesLength = tmpLength;
                 footnoteElementIndex
-                    = ((LinkedList)footnotesList.get(footnoteListIndex)).size() - 1;
+                    = getFootnoteList(footnoteListIndex).size() - 1;
             } else if ((split = getFootnoteSplit(footnoteListIndex, footnoteElementIndex,
-                                                 insertedFootnotesLength, availableBPD, true))
-                       > 0) {
+                    insertedFootnotesLength, availableBPD, true)) > 0) {
                 // add a piece of a footnote
                 availableBPD -= split;
                 insertedFootnotesLength += split;
@@ -732,12 +902,19 @@
     }
 
     /**
-     * @return a list of PageBreakPosition elements
+     * @return a list of {@link PageBreakPosition} elements
+     *          corresponding to the computed page- and column-breaks
      */
     public LinkedList getPageBreaks() {
         return pageBreaks;
     }
 
+    /**
+     * Insert the given {@link PageBreakPosition} as the first
+     * element in the list of page-breaks
+     *
+     * @param pageBreak the position to insert
+     */
     public void insertPageBreakAsFirst(PageBreakPosition pageBreak) {
         if (pageBreaks == null) {
             pageBreaks = new LinkedList();
@@ -759,9 +936,11 @@
         }
     }
 
+    /** {@inheritDoc} */
     public void updateData1(int total, double demerits) {
     }
 
+    /** {@inheritDoc} */
     public void updateData2(KnuthNode bestActiveNode,
                             KnuthSequence sequence,
                             int total) {
@@ -807,7 +986,7 @@
         int firstListIndex = ((KnuthPageNode) bestActiveNode.previous).footnoteListIndex;
         int firstElementIndex = ((KnuthPageNode) bestActiveNode.previous).footnoteElementIndex;
         if (footnotesList != null
-            && firstElementIndex == ((LinkedList) footnotesList.get(firstListIndex)).size() - 1) {
+                && firstElementIndex == getFootnoteList(firstListIndex).size() - 1) {
             // advance to the next list
             firstListIndex++;
             firstElementIndex = 0;
@@ -829,6 +1008,7 @@
                 ratio, difference));
     }
 
+    /** {@inheritDoc} */
     protected int filterActiveNodes() {
         // leave only the active node with fewest total demerits
         KnuthNode bestActiveNode = null;
@@ -848,11 +1028,18 @@
                 }
             }
         }
+        assert (bestActiveNode != null);
         return bestActiveNode.line;
     }
 
-    public LinkedList getFootnoteList(int index) {
-        return (LinkedList) footnotesList.get(index);
+    /**
+     * Obtain the element-list corresponding to the footnote at the given index.
+     *
+     * @param index the index in the list of footnotes
+     * @return  the element-list
+     */
+    protected final List getFootnoteList(int index) {
+        return (List) footnotesList.get(index);
     }
 
     /** @return the associated top-level formatting object. */
@@ -889,4 +1076,63 @@
 
     }
 
+    /** {@inheritDoc} */
+    protected boolean ipdChanged() {
+        return ipdChange;
+    }
+
+    /** {@inheritDoc} */
+    protected int handleIpdChange() {
+        log.trace("Best node for ipd change:" + bestNodeForIPDChange);
+        // TODO finish()
+        /*
+         * The third parameter is used to determine if this is the last page, so
+         * if the content must be vertically justified or not. If we are here
+         * this means that there is further content and the next page has a
+         * different ipd. So tweak the parameter to fall into the non-last-page
+         * case.
+         */
+        calculateBreakPoints(bestNodeForIPDChange, par, bestNodeForIPDChange.line + 1);
+        activeLines = null;
+        return bestNodeForIPDChange.line;
+    }
+
+    /**
+     * Add a node at the end of the given line's existing active nodes.
+     * If this is the first node in the line, adjust endLine accordingly.
+     * @param line number of the line ending at the node's corresponding breakpoint
+     * @param node the active node to add
+     */
+    protected void addNode(int line, KnuthNode node) {
+        if (node.position < par.size() - 1 && line > 0 && ipdChange(line - 1)) {
+            log.trace("IPD changes at page " + line);
+            ipdChange = true;
+            if (bestNodeForIPDChange == null
+                    || node.totalDemerits < bestNodeForIPDChange.totalDemerits) {
+                bestNodeForIPDChange = node;
+            }
+        } else {
+            if (node.position == par.size() - 1) {
+                /*
+                 * The whole sequence could actually fit on the last page before
+                 * the IPD change. No need to do any special handling.
+                 */
+                ipdChange = false;
+            }
+            super.addNode(line, node);
+        }
+    }
+
+    KnuthNode getBestNodeBeforeIPDChange() {
+        return bestNodeForIPDChange;
+    }
+
+    /** {@inheritDoc} */
+    protected boolean ipdChange(int line) {
+        if (pageProvider == null) {
+            return false;
+        }
+        return pageProvider.ipdChange(line);
+    }
+
 }

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/PageProvider.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/PageProvider.java?rev=816718&r1=816717&r2=816718&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/PageProvider.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/PageProvider.java Fri Sep 18 17:10:42 2009
@@ -146,6 +146,76 @@
         return this.lastReportedBPD;
     }
 
+    // Wish there were a more elegant way to do this in Java
+    private int[] getColIndexAndColCount(int index) {
+        int columnCount = 0;
+        int colIndex = startColumnOfCurrentElementList + index;
+        int pageIndex = -1;
+        do {
+            colIndex -= columnCount;
+            pageIndex++;
+            Page page = getPage(false, pageIndex, RELTO_CURRENT_ELEMENT_LIST);
+            columnCount = page.getPageViewport().getCurrentSpan().getColumnCount();
+        } while (colIndex >= columnCount);
+        return new int[] {colIndex, columnCount};
+    }
+
+    /**
+     * Returns true if the part following the given one has a different IPD.
+     *
+     * @param index index of the current part
+     * @return true if the following part has a different IPD, false otherwise
+     */
+    public boolean ipdChange(int index) {
+        int columnCount = 0;
+        int colIndex = startColumnOfCurrentElementList + index;
+        int pageIndex = -1;
+        Page page;
+        do {
+            colIndex -= columnCount;
+            pageIndex++;
+            page = getPage(false, pageIndex, RELTO_CURRENT_ELEMENT_LIST);
+            columnCount = page.getPageViewport().getCurrentSpan().getColumnCount();
+        } while (colIndex >= columnCount);
+        if (colIndex + 1 < columnCount) {
+            // Next part is a column on same page => same IPD
+            return false;
+        } else {
+            Page nextPage = getPage(false, pageIndex + 1, RELTO_CURRENT_ELEMENT_LIST);
+            return page.getPageViewport().getBodyRegion().getIPD()
+                    != nextPage.getPageViewport().getBodyRegion().getIPD();
+        }
+    }
+
+    /**
+     * Checks if a break at the passed index would start a new page
+     * @param index the index of the element before the break
+     * @return  {@code true} if the break starts a new page
+     */
+    boolean startPage(int index) {
+        return getColIndexAndColCount(index)[0] == 0;
+    }
+
+    /**
+     * Checks if a break at the passed index would end a page
+     * @param index the index of the element before the break
+     * @return  {@code true} if the break ends a page
+     */
+    boolean endPage(int index) {
+        int[] colIndexAndColCount = getColIndexAndColCount(index);
+        return colIndexAndColCount[0] == colIndexAndColCount[1] - 1;
+    }
+
+    /**
+     * Obtain the applicable column-count for the element at the
+     * passed index
+     * @param index the index of the element
+     * @return  the number of columns
+     */
+    int getColumnCount(int index) {
+        return getColIndexAndColCount(index)[1];
+    }
+
     /**
      * Returns the part index (0<x<partCount) which denotes the first part on the last page
      * generated by the current element list.
@@ -272,4 +342,4 @@
         return page;
     }
 
-}
\ No newline at end of file
+}

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/Position.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/Position.java?rev=816718&r1=816717&r2=816718&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/Position.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/Position.java Fri Sep 18 17:10:42 2009
@@ -28,6 +28,11 @@
         layoutManager = lm;
     }
 
+   public Position(LayoutManager lm, int index) {
+        this(lm);
+        setIndex(index);
+    }
+
     public LayoutManager getLM() {
         return layoutManager;
     }

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/SpaceResolver.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/SpaceResolver.java?rev=816718&r1=816717&r2=816718&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/SpaceResolver.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/SpaceResolver.java Fri Sep 18 17:10:42 2009
@@ -19,7 +19,6 @@
 
 package org.apache.fop.layoutmgr;
 
-import java.util.LinkedList;
 import java.util.List;
 import java.util.ListIterator;
 
@@ -565,6 +564,11 @@
         public Position getOriginalBreakPosition() {
             return this.originalPosition;
         }
+
+        public Position getPosition() {
+            return originalPosition;
+        }
+
     }
 
     /**

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java?rev=816718&r1=816717&r2=816718&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java Fri Sep 18 17:10:42 2009
@@ -21,10 +21,6 @@
 
 import java.util.LinkedList;
 import java.util.List;
-import java.util.ListIterator;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 import org.apache.fop.area.Area;
 import org.apache.fop.area.Block;
@@ -35,10 +31,7 @@
 import org.apache.fop.fo.pagination.SideRegion;
 import org.apache.fop.fo.pagination.StaticContent;
 import org.apache.fop.layoutmgr.PageBreakingAlgorithm.PageBreakingLayoutListener;
-import org.apache.fop.layoutmgr.inline.InlineLevelLayoutManager;
 import org.apache.fop.layoutmgr.inline.TextLayoutManager;
-import org.apache.fop.traits.MinOptMax;
-import org.apache.fop.util.ListUtil;
 
 /**
  * LayoutManager for an fo:flow object.
@@ -48,11 +41,6 @@
  */
 public class StaticContentLayoutManager extends BlockStackingLayoutManager {
 
-    /**
-     * logging instance
-     */
-    private static Log log = LogFactory.getLog(StaticContentLayoutManager.class);
-
     private RegionReference targetRegion;
     private Block targetBlock;
     private SideRegion regionFO;
@@ -89,96 +77,7 @@
 
     /** {@inheritDoc} */
     public List getNextKnuthElements(LayoutContext context, int alignment) {
-        if (true) {
-            throw new UnsupportedOperationException(
-                "Shouldn't this method be emptied because it's never called at all?");
-        }
-        //TODO Empty this method?!?
-        // set layout dimensions
-        setContentAreaIPD(context.getRefIPD());
-        setContentAreaBPD(context.getStackLimitBP().opt);
-
-        //TODO Copied from elsewhere. May be worthwhile to factor out the common parts.
-        // currently active LM
-        BlockLevelLayoutManager curLM;
-        BlockLevelLayoutManager prevLM = null;
-        MinOptMax stackSize = new MinOptMax();
-        List returnedList;
-        List returnList = new LinkedList();
-
-        while ((curLM = ((BlockLevelLayoutManager) getChildLM())) != null) {
-            if (curLM instanceof InlineLevelLayoutManager) {
-                log.error("inline area not allowed under flow - ignoring");
-                curLM.setFinished(true);
-                continue;
-            }
-
-            // Set up a LayoutContext
-            MinOptMax bpd = context.getStackLimitBP();
-
-            LayoutContext childLC = new LayoutContext(0);
-            childLC.setStackLimitBP(MinOptMax.subtract(bpd, stackSize));
-            childLC.setRefIPD(context.getRefIPD());
-
-            // get elements from curLM
-            returnedList = curLM.getNextKnuthElements(childLC, alignment);
-            //log.debug("FLM.getNextKnuthElements> returnedList.size() = "
-            //    + returnedList.size());
-
-            // "wrap" the Position inside each element
-            List tempList = returnedList;
-            KnuthElement tempElement;
-            returnedList = new LinkedList();
-            ListIterator listIter = tempList.listIterator();
-            while (listIter.hasNext()) {
-                tempElement = (KnuthElement)listIter.next();
-                tempElement.setPosition(new NonLeafPosition(this, tempElement.getPosition()));
-                returnedList.add(tempElement);
-            }
-
-            if (returnedList.size() == 1
-                && ((KnuthElement)returnedList.get(0)).isPenalty()
-                && ((KnuthPenalty)returnedList.get(0)).getP() == -KnuthElement.INFINITE) {
-                // a descendant of this flow has break-before
-                returnList.addAll(returnedList);
-                return returnList;
-            } else {
-                if (!returnList.isEmpty()) {
-                    // there is a block before this one
-                    if (prevLM.mustKeepWithNext()
-                        || curLM.mustKeepWithPrevious()) {
-                        // add an infinite penalty to forbid a break between blocks
-                        returnList.add(new KnuthPenalty(0,
-                                KnuthElement.INFINITE, false,
-                                new Position(this), false));
-                    } else if (!((KnuthElement) ListUtil.getLast(returnList))
-                            .isGlue()) {
-                        // add a null penalty to allow a break between blocks
-                        returnList.add(new KnuthPenalty(0, 0, false, new Position(this), false));
-                    }
-                }
-/*LF*/          if (!returnedList.isEmpty()) { // controllare!
-                    returnList.addAll(returnedList);
-                    final KnuthElement last = (KnuthElement) ListUtil
-                            .getLast(returnedList);
-                    if (last.isPenalty()
-                            && ((KnuthPenalty) last).getP() == -KnuthElement.INFINITE) {
-                        // a descendant of this flow has break-after
-/*LF*/                  //log.debug("FLM - break after!!");
-                        return returnList;
-                    }
-/*LF*/          }
-            }
-            prevLM = curLM;
-        }
-
-        setFinished(true);
-
-        if (returnList.isEmpty()) {
-            return null;
-        } else {
-            return returnList;
-        }
+        throw new IllegalStateException();
     }
 
     /**
@@ -415,18 +314,18 @@
     }
 
     /** {@inheritDoc} */
-    public int getKeepTogetherStrength() {
-        return KEEP_AUTO;
+    public Keep getKeepTogether() {
+        return Keep.KEEP_AUTO;
     }
 
     /** {@inheritDoc} */
-    public int getKeepWithNextStrength() {
-        return KEEP_AUTO;
+    public Keep getKeepWithNext() {
+        return Keep.KEEP_AUTO;
     }
 
     /** {@inheritDoc} */
-    public int getKeepWithPreviousStrength() {
-        return KEEP_AUTO;
+    public Keep getKeepWithPrevious() {
+        return Keep.KEEP_AUTO;
     }
 
 }

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java?rev=816718&r1=816717&r2=816718&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java Fri Sep 18 17:10:42 2009
@@ -27,6 +27,7 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+
 import org.apache.fop.area.Area;
 import org.apache.fop.area.Block;
 import org.apache.fop.area.LineArea;
@@ -43,7 +44,6 @@
 import org.apache.fop.layoutmgr.Position;
 import org.apache.fop.layoutmgr.PositionIterator;
 import org.apache.fop.layoutmgr.SpaceSpecifier;
-import org.apache.fop.traits.MinOptMax;
 
 /**
  * Content Layout Manager.
@@ -111,8 +111,6 @@
         LayoutContext childLC = new LayoutContext(LayoutContext.NEW_AREA);
         childLC.setLeadingSpace(new SpaceSpecifier(false));
         childLC.setTrailingSpace(new SpaceSpecifier(false));
-        // set stackLimit for lines
-        childLC.setStackLimitIP(new MinOptMax(ipd));
         childLC.setRefIPD(ipd);
 
         int lineHeight = 14000;
@@ -129,8 +127,7 @@
 
         stackSize = 0;
 
-        List contentList =
-            getNextKnuthElements(childLC, Constants.EN_START);
+        List contentList = getNextKnuthElements(childLC, Constants.EN_START);
         ListIterator contentIter = contentList.listIterator();
         while (contentIter.hasNext()) {
             KnuthElement element = (KnuthElement) contentIter.next();
@@ -149,8 +146,7 @@
         lc.setFlags(LayoutContext.RESOLVE_LEADING_SPACE, true);
         lc.setLeadingSpace(new SpaceSpecifier(false));
         lc.setTrailingSpace(new SpaceSpecifier(false));
-        KnuthPossPosIter contentPosIter =
-            new KnuthPossPosIter(contentList, 0, contentList.size());
+        KnuthPossPosIter contentPosIter = new KnuthPossPosIter(contentList, 0, contentList.size());
         curLM.addAreas(contentPosIter, lc);
     }
 

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/inline/ImageLayout.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/inline/ImageLayout.java?rev=816718&r1=816717&r2=816718&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/inline/ImageLayout.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/inline/ImageLayout.java Fri Sep 18 17:10:42 2009
@@ -172,15 +172,15 @@
         }
 
         this.clip = false;
-        if (cwidth > ipd || cheight > bpd) {
-            int overflow = props.getOverflow();
-            if (overflow == EN_HIDDEN) {
-                this.clip = true;
-            } else if (overflow == EN_ERROR_IF_OVERFLOW) {
+        int overflow = props.getOverflow();
+        if (overflow == EN_HIDDEN) {
+            this.clip = true;
+        } else if (overflow == EN_ERROR_IF_OVERFLOW) {
+            if (cwidth > ipd || cheight > bpd) {
                 //TODO Don't use logging to report error!
                 log.error("Object overflows the viewport: clipping");
-                this.clip = true;
             }
+            this.clip = true;
         }
 
         int xoffset = computeXOffset(ipd, cwidth);

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java?rev=816718&r1=816717&r2=816718&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java Fri Sep 18 17:10:42 2009
@@ -248,8 +248,6 @@
         List returnList = new LinkedList();
         KnuthSequence lastSequence = null;
 
-        SpaceSpecifier leadingSpace = context.getLeadingSpace();
-
         if (fobj instanceof Title) {
             alignmentContext = new AlignmentContext(font,
                                     lineHeight.getOptimum(this).getLength().getValue(this),
@@ -274,14 +272,6 @@
             if (getSpaceStart() != null) {
                 context.getLeadingSpace().addSpace(new SpaceVal(getSpaceStart(), this));
             }
-
-            // Check for "fence"
-            if (hasLeadingFence(!context.isFirstArea())) {
-                // Reset leading space sequence for child areas
-                leadingSpace = new SpaceSpecifier(false);
-            }
-            // Reset state variables
-            clearPrevIPD(); // Clear stored prev content dimensions
         }
 
         StringBuffer trace = new StringBuffer("InlineLM:");

Modified: xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java?rev=816718&r1=816717&r2=816718&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java (original)
+++ xmlgraphics/fop/branches/Temp_Accessibility/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java Fri Sep 18 17:10:42 2009
@@ -19,12 +19,13 @@
 
 package org.apache.fop.layoutmgr.inline;
 
-import java.util.LinkedList;
 import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.ListIterator;
-import java.util.HashMap;
 
+import org.apache.fop.area.Area;
+import org.apache.fop.area.inline.Space;
 import org.apache.fop.fo.FObj;
 import org.apache.fop.fo.properties.SpaceProperty;
 import org.apache.fop.layoutmgr.AbstractLayoutManager;
@@ -34,8 +35,6 @@
 import org.apache.fop.layoutmgr.NonLeafPosition;
 import org.apache.fop.layoutmgr.Position;
 import org.apache.fop.layoutmgr.PositionIterator;
-import org.apache.fop.area.Area;
-import org.apache.fop.area.inline.Space;
 import org.apache.fop.traits.MinOptMax;
 
 /**
@@ -62,12 +61,6 @@
         }
     }
 
-
-    /**
-     * Size of any start or end borders and padding.
-     */
-    private MinOptMax allocIPD = new MinOptMax(0);
-
     /**
      * Size of border and padding in BPD (ie, before and after).
      */
@@ -78,9 +71,6 @@
     /** The child layout context */
     protected LayoutContext childLC;
 
-    /** Used to store previous content IPD for each child LM. */
-    private HashMap hmPrevIPD = new HashMap();
-
     /**
      * Create an inline stacking layout manager.
      * This is used for fo's that create areas that
@@ -149,22 +139,6 @@
     }
 
     /**
-     * TODO: Explain this method
-     * @param lm ???
-     * @return ???
-     */
-    protected MinOptMax getPrevIPD(LayoutManager lm) {
-        return (MinOptMax) hmPrevIPD.get(lm);
-    }
-
-    /**
-     * Clear the previous IPD calculation.
-     */
-    protected void clearPrevIPD() {
-        hmPrevIPD.clear();
-    }
-
-    /**
      * Returns the current area.
      * @return the current area
      */



---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org