diff options
Diffstat (limited to 'src/java/org/apache/fop/fo/flow/table/FixedColRowGroupBuilder.java')
-rw-r--r-- | src/java/org/apache/fop/fo/flow/table/FixedColRowGroupBuilder.java | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/src/java/org/apache/fop/fo/flow/table/FixedColRowGroupBuilder.java b/src/java/org/apache/fop/fo/flow/table/FixedColRowGroupBuilder.java index 22e5c02b8..602ae84a6 100644 --- a/src/java/org/apache/fop/fo/flow/table/FixedColRowGroupBuilder.java +++ b/src/java/org/apache/fop/fo/flow/table/FixedColRowGroupBuilder.java @@ -19,6 +19,15 @@ package org.apache.fop.fo.flow.table; +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; + +import org.apache.fop.fo.ValidationException; +import org.apache.fop.layoutmgr.table.EmptyGridUnit; +import org.apache.fop.layoutmgr.table.GridUnit; +import org.apache.fop.layoutmgr.table.PrimaryGridUnit; + /** * A row group builder optimised for a fixed number of columns, known before the parsing @@ -26,10 +35,149 @@ package org.apache.fop.fo.flow.table; */ class FixedColRowGroupBuilder extends RowGroupBuilder { + /** Number of columns in the corresponding table. */ + private int numberOfColumns; + + /** 0-based, index in the row group. */ + private int currentRowIndex; + + /** The rows belonging to this row group. List of List of {@link GridUnit}s. */ + private List/*<List<GridUnit>>*/ rows; + + private boolean firstInTable = true; + + private boolean firstInPart = true; + + /** The last encountered row. This is the last row of the table if it has no footer. */ + private List lastRow; + + private BorderResolver borderResolver; + + private boolean inFooter; + + private List lastFooterRow; FixedColRowGroupBuilder(Table t) { super(t); numberOfColumns = t.getNumberOfColumns(); + if (t.isSeparateBorderModel()) { + borderResolver = new SeparateBorderResolver(); + } else { + borderResolver = new CollapsingBorderResolver(t); + } + initialize(); + } + + /** + * Prepares this builder for creating a new row group. + */ + private void initialize() { + rows = new ArrayList(); + currentRowIndex = 0; } + /** {@inheritDoc} */ + void addTableCell(TableCell cell) { + for (int i = rows.size(); i < currentRowIndex + cell.getNumberRowsSpanned(); i++) { + List effRow = new ArrayList(numberOfColumns); + for (int j = 0; j < numberOfColumns; j++) { + effRow.add(null); + } + rows.add(effRow); + } + int columnIndex = cell.getColumnNumber() - 1; + PrimaryGridUnit pgu = new PrimaryGridUnit(cell, table.getColumn(columnIndex), columnIndex, + currentRowIndex); + List row = (List) rows.get(currentRowIndex); + row.set(columnIndex, pgu); + // TODO + GridUnit[] cellRow = new GridUnit[cell.getNumberColumnsSpanned()]; + cellRow[0] = pgu; + for (int j = 1; j < cell.getNumberColumnsSpanned(); j++) { + GridUnit gu = new GridUnit(pgu, table.getColumn(columnIndex + j), + columnIndex + j, j, 0); + row.set(columnIndex + j, gu); + cellRow[j] = gu; + } + pgu.addRow(cellRow); + for (int i = 1; i < cell.getNumberRowsSpanned(); i++) { + row = (List) rows.get(currentRowIndex + i); + cellRow = new GridUnit[cell.getNumberColumnsSpanned()]; + for (int j = 0; j < cell.getNumberColumnsSpanned(); j++) { + GridUnit gu = new GridUnit(pgu, table.getColumn(columnIndex + j), + columnIndex + j, j, i); + row.set(columnIndex + j, gu); + cellRow[j] = gu; + } + pgu.addRow(cellRow); + } + } + + private static void setFlagForCols(int flag, List row) { + for (ListIterator iter = row.listIterator(); iter.hasNext();) { + ((GridUnit) iter.next()).setFlag(flag); + } + } + + /** {@inheritDoc} */ + void endRow(TableCellContainer container) { + List currentRow = (List) rows.get(currentRowIndex); + lastRow = currentRow; + // Fill gaps with empty grid units + for (int i = 0; i < numberOfColumns; i++) { + if (currentRow.get(i) == null) { + currentRow.set(i, new EmptyGridUnit(table, currentRowIndex, i)); + } + } + borderResolver.endRow(currentRow, container); + ((GridUnit) currentRow.get(0)).setFlag(GridUnit.IN_FIRST_COLUMN); + ((GridUnit) currentRow.get(numberOfColumns - 1)).setFlag(GridUnit.IN_LAST_COLUMN); + if (inFooter) { + lastFooterRow = currentRow; + } else if (firstInTable) { + setFlagForCols(GridUnit.FIRST_IN_TABLE, currentRow); + firstInTable = false; + } + if (firstInPart) { + setFlagForCols(GridUnit.FIRST_IN_PART, currentRow); + firstInPart = false; + } + if (currentRowIndex == rows.size() - 1) { + // Means that the current row has no cell spanning over following rows + container.getTablePart().addRowGroup(rows); + initialize(); + } else { + currentRowIndex++; + } + } + + /** {@inheritDoc} */ + void startTablePart(TableBody part) { + firstInPart = true; + inFooter = part.isTableFooter(); + borderResolver.startPart(part); + } + + /** {@inheritDoc} */ + void endTablePart(TableBody tableBody) throws ValidationException { + if (rows.size() > 0) { + throw new ValidationException( + "A table-cell is spanning more rows than available in its parent element."); + } + setFlagForCols(GridUnit.LAST_IN_PART, lastRow); + borderResolver.endPart(tableBody); + inFooter = false; + } + + /** {@inheritDoc} */ + void endTable(TableBody lastTablePart) { + List lastTableRow; + if (lastFooterRow != null) { + lastTableRow = lastFooterRow; + } else { + lastTableRow = lastRow; + } + setFlagForCols(GridUnit.LAST_IN_TABLE, lastTableRow); + borderResolver.endTable(); + } } |