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/08/26 19:42:12 UTC

svn commit: r808135 - in /xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr: ./ inline/

Author: vhennebert
Date: Wed Aug 26 17:42:11 2009
New Revision: 808135

URL: http://svn.apache.org/viewvc?rev=808135&view=rev
Log:
Reverted changes made in revision 796809 (manual merge of clean-up changes made in the ChangingIPDHack branch). Those changes will be re-applied when merging the branch back to Trunk with svn merge --reintegrate (if everything goes well...)

Modified:
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/InlineKnuthSequence.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutContext.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LeafPosition.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageBreaker.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java?rev=808135&r1=808134&r2=808135&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java Wed Aug 26 17:42:11 2009
@@ -293,6 +293,14 @@
     /**
      * Starts the page breaking process.
      * @param flowBPD the constant available block-progression-dimension (used for every part)
+     */
+    public void doLayout(int flowBPD) {
+        doLayout(flowBPD, false);
+    }
+
+    /**
+     * Starts the page breaking process.
+     * @param flowBPD the constant available block-progression-dimension (used for every part)
      * @param autoHeight true if warnings about overflows should be disabled because the
      *                   the BPD is really undefined (for footnote-separators, for example)
      */

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java?rev=808135&r1=808134&r2=808135&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java Wed Aug 26 17:42:11 2009
@@ -47,22 +47,22 @@
     private static Log log = LogFactory.getLog(AbstractLayoutManager.class);
 
     /** Parent LayoutManager for this LayoutManager */
-    protected LayoutManager parentLM;
+    protected LayoutManager parentLM = null;
     /** List of child LayoutManagers */
-    protected List childLMs;
+    protected List childLMs = null;
     /** Iterator for child LayoutManagers */
-    protected ListIterator fobjIter;
+    protected ListIterator fobjIter = null;
     /** Marker map for markers related to this LayoutManager */
-    private Map markers;
+    private Map markers = null;
 
     /** True if this LayoutManager has handled all of its content. */
-    private boolean isFinished;
+    private boolean isFinished = false;
 
     /** child LM during getNextKnuthElement phase */
-    protected LayoutManager curChildLM;
+    protected LayoutManager curChildLM = null;
 
     /** child LM iterator during getNextKnuthElement phase */
-    protected ListIterator childLMiter;
+    protected ListIterator childLMiter = null;
 
     private int lastGeneratedPosition = -1;
     private int smallestPosNumberChecked = Integer.MAX_VALUE;

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java?rev=808135&r1=808134&r2=808135&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java Wed Aug 26 17:42:11 2009
@@ -117,7 +117,7 @@
             // set space after for each LM, in order to implement
             // display-align = distribute
             lc.setSpaceAfter(layoutContext.getSpaceAfter());
-            lc.setStackLimitBP(layoutContext.getStackLimitBP());
+            lc.setStackLimitsFrom(layoutContext);
             childLM.addAreas(childPosIter, lc);
         }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java?rev=808135&r1=808134&r2=808135&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java Wed Aug 26 17:42:11 2009
@@ -67,6 +67,9 @@
     private MinOptMax effSpaceBefore;
     private MinOptMax effSpaceAfter;
 
+    /** The list of child BreakPoss instances. */
+    protected List childBreaks = new java.util.ArrayList();
+
     /**
      * Creates a new BlockLayoutManager.
      * @param inBlock the block FO object to create the layout manager for.
@@ -246,8 +249,8 @@
         // and put them in a new list;
         LinkedList positionList = new LinkedList();
         Position pos;
-        boolean spaceBefore = false;
-        boolean spaceAfter = false;
+        boolean bSpaceBefore = false;
+        boolean bSpaceAfter = false;
         Position firstPos = null;
         Position lastPos = null;
         while (parentIter.hasNext()) {
@@ -270,11 +273,11 @@
                 // this means the space was not discarded
                 if (positionList.size() == 0) {
                     // pos was in the element representing space-before
-                    spaceBefore = true;
+                    bSpaceBefore = true;
                     //log.trace(" space before");
                 } else {
                     // pos was in the element representing space-after
-                    spaceAfter = true;
+                    bSpaceAfter = true;
                     //log.trace(" space-after");
                 }
             } else if (innerPosition.getLM() == this
@@ -299,7 +302,7 @@
             // the Positions in positionList were inside the elements
             // created by the LineLM
             childPosIter = new StackingIter(positionList.listIterator());
-        } else {
+            } else {
             // the Positions in positionList were inside the elements
             // created by the BlockLM in the createUnitElements() method
             //if (((Position) positionList.getLast()) instanceof
@@ -338,7 +341,7 @@
             //                   + " spacing");
             // add space before and / or after the paragraph
             // to reach a multiple of bpUnit
-            if (spaceBefore && spaceAfter) {
+            if (bSpaceBefore && bSpaceAfter) {
                 foSpaceBefore = new SpaceVal(getBlockFO()
                                     .getCommonMarginBlock().spaceBefore, this).getSpace();
                 foSpaceAfter = new SpaceVal(getBlockFO()
@@ -351,7 +354,7 @@
                         + foSpaceBefore.min
                         + foSpaceAfter.min)
                         * bpUnit - splitLength - adjustedSpaceBefore;
-                } else if (spaceBefore) {
+                } else if (bSpaceBefore) {
                 adjustedSpaceBefore = neededUnits(splitLength
                         + foSpaceBefore.min)
                         * bpUnit - splitLength;

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=808135&r1=808134&r2=808135&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 Wed Aug 26 17:42:11 2009
@@ -54,26 +54,31 @@
      */
     private static Log log = LogFactory.getLog(BlockStackingLayoutManager.class);
 
-    protected BlockParent parentArea;
+    /**
+     * Reference to FO whose areas it's managing or to the traits
+     * of the FO.
+     */
+    //protected LayoutManager curChildLM = null; AbstractLayoutManager also defines this!
+    protected BlockParent parentArea = null;
 
     /** Value of the block-progression-unit (non-standard property) */
-    protected int bpUnit;
+    protected int bpUnit = 0;
     /** space-before value adjusted for block-progression-unit handling */
-    protected int adjustedSpaceBefore;
+    protected int adjustedSpaceBefore = 0;
     /** space-after value adjusted for block-progression-unit handling */
-    protected int adjustedSpaceAfter;
+    protected int adjustedSpaceAfter = 0;
     /** Only used to store the original list when createUnitElements is called */
-    protected List storedList;
+    protected List storedList = null;
     /** Indicates whether break before has been served or not */
-    protected boolean breakBeforeServed;
+    protected boolean breakBeforeServed = false;
     /** Indicates whether the first visible mark has been returned by this LM, yet */
-    protected boolean firstVisibleMarkServed;
+    protected boolean firstVisibleMarkServed = false;
     /** Reference IPD available */
-    protected int referenceIPD;
+    protected int referenceIPD = 0;
     /** the effective start-indent value */
-    protected int startIndent;
+    protected int startIndent = 0;
     /** the effective end-indent value */
-    protected int endIndent;
+    protected int endIndent = 0;
     /**
      * Holds the (one-time use) fo:block space-before
      * and -after properties.  Large fo:blocks are split
@@ -83,13 +88,13 @@
      * Block and space-after at the end of the last Block
      * used in rendering the fo:block.
      */
-    protected MinOptMax foSpaceBefore;
+    protected MinOptMax foSpaceBefore = null;
     /** see foSpaceBefore */
-    protected MinOptMax foSpaceAfter;
+    protected MinOptMax foSpaceAfter = null;
 
     private Position auxiliaryPosition;
 
