diff options
-rw-r--r-- | src/documentation/content/xdocs/compliance.ihtml | 4 | ||||
-rw-r--r-- | src/java/org/apache/fop/fo/PropertyList.java | 46 | ||||
-rw-r--r-- | src/java/org/apache/fop/fo/expr/FromTableColumnFunction.java | 80 | ||||
-rw-r--r-- | src/java/org/apache/fop/fo/flow/Table.java | 39 | ||||
-rw-r--r-- | src/java/org/apache/fop/fo/flow/TableBody.java | 2 | ||||
-rw-r--r-- | src/java/org/apache/fop/fo/flow/TableCell.java | 22 | ||||
-rw-r--r-- | src/java/org/apache/fop/fo/flow/TableColumn.java | 23 | ||||
-rw-r--r-- | src/java/org/apache/fop/fo/flow/TableFObj.java | 4 | ||||
-rw-r--r-- | src/java/org/apache/fop/fo/flow/TableRow.java | 2 | ||||
-rw-r--r-- | src/java/org/apache/fop/fo/properties/ColumnNumberPropertyMaker.java | 38 | ||||
-rw-r--r-- | status.xml | 4 | ||||
-rwxr-xr-x | test/fotree/disabled-testcases.xml | 6 | ||||
-rw-r--r-- | test/fotree/testcases/properties_omitted_propertyname.fo | 31 |
13 files changed, 226 insertions, 75 deletions
diff --git a/src/documentation/content/xdocs/compliance.ihtml b/src/documentation/content/xdocs/compliance.ihtml index 001fe70a0..18ededcbe 100644 --- a/src/documentation/content/xdocs/compliance.ihtml +++ b/src/documentation/content/xdocs/compliance.ihtml @@ -7245,8 +7245,8 @@ <td class="no"> no </td> - <td class="no"> - no + <td class="yes"> + yes </td> <td align="center"> diff --git a/src/java/org/apache/fop/fo/PropertyList.java b/src/java/org/apache/fop/fo/PropertyList.java index cdd4a5522..38577e383 100644 --- a/src/java/org/apache/fop/fo/PropertyList.java +++ b/src/java/org/apache/fop/fo/PropertyList.java @@ -245,24 +245,38 @@ abstract public class PropertyList { * @throws FOPException If an error occurs while building the PropertyList */ public void addAttributesToList(Attributes attributes) { - /* - * If font-size is set on this FO, must set it first, since - * other attributes specified in terms of "ems" depend on it. - */ - /** @todo When we do "shorthand" properties, must handle the - * "font" property as well to see if font-size is set. - */ - String attributeName = "font-size"; - String attributeValue = attributes.getValue(attributeName); + /* + * If column-number/number-columns-spanned are specified, then we + * need them before all others (possible from-table-column() on any + * other property further in the list... + */ + String attributeName = "column-number"; + String attributeValue = attributes.getValue(attributeName); + convertAttributeToProperty(attributes, attributeName, + attributeValue); + attributeName = "number-columns-spanned"; + attributeValue = attributes.getValue(attributeName); + convertAttributeToProperty(attributes, attributeName, + attributeValue); + + /* + * If font-size is set on this FO, must set it first, since + * other attributes specified in terms of "ems" depend on it. + */ + /** @todo When we do "shorthand" properties, must handle the + * "font" property as well to see if font-size is set. + */ + attributeName = "font-size"; + attributeValue = attributes.getValue(attributeName); + convertAttributeToProperty(attributes, attributeName, + attributeValue); + + for (int i = 0; i < attributes.getLength(); i++) { + attributeName = attributes.getQName(i); + attributeValue = attributes.getValue(i); convertAttributeToProperty(attributes, attributeName, attributeValue); - - for (int i = 0; i < attributes.getLength(); i++) { - attributeName = attributes.getQName(i); - attributeValue = attributes.getValue(i); - convertAttributeToProperty(attributes, attributeName, - attributeValue); - } + } } /** diff --git a/src/java/org/apache/fop/fo/expr/FromTableColumnFunction.java b/src/java/org/apache/fop/fo/expr/FromTableColumnFunction.java index 101cfb179..61ef82d8b 100644 --- a/src/java/org/apache/fop/fo/expr/FromTableColumnFunction.java +++ b/src/java/org/apache/fop/fo/expr/FromTableColumnFunction.java @@ -18,6 +18,14 @@ package org.apache.fop.fo.expr; +import java.util.List; +import org.apache.fop.fo.Constants; +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.FOPropertyMapping; +import org.apache.fop.fo.flow.Table; +import org.apache.fop.fo.flow.TableFObj; +import org.apache.fop.fo.flow.TableCell; +import org.apache.fop.fo.flow.TableColumn; import org.apache.fop.fo.properties.Property; /** @@ -52,13 +60,73 @@ public class FromTableColumnFunction extends FunctionBase { */ public Property eval(Property[] args, PropertyInfo pInfo) throws PropertyException { - /* uncomment when implementing - String propName = args[0].getString(); - if (propName == null) { - throw new PropertyException("Incorrect parameter to from-table-column function"); + + FObj fo = pInfo.getPropertyList().getFObj(); + + /* obtain property Id for the property for which the function is being + * evaluated */ + int propId = 0; + if (args.length == 0) { + propId = pInfo.getPropertyMaker().getPropId(); + } else { + String propName = args[0].getString(); + propId = FOPropertyMapping.getPropertyId(propName); + } + + /* make sure we have a correct property id ... */ + if (propId != -1) { + /* obtain column number for which the function is being evaluated: */ + int columnNumber = -1; + int span = 0; + if (fo.getNameId() != Constants.FO_TABLE_CELL) { + // climb up to the nearest cell + do { + fo = (FObj) fo.getParent(); + } while (fo.getNameId() != Constants.FO_TABLE_CELL + && fo.getNameId() != Constants.FO_PAGE_SEQUENCE); + if (fo.getNameId() == Constants.FO_TABLE_CELL) { + //column-number is available on the cell + columnNumber = ((TableCell) fo).getColumnNumber(); + span = ((TableCell) fo).getNumberColumnsSpanned(); + } else { + //means no table-cell was found... + throw new PropertyException("from-table-column() may only be used on " + + "fo:table-cell or its descendants."); + } + } else { + //column-number is only accurately available through the propertyList + columnNumber = pInfo.getPropertyList().get(Constants.PR_COLUMN_NUMBER) + .getNumeric().getValue(); + span = pInfo.getPropertyList().get(Constants.PR_NUMBER_COLUMNS_SPANNED) + .getNumeric().getValue(); + } + + /* return the property from the column */ + Table t = ((TableFObj) fo).getTable(); + List cols = t.getColumns(); + if (cols == null) { + //no columns defined => no match: return default value + return pInfo.getPropertyList().get(propId, false, true); + } else { + if (t.isColumnNumberUsed(columnNumber)) { + //easiest case: exact match + return ((TableColumn) cols.get(columnNumber - 1)).getProperty(propId); + } else { + //no exact match: try all spans... + while (--span > 0 && !t.isColumnNumberUsed(++columnNumber)) { + //nop: just increment/decrement + } + if (t.isColumnNumberUsed(columnNumber)) { + return ((TableColumn) cols.get(columnNumber - 1)).getProperty(propId); + } else { + //no match: return default value + return pInfo.getPropertyList().get(propId, false, true); + } + } + } + } else { + throw new PropertyException("Incorrect parameter to from-table-column() function"); } - */ - throw new PropertyException("The from-table-column() function is not implemented, yet!"); } } diff --git a/src/java/org/apache/fop/fo/flow/Table.java b/src/java/org/apache/fop/fo/flow/Table.java index 037316f5c..dc14f642d 100644 --- a/src/java/org/apache/fop/fo/flow/Table.java +++ b/src/java/org/apache/fop/fo/flow/Table.java @@ -71,8 +71,8 @@ public class Table extends TableFObj { /** collection of columns in this table */ protected List columns = null; - private BitSet usedColumnIndices = new BitSet(); private int columnIndex = 1; + private BitSet usedColumnIndices = new BitSet(); private TableBody tableHeader = null; private TableBody tableFooter = null; @@ -212,8 +212,13 @@ public class Table extends TableFObj { missingChildElementError( "(marker*,table-column*,table-header?,table-footer?,table-body+)"); } - //release reference - usedColumnIndices = null; + if (columns != null && !columns.isEmpty()) { + for (int i = columns.size(); --i >= 0;) { + if (isColumnNumberUsed(i + 1)) { + ((TableColumn) columns.get(i)).releasePropertyList(); + } + } + } getFOEventHandler().endTable(this); } @@ -259,11 +264,7 @@ public class Table extends TableFObj { //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 - //TODO: need to make sure START/END BorderInfo - // are completely independent instances (clones?) - // = necessary for border-collapse="collapse" - // if collapsing is handled in FOTree + //TODO: need to force the column-number (?) for (int i = colRepeat - 1; --i >= 0;) { columns.add(col); } @@ -277,6 +278,7 @@ public class Table extends TableFObj { columnIndex++; } } + /** @return true of table-layout="auto" */ public boolean isAutoLayout() { return (tableLayout != EN_FIXED); @@ -426,6 +428,16 @@ public class Table extends TableFObj { } /** + * Checks if a certain column-number is already occupied + * + * @param colNr the column-number to check + * @return true if column-number is already in use + */ + public boolean isColumnNumberUsed(int colNr) { + return usedColumnIndices.get(colNr - 1); + } + + /** * Sets the current column index of the given Table * (used by TableColumn.bind() in case the column-number * was explicitly specified) @@ -435,14 +447,5 @@ public class Table extends TableFObj { public void setCurrentColumnIndex(int newIndex) { columnIndex = newIndex; } - - /** - * Checks if a certain column-number is already occupied - * - * @param colNr the column-number to check - * @return true if column-number is already in use - */ - protected boolean isColumnNumberUsed(int colNr) { - return usedColumnIndices.get(colNr - 1); - } + } diff --git a/src/java/org/apache/fop/fo/flow/TableBody.java b/src/java/org/apache/fop/fo/flow/TableBody.java index 22673b676..e970fb7d9 100644 --- a/src/java/org/apache/fop/fo/flow/TableBody.java +++ b/src/java/org/apache/fop/fo/flow/TableBody.java @@ -404,7 +404,7 @@ public class TableBody extends TableFObj { * @param colNr the column-number to check * @return true if column-number is already occupied */ - protected boolean isColumnNumberUsed(int colNr) { + public boolean isColumnNumberUsed(int colNr) { return usedColumnIndices.get(colNr - 1); } } diff --git a/src/java/org/apache/fop/fo/flow/TableCell.java b/src/java/org/apache/fop/fo/flow/TableCell.java index a3def066a..60826da16 100644 --- a/src/java/org/apache/fop/fo/flow/TableCell.java +++ b/src/java/org/apache/fop/fo/flow/TableCell.java @@ -124,28 +124,6 @@ public class TableCell extends TableFObj { startsRow = pList.get(PR_STARTS_ROW).getEnum(); width = pList.get(PR_WIDTH).getLength(); super.bind(pList); - - //check if any of the column-numbers occupied by this cell - //are already in use in the current row... - int i = -1; - int columnIndex = columnNumber.getValue(); - while (++i < getNumberColumnsSpanned()) { - //if table has explicit columns and the column-number isn't - //assigned to any column, increment further until the next - //column is encountered - if (getTable().columns != null) { - while (columnIndex <= getTable().columns.size() - && !getTable().isColumnNumberUsed(columnIndex)) { - columnIndex++; - } - } - //if column-number is already in use by another cell - //in the current row => error! - if (((TableFObj) parent).isColumnNumberUsed(columnIndex)) { - throw new FOPException("fo:table-cell overlaps in column " - + columnIndex, locator); - } - } } /** diff --git a/src/java/org/apache/fop/fo/flow/TableColumn.java b/src/java/org/apache/fop/fo/flow/TableColumn.java index 112ae8ce5..227bc4e83 100644 --- a/src/java/org/apache/fop/fo/flow/TableColumn.java +++ b/src/java/org/apache/fop/fo/flow/TableColumn.java @@ -26,9 +26,11 @@ import org.apache.fop.datatypes.Length; import org.apache.fop.datatypes.Numeric; 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.expr.PropertyException; import org.apache.fop.fo.properties.CommonBorderPaddingBackground; +import org.apache.fop.fo.properties.Property; /** * Class modelling the fo:table-column object. @@ -44,6 +46,7 @@ public class TableColumn extends TableFObj { // End of property values private boolean defaultColumn; + private StaticPropertyList pList = null; /** * @param parent FONode that is the parent of this object @@ -86,6 +89,7 @@ public class TableColumn extends TableFObj { throw new PropertyException("number-columns-spanned must be 1 or bigger, " + "but got " + numberColumnsSpanned.getValue()); } + this.pList = new StaticPropertyList(this, pList); } /** @@ -183,6 +187,25 @@ public class TableColumn extends TableFObj { 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.getInherited(propId); + } + + /** + * Clear the reference to the PropertyList (retained for from-table-column()) + * + */ + protected void releasePropertyList() { + this.pList = null; + } } diff --git a/src/java/org/apache/fop/fo/flow/TableFObj.java b/src/java/org/apache/fop/fo/flow/TableFObj.java index db95871e5..560b008cb 100644 --- a/src/java/org/apache/fop/fo/flow/TableFObj.java +++ b/src/java/org/apache/fop/fo/flow/TableFObj.java @@ -144,7 +144,7 @@ public abstract class TableFObj extends FObj { * @param colNr the column-number to check * @return true if column-number is already in use */ - protected boolean isColumnNumberUsed(int colNr) { + public boolean isColumnNumberUsed(int colNr) { return false; } @@ -155,7 +155,7 @@ public abstract class TableFObj extends FObj { * @return the base table instance * */ - protected Table getTable() { + public Table getTable() { if (this.getNameId() == FO_TABLE) { //node is a Table //=> return itself diff --git a/src/java/org/apache/fop/fo/flow/TableRow.java b/src/java/org/apache/fop/fo/flow/TableRow.java index bc4fad6cb..57da0f190 100644 --- a/src/java/org/apache/fop/fo/flow/TableRow.java +++ b/src/java/org/apache/fop/fo/flow/TableRow.java @@ -316,7 +316,7 @@ public class TableRow extends TableFObj { * @param colNr the column-number to check * @return true if column-number is already occupied */ - protected boolean isColumnNumberUsed(int colNr) { + public boolean isColumnNumberUsed(int colNr) { return usedColumnIndices.get(colNr - 1); } } diff --git a/src/java/org/apache/fop/fo/properties/ColumnNumberPropertyMaker.java b/src/java/org/apache/fop/fo/properties/ColumnNumberPropertyMaker.java index 211055e5c..71d422b30 100644 --- a/src/java/org/apache/fop/fo/properties/ColumnNumberPropertyMaker.java +++ b/src/java/org/apache/fop/fo/properties/ColumnNumberPropertyMaker.java @@ -18,6 +18,7 @@ package org.apache.fop.fo.properties; +import org.apache.fop.apps.FOPException; import org.apache.fop.fo.Constants; import org.apache.fop.fo.FObj; import org.apache.fop.fo.PropertyList; @@ -85,19 +86,44 @@ public class ColumnNumberPropertyMaker extends NumberProperty.Maker { throws PropertyException { Property p = super.get(0, propertyList, tryInherit, tryDefault); - FObj fo = propertyList.getFObj(); + TableFObj fo = (TableFObj) propertyList.getFObj(); TableFObj parent = (TableFObj) propertyList.getParentFObj(); + int columnIndex = p.getNumeric().getValue(); - if (p.getNumeric().getValue() <= 0) { - int columnIndex = parent.getCurrentColumnIndex(); + if (columnIndex <= 0) { fo.getLogger().warn("Specified negative or zero value for " + "column-number on " + fo.getName() + ": " - + p.getNumeric().getValue() + " forced to " - + columnIndex); - return new NumberProperty(columnIndex); + + columnIndex + " forced to " + + parent.getCurrentColumnIndex()); + return new NumberProperty(parent.getCurrentColumnIndex()); } //TODO: check for non-integer value and round + if (fo.getNameId() == Constants.FO_TABLE_CELL) { + //check if any of the column-numbers occupied by this cell + //are already in use in the current row... + int i = -1; + int colspan = propertyList.get(Constants.PR_NUMBER_COLUMNS_SPANNED) + .getNumeric().getValue(); + while (++i < colspan) { + //if table has explicit columns and the column-number isn't + //assigned to any column, increment further until the next + //column is encountered + if (fo.getTable().getColumns() != null) { + while (columnIndex <= fo.getTable().getColumns().size() + && !fo.getTable().isColumnNumberUsed(columnIndex)) { + columnIndex++; + } + } + //if column-number is already in use by another cell + //in the current row => error! + if (parent.isColumnNumberUsed(columnIndex + i)) { + throw new PropertyException("fo:table-cell overlaps in column " + + (columnIndex + i)); + } + } + } + //if column-number was explicitly specified, force the parent's current //column index to the specified value, so that the updated index will //be the correct initial value for the next cell (see Rec 7.26.8) diff --git a/status.xml b/status.xml index cd4b76c6c..5c17e4b58 100644 --- a/status.xml +++ b/status.xml @@ -27,6 +27,10 @@ <changes> <release version="FOP Trunk"> + <action context="Code" dev="AD" type="add"> + Added support for the from-table-column() function. + (Thanks to gerhard.oettl.at.oesoft.at for the inspiration.) + </action> <action context="Code" dev="JM" type="fix" fixes-bug="38397"> Bugfix: Spanned cells could lead to an false error message about overlapping cells and ultimately a NullPointerException. diff --git a/test/fotree/disabled-testcases.xml b/test/fotree/disabled-testcases.xml index 1ae6f553a..a574d39f5 100755 --- a/test/fotree/disabled-testcases.xml +++ b/test/fotree/disabled-testcases.xml @@ -31,4 +31,10 @@ <file>inline-progression-dimension_negative.fo</file> <description>The code currently doesn't set negative values to 0mpt as mandated by the spec.</description> </testcase> + <testcase> + <name>Markers and core function evaluation</name> + <file>from-table-column_marker.fo</file> + <description>The code currently evaluates this function according to the column in which the + marker appearsin the source document, rather than the column it is retrieved in.</description> + </testcase> </disabled-testcases> diff --git a/test/fotree/testcases/properties_omitted_propertyname.fo b/test/fotree/testcases/properties_omitted_propertyname.fo index 3ded0a105..77ee13458 100644 --- a/test/fotree/testcases/properties_omitted_propertyname.fo +++ b/test/fotree/testcases/properties_omitted_propertyname.fo @@ -61,7 +61,36 @@ </fo:block> </fo:block> </fo:block> - <!-- from-table-column (not implemented) --> + <fo:table border-collapse="separate" table-layout="fixed" width="100%"> + <fo:table-column column-width="proportional-column-width(1)" + text-align="start" /> + <fo:table-column column-width="proportional-column-width(1)" + text-align="center" /> + <fo:table-column column-width="proportional-column-width(1)" + text-align="end" /> + <fo:table-body> + <fo:table-cell starts-row="true"> + <fo:block text-align="from-table-column()"> + <test:assert property="text-align" expected="START" /> + Start-aligned + </fo:block> + </fo:table-cell> + <fo:table-cell text-align="from-table-column()" column-number="3"> + <test:assert property="text-align" expected="END" /> + <fo:block> + <test:assert property="text-align" expected="END" /> + End-aligned + </fo:block> + </fo:table-cell> + <fo:table-cell column-number="2"> + <fo:block text-align="from-table-column()"> + <test:assert property="text-align" expected="CENTER" /> + Center-aligned + </fo:block> + </fo:table-cell> + </fo:table-body> + </fo:table> + <!-- merge-property-value (not implemented) --> </fo:flow> </fo:page-sequence> |