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/03/30 14:25:21 UTC

svn commit: r524062 - in /xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr: KnuthPossPosIter.java table/RowPainter.java table/TableCellLayoutManager.java

Author: vhennebert
Date: Fri Mar 30 05:25:19 2007
New Revision: 524062

URL: http://svn.apache.org/viewvc?view=rev&rev=524062
Log:
- fix the painting of borders for spanning cells in collapsing model
- rename gridUnit into primaryGridUnit in TableCellLM for clarity
- fix some checkstyle issues

Modified:
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/KnuthPossPosIter.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/RowPainter.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/KnuthPossPosIter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/KnuthPossPosIter.java?view=diff&rev=524062&r1=524061&r2=524062
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/KnuthPossPosIter.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/KnuthPossPosIter.java Fri Mar 30 05:25:19 2007
@@ -28,8 +28,8 @@
     /**
      * Main constructor
      * @param elementList List of Knuth elements
-     * @param startPos starting position
-     * @param endPos ending position
+     * @param startPos starting position, inclusive
+     * @param endPos ending position, exclusive
      */
     public KnuthPossPosIter(List elementList, int startPos, int endPos) {
         super(elementList.listIterator(startPos));

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/RowPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/RowPainter.java?view=diff&rev=524062&r1=524061&r2=524062
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/RowPainter.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/RowPainter.java Fri Mar 30 05:25:19 2007
@@ -179,7 +179,8 @@
                     //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);
+                    addAreasForCell(primaryGridUnits[i], start[i], end[i], lastRow, partBPD[i],
+                            actualRowHeight);
                     primaryGridUnits[i] = null;
                     start[i] = 0;
                     end[i] = -1;
@@ -191,7 +192,8 @@
                 //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);
+                addAreasForCell(currentGU.getPrimary(), start[i], end[i], lastRow, partBPD[i],
+                        actualRowHeight);
                 start[i] = 0;
                 end[i] = -1;
                 partBPD[i] = 0;
@@ -221,11 +223,12 @@
      * @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},
