diff options
Diffstat (limited to 'src/java/org/apache/fop/layoutmgr/SpaceResolver.java')
-rw-r--r-- | src/java/org/apache/fop/layoutmgr/SpaceResolver.java | 110 |
1 files changed, 74 insertions, 36 deletions
diff --git a/src/java/org/apache/fop/layoutmgr/SpaceResolver.java b/src/java/org/apache/fop/layoutmgr/SpaceResolver.java index 49e416119..45e9990ea 100644 --- a/src/java/org/apache/fop/layoutmgr/SpaceResolver.java +++ b/src/java/org/apache/fop/layoutmgr/SpaceResolver.java @@ -18,6 +18,7 @@ package org.apache.fop.layoutmgr; +import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -74,9 +75,9 @@ public class SpaceResolver { int i = 0; ListIterator iter; if (first != null) { - iter = first.listIterator(first.size()); - while (iter.hasPrevious()) { - noBreak[i] = (UnresolvedListElementWithLength)iter.previous(); + iter = first.listIterator(); + while (iter.hasNext()) { + noBreak[i] = (UnresolvedListElementWithLength)iter.next(); noBreakLengths[i] = noBreak[i].getLength(); i++; } @@ -152,15 +153,21 @@ public class SpaceResolver { } private void removeConditionalBorderAndPadding( - UnresolvedListElement[] elems, MinOptMax[] lengths) { + UnresolvedListElement[] elems, MinOptMax[] lengths, boolean reverse) { for (int i = 0; i < elems.length; i++) { - if (elems[i] instanceof BorderOrPaddingElement) { - BorderOrPaddingElement bop = (BorderOrPaddingElement)elems[i]; + int effIndex; + if (reverse) { + effIndex = elems.length - 1 - i; + } else { + effIndex = i; + } + if (elems[effIndex] instanceof BorderOrPaddingElement) { + BorderOrPaddingElement bop = (BorderOrPaddingElement)elems[effIndex]; if (bop.isConditional() && !(bop.isFirst() || bop.isLast())) { if (log.isDebugEnabled()) { log.debug("Nulling conditional element: " + bop); } - lengths[i] = null; + lengths[effIndex] = null; } } } @@ -169,21 +176,28 @@ public class SpaceResolver { } } - private void performSpaceResolutionRule1(UnresolvedListElement[] elems, MinOptMax[] lengths) { + private void performSpaceResolutionRule1(UnresolvedListElement[] elems, MinOptMax[] lengths, + boolean reverse) { for (int i = 0; i < elems.length; i++) { - if (lengths[i] == null) { + int effIndex; + if (reverse) { + effIndex = elems.length - 1 - i; + } else { + effIndex = i; + } + if (lengths[effIndex] == null) { //Zeroed border or padding doesn't create a fence continue; - } else if (elems[i] instanceof BorderOrPaddingElement) { + } else if (elems[effIndex] instanceof BorderOrPaddingElement) { //Border or padding form fences! break; - } else if (!elems[i].isConditional()) { + } else if (!elems[effIndex].isConditional()) { break; } if (log.isDebugEnabled()) { - log.debug("Nulling conditional element using 4.3.1, rule 1: " + elems[i]); + log.debug("Nulling conditional element using 4.3.1, rule 1: " + elems[effIndex]); } - lengths[i] = null; + lengths[effIndex] = null; } if (log.isTraceEnabled() && elems.length > 0) { log.trace("-->Resulting list: " + toString(elems, lengths)); @@ -341,24 +355,55 @@ public class SpaceResolver { } } + private boolean hasFirstPart() { + return firstPart != null && firstPart.length > 0; + } + + private boolean hasSecondPart() { + return secondPart != null && secondPart.length > 0; + } + private void resolve() { if (breakPoss != null) { - if (firstPart != null) { - removeConditionalBorderAndPadding(firstPart, firstPartLengths); - performSpaceResolutionRule1(firstPart, firstPartLengths); + if (hasFirstPart()) { + removeConditionalBorderAndPadding(firstPart, firstPartLengths, true); + performSpaceResolutionRule1(firstPart, firstPartLengths, true); performSpaceResolutionRules2to3(firstPart, firstPartLengths); } - if (secondPart != null) { - removeConditionalBorderAndPadding(secondPart, secondPartLengths); - performSpaceResolutionRule1(secondPart, secondPartLengths); + if (hasSecondPart()) { + removeConditionalBorderAndPadding(secondPart, secondPartLengths, false); + performSpaceResolutionRule1(secondPart, secondPartLengths, false); performSpaceResolutionRules2to3(secondPart, secondPartLengths); } if (noBreak != null) { performSpaceResolutionRules2to3(noBreak, noBreakLengths); } } else { - if (isFirst || isLast) { - performSpaceResolutionRule1(secondPart, secondPartLengths); + if (isFirst) { + removeConditionalBorderAndPadding(secondPart, secondPartLengths, false); + performSpaceResolutionRule1(secondPart, secondPartLengths, false); + } + if (isLast) { + removeConditionalBorderAndPadding(firstPart, firstPartLengths, true); + performSpaceResolutionRule1(firstPart, firstPartLengths, true); + } + + if (hasFirstPart()) { + //Now that we've handled isFirst/isLast conditions, we need to look at the + //active part in its normal order so swap it back. + log.trace("Swapping first and second parts."); + UnresolvedListElementWithLength[] tempList; + MinOptMax[] tempLengths; + tempList = secondPart; + tempLengths = secondPartLengths; + secondPart = firstPart; + secondPartLengths = firstPartLengths; + firstPart = tempList; + firstPartLengths = tempLengths; + if (hasFirstPart()) { + throw new IllegalStateException("Didn't expect more than one parts in a" + + "no-break condition."); + } } performSpaceResolutionRules2to3(secondPart, secondPartLengths); } @@ -396,7 +441,7 @@ public class SpaceResolver { glue2shrink -= glue1.opt - glue1.min; glue2shrink -= glue3.opt - glue3.min; - + boolean hasPrecedingNonBlock = false; if (log.isDebugEnabled()) { log.debug("noBreakLength=" + noBreakLength + ", glue1=" + glue1 @@ -439,8 +484,9 @@ public class SpaceResolver { false, (Position)null, true)); iter.add(new KnuthGlue(glue3.opt, glue3.max - glue3.opt, glue3.opt - glue3.min, (Position)null, true)); + hasPrecedingNonBlock = true; } - if (isLast) { + if (isLast && hasPrecedingNonBlock) { //Otherwise, the preceding penalty and glue will be cut off iter.add(new KnuthBox(0, (Position)null, true)); } @@ -494,9 +540,7 @@ public class SpaceResolver { } } else { for (int i = 0; i < resolver.noBreak.length; i++) { - if (resolver.noBreak[i] instanceof SpaceElement) { - resolver.noBreak[i].notifyLayoutManager(resolver.noBreakLengths[i]); - } + resolver.noBreak[i].notifyLayoutManager(resolver.noBreakLengths[i]); } } } @@ -550,9 +594,7 @@ public class SpaceResolver { throw new IllegalStateException("Only applicable to no-break situations"); } for (int i = 0; i < resolver.secondPart.length; i++) { - if (resolver.secondPart[i] instanceof SpaceElement) { - resolver.secondPart[i].notifyLayoutManager(resolver.secondPartLengths[i]); - } + resolver.secondPart[i].notifyLayoutManager(resolver.secondPartLengths[i]); } } @@ -619,18 +661,14 @@ public class SpaceResolver { } } //last = !iter.hasNext(); - if (breakPoss == null & unresolvedSecond.size() == 0) { + if (breakPoss == null && unresolvedSecond.size() == 0 && !last) { + log.trace("Swap first and second parts in no-break condition," + + " second part is empty."); //The first list is reversed, so swap if this shouldn't happen List swapList = unresolvedSecond; unresolvedSecond = unresolvedFirst; unresolvedFirst = swapList; } - //Need to reverse the order of the first part - //From here on further down, the first part in the unresolved list is - //always the one nearest to the break. - if (unresolvedFirst.size() > 0) { - Collections.reverse(unresolvedFirst); - } log.debug("----start space resolution (first=" + first + ", last=" + last + ")..."); SpaceResolver resolver = new SpaceResolver( |