1 3 package com.nwalsh.saxon; 4 5 import java.util.Hashtable ; 6 import org.xml.sax.*; 7 import org.w3c.dom.*; 8 import javax.xml.transform.TransformerException ; 9 import com.icl.saxon.Controller; 10 import com.icl.saxon.expr.*; 11 import com.icl.saxon.om.*; 12 import com.icl.saxon.pattern.*; 13 import com.icl.saxon.Context; 14 import com.icl.saxon.tree.*; 15 import com.icl.saxon.functions.Extensions; 16 17 56 public class Table { 57 58 private static int pixelsPerInch = 96; 59 60 61 private static int nominalWidth = 6 * pixelsPerInch; 62 63 64 private static String tableWidth = "100%"; 65 66 67 private static boolean foStylesheet = false; 68 69 70 protected static Hashtable unitHash = null; 71 72 77 public Table() { 78 } 79 80 81 protected static void initializeHash() { 82 unitHash = new Hashtable (); 83 unitHash.put("in", new Float (pixelsPerInch)); 84 unitHash.put("cm", new Float (pixelsPerInch / 2.54)); 85 unitHash.put("mm", new Float (pixelsPerInch / 25.4)); 86 unitHash.put("pc", new Float ((pixelsPerInch / 72) * 12)); 87 unitHash.put("pt", new Float (pixelsPerInch / 72)); 88 unitHash.put("px", new Float (1)); 89 } 90 91 92 public static void setPixelsPerInch(int value) { 93 if (value > 0) { 94 pixelsPerInch = value; 95 initializeHash(); 96 } 97 } 98 99 100 public int getPixelsPerInch() { 101 return pixelsPerInch; 102 } 103 104 110 public static int convertLength(String length) { 111 int sign = 1; 113 String digits = ""; 114 String units = ""; 115 char lench[] = length.toCharArray(); 116 float flength = 0; 117 boolean done = false; 118 int pos = 0; 119 float factor = 1; 120 int pixels = 0; 121 122 if (unitHash == null) { 123 initializeHash(); 124 } 125 126 if (lench[pos] == '+' || lench[pos] == '-') { 127 if (lench[pos] == '-') { 128 sign = -1; 129 } 130 pos++; 131 } 132 133 while (!done) { 134 if (pos >= lench.length) { 135 done = true; 136 } else { 137 if ((lench[pos] > '9' || lench[pos] < '0') && lench[pos] != '.') { 138 done = true; 139 units = length.substring(pos); 140 } else { 141 digits += lench[pos++]; 142 } 143 } 144 } 145 146 try { 147 flength = Float.parseFloat(digits); 148 } catch (NumberFormatException e) { 149 System.out.println(digits + " is not a number; 1 used instead."); 150 flength = 1; 151 } 152 153 Float f = null; 154 155 if (!units.equals("")) { 156 f = (Float ) unitHash.get(units); 157 if (f == null) { 158 System.out.println(units + " is not a known unit; 1 used instead."); 159 factor = 1; 160 } else { 161 factor = f.floatValue(); 162 } 163 } else { 164 factor = 1; 165 } 166 167 f = new Float (flength * factor); 168 169 pixels = f.intValue() * sign; 170 171 return pixels; 172 } 173 174 186 protected static String getVariable(Context context, String varName) 187 throws TransformerException { 188 Value variable = null; 189 String varString = null; 190 191 try { 192 variable = Extensions.evaluate(context, "$" + varName); 193 varString = variable.asString(); 194 return varString; 195 } catch (IllegalArgumentException e) { 196 System.out.println("Undefined variable: " + varName); 197 return ""; 198 } 199 } 200 201 224 private static void setupColumnWidths(Context context) { 225 nominalWidth = 6 * pixelsPerInch; 227 tableWidth = "100%"; 228 229 String varString = null; 230 231 try { 232 varString = getVariable(context, "stylesheet.result.type"); 234 foStylesheet = varString.equals("fo"); 235 236 varString = getVariable(context, "nominal.table.width"); 238 nominalWidth = convertLength(varString); 239 240 varString = getVariable(context, "table.width"); 242 tableWidth = varString; 243 } catch (TransformerException e) { 244 } 246 } 247 248 295 public static NodeSetValue adjustColumnWidths (Context context, 296 NodeSetValue rtf_ns) { 297 298 FragmentValue rtf = (FragmentValue) rtf_ns; 299 300 setupColumnWidths(context); 301 302 try { 303 Controller controller = context.getController(); 304 NamePool namePool = controller.getNamePool(); 305 306 ColumnScanEmitter csEmitter = new ColumnScanEmitter(namePool); 307 rtf.replay(csEmitter); 308 309 int numColumns = csEmitter.columnCount(); 310 String widths[] = csEmitter.columnWidths(); 311 312 float relTotal = 0; 313 float relParts[] = new float[numColumns]; 314 315 float absTotal = 0; 316 float absParts[] = new float[numColumns]; 317 318 for (int count = 0; count < numColumns; count++) { 319 String width = widths[count]; 320 321 int pos = width.indexOf("*"); 322 if (pos >= 0) { 323 String relPart = width.substring(0, pos); 324 String absPart = width.substring(pos+1); 325 326 try { 327 float rel = Float.parseFloat(relPart); 328 relTotal += rel; 329 relParts[count] = rel; 330 } catch (NumberFormatException e) { 331 System.out.println(relPart + " is not a valid relative unit."); 332 } 333 334 int pixels = 0; 335 if (absPart != null && !absPart.equals("")) { 336 pixels = convertLength(absPart); 337 } 338 339 absTotal += pixels; 340 absParts[count] = pixels; 341 } else { 342 relParts[count] = 0; 343 344 int pixels = 0; 345 if (width != null && !width.equals("")) { 346 pixels = convertLength(width); 347 } 348 349 absTotal += pixels; 350 absParts[count] = pixels; 351 } 352 } 353 354 366 if (relTotal == 0) { 367 for (int count = 0; count < numColumns; count++) { 368 Float f = new Float (absParts[count]); 369 if (foStylesheet) { 370 int pixels = f.intValue(); 371 float inches = (float) pixels / pixelsPerInch; 372 widths[count] = inches + "in"; 373 } else { 374 widths[count] = Integer.toString(f.intValue()); 375 } 376 } 377 } else if (absTotal == 0) { 378 for (int count = 0; count < numColumns; count++) { 379 float rel = relParts[count] / relTotal * 100; 380 Float f = new Float (rel); 381 widths[count] = Integer.toString(f.intValue()); 382 } 383 widths = correctRoundingError(widths); 384 } else { 385 int pixelWidth = nominalWidth; 386 387 if (tableWidth.indexOf("%") <= 0) { 388 pixelWidth = convertLength(tableWidth); 389 } 390 391 if (pixelWidth <= absTotal) { 392 System.out.println("Table is wider than table width."); 393 } else { 394 pixelWidth -= absTotal; 395 } 396 397 absTotal = 0; 398 for (int count = 0; count < numColumns; count++) { 399 float rel = relParts[count] / relTotal * pixelWidth; 400 relParts[count] = rel + absParts[count]; 401 absTotal += rel + absParts[count]; 402 } 403 404 if (tableWidth.indexOf("%") <= 0) { 405 for (int count = 0; count < numColumns; count++) { 406 Float f = new Float (relParts[count]); 407 if (foStylesheet) { 408 int pixels = f.intValue(); 409 float inches = (float) pixels / pixelsPerInch; 410 widths[count] = inches + "in"; 411 } else { 412 widths[count] = Integer.toString(f.intValue()); 413 } 414 } 415 } else { 416 for (int count = 0; count < numColumns; count++) { 417 float rel = relParts[count] / absTotal * 100; 418 Float f = new Float (rel); 419 widths[count] = Integer.toString(f.intValue()); 420 } 421 widths = correctRoundingError(widths); 422 } 423 } 424 425 ColumnUpdateEmitter cuEmitter = new ColumnUpdateEmitter(controller, 426 namePool, 427 widths); 428 429 rtf.replay(cuEmitter); 430 return cuEmitter.getResultTreeFragment(); 431 } catch (TransformerException e) { 432 System.out.println("Transformer Exception in adjustColumnWidths"); 434 return rtf; 435 } 436 } 437 438 442 protected static String [] correctRoundingError(String widths[]) { 443 int totalWidth = 0; 444 445 for (int count = 0; count < widths.length; count++) { 446 try { 447 int width = Integer.parseInt(widths[count]); 448 totalWidth += width; 449 } catch (NumberFormatException nfe) { 450 } 452 } 453 454 float totalError = 100 - totalWidth; 455 float columnError = totalError / widths.length; 456 float error = 0; 457 458 for (int count = 0; count < widths.length; count++) { 459 try { 460 int width = Integer.parseInt(widths[count]); 461 error = error + columnError; 462 if (error >= 1.0) { 463 int adj = (int) Math.round(Math.floor(error)); 464 error = error - (float) Math.floor(error); 465 width = width + adj; 466 widths[count] = Integer.toString(width) + "%"; 467 } else { 468 widths[count] = Integer.toString(width) + "%"; 469 } 470 } catch (NumberFormatException nfe) { 471 } 473 } 474 475 return widths; 476 } 477 } 478 | Popular Tags |