+     * @param bodyType {@link TableRowIterator#HEADER}, {@link TableRowIterator#FOOTER}, or
      * {@link TableRowIterator#BODY}
      * @return the cell's height
      */
-    private int computeSpanHeight(PrimaryGridUnit pgu, int start, int end, int columnIndex, int bodyType) {
+    private int computeSpanHeight(PrimaryGridUnit pgu, int start, int end, int columnIndex,
+            int bodyType) {
         if (log.isTraceEnabled()) {
             log.trace("getting len for " + columnIndex + " "
                     + start + "-" + end);
@@ -299,14 +302,33 @@
             firstRow[bt] = row.getIndex();
         }
         //Determine the first row in this sequence
-        int startRow = Math.max(pgu.getStartRow(), firstRow[bt]);
+        int startRowIndex = Math.max(pgu.getStartRow(), firstRow[bt]);
+        int lastRowIndex = lastRow.getIndex();
+
+        // In collapsing-border model, if the cell spans over several columns/rows then
+        // dedicated areas will be created for each grid unit to hold the corresponding
+        // borders. For that we need to know the height of each grid unit, that is of each
+        // grid row spanned over by the cell
+        int[] spannedGridRowHeights = null;
+        if (!tclm.getTableLM().getTable().isSeparateBorderModel() && pgu.hasSpanning()) {
+            spannedGridRowHeights = new int[lastRowIndex - startRowIndex + 1];
+            int prevOffset = ((Integer)rowOffsets[bt].get(new Integer(startRowIndex))).intValue();
+            for (int i = 0; i < lastRowIndex - startRowIndex; i++) {
+                int newOffset = ((Integer) rowOffsets[bt].get(new Integer(startRowIndex + i + 1)))
+                        .intValue();
+                spannedGridRowHeights[i] = newOffset - prevOffset;
+                prevOffset = newOffset;
+            }
+            spannedGridRowHeights[lastRowIndex - startRowIndex] = rowHeight;
+        }
+
         //Determine y offset for the cell
-        Integer offset = (Integer)rowOffsets[bt].get(new Integer(startRow));
+        Integer offset = (Integer)rowOffsets[bt].get(new Integer(startRowIndex));
         while (offset == null) {
             //TODO Figure out what this does and when it's triggered
             //This block is probably never used, at least it's not triggered by any of our tests
-            startRow--;
-            offset = (Integer)rowOffsets[bt].get(new Integer(startRow));
+            startRowIndex--;
+            offset = (Integer)rowOffsets[bt].get(new Integer(startRowIndex));
         }
         int effYOffset = offset.intValue();
         int effCellHeight = rowHeight;
@@ -329,7 +351,8 @@
             SpaceResolver.performConditionalsNotification(pgu.getElements(),
                     startPos, endPos, prevBreak);
         }
-        cellLM.addAreas(new KnuthPossPosIter(pgu.getElements(),
-                startPos, endPos + 1), layoutContext);
+        cellLM.addAreas(new KnuthPossPosIter(pgu.getElements(), startPos, endPos + 1),
+                layoutContext, spannedGridRowHeights, startRowIndex - pgu.getStartRow(),
+                lastRowIndex - pgu.getStartRow() + 1);
     }
 }

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java?view=diff&rev=524062&r1=524061&r2=524062
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java Fri Mar 30 05:25:19 2007
@@ -16,13 +16,14 @@
  */
 
 /* $Id$ */
- 
+
 package org.apache.fop.layoutmgr.table;
 
 import java.util.LinkedList;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.fop.datatypes.PercentBaseContext;
 import org.apache.fop.fo.FONode;
 import org.apache.fop.fo.flow.Table;
 import org.apache.fop.fo.flow.TableCell;
@@ -48,20 +49,20 @@
  * LayoutManager for a table-cell FO.
  * A cell contains blocks. These blocks fill the cell.
  */
-public class TableCellLayoutManager extends BlockStackingLayoutManager 
+public class TableCellLayoutManager extends BlockStackingLayoutManager
             implements BlockLevelLayoutManager {
 
     /**
      * logging instance
      */
     private static Log log = LogFactory.getLog(TableCellLayoutManager.class);
-    
-    private PrimaryGridUnit gridUnit;
-    
+
+    private PrimaryGridUnit primaryGridUnit;
+
     private Block curBlockArea;
 
     private int inRowIPDOffset;
-    
+
     private int xoffset;
     private int yoffset;
     private int cellIPD;
@@ -75,23 +76,23 @@
     /**
      * Create a new Cell layout manager.
      * @param node table-cell FO for which to create the LM
-     * @param pgu primary grid unit for the cell 
+     * @param pgu primary grid unit for the cell
      */
     public TableCellLayoutManager(TableCell node, PrimaryGridUnit pgu) {
         super(node);
         fobj = node;
-        this.gridUnit = pgu;
+        this.primaryGridUnit = pgu;
     }
 
     /** @return the table-cell FO */
     public TableCell getTableCell() {
         return (TableCell)this.fobj;
     }
-    
+
     private boolean isSeparateBorderModel() {
         return getTable().isSeparateBorderModel();
     }
-    
+
     /** @see org.apache.fop.layoutmgr.LayoutManager#initialize() */
     public void initialize() {
         borderAndPaddingBPD = 0;
@@ -107,7 +108,7 @@
         borderAndPaddingBPD += getTableCell().getCommonBorderPaddingBackground()
                 .getPaddingAfter(false, this);
     }
-    
+
     /**
      * @return the table owning this cell
      */
@@ -118,12 +119,12 @@
         }
         return (Table)node;
     }
-    
+
 
     /** @see org.apache.fop.layoutmgr.BlockStackingLayoutManager#getIPIndents() */
     protected int getIPIndents() {
         int iIndents = 0;
-        int[] startEndBorderWidths = gridUnit.getStartEndBorderWidths();
+        int[] startEndBorderWidths = primaryGridUnit.getStartEndBorderWidths();
         startBorderWidth += startEndBorderWidths[0];
         endBorderWidth += startEndBorderWidths[1];
         iIndents += startBorderWidth;
@@ -135,14 +136,14 @@
         iIndents += getTableCell().getCommonBorderPaddingBackground().getPaddingEnd(false, this);
         return iIndents;
     }
-    
+
     /**
      * @see org.apache.fop.layoutmgr.LayoutManager
      */
     public LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
         MinOptMax stackLimit = new MinOptMax(context.getStackLimit());
 
-        referenceIPD = context.getRefIPD(); 
+        referenceIPD = context.getRefIPD();
         cellIPD = referenceIPD;
         cellIPD -= getIPIndents();
         if (isSeparateBorderModel()) {
@@ -173,7 +174,7 @@
                 context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
                 childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false);
             }
