Author: lbernardo
Date: Tue Dec  2 00:29:57 2014
New Revision: 1642793

URL: http://svn.apache.org/r1642793
Log:
Merged branches/Temp_BasicSideFloat back to trunk.

Added:
    xmlgraphics/fop/trunk/src/java/org/apache/fop/area/SideFloat.java
      - copied unchanged from r1642790, 
xmlgraphics/fop/branches/Temp_BasicSideFloats/src/java/org/apache/fop/area/SideFloat.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/FloatContentLayoutManager.java
      - copied unchanged from r1642790, 
xmlgraphics/fop/branches/Temp_BasicSideFloats/src/java/org/apache/fop/layoutmgr/FloatContentLayoutManager.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/FloatLayoutManager.java
      - copied unchanged from r1642790, 
xmlgraphics/fop/branches/Temp_BasicSideFloats/src/java/org/apache/fop/layoutmgr/inline/FloatLayoutManager.java
    xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/float_1.xml
      - copied unchanged from r1642790, 
xmlgraphics/fop/branches/Temp_BasicSideFloats/test/layoutengine/standard-testcases/float_1.xml
    xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/float_2.xml
      - copied unchanged from r1642790, 
xmlgraphics/fop/branches/Temp_BasicSideFloats/test/layoutengine/standard-testcases/float_2.xml
    xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/float_3.xml
      - copied unchanged from r1642790, 
xmlgraphics/fop/branches/Temp_BasicSideFloats/test/layoutengine/standard-testcases/float_3.xml
    xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/float_4.xml
      - copied unchanged from r1642790, 
xmlgraphics/fop/branches/Temp_BasicSideFloats/test/layoutengine/standard-testcases/float_4.xml
    xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/float_5.xml
      - copied unchanged from r1642790, 
xmlgraphics/fop/branches/Temp_BasicSideFloats/test/layoutengine/standard-testcases/float_5.xml
    xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/float_6.xml
      - copied unchanged from r1642790, 
xmlgraphics/fop/branches/Temp_BasicSideFloats/test/layoutengine/standard-testcases/float_6.xml
    xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/float_7.xml
      - copied unchanged from r1642790, 
xmlgraphics/fop/branches/Temp_BasicSideFloats/test/layoutengine/standard-testcases/float_7.xml
    
xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/flow_changing-ipd_5.xml
      - copied unchanged from r1642790, 
xmlgraphics/fop/branches/Temp_BasicSideFloats/test/layoutengine/standard-testcases/flow_changing-ipd_5.xml
Modified:
    xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Area.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Block.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/area/BlockParent.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/area/BlockViewport.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/area/LineArea.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineViewport.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/TextArea.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/XMLWhiteSpaceHandler.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/Float.java
    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/BreakingAlgorithm.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/KnuthBlockBox.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageBreaker.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/SpaceResolver.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/KnuthInlineBox.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
    
xmlgraphics/fop/trunk/test/java/org/apache/fop/layoutengine/LayoutEngineTestCase.java
    
xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/flow_changing-ipd_4.xml

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Area.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Area.java?rev=1642793&r1=1642792&r2=1642793&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Area.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Area.java Tue Dec  2 
00:29:57 2014
@@ -111,6 +111,8 @@ public class Area extends AreaTreeObject
     /** the area's block-progression-dimension */
     protected int bpd;
 
+    protected int effectiveIPD = -1;
+
     /**
      * Resolved bidirectional level for area.
      */
@@ -208,6 +210,10 @@ public class Area extends AreaTreeObject
         return getBorderAndPaddingWidthStart() + getIPD() + 
getBorderAndPaddingWidthEnd();
     }
 
