in assets/support/faq/docbook-xsl/extensions/xalan2/com/nwalsh/xalan/Table.java [223:474]
public DocumentFragment adjustColumnWidths (ExpressionContext context,
NodeIterator xalanNI) {
int nominalWidth = convertLength(Params.getString(context,
"nominal.table.width"));
String tableWidth = Params.getString(context, "table.width");
String styleType = Params.getString(context, "stylesheet.result.type");
boolean foStylesheet = styleType.equals("fo");
DocumentFragment xalanRTF = (DocumentFragment) xalanNI.nextNode();
Element colgroup = (Element) xalanRTF.getFirstChild();
// N.B. ...stree.ElementImpl doesn't implement getElementsByTagName()
Node firstCol = null;
// If this is an FO tree, there might be no colgroup...
if (colgroup.getLocalName().equals("colgroup")) {
firstCol = colgroup.getFirstChild();
} else {
firstCol = colgroup;
}
// Count the number of columns...
Node child = firstCol;
int numColumns = 0;
while (child != null) {
if (child.getNodeType() == Node.ELEMENT_NODE
&& (child.getNodeName().equals("col")
|| (child.getNamespaceURI().equals(foURI)
&& child.getLocalName().equals("table-column")))) {
numColumns++;
}
child = child.getNextSibling();
}
String widths[] = new String[numColumns];
Element columns[] = new Element[numColumns];
int colnum = 0;
child = firstCol;
while (child != null) {
if (child.getNodeType() == Node.ELEMENT_NODE
&& (child.getNodeName().equals("col")
|| (child.getNamespaceURI().equals(foURI)
&& child.getLocalName().equals("table-column")))) {
Element col = (Element) child;
columns[colnum] = col;
if (foStylesheet) {
if (col.getAttribute("column-width") == null) {
widths[colnum] = "1*";
} else {
widths[colnum] = col.getAttribute("column-width");
}
} else {
if (col.getAttribute("width") == null) {
widths[colnum] = "1*";
} else {
widths[colnum] = col.getAttribute("width");
}
}
colnum++;
}
child = child.getNextSibling();
}
float relTotal = 0;
float relParts[] = new float[numColumns];
float absTotal = 0;
float absParts[] = new float[numColumns];
for (int count = 0; count < numColumns; count++) {
String width = widths[count];
int pos = width.indexOf("*");
if (pos >= 0) {
String relPart = width.substring(0, pos);
String absPart = width.substring(pos+1);
try {
float rel = Float.parseFloat(relPart);
relTotal += rel;
relParts[count] = rel;
} catch (NumberFormatException e) {
System.out.println(relPart + " is not a valid relative unit.");
}
int pixels = 0;
if (absPart != null && !absPart.equals("")) {
pixels = convertLength(absPart);
}
absTotal += pixels;
absParts[count] = pixels;
} else {
relParts[count] = 0;
int pixels = 0;
if (width != null && !width.equals("")) {
pixels = convertLength(width);
}
absTotal += pixels;
absParts[count] = pixels;
}
}
// Ok, now we have the relative widths and absolute widths in
// two parallel arrays.
//
// - If there are no relative widths, output the absolute widths
// - If there are no absolute widths, output the relative widths
// - If there are a mixture of relative and absolute widths,
// - If the table width is absolute, turn these all into absolute
// widths.
// - If the table width is relative, turn these all into absolute
// widths in the nominalWidth and then turn them back into
// percentages.
if (relTotal == 0) {
for (int count = 0; count < numColumns; count++) {
Float f = new Float(absParts[count]);
if (foStylesheet) {
int pixels = f.intValue();
float inches = (float) pixels / pixelsPerInch;
widths[count] = inches + "in";
} else {
widths[count] = Integer.toString(f.intValue());
}
}
} else if (absTotal == 0) {
for (int count = 0; count < numColumns; count++) {
float rel = relParts[count] / relTotal * 100;
Float f = new Float(rel);
widths[count] = Integer.toString(f.intValue());
}
widths = correctRoundingError(widths);
} else {
int pixelWidth = nominalWidth;
if (tableWidth.indexOf("%") <= 0) {
pixelWidth = convertLength(tableWidth);
}
if (pixelWidth <= absTotal) {
System.out.println("Table is wider than table width.");
} else {
pixelWidth -= absTotal;
}
absTotal = 0;
for (int count = 0; count < numColumns; count++) {
float rel = relParts[count] / relTotal * pixelWidth;
relParts[count] = rel + absParts[count];
absTotal += rel + absParts[count];
}
if (tableWidth.indexOf("%") <= 0) {
for (int count = 0; count < numColumns; count++) {
Float f = new Float(relParts[count]);
if (foStylesheet) {
int pixels = f.intValue();
float inches = (float) pixels / pixelsPerInch;
widths[count] = inches + "in";
} else {
widths[count] = Integer.toString(f.intValue());
}
}
} else {
for (int count = 0; count < numColumns; count++) {
float rel = relParts[count] / absTotal * 100;
Float f = new Float(rel);
widths[count] = Integer.toString(f.intValue());
}
widths = correctRoundingError(widths);
}
}
// Now rebuild the colgroup with the right widths
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = null;
try {
docBuilder = docFactory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
System.out.println("PCE!");
return xalanRTF;
}
Document doc = docBuilder.newDocument();
DocumentFragment df = doc.createDocumentFragment();
DOMBuilder rtf = new DOMBuilder(doc, df);
try {
String ns = colgroup.getNamespaceURI();
String localName = colgroup.getLocalName();
String name = colgroup.getTagName();
if (colgroup.getLocalName().equals("colgroup")) {
rtf.startElement(ns, localName, name,
copyAttributes(colgroup));
}
for (colnum = 0; colnum < numColumns; colnum++) {
Element col = columns[colnum];
NamedNodeMap domAttr = col.getAttributes();
AttributesImpl attr = new AttributesImpl();
for (int acount = 0; acount < domAttr.getLength(); acount++) {
Node a = domAttr.item(acount);
String a_ns = a.getNamespaceURI();
String a_localName = a.getLocalName();
if ((foStylesheet && !a_localName.equals("column-width"))
|| !a_localName.equalsIgnoreCase("width")) {
attr.addAttribute(a.getNamespaceURI(),
a.getLocalName(),
a.getNodeName(),
"CDATA",
a.getNodeValue());
}
}
if (foStylesheet) {
attr.addAttribute("", "column-width", "column-width", "CDATA", widths[colnum]);
} else {
attr.addAttribute("", "width", "width", "CDATA", widths[colnum]);
}
rtf.startElement(col.getNamespaceURI(),
col.getLocalName(),
col.getTagName(),
attr);
rtf.endElement(col.getNamespaceURI(),
col.getLocalName(),
col.getTagName());
}
if (colgroup.getLocalName().equals("colgroup")) {
rtf.endElement(ns, localName, name);
}
} catch (SAXException se) {
System.out.println("SE!");
return xalanRTF;
}
return df;
}