aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/fop
diff options
context:
space:
mode:
authorVincent Hennebert <vhennebert@apache.org>2007-11-13 17:39:17 +0000
committerVincent Hennebert <vhennebert@apache.org>2007-11-13 17:39:17 +0000
commit20c46b41fd4972f4fc3265e32f150a647f93ff79 (patch)
tree6e4a44fd270e9c0ff69bf1df14b9ac3d3e1c2da1 /src/java/org/apache/fop
parentfdad001c2baf70ce221cf210cc20ce9f7d43749a (diff)
downloadxmlgraphics-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')
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java13
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java11
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java459
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
- * &lt; 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 &lt; 0 || index &gt;= 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
- }
- }
- }
-
}