]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Fixed a number of issues mainly related to border painting and row spanning.
authorJeremias Maerki <jeremias@apache.org>
Wed, 4 May 2005 15:10:19 +0000 (15:10 +0000)
committerJeremias Maerki <jeremias@apache.org>
Wed, 4 May 2005 15:10:19 +0000 (15:10 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_KnuthStylePageBreaking@198604 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/fop/layoutmgr/table/Cell.java
src/java/org/apache/fop/layoutmgr/table/GridUnit.java
src/java/org/apache/fop/layoutmgr/table/PrimaryGridUnit.java
src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java
src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java

index ac4f44ff3d438e07890c0d82315ddbd92a0ce4f5..f34f95b549f366acc9c80fe7eb8bc994f359f72d 100644 (file)
@@ -460,6 +460,8 @@ public class Cell extends BlockStackingLayoutManager implements BlockLevelLayout
                         int bpd = getContentHeight(rowHeight, gu);
                         bpd += gridUnit.getHalfMaxBeforeBorderWidth() 
                                 - (gu.getBorders().getBorderBeforeWidth(false) / 2);
+                        bpd += gridUnit.getHalfMaxAfterBorderWidth() 
+                                - (gu.getBorders().getBorderAfterWidth(false) / 2);
                         block.setBPD(bpd);
                         //TODO This needs to be fixed for row spanning
                         lastRowHeight = rowHeight;
index abec8c8c6078dc8827caafbb7e231f480c441639..e1ae72984d090fee3227eace7c6835f504efdd86 100644 (file)
@@ -156,6 +156,13 @@ public class GridUnit {
         return this.rowSpanIndex;
     }
     
+    /**
+     * @return the index of the grid unit inside a cell in column direction
+     */
+    public int getColSpanIndex() {
+        return this.colSpanIndex;
+    }
+
     /**
      * Returns a BorderInfo instance for a side of the currently applicable cell before border
      * resolution (i.e. the value from the FO). A return value of null indicates an empty cell.
index aff3be337f45469e381e937a48dd3fe5aa8a366d..2695890a7dd1a06589bae1fd32abd4bd71b61b24 100644 (file)
@@ -90,11 +90,10 @@ public class PrimaryGridUnit extends GridUnit {
     }
     
     /** 
-     * @return Returns the sum of half the maximum before and after border 
-     * widths of this cell.
+     * @return Returns the half the maximum after border width of this cell.
      */
-    public int getHalfMaxBorderWidth() {
-        int value = getHalfMaxBeforeBorderWidth();
+    public int getHalfMaxAfterBorderWidth() {
+        int value = 0;
         if (getRows() != null) {
             //Last row for after borders
             int after = 0;
@@ -113,6 +112,14 @@ public class PrimaryGridUnit extends GridUnit {
         return value;
     }
     
+    /** 
+     * @return Returns the sum of half the maximum before and after border 
+     * widths of this cell.
+     */
+    public int getHalfMaxBorderWidth() {
+        return getHalfMaxBeforeBorderWidth() + getHalfMaxAfterBorderWidth();
+    }
+    
     /** @param value The length of the cell content to remember. */
     public void setContentLength(int value) {
         this.contentLength = value;
index 843aaa9ef1646d749dc420777153147b4a2bb4e6..e306f64a61e6c10f63aa15486cc4e3a53120aa62 100644 (file)
@@ -220,13 +220,13 @@ public class TableContentLayoutManager {
             if ((prev == null) && (iter == this.trIter) && (this.headerIter != null)) {
                 prev = this.headerIter.getLastRow();
             }
-            if ((prev == null) && (iter == this.headerIter)) {
-                prev = this.trIter.getFirstRow();
+            if ((next == null) && (iter == this.headerIter)) {
+                next = this.trIter.getFirstRow();
             }
             if ((next == null) && (iter == this.trIter) && (this.footerIter != null)) {
                 next = this.footerIter.getFirstRow();
             }
-            if ((next == null) && (iter == this.footerIter)) {
+            if ((prev == null) && (iter == this.footerIter)) {
                 //TODO This could be bad for memory consumption because it already causes the
                 //whole body iterator to be prefetched!
                 prev = this.trIter.getLastRow();
@@ -265,17 +265,22 @@ public class TableContentLayoutManager {
                     } else {
                         other = null;
                     }
-                    if ((iter == this.trIter)
-                            && gu.getFlag(GridUnit.FIRST_IN_TABLE)
-                            && (this.headerIter == null)) {
-                        flags |= CollapsingBorderModel.VERTICAL_START_END_OF_TABLE;
-                    }
-                    if ((iter == this.headerIter)
-                            && gu.getFlag(GridUnit.FIRST_IN_TABLE)) {
-                        flags |= CollapsingBorderModel.VERTICAL_START_END_OF_TABLE;
+                    if (other == null 
+                            || other.isEmpty() 
+                            || gu.isEmpty() 
+                            || gu.getPrimary() != other.getPrimary()) {
+                        if ((iter == this.trIter)
+                                && gu.getFlag(GridUnit.FIRST_IN_TABLE)
+                                && (this.headerIter == null)) {
+                            flags |= CollapsingBorderModel.VERTICAL_START_END_OF_TABLE;
+                        }
+                        if ((iter == this.headerIter)
+                                && gu.getFlag(GridUnit.FIRST_IN_TABLE)) {
+                            flags |= CollapsingBorderModel.VERTICAL_START_END_OF_TABLE;
+                        }
+                        gu.resolveBorder(other, 
+                                CommonBorderPaddingBackground.BEFORE, flags);
                     }
-                    gu.resolveBorder(other, 
-                            CommonBorderPaddingBackground.BEFORE, flags);
                     
                     flags = 0;
                     if (next != null && i < next.getGridUnits().size()) {
@@ -283,17 +288,22 @@ public class TableContentLayoutManager {
                     } else {
                         other = null;
                     }
-                    if ((iter == this.trIter)
-                            && gu.getFlag(GridUnit.LAST_IN_TABLE)
-                            && (this.footerIter == null)) {
-                        flags |= CollapsingBorderModel.VERTICAL_START_END_OF_TABLE;
-                    }
-                    if ((iter == this.footerIter)
-                            && gu.getFlag(GridUnit.LAST_IN_TABLE)) {
-                        flags |= CollapsingBorderModel.VERTICAL_START_END_OF_TABLE;
+                    if (other == null 
+                            || other.isEmpty() 
+                            || gu.isEmpty() 
+                            || gu.getPrimary() != other.getPrimary()) {
+                        if ((iter == this.trIter)
+                                && gu.getFlag(GridUnit.LAST_IN_TABLE)
+                                && (this.footerIter == null)) {
+                            flags |= CollapsingBorderModel.VERTICAL_START_END_OF_TABLE;
+                        }
+                        if ((iter == this.footerIter)
+                                && gu.getFlag(GridUnit.LAST_IN_TABLE)) {
+                            flags |= CollapsingBorderModel.VERTICAL_START_END_OF_TABLE;
+                        }
+                        gu.resolveBorder(other, 
+                                CommonBorderPaddingBackground.AFTER, flags);
                     }
-                    gu.resolveBorder(other, 
-                            CommonBorderPaddingBackground.AFTER, flags);
                 }
 
             }
@@ -311,6 +321,7 @@ public class TableContentLayoutManager {
     private void createElementsForRowGroup(LayoutContext context, int alignment, 
             boolean isHeaderFooter, LinkedList returnList, 
             TableRowIterator.EffRow[] rowGroup) {
+        log.debug("Handling row group with " + rowGroup.length + " rows...");
         MinOptMax[] rowHeights = new MinOptMax[rowGroup.length];
         TableRowIterator.EffRow row;
         List pgus = new java.util.ArrayList(); //holds a list of a row's primary grid units
@@ -324,42 +335,46 @@ public class TableContentLayoutManager {
             int maxCellHeight = 0;
             for (int j = 0; j < row.getGridUnits().size(); j++) {
                 GridUnit gu = (GridUnit)row.getGridUnits().get(j);
-                if (gu.isPrimary() && !gu.isEmpty()) {
-                    PrimaryGridUnit primary = (PrimaryGridUnit)gu;
-                    primary.getCellLM().setParent(tableLM);
+                if ((gu.isPrimary() || (gu.getColSpanIndex() == 0 && gu.isLastGridUnitRowSpan())) 
+                        && !gu.isEmpty()) {
+                    PrimaryGridUnit primary = gu.getPrimary();
+                    
+                    if (gu.isPrimary()) {
+                        primary.getCellLM().setParent(tableLM);
+                     
+                        //Determine the table-row if any
+                        if (tableRow == null) {
+                            tableRow = primary.getRow();
+                            
+                            //Check for bpd on row, see CSS21, 17.5.3 Table height algorithms
+                            LengthRangeProperty bpd = tableRow.getBlockProgressionDimension();
+                            if (!bpd.getMinimum().isAuto()) {
+                                minContentHeight = Math.max(minContentHeight, 
+                                        bpd.getMinimum().getLength().getValue());
+                            }
+                        }
 
-                    //Determine the table-row if any
-                    if (tableRow == null) {
-                        tableRow = primary.getRow();
-                        
-                        //Check for bpd on row, see CSS21, 17.5.3 Table height algorithms
-                        LengthRangeProperty bpd = tableRow.getBlockProgressionDimension();
-                        if (!bpd.getMinimum().isAuto()) {
-                            minContentHeight = Math.max(minContentHeight, 
-                                    bpd.getMinimum().getLength().getValue());
+                        //Calculate width of cell
+                        int spanWidth = 0;
+                        for (int i = primary.getStartCol(); 
+                                i < primary.getStartCol() + primary.getCell().getNumberColumnsSpanned();
+                                i++) {
+                            spanWidth += getTableLM().getColumns().getColumn(i + 1)
+                                .getColumnWidth().getValue();
                         }
+                        LayoutContext childLC = new LayoutContext(0);
+                        childLC.setStackLimit(context.getStackLimit()); //necessary?
+                        childLC.setRefIPD(spanWidth);
+                        
+                        //Get the element list for the cell contents
+                        LinkedList elems = primary.getCellLM().getNextKnuthElements(childLC, alignment);
+                        primary.setElements(elems);
+                        log.debug("Elements: " + elems);
                     }
 
-                    //Calculate width of cell
-                    int spanWidth = 0;
-                    for (int i = primary.getStartCol(); 
-                            i < primary.getStartCol() + primary.getCell().getNumberColumnsSpanned();
-                            i++) {
-                        spanWidth += getTableLM().getColumns().getColumn(i + 1)
-                            .getColumnWidth().getValue();
-                    }
-                    log.info("spanWidth=" + spanWidth);
-                    LayoutContext childLC = new LayoutContext(0);
-                    childLC.setStackLimit(context.getStackLimit()); //necessary?
-                    childLC.setRefIPD(spanWidth);
-                    
-                    //Get the element list for the cell contents
-                    LinkedList elems = primary.getCellLM().getNextKnuthElements(childLC, alignment);
-                    primary.setElements(elems);
-                    log.debug("Elements: " + elems);
                     
                     //Calculate height of cell contents
-                    primary.setContentLength(calcCellHeightFromContents(elems));
+                    primary.setContentLength(calcCellHeightFromContents(primary.getElements()));
                     maxCellHeight = Math.max(maxCellHeight, primary.getContentLength());
 
                     //Calculate height of row, see CSS21, 17.5.3 Table height algorithms
@@ -379,6 +394,9 @@ public class TableContentLayoutManager {
                         padding += cbpb.getPaddingBefore(false);
                         padding += cbpb.getPaddingAfter(false);
                         int effRowHeight = effCellContentHeight + padding + halfMaxBorderWidths;
+                        for (int previous = 0; previous < gu.getRowSpanIndex(); previous++) {
+                            effRowHeight -= rowHeights[rgi - previous - 1].opt;
+                        }
                         if (effRowHeight > rowHeights[rgi].min) {
                             //This is the new height of the (grid) row
                             MinOptMaxUtil.extendMinimum(rowHeights[rgi], effRowHeight, false);
@@ -386,71 +404,31 @@ public class TableContentLayoutManager {
                         }
                     }
                     
-                    pgus.add(primary);
+                    if (gu.isPrimary()) {
+                        pgus.add(primary);
+                    }
                 }
             }
             
-            log.debug(row);
+            log.debug("row: " + row);
             
             PrimaryGridUnit[] pguArray = new PrimaryGridUnit[pgus.size()];
             pguArray = (PrimaryGridUnit[])pgus.toArray(pguArray);
+            
             LinkedList returnedList = getCombinedKnuthElementsForRow(pguArray, row, 
                     isHeaderFooter);
             if (returnedList != null) {
                 returnList.addAll(returnedList);
             }
-
-            /* not necessary anymore
-            if (row.getHeight().opt > maxCellHeight) {
-                int space = row.getHeight().opt - maxCellHeight;
-                KnuthPenalty penalty = (KnuthPenalty)returnList.removeLast();
-                //Insert dummy box before penalty
-                returnList.add(new KnuthBox(space, new Position(getTableLM()), false));
-                returnList.add(penalty);
-            }*/
-            
-            //Calculate row height in row groups with spans
-            /*
-            if (tableRow != null) {
-                LengthRangeProperty bpd = tableRow.getBlockProgressionDimension();
-                if (bpd.getOptimum().isAuto()) {
-                    rowHeights[rgi] = new MinOptMax(0, 0, Integer.MAX_VALUE);
-                } else {
-                    rowHeights[rgi] = MinOptMaxUtil.toMinOptMax(bpd);
-                }
-            } else {
-                rowHeights[rgi] = new MinOptMax(0, 0, Integer.MAX_VALUE);
-            }*/
-            /*
-            for (int j = 0; j < row.getGridUnits().size(); j++) {
-                GridUnit gu = (GridUnit)row.getGridUnits().get(j);
-                if (gu.isLastGridUnitRowSpan() && !gu.isEmpty()) {
-                    log.debug(rgi + " - " + gu);
-                    MinOptMax effCellHeight; 
-                    LengthRangeProperty bpd = gu.getCell().getBlockProgressionDimension();
-                    if (bpd.getOptimum().isAuto()) {
-                        effCellHeight = new MinOptMax(0, 0, Integer.MAX_VALUE);
-                    } else {
-                        effCellHeight = MinOptMaxUtil.toMinOptMax(bpd);
-                    }
-                    int contentLen = gu.getPrimary().getContentLength();
-                    if (getTableLM().getTable().isSeparateBorderModel()) {
-                        //contentLen += before and after borders of that cell plus half the BPD border-separation 
-                    } else {
-                        //contentLen += half of before and after borders for that cell
-                    }
-                    for (int previous = 0; previous < gu.getRowSpanIndex(); previous++) {
-                        contentLen -= rowHeights[rgi - previous - 1].opt;
-                    }
-                    log.debug("->" + contentLen);
-                    if (contentLen > effCellHeight.min) {
-                        MinOptMaxUtil.extendMinimum(effCellHeight, contentLen, true);
-                    }
-                    if (effCellHeight.min > rowHeights[rgi].min) {
-                        MinOptMaxUtil.extendMinimum(rowHeights[rgi], effCellHeight.min, false);
-                    }
-                }
-            }*/
+        }
+        if (log.isDebugEnabled()) {
+            log.debug("rowGroup:");
+            int totalHeight = 0;
+            for (int i = 0; i < rowHeights.length; i++) {
+                totalHeight += rowHeights[i].opt;
+                log.debug("  " + rowHeights[i]);
+            }
+            log.debug("  totalHeigth=" + totalHeight);
         }
     }
 
@@ -488,10 +466,14 @@ public class TableContentLayoutManager {
                 widths, fullWidths)) > 0) {
             int increase = step - laststep;
             int penaltyLen = step + getMaxRemainingHeight(fullWidths, widths) - totalHeight;
+            int effPenaltyLen = penaltyLen;
             int boxLen = step - addedBoxLen - penaltyLen;
             addedBoxLen += boxLen;
             
-            log.debug(step + " " + increase + " box=" + boxLen + " penalty=" + penaltyLen);
+            log.debug("step=" + step + " (+" + increase + ")"
+                    + " box=" + boxLen 
+                    + " penalty=" + penaltyLen
+                    + " effPenalty=" + effPenaltyLen);
             
             //Put all involved grid units into a list
             List gridUnitParts = new java.util.ArrayList(pguArray.length);
index ccbe2f2ab638437bc5655d5828a627c18154342d..edc1f85de5ea743455452e4563bd8edce4e06500 100644 (file)
@@ -53,6 +53,7 @@ public class TableRowIterator {
     /** The table on with this instance operates. */
     protected Table table;
     private ColumnSetup columns;
+    private int type;
     
     /** Holds the current row (TableCell instances) */
     private List currentRow = new java.util.ArrayList();
@@ -74,6 +75,7 @@ public class TableRowIterator {
     public TableRowIterator(Table table, ColumnSetup columns, int what) {
         this.table = table;
         this.columns = columns;
+        this.type = what;
         switch(what) {
             case HEADER: {
                 List bodyList = new java.util.ArrayList();
@@ -197,8 +199,11 @@ public class TableRowIterator {
                 if (rows.size() > 0) {
                     getCachedRow(rows.size() - 1).setFlagForAllGridUnits(
                             GridUnit.LAST_IN_BODY, true);
-                    getCachedRow(rows.size() - 1).setFlagForAllGridUnits(
-                            GridUnit.LAST_IN_TABLE, true);
+                    if ((type == FOOTER || table.getTableFooter() == null) 
+                            && type != HEADER) {
+                        getCachedRow(rows.size() - 1).setFlagForAllGridUnits(
+                                GridUnit.LAST_IN_TABLE, true);
+                    }
                 }
                 return false;
             }
@@ -235,7 +240,8 @@ public class TableRowIterator {
         if (firstInBody) {
             gridUnits.setFlagForAllGridUnits(GridUnit.FIRST_IN_BODY, true);
         }
-        if (firstInTable) {
+        if (firstInTable && (type == HEADER || table.getTableHeader() == null)
+                && type != FOOTER) {
             gridUnits.setFlagForAllGridUnits(GridUnit.FIRST_IN_TABLE, true);
         }
         log.debug(gridUnits);
@@ -268,11 +274,21 @@ public class TableRowIterator {
         //Create all row-spanned grid units based on information from the last row
         int colnum = 1;
         ListIterator spanIter = lastRowsSpanningCells.listIterator();
+        GridUnit[] horzSpan = null;
         while (spanIter.hasNext()) {
             GridUnit gu = (GridUnit)spanIter.next();
             if (gu != null) {
+                if (gu.getColSpanIndex() == 0) {
+                    horzSpan = new GridUnit[gu.getCell().getNumberColumnsSpanned()];
+                }
                 GridUnit newGU = gu.createNextRowSpanningGridUnit();
                 safelySetListItem(gridUnits, colnum - 1, newGU);
+                horzSpan[newGU.getColSpanIndex()] = newGU;
+                if (newGU.isLastGridUnitColSpan()) {
+                    //Add the array of row-spanned grid units to the primary grid unit
+                    newGU.getPrimary().addRow(horzSpan);
+                    horzSpan = null;
+                }
                 if (newGU.isLastGridUnitRowSpan()) {
                     spanIter.set(null);
                 } else {
@@ -313,7 +329,7 @@ public class TableRowIterator {
             
             if (gu.hasSpanning()) {
                 //Add grid units on spanned slots if any
-                GridUnit[] horzSpan = new GridUnit[cell.getNumberColumnsSpanned()];
+                horzSpan = new GridUnit[cell.getNumberColumnsSpanned()];
                 horzSpan[0] = gu;
                 for (int j = 1; j < cell.getNumberColumnsSpanned(); j++) {
                     colnum++;