From: Vincent Hennebert Date: Fri, 13 Dec 2013 23:04:04 +0000 (+0000) Subject: Attach the selected variant to KnuthPageNode in order to propagate the information... X-Git-Tag: fop-2_0~117^2~12 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=8c0f881ee1b6aaae77c732bf66a1c1887a0e639f;p=xmlgraphics-fop.git Attach the selected variant to KnuthPageNode in order to propagate the information down to area tree creation. Patch by Seifeddine Dridi, applied with some modifications. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_WhitespaceManagement@1550847 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/java/org/apache/fop/layoutmgr/BestFitLayoutUtils.java b/src/java/org/apache/fop/layoutmgr/BestFitLayoutUtils.java index 352a876d4..17dddc239 100644 --- a/src/java/org/apache/fop/layoutmgr/BestFitLayoutUtils.java +++ b/src/java/org/apache/fop/layoutmgr/BestFitLayoutUtils.java @@ -17,7 +17,6 @@ package org.apache.fop.layoutmgr; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; @@ -36,10 +35,12 @@ public final class BestFitLayoutUtils { public BestFitPosition(LayoutManager lm) { super(lm); } + public BestFitPosition(LayoutManager lm, List knuthList) { super(lm); this.knuthList = knuthList; } + public List getPositionList() { List positions = new LinkedList(); if (knuthList != null) { @@ -62,17 +63,16 @@ public final class BestFitLayoutUtils { List knuthList = new LinkedList(); - Iterator> iter = childrenLists.iterator(); - while (iter.hasNext()) { - - List childList = iter.next(); + BestFitPenalty bestFitPenalty = new BestFitPenalty(new BestFitPosition(lm)); + for (List childList : childrenLists) { SpaceResolver.resolveElementList(childList); int contentLength = ElementListUtils.calcContentLength(childList); - BestFitPenalty bestFitPenalty = - new BestFitPenalty(contentLength, childList, - new BestFitPosition(lm)); - knuthList.add(bestFitPenalty); + bestFitPenalty.addVariant(childList, contentLength); } + // TODO Adding the two enclosing boxes is definitely a dirty hack. + // Let's leave it like that for now, until I find a proper fix. + knuthList.add(new KnuthBox(0, new Position(lm), false)); + knuthList.add(bestFitPenalty); 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 13c88e82c..0f77edc8d 100644 --- a/src/java/org/apache/fop/layoutmgr/BestFitPenalty.java +++ b/src/java/org/apache/fop/layoutmgr/BestFitPenalty.java @@ -19,55 +19,59 @@ package org.apache.fop.layoutmgr; +import java.util.ArrayList; import java.util.List; import org.apache.fop.layoutmgr.BestFitLayoutUtils.BestFitPosition; /** - * A penalty class used to specify a set of alternatives for the layout engine + * A type of penalty used to specify a set of alternatives for the layout engine * to choose from. The chosen alternative must have an occupied size - * that is less than the available BPD of the current page - * and it must also be the best match when it is evaluated by {@link FittingStrategy}. + * that is less than the available BPD of the current page. */ public class BestFitPenalty extends KnuthPenalty { - private final List knuthList; - public boolean ignorePenalty; + public class Variant { - public BestFitPenalty(int width, List knuthList, Position pos) { - super(width, 0, false, pos, false); - this.knuthList = knuthList; + public final List knuthList; + public final int width; + + public Variant(List knuthList, int width) { + this.knuthList = knuthList; + this.width = width; + } + public KnuthElement toPenalty() { + return new KnuthPenalty(width, 0, false, null, false); + } } - public void activateContent() { - BestFitPosition pos = getBestFitPosition(); - pos.setKnuthList(knuthList); + private final BestFitPosition bestFitPosition; + + private final List variantList; + + public BestFitPenalty(BestFitPosition pos) { + super(0, 0, false, pos, false); + this.bestFitPosition = pos; + variantList = new ArrayList(); } - public int getWidth() { - if (ignorePenalty) { - return 0; - } - return super.getWidth(); + public void addVariant(List knuthList, int width) { + variantList.add(new Variant(knuthList, width)); } - public BestFitPosition getBestFitPosition() { - Position pos = super.getPosition(); - while (pos != null) { - if (pos instanceof BestFitPosition) { - return (BestFitPosition) pos; - } - pos = pos.getPosition(); - } - return null; + public void activatePenalty(Variant bestVariant) { + bestFitPosition.setKnuthList(bestVariant.knuthList); + } + + public List getVariantList() { + return variantList; } @Override public String toString() { String str = super.toString(); StringBuffer buffer = new StringBuffer(64); -// buffer.append(" number of alternatives = " + alternatives.size()); -// buffer.append(" fitting-strategy = " + strategy.getStrategyName()); + buffer.append(" number of variants = " + variantList.size()); return str + buffer.toString(); } diff --git a/src/java/org/apache/fop/layoutmgr/MultiSwitchLayoutManager.java b/src/java/org/apache/fop/layoutmgr/MultiSwitchLayoutManager.java index 50dee48b4..386aba39b 100644 --- a/src/java/org/apache/fop/layoutmgr/MultiSwitchLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/MultiSwitchLayoutManager.java @@ -137,7 +137,7 @@ public class MultiSwitchLayoutManager extends BlockStackingLayoutManager { */ @Override protected void flush() { - if (getCurrentArea() != null) { + if (curBlockArea != null) { parentLayoutManager.addChildArea(getCurrentArea()); } } @@ -151,6 +151,7 @@ public class MultiSwitchLayoutManager extends BlockStackingLayoutManager { AreaAdditionUtil.addAreas(this, newPosIter, context); flush(); + curBlockArea = null; } } diff --git a/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java b/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java index b7e2413bb..6db928ee8 100644 --- a/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java +++ b/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java @@ -30,6 +30,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.fop.fo.Constants; import org.apache.fop.fo.FObj; import org.apache.fop.layoutmgr.AbstractBreaker.PageBreakPosition; +import org.apache.fop.layoutmgr.BestFitPenalty.Variant; import org.apache.fop.traits.MinOptMax; import org.apache.fop.util.ListUtil; @@ -98,6 +99,9 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { private int currentKeepContext = Constants.EN_AUTO; private KnuthNode lastBeforeKeepContextSwitch; + /** Holds the variant that should be assigned to the next node to be created */ + private Variant variant; + /** * Construct a page breaking algorithm. * @param topLevelLM the top level layout manager @@ -149,12 +153,14 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { /** Index of the last inserted element of the last inserted footnote. */ public int footnoteElementIndex; + public final Variant variant; + public KnuthPageNode(int position, int line, int fitness, int totalWidth, int totalStretch, int totalShrink, int totalFootnotes, int footnoteListIndex, int footnoteElementIndex, double adjustRatio, int availableShrink, int availableStretch, - int difference, double totalDemerits, KnuthNode previous) { + int difference, double totalDemerits, KnuthNode previous, Variant variant) { super(position, line, fitness, totalWidth, totalStretch, totalShrink, adjustRatio, availableShrink, availableStretch, @@ -162,6 +168,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { this.totalFootnotes = totalFootnotes; this.footnoteListIndex = footnoteListIndex; this.footnoteElementIndex = footnoteElementIndex; + this.variant = variant; } } @@ -175,6 +182,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { private final int[] bestFootnotesLength = new int[4]; private final int[] bestFootnoteListIndex = new int[4]; private final int[] bestFootnoteElementIndex = new int[4]; + private final Variant[] bestVariant = new Variant[4]; @Override public void addRecord(double demerits, KnuthNode node, double adjust, @@ -186,6 +194,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { bestFootnotesLength[fitness] = insertedFootnotesLength; bestFootnoteListIndex[fitness] = footnoteListIndex; bestFootnoteElementIndex[fitness] = footnoteElementIndex; + bestVariant[fitness] = variant; } public int getFootnotesLength(int fitness) { @@ -199,6 +208,10 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { public int getFootnoteElementIndex(int fitness) { return bestFootnoteElementIndex[fitness]; } + + public Variant getVariant(int fitness) { + return bestVariant[fitness]; + } } /** {@inheritDoc} */ @@ -290,7 +303,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { totalWidth, totalStretch, totalShrink, insertedFootnotesLength, footnoteListIndex, footnoteElementIndex, adjustRatio, availableShrink, availableStretch, - difference, totalDemerits, previous); + difference, totalDemerits, previous, variant); } /** {@inheritDoc} */ @@ -304,7 +317,8 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { ((BestPageRecords) best).getFootnoteElementIndex(fitness), best.getAdjust(fitness), best.getAvailableShrink(fitness), best.getAvailableStretch(fitness), best.getDifference(fitness), - best.getDemerits(fitness), best.getNode(fitness)); + best.getDemerits(fitness), best.getNode(fitness), + ((BestPageRecords) best).getVariant(fitness)); } /** @@ -432,6 +446,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { /** {@inheritDoc} */ @Override protected void considerLegalBreak(KnuthElement element, int elementIdx) { + variant = null; if (element.isPenalty()) { int breakClass = ((KnuthPenalty) element).getBreakClass(); switch (breakClass) { @@ -500,7 +515,11 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { int footnoteSplit; boolean canDeferOldFN; if (element.isPenalty()) { - actualWidth += element.getWidth(); + if (element instanceof BestFitPenalty) { + actualWidth += handleBestFitPenalty(activeNode, (BestFitPenalty) element, elementIndex); + } else { + actualWidth += element.getWidth(); + } } if (footnotesPending) { // compute the total length of the footnotes not yet inserted @@ -560,6 +579,18 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { } } + private int handleBestFitPenalty(KnuthNode activeNode, BestFitPenalty penalty, int elementIndex) { + for (Variant var : penalty.getVariantList()) { + int difference = computeDifference(activeNode, var.toPenalty(), elementIndex); + double r = computeAdjustmentRatio(activeNode, difference); + if (r >= -1.0) { + variant = var; + return variant.width; + } + } + return 0; + } + /** * Checks whether footnotes from preceding pages may be deferred to the page after * the given element. @@ -970,6 +1001,12 @@ class PageBreakingAlgorithm extends BreakingAlgorithm { int total) { //int difference = (bestActiveNode.line < total) // ? bestActiveNode.difference : bestActiveNode.difference + fillerMinWidth; + // Check if the given node has an attached dynamic content + KnuthPageNode pageNode = (KnuthPageNode) bestActiveNode; + if (pageNode.variant != null) { + BestFitPenalty penalty = (BestFitPenalty) par.get(pageNode.position); + penalty.activatePenalty(pageNode.variant); + } int difference = bestActiveNode.difference; if (difference + bestActiveNode.availableShrink < 0) { if (!autoHeight) {