aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java')
-rw-r--r--src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java213
1 files changed, 132 insertions, 81 deletions
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;
}
/**