From: Karen Lease Date: Sun, 14 Oct 2001 20:43:32 +0000 (+0000) Subject: Implement proportional column widths X-Git-Tag: fop-0_20_3~8 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=93f018a104010262c09115de87dfb6013279b393;p=xmlgraphics-fop.git Implement proportional column widths git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194510 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/org/apache/fop/fo/flow/Table.java b/src/org/apache/fop/fo/flow/Table.java index faeebd153..6ebd4b711 100644 --- a/src/org/apache/fop/fo/flow/Table.java +++ b/src/org/apache/fop/fo/flow/Table.java @@ -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. diff --git a/src/org/apache/fop/fo/flow/TableColumn.java b/src/org/apache/fop/fo/flow/TableColumn.java index f4eddc5dd..44684ae33 100644 --- a/src/org/apache/fop/fo/flow/TableColumn.java +++ b/src/org/apache/fop/fo/flow/TableColumn.java @@ -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); + } } }