You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by vh...@apache.org on 2007/11/13 17:24:36 UTC

svn commit: r594571 [2/3] - in /xmlgraphics/fop/trunk: ./ src/java/org/apache/fop/fo/flow/ src/java/org/apache/fop/fo/flow/table/ src/java/org/apache/fop/fo/properties/ src/java/org/apache/fop/layoutmgr/table/ test/layoutengine/standard-testcases/

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/GridUnit.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/GridUnit.java?rev=594571&r1=594570&r2=594571&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/GridUnit.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/GridUnit.java Tue Nov 13 08:24:32 2007
@@ -22,10 +22,12 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.flow.table.BorderSpecification;
 import org.apache.fop.fo.flow.table.Table;
 import org.apache.fop.fo.flow.table.TableBody;
 import org.apache.fop.fo.flow.table.TableCell;
 import org.apache.fop.fo.flow.table.TableColumn;
+import org.apache.fop.fo.flow.table.TableFObj;
 import org.apache.fop.fo.flow.table.TableRow;
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo;
@@ -39,81 +41,142 @@
 
     /** Indicates that the grid unit is in the first column. */
     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 of the table. */
     public static final int FIRST_IN_TABLE = 2;
-    /** Indicates that the grid unit is in the first row of the table part (header, footer, body). */
+
+    /**
+     * 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). */
+
+    /**
+     * 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;
+    protected TableCell cell;
+
     /** 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 */
     private int colSpanIndex;
+
     /** index of grid unit within cell in row direction */
     private int rowSpanIndex;
+
     /** effective borders for a cell slot */
     private CommonBorderPaddingBackground effectiveBorders;
+
     /** flags for the grid unit */
     private byte flags = 0;
 
+    protected BorderSpecification[] resolvedBorders;
+
+    private CollapsingBorderModel collapsingBorderModel;
 
     /**
      * Creates a new grid unit.
-     *
-     * @param cell table cell which occupies this grid unit
+     * 
+     * @param table the containing table
      * @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
+     * @param rowSpanIndex index of this grid unit in the span, in row direction
      */
