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 je...@apache.org on 2007/12/12 17:13:16 UTC

svn commit: r603656 [2/7] - in /xmlgraphics/fop/branches/Temp_ImagePackageRedesign: ./ examples/fo/basic/ lib/ src/documentation/ src/documentation/content/xdocs/ src/documentation/content/xdocs/trunk/ src/documentation/intermediate-format-ng/ src/java...

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/Table.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/Table.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/Table.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/Table.java Wed Dec 12 08:13:06 2007
@@ -20,7 +20,6 @@
 package org.apache.fop.fo.flow.table;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
 import org.apache.fop.apps.FOPException;
@@ -154,7 +153,7 @@
     /**
      * {@inheritDoc}
      */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         getFOEventHandler().startTable(this);
     }
@@ -211,7 +210,7 @@
     /**
      * {@inheritDoc}
      */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
 
         if (!tableBodyFound) {
            missingChildElementError(
@@ -219,6 +218,11 @@
                        + ",table-body+)");
         }
         if (!inMarker()) {
+            if (tableFooter != null) {
+                rowGroupBuilder.endTable(tableFooter);
+            } else {
+                rowGroupBuilder.endTable((TableBody) getChildNodes().lastNode());
+            }
             /* clean up */
             for (int i = columns.size(); --i >= 0;) {
                 TableColumn col = (TableColumn) columns.get(i);
@@ -278,6 +282,13 @@
         }
     }
 
+    protected void setCollapsedBorders() {
+        createBorder(CommonBorderPaddingBackground.START);
+        createBorder(CommonBorderPaddingBackground.END);
+        createBorder(CommonBorderPaddingBackground.BEFORE);
+        createBorder(CommonBorderPaddingBackground.AFTER);
+    }
+
     private void finalizeColumns() throws FOPException {
         for (int i = 0; i < columns.size(); i++) {
             if (columns.get(i) == null) {
@@ -305,32 +316,6 @@
         for (int i = columns.size() + 1; i <= columnNumber; i++) {
             columns.add(createImplicitColumn(i));
         }
-        ((VariableColRowGroupBuilder) rowGroupBuilder).ensureNumberOfColumns(columnNumber);
-        if (tableHeader != null) {
-            for (Iterator iter = tableHeader.getRowGroups().iterator(); iter.hasNext();) {
-                VariableColRowGroupBuilder.fillWithEmptyGridUnits((List) iter.next(),
-                        columnNumber); 
-            }
-        }
-        if (tableFooter != null) {
-            for (Iterator iter = tableFooter.getRowGroups().iterator(); iter.hasNext();) {
-                VariableColRowGroupBuilder.fillWithEmptyGridUnits((List) iter.next(),
-                        columnNumber); 
-            }
-        }
-        FONodeIterator bodyIter = getChildNodes();
-        if (bodyIter != null) {
-            while (bodyIter.hasNext()) {
-                FONode node = bodyIter.nextNode();
-                if (node instanceof TableBody) { // AFAIK, may be a marker
-                    for (Iterator iter = ((TableBody) node).getRowGroups().iterator();
-                            iter.hasNext();) {
-                        VariableColRowGroupBuilder.fillWithEmptyGridUnits((List) iter.next(),
-                                columnNumber); 
-                    }
-                }
-            }
-        }
     }
 
     private TableColumn createImplicitColumn(int colNumber)
@@ -342,6 +327,9 @@
         implicitColumn.bind(pList);
         implicitColumn.setColumnWidth(new TableColLength(1.0, implicitColumn));
         implicitColumn.setColumnNumber(colNumber);
+        if (!isSeparateBorderModel()) {
+            implicitColumn.setCollapsedBorders(collapsingBorderModel); // TODO
+        }
         return implicitColumn;
     }
 

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableBody.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableBody.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableBody.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableBody.java Wed Dec 12 08:13:06 2007
@@ -50,15 +50,15 @@
     protected boolean tableRowsFound = false;
     protected boolean tableCellsFound = false;
 
-    /**
-     * used for initial values of column-number property
-     */
     private boolean firstRow = true;
 
     private boolean rowsStarted = false;
 
     private boolean lastCellEndsRow = true;
 
+    /** The last encountered table-row. */
+    private TableRow lastRow;
+
     private List rowGroups = new LinkedList();
 
     /**
@@ -101,14 +101,15 @@
     /**
      * {@inheritDoc}
      */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
+        super.startOfNode();
         getFOEventHandler().startBody(this);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
 
         if (!inMarker()) {
             pendingSpans = null;
@@ -130,16 +131,25 @@
         }
     }
 
+    /** {@inheritDoc} */
+    TableBody getTablePart() {
+        return this;
+    }
+
     protected void finishLastRowGroup() throws ValidationException {
-        RowGroupBuilder rowGroupBuilder = getTable().getRowGroupBuilder(); 
-        if (tableRowsFound || !lastCellEndsRow) {
-            rowGroupBuilder.signalRowEnd(this);
-        }
-        try {
-            rowGroupBuilder.signalEndOfPart(this);
-        } catch (ValidationException e) {
-            e.setLocator(locator);
-            throw e;
+        if (!inMarker()) {
+            RowGroupBuilder rowGroupBuilder = getTable().getRowGroupBuilder(); 
+            if (tableRowsFound) {
+                rowGroupBuilder.endRow(lastRow);
+            } else if (!lastCellEndsRow) {
+                rowGroupBuilder.endRow(this);
+            }
+            try {
+                rowGroupBuilder.endTablePart(this);
+            } catch (ValidationException e) {
+                e.setLocator(locator);
+                throw e;
+            }
         }
     }
 
@@ -184,13 +194,20 @@
         if (!inMarker()) {
             switch (child.getNameId()) {
             case FO_TABLE_ROW:
-                if (rowsStarted) {
+                if (!rowsStarted) {
+                    getTable().getRowGroupBuilder().startTablePart(this);
+                } else {
                     columnNumberManager.prepareForNextRow(pendingSpans);
-                    getTable().getRowGroupBuilder().signalRowEnd(this);
+                    getTable().getRowGroupBuilder().endRow(lastRow);
                 }
                 rowsStarted = true;
+                lastRow = (TableRow) child;
+                getTable().getRowGroupBuilder().startRow(lastRow);
                 break;
             case FO_TABLE_CELL:
+                if (!rowsStarted) {
+                    getTable().getRowGroupBuilder().startTablePart(this);
+                }
                 rowsStarted = true;
                 TableCell cell = (TableCell) child;
                 addTableCellChild(cell, firstRow);
@@ -198,7 +215,7 @@
                 if (lastCellEndsRow) {
                     firstRow = false;
                     columnNumberManager.prepareForNextRow(pendingSpans);
-                    getTable().getRowGroupBuilder().signalRowEnd(this);
+                    getTable().getRowGroupBuilder().endRow(this);
                 }
                 break;
             default:
@@ -208,11 +225,20 @@
         super.addChildNode(child);
     }
 
+    /** {inheritDoc} */
+    protected void setCollapsedBorders() {
+        Table table = (Table) parent;
+        createBorder(CommonBorderPaddingBackground.START, table);
+        createBorder(CommonBorderPaddingBackground.END, table);
+        createBorder(CommonBorderPaddingBackground.BEFORE);
+        createBorder(CommonBorderPaddingBackground.AFTER);
+    }
+
     void addRowGroup(List rowGroup) {
         rowGroups.add(rowGroup);
     }
 
-    List getRowGroups() {
+    public List getRowGroups() {
         return rowGroups;
     }
 
@@ -235,6 +261,10 @@
         return FO_TABLE_BODY;
     }
 
+    protected boolean isTableFooter() {
+        return false;
+    }
+
     /**
      * @param obj table row in question
      * @return true if the given table row is the first row of this body.
@@ -249,7 +279,7 @@
             firstRow = false;
             if (!lastCellEndsRow) {
                 columnNumberManager.prepareForNextRow(pendingSpans);
-                getTable().getRowGroupBuilder().signalRowEnd(this);
+                getTable().getRowGroupBuilder().endRow(this);
             }
         }
         rowsStarted = true;

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableCell.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableCell.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableCell.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableCell.java Wed Dec 12 08:13:06 2007
@@ -90,7 +90,7 @@
     /**
      * {@inheritDoc}
      */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         getFOEventHandler().startCell(this);
     }
@@ -100,7 +100,7 @@
      * FOEventHandler that we are at the end of the flow.
      * {@inheritDoc}
      */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         if (!blockItemFound) {
             if (getUserAgent().validateStrictly()) {
                 missingChildElementError("marker* (%block;)+");
@@ -131,6 +131,21 @@
             invalidChildError(loc, nsURI, localName);
         } else {
             blockItemFound = true;
+        }
+    }
+
+    /** {@inheritDoc} */
+    protected void setCollapsedBorders() {
+        createBorder(CommonBorderPaddingBackground.BEFORE);
+        createBorder(CommonBorderPaddingBackground.AFTER);
+        Table table = getTable();
+        if (table.hasExplicitColumns()) {
+            TableColumn col = table.getColumn(getColumnNumber() - 1);
+            createBorder(CommonBorderPaddingBackground.START, col);
+            createBorder(CommonBorderPaddingBackground.END, col);
+        } else {
+            createBorder(CommonBorderPaddingBackground.START);
+            createBorder(CommonBorderPaddingBackground.END);
         }
     }
 

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableCellContainer.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableCellContainer.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableCellContainer.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableCellContainer.java Wed Dec 12 08:13:06 2007
@@ -93,6 +93,13 @@
         }
     }
 
