From 36aa27625696174dd70c88a44bbcc09724d57643 Mon Sep 17 00:00:00 2001 From: Luca Furini Date: Thu, 6 Oct 2005 14:52:14 +0000 Subject: [PATCH] Fixing a bug reported by Jeremias affecting the handling of glue and penalty elements after a break when the algorithm restarts. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@306656 13f79535-47bb-0310-9956-ffa450edef68 --- .../fop/layoutmgr/BreakingAlgorithm.java | 48 +++++++++++++++++-- .../fop/layoutmgr/PageBreakingAlgorithm.java | 5 +- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java b/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java index c689e37a3..da5caeb7f 100644 --- a/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java +++ b/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java @@ -434,8 +434,7 @@ public abstract class BreakingAlgorithm { } log.debug("Restarting at node " + lastForced); - restartFrom(lastForced, i); - i = lastForced.position; + i = restartFrom(lastForced, i); } } finish(); @@ -487,7 +486,7 @@ public abstract class BreakingAlgorithm { protected void handleBox(KnuthBox box) { } - protected void restartFrom(KnuthNode restartingNode, int currentIndex) { + protected int restartFrom(KnuthNode restartingNode, int currentIndex) { restartingNode.totalDemerits = 0; addNode(restartingNode.line, restartingNode); startLine = restartingNode.line; @@ -496,6 +495,16 @@ public abstract class BreakingAlgorithm { totalStretch = restartingNode.totalStretch; totalShrink = restartingNode.totalShrink; lastTooShort = lastTooLong = null; + // the width, stretch and shrink already include the width, + // stretch and shrink of the suppressed glues; + // advance in the sequence in order to avoid taking into account + // these elements twice + int restartingIndex = restartingNode.position; + while (restartingIndex + 1 < par.size() + && !(getElement(restartingIndex + 1).isBox())) { + restartingIndex ++; + } + return restartingIndex; } protected void considerLegalBreak(KnuthElement element, int elementIdx) { @@ -554,10 +563,33 @@ public abstract class BreakingAlgorithm { if (force && (r <= -1 || r > threshold)) { int fitnessClass = computeFitness(r); double demerits = computeDemerits(node, element, fitnessClass, r); + int newWidth = totalWidth; + int newStretch = totalStretch; + int newShrink = totalShrink; + + // add the width, stretch and shrink of glue elements after + // the break + // this does not affect the dimension of the line / page, only + // the values stored in the node; these would be as if the break + // was just before the next box element, thus ignoring glues and + // penalties between the "real" break and the following box + for (int i = elementIdx; i < par.size(); i++) { + KnuthElement tempElement = getElement(i); + if (tempElement.isBox()) { + break; + } else if (tempElement.isGlue()) { + newWidth += tempElement.getW(); + newStretch += tempElement.getY(); + newShrink += tempElement.getZ(); + } else if (tempElement.isForcedBreak() && i != elementIdx) { + break; + } + } + if (r <= -1) { if (lastTooLong == null || demerits < lastTooLong.totalDemerits) { lastTooLong = createNode(elementIdx, line + 1, fitnessClass, - totalWidth, totalStretch, totalShrink, + newWidth, newStretch, newShrink, r, availableShrink, availableStretch, difference, demerits, node); if (log.isTraceEnabled()) { @@ -573,7 +605,7 @@ public abstract class BreakingAlgorithm { difference, fitnessClass); } lastTooShort = createNode(elementIdx, line + 1, fitnessClass, - totalWidth, totalStretch, totalShrink, + newWidth, newStretch, newShrink, r, availableShrink, availableStretch, difference, demerits, node); if (log.isTraceEnabled()) { @@ -596,6 +628,12 @@ public abstract class BreakingAlgorithm { int newStretch = totalStretch; int newShrink = totalShrink; + // add the width, stretch and shrink of glue elements after + // the break + // this does not affect the dimension of the line / page, only + // the values stored in the node; these would be as if the break + // was just before the next box element, thus ignoring glues and + // penalties between the "real" break and the following box for (int i = elementIdx; i < par.size(); i++) { KnuthElement tempElement = getElement(i); if (tempElement.isBox()) { diff --git a/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java b/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java index 6a974ab15..507e2a384 100644 --- a/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java +++ b/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java @@ -216,8 +216,8 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { } } - protected void restartFrom(KnuthNode restartingNode, int currentIndex) { - super.restartFrom(restartingNode, currentIndex); + protected int restartFrom(KnuthNode restartingNode, int currentIndex) { + int returnValue = super.restartFrom(restartingNode, currentIndex); newFootnotes = false; if (footnotesPending) { // remove from footnotesList the note lists that will be met @@ -230,6 +230,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { } } } + return returnValue; } private void resetFootnotes(LinkedList elementLists) { -- 2.39.5