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 ad...@apache.org on 2011/02/09 00:06:18 UTC

svn commit: r1068674 - in /xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr: BlockContainerLayoutManager.java BlockStackingLayoutManager.java

Author: adelmelle
Date: Tue Feb  8 23:06:18 2011
New Revision: 1068674

URL: http://svn.apache.org/viewvc?rev=1068674&view=rev
Log:
Further reduction of code duplication in/between getNextKnuthElements()

Modified:
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java?rev=1068674&r1=1068673&r2=1068674&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java Tue Feb  8 23:06:18 2011
@@ -188,12 +188,16 @@ public class BlockContainerLayoutManager
     public List getNextKnuthElements
         (LayoutContext context, int alignment, Stack lmStack,
          Position restartPosition, LayoutManager restartAtLM) {
-        boolean isRestart = (lmStack != null);
+
         resetSpaces();
         if (isAbsoluteOrFixed()) {
             return getNextKnuthElementsAbsolute(context);
         }
 
+        boolean isRestart = (lmStack != null);
+        boolean emptyStack = (!isRestart || lmStack.isEmpty());
+        BlockContainer fo = getBlockContainerFO();
+
         autoHeight = false;
         //boolean rotated = (getBlockContainerFO().getReferenceOrientation() % 180 != 0);
         int maxbpd = context.getStackLimitBP().getOpt();
@@ -204,7 +208,7 @@ public class BlockContainerLayoutManager
             //(i.e., it depends on content's block-progression-dimension)" (XSL 1.0, 7.14.1)
             allocBPD = maxbpd;
             autoHeight = true;
-            if (getBlockContainerFO().getReferenceOrientation() == 0) {
+            if (fo.getReferenceOrientation() == 0) {
                 //Cannot easily inline element list when ref-or="180"
                 inlineElementList = true;
             }
@@ -223,23 +227,20 @@ public class BlockContainerLayoutManager
         }
 
         double contentRectOffsetX = 0;
-        contentRectOffsetX += getBlockContainerFO()
-                .getCommonMarginBlock().startIndent.getValue(this);
+        contentRectOffsetX += fo.getCommonMarginBlock().startIndent.getValue(this);
         double contentRectOffsetY = 0;
-        contentRectOffsetY += getBlockContainerFO()
-                .getCommonBorderPaddingBackground().getBorderBeforeWidth(false);
-        contentRectOffsetY += getBlockContainerFO()
-                .getCommonBorderPaddingBackground().getPaddingBefore(false, this);
+        contentRectOffsetY += fo.getCommonBorderPaddingBackground().getBorderBeforeWidth(false);
+        contentRectOffsetY += fo.getCommonBorderPaddingBackground().getPaddingBefore(false, this);
 
         updateRelDims(contentRectOffsetX, contentRectOffsetY, autoHeight);
 
         int availableIPD = referenceIPD - getIPIndents();
         if (getContentAreaIPD() > availableIPD) {
             BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider.get(
-                    getBlockContainerFO().getUserAgent().getEventBroadcaster());
-            eventProducer.objectTooWide(this, getBlockContainerFO().getName(),
+                    fo.getUserAgent().getEventBroadcaster());
+            eventProducer.objectTooWide(this, fo.getName(),
                     getContentAreaIPD(), context.getRefIPD(),
-                    getBlockContainerFO().getLocator());
+                    fo.getLocator());
         }
 
         MinOptMax stackLimit = MinOptMax.getInstance(relDims.bpd);
@@ -248,125 +249,60 @@ public class BlockContainerLayoutManager
         List<ListElement> contentList = new LinkedList<ListElement>();
         List<ListElement> returnList = new LinkedList<ListElement>();
 
