Index: src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java =================================================================== --- src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java (revision 757829) +++ src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java (working copy) @@ -415,18 +415,18 @@ } /** {@inheritDoc} */ - public int getKeepTogetherStrength() { - return KEEP_AUTO; + public Keep getKeepTogether() { + return Keep.KEEP_AUTO; } /** {@inheritDoc} */ - public int getKeepWithNextStrength() { - return KEEP_AUTO; + public Keep getKeepWithNext() { + return Keep.KEEP_AUTO; } /** {@inheritDoc} */ - public int getKeepWithPreviousStrength() { - return KEEP_AUTO; + public Keep getKeepWithPrevious() { + return Keep.KEEP_AUTO; } } Index: src/java/org/apache/fop/layoutmgr/KeepUtil.java =================================================================== --- src/java/org/apache/fop/layoutmgr/KeepUtil.java (revision 757829) +++ src/java/org/apache/fop/layoutmgr/KeepUtil.java (working copy) @@ -1,109 +0,0 @@ -/* - * 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.KeepProperty; -import org.apache.fop.fo.properties.Property; - -/** - * Utility class for working with keeps. - */ -public class KeepUtil { - - /** - * Converts a keep property into an integer value. - *

- * 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 combined block-level keep strength from a keep property. - *

- * Note: This is a temporary method to be used until it is possible to differentiate between - * page and column keeps! - * @param keep the keep property - * @return the combined keep strength - */ - public static int getCombinedBlockLevelKeepStrength(KeepProperty keep) { - return Math.max( - getKeepStrength(keep.getWithinPage()), - getKeepStrength(keep.getWithinColumn())); - } - - /** - * Indicates whether a keep strength indicates a keep constraint. - * @param strength the keep strength - * @return true if the keep is not "auto" - */ - public static boolean hasKeep(int strength) { - return strength > BlockLevelLayoutManager.KEEP_AUTO; - } - - /** - * Returns the penalty value to be used for a certain keep strength. - *

- * @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; - } - - /** - * Returns a string representation of a keep strength value. - * @param keepStrength the keep strength - * @return the string representation - */ - public static String keepStrengthToString(int keepStrength) { - if (keepStrength == BlockLevelLayoutManager.KEEP_AUTO) { - return "auto"; - } else if (keepStrength == BlockLevelLayoutManager.KEEP_ALWAYS) { - return "always"; - } else { - return Integer.toString(keepStrength); - } - } - -} Index: src/java/org/apache/fop/layoutmgr/KnuthPenalty.java =================================================================== --- src/java/org/apache/fop/layoutmgr/KnuthPenalty.java (revision 757829) +++ src/java/org/apache/fop/layoutmgr/KnuthPenalty.java (working copy) @@ -169,6 +169,17 @@ } sb.append(")"); } + switch (getBreakClass()) { + case Constants.EN_PAGE: + sb.append(" (page context)"); + break; + case Constants.EN_COLUMN: + sb.append(" (column context)"); + break; + case Constants.EN_LINE: + sb.append(" (line context)"); + break; + } return sb.toString(); } Index: src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java =================================================================== --- src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java (revision 757829) +++ src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java (working copy) @@ -36,6 +36,7 @@ import org.apache.fop.fo.Constants; import org.apache.fop.fo.flow.Block; import org.apache.fop.fo.properties.CommonHyphenation; +import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontInfo; import org.apache.fop.fonts.FontTriplet; @@ -46,7 +47,7 @@ import org.apache.fop.layoutmgr.BreakingAlgorithm; import org.apache.fop.layoutmgr.ElementListObserver; import org.apache.fop.layoutmgr.InlineKnuthSequence; -import org.apache.fop.layoutmgr.KeepUtil; +import org.apache.fop.layoutmgr.Keep; import org.apache.fop.layoutmgr.KnuthBlockBox; import org.apache.fop.layoutmgr.KnuthBox; import org.apache.fop.layoutmgr.KnuthElement; @@ -1054,12 +1055,12 @@ for (int p = 0; p < knuthParagraphs.size(); p++) { // penalty between paragraphs if (p > 0) { - int strength = getKeepTogetherStrength(); - int penalty = KeepUtil.getPenaltyForKeep(strength); - if (penalty < KnuthElement.INFINITE) { + Keep keep = getKeepTogether(); + int penalty = keep.getPenalty(); +// if (penalty < KnuthElement.INFINITE) { returnList.add(new BreakElement( - new Position(this), penalty, context)); - } + new Position(this), penalty, keep.getContext(), context)); +// } } LineLayoutPossibilities llPoss; @@ -1098,12 +1099,12 @@ && i >= fobj.getOrphans() && i <= llPoss.getChosenLineCount() - fobj.getWidows()) { // penalty allowing a page break between lines - int strength = getKeepTogetherStrength(); - int penalty = KeepUtil.getPenaltyForKeep(strength); - if (penalty < KnuthElement.INFINITE) { + Keep keep = getKeepTogether(); + int penalty = keep.getPenalty(); +// if (penalty < KnuthElement.INFINITE) { returnList.add(new BreakElement( - returnPosition, penalty, context)); - } + returnPosition, penalty, keep.getContext(), context)); +// } } int endIndex = ((LineBreakPosition) llPoss.getChosenPosition(i)).getLeafPos(); @@ -1283,28 +1284,43 @@ } /** {@inheritDoc} */ - public int getKeepTogetherStrength() { - return ((BlockLevelLayoutManager) getParent()).getKeepTogetherStrength(); + public KeepProperty getKeepTogetherProperty() { + return ((BlockLevelLayoutManager) getParent()).getKeepTogetherProperty(); } /** {@inheritDoc} */ + public KeepProperty getKeepWithPreviousProperty() { + return ((BlockLevelLayoutManager) getParent()).getKeepWithPreviousProperty(); + } + + /** {@inheritDoc} */ + public KeepProperty getKeepWithNextProperty() { + return ((BlockLevelLayoutManager) getParent()).getKeepWithNextProperty(); + } + + /** {@inheritDoc} */ + public Keep getKeepTogether() { + return ((BlockLevelLayoutManager) getParent()).getKeepTogether(); + } + + /** {@inheritDoc} */ public boolean mustKeepWithPrevious() { - return getKeepWithPreviousStrength() > KEEP_AUTO; + return !getKeepWithPrevious().isAuto(); } /** {@inheritDoc} */ public boolean mustKeepWithNext() { - return getKeepWithNextStrength() > KEEP_AUTO; + return !getKeepWithNext().isAuto(); } /** {@inheritDoc} */ - public int getKeepWithNextStrength() { - return KEEP_AUTO; + public Keep getKeepWithNext() { + return Keep.KEEP_AUTO; } /** {@inheritDoc} */ - public int getKeepWithPreviousStrength() { - return KEEP_AUTO; + public Keep getKeepWithPrevious() { + return Keep.KEEP_AUTO; } /** {@inheritDoc} */ Index: src/java/org/apache/fop/layoutmgr/AbstractBreaker.java =================================================================== --- src/java/org/apache/fop/layoutmgr/AbstractBreaker.java (revision 757829) +++ src/java/org/apache/fop/layoutmgr/AbstractBreaker.java (working copy) @@ -399,7 +399,13 @@ ListElement lastBreakElement = effectiveList.getElement(endElementIndex); if (lastBreakElement.isPenalty()) { KnuthPenalty pen = (KnuthPenalty)lastBreakElement; - lastBreakClass = pen.getBreakClass(); + // TODO Handle keep.within-column differently so that break class is + // automatically set to the right value + if (pen.getP() >= KnuthPenalty.INFINITE - 1) { + lastBreakClass = Constants.EN_COLUMN; + } else { + lastBreakClass = pen.getBreakClass(); + } } else { lastBreakClass = Constants.EN_COLUMN; } Index: src/java/org/apache/fop/layoutmgr/BlockLevelLayoutManager.java =================================================================== --- src/java/org/apache/fop/layoutmgr/BlockLevelLayoutManager.java (revision 757829) +++ src/java/org/apache/fop/layoutmgr/BlockLevelLayoutManager.java (working copy) @@ -19,6 +19,8 @@ package org.apache.fop.layoutmgr; +import org.apache.fop.fo.properties.KeepProperty; + /** * The interface for LayoutManagers which generate block areas */ @@ -35,20 +37,21 @@ /** 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); + KeepProperty getKeepTogetherProperty(); + + KeepProperty getKeepWithPreviousProperty(); + + KeepProperty getKeepWithNextProperty(); + /** * Returns the keep-together strength for this element. * @return the keep-together strength */ - int getKeepTogetherStrength(); + Keep getKeepTogether(); /** * @return true if this element must be kept together @@ -59,7 +62,7 @@ * Returns the keep-with-previous strength for this element. * @return the keep-with-previous strength */ - int getKeepWithPreviousStrength(); + Keep getKeepWithPrevious(); /** * @return true if this element must be kept with the previous element. @@ -70,7 +73,7 @@ * Returns the keep-with-next strength for this element. * @return the keep-with-next strength */ - int getKeepWithNextStrength(); + Keep getKeepWithNext(); /** * @return true if this element must be kept with the next element. Index: src/java/org/apache/fop/layoutmgr/LayoutContext.java =================================================================== --- src/java/org/apache/fop/layoutmgr/LayoutContext.java (revision 757829) +++ src/java/org/apache/fop/layoutmgr/LayoutContext.java (working copy) @@ -145,8 +145,8 @@ private int breakBefore; private int breakAfter; - private int pendingKeepWithNext = BlockLevelLayoutManager.KEEP_AUTO; - private int pendingKeepWithPrevious = BlockLevelLayoutManager.KEEP_AUTO; + private Keep pendingKeepWithNext = Keep.KEEP_AUTO; + private Keep pendingKeepWithPrevious = Keep.KEEP_AUTO; private int disableColumnBalancing; @@ -237,7 +237,7 @@ * Returns the strength of a keep-with-next currently pending. * @return the keep-with-next strength */ - public int getKeepWithNextPending() { + public Keep getKeepWithNextPending() { return this.pendingKeepWithNext; } @@ -245,7 +245,7 @@ * Returns the strength of a keep-with-previous currently pending. * @return the keep-with-previous strength */ - public int getKeepWithPreviousPending() { + public Keep getKeepWithPreviousPending() { return this.pendingKeepWithPrevious; } @@ -253,14 +253,14 @@ * Clears any pending keep-with-next strength. */ public void clearKeepWithNextPending() { - this.pendingKeepWithNext = BlockLevelLayoutManager.KEEP_AUTO; + this.pendingKeepWithNext = Keep.KEEP_AUTO; } /** * Clears any pending keep-with-previous strength. */ public void clearKeepWithPreviousPending() { - this.pendingKeepWithPrevious = BlockLevelLayoutManager.KEEP_AUTO; + this.pendingKeepWithPrevious = Keep.KEEP_AUTO; } /** @@ -273,18 +273,18 @@ /** * Updates the currently pending keep-with-next strength. - * @param strength the new strength to consider + * @param keep the new strength to consider */ - public void updateKeepWithNextPending(int strength) { - this.pendingKeepWithNext = Math.max(this.pendingKeepWithNext, strength); + public void updateKeepWithNextPending(Keep keep) { + this.pendingKeepWithNext = this.pendingKeepWithNext.compare(keep); } /** * Updates the currently pending keep-with-previous strength. - * @param strength the new strength to consider + * @param keep the new strength to consider */ - public void updateKeepWithPreviousPending(int strength) { - this.pendingKeepWithPrevious = Math.max(this.pendingKeepWithPrevious, strength); + public void updateKeepWithPreviousPending(Keep keep) { + this.pendingKeepWithPrevious = this.pendingKeepWithPrevious.compare(keep); } /** @@ -292,7 +292,7 @@ * @return true if a keep-with-next constraint is pending */ public boolean isKeepWithNextPending() { - return getKeepWithNextPending() != BlockLevelLayoutManager.KEEP_AUTO; + return !getKeepWithNextPending().isAuto(); } /** @@ -300,7 +300,7 @@ * @return true if a keep-with-previous constraint is pending */ public boolean isKeepWithPreviousPending() { - return getKeepWithPreviousPending() != BlockLevelLayoutManager.KEEP_AUTO; + return !getKeepWithPreviousPending().isAuto(); } public void setLeadingSpace(SpaceSpecifier space) { @@ -677,9 +677,8 @@ + "\nStarts New Area: \t" + startsNewArea() + "\nIs Last Area: \t" + isLastArea() + "\nTry Hyphenate: \t" + tryHyphenate() - + "\nKeeps: \t[keep-with-next=" + KeepUtil.keepStrengthToString(getKeepWithNextPending()) - + "][keep-with-previous=" - + KeepUtil.keepStrengthToString(getKeepWithPreviousPending()) + "] pending" + + "\nKeeps: \t[keep-with-next=" + getKeepWithNextPending() + + "][keep-with-previous=" + getKeepWithPreviousPending() + "] pending" + "\nBreaks: \tforced [" + (breakBefore != Constants.EN_AUTO ? "break-before" : "") + "][" + (breakAfter != Constants.EN_AUTO ? "break-after" : "") + "]"; } Index: src/java/org/apache/fop/layoutmgr/Keep.java =================================================================== --- src/java/org/apache/fop/layoutmgr/Keep.java (revision 0) +++ src/java/org/apache/fop/layoutmgr/Keep.java (revision 0) @@ -0,0 +1,132 @@ +/* + * 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.KeepProperty; +import org.apache.fop.fo.properties.Property; + +/** + * TODO javadoc + */ +public class Keep { + + private static final int STRENGTH_AUTO = Integer.MIN_VALUE; + + private static final int STRENGTH_ALWAYS = Integer.MAX_VALUE; + + /** The integer value for "auto" keep strength. */ + public static final Keep KEEP_AUTO = new Keep(STRENGTH_AUTO, Constants.EN_AUTO); + + /** The integer value for "always" keep strength. */ + public static final Keep KEEP_ALWAYS = new Keep(STRENGTH_ALWAYS, Constants.EN_LINE); + + private int strength; + + private int context; + + private Keep(int strength, int context) { + this.strength = strength; + this.context = context; + } + + private static int getKeepStrength(Property keep) { + if (keep.isAuto()) { + return STRENGTH_AUTO; + } else if (keep.getEnum() == Constants.EN_ALWAYS) { + return STRENGTH_ALWAYS; + } else { + return keep.getNumber().intValue(); + } + } + + public static Keep getKeep(KeepProperty keepProperty) { + Keep keep = new Keep(STRENGTH_AUTO, Constants.EN_AUTO); + keep.update(keepProperty.getWithinPage(), Constants.EN_PAGE); + keep.update(keepProperty.getWithinColumn(), Constants.EN_COLUMN); + keep.update(keepProperty.getWithinLine(), Constants.EN_LINE); + return keep; + } + + private void update(Property keep, int context) { + if (!keep.isAuto()) { + this.strength = getKeepStrength(keep); + this.context = context; + } + } + + public boolean isAuto() { + return strength == STRENGTH_AUTO; + } + + /** + * Returns the context of this keep. + * + * @return one of {@link Constants#EN_LINE}, {@link Constants#EN_COLUMN} or + * {@link Constants#EN_PAGE} + */ + public int getContext() { + return context; + } + + public int getPenalty() { + if (strength == STRENGTH_AUTO) { + return 0; + } else if (strength == STRENGTH_ALWAYS) { + return KnuthElement.INFINITE; + } else { + return KnuthElement.INFINITE - 1; + } + } + + private static int getKeepContextPriority(int context) { + switch (context) { + case Constants.EN_LINE: return 0; + case Constants.EN_COLUMN: return 1; + case Constants.EN_PAGE: return 2; + case Constants.EN_AUTO: return 3; + default: throw new IllegalArgumentException(); + } + } + + public Keep compare(Keep other) { + int pThis = getKeepContextPriority(this.context); + int pOther = getKeepContextPriority(other.context); + if (pThis < pOther) { + return this; + } else if (pThis > pOther) { + return other; + } else if (strength >= other.strength) { + return this; + } else { + return other; + } + } + + /** {@inheritDoc} */ + public String toString() { + if (strength == STRENGTH_AUTO) { + return "auto"; + } else if (strength == STRENGTH_ALWAYS) { + return "always"; + } else { + return Integer.toString(strength); + } + } + +} Property changes on: src/java/org/apache/fop/layoutmgr/Keep.java ___________________________________________________________________ Added: svn:keywords + Revision Id Added: svn:eol-style + native Index: src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java =================================================================== --- src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java (revision 757829) +++ src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java (working copy) @@ -37,6 +37,7 @@ import org.apache.fop.datatypes.Length; import org.apache.fop.fo.flow.BlockContainer; import org.apache.fop.fo.properties.CommonAbsolutePosition; +import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.traits.MinOptMax; import org.apache.fop.traits.SpaceVal; import org.apache.fop.util.ListUtil; @@ -261,7 +262,7 @@ if (!firstVisibleMarkServed) { addKnuthElementsForSpaceBefore(returnList, alignment); - context.updateKeepWithPreviousPending(getKeepWithPreviousStrength()); + context.updateKeepWithPreviousPending(getKeepWithPrevious()); } addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed); @@ -391,7 +392,7 @@ context.clearPendingMarks(); addKnuthElementsForBreakAfter(returnList, context); - context.updateKeepWithNextPending(getKeepWithNextStrength()); + context.updateKeepWithNextPending(getKeepWithNext()); setFinished(true); return returnList; @@ -1011,23 +1012,18 @@ } /** {@inheritDoc} */ - public int getKeepTogetherStrength() { - int strength = KeepUtil.getCombinedBlockLevelKeepStrength( - getBlockContainerFO().getKeepTogether()); - strength = Math.max(strength, getParentKeepTogetherStrength()); - return strength; + public KeepProperty getKeepTogetherProperty() { + return getBlockContainerFO().getKeepTogether(); } /** {@inheritDoc} */ - public int getKeepWithNextStrength() { - return KeepUtil.getCombinedBlockLevelKeepStrength( - getBlockContainerFO().getKeepWithNext()); + public KeepProperty getKeepWithPreviousProperty() { + return getBlockContainerFO().getKeepWithPrevious(); } /** {@inheritDoc} */ - public int getKeepWithPreviousStrength() { - return KeepUtil.getCombinedBlockLevelKeepStrength( - getBlockContainerFO().getKeepWithPrevious()); + public KeepProperty getKeepWithNextProperty() { + return getBlockContainerFO().getKeepWithNext(); } /** Index: src/java/org/apache/fop/layoutmgr/BreakElement.java =================================================================== --- src/java/org/apache/fop/layoutmgr/BreakElement.java (revision 757829) +++ src/java/org/apache/fop/layoutmgr/BreakElement.java (working copy) @@ -41,9 +41,13 @@ * @param context the layout context which contains the pending conditional elements */ public BreakElement(Position position, int penaltyValue, LayoutContext context) { - this(position, 0, penaltyValue, -1, context); + this(position, penaltyValue, -1, context); } + public BreakElement(Position position, int penaltyValue, int breakClass, LayoutContext context) { + this(position, 0, penaltyValue, breakClass, context); + } + /** * Constructor for hard breaks. * @@ -168,6 +172,17 @@ sb.append("; w:"); sb.append(penaltyWidth); sb.append("]"); + switch (getBreakClass()) { + case Constants.EN_PAGE: + sb.append(" (page context)"); + break; + case Constants.EN_COLUMN: + sb.append(" (column context)"); + break; + case Constants.EN_LINE: + sb.append(" (line context)"); + break; + } return sb.toString(); } Index: src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java =================================================================== --- src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java (revision 757829) +++ src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java (working copy) @@ -154,7 +154,7 @@ context.updateKeepWithNextPending(childLC.getKeepWithNextPending()); childLC.clearKeepWithNextPending(); - context.updateKeepWithNextPending(getKeepWithNextStrength()); + context.updateKeepWithNextPending(getKeepWithNext()); } SpaceResolver.resolveElementList(returnList); @@ -203,18 +203,18 @@ } /** {@inheritDoc} */ - public int getKeepTogetherStrength() { - return KEEP_AUTO; + public Keep getKeepTogether() { + return Keep.KEEP_AUTO; } /** {@inheritDoc} */ - public int getKeepWithNextStrength() { - return KEEP_AUTO; + public Keep getKeepWithNext() { + return Keep.KEEP_AUTO; } /** {@inheritDoc} */ - public int getKeepWithPreviousStrength() { - return KEEP_AUTO; + public Keep getKeepWithPrevious() { + return Keep.KEEP_AUTO; } /** {@inheritDoc} */ Index: src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java =================================================================== --- src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java (revision 757829) +++ src/java/org/apache/fop/layoutmgr/FootnoteBodyLayoutManager.java (working copy) @@ -92,18 +92,18 @@ } /** {@inheritDoc} */ - public int getKeepTogetherStrength() { - return getParentKeepTogetherStrength(); + public Keep getKeepTogether() { + return getParentKeepTogether(); } /** {@inheritDoc} */ - public int getKeepWithNextStrength() { - return KEEP_AUTO; + public Keep getKeepWithNext() { + return Keep.KEEP_AUTO; } /** {@inheritDoc} */ - public int getKeepWithPreviousStrength() { - return KEEP_AUTO; + public Keep getKeepWithPrevious() { + return Keep.KEEP_AUTO; } } Index: src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java =================================================================== --- src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java (revision 757829) +++ src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java (working copy) @@ -210,21 +210,18 @@ } /** {@inheritDoc} */ - public int getKeepTogetherStrength() { - KeepProperty keep = getBlockFO().getKeepTogether(); - int strength = KeepUtil.getCombinedBlockLevelKeepStrength(keep); - strength = Math.max(strength, getParentKeepTogetherStrength()); - return strength; + public KeepProperty getKeepTogetherProperty() { + return getBlockFO().getKeepTogether(); } /** {@inheritDoc} */ - public int getKeepWithNextStrength() { - return KeepUtil.getCombinedBlockLevelKeepStrength(getBlockFO().getKeepWithNext()); + public KeepProperty getKeepWithPreviousProperty() { + return getBlockFO().getKeepWithPrevious(); } /** {@inheritDoc} */ - public int getKeepWithPreviousStrength() { - return KeepUtil.getCombinedBlockLevelKeepStrength(getBlockFO().getKeepWithPrevious()); + public KeepProperty getKeepWithNextProperty() { + return getBlockFO().getKeepWithNext(); } /** {@inheritDoc} */ Index: src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java =================================================================== --- src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java (revision 757829) +++ src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java (working copy) @@ -26,6 +26,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.apache.fop.fo.Constants; import org.apache.fop.fo.FObj; import org.apache.fop.layoutmgr.AbstractBreaker.PageBreakPosition; @@ -185,6 +186,34 @@ footnoteElementIndex = -1; } + private boolean deferred = false; + private boolean overridePageKeep = false; + + protected KnuthNode recoverFromTooLong(KnuthNode lastTooLong) { + if (log.isDebugEnabled()) { + log.debug("Recovering from too long: " + lastTooLong); + } + KnuthNode node = lastTooLong.previous; + if (!deferred) { + deferred = true; + while (!pageProvider.startPage(lastTooLong.line - 1)) { + lastTooLong = lastTooLong.previous; + } + node = lastTooLong.previous; + // content would overflow, insert empty line/page and try again + for (int i = 0; i < pageProvider.getColumnCount(lastTooLong.previous.line); i++) { + node = createNode( + node.position, node.line + 1, 1, + 0, 0, 0, + 0, 0, 0, + 0, 0, node); + } +// } else { +// overridePageKeep = true; + } + return node; + } + protected KnuthNode createNode(int position, int line, int fitness, int totalWidth, int totalStretch, int totalShrink, double adjustRatio, int availableShrink, int availableStretch, @@ -309,6 +338,37 @@ newFootnotes = false; } + protected boolean elementCanEndLine(KnuthElement element, int line) { + if (!(element instanceof KnuthPenalty) || pageProvider == null) { + return true; + } else { + KnuthPenalty p = (KnuthPenalty) element; + if (p.getP() <= 0) { + return true; + } else { + int context = p.getBreakClass(); + switch (context) { + case Constants.EN_LINE: + case Constants.EN_COLUMN: + return p.getP() < KnuthPenalty.INFINITE; + case Constants.EN_PAGE: + return p.getP() < KnuthPenalty.INFINITE || overridePageKeep + || !pageProvider.endPage(line - 1); + case Constants.EN_AUTO: + log.warn("keep is not auto but context is"); + return true; + default: + if (p.getP() < KnuthPenalty.INFINITE) { + log.warn("Non recognized keep context:" + context); + return true; + } else { + return false; + } + } + } + } + } + protected int computeDifference(KnuthNode activeNode, KnuthElement element, int elementIndex) { KnuthPageNode pageNode = (KnuthPageNode) activeNode; @@ -561,11 +621,11 @@ splitLength += element.getW(); } else { // element is a penalty - if (element.getP() < KnuthElement.INFINITE) { +// if (element.getP() < KnuthElement.INFINITE) { // end of the sub-sequence index = noteListIterator.previousIndex(); break; - } +// } } } } @@ -625,7 +685,9 @@ double f = Math.abs(r); f = 1 + 100 * f * f * f; if (element.isPenalty() && element.getP() >= 0) { - f += element.getP(); + if (element.getP() < KnuthPenalty.INFINITE) { + f += element.getP(); + } demerits = f * f; } else if (element.isPenalty() && !element.isForcedBreak()) { double penalty = element.getP(); Index: src/java/org/apache/fop/layoutmgr/PageProvider.java =================================================================== --- src/java/org/apache/fop/layoutmgr/PageProvider.java (revision 757829) +++ src/java/org/apache/fop/layoutmgr/PageProvider.java (working copy) @@ -146,6 +146,33 @@ return this.lastReportedBPD; } + // Wish there were a more elegant way to do this in Java + private int[] getColIndexAndColCount(int index) { + int columnCount = 0; + int colIndex = startColumnOfCurrentElementList + index; + int pageIndex = -1; + do { + colIndex -= columnCount; + pageIndex++; + Page page = getPage(false, pageIndex, RELTO_CURRENT_ELEMENT_LIST); + columnCount = page.getPageViewport().getCurrentSpan().getColumnCount(); + } while (colIndex >= columnCount); + return new int[] {colIndex, columnCount}; + } + + boolean startPage(int index) { + return getColIndexAndColCount(index)[0] == 0; + } + + boolean endPage(int index) { + int[] colIndexAndColCount = getColIndexAndColCount(index); + return colIndexAndColCount[0] == colIndexAndColCount[1] - 1; + } + + int getColumnCount(int index) { + return getColIndexAndColCount(index)[1]; + } + /** * Returns the part index (0 0) { if (end[0] + 1 == elementLists[0].size()) { - keepWithNextActive = Math.max(keepWithNextActive, keepWithNextPendingOnLabel); + keepWithNextActive = keepWithNextActive.compare(keepWithNextPendingOnLabel); } if (end[1] + 1 == elementLists[1].size()) { - keepWithNextActive = Math.max(keepWithNextActive, keepWithNextPendingOnBody); + keepWithNextActive = keepWithNextActive.compare(keepWithNextPendingOnBody); } // compute penalty height and box height @@ -339,14 +339,13 @@ } if (addedBoxHeight < totalHeight) { - int strength = BlockLevelLayoutManager.KEEP_AUTO; - strength = Math.max(strength, keepWithNextActive); - strength = Math.max(strength, getKeepTogetherStrength()); + Keep keep = keepWithNextActive.compare(getKeepTogether()); int p = stepPenalty; if (p > -KnuthElement.INFINITE) { - p = Math.max(p, KeepUtil.getPenaltyForKeep(strength)); + p = Math.max(p, keep.getPenalty()); } - returnList.add(new BreakElement(stepPosition, penaltyHeight, p, -1, context)); + returnList.add(new BreakElement(stepPosition, penaltyHeight, p, keep.getContext(), + context)); } } @@ -644,21 +643,18 @@ } /** {@inheritDoc} */ - public int getKeepTogetherStrength() { - int strength = KeepUtil.getCombinedBlockLevelKeepStrength( - getListItemFO().getKeepTogether()); - strength = Math.max(strength, getParentKeepTogetherStrength()); - return strength; + public KeepProperty getKeepTogetherProperty() { + return getListItemFO().getKeepTogether(); } /** {@inheritDoc} */ - public int getKeepWithNextStrength() { - return KeepUtil.getCombinedBlockLevelKeepStrength(getListItemFO().getKeepWithNext()); + public KeepProperty getKeepWithPreviousProperty() { + return getListItemFO().getKeepWithPrevious(); } /** {@inheritDoc} */ - public int getKeepWithPreviousStrength() { - return KeepUtil.getCombinedBlockLevelKeepStrength(getListItemFO().getKeepWithPrevious()); + public KeepProperty getKeepWithNextProperty() { + return getListItemFO().getKeepWithNext(); } /** {@inheritDoc} */ Index: src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java =================================================================== --- src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java (revision 757829) +++ src/java/org/apache/fop/layoutmgr/list/ListItemContentLayoutManager.java (working copy) @@ -28,8 +28,9 @@ 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.fo.properties.KeepProperty; import org.apache.fop.layoutmgr.BlockStackingLayoutManager; -import org.apache.fop.layoutmgr.KeepUtil; +import org.apache.fop.layoutmgr.Keep; import org.apache.fop.layoutmgr.LayoutContext; import org.apache.fop.layoutmgr.LayoutManager; import org.apache.fop.layoutmgr.NonLeafPosition; @@ -221,20 +222,18 @@ } /** {@inheritDoc} */ - public int getKeepTogetherStrength() { - int strength = KeepUtil.getCombinedBlockLevelKeepStrength(getPartFO().getKeepTogether()); - strength = Math.max(strength, getParentKeepTogetherStrength()); - return strength; + public KeepProperty getKeepTogetherProperty() { + return getPartFO().getKeepTogether(); } /** {@inheritDoc} */ - public int getKeepWithNextStrength() { - return KEEP_AUTO; + public Keep getKeepWithNext() { + return Keep.KEEP_AUTO; } /** {@inheritDoc} */ - public int getKeepWithPreviousStrength() { - return KEEP_AUTO; + public Keep getKeepWithPrevious() { + return Keep.KEEP_AUTO; } } Index: src/java/org/apache/fop/layoutmgr/table/ActiveCell.java =================================================================== --- src/java/org/apache/fop/layoutmgr/table/ActiveCell.java (revision 757829) +++ src/java/org/apache/fop/layoutmgr/table/ActiveCell.java (working copy) @@ -25,13 +25,14 @@ 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.ConditionalBorder; import org.apache.fop.fo.flow.table.EffRow; import org.apache.fop.fo.flow.table.PrimaryGridUnit; import org.apache.fop.fo.properties.CommonBorderPaddingBackground; -import org.apache.fop.layoutmgr.BlockLevelLayoutManager; import org.apache.fop.layoutmgr.ElementListUtils; +import org.apache.fop.layoutmgr.Keep; import org.apache.fop.layoutmgr.KnuthBlockBox; import org.apache.fop.layoutmgr.KnuthBox; import org.apache.fop.layoutmgr.KnuthElement; @@ -73,7 +74,7 @@ /** True if the next CellPart that will be created will be the last one for this cell. */ private boolean lastCellPart; - private int keepWithNextStrength; + private Keep keepWithNext; private int spanIndex = 0; @@ -211,7 +212,7 @@ includedLength = -1; // Avoid troubles with cells having content of zero length totalLength = previousRowsLength + ElementListUtils.calcContentLength(elementList); endRowIndex = rowIndex + pgu.getCell().getNumberRowsSpanned() - 1; - keepWithNextStrength = BlockLevelLayoutManager.KEEP_AUTO; + keepWithNext = Keep.KEEP_AUTO; remainingLength = totalLength - previousRowsLength; afterNextStep = new Step(previousRowsLength); @@ -305,7 +306,11 @@ KnuthElement el = (KnuthElement) knuthIter.next(); if (el.isPenalty()) { prevIsBox = false; - if (el.getP() < KnuthElement.INFINITE) { + if (el.getP() < KnuthElement.INFINITE + || ((KnuthPenalty) el).getBreakClass() == Constants.EN_PAGE) { + // TODO too much is being done in that test, only to handle + // keep.within-column properly. + // First legal break point breakFound = true; KnuthPenalty p = (KnuthPenalty) el; @@ -524,7 +529,7 @@ */ CellPart createCellPart() { if (nextStep.end + 1 == elementList.size()) { - keepWithNextStrength = pgu.getKeepWithNextStrength(); + keepWithNext = pgu.getKeepWithNext(); // TODO if keep-with-next is set on the row, must every cell of the row // contribute some content from children blocks? // see http://mail-archives.apache.org/mod_mbox/xmlgraphics-fop-dev/200802.mbox/ @@ -566,8 +571,8 @@ } } - int getKeepWithNextStrength() { - return keepWithNextStrength; + Keep getKeepWithNext() { + return keepWithNext; } int getPenaltyValue() { Index: src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java =================================================================== --- src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java (revision 757829) +++ src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java (working copy) @@ -35,10 +35,9 @@ import org.apache.fop.fo.flow.table.PrimaryGridUnit; import org.apache.fop.fo.flow.table.Table; import org.apache.fop.fo.flow.table.TablePart; -import org.apache.fop.layoutmgr.BlockLevelLayoutManager; import org.apache.fop.layoutmgr.BreakElement; import org.apache.fop.layoutmgr.ElementListUtils; -import org.apache.fop.layoutmgr.KeepUtil; +import org.apache.fop.layoutmgr.Keep; import org.apache.fop.layoutmgr.KnuthBox; import org.apache.fop.layoutmgr.KnuthElement; import org.apache.fop.layoutmgr.KnuthGlue; @@ -213,13 +212,13 @@ context.clearKeepsPending(); context.setBreakBefore(Constants.EN_AUTO); context.setBreakAfter(Constants.EN_AUTO); - int keepWithPrevious = BlockLevelLayoutManager.KEEP_AUTO; + Keep keepWithPrevious = Keep.KEEP_AUTO; int breakBefore = Constants.EN_AUTO; if (rowGroup != null) { RowGroupLayoutManager rowGroupLM = new RowGroupLayoutManager(getTableLM(), rowGroup, stepper); List nextRowGroupElems = rowGroupLM.getNextKnuthElements(context, alignment, bodyType); - keepWithPrevious = Math.max(keepWithPrevious, context.getKeepWithPreviousPending()); + keepWithPrevious = keepWithPrevious.compare(context.getKeepWithPreviousPending()); breakBefore = context.getBreakBefore(); int breakBetween = context.getBreakAfter(); returnList.addAll(nextRowGroupElems); @@ -228,7 +227,7 @@ //Note previous pending keep-with-next and clear the strength //(as the layout context is reused) - int keepWithNextPending = context.getKeepWithNextPending(); + Keep keepWithNextPending = context.getKeepWithNextPending(); context.clearKeepWithNextPending(); //Get elements for next row group @@ -246,17 +245,17 @@ */ //Determine keep constraints - int penaltyStrength = BlockLevelLayoutManager.KEEP_AUTO; - penaltyStrength = Math.max(penaltyStrength, keepWithNextPending); - penaltyStrength = Math.max(penaltyStrength, context.getKeepWithPreviousPending()); + Keep keep = keepWithNextPending.compare(context.getKeepWithPreviousPending()); context.clearKeepWithPreviousPending(); - penaltyStrength = Math.max(penaltyStrength, getTableLM().getKeepTogetherStrength()); - int penaltyValue = KeepUtil.getPenaltyForKeep(penaltyStrength); + keep = keep.compare(getTableLM().getKeepTogether()); + int penaltyValue = keep.getPenalty(); + int breakClass = keep.getContext(); breakBetween = BreakUtil.compareBreakClasses(breakBetween, context.getBreakBefore()); if (breakBetween != Constants.EN_AUTO) { penaltyValue = -KnuthElement.INFINITE; + breakClass = breakBetween; } BreakElement breakElement; ListIterator elemIter = returnList.listIterator(returnList.size()); @@ -267,7 +266,7 @@ breakElement = (BreakElement) elem; } breakElement.setPenaltyValue(penaltyValue); - breakElement.setBreakClass(breakBetween); + breakElement.setBreakClass(breakClass); returnList.addAll(nextRowGroupElems); breakBetween = context.getBreakAfter(); } Index: src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java =================================================================== --- src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java (revision 757829) +++ src/java/org/apache/fop/layoutmgr/table/RowGroupLayoutManager.java (working copy) @@ -60,8 +60,8 @@ LinkedList returnList = new LinkedList(); createElementsForRowGroup(context, alignment, bodyType, returnList); - context.updateKeepWithPreviousPending(rowGroup[0].getKeepWithPreviousStrength()); - context.updateKeepWithNextPending(rowGroup[rowGroup.length - 1].getKeepWithNextStrength()); + context.updateKeepWithPreviousPending(rowGroup[0].getKeepWithPrevious()); + context.updateKeepWithNextPending(rowGroup[rowGroup.length - 1].getKeepWithNext()); int breakBefore = Constants.EN_AUTO; TableRow firstRow = rowGroup[0].getTableRow(); Index: src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java =================================================================== --- src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java (revision 757829) +++ src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java (working copy) @@ -35,11 +35,11 @@ import org.apache.fop.fo.FObj; import org.apache.fop.fo.flow.table.Table; import org.apache.fop.fo.flow.table.TableColumn; +import org.apache.fop.fo.properties.KeepProperty; 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; @@ -256,10 +256,10 @@ log.debug(contentKnuthElements); wrapPositionElements(contentKnuthElements, returnList); - context.updateKeepWithPreviousPending(getKeepWithPreviousStrength()); + context.updateKeepWithPreviousPending(getKeepWithPrevious()); context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending()); - context.updateKeepWithNextPending(getKeepWithNextStrength()); + context.updateKeepWithNextPending(getKeepWithNext()); context.updateKeepWithNextPending(childLC.getKeepWithNextPending()); if (getTable().isSeparateBorderModel()) { @@ -448,20 +448,18 @@ } /** {@inheritDoc} */ - public int getKeepTogetherStrength() { - int strength = KeepUtil.getCombinedBlockLevelKeepStrength(getTable().getKeepTogether()); - strength = Math.max(strength, getParentKeepTogetherStrength()); - return strength; + public KeepProperty getKeepTogetherProperty() { + return getTable().getKeepTogether(); } /** {@inheritDoc} */ - public int getKeepWithNextStrength() { - return KeepUtil.getCombinedBlockLevelKeepStrength(getTable().getKeepWithNext()); + public KeepProperty getKeepWithPreviousProperty() { + return getTable().getKeepWithPrevious(); } /** {@inheritDoc} */ - public int getKeepWithPreviousStrength() { - return KeepUtil.getCombinedBlockLevelKeepStrength(getTable().getKeepWithPrevious()); + public KeepProperty getKeepWithNextProperty() { + return getTable().getKeepWithNext(); } // --------- Property Resolution related functions --------- // Index: src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java =================================================================== --- src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java (revision 757829) +++ src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java (working copy) @@ -24,6 +24,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.apache.fop.area.Area; import org.apache.fop.area.Block; import org.apache.fop.area.Trait; @@ -31,16 +32,16 @@ import org.apache.fop.fo.flow.table.GridUnit; import org.apache.fop.fo.flow.table.PrimaryGridUnit; import org.apache.fop.fo.flow.table.Table; -import org.apache.fop.fo.flow.table.TablePart; import org.apache.fop.fo.flow.table.TableCell; import org.apache.fop.fo.flow.table.TableColumn; +import org.apache.fop.fo.flow.table.TablePart; import org.apache.fop.fo.flow.table.TableRow; import org.apache.fop.fo.properties.CommonBorderPaddingBackground; 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.KeepUtil; +import org.apache.fop.layoutmgr.Keep; import org.apache.fop.layoutmgr.KnuthBox; import org.apache.fop.layoutmgr.KnuthElement; import org.apache.fop.layoutmgr.KnuthGlue; @@ -153,7 +154,7 @@ log.debug("child LM signals pending keep with next"); } if (contentList.isEmpty() && childLC.isKeepWithPreviousPending()) { - primaryGridUnit.setKeepWithPreviousStrength(childLC.getKeepWithPreviousPending()); + primaryGridUnit.setKeepWithPrevious(childLC.getKeepWithPreviousPending()); childLC.clearKeepWithPreviousPending(); } @@ -174,7 +175,7 @@ } prevLM = curLM; } - primaryGridUnit.setKeepWithNextStrength(context.getKeepWithNextPending()); + primaryGridUnit.setKeepWithNext(context.getKeepWithNextPending()); returnedList = new LinkedList(); if (!contentList.isEmpty()) { @@ -556,26 +557,23 @@ } /** {@inheritDoc} */ - public int getKeepTogetherStrength() { - int strength = KEEP_AUTO; + public Keep getKeepTogether() { + Keep keep = Keep.KEEP_AUTO; if (primaryGridUnit.getRow() != null) { - strength = Math.max(strength, KeepUtil.getKeepStrength( - primaryGridUnit.getRow().getKeepTogether().getWithinPage())); - strength = Math.max(strength, KeepUtil.getKeepStrength( - primaryGridUnit.getRow().getKeepTogether().getWithinColumn())); + keep = Keep.getKeep(primaryGridUnit.getRow().getKeepTogether()); } - strength = Math.max(strength, getParentKeepTogetherStrength()); - return strength; + keep = keep.compare(getParentKeepTogether()); + return keep; } /** {@inheritDoc} */ - public int getKeepWithNextStrength() { - return KEEP_AUTO; //TODO FIX ME (table-cell has no keep-with-next!) + public Keep getKeepWithNext() { + return Keep.KEEP_AUTO; //TODO FIX ME (table-cell has no keep-with-next!) } /** {@inheritDoc} */ - public int getKeepWithPreviousStrength() { - return KEEP_AUTO; //TODO FIX ME (table-cell has no keep-with-previous!) + public Keep getKeepWithPrevious() { + return Keep.KEEP_AUTO; //TODO FIX ME (table-cell has no keep-with-previous!) } // --------- Property Resolution related functions --------- // Index: src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java =================================================================== --- src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java (revision 757829) +++ src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java (working copy) @@ -23,6 +23,7 @@ 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.Keep; import org.apache.fop.layoutmgr.LayoutContext; import org.apache.fop.layoutmgr.PositionIterator; @@ -201,28 +202,17 @@ } /** {@inheritDoc} */ - public int getKeepTogetherStrength() { - int strength = KEEP_AUTO; + public Keep getKeepWithNext() { + return Keep.KEEP_AUTO; /* TODO Complete me! - int strength = KeepUtil.getCombinedBlockLevelKeepStrength( - getTableAndCaptionFO().getKeepTogether()); - */ - strength = Math.max(strength, getParentKeepTogetherStrength()); - return strength; - } - - /** {@inheritDoc} */ - public int getKeepWithNextStrength() { - return KEEP_AUTO; - /* TODO Complete me! return KeepUtil.getCombinedBlockLevelKeepStrength( getTableAndCaptionFO().getKeepWithNext()); */ } /** {@inheritDoc} */ - public int getKeepWithPreviousStrength() { - return KEEP_AUTO; + public Keep getKeepWithPrevious() { + return Keep.KEEP_AUTO; /* TODO Complete me! return KeepUtil.getCombinedBlockLevelKeepStrength( getTableAndCaptionFO().getKeepWithPrevious()); Index: src/java/org/apache/fop/layoutmgr/table/TableStepper.java =================================================================== --- src/java/org/apache/fop/layoutmgr/table/TableStepper.java (revision 757829) +++ src/java/org/apache/fop/layoutmgr/table/TableStepper.java (working copy) @@ -30,12 +30,10 @@ 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.BlockLevelLayoutManager; import org.apache.fop.layoutmgr.BreakElement; -import org.apache.fop.layoutmgr.KeepUtil; +import org.apache.fop.layoutmgr.Keep; import org.apache.fop.layoutmgr.KnuthBlockBox; 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; @@ -241,40 +239,38 @@ } } - int strength = BlockLevelLayoutManager.KEEP_AUTO; + Keep keep = Keep.KEEP_AUTO; int stepPenalty = 0; for (Iterator iter = activeCells.iterator(); iter.hasNext();) { ActiveCell activeCell = (ActiveCell) iter.next(); - strength = Math.max(strength, activeCell.getKeepWithNextStrength()); + keep = keep.compare(activeCell.getKeepWithNext()); stepPenalty = Math.max(stepPenalty, activeCell.getPenaltyValue()); } if (!rowFinished) { - strength = Math.max(strength, rowGroup[activeRowIndex].getKeepTogetherStrength()); + keep = keep.compare(rowGroup[activeRowIndex].getKeepTogether()); //The above call doesn't take the penalty from the table into account, so... - strength = Math.max(strength, getTableLM().getKeepTogetherStrength()); + keep = keep.compare(getTableLM().getKeepTogether()); } else if (activeRowIndex < rowGroup.length - 1) { - strength = Math.max(strength, - rowGroup[activeRowIndex].getKeepWithNextStrength()); - strength = Math.max(strength, - rowGroup[activeRowIndex + 1].getKeepWithPreviousStrength()); + keep = keep.compare(rowGroup[activeRowIndex].getKeepWithNext()); + keep = keep.compare(rowGroup[activeRowIndex + 1].getKeepWithPrevious()); nextBreakClass = BreakUtil.compareBreakClasses(nextBreakClass, rowGroup[activeRowIndex].getBreakAfter()); nextBreakClass = BreakUtil.compareBreakClasses(nextBreakClass, rowGroup[activeRowIndex + 1].getBreakBefore()); } - int p = KeepUtil.getPenaltyForKeep(strength); + int p = keep.getPenalty(); if (rowHeightSmallerThanFirstStep) { rowHeightSmallerThanFirstStep = false; p = KnuthPenalty.INFINITE; } - if (p > -KnuthElement.INFINITE) { - p = Math.max(p, stepPenalty); - } + p = Math.max(p, stepPenalty); + int breakClass = keep.getContext(); if (nextBreakClass != Constants.EN_AUTO) { log.trace("Forced break encountered"); p = -KnuthPenalty.INFINITE; //Overrides any keeps (see 4.8 in XSL 1.0) + breakClass = nextBreakClass; } - returnList.add(new BreakElement(penaltyPos, effPenaltyLen, p, nextBreakClass, context)); + returnList.add(new BreakElement(penaltyPos, effPenaltyLen, p, breakClass, context)); if (penaltyOrGlueLen < 0) { returnList.add(new KnuthGlue(-penaltyOrGlueLen, 0, 0, new Position(null), true)); } Index: src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java =================================================================== --- src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java (revision 757829) +++ src/java/org/apache/fop/layoutmgr/table/TableCaptionLayoutManager.java (working copy) @@ -23,6 +23,7 @@ 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.Keep; import org.apache.fop.layoutmgr.LayoutContext; import org.apache.fop.layoutmgr.PositionIterator; @@ -197,30 +198,17 @@ } /** {@inheritDoc} */ - public int getKeepTogetherStrength() { - int strength = KEEP_AUTO; + public Keep getKeepWithNext() { + return Keep.KEEP_AUTO; /* TODO Complete me! - strength = Math.max(strength, KeepUtil.getKeepStrength( - getTableCaptionFO().getKeepTogether().getWithinPage())); - strength = Math.max(strength, KeepUtil.getKeepStrength( - getTableCaptionFO().getKeepTogether().getWithinColumn())); - */ - strength = Math.max(strength, getParentKeepTogetherStrength()); - return strength; - } - - /** {@inheritDoc} */ - public int getKeepWithNextStrength() { - return KEEP_AUTO; - /* TODO Complete me! return KeepUtil.getCombinedBlockLevelKeepStrength( getTableCaptionFO().getKeepWithNext()); */ } /** {@inheritDoc} */ - public int getKeepWithPreviousStrength() { - return KEEP_AUTO; + public Keep getKeepWithPrevious() { + return Keep.KEEP_AUTO; /* TODO Complete me! return KeepUtil.getCombinedBlockLevelKeepStrength( getTableCaptionFO().getKeepWithPrevious()); Index: src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java =================================================================== --- src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java (revision 757829) +++ src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java (working copy) @@ -33,6 +33,7 @@ import org.apache.fop.fo.FObj; import org.apache.fop.fo.properties.BreakPropertySet; import org.apache.fop.fo.properties.CommonBorderPaddingBackground; +import org.apache.fop.fo.properties.KeepProperty; import org.apache.fop.fo.properties.SpaceProperty; import org.apache.fop.layoutmgr.inline.InlineLayoutManager; import org.apache.fop.layoutmgr.inline.LineLayoutManager; @@ -274,7 +275,7 @@ if (!firstVisibleMarkServed) { addKnuthElementsForSpaceBefore(returnList, alignment); - context.updateKeepWithPreviousPending(getKeepWithPreviousStrength()); + context.updateKeepWithPreviousPending(getKeepWithPrevious()); } addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed); @@ -417,7 +418,7 @@ returnList.add(forcedBreakAfterLast); } - context.updateKeepWithNextPending(getKeepWithNextStrength()); + context.updateKeepWithNextPending(getKeepWithNext()); setFinished(true); @@ -436,21 +437,21 @@ || context.isKeepWithNextPending() || childLC.isKeepWithPreviousPending()) { - int strength = getKeepTogetherStrength(); + Keep keep = getKeepTogether(); //Handle pending keep-with-next - strength = Math.max(strength, context.getKeepWithNextPending()); + keep = keep.compare(context.getKeepWithNextPending()); context.clearKeepWithNextPending(); //Handle pending keep-with-previous from child LM - strength = Math.max(strength, childLC.getKeepWithPreviousPending()); + keep = keep.compare(childLC.getKeepWithPreviousPending()); childLC.clearKeepWithPreviousPending(); - int penalty = KeepUtil.getPenaltyForKeep(strength); + int penalty = keep.getPenalty(); // add a penalty to forbid or discourage a break between blocks contentList.add(new BreakElement( - new Position(this), penalty, context)); + new Position(this), penalty, keep.getContext(), context)); return; } @@ -817,35 +818,64 @@ * Retrieves and returns the keep-together strength from the parent element. * @return the keep-together strength */ - protected int getParentKeepTogetherStrength() { - int strength = KEEP_AUTO; + protected Keep getParentKeepTogether() { + Keep keep = Keep.KEEP_AUTO; if (getParent() instanceof BlockLevelLayoutManager) { - strength = ((BlockLevelLayoutManager)getParent()).getKeepTogetherStrength(); + keep = ((BlockLevelLayoutManager)getParent()).getKeepTogether(); } else if (getParent() instanceof InlineLayoutManager) { if (((InlineLayoutManager) getParent()).mustKeepTogether()) { - strength = KEEP_ALWAYS; + keep = Keep.KEEP_ALWAYS; } //TODO Fix me //strength = ((InlineLayoutManager) getParent()).getKeepTogetherStrength(); } - return strength; + return keep; } /** {@inheritDoc} */ public boolean mustKeepTogether() { - return getKeepTogetherStrength() > KEEP_AUTO; + return !getKeepTogether().isAuto(); } /** {@inheritDoc} */ public boolean mustKeepWithPrevious() { - return getKeepWithPreviousStrength() > KEEP_AUTO; + return !getKeepWithPrevious().isAuto(); } /** {@inheritDoc} */ public boolean mustKeepWithNext() { - return getKeepWithNextStrength() > KEEP_AUTO; + return !getKeepWithNext().isAuto(); } + public KeepProperty getKeepTogetherProperty() { + throw new IllegalStateException(); + } + + public KeepProperty getKeepWithPreviousProperty() { + throw new IllegalStateException(); + } + + public KeepProperty getKeepWithNextProperty() { + throw new IllegalStateException(); + } + + /** {@inheritDoc} */ + public Keep getKeepTogether() { + Keep keep = Keep.getKeep(getKeepTogetherProperty()); + keep = keep.compare(getParentKeepTogether()); + return keep; + } + + /** {@inheritDoc} */ + public Keep getKeepWithPrevious() { + return Keep.getKeep(getKeepWithPreviousProperty()); + } + + /** {@inheritDoc} */ + public Keep getKeepWithNext() { + return Keep.getKeep(getKeepWithNextProperty()); + } + /** * Adds the unresolved elements for border and padding to a layout context so break * possibilities can be properly constructed. Index: src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java =================================================================== --- src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java (revision 757829) +++ src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java (working copy) @@ -22,6 +22,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.fop.fo.Constants; import org.apache.fop.fo.FONode; /** @@ -448,6 +449,7 @@ if (log.isTraceEnabled()) { log.trace("Looping over " + (par.size() - startIndex) + " elements"); + log.trace(par); } KnuthNode lastForced = getNode(0); @@ -477,11 +479,11 @@ // only if its penalty is not infinite; // consider all penalties, non-flagged penalties or non-forcing penalties // according to the value of allowedBreaks - if (((KnuthPenalty) thisElement).getP() < KnuthElement.INFINITE - && (!(allowedBreaks == NO_FLAGGED_PENALTIES) - || !(((KnuthPenalty) thisElement).isFlagged())) - && (!(allowedBreaks == ONLY_FORCED_BREAKS) - || ((KnuthPenalty) thisElement).getP() == -KnuthElement.INFINITE)) { + KnuthPenalty p = (KnuthPenalty) thisElement; + if (((p.getP() < KnuthElement.INFINITE || p.getBreakClass() != Constants.EN_LINE) + && (!(allowedBreaks == NO_FLAGGED_PENALTIES) || !p.isFlagged()) + && (!(allowedBreaks == ONLY_FORCED_BREAKS) + || p.isForcedBreak()))) { considerLegalBreak(thisElement, i); } previousIsBox = false; @@ -495,13 +497,14 @@ // were "bad" breaks since the beginning; // if it is not the node we just restarted from, lastDeactivated can // replace either lastTooShort or lastTooLong - if (lastDeactivated != null && lastDeactivated != lastForced) { - if (lastDeactivated.adjustRatio > 0) { - lastTooShort = lastDeactivated; - } else { - lastTooLong = lastDeactivated; - } - } + // TODO re-enable and make it work with keep.within-column +// if (lastDeactivated != null && lastDeactivated != lastForced) { +// if (lastDeactivated.adjustRatio > 0) { +// lastTooShort = lastDeactivated; +// } else { +// lastTooLong = lastDeactivated; +// } +// } if (lastTooShort == null || lastForced.position == lastTooShort.position) { if (isPartOverflowRecoveryActivated()) { if (this.lastRecovered == null) { @@ -510,12 +513,7 @@ log.debug("Recovery point: " + lastRecovered); } } - // content would overflow, insert empty line/page and try again - KnuthNode node = createNode( - lastTooLong.previous.position, lastTooLong.previous.line + 1, 1, - 0, 0, 0, - 0, 0, 0, - 0, 0, lastTooLong.previous); + KnuthNode node = recoverFromTooLong(lastTooLong); lastForced = node; node.fitRecoveryCounter = lastTooLong.previous.fitRecoveryCounter + 1; if (log.isDebugEnabled()) { @@ -571,6 +569,16 @@ return line; } + protected KnuthNode recoverFromTooLong(KnuthNode lastTooLong) { + // content would overflow, insert empty line/page and try again + KnuthNode node = createNode( + lastTooLong.previous.position, lastTooLong.previous.line + 1, 1, + 0, 0, 0, + 0, 0, 0, + 0, 0, lastTooLong.previous); + return node; + } + /** * This method tries to find the context FO for a position in a KnuthSequence. * @param seq the KnuthSequence to inspect @@ -689,6 +697,9 @@ lastDeactivated = null; lastTooLong = null; for (int line = startLine; line < endLine; line++) { + if (!elementCanEndLine(element, line + 1)) { + continue; + } for (KnuthNode node = getNode(line); node != null; node = node.next) { if (node.position == elementIdx) { continue; @@ -759,6 +770,7 @@ } if (r <= -1) { + log.debug("Considering tooLong, demerits=" + demerits); if (lastTooLong == null || demerits < lastTooLong.totalDemerits) { lastTooLong = createNode(elementIdx, line + 1, fitnessClass, newWidth, newStretch, newShrink, @@ -791,6 +803,11 @@ } } + protected boolean elementCanEndLine(KnuthElement element, int line) { + return !(element instanceof KnuthPenalty) + || ((KnuthPenalty) element).getP() < KnuthPenalty.INFINITE; + } + /** * Adds new active nodes for breaks at the given element. * @param line number of the previous line; this element will end line number (line+1) Index: src/java/org/apache/fop/fo/flow/table/EffRow.java =================================================================== --- src/java/org/apache/fop/fo/flow/table/EffRow.java (revision 757829) +++ src/java/org/apache/fop/fo/flow/table/EffRow.java (working copy) @@ -23,8 +23,7 @@ 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.Keep; import org.apache.fop.layoutmgr.table.TableRowIterator; import org.apache.fop.traits.MinOptMax; import org.apache.fop.util.BreakUtil; @@ -170,20 +169,19 @@ * * @return the strength of the keep-with-previous constraint */ - public int getKeepWithPreviousStrength() { - int strength = BlockLevelLayoutManager.KEEP_AUTO; + public Keep getKeepWithPrevious() { + Keep keep = Keep.KEEP_AUTO; TableRow row = getTableRow(); if (row != null) { - strength = Math.max(strength, - KeepUtil.getCombinedBlockLevelKeepStrength(row.getKeepWithPrevious())); + keep = Keep.getKeep(row.getKeepWithPrevious()); } for (Iterator iter = gridUnits.iterator(); iter.hasNext();) { GridUnit gu = (GridUnit) iter.next(); if (gu.isPrimary()) { - strength = Math.max(strength, gu.getPrimary().getKeepWithPreviousStrength()); + keep = keep.compare(gu.getPrimary().getKeepWithPrevious()); } } - return strength; + return keep; } /** @@ -192,20 +190,19 @@ * * @return the strength of the keep-with-next constraint */ - public int getKeepWithNextStrength() { - int strength = BlockLevelLayoutManager.KEEP_AUTO; + public Keep getKeepWithNext() { + Keep keep = Keep.KEEP_AUTO; TableRow row = getTableRow(); if (row != null) { - strength = Math.max(strength, - KeepUtil.getCombinedBlockLevelKeepStrength(row.getKeepWithNext())); + keep = Keep.getKeep(row.getKeepWithNext()); } for (Iterator iter = gridUnits.iterator(); iter.hasNext();) { GridUnit gu = (GridUnit) iter.next(); if (!gu.isEmpty() && gu.getColSpanIndex() == 0 && gu.isLastGridUnitRowSpan()) { - strength = Math.max(strength, gu.getPrimary().getKeepWithNextStrength()); + keep = keep.compare(gu.getPrimary().getKeepWithNext()); } } - return strength; + return keep; } /** @@ -213,16 +210,13 @@ * not take the parent table's keeps into account! * @return the keep-together strength */ - public int getKeepTogetherStrength() { + public Keep getKeepTogether() { TableRow row = getTableRow(); - int strength = BlockLevelLayoutManager.KEEP_AUTO; + Keep keep = Keep.KEEP_AUTO; if (row != null) { - strength = Math.max(strength, KeepUtil.getKeepStrength( - row.getKeepTogether().getWithinPage())); - strength = Math.max(strength, KeepUtil.getKeepStrength( - row.getKeepTogether().getWithinColumn())); + keep = Keep.getKeep(row.getKeepTogether()); } - return strength; + return keep; } /** Index: src/java/org/apache/fop/fo/flow/table/PrimaryGridUnit.java =================================================================== --- src/java/org/apache/fop/fo/flow/table/PrimaryGridUnit.java (revision 757829) +++ src/java/org/apache/fop/fo/flow/table/PrimaryGridUnit.java (working copy) @@ -19,14 +19,13 @@ package org.apache.fop.fo.flow.table; -import java.util.LinkedList; import java.util.List; import org.apache.fop.fo.Constants; import org.apache.fop.fo.FONode; import org.apache.fop.fo.properties.CommonBorderPaddingBackground; -import org.apache.fop.layoutmgr.BlockLevelLayoutManager; import org.apache.fop.layoutmgr.ElementListUtils; +import org.apache.fop.layoutmgr.Keep; import org.apache.fop.layoutmgr.table.TableCellLayoutManager; /** @@ -54,8 +53,8 @@ private boolean isSeparateBorderModel; private int halfBorderSeparationBPD; - private int keepWithPrevious = BlockLevelLayoutManager.KEEP_AUTO; - private int keepWithNext = BlockLevelLayoutManager.KEEP_AUTO; + private Keep keepWithPrevious = Keep.KEEP_AUTO; + private Keep keepWithNext = Keep.KEEP_AUTO; private int breakBefore = Constants.EN_AUTO; private int breakAfter = Constants.EN_AUTO; @@ -334,16 +333,16 @@ * * @return the keep-with-previous strength */ - public int getKeepWithPreviousStrength() { + public Keep getKeepWithPrevious() { return keepWithPrevious; } /** * Don't use, reserved for TableCellLM. TODO - * @param strength the keep strength + * @param keep the keep strength */ - public void setKeepWithPreviousStrength(int strength) { - this.keepWithPrevious = strength; + public void setKeepWithPrevious(Keep keep) { + this.keepWithPrevious = keep; } /** @@ -352,16 +351,16 @@ * * @return the keep-with-next strength */ - public int getKeepWithNextStrength() { + public Keep getKeepWithNext() { return keepWithNext; } /** * Don't use, reserved for TableCellLM. TODO - * @param strength the keep strength + * @param keep the keep strength */ - public void setKeepWithNextStrength(int strength) { - this.keepWithNext = strength; + public void setKeepWithNext(Keep keep) { + this.keepWithNext = keep; } /**