static class TableAndCaptionMaker extends ElementMapping.Maker {
public FONode make(FONode parent) {
- return new org.apache.fop.fo.flow.TableAndCaption(parent);
+ return new org.apache.fop.fo.flow.table.TableAndCaption(parent);
}
}
static class TableMaker extends ElementMapping.Maker {
public FONode make(FONode parent) {
- return new org.apache.fop.fo.flow.Table(parent);
+ return new org.apache.fop.fo.flow.table.Table(parent);
}
}
static class TableColumnMaker extends ElementMapping.Maker {
public FONode make(FONode parent) {
- return new org.apache.fop.fo.flow.TableColumn(parent);
+ return new org.apache.fop.fo.flow.table.TableColumn(parent);
}
}
static class TableCaptionMaker extends ElementMapping.Maker {
public FONode make(FONode parent) {
- return new org.apache.fop.fo.flow.TableCaption(parent);
+ return new org.apache.fop.fo.flow.table.TableCaption(parent);
}
}
static class TableBodyMaker extends ElementMapping.Maker {
public FONode make(FONode parent) {
- return new org.apache.fop.fo.flow.TableBody(parent);
+ return new org.apache.fop.fo.flow.table.TableBody(parent);
}
}
static class TableHeaderMaker extends ElementMapping.Maker {
public FONode make(FONode parent) {
- return new org.apache.fop.fo.flow.TableHeader(parent);
+ return new org.apache.fop.fo.flow.table.TableHeader(parent);
}
}
static class TableFooterMaker extends ElementMapping.Maker {
public FONode make(FONode parent) {
- return new org.apache.fop.fo.flow.TableFooter(parent);
+ return new org.apache.fop.fo.flow.table.TableFooter(parent);
}
}
static class TableRowMaker extends ElementMapping.Maker {
public FONode make(FONode parent) {
- return new org.apache.fop.fo.flow.TableRow(parent);
+ return new org.apache.fop.fo.flow.table.TableRow(parent);
}
}
static class TableCellMaker extends ElementMapping.Maker {
public FONode make(FONode parent) {
- return new org.apache.fop.fo.flow.TableCell(parent);
+ return new org.apache.fop.fo.flow.table.TableCell(parent);
}
}
import org.apache.fop.fo.flow.ListBlock;
import org.apache.fop.fo.flow.ListItem;
import org.apache.fop.fo.flow.PageNumber;
-import org.apache.fop.fo.flow.Table;
-import org.apache.fop.fo.flow.TableBody;
-import org.apache.fop.fo.flow.TableCell;
-import org.apache.fop.fo.flow.TableColumn;
-import org.apache.fop.fo.flow.TableRow;
+import org.apache.fop.fo.flow.table.Table;
+import org.apache.fop.fo.flow.table.TableBody;
+import org.apache.fop.fo.flow.table.TableCell;
+import org.apache.fop.fo.flow.table.TableColumn;
+import org.apache.fop.fo.flow.table.TableRow;
import org.apache.fop.fo.pagination.Flow;
import org.apache.fop.fo.pagination.PageSequence;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fo.properties.BoxPropShorthandParser;
import org.apache.fop.fo.properties.CharacterProperty;
import org.apache.fop.fo.properties.ColorProperty;
-import org.apache.fop.fo.flow.TableFObj.ColumnNumberPropertyMaker;
+import org.apache.fop.fo.flow.table.TableFObj.ColumnNumberPropertyMaker;
import org.apache.fop.fo.properties.CondLengthProperty;
import org.apache.fop.fo.properties.CorrespondingPropertyMaker;
import org.apache.fop.fo.properties.DimensionPropertyMaker;
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;
-import org.apache.fop.fo.flow.TableFObj;
+import org.apache.fop.fo.flow.table.ColumnNumberManager;
+import org.apache.fop.fo.flow.table.Table;
+import org.apache.fop.fo.flow.table.TableCell;
+import org.apache.fop.fo.flow.table.TableColumn;
+import org.apache.fop.fo.flow.table.TableFObj;
import org.apache.fop.fo.properties.Property;
/**
package org.apache.fop.fo.expr;
import org.apache.fop.fo.PropertyList;
-import org.apache.fop.fo.flow.Table;
+import org.apache.fop.fo.flow.table.Table;
import org.apache.fop.fo.properties.Property;
import org.apache.fop.fo.properties.TableColLength;
+++ /dev/null
-/*
- * 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);
- }
-
- columnNumber = end + 1;
- 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);
- }
-
-}
+++ /dev/null
-/*
- * 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();
-}
+++ /dev/null
-/*
- * 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;
-
-
-/**
- * A row group builder optimised for a fixed number of columns, known before the parsing
- * of cells starts (that is, if the fo:table has explicit fo:table-column children).
- */
-class FixedColRowGroupBuilder extends RowGroupBuilder {
-
-
- FixedColRowGroupBuilder(Table t) {
- super(t);
- numberOfColumns = t.getNumberOfColumns();
- }
-
-}
import org.apache.fop.fo.FOText;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.ValidationException;
+import org.apache.fop.fo.flow.table.Table;
import org.xml.sax.Locator;
/**
+++ /dev/null
-/*
- * 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.ArrayList;
-import java.util.List;
-
-import org.apache.fop.layoutmgr.table.GridUnit;
-import org.apache.fop.layoutmgr.table.PrimaryGridUnit;
-
-/**
- * A class that creates groups of rows belonging to a same set of spans. The first row of
- * such a group has only cells which don't span over several rows, or whose spanning
- * starts on this row. Similarly, the last row has only non-row spanning cells or spans
- * which end on this row.
- */
-abstract class RowGroupBuilder {
-
- /** Number of columns in the corresponding table. */
- protected int numberOfColumns;
-
- /** 0-based, index in the row group. */
- private int currentRowIndex;
-
- private Table table;
-
- /** The rows belonging to this row group. List of List of {@link GridUnit}s. */
- protected List rows;
-
- /**
- * Creates and initialises a new builder for the given table.
- *
- * @param t a table
- */
- protected RowGroupBuilder(Table t) {
- table = t;
- initialize();
- }
-
- /**
- * Prepares this builder for creating a new row group.
- */
- private void initialize() {
- rows = new ArrayList();
- currentRowIndex = 0;
- }
-
- /**
- * Adds a table-cell to the row-group, creating {@link GridUnit}s accordingly.
- *
- * @param cell
- */
- void addTableCell(TableCell cell) {
- for (int i = rows.size(); i < currentRowIndex + cell.getNumberRowsSpanned(); i++) {
- List effRow = new ArrayList(numberOfColumns);
- for (int j = 0; j < numberOfColumns; j++) {
- effRow.add(null);
- }
- rows.add(effRow);
- }
- int columnIndex = cell.getColumnNumber() - 1;
- PrimaryGridUnit pgu = new PrimaryGridUnit(cell, table.getColumn(columnIndex), columnIndex,
- currentRowIndex);
- List row = (List) rows.get(currentRowIndex);
- row.set(columnIndex, pgu);
- for (int j = 1; j < cell.getNumberColumnsSpanned(); j++) {
- row.set(j + columnIndex,
- new GridUnit(pgu, table.getColumn(columnIndex + j), columnIndex + j, j));
- }
- for (int i = 1; i < cell.getNumberRowsSpanned(); i++) {
- row = (List) rows.get(currentRowIndex + i);
- for (int j = 0; j < cell.getNumberColumnsSpanned(); j++) {
- row.set(j + columnIndex,
- new GridUnit(pgu, table.getColumn(columnIndex + j), columnIndex + j, j));
- }
- }
-
- }
-
- /**
- * Signals that a table row has just ended, potentially finishing the current row
- * group.
- *
- * @param body the table-body containing the row. Its
- * {@link TableBody#addRowGroup(List)} method will be called if the current row group
- * is finished.
- */
- void signalNewRow(TableBody body) {
- if (currentRowIndex == rows.size() - 1) {
- // Means that the current row has no cell spanning over following rows
- body.addRowGroup(rows);
- initialize();
- } else {
- currentRowIndex++;
- }
- }
-
- /**
- * Finishes and records the last row-group of the given table-body, if any. If there
- * is no fo:table-row and the last cell of the table-body didn't have ends-row="true",
- * then the {@link signalNewRow} method has not been called and the last row group has
- * yet to be recorded.
- *
- * @param tableBody
- */
- void finishLastRowGroup(TableBody tableBody) {
- if (rows.size() > 0) {
- tableBody.addRowGroup(rows);
- }
- // Reset, in case this rowGroupBuilder is re-used for other
- // table-header/footer/body
- initialize();
- }
-
-}
+++ /dev/null
-/*
- * 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.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.fop.apps.FOPException;
-import org.apache.fop.datatypes.Length;
-import org.apache.fop.datatypes.ValidationPercentBaseContext;
-import org.apache.fop.fo.FONode;
-import org.apache.fop.fo.PropertyList;
-import org.apache.fop.fo.StaticPropertyList;
-import org.apache.fop.fo.ValidationException;
-import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
-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.apache.fop.fo.properties.TableColLength;
-import org.xml.sax.Locator;
-
-/**
- * Class modelling the fo:table object.
- */
-public class Table extends TableFObj implements ColumnNumberManagerHolder {
-
- /** properties */
- private CommonBorderPaddingBackground commonBorderPaddingBackground;
- private CommonMarginBlock commonMarginBlock;
- private LengthRangeProperty blockProgressionDimension;
- private int borderCollapse;
- private LengthPairProperty borderSeparation;
- private int breakAfter;
- private int breakBefore;
- private LengthRangeProperty inlineProgressionDimension;
- private KeepProperty keepTogether;
- private KeepProperty keepWithNext;
- private KeepProperty keepWithPrevious;
- private int tableLayout;
- private int tableOmitFooterAtBreak;
- private int tableOmitHeaderAtBreak;
- // Unused but valid items, commented out for performance:
- // private CommonAccessibility commonAccessibility;
- // private CommonAural commonAural;
- // 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();
-
- 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 hasExplicitColumns = false;
- private boolean columnsFinalized = false;
- private RowGroupBuilder rowGroupBuilder;
-
- /**
- * 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
- */
- public Table(FONode parent) {
- super(parent);
- }
-
- /**
- * {@inheritDoc}
- */
- public void bind(PropertyList pList) throws FOPException {
- super.bind(pList);
- commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
- commonMarginBlock = pList.getMarginBlockProps();
- blockProgressionDimension = pList.get(PR_BLOCK_PROGRESSION_DIMENSION).getLengthRange();
- borderCollapse = pList.get(PR_BORDER_COLLAPSE).getEnum();
- borderSeparation = pList.get(PR_BORDER_SEPARATION).getLengthPair();
- breakAfter = pList.get(PR_BREAK_AFTER).getEnum();
- breakBefore = pList.get(PR_BREAK_BEFORE).getEnum();
- inlineProgressionDimension = pList.get(PR_INLINE_PROGRESSION_DIMENSION).getLengthRange();
- keepTogether = pList.get(PR_KEEP_TOGETHER).getKeep();
- keepWithNext = pList.get(PR_KEEP_WITH_NEXT).getKeep();
- keepWithPrevious = pList.get(PR_KEEP_WITH_PREVIOUS).getKeep();
- tableLayout = pList.get(PR_TABLE_LAYOUT).getEnum();
- tableOmitFooterAtBreak = pList.get(PR_TABLE_OMIT_FOOTER_AT_BREAK).getEnum();
- tableOmitHeaderAtBreak = pList.get(PR_TABLE_OMIT_HEADER_AT_BREAK).getEnum();
-
- //Bind extension properties
- widowContentLimit = pList.get(PR_X_WIDOW_CONTENT_LIMIT).getLength();
- orphanContentLimit = pList.get(PR_X_ORPHAN_CONTENT_LIMIT).getLength();
-
- if (!blockProgressionDimension.getOptimum(null).isAuto()) {
- attributeWarning("only a value of \"auto\" for block-progression-dimension has a well-specified"
- + " behavior on fo:table. Falling back to \"auto\"");
- // Anyway, the bpd of a table is not used by the layout code
- }
- if (tableLayout == EN_AUTO) {
- attributeWarning("table-layout=\"auto\" is currently not supported by FOP");
- }
- if (!isSeparateBorderModel()
- && getCommonBorderPaddingBackground().hasPadding(
- ValidationPercentBaseContext.getPseudoContext())) {
- //See "17.6.2 The collapsing border model" in CSS2
- attributeWarning("In collapsing border model a table does not have padding"
- + " (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
- * (see addDefaultColumn())
- */
- this.propList = pList;
- }
-
- /**
- * {@inheritDoc}
- */
- protected void startOfNode() throws FOPException {
- 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)
- throws ValidationException {
- if (FO_URI.equals(nsURI)) {
- if ("marker".equals(localName)) {
- if (tableColumnFound || tableHeaderFound || tableFooterFound
- || tableBodyFound) {
- 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",
- "(table-header?,table-footer?,table-body+)");
- }
- } else if ("table-header".equals(localName)) {
- if (tableHeaderFound) {
- tooManyNodesError(loc, "table-header");
- } else {
- tableHeaderFound = true;
- if (tableFooterFound || tableBodyFound) {
- nodesOutOfOrderError(loc, "fo:table-header",
- "(table-footer?,table-body+)");
- }
- }
- } else if ("table-footer".equals(localName)) {
- if (tableFooterFound) {
- tooManyNodesError(loc, "table-footer");
- } else {
- tableFooterFound = true;
- if (tableBodyFound && getUserAgent().validateStrictly()) {
- nodesOutOfOrderError(loc, "fo:table-footer",
- "(table-body+)");
- }
- }
- } else if ("table-body".equals(localName)) {
- tableBodyFound = true;
- } else {
- invalidChildError(loc, nsURI, localName);
- }
- } else {
- invalidChildError(loc, nsURI, localName);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- protected void endOfNode() throws FOPException {
-
- if (!tableBodyFound) {
- missingChildElementError(
- "(marker*,table-column*,table-header?,table-footer?"
- + ",table-body+)");
- }
- if (!inMarker()) {
- /* clean up */
- for (int i = columns.size(); --i >= 0;) {
- TableColumn col = (TableColumn) columns.get(i);
- if (col != null) {
- col.releasePropertyList();
- }
- }
- this.propList = null;
- rowGroupBuilder = null;
- }
- getFOEventHandler().endTable(this);
-
- }
-
- /**
- * {@inheritDoc}
- */
- protected void addChildNode(FONode child) throws FOPException {
-
- int childId = child.getNameId();
-
- switch (childId) {
- case FO_TABLE_COLUMN:
- hasExplicitColumns = true;
- if (!inMarker()) {
- addColumnNode((TableColumn) child);
- } else {
- columns.add((TableColumn) child);
- }
- break;
- case FO_TABLE_HEADER:
- case FO_TABLE_FOOTER:
- case FO_TABLE_BODY:
- if (!columnsFinalized) {
- columnsFinalized = true;
- if (hasExplicitColumns) {
- finalizeColumns();
- rowGroupBuilder = new FixedColRowGroupBuilder(this);
- } else {
- rowGroupBuilder = new VariableColRowGroupBuilder(this);
- }
-
- }
- switch (childId) {
- case FO_TABLE_FOOTER:
- tableFooter = (TableBody) child;
- break;
- case FO_TABLE_HEADER:
- tableHeader = (TableBody) child;
- break;
- default:
- super.addChildNode(child);
- }
- break;
- default:
- super.addChildNode(child);
- }
- }
-
- private void finalizeColumns() throws FOPException {
- for (int i = 0; i < columns.size(); i++) {
- if (columns.get(i) == null) {
- columns.set(i, createImplicitColumn(i + 1));
- }
- }
- }
-
- /** {@inheritDoc} */
- public Table getTable() {
- return this;
- }
-
- /**
- * Creates the appropriate number of additional implicit columns to match the given
- * column number. Used when the table has no explicit column: the number of columns is
- * then determined by the row that has the most columns.
- *
- * @param columnNumber the table must at least have this number of column
- * @throws FOPException if there was an error creating the property list for implicit
- * columns
- */
- void ensureColumnNumber(int columnNumber) throws FOPException {
- assert !hasExplicitColumns;
- for (int i = columns.size() + 1; i <= columnNumber; i++) {
- columns.add(createImplicitColumn(i));
- }
- ((VariableColRowGroupBuilder) rowGroupBuilder).ensureNumberOfColumns(columnNumber);
- if (tableHeader != null) {
- for (Iterator iter = tableHeader.getRowGroups().iterator(); iter.hasNext();) {
- VariableColRowGroupBuilder.fillWithEmptyGridUnits((List) iter.next(),
- columnNumber);
- }
- }
- if (tableFooter != null) {
- for (Iterator iter = tableFooter.getRowGroups().iterator(); iter.hasNext();) {
- VariableColRowGroupBuilder.fillWithEmptyGridUnits((List) iter.next(),
- columnNumber);
- }
- }
- FONodeIterator bodyIter = getChildNodes();
- if (bodyIter != null) {
- while (bodyIter.hasNext()) {
- FONode node = bodyIter.nextNode();
- if (node instanceof TableBody) { // AFAIK, may be a marker
- for (Iterator iter = ((TableBody) node).getRowGroups().iterator();
- iter.hasNext();) {
- VariableColRowGroupBuilder.fillWithEmptyGridUnits((List) iter.next(),
- columnNumber);
- }
- }
- }
- }
- }
-
- private TableColumn createImplicitColumn(int colNumber)
- throws FOPException {
- TableColumn implicitColumn = new TableColumn(this, true);
- PropertyList pList = new StaticPropertyList(
- implicitColumn, this.propList);
- pList.setWritingMode();
- implicitColumn.bind(pList);
- implicitColumn.setColumnWidth(new TableColLength(1.0, implicitColumn));
- implicitColumn.setColumnNumber(colNumber);
- return implicitColumn;
- }
-
- /**
- * Adds a column to the columns List, and updates the columnIndex
- * used for determining initial values for column-number
- *
- * @param col the column to add
- * @throws FOPException
- */
- private void addColumnNode(TableColumn col) {
-
- int colNumber = col.getColumnNumber();
- int colRepeat = col.getNumberColumnsRepeated();
-
- /* 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);
- }
-
- // 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);
- }
-
- columnNumberManager.signalUsedColumnNumbers(colNumber, colNumber + colRepeat - 1);
- }
-
- boolean hasExplicitColumns() {
- return hasExplicitColumns;
- }
-
- /** @return true of table-layout="auto" */
- public boolean isAutoLayout() {
- return (tableLayout == EN_AUTO);
- }
-
- /**
- * Returns the list of table-column elements.
- *
- * @return a list of {@link TableColumn} elements, may contain null elements
- */
- public List getColumns() {
- return columns;
- }
-
- /**
- * Returns the column at the given index.
- *
- * @param index index of the column to be retrieved, 0-based
- * @return the corresponding column (may be an implicitly created column)
- */
- TableColumn getColumn(int index) {
- return (TableColumn) columns.get(index);
- }
-
- /**
- * Returns the number of columns of this table.
- *
- * @return the number of columns, implicit or explicit, in this table
- */
- int getNumberOfColumns() {
- return columns.size();
- }
-
- /** @return the body for the table-header. */
- public TableBody getTableHeader() {
- return tableHeader;
- }
-
- /** @return the body for the table-footer. */
- public TableBody getTableFooter() {
- return tableFooter;
- }
-
- /** @return true if the table-header should be omitted at breaks */
- public boolean omitHeaderAtBreak() {
- return (this.tableOmitHeaderAtBreak == EN_TRUE);
- }
-
- /** @return true if the table-footer should be omitted at breaks */
- public boolean omitFooterAtBreak() {
- return (this.tableOmitFooterAtBreak == EN_TRUE);
- }
-
- /**
- * @return the "inline-progression-dimension" property.
- */
- public LengthRangeProperty getInlineProgressionDimension() {
- return inlineProgressionDimension;
- }
-
- /**
- * @return the "block-progression-dimension" property.
- */
- public LengthRangeProperty getBlockProgressionDimension() {
- return blockProgressionDimension;
- }
-
- /**
- * @return the Common Margin Properties-Block.
- */
- public CommonMarginBlock getCommonMarginBlock() {
- return commonMarginBlock;
- }
-
- /**
- * @return the Common Border, Padding, and Background Properties.
- */
- public CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
- return commonBorderPaddingBackground;
- }
-
- /** @return the "break-after" property. */
- public int getBreakAfter() {
- return breakAfter;
- }
-
- /** @return the "break-before" property. */
- public int getBreakBefore() {
- return breakBefore;
- }
-
- /** @return the "keep-with-next" property. */
- public KeepProperty getKeepWithNext() {
- return keepWithNext;
- }
-
- /** @return the "keep-with-previous" property. */
- public KeepProperty getKeepWithPrevious() {
- return keepWithPrevious;
- }
-
- /** @return the "keep-together" property. */
- public KeepProperty getKeepTogether() {
- return keepTogether;
- }
-
- /**
- * Convenience method to check if a keep-together constraint is specified.
- * @return true if keep-together is active.
- */
- public boolean mustKeepTogether() {
- return !getKeepTogether().getWithinPage().isAuto()
- || !getKeepTogether().getWithinColumn().isAuto();
- }
-
- /** @return the "border-collapse" property. */
- public int getBorderCollapse() {
- return borderCollapse;
- }
-
- /** @return true if the separate border model is active */
- 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;
- }
-
- /** @return the "fox:orphan-content-limit" extension property */
- public Length getOrphanContentLimit() {
- return orphanContentLimit;
- }
-
- /** {@inheritDoc} */
- public String getLocalName() {
- return "table";
- }
-
- /** {@inheritDoc} */
- public int getNameId() {
- return FO_TABLE;
- }
-
- /**
- * {@inheritDoc}
- */
- public FONode clone(FONode parent, boolean removeChildren)
- throws FOPException {
- Table clone = (Table) super.clone(parent, removeChildren);
- clone.columnsFinalized = false;
- if (removeChildren) {
- clone.columns = new ArrayList();
- clone.tableHeader = null;
- clone.tableFooter = null;
- }
- return clone;
- }
-
- /** {@inheritDoc} */
- public ColumnNumberManager getColumnNumberManager() {
- return columnNumberManager;
- }
-
- RowGroupBuilder getRowGroupBuilder() {
- return rowGroupBuilder;
- }
-}
+++ /dev/null
-/*
- * 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;
-
-// XML
-import org.xml.sax.Locator;
-
-import org.apache.fop.apps.FOPException;
-import org.apache.fop.fo.FONode;
-import org.apache.fop.fo.FObj;
-import org.apache.fop.fo.ValidationException;
-
-/**
- * Class modelling the fo:table-and-caption property.
- * @todo needs implementation
- */
-public class TableAndCaption extends FObj {
- // The value of properties relevant for fo:table-and-caption.
- // Unused but valid items, commented out for performance:
- // private CommonAccessibility commonAccessibility;
- // private CommonAural commonAural;
- // private CommonBorderPaddingBackground commonBorderPaddingBackground;
- // private CommonMarginBlock commonMarginBlock;
- // private CommonRelativePosition commonRelativePosition;
- // private int breakAfter;
- // private int breakBefore;
- // private int captionSide;
- // private int intrusionDisplace;
- // private KeepProperty keepTogether;
- // private KeepProperty keepWithNext;
- // private KeepProperty keepWithPrevious;
- // private int textAlign;
- // End of property values
-
- static boolean notImplementedWarningGiven = false;
-
- /** used for FO validation */
- private boolean tableCaptionFound = false;
- private boolean tableFound = false;
-
- /**
- * @param parent FONode that is the parent of this object
- */
- public TableAndCaption(FONode parent) {
- super(parent);
-
- if (!notImplementedWarningGiven) {
- log.warn("fo:table-and-caption is not yet implemented.");
- notImplementedWarningGiven = true;
- }
- }
-
- /**
- * Make sure content model satisfied, if so then tell the
- * FOEventHandler that we are at the end of the flow.
- * {@inheritDoc}
- */
- protected void endOfNode() throws FOPException {
- if (!tableFound) {
- missingChildElementError("marker* table-caption? table");
- }
- }
-
- /**
- * {@inheritDoc}
- * XSL Content Model: marker* table-caption? table
- */
- protected void validateChildNode(Locator loc, String nsURI, String localName)
- throws ValidationException {
-
- if (FO_URI.equals(nsURI) && localName.equals("marker")) {
- if (tableCaptionFound) {
- nodesOutOfOrderError(loc, "fo:marker", "fo:table-caption");
- } else if (tableFound) {
- nodesOutOfOrderError(loc, "fo:marker", "fo:table");
- }
- } else if (FO_URI.equals(nsURI) && localName.equals("table-caption")) {
- if (tableCaptionFound) {
- tooManyNodesError(loc, "fo:table-caption");
- } else if (tableFound) {
- nodesOutOfOrderError(loc, "fo:table-caption", "fo:table");
- } else {
- tableCaptionFound = true;
- }
- } else if (FO_URI.equals(nsURI) && localName.equals("table")) {
- if (tableFound) {
- tooManyNodesError(loc, "fo:table");
- } else {
- tableFound = true;
- }
- } else {
- invalidChildError(loc, nsURI, localName);
- }
- }
-
- /** {@inheritDoc} */
- public String getLocalName() {
- return "table-and-caption";
- }
-
- /**
- * {@inheritDoc}
- */
- public int getNameId() {
- return FO_TABLE_AND_CAPTION;
- }
-}
-
+++ /dev/null
-/*
- * 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.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.apache.fop.apps.FOPException;
-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.
- */
-public class TableBody extends TableCellContainer {
- // The value of properties relevant for fo:table-body.
- private CommonBorderPaddingBackground commonBorderPaddingBackground;
- // Unused but valid items, commented out for performance:
- // private CommonAccessibility commonAccessibility;
- // private CommonAural commonAural;
- // 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
- */
- private boolean firstRow = true;
-
- private boolean rowsStarted = false;
-
- private List rowGroups = new LinkedList();
-
- /**
- * @param parent FONode that is the parent of the object
- */
- public TableBody(FONode parent) {
- super(parent);
- }
-
- /**
- * {@inheritDoc}
- */
- public void bind(PropertyList pList) throws FOPException {
- commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
- super.bind(pList);
- }
-
- /**
- * {@inheritDoc}
- */
- public void processNode(String elementName, Locator locator,
- Attributes attlist, PropertyList pList)
- throws FOPException {
- if (!inMarker()) {
- Table t = getTable();
- if (t.hasExplicitColumns()) {
- int size = t.getNumberOfColumns();
- pendingSpans = new ArrayList(size);
- for (int i = 0; i < size; i++) {
- pendingSpans.add(null);
- }
- } else {
- pendingSpans = new ArrayList();
- }
- columnNumberManager = new ColumnNumberManager();
- }
- super.processNode(elementName, locator, attlist, pList);
- }
-
- /**
- * {@inheritDoc}
- */
- protected void startOfNode() throws FOPException {
- getFOEventHandler().startBody(this);
- }
-
- /**
- * {@inheritDoc}
- */
- protected void endOfNode() throws FOPException {
-
- if (!inMarker()) {
- pendingSpans = null;
- columnNumberManager = null;
- }
-
- getFOEventHandler().endBody(this);
-
- if (!(tableRowsFound || tableCellsFound)) {
- if (getUserAgent().validateStrictly()) {
- missingChildElementError("marker* (table-row+|table-cell+)");
- } else {
- log.error("fo:table-body must not be empty. "
- + "Expected: marker* (table-row+|table-cell+)");
- getParent().removeChild(this);
- }
- } else {
- getTable().getRowGroupBuilder().finishLastRowGroup(this);
- }
- }
-
- /**
- * {@inheritDoc} String, String)
- * XSL Content Model: marker* (table-row+|table-cell+)
- */
- protected void validateChildNode(Locator loc, String nsURI, String localName)
- throws ValidationException {
- if (FO_URI.equals(nsURI)) {
- if (localName.equals("marker")) {
- if (tableRowsFound || tableCellsFound) {
- nodesOutOfOrderError(loc, "fo:marker", "(table-row+|table-cell+)");
- }
- } else if (localName.equals("table-row")) {
- tableRowsFound = true;
- if (tableCellsFound) {
- invalidChildError(loc, nsURI, localName, "Either fo:table-rows" +
- " or fo:table-cells may be children of an " + getName() +
- " but not both");
- }
- } else if (localName.equals("table-cell")) {
- tableCellsFound = true;
- if (tableRowsFound) {
- invalidChildError(loc, nsURI, localName,
- "Either fo:table-rows or fo:table-cells "
- + "may be children of an "
- + getName() + " but not both");
- }
- } else {
- invalidChildError(loc, nsURI, localName);
- }
- } else {
- invalidChildError(loc, nsURI, localName);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- protected void addChildNode(FONode child) throws FOPException {
- if (!inMarker()) {
- switch (child.getNameId()) {
- case FO_TABLE_ROW:
- if (rowsStarted) {
- columnNumberManager.prepareForNextRow(pendingSpans);
- getTable().getRowGroupBuilder().signalNewRow(this);
- }
- rowsStarted = true;
- break;
- case FO_TABLE_CELL:
- rowsStarted = true;
- TableCell cell = (TableCell) child;
- addTableCellChild(cell, firstRow);
- if (cell.endsRow()) {
- firstRow = false;
- columnNumberManager.prepareForNextRow(pendingSpans);
- getTable().getRowGroupBuilder().signalNewRow(this);
- }
- break;
- default:
- //nop
- }
- }
- super.addChildNode(child);
- }
-
- void addRowGroup(List rowGroup) {
- rowGroups.add(rowGroup);
- }
-
- List getRowGroups() {
- return rowGroups;
- }
-
- /**
- * @return the Common Border, Padding, and Background Properties.
- */
- public CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
- return commonBorderPaddingBackground;
- }
-
- /** {@inheritDoc} */
- public String getLocalName() {
- return "table-body";
- }
-
- /**
- * {@inheritDoc}
- */
- public int getNameId() {
- return FO_TABLE_BODY;
- }
-
- /**
- * @param obj table row in question
- * @return true if the given table row is the first row of this body.
- */
- public boolean isFirst(TableRow obj) {
- return (firstChild == null
- || firstChild == obj);
- }
-
- void signalNewRow() {
- if (rowsStarted) {
- firstRow = false;
- TableCell previousCell = (TableCell) getChildNodes().lastNode();
- if (!previousCell.endsRow()) {
- columnNumberManager.prepareForNextRow(pendingSpans);
- getTable().getRowGroupBuilder().signalNewRow(this);
- }
- }
- rowsStarted = true;
- }
-
-}
+++ /dev/null
-/*
- * 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;
-
-// XML
-import org.xml.sax.Locator;
-
-import org.apache.fop.apps.FOPException;
-import org.apache.fop.fo.FONode;
-import org.apache.fop.fo.FObj;
-import org.apache.fop.fo.PropertyList;
-import org.apache.fop.fo.ValidationException;
-
-
-/**
- * Class modelling the fo:table-caption object.
- */
-public class TableCaption extends FObj {
- // The value of properties relevant for fo:table-caption.
- // Unused but valid items, commented out for performance:
- // private CommonAural commonAural;
- // private CommonRelativePosition commonRelativePosition;
- // private LengthRangeProperty blockProgressionDimension;
- // private Length height;
- // private LengthRangeProperty inlineProgressionDimension;
- // private int intrusionDisplace;
- // private KeepProperty keepTogether;
- // private Length width;
- // End of property values
-
- /** used for FO validation */
- private boolean blockItemFound = false;
-
- static boolean notImplementedWarningGiven = false;
-
- /**
- * @param parent FONode that is the parent of this object
- */
- public TableCaption(FONode parent) {
- super(parent);
-
- if (!notImplementedWarningGiven) {
- log.warn("fo:table-caption is not yet implemented.");
- notImplementedWarningGiven = true;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void bind(PropertyList pList) throws FOPException {
- super.bind(pList);
- }
-
- /**
- * {@inheritDoc}
- */
- protected void endOfNode() throws FOPException {
- if (firstChild == null) {
- missingChildElementError("marker* (%block;)");
- }
- }
-
- /**
- * {@inheritDoc}
- * XSL Content Model: marker* (%block;)
- */
- protected void validateChildNode(Locator loc, String nsURI, String localName)
- throws ValidationException {
- if (FO_URI.equals(nsURI) && localName.equals("marker")) {
- if (blockItemFound) {
- nodesOutOfOrderError(loc, "fo:marker", "(%block;)");
- }
- } else if (!isBlockItem(nsURI, localName)) {
- invalidChildError(loc, nsURI, localName);
- } else {
- blockItemFound = true;
- }
- }
-
- /** {@inheritDoc} */
- public String getLocalName() {
- return "table-caption";
- }
-
- /**
- * {@inheritDoc}
- */
- public int getNameId() {
- return FO_TABLE_CAPTION;
- }
-}
-
+++ /dev/null
-/*
- * 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 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.apache.fop.fo.properties.LengthRangeProperty;
-
-/**
- * Class modelling the fo:table-cell object.
- */
-public class TableCell extends TableFObj {
- // The value of properties relevant for fo:table-cell.
- private CommonBorderPaddingBackground commonBorderPaddingBackground;
- private LengthRangeProperty blockProgressionDimension;
- private int columnNumber;
- private int displayAlign;
- private int emptyCells;
- private int endsRow;
- private int numberColumnsSpanned;
- private int numberRowsSpanned;
- private int startsRow;
- private Length width;
- // Unused but valid items, commented out for performance:
- // private CommonAccessibility commonAccessibility;
- // private CommonAural commonAural;
- // private CommonRelativePosition commonRelativePosition;
- // private int relativeAlign;
- // private Length height;
- // private LengthRangeProperty inlineProgressionDimension;
- // private KeepProperty keepTogether;
- // private KeepProperty keepWithNext;
- // private KeepProperty keepWithPrevious;
- // End of property values
-
- /** used for FO validation */
- private boolean blockItemFound = false;
-
- /**
- * @param parent FONode that is the parent of this object
- */
- public TableCell(FONode parent) {
- super(parent);
- }
-
- /**
- * {@inheritDoc}
- */
- public void bind(PropertyList pList) throws FOPException {
- super.bind(pList);
- commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
- 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();
- width = pList.get(PR_WIDTH).getLength();
- }
-
- /**
- * {@inheritDoc}
- */
- protected void startOfNode() throws FOPException {
- super.startOfNode();
- getFOEventHandler().startCell(this);
- }
-
- /**
- * Make sure content model satisfied, if so then tell the
- * FOEventHandler that we are at the end of the flow.
- * {@inheritDoc}
- */
- protected void endOfNode() throws FOPException {
- if (!blockItemFound) {
- if (getUserAgent().validateStrictly()) {
- missingChildElementError("marker* (%block;)+");
- } else if (firstChild != null) {
- log.warn("fo:table-cell content that is not "
- + "enclosed by a fo:block will be dropped/ignored.");
- }
- }
- 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.");
- }
- getFOEventHandler().endCell(this);
- }
-
- /**
- * {@inheritDoc}
- * XSL Content Model: marker* (%block;)+
- */
- protected void validateChildNode(Locator loc, String nsURI, String localName)
- throws ValidationException {
- if (FO_URI.equals(nsURI) && localName.equals("marker")) {
- if (blockItemFound) {
- nodesOutOfOrderError(loc, "fo:marker", "(%block;)");
- }
- } else if (!isBlockItem(nsURI, localName)) {
- invalidChildError(loc, nsURI, localName);
- } else {
- blockItemFound = true;
- }
- }
-
- /** {@inheritDoc} */
- public boolean generatesReferenceAreas() {
- return true;
- }
-
- /**
- * @return the Common Border, Padding, and Background Properties.
- */
- public CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
- return this.commonBorderPaddingBackground;
- }
-
- /**
- * @return the "column-number" property.
- */
- 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.
- */
- public int getNumberColumnsSpanned() {
- return Math.max(numberColumnsSpanned, 1);
- }
-
- /**
- * @return the "number-rows-spanned" property.
- */
- public int getNumberRowsSpanned() {
- return Math.max(numberRowsSpanned, 1);
- }
-
- /**
- * @return the "block-progression-dimension" property.
- */
- public LengthRangeProperty getBlockProgressionDimension() {
- return blockProgressionDimension;
- }
-
- /** @return the display-align property. */
- 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";
- }
-
- /**
- * {@inheritDoc}
- */
- public final int getNameId() {
- return FO_TABLE_CELL;
- }
-
-}
+++ /dev/null
-/*
- * 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.List;
-
-import org.apache.fop.apps.FOPException;
-import org.apache.fop.datatypes.Length;
-import org.apache.fop.fo.FONode;
-import org.apache.fop.fo.ValidationException;
-
-/**
- * A common class for fo:table-body and fo:table-row which both can contain fo:table-cell.
- */
-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, boolean firstRow) throws FOPException {
- int colNumber = cell.getColumnNumber();
- int colSpan = cell.getNumberColumnsSpanned();
- int rowSpan = cell.getNumberRowsSpanned();
-
- Table t = getTable();
- if (t.hasExplicitColumns()) {
- if (colNumber + colSpan - 1 > t.getNumberOfColumns()) {
- throw new ValidationException(FONode.errorText(locator) + "column-number or "
- + "number of cells in the row overflows the number of fo:table-column "
- + "specified for the table.");
- }
- } else {
- t.ensureColumnNumber(colNumber + colSpan - 1);
- // re-cap the size of pendingSpans
- while (pendingSpans.size() < colNumber + colSpan - 1) {
- pendingSpans.add(null);
- }
- }
- if (firstRow) {
- handleCellWidth(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);
-
- t.getRowGroupBuilder().addTableCell(cell);
- }
-
- 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 = colNumber; i < colNumber + colSpan; ++i) {
- TableColumn col = t.getColumn(i - 1);
- if (colWidth != null) {
- col.setColumnWidth(colWidth);
- }
- }
- }
-
- /** {@inheritDoc} */
- public ColumnNumberManager getColumnNumberManager() {
- return columnNumberManager;
- }
-
-}
+++ /dev/null
-/*
- * 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;
-
-// XML
-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.expr.PropertyException;
-import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
-import org.apache.fop.fo.properties.Property;
-import org.apache.fop.fo.properties.TableColLength;
-
-/**
- * Class modelling the fo:table-column object.
- */
-public class TableColumn extends TableFObj {
- // The value of properties relevant for fo:table-column.
- private CommonBorderPaddingBackground commonBorderPaddingBackground;
- private int columnNumber;
- private Length columnWidth;
- private int numberColumnsRepeated;
- private int numberColumnsSpanned;
- // Unused but valid items, commented out for performance:
- // private int visibility;
- // End of property values
-
- private boolean implicitColumn;
- 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 implicit true if this table-column has automatically been created (does not
- * correspond to an explicit fo:table-column in the input document)
- */
- public TableColumn(FONode parent, boolean implicit) {
- super(parent);
- this.implicitColumn = implicit;
- }
-
-
- /**
- * {@inheritDoc}
- */
- public void bind(PropertyList pList) throws FOPException {
- commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
- columnNumber = pList.get(PR_COLUMN_NUMBER).getNumeric().getValue();
- columnWidth = pList.get(PR_COLUMN_WIDTH).getLength();
- numberColumnsRepeated = pList.get(PR_NUMBER_COLUMNS_REPEATED)
- .getNumeric().getValue();
- 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);
- }
- if (numberColumnsSpanned <= 0) {
- throw new PropertyException("number-columns-spanned must be 1 or bigger, "
- + "but got " + numberColumnsSpanned);
- }
-
- /* check for unspecified width and replace with default of
- * proportional-column-width(1), in case of fixed table-layout
- * warn only for explicit columns
- */
- if (columnWidth.getEnum() == EN_AUTO) {
- if (!this.implicitColumn && !getTable().isAutoLayout()) {
- log.warn("table-layout=\"fixed\" and column-width unspecified "
- + "=> falling back to proportional-column-width(1)");
- }
- 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
- * (cleared in Table.endOfNode())
- */
- if (!this.implicitColumn) {
- this.pList = pList;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- protected void startOfNode() throws FOPException {
- getFOEventHandler().startColumn(this);
- }
-
- /**
- * {@inheritDoc}
- */
- protected void endOfNode() throws FOPException {
- getFOEventHandler().endColumn(this);
- }
-
- /**
- * {@inheritDoc}
- * XSL Content Model: empty
- */
- protected void validateChildNode(Locator loc,
- String nsURI, String localName)
- throws ValidationException {
- invalidChildError(loc, nsURI, localName);
- }
-
- /**
- * @return the Common Border, Padding, and Background Properties.
- */
- public CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
- return commonBorderPaddingBackground;
- }
-
- /**
- * @return the "column-width" property.
- */
- public Length getColumnWidth() {
- return columnWidth;
- }
-
- /**
- * Sets the column width.
- * @param columnWidth the column width
- */
- public void setColumnWidth(Length columnWidth) {
- this.columnWidth = columnWidth;
- }
-
- /**
- * @return the "column-number" property.
- */
- public int getColumnNumber() {
- return columnNumber;
- }
-
- /**
- * Used for setting the column-number for an implicit column
- * @param columnNumber
- */
- protected void setColumnNumber(int columnNumber) {
- this.columnNumber = columnNumber;
- }
-
- /** @return value for number-columns-repeated. */
- public int getNumberColumnsRepeated() {
- return numberColumnsRepeated;
- }
-
- /** @return value for number-columns-spanned. */
- public int getNumberColumnsSpanned() {
- return numberColumnsSpanned;
- }
-
- /** {@inheritDoc} */
- public String getLocalName() {
- return "table-column";
- }
-
- /** {@inheritDoc} */
- 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.
- * Note that this only used to provide better
- * user feedback (see ColumnSetup).
- * @return true if this table-column has been created as default column
- */
- public boolean isImplicitColumn() {
- return implicitColumn;
- }
-
- /** {@inheritDoc} */
- public String toString() {
- StringBuffer sb = new StringBuffer("fo:table-column");
- sb.append(" column-number=").append(getColumnNumber());
- if (getNumberColumnsRepeated() > 1) {
- sb.append(" number-columns-repeated=")
- .append(getNumberColumnsRepeated());
- }
- if (getNumberColumnsSpanned() > 1) {
- sb.append(" number-columns-spanned=")
- .append(getNumberColumnsSpanned());
- }
- sb.append(" column-width=").append(getColumnWidth());
- return sb.toString();
- }
-
- /**
- * Retrieve a property value through its Id; used by
- * from-table-column() function
- *
- * @param propId the id for the property to retrieve
- * @return the requested Property
- * @throws PropertyException
- */
- public Property getProperty(int propId) throws PropertyException {
- return this.pList.get(propId);
- }
-
- /**
- * Clear the reference to the PropertyList (retained for
- * from-table-column())
- */
- protected void releasePropertyList() {
- this.pList = null;
- }
-
-}
+++ /dev/null
-/*
- * 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 org.apache.fop.apps.FOPException;
-import org.apache.fop.datatypes.Numeric;
-import org.apache.fop.datatypes.ValidationPercentBaseContext;
-import org.apache.fop.fo.Constants;
-import org.apache.fop.fo.FONode;
-import org.apache.fop.fo.FObj;
-import org.apache.fop.fo.PropertyList;
-import org.apache.fop.fo.expr.PropertyException;
-import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
-import org.apache.fop.fo.properties.NumberProperty;
-import org.apache.fop.fo.properties.Property;
-
-/**
- * Common base class for table-related FOs
- */
-public abstract class TableFObj extends FObj {
-
- private Numeric borderAfterPrecedence;
- private Numeric borderBeforePrecedence;
- private Numeric borderEndPrecedence;
- private Numeric borderStartPrecedence;
-
- /**
- * Main constructor
- *
- * @param parent the parent node
- */
- public TableFObj(FONode parent) {
- super(parent);
- }
-
- /**
- * {@inheritDoc}
- */
- public void bind(PropertyList pList) throws FOPException {
- super.bind(pList);
- borderAfterPrecedence = pList.get(PR_BORDER_AFTER_PRECEDENCE).getNumeric();
- borderBeforePrecedence = pList.get(PR_BORDER_BEFORE_PRECEDENCE).getNumeric();
- borderEndPrecedence = pList.get(PR_BORDER_END_PRECEDENCE).getNumeric();
- borderStartPrecedence = pList.get(PR_BORDER_START_PRECEDENCE).getNumeric();
- if (getNameId() != FO_TABLE //Separate check for fo:table in Table.java
- && getNameId() != FO_TABLE_CELL
- && getCommonBorderPaddingBackground().hasPadding(
- ValidationPercentBaseContext.getPseudoContext())) {
- attributeWarning(
- "padding-* properties are not applicable to " + getName()
- + ", but a non-zero value for padding was found.");
- }
- }
-
- /**
- *
- * @param side the side for which to return the border precedence
- * @return the "border-precedence" value for the given side
- */
- public Numeric getBorderPrecedence(int side) {
- switch (side) {
- case CommonBorderPaddingBackground.BEFORE:
- return borderBeforePrecedence;
- case CommonBorderPaddingBackground.AFTER:
- return borderAfterPrecedence;
- case CommonBorderPaddingBackground.START:
- return borderStartPrecedence;
- case CommonBorderPaddingBackground.END:
- return borderEndPrecedence;
- default:
- return null;
- }
- }
-
- /**
- * Convenience method to returns a reference
- * to the base Table instance
- *
- * @return the base table instance
- *
- */
- public Table 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();
-
- /**
- * PropertyMaker subclass for the column-number property
- *
- */
- public static class ColumnNumberPropertyMaker extends NumberProperty.Maker {
-
- /**
- * Constructor
- * @param propId the id of the property for which the maker should
- * be created
- */
- public ColumnNumberPropertyMaker(int propId) {
- super(propId);
- }
-
- /**
- * {@inheritDoc}
- */
- public Property make(PropertyList propertyList)
- throws PropertyException {
- FObj fo = propertyList.getFObj();
-
- 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
- * 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)
- throws PropertyException {
- Property p = super.make(propertyList, value, fo);
-
- 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 "
- + columnIndexManager.getCurrentColumnNumber());
- return NumberProperty.getInstance(columnIndexManager.getCurrentColumnNumber());
- } else {
- double tmpIndex = p.getNumeric().getNumericValue();
- if (tmpIndex - columnIndex > 0.0) {
- columnIndex = (int) Math.round(tmpIndex);
- log.warn("Rounding specified column-number of "
- + tmpIndex + " to " + columnIndex);
- p = NumberProperty.getInstance(columnIndex);
- }
- }
-
- int colSpan = propertyList.get(Constants.PR_NUMBER_COLUMNS_SPANNED)
- .getNumeric().getValue();
- int i = -1;
- while (++i < colSpan) {
- if (columnIndexManager.isColumnNumberUsed(columnIndex + i)) {
- /* if column-number is already in use by another
- * cell/column => error!
- */
- StringBuffer errorMessage = new StringBuffer();
- errorMessage.append(fo.getName() + " overlaps in column ")
- .append(columnIndex + i);
- org.xml.sax.Locator loc = fo.getLocator();
- if (loc != null && loc.getLineNumber() != -1) {
- errorMessage.append(" (line #")
- .append(loc.getLineNumber()).append(", column #")
- .append(loc.getColumnNumber()).append(")");
- }
- throw new PropertyException(errorMessage.toString());
- }
- }
-
- return p;
- }
- }
-}
+++ /dev/null
-/*
- * 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;
-
-// FOP
-import org.apache.fop.apps.FOPException;
-import org.apache.fop.fo.FONode;
-
-
-/**
- * Class modelling the fo:table-footer object.
- */
-public class TableFooter extends TableBody {
-
- /**
- * @param parent FONode that is the parent of this object
- */
- public TableFooter(FONode parent) {
- super(parent);
- }
-
- /**
- * {@inheritDoc}
- */
- protected void startOfNode() throws FOPException {
- //getFOEventHandler().startBody(this);
- }
-
- /**
- * {@inheritDoc}
- */
- protected void endOfNode() throws FOPException {
-// getFOEventHandler().endFooter(this);
- if (!(tableRowsFound || tableCellsFound)) {
- missingChildElementError("marker* (table-row+|table-cell+)");
- } else {
- getTable().getRowGroupBuilder().finishLastRowGroup(this);
- }
-// convertCellsToRows();
- }
-
- /** {@inheritDoc} */
- public String getLocalName() {
- return "table-footer";
- }
-
- /** {@inheritDoc} */
- public int getNameId() {
- return FO_TABLE_FOOTER;
- }
-}
+++ /dev/null
-/*
- * 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;
-
-// FOP
-import org.apache.fop.apps.FOPException;
-import org.apache.fop.fo.FONode;
-
-
-/**
- * Class modelling the fo:table-header object.
- */
-public class TableHeader extends TableBody {
-
- /**
- * @param parent FONode that is the parent of this object
- */
- public TableHeader(FONode parent) {
- super(parent);
- }
-
- /**
- * {@inheritDoc}
- */
- protected void startOfNode() throws FOPException {
- //getFOEventHandler().startHeader(this);
- }
-
- /**
- * {@inheritDoc}
- */
- protected void endOfNode() throws FOPException {
-// getFOEventHandler().endHeader(this);
- if (!(tableRowsFound || tableCellsFound)) {
- missingChildElementError("marker* (table-row+|table-cell+)");
- } else {
- getTable().getRowGroupBuilder().finishLastRowGroup(this);
- }
-// convertCellsToRows();
- }
-
- /** {@inheritDoc} */
- public String getLocalName() {
- return "table-header";
- }
-
- /** {@inheritDoc} */
- public int getNameId() {
- return FO_TABLE_HEADER;
- }
-}
+++ /dev/null
-/*
- * 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 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.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.
- */
-public class TableRow extends TableCellContainer {
- // The value of properties relevant for fo:table-row.
- private LengthRangeProperty blockProgressionDimension;
- private CommonBorderPaddingBackground commonBorderPaddingBackground;
- private int breakAfter;
- private int breakBefore;
- private Length height;
- private KeepProperty keepTogether;
- private KeepProperty keepWithNext;
- private KeepProperty keepWithPrevious;
- // Unused but valid items, commented out for performance:
- // private CommonAccessibility commonAccessibility;
- // private CommonAural commonAural;
- // private CommonRelativePosition commonRelativePosition;
- // private int visibility;
- // End of property values
-
- /**
- * @param parent FONode that is the parent of this object
- */
- public TableRow(FONode parent) {
- super(parent);
- }
-
- /** {@inheritDoc} */
- public void bind(PropertyList pList) throws FOPException {
- blockProgressionDimension
- = pList.get(PR_BLOCK_PROGRESSION_DIMENSION).getLengthRange();
- commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
- breakAfter = pList.get(PR_BREAK_AFTER).getEnum();
- breakBefore = pList.get(PR_BREAK_BEFORE).getEnum();
- height = pList.get(PR_HEIGHT).getLength();
- keepTogether = pList.get(PR_KEEP_TOGETHER).getKeep();
- keepWithNext = pList.get(PR_KEEP_WITH_NEXT).getKeep();
- keepWithPrevious = pList.get(PR_KEEP_WITH_PREVIOUS).getKeep();
- super.bind(pList);
- }
-
- /** {@inheritDoc} */
- public void processNode(String elementName, Locator locator,
- Attributes attlist, PropertyList pList) throws FOPException {
- if (!inMarker()) {
- TableBody body = (TableBody) parent;
- pendingSpans = body.pendingSpans;
- columnNumberManager = body.columnNumberManager;
- }
- super.processNode(elementName, locator, attlist, pList);
- }
-
- /**
- * {@inheritDoc}
- */
- protected void addChildNode(FONode child) throws FOPException {
- if (!inMarker()) {
- TableCell cell = (TableCell) child;
- TableBody body = (TableBody) getParent();
- addTableCellChild(cell, body.isFirst(this));
- }
- super.addChildNode(child);
- }
-
- /**
- * {@inheritDoc}
- */
- protected void startOfNode() throws FOPException {
- super.startOfNode();
- getFOEventHandler().startRow(this);
- }
-
- /**
- * {@inheritDoc}
- */
- protected void endOfNode() throws FOPException {
- if (firstChild == null) {
- missingChildElementError("(table-cell+)");
- }
- if (!inMarker()) {
- pendingSpans = null;
- columnNumberManager = null;
- }
- getFOEventHandler().endRow(this);
- }
-
- /**
- * {@inheritDoc} String, String)
- * XSL Content Model: (table-cell+)
- */
- 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;
- }
-
- /** @return the "break-before" property. */
- public int getBreakBefore() {
- return breakBefore;
- }
-
- /** @return the "keep-with-previous" property. */
- public KeepProperty getKeepWithPrevious() {
- return keepWithPrevious;
- }
-
- /** @return the "keep-with-next" property. */
- public KeepProperty getKeepWithNext() {
- return keepWithNext;
- }
-
- /** @return the "keep-together" property. */
- public KeepProperty getKeepTogether() {
- return keepTogether;
- }
-
- /**
- * Convenience method to check if a keep-together
- * constraint is specified.
- * @return true if keep-together is active.
- */
- public boolean mustKeepTogether() {
- return !getKeepTogether().getWithinPage().isAuto()
- || !getKeepTogether().getWithinColumn().isAuto();
- }
-
- /**
- * Convenience method to check if a keep-with-next
- * constraint is specified.
- * @return true if keep-with-next is active.
- */
- public boolean mustKeepWithNext() {
- return !getKeepWithNext().getWithinPage().isAuto()
- || !getKeepWithNext().getWithinColumn().isAuto();
- }
-
- /**
- * Convenience method to check if a keep-with-previous
- * constraint is specified.
- * @return true if keep-with-previous is active.
- */
- public boolean mustKeepWithPrevious() {
- return !getKeepWithPrevious().getWithinPage().isAuto()
- || !getKeepWithPrevious().getWithinColumn().isAuto();
- }
-
- /**
- * @return the "block-progression-dimension" property.
- */
- public LengthRangeProperty getBlockProgressionDimension() {
- return blockProgressionDimension;
- }
-
- /**
- * @return the "height" property.
- */
- public Length getHeight() {
- return height;
- }
-
- /**
- * @return the Common Border, Padding, and Background Properties.
- */
- public CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
- return commonBorderPaddingBackground;
- }
-
- /** {@inheritDoc} */
- public String getLocalName() {
- return "table-row";
- }
-
- /** {@inheritDoc} */
- public int getNameId() {
- return FO_TABLE_ROW;
- }
-}
+++ /dev/null
-/*
- * 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.List;
-
-import org.apache.fop.layoutmgr.table.EmptyGridUnit;
-
-/**
- * A row group builder accommodating a variable number of columns. More flexible, but less
- * efficient.
- */
-class VariableColRowGroupBuilder extends RowGroupBuilder {
-
- VariableColRowGroupBuilder(Table t) {
- super(t);
- numberOfColumns = 1;
- }
-
- /**
- * Fills the given row group with empty grid units if necessary, so that it matches
- * the given number of columns.
- *
- * @param rowGroup a List of List of GridUnit
- * @param numberOfColumns the number of columns that the row group must have
- */
- static void fillWithEmptyGridUnits(List rowGroup, int numberOfColumns) {
- for (int i = 0; i < rowGroup.size(); i++) {
- List effRow = (List) rowGroup.get(i);
- for (int j = effRow.size(); j < numberOfColumns; j++) {
- effRow.add(new EmptyGridUnit(null, null, null, j));
- }
- }
- }
-
- /**
- * Updates the current row group to match the given number of columns, by adding empty
- * grid units if necessary.
- *
- * @param numberOfColumns new number of columns
- */
- void ensureNumberOfColumns(int numberOfColumns) {
- this.numberOfColumns = numberOfColumns;
- fillWithEmptyGridUnits(rows, numberOfColumns);
- }
-
-}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.flow.table;
+
+import java.util.BitSet;
+import java.util.List;
+
+import org.apache.fop.fo.flow.table.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);
+ }
+
+ columnNumber = end + 1;
+ 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);
+ }
+
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.flow.table;
+
+/**
+ * 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();
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.flow.table;
+
+
+/**
+ * A row group builder optimised for a fixed number of columns, known before the parsing
+ * of cells starts (that is, if the fo:table has explicit fo:table-column children).
+ */
+class FixedColRowGroupBuilder extends RowGroupBuilder {
+
+
+ FixedColRowGroupBuilder(Table t) {
+ super(t);
+ numberOfColumns = t.getNumberOfColumns();
+ }
+
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.flow.table;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.fop.layoutmgr.table.GridUnit;
+import org.apache.fop.layoutmgr.table.PrimaryGridUnit;
+
+/**
+ * A class that creates groups of rows belonging to a same set of spans. The first row of
+ * such a group has only cells which don't span over several rows, or whose spanning
+ * starts on this row. Similarly, the last row has only non-row spanning cells or spans
+ * which end on this row.
+ */
+abstract class RowGroupBuilder {
+
+ /** Number of columns in the corresponding table. */
+ protected int numberOfColumns;
+
+ /** 0-based, index in the row group. */
+ private int currentRowIndex;
+
+ private Table table;
+
+ /** The rows belonging to this row group. List of List of {@link GridUnit}s. */
+ protected List rows;
+
+ /**
+ * Creates and initialises a new builder for the given table.
+ *
+ * @param t a table
+ */
+ protected RowGroupBuilder(Table t) {
+ table = t;
+ initialize();
+ }
+
+ /**
+ * Prepares this builder for creating a new row group.
+ */
+ private void initialize() {
+ rows = new ArrayList();
+ currentRowIndex = 0;
+ }
+
+ /**
+ * Adds a table-cell to the row-group, creating {@link GridUnit}s accordingly.
+ *
+ * @param cell
+ */
+ void addTableCell(TableCell cell) {
+ for (int i = rows.size(); i < currentRowIndex + cell.getNumberRowsSpanned(); i++) {
+ List effRow = new ArrayList(numberOfColumns);
+ for (int j = 0; j < numberOfColumns; j++) {
+ effRow.add(null);
+ }
+ rows.add(effRow);
+ }
+ int columnIndex = cell.getColumnNumber() - 1;
+ PrimaryGridUnit pgu = new PrimaryGridUnit(cell, table.getColumn(columnIndex), columnIndex,
+ currentRowIndex);
+ List row = (List) rows.get(currentRowIndex);
+ row.set(columnIndex, pgu);
+ for (int j = 1; j < cell.getNumberColumnsSpanned(); j++) {
+ row.set(j + columnIndex,
+ new GridUnit(pgu, table.getColumn(columnIndex + j), columnIndex + j, j));
+ }
+ for (int i = 1; i < cell.getNumberRowsSpanned(); i++) {
+ row = (List) rows.get(currentRowIndex + i);
+ for (int j = 0; j < cell.getNumberColumnsSpanned(); j++) {
+ row.set(j + columnIndex,
+ new GridUnit(pgu, table.getColumn(columnIndex + j), columnIndex + j, j));
+ }
+ }
+
+ }
+
+ /**
+ * Signals that a table row has just ended, potentially finishing the current row
+ * group.
+ *
+ * @param body the table-body containing the row. Its
+ * {@link TableBody#addRowGroup(List)} method will be called if the current row group
+ * is finished.
+ */
+ void signalNewRow(TableBody body) {
+ if (currentRowIndex == rows.size() - 1) {
+ // Means that the current row has no cell spanning over following rows
+ body.addRowGroup(rows);
+ initialize();
+ } else {
+ currentRowIndex++;
+ }
+ }
+
+ /**
+ * Finishes and records the last row-group of the given table-body, if any. If there
+ * is no fo:table-row and the last cell of the table-body didn't have ends-row="true",
+ * then the {@link signalNewRow} method has not been called and the last row group has
+ * yet to be recorded.
+ *
+ * @param tableBody
+ */
+ void finishLastRowGroup(TableBody tableBody) {
+ if (rows.size() > 0) {
+ tableBody.addRowGroup(rows);
+ }
+ // Reset, in case this rowGroupBuilder is re-used for other
+ // table-header/footer/body
+ initialize();
+ }
+
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.flow.table;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.datatypes.Length;
+import org.apache.fop.datatypes.ValidationPercentBaseContext;
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.PropertyList;
+import org.apache.fop.fo.StaticPropertyList;
+import org.apache.fop.fo.ValidationException;
+import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
+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.apache.fop.fo.properties.TableColLength;
+import org.xml.sax.Locator;
+
+/**
+ * Class modelling the fo:table object.
+ */
+public class Table extends TableFObj implements ColumnNumberManagerHolder {
+
+ /** properties */
+ private CommonBorderPaddingBackground commonBorderPaddingBackground;
+ private CommonMarginBlock commonMarginBlock;
+ private LengthRangeProperty blockProgressionDimension;
+ private int borderCollapse;
+ private LengthPairProperty borderSeparation;
+ private int breakAfter;
+ private int breakBefore;
+ private LengthRangeProperty inlineProgressionDimension;
+ private KeepProperty keepTogether;
+ private KeepProperty keepWithNext;
+ private KeepProperty keepWithPrevious;
+ private int tableLayout;
+ private int tableOmitFooterAtBreak;
+ private int tableOmitHeaderAtBreak;
+ // Unused but valid items, commented out for performance:
+ // private CommonAccessibility commonAccessibility;
+ // private CommonAural commonAural;
+ // 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();
+
+ 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 hasExplicitColumns = false;
+ private boolean columnsFinalized = false;
+ private RowGroupBuilder rowGroupBuilder;
+
+ /**
+ * 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
+ */
+ public Table(FONode parent) {
+ super(parent);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void bind(PropertyList pList) throws FOPException {
+ super.bind(pList);
+ commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
+ commonMarginBlock = pList.getMarginBlockProps();
+ blockProgressionDimension = pList.get(PR_BLOCK_PROGRESSION_DIMENSION).getLengthRange();
+ borderCollapse = pList.get(PR_BORDER_COLLAPSE).getEnum();
+ borderSeparation = pList.get(PR_BORDER_SEPARATION).getLengthPair();
+ breakAfter = pList.get(PR_BREAK_AFTER).getEnum();
+ breakBefore = pList.get(PR_BREAK_BEFORE).getEnum();
+ inlineProgressionDimension = pList.get(PR_INLINE_PROGRESSION_DIMENSION).getLengthRange();
+ keepTogether = pList.get(PR_KEEP_TOGETHER).getKeep();
+ keepWithNext = pList.get(PR_KEEP_WITH_NEXT).getKeep();
+ keepWithPrevious = pList.get(PR_KEEP_WITH_PREVIOUS).getKeep();
+ tableLayout = pList.get(PR_TABLE_LAYOUT).getEnum();
+ tableOmitFooterAtBreak = pList.get(PR_TABLE_OMIT_FOOTER_AT_BREAK).getEnum();
+ tableOmitHeaderAtBreak = pList.get(PR_TABLE_OMIT_HEADER_AT_BREAK).getEnum();
+
+ //Bind extension properties
+ widowContentLimit = pList.get(PR_X_WIDOW_CONTENT_LIMIT).getLength();
+ orphanContentLimit = pList.get(PR_X_ORPHAN_CONTENT_LIMIT).getLength();
+
+ if (!blockProgressionDimension.getOptimum(null).isAuto()) {
+ attributeWarning("only a value of \"auto\" for block-progression-dimension has a well-specified"
+ + " behavior on fo:table. Falling back to \"auto\"");
+ // Anyway, the bpd of a table is not used by the layout code
+ }
+ if (tableLayout == EN_AUTO) {
+ attributeWarning("table-layout=\"auto\" is currently not supported by FOP");
+ }
+ if (!isSeparateBorderModel()
+ && getCommonBorderPaddingBackground().hasPadding(
+ ValidationPercentBaseContext.getPseudoContext())) {
+ //See "17.6.2 The collapsing border model" in CSS2
+ attributeWarning("In collapsing border model a table does not have padding"
+ + " (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
+ * (see addDefaultColumn())
+ */
+ this.propList = pList;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void startOfNode() throws FOPException {
+ 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)
+ throws ValidationException {
+ if (FO_URI.equals(nsURI)) {
+ if ("marker".equals(localName)) {
+ if (tableColumnFound || tableHeaderFound || tableFooterFound
+ || tableBodyFound) {
+ 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",
+ "(table-header?,table-footer?,table-body+)");
+ }
+ } else if ("table-header".equals(localName)) {
+ if (tableHeaderFound) {
+ tooManyNodesError(loc, "table-header");
+ } else {
+ tableHeaderFound = true;
+ if (tableFooterFound || tableBodyFound) {
+ nodesOutOfOrderError(loc, "fo:table-header",
+ "(table-footer?,table-body+)");
+ }
+ }
+ } else if ("table-footer".equals(localName)) {
+ if (tableFooterFound) {
+ tooManyNodesError(loc, "table-footer");
+ } else {
+ tableFooterFound = true;
+ if (tableBodyFound && getUserAgent().validateStrictly()) {
+ nodesOutOfOrderError(loc, "fo:table-footer",
+ "(table-body+)");
+ }
+ }
+ } else if ("table-body".equals(localName)) {
+ tableBodyFound = true;
+ } else {
+ invalidChildError(loc, nsURI, localName);
+ }
+ } else {
+ invalidChildError(loc, nsURI, localName);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void endOfNode() throws FOPException {
+
+ if (!tableBodyFound) {
+ missingChildElementError(
+ "(marker*,table-column*,table-header?,table-footer?"
+ + ",table-body+)");
+ }
+ if (!inMarker()) {
+ /* clean up */
+ for (int i = columns.size(); --i >= 0;) {
+ TableColumn col = (TableColumn) columns.get(i);
+ if (col != null) {
+ col.releasePropertyList();
+ }
+ }
+ this.propList = null;
+ rowGroupBuilder = null;
+ }
+ getFOEventHandler().endTable(this);
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void addChildNode(FONode child) throws FOPException {
+
+ int childId = child.getNameId();
+
+ switch (childId) {
+ case FO_TABLE_COLUMN:
+ hasExplicitColumns = true;
+ if (!inMarker()) {
+ addColumnNode((TableColumn) child);
+ } else {
+ columns.add((TableColumn) child);
+ }
+ break;
+ case FO_TABLE_HEADER:
+ case FO_TABLE_FOOTER:
+ case FO_TABLE_BODY:
+ if (!columnsFinalized) {
+ columnsFinalized = true;
+ if (hasExplicitColumns) {
+ finalizeColumns();
+ rowGroupBuilder = new FixedColRowGroupBuilder(this);
+ } else {
+ rowGroupBuilder = new VariableColRowGroupBuilder(this);
+ }
+
+ }
+ switch (childId) {
+ case FO_TABLE_FOOTER:
+ tableFooter = (TableBody) child;
+ break;
+ case FO_TABLE_HEADER:
+ tableHeader = (TableBody) child;
+ break;
+ default:
+ super.addChildNode(child);
+ }
+ break;
+ default:
+ super.addChildNode(child);
+ }
+ }
+
+ private void finalizeColumns() throws FOPException {
+ for (int i = 0; i < columns.size(); i++) {
+ if (columns.get(i) == null) {
+ columns.set(i, createImplicitColumn(i + 1));
+ }
+ }
+ }
+
+ /** {@inheritDoc} */
+ public Table getTable() {
+ return this;
+ }
+
+ /**
+ * Creates the appropriate number of additional implicit columns to match the given
+ * column number. Used when the table has no explicit column: the number of columns is
+ * then determined by the row that has the most columns.
+ *
+ * @param columnNumber the table must at least have this number of column
+ * @throws FOPException if there was an error creating the property list for implicit
+ * columns
+ */
+ void ensureColumnNumber(int columnNumber) throws FOPException {
+ assert !hasExplicitColumns;
+ for (int i = columns.size() + 1; i <= columnNumber; i++) {
+ columns.add(createImplicitColumn(i));
+ }
+ ((VariableColRowGroupBuilder) rowGroupBuilder).ensureNumberOfColumns(columnNumber);
+ if (tableHeader != null) {
+ for (Iterator iter = tableHeader.getRowGroups().iterator(); iter.hasNext();) {
+ VariableColRowGroupBuilder.fillWithEmptyGridUnits((List) iter.next(),
+ columnNumber);
+ }
+ }
+ if (tableFooter != null) {
+ for (Iterator iter = tableFooter.getRowGroups().iterator(); iter.hasNext();) {
+ VariableColRowGroupBuilder.fillWithEmptyGridUnits((List) iter.next(),
+ columnNumber);
+ }
+ }
+ FONodeIterator bodyIter = getChildNodes();
+ if (bodyIter != null) {
+ while (bodyIter.hasNext()) {
+ FONode node = bodyIter.nextNode();
+ if (node instanceof TableBody) { // AFAIK, may be a marker
+ for (Iterator iter = ((TableBody) node).getRowGroups().iterator();
+ iter.hasNext();) {
+ VariableColRowGroupBuilder.fillWithEmptyGridUnits((List) iter.next(),
+ columnNumber);
+ }
+ }
+ }
+ }
+ }
+
+ private TableColumn createImplicitColumn(int colNumber)
+ throws FOPException {
+ TableColumn implicitColumn = new TableColumn(this, true);
+ PropertyList pList = new StaticPropertyList(
+ implicitColumn, this.propList);
+ pList.setWritingMode();
+ implicitColumn.bind(pList);
+ implicitColumn.setColumnWidth(new TableColLength(1.0, implicitColumn));
+ implicitColumn.setColumnNumber(colNumber);
+ return implicitColumn;
+ }
+
+ /**
+ * Adds a column to the columns List, and updates the columnIndex
+ * used for determining initial values for column-number
+ *
+ * @param col the column to add
+ * @throws FOPException
+ */
+ private void addColumnNode(TableColumn col) {
+
+ int colNumber = col.getColumnNumber();
+ int colRepeat = col.getNumberColumnsRepeated();
+
+ /* 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);
+ }
+
+ // 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);
+ }
+
+ columnNumberManager.signalUsedColumnNumbers(colNumber, colNumber + colRepeat - 1);
+ }
+
+ boolean hasExplicitColumns() {
+ return hasExplicitColumns;
+ }
+
+ /** @return true of table-layout="auto" */
+ public boolean isAutoLayout() {
+ return (tableLayout == EN_AUTO);
+ }
+
+ /**
+ * Returns the list of table-column elements.
+ *
+ * @return a list of {@link TableColumn} elements, may contain null elements
+ */
+ public List getColumns() {
+ return columns;
+ }
+
+ /**
+ * Returns the column at the given index.
+ *
+ * @param index index of the column to be retrieved, 0-based
+ * @return the corresponding column (may be an implicitly created column)
+ */
+ TableColumn getColumn(int index) {
+ return (TableColumn) columns.get(index);
+ }
+
+ /**
+ * Returns the number of columns of this table.
+ *
+ * @return the number of columns, implicit or explicit, in this table
+ */
+ int getNumberOfColumns() {
+ return columns.size();
+ }
+
+ /** @return the body for the table-header. */
+ public TableBody getTableHeader() {
+ return tableHeader;
+ }
+
+ /** @return the body for the table-footer. */
+ public TableBody getTableFooter() {
+ return tableFooter;
+ }
+
+ /** @return true if the table-header should be omitted at breaks */
+ public boolean omitHeaderAtBreak() {
+ return (this.tableOmitHeaderAtBreak == EN_TRUE);
+ }
+
+ /** @return true if the table-footer should be omitted at breaks */
+ public boolean omitFooterAtBreak() {
+ return (this.tableOmitFooterAtBreak == EN_TRUE);
+ }
+
+ /**
+ * @return the "inline-progression-dimension" property.
+ */
+ public LengthRangeProperty getInlineProgressionDimension() {
+ return inlineProgressionDimension;
+ }
+
+ /**
+ * @return the "block-progression-dimension" property.
+ */
+ public LengthRangeProperty getBlockProgressionDimension() {
+ return blockProgressionDimension;
+ }
+
+ /**
+ * @return the Common Margin Properties-Block.
+ */
+ public CommonMarginBlock getCommonMarginBlock() {
+ return commonMarginBlock;
+ }
+
+ /**
+ * @return the Common Border, Padding, and Background Properties.
+ */
+ public CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
+ return commonBorderPaddingBackground;
+ }
+
+ /** @return the "break-after" property. */
+ public int getBreakAfter() {
+ return breakAfter;
+ }
+
+ /** @return the "break-before" property. */
+ public int getBreakBefore() {
+ return breakBefore;
+ }
+
+ /** @return the "keep-with-next" property. */
+ public KeepProperty getKeepWithNext() {
+ return keepWithNext;
+ }
+
+ /** @return the "keep-with-previous" property. */
+ public KeepProperty getKeepWithPrevious() {
+ return keepWithPrevious;
+ }
+
+ /** @return the "keep-together" property. */
+ public KeepProperty getKeepTogether() {
+ return keepTogether;
+ }
+
+ /**
+ * Convenience method to check if a keep-together constraint is specified.
+ * @return true if keep-together is active.
+ */
+ public boolean mustKeepTogether() {
+ return !getKeepTogether().getWithinPage().isAuto()
+ || !getKeepTogether().getWithinColumn().isAuto();
+ }
+
+ /** @return the "border-collapse" property. */
+ public int getBorderCollapse() {
+ return borderCollapse;
+ }
+
+ /** @return true if the separate border model is active */
+ 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;
+ }
+
+ /** @return the "fox:orphan-content-limit" extension property */
+ public Length getOrphanContentLimit() {
+ return orphanContentLimit;
+ }
+
+ /** {@inheritDoc} */
+ public String getLocalName() {
+ return "table";
+ }
+
+ /** {@inheritDoc} */
+ public int getNameId() {
+ return FO_TABLE;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public FONode clone(FONode parent, boolean removeChildren)
+ throws FOPException {
+ Table clone = (Table) super.clone(parent, removeChildren);
+ clone.columnsFinalized = false;
+ if (removeChildren) {
+ clone.columns = new ArrayList();
+ clone.tableHeader = null;
+ clone.tableFooter = null;
+ }
+ return clone;
+ }
+
+ /** {@inheritDoc} */
+ public ColumnNumberManager getColumnNumberManager() {
+ return columnNumberManager;
+ }
+
+ RowGroupBuilder getRowGroupBuilder() {
+ return rowGroupBuilder;
+ }
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.flow.table;
+
+// XML
+import org.xml.sax.Locator;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.FObj;
+import org.apache.fop.fo.ValidationException;
+
+/**
+ * Class modelling the fo:table-and-caption property.
+ * @todo needs implementation
+ */
+public class TableAndCaption extends FObj {
+ // The value of properties relevant for fo:table-and-caption.
+ // Unused but valid items, commented out for performance:
+ // private CommonAccessibility commonAccessibility;
+ // private CommonAural commonAural;
+ // private CommonBorderPaddingBackground commonBorderPaddingBackground;
+ // private CommonMarginBlock commonMarginBlock;
+ // private CommonRelativePosition commonRelativePosition;
+ // private int breakAfter;
+ // private int breakBefore;
+ // private int captionSide;
+ // private int intrusionDisplace;
+ // private KeepProperty keepTogether;
+ // private KeepProperty keepWithNext;
+ // private KeepProperty keepWithPrevious;
+ // private int textAlign;
+ // End of property values
+
+ static boolean notImplementedWarningGiven = false;
+
+ /** used for FO validation */
+ private boolean tableCaptionFound = false;
+ private boolean tableFound = false;
+
+ /**
+ * @param parent FONode that is the parent of this object
+ */
+ public TableAndCaption(FONode parent) {
+ super(parent);
+
+ if (!notImplementedWarningGiven) {
+ log.warn("fo:table-and-caption is not yet implemented.");
+ notImplementedWarningGiven = true;
+ }
+ }
+
+ /**
+ * Make sure content model satisfied, if so then tell the
+ * FOEventHandler that we are at the end of the flow.
+ * {@inheritDoc}
+ */
+ protected void endOfNode() throws FOPException {
+ if (!tableFound) {
+ missingChildElementError("marker* table-caption? table");
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ * XSL Content Model: marker* table-caption? table
+ */
+ protected void validateChildNode(Locator loc, String nsURI, String localName)
+ throws ValidationException {
+
+ if (FO_URI.equals(nsURI) && localName.equals("marker")) {
+ if (tableCaptionFound) {
+ nodesOutOfOrderError(loc, "fo:marker", "fo:table-caption");
+ } else if (tableFound) {
+ nodesOutOfOrderError(loc, "fo:marker", "fo:table");
+ }
+ } else if (FO_URI.equals(nsURI) && localName.equals("table-caption")) {
+ if (tableCaptionFound) {
+ tooManyNodesError(loc, "fo:table-caption");
+ } else if (tableFound) {
+ nodesOutOfOrderError(loc, "fo:table-caption", "fo:table");
+ } else {
+ tableCaptionFound = true;
+ }
+ } else if (FO_URI.equals(nsURI) && localName.equals("table")) {
+ if (tableFound) {
+ tooManyNodesError(loc, "fo:table");
+ } else {
+ tableFound = true;
+ }
+ } else {
+ invalidChildError(loc, nsURI, localName);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public String getLocalName() {
+ return "table-and-caption";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getNameId() {
+ return FO_TABLE_AND_CAPTION;
+ }
+}
+
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.flow.table;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.fop.apps.FOPException;
+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.
+ */
+public class TableBody extends TableCellContainer {
+ // The value of properties relevant for fo:table-body.
+ private CommonBorderPaddingBackground commonBorderPaddingBackground;
+ // Unused but valid items, commented out for performance:
+ // private CommonAccessibility commonAccessibility;
+ // private CommonAural commonAural;
+ // 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
+ */
+ private boolean firstRow = true;
+
+ private boolean rowsStarted = false;
+
+ private List rowGroups = new LinkedList();
+
+ /**
+ * @param parent FONode that is the parent of the object
+ */
+ public TableBody(FONode parent) {
+ super(parent);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void bind(PropertyList pList) throws FOPException {
+ commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
+ super.bind(pList);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void processNode(String elementName, Locator locator,
+ Attributes attlist, PropertyList pList)
+ throws FOPException {
+ if (!inMarker()) {
+ Table t = getTable();
+ if (t.hasExplicitColumns()) {
+ int size = t.getNumberOfColumns();
+ pendingSpans = new ArrayList(size);
+ for (int i = 0; i < size; i++) {
+ pendingSpans.add(null);
+ }
+ } else {
+ pendingSpans = new ArrayList();
+ }
+ columnNumberManager = new ColumnNumberManager();
+ }
+ super.processNode(elementName, locator, attlist, pList);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void startOfNode() throws FOPException {
+ getFOEventHandler().startBody(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void endOfNode() throws FOPException {
+
+ if (!inMarker()) {
+ pendingSpans = null;
+ columnNumberManager = null;
+ }
+
+ getFOEventHandler().endBody(this);
+
+ if (!(tableRowsFound || tableCellsFound)) {
+ if (getUserAgent().validateStrictly()) {
+ missingChildElementError("marker* (table-row+|table-cell+)");
+ } else {
+ log.error("fo:table-body must not be empty. "
+ + "Expected: marker* (table-row+|table-cell+)");
+ getParent().removeChild(this);
+ }
+ } else {
+ getTable().getRowGroupBuilder().finishLastRowGroup(this);
+ }
+ }
+
+ /**
+ * {@inheritDoc} String, String)
+ * XSL Content Model: marker* (table-row+|table-cell+)
+ */
+ protected void validateChildNode(Locator loc, String nsURI, String localName)
+ throws ValidationException {
+ if (FO_URI.equals(nsURI)) {
+ if (localName.equals("marker")) {
+ if (tableRowsFound || tableCellsFound) {
+ nodesOutOfOrderError(loc, "fo:marker", "(table-row+|table-cell+)");
+ }
+ } else if (localName.equals("table-row")) {
+ tableRowsFound = true;
+ if (tableCellsFound) {
+ invalidChildError(loc, nsURI, localName, "Either fo:table-rows" +
+ " or fo:table-cells may be children of an " + getName() +
+ " but not both");
+ }
+ } else if (localName.equals("table-cell")) {
+ tableCellsFound = true;
+ if (tableRowsFound) {
+ invalidChildError(loc, nsURI, localName,
+ "Either fo:table-rows or fo:table-cells "
+ + "may be children of an "
+ + getName() + " but not both");
+ }
+ } else {
+ invalidChildError(loc, nsURI, localName);
+ }
+ } else {
+ invalidChildError(loc, nsURI, localName);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void addChildNode(FONode child) throws FOPException {
+ if (!inMarker()) {
+ switch (child.getNameId()) {
+ case FO_TABLE_ROW:
+ if (rowsStarted) {
+ columnNumberManager.prepareForNextRow(pendingSpans);
+ getTable().getRowGroupBuilder().signalNewRow(this);
+ }
+ rowsStarted = true;
+ break;
+ case FO_TABLE_CELL:
+ rowsStarted = true;
+ TableCell cell = (TableCell) child;
+ addTableCellChild(cell, firstRow);
+ if (cell.endsRow()) {
+ firstRow = false;
+ columnNumberManager.prepareForNextRow(pendingSpans);
+ getTable().getRowGroupBuilder().signalNewRow(this);
+ }
+ break;
+ default:
+ //nop
+ }
+ }
+ super.addChildNode(child);
+ }
+
+ void addRowGroup(List rowGroup) {
+ rowGroups.add(rowGroup);
+ }
+
+ List getRowGroups() {
+ return rowGroups;
+ }
+
+ /**
+ * @return the Common Border, Padding, and Background Properties.
+ */
+ public CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
+ return commonBorderPaddingBackground;
+ }
+
+ /** {@inheritDoc} */
+ public String getLocalName() {
+ return "table-body";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getNameId() {
+ return FO_TABLE_BODY;
+ }
+
+ /**
+ * @param obj table row in question
+ * @return true if the given table row is the first row of this body.
+ */
+ public boolean isFirst(TableRow obj) {
+ return (firstChild == null
+ || firstChild == obj);
+ }
+
+ void signalNewRow() {
+ if (rowsStarted) {
+ firstRow = false;
+ TableCell previousCell = (TableCell) getChildNodes().lastNode();
+ if (!previousCell.endsRow()) {
+ columnNumberManager.prepareForNextRow(pendingSpans);
+ getTable().getRowGroupBuilder().signalNewRow(this);
+ }
+ }
+ rowsStarted = true;
+ }
+
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.flow.table;
+
+// XML
+import org.xml.sax.Locator;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.FObj;
+import org.apache.fop.fo.PropertyList;
+import org.apache.fop.fo.ValidationException;
+
+
+/**
+ * Class modelling the fo:table-caption object.
+ */
+public class TableCaption extends FObj {
+ // The value of properties relevant for fo:table-caption.
+ // Unused but valid items, commented out for performance:
+ // private CommonAural commonAural;
+ // private CommonRelativePosition commonRelativePosition;
+ // private LengthRangeProperty blockProgressionDimension;
+ // private Length height;
+ // private LengthRangeProperty inlineProgressionDimension;
+ // private int intrusionDisplace;
+ // private KeepProperty keepTogether;
+ // private Length width;
+ // End of property values
+
+ /** used for FO validation */
+ private boolean blockItemFound = false;
+
+ static boolean notImplementedWarningGiven = false;
+
+ /**
+ * @param parent FONode that is the parent of this object
+ */
+ public TableCaption(FONode parent) {
+ super(parent);
+
+ if (!notImplementedWarningGiven) {
+ log.warn("fo:table-caption is not yet implemented.");
+ notImplementedWarningGiven = true;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void bind(PropertyList pList) throws FOPException {
+ super.bind(pList);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void endOfNode() throws FOPException {
+ if (firstChild == null) {
+ missingChildElementError("marker* (%block;)");
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ * XSL Content Model: marker* (%block;)
+ */
+ protected void validateChildNode(Locator loc, String nsURI, String localName)
+ throws ValidationException {
+ if (FO_URI.equals(nsURI) && localName.equals("marker")) {
+ if (blockItemFound) {
+ nodesOutOfOrderError(loc, "fo:marker", "(%block;)");
+ }
+ } else if (!isBlockItem(nsURI, localName)) {
+ invalidChildError(loc, nsURI, localName);
+ } else {
+ blockItemFound = true;
+ }
+ }
+
+ /** {@inheritDoc} */
+ public String getLocalName() {
+ return "table-caption";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getNameId() {
+ return FO_TABLE_CAPTION;
+ }
+}
+
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.flow.table;
+
+import org.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.apache.fop.fo.properties.LengthRangeProperty;
+
+/**
+ * Class modelling the fo:table-cell object.
+ */
+public class TableCell extends TableFObj {
+ // The value of properties relevant for fo:table-cell.
+ private CommonBorderPaddingBackground commonBorderPaddingBackground;
+ private LengthRangeProperty blockProgressionDimension;
+ private int columnNumber;
+ private int displayAlign;
+ private int emptyCells;
+ private int endsRow;
+ private int numberColumnsSpanned;
+ private int numberRowsSpanned;
+ private int startsRow;
+ private Length width;
+ // Unused but valid items, commented out for performance:
+ // private CommonAccessibility commonAccessibility;
+ // private CommonAural commonAural;
+ // private CommonRelativePosition commonRelativePosition;
+ // private int relativeAlign;
+ // private Length height;
+ // private LengthRangeProperty inlineProgressionDimension;
+ // private KeepProperty keepTogether;
+ // private KeepProperty keepWithNext;
+ // private KeepProperty keepWithPrevious;
+ // End of property values
+
+ /** used for FO validation */
+ private boolean blockItemFound = false;
+
+ /**
+ * @param parent FONode that is the parent of this object
+ */
+ public TableCell(FONode parent) {
+ super(parent);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void bind(PropertyList pList) throws FOPException {
+ super.bind(pList);
+ commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
+ 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();
+ width = pList.get(PR_WIDTH).getLength();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void startOfNode() throws FOPException {
+ super.startOfNode();
+ getFOEventHandler().startCell(this);
+ }
+
+ /**
+ * Make sure content model satisfied, if so then tell the
+ * FOEventHandler that we are at the end of the flow.
+ * {@inheritDoc}
+ */
+ protected void endOfNode() throws FOPException {
+ if (!blockItemFound) {
+ if (getUserAgent().validateStrictly()) {
+ missingChildElementError("marker* (%block;)+");
+ } else if (firstChild != null) {
+ log.warn("fo:table-cell content that is not "
+ + "enclosed by a fo:block will be dropped/ignored.");
+ }
+ }
+ 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.");
+ }
+ getFOEventHandler().endCell(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ * XSL Content Model: marker* (%block;)+
+ */
+ protected void validateChildNode(Locator loc, String nsURI, String localName)
+ throws ValidationException {
+ if (FO_URI.equals(nsURI) && localName.equals("marker")) {
+ if (blockItemFound) {
+ nodesOutOfOrderError(loc, "fo:marker", "(%block;)");
+ }
+ } else if (!isBlockItem(nsURI, localName)) {
+ invalidChildError(loc, nsURI, localName);
+ } else {
+ blockItemFound = true;
+ }
+ }
+
+ /** {@inheritDoc} */
+ public boolean generatesReferenceAreas() {
+ return true;
+ }
+
+ /**
+ * @return the Common Border, Padding, and Background Properties.
+ */
+ public CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
+ return this.commonBorderPaddingBackground;
+ }
+
+ /**
+ * @return the "column-number" property.
+ */
+ 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.
+ */
+ public int getNumberColumnsSpanned() {
+ return Math.max(numberColumnsSpanned, 1);
+ }
+
+ /**
+ * @return the "number-rows-spanned" property.
+ */
+ public int getNumberRowsSpanned() {
+ return Math.max(numberRowsSpanned, 1);
+ }
+
+ /**
+ * @return the "block-progression-dimension" property.
+ */
+ public LengthRangeProperty getBlockProgressionDimension() {
+ return blockProgressionDimension;
+ }
+
+ /** @return the display-align property. */
+ 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";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final int getNameId() {
+ return FO_TABLE_CELL;
+ }
+
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.flow.table;
+
+import java.util.List;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.datatypes.Length;
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.ValidationException;
+
+/**
+ * A common class for fo:table-body and fo:table-row which both can contain fo:table-cell.
+ */
+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, boolean firstRow) throws FOPException {
+ int colNumber = cell.getColumnNumber();
+ int colSpan = cell.getNumberColumnsSpanned();
+ int rowSpan = cell.getNumberRowsSpanned();
+
+ Table t = getTable();
+ if (t.hasExplicitColumns()) {
+ if (colNumber + colSpan - 1 > t.getNumberOfColumns()) {
+ throw new ValidationException(FONode.errorText(locator) + "column-number or "
+ + "number of cells in the row overflows the number of fo:table-column "
+ + "specified for the table.");
+ }
+ } else {
+ t.ensureColumnNumber(colNumber + colSpan - 1);
+ // re-cap the size of pendingSpans
+ while (pendingSpans.size() < colNumber + colSpan - 1) {
+ pendingSpans.add(null);
+ }
+ }
+ if (firstRow) {
+ handleCellWidth(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);
+
+ t.getRowGroupBuilder().addTableCell(cell);
+ }
+
+ 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 = colNumber; i < colNumber + colSpan; ++i) {
+ TableColumn col = t.getColumn(i - 1);
+ if (colWidth != null) {
+ col.setColumnWidth(colWidth);
+ }
+ }
+ }
+
+ /** {@inheritDoc} */
+ public ColumnNumberManager getColumnNumberManager() {
+ return columnNumberManager;
+ }
+
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.flow.table;
+
+// XML
+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.expr.PropertyException;
+import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
+import org.apache.fop.fo.properties.Property;
+import org.apache.fop.fo.properties.TableColLength;
+
+/**
+ * Class modelling the fo:table-column object.
+ */
+public class TableColumn extends TableFObj {
+ // The value of properties relevant for fo:table-column.
+ private CommonBorderPaddingBackground commonBorderPaddingBackground;
+ private int columnNumber;
+ private Length columnWidth;
+ private int numberColumnsRepeated;
+ private int numberColumnsSpanned;
+ // Unused but valid items, commented out for performance:
+ // private int visibility;
+ // End of property values
+
+ private boolean implicitColumn;
+ 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 implicit true if this table-column has automatically been created (does not
+ * correspond to an explicit fo:table-column in the input document)
+ */
+ public TableColumn(FONode parent, boolean implicit) {
+ super(parent);
+ this.implicitColumn = implicit;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void bind(PropertyList pList) throws FOPException {
+ commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
+ columnNumber = pList.get(PR_COLUMN_NUMBER).getNumeric().getValue();
+ columnWidth = pList.get(PR_COLUMN_WIDTH).getLength();
+ numberColumnsRepeated = pList.get(PR_NUMBER_COLUMNS_REPEATED)
+ .getNumeric().getValue();
+ 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);
+ }
+ if (numberColumnsSpanned <= 0) {
+ throw new PropertyException("number-columns-spanned must be 1 or bigger, "
+ + "but got " + numberColumnsSpanned);
+ }
+
+ /* check for unspecified width and replace with default of
+ * proportional-column-width(1), in case of fixed table-layout
+ * warn only for explicit columns
+ */
+ if (columnWidth.getEnum() == EN_AUTO) {
+ if (!this.implicitColumn && !getTable().isAutoLayout()) {
+ log.warn("table-layout=\"fixed\" and column-width unspecified "
+ + "=> falling back to proportional-column-width(1)");
+ }
+ 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
+ * (cleared in Table.endOfNode())
+ */
+ if (!this.implicitColumn) {
+ this.pList = pList;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void startOfNode() throws FOPException {
+ getFOEventHandler().startColumn(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void endOfNode() throws FOPException {
+ getFOEventHandler().endColumn(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ * XSL Content Model: empty
+ */
+ protected void validateChildNode(Locator loc,
+ String nsURI, String localName)
+ throws ValidationException {
+ invalidChildError(loc, nsURI, localName);
+ }
+
+ /**
+ * @return the Common Border, Padding, and Background Properties.
+ */
+ public CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
+ return commonBorderPaddingBackground;
+ }
+
+ /**
+ * @return the "column-width" property.
+ */
+ public Length getColumnWidth() {
+ return columnWidth;
+ }
+
+ /**
+ * Sets the column width.
+ * @param columnWidth the column width
+ */
+ public void setColumnWidth(Length columnWidth) {
+ this.columnWidth = columnWidth;
+ }
+
+ /**
+ * @return the "column-number" property.
+ */
+ public int getColumnNumber() {
+ return columnNumber;
+ }
+
+ /**
+ * Used for setting the column-number for an implicit column
+ * @param columnNumber
+ */
+ protected void setColumnNumber(int columnNumber) {
+ this.columnNumber = columnNumber;
+ }
+
+ /** @return value for number-columns-repeated. */
+ public int getNumberColumnsRepeated() {
+ return numberColumnsRepeated;
+ }
+
+ /** @return value for number-columns-spanned. */
+ public int getNumberColumnsSpanned() {
+ return numberColumnsSpanned;
+ }
+
+ /** {@inheritDoc} */
+ public String getLocalName() {
+ return "table-column";
+ }
+
+ /** {@inheritDoc} */
+ 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.
+ * Note that this only used to provide better
+ * user feedback (see ColumnSetup).
+ * @return true if this table-column has been created as default column
+ */
+ public boolean isImplicitColumn() {
+ return implicitColumn;
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ StringBuffer sb = new StringBuffer("fo:table-column");
+ sb.append(" column-number=").append(getColumnNumber());
+ if (getNumberColumnsRepeated() > 1) {
+ sb.append(" number-columns-repeated=")
+ .append(getNumberColumnsRepeated());
+ }
+ if (getNumberColumnsSpanned() > 1) {
+ sb.append(" number-columns-spanned=")
+ .append(getNumberColumnsSpanned());
+ }
+ sb.append(" column-width=").append(getColumnWidth());
+ return sb.toString();
+ }
+
+ /**
+ * Retrieve a property value through its Id; used by
+ * from-table-column() function
+ *
+ * @param propId the id for the property to retrieve
+ * @return the requested Property
+ * @throws PropertyException
+ */
+ public Property getProperty(int propId) throws PropertyException {
+ return this.pList.get(propId);
+ }
+
+ /**
+ * Clear the reference to the PropertyList (retained for
+ * from-table-column())
+ */
+ protected void releasePropertyList() {
+ this.pList = null;
+ }
+
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.flow.table;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.datatypes.Numeric;
+import org.apache.fop.datatypes.ValidationPercentBaseContext;
+import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.FObj;
+import org.apache.fop.fo.PropertyList;
+import org.apache.fop.fo.expr.PropertyException;
+import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
+import org.apache.fop.fo.properties.NumberProperty;
+import org.apache.fop.fo.properties.Property;
+
+/**
+ * Common base class for table-related FOs
+ */
+public abstract class TableFObj extends FObj {
+
+ private Numeric borderAfterPrecedence;
+ private Numeric borderBeforePrecedence;
+ private Numeric borderEndPrecedence;
+ private Numeric borderStartPrecedence;
+
+ /**
+ * Main constructor
+ *
+ * @param parent the parent node
+ */
+ public TableFObj(FONode parent) {
+ super(parent);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void bind(PropertyList pList) throws FOPException {
+ super.bind(pList);
+ borderAfterPrecedence = pList.get(PR_BORDER_AFTER_PRECEDENCE).getNumeric();
+ borderBeforePrecedence = pList.get(PR_BORDER_BEFORE_PRECEDENCE).getNumeric();
+ borderEndPrecedence = pList.get(PR_BORDER_END_PRECEDENCE).getNumeric();
+ borderStartPrecedence = pList.get(PR_BORDER_START_PRECEDENCE).getNumeric();
+ if (getNameId() != FO_TABLE //Separate check for fo:table in Table.java
+ && getNameId() != FO_TABLE_CELL
+ && getCommonBorderPaddingBackground().hasPadding(
+ ValidationPercentBaseContext.getPseudoContext())) {
+ attributeWarning(
+ "padding-* properties are not applicable to " + getName()
+ + ", but a non-zero value for padding was found.");
+ }
+ }
+
+ /**
+ *
+ * @param side the side for which to return the border precedence
+ * @return the "border-precedence" value for the given side
+ */
+ public Numeric getBorderPrecedence(int side) {
+ switch (side) {
+ case CommonBorderPaddingBackground.BEFORE:
+ return borderBeforePrecedence;
+ case CommonBorderPaddingBackground.AFTER:
+ return borderAfterPrecedence;
+ case CommonBorderPaddingBackground.START:
+ return borderStartPrecedence;
+ case CommonBorderPaddingBackground.END:
+ return borderEndPrecedence;
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Convenience method to returns a reference
+ * to the base Table instance
+ *
+ * @return the base table instance
+ *
+ */
+ public Table 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();
+
+ /**
+ * PropertyMaker subclass for the column-number property
+ *
+ */
+ public static class ColumnNumberPropertyMaker extends NumberProperty.Maker {
+
+ /**
+ * Constructor
+ * @param propId the id of the property for which the maker should
+ * be created
+ */
+ public ColumnNumberPropertyMaker(int propId) {
+ super(propId);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Property make(PropertyList propertyList)
+ throws PropertyException {
+ FObj fo = propertyList.getFObj();
+
+ 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
+ * 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)
+ throws PropertyException {
+ Property p = super.make(propertyList, value, fo);
+
+ 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 "
+ + columnIndexManager.getCurrentColumnNumber());
+ return NumberProperty.getInstance(columnIndexManager.getCurrentColumnNumber());
+ } else {
+ double tmpIndex = p.getNumeric().getNumericValue();
+ if (tmpIndex - columnIndex > 0.0) {
+ columnIndex = (int) Math.round(tmpIndex);
+ log.warn("Rounding specified column-number of "
+ + tmpIndex + " to " + columnIndex);
+ p = NumberProperty.getInstance(columnIndex);
+ }
+ }
+
+ int colSpan = propertyList.get(Constants.PR_NUMBER_COLUMNS_SPANNED)
+ .getNumeric().getValue();
+ int i = -1;
+ while (++i < colSpan) {
+ if (columnIndexManager.isColumnNumberUsed(columnIndex + i)) {
+ /* if column-number is already in use by another
+ * cell/column => error!
+ */
+ StringBuffer errorMessage = new StringBuffer();
+ errorMessage.append(fo.getName() + " overlaps in column ")
+ .append(columnIndex + i);
+ org.xml.sax.Locator loc = fo.getLocator();
+ if (loc != null && loc.getLineNumber() != -1) {
+ errorMessage.append(" (line #")
+ .append(loc.getLineNumber()).append(", column #")
+ .append(loc.getColumnNumber()).append(")");
+ }
+ throw new PropertyException(errorMessage.toString());
+ }
+ }
+
+ return p;
+ }
+ }
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.flow.table;
+
+// FOP
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.FONode;
+
+
+/**
+ * Class modelling the fo:table-footer object.
+ */
+public class TableFooter extends TableBody {
+
+ /**
+ * @param parent FONode that is the parent of this object
+ */
+ public TableFooter(FONode parent) {
+ super(parent);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void startOfNode() throws FOPException {
+ //getFOEventHandler().startBody(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void endOfNode() throws FOPException {
+// getFOEventHandler().endFooter(this);
+ if (!(tableRowsFound || tableCellsFound)) {
+ missingChildElementError("marker* (table-row+|table-cell+)");
+ } else {
+ getTable().getRowGroupBuilder().finishLastRowGroup(this);
+ }
+// convertCellsToRows();
+ }
+
+ /** {@inheritDoc} */
+ public String getLocalName() {
+ return "table-footer";
+ }
+
+ /** {@inheritDoc} */
+ public int getNameId() {
+ return FO_TABLE_FOOTER;
+ }
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.flow.table;
+
+// FOP
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.FONode;
+
+
+/**
+ * Class modelling the fo:table-header object.
+ */
+public class TableHeader extends TableBody {
+
+ /**
+ * @param parent FONode that is the parent of this object
+ */
+ public TableHeader(FONode parent) {
+ super(parent);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void startOfNode() throws FOPException {
+ //getFOEventHandler().startHeader(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void endOfNode() throws FOPException {
+// getFOEventHandler().endHeader(this);
+ if (!(tableRowsFound || tableCellsFound)) {
+ missingChildElementError("marker* (table-row+|table-cell+)");
+ } else {
+ getTable().getRowGroupBuilder().finishLastRowGroup(this);
+ }
+// convertCellsToRows();
+ }
+
+ /** {@inheritDoc} */
+ public String getLocalName() {
+ return "table-header";
+ }
+
+ /** {@inheritDoc} */
+ public int getNameId() {
+ return FO_TABLE_HEADER;
+ }
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.flow.table;
+
+import org.apache.fop.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.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.
+ */
+public class TableRow extends TableCellContainer {
+ // The value of properties relevant for fo:table-row.
+ private LengthRangeProperty blockProgressionDimension;
+ private CommonBorderPaddingBackground commonBorderPaddingBackground;
+ private int breakAfter;
+ private int breakBefore;
+ private Length height;
+ private KeepProperty keepTogether;
+ private KeepProperty keepWithNext;
+ private KeepProperty keepWithPrevious;
+ // Unused but valid items, commented out for performance:
+ // private CommonAccessibility commonAccessibility;
+ // private CommonAural commonAural;
+ // private CommonRelativePosition commonRelativePosition;
+ // private int visibility;
+ // End of property values
+
+ /**
+ * @param parent FONode that is the parent of this object
+ */
+ public TableRow(FONode parent) {
+ super(parent);
+ }
+
+ /** {@inheritDoc} */
+ public void bind(PropertyList pList) throws FOPException {
+ blockProgressionDimension
+ = pList.get(PR_BLOCK_PROGRESSION_DIMENSION).getLengthRange();
+ commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
+ breakAfter = pList.get(PR_BREAK_AFTER).getEnum();
+ breakBefore = pList.get(PR_BREAK_BEFORE).getEnum();
+ height = pList.get(PR_HEIGHT).getLength();
+ keepTogether = pList.get(PR_KEEP_TOGETHER).getKeep();
+ keepWithNext = pList.get(PR_KEEP_WITH_NEXT).getKeep();
+ keepWithPrevious = pList.get(PR_KEEP_WITH_PREVIOUS).getKeep();
+ super.bind(pList);
+ }
+
+ /** {@inheritDoc} */
+ public void processNode(String elementName, Locator locator,
+ Attributes attlist, PropertyList pList) throws FOPException {
+ if (!inMarker()) {
+ TableBody body = (TableBody) parent;
+ pendingSpans = body.pendingSpans;
+ columnNumberManager = body.columnNumberManager;
+ }
+ super.processNode(elementName, locator, attlist, pList);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void addChildNode(FONode child) throws FOPException {
+ if (!inMarker()) {
+ TableCell cell = (TableCell) child;
+ TableBody body = (TableBody) getParent();
+ addTableCellChild(cell, body.isFirst(this));
+ }
+ super.addChildNode(child);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void startOfNode() throws FOPException {
+ super.startOfNode();
+ getFOEventHandler().startRow(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void endOfNode() throws FOPException {
+ if (firstChild == null) {
+ missingChildElementError("(table-cell+)");
+ }
+ if (!inMarker()) {
+ pendingSpans = null;
+ columnNumberManager = null;
+ }
+ getFOEventHandler().endRow(this);
+ }
+
+ /**
+ * {@inheritDoc} String, String)
+ * XSL Content Model: (table-cell+)
+ */
+ 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;
+ }
+
+ /** @return the "break-before" property. */
+ public int getBreakBefore() {
+ return breakBefore;
+ }
+
+ /** @return the "keep-with-previous" property. */
+ public KeepProperty getKeepWithPrevious() {
+ return keepWithPrevious;
+ }
+
+ /** @return the "keep-with-next" property. */
+ public KeepProperty getKeepWithNext() {
+ return keepWithNext;
+ }
+
+ /** @return the "keep-together" property. */
+ public KeepProperty getKeepTogether() {
+ return keepTogether;
+ }
+
+ /**
+ * Convenience method to check if a keep-together
+ * constraint is specified.
+ * @return true if keep-together is active.
+ */
+ public boolean mustKeepTogether() {
+ return !getKeepTogether().getWithinPage().isAuto()
+ || !getKeepTogether().getWithinColumn().isAuto();
+ }
+
+ /**
+ * Convenience method to check if a keep-with-next
+ * constraint is specified.
+ * @return true if keep-with-next is active.
+ */
+ public boolean mustKeepWithNext() {
+ return !getKeepWithNext().getWithinPage().isAuto()
+ || !getKeepWithNext().getWithinColumn().isAuto();
+ }
+
+ /**
+ * Convenience method to check if a keep-with-previous
+ * constraint is specified.
+ * @return true if keep-with-previous is active.
+ */
+ public boolean mustKeepWithPrevious() {
+ return !getKeepWithPrevious().getWithinPage().isAuto()
+ || !getKeepWithPrevious().getWithinColumn().isAuto();
+ }
+
+ /**
+ * @return the "block-progression-dimension" property.
+ */
+ public LengthRangeProperty getBlockProgressionDimension() {
+ return blockProgressionDimension;
+ }
+
+ /**
+ * @return the "height" property.
+ */
+ public Length getHeight() {
+ return height;
+ }
+
+ /**
+ * @return the Common Border, Padding, and Background Properties.
+ */
+ public CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
+ return commonBorderPaddingBackground;
+ }
+
+ /** {@inheritDoc} */
+ public String getLocalName() {
+ return "table-row";
+ }
+
+ /** {@inheritDoc} */
+ public int getNameId() {
+ return FO_TABLE_ROW;
+ }
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.flow.table;
+
+import java.util.List;
+
+import org.apache.fop.layoutmgr.table.EmptyGridUnit;
+
+/**
+ * A row group builder accommodating a variable number of columns. More flexible, but less
+ * efficient.
+ */
+class VariableColRowGroupBuilder extends RowGroupBuilder {
+
+ VariableColRowGroupBuilder(Table t) {
+ super(t);
+ numberOfColumns = 1;
+ }
+
+ /**
+ * Fills the given row group with empty grid units if necessary, so that it matches
+ * the given number of columns.
+ *
+ * @param rowGroup a List of List of GridUnit
+ * @param numberOfColumns the number of columns that the row group must have
+ */
+ static void fillWithEmptyGridUnits(List rowGroup, int numberOfColumns) {
+ for (int i = 0; i < rowGroup.size(); i++) {
+ List effRow = (List) rowGroup.get(i);
+ for (int j = effRow.size(); j < numberOfColumns; j++) {
+ effRow.add(new EmptyGridUnit(null, null, null, j));
+ }
+ }
+ }
+
+ /**
+ * Updates the current row group to match the given number of columns, by adding empty
+ * grid units if necessary.
+ *
+ * @param numberOfColumns new number of columns
+ */
+ void ensureNumberOfColumns(int numberOfColumns) {
+ this.numberOfColumns = numberOfColumns;
+ fillWithEmptyGridUnits(rows, numberOfColumns);
+ }
+
+}
} else if (fobj instanceof org.apache.fop.fo.flow.ListItem) {
return ((org.apache.fop.fo.flow.ListItem)fobj)
.getCommonBorderPaddingBackground();
- } else if (fobj instanceof org.apache.fop.fo.flow.Table) {
- return ((org.apache.fop.fo.flow.Table)fobj)
+ } else if (fobj instanceof org.apache.fop.fo.flow.table.Table) {
+ return ((org.apache.fop.fo.flow.table.Table)fobj)
.getCommonBorderPaddingBackground();
} else {
return null;
} else if (fobj instanceof org.apache.fop.fo.flow.ListItem) {
return ((org.apache.fop.fo.flow.ListItem)fobj)
.getCommonMarginBlock().spaceBefore;
- } else if (fobj instanceof org.apache.fop.fo.flow.Table) {
- return ((org.apache.fop.fo.flow.Table)fobj)
+ } else if (fobj instanceof org.apache.fop.fo.flow.table.Table) {
+ return ((org.apache.fop.fo.flow.table.Table)fobj)
.getCommonMarginBlock().spaceBefore;
} else {
return null;
} else if (fobj instanceof org.apache.fop.fo.flow.ListItem) {
return ((org.apache.fop.fo.flow.ListItem)fobj)
.getCommonMarginBlock().spaceAfter;
- } else if (fobj instanceof org.apache.fop.fo.flow.Table) {
- return ((org.apache.fop.fo.flow.Table)fobj)
+ } else if (fobj instanceof org.apache.fop.fo.flow.table.Table) {
+ return ((org.apache.fop.fo.flow.table.Table)fobj)
.getCommonMarginBlock().spaceAfter;
} else {
return null;
breakBefore = ((org.apache.fop.fo.flow.ListBlock) fobj).getBreakBefore();
} else if (fobj instanceof org.apache.fop.fo.flow.ListItem) {
breakBefore = ((org.apache.fop.fo.flow.ListItem) fobj).getBreakBefore();
- } else if (fobj instanceof org.apache.fop.fo.flow.Table) {
- breakBefore = ((org.apache.fop.fo.flow.Table) fobj).getBreakBefore();
+ } else if (fobj instanceof org.apache.fop.fo.flow.table.Table) {
+ breakBefore = ((org.apache.fop.fo.flow.table.Table) fobj).getBreakBefore();
}
if (breakBefore == EN_PAGE
|| breakBefore == EN_COLUMN
breakAfter = ((org.apache.fop.fo.flow.ListBlock) fobj).getBreakAfter();
} else if (fobj instanceof org.apache.fop.fo.flow.ListItem) {
breakAfter = ((org.apache.fop.fo.flow.ListItem) fobj).getBreakAfter();
- } else if (fobj instanceof org.apache.fop.fo.flow.Table) {
- breakAfter = ((org.apache.fop.fo.flow.Table) fobj).getBreakAfter();
+ } else if (fobj instanceof org.apache.fop.fo.flow.table.Table) {
+ breakAfter = ((org.apache.fop.fo.flow.table.Table) fobj).getBreakAfter();
}
if (breakAfter == EN_PAGE
|| breakAfter == EN_COLUMN
import org.apache.fop.fo.flow.PageNumberCitation;
import org.apache.fop.fo.flow.PageNumberCitationLast;
import org.apache.fop.fo.flow.RetrieveMarker;
-import org.apache.fop.fo.flow.Table;
-import org.apache.fop.fo.flow.TableBody;
-import org.apache.fop.fo.flow.TableCell;
-import org.apache.fop.fo.flow.TableColumn;
-import org.apache.fop.fo.flow.TableFooter;
-import org.apache.fop.fo.flow.TableHeader;
-import org.apache.fop.fo.flow.TableRow;
import org.apache.fop.fo.flow.Wrapper;
+import org.apache.fop.fo.flow.table.Table;
+import org.apache.fop.fo.flow.table.TableBody;
+import org.apache.fop.fo.flow.table.TableCell;
+import org.apache.fop.fo.flow.table.TableColumn;
+import org.apache.fop.fo.flow.table.TableFooter;
+import org.apache.fop.fo.flow.table.TableHeader;
+import org.apache.fop.fo.flow.table.TableRow;
import org.apache.fop.fo.pagination.Flow;
import org.apache.fop.fo.pagination.PageSequence;
import org.apache.fop.fo.pagination.SideRegion;
package org.apache.fop.layoutmgr.table;
import org.apache.fop.fo.Constants;
-import org.apache.fop.fo.flow.Table;
-import org.apache.fop.fo.flow.TableBody;
-import org.apache.fop.fo.flow.TableCell;
-import org.apache.fop.fo.flow.TableColumn;
-import org.apache.fop.fo.flow.TableRow;
+import org.apache.fop.fo.flow.table.Table;
+import org.apache.fop.fo.flow.table.TableBody;
+import org.apache.fop.fo.flow.table.TableCell;
+import org.apache.fop.fo.flow.table.TableColumn;
+import org.apache.fop.fo.flow.table.TableRow;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo;
/**
import org.apache.fop.datatypes.Length;
import org.apache.fop.fo.FONode;
-import org.apache.fop.fo.flow.Table;
-import org.apache.fop.fo.flow.TableColumn;
+import org.apache.fop.fo.flow.table.Table;
+import org.apache.fop.fo.flow.table.TableColumn;
import org.apache.fop.fo.properties.TableColLength;
/**
import java.util.Iterator;
import java.util.List;
-import org.apache.fop.fo.flow.TableRow;
+import org.apache.fop.fo.flow.table.TableRow;
import org.apache.fop.traits.MinOptMax;
/**
package org.apache.fop.layoutmgr.table;
-import org.apache.fop.fo.flow.TableBody;
-import org.apache.fop.fo.flow.TableColumn;
-import org.apache.fop.fo.flow.TableRow;
+import org.apache.fop.fo.flow.table.TableBody;
+import org.apache.fop.fo.flow.table.TableColumn;
+import org.apache.fop.fo.flow.table.TableRow;
/**
* GridUnit subclass for empty grid units.
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.fo.FONode;
-import org.apache.fop.fo.flow.Table;
-import org.apache.fop.fo.flow.TableBody;
-import org.apache.fop.fo.flow.TableCell;
-import org.apache.fop.fo.flow.TableColumn;
-import org.apache.fop.fo.flow.TableRow;
+import org.apache.fop.fo.flow.table.Table;
+import org.apache.fop.fo.flow.table.TableBody;
+import org.apache.fop.fo.flow.table.TableCell;
+import org.apache.fop.fo.flow.table.TableColumn;
+import org.apache.fop.fo.flow.table.TableRow;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.fop.fo.flow.TableCell;
-import org.apache.fop.fo.flow.TableColumn;
+import org.apache.fop.fo.flow.table.TableCell;
+import org.apache.fop.fo.flow.table.TableColumn;
/**
* This class represents a primary grid unit of a spanned cell. This is the "before-start"
import org.apache.commons.logging.LogFactory;
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FONode;
-import org.apache.fop.fo.flow.TableRow;
+import org.apache.fop.fo.flow.table.TableRow;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.LengthRangeProperty;
import org.apache.fop.layoutmgr.BreakElement;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.fop.fo.flow.TableRow;
+import org.apache.fop.fo.flow.table.TableRow;
import org.apache.fop.fo.properties.LengthRangeProperty;
import org.apache.fop.layoutmgr.ElementListUtils;
import org.apache.fop.layoutmgr.KnuthElement;
package org.apache.fop.layoutmgr.table;
-import org.apache.fop.fo.flow.TableAndCaption;
+import org.apache.fop.fo.flow.table.TableAndCaption;
import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.layoutmgr.PositionIterator;
package org.apache.fop.layoutmgr.table;
-import org.apache.fop.fo.flow.TableCaption;
+import org.apache.fop.fo.flow.table.TableCaption;
import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.layoutmgr.PositionIterator;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.datatypes.PercentBaseContext;
import org.apache.fop.fo.FONode;
-import org.apache.fop.fo.flow.Table;
-import org.apache.fop.fo.flow.TableCell;
+import org.apache.fop.fo.flow.table.Table;
+import org.apache.fop.fo.flow.table.TableCell;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.layoutmgr.AreaAdditionUtil;
import org.apache.fop.layoutmgr.BlockLevelLayoutManager;
import org.apache.fop.datatypes.PercentBaseContext;
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FObj;
-import org.apache.fop.fo.flow.Table;
-import org.apache.fop.fo.flow.TableBody;
-import org.apache.fop.fo.flow.TableRow;
+import org.apache.fop.fo.flow.table.Table;
+import org.apache.fop.fo.flow.table.TableBody;
+import org.apache.fop.fo.flow.table.TableRow;
import org.apache.fop.layoutmgr.BreakElement;
import org.apache.fop.layoutmgr.ElementListUtils;
import org.apache.fop.layoutmgr.KnuthBox;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.fop.fo.flow.Table;
-import org.apache.fop.fo.flow.TableColumn;
+import org.apache.fop.fo.flow.table.Table;
+import org.apache.fop.fo.flow.table.TableColumn;
import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
import org.apache.fop.layoutmgr.ConditionalElementListener;
import org.apache.fop.layoutmgr.KnuthElement;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.fo.flow.Marker;
-import org.apache.fop.fo.flow.Table;
-import org.apache.fop.fo.flow.TableBody;
-import org.apache.fop.fo.flow.TableCell;
-import org.apache.fop.fo.flow.TableColumn;
-import org.apache.fop.fo.flow.TableRow;
+import org.apache.fop.fo.flow.table.Table;
+import org.apache.fop.fo.flow.table.TableBody;
+import org.apache.fop.fo.flow.table.TableCell;
+import org.apache.fop.fo.flow.table.TableColumn;
+import org.apache.fop.fo.flow.table.TableRow;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FONode;
-import org.apache.fop.fo.flow.TableRow;
+import org.apache.fop.fo.flow.table.TableRow;
import org.apache.fop.layoutmgr.BreakElement;
import org.apache.fop.layoutmgr.KnuthBox;
import org.apache.fop.layoutmgr.KnuthGlue;
import org.apache.fop.fo.flow.ListItemBody;
import org.apache.fop.fo.flow.ListItemLabel;
import org.apache.fop.fo.flow.PageNumber;
-import org.apache.fop.fo.flow.Table;
-import org.apache.fop.fo.flow.TableBody;
-import org.apache.fop.fo.flow.TableCell;
-import org.apache.fop.fo.flow.TableColumn;
-import org.apache.fop.fo.flow.TableHeader;
-import org.apache.fop.fo.flow.TableRow;
+import org.apache.fop.fo.flow.table.Table;
+import org.apache.fop.fo.flow.table.TableBody;
+import org.apache.fop.fo.flow.table.TableCell;
+import org.apache.fop.fo.flow.table.TableColumn;
+import org.apache.fop.fo.flow.table.TableHeader;
+import org.apache.fop.fo.flow.table.TableRow;
import org.apache.fop.fo.pagination.Flow;
import org.apache.fop.fo.pagination.PageSequence;
import org.apache.fop.fo.pagination.PageSequenceMaster;
import org.apache.fop.apps.FOPException;
import org.apache.fop.fo.Constants;
-import org.apache.fop.fo.flow.Table;
-import org.apache.fop.fo.flow.TableBody;
-import org.apache.fop.fo.flow.TableCell;
-import org.apache.fop.fo.flow.TableHeader;
-import org.apache.fop.fo.flow.TableRow;
+import org.apache.fop.fo.flow.table.Table;
+import org.apache.fop.fo.flow.table.TableBody;
+import org.apache.fop.fo.flow.table.TableCell;
+import org.apache.fop.fo.flow.table.TableHeader;
+import org.apache.fop.fo.flow.table.TableRow;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.render.rtf.rtflib.rtfdoc.ITableAttributes;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfAttributes;
import org.apache.fop.fo.flow.ExternalGraphic;
import org.apache.fop.fo.flow.Footnote;
import org.apache.fop.fo.flow.FootnoteBody;
-import org.apache.fop.fo.flow.InstreamForeignObject;
import org.apache.fop.fo.flow.Inline;
+import org.apache.fop.fo.flow.InstreamForeignObject;
import org.apache.fop.fo.flow.Leader;
import org.apache.fop.fo.flow.ListBlock;
import org.apache.fop.fo.flow.ListItem;
import org.apache.fop.fo.flow.PageNumber;
-import org.apache.fop.fo.flow.Table;
-import org.apache.fop.fo.flow.TableBody;
-import org.apache.fop.fo.flow.TableCell;
-import org.apache.fop.fo.flow.TableColumn;
-import org.apache.fop.fo.flow.TableRow;
+import org.apache.fop.fo.flow.table.Table;
+import org.apache.fop.fo.flow.table.TableBody;
+import org.apache.fop.fo.flow.table.TableCell;
+import org.apache.fop.fo.flow.table.TableColumn;
+import org.apache.fop.fo.flow.table.TableRow;
import org.apache.fop.fo.pagination.Flow;
import org.apache.fop.fo.pagination.PageSequence;
import org.apache.fop.fo.pagination.PageSequenceMaster;
+++ /dev/null
-/*
- * 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.Iterator;
-
-import org.apache.fop.apps.FOUserAgent;
-import org.apache.fop.fo.FOEventHandler;
-import org.apache.fop.fotreetest.FOTreeUnitTester;
-
-/**
- * Superclass for testcases related to tables, factoring the common stuff.
- */
-abstract class AbstractTableTestCase extends FOTreeUnitTester {
-
- private FOTreeUnitTester.FOEventHandlerFactory tableHandlerFactory;
-
- private TableHandler tableHandler;
-
- public AbstractTableTestCase() throws Exception {
- super();
- tableHandlerFactory = new FOEventHandlerFactory() {
- public FOEventHandler createFOEventHandler(FOUserAgent foUserAgent) {
- tableHandler = new TableHandler(foUserAgent);
- return tableHandler;
- }
- };
- }
-
- protected void setUp(String filename) throws Exception {
- setUp(filename, tableHandlerFactory);
- }
-
- protected TableHandler getTableHandler() {
- return tableHandler;
- }
-
- protected Iterator getTableIterator() {
- return tableHandler.getTables().iterator();
- }
-}
+++ /dev/null
-/*
- * 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.Iterator;
-
-import org.apache.fop.datatypes.PercentBaseContext;
-import org.apache.fop.fo.FObj;
-
-
-public class TableColumnColumnNumberTestCase extends AbstractTableTestCase {
-
- /**
- * A percentBaseContext that mimics the behaviour of TableLM for computing the widths
- * of columns. All what needs to be known is the width of a table unit (as in
- * proportional-column-width()).
- */
- private class TablePercentBaseContext implements PercentBaseContext {
-
- private int unitaryWidth;
-
- void setUnitaryWidth(int unitaryWidth) {
- this.unitaryWidth = unitaryWidth;
- }
-
- public int getBaseLength(int lengthBase, FObj fobj) {
- return unitaryWidth;
- }
- }
-
- private TablePercentBaseContext percentBaseContext = new TablePercentBaseContext();
-
- public TableColumnColumnNumberTestCase() throws Exception {
- super();
- }
-
- private void checkColumn(Table t, int number, boolean isImplicit, int spans, int repeated, int width) {
- TableColumn c = t.getColumn(number - 1);
- // TODO a repeated column has a correct number only for its first occurrence
-// assertEquals(number, c.getColumnNumber());
- assertEquals(isImplicit, c.isImplicitColumn());
- assertEquals(spans, c.getNumberColumnsSpanned());
- assertEquals(repeated, c.getNumberColumnsRepeated());
- assertEquals(width, c.getColumnWidth().getValue(percentBaseContext));
- }
-
- public void testColumnNumber() throws Exception {
- setUp("table/table-column_column-number.fo");
- Iterator tableIter = getTableIterator();
- Table t = (Table) tableIter.next();
- assertEquals(2, t.getNumberOfColumns());
- checkColumn(t, 1, false, 1, 2, 100000);
- checkColumn(t, 2, false, 1, 2, 100000);
-
- t = (Table) tableIter.next();
- assertEquals(2, t.getNumberOfColumns());
- checkColumn(t, 1, false, 1, 1, 200000);
- checkColumn(t, 2, false, 1, 1, 100000);
-
- t = (Table) tableIter.next();
- assertEquals(3, t.getNumberOfColumns());
- checkColumn(t, 1, false, 1, 1, 100000);
- checkColumn(t, 2, false, 1, 1, 150000);
- checkColumn(t, 3, false, 1, 1, 200000);
-
- t = (Table) tableIter.next();
- percentBaseContext.setUnitaryWidth(125000);
- assertEquals(4, t.getNumberOfColumns());
- checkColumn(t, 1, false, 1, 1, 100000);
- checkColumn(t, 2, true, 1, 1, 125000);
- checkColumn(t, 3, false, 1, 1, 150000);
- checkColumn(t, 4, false, 1, 1, 175000);
- }
-
- private void checkImplicitColumns(Iterator tableIter, int columnNumber) {
- Table t = (Table) tableIter.next();
- assertEquals(columnNumber, t.getNumberOfColumns());
- for (int i = 1; i <= columnNumber; i++) {
- checkColumn(t, i, true, 1, 1, 100000);
- }
- }
-
- public void testImplicitColumns() throws Exception {
- setUp("table/implicit_columns_column-number.fo");
- percentBaseContext.setUnitaryWidth(100000);
- Iterator tableIter = getTableIterator();
-
- checkImplicitColumns(tableIter, 2);
- checkImplicitColumns(tableIter, 2);
- checkImplicitColumns(tableIter, 2);
- checkImplicitColumns(tableIter, 2);
- checkImplicitColumns(tableIter, 3);
- checkImplicitColumns(tableIter, 4);
- checkImplicitColumns(tableIter, 3);
- }
-}
+++ /dev/null
-/*
- * 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.LinkedList;
-import java.util.List;
-
-import org.apache.fop.apps.FOUserAgent;
-import org.apache.fop.fo.FOEventHandler;
-import org.apache.fop.fo.flow.Table;
-
-public class TableHandler extends FOEventHandler {
-
- /** All the tables encountered in the FO file. List of Table objects. */
- private List tables = new LinkedList();
-
- TableHandler(FOUserAgent foUserAgent) {
- super(foUserAgent);
- }
-
- public void endTable(Table tbl) {
- tables.add(tbl);
- }
-
- List getTables() {
- return tables;
- }
-}
+++ /dev/null
-/*
- * 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.Iterator;
-import java.util.List;
-
-/**
- * Tests that TableRowIterator returns, for each part of a table, the expected number of
- * row-groups with the expected number or rows in each.
- */
-public class TableRowIteratorTestCase extends AbstractTableTestCase {
-
- public TableRowIteratorTestCase() throws Exception {
- super();
- }
-
- /**
- * Prepares the iterators over the tables contained in the given FO file.
- *
- * @param filename basename of a test FO file
- * @throws Exception
- */
-// private void setUp(String filename) throws Exception {
-// foReader.parse(new File("test/layoutmgr/table/" + filename).toURL().toExternalForm());
-// List tables = tableHandler.getTables();
-// List columnSetups = new LinkedList();
-// tableIterator = tables.iterator();
-// for (Iterator i = tables.iterator(); i.hasNext();) {
-// columnSetups.add(new ColumnSetup((Table) i.next()));
-// }
-// columnSetupIterator = columnSetups.iterator();
-// }
-
- /**
- * Checks that the given iterator will return row groups as expected. More precisely,
- * checks that the number of row groups corresponds to the size of the given array,
- * and that the number of rows inside each row group is equal to the corresponding
- * integer in the array.
- *
- * @param tri an iterator over a given part of a table (HEADER, FOOTER, BODY)
- * @param expectedRowLengths expected lengths of all the row groups of this part of
- * the table
- */
- private void checkTablePartRowGroups(TableBody body, int[] expectedRowLengths) {
- Iterator rowGroupIter = body.getRowGroups().iterator();
- for (int i = 0; i < expectedRowLengths.length; i++) {
- assertTrue(rowGroupIter.hasNext());
- List rowGroup = (List) rowGroupIter.next();
- assertEquals(expectedRowLengths[i], rowGroup.size());
- }
- assertFalse(rowGroupIter.hasNext());
- }
-
- /**
- * Gets the next table and checks its row-groups.
- * @param tableIter TODO
- * @param expectedHeaderRowLengths expected row-group sizes for the header. If null
- * the table is not expected to have a header
- * @param expectedFooterRowLengths expected row-group sizes for the footer. If null
- * the table is not expected to have a footer
- * @param expectedBodyRowLengths expected row-group sizes for the body(-ies)
- */
- private void checkNextTableRowGroups(Iterator tableIter,
- int[] expectedHeaderRowLengths, int[] expectedFooterRowLengths, int[][] expectedBodyRowLengths) {
- Table table = (Table) tableIter.next();
- if (expectedHeaderRowLengths == null) {
- assertNull(table.getTableHeader());
- } else {
- checkTablePartRowGroups(table.getTableHeader(), expectedHeaderRowLengths);
- }
- if (expectedFooterRowLengths == null) {
- assertNull(table.getTableFooter());
- } else {
- checkTablePartRowGroups(table.getTableFooter(), expectedFooterRowLengths);
- }
- Iterator bodyIter = table.getChildNodes();
- for (int i = 0; i < expectedBodyRowLengths.length; i++) {
- assertTrue(bodyIter.hasNext());
- checkTablePartRowGroups((TableBody) bodyIter.next(), expectedBodyRowLengths[i]);
- }
-
-// ColumnSetup columnSetup = (ColumnSetup) columnSetupIterator.next();
-// TableRowIterator tri;
-// if (expectedHeaderRowLengths != null) {
-// tri = new TableRowIterator(table, columnSetup, TableRowIterator.HEADER);
-// checkTablePartRowGroups(tri, expectedHeaderRowLengths);
-// }
-// if (expectedFooterRowLengths != null) {
-// tri = new TableRowIterator(table, columnSetup, TableRowIterator.FOOTER);
-// checkTablePartRowGroups(tri, expectedFooterRowLengths);
-// }
-// tri = new TableRowIterator(table, columnSetup, TableRowIterator.BODY);
-// checkTablePartRowGroups(tri, expectedBodyRowLengths);
- }
-
- public void checkSimple(String filename) throws Exception {
- setUp(filename);
- Iterator tableIter = getTableIterator();
-
- // Table 1: no header, no footer, one body (1 row)
- checkNextTableRowGroups(tableIter, null, null, new int[][] {{1}});
-
- // Table 2: no header, no footer, one body (2 rows)
- checkNextTableRowGroups(tableIter, null, null, new int[][] {{1, 1}});
-
- // Table 3: no header, no footer, two bodies (1 row, 1 row)
- checkNextTableRowGroups(tableIter, null, null, new int[][] {{1}, {1}});
-
- // Table 4: no header, no footer, two bodies (2 rows, 3 rows)
- checkNextTableRowGroups(tableIter, null, null, new int[][] {{1, 1}, {1, 1, 1}});
-
- // Table 5: one header (1 row), no footer, one body (1 row)
- checkNextTableRowGroups(tableIter, new int[] {1}, null, new int[][] {{1}});
-
- // Table 6: no header, one footer (1 row), one body (1 row)
- checkNextTableRowGroups(tableIter, null, new int[] {1}, new int[][] {{1}});
-
- // Table 7: one header (1 row), one footer (1 row), one body (1 row)
- checkNextTableRowGroups(tableIter, new int[] {1}, new int[] {1}, new int[][] {{1}});
-
- // Table 8: one header (2 rows), one footer (3 rows), one body (2 rows)
- checkNextTableRowGroups(tableIter, new int[] {1, 1}, new int[] {1, 1, 1}, new int[][] {{1, 1}});
-
- // Table 9: one header (3 rows), one footer (2 rows), three bodies (2 rows, 1 row, 3 rows)
- checkNextTableRowGroups(tableIter, new int[] {1, 1, 1}, new int[] {1, 1}, new int[][] {{1, 1}, {1}, {1, 1, 1}});
- }
-
- public void checkSpans(String filename) throws Exception {
- setUp(filename);
- Iterator tableIter = getTableIterator();
-
- // Table 1: no header, no footer, one body (1 row with column-span)
- checkNextTableRowGroups(tableIter, null, null, new int[][] {{1}});
-
- // Table 2: no header, no footer, one body (1 row-group of 2 rows)
- checkNextTableRowGroups(tableIter, null, null, new int[][] {{2}});
-
- // Table 3: no header, no footer, one body (1 row-group of 2 rows, 1 row)
- checkNextTableRowGroups(tableIter, null, null, new int[][] {{2, 1}});
-
- // Table 4: no header, no footer, one body (1 row, 1 row-group of 2 rows)
- checkNextTableRowGroups(tableIter, null, null, new int[][] {{1, 2}});
-
- // Table 5: no header, no footer, one body (1 row, 1 row-group of 3 rows, 1 row)
- checkNextTableRowGroups(tableIter, null, null, new int[][] {{1, 3, 1}});
-
- // Table 6: one header (1 row-group of 2 rows), one footer (1 row, 1 row-group of 3 rows),
- // one body (1 row-group of 2 rows, 1 row, 1 row-group of 3 rows)
- checkNextTableRowGroups(tableIter, new int[] {2}, new int[] {1, 3}, new int[][] {{2, 1, 3}});
- }
-
- public void testWithRowsSimple() throws Exception {
- checkSimple("table/TableRowIterator_simple.fo");
- }
-
- public void testWithRowsSpans() throws Exception {
- checkSpans("table/TableRowIterator_spans.fo");
- }
-
- public void testNoRowSimple() throws Exception {
- checkSimple("table/TableRowIterator_no-row_simple.fo");
- }
-
- public void testNoRowSpans() throws Exception {
- checkSpans("table/TableRowIterator_no-row_spans.fo");
- }
-
- public void testNoColWithRowsSimple() throws Exception {
- checkSimple("table/TableRowIterator_no-col_simple.fo");
- }
-
- public void testNoColWithRowsSpans() throws Exception {
- checkSpans("table/TableRowIterator_no-col_spans.fo");
- }
-
- public void testNoColNoRowSimple() throws Exception {
- checkSimple("table/TableRowIterator_no-col_no-row_simple.fo");
- }
-
- public void testNoColNoRowSpans() throws Exception {
- checkSpans("table/TableRowIterator_no-col_no-row_spans.fo");
- }
-}
+++ /dev/null
-/*
- * 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 org.apache.fop.fo.ValidationException;
-
-public class TooManyColumnsTestCase extends AbstractTableTestCase {
-
- public TooManyColumnsTestCase() throws Exception {
- super();
- }
-
- private void launchTest(String filename) throws Exception {
- try {
- setUp(filename);
- fail();
- } catch (ValidationException e) {
- // TODO check location
- }
- }
-
- public void testBody1() throws Exception {
- launchTest("table/too-many-columns_body_1.fo");
- }
-
- public void testBody2() throws Exception {
- launchTest("table/too-many-columns_body_2.fo");
- }
-
- public void testBody3() throws Exception {
- launchTest("table/too-many-columns_body_3.fo");
- }
-
- public void testHeader() throws Exception {
- launchTest("table/too-many-columns_header.fo");
- }
-
- public void testFooter() throws Exception {
- launchTest("table/too-many-columns_footer.fo");
- }
-}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.flow.table;
+
+import java.util.Iterator;
+
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fo.FOEventHandler;
+import org.apache.fop.fotreetest.FOTreeUnitTester;
+
+/**
+ * Superclass for testcases related to tables, factoring the common stuff.
+ */
+abstract class AbstractTableTestCase extends FOTreeUnitTester {
+
+ private FOTreeUnitTester.FOEventHandlerFactory tableHandlerFactory;
+
+ private TableHandler tableHandler;
+
+ public AbstractTableTestCase() throws Exception {
+ super();
+ tableHandlerFactory = new FOEventHandlerFactory() {
+ public FOEventHandler createFOEventHandler(FOUserAgent foUserAgent) {
+ tableHandler = new TableHandler(foUserAgent);
+ return tableHandler;
+ }
+ };
+ }
+
+ protected void setUp(String filename) throws Exception {
+ setUp(filename, tableHandlerFactory);
+ }
+
+ protected TableHandler getTableHandler() {
+ return tableHandler;
+ }
+
+ protected Iterator getTableIterator() {
+ return tableHandler.getTables().iterator();
+ }
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.flow.table;
+
+import java.util.Iterator;
+
+import org.apache.fop.datatypes.PercentBaseContext;
+import org.apache.fop.fo.FObj;
+
+
+public class TableColumnColumnNumberTestCase extends AbstractTableTestCase {
+
+ /**
+ * A percentBaseContext that mimics the behaviour of TableLM for computing the widths
+ * of columns. All what needs to be known is the width of a table unit (as in
+ * proportional-column-width()).
+ */
+ private class TablePercentBaseContext implements PercentBaseContext {
+
+ private int unitaryWidth;
+
+ void setUnitaryWidth(int unitaryWidth) {
+ this.unitaryWidth = unitaryWidth;
+ }
+
+ public int getBaseLength(int lengthBase, FObj fobj) {
+ return unitaryWidth;
+ }
+ }
+
+ private TablePercentBaseContext percentBaseContext = new TablePercentBaseContext();
+
+ public TableColumnColumnNumberTestCase() throws Exception {
+ super();
+ }
+
+ private void checkColumn(Table t, int number, boolean isImplicit, int spans, int repeated, int width) {
+ TableColumn c = t.getColumn(number - 1);
+ // TODO a repeated column has a correct number only for its first occurrence
+// assertEquals(number, c.getColumnNumber());
+ assertEquals(isImplicit, c.isImplicitColumn());
+ assertEquals(spans, c.getNumberColumnsSpanned());
+ assertEquals(repeated, c.getNumberColumnsRepeated());
+ assertEquals(width, c.getColumnWidth().getValue(percentBaseContext));
+ }
+
+ public void testColumnNumber() throws Exception {
+ setUp("table/table-column_column-number.fo");
+ Iterator tableIter = getTableIterator();
+ Table t = (Table) tableIter.next();
+ assertEquals(2, t.getNumberOfColumns());
+ checkColumn(t, 1, false, 1, 2, 100000);
+ checkColumn(t, 2, false, 1, 2, 100000);
+
+ t = (Table) tableIter.next();
+ assertEquals(2, t.getNumberOfColumns());
+ checkColumn(t, 1, false, 1, 1, 200000);
+ checkColumn(t, 2, false, 1, 1, 100000);
+
+ t = (Table) tableIter.next();
+ assertEquals(3, t.getNumberOfColumns());
+ checkColumn(t, 1, false, 1, 1, 100000);
+ checkColumn(t, 2, false, 1, 1, 150000);
+ checkColumn(t, 3, false, 1, 1, 200000);
+
+ t = (Table) tableIter.next();
+ percentBaseContext.setUnitaryWidth(125000);
+ assertEquals(4, t.getNumberOfColumns());
+ checkColumn(t, 1, false, 1, 1, 100000);
+ checkColumn(t, 2, true, 1, 1, 125000);
+ checkColumn(t, 3, false, 1, 1, 150000);
+ checkColumn(t, 4, false, 1, 1, 175000);
+ }
+
+ private void checkImplicitColumns(Iterator tableIter, int columnNumber) {
+ Table t = (Table) tableIter.next();
+ assertEquals(columnNumber, t.getNumberOfColumns());
+ for (int i = 1; i <= columnNumber; i++) {
+ checkColumn(t, i, true, 1, 1, 100000);
+ }
+ }
+
+ public void testImplicitColumns() throws Exception {
+ setUp("table/implicit_columns_column-number.fo");
+ percentBaseContext.setUnitaryWidth(100000);
+ Iterator tableIter = getTableIterator();
+
+ checkImplicitColumns(tableIter, 2);
+ checkImplicitColumns(tableIter, 2);
+ checkImplicitColumns(tableIter, 2);
+ checkImplicitColumns(tableIter, 2);
+ checkImplicitColumns(tableIter, 3);
+ checkImplicitColumns(tableIter, 4);
+ checkImplicitColumns(tableIter, 3);
+ }
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.flow.table;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fo.FOEventHandler;
+import org.apache.fop.fo.flow.table.Table;
+
+public class TableHandler extends FOEventHandler {
+
+ /** All the tables encountered in the FO file. List of Table objects. */
+ private List tables = new LinkedList();
+
+ TableHandler(FOUserAgent foUserAgent) {
+ super(foUserAgent);
+ }
+
+ public void endTable(Table tbl) {
+ tables.add(tbl);
+ }
+
+ List getTables() {
+ return tables;
+ }
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.flow.table;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Tests that TableRowIterator returns, for each part of a table, the expected number of
+ * row-groups with the expected number or rows in each.
+ */
+public class TableRowIteratorTestCase extends AbstractTableTestCase {
+
+ public TableRowIteratorTestCase() throws Exception {
+ super();
+ }
+
+ /**
+ * Prepares the iterators over the tables contained in the given FO file.
+ *
+ * @param filename basename of a test FO file
+ * @throws Exception
+ */
+// private void setUp(String filename) throws Exception {
+// foReader.parse(new File("test/layoutmgr/table/" + filename).toURL().toExternalForm());
+// List tables = tableHandler.getTables();
+// List columnSetups = new LinkedList();
+// tableIterator = tables.iterator();
+// for (Iterator i = tables.iterator(); i.hasNext();) {
+// columnSetups.add(new ColumnSetup((Table) i.next()));
+// }
+// columnSetupIterator = columnSetups.iterator();
+// }
+
+ /**
+ * Checks that the given iterator will return row groups as expected. More precisely,
+ * checks that the number of row groups corresponds to the size of the given array,
+ * and that the number of rows inside each row group is equal to the corresponding
+ * integer in the array.
+ *
+ * @param tri an iterator over a given part of a table (HEADER, FOOTER, BODY)
+ * @param expectedRowLengths expected lengths of all the row groups of this part of
+ * the table
+ */
+ private void checkTablePartRowGroups(TableBody body, int[] expectedRowLengths) {
+ Iterator rowGroupIter = body.getRowGroups().iterator();
+ for (int i = 0; i < expectedRowLengths.length; i++) {
+ assertTrue(rowGroupIter.hasNext());
+ List rowGroup = (List) rowGroupIter.next();
+ assertEquals(expectedRowLengths[i], rowGroup.size());
+ }
+ assertFalse(rowGroupIter.hasNext());
+ }
+
+ /**
+ * Gets the next table and checks its row-groups.
+ * @param tableIter TODO
+ * @param expectedHeaderRowLengths expected row-group sizes for the header. If null
+ * the table is not expected to have a header
+ * @param expectedFooterRowLengths expected row-group sizes for the footer. If null
+ * the table is not expected to have a footer
+ * @param expectedBodyRowLengths expected row-group sizes for the body(-ies)
+ */
+ private void checkNextTableRowGroups(Iterator tableIter,
+ int[] expectedHeaderRowLengths, int[] expectedFooterRowLengths, int[][] expectedBodyRowLengths) {
+ Table table = (Table) tableIter.next();
+ if (expectedHeaderRowLengths == null) {
+ assertNull(table.getTableHeader());
+ } else {
+ checkTablePartRowGroups(table.getTableHeader(), expectedHeaderRowLengths);
+ }
+ if (expectedFooterRowLengths == null) {
+ assertNull(table.getTableFooter());
+ } else {
+ checkTablePartRowGroups(table.getTableFooter(), expectedFooterRowLengths);
+ }
+ Iterator bodyIter = table.getChildNodes();
+ for (int i = 0; i < expectedBodyRowLengths.length; i++) {
+ assertTrue(bodyIter.hasNext());
+ checkTablePartRowGroups((TableBody) bodyIter.next(), expectedBodyRowLengths[i]);
+ }
+
+// ColumnSetup columnSetup = (ColumnSetup) columnSetupIterator.next();
+// TableRowIterator tri;
+// if (expectedHeaderRowLengths != null) {
+// tri = new TableRowIterator(table, columnSetup, TableRowIterator.HEADER);
+// checkTablePartRowGroups(tri, expectedHeaderRowLengths);
+// }
+// if (expectedFooterRowLengths != null) {
+// tri = new TableRowIterator(table, columnSetup, TableRowIterator.FOOTER);
+// checkTablePartRowGroups(tri, expectedFooterRowLengths);
+// }
+// tri = new TableRowIterator(table, columnSetup, TableRowIterator.BODY);
+// checkTablePartRowGroups(tri, expectedBodyRowLengths);
+ }
+
+ public void checkSimple(String filename) throws Exception {
+ setUp(filename);
+ Iterator tableIter = getTableIterator();
+
+ // Table 1: no header, no footer, one body (1 row)
+ checkNextTableRowGroups(tableIter, null, null, new int[][] {{1}});
+
+ // Table 2: no header, no footer, one body (2 rows)
+ checkNextTableRowGroups(tableIter, null, null, new int[][] {{1, 1}});
+
+ // Table 3: no header, no footer, two bodies (1 row, 1 row)
+ checkNextTableRowGroups(tableIter, null, null, new int[][] {{1}, {1}});
+
+ // Table 4: no header, no footer, two bodies (2 rows, 3 rows)
+ checkNextTableRowGroups(tableIter, null, null, new int[][] {{1, 1}, {1, 1, 1}});
+
+ // Table 5: one header (1 row), no footer, one body (1 row)
+ checkNextTableRowGroups(tableIter, new int[] {1}, null, new int[][] {{1}});
+
+ // Table 6: no header, one footer (1 row), one body (1 row)
+ checkNextTableRowGroups(tableIter, null, new int[] {1}, new int[][] {{1}});
+
+ // Table 7: one header (1 row), one footer (1 row), one body (1 row)
+ checkNextTableRowGroups(tableIter, new int[] {1}, new int[] {1}, new int[][] {{1}});
+
+ // Table 8: one header (2 rows), one footer (3 rows), one body (2 rows)
+ checkNextTableRowGroups(tableIter, new int[] {1, 1}, new int[] {1, 1, 1}, new int[][] {{1, 1}});
+
+ // Table 9: one header (3 rows), one footer (2 rows), three bodies (2 rows, 1 row, 3 rows)
+ checkNextTableRowGroups(tableIter, new int[] {1, 1, 1}, new int[] {1, 1}, new int[][] {{1, 1}, {1}, {1, 1, 1}});
+ }
+
+ public void checkSpans(String filename) throws Exception {
+ setUp(filename);
+ Iterator tableIter = getTableIterator();
+
+ // Table 1: no header, no footer, one body (1 row with column-span)
+ checkNextTableRowGroups(tableIter, null, null, new int[][] {{1}});
+
+ // Table 2: no header, no footer, one body (1 row-group of 2 rows)
+ checkNextTableRowGroups(tableIter, null, null, new int[][] {{2}});
+
+ // Table 3: no header, no footer, one body (1 row-group of 2 rows, 1 row)
+ checkNextTableRowGroups(tableIter, null, null, new int[][] {{2, 1}});
+
+ // Table 4: no header, no footer, one body (1 row, 1 row-group of 2 rows)
+ checkNextTableRowGroups(tableIter, null, null, new int[][] {{1, 2}});
+
+ // Table 5: no header, no footer, one body (1 row, 1 row-group of 3 rows, 1 row)
+ checkNextTableRowGroups(tableIter, null, null, new int[][] {{1, 3, 1}});
+
+ // Table 6: one header (1 row-group of 2 rows), one footer (1 row, 1 row-group of 3 rows),
+ // one body (1 row-group of 2 rows, 1 row, 1 row-group of 3 rows)
+ checkNextTableRowGroups(tableIter, new int[] {2}, new int[] {1, 3}, new int[][] {{2, 1, 3}});
+ }
+
+ public void testWithRowsSimple() throws Exception {
+ checkSimple("table/TableRowIterator_simple.fo");
+ }
+
+ public void testWithRowsSpans() throws Exception {
+ checkSpans("table/TableRowIterator_spans.fo");
+ }
+
+ public void testNoRowSimple() throws Exception {
+ checkSimple("table/TableRowIterator_no-row_simple.fo");
+ }
+
+ public void testNoRowSpans() throws Exception {
+ checkSpans("table/TableRowIterator_no-row_spans.fo");
+ }
+
+ public void testNoColWithRowsSimple() throws Exception {
+ checkSimple("table/TableRowIterator_no-col_simple.fo");
+ }
+
+ public void testNoColWithRowsSpans() throws Exception {
+ checkSpans("table/TableRowIterator_no-col_spans.fo");
+ }
+
+ public void testNoColNoRowSimple() throws Exception {
+ checkSimple("table/TableRowIterator_no-col_no-row_simple.fo");
+ }
+
+ public void testNoColNoRowSpans() throws Exception {
+ checkSpans("table/TableRowIterator_no-col_no-row_spans.fo");
+ }
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fo.flow.table;
+
+import org.apache.fop.fo.ValidationException;
+
+public class TooManyColumnsTestCase extends AbstractTableTestCase {
+
+ public TooManyColumnsTestCase() throws Exception {
+ super();
+ }
+
+ private void launchTest(String filename) throws Exception {
+ try {
+ setUp(filename);
+ fail();
+ } catch (ValidationException e) {
+ // TODO check location
+ }
+ }
+
+ public void testBody1() throws Exception {
+ launchTest("table/too-many-columns_body_1.fo");
+ }
+
+ public void testBody2() throws Exception {
+ launchTest("table/too-many-columns_body_2.fo");
+ }
+
+ public void testBody3() throws Exception {
+ launchTest("table/too-many-columns_body_3.fo");
+ }
+
+ public void testHeader() throws Exception {
+ launchTest("table/too-many-columns_header.fo");
+ }
+
+ public void testFooter() throws Exception {
+ launchTest("table/too-many-columns_footer.fo");
+ }
+}
import org.apache.commons.io.filefilter.SuffixFileFilter;
import org.apache.commons.io.filefilter.TrueFileFilter;
import org.apache.fop.DebugHelper;
-import org.apache.fop.fo.flow.TooManyColumnsTestCase;
+import org.apache.fop.fo.flow.table.TooManyColumnsTestCase;
import org.apache.fop.layoutengine.LayoutEngineTestSuite;
import junit.framework.Test;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.fo.FOEventHandler;
-import org.apache.fop.fo.flow.Table;
+import org.apache.fop.fo.flow.table.Table;
public class TableHandler extends FOEventHandler {