jeremias    2005/02/08 08:25:13

  Modified:    src/java/org/apache/fop/layoutmgr/table Row.java Cell.java
  Log:
  Support for column-number on table-cell.
  RowLM now also handles gaps (=empty cells) properly.
  Positioning of cells inside the row changed. More responsibility into 
getNextBreakPoss stage because it is a lot easier to implement and there's less 
redundancy.
  
  Revision  Changes    Path
  1.20      +177 -66   xml-fop/src/java/org/apache/fop/layoutmgr/table/Row.java
  
  Index: Row.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/table/Row.java,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- Row.java  8 Feb 2005 11:21:57 -0000       1.19
  +++ Row.java  8 Feb 2005 16:25:12 -0000       1.20
  @@ -20,6 +20,7 @@
   
   import org.apache.fop.fo.FONode;
   import org.apache.fop.fo.flow.Table;
  +import org.apache.fop.fo.flow.TableCell;
   import org.apache.fop.fo.flow.TableRow;
   import org.apache.fop.fo.properties.LengthRangeProperty;
   import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
  @@ -40,6 +41,7 @@
   import java.util.Iterator;
   import java.util.ArrayList;
   import java.util.List;
  +import java.util.ListIterator;
   
   /**
    * LayoutManager for a table-row FO.
  @@ -49,6 +51,14 @@
    * but effect the occupied columns of future rows.
    */
   public class Row extends BlockStackingLayoutManager {
  +    
  +    /** Used by CellInfo: Indicates start of cell. */
  +    public static final int CI_START_OF_CELL = 0;
  +    /** Used by CellInfo: Indicates part of a spanned cell in column 
direction. */
  +    public static final int CI_COL_SPAN      = 1;
  +    /** Used by CellInfo: Indicates part of a spanned cell in row direction. 
*/
  +    public static final int CI_ROW_SPAN      = 2;
  +    
       private TableRow fobj;
       
       private List cellList = null;
  @@ -96,30 +106,77 @@
       }
   
       private void setupCells() {
  -        cellList = new ArrayList();
  +        cellList = new java.util.ArrayList();
  +        List availableCells = new java.util.ArrayList();
           // add cells to list
           while (childLMiter.hasNext()) {
               curChildLM = (LayoutManager) childLMiter.next();
               curChildLM.setParent(this);
               curChildLM.initialize();
  -            cellList.add(curChildLM);
  +            availableCells.add(curChildLM);
  +        }
  +        
  +        //Transfer available cells to their slots
  +        int colnum = 1;
  +        ListIterator iter = availableCells.listIterator();
  +        while (iter.hasNext()) {
  +            Cell cellLM = (Cell)iter.next();
  +            TableCell cell = cellLM.getFObj();
  +            if (cell.hasColumnNumber()) {
  +                colnum = cell.getColumnNumber();
  +            }
  +            while (colnum > cellList.size()) {
  +                cellList.add(null);
  +            }
  +            if (cellList.get(colnum - 1) != null) {
  +                log.error("Overlapping cell at position " + colnum);
  +            }
  +            //Add cell info for primary slot
  +            cellList.set(colnum - 1, new CellInfo(cellLM));
  +            
  +            //Add cell infos on spanned slots if any
  +            for (int j = 1; j < cell.getNumberColumnsSpanned(); j++) {
  +                colnum++;
  +                if (colnum > cellList.size()) {
  +                    cellList.add(new CellInfo(CI_COL_SPAN));
  +                } else {
  +                    if (cellList.get(colnum - 1) != null) {
  +                        log.error("Overlapping cell at position " + colnum);
  +                    }
  +                    cellList.set(colnum - 1, new CellInfo(CI_COL_SPAN));
  +                }
  +            }
  +            colnum++;
  +        }
  +        
  +        //Post-processing the list (looking for gaps)
  +        int pos = 1;
  +        ListIterator ppIter = cellList.listIterator();
  +        while (ppIter.hasNext()) {
  +            CellInfo cellInfo = (CellInfo)ppIter.next();
  +            if (cellInfo == null) {
  +                //Add cell info on empty cell
  +                ppIter.set(new CellInfo(CI_START_OF_CELL));
  +            }
  +            pos++;
           }
       }
   
       /**
  -     * Get the layout manager for a cell.
  +     * Get the cell info for a cell.
        *
  -     * @param pos the position of the cell
  -     * @return the cell layout manager
  +     * @param pos the position of the cell (must be >= 1)
  +     * @return the cell info object
        */
  -    protected Cell getCellLM(int pos) {
  +    protected CellInfo getCellInfo(int pos) {
           if (cellList == null) {
               setupCells();
           }
  -        if (pos < cellList.size()) {
  -            return (Cell)cellList.get(pos);
  +        if (pos <= cellList.size()) {
  +            return (CellInfo)cellList.get(pos - 1);
  +        } else {
  +            return null;
           }
  -        return null;
       }
   
       /**
  @@ -131,7 +188,8 @@
        * @return the next break possibility
        */
       public BreakPoss getNextBreakPoss(LayoutContext context) {
  -        LayoutManager curLM; // currently active LM
  +        //LayoutManager curLM; // currently active LM
  +        CellInfo curCellInfo; //currently active cell info
   
           BreakPoss lastPos = null;
           List breakList = new java.util.ArrayList();
  @@ -141,12 +199,19 @@
           int opt = 0;
           int max = 0;
   
  +        // This is used for the displacement of the individual cells
  +        int ipdOffset = 0;
  +        
           int startColumn = 1;
  -        int cellLMIndex = 0;
           boolean over = false;
   
  -        while ((curLM = getCellLM(cellLMIndex++)) != null) {
  -            Cell cellLM = (Cell)curLM;
  +        while ((curCellInfo = getCellInfo(startColumn)) != null) {
  +            Cell cellLM = curCellInfo.layoutManager;
  +            if (curCellInfo.isColSpan()) {
  +                //skip spanned slots
  +                startColumn++;
  +                continue;
  +            }
               
               List childBreaks = new ArrayList();
               MinOptMax stackSize = new MinOptMax();
  @@ -161,6 +226,7 @@
                     MinOptMax.subtract(context.getStackLimit(),
                                        stackSize));
   
  +            //Determine which columns this cell will occupy
               getColumnsForCell(cellLM, startColumn, spannedColumns);
               int childRefIPD = 0;
               Iterator i = spannedColumns.iterator();
  @@ -175,35 +241,52 @@
               }
               childLC.setRefIPD(childRefIPD);
   
  -            while (!curLM.isFinished()) {
  -                if ((bp = curLM.getNextBreakPoss(childLC)) != null) {
  -                    if (stackSize.opt + bp.getStackingSize().opt > 
context.getStackLimit().max) {
  -                        // reset to last break
  -                        if (lastPos != null) {
  -                            LayoutManager lm = lastPos.getLayoutManager();
  -                            lm.resetPosition(lastPos.getPosition());
  -                            if (lm != curLM) {
  -                                curLM.resetPosition(null);
  +            if (cellLM != null) {
  +                cellLM.setInRowIPDOffset(ipdOffset);
  +                while (!cellLM.isFinished()) {
  +                    if ((bp = cellLM.getNextBreakPoss(childLC)) != null) {
  +                        if (stackSize.opt + bp.getStackingSize().opt > 
context.getStackLimit().max) {
  +                            // reset to last break
  +                            if (lastPos != null) {
  +                                LayoutManager lm = 
lastPos.getLayoutManager();
  +                                lm.resetPosition(lastPos.getPosition());
  +                                if (lm != cellLM) {
  +                                    cellLM.resetPosition(null);
  +                                }
  +                            } else {
  +                                cellLM.resetPosition(null);
                               }
  -                        } else {
  -                            curLM.resetPosition(null);
  +                            over = true;
  +                            break;
  +                        }
  +                        stackSize.add(bp.getStackingSize());
  +                        lastPos = bp;
  +                        childBreaks.add(bp);
  +
  +                        if (bp.nextBreakOverflows()) {
  +                            over = true;
  +                            break;
                           }
  -                        over = true;
  -                        break;
  -                    }
  -                    stackSize.add(bp.getStackingSize());
  -                    lastPos = bp;
  -                    childBreaks.add(bp);
  -
  -                    if (bp.nextBreakOverflows()) {
  -                        over = true;
  -                        break;
  -                    }
   
  -                    childLC.setStackLimit(MinOptMax.subtract(
  -                                             context.getStackLimit(), 
stackSize));
  +                        childLC.setStackLimit(MinOptMax.subtract(
  +                                                 context.getStackLimit(), 
stackSize));
  +                    }
                   }
  +                startColumn += cellLM.getFObj().getNumberColumnsSpanned();
  +            } else {
  +                //Skipping empty cells
  +                //log.debug("empty cell at pos " + startColumn);
  +                startColumn++;
               }
  +            
  +            //Adjust in-row x offset for individual cells
  +            //TODO Probably needs more work to support writing modes
  +            ipdOffset += childRefIPD;
  +            if (getTable().getBorderCollapse() == EN_SEPARATE) {
  +                ipdOffset += 
getTable().getBorderSeparation().getIPD().getLength().getValue();
  +            }
  +            
  +            
               // the min is the maximum min of all cells
               if (stackSize.min > min) {
                   min = stackSize.min;
  @@ -217,9 +300,9 @@
                   max = stackSize.max;
               }
   
  -            breakList.add(childBreaks);
  -            
  -            startColumn += cellLM.getFObj().getNumberColumnsSpanned();
  +            if (childBreaks.size() > 0) {
  +                breakList.add(childBreaks);
  +            }
           }
           MinOptMax rowSize = new MinOptMax(min, opt, max);
           LengthRangeProperty specifiedBPD = 
fobj.getBlockProgressionDimension();
  @@ -234,13 +317,20 @@
           rowHeight = rowSize.opt;
   
           boolean fin = true;
  -        cellLMIndex = 0;
  +        startColumn = 1;
           //Check if any of the cell LMs haven't finished, yet
  -        while ((curLM = getCellLM(cellLMIndex++)) != null) {
  -            if (!curLM.isFinished()) {
  +        while ((curCellInfo = getCellInfo(startColumn)) != null) {
  +            Cell cellLM = curCellInfo.layoutManager;
  +            if (cellLM == null) {
  +                //skip empty cell
  +                startColumn++;
  +                continue;
  +            }
  +            if (!cellLM.isFinished()) {
                   fin = false;
                   break;
               }
  +            startColumn += cellLM.getFObj().getNumberColumnsSpanned();
           }
   
           setFinished(fin);
  @@ -274,7 +364,12 @@
        * @param spannedColumns List to receive the applicable columns
        */
       private void getColumnsForCell(Cell cellLM, int startCell, List 
spannedColumns) {
  -        int count = cellLM.getFObj().getNumberColumnsSpanned();
  +        int count;
  +        if (cellLM != null) {
  +            count = cellLM.getFObj().getNumberColumnsSpanned();
  +        } else {
  +            count = 1;
  +        }
           spannedColumns.clear();
           for (int i = 0; i < count; i++) {
               spannedColumns.add(getColumn(startCell + i));
  @@ -290,22 +385,28 @@
        * If pos is null, then back up to the first child LM.
        */
       protected void reset(Position pos) {
  -        LayoutManager curLM; // currently active LM
  -        int cellcount = 0;
  +        //LayoutManager curLM; // currently active LM
  +        CellInfo curCellInfo;
  +        int cellIndex = 0;
   
           if (pos == null) {
  -            while ((curLM = getCellLM(cellcount)) != null) {
  -                curLM.resetPosition(null);
  -                cellcount++;
  +            while ((curCellInfo = getCellInfo(cellIndex)) != null) {
  +                if (curCellInfo.layoutManager != null) {
  +                    curCellInfo.layoutManager.resetPosition(null);
  +                }
  +                cellIndex++;
               }
           } else {
               RowPosition rpos = (RowPosition)pos;
               List breaks = rpos.cellBreaks;
   
  -            while ((curLM = getCellLM(cellcount)) != null) {
  -                List childbreaks = (List)breaks.get(cellcount);
  -                
curLM.resetPosition((Position)childbreaks.get(childbreaks.size() - 1));
  -                cellcount++;
  +            while ((curCellInfo = getCellInfo(cellIndex)) != null) {
  +                if (curCellInfo.layoutManager != null) {
  +                    List childbreaks = (List)breaks.get(cellIndex);
  +                    curCellInfo.layoutManager.resetPosition(
  +                            (Position)childbreaks.get(childbreaks.size() - 
1));
  +                }
  +                cellIndex++;
               }
           }
   
  @@ -364,30 +465,18 @@
                   parentLM.addChild(rowArea);
               }
   
  -            int cellcount = 0;
  -            int x = this.xoffset;
  -            //int x = (TableLayoutManager)getParent()).;
               for (Iterator iter = lfp.cellBreaks.iterator(); iter.hasNext();) 
{
                   List cellsbr = (List)iter.next();
                   BreakPossPosIter breakPosIter;
                   breakPosIter = new BreakPossPosIter(cellsbr, 0, 
cellsbr.size());
                   iStartPos = lfp.getLeafPos() + 1;
   
  -                int cellWidth = 0;
                   while ((childLM = (Cell)breakPosIter.getNextChildLM()) != 
null) {
  -                    cellWidth = childLM.getReferenceIPD();
  -                    childLM.setXOffset(x);
  +                    childLM.setXOffset(xoffset);
                       childLM.setYOffset(yoffset);
                       childLM.setRowHeight(rowHeight);
                       childLM.addAreas(breakPosIter, lc);
                   }
  -                x += cellWidth;
  -                
  -                //Handle border-separation
  -                Table table = getTable();
  -                if (table.getBorderCollapse() == EN_SEPARATE) {
  -                    x += 
table.getBorderSeparation().getIPD().getLength().getValue();
  -                }
               }
           }
   
  @@ -461,5 +550,27 @@
           }
       }
   
  +    private class CellInfo {
  +        
  +        /** layout manager for this cell, may be null */
  +        public Cell layoutManager;
  +        /** flags for this cell, on of Row.CI_* */
  +        public int flags = CI_START_OF_CELL;
  +        
  +        public CellInfo(Cell layoutManager) {
  +            this.layoutManager = layoutManager;
  +        }
  +        
  +        public CellInfo(int flags) {
  +            this.flags = flags;
  +        }
  +        
  +        /** @return true if the cell is part of a span in column direction */
  +        public boolean isColSpan() {
  +            return (flags & CI_COL_SPAN) != 0;
  +        }
  +
  +    }
  +    
   }
   
  
  
  
  1.17      +15 -10    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.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- Cell.java 8 Feb 2005 11:21:57 -0000       1.16
  +++ Cell.java 8 Feb 2005 16:25:12 -0000       1.17
  @@ -50,6 +50,8 @@
   
       private List childBreaks = new ArrayList();
   
  +    private int inRowIPDOffset;
  +    
       private int xoffset;
       private int yoffset;
       private int referenceIPD;
  @@ -72,11 +74,6 @@
           return this.fobj;
       }
       
  -    /** @return this cell's reference IPD */
  -    public int getReferenceIPD() {
  -        return this.referenceIPD;
  -    }
  -    
       private int getIPIndents() {
           int iIndents = 0;
           iIndents += 
fobj.getCommonBorderPaddingBackground().getIPPaddingAndBorder(false);
  @@ -188,8 +185,8 @@
       }
   
       /**
  -     * Set the x offset of this cell.
  -     * This offset is used to set the absolute position of the cell.
  +     * Set the x offset of this cell (usually the same as its parent row).
  +     * This offset is used to determine the absolute position of the cell.
        *
        * @param off the x offset
        */
  @@ -198,6 +195,15 @@
       }
   
       /**
  +     * Set the IPD offset of this cell inside the table-row.
  +     * This offset is used to determine the absolute position of the cell.
  +     * @param off the IPD offset
  +     */
  +    public void setInRowIPDOffset(int off) {
  +        this.inRowIPDOffset = off;
  +    }
  +    
  +    /**
        * Set the row height that contains this cell. This method is used during
        * addAreas() stage.
        *
  @@ -285,7 +291,8 @@
               curBlockArea.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE);
               curBlockArea.setPositioning(Block.ABSOLUTE);
               // set position
  -            int x = xoffset; //mimic start-indent
  +            int x = xoffset + inRowIPDOffset;
  +            //mimic start-indent
               x += 
fobj.getCommonBorderPaddingBackground().getBorderStartWidth(false);
               curBlockArea.setXOffset(x);
               curBlockArea.setYOffset(yoffset);
  @@ -294,8 +301,6 @@
   
               // Set up dimensions
               Area parentArea = parentLM.getParentArea(curBlockArea);
  -            int referenceIPD = parentArea.getIPD();
  -            //curBlockArea.setIPD(referenceIPD);
               // Get reference IPD from parentArea
               setCurrentArea(curBlockArea); // ??? for generic operations
           }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to