aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Hennebert <vhennebert@apache.org>2009-08-26 17:42:11 +0000
committerVincent Hennebert <vhennebert@apache.org>2009-08-26 17:42:11 +0000
commit9520407736edcb4389c1418b70e0f7f376d7bd85 (patch)
tree04d708dc09139eae1e4668c14314231c5ed4a71c
parentccc743d929c38077f06886f245bd05f3a7780999 (diff)
downloadxmlgraphics-fop-9520407736edcb4389c1418b70e0f7f376d7bd85.tar.gz
xmlgraphics-fop-9520407736edcb4389c1418b70e0f7f376d7bd85.zip
Reverted changes made in revision 796809 (manual merge of clean-up changes made in the ChangingIPDHack branch). Those changes will be re-applied when merging the branch back to Trunk with svn merge --reintegrate (if everything goes well...)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@808135 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--src/java/org/apache/fop/layoutmgr/AbstractBreaker.java8
-rw-r--r--src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java14
-rw-r--r--src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java17
-rw-r--r--src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java213
-rw-r--r--src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java8
-rw-r--r--src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java155
-rw-r--r--src/java/org/apache/fop/layoutmgr/InlineKnuthSequence.java16
-rw-r--r--src/java/org/apache/fop/layoutmgr/LayoutContext.java39
-rw-r--r--src/java/org/apache/fop/layoutmgr/LeafPosition.java6
-rw-r--r--src/java/org/apache/fop/layoutmgr/PageBreaker.java8
-rw-r--r--src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java103
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java10
-rwxr-xr-xsrc/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java10
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java32
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java509
16 files changed, 807 insertions, 343 deletions
diff --git a/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java b/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
index cc23de404..6393935ae 100644
--- a/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
+++ b/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
@@ -293,6 +293,14 @@ public abstract class AbstractBreaker {
/**
* Starts the page breaking process.
* @param flowBPD the constant available block-progression-dimension (used for every part)
+ */
+ public void doLayout(int flowBPD) {
+ doLayout(flowBPD, false);
+ }
+
+ /**
+ * Starts the page breaking process.
+ * @param flowBPD the constant available block-progression-dimension (used for every part)
* @param autoHeight true if warnings about overflows should be disabled because the
* the BPD is really undefined (for footnote-separators, for example)
*/
diff --git a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java
index 690081d23..8dca1c749 100644
--- a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java
@@ -47,22 +47,22 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager
private static Log log = LogFactory.getLog(AbstractLayoutManager.class);
/** Parent LayoutManager for this LayoutManager */
- protected LayoutManager parentLM;
+ protected LayoutManager parentLM = null;
/** List of child LayoutManagers */
- protected List childLMs;
+ protected List childLMs = null;
/** Iterator for child LayoutManagers */
- protected ListIterator fobjIter;
+ protected ListIterator fobjIter = null;
/** Marker map for markers related to this LayoutManager */
- private Map markers;
+ private Map markers = null;
/** True if this LayoutManager has handled all of its content. */
- private boolean isFinished;
+ private boolean isFinished = false;
/** child LM during getNextKnuthElement phase */
- protected LayoutManager curChildLM;
+ protected LayoutManager curChildLM = null;
/** child LM iterator during getNextKnuthElement phase */
- protected ListIterator childLMiter;
+ protected ListIterator childLMiter = null;
private int lastGeneratedPosition = -1;
private int smallestPosNumberChecked = Integer.MAX_VALUE;
diff --git a/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java b/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java
index 14183c52e..a429359ad 100644
--- a/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java
+++ b/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java
@@ -117,7 +117,7 @@ public class AreaAdditionUtil {
// set space after for each LM, in order to implement
// display-align = distribute
lc.setSpaceAfter(layoutContext.getSpaceAfter());
- lc.setStackLimitBP(layoutContext.getStackLimitBP());
+ lc.setStackLimitsFrom(layoutContext);
childLM.addAreas(childPosIter, lc);
}
diff --git a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
index 4b21b4e11..20895a38e 100644
--- a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
@@ -67,6 +67,9 @@ public class BlockLayoutManager extends BlockStackingLayoutManager
private MinOptMax effSpaceBefore;
private MinOptMax effSpaceAfter;
+ /** The list of child BreakPoss instances. */
+ protected List childBreaks = new java.util.ArrayList();
+
/**
* Creates a new BlockLayoutManager.
* @param inBlock the block FO object to create the layout manager for.
@@ -246,8 +249,8 @@ public class BlockLayoutManager extends BlockStackingLayoutManager
// and put them in a new list;
LinkedList positionList = new LinkedList();
Position pos;
- boolean spaceBefore = false;
- boolean spaceAfter = false;
+ boolean bSpaceBefore = false;
+ boolean bSpaceAfter = false;
Position firstPos = null;
Position lastPos = null;
while (parentIter.hasNext()) {
@@ -270,11 +273,11 @@ public class BlockLayoutManager extends BlockStackingLayoutManager
// this means the space was not discarded
if (positionList.size() == 0) {
// pos was in the element representing space-before
- spaceBefore = true;
+ bSpaceBefore = true;
//log.trace(" space before");
} else {
// pos was in the element representing space-after
- spaceAfter = true;
+ bSpaceAfter = true;
//log.trace(" space-after");
}
} else if (innerPosition.getLM() == this
@@ -299,7 +302,7 @@ public class BlockLayoutManager extends BlockStackingLayoutManager
// the Positions in positionList were inside the elements
// created by the LineLM
childPosIter = new StackingIter(positionList.listIterator());
- } else {
+ } else {
// the Positions in positionList were inside the elements
// created by the BlockLM in the createUnitElements() method
//if (((Position) positionList.getLast()) instanceof
@@ -338,7 +341,7 @@ public class BlockLayoutManager extends BlockStackingLayoutManager
// + " spacing");
// add space before and / or after the paragraph
// to reach a multiple of bpUnit
- if (spaceBefore && spaceAfter) {
+ if (bSpaceBefore && bSpaceAfter) {
foSpaceBefore = new SpaceVal(getBlockFO()
.getCommonMarginBlock().spaceBefore, this).getSpace();
foSpaceAfter = new SpaceVal(getBlockFO()
@@ -351,7 +354,7 @@ public class BlockLayoutManager extends BlockStackingLayoutManager
+ foSpaceBefore.min
+ foSpaceAfter.min)
* bpUnit - splitLength - adjustedSpaceBefore;
- } else if (spaceBefore) {
+ } else if (bSpaceBefore) {
adjustedSpaceBefore = neededUnits(splitLength
+ foSpaceBefore.min)
* bpUnit - splitLength;
diff --git a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
index 3cd7b0994..73c8eb00d 100644
--- a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
@@ -54,26 +54,31 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
*/
private static Log log = LogFactory.getLog(BlockStackingLayoutManager.class);
- protected BlockParent parentArea;
+ /**
+ * Reference to FO whose areas it's managing or to the traits
+ * of the FO.
+ */
+ //protected LayoutManager curChildLM = null; AbstractLayoutManager also defines this!
+ protected BlockParent parentArea = null;
/** Value of the block-progression-unit (non-standard property) */
- protected int bpUnit;
+ protected int bpUnit = 0;
/** space-before value adjusted for block-progression-unit handling */
- protected int adjustedSpaceBefore;
+ protected int adjustedSpaceBefore = 0;
/** space-after value adjusted for block-progression-unit handling */
- protected int adjustedSpaceAfter;
+ protected int adjustedSpaceAfter = 0;
/** Only used to store the original list when createUnitElements is called */
- protected List storedList;
+ protected List storedList = null;
/** Indicates whether break before has been served or not */
- protected boolean breakBeforeServed;
+ protected boolean breakBeforeServed = false;
/** Indicates whether the first visible mark has been returned by this LM, yet */
- protected boolean firstVisibleMarkServed;
+ protected boolean firstVisibleMarkServed = false;
/** Reference IPD available */
- protected int referenceIPD;
+ protected int referenceIPD = 0;
/** the effective start-indent value */
- protected int startIndent;
+ protected int startIndent = 0;
/** the effective end-indent value */
- protected int endIndent;
+ protected int endIndent = 0;
/**
* Holds the (one-time use) fo:block space-before
* and -after properties. Large fo:blocks are split
@@ -83,13 +88,13 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
* Block and space-after at the end of the last Block
* used in rendering the fo:block.
*/
- protected MinOptMax foSpaceBefore;
+ protected MinOptMax foSpaceBefore = null;
/** see foSpaceBefore */
- protected MinOptMax foSpaceAfter;
+ protected MinOptMax foSpaceAfter = null;
private Position auxiliaryPosition;
- private int contentAreaIPD;
+ private int contentAreaIPD = 0;
/**
* @param node the fo this LM deals with
@@ -243,27 +248,38 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
/** {@inheritDoc} */
public List getNextKnuthElements(LayoutContext context, int alignment) {
+ //log.debug("BLM.getNextKnuthElements> keep-together = "
+ // + layoutProps.keepTogether.getType());
+ //log.debug(" keep-with-previous = " +
+ // layoutProps.keepWithPrevious.getType());
+ //log.debug(" keep-with-next = " +
+ // layoutProps.keepWithNext.getType());
+ BlockLevelLayoutManager curLM; // currently active LM
+ BlockLevelLayoutManager prevLM = null; // previously active LM
+
referenceIPD = context.getRefIPD();
+
updateContentAreaIPDwithOverconstrainedAdjust();
+ List returnedList = null;
List contentList = new LinkedList();
- List elements = new LinkedList();
+ List returnList = new LinkedList();
if (!breakBeforeServed) {
breakBeforeServed = true;
if (!context.suppressBreakBefore()) {
- if (addKnuthElementsForBreakBefore(elements, context)) {
- return elements;
+ if (addKnuthElementsForBreakBefore(returnList, context)) {
+ return returnList;
}
}
}
if (!firstVisibleMarkServed) {
- addKnuthElementsForSpaceBefore(elements, alignment);
+ addKnuthElementsForSpaceBefore(returnList, alignment);
context.updateKeepWithPreviousPending(getKeepWithPrevious());
}
- addKnuthElementsForBorderPaddingBefore(elements, !firstVisibleMarkServed);
+ addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed);
firstVisibleMarkServed = true;
//Spaces, border and padding to be repeated at each break
@@ -272,107 +288,142 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
//Used to indicate a special break-after case when all content has already been generated.
BreakElement forcedBreakAfterLast = null;
- LayoutManager currentChildLM;
- while ((currentChildLM = (LayoutManager) getChildLM()) != null) {
+ while ((curLM = (BlockLevelLayoutManager) getChildLM()) != null) {
LayoutContext childLC = new LayoutContext(0);
+ childLC.copyPendingMarksFrom(context);
+ if (curLM instanceof LineLayoutManager) {
+ // curLM is a LineLayoutManager
+ // set stackLimit for lines (stack limit is now i-p-direction, not b-p-direction!)
+ childLC.setStackLimitBP(context.getStackLimitBP());
+ childLC.setStackLimitIP(new MinOptMax(getContentAreaIPD()));
+ childLC.setRefIPD(getContentAreaIPD());
+ } else {
+ // curLM is a ?
+ //childLC.setStackLimit(MinOptMax.subtract(context
+ // .getStackLimit(), stackSize));
+ childLC.setStackLimitBP(context.getStackLimitBP());
+ childLC.setRefIPD(referenceIPD);
+ }
+ if (curLM == this.childLMs.get(0)) {
+ childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE);
+ //Handled already by the parent (break collapsing, see above)
+ }
- List childrenElements = getNextChildElements(currentChildLM, context, childLC,
- alignment);
-
- if (contentList.isEmpty()) {
+ // get elements from curLM
+ returnedList = curLM.getNextKnuthElements(childLC, alignment);
+ if (contentList.isEmpty() && childLC.isKeepWithPreviousPending()) {
//Propagate keep-with-previous up from the first child
context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending());
+ childLC.clearKeepWithPreviousPending();
}
- if (childrenElements != null && !childrenElements.isEmpty()) {
- if (!contentList.isEmpty()
- && !ElementListUtils.startsWithForcedBreak(childrenElements)) {
+ if (returnedList != null
+ && returnedList.size() == 1
+ && ((ListElement) returnedList.get(0)).isForcedBreak()) {
+
+ if (curLM.isFinished() && !hasNextChildLM()) {
+ // a descendant of this block has break-before
+ forcedBreakAfterLast = (BreakElement) returnedList.get(0);
+ context.clearPendingMarks();
+ break;
+ }
+
+ if (contentList.isEmpty()) {
+ // Empty fo:block, zero-length box makes sure the IDs and/or markers
+ // are registered and borders/padding are painted.
+ returnList.add(new KnuthBox(0, notifyPos(new Position(this)), false));
+ }
+ // a descendant of this block has break-before
+ contentList.addAll(returnedList);
+
+ /* extension: conversione di tutta la sequenza fin'ora ottenuta */
+ if (bpUnit > 0) {
+ storedList = contentList;
+ contentList = createUnitElements(contentList);
+ }
+ /* end of extension */
+
+ // "wrap" the Position inside each element
+ // moving the elements from contentList to returnList
+ returnedList = new LinkedList();
+ wrapPositionElements(contentList, returnList);
+
+ return returnList;
+ } else {
+ if (returnedList == null || returnedList.isEmpty()) {
+ //Avoid NoSuchElementException below (happens with empty blocks)
+ continue;
+ }
+ if (prevLM != null
+ && !ElementListUtils.startsWithForcedBreak(returnedList)) {
// there is a block handled by prevLM before the one
// handled by curLM, and the one handled
// by the current LM does not begin with a break
addInBetweenBreak(contentList, context, childLC);
}
- if (childrenElements.size() == 1
- && ElementListUtils.startsWithForcedBreak(childrenElements)) {
-
- if (currentChildLM.isFinished() && !hasNextChildLM()) {
- // a descendant of this block has break-before
- forcedBreakAfterLast = (BreakElement) childrenElements.get(0);
+ contentList.addAll(returnedList);
+ if (ElementListUtils.endsWithForcedBreak(returnedList)) {
+ // a descendant of this block has break-after
+ if (curLM.isFinished() && !hasNextChildLM()) {
+ forcedBreakAfterLast = (BreakElement) ListUtil
+ .removeLast(contentList);
context.clearPendingMarks();
break;
}
- if (contentList.isEmpty()) {
- // Empty fo:block, zero-length box makes sure the IDs and/or markers
- // are registered and borders/padding are painted.
- elements.add(new KnuthBox(0, notifyPos(new Position(this)), false));
+ /* extension: conversione di tutta la sequenza fin'ora ottenuta */
+ if (bpUnit > 0) {
+ storedList = contentList;
+ contentList = createUnitElements(contentList);
}
- // a descendant of this block has break-before
- contentList.addAll(childrenElements);
+ /* end of extension */
- wrapPositionElements(contentList, elements);
+ returnedList = new LinkedList();
+ wrapPositionElements(contentList, returnList);
- return elements;
- } else {
- contentList.addAll(childrenElements);
- if (ElementListUtils.endsWithForcedBreak(childrenElements)) {
- // a descendant of this block has break-after
- if (currentChildLM.isFinished() && !hasNextChildLM()) {
- forcedBreakAfterLast = (BreakElement) ListUtil.removeLast(contentList);
- context.clearPendingMarks();
- break;
- }
-
- wrapPositionElements(contentList, elements);
-
- return elements;
- }
+ return returnList;
}
- context.updateKeepWithNextPending(childLC.getKeepWithNextPending());
}
+ // propagate and clear
+ context.updateKeepWithNextPending(childLC.getKeepWithNextPending());
+ childLC.clearKeepsPending();
+ prevLM = curLM;
+ }
+
+ /* Extension: conversione di tutta la sequenza fin'ora ottenuta */
+ if (bpUnit > 0) {
+ storedList = contentList;
+ contentList = createUnitElements(contentList);
}
+ /* end of extension */
+ returnedList = new LinkedList();
if (!contentList.isEmpty()) {
- wrapPositionElements(contentList, elements);
+ wrapPositionElements(contentList, returnList);
} else if (forcedBreakAfterLast == null) {
// Empty fo:block, zero-length box makes sure the IDs and/or markers
// are registered.
- elements.add(new KnuthBox(0, notifyPos(new Position(this)), true));
+ returnList.add(new KnuthBox(0, notifyPos(new Position(this)), true));
}
- addKnuthElementsForBorderPaddingAfter(elements, true);
- addKnuthElementsForSpaceAfter(elements, alignment);
+ addKnuthElementsForBorderPaddingAfter(returnList, true);
+ addKnuthElementsForSpaceAfter(returnList, alignment);
//All child content is processed. Only break-after can occur now, so...
context.clearPendingMarks();
if (forcedBreakAfterLast == null) {
- addKnuthElementsForBreakAfter(elements, context);
- } else {
+ addKnuthElementsForBreakAfter(returnList, context);
+ }
+
+ if (forcedBreakAfterLast != null) {
forcedBreakAfterLast.clearPendingMarks();
- elements.add(forcedBreakAfterLast);
+ returnList.add(forcedBreakAfterLast);
}
context.updateKeepWithNextPending(getKeepWithNext());
setFinished(true);
- return elements;
- }
-
- private List getNextChildElements(LayoutManager childLM, LayoutContext context,
- LayoutContext childLC, int alignment) {
- childLC.copyPendingMarksFrom(context);
- childLC.setStackLimitBP(context.getStackLimitBP());
- if (childLM instanceof LineLayoutManager) {
- childLC.setRefIPD(getContentAreaIPD());
- } else {
- childLC.setRefIPD(referenceIPD);
- }
- if (childLM == this.childLMs.get(0)) {
- childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE);
- //Handled already by the parent (break collapsing, see above)
- }
-
- return childLM.getNextKnuthElements(childLC, alignment);
+ return returnList;
}
/**
diff --git a/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java b/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java
index bde969211..c6bd7bcec 100644
--- a/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java
+++ b/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java
@@ -1283,8 +1283,12 @@ public abstract class BreakingAlgorithm {
* @return the width/length in millipoints
*/
protected int getLineWidth(int line) {
- assert lineWidth >= 0;
- return this.lineWidth;
+ if (this.lineWidth < 0) {
+ throw new IllegalStateException("lineWidth must be set"
+ + (this.lineWidth != 0 ? " and positive, but it is: " + this.lineWidth : ""));
+ } else {
+ return this.lineWidth;
+ }
}
/** @return the constant line/part width or -1 if there is no such value */
diff --git a/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java
index 6424475c3..5a80c3318 100644
--- a/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java
@@ -29,6 +29,8 @@ import org.apache.commons.logging.LogFactory;
import org.apache.fop.area.Area;
import org.apache.fop.area.BlockParent;
import org.apache.fop.fo.pagination.Flow;
+import org.apache.fop.layoutmgr.inline.InlineLevelLayoutManager;
+import org.apache.fop.layoutmgr.inline.WrapperLayoutManager;
/**
* LayoutManager for an fo:flow object.
@@ -62,89 +64,110 @@ public class FlowLayoutManager extends BlockStackingLayoutManager
/** {@inheritDoc} */
public List getNextKnuthElements(LayoutContext context, int alignment) {
- List elements = new LinkedList();
+ // set layout dimensions
+ int flowIPD = getCurrentPV().getCurrentSpan().getColumnWidth();
+ int flowBPD = getCurrentPV().getBodyRegion().getBPD();
- LayoutManager currentChildLM;
- while ((currentChildLM = getChildLM()) != null) {
- if (handleSpanChange(currentChildLM, elements, context)) {
- SpaceResolver.resolveElementList(elements);
- return elements;
+ // currently active LM
+ LayoutManager curLM;
+ List returnedList;
+ List returnList = new LinkedList();
+
+ while ((curLM = getChildLM()) != null) {
+ if (!(curLM instanceof WrapperLayoutManager)
+ && curLM instanceof InlineLevelLayoutManager) {
+ log.error("inline area not allowed under flow - ignoring");
+ curLM.setFinished(true);
+ continue;
}
- LayoutContext childLC = new LayoutContext(0);
- List childrenElements = getNextChildElements(currentChildLM, context, childLC,
- alignment);
- if (elements.isEmpty()) {
- context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending());
+ int span = EN_NONE;
+ int disableColumnBalancing = EN_FALSE;
+ if (curLM instanceof BlockLayoutManager) {
+ span = ((BlockLayoutManager)curLM).getBlockFO().getSpan();
+ disableColumnBalancing = ((BlockLayoutManager) curLM).getBlockFO()
+ .getDisableColumnBalancing();
+ } else if (curLM instanceof BlockContainerLayoutManager) {
+ span = ((BlockContainerLayoutManager)curLM).getBlockContainerFO().getSpan();
+ disableColumnBalancing = ((BlockContainerLayoutManager) curLM).getBlockContainerFO()
+ .getDisableColumnBalancing();
}
- if (!elements.isEmpty()
- && !ElementListUtils.startsWithForcedBreak(childrenElements)) {
- addInBetweenBreak(elements, context, childLC);
+
+ int currentSpan = context.getCurrentSpan();
+ if (currentSpan != span) {
+ if (span == EN_ALL) {
+ context.setDisableColumnBalancing(disableColumnBalancing);
+ }
+ log.debug("span change from " + currentSpan + " to " + span);
+ context.signalSpanChange(span);
+ SpaceResolver.resolveElementList(returnList);
+ return returnList;
}
- context.updateKeepWithNextPending(childLC.getKeepWithNextPending());
- elements.addAll(childrenElements);
+ // Set up a LayoutContext
+ //MinOptMax bpd = context.getStackLimit();
- if (ElementListUtils.endsWithForcedBreak(elements)) {
- // a descendant of this flow has break-before or break-after
- if (currentChildLM.isFinished() && !hasNextChildLM()) {
- setFinished(true);
- }
- SpaceResolver.resolveElementList(elements);
- return elements;
+ LayoutContext childLC = new LayoutContext(0);
+ childLC.setStackLimitBP(context.getStackLimitBP());
+ childLC.setRefIPD(context.getRefIPD());
+ childLC.setWritingMode(getCurrentPage().getSimplePageMaster().getWritingMode());
+
+ // get elements from curLM
+ returnedList = curLM.getNextKnuthElements(childLC, alignment);
+ //log.debug("FLM.getNextKnuthElements> returnedList.size() = " + returnedList.size());
+ if (returnList.size() == 0 && childLC.isKeepWithPreviousPending()) {
+ context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending());
+ childLC.clearKeepWithPreviousPending();
}
- }
- SpaceResolver.resolveElementList(elements);
- setFinished(true);
+ // "wrap" the Position inside each element
+ List tempList = returnedList;
+ returnedList = new LinkedList();
+ wrapPositionElements(tempList, returnedList);
+
+ if (returnedList.size() == 1
+ && ElementListUtils.endsWithForcedBreak(returnedList)) {
+ // a descendant of this flow has break-before
+ returnList.addAll(returnedList);
+ SpaceResolver.resolveElementList(returnList);
+ return returnList;
+ } else if (returnedList.size() > 0) {
+ if (returnList.size() > 0
+ && !ElementListUtils.startsWithForcedBreak(returnedList)) {
+ addInBetweenBreak(returnList, context, childLC);
+ }
+ returnList.addAll(returnedList);
+ if (ElementListUtils.endsWithForcedBreak(returnList)) {
+ if (curLM.isFinished() && !hasNextChildLM()) {
+ //If the layout manager is finished at this point, the pending
+ //marks become irrelevant.
+ childLC.clearPendingMarks();
+ //setFinished(true);
+ break;
+ }
+ // a descendant of this flow has break-after
+ SpaceResolver.resolveElementList(returnList);
+ return returnList;
+ }
+ }
- assert !elements.isEmpty();
- return elements;
- }
+ //Propagate and clear
+ context.updateKeepWithNextPending(childLC.getKeepWithNextPending());
+ childLC.clearKeepWithNextPending();
- private boolean handleSpanChange(LayoutManager childLM, List elements, LayoutContext context) {
- int span = EN_NONE;
- int disableColumnBalancing = EN_FALSE;
- if (childLM instanceof BlockLayoutManager) {
- span = ((BlockLayoutManager)childLM).getBlockFO().getSpan();
- disableColumnBalancing = ((BlockLayoutManager) childLM).getBlockFO()
- .getDisableColumnBalancing();
- } else if (childLM instanceof BlockContainerLayoutManager) {
- span = ((BlockContainerLayoutManager)childLM).getBlockContainerFO().getSpan();
- disableColumnBalancing = ((BlockContainerLayoutManager) childLM).getBlockContainerFO()
- .getDisableColumnBalancing();
+ context.updateKeepWithNextPending(getKeepWithNext());
}
- int currentSpan = context.getCurrentSpan();
- if (currentSpan != span) {
- if (span == EN_ALL) {
- context.setDisableColumnBalancing(disableColumnBalancing);
- }
- log.debug("span change from " + currentSpan + " to " + span);
- context.signalSpanChange(span);
- return true;
+ SpaceResolver.resolveElementList(returnList);
+ setFinished(true);
+
+ if (returnList.size() > 0) {
+ return returnList;
} else {
- return false;
+ return null;
}
}
- private List getNextChildElements(LayoutManager childLM, LayoutContext context,
- LayoutContext childLC, int alignment) {
- childLC.setStackLimitBP(context.getStackLimitBP());
- childLC.setRefIPD(context.getRefIPD());
- childLC.setWritingMode(getCurrentPage().getSimplePageMaster().getWritingMode());
-
- // get elements from curLM
- List childrenElements = childLM.getNextKnuthElements(childLC, alignment);
- assert !childrenElements.isEmpty();
-
- // "wrap" the Position inside each element
- List tempList = childrenElements;
- childrenElements = new LinkedList();
- wrapPositionElements(tempList, childrenElements);
- return childrenElements;
- }
-
/**
* {@inheritDoc}
*/
diff --git a/src/java/org/apache/fop/layoutmgr/InlineKnuthSequence.java b/src/java/org/apache/fop/layoutmgr/InlineKnuthSequence.java
index 104c71131..6d11a3c24 100644
--- a/src/java/org/apache/fop/layoutmgr/InlineKnuthSequence.java
+++ b/src/java/org/apache/fop/layoutmgr/InlineKnuthSequence.java
@@ -57,12 +57,16 @@ public class InlineKnuthSequence extends KnuthSequence {
return true;
}
- /** {@inheritDoc} */
+ /* (non-Javadoc)
+ * {@inheritDoc}
+ */
public boolean canAppendSequence(KnuthSequence sequence) {
return sequence.isInlineSequence() && !isClosed;
}
- /** {@inheritDoc} */
+ /* (non-Javadoc)
+ * {@inheritDoc}
+ */
public boolean appendSequence(KnuthSequence sequence) {
if (!canAppendSequence(sequence)) {
return false;
@@ -79,14 +83,18 @@ public class InlineKnuthSequence extends KnuthSequence {
return true;
}
- /** {@inheritDoc} */
+ /* (non-Javadoc)
+ * {@inheritDoc}
+ */
public boolean appendSequence(KnuthSequence sequence, boolean keepTogether,
BreakElement breakElement) {
return appendSequence(sequence);
}
- /** {@inheritDoc} */
+ /* (non-Javadoc)
+ * {@inheritDoc}
+ */
public KnuthSequence endSequence() {
if (!isClosed) {
add(new KnuthPenalty(0, -KnuthElement.INFINITE, false, null, false));
diff --git a/src/java/org/apache/fop/layoutmgr/LayoutContext.java b/src/java/org/apache/fop/layoutmgr/LayoutContext.java
index 81726e57b..41d4c5cfc 100644
--- a/src/java/org/apache/fop/layoutmgr/LayoutContext.java
+++ b/src/java/org/apache/fop/layoutmgr/LayoutContext.java
@@ -78,6 +78,15 @@ public class LayoutContext {
* level LM to allow them to optimize returned break possibilities.
*/
private MinOptMax stackLimitBP;
+ /**
+ * Total available stacking dimension for a "galley-level" layout
+ * manager in inline-progression-direction. It is passed by the
+ * parent LM. For LineLM, the block LM determines this based on
+ * indent properties.
+ * These LM <b>may</b> wish to pass this information down to lower
+ * level LM to allow them to optimize returned break possibilities.
+ */
+ private MinOptMax stackLimitIP;
/** to keep track of spanning in multi-column layout */
private int currentSpan = Constants.NOT_SET;
@@ -149,7 +158,7 @@ public class LayoutContext {
this.flags = parentLC.flags;
this.refIPD = parentLC.refIPD;
this.writingMode = parentLC.writingMode;
- setStackLimitBP(parentLC.getStackLimitBP());
+ setStackLimitsFrom(parentLC);
this.leadingSpace = parentLC.leadingSpace; //???
this.trailingSpace = parentLC.trailingSpace; //???
this.hyphContext = parentLC.hyphContext;
@@ -174,6 +183,7 @@ public class LayoutContext {
this.flags = flags;
this.refIPD = 0;
stackLimitBP = new MinOptMax(0);
+ stackLimitIP = new MinOptMax(0);
leadingSpace = null;
trailingSpace = null;
}
@@ -388,6 +398,31 @@ public class LayoutContext {
}
/**
+ * Sets the stack limit in inline-progression-dimension.
+ * @param limit the stack limit
+ */
+ public void setStackLimitIP(MinOptMax limit) {
+ stackLimitIP = limit;
+ }
+
+ /**
+ * Returns the stack limit in inline-progression-dimension.
+ * @return the stack limit
+ */
+ public MinOptMax getStackLimitIP() {
+ return stackLimitIP;
+ }
+
+ /**
+ * Sets (Copies) the stack limits in both directions from another layout context.
+ * @param context the layout context to take the values from
+ */
+ public void setStackLimitsFrom(LayoutContext context) {
+ setStackLimitBP(context.getStackLimitBP());
+ setStackLimitIP(context.getStackLimitIP());
+ }
+
+ /**
* Sets the inline-progression-dimension of the nearest ancestor reference area.
*/
public void setRefIPD(int ipd) {
@@ -627,6 +662,8 @@ public class LayoutContext {
return "Layout Context:"
+ "\nStack Limit BPD: \t"
+ (getStackLimitBP() == null ? "null" : getStackLimitBP().toString())
+ + "\nStack Limit IPD: \t"
+ + (getStackLimitIP() == null ? "null" : getStackLimitIP().toString())
+ "\nTrailing Space: \t"
+ (getTrailingSpace() == null ? "null" : getTrailingSpace().toString())
+ "\nLeading Space: \t"
diff --git a/src/java/org/apache/fop/layoutmgr/LeafPosition.java b/src/java/org/apache/fop/layoutmgr/LeafPosition.java
index 07eeef51f..ed8cc94e2 100644
--- a/src/java/org/apache/fop/layoutmgr/LeafPosition.java
+++ b/src/java/org/apache/fop/layoutmgr/LeafPosition.java
@@ -21,15 +21,15 @@ package org.apache.fop.layoutmgr;
public class LeafPosition extends Position {
- private int leafPos;
+ private int iLeafPos;
public LeafPosition(LayoutManager lm, int pos) {
super(lm);
- leafPos = pos;
+ iLeafPos = pos;
}
public int getLeafPos() {
- return leafPos;
+ return iLeafPos;
}
public boolean generatesAreas() {
diff --git a/src/java/org/apache/fop/layoutmgr/PageBreaker.java b/src/java/org/apache/fop/layoutmgr/PageBreaker.java
index 84afdcea9..ed0b37602 100644
--- a/src/java/org/apache/fop/layoutmgr/PageBreaker.java
+++ b/src/java/org/apache/fop/layoutmgr/PageBreaker.java
@@ -77,14 +77,6 @@ public class PageBreaker extends AbstractBreaker {
return pslm.getPageProvider();
}
- /**
- * Starts the page breaking process.
- * @param flowBPD the constant available block-progression-dimension (used for every part)
- */
- void doLayout(int flowBPD) {
- doLayout(flowBPD, false);
- }
-
/** {@inheritDoc} */
protected PageBreakingLayoutListener createLayoutListener() {
return new PageBreakingLayoutListener() {
diff --git a/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java
index d5949f4a2..4bfbd46f5 100644
--- a/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java
@@ -21,6 +21,10 @@ package org.apache.fop.layoutmgr;
import java.util.LinkedList;
import java.util.List;
+import java.util.ListIterator;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.fop.area.Area;
import org.apache.fop.area.Block;
@@ -31,7 +35,10 @@ import org.apache.fop.fo.pagination.PageSequence;
import org.apache.fop.fo.pagination.SideRegion;
import org.apache.fop.fo.pagination.StaticContent;
import org.apache.fop.layoutmgr.PageBreakingAlgorithm.PageBreakingLayoutListener;
+import org.apache.fop.layoutmgr.inline.InlineLevelLayoutManager;
import org.apache.fop.layoutmgr.inline.TextLayoutManager;
+import org.apache.fop.traits.MinOptMax;
+import org.apache.fop.util.ListUtil;
/**
* LayoutManager for an fo:flow object.
@@ -41,6 +48,11 @@ import org.apache.fop.layoutmgr.inline.TextLayoutManager;
*/
public class StaticContentLayoutManager extends BlockStackingLayoutManager {
+ /**
+ * logging instance
+ */
+ private static Log log = LogFactory.getLog(StaticContentLayoutManager.class);
+
private RegionReference targetRegion;
private Block targetBlock;
private SideRegion regionFO;
@@ -77,7 +89,96 @@ public class StaticContentLayoutManager extends BlockStackingLayoutManager {
/** {@inheritDoc} */
public List getNextKnuthElements(LayoutContext context, int alignment) {
- throw new IllegalStateException();
+ if (true) {
+ throw new UnsupportedOperationException(
+ "Shouldn't this method be emptied because it's never called at all?");
+ }
+ //TODO Empty this method?!?
+ // set layout dimensions
+ setContentAreaIPD(context.getRefIPD());
+ setContentAreaBPD(context.getStackLimitBP().opt);
+
+ //TODO Copied from elsewhere. May be worthwhile to factor out the common parts.
+ // currently active LM
+ BlockLevelLayoutManager curLM;
+ BlockLevelLayoutManager prevLM = null;
+ MinOptMax stackSize = new MinOptMax();
+ List returnedList;
+ List returnList = new LinkedList();
+
+ while ((curLM = ((BlockLevelLayoutManager) getChildLM())) != null) {
+ if (curLM instanceof InlineLevelLayoutManager) {
+ log.error("inline area not allowed under flow - ignoring");
+ curLM.setFinished(true);
+ continue;
+ }
+
+ // Set up a LayoutContext
+ MinOptMax bpd = context.getStackLimitBP();
+
+ LayoutContext childLC = new LayoutContext(0);
+ childLC.setStackLimitBP(MinOptMax.subtract(bpd, stackSize));
+ childLC.setRefIPD(context.getRefIPD());
+
+ // get elements from curLM
+ returnedList = curLM.getNextKnuthElements(childLC, alignment);
+ //log.debug("FLM.getNextKnuthElements> returnedList.size() = "
+ // + returnedList.size());
+
+ // "wrap" the Position inside each element
+ List tempList = returnedList;
+ KnuthElement tempElement;
+ returnedList = new LinkedList();
+ ListIterator listIter = tempList.listIterator();
+ while (listIter.hasNext()) {
+ tempElement = (KnuthElement)listIter.next();
+ tempElement.setPosition(new NonLeafPosition(this, tempElement.getPosition()));
+ returnedList.add(tempElement);
+ }
+
+ if (returnedList.size() == 1
+ && ((KnuthElement)returnedList.get(0)).isPenalty()
+ && ((KnuthPenalty)returnedList.get(0)).getP() == -KnuthElement.INFINITE) {
+ // a descendant of this flow has break-before
+ returnList.addAll(returnedList);
+ return returnList;
+ } else {
+ if (!returnList.isEmpty()) {
+ // there is a block before this one
+ if (prevLM.mustKeepWithNext()
+ || curLM.mustKeepWithPrevious()) {
+ // add an infinite penalty to forbid a break between blocks
+ returnList.add(new KnuthPenalty(0,
+ KnuthElement.INFINITE, false,
+ new Position(this), false));
+ } else if (!((KnuthElement) ListUtil.getLast(returnList))
+ .isGlue()) {
+ // add a null penalty to allow a break between blocks
+ returnList.add(new KnuthPenalty(0, 0, false, new Position(this), false));
+ }
+ }
+/*LF*/ if (!returnedList.isEmpty()) { // controllare!
+ returnList.addAll(returnedList);
+ final KnuthElement last = (KnuthElement) ListUtil
+ .getLast(returnedList);
+ if (last.isPenalty()
+ && ((KnuthPenalty) last).getP() == -KnuthElement.INFINITE) {
+ // a descendant of this flow has break-after
+/*LF*/ //log.debug("FLM - break after!!");
+ return returnList;
+ }
+/*LF*/ }
+ }
+ prevLM = curLM;
+ }
+
+ setFinished(true);
+
+ if (returnList.isEmpty()) {
+ return null;
+ } else {
+ return returnList;
+ }
}
/**
diff --git a/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java
index 95f798161..a5247d652 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java
@@ -27,7 +27,6 @@ import java.util.ListIterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-
import org.apache.fop.area.Area;
import org.apache.fop.area.Block;
import org.apache.fop.area.LineArea;
@@ -44,6 +43,7 @@ import org.apache.fop.layoutmgr.PageSequenceLayoutManager;
import org.apache.fop.layoutmgr.Position;
import org.apache.fop.layoutmgr.PositionIterator;
import org.apache.fop.layoutmgr.SpaceSpecifier;
+import org.apache.fop.traits.MinOptMax;
/**
* Content Layout Manager.
@@ -111,6 +111,8 @@ public class ContentLayoutManager extends AbstractBaseLayoutManager
LayoutContext childLC = new LayoutContext(LayoutContext.NEW_AREA);
childLC.setLeadingSpace(new SpaceSpecifier(false));
childLC.setTrailingSpace(new SpaceSpecifier(false));
+ // set stackLimit for lines
+ childLC.setStackLimitIP(new MinOptMax(ipd));
childLC.setRefIPD(ipd);
int lineHeight = 14000;
@@ -127,7 +129,8 @@ public class ContentLayoutManager extends AbstractBaseLayoutManager
stackSize = 0;
- List contentList = getNextKnuthElements(childLC, Constants.EN_START);
+ List contentList =
+ getNextKnuthElements(childLC, Constants.EN_START);
ListIterator contentIter = contentList.listIterator();
while (contentIter.hasNext()) {
KnuthElement element = (KnuthElement) contentIter.next();
@@ -146,7 +149,8 @@ public class ContentLayoutManager extends AbstractBaseLayoutManager
lc.setFlags(LayoutContext.RESOLVE_LEADING_SPACE, true);
lc.setLeadingSpace(new SpaceSpecifier(false));
lc.setTrailingSpace(new SpaceSpecifier(false));
- KnuthPossPosIter contentPosIter = new KnuthPossPosIter(contentList, 0, contentList.size());
+ KnuthPossPosIter contentPosIter =
+ new KnuthPossPosIter(contentList, 0, contentList.size());
curLM.addAreas(contentPosIter, lc);
}
diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java
index 6e0c34a82..0c332281f 100755
--- a/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java
@@ -248,6 +248,8 @@ public class InlineLayoutManager extends InlineStackingLayoutManager {
List returnList = new LinkedList();
KnuthSequence lastSequence = null;
+ SpaceSpecifier leadingSpace = context.getLeadingSpace();
+
if (fobj instanceof Title) {
alignmentContext = new AlignmentContext(font,
lineHeight.getOptimum(this).getLength().getValue(this),
@@ -272,6 +274,14 @@ public class InlineLayoutManager extends InlineStackingLayoutManager {
if (getSpaceStart() != null) {
context.getLeadingSpace().addSpace(new SpaceVal(getSpaceStart(), this));
}
+
+ // Check for "fence"
+ if (hasLeadingFence(!context.isFirstArea())) {
+ // Reset leading space sequence for child areas
+ leadingSpace = new SpaceSpecifier(false);
+ }
+ // Reset state variables
+ clearPrevIPD(); // Clear stored prev content dimensions
}
StringBuffer trace = new StringBuffer("InlineLM:");
diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java
index 65e59554f..963b98b37 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java
@@ -19,13 +19,12 @@
package org.apache.fop.layoutmgr.inline;
-import java.util.Iterator;
import java.util.LinkedList;
+import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
+import java.util.HashMap;
-import org.apache.fop.area.Area;
-import org.apache.fop.area.inline.Space;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.properties.SpaceProperty;
import org.apache.fop.layoutmgr.AbstractLayoutManager;
@@ -35,6 +34,8 @@ import org.apache.fop.layoutmgr.LayoutManager;
import org.apache.fop.layoutmgr.NonLeafPosition;
import org.apache.fop.layoutmgr.Position;
import org.apache.fop.layoutmgr.PositionIterator;
+import org.apache.fop.area.Area;
+import org.apache.fop.area.inline.Space;
import org.apache.fop.traits.MinOptMax;
/**
@@ -61,6 +62,12 @@ public abstract class InlineStackingLayoutManager extends AbstractLayoutManager
}
}
+
+ /**
+ * Size of any start or end borders and padding.
+ */
+ private MinOptMax allocIPD = new MinOptMax(0);
+
/**
* Size of border and padding in BPD (ie, before and after).
*/
@@ -71,6 +78,9 @@ public abstract class InlineStackingLayoutManager extends AbstractLayoutManager
/** The child layout context */
protected LayoutContext childLC;
+ /** Used to store previous content IPD for each child LM. */
+ private HashMap hmPrevIPD = new HashMap();
+
/**
* Create an inline stacking layout manager.
* This is used for fo's that create areas that
@@ -139,6 +149,22 @@ public abstract class InlineStackingLayoutManager extends AbstractLayoutManager
}
/**
+ * TODO: Explain this method
+ * @param lm ???
+ * @return ???
+ */
+ protected MinOptMax getPrevIPD(LayoutManager lm) {
+ return (MinOptMax) hmPrevIPD.get(lm);
+ }
+
+ /**
+ * Clear the previous IPD calculation.
+ */
+ protected void clearPrevIPD() {
+ hmPrevIPD.clear();
+ }
+
+ /**
* Returns the current area.
* @return the current area
*/
diff --git a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
index 95bc9ab2d..aea851f54 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
@@ -116,8 +116,8 @@ public class LineLayoutManager extends InlineStackingLayoutManager
* inline break positions.
*/
private static class LineBreakPosition extends LeafPosition {
- private int parIndex; // index of the Paragraph this Position refers to
- private int startIndex; //index of the first element this Position refers to
+ private int iParIndex; // index of the Paragraph this Position refers to
+ private int iStartIndex; //index of the first element this Position refers to
private int availableShrink;
private int availableStretch;
private int difference;
@@ -130,16 +130,16 @@ public class LineLayoutManager extends InlineStackingLayoutManager
private int spaceAfter;
private int baseline;
- LineBreakPosition(LayoutManager lm, int index, int startIndex, int breakIndex,
+ LineBreakPosition(LayoutManager lm, int index, int iStartIndex, int iBreakIndex,
int shrink, int stretch, int diff,
double ipdA, double adjust, int ind,
int lh, int lw, int sb, int sa, int bl) {
- super(lm, breakIndex);
+ super(lm, iBreakIndex);
availableShrink = shrink;
availableStretch = stretch;
difference = diff;
- parIndex = index;
- this.startIndex = startIndex;
+ iParIndex = index;
+ this.iStartIndex = iStartIndex;
ipdAdjust = ipdA;
dAdjust = adjust;
startIndent = ind;
@@ -167,13 +167,18 @@ public class LineLayoutManager extends InlineStackingLayoutManager
private Length lineHeight;
private int lead;
private int follow;
- private AlignmentContext alignmentContext;
+ private AlignmentContext alignmentContext = null;
- private List knuthParagraphs;
+ private List knuthParagraphs = null;
+ private int iReturnedLBP = 0;
+
+ // parameters of Knuth's algorithm:
+ // penalty value for flagged penalties
+ private int flaggedPenalty = 50;
private LineLayoutPossibilities lineLayouts;
private List lineLayoutsList;
- private int ipd = 0;
+ private int iLineWidth = 0;
/**
* this constant is used to create elements when text-align is center:
@@ -233,7 +238,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
} else {
lineFiller = new MinOptMax(lastLineEndIndent,
lastLineEndIndent,
- layoutManager.ipd);
+ layoutManager.iLineWidth);
}
// add auxiliary elements at the beginning of the paragraph
@@ -314,9 +319,11 @@ public class LineLayoutManager extends InlineStackingLayoutManager
private int activePossibility;
private int addedPositions;
private int textIndent;
+ private int fillerMinWidth;
private int lineHeight;
private int lead;
private int follow;
+ private int maxDiff;
private static final double MAX_DEMERITS = 10e6;
public LineBreakingAlgorithm (int pageAlign,
@@ -327,17 +334,22 @@ public class LineLayoutManager extends InlineStackingLayoutManager
super(textAlign, textAlignLast, first, false, maxFlagCount);
pageAlignment = pageAlign;
textIndent = indent;
+ fillerMinWidth = fillerWidth;
lineHeight = lh;
lead = ld;
follow = fl;
thisLLM = llm;
activePossibility = -1;
+ maxDiff = fobj.getWidows() >= fobj.getOrphans()
+ ? fobj.getWidows()
+ : fobj.getOrphans();
}
public void updateData1(int lineCount, double demerits) {
lineLayouts.addPossibility(lineCount, demerits);
- if (log.isTraceEnabled()) {
- log.trace("Layout possibility in " + lineCount + " lines; break at position:");
+ if (super.log.isTraceEnabled()) {
+ super.log.trace(
+ "Layout possibility in " + lineCount + " lines; break at position:");
}
}
@@ -418,7 +430,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
// true if this line contains only zero-height, auxiliary boxes
// and the actual line width is 0; in this case, the line "collapses"
// i.e. the line area will have bpd = 0
- boolean bZeroHeightLine = (difference == ipd);
+ boolean bZeroHeightLine = (difference == iLineWidth);
// if line-stacking-strategy is "font-height", the line height
// is not affected by its content
@@ -474,7 +486,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
firstElementIndex, lastElementIndex,
availableShrink, availableStretch,
difference, ratio, 0, indent,
- 0, ipd, 0, 0, 0);
+ 0, iLineWidth, 0, 0, 0);
} else {
return new LineBreakPosition(thisLLM,
knuthParagraphs.indexOf(par),
@@ -482,7 +494,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
availableShrink, availableStretch,
difference, ratio, 0, indent,
lineLead + lineFollow,
- ipd, spaceBefore, spaceAfter,
+ iLineWidth, spaceBefore, spaceAfter,
lineLead);
}
}
@@ -566,12 +578,14 @@ public class LineLayoutManager extends InlineStackingLayoutManager
FontInfo fi = fobj.getFOEventHandler().getFontInfo();
FontTriplet[] fontkeys = fobj.getCommonFont().getFontState(fi);
Font fs = fi.getFontInstance(fontkeys[0], fobj.getCommonFont().fontSize.getValue(this));
- alignmentContext = new AlignmentContext(fs, lineHeight.getValue(this),
- context.getWritingMode());
+ alignmentContext
+ = new AlignmentContext(fs, lineHeight.getValue(this), context.getWritingMode());
context.setAlignmentContext(alignmentContext);
// Get a break from currently active child LM
// Set up constraints for inline level managers
+ clearPrevIPD();
+
//PHASE 1: Create Knuth elements
if (knuthParagraphs == null) {
// it's the first time this method is called
@@ -592,6 +606,34 @@ public class LineLayoutManager extends InlineStackingLayoutManager
//PHASE 2: Create line breaks
return createLineBreaks(context.getBPAlignment(), context);
+ /*
+ LineBreakPosition lbp = null;
+ if (breakpoints == null) {
+ // find the optimal line breaking points for each paragraph
+ breakpoints = new ArrayList();
+ ListIterator paragraphsIterator
+ = knuthParagraphs.listIterator(knuthParagraphs.size());
+ Paragraph currPar = null;
+ while (paragraphsIterator.hasPrevious()) {
+ currPar = (Paragraph) paragraphsIterator.previous();
+ findBreakingPoints(currPar, context.getStackLimit().opt);
+ }
+ }*/
+
+ //PHASE 3: Return lines
+
+ /*
+ // get a break point from the list
+ lbp = (LineBreakPosition) breakpoints.get(iReturnedLBP ++);
+ if (iReturnedLBP == breakpoints.size()) {
+ setFinished(true);
+ }
+
+ BreakPoss curLineBP = new BreakPoss(lbp);
+ curLineBP.setFlag(BreakPoss.ISLAST, isFinished());
+ curLineBP.setStackingSize(new MinOptMax(lbp.lineHeight));
+ return curLineBP;
+ */
}
/**
@@ -601,20 +643,22 @@ public class LineLayoutManager extends InlineStackingLayoutManager
private void collectInlineKnuthElements(LayoutContext context) {
LayoutContext inlineLC = new LayoutContext(context);
- ipd = context.getRefIPD();
+ InlineLevelLayoutManager curLM;
+ List returnedList = null;
+ iLineWidth = context.getStackLimitIP().opt;
// convert all the text in a sequence of paragraphs made
// of KnuthBox, KnuthGlue and KnuthPenalty objects
- boolean previousIsBox = false;
+ boolean bPrevWasKnuthBox = false;
StringBuffer trace = new StringBuffer("LineLM:");
Paragraph lastPar = null;
- InlineLevelLayoutManager curLM;
while ((curLM = (InlineLevelLayoutManager) getChildLM()) != null) {
- List inlineElements = curLM.getNextKnuthElements(inlineLC, effectiveAlignment);
- if (inlineElements == null || inlineElements.size() == 0) {
+ returnedList = curLM.getNextKnuthElements(inlineLC, effectiveAlignment);
+ if (returnedList == null
+ || returnedList.size() == 0) {
/* curLM.getNextKnuthElements() returned null or an empty list;
* this can happen if there is nothing more to layout,
* so just iterate once more to see if there are other children */
@@ -622,7 +666,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
}
if (lastPar != null) {
- KnuthSequence firstSeq = (KnuthSequence) inlineElements.get(0);
+ KnuthSequence firstSeq = (KnuthSequence) returnedList.get(0);
// finish last paragraph before a new block sequence
if (!firstSeq.isInlineSequence()) {
@@ -632,7 +676,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
if (log.isTraceEnabled()) {
trace.append(" ]");
}
- previousIsBox = false;
+ bPrevWasKnuthBox = false;
}
// does the first element of the first paragraph add to an existing word?
@@ -640,24 +684,27 @@ public class LineLayoutManager extends InlineStackingLayoutManager
KnuthElement thisElement;
thisElement = (KnuthElement) firstSeq.get(0);
if (thisElement.isBox() && !thisElement.isAuxiliary()
- && previousIsBox) {
+ && bPrevWasKnuthBox) {
lastPar.addALetterSpace();
}
}
}
// loop over the KnuthSequences (and single KnuthElements) in returnedList
- ListIterator iter = inlineElements.listIterator();
+ ListIterator iter = returnedList.listIterator();
while (iter.hasNext()) {
KnuthSequence sequence = (KnuthSequence) iter.next();
// the sequence contains inline Knuth elements
if (sequence.isInlineSequence()) {
// look at the last element
ListElement lastElement = sequence.getLast();
- assert lastElement != null;
- previousIsBox = lastElement.isBox()
- && !((KnuthElement) lastElement).isAuxiliary()
- && ((KnuthElement) lastElement).getW() != 0;
+ if (lastElement == null) {
+ throw new NullPointerException(
+ "Sequence was empty! lastElement is null");
+ }
+ bPrevWasKnuthBox = lastElement.isBox()
+ && !((KnuthElement) lastElement).isAuxiliary()
+ && ((KnuthElement) lastElement).getW() != 0;
// if last paragraph is open, add the new elements to the paragraph
// else this is the last paragraph
@@ -682,7 +729,8 @@ public class LineLayoutManager extends InlineStackingLayoutManager
// finish last paragraph if it was closed with a linefeed
if (lastElement.isPenalty()
- && ((KnuthPenalty) lastElement).getP() == -KnuthPenalty.INFINITE) {
+ && ((KnuthPenalty) lastElement).getP()
+ == -KnuthPenalty.INFINITE) {
// a penalty item whose value is -inf
// represents a preserved linefeed,
// which forces a line break
@@ -690,7 +738,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
if (!lastPar.containsBox()) {
//only a forced linefeed on this line
//-> compensate with an auxiliary glue
- lastPar.add(new KnuthGlue(ipd, 0, ipd, null, true));
+ lastPar.add(new KnuthGlue(iLineWidth, 0, iLineWidth, null, true));
}
lastPar.endParagraph();
ElementListObserver.observe(lastPar, "line", null);
@@ -698,7 +746,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
if (log.isTraceEnabled()) {
trace.append(" ]");
}
- previousIsBox = false;
+ bPrevWasKnuthBox = false;
}
} else { // the sequence is a block sequence
// the positions will be wrapped with this LM in postProcessLineBreaks
@@ -720,14 +768,144 @@ public class LineLayoutManager extends InlineStackingLayoutManager
}
/**
+ * Find a set of breaking points.
+ * This method is called only once by getNextBreakPoss, and it
+ * subsequently calls the other findBreakingPoints() method with
+ * different parameters, until a set of breaking points is found.
+ *
+ * @param par the list of elements that must be parted
+ * into lines
+ * @param lineWidth the desired length ot the lines
+ */
+ /*
+ private void findBreakingPoints(Paragraph par, int lineWidth) {
+ // maximum adjustment ratio permitted
+ float maxAdjustment = 1;
+
+ // first try
+ if (!findBreakingPoints(par, lineWidth, maxAdjustment, false)) {
+ // the first try failed, now try something different
+ log.debug("No set of breaking points found with maxAdjustment = " + maxAdjustment);
+ if (hyphenationProperties.hyphenate == Constants.EN_TRUE) {
+ // consider every hyphenation point as a legal break
+ findHyphenationPoints(par);
+ } else {
+ // try with a higher threshold
+ maxAdjustment = 5;
+ }
+
+ if (!findBreakingPoints(par, lineWidth, maxAdjustment, false)) {
+ // the second try failed too, try with a huge threshold;
+ // if this fails too, use a different algorithm
+ log.debug("No set of breaking points found with maxAdjustment = " + maxAdjustment
+ + (hyphenationProperties.hyphenate == Constants.EN_TRUE ? " and hyphenation" : ""));
+ maxAdjustment = 20;
+ if (!findBreakingPoints(par, lineWidth, maxAdjustment, true)) {
+ log.debug("No set of breaking points found, using first-fit algorithm");
+ }
+ }
+ }
+ }
+
+ private boolean findBreakingPoints(Paragraph par, int lineWidth,
+ double threshold, boolean force) {
+ KnuthParagraph knuthPara = new KnuthParagraph(par);
+ int lines = knuthPara.findBreakPoints(lineWidth, threshold, force);
+ if (lines == 0) {
+ return false;
+ }
+
+ for (int i = lines-1; i >= 0; i--) {
+ int line = i+1;
+ if (log.isTraceEnabled()) {
+ log.trace("Making line from " + knuthPara.getStart(i) + " to " +
+ knuthPara.getEnd(i));
+ }
+ // compute indent and adjustment ratio, according to
+ // the value of text-align and text-align-last
+
+ int difference = knuthPara.getDifference(i);
+ if (line == lines) {
+ difference += par.lineFillerWidth;
+ }
+ int textAlign = (line < lines)
+ ? textAlignment : textAlignmentLast;
+ int indent = (textAlign == EN_CENTER)
+ ? difference / 2
+ : (textAlign == EN_END) ? difference : 0;
+ indent += (line == 1 && knuthParagraphs.indexOf(par) == 0)
+ ? textIndent.getValue(this) : 0;
+ double ratio = (textAlign == EN_JUSTIFY)
+ ? knuthPara.getAdjustRatio(i) : 0;
+
+ int start = knuthPara.getStart(i);
+ int end = knuthPara.getEnd(i);
+ makeLineBreakPosition(par, start, end, 0, ratio, indent);
+ }
+ return true;
+ }
+
+ private void makeLineBreakPosition(Paragraph par,
+ int firstElementIndex, int lastElementIndex,
+ int insertIndex, double ratio, int indent) {
+ // line height calculation
+
+ int halfLeading = (lineHeight - lead - follow) / 2;
+ // height above the main baseline
+ int lineLead = lead + halfLeading;
+ // maximum size of top and bottom alignment
+ int lineFollow = follow + halfLeading;
+
+ ListIterator inlineIterator
+ = par.listIterator(firstElementIndex);
+ for (int j = firstElementIndex;
+ j <= lastElementIndex;
+ j++) {
+ KnuthElement element = (KnuthElement) inlineIterator.next();
+ if (element.isBox()) {
+ KnuthInlineBox box = (KnuthInlineBox)element;
+ if (box.getLead() > lineLead) {
+ lineLead = box.getLead();
+ }
+ if (box.getTotal() > lineFollow) {
+ lineFollow = box.getTotal();
+ }
+ if (box.getMiddle() > lineLead + middleShift) {
+ lineLead += box.getMiddle()
+ - lineLead - middleShift;
+ }
+ if (box.getMiddle() > middlefollow - middleShift) {
+ middlefollow += box.getMiddle()
+ - middlefollow + middleShift;
+ }
+ }
+ }
+
+ if (lineFollow - lineLead > middlefollow) {
+ middlefollow = lineFollow - lineLead;
+ }
+
+ breakpoints.add(insertIndex,
+ new LineBreakPosition(this,
+ knuthParagraphs.indexOf(par),
+ lastElementIndex ,
+ ratio, 0, indent,
+ lineLead + middlefollow,
+ lineLead));
+ }*/
+
+
+ /**
* Phase 2 of Knuth algorithm: find optimal break points.
* @param alignment alignment in BP direction of the paragraph
* @param context the layout context
* @return a list of Knuth elements representing broken lines
*/
private List createLineBreaks(int alignment, LayoutContext context) {
+
// find the optimal line breaking points for each paragraph
- ListIterator paragraphsIterator = knuthParagraphs.listIterator(knuthParagraphs.size());
+ ListIterator paragraphsIterator
+ = knuthParagraphs.listIterator(knuthParagraphs.size());
lineLayoutsList = new ArrayList(knuthParagraphs.size());
LineLayoutPossibilities llPoss;
while (paragraphsIterator.hasPrevious()) {
@@ -780,7 +958,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
} else {
allowedBreaks = BreakingAlgorithm.NO_FLAGGED_PENALTIES;
}
- alg.setConstantLineWidth(ipd);
+ alg.setConstantLineWidth(iLineWidth);
iBPcount = alg.findBreakingPoints(currPar,
maxAdjustment, false, allowedBreaks);
if (iBPcount == 0 || alignment == EN_JUSTIFY) {
@@ -836,26 +1014,26 @@ public class LineLayoutManager extends InlineStackingLayoutManager
alg.resetAlgorithm();
lineLayouts.savePossibilities(true);
// try with shorter lines
- int savedLineWidth = ipd;
- ipd = (int) (ipd * 0.95);
+ int savedLineWidth = iLineWidth;
+ iLineWidth = (int) (iLineWidth * 0.95);
iBPcount = alg.findBreakingPoints(currPar,
- maxAdjustment, true, allowedBreaks);
+ maxAdjustment, true, allowedBreaks);
// use normal lines, when possible
lineLayouts.restorePossibilities();
- ipd = savedLineWidth;
+ iLineWidth = savedLineWidth;
}
if (!lineLayouts.canUseLessLines()) {
alg.resetAlgorithm();
lineLayouts.savePossibilities(true);
// try with longer lines
- int savedLineWidth = ipd;
- ipd = (int) (ipd * 1.05);
- alg.setConstantLineWidth(ipd);
+ int savedLineWidth = iLineWidth;
+ iLineWidth = (int) (iLineWidth * 1.05);
+ alg.setConstantLineWidth(iLineWidth);
iBPcount = alg.findBreakingPoints(currPar,
maxAdjustment, true, allowedBreaks);
// use normal lines, when possible
lineLayouts.restorePossibilities();
- ipd = savedLineWidth;
+ iLineWidth = savedLineWidth;
}
//log.debug("LLM.getNextKnuthElements> now, layouts with more lines? " + lineLayouts.canUseMoreLines());
//log.debug(" now, layouts with fewer lines? " + lineLayouts.canUseLessLines());
@@ -937,14 +1115,15 @@ public class LineLayoutManager extends InlineStackingLayoutManager
while (elementIterator.nextIndex() <= endIndex) {
KnuthElement element = (KnuthElement) elementIterator.next();
if (element instanceof KnuthInlineBox
- && ((KnuthInlineBox) element).isAnchor()) {
+ && ((KnuthInlineBox) element).isAnchor()) {
footnoteList.add(((KnuthInlineBox) element).getFootnoteBodyLM());
} else if (element instanceof KnuthBlockBox) {
footnoteList.addAll(((KnuthBlockBox) element).getFootnoteBodyLMs());
}
}
startIndex = endIndex + 1;
- LineBreakPosition lbp = (LineBreakPosition) llPoss.getChosenPosition(i);
+ LineBreakPosition lbp
+ = (LineBreakPosition) llPoss.getChosenPosition(i);
returnList.add(new KnuthBlockBox
(lbp.lineHeight + lbp.spaceBefore + lbp.spaceAfter,
footnoteList, lbp, false));
@@ -1418,7 +1597,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
Position pos = (Position) parentIter.next();
boolean isLastPosition = !parentIter.hasNext();
if (pos instanceof LineBreakPosition) {
- addInlineArea(context, (LineBreakPosition) pos, isLastPosition);
+ addInlineArea(context, pos, isLastPosition);
} else if ((pos instanceof NonLeafPosition) && pos.generatesAreas()) {
addBlockArea(context, pos, isLastPosition);
} else {
@@ -1438,129 +1617,147 @@ public class LineLayoutManager extends InlineStackingLayoutManager
* @param pos the position for which the line is generated
* @param isLastPosition true if this is the last position of this LM
*/
- private void addInlineArea(LayoutContext context, LineBreakPosition lbp,
- boolean isLastPosition) {
- // the TLM which created the last KnuthElement in this line
- LayoutManager lastLM = null;
-
- KnuthSequence seq = (KnuthSequence) knuthParagraphs.get(lbp.parIndex);
- int startElementIndex = lbp.startIndex;
- int endElementIndex = lbp.getLeafPos();
-
- LineArea lineArea = new LineArea(
- (lbp.getLeafPos() < seq.size() - 1 ? textAlignment : textAlignmentLast),
- lbp.difference, lbp.availableStretch, lbp.availableShrink);
- if (lbp.startIndent != 0) {
- lineArea.addTrait(Trait.START_INDENT, new Integer(lbp.startIndent));
- }
- lineArea.setBPD(lbp.lineHeight);
- lineArea.setIPD(lbp.lineWidth);
- lineArea.addTrait(Trait.SPACE_BEFORE, new Integer(lbp.spaceBefore));
- lineArea.addTrait(Trait.SPACE_AFTER, new Integer(lbp.spaceAfter));
- alignmentContext.resizeLine(lbp.lineHeight, lbp.baseline);
-
- if (seq instanceof Paragraph) {
- Paragraph currPar = (Paragraph) seq;
- // ignore the first elements added by the LineLayoutManager
- startElementIndex += (startElementIndex == 0) ? currPar.ignoreAtStart : 0;
-
- // if this is the last line area that for this paragraph,
- // ignore the last elements added by the LineLayoutManager and
- // subtract the last-line-end-indent from the area ipd
- if (endElementIndex == (currPar.size() - 1)) {
- endElementIndex -= currPar.ignoreAtEnd;
- lineArea.setIPD(lineArea.getIPD() - lastLineEndIndent.getValue(this));
+ private void addInlineArea(LayoutContext context, Position pos, boolean isLastPosition) {
+ ListIterator seqIterator = null;
+ KnuthElement tempElement = null;
+ // the TLM which created the last KnuthElement in this line
+ LayoutManager lastLM = null;
+
+ LineBreakPosition lbp = (LineBreakPosition) pos;
+ int iCurrParIndex;
+ iCurrParIndex = lbp.iParIndex;
+ KnuthSequence seq = (KnuthSequence) knuthParagraphs.get(iCurrParIndex);
+ int iStartElement = lbp.iStartIndex;
+ int iEndElement = lbp.getLeafPos();
+
+ LineArea lineArea
+ = new LineArea((lbp.getLeafPos() < seq.size() - 1
+ ? textAlignment : textAlignmentLast),
+ lbp.difference, lbp.availableStretch, lbp.availableShrink);
+ if (lbp.startIndent != 0) {
+ lineArea.addTrait(Trait.START_INDENT, new Integer(lbp.startIndent));
+ }
+ lineArea.setBPD(lbp.lineHeight);
+ lineArea.setIPD(lbp.lineWidth);
+ lineArea.addTrait(Trait.SPACE_BEFORE, new Integer(lbp.spaceBefore));
+ lineArea.addTrait(Trait.SPACE_AFTER, new Integer(lbp.spaceAfter));
+ alignmentContext.resizeLine(lbp.lineHeight, lbp.baseline);
+
+ if (seq instanceof Paragraph) {
+ Paragraph currPar = (Paragraph) seq;
+ // ignore the first elements added by the LineLayoutManager
+ iStartElement += (iStartElement == 0) ? currPar.ignoreAtStart : 0;
+
+ // if this is the last line area that for this paragraph,
+ // ignore the last elements added by the LineLayoutManager and
+ // subtract the last-line-end-indent from the area ipd
+ if (iEndElement == (currPar.size() - 1)) {
+ iEndElement -= currPar.ignoreAtEnd;
+ lineArea.setIPD(lineArea.getIPD() - lastLineEndIndent.getValue(this));
+ }
}
- }
- // Remove trailing spaces if allowed so
- if (whiteSpaceTreament == EN_IGNORE_IF_SURROUNDING_LINEFEED
+ // Remove trailing spaces if allowed so
+ if (whiteSpaceTreament == EN_IGNORE_IF_SURROUNDING_LINEFEED
|| whiteSpaceTreament == EN_IGNORE
|| whiteSpaceTreament == EN_IGNORE_IF_BEFORE_LINEFEED) {
- // ignore the last element in the line if it is a KnuthGlue object
- ListIterator seqIterator = seq.listIterator(endElementIndex);
- KnuthElement lastElement = (KnuthElement) seqIterator.next();
- lastLM = lastElement.getLayoutManager();
- if (lastElement.isGlue()) {
- endElementIndex--;
- // this returns the same KnuthElement
- seqIterator.previous();
- if (seqIterator.hasPrevious()) {
- lastLM = ((KnuthElement) seqIterator.previous()).getLayoutManager();
+ // ignore the last element in the line if it is a KnuthGlue object
+ seqIterator = seq.listIterator(iEndElement);
+ tempElement = (KnuthElement) seqIterator.next();
+ if (tempElement.isGlue()) {
+ iEndElement--;
+ // this returns the same KnuthElement
+ seqIterator.previous();
+ if (seqIterator.hasPrevious()) {
+ tempElement = (KnuthElement) seqIterator.previous();
+ } else {
+ tempElement = null;
+ }
+ }
+ if (tempElement != null) {
+ lastLM = tempElement.getLayoutManager();
}
}
- }
- // Remove leading spaces if allowed so
- if (whiteSpaceTreament == EN_IGNORE_IF_SURROUNDING_LINEFEED
+ // Remove leading spaces if allowed so
+ if (whiteSpaceTreament == EN_IGNORE_IF_SURROUNDING_LINEFEED
|| whiteSpaceTreament == EN_IGNORE
|| whiteSpaceTreament == EN_IGNORE_IF_AFTER_LINEFEED) {
- // ignore KnuthGlue and KnuthPenalty objects
- // at the beginning of the line
- ListIterator seqIterator = seq.listIterator(startElementIndex);
- while (seqIterator.hasNext() && !((KnuthElement) seqIterator.next()).isBox()) {
- startElementIndex++;
+ // ignore KnuthGlue and KnuthPenalty objects
+ // at the beginning of the line
+ seqIterator = seq.listIterator(iStartElement);
+ tempElement = (KnuthElement) seqIterator.next();
+ while (!tempElement.isBox() && seqIterator.hasNext()) {
+ tempElement = (KnuthElement) seqIterator.next();
+ iStartElement++;
+ }
}
- }
- // Add the inline areas to lineArea
- PositionIterator inlinePosIter = new KnuthPossPosIter(seq, startElementIndex,
- endElementIndex + 1);
-
- LayoutContext lc = new LayoutContext(0);
- lc.setAlignmentContext(alignmentContext);
- lc.setSpaceAdjust(lbp.dAdjust);
- lc.setIPDAdjust(lbp.ipdAdjust);
- lc.setLeadingSpace(new SpaceSpecifier(true));
- lc.setTrailingSpace(new SpaceSpecifier(false));
- lc.setFlags(LayoutContext.RESOLVE_LEADING_SPACE, true);
-
- /*
- * extension (not in the XSL FO recommendation): if the left and right margins
- * have been optimized, recompute indents and / or adjust ratio, according
- * to the paragraph horizontal alignment
- */
- if (false && textAlignment == EN_JUSTIFY) {
- // re-compute space adjust ratio
- int updatedDifference = context.getRefIPD()
- - lbp.lineWidth + lbp.difference;
- double updatedRatio = 0.0;
- if (updatedDifference > 0) {
- updatedRatio = (float) updatedDifference / lbp.availableStretch;
- } else if (updatedDifference < 0) {
- updatedRatio = (float) updatedDifference / lbp.availableShrink;
+ // Add the inline areas to lineArea
+ PositionIterator inlinePosIter
+ = new KnuthPossPosIter(seq, iStartElement, iEndElement + 1);
+
+ iStartElement = lbp.getLeafPos() + 1;
+ if (iStartElement == seq.size()) {
+ // advance to next paragraph
+ iStartElement = 0;
}
- lc.setIPDAdjust(updatedRatio);
- //log.debug("LLM.addAreas> old difference = " + lbp.difference + " new difference = " + updatedDifference);
- //log.debug(" old ratio = " + lbp.ipdAdjust + " new ratio = " + updatedRatio);
- } else if (false && textAlignment == EN_CENTER) {
- // re-compute indent
- int updatedIndent = lbp.startIndent
- + (context.getRefIPD() - lbp.lineWidth) / 2;
- lineArea.addTrait(Trait.START_INDENT, new Integer(updatedIndent));
- } else if (false && textAlignment == EN_END) {
- // re-compute indent
- int updatedIndent = lbp.startIndent
- + (context.getRefIPD() - lbp.lineWidth);
- lineArea.addTrait(Trait.START_INDENT, new Integer(updatedIndent));
- }
- setCurrentArea(lineArea);
- setChildContext(lc);
- LayoutManager childLM;
- while ((childLM = inlinePosIter.getNextChildLM()) != null) {
- lc.setFlags(LayoutContext.LAST_AREA, (childLM == lastLM));
- childLM.addAreas(inlinePosIter, lc);
- lc.setLeadingSpace(lc.getTrailingSpace());
+ LayoutContext lc = new LayoutContext(0);
+ lc.setAlignmentContext(alignmentContext);
+ lc.setSpaceAdjust(lbp.dAdjust);
+ lc.setIPDAdjust(lbp.ipdAdjust);
+ lc.setLeadingSpace(new SpaceSpecifier(true));
lc.setTrailingSpace(new SpaceSpecifier(false));
- }
+ lc.setFlags(LayoutContext.RESOLVE_LEADING_SPACE, true);
+
+ /*
+ * extension (not in the XSL FO recommendation): if the left and right margins
+ * have been optimized, recompute indents and / or adjust ratio, according
+ * to the paragraph horizontal alignment
+ */
+ if (false && textAlignment == EN_JUSTIFY) {
+ // re-compute space adjust ratio
+ int updatedDifference = context.getStackLimitIP().opt
+ - lbp.lineWidth + lbp.difference;
+ double updatedRatio = 0.0;
+ if (updatedDifference > 0) {
+ updatedRatio = (float) updatedDifference / lbp.availableStretch;
+ } else if (updatedDifference < 0) {
+ updatedRatio = (float) updatedDifference / lbp.availableShrink;
+ }
+ lc.setIPDAdjust(updatedRatio);
+ //log.debug("LLM.addAreas> old difference = " + lbp.difference + " new difference = " + updatedDifference);
+ //log.debug(" old ratio = " + lbp.ipdAdjust + " new ratio = " + updatedRatio);
+ } else if (false && textAlignment == EN_CENTER) {
+ // re-compute indent
+ int updatedIndent = lbp.startIndent
+ + (context.getStackLimitIP().opt - lbp.lineWidth) / 2;
+ lineArea.addTrait(Trait.START_INDENT, new Integer(updatedIndent));
+ } else if (false && textAlignment == EN_END) {
+ // re-compute indent
+ int updatedIndent = lbp.startIndent
+ + (context.getStackLimitIP().opt - lbp.lineWidth);
+ lineArea.addTrait(Trait.START_INDENT, new Integer(updatedIndent));
+ }
- // if display-align is distribute, add space after
- if (context.getSpaceAfter() > 0
- && (!context.isLastArea() || !isLastPosition)) {
- lineArea.setBPD(lineArea.getBPD() + context.getSpaceAfter());
- }
- lineArea.finalise();
- parentLM.addChildArea(lineArea);
+ setCurrentArea(lineArea);
+ setChildContext(lc);
+ LayoutManager childLM;
+ while ((childLM = inlinePosIter.getNextChildLM()) != null) {
+ lc.setFlags(LayoutContext.LAST_AREA, (childLM == lastLM));
+ childLM.addAreas(inlinePosIter, lc);
+ lc.setLeadingSpace(lc.getTrailingSpace());
+ lc.setTrailingSpace(new SpaceSpecifier(false));
+ }
+
+ // when can this be null?
+ // if display-align is distribute, add space after
+ if (context.getSpaceAfter() > 0
+ && (!context.isLastArea() || !isLastPosition)) {
+ lineArea.setBPD(lineArea.getBPD() + context.getSpaceAfter());
+ }
+ lineArea.finalise();
+ parentLM.addChildArea(lineArea);
}
/**
@@ -1603,7 +1800,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
// set last area flag
blocklc.setFlags(LayoutContext.LAST_AREA,
(context.isLastArea() && childLM == lastLM));
- blocklc.setStackLimitBP(context.getStackLimitBP());
+ blocklc.setStackLimitsFrom(context);
// Add the line areas to Area
childLM.addAreas(childPosIter, blocklc);
blocklc.setLeadingSpace(blocklc.getTrailingSpace());