ASF Bugzilla – Attachment 23990 Details for
Bug 46905
[PATCH] Implement keep-*.within-column
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Yet another update
b46905.patch (text/plain), 114.71 KB, created by
Andreas L. Delmelle
on 2009-07-15 15:19:07 UTC
(
hide
)
Description:
Yet another update
Filename:
MIME Type:
Creator:
Andreas L. Delmelle
Created:
2009-07-15 15:19:07 UTC
Size:
114.71 KB
patch
obsolete
>Index: src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java >=================================================================== >--- src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java (revision 793568) >+++ 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 793568) >+++ 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. >- * <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 combined block-level keep strength from a keep property. >- * <p> >- * 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. >- * <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; >- } >- >- /** >- * 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 793568) >+++ src/java/org/apache/fop/layoutmgr/KnuthPenalty.java (working copy) >@@ -45,7 +45,7 @@ > public static final int FLAGGED_PENALTY = 50; > > private int penalty; >- private boolean bFlagged; >+ private boolean isFlagged; > private int breakClass = -1; > > /** >@@ -55,12 +55,12 @@ > * @param p the penalty value of this penalty > * @param f is this penalty flagged? > * @param pos the Position stored in this penalty >- * @param bAux is this penalty auxiliary? >+ * @param isAuxiliary is this penalty auxiliary? > */ >- public KnuthPenalty(int w, int p, boolean f, Position pos, boolean bAux) { >- super(w, pos, bAux); >+ public KnuthPenalty(int w, int p, boolean f, Position pos, boolean isAuxiliary) { >+ super(w, pos, isAuxiliary); > penalty = p; >- bFlagged = f; >+ isFlagged = f; > } > > /** >@@ -69,20 +69,39 @@ > * @param w the width of this penalty > * @param p the penalty value of this penalty > * @param f is this penalty flagged? >- * @param iBreakClass the break class of this penalty (one of >+ * @param breakClass the break class of this penalty (one of > * {@link Constants#EN_AUTO}, {@link Constants#EN_COLUMN}, {@link Constants#EN_PAGE}, > * {@link Constants#EN_EVEN_PAGE}, {@link Constants#EN_ODD_PAGE}) > * @param pos the Position stored in this penalty >- * @param bAux is this penalty auxiliary? >+ * @param isAuxiliary is this penalty auxiliary? > */ > public KnuthPenalty(int w, int p, boolean f, >- int iBreakClass, Position pos, boolean bAux) { >- super(w, pos, bAux); >- penalty = p; >- bFlagged = f; >- breakClass = iBreakClass; >+ int breakClass, Position pos, boolean isAuxiliary) { >+ this(w, p, f, pos, isAuxiliary); >+ this.breakClass = breakClass; > } > >+ private static String getBreakClassName(int breakClass) { >+ return AbstractBreaker.getBreakClassName(breakClass); >+ } >+ >+ /** >+ * Get the penalty's value as a {@code java.lang.String}. >+ * (Mainly used in {@code toString()} methods, to improve readability >+ * of the trace logs.) >+ * >+ * @param penaltyValue the penalty value >+ * @return the penalty value as a {@code java.lang.String} >+ */ >+ protected static String valueOf(int penaltyValue) { >+ String result = (penaltyValue < 0) ? "-" : ""; >+ int tmpValue = Math.abs(penaltyValue); >+ result += (tmpValue == KnuthElement.INFINITE) >+ ? "INFINITE" >+ : String.valueOf(tmpValue); >+ return result; >+ } >+ > /** {@inheritDoc} */ > public boolean isPenalty() { > return true; >@@ -105,7 +124,7 @@ > > /** @return true is this penalty is a flagged one. */ > public boolean isFlagged() { >- return bFlagged; >+ return isFlagged; > } > > /** {@inheritDoc} */ >@@ -121,14 +140,6 @@ > return breakClass; > } > >- /** >- * Sets the break class for this penalty. >- * @param cl the break class (EN_AUTO, EN_COLUMN, EN_PAGE, EN_EVEN_PAGE, EN_ODD_PAGE) >- */ >- public void setBreakClass(int cl) { >- this.breakClass = cl; >- } >- > /** {@inheritDoc} */ > public String toString() { > StringBuffer sb = new StringBuffer(64); >@@ -137,39 +148,22 @@ > } > sb.append("penalty"); > sb.append(" p="); >- if (getP() < 0) { >- sb.append("-"); >- } >- if (Math.abs(getP()) == INFINITE) { >- sb.append("INFINITE"); >- } else { >- sb.append(getP()); >- } >- if (isFlagged()) { >+ sb.append(valueOf(this.penalty)); >+ if (this.isFlagged) { > sb.append(" [flagged]"); > } > sb.append(" w="); > sb.append(getW()); > if (isForcedBreak()) { >- sb.append(" (forced break"); >- switch (getBreakClass()) { >- case Constants.EN_PAGE: >- sb.append(", page"); >- break; >- case Constants.EN_COLUMN: >- sb.append(", column"); >- break; >- case Constants.EN_EVEN_PAGE: >- sb.append(", even page"); >- break; >- case Constants.EN_ODD_PAGE: >- sb.append(", odd page"); >- break; >- default: >- } >- sb.append(")"); >+ sb.append(" (forced break, ") >+ .append(getBreakClassName(this.breakClass)) >+ .append(")"); >+ } else if (this.penalty >= 0 && this.breakClass != -1) { >+ //penalty corresponding to a keep constraint >+ sb.append(" (keep constraint, ") >+ .append(getBreakClassName(this.breakClass)) >+ .append(")"); > } > return sb.toString(); > } >- > } >Index: src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java >=================================================================== >--- src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java (revision 793568) >+++ src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java (working copy) >@@ -36,32 +36,13 @@ > 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; > import org.apache.fop.hyphenation.Hyphenation; > import org.apache.fop.hyphenation.Hyphenator; >-import org.apache.fop.layoutmgr.BlockLevelLayoutManager; >-import org.apache.fop.layoutmgr.BreakElement; >-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.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.KnuthPossPosIter; >-import org.apache.fop.layoutmgr.KnuthSequence; >-import org.apache.fop.layoutmgr.LayoutContext; >-import org.apache.fop.layoutmgr.LayoutManager; >-import org.apache.fop.layoutmgr.LeafPosition; >-import org.apache.fop.layoutmgr.ListElement; >-import org.apache.fop.layoutmgr.NonLeafPosition; >-import org.apache.fop.layoutmgr.Position; >-import org.apache.fop.layoutmgr.PositionIterator; >-import org.apache.fop.layoutmgr.SpaceSpecifier; >+import org.apache.fop.layoutmgr.*; > import org.apache.fop.traits.MinOptMax; > > /** >@@ -169,7 +150,6 @@ > private AlignmentContext alignmentContext = null; > > private List knuthParagraphs = null; >- private int iReturnedLBP = 0; > > // parameters of Knuth's algorithm: > // penalty value for flagged penalties >@@ -605,34 +585,6 @@ > > //PHASE 2: Create line breaks > return createLineBreaks(context.getBPAlignment(), context); >- /* >- LineBreakPosition lbp = null; >- if (breakpoints == null) { >- // find the optimal line breaking points for each paragraph >- breakpoints = new ArrayList(); >- ListIterator paragraphsIterator >- = knuthParagraphs.listIterator(knuthParagraphs.size()); >- Paragraph currPar = null; >- while (paragraphsIterator.hasPrevious()) { >- currPar = (Paragraph) paragraphsIterator.previous(); >- findBreakingPoints(currPar, context.getStackLimit().opt); >- } >- }*/ >- >- //PHASE 3: Return lines >- >- /* >- // get a break point from the list >- lbp = (LineBreakPosition) breakpoints.get(iReturnedLBP ++); >- if (iReturnedLBP == breakpoints.size()) { >- setFinished(true); >- } >- >- BreakPoss curLineBP = new BreakPoss(lbp); >- curLineBP.setFlag(BreakPoss.ISLAST, isFinished()); >- curLineBP.setStackingSize(new MinOptMax(lbp.lineHeight)); >- return curLineBP; >- */ > } > > /** >@@ -767,134 +719,6 @@ > } > > /** >- * Find a set of breaking points. >- * This method is called only once by getNextBreakPoss, and it >- * subsequently calls the other findBreakingPoints() method with >- * different parameters, until a set of breaking points is found. >- * >- * @param par the list of elements that must be parted >- * into lines >- * @param lineWidth the desired length ot the lines >- */ >- /* >- private void findBreakingPoints(Paragraph par, int lineWidth) { >- // maximum adjustment ratio permitted >- float maxAdjustment = 1; >- >- // first try >- if (!findBreakingPoints(par, lineWidth, maxAdjustment, false)) { >- // the first try failed, now try something different >- log.debug("No set of breaking points found with maxAdjustment = " + maxAdjustment); >- if (hyphenationProperties.hyphenate == Constants.EN_TRUE) { >- // consider every hyphenation point as a legal break >- findHyphenationPoints(par); >- } else { >- // try with a higher threshold >- maxAdjustment = 5; >- } >- >- if (!findBreakingPoints(par, lineWidth, maxAdjustment, false)) { >- // the second try failed too, try with a huge threshold; >- // if this fails too, use a different algorithm >- log.debug("No set of breaking points found with maxAdjustment = " + maxAdjustment >- + (hyphenationProperties.hyphenate == Constants.EN_TRUE ? " and hyphenation" : "")); >- maxAdjustment = 20; >- if (!findBreakingPoints(par, lineWidth, maxAdjustment, true)) { >- log.debug("No set of breaking points found, using first-fit algorithm"); >- } >- } >- } >- } >- >- private boolean findBreakingPoints(Paragraph par, int lineWidth, >- double threshold, boolean force) { >- KnuthParagraph knuthPara = new KnuthParagraph(par); >- int lines = knuthPara.findBreakPoints(lineWidth, threshold, force); >- if (lines == 0) { >- return false; >- } >- >- for (int i = lines-1; i >= 0; i--) { >- int line = i+1; >- if (log.isTraceEnabled()) { >- log.trace("Making line from " + knuthPara.getStart(i) + " to " + >- knuthPara.getEnd(i)); >- } >- // compute indent and adjustment ratio, according to >- // the value of text-align and text-align-last >- >- int difference = knuthPara.getDifference(i); >- if (line == lines) { >- difference += par.lineFillerWidth; >- } >- int textAlign = (line < lines) >- ? textAlignment : textAlignmentLast; >- int indent = (textAlign == EN_CENTER) >- ? difference / 2 >- : (textAlign == EN_END) ? difference : 0; >- indent += (line == 1 && knuthParagraphs.indexOf(par) == 0) >- ? textIndent.getValue(this) : 0; >- double ratio = (textAlign == EN_JUSTIFY) >- ? knuthPara.getAdjustRatio(i) : 0; >- >- int start = knuthPara.getStart(i); >- int end = knuthPara.getEnd(i); >- makeLineBreakPosition(par, start, end, 0, ratio, indent); >- } >- return true; >- } >- >- private void makeLineBreakPosition(Paragraph par, >- int firstElementIndex, int lastElementIndex, >- int insertIndex, double ratio, int indent) { >- // line height calculation >- >- int halfLeading = (lineHeight - lead - follow) / 2; >- // height above the main baseline >- int lineLead = lead + halfLeading; >- // maximum size of top and bottom alignment >- int lineFollow = follow + halfLeading; >- >- ListIterator inlineIterator >- = par.listIterator(firstElementIndex); >- for (int j = firstElementIndex; >- j <= lastElementIndex; >- j++) { >- KnuthElement element = (KnuthElement) inlineIterator.next(); >- if (element.isBox()) { >- KnuthInlineBox box = (KnuthInlineBox)element; >- if (box.getLead() > lineLead) { >- lineLead = box.getLead(); >- } >- if (box.getTotal() > lineFollow) { >- lineFollow = box.getTotal(); >- } >- if (box.getMiddle() > lineLead + middleShift) { >- lineLead += box.getMiddle() >- - lineLead - middleShift; >- } >- if (box.getMiddle() > middlefollow - middleShift) { >- middlefollow += box.getMiddle() >- - middlefollow + middleShift; >- } >- } >- } >- >- if (lineFollow - lineLead > middlefollow) { >- middlefollow = lineFollow - lineLead; >- } >- >- breakpoints.add(insertIndex, >- new LineBreakPosition(this, >- knuthParagraphs.indexOf(par), >- lastElementIndex , >- ratio, 0, indent, >- lineLead + middlefollow, >- lineLead)); >- }*/ >- >- >- /** > * Phase 2 of Knuth algorithm: find optimal break points. > * @param alignment alignment in BP direction of the paragraph > * @param context the layout context >@@ -1054,12 +878,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) { >- returnList.add(new BreakElement( >- new Position(this), penalty, context)); >- } >+ Keep keep = getKeepTogether(); >+ returnList.add(new BreakElement( >+ new Position(this), >+ keep.getPenalty(), >+ keep.getContext(), >+ context)); > } > > LineLayoutPossibilities llPoss; >@@ -1098,12 +922,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) { >- returnList.add(new BreakElement( >- returnPosition, penalty, context)); >- } >+ Keep keep = getKeepTogether(); >+ returnList.add(new BreakElement( >+ new Position(this), >+ keep.getPenalty(), >+ keep.getContext(), >+ context)); > } > int endIndex > = ((LineBreakPosition) llPoss.getChosenPosition(i)).getLeafPos(); >@@ -1283,28 +1107,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} */ >@@ -1409,6 +1248,7 @@ > break; > } > //TODO Something's not right here. See block_hyphenation_linefeed_preserve.xml >+ //for more info: see also https://issues.apache.org/bugzilla/show_bug.cgi?id=38264 > > // collect word fragments, ignoring auxiliary elements; > // each word fragment was created by a different TextLM >Index: src/java/org/apache/fop/layoutmgr/BlockLevelLayoutManager.java >=================================================================== >--- src/java/org/apache/fop/layoutmgr/BlockLevelLayoutManager.java (revision 793568) >+++ 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,11 +37,6 @@ > /** 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); >@@ -48,7 +45,7 @@ > * 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 +56,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,11 +67,31 @@ > * 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. > */ > boolean mustKeepWithNext(); > >+ /** >+ * Returns the keep-together property specified on the FObj. >+ * (optional operation) >+ * @return the keep-together property >+ */ >+ KeepProperty getKeepTogetherProperty(); >+ >+ /** >+ * Returns the keep-with-previous property specified on the FObj. >+ * (optional operation) >+ * @return the keep-together property >+ */ >+ KeepProperty getKeepWithPreviousProperty(); >+ >+ /** >+ * Returns the keep-with-next property specified on the FObj. >+ * (optional operation) >+ * @return the keep-together property >+ */ >+ KeepProperty getKeepWithNextProperty(); > } >Index: src/java/org/apache/fop/layoutmgr/LayoutContext.java >=================================================================== >--- src/java/org/apache/fop/layoutmgr/LayoutContext.java (revision 793568) >+++ 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,152 @@ >+/* >+ * 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; >+ >+/** >+ * Object representing a keep constraint, corresponding >+ * to the XSL-FO <a href="http://www.w3.org/TR/xsl/#d0e26492">keep properties</a>. >+ */ >+public class Keep { >+ >+ /** The integer value for "auto" keep strength. */ >+ private static final int STRENGTH_AUTO = Integer.MIN_VALUE; >+ >+ /** The integer value for "always" keep strength. */ >+ private static final int STRENGTH_ALWAYS = Integer.MAX_VALUE; >+ >+ public static final Keep KEEP_AUTO = new Keep(STRENGTH_AUTO, Constants.EN_AUTO); >+ >+ 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(); >+ } >+ } >+ >+ /** >+ * Obtain a Keep instance corresponding to the given {@link KeepProperty} >+ * >+ * @param keepProperty the {@link KeepProperty} >+ * @return a new instance corresponding to the given property >+ */ >+ 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; >+ } >+ } >+ >+ /** @return {@code true} if the keep property was specified as "auto" */ >+ 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; >+ } >+ >+ /** @return the penalty value corresponding to the strength of this Keep */ >+ 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(); >+ } >+ } >+ >+ /** >+ * Compare this Keep instance to another one, and return the >+ * stronger one if the context is the same >+ * >+ * @param other the instance to compare to >+ * @return the winning Keep instance >+ */ >+ public Keep compare(Keep other) { >+ >+ /* check strength "always" first, regardless of priority */ >+ if (this.strength == STRENGTH_ALWAYS >+ && this.strength > other.strength) { >+ return this; >+ } else if (other.strength == STRENGTH_ALWAYS >+ && other.strength > this.strength) { >+ return other; >+ } >+ >+ int pThis = getKeepContextPriority(this.context); >+ int pOther = getKeepContextPriority(other.context); >+ >+ /* equal priority: strongest wins */ >+ if (pThis == pOther) { >+ return (strength >= other.strength) ? this : other; >+ } >+ >+ /* different priority: lowest priority wins */ >+ return (pThis < pOther) ? this : other; >+ } >+ >+ /** {@inheritDoc} */ >+ public String toString() { >+ return (strength == STRENGTH_AUTO) ? "auto" >+ : (strength == STRENGTH_ALWAYS) ? "always" >+ : Integer.toString(strength); >+ } >+} > >Property changes on: src/java/org/apache/fop/layoutmgr/Keep.java >___________________________________________________________________ >Name: svn:keywords > + Id >Name: svn:eol-style > + native > >Index: src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java >=================================================================== >--- src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java (revision 793568) >+++ 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); >@@ -271,9 +272,9 @@ > //Spaces, border and padding to be repeated at each break > addPendingMarks(context); > >- BlockLevelLayoutManager curLM; // currently active LM >- BlockLevelLayoutManager prevLM = null; // previously active LM >- while ((curLM = (BlockLevelLayoutManager) getChildLM()) != null) { >+ LayoutManager curLM; // currently active LM >+ LayoutManager prevLM = null; // previously active LM >+ while ((curLM = getChildLM()) != null) { > LayoutContext childLC = new LayoutContext(0); > childLC.copyPendingMarksFrom(context); > // curLM is a ? >@@ -323,8 +324,7 @@ > //Avoid NoSuchElementException below (happens with empty blocks) > continue; > } >- if (((ListElement) ListUtil.getLast(returnedList)) >- .isForcedBreak()) { >+ if (ElementListUtils.endsWithForcedBreak(returnedList)) { > // a descendant of this block has break-after > if (curLM.isFinished()) { > // there is no other content in this block; >@@ -391,7 +391,7 @@ > context.clearPendingMarks(); > addKnuthElementsForBreakAfter(returnList, context); > >- context.updateKeepWithNextPending(getKeepWithNextStrength()); >+ context.updateKeepWithNextPending(getKeepWithNext()); > > setFinished(true); > return returnList; >@@ -1011,23 +1011,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 793568) >+++ src/java/org/apache/fop/layoutmgr/BreakElement.java (working copy) >@@ -41,10 +41,25 @@ > * @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); > } > > /** >+ * Create a new BreakElement for the given {@code position}, {@code penaltyValue} >+ * and {@code breakClass}. (Used principally to generate break-possibilities in >+ * ranges of content that must be kept together within the context corresponding >+ * to the {@code breakClass}; expected to be one of {@link Constants#EN_AUTO}, >+ * {@link Constants#EN_LINE}, {@link Constants#EN_COLUMN} or {@link Constants#EN_PAGE}) >+ * @param position the corresponding {@link Position} >+ * @param penaltyValue the penalty value >+ * @param breakClass the break class >+ * @param context the {@link LayoutContext} >+ */ >+ public BreakElement(Position position, int penaltyValue, int breakClass, LayoutContext context) { >+ this(position, 0, penaltyValue, breakClass, context); >+ } >+ >+ /** > * Constructor for hard breaks. > * > * @param position the Position instance needed by the addAreas stage of the LMs. >@@ -65,6 +80,10 @@ > this.pendingAfterMarks = context.getPendingAfterMarks(); > } > >+ private static String getBreakClassName(int breakClass) { >+ return AbstractBreaker.getBreakClassName(breakClass); >+ } >+ > /** {@inheritDoc} */ > public boolean isConditional() { > return false; //Does not really apply here >@@ -143,27 +162,17 @@ > > /** {@inheritDoc} */ > public String toString() { >- StringBuffer sb = new StringBuffer(); >+ StringBuffer sb = new StringBuffer(64); > sb.append("BreakPossibility[p:"); >- sb.append(this.penaltyValue); >+ sb.append(KnuthPenalty.valueOf(this.penaltyValue)); > if (isForcedBreak()) { >- sb.append(" (forced break"); >- switch (getBreakClass()) { >- case Constants.EN_PAGE: >- sb.append(", page"); >- break; >- case Constants.EN_COLUMN: >- sb.append(", column"); >- break; >- case Constants.EN_EVEN_PAGE: >- sb.append(", even page"); >- break; >- case Constants.EN_ODD_PAGE: >- sb.append(", odd page"); >- break; >- default: >- } >- sb.append(")"); >+ sb.append(" (forced break, ") >+ .append(getBreakClassName(this.breakClass)) >+ .append(")"); >+ } else if (this.penaltyValue >= 0 && this.breakClass != -1) { >+ sb.append(" (keep constraint, ") >+ .append(getBreakClassName(this.breakClass)) >+ .append(")"); > } > sb.append("; w:"); > sb.append(penaltyWidth); >Index: src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java >=================================================================== >--- src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java (revision 793568) >+++ src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java (working copy) >@@ -63,10 +63,6 @@ > /** {@inheritDoc} */ > public List getNextKnuthElements(LayoutContext context, int alignment) { > >- // set layout dimensions >- int flowIPD = getCurrentPV().getCurrentSpan().getColumnWidth(); >- int flowBPD = getCurrentPV().getBodyRegion().getBPD(); >- > // currently active LM > LayoutManager curLM; > List returnedList; >@@ -84,12 +80,10 @@ > int disableColumnBalancing = EN_FALSE; > if (curLM instanceof BlockLayoutManager) { > span = ((BlockLayoutManager)curLM).getBlockFO().getSpan(); >- disableColumnBalancing = ((BlockLayoutManager) curLM).getBlockFO() >- .getDisableColumnBalancing(); >+ disableColumnBalancing = ((BlockLayoutManager) curLM).getBlockFO().getDisableColumnBalancing(); > } else if (curLM instanceof BlockContainerLayoutManager) { > span = ((BlockContainerLayoutManager)curLM).getBlockContainerFO().getSpan(); >- disableColumnBalancing = ((BlockContainerLayoutManager) curLM).getBlockContainerFO() >- .getDisableColumnBalancing(); >+ disableColumnBalancing = ((BlockContainerLayoutManager) curLM).getBlockContainerFO().getDisableColumnBalancing(); > } > > int currentSpan = context.getCurrentSpan(); >@@ -113,6 +107,7 @@ > > // get elements from curLM > returnedList = curLM.getNextKnuthElements(childLC, alignment); >+ //int contentHeight = ElementListUtils.calcContentLength(returnedList); > //log.debug("FLM.getNextKnuthElements> returnedList.size() = " + returnedList.size()); > if (returnList.size() == 0 && childLC.isKeepWithPreviousPending()) { > context.updateKeepWithPreviousPending(childLC.getKeepWithPreviousPending()); >@@ -154,7 +149,7 @@ > context.updateKeepWithNextPending(childLC.getKeepWithNextPending()); > childLC.clearKeepWithNextPending(); > >- context.updateKeepWithNextPending(getKeepWithNextStrength()); >+ context.updateKeepWithNextPending(getKeepWithNext()); > } > > SpaceResolver.resolveElementList(returnList); >@@ -203,18 +198,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 793568) >+++ 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 793568) >+++ 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/PageBreaker.java >=================================================================== >--- src/java/org/apache/fop/layoutmgr/PageBreaker.java (revision 793568) >+++ src/java/org/apache/fop/layoutmgr/PageBreaker.java (working copy) >@@ -443,9 +443,7 @@ > pslm.getCurrentPV().getCurrentSpan().notifyFlowsFinished(); > } > >- /** >- * @return the current child flow layout manager >- */ >+ /** @return the current child flow layout manager */ > protected LayoutManager getCurrentChildLM() { > return childFLM; > } >@@ -464,45 +462,52 @@ > */ > private void handleBreakTrait(int breakVal) { > Page curPage = pslm.getCurrentPage(); >- if (breakVal == Constants.EN_ALL) { >+ switch (breakVal) { >+ case Constants.EN_ALL: > //break due to span change in multi-column layout > curPage.getPageViewport().createSpan(true); > return; >- } else if (breakVal == Constants.EN_NONE) { >+ case Constants.EN_NONE: > curPage.getPageViewport().createSpan(false); > return; >- } else if (breakVal == Constants.EN_COLUMN >- || breakVal <= 0 >- || breakVal == Constants.EN_AUTO) { >+ case Constants.EN_COLUMN: >+ case Constants.EN_AUTO: >+ case Constants.EN_PAGE: >+ case -1: > PageViewport pv = curPage.getPageViewport(); > > //Check if previous page was spanned > boolean forceNewPageWithSpan = false; > RegionBody rb = (RegionBody)curPage.getSimplePageMaster().getRegion( > Constants.FO_REGION_BODY); >- if (rb.getColumnCount() > 1 >- && pv.getCurrentSpan().getColumnCount() == 1) { >- forceNewPageWithSpan = true; >- } >+ forceNewPageWithSpan >+ = (rb.getColumnCount() > 1 >+ && pv.getCurrentSpan().getColumnCount() == 1); > > if (forceNewPageWithSpan) { >+ log.trace("Forcing new page with span"); > curPage = pslm.makeNewPage(false, false); > curPage.getPageViewport().createSpan(true); > } else if (pv.getCurrentSpan().hasMoreFlows()) { >+ log.trace("Moving to next flow"); > pv.getCurrentSpan().moveToNextFlow(); > } else { >- curPage = pslm.makeNewPage(false, false); >+ log.trace("Making new page"); >+ /*curPage = */pslm.makeNewPage(false, false); > } > return; >+ default: >+ log.debug("handling break-before after page " + pslm.getCurrentPageNum() >+ + " breakVal=" + getBreakClassName(breakVal)); >+ if (needBlankPageBeforeNew(breakVal)) { >+ log.trace("Inserting blank page"); >+ /*curPage = */pslm.makeNewPage(true, false); >+ } >+ if (needNewPage(breakVal)) { >+ log.trace("Making new page"); >+ /*curPage = */pslm.makeNewPage(false, false); >+ } > } >- log.debug("handling break-before after page " + pslm.getCurrentPageNum() >- + " breakVal=" + getBreakClassName(breakVal)); >- if (needBlankPageBeforeNew(breakVal)) { >- curPage = pslm.makeNewPage(true, false); >- } >- if (needNewPage(breakVal)) { >- curPage = pslm.makeNewPage(false, false); >- } > } > > /** >Index: src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java >=================================================================== >--- src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java (revision 793568) >+++ src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java (working copy) >@@ -190,6 +190,75 @@ > footnoteElementIndex = -1; > } > >+ private int currentKeepContext = Constants.EN_AUTO; >+ private KnuthNode lastBeforeKeepContextSwitch; >+ >+ /** >+ * {@inheritDoc} >+ * Overridden to defer a part to the next page, if it >+ * must be kept within one page, but is too large to fit in >+ * the last column. >+ */ >+ protected KnuthNode recoverFromTooLong(KnuthNode lastTooLong) { >+ >+ if (log.isDebugEnabled()) { >+ log.debug("Recovering from too long: " + lastTooLong); >+ log.debug("\tlastTooShort = " + getLastTooShort()); >+ log.debug("\tlastBeforeKeepContextSwitch = " + lastBeforeKeepContextSwitch); >+ log.debug("\tcurrentKeepContext = " + AbstractBreaker.getBreakClassName(currentKeepContext)); >+ } >+ >+ if (lastBeforeKeepContextSwitch == null >+ || currentKeepContext == Constants.EN_AUTO) { >+ return super.recoverFromTooLong(lastTooLong); >+ } >+ >+ KnuthNode node = lastBeforeKeepContextSwitch; >+ lastBeforeKeepContextSwitch = null; >+ // content would overflow, insert empty page/column(s) and try again >+ while (!pageProvider.endPage(node.line - 1)) { >+ log.trace("Adding node for empty column"); >+ node = createNode( >+ node.position, >+ node.line + 1, 1, >+ 0, 0, 0, >+ 0, 0, 0, >+ 0, 0, node); >+ } >+ return node; >+ } >+ >+ /** >+ * Compare two KnuthNodes and return the node with the least demerit. >+ * >+ * @param node1 The first knuth node. >+ * @param node2 The other knuth node. >+ * @return the node with the least demerit. >+ */ >+ protected KnuthNode compareNodes(KnuthNode node1, KnuthNode node2) { >+ >+ /* if either node is null, return the other one */ >+ if (node1 == null || node2 == null) { >+ return (node1 == null) ? node2 : node1; >+ } >+ >+ /* if either one of the nodes corresponds to a mere column-break, >+ * and the other one corresponds to a page-break, return the page-break node >+ */ >+ if (pageProvider != null) { >+ if (pageProvider.endPage(node1.line - 1) >+ && !pageProvider.endPage(node2.line - 1)) { >+ return node1; >+ } else if (pageProvider.endPage(node2.line - 1) >+ && !pageProvider.endPage(node1.line - 1)) { >+ return node2; >+ } >+ } >+ >+ /* all other cases: use superclass implementation */ >+ return super.compareNodes(node1, node2); >+ } >+ > /** {@inheritDoc} */ > protected KnuthNode createNode(int position, int line, int fitness, > int totalWidth, int totalStretch, int totalShrink, >@@ -234,6 +303,28 @@ > } > > /** >+ * {@inheritDoc} >+ * Overridden to consider penalties with value {@link KnuthElement#INFINITE} >+ * as legal break-points, if the current keep-context allows this >+ * (a keep-*.within-page="always" constraint still permits column-breaks) >+ */ >+ protected void handlePenaltyAt(KnuthPenalty penalty, int position, >+ int allowedBreaks) { >+ super.handlePenaltyAt(penalty, position, allowedBreaks); >+ /* if the penalty had value INFINITE, default implementation >+ * will not have considered it a legal break, but it could still >+ * be one. >+ */ >+ if (penalty.getP() == KnuthPenalty.INFINITE) { >+ int breakClass = penalty.getBreakClass(); >+ if (breakClass == Constants.EN_PAGE >+ || breakClass == Constants.EN_COLUMN) { >+ considerLegalBreak(penalty, position); >+ } >+ } >+ } >+ >+ /** > * Handles the footnotes cited inside a block-level box. Updates footnotesList and the > * value of totalFootnotesLength with the lengths of the given footnotes. > * @param elementLists list of KnuthElement sequences corresponding to the footnotes >@@ -317,10 +408,60 @@ > > /** {@inheritDoc} */ > protected void considerLegalBreak(KnuthElement element, int elementIdx) { >+ if (element.isPenalty()) { >+ int breakClass = ((KnuthPenalty) element).getBreakClass(); >+ switch (breakClass) { >+ case Constants.EN_PAGE: >+ case Constants.EN_COLUMN: >+ if (this.currentKeepContext != breakClass) { >+ this.lastBeforeKeepContextSwitch = getLastTooShort(); >+ } >+ this.currentKeepContext = breakClass; >+ break; >+ case Constants.EN_AUTO: >+ this.currentKeepContext = breakClass; >+ break; >+ default: >+ //nop >+ } >+ } > super.considerLegalBreak(element, elementIdx); > newFootnotes = false; > } > >+ /** {@inheritDoc} */ >+ protected boolean elementCanEndLine(KnuthElement element, int line) { >+ if (!(element.isPenalty()) || 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 >+ || !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; >+ } >+ } >+ } >+ } >+ } >+ >+ /** {@inheritDoc} */ > protected int computeDifference(KnuthNode activeNode, KnuthElement element, > int elementIndex) { > KnuthPageNode pageNode = (KnuthPageNode) activeNode; >Index: src/java/org/apache/fop/layoutmgr/PageProvider.java >=================================================================== >--- src/java/org/apache/fop/layoutmgr/PageProvider.java (revision 793568) >+++ src/java/org/apache/fop/layoutmgr/PageProvider.java (working copy) >@@ -146,7 +146,50 @@ > 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}; >+ } >+ > /** >+ * Checks if a break at the passed index would start a new page >+ * @param index the index of the element before the break >+ * @return {@code true} if the break starts a new page >+ */ >+ boolean startPage(int index) { >+ return getColIndexAndColCount(index)[0] == 0; >+ } >+ >+ /** >+ * Checks if a break at the passed index would end a page >+ * @param index the index of the element before the break >+ * @return {@code true} if the break ends a page >+ */ >+ boolean endPage(int index) { >+ int[] colIndexAndColCount = getColIndexAndColCount(index); >+ return colIndexAndColCount[0] == colIndexAndColCount[1] - 1; >+ } >+ >+ /** >+ * Obtain the applicable column-count for the element at the >+ * passed index >+ * @param index the index of the element >+ * @return the number of columns >+ */ >+ int getColumnCount(int index) { >+ return getColIndexAndColCount(index)[1]; >+ } >+ >+ /** > * Returns the part index (0<x<partCount) which denotes the first part on the last page > * generated by the current element list. > * @param partCount Number of parts determined by the breaking algorithm >@@ -272,4 +315,4 @@ > return page; > } > >-} >\ No newline at end of file >+} >Index: src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java >=================================================================== >--- src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java (revision 793568) >+++ src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java (working copy) >@@ -29,10 +29,10 @@ > import org.apache.fop.area.Area; > import org.apache.fop.area.Block; > import org.apache.fop.fo.flow.ListBlock; >+import org.apache.fop.fo.properties.KeepProperty; > 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; >@@ -279,21 +279,18 @@ > } > > /** {@inheritDoc} */ >- public int getKeepTogetherStrength() { >- int strength = KeepUtil.getCombinedBlockLevelKeepStrength( >- getListBlockFO().getKeepTogether()); >- strength = Math.max(strength, getParentKeepTogetherStrength()); >- return strength; >+ public KeepProperty getKeepTogetherProperty() { >+ return getListBlockFO().getKeepTogether(); > } > > /** {@inheritDoc} */ >- public int getKeepWithNextStrength() { >- return KeepUtil.getCombinedBlockLevelKeepStrength(getListBlockFO().getKeepWithNext()); >+ public KeepProperty getKeepWithPreviousProperty() { >+ return getListBlockFO().getKeepWithPrevious(); > } > > /** {@inheritDoc} */ >- public int getKeepWithPreviousStrength() { >- return KeepUtil.getCombinedBlockLevelKeepStrength(getListBlockFO().getKeepWithPrevious()); >+ public KeepProperty getKeepWithNextProperty() { >+ return getListBlockFO().getKeepWithNext(); > } > > /** {@inheritDoc} */ >Index: src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java >=================================================================== >--- src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java (revision 793568) >+++ src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java (working copy) >@@ -32,13 +32,13 @@ > 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.fo.properties.KeepProperty; > 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.Keep; > import org.apache.fop.layoutmgr.KnuthBlockBox; > import org.apache.fop.layoutmgr.KnuthBox; > import org.apache.fop.layoutmgr.KnuthElement; >@@ -83,8 +83,8 @@ > private MinOptMax effSpaceBefore; > private MinOptMax effSpaceAfter; > >- private int keepWithNextPendingOnLabel; >- private int keepWithNextPendingOnBody; >+ private Keep keepWithNextPendingOnLabel; >+ private Keep keepWithNextPendingOnBody; > > private int listItemHeight; > >@@ -254,8 +254,8 @@ > > context.updateKeepWithNextPending(this.keepWithNextPendingOnLabel); > context.updateKeepWithNextPending(this.keepWithNextPendingOnBody); >- context.updateKeepWithNextPending(getKeepWithNextStrength()); >- context.updateKeepWithPreviousPending(getKeepWithPreviousStrength()); >+ context.updateKeepWithNextPending(getKeepWithNext()); >+ context.updateKeepWithPreviousPending(getKeepWithPrevious()); > > setFinished(true); > resetSpaces(); >@@ -276,16 +276,16 @@ > int totalHeight = Math.max(fullHeights[0], fullHeights[1]); > int step; > int addedBoxHeight = 0; >- int keepWithNextActive = BlockLevelLayoutManager.KEEP_AUTO; >+ Keep keepWithNextActive = Keep.KEEP_AUTO; > > LinkedList returnList = new LinkedList(); > while ((step = getNextStep(elementLists, start, end, partialHeights)) > 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 793568) >+++ 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 793568) >+++ src/java/org/apache/fop/layoutmgr/table/ActiveCell.java (working copy) >@@ -32,8 +32,8 @@ > 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; >@@ -75,7 +75,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; > >@@ -218,7 +218,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); >@@ -314,7 +314,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; >@@ -533,7 +537,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/ >@@ -576,8 +580,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 793568) >+++ 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 793568) >+++ 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 793568) >+++ 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 793568) >+++ 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,25 +32,13 @@ > 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.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.Position; >-import org.apache.fop.layoutmgr.PositionIterator; >-import org.apache.fop.layoutmgr.SpaceResolver; >-import org.apache.fop.layoutmgr.TraitSetter; >+import org.apache.fop.layoutmgr.*; > import org.apache.fop.traits.BorderProps; > import org.apache.fop.traits.MinOptMax; > import org.apache.fop.util.ListUtil; >@@ -138,9 +127,9 @@ > List contentList = new LinkedList(); > List returnList = new LinkedList(); > >- BlockLevelLayoutManager curLM; // currently active LM >- BlockLevelLayoutManager prevLM = null; // previously active LM >- while ((curLM = (BlockLevelLayoutManager) getChildLM()) != null) { >+ LayoutManager curLM; // currently active LM >+ LayoutManager prevLM = null; // previously active LM >+ while ((curLM = getChildLM()) != null) { > LayoutContext childLC = new LayoutContext(0); > // curLM is a ? > childLC.setStackLimitBP(MinOptMax.subtract(context >@@ -153,11 +142,12 @@ > log.debug("child LM signals pending keep with next"); > } > if (contentList.isEmpty() && childLC.isKeepWithPreviousPending()) { >- primaryGridUnit.setKeepWithPreviousStrength(childLC.getKeepWithPreviousPending()); >+ primaryGridUnit.setKeepWithPrevious(childLC.getKeepWithPreviousPending()); > childLC.clearKeepWithPreviousPending(); > } > >- if (prevLM != null) { >+ if (prevLM != null >+ && !ElementListUtils.endsWithForcedBreak(contentList)) { > // there is a block handled by prevLM > // before the one handled by curLM > addInBetweenBreak(contentList, context, childLC); >@@ -174,7 +164,7 @@ > } > prevLM = curLM; > } >- primaryGridUnit.setKeepWithNextStrength(context.getKeepWithNextPending()); >+ primaryGridUnit.setKeepWithNext(context.getKeepWithNextPending()); > > returnedList = new LinkedList(); > if (!contentList.isEmpty()) { >@@ -195,7 +185,7 @@ > } > final KnuthElement lastItem = (KnuthElement) ListUtil > .getLast(returnList); >- if (((KnuthElement) lastItem).isForcedBreak()) { >+ if (lastItem.isForcedBreak()) { > KnuthPenalty p = (KnuthPenalty) lastItem; > primaryGridUnit.setBreakAfter(p.getBreakClass()); > p.setP(0); >@@ -556,26 +546,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 793568) >+++ 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,32 +202,21 @@ > } > > /** {@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()); > */ > } > >-} >\ No newline at end of file >+} >Index: src/java/org/apache/fop/layoutmgr/table/TableStepper.java >=================================================================== >--- src/java/org/apache/fop/layoutmgr/table/TableStepper.java (revision 793568) >+++ 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 793568) >+++ 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 793568) >+++ src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java (working copy) >@@ -31,9 +31,11 @@ > import org.apache.fop.area.Block; > import org.apache.fop.area.BlockParent; > import org.apache.fop.fo.FObj; >+import org.apache.fop.fo.Constants; > import org.apache.fop.fo.properties.BreakPropertySet; > import org.apache.fop.fo.properties.CommonBorderPaddingBackground; > import org.apache.fop.fo.properties.SpaceProperty; >+import org.apache.fop.fo.properties.KeepProperty; > import org.apache.fop.layoutmgr.inline.InlineLayoutManager; > import org.apache.fop.layoutmgr.inline.LineLayoutManager; > import org.apache.fop.traits.MinOptMax; >@@ -259,7 +261,7 @@ > > updateContentAreaIPDwithOverconstrainedAdjust(); > >- List returnedList = null; >+ List returnedList; > List contentList = new LinkedList(); > List returnList = new LinkedList(); > >@@ -274,7 +276,7 @@ > > if (!firstVisibleMarkServed) { > addKnuthElementsForSpaceBefore(returnList, alignment); >- context.updateKeepWithPreviousPending(getKeepWithPreviousStrength()); >+ context.updateKeepWithPreviousPending(getKeepWithPrevious()); > } > > addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed); >@@ -316,7 +318,7 @@ > } > if (returnedList != null > && returnedList.size() == 1 >- && ((ListElement) returnedList.get(0)).isForcedBreak()) { >+ && ElementListUtils.startsWithForcedBreak(returnedList)) { > > if (curLM.isFinished() && !hasNextChildLM()) { > // a descendant of this block has break-before >@@ -342,7 +344,6 @@ > > // "wrap" the Position inside each element > // moving the elements from contentList to returnList >- returnedList = new LinkedList(); > wrapPositionElements(contentList, returnList); > > return returnList; >@@ -375,7 +376,6 @@ > } > /* end of extension */ > >- returnedList = new LinkedList(); > wrapPositionElements(contentList, returnList); > > return returnList; >@@ -394,7 +394,6 @@ > } > /* end of extension */ > >- returnedList = new LinkedList(); > if (!contentList.isEmpty()) { > wrapPositionElements(contentList, returnList); > } else if (forcedBreakAfterLast == null) { >@@ -417,7 +416,7 @@ > returnList.add(forcedBreakAfterLast); > } > >- context.updateKeepWithNextPending(getKeepWithNextStrength()); >+ context.updateKeepWithNextPending(getKeepWithNext()); > > setFinished(true); > >@@ -426,31 +425,31 @@ > > /** > * 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 contentList >+ * @param parentLC > * @param childLC the currently active child layout context > */ >- protected void addInBetweenBreak(List contentList, LayoutContext context, >- LayoutContext childLC) { >+ protected void addInBetweenBreak(List contentList, LayoutContext parentLC, >+ LayoutContext childLC) { >+ > if (mustKeepTogether() >- || context.isKeepWithNextPending() >+ || parentLC.isKeepWithNextPending() > || childLC.isKeepWithPreviousPending()) { > >- int strength = getKeepTogetherStrength(); >+ Keep keep = getKeepTogether(); > > //Handle pending keep-with-next >- strength = Math.max(strength, context.getKeepWithNextPending()); >- context.clearKeepWithNextPending(); >+ keep = keep.compare(parentLC.getKeepWithNextPending()); >+ parentLC.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); >- > // add a penalty to forbid or discourage a break between blocks > contentList.add(new BreakElement( >- new Position(this), penalty, context)); >+ new Position(this), keep.getPenalty(), >+ keep.getContext(), parentLC)); > return; > } > >@@ -481,7 +480,7 @@ > > // add a null penalty to allow a break between blocks > contentList.add(new BreakElement( >- new Position(this), 0, context)); >+ new Position(this), 0, Constants.EN_AUTO, parentLC)); > } > } > >@@ -817,36 +816,80 @@ > * 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(); > } > >+ /** {@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()); >+ } >+ > /** >+ * {@inheritDoc} >+ * Default implementation throws {@code IllegalStateException} >+ * Must be implemented by the subclass, if applicable. >+ */ >+ public KeepProperty getKeepTogetherProperty() { >+ throw new IllegalStateException(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ * Default implementation throws {@code IllegalStateException} >+ * Must be implemented by the subclass, if applicable. >+ */ >+ public KeepProperty getKeepWithPreviousProperty() { >+ throw new IllegalStateException(); >+ } >+ >+ /** >+ * {@inheritDoc} >+ * Default implementation throws {@code IllegalStateException} >+ * Must be implemented by the subclass, if applicable. >+ */ >+ public KeepProperty getKeepWithNextProperty() { >+ throw new IllegalStateException(); >+ } >+ >+ /** > * Adds the unresolved elements for border and padding to a layout context so break > * possibilities can be properly constructed. > * @param context the layout context >Index: src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java >=================================================================== >--- src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java (revision 793568) >+++ src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java (working copy) >@@ -611,6 +611,14 @@ > } > > /** >+ * Return the last node that yielded a too short line. >+ * @return the node corresponding to the last too short line >+ */ >+ protected final KnuthNode getLastTooShort() { >+ return this.lastTooShort; >+ } >+ >+ /** > * Generic handler for a {@link KnuthElement} at the given {@code position}, > * taking into account whether the preceding element was a box, and which > * type(s) of breaks are allowed. >@@ -647,7 +655,7 @@ > > /** > * Handle a {@link KnuthBox}. >- * <em>Note: default implementation just adds the box's width >+ * <br/><em>Note: default implementation just adds the box's width > * to the total content width. Subclasses that do not keep track > * of this themselves, but override this method, should remember > * to call {@code super.handleBox(box)} to avoid unwanted side-effects.</em> >@@ -808,14 +816,21 @@ > lastDeactivated = null; > lastTooLong = null; > for (int line = startLine; line < endLine; line++) { >- if (!elementCanEndLine(element, line)) { >- continue; >- } > for (KnuthNode node = getNode(line); node != null; node = node.next) { > if (node.position == elementIdx) { > continue; > } > int difference = computeDifference(node, element, elementIdx); >+ if (!elementCanEndLine(element, endLine)) { >+ if (difference >= 0) { >+ /* as long as the difference is positive, >+ * we don't really need a break anyway... >+ */ >+ log.trace("Skipping legal break"); >+ break; >+ } >+ } >+ > double r = computeAdjustmentRatio(node, difference); > int availableShrink = totalShrink - node.totalShrink; > int availableStretch = totalStretch - node.totalStretch; >Index: src/java/org/apache/fop/fo/flow/table/EffRow.java >=================================================================== >--- src/java/org/apache/fop/fo/flow/table/EffRow.java (revision 793568) >+++ 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 793568) >+++ 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; > } > > /** >Index: test/layoutengine/standard-testcases/inline_block_nested_6.xml >=================================================================== >--- test/layoutengine/standard-testcases/inline_block_nested_6.xml (revision 793568) >+++ test/layoutengine/standard-testcases/inline_block_nested_6.xml (working copy) >@@ -52,16 +52,15 @@ > <skip>5</skip> > <!-- penalty between blocks b11 and b12, set by InlineLM in b1 --> > <penalty w="0" p="0"/> >- <skip>6</skip> >+ <skip>5</skip> > <!-- penalty between blocks b21 and b22, set by InlineLM in b2 --> > <!-- keep-together.within-page="always" --> > <penalty w="0" p="1000"/> >- <skip>6</skip> >+ <skip>3</skip> > <!-- penalty between blocks b31 and b32, set by InlineLM in b3 --> > <!-- keep-with-next.within-page="always" --> > <penalty w="0" p="1000"/> >- <skip>5</skip> >- <skip>3</skip> >+ <skip>14</skip> > </element-list> > </checks> > </testcase> >Index: test/layoutengine/standard-testcases/keep_within-column_basic.xml >=================================================================== >--- test/layoutengine/standard-testcases/keep_within-column_basic.xml (revision 0) >+++ test/layoutengine/standard-testcases/keep_within-column_basic.xml (revision 0) >@@ -0,0 +1,141 @@ >+<?xml version="1.0" encoding="UTF-8"?> >+<!-- >+ 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$ --> >+<testcase> >+ <info> >+ <p> >+ This test checks whether keeps within-column are respected. >+ </p> >+ </info> >+ <fo> >+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> >+ <fo:layout-master-set> >+ <fo:simple-page-master master-name="page" page-width="400pt" page-height="70pt"> >+ <fo:region-body column-count="5" /> >+ </fo:simple-page-master> >+ </fo:layout-master-set> >+ <fo:page-sequence master-reference="page" font-size="10pt"> >+ <fo:flow flow-name="xsl-region-body"> >+ <fo:block break-before="page"> >+ <!-- simple test: keep the second block together within >+ one column, breaking the preceding block early >+ if necessary --> >+ <fo:block id="block-1"> >+ [BOB-1] foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar [EOB-1] >+ </fo:block> >+ <fo:block id="block-2" keep-together.within-column="always"> >+ [BOB-2] foo bar foo bar foo bar foo bar foo [EOB-2] >+ </fo:block> >+ </fo:block> >+ <fo:block break-before="page"> >+ <!-- same as the first, but now a nested block >+ with a higher integer value, and some content >+ following --> >+ <fo:block id="block-3" keep-together.within-column="5"> >+ [BOB-3] foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ <fo:block font-weight="bold" id="block-3a" keep-together.within-column="always"> >+ [BOB-3a] foo bar foo bar foo bar foo bar foo [EOB-3a] >+ </fo:block> >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar [EOB-3] >+ </fo:block> >+ </fo:block> >+ <fo:block break-before="page"> >+ <!-- nested block must be kept together within the same >+ page, while the outer block may be broken, if necessary --> >+ <fo:block font-style="italic" id="block-4" keep-together.within-column="5"> >+ [BOB-4] foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ <fo:block id="block-4a" keep-together.within-page="always"> >+ [BOB-4a] foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar [EOB-4a] >+ </fo:block> >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar [EOB-4] >+ </fo:block> >+ </fo:block> >+ <fo:block break-before="page"> >+ <!-- test keep-with-next in conjunction with keep-together >+ respecting the default value for widows/orphans --> >+ <fo:block id="block-5"> >+ <fo:block id="block-5a"> >+ [BOB-5a] foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar [EOB-5a] >+ </fo:block> >+ <fo:block id="block-5b" keep-with-next.within-column="always"> >+ [BOB-5b] foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar [EOB-5b] >+ </fo:block> >+ <fo:block id="block-5c" keep-together.within-column="always"> >+ [BOB-5c] foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar [EOB-5c] >+ </fo:block> >+ </fo:block> >+ </fo:block> >+ <fo:block break-before="page"> >+ <!-- test keep-together in conjunction with keep-with-previous --> >+ <fo:block id="block-6"> >+ <fo:block id="block-6a"> >+ [BOB-6a] foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar [EOB-6a] >+ </fo:block> >+ <fo:block id="block-6b" keep-together.within-column="always"> >+ [BOB-6b] foo bar foo bar foo bar foo bar foo bar [EOB-6b] >+ </fo:block> >+ <fo:block id="block-6c" keep-with-previous.within-column="always"> >+ [BOB-6c] foo bar foo bar foo bar foo bar foo bar >+ foo bar foo bar foo bar foo bar foo bar [EOB-6c] >+ </fo:block> >+ </fo:block> >+ </fo:block> >+ </fo:flow> >+ </fo:page-sequence> >+ </fo:root> >+ </fo> >+ <checks> >+ <eval expected="10" xpath="count(//page)" /> >+ </checks> >+</testcase> >+ >+ >Index: test/layoutengine/standard-testcases/table-row_keep-together.xml >=================================================================== >--- test/layoutengine/standard-testcases/table-row_keep-together.xml (revision 793568) >+++ test/layoutengine/standard-testcases/table-row_keep-together.xml (working copy) >@@ -64,10 +64,10 @@ > <element-list category="breaker" index="0"> > <box w="14400"/> > <penalty w="0" p="0"/> >- <box w="28800"/> >- <penalty w="0" p="0"/> > <box w="14400"/> >- <skip>3</skip> >+ <penalty w="0" p="INF"/> >+ <box w="14400"/> >+ <skip>5</skip> > </element-list> > </checks> > </testcase> >Index: test/layoutengine/standard-testcases/table_keep-together.xml >=================================================================== >--- test/layoutengine/standard-testcases/table_keep-together.xml (revision 793568) >+++ test/layoutengine/standard-testcases/table_keep-together.xml (working copy) >@@ -101,9 +101,11 @@ > <element-list category="breaker" index="0"> > <box w="14400"/> > <penalty w="0" p="0"/> >- <box w="28800"/> >+ <box w="14400"/> > <penalty w="0" p="INF"/> > <box w="14400"/> >+ <penalty w="0" p="INF"/> >+ <box w="14400"/> > <penalty w="0" p="0"/> > <box w="14400"/> > <skip>3</skip>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 46905
:
23411
|
23799
|
23800
|
23801
|
23802
|
23863
|
23864
|
23865
|
23886
|
23916
|
23990
|
24015
|
24152