-            
+
             if (returnedList.size() == 1
                     && ((ListElement)returnedList.getFirst()).isForcedBreak()) {
                 // a descendant of this block has break-before
@@ -193,13 +194,13 @@
 
                 //Space resolution
                 SpaceResolver.resolveElementList(returnList);
-                
+
                 return returnList;
             } else {
                 if (prevLM != null) {
                     // there is a block handled by prevLM
                     // before the one handled by curLM
-                    if (mustKeepTogether() 
+                    if (mustKeepTogether()
                             || context.isKeepWithNextPending()
                             || childLC.isKeepWithPreviousPending()) {
                         //Clear keep pending flag
@@ -242,7 +243,7 @@
 
                     //Space resolution
                     SpaceResolver.resolveElementList(returnList);
-                    
+
                     return returnList;
                 }
             }
@@ -256,16 +257,16 @@
 
         returnedList = new LinkedList();
         wrapPositionElements(contentList, returnList);
-        
+
         //Space resolution
         SpaceResolver.resolveElementList(returnList);
-        
+
         getPSLM().notifyEndOfLayout(((TableCell)getFObj()).getId());
-        
+
         setFinished(true);
         return returnList;
     }
-    
+
     /**
      * Set the y offset of this cell.
      * This offset is used to set the absolute position of the cell.
@@ -294,7 +295,7 @@
     public void setInRowIPDOffset(int off) {
         this.inRowIPDOffset = off;
     }
-    
+
     /**
      * Set the content height for this cell. This method is used during
      * addAreas() stage.
@@ -304,7 +305,7 @@
     public void setContentHeight(int h) {
         usedBPD = h;
     }
-    
+
     /**
      * Set the row height that contains this cell. This method is used during
      * addAreas() stage.
@@ -328,24 +329,36 @@
         } else {
             bpd -= gu.getPrimary().getHalfMaxBorderWidth();
         }
-        CommonBorderPaddingBackground cbpb 
-            = gu.getCell().getCommonBorderPaddingBackground(); 
+        CommonBorderPaddingBackground cbpb
+            = gu.getCell().getCommonBorderPaddingBackground();
         bpd -= cbpb.getPaddingBefore(false, this);
         bpd -= cbpb.getPaddingAfter(false, this);
         bpd -= 2 * ((TableLayoutManager)getParent()).getHalfBorderSeparationBPD();
         return bpd;
     }
-    
+
     /**
-     * Add the areas for the break points.
-     * The cell contains block stacking layout managers
-     * that add block areas.
-     *
+     * Add the areas for the break points. The cell contains block stacking layout
+     * managers that add block areas.
+     * 
+     * <p>In the collapsing-border model, the borders of a cell that spans over several
+     * rows or columns are drawn separately for each grid unit. Therefore we must know the
+     * height of each grid row spanned over by the cell. Also, if the cell is broken over
+     * two pages we must know which spanned grid rows are present on the current page.</p>
+     * 
      * @param parentIter the iterator of the break positions
      * @param layoutContext the layout context for adding the areas
+     * @param spannedGridRowHeights in collapsing-border model for a spanning cell, height
+     * of each spanned grid row
+     * @param startRow first grid row on the current page spanned over by the cell,
+     * inclusive
+     * @param endRow last grid row on the current page spanned over by the cell, exclusive
      */
     public void addAreas(PositionIterator parentIter,
-                         LayoutContext layoutContext) {
+                         LayoutContext layoutContext,
+                         int[] spannedGridRowHeights,
+                         int startRow,
+                         int endRow) {
         getParentArea(null);
 
         getPSLM().addIDToPage(getTableCell().getId());
@@ -358,68 +371,65 @@
                         false, false, false, false, this);
             }
         } else {
-            boolean[] outer = new boolean[] {
-                    gridUnit.getFlag(GridUnit.FIRST_IN_TABLE), 
-                    gridUnit.getFlag(GridUnit.LAST_IN_TABLE),
-                    gridUnit.getFlag(GridUnit.IN_FIRST_COLUMN),
-                    gridUnit.getFlag(GridUnit.IN_LAST_COLUMN)};
-            if (!gridUnit.hasSpanning()) {
+            if (!primaryGridUnit.hasSpanning()) {
                 //Can set the borders directly if there's no span
-                TraitSetter.addCollapsingBorders(curBlockArea, 
-                        gridUnit.getBorders(), outer, this);
+                boolean[] outer = new boolean[] {
+                        primaryGridUnit.getFlag(GridUnit.FIRST_IN_TABLE),
+                        primaryGridUnit.getFlag(GridUnit.LAST_IN_TABLE),
+                        primaryGridUnit.getFlag(GridUnit.IN_FIRST_COLUMN),
+                        primaryGridUnit.getFlag(GridUnit.IN_LAST_COLUMN)};
+                TraitSetter.addCollapsingBorders(curBlockArea,
+                        primaryGridUnit.getBorders(), outer, this);
             } else {
+                boolean[] outer = new boolean[4];
                 int dy = yoffset;
-                for (int y = 0; y < gridUnit.getRows().size(); y++) {
-                    GridUnit[] gridUnits = (GridUnit[])gridUnit.getRows().get(y);
+                for (int y = startRow; y < endRow; y++) {
+                    GridUnit[] gridUnits = (GridUnit[])primaryGridUnit.getRows().get(y);
                     int dx = xoffset;
-                    int lastRowHeight = 0;
                     for (int x = 0; x < gridUnits.length; x++) {
                         GridUnit gu = gridUnits[x];
                         if (!gu.hasBorders()) {
                             continue;
                         }
-                        
+
                         //Blocks for painting grid unit borders
                         Block block = new Block();
                         block.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE);
                         block.setPositioning(Block.ABSOLUTE);
 
-                        int bpd = getContentHeight(gu);
-                        if (isSeparateBorderModel()) {
-                            bpd += (gu.getBorders().getBorderBeforeWidth(false));
-                            bpd += (gu.getBorders().getBorderAfterWidth(false));
-                        } else {
-                            bpd += gridUnit.getHalfMaxBeforeBorderWidth() 
-                                    - (gu.getBorders().getBorderBeforeWidth(false) / 2);
-                            bpd += gridUnit.getHalfMaxAfterBorderWidth() 
-                                    - (gu.getBorders().getBorderAfterWidth(false) / 2);
-                        }
+                        int bpd = spannedGridRowHeights[y - startRow];
+                        bpd -= gu.getBorders().getBorderBeforeWidth(false) / 2;
+                        bpd -= gu.getBorders().getBorderAfterWidth(false) / 2;
                         block.setBPD(bpd);
-                        lastRowHeight = rowHeight;
-                        int ipd = gu.getColumn().getColumnWidth().getValue(this);
-                        int borderStartWidth = gu.getBorders().getBorderStartWidth(false) / 2; 
+                        if (log.isTraceEnabled()) {
+                            log.trace("pgu: " + primaryGridUnit + "; gu: " + gu + "; yoffset: "
+                                    + (dy - gu.getBorders().getBorderBeforeWidth(false) / 2)
+                                    + "; bpd: " + bpd);
+                        }
+                        int ipd = gu.getColumn().getColumnWidth().getValue(
+                                (PercentBaseContext) getParent());
+                        int borderStartWidth = gu.getBorders().getBorderStartWidth(false) / 2;
                         ipd -= borderStartWidth;
                         ipd -= gu.getBorders().getBorderEndWidth(false) / 2;
                         block.setIPD(ipd);
                         block.setXOffset(dx + borderStartWidth);
-                        int halfCollapsingBorderHeight = 0;
-                        if (!isSeparateBorderModel()) {
-                            halfCollapsingBorderHeight 
-                                += gu.getBorders().getBorderBeforeWidth(false) / 2;
-                        }
-                        block.setYOffset(dy - halfCollapsingBorderHeight);
+                        block.setYOffset(dy - gu.getBorders().getBorderBeforeWidth(false) / 2);
+                        outer[0] = gu.getFlag(GridUnit.FIRST_IN_TABLE);
+                        outer[1] = gu.getFlag(GridUnit.LAST_IN_TABLE);
+                        outer[2] = gu.getFlag(GridUnit.IN_FIRST_COLUMN);
+                        outer[3] = gu.getFlag(GridUnit.IN_LAST_COLUMN);
                         TraitSetter.addCollapsingBorders(block, gu.getBorders(), outer, this);
                         parentLM.addChildArea(block);
-                        dx += gu.getColumn().getColumnWidth().getValue(this);
+                        dx += gu.getColumn().getColumnWidth().getValue(
+                                (PercentBaseContext) getParent());
                     }
-                    dy += lastRowHeight;
+                    dy += spannedGridRowHeights[y - startRow];
                 }
-                log.warn("TODO Add collapsed border painting for spanned cells");
             }
         }
 
         //Handle display-align
-        int contentBPD = getContentHeight(gridUnit);
+        int contentBPD = getContentHeight(primaryGridUnit);
         if (usedBPD < contentBPD) {
             if (getTableCell().getDisplayAlign() == EN_CENTER) {
                 Block space = new Block();
@@ -433,7 +443,7 @@
         }
 
         AreaAdditionUtil.addAreas(this, parentIter, layoutContext);
-        
+
         curBlockArea.setBPD(contentBPD);
 
         // Add background after we know the BPD
@@ -448,7 +458,7 @@
                     getTableCell().getCommonBorderPaddingBackground(),
                     this);
         }
