summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/java/org/apache/fop/layoutmgr/BestFitLayoutUtils.java12
-rw-r--r--src/java/org/apache/fop/layoutmgr/BestFitPenalty.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/MultiCaseLayoutManager.java32
-rw-r--r--src/java/org/apache/fop/layoutmgr/MultiSwitchLayoutManager.java58
-rw-r--r--src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java27
-rw-r--r--test/layoutengine/standard-testcases/multi-switch_best-fit_multiple-variants.xml11
6 files changed, 33 insertions, 109 deletions
diff --git a/src/java/org/apache/fop/layoutmgr/BestFitLayoutUtils.java b/src/java/org/apache/fop/layoutmgr/BestFitLayoutUtils.java
index c59c9d607..148a83eba 100644
--- a/src/java/org/apache/fop/layoutmgr/BestFitLayoutUtils.java
+++ b/src/java/org/apache/fop/layoutmgr/BestFitLayoutUtils.java
@@ -40,10 +40,12 @@ public final class BestFitLayoutUtils {
public List<Position> getPositionList() {
List<Position> positions = new LinkedList<Position>();
- if (knuthList != null) {
+ if (knuthList != null && !knuthList.isEmpty()) {
SpaceResolver.performConditionalsNotification(knuthList, 0, knuthList.size() - 1, -1);
- for (ListElement elem : knuthList) {
- positions.add(elem.getPosition());
+ for (ListElement el : knuthList) {
+ if (el.getPosition() != null) {
+ positions.add(el.getPosition());
+ }
}
}
return positions;
@@ -75,10 +77,6 @@ public final class BestFitLayoutUtils {
// when they are at the end of the Knuth list.
knuthList.add(new KnuthBox(0, new Position(lm), false));
knuthList.add(bestFitPenalty);
- Variant firstVariant = bestFitPenalty.getVariants().get(0);
- BestFitPosition pos = new BestFitPosition(lm);
- pos.setKnuthList(firstVariant.knuthList);
- knuthList.add(new KnuthGlue(firstVariant.width, 0, 0, pos, false));
knuthList.add(new KnuthBox(0, new Position(lm), false));
return knuthList;
}
diff --git a/src/java/org/apache/fop/layoutmgr/BestFitPenalty.java b/src/java/org/apache/fop/layoutmgr/BestFitPenalty.java
index 334a36900..692cc19cb 100644
--- a/src/java/org/apache/fop/layoutmgr/BestFitPenalty.java
+++ b/src/java/org/apache/fop/layoutmgr/BestFitPenalty.java
@@ -35,10 +35,12 @@ public class BestFitPenalty extends KnuthPenalty {
public final List<ListElement> knuthList;
public final int width;
+ public int penaltyIndex;
public Variant(List<ListElement> knuthList, int width) {
this.knuthList = knuthList;
this.width = width;
+ this.penaltyIndex = -1;
}
public KnuthElement toPenalty() {
diff --git a/src/java/org/apache/fop/layoutmgr/MultiCaseLayoutManager.java b/src/java/org/apache/fop/layoutmgr/MultiCaseLayoutManager.java
index bc3e61b8e..9469a2fb8 100644
--- a/src/java/org/apache/fop/layoutmgr/MultiCaseLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/MultiCaseLayoutManager.java
@@ -18,14 +18,10 @@
package org.apache.fop.layoutmgr;
import org.apache.fop.area.Area;
-import org.apache.fop.area.Block;
-import org.apache.fop.area.LineArea;
import org.apache.fop.fo.FObj;
public class MultiCaseLayoutManager extends BlockStackingLayoutManager {
- private Block curBlockArea;
-
public MultiCaseLayoutManager(FObj node) {
super(node);
}
@@ -47,36 +43,12 @@ public class MultiCaseLayoutManager extends BlockStackingLayoutManager {
@Override
public Area getParentArea(Area childArea) {
- if (curBlockArea == null) {
- curBlockArea = new Block();
- curBlockArea.setIPD(super.getContentAreaIPD());
- // Set up dimensions
- // Must get dimensions from parent area
- /*Area parentArea = */parentLayoutManager.getParentArea(curBlockArea);
- setCurrentArea(curBlockArea);
- }
- return curBlockArea;
+ return parentLayoutManager.getParentArea(childArea);
}
@Override
public void addChildArea(Area childArea) {
- if (curBlockArea != null) {
- if (childArea instanceof LineArea) {
- curBlockArea.addLineArea((LineArea) childArea);
- } else {
- curBlockArea.addBlock((Block) childArea);
- }
- }
- }
-
- /**
- * Force current area to be added to parent area.
- */
- @Override
- protected void flush() {
- if (getCurrentArea() != null) {
- super.flush();
- }
+ parentLayoutManager.addChildArea(childArea);
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/layoutmgr/MultiSwitchLayoutManager.java b/src/java/org/apache/fop/layoutmgr/MultiSwitchLayoutManager.java
index 8ef901a56..a2b0e90b0 100644
--- a/src/java/org/apache/fop/layoutmgr/MultiSwitchLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/MultiSwitchLayoutManager.java
@@ -22,14 +22,10 @@ import java.util.LinkedList;
import java.util.List;
import org.apache.fop.area.Area;
-import org.apache.fop.area.Block;
-import org.apache.fop.area.LineArea;
import org.apache.fop.fo.FObj;
public class MultiSwitchLayoutManager extends BlockStackingLayoutManager {
- private Block curBlockArea;
-
public MultiSwitchLayoutManager(FObj node) {
super(node);
}
@@ -56,60 +52,13 @@ public class MultiSwitchLayoutManager extends BlockStackingLayoutManager {
}
@Override
- public Keep getKeepTogether() {
- return Keep.KEEP_AUTO;
- }
-
- @Override
- public Keep getKeepWithNext() {
- return Keep.KEEP_AUTO;
- }
-
- @Override
- public Keep getKeepWithPrevious() {
- return Keep.KEEP_AUTO;
- }
-
- @Override
- public int getContentAreaIPD() {
- if (curBlockArea != null) {
- return curBlockArea.getIPD();
- }
- return super.getContentAreaIPD();
- }
-
- @Override
public Area getParentArea(Area childArea) {
- if (curBlockArea == null) {
- curBlockArea = new Block();
- curBlockArea.setIPD(super.getContentAreaIPD());
- setCurrentArea(curBlockArea);
- // Set up dimensions
- // Must get dimensions from parent area
- /*Area parentArea = */parentLayoutManager.getParentArea(curBlockArea);
- }
- return curBlockArea;
+ return parentLayoutManager.getParentArea(childArea);
}
@Override
public void addChildArea(Area childArea) {
- if (curBlockArea != null) {
- if (childArea instanceof LineArea) {
- curBlockArea.addLineArea((LineArea) childArea);
- } else {
- curBlockArea.addBlock((Block) childArea);
- }
- }
- }
-
- /**
- * Force current area to be added to parent area.
- */
- @Override
- protected void flush() {
- if (curBlockArea != null) {
- parentLayoutManager.addChildArea(getCurrentArea());
- }
+ parentLayoutManager.addChildArea(childArea);
}
@Override
@@ -121,9 +70,6 @@ public class MultiSwitchLayoutManager extends BlockStackingLayoutManager {
AreaAdditionUtil.addAreas(this, newPosIter, context);
flush();
- // TODO removing the following line forces the generated area
- // to be rendered twice in some cases...
- curBlockArea = null;
}
}
diff --git a/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java b/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
index a5ed077d8..8c587bcc6 100644
--- a/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
+++ b/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
@@ -99,9 +99,6 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
private int currentKeepContext = Constants.EN_AUTO;
private KnuthNode lastBeforeKeepContextSwitch;
- /** Holds the variant of a dynamic content that must be attached to the next page node */
- private Variant variant;
-
/**
* Construct a page breaking algorithm.
* @param topLevelLM the top level layout manager
@@ -156,7 +153,10 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
/** Index of the last inserted element of the last inserted footnote. */
public int footnoteElementIndex;
+ /** Current active variant attached to this node */
public final Variant variant;
+ /** Pending variant to be assigned to all descending nodes */
+ public Variant pendingVariant;
public KnuthPageNode(int position,
int line, int fitness,
@@ -201,7 +201,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
bestTotalFootnotesLength[fitness] = totalFootnotesLength;
bestFootnoteListIndex[fitness] = footnoteListIndex;
bestFootnoteElementIndex[fitness] = footnoteElementIndex;
- bestVariant[fitness] = variant;
+ bestVariant[fitness] = ((KnuthPageNode) node).pendingVariant;
}
public int getInsertedFootnotesLength(int fitness) {
@@ -223,6 +223,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
public Variant getVariant(int fitness) {
return bestVariant[fitness];
}
+
}
/** {@inheritDoc} */
@@ -315,7 +316,8 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
insertedFootnotesLength, totalFootnotesLength,
footnoteListIndex, footnoteElementIndex,
adjustRatio, availableShrink, availableStretch,
- difference, totalDemerits, previous, variant);
+ difference, totalDemerits, previous,
+ (previous != null) ? ((KnuthPageNode)previous).pendingVariant : null);
}
/** {@inheritDoc} */
@@ -525,12 +527,14 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
int actualWidth = totalWidth - pageNode.totalWidth;
int footnoteSplit;
boolean canDeferOldFN;
- variant = null;
if (element.isPenalty()) {
if (element instanceof BestFitPenalty) {
- actualWidth += handleBestFitPenalty(activeNode, (BestFitPenalty) element, elementIndex);
+ actualWidth += handleBestFitPenalty(pageNode, (BestFitPenalty) element, elementIndex);
} else {
actualWidth += element.getWidth();
+ if (pageNode.pendingVariant != null) {
+ actualWidth += ((KnuthPageNode) activeNode).pendingVariant.width;
+ }
}
}
if (footnotesPending) {
@@ -591,13 +595,14 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
}
}
- private int handleBestFitPenalty(KnuthNode activeNode, BestFitPenalty penalty, int elementIndex) {
+ private int handleBestFitPenalty(KnuthPageNode activeNode, BestFitPenalty penalty, int elementIndex) {
for (Variant var : penalty.getVariants()) {
int difference = computeDifference(activeNode, var.toPenalty(), elementIndex);
double r = computeAdjustmentRatio(activeNode, difference);
if (r >= -1.0) {
- variant = var;
- return variant.width;
+ var.penaltyIndex = elementIndex;
+ activeNode.pendingVariant = var;
+ return var.width;
}
}
return 0;
@@ -1018,7 +1023,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
// Check if the given node has an attached variant of a dynamic content
KnuthPageNode pageNode = (KnuthPageNode) bestActiveNode;
if (pageNode.variant != null) {
- BestFitPenalty penalty = (BestFitPenalty) par.get(pageNode.position);
+ BestFitPenalty penalty = (BestFitPenalty) par.get(pageNode.variant.penaltyIndex);
penalty.setActiveVariant(pageNode.variant);
}
int difference = bestActiveNode.difference;
diff --git a/test/layoutengine/standard-testcases/multi-switch_best-fit_multiple-variants.xml b/test/layoutengine/standard-testcases/multi-switch_best-fit_multiple-variants.xml
index bb0715fa0..11b3cfe7d 100644
--- a/test/layoutengine/standard-testcases/multi-switch_best-fit_multiple-variants.xml
+++ b/test/layoutengine/standard-testcases/multi-switch_best-fit_multiple-variants.xml
@@ -106,13 +106,13 @@
<!-- 1. First variant -->
<eval expected="3" xpath="count(//pageSequence[1]/pageViewport)"/>
<eval expected="Filler" xpath="//pageSequence[1]/pageViewport[2]//flow/block[1]"/>
- <eval expected="Variant 1 line 1" xpath="//pageSequence[1]/pageViewport[2]//flow/block[3]/block/block[1]"/>
+ <eval expected="Variant 1 line 1" xpath="//pageSequence[1]/pageViewport[2]//flow/block[3]"/>
<eval expected="This text should be on page 3." xpath="//pageSequence[1]/pageViewport[3]//flow/block[1]"/>
<!-- 2. Second variant -->
<eval expected="3" xpath="count(//pageSequence[2]/pageViewport)"/>
<eval expected="Page 2 line 1" xpath="//pageSequence[2]/pageViewport[2]//flow/block[1]"/>
- <eval expected="Variant 2 line 1" xpath="//pageSequence[2]/pageViewport[2]//flow/block[4]/block/block[1]"/>
+ <eval expected="Variant 2 line 1" xpath="//pageSequence[2]/pageViewport[2]//flow/block[4]"/>
<eval expected="This text should be on page 3." xpath="//pageSequence[2]/pageViewport[3]//flow/block[1]"/>
<!-- 3. No variant -->
@@ -122,8 +122,9 @@
<eval expected="Page 2 line 2" xpath="//pageSequence[3]/pageViewport[2]//flow/block[2]"/>
<eval expected="Filler" xpath="//pageSequence[3]/pageViewport[2]//flow/block[3]"/>
<eval expected="Before the multi-switch" xpath="//pageSequence[3]/pageViewport[2]//flow/block[4]"/>
- <eval expected="2" xpath="count(//pageSequence[3]/pageViewport[3]//flow/block)"/>
- <eval expected="Variant 1 line 1" xpath="//pageSequence[3]/pageViewport[3]//flow/block[1]/block/block[1]"/>
- <eval expected="This text should be on page 3." xpath="//pageSequence[3]/pageViewport[3]//flow/block[2]"/>
+ <eval expected="3" xpath="count(//pageSequence[3]/pageViewport[3]//flow/block)"/>
+ <eval expected="Variant 1 line 1" xpath="//pageSequence[3]/pageViewport[3]//flow/block[1]"/>
+ <eval expected="Variant 1 line 2" xpath="//pageSequence[3]/pageViewport[3]//flow/block[2]"/>
+ <eval expected="This text should be on page 3." xpath="//pageSequence[3]/pageViewport[3]//flow/block[3]"/>
</checks>
</testcase>