]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Implementation for from-table-column(). See: bugzilla 38282
authorAndreas L. Delmelle <adelmelle@apache.org>
Tue, 31 Jan 2006 22:09:36 +0000 (22:09 +0000)
committerAndreas L. Delmelle <adelmelle@apache.org>
Tue, 31 Jan 2006 22:09:36 +0000 (22:09 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@373922 13f79535-47bb-0310-9956-ffa450edef68

13 files changed:
src/documentation/content/xdocs/compliance.ihtml
src/java/org/apache/fop/fo/PropertyList.java
src/java/org/apache/fop/fo/expr/FromTableColumnFunction.java
src/java/org/apache/fop/fo/flow/Table.java
src/java/org/apache/fop/fo/flow/TableBody.java
src/java/org/apache/fop/fo/flow/TableCell.java
src/java/org/apache/fop/fo/flow/TableColumn.java
src/java/org/apache/fop/fo/flow/TableFObj.java
src/java/org/apache/fop/fo/flow/TableRow.java
src/java/org/apache/fop/fo/properties/ColumnNumberPropertyMaker.java
status.xml
test/fotree/disabled-testcases.xml
test/fotree/testcases/properties_omitted_propertyname.fo

index 001fe70a0299104f0a30e743620cf364626d9117..18ededcbeaf3d527d54d9c6d9f11bdef24b8f618 100644 (file)
       <td class="no">
         no
       </td>
-      <td class="no">
-        no
+      <td class="yes">
+        yes
       </td>
       <td align="center">
         &nbsp;
index cdd4a5522aeb4d0f863322fe8f6d20913d610f4c..38577e3837f3bfec9e36e3a4b4c8fd358a69b34f 100644 (file)
@@ -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);
-            }
+        }
     }
 
     /**
index 101cfb179d824895bf7db715937ea0f7598e0229..61ef82d8bf81c043f89e33ffd55dd88659014860 100644 (file)
 
 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!");
     }
 
 }
index 037316f5cedcd3d873fd1737f3dc6b3b2822965c..dc14f642d33cc168f1deb2a2c0a02037a4217c56 100644 (file)
@@ -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);
@@ -425,6 +427,16 @@ public class Table extends TableFObj {
         return columnIndex;
     }
 
+    /**
+     * Checks if a certain column-number is already occupied
+     * 
+     * @param colNr the column-number to check
+     * @return true if column-number is already in use
+     */
+    public boolean isColumnNumberUsed(int colNr) {
+        return usedColumnIndices.get(colNr - 1);
+    }
+
     /**
      * Sets the current column index of the given Table
      * (used by TableColumn.bind() in case the column-number
@@ -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);
-    }    
+    
 }
index 22673b676c72c43fa5c3e56e8ce19f2f7c754882..e970fb7d92e3cc615621ff2abb9d4d95e06f6fff 100644 (file)
@@ -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);
     }    
 }
index a3def066a111f71cba3020474e6799617415e725..60826da163454fcf462d7dfd73e9794cfc1ec913 100644 (file)
@@ -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);
-            }
-        }
     }
 
     /**
index 112ae8ce5faac45b81fdf2c5da09553a9493698a..227bc4e83d4f63e7ecf6d188beded5ffd3dec1a5 100644 (file)
@@ -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;
+    }
 
 }
 
index db95871e5cce7451c806fef3f50098dabccf1a45..560b008cb9fe30e243738b25a4f4359a1b4bfed4 100644 (file)
@@ -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
index bc4fad6cb8bd55d94cd4d51fd1de16ee3c260946..57da0f190b382a8c9c563557d41bf31655bc0568 100644 (file)
@@ -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);
     }
 }
index 211055e5c40e8f29f9449061c6f95f319f7b0bf6..71d422b30d033e18c310510400b78644e100d933 100644 (file)
@@ -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)
index cd4b76c6c854c22bfc70b518c3c12923e97cd12d..5c17e4b58823966fd8d0e35e5b59705d98b3a8b5 100644 (file)
 
   <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.
index 1ae6f553a3aed75101d68105b8c5494fd02b54cf..a574d39f541762971440432c7e8b7b0aa7430001 100755 (executable)
     <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>
index 3ded0a105e54e6c57ff7a8ee0165bbe4fa9ec09b..77ee1345805c8fea218061a9e67cb4af94d42267 100644 (file)
           </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>