handle lists when ipd changes due to a float
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_BasicSideFloats@1637403 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/java/org/apache/fop/layoutmgr/PageBreaker.java b/src/java/org/apache/fop/layoutmgr/PageBreaker.java
index aa1e250..206aac8 100644
--- a/src/java/org/apache/fop/layoutmgr/PageBreaker.java
+++ b/src/java/org/apache/fop/layoutmgr/PageBreaker.java
@@ -36,6 +36,7 @@
import org.apache.fop.fo.pagination.StaticContent;
import org.apache.fop.layoutmgr.BreakingAlgorithm.KnuthNode;
import org.apache.fop.layoutmgr.PageBreakingAlgorithm.PageBreakingLayoutListener;
+import org.apache.fop.layoutmgr.list.ListItemLayoutManager;
import org.apache.fop.traits.MinOptMax;
/**
@@ -685,19 +686,23 @@
blockListIndex = -1;
LayoutManager restartAtLM = null;
if (positionAtBreak != null && positionAtBreak.getIndex() == -1) {
- Position position;
- Iterator iter = blockList.listIterator(floatPosition + 1);
- do {
- KnuthElement nextElement = (KnuthElement) iter.next();
- position = nextElement.getPosition();
- } while (position == null || position instanceof SpaceResolver.SpaceHandlingPosition
- || position instanceof SpaceResolver.SpaceHandlingBreakPosition
- && position.getPosition().getIndex() == -1);
- LayoutManager surroundingLM = positionAtBreak.getLM();
- while (position.getLM() != surroundingLM) {
- position = position.getPosition();
+ if (positionAtBreak instanceof ListItemLayoutManager.ListItemPosition) {
+ restartAtLM = positionAtBreak.getLM();
+ } else {
+ Position position;
+ Iterator iter = blockList.listIterator(floatPosition + 1);
+ do {
+ KnuthElement nextElement = (KnuthElement) iter.next();
+ position = nextElement.getPosition();
+ } while (position == null || position instanceof SpaceResolver.SpaceHandlingPosition
+ || position instanceof SpaceResolver.SpaceHandlingBreakPosition
+ && position.getPosition().getIndex() == -1);
+ LayoutManager surroundingLM = positionAtBreak.getLM();
+ while (position.getLM() != surroundingLM) {
+ position = position.getPosition();
+ }
+ restartAtLM = position.getPosition().getLM();
}
- restartAtLM = position.getPosition().getLM();
}
int nextSequenceStartsOn = getNextBlockList(childLC, Constants.EN_COLUMN, positionAtBreak,
restartAtLM, firstElements);
diff --git a/src/java/org/apache/fop/layoutmgr/SpaceResolver.java b/src/java/org/apache/fop/layoutmgr/SpaceResolver.java
index 31bdaeb..551e7d3 100644
--- a/src/java/org/apache/fop/layoutmgr/SpaceResolver.java
+++ b/src/java/org/apache/fop/layoutmgr/SpaceResolver.java
@@ -696,7 +696,7 @@
beforeBreak.notifyBreakSituation(true, RelSide.BEFORE);
}
}
- el = (KnuthElement)effectiveList.get(endElementIndex);
+ el = endElementIndex > -1 ? (KnuthElement) effectiveList.get(endElementIndex) : null;
if (el != null && el.isPenalty()) {
Position pos = el.getPosition();
if (pos instanceof SpaceResolver.SpaceHandlingBreakPosition) {
diff --git a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
index 062a67b..a0af4fd 100644
--- a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
@@ -21,6 +21,7 @@
import java.util.LinkedList;
import java.util.List;
+import java.util.Stack;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -95,10 +96,11 @@
}
/** {@inheritDoc} */
- @Override
- public List getNextKnuthElements(LayoutContext context, int alignment) {
+ public List getNextKnuthElements(LayoutContext context, int alignment, Stack lmStack,
+ Position restartPosition, LayoutManager restartAtLM) {
resetSpaces();
- List returnList = super.getNextKnuthElements(context, alignment);
+ List returnList;
+ returnList = super.getNextKnuthElements(context, alignment, lmStack, restartPosition, restartAtLM);
//fox:widow-content-limit
int widowRowLimit = getListBlockFO().getWidowContentLimit().getValue();
diff --git a/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java
index 108402c..214ba62 100644
--- a/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java
@@ -21,6 +21,7 @@
import java.util.LinkedList;
import java.util.List;
+import java.util.Stack;
import org.apache.fop.area.Area;
import org.apache.fop.area.Block;
@@ -225,15 +226,15 @@
return Keep.KEEP_AUTO;
}
- @SuppressWarnings("unchecked")
- @Override
- public List<ListElement> getNextKnuthElements(LayoutContext context, int alignment) {
+ /** {@inheritDoc} */
+ public List getNextKnuthElements(LayoutContext context, int alignment, Stack lmStack,
+ Position restartPosition, LayoutManager restartAtLM) {
List<ListElement> elements = new LinkedList<ListElement>();
do {
- elements.addAll(super.getNextKnuthElements(context, alignment));
+ elements.addAll(super.getNextKnuthElements(context, alignment, lmStack, restartPosition,
+ restartAtLM));
} while (!isFinished());
return elements;
}
-
}
diff --git a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
index 6404e9f..ce9746b 100644
--- a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
@@ -23,6 +23,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
+import java.util.Stack;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -79,11 +80,13 @@
private Keep keepWithNextPendingOnLabel;
private Keep keepWithNextPendingOnBody;
- private class ListItemPosition extends Position {
+ public class ListItemPosition extends Position {
private int labelFirstIndex;
private int labelLastIndex;
private int bodyFirstIndex;
private int bodyLastIndex;
+ private Position originalLabelPosition;
+ private Position originalBodyPosition;
public ListItemPosition(LayoutManager lm, int labelFirst, int labelLast,
int bodyFirst, int bodyLast) {
@@ -124,6 +127,22 @@
sb.append(")");
return sb.toString();
}
+
+ public Position getOriginalLabelPosition() {
+ return originalLabelPosition;
+ }
+
+ public void setOriginalLabelPosition(Position originalLabelPosition) {
+ this.originalLabelPosition = originalLabelPosition;
+ }
+
+ public Position getOriginalBodyPosition() {
+ return originalBodyPosition;
+ }
+
+ public void setOriginalBodyPosition(Position originalBodyPosition) {
+ this.originalBodyPosition = originalBodyPosition;
+ }
}
/**
@@ -188,8 +207,8 @@
}
/** {@inheritDoc} */
- @Override
- public List getNextKnuthElements(LayoutContext context, int alignment) {
+ public List getNextKnuthElements(LayoutContext context, int alignment, Stack lmStack,
+ Position restartPosition, LayoutManager restartAtLM) {
referenceIPD = context.getRefIPD();
LayoutContext childLC;
@@ -205,7 +224,30 @@
childLC = makeChildLayoutContext(context);
childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE);
label.initialize();
- labelList = label.getNextKnuthElements(childLC, alignment);
+ boolean labelDone = false;
+ Stack labelLMStack = null;
+ Position labelRestartPosition = null;
+ LayoutManager labelRestartLM = null;
+ if (restartPosition != null && restartPosition instanceof ListItemPosition) {
+ ListItemPosition lip = (ListItemPosition) restartPosition;
+ if (lip.labelLastIndex <= lip.labelFirstIndex) {
+ labelDone = true;
+ } else {
+ labelRestartPosition = lip.getOriginalLabelPosition();
+ labelRestartLM = labelRestartPosition.getLM();
+ LayoutManager lm = labelRestartLM;
+ labelLMStack = new Stack();
+ while (lm != this) {
+ labelLMStack.push(lm);
+ lm = lm.getParent();
+ if (lm instanceof ListItemContentLayoutManager) {
+ lm = lm.getParent();
+ }
+ }
+ }
+ }
+ labelList = !labelDone ? label.getNextKnuthElements(childLC, alignment, labelLMStack,
+ labelRestartPosition, labelRestartLM) : new LinkedList<KnuthElement>();
//Space resolution as if the contents were placed in a new reference area
//(see 6.8.3, XSL 1.0, section on Constraints, last paragraph)
@@ -219,7 +261,30 @@
childLC = makeChildLayoutContext(context);
childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE);
body.initialize();
- bodyList = body.getNextKnuthElements(childLC, alignment);
+ boolean bodyDone = false;
+ Stack bodyLMStack = null;
+ Position bodyRestartPosition = null;
+ LayoutManager bodyRestartLM = null;
+ if (restartPosition != null && restartPosition instanceof ListItemPosition) {
+ ListItemPosition lip = (ListItemPosition) restartPosition;
+ if (lip.bodyLastIndex <= lip.bodyFirstIndex) {
+ bodyDone = true;
+ } else {
+ bodyRestartPosition = lip.getOriginalBodyPosition();
+ bodyRestartLM = bodyRestartPosition.getLM();
+ LayoutManager lm = bodyRestartLM;
+ bodyLMStack = new Stack();
+ while (lm != this) {
+ bodyLMStack.push(lm);
+ lm = lm.getParent();
+ if (lm instanceof ListItemContentLayoutManager) {
+ lm = lm.getParent();
+ }
+ }
+ }
+ }
+ bodyList = !bodyDone ? body.getNextKnuthElements(childLC, alignment, bodyLMStack,
+ bodyRestartPosition, bodyRestartLM) : new LinkedList<KnuthElement>();
//Space resolution as if the contents were placed in a new reference area
//(see 6.8.3, XSL 1.0, section on Constraints, last paragraph)
@@ -298,7 +363,9 @@
int additionalPenaltyHeight = 0;
int stepPenalty = 0;
int breakClass = EN_AUTO;
- KnuthElement endEl = (KnuthElement)elementLists[0].get(end[0]);
+ KnuthElement endEl = elementLists[0].size() > 0 ? (KnuthElement) elementLists[0].get(end[0])
+ : null;
+ Position originalLabelPosition = endEl != null ? endEl.getPosition().getPosition() : null;
if (endEl instanceof KnuthPenalty) {
additionalPenaltyHeight = endEl.getWidth();
stepPenalty = endEl.getPenalty() == -KnuthElement.INFINITE ? -KnuthElement.INFINITE : Math
@@ -306,7 +373,8 @@
breakClass = BreakUtil.compareBreakClasses(breakClass,
((KnuthPenalty) endEl).getBreakClass());
}
- endEl = (KnuthElement)elementLists[1].get(end[1]);
+ endEl = elementLists[1].size() > 0 ? (KnuthElement) elementLists[1].get(end[1]) : null;
+ Position originalBodyPosition = endEl != null ? endEl.getPosition().getPosition() : null;
if (endEl instanceof KnuthPenalty) {
additionalPenaltyHeight = Math.max(
additionalPenaltyHeight, endEl.getWidth());
@@ -329,8 +397,9 @@
// add the new elements
addedBoxHeight += boxHeight;
- ListItemPosition stepPosition = new ListItemPosition(this,
- start[0], end[0], start[1], end[1]);
+ ListItemPosition stepPosition = new ListItemPosition(this, start[0], end[0], start[1], end[1]);
+ stepPosition.setOriginalLabelPosition(originalLabelPosition);
+ stepPosition.setOriginalBodyPosition(originalBodyPosition);
if (footnoteList.isEmpty()) {
returnList.add(new KnuthBox(boxHeight, stepPosition, false));
} else {
@@ -673,6 +742,5 @@
breakBefore = BreakUtil.compareBreakClasses(breakBefore, body.getBreakBefore());
return breakBefore;
}
-
}
diff --git a/test/layoutengine/standard-testcases/float_5.xml b/test/layoutengine/standard-testcases/float_5.xml
new file mode 100644
index 0000000..e43d9d6
--- /dev/null
+++ b/test/layoutengine/standard-testcases/float_5.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id$ -->
+<testcase>
+ <info>
+ <p>
+ This test checks floats.
+ </p>
+ </info>
+ <fo>
+<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master margin="0.25in" master-name="page" page-height="11in" page-width="8.5in">
+ <fo:region-body />
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>
+Did you know... (taken from Wikipedia main page on November 6th, 2014, with the order slightly changed to better show the wrapping around the float)
+ </fo:block>
+ <fo:block>
+From Wikipedia's new and recently improved content:
+ </fo:block>
+ <fo:block>
+ <fo:float float="end">
+ <fo:block border="1pt solid red" padding="5pt" end-indent="0pt" start-indent="0pt">
+ <fo:block-container inline-progression-dimension="120pt">
+ <fo:block background-color="yellow">
+The former dean's house at the University of Wisconsin (this is the alt text of the image in the Wikipedia page)
+ </fo:block>
+ </fo:block-container>
+ </fo:block>
+ </fo:float>
+ </fo:block>
+ <fo:block>
+ <fo:list-block>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>
+... that the Queen Anne house (pictured) at the Allen Centennial Gardens was home to four deans of the University of Wisconsin–Madison College of Agricultural and Life Sciences?
+ </fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>
+... that rhapsodomancy was so vague, Virgil wrote against it in The Aeneid?
+ </fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>
+... that Australian physician Claudia Burton Bradley was one of the first diabetics to be treated with insulin?
+ </fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>
+... that Green Bay Packers offensive lineman David Bakhtiari was the first rookie in Packers history to start every game at left tackle in a season since the start of the 16-game season?
+ </fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>
+... that in the Byzantine Empire, the office of orphanotrophos, head of the imperial orphanage, ranked among the higher offices of state?
+ </fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>
+... that the stream Shingle Run is actually named after sawmills?
+ </fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>
+... that while testifying in a 2004 lawsuit involving the meaning of the word steakburger, a corporate CEO was grilled on the witness stand?
+ </fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ </fo:list-block>
+ </fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+</fo:root>
+ </fo>
+ <checks>
+ <!-- first float -->
+ <eval expected="450000" xpath="//pageViewport[1]/page/regionViewport[1]//flow[1]/block[4]/@left-offset" />
+ <eval expected="... that the Queen Anne house (pictured) at the Allen Centennial Gardens" xpath="//pageViewport[1]/page/regionViewport[1]//flow[1]/block[6]/block[1]/block[1]/block[2]/block[1]/lineArea[1]" />
+ <eval expected="... that Green Bay Packers offensive lineman David Bakhtiari was the first" xpath="//pageViewport[1]/page/regionViewport[1]//flow[1]/block[6]/block[1]/block[4]/block[2]/block[1]/lineArea[1]" />
+ <eval expected="rookie in Packers history to start every game at left tackle in a season since the start of the 16-game" xpath="//pageViewport[1]/page/regionViewport[1]//flow[1]/block[7]/block[1]/block[1]/block[1]/block[1]/lineArea[1]" />
+ </checks>
+</testcase>
+
+