-        if (!breakBeforeServed) {
-            breakBeforeServed = true;
-            if (!context.suppressBreakBefore()) {
-                if (addKnuthElementsForBreakBefore(returnList, context)) {
-                    return returnList;
-                }
-            }
-        }
-
-        if (!firstVisibleMarkServed) {
-            addKnuthElementsForSpaceBefore(returnList, alignment);
-            context.updateKeepWithPreviousPending(getKeepWithPrevious());
+        if (!breakBeforeServed(context, returnList)) {
+            return returnList;
         }
 
-        addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed);
-        firstVisibleMarkServed = true;
+        addFirstVisibleMarks(returnList, context, alignment);
 
         if (autoHeight && inlineElementList) {
             //Spaces, border and padding to be repeated at each break
             addPendingMarks(context);
 
-            LayoutManager curLM  = null; // currently active LM
+            LayoutManager curLM; // currently active LM
             LayoutManager prevLM = null; // previously active LM
 
-            LayoutContext childLC = new LayoutContext(0);
+            LayoutContext childLC;
+            boolean doReset = true;
             if (isRestart) {
-                if (lmStack.isEmpty()) {
+                if (emptyStack) {
                     assert restartAtLM != null && restartAtLM.getParent() == this;
                     curLM = restartAtLM;
-                    curLM.reset();
-                    setCurrentChildLM(curLM);
-
-                    childLC.copyPendingMarksFrom(context);
-                    childLC.setStackLimitBP(context.getStackLimitBP().minus(stackLimit));
-                    childLC.setRefIPD(relDims.ipd);
-                    childLC.setWritingMode(getBlockContainerFO().getWritingMode());
-                    if (curLM == this.childLMs.get(0)) {
-                        childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE);
-                        //Handled already by the parent (break collapsing, see above)
-                    }
-
-                    // get elements from curLM
-                    returnedList = curLM.getNextKnuthElements(childLC, alignment);
                 } else {
                     curLM = (LayoutManager) lmStack.pop();
-                    setCurrentChildLM(curLM);
-
-                    childLC.copyPendingMarksFrom(context);
-                    childLC.setStackLimitBP(context.getStackLimitBP().minus(stackLimit));
-                    childLC.setRefIPD(relDims.ipd);
-                    childLC.setWritingMode(getBlockContainerFO().getWritingMode());
-                    if (curLM == this.childLMs.get(0)) {
-                        childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE);
-                        //Handled already by the parent (break collapsing, see above)
-                    }
-
-                    // get elements from curLM
-                    returnedList = curLM.getNextKnuthElements(childLC, alignment, lmStack,
-                            restartPosition, restartAtLM);
-                }
-                if (contentList.isEmpty() && childLC.isKeepWithPreviousPending()) {
-                    //Propagate keep-with-previous up from the first child
-                    context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending());
-                    childLC.clearKeepWithPreviousPending();
-                }
-                if (returnedList.size() == 1
-                        && ElementListUtils.startsWithForcedBreak(returnedList)) {
-                    // a descendant of this block has break-before
-                    contentList.addAll(returnedList);
-
-                    // "wrap" the Position inside each element
-                    // moving the elements from contentList to returnList
-                    wrapPositionElements(contentList, returnList);
-
-                    return returnList;
-                } else {
-                    if (prevLM != null) {
-                        // there is a block handled by prevLM
-                        // before the one handled by curLM
-                        addInBetweenBreak(contentList, context, childLC);
-                    }
-                    contentList.addAll(returnedList);
-                    if (!returnedList.isEmpty()) {
-                        if (ElementListUtils.endsWithForcedBreak(returnedList)) {
-                            // a descendant of this block has break-after
-                            if (curLM.isFinished() && !hasNextChildLM()) {
-                                // there is no other content in this block;
-                                // it's useless to add space after before a page break
-                                setFinished(true);
-                            }
-
-                            wrapPositionElements(contentList, returnList);
-
-                            return returnList;
-                        }
-                    }
+                    // make sure the initial LM is not reset
+                    doReset = false;
                 }
+                setCurrentChildLM(curLM);
+            } else {
+                curLM = getChildLM();
             }
 
-            // propagate and clear
-            context.updateKeepWithNextPending(childLC.getKeepWithNextPending());
-            childLC.clearKeepsPending();
-            prevLM = curLM;
-
-            while ((curLM = getChildLM()) != null) {
-                curLM.reset();
+            while (curLM != null) {
+                if (doReset) {
+                    curLM.reset();
+                }
                 childLC = new LayoutContext(0);
                 childLC.copyPendingMarksFrom(context);
-                // curLM is a ?
                 childLC.setStackLimitBP(context.getStackLimitBP().minus(stackLimit));
                 childLC.setRefIPD(relDims.ipd);
-                childLC.setWritingMode(getBlockContainerFO().getWritingMode());
+                childLC.setWritingMode(fo.getWritingMode());
                 if (curLM == this.childLMs.get(0)) {
                     childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE);
                     //Handled already by the parent (break collapsing, see above)
                 }
 
                 // get elements from curLM
-                returnedList = curLM.getNextKnuthElements(childLC, alignment);
+                if (!isRestart || emptyStack) {
+                    returnedList = curLM.getNextKnuthElements(childLC, alignment);
+                } else {
+                    returnedList = curLM.getNextKnuthElements(childLC, alignment,
+                            lmStack, restartPosition, restartAtLM);
+                    // once encountered, irrelevant for following child LMs
+                    emptyStack = true;
+                    // force reset as of the next child
+                    doReset = true;
+                }
                 if (contentList.isEmpty() && childLC.isKeepWithPreviousPending()) {
                     //Propagate keep-with-previous up from the first child
                     context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending());
@@ -410,10 +346,9 @@ public class BlockContainerLayoutManager
                 context.updateKeepWithNextPending(childLC.getKeepWithNextPending());
                 childLC.clearKeepsPending();
                 prevLM = curLM;
+                curLM = getChildLM();
             }
