use layout grid to render vertical span (almost) correct

Signed-off-by: Florian Thienel <florian@thienel.org>
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableCell.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableCell.java
index bc583ad..1d77585 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableCell.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableCell.java
@@ -26,7 +26,6 @@
 	private int top;
 	private int left;
 	private int width;
-	private int height;
 	private final ArrayList<IStructuralBox> children = new ArrayList<IStructuralBox>();
 
 	private int startColumnIndex;
@@ -39,6 +38,7 @@
 	private GridArea gridArea;
 
 	private int naturalHeight;
+	private int usedHeight;
 
 	@Override
 	public void setParent(final IBox parent) {
@@ -90,11 +90,11 @@
 
 	@Override
 	public int getHeight() {
-		return height;
+		return usedHeight;
 	}
 
-	public void setHeight(final int height) {
-		this.height = height;
+	public void useHeight(final int height) {
+		usedHeight += height;
 	}
 
 	public int getNaturalHeight() {
@@ -103,7 +103,7 @@
 
 	@Override
 	public Rectangle getBounds() {
-		return new Rectangle(left, top, width, height);
+		return new Rectangle(left, top, width, usedHeight);
 	}
 
 	@Override
@@ -221,7 +221,7 @@
 			child.layout(graphics);
 			naturalHeight += child.getHeight();
 		}
-		height = naturalHeight;
+		usedHeight = 0;
 
 		return naturalHeight;
 	}
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableLayoutGrid.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableLayoutGrid.java
index ff07257..632da46 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableLayoutGrid.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableLayoutGrid.java
@@ -56,7 +56,7 @@
 			@Override
 			public Object visit(final TableRow box) {
 				if (box == parent) {
-					layoutGrid.addNextRow();
+					layoutGrid.addNextRow(box);
 					traverseChildren(box);
 				} else {
 					box.setLayoutGrid(layoutGrid);
@@ -84,8 +84,9 @@
 		return maxColumn;
 	}
 
-	public int addNextRow() {
+	public int addNextRow(final TableRow row) {
 		currentRow += 1;
+		row.setRowIndex(currentRow);
 		nextColumn = 1;
 		return currentRow;
 	}
@@ -149,7 +150,7 @@
 		return grid.get(position);
 	}
 
-	public IStructuralBox getRowChild(final GridPosition position, final TableRow parentRow) {
+	public IStructuralBox getRowChild(final GridPosition position) {
 		final TableCell cell = grid.get(position);
 		if (cell == null) {
 			return null;
@@ -217,7 +218,7 @@
 			}
 
 			private IStructuralBox visitStructuralBox(final IStructuralBox box) {
-				if (box.getParent() == parentRow) {
+				if (box.getParent() instanceof TableRow) {
 					return box;
 				}
 				return box.getParent().accept(this);
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableRow.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableRow.java
index 03c7759..2fc3678 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableRow.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableRow.java
@@ -29,6 +29,8 @@
 	private int height;
 	private final ArrayList<IStructuralBox> children = new ArrayList<IStructuralBox>();
 
+	private int rowIndex;
+
 	private TableColumnLayout columnLayout = new TableColumnLayout();
 	private TableLayoutGrid layoutGrid = new TableLayoutGrid();
 
@@ -141,6 +143,14 @@
 		return children;
 	}
 
+	public int getRowIndex() {
+		return rowIndex;
+	}
+
+	public void setRowIndex(final int rowIndex) {
+		this.rowIndex = rowIndex;
+	}
+
 	public TableColumnLayout getColumnLayout() {
 		return columnLayout;
 	}
@@ -169,33 +179,50 @@
 		TableColumnLayout.addColumnLayoutInformationForChildren(graphics, this, columnLayout);
 		TableLayoutGrid.setupLayoutGrid(graphics, this, layoutGrid);
 		int cellHeight = 0;
-		int columnIndex = 1;
-		for (int i = 0; i < children.size(); i += 1) {
-			final IStructuralBox child = children.get(i);
-			final TableCell cell = getContainedTableCell(child);
+
+		for (int column = 1; column <= layoutGrid.getColumns(); column += 1) {
+			final GridPosition position = new GridPosition(rowIndex, column);
+			final TableCell cell = layoutGrid.getCell(position);
+			final IStructuralBox child = layoutGrid.getRowChild(position);
 			if (cell != null) {
-				final int startColumn = getStartColumn(cell, columnIndex);
-				final int endColumn = getEndColumn(cell, startColumn);
+				final GridArea area = cell.getGridArea();
 
-				final int childLeft = getColumnWidth(1, startColumn - 1);
-				final int columnWidth = getColumnWidth(startColumn, endColumn);
+				final int childLeft = getColumnWidth(1, area.startColumn - 1);
+				final int columnWidth = getColumnWidth(area.startColumn, area.endColumn);
 
-				child.setWidth(columnWidth);
-				child.setPosition(0, childLeft);
+				if (column == area.startColumn) {
+					if (rowIndex == area.startRow) {
+						cell.calculateNaturalHeight(graphics, columnWidth);
+					}
+					if (rowIndex == area.endRow) {
+						cellHeight = Math.max(cellHeight, cell.getNaturalHeight() - cell.getHeight());
+					}
+				}
 
-				cellHeight = Math.max(cellHeight, cell.calculateNaturalHeight(graphics, columnWidth));
-				columnIndex = endColumn + 1;
+				if (child != null && child.getParent() == this) {
+					child.setPosition(0, childLeft);
+					child.setWidth(columnWidth);
+				}
 			}
 		}
 
 		height = 0;
-		for (int i = 0; i < children.size(); i += 1) {
-			final IStructuralBox child = children.get(i);
-			final TableCell cell = getContainedTableCell(child);
-			if (cell != null) {
-				cell.setHeight(cellHeight);
-				child.layout(graphics);
-				height = Math.max(height, child.getHeight());
+		for (int column = 1; column <= layoutGrid.getColumns(); column += 1) {
+			final GridPosition position = new GridPosition(rowIndex, column);
+			final TableCell cell = layoutGrid.getCell(position);
+			final IStructuralBox child = layoutGrid.getRowChild(position);
+			if (cell != null && child != null) {
+				final GridArea area = cell.getGridArea();
+				if (column == area.startColumn) {
+					cell.useHeight(cellHeight);
+
+					if (rowIndex == area.endRow) {
+						child.layout(graphics);
+						if (rowIndex == area.startRow) {
+							height = Math.max(height, child.getHeight());
+						}
+					}
+				}
 			}
 		}
 	}
@@ -215,29 +242,6 @@
 		return Math.round(width / columnLayout.getLastIndex());
 	}
 
-	private static TableCell getContainedTableCell(final IStructuralBox parent) {
-		return parent.accept(new TableCellVisitor<TableCell>() {
-			@Override
-			public TableCell visit(final TableCell box) {
-				return box;
-			}
-		});
-	}
-
-	private static int getStartColumn(final TableCell cell, final int defaultColumn) {
-		if (cell == null || cell.getStartColumnIndex() <= defaultColumn) {
-			return defaultColumn;
-		}
-		return cell.getStartColumnIndex();
-	}
-
-	private static int getEndColumn(final TableCell cell, final int defaultColumn) {
-		if (cell == null || cell.getEndColumnIndex() <= defaultColumn) {
-			return defaultColumn;
-		}
-		return cell.getEndColumnIndex();
-	}
-
 	@Override
 	public boolean reconcileLayout(final Graphics graphics) {
 		final int oldHeight = height;
@@ -249,21 +253,4 @@
 	public void paint(final Graphics graphics) {
 		ChildBoxPainter.paint(children, graphics);
 	}
-
-	private static class TableCellVisitor<T> extends DepthFirstBoxTraversal<T> {
-		@Override
-		public final T visit(final Table box) {
-			return null;
-		}
-
-		@Override
-		public final T visit(final TableRowGroup box) {
-			return null;
-		}
-
-		@Override
-		public final T visit(final TableRow box) {
-			return null;
-		}
-	};
 }