-        
+
         flush();
 
         curBlockArea = null;
@@ -473,8 +483,7 @@
             curBlockArea.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE);
             TraitSetter.setProducerID(curBlockArea, getTableCell().getId());
             curBlockArea.setPositioning(Block.ABSOLUTE);
-            int indent = 0;
-            indent += startBorderWidth;
+            int indent = startBorderWidth;
             if (!isSeparateBorderModel()) {
                 indent /= 2;
             }
@@ -483,18 +492,18 @@
             // set position
             int borderAdjust = 0;
             if (!isSeparateBorderModel()) {
-                if (gridUnit.hasSpanning()) {
-                    borderAdjust -= gridUnit.getHalfMaxBeforeBorderWidth();
+                if (primaryGridUnit.hasSpanning()) {
+                    borderAdjust -= primaryGridUnit.getHalfMaxBeforeBorderWidth();
                 } else {
-                    borderAdjust += gridUnit.getHalfMaxBeforeBorderWidth();
+                    borderAdjust += primaryGridUnit.getHalfMaxBeforeBorderWidth();
                 }
             } else {
-                //borderAdjust += gridUnit.getBorders().getBorderBeforeWidth(false);
+                //borderAdjust += primaryGridUnit.getBorders().getBorderBeforeWidth(false);
             }
             TableLayoutManager tableLM = (TableLayoutManager)getParent();
-            curBlockArea.setXOffset(xoffset + inRowIPDOffset 
+            curBlockArea.setXOffset(xoffset + inRowIPDOffset
                     + tableLM.getHalfBorderSeparationIPD() + indent);
-            curBlockArea.setYOffset(yoffset - borderAdjust 
+            curBlockArea.setYOffset(yoffset - borderAdjust
                     + tableLM.getHalfBorderSeparationBPD());
             curBlockArea.setIPD(cellIPD);
             //curBlockArea.setHeight();
@@ -550,8 +559,8 @@
     public boolean mustKeepTogether() {
         //TODO Keeps will have to be more sophisticated sooner or later
         boolean keep = ((BlockLevelLayoutManager)getParent()).mustKeepTogether();
-        if (gridUnit.getRow() != null) {
-            keep |= gridUnit.getRow().mustKeepTogether();
+        if (primaryGridUnit.getRow() != null) {
+            keep |= primaryGridUnit.getRow().mustKeepTogether();
         }
         return keep;
     }
@@ -577,9 +586,9 @@
             || !fobj.getKeepWithNext().getWithinColumn().isAuto();
             */
     }
-    
+
     // --------- Property Resolution related functions --------- //
-    
+
     /**
      * Returns the IPD of the content area
      * @return the IPD of the content area
@@ -587,7 +596,7 @@
     public int getContentAreaIPD() {
         return cellIPD;
     }
-   
+
     /**
      * Returns the BPD of the content area
      * @return the BPD of the content area
@@ -600,14 +609,14 @@
             return -1;
         }
     }
-   
+
     /**
      * @see org.apache.fop.layoutmgr.LayoutManager#getGeneratesReferenceArea
      */
     public boolean getGeneratesReferenceArea() {
         return true;
     }
-   
+
     /**
      * @see org.apache.fop.layoutmgr.LayoutManager#getGeneratesBlockArea
      */



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