]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
New member variable "index" on Position (used for first/last checks).
authorJeremias Maerki <jeremias@apache.org>
Mon, 30 May 2005 09:11:10 +0000 (09:11 +0000)
committerJeremias Maerki <jeremias@apache.org>
Mon, 30 May 2005 09:11:10 +0000 (09:11 +0000)
Position numbering implemented in BlockStackingLayoutManager (see member variables: lastGeneratedPosition and smallestPosNumberChecked)
Use notifyPos to give a Position an index (Don't reuse Position instances that get an index!)
Flags on TableContentPosition indicating first and last status (see TableStepper).
New way of determining first/last area implemented on all currently implemented block-level FOs.
Removed obsolete isBogus() method from LayoutManager.
Removed duplicate wrapPositionElements() method in FlowLayoutManager.
Some javadocs here and there.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@198701 13f79535-47bb-0310-9956-ffa450edef68

21 files changed:
src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java
src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java
src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
src/java/org/apache/fop/layoutmgr/BlockLevelLayoutManager.java
src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java
src/java/org/apache/fop/layoutmgr/LayoutManager.java
src/java/org/apache/fop/layoutmgr/LeafPosition.java
src/java/org/apache/fop/layoutmgr/NonLeafPosition.java
src/java/org/apache/fop/layoutmgr/Position.java
src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java
src/java/org/apache/fop/layoutmgr/list/Item.java
src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
src/java/org/apache/fop/layoutmgr/table/Cell.java
src/java/org/apache/fop/layoutmgr/table/EffRow.java
src/java/org/apache/fop/layoutmgr/table/GridUnit.java
src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java
src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
src/java/org/apache/fop/layoutmgr/table/TableStepper.java

index c43a9eda5e2c9cd4636959aabad4571e241091ac..4541a1be5a70e4993f43bb525f4797ec9d6f7265 100644 (file)
@@ -47,13 +47,6 @@ public abstract class AbstractLayoutManager implements LayoutManager, Constants
     private boolean bFinished = false;
     protected boolean bInited = false;
     
-    /**
-     * Used during addAreas(): signals that a BreakPoss is not generating areas
-     * and therefore shouldn't add IDs and markers to the current page.
-     * @see org.apache.fop.layoutmgr.AbstractLayoutManager#isBogus
-     */
-    protected boolean bBogus = false;
-
     /** child LM and child LM iterator during getNextBreakPoss phase */
     protected LayoutManager curChildLM = null;
     protected ListIterator childLMiter = null;
@@ -114,15 +107,6 @@ public abstract class AbstractLayoutManager implements LayoutManager, Constants
         return false;
     }
 
