]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Small improvements of the table layout code:
authorVincent Hennebert <vhennebert@apache.org>
Fri, 24 Nov 2006 17:32:48 +0000 (17:32 +0000)
committerVincent Hennebert <vhennebert@apache.org>
Fri, 24 Nov 2006 17:32:48 +0000 (17:32 +0000)
- javadoc
- code cleanup
- give more explicit names (I believe) to some variables
- remove whitespaces at ends of lines

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

src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java
src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModelEyeCatching.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/PrimaryGridUnit.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/TableRowIterator.java

index 53b90fea99df0a75f914d5cd8dd0d5a94cd05088..168a3b145d1544eb2442ed0094bb9d24cbdd8b5e 100755 (executable)
@@ -249,18 +249,34 @@ public class CommonBorderPaddingBackground implements Cloneable {
         return this.fopimage;
     }
     
+    /**
+     * @param bDiscard indicates whether the .conditionality component should be
+     * considered (start of a reference-area)
+     */
     public int getBorderStartWidth(boolean bDiscard) {
         return getBorderWidth(START, bDiscard);
     }
 
+    /**
+     * @param bDiscard indicates whether the .conditionality component should be
+     * considered (end of a reference-area)
+     */
     public int getBorderEndWidth(boolean bDiscard) {
         return getBorderWidth(END, bDiscard);
     }
 
+    /**
+     * @param bDiscard indicates whether the .conditionality component should be
+     * considered (start of a reference-area)
+     */
     public int getBorderBeforeWidth(boolean bDiscard) {
         return getBorderWidth(BEFORE, bDiscard);
     }
 
+    /**
+     * @param bDiscard indicates whether the .conditionality component should be
+     * considered (end of a reference-area)
+     */
     public int getBorderAfterWidth(boolean bDiscard) {
         return getBorderWidth(AFTER, bDiscard);
     }
index 7b81ad47846bc15dabf3027abfcf6d925a845cb2..ca6939e56038ba5856e8a5b358e900b79ebea215 100644 (file)
@@ -1444,7 +1444,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
      * 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