-    private int contentAreaIPD;
+    private int contentAreaIPD = 0;
 
     /**
      * @param node the fo this LM deals with
@@ -243,27 +248,38 @@
 
     /** {@inheritDoc} */
     public List getNextKnuthElements(LayoutContext context, int alignment) {
+        //log.debug("BLM.getNextKnuthElements> keep-together = "
+              // + layoutProps.keepTogether.getType());
+        //log.debug(" keep-with-previous = " +
+              // layoutProps.keepWithPrevious.getType());
+        //log.debug(" keep-with-next = " +
+              // layoutProps.keepWithNext.getType());
+        BlockLevelLayoutManager curLM; // currently active LM
+        BlockLevelLayoutManager prevLM = null; // previously active LM
+
         referenceIPD = context.getRefIPD();
+
         updateContentAreaIPDwithOverconstrainedAdjust();
 
+        List returnedList = null;
         List contentList = new LinkedList();
-        List elements = new LinkedList();
+        List returnList = new LinkedList();
 
         if (!breakBeforeServed) {
             breakBeforeServed = true;
             if (!context.suppressBreakBefore()) {
-                if (addKnuthElementsForBreakBefore(elements, context)) {
-                    return elements;
+                if (addKnuthElementsForBreakBefore(returnList, context)) {
+                    return returnList;
                 }
             }
         }
 
         if (!firstVisibleMarkServed) {
-            addKnuthElementsForSpaceBefore(elements, alignment);
+            addKnuthElementsForSpaceBefore(returnList, alignment);
             context.updateKeepWithPreviousPending(getKeepWithPrevious());
         }
 
-        addKnuthElementsForBorderPaddingBefore(elements, !firstVisibleMarkServed);
+        addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed);
         firstVisibleMarkServed = true;
 
         //Spaces, border and padding to be repeated at each break
@@ -272,107 +288,142 @@
         //Used to indicate a special break-after case when all content has already been generated.
         BreakElement forcedBreakAfterLast = null;
 
-        LayoutManager currentChildLM;
-        while ((currentChildLM = (LayoutManager) getChildLM()) != null) {
+        while ((curLM = (BlockLevelLayoutManager) getChildLM()) != null) {
             LayoutContext childLC = new LayoutContext(0);
+            childLC.copyPendingMarksFrom(context);
+            if (curLM instanceof LineLayoutManager) {
+                // curLM is a LineLayoutManager
+                // set stackLimit for lines (stack limit is now i-p-direction, not b-p-direction!)
+                childLC.setStackLimitBP(context.getStackLimitBP());
+                childLC.setStackLimitIP(new MinOptMax(getContentAreaIPD()));
+                childLC.setRefIPD(getContentAreaIPD());
+            } else {
+                // curLM is a ?
+                //childLC.setStackLimit(MinOptMax.subtract(context
+                //        .getStackLimit(), stackSize));
+                childLC.setStackLimitBP(context.getStackLimitBP());
+                childLC.setRefIPD(referenceIPD);
+            }
+            if (curLM == this.childLMs.get(0)) {
+                childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE);
+                //Handled already by the parent (break collapsing, see above)
+            }
 
-            List childrenElements = getNextChildElements(currentChildLM, context, childLC,
-                    alignment);
-
-            if (contentList.isEmpty()) {
+            // get elements from curLM
+            returnedList = curLM.getNextKnuthElements(childLC, alignment);
+            if (contentList.isEmpty() && childLC.isKeepWithPreviousPending()) {
                 //Propagate keep-with-previous up from the first child
                 context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending());
+                childLC.clearKeepWithPreviousPending();
             }
-            if (childrenElements != null && !childrenElements.isEmpty()) {
-                if (!contentList.isEmpty()
-                        && !ElementListUtils.startsWithForcedBreak(childrenElements)) {
+            if (returnedList != null
+                    && returnedList.size() == 1
+                    && ((ListElement) returnedList.get(0)).isForcedBreak()) {
+
+                if (curLM.isFinished() && !hasNextChildLM()) {
+                    // a descendant of this block has break-before
+                    forcedBreakAfterLast = (BreakElement) returnedList.get(0);
+                    context.clearPendingMarks();
+                    break;
+                }
+
+                if (contentList.isEmpty()) {
+                    // Empty fo:block, zero-length box makes sure the IDs and/or markers
+                    // are registered and borders/padding are painted.
+                    returnList.add(new KnuthBox(0, notifyPos(new Position(this)), false));
+                }
+                // a descendant of this block has break-before
+                contentList.addAll(returnedList);
+
+                /* extension: conversione di tutta la sequenza fin'ora ottenuta */
+                if (bpUnit > 0) {
+                    storedList = contentList;
+                    contentList = createUnitElements(contentList);
+                }
+                /* end of extension */
+
+                // "wrap" the Position inside each element
+                // moving the elements from contentList to returnList
+                returnedList = new LinkedList();
+                wrapPositionElements(contentList, returnList);
+
+                return returnList;
+            } else {
+                if (returnedList == null || returnedList.isEmpty()) {
+                    //Avoid NoSuchElementException below (happens with empty blocks)
+                    continue;
+                }
+                if (prevLM != null
+                        && !ElementListUtils.startsWithForcedBreak(returnedList)) {
                     // there is a block handled by prevLM before the one
                     // handled by curLM, and the one handled
                     // by the current LM does not begin with a break
                     addInBetweenBreak(contentList, context, childLC);
                 }
-                if (childrenElements.size() == 1
-                        && ElementListUtils.startsWithForcedBreak(childrenElements)) {
-
-                    if (currentChildLM.isFinished() && !hasNextChildLM()) {
-                        // a descendant of this block has break-before
-                        forcedBreakAfterLast = (BreakElement) childrenElements.get(0);
+                contentList.addAll(returnedList);
+                if (ElementListUtils.endsWithForcedBreak(returnedList)) {
+                    // a descendant of this block has break-after
+                    if (curLM.isFinished() && !hasNextChildLM()) {
+                        forcedBreakAfterLast = (BreakElement) ListUtil
+                                .removeLast(contentList);
                         context.clearPendingMarks();
                         break;
                     }
 
-                    if (contentList.isEmpty()) {
-                        // Empty fo:block, zero-length box makes sure the IDs and/or markers
-                        // are registered and borders/padding are painted.
-                        elements.add(new KnuthBox(0, notifyPos(new Position(this)), false));
+                    /* extension: conversione di tutta la sequenza fin'ora ottenuta */
+                    if (bpUnit > 0) {
+                        storedList = contentList;
+                        contentList = createUnitElements(contentList);
                     }
-                    // a descendant of this block has break-before
-                    contentList.addAll(childrenElements);
-
-                    wrapPositionElements(contentList, elements);
-
-                    return elements;
-                } else {
-                    contentList.addAll(childrenElements);
-                    if (ElementListUtils.endsWithForcedBreak(childrenElements)) {
-                        // a descendant of this block has break-after
-                        if (currentChildLM.isFinished() && !hasNextChildLM()) {
-                            forcedBreakAfterLast = (BreakElement) ListUtil.removeLast(contentList);
-                            context.clearPendingMarks();
-                            break;
-                        }
+                    /* end of extension */
 
-                        wrapPositionElements(contentList, elements);
+                    returnedList = new LinkedList();
+                    wrapPositionElements(contentList, returnList);
 
-                        return elements;
-                    }
+                    return returnList;
                 }
-                context.updateKeepWithNextPending(childLC.getKeepWithNextPending());
             }
+            // propagate and clear
+            context.updateKeepWithNextPending(childLC.getKeepWithNextPending());
+            childLC.clearKeepsPending();
+            prevLM = curLM;
+        }
+
+        /* Extension: conversione di tutta la sequenza fin'ora ottenuta */
+        if (bpUnit > 0) {
+            storedList = contentList;
+            contentList = createUnitElements(contentList);
         }
+        /* end of extension */
 
+        returnedList = new LinkedList();
         if (!contentList.isEmpty()) {
-            wrapPositionElements(contentList, elements);
+            wrapPositionElements(contentList, returnList);
         } else if (forcedBreakAfterLast == null) {
             // Empty fo:block, zero-length box makes sure the IDs and/or markers
             // are registered.
-            elements.add(new KnuthBox(0, notifyPos(new Position(this)), true));
+            returnList.add(new KnuthBox(0, notifyPos(new Position(this)), true));
         }
 
-        addKnuthElementsForBorderPaddingAfter(elements, true);
-        addKnuthElementsForSpaceAfter(elements, alignment);
+        addKnuthElementsForBorderPaddingAfter(returnList, true);
+        addKnuthElementsForSpaceAfter(returnList, alignment);
 
         //All child content is processed. Only break-after can occur now, so...
         context.clearPendingMarks();
         if (forcedBreakAfterLast == null) {
-            addKnuthElementsForBreakAfter(elements, context);
-        } else {
+            addKnuthElementsForBreakAfter(returnList, context);
+        }
+
+        if (forcedBreakAfterLast != null) {
             forcedBreakAfterLast.clearPendingMarks();
-            elements.add(forcedBreakAfterLast);
+            returnList.add(forcedBreakAfterLast);
         }
 
         context.updateKeepWithNextPending(getKeepWithNext());
 
         setFinished(true);
 
-        return elements;
-    }
-
-    private List getNextChildElements(LayoutManager childLM, LayoutContext context,
-            LayoutContext childLC, int alignment) {
-        childLC.copyPendingMarksFrom(context);
-        childLC.setStackLimitBP(context.getStackLimitBP());
-        if (childLM instanceof LineLayoutManager) {
-            childLC.setRefIPD(getContentAreaIPD());
-        } else {
-            childLC.setRefIPD(referenceIPD);
-        }
-        if (childLM == this.childLMs.get(0)) {
-            childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE);
-            //Handled already by the parent (break collapsing, see above)
-        }
-
-        return childLM.getNextKnuthElements(childLC, alignment);
+        return returnList;
     }
 
     /**

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java?rev=808135&r1=808134&r2=808135&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java Wed Aug 26 17:42:11 2009
@@ -1283,8 +1283,12 @@
      * @return the width/length in millipoints
      */
     protected int getLineWidth(int line) {
-        assert lineWidth >= 0;
-        return this.lineWidth;
+        if (this.lineWidth < 0) {
+            throw new IllegalStateException("lineWidth must be set"
+                    + (this.lineWidth != 0 ? " and positive, but it is: " + this.lineWidth : ""));
+        } else {
+            return this.lineWidth;
+        }
     }
 
     /** @return the constant line/part width or -1 if there is no such value */

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java?rev=808135&r1=808134&r2=808135&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java Wed Aug 26 17:42:11 2009
@@ -29,6 +29,8 @@
 import org.apache.fop.area.Area;
 import org.apache.fop.area.BlockParent;
 import org.apache.fop.fo.pagination.Flow;
+import org.apache.fop.layoutmgr.inline.InlineLevelLayoutManager;
+import org.apache.fop.layoutmgr.inline.WrapperLayoutManager;
 
 /**
  * LayoutManager for an fo:flow object.
@@ -62,89 +64,110 @@
     /** {@inheritDoc} */
     public List getNextKnuthElements(LayoutContext context, int alignment) {
 
-        List elements = new LinkedList();
+        // set layout dimensions
+        int flowIPD = getCurrentPV().getCurrentSpan().getColumnWidth();
+        int flowBPD = getCurrentPV().getBodyRegion().getBPD();
+
+        // currently active LM
+        LayoutManager curLM;
+        List returnedList;
+        List returnList = new LinkedList();
 
-        LayoutManager currentChildLM;
-        while ((currentChildLM = getChildLM()) != null) {
-            if (handleSpanChange(currentChildLM, elements, context)) {
-                SpaceResolver.resolveElementList(elements);
-                return elements;
+        while ((curLM = getChildLM()) != null) {
+            if (!(curLM instanceof WrapperLayoutManager)
+                && curLM instanceof InlineLevelLayoutManager) {
+                log.error("inline area not allowed under flow - ignoring");
+                curLM.setFinished(true);
+                continue;
             }
 
-            LayoutContext childLC = new LayoutContext(0);
-            List childrenElements = getNextChildElements(currentChildLM, context, childLC,
-                    alignment);
-            if (elements.isEmpty()) {
-                context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending());
+            int span = EN_NONE;
+            int disableColumnBalancing = EN_FALSE;
+            if (curLM instanceof BlockLayoutManager) {
+                span = ((BlockLayoutManager)curLM).getBlockFO().getSpan();
+                disableColumnBalancing = ((BlockLayoutManager) curLM).getBlockFO()
+                        .getDisableColumnBalancing();
+            } else if (curLM instanceof BlockContainerLayoutManager) {
+                span = ((BlockContainerLayoutManager)curLM).getBlockContainerFO().getSpan();
+                disableColumnBalancing = ((BlockContainerLayoutManager) curLM).getBlockContainerFO()
+                        .getDisableColumnBalancing();
             }
-            if (!elements.isEmpty()
-                    && !ElementListUtils.startsWithForcedBreak(childrenElements)) {
-                addInBetweenBreak(elements, context, childLC);
+
+            int currentSpan = context.getCurrentSpan();
+            if (currentSpan != span) {
+                if (span == EN_ALL) {
+                    context.setDisableColumnBalancing(disableColumnBalancing);
+                }
+                log.debug("span change from " + currentSpan + " to " + span);
+                context.signalSpanChange(span);
+                SpaceResolver.resolveElementList(returnList);
+                return returnList;
             }
-            context.updateKeepWithNextPending(childLC.getKeepWithNextPending());
 
-            elements.addAll(childrenElements);
+            // Set up a LayoutContext
+            //MinOptMax bpd = context.getStackLimit();
 
-            if (ElementListUtils.endsWithForcedBreak(elements)) {
-                // a descendant of this flow has break-before or break-after
-                if (currentChildLM.isFinished() && !hasNextChildLM()) {
-                    setFinished(true);
-                }
-                SpaceResolver.resolveElementList(elements);
-                return elements;
+            LayoutContext childLC = new LayoutContext(0);
+            childLC.setStackLimitBP(context.getStackLimitBP());
+            childLC.setRefIPD(context.getRefIPD());
+            childLC.setWritingMode(getCurrentPage().getSimplePageMaster().getWritingMode());
+
+            // get elements from curLM
+            returnedList = curLM.getNextKnuthElements(childLC, alignment);
+            //log.debug("FLM.getNextKnuthElements> returnedList.size() = " + returnedList.size());
+            if (returnList.size() == 0 && childLC.isKeepWithPreviousPending()) {
+                context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending());
+                childLC.clearKeepWithPreviousPending();
             }
-        }
 
-        SpaceResolver.resolveElementList(elements);
-        setFinished(true);
+            // "wrap" the Position inside each element
+            List tempList = returnedList;
+            returnedList = new LinkedList();
+            wrapPositionElements(tempList, returnedList);
+
+            if (returnedList.size() == 1
+                && ElementListUtils.endsWithForcedBreak(returnedList)) {
+                // a descendant of this flow has break-before
+                returnList.addAll(returnedList);
+                SpaceResolver.resolveElementList(returnList);
+                return returnList;
+            } else if (returnedList.size() > 0) {
+                if (returnList.size() > 0
+                        && !ElementListUtils.startsWithForcedBreak(returnedList)) {
+                    addInBetweenBreak(returnList, context, childLC);
+                }
+                returnList.addAll(returnedList);
+                if (ElementListUtils.endsWithForcedBreak(returnList)) {
+                    if (curLM.isFinished() && !hasNextChildLM()) {
+                        //If the layout manager is finished at this point, the pending
+                        //marks become irrelevant.
+                        childLC.clearPendingMarks();
+                        //setFinished(true);
+                        break;
+                    }
+                    // a descendant of this flow has break-after
+                    SpaceResolver.resolveElementList(returnList);
+                    return returnList;
+                }
+            }
 
-        assert !elements.isEmpty();
-        return elements;
-    }
+            //Propagate and clear
+            context.updateKeepWithNextPending(childLC.getKeepWithNextPending());
+            childLC.clearKeepWithNextPending();
 
-    private boolean handleSpanChange(LayoutManager childLM, List elements, LayoutContext context) {
-        int span = EN_NONE;
-        int disableColumnBalancing = EN_FALSE;
-        if (childLM instanceof BlockLayoutManager) {
-            span = ((BlockLayoutManager)childLM).getBlockFO().getSpan();
-            disableColumnBalancing = ((BlockLayoutManager) childLM).getBlockFO()
-                    .getDisableColumnBalancing();
-        } else if (childLM instanceof BlockContainerLayoutManager) {
-            span = ((BlockContainerLayoutManager)childLM).getBlockContainerFO().getSpan();
-            disableColumnBalancing = ((BlockContainerLayoutManager) childLM).getBlockContainerFO()
-                    .getDisableColumnBalancing();
+            context.updateKeepWithNextPending(getKeepWithNext());
         }
 
-        int currentSpan = context.getCurrentSpan();
-        if (currentSpan != span) {
-            if (span == EN_ALL) {
-                context.setDisableColumnBalancing(disableColumnBalancing);
-            }
-            log.debug("span change from " + currentSpan + " to " + span);
-            context.signalSpanChange(span);
-            return true;
+        SpaceResolver.resolveElementList(returnList);
+        setFinished(true);
+
+        if (returnList.size() > 0) {
+            return returnList;
         } else {
-            return false;
+            return null;
         }
     }
 
-    private List getNextChildElements(LayoutManager childLM, LayoutContext context,
-            LayoutContext childLC, int alignment) {
-        childLC.setStackLimitBP(context.getStackLimitBP());
-        childLC.setRefIPD(context.getRefIPD());
-        childLC.setWritingMode(getCurrentPage().getSimplePageMaster().getWritingMode());
-
-        // get elements from curLM
-        List childrenElements = childLM.getNextKnuthElements(childLC, alignment);
-        assert !childrenElements.isEmpty();
-
-        // "wrap" the Position inside each element
-        List tempList = childrenElements;
-        childrenElements = new LinkedList();
-        wrapPositionElements(tempList, childrenElements);
-        return childrenElements;
-    }
-
     /**
      * {@inheritDoc}
      */

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/InlineKnuthSequence.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/InlineKnuthSequence.java?rev=808135&r1=808134&r2=808135&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/InlineKnuthSequence.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/InlineKnuthSequence.java Wed Aug 26 17:42:11 2009
@@ -57,12 +57,16 @@
         return true;
     }
 
-    /** {@inheritDoc} */
+    /* (non-Javadoc)
+     * {@inheritDoc}
+     */
     public boolean canAppendSequence(KnuthSequence sequence) {
         return sequence.isInlineSequence() && !isClosed;
     }
 
-    /** {@inheritDoc} */
+    /* (non-Javadoc)
+     * {@inheritDoc}
+     */
     public boolean appendSequence(KnuthSequence sequence) {
         if (!canAppendSequence(sequence)) {
             return false;
@@ -79,14 +83,18 @@
         return true;
     }
 
-    /** {@inheritDoc} */
+    /* (non-Javadoc)
+     * {@inheritDoc}
+     */
     public boolean appendSequence(KnuthSequence sequence, boolean keepTogether,
                                   BreakElement breakElement) {
         return appendSequence(sequence);
     }
 
 
-    /** {@inheritDoc} */
+    /* (non-Javadoc)
+     * {@inheritDoc}
+     */
     public KnuthSequence endSequence() {
         if (!isClosed) {
             add(new KnuthPenalty(0, -KnuthElement.INFINITE, false, null, false));

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutContext.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutContext.java?rev=808135&r1=808134&r2=808135&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutContext.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutContext.java Wed Aug 26 17:42:11 2009
@@ -78,6 +78,15 @@
      * level LM to allow them to optimize returned break possibilities.
      */
     private MinOptMax stackLimitBP;
+    /**
+     * Total available stacking dimension for a "galley-level" layout
+     * manager in inline-progression-direction. It is passed by the
+     * parent LM. For LineLM, the block LM determines this based on
+     * indent properties.
+     * These LM <b>may</b> wish to pass this information down to lower
+     * level LM to allow them to optimize returned break possibilities.
+     */
+    private MinOptMax stackLimitIP;
 
     /** to keep track of spanning in multi-column layout */
     private int currentSpan = Constants.NOT_SET;
@@ -149,7 +158,7 @@
         this.flags = parentLC.flags;
         this.refIPD = parentLC.refIPD;
         this.writingMode = parentLC.writingMode;
-        setStackLimitBP(parentLC.getStackLimitBP());
+        setStackLimitsFrom(parentLC);
         this.leadingSpace = parentLC.leadingSpace; //???
         this.trailingSpace = parentLC.trailingSpace; //???
         this.hyphContext = parentLC.hyphContext;
@@ -174,6 +183,7 @@
         this.flags = flags;
         this.refIPD = 0;
         stackLimitBP = new MinOptMax(0);
+        stackLimitIP = new MinOptMax(0);
         leadingSpace = null;
         trailingSpace = null;
     }
@@ -388,6 +398,31 @@
     }
 
     /**
+     * Sets the stack limit in inline-progression-dimension.
+     * @param limit the stack limit
+     */
+    public void setStackLimitIP(MinOptMax limit) {
+        stackLimitIP = limit;
+    }
+
+    /**
+     * Returns the stack limit in inline-progression-dimension.
+     * @return the stack limit
+     */
+    public MinOptMax getStackLimitIP() {
+        return stackLimitIP;
+    }
+
+    /**
+     * Sets (Copies) the stack limits in both directions from another layout context.
+     * @param context the layout context to take the values from
+     */
+    public void setStackLimitsFrom(LayoutContext context) {
+        setStackLimitBP(context.getStackLimitBP());
+        setStackLimitIP(context.getStackLimitIP());
+    }
+
+    /**
      * Sets the inline-progression-dimension of the nearest ancestor reference area.
      */
     public void setRefIPD(int ipd) {
@@ -627,6 +662,8 @@
         return "Layout Context:"
         + "\nStack Limit BPD: \t"
             + (getStackLimitBP() == null ? "null" : getStackLimitBP().toString())
+        + "\nStack Limit IPD: \t"
+            + (getStackLimitIP() == null ? "null" : getStackLimitIP().toString())
         + "\nTrailing Space: \t"
             + (getTrailingSpace() == null ? "null" : getTrailingSpace().toString())
         + "\nLeading Space: \t"

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LeafPosition.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LeafPosition.java?rev=808135&r1=808134&r2=808135&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LeafPosition.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LeafPosition.java Wed Aug 26 17:42:11 2009
@@ -21,15 +21,15 @@
 
 public class LeafPosition extends Position {
 
-    private int leafPos;
+    private int iLeafPos;
 
     public LeafPosition(LayoutManager lm, int pos) {
         super(lm);
-        leafPos = pos;
+        iLeafPos = pos;
     }
 
     public int getLeafPos() {
-        return leafPos;
+        return iLeafPos;
     }
 
     public boolean generatesAreas() {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageBreaker.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageBreaker.java?rev=808135&r1=808134&r2=808135&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageBreaker.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageBreaker.java Wed Aug 26 17:42:11 2009
@@ -77,14 +77,6 @@
         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() {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java?rev=808135&r1=808134&r2=808135&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java Wed Aug 26 17:42:11 2009
@@ -21,6 +21,10 @@
 
 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;
@@ -31,7 +35,10 @@
 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.
@@ -41,6 +48,11 @@
  */
 public class StaticContentLayoutManager extends BlockStackingLayoutManager {
 
+    /**
+     * logging instance
+     */
+    private static Log log = LogFactory.getLog(StaticContentLayoutManager.class);
+
     private RegionReference targetRegion;
     private Block targetBlock;
     private SideRegion regionFO;
@@ -77,7 +89,96 @@
 
     /** {@inheritDoc} */
     public List getNextKnuthElements(LayoutContext context, int alignment) {
-        throw new IllegalStateException();
+        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;
+        }
     }
 
     /**

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java?rev=808135&r1=808134&r2=808135&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java Wed Aug 26 17:42:11 2009
@@ -27,7 +27,6 @@
 
 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;
@@ -44,6 +43,7 @@
 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,6 +111,8 @@
         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;
@@ -127,7 +129,8 @@
 
         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();
@@ -146,7 +149,8 @@
         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/trunk/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java?rev=808135&r1=808134&r2=808135&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java Wed Aug 26 17:42:11 2009
@@ -248,6 +248,8 @@
         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),
@@ -272,6 +274,14 @@
             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/trunk/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java?rev=808135&r1=808134&r2=808135&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java Wed Aug 26 17:42:11 2009
@@ -19,13 +19,12 @@
 
 package org.apache.fop.layoutmgr.inline;
 
-import java.util.Iterator;
 import java.util.LinkedList;
+import java.util.Iterator;
 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;
@@ -35,6 +34,8 @@
 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;
 
 /**
@@ -61,6 +62,12 @@
         }
     }
 
+
+    /**
+     * 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).
      */
@@ -71,6 +78,9 @@
     /** 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
@@ -139,6 +149,22 @@
     }
 
     /**
+     * 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
      */

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java?rev=808135&r1=808134&r2=808135&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java Wed Aug 26 17:42:11 2009
@@ -116,8 +116,8 @@
      * inline break positions.
      */
     private static class LineBreakPosition extends LeafPosition {
-        private int parIndex; // index of the Paragraph this Position refers to
-        private int startIndex; //index of the first element this Position refers to
+        private int iParIndex; // index of the Paragraph this Position refers to
+        private int iStartIndex; //index of the first element this Position refers to
         private int availableShrink;
         private int availableStretch;
         private int difference;
@@ -130,16 +130,16 @@
         private int spaceAfter;
         private int baseline;
 
-        LineBreakPosition(LayoutManager lm, int index, int startIndex, int breakIndex,
+        LineBreakPosition(LayoutManager lm, int index, int iStartIndex, int iBreakIndex,
                           int shrink, int stretch, int diff,
                           double ipdA, double adjust, int ind,
                           int lh, int lw, int sb, int sa, int bl) {
-            super(lm, breakIndex);
+            super(lm, iBreakIndex);
             availableShrink = shrink;
             availableStretch = stretch;
             difference = diff;
-            parIndex = index;
-            this.startIndex = startIndex;
+            iParIndex = index;
+            this.iStartIndex = iStartIndex;
             ipdAdjust = ipdA;
             dAdjust = adjust;
             startIndent = ind;
@@ -167,13 +167,18 @@
     private Length lineHeight;
     private int lead;
     private int follow;
-    private AlignmentContext alignmentContext;
+    private AlignmentContext alignmentContext = null;
 
-    private List knuthParagraphs;
+    private List knuthParagraphs = null;
+    private int iReturnedLBP = 0;
+
+    //     parameters of Knuth's algorithm:
+    // penalty value for flagged penalties
+    private int flaggedPenalty = 50;
 
     private LineLayoutPossibilities lineLayouts;
     private List lineLayoutsList;
-    private int ipd = 0;
+    private int iLineWidth = 0;
 
     /**
      * this constant is used to create elements when text-align is center:
@@ -233,7 +238,7 @@
             } else {
                 lineFiller = new MinOptMax(lastLineEndIndent,
                                             lastLineEndIndent,
-                                            layoutManager.ipd);
+                                            layoutManager.iLineWidth);
             }
 
             // add auxiliary elements at the beginning of the paragraph
@@ -314,9 +319,11 @@
         private int activePossibility;
         private int addedPositions;
         private int textIndent;
+        private int fillerMinWidth;
         private int lineHeight;
         private int lead;
         private int follow;
+        private int maxDiff;
         private static final double MAX_DEMERITS = 10e6;
 
         public LineBreakingAlgorithm (int pageAlign,
@@ -327,17 +334,22 @@
             super(textAlign, textAlignLast, first, false, maxFlagCount);
             pageAlignment = pageAlign;
             textIndent = indent;
+            fillerMinWidth = fillerWidth;
             lineHeight = lh;
             lead = ld;
             follow = fl;
             thisLLM = llm;
             activePossibility = -1;
+            maxDiff = fobj.getWidows() >= fobj.getOrphans()
+                    ? fobj.getWidows()
+                    : fobj.getOrphans();
         }
 
         public void updateData1(int lineCount, double demerits) {
             lineLayouts.addPossibility(lineCount, demerits);
-            if (log.isTraceEnabled()) {
-                log.trace("Layout possibility in " + lineCount + " lines; break at position:");
+            if (super.log.isTraceEnabled()) {
+                super.log.trace(
+                        "Layout possibility in " + lineCount + " lines; break at position:");
             }
         }
 
@@ -418,7 +430,7 @@
             // true if this line contains only zero-height, auxiliary boxes
             // and the actual line width is 0; in this case, the line "collapses"
             // i.e. the line area will have bpd = 0
-            boolean bZeroHeightLine = (difference == ipd);
+            boolean bZeroHeightLine = (difference == iLineWidth);
 
             // if line-stacking-strategy is "font-height", the line height
             // is not affected by its content
@@ -474,7 +486,7 @@
                                              firstElementIndex, lastElementIndex,
                                              availableShrink, availableStretch,
                                              difference, ratio, 0, indent,
-                                             0, ipd, 0, 0, 0);
+                                             0, iLineWidth, 0, 0, 0);
             } else {
                 return new LineBreakPosition(thisLLM,
                                              knuthParagraphs.indexOf(par),
@@ -482,7 +494,7 @@
                                              availableShrink, availableStretch,
                                              difference, ratio, 0, indent,
                                              lineLead + lineFollow,
-                                             ipd, spaceBefore, spaceAfter,
+                                             iLineWidth, spaceBefore, spaceAfter,
                                              lineLead);
             }
         }
@@ -566,12 +578,14 @@
         FontInfo fi = fobj.getFOEventHandler().getFontInfo();
         FontTriplet[] fontkeys = fobj.getCommonFont().getFontState(fi);
         Font fs = fi.getFontInstance(fontkeys[0], fobj.getCommonFont().fontSize.getValue(this));
-        alignmentContext = new AlignmentContext(fs, lineHeight.getValue(this),
-                context.getWritingMode());
+        alignmentContext
+          = new AlignmentContext(fs, lineHeight.getValue(this), context.getWritingMode());
         context.setAlignmentContext(alignmentContext);
         // Get a break from currently active child LM
         // Set up constraints for inline level managers
 
+        clearPrevIPD();
+
         //PHASE 1: Create Knuth elements
         if (knuthParagraphs == null) {
             // it's the first time this method is called
@@ -592,6 +606,34 @@
 
         //PHASE 2: Create line breaks
         return createLineBreaks(context.getBPAlignment(), context);
+        /*
+        LineBreakPosition lbp = null;
+        if (breakpoints == null) {
+            // find the optimal line breaking points for each paragraph
+            breakpoints = new ArrayList();
+            ListIterator paragraphsIterator
+                = knuthParagraphs.listIterator(knuthParagraphs.size());
+            Paragraph currPar = null;
+            while (paragraphsIterator.hasPrevious()) {
+                currPar = (Paragraph) paragraphsIterator.previous();
+                findBreakingPoints(currPar, context.getStackLimit().opt);
+            }
+        }*/
+
+        //PHASE 3: Return lines
+
+        /*
+        // get a break point from the list
+        lbp = (LineBreakPosition) breakpoints.get(iReturnedLBP ++);
+        if (iReturnedLBP == breakpoints.size()) {
+            setFinished(true);
+        }
+
+        BreakPoss curLineBP = new BreakPoss(lbp);
+        curLineBP.setFlag(BreakPoss.ISLAST, isFinished());
+        curLineBP.setStackingSize(new MinOptMax(lbp.lineHeight));
+        return curLineBP;
+        */
     }
 
     /**
@@ -601,20 +643,22 @@
     private void collectInlineKnuthElements(LayoutContext context) {
         LayoutContext inlineLC = new LayoutContext(context);
 
-        ipd = context.getRefIPD();
+        InlineLevelLayoutManager curLM;
+        List returnedList = null;
+        iLineWidth = context.getStackLimitIP().opt;
 
         // convert all the text in a sequence of paragraphs made
         // of KnuthBox, KnuthGlue and KnuthPenalty objects
-        boolean previousIsBox = false;
+        boolean bPrevWasKnuthBox = false;
 
         StringBuffer trace = new StringBuffer("LineLM:");
 
         Paragraph lastPar = null;
 
-        InlineLevelLayoutManager curLM;
         while ((curLM = (InlineLevelLayoutManager) getChildLM()) != null) {
-            List inlineElements = curLM.getNextKnuthElements(inlineLC, effectiveAlignment);
-            if (inlineElements == null || inlineElements.size() == 0) {
+            returnedList = curLM.getNextKnuthElements(inlineLC, effectiveAlignment);
+            if (returnedList == null
+                    || returnedList.size() == 0) {
                 /* curLM.getNextKnuthElements() returned null or an empty list;
                  * this can happen if there is nothing more to layout,
                  * so just iterate once more to see if there are other children */
@@ -622,7 +666,7 @@
             }
 
             if (lastPar != null) {
-                KnuthSequence firstSeq = (KnuthSequence) inlineElements.get(0);
+                KnuthSequence firstSeq = (KnuthSequence) returnedList.get(0);
 
                 // finish last paragraph before a new block sequence
                 if (!firstSeq.isInlineSequence()) {
@@ -632,7 +676,7 @@
                     if (log.isTraceEnabled()) {
                         trace.append(" ]");
                     }
-                    previousIsBox = false;
+                    bPrevWasKnuthBox = false;
                 }
 
                 // does the first element of the first paragraph add to an existing word?
@@ -640,24 +684,27 @@
                     KnuthElement thisElement;
                     thisElement = (KnuthElement) firstSeq.get(0);
                     if (thisElement.isBox() && !thisElement.isAuxiliary()
-                            && previousIsBox) {
+                            && bPrevWasKnuthBox) {
                         lastPar.addALetterSpace();
                     }
                 }
             }
 
             // loop over the KnuthSequences (and single KnuthElements) in returnedList
-            ListIterator iter = inlineElements.listIterator();
+            ListIterator iter = returnedList.listIterator();
             while (iter.hasNext()) {
                 KnuthSequence sequence = (KnuthSequence) iter.next();
                 // the sequence contains inline Knuth elements
                 if (sequence.isInlineSequence()) {
                     // look at the last element
                     ListElement lastElement = sequence.getLast();
-                    assert lastElement != null;
-                    previousIsBox = lastElement.isBox()
-                            && !((KnuthElement) lastElement).isAuxiliary()
-                            && ((KnuthElement) lastElement).getW() != 0;
+                    if (lastElement == null) {
+                        throw new NullPointerException(
+                        "Sequence was empty! lastElement is null");
+                    }
+                    bPrevWasKnuthBox = lastElement.isBox()
+                                        && !((KnuthElement) lastElement).isAuxiliary()
+                                        && ((KnuthElement) lastElement).getW() != 0;
 
                     // if last paragraph is open, add the new elements to the paragraph
                     // else this is the last paragraph
@@ -682,7 +729,8 @@
 
                     // finish last paragraph if it was closed with a linefeed
                     if (lastElement.isPenalty()
-                            && ((KnuthPenalty) lastElement).getP() == -KnuthPenalty.INFINITE) {
+                            && ((KnuthPenalty) lastElement).getP()
+                            == -KnuthPenalty.INFINITE) {
                         // a penalty item whose value is -inf
                         // represents a preserved linefeed,
                         // which forces a line break
@@ -690,7 +738,7 @@
                         if (!lastPar.containsBox()) {
                             //only a forced linefeed on this line
                             //-> compensate with an auxiliary glue
-                            lastPar.add(new KnuthGlue(ipd, 0, ipd, null, true));
+                            lastPar.add(new KnuthGlue(iLineWidth, 0, iLineWidth, null, true));
                         }
                         lastPar.endParagraph();
                         ElementListObserver.observe(lastPar, "line", null);
@@ -698,7 +746,7 @@
                         if (log.isTraceEnabled()) {
                             trace.append(" ]");
                         }
-                        previousIsBox = false;
+                        bPrevWasKnuthBox = false;
                     }
                 } else { // the sequence is a block sequence
                     // the positions will be wrapped with this LM in postProcessLineBreaks
@@ -720,14 +768,144 @@
     }
 
     /**
+     * Find a set of breaking points.
+     * This method is called only once by getNextBreakPoss, and it
+     * subsequently calls the other findBreakingPoints() method with
+     * different parameters, until a set of breaking points is found.
+     *
+     * @param par       the list of elements that must be parted
+     *                  into lines
+     * @param lineWidth the desired length ot the lines
+     */
+    /*
+    private void findBreakingPoints(Paragraph par, int lineWidth) {
+        // maximum adjustment ratio permitted
+        float maxAdjustment = 1;
+
+        // first try
+        if (!findBreakingPoints(par, lineWidth, maxAdjustment, false)) {
+            // the first try failed, now try something different
+            log.debug("No set of breaking points found with maxAdjustment = " + maxAdjustment);
+            if (hyphenationProperties.hyphenate == Constants.EN_TRUE) {
+                // consider every hyphenation point as a legal break
+                findHyphenationPoints(par);
+            } else {
+                // try with a higher threshold
+                maxAdjustment = 5;
+            }
+
+            if (!findBreakingPoints(par, lineWidth, maxAdjustment, false)) {
+                // the second try failed too, try with a huge threshold;
+                // if this fails too, use a different algorithm
+                log.debug("No set of breaking points found with maxAdjustment = " + maxAdjustment
+                          + (hyphenationProperties.hyphenate == Constants.EN_TRUE ? " and hyphenation" : ""));
+                maxAdjustment = 20;
+                if (!findBreakingPoints(par, lineWidth, maxAdjustment, true)) {
+                    log.debug("No set of breaking points found, using first-fit algorithm");
+                }
+            }
+        }
+    }
+
+    private boolean findBreakingPoints(Paragraph par, int lineWidth,
+            double threshold, boolean force) {
+        KnuthParagraph knuthPara = new KnuthParagraph(par);
+        int lines = knuthPara.findBreakPoints(lineWidth, threshold, force);
+        if (lines == 0) {
+            return false;
+        }
+
+        for (int i = lines-1; i >= 0; i--) {
+            int line = i+1;
+            if (log.isTraceEnabled()) {
+                log.trace("Making line from " + knuthPara.getStart(i) + " to " +
+                           knuthPara.getEnd(i));
+            }
+            // compute indent and adjustment ratio, according to
+            // the value of text-align and text-align-last
+
+            int difference = knuthPara.getDifference(i);
+            if (line == lines) {
+                difference += par.lineFillerWidth;
+            }
+            int textAlign = (line < lines)
+                ? textAlignment : textAlignmentLast;
+            int indent = (textAlign == EN_CENTER)
+                ? difference / 2
+                : (textAlign == EN_END) ? difference : 0;
+            indent += (line == 1 && knuthParagraphs.indexOf(par) == 0)
+                ? textIndent.getValue(this) : 0;
+            double ratio = (textAlign == EN_JUSTIFY)
+                ? knuthPara.getAdjustRatio(i) : 0;
+
+            int start = knuthPara.getStart(i);
+            int end = knuthPara.getEnd(i);
+            makeLineBreakPosition(par, start, end, 0, ratio, indent);
+        }
+        return true;
+    }
+
+    private void makeLineBreakPosition(Paragraph par,
+                                       int firstElementIndex, int lastElementIndex,
+                                       int insertIndex, double ratio, int indent) {
+        // line height calculation
+
+        int halfLeading = (lineHeight - lead - follow) / 2;
+        // height above the main baseline
+        int lineLead = lead + halfLeading;
+        // maximum size of top and bottom alignment
+        int lineFollow = follow + halfLeading;
+
+        ListIterator inlineIterator
+            = par.listIterator(firstElementIndex);
+        for (int j = firstElementIndex;
+             j <= lastElementIndex;
+             j++) {
+            KnuthElement element = (KnuthElement) inlineIterator.next();
+            if (element.isBox()) {
+                KnuthInlineBox box = (KnuthInlineBox)element;
+                if (box.getLead() > lineLead) {
+                    lineLead = box.getLead();
+                }
+                if (box.getTotal() > lineFollow) {
+                    lineFollow = box.getTotal();
+                }
+                if (box.getMiddle() > lineLead + middleShift) {
+                    lineLead += box.getMiddle()
+                                - lineLead - middleShift;
+                }
+                if (box.getMiddle() > middlefollow - middleShift) {
+                    middlefollow += box.getMiddle()
+                                    - middlefollow + middleShift;
+                }
+            }
+        }
+
+        if (lineFollow - lineLead > middlefollow) {
+                    middlefollow = lineFollow - lineLead;
+        }
+
+        breakpoints.add(insertIndex,
+                        new LineBreakPosition(this,
+                                              knuthParagraphs.indexOf(par),
+                                              lastElementIndex ,
+                                              ratio, 0, indent,
+                                              lineLead + middlefollow,
+                                              lineLead));
+    }*/
+
+
+    /**
      * Phase 2 of Knuth algorithm: find optimal break points.
      * @param alignment alignment in BP direction of the paragraph
      * @param context the layout context
      * @return a list of Knuth elements representing broken lines
      */
     private List createLineBreaks(int alignment, LayoutContext context) {
+
         // find the optimal line breaking points for each paragraph
-        ListIterator paragraphsIterator = knuthParagraphs.listIterator(knuthParagraphs.size());
+        ListIterator paragraphsIterator
+            = knuthParagraphs.listIterator(knuthParagraphs.size());
         lineLayoutsList = new ArrayList(knuthParagraphs.size());
         LineLayoutPossibilities llPoss;
         while (paragraphsIterator.hasPrevious()) {
@@ -780,7 +958,7 @@
         } else {
             allowedBreaks = BreakingAlgorithm.NO_FLAGGED_PENALTIES;
         }
-        alg.setConstantLineWidth(ipd);
+        alg.setConstantLineWidth(iLineWidth);
         iBPcount = alg.findBreakingPoints(currPar,
                                           maxAdjustment, false, allowedBreaks);
         if (iBPcount == 0 || alignment == EN_JUSTIFY) {
@@ -836,26 +1014,26 @@
                     alg.resetAlgorithm();
                     lineLayouts.savePossibilities(true);
                     // try with shorter lines
-                    int savedLineWidth = ipd;
-                    ipd = (int) (ipd * 0.95);
+                    int savedLineWidth = iLineWidth;
+                    iLineWidth = (int) (iLineWidth * 0.95);
                     iBPcount = alg.findBreakingPoints(currPar,
-                            maxAdjustment, true, allowedBreaks);
+                             maxAdjustment, true, allowedBreaks);
                     // use normal lines, when possible
                     lineLayouts.restorePossibilities();
-                    ipd = savedLineWidth;
+                    iLineWidth = savedLineWidth;
                 }
                 if (!lineLayouts.canUseLessLines()) {
                     alg.resetAlgorithm();
                     lineLayouts.savePossibilities(true);
                     // try with longer lines
-                    int savedLineWidth = ipd;
-                    ipd = (int) (ipd * 1.05);
-                    alg.setConstantLineWidth(ipd);
+                    int savedLineWidth = iLineWidth;
+                    iLineWidth = (int) (iLineWidth * 1.05);
+                    alg.setConstantLineWidth(iLineWidth);
                     iBPcount = alg.findBreakingPoints(currPar,
                             maxAdjustment, true, allowedBreaks);
                     // use normal lines, when possible
                     lineLayouts.restorePossibilities();
-                    ipd = savedLineWidth;
+                    iLineWidth = savedLineWidth;
                 }
                 //log.debug("LLM.getNextKnuthElements> now, layouts with more lines? " + lineLayouts.canUseMoreLines());
                 //log.debug("                          now, layouts with fewer lines? " + lineLayouts.canUseLessLines());
@@ -937,14 +1115,15 @@
                     while (elementIterator.nextIndex() <= endIndex) {
                         KnuthElement element = (KnuthElement) elementIterator.next();
                         if (element instanceof KnuthInlineBox
-                                && ((KnuthInlineBox) element).isAnchor()) {
+                            && ((KnuthInlineBox) element).isAnchor()) {
                             footnoteList.add(((KnuthInlineBox) element).getFootnoteBodyLM());
                         } else if (element instanceof KnuthBlockBox) {
                             footnoteList.addAll(((KnuthBlockBox) element).getFootnoteBodyLMs());
                         }
                     }
                     startIndex = endIndex + 1;
-                    LineBreakPosition lbp = (LineBreakPosition) llPoss.getChosenPosition(i);
+                    LineBreakPosition lbp
+                      = (LineBreakPosition) llPoss.getChosenPosition(i);
                     returnList.add(new KnuthBlockBox
                                    (lbp.lineHeight + lbp.spaceBefore + lbp.spaceAfter,
                                     footnoteList, lbp, false));
@@ -1418,7 +1597,7 @@
             Position pos = (Position) parentIter.next();
             boolean isLastPosition = !parentIter.hasNext();
             if (pos instanceof LineBreakPosition) {
-                addInlineArea(context, (LineBreakPosition) pos, isLastPosition);
+                addInlineArea(context, pos, isLastPosition);
             } else if ((pos instanceof NonLeafPosition) && pos.generatesAreas()) {
                 addBlockArea(context, pos, isLastPosition);
             } else {
@@ -1438,129 +1617,147 @@
      * @param pos the position for which the line is generated
      * @param isLastPosition true if this is the last position of this LM
      */
-    private void addInlineArea(LayoutContext context, LineBreakPosition lbp,
-            boolean isLastPosition) {
-        // the TLM which created the last KnuthElement in this line
-        LayoutManager lastLM = null;
-
-        KnuthSequence seq = (KnuthSequence) knuthParagraphs.get(lbp.parIndex);
-        int startElementIndex = lbp.startIndex;
-        int endElementIndex = lbp.getLeafPos();
-
-        LineArea lineArea = new LineArea(
-                (lbp.getLeafPos() < seq.size() - 1 ? textAlignment : textAlignmentLast),
-                lbp.difference, lbp.availableStretch, lbp.availableShrink);
-        if (lbp.startIndent != 0) {
-            lineArea.addTrait(Trait.START_INDENT, new Integer(lbp.startIndent));
-        }
-        lineArea.setBPD(lbp.lineHeight);
-        lineArea.setIPD(lbp.lineWidth);
-        lineArea.addTrait(Trait.SPACE_BEFORE, new Integer(lbp.spaceBefore));
-        lineArea.addTrait(Trait.SPACE_AFTER, new Integer(lbp.spaceAfter));
-        alignmentContext.resizeLine(lbp.lineHeight, lbp.baseline);
-
-        if (seq instanceof Paragraph) {
-            Paragraph currPar = (Paragraph) seq;
-            // ignore the first elements added by the LineLayoutManager
-            startElementIndex += (startElementIndex == 0) ? currPar.ignoreAtStart : 0;
-
-            // if this is the last line area that for this paragraph,
-            // ignore the last elements added by the LineLayoutManager and
-            // subtract the last-line-end-indent from the area ipd
-            if (endElementIndex == (currPar.size() - 1)) {
-                endElementIndex -= currPar.ignoreAtEnd;
-                lineArea.setIPD(lineArea.getIPD() - lastLineEndIndent.getValue(this));
+    private void addInlineArea(LayoutContext context, Position pos, boolean isLastPosition) {
+            ListIterator seqIterator = null;
+            KnuthElement tempElement = null;
+            // the TLM which created the last KnuthElement in this line
+            LayoutManager lastLM = null;
+
+            LineBreakPosition lbp = (LineBreakPosition) pos;
+            int iCurrParIndex;
+            iCurrParIndex = lbp.iParIndex;
+            KnuthSequence seq = (KnuthSequence) knuthParagraphs.get(iCurrParIndex);
+            int iStartElement = lbp.iStartIndex;
+            int iEndElement = lbp.getLeafPos();
+
+            LineArea lineArea
+              = new LineArea((lbp.getLeafPos() < seq.size() - 1
+                              ? textAlignment : textAlignmentLast),
+                              lbp.difference, lbp.availableStretch, lbp.availableShrink);
+            if (lbp.startIndent != 0) {
+                lineArea.addTrait(Trait.START_INDENT, new Integer(lbp.startIndent));
+            }
+            lineArea.setBPD(lbp.lineHeight);
+            lineArea.setIPD(lbp.lineWidth);
+            lineArea.addTrait(Trait.SPACE_BEFORE, new Integer(lbp.spaceBefore));
+            lineArea.addTrait(Trait.SPACE_AFTER, new Integer(lbp.spaceAfter));
+            alignmentContext.resizeLine(lbp.lineHeight, lbp.baseline);
+
+            if (seq instanceof Paragraph) {
+                Paragraph currPar = (Paragraph) seq;
+                // ignore the first elements added by the LineLayoutManager
+                iStartElement += (iStartElement == 0) ? currPar.ignoreAtStart : 0;
+
+                // if this is the last line area that for this paragraph,
+                // ignore the last elements added by the LineLayoutManager and
+                // subtract the last-line-end-indent from the area ipd
+                if (iEndElement == (currPar.size() - 1)) {
+                    iEndElement -= currPar.ignoreAtEnd;
+                    lineArea.setIPD(lineArea.getIPD() - lastLineEndIndent.getValue(this));
+                }
             }
-        }
 
-        // Remove trailing spaces if allowed so
-        if (whiteSpaceTreament == EN_IGNORE_IF_SURROUNDING_LINEFEED
+            // Remove trailing spaces if allowed so
+            if (whiteSpaceTreament == EN_IGNORE_IF_SURROUNDING_LINEFEED
                 || whiteSpaceTreament == EN_IGNORE
                 || whiteSpaceTreament == EN_IGNORE_IF_BEFORE_LINEFEED) {
-            // ignore the last element in the line if it is a KnuthGlue object
-            ListIterator seqIterator = seq.listIterator(endElementIndex);
-            KnuthElement lastElement = (KnuthElement) seqIterator.next();
-            lastLM = lastElement.getLayoutManager();
-            if (lastElement.isGlue()) {
-                endElementIndex--;
-                // this returns the same KnuthElement
-                seqIterator.previous();
-                if (seqIterator.hasPrevious()) {
-                    lastLM = ((KnuthElement) seqIterator.previous()).getLayoutManager();
+                // ignore the last element in the line if it is a KnuthGlue object
+                seqIterator = seq.listIterator(iEndElement);
+                tempElement = (KnuthElement) seqIterator.next();
+                if (tempElement.isGlue()) {
+                    iEndElement--;
+                    // this returns the same KnuthElement
+                    seqIterator.previous();
+                    if (seqIterator.hasPrevious()) {
+                        tempElement = (KnuthElement) seqIterator.previous();
+                    } else {
+                        tempElement = null;
+                    }
+                }
+                if (tempElement != null) {
+                    lastLM = tempElement.getLayoutManager();
                 }
             }
-        }
 
-        // Remove leading spaces if allowed so
-        if (whiteSpaceTreament == EN_IGNORE_IF_SURROUNDING_LINEFEED
+            // Remove leading spaces if allowed so
+            if (whiteSpaceTreament == EN_IGNORE_IF_SURROUNDING_LINEFEED
                 || whiteSpaceTreament == EN_IGNORE
                 || whiteSpaceTreament == EN_IGNORE_IF_AFTER_LINEFEED) {
-            // ignore KnuthGlue and KnuthPenalty objects
-            // at the beginning of the line
-            ListIterator seqIterator = seq.listIterator(startElementIndex);
-            while (seqIterator.hasNext() && !((KnuthElement) seqIterator.next()).isBox()) {
-                startElementIndex++;
-            }
-        }
-        // Add the inline areas to lineArea
-        PositionIterator inlinePosIter = new KnuthPossPosIter(seq, startElementIndex,
-                endElementIndex + 1);
-
-        LayoutContext lc = new LayoutContext(0);
-        lc.setAlignmentContext(alignmentContext);
-        lc.setSpaceAdjust(lbp.dAdjust);
-        lc.setIPDAdjust(lbp.ipdAdjust);
-        lc.setLeadingSpace(new SpaceSpecifier(true));
-        lc.setTrailingSpace(new SpaceSpecifier(false));
-        lc.setFlags(LayoutContext.RESOLVE_LEADING_SPACE, true);
-
-        /*
-         * extension (not in the XSL FO recommendation): if the left and right margins
-         * have been optimized, recompute indents and / or adjust ratio, according
-         * to the paragraph horizontal alignment
-         */
-        if (false && textAlignment == EN_JUSTIFY) {
-            // re-compute space adjust ratio
-            int updatedDifference = context.getRefIPD()
-            - lbp.lineWidth + lbp.difference;
-            double updatedRatio = 0.0;
-            if (updatedDifference > 0) {
-                updatedRatio = (float) updatedDifference / lbp.availableStretch;
-            } else if (updatedDifference < 0) {
-                updatedRatio = (float) updatedDifference / lbp.availableShrink;
-            }
-            lc.setIPDAdjust(updatedRatio);
-            //log.debug("LLM.addAreas> old difference = " + lbp.difference + " new difference = " + updatedDifference);
-            //log.debug("              old ratio = " + lbp.ipdAdjust + " new ratio = " + updatedRatio);
-        } else if (false && textAlignment == EN_CENTER) {
-            // re-compute indent
-            int updatedIndent = lbp.startIndent
-            + (context.getRefIPD() - lbp.lineWidth) / 2;
-            lineArea.addTrait(Trait.START_INDENT, new Integer(updatedIndent));
-        } else if (false && textAlignment == EN_END) {
-            // re-compute indent
-            int updatedIndent = lbp.startIndent
-            + (context.getRefIPD() - lbp.lineWidth);
-            lineArea.addTrait(Trait.START_INDENT, new Integer(updatedIndent));
-        }
-
-        setCurrentArea(lineArea);
-        setChildContext(lc);
-        LayoutManager childLM;
-        while ((childLM = inlinePosIter.getNextChildLM()) != null) {
-            lc.setFlags(LayoutContext.LAST_AREA, (childLM == lastLM));
-            childLM.addAreas(inlinePosIter, lc);
-            lc.setLeadingSpace(lc.getTrailingSpace());
+                // ignore KnuthGlue and KnuthPenalty objects
+                // at the beginning of the line
+                seqIterator = seq.listIterator(iStartElement);
+                tempElement = (KnuthElement) seqIterator.next();
+                while (!tempElement.isBox() && seqIterator.hasNext()) {
+                    tempElement = (KnuthElement) seqIterator.next();
+                    iStartElement++;
+                }
+            }
+            // Add the inline areas to lineArea
+            PositionIterator inlinePosIter
+              = new KnuthPossPosIter(seq, iStartElement, iEndElement + 1);
+
+            iStartElement = lbp.getLeafPos() + 1;
+            if (iStartElement == seq.size()) {
+                // advance to next paragraph
+                iStartElement = 0;
+            }
+
+            LayoutContext lc = new LayoutContext(0);
+            lc.setAlignmentContext(alignmentContext);
+            lc.setSpaceAdjust(lbp.dAdjust);
+            lc.setIPDAdjust(lbp.ipdAdjust);
+            lc.setLeadingSpace(new SpaceSpecifier(true));
             lc.setTrailingSpace(new SpaceSpecifier(false));
-        }
+            lc.setFlags(LayoutContext.RESOLVE_LEADING_SPACE, true);
 
-        // if display-align is distribute, add space after
-        if (context.getSpaceAfter() > 0
-                && (!context.isLastArea() || !isLastPosition)) {
-            lineArea.setBPD(lineArea.getBPD() + context.getSpaceAfter());
-        }
-        lineArea.finalise();
-        parentLM.addChildArea(lineArea);
+            /*
+             * extension (not in the XSL FO recommendation): if the left and right margins
+             * have been optimized, recompute indents and / or adjust ratio, according
+             * to the paragraph horizontal alignment
+             */
+            if (false && textAlignment == EN_JUSTIFY) {
+                // re-compute space adjust ratio
+                int updatedDifference = context.getStackLimitIP().opt
+                                        - lbp.lineWidth + lbp.difference;
+                double updatedRatio = 0.0;
+                if (updatedDifference > 0) {
+                    updatedRatio = (float) updatedDifference / lbp.availableStretch;
+                } else if (updatedDifference < 0) {
+                    updatedRatio = (float) updatedDifference / lbp.availableShrink;
+                }
+                lc.setIPDAdjust(updatedRatio);
+                //log.debug("LLM.addAreas> old difference = " + lbp.difference + " new difference = " + updatedDifference);
+                //log.debug("              old ratio = " + lbp.ipdAdjust + " new ratio = " + updatedRatio);
+            } else if (false && textAlignment == EN_CENTER) {
+                // re-compute indent
+                int updatedIndent = lbp.startIndent
+                                    + (context.getStackLimitIP().opt - lbp.lineWidth) / 2;
+                lineArea.addTrait(Trait.START_INDENT, new Integer(updatedIndent));
+            } else if (false && textAlignment == EN_END) {
+                // re-compute indent
+                int updatedIndent = lbp.startIndent
+                                    + (context.getStackLimitIP().opt - lbp.lineWidth);
+                lineArea.addTrait(Trait.START_INDENT, new Integer(updatedIndent));
+            }
+
+            setCurrentArea(lineArea);
+            setChildContext(lc);
+            LayoutManager childLM;
+            while ((childLM = inlinePosIter.getNextChildLM()) != null) {
+                lc.setFlags(LayoutContext.LAST_AREA, (childLM == lastLM));
+                childLM.addAreas(inlinePosIter, lc);
+                lc.setLeadingSpace(lc.getTrailingSpace());
+                lc.setTrailingSpace(new SpaceSpecifier(false));
+            }
+
+            // when can this be null?
+            // if display-align is distribute, add space after
+            if (context.getSpaceAfter() > 0
+                    && (!context.isLastArea() || !isLastPosition)) {
+                lineArea.setBPD(lineArea.getBPD() + context.getSpaceAfter());
+            }
+            lineArea.finalise();
+            parentLM.addChildArea(lineArea);
     }
 
     /**
@@ -1603,7 +1800,7 @@
             // set last area flag
             blocklc.setFlags(LayoutContext.LAST_AREA,
                              (context.isLastArea() && childLM == lastLM));
-            blocklc.setStackLimitBP(context.getStackLimitBP());
+            blocklc.setStackLimitsFrom(context);
             // Add the line areas to Area
             childLM.addAreas(childPosIter, blocklc);
             blocklc.setLeadingSpace(blocklc.getTrailingSpace());



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


Re: svn commit: r808135 - in /xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr: ./ inline/

Posted by Vincent Hennebert <vh...@gmail.com>.
> Author: vhennebert
> Date: Wed Aug 26 17:42:11 2009
> New Revision: 808135
> 
> URL: http://svn.apache.org/viewvc?rev=808135&view=rev
> Log:
> Reverted changes made in revision 796809 (manual merge of clean-up changes made in the ChangingIPDHack branch). Those changes will be re-applied when merging the branch back to Trunk with svn merge --reintegrate (if everything goes well...)

And of course not everything went well. svn merge --reintegrate failed
for obscure reasons of subtree mergeinfo, explained in more details on
the following page:
http://blogs.open.collab.net/svn/2008/07/subversion-merg.html

I ended up doing the merge ‘by hand’ using the 2-URL merge syntax
mentioned in the document above. Hopefully everything went well. I think
the svn:mergeinfo properties should be cleared from most of the files in
the repository. Attention also needs to be paid when moving/copying
files. According to the document above the svn:mergeinfo property
created in such a case is most of times unnecessary.


Vincent