]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
TableRowIterator:
authorVincent Hennebert <vhennebert@apache.org>
Wed, 28 Mar 2007 14:49:58 +0000 (14:49 +0000)
committerVincent Hennebert <vhennebert@apache.org>
Wed, 28 Mar 2007 14:49:58 +0000 (14:49 +0000)
- 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

src/java/org/apache/fop/layoutmgr/table/RowPainter.java
src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java
src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java

index 1c640f973f5134b49a11d025ea2befee22f89961..3b9fbe41c44253217d49211b77121efbf1db46b0 100644 (file)
@@ -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();
index 914f134af13080486f5f4bc7e029b3e2a81c828f..44a13af8b7fc400693e883325cc22aa9bae1ea0a 100644 (file)
@@ -691,7 +691,6 @@ public class TableContentLayoutManager implements PercentBaseContext {
             iterateAndPaintPositions(nestedIter, painter);
         }
         
-        painter.notifyEndOfSequence();
         this.usedBPD += painter.getAccumulatedBPD();
 
         if (markers != null) {
index 63d153584ec4b931f9da9b6c3b3f32bf19424760..f8cedd7de7a5e48cdf837f80f668571ae74b454a 100644 (file)
@@ -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;
                 }