+     * @param force if true, every Position is wrapped regardless of its LM of origin
      */
     protected void wrapPositionElements(List sourceList, List targetList, boolean force) {
           
index e1f573162a48951b89ffc32b2a28be6ea4441077..cf57947fb601700d884b4c730fc1cfdbe33fa4ed 100644 (file)
@@ -98,8 +98,8 @@ public class CollapsingBorderModelEyeCatching extends CollapsingBorderModel {
             other[1] = otherRow.getCommonBorderPaddingBackground().getBorderInfo(otherSide);
         }
         if (currentBody != null
-                && ((side == BEFORE && currentGridUnit.getFlag(GridUnit.FIRST_IN_BODY))
-                || (side == AFTER && currentGridUnit.getFlag(GridUnit.LAST_IN_BODY))
+                && ((side == BEFORE && currentGridUnit.getFlag(GridUnit.FIRST_IN_PART))
+                || (side == AFTER && currentGridUnit.getFlag(GridUnit.LAST_IN_PART))
                 || (currentGridUnit.getFlag(GridUnit.IN_FIRST_COLUMN) && side == START)
                 || (currentGridUnit.getFlag(GridUnit.IN_LAST_COLUMN) && side == END))) {
             //row group (=body, table-header or table-footer)
@@ -107,8 +107,8 @@ public class CollapsingBorderModelEyeCatching extends CollapsingBorderModel {
         }
         if (otherGridUnit != null
                 && otherBody != null
-                && ((otherSide == BEFORE && otherGridUnit.getFlag(GridUnit.FIRST_IN_BODY))
-                    || (otherSide == AFTER && otherGridUnit.getFlag(GridUnit.LAST_IN_BODY)))) {
+                && ((otherSide == BEFORE && otherGridUnit.getFlag(GridUnit.FIRST_IN_PART))
+                    || (otherSide == AFTER && otherGridUnit.getFlag(GridUnit.LAST_IN_PART)))) {
             //row group (=body, table-header or table-footer)
             other[2] = otherBody.getCommonBorderPaddingBackground().getBorderInfo(otherSide);
         }
index 982ba8c45706967a925c4a085efb74b5e705baa0..1e184e767ee367821e38878a460292f1cdded419 100644 (file)
@@ -29,15 +29,16 @@ import org.apache.fop.traits.MinOptMax;
  * This class represents an effective row in a table and holds a list of grid units occupying
  * the row as well as some additional values.
  */
-public class EffRow {
+class EffRow {
     
     /** Indicates that the row is the first in a table-body */
-    public static final int FIRST_IN_BODY = GridUnit.FIRST_IN_BODY;
+    public static final int FIRST_IN_PART = GridUnit.FIRST_IN_PART;
     /** Indicates that the row is the last in a table-body */
-    public static final int LAST_IN_BODY = GridUnit.LAST_IN_BODY;
+    public static final int LAST_IN_PART = GridUnit.LAST_IN_PART;
     
     private List gridUnits = new java.util.ArrayList();
     private int index;
+    /** One of HEADER, FOOTER, BODY */
     private int bodyType;
     private MinOptMax height;
     private MinOptMax explicitHeight;
@@ -142,14 +143,15 @@ 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
+     * @param which the requested flag (one of {@link EffRow#FIRST_IN_PART} or {@link
+     * EffRow#LAST_IN_PART})
      * @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);
+        if (which == FIRST_IN_PART) {
+            return getGridUnit(0).getFlag(GridUnit.FIRST_IN_PART);
+        } else if (which == LAST_IN_PART) {
+            return getGridUnit(0).getFlag(GridUnit.LAST_IN_PART);
         } else {
             throw new IllegalArgumentException("Illegal flag queried: " +  which);
         }
@@ -172,4 +174,4 @@ public class EffRow {
         sb.append("}");
         return sb.toString();
     }
-}
\ No newline at end of file
+}
index 2716f13f3f8996a83496dd2d9d003e0abc730753..029e9c93ca05f921a9d5fc1b92c97a100f6af49d 100644 (file)
@@ -37,28 +37,28 @@ public class GridUnit {
     public static final int IN_FIRST_COLUMN = 0;
     /** Indicates that the grid unit is in the last column. */
     public static final int IN_LAST_COLUMN = 1;
-    /** Indicates that the grid unit is in the first row (context: table). */
+    /** Indicates that the grid unit is in the first row of the table. */
     public static final int FIRST_IN_TABLE = 2;
-    /** Indicates that the grid unit is in the first row (context: body). */
-    public static final int FIRST_IN_BODY = 3;
-    /** Indicates that the grid unit is in the last row (context: body). */
-    public static final int LAST_IN_BODY = 4;
-    /** Indicates that the grid unit is in the last row (context: table). */
+    /** Indicates that the grid unit is in the first row of the table part (header, footer, body). */
+    public static final int FIRST_IN_PART = 3;
+    /** Indicates that the grid unit is in the last row of the table part (header, footer, body). */
+    public static final int LAST_IN_PART = 4;
+    /** Indicates that the grid unit is in the last row of the table. */
     public static final int LAST_IN_TABLE = 5;
     /** Indicates that the primary grid unit has a pending keep-with-next. */
     public static final int KEEP_WITH_NEXT_PENDING = 6;
     /** Indicates that the primary grid unit has a pending keep-with-previous. */
     public static final int KEEP_WITH_PREVIOUS_PENDING = 7;
-    
+
     /** Primary grid unit */
     private PrimaryGridUnit primary;
     /** Table cell which occupies this grid unit */
     private TableCell cell;
-    /** Table row which occupied this grid unit (may be null) */
+    /** Table row which occupies this grid unit (may be null) */
     private TableRow row;
     /** Table column that this grid unit belongs to */
     private TableColumn column;
-    
+
     /** start index of grid unit within row in column direction */
     private int startCol;
     /** index of grid unit within cell in column direction */
@@ -69,16 +69,41 @@ public class GridUnit {
     private CommonBorderPaddingBackground effectiveBorders;
     /** flags for the grid unit */
     private byte flags = 0;
-    
-    
+
+
+    /**
+     * Creates a new grid unit.
+     *
+     * @param cell table cell which occupies this grid unit
+     * @param column table column this grid unit belongs to
+     * @param startCol index of the column this grid unit belongs to
+     * @param colSpanIndex index of this grid unit in the span, in column direction
+     */
     public GridUnit(TableCell cell, TableColumn column, int startCol, int colSpanIndex) {
         this(null, cell, column, startCol, colSpanIndex);
     }
-    
+
+    /**
+     * Creates a new grid unit.
+     *
+     * @param primary ??
+     * @param column table column this grid unit belongs to
+     * @param startCol index of the column this grid unit belongs to
+     * @param colSpanIndex index of this grid unit in the span, in column direction
+     */
     public GridUnit(PrimaryGridUnit primary, TableColumn column, int startCol, int colSpanIndex) {
         this(primary, primary.getCell(), column, startCol, colSpanIndex);
     }
-    
+
+    /**
+     * Creates a new grid unit.
+     *
+     * @param primary ??
+     * @param cell table cell which occupies this grid unit
+     * @param column table column this grid unit belongs to
+     * @param startCol index of the column this grid unit belongs to
+     * @param colSpanIndex index of this grid unit in the span, in column direction
+     */
     protected GridUnit(PrimaryGridUnit primary, TableCell cell, TableColumn column, int startCol, int colSpanIndex) {
         this.primary = primary;
         this.cell = cell;
@@ -86,15 +111,15 @@ public class GridUnit {
         this.startCol = startCol;
         this.colSpanIndex = colSpanIndex;
     }
-    
+
     public TableCell getCell() {
         return cell;
     }
-    
+
     public TableColumn getColumn() {
         return column;
     }
-    
+
     public TableRow getRow() {
         if (row != null) {
             return row;
@@ -104,7 +129,7 @@ public class GridUnit {
             return null;
         }
     }
-    
+
     /**
      * Sets the table-row FO, if applicable.
      * @param row the table-row FO
@@ -120,7 +145,7 @@ public class GridUnit {
         }
         return (TableBody)node;
     }
-    
+
     public Table getTable() {
         FONode node = getBody();
         while (node != null && !(node instanceof Table)) {
@@ -131,7 +156,7 @@ public class GridUnit {
         }
         return (Table)node;
     }
-    
+
     /**
      * @return the primary grid unit if this is a spanned grid unit
      */
@@ -142,15 +167,15 @@ public class GridUnit {
     public boolean isPrimary() {
         return false;
     }
-    
+
     public boolean isEmpty() {
         return cell == null;
     }
-    
+
     public int getStartCol() {
         return startCol;
     }
-    
+
     /** @return true if the grid unit is the last in column spanning direction */
     public boolean isLastGridUnitColSpan() {
         if (cell != null) {
@@ -159,8 +184,8 @@ public class GridUnit {
             return true;
         }
     }
-    
-    /** @return true if the grid unit is the last in column spanning direction */
+
+    /** @return true if the grid unit is the last in row spanning direction */
     public boolean isLastGridUnitRowSpan() {
         if (cell != null) {
             return (rowSpanIndex == cell.getNumberRowsSpanned() - 1);
@@ -168,14 +193,14 @@ public class GridUnit {
             return true;
         }
     }
-    
+
     /**
      * @return the index of the grid unit inside a cell in row direction
      */
     public int getRowSpanIndex() {
         return rowSpanIndex;
     }
-    
+
     /**
      * @return the index of the grid unit inside a cell in column direction
      */
@@ -186,7 +211,7 @@ public class GridUnit {
     /**
      * Returns a BorderInfo instance for a side of the currently applicable cell before border
      * resolution (i.e. the value from the FO). A return value of null indicates an empty cell.
-     * See CollapsingBorderModel(EyeCatching) where this method is used. 
+     * See CollapsingBorderModel(EyeCatching) where this method is used.
      * @param side for which side to return the BorderInfo
      * @return the requested BorderInfo instance or null if the grid unit is an empty cell
      */
@@ -197,21 +222,21 @@ public class GridUnit {
             return null;
         }
     }
-    
+
     /**
      * @return the resolved normal borders for this grid unit
      */
     public CommonBorderPaddingBackground getBorders() {
         return effectiveBorders;
     }
-    
+
     /**
      * @return true if the grid unit has any borders.
      */
     public boolean hasBorders() {
         return (getBorders() != null) && getBorders().hasBorder();
     }
-    
+
     /**
      * Assigns the borders from the given cell to this cell info. Used in
      * case of separate border model.
@@ -221,7 +246,7 @@ public class GridUnit {
             effectiveBorders = cell.getCommonBorderPaddingBackground();
         }
     }
-    
+
     /**
      * Resolve collapsing borders for the given cell. Used in case of the collapsing border model.
      * @param other neighbouring grid unit if any
@@ -230,7 +255,7 @@ public class GridUnit {
     public void resolveBorder(GridUnit other, int side) {
         resolveBorder(other, side, 0);
     }
-    
+
     /**
      * Resolve collapsing borders for the given cell. Used in case of the collapsing border model.
      * @param other neighbouring grid unit if any
@@ -243,13 +268,13 @@ public class GridUnit {
         if (effectiveBorders == null) {
             effectiveBorders = new CommonBorderPaddingBackground();
         }
-        effectiveBorders.setBorderInfo(borderModel.determineWinner(this, other, 
+        effectiveBorders.setBorderInfo(borderModel.determineWinner(this, other,
                         side, resFlags), side);
         if (cell != null) {
             effectiveBorders.setPadding(cell.getCommonBorderPaddingBackground());
         }
     }
-    
+
     /**
      * Returns a flag for this GridUnit.
      * @param which the requested flag
@@ -258,7 +283,7 @@ public class GridUnit {
     public boolean getFlag(int which) {
         return (flags & (1 << which)) != 0;
     }
-    
+
     /**
      * Sets a flag on a GridUnit.
      * @param which the flag to set
@@ -271,7 +296,7 @@ public class GridUnit {
             flags &= ~(1 << which); //clear flag
         }
     }
-    
+
     /**
      * @return the grid unit just below this grid unit if the cell is spanning.
      */
index 73f5e5acbff9c286e760d0d6eefe657c2add966c..19ccee59224d822d22255f0ee60e995683eaa02b 100644 (file)
@@ -36,11 +36,19 @@ public class PrimaryGridUnit extends GridUnit {
     private LinkedList elements;
     /** Index of row where this cell starts */
     private int startRow;
-    /** Links to the spanned grid units. (List of GridUnit arrays, one array represents a row) */ 
+    /** Links to the spanned grid units. (List of GridUnit arrays, one array represents a row) */
     private List rows;
     /** The calculated size of the cell's content. (cached value) */
     private int contentLength = -1;
-    
+
+    /**
+     * Creates a new primary grid unit.
+     *
+     * @param cell table cell which occupies this grid unit
+     * @param column table column this grid unit belongs to
+     * @param startCol index of the column this grid unit belongs to, zero-based
+     * @param startRow index of the row this grid unit belongs to, zero-based
+     */
     public PrimaryGridUnit(TableCell cell, TableColumn column, int startCol, int startRow) {
         super(cell, column, startCol, 0);
         this.startRow = startRow;
@@ -48,25 +56,30 @@ public class PrimaryGridUnit extends GridUnit {
             cellLM = new TableCellLayoutManager(cell, this);
         }
     }
-    
+
     public TableCellLayoutManager getCellLM() {
         return cellLM;
     }
-    
+
     public boolean isPrimary() {
         return true;
     }
-    
+
+    /**
+     * Sets the Knuth elements for the table cell containing this grid unit.
+     *
+     * @param elements a list of ListElement (?)
+     */
     public void setElements(LinkedList elements) {
         this.elements = elements;
     }
-    
+
     public LinkedList getElements() {
         return this.elements;
     }
-    
-    /** 
-     * @return Returns the half the maximum before border width of this cell.
+
+    /**
+     * @return half the maximum before border width of this cell.
      */
     public int getHalfMaxBeforeBorderWidth() {
         int value = 0;
@@ -76,7 +89,7 @@ public class PrimaryGridUnit extends GridUnit {
             GridUnit[] row = (GridUnit[])getRows().get(0);
             for (int i = 0; i < row.length; i++) {
                 if (row[i].hasBorders()) {
-                    before = Math.max(before, 
+                    before = Math.max(before,
                             row[i].getBorders().getBorderBeforeWidth(false));
                 }
             }
@@ -88,9 +101,9 @@ public class PrimaryGridUnit extends GridUnit {
         }
         return value;
     }
-    
-    /** 
-     * @return Returns the half the maximum after border width of this cell.
+
+    /**
+     * @return half the maximum after border width of this cell.
      */
     public int getHalfMaxAfterBorderWidth() {
         int value = 0;
@@ -111,21 +124,21 @@ public class PrimaryGridUnit extends GridUnit {
         }
         return value;
     }
-    
-    /** 
-     * @return Returns the sum of half the maximum before and after border 
+
+    /**
+     * @return the sum of half the maximum before and after border
      * widths of this cell.
      */
     public int getHalfMaxBorderWidth() {
         return getHalfMaxBeforeBorderWidth() + getHalfMaxAfterBorderWidth();
     }
-    
+
     /** @param value The length of the cell content to remember. */
     public void setContentLength(int value) {
         this.contentLength = value;
     }
-    
-    /** @return Returns the length of the cell content. */
+
+    /** @return the length of the cell content. */
     public int getContentLength() {
         return contentLength;
     }
@@ -135,28 +148,45 @@ public class PrimaryGridUnit extends GridUnit {
         if (!getCell().getBlockProgressionDimension().getOptimum(null).isAuto()) {
             return true;
         }
-        if (getRow() != null 
+        if (getRow() != null
                 && !getRow().getBlockProgressionDimension().getOptimum(null).isAuto()) {
             return true;
         }
         return false;
     }
 
+    /**
+     * Returns the grid units belonging to the same span as this one.
+     *
+     * @return a list of GridUnit[], each array corresponds to a row
+     */
     public List getRows() {
         return this.rows;
     }
-    
+
     public void addRow(GridUnit[] row) {
         if (rows == null) {
             rows = new java.util.ArrayList();
         }
         rows.add(row);
     }
-    
+
+    /**
+     * Returns the index of the row this grid unit belongs to.
+     *
+     * @return the index of the row this grid unit belongs to.
+     */
     public int getStartRow() {
         return this.startRow;
     }
 
+    /**
+     * Returns the widths of the start- and end-borders of the span this grid unit belongs
+     * to.
+     *
+     * @return a two-element array containing the widths of the start-border then the
+     * end-border
+     */
     public int[] getStartEndBorderWidths() {
         int[] widths = new int[2];
         if (rows == null) {
@@ -165,17 +195,17 @@ public class PrimaryGridUnit extends GridUnit {
         } else {
             for (int i = 0; i < rows.size(); i++) {
                 GridUnit[] gridUnits = (GridUnit[])rows.get(i);
-                widths[0] = Math.max(widths[0], 
+                widths[0] = Math.max(widths[0],
                         (gridUnits[0]).
                             getBorders().getBorderStartWidth(false));
-                widths[1] = Math.max(widths[1], 
+                widths[1] = Math.max(widths[1],
                         (gridUnits[gridUnits.length - 1]).
                             getBorders().getBorderEndWidth(false));
             }
         }
         return widths;
     }
-    
+
     /** @see java.lang.Object#toString() */
     public String toString() {
         StringBuffer sb = new StringBuffer(super.toString());
@@ -185,8 +215,8 @@ public class PrimaryGridUnit extends GridUnit {
 
     /** @return true if this cell spans over more than one grid unit. */
     public boolean hasSpanning() {
-        return (getCell().getNumberColumnsSpanned() > 1) 
+        return (getCell().getNumberColumnsSpanned() > 1)
             || (getCell().getNumberRowsSpanned() > 1);
     }
-    
+
 }
index e0eaf079e605cc498f1b9b93bc3ffa32399dbc6f..2ab9a1cde8a03b03c44a8cb5fc3580b664112343 100644 (file)
@@ -65,7 +65,7 @@ public class TableContentLayoutManager implements PercentBaseContext {
     private static Log log = LogFactory.getLog(TableContentLayoutManager.class);
 
     private TableLayoutManager tableLM;
-    private TableRowIterator trIter;
+    private TableRowIterator bodyIter;
     private TableRowIterator headerIter;
     private TableRowIterator footerIter;
     private LinkedList headerList;
@@ -86,7 +86,8 @@ public class TableContentLayoutManager implements PercentBaseContext {
     public TableContentLayoutManager(TableLayoutManager parent) {
         this.tableLM = parent;
         Table table = getTableLM().getTable();
-        this.trIter = new TableRowIterator(table, getTableLM().getColumns(), TableRowIterator.BODY);
+        this.bodyIter = new TableRowIterator(table, getTableLM().getColumns(),
+                TableRowIterator.BODY);
         if (table.getTableHeader() != null) {
             headerIter = new TableRowIterator(table, 
                     getTableLM().getColumns(), TableRowIterator.HEADER);
@@ -146,8 +147,8 @@ public class TableContentLayoutManager implements PercentBaseContext {
             this.headerList = getKnuthElementsForRowIterator(
                     headerIter, context, alignment, TableRowIterator.HEADER);
             ElementListUtils.removeLegalBreaks(this.headerList);
-            this.headerNetHeight = 
-                ElementListUtils.calcContentLength(this.headerList);
+            this.headerNetHeight
+                    = ElementListUtils.calcContentLength(this.headerList);
             if (log.isDebugEnabled()) {
                 log.debug("==> Header: " 
                         + headerNetHeight + " - " + this.headerList);
@@ -167,8 +168,8 @@ public class TableContentLayoutManager implements PercentBaseContext {
             this.footerList = getKnuthElementsForRowIterator(
                     footerIter, context, alignment, TableRowIterator.FOOTER);
             ElementListUtils.removeLegalBreaks(this.footerList);
-            this.footerNetHeight = 
-                    ElementListUtils.calcContentLength(this.footerList);
+            this.footerNetHeight
+                    ElementListUtils.calcContentLength(this.footerList);
             if (log.isDebugEnabled()) {
                 log.debug("==> Footer: " 
                         + footerNetHeight + " - " + this.footerList);
@@ -180,7 +181,7 @@ public class TableContentLayoutManager implements PercentBaseContext {
             footerAsLast = box;
         }
         LinkedList returnList = getKnuthElementsForRowIterator(
-                trIter, context, alignment, TableRowIterator.BODY);
+                bodyIter, context, alignment, TableRowIterator.BODY);
         if (headerAsFirst != null) {
             returnList.add(0, headerAsFirst);
         } else if (headerAsSecondToLast != null) {
@@ -312,36 +313,31 @@ public class TableContentLayoutManager implements PercentBaseContext {
             TableRowIterator iter) {
         for (int rgi = 0; rgi < rowGroup.length; rgi++) {
             EffRow row = rowGroup[rgi];
-            EffRow prev = iter.getCachedRow(row.getIndex() - 1);
-            EffRow next = iter.getCachedRow(row.getIndex() + 1);
-            if (next == null) {
-                //It wasn't read, yet, or we are at the last row
-                next = iter.getNextRow();
-                iter.backToPreviousRow();
+            EffRow prevRow = iter.getPrecedingRow(row);
+            EffRow nextRow = iter.getFollowingRow(row);
+            if ((prevRow == null) && (iter == this.bodyIter) && (this.headerIter != null)) {
+                prevRow = this.headerIter.getLastRow();
             }
-            if ((prev == null) && (iter == this.trIter) && (this.headerIter != null)) {
-                prev = this.headerIter.getLastRow();
+            if ((nextRow == null) && (iter == this.headerIter)) {
+                nextRow = this.bodyIter.getFirstRow();
             }
-            if ((next == null) && (iter == this.headerIter)) {
-                next = this.trIter.getFirstRow();
+            if ((nextRow == null) && (iter == this.bodyIter) && (this.footerIter != null)) {
+                nextRow = this.footerIter.getFirstRow();
             }
-            if ((next == null) && (iter == this.trIter) && (this.footerIter != null)) {
-                next = this.footerIter.getFirstRow();
-            }
-            if ((prev == null) && (iter == this.footerIter)) {
+            if ((prevRow == null) && (iter == this.footerIter)) {
                 //TODO This could be bad for memory consumption because it already causes the
                 //whole body iterator to be prefetched!
-                prev = this.trIter.getLastRow();
+                prevRow = this.bodyIter.getLastRow();
             }
-            log.debug(prev + " - " + row + " - " + next);
+            log.debug(prevRow + " - " + row + " - " + nextRow);
             
             //Determine the grid units necessary for getting all the borders right
             int guCount = row.getGridUnits().size();
-            if (prev != null) {
-                guCount = Math.max(guCount, prev.getGridUnits().size());
+            if (prevRow != null) {
+                guCount = Math.max(guCount, prevRow.getGridUnits().size());
             }
-            if (next != null) {
-                guCount = Math.max(guCount, next.getGridUnits().size());
+            if (nextRow != null) {
+                guCount = Math.max(guCount, nextRow.getGridUnits().size());
             }
             GridUnit gu = row.getGridUnit(0);
             //Create empty grid units to hold resolved borders of neighbouring cells
@@ -362,8 +358,8 @@ public class TableContentLayoutManager implements PercentBaseContext {
                     gu = row.getGridUnit(i);
                     GridUnit other;
                     int flags = 0;
-                    if (prev != null && i < prev.getGridUnits().size()) {
-                        other = prev.getGridUnit(i);
+                    if (prevRow != null && i < prevRow.getGridUnits().size()) {
+                        other = prevRow.getGridUnit(i);
                     } else {
                         other = null;
                     }
@@ -371,7 +367,7 @@ public class TableContentLayoutManager implements PercentBaseContext {
                             || other.isEmpty() 
                             || gu.isEmpty() 
                             || gu.getPrimary() != other.getPrimary()) {
-                        if ((iter == this.trIter)
+                        if ((iter == this.bodyIter)
                                 && gu.getFlag(GridUnit.FIRST_IN_TABLE)
                                 && (this.headerIter == null)) {
                             flags |= CollapsingBorderModel.VERTICAL_START_END_OF_TABLE;
@@ -385,8 +381,8 @@ public class TableContentLayoutManager implements PercentBaseContext {
                     }
                     
                     flags = 0;
-                    if (next != null && i < next.getGridUnits().size()) {
-                        other = next.getGridUnit(i);
+                    if (nextRow != null && i < nextRow.getGridUnits().size()) {
+                        other = nextRow.getGridUnit(i);
                     } else {
                         other = null;
                     }
@@ -394,7 +390,7 @@ public class TableContentLayoutManager implements PercentBaseContext {
                             || other.isEmpty() 
                             || gu.isEmpty() 
                             || gu.getPrimary() != other.getPrimary()) {
-                        if ((iter == this.trIter)
+                        if ((iter == this.bodyIter)
                                 && gu.getFlag(GridUnit.LAST_IN_TABLE)
                                 && (this.footerIter == null)) {
                             flags |= CollapsingBorderModel.VERTICAL_START_END_OF_TABLE;
@@ -608,7 +604,7 @@ public class TableContentLayoutManager implements PercentBaseContext {
     }
     
     /**
-     * Adds the areas generated my this layout manager to the area tree.
+     * Adds the areas generated by this layout manager to the area tree.
      * @param parentIter the position iterator
      * @param layoutContext the layout context for adding areas
      */
@@ -723,12 +719,12 @@ public class TableContentLayoutManager implements PercentBaseContext {
                     body = part.pgu.getBody();
                 }
                 if (tcpos.getFlag(TableContentPosition.FIRST_IN_ROWGROUP) 
-                        && tcpos.row.getFlag(EffRow.FIRST_IN_BODY)) {
+                        && tcpos.row.getFlag(EffRow.FIRST_IN_PART)) {
                     firstPos = true;
 
                 }
                 if (tcpos.getFlag(TableContentPosition.LAST_IN_ROWGROUP) 
-                        && tcpos.row.getFlag(EffRow.LAST_IN_BODY)) {
+                        && tcpos.row.getFlag(EffRow.LAST_IN_PART)) {
                     lastPos = true;
                     getTableLM().getCurrentPV().addMarkers(body.getMarkers(), 
                             true, firstPos, lastPos);
index f5102361535f5dd066ed3cb7350c47c7331fcdd4..2e653e23d932a8ae377b5420293b7d8ef4532f92 100644 (file)
@@ -46,10 +46,10 @@ import org.apache.fop.fo.FObj;
 
 /**
  * LayoutManager for a table FO.
- * A table consists of oldColumns, table header, table footer and multiple
+ * A table consists of columns, table header, table footer and multiple
  * table bodies.
  * The header, footer and body add the areas created from the table cells.
- * The table then creates areas for the oldColumns, bodies and rows
+ * The table then creates areas for the columns, bodies and rows
  * the render background.
  */
 public class TableLayoutManager extends BlockStackingLayoutManager 
@@ -210,7 +210,7 @@ public class TableLayoutManager extends BlockStackingLayoutManager
         //Spaces, border and padding to be repeated at each break
         addPendingMarks(context);
 
-        LinkedList returnedList = null;
+        LinkedList contentKnuthElements = null;
         LinkedList contentList = new LinkedList();
         //Position returnPosition = new NonLeafPosition(this, null);
         //Body prevLM = null;
@@ -226,7 +226,7 @@ public class TableLayoutManager extends BlockStackingLayoutManager
         if (contentLM == null) {
             contentLM = new TableContentLayoutManager(this);
         }
-        returnedList = contentLM.getNextKnuthElements(childLC, alignment);
+        contentKnuthElements = contentLM.getNextKnuthElements(childLC, alignment);
         if (childLC.isKeepWithNextPending()) {
             log.debug("TableContentLM signals pending keep-with-next");
             context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING);
@@ -237,15 +237,15 @@ public class TableLayoutManager extends BlockStackingLayoutManager
         }
         
         //Set index values on elements coming from the content LM
-        Iterator iter = returnedList.iterator();
+        Iterator iter = contentKnuthElements.iterator();
         while (iter.hasNext()) {
             ListElement el = (ListElement)iter.next();
             notifyPos(el.getPosition());
         }
-        log.debug(returnedList);
+        log.debug(contentKnuthElements);
         
-        if (returnedList.size() == 1
-                && ((ListElement)returnedList.getFirst()).isForcedBreak()) {
+        if (contentKnuthElements.size() == 1
+                && ((ListElement)contentKnuthElements.getFirst()).isForcedBreak()) {
             // a descendant of this block has break-before
             if (returnList.size() == 0) {
                 // the first child (or its first child ...) has
@@ -256,11 +256,11 @@ public class TableLayoutManager extends BlockStackingLayoutManager
                 //FIX ME
                 //bSpaceBeforeServed = false;
             }
-            contentList.addAll(returnedList);
+            contentList.addAll(contentKnuthElements);
 
             // "wrap" the Position inside each element
             // moving the elements from contentList to returnList
-            returnedList = new LinkedList();
+            contentKnuthElements = new LinkedList();
             wrapPositionElements(contentList, returnList);
 
             return returnList;
@@ -287,9 +287,9 @@ public class TableLayoutManager extends BlockStackingLayoutManager
                     // a penalty
                 }
             }*/
-            contentList.addAll(returnedList);
-            if (returnedList.size() > 0) {
-                if (((ListElement)returnedList.getLast()).isForcedBreak()) {
+            contentList.addAll(contentKnuthElements);
+            if (contentKnuthElements.size() > 0) {
+                if (((ListElement)contentKnuthElements.getLast()).isForcedBreak()) {
                     // a descendant of this block has break-after
                     if (false /*curLM.isFinished()*/) {
                         // there is no other content in this block;
@@ -297,7 +297,7 @@ public class TableLayoutManager extends BlockStackingLayoutManager
                         setFinished(true);
                     }
 
-                    returnedList = new LinkedList();
+                    contentKnuthElements = new LinkedList();
                     wrapPositionElements(contentList, returnList);
 
                     return returnList;
@@ -317,7 +317,7 @@ public class TableLayoutManager extends BlockStackingLayoutManager
     
     /**
      * The table area is a reference area that contains areas for
-     * oldColumns, bodies, rows and the contents are in cells.
+     * columns, bodies, rows and the contents are in cells.
      *
      * @param parentIter the position iterator
      * @param layoutContext the layout context for adding areas
index 0e193c3ff8496dd2c066f2ec026257f9f6127d1a..2fc91cb4b04989caab8b1aad6051cfd9cd73e4aa 100644 (file)
@@ -35,89 +35,108 @@ import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 
 
 /**
- * <p>Iterator that lets the table layout manager step over all rows of a table.
- * </p>
- * <p>Note: This class is not thread-safe.
- * </p>
+ * Iterator that lets the table layout manager step over all of the rows of a part of the
+ * table (table-header, table-footer or table-body).
+ * <p>Note: This class is not thread-safe.</p>
  */
 public class TableRowIterator {
 
-    /** Selects the list of table-body elements for iteration. */
+    /** Selects the table-body elements for iteration. */
     public static final int BODY = 0;
-    /** Selects the table-header element for iteration. */
+    /** Selects the table-header elements for iteration. */
     public static final int HEADER = 1;
-    /** Selects the table-footer element for iteration. */
-    public static final int FOOTER = 2; 
-    
+    /** Selects the table-footer elements for iteration. */
+    public static final int FOOTER = 2;
+
     /** Logger **/
     private static Log log = LogFactory.getLog(TableRowIterator.class);
 
-    /** The table on with this instance operates. */
+    /** The table on which this instance operates. */
     protected Table table;
+    /** Column setup of the operated table. */
     private ColumnSetup columns;
-    private int type;
-    
-    /** Holds the current row (TableCell instances) */
+
+    /** Part of the table over which to iterate. One of BODY, HEADER or FOOTER. */
+    private int tablePart;
+
+    /** Holds the currently fetched row (TableCell instances). */
     private List currentRow = new java.util.ArrayList();
-    /** Holds the grid units of cell from the last row while will span over the current row 
-     * (GridUnit instance) */
-    private List lastRowsSpanningCells = new java.util.ArrayList();
-    private int currentRowIndex = -1;
-    //TODO rows should later be a Jakarta Commons LinkedList so concurrent modifications while 
-    //using a ListIterator are possible
-    /** List of cache rows. */
-    private List rows = new java.util.ArrayList();
-    //private int indexOfFirstRowInList;
-    private int currentIndex = -1;
+
+    /**
+     * Holds the grid units of cells from the previous row which will span over the
+     * current row. Should be read "previous row's spanning cells". List of GridUnit
+     * instances.
+     */
+    private List previousRowsSpanningCells = new java.util.ArrayList();
+
+    /** Index of the row currently being fetched. */
+    private int fetchIndex = -1;
+
+    /** Spans found on the current row which will also span over the next row. */
     private int pendingRowSpans;
-    
+
+    //TODO rows should later be a Jakarta Commons LinkedList so concurrent modifications while
+    //using a ListIterator are possible
+    /** List of cached rows. This a list of EffRow elements. */
+    private List fetchedRows = new java.util.ArrayList();
+
+    /**
+     * Index of the row that will be returned at the next iteration step. Note that there
+     * is no direct relation between this field and {@link
+     * TableRowIterator#fetchIndex}. The fetching of rows and the iterating over them are
+     * two different processes. Hence the two indices. */
+    private int iteratorIndex = 0;
+
     //prefetch state
-    private ListIterator bodyIterator = null;
-    private ListIterator childInBodyIterator = null;
-    
+    /**
+     * Iterator over the requested table's part(s) (header, footer, body). Note that
+     * a table may have several table-body children, hence the iterator.
+     */
+    private ListIterator tablePartIterator = null;
+    /** Iterator over a part's child elements (either table-rows or table-cells). */
+    private ListIterator tablePartChildIterator = null;
+
     /**
      * Creates a new TableRowIterator.
      * @param table the table to iterate over
      * @param columns the column setup for the table
-     * @param what indicates what part of the table to iterate over (HEADER, FOOTER, BODY)
+     * @param tablePart indicates what part of the table to iterate over (HEADER, FOOTER, BODY)
      */
-    public TableRowIterator(Table table, ColumnSetup columns, int what) {
+    public TableRowIterator(Table table, ColumnSetup columns, int tablePart) {
         this.table = table;
         this.columns = columns;
-        this.type = what;
-        switch(what) {
+        this.tablePart = tablePart;
+        switch(tablePart) {
             case HEADER: {
                 List bodyList = new java.util.ArrayList();
                 bodyList.add(table.getTableHeader());
-                this.bodyIterator = bodyList.listIterator();
+                this.tablePartIterator = bodyList.listIterator();
                 break;
             }
             case FOOTER: {
                 List bodyList = new java.util.ArrayList();
                 bodyList.add(table.getTableFooter());
-                this.bodyIterator = bodyList.listIterator();
+                this.tablePartIterator = bodyList.listIterator();
                 break;
             }
             default: {
-                this.bodyIterator = table.getChildNodes();
+                this.tablePartIterator = table.getChildNodes();
             }
         }
     }
-    
+
     /**
-     * <p>Preloads the whole table. 
-     * </p>
-     * <p>Note:This is inefficient for large tables.
-     * </p>
+     * Preloads the whole table.
+     * <p>Note:This is inefficient for large tables.</p>
      */
     public void prefetchAll() {
         while (prefetchNext()) {
             log.trace("found row...");
         }
     }
-    
+
     /**
-     * Returns the next row group if any. A row group in this context is the minimum number of 
+     * Returns the next row group if any. A row group in this context is the minimum number of
      * consecutive rows which contains all spanned grid units of its cells.
      * @return the next row group, or null
      */
@@ -154,118 +173,155 @@ public class TableRowIterator {
         }
         return rowGroup;
     }
-    
+
     /**
-     * Retuns the next effective row.
-     * @return the requested effective row.
+     * Returns the row at the given index, fetching rows up to the requested one if
+     * necessary.
+     *
+     * @return the requested row, or null if there is no row at the given index (index
+     * &lt; 0 or end of table-part reached)
      */
-    public EffRow getNextRow() {
-        currentIndex++;
+    private EffRow getRow(int index) {
         boolean moreRows = true;
-        while (moreRows && rows.size() < currentIndex + 1) {
+        while (moreRows && fetchedRows.size() <= index) {
             moreRows = prefetchNext();
         }
-        if (currentIndex < rows.size()) {
-            return getCachedRow(currentIndex);
-        } else {
-            return null;
-        }
+        // Whatever the value of index, getCachedRow will handle it nicely
+        return getCachedRow(index);
+    }
+
+    /**
+     * Returns the next effective row.
+     * @return the requested effective row or null if there is no more row.
+     */
+    private EffRow getNextRow() {
+        return getRow(iteratorIndex++);
+    }
+
+    /**
+     * Returns the row preceding the given row, without moving the iterator.
+     *
+     * @param row a row in the iterated table part
+     * @return the preceding row, or null if there is no such row (the given row is the
+     * first one in the table part)
+     */
+    public EffRow getPrecedingRow(EffRow row) {
+        return getRow(row.getIndex() - 1);
+    }
+
+    /**
+     * Returns the row following the given row, without moving the iterator.
+     *
+     * @param row a row in the iterated table part
+     * @return the following row, or null if there is no more row
+     */
+    public EffRow getFollowingRow(EffRow row) {
+        return getRow(row.getIndex() + 1);
     }
-    
+
     /**
      * Sets the iterator to the previous row.
      */
     public void backToPreviousRow() {
-        currentIndex--;
+        iteratorIndex--;
     }
-    
+
     /**
      * Returns the first effective row.
      * @return the requested effective row.
      */
     public EffRow getFirstRow() {
-        if (rows.size() == 0) {
+        if (fetchedRows.size() == 0) {
             prefetchNext();
         }
         return getCachedRow(0);
     }
-    
+
     /**
-     * <p>Returns the last effective row.
-     * </p>
+     * Returns the last effective row.
      * <p>Note:This is inefficient for large tables because the whole table
-     * if preloaded.
-     * </p>
+     * if preloaded.</p>
      * @return the requested effective row.
      */
     public EffRow getLastRow() {
         while (prefetchNext()) {
             //nop
         }
-        return getCachedRow(rows.size() - 1);
+        return getCachedRow(fetchedRows.size() - 1);
     }
-    
+
     /**
-     * Returns a cached effective row.
+     * Returns a cached effective row. If the given index points outside the range of rows
+     * (negative or greater than the number of already fetched rows), this methods
+     * terminates nicely by returning null.
+     * 
      * @param index index of the row (zero-based)
-     * @return the requested effective row
+     * @return the requested effective row or null if (index &lt; 0 || index &gt;= the
+     * number of already fetched rows)
      */
     public EffRow getCachedRow(int index) {
-        if (index < 0 || index >= rows.size()) {
+        if (index < 0 || index >= fetchedRows.size()) {
             return null;
         } else {
-            return (EffRow)rows.get(index);
+            return (EffRow)fetchedRows.get(index);
         }
     }
-    
+
+    /**
+     * Fetches the next row.
+     * 
+     * @return true if there was a row to fetch; otherwise, false (the end of the
+     * table-part has been reached)
+     */
     private boolean prefetchNext() {
         boolean firstInTable = false;
-        boolean firstInBody = false;
-        if (childInBodyIterator != null) {
-            if (!childInBodyIterator.hasNext()) {
-                //force skip on to next body
-                if (pendingRowSpans > 0) {
-                    this.currentRow.clear();
-                    this.currentRowIndex++;
-                    EffRow gridUnits = buildGridRow(this.currentRow, null);
-                    log.debug(gridUnits);
-                    rows.add(gridUnits);
-                    return true;
-                }
-                childInBodyIterator = null;
-                if (rows.size() > 0) {
-                    getCachedRow(rows.size() - 1).setFlagForAllGridUnits(
-                            GridUnit.LAST_IN_BODY, true);
-                }
+        boolean firstInTablePart = false;
+        // If we are at the end of the current table part
+        if (tablePartChildIterator != null && !tablePartChildIterator.hasNext()) {
+            //force skip on to next component
+            if (pendingRowSpans > 0) {
+                this.currentRow.clear();
+                this.fetchIndex++;
+                EffRow gridUnits = buildGridRow(this.currentRow, null);
+                log.debug(gridUnits);
+                fetchedRows.add(gridUnits);
+                return true;
+            }
+            tablePartChildIterator = null;
+            if (fetchedRows.size() > 0) {
+                getCachedRow(fetchedRows.size() - 1).setFlagForAllGridUnits(
+                        GridUnit.LAST_IN_PART, true);
             }
         }
-        if (childInBodyIterator == null) {
-            if (bodyIterator.hasNext()) {
-                childInBodyIterator = ((TableBody)bodyIterator.next()).getChildNodes();
-                if (rows.size() == 0) {
+        // If the iterating over the current table-part has not started yet
+        if (tablePartChildIterator == null) {
+            if (tablePartIterator.hasNext()) {
+                tablePartChildIterator = ((TableBody)tablePartIterator.next()).getChildNodes();
+                if (fetchedRows.size() == 0) {
                     firstInTable = true;
                 }
-                firstInBody = true;
+                firstInTablePart = true;
             } else {
-                //no more rows
-                if (rows.size() > 0) {
-                    getCachedRow(rows.size() - 1).setFlagForAllGridUnits(
-                            GridUnit.LAST_IN_BODY, true);
-                    if ((type == FOOTER || table.getTableFooter() == null) 
-                            && type != HEADER) {
-                        getCachedRow(rows.size() - 1).setFlagForAllGridUnits(
+                //no more rows in that part of the table
+                if (fetchedRows.size() > 0) {
+                    getCachedRow(fetchedRows.size() - 1).setFlagForAllGridUnits(
+                            GridUnit.LAST_IN_PART, true);
+                    // If the last row is the last of the table
+                    if (tablePart == FOOTER
+                            || (tablePart == BODY && table.getTableFooter() == null)) {
+                        getCachedRow(fetchedRows.size() - 1).setFlagForAllGridUnits(
                                 GridUnit.LAST_IN_TABLE, true);
                     }
                 }
                 return false;
             }
         }
-        Object node = childInBodyIterator.next();
+        Object node = tablePartChildIterator.next();
         while (node instanceof Marker) {
-            node = childInBodyIterator.next();
+            node = tablePartChildIterator.next();
         }
         this.currentRow.clear();
-        this.currentRowIndex++;
+        this.fetchIndex++;
         TableRow rowFO = null;
         if (node instanceof TableRow) {
             rowFO = (TableRow)node;
@@ -276,11 +332,11 @@ public class TableRowIterator {
         } else if (node instanceof TableCell) {
             this.currentRow.add(node);
             if (!((TableCell)node).endsRow()) {
-                while (childInBodyIterator.hasNext()) {
-                    TableCell cell = (TableCell)childInBodyIterator.next();
+                while (tablePartChildIterator.hasNext()) {
+                    TableCell cell = (TableCell)tablePartChildIterator.next();
                     if (cell.startsRow()) {
                         //next row already starts here, one step back
-                        childInBodyIterator.previous();
+                        tablePartChildIterator.previous();
                         break;
                     }
                     this.currentRow.add(cell);
@@ -293,25 +349,33 @@ public class TableRowIterator {
             throw new IllegalStateException("Illegal class found: " + node.getClass().getName());
         }
         EffRow gridUnits = buildGridRow(this.currentRow, rowFO);
-        if (firstInBody) {
-            gridUnits.setFlagForAllGridUnits(GridUnit.FIRST_IN_BODY, true);
+        if (firstInTablePart) {
+            gridUnits.setFlagForAllGridUnits(GridUnit.FIRST_IN_PART, true);
         }
-        if (firstInTable && (type == HEADER || table.getTableHeader() == null)
-                && type != FOOTER) {
+        if (firstInTable && (tablePart == HEADER || table.getTableHeader() == null)
+                && tablePart != FOOTER) {
             gridUnits.setFlagForAllGridUnits(GridUnit.FIRST_IN_TABLE, true);
         }
         log.debug(gridUnits);
-        rows.add(gridUnits);
+        fetchedRows.add(gridUnits);
         return true;
     }
 
+    /**
+     * Places the given object at the given position in the list, first extending it if
+     * necessary with null objects to reach the position.
+     *
+     * @param list the list in which to place the object
+     * @param position index at which the object must be placed (0-based)
+     * @param obj the object to place
+     */
     private void safelySetListItem(List list, int position, Object obj) {
         while (position >= list.size()) {
             list.add(null);
         }
         list.set(position, obj);
     }
-    
+
     private Object safelyGetListItem(List list, int position) {
         if (position >= list.size()) {
             return null;
@@ -319,18 +383,25 @@ public class TableRowIterator {
             return list.get(position);
         }
     }
-    
+
+    /**
+     * Builds the list of grid units corresponding to the given table row.
+     *
+     * @param cells list of cells belonging to the row
+     * @param rowFO the fo:table-row object containing the row, possibly null
+     * @return the list of grid units
+     */
     private EffRow buildGridRow(List cells, TableRow rowFO) {
-        EffRow row = new EffRow(this.currentRowIndex, type);
+        EffRow row = new EffRow(this.fetchIndex, tablePart);
         List gridUnits = row.getGridUnits();
-        
+
         TableBody bodyFO = null;
-        
-        //Create all row-spanned grid units based on information from the last row
+
+        //Create all row-spanned grid units based on information from the previous row
         int colnum = 1;
-        GridUnit[] horzSpan = null;
+        GridUnit[] horzSpan = null;  // Grid units horizontally spanned by a single cell
         if (pendingRowSpans > 0) {
-            ListIterator spanIter = lastRowsSpanningCells.listIterator();
+            ListIterator spanIter = previousRowsSpanningCells.listIterator();
             while (spanIter.hasNext()) {
                 GridUnit gu = (GridUnit)spanIter.next();
                 if (gu != null) {
@@ -359,40 +430,40 @@ public class TableRowIterator {
         if (pendingRowSpans < 0) {
             throw new IllegalStateException("pendingRowSpans must not become negative!");
         }
-        
+
         //Transfer available cells to their slots
         colnum = 1;
         ListIterator iter = cells.listIterator();
         while (iter.hasNext()) {
             TableCell cell = (TableCell)iter.next();
-            
+
             colnum = cell.getColumnNumber();
 
             //TODO: remove the check below???
             //shouldn't happen here, since
-            //overlapping cells already caught in 
+            //overlapping cells already caught in
             //fo.flow.TableCell.bind()...
-            GridUnit other = (GridUnit)safelyGetListItem(gridUnits, colnum - 1); 
+            GridUnit other = (GridUnit)safelyGetListItem(gridUnits, colnum - 1);
             if (other != null) {
-                String err = "A table-cell (" 
-                        + cell.getContextInfo() 
-                        + ") is overlapping with another (" 
-                        + other.getCell().getContextInfo() 
+                String err = "A table-cell ("
+                        + cell.getContextInfo()
+                        + ") is overlapping with another ("
+                        + other.getCell().getContextInfo()
                         + ") in column " + colnum;
-                throw new IllegalStateException(err 
+                throw new IllegalStateException(err
                         + " (this should have been catched by FO tree validation)");
             }
             TableColumn col = columns.getColumn(colnum);
 
             //Add grid unit for primary grid unit
-            PrimaryGridUnit gu = new PrimaryGridUnit(cell, col, colnum - 1, this.currentRowIndex);
+            PrimaryGridUnit gu = new PrimaryGridUnit(cell, col, colnum - 1, this.fetchIndex);
             safelySetListItem(gridUnits, colnum - 1, gu);
             boolean hasRowSpanningLeft = !gu.isLastGridUnitRowSpan();
             if (hasRowSpanningLeft) {
                 pendingRowSpans++;
-                safelySetListItem(lastRowsSpanningCells, colnum - 1, gu);
+                safelySetListItem(previousRowsSpanningCells, colnum - 1, gu);
             }
-            
+
             if (gu.hasSpanning()) {
                 //Add grid units on spanned slots if any
                 horzSpan = new GridUnit[cell.getNumberColumnsSpanned()];
@@ -401,68 +472,68 @@ public class TableRowIterator {
                     colnum++;
                     GridUnit guSpan = new GridUnit(gu, columns.getColumn(colnum), colnum - 1, j);
                     //TODO: remove the check below???
-                    other = (GridUnit)safelyGetListItem(gridUnits, colnum - 1); 
+                    other = (GridUnit)safelyGetListItem(gridUnits, colnum - 1);
                     if (other != null) {
-                        String err = "A table-cell (" 
-                            + cell.getContextInfo() 
-                            + ") is overlapping with another (" 
-                            + other.getCell().getContextInfo() 
+                        String err = "A table-cell ("
+                            + cell.getContextInfo()
+                            + ") is overlapping with another ("
+                            + other.getCell().getContextInfo()
                             + ") in column " + colnum;
-                        throw new IllegalStateException(err 
+                        throw new IllegalStateException(err
                             + " (this should have been catched by FO tree validation)");
                     }
                     safelySetListItem(gridUnits, colnum - 1, guSpan);
                     if (hasRowSpanningLeft) {
                         pendingRowSpans++;
-                        safelySetListItem(lastRowsSpanningCells, colnum - 1, gu);
+                        safelySetListItem(previousRowsSpanningCells, colnum - 1, gu);
                     }
                     horzSpan[j] = guSpan;
                 }
                 gu.addRow(horzSpan);
             }
-            
+
             //Gather info for empty grid units (used later)
             if (bodyFO == null) {
                 bodyFO = gu.getBody();
             }
-            
+
             colnum++;
         }
-        
+
         //Post-processing the list (looking for gaps and resolve start and end borders)
         fillEmptyGridUnits(gridUnits, rowFO, bodyFO);
         resolveStartEndBorders(gridUnits);
-        
+
         return row;
     }
-    
+
     private void fillEmptyGridUnits(List gridUnits, TableRow row, TableBody body) {
         for (int pos = 1; pos <= gridUnits.size(); pos++) {
             GridUnit gu = (GridUnit)gridUnits.get(pos - 1);
-            
+
             //Empty grid units
             if (gu == null) {
                 //Add grid unit
-                gu = new EmptyGridUnit(row, columns.getColumn(pos), body, 
+                gu = new EmptyGridUnit(row, columns.getColumn(pos), body,
                         pos - 1);
                 gridUnits.set(pos - 1, gu);
             }
-            
+
             //Set flags
             gu.setFlag(GridUnit.IN_FIRST_COLUMN, (pos == 1));
             gu.setFlag(GridUnit.IN_LAST_COLUMN, (pos == gridUnits.size()));
         }
     }
-    
+
     private void resolveStartEndBorders(List gridUnits) {
         for (int pos = 1; pos <= gridUnits.size(); pos++) {
             GridUnit starting = (GridUnit)gridUnits.get(pos - 1);
-         
+
             //Border resolution
             if (table.isSeparateBorderModel()) {
                 starting.assignBorderForSeparateBorderModel();
             } else {
-                //Neighbouring grid unit at start edge 
+                //Neighbouring grid unit at start edge
                 GridUnit start = null;
                 int find = pos - 1;
                 while (find >= 1) {
@@ -473,15 +544,15 @@ public class TableRowIterator {
                     }
                     find--;
                 }
-                
+
                 //Ending grid unit for current cell
                 GridUnit ending = null;
                 if (starting.getCell() != null) {
                     pos += starting.getCell().getNumberColumnsSpanned() - 1;
                 }
                 ending = (GridUnit)gridUnits.get(pos - 1);
-                
-                //Neighbouring grid unit at end edge 
+
+                //Neighbouring grid unit at end edge
                 GridUnit end = null;
                 find = pos + 1;
                 while (find <= gridUnits.size()) {
@@ -492,9 +563,9 @@ public class TableRowIterator {
                     }
                     find++;
                 }
-                starting.resolveBorder(start, 
+                starting.resolveBorder(start,
                         CommonBorderPaddingBackground.START);
-                ending.resolveBorder(end, 
+                ending.resolveBorder(end,
                         CommonBorderPaddingBackground.END);
                 //Only start and end borders here, before and after during layout
             }