]> granicus.if.org Git - docbook-dsssl/commitdiff
Correct rounding errors in column percentage width calculation
authorNorman Walsh <ndw@nwalsh.com>
Fri, 15 Nov 2002 13:50:53 +0000 (13:50 +0000)
committerNorman Walsh <ndw@nwalsh.com>
Fri, 15 Nov 2002 13:50:53 +0000 (13:50 +0000)
xsl/extensions/saxon643/com/nwalsh/saxon/Table.java
xsl/extensions/xalan2/com/nwalsh/xalan/Table.java

index cd9add142d429c24d9c4c61b39dcbf2e24b7fd5f..c49632a1e7981904c117c53996d7ce7c6bb0de29 100644 (file)
@@ -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;
+  }
 }
index bad7039e285c7df3fc5a73c87ba724176bd6e47b..58b4d0b596b2f0fa6f6dcd2d620534367f205033 100644 (file)
@@ -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;
+  }
 }