+    /**
+     * Returns the enclosing table-header/footer/body of this container.
+     * 
+     * @return <code>this</code> for TableBody, or the parent element for TableRow
+     */
+    abstract TableBody getTablePart();
+
     /** {@inheritDoc} */
     public ColumnNumberManager getColumnNumberManager() {
         return columnNumberManager;

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableColumn.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableColumn.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableColumn.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableColumn.java Wed Dec 12 08:13:06 2007
@@ -31,6 +31,7 @@
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 import org.apache.fop.fo.properties.Property;
 import org.apache.fop.fo.properties.TableColLength;
+import org.apache.fop.layoutmgr.table.CollapsingBorderModel;
 
 /**
  * Class modelling the fo:table-column object.
@@ -114,14 +115,27 @@
     /**
      * {@inheritDoc}
      */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
+        super.startOfNode();
         getFOEventHandler().startColumn(this);
     }
 
-    /**
-     * {@inheritDoc}
-     */
-    protected void endOfNode() throws FOPException {
+    void setCollapsedBorders(CollapsingBorderModel collapsingBorderModel) {
+        this.collapsingBorderModel = collapsingBorderModel;
+        setCollapsedBorders();
+    }
+
+    /** {@inheritDoc} */
+    protected void setCollapsedBorders() {
+        Table table = (Table) parent;
+        createBorder(CommonBorderPaddingBackground.BEFORE, table);
+        createBorder(CommonBorderPaddingBackground.AFTER, table);
+        createBorder(CommonBorderPaddingBackground.START);
+        createBorder(CommonBorderPaddingBackground.END);
+    }
+
+    /** {@inheritDoc} */
+    public void endOfNode() throws FOPException {
         getFOEventHandler().endColumn(this);
     }
 

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableFObj.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableFObj.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableFObj.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableFObj.java Wed Dec 12 08:13:06 2007
@@ -30,6 +30,7 @@
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 import org.apache.fop.fo.properties.NumberProperty;
 import org.apache.fop.fo.properties.Property;
+import org.apache.fop.layoutmgr.table.CollapsingBorderModel;
 
 /**
  * Common base class for table-related FOs
@@ -41,6 +42,10 @@
     private Numeric borderEndPrecedence;
     private Numeric borderStartPrecedence;
 
+    BorderSpecification[] resolvedBorders = new BorderSpecification[4]; // TODO
+
+    CollapsingBorderModel collapsingBorderModel;
+    
     /**
      * Main constructor
      * 
@@ -122,9 +127,7 @@
             super(propId);
         }
 
-        /**
-         * {@inheritDoc}
-         */
+        /** {@inheritDoc} */
         public Property make(PropertyList propertyList)
                 throws PropertyException {
             FObj fo = propertyList.getFObj();
@@ -188,5 +191,56 @@
 
             return p;
         }
+    }
+
+    /** {@inheritDoc} */
+    public void startOfNode() throws FOPException {
+        super.startOfNode();
+        Table table = getTable();
+        if (!inMarker() && !table.isSeparateBorderModel()) {
+            collapsingBorderModel = CollapsingBorderModel.getBorderModelFor(table
+                    .getBorderCollapse());
+            resolvedBorders = new BorderSpecification[4];
+            setCollapsedBorders();
+        }
+    }
+
+    /*
+     * TODO made public so that RetrieveMarker can access it.  
+     */
+    /** {@inheritDoc} */
+    public void endOfNode() throws FOPException {
+        super.endOfNode();
+    }
+
+    /**
+     * Prepares the borders of this element if the collapsing-border model is in use.
+     * Conflict resolution with parent elements is done where applicable.
+     */
+    protected abstract void setCollapsedBorders();
+
+    /**
+     * Creates a BorderSpecification from the border set on the given side. If no border
+     * is set, a BorderSpecification with border-style none is created.
+     * 
+     * @param side one of CommonBorderPaddingBackground.BEFORE|AFTER|START|END
+     */
+    protected void createBorder(int side) {
+        resolvedBorders[side] = new BorderSpecification(getCommonBorderPaddingBackground()
+                .getBorderInfo(side), getNameId()); 
+    }
+
+    /**
+     * Creates a BorderSpecification from the border set on the given side, performing
+     * conflict resolution with the same border on the given object.
+     * 
+     * @param side one of CommonBorderPaddingBackground.BEFORE|AFTER|START|END
+     * @param competitor a parent table element whose side coincides with the given side
+     * on this element
+     */
+    protected void createBorder(int side, TableFObj competitor) {
+        createBorder(side);
+        resolvedBorders[side] = collapsingBorderModel.determineWinner(resolvedBorders[side],
+                competitor.resolvedBorders[side]);
     }
 }

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableFooter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableFooter.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableFooter.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableFooter.java Wed Dec 12 08:13:06 2007
@@ -39,14 +39,15 @@
     /**
      * {@inheritDoc}
      */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