+    public int getEffectiveAllocIPD() {
+        return getBorderAndPaddingWidthStart() + getEffectiveIPD() + 
getBorderAndPaddingWidthEnd();
+    }
+
     /**
      * Get the allocation block progression dimension of this area.
      * This adds the content, borders, padding and spaces to find the
@@ -499,4 +505,14 @@ public class Area extends AreaTreeObject
         sb.append("}");
         return sb.toString();
     }
+
+    public int getEffectiveIPD() {
+        return 0;
+    }
+
+    public void activateEffectiveIPD() {
+        if (effectiveIPD != -1) {
+            ipd = effectiveIPD;
+        }
+    }
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Block.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Block.java?rev=1642793&r1=1642792&r2=1642793&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Block.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/Block.java Tue Dec  2 
00:29:57 2014
@@ -184,5 +184,21 @@ public class Block extends BlockParent {
         return location;
     }
 
+    // maybe this can be done in the parent?
+    public int getEffectiveIPD() {
+        int eIPD = super.getEffectiveIPD();
+        if (eIPD != 0) {
+            effectiveIPD = eIPD;
+        }
+        return eIPD;
+    }
+
+    // maybe this can be done in the parent?
+    public void activateEffectiveIPD() {
+        super.activateEffectiveIPD();
+        if (effectiveIPD != -1) {
+            ipd = effectiveIPD;
+        }
+    }
 }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/BlockParent.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/BlockParent.java?rev=1642793&r1=1642792&r2=1642793&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/BlockParent.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/BlockParent.java Tue Dec 
 2 00:29:57 2014
@@ -123,4 +123,25 @@ public class BlockParent extends Area {
     public int getYOffset() {
         return yOffset;
     }
+
+    public int getEffectiveIPD() {
+        int maxIPD = 0;
+        if (children != null) {
+            for (Area area : children) {
+                int effectiveIPD = area.getEffectiveIPD();
+                if (effectiveIPD > maxIPD) {
+                    maxIPD = effectiveIPD;
+                }
+            }
+        }
+        return maxIPD;
+    }
+
+    public void activateEffectiveIPD() {
+        if (children != null) {
+            for (Area area : children) {
+                area.activateEffectiveIPD();
+            }
+        }
+    }
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/BlockViewport.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/BlockViewport.java?rev=1642793&r1=1642792&r2=1642793&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/BlockViewport.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/BlockViewport.java Tue 
Dec  2 00:29:57 2014
@@ -93,5 +93,9 @@ public class BlockViewport extends Block
             return null;
         }
     }
+
+    public int getEffectiveIPD() {
+        return getIPD();
+    }
 }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/area/LineArea.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/LineArea.java?rev=1642793&r1=1642792&r2=1642793&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/LineArea.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/LineArea.java Tue Dec  2 
00:29:57 2014
@@ -283,5 +283,19 @@ public class LineArea extends Area {
             // been handled, modifying the line indent
         }
     }
+
+    public int getEffectiveIPD() {
+        int maxIPD = 0;
+        if (inlineAreas != null) {
+            for (Area area : inlineAreas) {
+                int effectiveIPD = area.getEffectiveIPD();
+                if (effectiveIPD > maxIPD) {
+                    maxIPD = effectiveIPD;
+                }
+            }
+        }
+        return maxIPD;
+    }
+
 }
 

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineViewport.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineViewport.java?rev=1642793&r1=1642792&r2=1642793&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineViewport.java 
(original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/InlineViewport.java 
Tue Dec  2 00:29:57 2014
@@ -149,4 +149,7 @@ public class InlineViewport extends Inli
         this.content = (Area) in.readObject();
     }
 
+    public int getEffectiveIPD() {
+        return getIPD();
+    }
 }

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/TextArea.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/TextArea.java?rev=1642793&r1=1642792&r2=1642793&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/TextArea.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/area/inline/TextArea.java Tue 
Dec  2 00:29:57 2014
@@ -209,5 +209,8 @@ public class TextArea extends AbstractTe
         }
     }
 
+    public int getEffectiveIPD() {
+        return getIPD();
+    }
 }
 

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/XMLWhiteSpaceHandler.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/XMLWhiteSpaceHandler.java?rev=1642793&r1=1642792&r2=1642793&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/XMLWhiteSpaceHandler.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/XMLWhiteSpaceHandler.java 
Tue Dec  2 00:29:57 2014
@@ -23,6 +23,7 @@ import java.util.List;
 import java.util.Stack;
 
 import org.apache.fop.fo.flow.Block;
+import org.apache.fop.fo.flow.Float;
 import org.apache.fop.util.CharUtilities;
 
 /**
@@ -157,6 +158,10 @@ public class XMLWhiteSpaceHandler {
 
         charIter = new RecursiveCharIterator(fo, firstTextNode);
         inWhiteSpace = false;
+        if (firstTextNode.siblings != null && firstTextNode.siblings[0] != null
+                && firstTextNode.siblings[0].getNameId() == 
Constants.FO_FLOAT) {
+            inWhiteSpace = ((Float) 
firstTextNode.siblings[0]).getInWhiteSpace();
+        }
 
         if (fo == currentBlock
                 || currentBlock == null
@@ -232,6 +237,9 @@ public class XMLWhiteSpaceHandler {
                 firstWhiteSpaceInSeq = null;
             }
         }
+        if (nextChild instanceof Float) {
+            ((Float) nextChild).setInWhiteSpace(inWhiteSpace);
+        }
     }
 
     /**

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/Float.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/Float.java?rev=1642793&r1=1642792&r2=1642793&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/Float.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fo/flow/Float.java Tue Dec  2 
00:29:57 2014
@@ -20,6 +20,7 @@
 package org.apache.fop.fo.flow;
 
 // XML
+import org.xml.sax.Attributes;
 import org.xml.sax.Locator;
 
 import org.apache.fop.apps.FOPException;
@@ -34,11 +35,11 @@ import org.apache.fop.fo.ValidationExcep
  */
 public class Float extends FObj {
     // The value of properties relevant for fo:float (commented out for 
performance.
-    //     private int float_;
-    //     private int clear;
+    private int foFloat;
+    private int clear;
     // End of property values
-
-    private static boolean notImplementedWarningGiven;
+    private boolean inWhiteSpace;
+    private boolean disabled;
 
     /**
      * Base constructor
@@ -47,17 +48,13 @@ public class Float extends FObj {
      */
     public Float(FONode parent) {
         super(parent);
-
-        if (!notImplementedWarningGiven) {
-            getFOValidationEventProducer().unimplementedFeature(this, 
getName(),
-                    getName(), getLocator());
-            notImplementedWarningGiven = true;
-        }
     }
 
     /** {@inheritDoc} */
     public void bind(PropertyList pList) throws FOPException {
-        // No active properties -> Nothing to do.
+        super.bind(pList);
+        foFloat = pList.get(PR_FLOAT).getEnum();
+        clear = pList.get(PR_CLEAR).getEnum();
     }
 
     /**
@@ -92,4 +89,30 @@ public class Float extends FObj {
     public int getNameId() {
         return FO_FLOAT;
     }
+
+    public int getFloat() {
+        return foFloat;
+    }
+
+    public void setInWhiteSpace(boolean iws) {
+        inWhiteSpace = iws;
+    }
+
+    public boolean getInWhiteSpace() {
+        return inWhiteSpace;
+    }
+
+    public void processNode(String elementName, Locator locator, Attributes 
attlist, PropertyList pList)
+            throws FOPException {
+        if (findAncestor(FO_TABLE) > 0) {
+            disabled = true;
+            getFOValidationEventProducer().unimplementedFeature(this, 
"fo:table", getName(), getLocator());
+        } else {
+            super.processNode(elementName, locator, attlist, pList);
+        }
+    }
+
+    public boolean isDisabled() {
+        return disabled;
+    }
 }

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=1642793&r1=1642792&r2=1642793&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 
Tue Dec  2 00:29:57 2014
@@ -67,6 +67,17 @@ public abstract class AbstractBreaker {
         }
     }
 
+    public static class FloatPosition extends LeafPosition {
+        double bpdAdjust; // Percentage to adjust (stretch or shrink)
+        int difference;
+
+        FloatPosition(LayoutManager lm, int breakIndex, double bpdA, int diff) 
{
+            super(lm, breakIndex);
+            bpdAdjust = bpdA;
+            difference = diff;
+        }
+    }
+
     /**
      * Helper method, mainly used to improve debug/trace output
      * @param breakClassId  the {@link Constants} enum value.
@@ -195,9 +206,12 @@ public abstract class AbstractBreaker {
     }
 
     // used by doLayout and getNextBlockList*
-    private List<BlockSequence> blockLists;
+    protected List<BlockSequence> blockLists;
 
     private boolean empty = true;
+    /** blockListIndex of the current BlockSequence in blockLists */
+    protected int blockListIndex;
+
 
     /** desired text alignment */
     protected int alignment;
@@ -372,7 +386,7 @@ public abstract class AbstractBreaker {
 
             //*** Phases 2 and 3 ***
             log.debug("PLM> blockLists.size() = " + blockLists.size());
-            for (int blockListIndex = 0; blockListIndex < blockLists.size(); 
blockListIndex++) {
+            for (blockListIndex = 0; blockListIndex < blockLists.size(); 
blockListIndex++) {
                 blockList = blockLists.get(blockListIndex);
 
                 //debug code start
@@ -394,7 +408,10 @@ public abstract class AbstractBreaker {
                 alg.setConstantLineWidth(flowBPD);
                 int optimalPageCount = alg.findBreakingPoints(blockList, 1, 
true,
                         BreakingAlgorithm.ALL_BREAKS);
-                if (Math.abs(alg.getIPDdifference()) > 1) {
+
+                if (alg.handlingFloat()) {
+                    nextSequenceStartsOn = handleFloatLayout(alg, 
optimalPageCount, blockList, childLC);
+                } else if (Math.abs(alg.getIPDdifference()) > 1) {
                     addAreas(alg, optimalPageCount, blockList, blockList);
                     // *** redo Phase 1 ***
                     log.trace("IPD changes after page " + optimalPageCount);
@@ -476,14 +493,14 @@ public abstract class AbstractBreaker {
         for (int p = startPart; p < startPart + partCount; p++) {
             PageBreakPosition pbp = alg.getPageBreaks().get(p);
 
-            //Check the last break position for forced breaks
+            // Check the last break position for forced breaks
             int lastBreakClass;
             if (p == 0) {
                 lastBreakClass = effectiveList.getStartOn();
             } else {
                 ListElement lastBreakElement = 
effectiveList.getElement(endElementIndex);
                 if (lastBreakElement.isPenalty()) {
-                    KnuthPenalty pen = (KnuthPenalty)lastBreakElement;
+                    KnuthPenalty pen = (KnuthPenalty) lastBreakElement;
                     if (pen.getPenalty() == KnuthPenalty.INFINITE) {
                         /**
                          * That means that there was a 
keep.within-page="always", but that
@@ -500,14 +517,12 @@ public abstract class AbstractBreaker {
                 }
             }
 
-            //the end of the new part
+            // the end of the new part
             endElementIndex = pbp.getLeafPos();
 
             // ignore the first elements added by the
             // PageSequenceLayoutManager
-            startElementIndex += (startElementIndex == 0)
-                    ? effectiveList.ignoreAtStart
-                    : 0;
+            startElementIndex += (startElementIndex == 0) ? 
effectiveList.ignoreAtStart : 0;
 
             log.debug("PLM> part: " + (p + 1)
                     + ", start at pos " + startElementIndex
@@ -518,20 +533,17 @@ public abstract class AbstractBreaker {
 
             int displayAlign = getCurrentDisplayAlign();
 
-            //The following is needed by 
SpaceResolver.performConditionalsNotification()
-            //further down as there may be important Position elements in the 
element list trailer
+            // The following is needed by 
SpaceResolver.performConditionalsNotification()
+            // further down as there may be important Position elements in the 
element list trailer
             int notificationEndElementIndex = endElementIndex;
 
             // ignore the last elements added by the
             // PageSequenceLayoutManager
-            endElementIndex -= (endElementIndex == (originalList.size() - 1))
-                    ? effectiveList.ignoreAtEnd
-                    : 0;
+            endElementIndex -= (endElementIndex == (originalList.size() - 1)) 
? effectiveList.ignoreAtEnd : 0;
 
             // ignore the last element in the page if it is a KnuthGlue
             // object
-            if (((KnuthElement) effectiveList.get(endElementIndex))
-                    .isGlue()) {
+            if (((KnuthElement) effectiveList.get(endElementIndex)).isGlue()) {
                 endElementIndex--;
             }
 
@@ -556,13 +568,12 @@ public abstract class AbstractBreaker {
                 }
 
                 // Handle SpaceHandling(Break)Positions, see SpaceResolver!
-                SpaceResolver.performConditionalsNotification(effectiveList,
-                        startElementIndex, notificationEndElementIndex, 
lastBreak);
+                SpaceResolver.performConditionalsNotification(effectiveList, 
startElementIndex,
+                        notificationEndElementIndex, lastBreak);
                 // Add areas now!
-                addAreas(new KnuthPossPosIter(effectiveList,
-                        startElementIndex, endElementIndex + 1), childLC);
+                addAreas(new KnuthPossPosIter(effectiveList, 
startElementIndex, endElementIndex + 1), childLC);
             } else {
-                //no content for this part
+                // no content for this part
                 handleEmptyContent();
             }
 
@@ -571,6 +582,10 @@ public abstract class AbstractBreaker {
             lastBreak = endElementIndex;
             startElementIndex = pbp.getLeafPos() + 1;
         }
+        if (alg.handlingFloat()) {
+            addAreasForFloats(alg, startPart, partCount, originalList, 
effectiveList, childLC, lastBreak,
+                    startElementIndex, endElementIndex);
+        }
     }
     /**
      * Notifies the layout managers about the space and conditional length 
situation based on
@@ -774,4 +789,14 @@ public abstract class AbstractBreaker {
         return nextSequenceStartsOn;
     }
 
+    protected int handleFloatLayout(PageBreakingAlgorithm alg, int 
optimalPageCount, BlockSequence blockList,
+            LayoutContext childLC) {
+        throw new IllegalStateException();
+    }
+
+    protected void addAreasForFloats(PageBreakingAlgorithm alg, int startPart, 
int partCount,
+            BlockSequence originalList, BlockSequence effectiveList, final 
LayoutContext childLC,
+            int lastBreak, int startElementIndex, int endElementIndex) {
+        throw new IllegalStateException();
+    }
 }

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=1642793&r1=1642792&r2=1642793&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
 Tue Dec  2 00:29:57 2014
@@ -537,4 +537,11 @@ public abstract class AbstractLayoutMana
         }
         ((AbstractLayoutManager) lm).possiblyRegisterMarkersForTables(markers, 
isStarting, isFirst, isLast);
     }
+
+    public boolean handlingFloat() {
+        if (parentLayoutManager != null && parentLayoutManager instanceof 
AbstractLayoutManager) {
+            return ((AbstractLayoutManager) 
parentLayoutManager).handlingFloat();
+        }
+        return false;
+    }
 }

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=1642793&r1=1642792&r2=1642793&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 
Tue Dec  2 00:29:57 2014
@@ -558,6 +558,9 @@ public abstract class BreakingAlgorithm 
                     elementIndex, previousIsBox, allowedBreaks).isBox();
 
             if (activeNodeCount == 0) {
+                if (handlingFloat()) {
+                    return handleFloat();
+                }
                 if (getIPDdifference() != 0) {
                     return handleIpdChange();
                 }
@@ -945,8 +948,11 @@ public abstract class BreakingAlgorithm 
                     log.trace("\tline=" + line);
                 }
 
+                if (element.isForcedBreak() && handlingFloat()) {
+                    disableFloatHandling(); // so that we do not create a 
float edge position later
+                }
                 // The line would be too long.
-                if (r < -1 || element.isForcedBreak()) {
+                if (r < -1 || element.isForcedBreak() || handlingFloat()) {
                     deactivateNode(node, line);
                 }
 
@@ -1028,6 +1034,13 @@ public abstract class BreakingAlgorithm 
             }
         }
 
+        createForcedNodes(node, line, elementIdx, difference, r, demerits, 
fitnessClass, availableShrink,
+                availableStretch, newWidth, newStretch, newShrink);
+    }
+
+    protected void createForcedNodes(KnuthNode node, int line, int elementIdx, 
int difference, double r,
+            double demerits, int fitnessClass, int availableShrink, int 
availableStretch, int newWidth,
+            int newStretch, int newShrink) {
         if (r <= -1) {
             log.debug("Considering tooLong, demerits=" + demerits);
             if (lastTooLong == null || demerits < lastTooLong.totalDemerits) {
@@ -1042,10 +1055,9 @@ public abstract class BreakingAlgorithm 
         } else {
             if (lastTooShort == null || demerits <= 
lastTooShort.totalDemerits) {
                 if (considerTooShort) {
-                    //consider possibilities which are too short
-                    best.addRecord(demerits, node, r,
-                            availableShrink, availableStretch,
-                            difference, fitnessClass);
+                    // consider possibilities which are too short
+                    best.addRecord(demerits, node, r, availableShrink, 
availableStretch, difference,
+                            fitnessClass);
                 }
                 lastTooShort = createNode(elementIdx, line + 1, fitnessClass,
                         newWidth, newStretch, newShrink,
@@ -1451,4 +1463,15 @@ public abstract class BreakingAlgorithm 
         return this.alignmentLast;
     }
 
+    protected boolean handlingFloat() {
+        return false;
+    }
+
+    protected int handleFloat() {
+        throw new IllegalStateException();
+    }
+
+    protected void disableFloatHandling() {
+        throw new IllegalStateException();
+    }
 }

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=1642793&r1=1642792&r2=1642793&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 
Tue Dec  2 00:29:57 2014
@@ -49,6 +49,8 @@ public class FlowLayoutManager extends B
     /** Array of areas currently being filled stored by area class */
     private final BlockParent[] currentAreas = new BlockParent[Area.CLASS_MAX];
 
+    private boolean handlingFloat;
+
     /**
      * This is the top level layout manager.
      * It is created by the PageSequence FO.
@@ -374,6 +376,10 @@ public class FlowLayoutManager extends B
      */
     @Override
     public void addChildArea(Area childArea) {
+        if (childArea instanceof BlockParent && handlingFloat()) {
+            BlockParent bp = (BlockParent) childArea;
+            bp.setXOffset(getPSLM().getStartIntrusionAdjustment());
+        }
         getParentArea(childArea);
         addChildToArea(childArea,
                           this.currentAreas[childArea.getAreaClass()]);
@@ -385,7 +391,7 @@ public class FlowLayoutManager extends B
         BlockParent parentArea = null;
         int aclass = childArea.getAreaClass();
 
-        if (aclass == Area.CLASS_NORMAL) {
+        if (aclass == Area.CLASS_NORMAL || aclass == Area.CLASS_SIDE_FLOAT) {
             parentArea = getCurrentPV().getCurrentFlow();
         } else if (aclass == Area.CLASS_BEFORE_FLOAT) {
             parentArea = getCurrentPV().getBodyRegion().getBeforeFloat();
@@ -407,7 +413,8 @@ public class FlowLayoutManager extends B
      */
     @Override
     public int getContentAreaIPD() {
-        return getCurrentPV().getCurrentSpan().getColumnWidth();
+        int flowIPD = getPSLM().getCurrentColumnWidth();
+        return flowIPD;
     }
 
     /**
@@ -425,5 +432,16 @@ public class FlowLayoutManager extends B
         return true;
     }
 
+    public void handleFloatOn() {
+        handlingFloat = true;
+    }
+
+    public void handleFloatOff() {
+        handlingFloat = false;
+    }
+
+    public boolean handlingFloat() {
+        return handlingFloat;
+    }
 }
 

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/KnuthBlockBox.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/KnuthBlockBox.java?rev=1642793&r1=1642792&r2=1642793&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/KnuthBlockBox.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/KnuthBlockBox.java 
Tue Dec  2 00:29:57 2014
@@ -36,6 +36,7 @@ public class KnuthBlockBox extends Knuth
      */
     private int bpd;
     private List<FootnoteBodyLayoutManager> footnoteList;
+    private List<FloatContentLayoutManager> floatContentLMs;
     /** List of Knuth elements. This is a list of LinkedList elements. */
     private List elementLists;
 
@@ -53,6 +54,7 @@ public class KnuthBlockBox extends Knuth
         ipdRange = range;
         bpd = bpdim;
         footnoteList = new LinkedList<FootnoteBodyLayoutManager>();
+        floatContentLMs = new LinkedList<FloatContentLayoutManager>();
     }
 
     /**
@@ -69,6 +71,16 @@ public class KnuthBlockBox extends Knuth
         ipdRange = MinOptMax.ZERO;
         bpd = 0;
         footnoteList = new LinkedList<FootnoteBodyLayoutManager>(list);
+        floatContentLMs = new LinkedList<FloatContentLayoutManager>();
+    }
+
+    public KnuthBlockBox(int width, List list, Position pos, boolean auxiliary,
+            List<FloatContentLayoutManager> fclms) {
+        super(width, pos, auxiliary);
+        ipdRange = MinOptMax.ZERO;
+        bpd = 0;
+        footnoteList = new LinkedList<FootnoteBodyLayoutManager>(list);
+        floatContentLMs = new LinkedList<FloatContentLayoutManager>(fclms);
     }
 
     /**
@@ -122,4 +134,12 @@ public class KnuthBlockBox extends Knuth
     public int getBPD() {
         return bpd;
     }
+
+    public List<FloatContentLayoutManager> getFloatContentLMs() {
+        return floatContentLMs;
+    }
+
+    public boolean hasFloatAnchors() {
+        return (floatContentLMs.size() > 0);
+    }
 }

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java?rev=1642793&r1=1642792&r2=1642793&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java
 (original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java
 Tue Dec  2 00:29:57 2014
@@ -41,6 +41,7 @@ import org.apache.fop.fo.flow.Block;
 import org.apache.fop.fo.flow.BlockContainer;
 import org.apache.fop.fo.flow.Character;
 import org.apache.fop.fo.flow.ExternalGraphic;
+import org.apache.fop.fo.flow.Float;
 import org.apache.fop.fo.flow.Footnote;
 import org.apache.fop.fo.flow.Inline;
 import org.apache.fop.fo.flow.InlineContainer;
@@ -74,6 +75,7 @@ import org.apache.fop.layoutmgr.inline.B
 import org.apache.fop.layoutmgr.inline.CharacterLayoutManager;
 import org.apache.fop.layoutmgr.inline.ContentLayoutManager;
 import org.apache.fop.layoutmgr.inline.ExternalGraphicLayoutManager;
+import org.apache.fop.layoutmgr.inline.FloatLayoutManager;
 import org.apache.fop.layoutmgr.inline.FootnoteLayoutManager;
 import org.apache.fop.layoutmgr.inline.InlineContainerLayoutManager;
 import org.apache.fop.layoutmgr.inline.InlineLayoutManager;
@@ -113,7 +115,7 @@ public class LayoutManagerMapping implem
         registerMaker(FObjMixed.class, new Maker());
         registerMaker(BidiOverride.class, new 
BidiOverrideLayoutManagerMaker());
         registerMaker(Inline.class, new InlineLayoutManagerMaker());
-        registerMaker(Footnote.class, new FootnodeLayoutManagerMaker());
+        registerMaker(Footnote.class, new FootnoteLayoutManagerMaker());
         registerMaker(InlineContainer.class,
                    new InlineContainerLayoutManagerMaker());
         registerMaker(BasicLink.class, new BasicLinkLayoutManagerMaker());
@@ -146,6 +148,7 @@ public class LayoutManagerMapping implem
         registerMaker(Title.class, new InlineLayoutManagerMaker());
         registerMaker(MultiCase.class, new MultiCaseLayoutManagerMaker());
         registerMaker(MultiSwitch.class, new MultiSwitchLayoutManagerMaker());
+        registerMaker(Float.class, new FloatLayoutManagerMaker());
     }
 
     /**
@@ -267,7 +270,7 @@ public class LayoutManagerMapping implem
     }
 
     /** a layout manager maker */
-    public static class FootnodeLayoutManagerMaker extends Maker {
+    public static class FootnoteLayoutManagerMaker extends Maker {
         /** {@inheritDoc} */
         public void make(FONode node, List lms) {
             lms.add(new FootnoteLayoutManager((Footnote) node));
@@ -463,4 +466,10 @@ public class LayoutManagerMapping implem
         }
     }
 
+    public static class FloatLayoutManagerMaker extends Maker {
+        public void make(FONode node, List lms) {
+            lms.add(new FloatLayoutManager((Float) node));
+        }
+    }
+
 }

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=1642793&r1=1642792&r2=1642793&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 
Tue Dec  2 00:29:57 2014
@@ -20,6 +20,8 @@
 package org.apache.fop.layoutmgr;
 
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
 
@@ -32,7 +34,9 @@ import org.apache.fop.fo.FObj;
 import org.apache.fop.fo.pagination.Region;
 import org.apache.fop.fo.pagination.RegionBody;
 import org.apache.fop.fo.pagination.StaticContent;
+import org.apache.fop.layoutmgr.BreakingAlgorithm.KnuthNode;
 import 
org.apache.fop.layoutmgr.PageBreakingAlgorithm.PageBreakingLayoutListener;
+import org.apache.fop.layoutmgr.list.ListItemLayoutManager;
 import org.apache.fop.traits.MinOptMax;
 
 /**
@@ -47,6 +51,23 @@ public class PageBreaker extends Abstrac
     private PageProvider pageProvider;
     private Block separatorArea;
     private boolean spanAllActive;
+    private boolean handlingStartOfFloat;
+    private boolean handlingEndOfFloat;
+    private int floatHeight;
+    private int floatYOffset;
+
+    private List relayedFootnotesList;
+    private List relayedLengthList;
+    private int relayedTotalFootnotesLength;
+    private int relayedInsertedFootnotesLength;
+    private boolean relayedFootnotesPending;
+    private boolean relayedNewFootnotes;
+    private int relayedFirstNewFootnoteIndex;
+    private int relayedFootnoteListIndex;
+    private int relayedFootnoteElementIndex = -1;
+    private MinOptMax relayedFootnoteSeparatorLength;
+    private int previousFootnoteListIndex = -2;
+    private int previousFootnoteElementIndex = -2;
 
     /**
      * The FlowLayoutManager object, which processes
@@ -69,7 +90,7 @@ public class PageBreaker extends Abstrac
 
     /** {@inheritDoc} */
     protected void updateLayoutContext(LayoutContext context) {
-        int flowIPD = pslm.getCurrentPV().getCurrentSpan().getColumnWidth();
+        int flowIPD = pslm.getCurrentColumnWidth();
         context.setRefIPD(flowIPD);
     }
 
@@ -140,18 +161,20 @@ public class PageBreaker extends Abstrac
     /** {@inheritDoc} */
     protected int getNextBlockList(LayoutContext childLC, int 
nextSequenceStartsOn,
             Position positionAtIPDChange, LayoutManager restartLM, List 
firstElements) {
-        if (!firstPart) {
-            // if this is the first page that will be created by
-            // the current BlockSequence, it could have a break
-            // condition that must be satisfied;
-            // otherwise, we may simply need a new page
-            handleBreakTrait(nextSequenceStartsOn);
-        }
-        firstPart = false;
-        pageBreakHandled = true;
+        if (!handlingFloat()) {
+            if (!firstPart) {
+                // if this is the first page that will be created by
+                // the current BlockSequence, it could have a break
+                // condition that must be satisfied;
+                // otherwise, we may simply need a new page
+                handleBreakTrait(nextSequenceStartsOn);
+            }
+            firstPart = false;
+            pageBreakHandled = true;
 
-        pageProvider.setStartOfNextElementList(pslm.getCurrentPageNum(),
-                pslm.getCurrentPV().getCurrentSpan().getCurrentFlowIndex(), 
this.spanAllActive);
+            pageProvider.setStartOfNextElementList(pslm.getCurrentPageNum(), 
pslm.getCurrentPV()
+                    .getCurrentSpan().getCurrentFlowIndex(), 
this.spanAllActive);
+        }
         return super.getNextBlockList(childLC, nextSequenceStartsOn, 
positionAtIPDChange,
                 restartLM, firstElements);
     }
@@ -234,6 +257,7 @@ public class PageBreaker extends Abstrac
             // handle the footnote separator
             handleFootnoteSeparator();
         }
+
         return contentList;
     }
 
@@ -616,4 +640,238 @@ public class PageBreaker extends Abstrac
             return true;
         }
     }
+
+    protected boolean handlingStartOfFloat() {
+        return handlingStartOfFloat;
+    }
+
+    protected void handleStartOfFloat(int fHeight, int fYOffset) {
+        handlingStartOfFloat = true;
+        handlingEndOfFloat = false;
+        floatHeight = fHeight;
+        floatYOffset = fYOffset;
+        childFLM.handleFloatOn();
+    }
+
+    protected int getFloatHeight() {
+        return floatHeight;
+    }
+
+    protected int getFloatYOffset() {
+        return floatYOffset;
+    }
+
+    protected boolean handlingEndOfFloat() {
+        return handlingEndOfFloat;
+    }
+
+    protected void handleEndOfFloat(int fHeight) {
+        handlingEndOfFloat = true;
+        handlingStartOfFloat = false;
+        floatHeight = fHeight;
+        childFLM.handleFloatOff();
+    }
+
+    protected boolean handlingFloat() {
+        return (handlingStartOfFloat || handlingEndOfFloat);
+    }
+
+    public int getOffsetDueToFloat() {
+        handlingEndOfFloat = false;
+        return floatHeight + floatYOffset;
+    }
+
+    protected int handleFloatLayout(PageBreakingAlgorithm alg, int 
optimalPageCount, BlockSequence blockList,
+            LayoutContext childLC) {
+        pageBreakHandled = true;
+        List firstElements = Collections.EMPTY_LIST;
+        KnuthNode floatNode = alg.getBestFloatEdgeNode();
+        int floatPosition = floatNode.position;
+        KnuthElement floatElem = alg.getElement(floatPosition);
+        Position positionAtBreak = floatElem.getPosition();
+        if (!(positionAtBreak instanceof 
SpaceResolver.SpaceHandlingBreakPosition)) {
+            throw new UnsupportedOperationException("Don't know how to restart 
at position" + positionAtBreak);
+        }
+        /* Retrieve the original position wrapped into this space position */
+        positionAtBreak = positionAtBreak.getPosition();
+        addAreas(alg, optimalPageCount, blockList, blockList);
+        blockLists.clear();
+        blockListIndex = -1;
+        LayoutManager restartAtLM = null;
+        if (positionAtBreak != null && positionAtBreak.getIndex() == -1) {
+            if (positionAtBreak instanceof 
ListItemLayoutManager.ListItemPosition) {
+                restartAtLM = positionAtBreak.getLM();
+            } else {
+                Position position;
+                Iterator iter = blockList.listIterator(floatPosition + 1);
+                do {
+                    KnuthElement nextElement = (KnuthElement) iter.next();
+                    position = nextElement.getPosition();
+                } while (position == null || position instanceof 
SpaceResolver.SpaceHandlingPosition
+                        || position instanceof 
SpaceResolver.SpaceHandlingBreakPosition
+                        && position.getPosition().getIndex() == -1);
+                LayoutManager surroundingLM = positionAtBreak.getLM();
+                while (position.getLM() != surroundingLM) {
+                    position = position.getPosition();
+                }
+                restartAtLM = position.getPosition().getLM();
+            }
+        }
+        int nextSequenceStartsOn = getNextBlockList(childLC, 
Constants.EN_COLUMN, positionAtBreak,
+                restartAtLM, firstElements);
+        return nextSequenceStartsOn;
+    }
+
+    protected void addAreasForFloats(PageBreakingAlgorithm alg, int startPart, 
int partCount,
+            BlockSequence originalList, BlockSequence effectiveList, final 
LayoutContext childLC,
+            int lastBreak, int startElementIndex, int endElementIndex) {
+        FloatPosition pbp = alg.getFloatPosition();
+
+        // Check the last break position for forced breaks
+        int lastBreakClass;
+        if (startElementIndex == 0) {
+            lastBreakClass = effectiveList.getStartOn();
+        } else {
+            ListElement lastBreakElement = 
effectiveList.getElement(endElementIndex);
+            if (lastBreakElement.isPenalty()) {
+                KnuthPenalty pen = (KnuthPenalty) lastBreakElement;
+                if (pen.getPenalty() == KnuthPenalty.INFINITE) {
+                    /**
+                     * That means that there was a keep.within-page="always", 
but that
+                     * it's OK to break at a column. TODO The break class is 
being
+                     * abused to implement keep.within-column and 
keep.within-page.
+                     * This is very misleading and must be revised.
+                     */
+                    lastBreakClass = Constants.EN_COLUMN;
+                } else {
+                    lastBreakClass = pen.getBreakClass();
+                }
+            } else {
+                lastBreakClass = Constants.EN_COLUMN;
+            }
+        }
+
+        // the end of the new part
+        endElementIndex = pbp.getLeafPos();
+
+        // ignore the first elements added by the
+        // PageSequenceLayoutManager
+        startElementIndex += (startElementIndex == 0) ? 
effectiveList.ignoreAtStart : 0;
+
+        log.debug("PLM> part: " + (startPart + partCount + 1) + ", start at 
pos " + startElementIndex
+                + ", break at pos " + endElementIndex + ", break class = "
+                + getBreakClassName(lastBreakClass));
+
+        startPart(effectiveList, lastBreakClass);
+
+        int displayAlign = getCurrentDisplayAlign();
+
+        // The following is needed by 
SpaceResolver.performConditionalsNotification()
+        // further down as there may be important Position elements in the 
element list trailer
+        int notificationEndElementIndex = endElementIndex;
+
+        // ignore the last elements added by the
+        // PageSequenceLayoutManager
+        endElementIndex -= (endElementIndex == (originalList.size() - 1)) ? 
effectiveList.ignoreAtEnd : 0;
+
+        // ignore the last element in the page if it is a KnuthGlue
+        // object
+        if (((KnuthElement) effectiveList.get(endElementIndex)).isGlue()) {
+            endElementIndex--;
+        }
+
+        // ignore KnuthGlue and KnuthPenalty objects
+        // at the beginning of the line
+        startElementIndex = alg.par.getFirstBoxIndex(startElementIndex);
+
+        if (startElementIndex <= endElementIndex) {
+            if (log.isDebugEnabled()) {
+                log.debug("     addAreas from " + startElementIndex + " to " + 
endElementIndex);
+            }
+            // set the space adjustment ratio
+            childLC.setSpaceAdjust(pbp.bpdAdjust);
+            // add space before if display-align is center or bottom
+            // add space after if display-align is distribute and
+            // this is not the last page
+            if (pbp.difference != 0 && displayAlign == Constants.EN_CENTER) {
+                childLC.setSpaceBefore(pbp.difference / 2);
+            } else if (pbp.difference != 0 && displayAlign == 
Constants.EN_AFTER) {
+                childLC.setSpaceBefore(pbp.difference);
+            }
+
+            // Handle SpaceHandling(Break)Positions, see SpaceResolver!
+            SpaceResolver.performConditionalsNotification(effectiveList, 
startElementIndex,
+                    notificationEndElementIndex, lastBreak);
+            // Add areas of lines, in the current page, before the float or 
during float
+            addAreas(new KnuthPossPosIter(effectiveList, startElementIndex, 
endElementIndex + 1), childLC);
+            // add areas for the float, if applicable
+            if (alg.handlingStartOfFloat()) {
+                for (int k = startElementIndex; k < endElementIndex + 1; k++) {
+                    ListElement le = effectiveList.getElement(k);
+                    if (le instanceof KnuthBlockBox) {
+                        KnuthBlockBox kbb = (KnuthBlockBox) le;
+                        for (FloatContentLayoutManager fclm : 
kbb.getFloatContentLMs()) {
+                            fclm.processAreas(childLC);
+                            int floatHeight = fclm.getFloatHeight();
+                            int floatYOffset = fclm.getFloatYOffset();
+                            PageSequenceLayoutManager pslm = 
(PageSequenceLayoutManager) getTopLevelLM();
+                            pslm.recordStartOfFloat(floatHeight, floatYOffset);
+                        }
+                    }
+                }
+            }
+            if (alg.handlingEndOfFloat()) {
+                PageSequenceLayoutManager pslm = (PageSequenceLayoutManager) 
getTopLevelLM();
+                pslm.setEndIntrusionAdjustment(0);
+                pslm.setStartIntrusionAdjustment(0);
+                int effectiveFloatHeight = alg.getFloatHeight();
+                pslm.recordEndOfFloat(effectiveFloatHeight);
+            }
+            if (alg.handlingFloat()) {
+                PageSequenceLayoutManager pslm = (PageSequenceLayoutManager) 
getTopLevelLM();
+                alg.relayFootnotes(pslm);
+            }
+        } else {
+            // no content for this part
+            handleEmptyContent();
+        }
+
+        pageBreakHandled = true;
+    }
+
+    public void holdFootnotes(List fl, List ll, int tfl, int ifl, boolean fp, 
boolean nf, int fnfi, int fli,
+            int fei, MinOptMax fsl, int pfli, int pfei) {
+        relayedFootnotesList = fl;
+        relayedLengthList = ll;
+        relayedTotalFootnotesLength = tfl;
+        relayedInsertedFootnotesLength = ifl;
+        relayedFootnotesPending = fp;
+        relayedNewFootnotes = nf;
+        relayedFirstNewFootnoteIndex = fnfi;
+        relayedFootnoteListIndex = fli;
+        relayedFootnoteElementIndex = fei;
+        relayedFootnoteSeparatorLength = fsl;
+        previousFootnoteListIndex = pfli;
+        previousFootnoteElementIndex = pfei;
+    }
+
+    public void retrieveFootones(PageBreakingAlgorithm alg) {
+        if (relayedFootnotesList != null && relayedFootnotesList.size() > 0) {
+            alg.loadFootnotes(relayedFootnotesList, relayedLengthList, 
relayedTotalFootnotesLength,
+                    relayedInsertedFootnotesLength, relayedFootnotesPending, 
relayedNewFootnotes,
+                    relayedFirstNewFootnoteIndex, relayedFootnoteListIndex, 
relayedFootnoteElementIndex,
+                    relayedFootnoteSeparatorLength, previousFootnoteListIndex,
+                    previousFootnoteElementIndex);
+            relayedFootnotesList = null;
+            relayedLengthList = null;
+            relayedTotalFootnotesLength = 0;
+            relayedInsertedFootnotesLength = 0;
+            relayedFootnotesPending = false;
+            relayedNewFootnotes = false;
+            relayedFirstNewFootnoteIndex = 0;
+            relayedFootnoteListIndex = 0;
+            relayedFootnoteElementIndex = -1;
+            relayedFootnoteSeparatorLength = null;
+        }
+    }
 }

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java?rev=1642793&r1=1642792&r2=1642793&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
 (original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
 Tue Dec  2 00:29:57 2014
@@ -29,6 +29,7 @@ import org.apache.commons.logging.LogFac
 
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.FObj;
+import org.apache.fop.layoutmgr.AbstractBreaker.FloatPosition;
 import org.apache.fop.layoutmgr.AbstractBreaker.PageBreakPosition;
 import org.apache.fop.layoutmgr.WhitespaceManagementPenalty.Variant;
 import org.apache.fop.traits.MinOptMax;
@@ -99,6 +100,16 @@ class PageBreakingAlgorithm extends Brea
     private int currentKeepContext = Constants.EN_AUTO;
     private KnuthNode lastBeforeKeepContextSwitch;
 
+    // just one float for now...
+    private boolean handlingStartOfFloat;
+    private boolean handlingEndOfFloat;
+    private int floatHeight;
+    private KnuthNode bestFloatEdgeNode;
+    private FloatPosition floatPosition;
+    private int previousFootnoteListIndex = -2;
+    private int previousFootnoteElementIndex = -2;
+    private boolean relayingFootnotes;
+
     /**
      * Construct a page breaking algorithm.
      * @param topLevelLM the top level layout manager
@@ -235,6 +246,18 @@ class PageBreakingAlgorithm extends Brea
         insertedFootnotesLength = 0;
         footnoteListIndex = 0;
         footnoteElementIndex = -1;
+        if (topLevelLM instanceof PageSequenceLayoutManager) {
+            PageSequenceLayoutManager pslm = (PageSequenceLayoutManager) 
topLevelLM;
+            if (pslm.handlingStartOfFloat() || pslm.handlingEndOfFloat()) {
+                pslm.retrieveFootnotes(this);
+            }
+            if (pslm.handlingStartOfFloat()) {
+                floatHeight = Math.min(pslm.getFloatHeight(), lineWidth - 
pslm.getFloatYOffset());
+            }
+            if (pslm.handlingEndOfFloat()) {
+                totalWidth += pslm.getOffsetDueToFloat() + 
insertedFootnotesLength;
+            }
+        }
     }
 
     /**
@@ -352,6 +375,12 @@ class PageBreakingAlgorithm extends Brea
                 firstNewFootnoteIndex = footnotesList.size() - 1;
             }
         }
+        if (box instanceof KnuthBlockBox && ((KnuthBlockBox) 
box).hasFloatAnchors()) {
+            handlingStartOfFloat = true;
+        }
+        if (floatHeight != 0 && totalWidth >= floatHeight) {
+            handlingEndOfFloat = true;
+        }
     }
 
     /**
@@ -1064,17 +1093,6 @@ class PageBreakingAlgorithm extends Brea
                 difference = 0;
             }
         }
-        // compute the indexes of the first footnote list and the first 
element in that list
-        int firstListIndex = ((KnuthPageNode) 
bestActiveNode.previous).footnoteListIndex;
-        int firstElementIndex = ((KnuthPageNode) 
bestActiveNode.previous).footnoteElementIndex;
-        if (footnotesList != null
-                && firstElementIndex == getFootnoteList(firstListIndex).size() 
- 1) {
-            // advance to the next list
-            firstListIndex++;
-            firstElementIndex = 0;
-        } else {
-            firstElementIndex++;
-        }
 
         // add nodes at the beginning of the list, as they are found
         // backwards, from the last one to the first one
@@ -1082,12 +1100,31 @@ class PageBreakingAlgorithm extends Brea
             log.debug("BBA> difference=" + difference + " ratio=" + ratio
                     + " position=" + bestActiveNode.position);
         }
-        insertPageBreakAsFirst(new PageBreakPosition(this.topLevelLM,
-                bestActiveNode.position,
-                firstListIndex, firstElementIndex,
-                ((KnuthPageNode) bestActiveNode).footnoteListIndex,
-                ((KnuthPageNode) bestActiveNode).footnoteElementIndex,
-                ratio, difference));
+        if (handlingFloat() && floatPosition == null) {
+            floatPosition = new FloatPosition(this.topLevelLM, 
bestActiveNode.position, ratio, difference);
+        } else {
+            boolean useRelayedFootnotes = relayingFootnotes && 
bestActiveNode.previous.position == 0;
+            // compute the indexes of the first footnote list and the first 
element in that list
+            int firstListIndex = (useRelayedFootnotes) ? 
previousFootnoteListIndex
+                    : ((KnuthPageNode) 
bestActiveNode.previous).footnoteListIndex;
+            int firstElementIndex = (useRelayedFootnotes) ? 
previousFootnoteElementIndex
+                    : ((KnuthPageNode) 
bestActiveNode.previous).footnoteElementIndex;
+            if (useRelayedFootnotes) {
+                previousFootnoteListIndex = -2;
+                previousFootnoteElementIndex = -2;
+                relayingFootnotes = false;
+            }
+            if (footnotesList != null && firstElementIndex == 
getFootnoteList(firstListIndex).size() - 1) {
+                // advance to the next list
+                firstListIndex++;
+                firstElementIndex = 0;
+            } else {
+                firstElementIndex++;
+            }
+            insertPageBreakAsFirst(new PageBreakPosition(this.topLevelLM, 
bestActiveNode.position,
+                    firstListIndex, firstElementIndex, ((KnuthPageNode) 
bestActiveNode).footnoteListIndex,
+                    ((KnuthPageNode) bestActiveNode).footnoteElementIndex, 
ratio, difference));
+        }
     }
 
     /** {@inheritDoc} */
@@ -1233,4 +1270,94 @@ class PageBreakingAlgorithm extends Brea
         }
         return pageProvider.compareIPDs(line);
     }
+
+    protected boolean handlingFloat() {
+        return (handlingStartOfFloat || handlingEndOfFloat);
+    }
+
+    protected void createForcedNodes(KnuthNode node, int line, int elementIdx, 
int difference, double r,
+            double demerits, int fitnessClass, int availableShrink, int 
availableStretch, int newWidth,
+            int newStretch, int newShrink) {
+        if (handlingFloat()) {
+            if (bestFloatEdgeNode == null || demerits <= 
bestFloatEdgeNode.totalDemerits) {
+                bestFloatEdgeNode = createNode(elementIdx, line + 1, 
fitnessClass, newWidth, newStretch,
+                        newShrink, r, availableShrink, availableStretch, 
difference, demerits, node);
+            }
+        } else {
+            super.createForcedNodes(node, line, elementIdx, difference, r, 
demerits, fitnessClass,
+                    availableShrink, availableStretch, newWidth, newStretch, 
newShrink);
+        }
+    }
+
+    protected int handleFloat() {
+        calculateBreakPoints(bestFloatEdgeNode, par, bestFloatEdgeNode.line);
+        activeLines = null;
+        return bestFloatEdgeNode.line - 1;
+    }
+
+    protected KnuthNode getBestFloatEdgeNode() {
+        return bestFloatEdgeNode;
+    }
+
+    protected FloatPosition getFloatPosition() {
+        return floatPosition;
+    }
+
+    protected int getFloatHeight() {
+        return floatHeight;
+    }
+
+    protected boolean handlingStartOfFloat() {
+        return handlingStartOfFloat;
+    }
+
+    protected boolean handlingEndOfFloat() {
+        return handlingEndOfFloat;
+    }
+
+    /**
+     * Deactivate the given node
+     *
+     * @param node  the node
+     * @param line  the line number
+     */
+    protected void deactivateNode(KnuthNode node, int line) {
+        super.deactivateNode(node, line);
+        if (handlingEndOfFloat) {
+            floatHeight = totalWidth;
+        }
+    }
+
+    protected void disableFloatHandling() {
+        handlingEndOfFloat = false;
+        handlingStartOfFloat = false;
+    }
+
+    public void loadFootnotes(List fl, List ll, int tfl, int ifl, boolean fp, 
boolean nf, int fnfi, int fli,
+            int fei, MinOptMax fsl, int pfli, int pfei) {
+        footnotesList = fl;
+        lengthList = ll;
+        totalFootnotesLength = tfl;
+        insertedFootnotesLength = ifl;
+        footnotesPending = fp;
+        newFootnotes = nf;
+        firstNewFootnoteIndex = fnfi;
+        footnoteListIndex = fli;
+        footnoteElementIndex = fei;
+        footnoteSeparatorLength = fsl;
+        previousFootnoteListIndex = pfli;
+        previousFootnoteElementIndex = pfei;
+        relayingFootnotes = !(previousFootnoteListIndex == -2 && 
previousFootnoteElementIndex == -2);
+    }
+
+    public void relayFootnotes(PageSequenceLayoutManager pslm) {
+        if (!relayingFootnotes) {
+            previousFootnoteListIndex = ((KnuthPageNode) 
bestFloatEdgeNode.previous).footnoteListIndex;
+            previousFootnoteElementIndex = ((KnuthPageNode) 
bestFloatEdgeNode.previous).footnoteElementIndex;
+        }
+        pslm.holdFootnotes(footnotesList, lengthList, totalFootnotesLength, 
insertedFootnotesLength,
+                footnotesPending, newFootnotes, firstNewFootnoteIndex, 
footnoteListIndex,
+                footnoteElementIndex, footnoteSeparatorLength, 
previousFootnoteListIndex,
+                previousFootnoteElementIndex);
+    }
 }

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java?rev=1642793&r1=1642792&r2=1642793&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java
 (original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java
 Tue Dec  2 00:29:57 2014
@@ -36,6 +36,7 @@ import org.apache.fop.fo.pagination.Page
 import org.apache.fop.fo.pagination.SideRegion;
 import org.apache.fop.fo.pagination.StaticContent;
 import org.apache.fop.layoutmgr.inline.ContentLayoutManager;
+import org.apache.fop.traits.MinOptMax;
 
 /**
  * LayoutManager for a PageSequence.  This class is instantiated by
@@ -56,6 +57,9 @@ public class PageSequenceLayoutManager e
     /** Footnotes coming from repeated table footers, to be added after any 
other footnote. */
     private List<List<KnuthElement>> tableFooterFootnotes;
 
+    private int startIntrusionAdjustment;
+    private int endIntrusionAdjustment;
+
     /**
      * Constructor
      *
@@ -293,4 +297,64 @@ public class PageSequenceLayoutManager e
         }
     }
 
+    public void setStartIntrusionAdjustment(int sia) {
+        startIntrusionAdjustment = sia;
+    }
+
+    public void setEndIntrusionAdjustment(int eia) {
+        endIntrusionAdjustment = eia;
+    }
+
+    public int getStartIntrusionAdjustment() {
+        return startIntrusionAdjustment;
+    }
+
+    public int getEndIntrusionAdjustment() {
+        return endIntrusionAdjustment;
+    }
+
+    public void recordEndOfFloat(int fHeight) {
+        pageBreaker.handleEndOfFloat(fHeight);
+    }
+
+    public boolean handlingEndOfFloat() {
+        return pageBreaker.handlingEndOfFloat();
+    }
+
+    public int getOffsetDueToFloat() {
+        return pageBreaker.getOffsetDueToFloat();
+    }
+
+    public void recordStartOfFloat(int fHeight, int fYOffset) {
+        pageBreaker.handleStartOfFloat(fHeight, fYOffset);
+    }
+
+    public boolean handlingStartOfFloat() {
+        return pageBreaker.handlingStartOfFloat();
+    }
+
+    public int getFloatHeight() {
+        return pageBreaker.getFloatHeight();
+    }
+
+    public int getFloatYOffset() {
+        return pageBreaker.getFloatYOffset();
+    }
+
+    public int getCurrentColumnWidth() {
+        int flowIPD = getCurrentPV().getCurrentSpan().getColumnWidth();
+        flowIPD -= startIntrusionAdjustment + endIntrusionAdjustment;
+        return flowIPD;
+    }
+
+    public void holdFootnotes(List fl, List ll, int tfl, int ifl, boolean fp, 
boolean nf, int fnfi, int fli,
+            int fei, MinOptMax fsl, int pfli, int pfei) {
+        if (fl != null && fl.size() > 0) {
+            pageBreaker.holdFootnotes(fl, ll, tfl, ifl, fp, nf, fnfi, fli, 
fei, fsl, pfli, pfei);
+        }
+    }
+
+    public void retrieveFootnotes(PageBreakingAlgorithm alg) {
+        pageBreaker.retrieveFootones(alg);
+    }
 }

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/SpaceResolver.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/SpaceResolver.java?rev=1642793&r1=1642792&r2=1642793&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/SpaceResolver.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/SpaceResolver.java 
Tue Dec  2 00:29:57 2014
@@ -696,7 +696,7 @@ public final class SpaceResolver {
                 beforeBreak.notifyBreakSituation(true, RelSide.BEFORE);
             }
         }
-        el = (KnuthElement)effectiveList.get(endElementIndex);
+        el = endElementIndex > -1 ? (KnuthElement) 
effectiveList.get(endElementIndex) : null;
         if (el != null && el.isPenalty()) {
             Position pos = el.getPosition();
             if (pos instanceof SpaceResolver.SpaceHandlingBreakPosition) {

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/KnuthInlineBox.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/KnuthInlineBox.java?rev=1642793&r1=1642792&r2=1642793&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/KnuthInlineBox.java
 (original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/inline/KnuthInlineBox.java
 Tue Dec  2 00:29:57 2014
@@ -19,6 +19,7 @@
 
 package org.apache.fop.layoutmgr.inline;
 
+import org.apache.fop.layoutmgr.FloatContentLayoutManager;
 import org.apache.fop.layoutmgr.FootnoteBodyLayoutManager;
 import org.apache.fop.layoutmgr.KnuthBox;
 import org.apache.fop.layoutmgr.Position;
@@ -30,6 +31,8 @@ public class KnuthInlineBox extends Knut
 
     private FootnoteBodyLayoutManager footnoteBodyLM;
     private AlignmentContext alignmentContext;
+    private FloatContentLayoutManager floatContentLM;
+
 
     /**
      * Create a new KnuthBox.
@@ -72,4 +75,17 @@ public class KnuthInlineBox extends Knut
     public boolean isAnchor() {
         return (footnoteBodyLM != null);
     }
+
+    public void setFloatContentLM(FloatContentLayoutManager fclm) {
+        floatContentLM = fclm;
+    }
+
+    public FloatContentLayoutManager getFloatContentLM() {
+        return floatContentLM;
+    }
+
+    public boolean isFloatAnchor() {
+        return (floatContentLM != null);
+    }
+
 }

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=1642793&r1=1642792&r2=1642793&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
 Tue Dec  2 00:29:57 2014
@@ -20,6 +20,7 @@
 package org.apache.fop.layoutmgr.inline;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
@@ -50,6 +51,7 @@ import org.apache.fop.layoutmgr.BlockLev
 import org.apache.fop.layoutmgr.BreakElement;
 import org.apache.fop.layoutmgr.BreakingAlgorithm;
 import org.apache.fop.layoutmgr.ElementListObserver;
+import org.apache.fop.layoutmgr.FloatContentLayoutManager;
 import org.apache.fop.layoutmgr.FootenoteUtil;
 import org.apache.fop.layoutmgr.FootnoteBodyLayoutManager;
 import org.apache.fop.layoutmgr.InlineKnuthSequence;
@@ -963,13 +965,19 @@ public class LineLayoutManager extends I
                 /* "normal" vertical alignment: create a sequence whose boxes
                    represent effective lines, and contain LineBreakPositions */
                 int startIndex = 0;
+                int previousEndIndex = 0;
                 for (int i = 0;
                         i < llPoss.getChosenLineCount();
                         i++) {
+                    int orphans = fobj.getOrphans();
+                    int widows = fobj.getWidows();
+                    if (handlingFloat()) {
+                        orphans = 1;
+                        widows = 1;
+                    }
                     if (returnList.size() > 0
                             && i > 0 //if i==0 break generated above already
-                            && i >= fobj.getOrphans()
-                            && i <= llPoss.getChosenLineCount() - 
fobj.getWidows()) {
+                            && i >= orphans && i <= 
llPoss.getChosenLineCount() - widows) {
                         // penalty allowing a page break between lines
                         Keep keep = getKeepTogether();
                         returnList.add(new BreakElement(
@@ -983,14 +991,28 @@ public class LineLayoutManager extends I
                     // whose citations are in this line
                     List<FootnoteBodyLayoutManager> footnoteList = 
FootenoteUtil.getFootnotes(
                             seq, startIndex, endIndex);
+                    List<FloatContentLayoutManager> floats = 
FloatContentLayoutManager.checkForFloats(seq,
+                            startIndex, endIndex);
                     startIndex = endIndex + 1;
                     LineBreakPosition lbp = (LineBreakPosition) 
llPoss.getChosenPosition(i);
                     if (baselineOffset < 0) {
                         baselineOffset = lbp.spaceBefore + lbp.baseline;
                     }
-                    returnList.add(new KnuthBlockBox(
-                                   lbp.lineHeight + lbp.spaceBefore + 
lbp.spaceAfter,
-                                    footnoteList, lbp, false));
+                    if (floats.isEmpty()) {
+                        returnList.add(new KnuthBlockBox(lbp.lineHeight + 
lbp.spaceBefore + lbp.spaceAfter,
+                                footnoteList, lbp, false));
+                    } else {
+                        // add a line with height zero and no content and 
attach float to it
+                        returnList.add(new KnuthBlockBox(0, 
Collections.emptyList(), null, false, floats));
+                        // add a break element to signal that we should 
restart LB at this break
+                        Keep keep = getKeepTogether();
+                        returnList.add(new BreakElement(new LeafPosition(this, 
p, previousEndIndex), keep
+                                .getPenalty(), keep.getContext(), context));
+                        // add the original line where the float was but 
without the float now
+                        returnList.add(new KnuthBlockBox(lbp.lineHeight + 
lbp.spaceBefore + lbp.spaceAfter,
+                                footnoteList, lbp, false));
+                    }
+                    previousEndIndex = endIndex;
                 }
             }
         }
@@ -1196,10 +1218,15 @@ public class LineLayoutManager extends I
         for (int p = 0; p < knuthParagraphs.size(); p++) {
             LineLayoutPossibilities llPoss = lineLayoutsList[p];
             //log.debug("demerits of the chosen layout: " + 
llPoss.getChosenDemerits());
+            int orphans = fobj.getOrphans();
+            int widows = fobj.getWidows();
+            if (handlingFloat()) {
+                orphans = 1;
+                widows = 1;
+            }
             for (int i = 0; i < llPoss.getChosenLineCount(); i++) {
-                if (!((BlockLevelLayoutManager) 
parentLayoutManager).mustKeepTogether()
-                    && i >= fobj.getOrphans()
-                    && i <= llPoss.getChosenLineCount() - fobj.getWidows()) {
+                if (!((BlockLevelLayoutManager) 
parentLayoutManager).mustKeepTogether() && i >= orphans
+                        && i <= llPoss.getChosenLineCount() - widows) {
                     // null penalty allowing a page break between lines
                     returnList.add(new KnuthPenalty(0, 0, false, new 
Position(this), false));
                 }

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java?rev=1642793&r1=1642792&r2=1642793&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
 (original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
 Tue Dec  2 00:29:57 2014
@@ -21,6 +21,7 @@ package org.apache.fop.layoutmgr.list;
 
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Stack;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -95,10 +96,11 @@ public class ListBlockLayoutManager exte
     }
 
     /** {@inheritDoc} */
-    @Override
-    public List getNextKnuthElements(LayoutContext context, int alignment) {
+    public List getNextKnuthElements(LayoutContext context, int alignment, 
Stack lmStack,
+            Position restartPosition, LayoutManager restartAtLM) {
         resetSpaces();
-        List returnList = super.getNextKnuthElements(context, alignment);
+        List returnList;
+        returnList = super.getNextKnuthElements(context, alignment, lmStack, 
restartPosition, restartAtLM);
 
         //fox:widow-content-limit
         int widowRowLimit = getListBlockFO().getWidowContentLimit().getValue();
@@ -275,5 +277,9 @@ public class ListBlockLayoutManager exte
         return getListBlockFO().getKeepWithNext();
     }
 
+    /** {@inheritDoc} */
+    public boolean isRestartable() {
+        return true;
+    }
 }
 

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java?rev=1642793&r1=1642792&r2=1642793&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java
 (original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java
 Tue Dec  2 00:29:57 2014
@@ -21,6 +21,7 @@ package org.apache.fop.layoutmgr.list;
 
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Stack;
 
 import org.apache.fop.area.Area;
 import org.apache.fop.area.Block;
@@ -225,15 +226,15 @@ public class ListItemContentLayoutManage
         return Keep.KEEP_AUTO;
     }
 
-    @SuppressWarnings("unchecked")
-    @Override
-    public List<ListElement> getNextKnuthElements(LayoutContext context, int 
alignment) {
+    /** {@inheritDoc} */
+    public List getNextKnuthElements(LayoutContext context, int alignment, 
Stack lmStack,
+            Position restartPosition, LayoutManager restartAtLM) {
         List<ListElement> elements = new LinkedList<ListElement>();
         do {
-            elements.addAll(super.getNextKnuthElements(context, alignment));
+            elements.addAll(super.getNextKnuthElements(context, alignment, 
lmStack, restartPosition,
+                    restartAtLM));
         } while (!isFinished());
         return elements;
     }
-
 }
 

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java?rev=1642793&r1=1642792&r2=1642793&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
 (original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
 Tue Dec  2 00:29:57 2014
@@ -20,9 +20,11 @@
 package org.apache.fop.layoutmgr.list;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.ListIterator;
+import java.util.Stack;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -39,15 +41,16 @@ import org.apache.fop.layoutmgr.BreakOpp
 import org.apache.fop.layoutmgr.BreakOpportunityHelper;
 import org.apache.fop.layoutmgr.ElementListObserver;
 import org.apache.fop.layoutmgr.ElementListUtils;
+import org.apache.fop.layoutmgr.FloatContentLayoutManager;
 import org.apache.fop.layoutmgr.FootenoteUtil;
 import org.apache.fop.layoutmgr.Keep;
 import org.apache.fop.layoutmgr.KnuthBlockBox;
-import org.apache.fop.layoutmgr.KnuthBox;
 import org.apache.fop.layoutmgr.KnuthElement;
 import org.apache.fop.layoutmgr.KnuthPenalty;
 import org.apache.fop.layoutmgr.KnuthPossPosIter;
 import org.apache.fop.layoutmgr.LayoutContext;
 import org.apache.fop.layoutmgr.LayoutManager;
+import org.apache.fop.layoutmgr.LeafPosition;
 import org.apache.fop.layoutmgr.ListElement;
 import org.apache.fop.layoutmgr.NonLeafPosition;
 import org.apache.fop.layoutmgr.Position;
@@ -79,11 +82,13 @@ public class ListItemLayoutManager exten
     private Keep keepWithNextPendingOnLabel;
     private Keep keepWithNextPendingOnBody;
 
-    private class ListItemPosition extends Position {
+    public class ListItemPosition extends Position {
         private int labelFirstIndex;
         private int labelLastIndex;
         private int bodyFirstIndex;
         private int bodyLastIndex;
+        private Position originalLabelPosition;
+        private Position originalBodyPosition;
 
         public ListItemPosition(LayoutManager lm, int labelFirst, int 
labelLast,
                 int bodyFirst, int bodyLast) {
@@ -124,6 +129,22 @@ public class ListItemLayoutManager exten
             sb.append(")");
             return sb.toString();
         }
+
+        public Position getOriginalLabelPosition() {
+            return originalLabelPosition;
+        }
+
+        public void setOriginalLabelPosition(Position originalLabelPosition) {
+            this.originalLabelPosition = originalLabelPosition;
+        }
+
+        public Position getOriginalBodyPosition() {
+            return originalBodyPosition;
+        }
+
+        public void setOriginalBodyPosition(Position originalBodyPosition) {
+            this.originalBodyPosition = originalBodyPosition;
+        }
     }
 
     /**
@@ -188,8 +209,8 @@ public class ListItemLayoutManager exten
     }
 
     /** {@inheritDoc} */
-    @Override
-    public List getNextKnuthElements(LayoutContext context, int alignment) {
+    public List getNextKnuthElements(LayoutContext context, int alignment, 
Stack lmStack,
+            Position restartPosition, LayoutManager restartAtLM) {
         referenceIPD = context.getRefIPD();
         LayoutContext childLC;
 
@@ -205,7 +226,30 @@ public class ListItemLayoutManager exten
         childLC = makeChildLayoutContext(context);
         childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE);
         label.initialize();
-        labelList = label.getNextKnuthElements(childLC, alignment);
+        boolean labelDone = false;
+        Stack labelLMStack = null;
+        Position labelRestartPosition = null;
+        LayoutManager labelRestartLM = null;
+        if (restartPosition != null && restartPosition instanceof 
ListItemPosition) {
+            ListItemPosition lip = (ListItemPosition) restartPosition;
+            if (lip.labelLastIndex <= lip.labelFirstIndex) {
+                labelDone = true;
+            } else {
+                labelRestartPosition = lip.getOriginalLabelPosition();
+                labelRestartLM = labelRestartPosition.getLM();
+                LayoutManager lm = labelRestartLM;
+                labelLMStack = new Stack();
+                while (lm != this) {
+                    labelLMStack.push(lm);
+                    lm = lm.getParent();
+                    if (lm instanceof ListItemContentLayoutManager) {
+                        lm = lm.getParent();
+                    }
+                }
+            }
+        }
+        labelList = !labelDone ? label.getNextKnuthElements(childLC, 
alignment, labelLMStack,
+                labelRestartPosition, labelRestartLM) : new 
LinkedList<KnuthElement>();
 
         //Space resolution as if the contents were placed in a new reference 
area
         //(see 6.8.3, XSL 1.0, section on Constraints, last paragraph)
@@ -219,7 +263,30 @@ public class ListItemLayoutManager exten
         childLC = makeChildLayoutContext(context);
         childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE);
         body.initialize();
-        bodyList = body.getNextKnuthElements(childLC, alignment);
+        boolean bodyDone = false;
+        Stack bodyLMStack = null;
+        Position bodyRestartPosition = null;
+        LayoutManager bodyRestartLM = null;
+        if (restartPosition != null && restartPosition instanceof 
ListItemPosition) {
+            ListItemPosition lip = (ListItemPosition) restartPosition;
+            if (lip.bodyLastIndex <= lip.bodyFirstIndex) {
+                bodyDone = true;
+            } else {
+                bodyRestartPosition = lip.getOriginalBodyPosition();
+                bodyRestartLM = bodyRestartPosition.getLM();
+                LayoutManager lm = bodyRestartLM;
+                bodyLMStack = new Stack();
+                while (lm != this) {
+                    bodyLMStack.push(lm);
+                    lm = lm.getParent();
+                    if (lm instanceof ListItemContentLayoutManager) {
+                        lm = lm.getParent();
+                    }
+                }
+            }
+        }
+        bodyList = !bodyDone ? body.getNextKnuthElements(childLC, alignment, 
bodyLMStack,
+                bodyRestartPosition, bodyRestartLM) : new 
LinkedList<KnuthElement>();
 
         //Space resolution as if the contents were placed in a new reference 
area
         //(see 6.8.3, XSL 1.0, section on Constraints, last paragraph)
@@ -229,8 +296,34 @@ public class ListItemLayoutManager exten
         
context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending());
         this.keepWithNextPendingOnBody = childLC.getKeepWithNextPending();
 
+        List<ListElement> returnedList = new LinkedList<ListElement>();
+        if (!labelList.isEmpty() && labelList.get(0) instanceof KnuthBlockBox) 
{
+            KnuthBlockBox kbb = (KnuthBlockBox) labelList.get(0);
+            if (kbb.getWidth() == 0 && kbb.hasFloatAnchors()) {
+                List<FloatContentLayoutManager> floats = 
kbb.getFloatContentLMs();
+                returnedList.add(new KnuthBlockBox(0, Collections.emptyList(), 
null, false, floats));
+                Keep keep = getKeepTogether();
+                returnedList.add(new BreakElement(new LeafPosition(this, 0), 
keep.getPenalty(), keep
+                        .getContext(), context));
+                labelList.remove(0);
+                labelList.remove(0);
+            }
+        }
+        if (!bodyList.isEmpty() && bodyList.get(0) instanceof KnuthBlockBox) {
+            KnuthBlockBox kbb = (KnuthBlockBox) bodyList.get(0);
+            if (kbb.getWidth() == 0 && kbb.hasFloatAnchors()) {
+                List<FloatContentLayoutManager> floats = 
kbb.getFloatContentLMs();
+                returnedList.add(new KnuthBlockBox(0, Collections.emptyList(), 
null, false, floats));
+                Keep keep = getKeepTogether();
+                returnedList.add(new BreakElement(new LeafPosition(this, 0), 
keep.getPenalty(), keep
+                        .getContext(), context));
+                bodyList.remove(0);
+                bodyList.remove(0);
+            }
+        }
+
         // create a combined list
-        List returnedList = getCombinedKnuthElementsForListItem(labelList, 
bodyList, context);
+        returnedList.addAll(getCombinedKnuthElementsForListItem(labelList, 
bodyList, context));
 
         // "wrap" the Position inside each element
         wrapPositionElements(returnedList, returnList, true);
@@ -298,7 +391,9 @@ public class ListItemLayoutManager exten
             int additionalPenaltyHeight = 0;
             int stepPenalty = 0;
             int breakClass = EN_AUTO;
-            KnuthElement endEl = (KnuthElement)elementLists[0].get(end[0]);
+            KnuthElement endEl = elementLists[0].size() > 0 ? (KnuthElement) 
elementLists[0].get(end[0])
+                    : null;
+            Position originalLabelPosition = endEl != null ? 
endEl.getPosition().getPosition() : null;
             if (endEl instanceof KnuthPenalty) {
                 additionalPenaltyHeight = endEl.getWidth();
                 stepPenalty = endEl.getPenalty() == -KnuthElement.INFINITE ? 
-KnuthElement.INFINITE : Math
@@ -306,7 +401,8 @@ public class ListItemLayoutManager exten
                 breakClass = BreakUtil.compareBreakClasses(breakClass,
                         ((KnuthPenalty) endEl).getBreakClass());
             }
-            endEl = (KnuthElement)elementLists[1].get(end[1]);
+            endEl = elementLists[1].size() > 0 ? (KnuthElement) 
elementLists[1].get(end[1]) : null;
+            Position originalBodyPosition = endEl != null ? 
endEl.getPosition().getPosition() : null;
             if (endEl instanceof KnuthPenalty) {
                 additionalPenaltyHeight = Math.max(
                         additionalPenaltyHeight, endEl.getWidth());
@@ -327,13 +423,26 @@ public class ListItemLayoutManager exten
                 
footnoteList.addAll(FootenoteUtil.getFootnotes(elementLists[i], start[i], 
end[i]));
             }
 
+            LinkedList<FloatContentLayoutManager> floats = new 
LinkedList<FloatContentLayoutManager>();
+            for (int i = 0; i < elementLists.length; i++) {
+                
floats.addAll(FloatContentLayoutManager.checkForFloats(elementLists[i], 
start[i], end[i]));
+            }
+
             // add the new elements
             addedBoxHeight += boxHeight;
-            ListItemPosition stepPosition = new ListItemPosition(this,
-                    start[0], end[0], start[1], end[1]);
-            if (footnoteList.isEmpty()) {
-                returnList.add(new KnuthBox(boxHeight, stepPosition, false));
+            ListItemPosition stepPosition = new ListItemPosition(this, 
start[0], end[0], start[1], end[1]);
+            stepPosition.setOriginalLabelPosition(originalLabelPosition);
+            stepPosition.setOriginalBodyPosition(originalBodyPosition);
+
+            if (floats.isEmpty()) {
+                returnList.add(new KnuthBlockBox(boxHeight, footnoteList, 
stepPosition, false));
             } else {
+                // add a line with height zero and no content and attach float 
to it
+                returnList.add(new KnuthBlockBox(0, Collections.emptyList(), 
stepPosition, false, floats));
+                // add a break element to signal that we should restart LB at 
this break
+                Keep keep = getKeepTogether();
+                returnList.add(new BreakElement(stepPosition, 
keep.getPenalty(), keep.getContext(), context));
+                // add the original line where the float was but without the 
float now
                 returnList.add(new KnuthBlockBox(boxHeight, footnoteList, 
stepPosition, false));
             }
 
@@ -512,6 +621,10 @@ public class ListItemLayoutManager exten
                 positionList.add(pos.getPosition());
             }
         }
+        if (positionList.isEmpty()) {
+            reset();
+            return;
+        }
 
         registerMarkers(true, isFirst(firstPos), isLast(lastPos));
 
@@ -674,5 +787,9 @@ public class ListItemLayoutManager exten
         return breakBefore;
     }
 
+    /** {@inheritDoc} */
+    public boolean isRestartable() {
+        return true;
+    }
 }
 

Modified: 
xmlgraphics/fop/trunk/test/java/org/apache/fop/layoutengine/LayoutEngineTestCase.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/java/org/apache/fop/layoutengine/LayoutEngineTestCase.java?rev=1642793&r1=1642792&r2=1642793&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/test/java/org/apache/fop/layoutengine/LayoutEngineTestCase.java
 (original)
+++ 
xmlgraphics/fop/trunk/test/java/org/apache/fop/layoutengine/LayoutEngineTestCase.java
 Tue Dec  2 00:29:57 2014
@@ -323,7 +323,11 @@ public class LayoutEngineTestCase {
             throw new RuntimeException("No available area tree check");
         }
         for (LayoutEngineCheck check : checks) {
-            check.check(result);
+            try {
+                check.check(result);
+            } catch (RuntimeException rte) {
+                throw new RuntimeException("Layout test (" + 
testFile.getName() + "): " + rte.getMessage());
+            }
         }
     }
 



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to