Browse Source

Implement proportional column widths


git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194510 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-0_20_3
Karen Lease 22 years ago
parent
commit
93f018a104
2 changed files with 211 additions and 32 deletions
  1. 178
    13
      src/org/apache/fop/fo/flow/Table.java
  2. 33
    19
      src/org/apache/fop/fo/flow/TableColumn.java

+ 178
- 13
src/org/apache/fop/fo/flow/Table.java View 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.

+ 33
- 19
src/org/apache/fop/fo/flow/TableColumn.java View 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);
}
}

}

Loading…
Cancel
Save