diff options
author | Vincent Hennebert <vhennebert@apache.org> | 2007-11-13 17:39:17 +0000 |
---|---|---|
committer | Vincent Hennebert <vhennebert@apache.org> | 2007-11-13 17:39:17 +0000 |
commit | 20c46b41fd4972f4fc3265e32f150a647f93ff79 (patch) | |
tree | 6e4a44fd270e9c0ff69bf1df14b9ac3d3e1c2da1 /src/java/org/apache/fop | |
parent | fdad001c2baf70ce221cf210cc20ce9f7d43749a (diff) | |
download | xmlgraphics-fop-20c46b41fd4972f4fc3265e32f150a647f93ff79.tar.gz xmlgraphics-fop-20c46b41fd4972f4fc3265e32f150a647f93ff79.zip |
Cleaned up RowGroupLayoutManager and TableRowIterator
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@594592 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/fop')
3 files changed, 10 insertions, 473 deletions
diff --git a/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java index 9117f4ecb..92b981553 100644 --- a/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java @@ -49,21 +49,12 @@ class RowGroupLayoutManager { private TableLayoutManager tableLM; - private TableRowIterator bodyIter; - private TableRowIterator headerIter; - private TableRowIterator footerIter; - private TableRowIterator thisIter; private TableStepper tableStepper; - RowGroupLayoutManager(TableLayoutManager tableLM, EffRow[] rowGroup, TableRowIterator bodyIter, - TableRowIterator headerIter, TableRowIterator footerIter, TableRowIterator thisIter, + RowGroupLayoutManager(TableLayoutManager tableLM, EffRow[] rowGroup, TableStepper tableStepper) { this.tableLM = tableLM; this.rowGroup = rowGroup; - this.bodyIter = bodyIter; - this.headerIter = headerIter; - this.footerIter = footerIter; - this.thisIter = thisIter; this.tableStepper = tableStepper; } @@ -160,7 +151,7 @@ class RowGroupLayoutManager { int maxCellHeight = 0; int effRowContentHeight = 0; for (int j = 0; j < row.getGridUnits().size(); j++) { -// assert maxColumnCount == 0 || maxColumnCount == row.getGridUnits().size(); // TODO vh + assert maxColumnCount == 0 || maxColumnCount == row.getGridUnits().size(); maxColumnCount = Math.max(maxColumnCount, row.getGridUnits().size()); GridUnit gu = row.getGridUnit(j); if ((gu.isPrimary() || (gu.getColSpanIndex() == 0 && gu.isLastGridUnitRowSpan())) diff --git a/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java index d9893a120..0799e42bd 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java @@ -76,15 +76,12 @@ public class TableContentLayoutManager implements PercentBaseContext { public TableContentLayoutManager(TableLayoutManager parent) { this.tableLM = parent; Table table = getTableLM().getTable(); - this.bodyIter = new TableRowIterator(table, getTableLM().getColumns(), - TableRowIterator.BODY); + this.bodyIter = new TableRowIterator(table, TableRowIterator.BODY); if (table.getTableHeader() != null) { - headerIter = new TableRowIterator(table, - getTableLM().getColumns(), TableRowIterator.HEADER); + headerIter = new TableRowIterator(table, TableRowIterator.HEADER); } if (table.getTableFooter() != null) { - footerIter = new TableRowIterator(table, - getTableLM().getColumns(), TableRowIterator.FOOTER); + footerIter = new TableRowIterator(table, TableRowIterator.FOOTER); } } @@ -213,7 +210,7 @@ public class TableContentLayoutManager implements PercentBaseContext { int breakBetween = Constants.EN_AUTO; while ((rowGroup = iter.getNextRowGroup()) != null) { RowGroupLayoutManager rowGroupLM = new RowGroupLayoutManager(getTableLM(), rowGroup, - bodyIter, headerIter, footerIter, iter, stepper); + stepper); if (breakBetween == Constants.EN_AUTO) { // TODO improve breakBetween = rowGroupLM.getBreakBefore(); diff --git a/src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java b/src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java index 578cf2a19..51914ca92 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java @@ -22,21 +22,11 @@ package org.apache.fop.layoutmgr.table; import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import java.util.ListIterator; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.apache.fop.fo.FONode; import org.apache.fop.fo.FONode.FONodeIterator; -import org.apache.fop.fo.flow.Marker; -import org.apache.fop.fo.flow.table.GridUnit; -import org.apache.fop.fo.flow.table.PrimaryGridUnit; import org.apache.fop.fo.flow.table.Table; import org.apache.fop.fo.flow.table.TableBody; -import org.apache.fop.fo.flow.table.TableCell; -import org.apache.fop.fo.flow.table.TableColumn; -import org.apache.fop.fo.flow.table.TableRow; -import org.apache.fop.fo.properties.CommonBorderPaddingBackground; /** @@ -53,78 +43,30 @@ public class TableRowIterator { /** Selects the table-footer elements for iteration. */ public static final int FOOTER = 2; - /** Logger **/ - private static Log log = LogFactory.getLog(TableRowIterator.class); - /** The table on which this instance operates. */ protected Table table; - /** Column setup of the operated table. */ - private ColumnSetup columns; /** Part of the table over which to iterate. One of BODY, HEADER or FOOTER. */ private int tablePart; - /** Holds the currently fetched row (TableCell instances). */ - private List currentRow = new java.util.ArrayList(); - - /** - * Holds the grid units of cells from the previous row which will span over the - * current row. Should be read "previous row's spanning cells". List of GridUnit - * instances. - */ - private List previousRowsSpanningCells = new java.util.ArrayList(); - - /** Index of the row currently being fetched. */ - private int fetchIndex = -1; - - /** - * Number of spans found on the current row which will also span over the next row. - */ - private int pendingRowSpans; - - //TODO rows should later be a Jakarta Commons LinkedList so concurrent modifications while - //using a ListIterator are possible - /** List of cached rows. This is a list of EffRow elements. */ - private List fetchedRows = new java.util.ArrayList(); - - /** - * Index of the row that will be returned at the next iteration step. Note that there - * is no direct relation between this field and {@link - * TableRowIterator#fetchIndex}. The fetching of rows and the iterating over them are - * two different processes. Hence the two indices. */ - private int iteratorIndex = 0; - - //prefetch state - /** - * Iterator over the requested table's part(s) (header, footer, body). Note that - * a table may have several table-body children, hence the iterator. - */ - private ListIterator tablePartIterator = null; - /** Iterator over a part's child elements (either table-rows or table-cells). */ - private ListIterator tablePartChildIterator = null; - private Iterator rowGroupsIter; /** * Creates a new TableRowIterator. * @param table the table to iterate over - * @param columns the column setup for the table * @param tablePart indicates what part of the table to iterate over (HEADER, FOOTER, BODY) */ - public TableRowIterator(Table table, ColumnSetup columns, int tablePart) { + public TableRowIterator(Table table, int tablePart) { this.table = table; - this.columns = columns; this.tablePart = tablePart; switch(tablePart) { - case HEADER: { + case HEADER: rowGroupsIter = table.getTableHeader().getRowGroups().iterator(); break; - } - case FOOTER: { + case FOOTER: rowGroupsIter = table.getTableFooter().getRowGroups().iterator(); break; - } - default: { + default: List rowGroupsList = new LinkedList(); // TODO this is ugly for (FONodeIterator iter = table.getChildNodes(); iter.hasNext();) { @@ -134,7 +76,6 @@ public class TableRowIterator { } } rowGroupsIter = rowGroupsList.iterator(); - } } } @@ -158,396 +99,4 @@ public class TableRowIterator { return effRowGroup; } - /** - * Returns the row at the given index, fetching rows up to the requested one if - * necessary. - * - * @return the requested row, or null if there is no row at the given index (index - * < 0 or end of table-part reached) - */ - private EffRow getRow(int index) { - boolean moreRows = true; - while (moreRows && fetchedRows.size() <= index) { - moreRows = prefetchNext(); - } - // Whatever the value of index, getCachedRow will handle it nicely - return getCachedRow(index); - } - - /** - * Returns the next effective row. - * @return the requested effective row or null if there is no more row. - */ - private EffRow getNextRow() { - return getRow(iteratorIndex++); - } - - /** - * Returns the row preceding the given row, without moving the iterator. - * - * @param row a row in the iterated table part - * @return the preceding row, or null if there is no such row (the given row is the - * first one in the table part) - */ - EffRow getPrecedingRow(EffRow row) { - return getRow(row.getIndex() - 1); - } - - /** - * Returns the row following the given row, without moving the iterator. - * - * @param row a row in the iterated table part - * @return the following row, or null if there is no more row - */ - EffRow getFollowingRow(EffRow row) { - return getRow(row.getIndex() + 1); - } - - /** - * Returns the first effective row. - * @return the requested effective row. - */ - EffRow getFirstRow() { - if (fetchedRows.size() == 0) { - prefetchNext(); - } - return getCachedRow(0); - } - - /** - * Returns the last effective row. - * <p>Note:This is inefficient for large tables because the whole table - * if preloaded.</p> - * @return the requested effective row. - */ - EffRow getLastRow() { - while (prefetchNext()) { - //nop - } - return getCachedRow(fetchedRows.size() - 1); - } - - /** - * Returns a cached effective row. If the given index points outside the range of rows - * (negative or greater than the number of already fetched rows), this methods - * terminates nicely by returning null. - * - * @param index index of the row (zero-based) - * @return the requested effective row or null if (index < 0 || index >= the - * number of already fetched rows) - */ - private EffRow getCachedRow(int index) { - if (index < 0 || index >= fetchedRows.size()) { - return null; - } else { - return (EffRow)fetchedRows.get(index); - } - } - - /** - * Fetches the next row. - * - * @return true if there was a row to fetch; otherwise, false (the end of the - * table-part has been reached) - */ - private boolean prefetchNext() { - boolean firstInTable = false; - boolean firstInTablePart = false; - // If we are at the end of the current table part - if (tablePartChildIterator != null && !tablePartChildIterator.hasNext()) { - //force skip on to next component - if (pendingRowSpans > 0) { - this.currentRow.clear(); - this.fetchIndex++; - EffRow gridUnits = buildGridRow(this.currentRow, null); - log.debug(gridUnits); - fetchedRows.add(gridUnits); - return true; - } - tablePartChildIterator = null; - if (fetchedRows.size() > 0) { - getCachedRow(fetchedRows.size() - 1).setFlagForAllGridUnits( - GridUnit.LAST_IN_PART, true); - } - } - // If the iterating over the current table-part has not started yet - if (tablePartChildIterator == null) { - if (tablePartIterator.hasNext()) { - tablePartChildIterator = ((TableBody)tablePartIterator.next()).getChildNodes(); - if (fetchedRows.size() == 0) { - firstInTable = true; - } - firstInTablePart = true; - } else { - //no more rows in that part of the table - if (fetchedRows.size() > 0) { - getCachedRow(fetchedRows.size() - 1).setFlagForAllGridUnits( - GridUnit.LAST_IN_PART, true); - // If the last row is the last of the table - if (tablePart == FOOTER - || (tablePart == BODY && table.getTableFooter() == null)) { - getCachedRow(fetchedRows.size() - 1).setFlagForAllGridUnits( - GridUnit.LAST_IN_TABLE, true); - } - } - return false; - } - } - Object node = tablePartChildIterator.next(); - while (node instanceof Marker) { - node = tablePartChildIterator.next(); - } - this.currentRow.clear(); - this.fetchIndex++; - TableRow rowFO = null; - if (node instanceof TableRow) { - rowFO = (TableRow)node; - ListIterator cellIterator = rowFO.getChildNodes(); - while (cellIterator.hasNext()) { - this.currentRow.add(cellIterator.next()); - } - } else if (node instanceof TableCell) { - this.currentRow.add(node); - if (!((TableCell)node).endsRow()) { - while (tablePartChildIterator.hasNext()) { - TableCell cell = (TableCell)tablePartChildIterator.next(); - if (cell.startsRow()) { - //next row already starts here, one step back - tablePartChildIterator.previous(); - break; - } - this.currentRow.add(cell); - if (cell.endsRow()) { - break; - } - } - } - } else { - throw new IllegalStateException("Illegal class found: " + node.getClass().getName()); - } - EffRow gridUnits = buildGridRow(this.currentRow, rowFO); - if (firstInTablePart) { - gridUnits.setFlagForAllGridUnits(GridUnit.FIRST_IN_PART, true); - } - if (firstInTable && (tablePart == HEADER || table.getTableHeader() == null) - && tablePart != FOOTER) { - gridUnits.setFlagForAllGridUnits(GridUnit.FIRST_IN_TABLE, true); - } - log.debug(gridUnits); - fetchedRows.add(gridUnits); - return true; - } - - /** - * Places the given object at the given position in the list, first extending it if - * necessary with null objects to reach the position. - * - * @param list the list in which to place the object - * @param position index at which the object must be placed (0-based) - * @param obj the object to place - */ - private void safelySetListItem(List list, int position, Object obj) { - while (position >= list.size()) { - list.add(null); - } - list.set(position, obj); - } - - private Object safelyGetListItem(List list, int position) { - if (position >= list.size()) { - return null; - } else { - return list.get(position); - } - } - - /** - * Builds the list of grid units corresponding to the given table row. - * - * @param cells list of cells starting at the current row - * @param rowFO the fo:table-row object containing the row, possibly null - * @return the list of grid units - */ - private EffRow buildGridRow(List cells, TableRow rowFO) { - EffRow row = new EffRow(this.fetchIndex, tablePart, null); - List gridUnits = row.getGridUnits(); - - TableBody bodyFO = null; - - //Create all row-spanned grid units based on information from the previous row - int colnum = 1; - GridUnit[] horzSpan = null; // Grid units horizontally spanned by a single cell - if (pendingRowSpans > 0) { - ListIterator spanIter = previousRowsSpanningCells.listIterator(); - while (spanIter.hasNext()) { - GridUnit gu = (GridUnit)spanIter.next(); - if (gu != null) { - if (gu.getColSpanIndex() == 0) { - horzSpan = new GridUnit[gu.getCell().getNumberColumnsSpanned()]; - } -// GridUnit newGU = gu.createNextRowSpanningGridUnit(); - GridUnit newGU = null; - newGU.setRow(rowFO); - safelySetListItem(gridUnits, colnum - 1, newGU); - horzSpan[newGU.getColSpanIndex()] = newGU; - if (newGU.isLastGridUnitColSpan()) { - //Add the array of row-spanned grid units to the primary grid unit - newGU.getPrimary().addRow(horzSpan); - horzSpan = null; - } - if (newGU.isLastGridUnitRowSpan()) { - spanIter.set(null); - pendingRowSpans--; - } else { - spanIter.set(newGU); - } - } - colnum++; - } - } - if (pendingRowSpans < 0) { - throw new IllegalStateException("pendingRowSpans must not become negative!"); - } - - //Transfer available cells to their slots - colnum = 1; - ListIterator iter = cells.listIterator(); - while (iter.hasNext()) { - TableCell cell = (TableCell)iter.next(); - - colnum = cell.getColumnNumber(); - - //TODO: remove the check below??? - //shouldn't happen here, since - //overlapping cells already caught in - //fo.flow.TableCell.bind()... - GridUnit other = (GridUnit)safelyGetListItem(gridUnits, colnum - 1); - if (other != null) { - String err = "A table-cell (" - + cell.getContextInfo() - + ") is overlapping with another (" - + other.getCell().getContextInfo() - + ") in column " + colnum; - throw new IllegalStateException(err - + " (this should have been catched by FO tree validation)"); - } - TableColumn col = columns.getColumn(colnum); - - //Add grid unit for primary grid unit - PrimaryGridUnit gu = new PrimaryGridUnit(cell, col, colnum - 1, this.fetchIndex); - safelySetListItem(gridUnits, colnum - 1, gu); - boolean hasRowSpanningLeft = !gu.isLastGridUnitRowSpan(); - if (hasRowSpanningLeft) { - pendingRowSpans++; - safelySetListItem(previousRowsSpanningCells, colnum - 1, gu); - } - - if (gu.hasSpanning()) { - //Add grid units on spanned slots if any - horzSpan = new GridUnit[cell.getNumberColumnsSpanned()]; - horzSpan[0] = gu; - for (int j = 1; j < cell.getNumberColumnsSpanned(); j++) { - colnum++; - GridUnit guSpan = new GridUnit(gu, columns.getColumn(colnum), colnum - 1, j, 0); - //TODO: remove the check below??? - other = (GridUnit)safelyGetListItem(gridUnits, colnum - 1); - if (other != null) { - String err = "A table-cell (" - + cell.getContextInfo() - + ") is overlapping with another (" - + other.getCell().getContextInfo() - + ") in column " + colnum; - throw new IllegalStateException(err - + " (this should have been catched by FO tree validation)"); - } - safelySetListItem(gridUnits, colnum - 1, guSpan); - if (hasRowSpanningLeft) { - pendingRowSpans++; - safelySetListItem(previousRowsSpanningCells, colnum - 1, guSpan); - } - horzSpan[j] = guSpan; - } - gu.addRow(horzSpan); - } - - //Gather info for empty grid units (used later) - if (bodyFO == null) { - bodyFO = gu.getBody(); - } - - colnum++; - } - - //Post-processing the list (looking for gaps and resolve start and end borders) -// fillEmptyGridUnits(gridUnits, rowFO, bodyFO); - resolveStartEndBorders(gridUnits); - - return row; - } - -// private void fillEmptyGridUnits(List gridUnits, TableRow row, TableBody body) { -// for (int pos = 1; pos <= gridUnits.size(); pos++) { -// GridUnit gu = (GridUnit)gridUnits.get(pos - 1); -// -// //Empty grid units -// if (gu == null) { -// //Add grid unit -// gu = new EmptyGridUnit(row, columns.getColumn(pos), body, -// pos - 1); -// gridUnits.set(pos - 1, gu); -// } -// -// //Set flags -// gu.setFlag(GridUnit.IN_FIRST_COLUMN, (pos == 1)); -// gu.setFlag(GridUnit.IN_LAST_COLUMN, (pos == gridUnits.size())); -// } -// } - - private void resolveStartEndBorders(List gridUnits) { - for (int pos = 1; pos <= gridUnits.size(); pos++) { - GridUnit starting = (GridUnit)gridUnits.get(pos - 1); - - //Border resolution - if (table.isSeparateBorderModel()) { - starting.assignBorderForSeparateBorderModel(); - } else { - //Neighbouring grid unit at start edge - GridUnit start = null; - int find = pos - 1; - while (find >= 1) { - GridUnit candidate = (GridUnit)gridUnits.get(find - 1); - if (candidate.isLastGridUnitColSpan()) { - start = candidate; - break; - } - find--; - } - - //Ending grid unit for current cell - GridUnit ending = null; - if (starting.getCell() != null) { - pos += starting.getCell().getNumberColumnsSpanned() - 1; - } - ending = (GridUnit)gridUnits.get(pos - 1); - - //Neighbouring grid unit at end edge - GridUnit end = null; - find = pos + 1; - while (find <= gridUnits.size()) { - GridUnit candidate = (GridUnit)gridUnits.get(find - 1); - if (candidate.isPrimary()) { - end = candidate; - break; - } - find++; - } - starting.resolveBorder(start, - CommonBorderPaddingBackground.START); - ending.resolveBorder(end, - CommonBorderPaddingBackground.END); - //Only start and end borders here, before and after during layout - } - } - } - } |