]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Implement proportional column widths
authorKaren Lease <klease@apache.org>
Sun, 14 Oct 2001 20:43:32 +0000 (20:43 +0000)
committerKaren Lease <klease@apache.org>
Sun, 14 Oct 2001 20:43:32 +0000 (20:43 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194510 13f79535-47bb-0310-9956-ffa450edef68

src/org/apache/fop/fo/flow/Table.java
src/org/apache/fop/fo/flow/TableColumn.java

index faeebd153c880bc99a08f7b3d37014303e69243b..6ebd4b711e2ff1575396e68a5b5c75e64df609d5 100644 (file)
@@ -32,12 +32,13 @@ public class Table extends FObj {
         return new Table.Maker();
     }
 
+    private static final int MINCOLWIDTH = 10000; // 10pt
     int breakBefore;
     int breakAfter;
     int spaceBefore;
     int spaceAfter;
     ColorType backgroundColor;
-    int width;
+    LengthRange ipd;
     int height;
     String id;
     TableHeader tableHeader = null;
@@ -47,6 +48,14 @@ public class Table extends FObj {
 
     Vector columns = new Vector();
     int bodyCount = 0;
+    private boolean bAutoLayout=false;
+    private int contentWidth = 0; // Sum of column widths
+    /** Optimum inline-progression-dimension */
+    private int optIPD;
+    /** Minimum inline-progression-dimension */
+    private int minIPD;
+    /** Maximum inline-progression-dimension */
+    private int maxIPD;
 
     AreaContainer areaContainer;
 
@@ -106,8 +115,12 @@ public class Table extends FObj {
                 this.properties.get("space-after.optimum").getLength().mvalue();
             this.backgroundColor =
                 this.properties.get("background-color").getColorType();
-            this.width = this.properties.get("width").getLength().mvalue();
+            this.ipd =
+               this.properties.get("inline-progression-dimension").
+               getLengthRange();
             this.height = this.properties.get("height").getLength().mvalue();
+            this.bAutoLayout = (this.properties.get("table-layout").getEnum() == 
+               TableLayout.AUTO);
 
             this.id = this.properties.get("id").getString();
 
@@ -157,6 +170,7 @@ public class Table extends FObj {
             new AreaContainer(propMgr.getFontState(area.getFontInfo()), 0, 0,
                               area.getAllocationWidth(), area.spaceLeft(),
                               Position.STATIC);
+
         areaContainer.foCreator = this;    // G Seshadri
         areaContainer.setPage(area.getPage());
         areaContainer.setBackgroundColor(backgroundColor);
@@ -170,13 +184,20 @@ public class Table extends FObj {
         boolean addedFooter = false;
         int numChildren = this.children.size();
 
-       // Set up the column vector
+       // Set up the column vector;
+       // calculate width of all columns and get total width
        if (columns.size()==0) {
            findColumns(areaContainer);
+           if (this.bAutoLayout) {
+               log.warn("table-layout=auto is not supported, using fixed!");
+           }
+           // Pretend it's fixed...
+           this.contentWidth = 
+               calcFixedColumnWidths(areaContainer.getAllocationWidth());
        }
-       // Now layout all the columns and get total offset
-        areaContainer.setAllocationWidth( layoutColumns(areaContainer));
-
+        areaContainer.setAllocationWidth(this.contentWidth);
+        layoutColumns(areaContainer);
+       
         for (int i = this.marker; i < numChildren; i++) {
             FONode fo = (FONode)children.elementAt(i);
             if (fo instanceof TableHeader) {
@@ -368,27 +389,126 @@ public class Table extends FObj {
         }
     }
 
-    private int layoutColumns(Area areaContainer) throws FOPException  {
-        int offset = 0;
+
+
+    private int calcFixedColumnWidths(int maxAllocationWidth) {
        int nextColumnNumber=1;
+       int iEmptyCols=0;
+       double dTblUnits=0.0;
+       int iFixedWidth=0;
+       double dWidthFactor = 0.0;
+       double dUnitLength = 0.0;
+       double tuMin = 100000.0 ; // Minimum number of proportional units
        Enumeration eCol = columns.elements();
        while (eCol.hasMoreElements()) {
            TableColumn c = (TableColumn)eCol.nextElement();
            if (c == null) {
-               log.warn("No table-column specified in column " +
+               log.warn("No table-column specification for column " +
                         nextColumnNumber);
+               // What about sizing issues?
+               iEmptyCols++;
            }
            else {
-               //c.doSetup(areaContainer);
-               c.setColumnOffset(offset);
-               c.layout(areaContainer);
-               offset += c.getColumnWidth();
+                Length colLength = c.getColumnWidthAsLength();
+               double tu = colLength.getTableUnits();
+               if (tu > 0 && tu < tuMin && colLength.mvalue()==0) {
+                   /* Keep track of minimum number of proportional units
+                    * in any column which has only proportional units.
+                    */
+                   tuMin = tu;
+               }
+               dTblUnits += tu;
+               iFixedWidth +=  colLength.mvalue();
            }
            nextColumnNumber++;
        }
+
+       setIPD((dTblUnits > 0.0), maxAllocationWidth);
+       if (dTblUnits > 0.0) {
+           int iProportionalWidth = 0;
+           if (this.optIPD > iFixedWidth) {
+               iProportionalWidth = this.optIPD - iFixedWidth;
+           }
+           else if (this.maxIPD > iFixedWidth) {
+               iProportionalWidth = this.maxIPD - iFixedWidth;
+           }
+           else {
+               iProportionalWidth = maxAllocationWidth - iFixedWidth;
+           }
+           if (iProportionalWidth > 0) {
+               dUnitLength = ((double)iProportionalWidth)/dTblUnits;
+           }
+           else {
+               log.error("Sum of fixed column widths " + iFixedWidth +
+                         " greater than maximum available IPD " +
+                         maxAllocationWidth + "; no space for " +
+                         dTblUnits + " proportional units.");
+               /* Set remaining proportional units to a number which
+                * will assure the minimum column size for tuMin.
+                */
+               dUnitLength = MINCOLWIDTH/tuMin;
+               // Reduce fixed column widths by this much???
+           }
+           //log.debug("1 table-unit = " + dUnitLength + " mpt");
+       }
+       else {
+           /* No proportional units. If minimum IPD is specified, check
+            * that sum of column widths > minIPD.
+            */
+           int iTableWidth = iFixedWidth;
+           if (this.minIPD > iFixedWidth) {
+               iTableWidth = this.minIPD;
+               // Add extra space to each column
+               dWidthFactor = (double)this.minIPD/(double)iFixedWidth;
+           }
+           else if (this.maxIPD < iFixedWidth) {
+               // Note: if maxIPD=auto, use maxAllocWidth
+               log.warn("Sum of fixed column widths " + iFixedWidth +
+                        " greater than maximum specified IPD " + this.maxIPD);
+           }
+           else if (this.optIPD != -1 && iFixedWidth != this.optIPD) {
+               log.warn("Sum of fixed column widths " + iFixedWidth +
+                        " differs from specified optimum IPD " + this.optIPD);
+           }
+       }
+       // Now distribute the extra units onto each column and set offsets
+       int offset = 0;
+       eCol = columns.elements();
+       while (eCol.hasMoreElements()) {
+           TableColumn c = (TableColumn)eCol.nextElement();
+           if (c != null) {
+               c.setColumnOffset(offset);
+               Length l = c.getColumnWidthAsLength();
+               if (dUnitLength > 0) {
+                   l.resolveTableUnit(dUnitLength);
+               }
+               // Check minimum values and adjust if necessary
+               int colWidth = l.mvalue();
+               if (colWidth <= 0) {
+                   log.warn("Zero-width table column!");
+               }
+               if (dWidthFactor > 0.0) {
+                   // Increase column sizes to use up extra space
+                   colWidth *= dWidthFactor;
+               }
+               c.setColumnWidth(colWidth);
+               offset += colWidth;
+           }
+       }
        return offset;
     }
 
+    private void layoutColumns(Area tableArea) throws FOPException  {
+       Enumeration eCol = columns.elements();
+       while (eCol.hasMoreElements()) {
+           TableColumn c = (TableColumn)eCol.nextElement();
+           if (c != null) {
+               c.layout(tableArea);
+           }
+       }
+    }
+
+
     public int getAreaHeight() {
         return areaContainer.getHeight();
     }
@@ -403,6 +523,51 @@ public class Table extends FObj {
             return 0;    // not laid out yet
     }
 
+    /**
+     * Initialize table inline-progression-properties values
+     */
+    private void setIPD(boolean bHasProportionalUnits, int maxAllocIPD) {
+       boolean bMaxIsSpecified = !this.ipd.getMaximum().getLength().isAuto();
+       if (bMaxIsSpecified) {
+           this.maxIPD = ipd.getMaximum().getLength().mvalue();
+       }
+       else {
+           this.maxIPD = maxAllocIPD;
+       }
+
+       if (ipd.getOptimum().getLength().isAuto()) {
+           this.optIPD = -1;
+       }
+       else {
+           this.optIPD = ipd.getMaximum().getLength().mvalue();
+       }
+       if (ipd.getMinimum().getLength().isAuto()) {
+           this.minIPD = -1;
+       }
+       else {
+           this.minIPD = ipd.getMinimum().getLength().mvalue();
+       }
+       if (bHasProportionalUnits && this.optIPD < 0) {
+           if (this.minIPD > 0) {
+               if (bMaxIsSpecified) {
+                   this.optIPD = (minIPD + maxIPD)/2;
+               }
+               else {
+                   this.optIPD = this.minIPD;
+               }
+           }
+           else if (bMaxIsSpecified) {
+               this.optIPD = this.maxIPD;
+           }
+           else {
+               log.error("At least one of minimum, optimum, or maximum " +
+                         "IPD must be specified on table.");
+               this.optIPD = this.maxIPD;
+           }
+       }
+    }
+
+
     // /**
     // * Return the last TableRow in the header or null if no header or
     // * no header in non-first areas.
index f4eddc5dd262319f46152e8a91556f81a7793dba..44684ae335272ef70f848c5c822dd327ccfb1459 100644 (file)
@@ -18,6 +18,7 @@ public class TableColumn extends FObj {
 
     ColorType backgroundColor;
 
+    Length columnWidthPropVal;
     int columnWidth;
     int columnOffset;
     int numColumnsRepeated;
@@ -44,10 +45,22 @@ public class TableColumn extends FObj {
         this.name = "fo:table-column";
     }
 
+    public Length getColumnWidthAsLength() {
+        return columnWidthPropVal;
+    }
+
     public int getColumnWidth() {
         return columnWidth;
     }
 
+    /**
+     * Set the column width value in base units which overrides the
+     * value from the column-width Property.
+     */
+    public void setColumnWidth(int columnWidth) {
+        this.columnWidth = columnWidth;
+    }
+
     public int getColumnNumber() {
         return iColumnNumber;
     }
@@ -78,8 +91,10 @@ public class TableColumn extends FObj {
         this.backgroundColor =
             this.properties.get("background-color").getColorType();
 
-        this.columnWidth =
-            this.properties.get("column-width").getLength().mvalue();
+        this.columnWidthPropVal =
+            this.properties.get("column-width").getLength();
+       // This won't include resolved table-units or % values yet.
+       this.columnWidth = columnWidthPropVal.mvalue();
 
         // initialize id
         String id = this.properties.get("id").getString();
@@ -98,21 +113,18 @@ public class TableColumn extends FObj {
                 doSetup(area);
             }
         }
-
-        // KL: don't take table borders into account!
-        this.areaContainer =
-            new AreaContainer(propMgr.getFontState(area.getFontInfo()),
-                              columnOffset /* - area.getBorderLeftWidth() */,
-                              /* -area.getBorderTopWidth() */
-        0, columnWidth, area.getContentHeight(), Position.RELATIVE);
-        // area.getHeight(), Position.RELATIVE);
-        areaContainer.foCreator = this;    // G Seshadri
-        areaContainer.setPage(area.getPage());
-        areaContainer.setBorderAndPadding(propMgr.getBorderAndPadding());
-        areaContainer.setBackgroundColor(this.backgroundColor);
-        areaContainer.setHeight(area.getHeight());
-        area.addChild(areaContainer);
-
+       if (columnWidth > 0) {
+           this.areaContainer =
+               new AreaContainer(propMgr.getFontState(area.getFontInfo()),
+                                 columnOffset, 0, columnWidth,
+                                 area.getContentHeight(), Position.RELATIVE);
+           areaContainer.foCreator = this;    // G Seshadri
+           areaContainer.setPage(area.getPage());
+           areaContainer.setBorderAndPadding(propMgr.getBorderAndPadding());
+           areaContainer.setBackgroundColor(this.backgroundColor);
+           areaContainer.setHeight(area.getHeight());
+           area.addChild(areaContainer);
+       }
         return new Status(Status.OK);
     }
 
@@ -121,8 +133,10 @@ public class TableColumn extends FObj {
     }
 
     public void setHeight(int height) {
-        areaContainer.setMaxHeight(height);
-        areaContainer.setHeight(height);
+       if (areaContainer != null) {
+           areaContainer.setMaxHeight(height);
+           areaContainer.setHeight(height);
+       }
     }
 
 }