From 9b3c25d9daff658a9144330172f58cfd4688eca3 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Tue, 24 May 2005 09:41:32 +0000 Subject: 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 --- .../fop/layoutmgr/BlockStackingLayoutManager.java | 23 ++++++- .../apache/fop/layoutmgr/FlowLayoutManager.java | 16 ++++- src/java/org/apache/fop/layoutmgr/list/Item.java | 46 +++++++------- .../fop/layoutmgr/list/ListBlockLayoutManager.java | 56 +++++++++++++---- .../fop/layoutmgr/list/ListItemLayoutManager.java | 70 ++++++++++++++++------ src/java/org/apache/fop/layoutmgr/table/Cell.java | 20 ++++++- .../org/apache/fop/layoutmgr/table/GridUnit.java | 4 ++ .../layoutmgr/table/TableContentLayoutManager.java | 27 ++++++++- .../fop/layoutmgr/table/TableLayoutManager.java | 8 +++ .../apache/fop/layoutmgr/table/TableStepper.java | 44 +++++++++++++- 10 files changed, 251 insertions(+), 63 deletions(-) (limited to 'src/java/org/apache/fop/layoutmgr') 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,20 +61,28 @@ 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 @@ -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,11 +109,18 @@ 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; } -- cgit v1.2.3