-    /** @see org.apache.fop.layoutmgr.LayoutManager#isBogus() */
-    public boolean isBogus() {
-        if (getParent().isBogus()) {
-            return true;
-        } else {
-            return bBogus;
-        }
-    }
-    
     /**
      * Return currently active child LayoutManager or null if
      * all children have finished layout.
index 57c1dba2e1d26f852701fb038c9ad08dc1075f21..13198cae84d8762a96656816c4fa384e92991718 100644 (file)
@@ -37,11 +37,14 @@ public class AreaAdditionUtil {
         }
     }
 
-    public static void addAreas(PositionIterator parentIter, LayoutContext layoutContext) {
+    public static void addAreas(BlockStackingLayoutManager bslm, 
+            PositionIterator parentIter, LayoutContext layoutContext) {
         LayoutManager childLM = null;
         LayoutContext lc = new LayoutContext(0);
         LayoutManager firstLM = null;
         LayoutManager lastLM = null;
+        Position firstPos = null;
+        Position lastPos = null;
 
         // "unwrap" the NonLeafPositions stored in parentIter
         // and put them in a new list; 
@@ -49,6 +52,12 @@ public class AreaAdditionUtil {
         Position pos;
         while (parentIter.hasNext()) {
             pos = (Position)parentIter.next();
+            if (pos.getIndex() >= 0) {
+                if (firstPos == null) {
+                    firstPos = pos;
+                }
+                lastPos = pos;
+            }
             if (pos instanceof NonLeafPosition) {
                 // pos was created by a child of this FlowLM
                 positionList.add(((NonLeafPosition) pos).getPosition());
@@ -60,6 +69,11 @@ public class AreaAdditionUtil {
                 // pos was created by this LM, so it must be ignored
             }
         }
+        
+        if (bslm.markers != null) {
+            bslm.getCurrentPV().addMarkers(bslm.markers, true, 
+                    bslm.isFirst(firstPos), bslm.isLast(lastPos));
+        }
 
         StackingIter childPosIter = new StackingIter(positionList.listIterator());
         while ((childLM = childPosIter.getNextChildLM()) != null) {
@@ -75,6 +89,11 @@ public class AreaAdditionUtil {
             lc.setStackLimit(layoutContext.getStackLimit());
             childLM.addAreas(childPosIter, lc);
         }
+        if (bslm.markers != null) {
+            bslm.getCurrentPV().addMarkers(bslm.markers, false, 
+                    bslm.isFirst(firstPos), bslm.isLast(lastPos));
+        }
+        
     }
     
 }
index d9e06a5ff736364d82ebc9bd5a678212f24f0eab..6c83e599e8fe019683547e483a7828c7ecd6ce72 100644 (file)
@@ -195,11 +195,10 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager {
         LinkedList returnedList = null;
         LinkedList contentList = new LinkedList();
         LinkedList returnList = new LinkedList();
-        Position returnPosition = new NonLeafPosition(this, null);
         
         if (!bBreakBeforeServed) {
             try {
-                if (addKnuthElementsForBreakBefore(returnList, returnPosition)) {
+                if (addKnuthElementsForBreakBefore(returnList)) {
                     return returnList;
                 }
             } finally {
@@ -208,11 +207,11 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager {
         }
 
         if (!bSpaceBeforeServed) {
-            addKnuthElementsForSpaceBefore(returnList, returnPosition, alignment);
+            addKnuthElementsForSpaceBefore(returnList, alignment);
             bSpaceBeforeServed = true;
         }
         
-        addKnuthElementsForBorderPaddingBefore(returnList, returnPosition);
+        addKnuthElementsForBorderPaddingBefore(returnList);
 
         if (autoHeight) {
             BlockLevelLayoutManager curLM; // currently active LM
@@ -306,7 +305,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager {
             }
 
             Position bcPosition = new BlockContainerPosition(this, breaker);
-            returnList.add(new KnuthBox(vpContentBPD, bcPosition, false));
+            returnList.add(new KnuthBox(vpContentBPD, notifyPos(bcPosition), false));
             //TODO Handle min/opt/max for block-progression-dimension
             /* These two elements will be used to add stretchability to the above box
             returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE, 
@@ -325,9 +324,9 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager {
                 }
             }
         }
-        addKnuthElementsForBorderPaddingAfter(returnList, returnPosition);
-        addKnuthElementsForSpaceAfter(returnList, returnPosition, alignment);
-        addKnuthElementsForBreakAfter(returnList, returnPosition);
+        addKnuthElementsForBorderPaddingAfter(returnList);
+        addKnuthElementsForSpaceAfter(returnList, alignment);
+        addKnuthElementsForBreakAfter(returnList);
 
         setFinished(true);
         return returnList;
@@ -402,7 +401,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager {
         LinkedList returnList = new LinkedList();
         if (!breaker.isEmpty()) {
             Position bcPosition = new BlockContainerPosition(this, breaker);
-            returnList.add(new KnuthBox(0, bcPosition, false));
+            returnList.add(new KnuthBox(0, notifyPos(bcPosition), false));
     
             //TODO Maybe check for page overflow when autoHeight=true
             if (!autoHeight & (contentOverflows/*usedBPD > relDims.bpd*/)) {
@@ -504,7 +503,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager {
         }
         
         protected void addAreas(PositionIterator posIter, LayoutContext context) {
-            AreaAdditionUtil.addAreas(posIter, context);    
+            AreaAdditionUtil.addAreas(bclm, posIter, context);    
         }
         
         protected void doPhase3(PageBreakingAlgorithm alg, int partCount, 
@@ -562,10 +561,6 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager {
             addBlockSpacing(0.0, new MinOptMax(layoutContext.getSpaceBefore()));
         }
 
-        getPSLM().addIDToPage(getBlockContainerFO().getId());
-        //addMarkersToPV(true, bp1.isFirstArea(), bp1.isLastArea());
-        getCurrentPV().addMarkers(markers, true, true, false);
-
         LayoutManager childLM = null;
         LayoutManager lastLM = null;
         LayoutContext lc = new LayoutContext(0);
@@ -582,9 +577,17 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager {
         Position pos;
         boolean bSpaceBefore = false;
         boolean bSpaceAfter = false;
+        Position firstPos = null;
+        Position lastPos = null;
         while (parentIter.hasNext()) {
             pos = (Position) parentIter.next();
-            /* LF *///System.out.println("pos = " + pos.getClass().getName());
+            //System.out.println("pos = " + pos.getClass().getName());
+            if (pos.getIndex() >= 0) {
+                if (firstPos == null) {
+                    firstPos = pos;
+                }
+                lastPos = pos;
+            }
             Position innerPosition = null;
             if (pos instanceof NonLeafPosition) {
                 innerPosition = ((NonLeafPosition)pos).getPosition();
@@ -626,6 +629,11 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager {
             }
         }
 
+        getPSLM().addIDToPage(getBlockContainerFO().getId());
+        if (markers != null) {
+            getCurrentPV().addMarkers(markers, true, isFirst(firstPos), isLast(lastPos));
+        }
+
         if (bcpos == null) {
             if (bpUnit == 0) {
                 // the Positions in positionList were inside the elements
@@ -726,7 +734,9 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager {
         //int bIndents = getBlockContainerFO().getCommonBorderPaddingBackground()
         //    .getBPPaddingAndBorder(false);
 
-        getCurrentPV().addMarkers(markers, false, false, true);
+        if (markers != null) {
+            getCurrentPV().addMarkers(markers, false, isFirst(firstPos), isLast(lastPos));
+        }
 
         flush();
 
index b7352367b4c647ce49d4fdcca8a6a2d8fa01280e..371bf53b5e5557370cc4543731195dd6a77f403a 100644 (file)
@@ -201,7 +201,7 @@ public class BlockLayoutManager extends BlockStackingLayoutManager {
 
     public void addAreas(PositionIterator parentIter,
             LayoutContext layoutContext) {
-        /* LF *///System.out.println(" BLM.addAreas>");
+        //System.out.println(" BLM.addAreas>");
         getParentArea(null);
 
         // if this will create the first block area in a page
@@ -210,18 +210,14 @@ public class BlockLayoutManager extends BlockStackingLayoutManager {
             addBlockSpacing(0.0, new MinOptMax(layoutContext.getSpaceBefore()));
         }
 
-        getPSLM().addIDToPage(getBlockFO().getId());
-        //addMarkersToPV(true, bp1.isFirstArea(), bp1.isLastArea());
-        getCurrentPV().addMarkers(markers, true, true, false);
-
         LayoutManager childLM = null;
         LayoutManager lastLM = null;
         LayoutContext lc = new LayoutContext(0);
-        /* LF */// set space after in the LayoutContext for children
-        /* LF */if (layoutContext.getSpaceAfter() > 0) {
-            /* LF */lc.setSpaceAfter(layoutContext.getSpaceAfter());
-            /* LF */}
-        /* LF */PositionIterator childPosIter;
+        // set space after in the LayoutContext for children
+        if (layoutContext.getSpaceAfter() > 0) {
+            lc.setSpaceAfter(layoutContext.getSpaceAfter());
+        }
+        PositionIterator childPosIter;
 
         // "unwrap" the NonLeafPositions stored in parentIter
         // and put them in a new list;
@@ -229,9 +225,17 @@ public class BlockLayoutManager extends BlockStackingLayoutManager {
         Position pos;
         boolean bSpaceBefore = false;
         boolean bSpaceAfter = false;
+        Position firstPos = null;
+        Position lastPos = null;
         while (parentIter.hasNext()) {
             pos = (Position) parentIter.next();
             //log.trace("pos = " + pos.getClass().getName() + "; " + pos);
+            if (pos.getIndex() >= 0) {
+                if (firstPos == null) {
+                    firstPos = pos;
+                }
+                lastPos = pos;
+            }
             Position innerPosition = pos;
             if (pos instanceof NonLeafPosition) {
                 //Not all elements are wrapped
@@ -264,6 +268,17 @@ public class BlockLayoutManager extends BlockStackingLayoutManager {
             }
         }
 
+        getPSLM().addIDToPage(getBlockFO().getId());
+        /* TODO remove when markers are really ok
+        log.debug("Checking on " + this);
+        log.debug("Checking first=" + firstPos);
+        log.debug("Checking last=" + lastPos);
+        log.debug("->" + isFirst(firstPos) + "/" + isLast(lastPos));
+        */
+        if (markers != null) {
+            getCurrentPV().addMarkers(markers, true, isFirst(firstPos), isLast(lastPos));
+        }
+
         if (bpUnit == 0) {
             // the Positions in positionList were inside the elements
             // created by the LineLM
@@ -345,14 +360,16 @@ public class BlockLayoutManager extends BlockStackingLayoutManager {
             // set last area flag
             lc.setFlags(LayoutContext.LAST_AREA,
                     (layoutContext.isLastArea() && childLM == lastLM));
-            /*LF*/lc.setStackLimit(layoutContext.getStackLimit());
+            lc.setStackLimit(layoutContext.getStackLimit());
             // Add the line areas to Area
             childLM.addAreas(childPosIter, lc);
         }
 
-        int bIndents = getBlockFO().getCommonBorderPaddingBackground().getBPPaddingAndBorder(false);
+        //int bIndents = getBlockFO().getCommonBorderPaddingBackground().getBPPaddingAndBorder(false);
 
-        getCurrentPV().addMarkers(markers, false, false, true);
+        if (markers != null) {
+            getCurrentPV().addMarkers(markers, false, isFirst(firstPos), isLast(lastPos));
+        }
 
         flush();
 
index a523830dd376c924a481b0e5bfa93caf9351bfa6..ffba6ffbf5b3c4ad7279ea3a032af06f6eea0352 100644 (file)
@@ -23,11 +23,16 @@ package org.apache.fop.layoutmgr;
  */
 public interface BlockLevelLayoutManager extends LayoutManager {
 
-    static final int NO_ADJUSTMENT = -1;
-    static final int SPACE_BEFORE_ADJUSTMENT = 0;
-    static final int SPACE_AFTER_ADJUSTMENT = 1;
-    static final int LINE_NUMBER_ADJUSTMENT = 2;
-    static final int LINE_HEIGHT_ADJUSTMENT = 3;
+    /** Adjustment class: no adjustment */
+    int NO_ADJUSTMENT = -1;
+    /** Adjustment class: adjustment for space-before */
+    int SPACE_BEFORE_ADJUSTMENT = 0;
+    /** Adjustment class: adjustment for space-after */
+    int SPACE_AFTER_ADJUSTMENT = 1;
+    /** Adjustment class: adjustment for number of lines */
+    int LINE_NUMBER_ADJUSTMENT = 2;
+    /** Adjustment class: adjustment for line height */
+    int LINE_HEIGHT_ADJUSTMENT = 3;
 
     int negotiateBPDAdjustment(int adj, KnuthElement lastElement);
 
index 23a5a02bd476a5832b76f05e31364467f3b8359a..e36f22c9ba586a6868dd633fabec9b334a40dcd8 100644 (file)
@@ -61,7 +61,12 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
     protected boolean bSpaceBeforeServed = false;
     /** Reference IPD available */
     protected int referenceIPD = 0;
+    
+    private int lastGeneratedPosition = -1;
+    private int smallestPosNumberChecked = Integer.MAX_VALUE;
 
+    private Position auxiliaryPosition;
+    
     public BlockStackingLayoutManager(FObj node) {
         super(node);
         fobj = node;
@@ -158,6 +163,63 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
         }
     }
 
+    /**
+     * Adds a Position to the Position participating in the first|last determination by assigning
+     * it a unique position index.
+     * @param pos the Position
+     * @return the same Position but with a position index
+     */
+    protected Position notifyPos(Position pos) {
+        if (pos.getIndex() >= 0) {
+            throw new IllegalStateException("Position already got its index");
+        }
+        lastGeneratedPosition++;
+        pos.setIndex(lastGeneratedPosition);
+        return pos;
+    }
+    
+    /**
+     * Indicates whether the given Position is the first area-generating Position of this LM.
+     * @param pos the Position (must be one with a position index)
+     * @return True if it is the first Position
+     */
+    public boolean isFirst(Position pos) {
+        //log.trace("isFirst() smallestPosNumberChecked=" + smallestPosNumberChecked + " " + pos);
+        if (pos.getIndex() < 0) {
+            throw new IllegalArgumentException("Only Positions with an index can be checked");
+        }
+        if (pos.getIndex() == this.smallestPosNumberChecked) {
+            return true;
+        } else if (pos.getIndex() < this.smallestPosNumberChecked) {
+            this.smallestPosNumberChecked = pos.getIndex();
+            return true;
+        } else {
+            return false;
+        }
+    }
+    
+    /**
+     * Indicates whether the given Position is the last area-generating Position of this LM.
+     * @param pos the Position (must be one with a position index)
+     * @return True if it is the last Position
+     */
+    public boolean isLast(Position pos) {
+        //log.trace("isLast() lastGenPos=" + lastGeneratedPosition + " " + pos);
+        if (pos.getIndex() < 0) {
+            throw new IllegalArgumentException("Only Positions with an index can be checked");
+        }
+        return (pos.getIndex() == this.lastGeneratedPosition
+                && isFinished());
+    }
+
+    /** @return a cached auxiliary Position instance used for things like spaces. */
+    protected Position getAuxiliaryPosition() {
+        if (this.auxiliaryPosition == null) {
+            this.auxiliaryPosition = new NonLeafPosition(this, null);
+        }
+        return this.auxiliaryPosition;
+    }
+    
     /**
      * @param len length in millipoints to span with bp units
      * @return the minimum integer n such that n * bpUnit >= len
@@ -196,11 +258,10 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
         LinkedList returnedList = null;
         LinkedList contentList = new LinkedList();
         LinkedList returnList = new LinkedList();
-        Position returnPosition = new NonLeafPosition(this, null);
 
         if (!bBreakBeforeServed) {
             try {
-                if (addKnuthElementsForBreakBefore(returnList, returnPosition)) {
+                if (addKnuthElementsForBreakBefore(returnList)) {
                     return returnList;
                 }
             } finally {
@@ -209,11 +270,11 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
         }
 
         if (!bSpaceBeforeServed) {
-            addKnuthElementsForSpaceBefore(returnList, returnPosition, alignment);
+            addKnuthElementsForSpaceBefore(returnList, alignment);
             bSpaceBeforeServed = true;
         }
         
-        addKnuthElementsForBorderPaddingBefore(returnList, returnPosition);
+        addKnuthElementsForBorderPaddingBefore(returnList);
         
         while ((curLM = (BlockLevelLayoutManager) getChildLM()) != null) {
             LayoutContext childLC = new LayoutContext(0);
@@ -344,12 +405,12 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
             wrapPositionElements(contentList, returnList);
         } else {
             //Empty fo:block, zero-length box makes sure the IDs are registered.
-            returnList.add(new KnuthBox(0, new Position(this), true));
+            returnList.add(new KnuthBox(0, notifyPos(new Position(this)), true));
         }
 
-        addKnuthElementsForBorderPaddingAfter(returnList, returnPosition);
-        addKnuthElementsForSpaceAfter(returnList, returnPosition, alignment);
-        addKnuthElementsForBreakAfter(returnList, returnPosition);
+        addKnuthElementsForBorderPaddingAfter(returnList);
+        addKnuthElementsForSpaceAfter(returnList, alignment);
+        addKnuthElementsForBreakAfter(returnList);
 
         if (mustKeepWithNext()) {
             context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING);
@@ -701,8 +762,8 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
      * @param returnList return list to add the additional elements to
      * @param returnPosition applicable return position
      */
-    protected void addKnuthElementsForBorderPaddingBefore(LinkedList returnList, 
-            Position returnPosition) {
+    protected void addKnuthElementsForBorderPaddingBefore(LinkedList returnList/*
+            Position returnPosition*/) {
         //Border and Padding (before)
         CommonBorderPaddingBackground borderAndPadding = null;
         if (fobj instanceof org.apache.fop.fo.flow.Block) {
@@ -717,7 +778,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
             int bpBefore = borderAndPadding.getBorderBeforeWidth(false)
                          + borderAndPadding.getPaddingBefore(false);
             if (bpBefore > 0) {
-                returnList.add(new KnuthBox(bpBefore, returnPosition, true));
+                returnList.add(new KnuthBox(bpBefore, getAuxiliaryPosition(), true));
             }
         }
     }
@@ -727,8 +788,8 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
      * @param returnList return list to add the additional elements to
      * @param returnPosition applicable return position
      */
-    protected void addKnuthElementsForBorderPaddingAfter(LinkedList returnList, 
-            Position returnPosition) {
+    protected void addKnuthElementsForBorderPaddingAfter(LinkedList returnList/*
+            Position returnPosition*/) {
         //Border and Padding (after)
         CommonBorderPaddingBackground borderAndPadding = null;
         if (fobj instanceof org.apache.fop.fo.flow.Block) {
@@ -743,7 +804,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
             int bpAfter = borderAndPadding.getBorderAfterWidth(false)
                         + borderAndPadding.getPaddingAfter(false);
             if (bpAfter > 0) {
-                returnList.add(new KnuthBox(bpAfter, returnPosition, true));
+                returnList.add(new KnuthBox(bpAfter, getAuxiliaryPosition(), true));
             }
         }
     }
@@ -754,8 +815,8 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
      * @param returnPosition applicable return position
      * @return true if an element has been added due to a break-before.
      */
-    protected boolean addKnuthElementsForBreakBefore(LinkedList returnList, 
-            Position returnPosition) {
+    protected boolean addKnuthElementsForBreakBefore(LinkedList returnList/*
+            Position returnPosition*/) {
         int breakBefore = -1;
         if (fobj instanceof org.apache.fop.fo.flow.Block) {
             breakBefore = ((org.apache.fop.fo.flow.Block) fobj).getBreakBefore();
@@ -768,7 +829,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
                 || breakBefore == EN_ODD_PAGE) {
             // return a penalty element, representing a forced page break
             returnList.add(new KnuthPenalty(0, -KnuthElement.INFINITE, false,
-                    breakBefore, returnPosition, false));
+                    breakBefore, getAuxiliaryPosition(), false));
             return true;
         } else {
             return false;
@@ -781,8 +842,8 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
      * @param returnPosition applicable return position
      * @return true if an element has been added due to a break-after.
      */
-    protected boolean addKnuthElementsForBreakAfter(LinkedList returnList, 
-            Position returnPosition) {
+    protected boolean addKnuthElementsForBreakAfter(LinkedList returnList/*
+            Position returnPosition*/) {
         int breakAfter = -1;
         if (fobj instanceof org.apache.fop.fo.flow.Block) {
             breakAfter = ((org.apache.fop.fo.flow.Block) fobj).getBreakAfter();
@@ -795,7 +856,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
                 || breakAfter == EN_ODD_PAGE) {
             // add a penalty element, representing a forced page break
             returnList.add(new KnuthPenalty(0, -KnuthElement.INFINITE, false,
-                    breakAfter, returnPosition, false));
+                    breakAfter, getAuxiliaryPosition(), false));
             return true;
         } else {
             return false;
@@ -808,8 +869,8 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
      * @param returnPosition applicable return position
      * @param alignment vertical alignment
      */
-    protected void addKnuthElementsForSpaceBefore(LinkedList returnList, 
-            Position returnPosition, int alignment) {
+    protected void addKnuthElementsForSpaceBefore(LinkedList returnList/*
+            Position returnPosition*/, int alignment) {
         SpaceProperty spaceBefore = null;
         if (fobj instanceof org.apache.fop.fo.flow.Block) {
             spaceBefore = ((org.apache.fop.fo.flow.Block)fobj)
@@ -825,14 +886,14 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
                         && spaceBefore.getMaximum().getLength().getValue() == 0)) {
             if (spaceBefore != null && !spaceBefore.getSpace().isDiscard()) {
                 // add elements to prevent the glue to be discarded
-                returnList.add(new KnuthBox(0, returnPosition, false));
+                returnList.add(new KnuthBox(0, getAuxiliaryPosition(), false));
                 returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE,
-                        false, returnPosition, false));
+                        false, getAuxiliaryPosition(), false));
             }
             if (bpUnit > 0) {
                 returnList.add(new KnuthGlue(0, 0, 0,
                         BlockLevelLayoutManager.SPACE_BEFORE_ADJUSTMENT, 
-                        returnPosition, true));
+                        getAuxiliaryPosition(), true));
             } else /*if (alignment == EN_JUSTIFY)*/ {
                 returnList.add(new KnuthGlue(
                         spaceBefore.getOptimum().getLength().getValue(),
@@ -841,7 +902,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
                         spaceBefore.getOptimum().getLength().getValue()
                                 - spaceBefore.getMinimum().getLength().getValue(),
                         BlockLevelLayoutManager.SPACE_BEFORE_ADJUSTMENT, 
-                        returnPosition, true));
+                        getAuxiliaryPosition(), true));
             } /*else {
                 returnList.add(new KnuthGlue(
                         spaceBefore.getOptimum().getLength().getValue(), 
@@ -857,7 +918,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
      * @param returnPosition applicable return position
      * @param alignment vertical alignment
      */
-    protected void addKnuthElementsForSpaceAfter(LinkedList returnList, Position returnPosition
+    protected void addKnuthElementsForSpaceAfter(LinkedList returnList/*, Position returnPosition*/
                 int alignment) {
         SpaceProperty spaceAfter = null;
         if (fobj instanceof org.apache.fop.fo.flow.Block) {
@@ -874,12 +935,12 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
                         && spaceAfter.getMaximum().getLength().getValue() == 0)) {
             if (spaceAfter != null && !spaceAfter.getSpace().isDiscard()) {
                 returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE,
-                        false, returnPosition, false));
+                        false, getAuxiliaryPosition(), false));
             }
             if (bpUnit > 0) {
                 returnList.add(new KnuthGlue(0, 0, 0, 
                         BlockLevelLayoutManager.SPACE_AFTER_ADJUSTMENT,
-                        returnPosition, true));
+                        getAuxiliaryPosition(), true));
             } else /*if (alignment == EN_JUSTIFY)*/ {
                 returnList.add(new KnuthGlue(
                         spaceAfter.getOptimum().getLength().getValue(),
@@ -887,7 +948,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
                                 - spaceAfter.getOptimum().getLength().getValue(),
                         spaceAfter.getOptimum().getLength().getValue()
                                 - spaceAfter.getMinimum().getLength().getValue(),
-                        BlockLevelLayoutManager.SPACE_AFTER_ADJUSTMENT, returnPosition,
+                        BlockLevelLayoutManager.SPACE_AFTER_ADJUSTMENT, getAuxiliaryPosition(),
                         (!spaceAfter.getSpace().isDiscard()) ? false : true));
             } /*else {
                 returnList.add(new KnuthGlue(
@@ -896,7 +957,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
                         (!spaceAfter.getSpace().isDiscard()) ? false : true));
             }*/
             if (spaceAfter != null && !spaceAfter.getSpace().isDiscard()) {
-                returnList.add(new KnuthBox(0, returnPosition, true));
+                returnList.add(new KnuthBox(0, getAuxiliaryPosition(), true));
             }
         }
     }
@@ -1262,13 +1323,25 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
      * @param targetList target list receiving the wrapped position elements
      */
     protected void wrapPositionElements(List sourceList, List targetList) {
+        wrapPositionElements(sourceList, targetList, false);
+    }
+    
+    /**
+     * "wrap" the Position inside each element moving the elements from 
+     * SourceList to targetList
+     * @param sourceList source list
+     * @param targetList target list receiving the wrapped position elements
+     * @param force if true, every Position is wrapper regardless of its LM of origin
+     */
+    protected void wrapPositionElements(List sourceList, List targetList, boolean force) {
+          
         ListIterator listIter = sourceList.listIterator();
         while (listIter.hasNext()) {
             KnuthElement tempElement;
             tempElement = (KnuthElement) listIter.next();
-            if (tempElement.getLayoutManager() != this) {
-                tempElement.setPosition(new NonLeafPosition(this,
-                        tempElement.getPosition()));
+            if (force || tempElement.getLayoutManager() != this) {
+                tempElement.setPosition(notifyPos(new NonLeafPosition(this,
+                        tempElement.getPosition())));
             }
             targetList.add(tempElement);
         }
index 5a69104f31a1548bb190922abfc9019eae719d28..423c8e98d82622deb5374e709adcab5605d15be8 100644 (file)
@@ -57,25 +57,6 @@ public class FlowLayoutManager extends BlockStackingLayoutManager
         fobj = node;
     }
 
-    /**
-     * "wrap" the Position inside each element moving the elements from 
-     * SourceList to targetList
-     * @param sourceList source list
-     * @param targetList target list receiving the wrapped position elements
-     */
-    protected void wrapPositionElements(List sourceList, List targetList) {
-        ListIterator listIter = sourceList.listIterator();
-        while (listIter.hasNext()) {
-            KnuthElement tempElement;
-            tempElement = (KnuthElement) listIter.next();
-            //if (tempElement.getLayoutManager() != this) {
-            tempElement.setPosition(new NonLeafPosition(this,
-                    tempElement.getPosition()));
-            //}
-            targetList.add(tempElement);
-        }
-    }
-
     /** @see org.apache.fop.layoutmgr.LayoutManager */
     public LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
         // set layout dimensions
@@ -296,7 +277,7 @@ public class FlowLayoutManager extends BlockStackingLayoutManager
      * @see org.apache.fop.layoutmgr.LayoutManager#addAreas(PositionIterator, LayoutContext)
      */
     public void addAreas(PositionIterator parentIter, LayoutContext layoutContext) {
-        AreaAdditionUtil.addAreas(parentIter, layoutContext);
+        AreaAdditionUtil.addAreas(this, parentIter, layoutContext);
         flush();
     }
 
index bd8ec91ebbb3497a3f68ebc1ad811920b4bee692..56d39dda1747a365f42b5c52c336e749c0a86088 100644 (file)
@@ -50,6 +50,7 @@ public interface LayoutManager {
     /**
      * Get the active PageSequenceLayoutManager instance for this
      * layout process.
+     * @return the PageSequenceLayoutManager
      */
     PageSequenceLayoutManager getPSLM();
 
@@ -62,17 +63,6 @@ public interface LayoutManager {
      */
     boolean generatesInlineAreas();
 
-    /**
-     * This method is used during the stage where addAreas() converts BreakPoss
-     * instances to areas. It is used to skip adding IDs and markers to a page
-     * when the current BreakPoss/area was only generated to signal a break
-     * situation. This avoids adding IDs and markers to the wrong pages.
-     * @todo This is a hack. This should be handled differently in the long term.
-     * @return true if the current BreakPoss/area was only generated to signal
-     *     break situations.
-     */
-    boolean isBogus();
-    
     /**
      * Return true if the next area which would be generated by this
      * LayoutManager could start a new line (or flow for block-level FO).
@@ -85,7 +75,7 @@ public interface LayoutManager {
     /**
      * Reset to the position.
      *
-     * @param position
+     * @param position the Position to reset to
      */
     void resetPosition(Position position);
 
index d4375501f3e924f96ef577fa007b0b72fa7fa140..f2f46b43c639e622008f9b58929fd20a451027fc 100644 (file)
@@ -31,11 +31,16 @@ public class LeafPosition extends Position {
         return iLeafPos;
     }
     
+    public boolean generatesAreas() {
+        return getLM() != null;
+    }
+    
     /** @see java.lang.Object#toString()*/
     public String toString() {
-        StringBuffer sb = new StringBuffer(super.toString());
-        sb.append(" {pos=").append(getLeafPos());
-        sb.append(", lm=").append(getLM()).append("}");
+        StringBuffer sb = new StringBuffer();
+        sb.append("LeafPos:").append(getIndex()).append("(");
+        sb.append("pos=").append(getLeafPos());
+        sb.append(", lm=").append(getShortLMName()).append(")");
         return sb.toString();
     }
 }
index 7f21a54d31ffeb02f5bf590e68a9c109671b487a..d78dc695556afb61fe3458ab48184e837e7c646a 100644 (file)
@@ -31,10 +31,16 @@ public class NonLeafPosition extends Position {
         return subPos;
     }
     
+    public boolean generatesAreas() {
+        return (subPos != null ? subPos.generatesAreas() : false);
+    }
+    
     /** @see java.lang.Object#toString() */
     public String toString() {
         StringBuffer sb = new StringBuffer();
-        sb.append("NonLeafPos(");
+        sb.append("NonLeafPos:").append(getIndex()).append("(");
+        sb.append(getShortLMName());
+        sb.append(", ");
         if (getPosition() != null) {
             sb.append(getPosition().toString());
         } else {
index 40fc573a957c8c24c29c862f70ddea9217e71c4c..700b8f41cec4435bc792fec7116e0c7565a21698 100644 (file)
@@ -21,6 +21,7 @@ package org.apache.fop.layoutmgr;
 public class Position {
     
     private LayoutManager layoutManager;
+    private int index = -1;
 
     public Position(LayoutManager lm) {
         layoutManager = lm;
@@ -38,16 +39,38 @@ public class Position {
         return null;
     }
     
+    public boolean generatesAreas() {
+        return false;
+    }
+    
+    public void setIndex(int value) {
+        this.index = value;
+    }
+    
+    public int getIndex() {
+        return this.index;
+    }
+    
+    public String getShortLMName() {
+        if (getLM() != null) {
+            String lm = getLM().toString();
+            int idx = lm.lastIndexOf('.');
+            if (idx >= 0 && lm.indexOf('@') > 0) {
+                return(lm.substring(idx + 1));
+            } else {
+                return lm;
+            }
+        } else {
+            return "null";
+        }
+    }
     
     /** @see java.lang.Object#toString() */
     public String toString() {
         StringBuffer sb = new StringBuffer();
-        sb.append("Position");
-        if (getLM() != null) {
-            sb.append(" {");
-            sb.append(getLM());
-            sb.append("}");
-        }
+        sb.append("Position:").append(getIndex()).append("(");
+        sb.append(getShortLMName());
+        sb.append(")");
         return sb.toString();
     }
 }
index c712de22870915a025ad17098d24495bd9de765e..16914757edcaf29fe01cd47217b84d5f3e406ae9 100644 (file)
@@ -155,7 +155,7 @@ public class StaticContentLayoutManager extends BlockStackingLayoutManager {
      * @see org.apache.fop.layoutmgr.LayoutManager#addAreas(PositionIterator, LayoutContext)
      */
     public void addAreas(PositionIterator parentIter, LayoutContext layoutContext) {
-        AreaAdditionUtil.addAreas(parentIter, layoutContext);
+        AreaAdditionUtil.addAreas(this, parentIter, layoutContext);
 
         flush();
         targetRegion = null;
@@ -267,7 +267,7 @@ public class StaticContentLayoutManager extends BlockStackingLayoutManager {
         }
         
         protected void addAreas(PositionIterator posIter, LayoutContext context) {
-            AreaAdditionUtil.addAreas(posIter, context);    
+            AreaAdditionUtil.addAreas(lm, posIter, context);    
         }
         
         protected void doPhase3(PageBreakingAlgorithm alg, int partCount, 
index 16a9ab3f31ece3aa9efefec408b0c995536d648b..4911f557d7535e12070dfb973a1a26d038d3441c 100644 (file)
@@ -118,6 +118,8 @@ public class Item extends BlockStackingLayoutManager {
         LayoutContext lc = new LayoutContext(0);
         LayoutManager firstLM = null;
         LayoutManager lastLM = null;
+        Position firstPos = null;
+        Position lastPos = null;
 
         // "unwrap" the NonLeafPositions stored in parentIter
         // and put them in a new list; 
@@ -125,6 +127,12 @@ public class Item extends BlockStackingLayoutManager {
         Position pos;
         while (parentIter.hasNext()) {
             pos = (Position)parentIter.next();
+            if (pos.getIndex() >= 0) {
+                if (firstPos == null) {
+                    firstPos = pos;
+                }
+                lastPos = pos;
+            }
             if (pos instanceof NonLeafPosition) {
                 // pos was created by a child of this ListBlockLM
                 positionList.add(((NonLeafPosition) pos).getPosition());
@@ -137,6 +145,10 @@ public class Item extends BlockStackingLayoutManager {
             }
         }
 
+        if (markers != null) {
+            getCurrentPV().addMarkers(markers, true, isFirst(firstPos), isLast(lastPos));
+        }
+        
         StackingIter childPosIter = new StackingIter(positionList.listIterator());
         while ((childLM = childPosIter.getNextChildLM()) != null) {
             // Add the block areas to Area
@@ -146,6 +158,10 @@ public class Item extends BlockStackingLayoutManager {
             childLM.addAreas(childPosIter, lc);
         }
 
+        if (markers != null) {
+            getCurrentPV().addMarkers(markers, false, isFirst(firstPos), isLast(lastPos));
+        }
+
         flush();
 
         curBlockArea = null;
index 848d1500205f0256c2a0481846c696300f0871f2..6870ccec8154e54f47d54e018d3dc938ad7b4ee1 100644 (file)
@@ -131,6 +131,8 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager {
         LayoutContext lc = new LayoutContext(0);
         LayoutManager firstLM = null;
         LayoutManager lastLM = null;
+        Position firstPos = null;
+        Position lastPos = null;
 
         // "unwrap" the NonLeafPositions stored in parentIter
         // and put them in a new list; 
@@ -138,6 +140,12 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager {
         Position pos;
         while (parentIter.hasNext()) {
             pos = (Position)parentIter.next();
+            if (pos.getIndex() >= 0) {
+                if (firstPos == null) {
+                    firstPos = pos;
+                }
+                lastPos = pos;
+            }
             if (pos instanceof NonLeafPosition
                 && ((NonLeafPosition) pos).getPosition().getLM() != this) {
                 // pos was created by a child of this ListBlockLM
@@ -149,6 +157,10 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager {
             }
         }
 
+        if (markers != null) {
+            getCurrentPV().addMarkers(markers, true, isFirst(firstPos), isLast(lastPos));
+        }
+
         StackingIter childPosIter = new StackingIter(positionList.listIterator());
         while ((childLM = childPosIter.getNextChildLM()) != null) {
             // Add the block areas to Area
@@ -158,6 +170,10 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager {
             childLM.addAreas(childPosIter, lc);
         }
 
+        if (markers != null) {
+            getCurrentPV().addMarkers(markers, false, isFirst(firstPos), isLast(lastPos));
+        }
+
         flush();
 
         // if adjusted space after
index 06da89d4b9ba4271ea46c6b588df59aa903cca65..32f56bbe57f4d1efe5380b0fcbc37b883be4b4b5 100644 (file)
@@ -104,6 +104,16 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager {
         public int getBodyLastIndex() {
             return iBodyLastIndex;
         }
+        
+        /** @see java.lang.Object#toString() */
+        public String toString() {
+            StringBuffer sb = new StringBuffer("ListItemPosition:");
+            sb.append(getIndex()).append("(");
+            sb.append("label:").append(iLabelFirstIndex).append("-").append(iLabelLastIndex);
+            sb.append(" body:").append(iBodyFirstIndex).append("-").append(iBodyLastIndex);
+            sb.append(")");
+            return sb.toString();
+        }
     }
 
     /**
@@ -184,14 +194,8 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager {
 
         // "wrap" the Position inside each element
         LinkedList 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);
-        }
+        wrapPositionElements(tempList, returnedList, true);
         
         if (keepWithNextPendingOnLabel || keepWithNextPendingOnBody || mustKeepWithNext()) {
             context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING);
@@ -422,18 +426,30 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager {
         getPSLM().addIDToPage(getListItemFO().getId());
 
         LayoutContext lc = new LayoutContext(0);
+        Position firstPos = null;
+        Position lastPos = null;
 
         // "unwrap" the NonLeafPositions stored in parentIter
         LinkedList positionList = new LinkedList();
         Position pos;
         while (parentIter.hasNext()) {
             pos = (Position) parentIter.next();
+            if (pos.getIndex() >= 0) {
+                if (firstPos == null) {
+                    firstPos = pos;
+                }
+                lastPos = pos;
+            }
             if (pos instanceof NonLeafPosition) {
                 // pos contains a ListItemPosition created by this ListBlockLM
                 positionList.add(((NonLeafPosition) pos).getPosition());
             }
         }
 
+        if (markers != null) {
+            getCurrentPV().addMarkers(markers, true, isFirst(firstPos), isLast(lastPos));
+        }
+
         // use the first and the last ListItemPosition to determine the 
         // corresponding indexes in the original labelList and bodyList
         int labelFirstIndex = ((ListItemPosition) positionList.getFirst()).getLabelFirstIndex();
@@ -476,6 +492,10 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager {
             curBlockArea.setBPD(savedBPD);
         }
 
+        if (markers != null) {
+            getCurrentPV().addMarkers(markers, false, isFirst(firstPos), isLast(lastPos));
+        }
+
         flush();
 
         // if adjusted space after
index d2b86c157573cd82cccf92fac683aec100ee6c20..cb2f00c2e96e6680d5d1fe501c1b517328acc72f 100644 (file)
@@ -19,7 +19,6 @@
 package org.apache.fop.layoutmgr.table;
 
 import java.util.LinkedList;
-import java.util.List;
 
 import org.apache.fop.fo.FONode;
 import org.apache.fop.fo.flow.Table;
@@ -63,9 +62,6 @@ public class Cell extends BlockStackingLayoutManager implements BlockLevelLayout
     private int borderAndPaddingBPD;
     private boolean emptyCell = true;
 
-    /** List of Lists containing OldGridUnit instances, one List per row. */
-    private List rows = new java.util.ArrayList(); 
-    
     /**
      * Create a new Cell layout manager.
      * @param node table-cell FO for which to create the LM
@@ -113,16 +109,6 @@ public class Cell extends BlockStackingLayoutManager implements BlockLevelLayout
     }
     
 
-    /**
-     * Called by Row LM to register the grid units occupied by this cell for a row.
-     * @param spannedGridUnits a List of GridUnits
-     */
-    public void addGridUnitsFromRow(List spannedGridUnits) {
-        log.debug("Getting another row, " + spannedGridUnits.size() + " grid units");
-        this.rows.add(spannedGridUnits);
-        
-    }
-
     private int getIPIndents() {
         int iIndents = 0;
         int[] startEndBorderWidths = gridUnit.getStartEndBorderWidths();
@@ -331,11 +317,8 @@ public class Cell extends BlockStackingLayoutManager implements BlockLevelLayout
     public void addAreas(PositionIterator parentIter,
                          LayoutContext layoutContext) {
         getParentArea(null);
-        bBogus = false; //!bp1.generatesAreas(); 
 
-        if (!isBogus()) {
-            getPSLM().addIDToPage(fobj.getId());
-        }
+        getPSLM().addIDToPage(fobj.getId());
 
         if (isSeparateBorderModel()) {
             if (!emptyCell || fobj.showEmptyCells()) {
@@ -381,7 +364,6 @@ public class Cell extends BlockStackingLayoutManager implements BlockLevelLayout
                                     - (gu.getBorders().getBorderAfterWidth(false) / 2);
                         }
                         block.setBPD(bpd);
-                        //TODO This needs to be fixed for row spanning
                         lastRowHeight = rowHeight;
                         int ipd = gu.getColumn().getColumnWidth().getValue();
                         int borderStartWidth = gu.getBorders().getBorderStartWidth(false) / 2; 
@@ -418,7 +400,7 @@ public class Cell extends BlockStackingLayoutManager implements BlockLevelLayout
             }
         }
 
-        AreaAdditionUtil.addAreas(parentIter, layoutContext);
+        AreaAdditionUtil.addAreas(this, parentIter, layoutContext);
         
         int contentBPD = getContentHeight(rowHeight, gridUnit);
         curBlockArea.setBPD(contentBPD);
index bdb2a6747d4bb997879bbe03b2f82fb7ebb13a17..ddb2a47cb9e137800f629ba831fc860b57bceac1 100644 (file)
@@ -29,41 +29,68 @@ import org.apache.fop.traits.MinOptMax;
  */
 public class EffRow {
     
+    /** Indicates that the row is the first in a table-body */
+    public static final int FIRST_IN_BODY = GridUnit.FIRST_IN_BODY;
+    /** Indicates that the row is the last in a table-body */
+    public static final int LAST_IN_BODY = GridUnit.LAST_IN_BODY;
+    
     private List gridUnits = new java.util.ArrayList();
     private int index;
     private int bodyType;
     private MinOptMax height;
     private MinOptMax explicitHeight;
     
+    /**
+     * Creates a new effective row instance.
+     * @param index index of the row
+     * @param bodyType type of body (one of HEADER, FOOTER, BODY as found on TableRowIterator)
+     */
     public EffRow(int index, int bodyType) {
         this.index = index;
         this.bodyType = bodyType;
     }
     
+    /** @return the index of the EffRow in the sequence of rows */
     public int getIndex() {
         return this.index;
     }
     
+    /**
+     * @return an indicator what type of body this EffRow is in (one of HEADER, FOOTER, BODY 
+     * as found on TableRowIterator)
+     */
     public int getBodyType() {
         return this.bodyType;
     }
     
+    /** @return the calculated height for this EffRow. */
     public MinOptMax getHeight() {
         return this.height;
     }
     
+    /**
+     * Sets the calculated height for this EffRow.
+     * @param mom the calculated height
+     */
     public void setHeight(MinOptMax mom) {
         this.height = mom;
     }
     
+    /** @return the explicit height of the EffRow (as specified through properties) */
     public MinOptMax getExplicitHeight() {
         return this.explicitHeight;
     }
     
+    /**
+     * Sets the height for this row that resulted from the explicit height properties specified
+     * by the user.
+     * @param mom the height
+     */
     public void setExplicitHeight(MinOptMax mom) {
         this.explicitHeight = mom;
     }
     
+    /** @return the list of GridUnits for this EffRow */
     public List getGridUnits() {
         return gridUnits;
     }
@@ -92,6 +119,11 @@ public class EffRow {
         }
     }
     
+    /**
+     * Sets a flag on all grid units of this effective row.
+     * @param flag which flag to set (on of the GridUnit.* constants)
+     * @param value new value for the flag
+     */
     public void setFlagForAllGridUnits(int flag, boolean value) {
         Iterator iter = gridUnits.iterator();
         while (iter.hasNext()) {
@@ -100,6 +132,22 @@ public class EffRow {
         }
     }
 
+    /**
+     * Returns a flag for this effective row. Only a subset of the flags on GridUnit is supported.
+     * The flag is determined by inspecting flags on the EffRow's GridUnits.
+     * @param which the requested flag
+     * @return true if the flag is set
+     */
+    public boolean getFlag(int which) {
+        if (which == FIRST_IN_BODY) {
+            return getGridUnit(0).getFlag(GridUnit.FIRST_IN_BODY);
+        } else if (which == LAST_IN_BODY) {
+            return getGridUnit(0).getFlag(GridUnit.LAST_IN_BODY);
+        } else {
+            throw new IllegalArgumentException("Illegal flag queried: " +  which);
+        }
+    }
+    
     /** @see java.lang.Object#toString() */
     public String toString() {
         StringBuffer sb = new StringBuffer("EffRow {");
index d51681c3b7efe9d0109c8ac630426cac64a815e8..fce7498631353dd31f383c08e8996cb8751283fb 100644 (file)
@@ -244,10 +244,20 @@ public class GridUnit {
                         side, resFlags), side);
     }
     
+    /**
+     * Returns a flag for this GridUnit.
+     * @param which the requested flag
+     * @return the value of the flag
+     */
     public boolean getFlag(int which) {
         return (flags & (1 << which)) != 0;
     }
     
+    /**
+     * Sets a flag on a GridUnit.
+     * @param which the flag to set
+     * @param value the new value for the flag
+     */
     public void setFlag(int which, boolean value) {
         if (value) {
             flags |= (1 << which); //set flag
index d804904570416a0c3c8e273c2f0a720779a1439f..0381b4eddb11cd8328aa628d39e89e380d3776ec 100644 (file)
@@ -29,6 +29,7 @@ import org.apache.commons.logging.LogFactory;
 import org.apache.fop.area.Block;
 import org.apache.fop.area.Trait;
 import org.apache.fop.fo.flow.Table;
+import org.apache.fop.fo.flow.TableBody;
 import org.apache.fop.fo.flow.TableRow;
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 import org.apache.fop.fo.properties.LengthRangeProperty;
@@ -500,28 +501,22 @@ public class TableContentLayoutManager {
         RowPainter painter = new RowPainter(layoutContext);
 
         List positions = new java.util.ArrayList();
+        List headerElements = null;
         List footerElements = null;
+        Position firstPos = null;
         Position lastPos = null;
         while (parentIter.hasNext()) {
             Position pos = (Position)parentIter.next();
+            if (firstPos == null) {
+                firstPos = pos;
+            }
             lastPos = pos;
             if (pos instanceof TableHeaderFooterPosition) {
                 TableHeaderFooterPosition thfpos = (TableHeaderFooterPosition)pos;
                 //these positions need to be unpacked
                 if (thfpos.header) {
-                    //header positions for the last part are the second-to-last element and need to
-                    //be handled first before all other TableContentPositions
-                    PositionIterator nestedIter = new KnuthPossPosIter(thfpos.nestedElements);
-                    while (nestedIter.hasNext()) {
-                        Position containedPos = (Position)nestedIter.next();
-                        if (containedPos instanceof TableContentPosition) {
-                            TableContentPosition tcpos = (TableContentPosition)containedPos;
-                            painter.handleTableContentPosition(tcpos);
-                        } else {
-                            log.debug("Ignoring position: " + containedPos);
-                        }
-                    }
-                    painter.addAreasAndFlushRow(true);
+                    //Positions for header will be added first
+                    headerElements = thfpos.nestedElements;
                 } else {
                     //Positions for footers are simply added at the end
                     footerElements = thfpos.nestedElements;
@@ -540,54 +535,102 @@ public class TableContentLayoutManager {
             if (penaltyPos.headerElements != null) {
                 //Header positions for the penalty position are in the last element and need to
                 //be handled first before all other TableContentPositions
-                PositionIterator nestedIter = new KnuthPossPosIter(penaltyPos.headerElements);
-                while (nestedIter.hasNext()) {
-                    Position containedPos = (Position)nestedIter.next();
-                    if (containedPos instanceof TableContentPosition) {
-                        TableContentPosition tcpos = (TableContentPosition)containedPos;
-                        painter.handleTableContentPosition(tcpos);
-                    } else {
-                        log.debug("Ignoring position: " + containedPos);
-                    }
-                }
-                painter.addAreasAndFlushRow(true);
+                headerElements = penaltyPos.headerElements;
             }
             if (penaltyPos.footerElements != null) {
                 footerElements = penaltyPos.footerElements; 
             }
         }
 
+        Map markers = getTableLM().getTable().getMarkers();
+        if (markers != null) {
+            getTableLM().getCurrentPV().addMarkers(markers, 
+                    true, getTableLM().isFirst(firstPos), getTableLM().isLast(lastPos));
+        }
         
-        Iterator posIter = positions.iterator();
-        //Iterate over all steps
-        while (posIter.hasNext()) {
-            Position pos = (Position)posIter.next();
-            if (pos instanceof TableContentPosition) {
-                TableContentPosition tcpos = (TableContentPosition)pos;
-                painter.handleTableContentPosition(tcpos);
-            } else {
-                log.debug("Ignoring position: " + pos);
-            }
+        if (headerElements != null) {
+            //header positions for the last part are the second-to-last element and need to
+            //be handled first before all other TableContentPositions
+            PositionIterator nestedIter = new KnuthPossPosIter(headerElements);
+            iterateAndPaintPositions(nestedIter, painter);
+            painter.addAreasAndFlushRow(true);
         }
+        
+        //Iterate over all steps
+        Iterator posIter = positions.iterator();
+        iterateAndPaintPositions(posIter, painter);
         painter.addAreasAndFlushRow(true);
 
         if (footerElements != null) {
             //Positions for footers are simply added at the end
-            PositionIterator iter = new KnuthPossPosIter(footerElements);
-            while (iter.hasNext()) {
-                Position pos = (Position)iter.next();
-                if (pos instanceof TableContentPosition) {
-                    TableContentPosition tcpos = (TableContentPosition)pos;
-                    painter.handleTableContentPosition(tcpos);
-                } else {
-                    log.debug("Ignoring position: " + pos);
-                }
-            }
+            PositionIterator nestedIter = new KnuthPossPosIter(footerElements);
+            iterateAndPaintPositions(nestedIter, painter);
             painter.addAreasAndFlushRow(true);
         }
         
         painter.notifyEndOfSequence();
         this.usedBPD += painter.getAccumulatedBPD();
+
+        if (markers != null) {
+            getTableLM().getCurrentPV().addMarkers(markers, 
+                    false, getTableLM().isFirst(firstPos), getTableLM().isLast(lastPos));
+        }
+    }
+    
+    private void iterateAndPaintPositions(Iterator iterator, RowPainter painter) {
+        List lst = new java.util.ArrayList();
+        boolean firstPos = false;
+        boolean lastPos = false;
+        TableBody body = null;
+        while (iterator.hasNext()) {
+            Position pos = (Position)iterator.next();
+            //System.out.println(pos);
+            if (pos instanceof TableContentPosition) {
+                TableContentPosition tcpos = (TableContentPosition)pos;
+                lst.add(tcpos);
+                //System.out.println(tcpos.row);
+                GridUnitPart part = (GridUnitPart)tcpos.gridUnitParts.get(0);
+                if (body == null) {
+                    body = part.pgu.getBody();
+                }
+                if (tcpos.getFlag(TableContentPosition.FIRST_IN_ROWGROUP) 
+                        && tcpos.row.getFlag(EffRow.FIRST_IN_BODY)) {
+                    //System.out.println("pgu is first in body");
+                    firstPos = true;
+
+                }
+                if (tcpos.getFlag(TableContentPosition.LAST_IN_ROWGROUP) 
+                        && tcpos.row.getFlag(EffRow.LAST_IN_BODY)) {
+                    //System.out.println("pgu is last in body");
+                    lastPos = true;
+                    getTableLM().getCurrentPV().addMarkers(body.getMarkers(), 
+                            true, firstPos, lastPos);
+                    int size = lst.size();
+                    for (int i = 0; i < size; i++) {
+                        painter.handleTableContentPosition((TableContentPosition)lst.get(i));
+                    }
+                    getTableLM().getCurrentPV().addMarkers(body.getMarkers(), 
+                            false, firstPos, lastPos);
+                    //reset
+                    firstPos = false;
+                    lastPos = false;
+                    body = null;
+                    lst.clear();
+                }
+            } else {
+                log.debug("Ignoring position: " + pos);
+            }
+        }
+        if (body != null) {
+            getTableLM().getCurrentPV().addMarkers(body.getMarkers(), 
+                    true, firstPos, lastPos);
+            int size = lst.size();
+            for (int i = 0; i < size; i++) {
+                painter.handleTableContentPosition((TableContentPosition)lst.get(i));
+            }
+            getTableLM().getCurrentPV().addMarkers(body.getMarkers(), 
+                    false, firstPos, lastPos);
+        }
     }
    
     private class RowPainter {
@@ -828,11 +871,22 @@ public class TableContentLayoutManager {
             this.end = end;
         }
         
+        /** @return true if this part is the first part of a cell */
+        public boolean isFirstPart() {
+            return (start == 0);
+        }
+        
+        /** @return true if this part is the last part of a cell */
+        public boolean isLastPart() {
+            return (end >= 0 && end == pgu.getElements().size() - 1);
+        }
+        
         /** @see java.lang.Object#toString() */
         public String toString() {
             StringBuffer sb = new StringBuffer("Part: ");
             sb.append(start).append("-").append(end);
-            sb.append(" ").append(pgu);
+            sb.append(" [").append(isFirstPart() ? "F" : "-").append(isLastPart() ? "L" : "-");
+            sb.append("] ").append(pgu);
             return sb.toString();
         }
         
@@ -844,10 +898,17 @@ public class TableContentLayoutManager {
      */
     public static class TableContentPosition extends Position {
 
+        /** The position is the first of the row group. */ 
+        public static final int FIRST_IN_ROWGROUP = 1;
+        /** The position is the last of the row group. */ 
+        public static final int LAST_IN_ROWGROUP = 2;
+        
         /** the list of GridUnitParts making up this position */
         protected List gridUnitParts;
         /** effective row this position belongs to */
         protected EffRow row;
+        /** flags for the position */
+        protected int flags;
         
         /**
          * Creates a new TableContentPosition.
@@ -862,11 +923,37 @@ public class TableContentLayoutManager {
             this.row = row;
         }
         
+        /**
+         * Returns a flag for this GridUnit.
+         * @param which the requested flag
+         * @return the value of the flag
+         */
+        public boolean getFlag(int which) {
+            return (flags & (1 << which)) != 0;
+        }
+        
+        /**
+         * Sets a flag on a GridUnit.
+         * @param which the flag to set
+         * @param value the new value for the flag
+         */
+        public void setFlag(int which, boolean value) {
+            if (value) {
+                flags |= (1 << which); //set flag
+            } else {
+                flags &= ~(1 << which); //clear flag
+            }
+        }
+        
         /** @see java.lang.Object#toString() */
         public String toString() {
-            StringBuffer sb = new StringBuffer("TableContentPosition {");
+            StringBuffer sb = new StringBuffer("TableContentPosition:");
+            sb.append(getIndex());
+            sb.append("[").append(getFlag(FIRST_IN_ROWGROUP) ? "F" : "-");
+            sb.append((getFlag(LAST_IN_ROWGROUP) ? "L" : "-")).append("]");
+            sb.append("(");
             sb.append(gridUnitParts);
-            sb.append("}");
+            sb.append(")");
             return sb.toString();
         }
     }
@@ -899,9 +986,10 @@ public class TableContentLayoutManager {
         public String toString() {
             StringBuffer sb = new StringBuffer("Table");
             sb.append(header ? "Header" : "Footer");
-            sb.append("Position {");
+            sb.append("Position:");
+            sb.append(getIndex()).append("(");
             sb.append(nestedElements);
-            sb.append("}");
+            sb.append(")");
             return sb.toString();
         }
     }
@@ -927,13 +1015,13 @@ public class TableContentLayoutManager {
         
         /** @see java.lang.Object#toString() */
         public String toString() {
-            StringBuffer sb = new StringBuffer("TableHFPenaltyPosition");
-            sb.append(" {");
+            StringBuffer sb = new StringBuffer("TableHFPenaltyPosition:");
+            sb.append(getIndex()).append("(");
             sb.append("header:");
             sb.append(headerElements);
             sb.append(", footer:");
             sb.append(footerElements);
-            sb.append("}");
+            sb.append(")");
             return sb.toString();
         }
     }
index d9bcfc81e0d25f211baa8623edd3460786a7a5e7..76e3fbdfeb81b5f0ba31616f9db3dafa53cc74e0 100644 (file)
@@ -190,6 +190,13 @@ public class TableLayoutManager extends BlockStackingLayoutManager
             log.debug("TableContentLM signals pending keep-with-previous");
             context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
         }
+        
+        //Set index values on elements coming from the content LM
+        Iterator iter = returnedList.iterator();
+        while (iter.hasNext()) {
+            KnuthElement el = (KnuthElement)iter.next();
+            notifyPos(el.getPosition());
+        }
         log.debug(returnedList);
         
         if (returnedList.size() == 1
index 0d8d947a936529da34eaed3a1a033542e595920d..55a3c1b1b0a18bae4b81ee9a3c2f85d0f44e24ad 100644 (file)
@@ -198,6 +198,7 @@ public class TableStepper {
         int laststep = 0;
         int step;
         int addedBoxLen = 0;
+        TableContentPosition lastTCPos = null;
         LinkedList returnList = new LinkedList();
         while ((step = getNextStep(laststep)) >= 0) {
             if (rowBacktrackForLastStep) {
@@ -262,6 +263,10 @@ public class TableStepper {
             }
             TableContentPosition tcpos = new TableContentPosition(getTableLM(), 
                     gridUnitParts, getActiveRow());
+            if (returnList.size() == 0) {
+                tcpos.setFlag(TableContentPosition.FIRST_IN_ROWGROUP, true);
+            }
+            lastTCPos = tcpos;
             log.debug(" - " + rowBacktrackForLastStep + " - " + activeRow + " - " + tcpos);
             returnList.add(new KnuthBox(boxLen, tcpos, false));
             TableHFPenaltyPosition penaltyPos = new TableHFPenaltyPosition(getTableLM());
@@ -301,6 +306,7 @@ public class TableStepper {
             //we have to signal the still pending last keep-with-next using the LayoutContext.
             context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING);
         }
+        lastTCPos.setFlag(TableContentPosition.LAST_IN_ROWGROUP, true);
         return returnList;
     }