-    public GridUnit(TableCell cell, TableColumn column, int startCol, int colSpanIndex) {
-        this(null, cell, column, startCol, colSpanIndex);
+    protected GridUnit(Table table, TableColumn column, int startCol, int colSpanIndex,
+            int rowSpanIndex) {
+        this(column, startCol, colSpanIndex, rowSpanIndex);
+        setBorders(table);
     }
 
     /**
      * Creates a new grid unit.
-     *
-     * @param primary the before-start grid unit of the cell containing this 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
+     * @param rowSpanIndex index of this grid unit in the span, in row direction
      */
-    public GridUnit(PrimaryGridUnit primary, TableColumn column, int startCol, int colSpanIndex) {
-        this(primary, primary.getCell(), column, startCol, colSpanIndex);
+    protected GridUnit(TableCell cell, TableColumn column, int startCol, int colSpanIndex,
+            int rowSpanIndex) {
+        this(column, startCol, colSpanIndex, rowSpanIndex);
+        this.cell = cell;
+        setBorders(cell.getTable());
     }
 
     /**
      * Creates a new grid unit.
-     *
+     * 
      * @param primary the before-start grid unit of the cell containing this 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
+     * @param rowSpanIndex index of this grid unit in the span, in row direction
      */
-    protected GridUnit(PrimaryGridUnit primary, TableCell cell, TableColumn column, int startCol, int colSpanIndex) {
+    public GridUnit(PrimaryGridUnit primary, TableColumn column, int startCol, int colSpanIndex,
+            int rowSpanIndex) {
+        this(primary.getCell(), column, startCol, colSpanIndex, rowSpanIndex);
         this.primary = primary;
-        this.cell = cell;
+    }
+
+    private GridUnit(TableColumn column, int startCol, int colSpanIndex, int rowSpanIndex) {
         this.column = column;
         this.startCol = startCol;
         this.colSpanIndex = colSpanIndex;
+        this.rowSpanIndex = rowSpanIndex;
+    }
+
+    private void setBorders(Table table/*TODO*/) {
+        if (table.isSeparateBorderModel()) {
+            assignBorderForSeparateBorderModel();
+        } else {
+            resolvedBorders = new BorderSpecification[4];
+            collapsingBorderModel = CollapsingBorderModel.getBorderModelFor(table
+                    .getBorderCollapse());
+            if (rowSpanIndex == 0) {
+                setBorder(CommonBorderPaddingBackground.BEFORE);
+            }
+            if (isLastGridUnitRowSpan()) {
+                setBorder(CommonBorderPaddingBackground.AFTER);
+            }
+            if (colSpanIndex == 0) {
+                setBorder(CommonBorderPaddingBackground.START);
+            }
+            if (isLastGridUnitColSpan()) {
+                setBorder(CommonBorderPaddingBackground.END);
+            }
+        }
+    }
+
+    protected void setBorder(int side) {
+        resolvedBorders[side] = cell.resolvedBorders[side];
     }
 
     public TableCell getCell() {
@@ -128,7 +191,7 @@
         if (row != null) {
             return row;
         } else if (getCell().getParent() instanceof TableRow) {
-            return (TableRow)getCell().getParent();
+            return (TableRow) getCell().getParent();
         } else {
             return null;
         }
@@ -136,6 +199,7 @@
 
     /**
      * Sets the table-row FO, if applicable.
+     * 
      * @param row the table-row FO
      */
     public void setRow(TableRow row) {
@@ -147,18 +211,7 @@
         while (node != null && !(node instanceof TableBody)) {
             node = node.getParent();
         }
-        return (TableBody)node;
-    }
-
-    public Table getTable() {
-        FONode node = getBody();
-        while (node != null && !(node instanceof Table)) {
-            node = node.getParent();
-        }
-        if (node == null && getColumn() != null) {
-            node = getColumn().getParent();
-        }
-        return (Table)node;
+        return (TableBody) node;
     }
 
     /**
@@ -167,7 +220,7 @@
      * @return the before-start grid unit of the cell containing this grid unit.
      */
     public PrimaryGridUnit getPrimary() {
-        return (isPrimary() ? (PrimaryGridUnit)this : primary);
+        return primary;
     }
 
     /**
@@ -194,20 +247,12 @@
 
     /** @return true if the grid unit is the last in column spanning direction */
     public boolean isLastGridUnitColSpan() {
-        if (cell != null) {
-            return (colSpanIndex == cell.getNumberColumnsSpanned() - 1);
-        } else {
-            return true;
-        }
+        return (colSpanIndex == cell.getNumberColumnsSpanned() - 1);
     }
 
     /** @return true if the grid unit is the last in row spanning direction */
     public boolean isLastGridUnitRowSpan() {
-        if (cell != null) {
-            return (rowSpanIndex == cell.getNumberRowsSpanned() - 1);
-        } else {
-            return true;
-        }
+        return (rowSpanIndex == cell.getNumberRowsSpanned() - 1);
     }
 
     /**
@@ -225,9 +270,10 @@
     }
 
     /**
-     * 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.
+     * 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.
+     * 
      * @param side for which side to return the BorderInfo
      * @return the requested BorderInfo instance or null if the grid unit is an empty cell
      */
@@ -243,9 +289,33 @@
      * @return the resolved normal borders for this grid unit
      */
     public CommonBorderPaddingBackground getBorders() {
+        // TODO
+        if (effectiveBorders == null) {
+            effectiveBorders = new CommonBorderPaddingBackground();
+            setBorderInfo(CommonBorderPaddingBackground.BEFORE);
+            setBorderInfo(CommonBorderPaddingBackground.AFTER);
+            setBorderInfo(CommonBorderPaddingBackground.START);
+            setBorderInfo(CommonBorderPaddingBackground.END);
+            if (cell != null) {
+                effectiveBorders.setPadding(cell.getCommonBorderPaddingBackground());
+            }
+            if (log.isDebugEnabled()) {
+                log.debug(this + " resolved borders: " + "before="
+                        + effectiveBorders.getBorderBeforeWidth(false) + ", " + "after="
+                        + effectiveBorders.getBorderAfterWidth(false) + ", " + "start="
+                        + effectiveBorders.getBorderStartWidth(false) + ", " + "end="
+                        + effectiveBorders.getBorderEndWidth(false));
+            }
+        }
         return effectiveBorders;
     }
 
+    private void setBorderInfo(int side) {
+        if (resolvedBorders[side] != null) {
+            effectiveBorders.setBorderInfo(resolvedBorders[side].getBorderInfo(), side);
+        }
+    }
+
     /**
      * @return true if the grid unit has any borders.
      */
@@ -254,8 +324,8 @@
     }
 
     /**
-     * Assigns the borders from the given cell to this cell info. Used in
-     * case of separate border model.
+     * Assigns the borders from the given cell to this cell info. Used in case of separate
+     * border model.
      */
     public void assignBorderForSeparateBorderModel() {
         if (cell != null) {
@@ -264,42 +334,39 @@
     }
 
     /**
-     * Resolve collapsing borders for the given cell. Used in case of the collapsing border model.
-     * @param other neighbouring grid unit if any
-     * @param side the side to resolve (one of CommonBorderPaddingBackground.BEFORE|AFTER|START|END)
+     * Resolve collapsing borders for the given cell. Used in case of the collapsing
+     * border model.
+     * 
+     * @param other neighbouring grid unit
+     * @param side the side to resolve (one of
+     * CommonBorderPaddingBackground.BEFORE|AFTER|START|END)
      */
     public void resolveBorder(GridUnit other, int side) {
-        resolveBorder(other, side, 0);
+        BorderSpecification resolvedBorder = collapsingBorderModel.determineWinner(
+                resolvedBorders[side], other.resolvedBorders[CollapsingBorderModel
+                        .getOtherSide(side)]);
+        if (resolvedBorder != null) {
+            this.resolvedBorders[side] = resolvedBorder;
+            other.resolvedBorders[CollapsingBorderModel.getOtherSide(side)] = resolvedBorder;
+        }
     }
 
     /**
-     * Resolve collapsing borders for the given cell. Used in case of the collapsing border model.
-     * @param other neighbouring grid unit if any
-     * @param side the side to resolve (one of CommonBorderPaddingBackground.BEFORE|AFTER|START|END)
-     * @param resFlags flags for the border resolution
-     */
-    public void resolveBorder(GridUnit other, int side, int resFlags) {
-        CollapsingBorderModel borderModel = CollapsingBorderModel.getBorderModelFor(
-                getTable().getBorderCollapse());
-        if (effectiveBorders == null) {
-            effectiveBorders = new CommonBorderPaddingBackground();
-        }
-        effectiveBorders.setBorderInfo(borderModel.determineWinner(this, other,
-                        side, resFlags), side);
-        if (cell != null) {
-            effectiveBorders.setPadding(cell.getCommonBorderPaddingBackground());
-        }
-        if (log.isDebugEnabled()) {
-            log.debug(this + " resolved borders: "
-                    + "before=" + effectiveBorders.getBorderBeforeWidth(false) + ", "
-                    + "after=" + effectiveBorders.getBorderAfterWidth(false) + ", "
-                    + "start=" + effectiveBorders.getBorderStartWidth(false) + ", "
-                    + "end=" + effectiveBorders.getBorderEndWidth(false));
-        }
+     * Resolves the border on the given side of this grid unit, comparing it against the
+     * same border of the given parent element.
+     * 
+     * @param side the side to resolve (one of
+     * CommonBorderPaddingBackground.BEFORE|AFTER|START|END)
+     * @param parent the parent element holding a competing border
+     */
+    public void resolveBorder(int side, TableFObj parent) {
+        resolvedBorders[side] = collapsingBorderModel.determineWinner(resolvedBorders[side],
+                parent.resolvedBorders[side]);
     }
 
     /**
      * Returns a flag for this GridUnit.
+     * 
      * @param which the requested flag
      * @return the value of the flag
      */
@@ -309,29 +376,25 @@
 
     /**
      * 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
+            flags |= (1 << which); // set flag
         } else {
-            flags &= ~(1 << which); //clear flag
+            flags &= ~(1 << which); // clear flag
         }
     }
 
     /**
-     * @return the grid unit just below this grid unit if the cell is spanning.
+     * Sets the given flag on this grid unit.
+     * 
+     * @param which the flag to set
      */
-    public GridUnit createNextRowSpanningGridUnit() {
-        if (isLastGridUnitRowSpan()) {
-            return null;
-        } else {
-            //cloning the current GridUnit with adjustments
-            GridUnit gu = new GridUnit(getPrimary(), getColumn(), startCol, colSpanIndex);
-            gu.rowSpanIndex = rowSpanIndex + 1;
-            return gu;
-        }
+    public void setFlag(int which) {
+        setFlag(which, true);
     }
 
     /** {@inheritDoc} */

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/PrimaryGridUnit.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/PrimaryGridUnit.java?rev=594571&r1=594570&r2=594571&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/PrimaryGridUnit.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/PrimaryGridUnit.java Tue Nov 13 08:24:32 2007
@@ -55,18 +55,22 @@
      * @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);
+        super(cell, column, startCol, 0, 0);
         this.startRow = startRow;
         log.trace("PrimaryGridUnit created, row " + startRow + " col " + startCol);
-        if (cell != null) {
-            cellLM = new TableCellLayoutManager(cell, this);
-        }
     }
 
     public TableCellLayoutManager getCellLM() {
+        assert cellLM != null;
         return cellLM;
     }
 
+    /** {@inheritDoc} */
+    public PrimaryGridUnit getPrimary() {
+        return this;
+    }
+
+    /** {@inheritDoc} */
     public boolean isPrimary() {
         return true;
     }
@@ -223,6 +227,14 @@
     public boolean hasSpanning() {
         return (getCell().getNumberColumnsSpanned() > 1)
             || (getCell().getNumberRowsSpanned() > 1);
+    }
+
+    /**
+     * Creates a cellLM for the corresponding table-cell. A new one must be created
+     * for each new static-content (TODO).
+     */
+    public void createCellLM() {
+        cellLM = new TableCellLayoutManager(cell, this);
     }
 
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java?rev=594571&r1=594570&r2=594571&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java Tue Nov 13 08:24:32 2007
@@ -97,10 +97,6 @@
 
     public LinkedList getNextKnuthElements(LayoutContext context, int alignment, int bodyType) {
         LinkedList returnList = new LinkedList();
-        //Border resolution
-        if (!tableLM.getTable().isSeparateBorderModel()) {
-            resolveNormalBeforeAfterBordersForRowGroup();
-        }
 
         //Reset keep-with-next when remaining inside the table.
         //The context flag is only used to propagate keep-with-next to the outside.
@@ -134,107 +130,6 @@
     }
 
     /**
-     * Resolves normal borders for a row group.
-     * @param iter Table row iterator to operate on
-     */
-    private void resolveNormalBeforeAfterBordersForRowGroup() {
-        for (int rgi = 0; rgi < rowGroup.length; rgi++) {
-            EffRow row = rowGroup[rgi];
-            EffRow prevRow = thisIter.getPrecedingRow(row);
-            EffRow nextRow = thisIter.getFollowingRow(row);
-            if ((prevRow == null) && (thisIter == bodyIter) && (headerIter != null)) {
-                prevRow = headerIter.getLastRow();
-            }
-            if ((nextRow == null) && (thisIter == headerIter)) {
-                nextRow = bodyIter.getFirstRow();
-            }
-            if ((nextRow == null) && (thisIter == bodyIter) && (footerIter != null)) {
-                nextRow = footerIter.getFirstRow();
-            }
-            if ((prevRow == null) && (thisIter == footerIter)) {
-                //TODO This could be bad for memory consumption because it already causes the
-                //whole body iterator to be prefetched!
-                prevRow = bodyIter.getLastRow();
-            }
-            log.debug("prevRow-row-nextRow: " + prevRow + " - " + row + " - " + nextRow);
-            
-            //Determine the grid units necessary for getting all the borders right
-            int guCount = row.getGridUnits().size();
-            if (prevRow != null) {
-                guCount = Math.max(guCount, prevRow.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
-            //TODO maybe this needs to be done differently (and sooner)
-            for (int i = 0; i < guCount - row.getGridUnits().size(); i++) {
-                //TODO This block is untested!
-                int pos = row.getGridUnits().size() + i;
-                row.getGridUnits().add(new EmptyGridUnit(gu.getRow(), 
-                        tableLM.getColumns().getColumn(pos + 1), gu.getBody(), 
-                        pos));
-            }
-            
-            //Now resolve normal borders
-            if (tableLM.getTable().isSeparateBorderModel()) {
-                //nop, borders are already assigned at this point
-            } else {
-                for (int i = 0; i < row.getGridUnits().size(); i++) {
-                    gu = row.getGridUnit(i);
-                    GridUnit other;
-                    int flags = 0;
-                    if (prevRow != null && i < prevRow.getGridUnits().size()) {
-                        other = prevRow.getGridUnit(i);
-                    } else {
-                        other = null;
-                    }
-                    if (other == null 
-                            || other.isEmpty() 
-                            || gu.isEmpty() 
-                            || gu.getPrimary() != other.getPrimary()) {
-                        if ((thisIter == bodyIter)
-                                && gu.getFlag(GridUnit.FIRST_IN_TABLE)
-                                && (headerIter == null)) {
-                            flags |= CollapsingBorderModel.VERTICAL_START_END_OF_TABLE;
-                        }
-                        if ((thisIter == headerIter)
-                                && gu.getFlag(GridUnit.FIRST_IN_TABLE)) {
-                            flags |= CollapsingBorderModel.VERTICAL_START_END_OF_TABLE;
-                        }
-                        gu.resolveBorder(other, 
-                                CommonBorderPaddingBackground.BEFORE, flags);
-                    }
-                    
-                    flags = 0;
-                    if (nextRow != null && i < nextRow.getGridUnits().size()) {
-                        other = nextRow.getGridUnit(i);
-                    } else {
-                        other = null;
-                    }
-                    if (other == null 
-                            || other.isEmpty() 
-                            || gu.isEmpty() 
-                            || gu.getPrimary() != other.getPrimary()) {
-                        if ((thisIter == bodyIter)
-                                && gu.getFlag(GridUnit.LAST_IN_TABLE)
-                                && (footerIter == null)) {
-                            flags |= CollapsingBorderModel.VERTICAL_START_END_OF_TABLE;
-                        }
-                        if ((thisIter == footerIter)
-                                && gu.getFlag(GridUnit.LAST_IN_TABLE)) {
-                            flags |= CollapsingBorderModel.VERTICAL_START_END_OF_TABLE;
-                        }
-                        gu.resolveBorder(other, 
-                                CommonBorderPaddingBackground.AFTER, flags);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
      * Creates Knuth elements for a row group (see TableRowIterator.getNextRowGroup()).
      * @param context Active LayoutContext
      * @param alignment alignment indicator
@@ -271,6 +166,7 @@
                     PrimaryGridUnit primary = gu.getPrimary();
                     
                     if (gu.isPrimary()) {
+                        primary.createCellLM(); // TODO a new LM must be created for every new static-content
                         primary.getCellLM().setParent(tableLM);
                      
                         //Determine the table-row if any

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java?rev=594571&r1=594570&r2=594571&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java Tue Nov 13 08:24:32 2007
@@ -20,11 +20,14 @@
 package org.apache.fop.layoutmgr.table;
 
 import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.ListIterator;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.FONode.FONodeIterator;
 import org.apache.fop.fo.flow.Marker;
 import org.apache.fop.fo.flow.table.Table;
 import org.apache.fop.fo.flow.table.TableBody;
@@ -98,6 +101,8 @@
     /** Iterator over a part's child elements (either table-rows or table-cells). */
     private ListIterator tablePartChildIterator = null;
 
+    private Iterator rowGroupsIter;
+
     /**
      * Creates a new TableRowIterator.
      * @param table the table to iterate over
@@ -110,19 +115,23 @@
         this.tablePart = tablePart;
         switch(tablePart) {
             case HEADER: {
-                List bodyList = new java.util.ArrayList();
-                bodyList.add(table.getTableHeader());
-                this.tablePartIterator = bodyList.listIterator();
+                rowGroupsIter = table.getTableHeader().getRowGroups().iterator();
                 break;
             }
             case FOOTER: {
-                List bodyList = new java.util.ArrayList();
-                bodyList.add(table.getTableFooter());
-                this.tablePartIterator = bodyList.listIterator();
+                rowGroupsIter = table.getTableFooter().getRowGroups().iterator();
                 break;
             }
             default: {
-                this.tablePartIterator = table.getChildNodes();
+                List rowGroupsList = new LinkedList();
+                // TODO this is ugly
+                for (FONodeIterator iter = table.getChildNodes(); iter.hasNext();) {
+                    FONode node = iter.nextNode();
+                    if (node instanceof TableBody) {
+                        rowGroupsList.addAll(((TableBody) node).getRowGroups());
+                    }
+                }
+                rowGroupsIter = rowGroupsList.iterator();
             }
         }
     }
@@ -132,38 +141,19 @@
      * consecutive rows which contains all spanned grid units of its cells.
      * @return the next row group, or null
      */
-    public EffRow[] getNextRowGroup() {
-        EffRow firstRowInGroup = getNextRow();
-        if (firstRowInGroup == null) {
+    EffRow[] getNextRowGroup() {
+        if (!rowGroupsIter.hasNext()) {
             return null;
         }
-        EffRow lastRowInGroup = firstRowInGroup;
-        int lastIndex = lastRowInGroup.getIndex();
-        boolean allFinished;
-        do {
-            allFinished = true;
-            Iterator iter = lastRowInGroup.getGridUnits().iterator();
-            while (iter.hasNext()) {
-                GridUnit gu = (GridUnit)iter.next();
-                if (!gu.isLastGridUnitRowSpan()) {
-                    allFinished = false;
-                    break;
-                }
-            }
-            lastIndex = lastRowInGroup.getIndex();
-            if (!allFinished) {
-                lastRowInGroup = getNextRow();
-                if (lastRowInGroup == null) {
-                    allFinished = true;
-                }
-            }
-        } while (!allFinished);
-        int rowCount = lastIndex - firstRowInGroup.getIndex() + 1;
-        EffRow[] rowGroup = new EffRow[rowCount];
-        for (int i = 0; i < rowCount; i++) {
-            rowGroup[i] = getCachedRow(i + firstRowInGroup.getIndex());
+        List rowGroup = (List) rowGroupsIter.next();
+        EffRow[] effRowGroup = new EffRow[rowGroup.size()];
+        int i = 0;
+        for (Iterator rowIter = rowGroup.iterator(); rowIter.hasNext();) {
+            List gridUnits = (List) rowIter.next();
+            effRowGroup[i] = new EffRow(i, tablePart, gridUnits);
+            i++;
         }
-        return rowGroup;
+        return effRowGroup;
     }
 
     /**
@@ -197,7 +187,7 @@
      * @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) {
+    EffRow getPrecedingRow(EffRow row) {
         return getRow(row.getIndex() - 1);
     }
 
@@ -207,7 +197,7 @@
      * @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) {
+    EffRow getFollowingRow(EffRow row) {
         return getRow(row.getIndex() + 1);
     }
 
@@ -215,7 +205,7 @@
      * Returns the first effective row.
      * @return the requested effective row.
      */
-    public EffRow getFirstRow() {
+    EffRow getFirstRow() {
         if (fetchedRows.size() == 0) {
             prefetchNext();
         }
@@ -228,7 +218,7 @@
      * if preloaded.</p>
      * @return the requested effective row.
      */
-    public EffRow getLastRow() {
+    EffRow getLastRow() {
         while (prefetchNext()) {
             //nop
         }
@@ -377,7 +367,7 @@
      * @return the list of grid units
      */
     private EffRow buildGridRow(List cells, TableRow rowFO) {
-        EffRow row = new EffRow(this.fetchIndex, tablePart);
+        EffRow row = new EffRow(this.fetchIndex, tablePart, null);
         List gridUnits = row.getGridUnits();
 
         TableBody bodyFO = null;
@@ -393,7 +383,8 @@
                     if (gu.getColSpanIndex() == 0) {
                         horzSpan = new GridUnit[gu.getCell().getNumberColumnsSpanned()];
                     }
-                    GridUnit newGU = gu.createNextRowSpanningGridUnit();
+//                    GridUnit newGU = gu.createNextRowSpanningGridUnit();
+                    GridUnit newGU = null;
                     newGU.setRow(rowFO);
                     safelySetListItem(gridUnits, colnum - 1, newGU);
                     horzSpan[newGU.getColSpanIndex()] = newGU;
@@ -455,7 +446,7 @@
                 horzSpan[0] = gu;
                 for (int j = 1; j < cell.getNumberColumnsSpanned(); j++) {
                     colnum++;
-                    GridUnit guSpan = new GridUnit(gu, columns.getColumn(colnum), colnum - 1, j);
+                    GridUnit guSpan = new GridUnit(gu, columns.getColumn(colnum), colnum - 1, j, 0);
                     //TODO: remove the check below???
                     other = (GridUnit)safelyGetListItem(gridUnits, colnum - 1);
                     if (other != null) {
@@ -486,29 +477,29 @@
         }
 
         //Post-processing the list (looking for gaps and resolve start and end borders)
-        fillEmptyGridUnits(gridUnits, rowFO, bodyFO);
+//        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,
-                        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 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,
+//                        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++) {

Modified: xmlgraphics/fop/trunk/status.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/status.xml?rev=594571&r1=594570&r2=594571&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/status.xml (original)
+++ xmlgraphics/fop/trunk/status.xml Tue Nov 13 08:24:32 2007
@@ -28,6 +28,21 @@
 
   <changes>
     <release version="FOP Trunk">
+      <action context="Code" dev="VH" type="add">
+        Step towards performance: the collapsing-border resolution algorithm no longer triggers the
+        retrieving of the whole table, when possible.
+      </action>
+      <action context="Code" dev="VH" type="fix">
+        In case of missing cells the border-end of the table was applied to an inner cell, instead
+        of the (empty) cell in the last column.
+      </action>
+      <action context="Code" dev="VH" type="fix">
+        Fixed the resolution of borders with table-columns (border-before/after was wrongly applied
+        to every cell of the column).
+      </action>
+      <action context="Code" dev="VH" type="fix">
+        Fixed the resolution of border-end on cells spanning several rows.
+      </action>
       <action context="Code" dev="JM" type="fix" fixes-bug="43835" due-to="David Churavy">
         Bugfix: Use Font.getName() (logical font name) instead of Font.getFontName()
         (localized) when registering fonts from AWT.

Added: xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/table_border-collapse_collapse_nrnc_no-col.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/table_border-collapse_collapse_nrnc_no-col.xml?rev=594571&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/table_border-collapse_collapse_nrnc_no-col.xml (added)
+++ xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/table_border-collapse_collapse_nrnc_no-col.xml Tue Nov 13 08:24:32 2007
@@ -0,0 +1,448 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<!-- $Id$ -->
+<!--
+  NOTE: this test is a clone of table_border-collapse_collapse_nrnc.xml where all of the
+  fo:table-column elements have been removed.
+-->
+<testcase>
+  <info>
+    <p>
+      This test checks tables with collapse border model. It tries to be as exhaustive as possible
+      by making a lot of situations to occur: different border widths, styles, colors, none/hidden
+      border styles, big borders, computation of row height, etc.
+    </p>
+  </info>
+  <fo>
+    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">
+      <fo:layout-master-set>
+        <fo:simple-page-master master-name="normal" page-width="16cm" page-height="15cm" margin="20pt">
+          <fo:region-body margin="0pt"/>
+        </fo:simple-page-master>
+      </fo:layout-master-set>
+      <fo:page-sequence master-reference="normal">
+        <fo:flow flow-name="xsl-region-body">
+          <fo:block>Before the tables</fo:block>
+
+          <!-- table 1 -->
+          <fo:table table-layout="fixed" width="200pt" border-collapse="collapse">
+            <fo:table-column column-width="proportional-column-width(1)"
+              number-columns-repeated="2"/>
+            <fo:table-body>
+              <fo:table-row>
+                <fo:table-cell
+                  border-top="12pt solid black"
+                  border-bottom="12pt solid blue"
+                  border-left="12pt solid red"
+                  border-right="12pt solid orange">
+                  <fo:block>Cell 1.1 Cell 1.1 Cell 1.1 Cell 1.1</fo:block>
+                </fo:table-cell>
+                <fo:table-cell
+                  border-top="4pt solid gray"
+                  border-bottom="10pt solid navy"
+                  border-left="4pt solid purple"
+                  border-right="4pt solid yellow">
+                  <fo:block>Cell 1.2</fo:block>
+                </fo:table-cell>
+              </fo:table-row>
+              <fo:table-row>
+                <fo:table-cell
+                  border-top="6pt solid gray"
+                  border-bottom="6pt solid navy"
+                  border-left="6pt solid purple"
+                  border-right="6pt solid yellow">
+                  <fo:block>Cell 2.1</fo:block>
+                </fo:table-cell>
+                <fo:table-cell
+                  border-top="10pt solid black"
+                  border-bottom="10pt solid blue"
+                  border-left="10pt solid red"
+                  border-right="10pt solid orange">
+                  <fo:block>Cell 2.2 Cell 2.2 Cell 2.2 Cell 2.2</fo:block>
+                </fo:table-cell>
+              </fo:table-row>
+            </fo:table-body>
+          </fo:table>
+
+          <fo:block>Between tables</fo:block>
+          <!-- table 2 -->
+          <fo:table table-layout="fixed" width="400pt" border-collapse="collapse">
+            <fo:table-body>
+              <!-- the height of this row is fixed by the 4th cell: only one row but big borders
+              which actually makes it higher than the 3rd cell -->
+              <fo:table-row>
+                <fo:table-cell
+                  border-top   ="4pt solid black"
+                  border-bottom="4pt solid black"
+                  border-left  ="4pt solid black"
+                  border-right ="4pt solid black">
+                  <fo:block>Cell 1.1</fo:block>
+                </fo:table-cell>
+                <fo:table-cell
+                  border-top   ="6pt solid silver"
+                  border-bottom="6pt solid silver"
+                  border-left  ="6pt solid silver"
+                  border-right ="6pt solid silver">
+                  <fo:block>Cell 1.2</fo:block>
+                </fo:table-cell>
+                <fo:table-cell
+                  border-top   ="5pt solid green"
+                  border-bottom="5pt solid green"
+                  border-left  ="5pt solid green"
+                  border-right ="5pt solid green">
+                  <fo:block>Cell 1.3 Cell 1.3 Cell 1.3 Cell 1.3</fo:block>
+                </fo:table-cell>
+                <fo:table-cell
+                  border-top   ="15pt solid navy"
+                  border-bottom="30pt solid navy"
+                  border-left  ="15pt solid navy"
+                  border-right =" 5pt solid navy">
+                  <fo:block>Cell 1.4</fo:block>
+                </fo:table-cell>
+              </fo:table-row>
+              <fo:table-row>
+                <fo:table-cell
+                  border-top   ="12pt solid maroon"
+                  border-bottom=" 6pt double maroon"
+                  border-left  =" 6pt solid maroon"
+                  border-right =" 6pt solid maroon">
+                  <fo:block>Cell 2.1 Cell 2.1 Cell 2.1 Cell 2.1 Cell 2.1 Cell 2.1</fo:block>
+                </fo:table-cell>
+                <fo:table-cell
+                  border-top   ="4pt hidden red"
+                  border-bottom="4pt dashed red"
+                  border-left  ="10pt dashed red"
+                  border-right ="4pt double red">
+                  <fo:block>Cell 2.2</fo:block>
+                </fo:table-cell>
+                <fo:table-cell
+                  border-top   ="6pt none maroon"
+                  border-bottom="6pt dotted maroon"
+                  border-left  ="10pt solid maroon"
+                  border-right ="6pt ridge maroon">
+                  <fo:block>Cell 2.3</fo:block>
+                </fo:table-cell>
+                <fo:table-cell
+                  border-top   ="5pt solid purple"
+                  border-bottom="5pt ridge purple"
+                  border-left  ="5pt dotted purple"
+                  border-right ="5pt solid purple">
+                  <fo:block>Cell 2.4</fo:block>
+                </fo:table-cell>
+              </fo:table-row>
+              <fo:table-row>
+                <fo:table-cell
+                  border-top   ="6pt double fuchsia"
+                  border-bottom="6pt inset fuchsia"
+                  border-left  ="30pt solid fuchsia"
+                  border-right ="6pt inset fuchsia">
+                  <fo:block>Cell 3.1</fo:block>
+                </fo:table-cell>
+                <fo:table-cell
+                  border-top   =" 4pt dashed lime"
+                  border-bottom=" 5pt outset lime"
+                  border-left  =" 5pt solid lime"
+                  border-right ="10pt groove lime">
+                  <fo:block>Cell 3.2 Cell 3.2 Cell 3.2 Cell 3.2 Cell 3.2 Cell 3.2</fo:block>
+                </fo:table-cell>
+                <fo:table-cell
+                  border-top   ="6pt dotted teal"
+                  border-bottom="4pt solid teal"
+                  border-left  ="10pt dotted teal"
+                  border-right ="4pt none teal">
+                  <fo:block>Cell 3.3</fo:block>
+                </fo:table-cell>
+                <fo:table-cell
+                  border-top   ="5pt ridge maroon"
+                  border-bottom="6pt solid maroon"
+                  border-left  ="10pt none maroon"
+                  border-right ="6pt none maroon">
+                  <fo:block>Cell 3.4</fo:block>
+                </fo:table-cell>
+              </fo:table-row>
+              <fo:table-row>
+                <fo:table-cell
+                  border-top   =" 6pt inset black"
+                  border-bottom=" 4pt solid black"
+                  border-left  =" 4pt solid black"
+                  border-right ="40pt solid black">
+                  <fo:block>Cell 4.1</fo:block>
+                </fo:table-cell>
+                <fo:table-cell
+                  border-top   =" 5pt outset silver"
+                  border-bottom="60pt solid silver"
+                  border-left  =" 6pt solid silver"
+                  border-right =" 6pt none silver">
+                  <fo:block>Cell 4.2 Cell 4.2</fo:block>
+                </fo:table-cell>
+                <fo:table-cell
+                  border-top   ="4pt double green"
+                  border-bottom="5pt solid green"
+                  border-left  ="6pt solid green"
+                  border-right ="5pt dashed green">
+                  <fo:block>Cell 4.3 Cell 4.3 Cell 4.3 Cell 4.3</fo:block>
+                </fo:table-cell>
+                <fo:table-cell
+                  border-top   ="6pt dotted navy"
+                  border-bottom="30pt solid navy"
+                  border-left  =" 5pt ridge navy"
+                  border-right ="50pt solid navy">
+                  <fo:block>Cell 4.4</fo:block>
+                </fo:table-cell>
+              </fo:table-row>
+            </fo:table-body>
+          </fo:table>
+          <fo:block>After the tables</fo:block>
+        </fo:flow>
+      </fo:page-sequence>
+    </fo:root>
+  </fo>
+  <checks>
+    <!-- table 1 -->
+    <eval expected="200000" xpath="//flow/block[2]/@ipd"/>
+    <eval expected="200000" xpath="//flow/block[2]/@ipda"/>
+    <eval expected="79600" xpath="//flow/block[2]/@bpd"/>
+    <eval expected="79600" xpath="//flow/block[2]/@bpda"/>
+    <!-- row 1 cell 1 -->
+    <eval expected="88000" xpath="//flow/block[2]/block[1]/@ipd"/>
+    <eval expected="112000" xpath="//flow/block[2]/block[1]/@ipda"/>
+    <eval expected="28800" xpath="//flow/block[2]/block[1]/@bpd"/>
+    <eval expected="52800" xpath="//flow/block[2]/block[1]/@bpda"/>
+    <eval expected="6000" xpath="//flow/block[2]/block[1]/@left-offset"/>
+    <eval expected="-6000" xpath="//flow/block[2]/block[1]/@top-offset"/>
+    <eval expected="(solid,#000000,12000,collapse-outer)" xpath="//flow/block[2]/block[1]/@border-before"/>
+    <eval expected="(solid,#0000ff,12000,collapse-inner)" xpath="//flow/block[2]/block[1]/@border-after"/>
+    <eval expected="(solid,#ff0000,12000,collapse-outer)" xpath="//flow/block[2]/block[1]/@border-start"/>
+    <eval expected="(solid,#ffa500,12000,collapse-inner)" xpath="//flow/block[2]/block[1]/@border-end"/>
+    <!-- row 1 cell 2 -->
+    <eval expected="92000" xpath="//flow/block[2]/block[2]/@ipd"/>
+    <eval expected="108000" xpath="//flow/block[2]/block[2]/@ipda"/>
+    <eval expected="33800" xpath="//flow/block[2]/block[2]/@bpd"/>
+    <eval expected="47800" xpath="//flow/block[2]/block[2]/@bpda"/>
+    <eval expected="106000" xpath="//flow/block[2]/block[2]/@left-offset"/>
+    <eval expected="-2000" xpath="//flow/block[2]/block[2]/@top-offset"/>
+    <eval expected="(solid,#808080,4000,collapse-outer)" xpath="//flow/block[2]/block[2]/@border-before"/>
+    <eval expected="(solid,#000080,10000,collapse-inner)" xpath="//flow/block[2]/block[2]/@border-after"/>
+    <eval expected="(solid,#ffa500,12000,collapse-inner)" xpath="//flow/block[2]/block[2]/@border-start"/>
+    <eval expected="(solid,#ffff00,4000,collapse-outer)" xpath="//flow/block[2]/block[2]/@border-end"/>
+    <!-- row 2 cell 1 -->
+    <eval expected="92000" xpath="//flow/block[2]/block[3]/@ipd"/>
+    <eval expected="108000" xpath="//flow/block[2]/block[3]/@ipda"/>
+    <eval expected="29800" xpath="//flow/block[2]/block[3]/@bpd"/>
+    <eval expected="47800" xpath="//flow/block[2]/block[3]/@bpda"/>
+    <eval expected="3000" xpath="//flow/block[2]/block[3]/@left-offset"/>
+    <eval expected="34800" xpath="//flow/block[2]/block[3]/@top-offset"/>
+    <eval expected="(solid,#0000ff,12000,collapse-inner)" xpath="//flow/block[2]/block[3]/@border-before"/>
+    <eval expected="(solid,#000080,6000,collapse-outer)" xpath="//flow/block[2]/block[3]/@border-after"/>
+    <eval expected="(solid,#800080,6000,collapse-outer)" xpath="//flow/block[2]/block[3]/@border-start"/>
+    <eval expected="(solid,#ff0000,10000,collapse-inner)" xpath="//flow/block[2]/block[3]/@border-end"/>
+    <!-- row 2 cell 2 -->
+    <eval expected="90000" xpath="//flow/block[2]/block[4]/@ipd"/>
+    <eval expected="110000" xpath="//flow/block[2]/block[4]/@ipda"/>
+    <eval expected="28800" xpath="//flow/block[2]/block[4]/@bpd"/>
+    <eval expected="48800" xpath="//flow/block[2]/block[4]/@bpda"/>
+    <eval expected="105000" xpath="//flow/block[2]/block[4]/@left-offset"/>
+    <eval expected="35800" xpath="//flow/block[2]/block[4]/@top-offset"/>
+    <eval expected="(solid,#000000,10000,collapse-inner)" xpath="//flow/block[2]/block[4]/@border-before"/>
+    <eval expected="(solid,#0000ff,10000,collapse-outer)" xpath="//flow/block[2]/block[4]/@border-after"/>
+    <eval expected="(solid,#ff0000,10000,collapse-inner)" xpath="//flow/block[2]/block[4]/@border-start"/>
+    <eval expected="(solid,#ffa500,10000,collapse-outer)" xpath="//flow/block[2]/block[4]/@border-end"/>
+
+    <!-- table 2 -->
+    <eval expected="400000" xpath="//flow/block[4]/@ipd"/>
+    <eval expected="400000" xpath="//flow/block[4]/@ipda"/>
+    <eval expected="198100" xpath="//flow/block[4]/@bpd"/>
+    <eval expected="198100" xpath="//flow/block[4]/@bpda"/>
+    <!-- row 1 cell 1 -->
+    <eval expected="95000" xpath="//flow/block[4]/block[1]/@ipd"/>
+    <eval expected="105000" xpath="//flow/block[4]/block[1]/@ipda"/>
+    <eval expected="28900" xpath="//flow/block[4]/block[1]/@bpd"/>
+    <eval expected="44900" xpath="//flow/block[4]/block[1]/@bpda"/>
+    <eval expected="2000" xpath="//flow/block[4]/block[1]/@left-offset"/>
+    <eval expected="-2000" xpath="//flow/block[4]/block[1]/@top-offset"/>
+    <eval expected="(solid,#000000,4000,collapse-outer)" xpath="//flow/block[4]/block[1]/@border-before"/>
+    <eval expected="(solid,#800000,12000,collapse-inner)" xpath="//flow/block[4]/block[1]/@border-after"/>
+    <eval expected="(solid,#000000,4000,collapse-outer)" xpath="//flow/block[4]/block[1]/@border-start"/>
+    <eval expected="(solid,#c0c0c0,6000,collapse-inner)" xpath="//flow/block[4]/block[1]/@border-end"/>
+    <!-- row 1 cell 2 -->
+    <eval expected="94000" xpath="//flow/block[4]/block[2]/@ipd"/>
+    <eval expected="106000" xpath="//flow/block[4]/block[2]/@ipda"/>
+    <eval expected="33900" xpath="//flow/block[4]/block[2]/@bpd"/>
+    <eval expected="39900" xpath="//flow/block[4]/block[2]/@bpda"/>
+    <eval expected="103000" xpath="//flow/block[4]/block[2]/@left-offset"/>
+    <eval expected="-3000" xpath="//flow/block[4]/block[2]/@top-offset"/>
+    <eval expected="(solid,#c0c0c0,6000,collapse-outer)" xpath="//flow/block[4]/block[2]/@border-before"/>
+    <eval expected="0" xpath="count(//flow/block[4]/block[2]/@border-after)"/>
+    <eval expected="(solid,#c0c0c0,6000,collapse-inner)" xpath="//flow/block[4]/block[2]/@border-start"/>
+    <eval expected="(solid,#c0c0c0,6000,collapse-inner)" xpath="//flow/block[4]/block[2]/@border-end"/>
+    <!-- row 1 cell 3 -->
+    <eval expected="89500" xpath="//flow/block[4]/block[3]/@ipd"/>
+    <eval expected="110500" xpath="//flow/block[4]/block[3]/@ipda"/>
+    <eval expected="31900" xpath="//flow/block[4]/block[3]/@bpd"/>
+    <eval expected="41900" xpath="//flow/block[4]/block[3]/@bpda"/>
+    <eval expected="203000" xpath="//flow/block[4]/block[3]/@left-offset"/>
+    <eval expected="-2500" xpath="//flow/block[4]/block[3]/@top-offset"/>
+    <eval expected="(solid,#008000,5000,collapse-outer)" xpath="//flow/block[4]/block[3]/@border-before"/>
+    <eval expected="(solid,#008000,5000,collapse-inner)" xpath="//flow/block[4]/block[3]/@border-after"/>
+    <eval expected="(solid,#c0c0c0,6000,collapse-inner)" xpath="//flow/block[4]/block[3]/@border-start"/>
+    <eval expected="(solid,#000080,15000,collapse-inner)" xpath="//flow/block[4]/block[3]/@border-end"/>
+    <!-- row 1 cell 4 -->
+    <eval expected="90000" xpath="//flow/block[4]/block[4]/@ipd"/>
+    <eval expected="110000" xpath="//flow/block[4]/block[4]/@ipda"/>
+    <eval expected="14400" xpath="//flow/block[4]/block[4]/@bpd"/>
+    <eval expected="59400" xpath="//flow/block[4]/block[4]/@bpda"/>
+    <eval expected="307500" xpath="//flow/block[4]/block[4]/@left-offset"/>
+    <eval expected="-7500" xpath="//flow/block[4]/block[4]/@top-offset"/>
+    <eval expected="(solid,#000080,15000,collapse-outer)" xpath="//flow/block[4]/block[4]/@border-before"/>
+    <eval expected="(solid,#000080,30000,collapse-inner)" xpath="//flow/block[4]/block[4]/@border-after"/>
+    <eval expected="(solid,#000080,15000,collapse-inner)" xpath="//flow/block[4]/block[4]/@border-start"/>
+    <eval expected="(solid,#000080,5000,collapse-outer)" xpath="//flow/block[4]/block[4]/@border-end"/>
+    <!-- row 2 cell 1 -->
+    <eval expected="92000" xpath="//flow/block[4]/block[5]/@ipd"/>
+    <eval expected="108000" xpath="//flow/block[4]/block[5]/@ipda"/>
+    <eval expected="43200" xpath="//flow/block[4]/block[5]/@bpd"/>
+    <eval expected="61200" xpath="//flow/block[4]/block[5]/@bpda"/>
+    <eval expected="3000" xpath="//flow/block[4]/block[5]/@left-offset"/>
+    <eval expected="30900" xpath="//flow/block[4]/block[5]/@top-offset"/>
+    <eval expected="(solid,#800000,12000,collapse-inner)" xpath="//flow/block[4]/block[5]/@border-before"/>
+    <eval expected="(double,#800000,6000,collapse-inner)" xpath="//flow/block[4]/block[5]/@border-after"/>
+    <eval expected="(solid,#800000,6000,collapse-outer)" xpath="//flow/block[4]/block[5]/@border-start"/>
+    <eval expected="(dashed,#ff0000,10000,collapse-inner)" xpath="//flow/block[4]/block[5]/@border-end"/>
+    <!-- row 2 cell 2 -->
+    <eval expected="90000" xpath="//flow/block[4]/block[6]/@ipd"/>
+    <eval expected="110000" xpath="//flow/block[4]/block[6]/@ipda"/>
+    <eval expected="50200" xpath="//flow/block[4]/block[6]/@bpd"/>
+    <eval expected="54200" xpath="//flow/block[4]/block[6]/@bpda"/>
+    <eval expected="105000" xpath="//flow/block[4]/block[6]/@left-offset"/>
+    <eval expected="36900" xpath="//flow/block[4]/block[6]/@top-offset"/>
+    <eval expected="0" xpath="count(//flow/block[4]/block[6]/@border-before)"/>
+    <eval expected="(dashed,#ff0000,4000,collapse-inner)" xpath="//flow/block[4]/block[6]/@border-after"/>
+    <eval expected="(dashed,#ff0000,10000,collapse-inner)" xpath="//flow/block[4]/block[6]/@border-start"/>
+    <eval expected="(solid,#800000,10000,collapse-inner)" xpath="//flow/block[4]/block[6]/@border-end"/>
+    <!-- row 2 cell 3 -->
+    <eval expected="92000" xpath="//flow/block[4]/block[7]/@ipd"/>
+    <eval expected="108000" xpath="//flow/block[4]/block[7]/@ipda"/>
+    <eval expected="46700" xpath="//flow/block[4]/block[7]/@bpd"/>
+    <eval expected="57700" xpath="//flow/block[4]/block[7]/@bpda"/>
+    <eval expected="205000" xpath="//flow/block[4]/block[7]/@left-offset"/>
+    <eval expected="34400" xpath="//flow/block[4]/block[7]/@top-offset"/>
+    <eval expected="(solid,#008000,5000,collapse-inner)" xpath="//flow/block[4]/block[7]/@border-before"/>
+    <eval expected="(dotted,#800000,6000,collapse-inner)" xpath="//flow/block[4]/block[7]/@border-after"/>
+    <eval expected="(solid,#800000,10000,collapse-inner)" xpath="//flow/block[4]/block[7]/@border-start"/>
+    <eval expected="(ridge,#800000,6000,collapse-inner)" xpath="//flow/block[4]/block[7]/@border-end"/>
+    <!-- row 2 cell 4 -->
+    <eval expected="94500" xpath="//flow/block[4]/block[8]/@ipd"/>
+    <eval expected="105500" xpath="//flow/block[4]/block[8]/@ipda"/>
+    <eval expected="34700" xpath="//flow/block[4]/block[8]/@bpd"/>
+    <eval expected="69700" xpath="//flow/block[4]/block[8]/@bpda"/>
+    <eval expected="303000" xpath="//flow/block[4]/block[8]/@left-offset"/>
+    <eval expected="21900" xpath="//flow/block[4]/block[8]/@top-offset"/>
+    <eval expected="(solid,#000080,30000,collapse-inner)" xpath="//flow/block[4]/block[8]/@border-before"/>
+    <eval expected="(ridge,#800080,5000,collapse-inner)" xpath="//flow/block[4]/block[8]/@border-after"/>
+    <eval expected="(ridge,#800000,6000,collapse-inner)" xpath="//flow/block[4]/block[8]/@border-start"/>
+    <eval expected="(solid,#800080,5000,collapse-outer)" xpath="//flow/block[4]/block[8]/@border-end"/>
+    <!-- row 3 cell 1 -->
+    <eval expected="82000" xpath="//flow/block[4]/block[9]/@ipd"/>
+    <eval expected="118000" xpath="//flow/block[4]/block[9]/@ipda"/>
+    <eval expected="41700" xpath="//flow/block[4]/block[9]/@bpd"/>
+    <eval expected="53700" xpath="//flow/block[4]/block[9]/@bpda"/>
+    <eval expected="15000" xpath="//flow/block[4]/block[9]/@left-offset"/>
+    <eval expected="86100" xpath="//flow/block[4]/block[9]/@top-offset"/>
+    <eval expected="(double,#ff00ff,6000,collapse-inner)" xpath="//flow/block[4]/block[9]/@border-before"/>
+    <eval expected="(inset,#ff00ff,6000,collapse-inner)" xpath="//flow/block[4]/block[9]/@border-after"/>
+    <eval expected="(solid,#ff00ff,30000,collapse-outer)" xpath="//flow/block[4]/block[9]/@border-start"/>
+    <eval expected="(inset,#ff00ff,6000,collapse-inner)" xpath="//flow/block[4]/block[9]/@border-end"/>
+    <!-- row 3 cell 2 -->
+    <eval expected="92000" xpath="//flow/block[4]/block[10]/@ipd"/>
+    <eval expected="108000" xpath="//flow/block[4]/block[10]/@ipda"/>
+    <eval expected="43200" xpath="//flow/block[4]/block[10]/@bpd"/>
+    <eval expected="52200" xpath="//flow/block[4]/block[10]/@bpda"/>
+    <eval expected="103000" xpath="//flow/block[4]/block[10]/@left-offset"/>
+    <eval expected="87100" xpath="//flow/block[4]/block[10]/@top-offset"/>
+    <eval expected="(dashed,#00ff00,4000,collapse-inner)" xpath="//flow/block[4]/block[10]/@border-before"/>
+    <eval expected="(outset,#00ff00,5000,collapse-inner)" xpath="//flow/block[4]/block[10]/@border-after"/>
+    <eval expected="(inset,#ff00ff,6000,collapse-inner)" xpath="//flow/block[4]/block[10]/@border-start"/>
+    <eval expected="(dotted,#008080,10000,collapse-inner)" xpath="//flow/block[4]/block[10]/@border-end"/>
+    <!-- row 3 cell 3 -->
+    <eval expected="95000" xpath="//flow/block[4]/block[11]/@ipd"/>
+    <eval expected="105000" xpath="//flow/block[4]/block[11]/@ipda"/>
+    <eval expected="42700" xpath="//flow/block[4]/block[11]/@bpd"/>
+    <eval expected="52700" xpath="//flow/block[4]/block[11]/@bpda"/>
+    <eval expected="205000" xpath="//flow/block[4]/block[11]/@left-offset"/>
+    <eval expected="86100" xpath="//flow/block[4]/block[11]/@top-offset"/>
+    <eval expected="(dotted,#008080,6000,collapse-inner)" xpath="//flow/block[4]/block[11]/@border-before"/>
+    <eval expected="(double,#008000,4000,collapse-inner)" xpath="//flow/block[4]/block[11]/@border-after"/>
+    <eval expected="(dotted,#008080,10000,collapse-inner)" xpath="//flow/block[4]/block[11]/@border-start"/>
+    <eval expected="0" xpath="count(//flow/block[4]/block[11]/@border-end)"/>
+    <!-- row 3 cell 4 -->
+    <eval expected="100000" xpath="//flow/block[4]/block[12]/@ipd"/>
+    <eval expected="100000" xpath="//flow/block[4]/block[12]/@ipda"/>
+    <eval expected="42200" xpath="//flow/block[4]/block[12]/@bpd"/>
+    <eval expected="53200" xpath="//flow/block[4]/block[12]/@bpda"/>
+    <eval expected="300000" xpath="//flow/block[4]/block[12]/@left-offset"/>
+    <eval expected="86600" xpath="//flow/block[4]/block[12]/@top-offset"/>
+    <eval expected="(ridge,#800000,5000,collapse-inner)" xpath="//flow/block[4]/block[12]/@border-before"/>
+    <eval expected="(solid,#800000,6000,collapse-inner)" xpath="//flow/block[4]/block[12]/@border-after"/>
+    <eval expected="0" xpath="count(//flow/block[4]/block[12]/@border-start)"/>
+    <eval expected="0" xpath="count(//flow/block[4]/block[12]/@border-end)"/>
+    <!-- row 4 cell 1 -->
+    <eval expected="78000" xpath="//flow/block[4]/block[13]/@ipd"/>
+    <eval expected="122000" xpath="//flow/block[4]/block[13]/@ipda"/>
+    <eval expected="56300" xpath="//flow/block[4]/block[13]/@bpd"/>
+    <eval expected="66300" xpath="//flow/block[4]/block[13]/@bpda"/>
+    <eval expected="2000" xpath="//flow/block[4]/block[13]/@left-offset"/>
+    <eval expected="133800" xpath="//flow/block[4]/block[13]/@top-offset"/>
+    <eval expected="(inset,#000000,6000,collapse-inner)" xpath="//flow/block[4]/block[13]/@border-before"/>
+    <eval expected="(solid,#000000,4000,collapse-outer)" xpath="//flow/block[4]/block[13]/@border-after"/>
+    <eval expected="(solid,#000000,4000,collapse-outer)" xpath="//flow/block[4]/block[13]/@border-start"/>
+    <eval expected="(solid,#000000,40000,collapse-inner)" xpath="//flow/block[4]/block[13]/@border-end"/>
+    <!-- row 4 cell 2 -->
+    <eval expected="77000" xpath="//flow/block[4]/block[14]/@ipd"/>
+    <eval expected="123000" xpath="//flow/block[4]/block[14]/@ipda"/>
+    <eval expected="28800" xpath="//flow/block[4]/block[14]/@bpd"/>
+    <eval expected="93800" xpath="//flow/block[4]/block[14]/@bpda"/>
+    <eval expected="120000" xpath="//flow/block[4]/block[14]/@left-offset"/>
+    <eval expected="134300" xpath="//flow/block[4]/block[14]/@top-offset"/>
+    <eval expected="(outset,#c0c0c0,5000,collapse-inner)" xpath="//flow/block[4]/block[14]/@border-before"/>
+    <eval expected="(solid,#c0c0c0,60000,collapse-outer)" xpath="//flow/block[4]/block[14]/@border-after"/>
+    <eval expected="(solid,#000000,40000,collapse-inner)" xpath="//flow/block[4]/block[14]/@border-start"/>
+    <eval expected="(solid,#008000,6000,collapse-inner)" xpath="//flow/block[4]/block[14]/@border-end"/>
+    <!-- row 4 cell 3 -->
+    <eval expected="94500" xpath="//flow/block[4]/block[15]/@ipd"/>
+    <eval expected="105500" xpath="//flow/block[4]/block[15]/@ipda"/>
+    <eval expected="56800" xpath="//flow/block[4]/block[15]/@bpd"/>
+    <eval expected="65800" xpath="//flow/block[4]/block[15]/@bpda"/>
+    <eval expected="203000" xpath="//flow/block[4]/block[15]/@left-offset"/>
+    <eval expected="134800" xpath="//flow/block[4]/block[15]/@top-offset"/>
+    <eval expected="(double,#008000,4000,collapse-inner)" xpath="//flow/block[4]/block[15]/@border-before"/>
+    <eval expected="(solid,#008000,5000,collapse-outer)" xpath="//flow/block[4]/block[15]/@border-after"/>
+    <eval expected="(solid,#008000,6000,collapse-inner)" xpath="//flow/block[4]/block[15]/@border-start"/>
+    <eval expected="(dashed,#008000,5000,collapse-inner)" xpath="//flow/block[4]/block[15]/@border-end"/>
+    <!-- row 4 cell 4 -->
+    <eval expected="72500" xpath="//flow/block[4]/block[16]/@ipd"/>
+    <eval expected="127500" xpath="//flow/block[4]/block[16]/@ipda"/>
+    <eval expected="43300" xpath="//flow/block[4]/block[16]/@bpd"/>
+    <eval expected="79300" xpath="//flow/block[4]/block[16]/@bpda"/>
+    <eval expected="302500" xpath="//flow/block[4]/block[16]/@left-offset"/>
+    <eval expected="133800" xpath="//flow/block[4]/block[16]/@top-offset"/>
+    <eval expected="(solid,#800000,6000,collapse-inner)" xpath="//flow/block[4]/block[16]/@border-before"/>
+    <eval expected="(solid,#000080,30000,collapse-outer)" xpath="//flow/block[4]/block[16]/@border-after"/>
+    <eval expected="(dashed,#008000,5000,collapse-inner)" xpath="//flow/block[4]/block[16]/@border-start"/>
+    <eval expected="(solid,#000080,50000,collapse-outer)" xpath="//flow/block[4]/block[16]/@border-end"/>
+  </checks>
+</testcase>

Propchange: xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/table_border-collapse_collapse_nrnc_no-col.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/table_border-collapse_collapse_nrnc_no-col.xml
------------------------------------------------------------------------------
    svn:keywords = Id

Added: xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/table_border-collapse_collapse_resolution.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/table_border-collapse_collapse_resolution.xml?rev=594571&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/table_border-collapse_collapse_resolution.xml (added)
+++ xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/table_border-collapse_collapse_resolution.xml Tue Nov 13 08:24:32 2007
@@ -0,0 +1,337 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<!-- $Id$ -->
+<testcase>
+  <info>
+    <p>
+      This test checks tables with collapsing-border model. Resolution between table, table-body,
+      table-row, table-cell...
+    </p>
+  </info>
+  <fo>
+    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">
+      <fo:layout-master-set>
+        <fo:simple-page-master master-name="normal" page-width="20cm" page-height="15cm" margin="20pt">
+          <fo:region-body margin="0pt"/>
+        </fo:simple-page-master>
+      </fo:layout-master-set>
+      <fo:page-sequence master-reference="normal">
+        <fo:flow flow-name="xsl-region-body">
+          <fo:block>Before the tables</fo:block>
+
+          <!-- table 1 -->
+          <fo:table table-layout="fixed" width="400pt" border-collapse="collapse"
+            border="10pt solid black">
+            <fo:table-column column-width="proportional-column-width(1)"/>
+            <fo:table-column column-width="proportional-column-width(1)"
+              border="6pt solid blue" border-before-width="12pt" border-after-width="14pt"/>
+            <fo:table-column column-width="proportional-column-width(1)"/>
+            <fo:table-column column-width="proportional-column-width(1)"/>
+            <fo:table-body border="4pt solid red" border-after-width="12pt">
+              <fo:table-row border="2pt solid green">
+                <fo:table-cell border="1pt solid yellow" border-start-width="12pt">
+                  <fo:block>Cell 1.1</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid yellow">
+                  <fo:block>Cell 1.2</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid yellow" border-before-width="12pt">
+                  <fo:block>Cell 1.3</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid yellow" border-end-width="12pt"
+                  number-rows-spanned="2">
+                  <fo:block>Cell 1.4</fo:block>
+                </fo:table-cell>
+              </fo:table-row>
+              <fo:table-row border="2pt solid green" border-start-width="12pt">
+                <fo:table-cell border="1pt solid yellow" number-rows-spanned="2">
+                  <fo:block>Cell 2.1</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid yellow">
+                  <fo:block>Cell 2.2</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid yellow">
+                  <fo:block>Cell 2.3</fo:block>
+                </fo:table-cell>
+              </fo:table-row>
+              <fo:table-row border="2pt solid cyan">
+                <fo:table-cell border="1pt solid yellow" border-before-width="12pt">
+                  <fo:block>Cell 3.2</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid yellow" border-after-width="14pt">
+                  <fo:block>Cell 3.3</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid yellow">
+                  <fo:block>Cell 3.4</fo:block>
+                </fo:table-cell>
+              </fo:table-row>
+            </fo:table-body>
+          </fo:table>
+
+          <!-- table 2 -->
+          <fo:block space-before="10pt" space-after="10pt">Between tables</fo:block>
+          <fo:table table-layout="fixed" width="400pt" border-collapse="collapse"
+            border="10pt solid black">
+            <fo:table-column column-width="proportional-column-width(1)"/>
+            <fo:table-column column-width="proportional-column-width(1)"
+              border="6pt solid blue" border-before-width="12pt" border-after-width="14pt"/>
+            <fo:table-column column-width="proportional-column-width(1)"/>
+            <fo:table-column column-width="proportional-column-width(1)"/>
+            <fo:table-header border="4pt solid magenta">
+              <fo:table-row border="2pt solid green">
+                <fo:table-cell border="1pt solid yellow">
+                  <fo:block>Header 1.1</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid yellow">
+                  <fo:block>Header 1.2</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid yellow">
+                  <fo:block>Header 1.3</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid grey" border-after-width="10pt">
+                  <fo:block>Header 1.4</fo:block>
+                </fo:table-cell>
+              </fo:table-row>
+            </fo:table-header>
+            <fo:table-footer border="4pt solid olive" border-after-width="12pt">
+              <fo:table-row border="2pt solid green">
+                <fo:table-cell border="1pt solid yellow">
+                  <fo:block>Footer 1.1</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid yellow">
+                  <fo:block>Footer 1.2</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid yellow">
+                  <fo:block>Footer 1.3</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid yellow" border-after-width="14pt"
+                  border-before-color="black" border-before-width="16pt">
+                  <fo:block>Footer 1.4</fo:block>
+                </fo:table-cell>
+              </fo:table-row>
+            </fo:table-footer>
+            <fo:table-body border="4pt solid red" border-after-width="12pt">
+              <fo:table-row border="2pt solid green">
+                <fo:table-cell border="1pt solid yellow" border-start-width="12pt">
+                  <fo:block>Cell 1.1</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid yellow">
+                  <fo:block>Cell 1.2</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid yellow" border-before-width="12pt">
+                  <fo:block>Cell 1.3</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid yellow" border-end-width="12pt"
+                  number-rows-spanned="2">
+                  <fo:block>Cell 1.4</fo:block>
+                </fo:table-cell>
+              </fo:table-row>
+              <fo:table-row border="2pt solid green" border-start-width="12pt">
+                <fo:table-cell border="1pt solid yellow" number-rows-spanned="2">
+                  <fo:block>Cell 2.1</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid yellow">
+                  <fo:block>Cell 2.2</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid yellow">
+                  <fo:block>Cell 2.3</fo:block>
+                </fo:table-cell>
+              </fo:table-row>
+              <fo:table-row border="2pt solid cyan">
+                <fo:table-cell border="1pt solid yellow" border-before-width="12pt">
+                  <fo:block>Cell 3.2</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid yellow" border-after-width="14pt">
+                  <fo:block>Cell 3.3</fo:block>
+                </fo:table-cell>
+                <fo:table-cell border="1pt solid yellow">
+                  <fo:block>Cell 3.4</fo:block>
+                </fo:table-cell>
+              </fo:table-row>
+            </fo:table-body>
+          </fo:table>
+
+          <fo:block>After the tables</fo:block>
+        </fo:flow>
+      </fo:page-sequence>
+    </fo:root>
+  </fo>
+  <checks>
+
+    <!-- table 1 -->
+    <!-- cell 1.1 -->
+    <eval expected="(solid,#000000,10000,collapse-outer)" xpath="//flow/block[2]/block[1]/@border-before"/>
+    <eval expected="(solid,#008000,2000,collapse-inner)" xpath="//flow/block[2]/block[1]/@border-after"/>
+    <eval expected="(solid,#ffff00,12000,collapse-outer)" xpath="//flow/block[2]/block[1]/@border-start"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[2]/block[1]/@border-end"/>
+    <!-- cell 1.2 -->
+    <eval expected="(solid,#0000ff,12000,collapse-outer)" xpath="//flow/block[2]/block[2]/@border-before"/>
+    <eval expected="(solid,#008000,2000,collapse-inner)" xpath="//flow/block[2]/block[2]/@border-after"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[2]/block[2]/@border-start"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[2]/block[2]/@border-end"/>
+    <!-- cell 1.3 -->
+    <eval expected="(solid,#ffff00,12000,collapse-outer)" xpath="//flow/block[2]/block[3]/@border-before"/>
+    <eval expected="(solid,#008000,2000,collapse-inner)" xpath="//flow/block[2]/block[3]/@border-after"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[2]/block[3]/@border-start"/>
+    <eval expected="(solid,#ffff00,1000,collapse-inner)" xpath="//flow/block[2]/block[3]/@border-end"/>
+    <!-- cell 2.2 -->
+    <eval expected="(solid,#008000,2000,collapse-inner)" xpath="//flow/block[2]/block[4]/@border-before"/>
+    <eval expected="(solid,#ffff00,12000,collapse-inner)" xpath="//flow/block[2]/block[4]/@border-after"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[2]/block[4]/@border-start"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[2]/block[4]/@border-end"/>
+    <!-- cell 2.3 -->
+    <eval expected="(solid,#008000,2000,collapse-inner)" xpath="//flow/block[2]/block[5]/@border-before"/>
+    <eval expected="(solid,#008000,2000,collapse-inner)" xpath="//flow/block[2]/block[5]/@border-after"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[2]/block[5]/@border-start"/>
+    <eval expected="(solid,#ffff00,1000,collapse-inner)" xpath="//flow/block[2]/block[5]/@border-end"/>
+    <!-- cell 1.4 -->
+    <eval expected="(solid,#000000,10000,collapse-outer)" xpath="//flow/block[2]/block[6]/@border-before"/>
+    <eval expected="" xpath="//flow/block[2]/block[6]/@border-after"/>
+    <eval expected="(solid,#ffff00,1000,collapse-inner)" xpath="//flow/block[2]/block[6]/@border-start"/>
+    <eval expected="(solid,#ffff00,12000,collapse-outer)" xpath="//flow/block[2]/block[6]/@border-end"/>
+    <eval expected="" xpath="//flow/block[2]/block[7]/@border-before"/>
+    <eval expected="(solid,#008000,2000,collapse-inner)" xpath="//flow/block[2]/block[7]/@border-after"/>
+    <eval expected="(solid,#ffff00,1000,collapse-inner)" xpath="//flow/block[2]/block[7]/@border-start"/>
+    <eval expected="(solid,#ffff00,12000,collapse-outer)" xpath="//flow/block[2]/block[7]/@border-end"/>
+    <!-- cell 2.1 -->
+    <eval expected="(solid,#008000,2000,collapse-inner)" xpath="//flow/block[2]/block[9]/@border-before"/>
+    <eval expected="" xpath="//flow/block[2]/block[9]/@border-after"/>
+    <eval expected="(solid,#008000,12000,collapse-outer)" xpath="//flow/block[2]/block[9]/@border-start"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[2]/block[9]/@border-end"/>
+    <eval expected="" xpath="//flow/block[2]/block[10]/@border-before"/>
+    <eval expected="(solid,#ff0000,12000,collapse-outer)" xpath="//flow/block[2]/block[10]/@border-after"/>
+    <eval expected="(solid,#000000,10000,collapse-outer)" xpath="//flow/block[2]/block[10]/@border-start"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[2]/block[10]/@border-end"/>
+    <!-- cell 3.2 -->
+    <eval expected="(solid,#ffff00,12000,collapse-inner)" xpath="//flow/block[2]/block[12]/@border-before"/>
+    <eval expected="(solid,#0000ff,14000,collapse-outer)" xpath="//flow/block[2]/block[12]/@border-after"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[2]/block[12]/@border-start"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[2]/block[12]/@border-end"/>
+    <!-- cell 3.3 -->
+    <eval expected="(solid,#00ffff,2000,collapse-inner)" xpath="//flow/block[2]/block[13]/@border-before"/>
+    <eval expected="(solid,#ffff00,14000,collapse-outer)" xpath="//flow/block[2]/block[13]/@border-after"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[2]/block[13]/@border-start"/>
+    <eval expected="(solid,#ffff00,1000,collapse-inner)" xpath="//flow/block[2]/block[13]/@border-end"/>
+    <!-- cell 3.4 -->
+    <eval expected="(solid,#00ffff,2000,collapse-inner)" xpath="//flow/block[2]/block[14]/@border-before"/>
+    <eval expected="(solid,#ff0000,12000,collapse-outer)" xpath="//flow/block[2]/block[14]/@border-after"/>
+    <eval expected="(solid,#ffff00,1000,collapse-inner)" xpath="//flow/block[2]/block[14]/@border-start"/>
+    <eval expected="(solid,#000000,10000,collapse-outer)" xpath="//flow/block[2]/block[14]/@border-end"/>
+
+    <!-- table 2 -->
+    <!-- header 1.1 -->
+    <eval expected="(solid,#000000,10000,collapse-outer)" xpath="//flow/block[4]/block[1]/@border-before"/>
+    <eval expected="(solid,#ff00ff,4000,collapse-inner)" xpath="//flow/block[4]/block[1]/@border-after"/>
+    <eval expected="(solid,#000000,10000,collapse-outer)" xpath="//flow/block[4]/block[1]/@border-start"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[4]/block[1]/@border-end"/>
+    <!-- header 1.2 -->
+    <eval expected="(solid,#0000ff,12000,collapse-outer)" xpath="//flow/block[4]/block[2]/@border-before"/>
+    <eval expected="(solid,#ff00ff,4000,collapse-inner)" xpath="//flow/block[4]/block[2]/@border-after"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[4]/block[2]/@border-start"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[4]/block[2]/@border-end"/>
+    <!-- header 1.3 -->
+    <eval expected="(solid,#000000,10000,collapse-outer)" xpath="//flow/block[4]/block[3]/@border-before"/>
+    <eval expected="(solid,#ffff00,12000,collapse-inner)" xpath="//flow/block[4]/block[3]/@border-after"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[4]/block[3]/@border-start"/>
+    <eval expected="(solid,#ffff00,1000,collapse-inner)" xpath="//flow/block[4]/block[3]/@border-end"/>
+    <!-- header 1.4 -->
+    <eval expected="(solid,#000000,10000,collapse-outer)" xpath="//flow/block[4]/block[4]/@border-before"/>
+    <eval expected="(solid,#808080,10000,collapse-inner)" xpath="//flow/block[4]/block[4]/@border-after"/>
+    <eval expected="(solid,#808080,1000,collapse-inner)" xpath="//flow/block[4]/block[4]/@border-start"/>
+    <eval expected="(solid,#000000,10000,collapse-outer)" xpath="//flow/block[4]/block[4]/@border-end"/>
+    <!-- cell 1.1 -->
+    <eval expected="(solid,#ff0000,4000,collapse-inner)" xpath="//flow/block[4]/block[5]/@border-before"/>
+    <eval expected="(solid,#008000,2000,collapse-inner)" xpath="//flow/block[4]/block[5]/@border-after"/>
+    <eval expected="(solid,#ffff00,12000,collapse-outer)" xpath="//flow/block[4]/block[5]/@border-start"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[4]/block[5]/@border-end"/>
+    <!-- cell 1.2 -->
+    <eval expected="(solid,#ff0000,4000,collapse-inner)" xpath="//flow/block[4]/block[6]/@border-before"/>
+    <eval expected="(solid,#008000,2000,collapse-inner)" xpath="//flow/block[4]/block[6]/@border-after"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[4]/block[6]/@border-start"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[4]/block[6]/@border-end"/>
+    <!-- cell 1.3 -->
+    <eval expected="(solid,#ffff00,12000,collapse-inner)" xpath="//flow/block[4]/block[7]/@border-before"/>
+    <eval expected="(solid,#008000,2000,collapse-inner)" xpath="//flow/block[4]/block[7]/@border-after"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[4]/block[7]/@border-start"/>
+    <eval expected="(solid,#ffff00,1000,collapse-inner)" xpath="//flow/block[4]/block[7]/@border-end"/>
+    <!-- cell 2.2 -->
+    <eval expected="(solid,#008000,2000,collapse-inner)" xpath="//flow/block[4]/block[8]/@border-before"/>
+    <eval expected="(solid,#ffff00,12000,collapse-inner)" xpath="//flow/block[4]/block[8]/@border-after"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[4]/block[8]/@border-start"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[4]/block[8]/@border-end"/>
+    <!-- cell 2.3 -->
+    <eval expected="(solid,#008000,2000,collapse-inner)" xpath="//flow/block[4]/block[9]/@border-before"/>
+    <eval expected="(solid,#008000,2000,collapse-inner)" xpath="//flow/block[4]/block[9]/@border-after"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[4]/block[9]/@border-start"/>
+    <eval expected="(solid,#ffff00,1000,collapse-inner)" xpath="//flow/block[4]/block[9]/@border-end"/>
+    <!-- cell 1.4 -->
+    <eval expected="(solid,#808080,10000,collapse-inner)" xpath="//flow/block[4]/block[10]/@border-before"/>
+    <eval expected="" xpath="//flow/block[4]/block[10]/@border-after"/>
+    <eval expected="(solid,#ffff00,1000,collapse-inner)" xpath="//flow/block[4]/block[10]/@border-start"/>
+    <eval expected="(solid,#ffff00,12000,collapse-outer)" xpath="//flow/block[4]/block[10]/@border-end"/>
+    <eval expected="" xpath="//flow/block[4]/block[11]/@border-before"/>
+    <eval expected="(solid,#008000,2000,collapse-inner)" xpath="//flow/block[4]/block[11]/@border-after"/>
+    <eval expected="(solid,#ffff00,1000,collapse-inner)" xpath="//flow/block[4]/block[11]/@border-start"/>
+    <eval expected="(solid,#ffff00,12000,collapse-outer)" xpath="//flow/block[4]/block[11]/@border-end"/>
+    <!-- cell 2.1 -->
+    <eval expected="(solid,#008000,2000,collapse-inner)" xpath="//flow/block[4]/block[13]/@border-before"/>
+    <eval expected="" xpath="//flow/block[4]/block[13]/@border-after"/>
+    <eval expected="(solid,#008000,12000,collapse-outer)" xpath="//flow/block[4]/block[13]/@border-start"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[4]/block[13]/@border-end"/>
+    <eval expected="" xpath="//flow/block[4]/block[14]/@border-before"/>
+    <eval expected="(solid,#ff0000,12000,collapse-inner)" xpath="//flow/block[4]/block[14]/@border-after"/>
+    <eval expected="(solid,#000000,10000,collapse-outer)" xpath="//flow/block[4]/block[14]/@border-start"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[4]/block[14]/@border-end"/>
+    <!-- cell 3.2 -->
+    <eval expected="(solid,#ffff00,12000,collapse-inner)" xpath="//flow/block[4]/block[16]/@border-before"/>
+    <eval expected="(solid,#ff0000,12000,collapse-inner)" xpath="//flow/block[4]/block[16]/@border-after"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[4]/block[16]/@border-start"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[4]/block[16]/@border-end"/>
+    <!-- cell 3.3 -->
+    <eval expected="(solid,#00ffff,2000,collapse-inner)" xpath="//flow/block[4]/block[17]/@border-before"/>
+    <eval expected="(solid,#ffff00,14000,collapse-inner)" xpath="//flow/block[4]/block[17]/@border-after"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[4]/block[17]/@border-start"/>
+    <eval expected="(solid,#ffff00,1000,collapse-inner)" xpath="//flow/block[4]/block[17]/@border-end"/>
+    <!-- cell 3.4 -->
+    <eval expected="(solid,#00ffff,2000,collapse-inner)" xpath="//flow/block[4]/block[18]/@border-before"/>
+    <eval expected="(solid,#000000,16000,collapse-inner)" xpath="//flow/block[4]/block[18]/@border-after"/>
+    <eval expected="(solid,#ffff00,1000,collapse-inner)" xpath="//flow/block[4]/block[18]/@border-start"/>
+    <eval expected="(solid,#000000,10000,collapse-outer)" xpath="//flow/block[4]/block[18]/@border-end"/>
+    <!-- footer 1.1 -->
+    <eval expected="(solid,#ff0000,12000,collapse-inner)" xpath="//flow/block[4]/block[19]/@border-before"/>
+    <eval expected="(solid,#808000,12000,collapse-outer)" xpath="//flow/block[4]/block[19]/@border-after"/>
+    <eval expected="(solid,#000000,10000,collapse-outer)" xpath="//flow/block[4]/block[19]/@border-start"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[4]/block[19]/@border-end"/>
+    <!-- footer 1.2 -->
+    <eval expected="(solid,#ff0000,12000,collapse-inner)" xpath="//flow/block[4]/block[20]/@border-before"/>
+    <eval expected="(solid,#0000ff,14000,collapse-outer)" xpath="//flow/block[4]/block[20]/@border-after"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[4]/block[20]/@border-start"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[4]/block[20]/@border-end"/>
+    <!-- footer 1.3 -->
+    <eval expected="(solid,#ffff00,14000,collapse-inner)" xpath="//flow/block[4]/block[21]/@border-before"/>
+    <eval expected="(solid,#808000,12000,collapse-outer)" xpath="//flow/block[4]/block[21]/@border-after"/>
+    <eval expected="(solid,#0000ff,6000,collapse-inner)" xpath="//flow/block[4]/block[21]/@border-start"/>
+    <eval expected="(solid,#ffff00,1000,collapse-inner)" xpath="//flow/block[4]/block[21]/@border-end"/>
+    <!-- footer 1.4 -->
+    <eval expected="(solid,#000000,16000,collapse-inner)" xpath="//flow/block[4]/block[22]/@border-before"/>
+    <eval expected="(solid,#ffff00,14000,collapse-outer)" xpath="//flow/block[4]/block[22]/@border-after"/>
+    <eval expected="(solid,#ffff00,1000,collapse-inner)" xpath="//flow/block[4]/block[22]/@border-start"/>
+    <eval expected="(solid,#000000,10000,collapse-outer)" xpath="//flow/block[4]/block[22]/@border-end"/>
+
+  </checks>
+</testcase>

Propchange: xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/table_border-collapse_collapse_resolution.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: xmlgraphics/fop/trunk/test/layoutengine/standard-testcases/table_border-collapse_collapse_resolution.xml
------------------------------------------------------------------------------
    svn:keywords = Id



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