klease 01/10/14 13:43:32 Modified: src/org/apache/fop/fo/flow Table.java TableColumn.java Log: Implement proportional column widths Revision Changes Path 1.39 +179 -14 xml-fop/src/org/apache/fop/fo/flow/Table.java Index: Table.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/fo/flow/Table.java,v retrieving revision 1.38 retrieving revision 1.39 diff -u -r1.38 -r1.39 --- Table.java 2001/09/20 21:01:18 1.38 +++ Table.java 2001/10/14 20:43:32 1.39 @@ -1,5 +1,5 @@ /* - * -- $Id: Table.java,v 1.38 2001/09/20 21:01:18 klease Exp $ -- + * -- $Id: Table.java,v 1.39 2001/10/14 20:43:32 klease Exp $ -- * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. * For details on use and redistribution please refer to the * LICENSE file included with these sources. @@ -32,12 +32,13 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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) { @@ -367,28 +388,127 @@ } } } + - 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(); } @@ -402,6 +522,51 @@ else 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 1.20 +34 -20 xml-fop/src/org/apache/fop/fo/flow/TableColumn.java Index: TableColumn.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/fo/flow/TableColumn.java,v retrieving revision 1.19 retrieving revision 1.20 diff -u -r1.19 -r1.20 --- TableColumn.java 2001/09/20 20:29:22 1.19 +++ TableColumn.java 2001/10/14 20:43:32 1.20 @@ -1,5 +1,5 @@ /* - * $Id: TableColumn.java,v 1.19 2001/09/20 20:29:22 klease Exp $ + * $Id: TableColumn.java,v 1.20 2001/10/14 20:43:32 klease Exp $ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. * For details on use and redistribution please refer to the * LICENSE file included with these sources. @@ -18,6 +18,7 @@ ColorType backgroundColor; + Length columnWidthPropVal; int columnWidth; int columnOffset; int numColumnsRepeated; @@ -44,10 +45,22 @@ 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 @@ 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 @@ 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 void setHeight(int height) { - areaContainer.setMaxHeight(height); - areaContainer.setHeight(height); + if (areaContainer != null) { + areaContainer.setMaxHeight(height); + areaContainer.setHeight(height); + } } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]