diff options
author | Vincent Hennebert <vhennebert@apache.org> | 2007-07-06 08:41:46 +0000 |
---|---|---|
committer | Vincent Hennebert <vhennebert@apache.org> | 2007-07-06 08:41:46 +0000 |
commit | b4f8fe813ddf37c867f428b8ecd19a102c302e38 (patch) | |
tree | b837820a01e4b234956987c5b1d4f20a2f829ad2 /src/java/org | |
parent | c47535396dca01e427b8f05b6b1cb1a8478d5de7 (diff) | |
download | xmlgraphics-fop-b4f8fe813ddf37c867f428b8ecd19a102c302e38.tar.gz xmlgraphics-fop-b4f8fe813ddf37c867f428b8ecd19a102c302e38.zip |
First step towards using a list of active cells for computing steps
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@553790 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org')
-rw-r--r-- | src/java/org/apache/fop/layoutmgr/KnuthPenalty.java | 7 | ||||
-rw-r--r-- | src/java/org/apache/fop/layoutmgr/table/TableStepper.java | 479 |
2 files changed, 226 insertions, 260 deletions
diff --git a/src/java/org/apache/fop/layoutmgr/KnuthPenalty.java b/src/java/org/apache/fop/layoutmgr/KnuthPenalty.java index ee7b3c6f9..771316bd1 100644 --- a/src/java/org/apache/fop/layoutmgr/KnuthPenalty.java +++ b/src/java/org/apache/fop/layoutmgr/KnuthPenalty.java @@ -111,14 +111,17 @@ public class KnuthPenalty extends KnuthElement { 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; diff --git a/src/java/org/apache/fop/layoutmgr/table/TableStepper.java b/src/java/org/apache/fop/layoutmgr/table/TableStepper.java index 60ccf2b0a..d85683b8a 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableStepper.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableStepper.java @@ -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 @@ import org.apache.fop.layoutmgr.LayoutContext; */ 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 @@ public class TableStepper { 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 @@ public class TableStepper { private EffRow getActiveRow() { return rowGroup[activeRowIndex]; } - + /** * Returns the grid unit at the given column number on the active row. * @@ -136,7 +190,7 @@ public class TableStepper { 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 @@ public class TableStepper { return gu.getPrimary(); } } - + private void calcTotalHeight() { totalHeight = 0; for (int i = 0; i < rowGroup.length; i++) { @@ -155,37 +209,13 @@ public class TableStepper { 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 @@ public class TableStepper { 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 @@ public class TableStepper { */ 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 @@ public class TableStepper { setup(maxColumnCount); initializeElementLists(); calcTotalHeight(); - + boolean signalKeepWithNext = false; int laststep = 0; int step; @@ -302,33 +282,34 @@ public class TableStepper { 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 @@ public class TableStepper { } } //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 @@ public class TableStepper { 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 @@ public class TableStepper { } 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 @@ public class TableStepper { 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 @@ public class TableStepper { 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 @@ public class TableStepper { 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 @@ public class TableStepper { //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; + 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; } - 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]; + 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 @@ public class TableStepper { //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 @@ public class TableStepper { } } } - 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 @@ public class TableStepper { 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 @@ public class TableStepper { /** * 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); } } - + } |