aboutsummaryrefslogtreecommitdiffstats
path: root/src/java
diff options
context:
space:
mode:
authorVincent Hennebert <vhennebert@apache.org>2007-10-30 16:21:39 +0000
committerVincent Hennebert <vhennebert@apache.org>2007-10-30 16:21:39 +0000
commit67295b556093f78416cce975060e678b94b054d0 (patch)
treefda965b47dd8a8cb13a52bad4cfb200c134059de /src/java
parent4800e08fe7dc2da4312a5229e5c6910796667771 (diff)
downloadxmlgraphics-fop-67295b556093f78416cce975060e678b94b054d0.tar.gz
xmlgraphics-fop-67295b556093f78416cce975060e678b94b054d0.zip
- factored the management of column numbers into a separate helper class
- moved the PendingSpan inner class from TableFObj into TableCellContainer, where it's a bit more appropriate - simplified the getTable method in TableFObj by overriding it in Table - simplified the propertyMaker for column-number: now it's the table-cell which notifies the parent table-body that it starts a new row. As an additional benefit the propertyMaker for starts-row is now called only once, instead of twice before - reworked, factored and simplified the handling of column indices in TableCellContainer - bugfix: repeated fo:table-column were not added at the right place in the column lists - bugfix: width set on cell on second row was applied to the column's width, whereas it shouldn't - checkstyle cleanup git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@590136 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java')
-rw-r--r--src/java/org/apache/fop/fo/expr/FromTableColumnFunction.java16
-rw-r--r--src/java/org/apache/fop/fo/flow/ColumnNumberManager.java116
-rw-r--r--src/java/org/apache/fop/fo/flow/ColumnNumberManagerHolder.java35
-rw-r--r--src/java/org/apache/fop/fo/flow/Table.java203
-rw-r--r--src/java/org/apache/fop/fo/flow/TableBody.java217
-rw-r--r--src/java/org/apache/fop/fo/flow/TableCell.java29
-rw-r--r--src/java/org/apache/fop/fo/flow/TableCellContainer.java157
-rw-r--r--src/java/org/apache/fop/fo/flow/TableColumn.java49
-rw-r--r--src/java/org/apache/fop/fo/flow/TableFObj.java142
-rw-r--r--src/java/org/apache/fop/fo/flow/TableRow.java96
10 files changed, 437 insertions, 623 deletions
diff --git a/src/java/org/apache/fop/fo/expr/FromTableColumnFunction.java b/src/java/org/apache/fop/fo/expr/FromTableColumnFunction.java
index 8b14a0c64..651f93451 100644
--- a/src/java/org/apache/fop/fo/expr/FromTableColumnFunction.java
+++ b/src/java/org/apache/fop/fo/expr/FromTableColumnFunction.java
@@ -23,6 +23,7 @@ import java.util.List;
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.FOPropertyMapping;
+import org.apache.fop.fo.flow.ColumnNumberManager;
import org.apache.fop.fo.flow.Table;
import org.apache.fop.fo.flow.TableCell;
import org.apache.fop.fo.flow.TableColumn;
@@ -61,9 +62,9 @@ public class FromTableColumnFunction extends FunctionBase {
*/
public Property eval(Property[] args,
PropertyInfo pInfo) throws PropertyException {
-
+
FObj fo = pInfo.getPropertyList().getFObj();
-
+
/* obtain property Id for the property for which the function is being
* evaluated */
int propId = 0;
@@ -73,7 +74,7 @@ public class FromTableColumnFunction extends FunctionBase {
String propName = args[0].getString();
propId = FOPropertyMapping.getPropertyId(propName);
}
-
+
/* make sure we have a correct property id ... */
if (propId != -1) {
/* obtain column number for which the function is being evaluated: */
@@ -81,7 +82,7 @@ public class FromTableColumnFunction extends FunctionBase {
int span = 0;
if (fo.getNameId() != Constants.FO_TABLE_CELL) {
// climb up to the nearest cell
- do {
+ do {
fo = (FObj) fo.getParent();
} while (fo.getNameId() != Constants.FO_TABLE_CELL
&& fo.getNameId() != Constants.FO_PAGE_SEQUENCE);
@@ -105,19 +106,20 @@ public class FromTableColumnFunction extends FunctionBase {
/* return the property from the column */
Table t = ((TableFObj) fo).getTable();
List cols = t.getColumns();
+ ColumnNumberManager columnIndexManager = t.getColumnNumberManager();
if (cols == null) {
//no columns defined => no match: return default value
return pInfo.getPropertyList().get(propId, false, true);
} else {
- if (t.isColumnNumberUsed(columnNumber)) {
+ if (columnIndexManager.isColumnNumberUsed(columnNumber)) {
//easiest case: exact match
return ((TableColumn) cols.get(columnNumber - 1)).getProperty(propId);
} else {
//no exact match: try all spans...
- while (--span > 0 && !t.isColumnNumberUsed(++columnNumber)) {
+ while (--span > 0 && !columnIndexManager.isColumnNumberUsed(++columnNumber)) {
//nop: just increment/decrement
}
- if (t.isColumnNumberUsed(columnNumber)) {
+ if (columnIndexManager.isColumnNumberUsed(columnNumber)) {
return ((TableColumn) cols.get(columnNumber - 1)).getProperty(propId);
} else {
//no match: return default value
diff --git a/src/java/org/apache/fop/fo/flow/ColumnNumberManager.java b/src/java/org/apache/fop/fo/flow/ColumnNumberManager.java
new file mode 100644
index 000000000..bc31440ea
--- /dev/null
+++ b/src/java/org/apache/fop/fo/flow/ColumnNumberManager.java
@@ -0,0 +1,116 @@
+/*
+ * 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;
+
+import java.util.BitSet;
+import java.util.List;
+
+import org.apache.fop.fo.flow.TableCellContainer.PendingSpan;
+
+/**
+ * Helper class maintaining a record of occupied columns and an index to the next
+ * non-occupied column.
+ */
+public class ColumnNumberManager {
+
+ private int columnNumber = 1;
+
+ /**
+ * We use the term "index" instead of "number" because, unlike column numbers, it's
+ * 0-based.
+ */
+ private BitSet usedColumnIndices = new BitSet();
+
+ /**
+ * Returns the number of the column that shall receive the next parsed cell.
+ *
+ * @return a column number, 1-based
+ */
+ int getCurrentColumnNumber() {
+ return columnNumber;
+ }
+
+ /**
+ * Flags columns <code>start</code> to <code>end</code> as occupied,
+ * and updates the number of the next available column.
+ *
+ * @param start start number, inclusive, 1-based
+ * @param end end number, inclusive
+ */
+ void signalUsedColumnNumbers(int start, int end) {
+ for (int i = start - 1; i < end; i++) {
+ usedColumnIndices.set(i);
+ }
+
+ while (usedColumnIndices.get(columnNumber - 1)) {
+ columnNumber++;
+ }
+ }
+
+ /**
+ * Resets the record of occupied columns, taking into account columns already occupied
+ * by previous spanning cells, and computes the number of the first free column.
+ *
+ * @param pendingSpans List&lt;PendingSpan&gt; of possible spans over the next row
+ */
+ void prepareForNextRow(List pendingSpans) {
+ usedColumnIndices.clear();
+ PendingSpan pSpan;
+ for (int i = 0; i < pendingSpans.size(); i++) {
+ pSpan = (PendingSpan) pendingSpans.get(i);
+ if (pSpan != null) {
+ pSpan.rowsLeft--;
+ if (pSpan.rowsLeft == 0) {
+ pendingSpans.set(i, null);
+ } else {
+ usedColumnIndices.set(i);
+ }
+ }
+ }
+ // Set columnNumber to the first available column
+ columnNumber = 1;
+ while (usedColumnIndices.get(columnNumber - 1)) {
+ columnNumber++;
+ }
+}
+
+ /**
+ * Checks whether a given column-number is already in use
+ * for the current row.
+ *
+ * @param colNr the column-number to check
+ * @return true if column-number is already occupied
+ */
+ public boolean isColumnNumberUsed(int colNr) {
+ return usedColumnIndices.get(colNr - 1);
+ }
+
+ /**
+ * Sets the current column index to a specific value
+ * (used by ColumnNumberPropertyMaker.make() in case the
+ * column-number was explicitly specified on the cell)
+ *
+ * @param newIndex the new column index
+ */
+ void setCurrentColumnIndex(int newIndex) {
+ columnNumber = newIndex;
+ }
+
+}
diff --git a/src/java/org/apache/fop/fo/flow/ColumnNumberManagerHolder.java b/src/java/org/apache/fop/fo/flow/ColumnNumberManagerHolder.java
new file mode 100644
index 000000000..157ca749f
--- /dev/null
+++ b/src/java/org/apache/fop/fo/flow/ColumnNumberManagerHolder.java
@@ -0,0 +1,35 @@
+/*
+ * 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;
+
+/**
+ * Marking interface for table-related classes which contain a ColumnNumberManager
+ * instance (Table, for registering columns, or TableCellContainer, for managing occupied
+ * cells).
+ */
+public interface ColumnNumberManagerHolder {
+
+ /**
+ * Returns the encapsulated ColumnNumberManage instance.
+ *
+ * @return a {@link ColumnNumberManager} instance
+ */
+ ColumnNumberManager getColumnNumberManager();
+}
diff --git a/src/java/org/apache/fop/fo/flow/Table.java b/src/java/org/apache/fop/fo/flow/Table.java
index e8f607012..7bc2d49ec 100644
--- a/src/java/org/apache/fop/fo/flow/Table.java
+++ b/src/java/org/apache/fop/fo/flow/Table.java
@@ -20,11 +20,8 @@
package org.apache.fop.fo.flow;
import java.util.ArrayList;
-import java.util.BitSet;
import java.util.List;
-import org.xml.sax.Locator;
-
import org.apache.fop.apps.FOPException;
import org.apache.fop.datatypes.Length;
import org.apache.fop.datatypes.ValidationPercentBaseContext;
@@ -38,12 +35,13 @@ import org.apache.fop.fo.properties.CommonMarginBlock;
import org.apache.fop.fo.properties.KeepProperty;
import org.apache.fop.fo.properties.LengthPairProperty;
import org.apache.fop.fo.properties.LengthRangeProperty;
+import org.xml.sax.Locator;
/**
* Class modelling the fo:table object.
*/
-public class Table extends TableFObj {
-
+public class Table extends TableFObj implements ColumnNumberManagerHolder {
+
/** properties */
private CommonBorderPaddingBackground commonBorderPaddingBackground;
private CommonMarginBlock commonMarginBlock;
@@ -65,35 +63,33 @@ public class Table extends TableFObj {
// private CommonRelativePosition commonRelativePosition;
// private int intrusionDisplace;
// private int writingMode;
-
+
/** extension properties */
private Length widowContentLimit;
private Length orphanContentLimit;
/** collection of columns in this table */
private List columns = new ArrayList();
-
- /** helper variables for implicit column-numbering */
- private int columnIndex = 1;
- private BitSet usedColumnIndices = new BitSet();
-
+
+ private ColumnNumberManager columnNumberManager = new ColumnNumberManager();
+
/** the table-header and -footer */
private TableBody tableHeader = null;
private TableBody tableFooter = null;
-
+
/** used for validation */
private boolean tableColumnFound = false;
- private boolean tableHeaderFound = false;
- private boolean tableFooterFound = false;
- private boolean tableBodyFound = false;
+ private boolean tableHeaderFound = false;
+ private boolean tableFooterFound = false;
+ private boolean tableBodyFound = false;
/**
- * The table's property list. Used in case the table has
- * no explicit columns, as a parent property list to
+ * The table's property list. Used in case the table has
+ * no explicit columns, as a parent property list to
* internally generated TableColumns
*/
private PropertyList propList;
-
+
/**
* @param parent FONode that is the parent of this object
*/
@@ -133,7 +129,7 @@ public class Table extends TableFObj {
if (tableLayout == EN_AUTO) {
attributeWarning("table-layout=\"auto\" is currently not supported by FOP");
}
- if (!isSeparateBorderModel()
+ if (!isSeparateBorderModel()
&& getCommonBorderPaddingBackground().hasPadding(
ValidationPercentBaseContext.getPseudoContext())) {
//See "17.6.2 The collapsing border model" in CSS2
@@ -141,7 +137,7 @@ public class Table extends TableFObj {
+ " (see http://www.w3.org/TR/REC-CSS2/tables.html#collapsing-borders)"
+ ", but a non-zero value for padding was found. The padding will be ignored.");
}
-
+
/* Store reference to the property list, so
* new lists can be created in case the table has no
* explicit columns
@@ -157,24 +153,24 @@ public class Table extends TableFObj {
super.startOfNode();
getFOEventHandler().startTable(this);
}
-
+
/**
* {@inheritDoc}
* XSL Content Model: (marker*,table-column*,table-header?,table-footer?,table-body+)
*/
- protected void validateChildNode(Locator loc, String nsURI, String localName)
+ protected void validateChildNode(Locator loc, String nsURI, String localName)
throws ValidationException {
if (FO_URI.equals(nsURI)) {
if ("marker".equals(localName)) {
- if (tableColumnFound || tableHeaderFound || tableFooterFound
+ if (tableColumnFound || tableHeaderFound || tableFooterFound
|| tableBodyFound) {
- nodesOutOfOrderError(loc, "fo:marker",
+ nodesOutOfOrderError(loc, "fo:marker",
"(table-column*,table-header?,table-footer?,table-body+)");
}
} else if ("table-column".equals(localName)) {
tableColumnFound = true;
if (tableHeaderFound || tableFooterFound || tableBodyFound) {
- nodesOutOfOrderError(loc, "fo:table-column",
+ nodesOutOfOrderError(loc, "fo:table-column",
"(table-header?,table-footer?,table-body+)");
}
} else if ("table-header".equals(localName)) {
@@ -183,8 +179,8 @@ public class Table extends TableFObj {
} else {
tableHeaderFound = true;
if (tableFooterFound || tableBodyFound) {
- nodesOutOfOrderError(loc, "fo:table-header",
- "(table-footer?,table-body+)");
+ nodesOutOfOrderError(loc, "fo:table-header",
+ "(table-footer?,table-body+)");
}
}
} else if ("table-footer".equals(localName)) {
@@ -193,7 +189,7 @@ public class Table extends TableFObj {
} else {
tableFooterFound = true;
if (tableBodyFound && getUserAgent().validateStrictly()) {
- nodesOutOfOrderError(loc, "fo:table-footer",
+ nodesOutOfOrderError(loc, "fo:table-footer",
"(table-body+)");
}
}
@@ -211,7 +207,7 @@ public class Table extends TableFObj {
* {@inheritDoc}
*/
protected void endOfNode() throws FOPException {
-
+
if (!tableBodyFound) {
missingChildElementError(
"(marker*,table-column*,table-header?,table-footer?"
@@ -228,16 +224,16 @@ public class Table extends TableFObj {
this.propList = null;
}
getFOEventHandler().endTable(this);
-
+
}
/**
* {@inheritDoc}
*/
protected void addChildNode(FONode child) throws FOPException {
-
+
int childId = child.getNameId();
-
+
switch (childId) {
case FO_TABLE_COLUMN:
if (!inMarker()) {
@@ -246,33 +242,32 @@ public class Table extends TableFObj {
columns.add((TableColumn) child);
}
return;
- case FO_MARKER:
- super.addChildNode(child);
- return;
+ case FO_TABLE_FOOTER:
+ tableFooter = (TableBody) child;
+ break;
+ case FO_TABLE_HEADER:
+ tableHeader = (TableBody) child;
+ break;
default:
- switch (childId) {
- case FO_TABLE_FOOTER:
- tableFooter = (TableBody) child;
- break;
- case FO_TABLE_HEADER:
- tableHeader = (TableBody) child;
- break;
- default:
- super.addChildNode(child);
- }
+ super.addChildNode(child);
}
}
-
+
+ /** {@inheritDoc} */
+ public Table getTable() {
+ return this;
+ }
+
/**
- * Adds a default column to the columns list (called from
- * TableBody.addChildNode() when the table has no explicit
+ * Adds a default column to the columns list (called from
+ * TableBody.addChildNode() when the table has no explicit
* columns, and if processing the first row)
*
* @param colWidth the column's width (null if the default should be used)
* @param colNr the column-number from the cell
* @throws FOPException if there was an error creating the property list
*/
- protected void addDefaultColumn(Length colWidth, int colNr)
+ void addDefaultColumn(Length colWidth, int colNr)
throws FOPException {
TableColumn defaultColumn = new TableColumn(this, true);
PropertyList pList = new StaticPropertyList(
@@ -293,38 +288,29 @@ public class Table extends TableFObj {
* used for determining initial values for column-number
*
* @param col the column to add
- * @throws FOPException
+ * @throws FOPException
*/
private void addColumnNode(TableColumn col) {
-
+
int colNumber = col.getColumnNumber();
int colRepeat = col.getNumberColumnsRepeated();
-
- if (columns.size() < colNumber) {
- /* add nulls for non-occupied indices between
- /* the last column up to and including the current one
- */
- while (columns.size() < colNumber) {
- columns.add(null);
- }
+
+ /* add nulls for non-occupied indices between
+ * the last column up to and including the current one
+ */
+ while (columns.size() < colNumber + colRepeat - 1) {
+ columns.add(null);
}
-
- /* replace the null-value with the actual column */
- columns.set(colNumber - 1, col);
-
- if (colRepeat > 1) {
- //in case column is repeated:
- //for the time being, add the same column
- //(colRepeat - 1) times to the columns list
- //TODO: need to force the column-number (?)
- for (int i = colRepeat - 1; --i >= 0;) {
- columns.add(col);
- }
+
+ // in case column is repeated:
+ // for the time being, add the same column
+ // (colRepeat - 1) times to the columns list
+ // TODO: need to force the column-number (?)
+ for (int i = colNumber - 1; i < colNumber + colRepeat - 1; i++) {
+ columns.set(i, col);
}
- //flag column indices used by this column
- int startIndex = columnIndex - 1;
- int endIndex = startIndex + colRepeat;
- flagColumnIndices(startIndex, endIndex);
+
+ columnNumberManager.signalUsedColumnNumbers(colNumber, colNumber + colRepeat - 1);
}
/** @return true of table-layout="auto" */
@@ -345,7 +331,7 @@ public class Table extends TableFObj {
* Returns the column at the given index, if any.
*
* @param index index of the column to be retrieved, 0-based
- * @return the corresponding column, or null if their is no column at the given index
+ * @return the corresponding column, or null if their is no column at the given index
*/
TableColumn getColumn(int index) {
if (index >= columns.size()) {
@@ -355,6 +341,11 @@ public class Table extends TableFObj {
}
}
+ /**
+ * Returns the number of columns of this table.
+ *
+ * @return the number of columns, implicit or explicit, in this table
+ */
int getNumberOfColumns() {
return columns.size();
}
@@ -368,7 +359,7 @@ public class Table extends TableFObj {
public TableBody getTableFooter() {
return tableFooter;
}
-
+
/** @return true if the table-header should be omitted at breaks */
public boolean omitHeaderAtBreak() {
return (this.tableOmitHeaderAtBreak == EN_TRUE);
@@ -392,7 +383,7 @@ public class Table extends TableFObj {
public LengthRangeProperty getBlockProgressionDimension() {
return blockProgressionDimension;
}
-
+
/**
* @return the Common Margin Properties-Block.
*/
@@ -440,7 +431,7 @@ public class Table extends TableFObj {
return !getKeepTogether().getWithinPage().isAuto()
|| !getKeepTogether().getWithinColumn().isAuto();
}
-
+
/** @return the "border-collapse" property. */
public int getBorderCollapse() {
return borderCollapse;
@@ -450,12 +441,12 @@ public class Table extends TableFObj {
public boolean isSeparateBorderModel() {
return (getBorderCollapse() == EN_SEPARATE);
}
-
+
/** @return the "border-separation" property. */
public LengthPairProperty getBorderSeparation() {
return borderSeparation;
}
-
+
/** @return the "fox:widow-content-limit" extension property */
public Length getWidowContentLimit() {
return widowContentLimit;
@@ -477,50 +468,7 @@ public class Table extends TableFObj {
}
/**
- * Returns the current column index of the Table
- *
- * @return the next column number to use
- */
- public int getCurrentColumnIndex() {
- return columnIndex;
- }
-
- /**
- * Checks if a certain column-number is already occupied
- *
- * @param colNr the column-number to check
- * @return true if column-number is already in use
- */
- public boolean isColumnNumberUsed(int colNr) {
- return usedColumnIndices.get(colNr - 1);
- }
-
- /**
- * Sets the current column index of the given Table
- * (used by ColumnNumberPropertyMaker.make() in case the column-number
- * was explicitly specified)
- *
- * @param newIndex the new value for column index
- */
- public void setCurrentColumnIndex(int newIndex) {
- columnIndex = newIndex;
- }
-
- /**
- * {@inheritDoc}
- */
- protected void flagColumnIndices(int start, int end) {
- for (int i = start; i < end; i++) {
- usedColumnIndices.set(i);
- }
- //set index for the next column to use
- while (usedColumnIndices.get(columnIndex - 1)) {
- columnIndex++;
- }
- }
-
- /**
- * {@inheritDoc}
+ * {@inheritDoc}
*/
public FONode clone(FONode parent, boolean removeChildren)
throws FOPException {
@@ -533,4 +481,9 @@ public class Table extends TableFObj {
}
return fobj;
}
+
+ /** {@inheritDoc} */
+ public ColumnNumberManager getColumnNumberManager() {
+ return columnNumberManager;
+ }
}
diff --git a/src/java/org/apache/fop/fo/flow/TableBody.java b/src/java/org/apache/fop/fo/flow/TableBody.java
index cef5c78a1..e18675aa0 100644
--- a/src/java/org/apache/fop/fo/flow/TableBody.java
+++ b/src/java/org/apache/fop/fo/flow/TableBody.java
@@ -20,18 +20,13 @@
package org.apache.fop.fo.flow;
// Java
-import java.util.BitSet;
-import java.util.List;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.Locator;
-
import org.apache.fop.apps.FOPException;
-import org.apache.fop.datatypes.Length;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.ValidationException;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
/**
* Class modelling the fo:table-body object.
@@ -45,21 +40,20 @@ public class TableBody extends TableCellContainer {
// private CommonRelativePosition commonRelativePosition;
// private int visibility;
// End of property values
-
+
/**
* used for validation
*/
protected boolean tableRowsFound = false;
protected boolean tableCellsFound = false;
-
+
/**
* used for initial values of column-number property
*/
- protected List pendingSpans;
- protected BitSet usedColumnIndices;
- private int columnIndex = 1;
- protected boolean firstRow = true;
-
+ private boolean firstRow = true;
+
+ private boolean rowsStarted = false;
+
/**
* @param parent FONode that is the parent of the object
*/
@@ -74,12 +68,12 @@ public class TableBody extends TableCellContainer {
commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
super.bind(pList);
}
-
+
/**
- * {@inheritDoc}
+ * {@inheritDoc}
*/
- public void processNode(String elementName, Locator locator,
- Attributes attlist, PropertyList pList)
+ public void processNode(String elementName, Locator locator,
+ Attributes attlist, PropertyList pList)
throws FOPException {
if (!inMarker()) {
int cap = getTable().getNumberOfColumns();
@@ -87,8 +81,7 @@ public class TableBody extends TableCellContainer {
cap = 10; // Default value for ArrayList
}
pendingSpans = new java.util.ArrayList(cap);
- usedColumnIndices = new java.util.BitSet(cap);
- setNextColumnIndex();
+ columnNumberManager = new ColumnNumberManager();
}
super.processNode(elementName, locator, attlist, pList);
}
@@ -104,14 +97,14 @@ public class TableBody extends TableCellContainer {
* {@inheritDoc}
*/
protected void endOfNode() throws FOPException {
-
+
if (!inMarker()) {
pendingSpans = null;
- usedColumnIndices = null;
+ columnNumberManager = null;
}
-
+
getFOEventHandler().endBody(this);
-
+
if (!(tableRowsFound || tableCellsFound)) {
if (getUserAgent().validateStrictly()) {
missingChildElementError("marker* (table-row+|table-cell+)");
@@ -120,14 +113,14 @@ public class TableBody extends TableCellContainer {
+ "Expected: marker* (table-row+|table-cell+)");
getParent().removeChild(this);
}
- }
+ }
}
/**
* {@inheritDoc} String, String)
* XSL Content Model: marker* (table-row+|table-cell+)
*/
- protected void validateChildNode(Locator loc, String nsURI, String localName)
+ protected void validateChildNode(Locator loc, String nsURI, String localName)
throws ValidationException {
if (FO_URI.equals(nsURI)) {
if (localName.equals("marker")) {
@@ -144,11 +137,11 @@ public class TableBody extends TableCellContainer {
} else if (localName.equals("table-cell")) {
tableCellsFound = true;
if (tableRowsFound) {
- invalidChildError(loc, nsURI, localName,
+ invalidChildError(loc, nsURI, localName,
"Either fo:table-rows or fo:table-cells "
- + "may be children of an "
+ + "may be children of an "
+ getName() + " but not both");
- }
+ }
} else {
invalidChildError(loc, nsURI, localName);
}
@@ -156,29 +149,35 @@ public class TableBody extends TableCellContainer {
invalidChildError(loc, nsURI, localName);
}
}
-
+
/**
* {@inheritDoc}
*/
protected void addChildNode(FONode child) throws FOPException {
if (!inMarker()) {
- if (firstRow) {
- switch (child.getNameId()) {
- case FO_TABLE_ROW:
+ switch (child.getNameId()) {
+ case FO_TABLE_ROW:
+ if (rowsStarted) {
+ columnNumberManager.prepareForNextRow(pendingSpans);
+ }
+ rowsStarted = true;
+ break;
+ case FO_TABLE_CELL:
+ rowsStarted = true;
+ TableCell cell = (TableCell) child;
+ addTableCellChild(cell, firstRow);
+ if (cell.endsRow()) {
firstRow = false;
- break;
- case FO_TABLE_CELL:
- TableCell cell = (TableCell) child;
- addTableCellChild(cell);
- break;
- default:
- //nop
+ columnNumberManager.prepareForNextRow(pendingSpans);
}
+ break;
+ default:
+ //nop
}
}
super.addChildNode(child);
}
-
+
/**
* @return the Common Border, Padding, and Background Properties.
*/
@@ -203,139 +202,19 @@ public class TableBody extends TableCellContainer {
* @return true if the given table row is the first row of this body.
*/
public boolean isFirst(TableRow obj) {
- return (firstChild == null
+ return (firstChild == null
|| firstChild == obj);
}
- /**
- * Initializes list of pending row-spans; used for correctly
- * assigning initial value for column-number for the
- * cells of following rows
- * (note: not literally mentioned in the Rec, but it is assumed
- * that, if the first cell in a given row spans two rows, then
- * the first cell of the following row will have an initial
- * column-number of 2, since the first column is already
- * occupied...)
- */
- protected void initPendingSpans(FONode child) {
- if (child.getNameId() == FO_TABLE_ROW) {
- pendingSpans = ((TableRow) child).pendingSpans;
- } else if (pendingSpans == null) {
- int colNumber = getTable().getNumberOfColumns();
- if (colNumber == 0) {
- pendingSpans = new java.util.ArrayList();
- } else {
- pendingSpans = new java.util.ArrayList(colNumber);
- for (int i = colNumber; --i >= 0;) {
- pendingSpans.add(null);
- }
+ void signalNewRow() {
+ if (rowsStarted) {
+ firstRow = false;
+ TableCell previousCell = (TableCell) getChildNodes().lastNode();
+ if (!previousCell.endsRow()) {
+ columnNumberManager.prepareForNextRow(pendingSpans);
}
}
- }
-
- /**
- * Returns the current column index of the TableBody
- *
- * @return the next column number to use
- */
- protected int getCurrentColumnIndex() {
- return columnIndex;
+ rowsStarted = true;
}
- /**
- * Sets the current column index to a specific value
- * (used by ColumnNumberPropertyMaker.make() in case the
- * column-number was explicitly specified on the cell)
- *
- * @param newIndex the new column index
- */
- protected void setCurrentColumnIndex(int newIndex) {
- columnIndex = newIndex;
- }
-
- /**
- * Resets the current column index for the TableBody
- *
- */
- protected void resetColumnIndex() {
- columnIndex = 1;
- for (int i = usedColumnIndices.length(); --i >= 0;) {
- usedColumnIndices.clear(i);
- }
-
- PendingSpan pSpan;
- for (int i = pendingSpans.size(); --i >= 0;) {
- pSpan = (PendingSpan) pendingSpans.get(i);
- if (pSpan != null) {
- pSpan.rowsLeft--;
- if (pSpan.rowsLeft == 0) {
- pendingSpans.set(i, null);
- } else {
- usedColumnIndices.set(i);
- }
- }
- }
- if (!firstRow) {
- setNextColumnIndex();
- }
- }
-
- /**
- * Increases columnIndex to the next available value
- *
- */
- protected void setNextColumnIndex() {
- while (usedColumnIndices.get(columnIndex - 1)) {
- //increment columnIndex
- columnIndex++;
- }
- //if the table has explicit columns, and
- //the index is not assigned to any
- //column, increment further until the next
- //index occupied by a column...
- while (columnIndex <= getTable().getNumberOfColumns()
- && !getTable().isColumnNumberUsed(columnIndex) ) {
- columnIndex++;
- }
- }
-
- /**
- * Checks whether the previous cell had 'ends-row="true"'
- *
- * @return true if:
- * a) there is a previous cell, which
- * had ends-row="true"
- * b) there is no previous cell (implicit
- * start of row)
- */
- protected boolean previousCellEndedRow() {
- if (firstChild != null) {
- FONode prevNode = getChildNodes().lastNode();
- if (prevNode.getNameId() == FO_TABLE_CELL) {
- return ((TableCell) prevNode).endsRow();
- }
- }
- return true;
- }
-
- /**
- * Checks whether a given column-number is already in use
- * for the current row;
- *
- * @param colNr the column-number to check
- * @return true if column-number is already occupied
- */
- public boolean isColumnNumberUsed(int colNr) {
- return usedColumnIndices.get(colNr - 1);
- }
-
- /**
- * {@inheritDoc}
- */
- protected void flagColumnIndices(int start, int end) {
- for (int i = start; i < end; i++) {
- usedColumnIndices.set(i);
- }
- setNextColumnIndex();
- }
}
diff --git a/src/java/org/apache/fop/fo/flow/TableCell.java b/src/java/org/apache/fop/fo/flow/TableCell.java
index 585d670d3..04eb904d8 100644
--- a/src/java/org/apache/fop/fo/flow/TableCell.java
+++ b/src/java/org/apache/fop/fo/flow/TableCell.java
@@ -55,7 +55,7 @@ public class TableCell extends TableFObj {
// private KeepProperty keepWithNext;
// private KeepProperty keepWithPrevious;
// End of property values
-
+
/** used for FO validation */
private boolean blockItemFound = false;
@@ -75,12 +75,16 @@ public class TableCell extends TableFObj {
blockProgressionDimension = pList.get(PR_BLOCK_PROGRESSION_DIMENSION).getLengthRange();
displayAlign = pList.get(PR_DISPLAY_ALIGN).getEnum();
emptyCells = pList.get(PR_EMPTY_CELLS).getEnum();
+ startsRow = pList.get(PR_STARTS_ROW).getEnum();
+ // For properly computing columnNumber
+ if (startsRow() && getParent().getNameId() != FO_TABLE_ROW) {
+ ((TableBody) getParent()).signalNewRow();
+ }
endsRow = pList.get(PR_ENDS_ROW).getEnum();
columnNumber = pList.get(PR_COLUMN_NUMBER).getNumeric().getValue();
numberColumnsSpanned = pList.get(PR_NUMBER_COLUMNS_SPANNED).getNumeric().getValue();
numberRowsSpanned = pList.get(PR_NUMBER_ROWS_SPANNED).getNumeric().getValue();
- startsRow = pList.get(PR_STARTS_ROW).getEnum();
- width = pList.get(PR_WIDTH).getLength();
+ width = pList.get(PR_WIDTH).getLength();
}
/**
@@ -105,7 +109,7 @@ public class TableCell extends TableFObj {
+ "enclosed by a fo:block will be dropped/ignored.");
}
}
- if ((startsRow() || endsRow())
+ if ((startsRow() || endsRow())
&& getParent().getNameId() == FO_TABLE_ROW ) {
log.warn("starts-row/ends-row for fo:table-cells "
+ "non-applicable for children of an fo:table-row.");
@@ -117,7 +121,7 @@ public class TableCell extends TableFObj {
* {@inheritDoc}
* XSL Content Model: marker* (%block;)+
*/
- protected void validateChildNode(Locator loc, String nsURI, String localName)
+ protected void validateChildNode(Locator loc, String nsURI, String localName)
throws ValidationException {
if (FO_URI.equals(nsURI) && localName.equals("marker")) {
if (blockItemFound) {
@@ -148,12 +152,12 @@ public class TableCell extends TableFObj {
public int getColumnNumber() {
return columnNumber;
}
-
+
/** @return true if "empty-cells" is "show" */
public boolean showEmptyCells() {
return (this.emptyCells == EN_SHOW);
}
-
+
/**
* @return the "number-columns-spanned" property.
*/
@@ -167,7 +171,7 @@ public class TableCell extends TableFObj {
public int getNumberRowsSpanned() {
return Math.max(numberRowsSpanned, 1);
}
-
+
/**
* @return the "block-progression-dimension" property.
*/
@@ -179,24 +183,24 @@ public class TableCell extends TableFObj {
public int getDisplayAlign() {
return displayAlign;
}
-
+
/**
* @return the "width" property.
*/
public Length getWidth() {
return width;
}
-
+
/** @return true if the cell starts a row. */
public boolean startsRow() {
return (startsRow == EN_TRUE);
}
-
+
/** @return true if the cell ends a row. */
public boolean endsRow() {
return (endsRow == EN_TRUE);
}
-
+
/** {@inheritDoc} */
public String getLocalName() {
return "table-cell";
@@ -208,4 +212,5 @@ public class TableCell extends TableFObj {
public final int getNameId() {
return FO_TABLE_CELL;
}
+
}
diff --git a/src/java/org/apache/fop/fo/flow/TableCellContainer.java b/src/java/org/apache/fop/fo/flow/TableCellContainer.java
index 9fa602a19..228e3c80d 100644
--- a/src/java/org/apache/fop/fo/flow/TableCellContainer.java
+++ b/src/java/org/apache/fop/fo/flow/TableCellContainer.java
@@ -28,28 +28,75 @@ import org.apache.fop.fo.FONode;
/**
* A common class for fo:table-body and fo:table-row which both can contain fo:table-cell.
*/
-public abstract class TableCellContainer extends TableFObj {
+public abstract class TableCellContainer extends TableFObj implements ColumnNumberManagerHolder {
+
+ /**
+ * Used for determining initial values for column-numbers
+ * in case of row-spanning cells
+ * (for clarity)
+ *
+ */
+ static class PendingSpan {
+
+ /**
+ * member variable holding the number of rows left
+ */
+ protected int rowsLeft;
+
+ /**
+ * Constructor
+ *
+ * @param rows number of rows spanned
+ */
+ public PendingSpan(int rows) {
+ rowsLeft = rows;
+ }
+ }
+
+ protected List pendingSpans;
+
+ protected ColumnNumberManager columnNumberManager;
public TableCellContainer(FONode parent) {
super(parent);
}
- protected void addTableCellChild(TableCell cell) throws FOPException {
- Table t = getTable();
- int colNr = cell.getColumnNumber();
+ protected void addTableCellChild(TableCell cell, boolean firstRow) throws FOPException {
+ int colNumber = cell.getColumnNumber();
int colSpan = cell.getNumberColumnsSpanned();
+ int rowSpan = cell.getNumberRowsSpanned();
+
+ if (firstRow) {
+ handleCellWidth(cell, colNumber, colSpan);
+ updatePendingSpansSize(cell, colNumber, colSpan);
+ }
+
+ /* if the current cell spans more than one row,
+ * update pending span list for the next row
+ */
+ if (rowSpan > 1) {
+ for (int i = 0; i < colSpan; i++) {
+ pendingSpans.set(colNumber - 1 + i, new PendingSpan(rowSpan));
+ }
+ }
+
+ columnNumberManager.signalUsedColumnNumbers(colNumber, colNumber + colSpan - 1);
+ }
+
+ private void handleCellWidth(TableCell cell, int colNumber, int colSpan) throws FOPException {
+ Table t = getTable();
Length colWidth = null;
if (cell.getWidth().getEnum() != EN_AUTO
&& colSpan == 1) {
colWidth = cell.getWidth();
}
-
- for (int i = colNr; i < colNr + colSpan; ++i) {
+
+ for (int i = colNumber; i < colNumber + colSpan; ++i) {
TableColumn col = t.getColumn(i - 1);
if (col == null) {
- t.addDefaultColumn(colWidth,
- i == colNr
+ t.addDefaultColumn(colWidth,
+ i == colNumber
? cell.getColumnNumber()
: 0);
} else {
@@ -61,97 +108,15 @@ public abstract class TableCellContainer extends TableFObj {
}
}
- protected void addChildNode(FONode child) throws FOPException {
- if (!inMarker()
- && child.getNameId() == FO_TABLE_CELL) {
- /* update current column index for the table-body/table-row */
- updateColumnIndex((TableCell) child);
+ private void updatePendingSpansSize(TableCell cell, int colNumber, int colSpan) {
+ while (pendingSpans.size() < colNumber + colSpan - 1) {
+ pendingSpans.add(null);
}
- super.addChildNode(child);
}
-
- private void updateColumnIndex(TableCell cell) {
-
- int rowSpan = cell.getNumberRowsSpanned();
- int colSpan = cell.getNumberColumnsSpanned();
- int columnIndex = getCurrentColumnIndex();
- int i;
-
- if (getNameId() == FO_TABLE_ROW) {
-
- TableRow row = (TableRow) this;
-
- for (i = colSpan;
- --i >= 0 || row.pendingSpans.size() < cell.getColumnNumber();) {
- row.pendingSpans.add(null);
- }
-
- /* if the current cell spans more than one row,
- * update pending span list for the next row
- */
- if (rowSpan > 1) {
- for (i = colSpan; --i >= 0;) {
- row.pendingSpans.set(columnIndex - 1 + i,
- new PendingSpan(rowSpan));
- }
- }
- } else {
-
- TableBody body = (TableBody) this;
-
- /* if body.firstRow is still true, and :
- * a) the cell starts a row,
- * b) there was a previous cell
- * c) that previous cell didn't explicitly end the previous row
- * => set firstRow flag to false
- */
- if (body.firstRow && cell.startsRow()) {
- if (!body.previousCellEndedRow()) {
- body.firstRow = false;
- }
- }
-
- /* pendingSpans not initialized for the first row...
- */
- if (body.firstRow) {
- for (i = colSpan;
- --i >= 0|| body.pendingSpans.size() < cell.getColumnNumber();) {
- body.pendingSpans.add(null);
- }
- }
-
- /* if the current cell spans more than one row,
- * update pending span list for the next row
- */
- if (rowSpan > 1) {
- for (i = colSpan; --i >= 0;) {
- body.pendingSpans.set(columnIndex - 1 + i,
- new PendingSpan(rowSpan));
- }
- }
- }
-
- /* flag column indices used by this cell,
- * take into account that possibly not all column-numbers
- * are used by columns in the parent table (if any),
- * so a cell spanning three columns, might actually
- * take up more than three columnIndices...
- */
- int startIndex = columnIndex - 1;
- int endIndex = startIndex + colSpan;
- List cols = getTable().getColumns();
- int tmpIndex = endIndex;
- for (i = startIndex; i <= tmpIndex; ++i) {
- if (i < cols.size() && cols.get(i) == null) {
- endIndex++;
- }
- }
- flagColumnIndices(startIndex, endIndex);
- if (getNameId() != FO_TABLE_ROW && cell.endsRow()) {
- ((TableBody) this).firstRow = false;
- ((TableBody) this).resetColumnIndex();
- }
+ /** {@inheritDoc} */
+ public ColumnNumberManager getColumnNumberManager() {
+ return columnNumberManager;
}
}
diff --git a/src/java/org/apache/fop/fo/flow/TableColumn.java b/src/java/org/apache/fop/fo/flow/TableColumn.java
index 30fb494f0..775b27ff3 100644
--- a/src/java/org/apache/fop/fo/flow/TableColumn.java
+++ b/src/java/org/apache/fop/fo/flow/TableColumn.java
@@ -45,17 +45,17 @@ public class TableColumn extends TableFObj {
// Unused but valid items, commented out for performance:
// private int visibility;
// End of property values
-
+
private boolean defaultColumn;
private PropertyList pList = null;
-
+
/**
* @param parent FONode that is the parent of this object
*/
public TableColumn(FONode parent) {
this(parent, false);
}
-
+
/**
* @param parent FONode that is the parent of this object
* @param defaultColumn true if this table-column has been manually created as a default column
@@ -64,7 +64,7 @@ public class TableColumn extends TableFObj {
super(parent);
this.defaultColumn = defaultColumn;
}
-
+
/**
* {@inheritDoc}
@@ -78,7 +78,7 @@ public class TableColumn extends TableFObj {
numberColumnsSpanned = pList.get(PR_NUMBER_COLUMNS_SPANNED)
.getNumeric().getValue();
super.bind(pList);
-
+
if (numberColumnsRepeated <= 0) {
throw new PropertyException("number-columns-repeated must be 1 or bigger, "
+ "but got " + numberColumnsRepeated);
@@ -87,10 +87,10 @@ public class TableColumn extends TableFObj {
throw new PropertyException("number-columns-spanned must be 1 or bigger, "
+ "but got " + numberColumnsSpanned);
}
-
- /* check for unspecified width and replace with default of
+
+ /* check for unspecified width and replace with default of
* proportional-column-width(1), in case of fixed table-layout
- * warn only for explicit columns
+ * warn only for explicit columns
*/
if (columnWidth.getEnum() == EN_AUTO) {
if (!this.defaultColumn && !getTable().isAutoLayout()) {
@@ -99,7 +99,7 @@ public class TableColumn extends TableFObj {
}
columnWidth = new TableColLength(1.0, this);
}
-
+
/* in case of explicit columns, from-table-column()
* can be used on descendants of the table-cells, so
* we need a reference to the column's property list
@@ -128,8 +128,8 @@ public class TableColumn extends TableFObj {
* {@inheritDoc}
* XSL Content Model: empty
*/
- protected void validateChildNode(Locator loc,
- String nsURI, String localName)
+ protected void validateChildNode(Locator loc,
+ String nsURI, String localName)
throws ValidationException {
invalidChildError(loc, nsURI, localName);
}
@@ -162,7 +162,7 @@ public class TableColumn extends TableFObj {
public int getColumnNumber() {
return columnNumber;
}
-
+
/**
* Used for setting the column-number for an implicit column
* @param columnNumber
@@ -175,12 +175,12 @@ public class TableColumn extends TableFObj {
public int getNumberColumnsRepeated() {
return numberColumnsRepeated;
}
-
+
/** @return value for number-columns-spanned. */
public int getNumberColumnsSpanned() {
return numberColumnsSpanned;
}
-
+
/** {@inheritDoc} */
public String getLocalName() {
return "table-column";
@@ -190,11 +190,11 @@ public class TableColumn extends TableFObj {
public int getNameId() {
return FO_TABLE_COLUMN;
}
-
+
/**
- * Indicates whether this table-column has been created as
- * default column for this table in case no table-columns
- * have been defined.
+ * Indicates whether this table-column has been created as
+ * default column for this table in case no table-columns
+ * have been defined.
* Note that this only used to provide better
* user feedback (see ColumnSetup).
* @return true if this table-column has been created as default column
@@ -202,7 +202,7 @@ public class TableColumn extends TableFObj {
public boolean isDefaultColumn() {
return defaultColumn;
}
-
+
/** {@inheritDoc} */
public String toString() {
StringBuffer sb = new StringBuffer("fo:table-column");
@@ -218,9 +218,9 @@ public class TableColumn extends TableFObj {
sb.append(" column-width=").append(getColumnWidth());
return sb.toString();
}
-
+
/**
- * Retrieve a property value through its Id; used by
+ * Retrieve a property value through its Id; used by
* from-table-column() function
*
* @param propId the id for the property to retrieve
@@ -230,12 +230,13 @@ public class TableColumn extends TableFObj {
public Property getProperty(int propId) throws PropertyException {
return this.pList.get(propId);
}
-
+
/**
- * Clear the reference to the PropertyList (retained for
+ * Clear the reference to the PropertyList (retained for
* from-table-column())
*/
protected void releasePropertyList() {
this.pList = null;
- }
+ }
+
}
diff --git a/src/java/org/apache/fop/fo/flow/TableFObj.java b/src/java/org/apache/fop/fo/flow/TableFObj.java
index bd5642feb..e00559d3e 100644
--- a/src/java/org/apache/fop/fo/flow/TableFObj.java
+++ b/src/java/org/apache/fop/fo/flow/TableFObj.java
@@ -40,30 +40,7 @@ public abstract class TableFObj extends FObj {
private Numeric borderBeforePrecedence;
private Numeric borderEndPrecedence;
private Numeric borderStartPrecedence;
-
- /**
- * Used for determining initial values for column-numbers
- * in case of row-spanning cells
- * (for clarity)
- *
- */
- protected static class PendingSpan {
-
- /**
- * member variable holding the number of rows left
- */
- protected int rowsLeft;
-
- /**
- * Constructor
- *
- * @param rows number of rows spanned
- */
- public PendingSpan(int rows) {
- rowsLeft = rows;
- }
- }
-
+
/**
* Main constructor
*
@@ -113,73 +90,23 @@ public abstract class TableFObj extends FObj {
}
/**
- * Returns the current column index of the given TableFObj
- * (overridden for Table, TableBody, TableRow)
- *
- * @return the next column number to use
- */
- protected int getCurrentColumnIndex() {
- return 0;
- }
-
- /**
- * Sets the current column index of the given TableFObj
- * used when a value for column-number is explicitly
- * specified on the child FO (TableCell or TableColumn)
- * (overridden for Table, TableBody, TableRow)
- *
- * @param newIndex new value for column index
- */
- protected void setCurrentColumnIndex(int newIndex) {
- //do nothing by default
- }
-
- /**
- * Checks if a certain column-number is already occupied
- * (overridden for Table, TableBody, TableRow)
- *
- * @param colNr the column-number to check
- * @return true if column-number is already in use
- */
- public boolean isColumnNumberUsed(int colNr) {
- return false;
- }
-
- /**
- * Convenience method to returns a reference
+ * Convenience method to returns a reference
* to the base Table instance
*
* @return the base table instance
*
*/
public Table getTable() {
- if (this.getNameId() == FO_TABLE) {
- //node is a Table
- //=> return itself
- return (Table) this;
- } else {
- //any other Table-node
- //=> recursive call to parent.getTable()
- return ((TableFObj) parent).getTable();
- }
+ // Will be overridden in Table; for any other Table-node, recursive call to
+ // parent.getTable()
+ return ((TableFObj) parent).getTable();
}
-
+
/**
* @return the Common Border, Padding, and Background Properties.
*/
public abstract CommonBorderPaddingBackground getCommonBorderPaddingBackground();
-
- /**
- * Flags column indices from <code>start</code> to <code>end</code>,
- * and updates the current column index.
- * Overridden for Table, TableBody, TableRow
- * @param start start index
- * @param end end index
- */
- protected void flagColumnIndices(int start, int end) {
- //nop
- }
-
+
/**
* PropertyMaker subclass for the column-number property
*
@@ -188,7 +115,7 @@ public abstract class TableFObj extends FObj {
/**
* Constructor
- * @param propId the id of the property for which the maker should
+ * @param propId the id of the property for which the maker should
* be created
*/
public ColumnNumberPropertyMaker(int propId) {
@@ -198,47 +125,36 @@ public abstract class TableFObj extends FObj {
/**
* {@inheritDoc}
*/
- public Property make(PropertyList propertyList)
+ public Property make(PropertyList propertyList)
throws PropertyException {
FObj fo = propertyList.getFObj();
- if (fo.getNameId() == Constants.FO_TABLE_CELL
- || fo.getNameId() == Constants.FO_TABLE_COLUMN) {
- if (fo.getNameId() == Constants.FO_TABLE_CELL
- && fo.getParent().getNameId() != Constants.FO_TABLE_ROW
- && (propertyList.get(Constants.PR_STARTS_ROW).getEnum()
- == Constants.EN_TRUE)) {
- TableBody parent = (TableBody) fo.getParent();
- if (!parent.previousCellEndedRow()) {
- parent.resetColumnIndex();
- }
- }
- }
- return NumberProperty.getInstance(
- ((TableFObj) fo.getParent()).getCurrentColumnIndex());
+ return NumberProperty.getInstance(((ColumnNumberManagerHolder) fo.getParent())
+ .getColumnNumberManager().getCurrentColumnNumber());
}
-
-
+
+
/**
- * Check the value of the column-number property.
- * Return the parent's column index (initial value) in case
+ * Check the value of the column-number property.
+ * Return the parent's column index (initial value) in case
* of a negative or zero value
*
* @see org.apache.fop.fo.properties.PropertyMaker#make(PropertyList, String, FObj)
*/
- public Property make(PropertyList propertyList, String value, FObj fo)
+ public Property make(PropertyList propertyList, String value, FObj fo)
throws PropertyException {
Property p = super.make(propertyList, value, fo);
-
- TableFObj parent = (TableFObj) propertyList.getParentFObj();
-
+
+ ColumnNumberManagerHolder parent
+ = (ColumnNumberManagerHolder) propertyList.getParentFObj();
+ ColumnNumberManager columnIndexManager = parent.getColumnNumberManager();
int columnIndex = p.getNumeric().getValue();
if (columnIndex <= 0) {
log.warn("Specified negative or zero value for "
+ "column-number on " + fo.getName() + ": "
- + columnIndex + " forced to "
- + parent.getCurrentColumnIndex());
- return NumberProperty.getInstance(parent.getCurrentColumnIndex());
+ + columnIndex + " forced to "
+ + columnIndexManager.getCurrentColumnNumber());
+ return NumberProperty.getInstance(columnIndexManager.getCurrentColumnNumber());
} else {
double tmpIndex = p.getNumeric().getNumericValue();
if (tmpIndex - columnIndex > 0.0) {
@@ -248,15 +164,15 @@ public abstract class TableFObj extends FObj {
p = NumberProperty.getInstance(columnIndex);
}
}
-
- parent.setCurrentColumnIndex(columnIndex);
-
+
+ columnIndexManager.setCurrentColumnIndex(columnIndex);
+
int colSpan = propertyList.get(Constants.PR_NUMBER_COLUMNS_SPANNED)
.getNumeric().getValue();
int i = -1;
while (++i < colSpan) {
- if (parent.isColumnNumberUsed(columnIndex + i)) {
- /* if column-number is already in use by another
+ if (columnIndexManager.isColumnNumberUsed(columnIndex + i)) {
+ /* if column-number is already in use by another
* cell/column => error!
*/
StringBuffer errorMessage = new StringBuffer();
@@ -271,7 +187,7 @@ public abstract class TableFObj extends FObj {
throw new PropertyException(errorMessage.toString());
}
}
-
+
return p;
}
}
diff --git a/src/java/org/apache/fop/fo/flow/TableRow.java b/src/java/org/apache/fop/fo/flow/TableRow.java
index b6feeabba..bbc8081a6 100644
--- a/src/java/org/apache/fop/fo/flow/TableRow.java
+++ b/src/java/org/apache/fop/fo/flow/TableRow.java
@@ -19,12 +19,6 @@
package org.apache.fop.fo.flow;
-import java.util.BitSet;
-import java.util.List;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.Locator;
-
import org.apache.fop.apps.FOPException;
import org.apache.fop.datatypes.Length;
import org.apache.fop.fo.FONode;
@@ -33,6 +27,8 @@ import org.apache.fop.fo.ValidationException;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.KeepProperty;
import org.apache.fop.fo.properties.LengthRangeProperty;
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
/**
* Class modelling the fo:table-row object.
@@ -53,10 +49,6 @@ public class TableRow extends TableCellContainer {
// private CommonRelativePosition commonRelativePosition;
// private int visibility;
// End of property values
-
- protected List pendingSpans;
- protected BitSet usedColumnIndices;
- private int columnIndex = 1;
/**
* @param parent FONode that is the parent of this object
@@ -67,7 +59,7 @@ public class TableRow extends TableCellContainer {
/** {@inheritDoc} */
public void bind(PropertyList pList) throws FOPException {
- blockProgressionDimension
+ blockProgressionDimension
= pList.get(PR_BLOCK_PROGRESSION_DIMENSION).getLengthRange();
commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
breakAfter = pList.get(PR_BREAK_AFTER).getEnum();
@@ -80,16 +72,12 @@ public class TableRow extends TableCellContainer {
}
/** {@inheritDoc} */
- public void processNode(String elementName, Locator locator,
+ public void processNode(String elementName, Locator locator,
Attributes attlist, PropertyList pList) throws FOPException {
if (!inMarker()) {
TableBody body = (TableBody) parent;
- body.resetColumnIndex();
pendingSpans = body.pendingSpans;
- usedColumnIndices = body.usedColumnIndices;
- while (usedColumnIndices.get(columnIndex - 1)) {
- columnIndex++;
- }
+ columnNumberManager = body.columnNumberManager;
}
super.processNode(elementName, locator, attlist, pList);
}
@@ -99,11 +87,9 @@ public class TableRow extends TableCellContainer {
*/
protected void addChildNode(FONode child) throws FOPException {
if (!inMarker()) {
+ TableCell cell = (TableCell) child;
TableBody body = (TableBody) getParent();
- if (body.isFirst(this)) {
- TableCell cell = (TableCell) child;
- addTableCellChild(cell);
- }
+ addTableCellChild(cell, body.isFirst(this));
}
super.addChildNode(child);
}
@@ -125,7 +111,7 @@ public class TableRow extends TableCellContainer {
}
if (!inMarker()) {
pendingSpans = null;
- usedColumnIndices = null;
+ columnNumberManager = null;
}
getFOEventHandler().endRow(this);
}
@@ -134,14 +120,14 @@ public class TableRow extends TableCellContainer {
* {@inheritDoc} String, String)
* XSL Content Model: (table-cell+)
*/
- protected void validateChildNode(Locator loc, String nsURI,
- String localName)
+ protected void validateChildNode(Locator loc, String nsURI,
+ String localName)
throws ValidationException {
if (!(FO_URI.equals(nsURI) && localName.equals("table-cell"))) {
invalidChildError(loc, nsURI, localName);
}
- }
-
+ }
+
/** @return the "break-after" property. */
public int getBreakAfter() {
return breakAfter;
@@ -168,7 +154,7 @@ public class TableRow extends TableCellContainer {
}
/**
- * Convenience method to check if a keep-together
+ * Convenience method to check if a keep-together
* constraint is specified.
* @return true if keep-together is active.
*/
@@ -176,9 +162,9 @@ public class TableRow extends TableCellContainer {
return !getKeepTogether().getWithinPage().isAuto()
|| !getKeepTogether().getWithinColumn().isAuto();
}
-
+
/**
- * Convenience method to check if a keep-with-next
+ * Convenience method to check if a keep-with-next
* constraint is specified.
* @return true if keep-with-next is active.
*/
@@ -186,9 +172,9 @@ public class TableRow extends TableCellContainer {
return !getKeepWithNext().getWithinPage().isAuto()
|| !getKeepWithNext().getWithinColumn().isAuto();
}
-
+
/**
- * Convenience method to check if a keep-with-previous
+ * Convenience method to check if a keep-with-previous
* constraint is specified.
* @return true if keep-with-previous is active.
*/
@@ -196,7 +182,7 @@ public class TableRow extends TableCellContainer {
return !getKeepWithPrevious().getWithinPage().isAuto()
|| !getKeepWithPrevious().getWithinColumn().isAuto();
}
-
+
/**
* @return the "block-progression-dimension" property.
*/
@@ -217,7 +203,7 @@ public class TableRow extends TableCellContainer {
public CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
return commonBorderPaddingBackground;
}
-
+
/** {@inheritDoc} */
public String getLocalName() {
return "table-row";
@@ -227,48 +213,4 @@ public class TableRow extends TableCellContainer {
public int getNameId() {
return FO_TABLE_ROW;
}
-
- /**
- * Returns the current column index of the TableRow
- *
- * @return the next column number to use
- */
- public int getCurrentColumnIndex() {
- return columnIndex;
- }
-
- /**
- * Sets the current column index to a specific value
- * in case a column-number was explicitly specified
- * (used by ColumnNumberPropertyMaker.make())
- *
- * @param newIndex new value for column index
- */
- public void setCurrentColumnIndex(int newIndex) {
- columnIndex = newIndex;
- }
-
- /**
- * Checks whether a given column-number is already in use
- * for the current row (used by TableCell.bind());
- *
- * @param colNr the column-number to check
- * @return true if column-number is already occupied
- */
- public boolean isColumnNumberUsed(int colNr) {
- return usedColumnIndices.get(colNr - 1);
- }
-
- /**
- * {@inheritDoc}
- */
- protected void flagColumnIndices(int start, int end) {
- for (int i = start; i < end; i++) {
- usedColumnIndices.set(i);
- }
- // update columnIndex for the next cell
- while (usedColumnIndices.get(columnIndex - 1)) {
- columnIndex++;
- }
- }
}