+        super.startOfNode();
         //getFOEventHandler().startBody(this);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
 //      getFOEventHandler().endFooter(this);
         if (!(tableRowsFound || tableCellsFound)) {
             missingChildElementError("marker* (table-row+|table-cell+)");
@@ -64,5 +65,10 @@
     /** {@inheritDoc} */
     public int getNameId() {
         return FO_TABLE_FOOTER;
+    }
+
+    /** {@inheritDoc} */
+    protected boolean isTableFooter() {
+        return true;
     }
 }

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableHeader.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableHeader.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableHeader.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableHeader.java Wed Dec 12 08:13:06 2007
@@ -39,14 +39,15 @@
     /**
      * {@inheritDoc}
      */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
+        super.startOfNode();
         //getFOEventHandler().startHeader(this);
     }
 
     /**
      * {@inheritDoc}
      */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
 //      getFOEventHandler().endHeader(this);
         if (!(tableRowsFound || tableCellsFound)) {
             missingChildElementError("marker* (table-row+|table-cell+)");

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableRow.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableRow.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableRow.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/TableRow.java Wed Dec 12 08:13:06 2007
@@ -97,7 +97,7 @@
     /**
      * {@inheritDoc}
      */
-    protected void startOfNode() throws FOPException {
+    public void startOfNode() throws FOPException {
         super.startOfNode();
         getFOEventHandler().startRow(this);
     }
@@ -105,7 +105,7 @@
     /**
      * {@inheritDoc}
      */
-    protected void endOfNode() throws FOPException {
+    public void endOfNode() throws FOPException {
         if (firstChild == null) {
             missingChildElementError("(table-cell+)");
         }
@@ -126,6 +126,25 @@
         if (!(FO_URI.equals(nsURI) && localName.equals("table-cell"))) {
             invalidChildError(loc, nsURI, localName);
         }
+    }
+
+    /** {@inheritDoc} */
+    TableBody getTablePart() {
+        return (TableBody) parent;
+    }
+
+    /** {@inheritDoc} */
+    boolean isTableRow() {
+        return true;
+    }
+
+    /** {inheritDoc} */
+    protected void setCollapsedBorders() {
+        TableBody body = (TableBody) parent;
+        createBorder(CommonBorderPaddingBackground.START, body);
+        createBorder(CommonBorderPaddingBackground.END, body);
+        createBorder(CommonBorderPaddingBackground.BEFORE);
+        createBorder(CommonBorderPaddingBackground.AFTER);
     }
 
     /** @return the "break-after" property. */

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/VariableColRowGroupBuilder.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/VariableColRowGroupBuilder.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/VariableColRowGroupBuilder.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/flow/table/VariableColRowGroupBuilder.java Wed Dec 12 08:13:06 2007
@@ -19,9 +19,12 @@
 
 package org.apache.fop.fo.flow.table;
 
+import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.List;
 
-import org.apache.fop.layoutmgr.table.EmptyGridUnit;
+import org.apache.fop.fo.ValidationException;
+
 
 /**
  * A row group builder accommodating a variable number of columns. More flexible, but less
@@ -31,34 +34,78 @@
 
     VariableColRowGroupBuilder(Table t) {
         super(t);
-        numberOfColumns = 1;
     }
 
     /**
-     * Fills the given row group with empty grid units if necessary, so that it matches
-     * the given number of columns.
-     * 
-     * @param rowGroup a List of List of GridUnit
-     * @param numberOfColumns the number of columns that the row group must have
+     * Each event is recorded and will be played once the table is finished, and the final
+     * number of columns known.
      */
-    static void fillWithEmptyGridUnits(List rowGroup, int numberOfColumns) {
-        for (int i = 0; i < rowGroup.size(); i++) {
-            List effRow = (List) rowGroup.get(i);
-            for (int j = effRow.size(); j < numberOfColumns; j++) {
-                effRow.add(new EmptyGridUnit(null, null, null, j));
+    private static interface Event {
+        /**
+         * Plays this event
+         * 
+         * @param rowGroupBuilder the delegate builder which will actually create the row
+         * groups
+         * @throws ValidationException if a row-spanning cell overflows its parent body
+         */
+        void play(RowGroupBuilder rowGroupBuilder) throws ValidationException;
+    }
+
+    /** The queue of events sent to this builder. */
+    private List events = new LinkedList();
+
+    /** {@inheritDoc} */
+    void addTableCell(final TableCell cell) {
+        events.add(new Event() {
+            public void play(RowGroupBuilder rowGroupBuilder) {
+                rowGroupBuilder.addTableCell(cell);
             }
-        }
+        });
     }
 
-    /**
-     * Updates the current row group to match the given number of columns, by adding empty
-     * grid units if necessary.
-     * 
-     * @param numberOfColumns new number of columns
-     */
-    void ensureNumberOfColumns(int numberOfColumns) {
-        this.numberOfColumns = numberOfColumns;
-        fillWithEmptyGridUnits(rows, numberOfColumns);
+    /** {@inheritDoc} */
+    void startRow(final TableRow tableRow) {
+        events.add(new Event() {
+            public void play(RowGroupBuilder rowGroupBuilder) {
+                rowGroupBuilder.startRow(tableRow);
+            }
+        });
     }
 
+    /** {@inheritDoc} */
+    void endRow(final TableCellContainer container) {
+        events.add(new Event() {
+            public void play(RowGroupBuilder rowGroupBuilder) {
+                rowGroupBuilder.endRow(container);
+            }
+        });
+    }
+
+    /** {@inheritDoc} */
+    void startTablePart(final TableBody part) {
+        events.add(new Event() {
+            public void play(RowGroupBuilder rowGroupBuilder) {
+                rowGroupBuilder.startTablePart(part);
+            }
+        });
+    }
+
+    /** {@inheritDoc} */
+    void endTablePart(final TableBody tableBody) throws ValidationException {
+        // TODO catch the ValidationException sooner?
+        events.add(new Event() {
+            public void play(RowGroupBuilder rowGroupBuilder) throws ValidationException {
+                rowGroupBuilder.endTablePart(tableBody);
+            }
+        });
+    }
+
+    /** {@inheritDoc} */
+    void endTable(final TableBody lastTablePart) throws ValidationException {
+        RowGroupBuilder delegate = new FixedColRowGroupBuilder(table);
+        for (Iterator eventIter = events.iterator(); eventIter.hasNext();) {
+            ((Event) eventIter.next()).play(delegate);
+        }
+        delegate.endTable(lastTablePart);
+    }
 }

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/properties/ColorProperty.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/properties/ColorProperty.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/properties/ColorProperty.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/properties/ColorProperty.java Wed Dec 12 08:13:06 2007
@@ -103,12 +103,12 @@
     }
 
     /**
-     * 
-     * @param value
-     * @return
+     * Returns an instance of a color property given a color
+     * @param color the color value
+     * @return the color property
      */
-    public static ColorProperty getInstance(Color value) {
-        return (ColorProperty) cache.fetch(new ColorProperty(value));
+    public static ColorProperty getInstance(Color color) {
+        return (ColorProperty) cache.fetch(new ColorProperty(color));
     }
     
     /**

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java Wed Dec 12 08:13:06 2007
@@ -126,6 +126,25 @@
         }
     }
 
+    /**
+     * A border info with style none. Used as a singleton, in the collapsing-border model,
+     * for elements which don't specify any border on some of their sides.
+     */
+    private static BorderInfo defaultBorderInfo;
+
+    /**
+     * Returns a default BorderInfo of style none.
+     * 
+     * @return a BorderInfo instance with style set to {@link Constants#EN_NONE}
+     */
+    public static synchronized BorderInfo getDefaultBorderInfo() {
+        if (defaultBorderInfo == null) {
+            /* It is enough to set color and width to null, as they should never be consulted */
+            defaultBorderInfo = new BorderInfo(Constants.EN_NONE, null, null);
+        }
+        return defaultBorderInfo;
+    }
+
     private BorderInfo[] borderInfo = new BorderInfo[4];
     private CondLengthProperty[] padding = new CondLengthProperty[4];
 
@@ -227,7 +246,11 @@
      * @return the border info for a side
      */
     public BorderInfo getBorderInfo(int side) {
-        return this.borderInfo[side];
+        if (this.borderInfo[side] == null) {
+            return getDefaultBorderInfo();
+        } else {
+            return this.borderInfo[side];
+        }
     }
     
     /**

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/properties/PropertyCache.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/properties/PropertyCache.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/properties/PropertyCache.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fo/properties/PropertyCache.java Wed Dec 12 08:13:06 2007
@@ -19,6 +19,7 @@
 
 package org.apache.fop.fo.properties;
 
+import java.lang.ref.ReferenceQueue;
 import java.lang.ref.WeakReference;
 
 /**
@@ -41,10 +42,15 @@
     /** the table of hash-buckets */
     private CacheEntry[] table = new CacheEntry[8];
     
+    boolean[] votesForRehash = new boolean[SEGMENT_MASK + 1];
+    
     /* same hash function as used by java.util.HashMap */
     private static int hash(Object x) {
-        int h = x.hashCode();
-
+        return hash(x.hashCode());
+    }
+    
+    private static int hash(int hashCode) {
+        int h = hashCode;
         h += ~(h << 9);
         h ^= (h >>> 14);
         h += (h << 4);
@@ -58,86 +64,79 @@
     }
     
     /* Class modeling a cached entry */
-    private final class CacheEntry {
-        final CacheEntry next;
-        volatile WeakReference ref;
+    private final class CacheEntry extends WeakReference {
+        volatile CacheEntry nextEntry;
         final int hash;
         
         /* main constructor */
-        CacheEntry(Object p, CacheEntry next) {
-            this.next = next;
-            this.ref = new WeakReference(p);
+        public CacheEntry(Object p, CacheEntry nextEntry, ReferenceQueue refQueue) {
+            super(p, refQueue);
+            this.nextEntry = nextEntry;
             this.hash = p.hashCode();
         }
         
-        /* clone constructor */
-        CacheEntry(CacheEntry old, CacheEntry next) {
-            this.next = next;
-            this.ref = old.ref;
-            this.hash = old.hash;
-        }
-        
     }
     
     /* Wrapper objects to synchronize on */
     private final class CacheSegment {
         private int count = 0;
-    }
+        private ReferenceQueue staleEntries = new ReferenceQueue();
+    }    
     
-    /*
-     * Class modeling a cleanup thread.
-     * 
-     * Once run() is called, the segment is locked and the hash-bucket
-     * will be traversed, removing any obsolete entries.
-     * If the cleanup has no effect, rehash() is called.
-     */
-    private final class CacheCleaner implements Runnable {
-        
-        private int hash;
-        
-        CacheCleaner(int hash) {
-            this.hash = hash;
+    private final void cleanSegment(int segmentIndex) {
+        CacheEntry entry;
+        CacheSegment segment = segments[segmentIndex];
+        int bucketIndex;
+        int oldCount = segment.count;
+
+        while ((entry = (CacheEntry) segment.staleEntries.poll()) != null) {
+            bucketIndex = hash(entry.hash) & (table.length - 1);
+            /* remove obsolete entry */
+            /* 1. move to the corresponding entry */
+            CacheEntry prev = null;
+            CacheEntry e = table[bucketIndex];
+            while (e != null
+                    && e.nextEntry != null
+                    && e.hash != entry.hash) {
+                prev = e;
+                e = e.nextEntry;
+            }
+            if (e != null) {
+                /* 2. remove reference from the chain */
+                if (prev == null) {
+                    table[bucketIndex] = e.nextEntry;
+                } else {
+                    prev.nextEntry = e.nextEntry;
+                }
+                segment.count--;
+            }
         }
-        
-        public void run() {
-            //System.out.println("Cleaning segment " + this.segment);
-            CacheSegment segment = segments[this.hash & SEGMENT_MASK];
-            int oldCount;
-            int newCount;
-            synchronized (segment) {
-                oldCount = segment.count;
-                /* check first to see if another cleaner thread already
-                 * pushed the number of entries back below the threshold
-                 * if so, return immediately
-                 */
-                if (segment.count < (2 * table.length)) {
-                    return;
+        synchronized (votesForRehash) {
+            if (oldCount > segment.count) {
+                if (votesForRehash[segmentIndex]) {
+                    votesForRehash[segmentIndex] = false;
                 }
-                
-                int index = this.hash & (table.length - 1);
-                CacheEntry first = table[index];
-                WeakReference ref;
-                for (CacheEntry e = first; e != null; e = e.next) {
-                    ref = e.ref;
-                    if (ref != null && ref.get() == null) {
-                        /* remove obsolete entry
-                        /* 1. clear value, cause interference for non-blocking get() */
-                        e.ref = null;
-                        
-                        /* 2. clone the segment, without the obsolete entry */
-                        CacheEntry head = e.next;
-                        for (CacheEntry c = first; c != e; c = c.next) {
-                            head = new CacheEntry(c, head);
+                return;
+            } else {
+                /* cleanup had no effect */
+                if (!votesForRehash[segmentIndex]) {
+                    /* first time for this segment */
+                    votesForRehash[segmentIndex] = true;
+                    int voteCount = 0;
+                    for (int i = SEGMENT_MASK + 1; --i >= 0; ) {
+                        if (votesForRehash[i]) {
+                            voteCount++;
+                        }
+                    }
+                    if (voteCount > SEGMENT_MASK / 4) {
+                        rehash(SEGMENT_MASK);
+                        /* reset votes */
+                        for (int i = SEGMENT_MASK + 1; --i >= 0;) {
+                            votesForRehash[i] = false;
                         }
-                        table[index] = head;
-                        segment.count--;
+    
                     }
                 }
-                newCount = segment.count;
-            }
-            if (oldCount == newCount) {
-                /* cleanup had no effect, try rehashing */
-                rehash(SEGMENT_MASK);
             }
         }
     }
@@ -146,7 +145,7 @@
      * Puts a new instance in the cache.
      * If the total number of entries for the corresponding
      * segment exceeds twice the amount of hash-buckets, a
-     * cleanup thread will be launched to remove obsolete
+     * cleanup will be performed to try and remove obsolete
      * entries.
      */
     private final void put(Object o) {
@@ -159,26 +158,22 @@
             CacheEntry entry = table[index];
             
             if (entry == null) {
-                entry = new CacheEntry(o, null);
+                entry = new CacheEntry(o, null, segment.staleEntries);
                 table[index] = entry;
                 segment.count++;
             } else {
-                WeakReference ref = entry.ref;
-                if (ref != null && eq(ref.get(), o)) {
+                Object p = entry.get();
+                if (eq(p, o)) {
                     return;
                 } else {
-                    CacheEntry newEntry = new CacheEntry(o, entry);
+                    CacheEntry newEntry = new CacheEntry(o, entry, segment.staleEntries);
                     table[index] = newEntry;
                     segment.count++;
                 }
             }
             
             if (segment.count > (2 * table.length)) {
-                /* launch cleanup in a separate thread, 
-                 * so it acquires its own lock, and put()
-                 * can return immediately */
-                Thread cleaner = new Thread(new CacheCleaner(hash));
-                cleaner.start();
+                cleanSegment(hash & SEGMENT_MASK);
             }
         }
     }
@@ -191,14 +186,12 @@
         int index = hash & (table.length - 1);
         
         CacheEntry entry = table[index];
-        WeakReference r;
         Object q;
         
         /* try non-synched first */
-        for (CacheEntry e = entry; e != null; e = e.next) {
+        for (CacheEntry e = entry; e != null; e = e.nextEntry) {
             if (e.hash == o.hashCode()
-                    && (r = e.ref) != null
-                    && (q = r.get()) != null
+                    && (q = e.get()) != null
                     &&  eq(q, o)) {
                 return q;
             }
@@ -210,10 +203,9 @@
         CacheSegment segment = segments[hash & SEGMENT_MASK];
         synchronized (segment) {
             entry = table[index];
-            for (CacheEntry e = entry; e != null; e = e.next) {
+            for (CacheEntry e = entry; e != null; e = e.nextEntry) {
                 if (e.hash == o.hashCode()
-                        && (r = e.ref) != null
-                        && (q = r.get()) != null
+                        && (q = e.get()) != null
                         &&  eq(q, o)) {
                     return q;
                 }
@@ -224,16 +216,8 @@
     
     /*
      * Recursively acquires locks on all 32 segments,
-     * then performs a check on the segments first to see `
-     * how many precisely exceed the threshold ( 2 x table.length ). 
-     * If this number exceeds half the amount of buckets, 
      * extends the cache and redistributes the entries.
      * 
-     * Example:
-     * For a cache with default size of 8 buckets, each bucket is
-     * a segment, and as such, rehash() will only have effect
-     * if more than 4 buckets exceed the size of 16 entries.
-     * 
      */
     private final void rehash(int index) {
         
@@ -246,40 +230,24 @@
                 /* double the amount of buckets */
                 int newLength = table.length << 1;
                 if (newLength > 0) { //no overflow?
-                    /* Check segmentcounts first */
-                    int countSegments = 0;
-                    int threshold = table.length * 2;
+                    /* reset segmentcounts */
                     for (int i = segments.length; --i >= 0;) {
-                        if (segments[i].count > threshold) {
-                            countSegments++;
-                        }
-                    }
-                    
-                    if (countSegments <= (table.length / 2)) {
-                        return;
-                    } else {
-                        /* reset segmentcounts */
-                        for (int i = segments.length; --i >= 0;) {
-                            segments[i].count = 0;
-                        }
+                        segments[i].count = 0;
                     }
                     
                     CacheEntry[] newTable = new CacheEntry[newLength];
                     
                     int hash, idx;
-                    WeakReference ref;
                     Object o;
                     newLength--;
                     for (int i = table.length; --i >= 0;) {
-                        for (CacheEntry c = table[i]; c != null; c = c.next) {
-                            ref = c.ref;
-                            if (ref != null) {
-                                if ((o = ref.get()) != null) {
-                                    hash = hash(o);
-                                    idx = hash & newLength;
-                                    newTable[idx] = new CacheEntry(c, newTable[idx]);
-                                    segments[hash & SEGMENT_MASK].count++;
-                                }
+                        for (CacheEntry c = table[i]; c != null; c = c.nextEntry) {
+                            if ((o = c.get()) != null) {
+                                hash = c.hash;
+                                idx = hash & newLength;
+                                newTable[idx] = new CacheEntry(o, newTable[idx], 
+                                        segments[hash & SEGMENT_MASK].staleEntries);
+                                segments[hash & SEGMENT_MASK].count++;
                             }
                         }
                     }

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fonts/FontLoader.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fonts/FontLoader.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fonts/FontLoader.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fonts/FontLoader.java Wed Dec 12 08:13:06 2007
@@ -110,7 +110,10 @@
         String effURI;
         boolean type1 = isType1(fontFileURI);
         if (type1) {
-            effURI = fontFileURI.substring(0, fontFileURI.length() - 4) + ".pfm";
+            String pfmExt = fontFileURI.substring(
+                    fontFileURI.length() - 3, fontFileURI.length());
+            pfmExt = pfmExt.substring(0, 2) + (Character.isUpperCase(pfmExt.charAt(2)) ? "M" : "m");
+            effURI = fontFileURI.substring(0, fontFileURI.length() - 4) + "." + pfmExt;
         } else {
             effURI = fontFileURI;
         }

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fonts/LazyFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fonts/LazyFont.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fonts/LazyFont.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fonts/LazyFont.java Wed Dec 12 08:13:06 2007
@@ -27,10 +27,12 @@
 import javax.xml.transform.Source;
 import javax.xml.transform.stream.StreamSource;
 
+import org.xml.sax.InputSource;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+
 import org.apache.fop.apps.FOPException;
-import org.xml.sax.InputSource;
 
 /**
  * This class is used to defer the loading of a font until it is really used.
@@ -95,8 +97,10 @@
                             in = new java.net.URL(source.getSystemId()).openStream();
                         }
                         if (in == null) {
-                            String err = "Cannot load font: failed to create InputStream from"
-                                + " Source for metrics file " + metricsFileName; 
+                            String err = "Cannot load font: After URI resolution, the returned"
+                                + " Source object does not contain an InputStream"
+                                + " or a valid URL (system identifier) for metrics file: "
+                                + metricsFileName; 
                             if (fail) {
                                 throw new RuntimeException(err);
                             } else {

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fonts/MutableFont.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fonts/MutableFont.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fonts/MutableFont.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fonts/MutableFont.java Wed Dec 12 08:13:06 2007
@@ -43,7 +43,7 @@
 
     /**
      * Sets the font's family names (Example: "Helvetica").
-     * @param name the font's family names (a Set of Strings)
+     * @param names the font's family names (a Set of Strings)
      */
     void setFamilyNames(Set names);
     

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fonts/type1/PFMFile.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fonts/type1/PFMFile.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fonts/type1/PFMFile.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/fonts/type1/PFMFile.java Wed Dec 12 08:13:06 2007
@@ -28,6 +28,7 @@
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+
 import org.apache.fop.fonts.Glyphs;
 
 /**
@@ -297,22 +298,24 @@
      * @return The name of the charset.
      */
     public String getCharSetName() {
+        //TODO Had to remove the detection for Expert(Subset) encoding. The PFM is not suitable
+        //for detecting these character sets. We have to parse the AFM for that.
         switch (dfCharSet) {
         case 0:
             return "WinAnsi"; // AKA ISOAdobe
-        case 1:
-            return "Expert";
         case 2:
             if ("Symbol".equals(getPostscriptName())) {
                 return "Symbol";
-            } else {
-                return "ExpertSubset";
             }
+            break;
         case 128:
             return "Shift-JIS (Japanese)";
         default:
-            return "Unknown (" + dfCharSet + ", 0x" + Integer.toHexString(dfCharSet) + ")";
+            log.warn("Unknown charset detected (" + dfCharSet
+                    + ", 0x" + Integer.toHexString(dfCharSet)
+                    + "). Trying fallback to WinAnsi.");
         }
+        return "WinAnsi"; 
     }
 
     /**

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java Wed Dec 12 08:13:06 2007
@@ -19,21 +19,22 @@
 
 package org.apache.fop.layoutmgr;
 
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.fop.fo.FObj;
-import org.apache.fop.fo.FONode;
+
 import org.apache.fop.area.Area;
 import org.apache.fop.area.PageViewport;
 import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.FObj;
 import org.apache.fop.fo.flow.RetrieveMarker;
 
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.ListIterator;
-import java.util.Map;
-
 /**
  * The base class for most LayoutManagers.
  */
@@ -403,7 +404,7 @@
 
     /** {@inheritDoc} */
     public String toString() {
-        return (super.toString() + "[fobj=" + fobj.toString() + "]");
+        return (super.toString() + (fobj != null ? "[fobj=" + fobj.toString() + "]" : ""));
     }
     
     

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java Wed Dec 12 08:13:06 2007
@@ -26,9 +26,10 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+
 import org.apache.fop.area.Area;
-import org.apache.fop.area.BlockParent;
 import org.apache.fop.area.Block;
+import org.apache.fop.area.BlockParent;
 import org.apache.fop.fo.FObj;
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
 import org.apache.fop.fo.properties.SpaceProperty;
@@ -225,9 +226,7 @@
         return contentIPD;
     }
     
-    /**
-     * {@inheritDoc} 
-     */
+    /** {@inheritDoc} */
     public LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
         //log.debug("BLM.getNextKnuthElements> keep-together = "
               // + layoutProps.keepTogether.getType());
@@ -266,6 +265,9 @@
         //Spaces, border and padding to be repeated at each break
         addPendingMarks(context);
         
+        //Used to indicate a special break-after case when all content has already been generated.
+        BreakElement forcedBreakAfterLast = null;
+        
         while ((curLM = (BlockLevelLayoutManager) getChildLM()) != null) {
             LayoutContext childLC = new LayoutContext(0);
             childLC.copyPendingMarksFrom(context);
@@ -292,17 +294,14 @@
                     && returnedList.size() == 1
                     && ((ListElement) returnedList.getFirst()).isForcedBreak()) {
                 // a descendant of this block has break-before
-                /*
-                if (returnList.size() == 0) {
-                    // the first child (or its first child ...) has
-                    // break-before;
-                    // all this block, including space before, will be put in
-                    // the
-                    // following page
-                    bSpaceBeforeServed = false;
-                }*/
                 contentList.addAll(returnedList);
 
+                if (curLM.isFinished() && !hasNextChildLM()) {
+                    forcedBreakAfterLast = (BreakElement)contentList.removeLast();
+                    context.clearPendingMarks();
+                    break;
+                }
+
                 /* extension: conversione di tutta la sequenza fin'ora ottenuta */
                 if (bpUnit > 0) {
                     storedList = contentList;
@@ -349,6 +348,11 @@
                 contentList.addAll(returnedList);
                 if (((ListElement) returnedList.getLast()).isForcedBreak()) {
                     // a descendant of this block has break-after
+                    if (curLM.isFinished() && !hasNextChildLM()) {
+                        forcedBreakAfterLast = (BreakElement)contentList.removeLast();
+                        context.clearPendingMarks();
+                        break;
+                    }
 
                     /* extension: conversione di tutta la sequenza fin'ora ottenuta */
                     if (bpUnit > 0) {
@@ -380,7 +384,7 @@
         returnedList = new LinkedList();
         if (contentList.size() > 0) {
             wrapPositionElements(contentList, returnList);
-        } else {
+        } else if (forcedBreakAfterLast == null) {
             // Empty fo:block, zero-length box makes sure the IDs and/or markers 
             // are registered.
             returnList.add(new KnuthBox(0, notifyPos(new Position(this)), true));
@@ -388,8 +392,15 @@
 
         addKnuthElementsForBorderPaddingAfter(returnList, true);
         addKnuthElementsForSpaceAfter(returnList, alignment);
-        addKnuthElementsForBreakAfter(returnList, context);
+        if (forcedBreakAfterLast == null) {
+            addKnuthElementsForBreakAfter(returnList, context);
+        }
 
+        if (forcedBreakAfterLast != null) {
+            forcedBreakAfterLast.clearPendingMarks();
+            wrapPositionElement(forcedBreakAfterLast, returnList, false);
+        }
+        
         if (mustKeepWithNext()) {
             context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING);
         }
@@ -1455,14 +1466,25 @@
         while (listIter.hasNext()) {
             ListElement tempElement;
             tempElement = (ListElement) listIter.next();
-            if (force || tempElement.getLayoutManager() != this) {
-                tempElement.setPosition(notifyPos(new NonLeafPosition(this,
-                        tempElement.getPosition())));
-            }
-            targetList.add(tempElement);
+            wrapPositionElement(tempElement, targetList, force);
+        }
+    }
+
+    /**
+     * "wrap" the Position inside the given element and add it to the target list.
+     * @param el the list element
+     * @param targetList target list receiving the wrapped position elements
+     * @param force if true, every Position is wrapped regardless of its LM of origin
+     */
+    protected void wrapPositionElement(ListElement el, List targetList, boolean force) {
+        if (force || el.getLayoutManager() != this) {
+            el.setPosition(notifyPos(new NonLeafPosition(this,
+                    el.getPosition())));
         }
+        targetList.add(el);
     }
 
+    
     /** @return the sum of start-indent and end-indent */
     protected int getIPIndents() {
         return startIndent + endIndent;

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/BreakElement.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/BreakElement.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/BreakElement.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/BreakElement.java Wed Dec 12 08:13:06 2007
@@ -119,6 +119,16 @@
         return this.pendingAfterMarks;
     }
     
+    /**
+     * Clears all pending marks associated with this break element. This is used in break
+     * cases where we only know very late if the break is actually after all the content
+     * of an FO has been generated.
+     */
+    public void clearPendingMarks() {
+        this.pendingBeforeMarks = null;
+        this.pendingAfterMarks = null;
+    }
+    
     /** {@inheritDoc} */
     public String toString() {
         StringBuffer sb = new StringBuffer();

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java Wed Dec 12 08:13:06 2007
@@ -19,16 +19,17 @@
 
 package org.apache.fop.layoutmgr;
 
+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.pagination.Flow;
-import org.apache.fop.layoutmgr.inline.InlineLevelLayoutManager;
+
 import org.apache.fop.area.Area;
 import org.apache.fop.area.BlockParent;
-
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
+import org.apache.fop.fo.pagination.Flow;
+import org.apache.fop.layoutmgr.inline.InlineLevelLayoutManager;
 
 /**
  * LayoutManager for an fo:flow object.
@@ -141,6 +142,13 @@
                 if (returnedList.size() > 0) {
                     returnList.addAll(returnedList);
                     if (ElementListUtils.endsWithForcedBreak(returnList)) {
+                        if (curLM.isFinished() && !hasNextChildLM()) {
+                            //If the layout manager is finished at this point, the pending
+                            //marks become irrelevant.
+                            childLC.clearPendingMarks();
+                            //setFinished(true);
+                            break;
+                        }
                         // a descendant of this flow has break-after
                         SpaceResolver.resolveElementList(returnList);
                         return returnList;

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/LayoutContext.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/LayoutContext.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/LayoutContext.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/LayoutContext.java Wed Dec 12 08:13:06 2007
@@ -23,9 +23,9 @@
 import java.util.List;
 
 import org.apache.fop.fo.Constants;
+import org.apache.fop.layoutmgr.inline.AlignmentContext;
 import org.apache.fop.layoutmgr.inline.HyphContext;
 import org.apache.fop.traits.MinOptMax;
-import org.apache.fop.layoutmgr.inline.AlignmentContext;
 
 
 /**
@@ -262,6 +262,18 @@
             return Collections.unmodifiableList(this.pendingAfterMarks);
         } else {
             return null;
+        }
+    }
+    
+    /**
+     * Clears all pending marks on the LayoutContext.
+     */
+    public void clearPendingMarks() {
+        if (this.pendingBeforeMarks != null) {
+            this.pendingBeforeMarks.clear();
+        }
+        if (this.pendingAfterMarks != null) {
+            this.pendingAfterMarks.clear();
         }
     }
     

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/SpaceResolver.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/SpaceResolver.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/SpaceResolver.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/SpaceResolver.java Wed Dec 12 08:13:06 2007
@@ -25,6 +25,7 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+
 import org.apache.fop.traits.MinOptMax;
 
 /**
@@ -441,7 +442,6 @@
         glue2shrink -= glue3.opt - glue3.min;
         
         boolean hasPrecedingNonBlock = false;
-        boolean forcedBreak = false;
         if (log.isDebugEnabled()) {
             log.debug("noBreakLength=" + noBreakLength 
                     + ", glue1=" + glue1 
@@ -449,11 +449,16 @@
                     + ", glue3=" + glue3);
         }
         if (breakPoss != null) {
+            boolean forcedBreak = breakPoss.isForcedBreak();
             if (glue1.isNonZero()) {
                 iter.add(new KnuthPenalty(0, KnuthPenalty.INFINITE, 
                         false, (Position)null, true));
                 iter.add(new KnuthGlue(glue1.opt, glue1.max - glue1.opt, glue1.opt - glue1.min, 
                         (Position)null, true));
+                if (forcedBreak) {
+                    //Otherwise, the preceding penalty and glue will be cut off
+                    iter.add(new KnuthBox(0, (Position)null, true));
+                }
             }
             iter.add(new KnuthPenalty(breakPoss.getPenaltyWidth(), breakPoss.getPenaltyValue(), 
                     false, breakPoss.getBreakClass(), 

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLastLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLastLayoutManager.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLastLayoutManager.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLastLayoutManager.java Wed Dec 12 08:13:06 2007
@@ -19,22 +19,20 @@
 
 package org.apache.fop.layoutmgr.inline;
 
-import org.apache.fop.fo.flow.PageNumberCitationLast;
 import org.apache.fop.area.PageViewport;
 import org.apache.fop.area.Resolvable;
 import org.apache.fop.area.inline.InlineArea;
-import org.apache.fop.area.inline.UnresolvedPageNumber;
 import org.apache.fop.area.inline.TextArea;
+import org.apache.fop.area.inline.UnresolvedPageNumber;
+import org.apache.fop.fo.flow.PageNumberCitationLast;
 import org.apache.fop.layoutmgr.LayoutContext;
 import org.apache.fop.layoutmgr.LayoutManager;
 
 /**
  * LayoutManager for the fo:page-number-citation-last formatting object
  */
-public class PageNumberCitationLastLayoutManager extends PageNumberCitationLayoutManager {
+public class PageNumberCitationLastLayoutManager extends AbstractPageNumberCitationLayoutManager {
 
-    private PageNumberCitationLast fobj;
-    
     /**
      * Constructor
      *

Propchange: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLastLayoutManager.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java Wed Dec 12 08:13:06 2007
@@ -19,33 +19,19 @@
 
 package org.apache.fop.layoutmgr.inline;
 
-import org.apache.fop.fo.flow.PageNumberCitation;
 import org.apache.fop.area.PageViewport;
-import org.apache.fop.area.Resolvable;
-import org.apache.fop.area.Trait;
 import org.apache.fop.area.inline.InlineArea;
-import org.apache.fop.area.inline.UnresolvedPageNumber;
 import org.apache.fop.area.inline.TextArea;
-import org.apache.fop.fonts.Font;
-import org.apache.fop.fonts.FontInfo;
-import org.apache.fop.fonts.FontTriplet;
+import org.apache.fop.area.inline.UnresolvedPageNumber;
+import org.apache.fop.fo.flow.PageNumberCitation;
 import org.apache.fop.layoutmgr.LayoutContext;
 import org.apache.fop.layoutmgr.LayoutManager;
-import org.apache.fop.layoutmgr.PositionIterator;
-import org.apache.fop.layoutmgr.TraitSetter;
 
 /**
  * LayoutManager for the fo:page-number-citation formatting object
  */
-public class PageNumberCitationLayoutManager extends LeafNodeLayoutManager {
+public class PageNumberCitationLayoutManager extends AbstractPageNumberCitationLayoutManager {
 
-    private PageNumberCitation fobj;
-    /** Font for the page-number-citation */
-    protected Font font;
-    
-    /** Indicates whether the page referred to by the citation has been resolved yet */
-    protected boolean resolved = false;
-    
     /**
      * Constructor
      *
@@ -54,50 +40,15 @@
      */
     public PageNumberCitationLayoutManager(PageNumberCitation node) {
         super(node);
-        fobj = node;
     }
     
     /** {@inheritDoc} */
-    public void initialize() {
-        FontInfo fi = fobj.getFOEventHandler().getFontInfo();
-        FontTriplet[] fontkeys = fobj.getCommonFont().getFontState(fi);
-        font = fi.getFontInstance(fontkeys[0], fobj.getCommonFont().fontSize.getValue(this));
-        setCommonBorderPaddingBackground(fobj.getCommonBorderPaddingBackground());
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    protected AlignmentContext makeAlignmentContext(LayoutContext context) {
-        return new AlignmentContext(
-                font
-                , fobj.getLineHeight().getOptimum(this).getLength().getValue(this)
-                , fobj.getAlignmentAdjust()
-                , fobj.getAlignmentBaseline()
-                , fobj.getBaselineShift()
-                , fobj.getDominantBaseline()
-                , context.getAlignmentContext()
-            );
-    }
-
-    /** {@inheritDoc} */
     public InlineArea get(LayoutContext context) {
         curArea = getPageNumberCitationInlineArea(parentLM);
         return curArea;
     }
     
     /**
-     * {@inheritDoc}
-     *                                                                      , LayoutContext) 
-     */
-    public void addAreas(PositionIterator posIter, LayoutContext context) {
-        super.addAreas(posIter, context);
-        if (!resolved) {
-            getPSLM().addUnresolvedArea(fobj.getRefId(), (Resolvable) curArea);
-        }
-    }
-    
-    /**
      * if id can be resolved then simply return a word, otherwise
      * return a resolvable area
      */
@@ -124,34 +75,5 @@
         return text;
     }
     
-    /**
-     * Updates the traits for the generated text area. 
-     * @param text the text area
-     */
-    protected void updateTextAreaTraits(TextArea text) {
-        TraitSetter.setProducerID(text, fobj.getId());
-        text.setBPD(font.getAscender() - font.getDescender());
-        text.setBaselineOffset(font.getAscender());
-        TraitSetter.addFontTraits(text, font);
-        text.addTrait(Trait.COLOR, fobj.getColor());
-        TraitSetter.addTextDecoration(text, fobj.getTextDecoration());
-    }
-    
-    /**
-     * @param str string to be measured
-     * @return width (in millipoints ??) of the string
-     */
-    protected int getStringWidth(String str) {
-        int width = 0;
-        for (int count = 0; count < str.length(); count++) {
-            width += font.getCharWidth(str.charAt(count));
-        }
-        return width;
-    }
-
-    /** {@inheritDoc} */
-    protected void addId() {
-        getPSLM().addIDToPage(fobj.getId());
-    }
 }
 

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/table/ActiveCell.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/table/ActiveCell.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/table/ActiveCell.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/table/ActiveCell.java Wed Dec 12 08:13:06 2007
@@ -22,6 +22,9 @@
 import java.util.List;
 import java.util.ListIterator;
 
+import org.apache.fop.fo.flow.table.EffRow;
+import org.apache.fop.fo.flow.table.GridUnit;
+import org.apache.fop.fo.flow.table.PrimaryGridUnit;
 import org.apache.fop.layoutmgr.ElementListUtils;
 import org.apache.fop.layoutmgr.KnuthBox;
 import org.apache.fop.layoutmgr.KnuthElement;
@@ -239,6 +242,8 @@
      * @return true if this cell's next step is inferior or equal to the next minimal step
      */
     boolean contributesContent() {
+        // return includedInLastStep() && the cell hasn't finished yet, otherwise there's
+        // nothing more to contribute
         return includedInLastStep() && end >= start;
     }
 
@@ -248,7 +253,7 @@
      * @return true if this cell's first step is inferior or equal to the current one 
      */
     boolean hasStarted() {
-        return includedLength > 0;
+        return includedLength >= 0;
     }
 
     /**

Modified: xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModel.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModel.java?rev=603656&r1=603655&r2=603656&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModel.java (original)
+++ xmlgraphics/fop/branches/Temp_ImagePackageRedesign/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModel.java Wed Dec 12 08:13:06 2007
@@ -20,8 +20,8 @@
 package org.apache.fop.layoutmgr.table;
 
 import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.flow.table.BorderSpecification;
 import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
-import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo;
 
 /**
  * This class is a superclass for the two collapsing border models defined
@@ -37,10 +37,7 @@
     protected static final int START = CommonBorderPaddingBackground.START;
     /** end side */
     protected static final int END = CommonBorderPaddingBackground.END;
-    
-    /** Flag: current grid unit is either start or end of the table. */
-    public static final int VERTICAL_START_END_OF_TABLE = 1;
-    
+
     /** Indicates that the cell is/starts in the first row being painted on a particular page */
     //public static final int FIRST_ROW_IN_TABLE_PART = 1;
     /** Indicates that the cell is/ends in the last row being painted on a particular page */
@@ -53,7 +50,7 @@
     //These statics are used singleton-style. No MT issues here.
     private static CollapsingBorderModel collapse = null;
     private static CollapsingBorderModel collapseWithPrecedence = null;
-    
+
     /**
      * @param borderCollapse border collapse control
      * @return the border model for the cell
@@ -74,12 +71,12 @@
                 throw new IllegalArgumentException("Illegal border-collapse mode.");
         }
     }
-    
+
     /**
      * @param side the side on the current cell
      * @return the adjacent side on the neighbouring cell
      */
-    public static int getOtherSide(int side) {
+    public/*TODO*/ static int getOtherSide(int side) {
         switch (side) {
             case CommonBorderPaddingBackground.BEFORE:
                 return CommonBorderPaddingBackground.AFTER;
@@ -93,23 +90,32 @@
                 throw new IllegalArgumentException("Illegal parameter: side");
         }
     }
-    
+
     /**
      * @param side the side to investigate
      * @return true if the adjacent cell is before or after
      */
     protected boolean isVerticalRelation(int side) {
-        return (side == CommonBorderPaddingBackground.BEFORE 
+        return (side == CommonBorderPaddingBackground.BEFORE
                 || side == CommonBorderPaddingBackground.AFTER);
     }
 
-    
+    private static int compareInt(int value1, int value2) {
+        if (value1 < value2) {
+            return -1;
+        } else if (value1 == value2) {
+            return 0;
+        } else {
+            return 1;
+        }
+    }
+
     /**
      * See rule 4 in 6.7.10 for the collapsing border model.
      * @param style the border style to get the preference value for
      * @return the preference value of the style
      */
-    public int getPreferenceValue(int style) {
+    private static int getStylePreferenceValue(int style) {
         switch (style) {
             case Constants.EN_DOUBLE: return 0;
             case Constants.EN_SOLID: return -1;
@@ -122,14 +128,62 @@
             default: throw new IllegalStateException("Illegal border style: " + style);
         }
     }
-    
+
     /**
-     * Determines the winning BorderInfo.
-     * @param current grid unit of the current element
-     * @param neighbour grid unit of the neighbouring element
-     * @return the winning BorderInfo
-     */
-    public abstract BorderInfo determineWinner(
-            GridUnit current, GridUnit neighbour, int side, int flags);
-    
+     * Compares the two given styles (see {@link Constants}).
+     * 
+     * @param style1 a style constant
+     * @param style2 another style constant
+     * @return a value &lt; 0 if style1 has less priority than style2, 0 if both are
+     * equal, a value &gt; 0 if style1 has more priority than style2
+     */
+    static int compareStyles(int style1, int style2) {
+        int value1 = getStylePreferenceValue(style1);
+        int value2 = getStylePreferenceValue(style2);
+        return compareInt(value1, value2);
+    }
+
+    private static int getHolderPreferenceValue(int id) {
+        switch (id) {
+        case Constants.FO_TABLE_CELL: return 0;
+        case Constants.FO_TABLE_ROW: return -1;
+        case Constants.FO_TABLE_HEADER:
+        case Constants.FO_TABLE_FOOTER:
+        case Constants.FO_TABLE_BODY:
+            return -2;
+        case Constants.FO_TABLE_COLUMN: return -3;
+        // TODO colgroup
+        case Constants.FO_TABLE: return -4;
+        default: throw new IllegalStateException();
+        }
+    }
+
+    /**
+     * Compares the two given FO ids ({@link Constants}.FO*) in terms of border
+     * declaration.
+     * 
+     * @param id1 a FO id ({@link Constants#FO_TABLE}, {@link Constants#FO_TABLE_BODY},
+     * etc.)
+     * @param id2 another FO id
+     * @return a value &lt; 0 if id1 has less priority than id2, 0 if both are equal, a
+     * value &gt; 0 if id1 has more priority than id2
+     */
+    static int compareFOs(int id1, int id2) {
+        int p1 = getHolderPreferenceValue(id1);
+        int p2 = getHolderPreferenceValue(id2);
+        return compareInt(p1, p2);
+    }
+
+    /**
+     * Returns the border which wins the border conflict resolution. In case the two
+     * borders are equivalent (identical, or only the color is different), null is
+     * returned.
+     * 
+     * @param border1 a border specification
+     * @param border2 another border specification
+     * @return the winning border, null if the two borders are equivalent
+     */
+    public abstract BorderSpecification determineWinner(BorderSpecification border1,
+            BorderSpecification border2);
+
 }



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