From 67295b556093f78416cce975060e678b94b054d0 Mon Sep 17 00:00:00 2001 From: Vincent Hennebert Date: Tue, 30 Oct 2007 16:21:39 +0000 Subject: [PATCH] - 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 --- .../fop/fo/expr/FromTableColumnFunction.java | 16 +- .../fop/fo/flow/ColumnNumberManager.java | 116 ++++++++++ .../fo/flow/ColumnNumberManagerHolder.java | 35 +++ src/java/org/apache/fop/fo/flow/Table.java | 203 +++++++--------- .../org/apache/fop/fo/flow/TableBody.java | 217 ++++-------------- .../org/apache/fop/fo/flow/TableCell.java | 29 ++- .../fop/fo/flow/TableCellContainer.java | 157 +++++-------- .../org/apache/fop/fo/flow/TableColumn.java | 49 ++-- .../org/apache/fop/fo/flow/TableFObj.java | 142 +++--------- src/java/org/apache/fop/fo/flow/TableRow.java | 96 ++------ 10 files changed, 437 insertions(+), 623 deletions(-) create mode 100644 src/java/org/apache/fop/fo/flow/ColumnNumberManager.java create mode 100644 src/java/org/apache/fop/fo/flow/ColumnNumberManagerHolder.java 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 start to end 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<PendingSpan> 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 start to end, - * 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++; - } - } } -- 2.39.5