From f27f08897a1816c3e32af7466a29f5282e225dcb Mon Sep 17 00:00:00 2001 From: Vincent Hennebert Date: Wed, 28 Mar 2007 14:49:58 +0000 Subject: [PATCH] TableRowIterator: - bugfix: add the correct grid unit for a col span RowPainter.addAreasAndFlushRow: - substract a part of this method into another method - avoid calling it twice by properly resetting lastRow - simplify it thanks to the previous point and the bugfix above git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@523349 13f79535-47bb-0310-9956-ffa450edef68 --- .../fop/layoutmgr/table/RowPainter.java | 237 +++++++++--------- .../table/TableContentLayoutManager.java | 1 - .../fop/layoutmgr/table/TableRowIterator.java | 2 +- 3 files changed, 121 insertions(+), 119 deletions(-) diff --git a/src/java/org/apache/fop/layoutmgr/table/RowPainter.java b/src/java/org/apache/fop/layoutmgr/table/RowPainter.java index 1c640f973..3b9fbe41c 100644 --- a/src/java/org/apache/fop/layoutmgr/table/RowPainter.java +++ b/src/java/org/apache/fop/layoutmgr/table/RowPainter.java @@ -42,7 +42,6 @@ class RowPainter { /** Currently handled row (= last encountered row). */ private EffRow lastRow = null; private LayoutContext layoutContext; - private int lastRowHeight = 0; /** * For each part of the table (header, footer, body), index of the first row of that * part present on the current page. @@ -71,9 +70,9 @@ class RowPainter { private int[] end; /** * Length, for each column, of the elements from the current cell put on the - * current page. + * current page. This is the corresponding area's bpd. */ - private int[] partLength; + private int[] partBPD; private TableContentLayoutManager tclm; public RowPainter(TableContentLayoutManager tclm, LayoutContext layoutContext) { @@ -83,7 +82,7 @@ class RowPainter { this.primaryGridUnits = new PrimaryGridUnit[colCount]; this.start = new int[colCount]; this.end = new int[colCount]; - this.partLength = new int[colCount]; + this.partBPD = new int[colCount]; Arrays.fill(firstRow, -1); Arrays.fill(end, -1); } @@ -92,12 +91,9 @@ class RowPainter { return this.accumulatedBPD; } - public void notifyEndOfSequence() { - this.accumulatedBPD += lastRowHeight; //for last row - } - public void notifyNestedPenaltyArea(int length) { - this.lastRowHeight += length; + yoffset += length; + accumulatedBPD += length; } /** @@ -109,8 +105,6 @@ class RowPainter { public void handleTableContentPosition(TableContentPosition tcpos) { if (lastRow != tcpos.row && lastRow != null) { addAreasAndFlushRow(false); - yoffset += lastRowHeight; - this.accumulatedBPD += lastRowHeight; } if (log.isDebugEnabled()) { log.debug("===handleTableContentPosition(" + tcpos); @@ -149,12 +143,12 @@ class RowPainter { * lying on the current page must be drawn. * * @param forcedFlush true if the elements must be drawn even if the row isn't - * finished yet (last row on the page) + * finished yet (last row on the page), or if the row is the last of the current table + * part * @return the height of the (grid) row */ public int addAreasAndFlushRow(boolean forcedFlush) { int actualRowHeight = 0; - int readyCount = 0; int bt = lastRow.getBodyType(); if (log.isDebugEnabled()) { @@ -165,78 +159,11 @@ class RowPainter { for (int i = 0; i < primaryGridUnits.length; i++) { if ((primaryGridUnits[i] != null) && (forcedFlush || (end[i] == primaryGridUnits[i].getElements().size() - 1))) { - if (log.isTraceEnabled()) { - log.trace("getting len for " + i + " " - + start[i] + "-" + end[i]); - } - readyCount++; - int len = ElementListUtils.calcContentLength( - primaryGridUnits[i].getElements(), start[i], end[i]); - partLength[i] = len; - if (log.isTraceEnabled()) { - log.trace("len of part: " + len); - } - - if (start[i] == 0) { - LengthRangeProperty bpd = primaryGridUnits[i].getCell() - .getBlockProgressionDimension(); - if (!bpd.getMinimum(tclm.getTableLM()).isAuto()) { - int min = bpd.getMinimum(tclm.getTableLM()) - .getLength().getValue(tclm.getTableLM()); - if (min > 0) { - len = Math.max(len, min); - } - } - if (!bpd.getOptimum(tclm.getTableLM()).isAuto()) { - int opt = bpd.getOptimum(tclm.getTableLM()) - .getLength().getValue(tclm.getTableLM()); - if (opt > 0) { - len = Math.max(len, opt); - } - } - if (primaryGridUnits[i].getRow() != null) { - bpd = primaryGridUnits[i].getRow().getBlockProgressionDimension(); - if (!bpd.getMinimum(tclm.getTableLM()).isAuto()) { - int min = bpd.getMinimum(tclm.getTableLM()).getLength() - .getValue(tclm.getTableLM()); - if (min > 0) { - len = Math.max(len, min); - } - } - } - } - - // Add the padding if any - len += primaryGridUnits[i].getBorders() - .getPaddingBefore(false, primaryGridUnits[i].getCellLM()); - len += primaryGridUnits[i].getBorders() - .getPaddingAfter(false, primaryGridUnits[i].getCellLM()); - - //Now add the borders to the contentLength - if (tclm.isSeparateBorderModel()) { - len += primaryGridUnits[i].getBorders().getBorderBeforeWidth(false); - len += primaryGridUnits[i].getBorders().getBorderAfterWidth(false); - } else { - len += primaryGridUnits[i].getHalfMaxBeforeBorderWidth(); - len += primaryGridUnits[i].getHalfMaxAfterBorderWidth(); - } - int startRow = Math.max(primaryGridUnits[i].getStartRow(), firstRow[bt]); - Integer storedOffset = (Integer)rowOffsets[bt].get(new Integer(startRow)); - int effYOffset; - if (storedOffset != null) { - effYOffset = storedOffset.intValue(); - } else { - effYOffset = yoffset; - } - len -= yoffset - effYOffset; - actualRowHeight = Math.max(actualRowHeight, len); + actualRowHeight = Math.max(actualRowHeight, computeSpanHeight( + primaryGridUnits[i], start[i], end[i], i, bt)); } } - if (readyCount == 0) { - return 0; - } actualRowHeight += 2 * tclm.getTableLM().getHalfBorderSeparationBPD(); - lastRowHeight = actualRowHeight; //Add areas for row tclm.addRowBackgroundArea(rowFO, actualRowHeight, layoutContext.getRefIPD(), yoffset); @@ -245,50 +172,126 @@ class RowPainter { //currentGU can be null if there's no grid unit //at this place in the current row (empty cell and no borders to process) - if ((primaryGridUnits[i] != null) - && (forcedFlush || (end[i] == primaryGridUnits[i].getElements().size() - 1) - && /*[1]*/ (currentGU == null || currentGU.isLastGridUnitRowSpan())) - || /*[2]*/ (primaryGridUnits[i] == null && currentGU != null)) { - - //[1] the last line in the "if" above is to avoid a premature end of a - //row-spanned cell because no GridUnitParts are generated after a cell is - //finished with its content. - //See table-cell_number-rows-spanned_bug38397.xml - - //[2] A row-spanned cell has finished contributing content on the previous page - //and now still has to cause grid units to be painted. - //See table-cell_page-break_span.xml - - if (log.isDebugEnabled()) { - log.debug((forcedFlush ? "FORCED " : "") + "flushing... col=" + i - + " elem-list:" + start[i] + "-" + end[i]); - } - PrimaryGridUnit gu = primaryGridUnits[i]; - if (gu == null - && !currentGU.isEmpty() - && currentGU.getColSpanIndex() == 0 - && currentGU.isLastGridUnitColSpan() - && (forcedFlush || currentGU.isLastGridUnitRowSpan())) { - //Grid unit to be painted is not the primary - //the checks above make sure no cell is painted more than once - gu = currentGU.getPrimary(); - } - - //gu can still be null if we're talking about an EmptyGridUnit, for example - if (gu != null) { - addAreasForCell(gu, start[i], end[i], - lastRow, - partLength[i], actualRowHeight); + if (primaryGridUnits[i] != null) { + if (forcedFlush || ((end[i] == primaryGridUnits[i].getElements().size() - 1) + && (currentGU == null || currentGU.isLastGridUnitRowSpan()))) { + //the last line in the "if" above is to avoid a premature end of a + //row-spanned cell because no GridUnitParts are generated after a cell is + //finished with its content. + //See table-cell_number-rows-spanned_bug38397.xml + addAreasForCell(primaryGridUnits[i], start[i], end[i], lastRow, partBPD[i], actualRowHeight); primaryGridUnits[i] = null; start[i] = 0; end[i] = -1; - partLength[i] = 0; + partBPD[i] = 0; } + } else if (currentGU != null && !currentGU.isEmpty() + && currentGU.getColSpanIndex() == 0 + && (forcedFlush || currentGU.isLastGridUnitRowSpan())) { + //A row-spanned cell has finished contributing content on the previous page + //and now still has to cause grid units to be painted. + //See table-cell_page-break_span.xml + addAreasForCell(currentGU.getPrimary(), start[i], end[i], lastRow, partBPD[i], actualRowHeight); + start[i] = 0; + end[i] = -1; + partBPD[i] = 0; } } + yoffset += actualRowHeight; + accumulatedBPD += actualRowHeight; + if (forcedFlush) { + // Either the end of the page is reached, then this was the last call of this + // method and we no longer care about lastRow; or the end of a table-part + // (header, footer, body) has been reached, and the next row will anyway be + // different from the current one, and this is unnecessary to recall this + // method in the first lines of handleTableContentPosition, so we may reset + // lastRow + lastRow = null; + } return actualRowHeight; } + /** + * Computes the total height of the part of the given cell spanning on the current + * active row, including borders and paddings. The bpd is also stored in partBPD, and + * it is ensured that the cell's or row's explicit height is respected. yoffset is + * updated accordingly. + * + * @param pgu primary grid unit corresponding to the cell + * @param start index of the first element of the cell occuring on the current page + * @param end index of the last element of the cell occuring on the current page + * @param columnIndex column index of the cell + * @param bodyType {@link TableRowIterator#HEADER}, {@link TableRowIterator#FOOTER}, + * {@link TableRowIterator#BODY} + * @return the cell's height + */ + private int computeSpanHeight(PrimaryGridUnit pgu, int start, int end, int columnIndex, int bodyType) { + if (log.isTraceEnabled()) { + log.trace("getting len for " + columnIndex + " " + + start + "-" + end); + } + int len = ElementListUtils.calcContentLength( + pgu.getElements(), start, end); + partBPD[columnIndex] = len; + if (log.isTraceEnabled()) { + log.trace("len of part: " + len); + } + + if (start == 0) { + LengthRangeProperty bpd = pgu.getCell() + .getBlockProgressionDimension(); + if (!bpd.getMinimum(tclm.getTableLM()).isAuto()) { + int min = bpd.getMinimum(tclm.getTableLM()) + .getLength().getValue(tclm.getTableLM()); + if (min > 0) { + len = Math.max(len, min); + } + } + if (!bpd.getOptimum(tclm.getTableLM()).isAuto()) { + int opt = bpd.getOptimum(tclm.getTableLM()) + .getLength().getValue(tclm.getTableLM()); + if (opt > 0) { + len = Math.max(len, opt); + } + } + if (pgu.getRow() != null) { + bpd = pgu.getRow().getBlockProgressionDimension(); + if (!bpd.getMinimum(tclm.getTableLM()).isAuto()) { + int min = bpd.getMinimum(tclm.getTableLM()).getLength() + .getValue(tclm.getTableLM()); + if (min > 0) { + len = Math.max(len, min); + } + } + } + } + + // Add the padding if any + len += pgu.getBorders() + .getPaddingBefore(false, pgu.getCellLM()); + len += pgu.getBorders() + .getPaddingAfter(false, pgu.getCellLM()); + + //Now add the borders to the contentLength + if (tclm.isSeparateBorderModel()) { + len += pgu.getBorders().getBorderBeforeWidth(false); + len += pgu.getBorders().getBorderAfterWidth(false); + } else { + len += pgu.getHalfMaxBeforeBorderWidth(); + len += pgu.getHalfMaxAfterBorderWidth(); + } + int startRow = Math.max(pgu.getStartRow(), firstRow[bodyType]); + Integer storedOffset = (Integer)rowOffsets[bodyType].get(new Integer(startRow)); + int effYOffset; + if (storedOffset != null) { + effYOffset = storedOffset.intValue(); + } else { + effYOffset = yoffset; + } + len -= yoffset - effYOffset; + return len; + } + private void addAreasForCell(PrimaryGridUnit pgu, int startPos, int endPos, EffRow row, int contentHeight, int rowHeight) { int bt = row.getBodyType(); diff --git a/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java index 914f134af..44a13af8b 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java @@ -691,7 +691,6 @@ public class TableContentLayoutManager implements PercentBaseContext { iterateAndPaintPositions(nestedIter, painter); } - painter.notifyEndOfSequence(); this.usedBPD += painter.getAccumulatedBPD(); if (markers != null) { diff --git a/src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java b/src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java index 63d153584..f8cedd7de 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java @@ -477,7 +477,7 @@ public class TableRowIterator { safelySetListItem(gridUnits, colnum - 1, guSpan); if (hasRowSpanningLeft) { pendingRowSpans++; - safelySetListItem(previousRowsSpanningCells, colnum - 1, gu); + safelySetListItem(previousRowsSpanningCells, colnum - 1, guSpan); } horzSpan[j] = guSpan; } -- 2.39.5