aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org
diff options
context:
space:
mode:
Diffstat (limited to 'src/java/org')
-rw-r--r--src/java/org/apache/fop/fo/flow/RetrieveMarker.java13
-rw-r--r--src/java/org/apache/fop/fo/flow/table/BorderResolver.java56
-rw-r--r--src/java/org/apache/fop/fo/flow/table/BorderSpecification.java71
-rw-r--r--src/java/org/apache/fop/fo/flow/table/CollapsingBorderResolver.java169
-rw-r--r--src/java/org/apache/fop/fo/flow/table/FixedColRowGroupBuilder.java148
-rw-r--r--src/java/org/apache/fop/fo/flow/table/RowGroupBuilder.java98
-rw-r--r--src/java/org/apache/fop/fo/flow/table/SeparateBorderResolver.java44
-rw-r--r--src/java/org/apache/fop/fo/flow/table/Table.java48
-rw-r--r--src/java/org/apache/fop/fo/flow/table/TableBody.java67
-rw-r--r--src/java/org/apache/fop/fo/flow/table/TableCell.java19
-rw-r--r--src/java/org/apache/fop/fo/flow/table/TableCellContainer.java7
-rw-r--r--src/java/org/apache/fop/fo/flow/table/TableColumn.java24
-rw-r--r--src/java/org/apache/fop/fo/flow/table/TableFObj.java60
-rw-r--r--src/java/org/apache/fop/fo/flow/table/TableFooter.java10
-rw-r--r--src/java/org/apache/fop/fo/flow/table/TableHeader.java5
-rw-r--r--src/java/org/apache/fop/fo/flow/table/TableRow.java23
-rw-r--r--src/java/org/apache/fop/fo/flow/table/VariableColRowGroupBuilder.java82
-rwxr-xr-xsrc/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java8
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModel.java94
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModelEyeCatching.java299
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/EffRow.java6
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/EmptyGridUnit.java48
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/GridUnit.java227
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/PrimaryGridUnit.java20
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java106
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java113
26 files changed, 1153 insertions, 712 deletions
diff --git a/src/java/org/apache/fop/fo/flow/RetrieveMarker.java b/src/java/org/apache/fop/fo/flow/RetrieveMarker.java
index f2679d04b..7356bc72e 100644
--- a/src/java/org/apache/fop/fo/flow/RetrieveMarker.java
+++ b/src/java/org/apache/fop/fo/flow/RetrieveMarker.java
@@ -23,12 +23,13 @@ import java.util.Iterator;
import org.apache.fop.apps.FOPException;
import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.FOText;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.FObjMixed;
-import org.apache.fop.fo.FOText;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.ValidationException;
import org.apache.fop.fo.flow.table.Table;
+import org.apache.fop.fo.flow.table.TableFObj;
import org.xml.sax.Locator;
/**
@@ -126,6 +127,12 @@ public class RetrieveMarker extends FObjMixed {
getLocator(),
pList,
newPropertyList);
+ if (newChild instanceof TableFObj) {
+ // TODO calling startOfNode (and endOfNode, below) on other fobjs may
+ // have undesirable side-effects. This is really ugly and will need to
+ // be addressed sooner or later
+ ((TableFObj) newChild).startOfNode();
+ }
addChildTo(newChild, (FObj) newParent);
if (newChild.getNameId() == FO_TABLE) {
Table t = (Table) child;
@@ -138,6 +145,10 @@ public class RetrieveMarker extends FObjMixed {
}
cloneSubtree(child.getChildNodes(), newChild,
marker, newPropertyList);
+ if (newChild instanceof TableFObj) {
+ // TODO this is ugly
+ ((TableFObj) newChild).endOfNode();
+ }
} else if (child instanceof FOText) {
FOText ft = (FOText) newChild;
ft.bind(parentPropertyList);
diff --git a/src/java/org/apache/fop/fo/flow/table/BorderResolver.java b/src/java/org/apache/fop/fo/flow/table/BorderResolver.java
new file mode 100644
index 000000000..0a8f3d39e
--- /dev/null
+++ b/src/java/org/apache/fop/fo/flow/table/BorderResolver.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.flow.table;
+
+import java.util.List;
+
+/**
+ * A class dedicated to the resolution of borders in tables. It receives a series of
+ * events as the table is parsed and performs border resolution accordingly.
+ */
+interface BorderResolver {
+
+ /**
+ * Receives notification of the end of a row.
+ *
+ * @param row the row that has just been finished
+ * @param container the FO element holding the given row
+ */
+ void endRow(List/*<GridUnit>*/ row, TableCellContainer container);
+
+ /**
+ * Receives notification of the start of a table-header/footer/body.
+ *
+ * @param part the part that has started
+ */
+ void startPart(TableBody part);
+
+ /**
+ * Receives notification of the end of a table-header/footer/body.
+ *
+ * @param part the part that has ended
+ */
+ void endPart(TableBody part);
+
+ /**
+ * Receives notification of the end of the table.
+ */
+ void endTable();
+}
diff --git a/src/java/org/apache/fop/fo/flow/table/BorderSpecification.java b/src/java/org/apache/fop/fo/flow/table/BorderSpecification.java
new file mode 100644
index 000000000..214f9be07
--- /dev/null
+++ b/src/java/org/apache/fop/fo/flow/table/BorderSpecification.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.flow.table;
+
+import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo;
+
+/**
+ * A border's informations, along with the FO element which declared it. Used for border
+ * resolution in the collapsing-border model.
+ */
+public/*TODO*/ class BorderSpecification {
+
+ private BorderInfo borderInfo;
+
+ private int holder;
+
+ /**
+ * Creates a new border specification.
+ *
+ * @param borderInfo the border's informations
+ * @param holder the FO element declaring this border
+ */
+ public/*TODO*/ BorderSpecification(BorderInfo borderInfo, int holder) {
+ this.borderInfo = borderInfo;
+ this.holder = holder;
+ }
+
+ /**
+ * Returns this border's informations.
+ *
+ * @return this border's informations
+ */
+ public/*TODO*/ BorderInfo getBorderInfo() {
+ return borderInfo;
+ }
+
+ /**
+ * Returns the FO element declaring this border.
+ *
+ * @return one of {@link Constants#FO_TABLE}, {@link Constants#FO_TABLE_COLUMN},
+ * {@link Constants#FO_TABLE_HEADER}, {@link Constants#FO_TABLE_FOOTER},
+ * {@link Constants#FO_TABLE_BODY}, {@link Constants#FO_TABLE_ROW},
+ * {@link Constants#FO_TABLE_CELL}
+ */
+ public/*TODO*/ int getHolder() {
+ return holder;
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return "{" + borderInfo + ", " + holder + "}";
+ }
+}
diff --git a/src/java/org/apache/fop/fo/flow/table/CollapsingBorderResolver.java b/src/java/org/apache/fop/fo/flow/table/CollapsingBorderResolver.java
new file mode 100644
index 000000000..732acb6be
--- /dev/null
+++ b/src/java/org/apache/fop/fo/flow/table/CollapsingBorderResolver.java
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.flow.table;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
+import org.apache.fop.layoutmgr.table.GridUnit;
+
+/**
+ * A class that implements the border-collapsing model.
+ */
+class CollapsingBorderResolver implements BorderResolver {
+
+ private Table table;
+
+ private List previousRow;
+
+ /**
+ * The flow of rows is interrupted by the table-footer. Save the header's last row (if
+ * any) for resolution between it and the body's first row.
+ */
+ private List previousRowSave;
+
+ private TableBody currentTablePart;
+
+ private boolean firstInTable;
+
+ private boolean firstInPart;
+
+ private List footerFirstRow;
+
+ private List footerLastRow;
+
+ private boolean inFooter;
+
+ CollapsingBorderResolver(Table table) {
+ this.table = table;
+ firstInTable = true;
+ }
+
+ /** {@inheritDoc} */
+ public void endRow(List row, TableCellContainer container) {
+ // Resolve before- and after-borders for the table-row
+ if (container instanceof TableRow) {
+ TableRow tableRow = (TableRow) container;
+ for (Iterator iter = row.iterator(); iter.hasNext();) {
+ GridUnit gu = (GridUnit) iter.next();
+ if (gu.getRowSpanIndex() == 0) {
+ gu.resolveBorder(CommonBorderPaddingBackground.BEFORE, tableRow);
+ }
+ if (gu.isLastGridUnitRowSpan()) {
+ gu.resolveBorder(CommonBorderPaddingBackground.AFTER, tableRow);
+ }
+ }
+ }
+ if (inFooter) {
+ if (footerFirstRow == null) {
+ footerFirstRow = row;
+ }
+ footerLastRow = row;
+ } else if (firstInTable) {
+ // Resolve border-before for the first row in the table
+ for (int i = 0; i < row.size(); i++) {
+ TableColumn column = table.getColumn(i);
+ ((GridUnit) row.get(i)).resolveBorder(CommonBorderPaddingBackground.BEFORE, column);
+ }
+ firstInTable = false;
+ }
+ if (firstInPart) {
+ // Resolve border-before for the first row in the part
+ for (int i = 0; i < row.size(); i++) {
+ ((GridUnit) row.get(i)).resolveBorder(CommonBorderPaddingBackground.BEFORE,
+ currentTablePart);
+ }
+ firstInPart = false;
+ }
+ if (previousRow != null) {
+ // Resolve after/before borders between rows
+ for (int i = 0; i < row.size(); i++) {
+ GridUnit gu = (GridUnit) row.get(i);
+ if (gu.getRowSpanIndex() == 0) {
+ GridUnit beforeGU = (GridUnit) previousRow.get(i);
+ gu.resolveBorder(beforeGU, CommonBorderPaddingBackground.BEFORE);
+ }
+ }
+ }
+ // Resolve start/end borders in the row
+ Iterator guIter = row.iterator();
+ GridUnit gu = (GridUnit) guIter.next();
+ gu.resolveBorder(CommonBorderPaddingBackground.START, container);
+ while (guIter.hasNext()) {
+ GridUnit guEnd = (GridUnit) guIter.next();
+ if (gu.isLastGridUnitColSpan()) {
+ gu.resolveBorder(guEnd, CommonBorderPaddingBackground.END);
+ }
+ gu = guEnd;
+ }
+ gu.resolveBorder(CommonBorderPaddingBackground.END, container);
+
+ previousRow = row;
+ }
+
+ /** {@inheritDoc} */
+ public void startPart(TableBody part) {
+ firstInPart = true;
+ currentTablePart = part;
+ if (part.isTableFooter()) {
+ inFooter = true;
+ previousRowSave = previousRow;
+ previousRow = null;
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void endPart(TableBody part) {
+ // Resolve border-after for the last row in the part
+ for (int i = 0; i < previousRow.size(); i++) {
+ ((GridUnit) previousRow.get(i))
+ .resolveBorder(CommonBorderPaddingBackground.AFTER, part);
+ }
+ if (inFooter) {
+ inFooter = false;
+ previousRow = previousRowSave;
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void endTable() {
+ if (footerFirstRow != null) {
+ // Resolve after/before border between the last row of table-body and the
+ // first row of table-footer
+ for (int i = 0; i < footerFirstRow.size(); i++) {
+ GridUnit gu = (GridUnit) footerFirstRow.get(i);
+ GridUnit beforeGU = (GridUnit) previousRow.get(i);
+ gu.resolveBorder(beforeGU, CommonBorderPaddingBackground.BEFORE);
+ }
+ }
+ List lastRow;
+ if (footerLastRow != null) {
+ lastRow = footerLastRow;
+ } else {
+ lastRow = previousRow;
+ }
+ // Resolve border-after for the last row of the table
+ for (int i = 0; i < lastRow.size(); i++) {
+ TableColumn column = table.getColumn(i);
+ ((GridUnit) lastRow.get(i)).resolveBorder(CommonBorderPaddingBackground.AFTER, column);
+ }
+ }
+}
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();
+ }
}
diff --git a/src/java/org/apache/fop/fo/flow/table/RowGroupBuilder.java b/src/java/org/apache/fop/fo/flow/table/RowGroupBuilder.java
index 2f9a009c2..7f09f7d46 100644
--- a/src/java/org/apache/fop/fo/flow/table/RowGroupBuilder.java
+++ b/src/java/org/apache/fop/fo/flow/table/RowGroupBuilder.java
@@ -19,12 +19,8 @@
package org.apache.fop.fo.flow.table;
-import java.util.ArrayList;
-import java.util.List;
-
import org.apache.fop.fo.ValidationException;
import org.apache.fop.layoutmgr.table.GridUnit;
-import org.apache.fop.layoutmgr.table.PrimaryGridUnit;
/**
* A class that creates groups of rows belonging to a same set of spans. The first row of
@@ -34,16 +30,7 @@ import org.apache.fop.layoutmgr.table.PrimaryGridUnit;
*/
abstract class RowGroupBuilder {
- /** Number of columns in the corresponding table. */
- protected int numberOfColumns;
-
- /** 0-based, index in the row group. */
- private int currentRowIndex;
-
- private Table table;
-
- /** The rows belonging to this row group. List of List of {@link GridUnit}s. */
- protected List rows;
+ protected Table table;
/**
* Creates and initialises a new builder for the given table.
@@ -52,81 +39,48 @@ abstract class RowGroupBuilder {
*/
protected RowGroupBuilder(Table t) {
table = t;
- initialize();
}
+
/**
- * Prepares this builder for creating a new row group.
+ * Adds a table-cell to the current row-group, creating {@link GridUnit}s accordingly.
+ *
+ * @param cell the cell to add
*/
- private void initialize() {
- rows = new ArrayList();
- currentRowIndex = 0;
- }
+ abstract void addTableCell(TableCell cell);
/**
- * Adds a table-cell to the row-group, creating {@link GridUnit}s accordingly.
+ * Receives notification of the end of the current row. If the current row finishes
+ * the row group, the {@link TableBody#addRowGroup(List)} method of the parent table
+ * part (i.e., the given container itself or its parent if this is a table-row) will
+ * be called
*
- * @param cell
+ * @param container the parent element of the current row
*/
- 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);
- for (int j = 1; j < cell.getNumberColumnsSpanned(); j++) {
- row.set(j + columnIndex,
- new GridUnit(pgu, table.getColumn(columnIndex + j), columnIndex + j, j));
- }
- for (int i = 1; i < cell.getNumberRowsSpanned(); i++) {
- row = (List) rows.get(currentRowIndex + i);
- for (int j = 0; j < cell.getNumberColumnsSpanned(); j++) {
- row.set(j + columnIndex,
- new GridUnit(pgu, table.getColumn(columnIndex + j), columnIndex + j, j));
- }
- }
-
- }
+ abstract void endRow(TableCellContainer container);
/**
- * Signals that a table row has just ended, potentially finishing the current row
- * group.
+ * Receives notification of the start of a table-header/footer/body.
*
- * @param body the table-body containing the row. Its
- * {@link TableBody#addRowGroup(List)} method will be called if the current row group
- * is finished.
+ * @param part the part being started
*/
- void signalRowEnd(TableBody body) {
- if (currentRowIndex == rows.size() - 1) {
- // Means that the current row has no cell spanning over following rows
- body.addRowGroup(rows);
- initialize();
- } else {
- currentRowIndex++;
- }
- }
+ abstract void startTablePart(TableBody part);
/**
- * Signals that the end of a table-header/footer/body has been reached. The current
+ * Receives notification of the end of a table-header/footer/body. The current
* row-group is checked for emptiness. This row group builder is reset for handling
* further possible table parts.
*
- * @param tableBody the table part being finished
- * @throws ValidationException if a cell is spanning further than the given table part
+ * @param tableBody the table part being ended
+ * @throws ValidationException if a row-spanning cell overflows the given table part
*/
- void signalEndOfPart(TableBody tableBody) throws ValidationException {
- if (rows.size() > 0) {
- throw new ValidationException(
- "A table-cell is spanning more rows than available in its parent element.");
- }
- initialize();
- }
+ abstract void endTablePart(TableBody tableBody) throws ValidationException;
+ /**
+ * Receives notification of the end of the table.
+ *
+ * @param lastTablePart the last part of the table
+ * @throws ValidationException if a row-spanning cell overflows one of the table's parts
+ */
+ abstract void endTable(TableBody lastTablePart) throws ValidationException;
}
diff --git a/src/java/org/apache/fop/fo/flow/table/SeparateBorderResolver.java b/src/java/org/apache/fop/fo/flow/table/SeparateBorderResolver.java
new file mode 100644
index 000000000..37e3cb6e8
--- /dev/null
+++ b/src/java/org/apache/fop/fo/flow/table/SeparateBorderResolver.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.flow.table;
+
+import java.util.List;
+
+/**
+ * A resolver for the separate-border model. Basically this class does nothing.
+ */
+class SeparateBorderResolver implements BorderResolver {
+
+ /** {@inheritDoc} */
+ public void endRow(List row, TableCellContainer container) {
+ }
+
+ /** {@inheritDoc} */
+ public void startPart(TableBody part) {
+ }
+
+ /** {@inheritDoc} */
+ public void endPart(TableBody part) {
+ }
+
+ /** {@inheritDoc} */
+ public void endTable() {
+ }
+}
diff --git a/src/java/org/apache/fop/fo/flow/table/Table.java b/src/java/org/apache/fop/fo/flow/table/Table.java
index 07fc95f7e..b2f240c72 100644
--- a/src/java/org/apache/fop/fo/flow/table/Table.java
+++ b/src/java/org/apache/fop/fo/flow/table/Table.java
@@ -20,7 +20,6 @@
package org.apache.fop.fo.flow.table;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.List;
import org.apache.fop.apps.FOPException;
@@ -154,7 +153,7 @@ public class Table extends TableFObj implements ColumnNumberManagerHolder {
/**
* {@inheritDoc}
*/
- protected void startOfNode() throws FOPException {
+ public void startOfNode() throws FOPException {
super.startOfNode();
getFOEventHandler().startTable(this);
}
@@ -211,7 +210,7 @@ public class Table extends TableFObj implements ColumnNumberManagerHolder {
/**
* {@inheritDoc}
*/
- protected void endOfNode() throws FOPException {
+ public void endOfNode() throws FOPException {
if (!tableBodyFound) {
missingChildElementError(
@@ -219,6 +218,11 @@ public class Table extends TableFObj implements ColumnNumberManagerHolder {
+ ",table-body+)");
}
if (!inMarker()) {
+ if (tableFooter != null) {
+ rowGroupBuilder.endTable(tableFooter);
+ } else {
+ rowGroupBuilder.endTable((TableBody) getChildNodes().lastNode());
+ }
/* clean up */
for (int i = columns.size(); --i >= 0;) {
TableColumn col = (TableColumn) columns.get(i);
@@ -278,6 +282,13 @@ public class Table extends TableFObj implements ColumnNumberManagerHolder {
}
}
+ protected void setCollapsedBorders() {
+ createBorder(CommonBorderPaddingBackground.START);
+ createBorder(CommonBorderPaddingBackground.END);
+ createBorder(CommonBorderPaddingBackground.BEFORE);
+ createBorder(CommonBorderPaddingBackground.AFTER);
+ }
+
private void finalizeColumns() throws FOPException {
for (int i = 0; i < columns.size(); i++) {
if (columns.get(i) == null) {
@@ -305,32 +316,6 @@ public class Table extends TableFObj implements ColumnNumberManagerHolder {
for (int i = columns.size() + 1; i <= columnNumber; i++) {
columns.add(createImplicitColumn(i));
}
- ((VariableColRowGroupBuilder) rowGroupBuilder).ensureNumberOfColumns(columnNumber);
- if (tableHeader != null) {
- for (Iterator iter = tableHeader.getRowGroups().iterator(); iter.hasNext();) {
- VariableColRowGroupBuilder.fillWithEmptyGridUnits((List) iter.next(),
- columnNumber);
- }
- }
- if (tableFooter != null) {
- for (Iterator iter = tableFooter.getRowGroups().iterator(); iter.hasNext();) {
- VariableColRowGroupBuilder.fillWithEmptyGridUnits((List) iter.next(),
- columnNumber);
- }
- }
- FONodeIterator bodyIter = getChildNodes();
- if (bodyIter != null) {
- while (bodyIter.hasNext()) {
- FONode node = bodyIter.nextNode();
- if (node instanceof TableBody) { // AFAIK, may be a marker
- for (Iterator iter = ((TableBody) node).getRowGroups().iterator();
- iter.hasNext();) {
- VariableColRowGroupBuilder.fillWithEmptyGridUnits((List) iter.next(),
- columnNumber);
- }
- }
- }
- }
}
private TableColumn createImplicitColumn(int colNumber)
@@ -342,6 +327,9 @@ public class Table extends TableFObj implements ColumnNumberManagerHolder {
implicitColumn.bind(pList);
implicitColumn.setColumnWidth(new TableColLength(1.0, implicitColumn));
implicitColumn.setColumnNumber(colNumber);
+ if (!isSeparateBorderModel()) {
+ implicitColumn.setCollapsedBorders(collapsingBorderModel); // TODO
+ }
return implicitColumn;
}
@@ -399,7 +387,7 @@ public class Table extends TableFObj implements ColumnNumberManagerHolder {
* @param index index of the column to be retrieved, 0-based
* @return the corresponding column (may be an implicitly created column)
*/
- TableColumn getColumn(int index) {
+ public/*TODO*/ TableColumn getColumn(int index) {
return (TableColumn) columns.get(index);
}
diff --git a/src/java/org/apache/fop/fo/flow/table/TableBody.java b/src/java/org/apache/fop/fo/flow/table/TableBody.java
index 7e4ee2fb0..ece1f0049 100644
--- a/src/java/org/apache/fop/fo/flow/table/TableBody.java
+++ b/src/java/org/apache/fop/fo/flow/table/TableBody.java
@@ -50,15 +50,15 @@ public class TableBody extends TableCellContainer {
protected boolean tableRowsFound = false;
protected boolean tableCellsFound = false;
- /**
- * used for initial values of column-number property
- */
private boolean firstRow = true;
private boolean rowsStarted = false;
private boolean lastCellEndsRow = true;
+ /** The last encountered table-row. */
+ private TableRow lastRow;
+
private List rowGroups = new LinkedList();
/**
@@ -101,14 +101,15 @@ public class TableBody extends TableCellContainer {
/**
* {@inheritDoc}
*/
- protected void startOfNode() throws FOPException {
+ public void startOfNode() throws FOPException {
+ super.startOfNode();
getFOEventHandler().startBody(this);
}
/**
* {@inheritDoc}
*/
- protected void endOfNode() throws FOPException {
+ public void endOfNode() throws FOPException {
if (!inMarker()) {
pendingSpans = null;
@@ -130,16 +131,25 @@ public class TableBody extends TableCellContainer {
}
}
+ /** {@inheritDoc} */
+ TableBody getTablePart() {
+ return this;
+ }
+
protected void finishLastRowGroup() throws ValidationException {
- RowGroupBuilder rowGroupBuilder = getTable().getRowGroupBuilder();
- if (tableRowsFound || !lastCellEndsRow) {
- rowGroupBuilder.signalRowEnd(this);
- }
- try {
- rowGroupBuilder.signalEndOfPart(this);
- } catch (ValidationException e) {
- e.setLocator(locator);
- throw e;
+ if (!inMarker()) {
+ RowGroupBuilder rowGroupBuilder = getTable().getRowGroupBuilder();
+ if (tableRowsFound) {
+ rowGroupBuilder.endRow(lastRow);
+ } else if (!lastCellEndsRow) {
+ rowGroupBuilder.endRow(this);
+ }
+ try {
+ rowGroupBuilder.endTablePart(this);
+ } catch (ValidationException e) {
+ e.setLocator(locator);
+ throw e;
+ }
}
}
@@ -184,13 +194,19 @@ public class TableBody extends TableCellContainer {
if (!inMarker()) {
switch (child.getNameId()) {
case FO_TABLE_ROW:
- if (rowsStarted) {
+ if (!rowsStarted) {
+ getTable().getRowGroupBuilder().startTablePart(this);
+ } else {
columnNumberManager.prepareForNextRow(pendingSpans);
- getTable().getRowGroupBuilder().signalRowEnd(this);
+ getTable().getRowGroupBuilder().endRow(lastRow);
}
rowsStarted = true;
+ lastRow = (TableRow) child;
break;
case FO_TABLE_CELL:
+ if (!rowsStarted) {
+ getTable().getRowGroupBuilder().startTablePart(this);
+ }
rowsStarted = true;
TableCell cell = (TableCell) child;
addTableCellChild(cell, firstRow);
@@ -198,7 +214,7 @@ public class TableBody extends TableCellContainer {
if (lastCellEndsRow) {
firstRow = false;
columnNumberManager.prepareForNextRow(pendingSpans);
- getTable().getRowGroupBuilder().signalRowEnd(this);
+ getTable().getRowGroupBuilder().endRow(this);
}
break;
default:
@@ -208,11 +224,20 @@ public class TableBody extends TableCellContainer {
super.addChildNode(child);
}
+ /** {inheritDoc} */
+ protected void setCollapsedBorders() {
+ Table table = (Table) parent;
+ createBorder(CommonBorderPaddingBackground.START, table);
+ createBorder(CommonBorderPaddingBackground.END, table);
+ createBorder(CommonBorderPaddingBackground.BEFORE);
+ createBorder(CommonBorderPaddingBackground.AFTER);
+ }
+
void addRowGroup(List rowGroup) {
rowGroups.add(rowGroup);
}
- List getRowGroups() {
+ public List getRowGroups() {
return rowGroups;
}
@@ -235,6 +260,10 @@ public class TableBody extends TableCellContainer {
return FO_TABLE_BODY;
}
+ protected boolean isTableFooter() {
+ return false;
+ }
+
/**
* @param obj table row in question
* @return true if the given table row is the first row of this body.
@@ -249,7 +278,7 @@ public class TableBody extends TableCellContainer {
firstRow = false;
if (!lastCellEndsRow) {
columnNumberManager.prepareForNextRow(pendingSpans);
- getTable().getRowGroupBuilder().signalRowEnd(this);
+ getTable().getRowGroupBuilder().endRow(this);
}
}
rowsStarted = true;
diff --git a/src/java/org/apache/fop/fo/flow/table/TableCell.java b/src/java/org/apache/fop/fo/flow/table/TableCell.java
index 34c6266a7..f85d0e97e 100644
--- a/src/java/org/apache/fop/fo/flow/table/TableCell.java
+++ b/src/java/org/apache/fop/fo/flow/table/TableCell.java
@@ -90,7 +90,7 @@ public class TableCell extends TableFObj {
/**
* {@inheritDoc}
*/
- protected void startOfNode() throws FOPException {
+ public void startOfNode() throws FOPException {
super.startOfNode();
getFOEventHandler().startCell(this);
}
@@ -100,7 +100,7 @@ public class TableCell extends TableFObj {
* FOEventHandler that we are at the end of the flow.
* {@inheritDoc}
*/
- protected void endOfNode() throws FOPException {
+ public void endOfNode() throws FOPException {
if (!blockItemFound) {
if (getUserAgent().validateStrictly()) {
missingChildElementError("marker* (%block;)+");
@@ -135,6 +135,21 @@ public class TableCell extends TableFObj {
}
/** {@inheritDoc} */
+ protected void setCollapsedBorders() {
+ createBorder(CommonBorderPaddingBackground.BEFORE);
+ createBorder(CommonBorderPaddingBackground.AFTER);
+ Table table = getTable();
+ if (table.hasExplicitColumns()) {
+ TableColumn col = table.getColumn(getColumnNumber() - 1);
+ createBorder(CommonBorderPaddingBackground.START, col);
+ createBorder(CommonBorderPaddingBackground.END, col);
+ } else {
+ createBorder(CommonBorderPaddingBackground.START);
+ createBorder(CommonBorderPaddingBackground.END);
+ }
+ }
+
+ /** {@inheritDoc} */
public boolean generatesReferenceAreas() {
return true;
}
diff --git a/src/java/org/apache/fop/fo/flow/table/TableCellContainer.java b/src/java/org/apache/fop/fo/flow/table/TableCellContainer.java
index ebb066c5c..7c91be351 100644
--- a/src/java/org/apache/fop/fo/flow/table/TableCellContainer.java
+++ b/src/java/org/apache/fop/fo/flow/table/TableCellContainer.java
@@ -93,6 +93,13 @@ public abstract class TableCellContainer extends TableFObj implements ColumnNumb
}
}
+ /**
+ * Returns the enclosing table-header/footer/body of this container.
+ *
+ * @return <code>this</code> for TableBody, or the parent element for TableRow
+ */
+ abstract TableBody getTablePart();
+
/** {@inheritDoc} */
public ColumnNumberManager getColumnNumberManager() {
return columnNumberManager;
diff --git a/src/java/org/apache/fop/fo/flow/table/TableColumn.java b/src/java/org/apache/fop/fo/flow/table/TableColumn.java
index aa2dfcb0a..aeb401893 100644
--- a/src/java/org/apache/fop/fo/flow/table/TableColumn.java
+++ b/src/java/org/apache/fop/fo/flow/table/TableColumn.java
@@ -31,6 +31,7 @@ import org.apache.fop.fo.expr.PropertyException;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.Property;
import org.apache.fop.fo.properties.TableColLength;
+import org.apache.fop.layoutmgr.table.CollapsingBorderModel;
/**
* Class modelling the fo:table-column object.
@@ -114,14 +115,27 @@ public class TableColumn extends TableFObj {
/**
* {@inheritDoc}
*/
- protected void startOfNode() throws FOPException {
+ public void startOfNode() throws FOPException {
+ super.startOfNode();
getFOEventHandler().startColumn(this);
}
- /**
- * {@inheritDoc}
- */
- protected void endOfNode() throws FOPException {
+ void setCollapsedBorders(CollapsingBorderModel collapsingBorderModel) {
+ this.collapsingBorderModel = collapsingBorderModel;
+ setCollapsedBorders();
+ }
+
+ /** {@inheritDoc} */
+ protected void setCollapsedBorders() {
+ Table table = (Table) parent;
+ createBorder(CommonBorderPaddingBackground.BEFORE, table);
+ createBorder(CommonBorderPaddingBackground.AFTER, table);
+ createBorder(CommonBorderPaddingBackground.START);
+ createBorder(CommonBorderPaddingBackground.END);
+ }
+
+ /** {@inheritDoc} */
+ public void endOfNode() throws FOPException {
getFOEventHandler().endColumn(this);
}
diff --git a/src/java/org/apache/fop/fo/flow/table/TableFObj.java b/src/java/org/apache/fop/fo/flow/table/TableFObj.java
index 53995464b..984f242f2 100644
--- a/src/java/org/apache/fop/fo/flow/table/TableFObj.java
+++ b/src/java/org/apache/fop/fo/flow/table/TableFObj.java
@@ -30,6 +30,7 @@ import org.apache.fop.fo.expr.PropertyException;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.NumberProperty;
import org.apache.fop.fo.properties.Property;
+import org.apache.fop.layoutmgr.table.CollapsingBorderModel;
/**
* Common base class for table-related FOs
@@ -41,6 +42,10 @@ public abstract class TableFObj extends FObj {
private Numeric borderEndPrecedence;
private Numeric borderStartPrecedence;
+ public/*TODO*/ BorderSpecification[] resolvedBorders = new BorderSpecification[4]; // TODO
+
+ CollapsingBorderModel collapsingBorderModel;
+
/**
* Main constructor
*
@@ -122,9 +127,7 @@ public abstract class TableFObj extends FObj {
super(propId);
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public Property make(PropertyList propertyList)
throws PropertyException {
FObj fo = propertyList.getFObj();
@@ -189,4 +192,55 @@ public abstract class TableFObj extends FObj {
return p;
}
}
+
+ /** {@inheritDoc} */
+ public void startOfNode() throws FOPException {
+ super.startOfNode();
+ Table table = getTable();
+ if (!inMarker() && !table.isSeparateBorderModel()) {
+ collapsingBorderModel = CollapsingBorderModel.getBorderModelFor(table
+ .getBorderCollapse());
+ resolvedBorders = new BorderSpecification[4];
+ setCollapsedBorders();
+ }
+ }
+
+ /*
+ * TODO made public so that RetrieveMarker can access it.
+ */
+ /** {@inheritDoc} */
+ public void endOfNode() throws FOPException {
+ super.endOfNode();
+ }
+
+ /**
+ * Prepares the borders of this element if the collapsing-border model is in use.
+ * Conflict resolution with parent elements is done where applicable.
+ */
+ protected abstract void setCollapsedBorders();
+
+ /**
+ * Creates a BorderSpecification from the border set on the given side. If no border
+ * is set, a BorderSpecification with border-style none is created.
+ *
+ * @param side one of CommonBorderPaddingBackground.BEFORE|AFTER|START|END
+ */
+ protected void createBorder(int side) {
+ resolvedBorders[side] = new BorderSpecification(getCommonBorderPaddingBackground()
+ .getBorderInfo(side), getNameId());
+ }
+
+ /**
+ * Creates a BorderSpecification from the border set on the given side, performing
+ * conflict resolution with the same border on the given object.
+ *
+ * @param side one of CommonBorderPaddingBackground.BEFORE|AFTER|START|END
+ * @param competitor a parent table element whose side coincides with the given side
+ * on this element
+ */
+ protected void createBorder(int side, TableFObj competitor) {
+ createBorder(side);
+ resolvedBorders[side] = collapsingBorderModel.determineWinner(resolvedBorders[side],
+ competitor.resolvedBorders[side]);
+ }
}
diff --git a/src/java/org/apache/fop/fo/flow/table/TableFooter.java b/src/java/org/apache/fop/fo/flow/table/TableFooter.java
index a7ee21406..e886d2ee1 100644
--- a/src/java/org/apache/fop/fo/flow/table/TableFooter.java
+++ b/src/java/org/apache/fop/fo/flow/table/TableFooter.java
@@ -39,14 +39,15 @@ public class TableFooter extends TableBody {
/**
* {@inheritDoc}
*/
- protected void startOfNode() throws FOPException {
+ public void startOfNode() throws FOPException {
+ super.startOfNode();
//getFOEventHandler().startBody(this);
}
/**
* {@inheritDoc}
*/
- protected void endOfNode() throws FOPException {
+ public void endOfNode() throws FOPException {
// getFOEventHandler().endFooter(this);
if (!(tableRowsFound || tableCellsFound)) {
missingChildElementError("marker* (table-row+|table-cell+)");
@@ -65,4 +66,9 @@ public class TableFooter extends TableBody {
public int getNameId() {
return FO_TABLE_FOOTER;
}
+
+ /** {@inheritDoc} */
+ protected boolean isTableFooter() {
+ return true;
+ }
}
diff --git a/src/java/org/apache/fop/fo/flow/table/TableHeader.java b/src/java/org/apache/fop/fo/flow/table/TableHeader.java
index bc9d88952..01ada2aa7 100644
--- a/src/java/org/apache/fop/fo/flow/table/TableHeader.java
+++ b/src/java/org/apache/fop/fo/flow/table/TableHeader.java
@@ -39,14 +39,15 @@ public class TableHeader extends TableBody {
/**
* {@inheritDoc}
*/
- protected void startOfNode() throws FOPException {
+ public void startOfNode() throws FOPException {
+ super.startOfNode();
//getFOEventHandler().startHeader(this);
}
/**
* {@inheritDoc}
*/
- protected void endOfNode() throws FOPException {
+ public void endOfNode() throws FOPException {
// getFOEventHandler().endHeader(this);
if (!(tableRowsFound || tableCellsFound)) {
missingChildElementError("marker* (table-row+|table-cell+)");
diff --git a/src/java/org/apache/fop/fo/flow/table/TableRow.java b/src/java/org/apache/fop/fo/flow/table/TableRow.java
index edc8d13df..a025f92fd 100644
--- a/src/java/org/apache/fop/fo/flow/table/TableRow.java
+++ b/src/java/org/apache/fop/fo/flow/table/TableRow.java
@@ -97,7 +97,7 @@ public class TableRow extends TableCellContainer {
/**
* {@inheritDoc}
*/
- protected void startOfNode() throws FOPException {
+ public void startOfNode() throws FOPException {
super.startOfNode();
getFOEventHandler().startRow(this);
}
@@ -105,7 +105,7 @@ public class TableRow extends TableCellContainer {
/**
* {@inheritDoc}
*/
- protected void endOfNode() throws FOPException {
+ public void endOfNode() throws FOPException {
if (firstChild == null) {
missingChildElementError("(table-cell+)");
}
@@ -128,6 +128,25 @@ public class TableRow extends TableCellContainer {
}
}
+ /** {@inheritDoc} */
+ TableBody getTablePart() {
+ return (TableBody) parent;
+ }
+
+ /** {@inheritDoc} */
+ boolean isTableRow() {
+ return true;
+ }
+
+ /** {inheritDoc} */
+ protected void setCollapsedBorders() {
+ TableBody body = (TableBody) parent;
+ createBorder(CommonBorderPaddingBackground.START, body);
+ createBorder(CommonBorderPaddingBackground.END, body);
+ createBorder(CommonBorderPaddingBackground.BEFORE);
+ createBorder(CommonBorderPaddingBackground.AFTER);
+ }
+
/** @return the "break-after" property. */
public int getBreakAfter() {
return breakAfter;
diff --git a/src/java/org/apache/fop/fo/flow/table/VariableColRowGroupBuilder.java b/src/java/org/apache/fop/fo/flow/table/VariableColRowGroupBuilder.java
index 53b7bfca1..e35ad5c27 100644
--- a/src/java/org/apache/fop/fo/flow/table/VariableColRowGroupBuilder.java
+++ b/src/java/org/apache/fop/fo/flow/table/VariableColRowGroupBuilder.java
@@ -19,9 +19,12 @@
package org.apache.fop.fo.flow.table;
+import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
-import org.apache.fop.layoutmgr.table.EmptyGridUnit;
+import org.apache.fop.fo.ValidationException;
+
/**
* A row group builder accommodating a variable number of columns. More flexible, but less
@@ -31,34 +34,69 @@ class VariableColRowGroupBuilder extends RowGroupBuilder {
VariableColRowGroupBuilder(Table t) {
super(t);
- numberOfColumns = 1;
}
/**
- * Fills the given row group with empty grid units if necessary, so that it matches
- * the given number of columns.
- *
- * @param rowGroup a List of List of GridUnit
- * @param numberOfColumns the number of columns that the row group must have
+ * Each event is recorded and will be played once the table is finished, and the final
+ * number of columns known.
*/
- static void fillWithEmptyGridUnits(List rowGroup, int numberOfColumns) {
- for (int i = 0; i < rowGroup.size(); i++) {
- List effRow = (List) rowGroup.get(i);
- for (int j = effRow.size(); j < numberOfColumns; j++) {
- effRow.add(new EmptyGridUnit(null, null, null, j));
+ private static interface Event {
+ /**
+ * Plays this event
+ *
+ * @param rowGroupBuilder the delegate builder which will actually create the row
+ * groups
+ * @throws ValidationException if a row-spanning cell overflows its parent body
+ */
+ void play(RowGroupBuilder rowGroupBuilder) throws ValidationException;
+ }
+
+ /** The queue of events sent to this builder. */
+ private List events = new LinkedList();
+
+ /** {@inheritDoc} */
+ void addTableCell(final TableCell cell) {
+ events.add(new Event() {
+ public void play(RowGroupBuilder rowGroupBuilder) {
+ rowGroupBuilder.addTableCell(cell);
}
- }
+ });
}
- /**
- * Updates the current row group to match the given number of columns, by adding empty
- * grid units if necessary.
- *
- * @param numberOfColumns new number of columns
- */
- void ensureNumberOfColumns(int numberOfColumns) {
- this.numberOfColumns = numberOfColumns;
- fillWithEmptyGridUnits(rows, numberOfColumns);
+ /** {@inheritDoc} */
+ void endRow(final TableCellContainer container) {
+ events.add(new Event() {
+ public void play(RowGroupBuilder rowGroupBuilder) {
+ rowGroupBuilder.endRow(container);
+ }
+ });
}
+ /** {@inheritDoc} */
+ void startTablePart(final TableBody part) {
+ events.add(new Event() {
+ public void play(RowGroupBuilder rowGroupBuilder) {
+ rowGroupBuilder.startTablePart(part);
+ }
+ });
+ }
+
+ /** {@inheritDoc} */
+ void endTablePart(final TableBody tableBody) throws ValidationException {
+ // TODO catch the ValidationException sooner?
+ events.add(new Event() {
+ public void play(RowGroupBuilder rowGroupBuilder) throws ValidationException {
+ rowGroupBuilder.endTablePart(tableBody);
+ }
+ });
+ }
+
+ /** {@inheritDoc} */
+ void endTable(final TableBody lastTablePart) throws ValidationException {
+ RowGroupBuilder delegate = new FixedColRowGroupBuilder(table);
+ for (Iterator eventIter = events.iterator(); eventIter.hasNext();) {
+ ((Event) eventIter.next()).play(delegate);
+ }
+ delegate.endTable(lastTablePart);
+ }
}
diff --git a/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java b/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java
index d021ec922..114dadb94 100755
--- a/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java
+++ b/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java
@@ -83,7 +83,7 @@ public class CommonBorderPaddingBackground {
private Color mColor; // Border color
private CondLengthProperty mWidth;
- BorderInfo(int style, CondLengthProperty width, Color color) {
+ public BorderInfo(int style, CondLengthProperty width, Color color) {
mStyle = style;
mWidth = width;
mColor = color;
@@ -227,7 +227,11 @@ public class CommonBorderPaddingBackground {
* @return the border info for a side
*/
public BorderInfo getBorderInfo(int side) {
- return this.borderInfo[side];
+ if (this.borderInfo[side] == null) {
+ return new BorderInfo(Constants.EN_NONE, null, null); // TODO
+ } else {
+ return this.borderInfo[side];
+ }
}
/**
diff --git a/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModel.java b/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModel.java
index 5c60ee6fd..5cfe5e382 100644
--- a/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModel.java
+++ b/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModel.java
@@ -20,8 +20,8 @@
package org.apache.fop.layoutmgr.table;
import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.flow.table.BorderSpecification;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
-import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo;
/**
* This class is a superclass for the two collapsing border models defined
@@ -37,10 +37,7 @@ public abstract class CollapsingBorderModel {
protected static final int START = CommonBorderPaddingBackground.START;
/** end side */
protected static final int END = CommonBorderPaddingBackground.END;
-
- /** Flag: current grid unit is either start or end of the table. */
- public static final int VERTICAL_START_END_OF_TABLE = 1;
-
+
/** Indicates that the cell is/starts in the first row being painted on a particular page */
//public static final int FIRST_ROW_IN_TABLE_PART = 1;
/** Indicates that the cell is/ends in the last row being painted on a particular page */
@@ -53,7 +50,7 @@ public abstract class CollapsingBorderModel {
//These statics are used singleton-style. No MT issues here.
private static CollapsingBorderModel collapse = null;
private static CollapsingBorderModel collapseWithPrecedence = null;
-
+
/**
* @param borderCollapse border collapse control
* @return the border model for the cell
@@ -74,12 +71,12 @@ public abstract class CollapsingBorderModel {
throw new IllegalArgumentException("Illegal border-collapse mode.");
}
}
-
+
/**
* @param side the side on the current cell
* @return the adjacent side on the neighbouring cell
*/
- public static int getOtherSide(int side) {
+ static int getOtherSide(int side) {
switch (side) {
case CommonBorderPaddingBackground.BEFORE:
return CommonBorderPaddingBackground.AFTER;
@@ -93,23 +90,32 @@ public abstract class CollapsingBorderModel {
throw new IllegalArgumentException("Illegal parameter: side");
}
}
-
+
/**
* @param side the side to investigate
* @return true if the adjacent cell is before or after
*/
protected boolean isVerticalRelation(int side) {
- return (side == CommonBorderPaddingBackground.BEFORE
+ return (side == CommonBorderPaddingBackground.BEFORE
|| side == CommonBorderPaddingBackground.AFTER);
}
-
+ private static int compareInt(int value1, int value2) {
+ if (value1 < value2) {
+ return -1;
+ } else if (value1 == value2) {
+ return 0;
+ } else {
+ return 1;
+ }
+ }
+
/**
* See rule 4 in 6.7.10 for the collapsing border model.
* @param style the border style to get the preference value for
* @return the preference value of the style
*/
- public int getPreferenceValue(int style) {
+ private static int getStylePreferenceValue(int style) {
switch (style) {
case Constants.EN_DOUBLE: return 0;
case Constants.EN_SOLID: return -1;
@@ -122,14 +128,62 @@ public abstract class CollapsingBorderModel {
default: throw new IllegalStateException("Illegal border style: " + style);
}
}
-
+
+ /**
+ * Compares the two given styles (see {@link Constants}).
+ *
+ * @param style1 a style constant
+ * @param style2 another style constant
+ * @return a value &lt; 0 if style1 has less priority than style2, 0 if both are
+ * equal, a value &gt; 0 if style1 has more priority than style2
+ */
+ static int compareStyles(int style1, int style2) {
+ int value1 = getStylePreferenceValue(style1);
+ int value2 = getStylePreferenceValue(style2);
+ return compareInt(value1, value2);
+ }
+
+ private static int getHolderPreferenceValue(int id) {
+ switch (id) {
+ case Constants.FO_TABLE_CELL: return 0;
+ case Constants.FO_TABLE_ROW: return -1;
+ case Constants.FO_TABLE_HEADER:
+ case Constants.FO_TABLE_FOOTER:
+ case Constants.FO_TABLE_BODY:
+ return -2;
+ case Constants.FO_TABLE_COLUMN: return -3;
+ // TODO colgroup
+ case Constants.FO_TABLE: return -4;
+ default: throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Compares the two given FO ids ({@link Constants}.FO*) in terms of border
+ * declaration.
+ *
+ * @param id1 a FO id ({@link Constants#FO_TABLE}, {@link Constants#FO_TABLE_BODY},
+ * etc.)
+ * @param id2 another FO id
+ * @return a value &lt; 0 if id1 has less priority than id2, 0 if both are equal, a
+ * value &gt; 0 if id1 has more priority than id2
+ */
+ static int compareFOs(int id1, int id2) {
+ int p1 = getHolderPreferenceValue(id1);
+ int p2 = getHolderPreferenceValue(id2);
+ return compareInt(p1, p2);
+ }
+
/**
- * Determines the winning BorderInfo.
- * @param current grid unit of the current element
- * @param neighbour grid unit of the neighbouring element
- * @return the winning BorderInfo
+ * Returns the border which wins the border conflict resolution. In case the two
+ * borders are equivalent (identical, or only the color is different), null is
+ * returned.
+ *
+ * @param border1 a border specification
+ * @param border2 another border specification
+ * @return the winning border, null if the two borders are equivalent
*/
- public abstract BorderInfo determineWinner(
- GridUnit current, GridUnit neighbour, int side, int flags);
-
+ public abstract BorderSpecification determineWinner(BorderSpecification border1,
+ BorderSpecification border2);
+
}
diff --git a/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModelEyeCatching.java b/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModelEyeCatching.java
index ddbb20c47..5f979c986 100644
--- a/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModelEyeCatching.java
+++ b/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModelEyeCatching.java
@@ -20,11 +20,7 @@
package org.apache.fop.layoutmgr.table;
import org.apache.fop.fo.Constants;
-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.flow.table.BorderSpecification;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo;
/**
@@ -34,268 +30,45 @@ import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo;
*/
public class CollapsingBorderModelEyeCatching extends CollapsingBorderModel {
- public BorderInfo determineWinner(GridUnit currentGridUnit,
- GridUnit otherGridUnit, int side, int flags) {
- final boolean vertical = isVerticalRelation(side);
- final int otherSide = getOtherSide(side);
-
- //Get cells
- TableCell currentCell = currentGridUnit.getCell();
- TableCell otherCell = null;
- if (otherGridUnit != null) {
- otherCell = otherGridUnit.getCell();
- }
-
- //Get rows
- TableRow currentRow = currentGridUnit.getRow();
- TableRow otherRow = null;
- if (vertical && otherCell != null) {
- otherRow = otherGridUnit.getRow();
- }
-
- //get bodies
- TableBody currentBody = currentGridUnit.getBody();
- TableBody otherBody = null;
- if (otherRow != null) {
- otherBody = otherGridUnit.getBody();
- }
-
- //get columns
- TableColumn currentColumn = currentGridUnit.getColumn();
- TableColumn otherColumn = null;
- if (otherGridUnit != null) {
- otherColumn = otherGridUnit.getColumn();
- }
-
- //TODO get column groups
-
- //Get table
- Table table = currentGridUnit.getTable();
-
- //----------------------------------------------------------------------
- //We're creating two arrays containing the applicable BorderInfos for
- //each cell in question.
- //0 = cell, 1 = row, 2 = row group (body), 3 = column,
- //4 = col group (spanned column, see 6.7.3), 5 = table
-
- BorderInfo[] current = new BorderInfo[6];
- BorderInfo[] other = new BorderInfo[6];
- //cell
- current[0] = currentGridUnit.getOriginalBorderInfoForCell(side);
- if (otherGridUnit != null) {
- other[0] = otherGridUnit.getOriginalBorderInfoForCell(otherSide);
- }
- if ((currentRow != null)
- && (side == BEFORE
- || side == AFTER
- || (currentGridUnit.getFlag(GridUnit.IN_FIRST_COLUMN) && side == START)
- || (currentGridUnit.getFlag(GridUnit.IN_LAST_COLUMN) && side == END))) {
- //row
- current[1] = currentRow.getCommonBorderPaddingBackground().getBorderInfo(side);
- }
- if (otherRow != null) {
- //row
- other[1] = otherRow.getCommonBorderPaddingBackground().getBorderInfo(otherSide);
- }
- if (currentBody != null
- && ((side == BEFORE && currentGridUnit.getFlag(GridUnit.FIRST_IN_PART))
- || (side == AFTER && currentGridUnit.getFlag(GridUnit.LAST_IN_PART))
- || (currentGridUnit.getFlag(GridUnit.IN_FIRST_COLUMN) && side == START)
- || (currentGridUnit.getFlag(GridUnit.IN_LAST_COLUMN) && side == END))) {
- //row group (=body, table-header or table-footer)
- current[2] = currentBody.getCommonBorderPaddingBackground().getBorderInfo(side);
- }
- if (otherGridUnit != null
- && otherBody != null
- && ((otherSide == BEFORE && otherGridUnit.getFlag(GridUnit.FIRST_IN_PART))
- || (otherSide == AFTER && otherGridUnit.getFlag(GridUnit.LAST_IN_PART)))) {
- //row group (=body, table-header or table-footer)
- other[2] = otherBody.getCommonBorderPaddingBackground().getBorderInfo(otherSide);
- }
- if ((side == BEFORE && otherGridUnit == null)
- || (side == AFTER && otherGridUnit == null)
- || (side == START)
- || (side == END)) {
- //column
- current[3] = currentColumn.getCommonBorderPaddingBackground().getBorderInfo(side);
- }
- if (otherColumn != null) {
- //column
- other[3] = otherColumn.getCommonBorderPaddingBackground().getBorderInfo(otherSide);
- }
- //TODO current[4] and other[4] for column groups
- if (otherGridUnit == null
- && ((side == BEFORE && (flags & VERTICAL_START_END_OF_TABLE) > 0)
- || (side == AFTER && (flags & VERTICAL_START_END_OF_TABLE) > 0)
- || (side == START)
- || (side == END))) {
- //table
- current[5] = table.getCommonBorderPaddingBackground().getBorderInfo(side);
- }
- //other[6] is always null, since it's always the same table
-
- BorderInfo resolved = null;
-
- // *** Rule 1 ***
- resolved = doRule1(current, other);
- if (resolved != null) {
- return resolved;
- }
-
- // *** Rule 2 ***
- if (!doRule2(current, other)) {
- }
-
- // *** Rule 3 ***
- resolved = doRule3(current, other);
- if (resolved != null) {
- return resolved;
- }
-
- // *** Rule 4 ***
- resolved = doRule4(current, other);
- if (resolved != null) {
- return resolved;
- }
-
- // *** Rule 5 ***
- resolved = doRule5(current, other);
- if (resolved != null) {
- return resolved;
- }
-
- return null; //no winner, no border
- }
-
- private BorderInfo doRule1(BorderInfo[] current, BorderInfo[] other) {
- for (int i = 0; i < current.length; i++) {
- if ((current[i] != null) && (current[i].getStyle() == Constants.EN_HIDDEN)) {
- return current[i];
- }
- if ((other[i] != null) && (other[i].getStyle() == Constants.EN_HIDDEN)) {
- return other[i];
- }
- }
- return null;
- }
-
- private boolean doRule2(BorderInfo[] current, BorderInfo[] other) {
- boolean found = false;
- for (int i = 0; i < current.length; i++) {
- if ((current[i] != null) && (current[i].getStyle() != Constants.EN_NONE)) {
- found = true;
- break;
+ /** {@inheritDoc} */
+ public BorderSpecification determineWinner(BorderSpecification border1,
+ BorderSpecification border2) {
+ BorderInfo bi1 = border1.getBorderInfo();
+ BorderInfo bi2 = border2.getBorderInfo();
+ // Rule 1
+ if (bi1.getStyle() == Constants.EN_HIDDEN) {
+ return border1;
+ } else if (bi2.getStyle() == Constants.EN_HIDDEN) {
+ return border2;
+ }
+ // Rule 2
+ if (bi2.getStyle() == Constants.EN_NONE) {
+ return border1;
+ } else if (bi1.getStyle() == Constants.EN_NONE) {
+ return border2;
+ }
+ // Rule 3
+ int width1 = bi1.getRetainedWidth();
+ int width2 = bi2.getRetainedWidth();
+ if (width1 > width2) {
+ return border1;
+ } else if (width1 == width2) {
+ int cmp = compareStyles(bi1.getStyle(), bi2.getStyle());
+ if (cmp > 0) {
+ return border1;
+ } else if (cmp < 0) {
+ return border2;
}
- if ((other[i] != null) && (other[i].getStyle() != Constants.EN_NONE)) {
- found = true;
- break;
- }
- }
- return found;
- }
-
- private BorderInfo doRule3(BorderInfo[] current, BorderInfo[] other) {
- int width = 0;
- //Find max border width
- for (int i = 0; i < current.length; i++) {
- if ((current[i] != null) && (current[i].getRetainedWidth() > width)) {
- width = current[i].getRetainedWidth();
- }
- if ((other[i] != null) && (other[i].getRetainedWidth() > width)) {
- width = other[i].getRetainedWidth();
- }
- }
- BorderInfo widest = null;
- int count = 0;
- //See if there's only one with the widest border
- for (int i = 0; i < current.length; i++) {
- if ((current[i] != null) && (current[i].getRetainedWidth() == width)) {
- count++;
- if (widest == null) {
- widest = current[i];
- }
- } else {
- current[i] = null; //Discard the narrower ones
- }
- if ((other[i] != null) && (other[i].getRetainedWidth() == width)) {
- count++;
- if (widest == null) {
- widest = other[i];
- }
- } else {
- other[i] = null; //Discard the narrower ones
- }
- }
- if (count == 1) {
- return widest;
} else {
- return null;
+ return border2;
}
- }
-
- private BorderInfo doRule4(BorderInfo[] current, BorderInfo[] other) {
- int pref = getPreferenceValue(Constants.EN_INSET); //Lowest preference
- //Find highest preference value
- for (int i = 0; i < current.length; i++) {
- if (current[i] != null) {
- int currPref = getPreferenceValue(current[i].getStyle());
- if (currPref > pref) {
- pref = currPref;
- }
- }
- if (other[i] != null) {
- int currPref = getPreferenceValue(other[i].getStyle());
- if (currPref > pref) {
- pref = currPref;
- }
- }
- }
- BorderInfo preferred = null;
- int count = 0;
- //See if there's only one with the preferred border style
- for (int i = 0; i < current.length; i++) {
- if (current[i] != null) {
- int currPref = getPreferenceValue(current[i].getStyle());
- if (currPref == pref) {
- count++;
- if (preferred == null) {
- preferred = current[i];
- }
- break;
- }
- } else {
- current[i] = null; //Discard the ones that are not preferred
- }
- if (other[i] != null) {
- int currPref = getPreferenceValue(other[i].getStyle());
- if (currPref == pref) {
- count++;
- if (preferred == null) {
- preferred = other[i];
- }
- break;
- }
- } else {
- other[i] = null; //Discard the ones that are not preferred
- }
- }
- if (count == 1) {
- return preferred;
- } else {
- return null;
- }
- }
-
- private BorderInfo doRule5(BorderInfo[] current, BorderInfo[] other) {
- for (int i = 0; i < current.length; i++) {
- if (current[i] != null) {
- return current[i];
- }
- if (other[i] != null) {
- return other[i];
- }
+ // Rule 4
+ int cmp = compareFOs(border1.getHolder(), border2.getHolder());
+ if (cmp > 0) {
+ return border1;
+ } else if (cmp < 0) {
+ return border2;
}
return null;
}
-
}
diff --git a/src/java/org/apache/fop/layoutmgr/table/EffRow.java b/src/java/org/apache/fop/layoutmgr/table/EffRow.java
index 1e4924a5a..fe57809e9 100644
--- a/src/java/org/apache/fop/layoutmgr/table/EffRow.java
+++ b/src/java/org/apache/fop/layoutmgr/table/EffRow.java
@@ -47,12 +47,14 @@ class EffRow {
* Creates a new effective row instance.
* @param index index of the row
* @param bodyType type of body (one of HEADER, FOOTER, BODY as found on TableRowIterator)
+ * @param gridUnits the grid units this row is made of
*/
- public EffRow(int index, int bodyType) {
+ public EffRow(int index, int bodyType, List gridUnits) {
this.index = index;
this.bodyType = bodyType;
+ this.gridUnits = gridUnits;
}
-
+
/** @return the index of the EffRow in the sequence of rows */
public int getIndex() {
return this.index;
diff --git a/src/java/org/apache/fop/layoutmgr/table/EmptyGridUnit.java b/src/java/org/apache/fop/layoutmgr/table/EmptyGridUnit.java
index 5c208b84b..50500c498 100644
--- a/src/java/org/apache/fop/layoutmgr/table/EmptyGridUnit.java
+++ b/src/java/org/apache/fop/layoutmgr/table/EmptyGridUnit.java
@@ -19,9 +19,12 @@
package org.apache.fop.layoutmgr.table;
+import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.flow.table.BorderSpecification;
+import org.apache.fop.fo.flow.table.Table;
import org.apache.fop.fo.flow.table.TableBody;
-import org.apache.fop.fo.flow.table.TableColumn;
import org.apache.fop.fo.flow.table.TableRow;
+import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
/**
* GridUnit subclass for empty grid units.
@@ -30,25 +33,34 @@ public class EmptyGridUnit extends GridUnit {
private TableRow row;
private TableBody body;
-
+
/**
- * @param row Optional table-row instance
- * @param column table-column instance
- * @param body table-body the grid unit belongs to
- * @param startCol column index
+ * @param table the containing table
+ * @param startRow index of the row this grid unit belongs to, 0-based
+ * @param startCol column index, 0-based
*/
- public EmptyGridUnit(TableRow row, TableColumn column, TableBody body,
- int startCol) {
- super(null, null, column, startCol, 0);
- this.row = row;
- this.body = body;
+ public EmptyGridUnit(Table table, int startRow, int startCol) {
+ super(table, table.getColumn(startCol), startCol, 0, 0);
}
-
+
+ /** {@inheritDoc} */
+ protected void setBorder(int side) {
+ resolvedBorders[side] = new BorderSpecification(
+ new CommonBorderPaddingBackground.BorderInfo(Constants.EN_NONE, null, null),
+ Constants.FO_TABLE_CELL);
+ }
+
+ /** {@inheritDoc} */
+ public PrimaryGridUnit getPrimary() {
+ throw new UnsupportedOperationException();
+// return this; TODO
+ }
+
/** {@inheritDoc} */
public boolean isPrimary() {
return true;
}
-
+
/** {@inheritDoc} */
public TableBody getBody() {
return this.body;
@@ -58,4 +70,14 @@ public class EmptyGridUnit extends GridUnit {
public TableRow getRow() {
return this.row;
}
+
+ /** {@inheritDoc} */
+ public boolean isLastGridUnitColSpan() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ public boolean isLastGridUnitRowSpan() {
+ return true;
+ }
}
diff --git a/src/java/org/apache/fop/layoutmgr/table/GridUnit.java b/src/java/org/apache/fop/layoutmgr/table/GridUnit.java
index 79b2cca9e..7f713351f 100644
--- a/src/java/org/apache/fop/layoutmgr/table/GridUnit.java
+++ b/src/java/org/apache/fop/layoutmgr/table/GridUnit.java
@@ -22,10 +22,12 @@ package org.apache.fop.layoutmgr.table;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.flow.table.BorderSpecification;
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.TableFObj;
import org.apache.fop.fo.flow.table.TableRow;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo;
@@ -39,81 +41,142 @@ public class GridUnit {
/** Indicates that the grid unit is in the first column. */
public static final int IN_FIRST_COLUMN = 0;
+
/** Indicates that the grid unit is in the last column. */
public static final int IN_LAST_COLUMN = 1;
+
/** Indicates that the grid unit is in the first row of the table. */
public static final int FIRST_IN_TABLE = 2;
- /** Indicates that the grid unit is in the first row of the table part (header, footer, body). */
+
+ /**
+ * Indicates that the grid unit is in the first row of the table part (header, footer,
+ * body).
+ */
public static final int FIRST_IN_PART = 3;
- /** Indicates that the grid unit is in the last row of the table part (header, footer, body). */
+
+ /**
+ * Indicates that the grid unit is in the last row of the table part (header, footer,
+ * body).
+ */
public static final int LAST_IN_PART = 4;
+
/** Indicates that the grid unit is in the last row of the table. */
public static final int LAST_IN_TABLE = 5;
+
/** Indicates that the primary grid unit has a pending keep-with-next. */
public static final int KEEP_WITH_NEXT_PENDING = 6;
+
/** Indicates that the primary grid unit has a pending keep-with-previous. */
public static final int KEEP_WITH_PREVIOUS_PENDING = 7;
/** Primary grid unit */
private PrimaryGridUnit primary;
+
/** Table cell which occupies this grid unit */
- private TableCell cell;
+ protected TableCell cell;
+
/** Table row which occupies this grid unit (may be null) */
private TableRow row;
+
/** Table column that this grid unit belongs to */
private TableColumn column;
/** start index of grid unit within row in column direction */
private int startCol;
+
/** index of grid unit within cell in column direction */
private int colSpanIndex;
+
/** index of grid unit within cell in row direction */
private int rowSpanIndex;
+
/** effective borders for a cell slot */
private CommonBorderPaddingBackground effectiveBorders;
+
/** flags for the grid unit */
private byte flags = 0;
+ protected BorderSpecification[] resolvedBorders;
+
+ private CollapsingBorderModel collapsingBorderModel;
/**
* Creates a new grid unit.
- *
- * @param cell table cell which occupies this grid unit
+ *
+ * @param table the containing table
* @param column table column this grid unit belongs to
* @param startCol index of the column this grid unit belongs to
* @param colSpanIndex index of this grid unit in the span, in column direction
+ * @param rowSpanIndex index of this grid unit in the span, in row direction
*/
- public GridUnit(TableCell cell, TableColumn column, int startCol, int colSpanIndex) {
- this(null, cell, column, startCol, colSpanIndex);
+ protected GridUnit(Table table, TableColumn column, int startCol, int colSpanIndex,
+ int rowSpanIndex) {
+ this(column, startCol, colSpanIndex, rowSpanIndex);
+ setBorders(table);
}
/**
* Creates a new grid unit.
- *
- * @param primary the before-start grid unit of the cell containing this grid unit
+ *
+ * @param cell table cell which occupies this grid unit
* @param column table column this grid unit belongs to
* @param startCol index of the column this grid unit belongs to
* @param colSpanIndex index of this grid unit in the span, in column direction
+ * @param rowSpanIndex index of this grid unit in the span, in row direction
*/
- public GridUnit(PrimaryGridUnit primary, TableColumn column, int startCol, int colSpanIndex) {
- this(primary, primary.getCell(), column, startCol, colSpanIndex);
+ protected GridUnit(TableCell cell, TableColumn column, int startCol, int colSpanIndex,
+ int rowSpanIndex) {
+ this(column, startCol, colSpanIndex, rowSpanIndex);
+ this.cell = cell;
+ setBorders(cell.getTable());
}
/**
* Creates a new grid unit.
- *
+ *
* @param primary the before-start grid unit of the cell containing this grid unit
- * @param cell table cell which occupies this grid unit
* @param column table column this grid unit belongs to
* @param startCol index of the column this grid unit belongs to
* @param colSpanIndex index of this grid unit in the span, in column direction
+ * @param rowSpanIndex index of this grid unit in the span, in row direction
*/
- protected GridUnit(PrimaryGridUnit primary, TableCell cell, TableColumn column, int startCol, int colSpanIndex) {
+ public GridUnit(PrimaryGridUnit primary, TableColumn column, int startCol, int colSpanIndex,
+ int rowSpanIndex) {
+ this(primary.getCell(), column, startCol, colSpanIndex, rowSpanIndex);
this.primary = primary;
- this.cell = cell;
+ }
+
+ private GridUnit(TableColumn column, int startCol, int colSpanIndex, int rowSpanIndex) {
this.column = column;
this.startCol = startCol;
this.colSpanIndex = colSpanIndex;
+ this.rowSpanIndex = rowSpanIndex;
+ }
+
+ private void setBorders(Table table/*TODO*/) {
+ if (table.isSeparateBorderModel()) {
+ assignBorderForSeparateBorderModel();
+ } else {
+ resolvedBorders = new BorderSpecification[4];
+ collapsingBorderModel = CollapsingBorderModel.getBorderModelFor(table
+ .getBorderCollapse());
+ if (rowSpanIndex == 0) {
+ setBorder(CommonBorderPaddingBackground.BEFORE);
+ }
+ if (isLastGridUnitRowSpan()) {
+ setBorder(CommonBorderPaddingBackground.AFTER);
+ }
+ if (colSpanIndex == 0) {
+ setBorder(CommonBorderPaddingBackground.START);
+ }
+ if (isLastGridUnitColSpan()) {
+ setBorder(CommonBorderPaddingBackground.END);
+ }
+ }
+ }
+
+ protected void setBorder(int side) {
+ resolvedBorders[side] = cell.resolvedBorders[side];
}
public TableCell getCell() {
@@ -128,7 +191,7 @@ public class GridUnit {
if (row != null) {
return row;
} else if (getCell().getParent() instanceof TableRow) {
- return (TableRow)getCell().getParent();
+ return (TableRow) getCell().getParent();
} else {
return null;
}
@@ -136,6 +199,7 @@ public class GridUnit {
/**
* Sets the table-row FO, if applicable.
+ *
* @param row the table-row FO
*/
public void setRow(TableRow row) {
@@ -147,18 +211,7 @@ public class GridUnit {
while (node != null && !(node instanceof TableBody)) {
node = node.getParent();
}
- return (TableBody)node;
- }
-
- public Table getTable() {
- FONode node = getBody();
- while (node != null && !(node instanceof Table)) {
- node = node.getParent();
- }
- if (node == null && getColumn() != null) {
- node = getColumn().getParent();
- }
- return (Table)node;
+ return (TableBody) node;
}
/**
@@ -167,7 +220,7 @@ public class GridUnit {
* @return the before-start grid unit of the cell containing this grid unit.
*/
public PrimaryGridUnit getPrimary() {
- return (isPrimary() ? (PrimaryGridUnit)this : primary);
+ return primary;
}
/**
@@ -194,20 +247,12 @@ public class GridUnit {
/** @return true if the grid unit is the last in column spanning direction */
public boolean isLastGridUnitColSpan() {
- if (cell != null) {
- return (colSpanIndex == cell.getNumberColumnsSpanned() - 1);
- } else {
- return true;
- }
+ return (colSpanIndex == cell.getNumberColumnsSpanned() - 1);
}
/** @return true if the grid unit is the last in row spanning direction */
public boolean isLastGridUnitRowSpan() {
- if (cell != null) {
- return (rowSpanIndex == cell.getNumberRowsSpanned() - 1);
- } else {
- return true;
- }
+ return (rowSpanIndex == cell.getNumberRowsSpanned() - 1);
}
/**
@@ -225,9 +270,10 @@ public class GridUnit {
}
/**
- * Returns a BorderInfo instance for a side of the currently applicable cell before border
- * resolution (i.e. the value from the FO). A return value of null indicates an empty cell.
- * See CollapsingBorderModel(EyeCatching) where this method is used.
+ * Returns a BorderInfo instance for a side of the currently applicable cell before
+ * border resolution (i.e. the value from the FO). A return value of null indicates an
+ * empty cell. See CollapsingBorderModel(EyeCatching) where this method is used.
+ *
* @param side for which side to return the BorderInfo
* @return the requested BorderInfo instance or null if the grid unit is an empty cell
*/
@@ -243,9 +289,33 @@ public class GridUnit {
* @return the resolved normal borders for this grid unit
*/
public CommonBorderPaddingBackground getBorders() {
+ // TODO
+ if (effectiveBorders == null) {
+ effectiveBorders = new CommonBorderPaddingBackground();
+ setBorderInfo(CommonBorderPaddingBackground.BEFORE);
+ setBorderInfo(CommonBorderPaddingBackground.AFTER);
+ setBorderInfo(CommonBorderPaddingBackground.START);
+ setBorderInfo(CommonBorderPaddingBackground.END);
+ if (cell != null) {
+ effectiveBorders.setPadding(cell.getCommonBorderPaddingBackground());
+ }
+ if (log.isDebugEnabled()) {
+ log.debug(this + " resolved borders: " + "before="
+ + effectiveBorders.getBorderBeforeWidth(false) + ", " + "after="
+ + effectiveBorders.getBorderAfterWidth(false) + ", " + "start="
+ + effectiveBorders.getBorderStartWidth(false) + ", " + "end="
+ + effectiveBorders.getBorderEndWidth(false));
+ }
+ }
return effectiveBorders;
}
+ private void setBorderInfo(int side) {
+ if (resolvedBorders[side] != null) {
+ effectiveBorders.setBorderInfo(resolvedBorders[side].getBorderInfo(), side);
+ }
+ }
+
/**
* @return true if the grid unit has any borders.
*/
@@ -254,8 +324,8 @@ public class GridUnit {
}
/**
- * Assigns the borders from the given cell to this cell info. Used in
- * case of separate border model.
+ * Assigns the borders from the given cell to this cell info. Used in case of separate
+ * border model.
*/
public void assignBorderForSeparateBorderModel() {
if (cell != null) {
@@ -264,42 +334,39 @@ public class GridUnit {
}
/**
- * Resolve collapsing borders for the given cell. Used in case of the collapsing border model.
- * @param other neighbouring grid unit if any
- * @param side the side to resolve (one of CommonBorderPaddingBackground.BEFORE|AFTER|START|END)
+ * Resolve collapsing borders for the given cell. Used in case of the collapsing
+ * border model.
+ *
+ * @param other neighbouring grid unit
+ * @param side the side to resolve (one of
+ * CommonBorderPaddingBackground.BEFORE|AFTER|START|END)
*/
public void resolveBorder(GridUnit other, int side) {
- resolveBorder(other, side, 0);
+ BorderSpecification resolvedBorder = collapsingBorderModel.determineWinner(
+ resolvedBorders[side], other.resolvedBorders[CollapsingBorderModel
+ .getOtherSide(side)]);
+ if (resolvedBorder != null) {
+ this.resolvedBorders[side] = resolvedBorder;
+ other.resolvedBorders[CollapsingBorderModel.getOtherSide(side)] = resolvedBorder;
+ }
}
/**
- * Resolve collapsing borders for the given cell. Used in case of the collapsing border model.
- * @param other neighbouring grid unit if any
- * @param side the side to resolve (one of CommonBorderPaddingBackground.BEFORE|AFTER|START|END)
- * @param resFlags flags for the border resolution
+ * Resolves the border on the given side of this grid unit, comparing it against the
+ * same border of the given parent element.
+ *
+ * @param side the side to resolve (one of
+ * CommonBorderPaddingBackground.BEFORE|AFTER|START|END)
+ * @param parent the parent element holding a competing border
*/
- public void resolveBorder(GridUnit other, int side, int resFlags) {
- CollapsingBorderModel borderModel = CollapsingBorderModel.getBorderModelFor(
- getTable().getBorderCollapse());
- if (effectiveBorders == null) {
- effectiveBorders = new CommonBorderPaddingBackground();
- }
- effectiveBorders.setBorderInfo(borderModel.determineWinner(this, other,
- side, resFlags), side);
- if (cell != null) {
- effectiveBorders.setPadding(cell.getCommonBorderPaddingBackground());
- }
- if (log.isDebugEnabled()) {
- log.debug(this + " resolved borders: "
- + "before=" + effectiveBorders.getBorderBeforeWidth(false) + ", "
- + "after=" + effectiveBorders.getBorderAfterWidth(false) + ", "
- + "start=" + effectiveBorders.getBorderStartWidth(false) + ", "
- + "end=" + effectiveBorders.getBorderEndWidth(false));
- }
+ public void resolveBorder(int side, TableFObj parent) {
+ resolvedBorders[side] = collapsingBorderModel.determineWinner(resolvedBorders[side],
+ parent.resolvedBorders[side]);
}
/**
* Returns a flag for this GridUnit.
+ *
* @param which the requested flag
* @return the value of the flag
*/
@@ -309,29 +376,25 @@ public class GridUnit {
/**
* Sets a flag on a GridUnit.
+ *
* @param which the flag to set
* @param value the new value for the flag
*/
public void setFlag(int which, boolean value) {
if (value) {
- flags |= (1 << which); //set flag
+ flags |= (1 << which); // set flag
} else {
- flags &= ~(1 << which); //clear flag
+ flags &= ~(1 << which); // clear flag
}
}
/**
- * @return the grid unit just below this grid unit if the cell is spanning.
+ * Sets the given flag on this grid unit.
+ *
+ * @param which the flag to set
*/
- public GridUnit createNextRowSpanningGridUnit() {
- if (isLastGridUnitRowSpan()) {
- return null;
- } else {
- //cloning the current GridUnit with adjustments
- GridUnit gu = new GridUnit(getPrimary(), getColumn(), startCol, colSpanIndex);
- gu.rowSpanIndex = rowSpanIndex + 1;
- return gu;
- }
+ public void setFlag(int which) {
+ setFlag(which, true);
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/layoutmgr/table/PrimaryGridUnit.java b/src/java/org/apache/fop/layoutmgr/table/PrimaryGridUnit.java
index ece022556..34daf7d96 100644
--- a/src/java/org/apache/fop/layoutmgr/table/PrimaryGridUnit.java
+++ b/src/java/org/apache/fop/layoutmgr/table/PrimaryGridUnit.java
@@ -55,18 +55,22 @@ public class PrimaryGridUnit extends GridUnit {
* @param startRow index of the row this grid unit belongs to, zero-based
*/
public PrimaryGridUnit(TableCell cell, TableColumn column, int startCol, int startRow) {
- super(cell, column, startCol, 0);
+ super(cell, column, startCol, 0, 0);
this.startRow = startRow;
log.trace("PrimaryGridUnit created, row " + startRow + " col " + startCol);
- if (cell != null) {
- cellLM = new TableCellLayoutManager(cell, this);
- }
}
public TableCellLayoutManager getCellLM() {
+ assert cellLM != null;
return cellLM;
}
+ /** {@inheritDoc} */
+ public PrimaryGridUnit getPrimary() {
+ return this;
+ }
+
+ /** {@inheritDoc} */
public boolean isPrimary() {
return true;
}
@@ -225,4 +229,12 @@ public class PrimaryGridUnit extends GridUnit {
|| (getCell().getNumberRowsSpanned() > 1);
}
+ /**
+ * Creates a cellLM for the corresponding table-cell. A new one must be created
+ * for each new static-content (TODO).
+ */
+ public void createCellLM() {
+ cellLM = new TableCellLayoutManager(cell, this);
+ }
+
}
diff --git a/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java
index 4dd42110f..c7776ff7b 100644
--- a/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java
@@ -97,10 +97,6 @@ class RowGroupLayoutManager {
public LinkedList getNextKnuthElements(LayoutContext context, int alignment, int bodyType) {
LinkedList returnList = new LinkedList();
- //Border resolution
- if (!tableLM.getTable().isSeparateBorderModel()) {
- resolveNormalBeforeAfterBordersForRowGroup();
- }
//Reset keep-with-next when remaining inside the table.
//The context flag is only used to propagate keep-with-next to the outside.
@@ -134,107 +130,6 @@ class RowGroupLayoutManager {
}
/**
- * Resolves normal borders for a row group.
- * @param iter Table row iterator to operate on
- */
- private void resolveNormalBeforeAfterBordersForRowGroup() {
- for (int rgi = 0; rgi < rowGroup.length; rgi++) {
- EffRow row = rowGroup[rgi];
- EffRow prevRow = thisIter.getPrecedingRow(row);
- EffRow nextRow = thisIter.getFollowingRow(row);
- if ((prevRow == null) && (thisIter == bodyIter) && (headerIter != null)) {
- prevRow = headerIter.getLastRow();
- }
- if ((nextRow == null) && (thisIter == headerIter)) {
- nextRow = bodyIter.getFirstRow();
- }
- if ((nextRow == null) && (thisIter == bodyIter) && (footerIter != null)) {
- nextRow = footerIter.getFirstRow();
- }
- if ((prevRow == null) && (thisIter == footerIter)) {
- //TODO This could be bad for memory consumption because it already causes the
- //whole body iterator to be prefetched!
- prevRow = bodyIter.getLastRow();
- }
- log.debug("prevRow-row-nextRow: " + prevRow + " - " + row + " - " + nextRow);
-
- //Determine the grid units necessary for getting all the borders right
- int guCount = row.getGridUnits().size();
- if (prevRow != null) {
- guCount = Math.max(guCount, prevRow.getGridUnits().size());
- }
- if (nextRow != null) {
- guCount = Math.max(guCount, nextRow.getGridUnits().size());
- }
- GridUnit gu = row.getGridUnit(0);
- //Create empty grid units to hold resolved borders of neighbouring cells
- //TODO maybe this needs to be done differently (and sooner)
- for (int i = 0; i < guCount - row.getGridUnits().size(); i++) {
- //TODO This block is untested!
- int pos = row.getGridUnits().size() + i;
- row.getGridUnits().add(new EmptyGridUnit(gu.getRow(),
- tableLM.getColumns().getColumn(pos + 1), gu.getBody(),
- pos));
- }
-
- //Now resolve normal borders
- if (tableLM.getTable().isSeparateBorderModel()) {
- //nop, borders are already assigned at this point
- } else {
- for (int i = 0; i < row.getGridUnits().size(); i++) {
- gu = row.getGridUnit(i);
- GridUnit other;
- int flags = 0;
- if (prevRow != null && i < prevRow.getGridUnits().size()) {
- other = prevRow.getGridUnit(i);
- } else {
- other = null;
- }
- if (other == null
- || other.isEmpty()
- || gu.isEmpty()
- || gu.getPrimary() != other.getPrimary()) {
- if ((thisIter == bodyIter)
- && gu.getFlag(GridUnit.FIRST_IN_TABLE)
- && (headerIter == null)) {
- flags |= CollapsingBorderModel.VERTICAL_START_END_OF_TABLE;
- }
- if ((thisIter == headerIter)
- && gu.getFlag(GridUnit.FIRST_IN_TABLE)) {
- flags |= CollapsingBorderModel.VERTICAL_START_END_OF_TABLE;
- }
- gu.resolveBorder(other,
- CommonBorderPaddingBackground.BEFORE, flags);
- }
-
- flags = 0;
- if (nextRow != null && i < nextRow.getGridUnits().size()) {
- other = nextRow.getGridUnit(i);
- } else {
- other = null;
- }
- if (other == null
- || other.isEmpty()
- || gu.isEmpty()
- || gu.getPrimary() != other.getPrimary()) {
- if ((thisIter == bodyIter)
- && gu.getFlag(GridUnit.LAST_IN_TABLE)
- && (footerIter == null)) {
- flags |= CollapsingBorderModel.VERTICAL_START_END_OF_TABLE;
- }
- if ((thisIter == footerIter)
- && gu.getFlag(GridUnit.LAST_IN_TABLE)) {
- flags |= CollapsingBorderModel.VERTICAL_START_END_OF_TABLE;
- }
- gu.resolveBorder(other,
- CommonBorderPaddingBackground.AFTER, flags);
- }
- }
- }
- }
- }
-
- /**
* Creates Knuth elements for a row group (see TableRowIterator.getNextRowGroup()).
* @param context Active LayoutContext
* @param alignment alignment indicator
@@ -271,6 +166,7 @@ class RowGroupLayoutManager {
PrimaryGridUnit primary = gu.getPrimary();
if (gu.isPrimary()) {
+ primary.createCellLM(); // TODO a new LM must be created for every new static-content
primary.getCellLM().setParent(tableLM);
//Determine the table-row if any
diff --git a/src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java b/src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java
index dfac329a8..3acde70d3 100644
--- a/src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java
+++ b/src/java/org/apache/fop/layoutmgr/table/TableRowIterator.java
@@ -20,11 +20,14 @@
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.Table;
import org.apache.fop.fo.flow.table.TableBody;
@@ -98,6 +101,8 @@ public class TableRowIterator {
/** 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
@@ -110,19 +115,23 @@ public class TableRowIterator {
this.tablePart = tablePart;
switch(tablePart) {
case HEADER: {
- List bodyList = new java.util.ArrayList();
- bodyList.add(table.getTableHeader());
- this.tablePartIterator = bodyList.listIterator();
+ rowGroupsIter = table.getTableHeader().getRowGroups().iterator();
break;
}
case FOOTER: {
- List bodyList = new java.util.ArrayList();
- bodyList.add(table.getTableFooter());
- this.tablePartIterator = bodyList.listIterator();
+ rowGroupsIter = table.getTableFooter().getRowGroups().iterator();
break;
}
default: {
- this.tablePartIterator = table.getChildNodes();
+ List rowGroupsList = new LinkedList();
+ // TODO this is ugly
+ for (FONodeIterator iter = table.getChildNodes(); iter.hasNext();) {
+ FONode node = iter.nextNode();
+ if (node instanceof TableBody) {
+ rowGroupsList.addAll(((TableBody) node).getRowGroups());
+ }
+ }
+ rowGroupsIter = rowGroupsList.iterator();
}
}
}
@@ -132,38 +141,19 @@ public class TableRowIterator {
* consecutive rows which contains all spanned grid units of its cells.
* @return the next row group, or null
*/
- public EffRow[] getNextRowGroup() {
- EffRow firstRowInGroup = getNextRow();
- if (firstRowInGroup == null) {
+ EffRow[] getNextRowGroup() {
+ if (!rowGroupsIter.hasNext()) {
return null;
}
- EffRow lastRowInGroup = firstRowInGroup;
- int lastIndex = lastRowInGroup.getIndex();
- boolean allFinished;
- do {
- allFinished = true;
- Iterator iter = lastRowInGroup.getGridUnits().iterator();
- while (iter.hasNext()) {
- GridUnit gu = (GridUnit)iter.next();
- if (!gu.isLastGridUnitRowSpan()) {
- allFinished = false;
- break;
- }
- }
- lastIndex = lastRowInGroup.getIndex();
- if (!allFinished) {
- lastRowInGroup = getNextRow();
- if (lastRowInGroup == null) {
- allFinished = true;
- }
- }
- } while (!allFinished);
- int rowCount = lastIndex - firstRowInGroup.getIndex() + 1;
- EffRow[] rowGroup = new EffRow[rowCount];
- for (int i = 0; i < rowCount; i++) {
- rowGroup[i] = getCachedRow(i + firstRowInGroup.getIndex());
+ List rowGroup = (List) rowGroupsIter.next();
+ EffRow[] effRowGroup = new EffRow[rowGroup.size()];
+ int i = 0;
+ for (Iterator rowIter = rowGroup.iterator(); rowIter.hasNext();) {
+ List gridUnits = (List) rowIter.next();
+ effRowGroup[i] = new EffRow(i, tablePart, gridUnits);
+ i++;
}
- return rowGroup;
+ return effRowGroup;
}
/**
@@ -197,7 +187,7 @@ public class TableRowIterator {
* @return the preceding row, or null if there is no such row (the given row is the
* first one in the table part)
*/
- public EffRow getPrecedingRow(EffRow row) {
+ EffRow getPrecedingRow(EffRow row) {
return getRow(row.getIndex() - 1);
}
@@ -207,7 +197,7 @@ public class TableRowIterator {
* @param row a row in the iterated table part
* @return the following row, or null if there is no more row
*/
- public EffRow getFollowingRow(EffRow row) {
+ EffRow getFollowingRow(EffRow row) {
return getRow(row.getIndex() + 1);
}
@@ -215,7 +205,7 @@ public class TableRowIterator {
* Returns the first effective row.
* @return the requested effective row.
*/
- public EffRow getFirstRow() {
+ EffRow getFirstRow() {
if (fetchedRows.size() == 0) {
prefetchNext();
}
@@ -228,7 +218,7 @@ public class TableRowIterator {
* if preloaded.</p>
* @return the requested effective row.
*/
- public EffRow getLastRow() {
+ EffRow getLastRow() {
while (prefetchNext()) {
//nop
}
@@ -377,7 +367,7 @@ public class TableRowIterator {
* @return the list of grid units
*/
private EffRow buildGridRow(List cells, TableRow rowFO) {
- EffRow row = new EffRow(this.fetchIndex, tablePart);
+ EffRow row = new EffRow(this.fetchIndex, tablePart, null);
List gridUnits = row.getGridUnits();
TableBody bodyFO = null;
@@ -393,7 +383,8 @@ public class TableRowIterator {
if (gu.getColSpanIndex() == 0) {
horzSpan = new GridUnit[gu.getCell().getNumberColumnsSpanned()];
}
- GridUnit newGU = gu.createNextRowSpanningGridUnit();
+// GridUnit newGU = gu.createNextRowSpanningGridUnit();
+ GridUnit newGU = null;
newGU.setRow(rowFO);
safelySetListItem(gridUnits, colnum - 1, newGU);
horzSpan[newGU.getColSpanIndex()] = newGU;
@@ -455,7 +446,7 @@ public class TableRowIterator {
horzSpan[0] = gu;
for (int j = 1; j < cell.getNumberColumnsSpanned(); j++) {
colnum++;
- GridUnit guSpan = new GridUnit(gu, columns.getColumn(colnum), colnum - 1, j);
+ 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) {
@@ -486,29 +477,29 @@ public class TableRowIterator {
}
//Post-processing the list (looking for gaps and resolve start and end borders)
- fillEmptyGridUnits(gridUnits, rowFO, bodyFO);
+// 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 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++) {