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 je...@apache.org on 2005/05/04 09:18:13 UTC

cvs commit: xml-fop/src/java/org/apache/fop/layoutmgr MinOptMaxUtil.java

jeremias    2005/05/04 00:18:13

  Modified:    src/java/org/apache/fop/layoutmgr/table Tag:
                        Temp_KnuthStylePageBreaking TableRowIterator.java
                        Cell.java GridUnit.java CollapsingBorderModel.java
                        EmptyGridUnit.java TableContentLayoutManager.java
                        PrimaryGridUnit.java
                        CollapsingBorderModelEyeCatching.java
               src/java/org/apache/fop/layoutmgr Tag:
                        Temp_KnuthStylePageBreaking MinOptMaxUtil.java
  Log:
  Next step: Basic border resolution and proper painting (even though it's following a possibly misinterpreted model ATM)
  Bugfixes in the collapsing border model resolution.
  Note: The Knuth elements do not take borders into account, yet, so page breaking is off-target.
  
  Revision  Changes    Path
  No                   revision
  No                   revision
  1.1.2.5   +51 -3     xml-fop/src/java/org/apache/fop/layoutmgr/table/Attic/TableRowIterator.java
  
  Index: TableRowIterator.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/table/Attic/TableRowIterator.java,v
  retrieving revision 1.1.2.4
  retrieving revision 1.1.2.5
  diff -u -r1.1.2.4 -r1.1.2.5
  --- TableRowIterator.java	28 Apr 2005 13:44:01 -0000	1.1.2.4
  +++ TableRowIterator.java	4 May 2005 07:18:12 -0000	1.1.2.5
  @@ -150,11 +150,35 @@
           }
       }
       
  +    public void backToPreviewRow() {
  +        currentIndex--;
  +    }
  +    
  +    public EffRow getFirstRow() {
  +        if (rows.size() == 0) {
  +            prefetchNext();
  +        }
  +        return getCachedRow(0);
  +    }
  +    
  +    public EffRow getLastRow() {
  +        while (prefetchNext()) {
  +            //nop
  +        }
  +        return getCachedRow(rows.size() - 1);
  +    }
  +    
       public EffRow getCachedRow(int index) {
  -        return (EffRow)rows.get(index);
  +        if (index < 0 || index >= rows.size()) {
  +            return null;
  +        } else {
  +            return (EffRow)rows.get(index);
  +        }
       }
       
       private boolean prefetchNext() {
  +        boolean firstInTable = false;
  +        boolean firstInBody = false;
           if (childInBodyIterator != null) {
               if (!childInBodyIterator.hasNext()) {
                   //force skip on to next body
  @@ -164,8 +188,18 @@
           if (childInBodyIterator == null) {
               if (bodyIterator.hasNext()) {
                   childInBodyIterator = ((TableBody)bodyIterator.next()).getChildNodes();
  +                if (rows.size() == 0) {
  +                    firstInTable = true;
  +                }
  +                firstInBody = true;
               } else {
                   //no more rows
  +                if (rows.size() > 0) {
  +                    getCachedRow(rows.size() - 1).setFlagForAllGridUnits(
  +                            GridUnit.LAST_IN_BODY, true);
  +                    getCachedRow(rows.size() - 1).setFlagForAllGridUnits(
  +                            GridUnit.LAST_IN_TABLE, true);
  +                }
                   return false;
               }
           }
  @@ -198,6 +232,12 @@
               throw new IllegalStateException("Illegal class found: " + node.getClass().getName());
           }
           EffRow gridUnits = buildGridRow(this.currentRow);
  +        if (firstInBody) {
  +            gridUnits.setFlagForAllGridUnits(GridUnit.FIRST_IN_BODY, true);
  +        }
  +        if (firstInTable) {
  +            gridUnits.setFlagForAllGridUnits(GridUnit.FIRST_IN_TABLE, true);
  +        }
           log.debug(gridUnits);
           rows.add(gridUnits);
           return true;
  @@ -277,7 +317,7 @@
                   horzSpan[0] = gu;
                   for (int j = 1; j < cell.getNumberColumnsSpanned(); j++) {
                       colnum++;
  -                    GridUnit guSpan = new GridUnit(cell, columns.getColumn(colnum), colnum - 1, j);
  +                    GridUnit guSpan = new GridUnit(gu, columns.getColumn(colnum), colnum - 1, j);
                       if (safelyGetListItem(gridUnits, colnum - 1) != null) {
                           log.error("Overlapping cell at position " + colnum);
                           //TODO throw layout exception
  @@ -409,6 +449,14 @@
               return gridUnits;
           }
           
  +        public void setFlagForAllGridUnits(int flag, boolean value) {
  +            Iterator iter = gridUnits.iterator();
  +            while (iter.hasNext()) {
  +                GridUnit gu = (GridUnit)iter.next();
  +                gu.setFlag(flag, value);
  +            }
  +        }
  +
           /** @see java.lang.Object#toString() */
           public String toString() {
               StringBuffer sb = new StringBuffer("EffRow {");
  
  
  
  1.26.2.5  +34 -36    xml-fop/src/java/org/apache/fop/layoutmgr/table/Cell.java
  
  Index: Cell.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/table/Cell.java,v
  retrieving revision 1.26.2.4
  retrieving revision 1.26.2.5
  diff -u -r1.26.2.4 -r1.26.2.5
  --- Cell.java	28 Apr 2005 13:44:01 -0000	1.26.2.4
  +++ Cell.java	4 May 2005 07:18:12 -0000	1.26.2.5
  @@ -395,6 +395,16 @@
           rowHeight = h;
       }
   
  +    private int getContentHeight(int rowHeight, GridUnit gu) {
  +        int bpd = rowHeight;
  +        bpd -= gu.getPrimary().getHalfMaxBorderWidth();
  +        CommonBorderPaddingBackground cbpb 
  +            = gu.getCell().getCommonBorderPaddingBackground(); 
  +        bpd -= cbpb.getPaddingBefore(false);
  +        bpd -= cbpb.getPaddingAfter(false);
  +        return bpd;
  +    }
  +    
       /**
        * Add the areas for the break points.
        * The cell contains block stacking layout managers
  @@ -421,7 +431,11 @@
           } else {
               TraitSetter.addBackground(curBlockArea, fobj.getCommonBorderPaddingBackground());
               //TODO Set these booleans right
  -            boolean[] outer = new boolean[] {false, false, false, false};
  +            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()) {
                   //Can set the borders directly if there's no span
                   TraitSetter.addCollapsingBorders(curBlockArea, 
  @@ -442,9 +456,12 @@
                           Block block = new Block();
                           block.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE);
                           block.setPositioning(Block.ABSOLUTE);
  -                        //block.setBPD(gu.row.getRowHeight());
  -                        block.setBPD(rowHeight); //TODO This needs to be fixed for row spanning
  -                        //lastRowHeight = gu.row.getRowHeight();
  +
  +                        int bpd = getContentHeight(rowHeight, gu);
  +                        bpd += gridUnit.getHalfMaxBeforeBorderWidth() 
  +                                - (gu.getBorders().getBorderBeforeWidth(false) / 2);
  +                        block.setBPD(bpd);
  +                        //TODO This needs to be fixed for row spanning
                           lastRowHeight = rowHeight;
                           int ipd = gu.getColumn().getColumnWidth().getValue();
                           int borderStartWidth = gu.getBorders().getBorderStartWidth(false) / 2; 
  @@ -452,7 +469,12 @@
                           ipd -= gu.getBorders().getBorderEndWidth(false) / 2;
                           block.setIPD(ipd);
                           block.setXOffset(dx + borderStartWidth);
  -                        block.setYOffset(dy);
  +                        int halfCollapsingBorderHeight = 0;
  +                        if (!fobj.isSeparateBorderModel()) {
  +                            halfCollapsingBorderHeight += 
  +                                gu.getBorders().getBorderBeforeWidth(false) / 2;
  +                        }
  +                        block.setYOffset(dy - halfCollapsingBorderHeight);
                           TraitSetter.addCollapsingBorders(block, gu.getBorders(), outer);
                           parentLM.addChildArea(block);
                           dx += gu.getColumn().getColumnWidth().getValue();
  @@ -477,35 +499,8 @@
           }
   
           AreaAdditionUtil.addAreas(parentIter, layoutContext);
  -        /*
  -        LayoutManager childLM;
  -        int iStartPos = 0;
  -        LayoutContext lc = new LayoutContext(0);
  -        PositionIterator childPosIter;
  -        childPosIter = new StackingIter(positionList.listIterator());
  -        while ((childLM = childPosIter.getNextChildLM()) != null) {
  -            // set last area flag
  -            lc.setFlags(LayoutContext.LAST_AREA,
  -                    (layoutContext.isLastArea() && childLM == lastLM));
  -            lc.setStackLimit(layoutContext.getStackLimit());
  -            // Add the line areas to Area
  -            childLM.addAreas(childPosIter, lc);
  -        }
  -        while (parentIter.hasNext()) {
  -            LeafPosition lfp = (LeafPosition) parentIter.next();
  -            // Add the block areas to Area
  -            PositionIterator breakPosIter =
  -              new BreakPossPosIter(childBreaks, iStartPos,
  -                                   lfp.getLeafPos() + 1);
  -            iStartPos = lfp.getLeafPos() + 1;
  -            while ((childLM = breakPosIter.getNextChildLM()) != null) {
  -                childLM.addAreas(breakPosIter, lc);
  -            }
  -        }*/
  -
           
  -        int contentBPD = rowHeight;
  -        contentBPD -= borderAndPaddingBPD;
  +        int contentBPD = getContentHeight(rowHeight, gridUnit);
           curBlockArea.setBPD(contentBPD);
   
           flush();
  @@ -546,8 +541,11 @@
               }
               int halfCollapsingBorderHeight = 0;
               if (!fobj.isSeparateBorderModel()) {
  -                halfCollapsingBorderHeight += 
  -                    gridUnit.getBorders().getBorderBeforeWidth(false) / 2;
  +                if (gridUnit.hasSpanning()) {
  +                    halfCollapsingBorderHeight -= gridUnit.getHalfMaxBeforeBorderWidth();
  +                } else {
  +                    halfCollapsingBorderHeight += gridUnit.getHalfMaxBeforeBorderWidth();
  +                }
               }
               curBlockArea.setXOffset(xoffset + inRowIPDOffset + halfBorderSep + indent);
               curBlockArea.setYOffset(yoffset - halfCollapsingBorderHeight);
  @@ -585,7 +583,7 @@
           }
       }
   
  -    /* (non-Javadoc)
  +    /**
        * @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#negotiateBPDAdjustment(int, org.apache.fop.layoutmgr.KnuthElement)
        */
       public int negotiateBPDAdjustment(int adj, KnuthElement lastElement) {
  
  
  
  1.1.2.5   +38 -3     xml-fop/src/java/org/apache/fop/layoutmgr/table/GridUnit.java
  
  Index: GridUnit.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/table/GridUnit.java,v
  retrieving revision 1.1.2.4
  retrieving revision 1.1.2.5
  diff -u -r1.1.2.4 -r1.1.2.5
  --- GridUnit.java	28 Apr 2005 13:44:01 -0000	1.1.2.4
  +++ GridUnit.java	4 May 2005 07:18:12 -0000	1.1.2.5
  @@ -45,6 +45,8 @@
       /** Indicates that the grid unit is in the last row (context: table). */
       public static final int LAST_IN_TABLE = 5;
       
  +    /** Primary grid unit */
  +    private PrimaryGridUnit primary;
       /** Table cell which occupies this grid unit */
       private TableCell cell;
       /** Table column that this grid unit belongs to */
  @@ -63,6 +65,15 @@
       
       
       public GridUnit(TableCell cell, TableColumn column, int startCol, int colSpanIndex) {
  +        this(null, cell, column, startCol, colSpanIndex);
  +    }
  +    
  +    public GridUnit(PrimaryGridUnit primary, TableColumn column, int startCol, int colSpanIndex) {
  +        this(primary, primary.getCell(), column, startCol, colSpanIndex);
  +    }
  +    
  +    protected GridUnit(PrimaryGridUnit primary, TableCell cell, TableColumn column, int startCol, int colSpanIndex) {
  +        this.primary = primary;
           this.cell = cell;
           this.column = column;
           this.startCol = startCol;
  @@ -101,6 +112,13 @@
           return (Table)node;
       }
       
  +    /**
  +     * @return the primary grid unit if this is a spanned grid unit
  +     */
  +    public PrimaryGridUnit getPrimary() {
  +        return (isPrimary() ? (PrimaryGridUnit)this : this.primary);
  +    }
  +
       public boolean isPrimary() {
           return false;
       }
  @@ -132,6 +150,13 @@
       }
       
       /**
  +     * @return the index of the grid unit inside a cell in row direction
  +     */
  +    public int getRowSpanIndex() {
  +        return this.rowSpanIndex;
  +    }
  +    
  +    /**
        * 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.
        * See CollapsingBorderModel(EyeCatching) where this method is used. 
  @@ -176,6 +201,16 @@
        * @param side the side to resolve (one of CommonBorderPaddingBackground.BEFORE|AFTER|START|END)
        */
       public void resolveBorder(GridUnit other, int side) {
  +        resolveBorder(other, side, 0);
  +    }
  +    
  +    /**
  +     * Resolve collapsing borders for the given cell. Used in case of the collapsing border model.
  +     * @param other neighbouring grid unit if any
  +     * @param side the side to resolve (one of CommonBorderPaddingBackground.BEFORE|AFTER|START|END)
  +     * @param resFlags flags for the border resolution
  +     */
  +    public void resolveBorder(GridUnit other, int side, int resFlags) {
           CollapsingBorderModel borderModel = CollapsingBorderModel.getBorderModelFor(
                   getTable().getBorderCollapse());
           if (this.effBorders == null) {
  @@ -183,7 +218,7 @@
           }
           this.effBorders.setBorderInfo(
                   borderModel.determineWinner(this, other, 
  -                        side, 0), side);
  +                        side, resFlags), side);
       }
       
       public boolean getFlag(int which) {
  @@ -206,7 +241,7 @@
               return null;
           } else {
               //cloning the current GridUnit with adjustments
  -            GridUnit gu = new GridUnit(getCell(), getColumn(), startCol, colSpanIndex);
  +            GridUnit gu = new GridUnit(getPrimary(), getColumn(), startCol, colSpanIndex);
               gu.rowSpanIndex = rowSpanIndex + 1;
               return gu;
           }
  
  
  
  1.1.2.3   +17 -5     xml-fop/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModel.java
  
  Index: CollapsingBorderModel.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModel.java,v
  retrieving revision 1.1.2.2
  retrieving revision 1.1.2.3
  diff -u -r1.1.2.2 -r1.1.2.3
  --- CollapsingBorderModel.java	7 Apr 2005 07:09:24 -0000	1.1.2.2
  +++ CollapsingBorderModel.java	4 May 2005 07:18:12 -0000	1.1.2.3
  @@ -28,14 +28,26 @@
    */
   public abstract class CollapsingBorderModel {
   
  +    /** before side */
  +    protected static final int BEFORE = CommonBorderPaddingBackground.BEFORE;
  +    /** after side */
  +    protected static final int AFTER = CommonBorderPaddingBackground.AFTER;
  +    /** start side */
  +    protected static final int START = CommonBorderPaddingBackground.START;
  +    /** end side */
  +    protected static final int END = CommonBorderPaddingBackground.END;
  +    
  +    /** Flag: current grid unit is either start or end of the table. */
  +    public static final int VERTICAL_START_END_OF_TABLE = 1;
  +    
       /** Indicates that the cell is/starts in the first row being painted on a particular page */
  -    public static final int FIRST_ROW_IN_TABLE_PART = 1;
  +    //public static final int FIRST_ROW_IN_TABLE_PART = 1;
       /** Indicates that the cell is/ends in the last row being painted on a particular page */
  -    public static final int LAST_ROW_IN_TABLE_PART  = 2;
  +    //public static final int LAST_ROW_IN_TABLE_PART  = 2;
       /** Indicates that the cell is/starts in the first row of a body/table-header/table-footer */
  -    public static final int FIRST_ROW_IN_GROUP      = 4;
  +    //public static final int FIRST_ROW_IN_GROUP      = 4;
       /** Indicates that the cell is/end in the last row of a body/table-header/table-footer */
  -    public static final int LAST_ROW_IN_GROUP       = 8;
  +    //public static final int LAST_ROW_IN_GROUP       = 8;
       
       private static CollapsingBorderModel collapse = null;
       private static CollapsingBorderModel collapseWithPrecedence = null;
  
  
  
  1.1.2.2   +3 -5      xml-fop/src/java/org/apache/fop/layoutmgr/table/Attic/EmptyGridUnit.java
  
  Index: EmptyGridUnit.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/table/Attic/EmptyGridUnit.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- EmptyGridUnit.java	7 Apr 2005 07:09:24 -0000	1.1.2.1
  +++ EmptyGridUnit.java	4 May 2005 07:18:12 -0000	1.1.2.2
  @@ -19,7 +19,6 @@
   package org.apache.fop.layoutmgr.table;
   
   import org.apache.fop.fo.flow.TableBody;
  -import org.apache.fop.fo.flow.TableCell;
   import org.apache.fop.fo.flow.TableColumn;
   import org.apache.fop.fo.flow.TableRow;
   
  @@ -35,12 +34,11 @@
        * @param row Optional table-row instance
        * @param column table-column instance
        * @param body table-body the grid unit belongs to
  -     * @param startCol 
  -     * @param colSpanIndex
  +     * @param startCol column index 
        */
       public EmptyGridUnit(TableRow row, TableColumn column, TableBody body, 
               int startCol) {
  -        super(null, column, startCol, 0);
  +        super(null, null, column, startCol, 0);
           this.row = row;
           this.body = body;
       }
  
  
  
  1.1.2.9   +307 -86   xml-fop/src/java/org/apache/fop/layoutmgr/table/Attic/TableContentLayoutManager.java
  
  Index: TableContentLayoutManager.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/table/Attic/TableContentLayoutManager.java,v
  retrieving revision 1.1.2.8
  retrieving revision 1.1.2.9
  diff -u -r1.1.2.8 -r1.1.2.9
  --- TableContentLayoutManager.java	28 Apr 2005 13:44:01 -0000	1.1.2.8
  +++ TableContentLayoutManager.java	4 May 2005 07:18:13 -0000	1.1.2.9
  @@ -30,6 +30,7 @@
   import org.apache.fop.area.Trait;
   import org.apache.fop.fo.flow.Table;
   import org.apache.fop.fo.flow.TableRow;
  +import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
   import org.apache.fop.fo.properties.LengthRangeProperty;
   import org.apache.fop.layoutmgr.KnuthBox;
   import org.apache.fop.layoutmgr.KnuthElement;
  @@ -37,6 +38,7 @@
   import org.apache.fop.layoutmgr.KnuthPossPosIter;
   import org.apache.fop.layoutmgr.LayoutContext;
   import org.apache.fop.layoutmgr.LayoutManager;
  +import org.apache.fop.layoutmgr.MinOptMaxUtil;
   import org.apache.fop.layoutmgr.Position;
   import org.apache.fop.layoutmgr.PositionIterator;
   import org.apache.fop.layoutmgr.TraitSetter;
  @@ -62,6 +64,10 @@
       private int startXOffset;
       private int usedBPD;
       
  +    /**
  +     * Main constructor
  +     * @param parent Parent layout manager
  +     */
       public TableContentLayoutManager(TableLayoutManager parent) {
           this.tableLM = parent;
           Table table = getTableLM().getTable();
  @@ -76,10 +82,16 @@
           }
       }
       
  +    /**
  +     * @return the table layout manager
  +     */
       public TableLayoutManager getTableLM() {
           return this.tableLM;
       }
       
  +    /**
  +     * @return the column setup of this table
  +     */
       public ColumnSetup getColumns() {
           return getTableLM().getColumns();
       }
  @@ -169,101 +181,292 @@
        * @param iter TableRowIterator instance to fetch rows from
        * @param context Active LayoutContext
        * @param alignment alignment indicator
  +     * @param isHeaderFooter true if currently handling headers/footers
        * @return An element list
        */
       private LinkedList getKnuthElementsForRowIterator(TableRowIterator iter, 
  -            LayoutContext context, int alignment, boolean disableHeaderFooter) {
  +            LayoutContext context, int alignment, boolean isHeaderFooter) {
           LinkedList returnList = new LinkedList();
           TableRowIterator.EffRow[] rowGroup = null;
  -        TableRowIterator.EffRow row = null;
           while ((rowGroup = iter.getNextRowGroup()) != null) {
  -            for (int rgi = 0; rgi < rowGroup.length; rgi++) {
  -                row = rowGroup[rgi];
  -                List pgus = new java.util.ArrayList();
  -                TableRow tableRow = null;
  -                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);
  -
  -                        //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);
  +            resolveNormalBeforeAfterBordersForRowGroup(rowGroup, iter);
  +            createElementsForRowGroup(context, alignment, isHeaderFooter, 
  +                        returnList, rowGroup);
  +        }
  +        
  +        //Remove last penalty
  +        KnuthElement last = (KnuthElement)returnList.getLast();
  +        if (last.isPenalty() && last.getW() == 0 && last.getP() == 0) {
  +            returnList.removeLast();
  +        }
  +        return returnList;
  +    }
  +
  +    /**
  +     * Resolves normal borders for a row group.
  +     * @param iter Table row iterator to operate on
  +     */
  +    private void resolveNormalBeforeAfterBordersForRowGroup(TableRowIterator.EffRow[] rowGroup, 
  +            TableRowIterator iter) {
  +        for (int rgi = 0; rgi < rowGroup.length; rgi++) {
  +            TableRowIterator.EffRow row = rowGroup[rgi];
  +            TableRowIterator.EffRow prev = iter.getCachedRow(row.getIndex() - 1);
  +            TableRowIterator.EffRow next = iter.getCachedRow(row.getIndex() + 1);
  +            if (next == null) {
  +                //It wasn't read, yet, or we are at the last row
  +                next = iter.getNextRow();
  +                iter.backToPreviewRow();
  +            }
  +            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.trIter) && (this.footerIter != null)) {
  +                next = this.footerIter.getFirstRow();
  +            }
  +            if ((next == 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();
  +            }
  +            log.debug(prev + " - " + row + " - " + next);
  +            
  +            //Determine the grid units necessary for getting all the borders right
  +            int guCount = row.getGridUnits().size();
  +            if (prev != null) {
  +                guCount = Math.max(guCount, prev.getGridUnits().size());
  +            }
  +            if (next != null) {
  +                guCount = Math.max(guCount, next.getGridUnits().size());
  +            }
  +            GridUnit gu = (GridUnit)row.getGridUnits().get(0);
  +            //Create empty grid units to hold resolved borders of neighbouring cells
  +            //TODO maybe this needs to be done differently (and sooner)
  +            for (int i = 0; i < guCount - row.getGridUnits().size(); i++) {
  +                //TODO This block in untested!
  +                int pos = row.getGridUnits().size() + i;
  +                row.getGridUnits().add(new EmptyGridUnit(gu.getRow(), 
  +                        this.tableLM.getColumns().getColumn(pos + 1), gu.getBody(), 
  +                        pos));
  +            }
  +            
  +            //Now resolve normal borders
  +            if (getTableLM().getTable().isSeparateBorderModel()) {
  +                //nop, borders are already assigned at this point
  +            } else {
  +                for (int i = 0; i < row.getGridUnits().size(); i++) {
  +                    gu = (GridUnit)row.getGridUnits().get(i);
  +                    GridUnit other;
  +                    int flags = 0;
  +                    if (prev != null && i < prev.getGridUnits().size()) {
  +                        other = (GridUnit)prev.getGridUnits().get(i);
  +                    } 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;
  +                    }
  +                    gu.resolveBorder(other, 
  +                            CommonBorderPaddingBackground.BEFORE, flags);
  +                    
  +                    flags = 0;
  +                    if (next != null && i < next.getGridUnits().size()) {
  +                        other = (GridUnit)next.getGridUnits().get(i);
  +                    } 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;
  +                    }
  +                    gu.resolveBorder(other, 
  +                            CommonBorderPaddingBackground.AFTER, flags);
  +                }
  +
  +            }
  +        }
  +    }
  +
  +    /**
  +     * Creates Knuth elements for a row group (see TableRowIterator.getNextRowGroup()).
  +     * @param context Active LayoutContext
  +     * @param alignment alignment indicator
  +     * @param isHeaderFooter true if currently processing headers/footers
  +     * @param returnList List to received the generated elements
  +     * @param rowGroup row group to process
  +     */
  +    private void createElementsForRowGroup(LayoutContext context, int alignment, 
  +            boolean isHeaderFooter, LinkedList returnList, 
  +            TableRowIterator.EffRow[] rowGroup) {
  +        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
  +        for (int rgi = 0; rgi < rowGroup.length; rgi++) {
  +            row = rowGroup[rgi];
  +            rowHeights[rgi] = new MinOptMax(0, 0, Integer.MAX_VALUE);
  +            
  +            pgus.clear();
  +            TableRow tableRow = null;
  +            int minContentHeight = 0;
  +            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);
  +
  +                    //Determine the table-row if any
  +                    if (tableRow == null) {
  +                        tableRow = primary.getRow();
                           
  -                        LinkedList elems = primary.getCellLM().getNextKnuthElements(childLC, alignment);
  -                        primary.setElements(elems);
  -                        log.debug("Elements: " + elems);
  -                        int len = calcCellHeightFromContents(elems);
  -                        pgus.add(primary);
  -                        maxCellHeight = Math.max(maxCellHeight, len);
  -                        if (len > row.getHeight().opt) {
  -                            row.setHeight(new MinOptMax(len));
  +                        //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();
  +                    }
  +                    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));
  +                    maxCellHeight = Math.max(maxCellHeight, primary.getContentLength());
  +
  +                    //Calculate height of row, see CSS21, 17.5.3 Table height algorithms
  +                    if (gu.isLastGridUnitRowSpan()) {
  +                        int effCellContentHeight = minContentHeight;
                           LengthRangeProperty bpd = primary.getCell().getBlockProgressionDimension();
  -                        if (!bpd.getOptimum().isAuto()) {
  -                            if (bpd.getOptimum().getLength().getValue() > row.getHeight().opt) {
  -                                row.setHeight(new MinOptMax(bpd.getOptimum().getLength().getValue()));
  -                            }
  +                        if (!bpd.getMinimum().isAuto()) {
  +                            effCellContentHeight = Math.max(effCellContentHeight,
  +                                    bpd.getMinimum().getLength().getValue());
                           }
  -                        if (tableRow == null) {
  -                            tableRow = primary.getRow();
  +                        effCellContentHeight = Math.max(effCellContentHeight, 
  +                                primary.getContentLength());
  +                        int halfMaxBorderWidths = primary.getHalfMaxBorderWidth();
  +                        int padding = 0;
  +                        CommonBorderPaddingBackground cbpb 
  +                            = primary.getCell().getCommonBorderPaddingBackground(); 
  +                        padding += cbpb.getPaddingBefore(false);
  +                        padding += cbpb.getPaddingAfter(false);
  +                        int effRowHeight = effCellContentHeight + padding + halfMaxBorderWidths;
  +                        if (effRowHeight > rowHeights[rgi].min) {
  +                            //This is the new height of the (grid) row
  +                            MinOptMaxUtil.extendMinimum(rowHeights[rgi], effRowHeight, false);
  +                            row.setHeight(rowHeights[rgi]);
                           }
                       }
  +                    
  +                    pgus.add(primary);
                   }
  -                
  -                if (tableRow != null) {
  -                    LengthRangeProperty bpd = tableRow.getBlockProgressionDimension();
  -                    if (!bpd.getOptimum().isAuto()) {
  -                        if (bpd.getOptimum().getLength().getValue() > row.getHeight().opt) {
  -                            row.setHeight(new MinOptMax(bpd.getOptimum().getLength().getValue()));
  -                        }
  -                    }
  +            }
  +            
  +            log.debug(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);
                   }
  -                log.debug(row);
  -                
  -                PrimaryGridUnit[] pguArray = new PrimaryGridUnit[pgus.size()];
  -                pguArray = (PrimaryGridUnit[])pgus.toArray(pguArray);
  -                LinkedList returnedList = getCombinedKnuthElementsForRow(pguArray, row, 
  -                        disableHeaderFooter);
  -                if (returnedList != null) {
  -                    returnList.addAll(returnedList);
  -                }
  -
  -                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);
  +            } 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);
  +                    }
                   }
  -            }
  +            }*/
           }
  -        
  -        //Remove last penalty
  -        KnuthElement last = (KnuthElement)returnList.getLast();
  -        if (last.isPenalty() && last.getW() == 0 && last.getP() == 0) {
  -            returnList.removeLast();
  -        }
  -        return returnList;
       }
   
       private LinkedList getCombinedKnuthElementsForRow(PrimaryGridUnit[] pguArray, 
  -            TableRowIterator.EffRow row, boolean disableHeaderFooter) {
  +            TableRowIterator.EffRow row, boolean isHeaderFooter) {
           List[] elementLists = new List[pguArray.length];
           for (int i = 0; i < pguArray.length; i++) {
  -            //Copy elements to array lists to improve element access performance
  -            elementLists[i] = new java.util.ArrayList(pguArray[i].getElements());
  +            if (pguArray[i].hasBPD()) {
  +                List list = new java.util.ArrayList(1);
  +                list.add(new KnuthBoxCellWithBPD(
  +                        pguArray[i].getEffectiveContentLength(), pguArray[i]));
  +                elementLists[i] = list;
  +            } else {
  +                //Copy elements (LinkedList) to array lists to improve element access performance
  +                elementLists[i] = new java.util.ArrayList(pguArray[i].getElements());
  +            }
           }
           int[] index = new int[pguArray.length];
           int[] start = new int[pguArray.length];
  @@ -274,7 +477,7 @@
           
           int totalHeight = 0;
           for (int i = 0; i < pguArray.length; i++) {
  -            fullWidths[i] = calcCellHeightFromContents(pguArray[i].getElements());
  +            fullWidths[i] = pguArray[i].getContentLength();
               totalHeight = Math.max(totalHeight, fullWidths[i]);
           }
           int laststep = 0;
  @@ -294,7 +497,14 @@
               List gridUnitParts = new java.util.ArrayList(pguArray.length);
               for (int i = 0; i < pguArray.length; i++) {
                   if (end[i] >= start[i]) {
  -                    gridUnitParts.add(new GridUnitPart(pguArray[i], start[i], end[i]));
  +                    if (start[i] == 0 && end[i] == 0 
  +                            && elementLists[i].size() == 1
  +                            && elementLists[i].get(0) instanceof KnuthBoxCellWithBPD) {
  +                        gridUnitParts.add(new GridUnitPart(pguArray[i], 
  +                                0, pguArray[i].getElements().size() - 1));
  +                    } else {
  +                        gridUnitParts.add(new GridUnitPart(pguArray[i], start[i], end[i]));
  +                    }
                   }
               }
               
  @@ -303,7 +513,7 @@
                       gridUnitParts, row);
               returnList.add(new KnuthBox(boxLen, tcpos, false));
               TableHFPenaltyPosition penaltyPos = new TableHFPenaltyPosition(getTableLM());
  -            if (!disableHeaderFooter) {
  +            if (!isHeaderFooter) {
                   if (!getTableLM().getTable().omitHeaderAtBreak()) {
                       penaltyLen += this.headerNetHeight;
                       penaltyPos.headerElements = this.headerList;
  @@ -547,9 +757,8 @@
           private void handleTableContentPosition(TableContentPosition tcpos) {
               rowFO = null;
               if (lastRow != tcpos.row && lastRow != null) {
  -                //yoffset += lastRow.getHeight().opt;
  -                yoffset += lastRowHeight;
  -                this.accumulatedBPD += lastRowHeight;
  +                yoffset += lastRow.getHeight().opt;
  +                this.accumulatedBPD += lastRow.getHeight().opt;
               }
               lastRow = tcpos.row;
               Iterator partIter = tcpos.gridUnitParts.iterator();
  @@ -573,7 +782,7 @@
               
               //Calculate the height of the row
               int maxLen = addAreasAndFlushRow(false);
  -            lastRowHeight = maxLen;
  +            lastRowHeight = tcpos.row.getHeight().opt;
           }
           
           private int addAreasAndFlushRow(boolean finalFlush) {
  @@ -588,7 +797,7 @@
                       partLength[i] = len;
                       log.debug("len of part: " + len);
                       maxLen = Math.max(maxLen, len);
  -                    maxLen = Math.max(maxLen, getExplicitCellHeight(gridUnits[i]));
  +                    //maxLen = Math.max(maxLen, getExplicitCellHeight(gridUnits[i]));
                   }
               }
               
  @@ -602,7 +811,8 @@
                                   + start[i] + "-" + end[i]);
                       }
                       addAreasForCell(gridUnits[i], start[i], end[i], 
  -                            layoutContext, lastRow, yoffset, partLength[i], maxLen);
  +                            layoutContext, lastRow, yoffset, 
  +                            partLength[i], lastRow.getHeight().opt);
                       gridUnits[i] = null;
                       start[i] = 0;
                       end[i] = 0;
  @@ -615,7 +825,8 @@
           }
   
       }
  -    
  +
  +    /*
       private int getExplicitCellHeight(PrimaryGridUnit pgu) {
           int len = 0;
           if (!pgu.getCell().getBlockProgressionDimension().getOptimum().isAuto()) {
  @@ -628,7 +839,7 @@
                       .getOptimum().getLength().getValue());
           }
           return len;
  -    }
  +    }*/
       
       private void addAreasForCell(PrimaryGridUnit gu, int start, int end, 
               LayoutContext layoutContext, TableRowIterator.EffRow row, 
  @@ -772,5 +983,15 @@
               return sb.toString();
           }
       }
  +    
  +    private class KnuthBoxCellWithBPD extends KnuthBox {
  +        
  +        private PrimaryGridUnit pgu;
  +        
  +        public KnuthBoxCellWithBPD(int w, PrimaryGridUnit pgu) {
  +            super(w, null, true);
  +            this.pgu = pgu;
  +        }
  +}
   
   }
  
  
  
  1.1.2.3   +92 -1     xml-fop/src/java/org/apache/fop/layoutmgr/table/Attic/PrimaryGridUnit.java
  
  Index: PrimaryGridUnit.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/table/Attic/PrimaryGridUnit.java,v
  retrieving revision 1.1.2.2
  retrieving revision 1.1.2.3
  diff -u -r1.1.2.2 -r1.1.2.3
  --- PrimaryGridUnit.java	7 Apr 2005 07:09:24 -0000	1.1.2.2
  +++ PrimaryGridUnit.java	4 May 2005 07:18:13 -0000	1.1.2.3
  @@ -23,6 +23,7 @@
   
   import org.apache.fop.fo.flow.TableCell;
   import org.apache.fop.fo.flow.TableColumn;
  +import org.apache.fop.fo.properties.LengthRangeProperty;
   
   /**
    * This class represents a primary grid unit of a spanned cell.
  @@ -37,6 +38,8 @@
       private int startRow;
       /** Links to the spanned grid units. (List of GridUnit arrays, one array represents a row) */ 
       private List rows;
  +    /** The calculated size of the cell's content. (cached value) */
  +    private int contentLength = -1;
       
       public PrimaryGridUnit(TableCell cell, TableColumn column, int startCol, int startRow) {
           super(cell, column, startCol, 0);
  @@ -62,6 +65,94 @@
           return this.elements;
       }
       
  +    /** 
  +     * @return Returns the half the maximum before border width of this cell.
  +     */
  +    public int getHalfMaxBeforeBorderWidth() {
  +        int value = 0;
  +        if (getRows() != null) {
  +            int before = 0;
  +            //first row for before borders
  +            GridUnit[] row = (GridUnit[])getRows().get(0);
  +            for (int i = 0; i < row.length; i++) {
  +                if (row[i].hasBorders()) {
  +                    before = Math.max(before, 
  +                            row[i].getBorders().getBorderBeforeWidth(false));
  +                }
  +            }
  +            value += before / 2;
  +        } else {
  +            if (hasBorders()) {
  +                value += getBorders().getBorderBeforeWidth(false) / 2;
  +            }
  +        }
  +        return value;
  +    }
  +    
  +    /** 
  +     * @return Returns the sum of half the maximum before and after border 
  +     * widths of this cell.
  +     */
  +    public int getHalfMaxBorderWidth() {
  +        int value = getHalfMaxBeforeBorderWidth();
  +        if (getRows() != null) {
  +            //Last row for after borders
  +            int after = 0;
  +            GridUnit[] row = (GridUnit[])getRows().get(getRows().size() - 1);
  +            for (int i = 0; i < row.length; i++) {
  +                if (row[i].hasBorders()) {
  +                    after = Math.max(after, row[i].getBorders().getBorderAfterWidth(false));
  +                }
  +            }
  +            value += after / 2;
  +        } else {
  +            if (hasBorders()) {
  +                value += getBorders().getBorderAfterWidth(false) / 2;
  +            }
  +        }
  +        return value;
  +    }
  +    
  +    /** @param value The length of the cell content to remember. */
  +    public void setContentLength(int value) {
  +        this.contentLength = value;
  +    }
  +    
  +    /** @return Returns the length of the cell content. */
  +    public int getContentLength() {
  +        return contentLength;
  +    }
  +
  +    /** 
  +     * @return Returns the length of the cell content after the bpd/height attributes on cell
  +     * and row have been taken into account.
  +     */
  +    public int getEffectiveContentLength() {
  +        int value = getContentLength();
  +        if (!getCell().getBlockProgressionDimension().getMinimum().isAuto()) {
  +            value = Math.max(value, 
  +                    getCell().getBlockProgressionDimension().getMinimum().getLength().getValue());
  +        }
  +        if (getRow() != null 
  +                && !getRow().getBlockProgressionDimension().getMinimum().isAuto()) {
  +            value = Math.max(value, 
  +                    getRow().getBlockProgressionDimension().getMinimum().getLength().getValue());
  +        }
  +        return value;
  +    }
  +    
  +    /** @return true if cell/row has an explicit BPD/height */
  +    public boolean hasBPD() {
  +        if (!getCell().getBlockProgressionDimension().getOptimum().isAuto()) {
  +            return true;
  +        }
  +        if (getRow() != null 
  +                && !getRow().getBlockProgressionDimension().getOptimum().isAuto()) {
  +            return true;
  +        }
  +        return false;
  +    }
  +
       public List getRows() {
           return this.rows;
       }
  
  
  
  1.1.2.3   +16 -22    xml-fop/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModelEyeCatching.java
  
  Index: CollapsingBorderModelEyeCatching.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModelEyeCatching.java,v
  retrieving revision 1.1.2.2
  retrieving revision 1.1.2.3
  diff -u -r1.1.2.2 -r1.1.2.3
  --- CollapsingBorderModelEyeCatching.java	7 Apr 2005 07:09:24 -0000	1.1.2.2
  +++ CollapsingBorderModelEyeCatching.java	4 May 2005 07:18:13 -0000	1.1.2.3
  @@ -24,7 +24,6 @@
   import org.apache.fop.fo.flow.TableCell;
   import org.apache.fop.fo.flow.TableColumn;
   import org.apache.fop.fo.flow.TableRow;
  -import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
   import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo;
   
   /**
  @@ -34,11 +33,6 @@
    */
   public class CollapsingBorderModelEyeCatching extends CollapsingBorderModel {
   
  -    private static final int BEFORE = CommonBorderPaddingBackground.BEFORE;
  -    private static final int AFTER = CommonBorderPaddingBackground.AFTER;
  -    private static final int START = CommonBorderPaddingBackground.START;
  -    private static final int END = CommonBorderPaddingBackground.END;
  -    
       public BorderInfo determineWinner(GridUnit currentGridUnit, 
               GridUnit otherGridUnit, int side, int flags) {
           final boolean vertical = isVerticalRelation(side);
  @@ -109,8 +103,9 @@
               //row group (=body, table-header or table-footer)
               current[2] = currentBody.getCommonBorderPaddingBackground().getBorderInfo(side);
           }
  -        if ((otherSide == BEFORE && otherGridUnit.getFlag(GridUnit.FIRST_IN_BODY))
  -                || (otherSide == AFTER && otherGridUnit.getFlag(GridUnit.LAST_IN_BODY))) {
  +        if (otherGridUnit != null
  +                && ((otherSide == BEFORE && otherGridUnit.getFlag(GridUnit.FIRST_IN_BODY))
  +                    || (otherSide == AFTER && otherGridUnit.getFlag(GridUnit.LAST_IN_BODY)))) {
               //row group (=body, table-header or table-footer)
               other[2] = otherBody.getCommonBorderPaddingBackground().getBorderInfo(otherSide);
           }
  @@ -126,7 +121,11 @@
               other[3] = otherColumn.getCommonBorderPaddingBackground().getBorderInfo(otherSide);
           }
           //TODO current[4] and other[4] for column groups
  -        if (otherGridUnit == null) {
  +        if (otherGridUnit == null
  +            && ((side == BEFORE && (flags & VERTICAL_START_END_OF_TABLE) > 0)
  +                    || (side == AFTER && (flags & VERTICAL_START_END_OF_TABLE) > 0)
  +                    || (side == START)
  +                    || (side == END))) {
               //table
               current[5] = table.getCommonBorderPaddingBackground().getBorderInfo(side);
           }
  @@ -142,7 +141,6 @@
           
           // *** Rule 2 ***
           if (!doRule2(current, other)) {
  -            return null; //paint no border
           }
           
           // *** Rule 3 ***
  @@ -167,7 +165,7 @@
       }
   
       private BorderInfo doRule1(BorderInfo[] current, BorderInfo[] other) {
  -        for (int i = 0; i < current.length - 1; i++) {
  +        for (int i = 0; i < current.length; i++) {
               if ((current[i] != null) && (current[i].getStyle() == Constants.EN_HIDDEN)) {
                   return current[i];
               }
  @@ -180,7 +178,7 @@
       
       private boolean doRule2(BorderInfo[] current, BorderInfo[] other) {
           boolean found = false;
  -        for (int i = 0; i < current.length - 1; i++) {
  +        for (int i = 0; i < current.length; i++) {
               if ((current[i] != null) && (current[i].getStyle() != Constants.EN_NONE)) {
                   found = true;
                   break;
  @@ -196,7 +194,7 @@
       private BorderInfo doRule3(BorderInfo[] current, BorderInfo[] other) {
           int width = 0;
           //Find max border width
  -        for (int i = 0; i < current.length - 1; i++) {
  +        for (int i = 0; i < current.length; i++) {
               if ((current[i] != null) && (current[i].getRetainedWidth() > width)) {
                   width = current[i].getRetainedWidth();
               }
  @@ -207,13 +205,12 @@
           BorderInfo widest = null;
           int count = 0;
           //See if there's only one with the widest border
  -        for (int i = 0; i < current.length - 1; i++) {
  +        for (int i = 0; i < current.length; i++) {
               if ((current[i] != null) && (current[i].getRetainedWidth() == width)) {
                   count++;
                   if (widest == null) {
                       widest = current[i];
                   }
  -                break;
               } else {
                   current[i] = null; //Discard the narrower ones
               }
  @@ -222,7 +219,6 @@
                   if (widest == null) {
                       widest = other[i];
                   }
  -                break;
               } else {
                   other[i] = null; //Discard the narrower ones
               }
  @@ -237,26 +233,24 @@
       private BorderInfo doRule4(BorderInfo[] current, BorderInfo[] other) {
           int pref = getPreferenceValue(Constants.EN_INSET); //Lowest preference
           //Find highest preference value
  -        for (int i = 0; i < current.length - 1; i++) {
  +        for (int i = 0; i < current.length; i++) {
               if (current[i] != null) {
                   int currPref = getPreferenceValue(current[i].getStyle());
                   if (currPref > pref) {
                       pref = currPref;
  -                    break;
                   }
               }
               if (other[i] != null) {
                   int currPref = getPreferenceValue(other[i].getStyle());
                   if (currPref > pref) {
                       pref = currPref;
  -                    break;
                   }
               }
           }
           BorderInfo preferred = null;
           int count = 0;
           //See if there's only one with the preferred border style
  -        for (int i = 0; i < current.length - 1; i++) {
  +        for (int i = 0; i < current.length; i++) {
               if (current[i] != null) {
                   int currPref = getPreferenceValue(current[i].getStyle());
                   if (currPref == pref) {
  @@ -290,7 +284,7 @@
       }
   
       private BorderInfo doRule5(BorderInfo[] current, BorderInfo[] other) {
  -        for (int i = 0; i < current.length - 1; i++) {
  +        for (int i = 0; i < current.length; i++) {
               if (current[i] != null) {
                   return current[i];
               }
  
  
  
  No                   revision
  No                   revision
  1.1.2.1   +31 -1     xml-fop/src/java/org/apache/fop/layoutmgr/MinOptMaxUtil.java
  
  Index: MinOptMaxUtil.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/MinOptMaxUtil.java,v
  retrieving revision 1.1
  retrieving revision 1.1.2.1
  diff -u -r1.1 -r1.1.2.1
  --- MinOptMaxUtil.java	7 Feb 2005 11:01:36 -0000	1.1
  +++ MinOptMaxUtil.java	4 May 2005 07:18:13 -0000	1.1.2.1
  @@ -63,6 +63,19 @@
           }
       }
   
  +    public static void extendMinimum(MinOptMax mom, int len, boolean optToLen) {
  +        System.out.print("before: " + mom);
  +        if (mom.min < len) {
  +            mom.min = len;
  +            mom.opt = Math.max(mom.min, mom.opt);
  +            if (optToLen) {
  +                mom.opt = Math.min(mom.min, len);
  +            }
  +            mom.max = Math.max(mom.opt, mom.max);
  +        }
  +        System.out.println(" - after: " + mom);
  +    }
  +    
       /**
        * After a calculation on a MinOptMax, this can be called to set opt to
        * a new effective value.
  @@ -77,4 +90,21 @@
           }
       }
       
  +    /**
  +     * Converts a LengthRangeProperty to a MinOptMax.
  +     * @param prop LengthRangeProperty
  +     * @return the requested MinOptMax instance
  +     */
  +    public static MinOptMax toMinOptMax(LengthRangeProperty prop) {
  +        MinOptMax mom = new MinOptMax(
  +                (prop.getMinimum().isAuto() 
  +                        ? 0 : prop.getMinimum().getLength().getValue()),
  +                (prop.getOptimum().isAuto() 
  +                        ? 0 : prop.getOptimum().getLength().getValue()),
  +                (prop.getMinimum().isAuto() 
  +                        ? Integer.MAX_VALUE 
  +                        : prop.getMaximum().getLength().getValue()));
  +        return mom;
  +    }
  +    
   }
  
  
  

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