Index: src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java
===================================================================
--- src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java (revision 786985)
+++ 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 786985)
+++ src/java/org/apache/fop/layoutmgr/KeepUtil.java (working copy)
@@ -1,109 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.layoutmgr;
-
-import org.apache.fop.fo.Constants;
-import org.apache.fop.fo.properties.KeepProperty;
-import org.apache.fop.fo.properties.Property;
-
-/**
- * Utility class for working with keeps.
- */
-public class KeepUtil {
-
- /**
- * Converts a keep property into an integer value.
- *
- * Note: The conversion restricts the effectively available integer range by two values.
- * Integer.MIN_VALUE is used to represent the value "auto" and
- * Integer.MAX_VALUE is used to represebt the value "always".
- * @param keep the keep property
- * @return the keep value as an integer
- */
- public static int getKeepStrength(Property keep) {
- if (keep.isAuto()) {
- return BlockLevelLayoutManager.KEEP_AUTO;
- } else if (keep.getEnum() == Constants.EN_ALWAYS) {
- return BlockLevelLayoutManager.KEEP_ALWAYS;
- } else {
- return keep.getNumber().intValue();
- }
- }
-
- /**
- * Returns the combined block-level keep strength from a keep property.
- *
- * Note: This is a temporary method to be used until it is possible to differentiate between
- * page and column keeps!
- * @param keep the keep property
- * @return the combined keep strength
- */
- public static int getCombinedBlockLevelKeepStrength(KeepProperty keep) {
- return Math.max(
- getKeepStrength(keep.getWithinPage()),
- getKeepStrength(keep.getWithinColumn()));
- }
-
- /**
- * Indicates whether a keep strength indicates a keep constraint.
- * @param strength the keep strength
- * @return true if the keep is not "auto"
- */
- public static boolean hasKeep(int strength) {
- return strength > BlockLevelLayoutManager.KEEP_AUTO;
- }
-
- /**
- * Returns the penalty value to be used for a certain keep strength.
- *
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 786985)
+++ 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 786985)
+++ 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 786985)
+++ 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 786985)
+++ 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 786985)
+++ 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 786985)
+++ src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java (working copy)
@@ -24,6 +24,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
import org.apache.fop.area.Area;
import org.apache.fop.area.Block;
import org.apache.fop.area.Trait;
@@ -31,16 +32,17 @@
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.ElementListUtils;
+import org.apache.fop.layoutmgr.Keep;
import org.apache.fop.layoutmgr.KnuthBox;
import org.apache.fop.layoutmgr.KnuthElement;
import org.apache.fop.layoutmgr.KnuthGlue;
@@ -153,11 +155,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 +177,7 @@
}
prevLM = curLM;
}
- primaryGridUnit.setKeepWithNextStrength(context.getKeepWithNextPending());
+ primaryGridUnit.setKeepWithNext(context.getKeepWithNextPending());
returnedList = new LinkedList();
if (!contentList.isEmpty()) {
@@ -195,7 +198,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 +559,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 786985)
+++ 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 786985)
+++ 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 786985)
+++ 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 786985)
+++ src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java (working copy)
@@ -34,6 +34,7 @@
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 +260,7 @@
updateContentAreaIPDwithOverconstrainedAdjust();
- List returnedList = null;
+ List returnedList;
List contentList = new LinkedList();
List returnList = new LinkedList();
@@ -274,7 +275,7 @@
if (!firstVisibleMarkServed) {
addKnuthElementsForSpaceBefore(returnList, alignment);
- context.updateKeepWithPreviousPending(getKeepWithPreviousStrength());
+ context.updateKeepWithPreviousPending(getKeepWithPrevious());
}
addKnuthElementsForBorderPaddingBefore(returnList, !firstVisibleMarkServed);
@@ -316,7 +317,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 +343,6 @@
// "wrap" the Position inside each element
// moving the elements from contentList to returnList
- returnedList = new LinkedList();
wrapPositionElements(contentList, returnList);
return returnList;
@@ -375,7 +375,6 @@
}
/* end of extension */
- returnedList = new LinkedList();
wrapPositionElements(contentList, returnList);
return returnList;
@@ -394,7 +393,6 @@
}
/* end of extension */
- returnedList = new LinkedList();
if (!contentList.isEmpty()) {
wrapPositionElements(contentList, returnList);
} else if (forcedBreakAfterLast == null) {
@@ -417,7 +415,7 @@
returnList.add(forcedBreakAfterLast);
}
- context.updateKeepWithNextPending(getKeepWithNextStrength());
+ context.updateKeepWithNextPending(getKeepWithNext());
setFinished(true);
@@ -426,31 +424,32 @@
/**
* 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);
+ int penalty = keep.getPenalty();
// add a penalty to forbid or discourage a break between blocks
contentList.add(new BreakElement(
- new Position(this), penalty, context));
+ new Position(this), penalty, keep.getContext(), 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, 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 UnsupportedOperationException}
+ * Must be implemented by the subclass, if applicable.
+ */
+ public KeepProperty getKeepTogetherProperty() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ * Default implementation throws {@code UnsupportedOperationException}
+ * Must be implemented by the subclass, if applicable.
+ */
+ public KeepProperty getKeepWithPreviousProperty() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ * Default implementation throws {@code UnsupportedOperationException}
+ * Must be implemented by the subclass, if applicable.
+ */
+ public KeepProperty getKeepWithNextProperty() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
* 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 786985)
+++ src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java (working copy)
@@ -22,12 +22,12 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.Constants;
/**
* The set of nodes is sorted into lines indexed into activeLines.
* The nodes in each line are linked together in a single linked list by the
- * KnuthNode.next field. The activeLines array contains a link to the head of
+ * {@link KnuthNode#next} field. The activeLines array contains a link to the head of
* the linked list in index 'line*2' and a link to the tail at index 'line*2+1'.
*
* The set of active nodes can be traversed by
@@ -57,13 +57,20 @@
/** wrap-option = "no-wrap". */
public static final int ONLY_FORCED_BREAKS = 2;
+ static class FitnessClasses {
+ static final int VERY_TIGHT = 0;
+ static final int TIGHT = 1;
+ static final int LOOSE = 2;
+ static final int VERY_LOOSE = 3;
+
+ static final String[] NAMES = { "VERY TIGHT", "TIGHT", "LOOSE", "VERY LOOSE" };
+ }
+
// parameters of Knuth's algorithm:
- /** Penalty value for flagged penalties. */
- private int flaggedPenalty = 50;
/** Demerit for consecutive lines ending at flagged penalties. */
- protected int repeatedFlaggedDemerit = 50;
+ protected int repeatedFlaggedDemerit = KnuthPenalty.FLAGGED_PENALTY;
/** Demerit for consecutive lines belonging to incompatible fitness classes . */
- protected int incompatibleFitnessDemerit = 50;
+ protected int incompatibleFitnessDemerit = KnuthPenalty.FLAGGED_PENALTY;
/** Maximum number of consecutive lines ending with a flagged penalty.
* Only a value >= 1 is a significant limit.
*/
@@ -110,7 +117,7 @@
/** Alignment of the paragraph's last line. */
protected int alignmentLast;
/** Used to handle the text-indent property (indent the first line of a paragraph). */
- protected boolean bFirst;
+ protected boolean indentFirstPart;
/**
* The set of active nodes in ascending line order. For each line l, activeLines[2l] contains a
@@ -151,30 +158,35 @@
protected BestRecords best;
- /** {@inheritDoc} */
private boolean partOverflowRecoveryActivated = true;
private KnuthNode lastRecovered;
/**
* Create a new instance.
- * @param align alignment of the paragraph/page. One of EN_START, EN_JUSTIFY, etc. For
- * pages EN_BEFORE, EN_AFTER are mapped to the corresponding inline properties
- * (EN_START, EN_END)
+ *
+ * @param align alignment of the paragraph/page. One of {@link Constants#EN_START},
+ * {@link Constants#EN_JUSTIFY}, {@link Constants#EN_CENTER},
+ * {@link Constants#EN_END}.
+ * For pages, {@link Constants#EN_BEFORE} and {@link Constants#EN_AFTER}
+ * are mapped to the corresponding inline properties,
+ * {@link Constants#EN_START} and {@link Constants#EN_END}.
* @param alignLast alignment of the paragraph's last line
- * @param first for the text-indent property (indent the first line of a paragraph)
- * @param partOverflowRecovery true if too long elements should be moved to the next line/part
- * @param maxFlagCount maximum allowed number of consecutive lines ending at a flagged penalty
- * item
+ * @param first for the text-indent property ({@code true} if the first line
+ * of a paragraph should be indented)
+ * @param partOverflowRecovery {@code true} if too long elements should be moved to
+ * the next line/part
+ * @param maxFlagCount maximum allowed number of consecutive lines ending at a flagged penalty
+ * item
*/
public BreakingAlgorithm(int align, int alignLast,
boolean first, boolean partOverflowRecovery,
int maxFlagCount) {
- alignment = align;
- alignmentLast = alignLast;
- bFirst = first;
+ this.alignment = align;
+ this.alignmentLast = alignLast;
+ this.indentFirstPart = first;
this.partOverflowRecoveryActivated = partOverflowRecovery;
this.best = new BestRecords();
- maxFlaggedPenaltiesCount = maxFlagCount;
+ this.maxFlaggedPenaltiesCount = maxFlagCount;
}
@@ -249,7 +261,8 @@
return "";
+ + " dem:" + totalDemerits
+ + " fitness:" + FitnessClasses.NAMES[fitness] + ">";
}
}
@@ -386,7 +399,6 @@
* one of the optimal breakpoints
* @param sequence the corresponding paragraph
* @param total the number of lines into which the paragraph will be broken
- * @see #calculateBreakPoints(KnuthNode, KnuthSequence, int)
*/
public abstract void updateData2(KnuthNode bestActiveNode,
KnuthSequence sequence,
@@ -404,13 +416,18 @@
return findBreakingPoints(par, 0, threshold, force, allowedBreaks);
}
- /** Finds an optimal set of breakpoints for the given paragraph.
- * @param par the paragraph to break
- * @param startIndex index of the Knuth element at which the breaking must start
- * @param threshold upper bound of the adjustment ratio
- * @param force true if a set of breakpoints must be found even if there are no
- * feasible ones
- * @param allowedBreaks one of ONLY_FORCED_BREAKS, NO_FLAGGED_PENALTIES, ALL_BREAKS
+ /**
+ * Finds an optimal set of breakpoints for the given paragraph.
+ *
+ * @param par the paragraph to break
+ * @param startIndex index of the Knuth element at which the breaking must start
+ * @param threshold upper bound of the adjustment ratio
+ * @param force {@code true} if a set of breakpoints must be found, even
+ * if there are no feasible ones
+ * @param allowedBreaks the type(s) of breaks allowed. One of {@link #ONLY_FORCED_BREAKS},
+ * {@link #NO_FLAGGED_PENALTIES} or {@link #ALL_BREAKS}.
+ *
+ * @return the number of effective breaks
*/
public int findBreakingPoints(KnuthSequence par, int startIndex,
double threshold, boolean force,
@@ -418,142 +435,67 @@
this.par = par;
this.threshold = threshold;
this.force = force;
- //this.lineWidth = lineWidth;
+
+ // initialize the algorithm
initialize();
- activeLines = new KnuthNode[20];
-
- // reset lastTooShort and lastTooLong, as they could be not null
- // because of previous calls to findBreakingPoints
- lastTooShort = lastTooLong = null;
- // reset startLine and endLine
- startLine = endLine = 0;
- // current element in the paragraph
- KnuthElement thisElement = null;
// previous element in the paragraph is a KnuthBox?
boolean previousIsBox = false;
- // index of the first KnuthBox in the sequence
- int firstBoxIndex = startIndex;
- if (alignment != org.apache.fop.fo.Constants.EN_CENTER) {
- while (par.size() > firstBoxIndex
- && !((KnuthElement) par.get(firstBoxIndex)).isBox()) {
- firstBoxIndex++;
- }
+ // index of the first KnuthBox in the sequence, in case of non-centered
+ // alignment. For centered alignment, we need to take into account preceding
+ // penalties+glues used for the filler spaces
+ if (alignment != Constants.EN_CENTER) {
+ startIndex = par.getFirstBoxIndex();
}
+ startIndex = (startIndex == -1) ? 0 : startIndex;
// create an active node representing the starting point
- activeLines = new KnuthNode[20];
- addNode(0, createNode(firstBoxIndex, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, null));
+ addNode(0, createNode(startIndex, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, null));
+ KnuthNode lastForced = getNode(0);
+
if (log.isTraceEnabled()) {
log.trace("Looping over " + (par.size() - startIndex) + " elements");
+ log.trace(par);
}
- KnuthNode lastForced = getNode(0);
+ // main loop
+ int elementIndex = startIndex;
+ while (!isEndOfParagraph(elementIndex)) {
- // main loop
- for (int i = startIndex; i < par.size(); i++) {
- thisElement = getElement(i);
- if (thisElement.isBox()) {
- // a KnuthBox object is not a legal line break
- totalWidth += thisElement.getW();
- previousIsBox = true;
- handleBox((KnuthBox) thisElement);
- } else if (thisElement.isGlue()) {
- // a KnuthGlue object is a legal line break
- // only if the previous object is a KnuthBox
- // consider these glues according to the value of allowedBreaks
- if (previousIsBox
- && !(allowedBreaks == ONLY_FORCED_BREAKS)) {
- considerLegalBreak(thisElement, i);
- }
- totalWidth += thisElement.getW();
- totalStretch += thisElement.getY();
- totalShrink += thisElement.getZ();
- previousIsBox = false;
- } else {
- // a KnuthPenalty is a legal line break
- // only if its penalty is not infinite;
- // consider all penalties, non-flagged penalties or non-forcing penalties
- // according to the value of allowedBreaks
- if (((KnuthPenalty) thisElement).getP() < KnuthElement.INFINITE
- && (!(allowedBreaks == NO_FLAGGED_PENALTIES)
- || !(((KnuthPenalty) thisElement).isFlagged()))
- && (!(allowedBreaks == ONLY_FORCED_BREAKS)
- || ((KnuthPenalty) thisElement).getP() == -KnuthElement.INFINITE)) {
- considerLegalBreak(thisElement, i);
- }
- previousIsBox = false;
- }
+ previousIsBox = handleElementAt(
+ elementIndex, previousIsBox, allowedBreaks).isBox();
+
if (activeNodeCount == 0) {
+
if (!force) {
log.debug("Could not find a set of breaking points " + threshold);
return 0;
}
+
// lastDeactivated was a "good" break, while lastTooShort and lastTooLong
// were "bad" breaks since the beginning;
// if it is not the node we just restarted from, lastDeactivated can
// replace either lastTooShort or lastTooLong
if (lastDeactivated != null && lastDeactivated != lastForced) {
- if (lastDeactivated.adjustRatio > 0) {
- lastTooShort = lastDeactivated;
- } else {
- lastTooLong = lastDeactivated;
- }
+ replaceLastDeactivated();
}
- if (lastTooShort == null || lastForced.position == lastTooShort.position) {
- if (isPartOverflowRecoveryActivated()) {
- if (this.lastRecovered == null) {
- this.lastRecovered = lastTooLong;
- if (log.isDebugEnabled()) {
- log.debug("Recovery point: " + lastRecovered);
- }
- }
- // content would overflow, insert empty line/page and try again
- KnuthNode node = createNode(
- lastTooLong.previous.position, lastTooLong.previous.line + 1, 1,
- 0, 0, 0,
- 0, 0, 0,
- 0, 0, lastTooLong.previous);
- lastForced = node;
- node.fitRecoveryCounter = lastTooLong.previous.fitRecoveryCounter + 1;
- if (log.isDebugEnabled()) {
- log.debug("first part doesn't fit into line, recovering: "
- + node.fitRecoveryCounter);
- }
- if (node.fitRecoveryCounter > getMaxRecoveryAttempts()) {
- while (lastForced.fitRecoveryCounter > 0) {
- lastForced = lastForced.previous;
- lastDeactivated = lastForced.previous;
- startLine--;
- endLine--;
- }
- lastForced = this.lastRecovered;
- this.lastRecovered = null;
- startLine = lastForced.line;
- endLine = lastForced.line;
- log.debug("rolled back...");
- }
- } else {
- lastForced = lastTooLong;
- }
+
+ if (lastTooShort == null
+ || lastForced.position == lastTooShort.position) {
+ lastForced = recoverFromOverflow();
} else {
lastForced = lastTooShort;
this.lastRecovered = null;
}
-
- if (log.isDebugEnabled()) {
- log.debug("Restarting at node " + lastForced);
- }
- i = restartFrom(lastForced, i);
+ elementIndex = restartFrom(lastForced, elementIndex);
+ } else {
+ elementIndex++;
}
}
+
finish();
- if (log.isTraceEnabled()) {
- log.trace("Main loop completed " + activeNodeCount);
- log.trace("Active nodes=" + toString(""));
- }
// there is at least one set of breaking points
// select one or more active nodes, removing the others from the list
@@ -571,42 +513,33 @@
return line;
}
- /**
- * This method tries to find the context FO for a position in a KnuthSequence.
- * @param seq the KnuthSequence to inspect
- * @param position the index of the position in the KnuthSequence
- * @return the requested context FO note or null, if no context node could be determined
- */
- private FONode findContextFO(KnuthSequence seq, int position) {
- ListElement el = seq.getElement(position);
- while (el.getLayoutManager() == null && position < seq.size() - 1) {
- position++;
- el = seq.getElement(position);
+ protected KnuthNode recoverFromTooLong(KnuthNode lastTooLong) {
+ if (log.isDebugEnabled()) {
+ log.debug("Recovering from too long: " + lastTooLong);
}
- Position pos = (el != null ? el.getPosition() : null);
- LayoutManager lm = (pos != null ? pos.getLM() : null);
- while (pos instanceof NonLeafPosition) {
- pos = ((NonLeafPosition)pos).getPosition();
- if (pos != null && pos.getLM() != null) {
- lm = pos.getLM();
- }
- }
- if (lm != null) {
- return lm.getFObj();
- } else {
- return null;
- }
+
+ // content would overflow, insert empty line/page and try again
+ return createNode(
+ lastTooLong.previous.position, lastTooLong.previous.line + 1, 1,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, lastTooLong.previous);
}
- /** Resets the algorithm's variables. */
+ /** Initializes the algorithm's variables. */
protected void initialize() {
this.totalWidth = 0;
this.totalStretch = 0;
this.totalShrink = 0;
+ this.lastTooShort = this.lastTooLong = null;
+ this.startLine = this.endLine = 0;
+ this.activeLines = new KnuthNode[20];
}
- /** Creates a new active node for a feasible breakpoint at the given position. Only
+ /**
+ * Creates a new active node for a feasible breakpoint at the given position. Only
* called in forced mode.
+ *
* @param position index of the element in the Knuth sequence
* @param line number of the line ending at the breakpoint
* @param fitness fitness class of the line ending at the breakpoint. One of 0, 1, 2, 3.
@@ -621,6 +554,7 @@
* @param difference difference between target and actual line width
* @param totalDemerits minimum total demerits up to the breakpoint
* @param previous active node for the preceding breakpoint
+ * @return a new node
*/
protected KnuthNode createNode(int position, int line, int fitness,
int totalWidth, int totalStretch, int totalShrink,
@@ -646,11 +580,179 @@
best.getNode(fitness));
}
- /** Empty method, hook for subclasses. */
+ /**
+ * 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;
+ }
+
+ /**
+ * @param elementIndex the index to check
+ *
+ * @return {@code true} if the given element index points to
+ * the end of the current paragraph, or beyond
+ */
+ protected final boolean isEndOfParagraph(int elementIndex) {
+ return (elementIndex - par.size() >= 0);
+ }
+
+ /**
+ * 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.
+ * Non-overridable. This method simply serves to route the call to one of the
+ * more specific handlers ({@link #handleBox(KnuthBox)},
+ * {@link #handleGlueAt(KnuthGlue,int,boolean,int)} or
+ * {@link #handlePenaltyAt(KnuthPenalty,int,int)}. The specialized handlers
+ * can be overridden by subclasses to add to or modify the default behavior
+ * for the different types of elements.
+ *
+ * @param position the position index of the element in the list
+ * @param previousIsBox {@code true} if the previous element is a box
+ * @param allowedBreaks the type(s) of breaks allowed; should be one
+ * of {@link #ALL_BREAKS}, {@link #NO_FLAGGED_PENALTIES}
+ * or {@link #ONLY_FORCED_BREAKS}
+ * @return the handled element
+ */
+ protected final KnuthElement handleElementAt(int position,
+ boolean previousIsBox,
+ int allowedBreaks) {
+ KnuthElement element = getElement(position);
+ if (element.isBox()) {
+ handleBox((KnuthBox) element);
+ } else if (element.isGlue()) {
+ handleGlueAt((KnuthGlue) element, position, previousIsBox, allowedBreaks);
+ } else if (element.isPenalty()){
+ handlePenaltyAt((KnuthPenalty) element, position, allowedBreaks);
+ } else {
+ throw new IllegalArgumentException(
+ "Unknown KnuthElement type: expecting KnuthBox, KnuthGlue or KnuthPenalty");
+ }
+ return element;
+ }
+
+ /**
+ * Handle a {@link KnuthBox}.
+ *
+ * @param box the {@link KnuthBox} to handle
+ */
protected void handleBox(KnuthBox box) {
+ // a KnuthBox object is not a legal line break,
+ // just add the width to the total
+ totalWidth += box.getW();
}
+ /**
+ * Handle a {@link KnuthGlue} at the given position,
+ * taking into account the additional parameters.
+ *
+ * @param glue the {@link KnuthGlue} to handle
+ * @param position the position of the glue in the list
+ * @param previousIsBox {@code true} if the preceding element is a box
+ * @param allowedBreaks the type of breaks that are allowed
+ */
+ protected void handleGlueAt(KnuthGlue glue, int position,
+ boolean previousIsBox, int allowedBreaks) {
+ // a KnuthGlue object is a legal line break
+ // only if the previous object is a KnuthBox
+ // consider these glues according to the value of allowedBreaks
+ if (previousIsBox
+ && !(allowedBreaks == ONLY_FORCED_BREAKS)) {
+ considerLegalBreak(glue, position);
+ }
+ totalWidth += glue.getW();
+ totalStretch += glue.getY();
+ totalShrink += glue.getZ();
+ }
+
+ /**
+ * Handle a {@link KnuthPenalty} at the given position,
+ * taking into account the type of breaks allowed.
+ *
+ * @param penalty the {@link KnuthPenalty} to handle
+ * @param position the position of the penalty in the list
+ * @param allowedBreaks the type of breaks that are allowed
+ */
+ protected void handlePenaltyAt(KnuthPenalty penalty, int position,
+ int allowedBreaks) {
+ // a KnuthPenalty is a legal line break
+ // only if its penalty is not infinite;
+ // consider all penalties, non-flagged penalties or non-forcing penalties
+ // according to the value of allowedBreaks
+ if (((penalty.getP() < KnuthElement.INFINITE)
+ && (!(allowedBreaks == NO_FLAGGED_PENALTIES) || !penalty.isFlagged())
+ && (!(allowedBreaks == ONLY_FORCED_BREAKS)
+ || penalty.isForcedBreak()))) {
+ considerLegalBreak(penalty, position);
+ }
+ }
+
+ /**
+ * Replace the last too-long or too-short node by the last deactivated
+ * node, if applicable.
+ */
+ protected final void replaceLastDeactivated() {
+ if (lastDeactivated.adjustRatio > 0) {
+ //last deactivated was too short
+ lastTooShort = lastDeactivated;
+ } else {
+ //last deactivated was too long or exactly the right width
+ lastTooLong = lastDeactivated;
+ }
+ }
+
+ /**
+ * Recover from an overflow condition.
+ *
+ * @return the new {@code lastForced} node
+ */
+ protected KnuthNode recoverFromOverflow() {
+ KnuthNode lastForced;
+ if (isPartOverflowRecoveryActivated()) {
+ if (lastRecovered == null) {
+ lastRecovered = lastTooLong;
+ if (log.isDebugEnabled()) {
+ log.debug("Recovery point: " + lastRecovered);
+ }
+ }
+ KnuthNode node = recoverFromTooLong(lastTooLong);
+ lastForced = node;
+ node.fitRecoveryCounter = lastTooLong.previous.fitRecoveryCounter + 1;
+ if (log.isDebugEnabled()) {
+ log.debug("first part doesn't fit into line, recovering: "
+ + node.fitRecoveryCounter);
+ }
+ if (node.fitRecoveryCounter > getMaxRecoveryAttempts()) {
+ while (lastForced.fitRecoveryCounter > 0
+ && lastForced.previous != null) {
+ lastForced = lastForced.previous;
+ lastDeactivated = lastForced.previous;
+ }
+ lastForced = lastRecovered;
+ lastRecovered = null;
+ startLine = lastForced.line;
+ endLine = lastForced.line;
+ log.debug("rolled back...");
+ }
+ } else {
+ lastForced = lastTooLong;
+ }
+ return lastForced;
+ }
+
+ /**
+ * Restart from the given node at the given index.
+ *
+ * @param restartingNode the {@link KnuthNode} to restart from
+ * @param currentIndex the current position index
+ * @return the index of the restart point
+ */
protected int restartFrom(KnuthNode restartingNode, int currentIndex) {
+ if (log.isDebugEnabled()) {
+ log.debug("Restarting at node " + restartingNode);
+ }
restartingNode.totalDemerits = 0;
addNode(restartingNode.line, restartingNode);
startLine = restartingNode.line;
@@ -672,7 +774,8 @@
return restartingIndex;
}
- /** Determines if the given breakpoint is a feasible breakpoint. That is, if a decent
+ /**
+ * Determines if the given breakpoint is a feasible breakpoint. That is, if a decent
* line may be built between one of the currently active nodes and this breakpoint.
* @param element the paragraph's element to consider
* @param elementIdx the element's index inside the paragraph
@@ -689,6 +792,9 @@
lastDeactivated = null;
lastTooLong = null;
for (int line = startLine; line < endLine; line++) {
+ if (!elementCanEndLine(element, line + 1)) {
+ continue;
+ }
for (KnuthNode node = getNode(line); node != null; node = node.next) {
if (node.position == elementIdx) {
continue;
@@ -697,6 +803,7 @@
double r = computeAdjustmentRatio(node, difference);
int availableShrink = totalShrink - node.totalShrink;
int availableStretch = totalStretch - node.totalStretch;
+
if (log.isTraceEnabled()) {
log.trace("\tr=" + r + " difference=" + difference);
log.trace("\tline=" + line);
@@ -704,22 +811,17 @@
// The line would be too long.
if (r < -1 || element.isForcedBreak()) {
- // Deactivate node.
- if (log.isTraceEnabled()) {
- log.trace("Removing " + node);
- }
- removeNode(line, node);
- lastDeactivated = compareNodes(lastDeactivated, node);
+ deactivateNode(node, line);
}
+ int fitnessClass = computeFitness(r);
+ double demerits = computeDemerits(node, element, fitnessClass, r);
// The line is within the available shrink and the threshold.
if (r >= -1 && r <= threshold) {
- int fitnessClass = computeFitness(r);
- double demerits = computeDemerits(node, element, fitnessClass, r);
if (log.isTraceEnabled()) {
log.trace("\tDemerits=" + demerits);
- log.trace("\tFitness class=" + fitnessClass);
+ log.trace("\tFitness class=" + FitnessClasses.NAMES[fitnessClass]);
}
if (demerits < best.getDemerits(fitnessClass)) {
@@ -733,8 +835,6 @@
// The line is way too short, but we are in forcing mode, so a node is
// calculated and stored in lastValidNode.
if (force && (r <= -1 || r > threshold)) {
- int fitnessClass = computeFitness(r);
- double demerits = computeDemerits(node, element, fitnessClass, r);
int newWidth = totalWidth;
int newStretch = totalStretch;
int newShrink = totalShrink;
@@ -759,6 +859,7 @@
}
if (r <= -1) {
+ log.debug("Considering tooLong, demerits=" + demerits);
if (lastTooLong == null || demerits < lastTooLong.totalDemerits) {
lastTooLong = createNode(elementIdx, line + 1, fitnessClass,
newWidth, newStretch, newShrink,
@@ -792,6 +893,37 @@
}
/**
+ * Deactivate the given node
+ *
+ * @param node the node
+ * @param line the line number
+ */
+ protected void deactivateNode(KnuthNode node, int line) {
+ // Deactivate node...
+ if (log.isTraceEnabled()) {
+ log.trace("Removing " + node);
+ }
+ removeNode(line, node);
+ // ... and remember it, if it was a good candidate
+ lastDeactivated = compareNodes(lastDeactivated, node);
+ }
+
+ /**
+ * Check if the given {@link KnuthElement} at the given line number
+ * can end a "line" (= a "column" or "page" in page-breaking context).
+ *
+ * @param element the {@link KnuthElement} to check.
+ * @param line the "line" number
+ * @return {@code true} if the given element can terminate a "line"
+ */
+ protected boolean elementCanEndLine(KnuthElement element, int line) {
+ // Default implementation: the element can end a line if either it is not
+ // a penalty, or it is a penalty with value less than KnuthElement.INFINITE.
+ return !(element.isPenalty())
+ || element.getP() < KnuthPenalty.INFINITE;
+ }
+
+ /**
* Adds new active nodes for breaks at the given element.
* @param line number of the previous line; this element will end line number (line+1)
* @param elementIdx the element's index
@@ -832,7 +964,7 @@
// by line number and position;
if (log.isTraceEnabled()) {
log.trace("\tInsert new break in list of " + activeNodeCount
- + " from fitness class " + i);
+ + " from fitness class " + FitnessClasses.NAMES[i]);
}
KnuthNode newNode = createNode(elementIdx, line + 1, i,
newWidth, newStretch, newShrink);
@@ -846,8 +978,9 @@
* Return the difference between the natural width of a line that would be made
* between the given active node and the given element, and the available width of the
* real line.
- * @param activeNode node for the previous breakpoint
- * @param element currently considered breakpoint
+ * @param activeNode node for the previous breakpoint
+ * @param element currently considered breakpoint
+ * @param elementIndex index of the element that is considered as a breakpoint
* @return The difference in width. Positive numbers mean extra space in the line,
* negative number that the line overflows.
*/
@@ -862,7 +995,7 @@
}
/**
- * Return the adjust ration needed to make up for the difference. A ration of
+ * Return the adjustment ratio needed to make up for the difference. A ratio of
*
* - 0 means that the break has the exact right width
* - >= -1 && < 0 means that the break is wider than the line,
@@ -871,9 +1004,9 @@
* but within the maximum values of the glues.
* - > 1 means that the break is too small to make up for the glues.
*
- * @param activeNode
- * @param difference
- * @return The ration.
+ * @param activeNode the currently active node
+ * @param difference the difference between content-length and available width
+ * @return The adjustment ratio.
*/
protected double computeAdjustmentRatio(KnuthNode activeNode, int difference) {
// compute the adjustment ratio
@@ -901,18 +1034,18 @@
* very tight or very loose).
* See the section on "More Bells and Whistles" in Knuth's
* "Breaking Paragraphs Into Lines".
- * @param r
+ * @param adjustRatio the adjustment ratio
* @return the fitness class
*/
- private int computeFitness(double r) {
- if (r < -0.5) {
- return 0;
- } else if (r <= 0.5) {
- return 1;
- } else if (r <= 1) {
- return 2;
+ private int computeFitness(double adjustRatio) {
+ if (adjustRatio < -0.5) {
+ return FitnessClasses.VERY_TIGHT;
+ } else if (adjustRatio <= 0.5) {
+ return FitnessClasses.TIGHT;
+ } else if (adjustRatio <= 1) {
+ return FitnessClasses.LOOSE;
} else {
- return 3;
+ return FitnessClasses.VERY_LOOSE;
}
}
@@ -933,12 +1066,14 @@
// compute demerits
double f = Math.abs(r);
f = 1 + 100 * f * f * f;
- if (element.isPenalty() && element.getP() >= 0) {
- f += element.getP();
- demerits = f * f;
- } else if (element.isPenalty() && !element.isForcedBreak()) {
+ if (element.isPenalty()) {
double penalty = element.getP();
- demerits = f * f - penalty * penalty;
+ if (penalty >= 0) {
+ f += penalty;
+ demerits = f * f;
+ } else if (!element.isForcedBreak()) {
+ demerits = f * f - penalty * penalty;
+ }
} else {
demerits = f * f;
}
@@ -982,7 +1117,15 @@
return demerits;
}
+ /**
+ * Hook for subclasses to trigger special behavior after ending the
+ * main loop in {@link #findBreakingPoints(KnuthSequence,int,double,boolean,int)}
+ */
protected void finish() {
+ if (log.isTraceEnabled()) {
+ log.trace("Main loop completed " + activeNodeCount);
+ log.trace("Active nodes=" + toString(""));
+ }
}
/**
@@ -1106,10 +1249,10 @@
sb.append("[\n");
for (int i = startLine; i < endLine; i++) {
for (KnuthNode node = getNode(i); node != null; node = node.next) {
- sb.append(prepend + "\t" + node + ",\n");
+ sb.append(prepend).append('\t').append(node).append(",\n");
}
}
- sb.append(prepend + "]");
+ sb.append(prepend).append("]");
return sb.toString();
}
Index: src/java/org/apache/fop/layoutmgr/KnuthSequence.java
===================================================================
--- src/java/org/apache/fop/layoutmgr/KnuthSequence.java (revision 786985)
+++ src/java/org/apache/fop/layoutmgr/KnuthSequence.java (working copy)
@@ -19,6 +19,8 @@
package org.apache.fop.layoutmgr;
+import org.apache.fop.util.ListUtil;
+
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
@@ -26,10 +28,10 @@
/**
* Represents a list of Knuth elements.
*/
-/**
- *
- */
public abstract class KnuthSequence extends ArrayList {
+
+ private int firstBoxIndex = -1;
+
/**
* Creates a new and empty list.
*/
@@ -132,11 +134,9 @@
* @return the last element of this sequence.
*/
public ListElement getLast() {
- int idx = size();
- if (idx == 0) {
- return null;
- }
- return (ListElement) get(idx - 1);
+ return (isEmpty()
+ ? null
+ : (ListElement) ListUtil.getLast(this));
}
/**
@@ -144,25 +144,63 @@
* @return the removed element.
*/
public ListElement removeLast() {
- int idx = size();
- if (idx == 0) {
- return null;
- }
- return (ListElement) remove(idx - 1);
+ return (isEmpty()
+ ? null
+ : (ListElement) ListUtil.removeLast(this));
}
/**
- * @param index The index of the element to be returned
+ * @param index the index of the element to be returned
* @return the element at index index.
*/
public ListElement getElement(int index) {
- return (ListElement) get(index);
+ return ((index >= size() || index < 0)
+ ? null
+ : (ListElement) get(index));
}
+ /** @return the position index of the first box in this sequence */
+ protected int getFirstBoxIndex() {
+ if (isEmpty()) {
+ firstBoxIndex = -1;
+ } else if (firstBoxIndex == -1){
+ //not yet initialized, or dirty
+ firstBoxIndex = getFirstBoxIndex(0);
+ }
+ return firstBoxIndex;
+ }
+
/**
+ * @param fromIndex the index to start from
+ * @return the position index of the first box, after the given position
+ */
+ protected int getFirstBoxIndex(int fromIndex) {
+ if (isEmpty() || fromIndex >= size() || fromIndex < 0) {
+ return -1;
+ } else {
+ ListElement element = null;
+ int posIndex = fromIndex;
+ int lastIndex = size() - 1;
+ while (posIndex < lastIndex
+ && !(element = getElement(posIndex)).isBox()) {
+ posIndex++;
+ }
+ if (element != null && element.isBox()) {
+ return posIndex;
+ }
+ }
+ return -1;
+ }
+
+ /**
* Is this an inline or a block sequence?
* @return true if this is an inline sequence
*/
public abstract boolean isInlineSequence();
+ /** {@inheritDoc} */
+ public String toString() {
+ return "";
+ }
+
}
Index: src/java/org/apache/fop/fo/flow/table/EffRow.java
===================================================================
--- src/java/org/apache/fop/fo/flow/table/EffRow.java (revision 786985)
+++ 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 786985)
+++ 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/block_keep_within-column.xml
===================================================================
--- test/layoutengine/standard-testcases/block_keep_within-column.xml (revision 0)
+++ test/layoutengine/standard-testcases/block_keep_within-column.xml (revision 0)
@@ -0,0 +1,140 @@
+
+
+
+
+
+
+ This test checks whether keeps within-column are respected.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ [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]
+
+
+ [BOB-2] foo bar foo bar foo bar foo bar foo [EOB-2]
+
+
+
+
+
+ [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
+
+ [BOB-3a] foo bar foo bar foo bar foo bar foo [EOB-3a]
+
+ 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]
+
+
+
+
+
+ [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
+
+ [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]
+
+ 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]
+
+
+
+
+
+
+ [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]
+
+
+ [BOB-5b] foo bar foo bar foo bar foo bar foo bar
+ foo bar foo bar foo bar foo bar foo bar [EOB-5b]
+
+
+ [BOB-5c] foo bar foo bar foo bar foo bar foo bar
+ foo bar foo bar foo bar foo bar foo bar [EOB-5c]
+
+
+
+
+
+
+
+ [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]
+
+
+ [BOB-6b] foo bar foo bar foo bar foo bar foo bar [EOB-6b]
+
+
+ [BOB-6c] foo bar foo bar foo bar foo bar foo bar
+ foo bar foo bar foo bar foo bar foo bar [EOB-6c]
+
+
+
+
+
+
+
+
+
+
+
+
Index: test/layoutengine/standard-testcases/inline_block_nested_6.xml
===================================================================
--- test/layoutengine/standard-testcases/inline_block_nested_6.xml (revision 786985)
+++ test/layoutengine/standard-testcases/inline_block_nested_6.xml (working copy)
@@ -52,16 +52,15 @@
5
- 6
+ 5
- 6
+ 3
- 5
- 3
+ 14
Index: test/layoutengine/standard-testcases/table-row_keep-together.xml
===================================================================
--- test/layoutengine/standard-testcases/table-row_keep-together.xml (revision 786985)
+++ test/layoutengine/standard-testcases/table-row_keep-together.xml (working copy)
@@ -64,10 +64,10 @@
-
-
- 3
+
+
+ 5
Index: test/layoutengine/standard-testcases/table_keep-together.xml
===================================================================
--- test/layoutengine/standard-testcases/table_keep-together.xml (revision 786985)
+++ test/layoutengine/standard-testcases/table_keep-together.xml (working copy)
@@ -101,9 +101,11 @@
-
+
+
+
3