-
             wrapPositionElements(contentList, returnList);
-
         } else {
             returnList.add(generateNonInlinedBox(contentRectOffsetX, contentRectOffsetY));
         }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java?rev=1068674&r1=1068673&r2=1068674&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java Tue Feb  8 23:06:18 2011
@@ -253,22 +253,13 @@ public abstract class BlockStackingLayou
         List<ListElement> contentList = new LinkedList<ListElement>();
         List<ListElement> elements = new LinkedList<ListElement>();
 
-        if (!breakBeforeServed) {
-            breakBeforeServed = true;
-            if (!context.suppressBreakBefore()) {
-                if (addKnuthElementsForBreakBefore(elements, context)) {
-                    return elements;
-                }
-            }
+        if (!breakBeforeServed(context, elements)) {
+            // if this FO has break-before specified, and it
+            // has not yet been processed, return now
+            return elements;
         }
 
-        if (!firstVisibleMarkServed) {
-            addKnuthElementsForSpaceBefore(elements, alignment);
-            context.updateKeepWithPreviousPending(getKeepWithPrevious());
-        }
-
-        addKnuthElementsForBorderPaddingBefore(elements, !firstVisibleMarkServed);
-        firstVisibleMarkServed = true;
+        addFirstVisibleMarks(elements, context, alignment);
 
         //Spaces, border and padding to be repeated at each break
         addPendingMarks(context);
@@ -279,14 +270,15 @@ public abstract class BlockStackingLayou
         LayoutContext childLC;
         List<ListElement> childElements;
         LayoutManager currentChildLM;
+        // always reset in case of a restart (exception: see below)
         boolean doReset = isRestart;
         if (isRestart) {
             if (emptyStack) {
                 assert restartAtLM != null && restartAtLM.getParent() == this;
                 currentChildLM = restartAtLM;
-                currentChildLM.reset();
             } else {
                 currentChildLM = (LayoutManager) lmStack.pop();
+                // make sure the initial child LM is not reset
                 doReset = false;
             }
             setCurrentChildLM(currentChildLM);
@@ -318,6 +310,7 @@ public abstract class BlockStackingLayou
                 // propagate keep-with-previous up from the first child
                 context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending());
             }
+
             // handle non-empty child
             if (childElements != null && !childElements.isEmpty()) {
                 if (!contentList.isEmpty()
@@ -370,12 +363,15 @@ public abstract class BlockStackingLayou
             currentChildLM = getChildLM();
         }
 
-        if (!contentList.isEmpty()) {
+        if (contentList.isEmpty()) {
+            if (forcedBreakAfterLast == null) {
+                // empty fo:block: zero-length box makes sure the IDs and/or markers
+                // are registered.
+                elements.add(makeAuxiliaryZeroWidthBox());
+            }
+        } else {
+            // wrap child positions
             wrapPositionElements(contentList, elements);
-        } else if (forcedBreakAfterLast == null) {
-            // empty fo:block: zero-length box makes sure the IDs and/or markers
-            // are registered.
-            elements.add(makeAuxiliaryZeroWidthBox());
         }
 
         addKnuthElementsForBorderPaddingAfter(elements, true);
@@ -395,6 +391,45 @@ public abstract class BlockStackingLayou
         return elements;
     }
 
+    /**
+     * Checks if this LM's first "visible marks" (= borders, padding, spaces) have
+     * already been processed, and if necessary, adds corresponding elements to
+     * the specified list.
+     * @param elements  the element list
+     * @param context   the layout context
+     * @param alignment the vertical alignment
+     */
+    protected void addFirstVisibleMarks(List<ListElement> elements,
+                                        LayoutContext context, int alignment) {
+        if (!firstVisibleMarkServed) {
+            addKnuthElementsForSpaceBefore(elements, alignment);
+            context.updateKeepWithPreviousPending(getKeepWithPrevious());
+        }
+        addKnuthElementsForBorderPaddingBefore(elements, !firstVisibleMarkServed);
+        firstVisibleMarkServed = true;
+    }
+
+    /**
+     * Check whether there is a break-before condition. If so, and
+     * the specified {@code context} allows it, add the necessary elements
+     * to the given {@code elements} list.
+     * @param context   the layout context
+     * @param elements  the element list
+     * @return {@code false} if there is a break-before condition, and it has not been served;
+     * {@code true} otherwise
+     */
+    protected boolean breakBeforeServed(LayoutContext context, List<ListElement> elements) {
+        if (!breakBeforeServed) {
+            breakBeforeServed = true;
+            if (!context.suppressBreakBefore()) {
+                if (addKnuthElementsForBreakBefore(elements, context)) {
+                    return false;
+                }
+            }
+        }
+        return breakBeforeServed;
+    }
+
     private KnuthBox makeZeroWidthBox() {
         return new KnuthBox(0, new NonLeafPosition(this, null), false);
     }



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