diff options
author | Adrian Cumiskey <acumiskey@apache.org> | 2008-04-16 08:21:34 +0000 |
---|---|---|
committer | Adrian Cumiskey <acumiskey@apache.org> | 2008-04-16 08:21:34 +0000 |
commit | 592835167ab8951f61d1590197f646984588d070 (patch) | |
tree | d198bcce1ac27b7413448c765761e879191e52c0 /src | |
parent | 2bcd566ece9ea8fd6ff996cdb0969d4db5c345a6 (diff) | |
download | xmlgraphics-fop-592835167ab8951f61d1590197f646984588d070.tar.gz xmlgraphics-fop-592835167ab8951f61d1590197f646984588d070.zip |
Merged revisions 648381 via svnmerge from
https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk
........
r648381 | jeremias | 2008-04-15 20:18:46 +0100 (Tue, 15 Apr 2008) | 1 line
First part of the implementation of stage 1 for advanced keeps (see Wiki): Integer values are treated differently from "always" values in keep-together.within-column for all block-level FOs.
........
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AFPGOCAResources@648611 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
21 files changed, 374 insertions, 189 deletions
diff --git a/src/java/org/apache/fop/fo/flow/table/EffRow.java b/src/java/org/apache/fop/fo/flow/table/EffRow.java index 0b00b9620..31a8260cc 100644 --- a/src/java/org/apache/fop/fo/flow/table/EffRow.java +++ b/src/java/org/apache/fop/fo/flow/table/EffRow.java @@ -23,6 +23,8 @@ import java.util.Iterator; import java.util.List; import org.apache.fop.fo.Constants; +import org.apache.fop.layoutmgr.BlockLevelLayoutManager; +import org.apache.fop.layoutmgr.KeepUtil; import org.apache.fop.layoutmgr.table.TableRowIterator; import org.apache.fop.traits.MinOptMax; import org.apache.fop.util.BreakUtil; @@ -211,11 +213,27 @@ public class EffRow { * @return true if this row must be kept together */ public boolean mustKeepTogether() { - TableRow row = getTableRow(); - return row != null && row.mustKeepTogether(); + return getKeepTogetherStrength() != BlockLevelLayoutManager.KEEP_AUTO; } /** + * Returns the keep-together strength for this element. Note: The keep strength returned does + * not take the parent table's keeps into account! + * @return the keep-together strength + */ + public int getKeepTogetherStrength() { + TableRow row = getTableRow(); + int strength = BlockLevelLayoutManager.KEEP_AUTO; + if (row != null) { + strength = Math.max(strength, KeepUtil.getKeepStrength( + row.getKeepTogether().getWithinPage())); + strength = Math.max(strength, KeepUtil.getKeepStrength( + row.getKeepTogether().getWithinColumn())); + } + return strength; + } + + /** * Returns the break class for this row. This is a combination of break-before set on * the first children of any cells starting on this row. * <p><strong>Note:</strong> this method doesn't take into account break-before set on diff --git a/src/java/org/apache/fop/fo/flow/table/GridUnit.java b/src/java/org/apache/fop/fo/flow/table/GridUnit.java index b9394ff31..578fcb883 100644 --- a/src/java/org/apache/fop/fo/flow/table/GridUnit.java +++ b/src/java/org/apache/fop/fo/flow/table/GridUnit.java @@ -64,11 +64,16 @@ public class GridUnit { /** flags for the grid unit */ private byte flags = 0; + /** the border-before specification */ ConditionalBorder borderBefore; + /** the border-after specification */ ConditionalBorder borderAfter; + /** the border-start specification */ BorderSpecification borderStart; + /** the border-end specification */ BorderSpecification borderEnd; + /** The border model helper associated with the table */ protected CollapsingBorderModel collapsingBorderModel; /** @@ -146,6 +151,10 @@ public class GridUnit { } } + /** + * Returns the table cell associated with this grid unit. + * @return the table cell + */ public TableCell getCell() { return cell; } diff --git a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java index f01f0e12f..c0220e75e 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java @@ -308,22 +308,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager if (prevLM != null) { // there is a block handled by prevLM // before the one handled by curLM - if (mustKeepTogether() - || prevLM.mustKeepWithNext() - || curLM.mustKeepWithPrevious()) { - // add an infinite penalty to forbid a break between - // blocks - contentList.add(new BreakElement( - new Position(this), KnuthElement.INFINITE, context)); - } else if (!((ListElement) contentList.getLast()).isGlue()) { - // add a null penalty to allow a break between blocks - contentList.add(new BreakElement( - new Position(this), 0, context)); - } else { - // the last element in contentList is a glue; - // it is a feasible breakpoint, there is no need to add - // a penalty - } + addInBetweenBreak(contentList, context, childLC); } contentList.addAll(returnedList); if (returnedList.size() == 0) { @@ -1004,15 +989,19 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager } /** {@inheritDoc} */ - public boolean mustKeepTogether() { - //TODO Keeps will have to be more sophisticated sooner or later - return super.mustKeepTogether() - || !getBlockContainerFO().getKeepTogether().getWithinPage().isAuto() - || !getBlockContainerFO().getKeepTogether().getWithinColumn().isAuto(); + public int getKeepTogetherStrength() { + int strength = KEEP_AUTO; + strength = Math.max(strength, KeepUtil.getKeepStrength( + getBlockContainerFO().getKeepTogether().getWithinPage())); + strength = Math.max(strength, KeepUtil.getKeepStrength( + getBlockContainerFO().getKeepTogether().getWithinColumn())); + strength = Math.max(strength, getParentKeepTogetherStrength()); + return strength; } /** {@inheritDoc} */ public boolean mustKeepWithPrevious() { + //TODO Keeps will have to be more sophisticated sooner or later return !getBlockContainerFO().getKeepWithPrevious().getWithinPage().isAuto() || !getBlockContainerFO().getKeepWithPrevious().getWithinColumn().isAuto(); } diff --git a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java index f5270107c..253ec2af1 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java @@ -33,7 +33,6 @@ import org.apache.fop.datatypes.Length; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontInfo; import org.apache.fop.fonts.FontTriplet; -import org.apache.fop.layoutmgr.inline.InlineLayoutManager; import org.apache.fop.layoutmgr.inline.InlineLevelLayoutManager; import org.apache.fop.layoutmgr.inline.LineLayoutManager; import org.apache.fop.traits.MinOptMax; @@ -79,11 +78,13 @@ public class BlockLayoutManager extends BlockStackingLayoutManager proxyLMiter = new ProxyLMiter(); } + /** {@inheritDoc} */ public void initialize() { super.initialize(); FontInfo fi = getBlockFO().getFOEventHandler().getFontInfo(); FontTriplet[] fontkeys = getBlockFO().getCommonFont().getFontState(fi); - Font initFont = fi.getFontInstance(fontkeys[0], getBlockFO().getCommonFont().fontSize.getValue(this)); + Font initFont = fi.getFontInstance(fontkeys[0], + getBlockFO().getCommonFont().fontSize.getValue(this)); lead = initFont.getAscender(); follow = -initFont.getDescender(); //middleShift = -fs.getXHeight() / 2; @@ -135,7 +136,7 @@ public class BlockLayoutManager extends BlockStackingLayoutManager */ protected class ProxyLMiter extends LMiter { - /* + /** * Constructs a proxy iterator for Block LM. */ public ProxyLMiter() { @@ -206,40 +207,31 @@ public class BlockLayoutManager extends BlockStackingLayoutManager return llm; } - /** - * {@inheritDoc} - */ - public boolean mustKeepTogether() { - // TODO Keeps will have to be more sophisticated sooner or later - // TODO This is a quick fix for the fact that the parent is not always a BlockLevelLM; - // eventually mustKeepTogether() must be moved up to the LM interface - return (!getBlockFO().getKeepTogether().getWithinPage().isAuto() - || !getBlockFO().getKeepTogether().getWithinColumn().isAuto() - || (getParent() instanceof BlockLevelLayoutManager - && ((BlockLevelLayoutManager) getParent()).mustKeepTogether()) - || (getParent() instanceof InlineLayoutManager - && ((InlineLayoutManager) getParent()).mustKeepTogether())); + /** {@inheritDoc} */ + public int getKeepTogetherStrength() { + int strength = KEEP_AUTO; + strength = Math.max(strength, KeepUtil.getKeepStrength( + getBlockFO().getKeepTogether().getWithinPage())); + strength = Math.max(strength, KeepUtil.getKeepStrength( + getBlockFO().getKeepTogether().getWithinColumn())); + strength = Math.max(strength, getParentKeepTogetherStrength()); + return strength; } - - /** - * {@inheritDoc} - */ + + /** {@inheritDoc} */ public boolean mustKeepWithPrevious() { + //TODO Keeps will have to be more sophisticated sooner or later return !getBlockFO().getKeepWithPrevious().getWithinPage().isAuto() || !getBlockFO().getKeepWithPrevious().getWithinColumn().isAuto(); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public boolean mustKeepWithNext() { return !getBlockFO().getKeepWithNext().getWithinPage().isAuto() || !getBlockFO().getKeepWithNext().getWithinColumn().isAuto(); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void addAreas(PositionIterator parentIter, LayoutContext layoutContext) { getParentArea(null); diff --git a/src/java/org/apache/fop/layoutmgr/BlockLevelLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockLevelLayoutManager.java index 7e0e9e50e..3dc7ed46e 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockLevelLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockLevelLayoutManager.java @@ -35,11 +35,22 @@ public interface BlockLevelLayoutManager extends LayoutManager { /** Adjustment class: adjustment for line height */ int LINE_HEIGHT_ADJUSTMENT = 3; + /** The integer value for "auto" keep strength */ + int KEEP_AUTO = Integer.MIN_VALUE; + /** The integer value for "always" keep strength */ + int KEEP_ALWAYS = Integer.MAX_VALUE; + int negotiateBPDAdjustment(int adj, KnuthElement lastElement); void discardSpace(KnuthGlue spaceGlue); /** + * Returns the keep-together strength for this element. + * @return the keep-together strength + */ + int getKeepTogetherStrength(); + + /** * @return true if this element must be kept together */ boolean mustKeepTogether(); diff --git a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java index cb6db6b01..c6ead8d59 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java @@ -335,27 +335,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager if (prevLM != null) { // there is a block handled by prevLM // before the one handled by curLM - if (mustKeepTogether() - || context.isKeepWithNextPending() - || childLC.isKeepWithPreviousPending()) { - // Clear keep pending flag - context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false); - // add an infinite penalty to forbid a break between - // blocks - contentList.add(new BreakElement( - new Position(this), KnuthElement.INFINITE, context)); - } else if (!((ListElement) contentList.getLast()).isGlue()) { - // add a null penalty to allow a break between blocks - contentList.add(new BreakElement( - new Position(this), 0, context)); - } else { - // the last element in contentList is a glue; - // it is a feasible breakpoint, there is no need to add - // a penalty - log.warn("glue-type break possibility not handled properly, yet"); - //TODO Does this happen? If yes, need to deal with border and padding - //at the break possibility - } + addInBetweenBreak(contentList, context, childLC); } if (returnedList == null || returnedList.size() == 0) { //Avoid NoSuchElementException below (happens with empty blocks) @@ -433,6 +413,66 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager } /** + * Adds a break element to the content list between individual child elements. + * @param contentList the content list to populate + * @param context the current layout context + * @param childLC the currently active child layout context + */ + protected void addInBetweenBreak(LinkedList contentList, LayoutContext context, + LayoutContext childLC) { + if (mustKeepTogether() + || context.isKeepWithNextPending() + || childLC.isKeepWithPreviousPending()) { + + int strength = getKeepTogetherStrength(); + if (context.isKeepWithNextPending()) { + context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false); + strength = KEEP_ALWAYS; + } + if (childLC.isKeepWithPreviousPending()) { + childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false); + strength = KEEP_ALWAYS; + } + int penalty = KeepUtil.getPenaltyForKeep(strength); + + // add a penalty to forbid or discourage a break between blocks + contentList.add(new BreakElement( + new Position(this), penalty, context)); + return; + } + + ListElement last = (ListElement)contentList.getLast(); + if (last.isGlue()) { + // the last element in contentList is a glue; + // it is a feasible breakpoint, there is no need to add + // a penalty + log.warn("glue-type break possibility not handled properly, yet"); + //TODO Does this happen? If yes, need to deal with border and padding + //at the break possibility + } else if (!ElementListUtils.endsWithNonInfinitePenalty(contentList)) { + + // TODO vh: this is hacky + // The getNextKnuthElements method of TableCellLM must not be called + // twice, otherwise some settings like indents or borders will be + // counted several times and lead to a wrong output. Anyway the + // getNextKnuthElements methods should be called only once eventually + // (i.e., when multi-threading the code), even when there are forced + // breaks. + // If we add a break possibility after a forced break the + // AreaAdditionUtil.addAreas method will act on a sequence starting + // with a SpaceResolver.SpaceHandlingBreakPosition element, having no + // LM associated to it. Thus it will stop early instead of adding + // areas for following Positions. The above test aims at preventing + // such a situation from occurring. add a null penalty to allow a break + // between blocks + + // add a null penalty to allow a break between blocks + contentList.add(new BreakElement( + new Position(this), 0, context)); + } + } + + /** * {@inheritDoc} */ public int negotiateBPDAdjustment(int adj, KnuthElement lastElement) { @@ -759,26 +799,34 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager } /** - * {@inheritDoc} + * Retrieves and returns the keep-together strength from the parent element. + * @return the keep-together strength */ - // default action: ask parentLM + protected int getParentKeepTogetherStrength() { + int strength = KEEP_AUTO; + if (getParent() instanceof BlockLevelLayoutManager) { + strength = ((BlockLevelLayoutManager)getParent()).getKeepTogetherStrength(); + } else if (getParent() instanceof InlineLayoutManager) { + if (((InlineLayoutManager) getParent()).mustKeepTogether()) { + strength = KEEP_ALWAYS; + } + //TODO Fix me + //strength = ((InlineLayoutManager) getParent()).getKeepTogetherStrength(); + } + return strength; + } + + /** {@inheritDoc} */ public boolean mustKeepTogether() { - return ((getParent() instanceof BlockLevelLayoutManager - && ((BlockLevelLayoutManager) getParent()).mustKeepTogether()) - || (getParent() instanceof InlineLayoutManager - && ((InlineLayoutManager) getParent()).mustKeepTogether())); + return getKeepTogetherStrength() > KEEP_AUTO; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public boolean mustKeepWithPrevious() { return false; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public boolean mustKeepWithNext() { return false; } diff --git a/src/java/org/apache/fop/layoutmgr/ElementListUtils.java b/src/java/org/apache/fop/layoutmgr/ElementListUtils.java index a2baba2fc..9a87e71c4 100644 --- a/src/java/org/apache/fop/layoutmgr/ElementListUtils.java +++ b/src/java/org/apache/fop/layoutmgr/ElementListUtils.java @@ -190,6 +190,23 @@ public class ElementListUtils { } /** + * Indicates whether the given element list ends with a penalty with a non-infinite penalty + * value. + * @param elems the element list + * @return true if the list ends with a non-infinite penalty + */ + public static boolean endsWithNonInfinitePenalty(LinkedList elems) { + ListElement last = (ListElement)elems.getLast(); + if (last.isPenalty() && ((KnuthPenalty)last).getP() < KnuthElement.INFINITE) { + return true; + } else if (last instanceof BreakElement + && ((BreakElement)last).getPenaltyValue() < KnuthElement.INFINITE) { + return true; + } + return false; + } + + /** * Determines the position of the previous break before the start index on an * element list. * @param elems the element list diff --git a/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java index 115532cf1..ecfcbe2b4 100644 --- a/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java @@ -208,10 +208,10 @@ public class FlowLayoutManager extends BlockStackingLayoutManager } /** {@inheritDoc} */ - public boolean mustKeepTogether() { - return false; + public int getKeepTogetherStrength() { + return KEEP_AUTO; } - + /** {@inheritDoc} */ public boolean mustKeepWithPrevious() { return false; diff --git a/src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java b/src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java index 71f4df314..351504cd7 100644 --- a/src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java @@ -19,11 +19,11 @@ package org.apache.fop.layoutmgr; +import java.util.LinkedList; + import org.apache.fop.area.Area; import org.apache.fop.fo.flow.FootnoteBody; -import java.util.LinkedList; - /** * Layout manager for footnote bodies. */ @@ -91,4 +91,9 @@ public class FootnoteBodyLayoutManager extends BlockStackingLayoutManager { return (FootnoteBody) fobj; } + /** {@inheritDoc} */ + public int getKeepTogetherStrength() { + return getParentKeepTogetherStrength(); + } + } diff --git a/src/java/org/apache/fop/layoutmgr/KeepUtil.java b/src/java/org/apache/fop/layoutmgr/KeepUtil.java new file mode 100644 index 000000000..1fd595ae0 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/KeepUtil.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.layoutmgr; + +import org.apache.fop.fo.Constants; +import org.apache.fop.fo.properties.Property; + +/** + * Utility class for working with keeps. + */ +public class KeepUtil { + + /** + * Converts a keep property into an integer value. + * <p> + * Note: The conversion restricts the effectively available integer range by two values. + * Integer.MIN_VALUE is used to represent the value "auto" and + * Integer.MAX_VALUE is used to represebt the value "always". + * @param keep the keep property + * @return the keep value as an integer + */ + public static int getKeepStrength(Property keep) { + if (keep.isAuto()) { + return BlockLevelLayoutManager.KEEP_AUTO; + } else if (keep.getEnum() == Constants.EN_ALWAYS) { + return BlockLevelLayoutManager.KEEP_ALWAYS; + } else { + return keep.getNumber().intValue(); + } + } + + /** + * Returns the penalty value to be used for a certain keep strength. + * <ul> + * <li>"auto": returns 0</li> + * <li>"always": returns KnuthElement.INFINITE</li> + * <li>otherwise: returns KnuthElement.INFINITE - 1</li> + * </ul> + * @param keepStrength the keep strength + * @return the penalty value + */ + public static int getPenaltyForKeep(int keepStrength) { + if (keepStrength == BlockLevelLayoutManager.KEEP_AUTO) { + return 0; + } + int penalty = KnuthElement.INFINITE; + if (keepStrength < BlockLevelLayoutManager.KEEP_ALWAYS) { + penalty--; + } + return penalty; + } + +} diff --git a/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java index 763ddf58d..0d88f2a1d 100644 --- a/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java @@ -405,5 +405,10 @@ public class StaticContentLayoutManager extends BlockStackingLayoutManager { this.contentAreaBPD = contentAreaBPD; } + /** {@inheritDoc} */ + public int getKeepTogetherStrength() { + return KEEP_AUTO; + } + } diff --git a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java index 1258fbe18..08a3f3eff 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java @@ -1271,13 +1271,16 @@ public class LineLayoutManager extends InlineStackingLayoutManager } } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public boolean mustKeepTogether() { return ((BlockLevelLayoutManager) getParent()).mustKeepTogether(); } + /** {@inheritDoc} */ + public int getKeepTogetherStrength() { + return ((BlockLevelLayoutManager) getParent()).getKeepTogetherStrength(); + } + /** * {@inheritDoc} */ diff --git a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java index c17ddc711..eb64e0bf0 100644 --- a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java @@ -32,6 +32,7 @@ import org.apache.fop.fo.flow.ListBlock; import org.apache.fop.layoutmgr.BlockStackingLayoutManager; import org.apache.fop.layoutmgr.ConditionalElementListener; import org.apache.fop.layoutmgr.ElementListUtils; +import org.apache.fop.layoutmgr.KeepUtil; import org.apache.fop.layoutmgr.LayoutContext; import org.apache.fop.layoutmgr.LayoutManager; import org.apache.fop.layoutmgr.NonLeafPosition; @@ -278,15 +279,19 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager } /** {@inheritDoc} */ - public boolean mustKeepTogether() { - //TODO Keeps will have to be more sophisticated sooner or later - return super.mustKeepTogether() - || !getListBlockFO().getKeepTogether().getWithinPage().isAuto() - || !getListBlockFO().getKeepTogether().getWithinColumn().isAuto(); + public int getKeepTogetherStrength() { + int strength = KEEP_AUTO; + strength = Math.max(strength, KeepUtil.getKeepStrength( + getListBlockFO().getKeepTogether().getWithinPage())); + strength = Math.max(strength, KeepUtil.getKeepStrength( + getListBlockFO().getKeepTogether().getWithinColumn())); + strength = Math.max(strength, getParentKeepTogetherStrength()); + return strength; } - + /** {@inheritDoc} */ public boolean mustKeepWithPrevious() { + //TODO Keeps will have to be more sophisticated sooner or later return !getListBlockFO().getKeepWithPrevious().getWithinPage().isAuto() || !getListBlockFO().getKeepWithPrevious().getWithinColumn().isAuto(); } diff --git a/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java index 8b0028a8f..be7dbdbba 100644 --- a/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java @@ -28,8 +28,8 @@ import org.apache.fop.area.Block; 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.KeepUtil; import org.apache.fop.layoutmgr.LayoutContext; import org.apache.fop.layoutmgr.LayoutManager; import org.apache.fop.layoutmgr.NonLeafPosition; @@ -221,12 +221,15 @@ public class ListItemContentLayoutManager extends BlockStackingLayoutManager { } /** {@inheritDoc} */ - 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(); + public int getKeepTogetherStrength() { + int strength = KEEP_AUTO; + strength = Math.max(strength, KeepUtil.getKeepStrength( + getPartFO().getKeepTogether().getWithinPage())); + strength = Math.max(strength, KeepUtil.getKeepStrength( + getPartFO().getKeepTogether().getWithinColumn())); + strength = Math.max(strength, getParentKeepTogetherStrength()); + return strength; } - + } diff --git a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java index c6b5b8cf9..b727f8860 100644 --- a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java @@ -32,12 +32,12 @@ import org.apache.fop.area.Block; 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.BreakElement; import org.apache.fop.layoutmgr.ConditionalElementListener; import org.apache.fop.layoutmgr.ElementListObserver; import org.apache.fop.layoutmgr.ElementListUtils; +import org.apache.fop.layoutmgr.KeepUtil; import org.apache.fop.layoutmgr.KnuthBox; import org.apache.fop.layoutmgr.KnuthElement; import org.apache.fop.layoutmgr.KnuthPenalty; @@ -305,14 +305,17 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager //Additional penalty height from penalties in the source lists int additionalPenaltyHeight = 0; + int stepPenalty = 0; KnuthElement endEl = (KnuthElement)elementLists[0].get(end[0]); if (endEl instanceof KnuthPenalty) { additionalPenaltyHeight = endEl.getW(); + stepPenalty = Math.max(stepPenalty, endEl.getP()); } endEl = (KnuthElement)elementLists[1].get(end[1]); if (endEl instanceof KnuthPenalty) { additionalPenaltyHeight = Math.max( additionalPenaltyHeight, endEl.getW()); + stepPenalty = Math.max(stepPenalty, endEl.getP()); } int boxHeight = step - addedBoxHeight - penaltyHeight; @@ -324,10 +327,13 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager start[0], end[0], start[1], end[1]); returnList.add(new KnuthBox(boxHeight, stepPosition, false)); if (addedBoxHeight < totalHeight) { - int p = 0; - if (keepWithNextActive || mustKeepTogether()) { + int p = stepPenalty; + if (keepWithNextActive) { p = KnuthPenalty.INFINITE; } + if (mustKeepTogether()) { + p = Math.max(p, KeepUtil.getPenaltyForKeep(getKeepTogetherStrength())); + } returnList.add(new BreakElement(stepPosition, penaltyHeight, p, -1, context)); } } @@ -630,15 +636,19 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager } /** {@inheritDoc} */ - 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(); + public int getKeepTogetherStrength() { + int strength = KEEP_AUTO; + strength = Math.max(strength, KeepUtil.getKeepStrength( + getListItemFO().getKeepTogether().getWithinPage())); + strength = Math.max(strength, KeepUtil.getKeepStrength( + getListItemFO().getKeepTogether().getWithinColumn())); + strength = Math.max(strength, getParentKeepTogetherStrength()); + return strength; } /** {@inheritDoc} */ public boolean mustKeepWithPrevious() { + //TODO Keeps will have to be more sophisticated sooner or later return !getListItemFO().getKeepWithPrevious().getWithinPage().isAuto() || !getListItemFO().getKeepWithPrevious().getWithinColumn().isAuto(); } diff --git a/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java index 2e5bbdf1f..fc0d587ff 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java @@ -19,12 +19,12 @@ package org.apache.fop.layoutmgr.table; +import org.apache.fop.area.Area; +import org.apache.fop.area.Block; import org.apache.fop.fo.flow.table.TableAndCaption; import org.apache.fop.layoutmgr.BlockStackingLayoutManager; import org.apache.fop.layoutmgr.LayoutContext; import org.apache.fop.layoutmgr.PositionIterator; -import org.apache.fop.area.Area; -import org.apache.fop.area.Block; /** * LayoutManager for a table-and-caption FO. @@ -191,5 +191,18 @@ public class TableAndCaptionLayoutManager extends BlockStackingLayoutManager { curBlockArea.addBlock((Block) childArea); } } -} - + + /** {@inheritDoc} */ + public int getKeepTogetherStrength() { + int strength = KEEP_AUTO; + /* TODO Complete me! + strength = Math.max(strength, KeepUtil.getKeepStrength( + getTableAndCaption().getKeepTogether().getWithinPage())); + strength = Math.max(strength, KeepUtil.getKeepStrength( + getTableAndCaption().getKeepTogether().getWithinColumn())); + */ + strength = Math.max(strength, getParentKeepTogetherStrength()); + return strength; + } + +}
\ No newline at end of file diff --git a/src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java index 674fd9a90..8c4908547 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java @@ -19,12 +19,12 @@ package org.apache.fop.layoutmgr.table; +import org.apache.fop.area.Area; +import org.apache.fop.area.Block; import org.apache.fop.fo.flow.table.TableCaption; import org.apache.fop.layoutmgr.BlockStackingLayoutManager; import org.apache.fop.layoutmgr.LayoutContext; import org.apache.fop.layoutmgr.PositionIterator; -import org.apache.fop.area.Area; -import org.apache.fop.area.Block; /** * LayoutManager for a table-caption FO. @@ -46,6 +46,11 @@ public class TableCaptionLayoutManager extends BlockStackingLayoutManager { super(node); } + /** @return the table-caption FO */ + public TableCaption getTableCaption() { + return (TableCaption)this.fobj; + } + /** * Get the next break position for the caption. * @@ -190,5 +195,19 @@ public class TableCaptionLayoutManager extends BlockStackingLayoutManager { curBlockArea.addBlock((Block) childArea); } } + + /** {@inheritDoc} */ + public int getKeepTogetherStrength() { + int strength = KEEP_AUTO; + /* TODO Complete me! + strength = Math.max(strength, KeepUtil.getKeepStrength( + getTableCaption().getKeepTogether().getWithinPage())); + strength = Math.max(strength, KeepUtil.getKeepStrength( + getTableCaption().getKeepTogether().getWithinColumn())); + */ + strength = Math.max(strength, getParentKeepTogetherStrength()); + return strength; + } + } diff --git a/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java index 8acfebca0..291e27ae2 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java @@ -27,7 +27,6 @@ import org.apache.commons.logging.LogFactory; import org.apache.fop.area.Area; import org.apache.fop.area.Block; import org.apache.fop.area.Trait; -import org.apache.fop.datatypes.PercentBaseContext; import org.apache.fop.fo.flow.table.ConditionalBorder; import org.apache.fop.fo.flow.table.GridUnit; import org.apache.fop.fo.flow.table.PrimaryGridUnit; @@ -41,13 +40,12 @@ import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo; import org.apache.fop.layoutmgr.AreaAdditionUtil; import org.apache.fop.layoutmgr.BlockLevelLayoutManager; import org.apache.fop.layoutmgr.BlockStackingLayoutManager; -import org.apache.fop.layoutmgr.BreakElement; +import org.apache.fop.layoutmgr.KeepUtil; import org.apache.fop.layoutmgr.KnuthBox; import org.apache.fop.layoutmgr.KnuthElement; import org.apache.fop.layoutmgr.KnuthGlue; import org.apache.fop.layoutmgr.KnuthPenalty; import org.apache.fop.layoutmgr.LayoutContext; -import org.apache.fop.layoutmgr.ListElement; import org.apache.fop.layoutmgr.Position; import org.apache.fop.layoutmgr.PositionIterator; import org.apache.fop.layoutmgr.SpaceResolver; @@ -162,46 +160,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager if (prevLM != null) { // there is a block handled by prevLM // before the one handled by curLM - if (mustKeepTogether() - || 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 BreakElement( - new Position(this), KnuthElement.INFINITE, context)); - //contentList.add(new KnuthPenalty(0, - // KnuthElement.INFINITE, false, - // new Position(this), false)); - } else if (!(((ListElement) contentList.getLast()).isGlue() - || (((ListElement)contentList.getLast()).isPenalty() - && ((KnuthPenalty)contentList.getLast()).getP() < KnuthElement.INFINITE) - || (contentList.getLast() instanceof BreakElement - && ((BreakElement)contentList.getLast()).getPenaltyValue() < KnuthElement.INFINITE))) { - // TODO vh: this is hacky - // The getNextKnuthElements method of TableCellLM must not be called - // twice, otherwise some settings like indents or borders will be - // counted several times and lead to a wrong output. Anyway the - // getNextKnuthElements methods should be called only once eventually - // (i.e., when multi-threading the code), even when there are forced - // breaks. - // If we add a break possibility after a forced break the - // AreaAdditionUtil.addAreas method will act on a sequence starting - // with a SpaceResolver.SpaceHandlingBreakPosition element, having no - // LM associated to it. Thus it will stop early instead of adding - // areas for following Positions. The above test aims at preventing - // such a situation from occurring. add a null penalty to allow a break - // between blocks - contentList.add(new BreakElement( - new Position(this), 0, context)); - //contentList.add(new KnuthPenalty(0, 0, false, - // new Position(this), false)); - } else { - // the last element in contentList is a feasible breakpoint, there is - // no need to add a penalty - } + addInBetweenBreak(contentList, context, childLC); } contentList.addAll(returnedList); if (returnedList.size() == 0) { @@ -596,22 +555,22 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager // TODO Auto-generated method stub } - /** - * {@inheritDoc} - */ - public boolean mustKeepTogether() { - //TODO Keeps will have to be more sophisticated sooner or later - boolean keep = ((BlockLevelLayoutManager)getParent()).mustKeepTogether(); + /** {@inheritDoc} */ + public int getKeepTogetherStrength() { + int strength = KEEP_AUTO; if (primaryGridUnit.getRow() != null) { - keep |= primaryGridUnit.getRow().mustKeepTogether(); + strength = Math.max(strength, KeepUtil.getKeepStrength( + primaryGridUnit.getRow().getKeepTogether().getWithinPage())); + strength = Math.max(strength, KeepUtil.getKeepStrength( + primaryGridUnit.getRow().getKeepTogether().getWithinColumn())); } - return keep; + strength = Math.max(strength, getParentKeepTogetherStrength()); + return strength; } - - /** - * {@inheritDoc} - */ + + /** {@inheritDoc} */ public boolean mustKeepWithPrevious() { + //TODO Keeps will have to be more sophisticated sooner or later return false; //TODO FIX ME /* return !fobj.getKeepWithPrevious().getWithinPage().isAuto() @@ -619,9 +578,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager */ } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public boolean mustKeepWithNext() { return false; //TODO FIX ME /* diff --git a/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java index 7cdeb79d5..235bc1fd2 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java @@ -27,6 +27,7 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.apache.fop.datatypes.PercentBaseContext; import org.apache.fop.fo.Constants; import org.apache.fop.fo.FObj; @@ -36,6 +37,7 @@ import org.apache.fop.fo.flow.table.Table; import org.apache.fop.fo.flow.table.TableBody; import org.apache.fop.layoutmgr.BreakElement; import org.apache.fop.layoutmgr.ElementListUtils; +import org.apache.fop.layoutmgr.KeepUtil; import org.apache.fop.layoutmgr.KnuthBox; import org.apache.fop.layoutmgr.KnuthElement; import org.apache.fop.layoutmgr.KnuthPossPosIter; @@ -226,9 +228,12 @@ public class TableContentLayoutManager implements PercentBaseContext { nextRowGroupElems = rowGroupLM.getNextKnuthElements(context, alignment, bodyType); int penaltyValue = 0; keepBetween |= context.isKeepWithPreviousPending(); - if (keepBetween || tableLM.getTable().mustKeepTogether()) { + if (keepBetween) { penaltyValue = KnuthElement.INFINITE; } + penaltyValue = Math.max(penaltyValue, + KeepUtil.getPenaltyForKeep(getTableLM().getKeepTogetherStrength())); + breakBetween = BreakUtil.compareBreakClasses(breakBetween, context.getBreakBefore()); if (breakBetween != Constants.EN_AUTO) { diff --git a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java index 720ca5faa..5738a027c 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java @@ -39,6 +39,7 @@ import org.apache.fop.layoutmgr.BlockLevelEventProducer; import org.apache.fop.layoutmgr.BlockStackingLayoutManager; import org.apache.fop.layoutmgr.BreakElement; import org.apache.fop.layoutmgr.ConditionalElementListener; +import org.apache.fop.layoutmgr.KeepUtil; import org.apache.fop.layoutmgr.KnuthElement; import org.apache.fop.layoutmgr.KnuthGlue; import org.apache.fop.layoutmgr.LayoutContext; @@ -445,16 +446,17 @@ public class TableLayoutManager extends BlockStackingLayoutManager } - /** - * {@inheritDoc} - */ - public boolean mustKeepTogether() { - //TODO Keeps will have to be more sophisticated sooner or later - return super.mustKeepTogether() - || !getTable().getKeepTogether().getWithinPage().isAuto() - || !getTable().getKeepTogether().getWithinColumn().isAuto(); + /** {@inheritDoc} */ + public int getKeepTogetherStrength() { + int strength = KEEP_AUTO; + strength = Math.max(strength, KeepUtil.getKeepStrength( + getTable().getKeepTogether().getWithinPage())); + strength = Math.max(strength, KeepUtil.getKeepStrength( + getTable().getKeepTogether().getWithinColumn())); + strength = Math.max(strength, getParentKeepTogetherStrength()); + return strength; } - + /** * {@inheritDoc} */ diff --git a/src/java/org/apache/fop/layoutmgr/table/TableStepper.java b/src/java/org/apache/fop/layoutmgr/table/TableStepper.java index ba67e38e4..07894a07b 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableStepper.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableStepper.java @@ -25,11 +25,13 @@ import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.apache.fop.fo.Constants; import org.apache.fop.fo.flow.table.EffRow; import org.apache.fop.fo.flow.table.GridUnit; import org.apache.fop.fo.flow.table.PrimaryGridUnit; import org.apache.fop.layoutmgr.BreakElement; +import org.apache.fop.layoutmgr.KeepUtil; import org.apache.fop.layoutmgr.KnuthBox; import org.apache.fop.layoutmgr.KnuthGlue; import org.apache.fop.layoutmgr.KnuthPenalty; @@ -234,13 +236,15 @@ public class TableStepper { ActiveCell activeCell = (ActiveCell) iter.next(); keepWithNext |= activeCell.keepWithNextSignal(); } - if (keepWithNext || getTableLM().mustKeepTogether()) { + if (keepWithNext) { p = KnuthPenalty.INFINITE; } if (!rowFinished) { - if (rowGroup[activeRowIndex].mustKeepTogether()) { - p = KnuthPenalty.INFINITE; - } + p = Math.max(p, KeepUtil.getPenaltyForKeep( + rowGroup[activeRowIndex].getKeepTogetherStrength())); + //The above call doesn't take the penalty from the table into account, so... + p = Math.max(p, KeepUtil.getPenaltyForKeep( + getTableLM().getKeepTogetherStrength())); } else if (activeRowIndex < rowGroup.length - 1) { if (rowGroup[activeRowIndex].mustKeepWithNext() || rowGroup[activeRowIndex + 1].mustKeepWithPrevious()) { |