gt:                         	if (ch > maxh) maxh = ch;
context: /**
   * TableBodyBox.java
   * Copyright (c) 2005-2007 Radek Burget
   *
   * CSSBox is free software: you can redistribute it and/or modify
   * it under the terms of the GNU Lesser General Public License as published by
   * the Free Software Foundation, either version 3 of the License, or
   * (at your option) any later version.
   *  
   * CSSBox is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   * GNU Lesser General Public License for more details.
   *  
   * You should have received a copy of the GNU Lesser General Public License
   * along with CSSBox. If not, see <http://www.gnu.org/licenses/>.
   *
   * Created on 29.9.2006, 14:13:58 by burgetr
   */
  package org.fit.cssbox.layout;
  
  import java.util.Iterator;
  import java.util.Vector;
  
  import org.w3c.dom.Element;
  
  /**
   * A class that represents a group of table lines - the table body, header or footer.
   * @author burgetr
   */
  public class TableBodyBox extends BlockBox
  {
      /** The table the body belongs to */
      protected TableBox ownerTable;
      /** The row boxes contained inside */
      protected Vector<TableRowBox> rows;
      /** Number of columns inside */
      protected int numCols;
      /** array of cells */
      protected TableCellBox[][] cells;
      /** cell spacing */
      protected float spacing = 2;
      
      //====================================================================================
      
      /**
       * Create a new table body
       */
      public TableBodyBox(Element n, VisualContext ctx)
      {
          super(n, ctx);
          isblock = true;
          rows = new Vector<TableRowBox>();
      }
  
      /**
       * Create a new table body from an inline box
       */
      public TableBodyBox(InlineBox src)
      {
          super(src);
          isblock = true;
          rows = new Vector<TableRowBox>();
      }
      
      @Override
      public boolean rendersBackground()
      {
          //table body cannot have borders
          //the background is drawn in the individual cells
          return false;
      }
      
      /**
       * Add a new row to the table body.
       * @param row the new row
       */
      public void addRow(TableRowBox row)
      {
          rows.add(row);
          row.setOwnerBody(this);
      }
      
      /**
       * @return the number of rows in the body
       */
      public int getRowCount()
      {
          return rows.size();
      }
      
      /**
       * @return the number of columns in the body (the longest row)
       */
      public int getColumnCount()
      {
          return numCols;
      }
      
      /**
       * Returns a particular row by index.
       * @param index row index
       * @return the row
       */
      public TableRowBox getRow(int index)
      {
          return rows.elementAt(index);
      }
  
      /**
       * Sets the cell spacing
       */
      public void setSpacing(float spacing)
      {
      	this.spacing = spacing;
      }
      
      /**
       * @return the table where the caption is placed
       */
      public TableBox getOwnerTable()
      {
          return ownerTable;
      }
  
      /**
       * Sets the table where the caption belongs to.
       * @param ownerTable the table to set
       */
      public void setOwnerTable(TableBox ownerTable)
      {
          this.ownerTable = ownerTable;
      }
      
      //====================================================================================
      
      @Override
      public float getMaximalWidth()
      {
          float sum = spacing;
          for (int i = 0; i < numCols; i++)
              sum += getMaximalColumnWidth(i) + spacing;
          return sum;
      }
  
      @Override
      public float getMinimalWidth()
      {
          float sum = spacing;
          for (int i = 0; i < numCols; i++)
              sum += getMinimalColumnWidth(i) + spacing;
          return sum;
      }
      
      /**
       * Determine the minimal width of the column
       * @param col the column index
       * @return the minimal width of the column
       */ 
      public float getMinimalColumnWidth(int col)
      {
          float ret = 0;
          int r = 0;
          while (r < getRowCount())
          {
              TableCellBox cell = cells[col][r];
              if (cell != null)
              {
                  float min = cell.getMinimalWidth() / cell.getColspan();
                  if (min > ret) ret = min;
                  r += cell.getRowspan();
              }
              else
                  r++;
          }
          return ret;
      }
  
      /**
       * Determine the maximal width of the column
       * @param col the column index
       * @return the minimal width of the column
       */ 
      public float getMaximalColumnWidth(int col)
      {
          float ret = 0;
          int r = 0;
          while (r < getRowCount())
          {
              TableCellBox cell = cells[col][r];
              if (cell != null)
              {
                  float max = cell.getMaximalWidth() / cell.getColspan();
                  if (max > ret) ret = max;
                  r += cell.getRowspan();
              }
              else
                  r++;
          }
          return ret;
      }
      
      /**
       * Checks the maximal and minimal width of the column, if the column has fixed width 
       * and if it is relative. Updates the appropriate information in the TableColumn 
       * structure.
       * @param c the column index
       * @param col the column to be updated
       */ 
      public void updateColumn(int c, TableColumn col)
      {
          int r = 0;
          while (r < getRowCount())
          {
              TableCellBox cell = cells[c][r];
              if (cell != null)
              {
              	cell.setOwnerColumn(col);
                  //minimal width
                  float min = cell.getMinimalWidth() / cell.getColspan();
                  if (min > col.getMinimalWidth())
                      col.setMinimalWidth(min);
                  //maximal width
                  float max = cell.getMaximalWidth() / cell.getColspan();
                  if (max > col.getMaximalWidth())
                      col.setMaximalWidth(max);
                  //fixed width and percentages
                  if (cell.wset) 
                  {
                      col.wset = true;
                      if (cell.isRelative())
                      {
                          col.setRelative(true);
                          if (col.percent < cell.percent)
                              col.percent = cell.percent;
                      }
                      else
                      {
                          if (cell.getContentWidth() > col.abswidth)
                              col.abswidth = cell.getContentWidth();
                      }
                  }
                  //ensure the minimal width
                  if (col.getWidth() < col.getMinimalWidth())
                      col.setColumnWidth(col.getMinimalWidth());
                  r += cell.getRowspan();
              }
              else
                  r++;
          }
      }
      
      //====================================================================================
      
      @Override
      public void initBox()
      {
          organizeContent();
          calcOffsets();
      }
      
      @Override
      public boolean doLayout(float widthlimit, boolean force, boolean linestart)
      {
          return true;
      }
      
      public boolean doLayout(float widthlimit, Vector<TableColumn> columns)
      {
          setAvailableWidth(widthlimit);
  
          float y = spacing;
          float x = spacing;
          float maxw = 0;
          float maxh = 0;
          float wlimit = getAvailableContentWidth();
          
          /*System.out.println("Table body " + getColumnCount() + "x" + getRowCount());
          for (int r = 0; r < rows.size(); r++)
          {
              for (int c = 0; c < numCols; c++)
                  System.out.print("| " + cells[c][r]);
              System.out.println(" |");
          }*/
  
          float rowY[] = new float[getRowCount()]; //Y offests of the rows
          
          for (int r = 0; r < getRowCount(); r++)
          {
              TableRowBox row = getRow(r);
              
              x = spacing;
              maxh = 0;
              int c = 0;
              while (c < getColumnCount())
              {
                  TableCellBox cell = cells[c][r];
                  if (cell != null)
                  {
                      int firstrow = cell.getRow();
                      int lastrow = cell.getRow() + cell.getRowspan() - 1;
                      //compute cell width according to span
                      float cw = columns.elementAt(c).getWidth();
                      for (int i = 1; i < cell.getColspan(); i++)
                          cw += spacing + columns.elementAt(c+i).getWidth();
                      cell.setWidth(cw);
                      //compute the position
                      if (r == firstrow)
                      {
                          cell.doLayout(wlimit, true, true);
                          cell.setPosition(x, 0);
                          //int ch = cell.getHeight() / cell.getRowspan();
                          if (cell.getRowspan() == 1)
                          {
                          	float ch = cell.getHeight();
                          	if (ch > maxh) maxh = ch;
                          }
                      }
                      else if (r < lastrow)
                      {
                          //int ch = cell.getHeight() / cell.getRowspan();
                          if (cell.getRowspan() == 1)
                          {
                          	float ch = cell.getHeight();
  