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;
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;
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();
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);
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) {
}
}
- 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();
}
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.
ColorType backgroundColor;
+ Length columnWidthPropVal;
int columnWidth;
int columnOffset;
int numColumnsRepeated;
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;
}
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();
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);
}
}
public void setHeight(int height) {
- areaContainer.setMaxHeight(height);
- areaContainer.setHeight(height);
+ if (areaContainer != null) {
+ areaContainer.setMaxHeight(height);
+ areaContainer.setHeight(height);
+ }
}
}