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/07/06 10:41:47 UTC

svn commit: r553790 - in /xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr: KnuthPenalty.java table/TableStepper.java

Author: vhennebert
Date: Fri Jul  6 01:41:46 2007
New Revision: 553790

URL: http://svn.apache.org/viewvc?view=rev&rev=553790
Log:
First step towards using a list of active cells for computing steps

Modified:
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/KnuthPenalty.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableStepper.java

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/KnuthPenalty.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/KnuthPenalty.java?view=diff&rev=553790&r1=553789&r2=553790
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/KnuthPenalty.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/KnuthPenalty.java Fri Jul  6 01:41:46 2007
@@ -111,14 +111,17 @@
         return penalty == -KnuthElement.INFINITE;
     }
     
-    /** @return the break class of this penalty (one of the break-* constants) */
+    /**
+     * @return the break class of this penalty (EN_AUTO, EN_COLUMN, EN_PAGE, EN_EVEN_PAGE,
+     * EN_ODD_PAGE)
+     */
     public int getBreakClass() {
         return breakClass;
     }
     
     /**
      * Sets the break class for this penalty.
-     * @param cl the break class (one of the break-* constants)
+     * @param cl the break class (EN_AUTO, EN_COLUMN, EN_PAGE, EN_EVEN_PAGE, EN_ODD_PAGE)
      */
     public void setBreakClass(int cl) {
         this.breakClass = cl;

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableStepper.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableStepper.java?view=diff&rev=553790&r1=553789&r2=553790
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableStepper.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableStepper.java Fri Jul  6 01:41:46 2007
@@ -20,6 +20,7 @@
 package org.apache.fop.layoutmgr.table;
 
 import java.util.Arrays;
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -40,53 +41,118 @@
  */
 public class TableStepper {
 
+    private static class ActiveCell {
+        private PrimaryGridUnit pgu;
+        /** Knuth elements for this active cell. */
+        private List elementList;
+        /** Number of the row where the row-span begins, zero-based. */
+        private int startRow;
+        /** Index, in the list of Knuth elements, of the element starting the current step. */
+        private int start;
+        /** Index, in the list of Knuth elements, of the element ending the current step. */
+        private int end;
+        /**
+         * Total length of the Knuth elements already included in the steps, up to the
+         * current one.
+         */
+        private int width;
+        private int backupWidth;
+        private int baseWidth;
+        private int borderBefore;
+        private int borderAfter;
+        private int paddingBefore;
+        private int paddingAfter;
+        private boolean keepWithNextSignal;
+
+        ActiveCell(PrimaryGridUnit pgu, EffRow row, int rowIndex) {
+            this.pgu = pgu;
+            boolean makeBoxForWholeRow = false;
+            if (row.getExplicitHeight().min > 0) {
+                boolean contentsSmaller = ElementListUtils.removeLegalBreaks(
+                        pgu.getElements(), row.getExplicitHeight());
+                if (contentsSmaller) {
+                    makeBoxForWholeRow = true;
+                }
+            }
+            if (pgu.isLastGridUnitRowSpan() && pgu.getRow() != null) {
+                makeBoxForWholeRow |= pgu.getRow().mustKeepTogether();
+                makeBoxForWholeRow |= pgu.getTable().mustKeepTogether();
+            }
+            if (makeBoxForWholeRow) {
+                elementList = new java.util.ArrayList(1);
+                int height = row.getExplicitHeight().opt;
+                if (height == 0) {
+                    height = row.getHeight().opt;
+                }
+                elementList.add(new KnuthBoxCellWithBPD(height));
+            } else {
+                //Copy elements (LinkedList) to array lists to improve 
+                //element access performance
+                elementList = new java.util.ArrayList(pgu.getElements());
+//                if (log.isTraceEnabled()) {
+//                    log.trace("column " + (column+1) + ": recording " + elementLists.size() + " element(s)");
+//                }
+            }
+            if (pgu.getTable().isSeparateBorderModel()) {
+                borderBefore = pgu.getBorders().getBorderBeforeWidth(false);
+                borderAfter = pgu.getBorders().getBorderAfterWidth(false);
+            } else {
+                borderBefore = pgu.getHalfMaxBeforeBorderWidth();
+                borderAfter = pgu.getHalfMaxAfterBorderWidth();
+            }
+            paddingBefore = pgu.getBorders().getPaddingBefore(false, pgu.getCellLM());
+            paddingAfter = pgu.getBorders().getPaddingAfter(false, pgu.getCellLM());
+            start = 0;
+            end = -1;
+            width = 0;
+            startRow = rowIndex;
+            keepWithNextSignal = false;
+        }
+
+        private boolean endsOnRow(int rowIndex) {
+            return rowIndex == startRow + pgu.getCell().getNumberRowsSpanned() - 1;
+        }
+
+        int getRemainingHeight(int activeRowIndex, int halfBorderSeparationBPD, EffRow[] rowGroup) {
+            if (end == elementList.size() - 1) {
+                return 0;
+            }
+            if (!endsOnRow(activeRowIndex)) {
+                return 0;
+            }
+            int len = width;
+            if (len > 0) {
+                len += 2 * halfBorderSeparationBPD;
+                len += borderBefore + borderAfter;
+                len += paddingBefore + paddingAfter;
+            }
+            int nominalHeight = 0;
+            for (int r = startRow; r < startRow + pgu.getCell().getNumberRowsSpanned(); r++) {
+                nominalHeight += rowGroup[r].getHeight().opt;
+            }
+            return nominalHeight - len;
+        }
+
+        void backupWidth() {
+            backupWidth = width;
+        }
+    }
     /** Logger **/
     private static Log log = LogFactory.getLog(TableStepper.class);
 
     private TableContentLayoutManager tclm;
-    
+
     private EffRow[] rowGroup;
     /** Number of columns in the row group. */
     private int columnCount;
     private int totalHeight;
     private int activeRowIndex;
-    /**
-     * Knuth elements for active cells, per column. Active cells are cells spanning over
-     * the currently active row.
-     */
-    private List[] elementLists;
-    /**
-     * Number of the row where the row-span begins, per column. Zero-based.
-     */
-    private int[] startRow;
-    /**
-     * For each column, index, in the cell's list of Knuth elements, of the element
-     * starting the current step.
-     */
-    private int[] start;
-    /**
-     * For each column, index, in the cell's list of Knuth elements, of the element
-     * ending the current step.
-     */
-    private int[] end;
-    /**
-     * For each column, widths of the Knuth elements already included in the steps, up to
-     * the current one.
-     */
-    private int[] widths;
-    /**
-     * ?? Width from the start of the row-group up to the current row.
-     */
-    private int[] baseWidth;
-    private int[] borderBefore;
-    private int[] paddingBefore;
-    private int[] borderAfter;
-    private int[] paddingAfter;
     private boolean rowBacktrackForLastStep;
     private boolean skippedStep;
-    private boolean[] keepWithNextSignals;
     private int lastMaxPenaltyLength;
-    
+
+    private List activeCells = new LinkedList();
+
     /**
      * Main constructor
      * @param tclm The parent TableContentLayoutManager
@@ -103,18 +169,6 @@
     private void setup(int columnCount) {
         this.columnCount = columnCount;
         this.activeRowIndex = 0;
-        elementLists = new List[columnCount];
-        startRow = new int[columnCount];
-        start = new int[columnCount];
-        end = new int[columnCount];
-        widths = new int[columnCount];
-        baseWidth = new int[columnCount];
-        borderBefore = new int[columnCount];
-        paddingBefore = new int[columnCount];
-        borderAfter = new int[columnCount];
-        paddingAfter = new int[columnCount];
-        keepWithNextSignals = new boolean[columnCount];
-        Arrays.fill(end, -1);
     }
 
     /**
@@ -125,7 +179,7 @@
     private EffRow getActiveRow() {
         return rowGroup[activeRowIndex];
     }
-    
+
     /**
      * Returns the grid unit at the given column number on the active row.
      *
@@ -136,7 +190,7 @@
     private GridUnit getActiveGridUnit(int column) {
         return getActiveRow().safelyGetGridUnit(column);
     }
-    
+
     private PrimaryGridUnit getActivePrimaryGridUnit(int column) {
         GridUnit gu = getActiveGridUnit(column);
         if (gu == null) {
@@ -145,7 +199,7 @@
             return gu.getPrimary();
         }
     }
-    
+
     private void calcTotalHeight() {
         totalHeight = 0;
         for (int i = 0; i < rowGroup.length; i++) {
@@ -155,37 +209,13 @@
             log.debug("totalHeight=" + totalHeight);
         }
     }
-    
+
     private int getMaxRemainingHeight() {
         int maxW = 0;
         if (!rowBacktrackForLastStep) {
-            for (int i = 0; i < columnCount; i++) {
-                if (elementLists[i] == null) {
-                    continue;
-                }
-                if (end[i] == elementLists[i].size() - 1) {
-                    continue;
-                }
-                GridUnit gu = getActiveGridUnit(i); 
-                if (!gu.isLastGridUnitRowSpan()) {
-                    continue;
-                }
-                int len = widths[i]; 
-                if (len > 0) {
-                    len += 2 * getTableLM().getHalfBorderSeparationBPD();
-                    len += borderBefore[i] + borderAfter[i]; 
-                    len += paddingBefore[i] + paddingAfter[i]; 
-                }
-                int nominalHeight = rowGroup[activeRowIndex].getHeight().opt;
-                for (int r = 0; r < gu.getRowSpanIndex(); r++) {
-                    nominalHeight += rowGroup[activeRowIndex - r - 1].getHeight().opt;
-                }
-                if (len == nominalHeight) {
-                    //row is filled
-                    maxW = 0;
-                    break;
-                }
-                maxW = Math.max(maxW, nominalHeight - len);
+            for (Iterator iter = activeCells.iterator(); iter.hasNext();) {
+                maxW = Math.max(maxW, ((ActiveCell) iter.next()).getRemainingHeight(activeRowIndex,
+                        getTableLM().getHalfBorderSeparationBPD(), rowGroup));
             }
         }
         for (int i = activeRowIndex + 1; i < rowGroup.length; i++) {
@@ -198,58 +228,8 @@
     private void setupElementList(int column) {
         GridUnit gu = getActiveGridUnit(column);
         EffRow row = getActiveRow();
-        if (gu == null || gu.isEmpty()) {
-            elementLists[column] = null;
-            start[column] = 0;
-            end[column] = -1;
-            widths[column] = 0;
-            startRow[column] = activeRowIndex;
-            keepWithNextSignals[column] = false;
-        } else if (gu.isPrimary()) {
-            PrimaryGridUnit pgu = (PrimaryGridUnit)gu;
-            boolean makeBoxForWholeRow = false;
-            if (row.getExplicitHeight().min > 0) {
-                boolean contentsSmaller = ElementListUtils.removeLegalBreaks(
-                        pgu.getElements(), row.getExplicitHeight());
-                if (contentsSmaller) {
-                    makeBoxForWholeRow = true;
-                }
-            }
-            if (pgu.isLastGridUnitRowSpan() && pgu.getRow() != null) {
-                makeBoxForWholeRow |= pgu.getRow().mustKeepTogether();
-                makeBoxForWholeRow |= pgu.getTable().mustKeepTogether();
-            }
-            if (makeBoxForWholeRow) {
-                List list = new java.util.ArrayList(1);
-                int height = row.getExplicitHeight().opt;
-                if (height == 0) {
-                    height = row.getHeight().opt;
-                }
-                list.add(new KnuthBoxCellWithBPD(height));
-                elementLists[column] = list;
-            } else {
-                //Copy elements (LinkedList) to array lists to improve 
-                //element access performance
-                elementLists[column] = new java.util.ArrayList(pgu.getElements());
-                if (log.isTraceEnabled()) {
-                    log.trace("column " + (column+1) + ": recording " + elementLists[column].size() + " element(s)");
-                }
-            }
-            if (isSeparateBorderModel()) {
-                borderBefore[column] = pgu.getBorders().getBorderBeforeWidth(false);
-            } else {
-                borderBefore[column] = pgu.getBorders().getBorderBeforeWidth(false) / 2;
-                if (log.isTraceEnabled()) {
-                    log.trace("border before for column " + column + ": " + borderBefore[column]);
-                }
-            }
-            paddingBefore[column] = pgu.getBorders().getPaddingBefore(false, pgu.getCellLM());
-            paddingAfter[column] = pgu.getBorders().getPaddingAfter(false, pgu.getCellLM());
-            start[column] = 0;
-            end[column] = -1;
-            widths[column] = 0;
-            startRow[column] = activeRowIndex;
-            keepWithNextSignals[column] = false;
+        if (gu != null && !gu.isEmpty() && gu.isPrimary()) {
+            activeCells.add(new ActiveCell((PrimaryGridUnit) gu, row, activeRowIndex));
         }
     }
 
@@ -259,7 +239,7 @@
      */
     private void initializeElementLists() {
         log.trace("Entering initializeElementLists()");
-        for (int i = 0; i < start.length; i++) {
+        for (int i = 0; i < columnCount; i++) {
             setupElementList(i);
         }
     }
@@ -279,7 +259,7 @@
         setup(maxColumnCount);
         initializeElementLists();
         calcTotalHeight();
-        
+
         boolean signalKeepWithNext = false;
         int laststep = 0;
         int step;
@@ -302,33 +282,34 @@
             int breakClass = -1;
             //Put all involved grid units into a list
             List gridUnitParts = new java.util.ArrayList(maxColumnCount);
-            for (int i = 0; i < columnCount; i++) {
-                if (end[i] >= start[i]) {
-                    PrimaryGridUnit pgu = rowGroup[startRow[i]].getGridUnit(i).getPrimary();
-                    if (start[i] == 0 && end[i] == 0 
-                            && elementLists[i].size() == 1
-                            && elementLists[i].get(0) instanceof KnuthBoxCellWithBPD) {
+            for (Iterator iter = activeCells.iterator(); iter.hasNext();) {
+                ActiveCell activeCell = (ActiveCell) iter.next();
+                if (activeCell.end >= activeCell.start) {
+                    PrimaryGridUnit pgu = activeCell.pgu;
+                    if (activeCell.start == 0 && activeCell.end == 0
+                            && activeCell.elementList.size() == 1
+                            && activeCell.elementList.get(0) instanceof KnuthBoxCellWithBPD) {
                         //Special case: Cell with fixed BPD
-                        gridUnitParts.add(new GridUnitPart(pgu, 
+                        gridUnitParts.add(new GridUnitPart(pgu,
                                 0, pgu.getElements().size() - 1));
                     } else {
-                        gridUnitParts.add(new GridUnitPart(pgu, start[i], end[i]));
-                        if (((KnuthElement)elementLists[i].get(end[i])).isForcedBreak()) {
+                        gridUnitParts.add(new GridUnitPart(pgu, activeCell.start, activeCell.end));
+                        if (((KnuthElement)activeCell.elementList.get(activeCell.end)).isForcedBreak()) {
                             forcedBreak = true;
-                            breakClass = ((KnuthPenalty)elementLists[i].get(end[i])).getBreakClass();
+                            breakClass = ((KnuthPenalty)activeCell.elementList.get(activeCell.end)).getBreakClass();
                         }
                     }
-                    if (end[i] + 1 == elementLists[i].size()) {
+                    if (activeCell.end + 1 == activeCell.elementList.size()) {
                         if (pgu.getFlag(GridUnit.KEEP_WITH_NEXT_PENDING)) {
                             log.debug("PGU has pending keep-with-next");
-                            keepWithNextSignals[i] = true;
+                            activeCell.keepWithNextSignal = true;
                         }
                         if (pgu.getRow() != null && pgu.getRow().mustKeepWithNext()) {
                             log.debug("table-row causes keep-with-next");
-                            keepWithNextSignals[i] = true;
+                            activeCell.keepWithNextSignal = true;
                         }
                     }
-                    if (start[i] == 0 && end[i] >= 0) {
+                    if (activeCell.start == 0 && activeCell.end >= 0) {
                         if (pgu.getFlag(GridUnit.KEEP_WITH_PREVIOUS_PENDING)) {
                             log.debug("PGU has pending keep-with-previous");
                             if (returnList.size() == 0) {
@@ -345,17 +326,17 @@
                 }
             }
             //log.debug(">>> guPARTS: " + gridUnitParts);
-            
+
             //Create elements for step
             int effPenaltyLen = penaltyLen;
-            TableContentPosition tcpos = new TableContentPosition(getTableLM(), 
+            TableContentPosition tcpos = new TableContentPosition(getTableLM(),
                     gridUnitParts, rowGroup[normalRow]);
             if (returnList.size() == 0) {
                 tcpos.setFlag(TableContentPosition.FIRST_IN_ROWGROUP, true);
             }
             lastTCPos = tcpos;
             if (log.isDebugEnabled()) {
-                log.debug(" - backtrack=" + rowBacktrackForLastStep 
+                log.debug(" - backtrack=" + rowBacktrackForLastStep
                         + " - row=" + activeRowIndex + " - " + tcpos);
             }
             returnList.add(new KnuthBox(boxLen, tcpos, false));
@@ -370,26 +351,27 @@
                     penaltyPos.footerElements = tclm.getFooterElements();
                 }
             }
-            
+
             //Handle a penalty length coming from nested content
             //Example: nested table with header/footer
             if (this.lastMaxPenaltyLength != 0) {
                 penaltyPos.nestedPenaltyLength = this.lastMaxPenaltyLength;
                 if (log.isDebugEnabled()) {
-                    log.debug("Additional penalty length from table-cell break: " 
+                    log.debug("Additional penalty length from table-cell break: "
                             + this.lastMaxPenaltyLength);
                 }
             }
             effPenaltyLen += this.lastMaxPenaltyLength;
-            
+
             int p = 0;
             boolean allCellsHaveContributed = true;
             signalKeepWithNext = false;
-            for (int i = 0; i < columnCount; i++) {
-                if (start[i] == 0 && end[i] < 0 && elementLists[i] != null) {
+            for (Iterator iter = activeCells.iterator(); iter.hasNext();) {
+                ActiveCell activeCell = (ActiveCell) iter.next();
+                if (activeCell.start == 0 && activeCell.end < 0 && activeCell.elementList != null) {
                     allCellsHaveContributed = false;
                 }
-                signalKeepWithNext |= keepWithNextSignals[i];
+                signalKeepWithNext |= activeCell.keepWithNextSignal;
             }
             if (!allCellsHaveContributed) {
                 //Not all cells have contributed to a newly started row. The penalty here is
@@ -407,7 +389,7 @@
             }
             if (forcedBreak) {
                 if (skippedStep) {
-                    log.error("This is a conflict situation. The output may be wrong." 
+                    log.error("This is a conflict situation. The output may be wrong."
                             + " Please send your FO file to fop-dev@xmlgraphics.apache.org!");
                 }
                 p = -KnuthPenalty.INFINITE; //Overrides any keeps (see 4.8 in XSL 1.0)
@@ -416,11 +398,11 @@
 
             if (log.isDebugEnabled()) {
                 log.debug("step=" + step + " (+" + increase + ")"
-                        + " box=" + boxLen 
+                        + " box=" + boxLen
                         + " penalty=" + penaltyLen
                         + " effPenalty=" + effPenaltyLen);
             }
-            
+
             laststep = step;
             if (rowBacktrackForLastStep) {
                 //If row was set to previous, restore now
@@ -451,22 +433,21 @@
         if (isBreakCondition()) {
             return -1;
         }*/
-        
-        int[] backupWidths = new int[columnCount];
-        System.arraycopy(widths, 0, backupWidths, 0, columnCount);
+
+        for (Iterator iter = activeCells.iterator(); iter.hasNext();) {
+            ((ActiveCell) iter.next()).backupWidth();
+        }
 
         //set starting points
-        goToNextRowIfCurrentFinished(backupWidths);
+        goToNextRowIfCurrentFinished();
 
         //Get next possible sequence for each cell
         boolean stepFound = false;
-        for (int i = 0; i < columnCount; i++) {
-            if (elementLists[i] == null) {
-                continue;
-            }
-            while (end[i] + 1 < elementLists[i].size()) {
-                end[i]++;
-                KnuthElement el = (KnuthElement)elementLists[i].get(end[i]);
+        for (Iterator iter = activeCells.iterator(); iter.hasNext();) {
+            ActiveCell activeCell = (ActiveCell) iter.next();
+            while (activeCell.end + 1 < activeCell.elementList.size()) {
+                activeCell.end++;
+                KnuthElement el = (KnuthElement)activeCell.elementList.get(activeCell.end);
                 if (el.isPenalty()) {
                     this.lastMaxPenaltyLength = Math.max(this.lastMaxPenaltyLength, el.getW());
                     if (el.getP() <= -KnuthElement.INFINITE) {
@@ -477,50 +458,32 @@
                         break;
                     }
                 } else if (el.isGlue()) {
-                    if (end[i] > 0) {
-                        KnuthElement prev = (KnuthElement)elementLists[i].get(end[i] - 1);
+                    if (activeCell.end > 0) {
+                        KnuthElement prev = (KnuthElement)activeCell.elementList.get(activeCell.end - 1);
                         if (prev.isBox()) {
                             //Second legal break point
                             break;
                         }
                     }
-                    widths[i] += el.getW();
+                    activeCell.width += el.getW();
                 } else {
-                    widths[i] += el.getW();
+                    activeCell.width += el.getW();
                 }
             }
-            if (end[i] < start[i]) {
-                if (log.isTraceEnabled()) {
-                    log.trace("column " + (i + 1) + ": (end=" + end[i] + ") < (start=" + start[i]
-                            + ") => resetting width to backupWidth");
-                }
-                widths[i] = backupWidths[i];
+            if (activeCell.end < activeCell.start) {
+//                if (log.isTraceEnabled()) {
+//                    log.trace("column " + (i + 1) + ": (end=" + activeCell.end + ") < (start=" + activeCell.start
+//                            + ") => resetting width to backupWidth");
+//                }
+                activeCell.width = activeCell.backupWidth;
             } else {
                 stepFound = true;
             }
-            //log.debug("part " + start[i] + "-" + end[i] + " " + widths[i]);
-            if (end[i] + 1 >= elementLists[i].size()) {
-                //element list for this cell is finished
-                if (isSeparateBorderModel()) {
-                    borderAfter[i] = getActivePrimaryGridUnit(i)
-                            .getBorders().getBorderAfterWidth(false);
-                } else {
-                    borderAfter[i] = getActivePrimaryGridUnit(i).getHalfMaxAfterBorderWidth();
-                }
-            } else {
-                //element list for this cell is not finished
-                if (isSeparateBorderModel()) {
-                    borderAfter[i] = getActivePrimaryGridUnit(i)
-                            .getBorders().getBorderAfterWidth(false);
-                } else {
-                    //TODO fix me!
-                    borderAfter[i] = getActivePrimaryGridUnit(i).getHalfMaxAfterBorderWidth();
-                }
-            }
-            if (log.isTraceEnabled()) {
-                log.trace("column " + (i+1) + ": borders before=" + borderBefore[i] + " after=" + borderAfter[i]);
-                log.trace("column " + (i+1) + ": padding before=" + paddingBefore[i] + " after=" + paddingAfter[i]);
-            }
+            //log.debug("part " + activeCell.start + "-" + activeCell.end + " " + activeCell.width);
+//            if (log.isTraceEnabled()) {
+//                log.trace("column " + (i+1) + ": borders before=" + activeCell.borderBefore + " after=" + activeCell.borderAfter);
+//                log.trace("column " + (i+1) + ": padding before=" + activeCell.paddingBefore + " after=" + activeCell.paddingAfter);
+//            }
         }
         if (!stepFound) {
             return -1;
@@ -529,16 +492,17 @@
         //Determine smallest possible step
         int minStep = Integer.MAX_VALUE;
         StringBuffer sb = new StringBuffer();
-        for (int i = 0; i < columnCount; i++) {
-            baseWidth[i] = 0;
-            for (int prevRow = 0; prevRow < startRow[i]; prevRow++) {
-                baseWidth[i] += rowGroup[prevRow].getHeight().opt;
-            }
-            baseWidth[i] += 2 * getTableLM().getHalfBorderSeparationBPD();
-            baseWidth[i] += borderBefore[i] + borderAfter[i];
-            baseWidth[i] += paddingBefore[i] + paddingAfter[i];
-            if (end[i] >= start[i]) {
-                int len = baseWidth[i] + widths[i];
+        for (Iterator iter = activeCells.iterator(); iter.hasNext();) {
+            ActiveCell activeCell = (ActiveCell) iter.next();
+            activeCell.baseWidth = 0;
+            for (int prevRow = 0; prevRow < activeCell.startRow; prevRow++) {
+                activeCell.baseWidth += rowGroup[prevRow].getHeight().opt;
+            }
+            activeCell.baseWidth += 2 * getTableLM().getHalfBorderSeparationBPD();
+            activeCell.baseWidth += activeCell.borderBefore + activeCell.borderAfter;
+            activeCell.baseWidth += activeCell.paddingBefore + activeCell.paddingAfter;
+            if (activeCell.end >= activeCell.start) {
+                int len = activeCell.baseWidth + activeCell.width;
                 sb.append(len + " ");
                 minStep = Math.min(len, minStep);
             }
@@ -550,26 +514,27 @@
         //Check for constellations that would result in overlapping borders
         /*
         for (int i = 0; i < columnCount; i++) {
-            
+
         }*/
-        
+
         //Reset bigger-than-minimum sequences
         //See http://people.apache.org/~jeremias/fop/NextStepAlgoNotes.pdf
         rowBacktrackForLastStep = false;
         skippedStep = false;
-        for (int i = 0; i < columnCount; i++) {
-            int len = baseWidth[i] + widths[i];
+        for (Iterator iter = activeCells.iterator(); iter.hasNext();) {
+            ActiveCell activeCell = (ActiveCell) iter.next();
+            int len = activeCell.baseWidth + activeCell.width;
             if (len > minStep) {
-                widths[i] = backupWidths[i];
-                end[i] = start[i] - 1;
-                if (baseWidth[i] + widths[i] > minStep) {
-                    if (log.isDebugEnabled()) {
-                        log.debug("column "
-                                + (i + 1)
-                                + ": minStep vs. border/padding increase conflict: basewidth + width = "
-                                + baseWidth[i] + " + " + widths[i] + " = "
-                                + (baseWidth[i] + widths[i]));                        
-                    }
+                activeCell.width = activeCell.backupWidth;
+                activeCell.end = activeCell.start - 1;
+                if (activeCell.baseWidth + activeCell.width > minStep) {
+//                    if (log.isDebugEnabled()) {
+//                        log.debug("column "
+//                                + (i + 1)
+//                                + ": minStep vs. border/padding increase conflict: basewidth + width = "
+//                                + activeCell.baseWidth + " + " + activeCell.width + " = "
+//                                + (activeCell.baseWidth + activeCell.width));
+//                    }
                     if (activeRowIndex == 0) {
                         log.debug("  First row. Skip this step.");
                         skippedStep = true;
@@ -583,48 +548,51 @@
                 }
             }
         }
-        if (log.isDebugEnabled()) {
-            /*StringBuffer*/ sb = new StringBuffer("[col nb: start-end(width)] ");
-            for (int i = 0; i < columnCount; i++) {
-                if (end[i] >= start[i]) {
-                    sb.append(i + ": " + start[i] + "-" + end[i] + "(" + widths[i] + "), ");
-                } else {
-                    sb.append(i + ": skip, ");
-                }
-            }
-            log.debug(sb.toString());
-        }
+//        if (log.isDebugEnabled()) {
+//            /*StringBuffer*/ sb = new StringBuffer("[col nb: start-end(width)] ");
+//            for (int i = 0; i < columnCount; i++) {
+//                if (end[i] >= start[i]) {
+//                    sb.append(i + ": " + start[i] + "-" + end[i] + "(" + widths[i] + "), ");
+//                } else {
+//                    sb.append(i + ": skip, ");
+//                }
+//            }
+//            log.debug(sb.toString());
+//        }
 
         return minStep;
     }
 
-    private void goToNextRowIfCurrentFinished(int[] backupWidths) {
+    private void removeCellsEndingOnCurrentRow() {
+        for (Iterator iter = activeCells.iterator(); iter.hasNext();) {
+            ActiveCell activeCell = (ActiveCell) iter.next();
+            if (activeCell.endsOnRow(activeRowIndex)) {
+                iter.remove();
+            }
+        }
+    }
+
+        private void goToNextRowIfCurrentFinished() {
         // We assume that the current grid row is finished. If this is not the case this
         // boolean will be reset (see below)
         boolean currentGridRowFinished = true;
-        for (int i = 0; i < columnCount; i++) {
-            // null element lists probably correspond to empty cells
-            if (elementLists[i] == null) {
-                continue;
-            }
-            if (end[i] < elementLists[i].size()) {
-                start[i] = end[i] + 1;
-                if (end[i] + 1 < elementLists[i].size() 
-                        && getActiveGridUnit(i).isLastGridUnitRowSpan()) {
+        for (Iterator iter = activeCells.iterator(); iter.hasNext();) {
+            ActiveCell activeCell = (ActiveCell) iter.next();
+            if (activeCell.end < activeCell.elementList.size()) {
+                activeCell.start = activeCell.end + 1;
+                if (activeCell.end + 1 < activeCell.elementList.size()
+                        && activeCell.endsOnRow(activeRowIndex)) {
                     // Ok, so this grid unit is the last in the row-spanning direction and
                     // there are still unhandled Knuth elements. They /will/ have to be
                     // put on the current grid row, which means that this row isn't
                     // finished yet
                     currentGridRowFinished = false;
                 }
-            } else {
-                throw new IllegalStateException("end[i] overflows elementList[i].size()");
-//                start[i] = -1; //end of list reached
-//                end[i] = -1;
             }
         }
 
         if (currentGridRowFinished) {
+            removeCellsEndingOnCurrentRow();
             if (activeRowIndex < rowGroup.length - 1) {
                 TableRow rowFO = getActiveRow().getTableRow();
                 if (rowFO != null && rowFO.getBreakAfter() != Constants.EN_AUTO) {
@@ -637,11 +605,6 @@
                     log.debug("===> new row: " + activeRowIndex);
                 }
                 initializeElementLists();
-                for (int i = 0; i < columnCount; i++) {
-                    if (end[i] < 0) {
-                        backupWidths[i] = 0;
-                    }
-                }
                 rowFO = getActiveRow().getTableRow();
                 if (rowFO != null && rowFO.getBreakBefore() != Constants.EN_AUTO) {
                     log.warn(FONode.decorateWithContextInfo(
@@ -665,11 +628,11 @@
     /**
      * Marker class denoting table cells fitting in just one box (no legal break inside).
      */
-    private class KnuthBoxCellWithBPD extends KnuthBox {
-        
+    private static class KnuthBoxCellWithBPD extends KnuthBox {
+
         public KnuthBoxCellWithBPD(int w) {
             super(w, null, true);
         }
     }
-    
+
 }



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