From e8a9c7bf0a1ef4429ebe7a3a6dbac41c2bc583da Mon Sep 17 00:00:00 2001 From: Norman Walsh Date: Fri, 15 Nov 2002 13:50:53 +0000 Subject: [PATCH] Correct rounding errors in column percentage width calculation --- .../saxon643/com/nwalsh/saxon/Table.java | 46 ++++++++++++++++++- .../xalan2/com/nwalsh/xalan/Table.java | 46 ++++++++++++++++++- 2 files changed, 88 insertions(+), 4 deletions(-) diff --git a/xsl/extensions/saxon643/com/nwalsh/saxon/Table.java b/xsl/extensions/saxon643/com/nwalsh/saxon/Table.java index cd9add142..c49632a1e 100644 --- a/xsl/extensions/saxon643/com/nwalsh/saxon/Table.java +++ b/xsl/extensions/saxon643/com/nwalsh/saxon/Table.java @@ -378,8 +378,9 @@ public class Table { 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[count] = Integer.toString(f.intValue()); } + widths = correctRoundingError(widths); } else { int pixelWidth = nominalWidth; @@ -415,8 +416,9 @@ public class Table { 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[count] = Integer.toString(f.intValue()); } + widths = correctRoundingError(widths); } } @@ -432,4 +434,44 @@ public class Table { return rtf; } } + + /** + * Correct rounding errors introduced in calculating the width of each + * column. Make sure they sum to 100% in the end. + */ + protected static String[] correctRoundingError(String widths[]) { + int totalWidth = 0; + + for (int count = 0; count < widths.length; count++) { + try { + int width = Integer.parseInt(widths[count]); + totalWidth += width; + } catch (NumberFormatException nfe) { + // nop; "can't happen" + } + } + + float totalError = 100 - totalWidth; + float columnError = totalError / widths.length; + float error = 0; + + for (int count = 0; count < widths.length; count++) { + try { + int width = Integer.parseInt(widths[count]); + error = error + columnError; + if (error >= 1.0) { + int adj = (int) Math.round(Math.floor(error)); + error = error - (float) Math.floor(error); + width = width + adj; + widths[count] = Integer.toString(width) + "%"; + } else { + widths[count] = Integer.toString(width) + "%"; + } + } catch (NumberFormatException nfe) { + // nop; "can't happen" + } + } + + return widths; + } } diff --git a/xsl/extensions/xalan2/com/nwalsh/xalan/Table.java b/xsl/extensions/xalan2/com/nwalsh/xalan/Table.java index bad7039e2..58b4d0b59 100644 --- a/xsl/extensions/xalan2/com/nwalsh/xalan/Table.java +++ b/xsl/extensions/xalan2/com/nwalsh/xalan/Table.java @@ -357,8 +357,9 @@ public class Table { 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[count] = Integer.toString(f.intValue()); } + widths = correctRoundingError(widths); } else { int pixelWidth = nominalWidth; @@ -394,8 +395,9 @@ public class Table { 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[count] = Integer.toString(f.intValue()); } + widths = correctRoundingError(widths); } } @@ -486,4 +488,44 @@ public class Table { } return attrs; } + + /** + * Correct rounding errors introduced in calculating the width of each + * column. Make sure they sum to 100% in the end. + */ + protected String[] correctRoundingError(String widths[]) { + int totalWidth = 0; + + for (int count = 0; count < widths.length; count++) { + try { + int width = Integer.parseInt(widths[count]); + totalWidth += width; + } catch (NumberFormatException nfe) { + // nop; "can't happen" + } + } + + float totalError = 100 - totalWidth; + float columnError = totalError / widths.length; + float error = 0; + + for (int count = 0; count < widths.length; count++) { + try { + int width = Integer.parseInt(widths[count]); + error = error + columnError; + if (error >= 1.0) { + int adj = (int) Math.round(Math.floor(error)); + error = error - (float) Math.floor(error); + width = width + adj; + widths[count] = Integer.toString(width) + "%"; + } else { + widths[count] = Integer.toString(width) + "%"; + } + } catch (NumberFormatException nfe) { + // nop; "can't happen" + } + } + + return widths; + } } -- 2.50.1