aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache
diff options
context:
space:
mode:
authorJeremias Maerki <jeremias@apache.org>2005-05-24 09:41:32 +0000
committerJeremias Maerki <jeremias@apache.org>2005-05-24 09:41:32 +0000
commit9b3c25d9daff658a9144330172f58cfd4688eca3 (patch)
treee4648b25f0068defbf8e73903aed3bdfa0e1970a /src/java/org/apache
parent1af57e403ba314e8acc33bb696b140bb3f9ccafa (diff)
downloadxmlgraphics-fop-9b3c25d9daff658a9144330172f58cfd4688eca3.tar.gz
xmlgraphics-fop-9b3c25d9daff658a9144330172f58cfd4688eca3.zip
Modify keep-with-next and keep-with-previous handling to support "level-hopping" (see keep-with-next1a and keep-with-previous1a)
Full keep handling for tables (there's a remaning problem with keep-with-previous) keep-together support for lists. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@198683 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache')
-rw-r--r--src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java23
-rw-r--r--src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java16
-rw-r--r--src/java/org/apache/fop/layoutmgr/list/Item.java46
-rw-r--r--src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java56
-rw-r--r--src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java70
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/Cell.java20
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/GridUnit.java4
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java27
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java8
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/TableStepper.java44
10 files changed, 251 insertions, 63 deletions
diff --git a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
index 550099cd0..23a5a02bd 100644
--- a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
@@ -234,6 +234,10 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
// get elements from curLM
returnedList = curLM.getNextKnuthElements(childLC, alignment);
+ if (contentList.size() == 0 && childLC.isKeepWithPreviousPending()) {
+ context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
+ childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false);
+ }
if (returnedList != null
&& returnedList.size() == 1
&& ((KnuthElement) returnedList.getFirst()).isPenalty()
@@ -267,8 +271,11 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
// there is a block handled by prevLM
// before the one handled by curLM
if (mustKeepTogether()
- || prevLM.mustKeepWithNext()
- || curLM.mustKeepWithPrevious()) {
+ || context.isKeepWithNextPending()
+ || childLC.isKeepWithPreviousPending()) {
+ //Clear keep pending flag
+ context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false);
+ childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false);
// add an infinite penalty to forbid a break between
// blocks
contentList.add(new KnuthPenalty(0,
@@ -317,6 +324,11 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
return returnList;
}*/
}
+ if (childLC.isKeepWithNextPending()) {
+ //Clear and propagate
+ childLC.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false);
+ context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING);
+ }
prevLM = curLM;
}
@@ -339,6 +351,13 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
addKnuthElementsForSpaceAfter(returnList, returnPosition, alignment);
addKnuthElementsForBreakAfter(returnList, returnPosition);
+ if (mustKeepWithNext()) {
+ context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING);
+ }
+ if (mustKeepWithPrevious()) {
+ context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
+ }
+
setFinished(true);
return returnList;
diff --git a/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java
index 3399d05e6..5a69104f3 100644
--- a/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java
@@ -106,6 +106,10 @@ public class FlowLayoutManager extends BlockStackingLayoutManager
// get elements from curLM
returnedList = curLM.getNextKnuthElements(childLC, alignment);
//log.debug("FLM.getNextKnuthElements> returnedList.size() = " + returnedList.size());
+ if (returnList.size() == 0 && childLC.isKeepWithPreviousPending()) {
+ context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
+ childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false);
+ }
// "wrap" the Position inside each element
LinkedList tempList = returnedList;
@@ -121,8 +125,11 @@ public class FlowLayoutManager extends BlockStackingLayoutManager
} else {
if (returnList.size() > 0) {
// there is a block before this one
- if (prevLM.mustKeepWithNext()
- || curLM.mustKeepWithPrevious()) {
+ if (context.isKeepWithNextPending()
+ || childLC.isKeepWithPreviousPending()) {
+ //Clear pending keep flag
+ context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false);
+ childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false);
// add an infinite penalty to forbid a break between blocks
returnList.add(new KnuthPenalty(0, KnuthElement.INFINITE, false,
new Position(this), false));
@@ -142,6 +149,11 @@ public class FlowLayoutManager extends BlockStackingLayoutManager
}
}
}
+ if (childLC.isKeepWithNextPending()) {
+ //Clear and propagate
+ childLC.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false);
+ context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING);
+ }
prevLM = curLM;
}
diff --git a/src/java/org/apache/fop/layoutmgr/list/Item.java b/src/java/org/apache/fop/layoutmgr/list/Item.java
index a7dd3799e..16a9ab3f3 100644
--- a/src/java/org/apache/fop/layoutmgr/list/Item.java
+++ b/src/java/org/apache/fop/layoutmgr/list/Item.java
@@ -18,9 +18,10 @@
package org.apache.fop.layoutmgr.list;
-import org.apache.fop.fo.FObj;
+import org.apache.fop.fo.flow.AbstractListItemPart;
import org.apache.fop.fo.flow.ListItemBody;
import org.apache.fop.fo.flow.ListItemLabel;
+import org.apache.fop.layoutmgr.BlockLevelLayoutManager;
import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
import org.apache.fop.layoutmgr.LayoutManager;
import org.apache.fop.layoutmgr.LayoutContext;
@@ -30,17 +31,14 @@ import org.apache.fop.layoutmgr.NonLeafPosition;
import org.apache.fop.area.Area;
import org.apache.fop.area.Block;
-import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.LinkedList;
/**
- * LayoutManager for a table-cell FO.
- * A cell contains blocks. These blocks fill the cell.
+ * LayoutManager for a list-item-label or list-item-body FO.
*/
public class Item extends BlockStackingLayoutManager {
- private FObj fobj;
private Block curBlockArea;
@@ -63,21 +61,29 @@ public class Item extends BlockStackingLayoutManager {
/**
* Create a new Cell layout manager.
+ * @param node list-item-label node
*/
public Item(ListItemLabel node) {
super(node);
- fobj = node;
}
/**
* Create a new Cell layout manager.
+ * @param node list-item-body node
*/
public Item(ListItemBody node) {
super(node);
- fobj = node;
}
/**
+ * Convenience method.
+ * @return the ListBlock node
+ */
+ protected AbstractListItemPart getPartFO() {
+ return (AbstractListItemPart)fobj;
+ }
+
+ /**
* Set the x offset of this list item.
* This offset is used to set the absolute position
* of the list item within the parent block area.
@@ -88,6 +94,7 @@ public class Item extends BlockStackingLayoutManager {
xoffset = off;
}
+ /** @see org.apache.fop.layoutmgr.LayoutManager#getChangedKnuthElements(java.util.List, int) */
public LinkedList getChangedKnuthElements(List oldList, int alignment) {
//log.debug(" Item.getChanged>");
return super.getChangedKnuthElements(oldList, alignment);
@@ -105,12 +112,7 @@ public class Item extends BlockStackingLayoutManager {
LayoutContext layoutContext) {
getParentArea(null);
- int nameId = fobj.getNameId();
- if (nameId == FO_LIST_ITEM_LABEL) {
- getPSLM().addIDToPage(((ListItemLabel) fobj).getId());
- } else if (nameId == FO_LIST_ITEM_BODY) {
- getPSLM().addIDToPage(((ListItemBody) fobj).getId());
- }
+ getPSLM().addIDToPage(getPartFO().getId());
LayoutManager childLM = null;
LayoutContext lc = new LayoutContext(0);
@@ -144,15 +146,6 @@ public class Item extends BlockStackingLayoutManager {
childLM.addAreas(childPosIter, lc);
}
- /*
- if (borderProps != null) {
- TraitSetter.addBorders(curBlockArea, borderProps);
- }
- if (backgroundProps != null) {
- TraitSetter.addBackground(curBlockArea, backgroundProps);
- }
- */
-
flush();
curBlockArea = null;
@@ -214,5 +207,14 @@ public class Item extends BlockStackingLayoutManager {
//reset(resetPos);
}
}
+
+ /** @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepTogether() */
+ public boolean mustKeepTogether() {
+ //TODO Keeps will have to be more sophisticated sooner or later
+ return ((BlockLevelLayoutManager)getParent()).mustKeepTogether()
+ || !getPartFO().getKeepTogether().getWithinPage().isAuto()
+ || !getPartFO().getKeepTogether().getWithinColumn().isAuto();
+ }
+
}
diff --git a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
index 8a2655954..af58646b4 100644
--- a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
@@ -19,6 +19,7 @@
package org.apache.fop.layoutmgr.list;
import org.apache.fop.fo.flow.ListBlock;
+import org.apache.fop.layoutmgr.BlockLevelLayoutManager;
import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
import org.apache.fop.layoutmgr.LayoutManager;
import org.apache.fop.layoutmgr.LayoutContext;
@@ -41,8 +42,6 @@ import java.util.List;
* the list block area..
*/
public class ListBlockLayoutManager extends BlockStackingLayoutManager {
- private ListBlock fobj;
-
private Block curBlockArea;
//TODO space-before|after: handle space-resolution rules
@@ -78,20 +77,27 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager {
*/
public ListBlockLayoutManager(ListBlock node) {
super(node);
- fobj = node;
+ }
+
+ /**
+ * Convenience method.
+ * @return the ListBlock node
+ */
+ protected ListBlock getListBlockFO() {
+ return (ListBlock)fobj;
}
/** @see org.apache.fop.layoutmgr.AbstractLayoutManager#initProperties() */
protected void initProperties() {
super.initProperties();
- spaceBefore = new SpaceVal(fobj.getCommonMarginBlock().spaceBefore).getSpace();
- spaceAfter = new SpaceVal(fobj.getCommonMarginBlock().spaceAfter).getSpace();
+ spaceBefore = new SpaceVal(getListBlockFO().getCommonMarginBlock().spaceBefore).getSpace();
+ spaceAfter = new SpaceVal(getListBlockFO().getCommonMarginBlock().spaceAfter).getSpace();
}
private int getIPIndents() {
int iIndents = 0;
- iIndents += fobj.getCommonMarginBlock().startIndent.getValue();
- iIndents += fobj.getCommonMarginBlock().endIndent.getValue();
+ iIndents += getListBlockFO().getCommonMarginBlock().startIndent.getValue();
+ iIndents += getListBlockFO().getCommonMarginBlock().endIndent.getValue();
return iIndents;
}
@@ -116,7 +122,7 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager {
addBlockSpacing(adjust, spaceBefore);
spaceBefore = null;
- getPSLM().addIDToPage(fobj.getId());
+ getPSLM().addIDToPage(getListBlockFO().getId());
// the list block contains areas stacked from each list item
@@ -181,13 +187,16 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager {
/*Area parentArea =*/ parentLM.getParentArea(curBlockArea);
// set traits
- TraitSetter.addBorders(curBlockArea, fobj.getCommonBorderPaddingBackground());
- TraitSetter.addBackground(curBlockArea, fobj.getCommonBorderPaddingBackground());
+ TraitSetter.addBorders(curBlockArea,
+ getListBlockFO().getCommonBorderPaddingBackground());
+ TraitSetter.addBackground(curBlockArea,
+ getListBlockFO().getCommonBorderPaddingBackground());
TraitSetter.addMargins(curBlockArea,
- fobj.getCommonBorderPaddingBackground(),
- fobj.getCommonMarginBlock());
+ getListBlockFO().getCommonBorderPaddingBackground(),
+ getListBlockFO().getCommonMarginBlock());
TraitSetter.addBreaks(curBlockArea,
- fobj.getBreakBefore(), fobj.getBreakAfter());
+ getListBlockFO().getBreakBefore(),
+ getListBlockFO().getBreakAfter());
int contentIPD = referenceIPD - getIPIndents();
curBlockArea.setIPD(contentIPD);
@@ -220,5 +229,26 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager {
//TODO Something to put here?
}
}
+
+ /** @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepTogether() */
+ public boolean mustKeepTogether() {
+ //TODO Keeps will have to be more sophisticated sooner or later
+ return ((BlockLevelLayoutManager)getParent()).mustKeepTogether()
+ || !getListBlockFO().getKeepTogether().getWithinPage().isAuto()
+ || !getListBlockFO().getKeepTogether().getWithinColumn().isAuto();
+ }
+
+ /** @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepWithPrevious() */
+ public boolean mustKeepWithPrevious() {
+ return !getListBlockFO().getKeepWithPrevious().getWithinPage().isAuto()
+ || !getListBlockFO().getKeepWithPrevious().getWithinColumn().isAuto();
+ }
+
+ /** @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepWithNext() */
+ public boolean mustKeepWithNext() {
+ return !getListBlockFO().getKeepWithNext().getWithinPage().isAuto()
+ || !getListBlockFO().getKeepWithNext().getWithinColumn().isAuto();
+ }
+
}
diff --git a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
index 147194718..e2d8712a9 100644
--- a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
@@ -21,9 +21,9 @@ package org.apache.fop.layoutmgr.list;
import org.apache.fop.fo.flow.ListItem;
import org.apache.fop.fo.flow.ListItemBody;
import org.apache.fop.fo.flow.ListItemLabel;
+import org.apache.fop.layoutmgr.BlockLevelLayoutManager;
import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
import org.apache.fop.layoutmgr.LayoutManager;
-import org.apache.fop.layoutmgr.LeafPosition;
import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.layoutmgr.PositionIterator;
import org.apache.fop.layoutmgr.Position;
@@ -48,8 +48,6 @@ import java.util.ListIterator;
* The list item contains a list item label and a list item body.
*/
public class ListItemLayoutManager extends BlockStackingLayoutManager {
- private ListItem fobj;
-
private Item label;
private Item body;
@@ -64,13 +62,14 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager {
private MinOptMax spaceBefore;
private MinOptMax spaceAfter;
+ /*
private class ItemPosition extends LeafPosition {
protected List cellBreaks;
protected ItemPosition(LayoutManager lm, int pos, List l) {
super(lm, pos);
cellBreaks = l;
}
- }
+ }*/
private class ListItemPosition extends Position {
private int iLabelFirstIndex;
@@ -110,12 +109,19 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager {
*/
public ListItemLayoutManager(ListItem node) {
super(node);
- fobj = node;
setLabel(node.getLabel());
setBody(node.getBody());
}
/**
+ * Convenience method.
+ * @return the ListBlock node
+ */
+ protected ListItem getListItemFO() {
+ return (ListItem)fobj;
+ }
+
+ /**
* Create a LM for the fo:list-item-label object
* @param node the fo:list-item-label FO
*/
@@ -136,20 +142,18 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager {
/** @see org.apache.fop.layoutmgr.AbstractLayoutManager#initProperties() */
protected void initProperties() {
super.initProperties();
- spaceBefore = new SpaceVal(fobj.getCommonMarginBlock().spaceBefore).getSpace();
- spaceAfter = new SpaceVal(fobj.getCommonMarginBlock().spaceAfter).getSpace();
+ spaceBefore = new SpaceVal(getListItemFO().getCommonMarginBlock().spaceBefore).getSpace();
+ spaceAfter = new SpaceVal(getListItemFO().getCommonMarginBlock().spaceAfter).getSpace();
}
private int getIPIndents() {
int iIndents = 0;
- iIndents += fobj.getCommonMarginBlock().startIndent.getValue();
- iIndents += fobj.getCommonMarginBlock().endIndent.getValue();
+ iIndents += getListItemFO().getCommonMarginBlock().startIndent.getValue();
+ iIndents += getListItemFO().getCommonMarginBlock().endIndent.getValue();
return iIndents;
}
- /**
- * @see org.apache.fop.layoutmgr.LayoutManager#getNextKnuthElements(org.apache.fop.layoutmgr.LayoutContext, int)
- */
+ /** @see org.apache.fop.layoutmgr.LayoutManager */
public LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
referenceIPD = context.getRefIPD();
@@ -207,7 +211,11 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager {
start[0], end[0], start[1], end[1]);
returnList.add(new KnuthBox(boxHeight, stepPosition, false));
if (addedBoxHeight < totalHeight) {
- returnList.add(new KnuthPenalty(penaltyHeight, 0, false, stepPosition, false));
+ int p = 0;
+ if (mustKeepTogether()) {
+ p = KnuthPenalty.INFINITE;
+ }
+ returnList.add(new KnuthPenalty(penaltyHeight, p, false, stepPosition, false));
}
}
@@ -373,7 +381,7 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager {
addBlockSpacing(adjust, spaceBefore);
spaceBefore = null;
- getPSLM().addIDToPage(fobj.getId());
+ getPSLM().addIDToPage(getListItemFO().getId());
LayoutContext lc = new LayoutContext(0);
@@ -469,13 +477,16 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager {
/*Area parentArea =*/ parentLM.getParentArea(curBlockArea);
// set traits
- TraitSetter.addBorders(curBlockArea, fobj.getCommonBorderPaddingBackground());
- TraitSetter.addBackground(curBlockArea, fobj.getCommonBorderPaddingBackground());
+ TraitSetter.addBorders(curBlockArea,
+ getListItemFO().getCommonBorderPaddingBackground());
+ TraitSetter.addBackground(curBlockArea,
+ getListItemFO().getCommonBorderPaddingBackground());
TraitSetter.addMargins(curBlockArea,
- fobj.getCommonBorderPaddingBackground(),
- fobj.getCommonMarginBlock());
+ getListItemFO().getCommonBorderPaddingBackground(),
+ getListItemFO().getCommonMarginBlock());
TraitSetter.addBreaks(curBlockArea,
- fobj.getBreakBefore(), fobj.getBreakAfter());
+ getListItemFO().getBreakBefore(),
+ getListItemFO().getBreakAfter());
int contentIPD = referenceIPD - getIPIndents();
curBlockArea.setIPD(contentIPD);
@@ -508,5 +519,26 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager {
reset(null);
}
}
+
+ /** @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepTogether() */
+ public boolean mustKeepTogether() {
+ //TODO Keeps will have to be more sophisticated sooner or later
+ return ((BlockLevelLayoutManager)getParent()).mustKeepTogether()
+ || !getListItemFO().getKeepTogether().getWithinPage().isAuto()
+ || !getListItemFO().getKeepTogether().getWithinColumn().isAuto();
+ }
+
+ /** @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepWithPrevious() */
+ public boolean mustKeepWithPrevious() {
+ return !getListItemFO().getKeepWithPrevious().getWithinPage().isAuto()
+ || !getListItemFO().getKeepWithPrevious().getWithinColumn().isAuto();
+ }
+
+ /** @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepWithNext() */
+ public boolean mustKeepWithNext() {
+ return !getListItemFO().getKeepWithNext().getWithinPage().isAuto()
+ || !getListItemFO().getKeepWithNext().getWithinColumn().isAuto();
+ }
+
}
diff --git a/src/java/org/apache/fop/layoutmgr/table/Cell.java b/src/java/org/apache/fop/layoutmgr/table/Cell.java
index e64cb53f6..d2b86c157 100644
--- a/src/java/org/apache/fop/layoutmgr/table/Cell.java
+++ b/src/java/org/apache/fop/layoutmgr/table/Cell.java
@@ -168,6 +168,14 @@ public class Cell extends BlockStackingLayoutManager implements BlockLevelLayout
// get elements from curLM
returnedList = curLM.getNextKnuthElements(childLC, alignment);
+ if (childLC.isKeepWithNextPending()) {
+ log.debug("child LM signals pending keep with next");
+ }
+ if (contentList.size() == 0 && childLC.isKeepWithPreviousPending()) {
+ context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
+ childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false);
+ }
+
if (returnedList.size() == 1
&& ((KnuthElement) returnedList.getFirst()).isPenalty()
&& ((KnuthPenalty) returnedList.getFirst()).getP() == -KnuthElement.INFINITE) {
@@ -192,8 +200,11 @@ public class Cell extends BlockStackingLayoutManager implements BlockLevelLayout
// there is a block handled by prevLM
// before the one handled by curLM
if (mustKeepTogether()
- || prevLM.mustKeepWithNext()
- || curLM.mustKeepWithPrevious()) {
+ || context.isKeepWithNextPending()
+ || childLC.isKeepWithPreviousPending()) {
+ //Clear keep pending flag
+ context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false);
+ childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false);
// add an infinite penalty to forbid a break between
// blocks
contentList.add(new KnuthPenalty(0,
@@ -230,6 +241,11 @@ public class Cell extends BlockStackingLayoutManager implements BlockLevelLayout
return returnList;
}
}
+ if (childLC.isKeepWithNextPending()) {
+ //Clear and propagate
+ childLC.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false);
+ context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING);
+ }
prevLM = curLM;
}
diff --git a/src/java/org/apache/fop/layoutmgr/table/GridUnit.java b/src/java/org/apache/fop/layoutmgr/table/GridUnit.java
index 5b1d85d2b..d51681c3b 100644
--- a/src/java/org/apache/fop/layoutmgr/table/GridUnit.java
+++ b/src/java/org/apache/fop/layoutmgr/table/GridUnit.java
@@ -44,6 +44,10 @@ public class GridUnit {
public static final int LAST_IN_BODY = 4;
/** Indicates that the grid unit is in the last row (context: table). */
public static final int LAST_IN_TABLE = 5;
+ /** Indicates that the primary grid unit has a pending keep-with-next. */
+ public static final int KEEP_WITH_NEXT_PENDING = 6;
+ /** Indicates that the primary grid unit has a pending keep-with-previous. */
+ public static final int KEEP_WITH_PREVIOUS_PENDING = 7;
/** Primary grid unit */
private PrimaryGridUnit primary;
diff --git a/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java
index 20d3e70e2..d80490457 100644
--- a/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java
@@ -36,6 +36,7 @@ import org.apache.fop.layoutmgr.ElementListObserver;
import org.apache.fop.layoutmgr.ElementListUtils;
import org.apache.fop.layoutmgr.KnuthBox;
import org.apache.fop.layoutmgr.KnuthElement;
+import org.apache.fop.layoutmgr.KnuthPenalty;
import org.apache.fop.layoutmgr.KnuthPossPosIter;
import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.layoutmgr.LayoutManager;
@@ -193,6 +194,20 @@ public class TableContentLayoutManager {
}
createElementsForRowGroup(context, alignment, bodyType,
returnList, rowGroup);
+ if (context.isKeepWithNextPending()) {
+ log.debug("child LM (row group) signals pending keep-with-next");
+ }
+ if (context.isKeepWithPreviousPending()) {
+ log.debug("child LM (row group) signals pending keep-with-previous");
+ if (returnList.size() > 0) {
+ //Modify last penalty
+ KnuthElement last = (KnuthElement)returnList.getLast();
+ if (last.isPenalty()) {
+ KnuthPenalty pen = (KnuthPenalty)last;
+ pen.setP(KnuthPenalty.INFINITE);
+ }
+ }
+ }
}
if (returnList.size() > 0) {
@@ -381,6 +396,15 @@ public class TableContentLayoutManager {
childLC, alignment);
primary.setElements(elems);
ElementListObserver.observe(elems, "table-cell", primary.getCell().getId());
+
+ if (childLC.isKeepWithNextPending()) {
+ log.debug("child LM signals pending keep-with-next");
+ primary.setFlag(GridUnit.KEEP_WITH_NEXT_PENDING, true);
+ }
+ if (childLC.isKeepWithPreviousPending()) {
+ log.debug("child LM signals pending keep-with-previous");
+ primary.setFlag(GridUnit.KEEP_WITH_PREVIOUS_PENDING, true);
+ }
}
@@ -446,9 +470,10 @@ public class TableContentLayoutManager {
log.debug(" height=" + rowHeights[i] + " explicit=" + explicitRowHeights[i]);
}
}
+ //TODO It may make sense to reuse the stepper since it allocates quite some space
TableStepper stepper = new TableStepper(this);
LinkedList returnedList = stepper.getCombinedKnuthElementsForRowGroup(
- rowGroup, maxColumnCount, bodyType);
+ context, rowGroup, maxColumnCount, bodyType);
if (returnedList != null) {
returnList.addAll(returnedList);
}
diff --git a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
index 533a5f809..d9bcfc81e 100644
--- a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
@@ -182,6 +182,14 @@ public class TableLayoutManager extends BlockStackingLayoutManager
contentLM = new TableContentLayoutManager(this);
returnedList = contentLM.getNextKnuthElements(childLC, alignment);
+ if (childLC.isKeepWithNextPending()) {
+ log.debug("TableContentLM signals pending keep-with-next");
+ context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING);
+ }
+ if (childLC.isKeepWithPreviousPending()) {
+ log.debug("TableContentLM signals pending keep-with-previous");
+ context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
+ }
log.debug(returnedList);
if (returnedList.size() == 1
diff --git a/src/java/org/apache/fop/layoutmgr/table/TableStepper.java b/src/java/org/apache/fop/layoutmgr/table/TableStepper.java
index 21b0d44ba..391595795 100644
--- a/src/java/org/apache/fop/layoutmgr/table/TableStepper.java
+++ b/src/java/org/apache/fop/layoutmgr/table/TableStepper.java
@@ -29,6 +29,7 @@ import org.apache.fop.layoutmgr.ElementListUtils;
import org.apache.fop.layoutmgr.KnuthBox;
import org.apache.fop.layoutmgr.KnuthElement;
import org.apache.fop.layoutmgr.KnuthPenalty;
+import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.layoutmgr.table.TableContentLayoutManager.GridUnitPart;
import org.apache.fop.layoutmgr.table.TableContentLayoutManager.TableContentPosition;
import org.apache.fop.layoutmgr.table.TableContentLayoutManager.TableHFPenaltyPosition;
@@ -55,6 +56,7 @@ public class TableStepper {
private int[] borderBefore;
private int[] borderAfter;
private boolean rowBacktrackForLastStep;
+ private boolean[] keepWithNextSignals;
/**
* Main constructor
@@ -74,6 +76,7 @@ public class TableStepper {
baseWidth = new int[columnCount];
borderBefore = new int[columnCount];
borderAfter = new int[columnCount];
+ keepWithNextSignals = new boolean[columnCount];
Arrays.fill(end, -1);
}
@@ -165,6 +168,7 @@ public class TableStepper {
end[column] = -1;
widths[column] = 0;
startRow[column] = activeRow;
+ keepWithNextSignals[column] = false;
}
}
@@ -176,18 +180,21 @@ public class TableStepper {
/**
* Creates the combined element list for a row group.
+ * @param context Active LayoutContext
* @param rowGroup the row group
* @param maxColumnCount the maximum number of columns to expect
* @param bodyType Indicates what type of body is processed (boder, header or footer)
* @return the combined element list
*/
- public LinkedList getCombinedKnuthElementsForRowGroup(
+ public LinkedList getCombinedKnuthElementsForRowGroup(
+ LayoutContext context,
EffRow[] rowGroup, int maxColumnCount, int bodyType) {
this.rowGroup = rowGroup;
setup(maxColumnCount);
initializeElementLists();
calcTotalHeight();
+ boolean signalKeepWithNext = false;
int laststep = 0;
int step;
int addedBoxLen = 0;
@@ -217,6 +224,30 @@ public class TableStepper {
} else {
gridUnitParts.add(new GridUnitPart(pgu, start[i], end[i]));
}
+ if (end[i] + 1 == elementLists[i].size()) {
+ if (pgu.getFlag(GridUnit.KEEP_WITH_NEXT_PENDING)) {
+ log.debug("PGU has pending keep-with-next");
+ keepWithNextSignals[i] = true;
+ }
+ if (pgu.getRow() != null && pgu.getRow().mustKeepWithNext()) {
+ log.debug("table-row causes keep-with-next");
+ keepWithNextSignals[i] = true;
+ }
+ }
+ if (start[i] == 0 && end[i] >= 0) {
+ if (pgu.getFlag(GridUnit.KEEP_WITH_PREVIOUS_PENDING)) {
+ log.debug("PGU has pending keep-with-previous");
+ if (returnList.size() == 0) {
+ context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
+ }
+ }
+ if (pgu.getRow() != null && pgu.getRow().mustKeepWithPrevious()) {
+ log.debug("table-row causes keep-with-previous");
+ if (returnList.size() == 0) {
+ context.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING);
+ }
+ }
+ }
}
}
//log.debug(">>> guPARTS: " + gridUnitParts);
@@ -245,7 +276,11 @@ public class TableStepper {
}
}
int p = 0;
- if (getTableLM().mustKeepTogether()) {
+ signalKeepWithNext = false;
+ for (int i = 0; i < start.length; i++) {
+ signalKeepWithNext |= keepWithNextSignals[i];
+ }
+ if (signalKeepWithNext || getTableLM().mustKeepTogether()) {
p = KnuthPenalty.INFINITE;
}
returnList.add(new KnuthPenalty(effPenaltyLen, p, false, penaltyPos, false));
@@ -261,6 +296,11 @@ public class TableStepper {
activeRow++;
}
}
+ if (signalKeepWithNext) {
+ //Last step signalled a keep-with-next. Since the last penalty will be removed,
+ //we have to signal the still pending last keep-with-next using the LayoutContext.
+ context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING);
+ }
return returnList;
}